ctxo-mcp 0.4.2 → 0.5.1

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
@@ -41,17 +41,16 @@ Ctxo is an **MCP server** that **enhances** your existing AI tools with dependen
41
41
 
42
42
  ## Quick Start
43
43
 
44
- ```Shell
45
- # 1. Index your codebase
46
- npx ctxo-mcp index
47
-
48
- # 2. Add to your IDE's MCP config
49
- # (see IDE Setup below)
44
+ One command sets up everything — index directory, MCP server registration, AI tool rules, and git hooks:
50
45
 
51
- # 3. Start using — your AI assistant now has 14 code intelligence tools
46
+ ```Shell
47
+ npx ctxo-mcp init
52
48
  ```
53
49
 
54
- ## IDE Setup
50
+ 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.), and generates usage rules so your assistant knows when to call each tool.
51
+
52
+ <details>
53
+ <summary>Manual MCP config (if not using <code>ctxo init</code>)</summary>
55
54
 
56
55
  **Claude Code / Cursor / Windsurf / Cline** — `.mcp.json`:
57
56
 
@@ -71,6 +70,8 @@ npx ctxo-mcp index
71
70
  { "context_servers": { "ctxo": { "command": { "path": "npx", "args": ["-y", "ctxo-mcp"] } } } }
72
71
  ```
73
72
 
73
+ </details>
74
+
74
75
  ## 14 Tools
75
76
 
76
77
  | Tool | What it does |
@@ -107,17 +108,23 @@ Onboarding? → get_architectural_overlay → get_symbol_importanc
107
108
  ## CLI Commands
108
109
 
109
110
  ```Shell
110
- npx ctxo-mcp index # Build full codebase index
111
- npx ctxo-mcp index --check # CI gate: fail if index stale
112
- npx ctxo-mcp index --skip-history # Fast re-index without git history
113
- npx ctxo-mcp watch # File watcher for incremental re-index
114
- npx ctxo-mcp init # Install git hooks (post-commit, post-merge)
115
- npx ctxo-mcp status # Show index manifest
116
- npx ctxo-mcp sync # Rebuild SQLite cache from committed JSON
117
- npx ctxo-mcp stats # Show usage statistics
118
- npx ctxo-mcp stats --json # Machine-readable output
119
- npx ctxo-mcp stats --days 7 # Last 7 days only
120
- npx ctxo-mcp stats --clear # Delete all session data
111
+ # Setup
112
+ npx ctxo-mcp init # Interactive setup (index, AI tool rules, git hooks)
113
+ npx ctxo-mcp init --tools claude-code,cursor -y # Non-interactive setup
114
+ npx ctxo-mcp init --rules # Regenerate AI tool rules only
115
+ npx ctxo-mcp init --dry-run # Preview what would be created
116
+
117
+ # Indexing
118
+ npx ctxo-mcp index # Build full codebase index
119
+ npx ctxo-mcp index --check # CI gate: fail if index stale
120
+ npx ctxo-mcp index --skip-history # Fast re-index without git history
121
+ npx ctxo-mcp watch # File watcher for incremental re-index
122
+ npx ctxo-mcp sync # Rebuild SQLite cache from committed JSON
123
+
124
+ # Diagnostics
125
+ npx ctxo-mcp status # Show index manifest
126
+ npx ctxo-mcp doctor # Health check all subsystems (--json, --quiet)
127
+ npx ctxo-mcp stats # Show usage statistics (--json, --days N, --clear)
121
128
  ```
122
129
 
123
130
  **Example output:**
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-JIDIH7DS.js";
3
2
 
4
3
  // src/core/staleness/staleness-detector.ts
5
4
  import { statSync, existsSync } from "fs";
@@ -34,7 +33,8 @@ var StalenessDetector = class {
34
33
  };
35
34
  }
36
35
  };
36
+
37
37
  export {
38
38
  StalenessDetector
39
39
  };
40
- //# sourceMappingURL=staleness-detector-VSDPTPX7.js.map
40
+ //# sourceMappingURL=chunk-PSKDDLSF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/staleness/staleness-detector.ts"],"sourcesContent":["import { statSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport interface StalenessWarning {\n readonly staleFiles: string[];\n readonly message: string;\n}\n\nexport class StalenessDetector {\n private readonly projectRoot: string;\n private readonly indexDir: string;\n\n constructor(projectRoot: string, ctxoRoot: string) {\n this.projectRoot = projectRoot;\n this.indexDir = join(ctxoRoot, 'index');\n }\n\n check(indexedFiles: readonly string[]): StalenessWarning | undefined {\n if (!existsSync(this.indexDir)) return undefined;\n\n const staleFiles: string[] = [];\n\n for (const relativePath of indexedFiles) {\n const sourcePath = join(this.projectRoot, relativePath);\n const indexPath = join(this.indexDir, `${relativePath}.json`);\n\n if (!existsSync(sourcePath) || !existsSync(indexPath)) continue;\n\n try {\n const sourceMtime = Math.floor(statSync(sourcePath).mtimeMs / 1000);\n const indexMtime = Math.floor(statSync(indexPath).mtimeMs / 1000);\n\n if (sourceMtime > indexMtime) {\n staleFiles.push(relativePath);\n }\n } catch {\n // Skip files we can't stat\n }\n }\n\n if (staleFiles.length === 0) return undefined;\n\n return {\n staleFiles,\n message: `Index may be stale for ${staleFiles.length} file(s). Run \"ctxo index\" to refresh.`,\n };\n }\n}\n"],"mappings":";;;;AAAA,SAAS,UAAU,kBAAkB;AACrC,SAAS,YAAY;AAOd,IAAM,oBAAN,MAAwB;AAAA,EACZ;AAAA,EACA;AAAA,EAEjB,YAAY,aAAqB,UAAkB;AACjD,SAAK,cAAc;AACnB,SAAK,WAAW,KAAK,UAAU,OAAO;AAAA,EACxC;AAAA,EAEA,MAAM,cAA+D;AACnE,QAAI,CAAC,WAAW,KAAK,QAAQ,EAAG,QAAO;AAEvC,UAAM,aAAuB,CAAC;AAE9B,eAAW,gBAAgB,cAAc;AACvC,YAAM,aAAa,KAAK,KAAK,aAAa,YAAY;AACtD,YAAM,YAAY,KAAK,KAAK,UAAU,GAAG,YAAY,OAAO;AAE5D,UAAI,CAAC,WAAW,UAAU,KAAK,CAAC,WAAW,SAAS,EAAG;AAEvD,UAAI;AACF,cAAM,cAAc,KAAK,MAAM,SAAS,UAAU,EAAE,UAAU,GAAI;AAClE,cAAM,aAAa,KAAK,MAAM,SAAS,SAAS,EAAE,UAAU,GAAI;AAEhE,YAAI,cAAc,YAAY;AAC5B,qBAAW,KAAK,YAAY;AAAA,QAC9B;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,QAAI,WAAW,WAAW,EAAG,QAAO;AAEpC,WAAO;AAAA,MACL;AAAA,MACA,SAAS,0BAA0B,WAAW,MAAM;AAAA,IACtD;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/core/staleness/staleness-detector.ts"],"sourcesContent":["import { statSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport interface StalenessWarning {\n readonly staleFiles: string[];\n readonly message: string;\n}\n\nexport class StalenessDetector {\n private readonly projectRoot: string;\n private readonly indexDir: string;\n\n constructor(projectRoot: string, ctxoRoot: string) {\n this.projectRoot = projectRoot;\n this.indexDir = join(ctxoRoot, 'index');\n }\n\n check(indexedFiles: readonly string[]): StalenessWarning | undefined {\n if (!existsSync(this.indexDir)) return undefined;\n\n const staleFiles: string[] = [];\n\n for (const relativePath of indexedFiles) {\n const sourcePath = join(this.projectRoot, relativePath);\n const indexPath = join(this.indexDir, `${relativePath}.json`);\n\n if (!existsSync(sourcePath) || !existsSync(indexPath)) continue;\n\n try {\n const sourceMtime = Math.floor(statSync(sourcePath).mtimeMs / 1000);\n const indexMtime = Math.floor(statSync(indexPath).mtimeMs / 1000);\n\n if (sourceMtime > indexMtime) {\n staleFiles.push(relativePath);\n }\n } catch {\n // Skip files we can't stat\n }\n }\n\n if (staleFiles.length === 0) return undefined;\n\n return {\n staleFiles,\n message: `Index may be stale for ${staleFiles.length} file(s). Run \"ctxo index\" to refresh.`,\n };\n }\n}\n"],"mappings":";;;AAAA,SAAS,UAAU,kBAAkB;AACrC,SAAS,YAAY;AAOd,IAAM,oBAAN,MAAwB;AAAA,EACZ;AAAA,EACA;AAAA,EAEjB,YAAY,aAAqB,UAAkB;AACjD,SAAK,cAAc;AACnB,SAAK,WAAW,KAAK,UAAU,OAAO;AAAA,EACxC;AAAA,EAEA,MAAM,cAA+D;AACnE,QAAI,CAAC,WAAW,KAAK,QAAQ,EAAG,QAAO;AAEvC,UAAM,aAAuB,CAAC;AAE9B,eAAW,gBAAgB,cAAc;AACvC,YAAM,aAAa,KAAK,KAAK,aAAa,YAAY;AACtD,YAAM,YAAY,KAAK,KAAK,UAAU,GAAG,YAAY,OAAO;AAE5D,UAAI,CAAC,WAAW,UAAU,KAAK,CAAC,WAAW,SAAS,EAAG;AAEvD,UAAI;AACF,cAAM,cAAc,KAAK,MAAM,SAAS,UAAU,EAAE,UAAU,GAAI;AAClE,cAAM,aAAa,KAAK,MAAM,SAAS,SAAS,EAAE,UAAU,GAAI;AAEhE,YAAI,cAAc,YAAY;AAC5B,qBAAW,KAAK,YAAY;AAAA,QAC9B;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,QAAI,WAAW,WAAW,EAAG,QAAO;AAEpC,WAAO;AAAA,MACL;AAAA,MACA,SAAS,0BAA0B,WAAW,MAAM;AAAA,IACtD;AAAA,EACF;AACF;","names":[]}
@@ -6,6 +6,9 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
6
  var __esm = (fn, res) => function __init() {
7
7
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
8
  };
9
+ var __commonJS = (cb, mod) => function __require() {
10
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
+ };
9
12
  var __export = (target, all) => {
10
13
  for (var name in all)
11
14
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -22,7 +25,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
25
 
23
26
  export {
24
27
  __esm,
28
+ __commonJS,
25
29
  __export,
26
30
  __toCommonJS
27
31
  };
28
- //# sourceMappingURL=chunk-JIDIH7DS.js.map
32
+ //# sourceMappingURL=chunk-WNEGGJMV.js.map