@harness-engineering/cli 1.25.4 → 1.25.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/skills/claude-code/enforce-architecture/SKILL.md +12 -0
- package/dist/agents/skills/claude-code/harness-api-design/SKILL.md +12 -0
- package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +12 -0
- package/dist/agents/skills/claude-code/harness-auth/SKILL.md +12 -0
- package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +30 -6
- package/dist/agents/skills/claude-code/harness-database/SKILL.md +12 -0
- package/dist/agents/skills/claude-code/harness-debugging/SKILL.md +38 -6
- package/dist/agents/skills/claude-code/harness-deployment/SKILL.md +12 -0
- package/dist/agents/skills/claude-code/harness-execution/SKILL.md +30 -6
- package/dist/agents/skills/claude-code/harness-planning/SKILL.md +20 -9
- package/dist/agents/skills/claude-code/harness-pre-commit-review/SKILL.md +59 -6
- package/dist/agents/skills/claude-code/harness-refactoring/SKILL.md +28 -7
- package/dist/agents/skills/claude-code/harness-security-scan/SKILL.md +12 -0
- package/dist/agents/skills/claude-code/harness-skill-authoring/SKILL.md +43 -8
- package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +59 -7
- package/dist/agents/skills/claude-code/harness-tdd/SKILL.md +21 -0
- package/dist/agents/skills/claude-code/harness-verification/SKILL.md +31 -6
- package/dist/agents/skills/codex/enforce-architecture/SKILL.md +12 -0
- package/dist/agents/skills/codex/harness-api-design/SKILL.md +12 -0
- package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +12 -0
- package/dist/agents/skills/codex/harness-auth/SKILL.md +12 -0
- package/dist/agents/skills/codex/harness-code-review/SKILL.md +30 -6
- package/dist/agents/skills/codex/harness-database/SKILL.md +12 -0
- package/dist/agents/skills/codex/harness-debugging/SKILL.md +38 -6
- package/dist/agents/skills/codex/harness-deployment/SKILL.md +12 -0
- package/dist/agents/skills/codex/harness-execution/SKILL.md +30 -6
- package/dist/agents/skills/codex/harness-planning/SKILL.md +20 -9
- package/dist/agents/skills/codex/harness-pre-commit-review/SKILL.md +59 -6
- package/dist/agents/skills/codex/harness-refactoring/SKILL.md +28 -7
- package/dist/agents/skills/codex/harness-security-scan/SKILL.md +12 -0
- package/dist/agents/skills/codex/harness-skill-authoring/SKILL.md +43 -8
- package/dist/agents/skills/codex/harness-soundness-review/SKILL.md +59 -7
- package/dist/agents/skills/codex/harness-tdd/SKILL.md +21 -0
- package/dist/agents/skills/codex/harness-verification/SKILL.md +31 -6
- package/dist/agents/skills/cursor/enforce-architecture/SKILL.md +12 -0
- package/dist/agents/skills/cursor/harness-api-design/SKILL.md +12 -0
- package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +12 -0
- package/dist/agents/skills/cursor/harness-auth/SKILL.md +12 -0
- package/dist/agents/skills/cursor/harness-code-review/SKILL.md +30 -6
- package/dist/agents/skills/cursor/harness-database/SKILL.md +12 -0
- package/dist/agents/skills/cursor/harness-debugging/SKILL.md +38 -6
- package/dist/agents/skills/cursor/harness-deployment/SKILL.md +12 -0
- package/dist/agents/skills/cursor/harness-execution/SKILL.md +30 -6
- package/dist/agents/skills/cursor/harness-planning/SKILL.md +20 -9
- package/dist/agents/skills/cursor/harness-pre-commit-review/SKILL.md +59 -6
- package/dist/agents/skills/cursor/harness-refactoring/SKILL.md +28 -7
- package/dist/agents/skills/cursor/harness-security-scan/SKILL.md +12 -0
- package/dist/agents/skills/cursor/harness-skill-authoring/SKILL.md +43 -8
- package/dist/agents/skills/cursor/harness-soundness-review/SKILL.md +59 -7
- package/dist/agents/skills/cursor/harness-tdd/SKILL.md +21 -0
- package/dist/agents/skills/cursor/harness-verification/SKILL.md +31 -6
- package/dist/agents/skills/gemini-cli/enforce-architecture/SKILL.md +12 -0
- package/dist/agents/skills/gemini-cli/harness-api-design/SKILL.md +12 -0
- package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +12 -0
- package/dist/agents/skills/gemini-cli/harness-auth/SKILL.md +12 -0
- package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +30 -6
- package/dist/agents/skills/gemini-cli/harness-database/SKILL.md +12 -0
- package/dist/agents/skills/gemini-cli/harness-debugging/SKILL.md +38 -6
- package/dist/agents/skills/gemini-cli/harness-deployment/SKILL.md +12 -0
- package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +30 -6
- package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +20 -9
- package/dist/agents/skills/gemini-cli/harness-pre-commit-review/SKILL.md +59 -6
- package/dist/agents/skills/gemini-cli/harness-refactoring/SKILL.md +28 -7
- package/dist/agents/skills/gemini-cli/harness-security-scan/SKILL.md +12 -0
- package/dist/agents/skills/gemini-cli/harness-skill-authoring/SKILL.md +43 -8
- package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +59 -7
- package/dist/agents/skills/gemini-cli/harness-tdd/SKILL.md +21 -0
- package/dist/agents/skills/gemini-cli/harness-verification/SKILL.md +31 -6
- package/dist/{agents-md-MCUM4SIZ.js → agents-md-2PYJM2MK.js} +3 -3
- package/dist/{architecture-HNIO6AUX.js → architecture-VCLB7A23.js} +4 -4
- package/dist/{assess-project-6MV5TNY3.js → assess-project-64C6LIKN.js} +1 -1
- package/dist/bin/harness-mcp.js +16 -15
- package/dist/bin/harness.js +27 -115
- package/dist/business-knowledge-6RHYJOB3.js +7 -0
- package/dist/{check-phase-gate-VCBQHQAC.js → check-phase-gate-RT6PGEHY.js} +4 -4
- package/dist/{chunk-MI6MA6OP.js → chunk-42ZZLMYD.js} +169 -118
- package/dist/{chunk-BUYW3SA2.js → chunk-43VBX44J.js} +219 -107
- package/dist/{chunk-UV3BZMGT.js → chunk-4YEBV2FT.js} +2 -2
- package/dist/{chunk-5BQ5BOJL.js → chunk-7BAGSY5Q.js} +1 -1
- package/dist/{chunk-FSNPBT74.js → chunk-BUJOMC3O.js} +1 -1
- package/dist/{chunk-M55DGGF3.js → chunk-CBZECDCW.js} +5 -5
- package/dist/{chunk-XTITAVUR.js → chunk-EY6F2QXW.js} +1 -1
- package/dist/{chunk-6VZQJ5CX.js → chunk-FL6A72LV.js} +1 -1
- package/dist/{chunk-CXJTVICF.js → chunk-JQCS75DY.js} +4 -4
- package/dist/{chunk-WIQA4BSH.js → chunk-JUXFYB2K.js} +1 -1
- package/dist/{chunk-FES2YEQU.js → chunk-KJC4SE7C.js} +9 -9
- package/dist/{chunk-4NK7Z3BP.js → chunk-R2BI5UPK.js} +1 -1
- package/dist/{chunk-2KZAXESR.js → chunk-R7P2FMJT.js} +360 -183
- package/dist/chunk-RC5ZY3EV.js +82 -0
- package/dist/{chunk-K2SON7TI.js → chunk-RDQGCHKD.js} +252 -57
- package/dist/{chunk-EHRZMOQ2.js → chunk-RKZW3FDF.js} +1 -1
- package/dist/{chunk-BOQRTARD.js → chunk-SMY35HJM.js} +1 -1
- package/dist/{chunk-UQZBZINS.js → chunk-SZZ5UQL7.js} +6 -6
- package/dist/{chunk-AT74HEQM.js → chunk-U2OMWI7Z.js} +1 -1
- package/dist/{chunk-P7PANON5.js → chunk-VELT5VAG.js} +1 -1
- package/dist/{chunk-YTP2UDPV.js → chunk-WEOGCL7B.js} +3 -3
- package/dist/{chunk-TYV4EUAD.js → chunk-X2JJ3CPG.js} +8 -8
- package/dist/{chunk-GEEYCQDS.js → chunk-XLO4AXXM.js} +9 -9
- package/dist/{chunk-47N6R2F4.js → chunk-XMEEYMGE.js} +1 -1
- package/dist/{chunk-FIQL2HND.js → chunk-Y5JA4J2M.js} +2 -2
- package/dist/{chunk-F23H3U5U.js → chunk-ZAKUCM7O.js} +2 -2
- package/dist/{ci-workflow-RTM7VVTD.js → ci-workflow-SZL3KVUK.js} +3 -3
- package/dist/{dist-RADHOOXG.js → dist-GRW3X2ZQ.js} +3 -1
- package/dist/{dist-WCSJHQPK.js → dist-T3DGV5UN.js} +16 -2
- package/dist/{docs-UBOGGHTY.js → docs-WDLJORLK.js} +4 -4
- package/dist/{engine-MJJAP5CH.js → engine-2YWYRCKK.js} +3 -3
- package/dist/{entropy-EMSXF2PX.js → entropy-PJGTOORX.js} +3 -3
- package/dist/{feedback-ZLUX72HD.js → feedback-M5KCJKL2.js} +1 -1
- package/dist/{generate-agent-definitions-AWLPJ27C.js → generate-agent-definitions-MFDW6LZT.js} +4 -4
- package/dist/{graph-loader-JHQVQRUS.js → graph-loader-QMKXT454.js} +1 -1
- package/dist/hooks/telemetry-reporter.js +22 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +26 -25
- package/dist/{loader-JVSJZSWZ.js → loader-6O52FYHE.js} +3 -3
- package/dist/{mcp-JZ7YB7TD.js → mcp-GGNFWKVC.js} +16 -15
- package/dist/{performance-7AGWJUY4.js → performance-337U5URQ.js} +4 -4
- package/dist/{review-pipeline-ZWVQJTJX.js → review-pipeline-DB5RD4SN.js} +3 -3
- package/dist/{runtime-D6YUQPP2.js → runtime-B74EN2WD.js} +3 -3
- package/dist/{scan-MPJ6JHUY.js → scan-DXQUHGTT.js} +1 -1
- package/dist/{security-JLZUAQYT.js → security-3AYN6FVU.js} +1 -1
- package/dist/{validate-TIIHRPMA.js → validate-35CD7VWN.js} +4 -4
- package/dist/{validate-cross-check-ZOWFA3DB.js → validate-cross-check-LJKXBQYH.js} +3 -3
- package/package.json +5 -5
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateAgentsMd
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7BAGSY5Q.js";
|
|
4
4
|
import {
|
|
5
5
|
generateCIWorkflow
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RKZW3FDF.js";
|
|
7
7
|
import {
|
|
8
8
|
TemplateEngine
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BUJOMC3O.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-FL6A72LV.js";
|
|
17
17
|
import {
|
|
18
18
|
runPersona
|
|
19
19
|
} from "./chunk-GISMXMVL.js";
|
|
@@ -28,21 +28,21 @@ import {
|
|
|
28
28
|
OutputMode,
|
|
29
29
|
createCheckPhaseGateCommand,
|
|
30
30
|
findFiles
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-Y5JA4J2M.js";
|
|
32
32
|
import {
|
|
33
33
|
createGenerateAgentDefinitionsCommand,
|
|
34
34
|
generateAgentDefinitions
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-U2OMWI7Z.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-VELT5VAG.js";
|
|
43
43
|
import {
|
|
44
44
|
createScanCommand
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-R2BI5UPK.js";
|
|
46
46
|
import {
|
|
47
47
|
appendFrameworkAgents,
|
|
48
48
|
captureHealthSnapshot,
|
|
@@ -56,11 +56,11 @@ import {
|
|
|
56
56
|
loadOrRebuildIndex,
|
|
57
57
|
persistToolingConfig,
|
|
58
58
|
recommend
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-43VBX44J.js";
|
|
60
60
|
import {
|
|
61
61
|
findConfigFile,
|
|
62
62
|
resolveConfig
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-JUXFYB2K.js";
|
|
64
64
|
import {
|
|
65
65
|
VALID_PLATFORMS
|
|
66
66
|
} from "./chunk-3ISINLYT.js";
|
|
@@ -74,7 +74,7 @@ import {
|
|
|
74
74
|
} from "./chunk-6B6UN6SG.js";
|
|
75
75
|
import {
|
|
76
76
|
loadGraphStore
|
|
77
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-SMY35HJM.js";
|
|
78
78
|
import {
|
|
79
79
|
CLI_VERSION
|
|
80
80
|
} from "./chunk-BM3PWGXQ.js";
|
|
@@ -148,7 +148,7 @@ import {
|
|
|
148
148
|
validateKnowledgeMap,
|
|
149
149
|
writeConfig,
|
|
150
150
|
writeLockfile
|
|
151
|
-
} from "./chunk-
|
|
151
|
+
} from "./chunk-42ZZLMYD.js";
|
|
152
152
|
import {
|
|
153
153
|
Err,
|
|
154
154
|
Ok
|
|
@@ -173,7 +173,7 @@ import {
|
|
|
173
173
|
} from "./chunk-KFQGP6VL.js";
|
|
174
174
|
|
|
175
175
|
// src/index.ts
|
|
176
|
-
import { Command as
|
|
176
|
+
import { Command as Command84 } from "commander";
|
|
177
177
|
|
|
178
178
|
// src/commands/add.ts
|
|
179
179
|
init_dist();
|
|
@@ -362,7 +362,7 @@ function registerSkillsCommand(adoption) {
|
|
|
362
362
|
const globalOpts = cmd.optsWithGlobals();
|
|
363
363
|
const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
|
|
364
364
|
const cwd = process.cwd();
|
|
365
|
-
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-
|
|
365
|
+
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-T3DGV5UN.js");
|
|
366
366
|
const records = readAdoptionRecords(cwd);
|
|
367
367
|
if (records.length === 0) {
|
|
368
368
|
if (globalOpts.json) {
|
|
@@ -398,7 +398,7 @@ function registerRecentCommand(adoption) {
|
|
|
398
398
|
const globalOpts = cmd.optsWithGlobals();
|
|
399
399
|
const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
|
|
400
400
|
const cwd = process.cwd();
|
|
401
|
-
const { readAdoptionRecords } = await import("./dist-
|
|
401
|
+
const { readAdoptionRecords } = await import("./dist-T3DGV5UN.js");
|
|
402
402
|
const records = readAdoptionRecords(cwd);
|
|
403
403
|
if (records.length === 0) {
|
|
404
404
|
if (globalOpts.json) {
|
|
@@ -431,62 +431,68 @@ function registerRecentCommand(adoption) {
|
|
|
431
431
|
Showing ${limited.length} of ${records.length} invocations`);
|
|
432
432
|
});
|
|
433
433
|
}
|
|
434
|
+
function computePhaseRates(skillRecords) {
|
|
435
|
+
const phaseMap = /* @__PURE__ */ new Map();
|
|
436
|
+
for (const r of skillRecords) {
|
|
437
|
+
for (const phase of r.phasesReached) {
|
|
438
|
+
phaseMap.set(phase, (phaseMap.get(phase) ?? 0) + 1);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return Array.from(phaseMap.entries()).map(([phase, count]) => ({ phase, count, rate: count / skillRecords.length })).sort((a, b) => b.count - a.count);
|
|
442
|
+
}
|
|
443
|
+
function computeOutcomes(skillRecords) {
|
|
444
|
+
const outcomes = { completed: 0, failed: 0, abandoned: 0 };
|
|
445
|
+
for (const r of skillRecords) {
|
|
446
|
+
if (r.outcome in outcomes) {
|
|
447
|
+
outcomes[r.outcome]++;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return outcomes;
|
|
451
|
+
}
|
|
452
|
+
function printSkillDetail(name, summary, phaseRates, skillRecords) {
|
|
453
|
+
console.log(`Skill: ${name}`);
|
|
454
|
+
console.log(`Invocations: ${summary.invocations}`);
|
|
455
|
+
console.log(`Success rate: ${formatRate(summary.successRate)}`);
|
|
456
|
+
console.log(`Avg duration: ${formatDuration(summary.avgDuration)}`);
|
|
457
|
+
console.log(`Last used: ${summary.lastUsed.slice(0, 10)}`);
|
|
458
|
+
if (summary.tier != null) {
|
|
459
|
+
console.log(`Tier: ${summary.tier}`);
|
|
460
|
+
}
|
|
461
|
+
if (phaseRates.length > 0) {
|
|
462
|
+
console.log("\nPhase completion rates:");
|
|
463
|
+
for (const p of phaseRates) {
|
|
464
|
+
console.log(
|
|
465
|
+
` ${padRight(p.phase, 20)} ${formatRate(p.rate)} (${p.count}/${skillRecords.length})`
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
const outcomes = computeOutcomes(skillRecords);
|
|
470
|
+
console.log("\nOutcome breakdown:");
|
|
471
|
+
console.log(` Completed: ${outcomes.completed}`);
|
|
472
|
+
console.log(` Failed: ${outcomes.failed}`);
|
|
473
|
+
console.log(` Abandoned: ${outcomes.abandoned}`);
|
|
474
|
+
}
|
|
434
475
|
function registerSkillCommand(adoption) {
|
|
435
476
|
adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
|
|
436
477
|
const globalOpts = cmd.optsWithGlobals();
|
|
437
478
|
const cwd = process.cwd();
|
|
438
|
-
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-
|
|
479
|
+
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-T3DGV5UN.js");
|
|
439
480
|
const records = readAdoptionRecords(cwd);
|
|
440
481
|
const skillRecords = records.filter((r) => r.skill === name);
|
|
441
482
|
if (skillRecords.length === 0) {
|
|
442
|
-
if (globalOpts.json)
|
|
443
|
-
|
|
444
|
-
} else {
|
|
445
|
-
logger.info(`No adoption data found for skill "${name}".`);
|
|
446
|
-
}
|
|
483
|
+
if (globalOpts.json) console.log(JSON.stringify(null));
|
|
484
|
+
else logger.info(`No adoption data found for skill "${name}".`);
|
|
447
485
|
return;
|
|
448
486
|
}
|
|
449
|
-
const
|
|
450
|
-
const
|
|
451
|
-
const phaseMap = /* @__PURE__ */ new Map();
|
|
452
|
-
for (const r of skillRecords) {
|
|
453
|
-
for (const phase of r.phasesReached) {
|
|
454
|
-
phaseMap.set(phase, (phaseMap.get(phase) ?? 0) + 1);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
const phaseRates = Array.from(phaseMap.entries()).map(([phase, count]) => ({ phase, count, rate: count / skillRecords.length })).sort((a, b) => b.count - a.count);
|
|
487
|
+
const summary = aggregateBySkill(skillRecords)[0];
|
|
488
|
+
const phaseRates = computePhaseRates(skillRecords);
|
|
458
489
|
if (globalOpts.json) {
|
|
459
490
|
console.log(
|
|
460
491
|
JSON.stringify({ summary, phaseRates, totalRecords: skillRecords.length }, null, 2)
|
|
461
492
|
);
|
|
462
493
|
return;
|
|
463
494
|
}
|
|
464
|
-
|
|
465
|
-
console.log(`Invocations: ${summary.invocations}`);
|
|
466
|
-
console.log(`Success rate: ${formatRate(summary.successRate)}`);
|
|
467
|
-
console.log(`Avg duration: ${formatDuration(summary.avgDuration)}`);
|
|
468
|
-
console.log(`Last used: ${summary.lastUsed.slice(0, 10)}`);
|
|
469
|
-
if (summary.tier != null) {
|
|
470
|
-
console.log(`Tier: ${summary.tier}`);
|
|
471
|
-
}
|
|
472
|
-
if (phaseRates.length > 0) {
|
|
473
|
-
console.log("\nPhase completion rates:");
|
|
474
|
-
for (const p of phaseRates) {
|
|
475
|
-
console.log(
|
|
476
|
-
` ${padRight(p.phase, 20)} ${formatRate(p.rate)} (${p.count}/${skillRecords.length})`
|
|
477
|
-
);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
const outcomes = { completed: 0, failed: 0, abandoned: 0 };
|
|
481
|
-
for (const r of skillRecords) {
|
|
482
|
-
if (r.outcome in outcomes) {
|
|
483
|
-
outcomes[r.outcome]++;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
console.log("\nOutcome breakdown:");
|
|
487
|
-
console.log(` Completed: ${outcomes.completed}`);
|
|
488
|
-
console.log(` Failed: ${outcomes.failed}`);
|
|
489
|
-
console.log(` Abandoned: ${outcomes.abandoned}`);
|
|
495
|
+
printSkillDetail(name, summary, phaseRates, skillRecords);
|
|
490
496
|
});
|
|
491
497
|
}
|
|
492
498
|
function createAdoptionCommand() {
|
|
@@ -2052,6 +2058,12 @@ async function runCleanupSessions(options) {
|
|
|
2052
2058
|
}
|
|
2053
2059
|
return Ok(result);
|
|
2054
2060
|
}
|
|
2061
|
+
function printSessionList(label, sessions) {
|
|
2062
|
+
if (sessions.length === 0) return;
|
|
2063
|
+
console.log(`
|
|
2064
|
+
${label} (${sessions.length}):`);
|
|
2065
|
+
for (const s of sessions) console.log(` - ${s}`);
|
|
2066
|
+
}
|
|
2055
2067
|
function printResult(result, dryRun, asJson) {
|
|
2056
2068
|
const { removed, kept } = result;
|
|
2057
2069
|
if (asJson) {
|
|
@@ -2062,17 +2074,9 @@ function printResult(result, dryRun, asJson) {
|
|
|
2062
2074
|
console.log("No sessions found.");
|
|
2063
2075
|
return;
|
|
2064
2076
|
}
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
${label} (${removed.length}):`);
|
|
2069
|
-
for (const s of removed) console.log(` - ${s}`);
|
|
2070
|
-
}
|
|
2071
|
-
if (kept.length > 0) {
|
|
2072
|
-
console.log(`
|
|
2073
|
-
Kept (${kept.length}):`);
|
|
2074
|
-
for (const s of kept) console.log(` - ${s}`);
|
|
2075
|
-
}
|
|
2077
|
+
const removeLabel = dryRun ? "Stale (would remove)" : "Removed";
|
|
2078
|
+
printSessionList(removeLabel, removed);
|
|
2079
|
+
printSessionList("Kept", kept);
|
|
2076
2080
|
if (!dryRun && removed.length > 0) {
|
|
2077
2081
|
console.log(`
|
|
2078
2082
|
Cleaned up ${removed.length} stale session(s).`);
|
|
@@ -2146,16 +2150,7 @@ function spawnDashboardServer(server, env) {
|
|
|
2146
2150
|
});
|
|
2147
2151
|
return child;
|
|
2148
2152
|
}
|
|
2149
|
-
function
|
|
2150
|
-
const clientPort = Number(opts.port ?? DEFAULT_CLIENT_PORT);
|
|
2151
|
-
const apiPort = Number(opts.apiPort ?? DEFAULT_API_PORT);
|
|
2152
|
-
const projectPath = resolve11(opts.cwd ?? process.cwd());
|
|
2153
|
-
const url = `http://localhost:${apiPort}`;
|
|
2154
|
-
const server = resolveServerScript();
|
|
2155
|
-
if (!server) {
|
|
2156
|
-
console.error("Could not locate the dashboard server. Run `pnpm build` in packages/dashboard.");
|
|
2157
|
-
process.exit(1);
|
|
2158
|
-
}
|
|
2153
|
+
function buildDashboardEnv(opts, clientPort, apiPort, projectPath) {
|
|
2159
2154
|
const env = {
|
|
2160
2155
|
...process.env,
|
|
2161
2156
|
DASHBOARD_API_PORT: String(apiPort),
|
|
@@ -2167,6 +2162,19 @@ function runDashboard(opts) {
|
|
|
2167
2162
|
} else if (!env["ORCHESTRATOR_URL"] && !env["ORCHESTRATOR_PORT"]) {
|
|
2168
2163
|
env["ORCHESTRATOR_PORT"] = "8080";
|
|
2169
2164
|
}
|
|
2165
|
+
return env;
|
|
2166
|
+
}
|
|
2167
|
+
function runDashboard(opts) {
|
|
2168
|
+
const clientPort = Number(opts.port ?? DEFAULT_CLIENT_PORT);
|
|
2169
|
+
const apiPort = Number(opts.apiPort ?? DEFAULT_API_PORT);
|
|
2170
|
+
const projectPath = resolve11(opts.cwd ?? process.cwd());
|
|
2171
|
+
const url = `http://localhost:${apiPort}`;
|
|
2172
|
+
const server = resolveServerScript();
|
|
2173
|
+
if (!server) {
|
|
2174
|
+
console.error("Could not locate the dashboard server. Run `pnpm build` in packages/dashboard.");
|
|
2175
|
+
process.exit(1);
|
|
2176
|
+
}
|
|
2177
|
+
const env = buildDashboardEnv(opts, clientPort, apiPort, projectPath);
|
|
2170
2178
|
spawnDashboardServer(server, env);
|
|
2171
2179
|
console.log(`Dashboard API starting on http://localhost:${apiPort}`);
|
|
2172
2180
|
console.log(`Open ${url} (pass --no-open to suppress)`);
|
|
@@ -2757,7 +2765,7 @@ import { Command as Command25 } from "commander";
|
|
|
2757
2765
|
// src/commands/graph/status.ts
|
|
2758
2766
|
import * as path15 from "path";
|
|
2759
2767
|
async function runGraphStatus(projectPath) {
|
|
2760
|
-
const { GraphStore } = await import("./dist-
|
|
2768
|
+
const { GraphStore } = await import("./dist-GRW3X2ZQ.js");
|
|
2761
2769
|
const graphDir = path15.join(projectPath, ".harness", "graph");
|
|
2762
2770
|
const store = new GraphStore();
|
|
2763
2771
|
const loaded = await store.load(graphDir);
|
|
@@ -2797,7 +2805,7 @@ async function runGraphStatus(projectPath) {
|
|
|
2797
2805
|
// src/commands/graph/export.ts
|
|
2798
2806
|
import * as path16 from "path";
|
|
2799
2807
|
async function runGraphExport(projectPath, format) {
|
|
2800
|
-
const { GraphStore } = await import("./dist-
|
|
2808
|
+
const { GraphStore } = await import("./dist-GRW3X2ZQ.js");
|
|
2801
2809
|
const graphDir = path16.join(projectPath, ".harness", "graph");
|
|
2802
2810
|
const store = new GraphStore();
|
|
2803
2811
|
const loaded = await store.load(graphDir);
|
|
@@ -2833,7 +2841,7 @@ import * as path19 from "path";
|
|
|
2833
2841
|
import { Command as Command23 } from "commander";
|
|
2834
2842
|
import * as path17 from "path";
|
|
2835
2843
|
async function runQuery(projectPath, rootNodeId, opts) {
|
|
2836
|
-
const { GraphStore, ContextQL } = await import("./dist-
|
|
2844
|
+
const { GraphStore, ContextQL } = await import("./dist-GRW3X2ZQ.js");
|
|
2837
2845
|
const store = new GraphStore();
|
|
2838
2846
|
const graphDir = path17.join(projectPath, ".harness", "graph");
|
|
2839
2847
|
const loaded = await store.load(graphDir);
|
|
@@ -2927,7 +2935,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
2927
2935
|
SlackConnector,
|
|
2928
2936
|
CIConnector,
|
|
2929
2937
|
ConfluenceConnector
|
|
2930
|
-
} = await import("./dist-
|
|
2938
|
+
} = await import("./dist-GRW3X2ZQ.js");
|
|
2931
2939
|
const graphDir = path18.join(projectPath, ".harness", "graph");
|
|
2932
2940
|
const store = new GraphStore();
|
|
2933
2941
|
await store.load(graphDir);
|
|
@@ -5428,7 +5436,7 @@ function createMcpCommand() {
|
|
|
5428
5436
|
parseBudget
|
|
5429
5437
|
).action(async (opts) => {
|
|
5430
5438
|
const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
|
|
5431
|
-
import("./mcp-
|
|
5439
|
+
import("./mcp-GGNFWKVC.js"),
|
|
5432
5440
|
import("./tool-tiers-7QGZ3FKY.js")
|
|
5433
5441
|
]);
|
|
5434
5442
|
if (opts.tools && opts.tools.length > 0) {
|
|
@@ -5494,7 +5502,7 @@ function registerBenchCommand(perf) {
|
|
|
5494
5502
|
perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
|
|
5495
5503
|
const globalOpts = cmd.optsWithGlobals();
|
|
5496
5504
|
const cwd = process.cwd();
|
|
5497
|
-
const { BenchmarkRunner } = await import("./dist-
|
|
5505
|
+
const { BenchmarkRunner } = await import("./dist-T3DGV5UN.js");
|
|
5498
5506
|
const runner = new BenchmarkRunner();
|
|
5499
5507
|
const benchFiles = runner.discover(cwd, glob2);
|
|
5500
5508
|
if (benchFiles.length === 0) {
|
|
@@ -5558,7 +5566,7 @@ async function runBaselinesShow(globalOpts) {
|
|
|
5558
5566
|
}
|
|
5559
5567
|
async function runBaselinesUpdate(globalOpts) {
|
|
5560
5568
|
const cwd = process.cwd();
|
|
5561
|
-
const { BenchmarkRunner } = await import("./dist-
|
|
5569
|
+
const { BenchmarkRunner } = await import("./dist-T3DGV5UN.js");
|
|
5562
5570
|
const runner = new BenchmarkRunner();
|
|
5563
5571
|
const manager = new BaselineManager(cwd);
|
|
5564
5572
|
logger.info("Running benchmarks to update baselines...");
|
|
@@ -5599,7 +5607,7 @@ function registerReportCommand(perf) {
|
|
|
5599
5607
|
perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
|
|
5600
5608
|
const globalOpts = cmd.optsWithGlobals();
|
|
5601
5609
|
const cwd = process.cwd();
|
|
5602
|
-
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-
|
|
5610
|
+
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-T3DGV5UN.js");
|
|
5603
5611
|
const analyzer = new EntropyAnalyzer2({
|
|
5604
5612
|
rootDir: path40.resolve(cwd),
|
|
5605
5613
|
analyze: { complexity: true, coupling: true }
|
|
@@ -5990,7 +5998,7 @@ async function runPublishAnalyses(opts) {
|
|
|
5990
5998
|
const nameToExternalId = buildNameToExternalIdMap(projectPath);
|
|
5991
5999
|
if (!nameToExternalId) return process.exit(1);
|
|
5992
6000
|
const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
|
|
5993
|
-
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-
|
|
6001
|
+
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-T3DGV5UN.js");
|
|
5994
6002
|
const archive = new AnalysisArchive(path42.join(projectPath, ".harness", "analyses"));
|
|
5995
6003
|
const analyses = await archive.list();
|
|
5996
6004
|
if (analyses.length === 0) {
|
|
@@ -6275,10 +6283,10 @@ function prompt(question) {
|
|
|
6275
6283
|
input: process.stdin,
|
|
6276
6284
|
output: process.stdout
|
|
6277
6285
|
});
|
|
6278
|
-
return new Promise((
|
|
6286
|
+
return new Promise((resolve36) => {
|
|
6279
6287
|
rl.question(question, (answer) => {
|
|
6280
6288
|
rl.close();
|
|
6281
|
-
|
|
6289
|
+
resolve36(answer.trim().toLowerCase());
|
|
6282
6290
|
});
|
|
6283
6291
|
});
|
|
6284
6292
|
}
|
|
@@ -6287,10 +6295,10 @@ function promptRaw(question) {
|
|
|
6287
6295
|
input: process.stdin,
|
|
6288
6296
|
output: process.stdout
|
|
6289
6297
|
});
|
|
6290
|
-
return new Promise((
|
|
6298
|
+
return new Promise((resolve36) => {
|
|
6291
6299
|
rl.question(question, (answer) => {
|
|
6292
6300
|
rl.close();
|
|
6293
|
-
|
|
6301
|
+
resolve36(answer.trim());
|
|
6294
6302
|
});
|
|
6295
6303
|
});
|
|
6296
6304
|
}
|
|
@@ -6516,7 +6524,7 @@ function ensureHooks(cwd) {
|
|
|
6516
6524
|
}
|
|
6517
6525
|
async function runInitialGraphScan(cwd) {
|
|
6518
6526
|
try {
|
|
6519
|
-
const { runScan: runScan2 } = await import("./scan-
|
|
6527
|
+
const { runScan: runScan2 } = await import("./scan-DXQUHGTT.js");
|
|
6520
6528
|
const result = await runScan2(cwd);
|
|
6521
6529
|
return {
|
|
6522
6530
|
status: "pass",
|
|
@@ -7790,8 +7798,8 @@ async function resolveStatePath(projectPath, stream) {
|
|
|
7790
7798
|
}
|
|
7791
7799
|
async function confirmReset() {
|
|
7792
7800
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
7793
|
-
const answer = await new Promise((
|
|
7794
|
-
rl.question("Reset project state? This cannot be undone. [y/N] ",
|
|
7801
|
+
const answer = await new Promise((resolve36) => {
|
|
7802
|
+
rl.question("Reset project state? This cannot be undone. [y/N] ", resolve36);
|
|
7795
7803
|
});
|
|
7796
7804
|
rl.close();
|
|
7797
7805
|
return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
@@ -8019,7 +8027,7 @@ async function runSyncAnalyses(opts) {
|
|
|
8019
8027
|
return;
|
|
8020
8028
|
}
|
|
8021
8029
|
const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
|
|
8022
|
-
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-
|
|
8030
|
+
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-T3DGV5UN.js");
|
|
8023
8031
|
const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
|
|
8024
8032
|
const archive = new AnalysisArchive(path58.join(projectPath, ".harness", "analyses"));
|
|
8025
8033
|
const publishedIndex = loadPublishedIndex2(projectPath);
|
|
@@ -8135,7 +8143,7 @@ function createTaintCommand() {
|
|
|
8135
8143
|
}
|
|
8136
8144
|
|
|
8137
8145
|
// src/commands/telemetry/index.ts
|
|
8138
|
-
import { Command as
|
|
8146
|
+
import { Command as Command77 } from "commander";
|
|
8139
8147
|
|
|
8140
8148
|
// src/commands/telemetry/identify.ts
|
|
8141
8149
|
init_dist();
|
|
@@ -8201,29 +8209,33 @@ function resolveDisabledReason() {
|
|
|
8201
8209
|
if (process.env.HARNESS_TELEMETRY_OPTOUT === "1") return "HARNESS_TELEMETRY_OPTOUT=1";
|
|
8202
8210
|
return "telemetry.enabled is false in config";
|
|
8203
8211
|
}
|
|
8212
|
+
function printIdentity2(identity) {
|
|
8213
|
+
const hasIdentity = identity.project || identity.team || identity.alias;
|
|
8214
|
+
if (!hasIdentity) {
|
|
8215
|
+
logger.info("Identity: not configured");
|
|
8216
|
+
return;
|
|
8217
|
+
}
|
|
8218
|
+
logger.info("Identity:");
|
|
8219
|
+
for (const [key, value] of Object.entries(identity)) {
|
|
8220
|
+
if (value) logger.info(` ${key.padEnd(7)}: ${value}`);
|
|
8221
|
+
}
|
|
8222
|
+
}
|
|
8223
|
+
function printEnvOverrides(overrides) {
|
|
8224
|
+
const keys = Object.keys(overrides);
|
|
8225
|
+
if (keys.length === 0) return;
|
|
8226
|
+
logger.info("Env overrides:");
|
|
8227
|
+
for (const key of keys) {
|
|
8228
|
+
logger.info(` ${key}=${overrides[key]}`);
|
|
8229
|
+
}
|
|
8230
|
+
}
|
|
8204
8231
|
function printHumanStatus(result) {
|
|
8205
8232
|
logger.info(`Telemetry: ${result.consent.allowed ? "enabled" : "disabled"}`);
|
|
8206
8233
|
if (!result.consent.allowed && result.consent.reason) {
|
|
8207
8234
|
logger.info(` Reason: ${result.consent.reason}`);
|
|
8208
8235
|
}
|
|
8209
8236
|
logger.info(`Install ID: ${result.installId ?? "not yet created"}`);
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
if (hasIdentity) {
|
|
8213
|
-
logger.info("Identity:");
|
|
8214
|
-
for (const [key, value] of Object.entries(identity)) {
|
|
8215
|
-
if (value) logger.info(` ${key.padEnd(7)}: ${value}`);
|
|
8216
|
-
}
|
|
8217
|
-
} else {
|
|
8218
|
-
logger.info("Identity: not configured");
|
|
8219
|
-
}
|
|
8220
|
-
const overrideKeys = Object.keys(result.envOverrides);
|
|
8221
|
-
if (overrideKeys.length > 0) {
|
|
8222
|
-
logger.info("Env overrides:");
|
|
8223
|
-
for (const key of overrideKeys) {
|
|
8224
|
-
logger.info(` ${key}=${result.envOverrides[key]}`);
|
|
8225
|
-
}
|
|
8226
|
-
}
|
|
8237
|
+
printIdentity2(result.identity);
|
|
8238
|
+
printEnvOverrides(result.envOverrides);
|
|
8227
8239
|
}
|
|
8228
8240
|
function createStatusCommand() {
|
|
8229
8241
|
const cmd = new Command75("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
|
|
@@ -8257,16 +8269,176 @@ function createStatusCommand() {
|
|
|
8257
8269
|
return cmd;
|
|
8258
8270
|
}
|
|
8259
8271
|
|
|
8272
|
+
// src/commands/telemetry/test.ts
|
|
8273
|
+
init_dist();
|
|
8274
|
+
import { Command as Command76 } from "commander";
|
|
8275
|
+
|
|
8276
|
+
// src/bin/command-telemetry.ts
|
|
8277
|
+
import { existsSync as existsSync36, readFileSync as readFileSync25, mkdirSync as mkdirSync15, appendFileSync, writeFileSync as writeFileSync18 } from "fs";
|
|
8278
|
+
import { join as join45, parse as parsePath, resolve as resolve33 } from "path";
|
|
8279
|
+
import { spawn as spawn2 } from "child_process";
|
|
8280
|
+
var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
|
|
8281
|
+
var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
|
|
8282
|
+
function findProjectRoot(cwd) {
|
|
8283
|
+
let dir = resolve33(cwd);
|
|
8284
|
+
const { root } = parsePath(dir);
|
|
8285
|
+
while (dir !== root) {
|
|
8286
|
+
if (existsSync36(join45(dir, "harness.config.json"))) return dir;
|
|
8287
|
+
dir = resolve33(dir, "..");
|
|
8288
|
+
}
|
|
8289
|
+
return cwd;
|
|
8290
|
+
}
|
|
8291
|
+
var commandName = "";
|
|
8292
|
+
var startTime = 0;
|
|
8293
|
+
var recorded = false;
|
|
8294
|
+
function installCommandTelemetry(program, cwd) {
|
|
8295
|
+
if (typeof program.hook !== "function") return;
|
|
8296
|
+
const projectRoot = findProjectRoot(cwd);
|
|
8297
|
+
flushTelemetryBackground(projectRoot);
|
|
8298
|
+
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
8299
|
+
commandName = resolveCommandName(actionCommand);
|
|
8300
|
+
startTime = Date.now();
|
|
8301
|
+
});
|
|
8302
|
+
process.on("exit", (code) => {
|
|
8303
|
+
if (recorded || !commandName || EXCLUDED_COMMANDS.has(commandName)) return;
|
|
8304
|
+
recorded = true;
|
|
8305
|
+
const duration = Date.now() - startTime;
|
|
8306
|
+
const outcome = code === 0 ? "completed" : "failed";
|
|
8307
|
+
writeCommandRecordSync(projectRoot, commandName, duration, outcome);
|
|
8308
|
+
});
|
|
8309
|
+
}
|
|
8310
|
+
function resolveCommandName(cmd) {
|
|
8311
|
+
const parts = [];
|
|
8312
|
+
let current = cmd;
|
|
8313
|
+
while (current) {
|
|
8314
|
+
const name = current.name();
|
|
8315
|
+
if (name && name !== "harness") {
|
|
8316
|
+
parts.unshift(name);
|
|
8317
|
+
}
|
|
8318
|
+
current = current.parent;
|
|
8319
|
+
}
|
|
8320
|
+
return parts.length > 0 ? `cli/${parts.join(".")}` : "";
|
|
8321
|
+
}
|
|
8322
|
+
function writeCommandRecordSync(cwd, command, duration, outcome) {
|
|
8323
|
+
try {
|
|
8324
|
+
const metricsDir = join45(cwd, ".harness", "metrics");
|
|
8325
|
+
mkdirSync15(metricsDir, { recursive: true });
|
|
8326
|
+
const record = {
|
|
8327
|
+
skill: command,
|
|
8328
|
+
session: `cli-${Date.now()}`,
|
|
8329
|
+
startedAt: new Date(Date.now() - duration).toISOString(),
|
|
8330
|
+
duration,
|
|
8331
|
+
outcome,
|
|
8332
|
+
phasesReached: []
|
|
8333
|
+
};
|
|
8334
|
+
const adoptionFile = join45(metricsDir, "adoption.jsonl");
|
|
8335
|
+
appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
|
|
8336
|
+
} catch {
|
|
8337
|
+
}
|
|
8338
|
+
}
|
|
8339
|
+
function isTelemetryDisabledByConfig(cwd) {
|
|
8340
|
+
const configPath = join45(cwd, "harness.config.json");
|
|
8341
|
+
if (!existsSync36(configPath)) return false;
|
|
8342
|
+
try {
|
|
8343
|
+
const config = JSON.parse(readFileSync25(configPath, "utf-8"));
|
|
8344
|
+
return config?.telemetry?.enabled === false;
|
|
8345
|
+
} catch {
|
|
8346
|
+
return false;
|
|
8347
|
+
}
|
|
8348
|
+
}
|
|
8349
|
+
function isTelemetryOptedOut(cwd) {
|
|
8350
|
+
if (isTelemetryDisabledByConfig(cwd)) return true;
|
|
8351
|
+
return process.env.DO_NOT_TRACK === "1" || process.env.HARNESS_TELEMETRY_OPTOUT === "1";
|
|
8352
|
+
}
|
|
8353
|
+
function flushTelemetryBackground(cwd) {
|
|
8354
|
+
try {
|
|
8355
|
+
const adoptionFile = join45(cwd, ".harness", "metrics", "adoption.jsonl");
|
|
8356
|
+
if (!existsSync36(adoptionFile)) return;
|
|
8357
|
+
if (isTelemetryOptedOut(cwd)) return;
|
|
8358
|
+
const reporterPath = join45(cwd, ".harness", "hooks", "telemetry-reporter.js");
|
|
8359
|
+
if (!existsSync36(reporterPath)) return;
|
|
8360
|
+
const child = spawn2(process.execPath, [reporterPath], {
|
|
8361
|
+
cwd,
|
|
8362
|
+
stdio: ["pipe", "ignore", "ignore"],
|
|
8363
|
+
detached: true
|
|
8364
|
+
});
|
|
8365
|
+
child.stdin?.write("{}");
|
|
8366
|
+
child.stdin?.end();
|
|
8367
|
+
child.unref();
|
|
8368
|
+
} catch {
|
|
8369
|
+
}
|
|
8370
|
+
}
|
|
8371
|
+
|
|
8372
|
+
// src/commands/telemetry/test.ts
|
|
8373
|
+
var POSTHOG_BATCH_URL = "https://app.posthog.com/batch";
|
|
8374
|
+
function buildTestEvent(distinctId, installId, identity) {
|
|
8375
|
+
return {
|
|
8376
|
+
event: "telemetry_test",
|
|
8377
|
+
distinct_id: distinctId,
|
|
8378
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8379
|
+
properties: {
|
|
8380
|
+
installId,
|
|
8381
|
+
os: process.platform,
|
|
8382
|
+
nodeVersion: process.version,
|
|
8383
|
+
test: true,
|
|
8384
|
+
...identity.project ? { project: identity.project } : {},
|
|
8385
|
+
...identity.team ? { team: identity.team } : {}
|
|
8386
|
+
}
|
|
8387
|
+
};
|
|
8388
|
+
}
|
|
8389
|
+
function reportTestSuccess(status, distinctId, identity) {
|
|
8390
|
+
logger.success(`PostHog responded ${status} OK \u2014 telemetry is working`);
|
|
8391
|
+
logger.info(` distinct_id: ${distinctId}`);
|
|
8392
|
+
if (identity.project) logger.info(` project: ${identity.project}`);
|
|
8393
|
+
if (identity.team) logger.info(` team: ${identity.team}`);
|
|
8394
|
+
}
|
|
8395
|
+
function createTestCommand() {
|
|
8396
|
+
return new Command76("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
|
|
8397
|
+
const cwd = process.cwd();
|
|
8398
|
+
const consent = resolveConsent(cwd, void 0);
|
|
8399
|
+
if (!consent.allowed) {
|
|
8400
|
+
logger.error("Telemetry is disabled. Run `harness telemetry status` for details.");
|
|
8401
|
+
process.exitCode = 1;
|
|
8402
|
+
return;
|
|
8403
|
+
}
|
|
8404
|
+
const { installId, identity } = consent;
|
|
8405
|
+
const distinctId = identity.alias ?? installId;
|
|
8406
|
+
const event = buildTestEvent(distinctId, installId, identity);
|
|
8407
|
+
const payload = JSON.stringify({ api_key: POSTHOG_API_KEY, batch: [event] });
|
|
8408
|
+
logger.info(`Sending test event as "${distinctId}"...`);
|
|
8409
|
+
try {
|
|
8410
|
+
const res = await fetch(POSTHOG_BATCH_URL, {
|
|
8411
|
+
method: "POST",
|
|
8412
|
+
headers: { "Content-Type": "application/json" },
|
|
8413
|
+
body: payload,
|
|
8414
|
+
signal: AbortSignal.timeout(1e4)
|
|
8415
|
+
});
|
|
8416
|
+
const body = await res.text();
|
|
8417
|
+
if (res.ok) {
|
|
8418
|
+
reportTestSuccess(res.status, distinctId, identity);
|
|
8419
|
+
} else {
|
|
8420
|
+
logger.error(`PostHog responded ${res.status}: ${body}`);
|
|
8421
|
+
process.exitCode = 1;
|
|
8422
|
+
}
|
|
8423
|
+
} catch (err) {
|
|
8424
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
8425
|
+
logger.error(`Failed to reach PostHog: ${msg}`);
|
|
8426
|
+
process.exitCode = 1;
|
|
8427
|
+
}
|
|
8428
|
+
});
|
|
8429
|
+
}
|
|
8430
|
+
|
|
8260
8431
|
// src/commands/telemetry/index.ts
|
|
8261
8432
|
function createTelemetryCommand() {
|
|
8262
|
-
const command = new
|
|
8433
|
+
const command = new Command77("telemetry").description("Telemetry identity and status management");
|
|
8263
8434
|
command.addCommand(createIdentifyCommand());
|
|
8264
8435
|
command.addCommand(createStatusCommand());
|
|
8436
|
+
command.addCommand(createTestCommand());
|
|
8265
8437
|
return command;
|
|
8266
8438
|
}
|
|
8267
8439
|
|
|
8268
8440
|
// src/commands/traceability.ts
|
|
8269
|
-
import { Command as
|
|
8441
|
+
import { Command as Command78 } from "commander";
|
|
8270
8442
|
import chalk11 from "chalk";
|
|
8271
8443
|
function confidenceLabel(maxConfidence) {
|
|
8272
8444
|
if (maxConfidence >= 0.8) return "explicit";
|
|
@@ -8382,7 +8554,7 @@ async function runTraceability(options) {
|
|
|
8382
8554
|
const projectPath = process.cwd();
|
|
8383
8555
|
const store = await loadGraphStore(projectPath);
|
|
8384
8556
|
if (!store) handleNoStore(mode);
|
|
8385
|
-
const graphModule = await import("./dist-
|
|
8557
|
+
const graphModule = await import("./dist-GRW3X2ZQ.js");
|
|
8386
8558
|
const filterOptions = buildFilterOptions(options);
|
|
8387
8559
|
const results = graphModule.queryTraceability(store, filterOptions);
|
|
8388
8560
|
if (results.length === 0) handleEmptyResults(mode);
|
|
@@ -8397,7 +8569,7 @@ async function runTraceability(options) {
|
|
|
8397
8569
|
process.exit(ExitCode.SUCCESS);
|
|
8398
8570
|
}
|
|
8399
8571
|
function createTraceabilityCommand() {
|
|
8400
|
-
return new
|
|
8572
|
+
return new Command78("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) => {
|
|
8401
8573
|
const globalOpts = cmd.optsWithGlobals();
|
|
8402
8574
|
await runTraceability({
|
|
8403
8575
|
spec: opts.spec,
|
|
@@ -8411,7 +8583,7 @@ function createTraceabilityCommand() {
|
|
|
8411
8583
|
|
|
8412
8584
|
// src/commands/uninstall.ts
|
|
8413
8585
|
import * as path60 from "path";
|
|
8414
|
-
import { Command as
|
|
8586
|
+
import { Command as Command79 } from "commander";
|
|
8415
8587
|
async function runUninstall(skillName, options) {
|
|
8416
8588
|
const packageName = resolvePackageName(skillName);
|
|
8417
8589
|
const shortName = extractSkillName(packageName);
|
|
@@ -8448,7 +8620,7 @@ async function runUninstall(skillName, options) {
|
|
|
8448
8620
|
return result;
|
|
8449
8621
|
}
|
|
8450
8622
|
function createUninstallCommand() {
|
|
8451
|
-
const cmd = new
|
|
8623
|
+
const cmd = new Command79("uninstall");
|
|
8452
8624
|
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) => {
|
|
8453
8625
|
try {
|
|
8454
8626
|
const result = await runUninstall(skill, opts);
|
|
@@ -8470,7 +8642,7 @@ function createUninstallCommand() {
|
|
|
8470
8642
|
init_dist();
|
|
8471
8643
|
import * as fs40 from "fs/promises";
|
|
8472
8644
|
import * as path61 from "path";
|
|
8473
|
-
import { Command as
|
|
8645
|
+
import { Command as Command80 } from "commander";
|
|
8474
8646
|
async function runUninstallConstraints(options) {
|
|
8475
8647
|
const { packageName, configPath, lockfilePath } = options;
|
|
8476
8648
|
const lockfileResult = await readLockfile(lockfilePath);
|
|
@@ -8527,7 +8699,7 @@ async function runUninstallConstraints(options) {
|
|
|
8527
8699
|
};
|
|
8528
8700
|
}
|
|
8529
8701
|
function createUninstallConstraintsCommand() {
|
|
8530
|
-
const cmd = new
|
|
8702
|
+
const cmd = new Command80("uninstall-constraints");
|
|
8531
8703
|
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) => {
|
|
8532
8704
|
let configPath;
|
|
8533
8705
|
if (opts.config) {
|
|
@@ -8566,10 +8738,10 @@ function createUninstallConstraintsCommand() {
|
|
|
8566
8738
|
}
|
|
8567
8739
|
|
|
8568
8740
|
// src/commands/update.ts
|
|
8569
|
-
import { Command as
|
|
8741
|
+
import { Command as Command81 } from "commander";
|
|
8570
8742
|
import { execFile, execFileSync as execFileSync6 } from "child_process";
|
|
8571
|
-
import { realpathSync, existsSync as
|
|
8572
|
-
import { join as
|
|
8743
|
+
import { realpathSync, existsSync as existsSync37, readFileSync as readFileSync26 } from "fs";
|
|
8744
|
+
import { join as join48 } from "path";
|
|
8573
8745
|
import { promisify } from "util";
|
|
8574
8746
|
import readline3 from "readline";
|
|
8575
8747
|
import chalk12 from "chalk";
|
|
@@ -8635,10 +8807,10 @@ function prompt2(question) {
|
|
|
8635
8807
|
input: process.stdin,
|
|
8636
8808
|
output: process.stdout
|
|
8637
8809
|
});
|
|
8638
|
-
return new Promise((
|
|
8810
|
+
return new Promise((resolve36) => {
|
|
8639
8811
|
rl.question(question, (answer) => {
|
|
8640
8812
|
rl.close();
|
|
8641
|
-
|
|
8813
|
+
resolve36(answer.trim().toLowerCase());
|
|
8642
8814
|
});
|
|
8643
8815
|
});
|
|
8644
8816
|
}
|
|
@@ -8653,12 +8825,12 @@ async function ensureTelemetryIfNeeded() {
|
|
|
8653
8825
|
}
|
|
8654
8826
|
function refreshHooks() {
|
|
8655
8827
|
const cwd = process.cwd();
|
|
8656
|
-
const configPath =
|
|
8657
|
-
if (!
|
|
8828
|
+
const configPath = join48(cwd, "harness.config.json");
|
|
8829
|
+
if (!existsSync37(configPath)) return;
|
|
8658
8830
|
let profile = "standard";
|
|
8659
|
-
const profilePath =
|
|
8831
|
+
const profilePath = join48(cwd, ".harness", "hooks", "profile.json");
|
|
8660
8832
|
try {
|
|
8661
|
-
const data = JSON.parse(
|
|
8833
|
+
const data = JSON.parse(readFileSync26(profilePath, "utf-8"));
|
|
8662
8834
|
if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
|
|
8663
8835
|
profile = data.profile;
|
|
8664
8836
|
}
|
|
@@ -8784,7 +8956,7 @@ async function runUpdateAction(opts, globalOpts) {
|
|
|
8784
8956
|
process.exit(ExitCode.SUCCESS);
|
|
8785
8957
|
}
|
|
8786
8958
|
function createUpdateCommand() {
|
|
8787
|
-
return new
|
|
8959
|
+
return new Command81("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(
|
|
8788
8960
|
"--regenerate",
|
|
8789
8961
|
"Only regenerate slash commands and agent definitions (skip package updates)"
|
|
8790
8962
|
).action(async (opts, cmd) => {
|
|
@@ -8794,9 +8966,9 @@ function createUpdateCommand() {
|
|
|
8794
8966
|
}
|
|
8795
8967
|
|
|
8796
8968
|
// src/commands/usage.ts
|
|
8797
|
-
import { Command as
|
|
8969
|
+
import { Command as Command82 } from "commander";
|
|
8798
8970
|
async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
|
|
8799
|
-
const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-
|
|
8971
|
+
const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-T3DGV5UN.js");
|
|
8800
8972
|
const records = readCostRecords(cwd);
|
|
8801
8973
|
if (includeClaudeSessions) {
|
|
8802
8974
|
const ccRecords = parseCCRecords();
|
|
@@ -8840,6 +9012,41 @@ function formatModels(models) {
|
|
|
8840
9012
|
if (models.length === 1) return models[0] ?? "unknown";
|
|
8841
9013
|
return `${models[0] ?? "unknown"} and ${models.length - 1} other${models.length - 1 > 1 ? "s" : ""}`;
|
|
8842
9014
|
}
|
|
9015
|
+
function enrichDayForJson(day, pricingData) {
|
|
9016
|
+
const hitRate = computeCacheHitRate(day.cacheReadTokens, day.tokens.inputTokens);
|
|
9017
|
+
const savings = computeCacheSavings(day.cacheReadTokens, day.models[0], pricingData);
|
|
9018
|
+
return {
|
|
9019
|
+
...day,
|
|
9020
|
+
...hitRate != null ? { cacheHitRate: Math.round(hitRate * 1e3) / 1e3 } : {},
|
|
9021
|
+
...savings != null ? { cacheSavingsMicroUSD: savings } : {}
|
|
9022
|
+
};
|
|
9023
|
+
}
|
|
9024
|
+
function formatDayCacheColumns(day, pricingData) {
|
|
9025
|
+
const rate = computeCacheHitRate(day.cacheReadTokens, day.tokens.inputTokens);
|
|
9026
|
+
const savings = computeCacheSavings(day.cacheReadTokens, day.models[0], pricingData);
|
|
9027
|
+
const rateStr = rate != null ? formatPercent(rate).padStart(5) : " -";
|
|
9028
|
+
const savingsStr = savings != null ? formatMicroUSD(savings).padStart(7) : " N/A";
|
|
9029
|
+
return " | " + rateStr + " | " + savingsStr;
|
|
9030
|
+
}
|
|
9031
|
+
function printDailyTable(limited, pricingData) {
|
|
9032
|
+
const hasCacheData = limited.some((d) => d.cacheReadTokens != null && d.cacheReadTokens > 0);
|
|
9033
|
+
const cacheHeader = hasCacheData ? " | Cache | Saved " : "";
|
|
9034
|
+
const cacheDivider = hasCacheData ? " | ------ | -------" : "";
|
|
9035
|
+
const header = "Date | Sessions | Input | Output | Model(s) | Cost " + cacheHeader;
|
|
9036
|
+
const divider = "-------------|----------|-----------|-----------|------------------------------|-------" + cacheDivider;
|
|
9037
|
+
logger.info(header);
|
|
9038
|
+
logger.info(divider);
|
|
9039
|
+
for (const day of limited) {
|
|
9040
|
+
const date = day.date.padEnd(12);
|
|
9041
|
+
const sessions = String(day.sessionCount).padStart(8);
|
|
9042
|
+
const input = formatTokenCount(day.tokens.inputTokens).padStart(9);
|
|
9043
|
+
const output = formatTokenCount(day.tokens.outputTokens).padStart(9);
|
|
9044
|
+
const models = formatModels(day.models).padEnd(28);
|
|
9045
|
+
const cost = formatMicroUSD(day.costMicroUSD);
|
|
9046
|
+
const cacheCol = hasCacheData ? formatDayCacheColumns(day, pricingData) : "";
|
|
9047
|
+
logger.info(`${date} | ${sessions} | ${input} | ${output} | ${models} | ${cost}${cacheCol}`);
|
|
9048
|
+
}
|
|
9049
|
+
}
|
|
8843
9050
|
function registerDailyCommand(usage) {
|
|
8844
9051
|
usage.command("daily").description("Show per-day token usage and cost").option("--days <n>", "Number of days to show (default: 7, max: 90)", "7").action(async (opts, cmd) => {
|
|
8845
9052
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -8850,54 +9057,23 @@ function registerDailyCommand(usage) {
|
|
|
8850
9057
|
globalOpts.includeClaudeSessions
|
|
8851
9058
|
);
|
|
8852
9059
|
if (records.length === 0) {
|
|
8853
|
-
if (globalOpts.json)
|
|
8854
|
-
|
|
8855
|
-
} else {
|
|
8856
|
-
logger.info("No usage data found. Run some harness sessions first.");
|
|
8857
|
-
}
|
|
9060
|
+
if (globalOpts.json) console.log(JSON.stringify([]));
|
|
9061
|
+
else logger.info("No usage data found. Run some harness sessions first.");
|
|
8858
9062
|
return;
|
|
8859
9063
|
}
|
|
8860
|
-
const { aggregateByDay } = await import("./dist-
|
|
8861
|
-
const
|
|
8862
|
-
const limited = dailyData.slice(0, days);
|
|
9064
|
+
const { aggregateByDay } = await import("./dist-T3DGV5UN.js");
|
|
9065
|
+
const limited = aggregateByDay(records).slice(0, days);
|
|
8863
9066
|
if (globalOpts.json) {
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
...savings != null ? { cacheSavingsMicroUSD: savings } : {}
|
|
8871
|
-
};
|
|
8872
|
-
});
|
|
8873
|
-
console.log(JSON.stringify(enriched, null, 2));
|
|
8874
|
-
return;
|
|
8875
|
-
}
|
|
8876
|
-
const hasCacheData = limited.some((d) => d.cacheReadTokens != null && d.cacheReadTokens > 0);
|
|
8877
|
-
const cacheHeader = hasCacheData ? " | Cache | Saved " : "";
|
|
8878
|
-
const cacheDivider = hasCacheData ? " | ------ | -------" : "";
|
|
8879
|
-
const header = "Date | Sessions | Input | Output | Model(s) | Cost " + cacheHeader;
|
|
8880
|
-
const divider = "-------------|----------|-----------|-----------|------------------------------|-------" + cacheDivider;
|
|
8881
|
-
logger.info(header);
|
|
8882
|
-
logger.info(divider);
|
|
8883
|
-
for (const day of limited) {
|
|
8884
|
-
const date = day.date.padEnd(12);
|
|
8885
|
-
const sessions = String(day.sessionCount).padStart(8);
|
|
8886
|
-
const input = formatTokenCount(day.tokens.inputTokens).padStart(9);
|
|
8887
|
-
const output = formatTokenCount(day.tokens.outputTokens).padStart(9);
|
|
8888
|
-
const models = formatModels(day.models).padEnd(28);
|
|
8889
|
-
const cost = formatMicroUSD(day.costMicroUSD);
|
|
8890
|
-
const cacheCol = hasCacheData ? (() => {
|
|
8891
|
-
const rate = computeCacheHitRate(day.cacheReadTokens, day.tokens.inputTokens);
|
|
8892
|
-
const savings = computeCacheSavings(day.cacheReadTokens, day.models[0], pricingData);
|
|
8893
|
-
const rateStr = rate != null ? formatPercent(rate).padStart(5) : " -";
|
|
8894
|
-
const savingsStr = savings != null ? formatMicroUSD(savings).padStart(7) : " N/A";
|
|
8895
|
-
return " | " + rateStr + " | " + savingsStr;
|
|
8896
|
-
})() : "";
|
|
8897
|
-
logger.info(
|
|
8898
|
-
`${date} | ${sessions} | ${input} | ${output} | ${models} | ${cost}${cacheCol}`
|
|
9067
|
+
console.log(
|
|
9068
|
+
JSON.stringify(
|
|
9069
|
+
limited.map((d) => enrichDayForJson(d, pricingData)),
|
|
9070
|
+
null,
|
|
9071
|
+
2
|
|
9072
|
+
)
|
|
8899
9073
|
);
|
|
9074
|
+
return;
|
|
8900
9075
|
}
|
|
9076
|
+
printDailyTable(limited, pricingData);
|
|
8901
9077
|
});
|
|
8902
9078
|
}
|
|
8903
9079
|
function registerSessionsCommand(usage) {
|
|
@@ -8914,7 +9090,7 @@ function registerSessionsCommand(usage) {
|
|
|
8914
9090
|
}
|
|
8915
9091
|
return;
|
|
8916
9092
|
}
|
|
8917
|
-
const { aggregateBySession } = await import("./dist-
|
|
9093
|
+
const { aggregateBySession } = await import("./dist-T3DGV5UN.js");
|
|
8918
9094
|
const sessionData = aggregateBySession(records);
|
|
8919
9095
|
const limited = sessionData.slice(0, limit);
|
|
8920
9096
|
if (globalOpts.json) {
|
|
@@ -8994,7 +9170,7 @@ function registerSessionCommand(usage) {
|
|
|
8994
9170
|
cwd,
|
|
8995
9171
|
globalOpts.includeClaudeSessions
|
|
8996
9172
|
);
|
|
8997
|
-
const { aggregateBySession } = await import("./dist-
|
|
9173
|
+
const { aggregateBySession } = await import("./dist-T3DGV5UN.js");
|
|
8998
9174
|
const sessionData = aggregateBySession(records);
|
|
8999
9175
|
const match = sessionData.find((s) => s.sessionId === id);
|
|
9000
9176
|
if (!match) {
|
|
@@ -9029,7 +9205,7 @@ function registerLatestCommand(usage) {
|
|
|
9029
9205
|
}
|
|
9030
9206
|
return;
|
|
9031
9207
|
}
|
|
9032
|
-
const { aggregateBySession } = await import("./dist-
|
|
9208
|
+
const { aggregateBySession } = await import("./dist-T3DGV5UN.js");
|
|
9033
9209
|
const sessionData = aggregateBySession(records);
|
|
9034
9210
|
const latest = sessionData[0];
|
|
9035
9211
|
if (!latest) {
|
|
@@ -9055,7 +9231,7 @@ function registerLatestCommand(usage) {
|
|
|
9055
9231
|
});
|
|
9056
9232
|
}
|
|
9057
9233
|
function createUsageCommand() {
|
|
9058
|
-
const usage = new
|
|
9234
|
+
const usage = new Command82("usage").description("Token usage and cost tracking");
|
|
9059
9235
|
usage.option(
|
|
9060
9236
|
"--include-claude-sessions",
|
|
9061
9237
|
"Include Claude Code session data from ~/.claude/projects/"
|
|
@@ -9070,7 +9246,7 @@ function createUsageCommand() {
|
|
|
9070
9246
|
// src/commands/validate.ts
|
|
9071
9247
|
init_dist();
|
|
9072
9248
|
init_dist();
|
|
9073
|
-
import { Command as
|
|
9249
|
+
import { Command as Command83 } from "commander";
|
|
9074
9250
|
import * as path62 from "path";
|
|
9075
9251
|
async function runValidate(options) {
|
|
9076
9252
|
const configResult = resolveConfig(options.configPath);
|
|
@@ -9153,7 +9329,7 @@ function resolveValidateMode(globalOpts) {
|
|
|
9153
9329
|
return OutputMode.TEXT;
|
|
9154
9330
|
}
|
|
9155
9331
|
async function printCrossCheckWarnings(mode) {
|
|
9156
|
-
const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-
|
|
9332
|
+
const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-LJKXBQYH.js");
|
|
9157
9333
|
const cwd = process.cwd();
|
|
9158
9334
|
const crossResult = await runCrossCheck2({
|
|
9159
9335
|
specsDir: path62.join(cwd, "docs", "specs"),
|
|
@@ -9169,7 +9345,7 @@ async function printCrossCheckWarnings(mode) {
|
|
|
9169
9345
|
${crossResult.value.warnings} warnings`);
|
|
9170
9346
|
}
|
|
9171
9347
|
function createValidateCommand3() {
|
|
9172
|
-
const command = new
|
|
9348
|
+
const command = new Command83("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
|
|
9173
9349
|
"--agent-configs",
|
|
9174
9350
|
"Validate agent configs (CLAUDE.md, hooks, skills) via agnix or built-in fallback rules"
|
|
9175
9351
|
).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()));
|
|
@@ -9278,7 +9454,7 @@ var commandCreators = [
|
|
|
9278
9454
|
|
|
9279
9455
|
// src/index.ts
|
|
9280
9456
|
function createProgram() {
|
|
9281
|
-
const program = new
|
|
9457
|
+
const program = new Command84();
|
|
9282
9458
|
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");
|
|
9283
9459
|
for (const creator of commandCreators) {
|
|
9284
9460
|
program.addCommand(creator());
|
|
@@ -9298,6 +9474,7 @@ export {
|
|
|
9298
9474
|
printFirstRunWelcome,
|
|
9299
9475
|
buildPreamble,
|
|
9300
9476
|
runSnapshotCapture,
|
|
9477
|
+
installCommandTelemetry,
|
|
9301
9478
|
runUninstall,
|
|
9302
9479
|
runUninstallConstraints,
|
|
9303
9480
|
createProgram
|