@ctxo/cli 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,296 +10,59 @@
10
10
  <img alt="Ctxo — Code intelligence for AI agents" src="docs/img/hero-svg.svg" width="100%">
11
11
  </picture>
12
12
 
13
- </div>
14
-
15
- ***
16
-
17
- ### The Problem
18
-
19
- AI coding assistants like Copilot, Claude Code, and Cursor rely on generic tools `grep`, `find`, file reads to understand your codebase. On brownfield projects with thousands of files, this brute-force exploration creates a chain of problems:
20
-
21
- * **Context window saturation** The agent fills its window reading files one by one, leaving little room for actual reasoning
22
- * **Partial context hallucination** It sees a function but misses its dependencies, leading to wrong assumptions and broken suggestions
23
- * **Lost-in-the-middle** Critical information buried deep in a long context gets ignored by the model
24
- * **Context poisoning** Irrelevant code pulled in during exploration biases the model's output
25
- * **Iteration overhead** Understanding one symbol takes 10-20 tool calls, each adding more noise to the context
26
- * **Stale reasoning** After too many iterations, the agent contradicts its own earlier assumptions
27
-
28
- The result: more tokens burned, slower responses, higher cost, and lower quality output.
29
-
30
- ### The Solution
31
-
32
- Ctxo is an **MCP server** that **enhances** your existing AI tools with dependency-aware, history-enriched code intelligence. Instead of hundreds of `grep` and `read_file` calls, your agent gets the full picture symbol graphs, blast radius, git intent, and risk scores in a **single MCP call**.
33
-
34
- * **Clean context** Only relevant symbols and their transitive dependencies, nothing more
35
- * **Fewer iterations** One call replaces an entire exploration cycle
36
- * **Higher quality** The agent reasons over structured, complete context instead of fragmented file reads
37
-
38
- > A senior developer takes \~10 minutes to gather context across files. Ctxo delivers that same context in **under 500ms**.
39
-
40
- ## Quick Start
41
-
42
- Install the CLI, then run the setup wizard:
43
-
44
- ```Shell
45
- npm i -g @ctxo/cli
46
- ctxo init
47
- ```
48
-
49
- That's it. The interactive wizard detects your AI tools, registers the ctxo MCP server in the correct config file (`.mcp.json`, `.vscode/mcp.json`, etc.), generates usage rules so your assistant knows when to call each tool, and prompts to install language plugins it detects in your project (pass `--no-install` to skip).
50
-
51
- ### Language Plugins
52
-
53
- As of v0.7, Ctxo discovers language support from npm packages listed in your project's `package.json`. Three official plugins ship today:
54
-
55
13
  ```Shell
56
- npm i -D @ctxo/lang-typescript @ctxo/lang-go @ctxo/lang-csharp
14
+ npx @ctxo/cli init
15
+ npx @ctxo/cli index
57
16
  ```
58
17
 
59
- Or install one at a time with the CLI shortcut: `ctxo install typescript` (supports `--yes`, `--global`, `--dry-run`, `--pm`, `--version`). Any package named `@ctxo/lang-*` or `ctxo-lang-*` in your dependencies is auto-loaded.
60
-
61
- <details>
62
- <summary>Manual MCP config (if not using <code>ctxo init</code>)</summary>
63
-
64
- **Claude Code / Cursor / Windsurf / Augment / Antigravity** — `.mcp.json`:
65
-
66
- ```JSON
67
- { "mcpServers": { "ctxo": { "command": "npx", "args": ["-y", "@ctxo/cli"] } } }
68
- ```
69
-
70
- **VS Code (Copilot)** — `.vscode/mcp.json`:
71
-
72
- ```JSON
73
- { "servers": { "ctxo": { "type": "stdio", "command": "npx", "args": ["-y", "@ctxo/cli"] } } }
74
- ```
75
-
76
- **Amazon Q** — `.amazonq/mcp.json`:
77
-
78
- ```JSON
79
- { "mcpServers": { "ctxo": { "command": "npx", "args": ["-y", "@ctxo/cli"] } } }
80
- ```
81
-
82
- **Zed** — `settings.json`:
83
-
84
- ```JSON
85
- { "context_servers": { "ctxo": { "command": { "path": "npx", "args": ["-y", "@ctxo/cli"] } } } }
86
- ```
87
-
88
- </details>
89
-
90
- ## 14 Tools
91
-
92
- | Tool | What it does |
93
- | --------------------------- | ---------------------------------------------------------------------------------------- |
94
- | `get_logic_slice` | Symbol + transitive dependencies (L1-L4 progressive detail) |
95
- | `get_blast_radius` | What breaks if this changes (3-tier: confirmed/likely/potential) |
96
- | `get_architectural_overlay` | Project layer map (Domain/Infrastructure/Adapter) |
97
- | `get_why_context` | Git commit intent + anti-pattern warnings (reverts, rollbacks) |
98
- | `get_change_intelligence` | Complexity x churn composite score |
99
- | `find_dead_code` | Unreachable symbols, unused exports, scaffolding markers |
100
- | `get_context_for_task` | Task-optimized context (fix/extend/refactor/understand) |
101
- | `get_ranked_context` | Two-phase BM25 search (camelCase-aware, fuzzy correction) + PageRank within token budget |
102
- | `search_symbols` | Symbol name/regex search across index (`mode: 'fts'` for BM25) |
103
- | `get_changed_symbols` | Symbols in recently changed files (git diff) |
104
- | `find_importers` | Reverse dependency lookup ("who uses this?") |
105
- | `get_class_hierarchy` | Class inheritance tree (ancestors + descendants) |
106
- | `get_symbol_importance` | PageRank centrality ranking |
107
- | `get_pr_impact` | Full PR risk assessment in a single call |
108
-
109
- ## Tool Selection Guide
110
-
111
- ```
112
- Reviewing a PR? → get_pr_impact
113
- About to modify code? → get_blast_radius → get_why_context
114
- Understanding a symbol? → get_context_for_task(taskType: "understand")
115
- Fixing a bug? → get_context_for_task(taskType: "fix")
116
- Refactoring? → get_context_for_task(taskType: "refactor")
117
- Don't know the name? → search_symbols or get_ranked_context
118
- Finding unused code? → find_dead_code
119
- Safe to delete? → find_importers
120
- Onboarding? → get_architectural_overlay → get_symbol_importance
121
- ```
18
+ <a href="https://alperhankendi.github.io/Ctxo/docs/">
19
+ <img src="https://img.shields.io/badge/Get%20Started-%E2%86%92-06b6d4?style=for-the-badge&labelColor=0f172a" alt="Get Started →">
20
+ </a>
122
21
 
123
- ## CLI Commands
22
+ <sub>Detects your languages, installs the right plugins, wires Ctxo into your AI client, installs git hooks, and builds the first index one command.</sub>
124
23
 
125
- ```Shell
126
- # Setup
127
- ctxo init # Interactive setup (detects languages, prompts to install plugins, writes AI tool rules, git hooks)
128
- ctxo init --tools claude-code,cursor -y # Non-interactive setup
129
- ctxo init --no-install # Skip plugin install prompt
130
- ctxo init --rules # Regenerate AI tool rules only
131
- ctxo init --dry-run # Preview what would be created
132
-
133
- # Plugins (v0.7+)
134
- ctxo install # Install plugins for all detected languages
135
- ctxo install typescript go csharp # Install specific plugins
136
- ctxo install typescript --yes --pm pnpm # CI-friendly, pick package manager
137
- ctxo install typescript --global --version 0.7.0 # Pin version, install globally
138
-
139
- # Indexing
140
- ctxo index # Build full codebase index
141
- ctxo index --install-missing # Auto-install any missing plugins first
142
- ctxo index --check # CI gate: fail if index stale
143
- ctxo index --skip-history # Fast re-index without git history
144
- ctxo watch # File watcher for incremental re-index
145
- ctxo sync # Rebuild SQLite cache from committed JSON
146
-
147
- # Diagnostics
148
- ctxo status # Show index manifest
149
- ctxo doctor # Health check all subsystems (--json, --quiet)
150
- ctxo doctor --fix # Dependency-ordered auto-remediation (--dry-run, --yes)
151
- ctxo stats # Show usage statistics (--json, --days N, --clear)
152
- ctxo --version # Print CLI version (--verbose, --json)
153
- ctxo version # Verbose version subcommand (CLI + plugins + runtime)
154
- ```
155
-
156
- **Example output:**
157
-
158
- ```
159
- ctxo stats
160
-
161
- Usage Summary (all time)
162
- ────────────────────────────────────────
163
- Total tool calls: 30
164
- Total tokens served: 26.0K
165
-
166
- Top Tools
167
- ────────────────────────────────────────
168
- get_logic_slice 14 calls avg 352 tokens
169
- get_blast_radius 3 calls avg 1,279 tokens
170
- get_ranked_context 3 calls avg 898 tokens
171
- find_importers 2 calls avg 1,342 tokens
172
- get_context_for_task 2 calls avg 740 tokens
173
-
174
- Top Queried Symbols
175
- ────────────────────────────────────────
176
- SymbolNode 15 queries
177
- LogicSliceQuery 4 queries
178
- SqliteStorageAdapter 2 queries
179
-
180
- Detail Level Distribution
181
- ────────────────────────────────────────
182
- L1: ███░░░░░░░ 25%
183
- L2: ███░░░░░░░ 25%
184
- L3: ███░░░░░░░ 25%
185
- L4: ███░░░░░░░ 25%
186
- ```
187
-
188
- ## CI Integration
189
-
190
- Keep the committed `.ctxo/index/` in sync with the source tree by failing PRs when the index is stale. Drop-in examples:
191
-
192
- - GitHub Actions: [examples/github-actions/ctxo-check.yml](examples/github-actions/ctxo-check.yml)
193
- - GitLab CI: [examples/gitlab-ci/.gitlab-ci.yml](examples/gitlab-ci/.gitlab-ci.yml)
194
-
195
- Both run `ctxo index --check` on every PR/MR. If the index is stale, the job fails and the author runs `ctxo index` locally, then commits the refreshed index. Combined with the `post-commit` hook from `ctxo init`, this keeps the index current without any webhook infrastructure.
196
-
197
- ## Features
198
-
199
- **Response Envelope** All responses include `_meta` with item counts, truncation info, and drill-in hints. Large results auto-truncated at 8KB (configurable via `CTXO_RESPONSE_LIMIT`).
200
-
201
- **Intent Filtering** 4 tools accept `intent` parameter for keyword-based result filtering. `get_blast_radius(symbolId, intent: "test")` returns only test-related impacts.
202
-
203
- **Tool Annotations** All tools declare `readOnlyHint: true`, `idempotentHint: true`, `openWorldHint: false` for safe auto-approval in agent frameworks.
204
-
205
- **Privacy Masking** AWS keys, GCP service accounts, Azure connection strings, JWTs, private IPs, env secrets automatically redacted. Extensible via `.ctxo/masking.json`.
206
-
207
- **Interactive Graph** `ctxo visualize` generates a self-contained HTML with vis.js dependency graph. ForceAtlas2 layout, PageRank-based sizing, layer coloring, blast radius on click, git history per symbol, dead code and anti-pattern filters, dark/light theme.
208
-
209
- **Debug Mode** `DEBUG=ctxo:*` for all debug output, or `DEBUG=ctxo:git,ctxo:storage` for specific namespaces.
210
-
211
- **Per-tool savings vs manual approach:**
212
-
213
- ```
214
- Manual Tokens Ctxo Tokens Savings
215
- get_logic_slice ████████ 1,950 █ 150 92%
216
- get_blast_radius ███ 800 ██ 600 25%
217
- get_overlay ████████████ 25K██ 500 98%
218
- get_why_context █ 200 █ 200 0%
219
- get_change_intelligence ████████ 2,100 ▏ 50 98%
220
- find_dead_code █████████ 5,000 ████ 2,000 60%
221
- ────────────────────────────────────────────────────────────
222
- TOTAL 35,050 tokens 3,500 tokens 90%
223
- 329+ calls 6 calls 98%
224
- ```
225
-
226
- ## Agentic AI Usage
227
-
228
- **Claude Agent SDK:**
229
-
230
- ```TypeScript
231
- import { query } from "@anthropic-ai/claude-agent-sdk";
232
-
233
- for await (const message of query({
234
- prompt: "Analyze the blast radius of AuthService",
235
- options: {
236
- mcpServers: { ctxo: { command: "npx", args: ["-y", "@ctxo/cli"] } },
237
- allowedTools: ["mcp__ctxo__*"]
238
- }
239
- })) { /* ... */ }
240
- ```
241
-
242
- **OpenAI Agents SDK:**
24
+ </div>
243
25
 
244
- ```Python
245
- from agents import Agent, Runner
246
- from agents.mcp import MCPServerStdio
26
+ ***
247
27
 
248
- async with MCPServerStdio(params={"command": "npx", "args": ["@ctxo/cli"]}) as ctxo:
249
- agent = Agent(name="Reviewer", mcp_servers=[ctxo])
250
- result = await Runner.run(agent, "Review the PR impact")
251
- ```
28
+ ## The Problem: agents code blind
252
29
 
253
- See [Agentic AI Integration Guide](docs/agentic-ai-integration.md) for LangChain, raw MCP client, and CI/CD examples.
30
+ Drop a modern coding agent into a real repo. It ripgreps a symbol, gets 47 hits, reads five files to find the definition, five more for callers **misses the subclass entirely** (inheritance doesn't show up in text search), **never checks git history** (and confidently reintroduces a bug that was reverted three weeks ago), then runs out of context and starts hallucinating.
254
31
 
255
- ## Multi-Language Support
32
+ It's not a skill gap. It's a **sensory gap**. The agent is navigating your codebase with its eyes closed and a phone book.
256
33
 
257
- Language support ships as standalone plugins. Install only what your repo needs.
34
+ ## The Solution: proactive, not reactive
258
35
 
259
- | Language | Plugin Package | Engine | Tier | Toolchain required | Features |
260
- | --------------------- | ----------------------- | ---------------------------- | ------ | -------------------- | ------------------------------------------------------------------------------------------------------------------ |
261
- | TypeScript/JavaScript | `@ctxo/lang-typescript` | ts-morph | Full | bundled | Type-aware resolution, cross-file imports, `this.method()` calls, complexity metrics |
262
- | C# | `@ctxo/lang-csharp` | `ctxo-roslyn` (Roslyn) | Full | .NET SDK ≥ 8 on PATH | Symbols + `calls` / `uses` / `implements` / `extends`, cross-project resolution, complexity, tree-sitter fallback |
263
- | Go | `@ctxo/lang-go` | `ctxo-go-analyzer` | Full | Go ≥ 1.22 on PATH | Symbols + `calls` / `uses` / `implements` / `extends`, reflect-safe dead-code, generics, tree-sitter fallback |
264
- | All other languages | `@ctxo/lang-*` / `ctxo-lang-*` (plugin protocol) | tree-sitter (community adapter) | Syntax | bundled per plugin | Symbol inventory (functions, classes, types, methods), import edges, cyclomatic complexity, unexported symbols |
36
+ The core shift: your agent stops reacting to files it stumbles into and starts planning from a complete map. **Blast radius before the edit. Git intent before the bug fix. Importer list before the rename.**
265
37
 
266
- **Full tier** delivers type-resolved semantic edges across package boundaries — what `get_blast_radius`, `find_importers`, `find_dead_code` and `get_class_hierarchy` actually need. Requires the language's official toolchain on `PATH`; graceful degradation to tree-sitter syntax tier when missing.
38
+ Ctxo indexes your repo once kept fresh by file watchers and git hooks into a deterministic graph: every symbol, every edge (imports, calls, extends, implements), every relevant git commit with intent classified, every anti-pattern. All exposed through 14 semantic MCP tools.
267
39
 
268
- **Syntax tier** works out of the box via the `@ctxo/plugin-api` protocol (v1). Any package named `@ctxo/lang-*` or `ctxo-lang-*` in your dependencies is auto-discovered — third-party plugins can deliver new languages without touching core.
40
+ One `get_blast_radius` call replaces an entire ripgrep/read spiral. One `get_pr_impact` replaces a full review session of "wait, what calls this?"
269
41
 
270
- ## Index Visualizer
42
+ The agent still writes the code. It just stops writing it **blind** so the bug never has to be caught by the compiler, the tests, CI, or a user.
271
43
 
272
- Ctxo ships with an interactive visualizer that renders your codebase index as a dependency graph. Explore symbols, edges, layers, and PageRank scores visually deployed automatically to GitHub Pages on every push.
44
+ ## Codebase Dashboard
273
45
 
274
- ![1.00](docs/img/ui.png)
46
+ Full-stack analytics UI with eight views: File Tree, Heatmap, Co-Changes, Timeline, Architecture, MCP Explorer, and Diff. Deployed to GitHub Pages on every push.
275
47
 
276
- [Open Live Visualizer](https://alperhankendi.github.io/Ctxo/ctxo-visualizer.html)
48
+ ![Codebase Dashboard](docs/img/ui.png)
277
49
 
278
- ## How It Works
50
+ [Open Dashboard](https://alperhankendi.github.io/Ctxo/ctxo-visualizer.html)
279
51
 
280
- <img src="docs/img/mcp-server.png" alt="Ctxo MCP Server Architecture" width="400">
52
+ ## Dependency Graph
281
53
 
282
- Ctxo builds a **committed JSON index** (`.ctxo/index/`) that captures symbols, dependency edges, git history, and co-change data. The MCP server reads this index to answer queries no runtime parsing, no external services.
54
+ `ctxo visualize` generates a self-contained HTML from your `.ctxo/` index. Interactive force-directed graph with PageRank sizing, layer coloring, blast radius on click, and dark/light theme.
283
55
 
284
- The codebase is a pnpm monorepo with 5 packages: `@ctxo/cli` (this package), `@ctxo/plugin-api` (plugin protocol v1), and three official language plugins (`@ctxo/lang-typescript`, `@ctxo/lang-go`, `@ctxo/lang-csharp`).
56
+ ![Dependency Graph](docs/img/visualize-00-light.png)
285
57
 
286
- ```
287
- .ctxo/
288
- index/ ← committed (per-file JSON, reviewable in PRs)
289
- .cache/ ← gitignored (local SQLite, auto-rebuilt)
290
- config.yaml ← committed (team settings)
291
- masking.json ← committed (custom masking patterns)
292
- ```
58
+ [Open Dependency Graph](https://alperhankendi.github.io/Ctxo/visualize.html)
293
59
 
294
60
  ## Links
295
61
 
62
+ * [Docs](https://alperhankendi.github.io/Ctxo/docs/) quick start, MCP tools, CLI reference, integrations
296
63
  * [npm](https://www.npmjs.com/package/@ctxo/cli)
297
64
  * [Changelog](CHANGELOG.md)
298
65
  * [LLM Reference](llms-full.txt)
299
- * [MCP Validation Runbook](docs/runbook/mcp-validation/mcp-validation.md)
300
- * [CLI Validation Runbook](docs/runbook/cli-validation/cli-validation.md)
301
- * [Architecture](docs/artifacts/architecture.md)
302
- * [PRD](docs/artifacts/prd.md)
303
66
 
304
67
  ## License
305
68
 
@@ -38,7 +38,7 @@ import { dirname as dirname8, join as join24 } from "path";
38
38
  import { execFileSync as execFileSync2 } from "child_process";
39
39
  import { readFileSync as readFileSync6, writeFileSync as writeFileSync2, existsSync as existsSync9, statSync, readdirSync as readdirSync2 } from "fs";
40
40
  import { join as join8, relative, extname as extname3 } from "path";
41
- import { createRequire as createRequire2 } from "module";
41
+ import { createRequire as createRequire3 } from "module";
42
42
 
43
43
  // src/core/staleness/content-hasher.ts
44
44
  import { createHash } from "crypto";
@@ -74,6 +74,7 @@ import { dirname as dirname2, join } from "path";
74
74
 
75
75
  // src/adapters/language/plugin-discovery.ts
76
76
  import { existsSync, readFileSync } from "fs";
77
+ import { createRequire } from "module";
77
78
  import { dirname, isAbsolute, resolve } from "path";
78
79
  import { pathToFileURL } from "url";
79
80
  import { SUPPORTED_API_VERSION } from "@ctxo/plugin-api";
@@ -100,9 +101,46 @@ function readManifestDeps(manifestPath) {
100
101
  function isLocalSpecifier(spec) {
101
102
  return spec.startsWith(".") || spec.startsWith("/") || isAbsolute(spec);
102
103
  }
103
- async function tryLoad(specifier, baseDir) {
104
+ function pickEsmEntry(exportsField) {
105
+ if (!exportsField) return void 0;
106
+ if (typeof exportsField === "string") return exportsField;
107
+ if (typeof exportsField !== "object") return void 0;
108
+ const table = exportsField;
109
+ const dot = "." in table ? table["."] : exportsField;
110
+ if (typeof dot === "string") return dot;
111
+ if (!dot || typeof dot !== "object") return void 0;
112
+ for (const key of ["import", "node", "default"]) {
113
+ const nested = dot[key];
114
+ if (typeof nested === "string") return nested;
115
+ if (nested && typeof nested === "object") {
116
+ for (const inner of ["default", "import", "node"]) {
117
+ const v = nested[inner];
118
+ if (typeof v === "string") return v;
119
+ }
120
+ }
121
+ }
122
+ return void 0;
123
+ }
124
+ var cliFallbackRequire = createRequire(import.meta.url);
125
+ function resolvePluginEntryUrl(specifier, manifestRequire) {
126
+ let pkgJsonPath;
127
+ try {
128
+ pkgJsonPath = manifestRequire.resolve(`${specifier}/package.json`);
129
+ } catch (primary) {
130
+ try {
131
+ pkgJsonPath = cliFallbackRequire.resolve(`${specifier}/package.json`);
132
+ } catch {
133
+ throw primary;
134
+ }
135
+ }
136
+ const pkgDir = dirname(pkgJsonPath);
137
+ const pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
138
+ const entry = pickEsmEntry(pkgJson.exports) ?? pkgJson.module ?? pkgJson.main ?? "index.js";
139
+ return pathToFileURL(resolve(pkgDir, entry)).href;
140
+ }
141
+ async function tryLoad(specifier, baseDir, manifestRequire) {
104
142
  try {
105
- const target = isLocalSpecifier(specifier) ? pathToFileURL(resolve(baseDir, specifier)).href : specifier;
143
+ const target = isLocalSpecifier(specifier) ? pathToFileURL(resolve(baseDir, specifier)).href : resolvePluginEntryUrl(specifier, manifestRequire);
106
144
  const mod = await import(target);
107
145
  const candidate = mod.default ?? mod.plugin ?? mod;
108
146
  if (!candidate || typeof candidate !== "object") {
@@ -139,6 +177,7 @@ async function discoverPlugins(options) {
139
177
  }
140
178
  const baseDir = dirname(manifestPath);
141
179
  const specifiers = options.explicit ?? readManifestDeps(manifestPath);
180
+ const manifestRequire = createRequire(pathToFileURL(manifestPath).href);
142
181
  const plugins = [];
143
182
  const failures = [];
144
183
  for (const spec of specifiers) {
@@ -146,7 +185,7 @@ async function discoverPlugins(options) {
146
185
  log.info(`Skipping plugin ${spec} (matched ignoreProjects)`);
147
186
  continue;
148
187
  }
149
- const result = await tryLoad(spec, baseDir);
188
+ const result = await tryLoad(spec, baseDir, manifestRequire);
150
189
  if ("apiVersion" in result) {
151
190
  plugins.push({ plugin: result, specifier: spec });
152
191
  } else {
@@ -226,7 +265,7 @@ async function loadPlugins(projectRoot, options = {}) {
226
265
  // src/cli/install-command.ts
227
266
  import { existsSync as existsSync5 } from "fs";
228
267
  import { spawn } from "child_process";
229
- import { createRequire } from "module";
268
+ import { createRequire as createRequire2 } from "module";
230
269
  import { join as join4 } from "path";
231
270
 
232
271
  // src/core/detection/detect-languages.ts
@@ -596,7 +635,7 @@ function normalizeLanguage(input) {
596
635
  };
597
636
  return aliases[lowered] ?? null;
598
637
  }
599
- var installRequire = createRequire(import.meta.url);
638
+ var installRequire = createRequire2(import.meta.url);
600
639
  function isPluginInstalled(lang) {
601
640
  try {
602
641
  installRequire.resolve(`${officialPluginFor(lang)}/package.json`);
@@ -1036,7 +1075,7 @@ var CommunityDetector = class {
1036
1075
  };
1037
1076
 
1038
1077
  // src/cli/index-command.ts
1039
- var requireCjs = createRequire2(import.meta.url);
1078
+ var requireCjs = createRequire3(import.meta.url);
1040
1079
  var IndexCommand = class {
1041
1080
  projectRoot;
1042
1081
  ctxoRoot;
@@ -1683,7 +1722,7 @@ var VerifyCommand = class {
1683
1722
  // src/cli/init-command.ts
1684
1723
  import { join as join13 } from "path";
1685
1724
  import { existsSync as existsSync12, readFileSync as readFileSync8, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, chmodSync } from "fs";
1686
- import { createRequire as createRequire3 } from "module";
1725
+ import { createRequire as createRequire4 } from "module";
1687
1726
 
1688
1727
  // src/cli/ai-rules.ts
1689
1728
  import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4 } from "fs";
@@ -1695,7 +1734,9 @@ var PLATFORMS = [
1695
1734
  { id: "windsurf", name: "Windsurf", file: ".windsurfrules", mode: "create", detectPaths: [".windsurfrules", ".windsurf"], starred: false },
1696
1735
  { id: "antigravity", name: "Google Antigravity", file: "AGENTS.md", mode: "create", detectPaths: ["AGENTS.md", "GEMINI.md", ".gemini"], starred: false },
1697
1736
  { id: "augment", name: "Augment Code", file: "augment-guidelines.md", mode: "create", detectPaths: ["augment-guidelines.md", ".augment"], starred: false },
1698
- { id: "amazonq", name: "Amazon Q", file: ".amazonq/rules/ctxo.md", mode: "create", detectPaths: [".amazonq"], starred: false }
1737
+ { id: "amazonq", name: "Amazon Q", file: ".amazonq/rules/ctxo.md", mode: "create", detectPaths: [".amazonq"], starred: false },
1738
+ { id: "gemini-cli", name: "Gemini CLI", file: "GEMINI.md", mode: "append", detectPaths: [".gemini/settings.json", "GEMINI.md"], starred: false },
1739
+ { id: "continue", name: "Continue", file: ".continue/rules/ctxo.md", mode: "create", detectPaths: [".continue"], starred: false }
1699
1740
  ];
1700
1741
  function detectPlatforms(projectRoot) {
1701
1742
  const detected = /* @__PURE__ */ new Set();
@@ -1859,6 +1900,12 @@ function getMcpConfigTargets(selectedPlatformIds) {
1859
1900
  case "amazonq":
1860
1901
  targets.set(".amazonq/mcp.json", { file: ".amazonq/mcp.json", serverKey: "mcpServers" });
1861
1902
  break;
1903
+ case "gemini-cli":
1904
+ targets.set(".gemini/settings.json", { file: ".gemini/settings.json", serverKey: "mcpServers" });
1905
+ break;
1906
+ case "continue":
1907
+ targets.set(".continue/mcpServers/ctxo.json", { file: ".continue/mcpServers/ctxo.json", serverKey: "mcpServers" });
1908
+ break;
1862
1909
  }
1863
1910
  }
1864
1911
  return [...targets.values()];
@@ -1892,7 +1939,7 @@ function ensureMcpConfig(projectRoot, target) {
1892
1939
  }
1893
1940
 
1894
1941
  // src/cli/init-command.ts
1895
- var requireCjs2 = createRequire3(import.meta.url);
1942
+ var requireCjs2 = createRequire4(import.meta.url);
1896
1943
  function resolveInstalledPlugins(needed) {
1897
1944
  const installed = [];
1898
1945
  const missing = [];
@@ -2257,8 +2304,8 @@ var InitCommand = class {
2257
2304
  if (existsSync12(pkgPath)) {
2258
2305
  return JSON.parse(readFileSync8(pkgPath, "utf-8")).version;
2259
2306
  }
2260
- const { createRequire: createRequire7 } = await import("module");
2261
- const require4 = createRequire7(import.meta.url);
2307
+ const { createRequire: createRequire8 } = await import("module");
2308
+ const require4 = createRequire8(import.meta.url);
2262
2309
  return require4("../../package.json").version;
2263
2310
  } catch {
2264
2311
  return void 0;
@@ -2791,8 +2838,8 @@ var DoctorReporter = class {
2791
2838
  };
2792
2839
 
2793
2840
  // src/adapters/diagnostics/checks/runtime-check.ts
2794
- import { createRequire as createRequire4 } from "module";
2795
- var require2 = createRequire4(import.meta.url);
2841
+ import { createRequire as createRequire5 } from "module";
2842
+ var require2 = createRequire5(import.meta.url);
2796
2843
  function pass(id, title, message) {
2797
2844
  return { id, title, status: "pass", message };
2798
2845
  }
@@ -2983,8 +3030,8 @@ function buildSummary(info) {
2983
3030
  }
2984
3031
 
2985
3032
  // src/adapters/diagnostics/checks/language-coverage-check.ts
2986
- import { createRequire as createRequire5 } from "module";
2987
- var require3 = createRequire5(import.meta.url);
3033
+ import { createRequire as createRequire6 } from "module";
3034
+ var require3 = createRequire6(import.meta.url);
2988
3035
  var LanguageCoverageCheck = class {
2989
3036
  id = "language_coverage";
2990
3037
  title = "Language coverage";
@@ -3322,7 +3369,7 @@ var DiskUsageCheck = class {
3322
3369
  // src/cli/doctor-fix.ts
3323
3370
  import { execFileSync as execFileSync7 } from "child_process";
3324
3371
  import { appendFileSync, existsSync as existsSync19, mkdirSync as mkdirSync6, rmSync as rmSync2, unlinkSync as unlinkSync2 } from "fs";
3325
- import { createRequire as createRequire6 } from "module";
3372
+ import { createRequire as createRequire7 } from "module";
3326
3373
  import { dirname as dirname7, join as join21 } from "path";
3327
3374
  async function applyFixes(report, options) {
3328
3375
  if (isCI(process.env) && !options.yes && !options.dryRun) {
@@ -3508,7 +3555,7 @@ async function fixSqliteCache(projectRoot, ctxoRoot, dryRun) {
3508
3555
  if (existsSync19(cacheDir)) rmSync2(cacheDir, { recursive: true, force: true });
3509
3556
  await new SyncCommand(projectRoot).run();
3510
3557
  }
3511
- var doctorRequire = createRequire6(import.meta.url);
3558
+ var doctorRequire = createRequire7(import.meta.url);
3512
3559
  function canResolvePlugin(lang) {
3513
3560
  try {
3514
3561
  doctorRequire.resolve(`${officialPluginFor(lang)}/package.json`);
@@ -3559,7 +3606,7 @@ var DoctorCommand = class {
3559
3606
  this.ctxoRoot = join22(projectRoot, ".ctxo");
3560
3607
  }
3561
3608
  async run(options = {}) {
3562
- const { getVersion: getVersion2 } = await import("./cli-router-GZA44VOV.js");
3609
+ const { getVersion: getVersion2 } = await import("./cli-router-3UHVNKWD.js");
3563
3610
  console.error(`ctxo v${getVersion2()} \u2014 health check
3564
3611
  `);
3565
3612
  const checks = [
@@ -4055,4 +4102,4 @@ export {
4055
4102
  getVersion,
4056
4103
  locateGitRoot
4057
4104
  };
4058
- //# sourceMappingURL=cli-router-GZA44VOV.js.map
4105
+ //# sourceMappingURL=cli-router-3UHVNKWD.js.map