|
| Dependency | Role |
|---|---|
VS Code extension API (^1.90.0) |
View containers, tree views, commands, WebviewPanel |
| CodeMirror 6 | Plain-text chat-input editing, selection, and sizing |
markdown-it |
Governed Markdown parsing and renderer customization |
highlight.js |
Client-side syntax highlighting for fenced code blocks |
js-yaml |
YAML parsing for vector-open-doc and agent blocks |
3. Local Development
Prerequisites: Node.js ≥ 20, pnpm 10.33.3, VS Code.
cd frontend/vscode/vector
pnpm install
pnpm run compile
Open the frontend/vscode/vector/ folder in VS Code and press F5 to launch the extension in a development host.
Run tests:
pnpm test
4. Packaging
Build the .vsix package:
cd frontend/vscode/vector
pnpm run package
This produces a vector-<version>.vsix file in the package directory.
To install the packaged extension locally in VS Code:
code --install-extension vector-<version>.vsix
Or open VS Code → Extensions → ... → Install from VSIX… and select the generated file.
Note: Runtime-imported packages must be declared under
"dependencies"sovscecan bundle them into the generated.vsix. This extension usesjs-yamlat activation time, so packaging must include runtime dependencies.
5. Activation
The extension activates when the opened workspace contains .vector/document-types.yaml. This file is the source of truth for governed document types and their layout configuration.
6. Preview Architecture
Governed reading flows are extension-owned:
- The tree view and Vector commands open governed documents in one reusable
WebviewPanel. - The preview is read-only and scoped to governed documents opened through Vector flows.
- Wikilinks and frontmatter document references resolve through the same governed lookup boundary used by the sidebar.
- Preview resources are loaded through webview-safe local URIs with a restrictive Content Security Policy.
- Interactive prompt editing remains scoped to
document-viewer/; the dedicatedchat-input/,form-editor/, anddocument-actions/modules do not introduce a top-level editor platform. - Editable
chat-inputfields run on a dedicated CodeMirror 6 runtime inmedia/chat-input-runtime.js, so prompt state, selection, mention decorations, and auto-grow measurement no longer depend oncontenteditableDOM rewrites inpreview.js. chat-inputsubmissions preserve structured file-mention metadata for future use while the current agent execution path continues to consume only plain text content.
7. Naming Contracts
- Hash-brace substitution variables accepted by the extension are kebab-case only. Valid examples include
#{doc-type},#{file-path}, and#{document-type}. - Underscore-containing placeholders such as
#{doc_type}or#{document_type}are intentionally left unresolved and are treated as invalid contract usage. .vector/*.yamlschema field names are also kebab-case only. Extension-side YAML readers reject invalid schema fields defensively, while repository-wideruntime-doc validateremains the authoritative failure path.
8. Instruction Capability
The extension communicates prompt content to agents through a UUID-scoped instruction file managed entirely by the extension. This replaces the former <file> path handoff.
8.1 Configuration contract
.vector/agents.yaml must declare a top-level instructions-dir property:
instructions-dir: "${system-temp}/vector/instructions"
# Optional: override the default launch prompt (see section 8.7).
# prompt: 'Using Vector MCP, call get_instruction with id "<instruction-id>" and execute the returned instructions.'
agents:
claude:
type: cli
command: claude '<instruction>'
${system-temp} is the only supported variable. TypeScript resolves it with os.tmpdir(); the MCP counterpart resolves it with std::env::temp_dir(). The value must begin with ${system-temp}, must not contain .. or unsupported variable expressions, and must not resolve outside the system temporary directory.
This is a breaking change. Configurations that use the old <file> or <instruction-id> placeholders, or that omit instructions-dir, fail validation with an actionable error toast and prevent terminal creation. There is no compatibility fallback.
8.2 Distinct configuration responsibilities
| File | Responsibility |
|---|---|
.agents/mcp_config.json |
Declares how the MCP server (mcp-vector) is started — command, arguments, and transport type. Contains no agent-execution or instruction-directory configuration. |
.vector/agents.yaml |
Configures agents, profiles, and the instructions-dir where instruction files are written. This file is the source of truth for the instruction lifecycle. |
8.3 Instruction lifecycle
For each agent invocation:
- The extension resolves the prompt and substitutes all declared input values.
.vector/agents.yamlis loaded and validated.- The configured instruction directory is resolved.
- A cryptographically random UUID is generated with
crypto.randomUUID(). - The instruction directory is created when necessary.
- A file named
vector-instruction-<canonical-uuid>.txtis created exclusively with UTF-8 content and restrictive POSIX permissions (0o600) where supported (non-Windows). - The frontend-owned MCP directive is rendered with the UUID and substituted for
<instruction>as one shell-safe argument. No second interpolation pass occurs. - The terminal is created with the active workspace root as explicit
cwd. - The instruction file path is associated with the terminal for cleanup.
Retry behaviour: The MCP get_instruction tool does not delete the instruction file after a successful read. Repeated reads succeed for the full terminal lifetime, making agent retries safe.
Cleanup: Instruction files are deleted when the associated terminal closes, when the extension deactivates, or immediately after a launch failure after the file has been created. On activation, the extension removes only regular files matching the exact vector-instruction-<uuid>.txt filename shape that are older than 24 hours; it does not follow links, recurse, or delete unrelated files.
Cleanup failures are written to a local VS Code diagnostic output channel only. No telemetry is collected or emitted.
Size bound: The MCP get_instruction tool enforces a fixed, non-configurable 1 MiB limit. Instructions larger than 1 MiB are rejected with an actionable error; they must be decomposed.
8.4 Platform-specific filesystem guarantees
| Platform | Guarantee |
|---|---|
| Windows | get_instruction opens the target with FILE_FLAG_OPEN_REPARSE_POINT to avoid reparse-point redirection, inspects handle attributes via GetFileInformationByHandle to reject reparse points and directories, and validates the opened handle's canonical location with GetFinalPathNameByHandleW. Hard links are not detectable with these APIs alone; creating one across the boundary requires elevated privileges under default Windows policies. |
| Unix | symlink_metadata is used to detect and reject symbolic links before opening. A TOCTOU window exists between the metadata call and the open; O_NOFOLLOW-based elimination would require libc/nix. This is the strongest portable protection available in std. |
8.5 Workspace scope
The extension supports one governed project per VS Code window. The workspaceRoot selected during extension activation is the authoritative project root for agent actions, terminal creation, and instruction directory resolution. Mapping multiple governed projects inside one multi-root workspace is explicitly deferred and is not supported by this implementation.
8.6 Cross-language test matrix
TypeScript and Rust independently cover the same configuration validation cases using table-driven tests. Shared cross-language fixture infrastructure is intentionally deferred to a separate governed proposal and is not part of this implementation.
8.7 Configurable launch prompt
The optional root-level prompt field in .vector/agents.yaml controls the message sent to the agent terminal at launch.
Built-in default (used when prompt is absent):
process the instruction <instruction-id> by using the vector mcp
The default references vector mcp and never uses the word server.
Configured prompt — when prompt is present, its value overrides the built-in default:
prompt: "process the instruction <instruction-id> by using the vector mcp"
Placeholder substitution — every <instruction-id> token in the resolved prompt is replaced with the UUID generated for that launch. This applies to both the built-in default and any configured prompt. A configured prompt that omits the placeholder is sent verbatim; it cannot reference the generated instruction UUID.
Validation — prompt must be a string. A non-string value (number, boolean, mapping, …) fails validation with an actionable error toast before any terminal is created.
Backward compatibility — existing agents.yaml files that omit prompt continue to launch agents using the built-in default without any modification.
9. Changelog
1.5.0
- Instruction Capability (Breaking) — Replaces the
<file>path handoff with a UUID-scoped instruction file and the<instruction>placeholder..vector/agents.yamlmust declareinstructions-dir: "${system-temp}/vector/instructions". All agent commands must use<instruction>and must not use the obsolete<file>or<instruction-id>placeholders. The MCP server exposes a newget_instructiontool that reads the instruction file by UUID without exposing paths to the caller. See section 8 for the complete contract, platform guarantees, and migration guide. - Configurable Launch Prompt —
.vector/agents.yamlnow accepts an optional root-levelpromptstring that overrides the built-in default launch message. The<instruction-id>placeholder in the configured or default prompt is replaced with the UUID of each generated instruction at launch time. Existing configurations that omitpromptcontinue to use the built-in default unchanged. See section 8.7.
1.4.5
- Package-Qualified Wikilinks (
[[package/doc-id]]) — Resolve and open governed documents from synchronized package locations under.vector-database/packages/. - Sync Packages Command — Adds a "Sync Packages" action in the tree view title menu that executes
vector-database package syncin a VS Code terminal. - Identifier Parsing — Centralized document identifier parsing supporting both workspace-local (
doc-id) and package-qualified (package/doc-id) forms.
1.4.2
vector-agent-inline-actionblocks — new fence variant that renders an inline overlay collecting extra user context before spawning an agent. An optionalprompt-fieldkey controls the name of the field injected into the agent payload; omitting it falls back to the existingprompt-messagedefault.
1.4.1
- Robust Agent Availability Check — Fixed
isCommandInPathto spawn a login shell subprocess (pwshon Windows,shotherwise) to check command availability in the user's full shell path, supporting user-scoped package managers. - Improved QuickPick Feedback — Replaced silent returns with informative error messages when selecting an unavailable agent from the quick pick list.
1.2.22
- Navigation History Integration — Replaced custom file-open mechanisms with native VS Code document APIs. Workspace navigation buttons (Go Back / Go Forward) and their associated keybindings now work correctly after clicking links or navigating via the sidebar.
- Decommissioned Legacy Preview Controller — Removed the custom
GovernedPreviewControllerin favor of standard VS Code tab and editor management.
1.1.22
- Editable
chat-inputnow runs on a dedicated CodeMirror 6 runtime instead of the legacycontenteditableplus DOM-rewrite loop. - The extension continues to submit plain text for first-iteration agent execution while preserving structured mention metadata for future integrations.
0.9.18
- Syntax highlighting — fenced code blocks with a language identifier are highlighted client-side via
highlight.js. Plain```blocks are unaffected. vector-formblocks — inline forms inside governed documents. Supportsinput(single-line) andchat-inputfields. Editablechat-inputuses a document-viewer-scoped editor with extension-backed@file mentions, Markdown-aware styling, and bounded auto-grow behavior; fields pre-filled via#{}substitution remain read-only. All forms in a document are collected when any action is triggered; later fields override earlier ones for the same key.vector-open-docblocks — trigger link that opens a target document in the preview panel and performs#{}variable substitution before rendering. The source document is never modified on disk.vector-agent-buttonandvector-agent-actionblocks — trigger CLI agents defined in.vector/agents.yaml. On click, the available agents in the configured profile are presented via VSCode QuickPick. Selecting an agent resolves the prompt file, merges form fields with block-levelinput(form overrides static values), writes a temp file, replaces every<file>placeholder in the configured agent command with that temp file path, and spawns a named VSCode terminal running the resolved command. Unresolved#{}variables produce a warning. Temp files are cleaned up on terminal close or extension deactivation.
10. Non-Goals and Future Work
- Rich-text or WYSIWYG editing is intentionally out of scope.
- Full live preview for arbitrary editor navigation is not required.
- Additional preview history or richer reader interactions should come from follow-up RFCs.