@shrkcrft/mcp-server 0.1.0-alpha.15 → 0.1.0-alpha.17

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 (103) 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 +24 -0
  11. package/dist/server/fit-array-to-budget.d.ts.map +1 -0
  12. package/dist/server/fit-array-to-budget.js +60 -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 +81 -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 +36 -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
  95. package/dist/tools/r22-extras.tool.d.ts +0 -4
  96. package/dist/tools/r22-extras.tool.d.ts.map +0 -1
  97. package/dist/tools/r22-extras.tool.js +0 -42
  98. package/dist/tools/r26-ingest.tool.d.ts +0 -10
  99. package/dist/tools/r26-ingest.tool.d.ts.map +0 -1
  100. package/dist/tools/r26-ingest.tool.js +0 -174
  101. package/dist/tools/r34-search-unified.tool.d.ts +0 -3
  102. package/dist/tools/r34-search-unified.tool.d.ts.map +0 -1
  103. package/dist/tools/r34-search-unified.tool.js +0 -38
@@ -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"}
@@ -1,4 +1,5 @@
1
1
  import { EdgeKind, 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 unresolved`. Returns every
@@ -10,12 +11,13 @@ const NEXT = 'shrk graph index';
10
11
  */
11
12
  export const getGraphUnresolvedTool = {
12
13
  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
+ description: 'List every unresolved import in the code graph, grouped by source file. Sorted by unresolved-count desc. Pass `format:"table"` for a token-efficient columnar encoding of the file list. Read-only.',
14
15
  cliCommand: 'graph unresolved',
15
16
  inputSchema: {
16
17
  type: 'object',
17
18
  properties: {
18
19
  limit: { type: 'number' },
20
+ ...FORMAT_INPUT_PROPERTY,
19
21
  },
20
22
  additionalProperties: false,
21
23
  },
@@ -68,14 +70,16 @@ export const getGraphUnresolvedTool = {
68
70
  return a.path.localeCompare(b.path);
69
71
  });
70
72
  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
- },
73
+ const data = {
74
+ schema: 'sharkcraft.graph-unresolved/v1',
75
+ totalEdges,
76
+ totalFiles: list.length,
77
+ truncated: list.length > limit,
78
+ files: list.slice(0, limit),
79
79
  };
80
+ // `format:"table"` columnar-encodes the top-level `files` array (one row per
81
+ // source file); scalars (schema/totalEdges/…) and each row's inner
82
+ // `unresolved` string array are left untouched by the helper.
83
+ return { data: formatObjectArrays(data, input) };
80
84
  },
81
85
  };
@@ -1,3 +1,10 @@
1
1
  import type { IToolDefinition } from '../server/tool-definition.js';
2
+ /**
3
+ * The knowledge graph is the largest single payload shrk emits — hundreds of
4
+ * homogeneous node/edge objects. `format:"table"` returns the same data in
5
+ * columnar form (schema hoisted once, keys deduped) which is still valid JSON
6
+ * but a fraction of the tokens. `format:"json"` (default) keeps the explicit
7
+ * node/edge arrays for back-compat.
8
+ */
2
9
  export declare const getKnowledgeGraphTool: IToolDefinition;
3
10
  //# sourceMappingURL=get-knowledge-graph.tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-knowledge-graph.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-knowledge-graph.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,qBAAqB,EAAE,eASnC,CAAC"}
1
+ {"version":3,"file":"get-knowledge-graph.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-knowledge-graph.tool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIpE;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,eA8DnC,CAAC"}
@@ -1,10 +1,69 @@
1
1
  import { buildKnowledgeGraph } from '@shrkcrft/inspector';
2
+ import { compactArrayToColumnar, estimateTokens } from '@shrkcrft/compress';
3
+ import { wantsTable } from "../server/columnar-format.js";
4
+ import { fitArrayToBudget } from "../server/fit-array-to-budget.js";
5
+ /**
6
+ * The knowledge graph is the largest single payload shrk emits — hundreds of
7
+ * homogeneous node/edge objects. `format:"table"` returns the same data in
8
+ * columnar form (schema hoisted once, keys deduped) which is still valid JSON
9
+ * but a fraction of the tokens. `format:"json"` (default) keeps the explicit
10
+ * node/edge arrays for back-compat.
11
+ */
2
12
  export const getKnowledgeGraphTool = {
3
13
  name: 'get_knowledge_graph',
4
- description: 'Return the full SharkCraft knowledge graph: nodes (knowledge/rules/paths/templates/pipelines/presets/packs/boundaries) and edges (related-template, preset-references, pipeline-step-references, …). Read-only.',
5
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
6
- async handler(_input, ctx) {
14
+ description: 'Return the full SharkCraft knowledge graph: nodes (knowledge/rules/paths/templates/pipelines/presets/packs/boundaries) and edges (related-template, preset-references, pipeline-step-references, …). Pass `format:"table"` for a token-efficient columnar encoding (still valid JSON) — recommended for large graphs. Read-only.',
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {
18
+ format: {
19
+ type: 'string',
20
+ enum: ['json', 'table'],
21
+ description: 'json (default): explicit node/edge object arrays. table: columnar encoding (schema hoisted, keys deduped) — fewer tokens for large graphs.',
22
+ },
23
+ maxTokens: {
24
+ type: 'integer',
25
+ minimum: 1,
26
+ description: 'Token budget for the table. When set and the lossless columnar form still exceeds it, falls back to the lossy SmartCrusher row-sampler (representative rows kept; full original cached — retrieve via the returned ccrKey).',
27
+ },
28
+ },
29
+ additionalProperties: false,
30
+ },
31
+ async handler(input, ctx) {
7
32
  const graph = buildKnowledgeGraph(ctx.inspection);
33
+ const asTable = wantsTable(input);
34
+ const maxTokens = typeof input.maxTokens === 'number' && input.maxTokens > 0 ? Math.floor(input.maxTokens) : undefined;
35
+ const nodesTable = asTable ? compactArrayToColumnar(graph.nodes) : null;
36
+ const edgesTable = asTable ? compactArrayToColumnar(graph.edges) : null;
37
+ // Only advertise `table` when at least one array actually compacted — a tiny
38
+ // graph (e.g. edges:[]) stays the plain JSON form rather than a mislabelled
39
+ // "table" whose fields are bare arrays.
40
+ if (nodesTable || edgesTable) {
41
+ // P5.2: with no budget, keep the lossless columnar form (unchanged). With
42
+ // a budget, fit each array — sampling + CCR when it's still over.
43
+ const nodes = maxTokens
44
+ ? fitArrayToBudget(graph.nodes, maxTokens, ctx.ccrStore)
45
+ : { value: nodesTable ?? graph.nodes };
46
+ const edges = maxTokens
47
+ ? fitArrayToBudget(graph.edges, maxTokens, ctx.ccrStore)
48
+ : { value: edgesTable ?? graph.edges };
49
+ const ccrKeys = [nodes.ccrKey, edges.ccrKey].filter((k) => Boolean(k));
50
+ const before = estimateTokens(JSON.stringify({ nodes: graph.nodes, edges: graph.edges }));
51
+ const after = estimateTokens(JSON.stringify({ nodes: nodes.value, edges: edges.value }));
52
+ return {
53
+ data: {
54
+ format: 'table',
55
+ legend: 'Columnar tables: _table.cols are column names; each _table.rows[i] is one record aligned to cols; _table.absent lists [row,col] positions whose key was absent. Reconstruct objects by zipping cols with each row, skipping absent positions. If a column appears in _table.dict, its row cells are integer indices into dict[<col>] (deref to the real value). A field may be a plain array when it was too small to compact. A _table.sample block means rows were dropped to fit a budget — retrieve the full original via ccrKey.',
56
+ nodes: nodes.value,
57
+ edges: edges.value,
58
+ tokenEstimate: { before, after, saved: Math.max(0, before - after) },
59
+ ...(ccrKeys.length > 0
60
+ ? { ccrKeys, retrieveWith: `retrieve_original { "key": "${ccrKeys[0]}" }` }
61
+ : {}),
62
+ },
63
+ };
64
+ }
65
+ // Default (and tiny-graph) path: the original bare `{ nodes, edges }` shape,
66
+ // byte-identical to pre-compression clients (no extra `format` key).
8
67
  return { data: { nodes: graph.nodes, edges: graph.edges } };
9
68
  },
10
69
  };
@@ -1 +1 @@
1
- {"version":3,"file":"get-relevant-context.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-relevant-context.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIpE,eAAO,MAAM,sBAAsB,EAAE,eAqDpC,CAAC"}
1
+ {"version":3,"file":"get-relevant-context.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-relevant-context.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAKpE,eAAO,MAAM,sBAAsB,EAAE,eA6EpC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { buildContext } from '@shrkcrft/context';
2
2
  import { buildProjectOverview, renderOverviewText } from '@shrkcrft/inspector';
3
+ import { compressMarkdown } from '@shrkcrft/compress';
3
4
  export const getRelevantContextTool = {
4
5
  name: 'get_relevant_context',
5
6
  description: 'Build a token-budgeted, AI-ready context for a task — relevant rules/paths/templates/etc. **Prefer `prepare_agent_task` for first task grounding** (it returns this plus action hints + safety + next-command). Use this when you only need the context body. Read-only.',
@@ -17,6 +18,10 @@ export const getRelevantContextTool = {
17
18
  includeRules: { type: 'boolean' },
18
19
  includePaths: { type: 'boolean' },
19
20
  includeDocs: { type: 'boolean' },
21
+ compact: {
22
+ type: 'boolean',
23
+ description: 'When true, the markdown body is run through the deterministic markdown compressor (headers/leads/structure kept, prose thinned). Reversible: the original is cached and a `<<ccr:KEY>>` marker emitted — call retrieve_original to get it back.',
24
+ },
20
25
  },
21
26
  required: ['task'],
22
27
  additionalProperties: false,
@@ -37,18 +42,37 @@ export const getRelevantContextTool = {
37
42
  includeDocs: input.includeDocs,
38
43
  projectOverview: renderOverviewText(overview),
39
44
  });
45
+ const sections = result.sections.map((s) => ({
46
+ title: s.title,
47
+ tokens: s.tokens,
48
+ truncated: s.truncated ?? false,
49
+ entryIds: s.entryIds,
50
+ }));
51
+ if (input.compact === true) {
52
+ const c = compressMarkdown(result.body, ctx.ccrStore ? { store: ctx.ccrStore } : {});
53
+ return {
54
+ text: c.compressed,
55
+ data: {
56
+ totalTokens: result.totalTokens,
57
+ maxTokens: result.maxTokens,
58
+ omittedSections: result.omittedSections,
59
+ sections,
60
+ compaction: {
61
+ strategy: c.strategy,
62
+ tokensBefore: c.savings.before,
63
+ tokensAfter: c.savings.after,
64
+ ccrKey: c.ccrKey ?? null,
65
+ },
66
+ },
67
+ };
68
+ }
40
69
  return {
41
70
  text: result.body,
42
71
  data: {
43
72
  totalTokens: result.totalTokens,
44
73
  maxTokens: result.maxTokens,
45
74
  omittedSections: result.omittedSections,
46
- sections: result.sections.map((s) => ({
47
- title: s.title,
48
- tokens: s.tokens,
49
- truncated: s.truncated ?? false,
50
- entryIds: s.entryIds,
51
- })),
75
+ sections,
52
76
  },
53
77
  };
54
78
  },
@@ -1 +1 @@
1
- {"version":3,"file":"get-task-packet.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-task-packet.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,iBAAiB,EAAE,eA8C/B,CAAC"}
1
+ {"version":3,"file":"get-task-packet.tool.d.ts","sourceRoot":"","sources":["../../src/tools/get-task-packet.tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,eAAO,MAAM,iBAAiB,EAAE,eAiD/B,CAAC"}
@@ -1,13 +1,15 @@
1
1
  import { buildTaskPacket } from '@shrkcrft/inspector';
2
+ import { FORMAT_INPUT_PROPERTY, formatObjectArrays } from "../server/columnar-format.js";
2
3
  export const getTaskPacketTool = {
3
4
  name: 'get_task_packet',
4
- description: 'Full machine task packet (project overview, detected profiles, recommended pipelines, relevant rules/paths/templates, action hints, recommended CLI/MCP, forbidden actions, verification commands, human-review checkpoints, token-budgeted context body). **Prefer `prepare_agent_task` for first task grounding** — it returns the curated agent bundle plus next-safe-action. Read-only.',
5
+ description: 'Full machine task packet (project overview, detected profiles, recommended pipelines, relevant rules/paths/templates, action hints, recommended CLI/MCP, forbidden actions, verification commands, human-review checkpoints, token-budgeted context body). Pass `format:"table"` for a token-efficient columnar encoding of the structured lists. **Prefer `prepare_agent_task` for first task grounding** — it returns the curated agent bundle plus next-safe-action. Read-only.',
5
6
  inputSchema: {
6
7
  type: 'object',
7
8
  properties: {
8
9
  task: { type: 'string' },
9
10
  maxTokens: { type: 'number', minimum: 100, maximum: 20000 },
10
11
  scope: { type: 'array', items: { type: 'string' } },
12
+ ...FORMAT_INPUT_PROPERTY,
11
13
  },
12
14
  required: ['task'],
13
15
  additionalProperties: false,
@@ -22,27 +24,29 @@ export const getTaskPacketTool = {
22
24
  maxTokens,
23
25
  ...(scope ? { scope } : {}),
24
26
  });
25
- return {
26
- data: {
27
- task: packet.task,
28
- detectedProfiles: packet.detectedProfiles,
29
- recommendedPipelines: packet.recommendedPipelines,
30
- presetRecommendations: packet.presetRecommendations.map((r) => ({
31
- presetId: r.preset.id,
32
- confidence: r.confidence,
33
- score: r.score,
34
- })),
35
- relevantRules: packet.relevantRules.map((r) => ({ id: r.id, title: r.title })),
36
- relevantPaths: packet.relevantPaths.map((p) => ({ id: p.id, title: p.title })),
37
- relevantTemplates: packet.relevantTemplates.map((t) => ({ id: t.id, name: t.name })),
38
- recommendedMcpTools: packet.recommendedMcpTools,
39
- recommendedCliCommands: packet.recommendedCliCommands,
40
- forbiddenActions: packet.forbiddenActions,
41
- verificationCommands: packet.verificationCommands,
42
- humanReviewPoints: packet.humanReviewPoints,
43
- tokenEstimate: packet.tokenEstimate,
44
- context: packet.context,
45
- },
27
+ const data = {
28
+ task: packet.task,
29
+ detectedProfiles: packet.detectedProfiles,
30
+ recommendedPipelines: packet.recommendedPipelines,
31
+ presetRecommendations: packet.presetRecommendations.map((r) => ({
32
+ presetId: r.preset.id,
33
+ confidence: r.confidence,
34
+ score: r.score,
35
+ })),
36
+ relevantRules: packet.relevantRules.map((r) => ({ id: r.id, title: r.title })),
37
+ relevantPaths: packet.relevantPaths.map((p) => ({ id: p.id, title: p.title })),
38
+ relevantTemplates: packet.relevantTemplates.map((t) => ({ id: t.id, name: t.name })),
39
+ recommendedMcpTools: packet.recommendedMcpTools,
40
+ recommendedCliCommands: packet.recommendedCliCommands,
41
+ forbiddenActions: packet.forbiddenActions,
42
+ verificationCommands: packet.verificationCommands,
43
+ humanReviewPoints: packet.humanReviewPoints,
44
+ tokenEstimate: packet.tokenEstimate,
45
+ context: packet.context,
46
46
  };
47
+ // `format:"table"` columnar-encodes the structured object-array fields
48
+ // (relevantRules/Paths/Templates, presetRecommendations, …); scalars,
49
+ // string arrays, and the markdown context body are left untouched.
50
+ return { data: formatObjectArrays(data, input) };
47
51
  },
48
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"list-boundary-rules.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-boundary-rules.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,qBAAqB,EAAE,eAoBnC,CAAC"}
1
+ {"version":3,"file":"list-boundary-rules.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-boundary-rules.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,eAAO,MAAM,qBAAqB,EAAE,eAuBnC,CAAC"}
@@ -1,20 +1,24 @@
1
+ import { FORMAT_INPUT_PROPERTY, formatRows } from "../server/columnar-format.js";
1
2
  export const listBoundaryRulesTool = {
2
3
  name: 'list_boundary_rules',
3
- description: 'List every configured boundary rule (local + pack-contributed). Returns id, title, severity, from/forbidden patterns, source.',
4
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
5
- async handler(_input, ctx) {
6
- return {
7
- data: ctx.inspection.boundaryRegistry.list().map((r) => ({
8
- id: r.id,
9
- title: r.title,
10
- description: r.description,
11
- severity: r.severity ?? 'error',
12
- from: r.from,
13
- forbiddenImports: r.forbiddenImports ?? [],
14
- allowedImports: r.allowedImports ?? [],
15
- tags: r.tags ?? [],
16
- source: ctx.inspection.boundarySources.get(r.id) ?? null,
17
- })),
18
- };
4
+ description: 'List every configured boundary rule (local + pack-contributed). Returns id, title, severity, from/forbidden patterns, source. Pass `format:"table"` for a token-efficient columnar payload.',
5
+ inputSchema: {
6
+ type: 'object',
7
+ properties: { ...FORMAT_INPUT_PROPERTY },
8
+ additionalProperties: false,
9
+ },
10
+ async handler(input, ctx) {
11
+ const rows = ctx.inspection.boundaryRegistry.list().map((r) => ({
12
+ id: r.id,
13
+ title: r.title,
14
+ description: r.description,
15
+ severity: r.severity ?? 'error',
16
+ from: r.from,
17
+ forbiddenImports: r.forbiddenImports ?? [],
18
+ allowedImports: r.allowedImports ?? [],
19
+ tags: r.tags ?? [],
20
+ source: ctx.inspection.boundarySources.get(r.id) ?? null,
21
+ }));
22
+ return { data: formatRows(rows, input) };
19
23
  },
20
24
  };
@@ -1 +1 @@
1
- {"version":3,"file":"list-knowledge.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-knowledge.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,iBAAiB,EAAE,eA8C/B,CAAC"}
1
+ {"version":3,"file":"list-knowledge.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-knowledge.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,eAAO,MAAM,iBAAiB,EAAE,eA8C/B,CAAC"}
@@ -1,6 +1,7 @@
1
+ import { FORMAT_INPUT_PROPERTY, formatRows } from "../server/columnar-format.js";
1
2
  export const listKnowledgeTool = {
2
3
  name: 'list_knowledge',
3
- description: 'Lists available knowledge entries (id, title, type, tags, scope, priority, appliesWhen). Filterable.',
4
+ description: 'Lists available knowledge entries (id, title, type, tags, scope, priority, appliesWhen). Filterable. Pass `format:"table"` for a token-efficient columnar payload.',
4
5
  inputSchema: {
5
6
  type: 'object',
6
7
  properties: {
@@ -10,6 +11,7 @@ export const listKnowledgeTool = {
10
11
  tags: { type: 'array', items: { type: 'string' } },
11
12
  appliesWhen: { type: 'array', items: { type: 'string' } },
12
13
  limit: { type: 'integer', minimum: 1 },
14
+ ...FORMAT_INPUT_PROPERTY,
13
15
  },
14
16
  additionalProperties: false,
15
17
  },
@@ -30,17 +32,16 @@ export const listKnowledgeTool = {
30
32
  entries = entries.filter((e) => appliesWhen.some((a) => e.appliesWhen.includes(a)));
31
33
  }
32
34
  entries = entries.slice(0, limit);
33
- return {
34
- data: entries.map((e) => ({
35
- id: e.id,
36
- title: e.title,
37
- type: e.type,
38
- priority: e.priority,
39
- scope: e.scope,
40
- tags: e.tags,
41
- appliesWhen: e.appliesWhen,
42
- summary: e.summary,
43
- })),
44
- };
35
+ const rows = entries.map((e) => ({
36
+ id: e.id,
37
+ title: e.title,
38
+ type: e.type,
39
+ priority: e.priority,
40
+ scope: e.scope,
41
+ tags: e.tags,
42
+ appliesWhen: e.appliesWhen,
43
+ summary: e.summary,
44
+ }));
45
+ return { data: formatRows(rows, input) };
45
46
  },
46
47
  };
@@ -1 +1 @@
1
- {"version":3,"file":"list-packs.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-packs.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,aAAa,EAAE,eAmB3B,CAAC"}
1
+ {"version":3,"file":"list-packs.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-packs.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,eAAO,MAAM,aAAa,EAAE,eAsB3B,CAAC"}
@@ -1,19 +1,23 @@
1
+ import { FORMAT_INPUT_PROPERTY, formatRows } from "../server/columnar-format.js";
1
2
  export const listPacksTool = {
2
3
  name: 'list_packs',
3
- description: 'List discovered SharkCraft packs (third-party npm packages that ship knowledge / templates / pipelines). Each entry includes both declared file counts and resolved object counts after dedup.',
4
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
5
- async handler(_input, ctx) {
6
- return {
7
- data: ctx.inspection.packs.discoveredPacks.map((p) => ({
8
- packageName: p.packageName,
9
- packageVersion: p.packageVersion,
10
- valid: p.valid,
11
- contributionCounts: p.contributionCounts,
12
- resolvedCounts: p.resolvedCounts,
13
- signatureStatus: p.signatureStatus,
14
- signatureMessage: p.signatureMessage,
15
- loadError: p.loadError,
16
- })),
17
- };
4
+ description: 'List discovered SharkCraft packs (third-party npm packages that ship knowledge / templates / pipelines). Each entry includes both declared file counts and resolved object counts after dedup. Pass `format:"table"` for a token-efficient columnar payload.',
5
+ inputSchema: {
6
+ type: 'object',
7
+ properties: { ...FORMAT_INPUT_PROPERTY },
8
+ additionalProperties: false,
9
+ },
10
+ async handler(input, ctx) {
11
+ const rows = ctx.inspection.packs.discoveredPacks.map((p) => ({
12
+ packageName: p.packageName,
13
+ packageVersion: p.packageVersion,
14
+ valid: p.valid,
15
+ contributionCounts: p.contributionCounts,
16
+ resolvedCounts: p.resolvedCounts,
17
+ signatureStatus: p.signatureStatus,
18
+ signatureMessage: p.signatureMessage,
19
+ loadError: p.loadError,
20
+ }));
21
+ return { data: formatRows(rows, input) };
18
22
  },
19
23
  };
@@ -1 +1 @@
1
- {"version":3,"file":"list-path-conventions.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-path-conventions.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,uBAAuB,EAAE,eAmBrC,CAAC"}
1
+ {"version":3,"file":"list-path-conventions.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-path-conventions.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,eAAO,MAAM,uBAAuB,EAAE,eAsBrC,CAAC"}
@@ -1,20 +1,24 @@
1
+ import { FORMAT_INPUT_PROPERTY, formatRows } from "../server/columnar-format.js";
1
2
  export const listPathConventionsTool = {
2
3
  name: 'list_path_conventions',
3
- description: 'List known path conventions.',
4
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
5
- async handler(_input, ctx) {
4
+ description: 'List known path conventions. Pass `format:"table"` for a token-efficient columnar payload.',
5
+ inputSchema: {
6
+ type: 'object',
7
+ properties: { ...FORMAT_INPUT_PROPERTY },
8
+ additionalProperties: false,
9
+ },
10
+ async handler(input, ctx) {
6
11
  const paths = ctx.inspection.pathService.list();
7
- return {
8
- data: paths.map((p) => ({
9
- id: p.id,
10
- title: p.title,
11
- path: p.metadata?.path ?? '',
12
- priority: p.priority,
13
- tags: p.tags,
14
- scope: p.scope,
15
- appliesWhen: p.appliesWhen,
16
- description: p.metadata?.description ?? p.summary,
17
- })),
18
- };
12
+ const rows = paths.map((p) => ({
13
+ id: p.id,
14
+ title: p.title,
15
+ path: p.metadata?.path ?? '',
16
+ priority: p.priority,
17
+ tags: p.tags,
18
+ scope: p.scope,
19
+ appliesWhen: p.appliesWhen,
20
+ description: p.metadata?.description ?? p.summary,
21
+ }));
22
+ return { data: formatRows(rows, input) };
19
23
  },
20
24
  };
@@ -1 +1 @@
1
- {"version":3,"file":"list-pipelines.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-pipelines.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,iBAAiB,EAAE,eAkB/B,CAAC"}
1
+ {"version":3,"file":"list-pipelines.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-pipelines.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,eAAO,MAAM,iBAAiB,EAAE,eAqB/B,CAAC"}
@@ -1,19 +1,23 @@
1
+ import { FORMAT_INPUT_PROPERTY, formatRows } from "../server/columnar-format.js";
1
2
  export const listPipelinesTool = {
2
3
  name: 'list_pipelines',
3
- description: 'List available SharkCraft AI development pipelines (declarative agent workflows).',
4
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
5
- async handler(_input, ctx) {
4
+ description: 'List available SharkCraft AI development pipelines (declarative agent workflows). Pass `format:"table"` for a token-efficient columnar payload.',
5
+ inputSchema: {
6
+ type: 'object',
7
+ properties: { ...FORMAT_INPUT_PROPERTY },
8
+ additionalProperties: false,
9
+ },
10
+ async handler(input, ctx) {
6
11
  const list = ctx.inspection.pipelineRegistry.list();
7
- return {
8
- data: list.map((p) => ({
9
- id: p.id,
10
- title: p.title,
11
- description: p.description,
12
- tags: p.tags ?? [],
13
- scope: p.scope ?? [],
14
- appliesWhen: p.appliesWhen ?? [],
15
- stepCount: p.steps.length,
16
- })),
17
- };
12
+ const rows = list.map((p) => ({
13
+ id: p.id,
14
+ title: p.title,
15
+ description: p.description,
16
+ tags: p.tags ?? [],
17
+ scope: p.scope ?? [],
18
+ appliesWhen: p.appliesWhen ?? [],
19
+ stepCount: p.steps.length,
20
+ }));
21
+ return { data: formatRows(rows, input) };
18
22
  },
19
23
  };
@@ -1 +1 @@
1
- {"version":3,"file":"list-presets.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-presets.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,eAAe,EAAE,eA0B7B,CAAC"}
1
+ {"version":3,"file":"list-presets.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-presets.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,eAAO,MAAM,eAAe,EAAE,eA6B7B,CAAC"}
@@ -1,26 +1,30 @@
1
+ import { FORMAT_INPUT_PROPERTY, formatRows } from "../server/columnar-format.js";
1
2
  export const listPresetsTool = {
2
3
  name: 'list_presets',
3
- description: 'List all SharkCraft presets (built-in + pack-contributed). A preset is a reusable project setup (knowledge / rules / paths / templates / pipelines / docs) that can be applied via the CLI.',
4
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
5
- async handler(_input, ctx) {
4
+ description: 'List all SharkCraft presets (built-in + pack-contributed). A preset is a reusable project setup (knowledge / rules / paths / templates / pipelines / docs) that can be applied via the CLI. Pass `format:"table"` for a token-efficient columnar payload.',
5
+ inputSchema: {
6
+ type: 'object',
7
+ properties: { ...FORMAT_INPUT_PROPERTY },
8
+ additionalProperties: false,
9
+ },
10
+ async handler(input, ctx) {
6
11
  const presets = ctx.inspection.presetRegistry.list();
7
- return {
8
- data: presets.map((p) => ({
9
- id: p.id,
10
- title: p.title,
11
- description: p.description,
12
- tags: p.tags ?? [],
13
- appliesTo: p.appliesTo ?? [],
14
- weight: p.weight ?? 5,
15
- source: ctx.inspection.presetSources.get(p.id) ?? null,
16
- counts: {
17
- knowledge: p.includes.knowledge?.length ?? 0,
18
- rules: p.includes.rules?.length ?? 0,
19
- paths: p.includes.paths?.length ?? 0,
20
- templates: p.includes.templates?.length ?? 0,
21
- pipelines: p.includes.pipelines?.length ?? 0,
22
- },
23
- })),
24
- };
12
+ const rows = presets.map((p) => ({
13
+ id: p.id,
14
+ title: p.title,
15
+ description: p.description,
16
+ tags: p.tags ?? [],
17
+ appliesTo: p.appliesTo ?? [],
18
+ weight: p.weight ?? 5,
19
+ source: ctx.inspection.presetSources.get(p.id) ?? null,
20
+ counts: {
21
+ knowledge: p.includes.knowledge?.length ?? 0,
22
+ rules: p.includes.rules?.length ?? 0,
23
+ paths: p.includes.paths?.length ?? 0,
24
+ templates: p.includes.templates?.length ?? 0,
25
+ pipelines: p.includes.pipelines?.length ?? 0,
26
+ },
27
+ }));
28
+ return { data: formatRows(rows, input) };
25
29
  },
26
30
  };
@@ -1 +1 @@
1
- {"version":3,"file":"list-rules.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-rules.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,aAAa,EAAE,eAkB3B,CAAC"}
1
+ {"version":3,"file":"list-rules.tool.d.ts","sourceRoot":"","sources":["../../src/tools/list-rules.tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,eAAO,MAAM,aAAa,EAAE,eAqB3B,CAAC"}