@harness-engineering/cli 2.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/skills/claude-code/harness-compound/SKILL.md +153 -0
- package/dist/agents/skills/claude-code/harness-compound/skill.yaml +60 -0
- package/dist/agents/skills/claude-code/harness-knowledge-pipeline/SKILL.md +12 -1
- package/dist/agents/skills/claude-code/harness-observability/SKILL.md +2 -0
- package/dist/agents/skills/claude-code/harness-pulse/SKILL.md +138 -0
- package/dist/agents/skills/claude-code/harness-pulse/references/interview.md +77 -0
- package/dist/agents/skills/claude-code/harness-pulse/skill.yaml +61 -0
- package/dist/agents/skills/claude-code/harness-roadmap-pilot/SKILL.md +25 -1
- package/dist/agents/skills/codex/harness-compound/SKILL.md +153 -0
- package/dist/agents/skills/codex/harness-compound/skill.yaml +60 -0
- package/dist/agents/skills/codex/harness-knowledge-pipeline/SKILL.md +12 -1
- package/dist/agents/skills/codex/harness-observability/SKILL.md +2 -0
- package/dist/agents/skills/codex/harness-pulse/SKILL.md +138 -0
- package/dist/agents/skills/codex/harness-pulse/references/interview.md +77 -0
- package/dist/agents/skills/codex/harness-pulse/skill.yaml +61 -0
- package/dist/agents/skills/codex/harness-roadmap-pilot/SKILL.md +25 -1
- package/dist/agents/skills/cursor/harness-compound/SKILL.md +153 -0
- package/dist/agents/skills/cursor/harness-compound/skill.yaml +60 -0
- package/dist/agents/skills/cursor/harness-knowledge-pipeline/SKILL.md +12 -1
- package/dist/agents/skills/cursor/harness-observability/SKILL.md +2 -0
- package/dist/agents/skills/cursor/harness-pulse/SKILL.md +138 -0
- package/dist/agents/skills/cursor/harness-pulse/references/interview.md +77 -0
- package/dist/agents/skills/cursor/harness-pulse/skill.yaml +61 -0
- package/dist/agents/skills/cursor/harness-roadmap-pilot/SKILL.md +25 -1
- package/dist/agents/skills/gemini-cli/harness-compound/SKILL.md +153 -0
- package/dist/agents/skills/gemini-cli/harness-compound/skill.yaml +60 -0
- package/dist/agents/skills/gemini-cli/harness-knowledge-pipeline/SKILL.md +12 -1
- package/dist/agents/skills/gemini-cli/harness-observability/SKILL.md +2 -0
- package/dist/agents/skills/gemini-cli/harness-pulse/SKILL.md +138 -0
- package/dist/agents/skills/gemini-cli/harness-pulse/references/interview.md +77 -0
- package/dist/agents/skills/gemini-cli/harness-pulse/skill.yaml +61 -0
- package/dist/agents/skills/gemini-cli/harness-roadmap-pilot/SKILL.md +25 -1
- package/dist/agents/skills/package.json +1 -0
- package/dist/agents/skills/tests/fixtures/harness-compound/bug-track-fixture/input.json +10 -0
- package/dist/agents/skills/tests/fixtures/harness-compound/duplicate-detection-fixture/docs/solutions/bug-track/integration-issues/stalled-lease-cleanup.md +28 -0
- package/dist/agents/skills/tests/fixtures/harness-compound/duplicate-detection-fixture/expected.json +4 -0
- package/dist/agents/skills/tests/fixtures/harness-compound/duplicate-detection-fixture/input.json +10 -0
- package/dist/agents/skills/tests/fixtures/harness-compound/knowledge-track-fixture/input.json +10 -0
- package/dist/agents/skills/tests/harness-compound.test.ts +86 -0
- package/dist/{agents-md-6SAMHE7H.js → agents-md-L4X4MOWT.js} +3 -3
- package/dist/{architecture-5YR52NSV.js → architecture-WJRIYQ45.js} +4 -4
- package/dist/{assess-project-5X7TYQFM.js → assess-project-PHC2HO3V.js} +1 -1
- package/dist/bin/harness-mcp.js +16 -15
- package/dist/bin/harness.js +26 -25
- package/dist/{check-phase-gate-PLV2VDOL.js → check-phase-gate-646KY67H.js} +5 -4
- package/dist/{chunk-ZYLBIDLE.js → chunk-224XKVLP.js} +1 -1
- package/dist/{chunk-ELJ2MXMO.js → chunk-2QPHCR22.js} +9 -9
- package/dist/{chunk-SITVRO7K.js → chunk-2ZURBWEV.js} +9 -9
- package/dist/{chunk-2IBXUG6J.js → chunk-36X7TRUI.js} +2 -2
- package/dist/{chunk-6L2BU4BP.js → chunk-4HKVZO7R.js} +1 -1
- package/dist/{chunk-74YADB7T.js → chunk-7XQYOXTB.js} +96 -94
- package/dist/{chunk-S2WB4LE7.js → chunk-BMM3GXV6.js} +384 -28
- package/dist/{chunk-BYS3TQOO.js → chunk-CPYL6LJR.js} +1 -1
- package/dist/{chunk-QDRBWVVY.js → chunk-E7W3YOXL.js} +2 -2
- package/dist/{chunk-MTPHNOJW.js → chunk-FNCJ3UCU.js} +507 -244
- package/dist/{chunk-RYDPFIJY.js → chunk-JPWICLXQ.js} +1 -1
- package/dist/{chunk-RFYF7TJS.js → chunk-K4WRQTEF.js} +1835 -805
- package/dist/{chunk-DXGI7DL3.js → chunk-KTWKW6KJ.js} +1 -1
- package/dist/{chunk-JNKALGRM.js → chunk-KV7A5OZT.js} +5 -5
- package/dist/{chunk-KJD4J54I.js → chunk-LO7ZLV7S.js} +6 -1
- package/dist/{chunk-XHOGGZS7.js → chunk-QTUPHTTK.js} +1 -1
- package/dist/{chunk-R2CBBZA6.js → chunk-SVC7THFK.js} +1 -1
- package/dist/{chunk-PFM3BVVU.js → chunk-TNZYQTEE.js} +1 -1
- package/dist/{chunk-HT7HYYGT.js → chunk-VJQLUS5I.js} +1 -1
- package/dist/{chunk-6GXSJGSW.js → chunk-VKDBM3RX.js} +3 -3
- package/dist/{chunk-JZST2WZS.js → chunk-W4AFGFFB.js} +3 -3
- package/dist/{chunk-YJE23GRZ.js → chunk-YG4ZBGEH.js} +39 -5
- package/dist/{chunk-5ME3WG3G.js → chunk-YLOAQZLA.js} +5 -5
- package/dist/{chunk-7JQ7HLM4.js → chunk-YLTRFZAT.js} +8 -8
- package/dist/{chunk-BFBZK6BC.js → chunk-YWD6WXXM.js} +6 -6
- package/dist/chunk-ZCZD7FHU.js +16 -0
- package/dist/{ci-workflow-7T2XKB3P.js → ci-workflow-TOS5X527.js} +3 -3
- package/dist/{dist-77VNTHWV.js → dist-6RT2AVYU.js} +78 -2
- package/dist/{dist-42AYXCAK.js → dist-D27LJR2T.js} +7 -1
- package/dist/{docs-MSIJ6SDO.js → docs-HOJMQYDZ.js} +5 -4
- package/dist/{engine-F4P5RBE4.js → engine-D6UYH6DB.js} +3 -3
- package/dist/{entropy-GSUTIORR.js → entropy-LZ4IDGZR.js} +3 -3
- package/dist/{feedback-NST6T4HI.js → feedback-WV7EQVK7.js} +1 -1
- package/dist/{generate-agent-definitions-BOUGQIPA.js → generate-agent-definitions-ZHFFS6YG.js} +4 -4
- package/dist/glob-helper-FZPPTGJN.js +62 -0
- package/dist/{graph-loader-IAUPGLRV.js → graph-loader-5MKHAJJF.js} +1 -1
- package/dist/index.d.ts +44 -6
- package/dist/index.js +26 -25
- package/dist/{loader-6QTJC7IN.js → loader-Z23JTXIZ.js} +3 -3
- package/dist/{mcp-QFBGTUX6.js → mcp-QFZDPFNP.js} +16 -15
- package/dist/{performance-B2NAAIE5.js → performance-7ATLHTQU.js} +5 -4
- package/dist/{review-pipeline-6EYMBS6B.js → review-pipeline-COBGGXHJ.js} +3 -3
- package/dist/{runtime-VFZK6BCZ.js → runtime-KCBNQUXK.js} +3 -3
- package/dist/{scan-DB6FNYGG.js → scan-BIJYHOE7.js} +2 -1
- package/dist/{security-HRNTYHPM.js → security-MAPRIFQT.js} +1 -1
- package/dist/templates/orchestrator/harness.orchestrator.md +9 -1
- package/dist/{validate-YEMAFWJE.js → validate-74XTQR7Q.js} +4 -4
- package/dist/{validate-cross-check-DGHTJFVH.js → validate-cross-check-MI5MZ7MB.js} +3 -3
- package/package.json +7 -6
- package/dist/glob-helper-VCQXK5XY.js +0 -54
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateRuntime
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TNZYQTEE.js";
|
|
4
4
|
import {
|
|
5
5
|
generateAgentsMd
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4HKVZO7R.js";
|
|
7
7
|
import {
|
|
8
8
|
generateCIWorkflow
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JPWICLXQ.js";
|
|
10
10
|
import {
|
|
11
11
|
TemplateEngine
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-224XKVLP.js";
|
|
13
13
|
import {
|
|
14
14
|
generate,
|
|
15
15
|
validate
|
|
@@ -28,21 +28,22 @@ import {
|
|
|
28
28
|
OutputMode,
|
|
29
29
|
createCheckPhaseGateCommand,
|
|
30
30
|
findFiles
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-E7W3YOXL.js";
|
|
32
32
|
import {
|
|
33
33
|
createGenerateAgentDefinitionsCommand,
|
|
34
34
|
generateAgentDefinitions
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-SVC7THFK.js";
|
|
36
36
|
import {
|
|
37
37
|
toKebabCase
|
|
38
38
|
} from "./chunk-KET4QQZB.js";
|
|
39
39
|
import {
|
|
40
40
|
listPersonas,
|
|
41
41
|
loadPersona
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-VJQLUS5I.js";
|
|
43
43
|
import {
|
|
44
|
-
createScanCommand
|
|
45
|
-
|
|
44
|
+
createScanCommand,
|
|
45
|
+
loadIngestOptions
|
|
46
|
+
} from "./chunk-YG4ZBGEH.js";
|
|
46
47
|
import {
|
|
47
48
|
appendFrameworkAgents,
|
|
48
49
|
captureHealthSnapshot,
|
|
@@ -56,17 +57,17 @@ import {
|
|
|
56
57
|
loadCachedSnapshot,
|
|
57
58
|
persistToolingConfig,
|
|
58
59
|
recommend
|
|
59
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-7XQYOXTB.js";
|
|
60
61
|
import {
|
|
61
62
|
loadGraphStore
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-KTWKW6KJ.js";
|
|
63
64
|
import {
|
|
64
65
|
loadOrRebuildIndex
|
|
65
66
|
} from "./chunk-27AJKSQY.js";
|
|
66
67
|
import {
|
|
67
68
|
findConfigFile,
|
|
68
69
|
resolveConfig
|
|
69
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-LO7ZLV7S.js";
|
|
70
71
|
import {
|
|
71
72
|
VALID_PLATFORMS
|
|
72
73
|
} from "./chunk-3ISINLYT.js";
|
|
@@ -102,14 +103,19 @@ import {
|
|
|
102
103
|
appendLearning,
|
|
103
104
|
applyFixes,
|
|
104
105
|
archiveStream,
|
|
106
|
+
assembleCandidateReport,
|
|
107
|
+
assembleReport,
|
|
105
108
|
buildSnapshot,
|
|
106
109
|
checkDocCoverage,
|
|
107
110
|
checkTaint,
|
|
108
111
|
clearTaint,
|
|
112
|
+
computeHotspots,
|
|
109
113
|
computeOverallSeverity,
|
|
110
114
|
computeScanExitCode,
|
|
115
|
+
computeWindow,
|
|
111
116
|
createFixes,
|
|
112
117
|
createStream,
|
|
118
|
+
crossReferenceUndocumentedFixes,
|
|
113
119
|
deepMergeConstraints,
|
|
114
120
|
defineLayer,
|
|
115
121
|
detectCircularDepsInFiles,
|
|
@@ -118,9 +124,13 @@ import {
|
|
|
118
124
|
diff,
|
|
119
125
|
dist_exports,
|
|
120
126
|
extractBundle,
|
|
127
|
+
extractHeadlines,
|
|
128
|
+
formatIsoWeek,
|
|
121
129
|
generateSuggestions,
|
|
122
130
|
getOrCreateInstallId,
|
|
131
|
+
gitScan,
|
|
123
132
|
init_dist,
|
|
133
|
+
isoWeek,
|
|
124
134
|
listStreams,
|
|
125
135
|
listTaintedSessions,
|
|
126
136
|
loadState,
|
|
@@ -142,6 +152,7 @@ import {
|
|
|
142
152
|
resolveStreamPath,
|
|
143
153
|
runAll,
|
|
144
154
|
runCIChecks,
|
|
155
|
+
runPulse,
|
|
145
156
|
runReviewPipeline,
|
|
146
157
|
scanForInjection,
|
|
147
158
|
setActiveStream,
|
|
@@ -149,9 +160,11 @@ import {
|
|
|
149
160
|
validateAgentsMap,
|
|
150
161
|
validateDependencies,
|
|
151
162
|
validateKnowledgeMap,
|
|
163
|
+
validatePulseConfig,
|
|
164
|
+
validateSolutionsDir,
|
|
152
165
|
writeConfig,
|
|
153
166
|
writeLockfile
|
|
154
|
-
} from "./chunk-
|
|
167
|
+
} from "./chunk-K4WRQTEF.js";
|
|
155
168
|
import {
|
|
156
169
|
Err,
|
|
157
170
|
Ok
|
|
@@ -176,7 +189,7 @@ import {
|
|
|
176
189
|
} from "./chunk-KFQGP6VL.js";
|
|
177
190
|
|
|
178
191
|
// src/index.ts
|
|
179
|
-
import { Command as
|
|
192
|
+
import { Command as Command90 } from "commander";
|
|
180
193
|
|
|
181
194
|
// src/commands/add.ts
|
|
182
195
|
init_dist();
|
|
@@ -365,7 +378,7 @@ function registerSkillsCommand(adoption) {
|
|
|
365
378
|
const globalOpts = cmd.optsWithGlobals();
|
|
366
379
|
const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
|
|
367
380
|
const cwd = process.cwd();
|
|
368
|
-
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-
|
|
381
|
+
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-6RT2AVYU.js");
|
|
369
382
|
const records = readAdoptionRecords(cwd);
|
|
370
383
|
if (records.length === 0) {
|
|
371
384
|
if (globalOpts.json) {
|
|
@@ -401,7 +414,7 @@ function registerRecentCommand(adoption) {
|
|
|
401
414
|
const globalOpts = cmd.optsWithGlobals();
|
|
402
415
|
const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
|
|
403
416
|
const cwd = process.cwd();
|
|
404
|
-
const { readAdoptionRecords } = await import("./dist-
|
|
417
|
+
const { readAdoptionRecords } = await import("./dist-6RT2AVYU.js");
|
|
405
418
|
const records = readAdoptionRecords(cwd);
|
|
406
419
|
if (records.length === 0) {
|
|
407
420
|
if (globalOpts.json) {
|
|
@@ -479,7 +492,7 @@ function registerSkillCommand(adoption) {
|
|
|
479
492
|
adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
|
|
480
493
|
const globalOpts = cmd.optsWithGlobals();
|
|
481
494
|
const cwd = process.cwd();
|
|
482
|
-
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-
|
|
495
|
+
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-6RT2AVYU.js");
|
|
483
496
|
const records = readAdoptionRecords(cwd);
|
|
484
497
|
const skillRecords = records.filter((r) => r.skill === name);
|
|
485
498
|
if (skillRecords.length === 0) {
|
|
@@ -955,8 +968,7 @@ async function runCheckArch(options) {
|
|
|
955
968
|
const manager = new ArchBaselineManager(cwd, archConfig.baselinePath);
|
|
956
969
|
if (options.updateBaseline) {
|
|
957
970
|
const commitHash = getCommitHash(cwd);
|
|
958
|
-
|
|
959
|
-
manager.save(baseline2);
|
|
971
|
+
manager.update(results, commitHash);
|
|
960
972
|
return Ok({
|
|
961
973
|
passed: true,
|
|
962
974
|
mode: "baseline",
|
|
@@ -2101,16 +2113,108 @@ function createCleanupSessionsCommand() {
|
|
|
2101
2113
|
return command;
|
|
2102
2114
|
}
|
|
2103
2115
|
|
|
2104
|
-
// src/commands/
|
|
2116
|
+
// src/commands/compound/index.ts
|
|
2117
|
+
import { Command as Command20 } from "commander";
|
|
2118
|
+
|
|
2119
|
+
// src/commands/compound/scan-candidates.ts
|
|
2120
|
+
init_dist();
|
|
2121
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
2122
|
+
import { dirname as dirname2, join as join6, resolve as resolve11 } from "path";
|
|
2105
2123
|
import { Command as Command19 } from "commander";
|
|
2124
|
+
var HOTSPOT_THRESHOLD = 7;
|
|
2125
|
+
var DEFAULT_LOOKBACK = "7d";
|
|
2126
|
+
async function runCompoundScanCandidatesCommand(opts) {
|
|
2127
|
+
const startedAt = Date.now();
|
|
2128
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
2129
|
+
const lookback = opts.lookback ?? DEFAULT_LOOKBACK;
|
|
2130
|
+
let undocumented;
|
|
2131
|
+
let hotspots;
|
|
2132
|
+
try {
|
|
2133
|
+
const fixes = await gitScan({ since: lookback, cwd });
|
|
2134
|
+
undocumented = await crossReferenceUndocumentedFixes(fixes, opts.solutionsDir);
|
|
2135
|
+
hotspots = await computeHotspots({ since: lookback, cwd, threshold: HOTSPOT_THRESHOLD });
|
|
2136
|
+
} catch (err) {
|
|
2137
|
+
return emit(
|
|
2138
|
+
{ status: "failure", reason: err instanceof Error ? err.message : String(err), lookback },
|
|
2139
|
+
opts.nonInteractive
|
|
2140
|
+
);
|
|
2141
|
+
}
|
|
2142
|
+
const week = isoWeek(/* @__PURE__ */ new Date());
|
|
2143
|
+
const report = assembleCandidateReport({
|
|
2144
|
+
undocumentedFixes: undocumented,
|
|
2145
|
+
hotspotCandidates: hotspots,
|
|
2146
|
+
isoWeek: week,
|
|
2147
|
+
lookback
|
|
2148
|
+
});
|
|
2149
|
+
const outputPath = opts.outputPath ?? join6(cwd, "docs/solutions/.candidates", `${formatIsoWeek(week)}.md`);
|
|
2150
|
+
mkdirSync3(dirname2(outputPath), { recursive: true });
|
|
2151
|
+
writeFileSync3(outputPath, report);
|
|
2152
|
+
const candidatesFound = undocumented.length + hotspots.length;
|
|
2153
|
+
const status = {
|
|
2154
|
+
status: candidatesFound === 0 ? "no-issues" : "success",
|
|
2155
|
+
path: outputPath,
|
|
2156
|
+
candidatesFound,
|
|
2157
|
+
lookback,
|
|
2158
|
+
durationMs: Date.now() - startedAt
|
|
2159
|
+
};
|
|
2160
|
+
return emit(status, opts.nonInteractive);
|
|
2161
|
+
}
|
|
2162
|
+
function emit(status, nonInteractive) {
|
|
2163
|
+
if (nonInteractive) {
|
|
2164
|
+
process.stdout.write(JSON.stringify(status) + "\n");
|
|
2165
|
+
} else if (status.status === "failure") {
|
|
2166
|
+
process.stderr.write(`scan-candidates failed: ${status.reason}
|
|
2167
|
+
`);
|
|
2168
|
+
} else {
|
|
2169
|
+
process.stdout.write(
|
|
2170
|
+
`${status.candidatesFound} candidate(s) over ${status.lookback}
|
|
2171
|
+
\u2192 ${status.path}
|
|
2172
|
+
`
|
|
2173
|
+
);
|
|
2174
|
+
}
|
|
2175
|
+
return status;
|
|
2176
|
+
}
|
|
2177
|
+
function createScanCandidatesCommand() {
|
|
2178
|
+
return new Command19("scan-candidates").description(
|
|
2179
|
+
"Scan recent fixes and hotspots for undocumented learnings; write candidate prompts"
|
|
2180
|
+
).option("--lookback <window>", "Lookback window (e.g. 7d, 14d).", DEFAULT_LOOKBACK).option(
|
|
2181
|
+
"--non-interactive",
|
|
2182
|
+
"Emit single-line JSON status on stdout. Auto-detected when stdout is not a TTY."
|
|
2183
|
+
).option("--config <path>", "Path to harness.config.json", "harness.config.json").option(
|
|
2184
|
+
"--output-path <path>",
|
|
2185
|
+
"Override output file path (default: docs/solutions/.candidates/{YYYY-WW}.md)"
|
|
2186
|
+
).option("--solutions-dir <path>", "Solutions directory to cross-reference", "docs/solutions").action(
|
|
2187
|
+
async (options) => {
|
|
2188
|
+
const nonInteractive = options.nonInteractive === true || !process.stdout.isTTY;
|
|
2189
|
+
const status = await runCompoundScanCandidatesCommand({
|
|
2190
|
+
lookback: options.lookback,
|
|
2191
|
+
configPath: resolve11(process.cwd(), options.config),
|
|
2192
|
+
outputPath: options.outputPath ? resolve11(process.cwd(), options.outputPath) : void 0,
|
|
2193
|
+
solutionsDir: resolve11(process.cwd(), options.solutionsDir),
|
|
2194
|
+
nonInteractive
|
|
2195
|
+
});
|
|
2196
|
+
if (status.status === "failure") process.exitCode = 1;
|
|
2197
|
+
}
|
|
2198
|
+
);
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
// src/commands/compound/index.ts
|
|
2202
|
+
function createCompoundCommand() {
|
|
2203
|
+
const command = new Command20("compound").description("Compound (post-mortem playbook) commands");
|
|
2204
|
+
command.addCommand(createScanCandidatesCommand());
|
|
2205
|
+
return command;
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
// src/commands/dashboard.ts
|
|
2209
|
+
import { Command as Command21 } from "commander";
|
|
2106
2210
|
import { spawn } from "child_process";
|
|
2107
2211
|
import { existsSync as existsSync4 } from "fs";
|
|
2108
2212
|
import { createRequire } from "module";
|
|
2109
|
-
import { dirname as
|
|
2213
|
+
import { dirname as dirname3, join as join7, resolve as resolve12 } from "path";
|
|
2110
2214
|
import { setTimeout } from "timers";
|
|
2111
2215
|
import { fileURLToPath } from "url";
|
|
2112
2216
|
var __filename = fileURLToPath(import.meta.url);
|
|
2113
|
-
var __dirname =
|
|
2217
|
+
var __dirname = dirname3(__filename);
|
|
2114
2218
|
var require2 = createRequire(import.meta.url);
|
|
2115
2219
|
var DEFAULT_CLIENT_PORT = 3700;
|
|
2116
2220
|
var DEFAULT_API_PORT = 3701;
|
|
@@ -2121,21 +2225,21 @@ function openBrowser(url) {
|
|
|
2121
2225
|
function resolveServerScript() {
|
|
2122
2226
|
try {
|
|
2123
2227
|
const pkgPath = require2.resolve("@harness-engineering/dashboard/package.json");
|
|
2124
|
-
const pkgDir =
|
|
2125
|
-
const built2 =
|
|
2228
|
+
const pkgDir = dirname3(pkgPath);
|
|
2229
|
+
const built2 = join7(pkgDir, "dist", "server", "serve.js");
|
|
2126
2230
|
if (existsSync4(built2)) return { script: built2, dev: false };
|
|
2127
|
-
const dev2 =
|
|
2231
|
+
const dev2 = join7(pkgDir, "src", "server", "serve.ts");
|
|
2128
2232
|
if (existsSync4(dev2)) return { script: dev2, dev: true };
|
|
2129
2233
|
} catch {
|
|
2130
2234
|
}
|
|
2131
2235
|
const built = [
|
|
2132
|
-
|
|
2133
|
-
|
|
2236
|
+
join7(__dirname, "..", "..", "..", "dashboard", "dist", "server", "serve.js"),
|
|
2237
|
+
join7(__dirname, "..", "..", "..", "..", "packages", "dashboard", "dist", "server", "serve.js")
|
|
2134
2238
|
].find((p) => existsSync4(p));
|
|
2135
2239
|
if (built) return { script: built, dev: false };
|
|
2136
2240
|
const dev = [
|
|
2137
|
-
|
|
2138
|
-
|
|
2241
|
+
join7(__dirname, "..", "..", "..", "dashboard", "src", "server", "serve.ts"),
|
|
2242
|
+
join7(__dirname, "..", "..", "..", "..", "packages", "dashboard", "src", "server", "serve.ts")
|
|
2139
2243
|
].find((p) => existsSync4(p));
|
|
2140
2244
|
return dev ? { script: dev, dev: true } : null;
|
|
2141
2245
|
}
|
|
@@ -2170,7 +2274,7 @@ function buildDashboardEnv(opts, clientPort, apiPort, projectPath) {
|
|
|
2170
2274
|
function runDashboard(opts) {
|
|
2171
2275
|
const clientPort = Number(opts.port ?? DEFAULT_CLIENT_PORT);
|
|
2172
2276
|
const apiPort = Number(opts.apiPort ?? DEFAULT_API_PORT);
|
|
2173
|
-
const projectPath =
|
|
2277
|
+
const projectPath = resolve12(opts.cwd ?? process.cwd());
|
|
2174
2278
|
const url = `http://localhost:${apiPort}`;
|
|
2175
2279
|
const server = resolveServerScript();
|
|
2176
2280
|
if (!server) {
|
|
@@ -2186,11 +2290,11 @@ function runDashboard(opts) {
|
|
|
2186
2290
|
}
|
|
2187
2291
|
}
|
|
2188
2292
|
function createDashboardCommand() {
|
|
2189
|
-
return new
|
|
2293
|
+
return new Command21("dashboard").description("Start the Harness local web dashboard").option("--port <port>", "Client dev server port", String(DEFAULT_CLIENT_PORT)).option("--api-port <port>", "API server port", String(DEFAULT_API_PORT)).option("--orchestrator-url <url>", "Orchestrator URL (default: http://localhost:8080)").option("--no-open", "Do not automatically open browser").option("--cwd <path>", "Project directory (defaults to cwd)").action((opts) => runDashboard(opts));
|
|
2190
2294
|
}
|
|
2191
2295
|
|
|
2192
2296
|
// src/commands/doctor.ts
|
|
2193
|
-
import { Command as
|
|
2297
|
+
import { Command as Command22 } from "commander";
|
|
2194
2298
|
import * as fs7 from "fs";
|
|
2195
2299
|
import * as os from "os";
|
|
2196
2300
|
import * as path13 from "path";
|
|
@@ -2508,7 +2612,7 @@ function formatCheck(check) {
|
|
|
2508
2612
|
return line;
|
|
2509
2613
|
}
|
|
2510
2614
|
function createDoctorCommand() {
|
|
2511
|
-
return new
|
|
2615
|
+
return new Command22("doctor").description("Check environment health: Node version, slash commands, MCP configuration").action((_opts, cmd) => {
|
|
2512
2616
|
const globalOpts = cmd.optsWithGlobals();
|
|
2513
2617
|
const cwd = process.cwd();
|
|
2514
2618
|
const useJson = globalOpts.json;
|
|
@@ -2534,7 +2638,7 @@ function createDoctorCommand() {
|
|
|
2534
2638
|
|
|
2535
2639
|
// src/commands/fix-drift.ts
|
|
2536
2640
|
init_dist();
|
|
2537
|
-
import { Command as
|
|
2641
|
+
import { Command as Command23 } from "commander";
|
|
2538
2642
|
import * as path14 from "path";
|
|
2539
2643
|
async function runFixDrift(options) {
|
|
2540
2644
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -2667,7 +2771,7 @@ function printFixDriftResult(value, mode, formatter) {
|
|
|
2667
2771
|
}
|
|
2668
2772
|
}
|
|
2669
2773
|
function createFixDriftCommand() {
|
|
2670
|
-
const command = new
|
|
2774
|
+
const command = new Command23("fix-drift").description("Auto-fix entropy issues (doc drift, dead code)").option("--no-dry-run", "Actually apply fixes (default is dry-run mode)").action(async (opts, cmd) => {
|
|
2671
2775
|
const globalOpts = cmd.optsWithGlobals();
|
|
2672
2776
|
const mode = resolveOutputMode(globalOpts);
|
|
2673
2777
|
const formatter = new OutputFormatter(mode);
|
|
@@ -2697,7 +2801,7 @@ function createFixDriftCommand() {
|
|
|
2697
2801
|
}
|
|
2698
2802
|
|
|
2699
2803
|
// src/commands/generate.ts
|
|
2700
|
-
import { Command as
|
|
2804
|
+
import { Command as Command24 } from "commander";
|
|
2701
2805
|
function validatePlatforms(platforms) {
|
|
2702
2806
|
for (const p of platforms) {
|
|
2703
2807
|
if (!VALID_PLATFORMS.includes(p)) {
|
|
@@ -2757,50 +2861,75 @@ async function runGenerateAction(opts, globalOpts) {
|
|
|
2757
2861
|
}
|
|
2758
2862
|
}
|
|
2759
2863
|
function createGenerateCommand() {
|
|
2760
|
-
return new
|
|
2864
|
+
return new Command24("generate").description("Generate all platform integrations (slash commands + agent definitions)").option("--platforms <list>", "Target platforms (comma-separated)", "claude-code,gemini-cli").option("--global", "Write to global directories", false).option("--include-global", "Include built-in global skills", false).option("--output <dir>", "Custom output directory").option("--dry-run", "Show what would change without writing", false).option("--yes", "Skip deletion confirmation prompts", false).action(async (opts, cmd) => {
|
|
2761
2865
|
await runGenerateAction(opts, cmd.optsWithGlobals());
|
|
2762
2866
|
});
|
|
2763
2867
|
}
|
|
2764
2868
|
|
|
2765
2869
|
// src/commands/graph/index.ts
|
|
2766
|
-
import { Command as
|
|
2870
|
+
import { Command as Command27 } from "commander";
|
|
2767
2871
|
|
|
2768
2872
|
// src/commands/graph/status.ts
|
|
2769
2873
|
import * as path15 from "path";
|
|
2770
|
-
async function
|
|
2771
|
-
const { GraphStore } = await import("./dist-42AYXCAK.js");
|
|
2772
|
-
const graphDir = path15.join(projectPath, ".harness", "graph");
|
|
2773
|
-
const store = new GraphStore();
|
|
2774
|
-
const loaded = await store.load(graphDir);
|
|
2775
|
-
if (!loaded) return { status: "no_graph", message: "No graph found. Run `harness scan` first." };
|
|
2874
|
+
async function readConnectorSyncStatus(graphDir) {
|
|
2776
2875
|
const fs42 = await import("fs/promises");
|
|
2777
|
-
const
|
|
2778
|
-
let lastScan = "unknown";
|
|
2779
|
-
try {
|
|
2780
|
-
const meta = JSON.parse(await fs42.readFile(metaPath, "utf-8"));
|
|
2781
|
-
lastScan = meta.lastScanTimestamp;
|
|
2782
|
-
} catch {
|
|
2783
|
-
}
|
|
2784
|
-
const allNodes = store.findNodes({});
|
|
2785
|
-
const nodesByType = {};
|
|
2786
|
-
for (const node of allNodes) {
|
|
2787
|
-
nodesByType[node.type] = (nodesByType[node.type] ?? 0) + 1;
|
|
2788
|
-
}
|
|
2789
|
-
let connectorSyncStatus = {};
|
|
2876
|
+
const result = {};
|
|
2790
2877
|
try {
|
|
2791
2878
|
const syncMetaPath = path15.join(graphDir, "sync-metadata.json");
|
|
2792
2879
|
const syncMeta = JSON.parse(await fs42.readFile(syncMetaPath, "utf-8"));
|
|
2793
2880
|
for (const [name, data] of Object.entries(syncMeta.connectors ?? {})) {
|
|
2794
|
-
|
|
2881
|
+
result[name] = data.lastSyncTimestamp;
|
|
2795
2882
|
}
|
|
2796
2883
|
} catch {
|
|
2797
2884
|
}
|
|
2885
|
+
return result;
|
|
2886
|
+
}
|
|
2887
|
+
async function runGraphStatus(projectPath) {
|
|
2888
|
+
const { GraphStore, loadGraphMetadata } = await import("./dist-D27LJR2T.js");
|
|
2889
|
+
const graphDir = path15.join(projectPath, ".harness", "graph");
|
|
2890
|
+
const metaResult = await loadGraphMetadata(graphDir);
|
|
2891
|
+
if (metaResult.status === "not_found") {
|
|
2892
|
+
return { status: "no_graph", message: "No graph found. Run `harness scan` first." };
|
|
2893
|
+
}
|
|
2894
|
+
if (metaResult.status === "schema_mismatch") {
|
|
2895
|
+
return {
|
|
2896
|
+
status: "schema_mismatch",
|
|
2897
|
+
message: `Graph schema version mismatch: file is v${metaResult.found}, CLI expects v${metaResult.expected}. Run \`harness scan\` to rebuild.`
|
|
2898
|
+
};
|
|
2899
|
+
}
|
|
2900
|
+
const meta = metaResult.metadata;
|
|
2901
|
+
const connectorSyncStatus = await readConnectorSyncStatus(graphDir);
|
|
2902
|
+
if (meta.nodesByType) {
|
|
2903
|
+
return {
|
|
2904
|
+
status: "ok",
|
|
2905
|
+
nodeCount: meta.nodeCount,
|
|
2906
|
+
edgeCount: meta.edgeCount,
|
|
2907
|
+
nodesByType: { ...meta.nodesByType },
|
|
2908
|
+
lastScanTimestamp: meta.lastScanTimestamp,
|
|
2909
|
+
...Object.keys(connectorSyncStatus).length > 0 ? { connectorSyncStatus } : {}
|
|
2910
|
+
};
|
|
2911
|
+
}
|
|
2912
|
+
const store = new GraphStore();
|
|
2913
|
+
const loaded = await store.load(graphDir);
|
|
2914
|
+
if (!loaded) {
|
|
2915
|
+
return {
|
|
2916
|
+
status: "ok",
|
|
2917
|
+
nodeCount: meta.nodeCount,
|
|
2918
|
+
edgeCount: meta.edgeCount,
|
|
2919
|
+
lastScanTimestamp: meta.lastScanTimestamp,
|
|
2920
|
+
...Object.keys(connectorSyncStatus).length > 0 ? { connectorSyncStatus } : {}
|
|
2921
|
+
};
|
|
2922
|
+
}
|
|
2923
|
+
const nodesByType = {};
|
|
2924
|
+
for (const node of store.findNodes({})) {
|
|
2925
|
+
nodesByType[node.type] = (nodesByType[node.type] ?? 0) + 1;
|
|
2926
|
+
}
|
|
2798
2927
|
return {
|
|
2799
2928
|
status: "ok",
|
|
2800
2929
|
nodeCount: store.nodeCount,
|
|
2801
2930
|
edgeCount: store.edgeCount,
|
|
2802
2931
|
nodesByType,
|
|
2803
|
-
lastScanTimestamp:
|
|
2932
|
+
lastScanTimestamp: meta.lastScanTimestamp,
|
|
2804
2933
|
...Object.keys(connectorSyncStatus).length > 0 ? { connectorSyncStatus } : {}
|
|
2805
2934
|
};
|
|
2806
2935
|
}
|
|
@@ -2808,7 +2937,7 @@ async function runGraphStatus(projectPath) {
|
|
|
2808
2937
|
// src/commands/graph/export.ts
|
|
2809
2938
|
import * as path16 from "path";
|
|
2810
2939
|
async function runGraphExport(projectPath, format) {
|
|
2811
|
-
const { GraphStore } = await import("./dist-
|
|
2940
|
+
const { GraphStore } = await import("./dist-D27LJR2T.js");
|
|
2812
2941
|
const graphDir = path16.join(projectPath, ".harness", "graph");
|
|
2813
2942
|
const store = new GraphStore();
|
|
2814
2943
|
const loaded = await store.load(graphDir);
|
|
@@ -2841,10 +2970,10 @@ async function runGraphExport(projectPath, format) {
|
|
|
2841
2970
|
import * as path19 from "path";
|
|
2842
2971
|
|
|
2843
2972
|
// src/commands/graph/query.ts
|
|
2844
|
-
import { Command as
|
|
2973
|
+
import { Command as Command25 } from "commander";
|
|
2845
2974
|
import * as path17 from "path";
|
|
2846
2975
|
async function runQuery(projectPath, rootNodeId, opts) {
|
|
2847
|
-
const { GraphStore, ContextQL } = await import("./dist-
|
|
2976
|
+
const { GraphStore, ContextQL } = await import("./dist-D27LJR2T.js");
|
|
2848
2977
|
const store = new GraphStore();
|
|
2849
2978
|
const graphDir = path17.join(projectPath, ".harness", "graph");
|
|
2850
2979
|
const loaded = await store.load(graphDir);
|
|
@@ -2887,13 +3016,13 @@ async function runQueryAction(rootNodeId, opts, globalOpts) {
|
|
|
2887
3016
|
}
|
|
2888
3017
|
}
|
|
2889
3018
|
function createQueryCommand() {
|
|
2890
|
-
return new
|
|
3019
|
+
return new Command25("query").description("Query the knowledge graph").argument("<rootNodeId>", "Starting node ID").option("--depth <n>", "Max traversal depth", "3").option("--types <types>", "Comma-separated node types to include").option("--edges <edges>", "Comma-separated edge types to include").option("--bidirectional", "Traverse both directions").action(async (rootNodeId, opts, cmd) => {
|
|
2891
3020
|
await runQueryAction(rootNodeId, opts, cmd.optsWithGlobals());
|
|
2892
3021
|
});
|
|
2893
3022
|
}
|
|
2894
3023
|
|
|
2895
3024
|
// src/commands/graph/ingest.ts
|
|
2896
|
-
import { Command as
|
|
3025
|
+
import { Command as Command26 } from "commander";
|
|
2897
3026
|
import * as path18 from "path";
|
|
2898
3027
|
async function loadConnectorConfig(projectPath, source) {
|
|
2899
3028
|
try {
|
|
@@ -2941,20 +3070,21 @@ async function runIngest(projectPath, source, opts) {
|
|
|
2941
3070
|
ConfluenceConnector,
|
|
2942
3071
|
FigmaConnector,
|
|
2943
3072
|
MiroConnector
|
|
2944
|
-
} = await import("./dist-
|
|
3073
|
+
} = await import("./dist-D27LJR2T.js");
|
|
2945
3074
|
const graphDir = path18.join(projectPath, ".harness", "graph");
|
|
2946
3075
|
const store = new GraphStore();
|
|
2947
3076
|
await store.load(graphDir);
|
|
3077
|
+
const ingestOptions = loadIngestOptions(projectPath);
|
|
2948
3078
|
if (opts?.all) {
|
|
2949
3079
|
const startMs = Date.now();
|
|
2950
|
-
const codeResult = await new CodeIngestor(store).ingest(projectPath);
|
|
3080
|
+
const codeResult = await new CodeIngestor(store, ingestOptions).ingest(projectPath);
|
|
2951
3081
|
new TopologicalLinker(store).link();
|
|
2952
3082
|
const knowledgeResult = await new KnowledgeIngestor(store).ingestAll(projectPath);
|
|
2953
3083
|
const reqResult = await new RequirementIngestor(store).ingestSpecs(
|
|
2954
3084
|
path18.join(projectPath, "docs", "changes")
|
|
2955
3085
|
);
|
|
2956
3086
|
const gitResult = await new GitIngestor(store).ingest(projectPath);
|
|
2957
|
-
const { createExtractionRunner } = await import("./dist-
|
|
3087
|
+
const { createExtractionRunner } = await import("./dist-D27LJR2T.js");
|
|
2958
3088
|
const extractedDir = path18.join(projectPath, ".harness", "knowledge", "extracted");
|
|
2959
3089
|
const signalsResult = await createExtractionRunner().run(projectPath, store, extractedDir);
|
|
2960
3090
|
const syncManager = new SyncManager(store, graphDir);
|
|
@@ -2985,7 +3115,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
2985
3115
|
let result;
|
|
2986
3116
|
switch (source) {
|
|
2987
3117
|
case "code":
|
|
2988
|
-
result = await new CodeIngestor(store).ingest(projectPath);
|
|
3118
|
+
result = await new CodeIngestor(store, ingestOptions).ingest(projectPath);
|
|
2989
3119
|
new TopologicalLinker(store).link();
|
|
2990
3120
|
break;
|
|
2991
3121
|
case "knowledge":
|
|
@@ -3000,7 +3130,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
3000
3130
|
);
|
|
3001
3131
|
break;
|
|
3002
3132
|
case "business-signals": {
|
|
3003
|
-
const { createExtractionRunner } = await import("./dist-
|
|
3133
|
+
const { createExtractionRunner } = await import("./dist-D27LJR2T.js");
|
|
3004
3134
|
const extractedDir = path18.join(projectPath, ".harness", "knowledge", "extracted");
|
|
3005
3135
|
result = await createExtractionRunner().run(projectPath, store, extractedDir);
|
|
3006
3136
|
break;
|
|
@@ -3037,7 +3167,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
3037
3167
|
return result;
|
|
3038
3168
|
}
|
|
3039
3169
|
function createIngestCommand() {
|
|
3040
|
-
return new
|
|
3170
|
+
return new Command26("ingest").description("Ingest data into the knowledge graph").option(
|
|
3041
3171
|
"--source <name>",
|
|
3042
3172
|
"Source to ingest (code, knowledge, git, requirements, business-signals, jira, slack, ci, confluence, figma, miro)"
|
|
3043
3173
|
).option("--all", "Run all sources (code, knowledge, git, and configured connectors)").option("--full", "Force full re-ingestion").action(async (opts, cmd) => {
|
|
@@ -3072,15 +3202,17 @@ function resolveProjectPath(globalOpts) {
|
|
|
3072
3202
|
return path19.resolve(globalOpts.config ? path19.dirname(globalOpts.config) : ".");
|
|
3073
3203
|
}
|
|
3074
3204
|
function printGraphStatus(result) {
|
|
3075
|
-
if (result.status === "no_graph") {
|
|
3205
|
+
if (result.status === "no_graph" || result.status === "schema_mismatch") {
|
|
3076
3206
|
console.log(result.message);
|
|
3077
3207
|
return;
|
|
3078
3208
|
}
|
|
3079
3209
|
console.log(`Graph: ${result.nodeCount} nodes, ${result.edgeCount} edges`);
|
|
3080
3210
|
console.log(`Last scan: ${result.lastScanTimestamp}`);
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3211
|
+
if (result.nodesByType) {
|
|
3212
|
+
console.log("Nodes by type:");
|
|
3213
|
+
for (const [type, count] of Object.entries(result.nodesByType)) {
|
|
3214
|
+
console.log(` ${type}: ${count}`);
|
|
3215
|
+
}
|
|
3084
3216
|
}
|
|
3085
3217
|
if (!result.connectorSyncStatus) return;
|
|
3086
3218
|
console.log("Connector sync status:");
|
|
@@ -3113,17 +3245,17 @@ async function runExportAction(opts, cmd) {
|
|
|
3113
3245
|
}
|
|
3114
3246
|
}
|
|
3115
3247
|
function createGraphCommand() {
|
|
3116
|
-
const graph = new
|
|
3248
|
+
const graph = new Command27("graph").description("Knowledge graph management");
|
|
3117
3249
|
graph.command("status").description("Show graph statistics").action(runStatusAction);
|
|
3118
3250
|
graph.command("export").description("Export graph").requiredOption("--format <format>", "Output format (json, mermaid)").action(runExportAction);
|
|
3119
3251
|
return graph;
|
|
3120
3252
|
}
|
|
3121
3253
|
|
|
3122
3254
|
// src/commands/hooks/index.ts
|
|
3123
|
-
import { Command as
|
|
3255
|
+
import { Command as Command32 } from "commander";
|
|
3124
3256
|
|
|
3125
3257
|
// src/commands/hooks/init.ts
|
|
3126
|
-
import { Command as
|
|
3258
|
+
import { Command as Command28 } from "commander";
|
|
3127
3259
|
import * as fs8 from "fs";
|
|
3128
3260
|
import * as path20 from "path";
|
|
3129
3261
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -3245,7 +3377,7 @@ function initHooks(options) {
|
|
|
3245
3377
|
return { copiedScripts, settingsPath, profilePath };
|
|
3246
3378
|
}
|
|
3247
3379
|
function createInitCommand2() {
|
|
3248
|
-
return new
|
|
3380
|
+
return new Command28("init").description("Install Claude Code hook configurations into the current project").option("--profile <profile>", "Hook profile: minimal, standard, or strict", "standard").action(async (opts, cmd) => {
|
|
3249
3381
|
const globalOpts = cmd.optsWithGlobals();
|
|
3250
3382
|
const profile = opts.profile;
|
|
3251
3383
|
if (!VALID_PROFILES.includes(profile)) {
|
|
@@ -3283,7 +3415,7 @@ function createInitCommand2() {
|
|
|
3283
3415
|
}
|
|
3284
3416
|
|
|
3285
3417
|
// src/commands/hooks/list.ts
|
|
3286
|
-
import { Command as
|
|
3418
|
+
import { Command as Command29 } from "commander";
|
|
3287
3419
|
import * as fs9 from "fs";
|
|
3288
3420
|
import * as path21 from "path";
|
|
3289
3421
|
function listHooks(projectDir) {
|
|
@@ -3316,7 +3448,7 @@ function listHooks(projectDir) {
|
|
|
3316
3448
|
return result;
|
|
3317
3449
|
}
|
|
3318
3450
|
function createListCommand() {
|
|
3319
|
-
return new
|
|
3451
|
+
return new Command29("list").description("Show installed hooks and active profile").action(async (_opts, cmd) => {
|
|
3320
3452
|
const globalOpts = cmd.optsWithGlobals();
|
|
3321
3453
|
const projectDir = process.cwd();
|
|
3322
3454
|
const result = listHooks(projectDir);
|
|
@@ -3337,7 +3469,7 @@ function createListCommand() {
|
|
|
3337
3469
|
}
|
|
3338
3470
|
|
|
3339
3471
|
// src/commands/hooks/remove.ts
|
|
3340
|
-
import { Command as
|
|
3472
|
+
import { Command as Command30 } from "commander";
|
|
3341
3473
|
import * as fs10 from "fs";
|
|
3342
3474
|
import * as path22 from "path";
|
|
3343
3475
|
function removeHooks(projectDir) {
|
|
@@ -3367,7 +3499,7 @@ function removeHooks(projectDir) {
|
|
|
3367
3499
|
return { removed, hooksDir, settingsCleaned };
|
|
3368
3500
|
}
|
|
3369
3501
|
function createRemoveCommand() {
|
|
3370
|
-
return new
|
|
3502
|
+
return new Command30("remove").description("Remove harness-managed hooks from the current project").action(async (_opts, cmd) => {
|
|
3371
3503
|
const globalOpts = cmd.optsWithGlobals();
|
|
3372
3504
|
const projectDir = process.cwd();
|
|
3373
3505
|
const result = removeHooks(projectDir);
|
|
@@ -3389,7 +3521,7 @@ function createRemoveCommand() {
|
|
|
3389
3521
|
}
|
|
3390
3522
|
|
|
3391
3523
|
// src/commands/hooks/add.ts
|
|
3392
|
-
import { Command as
|
|
3524
|
+
import { Command as Command31 } from "commander";
|
|
3393
3525
|
import * as fs11 from "fs";
|
|
3394
3526
|
import * as path23 from "path";
|
|
3395
3527
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -3446,7 +3578,7 @@ function addHooks(hookName, projectDir) {
|
|
|
3446
3578
|
return result;
|
|
3447
3579
|
}
|
|
3448
3580
|
function createAddCommand2() {
|
|
3449
|
-
return new
|
|
3581
|
+
return new Command31("add").argument("<hook-name>", "Hook name or alias (e.g., sentinel)").description("Add a hook without changing the profile").action(async (hookName, _opts, cmd) => {
|
|
3450
3582
|
const projectDir = process.cwd();
|
|
3451
3583
|
try {
|
|
3452
3584
|
const res = addHooks(hookName, projectDir);
|
|
@@ -3471,7 +3603,7 @@ function createAddCommand2() {
|
|
|
3471
3603
|
|
|
3472
3604
|
// src/commands/hooks/index.ts
|
|
3473
3605
|
function createHooksCommand() {
|
|
3474
|
-
const command = new
|
|
3606
|
+
const command = new Command32("hooks").description("Manage Claude Code hook configurations");
|
|
3475
3607
|
command.addCommand(createInitCommand2());
|
|
3476
3608
|
command.addCommand(createListCommand());
|
|
3477
3609
|
command.addCommand(createRemoveCommand());
|
|
@@ -3480,7 +3612,7 @@ function createHooksCommand() {
|
|
|
3480
3612
|
}
|
|
3481
3613
|
|
|
3482
3614
|
// src/commands/impact-preview.ts
|
|
3483
|
-
import { Command as
|
|
3615
|
+
import { Command as Command33 } from "commander";
|
|
3484
3616
|
import { execSync as execSync4 } from "child_process";
|
|
3485
3617
|
import * as path24 from "path";
|
|
3486
3618
|
import * as fs12 from "fs";
|
|
@@ -3679,7 +3811,7 @@ async function runImpactPreview(options) {
|
|
|
3679
3811
|
return formatImpactOutput(stagedFiles, acc, options);
|
|
3680
3812
|
}
|
|
3681
3813
|
function createImpactPreviewCommand() {
|
|
3682
|
-
const command = new
|
|
3814
|
+
const command = new Command33("impact-preview").description("Show blast radius of staged changes using the knowledge graph").option("--detailed", "Show all affected files instead of top items").option("--per-file", "Show impact per staged file instead of aggregate").option("--path <dir>", "Project root (default: cwd)").action(async (opts) => {
|
|
3683
3815
|
const output = await runImpactPreview({
|
|
3684
3816
|
detailed: opts.detailed,
|
|
3685
3817
|
perFile: opts.perFile,
|
|
@@ -3693,13 +3825,13 @@ function createImpactPreviewCommand() {
|
|
|
3693
3825
|
|
|
3694
3826
|
// src/commands/init.ts
|
|
3695
3827
|
init_dist();
|
|
3696
|
-
import { Command as
|
|
3828
|
+
import { Command as Command35 } from "commander";
|
|
3697
3829
|
import chalk3 from "chalk";
|
|
3698
3830
|
import * as fs15 from "fs";
|
|
3699
3831
|
import * as path27 from "path";
|
|
3700
3832
|
|
|
3701
3833
|
// src/commands/setup-mcp.ts
|
|
3702
|
-
import { Command as
|
|
3834
|
+
import { Command as Command34 } from "commander";
|
|
3703
3835
|
import * as fs14 from "fs";
|
|
3704
3836
|
import * as path26 from "path";
|
|
3705
3837
|
import * as os2 from "os";
|
|
@@ -4023,7 +4155,7 @@ function printMcpResult(configured, skipped, trustedFolder) {
|
|
|
4023
4155
|
console.log("");
|
|
4024
4156
|
}
|
|
4025
4157
|
function createSetupMcpCommand() {
|
|
4026
|
-
return new
|
|
4158
|
+
return new Command34("setup-mcp").description("Configure MCP server for AI agent integration").option("--client <client>", "Client to configure (claude, gemini, codex, cursor, all)", "all").option("--pick", "Launch interactive tool picker (Cursor only)").option("--yes", "Bypass interactive picker and use curated 25-tool set (Cursor only)").action(async (opts, cmd) => {
|
|
4027
4159
|
const globalOpts = cmd.optsWithGlobals();
|
|
4028
4160
|
const cwd = process.cwd();
|
|
4029
4161
|
let configured;
|
|
@@ -4165,7 +4297,7 @@ async function runInitAction2(opts) {
|
|
|
4165
4297
|
process.exit(ExitCode.SUCCESS);
|
|
4166
4298
|
}
|
|
4167
4299
|
function createInitCommand3() {
|
|
4168
|
-
const command = new
|
|
4300
|
+
const command = new Command35("init").description("Initialize a new harness-engineering project").option("-n, --name <name>", "Project name").option("-l, --level <level>", "Adoption level (basic, intermediate, advanced)", "basic").option("-t, --template <template>", "Specific template name (e.g. orchestrator)").option("--framework <framework>", "Framework overlay (nextjs)").option("--language <language>", "Target language (typescript, python, go, rust, java)").option("-f, --force", "Overwrite existing files").option("-y, --yes", "Use defaults without prompting").action(async (opts, cmd) => {
|
|
4169
4301
|
const globalOpts = cmd.optsWithGlobals();
|
|
4170
4302
|
await runInitAction2({
|
|
4171
4303
|
name: opts.name,
|
|
@@ -4184,7 +4316,7 @@ import * as fs20 from "fs";
|
|
|
4184
4316
|
import * as os5 from "os";
|
|
4185
4317
|
import * as path32 from "path";
|
|
4186
4318
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
4187
|
-
import { Command as
|
|
4319
|
+
import { Command as Command36 } from "commander";
|
|
4188
4320
|
import { parse as yamlParse } from "yaml";
|
|
4189
4321
|
|
|
4190
4322
|
// src/registry/npm-client.ts
|
|
@@ -4744,7 +4876,7 @@ async function runInstall(skillName, options) {
|
|
|
4744
4876
|
return result;
|
|
4745
4877
|
}
|
|
4746
4878
|
function createInstallCommand() {
|
|
4747
|
-
const cmd = new
|
|
4879
|
+
const cmd = new Command36("install");
|
|
4748
4880
|
cmd.description("Install skills from npm registry, local directory, or GitHub repository").argument("<skill>", 'Skill name, @harness-skills/scoped package, or "." for bulk install').option("--version <range>", "Semver range or exact version to install").option("--force", "Force reinstall even if same version is already installed").option(
|
|
4749
4881
|
"--from <source>",
|
|
4750
4882
|
"Install from local path, directory, or GitHub (github:owner/repo, https://github.com/owner/repo)"
|
|
@@ -4780,7 +4912,7 @@ function createInstallCommand() {
|
|
|
4780
4912
|
init_dist();
|
|
4781
4913
|
import * as fs21 from "fs/promises";
|
|
4782
4914
|
import * as path33 from "path";
|
|
4783
|
-
import { Command as
|
|
4915
|
+
import { Command as Command37 } from "commander";
|
|
4784
4916
|
import semver3 from "semver";
|
|
4785
4917
|
async function runInstallConstraints(options) {
|
|
4786
4918
|
const { source, configPath, lockfilePath } = options;
|
|
@@ -5034,17 +5166,17 @@ async function handleInstallConstraints(source, opts) {
|
|
|
5034
5166
|
logInstallResult(result.value, opts);
|
|
5035
5167
|
}
|
|
5036
5168
|
function createInstallConstraintsCommand() {
|
|
5037
|
-
const cmd = new
|
|
5169
|
+
const cmd = new Command37("install-constraints");
|
|
5038
5170
|
cmd.description("Install a constraints bundle into the local harness config").argument("<source>", "Path to a .harness-constraints.json bundle file").option("--force-local", "Resolve all conflicts by keeping local values").option("--force-package", "Resolve all conflicts by using package values").option("--dry-run", "Show what would change without writing files").option("-c, --config <path>", "Path to harness.config.json").action(handleInstallConstraints);
|
|
5039
5171
|
return cmd;
|
|
5040
5172
|
}
|
|
5041
5173
|
|
|
5042
5174
|
// src/commands/integrations/index.ts
|
|
5043
|
-
import { Command as
|
|
5175
|
+
import { Command as Command42 } from "commander";
|
|
5044
5176
|
|
|
5045
5177
|
// src/commands/integrations/add.ts
|
|
5046
5178
|
init_dist();
|
|
5047
|
-
import { Command as
|
|
5179
|
+
import { Command as Command38 } from "commander";
|
|
5048
5180
|
import * as fs22 from "fs";
|
|
5049
5181
|
import * as path34 from "path";
|
|
5050
5182
|
import chalk4 from "chalk";
|
|
@@ -5108,7 +5240,7 @@ function printAddSuccess(value) {
|
|
|
5108
5240
|
}
|
|
5109
5241
|
}
|
|
5110
5242
|
function createAddIntegrationCommand() {
|
|
5111
|
-
return new
|
|
5243
|
+
return new Command38("add").description("Enable an MCP integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
|
|
5112
5244
|
const globalOpts = cmd.optsWithGlobals();
|
|
5113
5245
|
const result = addIntegration(process.cwd(), name);
|
|
5114
5246
|
if (!result.ok) {
|
|
@@ -5122,7 +5254,7 @@ function createAddIntegrationCommand() {
|
|
|
5122
5254
|
}
|
|
5123
5255
|
|
|
5124
5256
|
// src/commands/integrations/list.ts
|
|
5125
|
-
import { Command as
|
|
5257
|
+
import { Command as Command39 } from "commander";
|
|
5126
5258
|
import * as path35 from "path";
|
|
5127
5259
|
import chalk5 from "chalk";
|
|
5128
5260
|
function printTier0Integrations(tier0, mcpServers) {
|
|
@@ -5179,12 +5311,12 @@ async function runListIntegrations(globalOpts) {
|
|
|
5179
5311
|
process.exit(ExitCode.SUCCESS);
|
|
5180
5312
|
}
|
|
5181
5313
|
function createListIntegrationsCommand() {
|
|
5182
|
-
return new
|
|
5314
|
+
return new Command39("list").description("Show all MCP integrations with status").action(async (_opts, cmd) => runListIntegrations(cmd.optsWithGlobals()));
|
|
5183
5315
|
}
|
|
5184
5316
|
|
|
5185
5317
|
// src/commands/integrations/remove.ts
|
|
5186
5318
|
init_dist();
|
|
5187
|
-
import { Command as
|
|
5319
|
+
import { Command as Command40 } from "commander";
|
|
5188
5320
|
import * as fs23 from "fs";
|
|
5189
5321
|
import * as path36 from "path";
|
|
5190
5322
|
function removeIntegration(cwd, name) {
|
|
@@ -5211,7 +5343,7 @@ function removeIntegration(cwd, name) {
|
|
|
5211
5343
|
return Ok(def.displayName);
|
|
5212
5344
|
}
|
|
5213
5345
|
function createRemoveIntegrationCommand() {
|
|
5214
|
-
return new
|
|
5346
|
+
return new Command40("remove").description("Remove an MCP integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
|
|
5215
5347
|
const globalOpts = cmd.optsWithGlobals();
|
|
5216
5348
|
const cwd = process.cwd();
|
|
5217
5349
|
const result = removeIntegration(cwd, name);
|
|
@@ -5233,7 +5365,7 @@ function createRemoveIntegrationCommand() {
|
|
|
5233
5365
|
|
|
5234
5366
|
// src/commands/integrations/dismiss.ts
|
|
5235
5367
|
init_dist();
|
|
5236
|
-
import { Command as
|
|
5368
|
+
import { Command as Command41 } from "commander";
|
|
5237
5369
|
import * as path37 from "path";
|
|
5238
5370
|
function dismissIntegration(cwd, name) {
|
|
5239
5371
|
const def = INTEGRATION_REGISTRY.find((i) => i.name === name);
|
|
@@ -5255,7 +5387,7 @@ function dismissIntegration(cwd, name) {
|
|
|
5255
5387
|
return Ok(def.displayName);
|
|
5256
5388
|
}
|
|
5257
5389
|
function createDismissIntegrationCommand() {
|
|
5258
|
-
return new
|
|
5390
|
+
return new Command41("dismiss").description("Suppress doctor recommendations for an integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
|
|
5259
5391
|
const globalOpts = cmd.optsWithGlobals();
|
|
5260
5392
|
const cwd = process.cwd();
|
|
5261
5393
|
const result = dismissIntegration(cwd, name);
|
|
@@ -5279,7 +5411,7 @@ function createDismissIntegrationCommand() {
|
|
|
5279
5411
|
|
|
5280
5412
|
// src/commands/integrations/index.ts
|
|
5281
5413
|
function createIntegrationsCommand() {
|
|
5282
|
-
const command = new
|
|
5414
|
+
const command = new Command42("integrations").description(
|
|
5283
5415
|
"Manage MCP peer integrations (add, list, remove, dismiss)"
|
|
5284
5416
|
);
|
|
5285
5417
|
command.addCommand(createListIntegrationsCommand());
|
|
@@ -5290,18 +5422,18 @@ function createIntegrationsCommand() {
|
|
|
5290
5422
|
}
|
|
5291
5423
|
|
|
5292
5424
|
// src/commands/knowledge-pipeline.ts
|
|
5293
|
-
import { Command as
|
|
5425
|
+
import { Command as Command43 } from "commander";
|
|
5294
5426
|
import * as path38 from "path";
|
|
5295
5427
|
import chalk6 from "chalk";
|
|
5296
5428
|
function createKnowledgePipelineCommand() {
|
|
5297
|
-
return new
|
|
5429
|
+
return new Command43("knowledge-pipeline").description("Run knowledge extraction, drift detection, and gap analysis").option("--fix", "Enable convergence-based auto-remediation (default: detect-only)").option("--ci", "Non-interactive mode \u2014 apply safe fixes only, report everything else").option("--domain <name>", "Limit pipeline to a specific knowledge domain").option("--drift-check", "Exit 1 if unresolved drift exists (CI gate mode)").option("--analyze-images", "Enable vision model analysis of image files").option("--image-paths <paths>", "Comma-separated image file paths for analysis").option("--coverage", "Display per-domain coverage report").option("--check-contradictions", "Display cross-source contradiction report").action(async (opts, cmd) => {
|
|
5298
5430
|
const globalOpts = cmd.optsWithGlobals();
|
|
5299
5431
|
const projectDir = process.cwd();
|
|
5300
5432
|
try {
|
|
5301
5433
|
const graphDir = path38.join(projectDir, ".harness", "graph");
|
|
5302
5434
|
const fs42 = await import("fs/promises");
|
|
5303
5435
|
await fs42.mkdir(graphDir, { recursive: true });
|
|
5304
|
-
const { GraphStore, KnowledgePipelineRunner } = await import("./dist-
|
|
5436
|
+
const { GraphStore, KnowledgePipelineRunner } = await import("./dist-D27LJR2T.js");
|
|
5305
5437
|
const store = new GraphStore();
|
|
5306
5438
|
try {
|
|
5307
5439
|
await store.load(graphDir);
|
|
@@ -5458,11 +5590,11 @@ function createKnowledgePipelineCommand() {
|
|
|
5458
5590
|
}
|
|
5459
5591
|
|
|
5460
5592
|
// src/commands/learnings/index.ts
|
|
5461
|
-
import { Command as
|
|
5593
|
+
import { Command as Command45 } from "commander";
|
|
5462
5594
|
|
|
5463
5595
|
// src/commands/learnings/prune.ts
|
|
5464
5596
|
init_dist();
|
|
5465
|
-
import { Command as
|
|
5597
|
+
import { Command as Command44 } from "commander";
|
|
5466
5598
|
import * as path39 from "path";
|
|
5467
5599
|
async function handlePrune(opts) {
|
|
5468
5600
|
const projectPath = path39.resolve(opts.path);
|
|
@@ -5504,23 +5636,23 @@ function printPatternProposals(patterns) {
|
|
|
5504
5636
|
);
|
|
5505
5637
|
}
|
|
5506
5638
|
function createPruneCommand() {
|
|
5507
|
-
return new
|
|
5639
|
+
return new Command44("prune").description(
|
|
5508
5640
|
"Analyze global learnings for patterns, present improvement proposals, and archive old entries"
|
|
5509
5641
|
).option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(handlePrune);
|
|
5510
5642
|
}
|
|
5511
5643
|
|
|
5512
5644
|
// src/commands/learnings/index.ts
|
|
5513
5645
|
function createLearningsCommand() {
|
|
5514
|
-
const command = new
|
|
5646
|
+
const command = new Command45("learnings").description("Learnings management commands");
|
|
5515
5647
|
command.addCommand(createPruneCommand());
|
|
5516
5648
|
return command;
|
|
5517
5649
|
}
|
|
5518
5650
|
|
|
5519
5651
|
// src/commands/linter/index.ts
|
|
5520
|
-
import { Command as
|
|
5652
|
+
import { Command as Command48 } from "commander";
|
|
5521
5653
|
|
|
5522
5654
|
// src/commands/linter/generate.ts
|
|
5523
|
-
import { Command as
|
|
5655
|
+
import { Command as Command46 } from "commander";
|
|
5524
5656
|
function formatGenerateError(e) {
|
|
5525
5657
|
switch (e.type) {
|
|
5526
5658
|
case "parse":
|
|
@@ -5564,7 +5696,7 @@ function handleSuccess(result, useJson) {
|
|
|
5564
5696
|
Generated ${result.rulesGenerated.length} rules to ${result.outputDir}`);
|
|
5565
5697
|
}
|
|
5566
5698
|
function createGenerateCommand2() {
|
|
5567
|
-
return new
|
|
5699
|
+
return new Command46("generate").description("Generate ESLint rules from harness-linter.yml").option("-c, --config <path>", "Path to harness-linter.yml", "./harness-linter.yml").option("-o, --output <dir>", "Override output directory").option("--clean", "Remove existing files before generating").option("--dry-run", "Preview without writing files").option("--json", "Output as JSON").option("--verbose", "Show detailed output").action(async (options) => {
|
|
5568
5700
|
try {
|
|
5569
5701
|
if (options.verbose) logger.info(`Parsing config: ${options.config}`);
|
|
5570
5702
|
const result = await generate({
|
|
@@ -5586,9 +5718,9 @@ function createGenerateCommand2() {
|
|
|
5586
5718
|
}
|
|
5587
5719
|
|
|
5588
5720
|
// src/commands/linter/validate.ts
|
|
5589
|
-
import { Command as
|
|
5721
|
+
import { Command as Command47 } from "commander";
|
|
5590
5722
|
function createValidateCommand() {
|
|
5591
|
-
return new
|
|
5723
|
+
return new Command47("validate").description("Validate harness-linter.yml config").option("-c, --config <path>", "Path to harness-linter.yml", "./harness-linter.yml").option("--json", "Output as JSON").action(async (options) => {
|
|
5592
5724
|
try {
|
|
5593
5725
|
const result = await validate({ configPath: options.config });
|
|
5594
5726
|
if (options.json) {
|
|
@@ -5607,7 +5739,7 @@ function createValidateCommand() {
|
|
|
5607
5739
|
|
|
5608
5740
|
// src/commands/linter/index.ts
|
|
5609
5741
|
function createLinterCommand() {
|
|
5610
|
-
const linter = new
|
|
5742
|
+
const linter = new Command48("linter").description(
|
|
5611
5743
|
"Generate and validate ESLint rules from YAML config"
|
|
5612
5744
|
);
|
|
5613
5745
|
linter.addCommand(createGenerateCommand2());
|
|
@@ -5616,7 +5748,7 @@ function createLinterCommand() {
|
|
|
5616
5748
|
}
|
|
5617
5749
|
|
|
5618
5750
|
// src/commands/mcp.ts
|
|
5619
|
-
import { Command as
|
|
5751
|
+
import { Command as Command49 } from "commander";
|
|
5620
5752
|
var VALID_TIERS = /* @__PURE__ */ new Set(["core", "standard", "full"]);
|
|
5621
5753
|
function parseTier(value) {
|
|
5622
5754
|
const lower = value.toLowerCase();
|
|
@@ -5633,7 +5765,7 @@ function parseBudget(value) {
|
|
|
5633
5765
|
return n;
|
|
5634
5766
|
}
|
|
5635
5767
|
function createMcpCommand() {
|
|
5636
|
-
return new
|
|
5768
|
+
return new Command49("mcp").description("Start the MCP (Model Context Protocol) server on stdio").option("--tools <tools...>", "Only register the specified tools (used by Cursor integration)").option(
|
|
5637
5769
|
"--tier <core|standard|full>",
|
|
5638
5770
|
"Load a preset tool tier instead of all tools",
|
|
5639
5771
|
parseTier
|
|
@@ -5643,7 +5775,7 @@ function createMcpCommand() {
|
|
|
5643
5775
|
parseBudget
|
|
5644
5776
|
).action(async (opts) => {
|
|
5645
5777
|
const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
|
|
5646
|
-
import("./mcp-
|
|
5778
|
+
import("./mcp-QFZDPFNP.js"),
|
|
5647
5779
|
import("./tool-tiers-7QGZ3FKY.js")
|
|
5648
5780
|
]);
|
|
5649
5781
|
if (opts.tools && opts.tools.length > 0) {
|
|
@@ -5665,7 +5797,7 @@ function createMcpCommand() {
|
|
|
5665
5797
|
|
|
5666
5798
|
// src/commands/migrate.ts
|
|
5667
5799
|
init_dist();
|
|
5668
|
-
import { Command as
|
|
5800
|
+
import { Command as Command50 } from "commander";
|
|
5669
5801
|
import * as fs24 from "fs";
|
|
5670
5802
|
import * as path40 from "path";
|
|
5671
5803
|
import * as readline from "readline";
|
|
@@ -5906,7 +6038,7 @@ function updateReferences(plan) {
|
|
|
5906
6038
|
}
|
|
5907
6039
|
async function prompt(question, def = "n") {
|
|
5908
6040
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
5909
|
-
const answer = await new Promise((
|
|
6041
|
+
const answer = await new Promise((resolve39) => rl.question(question, resolve39));
|
|
5910
6042
|
rl.close();
|
|
5911
6043
|
return (answer.trim() || def).toLowerCase();
|
|
5912
6044
|
}
|
|
@@ -6067,7 +6199,7 @@ async function runMigrate(opts) {
|
|
|
6067
6199
|
});
|
|
6068
6200
|
}
|
|
6069
6201
|
function createMigrateCommand() {
|
|
6070
|
-
return new
|
|
6202
|
+
return new Command50("migrate").description("Migrate legacy harness artifact locations to current layout").option("--dry-run", "Show the migration plan without moving files", false).option("--yes", "Skip confirmation prompt", false).option(
|
|
6071
6203
|
"--skip-references",
|
|
6072
6204
|
"Do not update path references in docs/sessions after moves",
|
|
6073
6205
|
false
|
|
@@ -6089,11 +6221,11 @@ function createMigrateCommand() {
|
|
|
6089
6221
|
}
|
|
6090
6222
|
|
|
6091
6223
|
// src/commands/orchestrator.ts
|
|
6092
|
-
import { Command as
|
|
6224
|
+
import { Command as Command51 } from "commander";
|
|
6093
6225
|
import * as path41 from "path";
|
|
6094
6226
|
import { Orchestrator, WorkflowLoader, launchTUI } from "@harness-engineering/orchestrator";
|
|
6095
6227
|
function createOrchestratorCommand() {
|
|
6096
|
-
const orchestrator = new
|
|
6228
|
+
const orchestrator = new Command51("orchestrator");
|
|
6097
6229
|
orchestrator.command("run").description("Run the orchestrator daemon").option("-w, --workflow <path>", "Path to harness.orchestrator.md", "harness.orchestrator.md").option("--headless", "Run without TUI (server-only mode for use with web dashboard)").action(async (opts) => {
|
|
6098
6230
|
const workflowPath = path41.resolve(process.cwd(), opts.workflow);
|
|
6099
6231
|
const loader = new WorkflowLoader();
|
|
@@ -6128,13 +6260,13 @@ function createOrchestratorCommand() {
|
|
|
6128
6260
|
|
|
6129
6261
|
// src/commands/perf.ts
|
|
6130
6262
|
init_dist();
|
|
6131
|
-
import { Command as
|
|
6263
|
+
import { Command as Command52 } from "commander";
|
|
6132
6264
|
import * as path42 from "path";
|
|
6133
6265
|
function registerBenchCommand(perf) {
|
|
6134
6266
|
perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
|
|
6135
6267
|
const globalOpts = cmd.optsWithGlobals();
|
|
6136
6268
|
const cwd = process.cwd();
|
|
6137
|
-
const { BenchmarkRunner } = await import("./dist-
|
|
6269
|
+
const { BenchmarkRunner } = await import("./dist-6RT2AVYU.js");
|
|
6138
6270
|
const runner = new BenchmarkRunner();
|
|
6139
6271
|
const benchFiles = runner.discover(cwd, glob2);
|
|
6140
6272
|
if (benchFiles.length === 0) {
|
|
@@ -6198,7 +6330,7 @@ async function runBaselinesShow(globalOpts) {
|
|
|
6198
6330
|
}
|
|
6199
6331
|
async function runBaselinesUpdate(globalOpts) {
|
|
6200
6332
|
const cwd = process.cwd();
|
|
6201
|
-
const { BenchmarkRunner } = await import("./dist-
|
|
6333
|
+
const { BenchmarkRunner } = await import("./dist-6RT2AVYU.js");
|
|
6202
6334
|
const runner = new BenchmarkRunner();
|
|
6203
6335
|
const manager = new BaselineManager(cwd);
|
|
6204
6336
|
logger.info("Running benchmarks to update baselines...");
|
|
@@ -6239,7 +6371,7 @@ function registerReportCommand(perf) {
|
|
|
6239
6371
|
perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
|
|
6240
6372
|
const globalOpts = cmd.optsWithGlobals();
|
|
6241
6373
|
const cwd = process.cwd();
|
|
6242
|
-
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-
|
|
6374
|
+
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-6RT2AVYU.js");
|
|
6243
6375
|
const analyzer = new EntropyAnalyzer2({
|
|
6244
6376
|
rootDir: path42.resolve(cwd),
|
|
6245
6377
|
analyze: { complexity: true, coupling: true }
|
|
@@ -6300,7 +6432,7 @@ function registerCriticalPathsCommand(perf) {
|
|
|
6300
6432
|
});
|
|
6301
6433
|
}
|
|
6302
6434
|
function createPerfCommand() {
|
|
6303
|
-
const perf = new
|
|
6435
|
+
const perf = new Command52("perf").description("Performance benchmark and baseline management");
|
|
6304
6436
|
registerBenchCommand(perf);
|
|
6305
6437
|
registerBaselinesCommands(perf);
|
|
6306
6438
|
registerReportCommand(perf);
|
|
@@ -6309,10 +6441,10 @@ function createPerfCommand() {
|
|
|
6309
6441
|
}
|
|
6310
6442
|
|
|
6311
6443
|
// src/commands/persona/index.ts
|
|
6312
|
-
import { Command as
|
|
6444
|
+
import { Command as Command55 } from "commander";
|
|
6313
6445
|
|
|
6314
6446
|
// src/commands/persona/list.ts
|
|
6315
|
-
import { Command as
|
|
6447
|
+
import { Command as Command53 } from "commander";
|
|
6316
6448
|
function printPersonaList(personas) {
|
|
6317
6449
|
if (personas.length === 0) {
|
|
6318
6450
|
logger.info("No personas found.");
|
|
@@ -6326,7 +6458,7 @@ function printPersonaList(personas) {
|
|
|
6326
6458
|
}
|
|
6327
6459
|
}
|
|
6328
6460
|
function createListCommand2() {
|
|
6329
|
-
return new
|
|
6461
|
+
return new Command53("list").description("List available agent personas").action(async (_opts, cmd) => {
|
|
6330
6462
|
const globalOpts = cmd.optsWithGlobals();
|
|
6331
6463
|
const personasDir = resolvePersonasDir();
|
|
6332
6464
|
const result = listPersonas(personasDir);
|
|
@@ -6346,7 +6478,7 @@ function createListCommand2() {
|
|
|
6346
6478
|
}
|
|
6347
6479
|
|
|
6348
6480
|
// src/commands/persona/generate.ts
|
|
6349
|
-
import { Command as
|
|
6481
|
+
import { Command as Command54 } from "commander";
|
|
6350
6482
|
import * as fs25 from "fs";
|
|
6351
6483
|
import * as path43 from "path";
|
|
6352
6484
|
function generatePersonaArtifacts(persona, outputDir, only) {
|
|
@@ -6381,7 +6513,7 @@ function generatePersonaArtifacts(persona, outputDir, only) {
|
|
|
6381
6513
|
return generated;
|
|
6382
6514
|
}
|
|
6383
6515
|
function createGenerateCommand3() {
|
|
6384
|
-
return new
|
|
6516
|
+
return new Command54("generate").description("Generate artifacts from a persona config").argument("<name>", "Persona name (e.g., architecture-enforcer)").option("--output-dir <dir>", "Output directory", ".").option("--only <type>", "Generate only: ci, agents-md, runtime").action(async (name, opts, cmd) => {
|
|
6385
6517
|
const globalOpts = cmd.optsWithGlobals();
|
|
6386
6518
|
const personaResult = loadPersona(path43.join(resolvePersonasDir(), `${name}.yaml`));
|
|
6387
6519
|
if (!personaResult.ok) {
|
|
@@ -6403,7 +6535,7 @@ function createGenerateCommand3() {
|
|
|
6403
6535
|
|
|
6404
6536
|
// src/commands/persona/index.ts
|
|
6405
6537
|
function createPersonaCommand() {
|
|
6406
|
-
const command = new
|
|
6538
|
+
const command = new Command55("persona").description("Agent persona management commands");
|
|
6407
6539
|
command.addCommand(createListCommand2());
|
|
6408
6540
|
command.addCommand(createGenerateCommand3());
|
|
6409
6541
|
return command;
|
|
@@ -6411,7 +6543,7 @@ function createPersonaCommand() {
|
|
|
6411
6543
|
|
|
6412
6544
|
// src/commands/predict.ts
|
|
6413
6545
|
init_dist();
|
|
6414
|
-
import { Command as
|
|
6546
|
+
import { Command as Command56 } from "commander";
|
|
6415
6547
|
import chalk8 from "chalk";
|
|
6416
6548
|
var CATEGORY_ORDER = [
|
|
6417
6549
|
"circular-deps",
|
|
@@ -6517,7 +6649,7 @@ function handlePredictError(err, mode) {
|
|
|
6517
6649
|
process.exit(ExitCode.ERROR);
|
|
6518
6650
|
}
|
|
6519
6651
|
function createPredictCommand() {
|
|
6520
|
-
const command = new
|
|
6652
|
+
const command = new Command56("predict").description("Predict which architectural constraints will break and when").option("--category <name>", "Filter to a single metric category").option("--no-roadmap", "Baseline only \u2014 skip roadmap spec impact").option("--horizon <weeks>", "Forecast horizon in weeks (default: 12)", "12").action(async (opts, cmd) => {
|
|
6521
6653
|
const globalOpts = cmd.optsWithGlobals();
|
|
6522
6654
|
const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
|
|
6523
6655
|
try {
|
|
@@ -6542,7 +6674,7 @@ function createPredictCommand() {
|
|
|
6542
6674
|
// src/commands/publish-analyses.ts
|
|
6543
6675
|
import * as fs26 from "fs";
|
|
6544
6676
|
import * as path44 from "path";
|
|
6545
|
-
import { Command as
|
|
6677
|
+
import { Command as Command57 } from "commander";
|
|
6546
6678
|
init_dist();
|
|
6547
6679
|
import {
|
|
6548
6680
|
renderAnalysisComment,
|
|
@@ -6630,7 +6762,7 @@ async function runPublishAnalyses(opts) {
|
|
|
6630
6762
|
const nameToExternalId = buildNameToExternalIdMap(projectPath);
|
|
6631
6763
|
if (!nameToExternalId) return process.exit(1);
|
|
6632
6764
|
const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
|
|
6633
|
-
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-
|
|
6765
|
+
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-6RT2AVYU.js");
|
|
6634
6766
|
const archive = new AnalysisArchive(path44.join(projectPath, ".harness", "analyses"));
|
|
6635
6767
|
const analyses = await archive.list();
|
|
6636
6768
|
if (analyses.length === 0) {
|
|
@@ -6653,7 +6785,7 @@ async function runPublishAnalyses(opts) {
|
|
|
6653
6785
|
}
|
|
6654
6786
|
}
|
|
6655
6787
|
function createPublishAnalysesCommand() {
|
|
6656
|
-
const command = new
|
|
6788
|
+
const command = new Command57("publish-analyses").description(
|
|
6657
6789
|
"Publishes locally generated intelligence analyses to the external issue tracker (e.g., GitHub)"
|
|
6658
6790
|
).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
6659
6791
|
try {
|
|
@@ -6668,8 +6800,109 @@ function createPublishAnalysesCommand() {
|
|
|
6668
6800
|
return command;
|
|
6669
6801
|
}
|
|
6670
6802
|
|
|
6803
|
+
// src/commands/pulse/index.ts
|
|
6804
|
+
import { Command as Command59 } from "commander";
|
|
6805
|
+
|
|
6806
|
+
// src/commands/pulse/run.ts
|
|
6807
|
+
init_dist();
|
|
6808
|
+
import { readFileSync as readFileSync15, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14 } from "fs";
|
|
6809
|
+
import { dirname as dirname17, join as join33, resolve as resolve28 } from "path";
|
|
6810
|
+
import { Command as Command58 } from "commander";
|
|
6811
|
+
async function runPulseRunCommand(opts) {
|
|
6812
|
+
const startedAt = Date.now();
|
|
6813
|
+
let raw;
|
|
6814
|
+
try {
|
|
6815
|
+
raw = JSON.parse(readFileSync15(opts.configPath, "utf-8"));
|
|
6816
|
+
} catch (err) {
|
|
6817
|
+
return emit2(
|
|
6818
|
+
{
|
|
6819
|
+
status: "failure",
|
|
6820
|
+
reason: `cannot read ${opts.configPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
6821
|
+
},
|
|
6822
|
+
opts.nonInteractive
|
|
6823
|
+
);
|
|
6824
|
+
}
|
|
6825
|
+
if (!raw.pulse?.enabled) {
|
|
6826
|
+
return emit2(
|
|
6827
|
+
{ status: "skipped", reason: "pulse.enabled is false or missing" },
|
|
6828
|
+
opts.nonInteractive
|
|
6829
|
+
);
|
|
6830
|
+
}
|
|
6831
|
+
const lookback = opts.lookback ?? raw.pulse.lookbackDefault ?? "24h";
|
|
6832
|
+
const window = computeWindow(/* @__PURE__ */ new Date(), lookback);
|
|
6833
|
+
const result = await runPulse(raw.pulse, window);
|
|
6834
|
+
if (result.sourcesQueried.length === 0 && result.sourcesSkipped.length === 0) {
|
|
6835
|
+
return emit2({ status: "skipped", reason: "no sources configured" }, opts.nonInteractive);
|
|
6836
|
+
}
|
|
6837
|
+
const productName = typeof raw.name === "string" ? raw.name : "Project";
|
|
6838
|
+
const report = assembleReport(result, productName, lookback);
|
|
6839
|
+
const now = /* @__PURE__ */ new Date();
|
|
6840
|
+
const ts = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}_${String(now.getHours()).padStart(2, "0")}-${String(now.getMinutes()).padStart(2, "0")}`;
|
|
6841
|
+
const filePath = join33(opts.outputDir, `${ts}.md`);
|
|
6842
|
+
mkdirSync13(dirname17(filePath), { recursive: true });
|
|
6843
|
+
writeFileSync14(filePath, report);
|
|
6844
|
+
const headlines = extractHeadlines(report);
|
|
6845
|
+
return emit2(
|
|
6846
|
+
{
|
|
6847
|
+
status: "success",
|
|
6848
|
+
path: filePath,
|
|
6849
|
+
headlinesSummary: headlines,
|
|
6850
|
+
durationMs: Date.now() - startedAt,
|
|
6851
|
+
sourcesQueried: result.sourcesQueried,
|
|
6852
|
+
sourcesSkipped: result.sourcesSkipped
|
|
6853
|
+
},
|
|
6854
|
+
opts.nonInteractive
|
|
6855
|
+
);
|
|
6856
|
+
}
|
|
6857
|
+
function emit2(status, nonInteractive) {
|
|
6858
|
+
if (nonInteractive) {
|
|
6859
|
+
process.stdout.write(JSON.stringify(status) + "\n");
|
|
6860
|
+
} else if (status.status === "success") {
|
|
6861
|
+
process.stdout.write(`${status.headlinesSummary ?? ""}
|
|
6862
|
+
|
|
6863
|
+
\u2192 ${status.path}
|
|
6864
|
+
`);
|
|
6865
|
+
} else if (status.status === "skipped") {
|
|
6866
|
+
process.stdout.write(`pulse skipped: ${status.reason}
|
|
6867
|
+
`);
|
|
6868
|
+
} else {
|
|
6869
|
+
process.stderr.write(`pulse failed: ${status.reason}
|
|
6870
|
+
`);
|
|
6871
|
+
}
|
|
6872
|
+
return status;
|
|
6873
|
+
}
|
|
6874
|
+
function createRunCommand2() {
|
|
6875
|
+
return new Command58("run").description("Run a pulse: query configured adapters, sanitize, assemble single-page report").option(
|
|
6876
|
+
"--lookback <window>",
|
|
6877
|
+
"Lookback window (e.g. 24h, 7d). Defaults to pulse.lookbackDefault."
|
|
6878
|
+
).option(
|
|
6879
|
+
"--non-interactive",
|
|
6880
|
+
"Emit single-line JSON status on stdout instead of headlines+path. Auto-detected when stdout is not a TTY."
|
|
6881
|
+
).option("--config <path>", "Path to harness.config.json", "harness.config.json").option("--output-dir <dir>", "Directory to write the report into", "docs/pulse-reports").action(
|
|
6882
|
+
async (options) => {
|
|
6883
|
+
const nonInteractive = options.nonInteractive === true || !process.stdout.isTTY;
|
|
6884
|
+
const status = await runPulseRunCommand({
|
|
6885
|
+
configPath: resolve28(process.cwd(), options.config),
|
|
6886
|
+
outputDir: resolve28(process.cwd(), options.outputDir),
|
|
6887
|
+
nonInteractive,
|
|
6888
|
+
lookback: options.lookback
|
|
6889
|
+
});
|
|
6890
|
+
if (status.status === "failure") {
|
|
6891
|
+
process.exitCode = 1;
|
|
6892
|
+
}
|
|
6893
|
+
}
|
|
6894
|
+
);
|
|
6895
|
+
}
|
|
6896
|
+
|
|
6897
|
+
// src/commands/pulse/index.ts
|
|
6898
|
+
function createPulseCommand() {
|
|
6899
|
+
const command = new Command59("pulse").description("Pulse (read-side observability) commands");
|
|
6900
|
+
command.addCommand(createRunCommand2());
|
|
6901
|
+
return command;
|
|
6902
|
+
}
|
|
6903
|
+
|
|
6671
6904
|
// src/commands/recommend.ts
|
|
6672
|
-
import { Command as
|
|
6905
|
+
import { Command as Command60 } from "commander";
|
|
6673
6906
|
import chalk9 from "chalk";
|
|
6674
6907
|
async function resolveSnapshot(cwd, noCache) {
|
|
6675
6908
|
if (!noCache) {
|
|
@@ -6733,7 +6966,7 @@ function printRecommendations(result) {
|
|
|
6733
6966
|
console.log("");
|
|
6734
6967
|
}
|
|
6735
6968
|
function createRecommendCommand() {
|
|
6736
|
-
const command = new
|
|
6969
|
+
const command = new Command60("recommend").description("Recommend skills based on codebase health analysis").option("--no-cache", "Force fresh health snapshot").option("--top <n>", "Max recommendations (default 5)", "5").action(async (opts, cmd) => {
|
|
6737
6970
|
const globalOpts = cmd.optsWithGlobals();
|
|
6738
6971
|
const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
|
|
6739
6972
|
try {
|
|
@@ -6770,9 +7003,9 @@ function createRecommendCommand() {
|
|
|
6770
7003
|
|
|
6771
7004
|
// src/commands/scan-config.ts
|
|
6772
7005
|
init_dist();
|
|
6773
|
-
import { Command as
|
|
6774
|
-
import { existsSync as existsSync23, readFileSync as
|
|
6775
|
-
import { join as
|
|
7006
|
+
import { Command as Command61 } from "commander";
|
|
7007
|
+
import { existsSync as existsSync23, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
|
|
7008
|
+
import { join as join34, relative as relative3 } from "path";
|
|
6776
7009
|
var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".gemini/settings.json", "skill.yaml"];
|
|
6777
7010
|
function stripHighSeverityPatterns(content, injectionFindings) {
|
|
6778
7011
|
const highLines = /* @__PURE__ */ new Set();
|
|
@@ -6798,7 +7031,7 @@ function applyFix(filePath, targetDir, content, injectionFindings) {
|
|
|
6798
7031
|
if (!hasHighSeverity) return;
|
|
6799
7032
|
const { cleaned, linesStripped } = stripHighSeverityPatterns(content, injectionFindings);
|
|
6800
7033
|
if (linesStripped > 0) {
|
|
6801
|
-
|
|
7034
|
+
writeFileSync15(filePath, cleaned);
|
|
6802
7035
|
logger.info(
|
|
6803
7036
|
`scan-config --fix: stripped ${linesStripped} high-severity line(s) from ${relative3(targetDir, filePath).replaceAll("\\", "/")}`
|
|
6804
7037
|
);
|
|
@@ -6808,7 +7041,7 @@ function scanSingleFile(filePath, targetDir, scanner, options) {
|
|
|
6808
7041
|
if (!existsSync23(filePath)) return null;
|
|
6809
7042
|
let content;
|
|
6810
7043
|
try {
|
|
6811
|
-
content =
|
|
7044
|
+
content = readFileSync16(filePath, "utf8");
|
|
6812
7045
|
} catch {
|
|
6813
7046
|
return null;
|
|
6814
7047
|
}
|
|
@@ -6829,7 +7062,7 @@ async function runScanConfig(targetDir, options) {
|
|
|
6829
7062
|
const scanner = new SecurityScanner(parseSecurityConfig({}));
|
|
6830
7063
|
const results = [];
|
|
6831
7064
|
for (const configFile of CONFIG_FILES) {
|
|
6832
|
-
const result = scanSingleFile(
|
|
7065
|
+
const result = scanSingleFile(join34(targetDir, configFile), targetDir, scanner, options);
|
|
6833
7066
|
if (result) results.push(result);
|
|
6834
7067
|
}
|
|
6835
7068
|
return { exitCode: computeScanExitCode(results), results };
|
|
@@ -6859,7 +7092,7 @@ function formatTextOutput(result) {
|
|
|
6859
7092
|
}
|
|
6860
7093
|
}
|
|
6861
7094
|
function createScanConfigCommand() {
|
|
6862
|
-
const command = new
|
|
7095
|
+
const command = new Command61("scan-config").description(
|
|
6863
7096
|
"Scan CLAUDE.md, AGENTS.md, .gemini/settings.json, and skill.yaml for prompt injection patterns"
|
|
6864
7097
|
).option("--path <dir>", "Target directory to scan (default: cwd)").option("--fix", "Strip high-severity patterns from files in-place").action(async (opts, cmd) => {
|
|
6865
7098
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -6876,7 +7109,7 @@ function createScanConfigCommand() {
|
|
|
6876
7109
|
}
|
|
6877
7110
|
|
|
6878
7111
|
// src/commands/setup.ts
|
|
6879
|
-
import { Command as
|
|
7112
|
+
import { Command as Command62 } from "commander";
|
|
6880
7113
|
import * as fs29 from "fs";
|
|
6881
7114
|
import * as os7 from "os";
|
|
6882
7115
|
import * as path47 from "path";
|
|
@@ -6915,10 +7148,10 @@ function prompt2(question) {
|
|
|
6915
7148
|
input: process.stdin,
|
|
6916
7149
|
output: process.stdout
|
|
6917
7150
|
});
|
|
6918
|
-
return new Promise((
|
|
7151
|
+
return new Promise((resolve39) => {
|
|
6919
7152
|
rl.question(question, (answer) => {
|
|
6920
7153
|
rl.close();
|
|
6921
|
-
|
|
7154
|
+
resolve39(answer.trim().toLowerCase());
|
|
6922
7155
|
});
|
|
6923
7156
|
});
|
|
6924
7157
|
}
|
|
@@ -6927,10 +7160,10 @@ function promptRaw(question) {
|
|
|
6927
7160
|
input: process.stdin,
|
|
6928
7161
|
output: process.stdout
|
|
6929
7162
|
});
|
|
6930
|
-
return new Promise((
|
|
7163
|
+
return new Promise((resolve39) => {
|
|
6931
7164
|
rl.question(question, (answer) => {
|
|
6932
7165
|
rl.close();
|
|
6933
|
-
|
|
7166
|
+
resolve39(answer.trim());
|
|
6934
7167
|
});
|
|
6935
7168
|
});
|
|
6936
7169
|
}
|
|
@@ -7169,7 +7402,7 @@ async function detectLegacyLayout(cwd) {
|
|
|
7169
7402
|
}
|
|
7170
7403
|
async function runInitialGraphScan(cwd) {
|
|
7171
7404
|
try {
|
|
7172
|
-
const { runScan: runScan2 } = await import("./scan-
|
|
7405
|
+
const { runScan: runScan2 } = await import("./scan-BIJYHOE7.js");
|
|
7173
7406
|
const result = await runScan2(cwd);
|
|
7174
7407
|
return {
|
|
7175
7408
|
status: "pass",
|
|
@@ -7208,7 +7441,7 @@ async function runSetup(cwd) {
|
|
|
7208
7441
|
return { steps, success };
|
|
7209
7442
|
}
|
|
7210
7443
|
function createSetupCommand() {
|
|
7211
|
-
return new
|
|
7444
|
+
return new Command62("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
|
|
7212
7445
|
const cwd = process.cwd();
|
|
7213
7446
|
console.log("");
|
|
7214
7447
|
console.log(` ${chalk11.bold("harness setup")}`);
|
|
@@ -7231,7 +7464,7 @@ function createSetupCommand() {
|
|
|
7231
7464
|
|
|
7232
7465
|
// src/commands/share.ts
|
|
7233
7466
|
init_dist();
|
|
7234
|
-
import { Command as
|
|
7467
|
+
import { Command as Command63 } from "commander";
|
|
7235
7468
|
import * as fs30 from "fs";
|
|
7236
7469
|
import * as path48 from "path";
|
|
7237
7470
|
import { parse as parseYaml } from "yaml";
|
|
@@ -7290,16 +7523,16 @@ Create a constraints.yaml in your project root to define what to share.`
|
|
|
7290
7523
|
logger.success(`Bundle written to ${outputPath}`);
|
|
7291
7524
|
}
|
|
7292
7525
|
function createShareCommand() {
|
|
7293
|
-
return new
|
|
7526
|
+
return new Command63("share").description("Extract and publish a constraints bundle from constraints.yaml").argument("[path]", "Path to the project root", ".").option("-o, --output <dir>", "Output directory for the bundle", ".").action(async (projectPath, options) => {
|
|
7294
7527
|
await runShareAction(projectPath, options);
|
|
7295
7528
|
});
|
|
7296
7529
|
}
|
|
7297
7530
|
|
|
7298
7531
|
// src/commands/skill/index.ts
|
|
7299
|
-
import { Command as
|
|
7532
|
+
import { Command as Command71 } from "commander";
|
|
7300
7533
|
|
|
7301
7534
|
// src/commands/skill/list.ts
|
|
7302
|
-
import { Command as
|
|
7535
|
+
import { Command as Command64 } from "commander";
|
|
7303
7536
|
import * as fs31 from "fs";
|
|
7304
7537
|
import * as path49 from "path";
|
|
7305
7538
|
import { parse } from "yaml";
|
|
@@ -7402,7 +7635,7 @@ function printSkillsVerbose(skills) {
|
|
|
7402
7635
|
for (const s of skills) printSkillEntry(s);
|
|
7403
7636
|
}
|
|
7404
7637
|
function createListCommand3() {
|
|
7405
|
-
return new
|
|
7638
|
+
return new Command64("list").description("List available skills").option("--installed", "Show only community-installed skills").option("--local", "Show only project-local skills").option("--all", "Show all skills (default)").action(async (opts, cmd) => {
|
|
7406
7639
|
const globalOpts = cmd.optsWithGlobals();
|
|
7407
7640
|
const skills = collectSkills({ filter: resolveFilter(opts) });
|
|
7408
7641
|
if (globalOpts.json) {
|
|
@@ -7417,7 +7650,7 @@ function createListCommand3() {
|
|
|
7417
7650
|
}
|
|
7418
7651
|
|
|
7419
7652
|
// src/commands/skill/run.ts
|
|
7420
|
-
import { Command as
|
|
7653
|
+
import { Command as Command65 } from "commander";
|
|
7421
7654
|
import * as fs32 from "fs";
|
|
7422
7655
|
import * as path50 from "path";
|
|
7423
7656
|
import { parse as parse2 } from "yaml";
|
|
@@ -7628,12 +7861,12 @@ async function runSkill(name, opts) {
|
|
|
7628
7861
|
process.stdout.write(preamble + content);
|
|
7629
7862
|
process.exit(ExitCode.SUCCESS);
|
|
7630
7863
|
}
|
|
7631
|
-
function
|
|
7632
|
-
return new
|
|
7864
|
+
function createRunCommand3() {
|
|
7865
|
+
return new Command65("run").description("Run a skill (outputs SKILL.md content with context preamble)").argument("<name>", "Skill name (e.g., harness-tdd)").option("--path <path>", "Project root path for context injection").option("--complexity <level>", "Rigor level: fast, standard, thorough", "standard").option("--phase <name>", "Start at a specific phase (for re-entry)").option("--party", "Enable multi-perspective evaluation").action(async (name, opts) => runSkill(name, opts));
|
|
7633
7866
|
}
|
|
7634
7867
|
|
|
7635
7868
|
// src/commands/skill/validate.ts
|
|
7636
|
-
import { Command as
|
|
7869
|
+
import { Command as Command66 } from "commander";
|
|
7637
7870
|
import * as fs33 from "fs";
|
|
7638
7871
|
import * as path51 from "path";
|
|
7639
7872
|
import { parse as parse3 } from "yaml";
|
|
@@ -7697,7 +7930,7 @@ function validateSkillEntry(name, skillsDir, errors) {
|
|
|
7697
7930
|
}
|
|
7698
7931
|
}
|
|
7699
7932
|
function createValidateCommand2() {
|
|
7700
|
-
return new
|
|
7933
|
+
return new Command66("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
|
|
7701
7934
|
const globalOpts = cmd.optsWithGlobals();
|
|
7702
7935
|
const skillsDir = resolveSkillsDir();
|
|
7703
7936
|
if (!fs33.existsSync(skillsDir)) {
|
|
@@ -7727,7 +7960,7 @@ function createValidateCommand2() {
|
|
|
7727
7960
|
}
|
|
7728
7961
|
|
|
7729
7962
|
// src/commands/skill/info.ts
|
|
7730
|
-
import { Command as
|
|
7963
|
+
import { Command as Command67 } from "commander";
|
|
7731
7964
|
import * as fs34 from "fs";
|
|
7732
7965
|
import * as path52 from "path";
|
|
7733
7966
|
import { parse as parse4 } from "yaml";
|
|
@@ -7773,7 +8006,7 @@ function printSkillInfo(skill) {
|
|
|
7773
8006
|
console.log(`Persistent: ${skill.state.persistent}`);
|
|
7774
8007
|
}
|
|
7775
8008
|
function createInfoCommand() {
|
|
7776
|
-
return new
|
|
8009
|
+
return new Command67("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
|
|
7777
8010
|
const globalOpts = cmd.optsWithGlobals();
|
|
7778
8011
|
const loaded = loadSkillMetadata2(name);
|
|
7779
8012
|
if (!loaded.ok) {
|
|
@@ -7790,7 +8023,7 @@ function createInfoCommand() {
|
|
|
7790
8023
|
}
|
|
7791
8024
|
|
|
7792
8025
|
// src/commands/skill/search.ts
|
|
7793
|
-
import { Command as
|
|
8026
|
+
import { Command as Command68 } from "commander";
|
|
7794
8027
|
async function runSearch(query, opts) {
|
|
7795
8028
|
const results = await searchNpmRegistry(query, opts.registry);
|
|
7796
8029
|
return results.filter((r) => {
|
|
@@ -7835,13 +8068,13 @@ async function runSearchAction(query, opts, globalOpts) {
|
|
|
7835
8068
|
}
|
|
7836
8069
|
}
|
|
7837
8070
|
function createSearchCommand() {
|
|
7838
|
-
return new
|
|
8071
|
+
return new Command68("search").description("Search for community skills on the @harness-skills registry").argument("<query>", "Search query").option("--platform <platform>", "Filter by platform (e.g., claude-code)").option("--trigger <trigger>", "Filter by trigger type (e.g., manual, automatic)").option("--registry <url>", "Use a custom npm registry URL").action(async (query, opts, cmd) => {
|
|
7839
8072
|
await runSearchAction(query, opts, cmd.optsWithGlobals());
|
|
7840
8073
|
});
|
|
7841
8074
|
}
|
|
7842
8075
|
|
|
7843
8076
|
// src/commands/skill/create.ts
|
|
7844
|
-
import { Command as
|
|
8077
|
+
import { Command as Command69 } from "commander";
|
|
7845
8078
|
import * as path53 from "path";
|
|
7846
8079
|
import * as fs35 from "fs";
|
|
7847
8080
|
import YAML from "yaml";
|
|
@@ -7961,7 +8194,7 @@ Next steps:`);
|
|
|
7961
8194
|
logger.info(` 3. Run: harness skills publish`);
|
|
7962
8195
|
}
|
|
7963
8196
|
function createCreateCommand() {
|
|
7964
|
-
return new
|
|
8197
|
+
return new Command69("create").description("Scaffold a new community skill").argument("<name>", "Skill name (kebab-case)").option("--description <desc>", "Skill description").option("--type <type>", "Skill type: rigid or flexible", "flexible").option("--platforms <platforms>", "Comma-separated platforms (default: claude-code)").option("--triggers <triggers>", "Comma-separated triggers (default: manual)").option("--output-dir <dir>", "Output directory (default: agents/skills/claude-code/)").action(async (name, opts, cmd) => {
|
|
7965
8198
|
const globalOpts = cmd.optsWithGlobals();
|
|
7966
8199
|
try {
|
|
7967
8200
|
const result = runCreate(name, {
|
|
@@ -7984,7 +8217,7 @@ function createCreateCommand() {
|
|
|
7984
8217
|
}
|
|
7985
8218
|
|
|
7986
8219
|
// src/commands/skill/publish.ts
|
|
7987
|
-
import { Command as
|
|
8220
|
+
import { Command as Command70 } from "commander";
|
|
7988
8221
|
import * as fs37 from "fs";
|
|
7989
8222
|
import * as path55 from "path";
|
|
7990
8223
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
@@ -8153,7 +8386,7 @@ ${skillMdContent}`;
|
|
|
8153
8386
|
};
|
|
8154
8387
|
}
|
|
8155
8388
|
function createPublishCommand() {
|
|
8156
|
-
return new
|
|
8389
|
+
return new Command70("publish").description("Validate and publish a skill to @harness-skills on npm").option("--dry-run", "Run validation and generate package.json without publishing").option("--dir <dir>", "Skill directory (default: current directory)").option("--registry <url>", "Use a custom npm registry URL").action(async (opts, cmd) => {
|
|
8157
8390
|
const globalOpts = cmd.optsWithGlobals();
|
|
8158
8391
|
const skillDir = opts.dir || process.cwd();
|
|
8159
8392
|
try {
|
|
@@ -8178,9 +8411,9 @@ function createPublishCommand() {
|
|
|
8178
8411
|
|
|
8179
8412
|
// src/commands/skill/index.ts
|
|
8180
8413
|
function createSkillCommand() {
|
|
8181
|
-
const command = new
|
|
8414
|
+
const command = new Command71("skill").description("Skill management commands");
|
|
8182
8415
|
command.addCommand(createListCommand3());
|
|
8183
|
-
command.addCommand(
|
|
8416
|
+
command.addCommand(createRunCommand3());
|
|
8184
8417
|
command.addCommand(createValidateCommand2());
|
|
8185
8418
|
command.addCommand(createInfoCommand());
|
|
8186
8419
|
command.addCommand(createSearchCommand());
|
|
@@ -8191,7 +8424,7 @@ function createSkillCommand() {
|
|
|
8191
8424
|
|
|
8192
8425
|
// src/commands/snapshot.ts
|
|
8193
8426
|
init_dist();
|
|
8194
|
-
import { Command as
|
|
8427
|
+
import { Command as Command72 } from "commander";
|
|
8195
8428
|
import { execSync as execSync5 } from "child_process";
|
|
8196
8429
|
import chalk12 from "chalk";
|
|
8197
8430
|
function getCommitHash3(cwd) {
|
|
@@ -8373,7 +8606,7 @@ function registerListCommand(parent) {
|
|
|
8373
8606
|
});
|
|
8374
8607
|
}
|
|
8375
8608
|
function createSnapshotCommand() {
|
|
8376
|
-
const command = new
|
|
8609
|
+
const command = new Command72("snapshot").description("Architecture timeline snapshot commands");
|
|
8377
8610
|
registerCaptureCommand(command);
|
|
8378
8611
|
registerTrendsCommand(command);
|
|
8379
8612
|
registerListCommand(command);
|
|
@@ -8381,11 +8614,11 @@ function createSnapshotCommand() {
|
|
|
8381
8614
|
}
|
|
8382
8615
|
|
|
8383
8616
|
// src/commands/state/index.ts
|
|
8384
|
-
import { Command as
|
|
8617
|
+
import { Command as Command77 } from "commander";
|
|
8385
8618
|
|
|
8386
8619
|
// src/commands/state/show.ts
|
|
8387
8620
|
init_dist();
|
|
8388
|
-
import { Command as
|
|
8621
|
+
import { Command as Command73 } from "commander";
|
|
8389
8622
|
import * as path56 from "path";
|
|
8390
8623
|
function printStateText(state, stream) {
|
|
8391
8624
|
if (stream) console.log(`Stream: ${stream}`);
|
|
@@ -8410,7 +8643,7 @@ function printStateProgress(progress) {
|
|
|
8410
8643
|
}
|
|
8411
8644
|
}
|
|
8412
8645
|
function createShowCommand() {
|
|
8413
|
-
return new
|
|
8646
|
+
return new Command73("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
|
|
8414
8647
|
const globalOpts = cmd.optsWithGlobals();
|
|
8415
8648
|
const result = await loadState(path56.resolve(opts.path), opts.stream);
|
|
8416
8649
|
if (!result.ok) {
|
|
@@ -8428,7 +8661,7 @@ function createShowCommand() {
|
|
|
8428
8661
|
|
|
8429
8662
|
// src/commands/state/reset.ts
|
|
8430
8663
|
init_dist();
|
|
8431
|
-
import { Command as
|
|
8664
|
+
import { Command as Command74 } from "commander";
|
|
8432
8665
|
import * as fs38 from "fs";
|
|
8433
8666
|
import * as path57 from "path";
|
|
8434
8667
|
import * as readline3 from "readline";
|
|
@@ -8445,8 +8678,8 @@ async function resolveStatePath(projectPath, stream) {
|
|
|
8445
8678
|
}
|
|
8446
8679
|
async function confirmReset() {
|
|
8447
8680
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
8448
|
-
const answer = await new Promise((
|
|
8449
|
-
rl.question("Reset project state? This cannot be undone. [y/N] ",
|
|
8681
|
+
const answer = await new Promise((resolve39) => {
|
|
8682
|
+
rl.question("Reset project state? This cannot be undone. [y/N] ", resolve39);
|
|
8450
8683
|
});
|
|
8451
8684
|
rl.close();
|
|
8452
8685
|
return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
@@ -8472,15 +8705,15 @@ async function runReset(opts) {
|
|
|
8472
8705
|
process.exit(ExitCode.SUCCESS);
|
|
8473
8706
|
}
|
|
8474
8707
|
function createResetCommand() {
|
|
8475
|
-
return new
|
|
8708
|
+
return new Command74("reset").description("Reset project state (deletes .harness/state.json)").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").option("--yes", "Skip confirmation prompt").action(async (opts) => runReset(opts));
|
|
8476
8709
|
}
|
|
8477
8710
|
|
|
8478
8711
|
// src/commands/state/learn.ts
|
|
8479
8712
|
init_dist();
|
|
8480
|
-
import { Command as
|
|
8713
|
+
import { Command as Command75 } from "commander";
|
|
8481
8714
|
import * as path58 from "path";
|
|
8482
8715
|
function createLearnCommand() {
|
|
8483
|
-
return new
|
|
8716
|
+
return new Command75("learn").description("Append a learning to .harness/learnings.md").argument("<message>", "The learning to record").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (message, opts, _cmd) => {
|
|
8484
8717
|
const projectPath = path58.resolve(opts.path);
|
|
8485
8718
|
const result = await appendLearning(projectPath, message, void 0, void 0, opts.stream);
|
|
8486
8719
|
if (!result.ok) {
|
|
@@ -8495,7 +8728,7 @@ function createLearnCommand() {
|
|
|
8495
8728
|
|
|
8496
8729
|
// src/commands/state/streams.ts
|
|
8497
8730
|
init_dist();
|
|
8498
|
-
import { Command as
|
|
8731
|
+
import { Command as Command76 } from "commander";
|
|
8499
8732
|
import * as path59 from "path";
|
|
8500
8733
|
async function runListStreams(opts, globalOpts) {
|
|
8501
8734
|
const projectPath = path59.resolve(opts.path);
|
|
@@ -8546,7 +8779,7 @@ async function runActivateStream(name, opts) {
|
|
|
8546
8779
|
process.exit(ExitCode.SUCCESS);
|
|
8547
8780
|
}
|
|
8548
8781
|
function createStreamsCommand() {
|
|
8549
|
-
const command = new
|
|
8782
|
+
const command = new Command76("streams").description("Manage state streams");
|
|
8550
8783
|
command.command("list").description("List all known streams").option("--path <path>", "Project root path", ".").action(async (opts, cmd) => runListStreams(opts, cmd.optsWithGlobals()));
|
|
8551
8784
|
command.command("create <name>").description("Create a new stream").option("--path <path>", "Project root path", ".").option("--branch <branch>", "Associate with a git branch").action(async (name, opts) => runCreateStream(name, opts));
|
|
8552
8785
|
command.command("archive <name>").description("Archive a stream").option("--path <path>", "Project root path", ".").action(async (name, opts) => runArchiveStream(name, opts));
|
|
@@ -8556,7 +8789,7 @@ function createStreamsCommand() {
|
|
|
8556
8789
|
|
|
8557
8790
|
// src/commands/state/index.ts
|
|
8558
8791
|
function createStateCommand() {
|
|
8559
|
-
const command = new
|
|
8792
|
+
const command = new Command77("state").description("Project state management commands");
|
|
8560
8793
|
command.addCommand(createShowCommand());
|
|
8561
8794
|
command.addCommand(createResetCommand());
|
|
8562
8795
|
command.addCommand(createLearnCommand());
|
|
@@ -8567,7 +8800,7 @@ function createStateCommand() {
|
|
|
8567
8800
|
// src/commands/sync-analyses.ts
|
|
8568
8801
|
import * as fs39 from "fs";
|
|
8569
8802
|
import * as path60 from "path";
|
|
8570
|
-
import { Command as
|
|
8803
|
+
import { Command as Command78 } from "commander";
|
|
8571
8804
|
init_dist();
|
|
8572
8805
|
function isValidRecord(record) {
|
|
8573
8806
|
return typeof record.issueId === "string" && !!record.issueId && typeof record.identifier === "string" && !!record.identifier && typeof record.analyzedAt === "string" && !/[/\\]/.test(record.issueId);
|
|
@@ -8674,7 +8907,7 @@ async function runSyncAnalyses(opts) {
|
|
|
8674
8907
|
return;
|
|
8675
8908
|
}
|
|
8676
8909
|
const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
|
|
8677
|
-
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-
|
|
8910
|
+
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-6RT2AVYU.js");
|
|
8678
8911
|
const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
|
|
8679
8912
|
const archive = new AnalysisArchive(path60.join(projectPath, ".harness", "analyses"));
|
|
8680
8913
|
const publishedIndex = loadPublishedIndex2(projectPath);
|
|
@@ -8696,7 +8929,7 @@ async function runSyncAnalyses(opts) {
|
|
|
8696
8929
|
}
|
|
8697
8930
|
}
|
|
8698
8931
|
function createSyncAnalysesCommand() {
|
|
8699
|
-
const command = new
|
|
8932
|
+
const command = new Command78("sync-analyses").description(
|
|
8700
8933
|
"Pull published intelligence analyses from the external issue tracker into the local .harness/analyses/ directory"
|
|
8701
8934
|
).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
8702
8935
|
try {
|
|
@@ -8711,7 +8944,7 @@ function createSyncAnalysesCommand() {
|
|
|
8711
8944
|
|
|
8712
8945
|
// src/commands/taint.ts
|
|
8713
8946
|
init_dist();
|
|
8714
|
-
import { Command as
|
|
8947
|
+
import { Command as Command79 } from "commander";
|
|
8715
8948
|
function getProjectRoot() {
|
|
8716
8949
|
return process.cwd();
|
|
8717
8950
|
}
|
|
@@ -8783,18 +9016,18 @@ function registerStatusCommand(taint) {
|
|
|
8783
9016
|
});
|
|
8784
9017
|
}
|
|
8785
9018
|
function createTaintCommand() {
|
|
8786
|
-
const taint = new
|
|
9019
|
+
const taint = new Command79("taint").description("Manage sentinel session taint state");
|
|
8787
9020
|
registerClearCommand(taint);
|
|
8788
9021
|
registerStatusCommand(taint);
|
|
8789
9022
|
return taint;
|
|
8790
9023
|
}
|
|
8791
9024
|
|
|
8792
9025
|
// src/commands/telemetry/index.ts
|
|
8793
|
-
import { Command as
|
|
9026
|
+
import { Command as Command83 } from "commander";
|
|
8794
9027
|
|
|
8795
9028
|
// src/commands/telemetry/identify.ts
|
|
8796
9029
|
init_dist();
|
|
8797
|
-
import { Command as
|
|
9030
|
+
import { Command as Command80 } from "commander";
|
|
8798
9031
|
import * as fs40 from "fs";
|
|
8799
9032
|
import * as path61 from "path";
|
|
8800
9033
|
function telemetryFilePath(cwd) {
|
|
@@ -8818,7 +9051,7 @@ function printIdentity(identity) {
|
|
|
8818
9051
|
}
|
|
8819
9052
|
}
|
|
8820
9053
|
function createIdentifyCommand() {
|
|
8821
|
-
const cmd = new
|
|
9054
|
+
const cmd = new Command80("identify").description("Set or clear telemetry identity fields in .harness/telemetry.json").option("--project <name>", "Project name").option("--team <name>", "Team name").option("--alias <name>", "User alias").option("--clear", "Remove all identity fields").action((opts) => {
|
|
8822
9055
|
const cwd = process.cwd();
|
|
8823
9056
|
if (opts.clear) {
|
|
8824
9057
|
writeTelemetryFile(cwd, { identity: {} });
|
|
@@ -8843,7 +9076,7 @@ function createIdentifyCommand() {
|
|
|
8843
9076
|
|
|
8844
9077
|
// src/commands/telemetry/status.ts
|
|
8845
9078
|
init_dist();
|
|
8846
|
-
import { Command as
|
|
9079
|
+
import { Command as Command81 } from "commander";
|
|
8847
9080
|
function gatherEnvOverrides() {
|
|
8848
9081
|
const overrides = {};
|
|
8849
9082
|
if (process.env.DO_NOT_TRACK) overrides.DO_NOT_TRACK = process.env.DO_NOT_TRACK;
|
|
@@ -8885,7 +9118,7 @@ function printHumanStatus(result) {
|
|
|
8885
9118
|
printEnvOverrides(result.envOverrides);
|
|
8886
9119
|
}
|
|
8887
9120
|
function createStatusCommand() {
|
|
8888
|
-
const cmd = new
|
|
9121
|
+
const cmd = new Command81("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
|
|
8889
9122
|
const cwd = process.cwd();
|
|
8890
9123
|
const envOverrides = gatherEnvOverrides();
|
|
8891
9124
|
const consent = resolveConsent(cwd, void 0);
|
|
@@ -8918,20 +9151,20 @@ function createStatusCommand() {
|
|
|
8918
9151
|
|
|
8919
9152
|
// src/commands/telemetry/test.ts
|
|
8920
9153
|
init_dist();
|
|
8921
|
-
import { Command as
|
|
9154
|
+
import { Command as Command82 } from "commander";
|
|
8922
9155
|
|
|
8923
9156
|
// src/bin/command-telemetry.ts
|
|
8924
|
-
import { existsSync as existsSync37, readFileSync as
|
|
8925
|
-
import { join as
|
|
9157
|
+
import { existsSync as existsSync37, readFileSync as readFileSync27, mkdirSync as mkdirSync18, appendFileSync, writeFileSync as writeFileSync21 } from "fs";
|
|
9158
|
+
import { join as join49, parse as parsePath, resolve as resolve36 } from "path";
|
|
8926
9159
|
import { spawn as spawn2 } from "child_process";
|
|
8927
9160
|
var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
|
|
8928
9161
|
var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
|
|
8929
9162
|
function findProjectRoot(cwd) {
|
|
8930
|
-
let dir =
|
|
9163
|
+
let dir = resolve36(cwd);
|
|
8931
9164
|
const { root } = parsePath(dir);
|
|
8932
9165
|
while (dir !== root) {
|
|
8933
|
-
if (existsSync37(
|
|
8934
|
-
dir =
|
|
9166
|
+
if (existsSync37(join49(dir, "harness.config.json"))) return dir;
|
|
9167
|
+
dir = resolve36(dir, "..");
|
|
8935
9168
|
}
|
|
8936
9169
|
return cwd;
|
|
8937
9170
|
}
|
|
@@ -8968,8 +9201,8 @@ function resolveCommandName(cmd) {
|
|
|
8968
9201
|
}
|
|
8969
9202
|
function writeCommandRecordSync(cwd, command, duration, outcome) {
|
|
8970
9203
|
try {
|
|
8971
|
-
const metricsDir =
|
|
8972
|
-
|
|
9204
|
+
const metricsDir = join49(cwd, ".harness", "metrics");
|
|
9205
|
+
mkdirSync18(metricsDir, { recursive: true });
|
|
8973
9206
|
const record = {
|
|
8974
9207
|
skill: command,
|
|
8975
9208
|
session: `cli-${Date.now()}`,
|
|
@@ -8978,16 +9211,16 @@ function writeCommandRecordSync(cwd, command, duration, outcome) {
|
|
|
8978
9211
|
outcome,
|
|
8979
9212
|
phasesReached: []
|
|
8980
9213
|
};
|
|
8981
|
-
const adoptionFile =
|
|
9214
|
+
const adoptionFile = join49(metricsDir, "adoption.jsonl");
|
|
8982
9215
|
appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
|
|
8983
9216
|
} catch {
|
|
8984
9217
|
}
|
|
8985
9218
|
}
|
|
8986
9219
|
function isTelemetryDisabledByConfig(cwd) {
|
|
8987
|
-
const configPath =
|
|
9220
|
+
const configPath = join49(cwd, "harness.config.json");
|
|
8988
9221
|
if (!existsSync37(configPath)) return false;
|
|
8989
9222
|
try {
|
|
8990
|
-
const config = JSON.parse(
|
|
9223
|
+
const config = JSON.parse(readFileSync27(configPath, "utf-8"));
|
|
8991
9224
|
return config?.telemetry?.enabled === false;
|
|
8992
9225
|
} catch {
|
|
8993
9226
|
return false;
|
|
@@ -8999,10 +9232,10 @@ function isTelemetryOptedOut(cwd) {
|
|
|
8999
9232
|
}
|
|
9000
9233
|
function flushTelemetryBackground(cwd) {
|
|
9001
9234
|
try {
|
|
9002
|
-
const adoptionFile =
|
|
9235
|
+
const adoptionFile = join49(cwd, ".harness", "metrics", "adoption.jsonl");
|
|
9003
9236
|
if (!existsSync37(adoptionFile)) return;
|
|
9004
9237
|
if (isTelemetryOptedOut(cwd)) return;
|
|
9005
|
-
const reporterPath =
|
|
9238
|
+
const reporterPath = join49(cwd, ".harness", "hooks", "telemetry-reporter.js");
|
|
9006
9239
|
if (!existsSync37(reporterPath)) return;
|
|
9007
9240
|
const child = spawn2(process.execPath, [reporterPath], {
|
|
9008
9241
|
cwd,
|
|
@@ -9040,7 +9273,7 @@ function reportTestSuccess(status, distinctId, identity) {
|
|
|
9040
9273
|
if (identity.team) logger.info(` team: ${identity.team}`);
|
|
9041
9274
|
}
|
|
9042
9275
|
function createTestCommand() {
|
|
9043
|
-
return new
|
|
9276
|
+
return new Command82("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
|
|
9044
9277
|
const cwd = process.cwd();
|
|
9045
9278
|
const consent = resolveConsent(cwd, void 0);
|
|
9046
9279
|
if (!consent.allowed) {
|
|
@@ -9077,7 +9310,7 @@ function createTestCommand() {
|
|
|
9077
9310
|
|
|
9078
9311
|
// src/commands/telemetry/index.ts
|
|
9079
9312
|
function createTelemetryCommand() {
|
|
9080
|
-
const command = new
|
|
9313
|
+
const command = new Command83("telemetry").description("Telemetry identity and status management");
|
|
9081
9314
|
command.addCommand(createIdentifyCommand());
|
|
9082
9315
|
command.addCommand(createStatusCommand());
|
|
9083
9316
|
command.addCommand(createTestCommand());
|
|
@@ -9085,7 +9318,7 @@ function createTelemetryCommand() {
|
|
|
9085
9318
|
}
|
|
9086
9319
|
|
|
9087
9320
|
// src/commands/traceability.ts
|
|
9088
|
-
import { Command as
|
|
9321
|
+
import { Command as Command84 } from "commander";
|
|
9089
9322
|
import chalk13 from "chalk";
|
|
9090
9323
|
function confidenceLabel(maxConfidence) {
|
|
9091
9324
|
if (maxConfidence >= 0.8) return "explicit";
|
|
@@ -9206,7 +9439,7 @@ async function runTraceability(options) {
|
|
|
9206
9439
|
const projectPath = process.cwd();
|
|
9207
9440
|
const store = await loadGraphStore(projectPath);
|
|
9208
9441
|
if (!store) handleNoStore(mode);
|
|
9209
|
-
const graphModule = await import("./dist-
|
|
9442
|
+
const graphModule = await import("./dist-D27LJR2T.js");
|
|
9210
9443
|
const filterOptions = buildFilterOptions(options);
|
|
9211
9444
|
const results = graphModule.queryTraceability(store, filterOptions);
|
|
9212
9445
|
if (results.length === 0) handleEmptyResults(mode);
|
|
@@ -9221,7 +9454,7 @@ async function runTraceability(options) {
|
|
|
9221
9454
|
process.exit(ExitCode.SUCCESS);
|
|
9222
9455
|
}
|
|
9223
9456
|
function createTraceabilityCommand() {
|
|
9224
|
-
return new
|
|
9457
|
+
return new Command84("traceability").description("Show spec-to-implementation traceability from the knowledge graph").option("--spec <path>", "Filter by spec file path").option("--feature <name>", "Filter by feature name").action(async (opts, cmd) => {
|
|
9225
9458
|
const globalOpts = cmd.optsWithGlobals();
|
|
9226
9459
|
await runTraceability({
|
|
9227
9460
|
spec: opts.spec,
|
|
@@ -9235,7 +9468,7 @@ function createTraceabilityCommand() {
|
|
|
9235
9468
|
|
|
9236
9469
|
// src/commands/uninstall.ts
|
|
9237
9470
|
import * as path62 from "path";
|
|
9238
|
-
import { Command as
|
|
9471
|
+
import { Command as Command85 } from "commander";
|
|
9239
9472
|
async function runUninstall(skillName, options) {
|
|
9240
9473
|
const packageName = resolvePackageName(skillName);
|
|
9241
9474
|
const shortName = extractSkillName(packageName);
|
|
@@ -9272,7 +9505,7 @@ async function runUninstall(skillName, options) {
|
|
|
9272
9505
|
return result;
|
|
9273
9506
|
}
|
|
9274
9507
|
function createUninstallCommand() {
|
|
9275
|
-
const cmd = new
|
|
9508
|
+
const cmd = new Command85("uninstall");
|
|
9276
9509
|
cmd.description("Uninstall a community skill").argument("<skill>", "Skill name or @harness-skills/scoped package name").option("--force", "Remove even if other skills depend on this one").action(async (skill, opts) => {
|
|
9277
9510
|
try {
|
|
9278
9511
|
const result = await runUninstall(skill, opts);
|
|
@@ -9294,7 +9527,7 @@ function createUninstallCommand() {
|
|
|
9294
9527
|
init_dist();
|
|
9295
9528
|
import * as fs41 from "fs/promises";
|
|
9296
9529
|
import * as path63 from "path";
|
|
9297
|
-
import { Command as
|
|
9530
|
+
import { Command as Command86 } from "commander";
|
|
9298
9531
|
async function runUninstallConstraints(options) {
|
|
9299
9532
|
const { packageName, configPath, lockfilePath } = options;
|
|
9300
9533
|
const lockfileResult = await readLockfile(lockfilePath);
|
|
@@ -9351,7 +9584,7 @@ async function runUninstallConstraints(options) {
|
|
|
9351
9584
|
};
|
|
9352
9585
|
}
|
|
9353
9586
|
function createUninstallConstraintsCommand() {
|
|
9354
|
-
const cmd = new
|
|
9587
|
+
const cmd = new Command86("uninstall-constraints");
|
|
9355
9588
|
cmd.description("Remove a previously installed constraints package").argument("<name>", "Name of the constraint package to uninstall").option("-c, --config <path>", "Path to harness.config.json").action(async (name, opts) => {
|
|
9356
9589
|
let configPath;
|
|
9357
9590
|
if (opts.config) {
|
|
@@ -9390,10 +9623,10 @@ function createUninstallConstraintsCommand() {
|
|
|
9390
9623
|
}
|
|
9391
9624
|
|
|
9392
9625
|
// src/commands/update.ts
|
|
9393
|
-
import { Command as
|
|
9626
|
+
import { Command as Command87 } from "commander";
|
|
9394
9627
|
import { execFile, execFileSync as execFileSync7 } from "child_process";
|
|
9395
|
-
import { realpathSync, existsSync as existsSync38, readFileSync as
|
|
9396
|
-
import { join as
|
|
9628
|
+
import { realpathSync, existsSync as existsSync38, readFileSync as readFileSync28 } from "fs";
|
|
9629
|
+
import { join as join52 } from "path";
|
|
9397
9630
|
import { promisify } from "util";
|
|
9398
9631
|
import readline4 from "readline";
|
|
9399
9632
|
import chalk14 from "chalk";
|
|
@@ -9459,10 +9692,10 @@ function prompt3(question) {
|
|
|
9459
9692
|
input: process.stdin,
|
|
9460
9693
|
output: process.stdout
|
|
9461
9694
|
});
|
|
9462
|
-
return new Promise((
|
|
9695
|
+
return new Promise((resolve39) => {
|
|
9463
9696
|
rl.question(question, (answer) => {
|
|
9464
9697
|
rl.close();
|
|
9465
|
-
|
|
9698
|
+
resolve39(answer.trim().toLowerCase());
|
|
9466
9699
|
});
|
|
9467
9700
|
});
|
|
9468
9701
|
}
|
|
@@ -9477,12 +9710,12 @@ async function ensureTelemetryIfNeeded() {
|
|
|
9477
9710
|
}
|
|
9478
9711
|
function refreshHooks() {
|
|
9479
9712
|
const cwd = process.cwd();
|
|
9480
|
-
const configPath =
|
|
9713
|
+
const configPath = join52(cwd, "harness.config.json");
|
|
9481
9714
|
if (!existsSync38(configPath)) return;
|
|
9482
9715
|
let profile = "standard";
|
|
9483
|
-
const profilePath =
|
|
9716
|
+
const profilePath = join52(cwd, ".harness", "hooks", "profile.json");
|
|
9484
9717
|
try {
|
|
9485
|
-
const data = JSON.parse(
|
|
9718
|
+
const data = JSON.parse(readFileSync28(profilePath, "utf-8"));
|
|
9486
9719
|
if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
|
|
9487
9720
|
profile = data.profile;
|
|
9488
9721
|
}
|
|
@@ -9608,7 +9841,7 @@ async function runUpdateAction(opts, globalOpts) {
|
|
|
9608
9841
|
process.exit(ExitCode.SUCCESS);
|
|
9609
9842
|
}
|
|
9610
9843
|
function createUpdateCommand() {
|
|
9611
|
-
return new
|
|
9844
|
+
return new Command87("update").description("Update all @harness-engineering packages to the latest version").option("--version <semver>", "Pin @harness-engineering/cli to a specific version").option("--force", "Force update even if versions match").option(
|
|
9612
9845
|
"--regenerate",
|
|
9613
9846
|
"Only regenerate slash commands and agent definitions (skip package updates)"
|
|
9614
9847
|
).action(async (opts, cmd) => {
|
|
@@ -9618,9 +9851,9 @@ function createUpdateCommand() {
|
|
|
9618
9851
|
}
|
|
9619
9852
|
|
|
9620
9853
|
// src/commands/usage.ts
|
|
9621
|
-
import { Command as
|
|
9854
|
+
import { Command as Command88 } from "commander";
|
|
9622
9855
|
async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
|
|
9623
|
-
const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-
|
|
9856
|
+
const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-6RT2AVYU.js");
|
|
9624
9857
|
const records = readCostRecords(cwd);
|
|
9625
9858
|
if (includeClaudeSessions) {
|
|
9626
9859
|
const ccRecords = parseCCRecords();
|
|
@@ -9713,7 +9946,7 @@ function registerDailyCommand(usage) {
|
|
|
9713
9946
|
else logger.info("No usage data found. Run some harness sessions first.");
|
|
9714
9947
|
return;
|
|
9715
9948
|
}
|
|
9716
|
-
const { aggregateByDay } = await import("./dist-
|
|
9949
|
+
const { aggregateByDay } = await import("./dist-6RT2AVYU.js");
|
|
9717
9950
|
const limited = aggregateByDay(records).slice(0, days);
|
|
9718
9951
|
if (globalOpts.json) {
|
|
9719
9952
|
console.log(
|
|
@@ -9742,7 +9975,7 @@ function registerSessionsCommand(usage) {
|
|
|
9742
9975
|
}
|
|
9743
9976
|
return;
|
|
9744
9977
|
}
|
|
9745
|
-
const { aggregateBySession } = await import("./dist-
|
|
9978
|
+
const { aggregateBySession } = await import("./dist-6RT2AVYU.js");
|
|
9746
9979
|
const sessionData = aggregateBySession(records);
|
|
9747
9980
|
const limited = sessionData.slice(0, limit);
|
|
9748
9981
|
if (globalOpts.json) {
|
|
@@ -9822,7 +10055,7 @@ function registerSessionCommand(usage) {
|
|
|
9822
10055
|
cwd,
|
|
9823
10056
|
globalOpts.includeClaudeSessions
|
|
9824
10057
|
);
|
|
9825
|
-
const { aggregateBySession } = await import("./dist-
|
|
10058
|
+
const { aggregateBySession } = await import("./dist-6RT2AVYU.js");
|
|
9826
10059
|
const sessionData = aggregateBySession(records);
|
|
9827
10060
|
const match = sessionData.find((s) => s.sessionId === id);
|
|
9828
10061
|
if (!match) {
|
|
@@ -9857,7 +10090,7 @@ function registerLatestCommand(usage) {
|
|
|
9857
10090
|
}
|
|
9858
10091
|
return;
|
|
9859
10092
|
}
|
|
9860
|
-
const { aggregateBySession } = await import("./dist-
|
|
10093
|
+
const { aggregateBySession } = await import("./dist-6RT2AVYU.js");
|
|
9861
10094
|
const sessionData = aggregateBySession(records);
|
|
9862
10095
|
const latest = sessionData[0];
|
|
9863
10096
|
if (!latest) {
|
|
@@ -9883,7 +10116,7 @@ function registerLatestCommand(usage) {
|
|
|
9883
10116
|
});
|
|
9884
10117
|
}
|
|
9885
10118
|
function createUsageCommand() {
|
|
9886
|
-
const usage = new
|
|
10119
|
+
const usage = new Command88("usage").description("Token usage and cost tracking");
|
|
9887
10120
|
usage.option(
|
|
9888
10121
|
"--include-claude-sessions",
|
|
9889
10122
|
"Include Claude Code session data from ~/.claude/projects/"
|
|
@@ -9898,7 +10131,7 @@ function createUsageCommand() {
|
|
|
9898
10131
|
// src/commands/validate.ts
|
|
9899
10132
|
init_dist();
|
|
9900
10133
|
init_dist();
|
|
9901
|
-
import { Command as
|
|
10134
|
+
import { Command as Command89 } from "commander";
|
|
9902
10135
|
import * as path64 from "path";
|
|
9903
10136
|
async function runValidate(options) {
|
|
9904
10137
|
const configResult = resolveConfig(options.configPath);
|
|
@@ -9952,6 +10185,34 @@ async function runValidate(options) {
|
|
|
9952
10185
|
});
|
|
9953
10186
|
}
|
|
9954
10187
|
result.checks.fileStructure = true;
|
|
10188
|
+
const pulseResult = await validatePulseConfig(cwd);
|
|
10189
|
+
if (pulseResult.ok) {
|
|
10190
|
+
result.checks.pulseConfig = true;
|
|
10191
|
+
} else {
|
|
10192
|
+
result.valid = false;
|
|
10193
|
+
result.checks.pulseConfig = false;
|
|
10194
|
+
result.issues.push({
|
|
10195
|
+
check: "pulseConfig",
|
|
10196
|
+
file: "harness.config.json",
|
|
10197
|
+
message: pulseResult.error.message,
|
|
10198
|
+
...pulseResult.error.suggestions?.[0] !== void 0 && {
|
|
10199
|
+
suggestion: pulseResult.error.suggestions[0]
|
|
10200
|
+
}
|
|
10201
|
+
});
|
|
10202
|
+
}
|
|
10203
|
+
const solutionsResult = await validateSolutionsDir(cwd);
|
|
10204
|
+
if (solutionsResult.ok) {
|
|
10205
|
+
result.checks.solutionsDir = true;
|
|
10206
|
+
} else {
|
|
10207
|
+
result.valid = false;
|
|
10208
|
+
result.checks.solutionsDir = false;
|
|
10209
|
+
const detail = solutionsResult.error.details;
|
|
10210
|
+
for (const issue of detail.issues ?? [
|
|
10211
|
+
{ file: "docs/solutions", message: solutionsResult.error.message }
|
|
10212
|
+
]) {
|
|
10213
|
+
result.issues.push({ check: "solutionsDir", file: issue.file, message: issue.message });
|
|
10214
|
+
}
|
|
10215
|
+
}
|
|
9955
10216
|
if (options.agentConfigs) {
|
|
9956
10217
|
const agentCfg = await validateAgentConfigs(cwd, {
|
|
9957
10218
|
strict: options.strict === true,
|
|
@@ -9981,7 +10242,7 @@ function resolveValidateMode(globalOpts) {
|
|
|
9981
10242
|
return OutputMode.TEXT;
|
|
9982
10243
|
}
|
|
9983
10244
|
async function printCrossCheckWarnings(mode) {
|
|
9984
|
-
const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-
|
|
10245
|
+
const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-MI5MZ7MB.js");
|
|
9985
10246
|
const cwd = process.cwd();
|
|
9986
10247
|
const crossResult = await runCrossCheck2({
|
|
9987
10248
|
specsDir: path64.join(cwd, "docs", "specs"),
|
|
@@ -9997,7 +10258,7 @@ async function printCrossCheckWarnings(mode) {
|
|
|
9997
10258
|
${crossResult.value.warnings} warnings`);
|
|
9998
10259
|
}
|
|
9999
10260
|
function createValidateCommand3() {
|
|
10000
|
-
const command = new
|
|
10261
|
+
const command = new Command89("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
|
|
10001
10262
|
"--agent-configs",
|
|
10002
10263
|
"Validate agent configs (CLAUDE.md, hooks, skills) via agnix or built-in fallback rules"
|
|
10003
10264
|
).option("--strict", "Treat warnings as errors (applies to --agent-configs)").option("--agnix-bin <path>", "Override the agnix binary path discovered on PATH").action(async (opts, cmd) => runValidateAction(opts, cmd.optsWithGlobals()));
|
|
@@ -10061,6 +10322,7 @@ var commandCreators = [
|
|
|
10061
10322
|
createCICommand,
|
|
10062
10323
|
createCleanupCommand,
|
|
10063
10324
|
createCleanupSessionsCommand,
|
|
10325
|
+
createCompoundCommand,
|
|
10064
10326
|
createCreateSkillCommand,
|
|
10065
10327
|
createDashboardCommand,
|
|
10066
10328
|
createDoctorCommand,
|
|
@@ -10086,6 +10348,7 @@ var commandCreators = [
|
|
|
10086
10348
|
createPersonaCommand,
|
|
10087
10349
|
createPredictCommand,
|
|
10088
10350
|
createPublishAnalysesCommand,
|
|
10351
|
+
createPulseCommand,
|
|
10089
10352
|
createQueryCommand,
|
|
10090
10353
|
createRecommendCommand,
|
|
10091
10354
|
createScanCommand,
|
|
@@ -10109,7 +10372,7 @@ var commandCreators = [
|
|
|
10109
10372
|
|
|
10110
10373
|
// src/index.ts
|
|
10111
10374
|
function createProgram() {
|
|
10112
|
-
const program = new
|
|
10375
|
+
const program = new Command90();
|
|
10113
10376
|
program.name("harness").description("CLI for Harness Engineering toolkit").version(CLI_VERSION).option("-c, --config <path>", "Path to config file").option("--json", "Output as JSON").option("--verbose", "Verbose output").option("--quiet", "Minimal output");
|
|
10114
10377
|
for (const creator of commandCreators) {
|
|
10115
10378
|
program.addCommand(creator());
|