@shrkcrft/mcp-server 0.1.0-alpha.16 → 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.
@@ -13,8 +13,12 @@ export interface IFittedArray {
13
13
  * rest dropped) with the FULL original cached in `store` — the agent can
14
14
  * `retrieve_original` with the returned `ccrKey`.
15
15
  *
16
- * This routes through `compressJson({ maxTokens })`, which owns the
17
- * lossless-vs-lossy decision, so the big-array tools all budget identically.
16
+ * `compressJson({ maxTokens })` owns the lossless-vs-lossy DECISION, but its
17
+ * sampler keep-count is not derived from the budget, so a single sample can
18
+ * still exceed `maxTokens`. We therefore binary-search the row cap so the
19
+ * emitted payload actually fits the budget (down to a 1-row floor — a single
20
+ * row's columnar envelope may still exceed a very small budget, which is the
21
+ * best achievable while keeping any data).
18
22
  */
19
23
  export declare function fitArrayToBudget(array: readonly unknown[], maxTokens: number | undefined, store?: ICcrStore): IFittedArray;
20
24
  //# sourceMappingURL=fit-array-to-budget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fit-array-to-budget.d.ts","sourceRoot":"","sources":["../../src/server/fit-array-to-budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE1F,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,KAAK,EAAE,OAAO,CAAC;IACf,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,CAAC,EAAE,SAAS,GAChB,YAAY,CAed"}
1
+ {"version":3,"file":"fit-array-to-budget.d.ts","sourceRoot":"","sources":["../../src/server/fit-array-to-budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,KAAK,EAAE,OAAO,CAAC;IACf,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,CAAC,EAAE,SAAS,GAChB,YAAY,CA2Cd"}
@@ -1,4 +1,4 @@
1
- import { compactArrayToColumnar, compressJson } from '@shrkcrft/compress';
1
+ import { compactArrayToColumnar, compressJson, estimateTokens, EContentType, } from '@shrkcrft/compress';
2
2
  /**
3
3
  * Fit a homogeneous object array to an optional token budget (P5.2).
4
4
  *
@@ -7,22 +7,54 @@ import { compactArrayToColumnar, compressJson } from '@shrkcrft/compress';
7
7
  * rest dropped) with the FULL original cached in `store` — the agent can
8
8
  * `retrieve_original` with the returned `ccrKey`.
9
9
  *
10
- * This routes through `compressJson({ maxTokens })`, which owns the
11
- * lossless-vs-lossy decision, so the big-array tools all budget identically.
10
+ * `compressJson({ maxTokens })` owns the lossless-vs-lossy DECISION, but its
11
+ * sampler keep-count is not derived from the budget, so a single sample can
12
+ * still exceed `maxTokens`. We therefore binary-search the row cap so the
13
+ * emitted payload actually fits the budget (down to a 1-row floor — a single
14
+ * row's columnar envelope may still exceed a very small budget, which is the
15
+ * best achievable while keeping any data).
12
16
  */
13
17
  export function fitArrayToBudget(array, maxTokens, store) {
14
18
  const columnar = compactArrayToColumnar(array) ?? array;
15
19
  if (!maxTokens || maxTokens <= 0)
16
20
  return { value: columnar };
17
- const result = compressJson(JSON.stringify(array), {
18
- maxTokens,
19
- ...(store ? { store } : {}),
20
- });
21
- // A CCR key is set only on the lossy sample path; under budget the result is
22
- // the lossless columnar/minified form, so fall back to the columnar value.
23
- if (result.ccrKey) {
24
- const firstLine = result.compressed.split('\n')[0] ?? 'null';
25
- return { value: JSON.parse(firstLine), ccrKey: result.ccrKey };
21
+ const json = JSON.stringify(array);
22
+ const run = (maxItems) => {
23
+ const r = compressJson(json, {
24
+ maxTokens,
25
+ ...(maxItems !== undefined ? { maxItems } : {}),
26
+ ...(store ? { store } : {}),
27
+ });
28
+ // A CCR key is set only on the lossy sample path; under budget the result
29
+ // is the lossless form, so the caller falls back to the columnar value.
30
+ if (!r.ccrKey)
31
+ return null;
32
+ const firstLine = r.compressed.split('\n')[0] ?? 'null';
33
+ return { value: JSON.parse(firstLine), ccrKey: r.ccrKey };
34
+ };
35
+ const fits = (fitted) => estimateTokens(JSON.stringify(fitted.value), EContentType.JsonArray) <= maxTokens;
36
+ // Default sample (no cap). Null → under budget, emit the lossless form.
37
+ const initial = run();
38
+ if (!initial)
39
+ return { value: columnar };
40
+ if (fits(initial))
41
+ return initial;
42
+ // Largest row cap whose sampled payload still fits the budget.
43
+ let lo = 1;
44
+ let hi = array.length;
45
+ let best = null;
46
+ while (lo <= hi) {
47
+ const mid = Math.floor((lo + hi) / 2);
48
+ const candidate = run(mid);
49
+ if (candidate && fits(candidate)) {
50
+ best = candidate;
51
+ lo = mid + 1;
52
+ }
53
+ else {
54
+ hi = mid - 1;
55
+ }
26
56
  }
27
- return { value: columnar };
57
+ // Even one row over budget → keep the smallest sample (best effort, still
58
+ // recoverable via ccrKey) rather than the much larger default sample.
59
+ return best ?? run(1) ?? initial;
28
60
  }
@@ -1 +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"}
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,eA6EjC,CAAC"}
@@ -21,11 +21,12 @@ export const compressContextTool = {
21
21
  description: 'Optional task/query text that biases which lines or matches are kept.',
22
22
  },
23
23
  maxItems: {
24
- type: 'number',
24
+ type: 'integer',
25
+ minimum: 1,
25
26
  description: 'Soft cap on retained lines / matches / hunks (compressor-specific).',
26
27
  },
27
28
  maxTokens: {
28
- type: 'number',
29
+ type: 'integer',
29
30
  minimum: 1,
30
31
  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
  },
@@ -19,7 +19,7 @@ export const depsAuditTool = {
19
19
  package: { type: 'string' },
20
20
  ...FORMAT_INPUT_PROPERTY,
21
21
  maxTokens: {
22
- type: 'number',
22
+ type: 'integer',
23
23
  minimum: 1,
24
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
25
  },
@@ -238,6 +238,10 @@ function rootOfSpecifier(spec) {
238
238
  function isBuiltinModule(spec) {
239
239
  if (spec.startsWith('node:'))
240
240
  return true;
241
+ // Bun runtime builtins (`bun:test`, `bun:sqlite`, …) are runtime-provided,
242
+ // never an npm dependency — so they are not "missing".
243
+ if (spec.startsWith('bun:'))
244
+ return true;
241
245
  return new Set([
242
246
  'fs', 'path', 'os', 'crypto', 'http', 'https', 'url', 'util', 'stream',
243
247
  'events', 'child_process', 'process', 'buffer', 'querystring', 'zlib',
@@ -21,7 +21,7 @@ export const getKnowledgeGraphTool = {
21
21
  description: 'json (default): explicit node/edge object arrays. table: columnar encoding (schema hoisted, keys deduped) — fewer tokens for large graphs.',
22
22
  },
23
23
  maxTokens: {
24
- type: 'number',
24
+ type: 'integer',
25
25
  minimum: 1,
26
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
27
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shrkcrft/mcp-server",
3
- "version": "0.1.0-alpha.16",
3
+ "version": "0.1.0-alpha.17",
4
4
  "description": "SharkCraft MCP server: 25 tools over @modelcontextprotocol/sdk's stdio transport.",
5
5
  "license": "MIT",
6
6
  "author": "SharkCraft contributors",
@@ -44,32 +44,32 @@
44
44
  "typecheck": "tsc --noEmit -p tsconfig.json"
45
45
  },
46
46
  "dependencies": {
47
- "@shrkcrft/core": "^0.1.0-alpha.16",
48
- "@shrkcrft/compress": "^0.1.0-alpha.16",
49
- "@shrkcrft/config": "^0.1.0-alpha.16",
50
- "@shrkcrft/workspace": "^0.1.0-alpha.16",
51
- "@shrkcrft/knowledge": "^0.1.0-alpha.16",
52
- "@shrkcrft/context": "^0.1.0-alpha.16",
53
- "@shrkcrft/rules": "^0.1.0-alpha.16",
54
- "@shrkcrft/paths": "^0.1.0-alpha.16",
55
- "@shrkcrft/templates": "^0.1.0-alpha.16",
56
- "@shrkcrft/pipelines": "^0.1.0-alpha.16",
57
- "@shrkcrft/presets": "^0.1.0-alpha.16",
58
- "@shrkcrft/boundaries": "^0.1.0-alpha.16",
59
- "@shrkcrft/graph": "^0.1.0-alpha.16",
60
- "@shrkcrft/rule-graph": "^0.1.0-alpha.16",
61
- "@shrkcrft/structural-search": "^0.1.0-alpha.16",
62
- "@shrkcrft/impact-engine": "^0.1.0-alpha.16",
63
- "@shrkcrft/context-planner": "^0.1.0-alpha.16",
64
- "@shrkcrft/architecture-guard": "^0.1.0-alpha.16",
65
- "@shrkcrft/framework-scanners": "^0.1.0-alpha.16",
66
- "@shrkcrft/api-surface-diff": "^0.1.0-alpha.16",
67
- "@shrkcrft/quality-gates": "^0.1.0-alpha.16",
68
- "@shrkcrft/migrate": "^0.1.0-alpha.16",
69
- "@shrkcrft/packs": "^0.1.0-alpha.16",
70
- "@shrkcrft/generator": "^0.1.0-alpha.16",
71
- "@shrkcrft/inspector": "^0.1.0-alpha.16",
72
- "@shrkcrft/embeddings": "^0.1.0-alpha.16",
47
+ "@shrkcrft/core": "^0.1.0-alpha.17",
48
+ "@shrkcrft/compress": "^0.1.0-alpha.17",
49
+ "@shrkcrft/config": "^0.1.0-alpha.17",
50
+ "@shrkcrft/workspace": "^0.1.0-alpha.17",
51
+ "@shrkcrft/knowledge": "^0.1.0-alpha.17",
52
+ "@shrkcrft/context": "^0.1.0-alpha.17",
53
+ "@shrkcrft/rules": "^0.1.0-alpha.17",
54
+ "@shrkcrft/paths": "^0.1.0-alpha.17",
55
+ "@shrkcrft/templates": "^0.1.0-alpha.17",
56
+ "@shrkcrft/pipelines": "^0.1.0-alpha.17",
57
+ "@shrkcrft/presets": "^0.1.0-alpha.17",
58
+ "@shrkcrft/boundaries": "^0.1.0-alpha.17",
59
+ "@shrkcrft/graph": "^0.1.0-alpha.17",
60
+ "@shrkcrft/rule-graph": "^0.1.0-alpha.17",
61
+ "@shrkcrft/structural-search": "^0.1.0-alpha.17",
62
+ "@shrkcrft/impact-engine": "^0.1.0-alpha.17",
63
+ "@shrkcrft/context-planner": "^0.1.0-alpha.17",
64
+ "@shrkcrft/architecture-guard": "^0.1.0-alpha.17",
65
+ "@shrkcrft/framework-scanners": "^0.1.0-alpha.17",
66
+ "@shrkcrft/api-surface-diff": "^0.1.0-alpha.17",
67
+ "@shrkcrft/quality-gates": "^0.1.0-alpha.17",
68
+ "@shrkcrft/migrate": "^0.1.0-alpha.17",
69
+ "@shrkcrft/packs": "^0.1.0-alpha.17",
70
+ "@shrkcrft/generator": "^0.1.0-alpha.17",
71
+ "@shrkcrft/inspector": "^0.1.0-alpha.17",
72
+ "@shrkcrft/embeddings": "^0.1.0-alpha.17",
73
73
  "@modelcontextprotocol/sdk": "^1.0.0",
74
74
  "zod": "^3.25.0 || ^4.0.0"
75
75
  },
@@ -1,4 +0,0 @@
1
- import type { IToolDefinition } from '../server/tool-definition.js';
2
- export declare const getMigrationReadinessTool: IToolDefinition;
3
- export declare const listMigrationProfilesTool: IToolDefinition;
4
- //# sourceMappingURL=r22-extras.tool.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"r22-extras.tool.d.ts","sourceRoot":"","sources":["../../src/tools/r22-extras.tool.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,yBAAyB,EAAE,eAuBvC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,eAevC,CAAC"}
@@ -1,42 +0,0 @@
1
- /**
2
- * Migration / readiness MCP tools. All read-only.
3
- */
4
- import { buildMigrationReadiness, listMigrationProfiles, listMigrationProfilesFromPacks, } from '@shrkcrft/inspector';
5
- export const getMigrationReadinessTool = {
6
- name: 'get_migration_readiness',
7
- description: 'Migration readiness verdict for a profile id. Read-only — probes local files and env vars; never runs source.',
8
- inputSchema: {
9
- type: 'object',
10
- properties: {
11
- profileId: { type: 'string' },
12
- },
13
- required: ['profileId'],
14
- additionalProperties: false,
15
- },
16
- async handler(input, ctx) {
17
- const profileId = typeof input['profileId'] === 'string' ? input['profileId'] : '';
18
- const packProfiles = await listMigrationProfilesFromPacks(ctx.inspection);
19
- const report = buildMigrationReadiness({
20
- profileId,
21
- projectRoot: ctx.inspection.projectRoot,
22
- customProfiles: packProfiles,
23
- });
24
- return { data: report };
25
- },
26
- };
27
- export const listMigrationProfilesTool = {
28
- name: 'list_migration_profiles',
29
- description: 'List registered migration profiles (built-in + pack-contributed). Read-only.',
30
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
31
- async handler(_input, ctx) {
32
- const packProfiles = await listMigrationProfilesFromPacks(ctx.inspection);
33
- const profiles = listMigrationProfiles(packProfiles).map((p) => ({
34
- id: p.id,
35
- title: p.title,
36
- description: p.description,
37
- successVerdict: p.successVerdict,
38
- checks: p.checks.length,
39
- }));
40
- return { data: profiles };
41
- },
42
- };
@@ -1,10 +0,0 @@
1
- import type { IToolDefinition } from '../server/tool-definition.js';
2
- export declare const createRepositoryIngestionPlanTool: IToolDefinition;
3
- export declare const getRepositoryKnowledgeModelTool: IToolDefinition;
4
- export declare const getRepositoryIngestionStatusTool: IToolDefinition;
5
- export declare const getRepositoryIngestionReportTool: IToolDefinition;
6
- export declare const getContradictionReportTool: IToolDefinition;
7
- export declare const getGeneratedCodeReportTool: IToolDefinition;
8
- export declare const getStabilityMapTool: IToolDefinition;
9
- export declare const getIngestAdoptionPreviewTool: IToolDefinition;
10
- //# sourceMappingURL=r26-ingest.tool.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"r26-ingest.tool.d.ts","sourceRoot":"","sources":["../../src/tools/r26-ingest.tool.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAyBpE,eAAO,MAAM,iCAAiC,EAAE,eA4B/C,CAAC;AAEF,eAAO,MAAM,+BAA+B,EAAE,eAyB7C,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,eAiB9C,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,eAiB9C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eAWxC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eAWxC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAejC,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,eAY1C,CAAC"}
@@ -1,174 +0,0 @@
1
- import * as nodePath from 'node:path';
2
- import { existsSync, readFileSync } from 'node:fs';
3
- import { buildContradictionReport, buildGeneratedCodeReport, buildIngestAdoptionPlan, buildRepositoryKnowledgeModel, buildStabilityMap, IngestDepth, IngestSection, } from '@shrkcrft/inspector';
4
- function nextHint(cmd) {
5
- return `Next: \`${cmd}\` (CLI is the only write path).`;
6
- }
7
- function parseDepth(raw) {
8
- if (typeof raw !== 'string')
9
- return IngestDepth.Standard;
10
- const lower = raw.toLowerCase();
11
- for (const d of Object.values(IngestDepth))
12
- if (d === lower)
13
- return d;
14
- return IngestDepth.Standard;
15
- }
16
- function parseSections(raw) {
17
- if (!Array.isArray(raw))
18
- return undefined;
19
- const out = [];
20
- for (const s of raw) {
21
- if (typeof s !== 'string')
22
- continue;
23
- for (const v of Object.values(IngestSection)) {
24
- if (v === s)
25
- out.push(v);
26
- }
27
- }
28
- return out.length > 0 ? out : undefined;
29
- }
30
- export const createRepositoryIngestionPlanTool = {
31
- name: 'create_repository_ingestion_plan',
32
- description: 'Build a SharkCraft repository knowledge model (read-only). Returns the model + a next-command hint. MCP never writes; pass --write-drafts to the CLI to materialise drafts under sharkcraft/ingestion/.',
33
- inputSchema: {
34
- type: 'object',
35
- additionalProperties: false,
36
- properties: {
37
- depth: { type: 'string' },
38
- include: { type: 'array', items: { type: 'string' } },
39
- exclude: { type: 'array', items: { type: 'string' } },
40
- presets: { type: 'array', items: { type: 'string' } },
41
- task: { type: 'string' },
42
- },
43
- },
44
- async handler(input, ctx) {
45
- const model = await buildRepositoryKnowledgeModel({
46
- inspection: ctx.inspection,
47
- depth: parseDepth(input.depth),
48
- selectedSections: parseSections(input.include),
49
- excludedSections: parseSections(input.exclude),
50
- forcedPresetIds: Array.isArray(input.presets) ? input.presets.filter((p) => typeof p === 'string') : undefined,
51
- ...(typeof input.task === 'string' ? { task: input.task } : {}),
52
- });
53
- return {
54
- text: nextHint('shrk ingest repository --write-drafts'),
55
- data: model,
56
- };
57
- },
58
- };
59
- export const getRepositoryKnowledgeModelTool = {
60
- name: 'get_repository_knowledge_model',
61
- description: 'Return the previously-saved repository knowledge model (`sharkcraft/ingestion/repository-knowledge-model.json`). Read-only.',
62
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
63
- handler(_input, ctx) {
64
- const file = nodePath.join(ctx.cwd, 'sharkcraft', 'ingestion', 'repository-knowledge-model.json');
65
- if (!existsSync(file)) {
66
- return {
67
- isError: true,
68
- error: { code: 'not-found', message: 'No saved knowledge model. Run `shrk ingest repository --write-drafts` first.' },
69
- };
70
- }
71
- try {
72
- const body = JSON.parse(readFileSync(file, 'utf8'));
73
- return {
74
- text: nextHint('shrk ingest report --format markdown'),
75
- data: body,
76
- };
77
- }
78
- catch (err) {
79
- return {
80
- isError: true,
81
- error: { code: 'parse-failed', message: err.message },
82
- };
83
- }
84
- },
85
- };
86
- export const getRepositoryIngestionStatusTool = {
87
- name: 'get_repository_ingestion_status',
88
- description: 'Report whether ingest drafts/adoption files exist on disk. Read-only.',
89
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
90
- handler(_input, ctx) {
91
- const base = nodePath.join(ctx.cwd, 'sharkcraft', 'ingestion');
92
- const modelExists = existsSync(nodePath.join(base, 'repository-knowledge-model.json'));
93
- const adoptionExists = existsSync(nodePath.join(base, 'adoption', 'ingest-adoption-state.json'));
94
- return {
95
- text: nextHint('shrk ingest status'),
96
- data: {
97
- ingestDirExists: existsSync(base),
98
- modelExists,
99
- adoptionExists,
100
- },
101
- };
102
- },
103
- };
104
- export const getRepositoryIngestionReportTool = {
105
- name: 'get_repository_ingestion_report',
106
- description: 'Return a markdown summary of the saved repository knowledge model. Read-only.',
107
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
108
- async handler(_input, ctx) {
109
- const file = nodePath.join(ctx.cwd, 'sharkcraft', 'ingestion', 'REPOSITORY_KNOWLEDGE_MODEL.md');
110
- if (!existsSync(file)) {
111
- return {
112
- isError: true,
113
- error: { code: 'not-found', message: 'No saved report — run `shrk ingest repository --write-drafts` first.' },
114
- };
115
- }
116
- return {
117
- text: nextHint('shrk ingest report --format markdown'),
118
- data: { markdown: readFileSync(file, 'utf8') },
119
- };
120
- },
121
- };
122
- export const getContradictionReportTool = {
123
- name: 'get_contradiction_report',
124
- description: 'Detect documentation/code contradictions (missing paths, deprecated CLI usage, missing commands). Read-only.',
125
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
126
- async handler(_input, ctx) {
127
- const report = buildContradictionReport({ inspection: ctx.inspection });
128
- return {
129
- text: nextHint('shrk contradictions --format markdown'),
130
- data: report,
131
- };
132
- },
133
- };
134
- export const getGeneratedCodeReportTool = {
135
- name: 'get_generated_code_report',
136
- description: 'Classify generated vs hand-written files; surface protect/policy recommendations. Read-only.',
137
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
138
- async handler(_input, ctx) {
139
- const report = buildGeneratedCodeReport({ inspection: ctx.inspection });
140
- return {
141
- text: nextHint('shrk generated report --format markdown'),
142
- data: report,
143
- };
144
- },
145
- };
146
- export const getStabilityMapTool = {
147
- name: 'get_stability_map',
148
- description: 'Classify repo areas as stable/experimental/deprecated/legacy/generated/internal/public-api/high-risk. Read-only.',
149
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
150
- async handler(_input, ctx) {
151
- const generated = buildGeneratedCodeReport({ inspection: ctx.inspection });
152
- const map = buildStabilityMap({
153
- inspection: ctx.inspection,
154
- generatedRoots: generated.generatedRoots.map((r) => r.path),
155
- });
156
- return {
157
- text: nextHint('shrk stability map --format markdown'),
158
- data: map,
159
- };
160
- },
161
- };
162
- export const getIngestAdoptionPreviewTool = {
163
- name: 'get_ingest_adoption_preview',
164
- description: 'Preview the ingest-adoption plan (safe-append / manual-review / low-confidence / already-covered / generated-protected). Read-only.',
165
- inputSchema: { type: 'object', properties: {}, additionalProperties: false },
166
- async handler(_input, ctx) {
167
- const model = await buildRepositoryKnowledgeModel({ inspection: ctx.inspection });
168
- const plan = buildIngestAdoptionPlan({ model });
169
- return {
170
- text: nextHint('shrk ingest adopt --write-patch'),
171
- data: plan,
172
- };
173
- },
174
- };
@@ -1,3 +0,0 @@
1
- import type { IToolDefinition } from '../server/tool-definition.js';
2
- export declare const searchUnifiedTool: IToolDefinition;
3
- //# sourceMappingURL=r34-search-unified.tool.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"r34-search-unified.tool.d.ts","sourceRoot":"","sources":["../../src/tools/r34-search-unified.tool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,iBAAiB,EAAE,eA4B/B,CAAC"}
@@ -1,38 +0,0 @@
1
- /**
2
- * Read-only MCP tool for unified search.
3
- */
4
- import { buildUniversalSearch } from '@shrkcrft/inspector';
5
- export const searchUnifiedTool = {
6
- name: 'search_unified',
7
- description: 'Universal search palette across every contribution kind. Returns the 7-section unified output + uncertainty footer. Read-only.',
8
- inputSchema: {
9
- type: 'object',
10
- additionalProperties: false,
11
- required: ['query'],
12
- properties: {
13
- query: { type: 'string' },
14
- kind: { type: 'string' },
15
- source: { type: 'string' },
16
- limit: { type: 'number' },
17
- commandsOnly: { type: 'boolean' },
18
- actionsOnly: { type: 'boolean' },
19
- },
20
- },
21
- async handler(input, ctx) {
22
- const query = typeof input.query === 'string' ? input.query : '';
23
- if (!query)
24
- return { isError: true, error: { code: 'invalid-input', message: 'query is required' } };
25
- const opts = {};
26
- if (typeof input.kind === 'string')
27
- opts.kind = input.kind;
28
- if (typeof input.source === 'string')
29
- opts.source = input.source;
30
- if (typeof input.limit === 'number')
31
- opts.limit = input.limit;
32
- if (input.commandsOnly === true)
33
- opts.commandsOnly = true;
34
- if (input.actionsOnly === true)
35
- opts.actionsOnly = true;
36
- return { data: await buildUniversalSearch(ctx.inspection, query, opts) };
37
- },
38
- };