VS Code Extension
The Phobos VS Code extension adds rich editor support for Phobos HCL pipeline templates (pipeline.hcl), release lifecycle templates (release_lifecycle.hcl), and Phobos variables files (*.pbvars β the input format Phobos reads at pipeline-creation time, analogous to Terraform's .tfvars). It is published to both the VS Code Marketplace and the Open VSX Registry, so the same VSIX serves VS Code, VSCodium, Cursor, Code OSS, Gitpod, Theia, and other VS Code-compatible editors. Every feature beyond syntax highlighting is powered by the Phobos Language Server, which is bundled in the GitLab-releases VSIXes and downloaded on first launch for registry installs β see Installation.
Check the FAQ to see if there's already an answer.
Featuresβ
Language supportβ
- Syntax highlighting β Full HCL grammar coloring for
pipeline.hcl,release_lifecycle.hcl, and*.pbvars, plus Phobos-specific semantic tokens layered on top. Generic.hclfiles are not claimed by default to avoid clashing with Terraform / Nomad / Packer in mixed-tool workspaces β opt in withphobos.editor.associateAllHclFiles. - Diagnostics β Real-time error, warning, and hint markers as you type. Covers parse errors, schema violations, cross-field constraints (
intervalrequiresattempts, deployments requireenvironment,mount_pointvolumes must be declared),stage_ordercorrectness, duplicate names, reserved keywords, dependency-name validation, dead action references (including typos in task-level attributes likesuccess_condition), undefinedvar.*/jwt.*/vcs_token.*/volume.*references, structural typos inpipeline.*/this.*/phobos.*reference paths, requiredplugin "<name>" { }configuration blocks, plugin-alias resolution (unresolvedplugin = <type>.<alias>refs, plus the ambiguity case where a type has only aliased instances), deprecations, and unused declarations..pbvarsfiles get cross-file diagnostics against the sibling template'svariable "<name>"declarations β unknown names error out, type mismatches against the declaredcty.Typeproduce friendly messages (e.g.variable "replicas" has type number but was assigned a value of type string), and unresolved references inside values surface HCL's own diagnostic. Enum-typed attributes accept variable references without false positives. - Hover documentation β Markdown-formatted docs on blocks, attributes, action labels (with inputs and outputs), named values (
var.*,jwt.*,pipeline.*,this.*, β¦), and task-output references that resolvepipeline.stage.<s>.task.<t>.outputs.<o>back to the declaring block. In a.pbvarsfile, hover an attribute name to surface the sibling variable'sdescription, declaredtype, and default-state. - Context-aware completion β Block types, attribute names, enumerated string values, HCL built-in functions, named-value namespaces, typed-output field navigation, sibling-name suggestions inside
dependencies = [...], and plugin-instance suggestions insideaction { plugin = <cursor> }offering every declared<type>.<alias>qualified name..pbvarscompletion offers each variable name from the sibling template as a typed snippet βstringinserts quotes-with-cursor-between,numberinserts a0placeholder,boolinserts atrue/falsechoice dropdown,object({...})types pre-populate every declared field as its own tab stop with=signs aligned. - Signature help β Parameter hints on HCL built-in function calls.
- Go-to-definition β Jump from any
var.*,jwt.*,vcs_token.*,volume.*,pipeline.stage.*,this.action.*,this.alias.*reference, oraction { plugin = <type>.<alias> }traversal to its declaration. - Find all references β Including cross-file propagation for workspace-level declarations and plugin-alias usages across every
action { plugin = <type>.<alias> }. - Rename β Rename
variable,jwt, andvcs_tokendeclarations across every file in the workspace in one edit. Plugin aliases also rename in place β edits touch just the alias half of each usage so the type prefix stays anchored to the action-label. - Call hierarchy β Right-click a task, deployment, or nested pipeline to explore
dependencies = [...]edges as a DAG (incoming and outgoing). - Document outline, folding, and selection-range expansion that follows the HCL AST.
- Formatting β Format the whole document or on save using canonical HCL formatting. On-type formatting re-formats a block when you close it with
}. - Inlay hints β Variable types and defaults, per-action plugin-instance badges (qualified
<type>.<alias>when the action setsplugin = ..., bare type otherwise), per-task action + output counts (: 2 actions, 1 output), per-stage children counts (: 3 tasks,: 2 tasks, 1 pipeline), and deployment environments. Each category is independently toggleable. - Document links β Plugin sources in
plugin_requirementsbecome clickable links to the plugin registry. - Code actions β Install-plugin quick-fix, declare-missing-plugin-block quick-fix (inserts the block at the natural anchor after
plugin_requirements), declare-aliased-plugin-block quick-fix (for unresolvedplugin = <type>.<alias>refs), set-plugin-ref quick-fix (one option per declared alias when a type has only aliased instances), deprecation rewrites, extract-to-variable / inline-variable refactors, andsource.fixAllfor bulk deprecation migration.
UIβ
- Phobos activity-bar view with two tree panels (Templates, Installed Plugins).
- Pipeline Graph webview β interactive DAG of stages, tasks, deployments, and dependencies for the active template.
- Evaluated Context panel β live namespace / value tree at the cursor, updated as you move through the document.
- Unified status-bar chip consolidating language-server state, CLI detection, plugin health, diagnostic counts, and deprecation count.
See Activity bar, Status bar, and Webviews below.
Installationβ
The extension is distributed through three channels:
| Channel | Includes language server | Notes |
|---|---|---|
| VS Code Marketplace / Open VSX Registry | No (downloads on demand) | Universal VSIX, small (~1 MB). On first launch the extension prompts to download the language server and installs it into the editor's global storage. |
GitLab releases (.vsix) | Yes | Platform-specific VSIXes with the phobos-language-server binary bundled. Best for air-gapped environments and internal deployments. |
| Built from source | No | See Building from source. |
Only the .vsix files published on the vscode-phobos GitLab releases page ship with phobos-language-server bundled. Installs from the VS Code Marketplace and Open VSX Registry do not include the binary β the extension downloads and verifies it on first launch, or on demand via Phobos: Install or Update Language Server. Pick the channel that matches your deployment: a public registry for hands-off install on a networked machine, GitLab releases for air-gapped / internal-hosted deployments.
From a registry (VS Code Marketplace or Open VSX)β
The extension is published to both registries from a single source β pick the one your editor uses:
- VS Code Marketplace β VS Code, Cursor, Kiro, and other Microsoft-licensed VS Code distributions.
- Open VSX Registry β VSCodium, Code OSS, Gitpod, Theia, and other Eclipse-licensed VS Code forks that can't legally use the Microsoft Marketplace.
Both registries publish the same VSIX. Install through your editor's Extensions view (search "Phobos" β Install) β neither bundles the language-server binary, so on first activation over a Phobos file the extension prompts:
Phobos language server not found. Install the latest version? [Install Latest] [Set Pathβ¦]
Choose Install Latest to download the platform-specific binary, verify its SHA-256 against the release manifest, and place it in VS Code's global storage. The language server starts automatically once the download completes. You can rerun or upgrade with the palette command Phobos: Install or Update Language Server.
Registry installs (Marketplace or Open VSX) need outbound HTTPS access to gitlab.com for the initial language-server download. For air-gapped environments, use the GitLab releases VSIX instead β it ships with the language server bundled.
From GitLab releasesβ
GitLab releases publish platform-specific VSIXes with the language-server binary bundled β the extension launches the server locally without any runtime download. Download the .vsix matching your platform from the vscode-phobos releases page, then install:
code --install-extension mc-phobos-<version>-<platform>.vsix
Or from inside VS Code: open the Extensions view (Ctrl+Shift+X), click the ... menu, and select Install from VSIXβ¦.
The available platform packages are:
| File suffix | Platform |
|---|---|
linux-x64 | Linux x86-64 (glibc) |
linux-arm64 | Linux ARM 64-bit (glibc) |
linux-armhf | Linux ARM 32-bit (ARMv7, glibc) |
alpine-x64 | Alpine Linux x86-64 (musl) |
alpine-arm64 | Alpine Linux ARM 64-bit (musl) |
darwin-x64 | macOS Intel |
darwin-arm64 | macOS Apple Silicon |
win32-x64 | Windows x86-64 |
win32-arm64 | Windows ARM 64-bit |
Installing the wrong platform package leaves the bundled binary unusable. The extension falls back to the marketplace-style runtime install (if the other tiers also miss) so you can recover without reinstalling β see Language-server discovery.
Building from sourceβ
When you build the extension from source the language server binary is not bundled. Install it separately using one of:
- Runtime install β Launch the extension and run Phobos: Install or Update Language Server from the command palette.
- Manual install β Download the appropriate binary from the language server releases page and place it on your
PATH, or setphobos.languageServer.pathto its absolute path.
# Replace VERSION with the release tag and PLATFORM with one of:
# linux_amd64, linux_arm64, linux_arm, linux_386,
# darwin_amd64, darwin_arm64
VERSION=0.1.0
PLATFORM=linux_amd64
BASE="https://gitlab.com/infor-cloud/martian-cloud/phobos/phobos-language-server/-/releases/${VERSION}/downloads"
curl -L -o phobos-language-server "${BASE}/phobos-language-server_${VERSION}_${PLATFORM}"
chmod +x phobos-language-server
sudo mv phobos-language-server /usr/local/bin/
Language-server discoveryβ
The extension resolves the phobos-language-server binary using a four-tier cascade. The first tier that finds a binary wins; higher tiers short-circuit lower ones.
phobos.languageServer.pathβ Honored only in trusted workspaces. If the setting is present but points at a missing file, an error is surfaced (no silent fallthrough) so you can notice the misconfiguration.- Bundled binary β
<extension>/bin/phobos-language-server. Present in platform-specific GitLab-releases VSIXes; absent from marketplace VSIXes. - Runtime-installed binary β
<globalStorage>/bin/phobos-language-server, populated by the Phobos: Install or Update Language Server command. Survives extension updates. - System
PATHβphobos-language-serverfound bywhich.
If every tier misses, the extension prompts you to install the latest release.
Activity barβ
The Phobos icon in the activity bar (left sidebar) opens two tree views:
- Templates β Every
pipeline.hcl/release_lifecycle.hclin the workspace, expanded to its document-symbol outline. Click a symbol to jump to the declaration. Click the refresh button in the view title to re-scan the workspace. - Installed Plugins β The language server's plugin inventory, grouped by plugin name. Expand a plugin to see actions, then actions to see inputs and outputs. Right-click a plugin and choose Browse Online to open its registry page in the browser.
Status barβ
A single Phobos chip lives in the right-hand status bar. It summarises every signal the extension tracks:
| Indicator | Meaning |
|---|---|
$(sync~spin) Phobos | Language server starting |
$(check) Phobos 0.4.2 | Healthy β server running, CLI detected, no diagnostics |
$(info) Phobos β¦ Β· N | N informational diagnostics (across all open templates) |
$(warning) Phobos β¦ Β· N | N warnings |
$(error) Phobos β¦ Β· N | N errors |
$(alert) Phobos CLI missing | The phobos CLI cannot be found |
$(alert) Phobos stopped | Language server stopped (crashed / disabled) |
$(alert) Phobos Β· N plugins failing | N plugin subprocesses failed to start |
Hover the chip to see a full Markdown breakdown (CLI path + version, plugin ready/failing counts, diagnostic counts per severity, active file kind, deprecation count). Click to open a QuickPick menu with targeted actions:
- Open the Problems panel (when diagnostics are present)
- Migrate deprecations in the active file
- Restart the language server
- Install or update the Phobos CLI
- Install or update the language server
- Show plugin output
- Refresh plugins
- Show the pipeline graph
- Show the evaluated context
- Open a project file (QuickPick across all templates)
- View documentation
Disable the chip with phobos.statusBar.enabled: false β a window reload is required.
Webviewsβ
Pipeline Graphβ
Phobos: Show Pipeline Graph opens a webview beside the editor that renders the active template as a layered DAG:
- Stages appear as columns, with tasks, deployments, and nested pipelines as nodes inside them.
dependencies = [...]edges connect sibling nodes within a stage.- Pre / post phases are grouped inside their parent stage.
- Clicking a node jumps to its declaration in the source file.
The graph refreshes when you save the active template or switch to a different Phobos file.
Evaluated Contextβ
Phobos: Show Evaluated Context opens a webview that lists every namespace the evaluator would expose at the cursor:
var.*,jwt.*,vcs_token.*,system.*,pipeline.*, and the current stage / taskthis.*.- Leaf values render their literal (for string / number / bool) and inferred type.
- Unknown / dynamic values are flagged so you can see what only resolves at runtime.
The panel updates as you move the cursor, so you can inspect context at any position inside a stage / task / action body without leaving the editor.
Commandsβ
Every command is reachable from the Command Palette (Ctrl+Shift+P).
| Command | Purpose |
|---|---|
Phobos: Restart Language Server | Restart the LSP without reloading the whole VS Code window. |
Phobos: Install or Update Language Server | Download the latest phobos-language-server release into global storage and restart the client. |
Phobos: Install or Update CLI | Install / update the phobos CLI via go install, a releases-page link, or a settings shortcut. |
Phobos: View Documentation | Open the hosted Phobos documentation in the default browser. |
Phobos: Show Pipeline Graph | Open the DAG webview for the active template. |
Phobos: Show Evaluated Context | Open the evaluator-namespace webview for the cursor position. |
Phobos: Open Project File | QuickPick across every pipeline.hcl / release_lifecycle.hcl in the workspace, badged by kind. |
Phobos: Migrate Deprecations in Current File | Apply every preferred deprecation fix in the active editor as a single undoable WorkspaceEdit. |
Phobos: Refresh (Installed Plugins view title) | Re-run plugin discovery on the server and refresh the tree. |
Phobos: Refresh Templates | Re-scan the workspace for template files and rebuild the Templates tree. |
Phobos: Show Plugin Output | Open the Phobos output channel where plugin-subprocess logs surface. |
Configurationβ
All settings live under the phobos namespace in VS Code. Open Settings (Ctrl+,) and search for phobos, or add them directly to settings.json.
Coreβ
| Setting | Type | Default | Description |
|---|---|---|---|
phobos.languageServer.enable | boolean | true | Enable / disable the language server entirely. When false, only syntax highlighting is available. |
phobos.languageServer.path | string | null | null | Absolute path to the phobos-language-server binary. Honoured only in trusted workspaces. See Language-server discovery for the full cascade when unset. |
phobos.languageServer.tcp.port | number | null | null | Connect to an already-running language server over TCP instead of spawning a subprocess. See Development mode. Refused in untrusted workspaces. |
phobos.cliPath | string | null | null | Absolute path to the phobos CLI. Unset = PATH resolution. Used by the extension for plugin install, SSO login, and similar flows. |
phobos.profile | string | null | null | Phobos profile name. Every extension-issued phobos β¦ command is prefixed with -p <profile>. |
phobos.instance.host | string | null | null | Phobos registry UI host (e.g. phobos.example.com). Used by the Browse Online action on plugin tree items. When unset, inferred from .phobos/settings.json in the workspace. |
phobos.editor.associateAllHclFiles | boolean | false | Treat every .hcl file in the workspace as a Phobos document. Off by default to avoid clashing with Terraform / Nomad / Packer extensions that also claim the .hcl extension. The canonical Phobos files (pipeline.hcl, release_lifecycle.hcl) and *.pbvars are always associated regardless of this setting. Toggling on claims every currently-open .hcl document immediately and routes future opens through the same path. Toggling off only affects future opens (existing docs keep their phobos language until you reload the window β VS Code provides no API to revert a doc's language assignment in place). |
On Windows, use forward slashes or escape backslashes in path settings: "C:/tools/phobos-language-server.exe" or "C:\\tools\\phobos-language-server.exe".
Inlay hintsβ
| Setting | Default | Description |
|---|---|---|
phobos.inlayHints.enabled | true | Master switch. When false, every sub-setting below is ignored. |
phobos.inlayHints.variableTypes | true | Show : string, : number, etc. after untyped variable defaults. |
phobos.inlayHints.variableDefaults | true | Show the resolved default value next to var.<name> references where the default is a literal. |
phobos.inlayHints.actionPlugins | true | Show the resolved plugin instance next to each action "<plugin>_<name>" label β : docker.builder when plugin = docker.builder is set, : docker otherwise. |
phobos.inlayHints.actionCounts | true | Show per-task action + output counts (: 2 actions, 1 output). The outputs half is hidden when the task has none. |
phobos.inlayHints.deployments | true | Show environment = "β¦" after deployment blocks in lifecycle templates. |
phobos.inlayHints.stages | true | Show a children-count summary after each stage "<name>" label (: 3 tasks, : 2 tasks, 1 pipeline). Main-phase direct children only. |
VS Code's global editor.inlayHints.enabled setting also needs to be on for any inlay hint to render.
Document links, semantic tokens, diagnosticsβ
| Setting | Default | Description |
|---|---|---|
phobos.documentLinks.enabled | true | Master switch for document links. |
phobos.documentLinks.pluginDocs | true | Link plugin_requirements.*.source values to the plugin registry. |
phobos.semanticTokens.enabled | true | Enable LSP semantic tokens (layered on top of the TextMate grammar). |
phobos.diagnostics.unusedAsHint | false | Render "unused variable / jwt / vcs_token / volume" diagnostics as Hint (dimmed, no Problems-panel count) instead of Information. |
phobos.statusBar.enabled | true | Show the unified Phobos status-bar chip. Toggling requires a window reload. |
Workspace Trustβ
Phobos templates can reference plugins installed at ~/.phobos.d/plugins/, and the language server normally spawns those plugin binaries to fetch schemas used for completion, hover, and validation inside action bodies. In untrusted workspaces the extension launches the server with PHOBOS_LSP_DISABLE_PLUGINS=1, which disables the subprocess-spawn path entirely. Syntax highlighting and built-in diagnostics stay available; plugin-specific action-body features are suppressed until you grant trust. Trust transitions restart the language server automatically.
The following settings are declared as restrictedConfigurations β VS Code ignores workspace-scoped overrides for them until trust is granted, so a hostile workspace can't point the extension at an attacker-controlled binary, host, or profile:
phobos.languageServer.pathphobos.languageServer.tcp.portphobos.cliPathphobos.profilephobos.instance.host
Virtual workspaces (over SSH, Codespaces with a virtual file system, etc.) are unsupported β the language server requires a local filesystem and the extension declines to start in those contexts.
Development modeβ
When working on phobos-language-server locally you can run it in TCP mode and have the extension connect to it instead of managing the subprocess itself.
1. Start the language server in TCP mode:
phobos-language-server --port 7777
2. Configure the extension to connect via TCP:
{
"phobos.languageServer.tcp.port": 7777
}
3. Reload the VS Code window (Ctrl+Shift+P β Developer: Reload Window).
The extension will now connect to the running process. You can restart the language server binary and reload the window as needed without touching your extension installation.
phobos.languageServer.path is ignored when phobos.languageServer.tcp.port is set. TCP mode is also refused in untrusted workspaces β grant trust first.
Viewing language server logsβ
If the extension is not behaving as expected, open the Phobos output channel:
- Open the Output panel (
Ctrl+Shift+Uor View β Output). - Select Phobos from the dropdown in the top-right corner of the panel.
The channel shows the resolved binary path, connection status, and any errors reported by the language server. A second channel β Phobos CLI β carries output from extension-issued phobos β¦ commands (plugin install, SSO login).
Frequently asked questions (FAQ)β
The extension prompted me to install the language server. Is that expected?β
Yes, for registry installs (VS Code Marketplace and Open VSX). Registry VSIXes ship without the language-server binary to keep them small and portable β the extension downloads it on first launch and installs it into the editor's global storage. You only see the prompt once; subsequent launches resolve the installed binary directly. If you prefer a bundled install (e.g. for an air-gapped machine), download a platform-specific VSIX from the GitLab releases page instead β those include the binary.
Why is syntax highlighting working but none of the other features are?β
The LSP features (diagnostics, hover, completion, formatting, go-to-definition) require phobos-language-server to be running. Check the Phobos output channel for errors. The most common causes are:
- The first-launch install prompt was cancelled. Run Phobos: Install or Update Language Server from the palette to retry.
- You installed a platform-specific VSIX for the wrong OS / architecture β the bundled binary won't run on a mismatched platform.
- You built the extension from source β the binary is not bundled in that case.
How do I upgrade the language server without reinstalling the extension?β
Run Phobos: Install or Update Language Server from the palette. The extension downloads the latest release, verifies its SHA-256, and restarts the language client. Works for every install channel.
How do I enable format on save?β
Add the following to your settings.json:
{
"[phobos]": {
"editor.formatOnSave": true
}
}
The language server crashed. What do I do?β
The extension automatically restarts the language server up to three times within a five-minute window. If it exhausts that budget it stops restarting and shows an error notification. Check the Phobos output channel for the error, then either fix the underlying issue or reload the VS Code window (Ctrl+Shift+P β Developer: Reload Window) to try again.
Can I use the extension without the language server?β
Yes. Set phobos.languageServer.enable to false to use only syntax highlighting. Diagnostics, hover, completion, formatting, and everything else will be unavailable.
My file is not recognized as a Phobos file. What's wrong?β
The extension claims three filename patterns by default:
- Files named exactly
pipeline.hclorrelease_lifecycle.hcl. - Any file with the
.pbvarsextension.
Other .hcl files are not claimed unless you opt in via phobos.editor.associateAllHclFiles β see Configuration. The default is off so the extension doesn't fight Terraform / Nomad / Packer for ownership of .hcl in mixed-tool workspaces.
If your file matches one of the patterns above but isn't highlighted, check that the language mode shown in the VS Code status bar reads Phobos rather than HCL or Plain Text. You can click the language indicator in the status bar to change it manually for the current file. To make the change permanent for a specific filename pattern, use VS Code's files.associations setting:
{
"files.associations": {
"my_pipeline.hcl": "phobos"
}
}
Can I use the extension in a forked editor like VSCodium, Code OSS, Cursor, or Kiro?β
Yes. Install from the Open VSX Registry (for VSCodium / Code OSS / Gitpod / Theia) or the VS Code Marketplace (for forks that support it, such as Cursor and Kiro). The runtime-install flow works the same way. If you're using an editor that doesn't support VS Code extensions, the Phobos Language Server can still power diagnostics, completion, and hover through any LSP-capable client β see the Language Server guide.