@opensip-cli/mcp 0.1.15

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 (188) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +33 -0
  4. package/dist/__tests__/command-transport.test.d.ts +13 -0
  5. package/dist/__tests__/command-transport.test.d.ts.map +1 -0
  6. package/dist/__tests__/command-transport.test.js +63 -0
  7. package/dist/__tests__/command-transport.test.js.map +1 -0
  8. package/dist/__tests__/e2e-stdio.test.d.ts +16 -0
  9. package/dist/__tests__/e2e-stdio.test.d.ts.map +1 -0
  10. package/dist/__tests__/e2e-stdio.test.js +271 -0
  11. package/dist/__tests__/e2e-stdio.test.js.map +1 -0
  12. package/dist/__tests__/freshness.test.d.ts +9 -0
  13. package/dist/__tests__/freshness.test.d.ts.map +1 -0
  14. package/dist/__tests__/freshness.test.js +78 -0
  15. package/dist/__tests__/freshness.test.js.map +1 -0
  16. package/dist/__tests__/integration.test.d.ts +20 -0
  17. package/dist/__tests__/integration.test.d.ts.map +1 -0
  18. package/dist/__tests__/integration.test.js +178 -0
  19. package/dist/__tests__/integration.test.js.map +1 -0
  20. package/dist/__tests__/register-mcp-graph-adapters.test.d.ts +12 -0
  21. package/dist/__tests__/register-mcp-graph-adapters.test.d.ts.map +1 -0
  22. package/dist/__tests__/register-mcp-graph-adapters.test.js +47 -0
  23. package/dist/__tests__/register-mcp-graph-adapters.test.js.map +1 -0
  24. package/dist/__tests__/session-results-read-port.test.d.ts +13 -0
  25. package/dist/__tests__/session-results-read-port.test.d.ts.map +1 -0
  26. package/dist/__tests__/session-results-read-port.test.js +151 -0
  27. package/dist/__tests__/session-results-read-port.test.js.map +1 -0
  28. package/dist/__tests__/sqlite-graph-read-port.test.d.ts +12 -0
  29. package/dist/__tests__/sqlite-graph-read-port.test.d.ts.map +1 -0
  30. package/dist/__tests__/sqlite-graph-read-port.test.js +322 -0
  31. package/dist/__tests__/sqlite-graph-read-port.test.js.map +1 -0
  32. package/dist/__tests__/tool-descriptor.test.d.ts +9 -0
  33. package/dist/__tests__/tool-descriptor.test.d.ts.map +1 -0
  34. package/dist/__tests__/tool-descriptor.test.js +55 -0
  35. package/dist/__tests__/tool-descriptor.test.js.map +1 -0
  36. package/dist/catalog-generation.d.ts +22 -0
  37. package/dist/catalog-generation.d.ts.map +1 -0
  38. package/dist/catalog-generation.js +21 -0
  39. package/dist/catalog-generation.js.map +1 -0
  40. package/dist/command.d.ts +3 -0
  41. package/dist/command.d.ts.map +1 -0
  42. package/dist/command.js +111 -0
  43. package/dist/command.js.map +1 -0
  44. package/dist/freshness.d.ts +50 -0
  45. package/dist/freshness.d.ts.map +1 -0
  46. package/dist/freshness.js +96 -0
  47. package/dist/freshness.js.map +1 -0
  48. package/dist/graph-read-port.d.ts +111 -0
  49. package/dist/graph-read-port.d.ts.map +1 -0
  50. package/dist/graph-read-port.js +16 -0
  51. package/dist/graph-read-port.js.map +1 -0
  52. package/dist/index.d.ts +9 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +9 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/mcp-error.d.ts +15 -0
  57. package/dist/mcp-error.d.ts.map +1 -0
  58. package/dist/mcp-error.js +5 -0
  59. package/dist/mcp-error.js.map +1 -0
  60. package/dist/register-mcp-graph-adapters.d.ts +3 -0
  61. package/dist/register-mcp-graph-adapters.d.ts.map +1 -0
  62. package/dist/register-mcp-graph-adapters.js +21 -0
  63. package/dist/register-mcp-graph-adapters.js.map +1 -0
  64. package/dist/result-dto.d.ts +63 -0
  65. package/dist/result-dto.d.ts.map +1 -0
  66. package/dist/result-dto.js +11 -0
  67. package/dist/result-dto.js.map +1 -0
  68. package/dist/results-read-port.d.ts +43 -0
  69. package/dist/results-read-port.d.ts.map +1 -0
  70. package/dist/results-read-port.js +13 -0
  71. package/dist/results-read-port.js.map +1 -0
  72. package/dist/server.d.ts +84 -0
  73. package/dist/server.d.ts.map +1 -0
  74. package/dist/server.js +153 -0
  75. package/dist/server.js.map +1 -0
  76. package/dist/session-results-read-port.d.ts +42 -0
  77. package/dist/session-results-read-port.d.ts.map +1 -0
  78. package/dist/session-results-read-port.js +147 -0
  79. package/dist/session-results-read-port.js.map +1 -0
  80. package/dist/sqlite-graph-read-port.d.ts +88 -0
  81. package/dist/sqlite-graph-read-port.d.ts.map +1 -0
  82. package/dist/sqlite-graph-read-port.js +304 -0
  83. package/dist/sqlite-graph-read-port.js.map +1 -0
  84. package/dist/symbol-dto.d.ts +58 -0
  85. package/dist/symbol-dto.d.ts.map +1 -0
  86. package/dist/symbol-dto.js +12 -0
  87. package/dist/symbol-dto.js.map +1 -0
  88. package/dist/tool.d.ts +6 -0
  89. package/dist/tool.d.ts.map +1 -0
  90. package/dist/tool.js +33 -0
  91. package/dist/tool.js.map +1 -0
  92. package/dist/tools/__tests__/graph-handlers.test.d.ts +11 -0
  93. package/dist/tools/__tests__/graph-handlers.test.d.ts.map +1 -0
  94. package/dist/tools/__tests__/graph-handlers.test.js +415 -0
  95. package/dist/tools/__tests__/graph-handlers.test.js.map +1 -0
  96. package/dist/tools/__tests__/graph-walk.test.d.ts +9 -0
  97. package/dist/tools/__tests__/graph-walk.test.d.ts.map +1 -0
  98. package/dist/tools/__tests__/graph-walk.test.js +72 -0
  99. package/dist/tools/__tests__/graph-walk.test.js.map +1 -0
  100. package/dist/tools/__tests__/refresh-graph.test.d.ts +11 -0
  101. package/dist/tools/__tests__/refresh-graph.test.d.ts.map +1 -0
  102. package/dist/tools/__tests__/refresh-graph.test.js +100 -0
  103. package/dist/tools/__tests__/refresh-graph.test.js.map +1 -0
  104. package/dist/tools/__tests__/result-handlers.test.d.ts +9 -0
  105. package/dist/tools/__tests__/result-handlers.test.d.ts.map +1 -0
  106. package/dist/tools/__tests__/result-handlers.test.js +194 -0
  107. package/dist/tools/__tests__/result-handlers.test.js.map +1 -0
  108. package/dist/tools/__tests__/schemas.test.d.ts +10 -0
  109. package/dist/tools/__tests__/schemas.test.d.ts.map +1 -0
  110. package/dist/tools/__tests__/schemas.test.js +73 -0
  111. package/dist/tools/__tests__/schemas.test.js.map +1 -0
  112. package/dist/tools/blast-radius.d.ts +12 -0
  113. package/dist/tools/blast-radius.d.ts.map +1 -0
  114. package/dist/tools/blast-radius.js +33 -0
  115. package/dist/tools/blast-radius.js.map +1 -0
  116. package/dist/tools/call-walk-tool.d.ts +17 -0
  117. package/dist/tools/call-walk-tool.d.ts.map +1 -0
  118. package/dist/tools/call-walk-tool.js +46 -0
  119. package/dist/tools/call-walk-tool.js.map +1 -0
  120. package/dist/tools/callees-of.d.ts +12 -0
  121. package/dist/tools/callees-of.d.ts.map +1 -0
  122. package/dist/tools/callees-of.js +20 -0
  123. package/dist/tools/callees-of.js.map +1 -0
  124. package/dist/tools/find-dead-code.d.ts +11 -0
  125. package/dist/tools/find-dead-code.d.ts.map +1 -0
  126. package/dist/tools/find-dead-code.js +26 -0
  127. package/dist/tools/find-dead-code.js.map +1 -0
  128. package/dist/tools/get-agent-catalog.d.ts +12 -0
  129. package/dist/tools/get-agent-catalog.d.ts.map +1 -0
  130. package/dist/tools/get-agent-catalog.js +23 -0
  131. package/dist/tools/get-agent-catalog.js.map +1 -0
  132. package/dist/tools/get-architecture.d.ts +11 -0
  133. package/dist/tools/get-architecture.d.ts.map +1 -0
  134. package/dist/tools/get-architecture.js +26 -0
  135. package/dist/tools/get-architecture.js.map +1 -0
  136. package/dist/tools/get-latest-findings.d.ts +13 -0
  137. package/dist/tools/get-latest-findings.d.ts.map +1 -0
  138. package/dist/tools/get-latest-findings.js +38 -0
  139. package/dist/tools/get-latest-findings.js.map +1 -0
  140. package/dist/tools/get-symbol.d.ts +18 -0
  141. package/dist/tools/get-symbol.d.ts.map +1 -0
  142. package/dist/tools/get-symbol.js +44 -0
  143. package/dist/tools/get-symbol.js.map +1 -0
  144. package/dist/tools/graph-walk.d.ts +50 -0
  145. package/dist/tools/graph-walk.d.ts.map +1 -0
  146. package/dist/tools/graph-walk.js +89 -0
  147. package/dist/tools/graph-walk.js.map +1 -0
  148. package/dist/tools/list-runs.d.ts +11 -0
  149. package/dist/tools/list-runs.d.ts.map +1 -0
  150. package/dist/tools/list-runs.js +37 -0
  151. package/dist/tools/list-runs.js.map +1 -0
  152. package/dist/tools/refresh-graph.d.ts +22 -0
  153. package/dist/tools/refresh-graph.d.ts.map +1 -0
  154. package/dist/tools/refresh-graph.js +75 -0
  155. package/dist/tools/refresh-graph.js.map +1 -0
  156. package/dist/tools/register.d.ts +13 -0
  157. package/dist/tools/register.d.ts.map +1 -0
  158. package/dist/tools/register.js +40 -0
  159. package/dist/tools/register.js.map +1 -0
  160. package/dist/tools/schemas.d.ts +54 -0
  161. package/dist/tools/schemas.d.ts.map +1 -0
  162. package/dist/tools/schemas.js +59 -0
  163. package/dist/tools/schemas.js.map +1 -0
  164. package/dist/tools/search-symbols.d.ts +12 -0
  165. package/dist/tools/search-symbols.d.ts.map +1 -0
  166. package/dist/tools/search-symbols.js +37 -0
  167. package/dist/tools/search-symbols.js.map +1 -0
  168. package/dist/tools/show-run.d.ts +12 -0
  169. package/dist/tools/show-run.d.ts.map +1 -0
  170. package/dist/tools/show-run.js +40 -0
  171. package/dist/tools/show-run.js.map +1 -0
  172. package/dist/tools/tool-result.d.ts +29 -0
  173. package/dist/tools/tool-result.d.ts.map +1 -0
  174. package/dist/tools/tool-result.js +39 -0
  175. package/dist/tools/tool-result.js.map +1 -0
  176. package/dist/tools/trace-path.d.ts +12 -0
  177. package/dist/tools/trace-path.d.ts.map +1 -0
  178. package/dist/tools/trace-path.js +57 -0
  179. package/dist/tools/trace-path.js.map +1 -0
  180. package/dist/tools/types.d.ts +20 -0
  181. package/dist/tools/types.d.ts.map +1 -0
  182. package/dist/tools/types.js +11 -0
  183. package/dist/tools/types.js.map +1 -0
  184. package/dist/tools/who-calls.d.ts +12 -0
  185. package/dist/tools/who-calls.d.ts.map +1 -0
  186. package/dist/tools/who-calls.js +21 -0
  187. package/dist/tools/who-calls.js.map +1 -0
  188. package/package.json +104 -0
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `find_dead_code` — orphan (unreachable) symbols (ADR-0084, Task 4.3).
3
+ *
4
+ * Delegates to `graphPort.deadCode()`, backed by graph's `orphan-subtree` rule
5
+ * (reachability from entry points) — NOT ad-hoc filesystem reachability. Returns
6
+ * the `{ data, freshness, truncated? }` envelope; `limit` caps the result.
7
+ */
8
+ import { limit as limitSchema } from './schemas.js';
9
+ import { errorResult, jsonResult } from './tool-result.js';
10
+ export function registerFindDeadCode(server, deps) {
11
+ server.register('find_dead_code', {
12
+ title: 'Find dead code',
13
+ description: 'List symbols unreachable from any entry point (the graph orphan-subtree rule). Each ' +
14
+ 'finding carries its symbolId + a reason. Reads the catalog only — no filesystem walk. ' +
15
+ 'Use `limit` to cap results.',
16
+ inputSchema: {
17
+ limit: limitSchema(),
18
+ },
19
+ }, ({ limit }) => {
20
+ const outcome = deps.graph.deadCode(limit);
21
+ if (!outcome.ok)
22
+ return errorResult(outcome.error);
23
+ return jsonResult(outcome.value);
24
+ });
25
+ }
26
+ //# sourceMappingURL=find-dead-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-dead-code.js","sourceRoot":"","sources":["../../src/tools/find-dead-code.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAK3D,MAAM,UAAU,oBAAoB,CAAC,MAAsB,EAAE,IAAiB;IAC5E,MAAM,CAAC,QAAQ,CACb,gBAAgB,EAChB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,sFAAsF;YACtF,wFAAwF;YACxF,6BAA6B;QAC/B,WAAW,EAAE;YACX,KAAK,EAAE,WAAW,EAAE;SACrB;KACF,EACD,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;QACZ,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `get_agent_catalog` — the self-describing OpenSIP command catalog (ADR-0084,
3
+ * Task 4.5).
4
+ *
5
+ * Reads `resultsPort.agentCatalog()` ONLY — never invokes a tool. Highlights the
6
+ * result-first workflow: an agent inspects existing findings (get_latest_findings,
7
+ * show_run, list_runs) before re-running anything.
8
+ */
9
+ import type { McpToolDeps } from './types.js';
10
+ import type { McpStdioServer } from '../server.js';
11
+ export declare function registerGetAgentCatalog(server: McpStdioServer, deps: McpToolDeps): void;
12
+ //# sourceMappingURL=get-agent-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-agent-catalog.d.ts","sourceRoot":"","sources":["../../src/tools/get-agent-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAgBvF"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `get_agent_catalog` — the self-describing OpenSIP command catalog (ADR-0084,
3
+ * Task 4.5).
4
+ *
5
+ * Reads `resultsPort.agentCatalog()` ONLY — never invokes a tool. Highlights the
6
+ * result-first workflow: an agent inspects existing findings (get_latest_findings,
7
+ * show_run, list_runs) before re-running anything.
8
+ */
9
+ import { errorResult, jsonResult } from './tool-result.js';
10
+ export function registerGetAgentCatalog(server, deps) {
11
+ server.register('get_agent_catalog', {
12
+ title: 'OpenSIP agent command catalog',
13
+ description: 'The self-describing catalog of OpenSIP commands an agent can run. Prefer the result ' +
14
+ 'tools (get_latest_findings, show_run, list_runs) to inspect EXISTING findings before ' +
15
+ 're-running any tool — re-running is expensive and usually unnecessary.',
16
+ }, () => {
17
+ const outcome = deps.results.agentCatalog();
18
+ if (!outcome.ok)
19
+ return errorResult(outcome.error);
20
+ return jsonResult(outcome.value);
21
+ });
22
+ }
23
+ //# sourceMappingURL=get-agent-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-agent-catalog.js","sourceRoot":"","sources":["../../src/tools/get-agent-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAK3D,MAAM,UAAU,uBAAuB,CAAC,MAAsB,EAAE,IAAiB;IAC/E,MAAM,CAAC,QAAQ,CACb,mBAAmB,EACnB;QACE,KAAK,EAAE,+BAA+B;QACtC,WAAW,EACT,sFAAsF;YACtF,uFAAuF;YACvF,wEAAwE;KAC3E,EACD,GAAG,EAAE;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAC5C,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `get_architecture` — compact codebase overview (ADR-0084, Task 4.3).
3
+ *
4
+ * Delegates to `graphPort.architectureSummary()`: function/edge counts,
5
+ * languages, the top-coupled packages, and the highest-blast hotspots (graph's
6
+ * canonical scoring). Capped via `limit`; carries `{ freshness }`.
7
+ */
8
+ import type { McpToolDeps } from './types.js';
9
+ import type { McpStdioServer } from '../server.js';
10
+ export declare function registerGetArchitecture(server: McpStdioServer, deps: McpToolDeps): void;
11
+ //# sourceMappingURL=get-architecture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-architecture.d.ts","sourceRoot":"","sources":["../../src/tools/get-architecture.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAmBvF"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `get_architecture` — compact codebase overview (ADR-0084, Task 4.3).
3
+ *
4
+ * Delegates to `graphPort.architectureSummary()`: function/edge counts,
5
+ * languages, the top-coupled packages, and the highest-blast hotspots (graph's
6
+ * canonical scoring). Capped via `limit`; carries `{ freshness }`.
7
+ */
8
+ import { limit as limitSchema } from './schemas.js';
9
+ import { errorResult, jsonResult } from './tool-result.js';
10
+ export function registerGetArchitecture(server, deps) {
11
+ server.register('get_architecture', {
12
+ title: 'Architecture overview',
13
+ description: 'High-level shape of the codebase: function/edge counts, languages, the most-coupled ' +
14
+ 'packages, and the highest blast-radius hotspots. A cheap first call to orient before ' +
15
+ 'drilling in with who_calls/blast_radius. Use `limit` to cap rows.',
16
+ inputSchema: {
17
+ limit: limitSchema(),
18
+ },
19
+ }, ({ limit }) => {
20
+ const outcome = deps.graph.architectureSummary(limit);
21
+ if (!outcome.ok)
22
+ return errorResult(outcome.error);
23
+ return jsonResult(outcome.value);
24
+ });
25
+ }
26
+ //# sourceMappingURL=get-architecture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-architecture.js","sourceRoot":"","sources":["../../src/tools/get-architecture.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAK3D,MAAM,UAAU,uBAAuB,CAAC,MAAsB,EAAE,IAAiB;IAC/E,MAAM,CAAC,QAAQ,CACb,kBAAkB,EAClB;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,sFAAsF;YACtF,uFAAuF;YACvF,mEAAmE;QACrE,WAAW,EAAE;YACX,KAAK,EAAE,WAAW,EAAE;SACrB;KACF,EACD,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;QACZ,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `get_latest_findings` — the behavior-critical, result-first tool (ADR-0084,
3
+ * Task 4.5).
4
+ *
5
+ * Reads `resultsPort.latestFindings()` ONLY — replays the most recent stored run
6
+ * for `tool`, severity/limit-filtered. Its description STEERS agents here before
7
+ * re-running OpenSIP (the verbatim instruction below is a product contract).
8
+ * Validates `tool` against the live registry → structured unknown-tool error.
9
+ */
10
+ import type { McpToolDeps } from './types.js';
11
+ import type { McpStdioServer } from '../server.js';
12
+ export declare function registerGetLatestFindings(server: McpStdioServer, deps: McpToolDeps): void;
13
+ //# sourceMappingURL=get-latest-findings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-latest-findings.d.ts","sourceRoot":"","sources":["../../src/tools/get-latest-findings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA4BzF"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * `get_latest_findings` — the behavior-critical, result-first tool (ADR-0084,
3
+ * Task 4.5).
4
+ *
5
+ * Reads `resultsPort.latestFindings()` ONLY — replays the most recent stored run
6
+ * for `tool`, severity/limit-filtered. Its description STEERS agents here before
7
+ * re-running OpenSIP (the verbatim instruction below is a product contract).
8
+ * Validates `tool` against the live registry → structured unknown-tool error.
9
+ */
10
+ import { limit as limitSchema, severity as severitySchema, toolId as toolIdSchema, } from './schemas.js';
11
+ import { errorResult, jsonResult, unknownToolError } from './tool-result.js';
12
+ export function registerGetLatestFindings(server, deps) {
13
+ server.register('get_latest_findings', {
14
+ title: 'Latest findings for a tool',
15
+ description: 'Get the findings from the most recent OpenSIP run of a tool (fit, graph, yagni, sim). ' +
16
+ 'Use this before re-running OpenSIP when the user mentions existing fit, graph, yagni, ' +
17
+ 'sim, errors, warnings, findings, or prior results. Filter by `severity` ' +
18
+ '(errors/warnings/all) and cap with `limit`. Replays the persisted session; never ' +
19
+ 're-runs the tool.',
20
+ inputSchema: {
21
+ tool: toolIdSchema(),
22
+ severity: severitySchema(),
23
+ limit: limitSchema(),
24
+ },
25
+ }, async ({ tool, severity, limit }) => {
26
+ if (!deps.validToolIds.has(tool))
27
+ return unknownToolError(tool, deps.validToolIds);
28
+ const outcome = await deps.results.latestFindings({
29
+ tool,
30
+ ...(severity === undefined ? {} : { severity }),
31
+ ...(limit === undefined ? {} : { limit }),
32
+ });
33
+ if (!outcome.ok)
34
+ return errorResult(outcome.error);
35
+ return jsonResult(outcome.value);
36
+ });
37
+ }
38
+ //# sourceMappingURL=get-latest-findings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-latest-findings.js","sourceRoot":"","sources":["../../src/tools/get-latest-findings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,KAAK,IAAI,WAAW,EACpB,QAAQ,IAAI,cAAc,EAC1B,MAAM,IAAI,YAAY,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAK7E,MAAM,UAAU,yBAAyB,CAAC,MAAsB,EAAE,IAAiB;IACjF,MAAM,CAAC,QAAQ,CACb,qBAAqB,EACrB;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EACT,wFAAwF;YACxF,wFAAwF;YACxF,0EAA0E;YAC1E,mFAAmF;YACnF,mBAAmB;QACrB,WAAW,EAAE;YACX,IAAI,EAAE,YAAY,EAAE;YACpB,QAAQ,EAAE,cAAc,EAAE;YAC1B,KAAK,EAAE,WAAW,EAAE;SACrB;KACF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;QAClC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QACnF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;YAChD,IAAI;YACJ,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;YAC/C,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;SAC1C,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `get_symbol` — resolve a symbol by file + line (ADR-0084, Task 4.1).
3
+ *
4
+ * Span-containment: every occurrence whose `[line, endLine]` span encloses the
5
+ * requested line. The result is deterministic and NEVER a silent pick:
6
+ * - exactly one → `{ data: SymbolRef, freshness }`
7
+ * - more than one → `{ ambiguous: true, candidates: SymbolRef[], freshness }`
8
+ * (the agent disambiguates by picking a `symbolId`)
9
+ * - none → a structured `symbol-not-found` error
10
+ *
11
+ * Each `SymbolRef` carries the stable `symbolId` + `bodyHash`. Reads only
12
+ * `graphPort` (no filesystem read — the `file` arg is matched against the
13
+ * catalog's project-relative paths).
14
+ */
15
+ import type { McpToolDeps } from './types.js';
16
+ import type { McpStdioServer } from '../server.js';
17
+ export declare function registerGetSymbol(server: McpStdioServer, deps: McpToolDeps): void;
18
+ //# sourceMappingURL=get-symbol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-symbol.d.ts","sourceRoot":"","sources":["../../src/tools/get-symbol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAgCjF"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * `get_symbol` — resolve a symbol by file + line (ADR-0084, Task 4.1).
3
+ *
4
+ * Span-containment: every occurrence whose `[line, endLine]` span encloses the
5
+ * requested line. The result is deterministic and NEVER a silent pick:
6
+ * - exactly one → `{ data: SymbolRef, freshness }`
7
+ * - more than one → `{ ambiguous: true, candidates: SymbolRef[], freshness }`
8
+ * (the agent disambiguates by picking a `symbolId`)
9
+ * - none → a structured `symbol-not-found` error
10
+ *
11
+ * Each `SymbolRef` carries the stable `symbolId` + `bodyHash`. Reads only
12
+ * `graphPort` (no filesystem read — the `file` arg is matched against the
13
+ * catalog's project-relative paths).
14
+ */
15
+ import { filePath as filePathSchema, line as lineSchema } from './schemas.js';
16
+ import { errorResult, failure, jsonResult } from './tool-result.js';
17
+ export function registerGetSymbol(server, deps) {
18
+ server.register('get_symbol', {
19
+ title: 'Get symbol by location',
20
+ description: 'Resolve the function/method declared at a project-relative file + line into a stable ' +
21
+ 'symbolId ("<filePath>:<line>:<column>") + bodyHash. On ambiguity (nested declarations ' +
22
+ 'enclosing the line) returns a candidate list — never a silent pick. Use the returned ' +
23
+ 'symbolId with who_calls, callees_of, blast_radius, or trace_path.',
24
+ inputSchema: {
25
+ file: filePathSchema(),
26
+ line: lineSchema(),
27
+ },
28
+ }, ({ file, line }) => {
29
+ const outcome = deps.graph.findBySpan(file, line);
30
+ if (!outcome.ok)
31
+ return errorResult(outcome.error);
32
+ const { data: candidates, freshness } = outcome.value;
33
+ if (candidates.length === 0) {
34
+ return failure('symbol-not-found', `No symbol declaration encloses ${file}:${String(line)}. ` +
35
+ (freshness.fresh
36
+ ? 'Check the file/line, or use search_symbols by name.'
37
+ : 'The catalog is stale/missing — run refresh_graph, then retry.'));
38
+ }
39
+ if (candidates.length === 1)
40
+ return jsonResult({ data: candidates[0], freshness });
41
+ return jsonResult({ ambiguous: true, candidates, freshness });
42
+ });
43
+ }
44
+ //# sourceMappingURL=get-symbol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-symbol.js","sourceRoot":"","sources":["../../src/tools/get-symbol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKpE,MAAM,UAAU,iBAAiB,CAAC,MAAsB,EAAE,IAAiB;IACzE,MAAM,CAAC,QAAQ,CACb,YAAY,EACZ;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,uFAAuF;YACvF,wFAAwF;YACxF,uFAAuF;YACvF,mEAAmE;QACrE,WAAW,EAAE;YACX,IAAI,EAAE,cAAc,EAAE;YACtB,IAAI,EAAE,UAAU,EAAE;SACnB;KACF,EACD,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,OAAO,CACZ,kBAAkB,EAClB,kCAAkC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI;gBACxD,CAAC,SAAS,CAAC,KAAK;oBACd,CAAC,CAAC,qDAAqD;oBACvD,CAAC,CAAC,+DAA+D,CAAC,CACvE,CAAC;QACJ,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QACnF,OAAO,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * `boundedBfs` — the single MCP traversal primitive (ADR-0084, Task 4.2).
3
+ *
4
+ * `who_calls`, `callees_of`, and `trace_path` are three callers of ONE
5
+ * generic bounded-adjacency walk → rule of three satisfied. This helper lives in
6
+ * `packages/mcp/` because it is MCP-specific traversal vocabulary: blast scoring
7
+ * stays in `@opensip-cli/graph` (`buildFeatures(['blast'])`, reused via the
8
+ * port), symbol projection stays in graph (`buildSymbolIndexEntries`) — neither
9
+ * is reinvented here, and `boundedBfs` is NEVER pushed down into `core`/`graph`.
10
+ *
11
+ * The walk is over a body-hash adjacency map (the graph engine's
12
+ * `Indexes.callers` / `Indexes.callees`, twin-union per ADR-0003). It is:
13
+ * - cycle-safe — a `visited` set guards re-entry,
14
+ * - depth-bounded — at most {@link HARD_MAX_DEPTH} BFS levels,
15
+ * - count-capped — stops at `cap` discovered nodes and reports `truncated`,
16
+ * - optionally goal-directed — returns the moment a `goal` node is reached,
17
+ * recording `parents` so the caller can reconstruct the path.
18
+ */
19
+ /** Hard node cap on a single walk before `truncated` is set (mirrors the port's ceiling). */
20
+ export declare const MAX_WALK_NODES = 2000;
21
+ export interface BoundedBfsOptions {
22
+ /** BFS levels to expand (clamped to `[1, HARD_MAX_DEPTH]`). */
23
+ readonly depth: number;
24
+ /** Discovered-node ceiling; `<= 0` falls back to {@link MAX_WALK_NODES}. */
25
+ readonly cap: number;
26
+ /** When set, the walk returns the instant this node is reached (`foundGoal`). */
27
+ readonly goal?: string;
28
+ }
29
+ export interface BoundedBfsResult {
30
+ /** Nodes reached, in discovery order, EXCLUDING `start`. */
31
+ readonly order: readonly string[];
32
+ /** `node → predecessor` for every reached node (for path reconstruction). */
33
+ readonly parents: ReadonlyMap<string, string>;
34
+ /** `true` iff `opts.goal` was provided and reached within the bounds. */
35
+ readonly foundGoal: boolean;
36
+ /** `true` iff a depth/node cap truncated the walk. */
37
+ readonly truncated: boolean;
38
+ }
39
+ /**
40
+ * Bounded, cycle-safe BFS from `start` over `adjacency`. Returns the reached
41
+ * node set (discovery order), the predecessor map, whether `goal` was reached,
42
+ * and whether a cap truncated the walk.
43
+ */
44
+ export declare function boundedBfs(adjacency: ReadonlyMap<string, readonly string[]>, start: string, opts: BoundedBfsOptions): BoundedBfsResult;
45
+ /**
46
+ * Rebuild the path `start → … → goal` from a {@link BoundedBfsResult.parents}
47
+ * map. Only meaningful when the walk reached `goal` (`foundGoal`).
48
+ */
49
+ export declare function reconstructPath(parents: ReadonlyMap<string, string>, start: string, goal: string): string[];
50
+ //# sourceMappingURL=graph-walk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-walk.d.ts","sourceRoot":"","sources":["../../src/tools/graph-walk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,6FAA6F;AAC7F,eAAO,MAAM,cAAc,OAAO,CAAC;AASnC,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAOD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EACjD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,iBAAiB,GACtB,gBAAgB,CAkBlB;AAsCD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,MAAM,EAAE,CASV"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * `boundedBfs` — the single MCP traversal primitive (ADR-0084, Task 4.2).
3
+ *
4
+ * `who_calls`, `callees_of`, and `trace_path` are three callers of ONE
5
+ * generic bounded-adjacency walk → rule of three satisfied. This helper lives in
6
+ * `packages/mcp/` because it is MCP-specific traversal vocabulary: blast scoring
7
+ * stays in `@opensip-cli/graph` (`buildFeatures(['blast'])`, reused via the
8
+ * port), symbol projection stays in graph (`buildSymbolIndexEntries`) — neither
9
+ * is reinvented here, and `boundedBfs` is NEVER pushed down into `core`/`graph`.
10
+ *
11
+ * The walk is over a body-hash adjacency map (the graph engine's
12
+ * `Indexes.callers` / `Indexes.callees`, twin-union per ADR-0003). It is:
13
+ * - cycle-safe — a `visited` set guards re-entry,
14
+ * - depth-bounded — at most {@link HARD_MAX_DEPTH} BFS levels,
15
+ * - count-capped — stops at `cap` discovered nodes and reports `truncated`,
16
+ * - optionally goal-directed — returns the moment a `goal` node is reached,
17
+ * recording `parents` so the caller can reconstruct the path.
18
+ */
19
+ /** Hard node cap on a single walk before `truncated` is set (mirrors the port's ceiling). */
20
+ export const MAX_WALK_NODES = 2000;
21
+ /**
22
+ * Defence-in-depth depth ceiling, mirroring `schemas.MAX_DEPTH`. The Zod input
23
+ * schema already clamps `depth` to `[1, 5]` at the boundary; this keeps the pure
24
+ * walk correct even if invoked directly (tests) with an out-of-range depth.
25
+ */
26
+ const HARD_MAX_DEPTH = 5;
27
+ function clampDepth(depth) {
28
+ if (!Number.isFinite(depth))
29
+ return HARD_MAX_DEPTH;
30
+ return Math.min(Math.max(Math.trunc(depth), 1), HARD_MAX_DEPTH);
31
+ }
32
+ /**
33
+ * Bounded, cycle-safe BFS from `start` over `adjacency`. Returns the reached
34
+ * node set (discovery order), the predecessor map, whether `goal` was reached,
35
+ * and whether a cap truncated the walk.
36
+ */
37
+ export function boundedBfs(adjacency, start, opts) {
38
+ const maxDepth = clampDepth(opts.depth);
39
+ const cap = opts.cap > 0 ? Math.trunc(opts.cap) : MAX_WALK_NODES;
40
+ const state = {
41
+ visited: new Set([start]),
42
+ parents: new Map(),
43
+ order: [],
44
+ };
45
+ let frontier = [start];
46
+ for (let d = 0; d < maxDepth && frontier.length > 0; d++) {
47
+ const step = expandFrontier(frontier, adjacency, state, cap, opts.goal);
48
+ if (step.halt !== undefined) {
49
+ return { order: state.order, parents: state.parents, ...step.halt };
50
+ }
51
+ frontier = step.next;
52
+ }
53
+ return { order: state.order, parents: state.parents, foundGoal: false, truncated: false };
54
+ }
55
+ /** Expand one BFS level: record newly-seen neighbors, halting on goal/cap. */
56
+ function expandFrontier(frontier, adjacency, state, cap, goal) {
57
+ const next = [];
58
+ for (const node of frontier) {
59
+ for (const neighbor of adjacency.get(node) ?? []) {
60
+ if (state.visited.has(neighbor))
61
+ continue;
62
+ state.visited.add(neighbor);
63
+ state.parents.set(neighbor, node);
64
+ state.order.push(neighbor);
65
+ if (neighbor === goal)
66
+ return { next, halt: { foundGoal: true, truncated: false } };
67
+ if (state.order.length >= cap)
68
+ return { next, halt: { foundGoal: false, truncated: true } };
69
+ next.push(neighbor);
70
+ }
71
+ }
72
+ return { next };
73
+ }
74
+ /**
75
+ * Rebuild the path `start → … → goal` from a {@link BoundedBfsResult.parents}
76
+ * map. Only meaningful when the walk reached `goal` (`foundGoal`).
77
+ */
78
+ export function reconstructPath(parents, start, goal) {
79
+ const path = [];
80
+ let cursor = goal;
81
+ while (cursor !== undefined) {
82
+ path.unshift(cursor);
83
+ if (cursor === start)
84
+ break;
85
+ cursor = parents.get(cursor);
86
+ }
87
+ return path;
88
+ }
89
+ //# sourceMappingURL=graph-walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-walk.js","sourceRoot":"","sources":["../../src/tools/graph-walk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `list_runs` — lean stored-run pointers (ADR-0084, Task 4.5).
3
+ *
4
+ * Reads `resultsPort.listRuns()` ONLY — replay of persisted sessions, never a
5
+ * re-run. Returns a menu of `RunSummary` rows, each with the `opensip sessions
6
+ * show …` command + MCP follow-up via `show_run` / `get_latest_findings`.
7
+ */
8
+ import type { McpToolDeps } from './types.js';
9
+ import type { McpStdioServer } from '../server.js';
10
+ export declare function registerListRuns(server: McpStdioServer, deps: McpToolDeps): void;
11
+ //# sourceMappingURL=list-runs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-runs.d.ts","sourceRoot":"","sources":["../../src/tools/list-runs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA6BhF"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * `list_runs` — lean stored-run pointers (ADR-0084, Task 4.5).
3
+ *
4
+ * Reads `resultsPort.listRuns()` ONLY — replay of persisted sessions, never a
5
+ * re-run. Returns a menu of `RunSummary` rows, each with the `opensip sessions
6
+ * show …` command + MCP follow-up via `show_run` / `get_latest_findings`.
7
+ */
8
+ import { z } from 'zod';
9
+ import { limit as limitSchema, toolId as toolIdSchema } from './schemas.js';
10
+ import { errorResult, jsonResult, unknownToolError } from './tool-result.js';
11
+ export function registerListRuns(server, deps) {
12
+ server.register('list_runs', {
13
+ title: 'List OpenSIP runs',
14
+ description: 'List recent stored OpenSIP runs (fit/graph/yagni/sim) as lean pointers — id, tool, ' +
15
+ 'timing, score/passed, and the replay command. Drill into one with show_run, or jump to ' +
16
+ 'a tool’s current findings with get_latest_findings. Replays persisted sessions; ' +
17
+ 'never re-runs a tool. Filter by `tool`, cap with `limit`.',
18
+ inputSchema: {
19
+ tool: toolIdSchema().optional(),
20
+ limit: limitSchema(),
21
+ summaryOnly: z.boolean().optional(),
22
+ },
23
+ }, ({ tool, limit, summaryOnly }) => {
24
+ if (tool !== undefined && !deps.validToolIds.has(tool)) {
25
+ return unknownToolError(tool, deps.validToolIds);
26
+ }
27
+ const outcome = deps.results.listRuns({
28
+ ...(tool === undefined ? {} : { tool }),
29
+ ...(limit === undefined ? {} : { limit }),
30
+ ...(summaryOnly === undefined ? {} : { summaryOnly }),
31
+ });
32
+ if (!outcome.ok)
33
+ return errorResult(outcome.error);
34
+ return jsonResult({ runs: outcome.value });
35
+ });
36
+ }
37
+ //# sourceMappingURL=list-runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-runs.js","sourceRoot":"","sources":["../../src/tools/list-runs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAK7E,MAAM,UAAU,gBAAgB,CAAC,MAAsB,EAAE,IAAiB;IACxE,MAAM,CAAC,QAAQ,CACb,WAAW,EACX;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,qFAAqF;YACrF,yFAAyF;YACzF,kFAAkF;YAClF,2DAA2D;QAC7D,WAAW,EAAE;YACX,IAAI,EAAE,YAAY,EAAE,CAAC,QAAQ,EAAE;YAC/B,KAAK,EAAE,WAAW,EAAE;YACpB,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;SACpC;KACF,EACD,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE;QAC/B,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACpC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;YACvC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YACzC,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;SACtD,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `refresh_graph` — the single state-changing op (ADR-0084, Task 4.4).
3
+ *
4
+ * Rebuilds the call-graph catalog through the graph engine's programmatic build
5
+ * (`runGraph`, wired by the host into `graphPort.refresh()`), persists it to the
6
+ * shared datastore, and atomically swaps the in-memory generation. Concurrent
7
+ * calls are serialized to ONE rebuild inside the port. v1 uses the exact
8
+ * single-program build (no cloud egress, no live render).
9
+ *
10
+ * COST WARNING (also in the tool description): a rebuild parses the whole
11
+ * project — agents must NOT loop it per query. Call it once when the catalog is
12
+ * missing/stale (other tools report `freshness.fresh === false`), then read.
13
+ *
14
+ * Observability: emits `mcp.refresh.run[.ok|.error]` to the stderr logger and
15
+ * (fire-and-forget, no-op when telemetry is disabled) records rebuild latency on
16
+ * the `opensip-cli` meter with bounded labels `{ command, op, outcome }` — never
17
+ * a path/id/symbol.
18
+ */
19
+ import type { McpToolDeps } from './types.js';
20
+ import type { McpStdioServer } from '../server.js';
21
+ export declare function registerRefreshGraph(server: McpStdioServer, deps: McpToolDeps): void;
22
+ //# sourceMappingURL=refresh-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh-graph.d.ts","sourceRoot":"","sources":["../../src/tools/refresh-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAenD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA6CpF"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * `refresh_graph` — the single state-changing op (ADR-0084, Task 4.4).
3
+ *
4
+ * Rebuilds the call-graph catalog through the graph engine's programmatic build
5
+ * (`runGraph`, wired by the host into `graphPort.refresh()`), persists it to the
6
+ * shared datastore, and atomically swaps the in-memory generation. Concurrent
7
+ * calls are serialized to ONE rebuild inside the port. v1 uses the exact
8
+ * single-program build (no cloud egress, no live render).
9
+ *
10
+ * COST WARNING (also in the tool description): a rebuild parses the whole
11
+ * project — agents must NOT loop it per query. Call it once when the catalog is
12
+ * missing/stale (other tools report `freshness.fresh === false`), then read.
13
+ *
14
+ * Observability: emits `mcp.refresh.run[.ok|.error]` to the stderr logger and
15
+ * (fire-and-forget, no-op when telemetry is disabled) records rebuild latency on
16
+ * the `opensip-cli` meter with bounded labels `{ command, op, outcome }` — never
17
+ * a path/id/symbol.
18
+ */
19
+ import { getMeter, logger } from '@opensip-cli/core';
20
+ import { errorResult, jsonResult } from './tool-result.js';
21
+ const LOG_MODULE = 'mcp:refresh';
22
+ /** Record rebuild latency on the shared meter (no-op until an OTel SDK is registered). */
23
+ function recordRefreshLatency(durationMs, outcome) {
24
+ try {
25
+ getMeter('opensip-cli')
26
+ .createHistogram('opensip_cli.mcp.refresh.duration_ms')
27
+ .record(durationMs, { command: 'mcp', op: 'refresh', outcome });
28
+ }
29
+ catch {
30
+ // Telemetry is best-effort; a meter failure must never fail a refresh.
31
+ }
32
+ }
33
+ export function registerRefreshGraph(server, deps) {
34
+ server.register('refresh_graph', {
35
+ title: 'Rebuild the call graph',
36
+ description: 'Rebuild the OpenSIP call-graph catalog from the current working tree (the only ' +
37
+ 'state-changing tool). EXPENSIVE — it parses the whole project; do NOT loop it per ' +
38
+ 'query. Call it once when other tools report a stale or missing catalog ' +
39
+ '(freshness.fresh === false), then read. Returns { builtAt, durationMs, freshness }.',
40
+ }, async () => {
41
+ const startedAt = Date.now();
42
+ try {
43
+ const outcome = await deps.graph.refresh();
44
+ const durationMs = Date.now() - startedAt;
45
+ if (!outcome.ok) {
46
+ logger.error({
47
+ evt: 'mcp.refresh.run.error',
48
+ module: LOG_MODULE,
49
+ code: outcome.error.code,
50
+ durationMs,
51
+ });
52
+ recordRefreshLatency(durationMs, 'error');
53
+ return errorResult(outcome.error);
54
+ }
55
+ const freshness = deps.graph.freshness();
56
+ logger.info({ evt: 'mcp.refresh.run.ok', module: LOG_MODULE, durationMs });
57
+ recordRefreshLatency(durationMs, 'ok');
58
+ return jsonResult({ builtAt: outcome.value.data.builtAt, durationMs, freshness });
59
+ }
60
+ catch (error) {
61
+ const durationMs = Date.now() - startedAt;
62
+ logger.error({
63
+ evt: 'mcp.refresh.run.error',
64
+ module: LOG_MODULE,
65
+ error: error instanceof Error ? error.message : String(error),
66
+ durationMs,
67
+ });
68
+ recordRefreshLatency(durationMs, 'error');
69
+ // A genuine build failure is an infra boundary: re-throw so the SDK emits
70
+ // a JSON-RPC error frame (the server's dispatch logs the decision point).
71
+ throw error;
72
+ }
73
+ });
74
+ }
75
+ //# sourceMappingURL=refresh-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh-graph.js","sourceRoot":"","sources":["../../src/tools/refresh-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAK3D,MAAM,UAAU,GAAG,aAAa,CAAC;AAEjC,0FAA0F;AAC1F,SAAS,oBAAoB,CAAC,UAAkB,EAAE,OAAuB;IACvE,IAAI,CAAC;QACH,QAAQ,CAAC,aAAa,CAAC;aACpB,eAAe,CAAC,qCAAqC,CAAC;aACtD,MAAM,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAsB,EAAE,IAAiB;IAC5E,MAAM,CAAC,QAAQ,CACb,eAAe,EACf;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,iFAAiF;YACjF,oFAAoF;YACpF,yEAAyE;YACzE,qFAAqF;KACxF,EACD,KAAK,IAAI,EAAE;QACT,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC1C,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;gBAChB,MAAM,CAAC,KAAK,CAAC;oBACX,GAAG,EAAE,uBAAuB;oBAC5B,MAAM,EAAE,UAAU;oBAClB,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;oBACxB,UAAU;iBACX,CAAC,CAAC;gBACH,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAC1C,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;YAC3E,oBAAoB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YACvC,OAAO,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QACpF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC1C,MAAM,CAAC,KAAK,CAAC;gBACX,GAAG,EAAE,uBAAuB;gBAC5B,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC7D,UAAU;aACX,CAAC,CAAC;YACH,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAC1C,0EAA0E;YAC1E,0EAA0E;YAC1E,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Mount the MCP tool catalog onto the server (ADR-0084, Phase 4).
3
+ *
4
+ * One place that wires every graph + result tool through the server's
5
+ * scope-wrapping {@link McpStdioServer.register} seam. The host calls this once
6
+ * (in `command.ts`) after building the ports; each tool reads ONLY its injected
7
+ * port (never `currentScope()`, never a run-command entry point).
8
+ */
9
+ import type { McpToolDeps } from './types.js';
10
+ import type { McpStdioServer } from '../server.js';
11
+ /** Register all 13 MCP tools (9 graph + 4 result) on `server`. */
12
+ export declare function registerMcpTools(server: McpStdioServer, deps: McpToolDeps): void;
13
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAiBhF"}