@shrkcrft/mcp-server 0.1.0-alpha.1 → 0.1.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.js +1 -1
- package/dist/server/create-mcp-server.d.ts.map +1 -1
- package/dist/server/create-mcp-server.js +21 -15
- package/dist/server/http-transport.d.ts +2 -7
- package/dist/server/http-transport.d.ts.map +1 -1
- package/dist/server/http-transport.js +6 -10
- package/dist/tools/all-tools.d.ts.map +1 -1
- package/dist/tools/all-tools.js +49 -7
- package/dist/tools/diff-check.tool.d.ts +15 -0
- package/dist/tools/diff-check.tool.d.ts.map +1 -0
- package/dist/tools/diff-check.tool.js +157 -0
- package/dist/tools/file-advice.tool.d.ts +22 -0
- package/dist/tools/file-advice.tool.d.ts.map +1 -0
- package/dist/tools/file-advice.tool.js +88 -0
- package/dist/tools/get-api-surface-diff.tool.d.ts +3 -0
- package/dist/tools/get-api-surface-diff.tool.d.ts.map +1 -0
- package/dist/tools/get-api-surface-diff.tool.js +60 -0
- package/dist/tools/get-arch-violations.tool.d.ts +3 -0
- package/dist/tools/get-arch-violations.tool.d.ts.map +1 -0
- package/dist/tools/get-arch-violations.tool.js +30 -0
- package/dist/tools/get-code-intelligence-state.tool.d.ts +11 -0
- package/dist/tools/get-code-intelligence-state.tool.d.ts.map +1 -0
- package/dist/tools/get-code-intelligence-state.tool.js +59 -0
- package/dist/tools/get-context-pack.tool.d.ts +3 -0
- package/dist/tools/get-context-pack.tool.d.ts.map +1 -0
- package/dist/tools/get-context-pack.tool.js +40 -0
- package/dist/tools/get-framework-entities.tool.d.ts +3 -0
- package/dist/tools/get-framework-entities.tool.d.ts.map +1 -0
- package/dist/tools/get-framework-entities.tool.js +68 -0
- package/dist/tools/get-graph-callers.tool.d.ts +3 -0
- package/dist/tools/get-graph-callers.tool.d.ts.map +1 -0
- package/dist/tools/get-graph-callers.tool.js +80 -0
- package/dist/tools/get-graph-context.tool.d.ts +3 -0
- package/dist/tools/get-graph-context.tool.d.ts.map +1 -0
- package/dist/tools/get-graph-context.tool.js +91 -0
- package/dist/tools/get-graph-cycles.tool.d.ts +10 -0
- package/dist/tools/get-graph-cycles.tool.d.ts.map +1 -0
- package/dist/tools/get-graph-cycles.tool.js +57 -0
- package/dist/tools/get-graph-deps.tool.d.ts +12 -0
- package/dist/tools/get-graph-deps.tool.d.ts.map +1 -0
- package/dist/tools/get-graph-deps.tool.js +80 -0
- package/dist/tools/get-graph-impact-analysis.tool.d.ts +3 -0
- package/dist/tools/get-graph-impact-analysis.tool.d.ts.map +1 -0
- package/dist/tools/get-graph-impact-analysis.tool.js +42 -0
- package/dist/tools/get-graph-impact.tool.d.ts +3 -0
- package/dist/tools/get-graph-impact.tool.d.ts.map +1 -0
- package/dist/tools/get-graph-impact.tool.js +127 -0
- package/dist/tools/get-graph-search.tool.d.ts +3 -0
- package/dist/tools/get-graph-search.tool.d.ts.map +1 -0
- package/dist/tools/get-graph-search.tool.js +75 -0
- package/dist/tools/get-graph-status.tool.d.ts +9 -0
- package/dist/tools/get-graph-status.tool.d.ts.map +1 -0
- package/dist/tools/get-graph-status.tool.js +46 -0
- package/dist/tools/get-graph-unresolved.tool.d.ts +11 -0
- package/dist/tools/get-graph-unresolved.tool.d.ts.map +1 -0
- package/dist/tools/get-graph-unresolved.tool.js +81 -0
- package/dist/tools/get-impact-baseline.tool.d.ts +9 -0
- package/dist/tools/get-impact-baseline.tool.d.ts.map +1 -0
- package/dist/tools/get-impact-baseline.tool.js +65 -0
- package/dist/tools/get-intent-benchmark-run.tool.d.ts +12 -0
- package/dist/tools/get-intent-benchmark-run.tool.d.ts.map +1 -0
- package/dist/tools/get-intent-benchmark-run.tool.js +55 -0
- package/dist/tools/get-migrations.tool.d.ts +3 -0
- package/dist/tools/get-migrations.tool.d.ts.map +1 -0
- package/dist/tools/get-migrations.tool.js +70 -0
- package/dist/tools/get-pattern-registry.tool.d.ts +8 -0
- package/dist/tools/get-pattern-registry.tool.d.ts.map +1 -0
- package/dist/tools/get-pattern-registry.tool.js +40 -0
- package/dist/tools/get-quality-gate.tool.d.ts +3 -0
- package/dist/tools/get-quality-gate.tool.d.ts.map +1 -0
- package/dist/tools/get-quality-gate.tool.js +27 -0
- package/dist/tools/get-rules-for-file.tool.d.ts +3 -0
- package/dist/tools/get-rules-for-file.tool.d.ts.map +1 -0
- package/dist/tools/get-rules-for-file.tool.js +54 -0
- package/dist/tools/get-structural-rewrite-plan.tool.d.ts +3 -0
- package/dist/tools/get-structural-rewrite-plan.tool.d.ts.map +1 -0
- package/dist/tools/get-structural-rewrite-plan.tool.js +46 -0
- package/dist/tools/get-structural-search.tool.d.ts +3 -0
- package/dist/tools/get-structural-search.tool.d.ts.map +1 -0
- package/dist/tools/get-structural-search.tool.js +35 -0
- package/dist/tools/primary-tools.d.ts +24 -0
- package/dist/tools/primary-tools.d.ts.map +1 -0
- package/dist/tools/primary-tools.js +70 -0
- package/dist/tools/r19-extras.tool.js +1 -1
- package/dist/tools/r32-profiles.tool.d.ts +0 -3
- package/dist/tools/r32-profiles.tool.d.ts.map +1 -1
- package/dist/tools/r32-profiles.tool.js +3 -54
- package/package.json +31 -20
- package/dist/tools/r28-plugin-lifecycle.tool.d.ts +0 -4
- package/dist/tools/r28-plugin-lifecycle.tool.d.ts.map +0 -1
- package/dist/tools/r28-plugin-lifecycle.tool.js +0 -94
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { runArchCheck } from '@shrkcrft/architecture-guard';
|
|
2
|
+
export const getArchViolationsTool = {
|
|
3
|
+
name: 'get_arch_violations',
|
|
4
|
+
description: 'Run the architecture-guard checks (public-API misuse, barrel risks, cycle severity) against the code graph. Reads `sharkcraft/arch.ts` if present for project-specific contracts. Read-only.',
|
|
5
|
+
cliCommand: 'arch check',
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
enable: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
publicApi: { type: 'boolean' },
|
|
13
|
+
barrels: { type: 'boolean' },
|
|
14
|
+
cycles: { type: 'boolean' },
|
|
15
|
+
contract: { type: 'boolean' },
|
|
16
|
+
},
|
|
17
|
+
additionalProperties: false,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
},
|
|
22
|
+
handler(input, ctx) {
|
|
23
|
+
const args = input;
|
|
24
|
+
const report = runArchCheck({
|
|
25
|
+
projectRoot: ctx.inspection.projectRoot,
|
|
26
|
+
...(args.enable ? { enable: args.enable } : {}),
|
|
27
|
+
});
|
|
28
|
+
return { data: report };
|
|
29
|
+
},
|
|
30
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IToolDefinition } from '../server/tool-definition.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read-only MCP mirror of `shrk code-intel`. Returns the same 14
|
|
4
|
+
* code-intelligence doctor findings in one shot — agents can pull
|
|
5
|
+
* the entire state without iterating `shrk doctor`'s full check list.
|
|
6
|
+
*
|
|
7
|
+
* Stable output schema (`sharkcraft.code-intelligence-state/v1`) so
|
|
8
|
+
* downstream renderers (dashboard, CI bots) can rely on the shape.
|
|
9
|
+
*/
|
|
10
|
+
export declare const getCodeIntelligenceStateTool: IToolDefinition;
|
|
11
|
+
//# sourceMappingURL=get-code-intelligence-state.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-code-intelligence-state.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-code-intelligence-state.tool.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AASpE;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,EAAE,eAiC1C,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { buildCodeIntelligenceChecks, DoctorSeverity, } from '@shrkcrft/inspector';
|
|
2
|
+
/**
|
|
3
|
+
* Read-only MCP mirror of `shrk code-intel`. Returns the same 14
|
|
4
|
+
* code-intelligence doctor findings in one shot — agents can pull
|
|
5
|
+
* the entire state without iterating `shrk doctor`'s full check list.
|
|
6
|
+
*
|
|
7
|
+
* Stable output schema (`sharkcraft.code-intelligence-state/v1`) so
|
|
8
|
+
* downstream renderers (dashboard, CI bots) can rely on the shape.
|
|
9
|
+
*/
|
|
10
|
+
export const getCodeIntelligenceStateTool = {
|
|
11
|
+
name: 'get_code_intelligence_state',
|
|
12
|
+
description: 'Return all code-intelligence doctor findings (graph, rule-graph, api-surface, quality-gate, migrations, architecture, impact, framework, structural-search, context-planner) in one payload. Read-only.',
|
|
13
|
+
cliCommand: 'code-intel',
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
only: { type: 'array', items: { type: 'string' } },
|
|
18
|
+
checkId: { type: 'string' },
|
|
19
|
+
},
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
},
|
|
22
|
+
handler(input, ctx) {
|
|
23
|
+
const args = input;
|
|
24
|
+
let checks = buildCodeIntelligenceChecks(ctx.inspection.projectRoot);
|
|
25
|
+
if (args.checkId) {
|
|
26
|
+
checks = checks.filter((c) => c.id === args.checkId);
|
|
27
|
+
}
|
|
28
|
+
if (args.only && args.only.length > 0) {
|
|
29
|
+
const allowed = new Set(args.only.map((s) => s.toLowerCase()));
|
|
30
|
+
checks = checks.filter((c) => allowed.has(c.severity));
|
|
31
|
+
}
|
|
32
|
+
const summary = summarize(checks);
|
|
33
|
+
return {
|
|
34
|
+
data: {
|
|
35
|
+
schema: 'sharkcraft.code-intelligence-state/v1',
|
|
36
|
+
totalChecks: checks.length,
|
|
37
|
+
summary,
|
|
38
|
+
checks,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
function summarize(checks) {
|
|
44
|
+
let ok = 0;
|
|
45
|
+
let info = 0;
|
|
46
|
+
let warnings = 0;
|
|
47
|
+
let errors = 0;
|
|
48
|
+
for (const c of checks) {
|
|
49
|
+
if (c.severity === DoctorSeverity.Ok)
|
|
50
|
+
ok += 1;
|
|
51
|
+
else if (c.severity === DoctorSeverity.Info)
|
|
52
|
+
info += 1;
|
|
53
|
+
else if (c.severity === DoctorSeverity.Warning)
|
|
54
|
+
warnings += 1;
|
|
55
|
+
else if (c.severity === DoctorSeverity.Error)
|
|
56
|
+
errors += 1;
|
|
57
|
+
}
|
|
58
|
+
return { ok, info, warnings, errors };
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-context-pack.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-context-pack.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAUpE,eAAO,MAAM,kBAAkB,EAAE,eAoChC,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { planContext } from '@shrkcrft/context-planner';
|
|
2
|
+
export const getContextPackTool = {
|
|
3
|
+
name: 'get_context_pack',
|
|
4
|
+
description: 'Produce a deterministic, token-budgeted context pack (`sharkcraft.context-pack/v1`) for an AI coding agent: ranked relevant files, applicable rules, paths, templates, likely tests, surfaced risks, do-not-touch zones. Read-only.',
|
|
5
|
+
cliCommand: 'plan-context',
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
task: { type: 'string' },
|
|
10
|
+
budgetTokens: { type: 'number' },
|
|
11
|
+
hintedFiles: { type: 'array', items: { type: 'string' } },
|
|
12
|
+
hintedPackages: { type: 'array', items: { type: 'string' } },
|
|
13
|
+
maxFiles: { type: 'number' },
|
|
14
|
+
},
|
|
15
|
+
required: ['task'],
|
|
16
|
+
additionalProperties: false,
|
|
17
|
+
},
|
|
18
|
+
handler(input, ctx) {
|
|
19
|
+
const args = input;
|
|
20
|
+
const task = (args.task ?? '').trim();
|
|
21
|
+
if (!task) {
|
|
22
|
+
return {
|
|
23
|
+
isError: true,
|
|
24
|
+
error: { code: 'invalid-input', message: 'task is required' },
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const pack = planContext({
|
|
28
|
+
projectRoot: ctx.inspection.projectRoot,
|
|
29
|
+
task,
|
|
30
|
+
budgetTokens: clamp(args.budgetTokens ?? 8000, 500, 64000),
|
|
31
|
+
maxFiles: clamp(args.maxFiles ?? 30, 1, 200),
|
|
32
|
+
...(args.hintedFiles ? { hintedFiles: args.hintedFiles } : {}),
|
|
33
|
+
...(args.hintedPackages ? { hintedPackages: args.hintedPackages } : {}),
|
|
34
|
+
});
|
|
35
|
+
return { data: pack };
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
function clamp(n, lo, hi) {
|
|
39
|
+
return Math.max(lo, Math.min(hi, n));
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-framework-entities.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-framework-entities.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAYpE,eAAO,MAAM,wBAAwB,EAAE,eA+DtC,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { FrameworkQueryApi } from '@shrkcrft/framework-scanners';
|
|
2
|
+
const NEXT = 'shrk framework index';
|
|
3
|
+
export const getFrameworkEntitiesTool = {
|
|
4
|
+
name: 'get_framework_entities',
|
|
5
|
+
description: 'Read-only: list framework entities discovered by the extractors (NestJS controllers/modules/providers/routes, React components/hook usages). Filters: framework, subtype, file. Pass `routes: true` for the NestJS route table.',
|
|
6
|
+
cliCommand: 'framework list',
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {
|
|
10
|
+
framework: { type: 'string' },
|
|
11
|
+
subtype: { type: 'string' },
|
|
12
|
+
file: { type: 'string' },
|
|
13
|
+
limit: { type: 'number' },
|
|
14
|
+
routes: { type: 'boolean' },
|
|
15
|
+
},
|
|
16
|
+
additionalProperties: false,
|
|
17
|
+
},
|
|
18
|
+
handler(input, ctx) {
|
|
19
|
+
const args = input;
|
|
20
|
+
const missing = FrameworkQueryApi.missingDescription(ctx.inspection.projectRoot);
|
|
21
|
+
if (missing) {
|
|
22
|
+
return {
|
|
23
|
+
isError: true,
|
|
24
|
+
error: { code: 'framework-missing', message: missing, details: { nextCommand: NEXT } },
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const api = FrameworkQueryApi.fromStore(ctx.inspection.projectRoot);
|
|
28
|
+
if (args.routes) {
|
|
29
|
+
const routes = api.routes();
|
|
30
|
+
return {
|
|
31
|
+
data: {
|
|
32
|
+
schema: 'sharkcraft.framework-routes/v1',
|
|
33
|
+
total: routes.length,
|
|
34
|
+
routes,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const limit = clamp(args.limit ?? 100, 1, 2000);
|
|
39
|
+
const entities = api.list({
|
|
40
|
+
...(args.framework ? { framework: args.framework } : {}),
|
|
41
|
+
...(args.subtype ? { subtype: args.subtype } : {}),
|
|
42
|
+
...(args.file ? { file: args.file } : {}),
|
|
43
|
+
limit,
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
data: {
|
|
47
|
+
schema: 'sharkcraft.framework-list/v1',
|
|
48
|
+
filters: {
|
|
49
|
+
framework: args.framework ?? null,
|
|
50
|
+
subtype: args.subtype ?? null,
|
|
51
|
+
file: args.file ?? null,
|
|
52
|
+
},
|
|
53
|
+
total: entities.length,
|
|
54
|
+
entities: entities.map((n) => ({
|
|
55
|
+
id: n.id,
|
|
56
|
+
label: n.label,
|
|
57
|
+
path: n.path,
|
|
58
|
+
framework: n.data?.['framework'] ?? null,
|
|
59
|
+
subtype: n.data?.['subtype'] ?? null,
|
|
60
|
+
data: n.data,
|
|
61
|
+
})),
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
function clamp(n, lo, hi) {
|
|
67
|
+
return Math.max(lo, Math.min(hi, n));
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-graph-callers.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-graph-callers.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AASpE,eAAO,MAAM,mBAAmB,EAAE,eA0DjC,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { GraphQueryApi, GraphStore } from '@shrkcrft/graph';
|
|
2
|
+
const NEXT = 'shrk graph index';
|
|
3
|
+
export const getGraphCallersTool = {
|
|
4
|
+
name: 'get_graph_callers',
|
|
5
|
+
description: 'Return files that call or reference the given symbol. Mode "call" → calls-symbol edges; mode "reference" → both references-symbol and calls-symbol. Read-only.',
|
|
6
|
+
cliCommand: 'graph callers',
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {
|
|
10
|
+
symbol: { type: 'string' },
|
|
11
|
+
mode: { type: 'string', enum: ['call', 'reference'] },
|
|
12
|
+
},
|
|
13
|
+
required: ['symbol'],
|
|
14
|
+
additionalProperties: false,
|
|
15
|
+
},
|
|
16
|
+
handler(input, ctx) {
|
|
17
|
+
const args = input;
|
|
18
|
+
const target = (args.symbol ?? '').trim();
|
|
19
|
+
if (!target) {
|
|
20
|
+
return {
|
|
21
|
+
isError: true,
|
|
22
|
+
error: { code: 'invalid-input', message: 'symbol is required' },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const mode = args.mode ?? 'call';
|
|
26
|
+
const store = new GraphStore(ctx.inspection.projectRoot);
|
|
27
|
+
if (!store.exists()) {
|
|
28
|
+
return {
|
|
29
|
+
isError: true,
|
|
30
|
+
error: {
|
|
31
|
+
code: 'graph-missing',
|
|
32
|
+
message: `Code-intelligence index is missing. Run '${NEXT}'.`,
|
|
33
|
+
details: { nextCommand: NEXT },
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const api = GraphQueryApi.fromStore(ctx.inspection.projectRoot);
|
|
38
|
+
const sym = resolveSymbol(api, target);
|
|
39
|
+
if (!sym) {
|
|
40
|
+
return {
|
|
41
|
+
isError: true,
|
|
42
|
+
error: {
|
|
43
|
+
code: 'not-found',
|
|
44
|
+
message: `No symbol matched "${target}".`,
|
|
45
|
+
details: { target },
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const hits = mode === 'reference' ? api.referencesOf(sym.id) : api.callersOf(sym.id);
|
|
50
|
+
return {
|
|
51
|
+
data: {
|
|
52
|
+
schema: 'sharkcraft.graph-callers/v1',
|
|
53
|
+
symbol: summarise(sym),
|
|
54
|
+
mode,
|
|
55
|
+
total: hits.length,
|
|
56
|
+
callers: hits.slice(0, 200).map(summarise),
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
function resolveSymbol(api, target) {
|
|
62
|
+
if (target.startsWith('symbol:'))
|
|
63
|
+
return api.neighbours(target)?.node;
|
|
64
|
+
const syms = api.findSymbol(target, { exact: true, limit: 5 });
|
|
65
|
+
if (syms.length === 0)
|
|
66
|
+
return undefined;
|
|
67
|
+
if (syms.length === 1)
|
|
68
|
+
return syms[0];
|
|
69
|
+
const exported = syms.find((s) => (s.data?.['isExported'] ?? false) === true);
|
|
70
|
+
return exported ?? syms[0];
|
|
71
|
+
}
|
|
72
|
+
function summarise(n) {
|
|
73
|
+
return {
|
|
74
|
+
id: n.id,
|
|
75
|
+
kind: n.kind,
|
|
76
|
+
label: n.label,
|
|
77
|
+
...(n.path ? { path: n.path } : {}),
|
|
78
|
+
...(n.line ? { line: n.line } : {}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-graph-context.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-graph-context.tool.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAQpE,eAAO,MAAM,mBAAmB,EAAE,eAiEjC,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { GraphQueryApi, GraphStore, NodeKind, } from '@shrkcrft/graph';
|
|
2
|
+
const NEXT = 'shrk graph index';
|
|
3
|
+
export const getGraphContextTool = {
|
|
4
|
+
name: 'get_graph_context',
|
|
5
|
+
description: 'Return graph context for a file or symbol: declared symbols, files this imports, files that import it. Read-only.',
|
|
6
|
+
cliCommand: 'graph context',
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: { target: { type: 'string' } },
|
|
10
|
+
required: ['target'],
|
|
11
|
+
additionalProperties: false,
|
|
12
|
+
},
|
|
13
|
+
handler(input, ctx) {
|
|
14
|
+
const args = input;
|
|
15
|
+
const target = (args.target ?? '').trim();
|
|
16
|
+
if (!target) {
|
|
17
|
+
return {
|
|
18
|
+
isError: true,
|
|
19
|
+
error: { code: 'invalid-input', message: 'target is required' },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const store = new GraphStore(ctx.inspection.projectRoot);
|
|
23
|
+
if (!store.exists()) {
|
|
24
|
+
return {
|
|
25
|
+
isError: true,
|
|
26
|
+
error: {
|
|
27
|
+
code: 'graph-missing',
|
|
28
|
+
message: `Code-intelligence index is missing. Run '${NEXT}'.`,
|
|
29
|
+
details: { nextCommand: NEXT },
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const api = GraphQueryApi.fromStore(ctx.inspection.projectRoot);
|
|
34
|
+
const anchor = resolveAnchor(api, target);
|
|
35
|
+
if (!anchor) {
|
|
36
|
+
return {
|
|
37
|
+
isError: true,
|
|
38
|
+
error: {
|
|
39
|
+
code: 'not-found',
|
|
40
|
+
message: `No graph node matched "${target}".`,
|
|
41
|
+
details: { target },
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const neighbours = api.neighbours(anchor.id);
|
|
46
|
+
const symbols = anchor.kind === NodeKind.File ? api.symbolsIn(anchor.id) : [];
|
|
47
|
+
return {
|
|
48
|
+
data: {
|
|
49
|
+
schema: 'sharkcraft.graph-context/v1',
|
|
50
|
+
anchor: summarise(anchor),
|
|
51
|
+
importsFrom: neighbours.out
|
|
52
|
+
.filter((o) => o.edge.kind === 'imports-file')
|
|
53
|
+
.slice(0, 50)
|
|
54
|
+
.map((o) => ('resolved' in o.target
|
|
55
|
+
? { id: o.target.id, resolved: false }
|
|
56
|
+
: { ...summarise(o.target), resolved: true })),
|
|
57
|
+
importedBy: neighbours.in
|
|
58
|
+
.filter((i) => i.edge.kind === 'imports-file')
|
|
59
|
+
.slice(0, 50)
|
|
60
|
+
.map((i) => ('resolved' in i.source
|
|
61
|
+
? { id: i.source.id, resolved: false }
|
|
62
|
+
: { ...summarise(i.source), resolved: true })),
|
|
63
|
+
symbols: symbols.slice(0, 50).map(summarise),
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
function resolveAnchor(api, target) {
|
|
69
|
+
const direct = api.neighbours(target);
|
|
70
|
+
if (direct)
|
|
71
|
+
return direct.node;
|
|
72
|
+
if (target.startsWith('file:') || target.startsWith('symbol:') || target.startsWith('package:')) {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
const f = api.findFile(target);
|
|
76
|
+
if (f)
|
|
77
|
+
return f;
|
|
78
|
+
const syms = api.findSymbol(target, { exact: true, limit: 1 });
|
|
79
|
+
if (syms.length > 0)
|
|
80
|
+
return syms[0];
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
function summarise(n) {
|
|
84
|
+
return {
|
|
85
|
+
id: n.id,
|
|
86
|
+
kind: n.kind,
|
|
87
|
+
label: n.label,
|
|
88
|
+
...(n.path ? { path: n.path } : {}),
|
|
89
|
+
...(n.line ? { line: n.line } : {}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IToolDefinition } from '../server/tool-definition.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read-only MCP mirror of `shrk graph cycles`. Returns the full SCC
|
|
4
|
+
* list (sorted by size desc) so agents can answer "show me every
|
|
5
|
+
* import cycle in this repo" in a single tool call. Mirrors the safety
|
|
6
|
+
* contract: read-only, structured error with nextCommand when state
|
|
7
|
+
* is missing.
|
|
8
|
+
*/
|
|
9
|
+
export declare const getGraphCyclesTool: IToolDefinition;
|
|
10
|
+
//# sourceMappingURL=get-graph-cycles.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-graph-cycles.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-graph-cycles.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAWpE;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAmDhC,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { GraphQueryApi, GraphStore } from '@shrkcrft/graph';
|
|
2
|
+
const NEXT = 'shrk graph index';
|
|
3
|
+
/**
|
|
4
|
+
* Read-only MCP mirror of `shrk graph cycles`. Returns the full SCC
|
|
5
|
+
* list (sorted by size desc) so agents can answer "show me every
|
|
6
|
+
* import cycle in this repo" in a single tool call. Mirrors the safety
|
|
7
|
+
* contract: read-only, structured error with nextCommand when state
|
|
8
|
+
* is missing.
|
|
9
|
+
*/
|
|
10
|
+
export const getGraphCyclesTool = {
|
|
11
|
+
name: 'get_graph_cycles',
|
|
12
|
+
description: 'Return every import cycle in the code graph (strongly-connected components of size ≥ 2 over `imports-file` edges). Sorted by size desc. Read-only.',
|
|
13
|
+
cliCommand: 'graph cycles',
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
limit: { type: 'number' },
|
|
18
|
+
minSize: { type: 'number' },
|
|
19
|
+
},
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
},
|
|
22
|
+
handler(input, ctx) {
|
|
23
|
+
const args = input;
|
|
24
|
+
const rawLimit = typeof args.limit === 'number' && Number.isFinite(args.limit) && args.limit > 0
|
|
25
|
+
? args.limit
|
|
26
|
+
: 50;
|
|
27
|
+
const minSize = typeof args.minSize === 'number' && Number.isFinite(args.minSize) && args.minSize >= 2
|
|
28
|
+
? args.minSize
|
|
29
|
+
: 2;
|
|
30
|
+
const store = new GraphStore(ctx.inspection.projectRoot);
|
|
31
|
+
if (!store.exists()) {
|
|
32
|
+
return {
|
|
33
|
+
isError: true,
|
|
34
|
+
error: {
|
|
35
|
+
code: 'graph-missing',
|
|
36
|
+
message: `Code-intelligence index is missing. Run '${NEXT}'.`,
|
|
37
|
+
details: { nextCommand: NEXT },
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const api = GraphQueryApi.fromStore(ctx.inspection.projectRoot);
|
|
42
|
+
const all = api.cycles();
|
|
43
|
+
const filtered = all.filter((c) => c.size >= minSize);
|
|
44
|
+
const limited = filtered.slice(0, rawLimit);
|
|
45
|
+
return {
|
|
46
|
+
data: {
|
|
47
|
+
schema: 'sharkcraft.graph-cycles/v1',
|
|
48
|
+
total: filtered.length,
|
|
49
|
+
truncated: filtered.length > rawLimit,
|
|
50
|
+
cycles: limited.map((c) => ({
|
|
51
|
+
size: c.size,
|
|
52
|
+
paths: c.paths ?? c.nodeIds.map((id) => id.replace(/^file:/, '')),
|
|
53
|
+
})),
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IToolDefinition } from '../server/tool-definition.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read-only MCP mirror of `shrk graph deps`. Returns the workspace
|
|
4
|
+
* package's outbound (`depends on`) and inbound (`depended on by`)
|
|
5
|
+
* `package-depends-on` edges from the persisted code graph.
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the safety contract: structured `graph-missing` error when
|
|
8
|
+
* the index isn't built; `not-found` when no `package:<name>` node
|
|
9
|
+
* exists.
|
|
10
|
+
*/
|
|
11
|
+
export declare const getGraphDepsTool: IToolDefinition;
|
|
12
|
+
//# sourceMappingURL=get-graph-deps.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-graph-deps.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-graph-deps.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AASpE;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAmE9B,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { EdgeKind, GraphQueryApi, GraphStore } from '@shrkcrft/graph';
|
|
2
|
+
const NEXT = 'shrk graph index';
|
|
3
|
+
/**
|
|
4
|
+
* Read-only MCP mirror of `shrk graph deps`. Returns the workspace
|
|
5
|
+
* package's outbound (`depends on`) and inbound (`depended on by`)
|
|
6
|
+
* `package-depends-on` edges from the persisted code graph.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors the safety contract: structured `graph-missing` error when
|
|
9
|
+
* the index isn't built; `not-found` when no `package:<name>` node
|
|
10
|
+
* exists.
|
|
11
|
+
*/
|
|
12
|
+
export const getGraphDepsTool = {
|
|
13
|
+
name: 'get_graph_deps',
|
|
14
|
+
description: 'Return inbound + outbound `package-depends-on` edges for a workspace package. Read-only.',
|
|
15
|
+
cliCommand: 'graph deps',
|
|
16
|
+
inputSchema: {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {
|
|
19
|
+
package: { type: 'string' },
|
|
20
|
+
},
|
|
21
|
+
required: ['package'],
|
|
22
|
+
additionalProperties: false,
|
|
23
|
+
},
|
|
24
|
+
handler(input, ctx) {
|
|
25
|
+
const args = input;
|
|
26
|
+
const target = (args.package ?? '').trim();
|
|
27
|
+
if (!target) {
|
|
28
|
+
return {
|
|
29
|
+
isError: true,
|
|
30
|
+
error: { code: 'invalid-input', message: 'package is required' },
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const store = new GraphStore(ctx.inspection.projectRoot);
|
|
34
|
+
if (!store.exists()) {
|
|
35
|
+
return {
|
|
36
|
+
isError: true,
|
|
37
|
+
error: {
|
|
38
|
+
code: 'graph-missing',
|
|
39
|
+
message: `Code-intelligence index is missing. Run '${NEXT}'.`,
|
|
40
|
+
details: { nextCommand: NEXT },
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const api = GraphQueryApi.fromStore(ctx.inspection.projectRoot);
|
|
45
|
+
const pkgId = `package:${target}`;
|
|
46
|
+
const pkgNode = api.neighbours(pkgId)?.node;
|
|
47
|
+
if (!pkgNode) {
|
|
48
|
+
return {
|
|
49
|
+
isError: true,
|
|
50
|
+
error: {
|
|
51
|
+
code: 'not-found',
|
|
52
|
+
message: `No workspace package node "${target}" in the graph.`,
|
|
53
|
+
details: { target },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const dependsOn = api
|
|
58
|
+
.packageDeps(target)
|
|
59
|
+
.map((n) => n.id.replace(/^package:/, ''))
|
|
60
|
+
.sort();
|
|
61
|
+
const dependedOnBy = [];
|
|
62
|
+
for (const p of api.allPackages()) {
|
|
63
|
+
const name = p.id.replace(/^package:/, '');
|
|
64
|
+
if (name === target)
|
|
65
|
+
continue;
|
|
66
|
+
if (api.packageDeps(name).some((n) => n.id === pkgId))
|
|
67
|
+
dependedOnBy.push(name);
|
|
68
|
+
}
|
|
69
|
+
dependedOnBy.sort();
|
|
70
|
+
void EdgeKind;
|
|
71
|
+
return {
|
|
72
|
+
data: {
|
|
73
|
+
schema: 'sharkcraft.graph-deps/v1',
|
|
74
|
+
package: target,
|
|
75
|
+
dependsOn,
|
|
76
|
+
dependedOnBy,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-graph-impact-analysis.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-graph-impact-analysis.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAUpE,eAAO,MAAM,0BAA0B,EAAE,eAmCxC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { analyzeGraphImpact } from '@shrkcrft/impact-engine';
|
|
2
|
+
export const getGraphImpactAnalysisTool = {
|
|
3
|
+
name: 'get_graph_impact_analysis',
|
|
4
|
+
description: 'Rich graph-backed change analysis (schema sharkcraft.graph-impact-analysis/v3). Inputs: file list OR symbol OR git ref. Returns affected symbols/files/packages/rules/templates/tests/risk + recommended validation commands. Read-only.',
|
|
5
|
+
cliCommand: 'graph impact',
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
files: { type: 'array', items: { type: 'string' } },
|
|
10
|
+
symbol: { type: 'string' },
|
|
11
|
+
gitref: { type: 'string' },
|
|
12
|
+
maxDepth: { type: 'number' },
|
|
13
|
+
limit: { type: 'number' },
|
|
14
|
+
},
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
},
|
|
17
|
+
handler(input, ctx) {
|
|
18
|
+
const args = input;
|
|
19
|
+
let resolved;
|
|
20
|
+
if (args.files && args.files.length > 0)
|
|
21
|
+
resolved = { kind: 'files', files: args.files };
|
|
22
|
+
else if (args.symbol)
|
|
23
|
+
resolved = { kind: 'symbol', symbolId: args.symbol };
|
|
24
|
+
else if (args.gitref)
|
|
25
|
+
resolved = { kind: 'gitref', ref: args.gitref };
|
|
26
|
+
if (!resolved) {
|
|
27
|
+
return {
|
|
28
|
+
isError: true,
|
|
29
|
+
error: { code: 'invalid-input', message: 'One of `files`, `symbol`, or `gitref` is required.' },
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const analysis = analyzeGraphImpact(resolved, {
|
|
33
|
+
projectRoot: ctx.inspection.projectRoot,
|
|
34
|
+
limit: clamp(args.limit ?? 200, 1, 2000),
|
|
35
|
+
maxDepth: clamp(args.maxDepth ?? 5, 1, 10),
|
|
36
|
+
});
|
|
37
|
+
return { data: analysis };
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
function clamp(n, lo, hi) {
|
|
41
|
+
return Math.max(lo, Math.min(hi, n));
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-graph-impact.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-graph-impact.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAUpE,eAAO,MAAM,kBAAkB,EAAE,eAmEhC,CAAC"}
|