diff --git a/.context/DECISIONS.md b/.context/DECISIONS.md index 32f8590b1..2f0f6bdc5 100644 --- a/.context/DECISIONS.md +++ b/.context/DECISIONS.md @@ -3,6 +3,7 @@ | Date | Decision | |----|--------| +| 2026-05-11 | Embedded and separately-published harnesses use distinct CI and release pipelines | | 2026-05-11 | Embedded foreign-language assets under internal/assets/ are intentional, not a smell | | 2026-05-10 | Placeholder overrides use EXTEND not REPLACE semantics | | 2026-05-10 | Editorial constitution at .context/ingest/KB-RULES.md, not CONSTITUTION.md | @@ -139,6 +140,20 @@ For significant decisions: --> +## [2026-05-11-211246] Embedded and separately-published harnesses use distinct CI and release pipelines + +**Status**: Accepted + +**Context**: ctx ships two kinds of artifact. Embedded harnesses (OpenCode plugin, Copilot CLI scripts, Claude/OpenCode/Copilot CLI skills, git trace hooks, etc.) live under internal/assets/, are //go:embed'd into the ctx Go binary, and reach users via 'ctx setup' writing their bytes to disk. Separately-published harnesses (currently just the VS Code extension under editors/vscode/) build to their own artifact (.vsix), publish to a third-party channel (VS Code Marketplace under publisher 'activememory'), version independently, and reach users via that channel's update mechanism. Until this session, the boundary was implicit: doc.go and embed_test.go talked only about the embedded tree; release.yml only built the Go binary; nothing in CI exercised the vscode extension at all. A reviewer's first read of internal/assets/integrations/ was 'this is a dumping ground' precisely because the contract was not documented. + +**Decision**: Embedded and separately-published harnesses use distinct CI and release pipelines + +**Rationale**: Conflating the two would have one of two consequences: (a) shoehorning vscode into //go:embed, which means baking a .vsix or its sources into the Go binary and writing them out at setup time -- bloating the binary with bytes most users never use, and forcing the Go release cadence onto something with its own marketplace cadence; or (b) leaving the vscode harness ungated 'because it's different' -- which is what we had, and which is how typos ship. The right move is to acknowledge the two patterns are first-class peers, give each a documented home (internal/assets/ vs. editors//), and gate each in CI with the toolchain appropriate to its release pipeline (Go test/build/vet for embedded; npm ci + esbuild + tsc for vscode). Future harnesses pick a pattern explicitly at placement time rather than drifting. + +**Consequence**: internal/assets/README.md now carries the 'Embedded vs. Separately-Published: At a Glance' table as the canonical reference. .github/workflows/ci.yml gained a vscode-extension job that gates the marketplace publish path. editors/vscode/README.md gained a 'Release' section with checklist and explicit notes on which CI gates protect the manual vsce publish. The two patterns are now first-class: a new harness must declare which it follows before placing files. Open implications: (1) anyone proposing to lift integrations/ out of internal/assets/ should re-read this decision -- the no-../ //go:embed constraint plus the pattern-asymmetry are the load-bearing reasons against; (2) the embedded-only quality gaps tracked in TASKS.md (shellcheck, PSScriptAnalyzer, skill frontmatter validity) and the separately-published quality gaps (vscode test rot, lint, vsce package dry-run) live in distinct gap-task clusters and should not be merged. Spec: specs/internal-assets-readme.md. + +--- + ## [2026-05-11-000000] Embedded foreign-language assets under internal/assets/ are intentional, not a smell **Status**: Accepted diff --git a/.context/LEARNINGS.md b/.context/LEARNINGS.md index 662b4cc7a..a714e472d 100644 --- a/.context/LEARNINGS.md +++ b/.context/LEARNINGS.md @@ -17,6 +17,7 @@ DO NOT UPDATE FOR: | Date | Learning | |----|--------| +| 2026-05-11 | tsc cross-tree include resolves node_modules from source file, not tsconfig | | 2026-05-10 | Go compile/tool version mismatch comes from the cached toolchain, not the system Go | | 2026-05-10 | An ongoing user's concrete workaround tax is the strongest validation evidence | | 2026-05-10 | Lift renames alongside features when borrowing from battle-tested external designs | @@ -140,6 +141,16 @@ DO NOT UPDATE FOR: --- +## [2026-05-11-202124] tsc cross-tree include resolves node_modules from source file, not tsconfig + +**Context**: Set up tsc --noEmit gate for the embedded OpenCode plugin. tsconfig lived in tools/typecheck/opencode/; include pointed at internal/assets/integrations/opencode/plugin/index.ts via relative path. First run failed with 'Cannot find module @opencode-ai/plugin' even though node_modules was correctly populated in tools/typecheck/opencode/. + +**Lesson**: When tsconfig.json sits in dir A but its 'include' points at .ts files in dir B, tsc resolves node_modules by walking up from each source file's location (dir B), NOT from the tsconfig's location (dir A). With moduleResolution: bundler the behavior is the same. The 'node_modules' that ships in dir A is invisible to a source file in a distant dir B. + +**Application**: For any cross-tree tsc setup (typecheck gate for embedded source elsewhere in the repo, monorepo-style references, etc.), add explicit baseUrl + paths to the tsconfig. Example: baseUrl: '.', paths: { '@opencode-ai/plugin': ['./node_modules/@opencode-ai/plugin/dist/index.d.ts'], '@opencode-ai/plugin/*': ['./node_modules/@opencode-ai/plugin/dist/*'] }. Add typeRoots ['./node_modules/@types', './node_modules'] for good measure. The cost is some manual path mapping; the benefit is that node_modules can live wherever the tooling does, not next to the source. + +--- + ## [2026-05-10-181418] Go compile/tool version mismatch comes from the cached toolchain, not the system Go **Context**: Hit 'compile: version "go1.26.1" does not match go tool version "go1.26.2"' on every go build / go test / make lint, even with my changes stashed out. System Go was 1.26.2 (healthy); go.mod pinned 1.26.1, so Go's auto-toolchain feature had downloaded 1.26.1 to ~/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.1.darwin-arm64/. That cached toolchain was internally inconsistent: its compile binary and stdlib export data disagreed on version. diff --git a/.context/TASKS.md b/.context/TASKS.md index 5bf98cb20..340797975 100644 --- a/.context/TASKS.md +++ b/.context/TASKS.md @@ -27,17 +27,19 @@ TASK STATUS LABELS: ## Phase 0 Grounding -- [-] Add TypeScript type-check step (bunx tsc --noEmit) for embedded +- [x] Add TypeScript type-check step (`tsc --noEmit`) for embedded editor-plugin assets to CI; nothing currently - checks .opencode/plugins/ctx/index.ts before embedding - #priority:low #added:2026-04-26-152912 #skipped:2026-05-11 reason: - scope redirected — investigation produced - specs/internal-assets-readme.md and `internal/assets/README.md` - documenting the embed contract; original work respawned into four - discrete gap tasks below (TS type-check, shellcheck, - PSScriptAnalyzer, skill frontmatter validation). - -- [ ] Add TypeScript `tsc --noEmit` gate for the embedded OpenCode + checks `.opencode/plugins/ctx/index.ts` before embedding + #priority:low #added:2026-04-26-152912 #completed:2026-05-11 + Implementation: `tools/typecheck/opencode/` (package.json, + tsconfig.json, README, package-lock.json); CI job + `typecheck-opencode-plugin` in `.github/workflows/ci.yml`; embed + contract documented in `internal/assets/README.md` and decision + recorded 2026-05-11. Investigation also surfaced three + related-but-distinct gap tasks (shellcheck, PSScriptAnalyzer, + skill frontmatter validation) listed below. + +- [-] Add TypeScript `tsc --noEmit` gate for the embedded OpenCode plugin (`internal/assets/integrations/opencode/plugin/index.ts`). Place tooling (`package.json`, `tsconfig.json`) in a sibling directory outside `internal/assets/` so it does not pollute the @@ -45,6 +47,11 @@ TASK STATUS LABELS: then `bunx tsc --noEmit`. Spec: respawn from `specs/internal-assets-readme.md` open work. #priority:low #added:2026-05-11 #grounding-gap + #skipped:2026-05-11 reason: duplicate of original line-30 task + above, which has now been completed end-to-end. CI uses `npm ci` + + `npx tsc --noEmit` (matching the existing `editors/vscode/` + convention) rather than Bun; `tsc` is the same compiler either + way and `@types/bun` provides Bun globals to the type-checker. - [ ] Add `shellcheck` gate for embedded shell scripts (`internal/assets/integrations/copilot-cli/scripts/*.sh` and @@ -65,6 +72,51 @@ TASK STATUS LABELS: `internal/assets/read/skill/`. #priority:medium #added:2026-05-11 #grounding-gap +- [x] Add CI guardrails for the VS Code extension at + `editors/vscode/` (separately-published deliverable, ships via + VS Code Marketplace under publisher `activememory`, not embedded + into the ctx binary). CI job `vscode-extension` runs `npm ci`, + `npm run build` (esbuild bundle), and `npx tsc --noEmit + -p tsconfig.ci.json` (production code only; test file excluded + pending separate fix). README docs added: `internal/assets/README.md` + gained an "Embedded vs. Separately-Published" comparison; the + extension's own README gained a "Release" section documenting + the manual `vsce publish` flow and the CI gates that protect it. + #priority:medium #added:2026-05-11 #completed:2026-05-11 + #grounding-gap + +- [x] Close VS Code documentation parity gap: ctx had a dedicated + `docs/home/opencode.md` (185 lines) and `site/home/opencode/` + published page, but no equivalent for VS Code — the extension + was reduced to a 24-line install snippet inside + `docs/operations/integrations.md` plus the marketplace README. + A docs-site reader had no path to day-to-day usage. Created + `docs/home/vscode.md` mirroring the opencode page shape + (problem, setup, what gets created, automatic hooks, + status bar, slash commands by category, natural language, + auto-bootstrap, prerequisites, configuration, troubleshooting, + verification, what's next). Registered in `zensical.toml`'s + "Get Started" nav. Expanded the integrations.md VS Code + subsection to point at the new home page and added a + parallel "First-Class Citizen" block in + `docs/recipes/multi-tool-setup.md`. #priority:medium + #added:2026-05-11 #completed:2026-05-11 #grounding-gap + +- [ ] Fix `editors/vscode/src/extension.test.ts` type errors and + re-enable test-file type-checking + vitest in CI. Two distinct + bugs: (1) tests import handlers (`handleComplete`, `handleTasks`, + `handleRemind`, `handlePad`, `handleNotify`, `handleSystem`, + `handleSpec`) that are no longer exported from `extension.ts` + (only `activate` and `deactivate` are exported now) — the test + suite is rotting against the actual extension surface; (2) the + `fakeToken` helper's `onCancellationRequested` mock signature + is `(cb: () => void) => …` but the VS Code API expects + `(e: any) => any` with at least one argument. Once fixed, + remove the `tsconfig.ci.json` carve-out and add `npm test` to + the `vscode-extension` CI job. Also worth adding `npm run lint` + (eslint) and a `vsce package` dry-run step. + #priority:medium #added:2026-05-11 #grounding-gap + - [ ] The target project (to be given to the Agent) has a good "phasing" mechanism for tasks; implement that; maybe `ctx task add` can have a `--phase` flag too, and we can have a auditor/normalizer for the current diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14d983f68..e121b1b10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,3 +66,51 @@ jobs: with: version: v2.11.4 args: --timeout=5m + + typecheck-opencode-plugin: + name: Typecheck OpenCode plugin + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: tools/typecheck/opencode/package-lock.json + + - name: Install dependencies + working-directory: tools/typecheck/opencode + run: npm ci + + - name: Type-check embedded plugin + working-directory: tools/typecheck/opencode + run: npx tsc --noEmit + + vscode-extension: + name: VS Code extension build + typecheck + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: editors/vscode/package-lock.json + + - name: Install dependencies + working-directory: editors/vscode + run: npm ci + + - name: Bundle (esbuild) + working-directory: editors/vscode + run: npm run build + + - name: Type-check production code + working-directory: editors/vscode + run: npx tsc --noEmit -p tsconfig.ci.json diff --git a/.gitignore b/.gitignore index 8096cef53..ae5056d24 100644 --- a/.gitignore +++ b/.gitignore @@ -71,6 +71,9 @@ editors/vscode/node_modules/ editors/vscode/dist/ editors/vscode/*.vsix +# Type-check tooling for embedded plugins +tools/typecheck/opencode/node_modules/ + # Some ideas are best kept hidden. ideas .context/.ctx.key diff --git a/docs/home/vscode.md b/docs/home/vscode.md new file mode 100644 index 000000000..cbb4af0b4 --- /dev/null +++ b/docs/home/vscode.md @@ -0,0 +1,234 @@ +--- +# / ctx: https://ctx.ist +# ,'`./ do you remember? +# `.,'\ +# \ Copyright 2026-present Context contributors. +# SPDX-License-Identifier: Apache-2.0 + +title: "ctx for VS Code" +icon: lucide/code-2 +--- + +![ctx](../images/ctx-banner.png) + +## The Problem + +Every Copilot Chat session in VS Code starts from zero. You re-explain +what you were doing, the AI repeats yesterday's mistakes, and decisions +you spent an hour reasoning through last week get rediscovered instead +of remembered. + +**Without ctx:** + +``` +@workspace add the validation middleware we discussed + +I don't have context about previous discussions. Could you describe +what validation middleware you're referring to? +``` + +**With ctx:** + +``` +@ctx Do you remember? + +Last session (2026-05-09): you decided on Zod schemas at the route level +(DECISIONS.md #12). Pattern lives in CONVENTIONS.md. Open task: wire +the auth middleware into the new /admin routes (TASKS.md, in-progress). +The reference implementation is src/middleware/auth.ts. +``` + +That's the whole pitch: **your AI remembers**, right inside the IDE you +already work in. + +## Setup + +Install the extension and the `ctx` binary, then `ctx init` your project: + +1. **Install the extension** from the + [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=activememory.ctx-context) + (publisher: `activememory`, display name: *ctx — Persistent Context + for AI*). Or build from source (see + [editors/vscode/README.md](https://github.com/ActiveMemory/ctx/blob/main/editors/vscode/README.md#development)). +2. **Install the ctx CLI** if you haven't already + ([installation docs](getting-started.md#installation)). If you skip + this step, the extension will auto-download the right binary for + your platform on first use (see [Auto-Bootstrap](#auto-bootstrap) + below). +3. **From your project root**, run: + + ```bash + ctx init && eval "$(ctx activate)" + ``` + +4. **Open Copilot Chat** in VS Code and type `@ctx /init` to verify + the extension can reach the CLI. + +### What Gets Created + +| File | Purpose | +|------|---------| +| `.context/` | Project-local context directory (created by `ctx init`) | +| `.github/copilot-instructions.md` | Repository instructions Copilot reads natively; regenerated automatically whenever `.context/` files change | + +The extension itself lives in VS Code's extension storage. No project +files are added beyond `.context/` and the Copilot instructions. + +## How You Use It + +Type `@ctx` in the Copilot Chat view to invoke the chat participant. +Then either: + +- **Use a slash command:** `@ctx /status`, `@ctx /wrapup`, etc. There + are 45 commands; the most common ones live in the [Slash Commands](#slash-commands) + table below. +- **Use natural language:** `@ctx what should I work on?` routes to + `/next`; `@ctx time to wrap up` routes to `/wrapup`. See + [Natural Language](#natural-language). + +The extension shows context-aware follow-up suggestions after each +command. For example, after `/init` you'll see buttons for "Show +status" or "Generate copilot integration." + +## What Happens Automatically + +The extension registers several VS Code event handlers that mirror +Claude Code's hook system. These run in the background; no user action +needed. + +| Trigger | What fires | +|---------|------------| +| **File save** | Task-completion check on non-`.context/` files | +| **Git commit** | Notification prompting to add a Decision, Learning, run `/verify`, or Skip | +| **`.context/` file change** | Refreshes pending reminders and regenerates `.github/copilot-instructions.md` | +| **Dependency file change** | When `go.mod`, `package.json`, etc. change, prompts to refresh the dependency map (`/map`) | +| **Every 5 minutes** | Updates the reminder status-bar item and writes a heartbeat timestamp | +| **Extension activate** | Fires `ctx system session-event --type start` | +| **Extension deactivate** | Fires `ctx system session-event --type end` | + +### Status Bar + +A `$(bell) ctx` indicator appears in the status bar when you have +pending reminders. It refreshes every 5 minutes and hides itself when +nothing is due. + +## Slash Commands + +The extension surfaces 45 commands across six categories. The most +commonly used: + +### Core Context + +| Command | When to use | +|---------|-------------| +| `/init` | Initialize a `.context/` directory with template files | +| `/status` | Token estimate, file count, what's recent | +| `/agent` | Print AI-ready context packet | +| `/drift` | Detect stale paths, missing files, dead references | +| `/recall` | Browse and search prior AI session history | +| `/add` | Add a task, decision, learning, or convention | + +### Session Lifecycle + +| Command | When to use | +|---------|-------------| +| `/wrapup` | End-of-session ceremony: status, drift, journal audit | +| `/remember` | Structured readback (trigger: "Do you remember?") from tasks, decisions, learnings, recent journal | +| `/reflect` | Surface items worth persisting as decisions or learnings | +| `/pause` / `/resume` | Save and restore session state for later | + +### Discovery & Planning + +| Command | When to use | +|---------|-------------| +| `/brainstorm` | Browse and develop ideas from `ideas/` | +| `/spec` | List or scaffold feature specs from templates | +| `/verify` | Run verification (doctor + drift) | +| `/map` | Show dependency map (go.mod, package.json) | + +Full list (with maintenance, audit, metadata, and system commands) is +in [editors/vscode/README.md](https://github.com/ActiveMemory/ctx/blob/main/editors/vscode/README.md#slash-commands). + +## Natural Language + +Plain English after `@ctx` is routed to the right command: + +- "What should I work on next?" → `/next` +- "Time to wrap up" → `/wrapup` +- "Show me the status" → `/status` +- "Add a decision" → `/add` +- "Check for drift" → `/drift` + +If the phrase doesn't match a known pattern, the extension surfaces a +short menu of likely matches. + +## Auto-Bootstrap + +If the ctx CLI isn't on PATH (or at a path configured via +`ctx.executablePath`), the extension auto-downloads the right binary: + +1. Detects OS and architecture (darwin / linux / windows, amd64 / arm64). +2. Fetches the latest release from + [GitHub Releases](https://github.com/ActiveMemory/ctx/releases). +3. Downloads and verifies the matching binary. +4. Caches it in VS Code's global storage directory. + +Subsequent sessions reuse the cached binary. To pin a specific version, +set `ctx.executablePath` in your VS Code settings. + +## Prerequisites + +- **VS Code 1.93+** +- **[GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat)** extension +- **ctx CLI** on PATH, or let the extension auto-download it + +## Configuration + +| Setting | Default | Description | +|---------|---------|-------------| +| `ctx.executablePath` | `ctx` | Path to the ctx CLI binary. Set this if ctx isn't on PATH and you don't want auto-download. | + +## Refreshing the Integration + +The extension updates through the VS Code Marketplace like any other +extension; install new versions via the Extensions view. Updates to +the **ctx CLI** are independent: bump it via your package manager, or +let the auto-bootstrap fetch the latest release. + +Unlike the OpenCode integration, there is **no `ctx setup` step** for +VS Code. The extension carries its own runtime; ctx's role is only to +provide the CLI it shells out to. + +## Troubleshooting + +| Symptom | Cause | Fix | +|---------|-------|-----| +| `@ctx` participant doesn't appear in Copilot Chat | Copilot Chat not installed or not signed in | Install [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat) and ensure you're signed in to a Copilot-eligible account | +| `@ctx /status` says ctx not found | CLI not on PATH and auto-download disabled | Either add ctx to PATH (`brew install activememory/tap/ctx` or download from [Releases](https://github.com/ActiveMemory/ctx/releases)), or unset `ctx.executablePath` to let the extension auto-download | +| Status-bar reminder never updates | Heartbeat suppressed or `.context/` doesn't exist | Run `ctx init` from your project root; reload VS Code if the indicator still doesn't appear within 5 minutes | +| Commands run but nothing is captured to `.context/` | Workspace folder missing or `.context/` outside the open folder | Make sure your project root (the one with `.context/`) is the workspace root, not a subdirectory of it | + +## Verify It Works + +Open Copilot Chat and ask: + +``` +@ctx Do you remember? +``` + +You should see a structured readback citing specific tasks, decisions, +and recent session topics. If you instead see "I don't have memory" or +"Let me check," something went wrong: confirm the CLI is reachable +(`@ctx /system doctor`) and `.context/` has files in it. + +## What's Next + +- [Your First Session](first-session.md): step-by-step walkthrough from + `ctx init` to verified recall. +- [Common Workflows](common-workflows.md): day-to-day commands for + tracking context, checking health, and browsing history. +- [Context Files](context-files.md): what lives in `.context/` and how + each file is used. +- [Setup across AI Tools](../recipes/multi-tool-setup.md): wiring ctx + for Claude Code, OpenCode, Cursor, Aider, Copilot, or Windsurf + alongside VS Code. diff --git a/docs/operations/integrations.md b/docs/operations/integrations.md index 6808d9a8d..f5b0ae952 100644 --- a/docs/operations/integrations.md +++ b/docs/operations/integrations.md @@ -475,57 +475,52 @@ to regenerate the instructions. ### VS Code Chat Extension (`@ctx`) The **ctx VS Code extension** adds a `@ctx` chat participant to -GitHub Copilot Chat, giving you direct access to all context commands -from within the editor. +GitHub Copilot Chat, giving you direct access to 45 context commands +from within the editor, plus automatic hooks on file save / git commit / +`.context/` changes / dependency-file edits, and a reminder status-bar +indicator. + +!!! tip "Full guide: [ctx for VS Code](../home/vscode.md)" + The home-page guide covers daily workflows, the full command list, + natural-language routing, auto-bootstrap of the ctx CLI, troubleshooting, + and "Verify It Works." This subsection is the install-and-pointers + overview; the dedicated page is the authoritative reference. #### Installation -1. Build from source (requires Node.js 18+): +The extension ships to the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=activememory.ctx-context) +under publisher `activememory` (display name: *ctx — Persistent Context +for AI*). Install via the Extensions view or `code --install-extension`. + +To build from source instead (requires Node.js 20+): ```bash cd editors/vscode -npm install +npm ci npm run build npx @vscode/vsce package +code --install-extension ctx-context-.vsix ``` -2. Install the `.vsix` file: +Reload VS Code. Type `@ctx` in Copilot Chat to verify. -```bash -code --install-extension ctx-context-0.8.1.vsix -``` +#### What Gets Created -3. Reload VS Code. Type `@ctx` in Copilot Chat to verify. - -#### Slash Commands - -| Command | Description | -|-----------------|------------------------------------------------------| -| `@ctx /init` | Initialize `.context/` directory with template files | -| `@ctx /status` | Show context summary with token estimate | -| `@ctx /agent` | Print AI-ready context packet | -| `@ctx /drift` | Detect stale or invalid context | -| `@ctx /journal` | Browse and search AI session history | -| `@ctx /hook` | Generate AI tool integration configs | -| `@ctx /add` | Add a task, decision, or learning | -| `@ctx /load` | Output assembled context Markdown | -| `@ctx /compact` | Archive completed tasks and clean up | -| `@ctx /sync` | Reconcile context with codebase | +| File | Purpose | +|------|---------| +| `.context/` | Project-local context directory (created by `ctx init`, not by the extension) | +| `.github/copilot-instructions.md` | Repository instructions Copilot reads natively; regenerated automatically when `.context/` files change | -#### Usage Examples +The extension itself lives in VS Code's extension storage; no project +files beyond `.context/` and the Copilot instructions are added. -```text -@ctx /init -@ctx /status -@ctx /add task Implement user authentication -@ctx /drift -@ctx /hook copilot -@ctx /journal -``` +#### How It Works -Typing `@ctx` without a command shows help with all available commands. -The extension also supports natural language: asking `@ctx` about -"status" or "drift" routes to the correct command automatically. +- **Chat participant:** `@ctx` is registered with VS Code's Chat API; 45 slash commands route to dedicated handlers that shell out to the ctx CLI. +- **Automatic hooks:** file save → task-completion check; git commit → decision/learning prompt; `.context/` change → regenerate Copilot instructions; dependency-file change → `/map` prompt. +- **Status-bar reminder:** a `$(bell) ctx` indicator surfaces pending session reminders, refreshing every 5 minutes. +- **Natural language:** plain English after `@ctx` is routed to the nearest matching command. +- **Auto-bootstrap:** if the ctx CLI isn't on PATH, the extension downloads the correct platform binary from GitHub Releases and caches it. #### Configuration @@ -533,12 +528,6 @@ The extension also supports natural language: asking `@ctx` about |----------------------|---------|------------------------------------------------------------------| | `ctx.executablePath` | `ctx` | Path to the ctx binary. Set this if `ctx` is not in your `PATH`. | -#### Follow-Up Suggestions - -After each command, the extension suggests relevant next steps. For -example, after `/init` it suggests `/status` and `/hook`; after -`/drift` it suggests `/sync`. - ### Session Persistence `ctx init` creates a `.context/sessions/` directory for storing diff --git a/docs/recipes/multi-tool-setup.md b/docs/recipes/multi-tool-setup.md index f392683cd..107d3f3b1 100644 --- a/docs/recipes/multi-tool-setup.md +++ b/docs/recipes/multi-tool-setup.md @@ -185,6 +185,28 @@ registers the ctx MCP server globally. See automatically. Context loads at session start, survives compaction, and persists at session end — no manual steps needed. +#### VS Code + +Install the **ctx** extension from the +[VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=activememory.ctx-context) +(publisher: `activememory`). Then, from your project root: + +```bash +ctx init && eval "$(ctx activate)" +``` + +Open Copilot Chat and type `@ctx /init` to verify. The extension +auto-downloads the ctx CLI if it isn't on PATH. See +[ctx for VS Code](../home/vscode.md) for full details. + +!!! tip "VS Code Is a First-Class Citizen" + The extension carries its own runtime. No `ctx setup` step is + needed. It registers a `@ctx` chat participant with 45 slash + commands, automatic hooks (file save, git commit, `.context/` + change, dependency-file edit), and a reminder status-bar + indicator. Unlike embedded harnesses, the extension ships + through its own pipeline to the VS Code Marketplace. + #### Cursor Add the system prompt snippet to `.cursor/settings.json`: diff --git a/editors/vscode/README.md b/editors/vscode/README.md index c940276f1..f23883738 100644 --- a/editors/vscode/README.md +++ b/editors/vscode/README.md @@ -210,6 +210,60 @@ mock. They verify: - Follow-up suggestions are returned after commands - Edge cases: missing workspace, cancellation, empty output +> **Note**: the test file currently has unresolved type errors +> (handler imports that no longer exist on `extension.ts`, and +> a `CancellationToken` mock with an out-of-date signature). The +> tests still run under vitest's loose runtime, but `tsc` against +> them fails. Tracked in TASKS.md; until fixed, the CI gate uses +> `tsconfig.ci.json` which excludes `**/*.test.ts`. + +## Release + +This extension is **published separately from the ctx Go binary**. +It does *not* ride along with `release.yml`. The release pipeline +is intentionally manual: a maintainer runs `vsce publish` from a +clean checkout against the `activememory` publisher account. + +CI guardrails that protect this manual publish (`vscode-extension` +job in `.github/workflows/ci.yml`) run on every PR and push to +`main`: + +- `npm ci`: clean dependency install from the committed lockfile. +- `npm run build`: esbuild bundles `src/extension.ts` to + `dist/extension.js`. Catches bundler errors and missing imports + at the JavaScript level. +- `npx tsc --noEmit -p tsconfig.ci.json`: type-checks the + production source (`src/**/*.ts` minus test files). Catches type + errors that esbuild silently passes through. + +What CI does **not** gate yet (known gaps): + +- **Tests** (`npm test`, vitest). The suite has type errors + unrelated to the production code; until they're fixed, gating + on vitest would force resolving them before any merge. +- **Lint** (`npm run lint`, eslint). +- **Publish dry-run** (`vsce package` to produce the `.vsix` + artifact without uploading). Worth adding once the test gate + is back. + +Release checklist for a maintainer: + +1. Bump `version` in `editors/vscode/package.json`. +2. Update `editors/vscode/CHANGELOG.md`. +3. Push to a branch, open PR. The `vscode-extension` CI job must + pass on the PR head. +4. After merge, from a clean checkout of `main`: + ```bash + cd editors/vscode + npm ci + npm run build + npx vsce package + npx vsce publish # requires VS Code Marketplace token + ``` +5. Tag the release commit and push the tag (the ctx-binary release + workflow keys on `v*` tags; the extension's tag does not need + to match, but keeping them in lockstep simplifies support). + ## License Apache-2.0 diff --git a/editors/vscode/package-lock.json b/editors/vscode/package-lock.json index 1fb53dcab..b2b975b7e 100644 --- a/editors/vscode/package-lock.json +++ b/editors/vscode/package-lock.json @@ -12,7 +12,7 @@ "@types/node": "^20.0.0", "@types/vscode": "^1.93.0", "@vscode/vsce": "^3.7.1", - "esbuild": "^0.25.12", + "esbuild": "^0.28.0", "typescript": "^5.6.0", "vitest": "^4.0.18" }, @@ -278,9 +278,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", "cpu": [ "ppc64" ], @@ -295,9 +295,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", "cpu": [ "arm" ], @@ -312,9 +312,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", "cpu": [ "arm64" ], @@ -329,9 +329,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", "cpu": [ "x64" ], @@ -346,9 +346,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", "cpu": [ "arm64" ], @@ -363,9 +363,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", "cpu": [ "x64" ], @@ -380,9 +380,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", "cpu": [ "arm64" ], @@ -397,9 +397,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", "cpu": [ "x64" ], @@ -414,9 +414,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", "cpu": [ "arm" ], @@ -431,9 +431,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", "cpu": [ "arm64" ], @@ -448,9 +448,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", "cpu": [ "ia32" ], @@ -465,9 +465,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", "cpu": [ "loong64" ], @@ -482,9 +482,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", "cpu": [ "mips64el" ], @@ -499,9 +499,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", "cpu": [ "ppc64" ], @@ -516,9 +516,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", "cpu": [ "riscv64" ], @@ -533,9 +533,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", "cpu": [ "s390x" ], @@ -550,9 +550,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", "cpu": [ "x64" ], @@ -567,9 +567,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", "cpu": [ "arm64" ], @@ -584,9 +584,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", "cpu": [ "x64" ], @@ -601,9 +601,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", "cpu": [ "arm64" ], @@ -618,9 +618,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", "cpu": [ "x64" ], @@ -635,9 +635,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", "cpu": [ "arm64" ], @@ -652,9 +652,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", "cpu": [ "x64" ], @@ -669,9 +669,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", "cpu": [ "arm64" ], @@ -686,9 +686,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", "cpu": [ "ia32" ], @@ -703,9 +703,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", "cpu": [ "x64" ], @@ -2542,9 +2542,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2555,32 +2555,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" } }, "node_modules/estree-walker": { diff --git a/editors/vscode/package.json b/editors/vscode/package.json index 7c3065327..664e4dcf9 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -218,7 +218,7 @@ "@types/node": "^20.0.0", "@types/vscode": "^1.93.0", "@vscode/vsce": "^3.7.1", - "esbuild": "^0.25.12", + "esbuild": "^0.28.0", "typescript": "^5.6.0", "vitest": "^4.0.18" } diff --git a/editors/vscode/tsconfig.ci.json b/editors/vscode/tsconfig.ci.json new file mode 100644 index 000000000..49a23bc7d --- /dev/null +++ b/editors/vscode/tsconfig.ci.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "dist", "**/*.test.ts"] +} diff --git a/editors/vscode/tsconfig.json b/editors/vscode/tsconfig.json index 5918f7b23..d5b1354aa 100644 --- a/editors/vscode/tsconfig.json +++ b/editors/vscode/tsconfig.json @@ -14,5 +14,6 @@ "declarationMap": true, "sourceMap": true }, + "include": ["src/**/*"], "exclude": ["node_modules", "dist"] } diff --git a/internal/assets/README.md b/internal/assets/README.md index 8c84345a3..2ca15cd31 100644 --- a/internal/assets/README.md +++ b/internal/assets/README.md @@ -81,9 +81,8 @@ A file belongs under `internal/assets/` if and only if: If a file is meant to be compiled, generated, fetched, linted, type-checked, or transformed before reaching a user, it does -**not** belong here — or, more precisely, only its -post-transformation output does. The directory is a *payload -manifest*, not a workspace. +**not** belong here. More precisely: only its post-transformation +output does. The directory is a *payload manifest*, not a workspace. ### Hard Go Constraint @@ -141,8 +140,7 @@ sibling `read/*/...test.go` files): `.ctxrc` schema parse as YAML/JSON Schema. * **Schema integrity**: `TestSchemaCoversCtxRC` asserts a bidirectional match between `.ctxrc` schema properties and the - Go struct that consumes them — drift in either direction - fails CI. + Go struct that consumes them. Drift in either direction fails CI. * **Spot-content**: targeted substring checks on a handful of representative files (e.g. CLAUDE.md contains "Context", ctx-history SKILL.md contains "history"). @@ -186,8 +184,8 @@ structure. * **Go source** that isn't an accessor for `FS`: put it where its package belongs. -* **Generated documentation**, transient build artifacts, or - caches — these have no business in source control here. +* **Generated documentation**, transient build artifacts, and + caches have no business in source control here. * **Runtime configuration** read from the user's environment (the user's `.ctxrc`, secrets, keys). User-owned state lives outside the binary. @@ -201,6 +199,40 @@ structure. * **Anything fetched or generated at install time.** If it isn't available at `go build`, it doesn't belong in `embed.FS`. +* **Separately-published deliverables.** ctx also ships a + VS Code extension at `editors/vscode/`. It is *not* embedded + into the ctx binary: it is built and published independently + to the VS Code Marketplace under publisher `activememory` + (see `editors/vscode/README.md`, section "Release"). That + artifact has its own version, its own toolchain, and its own + CI gate (`vscode-extension` job in `.github/workflows/ci.yml`). + Anything that ships via a third-party marketplace, package + registry, or other out-of-band channel belongs next to *its* + pipeline, not here. + +--- + +## Embedded vs. Separately-Published: At a Glance + +ctx ships two distinct kinds of artifact, and the rules around +them are not the same: + +| Dimension | Embedded assets (this tree) | Separately-published (e.g. `editors/vscode/`) | +|---|---|---| +| Carrier | the ctx Go binary | `.vsix` to VS Code Marketplace | +| Build pipeline | `go build` | `npm ci` + `esbuild` + `vsce package` | +| Release pipeline | `release.yml` (`./hack/build-all.sh`) | manual `vsce publish` | +| Version | pinned to the ctx release that compiled them | independent `version` in `package.json` | +| Update reaches user via | ctx binary upgrade | VS Code extension update | +| CI gate today | `typecheck-opencode-plugin` (embedded TS only) | `vscode-extension` (build + production tsc) | +| Lives in repo at | `internal/assets/...` | `editors//...` | + +If you are adding a new harness, decide which model it follows +*before* placing files. Embedded harnesses are simpler to ship +(one binary, no extra publish step) but every byte they carry +becomes part of every ctx release. Separately-published +harnesses have their own release cadence and surface, at the +cost of a second pipeline to maintain. --- diff --git a/site/home/about/index.html b/site/home/about/index.html index b24ec8c94..0b16c793c 100644 --- a/site/home/about/index.html +++ b/site/home/about/index.html @@ -942,6 +942,8 @@ + + diff --git a/site/home/common-workflows/index.html b/site/home/common-workflows/index.html index 41906c914..85406ee1d 100644 --- a/site/home/common-workflows/index.html +++ b/site/home/common-workflows/index.html @@ -748,6 +748,8 @@ + + @@ -862,6 +864,36 @@ +
  • + + + + + + + + + + ctx for VS Code + + + + + + + + +
  • + + + + + + + + + +
  • diff --git a/site/home/community/index.html b/site/home/community/index.html index 15368f386..c657bfb47 100644 --- a/site/home/community/index.html +++ b/site/home/community/index.html @@ -906,6 +906,8 @@ + + diff --git a/site/home/configuration/index.html b/site/home/configuration/index.html index e7d1faf37..a0d9e172b 100644 --- a/site/home/configuration/index.html +++ b/site/home/configuration/index.html @@ -746,6 +746,8 @@ + + diff --git a/site/home/context-files/index.html b/site/home/context-files/index.html index 6f49f8cf0..8b47804ea 100644 --- a/site/home/context-files/index.html +++ b/site/home/context-files/index.html @@ -746,6 +746,8 @@ + + diff --git a/site/home/contributing/index.html b/site/home/contributing/index.html index ec617125c..452dfbdfa 100644 --- a/site/home/contributing/index.html +++ b/site/home/contributing/index.html @@ -1295,6 +1295,8 @@ + + diff --git a/site/home/faq/index.html b/site/home/faq/index.html index 1b4289a52..a3d628bb9 100644 --- a/site/home/faq/index.html +++ b/site/home/faq/index.html @@ -991,6 +991,8 @@ + + diff --git a/site/home/first-session/index.html b/site/home/first-session/index.html index 8369badf6..ffe8f6e10 100644 --- a/site/home/first-session/index.html +++ b/site/home/first-session/index.html @@ -15,7 +15,7 @@ - + @@ -748,6 +748,8 @@ + + @@ -860,6 +862,36 @@ + + +
  • + + + + + + + + + + ctx for VS Code + + + + + + + + +
  • + + + + + + + + @@ -2068,7 +2100,7 @@

    What to .gitignore - + diff --git a/site/home/getting-started/index.html b/site/home/getting-started/index.html index d8449499d..a809ee9d1 100644 --- a/site/home/getting-started/index.html +++ b/site/home/getting-started/index.html @@ -748,6 +748,8 @@ + + @@ -1069,6 +1071,36 @@ +
  • + + + + + + + + + + ctx for VS Code + + + + + + + + +
  • + + + + + + + + + +
  • diff --git a/site/home/hub/index.html b/site/home/hub/index.html index 91afd6079..137379d4b 100644 --- a/site/home/hub/index.html +++ b/site/home/hub/index.html @@ -746,6 +746,8 @@ + + diff --git a/site/home/index.html b/site/home/index.html index 490235a9f..785f5ef1c 100644 --- a/site/home/index.html +++ b/site/home/index.html @@ -746,6 +746,8 @@ + + diff --git a/site/home/is-ctx-right/index.html b/site/home/is-ctx-right/index.html index 1f9913df9..340993c7e 100644 --- a/site/home/is-ctx-right/index.html +++ b/site/home/is-ctx-right/index.html @@ -975,6 +975,8 @@ + + diff --git a/site/home/joining-a-project/index.html b/site/home/joining-a-project/index.html index 5aa04c8f6..8dadec180 100644 --- a/site/home/joining-a-project/index.html +++ b/site/home/joining-a-project/index.html @@ -746,6 +746,8 @@ + + diff --git a/site/home/keeping-ai-honest/index.html b/site/home/keeping-ai-honest/index.html index b48964c9c..d6a057c45 100644 --- a/site/home/keeping-ai-honest/index.html +++ b/site/home/keeping-ai-honest/index.html @@ -746,6 +746,8 @@ + + diff --git a/site/home/opencode/index.html b/site/home/opencode/index.html index 1ee2dba19..6971ee2e8 100644 --- a/site/home/opencode/index.html +++ b/site/home/opencode/index.html @@ -18,7 +18,7 @@ - + @@ -748,6 +748,8 @@ + + @@ -1052,6 +1054,36 @@ +
  • + + + + + + + + + + ctx for VS Code + + + + + + + + +
  • + + + + + + + + + +
  • @@ -2242,13 +2274,13 @@

    What's Next +

  • - + - Slash Commands + What Gets Created @@ -1503,10 +1503,10 @@
  • - + - Usage Examples + How It Works @@ -1522,17 +1522,6 @@ -
  • - -
  • - - - - Follow-Up Suggestions - - - -
  • @@ -1591,7 +1580,7 @@
  • - + What Gets Created @@ -1602,7 +1591,7 @@
  • - + How It Works @@ -2522,10 +2511,10 @@
  • - + - Slash Commands + What Gets Created @@ -2533,10 +2522,10 @@
  • - + - Usage Examples + How It Works @@ -2552,17 +2541,6 @@ -
  • - -
  • - - - - Follow-Up Suggestions - - - -
  • @@ -2621,7 +2599,7 @@
  • - + What Gets Created @@ -2632,7 +2610,7 @@
  • - + How It Works @@ -3535,87 +3513,58 @@

    SetupVS Code Chat Extension (@ctx)

    The ctx VS Code extension adds a @ctx chat participant to -GitHub Copilot Chat, giving you direct access to all context commands -from within the editor.

    +GitHub Copilot Chat, giving you direct access to 45 context commands +from within the editor, plus automatic hooks on file save / git commit / +.context/ changes / dependency-file edits, and a reminder status-bar +indicator.

    +
    +

    Full guide: ctx for VS Code

    +

    The home-page guide covers daily workflows, the full command list, +natural-language routing, auto-bootstrap of the ctx CLI, troubleshooting, +and "Verify It Works." This subsection is the install-and-pointers +overview; the dedicated page is the authoritative reference.

    +

    Installation

    -
      -
    1. Build from source (requires Node.js 18+):
    2. -
    +

    The extension ships to the VS Code Marketplace +under publisher activememory (display name: ctx — Persistent Context +for AI). Install via the Extensions view or code --install-extension.

    +

    To build from source instead (requires Node.js 20+):

    cd editors/vscode
    -npm install
    +npm ci
     npm run build
     npx @vscode/vsce package
    +code --install-extension ctx-context-<version>.vsix
     
    -
      -
    1. Install the .vsix file:
    2. -
    -
    code --install-extension ctx-context-0.8.1.vsix
    -
    -
      -
    1. Reload VS Code. Type @ctx in Copilot Chat to verify.
    2. -
    -

    Slash Commands

    +

    Reload VS Code. Type @ctx in Copilot Chat to verify.

    +

    What Gets Created

    - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + +
    CommandDescriptionFilePurpose
    @ctx /initInitialize .context/ directory with template files
    @ctx /statusShow context summary with token estimate
    @ctx /agentPrint AI-ready context packet
    @ctx /driftDetect stale or invalid context
    @ctx /journalBrowse and search AI session history
    @ctx /hookGenerate AI tool integration configs
    @ctx /addAdd a task, decision, or learning
    @ctx /loadOutput assembled context Markdown
    @ctx /compactArchive completed tasks and clean up.context/Project-local context directory (created by ctx init, not by the extension)
    @ctx /syncReconcile context with codebase.github/copilot-instructions.mdRepository instructions Copilot reads natively; regenerated automatically when .context/ files change
    -

    Usage Examples

    -
    @ctx /init
    -@ctx /status
    -@ctx /add task Implement user authentication
    -@ctx /drift
    -@ctx /hook copilot
    -@ctx /journal
    -
    -

    Typing @ctx without a command shows help with all available commands. -The extension also supports natural language: asking @ctx about -"status" or "drift" routes to the correct command automatically.

    +

    The extension itself lives in VS Code's extension storage; no project +files beyond .context/ and the Copilot instructions are added.

    +

    How It Works

    +
      +
    • Chat participant: @ctx is registered with VS Code's Chat API; 45 slash commands route to dedicated handlers that shell out to the ctx CLI.
    • +
    • Automatic hooks: file save → task-completion check; git commit → decision/learning prompt; .context/ change → regenerate Copilot instructions; dependency-file change → /map prompt.
    • +
    • Status-bar reminder: a $(bell) ctx indicator surfaces pending session reminders, refreshing every 5 minutes.
    • +
    • Natural language: plain English after @ctx is routed to the nearest matching command.
    • +
    • Auto-bootstrap: if the ctx CLI isn't on PATH, the extension downloads the correct platform binary from GitHub Releases and caches it.
    • +

    Configuration

    @@ -3633,10 +3582,6 @@

    ConfigurationFollow-Up Suggestions

    -

    After each command, the extension suggests relevant next steps. For -example, after /init it suggests /status and /hook; after -/drift it suggests /sync.

    Session Persistence

    ctx init creates a .context/sessions/ directory for storing session data from non-Claude tools. The Markdown session parser scans @@ -3648,15 +3593,15 @@

    Manual Patterns
    // See .context/CONVENTIONS.md for naming patterns
    -// Following decision in .context/DECISIONS.md: Use PostgreSQL
    -
    -function getUserById(id: string) {
    -  // Copilot now has context
    -}
    +
    // See .context/CONVENTIONS.md for naming patterns
    +// Following decision in .context/DECISIONS.md: Use PostgreSQL
    +
    +function getUserById(id: string) {
    +  // Copilot now has context
    +}
     

    Pattern 3: Paste context into Copilot Chat

    -
    ctx agent --budget 2000
    +
    ctx agent --budget 2000
     

    Paste output into Copilot Chat for context-aware responses.


    @@ -3664,14 +3609,14 @@

    OpenCodeSetup

    -
    # Generate OpenCode plugin, global MCP config, skills, and AGENTS.md
    -ctx setup opencode --write
    -
    -# Initialize context
    -ctx init
    -eval "$(ctx activate)"
    +
    # Generate OpenCode plugin, global MCP config, skills, and AGENTS.md
    +ctx setup opencode --write
    +
    +# Initialize context
    +ctx init
    +eval "$(ctx activate)"
     
    -

    What Gets Created

    +

    What Gets Created

    @@ -3698,7 +3643,7 @@

    What Gets CreatedHow It Works

    +

    How It Works

    The plugin wires OpenCode lifecycle events to ctx system:

    • session.created — warms ctx state in the background (bootstrap + agent packet) so MCP queries are fast on first use
    • @@ -3711,30 +3656,30 @@

      How It WorksThe plugin is a single file with no runtime dependencies — no bun install needed. OpenCode loads it automatically on launch.

      Context Updates

      -
      # Get AI-optimized context packet
      -ctx agent
      -
      -# Check context health
      -ctx status
      +
      # Get AI-optimized context packet
      +ctx agent
      +
      +# Check context health
      +ctx status
       

      Windsurf IDE

      Windsurf supports custom instructions and file-based context.

      Setup

      -
      # Generate Windsurf configuration
      -ctx setup windsurf
      -
      -# Initialize context
      -ctx init
      +
      # Generate Windsurf configuration
      +ctx setup windsurf
      +
      +# Initialize context
      +ctx init
       

      Configuration

      Add to Windsurf settings:

      -
      // Split to multiple lines for readability
      -{
      -  "ai.customInstructions": "Always read .context/CONSTITUTION.md first. 
      -  Check .context/TASKS.md for current work. 
      -  Follow patterns in .context/CONVENTIONS.md."
      -}
      +
      // Split to multiple lines for readability
      +{
      +  "ai.customInstructions": "Always read .context/CONSTITUTION.md first. 
      +  Check .context/TASKS.md for current work. 
      +  Follow patterns in .context/CONVENTIONS.md."
      +}
       

      Usage

      Context files appear in the file tree. Reference them when chatting:

      @@ -3746,45 +3691,45 @@

      UsageGeneric Integration

      For any AI tool that can read files, use these patterns:

      Manual Context Loading

      -
      # Get full context
      -ctx load
      -
      -# Get AI-optimized packet
      -ctx agent --budget 8000
      -
      -# Get specific file
      -cat .context/TASKS.md
      +
      # Get full context
      +ctx load
      +
      +# Get AI-optimized packet
      +ctx agent --budget 8000
      +
      +# Get specific file
      +cat .context/TASKS.md
       

      System Prompt Template

      -
      You are working on a project with persistent context in .context/
      -
      -Before responding:
      -1. Read .context/CONSTITUTION.md - NEVER violate these rules
      -2. Check .context/TASKS.md for current work
      -3. Follow .context/CONVENTIONS.md patterns
      -4. Reference .context/DECISIONS.md for architectural choices
      -
      -When you learn something new, note it for .context/LEARNINGS.md
      -When you make a decision, document it for .context/DECISIONS.md
      +
      You are working on a project with persistent context in .context/
      +
      +Before responding:
      +1. Read .context/CONSTITUTION.md - NEVER violate these rules
      +2. Check .context/TASKS.md for current work
      +3. Follow .context/CONVENTIONS.md patterns
      +4. Reference .context/DECISIONS.md for architectural choices
      +
      +When you learn something new, note it for .context/LEARNINGS.md
      +When you make a decision, document it for .context/DECISIONS.md
       

      Automated Updates

      If your AI tool outputs to a log, use ctx watch:

      -
      # Watch log file for context-update commands
      -your-ai-tool 2>&1 | tee /tmp/ai.log &
      -ctx watch --log /tmp/ai.log
      +
      # Watch log file for context-update commands
      +your-ai-tool 2>&1 | tee /tmp/ai.log &
      +ctx watch --log /tmp/ai.log
       

      The AI can emit updates like:

      -
      <context-update type="complete">implement caching</context-update>
      -<context-update type="learning"
      -  context="Implementing caching layer"
      -  lesson="Important thing learned today"
      -  application="Apply this insight going forward"
      ->Caching Insight</context-update>
      +
      <context-update type="complete">implement caching</context-update>
      +<context-update type="learning"
      +  context="Implementing caching layer"
      +  lesson="Important thing learned today"
      +  application="Apply this insight going forward"
      +>Caching Insight</context-update>
       

      Context Update Commands

      The ctx watch command parses update commands from AI output. Use this format:

      -
      <context-update type="TYPE" [attributes]>Content</context-update>
      +
      <context-update type="TYPE" [attributes]>Content</context-update>
       

      Supported Types

    @@ -3824,25 +3769,25 @@

    Supported TypesSimple Format (Tasks, Conventions, Complete)

    -
    <context-update type="task">Implement rate limiting</context-update>
    -<context-update type="convention">Use kebab-case for files</context-update>
    -<context-update type="complete">rate limiting</context-update>
    +
    <context-update type="task">Implement rate limiting</context-update>
    +<context-update type="convention">Use kebab-case for files</context-update>
    +<context-update type="complete">rate limiting</context-update>
     

    Structured Format (Learnings, Decisions)

    Learnings and decisions support structured attributes for better documentation:

    Learning with full structure:

    -
    <context-update type="learning"
    -  context="Debugging Claude Code hooks"
    -  lesson="Hooks receive JSON via stdin, not environment variables"
    -  application="Parse JSON stdin with the host language (Go, Python, etc.): no jq needed"
    ->Hook Input Format</context-update>
    +
    <context-update type="learning"
    +  context="Debugging Claude Code hooks"
    +  lesson="Hooks receive JSON via stdin, not environment variables"
    +  application="Parse JSON stdin with the host language (Go, Python, etc.): no jq needed"
    +>Hook Input Format</context-update>
     

    Decision with full structure:

    -
    <context-update type="decision"
    -  context="Need a caching layer for API responses"
    -  rationale="Redis is fast, well-supported, and team has experience"
    -  consequence="Must provision Redis infrastructure; team training on Redis patterns"
    ->Use Redis for caching</context-update>
    +
    <context-update type="decision"
    +  context="Need a caching layer for API responses"
    +  rationale="Redis is fast, well-supported, and team has experience"
    +  consequence="Must provision Redis infrastructure; team training on Redis patterns"
    +>Use Redis for caching</context-update>
     

    Learnings require: context, lesson, application attributes. Decisions require: context, rationale, consequence attributes. diff --git a/site/recipes/multi-tool-setup/index.html b/site/recipes/multi-tool-setup/index.html index d6ad9287c..29b4a5ee1 100644 --- a/site/recipes/multi-tool-setup/index.html +++ b/site/recipes/multi-tool-setup/index.html @@ -968,6 +968,17 @@ + + +

  • + + + + VS Code + + + +
  • @@ -2020,6 +2031,17 @@ +
  • + +
  • + + + + VS Code + + + +
  • @@ -2465,43 +2487,61 @@

    OpenCodeVS Code

    +

    Install the ctx extension from the +VS Code Marketplace +(publisher: activememory). Then, from your project root:

    +
    ctx init && eval "$(ctx activate)"
    +
    +

    Open Copilot Chat and type @ctx /init to verify. The extension +auto-downloads the ctx CLI if it isn't on PATH. See +ctx for VS Code for full details.

    +
    +

    VS Code Is a First-Class Citizen

    +

    The extension carries its own runtime. No ctx setup step is +needed. It registers a @ctx chat participant with 45 slash +commands, automatic hooks (file save, git commit, .context/ +change, dependency-file edit), and a reminder status-bar +indicator. Unlike embedded harnesses, the extension ships +through its own pipeline to the VS Code Marketplace.

    +

    Cursor

    Add the system prompt snippet to .cursor/settings.json:

    -
    {
    -  "ai.systemPrompt": "Read .context/TASKS.md and .context/CONVENTIONS.md before responding. Follow rules in .context/CONSTITUTION.md."
    -}
    +
    {
    +  "ai.systemPrompt": "Read .context/TASKS.md and .context/CONVENTIONS.md before responding. Follow rules in .context/CONSTITUTION.md."
    +}
     

    Context files appear in Cursor's file tree. You can also paste a context packet directly into chat:

    -
    ctx agent --budget 4000 | xclip    # Linux
    -ctx agent --budget 4000 | pbcopy   # macOS
    +
    ctx agent --budget 4000 | xclip    # Linux
    +ctx agent --budget 4000 | pbcopy   # macOS
     

    Aider

    Create .aider.conf.yml so context files are loaded on every session:

    -
    read:
    -  - .context/CONSTITUTION.md
    -  - .context/TASKS.md
    -  - .context/CONVENTIONS.md
    -  - .context/DECISIONS.md
    +
    read:
    +  - .context/CONSTITUTION.md
    +  - .context/TASKS.md
    +  - .context/CONVENTIONS.md
    +  - .context/DECISIONS.md
     

    Then start Aider normally:

    -
    aider
    +
    aider
     

    Or specify files on the command line:

    -
    aider --read .context/TASKS.md --read .context/CONVENTIONS.md
    +
    aider --read .context/TASKS.md --read .context/CONVENTIONS.md
     

    Step 3: Set Up Shell Completion

    Shell completion lets you tab-complete ctx subcommands and flags, which is especially useful while learning the CLI.

    -
    # Bash (add to ~/.bashrc)
    -source <(ctx completion bash)
    -
    -# Zsh (add to ~/.zshrc)
    -source <(ctx completion zsh)
    -
    -# Fish
    -ctx completion fish > ~/.config/fish/completions/ctx.fish
    +
    # Bash (add to ~/.bashrc)
    +source <(ctx completion bash)
    +
    +# Zsh (add to ~/.zshrc)
    +source <(ctx completion zsh)
    +
    +# Fish
    +ctx completion fish > ~/.config/fish/completions/ctx.fish
     

    After sourcing, typing ctx a<TAB> completes to ctx agent, and ctx journal <TAB> shows list, show, and export.

    @@ -2521,12 +2561,12 @@

    Step 4: Verify the Setup Worksdo you remember?" check verifies both halves: recall and responsibility.

    For example, after resolving a tricky bug, a proactive agent might say:

    -
    That Redis timeout issue was subtle. Want me to save this as a *learning*
    -so we don't hit it again?
    +
    That Redis timeout issue was subtle. Want me to save this as a *learning*
    +so we don't hit it again?
     

    If you see behavior like this, the setup is working end to end.

    In Claude Code, you can also invoke the /ctx-status skill:

    -
    /ctx-status
    +
    /ctx-status
     

    This prints a summary of all context files, token counts, and recent activity, confirming that hooks are loading context.

    @@ -2557,61 +2597,61 @@

    Step 5: Enable Watch Mode

    Tools like Aider, Copilot, and Windsurf do not support native hooks for saving context automatically. For these, run ctx watch alongside your AI tool.

    Pipe the AI tool's output through ctx watch:

    -
    # Terminal 1: Run Aider with output logged
    -aider 2>&1 | tee /tmp/aider.log
    -
    -# Terminal 2: Watch the log for context updates
    -ctx watch --log /tmp/aider.log
    +
    # Terminal 1: Run Aider with output logged
    +aider 2>&1 | tee /tmp/aider.log
    +
    +# Terminal 2: Watch the log for context updates
    +ctx watch --log /tmp/aider.log
     

    Or for any generic tool:

    -
    your-ai-tool 2>&1 | tee /tmp/ai.log &
    -ctx watch --log /tmp/ai.log
    +
    your-ai-tool 2>&1 | tee /tmp/ai.log &
    +ctx watch --log /tmp/ai.log
     

    When the AI emits structured update commands, ctx watch parses and applies them automatically:

    -
    <context-update type="learning"
    -  context="Debugging rate limiter"
    -  lesson="Redis MULTI/EXEC does not roll back on error"
    -  application="Wrap rate-limit checks in Lua scripts instead"
    ->Redis Transaction Behavior</context-update>
    +
    <context-update type="learning"
    +  context="Debugging rate limiter"
    +  lesson="Redis MULTI/EXEC does not roll back on error"
    +  application="Wrap rate-limit checks in Lua scripts instead"
    +>Redis Transaction Behavior</context-update>
     

    To preview changes without modifying files:

    -
    ctx watch --dry-run --log /tmp/ai.log
    +
    ctx watch --dry-run --log /tmp/ai.log
     

    Step 6: Import Session Transcripts (Optional)

    If you want to browse past session transcripts, import them to the journal:

    -
    ctx journal import --all
    +
    ctx journal import --all
     

    This converts raw session data into editable Markdown files in .context/journal/. You can then enrich them with metadata using /ctx-journal-enrich-all inside your AI assistant.

    Putting It All Together

    Here is the condensed setup for all three tools:

    -
    # ## Common (run once per project) ##
    -cd your-project
    -ctx init
    -source <(ctx completion zsh)       # or bash/fish
    -
    -# ## Claude Code (automatic, just verify) ##
    -# Start Claude Code, then ask: "Do you remember?"
    -
    -# ## OpenCode ##
    -ctx setup opencode --write
    -# Start OpenCode, then ask: "Do you remember?"
    -
    -# ## Cursor ##
    -ctx setup cursor
    -# Add the system prompt to .cursor/settings.json
    -# Paste context: ctx agent --budget 4000 | pbcopy
    -
    -# ## Aider ##
    -ctx setup aider
    -# Create .aider.conf.yml with read: paths
    -# Run watch mode alongside: ctx watch --log /tmp/aider.log
    -
    -# ## Verify any Tool ##
    -# Ask your AI: "Do you remember?"
    -# Expect: specific tasks, decisions, recent context
    +
    # ## Common (run once per project) ##
    +cd your-project
    +ctx init
    +source <(ctx completion zsh)       # or bash/fish
    +
    +# ## Claude Code (automatic, just verify) ##
    +# Start Claude Code, then ask: "Do you remember?"
    +
    +# ## OpenCode ##
    +ctx setup opencode --write
    +# Start OpenCode, then ask: "Do you remember?"
    +
    +# ## Cursor ##
    +ctx setup cursor
    +# Add the system prompt to .cursor/settings.json
    +# Paste context: ctx agent --budget 4000 | pbcopy
    +
    +# ## Aider ##
    +ctx setup aider
    +# Create .aider.conf.yml with read: paths
    +# Run watch mode alongside: ctx watch --log /tmp/aider.log
    +
    +# ## Verify any Tool ##
    +# Ask your AI: "Do you remember?"
    +# Expect: specific tasks, decisions, recent context
     

    Tips

      @@ -2648,8 +2688,8 @@