milens 0.7.0 → 0.7.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.
Files changed (182) hide show
  1. package/.agents/skills/adapters/SKILL.md +54 -51
  2. package/.agents/skills/analyzer/SKILL.md +16 -19
  3. package/.agents/skills/apps/SKILL.md +60 -68
  4. package/.agents/skills/docs/SKILL.md +5 -25
  5. package/.agents/skills/milens/SKILL.md +6 -6
  6. package/.agents/skills/orchestrator/SKILL.md +8 -10
  7. package/.agents/skills/parser/SKILL.md +9 -11
  8. package/.agents/skills/root/SKILL.md +25 -29
  9. package/.agents/skills/scripts/SKILL.md +13 -16
  10. package/.agents/skills/security/SKILL.md +4 -9
  11. package/.agents/skills/server/SKILL.md +28 -25
  12. package/.agents/skills/store/SKILL.md +17 -21
  13. package/.agents/skills/test/SKILL.md +14 -19
  14. package/.agents/skills/ui/SKILL.md +1 -1
  15. package/README.md +12 -3
  16. package/adapters/README.md +144 -107
  17. package/adapters/claude-code/.claude/settings.json.hooks-snippet.json +26 -0
  18. package/adapters/claude-code/.claude-plugin/plugin.json +11 -0
  19. package/adapters/claude-code/.mcp.json +9 -0
  20. package/adapters/codex/.codex/config.toml +3 -0
  21. package/adapters/copilot/.vscode/mcp.json +10 -0
  22. package/adapters/cursor/.cursor/mcp.json +9 -0
  23. package/adapters/cursor/.cursorrules +69 -9
  24. package/adapters/gemini/.gemini/settings.json +9 -0
  25. package/dist/agents-md.d.ts +0 -1
  26. package/dist/agents-md.js +2 -2
  27. package/dist/agents-md.js.map +1 -1
  28. package/dist/analyzer/config.d.ts +0 -1
  29. package/dist/analyzer/engine.d.ts +0 -1
  30. package/dist/analyzer/engine.js +42 -40
  31. package/dist/analyzer/engine.js.map +1 -1
  32. package/dist/analyzer/enrich.d.ts +0 -1
  33. package/dist/analyzer/enrich.js +13 -0
  34. package/dist/analyzer/enrich.js.map +1 -1
  35. package/dist/analyzer/resolver.d.ts +0 -1
  36. package/dist/analyzer/resolver.js +48 -4
  37. package/dist/analyzer/resolver.js.map +1 -1
  38. package/dist/analyzer/review.d.ts +2 -2
  39. package/dist/analyzer/review.js +7 -59
  40. package/dist/analyzer/review.js.map +1 -1
  41. package/dist/analyzer/risk.d.ts +20 -0
  42. package/dist/analyzer/risk.js +76 -0
  43. package/dist/analyzer/risk.js.map +1 -0
  44. package/dist/analyzer/scanner.d.ts +0 -1
  45. package/dist/analyzer/scanner.js +2 -4
  46. package/dist/analyzer/scanner.js.map +1 -1
  47. package/dist/analyzer/scope-resolver.d.ts +0 -1
  48. package/dist/analyzer/scope-resolver.js +1 -1
  49. package/dist/analyzer/scope-resolver.js.map +1 -1
  50. package/dist/build-info.d.ts +2 -0
  51. package/dist/build-info.js +4 -0
  52. package/dist/build-info.js.map +1 -0
  53. package/dist/cli.d.ts +0 -1
  54. package/dist/cli.js +142 -16
  55. package/dist/cli.js.map +1 -1
  56. package/dist/metrics.d.ts +0 -1
  57. package/dist/orchestrator/orchestrator.d.ts +0 -1
  58. package/dist/orchestrator/orchestrator.js +16 -1
  59. package/dist/orchestrator/orchestrator.js.map +1 -1
  60. package/dist/orchestrator/reporter.d.ts +0 -1
  61. package/dist/parser/extract.d.ts +0 -1
  62. package/dist/parser/extract.js +53 -28
  63. package/dist/parser/extract.js.map +1 -1
  64. package/dist/parser/lang-css.d.ts +0 -1
  65. package/dist/parser/lang-go.d.ts +0 -1
  66. package/dist/parser/lang-html.d.ts +0 -1
  67. package/dist/parser/lang-java.d.ts +0 -1
  68. package/dist/parser/lang-js.d.ts +0 -1
  69. package/dist/parser/lang-md.d.ts +0 -1
  70. package/dist/parser/lang-php.d.ts +0 -1
  71. package/dist/parser/lang-py.d.ts +0 -1
  72. package/dist/parser/lang-ruby.d.ts +0 -1
  73. package/dist/parser/lang-rust.d.ts +0 -1
  74. package/dist/parser/lang-ts.d.ts +0 -1
  75. package/dist/parser/lang-vue.d.ts +0 -1
  76. package/dist/parser/language-provider.d.ts +0 -1
  77. package/dist/parser/languages.d.ts +0 -1
  78. package/dist/parser/loader.d.ts +0 -1
  79. package/dist/security/deps.d.ts +0 -1
  80. package/dist/security/rules.d.ts +0 -1
  81. package/dist/security/rules.js +13 -12
  82. package/dist/security/rules.js.map +1 -1
  83. package/dist/server/hooks.d.ts +0 -1
  84. package/dist/server/mcp-prompts.d.ts +0 -1
  85. package/dist/server/mcp-prompts.js +509 -523
  86. package/dist/server/mcp-prompts.js.map +1 -1
  87. package/dist/server/mcp.d.ts +0 -1
  88. package/dist/server/mcp.js +156 -655
  89. package/dist/server/mcp.js.map +1 -1
  90. package/dist/server/test-plan.d.ts +0 -1
  91. package/dist/server/tools/deps.d.ts +28 -0
  92. package/dist/server/tools/deps.js +2 -0
  93. package/dist/server/tools/deps.js.map +1 -0
  94. package/dist/server/tools/resources.d.ts +3 -0
  95. package/dist/server/tools/resources.js +103 -0
  96. package/dist/server/tools/resources.js.map +1 -0
  97. package/dist/server/tools/security.d.ts +3 -0
  98. package/dist/server/tools/security.js +176 -0
  99. package/dist/server/tools/security.js.map +1 -0
  100. package/dist/server/tools/session.d.ts +3 -0
  101. package/dist/server/tools/session.js +140 -0
  102. package/dist/server/tools/session.js.map +1 -0
  103. package/dist/server/tools/testing.d.ts +3 -0
  104. package/dist/server/tools/testing.js +200 -0
  105. package/dist/server/tools/testing.js.map +1 -0
  106. package/dist/server/watcher.d.ts +0 -1
  107. package/dist/server/watcher.js +1 -1
  108. package/dist/server/watcher.js.map +1 -1
  109. package/dist/skills.d.ts +0 -1
  110. package/dist/skills.js +8 -2
  111. package/dist/skills.js.map +1 -1
  112. package/dist/store/annotations.d.ts +1 -1
  113. package/dist/store/annotations.js +14 -3
  114. package/dist/store/annotations.js.map +1 -1
  115. package/dist/store/confidence.d.ts +0 -1
  116. package/dist/store/confidence.js +2 -0
  117. package/dist/store/confidence.js.map +1 -1
  118. package/dist/store/db.d.ts +9 -1
  119. package/dist/store/db.js +87 -20
  120. package/dist/store/db.js.map +1 -1
  121. package/dist/store/registry.d.ts +0 -1
  122. package/dist/store/vectors.d.ts +0 -1
  123. package/dist/types.d.ts +7 -1
  124. package/dist/ui/progress.d.ts +0 -1
  125. package/dist/uninstall.d.ts +0 -1
  126. package/dist/utils.d.ts +2 -1
  127. package/dist/utils.js +0 -0
  128. package/dist/utils.js.map +1 -1
  129. package/package.json +11 -8
  130. package/dist/agents-md.d.ts.map +0 -1
  131. package/dist/analyzer/config.d.ts.map +0 -1
  132. package/dist/analyzer/engine.d.ts.map +0 -1
  133. package/dist/analyzer/enrich.d.ts.map +0 -1
  134. package/dist/analyzer/resolver.d.ts.map +0 -1
  135. package/dist/analyzer/review.d.ts.map +0 -1
  136. package/dist/analyzer/scanner.d.ts.map +0 -1
  137. package/dist/analyzer/scope-resolver.d.ts.map +0 -1
  138. package/dist/analyzer/testplan.d.ts +0 -59
  139. package/dist/analyzer/testplan.d.ts.map +0 -1
  140. package/dist/analyzer/testplan.js +0 -218
  141. package/dist/analyzer/testplan.js.map +0 -1
  142. package/dist/cli.d.ts.map +0 -1
  143. package/dist/metrics.d.ts.map +0 -1
  144. package/dist/orchestrator/orchestrator.d.ts.map +0 -1
  145. package/dist/orchestrator/reporter.d.ts.map +0 -1
  146. package/dist/parser/extract.d.ts.map +0 -1
  147. package/dist/parser/lang-css.d.ts.map +0 -1
  148. package/dist/parser/lang-go.d.ts.map +0 -1
  149. package/dist/parser/lang-html.d.ts.map +0 -1
  150. package/dist/parser/lang-java.d.ts.map +0 -1
  151. package/dist/parser/lang-js.d.ts.map +0 -1
  152. package/dist/parser/lang-md.d.ts.map +0 -1
  153. package/dist/parser/lang-php.d.ts.map +0 -1
  154. package/dist/parser/lang-py.d.ts.map +0 -1
  155. package/dist/parser/lang-ruby.d.ts.map +0 -1
  156. package/dist/parser/lang-rust.d.ts.map +0 -1
  157. package/dist/parser/lang-ts.d.ts.map +0 -1
  158. package/dist/parser/lang-vue.d.ts.map +0 -1
  159. package/dist/parser/language-provider.d.ts.map +0 -1
  160. package/dist/parser/languages.d.ts.map +0 -1
  161. package/dist/parser/loader.d.ts.map +0 -1
  162. package/dist/security/deps.d.ts.map +0 -1
  163. package/dist/security/rules.d.ts.map +0 -1
  164. package/dist/server/hooks.d.ts.map +0 -1
  165. package/dist/server/mcp-prompts.d.ts.map +0 -1
  166. package/dist/server/mcp.d.ts.map +0 -1
  167. package/dist/server/test-plan.d.ts.map +0 -1
  168. package/dist/server/watcher.d.ts.map +0 -1
  169. package/dist/skills.d.ts.map +0 -1
  170. package/dist/store/annotations.d.ts.map +0 -1
  171. package/dist/store/confidence.d.ts.map +0 -1
  172. package/dist/store/db.d.ts.map +0 -1
  173. package/dist/store/registry.d.ts.map +0 -1
  174. package/dist/store/vectors.d.ts.map +0 -1
  175. package/dist/types.d.ts.map +0 -1
  176. package/dist/ui/progress.d.ts.map +0 -1
  177. package/dist/uninstall.d.ts.map +0 -1
  178. package/dist/utils.d.ts.map +0 -1
  179. package/docs/README.md +0 -25
  180. package/docs/diagram1.svg +0 -1
  181. package/docs/diagram2.svg +0 -1
  182. package/docs/diagram3.svg +0 -1
@@ -0,0 +1,103 @@
1
+ import { ResourceTemplate as Rt } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export function registerResources(server, deps) {
3
+ const { getDb, fmtSymbol } = deps;
4
+ server.resource('symbol', new Rt('milens://symbol/{name}', { list: undefined }), { description: 'Symbol context: definition, incoming refs, outgoing deps, role/heat metadata' }, async (uri, { name }) => {
5
+ const { db } = getDb();
6
+ const symbols = db.findSymbolByName(name);
7
+ if (symbols.length === 0) {
8
+ return { contents: [{ uri: uri.href, mimeType: 'text/plain', text: `"${name}" not found.` }] };
9
+ }
10
+ const lines = [];
11
+ for (const sym of symbols) {
12
+ lines.push(`${fmtSymbol(sym, 'L2')}${sym.exported ? ' (exported)' : ''}`);
13
+ const incoming = db.getIncomingLinks(sym.id).filter(l => l.type !== 'contains');
14
+ if (incoming.length > 0) {
15
+ lines.push(`incoming (${incoming.length}):`);
16
+ for (const l of incoming) {
17
+ const from = db.findSymbolById(l.fromId);
18
+ lines.push(` ${l.type}: ${from ? fmtSymbol(from) : l.fromId}`);
19
+ }
20
+ }
21
+ const outgoing = db.getOutgoingLinks(sym.id).filter(l => l.type !== 'contains');
22
+ if (outgoing.length > 0) {
23
+ lines.push(`outgoing (${outgoing.length}):`);
24
+ for (const l of outgoing) {
25
+ const to = db.findSymbolById(l.toId);
26
+ lines.push(` ${l.type}: ${to ? fmtSymbol(to) : l.toId}`);
27
+ }
28
+ }
29
+ lines.push('');
30
+ }
31
+ return { contents: [{ uri: uri.href, mimeType: 'text/plain', text: lines.join('\n') }] };
32
+ });
33
+ server.resource('file-symbols', new Rt('milens://file/{+path}', { list: undefined }), { description: 'All symbols in a file with ref/dep counts' }, async (uri, { path }) => {
34
+ const { db } = getDb();
35
+ const filePath = decodeURIComponent(path);
36
+ const symbols = db.getSymbolsByFile(filePath);
37
+ if (symbols.length === 0) {
38
+ return { contents: [{ uri: uri.href, mimeType: 'text/plain', text: `No symbols in "${filePath}".` }] };
39
+ }
40
+ const lines = [`${filePath}: ${symbols.length} symbols\n`];
41
+ for (const sym of symbols) {
42
+ const incoming = db.getIncomingLinks(sym.id).filter(l => l.type !== 'contains');
43
+ const outgoing = db.getOutgoingLinks(sym.id).filter(l => l.type !== 'contains');
44
+ const exp = sym.exported ? ' (exported)' : '';
45
+ lines.push(`${fmtSymbol(sym, 'L2')}${exp} ← ${incoming.length} refs, → ${outgoing.length} deps`);
46
+ }
47
+ return { contents: [{ uri: uri.href, mimeType: 'text/plain', text: lines.join('\n') }] };
48
+ });
49
+ server.resource('domain', new Rt('milens://domain/{name}', { list: undefined }), { description: 'Domain cluster details: files and top symbols in a domain' }, async (uri, { name }) => {
50
+ const { db } = getDb();
51
+ const domainName = name;
52
+ const allFiles = db.db_getFilesByZone(domainName);
53
+ if (allFiles.length === 0) {
54
+ return { contents: [{ uri: uri.href, mimeType: 'text/plain', text: `Domain "${domainName}" not found.` }] };
55
+ }
56
+ const lines = [`domain: ${domainName} (${allFiles.length} files)\n`];
57
+ let totalSymbols = 0;
58
+ for (const file of allFiles) {
59
+ const syms = db.getSymbolsByFile(file);
60
+ totalSymbols += syms.length;
61
+ const exported = syms.filter(s => s.exported);
62
+ lines.push(`${file}: ${syms.length} symbols (${exported.length} exported)`);
63
+ }
64
+ lines.push(`\ntotal: ${totalSymbols} symbols in ${allFiles.length} files`);
65
+ return { contents: [{ uri: uri.href, mimeType: 'text/plain', text: lines.join('\n') }] };
66
+ });
67
+ server.resource('overview', 'milens://overview', { description: 'Index overview: stats, domains, unresolved, test coverage, staleness' }, async (uri) => {
68
+ const { db, root, lazy } = getDb();
69
+ const stats = lazy.getCachedStats();
70
+ const unresolved = db.getUnresolvedStats();
71
+ const coverage = db.getTestCoverage();
72
+ const domains = lazy.getCachedDomainStats();
73
+ const staleFiles = db.getStaleFiles(24);
74
+ const lines = [
75
+ `repo: ${root}`,
76
+ `symbols: ${stats.symbols}`,
77
+ `links: ${stats.links}`,
78
+ `files: ${stats.files}`,
79
+ ];
80
+ if (unresolved.imports > 0 || unresolved.calls > 0) {
81
+ lines.push(`⚠ unresolved (internal): ${unresolved.imports} imports, ${unresolved.calls} calls`);
82
+ }
83
+ if (unresolved.externalImports > 0 || unresolved.externalCalls > 0) {
84
+ lines.push(`external (expected): ${unresolved.externalImports} imports, ${unresolved.externalCalls} calls`);
85
+ }
86
+ if (coverage.testFiles > 0) {
87
+ const pct = coverage.exportedProductionSymbols > 0
88
+ ? Math.round(coverage.testedSymbols / coverage.exportedProductionSymbols * 100) : 0;
89
+ lines.push(`test coverage: ${coverage.testedSymbols}/${coverage.exportedProductionSymbols} (${pct}%) from ${coverage.testFiles} test files`);
90
+ }
91
+ if (domains.length > 0) {
92
+ lines.push(`\ndomains (${domains.length}):`);
93
+ for (const d of domains) {
94
+ lines.push(` ${d.domain}: ${d.files} files, ${d.symbols} symbols`);
95
+ }
96
+ }
97
+ if (staleFiles.length > 0) {
98
+ lines.push(`\n⏳ ${staleFiles.length} stale files (>24h)`);
99
+ }
100
+ return { contents: [{ uri: uri.href, mimeType: 'text/plain', text: lines.join('\n') }] };
101
+ });
102
+ }
103
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../../src/server/tools/resources.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,IAAI,EAAE,EAAE,MAAM,yCAAyC,CAAC;AAEjF,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,IAAU;IAC7D,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAElC,MAAM,CAAC,QAAQ,CACb,QAAQ,EACR,IAAI,EAAE,CAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EACrD,EAAE,WAAW,EAAE,8EAA8E,EAAE,EAC/F,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtB,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAc,CAAC,CAAC;QACpD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,IAAI,cAAc,EAAE,CAAC,EAAE,CAAC;QACjG,CAAC;QACD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1E,MAAM,QAAQ,GAAG,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAChF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;gBAC7C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;oBACzB,MAAM,IAAI,GAAG,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;oBACzC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC;YACD,MAAM,QAAQ,GAAG,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAChF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;gBAC7C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;oBACzB,MAAM,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACrC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC5D,CAAC;YACH,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3F,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,QAAQ,CACb,cAAc,EACd,IAAI,EAAE,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EACpD,EAAE,WAAW,EAAE,2CAA2C,EAAE,EAC5D,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtB,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAc,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,kBAAkB,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;QACzG,CAAC;QACD,MAAM,KAAK,GAAa,CAAC,GAAG,QAAQ,KAAK,OAAO,CAAC,MAAM,YAAY,CAAC,CAAC;QACrE,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAChF,MAAM,QAAQ,GAAG,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAChF,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,YAAY,QAAQ,CAAC,MAAM,OAAO,CAAC,CAAC;QACnG,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3F,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,QAAQ,CACb,QAAQ,EACR,IAAI,EAAE,CAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EACrD,EAAE,WAAW,EAAE,2DAA2D,EAAE,EAC5E,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtB,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,IAAc,CAAC;QAClC,MAAM,QAAQ,GAAG,EAAE,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,UAAU,cAAc,EAAE,CAAC,EAAE,CAAC;QAC9G,CAAC;QACD,MAAM,KAAK,GAAa,CAAC,WAAW,UAAU,KAAK,QAAQ,CAAC,MAAM,WAAW,CAAC,CAAC;QAC/E,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC9C,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,MAAM,aAAa,QAAQ,CAAC,MAAM,YAAY,CAAC,CAAC;QAC9E,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,YAAY,YAAY,eAAe,QAAQ,CAAC,MAAM,QAAQ,CAAC,CAAC;QAC3E,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3F,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,QAAQ,CACb,UAAU,EACV,mBAAmB,EACnB,EAAE,WAAW,EAAE,sEAAsE,EAAE,EACvF,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,EAAE,CAAC,kBAAkB,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5C,MAAM,UAAU,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAExC,MAAM,KAAK,GAAa;YACtB,SAAS,IAAI,EAAE;YACf,YAAY,KAAK,CAAC,OAAO,EAAE;YAC3B,UAAU,KAAK,CAAC,KAAK,EAAE;YACvB,UAAU,KAAK,CAAC,KAAK,EAAE;SACxB,CAAC;QACF,IAAI,UAAU,CAAC,OAAO,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,4BAA4B,UAAU,CAAC,OAAO,aAAa,UAAU,CAAC,KAAK,QAAQ,CAAC,CAAC;QAClG,CAAC;QACD,IAAI,UAAU,CAAC,eAAe,GAAG,CAAC,IAAI,UAAU,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;YACnE,KAAK,CAAC,IAAI,CAAC,wBAAwB,UAAU,CAAC,eAAe,aAAa,UAAU,CAAC,aAAa,QAAQ,CAAC,CAAC;QAC9G,CAAC;QACD,IAAI,QAAQ,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,QAAQ,CAAC,yBAAyB,GAAG,CAAC;gBAChD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,GAAG,QAAQ,CAAC,yBAAyB,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtF,KAAK,CAAC,IAAI,CAAC,kBAAkB,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC,yBAAyB,KAAK,GAAG,WAAW,QAAQ,CAAC,SAAS,aAAa,CAAC,CAAC;QAC/I,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,cAAc,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;YAC7C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,OAAO,UAAU,CAAC,MAAM,qBAAqB,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3F,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { Deps } from './deps.js';
3
+ export declare function registerSecurityTools(server: McpServer, deps: Deps): void;
@@ -0,0 +1,176 @@
1
+ import { z } from 'zod';
2
+ import { resolve, relative, join, sep } from 'node:path';
3
+ import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
4
+ import { loadRules } from '../../security/rules.js';
5
+ import { globToRegex } from '../../utils.js';
6
+ /** Resolve `file` under `root` and reject any path that escapes it (path traversal / symlink). */
7
+ function resolveInsideRoot(root, file) {
8
+ const resolvedRoot = resolve(root);
9
+ const fullPath = resolve(resolvedRoot, file);
10
+ if (fullPath !== resolvedRoot && !fullPath.startsWith(resolvedRoot + sep))
11
+ return null;
12
+ return fullPath;
13
+ }
14
+ export function registerSecurityTools(server, deps) {
15
+ const { getDb } = deps;
16
+ server.tool('security_scan', 'Scan codebase for security vulnerabilities using 190+ built-in rules across 25 categories. Replaces multiple manual grep() calls. Categories: secrets, injection, rce, xss, deserialization, ssrf, xxe, path-traversal, file-upload, unicode, dangerous, config, data-leak, crypto, auth, jwt, cors-headers, dependency, cloud, docker, kubernetes, iac, business-logic, api-security, misc, file-access.', {
17
+ scope: z.enum(['all', 'secrets', 'injection', 'rce', 'xss', 'deserialization', 'ssrf', 'xxe', 'path-traversal', 'file-upload', 'unicode', 'dangerous', 'config', 'data-leak', 'crypto', 'auth', 'jwt', 'cors-headers', 'dependency', 'cloud', 'docker', 'kubernetes', 'iac', 'business-logic', 'api-security', 'misc', 'file-access']).optional().default('all').describe('Scan scope'),
18
+ repo: z.string().optional().describe('Repository root path'),
19
+ severity: z.enum(['CRITICAL', 'HIGH', 'MEDIUM', 'LOW']).optional().describe('Minimum severity filter'),
20
+ limit: z.number().optional().default(50).describe('Max findings'),
21
+ }, async ({ scope, repo, severity, limit }) => {
22
+ const { db, root } = getDb(repo);
23
+ const rules = loadRules();
24
+ // Filter rules by scope and severity
25
+ const filtered = rules.filter(r => {
26
+ if (scope !== 'all' && r.category !== scope)
27
+ return false;
28
+ if (severity) {
29
+ const sevOrder = { CRITICAL: 4, HIGH: 3, MEDIUM: 2, LOW: 1 };
30
+ if ((sevOrder[r.severity] || 0) < (sevOrder[severity] || 0))
31
+ return false;
32
+ }
33
+ return r.enabled;
34
+ });
35
+ // Get all source files from the DB
36
+ const symbols = db.getAllSymbols();
37
+ const fileSet = new Set();
38
+ for (const s of symbols) {
39
+ if (s.filePath && !s.filePath.includes('node_modules') && !s.filePath.includes('.git')) {
40
+ fileSet.add(s.filePath);
41
+ }
42
+ }
43
+ const files = [...fileSet].slice(0, 1000); // cap at 1000 files
44
+ const { readFileSync: rfs, existsSync: es } = await import('node:fs');
45
+ const { resolve: resolvePath } = await import('node:path');
46
+ const findings = [];
47
+ const byCategory = {};
48
+ const bySeverity = { CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0 };
49
+ for (const file of files) {
50
+ const fullPath = resolvePath(root, file);
51
+ if (!es(fullPath))
52
+ continue;
53
+ // Apply excludeGlob from each rule's exclusion pattern
54
+ let shouldExclude = false;
55
+ for (const rule of filtered) {
56
+ if (rule.excludeGlob) {
57
+ const excludePatterns = rule.excludeGlob.split(',');
58
+ for (const pattern of excludePatterns) {
59
+ const regex = globToRegex(pattern.trim());
60
+ if (regex.test(file) || regex.test('/' + file)) {
61
+ shouldExclude = true;
62
+ break;
63
+ }
64
+ }
65
+ }
66
+ if (shouldExclude)
67
+ break;
68
+ }
69
+ if (shouldExclude)
70
+ continue;
71
+ // Skip files that don't match rule fileGlobs (simple check)
72
+ const applicableRules = filtered.filter(r => {
73
+ if (!r.fileGlob)
74
+ return true;
75
+ // Simple glob: just check extension
76
+ const ext = r.fileGlob.replace('**/*.', '').replace('**/*', '');
77
+ return file.endsWith(ext) || r.fileGlob === '**/*';
78
+ });
79
+ if (applicableRules.length === 0)
80
+ continue;
81
+ try {
82
+ const content = rfs(fullPath, 'utf-8');
83
+ const lines = content.split('\n');
84
+ for (const rule of applicableRules) {
85
+ for (const pattern of rule.patterns) {
86
+ let match;
87
+ // Reset regex lastIndex for global patterns
88
+ pattern.lastIndex = 0;
89
+ while ((match = pattern.exec(content)) !== null) {
90
+ const lineNum = content.substring(0, match.index).split('\n').length;
91
+ const ctxStart = Math.max(0, lineNum - 3);
92
+ const ctxEnd = Math.min(lines.length, lineNum + 2);
93
+ const context = lines.slice(ctxStart, ctxEnd).join('\n');
94
+ findings.push({
95
+ ruleId: rule.id,
96
+ category: rule.category,
97
+ severity: rule.severity,
98
+ owasp: rule.owasp,
99
+ file,
100
+ line: lineNum,
101
+ match: match[0].length > 100 ? match[0].slice(0, 97) + '...' : match[0],
102
+ context,
103
+ fix: rule.fix,
104
+ });
105
+ byCategory[rule.category] = (byCategory[rule.category] || 0) + 1;
106
+ bySeverity[rule.severity] = (bySeverity[rule.severity] || 0) + 1;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ catch {
112
+ // Skip unreadable files
113
+ }
114
+ }
115
+ // Calculate security score (100 - deductions)
116
+ const deduction = findings.filter((f) => f.severity === 'CRITICAL').length * 5 +
117
+ findings.filter((f) => f.severity === 'HIGH').length * 2 +
118
+ findings.filter((f) => f.severity === 'MEDIUM').length * 0.5;
119
+ const score = Math.max(0, Math.round(100 - deduction));
120
+ const limited = findings.slice(0, limit);
121
+ return {
122
+ content: [{
123
+ type: 'text',
124
+ text: JSON.stringify({
125
+ summary: {
126
+ totalScanned: files.length,
127
+ findings: findings.length,
128
+ byCategory,
129
+ bySeverity,
130
+ score,
131
+ },
132
+ findings: limited,
133
+ }, null, 2),
134
+ }],
135
+ };
136
+ });
137
+ server.tool('fix_apply', 'Apply a security fix suggestion to a file. Creates a backup before modifying. CRITICAL rules require confirm: true.', {
138
+ ruleId: z.string().describe('Security rule ID (e.g. "hardcoded_secret")'),
139
+ file: z.string().describe('File path relative to repo root'),
140
+ line: z.number().describe('Line number where the issue was found'),
141
+ confirm: z.boolean().optional().default(false).describe('Confirmation required for CRITICAL rules'),
142
+ repo: z.string().optional(),
143
+ }, async ({ ruleId, file, line, confirm, repo }) => {
144
+ const { root } = getDb(repo);
145
+ const rules = loadRules();
146
+ const rule = rules.find(r => r.id === ruleId);
147
+ if (!rule)
148
+ return { content: [{ type: 'text', text: `Rule not found: "${ruleId}"` }] };
149
+ if (rule.severity === 'CRITICAL' && !confirm) {
150
+ return { content: [{ type: 'text', text: `CRITICAL rule "${ruleId}" requires confirmation. Set confirm: true to proceed.` }] };
151
+ }
152
+ const fullPath = resolveInsideRoot(root, file);
153
+ if (!fullPath)
154
+ return { content: [{ type: 'text', text: `Invalid file path: "${file}" resolves outside the repo root.` }] };
155
+ if (!existsSync(fullPath))
156
+ return { content: [{ type: 'text', text: `File not found: ${file}` }] };
157
+ const content = readFileSync(fullPath, 'utf-8');
158
+ const lines = content.split('\n');
159
+ if (line < 1 || line > lines.length)
160
+ return { content: [{ type: 'text', text: `Line ${line} out of range (file has ${lines.length} lines).` }] };
161
+ // Backup original
162
+ const backupDir = join(root, '.milens', 'backups');
163
+ mkdirSync(backupDir, { recursive: true });
164
+ const backupPath = join(backupDir, `${file.replace(/[\\/]/g, '_')}_${Date.now()}.bak`);
165
+ writeFileSync(backupPath, content, 'utf-8');
166
+ // Apply fix: add comment above the affected line with the fix suggestion
167
+ const targetLine = lines[line - 1];
168
+ const indent = targetLine.match(/^(\s*)/)?.[1] ?? '';
169
+ const fixComment = `${indent}// milens(fix): rule=${rule.id} — ${rule.fix ?? 'Review manually'}`;
170
+ lines.splice(line - 1, 0, fixComment);
171
+ const newContent = lines.join('\n');
172
+ writeFileSync(fullPath, newContent, 'utf-8');
173
+ return { content: [{ type: 'text', text: `Fix applied for rule "${ruleId}" at ${file}:${line}\nSeverity: ${rule.severity}\nBackup: ${relative(root, backupPath)}\nFix: ${rule.fix ?? 'Manual review needed'}\n\nAdded fix comment above line ${line}.` }] };
174
+ });
175
+ }
176
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../../src/server/tools/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { Deps } from './deps.js';
3
+ export declare function registerSessionTools(server: McpServer, deps: Deps): void;
@@ -0,0 +1,140 @@
1
+ import { z } from 'zod';
2
+ import { AnnotationStore } from '../../store/annotations.js';
3
+ import { HookManager, defaultOnSessionStart, defaultOnSessionEnd, defaultOnPreCommit, defaultOnFileChange, defaultOnPreCompact, defaultOnPostCompact, } from '../hooks.js';
4
+ import { BUILD_SHA, BUILT_AT } from '../../build-info.js';
5
+ export function registerSessionTools(server, deps) {
6
+ const { getDb, guard, getToolCallCount } = deps;
7
+ server.tool('annotate', 'Record a note about a symbol for future sessions. Use after discovering bugs, patterns, or important caveats.', {
8
+ symbol: z.string(),
9
+ key: z.enum(['note', 'bug', 'security', 'architecture', 'workflow', 'test', 'dependency', 'refactor']),
10
+ value: z.string(),
11
+ agent: z.string().optional(),
12
+ session_id: z.string().optional(),
13
+ confidence: z.number().optional().default(0.5),
14
+ }, async ({ symbol, key, value, agent, session_id, confidence }) => {
15
+ const { db } = getDb();
16
+ const store = new AnnotationStore(db.connection);
17
+ const ann = store.annotate(symbol, key, value, { agent, sessionId: session_id });
18
+ return { content: [{ type: 'text', text: `Annotation saved: ${ann.id}\n symbol: ${ann.symbol}\n key: ${ann.key}\n confidence: ${ann.confidence}` }] };
19
+ });
20
+ server.tool('recall', 'Retrieve annotations saved in previous sessions. Filter by symbol, key, or agent.', {
21
+ symbol: z.string().optional(), key: z.enum(['note', 'bug', 'security', 'architecture', 'workflow', 'test', 'dependency', 'refactor']).optional(),
22
+ agent: z.string().optional(), limit: z.number().optional().default(50),
23
+ }, async ({ symbol, key, agent, limit }) => {
24
+ const { db } = getDb();
25
+ const store = new AnnotationStore(db.connection);
26
+ const results = store.recall({ symbol, key, agent, limit });
27
+ if (results.length === 0)
28
+ return { content: [{ type: 'text', text: 'No annotations found.' }] };
29
+ const lines = [`${results.length} annotation(s):\n`];
30
+ for (const a of results) {
31
+ lines.push(`[${a.key}] ${a.symbol} — ${a.value.slice(0, 120)}`);
32
+ lines.push(` confidence: ${a.confidence.toFixed(1)} | agent: ${a.agent ?? '?'} | ${a.updatedAt}\n`);
33
+ }
34
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
35
+ });
36
+ server.tool('session_start', 'Start a new session. Returns a session ID to use with annotate, session_end, and handoff.', { agent: z.string().describe('Agent name (e.g. vibe-coder, reviewer)') }, async ({ agent }) => {
37
+ const { db, root, dbPath } = getDb();
38
+ const store = new AnnotationStore(db.connection);
39
+ const sessionId = store.sessionStart(agent);
40
+ let hookOutput = '';
41
+ try {
42
+ const manager = new HookManager();
43
+ const config = manager.loadConfig(root);
44
+ if (config.enabled && config.onSessionStart) {
45
+ hookOutput = await defaultOnSessionStart({ agent, sessionId, rootPath: root }, dbPath);
46
+ }
47
+ }
48
+ catch { /* hooks are best-effort */ }
49
+ const text = `Session started: ${sessionId}\nAgent: ${agent}\nBuild: ${BUILD_SHA} (${BUILT_AT})\nUse this ID with annotate() and session_end().`;
50
+ return { content: [{ type: 'text', text: hookOutput ? `${hookOutput}\n\n${text}` : text }] };
51
+ });
52
+ server.tool('session_context', 'Get metadata about a session: annotations, tool calls, duration.', { session_id: z.string() }, async ({ session_id }) => {
53
+ const { db, root } = getDb();
54
+ const store = new AnnotationStore(db.connection);
55
+ const ctx = store.sessionContext(session_id);
56
+ if (!ctx.session)
57
+ return { content: [{ type: 'text', text: `Session "${session_id}" not found.` }] };
58
+ const s = ctx.session;
59
+ const liveCalls = getToolCallCount(root);
60
+ const displayCalls = s.toolCallsCount > 0 ? s.toolCallsCount : liveCalls;
61
+ const lines = [
62
+ `Session: ${s.id}`,
63
+ `Agent: ${s.agent} | Status: ${s.status}`,
64
+ `Started: ${s.startedAt} | Ended: ${s.endedAt ?? 'in progress'}`,
65
+ `Tool calls: ${displayCalls}${s.toolCallsCount === 0 ? ' (live count, resets on restart)' : ''} | Annotations: ${s.annotationsCount}`,
66
+ ];
67
+ if (s.context)
68
+ lines.push(`Context: ${s.context}`);
69
+ if (ctx.annotations.length > 0) {
70
+ lines.push(`\nAnnotations (${ctx.annotations.length}):`);
71
+ for (const a of ctx.annotations) {
72
+ lines.push(` [${a.key}] ${a.symbol}: ${a.value.slice(0, 80)}`);
73
+ }
74
+ }
75
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
76
+ });
77
+ server.tool('session_end', 'End a session and record its stats. Shows audit trail: which symbols were safety-checked vs total edit operations. Use at the end of every session.', { session_id: z.string(), status: z.enum(['completed', 'failed']).optional().default('completed') }, async ({ session_id, status }) => {
78
+ const { db, root, dbPath } = getDb();
79
+ const store = new AnnotationStore(db.connection);
80
+ const summary = store.sessionEnd(session_id, status);
81
+ // Audit trail from SessionGuard
82
+ const audit = guard.getAudit(session_id);
83
+ guard.clear(session_id);
84
+ let hookOutput = '';
85
+ try {
86
+ const ctx = store.sessionContext(session_id);
87
+ const manager = new HookManager();
88
+ const config = manager.loadConfig(root);
89
+ if (config.enabled && config.onSessionEnd) {
90
+ hookOutput = await defaultOnSessionEnd({ agent: ctx.session.agent, sessionId: session_id, rootPath: root }, dbPath);
91
+ }
92
+ }
93
+ catch { /* hooks are best-effort */ }
94
+ const lines = [
95
+ `Session ended: ${session_id}`,
96
+ `Status: ${status}`,
97
+ `Annotations: ${summary.annotationCount}`,
98
+ `───`,
99
+ `Audit Trail:`,
100
+ ` safety checks performed: ${audit.checked.length}`,
101
+ audit.checked.length > 0 ? ` symbols checked: ${audit.checked.join(', ')}` : ' ⚠ no symbols were checked via guard_edit_check',
102
+ audit.editOps > 0 ? ` edit operations reported: ${audit.editOps}` : null,
103
+ ].filter(Boolean);
104
+ const text = lines.join('\n');
105
+ return { content: [{ type: 'text', text: hookOutput ? `${text}\n\n${hookOutput}` : text }] };
106
+ });
107
+ server.tool('handoff', 'Transfer context from one agent session to another. Ends the source session and creates a new one for the target agent.', {
108
+ from_session: z.string(), to_agent: z.string(),
109
+ context: z.string().describe('Summary of what was done, key decisions, and caveats for the next agent'),
110
+ }, async ({ from_session, to_agent, context }) => {
111
+ const { db } = getDb();
112
+ const store = new AnnotationStore(db.connection);
113
+ const result = store.handoff(from_session, to_agent, context);
114
+ return { content: [{ type: 'text', text: `Handoff complete.\nNew session: ${result.newSessionId}\nAgent: ${to_agent}\nAnnotations copied: ${result.annotationsCopied}` }] };
115
+ });
116
+ server.tool('pre_commit_check', 'Run pre-commit risk analysis: detect_changes + review_pr + dead code + coverage gaps. Use before committing.', { repo: z.string().optional().describe('Repository root path') }, async ({ repo }) => {
117
+ const { root } = getDb(repo);
118
+ const report = await defaultOnPreCommit(root);
119
+ return { content: [{ type: 'text', text: report }] };
120
+ });
121
+ server.tool('hook_onFileChange', 'Trigger the onFileChange hook. Call this when files are modified to get impact summary.', {
122
+ files: z.array(z.string()).describe('List of changed file paths'),
123
+ repo: z.string().optional(),
124
+ }, async ({ files, repo }) => {
125
+ const { root } = getDb(repo);
126
+ const report = await defaultOnFileChange(files, root);
127
+ return { content: [{ type: 'text', text: report }] };
128
+ });
129
+ server.tool('hook_preCompact', 'Trigger pre-compaction hook. Saves a metrics snapshot before context window compaction.', { repo: z.string().optional() }, async ({ repo }) => {
130
+ const { root, dbPath } = getDb(repo);
131
+ const report = await defaultOnPreCompact(root, dbPath);
132
+ return { content: [{ type: 'text', text: report }] };
133
+ });
134
+ server.tool('hook_postCompact', 'Trigger post-compaction hook. Recalls annotations to restore context after compaction.', { repo: z.string().optional() }, async ({ repo }) => {
135
+ const { root } = getDb(repo);
136
+ const report = await defaultOnPostCompact(root);
137
+ return { content: [{ type: 'text', text: report }] };
138
+ });
139
+ }
140
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/server/tools/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { Deps } from './deps.js';
3
+ export declare function registerTestingTools(server: McpServer, deps: Deps): void;