@harness-engineering/cli 1.25.7 → 1.26.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/README.md +1 -0
- package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +33 -5
- package/dist/agents/skills/claude-code/harness-execution/SKILL.md +6 -0
- package/dist/agents/skills/claude-code/harness-knowledge-pipeline/SKILL.md +277 -0
- package/dist/agents/skills/claude-code/harness-knowledge-pipeline/skill.yaml +60 -0
- package/dist/agents/skills/claude-code/harness-planning/SKILL.md +25 -1
- package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +22 -6
- package/dist/agents/skills/claude-code/initialize-harness-project/skill.yaml +2 -1
- package/dist/agents/skills/claude-code/initialize-test-suite-project/SKILL.md +415 -0
- package/dist/agents/skills/claude-code/initialize-test-suite-project/skill.yaml +35 -0
- package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +33 -5
- package/dist/agents/skills/codex/harness-execution/SKILL.md +6 -0
- package/dist/agents/skills/codex/harness-knowledge-pipeline/SKILL.md +277 -0
- package/dist/agents/skills/codex/harness-knowledge-pipeline/skill.yaml +60 -0
- package/dist/agents/skills/codex/harness-planning/SKILL.md +25 -1
- package/dist/agents/skills/codex/initialize-harness-project/SKILL.md +22 -6
- package/dist/agents/skills/codex/initialize-harness-project/skill.yaml +2 -1
- package/dist/agents/skills/codex/initialize-test-suite-project/SKILL.md +415 -0
- package/dist/agents/skills/codex/initialize-test-suite-project/skill.yaml +35 -0
- package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +33 -5
- package/dist/agents/skills/cursor/harness-execution/SKILL.md +6 -0
- package/dist/agents/skills/cursor/harness-knowledge-pipeline/SKILL.md +277 -0
- package/dist/agents/skills/cursor/harness-knowledge-pipeline/skill.yaml +60 -0
- package/dist/agents/skills/cursor/harness-planning/SKILL.md +25 -1
- package/dist/agents/skills/cursor/initialize-harness-project/SKILL.md +22 -6
- package/dist/agents/skills/cursor/initialize-harness-project/skill.yaml +2 -1
- package/dist/agents/skills/cursor/initialize-test-suite-project/SKILL.md +415 -0
- package/dist/agents/skills/cursor/initialize-test-suite-project/skill.yaml +35 -0
- package/dist/agents/skills/gemini-cli/harness-brainstorming/SKILL.md +33 -5
- package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +6 -0
- package/dist/agents/skills/gemini-cli/harness-knowledge-pipeline/SKILL.md +277 -0
- package/dist/agents/skills/gemini-cli/harness-knowledge-pipeline/skill.yaml +60 -0
- package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +25 -1
- package/dist/agents/skills/gemini-cli/initialize-harness-project/SKILL.md +22 -6
- package/dist/agents/skills/gemini-cli/initialize-harness-project/skill.yaml +2 -1
- package/dist/agents/skills/gemini-cli/initialize-test-suite-project/SKILL.md +415 -0
- package/dist/agents/skills/gemini-cli/initialize-test-suite-project/skill.yaml +35 -0
- package/dist/agents/skills/package.json +2 -2
- package/dist/agents/skills/tests/initialize-test-suite-project.test.ts +152 -0
- package/dist/{agents-md-QPO3H5HX.js → agents-md-VI3HLR7E.js} +3 -3
- package/dist/{architecture-IJLXRHZA.js → architecture-ZDDKEVID.js} +4 -4
- package/dist/{assess-project-QU6XIVJK.js → assess-project-Y6W7YDUA.js} +1 -1
- package/dist/bin/harness-mcp.js +16 -15
- package/dist/bin/harness.js +27 -27
- package/dist/{check-phase-gate-TNY64AOS.js → check-phase-gate-CXR3VM22.js} +4 -4
- package/dist/{chunk-JJQ3TW2E.js → chunk-2BPPS6YQ.js} +804 -93
- package/dist/{chunk-NKQEMWGT.js → chunk-2FPUPRCY.js} +3419 -126
- package/dist/{chunk-MLOGYWLY.js → chunk-3AMQYWGT.js} +2 -2
- package/dist/{chunk-AS5DQT4S.js → chunk-56A6OXVA.js} +9 -9
- package/dist/{chunk-G5SNXUIK.js → chunk-7GY6WNEI.js} +1 -1
- package/dist/{chunk-SZ3Q4XEO.js → chunk-AMRC4FU2.js} +441 -288
- package/dist/{chunk-K533WNZG.js → chunk-B66LRB5M.js} +1 -1
- package/dist/{chunk-YRBNAHH4.js → chunk-BK4DJIIY.js} +4 -4
- package/dist/{chunk-2DF6OZLG.js → chunk-DBIX3X4H.js} +2 -2
- package/dist/{chunk-LXPRO2FH.js → chunk-FUND5WJR.js} +2 -2
- package/dist/{chunk-FRDS4XGD.js → chunk-JV4Y2U5F.js} +1 -1
- package/dist/{chunk-XVJRFP7W.js → chunk-K56DTX7G.js} +6 -6
- package/dist/{chunk-K35D7HF3.js → chunk-N6B6RKQQ.js} +1 -1
- package/dist/{chunk-LTCEV7VF.js → chunk-NY7DTZ6K.js} +3 -3
- package/dist/{chunk-JPZY7ZQX.js → chunk-OLW7BJ5N.js} +1 -1
- package/dist/{chunk-KVJZQ2MV.js → chunk-ORNEK65Y.js} +1 -1
- package/dist/{chunk-D3XL2FLX.js → chunk-PNNFCVW4.js} +5 -5
- package/dist/{chunk-E5Z6NTTQ.js → chunk-Q3ZLVMQM.js} +1 -1
- package/dist/{chunk-PCOU2UXU.js → chunk-RAVD7QLY.js} +8 -8
- package/dist/{chunk-IQO7IINR.js → chunk-TSVYBDDE.js} +1 -1
- package/dist/{chunk-MCDCZMKN.js → chunk-TY2ESLVL.js} +1 -1
- package/dist/{chunk-TQRCODRJ.js → chunk-VKS3F46M.js} +1 -1
- package/dist/{chunk-GVNT2YC7.js → chunk-WZ7UHPT3.js} +9 -9
- package/dist/{chunk-ZIYLIYN4.js → chunk-YC4EYIER.js} +8 -2
- package/dist/{chunk-IT2KORSK.js → chunk-ZN6ROTYP.js} +1 -1
- package/dist/{ci-workflow-FJYRFZYQ.js → ci-workflow-EW37KVPS.js} +3 -3
- package/dist/{create-skill-6QWJHQYS.js → create-skill-4T5CBSJ2.js} +2 -2
- package/dist/{dist-ZV6GO6FA.js → dist-CJDGASPP.js} +2 -2
- package/dist/{dist-HPWNWCT6.js → dist-NCNAXUFD.js} +41 -1
- package/dist/{docs-7DW3DI4Z.js → docs-4XI2FQW2.js} +4 -4
- package/dist/{engine-P7EE2IWO.js → engine-4L4CDTHU.js} +3 -3
- package/dist/{entropy-HCXRTDFU.js → entropy-PBYSIQYS.js} +3 -3
- package/dist/{feedback-Y4FYN3NR.js → feedback-OTIFW5MK.js} +1 -1
- package/dist/{generate-agent-definitions-3EHPIWBO.js → generate-agent-definitions-CZGUXIIN.js} +4 -4
- package/dist/{graph-loader-KXVS3YK3.js → graph-loader-RDXSEBD7.js} +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.js +27 -27
- package/dist/{loader-SKHF3JVV.js → loader-UZOXCWFC.js} +3 -3
- package/dist/{mcp-MWYIPDQU.js → mcp-GWVVV6LH.js} +16 -15
- package/dist/{performance-ADWH5NJY.js → performance-5UQPP3XX.js} +4 -4
- package/dist/{review-pipeline-TLKE5OQD.js → review-pipeline-65V4EO6O.js} +3 -3
- package/dist/{runtime-7LYAW7GU.js → runtime-PXX7HNB3.js} +3 -3
- package/dist/{scan-BGJ7TLLV.js → scan-WM7XDUF7.js} +1 -1
- package/dist/{security-5XWINYVB.js → security-CAYDRZIZ.js} +1 -1
- package/dist/{validate-BFFHYHY7.js → validate-CWGXR7QM.js} +4 -4
- package/dist/{validate-cross-check-GQX7OVCR.js → validate-cross-check-BKCNLZYG.js} +3 -3
- package/package.json +10 -10
- package/dist/agents/commands/claude-code/harness/harness.md +0 -36
- package/dist/agents/commands/codex/AGENTS.md +0 -39
- package/dist/agents/commands/codex/harness/add-harness-component/SKILL.md +0 -204
- package/dist/agents/commands/codex/harness/add-harness-component/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/cleanup-dead-code/SKILL.md +0 -257
- package/dist/agents/commands/codex/harness/cleanup-dead-code/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/detect-doc-drift/SKILL.md +0 -191
- package/dist/agents/commands/codex/harness/detect-doc-drift/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/enforce-architecture/SKILL.md +0 -289
- package/dist/agents/commands/codex/harness/enforce-architecture/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-architecture-advisor/SKILL.md +0 -442
- package/dist/agents/commands/codex/harness/harness-architecture-advisor/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-autopilot/SKILL.md +0 -929
- package/dist/agents/commands/codex/harness/harness-autopilot/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-brainstorming/SKILL.md +0 -418
- package/dist/agents/commands/codex/harness/harness-brainstorming/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-code-review/SKILL.md +0 -850
- package/dist/agents/commands/codex/harness/harness-code-review/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-codebase-cleanup/SKILL.md +0 -236
- package/dist/agents/commands/codex/harness/harness-codebase-cleanup/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-debugging/SKILL.md +0 -378
- package/dist/agents/commands/codex/harness/harness-debugging/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-dependency-health/SKILL.md +0 -190
- package/dist/agents/commands/codex/harness/harness-dependency-health/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-docs-pipeline/SKILL.md +0 -472
- package/dist/agents/commands/codex/harness/harness-docs-pipeline/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-execution/SKILL.md +0 -522
- package/dist/agents/commands/codex/harness/harness-execution/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-hotspot-detector/SKILL.md +0 -172
- package/dist/agents/commands/codex/harness/harness-hotspot-detector/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-impact-analysis/SKILL.md +0 -195
- package/dist/agents/commands/codex/harness/harness-impact-analysis/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-integrity/SKILL.md +0 -178
- package/dist/agents/commands/codex/harness/harness-integrity/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-onboarding/SKILL.md +0 -299
- package/dist/agents/commands/codex/harness/harness-onboarding/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-perf/SKILL.md +0 -272
- package/dist/agents/commands/codex/harness/harness-perf/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-planning/SKILL.md +0 -592
- package/dist/agents/commands/codex/harness/harness-planning/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-refactoring/SKILL.md +0 -181
- package/dist/agents/commands/codex/harness/harness-refactoring/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-release-readiness/SKILL.md +0 -701
- package/dist/agents/commands/codex/harness/harness-release-readiness/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-roadmap/SKILL.md +0 -607
- package/dist/agents/commands/codex/harness/harness-roadmap/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-security-scan/SKILL.md +0 -147
- package/dist/agents/commands/codex/harness/harness-security-scan/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-skill-authoring/SKILL.md +0 -314
- package/dist/agents/commands/codex/harness/harness-skill-authoring/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-soundness-review/SKILL.md +0 -1280
- package/dist/agents/commands/codex/harness/harness-soundness-review/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-supply-chain-audit/SKILL.md +0 -255
- package/dist/agents/commands/codex/harness/harness-supply-chain-audit/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-tdd/SKILL.md +0 -189
- package/dist/agents/commands/codex/harness/harness-tdd/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-test-advisor/SKILL.md +0 -171
- package/dist/agents/commands/codex/harness/harness-test-advisor/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-verification/SKILL.md +0 -433
- package/dist/agents/commands/codex/harness/harness-verification/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/harness-verify/SKILL.md +0 -170
- package/dist/agents/commands/codex/harness/harness-verify/agents/openai.yaml +0 -3
- package/dist/agents/commands/codex/harness/initialize-harness-project/SKILL.md +0 -244
- package/dist/agents/commands/codex/harness/initialize-harness-project/agents/openai.yaml +0 -3
- package/dist/agents/commands/cursor/harness/add-harness-component.mdc +0 -200
- package/dist/agents/commands/cursor/harness/cleanup-dead-code.mdc +0 -253
- package/dist/agents/commands/cursor/harness/detect-doc-drift.mdc +0 -187
- package/dist/agents/commands/cursor/harness/enforce-architecture.mdc +0 -304
- package/dist/agents/commands/cursor/harness/harness-architecture-advisor.mdc +0 -457
- package/dist/agents/commands/cursor/harness/harness-autopilot.mdc +0 -924
- package/dist/agents/commands/cursor/harness/harness-brainstorming.mdc +0 -414
- package/dist/agents/commands/cursor/harness/harness-code-review.mdc +0 -865
- package/dist/agents/commands/cursor/harness/harness-codebase-cleanup.mdc +0 -232
- package/dist/agents/commands/cursor/harness/harness-debugging.mdc +0 -374
- package/dist/agents/commands/cursor/harness/harness-dependency-health.mdc +0 -187
- package/dist/agents/commands/cursor/harness/harness-docs-pipeline.mdc +0 -468
- package/dist/agents/commands/cursor/harness/harness-execution.mdc +0 -518
- package/dist/agents/commands/cursor/harness/harness-hotspot-detector.mdc +0 -169
- package/dist/agents/commands/cursor/harness/harness-impact-analysis.mdc +0 -192
- package/dist/agents/commands/cursor/harness/harness-integrity.mdc +0 -175
- package/dist/agents/commands/cursor/harness/harness-onboarding.mdc +0 -296
- package/dist/agents/commands/cursor/harness/harness-perf.mdc +0 -268
- package/dist/agents/commands/cursor/harness/harness-planning.mdc +0 -587
- package/dist/agents/commands/cursor/harness/harness-refactoring.mdc +0 -177
- package/dist/agents/commands/cursor/harness/harness-release-readiness.mdc +0 -697
- package/dist/agents/commands/cursor/harness/harness-roadmap.mdc +0 -603
- package/dist/agents/commands/cursor/harness/harness-security-scan.mdc +0 -162
- package/dist/agents/commands/cursor/harness/harness-skill-authoring.mdc +0 -300
- package/dist/agents/commands/cursor/harness/harness-soundness-review.mdc +0 -1275
- package/dist/agents/commands/cursor/harness/harness-supply-chain-audit.mdc +0 -252
- package/dist/agents/commands/cursor/harness/harness-tdd.mdc +0 -185
- package/dist/agents/commands/cursor/harness/harness-test-advisor.mdc +0 -168
- package/dist/agents/commands/cursor/harness/harness-verification.mdc +0 -429
- package/dist/agents/commands/cursor/harness/harness-verify.mdc +0 -167
- package/dist/agents/commands/cursor/harness/initialize-harness-project.mdc +0 -240
- package/dist/agents/commands/gemini-cli/harness/harness.toml +0 -277
- package/dist/{chunk-RRHUCDRD.js → chunk-ZP5E7YET.js} +3 -3
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateAgentsMd
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZN6ROTYP.js";
|
|
4
4
|
import {
|
|
5
5
|
generateCIWorkflow
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ORNEK65Y.js";
|
|
7
7
|
import {
|
|
8
8
|
TemplateEngine
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-B66LRB5M.js";
|
|
10
10
|
import {
|
|
11
11
|
generate,
|
|
12
12
|
validate
|
|
13
13
|
} from "./chunk-CQ553GZO.js";
|
|
14
14
|
import {
|
|
15
15
|
generateRuntime
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-N6B6RKQQ.js";
|
|
17
17
|
import {
|
|
18
18
|
runPersona
|
|
19
19
|
} from "./chunk-GISMXMVL.js";
|
|
@@ -28,24 +28,25 @@ import {
|
|
|
28
28
|
OutputMode,
|
|
29
29
|
createCheckPhaseGateCommand,
|
|
30
30
|
findFiles
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-FUND5WJR.js";
|
|
32
32
|
import {
|
|
33
33
|
createGenerateAgentDefinitionsCommand,
|
|
34
34
|
generateAgentDefinitions
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-TY2ESLVL.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-JV4Y2U5F.js";
|
|
43
43
|
import {
|
|
44
44
|
createScanCommand
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-Q3ZLVMQM.js";
|
|
46
46
|
import {
|
|
47
47
|
appendFrameworkAgents,
|
|
48
48
|
captureHealthSnapshot,
|
|
49
|
+
createAdviseSkillsCommand,
|
|
49
50
|
createGenerateSlashCommandsCommand,
|
|
50
51
|
ensureHarnessGitignore,
|
|
51
52
|
generateSlashCommands,
|
|
@@ -56,11 +57,11 @@ import {
|
|
|
56
57
|
loadOrRebuildIndex,
|
|
57
58
|
persistToolingConfig,
|
|
58
59
|
recommend
|
|
59
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-2BPPS6YQ.js";
|
|
60
61
|
import {
|
|
61
62
|
findConfigFile,
|
|
62
63
|
resolveConfig
|
|
63
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-VKS3F46M.js";
|
|
64
65
|
import {
|
|
65
66
|
VALID_PLATFORMS
|
|
66
67
|
} from "./chunk-3ISINLYT.js";
|
|
@@ -74,7 +75,7 @@ import {
|
|
|
74
75
|
} from "./chunk-6B6UN6SG.js";
|
|
75
76
|
import {
|
|
76
77
|
loadGraphStore
|
|
77
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-OLW7BJ5N.js";
|
|
78
79
|
import {
|
|
79
80
|
CLI_VERSION
|
|
80
81
|
} from "./chunk-BM3PWGXQ.js";
|
|
@@ -148,20 +149,20 @@ import {
|
|
|
148
149
|
validateKnowledgeMap,
|
|
149
150
|
writeConfig,
|
|
150
151
|
writeLockfile
|
|
151
|
-
} from "./chunk-
|
|
152
|
+
} from "./chunk-YC4EYIER.js";
|
|
152
153
|
import {
|
|
153
154
|
Err,
|
|
154
155
|
Ok
|
|
155
156
|
} from "./chunk-RL4VMEXL.js";
|
|
156
157
|
import {
|
|
157
158
|
createCreateSkillCommand
|
|
158
|
-
} from "./chunk-
|
|
159
|
-
import {
|
|
160
|
-
logger
|
|
161
|
-
} from "./chunk-EBJQ6N4M.js";
|
|
159
|
+
} from "./chunk-ZP5E7YET.js";
|
|
162
160
|
import {
|
|
163
161
|
SkillMetadataSchema
|
|
164
162
|
} from "./chunk-HIK6OEUF.js";
|
|
163
|
+
import {
|
|
164
|
+
logger
|
|
165
|
+
} from "./chunk-EBJQ6N4M.js";
|
|
165
166
|
import {
|
|
166
167
|
CLIError,
|
|
167
168
|
ExitCode,
|
|
@@ -173,7 +174,7 @@ import {
|
|
|
173
174
|
} from "./chunk-KFQGP6VL.js";
|
|
174
175
|
|
|
175
176
|
// src/index.ts
|
|
176
|
-
import { Command as
|
|
177
|
+
import { Command as Command85 } from "commander";
|
|
177
178
|
|
|
178
179
|
// src/commands/add.ts
|
|
179
180
|
init_dist();
|
|
@@ -264,7 +265,7 @@ function addDoc(name, cwd, configResult, created) {
|
|
|
264
265
|
return Ok(void 0);
|
|
265
266
|
}
|
|
266
267
|
async function addSkill(name, cwd, created) {
|
|
267
|
-
const { generateSkillFiles: generateSkillFiles2 } = await import("./create-skill-
|
|
268
|
+
const { generateSkillFiles: generateSkillFiles2 } = await import("./create-skill-4T5CBSJ2.js");
|
|
268
269
|
generateSkillFiles2({
|
|
269
270
|
name,
|
|
270
271
|
description: `${name} skill`,
|
|
@@ -362,7 +363,7 @@ function registerSkillsCommand(adoption) {
|
|
|
362
363
|
const globalOpts = cmd.optsWithGlobals();
|
|
363
364
|
const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
|
|
364
365
|
const cwd = process.cwd();
|
|
365
|
-
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-
|
|
366
|
+
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-CJDGASPP.js");
|
|
366
367
|
const records = readAdoptionRecords(cwd);
|
|
367
368
|
if (records.length === 0) {
|
|
368
369
|
if (globalOpts.json) {
|
|
@@ -398,7 +399,7 @@ function registerRecentCommand(adoption) {
|
|
|
398
399
|
const globalOpts = cmd.optsWithGlobals();
|
|
399
400
|
const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
|
|
400
401
|
const cwd = process.cwd();
|
|
401
|
-
const { readAdoptionRecords } = await import("./dist-
|
|
402
|
+
const { readAdoptionRecords } = await import("./dist-CJDGASPP.js");
|
|
402
403
|
const records = readAdoptionRecords(cwd);
|
|
403
404
|
if (records.length === 0) {
|
|
404
405
|
if (globalOpts.json) {
|
|
@@ -476,7 +477,7 @@ function registerSkillCommand(adoption) {
|
|
|
476
477
|
adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
|
|
477
478
|
const globalOpts = cmd.optsWithGlobals();
|
|
478
479
|
const cwd = process.cwd();
|
|
479
|
-
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-
|
|
480
|
+
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-CJDGASPP.js");
|
|
480
481
|
const records = readAdoptionRecords(cwd);
|
|
481
482
|
const skillRecords = records.filter((r) => r.skill === name);
|
|
482
483
|
if (skillRecords.length === 0) {
|
|
@@ -2765,7 +2766,7 @@ import { Command as Command25 } from "commander";
|
|
|
2765
2766
|
// src/commands/graph/status.ts
|
|
2766
2767
|
import * as path15 from "path";
|
|
2767
2768
|
async function runGraphStatus(projectPath) {
|
|
2768
|
-
const { GraphStore } = await import("./dist-
|
|
2769
|
+
const { GraphStore } = await import("./dist-NCNAXUFD.js");
|
|
2769
2770
|
const graphDir = path15.join(projectPath, ".harness", "graph");
|
|
2770
2771
|
const store = new GraphStore();
|
|
2771
2772
|
const loaded = await store.load(graphDir);
|
|
@@ -2805,7 +2806,7 @@ async function runGraphStatus(projectPath) {
|
|
|
2805
2806
|
// src/commands/graph/export.ts
|
|
2806
2807
|
import * as path16 from "path";
|
|
2807
2808
|
async function runGraphExport(projectPath, format) {
|
|
2808
|
-
const { GraphStore } = await import("./dist-
|
|
2809
|
+
const { GraphStore } = await import("./dist-NCNAXUFD.js");
|
|
2809
2810
|
const graphDir = path16.join(projectPath, ".harness", "graph");
|
|
2810
2811
|
const store = new GraphStore();
|
|
2811
2812
|
const loaded = await store.load(graphDir);
|
|
@@ -2841,7 +2842,7 @@ import * as path19 from "path";
|
|
|
2841
2842
|
import { Command as Command23 } from "commander";
|
|
2842
2843
|
import * as path17 from "path";
|
|
2843
2844
|
async function runQuery(projectPath, rootNodeId, opts) {
|
|
2844
|
-
const { GraphStore, ContextQL } = await import("./dist-
|
|
2845
|
+
const { GraphStore, ContextQL } = await import("./dist-NCNAXUFD.js");
|
|
2845
2846
|
const store = new GraphStore();
|
|
2846
2847
|
const graphDir = path17.join(projectPath, ".harness", "graph");
|
|
2847
2848
|
const loaded = await store.load(graphDir);
|
|
@@ -2935,7 +2936,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
2935
2936
|
SlackConnector,
|
|
2936
2937
|
CIConnector,
|
|
2937
2938
|
ConfluenceConnector
|
|
2938
|
-
} = await import("./dist-
|
|
2939
|
+
} = await import("./dist-NCNAXUFD.js");
|
|
2939
2940
|
const graphDir = path18.join(projectPath, ".harness", "graph");
|
|
2940
2941
|
const store = new GraphStore();
|
|
2941
2942
|
await store.load(graphDir);
|
|
@@ -2945,6 +2946,9 @@ async function runIngest(projectPath, source, opts) {
|
|
|
2945
2946
|
new TopologicalLinker(store).link();
|
|
2946
2947
|
const knowledgeResult = await new KnowledgeIngestor(store).ingestAll(projectPath);
|
|
2947
2948
|
const gitResult = await new GitIngestor(store).ingest(projectPath);
|
|
2949
|
+
const { createExtractionRunner } = await import("./dist-NCNAXUFD.js");
|
|
2950
|
+
const extractedDir = path18.join(projectPath, ".harness", "knowledge", "extracted");
|
|
2951
|
+
const signalsResult = await createExtractionRunner().run(projectPath, store, extractedDir);
|
|
2948
2952
|
const syncManager = new SyncManager(store, graphDir);
|
|
2949
2953
|
const connectorMap = {
|
|
2950
2954
|
jira: () => new JiraConnector(),
|
|
@@ -2958,7 +2962,13 @@ async function runIngest(projectPath, source, opts) {
|
|
|
2958
2962
|
}
|
|
2959
2963
|
const connectorResult = await syncManager.syncAll();
|
|
2960
2964
|
await store.save(graphDir);
|
|
2961
|
-
const merged = mergeResults(
|
|
2965
|
+
const merged = mergeResults(
|
|
2966
|
+
codeResult,
|
|
2967
|
+
knowledgeResult,
|
|
2968
|
+
gitResult,
|
|
2969
|
+
signalsResult,
|
|
2970
|
+
connectorResult
|
|
2971
|
+
);
|
|
2962
2972
|
return { ...merged, durationMs: Date.now() - startMs };
|
|
2963
2973
|
}
|
|
2964
2974
|
let result;
|
|
@@ -2973,11 +2983,17 @@ async function runIngest(projectPath, source, opts) {
|
|
|
2973
2983
|
case "git":
|
|
2974
2984
|
result = await new GitIngestor(store).ingest(projectPath);
|
|
2975
2985
|
break;
|
|
2986
|
+
case "business-signals": {
|
|
2987
|
+
const { createExtractionRunner } = await import("./dist-NCNAXUFD.js");
|
|
2988
|
+
const extractedDir = path18.join(projectPath, ".harness", "knowledge", "extracted");
|
|
2989
|
+
result = await createExtractionRunner().run(projectPath, store, extractedDir);
|
|
2990
|
+
break;
|
|
2991
|
+
}
|
|
2976
2992
|
default: {
|
|
2977
2993
|
const knownConnectors = ["jira", "slack", "ci", "confluence"];
|
|
2978
2994
|
if (!knownConnectors.includes(source)) {
|
|
2979
2995
|
throw new Error(
|
|
2980
|
-
`Unknown source: ${source}. Available: code, knowledge, git, jira, slack, ci, confluence`
|
|
2996
|
+
`Unknown source: ${source}. Available: code, knowledge, git, business-signals, jira, slack, ci, confluence`
|
|
2981
2997
|
);
|
|
2982
2998
|
}
|
|
2983
2999
|
if (!SyncManager) {
|
|
@@ -3005,7 +3021,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
3005
3021
|
function createIngestCommand() {
|
|
3006
3022
|
return new Command24("ingest").description("Ingest data into the knowledge graph").option(
|
|
3007
3023
|
"--source <name>",
|
|
3008
|
-
"Source to ingest (code, knowledge, git, jira, slack, ci, confluence)"
|
|
3024
|
+
"Source to ingest (code, knowledge, git, business-signals, jira, slack, ci, confluence)"
|
|
3009
3025
|
).option("--all", "Run all sources (code, knowledge, git, and configured connectors)").option("--full", "Force full re-ingestion").action(async (opts, cmd) => {
|
|
3010
3026
|
if (!opts.source && !opts.all) {
|
|
3011
3027
|
console.error("Error: --source or --all is required");
|
|
@@ -3820,6 +3836,7 @@ var ALL_MCP_TOOLS = [
|
|
|
3820
3836
|
"check_traceability",
|
|
3821
3837
|
"predict_failures",
|
|
3822
3838
|
"recommend_skills",
|
|
3839
|
+
"advise_skills",
|
|
3823
3840
|
"compute_blast_radius",
|
|
3824
3841
|
"dispatch_skills",
|
|
3825
3842
|
"compact",
|
|
@@ -5252,15 +5269,149 @@ function createIntegrationsCommand() {
|
|
|
5252
5269
|
return command;
|
|
5253
5270
|
}
|
|
5254
5271
|
|
|
5272
|
+
// src/commands/knowledge-pipeline.ts
|
|
5273
|
+
import { Command as Command41 } from "commander";
|
|
5274
|
+
import * as path38 from "path";
|
|
5275
|
+
import chalk6 from "chalk";
|
|
5276
|
+
function createKnowledgePipelineCommand() {
|
|
5277
|
+
return new Command41("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) => {
|
|
5278
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
5279
|
+
const projectDir = globalOpts.cwd ?? process.cwd();
|
|
5280
|
+
try {
|
|
5281
|
+
const graphDir = path38.join(projectDir, ".harness", "graph");
|
|
5282
|
+
const fs41 = await import("fs/promises");
|
|
5283
|
+
await fs41.mkdir(graphDir, { recursive: true });
|
|
5284
|
+
const { GraphStore, KnowledgePipelineRunner } = await import("./dist-NCNAXUFD.js");
|
|
5285
|
+
const store = new GraphStore();
|
|
5286
|
+
try {
|
|
5287
|
+
await store.load(graphDir);
|
|
5288
|
+
} catch {
|
|
5289
|
+
}
|
|
5290
|
+
const pipelineOpts = {
|
|
5291
|
+
projectDir,
|
|
5292
|
+
fix: Boolean(opts.fix),
|
|
5293
|
+
ci: Boolean(opts.ci),
|
|
5294
|
+
...opts.domain ? { domain: opts.domain } : {},
|
|
5295
|
+
graphDir,
|
|
5296
|
+
analyzeImages: Boolean(opts.analyzeImages)
|
|
5297
|
+
};
|
|
5298
|
+
if (opts.imagePaths) {
|
|
5299
|
+
pipelineOpts.imagePaths = opts.imagePaths.split(",").map((p) => p.trim());
|
|
5300
|
+
}
|
|
5301
|
+
if (opts.analyzeImages) {
|
|
5302
|
+
try {
|
|
5303
|
+
const intelligence = await import("@harness-engineering/intelligence");
|
|
5304
|
+
const ProviderClass = intelligence.AnthropicAnalysisProvider;
|
|
5305
|
+
pipelineOpts.analysisProvider = new ProviderClass();
|
|
5306
|
+
} catch {
|
|
5307
|
+
logger.error(
|
|
5308
|
+
"Image analysis requires @harness-engineering/intelligence with ANTHROPIC_API_KEY set."
|
|
5309
|
+
);
|
|
5310
|
+
process.exit(1);
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
const runner = new KnowledgePipelineRunner(store);
|
|
5314
|
+
const result = await runner.run(
|
|
5315
|
+
pipelineOpts
|
|
5316
|
+
);
|
|
5317
|
+
if (globalOpts.json) {
|
|
5318
|
+
console.log(
|
|
5319
|
+
JSON.stringify(
|
|
5320
|
+
{
|
|
5321
|
+
verdict: result.verdict,
|
|
5322
|
+
driftScore: result.driftScore,
|
|
5323
|
+
iterations: result.iterations,
|
|
5324
|
+
findings: result.findings,
|
|
5325
|
+
extraction: result.extraction,
|
|
5326
|
+
gaps: {
|
|
5327
|
+
domains: result.gaps.domains.length,
|
|
5328
|
+
totalEntries: result.gaps.totalEntries
|
|
5329
|
+
},
|
|
5330
|
+
remediations: result.remediations,
|
|
5331
|
+
contradictions: {
|
|
5332
|
+
count: result.contradictions.contradictions.length,
|
|
5333
|
+
sourcePairCounts: result.contradictions.sourcePairCounts
|
|
5334
|
+
},
|
|
5335
|
+
coverage: {
|
|
5336
|
+
overallScore: result.coverage.overallScore,
|
|
5337
|
+
overallGrade: result.coverage.overallGrade,
|
|
5338
|
+
domains: result.coverage.domains.length
|
|
5339
|
+
}
|
|
5340
|
+
},
|
|
5341
|
+
null,
|
|
5342
|
+
2
|
|
5343
|
+
)
|
|
5344
|
+
);
|
|
5345
|
+
} else {
|
|
5346
|
+
const verdictColor = result.verdict === "pass" ? chalk6.green("PASS") : result.verdict === "warn" ? chalk6.yellow("WARN") : chalk6.red("FAIL");
|
|
5347
|
+
console.log("");
|
|
5348
|
+
console.log(`KNOWLEDGE PIPELINE -- Verdict: ${verdictColor}`);
|
|
5349
|
+
console.log("");
|
|
5350
|
+
console.log(` Drift Score: ${result.driftScore.toFixed(2)}`);
|
|
5351
|
+
console.log(
|
|
5352
|
+
` Findings: ${result.findings.new} new, ${result.findings.stale} stale, ${result.findings.drifted} drifted, ${result.findings.contradicting} contradicting`
|
|
5353
|
+
);
|
|
5354
|
+
console.log(
|
|
5355
|
+
` Extraction: ${result.extraction.codeSignals} code signals, ${result.extraction.diagrams} diagrams, ${result.extraction.linkerFacts} linker facts, ${result.extraction.businessKnowledge} business knowledge, ${result.extraction.images} images`
|
|
5356
|
+
);
|
|
5357
|
+
console.log(
|
|
5358
|
+
` Gaps: ${result.gaps.domains.length} domains, ${result.gaps.totalEntries} total entries`
|
|
5359
|
+
);
|
|
5360
|
+
if (result.iterations > 1) {
|
|
5361
|
+
console.log(` Convergence: ${result.iterations} iterations`);
|
|
5362
|
+
}
|
|
5363
|
+
if (result.remediations.length > 0) {
|
|
5364
|
+
console.log(` Remediations: ${result.remediations.length} applied`);
|
|
5365
|
+
}
|
|
5366
|
+
if (opts.checkContradictions || result.contradictions.contradictions.length > 0) {
|
|
5367
|
+
console.log("");
|
|
5368
|
+
console.log(
|
|
5369
|
+
` Contradictions: ${result.contradictions.contradictions.length} detected across ${result.contradictions.totalChecked} knowledge nodes`
|
|
5370
|
+
);
|
|
5371
|
+
for (const c of result.contradictions.contradictions) {
|
|
5372
|
+
console.log(
|
|
5373
|
+
` ${chalk6.red("!")} ${c.description} [${c.conflictType}] (${c.severity})`
|
|
5374
|
+
);
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5377
|
+
if (opts.coverage || result.coverage.domains.length > 0) {
|
|
5378
|
+
console.log("");
|
|
5379
|
+
console.log(
|
|
5380
|
+
` Coverage: ${result.coverage.overallGrade} (${result.coverage.overallScore}/100)`
|
|
5381
|
+
);
|
|
5382
|
+
for (const d of result.coverage.domains) {
|
|
5383
|
+
console.log(
|
|
5384
|
+
` ${d.domain}: ${d.grade} (${d.score}/100) \u2014 ${d.knowledgeEntries} knowledge, ${d.linkedEntities}/${d.codeEntities} code linked`
|
|
5385
|
+
);
|
|
5386
|
+
}
|
|
5387
|
+
}
|
|
5388
|
+
console.log("");
|
|
5389
|
+
}
|
|
5390
|
+
const unresolvedDrift = result.findings.drifted + result.findings.stale + result.findings.contradicting;
|
|
5391
|
+
if (opts.driftCheck && unresolvedDrift > 0) {
|
|
5392
|
+
logger.error(
|
|
5393
|
+
`${unresolvedDrift} unresolved drift findings. Run /harness:knowledge-pipeline --fix to remediate.`
|
|
5394
|
+
);
|
|
5395
|
+
process.exit(1);
|
|
5396
|
+
}
|
|
5397
|
+
} catch (error) {
|
|
5398
|
+
logger.error(
|
|
5399
|
+
`Knowledge pipeline failed: ${error instanceof Error ? error.message : String(error)}`
|
|
5400
|
+
);
|
|
5401
|
+
process.exit(1);
|
|
5402
|
+
}
|
|
5403
|
+
});
|
|
5404
|
+
}
|
|
5405
|
+
|
|
5255
5406
|
// src/commands/learnings/index.ts
|
|
5256
|
-
import { Command as
|
|
5407
|
+
import { Command as Command43 } from "commander";
|
|
5257
5408
|
|
|
5258
5409
|
// src/commands/learnings/prune.ts
|
|
5259
5410
|
init_dist();
|
|
5260
|
-
import { Command as
|
|
5261
|
-
import * as
|
|
5411
|
+
import { Command as Command42 } from "commander";
|
|
5412
|
+
import * as path39 from "path";
|
|
5262
5413
|
async function handlePrune(opts) {
|
|
5263
|
-
const projectPath =
|
|
5414
|
+
const projectPath = path39.resolve(opts.path);
|
|
5264
5415
|
const result = await pruneLearnings(projectPath, opts.stream);
|
|
5265
5416
|
if (!result.ok) {
|
|
5266
5417
|
logger.error(result.error.message);
|
|
@@ -5299,23 +5450,23 @@ function printPatternProposals(patterns) {
|
|
|
5299
5450
|
);
|
|
5300
5451
|
}
|
|
5301
5452
|
function createPruneCommand() {
|
|
5302
|
-
return new
|
|
5453
|
+
return new Command42("prune").description(
|
|
5303
5454
|
"Analyze global learnings for patterns, present improvement proposals, and archive old entries"
|
|
5304
5455
|
).option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(handlePrune);
|
|
5305
5456
|
}
|
|
5306
5457
|
|
|
5307
5458
|
// src/commands/learnings/index.ts
|
|
5308
5459
|
function createLearningsCommand() {
|
|
5309
|
-
const command = new
|
|
5460
|
+
const command = new Command43("learnings").description("Learnings management commands");
|
|
5310
5461
|
command.addCommand(createPruneCommand());
|
|
5311
5462
|
return command;
|
|
5312
5463
|
}
|
|
5313
5464
|
|
|
5314
5465
|
// src/commands/linter/index.ts
|
|
5315
|
-
import { Command as
|
|
5466
|
+
import { Command as Command46 } from "commander";
|
|
5316
5467
|
|
|
5317
5468
|
// src/commands/linter/generate.ts
|
|
5318
|
-
import { Command as
|
|
5469
|
+
import { Command as Command44 } from "commander";
|
|
5319
5470
|
function formatGenerateError(e) {
|
|
5320
5471
|
switch (e.type) {
|
|
5321
5472
|
case "parse":
|
|
@@ -5359,7 +5510,7 @@ function handleSuccess(result, useJson) {
|
|
|
5359
5510
|
Generated ${result.rulesGenerated.length} rules to ${result.outputDir}`);
|
|
5360
5511
|
}
|
|
5361
5512
|
function createGenerateCommand2() {
|
|
5362
|
-
return new
|
|
5513
|
+
return new Command44("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) => {
|
|
5363
5514
|
try {
|
|
5364
5515
|
if (options.verbose) logger.info(`Parsing config: ${options.config}`);
|
|
5365
5516
|
const result = await generate({
|
|
@@ -5381,9 +5532,9 @@ function createGenerateCommand2() {
|
|
|
5381
5532
|
}
|
|
5382
5533
|
|
|
5383
5534
|
// src/commands/linter/validate.ts
|
|
5384
|
-
import { Command as
|
|
5535
|
+
import { Command as Command45 } from "commander";
|
|
5385
5536
|
function createValidateCommand() {
|
|
5386
|
-
return new
|
|
5537
|
+
return new Command45("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) => {
|
|
5387
5538
|
try {
|
|
5388
5539
|
const result = await validate({ configPath: options.config });
|
|
5389
5540
|
if (options.json) {
|
|
@@ -5402,7 +5553,7 @@ function createValidateCommand() {
|
|
|
5402
5553
|
|
|
5403
5554
|
// src/commands/linter/index.ts
|
|
5404
5555
|
function createLinterCommand() {
|
|
5405
|
-
const linter = new
|
|
5556
|
+
const linter = new Command46("linter").description(
|
|
5406
5557
|
"Generate and validate ESLint rules from YAML config"
|
|
5407
5558
|
);
|
|
5408
5559
|
linter.addCommand(createGenerateCommand2());
|
|
@@ -5411,7 +5562,7 @@ function createLinterCommand() {
|
|
|
5411
5562
|
}
|
|
5412
5563
|
|
|
5413
5564
|
// src/commands/mcp.ts
|
|
5414
|
-
import { Command as
|
|
5565
|
+
import { Command as Command47 } from "commander";
|
|
5415
5566
|
var VALID_TIERS = /* @__PURE__ */ new Set(["core", "standard", "full"]);
|
|
5416
5567
|
function parseTier(value) {
|
|
5417
5568
|
const lower = value.toLowerCase();
|
|
@@ -5428,7 +5579,7 @@ function parseBudget(value) {
|
|
|
5428
5579
|
return n;
|
|
5429
5580
|
}
|
|
5430
5581
|
function createMcpCommand() {
|
|
5431
|
-
return new
|
|
5582
|
+
return new Command47("mcp").description("Start the MCP (Model Context Protocol) server on stdio").option("--tools <tools...>", "Only register the specified tools (used by Cursor integration)").option(
|
|
5432
5583
|
"--tier <core|standard|full>",
|
|
5433
5584
|
"Load a preset tool tier instead of all tools",
|
|
5434
5585
|
parseTier
|
|
@@ -5438,7 +5589,7 @@ function createMcpCommand() {
|
|
|
5438
5589
|
parseBudget
|
|
5439
5590
|
).action(async (opts) => {
|
|
5440
5591
|
const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
|
|
5441
|
-
import("./mcp-
|
|
5592
|
+
import("./mcp-GWVVV6LH.js"),
|
|
5442
5593
|
import("./tool-tiers-7QGZ3FKY.js")
|
|
5443
5594
|
]);
|
|
5444
5595
|
if (opts.tools && opts.tools.length > 0) {
|
|
@@ -5459,13 +5610,13 @@ function createMcpCommand() {
|
|
|
5459
5610
|
}
|
|
5460
5611
|
|
|
5461
5612
|
// src/commands/orchestrator.ts
|
|
5462
|
-
import { Command as
|
|
5463
|
-
import * as
|
|
5613
|
+
import { Command as Command48 } from "commander";
|
|
5614
|
+
import * as path40 from "path";
|
|
5464
5615
|
import { Orchestrator, WorkflowLoader, launchTUI } from "@harness-engineering/orchestrator";
|
|
5465
5616
|
function createOrchestratorCommand() {
|
|
5466
|
-
const orchestrator = new
|
|
5617
|
+
const orchestrator = new Command48("orchestrator");
|
|
5467
5618
|
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) => {
|
|
5468
|
-
const workflowPath =
|
|
5619
|
+
const workflowPath = path40.resolve(process.cwd(), opts.workflow);
|
|
5469
5620
|
const loader = new WorkflowLoader();
|
|
5470
5621
|
const result = await loader.loadWorkflow(workflowPath);
|
|
5471
5622
|
if (!result.ok) {
|
|
@@ -5498,13 +5649,13 @@ function createOrchestratorCommand() {
|
|
|
5498
5649
|
|
|
5499
5650
|
// src/commands/perf.ts
|
|
5500
5651
|
init_dist();
|
|
5501
|
-
import { Command as
|
|
5502
|
-
import * as
|
|
5652
|
+
import { Command as Command49 } from "commander";
|
|
5653
|
+
import * as path41 from "path";
|
|
5503
5654
|
function registerBenchCommand(perf) {
|
|
5504
5655
|
perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
|
|
5505
5656
|
const globalOpts = cmd.optsWithGlobals();
|
|
5506
5657
|
const cwd = process.cwd();
|
|
5507
|
-
const { BenchmarkRunner } = await import("./dist-
|
|
5658
|
+
const { BenchmarkRunner } = await import("./dist-CJDGASPP.js");
|
|
5508
5659
|
const runner = new BenchmarkRunner();
|
|
5509
5660
|
const benchFiles = runner.discover(cwd, glob2);
|
|
5510
5661
|
if (benchFiles.length === 0) {
|
|
@@ -5568,7 +5719,7 @@ async function runBaselinesShow(globalOpts) {
|
|
|
5568
5719
|
}
|
|
5569
5720
|
async function runBaselinesUpdate(globalOpts) {
|
|
5570
5721
|
const cwd = process.cwd();
|
|
5571
|
-
const { BenchmarkRunner } = await import("./dist-
|
|
5722
|
+
const { BenchmarkRunner } = await import("./dist-CJDGASPP.js");
|
|
5572
5723
|
const runner = new BenchmarkRunner();
|
|
5573
5724
|
const manager = new BaselineManager(cwd);
|
|
5574
5725
|
logger.info("Running benchmarks to update baselines...");
|
|
@@ -5609,9 +5760,9 @@ function registerReportCommand(perf) {
|
|
|
5609
5760
|
perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
|
|
5610
5761
|
const globalOpts = cmd.optsWithGlobals();
|
|
5611
5762
|
const cwd = process.cwd();
|
|
5612
|
-
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-
|
|
5763
|
+
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-CJDGASPP.js");
|
|
5613
5764
|
const analyzer = new EntropyAnalyzer2({
|
|
5614
|
-
rootDir:
|
|
5765
|
+
rootDir: path41.resolve(cwd),
|
|
5615
5766
|
analyze: { complexity: true, coupling: true }
|
|
5616
5767
|
});
|
|
5617
5768
|
const result = await analyzer.analyze();
|
|
@@ -5670,7 +5821,7 @@ function registerCriticalPathsCommand(perf) {
|
|
|
5670
5821
|
});
|
|
5671
5822
|
}
|
|
5672
5823
|
function createPerfCommand() {
|
|
5673
|
-
const perf = new
|
|
5824
|
+
const perf = new Command49("perf").description("Performance benchmark and baseline management");
|
|
5674
5825
|
registerBenchCommand(perf);
|
|
5675
5826
|
registerBaselinesCommands(perf);
|
|
5676
5827
|
registerReportCommand(perf);
|
|
@@ -5679,10 +5830,10 @@ function createPerfCommand() {
|
|
|
5679
5830
|
}
|
|
5680
5831
|
|
|
5681
5832
|
// src/commands/persona/index.ts
|
|
5682
|
-
import { Command as
|
|
5833
|
+
import { Command as Command52 } from "commander";
|
|
5683
5834
|
|
|
5684
5835
|
// src/commands/persona/list.ts
|
|
5685
|
-
import { Command as
|
|
5836
|
+
import { Command as Command50 } from "commander";
|
|
5686
5837
|
function printPersonaList(personas) {
|
|
5687
5838
|
if (personas.length === 0) {
|
|
5688
5839
|
logger.info("No personas found.");
|
|
@@ -5696,7 +5847,7 @@ function printPersonaList(personas) {
|
|
|
5696
5847
|
}
|
|
5697
5848
|
}
|
|
5698
5849
|
function createListCommand2() {
|
|
5699
|
-
return new
|
|
5850
|
+
return new Command50("list").description("List available agent personas").action(async (_opts, cmd) => {
|
|
5700
5851
|
const globalOpts = cmd.optsWithGlobals();
|
|
5701
5852
|
const personasDir = resolvePersonasDir();
|
|
5702
5853
|
const result = listPersonas(personasDir);
|
|
@@ -5716,17 +5867,17 @@ function createListCommand2() {
|
|
|
5716
5867
|
}
|
|
5717
5868
|
|
|
5718
5869
|
// src/commands/persona/generate.ts
|
|
5719
|
-
import { Command as
|
|
5870
|
+
import { Command as Command51 } from "commander";
|
|
5720
5871
|
import * as fs24 from "fs";
|
|
5721
|
-
import * as
|
|
5872
|
+
import * as path42 from "path";
|
|
5722
5873
|
function generatePersonaArtifacts(persona, outputDir, only) {
|
|
5723
5874
|
const slug = toKebabCase(persona.name);
|
|
5724
5875
|
const generated = [];
|
|
5725
5876
|
if (!only || only === "runtime") {
|
|
5726
5877
|
const result = generateRuntime(persona);
|
|
5727
5878
|
if (result.ok) {
|
|
5728
|
-
const outPath =
|
|
5729
|
-
fs24.mkdirSync(
|
|
5879
|
+
const outPath = path42.join(outputDir, `${slug}.runtime.json`);
|
|
5880
|
+
fs24.mkdirSync(path42.dirname(outPath), { recursive: true });
|
|
5730
5881
|
fs24.writeFileSync(outPath, result.value);
|
|
5731
5882
|
generated.push(outPath);
|
|
5732
5883
|
}
|
|
@@ -5734,7 +5885,7 @@ function generatePersonaArtifacts(persona, outputDir, only) {
|
|
|
5734
5885
|
if (!only || only === "agents-md") {
|
|
5735
5886
|
const result = generateAgentsMd(persona);
|
|
5736
5887
|
if (result.ok) {
|
|
5737
|
-
const outPath =
|
|
5888
|
+
const outPath = path42.join(outputDir, `${slug}.agents.md`);
|
|
5738
5889
|
fs24.writeFileSync(outPath, result.value);
|
|
5739
5890
|
generated.push(outPath);
|
|
5740
5891
|
}
|
|
@@ -5742,8 +5893,8 @@ function generatePersonaArtifacts(persona, outputDir, only) {
|
|
|
5742
5893
|
if (!only || only === "ci") {
|
|
5743
5894
|
const result = generateCIWorkflow(persona, "github");
|
|
5744
5895
|
if (result.ok) {
|
|
5745
|
-
const outPath =
|
|
5746
|
-
fs24.mkdirSync(
|
|
5896
|
+
const outPath = path42.join(outputDir, ".github", "workflows", `${slug}.yml`);
|
|
5897
|
+
fs24.mkdirSync(path42.dirname(outPath), { recursive: true });
|
|
5747
5898
|
fs24.writeFileSync(outPath, result.value);
|
|
5748
5899
|
generated.push(outPath);
|
|
5749
5900
|
}
|
|
@@ -5751,16 +5902,16 @@ function generatePersonaArtifacts(persona, outputDir, only) {
|
|
|
5751
5902
|
return generated;
|
|
5752
5903
|
}
|
|
5753
5904
|
function createGenerateCommand3() {
|
|
5754
|
-
return new
|
|
5905
|
+
return new Command51("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) => {
|
|
5755
5906
|
const globalOpts = cmd.optsWithGlobals();
|
|
5756
|
-
const personaResult = loadPersona(
|
|
5907
|
+
const personaResult = loadPersona(path42.join(resolvePersonasDir(), `${name}.yaml`));
|
|
5757
5908
|
if (!personaResult.ok) {
|
|
5758
5909
|
logger.error(personaResult.error.message);
|
|
5759
5910
|
process.exit(ExitCode.ERROR);
|
|
5760
5911
|
}
|
|
5761
5912
|
const generated = generatePersonaArtifacts(
|
|
5762
5913
|
personaResult.value,
|
|
5763
|
-
|
|
5914
|
+
path42.resolve(opts.outputDir),
|
|
5764
5915
|
opts.only
|
|
5765
5916
|
);
|
|
5766
5917
|
if (!globalOpts.quiet) {
|
|
@@ -5773,7 +5924,7 @@ function createGenerateCommand3() {
|
|
|
5773
5924
|
|
|
5774
5925
|
// src/commands/persona/index.ts
|
|
5775
5926
|
function createPersonaCommand() {
|
|
5776
|
-
const command = new
|
|
5927
|
+
const command = new Command52("persona").description("Agent persona management commands");
|
|
5777
5928
|
command.addCommand(createListCommand2());
|
|
5778
5929
|
command.addCommand(createGenerateCommand3());
|
|
5779
5930
|
return command;
|
|
@@ -5781,8 +5932,8 @@ function createPersonaCommand() {
|
|
|
5781
5932
|
|
|
5782
5933
|
// src/commands/predict.ts
|
|
5783
5934
|
init_dist();
|
|
5784
|
-
import { Command as
|
|
5785
|
-
import
|
|
5935
|
+
import { Command as Command53 } from "commander";
|
|
5936
|
+
import chalk7 from "chalk";
|
|
5786
5937
|
var CATEGORY_ORDER = [
|
|
5787
5938
|
"circular-deps",
|
|
5788
5939
|
"layer-violations",
|
|
@@ -5803,11 +5954,11 @@ function crossingLabel(weeks) {
|
|
|
5803
5954
|
function severityPrefix(severity) {
|
|
5804
5955
|
switch (severity) {
|
|
5805
5956
|
case "critical":
|
|
5806
|
-
return
|
|
5957
|
+
return chalk7.red("[critical]");
|
|
5807
5958
|
case "warning":
|
|
5808
|
-
return
|
|
5959
|
+
return chalk7.yellow("[warning]");
|
|
5809
5960
|
case "info":
|
|
5810
|
-
return
|
|
5961
|
+
return chalk7.blue("[info]");
|
|
5811
5962
|
}
|
|
5812
5963
|
}
|
|
5813
5964
|
function printCategoryTable(result) {
|
|
@@ -5887,7 +6038,7 @@ function handlePredictError(err, mode) {
|
|
|
5887
6038
|
process.exit(ExitCode.ERROR);
|
|
5888
6039
|
}
|
|
5889
6040
|
function createPredictCommand() {
|
|
5890
|
-
const command = new
|
|
6041
|
+
const command = new Command53("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) => {
|
|
5891
6042
|
const globalOpts = cmd.optsWithGlobals();
|
|
5892
6043
|
const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
|
|
5893
6044
|
try {
|
|
@@ -5911,8 +6062,8 @@ function createPredictCommand() {
|
|
|
5911
6062
|
|
|
5912
6063
|
// src/commands/publish-analyses.ts
|
|
5913
6064
|
import * as fs25 from "fs";
|
|
5914
|
-
import * as
|
|
5915
|
-
import { Command as
|
|
6065
|
+
import * as path43 from "path";
|
|
6066
|
+
import { Command as Command54 } from "commander";
|
|
5916
6067
|
init_dist();
|
|
5917
6068
|
import {
|
|
5918
6069
|
renderAnalysisComment,
|
|
@@ -5920,7 +6071,7 @@ import {
|
|
|
5920
6071
|
savePublishedIndex
|
|
5921
6072
|
} from "@harness-engineering/orchestrator";
|
|
5922
6073
|
function bootstrapTrackerCommand(opts, verb) {
|
|
5923
|
-
const projectPath =
|
|
6074
|
+
const projectPath = path43.resolve(opts.dir);
|
|
5924
6075
|
const trackerConfig = loadTrackerSyncConfig(projectPath);
|
|
5925
6076
|
if (!trackerConfig) {
|
|
5926
6077
|
logger.error(`No tracker config found in harness.config.json. Cannot ${verb}.`);
|
|
@@ -5932,7 +6083,7 @@ function bootstrapTrackerCommand(opts, verb) {
|
|
|
5932
6083
|
);
|
|
5933
6084
|
return null;
|
|
5934
6085
|
}
|
|
5935
|
-
const projectEnvPath =
|
|
6086
|
+
const projectEnvPath = path43.join(projectPath, ".env");
|
|
5936
6087
|
if (fs25.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
|
|
5937
6088
|
__require("dotenv").config({ path: projectEnvPath });
|
|
5938
6089
|
}
|
|
@@ -5944,7 +6095,7 @@ function bootstrapTrackerCommand(opts, verb) {
|
|
|
5944
6095
|
return { token, projectPath, trackerConfig };
|
|
5945
6096
|
}
|
|
5946
6097
|
function buildNameToExternalIdMap(projectPath) {
|
|
5947
|
-
const roadmapFile =
|
|
6098
|
+
const roadmapFile = path43.join(projectPath, "docs", "roadmap.md");
|
|
5948
6099
|
if (!fs25.existsSync(roadmapFile)) {
|
|
5949
6100
|
logger.error("No docs/roadmap.md found. Cannot map issue hashes to external IDs.");
|
|
5950
6101
|
return null;
|
|
@@ -6000,8 +6151,8 @@ async function runPublishAnalyses(opts) {
|
|
|
6000
6151
|
const nameToExternalId = buildNameToExternalIdMap(projectPath);
|
|
6001
6152
|
if (!nameToExternalId) return process.exit(1);
|
|
6002
6153
|
const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
|
|
6003
|
-
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-
|
|
6004
|
-
const archive = new AnalysisArchive(
|
|
6154
|
+
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-CJDGASPP.js");
|
|
6155
|
+
const archive = new AnalysisArchive(path43.join(projectPath, ".harness", "analyses"));
|
|
6005
6156
|
const analyses = await archive.list();
|
|
6006
6157
|
if (analyses.length === 0) {
|
|
6007
6158
|
logger.info("No analyses found to publish.");
|
|
@@ -6023,7 +6174,7 @@ async function runPublishAnalyses(opts) {
|
|
|
6023
6174
|
}
|
|
6024
6175
|
}
|
|
6025
6176
|
function createPublishAnalysesCommand() {
|
|
6026
|
-
const command = new
|
|
6177
|
+
const command = new Command54("publish-analyses").description(
|
|
6027
6178
|
"Publishes locally generated intelligence analyses to the external issue tracker (e.g., GitHub)"
|
|
6028
6179
|
).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
6029
6180
|
try {
|
|
@@ -6039,8 +6190,8 @@ function createPublishAnalysesCommand() {
|
|
|
6039
6190
|
}
|
|
6040
6191
|
|
|
6041
6192
|
// src/commands/recommend.ts
|
|
6042
|
-
import { Command as
|
|
6043
|
-
import
|
|
6193
|
+
import { Command as Command55 } from "commander";
|
|
6194
|
+
import chalk8 from "chalk";
|
|
6044
6195
|
async function resolveSnapshot(cwd, noCache) {
|
|
6045
6196
|
if (!noCache) {
|
|
6046
6197
|
const cached = loadCachedSnapshot(cwd);
|
|
@@ -6074,12 +6225,12 @@ async function runRecommend(options) {
|
|
|
6074
6225
|
function formatRecommendation(rec) {
|
|
6075
6226
|
const lines = [];
|
|
6076
6227
|
if (rec.urgency === "critical") {
|
|
6077
|
-
lines.push(` ${
|
|
6228
|
+
lines.push(` ${chalk8.red("[CRITICAL]")} ${rec.sequence}. ${rec.skillName}`);
|
|
6078
6229
|
} else {
|
|
6079
6230
|
lines.push(` ${rec.sequence}. ${rec.skillName} (${rec.score.toFixed(2)})`);
|
|
6080
6231
|
}
|
|
6081
6232
|
for (const reason of rec.reasons) {
|
|
6082
|
-
lines.push(` ${
|
|
6233
|
+
lines.push(` ${chalk8.dim("\u2192")} ${reason}`);
|
|
6083
6234
|
}
|
|
6084
6235
|
return lines.join("\n");
|
|
6085
6236
|
}
|
|
@@ -6103,7 +6254,7 @@ function printRecommendations(result) {
|
|
|
6103
6254
|
console.log("");
|
|
6104
6255
|
}
|
|
6105
6256
|
function createRecommendCommand() {
|
|
6106
|
-
const command = new
|
|
6257
|
+
const command = new Command55("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) => {
|
|
6107
6258
|
const globalOpts = cmd.optsWithGlobals();
|
|
6108
6259
|
const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
|
|
6109
6260
|
try {
|
|
@@ -6140,9 +6291,9 @@ function createRecommendCommand() {
|
|
|
6140
6291
|
|
|
6141
6292
|
// src/commands/scan-config.ts
|
|
6142
6293
|
init_dist();
|
|
6143
|
-
import { Command as
|
|
6294
|
+
import { Command as Command56 } from "commander";
|
|
6144
6295
|
import { existsSync as existsSync22, readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "fs";
|
|
6145
|
-
import { join as
|
|
6296
|
+
import { join as join31, relative as relative2 } from "path";
|
|
6146
6297
|
var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".gemini/settings.json", "skill.yaml"];
|
|
6147
6298
|
function stripHighSeverityPatterns(content, injectionFindings) {
|
|
6148
6299
|
const highLines = /* @__PURE__ */ new Set();
|
|
@@ -6199,7 +6350,7 @@ async function runScanConfig(targetDir, options) {
|
|
|
6199
6350
|
const scanner = new SecurityScanner(parseSecurityConfig({}));
|
|
6200
6351
|
const results = [];
|
|
6201
6352
|
for (const configFile of CONFIG_FILES) {
|
|
6202
|
-
const result = scanSingleFile(
|
|
6353
|
+
const result = scanSingleFile(join31(targetDir, configFile), targetDir, scanner, options);
|
|
6203
6354
|
if (result) results.push(result);
|
|
6204
6355
|
}
|
|
6205
6356
|
return { exitCode: computeScanExitCode(results), results };
|
|
@@ -6229,7 +6380,7 @@ function formatTextOutput(result) {
|
|
|
6229
6380
|
}
|
|
6230
6381
|
}
|
|
6231
6382
|
function createScanConfigCommand() {
|
|
6232
|
-
const command = new
|
|
6383
|
+
const command = new Command56("scan-config").description(
|
|
6233
6384
|
"Scan CLAUDE.md, AGENTS.md, .gemini/settings.json, and skill.yaml for prompt injection patterns"
|
|
6234
6385
|
).option("--path <dir>", "Target directory to scan (default: cwd)").option("--fix", "Strip high-severity patterns from files in-place").action(async (opts, cmd) => {
|
|
6235
6386
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -6246,18 +6397,18 @@ function createScanConfigCommand() {
|
|
|
6246
6397
|
}
|
|
6247
6398
|
|
|
6248
6399
|
// src/commands/setup.ts
|
|
6249
|
-
import { Command as
|
|
6400
|
+
import { Command as Command57 } from "commander";
|
|
6250
6401
|
import * as fs28 from "fs";
|
|
6251
6402
|
import * as os7 from "os";
|
|
6252
|
-
import * as
|
|
6253
|
-
import
|
|
6403
|
+
import * as path46 from "path";
|
|
6404
|
+
import chalk10 from "chalk";
|
|
6254
6405
|
|
|
6255
6406
|
// src/utils/first-run.ts
|
|
6256
6407
|
import * as fs26 from "fs";
|
|
6257
6408
|
import * as os6 from "os";
|
|
6258
|
-
import * as
|
|
6259
|
-
var HARNESS_DIR =
|
|
6260
|
-
var MARKER_FILE =
|
|
6409
|
+
import * as path44 from "path";
|
|
6410
|
+
var HARNESS_DIR = path44.join(os6.homedir(), ".harness");
|
|
6411
|
+
var MARKER_FILE = path44.join(HARNESS_DIR, ".setup-complete");
|
|
6261
6412
|
function isFirstRun() {
|
|
6262
6413
|
return !fs26.existsSync(MARKER_FILE);
|
|
6263
6414
|
}
|
|
@@ -6277,9 +6428,9 @@ function printFirstRunWelcome() {
|
|
|
6277
6428
|
|
|
6278
6429
|
// src/commands/telemetry-wizard.ts
|
|
6279
6430
|
import * as fs27 from "fs";
|
|
6280
|
-
import * as
|
|
6431
|
+
import * as path45 from "path";
|
|
6281
6432
|
import readline from "readline";
|
|
6282
|
-
import
|
|
6433
|
+
import chalk9 from "chalk";
|
|
6283
6434
|
function prompt(question) {
|
|
6284
6435
|
const rl = readline.createInterface({
|
|
6285
6436
|
input: process.stdin,
|
|
@@ -6308,7 +6459,7 @@ function isNo(answer) {
|
|
|
6308
6459
|
return answer === "n" || answer === "no";
|
|
6309
6460
|
}
|
|
6310
6461
|
function isTelemetryConfigured(cwd) {
|
|
6311
|
-
const configPath =
|
|
6462
|
+
const configPath = path45.join(cwd, "harness.config.json");
|
|
6312
6463
|
try {
|
|
6313
6464
|
const raw = JSON.parse(fs27.readFileSync(configPath, "utf-8"));
|
|
6314
6465
|
return raw.telemetry !== void 0 && raw.adoption !== void 0;
|
|
@@ -6317,7 +6468,7 @@ function isTelemetryConfigured(cwd) {
|
|
|
6317
6468
|
}
|
|
6318
6469
|
}
|
|
6319
6470
|
function writeTelemetryConfig(cwd, result) {
|
|
6320
|
-
const configPath =
|
|
6471
|
+
const configPath = path45.join(cwd, "harness.config.json");
|
|
6321
6472
|
try {
|
|
6322
6473
|
const raw = JSON.parse(fs27.readFileSync(configPath, "utf-8"));
|
|
6323
6474
|
raw.telemetry = { enabled: result.telemetryEnabled };
|
|
@@ -6330,15 +6481,15 @@ function writeTelemetryConfig(cwd, result) {
|
|
|
6330
6481
|
}
|
|
6331
6482
|
const hasIdentity = result.identity.project || result.identity.team || result.identity.alias;
|
|
6332
6483
|
if (hasIdentity) {
|
|
6333
|
-
const harnessDir =
|
|
6484
|
+
const harnessDir = path45.join(cwd, ".harness");
|
|
6334
6485
|
fs27.mkdirSync(harnessDir, { recursive: true });
|
|
6335
|
-
const telemetryFile =
|
|
6486
|
+
const telemetryFile = path45.join(harnessDir, "telemetry.json");
|
|
6336
6487
|
fs27.writeFileSync(telemetryFile, JSON.stringify({ identity: result.identity }, null, 2) + "\n");
|
|
6337
6488
|
}
|
|
6338
6489
|
}
|
|
6339
6490
|
async function promptIdentity() {
|
|
6340
6491
|
console.log(
|
|
6341
|
-
` ${
|
|
6492
|
+
` ${chalk9.cyan("Identity")} (optional) \u2014 tag telemetry with project/team/alias for filtering.`
|
|
6342
6493
|
);
|
|
6343
6494
|
console.log(" Leave blank to keep anonymous.");
|
|
6344
6495
|
const answer = await prompt(" Set identity fields? (y/N) ");
|
|
@@ -6356,20 +6507,20 @@ async function promptIdentity() {
|
|
|
6356
6507
|
async function runTelemetryWizard() {
|
|
6357
6508
|
if (!process.stdin.isTTY) return null;
|
|
6358
6509
|
console.log("");
|
|
6359
|
-
console.log(` ${
|
|
6510
|
+
console.log(` ${chalk9.bold("Telemetry Configuration")}`);
|
|
6360
6511
|
console.log("");
|
|
6361
6512
|
console.log(" Harness can collect anonymous usage data to help improve the tool.");
|
|
6362
6513
|
console.log(" You can change these settings anytime in harness.config.json.");
|
|
6363
6514
|
console.log("");
|
|
6364
6515
|
console.log(
|
|
6365
|
-
` ${
|
|
6516
|
+
` ${chalk9.cyan("Anonymous telemetry")} \u2014 error rates, command usage, performance metrics.`
|
|
6366
6517
|
);
|
|
6367
6518
|
console.log(" No code, file contents, or personally identifiable info is sent.");
|
|
6368
6519
|
const telemetryAnswer = await prompt(" Enable anonymous telemetry? (Y/n) ");
|
|
6369
6520
|
const telemetryEnabled = !isNo(telemetryAnswer);
|
|
6370
6521
|
console.log("");
|
|
6371
6522
|
console.log(
|
|
6372
|
-
` ${
|
|
6523
|
+
` ${chalk9.cyan("Adoption tracking")} \u2014 which skills are used, how often, and success rates.`
|
|
6373
6524
|
);
|
|
6374
6525
|
console.log(" Stored locally in .harness/adoption/. Never sent externally.");
|
|
6375
6526
|
const adoptionAnswer = await prompt(" Enable local adoption tracking? (Y/n) ");
|
|
@@ -6379,7 +6530,7 @@ async function runTelemetryWizard() {
|
|
|
6379
6530
|
return { telemetryEnabled, adoptionEnabled, identity };
|
|
6380
6531
|
}
|
|
6381
6532
|
async function ensureTelemetryConfigured(cwd) {
|
|
6382
|
-
const configPath =
|
|
6533
|
+
const configPath = path45.join(cwd, "harness.config.json");
|
|
6383
6534
|
if (!fs27.existsSync(configPath)) {
|
|
6384
6535
|
return { status: "warn", message: "Not a harness project \u2014 skipped telemetry configuration" };
|
|
6385
6536
|
}
|
|
@@ -6426,7 +6577,7 @@ function runSlashCommandGeneration() {
|
|
|
6426
6577
|
}
|
|
6427
6578
|
}
|
|
6428
6579
|
function detectClient(dirName) {
|
|
6429
|
-
return fs28.existsSync(
|
|
6580
|
+
return fs28.existsSync(path46.join(os7.homedir(), dirName));
|
|
6430
6581
|
}
|
|
6431
6582
|
async function runMcpSetup(cwd) {
|
|
6432
6583
|
const results = [];
|
|
@@ -6463,12 +6614,12 @@ async function runMcpSetup(cwd) {
|
|
|
6463
6614
|
return results;
|
|
6464
6615
|
}
|
|
6465
6616
|
function formatStep(result) {
|
|
6466
|
-
const icon = result.status === "pass" ?
|
|
6617
|
+
const icon = result.status === "pass" ? chalk10.green("\u2713") : result.status === "warn" ? chalk10.yellow("\u26A0") : chalk10.red("\u2717");
|
|
6467
6618
|
return ` ${icon} ${result.message}`;
|
|
6468
6619
|
}
|
|
6469
6620
|
function configureTier0Integrations(cwd) {
|
|
6470
6621
|
try {
|
|
6471
|
-
const mcpPath =
|
|
6622
|
+
const mcpPath = path46.join(cwd, ".mcp.json");
|
|
6472
6623
|
const config = readMcpConfig(mcpPath);
|
|
6473
6624
|
const tier0 = INTEGRATION_REGISTRY.filter((i) => i.tier === 0);
|
|
6474
6625
|
const added = [];
|
|
@@ -6477,9 +6628,9 @@ function configureTier0Integrations(cwd) {
|
|
|
6477
6628
|
writeMcpEntry(mcpPath, integration.name, integration.mcpConfig);
|
|
6478
6629
|
added.push(integration.displayName);
|
|
6479
6630
|
}
|
|
6480
|
-
const geminiDir =
|
|
6631
|
+
const geminiDir = path46.join(cwd, ".gemini");
|
|
6481
6632
|
if (fs28.existsSync(geminiDir)) {
|
|
6482
|
-
const geminiPath =
|
|
6633
|
+
const geminiPath = path46.join(geminiDir, "settings.json");
|
|
6483
6634
|
const geminiConfig = readMcpConfig(geminiPath);
|
|
6484
6635
|
for (const integration of tier0) {
|
|
6485
6636
|
if (!geminiConfig.mcpServers[integration.name]) {
|
|
@@ -6500,12 +6651,12 @@ function configureTier0Integrations(cwd) {
|
|
|
6500
6651
|
}
|
|
6501
6652
|
}
|
|
6502
6653
|
function ensureHooks(cwd) {
|
|
6503
|
-
const configPath =
|
|
6654
|
+
const configPath = path46.join(cwd, "harness.config.json");
|
|
6504
6655
|
if (!fs28.existsSync(configPath)) {
|
|
6505
6656
|
return { status: "warn", message: "Not a harness project \u2014 skipped hook installation" };
|
|
6506
6657
|
}
|
|
6507
6658
|
let profile = "standard";
|
|
6508
|
-
const profilePath =
|
|
6659
|
+
const profilePath = path46.join(cwd, ".harness", "hooks", "profile.json");
|
|
6509
6660
|
try {
|
|
6510
6661
|
const data = JSON.parse(fs28.readFileSync(profilePath, "utf-8"));
|
|
6511
6662
|
if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
|
|
@@ -6526,7 +6677,7 @@ function ensureHooks(cwd) {
|
|
|
6526
6677
|
}
|
|
6527
6678
|
async function runInitialGraphScan(cwd) {
|
|
6528
6679
|
try {
|
|
6529
|
-
const { runScan: runScan2 } = await import("./scan-
|
|
6680
|
+
const { runScan: runScan2 } = await import("./scan-WM7XDUF7.js");
|
|
6530
6681
|
const result = await runScan2(cwd);
|
|
6531
6682
|
return {
|
|
6532
6683
|
status: "pass",
|
|
@@ -6563,10 +6714,10 @@ async function runSetup(cwd) {
|
|
|
6563
6714
|
return { steps, success };
|
|
6564
6715
|
}
|
|
6565
6716
|
function createSetupCommand() {
|
|
6566
|
-
return new
|
|
6717
|
+
return new Command57("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
|
|
6567
6718
|
const cwd = process.cwd();
|
|
6568
6719
|
console.log("");
|
|
6569
|
-
console.log(` ${
|
|
6720
|
+
console.log(` ${chalk10.bold("harness setup")}`);
|
|
6570
6721
|
console.log("");
|
|
6571
6722
|
const { steps, success } = await runSetup(cwd);
|
|
6572
6723
|
for (const step of steps) {
|
|
@@ -6586,14 +6737,14 @@ function createSetupCommand() {
|
|
|
6586
6737
|
|
|
6587
6738
|
// src/commands/share.ts
|
|
6588
6739
|
init_dist();
|
|
6589
|
-
import { Command as
|
|
6740
|
+
import { Command as Command58 } from "commander";
|
|
6590
6741
|
import * as fs29 from "fs";
|
|
6591
|
-
import * as
|
|
6742
|
+
import * as path47 from "path";
|
|
6592
6743
|
import { parse as parseYaml } from "yaml";
|
|
6593
6744
|
var MANIFEST_FILENAME = "constraints.yaml";
|
|
6594
6745
|
async function runShareAction(projectPath, options) {
|
|
6595
|
-
const rootDir =
|
|
6596
|
-
const manifestPath =
|
|
6746
|
+
const rootDir = path47.resolve(projectPath);
|
|
6747
|
+
const manifestPath = path47.join(rootDir, MANIFEST_FILENAME);
|
|
6597
6748
|
if (!fs29.existsSync(manifestPath)) {
|
|
6598
6749
|
logger.error(
|
|
6599
6750
|
`No ${MANIFEST_FILENAME} found at ${manifestPath}.
|
|
@@ -6617,7 +6768,7 @@ Create a constraints.yaml in your project root to define what to share.`
|
|
|
6617
6768
|
process.exit(1);
|
|
6618
6769
|
}
|
|
6619
6770
|
const manifest = manifestResult.value;
|
|
6620
|
-
const configResult = resolveConfig(
|
|
6771
|
+
const configResult = resolveConfig(path47.join(rootDir, "harness.config.json"));
|
|
6621
6772
|
if (!configResult.ok) {
|
|
6622
6773
|
logger.error(configResult.error.message);
|
|
6623
6774
|
process.exit(1);
|
|
@@ -6635,8 +6786,8 @@ Create a constraints.yaml in your project root to define what to share.`
|
|
|
6635
6786
|
);
|
|
6636
6787
|
process.exit(1);
|
|
6637
6788
|
}
|
|
6638
|
-
const outputDir =
|
|
6639
|
-
const outputPath =
|
|
6789
|
+
const outputDir = path47.resolve(options.output);
|
|
6790
|
+
const outputPath = path47.join(outputDir, `${manifest.name}.harness-constraints.json`);
|
|
6640
6791
|
const writeResult = await writeConfig(outputPath, bundle);
|
|
6641
6792
|
if (!writeResult.ok) {
|
|
6642
6793
|
logger.error(`Failed to write bundle: ${writeResult.error.message}`);
|
|
@@ -6645,25 +6796,25 @@ Create a constraints.yaml in your project root to define what to share.`
|
|
|
6645
6796
|
logger.success(`Bundle written to ${outputPath}`);
|
|
6646
6797
|
}
|
|
6647
6798
|
function createShareCommand() {
|
|
6648
|
-
return new
|
|
6799
|
+
return new Command58("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) => {
|
|
6649
6800
|
await runShareAction(projectPath, options);
|
|
6650
6801
|
});
|
|
6651
6802
|
}
|
|
6652
6803
|
|
|
6653
6804
|
// src/commands/skill/index.ts
|
|
6654
|
-
import { Command as
|
|
6805
|
+
import { Command as Command66 } from "commander";
|
|
6655
6806
|
|
|
6656
6807
|
// src/commands/skill/list.ts
|
|
6657
|
-
import { Command as
|
|
6808
|
+
import { Command as Command59 } from "commander";
|
|
6658
6809
|
import * as fs30 from "fs";
|
|
6659
|
-
import * as
|
|
6810
|
+
import * as path48 from "path";
|
|
6660
6811
|
import { parse } from "yaml";
|
|
6661
6812
|
function scanDirectory(dirPath, source) {
|
|
6662
6813
|
if (!fs30.existsSync(dirPath)) return [];
|
|
6663
6814
|
const entries = fs30.readdirSync(dirPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
6664
6815
|
const skills = [];
|
|
6665
6816
|
for (const name of entries) {
|
|
6666
|
-
const yamlPath =
|
|
6817
|
+
const yamlPath = path48.join(dirPath, name, "skill.yaml");
|
|
6667
6818
|
if (!fs30.existsSync(yamlPath)) continue;
|
|
6668
6819
|
try {
|
|
6669
6820
|
const raw = fs30.readFileSync(yamlPath, "utf-8");
|
|
@@ -6684,10 +6835,10 @@ function scanDirectory(dirPath, source) {
|
|
|
6684
6835
|
}
|
|
6685
6836
|
function collectCommunitySkills(seen, allSkills) {
|
|
6686
6837
|
const globalDir = resolveGlobalSkillsDir();
|
|
6687
|
-
const skillsDir =
|
|
6688
|
-
const communityBase =
|
|
6689
|
-
const communityPlatformDir =
|
|
6690
|
-
const lockfilePath =
|
|
6838
|
+
const skillsDir = path48.dirname(globalDir);
|
|
6839
|
+
const communityBase = path48.join(skillsDir, "community");
|
|
6840
|
+
const communityPlatformDir = path48.join(communityBase, "claude-code");
|
|
6841
|
+
const lockfilePath = path48.join(communityBase, "skills-lock.json");
|
|
6691
6842
|
const lockfile = readLockfile2(lockfilePath);
|
|
6692
6843
|
const communitySkills = scanDirectory(communityPlatformDir, "community");
|
|
6693
6844
|
for (const skill of communitySkills) {
|
|
@@ -6757,7 +6908,7 @@ function printSkillsVerbose(skills) {
|
|
|
6757
6908
|
for (const s of skills) printSkillEntry(s);
|
|
6758
6909
|
}
|
|
6759
6910
|
function createListCommand3() {
|
|
6760
|
-
return new
|
|
6911
|
+
return new Command59("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) => {
|
|
6761
6912
|
const globalOpts = cmd.optsWithGlobals();
|
|
6762
6913
|
const skills = collectSkills({ filter: resolveFilter(opts) });
|
|
6763
6914
|
if (globalOpts.json) {
|
|
@@ -6772,9 +6923,9 @@ function createListCommand3() {
|
|
|
6772
6923
|
}
|
|
6773
6924
|
|
|
6774
6925
|
// src/commands/skill/run.ts
|
|
6775
|
-
import { Command as
|
|
6926
|
+
import { Command as Command60 } from "commander";
|
|
6776
6927
|
import * as fs31 from "fs";
|
|
6777
|
-
import * as
|
|
6928
|
+
import * as path49 from "path";
|
|
6778
6929
|
import { parse as parse2 } from "yaml";
|
|
6779
6930
|
|
|
6780
6931
|
// src/skill/complexity.ts
|
|
@@ -6870,7 +7021,7 @@ ${options.principles}`);
|
|
|
6870
7021
|
|
|
6871
7022
|
// src/commands/skill/run.ts
|
|
6872
7023
|
function loadSkillMetadata(skillDir) {
|
|
6873
|
-
const yamlPath =
|
|
7024
|
+
const yamlPath = path49.join(skillDir, "skill.yaml");
|
|
6874
7025
|
if (!fs31.existsSync(yamlPath)) return null;
|
|
6875
7026
|
try {
|
|
6876
7027
|
const result = SkillMetadataSchema.safeParse(parse2(fs31.readFileSync(yamlPath, "utf-8")));
|
|
@@ -6885,18 +7036,18 @@ function resolveComplexity(metadata, requested, projectPath) {
|
|
|
6885
7036
|
return requested;
|
|
6886
7037
|
}
|
|
6887
7038
|
function loadPrinciples(projectPath) {
|
|
6888
|
-
const principlesPath =
|
|
7039
|
+
const principlesPath = path49.join(projectPath, "docs", "principles.md");
|
|
6889
7040
|
return fs31.existsSync(principlesPath) ? fs31.readFileSync(principlesPath, "utf-8") : void 0;
|
|
6890
7041
|
}
|
|
6891
7042
|
function readMostRecentFileInDir(dirPath) {
|
|
6892
|
-
const files = fs31.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs31.statSync(
|
|
6893
|
-
if (files.length > 0) return fs31.readFileSync(
|
|
7043
|
+
const files = fs31.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs31.statSync(path49.join(dirPath, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
7044
|
+
if (files.length > 0) return fs31.readFileSync(path49.join(dirPath, files[0].name), "utf-8");
|
|
6894
7045
|
return void 0;
|
|
6895
7046
|
}
|
|
6896
7047
|
function loadPriorState(metadata, projectPath) {
|
|
6897
7048
|
if (!metadata?.state.persistent || metadata.state.files.length === 0) return void 0;
|
|
6898
7049
|
for (const stateFilePath of metadata.state.files) {
|
|
6899
|
-
const fullPath =
|
|
7050
|
+
const fullPath = path49.join(projectPath, stateFilePath);
|
|
6900
7051
|
if (!fs31.existsSync(fullPath)) continue;
|
|
6901
7052
|
const stat = fs31.statSync(fullPath);
|
|
6902
7053
|
if (stat.isDirectory()) return readMostRecentFileInDir(fullPath);
|
|
@@ -6920,7 +7071,7 @@ function resolvePhaseState(metadata, projectPath, phase) {
|
|
|
6920
7071
|
}
|
|
6921
7072
|
function appendProjectState(content, metadata, projectPath, hasPathOpt) {
|
|
6922
7073
|
if (!metadata?.state.persistent || !hasPathOpt) return content;
|
|
6923
|
-
const stateFile =
|
|
7074
|
+
const stateFile = path49.join(projectPath, ".harness", "state.json");
|
|
6924
7075
|
if (!fs31.existsSync(stateFile)) return content;
|
|
6925
7076
|
const stateContent = fs31.readFileSync(stateFile, "utf-8");
|
|
6926
7077
|
return content + `
|
|
@@ -6934,14 +7085,14 @@ ${stateContent}
|
|
|
6934
7085
|
}
|
|
6935
7086
|
async function runSkill(name, opts) {
|
|
6936
7087
|
const skillsDir = resolveSkillsDir();
|
|
6937
|
-
const skillDir =
|
|
7088
|
+
const skillDir = path49.join(skillsDir, name);
|
|
6938
7089
|
if (!fs31.existsSync(skillDir)) {
|
|
6939
7090
|
logger.error(`Skill not found: ${name}`);
|
|
6940
7091
|
process.exit(ExitCode.ERROR);
|
|
6941
7092
|
return;
|
|
6942
7093
|
}
|
|
6943
7094
|
const metadata = loadSkillMetadata(skillDir);
|
|
6944
|
-
const projectPath = opts.path ?
|
|
7095
|
+
const projectPath = opts.path ? path49.resolve(opts.path) : process.cwd();
|
|
6945
7096
|
const complexity = resolveComplexity(
|
|
6946
7097
|
metadata,
|
|
6947
7098
|
opts.complexity ?? "standard",
|
|
@@ -6968,7 +7119,7 @@ async function runSkill(name, opts) {
|
|
|
6968
7119
|
...stateWarning !== void 0 && { stateWarning },
|
|
6969
7120
|
...opts.party !== void 0 && { party: opts.party }
|
|
6970
7121
|
});
|
|
6971
|
-
const skillMdPath =
|
|
7122
|
+
const skillMdPath = path49.join(skillDir, "SKILL.md");
|
|
6972
7123
|
if (!fs31.existsSync(skillMdPath)) {
|
|
6973
7124
|
logger.error(`SKILL.md not found for skill: ${name}`);
|
|
6974
7125
|
process.exit(ExitCode.ERROR);
|
|
@@ -6984,13 +7135,13 @@ async function runSkill(name, opts) {
|
|
|
6984
7135
|
process.exit(ExitCode.SUCCESS);
|
|
6985
7136
|
}
|
|
6986
7137
|
function createRunCommand2() {
|
|
6987
|
-
return new
|
|
7138
|
+
return new Command60("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));
|
|
6988
7139
|
}
|
|
6989
7140
|
|
|
6990
7141
|
// src/commands/skill/validate.ts
|
|
6991
|
-
import { Command as
|
|
7142
|
+
import { Command as Command61 } from "commander";
|
|
6992
7143
|
import * as fs32 from "fs";
|
|
6993
|
-
import * as
|
|
7144
|
+
import * as path50 from "path";
|
|
6994
7145
|
import { parse as parse3 } from "yaml";
|
|
6995
7146
|
var BEHAVIORAL_REQUIRED_SECTIONS = [
|
|
6996
7147
|
"## When to Use",
|
|
@@ -7031,8 +7182,8 @@ function validateSkillMd(name, skillMdPath, skillType, errors) {
|
|
|
7031
7182
|
}
|
|
7032
7183
|
}
|
|
7033
7184
|
function validateSkillEntry(name, skillsDir, errors) {
|
|
7034
|
-
const skillDir =
|
|
7035
|
-
const yamlPath =
|
|
7185
|
+
const skillDir = path50.join(skillsDir, name);
|
|
7186
|
+
const yamlPath = path50.join(skillDir, "skill.yaml");
|
|
7036
7187
|
if (!fs32.existsSync(yamlPath)) {
|
|
7037
7188
|
errors.push(`${name}: missing skill.yaml`);
|
|
7038
7189
|
return false;
|
|
@@ -7044,7 +7195,7 @@ function validateSkillEntry(name, skillsDir, errors) {
|
|
|
7044
7195
|
errors.push(`${name}/skill.yaml: ${result.error.message}`);
|
|
7045
7196
|
return false;
|
|
7046
7197
|
}
|
|
7047
|
-
validateSkillMd(name,
|
|
7198
|
+
validateSkillMd(name, path50.join(skillDir, "SKILL.md"), result.data.type, errors);
|
|
7048
7199
|
return true;
|
|
7049
7200
|
} catch (e) {
|
|
7050
7201
|
errors.push(`${name}: parse error \u2014 ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -7052,7 +7203,7 @@ function validateSkillEntry(name, skillsDir, errors) {
|
|
|
7052
7203
|
}
|
|
7053
7204
|
}
|
|
7054
7205
|
function createValidateCommand2() {
|
|
7055
|
-
return new
|
|
7206
|
+
return new Command61("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
|
|
7056
7207
|
const globalOpts = cmd.optsWithGlobals();
|
|
7057
7208
|
const skillsDir = resolveSkillsDir();
|
|
7058
7209
|
if (!fs32.existsSync(skillsDir)) {
|
|
@@ -7082,18 +7233,18 @@ function createValidateCommand2() {
|
|
|
7082
7233
|
}
|
|
7083
7234
|
|
|
7084
7235
|
// src/commands/skill/info.ts
|
|
7085
|
-
import { Command as
|
|
7236
|
+
import { Command as Command62 } from "commander";
|
|
7086
7237
|
import * as fs33 from "fs";
|
|
7087
|
-
import * as
|
|
7238
|
+
import * as path51 from "path";
|
|
7088
7239
|
import { parse as parse4 } from "yaml";
|
|
7089
7240
|
function loadSkillMetadata2(name) {
|
|
7090
7241
|
const skillsDir = resolveSkillsDir();
|
|
7091
|
-
const skillDir =
|
|
7242
|
+
const skillDir = path51.join(skillsDir, name);
|
|
7092
7243
|
if (!fs33.existsSync(skillDir)) {
|
|
7093
7244
|
logger.error(`Skill not found: ${name}`);
|
|
7094
7245
|
return { ok: false, exitCode: ExitCode.ERROR };
|
|
7095
7246
|
}
|
|
7096
|
-
const yamlPath =
|
|
7247
|
+
const yamlPath = path51.join(skillDir, "skill.yaml");
|
|
7097
7248
|
if (!fs33.existsSync(yamlPath)) {
|
|
7098
7249
|
logger.error(`skill.yaml not found for skill: ${name}`);
|
|
7099
7250
|
return { ok: false, exitCode: ExitCode.ERROR };
|
|
@@ -7128,7 +7279,7 @@ function printSkillInfo(skill) {
|
|
|
7128
7279
|
console.log(`Persistent: ${skill.state.persistent}`);
|
|
7129
7280
|
}
|
|
7130
7281
|
function createInfoCommand() {
|
|
7131
|
-
return new
|
|
7282
|
+
return new Command62("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
|
|
7132
7283
|
const globalOpts = cmd.optsWithGlobals();
|
|
7133
7284
|
const loaded = loadSkillMetadata2(name);
|
|
7134
7285
|
if (!loaded.ok) {
|
|
@@ -7145,7 +7296,7 @@ function createInfoCommand() {
|
|
|
7145
7296
|
}
|
|
7146
7297
|
|
|
7147
7298
|
// src/commands/skill/search.ts
|
|
7148
|
-
import { Command as
|
|
7299
|
+
import { Command as Command63 } from "commander";
|
|
7149
7300
|
async function runSearch(query, opts) {
|
|
7150
7301
|
const results = await searchNpmRegistry(query, opts.registry);
|
|
7151
7302
|
return results.filter((r) => {
|
|
@@ -7190,14 +7341,14 @@ async function runSearchAction(query, opts, globalOpts) {
|
|
|
7190
7341
|
}
|
|
7191
7342
|
}
|
|
7192
7343
|
function createSearchCommand() {
|
|
7193
|
-
return new
|
|
7344
|
+
return new Command63("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) => {
|
|
7194
7345
|
await runSearchAction(query, opts, cmd.optsWithGlobals());
|
|
7195
7346
|
});
|
|
7196
7347
|
}
|
|
7197
7348
|
|
|
7198
7349
|
// src/commands/skill/create.ts
|
|
7199
|
-
import { Command as
|
|
7200
|
-
import * as
|
|
7350
|
+
import { Command as Command64 } from "commander";
|
|
7351
|
+
import * as path52 from "path";
|
|
7201
7352
|
import * as fs34 from "fs";
|
|
7202
7353
|
import YAML from "yaml";
|
|
7203
7354
|
var KEBAB_CASE_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
@@ -7282,21 +7433,21 @@ function runCreate(name, opts) {
|
|
|
7282
7433
|
if (!KEBAB_CASE_RE.test(name)) {
|
|
7283
7434
|
throw new Error(`Invalid skill name "${name}". Must be kebab-case (e.g., my-skill).`);
|
|
7284
7435
|
}
|
|
7285
|
-
const baseDir = opts.outputDir ??
|
|
7286
|
-
const skillDir =
|
|
7436
|
+
const baseDir = opts.outputDir ?? path52.join(process.cwd(), "agents", "skills", "claude-code");
|
|
7437
|
+
const skillDir = path52.join(baseDir, name);
|
|
7287
7438
|
if (fs34.existsSync(skillDir)) {
|
|
7288
7439
|
throw new Error(`Skill directory already exists: ${skillDir}`);
|
|
7289
7440
|
}
|
|
7290
7441
|
fs34.mkdirSync(skillDir, { recursive: true });
|
|
7291
7442
|
const description = opts.description || `A community skill: ${name}`;
|
|
7292
7443
|
const skillYaml = buildSkillYaml(name, opts);
|
|
7293
|
-
const skillYamlPath =
|
|
7444
|
+
const skillYamlPath = path52.join(skillDir, "skill.yaml");
|
|
7294
7445
|
fs34.writeFileSync(skillYamlPath, YAML.stringify(skillYaml));
|
|
7295
7446
|
const skillMd = buildSkillMd(name, description);
|
|
7296
|
-
const skillMdPath =
|
|
7447
|
+
const skillMdPath = path52.join(skillDir, "SKILL.md");
|
|
7297
7448
|
fs34.writeFileSync(skillMdPath, skillMd);
|
|
7298
7449
|
const readme = buildReadme(name, description);
|
|
7299
|
-
const readmePath =
|
|
7450
|
+
const readmePath = path52.join(skillDir, "README.md");
|
|
7300
7451
|
fs34.writeFileSync(readmePath, readme);
|
|
7301
7452
|
return {
|
|
7302
7453
|
name,
|
|
@@ -7311,12 +7462,12 @@ function printCreateResult(name, result) {
|
|
|
7311
7462
|
}
|
|
7312
7463
|
logger.info(`
|
|
7313
7464
|
Next steps:`);
|
|
7314
|
-
logger.info(` 1. Edit ${
|
|
7465
|
+
logger.info(` 1. Edit ${path52.join(result.directory, "SKILL.md")} with your skill content`);
|
|
7315
7466
|
logger.info(` 2. Run: harness skill validate ${name}`);
|
|
7316
7467
|
logger.info(` 3. Run: harness skills publish`);
|
|
7317
7468
|
}
|
|
7318
7469
|
function createCreateCommand() {
|
|
7319
|
-
return new
|
|
7470
|
+
return new Command64("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) => {
|
|
7320
7471
|
const globalOpts = cmd.optsWithGlobals();
|
|
7321
7472
|
try {
|
|
7322
7473
|
const result = runCreate(name, {
|
|
@@ -7339,19 +7490,19 @@ function createCreateCommand() {
|
|
|
7339
7490
|
}
|
|
7340
7491
|
|
|
7341
7492
|
// src/commands/skill/publish.ts
|
|
7342
|
-
import { Command as
|
|
7493
|
+
import { Command as Command65 } from "commander";
|
|
7343
7494
|
import * as fs36 from "fs";
|
|
7344
|
-
import * as
|
|
7495
|
+
import * as path54 from "path";
|
|
7345
7496
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
7346
7497
|
|
|
7347
7498
|
// src/registry/validator.ts
|
|
7348
7499
|
import * as fs35 from "fs";
|
|
7349
|
-
import * as
|
|
7500
|
+
import * as path53 from "path";
|
|
7350
7501
|
import { parse as parse5 } from "yaml";
|
|
7351
7502
|
import semver4 from "semver";
|
|
7352
7503
|
async function validateForPublish(skillDir, registryUrl) {
|
|
7353
7504
|
const errors = [];
|
|
7354
|
-
const skillYamlPath =
|
|
7505
|
+
const skillYamlPath = path53.join(skillDir, "skill.yaml");
|
|
7355
7506
|
if (!fs35.existsSync(skillYamlPath)) {
|
|
7356
7507
|
errors.push("skill.yaml not found. Create one with: harness skill create <name>");
|
|
7357
7508
|
return { valid: false, errors };
|
|
@@ -7380,7 +7531,7 @@ async function validateForPublish(skillDir, registryUrl) {
|
|
|
7380
7531
|
if (!skillMeta.triggers || skillMeta.triggers.length === 0) {
|
|
7381
7532
|
errors.push("At least one trigger is required. Add triggers to skill.yaml.");
|
|
7382
7533
|
}
|
|
7383
|
-
const skillMdPath =
|
|
7534
|
+
const skillMdPath = path53.join(skillDir, "SKILL.md");
|
|
7384
7535
|
if (!fs35.existsSync(skillMdPath)) {
|
|
7385
7536
|
errors.push("SKILL.md not found. Create it with content describing your skill.");
|
|
7386
7537
|
} else {
|
|
@@ -7464,11 +7615,11 @@ ${errorList}`);
|
|
|
7464
7615
|
}
|
|
7465
7616
|
const meta = validation.skillMeta;
|
|
7466
7617
|
const pkg = derivePackageJson(meta);
|
|
7467
|
-
const pkgPath =
|
|
7618
|
+
const pkgPath = path54.join(skillDir, "package.json");
|
|
7468
7619
|
fs36.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
7469
|
-
const readmePath =
|
|
7620
|
+
const readmePath = path54.join(skillDir, "README.md");
|
|
7470
7621
|
if (!fs36.existsSync(readmePath)) {
|
|
7471
|
-
const skillMdContent = fs36.readFileSync(
|
|
7622
|
+
const skillMdContent = fs36.readFileSync(path54.join(skillDir, "SKILL.md"), "utf-8");
|
|
7472
7623
|
const readme = `# ${pkg.name}
|
|
7473
7624
|
|
|
7474
7625
|
${meta.description}
|
|
@@ -7508,7 +7659,7 @@ ${skillMdContent}`;
|
|
|
7508
7659
|
};
|
|
7509
7660
|
}
|
|
7510
7661
|
function createPublishCommand() {
|
|
7511
|
-
return new
|
|
7662
|
+
return new Command65("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) => {
|
|
7512
7663
|
const globalOpts = cmd.optsWithGlobals();
|
|
7513
7664
|
const skillDir = opts.dir || process.cwd();
|
|
7514
7665
|
try {
|
|
@@ -7533,7 +7684,7 @@ function createPublishCommand() {
|
|
|
7533
7684
|
|
|
7534
7685
|
// src/commands/skill/index.ts
|
|
7535
7686
|
function createSkillCommand() {
|
|
7536
|
-
const command = new
|
|
7687
|
+
const command = new Command66("skill").description("Skill management commands");
|
|
7537
7688
|
command.addCommand(createListCommand3());
|
|
7538
7689
|
command.addCommand(createRunCommand2());
|
|
7539
7690
|
command.addCommand(createValidateCommand2());
|
|
@@ -7546,9 +7697,9 @@ function createSkillCommand() {
|
|
|
7546
7697
|
|
|
7547
7698
|
// src/commands/snapshot.ts
|
|
7548
7699
|
init_dist();
|
|
7549
|
-
import { Command as
|
|
7700
|
+
import { Command as Command67 } from "commander";
|
|
7550
7701
|
import { execSync as execSync5 } from "child_process";
|
|
7551
|
-
import
|
|
7702
|
+
import chalk11 from "chalk";
|
|
7552
7703
|
function getCommitHash3(cwd) {
|
|
7553
7704
|
try {
|
|
7554
7705
|
return execSync5("git rev-parse --short HEAD", { cwd, encoding: "utf-8" }).toString().trim();
|
|
@@ -7573,9 +7724,9 @@ function formatDelta(delta) {
|
|
|
7573
7724
|
function directionSymbol(direction) {
|
|
7574
7725
|
switch (direction) {
|
|
7575
7726
|
case "improving":
|
|
7576
|
-
return
|
|
7727
|
+
return chalk11.green("improving");
|
|
7577
7728
|
case "declining":
|
|
7578
|
-
return
|
|
7729
|
+
return chalk11.red("declining");
|
|
7579
7730
|
case "stable":
|
|
7580
7731
|
return "=";
|
|
7581
7732
|
}
|
|
@@ -7728,7 +7879,7 @@ function registerListCommand(parent) {
|
|
|
7728
7879
|
});
|
|
7729
7880
|
}
|
|
7730
7881
|
function createSnapshotCommand() {
|
|
7731
|
-
const command = new
|
|
7882
|
+
const command = new Command67("snapshot").description("Architecture timeline snapshot commands");
|
|
7732
7883
|
registerCaptureCommand(command);
|
|
7733
7884
|
registerTrendsCommand(command);
|
|
7734
7885
|
registerListCommand(command);
|
|
@@ -7736,12 +7887,12 @@ function createSnapshotCommand() {
|
|
|
7736
7887
|
}
|
|
7737
7888
|
|
|
7738
7889
|
// src/commands/state/index.ts
|
|
7739
|
-
import { Command as
|
|
7890
|
+
import { Command as Command72 } from "commander";
|
|
7740
7891
|
|
|
7741
7892
|
// src/commands/state/show.ts
|
|
7742
7893
|
init_dist();
|
|
7743
|
-
import { Command as
|
|
7744
|
-
import * as
|
|
7894
|
+
import { Command as Command68 } from "commander";
|
|
7895
|
+
import * as path55 from "path";
|
|
7745
7896
|
function printStateText(state, stream) {
|
|
7746
7897
|
if (stream) console.log(`Stream: ${stream}`);
|
|
7747
7898
|
console.log(`Schema Version: ${state.schemaVersion}`);
|
|
@@ -7765,9 +7916,9 @@ function printStateProgress(progress) {
|
|
|
7765
7916
|
}
|
|
7766
7917
|
}
|
|
7767
7918
|
function createShowCommand() {
|
|
7768
|
-
return new
|
|
7919
|
+
return new Command68("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
|
|
7769
7920
|
const globalOpts = cmd.optsWithGlobals();
|
|
7770
|
-
const result = await loadState(
|
|
7921
|
+
const result = await loadState(path55.resolve(opts.path), opts.stream);
|
|
7771
7922
|
if (!result.ok) {
|
|
7772
7923
|
logger.error(result.error.message);
|
|
7773
7924
|
process.exit(ExitCode.ERROR);
|
|
@@ -7783,9 +7934,9 @@ function createShowCommand() {
|
|
|
7783
7934
|
|
|
7784
7935
|
// src/commands/state/reset.ts
|
|
7785
7936
|
init_dist();
|
|
7786
|
-
import { Command as
|
|
7937
|
+
import { Command as Command69 } from "commander";
|
|
7787
7938
|
import * as fs37 from "fs";
|
|
7788
|
-
import * as
|
|
7939
|
+
import * as path56 from "path";
|
|
7789
7940
|
import * as readline2 from "readline";
|
|
7790
7941
|
async function resolveStatePath(projectPath, stream) {
|
|
7791
7942
|
if (stream) {
|
|
@@ -7794,9 +7945,9 @@ async function resolveStatePath(projectPath, stream) {
|
|
|
7794
7945
|
logger.error(streamResult.error.message);
|
|
7795
7946
|
process.exit(ExitCode.ERROR);
|
|
7796
7947
|
}
|
|
7797
|
-
return
|
|
7948
|
+
return path56.join(streamResult.value, "state.json");
|
|
7798
7949
|
}
|
|
7799
|
-
return
|
|
7950
|
+
return path56.join(projectPath, ".harness", "state.json");
|
|
7800
7951
|
}
|
|
7801
7952
|
async function confirmReset() {
|
|
7802
7953
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -7807,7 +7958,7 @@ async function confirmReset() {
|
|
|
7807
7958
|
return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
7808
7959
|
}
|
|
7809
7960
|
async function runReset(opts) {
|
|
7810
|
-
const projectPath =
|
|
7961
|
+
const projectPath = path56.resolve(opts.path);
|
|
7811
7962
|
const statePath = await resolveStatePath(projectPath, opts.stream);
|
|
7812
7963
|
if (!fs37.existsSync(statePath)) {
|
|
7813
7964
|
logger.info("No state file found. Nothing to reset.");
|
|
@@ -7827,16 +7978,16 @@ async function runReset(opts) {
|
|
|
7827
7978
|
process.exit(ExitCode.SUCCESS);
|
|
7828
7979
|
}
|
|
7829
7980
|
function createResetCommand() {
|
|
7830
|
-
return new
|
|
7981
|
+
return new Command69("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));
|
|
7831
7982
|
}
|
|
7832
7983
|
|
|
7833
7984
|
// src/commands/state/learn.ts
|
|
7834
7985
|
init_dist();
|
|
7835
|
-
import { Command as
|
|
7836
|
-
import * as
|
|
7986
|
+
import { Command as Command70 } from "commander";
|
|
7987
|
+
import * as path57 from "path";
|
|
7837
7988
|
function createLearnCommand() {
|
|
7838
|
-
return new
|
|
7839
|
-
const projectPath =
|
|
7989
|
+
return new Command70("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) => {
|
|
7990
|
+
const projectPath = path57.resolve(opts.path);
|
|
7840
7991
|
const result = await appendLearning(projectPath, message, void 0, void 0, opts.stream);
|
|
7841
7992
|
if (!result.ok) {
|
|
7842
7993
|
logger.error(result.error.message);
|
|
@@ -7850,10 +8001,10 @@ function createLearnCommand() {
|
|
|
7850
8001
|
|
|
7851
8002
|
// src/commands/state/streams.ts
|
|
7852
8003
|
init_dist();
|
|
7853
|
-
import { Command as
|
|
7854
|
-
import * as
|
|
8004
|
+
import { Command as Command71 } from "commander";
|
|
8005
|
+
import * as path58 from "path";
|
|
7855
8006
|
async function runListStreams(opts, globalOpts) {
|
|
7856
|
-
const projectPath =
|
|
8007
|
+
const projectPath = path58.resolve(opts.path);
|
|
7857
8008
|
const indexResult = await loadStreamIndex(projectPath);
|
|
7858
8009
|
const result = await listStreams(projectPath);
|
|
7859
8010
|
if (!result.ok) {
|
|
@@ -7874,7 +8025,7 @@ async function runListStreams(opts, globalOpts) {
|
|
|
7874
8025
|
process.exit(ExitCode.SUCCESS);
|
|
7875
8026
|
}
|
|
7876
8027
|
async function runCreateStream(name, opts) {
|
|
7877
|
-
const result = await createStream(
|
|
8028
|
+
const result = await createStream(path58.resolve(opts.path), name, opts.branch);
|
|
7878
8029
|
if (!result.ok) {
|
|
7879
8030
|
logger.error(result.error.message);
|
|
7880
8031
|
process.exit(ExitCode.ERROR);
|
|
@@ -7883,7 +8034,7 @@ async function runCreateStream(name, opts) {
|
|
|
7883
8034
|
process.exit(ExitCode.SUCCESS);
|
|
7884
8035
|
}
|
|
7885
8036
|
async function runArchiveStream(name, opts) {
|
|
7886
|
-
const result = await archiveStream(
|
|
8037
|
+
const result = await archiveStream(path58.resolve(opts.path), name);
|
|
7887
8038
|
if (!result.ok) {
|
|
7888
8039
|
logger.error(result.error.message);
|
|
7889
8040
|
process.exit(ExitCode.ERROR);
|
|
@@ -7892,7 +8043,7 @@ async function runArchiveStream(name, opts) {
|
|
|
7892
8043
|
process.exit(ExitCode.SUCCESS);
|
|
7893
8044
|
}
|
|
7894
8045
|
async function runActivateStream(name, opts) {
|
|
7895
|
-
const result = await setActiveStream(
|
|
8046
|
+
const result = await setActiveStream(path58.resolve(opts.path), name);
|
|
7896
8047
|
if (!result.ok) {
|
|
7897
8048
|
logger.error(result.error.message);
|
|
7898
8049
|
process.exit(ExitCode.ERROR);
|
|
@@ -7901,7 +8052,7 @@ async function runActivateStream(name, opts) {
|
|
|
7901
8052
|
process.exit(ExitCode.SUCCESS);
|
|
7902
8053
|
}
|
|
7903
8054
|
function createStreamsCommand() {
|
|
7904
|
-
const command = new
|
|
8055
|
+
const command = new Command71("streams").description("Manage state streams");
|
|
7905
8056
|
command.command("list").description("List all known streams").option("--path <path>", "Project root path", ".").action(async (opts, cmd) => runListStreams(opts, cmd.optsWithGlobals()));
|
|
7906
8057
|
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));
|
|
7907
8058
|
command.command("archive <name>").description("Archive a stream").option("--path <path>", "Project root path", ".").action(async (name, opts) => runArchiveStream(name, opts));
|
|
@@ -7911,7 +8062,7 @@ function createStreamsCommand() {
|
|
|
7911
8062
|
|
|
7912
8063
|
// src/commands/state/index.ts
|
|
7913
8064
|
function createStateCommand() {
|
|
7914
|
-
const command = new
|
|
8065
|
+
const command = new Command72("state").description("Project state management commands");
|
|
7915
8066
|
command.addCommand(createShowCommand());
|
|
7916
8067
|
command.addCommand(createResetCommand());
|
|
7917
8068
|
command.addCommand(createLearnCommand());
|
|
@@ -7921,8 +8072,8 @@ function createStateCommand() {
|
|
|
7921
8072
|
|
|
7922
8073
|
// src/commands/sync-analyses.ts
|
|
7923
8074
|
import * as fs38 from "fs";
|
|
7924
|
-
import * as
|
|
7925
|
-
import { Command as
|
|
8075
|
+
import * as path59 from "path";
|
|
8076
|
+
import { Command as Command73 } from "commander";
|
|
7926
8077
|
init_dist();
|
|
7927
8078
|
function isValidRecord(record) {
|
|
7928
8079
|
return typeof record.issueId === "string" && !!record.issueId && typeof record.identifier === "string" && !!record.identifier && typeof record.analyzedAt === "string" && !/[/\\]/.test(record.issueId);
|
|
@@ -7948,7 +8099,7 @@ function extractAnalysisFromComments(comments) {
|
|
|
7948
8099
|
return null;
|
|
7949
8100
|
}
|
|
7950
8101
|
function bootstrapTrackerCommand2(opts, verb) {
|
|
7951
|
-
const projectPath =
|
|
8102
|
+
const projectPath = path59.resolve(opts.dir);
|
|
7952
8103
|
const trackerConfig = loadTrackerSyncConfig(projectPath);
|
|
7953
8104
|
if (!trackerConfig) {
|
|
7954
8105
|
logger.error(`No tracker config found in harness.config.json. Cannot ${verb}.`);
|
|
@@ -7960,7 +8111,7 @@ function bootstrapTrackerCommand2(opts, verb) {
|
|
|
7960
8111
|
);
|
|
7961
8112
|
return null;
|
|
7962
8113
|
}
|
|
7963
|
-
const projectEnvPath =
|
|
8114
|
+
const projectEnvPath = path59.join(projectPath, ".env");
|
|
7964
8115
|
if (fs38.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
|
|
7965
8116
|
__require("dotenv").config({ path: projectEnvPath });
|
|
7966
8117
|
}
|
|
@@ -7972,7 +8123,7 @@ function bootstrapTrackerCommand2(opts, verb) {
|
|
|
7972
8123
|
return { token, projectPath, trackerConfig };
|
|
7973
8124
|
}
|
|
7974
8125
|
function loadRoadmapFeatures(projectPath) {
|
|
7975
|
-
const roadmapFile =
|
|
8126
|
+
const roadmapFile = path59.join(projectPath, "docs", "roadmap.md");
|
|
7976
8127
|
if (!fs38.existsSync(roadmapFile)) {
|
|
7977
8128
|
logger.error("No docs/roadmap.md found. Cannot discover features with externalIds.");
|
|
7978
8129
|
return null;
|
|
@@ -8029,9 +8180,9 @@ async function runSyncAnalyses(opts) {
|
|
|
8029
8180
|
return;
|
|
8030
8181
|
}
|
|
8031
8182
|
const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
|
|
8032
|
-
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-
|
|
8183
|
+
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-CJDGASPP.js");
|
|
8033
8184
|
const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
|
|
8034
|
-
const archive = new AnalysisArchive(
|
|
8185
|
+
const archive = new AnalysisArchive(path59.join(projectPath, ".harness", "analyses"));
|
|
8035
8186
|
const publishedIndex = loadPublishedIndex2(projectPath);
|
|
8036
8187
|
const { syncedCount, skippedCount, warnCount } = await syncFeatureAnalyses(
|
|
8037
8188
|
features,
|
|
@@ -8051,7 +8202,7 @@ async function runSyncAnalyses(opts) {
|
|
|
8051
8202
|
}
|
|
8052
8203
|
}
|
|
8053
8204
|
function createSyncAnalysesCommand() {
|
|
8054
|
-
const command = new
|
|
8205
|
+
const command = new Command73("sync-analyses").description(
|
|
8055
8206
|
"Pull published intelligence analyses from the external issue tracker into the local .harness/analyses/ directory"
|
|
8056
8207
|
).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
8057
8208
|
try {
|
|
@@ -8066,7 +8217,7 @@ function createSyncAnalysesCommand() {
|
|
|
8066
8217
|
|
|
8067
8218
|
// src/commands/taint.ts
|
|
8068
8219
|
init_dist();
|
|
8069
|
-
import { Command as
|
|
8220
|
+
import { Command as Command74 } from "commander";
|
|
8070
8221
|
function getProjectRoot() {
|
|
8071
8222
|
return process.cwd();
|
|
8072
8223
|
}
|
|
@@ -8138,26 +8289,26 @@ function registerStatusCommand(taint) {
|
|
|
8138
8289
|
});
|
|
8139
8290
|
}
|
|
8140
8291
|
function createTaintCommand() {
|
|
8141
|
-
const taint = new
|
|
8292
|
+
const taint = new Command74("taint").description("Manage sentinel session taint state");
|
|
8142
8293
|
registerClearCommand(taint);
|
|
8143
8294
|
registerStatusCommand(taint);
|
|
8144
8295
|
return taint;
|
|
8145
8296
|
}
|
|
8146
8297
|
|
|
8147
8298
|
// src/commands/telemetry/index.ts
|
|
8148
|
-
import { Command as
|
|
8299
|
+
import { Command as Command78 } from "commander";
|
|
8149
8300
|
|
|
8150
8301
|
// src/commands/telemetry/identify.ts
|
|
8151
8302
|
init_dist();
|
|
8152
|
-
import { Command as
|
|
8303
|
+
import { Command as Command75 } from "commander";
|
|
8153
8304
|
import * as fs39 from "fs";
|
|
8154
|
-
import * as
|
|
8305
|
+
import * as path60 from "path";
|
|
8155
8306
|
function telemetryFilePath(cwd) {
|
|
8156
|
-
return
|
|
8307
|
+
return path60.join(cwd, ".harness", "telemetry.json");
|
|
8157
8308
|
}
|
|
8158
8309
|
function writeTelemetryFile(cwd, data) {
|
|
8159
8310
|
const filePath = telemetryFilePath(cwd);
|
|
8160
|
-
const dir =
|
|
8311
|
+
const dir = path60.dirname(filePath);
|
|
8161
8312
|
fs39.mkdirSync(dir, { recursive: true });
|
|
8162
8313
|
fs39.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
8163
8314
|
}
|
|
@@ -8173,7 +8324,7 @@ function printIdentity(identity) {
|
|
|
8173
8324
|
}
|
|
8174
8325
|
}
|
|
8175
8326
|
function createIdentifyCommand() {
|
|
8176
|
-
const cmd = new
|
|
8327
|
+
const cmd = new Command75("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) => {
|
|
8177
8328
|
const cwd = process.cwd();
|
|
8178
8329
|
if (opts.clear) {
|
|
8179
8330
|
writeTelemetryFile(cwd, { identity: {} });
|
|
@@ -8198,7 +8349,7 @@ function createIdentifyCommand() {
|
|
|
8198
8349
|
|
|
8199
8350
|
// src/commands/telemetry/status.ts
|
|
8200
8351
|
init_dist();
|
|
8201
|
-
import { Command as
|
|
8352
|
+
import { Command as Command76 } from "commander";
|
|
8202
8353
|
function gatherEnvOverrides() {
|
|
8203
8354
|
const overrides = {};
|
|
8204
8355
|
if (process.env.DO_NOT_TRACK) overrides.DO_NOT_TRACK = process.env.DO_NOT_TRACK;
|
|
@@ -8240,7 +8391,7 @@ function printHumanStatus(result) {
|
|
|
8240
8391
|
printEnvOverrides(result.envOverrides);
|
|
8241
8392
|
}
|
|
8242
8393
|
function createStatusCommand() {
|
|
8243
|
-
const cmd = new
|
|
8394
|
+
const cmd = new Command76("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
|
|
8244
8395
|
const cwd = process.cwd();
|
|
8245
8396
|
const envOverrides = gatherEnvOverrides();
|
|
8246
8397
|
const consent = resolveConsent(cwd, void 0);
|
|
@@ -8273,11 +8424,11 @@ function createStatusCommand() {
|
|
|
8273
8424
|
|
|
8274
8425
|
// src/commands/telemetry/test.ts
|
|
8275
8426
|
init_dist();
|
|
8276
|
-
import { Command as
|
|
8427
|
+
import { Command as Command77 } from "commander";
|
|
8277
8428
|
|
|
8278
8429
|
// src/bin/command-telemetry.ts
|
|
8279
8430
|
import { existsSync as existsSync36, readFileSync as readFileSync25, mkdirSync as mkdirSync15, appendFileSync, writeFileSync as writeFileSync18 } from "fs";
|
|
8280
|
-
import { join as
|
|
8431
|
+
import { join as join46, parse as parsePath, resolve as resolve33 } from "path";
|
|
8281
8432
|
import { spawn as spawn2 } from "child_process";
|
|
8282
8433
|
var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
|
|
8283
8434
|
var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
|
|
@@ -8285,7 +8436,7 @@ function findProjectRoot(cwd) {
|
|
|
8285
8436
|
let dir = resolve33(cwd);
|
|
8286
8437
|
const { root } = parsePath(dir);
|
|
8287
8438
|
while (dir !== root) {
|
|
8288
|
-
if (existsSync36(
|
|
8439
|
+
if (existsSync36(join46(dir, "harness.config.json"))) return dir;
|
|
8289
8440
|
dir = resolve33(dir, "..");
|
|
8290
8441
|
}
|
|
8291
8442
|
return cwd;
|
|
@@ -8323,7 +8474,7 @@ function resolveCommandName(cmd) {
|
|
|
8323
8474
|
}
|
|
8324
8475
|
function writeCommandRecordSync(cwd, command, duration, outcome) {
|
|
8325
8476
|
try {
|
|
8326
|
-
const metricsDir =
|
|
8477
|
+
const metricsDir = join46(cwd, ".harness", "metrics");
|
|
8327
8478
|
mkdirSync15(metricsDir, { recursive: true });
|
|
8328
8479
|
const record = {
|
|
8329
8480
|
skill: command,
|
|
@@ -8333,13 +8484,13 @@ function writeCommandRecordSync(cwd, command, duration, outcome) {
|
|
|
8333
8484
|
outcome,
|
|
8334
8485
|
phasesReached: []
|
|
8335
8486
|
};
|
|
8336
|
-
const adoptionFile =
|
|
8487
|
+
const adoptionFile = join46(metricsDir, "adoption.jsonl");
|
|
8337
8488
|
appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
|
|
8338
8489
|
} catch {
|
|
8339
8490
|
}
|
|
8340
8491
|
}
|
|
8341
8492
|
function isTelemetryDisabledByConfig(cwd) {
|
|
8342
|
-
const configPath =
|
|
8493
|
+
const configPath = join46(cwd, "harness.config.json");
|
|
8343
8494
|
if (!existsSync36(configPath)) return false;
|
|
8344
8495
|
try {
|
|
8345
8496
|
const config = JSON.parse(readFileSync25(configPath, "utf-8"));
|
|
@@ -8354,10 +8505,10 @@ function isTelemetryOptedOut(cwd) {
|
|
|
8354
8505
|
}
|
|
8355
8506
|
function flushTelemetryBackground(cwd) {
|
|
8356
8507
|
try {
|
|
8357
|
-
const adoptionFile =
|
|
8508
|
+
const adoptionFile = join46(cwd, ".harness", "metrics", "adoption.jsonl");
|
|
8358
8509
|
if (!existsSync36(adoptionFile)) return;
|
|
8359
8510
|
if (isTelemetryOptedOut(cwd)) return;
|
|
8360
|
-
const reporterPath =
|
|
8511
|
+
const reporterPath = join46(cwd, ".harness", "hooks", "telemetry-reporter.js");
|
|
8361
8512
|
if (!existsSync36(reporterPath)) return;
|
|
8362
8513
|
const child = spawn2(process.execPath, [reporterPath], {
|
|
8363
8514
|
cwd,
|
|
@@ -8395,7 +8546,7 @@ function reportTestSuccess(status, distinctId, identity) {
|
|
|
8395
8546
|
if (identity.team) logger.info(` team: ${identity.team}`);
|
|
8396
8547
|
}
|
|
8397
8548
|
function createTestCommand() {
|
|
8398
|
-
return new
|
|
8549
|
+
return new Command77("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
|
|
8399
8550
|
const cwd = process.cwd();
|
|
8400
8551
|
const consent = resolveConsent(cwd, void 0);
|
|
8401
8552
|
if (!consent.allowed) {
|
|
@@ -8432,7 +8583,7 @@ function createTestCommand() {
|
|
|
8432
8583
|
|
|
8433
8584
|
// src/commands/telemetry/index.ts
|
|
8434
8585
|
function createTelemetryCommand() {
|
|
8435
|
-
const command = new
|
|
8586
|
+
const command = new Command78("telemetry").description("Telemetry identity and status management");
|
|
8436
8587
|
command.addCommand(createIdentifyCommand());
|
|
8437
8588
|
command.addCommand(createStatusCommand());
|
|
8438
8589
|
command.addCommand(createTestCommand());
|
|
@@ -8440,8 +8591,8 @@ function createTelemetryCommand() {
|
|
|
8440
8591
|
}
|
|
8441
8592
|
|
|
8442
8593
|
// src/commands/traceability.ts
|
|
8443
|
-
import { Command as
|
|
8444
|
-
import
|
|
8594
|
+
import { Command as Command79 } from "commander";
|
|
8595
|
+
import chalk12 from "chalk";
|
|
8445
8596
|
function confidenceLabel(maxConfidence) {
|
|
8446
8597
|
if (maxConfidence >= 0.8) return "explicit";
|
|
8447
8598
|
if (maxConfidence > 0) return "inferred";
|
|
@@ -8450,13 +8601,13 @@ function confidenceLabel(maxConfidence) {
|
|
|
8450
8601
|
function statusIcon(status) {
|
|
8451
8602
|
switch (status) {
|
|
8452
8603
|
case "full":
|
|
8453
|
-
return
|
|
8604
|
+
return chalk12.green("\u2713 full");
|
|
8454
8605
|
case "code-only":
|
|
8455
|
-
return
|
|
8606
|
+
return chalk12.yellow("\u25D0 code-only");
|
|
8456
8607
|
case "test-only":
|
|
8457
|
-
return
|
|
8608
|
+
return chalk12.yellow("\u25D0 test-only");
|
|
8458
8609
|
case "none":
|
|
8459
|
-
return
|
|
8610
|
+
return chalk12.red("\u2717 none");
|
|
8460
8611
|
default:
|
|
8461
8612
|
return status;
|
|
8462
8613
|
}
|
|
@@ -8498,14 +8649,14 @@ function handleEmptyResults(mode) {
|
|
|
8498
8649
|
}
|
|
8499
8650
|
function printResultTable(result, mode) {
|
|
8500
8651
|
const specLabel = result.specPath || result.featureName || "Unknown";
|
|
8501
|
-
console.log(` ${
|
|
8652
|
+
console.log(` ${chalk12.cyan(specLabel)} ${chalk12.dim(`(${result.summary.total} requirements)`)}`);
|
|
8502
8653
|
console.log("");
|
|
8503
8654
|
const numWidth = 4;
|
|
8504
8655
|
const nameWidth = mode === OutputMode.VERBOSE ? 44 : 36;
|
|
8505
8656
|
const codeWidth = 6;
|
|
8506
8657
|
const testWidth = 7;
|
|
8507
8658
|
const confWidth = 12;
|
|
8508
|
-
const header =
|
|
8659
|
+
const header = chalk12.dim(
|
|
8509
8660
|
` ${pad("#", numWidth)}${pad("Requirement", nameWidth)}${pad("Code", codeWidth)}${pad("Tests", testWidth)}${pad("Confidence", confWidth)}Status`
|
|
8510
8661
|
);
|
|
8511
8662
|
console.log(header);
|
|
@@ -8534,10 +8685,10 @@ function printRequirementRows(requirements, mode, cols) {
|
|
|
8534
8685
|
);
|
|
8535
8686
|
if (mode === OutputMode.VERBOSE) {
|
|
8536
8687
|
for (const f of req.codeFiles) {
|
|
8537
|
-
console.log(
|
|
8688
|
+
console.log(chalk12.dim(` code: ${f.path} (${f.method})`));
|
|
8538
8689
|
}
|
|
8539
8690
|
for (const f of req.testFiles) {
|
|
8540
|
-
console.log(
|
|
8691
|
+
console.log(chalk12.dim(` test: ${f.path} (${f.method})`));
|
|
8541
8692
|
}
|
|
8542
8693
|
}
|
|
8543
8694
|
}
|
|
@@ -8548,7 +8699,7 @@ function printCoverageSummary(summary) {
|
|
|
8548
8699
|
const codePct = s.total > 0 ? Math.round(s.withCode / s.total * 100) : 0;
|
|
8549
8700
|
const testPct = s.total > 0 ? Math.round(s.withTests / s.total * 100) : 0;
|
|
8550
8701
|
console.log(
|
|
8551
|
-
` ${
|
|
8702
|
+
` ${chalk12.bold("Coverage:")} ${fullyPct}% fully traced (${s.fullyTraced}/${s.total}), ${codePct}% with code (${s.withCode}/${s.total}), ${testPct}% with tests (${s.withTests}/${s.total})`
|
|
8552
8703
|
);
|
|
8553
8704
|
}
|
|
8554
8705
|
async function runTraceability(options) {
|
|
@@ -8556,7 +8707,7 @@ async function runTraceability(options) {
|
|
|
8556
8707
|
const projectPath = process.cwd();
|
|
8557
8708
|
const store = await loadGraphStore(projectPath);
|
|
8558
8709
|
if (!store) handleNoStore(mode);
|
|
8559
|
-
const graphModule = await import("./dist-
|
|
8710
|
+
const graphModule = await import("./dist-NCNAXUFD.js");
|
|
8560
8711
|
const filterOptions = buildFilterOptions(options);
|
|
8561
8712
|
const results = graphModule.queryTraceability(store, filterOptions);
|
|
8562
8713
|
if (results.length === 0) handleEmptyResults(mode);
|
|
@@ -8564,14 +8715,14 @@ async function runTraceability(options) {
|
|
|
8564
8715
|
console.log(JSON.stringify(results, null, 2));
|
|
8565
8716
|
} else {
|
|
8566
8717
|
console.log("");
|
|
8567
|
-
console.log(
|
|
8718
|
+
console.log(chalk12.bold("Spec-to-Implementation Traceability"));
|
|
8568
8719
|
console.log("");
|
|
8569
8720
|
for (const result of results) printResultTable(result, mode);
|
|
8570
8721
|
}
|
|
8571
8722
|
process.exit(ExitCode.SUCCESS);
|
|
8572
8723
|
}
|
|
8573
8724
|
function createTraceabilityCommand() {
|
|
8574
|
-
return new
|
|
8725
|
+
return new Command79("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) => {
|
|
8575
8726
|
const globalOpts = cmd.optsWithGlobals();
|
|
8576
8727
|
await runTraceability({
|
|
8577
8728
|
spec: opts.spec,
|
|
@@ -8584,15 +8735,15 @@ function createTraceabilityCommand() {
|
|
|
8584
8735
|
}
|
|
8585
8736
|
|
|
8586
8737
|
// src/commands/uninstall.ts
|
|
8587
|
-
import * as
|
|
8588
|
-
import { Command as
|
|
8738
|
+
import * as path61 from "path";
|
|
8739
|
+
import { Command as Command80 } from "commander";
|
|
8589
8740
|
async function runUninstall(skillName, options) {
|
|
8590
8741
|
const packageName = resolvePackageName(skillName);
|
|
8591
8742
|
const shortName = extractSkillName(packageName);
|
|
8592
8743
|
const globalDir = resolveGlobalSkillsDir();
|
|
8593
|
-
const skillsDir =
|
|
8594
|
-
const communityBase =
|
|
8595
|
-
const lockfilePath =
|
|
8744
|
+
const skillsDir = path61.dirname(globalDir);
|
|
8745
|
+
const communityBase = path61.join(skillsDir, "community");
|
|
8746
|
+
const lockfilePath = path61.join(communityBase, "skills-lock.json");
|
|
8596
8747
|
const lockfile = readLockfile2(lockfilePath);
|
|
8597
8748
|
const entry = lockfile.skills[packageName];
|
|
8598
8749
|
if (!entry) {
|
|
@@ -8622,7 +8773,7 @@ async function runUninstall(skillName, options) {
|
|
|
8622
8773
|
return result;
|
|
8623
8774
|
}
|
|
8624
8775
|
function createUninstallCommand() {
|
|
8625
|
-
const cmd = new
|
|
8776
|
+
const cmd = new Command80("uninstall");
|
|
8626
8777
|
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) => {
|
|
8627
8778
|
try {
|
|
8628
8779
|
const result = await runUninstall(skill, opts);
|
|
@@ -8643,8 +8794,8 @@ function createUninstallCommand() {
|
|
|
8643
8794
|
// src/commands/uninstall-constraints.ts
|
|
8644
8795
|
init_dist();
|
|
8645
8796
|
import * as fs40 from "fs/promises";
|
|
8646
|
-
import * as
|
|
8647
|
-
import { Command as
|
|
8797
|
+
import * as path62 from "path";
|
|
8798
|
+
import { Command as Command81 } from "commander";
|
|
8648
8799
|
async function runUninstallConstraints(options) {
|
|
8649
8800
|
const { packageName, configPath, lockfilePath } = options;
|
|
8650
8801
|
const lockfileResult = await readLockfile(lockfilePath);
|
|
@@ -8701,11 +8852,11 @@ async function runUninstallConstraints(options) {
|
|
|
8701
8852
|
};
|
|
8702
8853
|
}
|
|
8703
8854
|
function createUninstallConstraintsCommand() {
|
|
8704
|
-
const cmd = new
|
|
8855
|
+
const cmd = new Command81("uninstall-constraints");
|
|
8705
8856
|
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) => {
|
|
8706
8857
|
let configPath;
|
|
8707
8858
|
if (opts.config) {
|
|
8708
|
-
configPath =
|
|
8859
|
+
configPath = path62.resolve(opts.config);
|
|
8709
8860
|
} else {
|
|
8710
8861
|
const found = findConfigFile();
|
|
8711
8862
|
if (!found.ok) {
|
|
@@ -8714,8 +8865,8 @@ function createUninstallConstraintsCommand() {
|
|
|
8714
8865
|
}
|
|
8715
8866
|
configPath = found.value;
|
|
8716
8867
|
}
|
|
8717
|
-
const projectRoot =
|
|
8718
|
-
const lockfilePath =
|
|
8868
|
+
const projectRoot = path62.dirname(configPath);
|
|
8869
|
+
const lockfilePath = path62.join(projectRoot, ".harness", "constraints.lock.json");
|
|
8719
8870
|
const result = await runUninstallConstraints({
|
|
8720
8871
|
packageName: name,
|
|
8721
8872
|
configPath,
|
|
@@ -8740,13 +8891,13 @@ function createUninstallConstraintsCommand() {
|
|
|
8740
8891
|
}
|
|
8741
8892
|
|
|
8742
8893
|
// src/commands/update.ts
|
|
8743
|
-
import { Command as
|
|
8894
|
+
import { Command as Command82 } from "commander";
|
|
8744
8895
|
import { execFile, execFileSync as execFileSync6 } from "child_process";
|
|
8745
8896
|
import { realpathSync, existsSync as existsSync37, readFileSync as readFileSync26 } from "fs";
|
|
8746
|
-
import { join as
|
|
8897
|
+
import { join as join49 } from "path";
|
|
8747
8898
|
import { promisify } from "util";
|
|
8748
8899
|
import readline3 from "readline";
|
|
8749
|
-
import
|
|
8900
|
+
import chalk13 from "chalk";
|
|
8750
8901
|
function detectPackageManager() {
|
|
8751
8902
|
try {
|
|
8752
8903
|
const argv1 = process.argv[1];
|
|
@@ -8827,10 +8978,10 @@ async function ensureTelemetryIfNeeded() {
|
|
|
8827
8978
|
}
|
|
8828
8979
|
function refreshHooks() {
|
|
8829
8980
|
const cwd = process.cwd();
|
|
8830
|
-
const configPath =
|
|
8981
|
+
const configPath = join49(cwd, "harness.config.json");
|
|
8831
8982
|
if (!existsSync37(configPath)) return;
|
|
8832
8983
|
let profile = "standard";
|
|
8833
|
-
const profilePath =
|
|
8984
|
+
const profilePath = join49(cwd, ".harness", "hooks", "profile.json");
|
|
8834
8985
|
try {
|
|
8835
8986
|
const data = JSON.parse(readFileSync26(profilePath, "utf-8"));
|
|
8836
8987
|
if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
|
|
@@ -8852,7 +9003,7 @@ function runLocalGraphScan() {
|
|
|
8852
9003
|
execFileSync6("harness", ["graph", "scan", "."], { stdio: "inherit" });
|
|
8853
9004
|
} catch {
|
|
8854
9005
|
logger.warn("Graph scan failed. Run manually:");
|
|
8855
|
-
console.log(` ${
|
|
9006
|
+
console.log(` ${chalk13.cyan("harness graph scan .")}`);
|
|
8856
9007
|
}
|
|
8857
9008
|
}
|
|
8858
9009
|
async function offerRegeneration() {
|
|
@@ -8869,7 +9020,7 @@ async function offerRegeneration() {
|
|
|
8869
9020
|
});
|
|
8870
9021
|
} catch {
|
|
8871
9022
|
logger.warn("Generation failed. Run manually:");
|
|
8872
|
-
console.log(` ${
|
|
9023
|
+
console.log(` ${chalk13.cyan(`harness generate${isGlobal ? " --global" : ""}`)}`);
|
|
8873
9024
|
}
|
|
8874
9025
|
if (!isGlobal) {
|
|
8875
9026
|
runLocalGraphScan();
|
|
@@ -8932,8 +9083,8 @@ async function runUpdateAction(opts, globalOpts) {
|
|
|
8932
9083
|
console.log("");
|
|
8933
9084
|
for (const { pkg, current, latest } of outdated) {
|
|
8934
9085
|
const shortName = pkg.replace("@harness-engineering/", "");
|
|
8935
|
-
const currentStr = current ?
|
|
8936
|
-
logger.info(`${shortName}: ${currentStr} \u2192 ${
|
|
9086
|
+
const currentStr = current ? chalk13.dim(`v${current}`) : chalk13.dim("not installed");
|
|
9087
|
+
logger.info(`${shortName}: ${currentStr} \u2192 ${chalk13.green(`v${latest}`)}`);
|
|
8937
9088
|
}
|
|
8938
9089
|
console.log("");
|
|
8939
9090
|
}
|
|
@@ -8949,7 +9100,7 @@ async function runUpdateAction(opts, globalOpts) {
|
|
|
8949
9100
|
} catch {
|
|
8950
9101
|
console.log("");
|
|
8951
9102
|
logger.error("Update failed. You can try manually:");
|
|
8952
|
-
console.log(` ${
|
|
9103
|
+
console.log(` ${chalk13.cyan(installCmd)}`);
|
|
8953
9104
|
process.exit(ExitCode.ERROR);
|
|
8954
9105
|
}
|
|
8955
9106
|
refreshHooks();
|
|
@@ -8958,7 +9109,7 @@ async function runUpdateAction(opts, globalOpts) {
|
|
|
8958
9109
|
process.exit(ExitCode.SUCCESS);
|
|
8959
9110
|
}
|
|
8960
9111
|
function createUpdateCommand() {
|
|
8961
|
-
return new
|
|
9112
|
+
return new Command82("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(
|
|
8962
9113
|
"--regenerate",
|
|
8963
9114
|
"Only regenerate slash commands and agent definitions (skip package updates)"
|
|
8964
9115
|
).action(async (opts, cmd) => {
|
|
@@ -8968,9 +9119,9 @@ function createUpdateCommand() {
|
|
|
8968
9119
|
}
|
|
8969
9120
|
|
|
8970
9121
|
// src/commands/usage.ts
|
|
8971
|
-
import { Command as
|
|
9122
|
+
import { Command as Command83 } from "commander";
|
|
8972
9123
|
async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
|
|
8973
|
-
const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-
|
|
9124
|
+
const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-CJDGASPP.js");
|
|
8974
9125
|
const records = readCostRecords(cwd);
|
|
8975
9126
|
if (includeClaudeSessions) {
|
|
8976
9127
|
const ccRecords = parseCCRecords();
|
|
@@ -9063,7 +9214,7 @@ function registerDailyCommand(usage) {
|
|
|
9063
9214
|
else logger.info("No usage data found. Run some harness sessions first.");
|
|
9064
9215
|
return;
|
|
9065
9216
|
}
|
|
9066
|
-
const { aggregateByDay } = await import("./dist-
|
|
9217
|
+
const { aggregateByDay } = await import("./dist-CJDGASPP.js");
|
|
9067
9218
|
const limited = aggregateByDay(records).slice(0, days);
|
|
9068
9219
|
if (globalOpts.json) {
|
|
9069
9220
|
console.log(
|
|
@@ -9092,7 +9243,7 @@ function registerSessionsCommand(usage) {
|
|
|
9092
9243
|
}
|
|
9093
9244
|
return;
|
|
9094
9245
|
}
|
|
9095
|
-
const { aggregateBySession } = await import("./dist-
|
|
9246
|
+
const { aggregateBySession } = await import("./dist-CJDGASPP.js");
|
|
9096
9247
|
const sessionData = aggregateBySession(records);
|
|
9097
9248
|
const limited = sessionData.slice(0, limit);
|
|
9098
9249
|
if (globalOpts.json) {
|
|
@@ -9172,7 +9323,7 @@ function registerSessionCommand(usage) {
|
|
|
9172
9323
|
cwd,
|
|
9173
9324
|
globalOpts.includeClaudeSessions
|
|
9174
9325
|
);
|
|
9175
|
-
const { aggregateBySession } = await import("./dist-
|
|
9326
|
+
const { aggregateBySession } = await import("./dist-CJDGASPP.js");
|
|
9176
9327
|
const sessionData = aggregateBySession(records);
|
|
9177
9328
|
const match = sessionData.find((s) => s.sessionId === id);
|
|
9178
9329
|
if (!match) {
|
|
@@ -9207,7 +9358,7 @@ function registerLatestCommand(usage) {
|
|
|
9207
9358
|
}
|
|
9208
9359
|
return;
|
|
9209
9360
|
}
|
|
9210
|
-
const { aggregateBySession } = await import("./dist-
|
|
9361
|
+
const { aggregateBySession } = await import("./dist-CJDGASPP.js");
|
|
9211
9362
|
const sessionData = aggregateBySession(records);
|
|
9212
9363
|
const latest = sessionData[0];
|
|
9213
9364
|
if (!latest) {
|
|
@@ -9233,7 +9384,7 @@ function registerLatestCommand(usage) {
|
|
|
9233
9384
|
});
|
|
9234
9385
|
}
|
|
9235
9386
|
function createUsageCommand() {
|
|
9236
|
-
const usage = new
|
|
9387
|
+
const usage = new Command83("usage").description("Token usage and cost tracking");
|
|
9237
9388
|
usage.option(
|
|
9238
9389
|
"--include-claude-sessions",
|
|
9239
9390
|
"Include Claude Code session data from ~/.claude/projects/"
|
|
@@ -9248,15 +9399,15 @@ function createUsageCommand() {
|
|
|
9248
9399
|
// src/commands/validate.ts
|
|
9249
9400
|
init_dist();
|
|
9250
9401
|
init_dist();
|
|
9251
|
-
import { Command as
|
|
9252
|
-
import * as
|
|
9402
|
+
import { Command as Command84 } from "commander";
|
|
9403
|
+
import * as path63 from "path";
|
|
9253
9404
|
async function runValidate(options) {
|
|
9254
9405
|
const configResult = resolveConfig(options.configPath);
|
|
9255
9406
|
if (!configResult.ok) {
|
|
9256
9407
|
return configResult;
|
|
9257
9408
|
}
|
|
9258
9409
|
const config = configResult.value;
|
|
9259
|
-
const cwd = options.cwd ?? (options.configPath ?
|
|
9410
|
+
const cwd = options.cwd ?? (options.configPath ? path63.dirname(path63.resolve(options.configPath)) : process.cwd());
|
|
9260
9411
|
const result = {
|
|
9261
9412
|
valid: true,
|
|
9262
9413
|
checks: {
|
|
@@ -9266,7 +9417,7 @@ async function runValidate(options) {
|
|
|
9266
9417
|
},
|
|
9267
9418
|
issues: []
|
|
9268
9419
|
};
|
|
9269
|
-
const agentsMapPath =
|
|
9420
|
+
const agentsMapPath = path63.resolve(cwd, config.agentsMapPath);
|
|
9270
9421
|
const agentsResult = await validateAgentsMap(agentsMapPath);
|
|
9271
9422
|
if (agentsResult.ok) {
|
|
9272
9423
|
result.checks.agentsMap = true;
|
|
@@ -9331,11 +9482,11 @@ function resolveValidateMode(globalOpts) {
|
|
|
9331
9482
|
return OutputMode.TEXT;
|
|
9332
9483
|
}
|
|
9333
9484
|
async function printCrossCheckWarnings(mode) {
|
|
9334
|
-
const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-
|
|
9485
|
+
const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-BKCNLZYG.js");
|
|
9335
9486
|
const cwd = process.cwd();
|
|
9336
9487
|
const crossResult = await runCrossCheck2({
|
|
9337
|
-
specsDir:
|
|
9338
|
-
plansDir:
|
|
9488
|
+
specsDir: path63.join(cwd, "docs", "specs"),
|
|
9489
|
+
plansDir: path63.join(cwd, "docs", "plans"),
|
|
9339
9490
|
projectPath: cwd
|
|
9340
9491
|
});
|
|
9341
9492
|
if (!crossResult.ok || crossResult.value.warnings === 0) return;
|
|
@@ -9347,7 +9498,7 @@ async function printCrossCheckWarnings(mode) {
|
|
|
9347
9498
|
${crossResult.value.warnings} warnings`);
|
|
9348
9499
|
}
|
|
9349
9500
|
function createValidateCommand3() {
|
|
9350
|
-
const command = new
|
|
9501
|
+
const command = new Command84("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
|
|
9351
9502
|
"--agent-configs",
|
|
9352
9503
|
"Validate agent configs (CLAUDE.md, hooks, skills) via agnix or built-in fallback rules"
|
|
9353
9504
|
).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()));
|
|
@@ -9397,6 +9548,7 @@ Agent configs checked via ${engineLabel}${note}`);
|
|
|
9397
9548
|
// src/commands/_registry.ts
|
|
9398
9549
|
var commandCreators = [
|
|
9399
9550
|
createAddCommand,
|
|
9551
|
+
createAdviseSkillsCommand,
|
|
9400
9552
|
createAdoptionCommand,
|
|
9401
9553
|
createAgentCommand,
|
|
9402
9554
|
createAuditProtectedCommand,
|
|
@@ -9425,6 +9577,7 @@ var commandCreators = [
|
|
|
9425
9577
|
createInstallCommand,
|
|
9426
9578
|
createInstallConstraintsCommand,
|
|
9427
9579
|
createIntegrationsCommand,
|
|
9580
|
+
createKnowledgePipelineCommand,
|
|
9428
9581
|
createLearningsCommand,
|
|
9429
9582
|
createLinterCommand,
|
|
9430
9583
|
createMcpCommand,
|
|
@@ -9456,7 +9609,7 @@ var commandCreators = [
|
|
|
9456
9609
|
|
|
9457
9610
|
// src/index.ts
|
|
9458
9611
|
function createProgram() {
|
|
9459
|
-
const program = new
|
|
9612
|
+
const program = new Command85();
|
|
9460
9613
|
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");
|
|
9461
9614
|
for (const creator of commandCreators) {
|
|
9462
9615
|
program.addCommand(creator());
|