@shrkcrft/mcp-server 0.1.0-alpha.1 → 0.1.0-alpha.10

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 (93) hide show
  1. package/README.md +1 -1
  2. package/dist/main.d.ts +1 -1
  3. package/dist/main.js +1 -1
  4. package/dist/server/create-mcp-server.d.ts.map +1 -1
  5. package/dist/server/create-mcp-server.js +21 -15
  6. package/dist/server/http-transport.d.ts +2 -7
  7. package/dist/server/http-transport.d.ts.map +1 -1
  8. package/dist/server/http-transport.js +6 -10
  9. package/dist/tools/all-tools.d.ts.map +1 -1
  10. package/dist/tools/all-tools.js +49 -7
  11. package/dist/tools/diff-check.tool.d.ts +15 -0
  12. package/dist/tools/diff-check.tool.d.ts.map +1 -0
  13. package/dist/tools/diff-check.tool.js +157 -0
  14. package/dist/tools/file-advice.tool.d.ts +22 -0
  15. package/dist/tools/file-advice.tool.d.ts.map +1 -0
  16. package/dist/tools/file-advice.tool.js +88 -0
  17. package/dist/tools/get-api-surface-diff.tool.d.ts +3 -0
  18. package/dist/tools/get-api-surface-diff.tool.d.ts.map +1 -0
  19. package/dist/tools/get-api-surface-diff.tool.js +60 -0
  20. package/dist/tools/get-arch-violations.tool.d.ts +3 -0
  21. package/dist/tools/get-arch-violations.tool.d.ts.map +1 -0
  22. package/dist/tools/get-arch-violations.tool.js +30 -0
  23. package/dist/tools/get-code-intelligence-state.tool.d.ts +11 -0
  24. package/dist/tools/get-code-intelligence-state.tool.d.ts.map +1 -0
  25. package/dist/tools/get-code-intelligence-state.tool.js +59 -0
  26. package/dist/tools/get-context-pack.tool.d.ts +3 -0
  27. package/dist/tools/get-context-pack.tool.d.ts.map +1 -0
  28. package/dist/tools/get-context-pack.tool.js +40 -0
  29. package/dist/tools/get-framework-entities.tool.d.ts +3 -0
  30. package/dist/tools/get-framework-entities.tool.d.ts.map +1 -0
  31. package/dist/tools/get-framework-entities.tool.js +68 -0
  32. package/dist/tools/get-graph-callers.tool.d.ts +3 -0
  33. package/dist/tools/get-graph-callers.tool.d.ts.map +1 -0
  34. package/dist/tools/get-graph-callers.tool.js +80 -0
  35. package/dist/tools/get-graph-context.tool.d.ts +3 -0
  36. package/dist/tools/get-graph-context.tool.d.ts.map +1 -0
  37. package/dist/tools/get-graph-context.tool.js +91 -0
  38. package/dist/tools/get-graph-cycles.tool.d.ts +10 -0
  39. package/dist/tools/get-graph-cycles.tool.d.ts.map +1 -0
  40. package/dist/tools/get-graph-cycles.tool.js +57 -0
  41. package/dist/tools/get-graph-deps.tool.d.ts +12 -0
  42. package/dist/tools/get-graph-deps.tool.d.ts.map +1 -0
  43. package/dist/tools/get-graph-deps.tool.js +80 -0
  44. package/dist/tools/get-graph-impact-analysis.tool.d.ts +3 -0
  45. package/dist/tools/get-graph-impact-analysis.tool.d.ts.map +1 -0
  46. package/dist/tools/get-graph-impact-analysis.tool.js +42 -0
  47. package/dist/tools/get-graph-impact.tool.d.ts +3 -0
  48. package/dist/tools/get-graph-impact.tool.d.ts.map +1 -0
  49. package/dist/tools/get-graph-impact.tool.js +127 -0
  50. package/dist/tools/get-graph-search.tool.d.ts +3 -0
  51. package/dist/tools/get-graph-search.tool.d.ts.map +1 -0
  52. package/dist/tools/get-graph-search.tool.js +75 -0
  53. package/dist/tools/get-graph-status.tool.d.ts +9 -0
  54. package/dist/tools/get-graph-status.tool.d.ts.map +1 -0
  55. package/dist/tools/get-graph-status.tool.js +46 -0
  56. package/dist/tools/get-graph-unresolved.tool.d.ts +11 -0
  57. package/dist/tools/get-graph-unresolved.tool.d.ts.map +1 -0
  58. package/dist/tools/get-graph-unresolved.tool.js +81 -0
  59. package/dist/tools/get-impact-baseline.tool.d.ts +9 -0
  60. package/dist/tools/get-impact-baseline.tool.d.ts.map +1 -0
  61. package/dist/tools/get-impact-baseline.tool.js +65 -0
  62. package/dist/tools/get-intent-benchmark-run.tool.d.ts +12 -0
  63. package/dist/tools/get-intent-benchmark-run.tool.d.ts.map +1 -0
  64. package/dist/tools/get-intent-benchmark-run.tool.js +55 -0
  65. package/dist/tools/get-migrations.tool.d.ts +3 -0
  66. package/dist/tools/get-migrations.tool.d.ts.map +1 -0
  67. package/dist/tools/get-migrations.tool.js +70 -0
  68. package/dist/tools/get-pattern-registry.tool.d.ts +8 -0
  69. package/dist/tools/get-pattern-registry.tool.d.ts.map +1 -0
  70. package/dist/tools/get-pattern-registry.tool.js +40 -0
  71. package/dist/tools/get-quality-gate.tool.d.ts +3 -0
  72. package/dist/tools/get-quality-gate.tool.d.ts.map +1 -0
  73. package/dist/tools/get-quality-gate.tool.js +27 -0
  74. package/dist/tools/get-rules-for-file.tool.d.ts +3 -0
  75. package/dist/tools/get-rules-for-file.tool.d.ts.map +1 -0
  76. package/dist/tools/get-rules-for-file.tool.js +54 -0
  77. package/dist/tools/get-structural-rewrite-plan.tool.d.ts +3 -0
  78. package/dist/tools/get-structural-rewrite-plan.tool.d.ts.map +1 -0
  79. package/dist/tools/get-structural-rewrite-plan.tool.js +46 -0
  80. package/dist/tools/get-structural-search.tool.d.ts +3 -0
  81. package/dist/tools/get-structural-search.tool.d.ts.map +1 -0
  82. package/dist/tools/get-structural-search.tool.js +35 -0
  83. package/dist/tools/primary-tools.d.ts +24 -0
  84. package/dist/tools/primary-tools.d.ts.map +1 -0
  85. package/dist/tools/primary-tools.js +70 -0
  86. package/dist/tools/r19-extras.tool.js +1 -1
  87. package/dist/tools/r32-profiles.tool.d.ts +0 -3
  88. package/dist/tools/r32-profiles.tool.d.ts.map +1 -1
  89. package/dist/tools/r32-profiles.tool.js +3 -54
  90. package/package.json +31 -20
  91. package/dist/tools/r28-plugin-lifecycle.tool.d.ts +0 -4
  92. package/dist/tools/r28-plugin-lifecycle.tool.d.ts.map +0 -1
  93. package/dist/tools/r28-plugin-lifecycle.tool.js +0 -94
@@ -0,0 +1,127 @@
1
+ import { GraphQueryApi, GraphStore } from '@shrkcrft/graph';
2
+ const NEXT = 'shrk graph index';
3
+ export const getGraphImpactTool = {
4
+ name: 'get_graph_impact',
5
+ description: 'Compute reverse closure (importers + transitive) for a file or symbol. Returns direct and transitive dependents capped by limit. Read-only.',
6
+ cliCommand: 'graph impact',
7
+ inputSchema: {
8
+ type: 'object',
9
+ properties: {
10
+ target: { type: 'string' },
11
+ maxDepth: { type: 'number' },
12
+ limit: { type: 'number' },
13
+ },
14
+ required: ['target'],
15
+ additionalProperties: false,
16
+ },
17
+ handler(input, ctx) {
18
+ const args = input;
19
+ const target = (args.target ?? '').trim();
20
+ if (!target) {
21
+ return {
22
+ isError: true,
23
+ error: { code: 'invalid-input', message: 'target is required' },
24
+ };
25
+ }
26
+ const maxDepth = clamp(args.maxDepth ?? 5, 1, 10);
27
+ const limit = clamp(args.limit ?? 200, 1, 2000);
28
+ const store = new GraphStore(ctx.inspection.projectRoot);
29
+ if (!store.exists()) {
30
+ return {
31
+ isError: true,
32
+ error: {
33
+ code: 'graph-missing',
34
+ message: `Code-intelligence index is missing. Run '${NEXT}'.`,
35
+ details: { nextCommand: NEXT },
36
+ },
37
+ };
38
+ }
39
+ const api = GraphQueryApi.fromStore(ctx.inspection.projectRoot);
40
+ const anchor = resolveAnchor(api, target);
41
+ if (!anchor) {
42
+ return {
43
+ isError: true,
44
+ error: {
45
+ code: 'not-found',
46
+ message: `No graph node matched "${target}".`,
47
+ details: { target },
48
+ },
49
+ };
50
+ }
51
+ const closure = reverseClosure(api, anchor.id, maxDepth, limit);
52
+ const direct = closure.layer[1] ?? [];
53
+ const transitive = closure.all.filter((id) => id !== anchor.id && !direct.includes(id));
54
+ return {
55
+ data: {
56
+ schema: 'sharkcraft.graph-impact/v1',
57
+ anchor: summarise(anchor),
58
+ maxDepth,
59
+ limit,
60
+ truncated: closure.truncated,
61
+ directDependents: direct.map((id) => summarise(api.neighbours(id).node)),
62
+ transitiveDependents: transitive
63
+ .slice(0, limit)
64
+ .map((id) => summarise(api.neighbours(id).node)),
65
+ totalReached: closure.all.length - 1,
66
+ },
67
+ };
68
+ },
69
+ };
70
+ function resolveAnchor(api, target) {
71
+ const direct = api.neighbours(target);
72
+ if (direct)
73
+ return direct.node;
74
+ if (target.startsWith('file:') || target.startsWith('symbol:') || target.startsWith('package:')) {
75
+ return undefined;
76
+ }
77
+ const f = api.findFile(target);
78
+ if (f)
79
+ return f;
80
+ const syms = api.findSymbol(target, { exact: true, limit: 1 });
81
+ if (syms.length > 0)
82
+ return syms[0];
83
+ return undefined;
84
+ }
85
+ function reverseClosure(api, startId, maxDepth, limit) {
86
+ const seen = new Set([startId]);
87
+ const layer = {};
88
+ let frontier = [startId];
89
+ let depth = 1;
90
+ let truncated = false;
91
+ while (depth <= maxDepth && frontier.length > 0) {
92
+ const next = [];
93
+ for (const id of frontier) {
94
+ for (const imp of api.importersOf(id)) {
95
+ if (seen.has(imp.id))
96
+ continue;
97
+ seen.add(imp.id);
98
+ next.push(imp.id);
99
+ if (seen.size - 1 >= limit) {
100
+ truncated = true;
101
+ break;
102
+ }
103
+ }
104
+ if (truncated)
105
+ break;
106
+ }
107
+ if (next.length > 0)
108
+ layer[depth] = next;
109
+ frontier = next;
110
+ depth += 1;
111
+ if (truncated)
112
+ break;
113
+ }
114
+ return { all: [...seen], layer, truncated };
115
+ }
116
+ function summarise(n) {
117
+ return {
118
+ id: n.id,
119
+ kind: n.kind,
120
+ label: n.label,
121
+ ...(n.path ? { path: n.path } : {}),
122
+ ...(n.line ? { line: n.line } : {}),
123
+ };
124
+ }
125
+ function clamp(n, lo, hi) {
126
+ return Math.max(lo, Math.min(hi, n));
127
+ }
@@ -0,0 +1,3 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ export declare const getGraphSearchTool: IToolDefinition;
3
+ //# sourceMappingURL=get-graph-search.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-graph-search.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-graph-search.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAWpE,eAAO,MAAM,kBAAkB,EAAE,eA6DhC,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { GraphQueryApi, GraphStore } from '@shrkcrft/graph';
2
+ const NEXT = 'shrk graph index';
3
+ export const getGraphSearchTool = {
4
+ name: 'get_graph_search',
5
+ description: 'Search the code graph by file path, symbol name, or package name. Returns ranked node summaries. Read-only.',
6
+ cliCommand: 'graph search',
7
+ inputSchema: {
8
+ type: 'object',
9
+ properties: {
10
+ query: { type: 'string' },
11
+ kind: { type: 'string', enum: ['file', 'symbol', 'package'] },
12
+ limit: { type: 'number' },
13
+ exact: { type: 'boolean' },
14
+ },
15
+ required: ['query'],
16
+ additionalProperties: false,
17
+ },
18
+ handler(input, ctx) {
19
+ const args = input;
20
+ const query = (args.query ?? '').trim();
21
+ if (!query) {
22
+ return {
23
+ isError: true,
24
+ error: { code: 'invalid-input', message: 'query is required' },
25
+ };
26
+ }
27
+ const limit = Math.max(1, Math.min(200, args.limit ?? 20));
28
+ const store = new GraphStore(ctx.inspection.projectRoot);
29
+ if (!store.exists()) {
30
+ return {
31
+ isError: true,
32
+ error: {
33
+ code: 'graph-missing',
34
+ message: `Code-intelligence index is missing. Run '${NEXT}'.`,
35
+ details: { nextCommand: NEXT },
36
+ },
37
+ };
38
+ }
39
+ const api = GraphQueryApi.fromStore(ctx.inspection.projectRoot);
40
+ const matches = [];
41
+ if (!args.kind || args.kind === 'file') {
42
+ const f = api.findFile(query);
43
+ if (f)
44
+ matches.push(f);
45
+ }
46
+ if (!args.kind || args.kind === 'symbol') {
47
+ const exact = args.exact ?? false;
48
+ for (const s of api.findSymbol(query, { exact, limit }))
49
+ matches.push(s);
50
+ }
51
+ if (!args.kind || args.kind === 'package') {
52
+ const p = api.neighbours(`package:${query}`);
53
+ if (p)
54
+ matches.push(p.node);
55
+ }
56
+ return {
57
+ data: {
58
+ schema: 'sharkcraft.graph-search/v1',
59
+ query,
60
+ kind: args.kind ?? 'any',
61
+ total: Math.min(matches.length, limit),
62
+ matches: matches.slice(0, limit).map(summarise),
63
+ },
64
+ };
65
+ },
66
+ };
67
+ function summarise(n) {
68
+ return {
69
+ id: n.id,
70
+ kind: n.kind,
71
+ label: n.label,
72
+ ...(n.path ? { path: n.path } : {}),
73
+ ...(n.line ? { line: n.line } : {}),
74
+ };
75
+ }
@@ -0,0 +1,9 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ /**
3
+ * Read-only status for the on-disk code graph. Returns
4
+ * { state: 'fresh' | 'corrupt' | 'missing' } and counters.
5
+ * On 'missing', `isError` + `error.details.nextCommand` direct the
6
+ * caller (CLI or human) to refresh.
7
+ */
8
+ export declare const getGraphStatusTool: IToolDefinition;
9
+ //# sourceMappingURL=get-graph-status.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-graph-status.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-graph-status.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAKpE;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAqChC,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { GraphStore } from '@shrkcrft/graph';
2
+ const NEXT = 'shrk graph index';
3
+ const STALE_HINT = `Code-intelligence index is missing or stale. Run '${NEXT}' to build it.`;
4
+ /**
5
+ * Read-only status for the on-disk code graph. Returns
6
+ * { state: 'fresh' | 'corrupt' | 'missing' } and counters.
7
+ * On 'missing', `isError` + `error.details.nextCommand` direct the
8
+ * caller (CLI or human) to refresh.
9
+ */
10
+ export const getGraphStatusTool = {
11
+ name: 'get_graph_status',
12
+ description: 'Read-only status of the SharkCraft code-intelligence graph: file/node/edge counts, schema, last indexed time, digest verification. Returns nextCommand when missing.',
13
+ cliCommand: 'graph status',
14
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
15
+ handler(_input, ctx) {
16
+ const store = new GraphStore(ctx.inspection.projectRoot);
17
+ if (!store.exists()) {
18
+ return {
19
+ isError: true,
20
+ error: {
21
+ code: 'graph-missing',
22
+ message: STALE_HINT,
23
+ details: { nextCommand: NEXT, state: 'missing' },
24
+ },
25
+ };
26
+ }
27
+ const verify = store.verifyDigest();
28
+ const snap = store.loadSnapshot();
29
+ return {
30
+ data: {
31
+ schema: snap.manifest.schema,
32
+ state: verify.ok ? 'fresh' : 'corrupt',
33
+ digestOk: verify.ok,
34
+ fileCount: snap.manifest.filesIndexed,
35
+ nodeCount: snap.nodes.size,
36
+ edgeCount: snap.edges.size,
37
+ nodesByKind: snap.manifest.nodesByKind,
38
+ edgesByKind: snap.manifest.edgesByKind,
39
+ workspacePackages: snap.manifest.workspacePackages,
40
+ lastIndexedAt: snap.manifest.lastIndexedAt,
41
+ lastIndexDurationMs: snap.manifest.lastIndexDurationMs,
42
+ ...(verify.ok ? {} : { expectedDigest: verify.expected, actualDigest: verify.actual }),
43
+ },
44
+ };
45
+ },
46
+ };
@@ -0,0 +1,11 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ /**
3
+ * Read-only MCP mirror of `shrk graph unresolved`. Returns every
4
+ * `unresolved:<spec>` ImportsFile edge grouped by source file.
5
+ * Sorted by unresolved-count desc so the worst offenders surface first.
6
+ *
7
+ * Same safety contract as the other graph tools: structured
8
+ * `graph-missing` error when the index isn't built yet.
9
+ */
10
+ export declare const getGraphUnresolvedTool: IToolDefinition;
11
+ //# sourceMappingURL=get-graph-unresolved.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-graph-unresolved.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-graph-unresolved.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AASpE;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAsEpC,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { EdgeKind, GraphStore } from '@shrkcrft/graph';
2
+ const NEXT = 'shrk graph index';
3
+ /**
4
+ * Read-only MCP mirror of `shrk graph unresolved`. Returns every
5
+ * `unresolved:<spec>` ImportsFile edge grouped by source file.
6
+ * Sorted by unresolved-count desc so the worst offenders surface first.
7
+ *
8
+ * Same safety contract as the other graph tools: structured
9
+ * `graph-missing` error when the index isn't built yet.
10
+ */
11
+ export const getGraphUnresolvedTool = {
12
+ name: 'get_graph_unresolved',
13
+ description: 'List every unresolved import in the code graph, grouped by source file. Sorted by unresolved-count desc. Read-only.',
14
+ cliCommand: 'graph unresolved',
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {
18
+ limit: { type: 'number' },
19
+ },
20
+ additionalProperties: false,
21
+ },
22
+ handler(input, ctx) {
23
+ const args = input;
24
+ const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) && args.limit > 0
25
+ ? args.limit
26
+ : 200;
27
+ const store = new GraphStore(ctx.inspection.projectRoot);
28
+ if (!store.exists()) {
29
+ return {
30
+ isError: true,
31
+ error: {
32
+ code: 'graph-missing',
33
+ message: `Code-intelligence index is missing. Run '${NEXT}'.`,
34
+ details: { nextCommand: NEXT },
35
+ },
36
+ };
37
+ }
38
+ const snap = store.loadSnapshot();
39
+ const groups = new Map();
40
+ for (const e of snap.edges.values()) {
41
+ if (e.kind !== EdgeKind.ImportsFile)
42
+ continue;
43
+ if (!e.to.startsWith('unresolved:'))
44
+ continue;
45
+ const fromNode = snap.nodes.get(e.from);
46
+ const spec = e.to.slice('unresolved:'.length);
47
+ const existing = groups.get(e.from);
48
+ if (existing) {
49
+ existing.specifiers.add(spec);
50
+ }
51
+ else {
52
+ groups.set(e.from, {
53
+ from: e.from,
54
+ ...(fromNode?.path ? { path: fromNode.path } : {}),
55
+ specifiers: new Set([spec]),
56
+ });
57
+ }
58
+ }
59
+ const list = [...groups.values()]
60
+ .map((g) => ({
61
+ path: g.path ?? g.from.replace(/^file:/, ''),
62
+ unresolved: [...g.specifiers].sort(),
63
+ }))
64
+ .sort((a, b) => {
65
+ if (b.unresolved.length !== a.unresolved.length) {
66
+ return b.unresolved.length - a.unresolved.length;
67
+ }
68
+ return a.path.localeCompare(b.path);
69
+ });
70
+ const totalEdges = list.reduce((n, g) => n + g.unresolved.length, 0);
71
+ return {
72
+ data: {
73
+ schema: 'sharkcraft.graph-unresolved/v1',
74
+ totalEdges,
75
+ totalFiles: list.length,
76
+ truncated: list.length > limit,
77
+ files: list.slice(0, limit),
78
+ },
79
+ };
80
+ },
81
+ };
@@ -0,0 +1,9 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ /**
3
+ * Read-only MCP mirror of `shrk impact baseline show`. Returns the
4
+ * frozen baseline + the most recent run + the delta between them.
5
+ * When either side is missing the response carries a structured hint
6
+ * pointing at the command that fills the gap.
7
+ */
8
+ export declare const getImpactBaselineTool: IToolDefinition;
9
+ //# sourceMappingURL=get-impact-baseline.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-impact-baseline.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-impact-baseline.tool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,eA0DnC,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { diffImpactReports, ImpactReportStore, } from '@shrkcrft/impact-engine';
2
+ /**
3
+ * Read-only MCP mirror of `shrk impact baseline show`. Returns the
4
+ * frozen baseline + the most recent run + the delta between them.
5
+ * When either side is missing the response carries a structured hint
6
+ * pointing at the command that fills the gap.
7
+ */
8
+ export const getImpactBaselineTool = {
9
+ name: 'get_impact_baseline',
10
+ description: 'Return the impact baseline + latest impact run + delta. Read-only mirror of `shrk impact baseline show`.',
11
+ cliCommand: 'impact baseline show',
12
+ inputSchema: {
13
+ type: 'object',
14
+ properties: {},
15
+ additionalProperties: false,
16
+ },
17
+ handler(_input, ctx) {
18
+ const store = new ImpactReportStore(ctx.inspection.projectRoot);
19
+ const baseline = store.readBaseline();
20
+ const last = store.read();
21
+ if (!baseline && !last) {
22
+ return {
23
+ data: {
24
+ schema: 'sharkcraft.impact-baseline/v1',
25
+ state: 'missing-both',
26
+ baseline: null,
27
+ last: null,
28
+ nextCommands: ['shrk impact --via-graph <target>', 'shrk impact baseline write'],
29
+ },
30
+ };
31
+ }
32
+ if (!baseline) {
33
+ return {
34
+ data: {
35
+ schema: 'sharkcraft.impact-baseline/v1',
36
+ state: 'missing-baseline',
37
+ baseline: null,
38
+ last,
39
+ nextCommands: ['shrk impact baseline write'],
40
+ },
41
+ };
42
+ }
43
+ if (!last) {
44
+ return {
45
+ data: {
46
+ schema: 'sharkcraft.impact-baseline/v1',
47
+ state: 'missing-last',
48
+ baseline,
49
+ last: null,
50
+ nextCommands: ['shrk impact --via-graph <target>'],
51
+ },
52
+ };
53
+ }
54
+ const delta = diffImpactReports(baseline, last);
55
+ return {
56
+ data: {
57
+ schema: 'sharkcraft.impact-baseline/v1',
58
+ state: 'present',
59
+ baseline,
60
+ last,
61
+ delta,
62
+ },
63
+ };
64
+ },
65
+ };
@@ -0,0 +1,12 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ /**
3
+ * Read-only MCP surface for the intent-classifier benchmark. Returns
4
+ * the latest persisted run + a hint about the source fixture so the
5
+ * agent can correlate misses against the labelled cases.
6
+ *
7
+ * When no run is on disk but a fixture is present, the tool reports
8
+ * `state: 'fixture-only'` and points at `shrk context benchmark` so
9
+ * the run can be created without an additional turn of guessing.
10
+ */
11
+ export declare const getIntentBenchmarkRunTool: IToolDefinition;
12
+ //# sourceMappingURL=get-intent-benchmark-run.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-intent-benchmark-run.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-intent-benchmark-run.tool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,EAAE,eA6CvC,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { loadIntentBenchmark, readBenchmarkRun, } from '@shrkcrft/context-planner';
2
+ /**
3
+ * Read-only MCP surface for the intent-classifier benchmark. Returns
4
+ * the latest persisted run + a hint about the source fixture so the
5
+ * agent can correlate misses against the labelled cases.
6
+ *
7
+ * When no run is on disk but a fixture is present, the tool reports
8
+ * `state: 'fixture-only'` and points at `shrk context benchmark` so
9
+ * the run can be created without an additional turn of guessing.
10
+ */
11
+ export const getIntentBenchmarkRunTool = {
12
+ name: 'get_intent_benchmark_run',
13
+ description: 'Return the most recent intent-classifier benchmark run. Read-only mirror of `shrk context benchmark`.',
14
+ cliCommand: 'context benchmark',
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {},
18
+ additionalProperties: false,
19
+ },
20
+ handler(_input, ctx) {
21
+ const root = ctx.inspection.projectRoot;
22
+ const fixture = loadIntentBenchmark(root);
23
+ const run = readBenchmarkRun(root);
24
+ if (!fixture && !run) {
25
+ return {
26
+ data: {
27
+ schema: 'sharkcraft.intent-benchmark/v1',
28
+ state: 'missing',
29
+ fixture: null,
30
+ run: null,
31
+ nextCommands: ['shrk context benchmark seed', 'shrk context benchmark'],
32
+ },
33
+ };
34
+ }
35
+ if (!run) {
36
+ return {
37
+ data: {
38
+ schema: 'sharkcraft.intent-benchmark/v1',
39
+ state: 'fixture-only',
40
+ fixtureCaseCount: fixture?.cases.length ?? 0,
41
+ run: null,
42
+ nextCommands: ['shrk context benchmark'],
43
+ },
44
+ };
45
+ }
46
+ return {
47
+ data: {
48
+ schema: 'sharkcraft.intent-benchmark/v1',
49
+ state: 'present',
50
+ fixtureCaseCount: fixture?.cases.length ?? run.total,
51
+ run,
52
+ },
53
+ };
54
+ },
55
+ };
@@ -0,0 +1,3 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ export declare const getMigrationsTool: IToolDefinition;
3
+ //# sourceMappingURL=get-migrations.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-migrations.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-migrations.tool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AA0BpE,eAAO,MAAM,iBAAiB,EAAE,eA+D/B,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import * as nodePath from 'node:path';
3
+ import { findResumePoint } from '@shrkcrft/migrate';
4
+ export const getMigrationsTool = {
5
+ name: 'get_migrations',
6
+ description: 'Read-only: list `@shrkcrft/migrate` run state from `.sharkcraft/migrations/*.state.json`. Mirrors the dashboard Migrations panel. Pass `id` to fetch a single run; otherwise returns every saved state newest-first.',
7
+ cliCommand: 'migrate',
8
+ inputSchema: {
9
+ type: 'object',
10
+ properties: {
11
+ id: { type: 'string' },
12
+ },
13
+ additionalProperties: false,
14
+ },
15
+ handler(input, ctx) {
16
+ const args = input;
17
+ const projectRoot = ctx.inspection.projectRoot;
18
+ const dir = nodePath.join(projectRoot, '.sharkcraft', 'migrations');
19
+ if (!existsSync(dir)) {
20
+ const payload = {
21
+ schema: 'sharkcraft.mcp-migrations/v1',
22
+ available: false,
23
+ total: 0,
24
+ migrations: [],
25
+ hint: 'no migrations have been run yet',
26
+ };
27
+ return { data: payload };
28
+ }
29
+ const rows = [];
30
+ let entries = [];
31
+ try {
32
+ entries = readdirSync(dir);
33
+ }
34
+ catch {
35
+ /* ignore */
36
+ }
37
+ for (const entry of entries) {
38
+ if (!entry.endsWith('.state.json'))
39
+ continue;
40
+ const abs = nodePath.join(dir, entry);
41
+ try {
42
+ const report = JSON.parse(readFileSync(abs, 'utf8'));
43
+ if (args.id && report.migration.id !== args.id)
44
+ continue;
45
+ const resumePoint = findResumePoint(report);
46
+ rows.push({
47
+ id: report.migration.id,
48
+ title: report.migration.title,
49
+ overall: report.overall,
50
+ dryRun: report.dryRun,
51
+ startedAt: report.startedAt,
52
+ totalDurationMs: report.totalDurationMs,
53
+ steps: report.steps,
54
+ ...(resumePoint !== undefined ? { resumePoint } : {}),
55
+ });
56
+ }
57
+ catch {
58
+ /* skip corrupt state */
59
+ }
60
+ }
61
+ rows.sort((a, b) => b.startedAt.localeCompare(a.startedAt));
62
+ const payload = {
63
+ schema: 'sharkcraft.mcp-migrations/v1',
64
+ available: true,
65
+ total: rows.length,
66
+ migrations: rows,
67
+ };
68
+ return { data: payload };
69
+ },
70
+ };
@@ -0,0 +1,8 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ /**
3
+ * Read-only MCP mirror of `shrk search-structural registry list`.
4
+ * Returns the full registry payload — the agent can pick a pattern by
5
+ * id and reference it in subsequent `get_structural_search` calls.
6
+ */
7
+ export declare const getPatternRegistryTool: IToolDefinition;
8
+ //# sourceMappingURL=get-pattern-registry.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-pattern-registry.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-pattern-registry.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAkCpC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { PatternRegistryStore } from '@shrkcrft/structural-search';
2
+ /**
3
+ * Read-only MCP mirror of `shrk search-structural registry list`.
4
+ * Returns the full registry payload — the agent can pick a pattern by
5
+ * id and reference it in subsequent `get_structural_search` calls.
6
+ */
7
+ export const getPatternRegistryTool = {
8
+ name: 'get_pattern_registry',
9
+ description: 'Return the persistent registry of reusable structural-search patterns. Read-only.',
10
+ cliCommand: 'search-structural registry list',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {},
14
+ additionalProperties: false,
15
+ },
16
+ handler(_input, ctx) {
17
+ const store = new PatternRegistryStore(ctx.inspection.projectRoot);
18
+ if (!store.exists()) {
19
+ return {
20
+ data: {
21
+ schema: 'sharkcraft.structural-pattern-registry/v1',
22
+ present: false,
23
+ path: store.absPath,
24
+ patterns: [],
25
+ nextCommands: ['shrk search-structural registry seed', 'shrk search-structural registry add'],
26
+ },
27
+ };
28
+ }
29
+ const reg = store.read();
30
+ return {
31
+ data: {
32
+ schema: reg.schema,
33
+ present: true,
34
+ path: store.absPath,
35
+ patterns: reg.patterns,
36
+ total: reg.patterns.length,
37
+ },
38
+ };
39
+ },
40
+ };
@@ -0,0 +1,3 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ export declare const getQualityGateTool: IToolDefinition;
3
+ //# sourceMappingURL=get-quality-gate.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-quality-gate.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-quality-gate.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAQpE,eAAO,MAAM,kBAAkB,EAAE,eA0BhC,CAAC"}