purecontext-mcp 1.2.0 → 1.5.0

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.
Files changed (177) hide show
  1. package/AGENT_INSTRUCTIONS.md +110 -784
  2. package/AGENT_REFERENCE.md +561 -0
  3. package/CHANGELOG.md +177 -6
  4. package/FRAMEWORK-ADAPTERS.md +351 -0
  5. package/LANGUAGE-SUPPORT.md +144 -0
  6. package/README.md +92 -12
  7. package/USER-GUIDE.md +8 -0
  8. package/dist/cli/hooks.d.ts +28 -0
  9. package/dist/cli/hooks.d.ts.map +1 -0
  10. package/dist/cli/hooks.js +570 -0
  11. package/dist/cli/hooks.js.map +1 -0
  12. package/dist/cli/install-detect.d.ts +16 -0
  13. package/dist/cli/install-detect.d.ts.map +1 -0
  14. package/dist/cli/install-detect.js +70 -0
  15. package/dist/cli/install-detect.js.map +1 -0
  16. package/dist/cli/install-writers.d.ts +59 -0
  17. package/dist/cli/install-writers.d.ts.map +1 -0
  18. package/dist/cli/install-writers.js +292 -0
  19. package/dist/cli/install-writers.js.map +1 -0
  20. package/dist/cli/install.d.ts +14 -0
  21. package/dist/cli/install.d.ts.map +1 -0
  22. package/dist/cli/install.js +150 -0
  23. package/dist/cli/install.js.map +1 -0
  24. package/dist/config/config-loader.js +3 -0
  25. package/dist/config/config-loader.js.map +1 -1
  26. package/dist/config/config-schema.d.ts +11 -0
  27. package/dist/config/config-schema.d.ts.map +1 -1
  28. package/dist/config/config-schema.js +15 -0
  29. package/dist/config/config-schema.js.map +1 -1
  30. package/dist/core/db/symbol-store.d.ts +1 -0
  31. package/dist/core/db/symbol-store.d.ts.map +1 -1
  32. package/dist/core/db/symbol-store.js +120 -6
  33. package/dist/core/db/symbol-store.js.map +1 -1
  34. package/dist/core/file-discovery.d.ts +6 -0
  35. package/dist/core/file-discovery.d.ts.map +1 -1
  36. package/dist/core/file-discovery.js +20 -13
  37. package/dist/core/file-discovery.js.map +1 -1
  38. package/dist/core/file-processor.d.ts.map +1 -1
  39. package/dist/core/file-processor.js +26 -1
  40. package/dist/core/file-processor.js.map +1 -1
  41. package/dist/core/git-log-reader.d.ts.map +1 -1
  42. package/dist/core/git-log-reader.js +21 -0
  43. package/dist/core/git-log-reader.js.map +1 -1
  44. package/dist/core/index-manager.d.ts.map +1 -1
  45. package/dist/core/index-manager.js +21 -7
  46. package/dist/core/index-manager.js.map +1 -1
  47. package/dist/core/indexing-worker.d.ts.map +1 -1
  48. package/dist/core/indexing-worker.js +14 -0
  49. package/dist/core/indexing-worker.js.map +1 -1
  50. package/dist/core/parse-dispatcher.d.ts.map +1 -1
  51. package/dist/core/parse-dispatcher.js +20 -5
  52. package/dist/core/parse-dispatcher.js.map +1 -1
  53. package/dist/core/search/query-preprocessor.d.ts +69 -3
  54. package/dist/core/search/query-preprocessor.d.ts.map +1 -1
  55. package/dist/core/search/query-preprocessor.js +450 -17
  56. package/dist/core/search/query-preprocessor.js.map +1 -1
  57. package/dist/core/search/relevance-ranker.d.ts +60 -5
  58. package/dist/core/search/relevance-ranker.d.ts.map +1 -1
  59. package/dist/core/search/relevance-ranker.js +931 -33
  60. package/dist/core/search/relevance-ranker.js.map +1 -1
  61. package/dist/core/test-mapper.d.ts.map +1 -1
  62. package/dist/core/test-mapper.js +7 -1
  63. package/dist/core/test-mapper.js.map +1 -1
  64. package/dist/core/types.d.ts +28 -1
  65. package/dist/core/types.d.ts.map +1 -1
  66. package/dist/handlers/angular-html.d.ts +3 -0
  67. package/dist/handlers/angular-html.d.ts.map +1 -0
  68. package/dist/handlers/angular-html.js +215 -0
  69. package/dist/handlers/angular-html.js.map +1 -0
  70. package/dist/handlers/c.d.ts.map +1 -1
  71. package/dist/handlers/c.js +19 -0
  72. package/dist/handlers/c.js.map +1 -1
  73. package/dist/handlers/cpp-macro-registry.d.ts +21 -0
  74. package/dist/handlers/cpp-macro-registry.d.ts.map +1 -0
  75. package/dist/handlers/cpp-macro-registry.js +44 -0
  76. package/dist/handlers/cpp-macro-registry.js.map +1 -0
  77. package/dist/handlers/cpp.d.ts.map +1 -1
  78. package/dist/handlers/cpp.js +579 -10
  79. package/dist/handlers/cpp.js.map +1 -1
  80. package/dist/handlers/csharp.d.ts.map +1 -1
  81. package/dist/handlers/csharp.js +39 -2
  82. package/dist/handlers/csharp.js.map +1 -1
  83. package/dist/handlers/css.d.ts +3 -0
  84. package/dist/handlers/css.d.ts.map +1 -0
  85. package/dist/handlers/css.js +154 -0
  86. package/dist/handlers/css.js.map +1 -0
  87. package/dist/handlers/erlang.d.ts.map +1 -1
  88. package/dist/handlers/erlang.js +8 -1
  89. package/dist/handlers/erlang.js.map +1 -1
  90. package/dist/handlers/fortran.js +1 -1
  91. package/dist/handlers/fortran.js.map +1 -1
  92. package/dist/handlers/go.d.ts.map +1 -1
  93. package/dist/handlers/go.js +87 -2
  94. package/dist/handlers/go.js.map +1 -1
  95. package/dist/handlers/handler-registry.d.ts.map +1 -1
  96. package/dist/handlers/handler-registry.js +4 -0
  97. package/dist/handlers/handler-registry.js.map +1 -1
  98. package/dist/handlers/hcl.d.ts +3 -0
  99. package/dist/handlers/hcl.d.ts.map +1 -0
  100. package/dist/handlers/hcl.js +193 -0
  101. package/dist/handlers/hcl.js.map +1 -0
  102. package/dist/handlers/java.d.ts.map +1 -1
  103. package/dist/handlers/java.js +33 -16
  104. package/dist/handlers/java.js.map +1 -1
  105. package/dist/handlers/kotlin.d.ts.map +1 -1
  106. package/dist/handlers/kotlin.js +48 -3
  107. package/dist/handlers/kotlin.js.map +1 -1
  108. package/dist/handlers/less.d.ts +3 -0
  109. package/dist/handlers/less.d.ts.map +1 -0
  110. package/dist/handlers/less.js +255 -0
  111. package/dist/handlers/less.js.map +1 -0
  112. package/dist/handlers/objective-c.d.ts.map +1 -1
  113. package/dist/handlers/objective-c.js +122 -64
  114. package/dist/handlers/objective-c.js.map +1 -1
  115. package/dist/handlers/openapi.d.ts.map +1 -1
  116. package/dist/handlers/openapi.js +30 -5
  117. package/dist/handlers/openapi.js.map +1 -1
  118. package/dist/handlers/php.d.ts.map +1 -1
  119. package/dist/handlers/php.js +287 -41
  120. package/dist/handlers/php.js.map +1 -1
  121. package/dist/handlers/protobuf.d.ts.map +1 -1
  122. package/dist/handlers/protobuf.js +1 -0
  123. package/dist/handlers/protobuf.js.map +1 -1
  124. package/dist/handlers/python.d.ts.map +1 -1
  125. package/dist/handlers/python.js +1 -3
  126. package/dist/handlers/python.js.map +1 -1
  127. package/dist/handlers/ruby-dsl.d.ts +23 -0
  128. package/dist/handlers/ruby-dsl.d.ts.map +1 -0
  129. package/dist/handlers/ruby-dsl.js +251 -0
  130. package/dist/handlers/ruby-dsl.js.map +1 -0
  131. package/dist/handlers/ruby.d.ts.map +1 -1
  132. package/dist/handlers/ruby.js +29 -4
  133. package/dist/handlers/ruby.js.map +1 -1
  134. package/dist/handlers/rust.d.ts.map +1 -1
  135. package/dist/handlers/rust.js +98 -2
  136. package/dist/handlers/rust.js.map +1 -1
  137. package/dist/handlers/scss.d.ts +3 -0
  138. package/dist/handlers/scss.d.ts.map +1 -0
  139. package/dist/handlers/scss.js +290 -0
  140. package/dist/handlers/scss.js.map +1 -0
  141. package/dist/handlers/sql.d.ts.map +1 -1
  142. package/dist/handlers/sql.js +37 -18
  143. package/dist/handlers/sql.js.map +1 -1
  144. package/dist/handlers/typescript.d.ts.map +1 -1
  145. package/dist/handlers/typescript.js +65 -17
  146. package/dist/handlers/typescript.js.map +1 -1
  147. package/dist/handlers/xml.d.ts.map +1 -1
  148. package/dist/handlers/xml.js +35 -2
  149. package/dist/handlers/xml.js.map +1 -1
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +91 -0
  152. package/dist/index.js.map +1 -1
  153. package/dist/server/mcp-server.d.ts.map +1 -1
  154. package/dist/server/mcp-server.js +10 -0
  155. package/dist/server/mcp-server.js.map +1 -1
  156. package/dist/server/tools/detect-antipatterns.d.ts +1 -1
  157. package/dist/server/tools/get-architecture-snapshot.d.ts +1 -1
  158. package/dist/server/tools/get-entry-points.d.ts +1 -1
  159. package/dist/server/tools/get-lexical-scope-matches.d.ts +54 -0
  160. package/dist/server/tools/get-lexical-scope-matches.d.ts.map +1 -0
  161. package/dist/server/tools/get-lexical-scope-matches.js +470 -0
  162. package/dist/server/tools/get-lexical-scope-matches.js.map +1 -0
  163. package/dist/server/tools/search-symbols.d.ts +10 -0
  164. package/dist/server/tools/search-symbols.d.ts.map +1 -1
  165. package/dist/server/tools/search-symbols.js +353 -8
  166. package/dist/server/tools/search-symbols.js.map +1 -1
  167. package/dist/server/tools/trace-invocation-chain.d.ts +53 -0
  168. package/dist/server/tools/trace-invocation-chain.d.ts.map +1 -0
  169. package/dist/server/tools/trace-invocation-chain.js +280 -0
  170. package/dist/server/tools/trace-invocation-chain.js.map +1 -0
  171. package/dist/version.d.ts +1 -1
  172. package/dist/version.js +1 -1
  173. package/docs/02-installation.md +89 -17
  174. package/docs/05-cli-reference.md +89 -0
  175. package/docs/dev/benchmark-findings-eu-za-tebe.md +210 -0
  176. package/docs/dev/phase-35-coverage-audit.md +469 -0
  177. package/package.json +4 -1
@@ -0,0 +1,70 @@
1
+ /**
2
+ * IDE/agent detection for `purecontext-mcp install all`.
3
+ *
4
+ * Each tool is detected by the presence of a characteristic directory or
5
+ * config file in the project root or the user's home directory.
6
+ */
7
+ import { existsSync } from 'fs';
8
+ import { join } from 'path';
9
+ import { homedir, platform } from 'os';
10
+ // ─── Platform config paths ────────────────────────────────────────────────────
11
+ export function getClaudeDesktopConfigPath() {
12
+ const p = platform();
13
+ if (p === 'darwin') {
14
+ return join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
15
+ }
16
+ if (p === 'win32') {
17
+ const appdata = process.env['APPDATA'];
18
+ if (!appdata)
19
+ return null;
20
+ return join(appdata, 'Claude', 'claude_desktop_config.json');
21
+ }
22
+ // Linux and others
23
+ return join(homedir(), '.config', 'Claude', 'claude_desktop_config.json');
24
+ }
25
+ // ─── Detection ────────────────────────────────────────────────────────────────
26
+ /**
27
+ * Return the list of AI coding tools detected in `projectRoot` or the user's
28
+ * home directory. Detection is based on characteristic directory/file signals.
29
+ *
30
+ * `cline` and `vscode` both trigger on `.vscode/` — intentional; they write
31
+ * to different output files so there is no conflict.
32
+ */
33
+ export async function detectInstalledIDEs(projectRoot) {
34
+ const detected = [];
35
+ // Claude Code — .claude/ directory in project or home
36
+ if (existsSync(join(projectRoot, '.claude')) || existsSync(join(homedir(), '.claude'))) {
37
+ detected.push('claude');
38
+ }
39
+ // Cursor — .cursor/ directory in project
40
+ if (existsSync(join(projectRoot, '.cursor'))) {
41
+ detected.push('cursor');
42
+ }
43
+ // Windsurf — .windsurf/ directory in project
44
+ if (existsSync(join(projectRoot, '.windsurf'))) {
45
+ detected.push('windsurf');
46
+ }
47
+ // Continue — .continue/ directory in project
48
+ if (existsSync(join(projectRoot, '.continue'))) {
49
+ detected.push('continue');
50
+ }
51
+ // Cline — .vscode/ directory exists (Cline runs inside VS Code)
52
+ if (existsSync(join(projectRoot, '.vscode'))) {
53
+ detected.push('cline');
54
+ }
55
+ // Roo Code — .roo/ directory in project
56
+ if (existsSync(join(projectRoot, '.roo'))) {
57
+ detected.push('roo-code');
58
+ }
59
+ // GitHub Copilot — .vscode/ directory exists
60
+ if (existsSync(join(projectRoot, '.vscode'))) {
61
+ detected.push('copilot');
62
+ }
63
+ // Claude Desktop — platform config path
64
+ const claudeDesktopConfig = getClaudeDesktopConfigPath();
65
+ if (claudeDesktopConfig && existsSync(claudeDesktopConfig)) {
66
+ detected.push('claude-desktop');
67
+ }
68
+ return detected;
69
+ }
70
+ //# sourceMappingURL=install-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-detect.js","sourceRoot":"","sources":["../../src/cli/install-detect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAEvC,iFAAiF;AAEjF,MAAM,UAAU,0BAA0B;IACxC,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;IACrB,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,OAAO,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAC;IAC/D,CAAC;IACD,mBAAmB;IACnB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAC;AAC5E,CAAC;AAED,iFAAiF;AAEjF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,WAAmB;IAC3D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,sDAAsD;IACtD,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QACvF,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAED,yCAAyC;IACzC,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QAC7C,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAED,6CAA6C;IAC7C,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QAC/C,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAED,6CAA6C;IAC7C,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QAC/C,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAED,gEAAgE;IAChE,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QAC7C,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IAED,wCAAwC;IACxC,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAED,6CAA6C;IAC7C,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QAC7C,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAED,wCAAwC;IACxC,MAAM,mBAAmB,GAAG,0BAA0B,EAAE,CAAC;IACzD,IAAI,mBAAmB,IAAI,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC3D,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Per-IDE writer functions for `purecontext-mcp install <tool>`.
3
+ *
4
+ * Each exported `install*` function is idempotent: calling it twice produces
5
+ * the same result without duplicating content. Marker comments
6
+ * (`<!-- purecontext-mcp-start/end -->`) delimit the managed block so that
7
+ * updates replace rather than append.
8
+ */
9
+ export type Scope = 'local' | 'global' | 'both';
10
+ export declare const START_MARKER = "<!-- purecontext-mcp-start -->";
11
+ export declare const END_MARKER = "<!-- purecontext-mcp-end -->";
12
+ export declare function getPureContextInstructions(format: 'markdown' | 'mdc' | 'json-system'): string;
13
+ /**
14
+ * Install for Claude Code.
15
+ * local → writes instruction block to <project>/CLAUDE.md
16
+ * global → writes hooks + ~/.claude/CLAUDE.md (existing behaviour)
17
+ * both → both of the above
18
+ */
19
+ export declare function installClaude(projectRoot: string, scope: Scope): Promise<void>;
20
+ /**
21
+ * Write `purecontext.mdc` with MDC frontmatter.
22
+ * local → <project>/.cursor/rules/
23
+ * global → ~/.cursor/rules/
24
+ */
25
+ export declare function installCursor(projectRoot: string, scope: Scope): Promise<void>;
26
+ /**
27
+ * Write `purecontext.md` into the Windsurf rules directory.
28
+ * local → <project>/.windsurf/rules/purecontext.md
29
+ * global → ~/.windsurf/rules/purecontext.md
30
+ */
31
+ export declare function installWindsurf(projectRoot: string, scope: Scope): Promise<void>;
32
+ /**
33
+ * Merge a `systemMessage` field into a Continue `config.json`.
34
+ * local → <project>/.continue/config.json
35
+ * global → ~/.continue/config.json
36
+ */
37
+ export declare function installContinue(projectRoot: string, scope: Scope): Promise<void>;
38
+ /**
39
+ * Write `.clinerules` with a marked block.
40
+ * local only — Cline has no known global config path.
41
+ */
42
+ export declare function installCline(projectRoot: string, scope: Scope): Promise<void>;
43
+ /**
44
+ * Write `.roo/rules-code.md` with a marked block.
45
+ * local only — Roo Code has no known global config path.
46
+ */
47
+ export declare function installRooCode(projectRoot: string, scope: Scope): Promise<void>;
48
+ /**
49
+ * Write `.github/copilot-instructions.md` with a marked block.
50
+ * local only — GitHub Copilot has no standard global instructions path.
51
+ */
52
+ export declare function installCopilot(projectRoot: string, scope: Scope): Promise<void>;
53
+ /**
54
+ * Merge the PureContext MCP server entry into the Claude Desktop config JSON.
55
+ * Always global — scope parameter is accepted for API consistency but ignored.
56
+ */
57
+ export declare function installClaudeDesktop(_projectRoot: string, _scope: Scope): Promise<void>;
58
+ export declare const INSTALL_WRITERS: Record<string, (projectRoot: string, scope: Scope) => Promise<void>>;
59
+ //# sourceMappingURL=install-writers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-writers.d.ts","sourceRoot":"","sources":["../../src/cli/install-writers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAIhD,eAAO,MAAM,YAAY,mCAAmC,CAAC;AAC7D,eAAO,MAAM,UAAU,iCAAiC,CAAC;AAiCzD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,aAAa,GAAG,MAAM,CAQ7F;AA8BD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAcpF;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBpF;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBtF;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBtF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBnF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBrF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBrF;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC7F;AAID,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAShG,CAAC"}
@@ -0,0 +1,292 @@
1
+ /**
2
+ * Per-IDE writer functions for `purecontext-mcp install <tool>`.
3
+ *
4
+ * Each exported `install*` function is idempotent: calling it twice produces
5
+ * the same result without duplicating content. Marker comments
6
+ * (`<!-- purecontext-mcp-start/end -->`) delimit the managed block so that
7
+ * updates replace rather than append.
8
+ */
9
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
10
+ import { join, dirname } from 'path';
11
+ import { homedir } from 'os';
12
+ import { cmdHooksInstall } from './hooks.js';
13
+ import { getClaudeDesktopConfigPath } from './install-detect.js';
14
+ // ─── Shared markers ───────────────────────────────────────────────────────────
15
+ export const START_MARKER = '<!-- purecontext-mcp-start -->';
16
+ export const END_MARKER = '<!-- purecontext-mcp-end -->';
17
+ // ─── Shared instruction content ───────────────────────────────────────────────
18
+ const MARKDOWN_CONTENT = `## PureContext MCP — Code Navigation
19
+
20
+ Always use PureContext MCP tools for code navigation. Never read entire files to find code.
21
+
22
+ ### Mandatory workflow
23
+
24
+ 1. **Start every session**: \`list_repos()\` → get \`repoId\` (required for all tools)
25
+ 2. **Find code by name**: \`search_symbols\` → read \`summary\` and \`signature\` → only call \`get_symbol_source\` for symbols you will actually edit
26
+ 3. **Find code by behaviour**: \`search_semantic\` for conceptual queries; \`search_text\` for literals/comments
27
+
28
+ ### Key tools
29
+
30
+ | Goal | Tool |
31
+ |------|------|
32
+ | Find function/class by name | \`search_symbols\` |
33
+ | Find by what it does | \`search_semantic\` |
34
+ | Find literal string or comment | \`search_text\` |
35
+ | All symbols in a file | \`get_file_outline\` |
36
+ | What breaks if I change this | \`get_blast_radius\` |
37
+ | All callers of a function | \`find_references\` |
38
+ | Callers/callees tree | \`get_call_hierarchy\` |
39
+
40
+ ### Anti-patterns — never do these
41
+
42
+ - Do not read whole files to find a function — use \`search_symbols\` + \`get_symbol_source\`
43
+ - Do not call \`get_symbol_source\` for every result — read \`summary\` first
44
+ - Do not skip \`list_repos\` — every tool needs a \`repoId\`
45
+ - Do not re-search after \`verdict: "no_match"\` — the symbol does not exist`;
46
+ export function getPureContextInstructions(format) {
47
+ if (format === 'mdc') {
48
+ return `---\ndescription: PureContext MCP code navigation rules\nalwaysApply: true\n---\n\n${MARKDOWN_CONTENT}`;
49
+ }
50
+ if (format === 'json-system') {
51
+ return MARKDOWN_CONTENT;
52
+ }
53
+ return MARKDOWN_CONTENT;
54
+ }
55
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
56
+ function replaceMarkerBlock(existing, newBlock) {
57
+ const startIdx = existing.indexOf(START_MARKER);
58
+ const endIdx = existing.indexOf(END_MARKER);
59
+ if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
60
+ return existing.slice(0, startIdx) + newBlock + existing.slice(endIdx + END_MARKER.length);
61
+ }
62
+ // No existing block — append
63
+ if (!existing.endsWith('\n'))
64
+ existing += '\n';
65
+ return existing + '\n' + newBlock + '\n';
66
+ }
67
+ function markedBlock(content) {
68
+ return `${START_MARKER}\n${content}\n${END_MARKER}`;
69
+ }
70
+ function ensureDir(filePath) {
71
+ mkdirSync(dirname(filePath), { recursive: true });
72
+ }
73
+ function writeIdempotent(filePath, content) {
74
+ ensureDir(filePath);
75
+ writeFileSync(filePath, content, 'utf-8');
76
+ }
77
+ // ─── Per-IDE installers ───────────────────────────────────────────────────────
78
+ /**
79
+ * Install for Claude Code.
80
+ * local → writes instruction block to <project>/CLAUDE.md
81
+ * global → writes hooks + ~/.claude/CLAUDE.md (existing behaviour)
82
+ * both → both of the above
83
+ */
84
+ export async function installClaude(projectRoot, scope) {
85
+ if (scope === 'local' || scope === 'both') {
86
+ const filePath = join(projectRoot, 'CLAUDE.md');
87
+ const block = markedBlock(getPureContextInstructions('markdown'));
88
+ if (existsSync(filePath)) {
89
+ const existing = readFileSync(filePath, 'utf-8');
90
+ writeFileSync(filePath, replaceMarkerBlock(existing, block), 'utf-8');
91
+ }
92
+ else {
93
+ writeIdempotent(filePath, block + '\n');
94
+ }
95
+ }
96
+ if (scope === 'global' || scope === 'both') {
97
+ cmdHooksInstall();
98
+ }
99
+ }
100
+ /**
101
+ * Write `purecontext.mdc` with MDC frontmatter.
102
+ * local → <project>/.cursor/rules/
103
+ * global → ~/.cursor/rules/
104
+ */
105
+ export async function installCursor(projectRoot, scope) {
106
+ const writeMdc = (filePath) => {
107
+ ensureDir(filePath);
108
+ const mdcContent = getPureContextInstructions('mdc');
109
+ if (existsSync(filePath)) {
110
+ const existing = readFileSync(filePath, 'utf-8');
111
+ if (existing.includes(START_MARKER)) {
112
+ writeFileSync(filePath, replaceMarkerBlock(existing, markedBlock(MARKDOWN_CONTENT)), 'utf-8');
113
+ return;
114
+ }
115
+ }
116
+ writeIdempotent(filePath, mdcContent + '\n');
117
+ };
118
+ if (scope === 'local' || scope === 'both') {
119
+ writeMdc(join(projectRoot, '.cursor', 'rules', 'purecontext.mdc'));
120
+ }
121
+ if (scope === 'global' || scope === 'both') {
122
+ writeMdc(join(homedir(), '.cursor', 'rules', 'purecontext.mdc'));
123
+ }
124
+ }
125
+ /**
126
+ * Write `purecontext.md` into the Windsurf rules directory.
127
+ * local → <project>/.windsurf/rules/purecontext.md
128
+ * global → ~/.windsurf/rules/purecontext.md
129
+ */
130
+ export async function installWindsurf(projectRoot, scope) {
131
+ const writeLocal = (filePath) => {
132
+ ensureDir(filePath);
133
+ writeFileSync(filePath, getPureContextInstructions('markdown') + '\n', 'utf-8');
134
+ };
135
+ const writeGlobal = (filePath) => {
136
+ const block = markedBlock(getPureContextInstructions('markdown'));
137
+ ensureDir(filePath);
138
+ if (existsSync(filePath)) {
139
+ const existing = readFileSync(filePath, 'utf-8');
140
+ writeFileSync(filePath, replaceMarkerBlock(existing, block), 'utf-8');
141
+ }
142
+ else {
143
+ writeFileSync(filePath, block + '\n', 'utf-8');
144
+ }
145
+ };
146
+ if (scope === 'local' || scope === 'both') {
147
+ writeLocal(join(projectRoot, '.windsurf', 'rules', 'purecontext.md'));
148
+ }
149
+ if (scope === 'global' || scope === 'both') {
150
+ writeGlobal(join(homedir(), '.windsurf', 'rules', 'purecontext.md'));
151
+ }
152
+ }
153
+ /**
154
+ * Merge a `systemMessage` field into a Continue `config.json`.
155
+ * local → <project>/.continue/config.json
156
+ * global → ~/.continue/config.json
157
+ */
158
+ export async function installContinue(projectRoot, scope) {
159
+ const writeConfig = (filePath) => {
160
+ ensureDir(filePath);
161
+ const instructions = getPureContextInstructions('json-system');
162
+ let config = {};
163
+ if (existsSync(filePath)) {
164
+ try {
165
+ config = JSON.parse(readFileSync(filePath, 'utf-8'));
166
+ }
167
+ catch {
168
+ config = {};
169
+ }
170
+ }
171
+ config['systemMessage'] = instructions;
172
+ writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
173
+ };
174
+ if (scope === 'local' || scope === 'both') {
175
+ writeConfig(join(projectRoot, '.continue', 'config.json'));
176
+ }
177
+ if (scope === 'global' || scope === 'both') {
178
+ writeConfig(join(homedir(), '.continue', 'config.json'));
179
+ }
180
+ }
181
+ /**
182
+ * Write `.clinerules` with a marked block.
183
+ * local only — Cline has no known global config path.
184
+ */
185
+ export async function installCline(projectRoot, scope) {
186
+ if (scope === 'global') {
187
+ console.log(' cline: no known global config path — skipped');
188
+ return;
189
+ }
190
+ const filePath = join(projectRoot, '.clinerules');
191
+ const block = markedBlock(getPureContextInstructions('markdown'));
192
+ if (existsSync(filePath)) {
193
+ const existing = readFileSync(filePath, 'utf-8');
194
+ writeFileSync(filePath, replaceMarkerBlock(existing, block), 'utf-8');
195
+ }
196
+ else {
197
+ writeIdempotent(filePath, block + '\n');
198
+ }
199
+ if (scope === 'both') {
200
+ console.log(' cline: no known global config path — global install skipped');
201
+ }
202
+ }
203
+ /**
204
+ * Write `.roo/rules-code.md` with a marked block.
205
+ * local only — Roo Code has no known global config path.
206
+ */
207
+ export async function installRooCode(projectRoot, scope) {
208
+ if (scope === 'global') {
209
+ console.log(' roo-code: no known global config path — skipped');
210
+ return;
211
+ }
212
+ const filePath = join(projectRoot, '.roo', 'rules-code.md');
213
+ const block = markedBlock(getPureContextInstructions('markdown'));
214
+ ensureDir(filePath);
215
+ if (existsSync(filePath)) {
216
+ const existing = readFileSync(filePath, 'utf-8');
217
+ writeFileSync(filePath, replaceMarkerBlock(existing, block), 'utf-8');
218
+ }
219
+ else {
220
+ writeFileSync(filePath, block + '\n', 'utf-8');
221
+ }
222
+ if (scope === 'both') {
223
+ console.log(' roo-code: no known global config path — global install skipped');
224
+ }
225
+ }
226
+ /**
227
+ * Write `.github/copilot-instructions.md` with a marked block.
228
+ * local only — GitHub Copilot has no standard global instructions path.
229
+ */
230
+ export async function installCopilot(projectRoot, scope) {
231
+ if (scope === 'global') {
232
+ console.log(' copilot: no known global config path — skipped');
233
+ return;
234
+ }
235
+ const filePath = join(projectRoot, '.github', 'copilot-instructions.md');
236
+ const block = markedBlock(getPureContextInstructions('markdown'));
237
+ ensureDir(filePath);
238
+ if (existsSync(filePath)) {
239
+ const existing = readFileSync(filePath, 'utf-8');
240
+ writeFileSync(filePath, replaceMarkerBlock(existing, block), 'utf-8');
241
+ }
242
+ else {
243
+ writeFileSync(filePath, block + '\n', 'utf-8');
244
+ }
245
+ if (scope === 'both') {
246
+ console.log(' copilot: no known global config path — global install skipped');
247
+ }
248
+ }
249
+ /**
250
+ * Merge the PureContext MCP server entry into the Claude Desktop config JSON.
251
+ * Always global — scope parameter is accepted for API consistency but ignored.
252
+ */
253
+ export async function installClaudeDesktop(_projectRoot, _scope) {
254
+ const configPath = getClaudeDesktopConfigPath();
255
+ if (!configPath) {
256
+ throw new Error('Cannot determine Claude Desktop config path for this platform');
257
+ }
258
+ ensureDir(configPath);
259
+ let config = {};
260
+ if (existsSync(configPath)) {
261
+ try {
262
+ config = JSON.parse(readFileSync(configPath, 'utf-8'));
263
+ }
264
+ catch {
265
+ config = {};
266
+ }
267
+ }
268
+ const mcpServers = (config['mcpServers'] ?? {});
269
+ const existing = mcpServers['purecontext-mcp'];
270
+ if (existing?.['command'] === 'npx') {
271
+ // Already present with same command — skip
272
+ return;
273
+ }
274
+ mcpServers['purecontext-mcp'] = {
275
+ command: 'npx',
276
+ args: ['purecontext-mcp'],
277
+ };
278
+ config['mcpServers'] = mcpServers;
279
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
280
+ }
281
+ // ─── Dispatch table ───────────────────────────────────────────────────────────
282
+ export const INSTALL_WRITERS = {
283
+ 'claude': installClaude,
284
+ 'cursor': installCursor,
285
+ 'windsurf': installWindsurf,
286
+ 'continue': installContinue,
287
+ 'cline': installCline,
288
+ 'roo-code': installRooCode,
289
+ 'copilot': installCopilot,
290
+ 'claude-desktop': installClaudeDesktop,
291
+ };
292
+ //# sourceMappingURL=install-writers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-writers.js","sourceRoot":"","sources":["../../src/cli/install-writers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAIjE,iFAAiF;AAEjF,MAAM,CAAC,MAAM,YAAY,GAAG,gCAAgC,CAAC;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAG,8BAA8B,CAAC;AAEzD,iFAAiF;AAEjF,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;6EA2BoD,CAAC;AAE9E,MAAM,UAAU,0BAA0B,CAAC,MAA0C;IACnF,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO,sFAAsF,gBAAgB,EAAE,CAAC;IAClH,CAAC;IACD,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QAC7B,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,iFAAiF;AAEjF,SAAS,kBAAkB,CAAC,QAAgB,EAAE,QAAgB;IAC5D,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC1D,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAC7F,CAAC;IACD,6BAA6B;IAC7B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,QAAQ,IAAI,IAAI,CAAC;IAC/C,OAAO,QAAQ,GAAG,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC;AAC3C,CAAC;AAED,SAAS,WAAW,CAAC,OAAe;IAClC,OAAO,GAAG,YAAY,KAAK,OAAO,KAAK,UAAU,EAAE,CAAC;AACtD,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB;IACjC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB,EAAE,OAAe;IACxD,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,iFAAiF;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,KAAY;IACnE,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,WAAW,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC,CAAC;QAClE,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,aAAa,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,eAAe,CAAC,QAAQ,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC3C,eAAe,EAAE,CAAC;IACpB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,KAAY;IACnE,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAE,EAAE;QACpC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpB,MAAM,UAAU,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,IAAI,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBACpC,aAAa,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;gBAC9F,OAAO;YACT,CAAC;QACH,CAAC;QACD,eAAe,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC;IAC/C,CAAC,CAAC;IAEF,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC3C,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAmB,EAAE,KAAY;IACrE,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAE,EAAE;QACtC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpB,aAAa,CAAC,QAAQ,EAAE,0BAA0B,CAAC,UAAU,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAClF,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,EAAE;QACvC,MAAM,KAAK,GAAG,WAAW,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC,CAAC;QAClE,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpB,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,aAAa,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,QAAQ,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC1C,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC3C,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAmB,EAAE,KAAY;IACrE,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,EAAE;QACvC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpB,MAAM,YAAY,GAAG,0BAA0B,CAAC,aAAa,CAAC,CAAC;QAC/D,IAAI,MAAM,GAA4B,EAAE,CAAC;QACzC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAA4B,CAAC;YAClF,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,GAAG,EAAE,CAAC;YACd,CAAC;QACH,CAAC;QACD,MAAM,CAAC,eAAe,CAAC,GAAG,YAAY,CAAC;QACvC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3E,CAAC,CAAC;IAEF,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC1C,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC3C,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAmB,EAAE,KAAY;IAClE,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,WAAW,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC,CAAC;IAClE,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,aAAa,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACN,eAAe,CAAC,QAAQ,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,WAAmB,EAAE,KAAY;IACpE,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,WAAW,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC,CAAC;IAClE,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpB,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,aAAa,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,QAAQ,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,WAAmB,EAAE,KAAY;IACpE,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,yBAAyB,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,WAAW,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC,CAAC;IAClE,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpB,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,aAAa,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,QAAQ,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,YAAoB,EAAE,MAAa;IAC5E,MAAM,UAAU,GAAG,0BAA0B,EAAE,CAAC;IAChD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,SAAS,CAAC,UAAU,CAAC,CAAC;IAEtB,IAAI,MAAM,GAA4B,EAAE,CAAC;IACzC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAA4B,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,CAA4B,CAAC;IAC3E,MAAM,QAAQ,GAAG,UAAU,CAAC,iBAAiB,CAAwC,CAAC;IAEtF,IAAI,QAAQ,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,EAAE,CAAC;QACpC,2CAA2C;QAC3C,OAAO;IACT,CAAC;IAED,UAAU,CAAC,iBAAiB,CAAC,GAAG;QAC9B,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,CAAC,iBAAiB,CAAC;KAC1B,CAAC;IACF,MAAM,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC;IAElC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAC7E,CAAC;AAED,iFAAiF;AAEjF,MAAM,CAAC,MAAM,eAAe,GAAyE;IACnG,QAAQ,EAAE,aAAa;IACvB,QAAQ,EAAE,aAAa;IACvB,UAAU,EAAE,eAAe;IAC3B,UAAU,EAAE,eAAe;IAC3B,OAAO,EAAE,YAAY;IACrB,UAAU,EAAE,cAAc;IAC1B,SAAS,EAAE,cAAc;IACzB,gBAAgB,EAAE,oBAAoB;CACvC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `purecontext-mcp install <tool|all> [--scope=local|global|both] [--dry-run] [--list]`
3
+ *
4
+ * Installs PureContext agent instructions into the conventions file of the
5
+ * specified AI coding IDE. `install all` auto-detects installed tools and
6
+ * installs each in sequence. `install --list` shows detection state without
7
+ * writing anything.
8
+ *
9
+ * If `--scope` is omitted the user is prompted interactively. In
10
+ * non-interactive environments (piped stdin) the prompt is skipped and
11
+ * `local` is used as a safe default.
12
+ */
13
+ export declare function runInstallCommand(args: string[]): Promise<void>;
14
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/cli/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA2IH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BrE"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * `purecontext-mcp install <tool|all> [--scope=local|global|both] [--dry-run] [--list]`
3
+ *
4
+ * Installs PureContext agent instructions into the conventions file of the
5
+ * specified AI coding IDE. `install all` auto-detects installed tools and
6
+ * installs each in sequence. `install --list` shows detection state without
7
+ * writing anything.
8
+ *
9
+ * If `--scope` is omitted the user is prompted interactively. In
10
+ * non-interactive environments (piped stdin) the prompt is skipped and
11
+ * `local` is used as a safe default.
12
+ */
13
+ import { createInterface } from 'readline';
14
+ import { detectInstalledIDEs } from './install-detect.js';
15
+ import { INSTALL_WRITERS } from './install-writers.js';
16
+ // ─── Scope helpers ────────────────────────────────────────────────────────────
17
+ const VALID_SCOPES = ['local', 'global', 'both'];
18
+ function parseScope(args) {
19
+ // --scope=local or --scope local
20
+ const eqForm = args.find((a) => a.startsWith('--scope='))?.split('=')[1];
21
+ if (eqForm)
22
+ return VALID_SCOPES.includes(eqForm) ? eqForm : undefined;
23
+ const idx = args.indexOf('--scope');
24
+ if (idx !== -1 && args[idx + 1]) {
25
+ const val = args[idx + 1];
26
+ return VALID_SCOPES.includes(val) ? val : undefined;
27
+ }
28
+ return undefined;
29
+ }
30
+ async function promptScope() {
31
+ if (!process.stdin.isTTY)
32
+ return 'local';
33
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
34
+ return new Promise((resolve) => {
35
+ console.log('\nWhere should PureContext be installed?');
36
+ console.log(' 1) Local — this project only');
37
+ console.log(' 2) Global — all projects (user-level config)');
38
+ console.log(' 3) Both\n');
39
+ rl.question('Choice [1/2/3]: ', (answer) => {
40
+ rl.close();
41
+ const trimmed = answer.trim();
42
+ if (trimmed === '2')
43
+ resolve('global');
44
+ else if (trimmed === '3')
45
+ resolve('both');
46
+ else
47
+ resolve('local');
48
+ });
49
+ });
50
+ }
51
+ // ─── Constants ────────────────────────────────────────────────────────────────
52
+ const KNOWN_TOOLS = [
53
+ 'claude',
54
+ 'cursor',
55
+ 'windsurf',
56
+ 'continue',
57
+ 'cline',
58
+ 'roo-code',
59
+ 'copilot',
60
+ 'claude-desktop',
61
+ ];
62
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
63
+ function isKnownTool(tool) {
64
+ return KNOWN_TOOLS.includes(tool);
65
+ }
66
+ async function runInstall(tool, projectRoot, dryRun, scope) {
67
+ const writer = INSTALL_WRITERS[tool];
68
+ if (!writer)
69
+ return false;
70
+ if (dryRun) {
71
+ console.log(` [dry-run] Would install: ${tool} (${scope})`);
72
+ return true;
73
+ }
74
+ try {
75
+ await writer(projectRoot, scope);
76
+ return true;
77
+ }
78
+ catch (err) {
79
+ process.stderr.write(` Error installing ${tool}: ${err.message}\n`);
80
+ return false;
81
+ }
82
+ }
83
+ // ─── Sub-commands ─────────────────────────────────────────────────────────────
84
+ async function cmdInstallOne(tool, projectRoot, dryRun, scope) {
85
+ if (!isKnownTool(tool)) {
86
+ process.stderr.write(`Unknown tool: "${tool}"\nValid tools: ${KNOWN_TOOLS.join(', ')}\n`);
87
+ process.exit(1);
88
+ }
89
+ const ok = await runInstall(tool, projectRoot, dryRun, scope);
90
+ if (ok && !dryRun) {
91
+ console.log(`\nInstalled for ${tool} (${scope}).`);
92
+ }
93
+ }
94
+ async function cmdInstallAll(projectRoot, dryRun, scope) {
95
+ const detected = await detectInstalledIDEs(projectRoot);
96
+ if (detected.length === 0) {
97
+ console.log('No supported IDEs detected in this directory.');
98
+ console.log(`Run \`npx purecontext-mcp install <tool>\` to install for a specific tool.`);
99
+ console.log(`Supported tools: ${KNOWN_TOOLS.join(', ')}`);
100
+ return;
101
+ }
102
+ const notDetected = KNOWN_TOOLS.filter((t) => !detected.includes(t));
103
+ console.log(`Detected IDEs: ${detected.join(', ')}\n`);
104
+ // Always include claude hooks when installing any tool
105
+ const toInstall = detected.includes('claude')
106
+ ? detected
107
+ : ['claude', ...detected];
108
+ for (const tool of toInstall) {
109
+ const label = `Installing ${tool}...`.padEnd(24);
110
+ const ok = await runInstall(tool, projectRoot, dryRun, scope);
111
+ console.log(`${label} ${ok ? '✓' : '✗'}`);
112
+ }
113
+ if (notDetected.length > 0) {
114
+ console.log(`\nNot detected: ${notDetected.join(', ')}`);
115
+ console.log(`Run \`npx purecontext-mcp install <tool>\` to install for a specific tool manually.`);
116
+ }
117
+ }
118
+ async function cmdInstallList(projectRoot) {
119
+ const detected = await detectInstalledIDEs(projectRoot);
120
+ console.log('\nIDE detection results:\n');
121
+ for (const tool of KNOWN_TOOLS) {
122
+ const status = detected.includes(tool) ? 'detected' : 'not detected';
123
+ console.log(` ${tool.padEnd(16)} ${status}`);
124
+ }
125
+ console.log();
126
+ }
127
+ // ─── CLI dispatcher ───────────────────────────────────────────────────────────
128
+ export async function runInstallCommand(args) {
129
+ const projectRoot = process.cwd();
130
+ const dryRun = args.includes('--dry-run');
131
+ const listFlag = args.includes('--list');
132
+ const toolArg = args.find((a) => !a.startsWith('--'));
133
+ if (listFlag) {
134
+ await cmdInstallList(projectRoot);
135
+ return;
136
+ }
137
+ if (!toolArg) {
138
+ process.stderr.write('Usage: purecontext-mcp install <tool|all> [--scope=local|global|both] [--dry-run] [--list]\n');
139
+ process.stderr.write(`Supported tools: ${KNOWN_TOOLS.join(', ')}\n`);
140
+ process.exit(1);
141
+ }
142
+ const scope = parseScope(args) ?? (await promptScope());
143
+ if (toolArg === 'all') {
144
+ await cmdInstallAll(projectRoot, dryRun, scope);
145
+ }
146
+ else {
147
+ await cmdInstallOne(toolArg, projectRoot, dryRun, scope);
148
+ }
149
+ }
150
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/cli/install.ts"],"names":[],"mappings":"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"}
@@ -127,6 +127,9 @@ function mergeConfig(partial) {
127
127
  },
128
128
  maxFileSizeBytes: partial.maxFileSizeBytes ?? DEFAULT_CONFIG.maxFileSizeBytes,
129
129
  allowSymlinks: partial.allowSymlinks ?? DEFAULT_CONFIG.allowSymlinks,
130
+ indexing: {
131
+ cssVariables: partial.indexing?.cssVariables ?? DEFAULT_CONFIG.indexing.cssVariables,
132
+ },
130
133
  transport: partial.transport ?? DEFAULT_CONFIG.transport,
131
134
  http: {
132
135
  port: pctxPort ?? partial.http?.port ?? DEFAULT_CONFIG.http.port,