@shrkcrft/mcp-server 0.1.0-alpha.14 → 0.1.0-alpha.16

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 (94) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -0
  4. package/dist/server/columnar-format.d.ts +34 -0
  5. package/dist/server/columnar-format.d.ts.map +1 -0
  6. package/dist/server/columnar-format.js +95 -0
  7. package/dist/server/create-mcp-server.d.ts +3 -0
  8. package/dist/server/create-mcp-server.d.ts.map +1 -1
  9. package/dist/server/create-mcp-server.js +5 -2
  10. package/dist/server/fit-array-to-budget.d.ts +20 -0
  11. package/dist/server/fit-array-to-budget.d.ts.map +1 -0
  12. package/dist/server/fit-array-to-budget.js +28 -0
  13. package/dist/server/serialize-tool-data.d.ts +15 -0
  14. package/dist/server/serialize-tool-data.d.ts.map +1 -0
  15. package/dist/server/serialize-tool-data.js +22 -0
  16. package/dist/server/tool-definition.d.ts +15 -0
  17. package/dist/server/tool-definition.d.ts.map +1 -1
  18. package/dist/server/tool-input-validators.d.ts.map +1 -1
  19. package/dist/server/tool-input-validators.js +43 -0
  20. package/dist/tools/agent-brief.tool.d.ts.map +1 -1
  21. package/dist/tools/agent-brief.tool.js +20 -0
  22. package/dist/tools/align-cache.tool.d.ts +11 -0
  23. package/dist/tools/align-cache.tool.d.ts.map +1 -0
  24. package/dist/tools/align-cache.tool.js +76 -0
  25. package/dist/tools/all-tools.d.ts.map +1 -1
  26. package/dist/tools/all-tools.js +7 -0
  27. package/dist/tools/architecture-map.tool.d.ts.map +1 -1
  28. package/dist/tools/architecture-map.tool.js +4 -2
  29. package/dist/tools/code-find-usages.tool.d.ts.map +1 -1
  30. package/dist/tools/code-find-usages.tool.js +15 -10
  31. package/dist/tools/command-catalog.tool.d.ts.map +1 -1
  32. package/dist/tools/command-catalog.tool.js +11 -7
  33. package/dist/tools/compress-context.tool.d.ts +8 -0
  34. package/dist/tools/compress-context.tool.d.ts.map +1 -0
  35. package/dist/tools/compress-context.tool.js +80 -0
  36. package/dist/tools/dashboard-summary.tool.d.ts.map +1 -1
  37. package/dist/tools/dashboard-summary.tool.js +2 -4
  38. package/dist/tools/deps-audit.tool.d.ts.map +1 -1
  39. package/dist/tools/deps-audit.tool.js +32 -2
  40. package/dist/tools/get-code-intelligence-state.tool.d.ts.map +1 -1
  41. package/dist/tools/get-code-intelligence-state.tool.js +8 -7
  42. package/dist/tools/get-graph-callers.tool.d.ts.map +1 -1
  43. package/dist/tools/get-graph-callers.tool.js +9 -8
  44. package/dist/tools/get-graph-context.tool.d.ts.map +1 -1
  45. package/dist/tools/get-graph-context.tool.js +19 -19
  46. package/dist/tools/get-graph-cycles.tool.d.ts.map +1 -1
  47. package/dist/tools/get-graph-cycles.tool.js +11 -10
  48. package/dist/tools/get-graph-impact-analysis.tool.d.ts.map +1 -1
  49. package/dist/tools/get-graph-impact-analysis.tool.js +3 -1
  50. package/dist/tools/get-graph-impact.tool.d.ts.map +1 -1
  51. package/dist/tools/get-graph-impact.tool.js +14 -13
  52. package/dist/tools/get-graph-search.tool.d.ts.map +1 -1
  53. package/dist/tools/get-graph-search.tool.js +9 -8
  54. package/dist/tools/get-graph-unresolved.tool.d.ts.map +1 -1
  55. package/dist/tools/get-graph-unresolved.tool.js +13 -9
  56. package/dist/tools/get-knowledge-graph.tool.d.ts +7 -0
  57. package/dist/tools/get-knowledge-graph.tool.d.ts.map +1 -1
  58. package/dist/tools/get-knowledge-graph.tool.js +62 -3
  59. package/dist/tools/get-relevant-context.tool.d.ts.map +1 -1
  60. package/dist/tools/get-relevant-context.tool.js +30 -6
  61. package/dist/tools/get-task-packet.tool.d.ts.map +1 -1
  62. package/dist/tools/get-task-packet.tool.js +26 -22
  63. package/dist/tools/list-boundary-rules.tool.d.ts.map +1 -1
  64. package/dist/tools/list-boundary-rules.tool.js +20 -16
  65. package/dist/tools/list-knowledge.tool.d.ts.map +1 -1
  66. package/dist/tools/list-knowledge.tool.js +14 -13
  67. package/dist/tools/list-packs.tool.d.ts.map +1 -1
  68. package/dist/tools/list-packs.tool.js +19 -15
  69. package/dist/tools/list-path-conventions.tool.d.ts.map +1 -1
  70. package/dist/tools/list-path-conventions.tool.js +19 -15
  71. package/dist/tools/list-pipelines.tool.d.ts.map +1 -1
  72. package/dist/tools/list-pipelines.tool.js +18 -14
  73. package/dist/tools/list-presets.tool.d.ts.map +1 -1
  74. package/dist/tools/list-presets.tool.js +25 -21
  75. package/dist/tools/list-rules.tool.d.ts.map +1 -1
  76. package/dist/tools/list-rules.tool.js +18 -14
  77. package/dist/tools/list-templates.tool.d.ts.map +1 -1
  78. package/dist/tools/list-templates.tool.js +18 -14
  79. package/dist/tools/primary-tools.d.ts.map +1 -1
  80. package/dist/tools/primary-tools.js +5 -0
  81. package/dist/tools/retrieve-original.tool.d.ts +9 -0
  82. package/dist/tools/retrieve-original.tool.d.ts.map +1 -0
  83. package/dist/tools/retrieve-original.tool.js +47 -0
  84. package/dist/tools/runtime-reports.tool.d.ts.map +1 -1
  85. package/dist/tools/runtime-reports.tool.js +1 -3
  86. package/dist/tools/safety-audit.tool.d.ts.map +1 -1
  87. package/dist/tools/safety-audit.tool.js +1 -4
  88. package/dist/tools/search-knowledge.tool.d.ts.map +1 -1
  89. package/dist/tools/search-knowledge.tool.js +17 -13
  90. package/dist/tools/search.tool.d.ts.map +1 -1
  91. package/dist/tools/search.tool.js +11 -8
  92. package/dist/tools/smart-context-bundle.tool.d.ts.map +1 -1
  93. package/dist/tools/smart-context-bundle.tool.js +4 -2
  94. package/package.json +27 -26
@@ -1,6 +1,7 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import * as nodePath from 'node:path';
3
3
  import { EdgeKind, GraphQueryApi, GraphStore, NodeKind } from '@shrkcrft/graph';
4
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
4
5
  /**
5
6
  * `code_find_usages` — structured usage finder backed by the
6
7
  * SharkCraft graph (file + symbol nodes + import/declare edges).
@@ -16,13 +17,14 @@ import { EdgeKind, GraphQueryApi, GraphStore, NodeKind } from '@shrkcrft/graph';
16
17
  */
17
18
  export const codeFindUsagesTool = {
18
19
  name: 'code_find_usages',
19
- description: 'Find structured usages of a symbol via the SharkCraft graph (file + symbol nodes). Read-only. Distinguishes definition, import-of-declaring-file, and neighbouring symbols.',
20
+ description: 'Find structured usages of a symbol via the SharkCraft graph (file + symbol nodes). Read-only. Distinguishes definition, import-of-declaring-file, and neighbouring symbols. Pass `format:"table"` for a token-efficient columnar encoding of the definitions/importers/neighbours arrays.',
20
21
  inputSchema: {
21
22
  type: 'object',
22
23
  properties: {
23
24
  symbolName: { type: 'string' },
24
25
  kindHint: { type: 'string' },
25
26
  maxResults: { type: 'number' },
27
+ ...FORMAT_INPUT_PROPERTY,
26
28
  },
27
29
  required: ['symbolName'],
28
30
  additionalProperties: false,
@@ -96,16 +98,19 @@ export const codeFindUsagesTool = {
96
98
  }
97
99
  }
98
100
  }
99
- return {
100
- data: {
101
- symbol: { name: symbolName, kind: matches[0]?.kind ?? 'unknown' },
102
- definitions,
103
- importersOfDeclaringFile: [...importerSet.values()],
104
- neighbouringSymbols: neighbours.slice(0, 12),
105
- totalSymbolMatches: matches.length,
106
- note: 'importersOfDeclaringFile = files that import the declaring file. This is a structural signal — it may include type-only imports and unused references. Pair with `shrk impact` for a tighter blast radius.',
107
- },
101
+ const data = {
102
+ symbol: { name: symbolName, kind: matches[0]?.kind ?? 'unknown' },
103
+ definitions,
104
+ importersOfDeclaringFile: [...importerSet.values()],
105
+ neighbouringSymbols: neighbours.slice(0, 12),
106
+ totalSymbolMatches: matches.length,
107
+ note: 'importersOfDeclaringFile = files that import the declaring file. This is a structural signal — it may include type-only imports and unused references. Pair with `shrk impact` for a tighter blast radius.',
108
108
  };
109
+ // `format:"table"` columnar-encodes the homogeneous object-array fields
110
+ // (definitions, importersOfDeclaringFile, neighbouringSymbols); the scalar
111
+ // `symbol` object, totalSymbolMatches, and the note string pass through
112
+ // untouched. Default/`format:"json"` returns the bare object unchanged.
113
+ return { data: formatObjectArrays(data, input) };
109
114
  },
110
115
  };
111
116
  function declaringFileOf(api, symbolId) {
@@ -1 +1 @@
1
- {"version":3,"file":"command-catalog.tool.d.ts","sourceRoot":"","sources":["../../src/tools/command-catalog.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAiBpE,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,cAAc,CAAC;CAC7C;AAwBD,eAAO,MAAM,sBAAsB,EAAE,SAAS,aAAa,EAgFzD,CAAC;AA+BH,eAAO,MAAM,qBAAqB,EAAE,eA4BnC,CAAC"}
1
+ {"version":3,"file":"command-catalog.tool.d.ts","sourceRoot":"","sources":["../../src/tools/command-catalog.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAkBpE,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,cAAc,CAAC;CAC7C;AAwBD,eAAO,MAAM,sBAAsB,EAAE,SAAS,aAAa,EAgFzD,CAAC;AA+BH,eAAO,MAAM,qBAAqB,EAAE,eA+BnC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
1
2
  const MCP_BOOTSTRAP_CORE = new Set([
2
3
  'doctor',
3
4
  'init',
@@ -123,6 +124,7 @@ export const getCommandCatalogTool = {
123
124
  properties: {
124
125
  safetyLevel: { type: 'string', description: 'Filter by safety level (read-only, writes-session, writes-drafts, writes-source, runs-shell, requires-review).' },
125
126
  category: { type: 'string', description: 'Filter by category.' },
127
+ ...FORMAT_INPUT_PROPERTY,
126
128
  },
127
129
  additionalProperties: false,
128
130
  },
@@ -134,14 +136,16 @@ export const getCommandCatalogTool = {
134
136
  entries = entries.filter((e) => e.safetyLevel === safety);
135
137
  if (typeof category === 'string')
136
138
  entries = entries.filter((e) => e.category === category);
137
- return {
138
- data: {
139
- entries,
140
- totals: {
141
- total: COMMAND_CATALOG_EXPORT.length,
142
- returned: entries.length,
143
- },
139
+ const data = {
140
+ entries,
141
+ totals: {
142
+ total: COMMAND_CATALOG_EXPORT.length,
143
+ returned: entries.length,
144
144
  },
145
145
  };
146
+ // `format:"table"` columnar-encodes the homogeneous `entries` array
147
+ // (the ~11-field catalog rows); the `totals` scalar object is left
148
+ // untouched. Default/`format:"json"` returns the object unchanged.
149
+ return { data: formatObjectArrays(data, input) };
146
150
  },
147
151
  };
@@ -0,0 +1,8 @@
1
+ import type { IToolDefinition } from '../server/tool-definition.js';
2
+ /**
3
+ * Deterministic context compressor exposed to agents — shrink a blob before it
4
+ * re-enters the prompt, with no model in the loop: it's a pure function of the
5
+ * input. Reversible via the CCR store wired into the server context.
6
+ */
7
+ export declare const compressContextTool: IToolDefinition;
8
+ //# sourceMappingURL=compress-context.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compress-context.tool.d.ts","sourceRoot":"","sources":["../../src/tools/compress-context.tool.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIpE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,eA4EjC,CAAC"}
@@ -0,0 +1,80 @@
1
+ import { compressContent, EContentType, } from '@shrkcrft/compress';
2
+ const CONTENT_TYPES = new Set(Object.values(EContentType));
3
+ /**
4
+ * Deterministic context compressor exposed to agents — shrink a blob before it
5
+ * re-enters the prompt, with no model in the loop: it's a pure function of the
6
+ * input. Reversible via the CCR store wired into the server context.
7
+ */
8
+ export const compressContextTool = {
9
+ name: 'compress_context',
10
+ description: 'Deterministically compress a blob (tool output, build/test log, grep/search results, unified diff, or JSON) BEFORE you feed it back to the model — same information, far fewer tokens. Routes by content type, hoists JSON object-array schemas into dense tables, and reduces logs/search/diffs to their highest-signal lines. Reversible: when a lossy pass drops detail it caches the original and emits a `<<ccr:KEY>>` marker — call `retrieve_original` to get the full text back. No AI involved; same bytes in, same bytes out. Read-only.',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {
14
+ content: { type: 'string', description: 'The text to compress.' },
15
+ contentType: {
16
+ type: 'string',
17
+ description: 'Force a content class instead of auto-detecting: json | json-array | git-diff | search-results | build-log | source-code | markdown | plain-text.',
18
+ },
19
+ query: {
20
+ type: 'string',
21
+ description: 'Optional task/query text that biases which lines or matches are kept.',
22
+ },
23
+ maxItems: {
24
+ type: 'number',
25
+ description: 'Soft cap on retained lines / matches / hunks (compressor-specific).',
26
+ },
27
+ maxTokens: {
28
+ type: 'number',
29
+ minimum: 1,
30
+ description: 'Token budget for a JSON array. When set and the lossless columnar form still exceeds it, falls back to the lossy SmartCrusher row-sampler (kept rows + CCR original).',
31
+ },
32
+ },
33
+ required: ['content'],
34
+ additionalProperties: false,
35
+ },
36
+ handler(input, ctx) {
37
+ const content = typeof input.content === 'string' ? input.content : '';
38
+ if (content.length === 0) {
39
+ return {
40
+ isError: true,
41
+ text: 'compress_context requires a non-empty "content" string.',
42
+ error: { code: 'invalid-input', message: 'content is required' },
43
+ };
44
+ }
45
+ const opts = {};
46
+ if (ctx.ccrStore)
47
+ opts.store = ctx.ccrStore;
48
+ if (typeof input.query === 'string')
49
+ opts.query = input.query;
50
+ if (typeof input.maxItems === 'number' && input.maxItems > 0) {
51
+ opts.maxItems = Math.floor(input.maxItems);
52
+ }
53
+ if (typeof input.maxTokens === 'number' && input.maxTokens > 0) {
54
+ opts.maxTokens = Math.floor(input.maxTokens);
55
+ }
56
+ if (typeof input.contentType === 'string' && CONTENT_TYPES.has(input.contentType)) {
57
+ opts.contentType = input.contentType;
58
+ }
59
+ const result = compressContent(content, opts);
60
+ const pct = Math.round(result.savings.ratio * 100);
61
+ return {
62
+ data: {
63
+ contentType: result.contentType,
64
+ strategy: result.strategy,
65
+ lossy: result.lossy,
66
+ tokensBefore: result.savings.before,
67
+ tokensAfter: result.savings.after,
68
+ tokensSaved: result.savings.saved,
69
+ savedRatio: result.savings.ratio,
70
+ ccrKey: result.ccrKey ?? null,
71
+ note: result.note,
72
+ compressed: result.compressed,
73
+ ...(result.ccrKey
74
+ ? { retrieveWith: `retrieve_original { "key": "${result.ccrKey}" }` }
75
+ : {}),
76
+ },
77
+ text: `${result.strategy}: ${result.savings.before} → ${result.savings.after} tokens (−${pct}%)${result.ccrKey ? ` · original cached as ${result.ccrKey}` : ''}`,
78
+ };
79
+ },
80
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-summary.tool.d.ts","sourceRoot":"","sources":["../../src/tools/dashboard-summary.tool.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAUpE,eAAO,MAAM,uBAAuB,EAAE,eA0LrC,CAAC"}
1
+ {"version":3,"file":"dashboard-summary.tool.d.ts","sourceRoot":"","sources":["../../src/tools/dashboard-summary.tool.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAQpE,eAAO,MAAM,uBAAuB,EAAE,eA0LrC,CAAC"}
@@ -1,8 +1,6 @@
1
1
  import { buildAreaMap, buildAiReadinessReport, buildCoverageReport, buildDriftReport, buildQualityReport, buildReleaseReadiness, buildSafetyAudit, evaluatePolicy, listConstructs, listDevSessionsDetailed, listFeatureBundles, listPlaybooks, } from '@shrkcrft/inspector';
2
2
  import { existsSync, readFileSync, statSync } from 'node:fs';
3
3
  import * as nodePath from 'node:path';
4
- // DX#4 — derive audit view from ALL_TOOLS at runtime.
5
- import { ALL_TOOLS } from "./all-tools.js";
6
4
  export const getDashboardSummaryTool = {
7
5
  name: 'get_dashboard_summary',
8
6
  description: 'Compact dashboard summary aggregating quality, safety, readiness, coverage, drift, packs, sessions, bundles, command-safety totals, and recommended next commands. Read-only.',
@@ -75,7 +73,7 @@ export const getDashboardSummaryTool = {
75
73
  const safety = buildSafetyAudit({
76
74
  inspection,
77
75
  catalog: [],
78
- mcpTools: ALL_TOOLS.map((t) => ({ name: t.name, description: t.description })),
76
+ mcpTools: (ctx.allTools ?? []).map((t) => ({ name: t.name, description: t.description })),
79
77
  planSecretEnv: 'SHARKCRAFT_PLAN_SECRET',
80
78
  planSecretConfigured: typeof process.env['SHARKCRAFT_PLAN_SECRET'] === 'string' &&
81
79
  process.env['SHARKCRAFT_PLAN_SECRET'].length > 0,
@@ -155,7 +153,7 @@ export const getDashboardSummaryTool = {
155
153
  invalid: inspection.packs.invalidPacks?.length ?? 0,
156
154
  },
157
155
  policy: policySummary,
158
- mcpTools: { total: ALL_TOOLS.length, anyWritable: safety.mcp.anyWritable },
156
+ mcpTools: { total: ctx.allTools?.length ?? 0, anyWritable: safety.mcp.anyWritable },
159
157
  reportSite: { available: siteAvailable, dir: reportSiteDir },
160
158
  releaseReadiness: releaseReadinessSummary,
161
159
  releaseSmoke: smokeSummary,
@@ -1 +1 @@
1
- {"version":3,"file":"deps-audit.tool.d.ts","sourceRoot":"","sources":["../../src/tools/deps-audit.tool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,eAoC3B,CAAC"}
1
+ {"version":3,"file":"deps-audit.tool.d.ts","sourceRoot":"","sources":["../../src/tools/deps-audit.tool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIpE;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,eAkE3B,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
2
2
  import * as nodePath from 'node:path';
3
3
  import { GraphQueryApi, GraphStore, NodeKind } from '@shrkcrft/graph';
4
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays, COLUMNAR_LEGEND } from "../server/columnar-format.js";
5
+ import { fitArrayToBudget } from "../server/fit-array-to-budget.js";
4
6
  /**
5
7
  * `deps_audit` — MCP wrapper around `shrk deps-audit`. Pure read-only.
6
8
  * Returns the same shape the CLI's `--json` mode emits.
@@ -10,11 +12,17 @@ import { GraphQueryApi, GraphStore, NodeKind } from '@shrkcrft/graph';
10
12
  */
11
13
  export const depsAuditTool = {
12
14
  name: 'deps_audit',
13
- description: 'Per-package audit of declared dependencies (package.json) vs actually-imported specifiers (graph). Reports missing + unused deps. Read-only.',
15
+ description: 'Per-package audit of declared dependencies (package.json) vs actually-imported specifiers (graph). Reports missing + unused deps. Pass `format:"table"` for a token-efficient columnar encoding of the per-package report list. Read-only.',
14
16
  inputSchema: {
15
17
  type: 'object',
16
18
  properties: {
17
19
  package: { type: 'string' },
20
+ ...FORMAT_INPUT_PROPERTY,
21
+ maxTokens: {
22
+ type: 'number',
23
+ minimum: 1,
24
+ description: 'Token budget for the per-package report list. When set and the columnar form still exceeds it, falls back to the lossy SmartCrusher row-sampler (full original cached — retrieve via the returned ccrKey).',
25
+ },
18
26
  },
19
27
  additionalProperties: false,
20
28
  },
@@ -38,7 +46,29 @@ export const depsAuditTool = {
38
46
  acc.unused += r.unusedDeps.length;
39
47
  return acc;
40
48
  }, { missing: 0, unused: 0 });
41
- return { data: { totals, packages: reports } };
49
+ // P5.2: an explicit token budget routes the per-package report list through
50
+ // the SmartCrusher row-sampler (lossy, CCR-recoverable) when even the
51
+ // columnar form is over budget.
52
+ const maxTokens = typeof input.maxTokens === 'number' && input.maxTokens > 0 ? Math.floor(input.maxTokens) : undefined;
53
+ if (maxTokens) {
54
+ const fitted = fitArrayToBudget(reports, maxTokens, ctx.ccrStore);
55
+ return {
56
+ data: {
57
+ _format: 'table',
58
+ _legend: COLUMNAR_LEGEND,
59
+ totals,
60
+ packages: fitted.value,
61
+ ...(fitted.ccrKey
62
+ ? { ccrKey: fitted.ccrKey, retrieveWith: `retrieve_original { "key": "${fitted.ccrKey}" }` }
63
+ : {}),
64
+ },
65
+ };
66
+ }
67
+ // `format:"table"` columnar-encodes the homogeneous `packages` report
68
+ // list; the `totals` scalar object is left untouched. The per-package
69
+ // string arrays (importedSpecifiers/missingDeps/unusedDeps) ride along
70
+ // inside each compacted row and reconstruct losslessly.
71
+ return { data: formatObjectArrays({ totals, packages: reports }, input) };
42
72
  },
43
73
  };
44
74
  function listWorkspacePackages(cwd, onlyName) {
@@ -1 +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"}
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;AAUpE;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,EAAE,eAiC1C,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { buildCodeIntelligenceChecks, DoctorSeverity, } from '@shrkcrft/inspector';
2
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
2
3
  /**
3
4
  * Read-only MCP mirror of `shrk code-intel`. Returns the same 14
4
5
  * code-intelligence doctor findings in one shot — agents can pull
@@ -16,6 +17,7 @@ export const getCodeIntelligenceStateTool = {
16
17
  properties: {
17
18
  only: { type: 'array', items: { type: 'string' } },
18
19
  checkId: { type: 'string' },
20
+ ...FORMAT_INPUT_PROPERTY,
19
21
  },
20
22
  additionalProperties: false,
21
23
  },
@@ -30,14 +32,13 @@ export const getCodeIntelligenceStateTool = {
30
32
  checks = checks.filter((c) => allowed.has(c.severity));
31
33
  }
32
34
  const summary = summarize(checks);
33
- return {
34
- data: {
35
- schema: 'sharkcraft.code-intelligence-state/v1',
36
- totalChecks: checks.length,
37
- summary,
38
- checks,
39
- },
35
+ const data = {
36
+ schema: 'sharkcraft.code-intelligence-state/v1',
37
+ totalChecks: checks.length,
38
+ summary,
39
+ checks,
40
40
  };
41
+ return { data: formatObjectArrays(data, input) };
41
42
  },
42
43
  };
43
44
  function summarize(checks) {
@@ -1 +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"}
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;AAUpE,eAAO,MAAM,mBAAmB,EAAE,eA0DjC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { GraphQueryApi, GraphStore } from '@shrkcrft/graph';
2
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
2
3
  const NEXT = 'shrk graph index';
3
4
  export const getGraphCallersTool = {
4
5
  name: 'get_graph_callers',
@@ -9,6 +10,7 @@ export const getGraphCallersTool = {
9
10
  properties: {
10
11
  symbol: { type: 'string' },
11
12
  mode: { type: 'string', enum: ['call', 'reference'] },
13
+ ...FORMAT_INPUT_PROPERTY,
12
14
  },
13
15
  required: ['symbol'],
14
16
  additionalProperties: false,
@@ -47,15 +49,14 @@ export const getGraphCallersTool = {
47
49
  };
48
50
  }
49
51
  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
- },
52
+ const data = {
53
+ schema: 'sharkcraft.graph-callers/v1',
54
+ symbol: summarise(sym),
55
+ mode,
56
+ total: hits.length,
57
+ callers: hits.slice(0, 200).map(summarise),
58
58
  };
59
+ return { data: formatObjectArrays(data, input) };
59
60
  },
60
61
  };
61
62
  function resolveSymbol(api, target) {
@@ -1 +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"}
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;AASpE,eAAO,MAAM,mBAAmB,EAAE,eAgEjC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { GraphQueryApi, GraphStore, NodeKind, } from '@shrkcrft/graph';
2
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
2
3
  const NEXT = 'shrk graph index';
3
4
  export const getGraphContextTool = {
4
5
  name: 'get_graph_context',
@@ -6,7 +7,7 @@ export const getGraphContextTool = {
6
7
  cliCommand: 'graph context',
7
8
  inputSchema: {
8
9
  type: 'object',
9
- properties: { target: { type: 'string' } },
10
+ properties: { target: { type: 'string' }, ...FORMAT_INPUT_PROPERTY },
10
11
  required: ['target'],
11
12
  additionalProperties: false,
12
13
  },
@@ -44,25 +45,24 @@ export const getGraphContextTool = {
44
45
  }
45
46
  const neighbours = api.neighbours(anchor.id);
46
47
  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
- },
48
+ const 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),
65
64
  };
65
+ return { data: formatObjectArrays(data, input) };
66
66
  },
67
67
  };
68
68
  function resolveAnchor(api, target) {
@@ -1 +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"}
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;AAYpE;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAmDhC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { GraphQueryApi, GraphStore } from '@shrkcrft/graph';
2
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
2
3
  const NEXT = 'shrk graph index';
3
4
  /**
4
5
  * Read-only MCP mirror of `shrk graph cycles`. Returns the full SCC
@@ -16,6 +17,7 @@ export const getGraphCyclesTool = {
16
17
  properties: {
17
18
  limit: { type: 'number' },
18
19
  minSize: { type: 'number' },
20
+ ...FORMAT_INPUT_PROPERTY,
19
21
  },
20
22
  additionalProperties: false,
21
23
  },
@@ -42,16 +44,15 @@ export const getGraphCyclesTool = {
42
44
  const all = api.cycles();
43
45
  const filtered = all.filter((c) => c.size >= minSize);
44
46
  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
- },
47
+ const data = {
48
+ schema: 'sharkcraft.graph-cycles/v1',
49
+ total: filtered.length,
50
+ truncated: filtered.length > rawLimit,
51
+ cycles: limited.map((c) => ({
52
+ size: c.size,
53
+ paths: c.paths ?? c.nodeIds.map((id) => id.replace(/^file:/, '')),
54
+ })),
55
55
  };
56
+ return { data: formatObjectArrays(data, input) };
56
57
  },
57
58
  };
@@ -1 +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"}
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;AAWpE,eAAO,MAAM,0BAA0B,EAAE,eAoCxC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { analyzeGraphImpact } from '@shrkcrft/impact-engine';
2
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
2
3
  export const getGraphImpactAnalysisTool = {
3
4
  name: 'get_graph_impact_analysis',
4
5
  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.',
@@ -11,6 +12,7 @@ export const getGraphImpactAnalysisTool = {
11
12
  gitref: { type: 'string' },
12
13
  maxDepth: { type: 'number' },
13
14
  limit: { type: 'number' },
15
+ ...FORMAT_INPUT_PROPERTY,
14
16
  },
15
17
  additionalProperties: false,
16
18
  },
@@ -34,7 +36,7 @@ export const getGraphImpactAnalysisTool = {
34
36
  limit: clamp(args.limit ?? 200, 1, 2000),
35
37
  maxDepth: clamp(args.maxDepth ?? 5, 1, 10),
36
38
  });
37
- return { data: analysis };
39
+ return { data: formatObjectArrays(analysis, input) };
38
40
  },
39
41
  };
40
42
  function clamp(n, lo, hi) {
@@ -1 +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"}
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;AAWpE,eAAO,MAAM,kBAAkB,EAAE,eAmEhC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { GraphQueryApi, GraphStore } from '@shrkcrft/graph';
2
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
2
3
  const NEXT = 'shrk graph index';
3
4
  export const getGraphImpactTool = {
4
5
  name: 'get_graph_impact',
@@ -10,6 +11,7 @@ export const getGraphImpactTool = {
10
11
  target: { type: 'string' },
11
12
  maxDepth: { type: 'number' },
12
13
  limit: { type: 'number' },
14
+ ...FORMAT_INPUT_PROPERTY,
13
15
  },
14
16
  required: ['target'],
15
17
  additionalProperties: false,
@@ -51,20 +53,19 @@ export const getGraphImpactTool = {
51
53
  const closure = reverseClosure(api, anchor.id, maxDepth, limit);
52
54
  const direct = closure.layer[1] ?? [];
53
55
  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
- },
56
+ const data = {
57
+ schema: 'sharkcraft.graph-impact/v1',
58
+ anchor: summarise(anchor),
59
+ maxDepth,
60
+ limit,
61
+ truncated: closure.truncated,
62
+ directDependents: direct.map((id) => summarise(api.neighbours(id).node)),
63
+ transitiveDependents: transitive
64
+ .slice(0, limit)
65
+ .map((id) => summarise(api.neighbours(id).node)),
66
+ totalReached: closure.all.length - 1,
67
67
  };
68
+ return { data: formatObjectArrays(data, input) };
68
69
  },
69
70
  };
70
71
  function resolveAnchor(api, target) {
@@ -1 +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"}
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;AAYpE,eAAO,MAAM,kBAAkB,EAAE,eA6DhC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { GraphQueryApi, GraphStore } from '@shrkcrft/graph';
2
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
2
3
  const NEXT = 'shrk graph index';
3
4
  export const getGraphSearchTool = {
4
5
  name: 'get_graph_search',
@@ -11,6 +12,7 @@ export const getGraphSearchTool = {
11
12
  kind: { type: 'string', enum: ['file', 'symbol', 'package'] },
12
13
  limit: { type: 'number' },
13
14
  exact: { type: 'boolean' },
15
+ ...FORMAT_INPUT_PROPERTY,
14
16
  },
15
17
  required: ['query'],
16
18
  additionalProperties: false,
@@ -53,15 +55,14 @@ export const getGraphSearchTool = {
53
55
  if (p)
54
56
  matches.push(p.node);
55
57
  }
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
- },
58
+ const data = {
59
+ schema: 'sharkcraft.graph-search/v1',
60
+ query,
61
+ kind: args.kind ?? 'any',
62
+ total: Math.min(matches.length, limit),
63
+ matches: matches.slice(0, limit).map(summarise),
64
64
  };
65
+ return { data: formatObjectArrays(data, input) };
65
66
  },
66
67
  };
67
68
  function summarise(n) {
@@ -1 +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"}
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;AAUpE;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAyEpC,CAAC"}