@harness-engineering/cli 2.4.5 → 2.6.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-md-2JUQ4FE2.js +13 -0
- package/dist/analyzer-VY6DJVOU-4AHIJLNS.js +26 -0
- package/dist/{architecture-NX7FWQD3.js → architecture-CXAVNB5X.js} +7 -4
- package/dist/{assess-project-PLY6ZWMW.js → assess-project-M626SSPN.js} +1 -1
- package/dist/bin/harness-mcp.js +20 -17
- package/dist/bin/harness.js +38 -35
- package/dist/{check-phase-gate-WFIEJKMN.js → check-phase-gate-XMU6LLUQ.js} +8 -5
- package/dist/{chunk-OPDIMKUZ.js → chunk-24KCOJJG.js} +2 -2
- package/dist/{chunk-72TZ2GZR.js → chunk-43M3RLFQ.js} +7 -7
- package/dist/{chunk-7TRTU7JL.js → chunk-5JNSFYZU.js} +2 -2
- package/dist/{chunk-PGY57ABC.js → chunk-6AX6R3LM.js} +7 -7
- package/dist/{chunk-TC4GQBIK.js → chunk-GWE5LL3R.js} +6 -6
- package/dist/{chunk-LJTQVJEP.js → chunk-GWF2OILZ.js} +2 -2
- package/dist/{chunk-FPUNXFJG.js → chunk-HFOB2MPQ.js} +2 -2
- package/dist/{chunk-Z6PF2YXB.js → chunk-HMW3VKUF.js} +3 -3
- package/dist/{chunk-NSLFLGUB.js → chunk-HYTRDAHV.js} +2 -2
- package/dist/{chunk-3XFFGAX4.js → chunk-I6K43QQS.js} +3 -3
- package/dist/{chunk-YL2N4OZQ.js → chunk-JFZOWO7D.js} +2 -2
- package/dist/{chunk-4H2KIQ3I.js → chunk-K246XQ2L.js} +2 -2
- package/dist/{chunk-ZEKY6PQQ.js → chunk-L5BCZ5XS.js} +2 -2
- package/dist/{chunk-4PO2QAXO.js → chunk-NX6A24DS.js} +2153 -985
- package/dist/{chunk-A5GXGRW6.js → chunk-OA6SWTU4.js} +6 -6
- package/dist/chunk-OH3NXXUY.js +383 -0
- package/dist/{chunk-DUK6C7I7.js → chunk-ORNMAYHB.js} +611 -300
- package/dist/{chunk-73ACYXIS.js → chunk-PFZEADQM.js} +1 -1
- package/dist/{chunk-M5TJOV3A.js → chunk-Q6ZR2L6Q.js} +2 -2
- package/dist/chunk-QCLOIUMX.js +395 -0
- package/dist/{chunk-DUCVDDZO.js → chunk-QOKMDDBJ.js} +4 -4
- package/dist/chunk-SZEFU6XC.js +3337 -0
- package/dist/{chunk-KEF624FQ.js → chunk-VTTNIZJL.js} +27 -6
- package/dist/chunk-XARGEOJV.js +21 -0
- package/dist/{chunk-HCTXLKAH.js → chunk-YP7I25SL.js} +2 -2
- package/dist/{chunk-65M5R3X6.js → chunk-YYRQCQPZ.js} +4204 -7347
- package/dist/ci-workflow-3JNDZQYD.js +13 -0
- package/dist/dist-E3SAAHCM.js +93 -0
- package/dist/{dist-SVZHSOLP.js → dist-OHDQBTSO.js} +119 -48
- package/dist/{docs-7LXCR62T.js → docs-5RYMDHN3.js} +8 -5
- package/dist/engine-KZ3PPUYE.js +13 -0
- package/dist/{entropy-LMOXWMR4.js → entropy-DQTAPSSE.js} +6 -3
- package/dist/{feedback-CLBC3IMP.js → feedback-WH6XPQJS.js} +1 -1
- package/dist/{generate-agent-definitions-5FDIGEVZ.js → generate-agent-definitions-SZA4QIHN.js} +8 -5
- package/dist/index.d.ts +47 -0
- package/dist/index.js +49 -46
- package/dist/loader-BNKGM23C.js +15 -0
- package/dist/{mcp-4W45E6OH.js → mcp-GZH4EYGD.js} +20 -17
- package/dist/{performance-WZQIUHLR.js → performance-54TMJOEU.js} +8 -5
- package/dist/{review-pipeline-YPRUHKM7.js → review-pipeline-OTDDVPNY.js} +6 -3
- package/dist/runtime-W5THSNAL.js +14 -0
- package/dist/{security-AZNLX3N6.js → security-27HW7CYT.js} +1 -1
- package/dist/timeline-manager-FPYKJRHR-VVX7CSGW.js +24 -0
- package/dist/{tool-tiers-QVWKAZX4.js → tool-tiers-B7JC2XC3.js} +9 -2
- package/dist/{validate-S7G6H7F4.js → validate-QRVCD4GP.js} +7 -4
- package/dist/validate-cross-check-BUAGBAPO.js +13 -0
- package/package.json +6 -6
- package/dist/agents-md-KJVGWF2S.js +0 -10
- package/dist/chunk-O63AAPIZ.js +0 -190
- package/dist/ci-workflow-XDIKOFSN.js +0 -10
- package/dist/dist-O733ZU6I.js +0 -49
- package/dist/engine-MMQF2ZW5.js +0 -10
- package/dist/loader-WTWR2CWT.js +0 -12
- package/dist/runtime-WC2IWI2X.js +0 -11
- package/dist/validate-cross-check-Z73SCHXZ.js +0 -10
|
@@ -1,12 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getSecurityTrendsDefinition,
|
|
3
|
+
handleGetSecurityTrends,
|
|
4
|
+
handleRunSecurityScan,
|
|
5
|
+
runSecurityScanDefinition
|
|
6
|
+
} from "./chunk-HFOB2MPQ.js";
|
|
1
7
|
import {
|
|
2
8
|
handleRunCodeReview,
|
|
3
9
|
runCodeReviewDefinition,
|
|
4
10
|
sortFindingsBySeverity
|
|
5
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-Q6ZR2L6Q.js";
|
|
6
12
|
import {
|
|
7
13
|
assessProjectDefinition,
|
|
8
14
|
handleAssessProject
|
|
9
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-OA6SWTU4.js";
|
|
16
|
+
import {
|
|
17
|
+
detectEntropyDefinition,
|
|
18
|
+
handleDetectEntropy
|
|
19
|
+
} from "./chunk-QOKMDDBJ.js";
|
|
20
|
+
import {
|
|
21
|
+
checkPerformanceDefinition,
|
|
22
|
+
getCriticalPathsDefinition,
|
|
23
|
+
getPerfBaselinesDefinition,
|
|
24
|
+
handleCheckPerformance,
|
|
25
|
+
handleGetCriticalPaths,
|
|
26
|
+
handleGetPerfBaselines,
|
|
27
|
+
handleUpdatePerfBaselines,
|
|
28
|
+
updatePerfBaselinesDefinition
|
|
29
|
+
} from "./chunk-6AX6R3LM.js";
|
|
10
30
|
import {
|
|
11
31
|
getBusinessKnowledgeResource
|
|
12
32
|
} from "./chunk-IOW3MW2K.js";
|
|
@@ -17,45 +37,34 @@ import {
|
|
|
17
37
|
handleCreateSelfReview,
|
|
18
38
|
handleRequestPeerReview,
|
|
19
39
|
requestPeerReviewDefinition
|
|
20
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-HMW3VKUF.js";
|
|
21
41
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
42
|
+
GENERATED_HEADER_CLAUDE,
|
|
43
|
+
GENERATED_HEADER_CODEX,
|
|
44
|
+
GENERATED_HEADER_CURSOR,
|
|
45
|
+
GENERATED_HEADER_GEMINI,
|
|
46
|
+
VALID_PLATFORMS,
|
|
47
|
+
applySyncPlan,
|
|
48
|
+
computeSyncPlan
|
|
49
|
+
} from "./chunk-3ISINLYT.js";
|
|
27
50
|
import {
|
|
28
51
|
loadGraphStore
|
|
29
52
|
} from "./chunk-5FDBXUFW.js";
|
|
30
53
|
import {
|
|
31
54
|
handleValidateProject,
|
|
32
55
|
validateToolDefinition
|
|
33
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-I6K43QQS.js";
|
|
34
57
|
import {
|
|
35
58
|
checkDependenciesDefinition,
|
|
36
59
|
handleCheckDependencies
|
|
37
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-5JNSFYZU.js";
|
|
38
61
|
import {
|
|
39
62
|
resolveProjectConfig
|
|
40
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-GWF2OILZ.js";
|
|
41
64
|
import {
|
|
42
65
|
checkDocsDefinition,
|
|
43
66
|
handleCheckDocs
|
|
44
|
-
} from "./chunk-
|
|
45
|
-
import {
|
|
46
|
-
detectEntropyDefinition,
|
|
47
|
-
handleDetectEntropy
|
|
48
|
-
} from "./chunk-DUCVDDZO.js";
|
|
49
|
-
import {
|
|
50
|
-
checkPerformanceDefinition,
|
|
51
|
-
getCriticalPathsDefinition,
|
|
52
|
-
getPerfBaselinesDefinition,
|
|
53
|
-
handleCheckPerformance,
|
|
54
|
-
handleGetCriticalPaths,
|
|
55
|
-
handleGetPerfBaselines,
|
|
56
|
-
handleUpdatePerfBaselines,
|
|
57
|
-
updatePerfBaselinesDefinition
|
|
58
|
-
} from "./chunk-PGY57ABC.js";
|
|
67
|
+
} from "./chunk-GWE5LL3R.js";
|
|
59
68
|
import {
|
|
60
69
|
resultToMcpResponse
|
|
61
70
|
} from "./chunk-EPUKTTJZ.js";
|
|
@@ -65,18 +74,6 @@ import {
|
|
|
65
74
|
import {
|
|
66
75
|
loadOrRebuildIndex
|
|
67
76
|
} from "./chunk-27AJKSQY.js";
|
|
68
|
-
import {
|
|
69
|
-
resolveConfig
|
|
70
|
-
} from "./chunk-KEF624FQ.js";
|
|
71
|
-
import {
|
|
72
|
-
GENERATED_HEADER_CLAUDE,
|
|
73
|
-
GENERATED_HEADER_CODEX,
|
|
74
|
-
GENERATED_HEADER_CURSOR,
|
|
75
|
-
GENERATED_HEADER_GEMINI,
|
|
76
|
-
VALID_PLATFORMS,
|
|
77
|
-
applySyncPlan,
|
|
78
|
-
computeSyncPlan
|
|
79
|
-
} from "./chunk-3ISINLYT.js";
|
|
80
77
|
import {
|
|
81
78
|
resolveCommunitySkillsDir,
|
|
82
79
|
resolveGlobalCommunitySkillsDir,
|
|
@@ -86,6 +83,20 @@ import {
|
|
|
86
83
|
resolveSkillsDir,
|
|
87
84
|
resolveTemplatesDir
|
|
88
85
|
} from "./chunk-6B6UN6SG.js";
|
|
86
|
+
import {
|
|
87
|
+
SkillMetadataSchema
|
|
88
|
+
} from "./chunk-HIK6OEUF.js";
|
|
89
|
+
import {
|
|
90
|
+
resolveConfig
|
|
91
|
+
} from "./chunk-VTTNIZJL.js";
|
|
92
|
+
import {
|
|
93
|
+
logger
|
|
94
|
+
} from "./chunk-EBJQ6N4M.js";
|
|
95
|
+
import {
|
|
96
|
+
CLIError,
|
|
97
|
+
ExitCode,
|
|
98
|
+
handleError
|
|
99
|
+
} from "./chunk-3WGJMBKH.js";
|
|
89
100
|
import {
|
|
90
101
|
CompactionPipeline,
|
|
91
102
|
ConflictError,
|
|
@@ -99,7 +110,7 @@ import {
|
|
|
99
110
|
detectChangeType,
|
|
100
111
|
estimateTokens,
|
|
101
112
|
extractLevel,
|
|
102
|
-
init_dist,
|
|
113
|
+
init_dist as init_dist2,
|
|
103
114
|
loadProjectRoadmapMode,
|
|
104
115
|
loadTrackerClientConfigFromProject,
|
|
105
116
|
loadTrackerSyncConfig,
|
|
@@ -107,22 +118,14 @@ import {
|
|
|
107
118
|
scanForInjection,
|
|
108
119
|
serializeEnvelope,
|
|
109
120
|
writeTaint
|
|
110
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-YYRQCQPZ.js";
|
|
111
122
|
import {
|
|
112
123
|
Err,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
} from "./chunk-
|
|
118
|
-
import {
|
|
119
|
-
logger
|
|
120
|
-
} from "./chunk-EBJQ6N4M.js";
|
|
121
|
-
import {
|
|
122
|
-
CLIError,
|
|
123
|
-
ExitCode,
|
|
124
|
-
handleError
|
|
125
|
-
} from "./chunk-3WGJMBKH.js";
|
|
124
|
+
INDEXED_FILE_KINDS,
|
|
125
|
+
INSIGHTS_KEYS,
|
|
126
|
+
Ok,
|
|
127
|
+
init_dist
|
|
128
|
+
} from "./chunk-OH3NXXUY.js";
|
|
126
129
|
|
|
127
130
|
// src/mcp/server.ts
|
|
128
131
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -345,7 +348,7 @@ function appendFrameworkAgents(targetDir, framework, language) {
|
|
|
345
348
|
}
|
|
346
349
|
|
|
347
350
|
// src/mcp/middleware/injection-guard.ts
|
|
348
|
-
|
|
351
|
+
init_dist2();
|
|
349
352
|
import { realpathSync } from "fs";
|
|
350
353
|
import { resolve } from "path";
|
|
351
354
|
function isDestructiveBash(command) {
|
|
@@ -466,7 +469,7 @@ function applyInjectionGuard(handlers, options = {}) {
|
|
|
466
469
|
}
|
|
467
470
|
|
|
468
471
|
// src/mcp/middleware/compaction.ts
|
|
469
|
-
|
|
472
|
+
init_dist2();
|
|
470
473
|
var DEFAULT_PIPELINE = new CompactionPipeline([
|
|
471
474
|
new StructuralStrategy(),
|
|
472
475
|
new TruncationStrategy()
|
|
@@ -553,6 +556,185 @@ function applyCompaction(handlers) {
|
|
|
553
556
|
return wrapped;
|
|
554
557
|
}
|
|
555
558
|
|
|
559
|
+
// src/mcp/tools/search-sessions.ts
|
|
560
|
+
init_dist2();
|
|
561
|
+
init_dist();
|
|
562
|
+
var searchSessionsDefinition = {
|
|
563
|
+
name: "search_sessions",
|
|
564
|
+
description: "Full-text search over archived + live session content (Hermes Phase 1, FTS5/BM25).",
|
|
565
|
+
inputSchema: {
|
|
566
|
+
type: "object",
|
|
567
|
+
properties: {
|
|
568
|
+
path: { type: "string", description: "Path to project root" },
|
|
569
|
+
query: { type: "string", description: "FTS5 query (bare words AND-joined)" },
|
|
570
|
+
limit: { type: "number", description: "Max results (default 20)" },
|
|
571
|
+
archivedOnly: {
|
|
572
|
+
type: "boolean",
|
|
573
|
+
description: "Only search archived sessions (skip live)."
|
|
574
|
+
},
|
|
575
|
+
fileKinds: {
|
|
576
|
+
type: "array",
|
|
577
|
+
items: { type: "string", enum: INDEXED_FILE_KINDS },
|
|
578
|
+
description: "Subset of file kinds to search."
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
required: ["path", "query"]
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
async function handleSearchSessions(input) {
|
|
585
|
+
try {
|
|
586
|
+
const pathInput = typeof input.path === "string" ? input.path : "";
|
|
587
|
+
const projectPath = sanitizePath(pathInput);
|
|
588
|
+
const query = typeof input.query === "string" ? input.query : "";
|
|
589
|
+
if (!query || query.trim() === "") {
|
|
590
|
+
return resultToMcpResponse(Err({ message: "query is required" }));
|
|
591
|
+
}
|
|
592
|
+
const limit = typeof input.limit === "number" ? input.limit : void 0;
|
|
593
|
+
const archivedOnly = input.archivedOnly === true;
|
|
594
|
+
const fileKinds = Array.isArray(input.fileKinds) ? input.fileKinds.filter(
|
|
595
|
+
(k) => typeof k === "string" && INDEXED_FILE_KINDS.includes(k)
|
|
596
|
+
) : void 0;
|
|
597
|
+
const orchestrator = await import("@harness-engineering/orchestrator");
|
|
598
|
+
const idx = orchestrator.openSearchIndex(projectPath);
|
|
599
|
+
try {
|
|
600
|
+
const result = idx.search(query, {
|
|
601
|
+
...limit !== void 0 && { limit },
|
|
602
|
+
...archivedOnly && { archivedOnly },
|
|
603
|
+
...fileKinds && fileKinds.length > 0 && { fileKinds }
|
|
604
|
+
});
|
|
605
|
+
return resultToMcpResponse(Ok(result));
|
|
606
|
+
} finally {
|
|
607
|
+
idx.close();
|
|
608
|
+
}
|
|
609
|
+
} catch (e) {
|
|
610
|
+
return resultToMcpResponse(Err({ message: e instanceof Error ? e.message : String(e) }));
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// src/mcp/tools/summarize-session.ts
|
|
615
|
+
init_dist2();
|
|
616
|
+
import * as fs2 from "fs";
|
|
617
|
+
import * as path2 from "path";
|
|
618
|
+
var summarizeSessionDefinition = {
|
|
619
|
+
name: "summarize_session",
|
|
620
|
+
description: "Generate or regenerate the LLM `llm-summary.md` for an archived session (Hermes Phase 1).",
|
|
621
|
+
inputSchema: {
|
|
622
|
+
type: "object",
|
|
623
|
+
properties: {
|
|
624
|
+
path: { type: "string", description: "Path to project root" },
|
|
625
|
+
sessionId: {
|
|
626
|
+
type: "string",
|
|
627
|
+
description: "Archived session id (basename of the directory inside .harness/archive/sessions/)"
|
|
628
|
+
},
|
|
629
|
+
force: {
|
|
630
|
+
type: "boolean",
|
|
631
|
+
description: "If true, overwrite an existing llm-summary.md. Default: false (no-op when present)."
|
|
632
|
+
}
|
|
633
|
+
},
|
|
634
|
+
required: ["path", "sessionId"]
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
async function resolveAnthropicProvider() {
|
|
638
|
+
try {
|
|
639
|
+
const intelligence = await import("@harness-engineering/intelligence");
|
|
640
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
641
|
+
if (!apiKey) return null;
|
|
642
|
+
const Provider = intelligence.AnthropicAnalysisProvider;
|
|
643
|
+
if (typeof Provider !== "function") return null;
|
|
644
|
+
return new Provider({ apiKey });
|
|
645
|
+
} catch {
|
|
646
|
+
return null;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
async function handleSummarizeSession(input) {
|
|
650
|
+
try {
|
|
651
|
+
const pathInput = typeof input.path === "string" ? input.path : "";
|
|
652
|
+
const projectPath = sanitizePath(pathInput);
|
|
653
|
+
const sessionId = typeof input.sessionId === "string" ? input.sessionId : "";
|
|
654
|
+
if (!sessionId) {
|
|
655
|
+
return resultToMcpResponse(Err({ message: "sessionId is required" }));
|
|
656
|
+
}
|
|
657
|
+
const force = input.force === true;
|
|
658
|
+
const archiveDir = path2.join(projectPath, ".harness", "archive", "sessions", sessionId);
|
|
659
|
+
if (!fs2.existsSync(archiveDir)) {
|
|
660
|
+
return resultToMcpResponse(Err({ message: `archived session not found: ${sessionId}` }));
|
|
661
|
+
}
|
|
662
|
+
const llmSummary = path2.join(archiveDir, "llm-summary.md");
|
|
663
|
+
if (fs2.existsSync(llmSummary) && !force) {
|
|
664
|
+
return resultToMcpResponse(
|
|
665
|
+
Ok({
|
|
666
|
+
sessionId,
|
|
667
|
+
status: "exists",
|
|
668
|
+
filePath: llmSummary
|
|
669
|
+
})
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
const provider = await resolveAnthropicProvider();
|
|
673
|
+
if (!provider) {
|
|
674
|
+
return resultToMcpResponse(
|
|
675
|
+
Err({
|
|
676
|
+
message: "No analysis provider configured. Set ANTHROPIC_API_KEY to enable session summarization."
|
|
677
|
+
})
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
const { summarizeArchivedSession } = await import("@harness-engineering/orchestrator");
|
|
681
|
+
const result = await summarizeArchivedSession({
|
|
682
|
+
archiveDir,
|
|
683
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
684
|
+
provider
|
|
685
|
+
});
|
|
686
|
+
if (!result.ok) {
|
|
687
|
+
return resultToMcpResponse(Err({ message: result.error.message }));
|
|
688
|
+
}
|
|
689
|
+
return resultToMcpResponse(
|
|
690
|
+
Ok({
|
|
691
|
+
sessionId,
|
|
692
|
+
status: "wrote",
|
|
693
|
+
filePath: result.value.filePath,
|
|
694
|
+
meta: result.value.meta
|
|
695
|
+
})
|
|
696
|
+
);
|
|
697
|
+
} catch (e) {
|
|
698
|
+
return resultToMcpResponse(Err({ message: e instanceof Error ? e.message : String(e) }));
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// src/mcp/tools/insights-summary.ts
|
|
703
|
+
init_dist2();
|
|
704
|
+
init_dist();
|
|
705
|
+
var insightsSummaryDefinition = {
|
|
706
|
+
name: "insights_summary",
|
|
707
|
+
description: "Composite report combining health, entropy, decay, attention, and impact (Hermes Phase 1).",
|
|
708
|
+
inputSchema: {
|
|
709
|
+
type: "object",
|
|
710
|
+
properties: {
|
|
711
|
+
path: { type: "string", description: "Path to project root" },
|
|
712
|
+
skip: {
|
|
713
|
+
type: "array",
|
|
714
|
+
items: { type: "string", enum: INSIGHTS_KEYS },
|
|
715
|
+
description: "Top-level keys to skip."
|
|
716
|
+
}
|
|
717
|
+
},
|
|
718
|
+
required: ["path"]
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
async function handleInsightsSummary(input) {
|
|
722
|
+
try {
|
|
723
|
+
const pathInput = typeof input.path === "string" ? input.path : "";
|
|
724
|
+
const projectPath = sanitizePath(pathInput);
|
|
725
|
+
const skip = Array.isArray(input.skip) ? input.skip.filter(
|
|
726
|
+
(k) => typeof k === "string" && INSIGHTS_KEYS.includes(k)
|
|
727
|
+
) : void 0;
|
|
728
|
+
const { composeInsights } = await import("./dist-OHDQBTSO.js");
|
|
729
|
+
const report = await composeInsights(projectPath, {
|
|
730
|
+
...skip && skip.length > 0 && { skip }
|
|
731
|
+
});
|
|
732
|
+
return resultToMcpResponse(Ok(report));
|
|
733
|
+
} catch (e) {
|
|
734
|
+
return resultToMcpResponse(Err({ message: e instanceof Error ? e.message : String(e) }));
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
556
738
|
// src/mcp/tools/linter.ts
|
|
557
739
|
var generateLinterDefinition = {
|
|
558
740
|
name: "generate_linter",
|
|
@@ -622,8 +804,8 @@ async function handleValidateLinterConfig(input) {
|
|
|
622
804
|
}
|
|
623
805
|
|
|
624
806
|
// src/mcp/tools/init.ts
|
|
625
|
-
import * as
|
|
626
|
-
import * as
|
|
807
|
+
import * as path3 from "path";
|
|
808
|
+
import * as fs3 from "fs";
|
|
627
809
|
var initProjectDefinition = {
|
|
628
810
|
name: "init_project",
|
|
629
811
|
description: "Scaffold a new harness engineering project from a template",
|
|
@@ -656,7 +838,7 @@ function findFrameworkLanguage(engine, framework) {
|
|
|
656
838
|
return templates.value.find((t) => t.framework === framework)?.language;
|
|
657
839
|
}
|
|
658
840
|
function tryDetectFramework(engine, safePath, input) {
|
|
659
|
-
if (input.framework || input.language || !
|
|
841
|
+
if (input.framework || input.language || !fs3.existsSync(safePath)) return null;
|
|
660
842
|
const result = engine.detectFramework(safePath);
|
|
661
843
|
if (!result.ok || !result.value || result.value.length === 0) return null;
|
|
662
844
|
const candidates = result.value.map((c) => `${c.framework} (${c.language}, score: ${c.score})`).join(", ");
|
|
@@ -688,7 +870,7 @@ function scaffoldMcp(engine, safePath, i, language) {
|
|
|
688
870
|
const resolveResult = engine.resolveTemplate(level, i.framework, language);
|
|
689
871
|
if (!resolveResult.ok) return resultToMcpResponse(resolveResult);
|
|
690
872
|
const renderResult = engine.render(resolveResult.value, {
|
|
691
|
-
projectName: i.name ??
|
|
873
|
+
projectName: i.name ?? path3.basename(safePath),
|
|
692
874
|
level: level ?? "",
|
|
693
875
|
...i.framework !== void 0 && { framework: i.framework },
|
|
694
876
|
...language !== void 0 && { language }
|
|
@@ -719,7 +901,7 @@ ${skippedMsg}`
|
|
|
719
901
|
async function handleInitProject(input) {
|
|
720
902
|
const i = input;
|
|
721
903
|
try {
|
|
722
|
-
const { TemplateEngine } = await import("./engine-
|
|
904
|
+
const { TemplateEngine } = await import("./engine-KZ3PPUYE.js");
|
|
723
905
|
const engine = new TemplateEngine(resolveTemplatesDir());
|
|
724
906
|
const safePath = sanitizePath(i.path);
|
|
725
907
|
const detected = tryDetectFramework(engine, safePath, i);
|
|
@@ -733,15 +915,15 @@ async function handleInitProject(input) {
|
|
|
733
915
|
}
|
|
734
916
|
|
|
735
917
|
// src/mcp/tools/persona.ts
|
|
736
|
-
|
|
737
|
-
import * as
|
|
918
|
+
init_dist2();
|
|
919
|
+
import * as path4 from "path";
|
|
738
920
|
var listPersonasDefinition = {
|
|
739
921
|
name: "list_personas",
|
|
740
922
|
description: "List available agent personas",
|
|
741
923
|
inputSchema: { type: "object", properties: {} }
|
|
742
924
|
};
|
|
743
925
|
async function handleListPersonas() {
|
|
744
|
-
const { listPersonas } = await import("./loader-
|
|
926
|
+
const { listPersonas } = await import("./loader-BNKGM23C.js");
|
|
745
927
|
const result = listPersonas(resolvePersonasDir());
|
|
746
928
|
return resultToMcpResponse(result);
|
|
747
929
|
}
|
|
@@ -765,12 +947,12 @@ async function handleGeneratePersonaArtifacts(input) {
|
|
|
765
947
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.name)) {
|
|
766
948
|
return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.name}`)));
|
|
767
949
|
}
|
|
768
|
-
const { loadPersona } = await import("./loader-
|
|
769
|
-
const { generateRuntime } = await import("./runtime-
|
|
770
|
-
const { generateAgentsMd } = await import("./agents-md-
|
|
771
|
-
const { generateCIWorkflow } = await import("./ci-workflow-
|
|
950
|
+
const { loadPersona } = await import("./loader-BNKGM23C.js");
|
|
951
|
+
const { generateRuntime } = await import("./runtime-W5THSNAL.js");
|
|
952
|
+
const { generateAgentsMd } = await import("./agents-md-2JUQ4FE2.js");
|
|
953
|
+
const { generateCIWorkflow } = await import("./ci-workflow-3JNDZQYD.js");
|
|
772
954
|
const personasDir = resolvePersonasDir();
|
|
773
|
-
const filePath =
|
|
955
|
+
const filePath = path4.join(personasDir, `${input.name}.yaml`);
|
|
774
956
|
if (!filePath.startsWith(personasDir)) {
|
|
775
957
|
return resultToMcpResponse(Err(new Error(`Invalid persona path: ${input.name}`)));
|
|
776
958
|
}
|
|
@@ -823,11 +1005,11 @@ async function handleRunPersona(input) {
|
|
|
823
1005
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.persona)) {
|
|
824
1006
|
return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.persona}`)));
|
|
825
1007
|
}
|
|
826
|
-
const { loadPersona } = await import("./loader-
|
|
1008
|
+
const { loadPersona } = await import("./loader-BNKGM23C.js");
|
|
827
1009
|
const { runPersona } = await import("./runner-AAEF2TXY.js");
|
|
828
1010
|
const { executeSkill } = await import("./skill-executor-MOCUIAYS.js");
|
|
829
1011
|
const personasDir = resolvePersonasDir();
|
|
830
|
-
const filePath =
|
|
1012
|
+
const filePath = path4.join(personasDir, `${input.persona}.yaml`);
|
|
831
1013
|
if (!filePath.startsWith(personasDir)) {
|
|
832
1014
|
return resultToMcpResponse(Err(new Error(`Invalid persona path: ${input.persona}`)));
|
|
833
1015
|
}
|
|
@@ -989,9 +1171,9 @@ async function handleRunAgentTask(input) {
|
|
|
989
1171
|
}
|
|
990
1172
|
|
|
991
1173
|
// src/mcp/tools/skill.ts
|
|
992
|
-
|
|
993
|
-
import * as
|
|
994
|
-
import * as
|
|
1174
|
+
init_dist2();
|
|
1175
|
+
import * as fs5 from "fs";
|
|
1176
|
+
import * as path6 from "path";
|
|
995
1177
|
import { parse as parseYaml } from "yaml";
|
|
996
1178
|
|
|
997
1179
|
// src/skill/dispatcher.ts
|
|
@@ -1178,8 +1360,8 @@ function formatSuggestions(suggestions) {
|
|
|
1178
1360
|
}
|
|
1179
1361
|
|
|
1180
1362
|
// src/skill/stack-profile.ts
|
|
1181
|
-
import
|
|
1182
|
-
import
|
|
1363
|
+
import fs4 from "fs";
|
|
1364
|
+
import path5 from "path";
|
|
1183
1365
|
var SIGNAL_DOMAIN_MAP = {
|
|
1184
1366
|
"prisma/schema.prisma": ["database"],
|
|
1185
1367
|
"drizzle.config.ts": ["database"],
|
|
@@ -1238,8 +1420,8 @@ function generateStackProfile(projectRoot) {
|
|
|
1238
1420
|
const signals = {};
|
|
1239
1421
|
const domainSet = /* @__PURE__ */ new Set();
|
|
1240
1422
|
for (const [pattern, domains] of Object.entries(SIGNAL_DOMAIN_MAP)) {
|
|
1241
|
-
const fullPath =
|
|
1242
|
-
const exists =
|
|
1423
|
+
const fullPath = path5.join(projectRoot, pattern);
|
|
1424
|
+
const exists = fs4.existsSync(fullPath);
|
|
1243
1425
|
signals[pattern] = exists;
|
|
1244
1426
|
if (exists) {
|
|
1245
1427
|
for (const domain of domains) domainSet.add(domain);
|
|
@@ -1252,23 +1434,23 @@ function generateStackProfile(projectRoot) {
|
|
|
1252
1434
|
};
|
|
1253
1435
|
}
|
|
1254
1436
|
function loadOrGenerateProfile(projectRoot) {
|
|
1255
|
-
const profilePath =
|
|
1256
|
-
if (
|
|
1437
|
+
const profilePath = path5.join(projectRoot, ".harness", "stack-profile.json");
|
|
1438
|
+
if (fs4.existsSync(profilePath)) {
|
|
1257
1439
|
try {
|
|
1258
|
-
return JSON.parse(
|
|
1440
|
+
return JSON.parse(fs4.readFileSync(profilePath, "utf-8"));
|
|
1259
1441
|
} catch {
|
|
1260
1442
|
}
|
|
1261
1443
|
}
|
|
1262
1444
|
const profile = generateStackProfile(projectRoot);
|
|
1263
|
-
|
|
1264
|
-
|
|
1445
|
+
fs4.mkdirSync(path5.dirname(profilePath), { recursive: true });
|
|
1446
|
+
fs4.writeFileSync(profilePath, JSON.stringify(profile, null, 2));
|
|
1265
1447
|
return profile;
|
|
1266
1448
|
}
|
|
1267
1449
|
|
|
1268
1450
|
// src/mcp/tools/event-emitter.ts
|
|
1269
1451
|
async function emitSkillEvent(projectPath, event) {
|
|
1270
1452
|
try {
|
|
1271
|
-
const { emitEvent } = await import("./dist-
|
|
1453
|
+
const { emitEvent } = await import("./dist-OHDQBTSO.js");
|
|
1272
1454
|
await emitEvent(projectPath, event);
|
|
1273
1455
|
} catch {
|
|
1274
1456
|
}
|
|
@@ -1303,18 +1485,18 @@ async function handleRunSkill(input) {
|
|
|
1303
1485
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.skill)) {
|
|
1304
1486
|
return resultToMcpResponse(Err(new Error(`Invalid skill name: ${input.skill}`)));
|
|
1305
1487
|
}
|
|
1306
|
-
const skillDir =
|
|
1488
|
+
const skillDir = path6.join(skillsDir, input.skill);
|
|
1307
1489
|
if (!skillDir.startsWith(skillsDir)) {
|
|
1308
1490
|
return resultToMcpResponse(Err(new Error(`Invalid skill path: ${input.skill}`)));
|
|
1309
1491
|
}
|
|
1310
|
-
if (!
|
|
1492
|
+
if (!fs5.existsSync(skillDir)) {
|
|
1311
1493
|
return resultToMcpResponse(Err(new Error(`Skill not found: ${input.skill}`)));
|
|
1312
1494
|
}
|
|
1313
|
-
const skillMdPath =
|
|
1314
|
-
if (!
|
|
1495
|
+
const skillMdPath = path6.join(skillDir, "SKILL.md");
|
|
1496
|
+
if (!fs5.existsSync(skillMdPath)) {
|
|
1315
1497
|
return resultToMcpResponse(Err(new Error(`SKILL.md not found for skill: ${input.skill}`)));
|
|
1316
1498
|
}
|
|
1317
|
-
let content =
|
|
1499
|
+
let content = fs5.readFileSync(skillMdPath, "utf-8");
|
|
1318
1500
|
const projectRoot = input.path ? sanitizePath(input.path) : process.cwd();
|
|
1319
1501
|
const configResult = resolveConfig();
|
|
1320
1502
|
const skillsConfig = configResult.ok ? configResult.value.skills : void 0;
|
|
@@ -1341,9 +1523,9 @@ async function handleRunSkill(input) {
|
|
|
1341
1523
|
}
|
|
1342
1524
|
if (input.path) {
|
|
1343
1525
|
const projectPath = sanitizePath(input.path);
|
|
1344
|
-
const stateFile =
|
|
1345
|
-
if (
|
|
1346
|
-
const stateContent =
|
|
1526
|
+
const stateFile = path6.join(projectPath, ".harness", "state.json");
|
|
1527
|
+
if (fs5.existsSync(stateFile)) {
|
|
1528
|
+
const stateContent = fs5.readFileSync(stateFile, "utf-8");
|
|
1347
1529
|
content += `
|
|
1348
1530
|
|
|
1349
1531
|
---
|
|
@@ -1354,10 +1536,10 @@ ${stateContent}
|
|
|
1354
1536
|
`;
|
|
1355
1537
|
}
|
|
1356
1538
|
}
|
|
1357
|
-
const skillYamlPath =
|
|
1358
|
-
if (
|
|
1539
|
+
const skillYamlPath = path6.join(skillDir, "skill.yaml");
|
|
1540
|
+
if (fs5.existsSync(skillYamlPath)) {
|
|
1359
1541
|
try {
|
|
1360
|
-
const rawYaml =
|
|
1542
|
+
const rawYaml = fs5.readFileSync(skillYamlPath, "utf-8");
|
|
1361
1543
|
const skillMeta = parseYaml(rawYaml);
|
|
1362
1544
|
if (skillMeta.type === "knowledge") {
|
|
1363
1545
|
const boundary = content.indexOf("\n## Details");
|
|
@@ -1440,22 +1622,22 @@ async function handleCreateSkill(input) {
|
|
|
1440
1622
|
}
|
|
1441
1623
|
|
|
1442
1624
|
// src/mcp/resources/skills.ts
|
|
1443
|
-
import * as
|
|
1444
|
-
import * as
|
|
1625
|
+
import * as fs6 from "fs";
|
|
1626
|
+
import * as path7 from "path";
|
|
1445
1627
|
import * as yaml from "yaml";
|
|
1446
1628
|
async function getSkillsResource(projectRoot) {
|
|
1447
|
-
const skillsDir =
|
|
1629
|
+
const skillsDir = path7.join(projectRoot, "agents", "skills", "claude-code");
|
|
1448
1630
|
const skills = [];
|
|
1449
|
-
if (!
|
|
1631
|
+
if (!fs6.existsSync(skillsDir)) {
|
|
1450
1632
|
return JSON.stringify(skills, null, 2);
|
|
1451
1633
|
}
|
|
1452
|
-
const entries =
|
|
1634
|
+
const entries = fs6.readdirSync(skillsDir, { withFileTypes: true });
|
|
1453
1635
|
for (const entry of entries) {
|
|
1454
1636
|
if (!entry.isDirectory()) continue;
|
|
1455
|
-
const skillYamlPath =
|
|
1456
|
-
if (!
|
|
1637
|
+
const skillYamlPath = path7.join(skillsDir, entry.name, "skill.yaml");
|
|
1638
|
+
if (!fs6.existsSync(skillYamlPath)) continue;
|
|
1457
1639
|
try {
|
|
1458
|
-
const content =
|
|
1640
|
+
const content = fs6.readFileSync(skillYamlPath, "utf-8");
|
|
1459
1641
|
const parsed = yaml.parse(content);
|
|
1460
1642
|
skills.push({
|
|
1461
1643
|
name: parsed.name,
|
|
@@ -1471,14 +1653,14 @@ async function getSkillsResource(projectRoot) {
|
|
|
1471
1653
|
}
|
|
1472
1654
|
|
|
1473
1655
|
// src/mcp/resources/rules.ts
|
|
1474
|
-
import * as
|
|
1475
|
-
import * as
|
|
1656
|
+
import * as fs7 from "fs";
|
|
1657
|
+
import * as path8 from "path";
|
|
1476
1658
|
async function getRulesResource(projectRoot) {
|
|
1477
1659
|
const rules = [];
|
|
1478
|
-
const configPath =
|
|
1479
|
-
if (
|
|
1660
|
+
const configPath = path8.join(projectRoot, "harness.config.json");
|
|
1661
|
+
if (fs7.existsSync(configPath)) {
|
|
1480
1662
|
try {
|
|
1481
|
-
const config = JSON.parse(
|
|
1663
|
+
const config = JSON.parse(fs7.readFileSync(configPath, "utf-8"));
|
|
1482
1664
|
if (config.layers) {
|
|
1483
1665
|
rules.push({ type: "layer-enforcement", config: config.layers });
|
|
1484
1666
|
}
|
|
@@ -1491,10 +1673,10 @@ async function getRulesResource(projectRoot) {
|
|
|
1491
1673
|
} catch {
|
|
1492
1674
|
}
|
|
1493
1675
|
}
|
|
1494
|
-
const linterPath =
|
|
1495
|
-
if (
|
|
1676
|
+
const linterPath = path8.join(projectRoot, ".harness", "linter.json");
|
|
1677
|
+
if (fs7.existsSync(linterPath)) {
|
|
1496
1678
|
try {
|
|
1497
|
-
const linterConfig = JSON.parse(
|
|
1679
|
+
const linterConfig = JSON.parse(fs7.readFileSync(linterPath, "utf-8"));
|
|
1498
1680
|
rules.push({ type: "linter", config: linterConfig });
|
|
1499
1681
|
} catch {
|
|
1500
1682
|
}
|
|
@@ -1503,45 +1685,45 @@ async function getRulesResource(projectRoot) {
|
|
|
1503
1685
|
}
|
|
1504
1686
|
|
|
1505
1687
|
// src/mcp/resources/project.ts
|
|
1506
|
-
import * as
|
|
1507
|
-
import * as
|
|
1688
|
+
import * as fs8 from "fs";
|
|
1689
|
+
import * as path9 from "path";
|
|
1508
1690
|
async function getProjectResource(projectRoot) {
|
|
1509
|
-
const agentsPath =
|
|
1510
|
-
if (
|
|
1511
|
-
return
|
|
1691
|
+
const agentsPath = path9.join(projectRoot, "AGENTS.md");
|
|
1692
|
+
if (fs8.existsSync(agentsPath)) {
|
|
1693
|
+
return fs8.readFileSync(agentsPath, "utf-8");
|
|
1512
1694
|
}
|
|
1513
1695
|
return "# No AGENTS.md found";
|
|
1514
1696
|
}
|
|
1515
1697
|
|
|
1516
1698
|
// src/mcp/resources/learnings.ts
|
|
1517
|
-
import * as
|
|
1518
|
-
import * as
|
|
1699
|
+
import * as fs9 from "fs";
|
|
1700
|
+
import * as path10 from "path";
|
|
1519
1701
|
async function getLearningsResource(projectRoot) {
|
|
1520
1702
|
const sections = [];
|
|
1521
|
-
const reviewPath =
|
|
1522
|
-
if (
|
|
1523
|
-
sections.push("## Review Learnings\n\n" +
|
|
1703
|
+
const reviewPath = path10.join(projectRoot, ".harness", "review-learnings.md");
|
|
1704
|
+
if (fs9.existsSync(reviewPath)) {
|
|
1705
|
+
sections.push("## Review Learnings\n\n" + fs9.readFileSync(reviewPath, "utf-8"));
|
|
1524
1706
|
}
|
|
1525
|
-
const antiPath =
|
|
1526
|
-
if (
|
|
1527
|
-
sections.push("## Anti-Pattern Log\n\n" +
|
|
1707
|
+
const antiPath = path10.join(projectRoot, ".harness", "anti-patterns.md");
|
|
1708
|
+
if (fs9.existsSync(antiPath)) {
|
|
1709
|
+
sections.push("## Anti-Pattern Log\n\n" + fs9.readFileSync(antiPath, "utf-8"));
|
|
1528
1710
|
}
|
|
1529
1711
|
return sections.length > 0 ? sections.join("\n\n---\n\n") : "No learnings files found.";
|
|
1530
1712
|
}
|
|
1531
1713
|
|
|
1532
1714
|
// src/mcp/tools/state.ts
|
|
1533
|
-
|
|
1715
|
+
init_dist2();
|
|
1534
1716
|
|
|
1535
1717
|
// src/mcp/tools/roadmap-auto-sync.ts
|
|
1536
|
-
|
|
1537
|
-
import * as
|
|
1538
|
-
import * as
|
|
1718
|
+
init_dist2();
|
|
1719
|
+
import * as fs10 from "fs";
|
|
1720
|
+
import * as path11 from "path";
|
|
1539
1721
|
async function autoSyncRoadmap(projectPath) {
|
|
1540
1722
|
try {
|
|
1541
|
-
const roadmapFile =
|
|
1542
|
-
if (!
|
|
1543
|
-
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-
|
|
1544
|
-
const raw =
|
|
1723
|
+
const roadmapFile = path11.join(projectPath, "docs", "roadmap.md");
|
|
1724
|
+
if (!fs10.existsSync(roadmapFile)) return;
|
|
1725
|
+
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-OHDQBTSO.js");
|
|
1726
|
+
const raw = fs10.readFileSync(roadmapFile, "utf-8");
|
|
1545
1727
|
const parseResult = parseRoadmap(raw);
|
|
1546
1728
|
if (!parseResult.ok) return;
|
|
1547
1729
|
const roadmap = parseResult.value;
|
|
@@ -1551,7 +1733,7 @@ async function autoSyncRoadmap(projectPath) {
|
|
|
1551
1733
|
return;
|
|
1552
1734
|
}
|
|
1553
1735
|
applySyncChanges(roadmap, syncResult.value);
|
|
1554
|
-
|
|
1736
|
+
fs10.writeFileSync(roadmapFile, serializeRoadmap(roadmap), "utf-8");
|
|
1555
1737
|
await triggerExternalSync(projectPath, roadmapFile);
|
|
1556
1738
|
} catch {
|
|
1557
1739
|
}
|
|
@@ -1560,8 +1742,8 @@ async function triggerExternalSync(projectPath, roadmapFile) {
|
|
|
1560
1742
|
try {
|
|
1561
1743
|
const trackerConfig = loadTrackerSyncConfig(projectPath);
|
|
1562
1744
|
if (!trackerConfig) return;
|
|
1563
|
-
const projectEnvPath =
|
|
1564
|
-
if (
|
|
1745
|
+
const projectEnvPath = path11.join(projectPath, ".env");
|
|
1746
|
+
if (fs10.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
|
|
1565
1747
|
const { config: loadDotenv } = await import("dotenv");
|
|
1566
1748
|
loadDotenv({ path: projectEnvPath });
|
|
1567
1749
|
}
|
|
@@ -1570,7 +1752,7 @@ async function triggerExternalSync(projectPath, roadmapFile) {
|
|
|
1570
1752
|
console.warn("[roadmap-sync] GITHUB_TOKEN not found \u2014 external sync skipped");
|
|
1571
1753
|
return;
|
|
1572
1754
|
}
|
|
1573
|
-
const { fullSync, GitHubIssuesSyncAdapter } = await import("./dist-
|
|
1755
|
+
const { fullSync, GitHubIssuesSyncAdapter } = await import("./dist-OHDQBTSO.js");
|
|
1574
1756
|
const adapter = new GitHubIssuesSyncAdapter({
|
|
1575
1757
|
token,
|
|
1576
1758
|
config: trackerConfig
|
|
@@ -1667,12 +1849,12 @@ var manageStateDefinition = {
|
|
|
1667
1849
|
}
|
|
1668
1850
|
};
|
|
1669
1851
|
async function handleShow(projectPath, input) {
|
|
1670
|
-
const { loadState } = await import("./dist-
|
|
1852
|
+
const { loadState } = await import("./dist-OHDQBTSO.js");
|
|
1671
1853
|
return resultToMcpResponse(await loadState(projectPath, input.stream, input.session));
|
|
1672
1854
|
}
|
|
1673
1855
|
async function handleLearn(projectPath, input) {
|
|
1674
1856
|
if (!input.learning) return mcpError("Error: learning is required for learn action");
|
|
1675
|
-
const { appendLearning } = await import("./dist-
|
|
1857
|
+
const { appendLearning } = await import("./dist-OHDQBTSO.js");
|
|
1676
1858
|
const result = await appendLearning(
|
|
1677
1859
|
projectPath,
|
|
1678
1860
|
input.learning,
|
|
@@ -1687,7 +1869,7 @@ async function handleLearn(projectPath, input) {
|
|
|
1687
1869
|
async function handleFailure(projectPath, input) {
|
|
1688
1870
|
if (!input.description) return mcpError("Error: description is required for failure action");
|
|
1689
1871
|
if (!input.failureType) return mcpError("Error: failureType is required for failure action");
|
|
1690
|
-
const { appendFailure } = await import("./dist-
|
|
1872
|
+
const { appendFailure } = await import("./dist-OHDQBTSO.js");
|
|
1691
1873
|
const result = await appendFailure(
|
|
1692
1874
|
projectPath,
|
|
1693
1875
|
input.description,
|
|
@@ -1706,19 +1888,19 @@ async function handleFailure(projectPath, input) {
|
|
|
1706
1888
|
return resultToMcpResponse(Ok({ recorded: true }));
|
|
1707
1889
|
}
|
|
1708
1890
|
async function handleArchive(projectPath, input) {
|
|
1709
|
-
const { archiveFailures } = await import("./dist-
|
|
1891
|
+
const { archiveFailures } = await import("./dist-OHDQBTSO.js");
|
|
1710
1892
|
const result = await archiveFailures(projectPath, input.stream, input.session);
|
|
1711
1893
|
if (!result.ok) return resultToMcpResponse(result);
|
|
1712
1894
|
return resultToMcpResponse(Ok({ archived: true }));
|
|
1713
1895
|
}
|
|
1714
1896
|
async function handleReset(projectPath, input) {
|
|
1715
|
-
const { saveState, DEFAULT_STATE } = await import("./dist-
|
|
1897
|
+
const { saveState, DEFAULT_STATE } = await import("./dist-OHDQBTSO.js");
|
|
1716
1898
|
const result = await saveState(projectPath, { ...DEFAULT_STATE }, input.stream, input.session);
|
|
1717
1899
|
if (!result.ok) return resultToMcpResponse(result);
|
|
1718
1900
|
return resultToMcpResponse(Ok({ reset: true }));
|
|
1719
1901
|
}
|
|
1720
1902
|
async function handleGate(projectPath, input) {
|
|
1721
|
-
const { runMechanicalGate } = await import("./dist-
|
|
1903
|
+
const { runMechanicalGate } = await import("./dist-OHDQBTSO.js");
|
|
1722
1904
|
const result = await runMechanicalGate(projectPath);
|
|
1723
1905
|
if (result.ok) {
|
|
1724
1906
|
await emitSkillEvent(projectPath, {
|
|
@@ -1738,7 +1920,7 @@ async function handleGate(projectPath, input) {
|
|
|
1738
1920
|
}
|
|
1739
1921
|
async function handleSaveHandoff(projectPath, input) {
|
|
1740
1922
|
if (!input.handoff) return mcpError("Error: handoff is required for save-handoff action");
|
|
1741
|
-
const { saveHandoff } = await import("./dist-
|
|
1923
|
+
const { saveHandoff } = await import("./dist-OHDQBTSO.js");
|
|
1742
1924
|
const result = await saveHandoff(
|
|
1743
1925
|
projectPath,
|
|
1744
1926
|
input.handoff,
|
|
@@ -1760,7 +1942,7 @@ async function handleSaveHandoff(projectPath, input) {
|
|
|
1760
1942
|
return resultToMcpResponse(Ok({ saved: true }));
|
|
1761
1943
|
}
|
|
1762
1944
|
async function handleLoadHandoff(projectPath, input) {
|
|
1763
|
-
const { loadHandoff } = await import("./dist-
|
|
1945
|
+
const { loadHandoff } = await import("./dist-OHDQBTSO.js");
|
|
1764
1946
|
return resultToMcpResponse(await loadHandoff(projectPath, input.stream, input.session));
|
|
1765
1947
|
}
|
|
1766
1948
|
async function handleAppendEntry(projectPath, input) {
|
|
@@ -1768,7 +1950,7 @@ async function handleAppendEntry(projectPath, input) {
|
|
|
1768
1950
|
if (!input.authorSkill) return mcpError("Error: authorSkill is required for append_entry action");
|
|
1769
1951
|
if (!input.content) return mcpError("Error: content is required for append_entry action");
|
|
1770
1952
|
if (input.session) {
|
|
1771
|
-
const { appendSessionEntry } = await import("./dist-
|
|
1953
|
+
const { appendSessionEntry } = await import("./dist-OHDQBTSO.js");
|
|
1772
1954
|
const result = await appendSessionEntry(
|
|
1773
1955
|
projectPath,
|
|
1774
1956
|
input.session,
|
|
@@ -1781,7 +1963,7 @@ async function handleAppendEntry(projectPath, input) {
|
|
|
1781
1963
|
if (input.section !== "decisions") {
|
|
1782
1964
|
return mcpError("Error: session is required for non-decisions sections");
|
|
1783
1965
|
}
|
|
1784
|
-
const { loadState, saveState } = await import("./dist-
|
|
1966
|
+
const { loadState, saveState } = await import("./dist-OHDQBTSO.js");
|
|
1785
1967
|
const lr = await loadState(projectPath, input.stream);
|
|
1786
1968
|
if (!lr.ok) return resultToMcpResponse(lr);
|
|
1787
1969
|
lr.value.decisions.push({
|
|
@@ -1799,7 +1981,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
|
|
|
1799
1981
|
if (!input.entryId) return mcpError("Error: entryId is required for update_entry_status action");
|
|
1800
1982
|
if (!input.newStatus)
|
|
1801
1983
|
return mcpError("Error: newStatus is required for update_entry_status action");
|
|
1802
|
-
const { updateSessionEntryStatus } = await import("./dist-
|
|
1984
|
+
const { updateSessionEntryStatus } = await import("./dist-OHDQBTSO.js");
|
|
1803
1985
|
const result = await updateSessionEntryStatus(
|
|
1804
1986
|
projectPath,
|
|
1805
1987
|
input.session,
|
|
@@ -1812,7 +1994,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
|
|
|
1812
1994
|
async function handleReadSection(projectPath, input) {
|
|
1813
1995
|
if (!input.session) return mcpError("Error: session is required for read_section action");
|
|
1814
1996
|
if (!input.section) return mcpError("Error: section is required for read_section action");
|
|
1815
|
-
const { readSessionSection } = await import("./dist-
|
|
1997
|
+
const { readSessionSection } = await import("./dist-OHDQBTSO.js");
|
|
1816
1998
|
const result = await readSessionSection(
|
|
1817
1999
|
projectPath,
|
|
1818
2000
|
input.session,
|
|
@@ -1822,14 +2004,16 @@ async function handleReadSection(projectPath, input) {
|
|
|
1822
2004
|
}
|
|
1823
2005
|
async function handleReadSections(projectPath, input) {
|
|
1824
2006
|
if (!input.session) return mcpError("Error: session is required for read_sections action");
|
|
1825
|
-
const { readSessionSections } = await import("./dist-
|
|
2007
|
+
const { readSessionSections } = await import("./dist-OHDQBTSO.js");
|
|
1826
2008
|
const result = await readSessionSections(projectPath, input.session);
|
|
1827
2009
|
return resultToMcpResponse(result);
|
|
1828
2010
|
}
|
|
1829
2011
|
async function handleArchiveSession(projectPath, input) {
|
|
1830
2012
|
if (!input.session) return mcpError("Error: session is required for archive_session action");
|
|
1831
|
-
const { archiveSession } = await import("./dist-
|
|
1832
|
-
const
|
|
2013
|
+
const { archiveSession } = await import("./dist-OHDQBTSO.js");
|
|
2014
|
+
const { buildArchiveHooks } = await import("@harness-engineering/orchestrator");
|
|
2015
|
+
const hooks = buildArchiveHooks({ projectPath });
|
|
2016
|
+
const result = await archiveSession(projectPath, input.session, { hooks });
|
|
1833
2017
|
if (!result.ok) return resultToMcpResponse(result);
|
|
1834
2018
|
await autoSyncRoadmap(projectPath);
|
|
1835
2019
|
return resultToMcpResponse(Ok({ archived: true }));
|
|
@@ -1908,7 +2092,7 @@ var listStreamsDefinition = {
|
|
|
1908
2092
|
};
|
|
1909
2093
|
async function handleListStreams(input) {
|
|
1910
2094
|
try {
|
|
1911
|
-
const { listStreams, loadStreamIndex } = await import("./dist-
|
|
2095
|
+
const { listStreams, loadStreamIndex } = await import("./dist-OHDQBTSO.js");
|
|
1912
2096
|
const projectPath = sanitizePath(input.path);
|
|
1913
2097
|
const indexResult = await loadStreamIndex(projectPath);
|
|
1914
2098
|
const streamsResult = await listStreams(projectPath);
|
|
@@ -1946,7 +2130,7 @@ var checkPhaseGateDefinition = {
|
|
|
1946
2130
|
};
|
|
1947
2131
|
async function handleCheckPhaseGate(input) {
|
|
1948
2132
|
try {
|
|
1949
|
-
const { runCheckPhaseGate } = await import("./check-phase-gate-
|
|
2133
|
+
const { runCheckPhaseGate } = await import("./check-phase-gate-XMU6LLUQ.js");
|
|
1950
2134
|
const result = await runCheckPhaseGate({ cwd: sanitizePath(input.path) });
|
|
1951
2135
|
if (result.ok) {
|
|
1952
2136
|
return { content: [{ type: "text", text: JSON.stringify(result.value) }] };
|
|
@@ -1966,7 +2150,7 @@ async function handleCheckPhaseGate(input) {
|
|
|
1966
2150
|
}
|
|
1967
2151
|
|
|
1968
2152
|
// src/mcp/tools/cross-check.ts
|
|
1969
|
-
import * as
|
|
2153
|
+
import * as path12 from "path";
|
|
1970
2154
|
var validateCrossCheckDefinition = {
|
|
1971
2155
|
name: "validate_cross_check",
|
|
1972
2156
|
description: "Validate plan-to-implementation coverage: checks that specs have plans and plans have implementations, detects staleness",
|
|
@@ -2002,15 +2186,15 @@ async function handleValidateCrossCheck(input) {
|
|
|
2002
2186
|
};
|
|
2003
2187
|
}
|
|
2004
2188
|
try {
|
|
2005
|
-
const { runCrossCheck } = await import("./validate-cross-check-
|
|
2006
|
-
const specsDir =
|
|
2189
|
+
const { runCrossCheck } = await import("./validate-cross-check-BUAGBAPO.js");
|
|
2190
|
+
const specsDir = path12.resolve(projectPath, input.specsDir ?? "docs/specs");
|
|
2007
2191
|
if (!specsDir.startsWith(projectPath)) {
|
|
2008
2192
|
return {
|
|
2009
2193
|
content: [{ type: "text", text: "Error: specsDir escapes project root" }],
|
|
2010
2194
|
isError: true
|
|
2011
2195
|
};
|
|
2012
2196
|
}
|
|
2013
|
-
const plansDir =
|
|
2197
|
+
const plansDir = path12.resolve(projectPath, input.plansDir ?? "docs/plans");
|
|
2014
2198
|
if (!plansDir.startsWith(projectPath)) {
|
|
2015
2199
|
return {
|
|
2016
2200
|
content: [{ type: "text", text: "Error: plansDir escapes project root" }],
|
|
@@ -2040,18 +2224,18 @@ async function handleValidateCrossCheck(input) {
|
|
|
2040
2224
|
}
|
|
2041
2225
|
|
|
2042
2226
|
// src/mcp/tools/generate-slash-commands.ts
|
|
2043
|
-
|
|
2227
|
+
init_dist2();
|
|
2044
2228
|
|
|
2045
2229
|
// src/commands/generate-slash-commands.ts
|
|
2046
2230
|
import { Command } from "commander";
|
|
2047
|
-
import
|
|
2048
|
-
import
|
|
2231
|
+
import fs13 from "fs";
|
|
2232
|
+
import path15 from "path";
|
|
2049
2233
|
import os from "os";
|
|
2050
2234
|
import readline from "readline";
|
|
2051
2235
|
|
|
2052
2236
|
// src/slash-commands/normalize.ts
|
|
2053
|
-
import
|
|
2054
|
-
import
|
|
2237
|
+
import fs11 from "fs";
|
|
2238
|
+
import path13 from "path";
|
|
2055
2239
|
import { parse as parse2 } from "yaml";
|
|
2056
2240
|
|
|
2057
2241
|
// src/slash-commands/normalize-name.ts
|
|
@@ -2071,7 +2255,7 @@ function normalizeName(skillName) {
|
|
|
2071
2255
|
function readSkillYaml(yamlPath) {
|
|
2072
2256
|
let raw;
|
|
2073
2257
|
try {
|
|
2074
|
-
raw =
|
|
2258
|
+
raw = fs11.readFileSync(yamlPath, "utf-8");
|
|
2075
2259
|
} catch {
|
|
2076
2260
|
return null;
|
|
2077
2261
|
}
|
|
@@ -2135,10 +2319,10 @@ function buildProcessLines(meta) {
|
|
|
2135
2319
|
];
|
|
2136
2320
|
}
|
|
2137
2321
|
function buildSpec(meta, normalized, entry, skillsDir, source) {
|
|
2138
|
-
const skillMdPath =
|
|
2139
|
-
const skillMdContent =
|
|
2140
|
-
const skillMdRelative =
|
|
2141
|
-
const skillYamlRelative =
|
|
2322
|
+
const skillMdPath = path13.join(skillsDir, entry.name, "SKILL.md");
|
|
2323
|
+
const skillMdContent = fs11.existsSync(skillMdPath) ? fs11.readFileSync(skillMdPath, "utf-8") : "";
|
|
2324
|
+
const skillMdRelative = path13.relative(process.cwd(), skillMdPath).replaceAll("\\", "/");
|
|
2325
|
+
const skillYamlRelative = path13.relative(process.cwd(), path13.join(skillsDir, entry.name, "skill.yaml")).replaceAll("\\", "/");
|
|
2142
2326
|
const args = (meta.cli?.args ?? []).map((a) => ({
|
|
2143
2327
|
name: a.name,
|
|
2144
2328
|
description: a.description ?? "",
|
|
@@ -2193,11 +2377,11 @@ function normalizeSkills(skillSources, platforms) {
|
|
|
2193
2377
|
const specs = [];
|
|
2194
2378
|
const nameMap = /* @__PURE__ */ new Map();
|
|
2195
2379
|
for (const { dir: skillsDir, source } of skillSources) {
|
|
2196
|
-
if (!
|
|
2197
|
-
const entries =
|
|
2380
|
+
if (!fs11.existsSync(skillsDir)) continue;
|
|
2381
|
+
const entries = fs11.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
2198
2382
|
for (const entry of entries) {
|
|
2199
|
-
const yamlPath =
|
|
2200
|
-
if (!
|
|
2383
|
+
const yamlPath = path13.join(skillsDir, entry.name, "skill.yaml");
|
|
2384
|
+
if (!fs11.existsSync(yamlPath)) continue;
|
|
2201
2385
|
const result = readSkillYaml(yamlPath);
|
|
2202
2386
|
if (!result) continue;
|
|
2203
2387
|
if (!result.success) {
|
|
@@ -2397,27 +2581,27 @@ function renderCodexAgentsMd(specs) {
|
|
|
2397
2581
|
}
|
|
2398
2582
|
|
|
2399
2583
|
// src/slash-commands/sync-codex.ts
|
|
2400
|
-
import
|
|
2401
|
-
import
|
|
2584
|
+
import fs12 from "fs";
|
|
2585
|
+
import path14 from "path";
|
|
2402
2586
|
function computeCodexSync(outputDir, specs, dryRun) {
|
|
2403
2587
|
const added = [];
|
|
2404
2588
|
const updated = [];
|
|
2405
2589
|
const unchanged = [];
|
|
2406
2590
|
const specSkillNames = /* @__PURE__ */ new Set();
|
|
2407
2591
|
for (const spec of specs) {
|
|
2408
|
-
const mdPath =
|
|
2409
|
-
const skillMd =
|
|
2410
|
-
const skillDir =
|
|
2592
|
+
const mdPath = path14.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
|
|
2593
|
+
const skillMd = fs12.existsSync(mdPath) ? fs12.readFileSync(mdPath, "utf-8") : "";
|
|
2594
|
+
const skillDir = path14.join(outputDir, spec.skillYamlName);
|
|
2411
2595
|
specSkillNames.add(spec.skillYamlName);
|
|
2412
2596
|
const renderedSkillMd = renderCodexSkill(skillMd);
|
|
2413
2597
|
const renderedOpenaiYaml = renderCodexOpenaiYaml(spec);
|
|
2414
|
-
const existingSkillMdPath =
|
|
2415
|
-
const existingOpenaiYamlPath =
|
|
2416
|
-
if (!
|
|
2598
|
+
const existingSkillMdPath = path14.join(skillDir, "SKILL.md");
|
|
2599
|
+
const existingOpenaiYamlPath = path14.join(skillDir, "agents", "openai.yaml");
|
|
2600
|
+
if (!fs12.existsSync(skillDir)) {
|
|
2417
2601
|
added.push(spec.skillYamlName);
|
|
2418
2602
|
} else {
|
|
2419
|
-
const existingSkillMd =
|
|
2420
|
-
const existingOpenaiYaml =
|
|
2603
|
+
const existingSkillMd = fs12.existsSync(existingSkillMdPath) ? fs12.readFileSync(existingSkillMdPath, "utf-8") : "";
|
|
2604
|
+
const existingOpenaiYaml = fs12.existsSync(existingOpenaiYamlPath) ? fs12.readFileSync(existingOpenaiYamlPath, "utf-8") : "";
|
|
2421
2605
|
if (existingSkillMd === renderedSkillMd && existingOpenaiYaml === renderedOpenaiYaml) {
|
|
2422
2606
|
unchanged.push(spec.skillYamlName);
|
|
2423
2607
|
} else {
|
|
@@ -2425,10 +2609,10 @@ function computeCodexSync(outputDir, specs, dryRun) {
|
|
|
2425
2609
|
}
|
|
2426
2610
|
}
|
|
2427
2611
|
if (!dryRun && !unchanged.includes(spec.skillYamlName)) {
|
|
2428
|
-
const agentsSubDir =
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2612
|
+
const agentsSubDir = path14.join(skillDir, "agents");
|
|
2613
|
+
fs12.mkdirSync(agentsSubDir, { recursive: true });
|
|
2614
|
+
fs12.writeFileSync(existingSkillMdPath, renderedSkillMd, "utf-8");
|
|
2615
|
+
fs12.writeFileSync(existingOpenaiYamlPath, renderedOpenaiYaml, "utf-8");
|
|
2432
2616
|
}
|
|
2433
2617
|
}
|
|
2434
2618
|
const removed = detectCodexOrphans(outputDir, specSkillNames);
|
|
@@ -2436,13 +2620,13 @@ function computeCodexSync(outputDir, specs, dryRun) {
|
|
|
2436
2620
|
}
|
|
2437
2621
|
function detectCodexOrphans(outputDir, specSkillNames) {
|
|
2438
2622
|
const removed = [];
|
|
2439
|
-
if (!
|
|
2440
|
-
const existingDirs =
|
|
2623
|
+
if (!fs12.existsSync(outputDir)) return removed;
|
|
2624
|
+
const existingDirs = fs12.readdirSync(outputDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
2441
2625
|
for (const dirName of existingDirs) {
|
|
2442
2626
|
if (specSkillNames.has(dirName)) continue;
|
|
2443
|
-
const skillMdPath =
|
|
2444
|
-
if (
|
|
2445
|
-
const content =
|
|
2627
|
+
const skillMdPath = path14.join(outputDir, dirName, "SKILL.md");
|
|
2628
|
+
if (fs12.existsSync(skillMdPath)) {
|
|
2629
|
+
const content = fs12.readFileSync(skillMdPath, "utf-8");
|
|
2446
2630
|
if (content.includes(GENERATED_HEADER_CODEX)) {
|
|
2447
2631
|
removed.push(dirName);
|
|
2448
2632
|
}
|
|
@@ -2454,19 +2638,19 @@ function detectCodexOrphans(outputDir, specSkillNames) {
|
|
|
2454
2638
|
// src/commands/generate-slash-commands.ts
|
|
2455
2639
|
function resolveOutputDir(platform, opts) {
|
|
2456
2640
|
if (opts.output) {
|
|
2457
|
-
return
|
|
2641
|
+
return path15.join(opts.output, "harness");
|
|
2458
2642
|
}
|
|
2459
2643
|
if (opts.global) {
|
|
2460
2644
|
const home = os.homedir();
|
|
2461
|
-
if (platform === "claude-code") return
|
|
2462
|
-
if (platform === "gemini-cli") return
|
|
2463
|
-
if (platform === "cursor") return
|
|
2464
|
-
return
|
|
2645
|
+
if (platform === "claude-code") return path15.join(home, ".claude", "commands", "harness");
|
|
2646
|
+
if (platform === "gemini-cli") return path15.join(home, ".gemini", "commands", "harness");
|
|
2647
|
+
if (platform === "cursor") return path15.join(home, ".cursor", "rules", "harness");
|
|
2648
|
+
return path15.join(home, ".codex", "harness");
|
|
2465
2649
|
}
|
|
2466
|
-
if (platform === "claude-code") return
|
|
2467
|
-
if (platform === "gemini-cli") return
|
|
2468
|
-
if (platform === "cursor") return
|
|
2469
|
-
return
|
|
2650
|
+
if (platform === "claude-code") return path15.join("agents", "commands", "claude-code", "harness");
|
|
2651
|
+
if (platform === "gemini-cli") return path15.join("agents", "commands", "gemini-cli", "harness");
|
|
2652
|
+
if (platform === "cursor") return path15.join("agents", "commands", "cursor", "harness");
|
|
2653
|
+
return path15.join("agents", "commands", "codex", "harness");
|
|
2470
2654
|
}
|
|
2471
2655
|
async function confirmDeletion(files) {
|
|
2472
2656
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -2482,8 +2666,8 @@ function resolveSkillSources(opts) {
|
|
|
2482
2666
|
const sources = [];
|
|
2483
2667
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
2484
2668
|
function addSource(dir, source) {
|
|
2485
|
-
const resolved =
|
|
2486
|
-
if (!seenPaths.has(resolved) &&
|
|
2669
|
+
const resolved = path15.resolve(dir);
|
|
2670
|
+
if (!seenPaths.has(resolved) && fs13.existsSync(dir)) {
|
|
2487
2671
|
seenPaths.add(resolved);
|
|
2488
2672
|
sources.push({ dir, source });
|
|
2489
2673
|
}
|
|
@@ -2510,7 +2694,7 @@ function resolveAbsoluteExecutionContext(spec) {
|
|
|
2510
2694
|
...spec,
|
|
2511
2695
|
prompt: {
|
|
2512
2696
|
...spec.prompt,
|
|
2513
|
-
executionContext: spec.prompt.executionContext.split("\n").map((line) => line.startsWith("@") ? `@${
|
|
2697
|
+
executionContext: spec.prompt.executionContext.split("\n").map((line) => line.startsWith("@") ? `@${path15.resolve(line.slice(1))}` : line).join("\n")
|
|
2514
2698
|
}
|
|
2515
2699
|
};
|
|
2516
2700
|
}
|
|
@@ -2519,26 +2703,26 @@ function renderSpec(platform, spec, useAbsolutePaths, cursorMode = "rules") {
|
|
|
2519
2703
|
if (cursorMode === "commands") {
|
|
2520
2704
|
return [`${spec.name}.md`, renderCursorCommand(spec)];
|
|
2521
2705
|
}
|
|
2522
|
-
const mdPath2 =
|
|
2523
|
-
const skillMd =
|
|
2706
|
+
const mdPath2 = path15.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
|
|
2707
|
+
const skillMd = fs13.existsSync(mdPath2) ? fs13.readFileSync(mdPath2, "utf-8") : "";
|
|
2524
2708
|
return [`${spec.skillYamlName}.mdc`, renderCursor(spec, skillMd, spec.cursor)];
|
|
2525
2709
|
}
|
|
2526
2710
|
if (platform === "claude-code") {
|
|
2527
2711
|
const renderSpecValue = useAbsolutePaths ? resolveAbsoluteExecutionContext(spec) : spec;
|
|
2528
2712
|
return [`${spec.name}.md`, renderClaudeCode(renderSpecValue)];
|
|
2529
2713
|
}
|
|
2530
|
-
const mdPath =
|
|
2531
|
-
const yamlPath =
|
|
2532
|
-
const mdContent =
|
|
2533
|
-
const yamlContent =
|
|
2714
|
+
const mdPath = path15.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
|
|
2715
|
+
const yamlPath = path15.join(spec.skillsBaseDir, spec.sourceDir, "skill.yaml");
|
|
2716
|
+
const mdContent = fs13.existsSync(mdPath) ? fs13.readFileSync(mdPath, "utf-8") : "";
|
|
2717
|
+
const yamlContent = fs13.existsSync(yamlPath) ? fs13.readFileSync(yamlPath, "utf-8") : "";
|
|
2534
2718
|
return [`${spec.name}.toml`, renderGemini(spec, mdContent, yamlContent)];
|
|
2535
2719
|
}
|
|
2536
2720
|
function generateForCodex(platform, outputDir, specs, dryRun) {
|
|
2537
2721
|
const codexSync = computeCodexSync(outputDir, specs, dryRun);
|
|
2538
|
-
const codexRoot =
|
|
2722
|
+
const codexRoot = path15.dirname(outputDir);
|
|
2539
2723
|
if (!dryRun) {
|
|
2540
|
-
|
|
2541
|
-
|
|
2724
|
+
fs13.mkdirSync(codexRoot, { recursive: true });
|
|
2725
|
+
fs13.writeFileSync(path15.join(codexRoot, "AGENTS.md"), renderCodexAgentsMd(specs), "utf-8");
|
|
2542
2726
|
}
|
|
2543
2727
|
return { platform, ...codexSync, outputDir };
|
|
2544
2728
|
}
|
|
@@ -2569,9 +2753,9 @@ function generateForPlatform(platform, outputDir, specs, opts) {
|
|
|
2569
2753
|
const allUpdated = [...plan.updated];
|
|
2570
2754
|
const allRemoved = [...plan.removed];
|
|
2571
2755
|
const allUnchanged = [...plan.unchanged];
|
|
2572
|
-
const parentDir =
|
|
2756
|
+
const parentDir = path15.dirname(outputDir);
|
|
2573
2757
|
for (const [ns, nsRendered] of customNamespaceRendered) {
|
|
2574
|
-
const nsDir =
|
|
2758
|
+
const nsDir = path15.join(parentDir, ns);
|
|
2575
2759
|
const nsPlan = computeSyncPlan(nsDir, nsRendered);
|
|
2576
2760
|
if (!opts.dryRun) {
|
|
2577
2761
|
applySyncPlan(nsDir, nsRendered, nsPlan, false);
|
|
@@ -2621,13 +2805,13 @@ async function handleOrphanDeletion(results, opts) {
|
|
|
2621
2805
|
const shouldDelete = opts.yes || await confirmDeletion(result.removed);
|
|
2622
2806
|
if (!shouldDelete) continue;
|
|
2623
2807
|
for (const filename of result.removed) {
|
|
2624
|
-
const filePath =
|
|
2625
|
-
if (!
|
|
2626
|
-
const stat =
|
|
2808
|
+
const filePath = path15.join(result.outputDir, filename);
|
|
2809
|
+
if (!fs13.existsSync(filePath)) continue;
|
|
2810
|
+
const stat = fs13.statSync(filePath);
|
|
2627
2811
|
if (stat.isDirectory()) {
|
|
2628
|
-
|
|
2812
|
+
fs13.rmSync(filePath, { recursive: true, force: true });
|
|
2629
2813
|
} else {
|
|
2630
|
-
|
|
2814
|
+
fs13.unlinkSync(filePath);
|
|
2631
2815
|
}
|
|
2632
2816
|
}
|
|
2633
2817
|
}
|
|
@@ -2769,7 +2953,7 @@ async function handleGenerateSlashCommands(input) {
|
|
|
2769
2953
|
// src/mcp/resources/state.ts
|
|
2770
2954
|
async function getStateResource(projectRoot) {
|
|
2771
2955
|
try {
|
|
2772
|
-
const { loadState, migrateToStreams } = await import("./dist-
|
|
2956
|
+
const { loadState, migrateToStreams } = await import("./dist-OHDQBTSO.js");
|
|
2773
2957
|
await migrateToStreams(projectRoot);
|
|
2774
2958
|
const result = await loadState(projectRoot);
|
|
2775
2959
|
if (result.ok) {
|
|
@@ -2794,7 +2978,7 @@ async function getStateResource(projectRoot) {
|
|
|
2794
2978
|
}
|
|
2795
2979
|
|
|
2796
2980
|
// src/mcp/tools/graph/query-graph.ts
|
|
2797
|
-
|
|
2981
|
+
init_dist2();
|
|
2798
2982
|
|
|
2799
2983
|
// src/mcp/tools/graph/shared.ts
|
|
2800
2984
|
function graphNotFoundError() {
|
|
@@ -3092,7 +3276,7 @@ async function handleFindContextFor(input) {
|
|
|
3092
3276
|
}
|
|
3093
3277
|
|
|
3094
3278
|
// src/mcp/tools/graph/get-relationships.ts
|
|
3095
|
-
|
|
3279
|
+
init_dist2();
|
|
3096
3280
|
var getRelationshipsDefinition = {
|
|
3097
3281
|
name: "get_relationships",
|
|
3098
3282
|
description: "Get relationships for a specific node in the knowledge graph, with configurable direction and depth.",
|
|
@@ -3358,7 +3542,7 @@ async function handleGetImpact(input) {
|
|
|
3358
3542
|
}
|
|
3359
3543
|
|
|
3360
3544
|
// src/mcp/tools/graph/ingest-source.ts
|
|
3361
|
-
import * as
|
|
3545
|
+
import * as path16 from "path";
|
|
3362
3546
|
var ingestSourceDefinition = {
|
|
3363
3547
|
name: "ingest_source",
|
|
3364
3548
|
description: "Ingest sources into the project knowledge graph. Supports code analysis, knowledge documents, git history, or all at once.",
|
|
@@ -3378,10 +3562,10 @@ var ingestSourceDefinition = {
|
|
|
3378
3562
|
async function handleIngestSource(input) {
|
|
3379
3563
|
try {
|
|
3380
3564
|
const projectPath = sanitizePath(input.path);
|
|
3381
|
-
const graphDir =
|
|
3565
|
+
const graphDir = path16.join(projectPath, ".harness", "graph");
|
|
3382
3566
|
const { GraphStore, CodeIngestor, TopologicalLinker, KnowledgeIngestor, GitIngestor } = await import("./dist-QPWXPCPL.js");
|
|
3383
|
-
const
|
|
3384
|
-
await
|
|
3567
|
+
const fs18 = await import("fs/promises");
|
|
3568
|
+
await fs18.mkdir(graphDir, { recursive: true });
|
|
3385
3569
|
const store = new GraphStore();
|
|
3386
3570
|
await store.load(graphDir);
|
|
3387
3571
|
const results = [];
|
|
@@ -3404,7 +3588,7 @@ async function handleIngestSource(input) {
|
|
|
3404
3588
|
}
|
|
3405
3589
|
if (input.source === "business-signals" || input.source === "all") {
|
|
3406
3590
|
const { createExtractionRunner } = await import("./dist-QPWXPCPL.js");
|
|
3407
|
-
const extractedDir =
|
|
3591
|
+
const extractedDir = path16.join(projectPath, ".harness", "knowledge", "extracted");
|
|
3408
3592
|
const signalsResult = await createExtractionRunner().run(projectPath, store, extractedDir);
|
|
3409
3593
|
results.push(signalsResult);
|
|
3410
3594
|
}
|
|
@@ -3444,7 +3628,7 @@ async function handleIngestSource(input) {
|
|
|
3444
3628
|
}
|
|
3445
3629
|
|
|
3446
3630
|
// src/mcp/tools/graph/detect-anomalies.ts
|
|
3447
|
-
|
|
3631
|
+
init_dist2();
|
|
3448
3632
|
var detectAnomaliesDefinition = {
|
|
3449
3633
|
name: "detect_anomalies",
|
|
3450
3634
|
description: "Detect structural anomalies \u2014 statistical outliers across code metrics and topological single points of failure in the import graph",
|
|
@@ -3675,8 +3859,8 @@ async function handleComputeBlastRadius(input) {
|
|
|
3675
3859
|
}
|
|
3676
3860
|
|
|
3677
3861
|
// src/mcp/resources/graph.ts
|
|
3678
|
-
import * as
|
|
3679
|
-
import * as
|
|
3862
|
+
import * as fs14 from "fs/promises";
|
|
3863
|
+
import * as path17 from "path";
|
|
3680
3864
|
var MAX_ITEMS = 5e3;
|
|
3681
3865
|
function formatStaleness(isoTimestamp) {
|
|
3682
3866
|
const then = new Date(isoTimestamp).getTime();
|
|
@@ -3699,9 +3883,9 @@ function countByType(items) {
|
|
|
3699
3883
|
return counts;
|
|
3700
3884
|
}
|
|
3701
3885
|
async function readLastScanTimestamp(projectRoot) {
|
|
3702
|
-
const metadataPath =
|
|
3886
|
+
const metadataPath = path17.join(projectRoot, ".harness", "graph", "metadata.json");
|
|
3703
3887
|
try {
|
|
3704
|
-
const raw = JSON.parse(await
|
|
3888
|
+
const raw = JSON.parse(await fs14.readFile(metadataPath, "utf-8"));
|
|
3705
3889
|
return raw.lastScanTimestamp ?? null;
|
|
3706
3890
|
} catch {
|
|
3707
3891
|
return null;
|
|
@@ -3771,7 +3955,7 @@ async function getRelationshipsResource(projectRoot) {
|
|
|
3771
3955
|
}
|
|
3772
3956
|
|
|
3773
3957
|
// src/mcp/tools/agent-definitions.ts
|
|
3774
|
-
|
|
3958
|
+
init_dist2();
|
|
3775
3959
|
var generateAgentDefinitionsDefinition = {
|
|
3776
3960
|
name: "generate_agent_definitions",
|
|
3777
3961
|
description: "Generate agent definition files from personas for Claude Code and Gemini CLI",
|
|
@@ -3789,7 +3973,7 @@ var generateAgentDefinitionsDefinition = {
|
|
|
3789
3973
|
}
|
|
3790
3974
|
};
|
|
3791
3975
|
async function handleGenerateAgentDefinitions(input) {
|
|
3792
|
-
const { generateAgentDefinitions } = await import("./generate-agent-definitions-
|
|
3976
|
+
const { generateAgentDefinitions } = await import("./generate-agent-definitions-SZA4QIHN.js");
|
|
3793
3977
|
const platforms = input.platform === "all" || !input.platform ? ["claude-code", "gemini-cli"] : [input.platform];
|
|
3794
3978
|
const results = generateAgentDefinitions({
|
|
3795
3979
|
platforms: [...platforms],
|
|
@@ -3800,12 +3984,12 @@ async function handleGenerateAgentDefinitions(input) {
|
|
|
3800
3984
|
}
|
|
3801
3985
|
|
|
3802
3986
|
// src/mcp/tools/roadmap.ts
|
|
3803
|
-
|
|
3804
|
-
import * as
|
|
3805
|
-
import * as
|
|
3987
|
+
init_dist2();
|
|
3988
|
+
import * as fs15 from "fs";
|
|
3989
|
+
import * as path18 from "path";
|
|
3806
3990
|
|
|
3807
3991
|
// src/mcp/tools/roadmap-file-less.ts
|
|
3808
|
-
|
|
3992
|
+
init_dist2();
|
|
3809
3993
|
var ok = (text) => ({ content: [{ type: "text", text }] });
|
|
3810
3994
|
var err = (text) => ({ content: [{ type: "text", text }], isError: true });
|
|
3811
3995
|
async function handleManageRoadmapFileLess(input, client) {
|
|
@@ -4003,21 +4187,21 @@ var manageRoadmapDefinition = {
|
|
|
4003
4187
|
}
|
|
4004
4188
|
};
|
|
4005
4189
|
function roadmapPath(projectRoot) {
|
|
4006
|
-
return
|
|
4190
|
+
return path18.join(projectRoot, "docs", "roadmap.md");
|
|
4007
4191
|
}
|
|
4008
4192
|
function readRoadmapFile(projectRoot) {
|
|
4009
4193
|
const filePath = roadmapPath(projectRoot);
|
|
4010
4194
|
try {
|
|
4011
|
-
return
|
|
4195
|
+
return fs15.readFileSync(filePath, "utf-8");
|
|
4012
4196
|
} catch {
|
|
4013
4197
|
return null;
|
|
4014
4198
|
}
|
|
4015
4199
|
}
|
|
4016
4200
|
function writeRoadmapFile(projectRoot, content) {
|
|
4017
4201
|
const filePath = roadmapPath(projectRoot);
|
|
4018
|
-
const dir =
|
|
4019
|
-
|
|
4020
|
-
|
|
4202
|
+
const dir = path18.dirname(filePath);
|
|
4203
|
+
fs15.mkdirSync(dir, { recursive: true });
|
|
4204
|
+
fs15.writeFileSync(filePath, content, "utf-8");
|
|
4021
4205
|
}
|
|
4022
4206
|
function roadmapNotFoundError() {
|
|
4023
4207
|
return {
|
|
@@ -4283,8 +4467,8 @@ async function handleManageRoadmap(input) {
|
|
|
4283
4467
|
return handleManageRoadmapFileLess(input, clientResult.value);
|
|
4284
4468
|
}
|
|
4285
4469
|
try {
|
|
4286
|
-
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges, assignFeature } = await import("./dist-
|
|
4287
|
-
const { Ok: Ok2 } = await import("./dist-
|
|
4470
|
+
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges, assignFeature } = await import("./dist-OHDQBTSO.js");
|
|
4471
|
+
const { Ok: Ok2 } = await import("./dist-E3SAAHCM.js");
|
|
4288
4472
|
const projectPath = projectPathPre;
|
|
4289
4473
|
const deps = {
|
|
4290
4474
|
parseRoadmap,
|
|
@@ -4722,7 +4906,7 @@ async function handleTransition(validInput, projectPath, id) {
|
|
|
4722
4906
|
const transition = transitionResult.data;
|
|
4723
4907
|
const prompt = renderTransition(transition);
|
|
4724
4908
|
try {
|
|
4725
|
-
const { saveHandoff } = await import("./dist-
|
|
4909
|
+
const { saveHandoff } = await import("./dist-OHDQBTSO.js");
|
|
4726
4910
|
await saveHandoff(
|
|
4727
4911
|
projectPath,
|
|
4728
4912
|
{
|
|
@@ -4803,7 +4987,7 @@ async function handleEmitInteraction(input) {
|
|
|
4803
4987
|
}
|
|
4804
4988
|
async function recordInteraction(projectPath, id, type, decision, stream) {
|
|
4805
4989
|
try {
|
|
4806
|
-
const { loadState, saveState } = await import("./dist-
|
|
4990
|
+
const { loadState, saveState } = await import("./dist-OHDQBTSO.js");
|
|
4807
4991
|
const stateResult = await loadState(projectPath, stream);
|
|
4808
4992
|
if (stateResult.ok) {
|
|
4809
4993
|
const state = stateResult.value;
|
|
@@ -4819,7 +5003,7 @@ async function recordInteraction(projectPath, id, type, decision, stream) {
|
|
|
4819
5003
|
}
|
|
4820
5004
|
|
|
4821
5005
|
// src/mcp/tools/gather-context.ts
|
|
4822
|
-
|
|
5006
|
+
init_dist2();
|
|
4823
5007
|
function flattenSessionSections(sections) {
|
|
4824
5008
|
if (!sections) return [];
|
|
4825
5009
|
return Object.entries(sections).flatMap(
|
|
@@ -4964,10 +5148,10 @@ async function handleGatherContext(input) {
|
|
|
4964
5148
|
input.include ?? ["state", "learnings", "handoff", "graph", "validation", "businessKnowledge"]
|
|
4965
5149
|
);
|
|
4966
5150
|
const errors = [];
|
|
4967
|
-
const statePromise = includeSet.has("state") ? import("./dist-
|
|
5151
|
+
const statePromise = includeSet.has("state") ? import("./dist-OHDQBTSO.js").then(
|
|
4968
5152
|
(core) => core.loadState(projectPath, void 0, input.session)
|
|
4969
5153
|
) : Promise.resolve(null);
|
|
4970
|
-
const learningsPromise = includeSet.has("learnings") ? import("./dist-
|
|
5154
|
+
const learningsPromise = includeSet.has("learnings") ? import("./dist-OHDQBTSO.js").then(
|
|
4971
5155
|
(core) => core.loadBudgetedLearnings(projectPath, {
|
|
4972
5156
|
intent: input.intent,
|
|
4973
5157
|
tokenBudget: input.learningsBudget ?? 1e3,
|
|
@@ -4976,7 +5160,7 @@ async function handleGatherContext(input) {
|
|
|
4976
5160
|
...input.depth !== void 0 && { depth: input.depth }
|
|
4977
5161
|
})
|
|
4978
5162
|
) : Promise.resolve(null);
|
|
4979
|
-
const handoffPromise = includeSet.has("handoff") ? import("./dist-
|
|
5163
|
+
const handoffPromise = includeSet.has("handoff") ? import("./dist-OHDQBTSO.js").then(
|
|
4980
5164
|
(core) => core.loadHandoff(projectPath, void 0, input.session)
|
|
4981
5165
|
) : Promise.resolve(null);
|
|
4982
5166
|
const graphPromise = includeSet.has("graph") ? (async () => {
|
|
@@ -5020,11 +5204,11 @@ async function handleGatherContext(input) {
|
|
|
5020
5204
|
context: contextBlocks
|
|
5021
5205
|
};
|
|
5022
5206
|
})() : Promise.resolve(null);
|
|
5023
|
-
const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-
|
|
5207
|
+
const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-OHDQBTSO.js").then(
|
|
5024
5208
|
(core) => core.readSessionSections(projectPath, input.session)
|
|
5025
5209
|
) : Promise.resolve(null);
|
|
5026
5210
|
const shouldIncludeEvents = input.includeEvents !== void 0 ? input.includeEvents : includeSet.has("events") || !!input.session && !input.include;
|
|
5027
|
-
const eventsPromise = shouldIncludeEvents ? import("./dist-
|
|
5211
|
+
const eventsPromise = shouldIncludeEvents ? import("./dist-OHDQBTSO.js").then(async (core) => {
|
|
5028
5212
|
const result = await core.loadEvents(projectPath, {
|
|
5029
5213
|
session: input.session
|
|
5030
5214
|
});
|
|
@@ -5032,7 +5216,7 @@ async function handleGatherContext(input) {
|
|
|
5032
5216
|
return core.formatEventTimeline(result.value);
|
|
5033
5217
|
}) : Promise.resolve(null);
|
|
5034
5218
|
const validationPromise = includeSet.has("validation") ? (async () => {
|
|
5035
|
-
const { handleValidateProject: handleValidateProject2 } = await import("./validate-
|
|
5219
|
+
const { handleValidateProject: handleValidateProject2 } = await import("./validate-QRVCD4GP.js");
|
|
5036
5220
|
const result = await handleValidateProject2({ path: projectPath });
|
|
5037
5221
|
const first = result.content[0];
|
|
5038
5222
|
return first ? JSON.parse(first.text) : null;
|
|
@@ -5135,7 +5319,7 @@ async function handleGatherContext(input) {
|
|
|
5135
5319
|
};
|
|
5136
5320
|
if (input.session) {
|
|
5137
5321
|
try {
|
|
5138
|
-
const core = await import("./dist-
|
|
5322
|
+
const core = await import("./dist-OHDQBTSO.js");
|
|
5139
5323
|
core.updateSessionIndex(
|
|
5140
5324
|
projectPath,
|
|
5141
5325
|
input.session,
|
|
@@ -5175,7 +5359,7 @@ async function handleGatherContext(input) {
|
|
|
5175
5359
|
}
|
|
5176
5360
|
|
|
5177
5361
|
// src/mcp/tools/review-changes.ts
|
|
5178
|
-
|
|
5362
|
+
init_dist2();
|
|
5179
5363
|
var SIZE_GATE_LINES = 1e4;
|
|
5180
5364
|
var reviewChangesDefinition = {
|
|
5181
5365
|
name: "review_changes",
|
|
@@ -5287,7 +5471,7 @@ async function handleReviewChanges(input) {
|
|
|
5287
5471
|
}
|
|
5288
5472
|
}
|
|
5289
5473
|
async function runQuickReview(projectPath, diff, diffLines, downgraded, offset, limit) {
|
|
5290
|
-
const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-
|
|
5474
|
+
const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-WH6XPQJS.js");
|
|
5291
5475
|
const result = await handleAnalyzeDiff2({ diff, path: projectPath });
|
|
5292
5476
|
const firstContent = result.content[0];
|
|
5293
5477
|
if (!firstContent) throw new Error("Empty analyze_diff response");
|
|
@@ -5322,7 +5506,7 @@ function extractFileCount(diffParsed) {
|
|
|
5322
5506
|
return files?.length ?? 0;
|
|
5323
5507
|
}
|
|
5324
5508
|
async function runStandardReview(projectPath, diff, diffLines, downgraded, offset, limit) {
|
|
5325
|
-
const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-
|
|
5509
|
+
const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-WH6XPQJS.js");
|
|
5326
5510
|
const [diffResult, reviewResult] = await Promise.all([
|
|
5327
5511
|
handleAnalyzeDiff2({ diff, path: projectPath }),
|
|
5328
5512
|
handleCreateSelfReview2({ path: projectPath, diff })
|
|
@@ -5357,7 +5541,7 @@ async function runStandardReview(projectPath, diff, diffLines, downgraded, offse
|
|
|
5357
5541
|
};
|
|
5358
5542
|
}
|
|
5359
5543
|
async function runDeepReview(projectPath, diff, diffLines, _downgraded, offset, limit) {
|
|
5360
|
-
const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-
|
|
5544
|
+
const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-OTDDVPNY.js");
|
|
5361
5545
|
const result = await handleRunCodeReview2({
|
|
5362
5546
|
path: projectPath,
|
|
5363
5547
|
diff,
|
|
@@ -5651,7 +5835,7 @@ async function handleDetectStaleConstraints(input) {
|
|
|
5651
5835
|
]
|
|
5652
5836
|
};
|
|
5653
5837
|
}
|
|
5654
|
-
const { detectStaleConstraints } = await import("./dist-
|
|
5838
|
+
const { detectStaleConstraints } = await import("./dist-OHDQBTSO.js");
|
|
5655
5839
|
const result = detectStaleConstraints(
|
|
5656
5840
|
store,
|
|
5657
5841
|
windowDays,
|
|
@@ -5679,12 +5863,12 @@ async function handleDetectStaleConstraints(input) {
|
|
|
5679
5863
|
}
|
|
5680
5864
|
|
|
5681
5865
|
// src/mcp/tools/search-skills.ts
|
|
5682
|
-
|
|
5866
|
+
init_dist2();
|
|
5683
5867
|
|
|
5684
5868
|
// src/skill/health-snapshot.ts
|
|
5685
5869
|
import { execSync } from "child_process";
|
|
5686
|
-
import * as
|
|
5687
|
-
import * as
|
|
5870
|
+
import * as fs16 from "fs";
|
|
5871
|
+
import * as path19 from "path";
|
|
5688
5872
|
var CACHE_FILE = "health-snapshot.json";
|
|
5689
5873
|
var STALENESS_MS = 36e5;
|
|
5690
5874
|
function isSnapshotFresh(snapshot, projectPath) {
|
|
@@ -5701,19 +5885,19 @@ function isSnapshotFresh(snapshot, projectPath) {
|
|
|
5701
5885
|
return age < STALENESS_MS;
|
|
5702
5886
|
}
|
|
5703
5887
|
function loadCachedSnapshot(projectPath) {
|
|
5704
|
-
const filePath =
|
|
5888
|
+
const filePath = path19.join(projectPath, ".harness", CACHE_FILE);
|
|
5705
5889
|
try {
|
|
5706
|
-
const raw =
|
|
5890
|
+
const raw = fs16.readFileSync(filePath, "utf-8");
|
|
5707
5891
|
return JSON.parse(raw);
|
|
5708
5892
|
} catch {
|
|
5709
5893
|
return null;
|
|
5710
5894
|
}
|
|
5711
5895
|
}
|
|
5712
5896
|
function saveCachedSnapshot(snapshot, projectPath) {
|
|
5713
|
-
const dir =
|
|
5714
|
-
|
|
5715
|
-
const filePath =
|
|
5716
|
-
|
|
5897
|
+
const dir = path19.join(projectPath, ".harness");
|
|
5898
|
+
fs16.mkdirSync(dir, { recursive: true });
|
|
5899
|
+
const filePath = path19.join(dir, CACHE_FILE);
|
|
5900
|
+
fs16.writeFileSync(filePath, JSON.stringify(snapshot, null, 2));
|
|
5717
5901
|
}
|
|
5718
5902
|
var SIGNAL_RULES = [
|
|
5719
5903
|
["circular-deps", (c) => c.deps.circularDeps > 0],
|
|
@@ -5771,10 +5955,10 @@ function countCriticalFindings(securityData) {
|
|
|
5771
5955
|
return findings.filter((f) => f.severity === "error").length;
|
|
5772
5956
|
}
|
|
5773
5957
|
async function runHealthChecks(projectPath) {
|
|
5774
|
-
const { handleAssessProject: handleAssessProject2 } = await import("./assess-project-
|
|
5775
|
-
const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-
|
|
5776
|
-
const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-
|
|
5777
|
-
const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-
|
|
5958
|
+
const { handleAssessProject: handleAssessProject2 } = await import("./assess-project-M626SSPN.js");
|
|
5959
|
+
const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-CXAVNB5X.js");
|
|
5960
|
+
const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-DQTAPSSE.js");
|
|
5961
|
+
const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-27HW7CYT.js");
|
|
5778
5962
|
const [assessResult, depsResult, entropyResult, securityResult] = await Promise.all([
|
|
5779
5963
|
handleAssessProject2({
|
|
5780
5964
|
path: projectPath,
|
|
@@ -5963,7 +6147,7 @@ async function handleSearchSkills(input) {
|
|
|
5963
6147
|
}
|
|
5964
6148
|
|
|
5965
6149
|
// src/skill/dispatch-engine.ts
|
|
5966
|
-
|
|
6150
|
+
init_dist2();
|
|
5967
6151
|
import { execSync as execSync2 } from "child_process";
|
|
5968
6152
|
|
|
5969
6153
|
// src/skill/recommendation-rules.ts
|
|
@@ -6558,7 +6742,7 @@ async function handleDispatchSkills(input) {
|
|
|
6558
6742
|
}
|
|
6559
6743
|
|
|
6560
6744
|
// src/mcp/tools/decay-trends.ts
|
|
6561
|
-
|
|
6745
|
+
init_dist2();
|
|
6562
6746
|
var getDecayTrendsDefinition = {
|
|
6563
6747
|
name: "get_decay_trends",
|
|
6564
6748
|
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?"',
|
|
@@ -6615,7 +6799,7 @@ async function handleGetDecayTrends(input) {
|
|
|
6615
6799
|
};
|
|
6616
6800
|
}
|
|
6617
6801
|
try {
|
|
6618
|
-
const core = await import("./dist-
|
|
6802
|
+
const core = await import("./dist-OHDQBTSO.js");
|
|
6619
6803
|
const { TimelineManager } = core;
|
|
6620
6804
|
const manager = new TimelineManager(projectPath);
|
|
6621
6805
|
const timeline = manager.load();
|
|
@@ -6750,7 +6934,7 @@ async function handleCodeOutline(input) {
|
|
|
6750
6934
|
};
|
|
6751
6935
|
}
|
|
6752
6936
|
try {
|
|
6753
|
-
const { getOutline, formatOutline, EXTENSION_MAP } = await import("./dist-
|
|
6937
|
+
const { getOutline, formatOutline, EXTENSION_MAP } = await import("./dist-OHDQBTSO.js");
|
|
6754
6938
|
const { stat } = await import("fs/promises");
|
|
6755
6939
|
const stats = await stat(targetPath).catch(() => null);
|
|
6756
6940
|
if (stats?.isFile()) {
|
|
@@ -6769,7 +6953,7 @@ async function handleCodeOutline(input) {
|
|
|
6769
6953
|
})
|
|
6770
6954
|
);
|
|
6771
6955
|
fileStats.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
6772
|
-
const { paginate: paginate2 } = await import("./dist-
|
|
6956
|
+
const { paginate: paginate2 } = await import("./dist-OHDQBTSO.js");
|
|
6773
6957
|
const paged = paginate2(fileStats, input.offset ?? 0, input.limit ?? 30);
|
|
6774
6958
|
const results = [];
|
|
6775
6959
|
for (const entry of paged.items) {
|
|
@@ -6842,7 +7026,7 @@ async function handleCodeSearch(input) {
|
|
|
6842
7026
|
};
|
|
6843
7027
|
}
|
|
6844
7028
|
try {
|
|
6845
|
-
const { searchSymbols } = await import("./dist-
|
|
7029
|
+
const { searchSymbols } = await import("./dist-OHDQBTSO.js");
|
|
6846
7030
|
const result = await searchSymbols(input.query, directory, input.glob);
|
|
6847
7031
|
const lines = [`Search: "${result.query}" \u2014 ${result.matches.length} matches`];
|
|
6848
7032
|
for (const match of result.matches) {
|
|
@@ -6911,7 +7095,7 @@ async function handleCodeUnfold(input) {
|
|
|
6911
7095
|
}
|
|
6912
7096
|
try {
|
|
6913
7097
|
if (input.symbol) {
|
|
6914
|
-
const { unfoldSymbol } = await import("./dist-
|
|
7098
|
+
const { unfoldSymbol } = await import("./dist-OHDQBTSO.js");
|
|
6915
7099
|
const result = await unfoldSymbol(filePath, input.symbol);
|
|
6916
7100
|
const header = result.warning ? `${result.file}:${result.startLine}-${result.endLine} ${result.warning}
|
|
6917
7101
|
` : `${result.file}:${result.startLine}-${result.endLine}
|
|
@@ -6919,7 +7103,7 @@ async function handleCodeUnfold(input) {
|
|
|
6919
7103
|
return { content: [{ type: "text", text: header + result.content }] };
|
|
6920
7104
|
}
|
|
6921
7105
|
if (input.startLine != null && input.endLine != null) {
|
|
6922
|
-
const { unfoldRange } = await import("./dist-
|
|
7106
|
+
const { unfoldRange } = await import("./dist-OHDQBTSO.js");
|
|
6923
7107
|
const result = await unfoldRange(filePath, input.startLine, input.endLine);
|
|
6924
7108
|
const header = `${result.file}:${result.startLine}-${result.endLine}
|
|
6925
7109
|
`;
|
|
@@ -7104,7 +7288,7 @@ async function handlePredictFailures(input) {
|
|
|
7104
7288
|
};
|
|
7105
7289
|
}
|
|
7106
7290
|
try {
|
|
7107
|
-
const core = await import("./dist-
|
|
7291
|
+
const core = await import("./dist-OHDQBTSO.js");
|
|
7108
7292
|
const { TimelineManager, PredictionEngine, SpecImpactEstimator } = core;
|
|
7109
7293
|
const manager = new TimelineManager(projectPath);
|
|
7110
7294
|
const includeRoadmap = input.includeRoadmap !== false;
|
|
@@ -7207,12 +7391,12 @@ async function handleRecommendSkills(input) {
|
|
|
7207
7391
|
}
|
|
7208
7392
|
|
|
7209
7393
|
// src/mcp/tools/advise-skills.ts
|
|
7210
|
-
import
|
|
7394
|
+
import path21 from "path";
|
|
7211
7395
|
|
|
7212
7396
|
// src/commands/advise-skills.ts
|
|
7213
7397
|
import { Command as Command2 } from "commander";
|
|
7214
|
-
import
|
|
7215
|
-
import
|
|
7398
|
+
import fs17 from "fs";
|
|
7399
|
+
import path20 from "path";
|
|
7216
7400
|
import chalk from "chalk";
|
|
7217
7401
|
|
|
7218
7402
|
// src/skill/content-matcher-types.ts
|
|
@@ -7731,10 +7915,10 @@ function renderTable(matches) {
|
|
|
7731
7915
|
|
|
7732
7916
|
// src/commands/advise-skills.ts
|
|
7733
7917
|
function readPackageDeps(cwd) {
|
|
7734
|
-
const pkgPath =
|
|
7735
|
-
if (!
|
|
7918
|
+
const pkgPath = path20.join(cwd, "package.json");
|
|
7919
|
+
if (!fs17.existsSync(pkgPath)) return { deps: {}, devDeps: {} };
|
|
7736
7920
|
try {
|
|
7737
|
-
const pkg = JSON.parse(
|
|
7921
|
+
const pkg = JSON.parse(fs17.readFileSync(pkgPath, "utf-8"));
|
|
7738
7922
|
const deps = typeof pkg.dependencies === "object" && pkg.dependencies !== null ? pkg.dependencies : {};
|
|
7739
7923
|
const devDeps = typeof pkg.devDependencies === "object" && pkg.devDependencies !== null ? pkg.devDependencies : {};
|
|
7740
7924
|
return { deps, devDeps };
|
|
@@ -7743,10 +7927,10 @@ function readPackageDeps(cwd) {
|
|
|
7743
7927
|
}
|
|
7744
7928
|
}
|
|
7745
7929
|
function readSpecText(specPath) {
|
|
7746
|
-
if (!
|
|
7930
|
+
if (!fs17.existsSync(specPath)) {
|
|
7747
7931
|
throw new Error(`Spec not found: ${specPath}`);
|
|
7748
7932
|
}
|
|
7749
|
-
return
|
|
7933
|
+
return fs17.readFileSync(specPath, "utf-8");
|
|
7750
7934
|
}
|
|
7751
7935
|
function filterMatchesByTier(result, top, thorough) {
|
|
7752
7936
|
const applySkills = result.matches.filter((m) => m.tier === "apply").slice(0, top);
|
|
@@ -7756,11 +7940,11 @@ function filterMatchesByTier(result, top, thorough) {
|
|
|
7756
7940
|
}
|
|
7757
7941
|
function extractFeatureName(specText, specPath) {
|
|
7758
7942
|
const titleMatch = specText.match(/^#\s+(.+)/m);
|
|
7759
|
-
return titleMatch?.[1] ??
|
|
7943
|
+
return titleMatch?.[1] ?? path20.basename(path20.dirname(specPath));
|
|
7760
7944
|
}
|
|
7761
7945
|
async function runAdviseSkills(options) {
|
|
7762
7946
|
const cwd = options.cwd ?? process.cwd();
|
|
7763
|
-
const specPath =
|
|
7947
|
+
const specPath = path20.resolve(cwd, options.specPath);
|
|
7764
7948
|
const specText = readSpecText(specPath);
|
|
7765
7949
|
const { deps, devDeps } = readPackageDeps(cwd);
|
|
7766
7950
|
const signals = extractSignals(specText, deps, devDeps);
|
|
@@ -7771,9 +7955,9 @@ async function runAdviseSkills(options) {
|
|
|
7771
7955
|
const result = matchContent(index, signals);
|
|
7772
7956
|
const filteredResult = filterMatchesByTier(result, options.top ?? 5, !!options.thorough);
|
|
7773
7957
|
const featureName = extractFeatureName(specText, specPath);
|
|
7774
|
-
const skillsMdPath =
|
|
7958
|
+
const skillsMdPath = path20.join(path20.dirname(specPath), "SKILLS.md");
|
|
7775
7959
|
const md = generateSkillsMd(featureName, filteredResult, totalSkills);
|
|
7776
|
-
|
|
7960
|
+
fs17.writeFileSync(skillsMdPath, md, "utf-8");
|
|
7777
7961
|
return { result: filteredResult, skillsMdPath, featureName, totalSkills };
|
|
7778
7962
|
}
|
|
7779
7963
|
function formatOutput(featureName, result, skillsMdPath, totalSkills) {
|
|
@@ -7867,7 +8051,7 @@ async function handleAdviseSkills(input) {
|
|
|
7867
8051
|
});
|
|
7868
8052
|
const response = {
|
|
7869
8053
|
featureName,
|
|
7870
|
-
skillsPath:
|
|
8054
|
+
skillsPath: path21.relative(projectRoot, skillsMdPath).replaceAll("\\", "/"),
|
|
7871
8055
|
totalScanned: totalSkills,
|
|
7872
8056
|
scanDuration: result.scanDuration,
|
|
7873
8057
|
apply: result.matches.filter((m) => m.tier === "apply").map((m) => ({
|
|
@@ -7900,7 +8084,7 @@ async function handleAdviseSkills(input) {
|
|
|
7900
8084
|
}
|
|
7901
8085
|
|
|
7902
8086
|
// src/mcp/tools/compact.ts
|
|
7903
|
-
|
|
8087
|
+
init_dist2();
|
|
7904
8088
|
var COMPACT_TOOL_DEFAULT_BUDGET = 2e3;
|
|
7905
8089
|
var compactToolDefinition = {
|
|
7906
8090
|
name: "compact",
|
|
@@ -8213,7 +8397,7 @@ async function handleDetectConstraintEmergence(input) {
|
|
|
8213
8397
|
}
|
|
8214
8398
|
const nodePath = await import("path");
|
|
8215
8399
|
const historyPath = nodePath.resolve(projectPath, ".harness/arch/violation-history.json");
|
|
8216
|
-
const { ViolationHistoryManager, detectEmergentConstraints } = await import("./dist-
|
|
8400
|
+
const { ViolationHistoryManager, detectEmergentConstraints } = await import("./dist-OHDQBTSO.js");
|
|
8217
8401
|
const manager = new ViolationHistoryManager(historyPath);
|
|
8218
8402
|
const history = manager.load();
|
|
8219
8403
|
const options = { windowWeeks, minOccurrences };
|
|
@@ -8301,7 +8485,7 @@ async function handleRunCIChecks(input) {
|
|
|
8301
8485
|
};
|
|
8302
8486
|
}
|
|
8303
8487
|
try {
|
|
8304
|
-
const { runCIChecks } = await import("./dist-
|
|
8488
|
+
const { runCIChecks } = await import("./dist-OHDQBTSO.js");
|
|
8305
8489
|
const skip = input.checks ? VALID_CHECKS.filter((c) => !input.checks.includes(c)) : [];
|
|
8306
8490
|
const result = await runCIChecks({
|
|
8307
8491
|
projectRoot: projectPath,
|
|
@@ -8363,7 +8547,7 @@ async function handleGenerateBlueprint(input) {
|
|
|
8363
8547
|
};
|
|
8364
8548
|
}
|
|
8365
8549
|
try {
|
|
8366
|
-
const { ProjectScanner } = await import("./dist-
|
|
8550
|
+
const { ProjectScanner } = await import("./dist-OHDQBTSO.js");
|
|
8367
8551
|
const scanner = new ProjectScanner(projectPath);
|
|
8368
8552
|
const data = await scanner.scan();
|
|
8369
8553
|
return {
|
|
@@ -8485,6 +8669,125 @@ async function handleSubscribeWebhook(input) {
|
|
|
8485
8669
|
return { content: [{ type: "text", text }] };
|
|
8486
8670
|
}
|
|
8487
8671
|
|
|
8672
|
+
// src/mcp/tools/skill-proposal.ts
|
|
8673
|
+
var emitSkillProposalDefinition = {
|
|
8674
|
+
name: "emit_skill_proposal",
|
|
8675
|
+
description: "Emit a skill proposal (new-skill or refinement) into the review queue. Writes `.harness/proposals/<id>.json` and returns the queue URL. The proposal does not gate the agent \u2014 soundness-review runs at approval time.",
|
|
8676
|
+
inputSchema: {
|
|
8677
|
+
type: "object",
|
|
8678
|
+
properties: {
|
|
8679
|
+
path: { type: "string", description: "Path to project root" },
|
|
8680
|
+
kind: {
|
|
8681
|
+
type: "string",
|
|
8682
|
+
enum: ["new-skill", "refinement"],
|
|
8683
|
+
description: "new-skill = full content; refinement = unified-diff against targetSkill"
|
|
8684
|
+
},
|
|
8685
|
+
targetSkill: {
|
|
8686
|
+
type: "string",
|
|
8687
|
+
description: "Existing skill name (required when kind is refinement)"
|
|
8688
|
+
},
|
|
8689
|
+
proposedBy: {
|
|
8690
|
+
type: "string",
|
|
8691
|
+
description: 'Agent identifier, e.g. "claude-code:harness-execution"'
|
|
8692
|
+
},
|
|
8693
|
+
justification: {
|
|
8694
|
+
type: "string",
|
|
8695
|
+
description: "Why this skill / refinement is worth promoting (20\u20132000 chars)"
|
|
8696
|
+
},
|
|
8697
|
+
sessionId: { type: "string", description: "Originating session id (optional)" },
|
|
8698
|
+
taskId: { type: "string", description: "Originating maintenance task id (optional)" },
|
|
8699
|
+
content: {
|
|
8700
|
+
type: "object",
|
|
8701
|
+
description: "Proposal content. new-skill \u21D2 skillYaml+skillMd; refinement \u21D2 diff",
|
|
8702
|
+
properties: {
|
|
8703
|
+
name: {
|
|
8704
|
+
type: "string",
|
|
8705
|
+
description: "kebab-case skill name (matches /^[a-z][a-z0-9-]*$/, \u226464 chars)"
|
|
8706
|
+
},
|
|
8707
|
+
description: { type: "string", description: "20\u2013280 chars" },
|
|
8708
|
+
skillYaml: { type: "string", description: "Full skill.yaml (new-skill only)" },
|
|
8709
|
+
skillMd: { type: "string", description: "Full SKILL.md (new-skill only)" },
|
|
8710
|
+
diff: { type: "string", description: "Unified diff (refinement only)" }
|
|
8711
|
+
},
|
|
8712
|
+
required: ["name", "description"]
|
|
8713
|
+
}
|
|
8714
|
+
},
|
|
8715
|
+
required: ["path", "kind", "proposedBy", "justification", "content"]
|
|
8716
|
+
}
|
|
8717
|
+
};
|
|
8718
|
+
async function handleEmitSkillProposal(input) {
|
|
8719
|
+
let projectPath;
|
|
8720
|
+
try {
|
|
8721
|
+
projectPath = sanitizePath(input.path);
|
|
8722
|
+
} catch (err2) {
|
|
8723
|
+
return mcpError(err2 instanceof Error ? err2.message : "Invalid path");
|
|
8724
|
+
}
|
|
8725
|
+
if (input.kind === "new-skill") {
|
|
8726
|
+
if (!input.content.skillYaml || !input.content.skillMd) {
|
|
8727
|
+
return mcpError("new-skill proposals require both skillYaml and skillMd");
|
|
8728
|
+
}
|
|
8729
|
+
if (input.targetSkill) {
|
|
8730
|
+
return mcpError("targetSkill is forbidden on new-skill proposals");
|
|
8731
|
+
}
|
|
8732
|
+
if (input.content.diff) {
|
|
8733
|
+
return mcpError("diff is forbidden on new-skill proposals (use skillYaml/skillMd)");
|
|
8734
|
+
}
|
|
8735
|
+
} else if (input.kind === "refinement") {
|
|
8736
|
+
if (!input.targetSkill) {
|
|
8737
|
+
return mcpError("refinement proposals require targetSkill");
|
|
8738
|
+
}
|
|
8739
|
+
if (!input.content.diff) {
|
|
8740
|
+
return mcpError("refinement proposals require a unified diff");
|
|
8741
|
+
}
|
|
8742
|
+
if (input.content.skillYaml || input.content.skillMd) {
|
|
8743
|
+
return mcpError("skillYaml/skillMd are forbidden on refinement proposals (encode in diff)");
|
|
8744
|
+
}
|
|
8745
|
+
}
|
|
8746
|
+
let createProposal;
|
|
8747
|
+
let ProposalConflictError;
|
|
8748
|
+
try {
|
|
8749
|
+
const core = await import("./dist-OHDQBTSO.js");
|
|
8750
|
+
createProposal = core.createProposal;
|
|
8751
|
+
ProposalConflictError = core.ProposalConflictError;
|
|
8752
|
+
} catch (err2) {
|
|
8753
|
+
return mcpError(
|
|
8754
|
+
`Failed to load proposal store: ${err2 instanceof Error ? err2.message : "unknown error"}`
|
|
8755
|
+
);
|
|
8756
|
+
}
|
|
8757
|
+
try {
|
|
8758
|
+
const proposal = await createProposal(projectPath, {
|
|
8759
|
+
kind: input.kind,
|
|
8760
|
+
targetSkill: input.targetSkill,
|
|
8761
|
+
proposedBy: input.proposedBy,
|
|
8762
|
+
justification: input.justification,
|
|
8763
|
+
sessionId: input.sessionId,
|
|
8764
|
+
taskId: input.taskId,
|
|
8765
|
+
content: input.content
|
|
8766
|
+
});
|
|
8767
|
+
const result = {
|
|
8768
|
+
id: proposal.id,
|
|
8769
|
+
path: `.harness/proposals/${proposal.id}.json`,
|
|
8770
|
+
queueUrl: "/s/proposals",
|
|
8771
|
+
status: proposal.status
|
|
8772
|
+
};
|
|
8773
|
+
return {
|
|
8774
|
+
content: [
|
|
8775
|
+
{
|
|
8776
|
+
type: "text",
|
|
8777
|
+
text: JSON.stringify(result, null, 2)
|
|
8778
|
+
}
|
|
8779
|
+
]
|
|
8780
|
+
};
|
|
8781
|
+
} catch (err2) {
|
|
8782
|
+
if (err2 instanceof ProposalConflictError) {
|
|
8783
|
+
return mcpError(err2.message);
|
|
8784
|
+
}
|
|
8785
|
+
return mcpError(
|
|
8786
|
+
`Failed to write proposal: ${err2 instanceof Error ? err2.message : "unknown error"}`
|
|
8787
|
+
);
|
|
8788
|
+
}
|
|
8789
|
+
}
|
|
8790
|
+
|
|
8488
8791
|
// src/mcp/server.ts
|
|
8489
8792
|
var TOOL_DEFINITIONS = [
|
|
8490
8793
|
validateToolDefinition,
|
|
@@ -8550,7 +8853,11 @@ var TOOL_DEFINITIONS = [
|
|
|
8550
8853
|
generateBlueprintDefinition,
|
|
8551
8854
|
triggerMaintenanceJobDefinition,
|
|
8552
8855
|
listGatewayTokensDefinition,
|
|
8553
|
-
subscribeWebhookDefinition
|
|
8856
|
+
subscribeWebhookDefinition,
|
|
8857
|
+
searchSessionsDefinition,
|
|
8858
|
+
summarizeSessionDefinition,
|
|
8859
|
+
insightsSummaryDefinition,
|
|
8860
|
+
emitSkillProposalDefinition
|
|
8554
8861
|
].map((def) => ({ ...def, trustedOutput: true }));
|
|
8555
8862
|
var TOOL_HANDLERS = {
|
|
8556
8863
|
validate_project: handleValidateProject,
|
|
@@ -8616,7 +8923,11 @@ var TOOL_HANDLERS = {
|
|
|
8616
8923
|
generate_blueprint: handleGenerateBlueprint,
|
|
8617
8924
|
trigger_maintenance_job: handleTriggerMaintenanceJob,
|
|
8618
8925
|
list_gateway_tokens: handleListGatewayTokens,
|
|
8619
|
-
subscribe_webhook: handleSubscribeWebhook
|
|
8926
|
+
subscribe_webhook: handleSubscribeWebhook,
|
|
8927
|
+
search_sessions: handleSearchSessions,
|
|
8928
|
+
summarize_session: handleSummarizeSession,
|
|
8929
|
+
insights_summary: handleInsightsSummary,
|
|
8930
|
+
emit_skill_proposal: handleEmitSkillProposal
|
|
8620
8931
|
};
|
|
8621
8932
|
var RESOURCE_DEFINITIONS = [
|
|
8622
8933
|
{
|
|
@@ -8718,7 +9029,7 @@ async function appendUpdateNotification(result, resolvedRoot) {
|
|
|
8718
9029
|
shouldRunCheck,
|
|
8719
9030
|
readCheckState,
|
|
8720
9031
|
spawnBackgroundCheck
|
|
8721
|
-
} = await import("./dist-
|
|
9032
|
+
} = await import("./dist-OHDQBTSO.js");
|
|
8722
9033
|
const { CLI_VERSION } = await import("./version-CUI434OP.js");
|
|
8723
9034
|
const configInterval = readConfigInterval(resolvedRoot);
|
|
8724
9035
|
const DEFAULT_INTERVAL = 864e5;
|