@harness-engineering/cli 1.24.1 → 1.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +10 -6
- package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +40 -5
- package/dist/agents/skills/claude-code/harness-git-workflow/SKILL.md +32 -11
- package/dist/agents/skills/claude-code/harness-planning/SKILL.md +19 -0
- package/dist/agents/skills/claude-code/harness-skill-authoring/SKILL.md +42 -7
- package/dist/agents/skills/claude-code/harness-verification/SKILL.md +25 -0
- package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +10 -6
- package/dist/agents/skills/codex/harness-code-review/SKILL.md +40 -5
- package/dist/agents/skills/codex/harness-git-workflow/SKILL.md +32 -11
- package/dist/agents/skills/codex/harness-planning/SKILL.md +19 -0
- package/dist/agents/skills/codex/harness-skill-authoring/SKILL.md +42 -7
- package/dist/agents/skills/codex/harness-verification/SKILL.md +25 -0
- package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +10 -6
- package/dist/agents/skills/cursor/harness-code-review/SKILL.md +40 -5
- package/dist/agents/skills/cursor/harness-git-workflow/SKILL.md +32 -11
- package/dist/agents/skills/cursor/harness-planning/SKILL.md +19 -0
- package/dist/agents/skills/cursor/harness-skill-authoring/SKILL.md +42 -7
- package/dist/agents/skills/cursor/harness-verification/SKILL.md +25 -0
- package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +10 -6
- package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +40 -5
- package/dist/agents/skills/gemini-cli/harness-git-workflow/SKILL.md +32 -11
- package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +19 -0
- package/dist/agents/skills/gemini-cli/harness-skill-authoring/SKILL.md +42 -7
- package/dist/agents/skills/gemini-cli/harness-verification/SKILL.md +25 -0
- package/dist/agents-md-MCUM4SIZ.js +10 -0
- package/dist/architecture-HNIO6AUX.js +15 -0
- package/dist/{assess-project-7JZCVM7D.js → assess-project-6MV5TNY3.js} +2 -1
- package/dist/bin/harness-mcp.js +19 -18
- package/dist/bin/harness.js +48 -31
- package/dist/{check-phase-gate-YQHAH4LL.js → check-phase-gate-VCBQHQAC.js} +6 -5
- package/dist/{chunk-Q3XYV5UC.js → chunk-47N6R2F4.js} +5 -1
- package/dist/chunk-4NK7Z3BP.js +43 -0
- package/dist/{chunk-I4QR3HNH.js → chunk-5BQ5BOJL.js} +5 -1
- package/dist/{chunk-LM5Z2WCA.js → chunk-6VZQJ5CX.js} +5 -1
- package/dist/{chunk-NV4FPO7J.js → chunk-AT74HEQM.js} +1 -1
- package/dist/{chunk-ZKVLBOYA.js → chunk-AZT567I6.js} +1495 -662
- package/dist/{chunk-TDLOFNNQ.js → chunk-BOQRTARD.js} +1 -1
- package/dist/{chunk-NU3BPEDR.js → chunk-CXJTVICF.js} +5 -5
- package/dist/{chunk-LOUH2LIC.js → chunk-EHRZMOQ2.js} +5 -1
- package/dist/{chunk-IDZNPTYD.js → chunk-EPUKTTJZ.js} +6 -1
- package/dist/{chunk-C5FTJ3EU.js → chunk-F23H3U5U.js} +62 -1
- package/dist/{chunk-BWWNQPPO.js → chunk-FES2YEQU.js} +10 -10
- package/dist/{chunk-W2OZK3KC.js → chunk-FIQL2HND.js} +6 -2
- package/dist/{chunk-FP53DDB5.js → chunk-FSNPBT74.js} +5 -1
- package/dist/{chunk-TUJAHI22.js → chunk-GEEYCQDS.js} +14 -10
- package/dist/{chunk-ZOVATVQC.js → chunk-HIK6OEUF.js} +6 -1
- package/dist/chunk-K2SON7TI.js +5382 -0
- package/dist/chunk-KFQGP6VL.js +33 -0
- package/dist/{chunk-JGMCHJ6B.js → chunk-M55DGGF3.js} +10 -6
- package/dist/{chunk-PCWYYFBP.js → chunk-MI6MA6OP.js} +16906 -13135
- package/dist/{chunk-YDRB55Q4.js → chunk-P7PANON5.js} +5 -1
- package/dist/chunk-RL4VMEXL.js +53 -0
- package/dist/{chunk-XNEMDKV5.js → chunk-RRHUCDRD.js} +1 -1
- package/dist/{chunk-LY3YVKXL.js → chunk-RX7TUMBR.js} +606 -175
- package/dist/{chunk-MS6KDQW7.js → chunk-TYV4EUAD.js} +13 -9
- package/dist/{chunk-2DAMN7ED.js → chunk-UQZBZINS.js} +6 -6
- package/dist/{chunk-HVFCCARH.js → chunk-UV3BZMGT.js} +64 -3
- package/dist/{chunk-AVVJ5EUU.js → chunk-WIQA4BSH.js} +12 -5
- package/dist/{chunk-UQEUYRBP.js → chunk-WWACIIBA.js} +1 -1
- package/dist/{chunk-LVYPPKZI.js → chunk-XTITAVUR.js} +5 -1
- package/dist/{chunk-JT732X6S.js → chunk-YTP2UDPV.js} +3 -3
- package/dist/ci-workflow-RTM7VVTD.js +10 -0
- package/dist/{constants-5JGUXPEK.js → constants-P4M3C2T3.js} +1 -0
- package/dist/{create-skill-QCXINA5Q.js → create-skill-6QWJHQYS.js} +3 -2
- package/dist/{dist-666AAZQ6.js → dist-3EWNRFFQ.js} +6 -1
- package/dist/{dist-RRMRZRV7.js → dist-ABTKRYZH.js} +1 -0
- package/dist/{dist-QW5G3GX3.js → dist-RADHOOXG.js} +4 -1
- package/dist/{dist-TZQUURSP.js → dist-WCSJHQPK.js} +108 -3
- package/dist/docs-UBOGGHTY.js +16 -0
- package/dist/engine-MJJAP5CH.js +10 -0
- package/dist/entropy-EMSXF2PX.js +14 -0
- package/dist/{feedback-RSPUJCJJ.js → feedback-ZLUX72HD.js} +3 -2
- package/dist/{generate-agent-definitions-OLYWXTYH.js → generate-agent-definitions-AWLPJ27C.js} +6 -5
- package/dist/{glob-helper-SRXMZPKM.js → glob-helper-VCQXK5XY.js} +2 -0
- package/dist/{graph-loader-M6FXJAKK.js → graph-loader-JHQVQRUS.js} +2 -1
- package/dist/index.d.ts +21 -15
- package/dist/index.js +36 -33
- package/dist/loader-JVSJZSWZ.js +12 -0
- package/dist/mcp-2553PNUC.js +38 -0
- package/dist/{performance-VVWOIJTE.js → performance-7AGWJUY4.js} +7 -6
- package/dist/review-pipeline-ZWVQJTJX.js +13 -0
- package/dist/{runner-TY7DJGQV.js → runner-AAEF2TXY.js} +1 -0
- package/dist/runtime-D6YUQPP2.js +11 -0
- package/dist/scan-MPJ6JHUY.js +9 -0
- package/dist/security-JLZUAQYT.js +14 -0
- package/dist/skill-executor-MOCUIAYS.js +9 -0
- package/dist/templates/base/.agnix.toml +16 -0
- package/dist/templates/orchestrator/WORKFLOW.md +55 -7
- package/dist/templates/orchestrator/template.json +1 -0
- package/dist/tool-tiers-7QGZ3FKY.js +98 -0
- package/dist/validate-TIIHRPMA.js +14 -0
- package/dist/validate-cross-check-ZOWFA3DB.js +10 -0
- package/dist/{version-KFFPOQAX.js → version-CUI434OP.js} +1 -0
- package/package.json +5 -5
- package/dist/agents-md-MMVRF77L.js +0 -9
- package/dist/architecture-JAEDPYQZ.js +0 -14
- package/dist/chunk-5LMZA5LZ.js +0 -38
- package/dist/chunk-OZIHPMA7.js +0 -5171
- package/dist/ci-workflow-HDH4LCOF.js +0 -9
- package/dist/docs-6SPJYTRR.js +0 -15
- package/dist/engine-CSITRE3J.js +0 -9
- package/dist/entropy-FZP643BK.js +0 -13
- package/dist/loader-P2P7CV2A.js +0 -11
- package/dist/mcp-JZG22CYT.js +0 -37
- package/dist/review-pipeline-XSRO7HYZ.js +0 -9
- package/dist/runtime-VMOIIP6B.js +0 -10
- package/dist/security-4AQ46P3H.js +0 -9
- package/dist/skill-executor-GA7BDX3F.js +0 -8
- package/dist/validate-T7UTXLEQ.js +0 -13
- package/dist/validate-cross-check-M4NP2UF5.js +0 -9
|
@@ -5,38 +5,41 @@ import {
|
|
|
5
5
|
handleCreateSelfReview,
|
|
6
6
|
handleRequestPeerReview,
|
|
7
7
|
requestPeerReviewDefinition
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-FES2YEQU.js";
|
|
9
9
|
import {
|
|
10
|
+
getSecurityTrendsDefinition,
|
|
11
|
+
handleGetSecurityTrends,
|
|
10
12
|
handleRunSecurityScan,
|
|
11
13
|
runSecurityScanDefinition
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-UV3BZMGT.js";
|
|
13
15
|
import {
|
|
14
16
|
handleRunCodeReview,
|
|
15
|
-
runCodeReviewDefinition
|
|
16
|
-
|
|
17
|
+
runCodeReviewDefinition,
|
|
18
|
+
sortFindingsBySeverity
|
|
19
|
+
} from "./chunk-F23H3U5U.js";
|
|
17
20
|
import {
|
|
18
21
|
assessProjectDefinition,
|
|
19
22
|
handleAssessProject
|
|
20
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-UQZBZINS.js";
|
|
21
24
|
import {
|
|
22
25
|
handleValidateProject,
|
|
23
26
|
validateToolDefinition
|
|
24
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-YTP2UDPV.js";
|
|
25
28
|
import {
|
|
26
29
|
checkDependenciesDefinition,
|
|
27
30
|
handleCheckDependencies
|
|
28
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-CXJTVICF.js";
|
|
29
32
|
import {
|
|
30
33
|
resolveProjectConfig
|
|
31
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-47N6R2F4.js";
|
|
32
35
|
import {
|
|
33
36
|
checkDocsDefinition,
|
|
34
37
|
handleCheckDocs
|
|
35
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-GEEYCQDS.js";
|
|
36
39
|
import {
|
|
37
40
|
detectEntropyDefinition,
|
|
38
41
|
handleDetectEntropy
|
|
39
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-M55DGGF3.js";
|
|
40
43
|
import {
|
|
41
44
|
checkPerformanceDefinition,
|
|
42
45
|
getCriticalPathsDefinition,
|
|
@@ -46,17 +49,16 @@ import {
|
|
|
46
49
|
handleGetPerfBaselines,
|
|
47
50
|
handleUpdatePerfBaselines,
|
|
48
51
|
updatePerfBaselinesDefinition
|
|
49
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-TYV4EUAD.js";
|
|
50
53
|
import {
|
|
51
54
|
resultToMcpResponse
|
|
52
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-EPUKTTJZ.js";
|
|
53
56
|
import {
|
|
54
57
|
sanitizePath
|
|
55
58
|
} from "./chunk-W6Y7ZW3Y.js";
|
|
56
59
|
import {
|
|
57
|
-
TrackerConfigSchema,
|
|
58
60
|
resolveConfig
|
|
59
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-WIQA4BSH.js";
|
|
60
62
|
import {
|
|
61
63
|
GENERATED_HEADER_CLAUDE,
|
|
62
64
|
GENERATED_HEADER_CODEX,
|
|
@@ -78,7 +80,7 @@ import {
|
|
|
78
80
|
} from "./chunk-6B6UN6SG.js";
|
|
79
81
|
import {
|
|
80
82
|
loadGraphStore
|
|
81
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-BOQRTARD.js";
|
|
82
84
|
import {
|
|
83
85
|
CompactionPipeline,
|
|
84
86
|
DEFAULT_TOKEN_BUDGET,
|
|
@@ -86,19 +88,24 @@ import {
|
|
|
86
88
|
StructuralStrategy,
|
|
87
89
|
TruncationStrategy,
|
|
88
90
|
checkTaint,
|
|
91
|
+
computeLoadPlan,
|
|
89
92
|
detectChangeType,
|
|
90
93
|
estimateTokens,
|
|
94
|
+
extractLevel,
|
|
95
|
+
init_dist,
|
|
96
|
+
loadTrackerSyncConfig,
|
|
97
|
+
paginate,
|
|
91
98
|
scanForInjection,
|
|
92
99
|
serializeEnvelope,
|
|
93
100
|
writeTaint
|
|
94
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-MI6MA6OP.js";
|
|
95
102
|
import {
|
|
96
103
|
Err,
|
|
97
104
|
Ok
|
|
98
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-RL4VMEXL.js";
|
|
99
106
|
import {
|
|
100
107
|
SkillMetadataSchema
|
|
101
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-HIK6OEUF.js";
|
|
102
109
|
import {
|
|
103
110
|
CLIError,
|
|
104
111
|
ExitCode,
|
|
@@ -116,6 +123,7 @@ import {
|
|
|
116
123
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
117
124
|
|
|
118
125
|
// src/mcp/middleware/injection-guard.ts
|
|
126
|
+
init_dist();
|
|
119
127
|
import { realpathSync } from "fs";
|
|
120
128
|
import { resolve } from "path";
|
|
121
129
|
function isDestructiveBash(command) {
|
|
@@ -236,25 +244,27 @@ function applyInjectionGuard(handlers, options = {}) {
|
|
|
236
244
|
}
|
|
237
245
|
|
|
238
246
|
// src/mcp/middleware/compaction.ts
|
|
247
|
+
init_dist();
|
|
239
248
|
var DEFAULT_PIPELINE = new CompactionPipeline([
|
|
240
249
|
new StructuralStrategy(),
|
|
241
250
|
new TruncationStrategy()
|
|
242
251
|
]);
|
|
243
|
-
|
|
252
|
+
var LOSSLESS_PIPELINE = new CompactionPipeline([new StructuralStrategy()]);
|
|
253
|
+
function buildHeader(pipeline, orig, comp) {
|
|
244
254
|
const pct = orig > 0 ? Math.round((1 - comp / orig) * 100) : 0;
|
|
245
|
-
return `<!-- packed: ${
|
|
255
|
+
return `<!-- packed: ${pipeline.strategyNames.join("+")} | ${orig}\u2192${comp} tokens (-${pct}%) -->`;
|
|
246
256
|
}
|
|
247
|
-
function compactText(text) {
|
|
248
|
-
return
|
|
257
|
+
function compactText(text, pipeline, budget) {
|
|
258
|
+
return pipeline.apply(text, budget);
|
|
249
259
|
}
|
|
250
|
-
function
|
|
260
|
+
function compactResultWith(result, pipeline, budget) {
|
|
251
261
|
const texts = result.content.filter((i) => i.type === "text");
|
|
252
262
|
const origTok = texts.reduce((s, i) => s + estimateTokens(i.text), 0);
|
|
253
263
|
const packed = /* @__PURE__ */ new Map();
|
|
254
|
-
for (const item of texts) packed.set(item, compactText(item.text));
|
|
264
|
+
for (const item of texts) packed.set(item, compactText(item.text, pipeline, budget));
|
|
255
265
|
const compTok = [...packed.values()].reduce((s, t) => s + estimateTokens(t), 0);
|
|
256
|
-
const hdrTok = estimateTokens(buildHeader(origTok, compTok));
|
|
257
|
-
const header = buildHeader(origTok, compTok + hdrTok);
|
|
266
|
+
const hdrTok = estimateTokens(buildHeader(pipeline, origTok, compTok));
|
|
267
|
+
const header = buildHeader(pipeline, origTok, compTok + hdrTok);
|
|
258
268
|
let first = true;
|
|
259
269
|
const content = result.content.map((item) => {
|
|
260
270
|
if (item.type !== "text") return item;
|
|
@@ -268,6 +278,32 @@ ${c}` };
|
|
|
268
278
|
});
|
|
269
279
|
return { ...result, content };
|
|
270
280
|
}
|
|
281
|
+
var LOSSLESS_ONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
282
|
+
"run_skill",
|
|
283
|
+
// Skill instructions the agent must follow completely
|
|
284
|
+
"emit_interaction",
|
|
285
|
+
// User decision trees — truncation breaks choice clarity
|
|
286
|
+
"manage_state",
|
|
287
|
+
// Project state JSON — truncation corrupts parsed schemas
|
|
288
|
+
"code_unfold",
|
|
289
|
+
// Complete symbol implementations by AST boundary
|
|
290
|
+
"init_project",
|
|
291
|
+
// Project scaffolding templates
|
|
292
|
+
"generate_linter",
|
|
293
|
+
// Generated ESLint rules — must be syntactically complete
|
|
294
|
+
"validate_linter_config",
|
|
295
|
+
// Linter validation — must be structurally complete
|
|
296
|
+
"generate_agent_definitions",
|
|
297
|
+
// Generated agent configs (YAML/JSON)
|
|
298
|
+
"generate_slash_commands",
|
|
299
|
+
// Generated command definitions
|
|
300
|
+
"run_persona",
|
|
301
|
+
// Persona execution results with generated artifacts
|
|
302
|
+
"generate_persona_artifacts",
|
|
303
|
+
// Generated configs, CI workflows
|
|
304
|
+
"manage_roadmap"
|
|
305
|
+
// Structured roadmap with cross-references and dependencies
|
|
306
|
+
]);
|
|
271
307
|
function wrapWithCompaction(toolName, handler) {
|
|
272
308
|
return async (input) => {
|
|
273
309
|
if (toolName === "compact") {
|
|
@@ -278,7 +314,10 @@ function wrapWithCompaction(toolName, handler) {
|
|
|
278
314
|
}
|
|
279
315
|
const result = await handler(input);
|
|
280
316
|
try {
|
|
281
|
-
|
|
317
|
+
if (LOSSLESS_ONLY_TOOLS.has(toolName)) {
|
|
318
|
+
return compactResultWith(result, LOSSLESS_PIPELINE);
|
|
319
|
+
}
|
|
320
|
+
return compactResultWith(result, DEFAULT_PIPELINE, DEFAULT_TOKEN_BUDGET);
|
|
282
321
|
} catch {
|
|
283
322
|
return result;
|
|
284
323
|
}
|
|
@@ -307,7 +346,7 @@ var generateLinterDefinition = {
|
|
|
307
346
|
};
|
|
308
347
|
async function handleGenerateLinter(input) {
|
|
309
348
|
try {
|
|
310
|
-
const { generate } = await import("./dist-
|
|
349
|
+
const { generate } = await import("./dist-ABTKRYZH.js");
|
|
311
350
|
const result = await generate({
|
|
312
351
|
configPath: sanitizePath(input.configPath),
|
|
313
352
|
...input.outputDir !== void 0 && { outputDir: sanitizePath(input.outputDir) }
|
|
@@ -341,7 +380,7 @@ var validateLinterConfigDefinition = {
|
|
|
341
380
|
};
|
|
342
381
|
async function handleValidateLinterConfig(input) {
|
|
343
382
|
try {
|
|
344
|
-
const { validate } = await import("./dist-
|
|
383
|
+
const { validate } = await import("./dist-ABTKRYZH.js");
|
|
345
384
|
const result = await validate({ configPath: sanitizePath(input.configPath) });
|
|
346
385
|
if ("success" in result && result.success) {
|
|
347
386
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
@@ -539,6 +578,9 @@ skills-index.json
|
|
|
539
578
|
stack-profile.json
|
|
540
579
|
metrics/
|
|
541
580
|
events.jsonl
|
|
581
|
+
.install-id
|
|
582
|
+
telemetry.json
|
|
583
|
+
.telemetry-notice-shown
|
|
542
584
|
`;
|
|
543
585
|
fs.mkdirSync(path.dirname(gitignorePath), { recursive: true });
|
|
544
586
|
fs.writeFileSync(gitignorePath, content);
|
|
@@ -651,7 +693,7 @@ ${skippedMsg}`
|
|
|
651
693
|
async function handleInitProject(input) {
|
|
652
694
|
const i = input;
|
|
653
695
|
try {
|
|
654
|
-
const { TemplateEngine } = await import("./engine-
|
|
696
|
+
const { TemplateEngine } = await import("./engine-MJJAP5CH.js");
|
|
655
697
|
const engine = new TemplateEngine(resolveTemplatesDir());
|
|
656
698
|
const safePath = sanitizePath(i.path);
|
|
657
699
|
const detected = tryDetectFramework(engine, safePath, i);
|
|
@@ -665,6 +707,7 @@ async function handleInitProject(input) {
|
|
|
665
707
|
}
|
|
666
708
|
|
|
667
709
|
// src/mcp/tools/persona.ts
|
|
710
|
+
init_dist();
|
|
668
711
|
import * as path3 from "path";
|
|
669
712
|
var listPersonasDefinition = {
|
|
670
713
|
name: "list_personas",
|
|
@@ -672,7 +715,7 @@ var listPersonasDefinition = {
|
|
|
672
715
|
inputSchema: { type: "object", properties: {} }
|
|
673
716
|
};
|
|
674
717
|
async function handleListPersonas() {
|
|
675
|
-
const { listPersonas } = await import("./loader-
|
|
718
|
+
const { listPersonas } = await import("./loader-JVSJZSWZ.js");
|
|
676
719
|
const result = listPersonas(resolvePersonasDir());
|
|
677
720
|
return resultToMcpResponse(result);
|
|
678
721
|
}
|
|
@@ -696,10 +739,10 @@ async function handleGeneratePersonaArtifacts(input) {
|
|
|
696
739
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.name)) {
|
|
697
740
|
return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.name}`)));
|
|
698
741
|
}
|
|
699
|
-
const { loadPersona } = await import("./loader-
|
|
700
|
-
const { generateRuntime } = await import("./runtime-
|
|
701
|
-
const { generateAgentsMd } = await import("./agents-md-
|
|
702
|
-
const { generateCIWorkflow } = await import("./ci-workflow-
|
|
742
|
+
const { loadPersona } = await import("./loader-JVSJZSWZ.js");
|
|
743
|
+
const { generateRuntime } = await import("./runtime-D6YUQPP2.js");
|
|
744
|
+
const { generateAgentsMd } = await import("./agents-md-MCUM4SIZ.js");
|
|
745
|
+
const { generateCIWorkflow } = await import("./ci-workflow-RTM7VVTD.js");
|
|
703
746
|
const personasDir = resolvePersonasDir();
|
|
704
747
|
const filePath = path3.join(personasDir, `${input.name}.yaml`);
|
|
705
748
|
if (!filePath.startsWith(personasDir)) {
|
|
@@ -754,9 +797,9 @@ async function handleRunPersona(input) {
|
|
|
754
797
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.persona)) {
|
|
755
798
|
return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.persona}`)));
|
|
756
799
|
}
|
|
757
|
-
const { loadPersona } = await import("./loader-
|
|
758
|
-
const { runPersona } = await import("./runner-
|
|
759
|
-
const { executeSkill } = await import("./skill-executor-
|
|
800
|
+
const { loadPersona } = await import("./loader-JVSJZSWZ.js");
|
|
801
|
+
const { runPersona } = await import("./runner-AAEF2TXY.js");
|
|
802
|
+
const { executeSkill } = await import("./skill-executor-MOCUIAYS.js");
|
|
760
803
|
const personasDir = resolvePersonasDir();
|
|
761
804
|
const filePath = path3.join(personasDir, `${input.persona}.yaml`);
|
|
762
805
|
if (!filePath.startsWith(personasDir)) {
|
|
@@ -766,7 +809,7 @@ async function handleRunPersona(input) {
|
|
|
766
809
|
if (!personaResult.ok) return resultToMcpResponse(personaResult);
|
|
767
810
|
const projectPath = input.path ? sanitizePath(input.path) : process.cwd();
|
|
768
811
|
const trigger = input.trigger ?? "auto";
|
|
769
|
-
const { ALLOWED_PERSONA_COMMANDS } = await import("./constants-
|
|
812
|
+
const { ALLOWED_PERSONA_COMMANDS } = await import("./constants-P4M3C2T3.js");
|
|
770
813
|
const commandExecutor = async (command) => {
|
|
771
814
|
if (!ALLOWED_PERSONA_COMMANDS.has(command)) {
|
|
772
815
|
return Err(new Error(`Unknown harness command: ${command}`));
|
|
@@ -920,6 +963,7 @@ async function handleRunAgentTask(input) {
|
|
|
920
963
|
}
|
|
921
964
|
|
|
922
965
|
// src/mcp/tools/skill.ts
|
|
966
|
+
init_dist();
|
|
923
967
|
import * as fs5 from "fs";
|
|
924
968
|
import * as path6 from "path";
|
|
925
969
|
import { parse as parseYaml } from "yaml";
|
|
@@ -1134,7 +1178,6 @@ function parseSkillEntry(yamlPath, source, tierOverrides) {
|
|
|
1134
1178
|
const meta = result.data;
|
|
1135
1179
|
const effectiveTier = tierOverrides?.[meta.name] ?? meta.tier;
|
|
1136
1180
|
if (meta.internal) return null;
|
|
1137
|
-
if (effectiveTier !== 3 && source !== "community") return null;
|
|
1138
1181
|
return {
|
|
1139
1182
|
tier: effectiveTier ?? 3,
|
|
1140
1183
|
type: meta.type,
|
|
@@ -1147,7 +1190,13 @@ function parseSkillEntry(yamlPath, source, tierOverrides) {
|
|
|
1147
1190
|
relatedSkills: meta.related_skills ?? [],
|
|
1148
1191
|
source,
|
|
1149
1192
|
addresses: meta.addresses ?? [],
|
|
1150
|
-
dependsOn: meta.depends_on ?? []
|
|
1193
|
+
dependsOn: meta.depends_on ?? [],
|
|
1194
|
+
...meta.context_budget && {
|
|
1195
|
+
contextBudget: {
|
|
1196
|
+
maxTokens: meta.context_budget.max_tokens,
|
|
1197
|
+
priority: meta.context_budget.priority
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1151
1200
|
};
|
|
1152
1201
|
}
|
|
1153
1202
|
function scanDirectory(dir, source, index, tierOverrides) {
|
|
@@ -1325,6 +1374,30 @@ async function handleRunSkill(input) {
|
|
|
1325
1374
|
return resultToMcpResponse(Err(new Error(`SKILL.md not found for skill: ${input.skill}`)));
|
|
1326
1375
|
}
|
|
1327
1376
|
let content = fs5.readFileSync(skillMdPath, "utf-8");
|
|
1377
|
+
const projectRoot = input.path ? sanitizePath(input.path) : process.cwd();
|
|
1378
|
+
const configResult = resolveConfig();
|
|
1379
|
+
const skillsConfig = configResult.ok ? configResult.value.skills : void 0;
|
|
1380
|
+
let sharedIndex;
|
|
1381
|
+
try {
|
|
1382
|
+
sharedIndex = loadOrRebuildIndex("claude-code", projectRoot, skillsConfig?.tierOverrides);
|
|
1383
|
+
const plan = computeLoadPlan(
|
|
1384
|
+
Object.entries(sharedIndex.skills).map(([name, entry]) => {
|
|
1385
|
+
const skill = { name };
|
|
1386
|
+
if (entry.contextBudget) {
|
|
1387
|
+
skill.budget = {
|
|
1388
|
+
max_tokens: entry.contextBudget.maxTokens,
|
|
1389
|
+
priority: entry.contextBudget.priority
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
return skill;
|
|
1393
|
+
})
|
|
1394
|
+
);
|
|
1395
|
+
const skillPlan = plan.find((p) => p.skillName === input.skill);
|
|
1396
|
+
if (skillPlan && skillPlan.level < 5) {
|
|
1397
|
+
content = extractLevel(content, skillPlan.level);
|
|
1398
|
+
}
|
|
1399
|
+
} catch {
|
|
1400
|
+
}
|
|
1328
1401
|
if (input.path) {
|
|
1329
1402
|
const projectPath = sanitizePath(input.path);
|
|
1330
1403
|
const stateFile = path6.join(projectPath, ".harness", "state.json");
|
|
@@ -1356,11 +1429,7 @@ ${stateContent}
|
|
|
1356
1429
|
}
|
|
1357
1430
|
if (isTier1Skill(input.skill)) {
|
|
1358
1431
|
try {
|
|
1359
|
-
const
|
|
1360
|
-
const platform = "claude-code";
|
|
1361
|
-
const configResult = resolveConfig();
|
|
1362
|
-
const skillsConfig = configResult.ok ? configResult.value.skills : void 0;
|
|
1363
|
-
const index = loadOrRebuildIndex(platform, projectRoot, skillsConfig?.tierOverrides);
|
|
1432
|
+
const index = sharedIndex ?? loadOrRebuildIndex("claude-code", projectRoot, skillsConfig?.tierOverrides);
|
|
1364
1433
|
const profile = loadOrGenerateProfile(projectRoot);
|
|
1365
1434
|
const taskDesc = [input.skill, input.phase].filter(Boolean).join(" ");
|
|
1366
1435
|
const result = suggest(index, taskDesc, profile, [], skillsConfig);
|
|
@@ -1400,7 +1469,7 @@ var createSkillDefinition = {
|
|
|
1400
1469
|
};
|
|
1401
1470
|
async function handleCreateSkill(input) {
|
|
1402
1471
|
try {
|
|
1403
|
-
const { generateSkillFiles } = await import("./create-skill-
|
|
1472
|
+
const { generateSkillFiles } = await import("./create-skill-6QWJHQYS.js");
|
|
1404
1473
|
const result = generateSkillFiles({
|
|
1405
1474
|
name: input.name,
|
|
1406
1475
|
description: input.description,
|
|
@@ -1511,14 +1580,18 @@ async function getLearningsResource(projectRoot) {
|
|
|
1511
1580
|
return sections.length > 0 ? sections.join("\n\n---\n\n") : "No learnings files found.";
|
|
1512
1581
|
}
|
|
1513
1582
|
|
|
1583
|
+
// src/mcp/tools/state.ts
|
|
1584
|
+
init_dist();
|
|
1585
|
+
|
|
1514
1586
|
// src/mcp/tools/roadmap-auto-sync.ts
|
|
1587
|
+
init_dist();
|
|
1515
1588
|
import * as fs10 from "fs";
|
|
1516
1589
|
import * as path11 from "path";
|
|
1517
1590
|
async function autoSyncRoadmap(projectPath) {
|
|
1518
1591
|
try {
|
|
1519
1592
|
const roadmapFile = path11.join(projectPath, "docs", "roadmap.md");
|
|
1520
1593
|
if (!fs10.existsSync(roadmapFile)) return;
|
|
1521
|
-
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-
|
|
1594
|
+
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-WCSJHQPK.js");
|
|
1522
1595
|
const raw = fs10.readFileSync(roadmapFile, "utf-8");
|
|
1523
1596
|
const parseResult = parseRoadmap(raw);
|
|
1524
1597
|
if (!parseResult.ok) return;
|
|
@@ -1536,7 +1609,7 @@ async function autoSyncRoadmap(projectPath) {
|
|
|
1536
1609
|
}
|
|
1537
1610
|
async function triggerExternalSync(projectPath, roadmapFile) {
|
|
1538
1611
|
try {
|
|
1539
|
-
const trackerConfig =
|
|
1612
|
+
const trackerConfig = loadTrackerSyncConfig(projectPath);
|
|
1540
1613
|
if (!trackerConfig) return;
|
|
1541
1614
|
const projectEnvPath = path11.join(projectPath, ".env");
|
|
1542
1615
|
if (fs10.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
|
|
@@ -1544,8 +1617,11 @@ async function triggerExternalSync(projectPath, roadmapFile) {
|
|
|
1544
1617
|
loadDotenv({ path: projectEnvPath });
|
|
1545
1618
|
}
|
|
1546
1619
|
const token = process.env.GITHUB_TOKEN;
|
|
1547
|
-
if (!token)
|
|
1548
|
-
|
|
1620
|
+
if (!token) {
|
|
1621
|
+
console.warn("[roadmap-sync] GITHUB_TOKEN not found \u2014 external sync skipped");
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1624
|
+
const { fullSync, GitHubIssuesSyncAdapter } = await import("./dist-WCSJHQPK.js");
|
|
1549
1625
|
const adapter = new GitHubIssuesSyncAdapter({
|
|
1550
1626
|
token,
|
|
1551
1627
|
config: trackerConfig
|
|
@@ -1564,21 +1640,6 @@ async function triggerExternalSync(projectPath, roadmapFile) {
|
|
|
1564
1640
|
);
|
|
1565
1641
|
}
|
|
1566
1642
|
}
|
|
1567
|
-
function loadTrackerConfig(projectPath) {
|
|
1568
|
-
try {
|
|
1569
|
-
const configPath = path11.join(projectPath, "harness.config.json");
|
|
1570
|
-
if (!fs10.existsSync(configPath)) return null;
|
|
1571
|
-
const raw = fs10.readFileSync(configPath, "utf-8");
|
|
1572
|
-
const config = JSON.parse(raw);
|
|
1573
|
-
const trackerRaw = config.roadmap?.tracker;
|
|
1574
|
-
if (!trackerRaw) return null;
|
|
1575
|
-
const parsed = TrackerConfigSchema.safeParse(trackerRaw);
|
|
1576
|
-
if (!parsed.success) return null;
|
|
1577
|
-
return parsed.data;
|
|
1578
|
-
} catch {
|
|
1579
|
-
return null;
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
1643
|
|
|
1583
1644
|
// src/mcp/utils.ts
|
|
1584
1645
|
function mcpError(text) {
|
|
@@ -1657,12 +1718,12 @@ var manageStateDefinition = {
|
|
|
1657
1718
|
}
|
|
1658
1719
|
};
|
|
1659
1720
|
async function handleShow(projectPath, input) {
|
|
1660
|
-
const { loadState } = await import("./dist-
|
|
1721
|
+
const { loadState } = await import("./dist-WCSJHQPK.js");
|
|
1661
1722
|
return resultToMcpResponse(await loadState(projectPath, input.stream, input.session));
|
|
1662
1723
|
}
|
|
1663
1724
|
async function handleLearn(projectPath, input) {
|
|
1664
1725
|
if (!input.learning) return mcpError("Error: learning is required for learn action");
|
|
1665
|
-
const { appendLearning } = await import("./dist-
|
|
1726
|
+
const { appendLearning } = await import("./dist-WCSJHQPK.js");
|
|
1666
1727
|
const result = await appendLearning(
|
|
1667
1728
|
projectPath,
|
|
1668
1729
|
input.learning,
|
|
@@ -1677,7 +1738,7 @@ async function handleLearn(projectPath, input) {
|
|
|
1677
1738
|
async function handleFailure(projectPath, input) {
|
|
1678
1739
|
if (!input.description) return mcpError("Error: description is required for failure action");
|
|
1679
1740
|
if (!input.failureType) return mcpError("Error: failureType is required for failure action");
|
|
1680
|
-
const { appendFailure } = await import("./dist-
|
|
1741
|
+
const { appendFailure } = await import("./dist-WCSJHQPK.js");
|
|
1681
1742
|
const result = await appendFailure(
|
|
1682
1743
|
projectPath,
|
|
1683
1744
|
input.description,
|
|
@@ -1690,24 +1751,24 @@ async function handleFailure(projectPath, input) {
|
|
|
1690
1751
|
return resultToMcpResponse(Ok({ recorded: true }));
|
|
1691
1752
|
}
|
|
1692
1753
|
async function handleArchive(projectPath, input) {
|
|
1693
|
-
const { archiveFailures } = await import("./dist-
|
|
1754
|
+
const { archiveFailures } = await import("./dist-WCSJHQPK.js");
|
|
1694
1755
|
const result = await archiveFailures(projectPath, input.stream, input.session);
|
|
1695
1756
|
if (!result.ok) return resultToMcpResponse(result);
|
|
1696
1757
|
return resultToMcpResponse(Ok({ archived: true }));
|
|
1697
1758
|
}
|
|
1698
1759
|
async function handleReset(projectPath, input) {
|
|
1699
|
-
const { saveState, DEFAULT_STATE } = await import("./dist-
|
|
1760
|
+
const { saveState, DEFAULT_STATE } = await import("./dist-WCSJHQPK.js");
|
|
1700
1761
|
const result = await saveState(projectPath, { ...DEFAULT_STATE }, input.stream, input.session);
|
|
1701
1762
|
if (!result.ok) return resultToMcpResponse(result);
|
|
1702
1763
|
return resultToMcpResponse(Ok({ reset: true }));
|
|
1703
1764
|
}
|
|
1704
1765
|
async function handleGate(projectPath, _input) {
|
|
1705
|
-
const { runMechanicalGate } = await import("./dist-
|
|
1766
|
+
const { runMechanicalGate } = await import("./dist-WCSJHQPK.js");
|
|
1706
1767
|
return resultToMcpResponse(await runMechanicalGate(projectPath));
|
|
1707
1768
|
}
|
|
1708
1769
|
async function handleSaveHandoff(projectPath, input) {
|
|
1709
1770
|
if (!input.handoff) return mcpError("Error: handoff is required for save-handoff action");
|
|
1710
|
-
const { saveHandoff } = await import("./dist-
|
|
1771
|
+
const { saveHandoff } = await import("./dist-WCSJHQPK.js");
|
|
1711
1772
|
const result = await saveHandoff(
|
|
1712
1773
|
projectPath,
|
|
1713
1774
|
input.handoff,
|
|
@@ -1719,23 +1780,38 @@ async function handleSaveHandoff(projectPath, input) {
|
|
|
1719
1780
|
return resultToMcpResponse(Ok({ saved: true }));
|
|
1720
1781
|
}
|
|
1721
1782
|
async function handleLoadHandoff(projectPath, input) {
|
|
1722
|
-
const { loadHandoff } = await import("./dist-
|
|
1783
|
+
const { loadHandoff } = await import("./dist-WCSJHQPK.js");
|
|
1723
1784
|
return resultToMcpResponse(await loadHandoff(projectPath, input.stream, input.session));
|
|
1724
1785
|
}
|
|
1725
1786
|
async function handleAppendEntry(projectPath, input) {
|
|
1726
|
-
if (!input.session) return mcpError("Error: session is required for append_entry action");
|
|
1727
1787
|
if (!input.section) return mcpError("Error: section is required for append_entry action");
|
|
1728
1788
|
if (!input.authorSkill) return mcpError("Error: authorSkill is required for append_entry action");
|
|
1729
1789
|
if (!input.content) return mcpError("Error: content is required for append_entry action");
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1790
|
+
if (input.session) {
|
|
1791
|
+
const { appendSessionEntry } = await import("./dist-WCSJHQPK.js");
|
|
1792
|
+
const result = await appendSessionEntry(
|
|
1793
|
+
projectPath,
|
|
1794
|
+
input.session,
|
|
1795
|
+
input.section,
|
|
1796
|
+
input.authorSkill,
|
|
1797
|
+
input.content
|
|
1798
|
+
);
|
|
1799
|
+
return resultToMcpResponse(result);
|
|
1800
|
+
}
|
|
1801
|
+
if (input.section !== "decisions") {
|
|
1802
|
+
return mcpError("Error: session is required for non-decisions sections");
|
|
1803
|
+
}
|
|
1804
|
+
const { loadState, saveState } = await import("./dist-WCSJHQPK.js");
|
|
1805
|
+
const lr = await loadState(projectPath, input.stream);
|
|
1806
|
+
if (!lr.ok) return resultToMcpResponse(lr);
|
|
1807
|
+
lr.value.decisions.push({
|
|
1808
|
+
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1809
|
+
decision: input.content,
|
|
1810
|
+
context: input.authorSkill
|
|
1811
|
+
});
|
|
1812
|
+
const sr = await saveState(projectPath, lr.value, input.stream);
|
|
1813
|
+
if (!sr.ok) return resultToMcpResponse(sr);
|
|
1814
|
+
return resultToMcpResponse(Ok({ appended: true, target: "global-state" }));
|
|
1739
1815
|
}
|
|
1740
1816
|
async function handleUpdateEntryStatus(projectPath, input) {
|
|
1741
1817
|
if (!input.session) return mcpError("Error: session is required for update_entry_status action");
|
|
@@ -1743,7 +1819,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
|
|
|
1743
1819
|
if (!input.entryId) return mcpError("Error: entryId is required for update_entry_status action");
|
|
1744
1820
|
if (!input.newStatus)
|
|
1745
1821
|
return mcpError("Error: newStatus is required for update_entry_status action");
|
|
1746
|
-
const { updateSessionEntryStatus } = await import("./dist-
|
|
1822
|
+
const { updateSessionEntryStatus } = await import("./dist-WCSJHQPK.js");
|
|
1747
1823
|
const result = await updateSessionEntryStatus(
|
|
1748
1824
|
projectPath,
|
|
1749
1825
|
input.session,
|
|
@@ -1756,7 +1832,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
|
|
|
1756
1832
|
async function handleReadSection(projectPath, input) {
|
|
1757
1833
|
if (!input.session) return mcpError("Error: session is required for read_section action");
|
|
1758
1834
|
if (!input.section) return mcpError("Error: section is required for read_section action");
|
|
1759
|
-
const { readSessionSection } = await import("./dist-
|
|
1835
|
+
const { readSessionSection } = await import("./dist-WCSJHQPK.js");
|
|
1760
1836
|
const result = await readSessionSection(
|
|
1761
1837
|
projectPath,
|
|
1762
1838
|
input.session,
|
|
@@ -1766,13 +1842,13 @@ async function handleReadSection(projectPath, input) {
|
|
|
1766
1842
|
}
|
|
1767
1843
|
async function handleReadSections(projectPath, input) {
|
|
1768
1844
|
if (!input.session) return mcpError("Error: session is required for read_sections action");
|
|
1769
|
-
const { readSessionSections } = await import("./dist-
|
|
1845
|
+
const { readSessionSections } = await import("./dist-WCSJHQPK.js");
|
|
1770
1846
|
const result = await readSessionSections(projectPath, input.session);
|
|
1771
1847
|
return resultToMcpResponse(result);
|
|
1772
1848
|
}
|
|
1773
1849
|
async function handleArchiveSession(projectPath, input) {
|
|
1774
1850
|
if (!input.session) return mcpError("Error: session is required for archive_session action");
|
|
1775
|
-
const { archiveSession } = await import("./dist-
|
|
1851
|
+
const { archiveSession } = await import("./dist-WCSJHQPK.js");
|
|
1776
1852
|
const result = await archiveSession(projectPath, input.session);
|
|
1777
1853
|
if (!result.ok) return resultToMcpResponse(result);
|
|
1778
1854
|
await autoSyncRoadmap(projectPath);
|
|
@@ -1836,7 +1912,7 @@ var listStreamsDefinition = {
|
|
|
1836
1912
|
};
|
|
1837
1913
|
async function handleListStreams(input) {
|
|
1838
1914
|
try {
|
|
1839
|
-
const { listStreams, loadStreamIndex } = await import("./dist-
|
|
1915
|
+
const { listStreams, loadStreamIndex } = await import("./dist-WCSJHQPK.js");
|
|
1840
1916
|
const projectPath = sanitizePath(input.path);
|
|
1841
1917
|
const indexResult = await loadStreamIndex(projectPath);
|
|
1842
1918
|
const streamsResult = await listStreams(projectPath);
|
|
@@ -1874,7 +1950,7 @@ var checkPhaseGateDefinition = {
|
|
|
1874
1950
|
};
|
|
1875
1951
|
async function handleCheckPhaseGate(input) {
|
|
1876
1952
|
try {
|
|
1877
|
-
const { runCheckPhaseGate } = await import("./check-phase-gate-
|
|
1953
|
+
const { runCheckPhaseGate } = await import("./check-phase-gate-VCBQHQAC.js");
|
|
1878
1954
|
const result = await runCheckPhaseGate({ cwd: sanitizePath(input.path) });
|
|
1879
1955
|
if (result.ok) {
|
|
1880
1956
|
return { content: [{ type: "text", text: JSON.stringify(result.value) }] };
|
|
@@ -1930,7 +2006,7 @@ async function handleValidateCrossCheck(input) {
|
|
|
1930
2006
|
};
|
|
1931
2007
|
}
|
|
1932
2008
|
try {
|
|
1933
|
-
const { runCrossCheck } = await import("./validate-cross-check-
|
|
2009
|
+
const { runCrossCheck } = await import("./validate-cross-check-ZOWFA3DB.js");
|
|
1934
2010
|
const specsDir = path12.resolve(projectPath, input.specsDir ?? "docs/specs");
|
|
1935
2011
|
if (!specsDir.startsWith(projectPath)) {
|
|
1936
2012
|
return {
|
|
@@ -1967,6 +2043,9 @@ async function handleValidateCrossCheck(input) {
|
|
|
1967
2043
|
}
|
|
1968
2044
|
}
|
|
1969
2045
|
|
|
2046
|
+
// src/mcp/tools/generate-slash-commands.ts
|
|
2047
|
+
init_dist();
|
|
2048
|
+
|
|
1970
2049
|
// src/commands/generate-slash-commands.ts
|
|
1971
2050
|
import { Command } from "commander";
|
|
1972
2051
|
import fs13 from "fs";
|
|
@@ -2650,7 +2729,7 @@ async function handleGenerateSlashCommands(input) {
|
|
|
2650
2729
|
// src/mcp/resources/state.ts
|
|
2651
2730
|
async function getStateResource(projectRoot) {
|
|
2652
2731
|
try {
|
|
2653
|
-
const { loadState, migrateToStreams } = await import("./dist-
|
|
2732
|
+
const { loadState, migrateToStreams } = await import("./dist-WCSJHQPK.js");
|
|
2654
2733
|
await migrateToStreams(projectRoot);
|
|
2655
2734
|
const result = await loadState(projectRoot);
|
|
2656
2735
|
if (result.ok) {
|
|
@@ -2674,6 +2753,9 @@ async function getStateResource(projectRoot) {
|
|
|
2674
2753
|
}
|
|
2675
2754
|
}
|
|
2676
2755
|
|
|
2756
|
+
// src/mcp/tools/graph/query-graph.ts
|
|
2757
|
+
init_dist();
|
|
2758
|
+
|
|
2677
2759
|
// src/mcp/tools/graph/shared.ts
|
|
2678
2760
|
function graphNotFoundError() {
|
|
2679
2761
|
return {
|
|
@@ -2728,6 +2810,14 @@ var queryGraphDefinition = {
|
|
|
2728
2810
|
type: "string",
|
|
2729
2811
|
enum: ["summary", "detailed"],
|
|
2730
2812
|
description: "Response density: summary returns node/edge counts by type + top 10 nodes by connectivity, detailed returns full arrays. Default: detailed"
|
|
2813
|
+
},
|
|
2814
|
+
offset: {
|
|
2815
|
+
type: "number",
|
|
2816
|
+
description: "Number of nodes to skip (pagination). Default: 0. Nodes are sorted by connectivity (edge count desc)."
|
|
2817
|
+
},
|
|
2818
|
+
limit: {
|
|
2819
|
+
type: "number",
|
|
2820
|
+
description: "Max nodes to return (pagination). Default: 50."
|
|
2731
2821
|
}
|
|
2732
2822
|
},
|
|
2733
2823
|
required: ["path", "rootNodeIds"]
|
|
@@ -2757,7 +2847,7 @@ async function handleQueryGraph(input) {
|
|
|
2757
2847
|
const projectPath = sanitizePath(input.path);
|
|
2758
2848
|
const store = await loadGraphStore(projectPath);
|
|
2759
2849
|
if (!store) return graphNotFoundError();
|
|
2760
|
-
const { ContextQL } = await import("./dist-
|
|
2850
|
+
const { ContextQL } = await import("./dist-RADHOOXG.js");
|
|
2761
2851
|
const cql = new ContextQL(store);
|
|
2762
2852
|
const result = cql.execute({
|
|
2763
2853
|
rootNodeIds: input.rootNodeIds,
|
|
@@ -2776,8 +2866,32 @@ async function handleQueryGraph(input) {
|
|
|
2776
2866
|
pruneObservability: input.pruneObservability
|
|
2777
2867
|
}
|
|
2778
2868
|
});
|
|
2779
|
-
|
|
2780
|
-
|
|
2869
|
+
if (input.mode === "summary") {
|
|
2870
|
+
const text = buildSummaryText(result);
|
|
2871
|
+
return { content: [{ type: "text", text }] };
|
|
2872
|
+
}
|
|
2873
|
+
const edgeCountByNode = /* @__PURE__ */ new Map();
|
|
2874
|
+
for (const edge of result.edges) {
|
|
2875
|
+
edgeCountByNode.set(edge.from, (edgeCountByNode.get(edge.from) ?? 0) + 1);
|
|
2876
|
+
edgeCountByNode.set(edge.to, (edgeCountByNode.get(edge.to) ?? 0) + 1);
|
|
2877
|
+
}
|
|
2878
|
+
const sortedNodes = [...result.nodes].sort(
|
|
2879
|
+
(a, b) => (edgeCountByNode.get(b.id) ?? 0) - (edgeCountByNode.get(a.id) ?? 0)
|
|
2880
|
+
);
|
|
2881
|
+
const offset = input.offset ?? 0;
|
|
2882
|
+
const limit = input.limit ?? 50;
|
|
2883
|
+
const paged = paginate(sortedNodes, offset, limit);
|
|
2884
|
+
const pagedNodeIds = new Set(paged.items.map((n) => n.id));
|
|
2885
|
+
const filteredEdges = result.edges.filter(
|
|
2886
|
+
(e) => pagedNodeIds.has(e.from) || pagedNodeIds.has(e.to)
|
|
2887
|
+
);
|
|
2888
|
+
const response = {
|
|
2889
|
+
nodes: paged.items,
|
|
2890
|
+
edges: filteredEdges,
|
|
2891
|
+
stats: result.stats,
|
|
2892
|
+
pagination: paged.pagination
|
|
2893
|
+
};
|
|
2894
|
+
return { content: [{ type: "text", text: JSON.stringify(response) }] };
|
|
2781
2895
|
} catch (error) {
|
|
2782
2896
|
return {
|
|
2783
2897
|
content: [
|
|
@@ -2815,7 +2929,7 @@ async function handleSearchSimilar(input) {
|
|
|
2815
2929
|
const projectPath = sanitizePath(input.path);
|
|
2816
2930
|
const store = await loadGraphStore(projectPath);
|
|
2817
2931
|
if (!store) return graphNotFoundError();
|
|
2818
|
-
const { FusionLayer } = await import("./dist-
|
|
2932
|
+
const { FusionLayer } = await import("./dist-RADHOOXG.js");
|
|
2819
2933
|
const fusion = new FusionLayer(store);
|
|
2820
2934
|
const results = fusion.search(input.query, input.topK ?? 10);
|
|
2821
2935
|
if (input.mode === "summary") {
|
|
@@ -2870,7 +2984,7 @@ async function handleFindContextFor(input) {
|
|
|
2870
2984
|
const projectPath = sanitizePath(input.path);
|
|
2871
2985
|
const store = await loadGraphStore(projectPath);
|
|
2872
2986
|
if (!store) return graphNotFoundError();
|
|
2873
|
-
const { FusionLayer, ContextQL } = await import("./dist-
|
|
2987
|
+
const { FusionLayer, ContextQL } = await import("./dist-RADHOOXG.js");
|
|
2874
2988
|
const fusion = new FusionLayer(store);
|
|
2875
2989
|
const cql = new ContextQL(store);
|
|
2876
2990
|
const tokenBudget = input.tokenBudget ?? 4e3;
|
|
@@ -2938,6 +3052,7 @@ async function handleFindContextFor(input) {
|
|
|
2938
3052
|
}
|
|
2939
3053
|
|
|
2940
3054
|
// src/mcp/tools/graph/get-relationships.ts
|
|
3055
|
+
init_dist();
|
|
2941
3056
|
var getRelationshipsDefinition = {
|
|
2942
3057
|
name: "get_relationships",
|
|
2943
3058
|
description: "Get relationships for a specific node in the knowledge graph, with configurable direction and depth.",
|
|
@@ -2956,6 +3071,14 @@ var getRelationshipsDefinition = {
|
|
|
2956
3071
|
type: "string",
|
|
2957
3072
|
enum: ["summary", "detailed"],
|
|
2958
3073
|
description: "Response density: summary returns neighbor counts by type + direct neighbors only, detailed returns full traversal. Default: detailed"
|
|
3074
|
+
},
|
|
3075
|
+
offset: {
|
|
3076
|
+
type: "number",
|
|
3077
|
+
description: "Number of edges to skip (pagination). Default: 0. Edges are sorted by weight (confidence desc)."
|
|
3078
|
+
},
|
|
3079
|
+
limit: {
|
|
3080
|
+
type: "number",
|
|
3081
|
+
description: "Max edges to return (pagination). Default: 50."
|
|
2959
3082
|
}
|
|
2960
3083
|
},
|
|
2961
3084
|
required: ["path", "nodeId"]
|
|
@@ -2966,7 +3089,7 @@ async function handleGetRelationships(input) {
|
|
|
2966
3089
|
const projectPath = sanitizePath(input.path);
|
|
2967
3090
|
const store = await loadGraphStore(projectPath);
|
|
2968
3091
|
if (!store) return graphNotFoundError();
|
|
2969
|
-
const { ContextQL } = await import("./dist-
|
|
3092
|
+
const { ContextQL } = await import("./dist-RADHOOXG.js");
|
|
2970
3093
|
const cql = new ContextQL(store);
|
|
2971
3094
|
const direction = input.direction ?? "both";
|
|
2972
3095
|
const bidirectional = direction === "both" || direction === "inbound";
|
|
@@ -3006,6 +3129,12 @@ async function handleGetRelationships(input) {
|
|
|
3006
3129
|
]
|
|
3007
3130
|
};
|
|
3008
3131
|
}
|
|
3132
|
+
const sortedEdges = [...filteredEdges].sort(
|
|
3133
|
+
(a, b) => (b.confidence ?? 1) - (a.confidence ?? 1)
|
|
3134
|
+
);
|
|
3135
|
+
const offset = input.offset ?? 0;
|
|
3136
|
+
const limit = input.limit ?? 50;
|
|
3137
|
+
const paged = paginate(sortedEdges, offset, limit);
|
|
3009
3138
|
return {
|
|
3010
3139
|
content: [
|
|
3011
3140
|
{
|
|
@@ -3014,9 +3143,15 @@ async function handleGetRelationships(input) {
|
|
|
3014
3143
|
nodeId: input.nodeId,
|
|
3015
3144
|
direction,
|
|
3016
3145
|
depth: input.depth ?? 1,
|
|
3017
|
-
nodes
|
|
3018
|
-
|
|
3019
|
-
|
|
3146
|
+
// Filter nodes to only those referenced by paginated edges
|
|
3147
|
+
nodes: filteredNodes.filter(
|
|
3148
|
+
(n) => paged.items.some(
|
|
3149
|
+
(e) => e.from === n.id || e.to === n.id
|
|
3150
|
+
)
|
|
3151
|
+
),
|
|
3152
|
+
edges: paged.items,
|
|
3153
|
+
stats: result.stats,
|
|
3154
|
+
pagination: paged.pagination
|
|
3020
3155
|
})
|
|
3021
3156
|
}
|
|
3022
3157
|
]
|
|
@@ -3072,7 +3207,7 @@ async function handleGetImpact(input) {
|
|
|
3072
3207
|
const projectPath = sanitizePath(input.path);
|
|
3073
3208
|
const store = await loadGraphStore(projectPath);
|
|
3074
3209
|
if (!store) return graphNotFoundError();
|
|
3075
|
-
const { ContextQL } = await import("./dist-
|
|
3210
|
+
const { ContextQL } = await import("./dist-RADHOOXG.js");
|
|
3076
3211
|
let targetNodeId = input.nodeId;
|
|
3077
3212
|
if (!targetNodeId && input.filePath) {
|
|
3078
3213
|
const fileNodes = store.findNodes({ type: "file" });
|
|
@@ -3204,7 +3339,7 @@ async function handleIngestSource(input) {
|
|
|
3204
3339
|
try {
|
|
3205
3340
|
const projectPath = sanitizePath(input.path);
|
|
3206
3341
|
const graphDir = path16.join(projectPath, ".harness", "graph");
|
|
3207
|
-
const { GraphStore, CodeIngestor, TopologicalLinker, KnowledgeIngestor, GitIngestor } = await import("./dist-
|
|
3342
|
+
const { GraphStore, CodeIngestor, TopologicalLinker, KnowledgeIngestor, GitIngestor } = await import("./dist-RADHOOXG.js");
|
|
3208
3343
|
const fs17 = await import("fs/promises");
|
|
3209
3344
|
await fs17.mkdir(graphDir, { recursive: true });
|
|
3210
3345
|
const store = new GraphStore();
|
|
@@ -3257,6 +3392,7 @@ async function handleIngestSource(input) {
|
|
|
3257
3392
|
}
|
|
3258
3393
|
|
|
3259
3394
|
// src/mcp/tools/graph/detect-anomalies.ts
|
|
3395
|
+
init_dist();
|
|
3260
3396
|
var detectAnomaliesDefinition = {
|
|
3261
3397
|
name: "detect_anomalies",
|
|
3262
3398
|
description: "Detect structural anomalies \u2014 statistical outliers across code metrics and topological single points of failure in the import graph",
|
|
@@ -3269,6 +3405,14 @@ var detectAnomaliesDefinition = {
|
|
|
3269
3405
|
type: "array",
|
|
3270
3406
|
items: { type: "string" },
|
|
3271
3407
|
description: "Metrics to analyze (default: cyclomaticComplexity, fanIn, fanOut, hotspotScore, transitiveDepth)"
|
|
3408
|
+
},
|
|
3409
|
+
offset: {
|
|
3410
|
+
type: "number",
|
|
3411
|
+
description: "Number of anomaly entries to skip (pagination). Default: 0. Anomalies are sorted by Z-score desc."
|
|
3412
|
+
},
|
|
3413
|
+
limit: {
|
|
3414
|
+
type: "number",
|
|
3415
|
+
description: "Max anomaly entries to return (pagination). Default: 30."
|
|
3272
3416
|
}
|
|
3273
3417
|
},
|
|
3274
3418
|
required: ["path"]
|
|
@@ -3279,14 +3423,23 @@ async function handleDetectAnomalies(input) {
|
|
|
3279
3423
|
const projectPath = sanitizePath(input.path);
|
|
3280
3424
|
const store = await loadGraphStore(projectPath);
|
|
3281
3425
|
if (!store) return graphNotFoundError();
|
|
3282
|
-
const { GraphAnomalyAdapter } = await import("./dist-
|
|
3426
|
+
const { GraphAnomalyAdapter } = await import("./dist-RADHOOXG.js");
|
|
3283
3427
|
const adapter = new GraphAnomalyAdapter(store);
|
|
3284
3428
|
const report = adapter.detect({
|
|
3285
3429
|
...input.threshold !== void 0 && { threshold: input.threshold },
|
|
3286
3430
|
...input.metrics !== void 0 && { metrics: input.metrics }
|
|
3287
3431
|
});
|
|
3432
|
+
const offset = input.offset ?? 0;
|
|
3433
|
+
const limit = input.limit ?? 30;
|
|
3434
|
+
const paged = paginate(report.statisticalOutliers, offset, limit);
|
|
3435
|
+
const { statisticalOutliers: _fullOutliers, ...rest } = report;
|
|
3436
|
+
const response = {
|
|
3437
|
+
...rest,
|
|
3438
|
+
statisticalOutliers: paged.items,
|
|
3439
|
+
pagination: paged.pagination
|
|
3440
|
+
};
|
|
3288
3441
|
return {
|
|
3289
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
3442
|
+
content: [{ type: "text", text: JSON.stringify(response) }]
|
|
3290
3443
|
};
|
|
3291
3444
|
} catch (error) {
|
|
3292
3445
|
return {
|
|
@@ -3319,7 +3472,7 @@ async function handleAskGraph(input) {
|
|
|
3319
3472
|
const projectPath = sanitizePath(input.path);
|
|
3320
3473
|
const store = await loadGraphStore(projectPath);
|
|
3321
3474
|
if (!store) return graphNotFoundError();
|
|
3322
|
-
const { askGraph } = await import("./dist-
|
|
3475
|
+
const { askGraph } = await import("./dist-RADHOOXG.js");
|
|
3323
3476
|
const result = await askGraph(store, input.question);
|
|
3324
3477
|
return {
|
|
3325
3478
|
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
@@ -3383,7 +3536,7 @@ async function handleComputeBlastRadius(input) {
|
|
|
3383
3536
|
const projectPath = sanitizePath(input.path);
|
|
3384
3537
|
const store = await loadGraphStore(projectPath);
|
|
3385
3538
|
if (!store) return graphNotFoundError();
|
|
3386
|
-
const { CascadeSimulator } = await import("./dist-
|
|
3539
|
+
const { CascadeSimulator } = await import("./dist-RADHOOXG.js");
|
|
3387
3540
|
let targetNodeId = input.nodeId;
|
|
3388
3541
|
if (!targetNodeId && input.file) {
|
|
3389
3542
|
const fileNodes = store.findNodes({ type: "file" });
|
|
@@ -3566,6 +3719,7 @@ async function getRelationshipsResource(projectRoot) {
|
|
|
3566
3719
|
}
|
|
3567
3720
|
|
|
3568
3721
|
// src/mcp/tools/agent-definitions.ts
|
|
3722
|
+
init_dist();
|
|
3569
3723
|
var generateAgentDefinitionsDefinition = {
|
|
3570
3724
|
name: "generate_agent_definitions",
|
|
3571
3725
|
description: "Generate agent definition files from personas for Claude Code and Gemini CLI",
|
|
@@ -3583,7 +3737,7 @@ var generateAgentDefinitionsDefinition = {
|
|
|
3583
3737
|
}
|
|
3584
3738
|
};
|
|
3585
3739
|
async function handleGenerateAgentDefinitions(input) {
|
|
3586
|
-
const { generateAgentDefinitions } = await import("./generate-agent-definitions-
|
|
3740
|
+
const { generateAgentDefinitions } = await import("./generate-agent-definitions-AWLPJ27C.js");
|
|
3587
3741
|
const platforms = input.platform === "all" || !input.platform ? ["claude-code", "gemini-cli"] : [input.platform];
|
|
3588
3742
|
const results = generateAgentDefinitions({
|
|
3589
3743
|
platforms: [...platforms],
|
|
@@ -3737,7 +3891,8 @@ function buildFeatureFromInput(input) {
|
|
|
3737
3891
|
summary: input.summary,
|
|
3738
3892
|
assignee: null,
|
|
3739
3893
|
priority: null,
|
|
3740
|
-
externalId: null
|
|
3894
|
+
externalId: null,
|
|
3895
|
+
updatedAt: null
|
|
3741
3896
|
};
|
|
3742
3897
|
}
|
|
3743
3898
|
function handleAdd(projectPath, input, deps) {
|
|
@@ -3910,8 +4065,8 @@ function shouldTriggerExternalSync(input, response) {
|
|
|
3910
4065
|
}
|
|
3911
4066
|
async function handleManageRoadmap(input) {
|
|
3912
4067
|
try {
|
|
3913
|
-
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges, assignFeature } = await import("./dist-
|
|
3914
|
-
const { Ok: Ok2 } = await import("./dist-
|
|
4068
|
+
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges, assignFeature } = await import("./dist-WCSJHQPK.js");
|
|
4069
|
+
const { Ok: Ok2 } = await import("./dist-3EWNRFFQ.js");
|
|
3915
4070
|
const projectPath = sanitizePath(input.path);
|
|
3916
4071
|
const deps = {
|
|
3917
4072
|
parseRoadmap,
|
|
@@ -4345,7 +4500,7 @@ async function handleTransition(validInput, projectPath, id) {
|
|
|
4345
4500
|
const transition = transitionResult.data;
|
|
4346
4501
|
const prompt = renderTransition(transition);
|
|
4347
4502
|
try {
|
|
4348
|
-
const { saveHandoff } = await import("./dist-
|
|
4503
|
+
const { saveHandoff } = await import("./dist-WCSJHQPK.js");
|
|
4349
4504
|
await saveHandoff(
|
|
4350
4505
|
projectPath,
|
|
4351
4506
|
{
|
|
@@ -4413,7 +4568,7 @@ async function handleEmitInteraction(input) {
|
|
|
4413
4568
|
}
|
|
4414
4569
|
async function recordInteraction(projectPath, id, type, decision, stream) {
|
|
4415
4570
|
try {
|
|
4416
|
-
const { loadState, saveState } = await import("./dist-
|
|
4571
|
+
const { loadState, saveState } = await import("./dist-WCSJHQPK.js");
|
|
4417
4572
|
const stateResult = await loadState(projectPath, stream);
|
|
4418
4573
|
if (stateResult.ok) {
|
|
4419
4574
|
const state = stateResult.value;
|
|
@@ -4429,6 +4584,51 @@ async function recordInteraction(projectPath, id, type, decision, stream) {
|
|
|
4429
4584
|
}
|
|
4430
4585
|
|
|
4431
4586
|
// src/mcp/tools/gather-context.ts
|
|
4587
|
+
init_dist();
|
|
4588
|
+
function flattenSessionSections(sections) {
|
|
4589
|
+
if (!sections) return [];
|
|
4590
|
+
return Object.entries(sections).flatMap(
|
|
4591
|
+
([name, entries]) => Array.isArray(entries) ? entries.map((e) => ({ sectionName: name, ...e })) : []
|
|
4592
|
+
);
|
|
4593
|
+
}
|
|
4594
|
+
function sectionItems(input) {
|
|
4595
|
+
if (input.section === "graphContext") {
|
|
4596
|
+
const blocks = input.graphContext?.context ?? [];
|
|
4597
|
+
return [...blocks].sort((a, b) => b.score - a.score);
|
|
4598
|
+
}
|
|
4599
|
+
if (input.section === "learnings") {
|
|
4600
|
+
return Array.isArray(input.learnings) ? input.learnings : [];
|
|
4601
|
+
}
|
|
4602
|
+
const flat = flattenSessionSections(input.sessionSections);
|
|
4603
|
+
return flat.sort((a, b) => (b.timestamp ?? "").localeCompare(a.timestamp ?? ""));
|
|
4604
|
+
}
|
|
4605
|
+
function checkSectionGuards(section, mode) {
|
|
4606
|
+
if (section === "graphContext" && (mode ?? "summary") === "summary") {
|
|
4607
|
+
return {
|
|
4608
|
+
content: [
|
|
4609
|
+
{
|
|
4610
|
+
type: "text",
|
|
4611
|
+
text: JSON.stringify({
|
|
4612
|
+
error: "section=graphContext requires mode=detailed. Summary mode aggregates graph blocks into counts \u2014 there are no paginatable items.",
|
|
4613
|
+
hint: 'Pass mode="detailed" to paginate graphContext blocks.'
|
|
4614
|
+
})
|
|
4615
|
+
}
|
|
4616
|
+
],
|
|
4617
|
+
isError: true
|
|
4618
|
+
};
|
|
4619
|
+
}
|
|
4620
|
+
return null;
|
|
4621
|
+
}
|
|
4622
|
+
function paginateSection(input) {
|
|
4623
|
+
const items = sectionItems(input);
|
|
4624
|
+
const paged = paginate(items, input.offset, input.limit);
|
|
4625
|
+
return {
|
|
4626
|
+
section: input.section,
|
|
4627
|
+
items: paged.items,
|
|
4628
|
+
pagination: paged.pagination,
|
|
4629
|
+
meta: input.meta
|
|
4630
|
+
};
|
|
4631
|
+
}
|
|
4432
4632
|
var gatherContextDefinition = {
|
|
4433
4633
|
name: "gather_context",
|
|
4434
4634
|
description: "Assemble all working context an agent needs in a single call: state, learnings, handoff, graph context, project validation, and session sections. Runs constituents in parallel.",
|
|
@@ -4477,6 +4677,19 @@ var gatherContextDefinition = {
|
|
|
4477
4677
|
type: "string",
|
|
4478
4678
|
enum: ["index", "summary", "full"],
|
|
4479
4679
|
description: 'Retrieval depth for learnings. "index" returns one-line summaries, "summary" (default) returns full entries, "full" returns entries with linked context.'
|
|
4680
|
+
},
|
|
4681
|
+
section: {
|
|
4682
|
+
type: "string",
|
|
4683
|
+
enum: ["graphContext", "learnings", "sessionSections"],
|
|
4684
|
+
description: "Section to paginate. When provided, offset/limit apply within this section only and the response contains only { section, items, pagination, meta }. Note: section=graphContext requires mode=detailed (summary mode has no paginatable blocks). When omitted, returns the full response."
|
|
4685
|
+
},
|
|
4686
|
+
offset: {
|
|
4687
|
+
type: "number",
|
|
4688
|
+
description: "Number of items to skip within the section (pagination). Default: 0. Requires section param."
|
|
4689
|
+
},
|
|
4690
|
+
limit: {
|
|
4691
|
+
type: "number",
|
|
4692
|
+
description: "Max items to return within the section (pagination). Default: 20. Requires section param."
|
|
4480
4693
|
}
|
|
4481
4694
|
},
|
|
4482
4695
|
required: ["path", "intent"]
|
|
@@ -4502,10 +4715,10 @@ async function handleGatherContext(input) {
|
|
|
4502
4715
|
input.include ?? ["state", "learnings", "handoff", "graph", "validation"]
|
|
4503
4716
|
);
|
|
4504
4717
|
const errors = [];
|
|
4505
|
-
const statePromise = includeSet.has("state") ? import("./dist-
|
|
4718
|
+
const statePromise = includeSet.has("state") ? import("./dist-WCSJHQPK.js").then(
|
|
4506
4719
|
(core) => core.loadState(projectPath, void 0, input.session)
|
|
4507
4720
|
) : Promise.resolve(null);
|
|
4508
|
-
const learningsPromise = includeSet.has("learnings") ? import("./dist-
|
|
4721
|
+
const learningsPromise = includeSet.has("learnings") ? import("./dist-WCSJHQPK.js").then(
|
|
4509
4722
|
(core) => core.loadBudgetedLearnings(projectPath, {
|
|
4510
4723
|
intent: input.intent,
|
|
4511
4724
|
tokenBudget: input.learningsBudget ?? 1e3,
|
|
@@ -4514,14 +4727,14 @@ async function handleGatherContext(input) {
|
|
|
4514
4727
|
...input.depth !== void 0 && { depth: input.depth }
|
|
4515
4728
|
})
|
|
4516
4729
|
) : Promise.resolve(null);
|
|
4517
|
-
const handoffPromise = includeSet.has("handoff") ? import("./dist-
|
|
4730
|
+
const handoffPromise = includeSet.has("handoff") ? import("./dist-WCSJHQPK.js").then(
|
|
4518
4731
|
(core) => core.loadHandoff(projectPath, void 0, input.session)
|
|
4519
4732
|
) : Promise.resolve(null);
|
|
4520
4733
|
const graphPromise = includeSet.has("graph") ? (async () => {
|
|
4521
|
-
const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-
|
|
4734
|
+
const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-JHQVQRUS.js");
|
|
4522
4735
|
const store = await loadGraphStore2(projectPath);
|
|
4523
4736
|
if (!store) return null;
|
|
4524
|
-
const { FusionLayer, ContextQL } = await import("./dist-
|
|
4737
|
+
const { FusionLayer, ContextQL } = await import("./dist-RADHOOXG.js");
|
|
4525
4738
|
const fusion = new FusionLayer(store);
|
|
4526
4739
|
const cql = new ContextQL(store);
|
|
4527
4740
|
const tokenBudget = input.tokenBudget ?? 4e3;
|
|
@@ -4558,11 +4771,11 @@ async function handleGatherContext(input) {
|
|
|
4558
4771
|
context: contextBlocks
|
|
4559
4772
|
};
|
|
4560
4773
|
})() : Promise.resolve(null);
|
|
4561
|
-
const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-
|
|
4774
|
+
const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-WCSJHQPK.js").then(
|
|
4562
4775
|
(core) => core.readSessionSections(projectPath, input.session)
|
|
4563
4776
|
) : Promise.resolve(null);
|
|
4564
4777
|
const shouldIncludeEvents = input.includeEvents !== void 0 ? input.includeEvents : includeSet.has("events") || !!input.session && !input.include;
|
|
4565
|
-
const eventsPromise = shouldIncludeEvents ? import("./dist-
|
|
4778
|
+
const eventsPromise = shouldIncludeEvents ? import("./dist-WCSJHQPK.js").then(async (core) => {
|
|
4566
4779
|
const result = await core.loadEvents(projectPath, {
|
|
4567
4780
|
session: input.session
|
|
4568
4781
|
});
|
|
@@ -4570,7 +4783,7 @@ async function handleGatherContext(input) {
|
|
|
4570
4783
|
return core.formatEventTimeline(result.value);
|
|
4571
4784
|
}) : Promise.resolve(null);
|
|
4572
4785
|
const validationPromise = includeSet.has("validation") ? (async () => {
|
|
4573
|
-
const { handleValidateProject: handleValidateProject2 } = await import("./validate-
|
|
4786
|
+
const { handleValidateProject: handleValidateProject2 } = await import("./validate-TIIHRPMA.js");
|
|
4574
4787
|
const result = await handleValidateProject2({ path: projectPath });
|
|
4575
4788
|
const first = result.content[0];
|
|
4576
4789
|
return first ? JSON.parse(first.text) : null;
|
|
@@ -4664,7 +4877,7 @@ async function handleGatherContext(input) {
|
|
|
4664
4877
|
};
|
|
4665
4878
|
if (input.session) {
|
|
4666
4879
|
try {
|
|
4667
|
-
const core = await import("./dist-
|
|
4880
|
+
const core = await import("./dist-WCSJHQPK.js");
|
|
4668
4881
|
core.updateSessionIndex(
|
|
4669
4882
|
projectPath,
|
|
4670
4883
|
input.session,
|
|
@@ -4674,8 +4887,25 @@ async function handleGatherContext(input) {
|
|
|
4674
4887
|
}
|
|
4675
4888
|
}
|
|
4676
4889
|
const outputText = JSON.stringify(output);
|
|
4677
|
-
const
|
|
4678
|
-
output.meta.tokenEstimate =
|
|
4890
|
+
const totalTokenEstimate = Math.ceil(outputText.length / 4);
|
|
4891
|
+
output.meta.tokenEstimate = totalTokenEstimate;
|
|
4892
|
+
if (input.section) {
|
|
4893
|
+
const guardError = checkSectionGuards(input.section, input.mode);
|
|
4894
|
+
if (guardError) return guardError;
|
|
4895
|
+
const result = paginateSection({
|
|
4896
|
+
section: input.section,
|
|
4897
|
+
offset: input.offset ?? 0,
|
|
4898
|
+
limit: input.limit ?? 20,
|
|
4899
|
+
graphContext,
|
|
4900
|
+
learnings: Array.isArray(outputLearnings) ? outputLearnings : [],
|
|
4901
|
+
sessionSections,
|
|
4902
|
+
meta: output.meta
|
|
4903
|
+
});
|
|
4904
|
+
const wrapped = { ...result, totalTokenEstimate };
|
|
4905
|
+
return {
|
|
4906
|
+
content: [{ type: "text", text: JSON.stringify(wrapped) }]
|
|
4907
|
+
};
|
|
4908
|
+
}
|
|
4679
4909
|
return {
|
|
4680
4910
|
content: [
|
|
4681
4911
|
{
|
|
@@ -4687,6 +4917,7 @@ async function handleGatherContext(input) {
|
|
|
4687
4917
|
}
|
|
4688
4918
|
|
|
4689
4919
|
// src/mcp/tools/review-changes.ts
|
|
4920
|
+
init_dist();
|
|
4690
4921
|
var SIZE_GATE_LINES = 1e4;
|
|
4691
4922
|
var reviewChangesDefinition = {
|
|
4692
4923
|
name: "review_changes",
|
|
@@ -4708,6 +4939,14 @@ var reviewChangesDefinition = {
|
|
|
4708
4939
|
type: "string",
|
|
4709
4940
|
enum: ["summary", "detailed"],
|
|
4710
4941
|
description: "Response density. Default: summary"
|
|
4942
|
+
},
|
|
4943
|
+
offset: {
|
|
4944
|
+
type: "number",
|
|
4945
|
+
description: "Number of findings to skip (pagination). Default: 0. Findings are sorted by severity desc (error > warning > info)."
|
|
4946
|
+
},
|
|
4947
|
+
limit: {
|
|
4948
|
+
type: "number",
|
|
4949
|
+
description: "Max findings to return (pagination). Default: 20."
|
|
4711
4950
|
}
|
|
4712
4951
|
},
|
|
4713
4952
|
required: ["path", "depth"]
|
|
@@ -4776,7 +5015,7 @@ async function handleReviewChanges(input) {
|
|
|
4776
5015
|
}
|
|
4777
5016
|
try {
|
|
4778
5017
|
const reviewFn = DEPTH_HANDLERS[effectiveDepth];
|
|
4779
|
-
return await reviewFn(projectPath, diff, diffLines, downgraded);
|
|
5018
|
+
return await reviewFn(projectPath, diff, diffLines, downgraded, input.offset, input.limit);
|
|
4780
5019
|
} catch (error) {
|
|
4781
5020
|
return {
|
|
4782
5021
|
content: [
|
|
@@ -4789,12 +5028,15 @@ async function handleReviewChanges(input) {
|
|
|
4789
5028
|
};
|
|
4790
5029
|
}
|
|
4791
5030
|
}
|
|
4792
|
-
async function runQuickReview(projectPath, diff, diffLines, downgraded) {
|
|
4793
|
-
const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-
|
|
5031
|
+
async function runQuickReview(projectPath, diff, diffLines, downgraded, offset, limit) {
|
|
5032
|
+
const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-ZLUX72HD.js");
|
|
4794
5033
|
const result = await handleAnalyzeDiff2({ diff, path: projectPath });
|
|
4795
5034
|
const firstContent = result.content[0];
|
|
4796
5035
|
if (!firstContent) throw new Error("Empty analyze_diff response");
|
|
4797
5036
|
const parsed = JSON.parse(firstContent.text);
|
|
5037
|
+
const rawFindings = parsed.findings ?? parsed.warnings ?? [];
|
|
5038
|
+
const sorted = sortFindingsBySeverity(rawFindings);
|
|
5039
|
+
const paged = paginate(sorted, offset ?? 0, limit ?? 20);
|
|
4798
5040
|
return {
|
|
4799
5041
|
content: [
|
|
4800
5042
|
{
|
|
@@ -4802,7 +5044,8 @@ async function runQuickReview(projectPath, diff, diffLines, downgraded) {
|
|
|
4802
5044
|
text: JSON.stringify({
|
|
4803
5045
|
depth: "quick",
|
|
4804
5046
|
downgraded,
|
|
4805
|
-
findings:
|
|
5047
|
+
findings: paged.items,
|
|
5048
|
+
pagination: paged.pagination,
|
|
4806
5049
|
fileCount: parsed.summary?.filesChanged ?? parsed.files?.length ?? 0,
|
|
4807
5050
|
lineCount: diffLines,
|
|
4808
5051
|
...result.isError ? { error: parsed } : {}
|
|
@@ -4820,8 +5063,8 @@ function extractFileCount(diffParsed) {
|
|
|
4820
5063
|
const files = diffParsed.files;
|
|
4821
5064
|
return files?.length ?? 0;
|
|
4822
5065
|
}
|
|
4823
|
-
async function runStandardReview(projectPath, diff, diffLines, downgraded) {
|
|
4824
|
-
const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-
|
|
5066
|
+
async function runStandardReview(projectPath, diff, diffLines, downgraded, offset, limit) {
|
|
5067
|
+
const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-ZLUX72HD.js");
|
|
4825
5068
|
const [diffResult, reviewResult] = await Promise.all([
|
|
4826
5069
|
handleAnalyzeDiff2({ diff, path: projectPath }),
|
|
4827
5070
|
handleCreateSelfReview2({ path: projectPath, diff })
|
|
@@ -4835,6 +5078,8 @@ async function runStandardReview(projectPath, diff, diffLines, downgraded) {
|
|
|
4835
5078
|
...extractFindings(diffParsed, "findings", "warnings"),
|
|
4836
5079
|
...extractFindings(reviewParsed, "findings", "items")
|
|
4837
5080
|
];
|
|
5081
|
+
const sorted = sortFindingsBySeverity(findings);
|
|
5082
|
+
const paged = paginate(sorted, offset ?? 0, limit ?? 20);
|
|
4838
5083
|
return {
|
|
4839
5084
|
content: [
|
|
4840
5085
|
{
|
|
@@ -4842,7 +5087,8 @@ async function runStandardReview(projectPath, diff, diffLines, downgraded) {
|
|
|
4842
5087
|
text: JSON.stringify({
|
|
4843
5088
|
depth: "standard",
|
|
4844
5089
|
downgraded,
|
|
4845
|
-
findings,
|
|
5090
|
+
findings: paged.items,
|
|
5091
|
+
pagination: paged.pagination,
|
|
4846
5092
|
diffAnalysis: diffParsed,
|
|
4847
5093
|
selfReview: reviewParsed,
|
|
4848
5094
|
fileCount: extractFileCount(diffParsed),
|
|
@@ -4852,12 +5098,19 @@ async function runStandardReview(projectPath, diff, diffLines, downgraded) {
|
|
|
4852
5098
|
]
|
|
4853
5099
|
};
|
|
4854
5100
|
}
|
|
4855
|
-
async function runDeepReview(projectPath, diff, diffLines, _downgraded) {
|
|
4856
|
-
const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-
|
|
4857
|
-
const result = await handleRunCodeReview2({
|
|
5101
|
+
async function runDeepReview(projectPath, diff, diffLines, _downgraded, offset, limit) {
|
|
5102
|
+
const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-ZWVQJTJX.js");
|
|
5103
|
+
const result = await handleRunCodeReview2({
|
|
5104
|
+
path: projectPath,
|
|
5105
|
+
diff,
|
|
5106
|
+
_skipPagination: true
|
|
5107
|
+
});
|
|
4858
5108
|
const deepContent = result.content[0];
|
|
4859
5109
|
if (!deepContent) throw new Error("Empty code review response");
|
|
4860
5110
|
const parsed = JSON.parse(deepContent.text);
|
|
5111
|
+
const rawFindings = parsed.findings ?? [];
|
|
5112
|
+
const sorted = sortFindingsBySeverity(rawFindings);
|
|
5113
|
+
const paged = paginate(sorted, offset ?? 0, limit ?? 20);
|
|
4861
5114
|
return {
|
|
4862
5115
|
content: [
|
|
4863
5116
|
{
|
|
@@ -4865,7 +5118,8 @@ async function runDeepReview(projectPath, diff, diffLines, _downgraded) {
|
|
|
4865
5118
|
text: JSON.stringify({
|
|
4866
5119
|
depth: "deep",
|
|
4867
5120
|
downgraded: false,
|
|
4868
|
-
findings:
|
|
5121
|
+
findings: paged.items,
|
|
5122
|
+
pagination: paged.pagination,
|
|
4869
5123
|
assessment: parsed.assessment,
|
|
4870
5124
|
findingCount: parsed.findingCount,
|
|
4871
5125
|
lineCount: diffLines,
|
|
@@ -4924,7 +5178,7 @@ async function handleCheckTaskIndependence(input) {
|
|
|
4924
5178
|
try {
|
|
4925
5179
|
const projectPath = sanitizePath(input.path);
|
|
4926
5180
|
const store = await loadGraphStore(projectPath);
|
|
4927
|
-
const { TaskIndependenceAnalyzer } = await import("./dist-
|
|
5181
|
+
const { TaskIndependenceAnalyzer } = await import("./dist-RADHOOXG.js");
|
|
4928
5182
|
const analyzer = new TaskIndependenceAnalyzer(store ?? void 0);
|
|
4929
5183
|
const result = analyzer.analyze({
|
|
4930
5184
|
tasks: input.tasks,
|
|
@@ -5012,7 +5266,7 @@ async function handlePredictConflicts(input) {
|
|
|
5012
5266
|
try {
|
|
5013
5267
|
const projectPath = sanitizePath(input.path);
|
|
5014
5268
|
const store = await loadGraphStore(projectPath);
|
|
5015
|
-
const { ConflictPredictor } = await import("./dist-
|
|
5269
|
+
const { ConflictPredictor } = await import("./dist-RADHOOXG.js");
|
|
5016
5270
|
const predictor = new ConflictPredictor(store ?? void 0);
|
|
5017
5271
|
const result = predictor.predict({
|
|
5018
5272
|
tasks: input.tasks,
|
|
@@ -5118,7 +5372,7 @@ async function handleDetectStaleConstraints(input) {
|
|
|
5118
5372
|
isError: true
|
|
5119
5373
|
};
|
|
5120
5374
|
}
|
|
5121
|
-
const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-
|
|
5375
|
+
const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-JHQVQRUS.js");
|
|
5122
5376
|
const store = await loadGraphStore2(projectPath);
|
|
5123
5377
|
if (!store) {
|
|
5124
5378
|
return {
|
|
@@ -5139,7 +5393,7 @@ async function handleDetectStaleConstraints(input) {
|
|
|
5139
5393
|
]
|
|
5140
5394
|
};
|
|
5141
5395
|
}
|
|
5142
|
-
const { detectStaleConstraints } = await import("./dist-
|
|
5396
|
+
const { detectStaleConstraints } = await import("./dist-WCSJHQPK.js");
|
|
5143
5397
|
const result = detectStaleConstraints(
|
|
5144
5398
|
store,
|
|
5145
5399
|
windowDays,
|
|
@@ -5166,6 +5420,9 @@ async function handleDetectStaleConstraints(input) {
|
|
|
5166
5420
|
}
|
|
5167
5421
|
}
|
|
5168
5422
|
|
|
5423
|
+
// src/mcp/tools/search-skills.ts
|
|
5424
|
+
init_dist();
|
|
5425
|
+
|
|
5169
5426
|
// src/skill/health-snapshot.ts
|
|
5170
5427
|
import { execSync } from "child_process";
|
|
5171
5428
|
import * as fs16 from "fs";
|
|
@@ -5256,10 +5513,10 @@ function countCriticalFindings(securityData) {
|
|
|
5256
5513
|
return findings.filter((f) => f.severity === "error").length;
|
|
5257
5514
|
}
|
|
5258
5515
|
async function runHealthChecks(projectPath) {
|
|
5259
|
-
const { handleAssessProject: handleAssessProject2 } = await import("./assess-project-
|
|
5260
|
-
const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-
|
|
5261
|
-
const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-
|
|
5262
|
-
const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-
|
|
5516
|
+
const { handleAssessProject: handleAssessProject2 } = await import("./assess-project-6MV5TNY3.js");
|
|
5517
|
+
const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-HNIO6AUX.js");
|
|
5518
|
+
const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-EMSXF2PX.js");
|
|
5519
|
+
const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-JLZUAQYT.js");
|
|
5263
5520
|
const [assessResult, depsResult, entropyResult, securityResult] = await Promise.all([
|
|
5264
5521
|
handleAssessProject2({
|
|
5265
5522
|
path: projectPath,
|
|
@@ -5314,10 +5571,10 @@ function avg(values) {
|
|
|
5314
5571
|
}
|
|
5315
5572
|
async function runGraphMetrics(projectPath) {
|
|
5316
5573
|
try {
|
|
5317
|
-
const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-
|
|
5574
|
+
const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-JHQVQRUS.js");
|
|
5318
5575
|
const store = await loadGraphStore2(projectPath);
|
|
5319
5576
|
if (!store) return ZERO_METRICS;
|
|
5320
|
-
const { GraphCouplingAdapter, GraphComplexityAdapter, GraphAnomalyAdapter } = await import("./dist-
|
|
5577
|
+
const { GraphCouplingAdapter, GraphComplexityAdapter, GraphAnomalyAdapter } = await import("./dist-RADHOOXG.js");
|
|
5321
5578
|
const couplingAdapter = new GraphCouplingAdapter(store);
|
|
5322
5579
|
const couplingData = couplingAdapter.computeCouplingData();
|
|
5323
5580
|
const files = couplingData.files;
|
|
@@ -5392,6 +5649,14 @@ var searchSkillsDefinition = {
|
|
|
5392
5649
|
type: "string",
|
|
5393
5650
|
enum: ["claude-code", "gemini-cli"],
|
|
5394
5651
|
description: "Target platform (defaults to claude-code)"
|
|
5652
|
+
},
|
|
5653
|
+
offset: {
|
|
5654
|
+
type: "number",
|
|
5655
|
+
description: "Number of results to skip (default 0)"
|
|
5656
|
+
},
|
|
5657
|
+
limit: {
|
|
5658
|
+
type: "number",
|
|
5659
|
+
description: "Maximum results to return (default 5)"
|
|
5395
5660
|
}
|
|
5396
5661
|
},
|
|
5397
5662
|
required: ["query"]
|
|
@@ -5408,10 +5673,11 @@ async function handleSearchSkills(input) {
|
|
|
5408
5673
|
const snapshot = loadCachedSnapshot(projectRoot);
|
|
5409
5674
|
const freshSnapshot = snapshot && isSnapshotFresh(snapshot, projectRoot) ? snapshot : void 0;
|
|
5410
5675
|
const queryTerms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 2);
|
|
5676
|
+
const MIN_SCORE = 0.25;
|
|
5411
5677
|
const results = [];
|
|
5412
5678
|
for (const [name, entry] of Object.entries(index.skills)) {
|
|
5413
5679
|
const score = scoreSkill(entry, queryTerms, profile, [], name, freshSnapshot);
|
|
5414
|
-
if (score
|
|
5680
|
+
if (score >= MIN_SCORE || queryTerms.length === 0) {
|
|
5415
5681
|
results.push({
|
|
5416
5682
|
name,
|
|
5417
5683
|
description: entry.description,
|
|
@@ -5423,18 +5689,23 @@ async function handleSearchSkills(input) {
|
|
|
5423
5689
|
}
|
|
5424
5690
|
}
|
|
5425
5691
|
results.sort((a, b) => b.score - a.score);
|
|
5426
|
-
const
|
|
5692
|
+
const { items, pagination } = paginate(
|
|
5693
|
+
results,
|
|
5694
|
+
input.offset ?? 0,
|
|
5695
|
+
input.limit ?? 5
|
|
5696
|
+
);
|
|
5427
5697
|
return {
|
|
5428
5698
|
content: [
|
|
5429
5699
|
{
|
|
5430
5700
|
type: "text",
|
|
5431
|
-
text: JSON.stringify({ results:
|
|
5701
|
+
text: JSON.stringify({ results: items, pagination }, null, 2)
|
|
5432
5702
|
}
|
|
5433
5703
|
]
|
|
5434
5704
|
};
|
|
5435
5705
|
}
|
|
5436
5706
|
|
|
5437
5707
|
// src/skill/dispatch-engine.ts
|
|
5708
|
+
init_dist();
|
|
5438
5709
|
import { execSync as execSync2 } from "child_process";
|
|
5439
5710
|
|
|
5440
5711
|
// src/skill/recommendation-rules.ts
|
|
@@ -5985,6 +6256,7 @@ async function handleDispatchSkills(input) {
|
|
|
5985
6256
|
}
|
|
5986
6257
|
|
|
5987
6258
|
// src/mcp/tools/decay-trends.ts
|
|
6259
|
+
init_dist();
|
|
5988
6260
|
var getDecayTrendsDefinition = {
|
|
5989
6261
|
name: "get_decay_trends",
|
|
5990
6262
|
description: 'Get architecture decay trends over time. Returns stability score history and per-category trend analysis from timeline snapshots. Use to answer questions like "is the architecture decaying?" or "which metrics are getting worse?"',
|
|
@@ -6012,6 +6284,14 @@ var getDecayTrendsDefinition = {
|
|
|
6012
6284
|
"module-size",
|
|
6013
6285
|
"dependency-depth"
|
|
6014
6286
|
]
|
|
6287
|
+
},
|
|
6288
|
+
offset: {
|
|
6289
|
+
type: "number",
|
|
6290
|
+
description: "Number of trend entries to skip (pagination). Default: 0. Trends are sorted by decay magnitude (absolute delta) desc. Ignored when category is set (category filter returns a single entry)."
|
|
6291
|
+
},
|
|
6292
|
+
limit: {
|
|
6293
|
+
type: "number",
|
|
6294
|
+
description: "Max trend entries to return (pagination). Default: 20. Ignored when category is set (category filter returns a single entry)."
|
|
6015
6295
|
}
|
|
6016
6296
|
},
|
|
6017
6297
|
required: ["path"]
|
|
@@ -6033,7 +6313,7 @@ async function handleGetDecayTrends(input) {
|
|
|
6033
6313
|
};
|
|
6034
6314
|
}
|
|
6035
6315
|
try {
|
|
6036
|
-
const core = await import("./dist-
|
|
6316
|
+
const core = await import("./dist-WCSJHQPK.js");
|
|
6037
6317
|
const { TimelineManager } = core;
|
|
6038
6318
|
const manager = new TimelineManager(projectPath);
|
|
6039
6319
|
const timeline = manager.load();
|
|
@@ -6051,9 +6331,14 @@ async function handleGetDecayTrends(input) {
|
|
|
6051
6331
|
if (input.last !== void 0) trendOptions.last = input.last;
|
|
6052
6332
|
if (input.since !== void 0) trendOptions.since = input.since;
|
|
6053
6333
|
const trends = manager.trends(trendOptions);
|
|
6334
|
+
const categoryEntries = Object.entries(trends.categories).map(([name, trend]) => ({
|
|
6335
|
+
category: name,
|
|
6336
|
+
...trend
|
|
6337
|
+
}));
|
|
6338
|
+
categoryEntries.sort((a, b) => Math.abs(b.delta) - Math.abs(a.delta));
|
|
6054
6339
|
if (input.category) {
|
|
6055
|
-
const
|
|
6056
|
-
if (!
|
|
6340
|
+
const match = categoryEntries.find((e) => e.category === input.category);
|
|
6341
|
+
if (!match) {
|
|
6057
6342
|
return {
|
|
6058
6343
|
content: [
|
|
6059
6344
|
{
|
|
@@ -6070,7 +6355,12 @@ async function handleGetDecayTrends(input) {
|
|
|
6070
6355
|
text: JSON.stringify(
|
|
6071
6356
|
{
|
|
6072
6357
|
category: input.category,
|
|
6073
|
-
trend:
|
|
6358
|
+
trend: {
|
|
6359
|
+
current: match.current,
|
|
6360
|
+
previous: match.previous,
|
|
6361
|
+
delta: match.delta,
|
|
6362
|
+
direction: match.direction
|
|
6363
|
+
},
|
|
6074
6364
|
snapshotCount: trends.snapshotCount,
|
|
6075
6365
|
from: trends.from,
|
|
6076
6366
|
to: trends.to
|
|
@@ -6082,11 +6372,23 @@ async function handleGetDecayTrends(input) {
|
|
|
6082
6372
|
]
|
|
6083
6373
|
};
|
|
6084
6374
|
}
|
|
6375
|
+
const paged = paginate(categoryEntries, input.offset ?? 0, input.limit ?? 20);
|
|
6085
6376
|
return {
|
|
6086
6377
|
content: [
|
|
6087
6378
|
{
|
|
6088
6379
|
type: "text",
|
|
6089
|
-
text: JSON.stringify(
|
|
6380
|
+
text: JSON.stringify(
|
|
6381
|
+
{
|
|
6382
|
+
stability: trends.stability,
|
|
6383
|
+
categories: paged.items,
|
|
6384
|
+
snapshotCount: trends.snapshotCount,
|
|
6385
|
+
from: trends.from,
|
|
6386
|
+
to: trends.to,
|
|
6387
|
+
pagination: paged.pagination
|
|
6388
|
+
},
|
|
6389
|
+
null,
|
|
6390
|
+
2
|
|
6391
|
+
)
|
|
6090
6392
|
}
|
|
6091
6393
|
]
|
|
6092
6394
|
};
|
|
@@ -6117,6 +6419,14 @@ var codeOutlineDefinition = {
|
|
|
6117
6419
|
glob: {
|
|
6118
6420
|
type: "string",
|
|
6119
6421
|
description: 'Optional glob pattern to filter files (e.g. "*.ts", "src/**/*.py"). Only used when path is a directory.'
|
|
6422
|
+
},
|
|
6423
|
+
offset: {
|
|
6424
|
+
type: "number",
|
|
6425
|
+
description: "Number of file entries to skip (pagination, directory mode only). Default: 0. Files are sorted by modification time desc."
|
|
6426
|
+
},
|
|
6427
|
+
limit: {
|
|
6428
|
+
type: "number",
|
|
6429
|
+
description: "Max file entries to return (pagination, directory mode only). Default: 30."
|
|
6120
6430
|
}
|
|
6121
6431
|
},
|
|
6122
6432
|
required: ["path"]
|
|
@@ -6138,7 +6448,7 @@ async function handleCodeOutline(input) {
|
|
|
6138
6448
|
};
|
|
6139
6449
|
}
|
|
6140
6450
|
try {
|
|
6141
|
-
const { getOutline, formatOutline, EXTENSION_MAP } = await import("./dist-
|
|
6451
|
+
const { getOutline, formatOutline, EXTENSION_MAP } = await import("./dist-WCSJHQPK.js");
|
|
6142
6452
|
const { stat } = await import("fs/promises");
|
|
6143
6453
|
const stats = await stat(targetPath).catch(() => null);
|
|
6144
6454
|
if (stats?.isFile()) {
|
|
@@ -6150,19 +6460,31 @@ async function handleCodeOutline(input) {
|
|
|
6150
6460
|
const exts = Object.keys(EXTENSION_MAP).map((e) => e.slice(1));
|
|
6151
6461
|
const pattern = input.glob ?? `**/*.{${exts.join(",")}}`;
|
|
6152
6462
|
const files = await glob(pattern, { cwd: targetPath, absolute: true });
|
|
6463
|
+
const fileStats = await Promise.all(
|
|
6464
|
+
files.map(async (f) => {
|
|
6465
|
+
const fStat = await stat(f).catch(() => null);
|
|
6466
|
+
return { path: f, mtimeMs: fStat?.mtimeMs ?? 0 };
|
|
6467
|
+
})
|
|
6468
|
+
);
|
|
6469
|
+
fileStats.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
6470
|
+
const { paginate: paginate2 } = await import("./dist-WCSJHQPK.js");
|
|
6471
|
+
const paged = paginate2(fileStats, input.offset ?? 0, input.limit ?? 30);
|
|
6153
6472
|
const results = [];
|
|
6154
|
-
const
|
|
6155
|
-
|
|
6156
|
-
const outline = await getOutline(file);
|
|
6473
|
+
for (const entry of paged.items) {
|
|
6474
|
+
const outline = await getOutline(entry.path);
|
|
6157
6475
|
results.push(formatOutline(outline));
|
|
6158
6476
|
}
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
|
|
6477
|
+
return {
|
|
6478
|
+
content: [
|
|
6479
|
+
{
|
|
6480
|
+
type: "text",
|
|
6481
|
+
text: JSON.stringify({
|
|
6482
|
+
outlines: results.join("\n\n"),
|
|
6483
|
+
pagination: paged.pagination
|
|
6484
|
+
})
|
|
6485
|
+
}
|
|
6486
|
+
]
|
|
6487
|
+
};
|
|
6166
6488
|
}
|
|
6167
6489
|
return {
|
|
6168
6490
|
content: [{ type: "text", text: `Error: Path not found: ${targetPath}` }],
|
|
@@ -6218,7 +6540,7 @@ async function handleCodeSearch(input) {
|
|
|
6218
6540
|
};
|
|
6219
6541
|
}
|
|
6220
6542
|
try {
|
|
6221
|
-
const { searchSymbols } = await import("./dist-
|
|
6543
|
+
const { searchSymbols } = await import("./dist-WCSJHQPK.js");
|
|
6222
6544
|
const result = await searchSymbols(input.query, directory, input.glob);
|
|
6223
6545
|
const lines = [`Search: "${result.query}" \u2014 ${result.matches.length} matches`];
|
|
6224
6546
|
for (const match of result.matches) {
|
|
@@ -6287,7 +6609,7 @@ async function handleCodeUnfold(input) {
|
|
|
6287
6609
|
}
|
|
6288
6610
|
try {
|
|
6289
6611
|
if (input.symbol) {
|
|
6290
|
-
const { unfoldSymbol } = await import("./dist-
|
|
6612
|
+
const { unfoldSymbol } = await import("./dist-WCSJHQPK.js");
|
|
6291
6613
|
const result = await unfoldSymbol(filePath, input.symbol);
|
|
6292
6614
|
const header = result.warning ? `${result.file}:${result.startLine}-${result.endLine} ${result.warning}
|
|
6293
6615
|
` : `${result.file}:${result.startLine}-${result.endLine}
|
|
@@ -6295,7 +6617,7 @@ async function handleCodeUnfold(input) {
|
|
|
6295
6617
|
return { content: [{ type: "text", text: header + result.content }] };
|
|
6296
6618
|
}
|
|
6297
6619
|
if (input.startLine != null && input.endLine != null) {
|
|
6298
|
-
const { unfoldRange } = await import("./dist-
|
|
6620
|
+
const { unfoldRange } = await import("./dist-WCSJHQPK.js");
|
|
6299
6621
|
const result = await unfoldRange(filePath, input.startLine, input.endLine);
|
|
6300
6622
|
const header = `${result.file}:${result.startLine}-${result.endLine}
|
|
6301
6623
|
`;
|
|
@@ -6357,7 +6679,7 @@ async function handleCheckTraceability(input) {
|
|
|
6357
6679
|
isError: true
|
|
6358
6680
|
};
|
|
6359
6681
|
}
|
|
6360
|
-
const { queryTraceability } = await import("./dist-
|
|
6682
|
+
const { queryTraceability } = await import("./dist-RADHOOXG.js");
|
|
6361
6683
|
const options = {};
|
|
6362
6684
|
if (input.spec) options.specPath = input.spec;
|
|
6363
6685
|
if (input.feature) options.featureName = input.feature;
|
|
@@ -6480,7 +6802,7 @@ async function handlePredictFailures(input) {
|
|
|
6480
6802
|
};
|
|
6481
6803
|
}
|
|
6482
6804
|
try {
|
|
6483
|
-
const core = await import("./dist-
|
|
6805
|
+
const core = await import("./dist-WCSJHQPK.js");
|
|
6484
6806
|
const { TimelineManager, PredictionEngine, SpecImpactEstimator } = core;
|
|
6485
6807
|
const manager = new TimelineManager(projectPath);
|
|
6486
6808
|
const includeRoadmap = input.includeRoadmap !== false;
|
|
@@ -6583,6 +6905,7 @@ async function handleRecommendSkills(input) {
|
|
|
6583
6905
|
}
|
|
6584
6906
|
|
|
6585
6907
|
// src/mcp/tools/compact.ts
|
|
6908
|
+
init_dist();
|
|
6586
6909
|
var COMPACT_TOOL_DEFAULT_BUDGET = 2e3;
|
|
6587
6910
|
var compactToolDefinition = {
|
|
6588
6911
|
name: "compact",
|
|
@@ -6669,7 +6992,7 @@ function handleContentMode(content, pipeline, budget, source) {
|
|
|
6669
6992
|
};
|
|
6670
6993
|
}
|
|
6671
6994
|
async function handleIntentMode(projectPath, intent, pipeline, budget, filterContent) {
|
|
6672
|
-
const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-
|
|
6995
|
+
const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-JHQVQRUS.js");
|
|
6673
6996
|
const store = await loadGraphStore2(projectPath);
|
|
6674
6997
|
if (!store) {
|
|
6675
6998
|
return {
|
|
@@ -6682,7 +7005,7 @@ async function handleIntentMode(projectPath, intent, pipeline, budget, filterCon
|
|
|
6682
7005
|
isError: true
|
|
6683
7006
|
};
|
|
6684
7007
|
}
|
|
6685
|
-
const { PackedSummaryCache, FusionLayer, ContextQL } = await import("./dist-
|
|
7008
|
+
const { PackedSummaryCache, FusionLayer, ContextQL } = await import("./dist-RADHOOXG.js");
|
|
6686
7009
|
const cache = new PackedSummaryCache(store);
|
|
6687
7010
|
const cachedEnvelope = cache.get(intent);
|
|
6688
7011
|
if (cachedEnvelope) {
|
|
@@ -6820,6 +7143,110 @@ Warning: unknown strategies ignored: ${unknownStrategies.join(", ")}` : "";
|
|
|
6820
7143
|
};
|
|
6821
7144
|
}
|
|
6822
7145
|
|
|
7146
|
+
// src/mcp/tools/constraint-emergence.ts
|
|
7147
|
+
var detectConstraintEmergenceDefinition = {
|
|
7148
|
+
name: "detect_constraint_emergence",
|
|
7149
|
+
description: "Cluster recurring violations by pattern and suggest new constraint rules. When N similar violations appear in M weeks, suggests emergent architectural norms learned from team behavior.",
|
|
7150
|
+
inputSchema: {
|
|
7151
|
+
type: "object",
|
|
7152
|
+
properties: {
|
|
7153
|
+
path: { type: "string", description: "Path to project root" },
|
|
7154
|
+
windowWeeks: {
|
|
7155
|
+
type: "number",
|
|
7156
|
+
description: "Time window in weeks to analyze (default: 4)"
|
|
7157
|
+
},
|
|
7158
|
+
minOccurrences: {
|
|
7159
|
+
type: "number",
|
|
7160
|
+
description: "Minimum number of similar violations to trigger a suggestion (default: 3)"
|
|
7161
|
+
},
|
|
7162
|
+
category: {
|
|
7163
|
+
type: "string",
|
|
7164
|
+
description: "Optional filter by constraint category",
|
|
7165
|
+
enum: [
|
|
7166
|
+
"circular-deps",
|
|
7167
|
+
"layer-violations",
|
|
7168
|
+
"complexity",
|
|
7169
|
+
"coupling",
|
|
7170
|
+
"forbidden-imports",
|
|
7171
|
+
"module-size",
|
|
7172
|
+
"dependency-depth"
|
|
7173
|
+
]
|
|
7174
|
+
}
|
|
7175
|
+
},
|
|
7176
|
+
required: ["path"]
|
|
7177
|
+
}
|
|
7178
|
+
};
|
|
7179
|
+
async function handleDetectConstraintEmergence(input) {
|
|
7180
|
+
let projectPath;
|
|
7181
|
+
try {
|
|
7182
|
+
projectPath = sanitizePath(input.path);
|
|
7183
|
+
} catch (error) {
|
|
7184
|
+
return {
|
|
7185
|
+
content: [
|
|
7186
|
+
{
|
|
7187
|
+
type: "text",
|
|
7188
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
7189
|
+
}
|
|
7190
|
+
],
|
|
7191
|
+
isError: true
|
|
7192
|
+
};
|
|
7193
|
+
}
|
|
7194
|
+
try {
|
|
7195
|
+
const windowWeeks = input.windowWeeks ?? 4;
|
|
7196
|
+
if (!Number.isFinite(windowWeeks) || windowWeeks < 1) {
|
|
7197
|
+
return {
|
|
7198
|
+
content: [
|
|
7199
|
+
{
|
|
7200
|
+
type: "text",
|
|
7201
|
+
text: "Error: windowWeeks must be a finite number >= 1"
|
|
7202
|
+
}
|
|
7203
|
+
],
|
|
7204
|
+
isError: true
|
|
7205
|
+
};
|
|
7206
|
+
}
|
|
7207
|
+
const minOccurrences = input.minOccurrences ?? 3;
|
|
7208
|
+
if (!Number.isFinite(minOccurrences) || minOccurrences < 2) {
|
|
7209
|
+
return {
|
|
7210
|
+
content: [
|
|
7211
|
+
{
|
|
7212
|
+
type: "text",
|
|
7213
|
+
text: "Error: minOccurrences must be a finite number >= 2"
|
|
7214
|
+
}
|
|
7215
|
+
],
|
|
7216
|
+
isError: true
|
|
7217
|
+
};
|
|
7218
|
+
}
|
|
7219
|
+
const nodePath = await import("path");
|
|
7220
|
+
const historyPath = nodePath.resolve(projectPath, ".harness/arch/violation-history.json");
|
|
7221
|
+
const { ViolationHistoryManager, detectEmergentConstraints } = await import("./dist-WCSJHQPK.js");
|
|
7222
|
+
const manager = new ViolationHistoryManager(historyPath);
|
|
7223
|
+
const history = manager.load();
|
|
7224
|
+
const options = { windowWeeks, minOccurrences };
|
|
7225
|
+
if (input.category) {
|
|
7226
|
+
options.category = input.category;
|
|
7227
|
+
}
|
|
7228
|
+
const result = detectEmergentConstraints(history, options);
|
|
7229
|
+
return {
|
|
7230
|
+
content: [
|
|
7231
|
+
{
|
|
7232
|
+
type: "text",
|
|
7233
|
+
text: JSON.stringify(result, null, 2)
|
|
7234
|
+
}
|
|
7235
|
+
]
|
|
7236
|
+
};
|
|
7237
|
+
} catch (error) {
|
|
7238
|
+
return {
|
|
7239
|
+
content: [
|
|
7240
|
+
{
|
|
7241
|
+
type: "text",
|
|
7242
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
7243
|
+
}
|
|
7244
|
+
],
|
|
7245
|
+
isError: true
|
|
7246
|
+
};
|
|
7247
|
+
}
|
|
7248
|
+
}
|
|
7249
|
+
|
|
6823
7250
|
// src/mcp/server.ts
|
|
6824
7251
|
var TOOL_DEFINITIONS = [
|
|
6825
7252
|
validateToolDefinition,
|
|
@@ -6851,6 +7278,7 @@ var TOOL_DEFINITIONS = [
|
|
|
6851
7278
|
ingestSourceDefinition,
|
|
6852
7279
|
generateAgentDefinitionsDefinition,
|
|
6853
7280
|
runSecurityScanDefinition,
|
|
7281
|
+
getSecurityTrendsDefinition,
|
|
6854
7282
|
checkPerformanceDefinition,
|
|
6855
7283
|
getPerfBaselinesDefinition,
|
|
6856
7284
|
updatePerfBaselinesDefinition,
|
|
@@ -6877,7 +7305,8 @@ var TOOL_DEFINITIONS = [
|
|
|
6877
7305
|
recommendSkillsDefinition,
|
|
6878
7306
|
computeBlastRadiusDefinition,
|
|
6879
7307
|
dispatchSkillsDefinition,
|
|
6880
|
-
compactToolDefinition
|
|
7308
|
+
compactToolDefinition,
|
|
7309
|
+
detectConstraintEmergenceDefinition
|
|
6881
7310
|
].map((def) => ({ ...def, trustedOutput: true }));
|
|
6882
7311
|
var TOOL_HANDLERS = {
|
|
6883
7312
|
validate_project: handleValidateProject,
|
|
@@ -6909,6 +7338,7 @@ var TOOL_HANDLERS = {
|
|
|
6909
7338
|
ingest_source: handleIngestSource,
|
|
6910
7339
|
generate_agent_definitions: handleGenerateAgentDefinitions,
|
|
6911
7340
|
run_security_scan: handleRunSecurityScan,
|
|
7341
|
+
get_security_trends: handleGetSecurityTrends,
|
|
6912
7342
|
check_performance: handleCheckPerformance,
|
|
6913
7343
|
get_perf_baselines: handleGetPerfBaselines,
|
|
6914
7344
|
update_perf_baselines: handleUpdatePerfBaselines,
|
|
@@ -6935,7 +7365,8 @@ var TOOL_HANDLERS = {
|
|
|
6935
7365
|
recommend_skills: handleRecommendSkills,
|
|
6936
7366
|
compute_blast_radius: handleComputeBlastRadius,
|
|
6937
7367
|
dispatch_skills: handleDispatchSkills,
|
|
6938
|
-
compact: handleCompact
|
|
7368
|
+
compact: handleCompact,
|
|
7369
|
+
detect_constraint_emergence: handleDetectConstraintEmergence
|
|
6939
7370
|
};
|
|
6940
7371
|
var RESOURCE_DEFINITIONS = [
|
|
6941
7372
|
{
|
|
@@ -7029,8 +7460,8 @@ async function appendUpdateNotification(result, resolvedRoot) {
|
|
|
7029
7460
|
shouldRunCheck,
|
|
7030
7461
|
readCheckState,
|
|
7031
7462
|
spawnBackgroundCheck
|
|
7032
|
-
} = await import("./dist-
|
|
7033
|
-
const { CLI_VERSION } = await import("./version-
|
|
7463
|
+
} = await import("./dist-WCSJHQPK.js");
|
|
7464
|
+
const { CLI_VERSION } = await import("./version-CUI434OP.js");
|
|
7034
7465
|
const configInterval = readConfigInterval(resolvedRoot);
|
|
7035
7466
|
const DEFAULT_INTERVAL = 864e5;
|
|
7036
7467
|
if (!isUpdateCheckEnabled(configInterval)) return;
|