@harness-engineering/cli 2.3.1 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/skills/claude-code/harness-compliance/SKILL.md +19 -0
- package/dist/agents/skills/codex/harness-compliance/SKILL.md +19 -0
- package/dist/agents/skills/cursor/harness-compliance/SKILL.md +19 -0
- package/dist/agents/skills/gemini-cli/harness-compliance/SKILL.md +19 -0
- package/dist/agents-md-2M46KG4F.js +10 -0
- package/dist/{architecture-544ISXDI.js → architecture-3ZSN5RDQ.js} +5 -5
- package/dist/{assess-project-PBO6XFJC.js → assess-project-KZWFQEJE.js} +5 -3
- package/dist/bin/harness-mcp.js +16 -16
- package/dist/bin/harness.js +29 -27
- package/dist/{check-phase-gate-BZU4DGF3.js → check-phase-gate-EWV5VYTG.js} +5 -5
- package/dist/{chunk-YNG7BWGB.js → chunk-2TGCYJMT.js} +340 -12
- package/dist/{chunk-TIQU5VY7.js → chunk-5FDBXUFW.js} +1 -1
- package/dist/{chunk-7BNK4M23.js → chunk-5XLLIYYL.js} +1 -1
- package/dist/{chunk-KJR4Z2YC.js → chunk-73KZ2E47.js} +9 -9
- package/dist/{chunk-J4MX5DIA.js → chunk-7RZZV73V.js} +5 -5
- package/dist/{chunk-TIJXG4UB.js → chunk-B2ZYMQGT.js} +64 -30
- package/dist/{chunk-XPRGWHBL.js → chunk-BCFDGOMA.js} +1 -1
- package/dist/{chunk-YI6NTL72.js → chunk-GLKASJZE.js} +6 -6
- package/dist/{chunk-N6DVSOLZ.js → chunk-GOSUZC5H.js} +608 -211
- package/dist/{chunk-22OKI5QI.js → chunk-I2KULMPD.js} +10 -10
- package/dist/{chunk-R6GLLMRZ.js → chunk-IEHXZB6J.js} +9 -9
- package/dist/{chunk-U2SF3KAQ.js → chunk-KOK7BFP2.js} +3 -3
- package/dist/{chunk-QZ67TDLJ.js → chunk-KRQTN46U.js} +3 -3
- package/dist/{chunk-EMJFHTPZ.js → chunk-LHHO7AH4.js} +3 -3
- package/dist/{chunk-2564TBT6.js → chunk-LJF6UY4R.js} +2 -2
- package/dist/{chunk-DBJC4ULT.js → chunk-MXOQEI72.js} +48 -8
- package/dist/{chunk-JMACX5FN.js → chunk-NM3ZIWVN.js} +2 -2
- package/dist/{chunk-KT5PWWWO.js → chunk-NTOKQJOX.js} +2 -2
- package/dist/chunk-O63AAPIZ.js +190 -0
- package/dist/{chunk-WMZKZCCE.js → chunk-OUXYITL5.js} +2 -2
- package/dist/{chunk-T2ZMHXCX.js → chunk-PPQ3TY2R.js} +2 -2
- package/dist/{chunk-LBYGGNEZ.js → chunk-QV5EBDWA.js} +1 -1
- package/dist/{chunk-IYA3NS5P.js → chunk-RRTTJ3VB.js} +2 -2
- package/dist/{chunk-A36MGB3V.js → chunk-TPNA2I4J.js} +206 -97
- package/dist/{chunk-LYMPKO6N.js → chunk-UPV7VDUB.js} +2 -2
- package/dist/{chunk-DHWFOHPX.js → chunk-UQJV7NNM.js} +2 -2
- package/dist/ci-workflow-5TBUHJFC.js +10 -0
- package/dist/{dist-ZS3Y3YWP.js → dist-HA6IIPRC.js} +41 -3
- package/dist/dist-O733ZU6I.js +49 -0
- package/dist/{dist-SQAOKWXM.js → dist-QPWXPCPL.js} +1 -1
- package/dist/{docs-VW2KDPI3.js → docs-D6WI2LCF.js} +5 -5
- package/dist/engine-GBEVIZZQ.js +10 -0
- package/dist/{entropy-P62LCVJI.js → entropy-V6M4KJDC.js} +4 -4
- package/dist/{feedback-O3TZAPGX.js → feedback-22I4HHXM.js} +1 -1
- package/dist/{generate-agent-definitions-WVCOZDKI.js → generate-agent-definitions-UM7T3WLA.js} +5 -5
- package/dist/{glob-helper-JE3MO4UD.js → glob-helper-XE2UGEOV.js} +1 -1
- package/dist/{graph-loader-TJU4E7KL.js → graph-loader-EQBOIHFZ.js} +1 -1
- package/dist/index.d.ts +158 -2
- package/dist/index.js +26 -26
- package/dist/loader-5V72NYMF.js +12 -0
- package/dist/{mcp-ST26QMDK.js → mcp-5KQGFG5U.js} +16 -16
- package/dist/{performance-5HQG3IU6.js → performance-MVORVVMG.js} +5 -5
- package/dist/{review-pipeline-VRDL5A7J.js → review-pipeline-JYSVCNGJ.js} +4 -4
- package/dist/runtime-KZC2OQI7.js +11 -0
- package/dist/{scan-SFX5U3TE.js → scan-4PPP6ZXT.js} +1 -1
- package/dist/{security-IMFAE6MW.js → security-WOVOBLCI.js} +1 -1
- package/dist/{tool-tiers-7QGZ3FKY.js → tool-tiers-QVWKAZX4.js} +5 -1
- package/dist/{validate-GW2DG64P.js → validate-55HGQKWR.js} +5 -5
- package/dist/validate-cross-check-H3PSV4VY.js +10 -0
- package/package.json +5 -5
- package/dist/agents-md-5JG3AE5A.js +0 -10
- package/dist/chunk-RL4VMEXL.js +0 -53
- package/dist/ci-workflow-ZO6FPO3V.js +0 -10
- package/dist/dist-3EWNRFFQ.js +0 -21
- package/dist/engine-LFQ2JSHY.js +0 -10
- package/dist/loader-UB2A65DN.js +0 -12
- package/dist/runtime-TQQT2MWQ.js +0 -11
- package/dist/validate-cross-check-F5YQVXLT.js +0 -10
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateRuntime
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OUXYITL5.js";
|
|
4
4
|
import {
|
|
5
5
|
generateAgentsMd
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RRTTJ3VB.js";
|
|
7
7
|
import {
|
|
8
8
|
generateCIWorkflow
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-UQJV7NNM.js";
|
|
10
10
|
import {
|
|
11
11
|
TemplateEngine
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-NM3ZIWVN.js";
|
|
13
13
|
import {
|
|
14
14
|
generate,
|
|
15
15
|
validate
|
|
@@ -28,22 +28,22 @@ import {
|
|
|
28
28
|
OutputMode,
|
|
29
29
|
createCheckPhaseGateCommand,
|
|
30
30
|
findFiles
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-KOK7BFP2.js";
|
|
32
32
|
import {
|
|
33
33
|
createGenerateAgentDefinitionsCommand,
|
|
34
34
|
generateAgentDefinitions
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-QV5EBDWA.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-NTOKQJOX.js";
|
|
43
43
|
import {
|
|
44
44
|
createScanCommand,
|
|
45
45
|
loadIngestOptions
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-5XLLIYYL.js";
|
|
47
47
|
import {
|
|
48
48
|
appendFrameworkAgents,
|
|
49
49
|
captureHealthSnapshot,
|
|
@@ -57,17 +57,18 @@ import {
|
|
|
57
57
|
loadCachedSnapshot,
|
|
58
58
|
persistToolingConfig,
|
|
59
59
|
recommend
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-TPNA2I4J.js";
|
|
61
61
|
import {
|
|
62
62
|
loadGraphStore
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-5FDBXUFW.js";
|
|
64
64
|
import {
|
|
65
65
|
loadOrRebuildIndex
|
|
66
66
|
} from "./chunk-27AJKSQY.js";
|
|
67
67
|
import {
|
|
68
|
+
BranchingConfigSchema,
|
|
68
69
|
findConfigFile,
|
|
69
70
|
resolveConfig
|
|
70
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-MXOQEI72.js";
|
|
71
72
|
import {
|
|
72
73
|
VALID_PLATFORMS
|
|
73
74
|
} from "./chunk-3ISINLYT.js";
|
|
@@ -131,6 +132,7 @@ import {
|
|
|
131
132
|
getOrCreateInstallId,
|
|
132
133
|
gitScan,
|
|
133
134
|
init_dist as init_dist2,
|
|
135
|
+
invalidateCheckState,
|
|
134
136
|
isoWeek,
|
|
135
137
|
listStreams,
|
|
136
138
|
listTaintedSessions,
|
|
@@ -163,6 +165,7 @@ import {
|
|
|
163
165
|
setActiveStream,
|
|
164
166
|
validateAgentConfigs,
|
|
165
167
|
validateAgentsMap,
|
|
168
|
+
validateBranchName,
|
|
166
169
|
validateDependencies,
|
|
167
170
|
validateKnowledgeMap,
|
|
168
171
|
validatePulseConfig,
|
|
@@ -170,15 +173,15 @@ import {
|
|
|
170
173
|
validateSolutionsDir,
|
|
171
174
|
writeConfig,
|
|
172
175
|
writeLockfile
|
|
173
|
-
} from "./chunk-
|
|
176
|
+
} from "./chunk-2TGCYJMT.js";
|
|
174
177
|
import {
|
|
175
178
|
Err,
|
|
176
179
|
Ok
|
|
177
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-O63AAPIZ.js";
|
|
178
181
|
import {
|
|
179
182
|
DEFAULT_SKIP_DIRS,
|
|
180
183
|
init_dist
|
|
181
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-BCFDGOMA.js";
|
|
182
185
|
import {
|
|
183
186
|
createCreateSkillCommand
|
|
184
187
|
} from "./chunk-ZP5E7YET.js";
|
|
@@ -199,7 +202,7 @@ import {
|
|
|
199
202
|
} from "./chunk-KFQGP6VL.js";
|
|
200
203
|
|
|
201
204
|
// src/index.ts
|
|
202
|
-
import { Command as
|
|
205
|
+
import { Command as Command97 } from "commander";
|
|
203
206
|
|
|
204
207
|
// src/commands/add.ts
|
|
205
208
|
init_dist2();
|
|
@@ -388,7 +391,7 @@ function registerSkillsCommand(adoption) {
|
|
|
388
391
|
const globalOpts = cmd.optsWithGlobals();
|
|
389
392
|
const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
|
|
390
393
|
const cwd = process.cwd();
|
|
391
|
-
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-
|
|
394
|
+
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-HA6IIPRC.js");
|
|
392
395
|
const records = readAdoptionRecords(cwd);
|
|
393
396
|
if (records.length === 0) {
|
|
394
397
|
if (globalOpts.json) {
|
|
@@ -424,7 +427,7 @@ function registerRecentCommand(adoption) {
|
|
|
424
427
|
const globalOpts = cmd.optsWithGlobals();
|
|
425
428
|
const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
|
|
426
429
|
const cwd = process.cwd();
|
|
427
|
-
const { readAdoptionRecords } = await import("./dist-
|
|
430
|
+
const { readAdoptionRecords } = await import("./dist-HA6IIPRC.js");
|
|
428
431
|
const records = readAdoptionRecords(cwd);
|
|
429
432
|
if (records.length === 0) {
|
|
430
433
|
if (globalOpts.json) {
|
|
@@ -502,7 +505,7 @@ function registerSkillCommand(adoption) {
|
|
|
502
505
|
adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
|
|
503
506
|
const globalOpts = cmd.optsWithGlobals();
|
|
504
507
|
const cwd = process.cwd();
|
|
505
|
-
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-
|
|
508
|
+
const { readAdoptionRecords, aggregateBySkill } = await import("./dist-HA6IIPRC.js");
|
|
506
509
|
const records = readAdoptionRecords(cwd);
|
|
507
510
|
const skillRecords = records.filter((r) => r.skill === name);
|
|
508
511
|
if (skillRecords.length === 0) {
|
|
@@ -2826,8 +2829,168 @@ function createFixDriftCommand() {
|
|
|
2826
2829
|
return command;
|
|
2827
2830
|
}
|
|
2828
2831
|
|
|
2829
|
-
// src/commands/
|
|
2832
|
+
// src/commands/gateway/index.ts
|
|
2833
|
+
import { Command as Command26 } from "commander";
|
|
2834
|
+
|
|
2835
|
+
// src/commands/gateway/token.ts
|
|
2830
2836
|
import { Command as Command24 } from "commander";
|
|
2837
|
+
import { resolve as resolve14 } from "path";
|
|
2838
|
+
import { TokenStore } from "@harness-engineering/orchestrator";
|
|
2839
|
+
function getStore() {
|
|
2840
|
+
const p = process.env["HARNESS_TOKENS_PATH"] ?? resolve14(".harness", "tokens.json");
|
|
2841
|
+
return new TokenStore(p);
|
|
2842
|
+
}
|
|
2843
|
+
async function runTokenCreate(opts) {
|
|
2844
|
+
const store = getStore();
|
|
2845
|
+
const result = await store.create(opts);
|
|
2846
|
+
return { id: result.id, token: result.token };
|
|
2847
|
+
}
|
|
2848
|
+
async function runTokenList() {
|
|
2849
|
+
const store = getStore();
|
|
2850
|
+
return store.list();
|
|
2851
|
+
}
|
|
2852
|
+
async function runTokenRevoke(id) {
|
|
2853
|
+
const store = getStore();
|
|
2854
|
+
return store.revoke(id);
|
|
2855
|
+
}
|
|
2856
|
+
function createTokenCommand() {
|
|
2857
|
+
const cmd = new Command24("token").description("Manage Gateway API tokens");
|
|
2858
|
+
cmd.command("create").description("Create a new auth token. Secret is shown ONCE.").requiredOption("--name <name>", "Human label").requiredOption("--scopes <scopes>", "Comma-separated scopes").option("--bridge <kind>", "slack | discord | github-app | custom").option("--tenant <id>", "Tenant identifier").option("--expires <iso>", "Expiry ISO-8601").action(
|
|
2859
|
+
async (opts) => {
|
|
2860
|
+
const scopes = opts.scopes.split(",").map((s) => s.trim());
|
|
2861
|
+
const input = { name: opts.name, scopes };
|
|
2862
|
+
if (opts.bridge) input.bridgeKind = opts.bridge;
|
|
2863
|
+
if (opts.tenant) input.tenantId = opts.tenant;
|
|
2864
|
+
if (opts.expires) input.expiresAt = opts.expires;
|
|
2865
|
+
const out = await runTokenCreate(input);
|
|
2866
|
+
console.log(JSON.stringify(out, null, 2));
|
|
2867
|
+
console.log("\nWARNING: Save this token now \u2014 it will NEVER be shown again.");
|
|
2868
|
+
}
|
|
2869
|
+
);
|
|
2870
|
+
cmd.command("list").description("List all tokens (secrets redacted)").action(async () => {
|
|
2871
|
+
const tokens = await runTokenList();
|
|
2872
|
+
console.log(JSON.stringify(tokens, null, 2));
|
|
2873
|
+
});
|
|
2874
|
+
cmd.command("revoke <id>").description("Delete a token by id").action(async (id) => {
|
|
2875
|
+
const ok = await runTokenRevoke(id);
|
|
2876
|
+
if (ok) console.log(`Revoked ${id}`);
|
|
2877
|
+
else {
|
|
2878
|
+
console.error(`No such token: ${id}`);
|
|
2879
|
+
process.exitCode = 1;
|
|
2880
|
+
}
|
|
2881
|
+
});
|
|
2882
|
+
return cmd;
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2885
|
+
// src/commands/gateway/deliveries.ts
|
|
2886
|
+
import { Command as Command25 } from "commander";
|
|
2887
|
+
import { createInterface } from "readline";
|
|
2888
|
+
import { resolve as resolve15 } from "path";
|
|
2889
|
+
import { WebhookQueue } from "@harness-engineering/orchestrator";
|
|
2890
|
+
function resolveQueuePath() {
|
|
2891
|
+
return process.env["HARNESS_WEBHOOK_QUEUE_PATH"] ?? resolve15(".harness", "webhook-queue.sqlite");
|
|
2892
|
+
}
|
|
2893
|
+
function getQueue() {
|
|
2894
|
+
return new WebhookQueue(resolveQueuePath());
|
|
2895
|
+
}
|
|
2896
|
+
function runDeliveriesList(queue, filter) {
|
|
2897
|
+
return queue.list(filter);
|
|
2898
|
+
}
|
|
2899
|
+
function runDeliveriesRetry(queue, id) {
|
|
2900
|
+
return queue.retryDead(id);
|
|
2901
|
+
}
|
|
2902
|
+
async function runDeliveriesPurge(queue, opts, runOpts = {}) {
|
|
2903
|
+
const errOut = runOpts.errOut ?? process.stderr;
|
|
2904
|
+
if (!opts.deadOnly && opts.olderThanMs === void 0 && !opts.all) {
|
|
2905
|
+
errOut.write("purge requires one of: --dead-only, --older-than <ms>, --all\n");
|
|
2906
|
+
return -1;
|
|
2907
|
+
}
|
|
2908
|
+
if (runOpts.confirm) {
|
|
2909
|
+
const count = queue.previewPurge(opts);
|
|
2910
|
+
const ok = await runOpts.confirm(count);
|
|
2911
|
+
if (!ok) return -1;
|
|
2912
|
+
}
|
|
2913
|
+
return queue.purge(opts);
|
|
2914
|
+
}
|
|
2915
|
+
function promptYesNo(message) {
|
|
2916
|
+
return new Promise((resolveAns) => {
|
|
2917
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
2918
|
+
rl.question(message, (answer) => {
|
|
2919
|
+
rl.close();
|
|
2920
|
+
const a = answer.trim().toLowerCase();
|
|
2921
|
+
resolveAns(a === "y" || a === "yes");
|
|
2922
|
+
});
|
|
2923
|
+
});
|
|
2924
|
+
}
|
|
2925
|
+
function createDeliveriesCommand() {
|
|
2926
|
+
const cmd = new Command25("deliveries").description("Inspect and manage webhook delivery queue");
|
|
2927
|
+
cmd.command("list").description("List delivery queue entries (newest first; capped at 200 rows)").option("--status <status>", "Filter by status: pending|failed|delivered|dead").option("--subscription <id>", "Filter by subscription ID").action((opts) => {
|
|
2928
|
+
const queue = getQueue();
|
|
2929
|
+
try {
|
|
2930
|
+
const filter = {};
|
|
2931
|
+
if (opts.status) filter.status = opts.status;
|
|
2932
|
+
if (opts.subscription) filter.subscriptionId = opts.subscription;
|
|
2933
|
+
const rows = runDeliveriesList(queue, filter);
|
|
2934
|
+
console.log(JSON.stringify(rows, null, 2));
|
|
2935
|
+
} finally {
|
|
2936
|
+
queue.close();
|
|
2937
|
+
}
|
|
2938
|
+
});
|
|
2939
|
+
cmd.command("retry <id>").description("Re-enqueue a dead-lettered delivery by ID").action((id) => {
|
|
2940
|
+
const queue = getQueue();
|
|
2941
|
+
try {
|
|
2942
|
+
const ok = runDeliveriesRetry(queue, id);
|
|
2943
|
+
if (ok) {
|
|
2944
|
+
console.log(`Delivery ${id} re-enqueued.`);
|
|
2945
|
+
} else {
|
|
2946
|
+
console.error(`Delivery ${id} not found or not in dead status.`);
|
|
2947
|
+
process.exitCode = 1;
|
|
2948
|
+
}
|
|
2949
|
+
} finally {
|
|
2950
|
+
queue.close();
|
|
2951
|
+
}
|
|
2952
|
+
});
|
|
2953
|
+
cmd.command("purge").description("Delete delivery rows from the queue (requires at least one filter)").option("--dead-only", "Delete only dead-lettered rows").option("--older-than <ms>", "Delete delivered rows older than N milliseconds").option("--all", "Delete every row in the queue (use with caution)").action(async (opts) => {
|
|
2954
|
+
const queue = getQueue();
|
|
2955
|
+
try {
|
|
2956
|
+
const purgeOpts = {};
|
|
2957
|
+
if (opts.deadOnly) purgeOpts.deadOnly = true;
|
|
2958
|
+
if (opts.olderThan !== void 0) purgeOpts.olderThanMs = Number(opts.olderThan);
|
|
2959
|
+
if (opts.all) purgeOpts.all = true;
|
|
2960
|
+
const isTty = Boolean(process.stdout.isTTY);
|
|
2961
|
+
const runOpts = {};
|
|
2962
|
+
if (isTty) {
|
|
2963
|
+
runOpts.confirm = (count) => {
|
|
2964
|
+
if (count === 0) {
|
|
2965
|
+
console.log("No matching rows to delete.");
|
|
2966
|
+
return false;
|
|
2967
|
+
}
|
|
2968
|
+
return promptYesNo(`Delete ${count} row(s)? [y/N] `);
|
|
2969
|
+
};
|
|
2970
|
+
}
|
|
2971
|
+
const result = await runDeliveriesPurge(queue, purgeOpts, runOpts);
|
|
2972
|
+
if (result === -1) {
|
|
2973
|
+
process.exitCode = 1;
|
|
2974
|
+
return;
|
|
2975
|
+
}
|
|
2976
|
+
console.log(`Deleted ${result} row(s).`);
|
|
2977
|
+
} finally {
|
|
2978
|
+
queue.close();
|
|
2979
|
+
}
|
|
2980
|
+
});
|
|
2981
|
+
return cmd;
|
|
2982
|
+
}
|
|
2983
|
+
|
|
2984
|
+
// src/commands/gateway/index.ts
|
|
2985
|
+
function createGatewayCommand() {
|
|
2986
|
+
const cmd = new Command26("gateway").description("Gateway API administration");
|
|
2987
|
+
cmd.addCommand(createTokenCommand());
|
|
2988
|
+
cmd.addCommand(createDeliveriesCommand());
|
|
2989
|
+
return cmd;
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
// src/commands/generate.ts
|
|
2993
|
+
import { Command as Command27 } from "commander";
|
|
2831
2994
|
function validatePlatforms(platforms) {
|
|
2832
2995
|
for (const p of platforms) {
|
|
2833
2996
|
if (!VALID_PLATFORMS.includes(p)) {
|
|
@@ -2887,13 +3050,13 @@ async function runGenerateAction(opts, globalOpts) {
|
|
|
2887
3050
|
}
|
|
2888
3051
|
}
|
|
2889
3052
|
function createGenerateCommand() {
|
|
2890
|
-
return new
|
|
3053
|
+
return new Command27("generate").description("Generate all platform integrations (slash commands + agent definitions)").option("--platforms <list>", "Target platforms (comma-separated)", "claude-code,gemini-cli").option("--global", "Write to global directories", false).option("--include-global", "Include built-in global skills", false).option("--output <dir>", "Custom output directory").option("--dry-run", "Show what would change without writing", false).option("--yes", "Skip deletion confirmation prompts", false).action(async (opts, cmd) => {
|
|
2891
3054
|
await runGenerateAction(opts, cmd.optsWithGlobals());
|
|
2892
3055
|
});
|
|
2893
3056
|
}
|
|
2894
3057
|
|
|
2895
3058
|
// src/commands/graph/index.ts
|
|
2896
|
-
import { Command as
|
|
3059
|
+
import { Command as Command30 } from "commander";
|
|
2897
3060
|
|
|
2898
3061
|
// src/commands/graph/status.ts
|
|
2899
3062
|
import * as path15 from "path";
|
|
@@ -2911,7 +3074,7 @@ async function readConnectorSyncStatus(graphDir) {
|
|
|
2911
3074
|
return result;
|
|
2912
3075
|
}
|
|
2913
3076
|
async function runGraphStatus(projectPath) {
|
|
2914
|
-
const { GraphStore, loadGraphMetadata } = await import("./dist-
|
|
3077
|
+
const { GraphStore, loadGraphMetadata } = await import("./dist-QPWXPCPL.js");
|
|
2915
3078
|
const graphDir = path15.join(projectPath, ".harness", "graph");
|
|
2916
3079
|
const metaResult = await loadGraphMetadata(graphDir);
|
|
2917
3080
|
if (metaResult.status === "not_found") {
|
|
@@ -2963,7 +3126,7 @@ async function runGraphStatus(projectPath) {
|
|
|
2963
3126
|
// src/commands/graph/export.ts
|
|
2964
3127
|
import * as path16 from "path";
|
|
2965
3128
|
async function runGraphExport(projectPath, format) {
|
|
2966
|
-
const { GraphStore } = await import("./dist-
|
|
3129
|
+
const { GraphStore } = await import("./dist-QPWXPCPL.js");
|
|
2967
3130
|
const graphDir = path16.join(projectPath, ".harness", "graph");
|
|
2968
3131
|
const store = new GraphStore();
|
|
2969
3132
|
const loaded = await store.load(graphDir);
|
|
@@ -2996,10 +3159,10 @@ async function runGraphExport(projectPath, format) {
|
|
|
2996
3159
|
import * as path19 from "path";
|
|
2997
3160
|
|
|
2998
3161
|
// src/commands/graph/query.ts
|
|
2999
|
-
import { Command as
|
|
3162
|
+
import { Command as Command28 } from "commander";
|
|
3000
3163
|
import * as path17 from "path";
|
|
3001
3164
|
async function runQuery(projectPath, rootNodeId, opts) {
|
|
3002
|
-
const { GraphStore, ContextQL } = await import("./dist-
|
|
3165
|
+
const { GraphStore, ContextQL } = await import("./dist-QPWXPCPL.js");
|
|
3003
3166
|
const store = new GraphStore();
|
|
3004
3167
|
const graphDir = path17.join(projectPath, ".harness", "graph");
|
|
3005
3168
|
const loaded = await store.load(graphDir);
|
|
@@ -3042,13 +3205,13 @@ async function runQueryAction(rootNodeId, opts, globalOpts) {
|
|
|
3042
3205
|
}
|
|
3043
3206
|
}
|
|
3044
3207
|
function createQueryCommand() {
|
|
3045
|
-
return new
|
|
3208
|
+
return new Command28("query").description("Query the knowledge graph").argument("<rootNodeId>", "Starting node ID").option("--depth <n>", "Max traversal depth", "3").option("--types <types>", "Comma-separated node types to include").option("--edges <edges>", "Comma-separated edge types to include").option("--bidirectional", "Traverse both directions").action(async (rootNodeId, opts, cmd) => {
|
|
3046
3209
|
await runQueryAction(rootNodeId, opts, cmd.optsWithGlobals());
|
|
3047
3210
|
});
|
|
3048
3211
|
}
|
|
3049
3212
|
|
|
3050
3213
|
// src/commands/graph/ingest.ts
|
|
3051
|
-
import { Command as
|
|
3214
|
+
import { Command as Command29 } from "commander";
|
|
3052
3215
|
import * as path18 from "path";
|
|
3053
3216
|
async function loadConnectorConfig(projectPath, source) {
|
|
3054
3217
|
try {
|
|
@@ -3096,7 +3259,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
3096
3259
|
ConfluenceConnector,
|
|
3097
3260
|
FigmaConnector,
|
|
3098
3261
|
MiroConnector
|
|
3099
|
-
} = await import("./dist-
|
|
3262
|
+
} = await import("./dist-QPWXPCPL.js");
|
|
3100
3263
|
const graphDir = path18.join(projectPath, ".harness", "graph");
|
|
3101
3264
|
const store = new GraphStore();
|
|
3102
3265
|
await store.load(graphDir);
|
|
@@ -3110,7 +3273,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
3110
3273
|
path18.join(projectPath, "docs", "changes")
|
|
3111
3274
|
);
|
|
3112
3275
|
const gitResult = await new GitIngestor(store).ingest(projectPath);
|
|
3113
|
-
const { createExtractionRunner } = await import("./dist-
|
|
3276
|
+
const { createExtractionRunner } = await import("./dist-QPWXPCPL.js");
|
|
3114
3277
|
const extractedDir = path18.join(projectPath, ".harness", "knowledge", "extracted");
|
|
3115
3278
|
const signalsResult = await createExtractionRunner().run(projectPath, store, extractedDir);
|
|
3116
3279
|
const syncManager = new SyncManager(store, graphDir);
|
|
@@ -3156,7 +3319,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
3156
3319
|
);
|
|
3157
3320
|
break;
|
|
3158
3321
|
case "business-signals": {
|
|
3159
|
-
const { createExtractionRunner } = await import("./dist-
|
|
3322
|
+
const { createExtractionRunner } = await import("./dist-QPWXPCPL.js");
|
|
3160
3323
|
const extractedDir = path18.join(projectPath, ".harness", "knowledge", "extracted");
|
|
3161
3324
|
result = await createExtractionRunner().run(projectPath, store, extractedDir);
|
|
3162
3325
|
break;
|
|
@@ -3193,7 +3356,7 @@ async function runIngest(projectPath, source, opts) {
|
|
|
3193
3356
|
return result;
|
|
3194
3357
|
}
|
|
3195
3358
|
function createIngestCommand() {
|
|
3196
|
-
return new
|
|
3359
|
+
return new Command29("ingest").description("Ingest data into the knowledge graph").option(
|
|
3197
3360
|
"--source <name>",
|
|
3198
3361
|
"Source to ingest (code, knowledge, git, requirements, business-signals, jira, slack, ci, confluence, figma, miro)"
|
|
3199
3362
|
).option("--all", "Run all sources (code, knowledge, git, and configured connectors)").option("--full", "Force full re-ingestion").action(async (opts, cmd) => {
|
|
@@ -3271,17 +3434,17 @@ async function runExportAction(opts, cmd) {
|
|
|
3271
3434
|
}
|
|
3272
3435
|
}
|
|
3273
3436
|
function createGraphCommand() {
|
|
3274
|
-
const graph = new
|
|
3437
|
+
const graph = new Command30("graph").description("Knowledge graph management");
|
|
3275
3438
|
graph.command("status").description("Show graph statistics").action(runStatusAction);
|
|
3276
3439
|
graph.command("export").description("Export graph").requiredOption("--format <format>", "Output format (json, mermaid)").action(runExportAction);
|
|
3277
3440
|
return graph;
|
|
3278
3441
|
}
|
|
3279
3442
|
|
|
3280
3443
|
// src/commands/hooks/index.ts
|
|
3281
|
-
import { Command as
|
|
3444
|
+
import { Command as Command35 } from "commander";
|
|
3282
3445
|
|
|
3283
3446
|
// src/commands/hooks/init.ts
|
|
3284
|
-
import { Command as
|
|
3447
|
+
import { Command as Command31 } from "commander";
|
|
3285
3448
|
import * as fs8 from "fs";
|
|
3286
3449
|
import * as path20 from "path";
|
|
3287
3450
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -3403,7 +3566,7 @@ function initHooks(options) {
|
|
|
3403
3566
|
return { copiedScripts, settingsPath, profilePath };
|
|
3404
3567
|
}
|
|
3405
3568
|
function createInitCommand2() {
|
|
3406
|
-
return new
|
|
3569
|
+
return new Command31("init").description("Install Claude Code hook configurations into the current project").option("--profile <profile>", "Hook profile: minimal, standard, or strict", "standard").action(async (opts, cmd) => {
|
|
3407
3570
|
const globalOpts = cmd.optsWithGlobals();
|
|
3408
3571
|
const profile = opts.profile;
|
|
3409
3572
|
if (!VALID_PROFILES.includes(profile)) {
|
|
@@ -3441,7 +3604,7 @@ function createInitCommand2() {
|
|
|
3441
3604
|
}
|
|
3442
3605
|
|
|
3443
3606
|
// src/commands/hooks/list.ts
|
|
3444
|
-
import { Command as
|
|
3607
|
+
import { Command as Command32 } from "commander";
|
|
3445
3608
|
import * as fs9 from "fs";
|
|
3446
3609
|
import * as path21 from "path";
|
|
3447
3610
|
function listHooks(projectDir) {
|
|
@@ -3474,7 +3637,7 @@ function listHooks(projectDir) {
|
|
|
3474
3637
|
return result;
|
|
3475
3638
|
}
|
|
3476
3639
|
function createListCommand() {
|
|
3477
|
-
return new
|
|
3640
|
+
return new Command32("list").description("Show installed hooks and active profile").action(async (_opts, cmd) => {
|
|
3478
3641
|
const globalOpts = cmd.optsWithGlobals();
|
|
3479
3642
|
const projectDir = process.cwd();
|
|
3480
3643
|
const result = listHooks(projectDir);
|
|
@@ -3495,7 +3658,7 @@ function createListCommand() {
|
|
|
3495
3658
|
}
|
|
3496
3659
|
|
|
3497
3660
|
// src/commands/hooks/remove.ts
|
|
3498
|
-
import { Command as
|
|
3661
|
+
import { Command as Command33 } from "commander";
|
|
3499
3662
|
import * as fs10 from "fs";
|
|
3500
3663
|
import * as path22 from "path";
|
|
3501
3664
|
function removeHooks(projectDir) {
|
|
@@ -3525,7 +3688,7 @@ function removeHooks(projectDir) {
|
|
|
3525
3688
|
return { removed, hooksDir, settingsCleaned };
|
|
3526
3689
|
}
|
|
3527
3690
|
function createRemoveCommand() {
|
|
3528
|
-
return new
|
|
3691
|
+
return new Command33("remove").description("Remove harness-managed hooks from the current project").action(async (_opts, cmd) => {
|
|
3529
3692
|
const globalOpts = cmd.optsWithGlobals();
|
|
3530
3693
|
const projectDir = process.cwd();
|
|
3531
3694
|
const result = removeHooks(projectDir);
|
|
@@ -3547,7 +3710,7 @@ function createRemoveCommand() {
|
|
|
3547
3710
|
}
|
|
3548
3711
|
|
|
3549
3712
|
// src/commands/hooks/add.ts
|
|
3550
|
-
import { Command as
|
|
3713
|
+
import { Command as Command34 } from "commander";
|
|
3551
3714
|
import * as fs11 from "fs";
|
|
3552
3715
|
import * as path23 from "path";
|
|
3553
3716
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -3604,7 +3767,7 @@ function addHooks(hookName, projectDir) {
|
|
|
3604
3767
|
return result;
|
|
3605
3768
|
}
|
|
3606
3769
|
function createAddCommand2() {
|
|
3607
|
-
return new
|
|
3770
|
+
return new Command34("add").argument("<hook-name>", "Hook name or alias (e.g., sentinel)").description("Add a hook without changing the profile").action(async (hookName, _opts, cmd) => {
|
|
3608
3771
|
const projectDir = process.cwd();
|
|
3609
3772
|
try {
|
|
3610
3773
|
const res = addHooks(hookName, projectDir);
|
|
@@ -3629,7 +3792,7 @@ function createAddCommand2() {
|
|
|
3629
3792
|
|
|
3630
3793
|
// src/commands/hooks/index.ts
|
|
3631
3794
|
function createHooksCommand() {
|
|
3632
|
-
const command = new
|
|
3795
|
+
const command = new Command35("hooks").description("Manage Claude Code hook configurations");
|
|
3633
3796
|
command.addCommand(createInitCommand2());
|
|
3634
3797
|
command.addCommand(createListCommand());
|
|
3635
3798
|
command.addCommand(createRemoveCommand());
|
|
@@ -3638,7 +3801,7 @@ function createHooksCommand() {
|
|
|
3638
3801
|
}
|
|
3639
3802
|
|
|
3640
3803
|
// src/commands/impact-preview.ts
|
|
3641
|
-
import { Command as
|
|
3804
|
+
import { Command as Command36 } from "commander";
|
|
3642
3805
|
import { execSync as execSync4 } from "child_process";
|
|
3643
3806
|
import * as path24 from "path";
|
|
3644
3807
|
import * as fs12 from "fs";
|
|
@@ -3837,7 +4000,7 @@ async function runImpactPreview(options) {
|
|
|
3837
4000
|
return formatImpactOutput(stagedFiles, acc, options);
|
|
3838
4001
|
}
|
|
3839
4002
|
function createImpactPreviewCommand() {
|
|
3840
|
-
const command = new
|
|
4003
|
+
const command = new Command36("impact-preview").description("Show blast radius of staged changes using the knowledge graph").option("--detailed", "Show all affected files instead of top items").option("--per-file", "Show impact per staged file instead of aggregate").option("--path <dir>", "Project root (default: cwd)").action(async (opts) => {
|
|
3841
4004
|
const output = await runImpactPreview({
|
|
3842
4005
|
detailed: opts.detailed,
|
|
3843
4006
|
perFile: opts.perFile,
|
|
@@ -3851,13 +4014,13 @@ function createImpactPreviewCommand() {
|
|
|
3851
4014
|
|
|
3852
4015
|
// src/commands/init.ts
|
|
3853
4016
|
init_dist2();
|
|
3854
|
-
import { Command as
|
|
4017
|
+
import { Command as Command38 } from "commander";
|
|
3855
4018
|
import chalk3 from "chalk";
|
|
3856
4019
|
import * as fs15 from "fs";
|
|
3857
4020
|
import * as path27 from "path";
|
|
3858
4021
|
|
|
3859
4022
|
// src/commands/setup-mcp.ts
|
|
3860
|
-
import { Command as
|
|
4023
|
+
import { Command as Command37 } from "commander";
|
|
3861
4024
|
import * as fs14 from "fs";
|
|
3862
4025
|
import * as path26 from "path";
|
|
3863
4026
|
import * as os2 from "os";
|
|
@@ -4018,7 +4181,12 @@ var ALL_MCP_TOOLS = [
|
|
|
4018
4181
|
"compact",
|
|
4019
4182
|
"detect_constraint_emergence",
|
|
4020
4183
|
"run_ci_checks",
|
|
4021
|
-
"generate_blueprint"
|
|
4184
|
+
"generate_blueprint",
|
|
4185
|
+
// Phase 2 Task 11 — Gateway API MCP wrappers
|
|
4186
|
+
"trigger_maintenance_job",
|
|
4187
|
+
"list_gateway_tokens",
|
|
4188
|
+
// Phase 3 Task 9 — Gateway API webhook wrapper
|
|
4189
|
+
"subscribe_webhook"
|
|
4022
4190
|
];
|
|
4023
4191
|
async function runCursorToolPicker() {
|
|
4024
4192
|
try {
|
|
@@ -4191,7 +4359,7 @@ function printMcpResult(configured, skipped, trustedFolder) {
|
|
|
4191
4359
|
console.log("");
|
|
4192
4360
|
}
|
|
4193
4361
|
function createSetupMcpCommand() {
|
|
4194
|
-
return new
|
|
4362
|
+
return new Command37("setup-mcp").description("Configure MCP server for AI agent integration").option(
|
|
4195
4363
|
"--client <client>",
|
|
4196
4364
|
"Client to configure (claude, gemini, codex, cursor, opencode, all)",
|
|
4197
4365
|
"all"
|
|
@@ -4337,7 +4505,7 @@ async function runInitAction2(opts) {
|
|
|
4337
4505
|
process.exit(ExitCode.SUCCESS);
|
|
4338
4506
|
}
|
|
4339
4507
|
function createInitCommand3() {
|
|
4340
|
-
const command = new
|
|
4508
|
+
const command = new Command38("init").description("Initialize a new harness-engineering project").option("-n, --name <name>", "Project name").option("-l, --level <level>", "Adoption level (basic, intermediate, advanced)", "basic").option("-t, --template <template>", "Specific template name (e.g. orchestrator)").option("--framework <framework>", "Framework overlay (nextjs)").option("--language <language>", "Target language (typescript, python, go, rust, java)").option("-f, --force", "Overwrite existing files").option("-y, --yes", "Use defaults without prompting").action(async (opts, cmd) => {
|
|
4341
4509
|
const globalOpts = cmd.optsWithGlobals();
|
|
4342
4510
|
await runInitAction2({
|
|
4343
4511
|
name: opts.name,
|
|
@@ -4356,7 +4524,7 @@ import * as fs20 from "fs";
|
|
|
4356
4524
|
import * as os5 from "os";
|
|
4357
4525
|
import * as path32 from "path";
|
|
4358
4526
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
4359
|
-
import { Command as
|
|
4527
|
+
import { Command as Command39 } from "commander";
|
|
4360
4528
|
import { parse as yamlParse } from "yaml";
|
|
4361
4529
|
|
|
4362
4530
|
// src/registry/npm-client.ts
|
|
@@ -4917,7 +5085,7 @@ async function runInstall(skillName, options) {
|
|
|
4917
5085
|
return result;
|
|
4918
5086
|
}
|
|
4919
5087
|
function createInstallCommand() {
|
|
4920
|
-
const cmd = new
|
|
5088
|
+
const cmd = new Command39("install");
|
|
4921
5089
|
cmd.description("Install skills from npm registry, local directory, or GitHub repository").argument("<skill>", 'Skill name, @harness-skills/scoped package, or "." for bulk install').option("--version <range>", "Semver range or exact version to install").option("--force", "Force reinstall even if same version is already installed").option(
|
|
4922
5090
|
"--from <source>",
|
|
4923
5091
|
"Install from local path, directory, or GitHub (github:owner/repo, https://github.com/owner/repo)"
|
|
@@ -4953,7 +5121,7 @@ function createInstallCommand() {
|
|
|
4953
5121
|
init_dist2();
|
|
4954
5122
|
import * as fs21 from "fs/promises";
|
|
4955
5123
|
import * as path33 from "path";
|
|
4956
|
-
import { Command as
|
|
5124
|
+
import { Command as Command40 } from "commander";
|
|
4957
5125
|
import semver3 from "semver";
|
|
4958
5126
|
async function runInstallConstraints(options) {
|
|
4959
5127
|
const { source, configPath, lockfilePath } = options;
|
|
@@ -5207,17 +5375,17 @@ async function handleInstallConstraints(source, opts) {
|
|
|
5207
5375
|
logInstallResult(result.value, opts);
|
|
5208
5376
|
}
|
|
5209
5377
|
function createInstallConstraintsCommand() {
|
|
5210
|
-
const cmd = new
|
|
5378
|
+
const cmd = new Command40("install-constraints");
|
|
5211
5379
|
cmd.description("Install a constraints bundle into the local harness config").argument("<source>", "Path to a .harness-constraints.json bundle file").option("--force-local", "Resolve all conflicts by keeping local values").option("--force-package", "Resolve all conflicts by using package values").option("--dry-run", "Show what would change without writing files").option("-c, --config <path>", "Path to harness.config.json").action(handleInstallConstraints);
|
|
5212
5380
|
return cmd;
|
|
5213
5381
|
}
|
|
5214
5382
|
|
|
5215
5383
|
// src/commands/integrations/index.ts
|
|
5216
|
-
import { Command as
|
|
5384
|
+
import { Command as Command45 } from "commander";
|
|
5217
5385
|
|
|
5218
5386
|
// src/commands/integrations/add.ts
|
|
5219
5387
|
init_dist2();
|
|
5220
|
-
import { Command as
|
|
5388
|
+
import { Command as Command41 } from "commander";
|
|
5221
5389
|
import * as fs22 from "fs";
|
|
5222
5390
|
import * as path34 from "path";
|
|
5223
5391
|
import chalk4 from "chalk";
|
|
@@ -5281,7 +5449,7 @@ function printAddSuccess(value) {
|
|
|
5281
5449
|
}
|
|
5282
5450
|
}
|
|
5283
5451
|
function createAddIntegrationCommand() {
|
|
5284
|
-
return new
|
|
5452
|
+
return new Command41("add").description("Enable an MCP integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
|
|
5285
5453
|
const globalOpts = cmd.optsWithGlobals();
|
|
5286
5454
|
const result = addIntegration(process.cwd(), name);
|
|
5287
5455
|
if (!result.ok) {
|
|
@@ -5295,7 +5463,7 @@ function createAddIntegrationCommand() {
|
|
|
5295
5463
|
}
|
|
5296
5464
|
|
|
5297
5465
|
// src/commands/integrations/list.ts
|
|
5298
|
-
import { Command as
|
|
5466
|
+
import { Command as Command42 } from "commander";
|
|
5299
5467
|
import * as path35 from "path";
|
|
5300
5468
|
import chalk5 from "chalk";
|
|
5301
5469
|
function printTier0Integrations(tier0, mcpServers) {
|
|
@@ -5352,12 +5520,12 @@ async function runListIntegrations(globalOpts) {
|
|
|
5352
5520
|
process.exit(ExitCode.SUCCESS);
|
|
5353
5521
|
}
|
|
5354
5522
|
function createListIntegrationsCommand() {
|
|
5355
|
-
return new
|
|
5523
|
+
return new Command42("list").description("Show all MCP integrations with status").action(async (_opts, cmd) => runListIntegrations(cmd.optsWithGlobals()));
|
|
5356
5524
|
}
|
|
5357
5525
|
|
|
5358
5526
|
// src/commands/integrations/remove.ts
|
|
5359
5527
|
init_dist2();
|
|
5360
|
-
import { Command as
|
|
5528
|
+
import { Command as Command43 } from "commander";
|
|
5361
5529
|
import * as fs23 from "fs";
|
|
5362
5530
|
import * as path36 from "path";
|
|
5363
5531
|
function removeIntegration(cwd, name) {
|
|
@@ -5384,7 +5552,7 @@ function removeIntegration(cwd, name) {
|
|
|
5384
5552
|
return Ok(def.displayName);
|
|
5385
5553
|
}
|
|
5386
5554
|
function createRemoveIntegrationCommand() {
|
|
5387
|
-
return new
|
|
5555
|
+
return new Command43("remove").description("Remove an MCP integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
|
|
5388
5556
|
const globalOpts = cmd.optsWithGlobals();
|
|
5389
5557
|
const cwd = process.cwd();
|
|
5390
5558
|
const result = removeIntegration(cwd, name);
|
|
@@ -5406,7 +5574,7 @@ function createRemoveIntegrationCommand() {
|
|
|
5406
5574
|
|
|
5407
5575
|
// src/commands/integrations/dismiss.ts
|
|
5408
5576
|
init_dist2();
|
|
5409
|
-
import { Command as
|
|
5577
|
+
import { Command as Command44 } from "commander";
|
|
5410
5578
|
import * as path37 from "path";
|
|
5411
5579
|
function dismissIntegration(cwd, name) {
|
|
5412
5580
|
const def = INTEGRATION_REGISTRY.find((i) => i.name === name);
|
|
@@ -5428,7 +5596,7 @@ function dismissIntegration(cwd, name) {
|
|
|
5428
5596
|
return Ok(def.displayName);
|
|
5429
5597
|
}
|
|
5430
5598
|
function createDismissIntegrationCommand() {
|
|
5431
|
-
return new
|
|
5599
|
+
return new Command44("dismiss").description("Suppress doctor recommendations for an integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
|
|
5432
5600
|
const globalOpts = cmd.optsWithGlobals();
|
|
5433
5601
|
const cwd = process.cwd();
|
|
5434
5602
|
const result = dismissIntegration(cwd, name);
|
|
@@ -5452,7 +5620,7 @@ function createDismissIntegrationCommand() {
|
|
|
5452
5620
|
|
|
5453
5621
|
// src/commands/integrations/index.ts
|
|
5454
5622
|
function createIntegrationsCommand() {
|
|
5455
|
-
const command = new
|
|
5623
|
+
const command = new Command45("integrations").description(
|
|
5456
5624
|
"Manage MCP peer integrations (add, list, remove, dismiss)"
|
|
5457
5625
|
);
|
|
5458
5626
|
command.addCommand(createListIntegrationsCommand());
|
|
@@ -5463,18 +5631,18 @@ function createIntegrationsCommand() {
|
|
|
5463
5631
|
}
|
|
5464
5632
|
|
|
5465
5633
|
// src/commands/knowledge-pipeline.ts
|
|
5466
|
-
import { Command as
|
|
5634
|
+
import { Command as Command46 } from "commander";
|
|
5467
5635
|
import * as path38 from "path";
|
|
5468
5636
|
import chalk6 from "chalk";
|
|
5469
5637
|
function createKnowledgePipelineCommand() {
|
|
5470
|
-
return new
|
|
5638
|
+
return new Command46("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) => {
|
|
5471
5639
|
const globalOpts = cmd.optsWithGlobals();
|
|
5472
5640
|
const projectDir = process.cwd();
|
|
5473
5641
|
try {
|
|
5474
5642
|
const graphDir = path38.join(projectDir, ".harness", "graph");
|
|
5475
5643
|
const fs44 = await import("fs/promises");
|
|
5476
5644
|
await fs44.mkdir(graphDir, { recursive: true });
|
|
5477
|
-
const { GraphStore, KnowledgePipelineRunner } = await import("./dist-
|
|
5645
|
+
const { GraphStore, KnowledgePipelineRunner } = await import("./dist-QPWXPCPL.js");
|
|
5478
5646
|
const store = new GraphStore();
|
|
5479
5647
|
try {
|
|
5480
5648
|
await store.load(graphDir);
|
|
@@ -5631,11 +5799,11 @@ function createKnowledgePipelineCommand() {
|
|
|
5631
5799
|
}
|
|
5632
5800
|
|
|
5633
5801
|
// src/commands/learnings/index.ts
|
|
5634
|
-
import { Command as
|
|
5802
|
+
import { Command as Command48 } from "commander";
|
|
5635
5803
|
|
|
5636
5804
|
// src/commands/learnings/prune.ts
|
|
5637
5805
|
init_dist2();
|
|
5638
|
-
import { Command as
|
|
5806
|
+
import { Command as Command47 } from "commander";
|
|
5639
5807
|
import * as path39 from "path";
|
|
5640
5808
|
async function handlePrune(opts) {
|
|
5641
5809
|
const projectPath = path39.resolve(opts.path);
|
|
@@ -5677,23 +5845,23 @@ function printPatternProposals(patterns) {
|
|
|
5677
5845
|
);
|
|
5678
5846
|
}
|
|
5679
5847
|
function createPruneCommand() {
|
|
5680
|
-
return new
|
|
5848
|
+
return new Command47("prune").description(
|
|
5681
5849
|
"Analyze global learnings for patterns, present improvement proposals, and archive old entries"
|
|
5682
5850
|
).option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(handlePrune);
|
|
5683
5851
|
}
|
|
5684
5852
|
|
|
5685
5853
|
// src/commands/learnings/index.ts
|
|
5686
5854
|
function createLearningsCommand() {
|
|
5687
|
-
const command = new
|
|
5855
|
+
const command = new Command48("learnings").description("Learnings management commands");
|
|
5688
5856
|
command.addCommand(createPruneCommand());
|
|
5689
5857
|
return command;
|
|
5690
5858
|
}
|
|
5691
5859
|
|
|
5692
5860
|
// src/commands/linter/index.ts
|
|
5693
|
-
import { Command as
|
|
5861
|
+
import { Command as Command51 } from "commander";
|
|
5694
5862
|
|
|
5695
5863
|
// src/commands/linter/generate.ts
|
|
5696
|
-
import { Command as
|
|
5864
|
+
import { Command as Command49 } from "commander";
|
|
5697
5865
|
function formatGenerateError(e) {
|
|
5698
5866
|
switch (e.type) {
|
|
5699
5867
|
case "parse":
|
|
@@ -5737,7 +5905,7 @@ function handleSuccess(result, useJson) {
|
|
|
5737
5905
|
Generated ${result.rulesGenerated.length} rules to ${result.outputDir}`);
|
|
5738
5906
|
}
|
|
5739
5907
|
function createGenerateCommand2() {
|
|
5740
|
-
return new
|
|
5908
|
+
return new Command49("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) => {
|
|
5741
5909
|
try {
|
|
5742
5910
|
if (options.verbose) logger.info(`Parsing config: ${options.config}`);
|
|
5743
5911
|
const result = await generate({
|
|
@@ -5759,9 +5927,9 @@ function createGenerateCommand2() {
|
|
|
5759
5927
|
}
|
|
5760
5928
|
|
|
5761
5929
|
// src/commands/linter/validate.ts
|
|
5762
|
-
import { Command as
|
|
5930
|
+
import { Command as Command50 } from "commander";
|
|
5763
5931
|
function createValidateCommand() {
|
|
5764
|
-
return new
|
|
5932
|
+
return new Command50("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) => {
|
|
5765
5933
|
try {
|
|
5766
5934
|
const result = await validate({ configPath: options.config });
|
|
5767
5935
|
if (options.json) {
|
|
@@ -5780,7 +5948,7 @@ function createValidateCommand() {
|
|
|
5780
5948
|
|
|
5781
5949
|
// src/commands/linter/index.ts
|
|
5782
5950
|
function createLinterCommand() {
|
|
5783
|
-
const linter = new
|
|
5951
|
+
const linter = new Command51("linter").description(
|
|
5784
5952
|
"Generate and validate ESLint rules from YAML config"
|
|
5785
5953
|
);
|
|
5786
5954
|
linter.addCommand(createGenerateCommand2());
|
|
@@ -5789,7 +5957,7 @@ function createLinterCommand() {
|
|
|
5789
5957
|
}
|
|
5790
5958
|
|
|
5791
5959
|
// src/commands/mcp.ts
|
|
5792
|
-
import { Command as
|
|
5960
|
+
import { Command as Command52 } from "commander";
|
|
5793
5961
|
var VALID_TIERS = /* @__PURE__ */ new Set(["core", "standard", "full"]);
|
|
5794
5962
|
function parseTier(value) {
|
|
5795
5963
|
const lower = value.toLowerCase();
|
|
@@ -5806,7 +5974,7 @@ function parseBudget(value) {
|
|
|
5806
5974
|
return n;
|
|
5807
5975
|
}
|
|
5808
5976
|
function createMcpCommand() {
|
|
5809
|
-
return new
|
|
5977
|
+
return new Command52("mcp").description("Start the MCP (Model Context Protocol) server on stdio").option("--tools <tools...>", "Only register the specified tools (used by Cursor integration)").option(
|
|
5810
5978
|
"--tier <core|standard|full>",
|
|
5811
5979
|
"Load a preset tool tier instead of all tools",
|
|
5812
5980
|
parseTier
|
|
@@ -5816,8 +5984,8 @@ function createMcpCommand() {
|
|
|
5816
5984
|
parseBudget
|
|
5817
5985
|
).action(async (opts) => {
|
|
5818
5986
|
const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
|
|
5819
|
-
import("./mcp-
|
|
5820
|
-
import("./tool-tiers-
|
|
5987
|
+
import("./mcp-5KQGFG5U.js"),
|
|
5988
|
+
import("./tool-tiers-QVWKAZX4.js")
|
|
5821
5989
|
]);
|
|
5822
5990
|
if (opts.tools && opts.tools.length > 0) {
|
|
5823
5991
|
await startServer2(opts.tools);
|
|
@@ -5839,7 +6007,7 @@ function createMcpCommand() {
|
|
|
5839
6007
|
// src/commands/migrate.ts
|
|
5840
6008
|
init_dist2();
|
|
5841
6009
|
init_dist();
|
|
5842
|
-
import { Command as
|
|
6010
|
+
import { Command as Command53 } from "commander";
|
|
5843
6011
|
import * as fs24 from "fs";
|
|
5844
6012
|
import * as path40 from "path";
|
|
5845
6013
|
import * as readline from "readline";
|
|
@@ -6082,7 +6250,7 @@ function updateReferences(plan) {
|
|
|
6082
6250
|
}
|
|
6083
6251
|
async function prompt(question, def = "n") {
|
|
6084
6252
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
6085
|
-
const answer = await new Promise((
|
|
6253
|
+
const answer = await new Promise((resolve42) => rl.question(question, resolve42));
|
|
6086
6254
|
rl.close();
|
|
6087
6255
|
return (answer.trim() || def).toLowerCase();
|
|
6088
6256
|
}
|
|
@@ -6245,7 +6413,7 @@ async function runMigrate(opts) {
|
|
|
6245
6413
|
});
|
|
6246
6414
|
}
|
|
6247
6415
|
function createMigrateCommand() {
|
|
6248
|
-
return new
|
|
6416
|
+
return new Command53("migrate").description("Migrate legacy harness artifact locations to current layout").option("--dry-run", "Show the migration plan without moving files", false).option("--yes", "Skip confirmation prompt", false).option(
|
|
6249
6417
|
"--skip-references",
|
|
6250
6418
|
"Do not update path references in docs/sessions after moves",
|
|
6251
6419
|
false
|
|
@@ -6267,11 +6435,11 @@ function createMigrateCommand() {
|
|
|
6267
6435
|
}
|
|
6268
6436
|
|
|
6269
6437
|
// src/commands/orchestrator.ts
|
|
6270
|
-
import { Command as
|
|
6438
|
+
import { Command as Command54 } from "commander";
|
|
6271
6439
|
import * as path41 from "path";
|
|
6272
6440
|
import { Orchestrator, WorkflowLoader, launchTUI } from "@harness-engineering/orchestrator";
|
|
6273
6441
|
function createOrchestratorCommand() {
|
|
6274
|
-
const orchestrator = new
|
|
6442
|
+
const orchestrator = new Command54("orchestrator");
|
|
6275
6443
|
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) => {
|
|
6276
6444
|
const workflowPath = path41.resolve(process.cwd(), opts.workflow);
|
|
6277
6445
|
const loader = new WorkflowLoader();
|
|
@@ -6306,13 +6474,13 @@ function createOrchestratorCommand() {
|
|
|
6306
6474
|
|
|
6307
6475
|
// src/commands/perf.ts
|
|
6308
6476
|
init_dist2();
|
|
6309
|
-
import { Command as
|
|
6477
|
+
import { Command as Command55 } from "commander";
|
|
6310
6478
|
import * as path42 from "path";
|
|
6311
6479
|
function registerBenchCommand(perf) {
|
|
6312
6480
|
perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
|
|
6313
6481
|
const globalOpts = cmd.optsWithGlobals();
|
|
6314
6482
|
const cwd = process.cwd();
|
|
6315
|
-
const { BenchmarkRunner } = await import("./dist-
|
|
6483
|
+
const { BenchmarkRunner } = await import("./dist-HA6IIPRC.js");
|
|
6316
6484
|
const runner = new BenchmarkRunner();
|
|
6317
6485
|
const benchFiles = runner.discover(cwd, glob2);
|
|
6318
6486
|
if (benchFiles.length === 0) {
|
|
@@ -6376,7 +6544,7 @@ async function runBaselinesShow(globalOpts) {
|
|
|
6376
6544
|
}
|
|
6377
6545
|
async function runBaselinesUpdate(globalOpts) {
|
|
6378
6546
|
const cwd = process.cwd();
|
|
6379
|
-
const { BenchmarkRunner } = await import("./dist-
|
|
6547
|
+
const { BenchmarkRunner } = await import("./dist-HA6IIPRC.js");
|
|
6380
6548
|
const runner = new BenchmarkRunner();
|
|
6381
6549
|
const manager = new BaselineManager(cwd);
|
|
6382
6550
|
logger.info("Running benchmarks to update baselines...");
|
|
@@ -6407,8 +6575,8 @@ function registerBaselinesCommands(perf) {
|
|
|
6407
6575
|
}
|
|
6408
6576
|
async function getCommitHash2(cwd) {
|
|
6409
6577
|
try {
|
|
6410
|
-
const { execSync:
|
|
6411
|
-
return
|
|
6578
|
+
const { execSync: execSync7 } = await import("child_process");
|
|
6579
|
+
return execSync7("git rev-parse --short HEAD", { cwd, encoding: "utf-8" }).trim();
|
|
6412
6580
|
} catch {
|
|
6413
6581
|
return "unknown";
|
|
6414
6582
|
}
|
|
@@ -6417,7 +6585,7 @@ function registerReportCommand(perf) {
|
|
|
6417
6585
|
perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
|
|
6418
6586
|
const globalOpts = cmd.optsWithGlobals();
|
|
6419
6587
|
const cwd = process.cwd();
|
|
6420
|
-
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-
|
|
6588
|
+
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-HA6IIPRC.js");
|
|
6421
6589
|
const analyzer = new EntropyAnalyzer2({
|
|
6422
6590
|
rootDir: path42.resolve(cwd),
|
|
6423
6591
|
analyze: { complexity: true, coupling: true }
|
|
@@ -6478,7 +6646,7 @@ function registerCriticalPathsCommand(perf) {
|
|
|
6478
6646
|
});
|
|
6479
6647
|
}
|
|
6480
6648
|
function createPerfCommand() {
|
|
6481
|
-
const perf = new
|
|
6649
|
+
const perf = new Command55("perf").description("Performance benchmark and baseline management");
|
|
6482
6650
|
registerBenchCommand(perf);
|
|
6483
6651
|
registerBaselinesCommands(perf);
|
|
6484
6652
|
registerReportCommand(perf);
|
|
@@ -6487,10 +6655,10 @@ function createPerfCommand() {
|
|
|
6487
6655
|
}
|
|
6488
6656
|
|
|
6489
6657
|
// src/commands/persona/index.ts
|
|
6490
|
-
import { Command as
|
|
6658
|
+
import { Command as Command58 } from "commander";
|
|
6491
6659
|
|
|
6492
6660
|
// src/commands/persona/list.ts
|
|
6493
|
-
import { Command as
|
|
6661
|
+
import { Command as Command56 } from "commander";
|
|
6494
6662
|
function printPersonaList(personas) {
|
|
6495
6663
|
if (personas.length === 0) {
|
|
6496
6664
|
logger.info("No personas found.");
|
|
@@ -6504,7 +6672,7 @@ function printPersonaList(personas) {
|
|
|
6504
6672
|
}
|
|
6505
6673
|
}
|
|
6506
6674
|
function createListCommand2() {
|
|
6507
|
-
return new
|
|
6675
|
+
return new Command56("list").description("List available agent personas").action(async (_opts, cmd) => {
|
|
6508
6676
|
const globalOpts = cmd.optsWithGlobals();
|
|
6509
6677
|
const personasDir = resolvePersonasDir();
|
|
6510
6678
|
const result = listPersonas(personasDir);
|
|
@@ -6524,7 +6692,7 @@ function createListCommand2() {
|
|
|
6524
6692
|
}
|
|
6525
6693
|
|
|
6526
6694
|
// src/commands/persona/generate.ts
|
|
6527
|
-
import { Command as
|
|
6695
|
+
import { Command as Command57 } from "commander";
|
|
6528
6696
|
import * as fs25 from "fs";
|
|
6529
6697
|
import * as path43 from "path";
|
|
6530
6698
|
function generatePersonaArtifacts(persona, outputDir, only) {
|
|
@@ -6559,7 +6727,7 @@ function generatePersonaArtifacts(persona, outputDir, only) {
|
|
|
6559
6727
|
return generated;
|
|
6560
6728
|
}
|
|
6561
6729
|
function createGenerateCommand3() {
|
|
6562
|
-
return new
|
|
6730
|
+
return new Command57("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) => {
|
|
6563
6731
|
const globalOpts = cmd.optsWithGlobals();
|
|
6564
6732
|
const personaResult = loadPersona(path43.join(resolvePersonasDir(), `${name}.yaml`));
|
|
6565
6733
|
if (!personaResult.ok) {
|
|
@@ -6581,7 +6749,7 @@ function createGenerateCommand3() {
|
|
|
6581
6749
|
|
|
6582
6750
|
// src/commands/persona/index.ts
|
|
6583
6751
|
function createPersonaCommand() {
|
|
6584
|
-
const command = new
|
|
6752
|
+
const command = new Command58("persona").description("Agent persona management commands");
|
|
6585
6753
|
command.addCommand(createListCommand2());
|
|
6586
6754
|
command.addCommand(createGenerateCommand3());
|
|
6587
6755
|
return command;
|
|
@@ -6589,7 +6757,7 @@ function createPersonaCommand() {
|
|
|
6589
6757
|
|
|
6590
6758
|
// src/commands/predict.ts
|
|
6591
6759
|
init_dist2();
|
|
6592
|
-
import { Command as
|
|
6760
|
+
import { Command as Command59 } from "commander";
|
|
6593
6761
|
import chalk8 from "chalk";
|
|
6594
6762
|
var CATEGORY_ORDER = [
|
|
6595
6763
|
"circular-deps",
|
|
@@ -6695,7 +6863,7 @@ function handlePredictError(err, mode) {
|
|
|
6695
6863
|
process.exit(ExitCode.ERROR);
|
|
6696
6864
|
}
|
|
6697
6865
|
function createPredictCommand() {
|
|
6698
|
-
const command = new
|
|
6866
|
+
const command = new Command59("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) => {
|
|
6699
6867
|
const globalOpts = cmd.optsWithGlobals();
|
|
6700
6868
|
const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
|
|
6701
6869
|
try {
|
|
@@ -6720,7 +6888,7 @@ function createPredictCommand() {
|
|
|
6720
6888
|
// src/commands/publish-analyses.ts
|
|
6721
6889
|
import * as fs26 from "fs";
|
|
6722
6890
|
import * as path44 from "path";
|
|
6723
|
-
import { Command as
|
|
6891
|
+
import { Command as Command60 } from "commander";
|
|
6724
6892
|
init_dist2();
|
|
6725
6893
|
import {
|
|
6726
6894
|
renderAnalysisComment,
|
|
@@ -6833,7 +7001,7 @@ async function runPublishAnalyses(opts) {
|
|
|
6833
7001
|
const nameToExternalId = await buildNameToExternalIdMap(projectPath);
|
|
6834
7002
|
if (!nameToExternalId) return process.exit(1);
|
|
6835
7003
|
const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
|
|
6836
|
-
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-
|
|
7004
|
+
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-HA6IIPRC.js");
|
|
6837
7005
|
const archive = new AnalysisArchive(path44.join(projectPath, ".harness", "analyses"));
|
|
6838
7006
|
const analyses = await archive.list();
|
|
6839
7007
|
if (analyses.length === 0) {
|
|
@@ -6856,7 +7024,7 @@ async function runPublishAnalyses(opts) {
|
|
|
6856
7024
|
}
|
|
6857
7025
|
}
|
|
6858
7026
|
function createPublishAnalysesCommand() {
|
|
6859
|
-
const command = new
|
|
7027
|
+
const command = new Command60("publish-analyses").description(
|
|
6860
7028
|
"Publishes locally generated intelligence analyses to the external issue tracker (e.g., GitHub)"
|
|
6861
7029
|
).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
6862
7030
|
try {
|
|
@@ -6872,13 +7040,13 @@ function createPublishAnalysesCommand() {
|
|
|
6872
7040
|
}
|
|
6873
7041
|
|
|
6874
7042
|
// src/commands/pulse/index.ts
|
|
6875
|
-
import { Command as
|
|
7043
|
+
import { Command as Command62 } from "commander";
|
|
6876
7044
|
|
|
6877
7045
|
// src/commands/pulse/run.ts
|
|
6878
7046
|
init_dist2();
|
|
6879
7047
|
import { readFileSync as readFileSync15, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14 } from "fs";
|
|
6880
|
-
import { dirname as dirname17, join as join35, resolve as
|
|
6881
|
-
import { Command as
|
|
7048
|
+
import { dirname as dirname17, join as join35, resolve as resolve30 } from "path";
|
|
7049
|
+
import { Command as Command61 } from "commander";
|
|
6882
7050
|
async function runPulseRunCommand(opts) {
|
|
6883
7051
|
const startedAt = Date.now();
|
|
6884
7052
|
let raw;
|
|
@@ -6943,7 +7111,7 @@ function emit2(status, nonInteractive) {
|
|
|
6943
7111
|
return status;
|
|
6944
7112
|
}
|
|
6945
7113
|
function createRunCommand2() {
|
|
6946
|
-
return new
|
|
7114
|
+
return new Command61("run").description("Run a pulse: query configured adapters, sanitize, assemble single-page report").option(
|
|
6947
7115
|
"--lookback <window>",
|
|
6948
7116
|
"Lookback window (e.g. 24h, 7d). Defaults to pulse.lookbackDefault."
|
|
6949
7117
|
).option(
|
|
@@ -6953,8 +7121,8 @@ function createRunCommand2() {
|
|
|
6953
7121
|
async (options) => {
|
|
6954
7122
|
const nonInteractive = options.nonInteractive === true || !process.stdout.isTTY;
|
|
6955
7123
|
const status = await runPulseRunCommand({
|
|
6956
|
-
configPath:
|
|
6957
|
-
outputDir:
|
|
7124
|
+
configPath: resolve30(process.cwd(), options.config),
|
|
7125
|
+
outputDir: resolve30(process.cwd(), options.outputDir),
|
|
6958
7126
|
nonInteractive,
|
|
6959
7127
|
lookback: options.lookback
|
|
6960
7128
|
});
|
|
@@ -6967,13 +7135,13 @@ function createRunCommand2() {
|
|
|
6967
7135
|
|
|
6968
7136
|
// src/commands/pulse/index.ts
|
|
6969
7137
|
function createPulseCommand() {
|
|
6970
|
-
const command = new
|
|
7138
|
+
const command = new Command62("pulse").description("Pulse (read-side observability) commands");
|
|
6971
7139
|
command.addCommand(createRunCommand2());
|
|
6972
7140
|
return command;
|
|
6973
7141
|
}
|
|
6974
7142
|
|
|
6975
7143
|
// src/commands/recommend.ts
|
|
6976
|
-
import { Command as
|
|
7144
|
+
import { Command as Command63 } from "commander";
|
|
6977
7145
|
import chalk9 from "chalk";
|
|
6978
7146
|
async function resolveSnapshot(cwd, noCache) {
|
|
6979
7147
|
if (!noCache) {
|
|
@@ -7037,7 +7205,7 @@ function printRecommendations(result) {
|
|
|
7037
7205
|
console.log("");
|
|
7038
7206
|
}
|
|
7039
7207
|
function createRecommendCommand() {
|
|
7040
|
-
const command = new
|
|
7208
|
+
const command = new Command63("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) => {
|
|
7041
7209
|
const globalOpts = cmd.optsWithGlobals();
|
|
7042
7210
|
const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
|
|
7043
7211
|
try {
|
|
@@ -7073,11 +7241,11 @@ function createRecommendCommand() {
|
|
|
7073
7241
|
}
|
|
7074
7242
|
|
|
7075
7243
|
// src/commands/roadmap/index.ts
|
|
7076
|
-
import { Command as
|
|
7244
|
+
import { Command as Command65 } from "commander";
|
|
7077
7245
|
|
|
7078
7246
|
// src/commands/roadmap/migrate.ts
|
|
7079
7247
|
init_dist2();
|
|
7080
|
-
import { Command as
|
|
7248
|
+
import { Command as Command64 } from "commander";
|
|
7081
7249
|
import * as fs28 from "fs";
|
|
7082
7250
|
import * as path46 from "path";
|
|
7083
7251
|
import chalk10 from "chalk";
|
|
@@ -7347,7 +7515,7 @@ async function runRoadmapMigrate(opts) {
|
|
|
7347
7515
|
}
|
|
7348
7516
|
}
|
|
7349
7517
|
function createRoadmapMigrateCommand() {
|
|
7350
|
-
return new
|
|
7518
|
+
return new Command64("migrate").description("Migrate the project roadmap to a different storage mode").requiredOption("--to <target>", 'Migration target (only "file-less" supported today)').option("--dry-run", "Print the migration plan without making any changes", false).option(
|
|
7351
7519
|
"--format <fmt>",
|
|
7352
7520
|
'Output format: "human" (default) or "json" (single JSON object for CI consumers)',
|
|
7353
7521
|
"human"
|
|
@@ -7382,14 +7550,14 @@ function createRoadmapMigrateCommand() {
|
|
|
7382
7550
|
|
|
7383
7551
|
// src/commands/roadmap/index.ts
|
|
7384
7552
|
function createRoadmapCommand() {
|
|
7385
|
-
const roadmap = new
|
|
7553
|
+
const roadmap = new Command65("roadmap").description("Roadmap management");
|
|
7386
7554
|
roadmap.addCommand(createRoadmapMigrateCommand());
|
|
7387
7555
|
return roadmap;
|
|
7388
7556
|
}
|
|
7389
7557
|
|
|
7390
7558
|
// src/commands/scan-config.ts
|
|
7391
7559
|
init_dist2();
|
|
7392
|
-
import { Command as
|
|
7560
|
+
import { Command as Command66 } from "commander";
|
|
7393
7561
|
import { existsSync as existsSync25, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
|
|
7394
7562
|
import { join as join38, relative as relative3 } from "path";
|
|
7395
7563
|
var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".gemini/settings.json", "skill.yaml"];
|
|
@@ -7478,7 +7646,7 @@ function formatTextOutput(result) {
|
|
|
7478
7646
|
}
|
|
7479
7647
|
}
|
|
7480
7648
|
function createScanConfigCommand() {
|
|
7481
|
-
const command = new
|
|
7649
|
+
const command = new Command66("scan-config").description(
|
|
7482
7650
|
"Scan CLAUDE.md, AGENTS.md, .gemini/settings.json, and skill.yaml for prompt injection patterns"
|
|
7483
7651
|
).option("--path <dir>", "Target directory to scan (default: cwd)").option("--fix", "Strip high-severity patterns from files in-place").action(async (opts, cmd) => {
|
|
7484
7652
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -7495,7 +7663,7 @@ function createScanConfigCommand() {
|
|
|
7495
7663
|
}
|
|
7496
7664
|
|
|
7497
7665
|
// src/commands/setup.ts
|
|
7498
|
-
import { Command as
|
|
7666
|
+
import { Command as Command67 } from "commander";
|
|
7499
7667
|
import * as fs31 from "fs";
|
|
7500
7668
|
import * as os8 from "os";
|
|
7501
7669
|
import * as path49 from "path";
|
|
@@ -7534,10 +7702,10 @@ function prompt2(question) {
|
|
|
7534
7702
|
input: process.stdin,
|
|
7535
7703
|
output: process.stdout
|
|
7536
7704
|
});
|
|
7537
|
-
return new Promise((
|
|
7705
|
+
return new Promise((resolve42) => {
|
|
7538
7706
|
rl.question(question, (answer) => {
|
|
7539
7707
|
rl.close();
|
|
7540
|
-
|
|
7708
|
+
resolve42(answer.trim().toLowerCase());
|
|
7541
7709
|
});
|
|
7542
7710
|
});
|
|
7543
7711
|
}
|
|
@@ -7546,10 +7714,10 @@ function promptRaw(question) {
|
|
|
7546
7714
|
input: process.stdin,
|
|
7547
7715
|
output: process.stdout
|
|
7548
7716
|
});
|
|
7549
|
-
return new Promise((
|
|
7717
|
+
return new Promise((resolve42) => {
|
|
7550
7718
|
rl.question(question, (answer) => {
|
|
7551
7719
|
rl.close();
|
|
7552
|
-
|
|
7720
|
+
resolve42(answer.trim());
|
|
7553
7721
|
});
|
|
7554
7722
|
});
|
|
7555
7723
|
}
|
|
@@ -7801,7 +7969,7 @@ async function detectLegacyLayout(cwd) {
|
|
|
7801
7969
|
}
|
|
7802
7970
|
async function runInitialGraphScan(cwd) {
|
|
7803
7971
|
try {
|
|
7804
|
-
const { runScan: runScan2 } = await import("./scan-
|
|
7972
|
+
const { runScan: runScan2 } = await import("./scan-4PPP6ZXT.js");
|
|
7805
7973
|
const result = await runScan2(cwd);
|
|
7806
7974
|
return {
|
|
7807
7975
|
status: "pass",
|
|
@@ -7840,7 +8008,7 @@ async function runSetup(cwd) {
|
|
|
7840
8008
|
return { steps, success };
|
|
7841
8009
|
}
|
|
7842
8010
|
function createSetupCommand() {
|
|
7843
|
-
return new
|
|
8011
|
+
return new Command67("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
|
|
7844
8012
|
const cwd = process.cwd();
|
|
7845
8013
|
console.log("");
|
|
7846
8014
|
console.log(` ${chalk12.bold("harness setup")}`);
|
|
@@ -7863,7 +8031,7 @@ function createSetupCommand() {
|
|
|
7863
8031
|
|
|
7864
8032
|
// src/commands/share.ts
|
|
7865
8033
|
init_dist2();
|
|
7866
|
-
import { Command as
|
|
8034
|
+
import { Command as Command68 } from "commander";
|
|
7867
8035
|
import * as fs32 from "fs";
|
|
7868
8036
|
import * as path50 from "path";
|
|
7869
8037
|
import { parse as parseYaml } from "yaml";
|
|
@@ -7922,16 +8090,16 @@ Create a constraints.yaml in your project root to define what to share.`
|
|
|
7922
8090
|
logger.success(`Bundle written to ${outputPath}`);
|
|
7923
8091
|
}
|
|
7924
8092
|
function createShareCommand() {
|
|
7925
|
-
return new
|
|
8093
|
+
return new Command68("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) => {
|
|
7926
8094
|
await runShareAction(projectPath, options);
|
|
7927
8095
|
});
|
|
7928
8096
|
}
|
|
7929
8097
|
|
|
7930
8098
|
// src/commands/skill/index.ts
|
|
7931
|
-
import { Command as
|
|
8099
|
+
import { Command as Command76 } from "commander";
|
|
7932
8100
|
|
|
7933
8101
|
// src/commands/skill/list.ts
|
|
7934
|
-
import { Command as
|
|
8102
|
+
import { Command as Command69 } from "commander";
|
|
7935
8103
|
import * as fs33 from "fs";
|
|
7936
8104
|
import * as path51 from "path";
|
|
7937
8105
|
import { parse } from "yaml";
|
|
@@ -8034,7 +8202,7 @@ function printSkillsVerbose(skills) {
|
|
|
8034
8202
|
for (const s of skills) printSkillEntry(s);
|
|
8035
8203
|
}
|
|
8036
8204
|
function createListCommand3() {
|
|
8037
|
-
return new
|
|
8205
|
+
return new Command69("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) => {
|
|
8038
8206
|
const globalOpts = cmd.optsWithGlobals();
|
|
8039
8207
|
const skills = collectSkills({ filter: resolveFilter(opts) });
|
|
8040
8208
|
if (globalOpts.json) {
|
|
@@ -8049,7 +8217,7 @@ function createListCommand3() {
|
|
|
8049
8217
|
}
|
|
8050
8218
|
|
|
8051
8219
|
// src/commands/skill/run.ts
|
|
8052
|
-
import { Command as
|
|
8220
|
+
import { Command as Command70 } from "commander";
|
|
8053
8221
|
import * as fs34 from "fs";
|
|
8054
8222
|
import * as path52 from "path";
|
|
8055
8223
|
import { parse as parse2 } from "yaml";
|
|
@@ -8261,11 +8429,11 @@ async function runSkill(name, opts) {
|
|
|
8261
8429
|
process.exit(ExitCode.SUCCESS);
|
|
8262
8430
|
}
|
|
8263
8431
|
function createRunCommand3() {
|
|
8264
|
-
return new
|
|
8432
|
+
return new Command70("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));
|
|
8265
8433
|
}
|
|
8266
8434
|
|
|
8267
8435
|
// src/commands/skill/validate.ts
|
|
8268
|
-
import { Command as
|
|
8436
|
+
import { Command as Command71 } from "commander";
|
|
8269
8437
|
import * as fs35 from "fs";
|
|
8270
8438
|
import * as path53 from "path";
|
|
8271
8439
|
import { parse as parse3 } from "yaml";
|
|
@@ -8329,7 +8497,7 @@ function validateSkillEntry(name, skillsDir, errors) {
|
|
|
8329
8497
|
}
|
|
8330
8498
|
}
|
|
8331
8499
|
function createValidateCommand2() {
|
|
8332
|
-
return new
|
|
8500
|
+
return new Command71("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
|
|
8333
8501
|
const globalOpts = cmd.optsWithGlobals();
|
|
8334
8502
|
const skillsDir = resolveSkillsDir();
|
|
8335
8503
|
if (!fs35.existsSync(skillsDir)) {
|
|
@@ -8359,7 +8527,7 @@ function createValidateCommand2() {
|
|
|
8359
8527
|
}
|
|
8360
8528
|
|
|
8361
8529
|
// src/commands/skill/info.ts
|
|
8362
|
-
import { Command as
|
|
8530
|
+
import { Command as Command72 } from "commander";
|
|
8363
8531
|
import * as fs36 from "fs";
|
|
8364
8532
|
import * as path54 from "path";
|
|
8365
8533
|
import { parse as parse4 } from "yaml";
|
|
@@ -8405,7 +8573,7 @@ function printSkillInfo(skill) {
|
|
|
8405
8573
|
console.log(`Persistent: ${skill.state.persistent}`);
|
|
8406
8574
|
}
|
|
8407
8575
|
function createInfoCommand() {
|
|
8408
|
-
return new
|
|
8576
|
+
return new Command72("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
|
|
8409
8577
|
const globalOpts = cmd.optsWithGlobals();
|
|
8410
8578
|
const loaded = loadSkillMetadata2(name);
|
|
8411
8579
|
if (!loaded.ok) {
|
|
@@ -8422,7 +8590,7 @@ function createInfoCommand() {
|
|
|
8422
8590
|
}
|
|
8423
8591
|
|
|
8424
8592
|
// src/commands/skill/search.ts
|
|
8425
|
-
import { Command as
|
|
8593
|
+
import { Command as Command73 } from "commander";
|
|
8426
8594
|
async function runSearch(query, opts) {
|
|
8427
8595
|
const results = await searchNpmRegistry(query, opts.registry);
|
|
8428
8596
|
return results.filter((r) => {
|
|
@@ -8467,13 +8635,13 @@ async function runSearchAction(query, opts, globalOpts) {
|
|
|
8467
8635
|
}
|
|
8468
8636
|
}
|
|
8469
8637
|
function createSearchCommand() {
|
|
8470
|
-
return new
|
|
8638
|
+
return new Command73("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) => {
|
|
8471
8639
|
await runSearchAction(query, opts, cmd.optsWithGlobals());
|
|
8472
8640
|
});
|
|
8473
8641
|
}
|
|
8474
8642
|
|
|
8475
8643
|
// src/commands/skill/create.ts
|
|
8476
|
-
import { Command as
|
|
8644
|
+
import { Command as Command74 } from "commander";
|
|
8477
8645
|
import * as path55 from "path";
|
|
8478
8646
|
import * as fs37 from "fs";
|
|
8479
8647
|
import YAML from "yaml";
|
|
@@ -8593,7 +8761,7 @@ Next steps:`);
|
|
|
8593
8761
|
logger.info(` 3. Run: harness skills publish`);
|
|
8594
8762
|
}
|
|
8595
8763
|
function createCreateCommand() {
|
|
8596
|
-
return new
|
|
8764
|
+
return new Command74("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) => {
|
|
8597
8765
|
const globalOpts = cmd.optsWithGlobals();
|
|
8598
8766
|
try {
|
|
8599
8767
|
const result = runCreate(name, {
|
|
@@ -8616,7 +8784,7 @@ function createCreateCommand() {
|
|
|
8616
8784
|
}
|
|
8617
8785
|
|
|
8618
8786
|
// src/commands/skill/publish.ts
|
|
8619
|
-
import { Command as
|
|
8787
|
+
import { Command as Command75 } from "commander";
|
|
8620
8788
|
import * as fs39 from "fs";
|
|
8621
8789
|
import * as path57 from "path";
|
|
8622
8790
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
@@ -8785,7 +8953,7 @@ ${skillMdContent}`;
|
|
|
8785
8953
|
};
|
|
8786
8954
|
}
|
|
8787
8955
|
function createPublishCommand() {
|
|
8788
|
-
return new
|
|
8956
|
+
return new Command75("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) => {
|
|
8789
8957
|
const globalOpts = cmd.optsWithGlobals();
|
|
8790
8958
|
const skillDir = opts.dir || process.cwd();
|
|
8791
8959
|
try {
|
|
@@ -8810,7 +8978,7 @@ function createPublishCommand() {
|
|
|
8810
8978
|
|
|
8811
8979
|
// src/commands/skill/index.ts
|
|
8812
8980
|
function createSkillCommand() {
|
|
8813
|
-
const command = new
|
|
8981
|
+
const command = new Command76("skill").description("Skill management commands");
|
|
8814
8982
|
command.addCommand(createListCommand3());
|
|
8815
8983
|
command.addCommand(createRunCommand3());
|
|
8816
8984
|
command.addCommand(createValidateCommand2());
|
|
@@ -8823,7 +8991,7 @@ function createSkillCommand() {
|
|
|
8823
8991
|
|
|
8824
8992
|
// src/commands/snapshot.ts
|
|
8825
8993
|
init_dist2();
|
|
8826
|
-
import { Command as
|
|
8994
|
+
import { Command as Command77 } from "commander";
|
|
8827
8995
|
import { execSync as execSync5 } from "child_process";
|
|
8828
8996
|
import chalk13 from "chalk";
|
|
8829
8997
|
function getCommitHash3(cwd) {
|
|
@@ -9005,7 +9173,7 @@ function registerListCommand(parent) {
|
|
|
9005
9173
|
});
|
|
9006
9174
|
}
|
|
9007
9175
|
function createSnapshotCommand() {
|
|
9008
|
-
const command = new
|
|
9176
|
+
const command = new Command77("snapshot").description("Architecture timeline snapshot commands");
|
|
9009
9177
|
registerCaptureCommand(command);
|
|
9010
9178
|
registerTrendsCommand(command);
|
|
9011
9179
|
registerListCommand(command);
|
|
@@ -9013,11 +9181,11 @@ function createSnapshotCommand() {
|
|
|
9013
9181
|
}
|
|
9014
9182
|
|
|
9015
9183
|
// src/commands/state/index.ts
|
|
9016
|
-
import { Command as
|
|
9184
|
+
import { Command as Command82 } from "commander";
|
|
9017
9185
|
|
|
9018
9186
|
// src/commands/state/show.ts
|
|
9019
9187
|
init_dist2();
|
|
9020
|
-
import { Command as
|
|
9188
|
+
import { Command as Command78 } from "commander";
|
|
9021
9189
|
import * as path58 from "path";
|
|
9022
9190
|
function printStateText(state, stream) {
|
|
9023
9191
|
if (stream) console.log(`Stream: ${stream}`);
|
|
@@ -9042,7 +9210,7 @@ function printStateProgress(progress) {
|
|
|
9042
9210
|
}
|
|
9043
9211
|
}
|
|
9044
9212
|
function createShowCommand() {
|
|
9045
|
-
return new
|
|
9213
|
+
return new Command78("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
|
|
9046
9214
|
const globalOpts = cmd.optsWithGlobals();
|
|
9047
9215
|
const result = await loadState(path58.resolve(opts.path), opts.stream);
|
|
9048
9216
|
if (!result.ok) {
|
|
@@ -9060,7 +9228,7 @@ function createShowCommand() {
|
|
|
9060
9228
|
|
|
9061
9229
|
// src/commands/state/reset.ts
|
|
9062
9230
|
init_dist2();
|
|
9063
|
-
import { Command as
|
|
9231
|
+
import { Command as Command79 } from "commander";
|
|
9064
9232
|
import * as fs40 from "fs";
|
|
9065
9233
|
import * as path59 from "path";
|
|
9066
9234
|
import * as readline3 from "readline";
|
|
@@ -9077,8 +9245,8 @@ async function resolveStatePath(projectPath, stream) {
|
|
|
9077
9245
|
}
|
|
9078
9246
|
async function confirmReset() {
|
|
9079
9247
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
9080
|
-
const answer = await new Promise((
|
|
9081
|
-
rl.question("Reset project state? This cannot be undone. [y/N] ",
|
|
9248
|
+
const answer = await new Promise((resolve42) => {
|
|
9249
|
+
rl.question("Reset project state? This cannot be undone. [y/N] ", resolve42);
|
|
9082
9250
|
});
|
|
9083
9251
|
rl.close();
|
|
9084
9252
|
return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
@@ -9104,15 +9272,15 @@ async function runReset(opts) {
|
|
|
9104
9272
|
process.exit(ExitCode.SUCCESS);
|
|
9105
9273
|
}
|
|
9106
9274
|
function createResetCommand() {
|
|
9107
|
-
return new
|
|
9275
|
+
return new Command79("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));
|
|
9108
9276
|
}
|
|
9109
9277
|
|
|
9110
9278
|
// src/commands/state/learn.ts
|
|
9111
9279
|
init_dist2();
|
|
9112
|
-
import { Command as
|
|
9280
|
+
import { Command as Command80 } from "commander";
|
|
9113
9281
|
import * as path60 from "path";
|
|
9114
9282
|
function createLearnCommand() {
|
|
9115
|
-
return new
|
|
9283
|
+
return new Command80("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) => {
|
|
9116
9284
|
const projectPath = path60.resolve(opts.path);
|
|
9117
9285
|
const result = await appendLearning(projectPath, message, void 0, void 0, opts.stream);
|
|
9118
9286
|
if (!result.ok) {
|
|
@@ -9127,7 +9295,7 @@ function createLearnCommand() {
|
|
|
9127
9295
|
|
|
9128
9296
|
// src/commands/state/streams.ts
|
|
9129
9297
|
init_dist2();
|
|
9130
|
-
import { Command as
|
|
9298
|
+
import { Command as Command81 } from "commander";
|
|
9131
9299
|
import * as path61 from "path";
|
|
9132
9300
|
async function runListStreams(opts, globalOpts) {
|
|
9133
9301
|
const projectPath = path61.resolve(opts.path);
|
|
@@ -9178,7 +9346,7 @@ async function runActivateStream(name, opts) {
|
|
|
9178
9346
|
process.exit(ExitCode.SUCCESS);
|
|
9179
9347
|
}
|
|
9180
9348
|
function createStreamsCommand() {
|
|
9181
|
-
const command = new
|
|
9349
|
+
const command = new Command81("streams").description("Manage state streams");
|
|
9182
9350
|
command.command("list").description("List all known streams").option("--path <path>", "Project root path", ".").action(async (opts, cmd) => runListStreams(opts, cmd.optsWithGlobals()));
|
|
9183
9351
|
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));
|
|
9184
9352
|
command.command("archive <name>").description("Archive a stream").option("--path <path>", "Project root path", ".").action(async (name, opts) => runArchiveStream(name, opts));
|
|
@@ -9188,7 +9356,7 @@ function createStreamsCommand() {
|
|
|
9188
9356
|
|
|
9189
9357
|
// src/commands/state/index.ts
|
|
9190
9358
|
function createStateCommand() {
|
|
9191
|
-
const command = new
|
|
9359
|
+
const command = new Command82("state").description("Project state management commands");
|
|
9192
9360
|
command.addCommand(createShowCommand());
|
|
9193
9361
|
command.addCommand(createResetCommand());
|
|
9194
9362
|
command.addCommand(createLearnCommand());
|
|
@@ -9199,7 +9367,7 @@ function createStateCommand() {
|
|
|
9199
9367
|
// src/commands/sync-analyses.ts
|
|
9200
9368
|
import * as fs41 from "fs";
|
|
9201
9369
|
import * as path62 from "path";
|
|
9202
|
-
import { Command as
|
|
9370
|
+
import { Command as Command83 } from "commander";
|
|
9203
9371
|
init_dist2();
|
|
9204
9372
|
function isValidRecord(record) {
|
|
9205
9373
|
return typeof record.issueId === "string" && !!record.issueId && typeof record.identifier === "string" && !!record.identifier && typeof record.analyzedAt === "string" && !/[/\\]/.test(record.issueId);
|
|
@@ -9325,7 +9493,7 @@ async function runSyncAnalyses(opts) {
|
|
|
9325
9493
|
return;
|
|
9326
9494
|
}
|
|
9327
9495
|
const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
|
|
9328
|
-
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-
|
|
9496
|
+
const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-HA6IIPRC.js");
|
|
9329
9497
|
const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
|
|
9330
9498
|
const archive = new AnalysisArchive(path62.join(projectPath, ".harness", "analyses"));
|
|
9331
9499
|
const publishedIndex = loadPublishedIndex2(projectPath);
|
|
@@ -9347,7 +9515,7 @@ async function runSyncAnalyses(opts) {
|
|
|
9347
9515
|
}
|
|
9348
9516
|
}
|
|
9349
9517
|
function createSyncAnalysesCommand() {
|
|
9350
|
-
const command = new
|
|
9518
|
+
const command = new Command83("sync-analyses").description(
|
|
9351
9519
|
"Pull published intelligence analyses from the external issue tracker into the local .harness/analyses/ directory"
|
|
9352
9520
|
).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
9353
9521
|
try {
|
|
@@ -9361,7 +9529,7 @@ function createSyncAnalysesCommand() {
|
|
|
9361
9529
|
}
|
|
9362
9530
|
|
|
9363
9531
|
// src/commands/sync-main.ts
|
|
9364
|
-
import { Command as
|
|
9532
|
+
import { Command as Command84 } from "commander";
|
|
9365
9533
|
import * as path63 from "path";
|
|
9366
9534
|
import {
|
|
9367
9535
|
syncMain as defaultSyncMain
|
|
@@ -9392,7 +9560,7 @@ function formatHuman(r) {
|
|
|
9392
9560
|
}
|
|
9393
9561
|
}
|
|
9394
9562
|
function createSyncMainCommand() {
|
|
9395
|
-
return new
|
|
9563
|
+
return new Command84("sync-main").description("Fast-forward the local default branch from origin (no-op on conflict)").option("--json", "Emit a SyncMainResult JSON object", false).option("--path <path>", "Project root path", ".").action(async (opts) => {
|
|
9396
9564
|
const cwd = path63.resolve(opts.path ?? ".");
|
|
9397
9565
|
const exitCode = await runSyncMain({ cwd, json: Boolean(opts.json) });
|
|
9398
9566
|
process.exit(exitCode);
|
|
@@ -9401,7 +9569,7 @@ function createSyncMainCommand() {
|
|
|
9401
9569
|
|
|
9402
9570
|
// src/commands/taint.ts
|
|
9403
9571
|
init_dist2();
|
|
9404
|
-
import { Command as
|
|
9572
|
+
import { Command as Command85 } from "commander";
|
|
9405
9573
|
function getProjectRoot() {
|
|
9406
9574
|
return process.cwd();
|
|
9407
9575
|
}
|
|
@@ -9473,18 +9641,18 @@ function registerStatusCommand(taint) {
|
|
|
9473
9641
|
});
|
|
9474
9642
|
}
|
|
9475
9643
|
function createTaintCommand() {
|
|
9476
|
-
const taint = new
|
|
9644
|
+
const taint = new Command85("taint").description("Manage sentinel session taint state");
|
|
9477
9645
|
registerClearCommand(taint);
|
|
9478
9646
|
registerStatusCommand(taint);
|
|
9479
9647
|
return taint;
|
|
9480
9648
|
}
|
|
9481
9649
|
|
|
9482
9650
|
// src/commands/telemetry/index.ts
|
|
9483
|
-
import { Command as
|
|
9651
|
+
import { Command as Command89 } from "commander";
|
|
9484
9652
|
|
|
9485
9653
|
// src/commands/telemetry/identify.ts
|
|
9486
9654
|
init_dist2();
|
|
9487
|
-
import { Command as
|
|
9655
|
+
import { Command as Command86 } from "commander";
|
|
9488
9656
|
import * as fs42 from "fs";
|
|
9489
9657
|
import * as path64 from "path";
|
|
9490
9658
|
function telemetryFilePath(cwd) {
|
|
@@ -9508,7 +9676,7 @@ function printIdentity(identity) {
|
|
|
9508
9676
|
}
|
|
9509
9677
|
}
|
|
9510
9678
|
function createIdentifyCommand() {
|
|
9511
|
-
const cmd = new
|
|
9679
|
+
const cmd = new Command86("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) => {
|
|
9512
9680
|
const cwd = process.cwd();
|
|
9513
9681
|
if (opts.clear) {
|
|
9514
9682
|
writeTelemetryFile(cwd, { identity: {} });
|
|
@@ -9533,7 +9701,7 @@ function createIdentifyCommand() {
|
|
|
9533
9701
|
|
|
9534
9702
|
// src/commands/telemetry/status.ts
|
|
9535
9703
|
init_dist2();
|
|
9536
|
-
import { Command as
|
|
9704
|
+
import { Command as Command87 } from "commander";
|
|
9537
9705
|
function gatherEnvOverrides() {
|
|
9538
9706
|
const overrides = {};
|
|
9539
9707
|
if (process.env.DO_NOT_TRACK) overrides.DO_NOT_TRACK = process.env.DO_NOT_TRACK;
|
|
@@ -9575,7 +9743,7 @@ function printHumanStatus(result) {
|
|
|
9575
9743
|
printEnvOverrides(result.envOverrides);
|
|
9576
9744
|
}
|
|
9577
9745
|
function createStatusCommand() {
|
|
9578
|
-
const cmd = new
|
|
9746
|
+
const cmd = new Command87("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
|
|
9579
9747
|
const cwd = process.cwd();
|
|
9580
9748
|
const envOverrides = gatherEnvOverrides();
|
|
9581
9749
|
const consent = resolveConsent(cwd, void 0);
|
|
@@ -9608,20 +9776,20 @@ function createStatusCommand() {
|
|
|
9608
9776
|
|
|
9609
9777
|
// src/commands/telemetry/test.ts
|
|
9610
9778
|
init_dist2();
|
|
9611
|
-
import { Command as
|
|
9779
|
+
import { Command as Command88 } from "commander";
|
|
9612
9780
|
|
|
9613
9781
|
// src/bin/command-telemetry.ts
|
|
9614
9782
|
import { existsSync as existsSync39, readFileSync as readFileSync29, mkdirSync as mkdirSync19, appendFileSync, writeFileSync as writeFileSync23 } from "fs";
|
|
9615
|
-
import { join as join53, parse as parsePath, resolve as
|
|
9783
|
+
import { join as join53, parse as parsePath, resolve as resolve39 } from "path";
|
|
9616
9784
|
import { spawn as spawn2 } from "child_process";
|
|
9617
9785
|
var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
|
|
9618
9786
|
var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
|
|
9619
9787
|
function findProjectRoot(cwd) {
|
|
9620
|
-
let dir =
|
|
9788
|
+
let dir = resolve39(cwd);
|
|
9621
9789
|
const { root } = parsePath(dir);
|
|
9622
9790
|
while (dir !== root) {
|
|
9623
9791
|
if (existsSync39(join53(dir, "harness.config.json"))) return dir;
|
|
9624
|
-
dir =
|
|
9792
|
+
dir = resolve39(dir, "..");
|
|
9625
9793
|
}
|
|
9626
9794
|
return cwd;
|
|
9627
9795
|
}
|
|
@@ -9730,7 +9898,7 @@ function reportTestSuccess(status, distinctId, identity) {
|
|
|
9730
9898
|
if (identity.team) logger.info(` team: ${identity.team}`);
|
|
9731
9899
|
}
|
|
9732
9900
|
function createTestCommand() {
|
|
9733
|
-
return new
|
|
9901
|
+
return new Command88("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
|
|
9734
9902
|
const cwd = process.cwd();
|
|
9735
9903
|
const consent = resolveConsent(cwd, void 0);
|
|
9736
9904
|
if (!consent.allowed) {
|
|
@@ -9767,7 +9935,7 @@ function createTestCommand() {
|
|
|
9767
9935
|
|
|
9768
9936
|
// src/commands/telemetry/index.ts
|
|
9769
9937
|
function createTelemetryCommand() {
|
|
9770
|
-
const command = new
|
|
9938
|
+
const command = new Command89("telemetry").description("Telemetry identity and status management");
|
|
9771
9939
|
command.addCommand(createIdentifyCommand());
|
|
9772
9940
|
command.addCommand(createStatusCommand());
|
|
9773
9941
|
command.addCommand(createTestCommand());
|
|
@@ -9775,7 +9943,7 @@ function createTelemetryCommand() {
|
|
|
9775
9943
|
}
|
|
9776
9944
|
|
|
9777
9945
|
// src/commands/traceability.ts
|
|
9778
|
-
import { Command as
|
|
9946
|
+
import { Command as Command90 } from "commander";
|
|
9779
9947
|
import chalk14 from "chalk";
|
|
9780
9948
|
function confidenceLabel(maxConfidence) {
|
|
9781
9949
|
if (maxConfidence >= 0.8) return "explicit";
|
|
@@ -9896,7 +10064,7 @@ async function runTraceability(options) {
|
|
|
9896
10064
|
const projectPath = process.cwd();
|
|
9897
10065
|
const store = await loadGraphStore(projectPath);
|
|
9898
10066
|
if (!store) handleNoStore(mode);
|
|
9899
|
-
const graphModule = await import("./dist-
|
|
10067
|
+
const graphModule = await import("./dist-QPWXPCPL.js");
|
|
9900
10068
|
const filterOptions = buildFilterOptions(options);
|
|
9901
10069
|
const results = graphModule.queryTraceability(store, filterOptions);
|
|
9902
10070
|
if (results.length === 0) handleEmptyResults(mode);
|
|
@@ -9911,7 +10079,7 @@ async function runTraceability(options) {
|
|
|
9911
10079
|
process.exit(ExitCode.SUCCESS);
|
|
9912
10080
|
}
|
|
9913
10081
|
function createTraceabilityCommand() {
|
|
9914
|
-
return new
|
|
10082
|
+
return new Command90("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) => {
|
|
9915
10083
|
const globalOpts = cmd.optsWithGlobals();
|
|
9916
10084
|
await runTraceability({
|
|
9917
10085
|
spec: opts.spec,
|
|
@@ -9925,7 +10093,7 @@ function createTraceabilityCommand() {
|
|
|
9925
10093
|
|
|
9926
10094
|
// src/commands/uninstall.ts
|
|
9927
10095
|
import * as path65 from "path";
|
|
9928
|
-
import { Command as
|
|
10096
|
+
import { Command as Command91 } from "commander";
|
|
9929
10097
|
async function runUninstall(skillName, options) {
|
|
9930
10098
|
const packageName = resolvePackageName(skillName);
|
|
9931
10099
|
const shortName = extractSkillName(packageName);
|
|
@@ -9962,7 +10130,7 @@ async function runUninstall(skillName, options) {
|
|
|
9962
10130
|
return result;
|
|
9963
10131
|
}
|
|
9964
10132
|
function createUninstallCommand() {
|
|
9965
|
-
const cmd = new
|
|
10133
|
+
const cmd = new Command91("uninstall");
|
|
9966
10134
|
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) => {
|
|
9967
10135
|
try {
|
|
9968
10136
|
const result = await runUninstall(skill, opts);
|
|
@@ -9984,7 +10152,7 @@ function createUninstallCommand() {
|
|
|
9984
10152
|
init_dist2();
|
|
9985
10153
|
import * as fs43 from "fs/promises";
|
|
9986
10154
|
import * as path66 from "path";
|
|
9987
|
-
import { Command as
|
|
10155
|
+
import { Command as Command92 } from "commander";
|
|
9988
10156
|
async function runUninstallConstraints(options) {
|
|
9989
10157
|
const { packageName, configPath, lockfilePath } = options;
|
|
9990
10158
|
const lockfileResult = await readLockfile(lockfilePath);
|
|
@@ -10041,7 +10209,7 @@ async function runUninstallConstraints(options) {
|
|
|
10041
10209
|
};
|
|
10042
10210
|
}
|
|
10043
10211
|
function createUninstallConstraintsCommand() {
|
|
10044
|
-
const cmd = new
|
|
10212
|
+
const cmd = new Command92("uninstall-constraints");
|
|
10045
10213
|
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) => {
|
|
10046
10214
|
let configPath;
|
|
10047
10215
|
if (opts.config) {
|
|
@@ -10080,29 +10248,34 @@ function createUninstallConstraintsCommand() {
|
|
|
10080
10248
|
}
|
|
10081
10249
|
|
|
10082
10250
|
// src/commands/update.ts
|
|
10083
|
-
|
|
10251
|
+
init_dist2();
|
|
10252
|
+
import { Command as Command93 } from "commander";
|
|
10084
10253
|
import { execFile, execFileSync as execFileSync7 } from "child_process";
|
|
10085
10254
|
import { realpathSync, existsSync as existsSync40, readFileSync as readFileSync30 } from "fs";
|
|
10086
|
-
import { join as join56 } from "path";
|
|
10255
|
+
import { dirname as dirname22, join as join56 } from "path";
|
|
10087
10256
|
import { promisify } from "util";
|
|
10088
10257
|
import readline4 from "readline";
|
|
10089
10258
|
import chalk15 from "chalk";
|
|
10259
|
+
var CLI_PACKAGE = "@harness-engineering/cli";
|
|
10260
|
+
function detectPackageManagerFromPath(resolvedPath) {
|
|
10261
|
+
const normalizedBin = resolvedPath.replace(/\\/g, "/");
|
|
10262
|
+
if (normalizedBin.includes("pnpm/global/") || // eslint-disable-line @harness-engineering/no-hardcoded-path-separator -- platform-safe
|
|
10263
|
+
normalizedBin.includes("pnpm-global/")) {
|
|
10264
|
+
return "pnpm";
|
|
10265
|
+
}
|
|
10266
|
+
if (normalizedBin.includes(".yarn/")) {
|
|
10267
|
+
return "yarn";
|
|
10268
|
+
}
|
|
10269
|
+
return "npm";
|
|
10270
|
+
}
|
|
10090
10271
|
function detectPackageManager() {
|
|
10091
10272
|
try {
|
|
10092
10273
|
const argv1 = process.argv[1];
|
|
10093
10274
|
if (!argv1) return "npm";
|
|
10094
|
-
|
|
10095
|
-
const normalizedBin = binPath.replace(/\\/g, "/");
|
|
10096
|
-
if (normalizedBin.includes("pnpm/global/") || // eslint-disable-line @harness-engineering/no-hardcoded-path-separator -- platform-safe
|
|
10097
|
-
normalizedBin.includes("pnpm-global/")) {
|
|
10098
|
-
return "pnpm";
|
|
10099
|
-
}
|
|
10100
|
-
if (normalizedBin.includes(".yarn/")) {
|
|
10101
|
-
return "yarn";
|
|
10102
|
-
}
|
|
10275
|
+
return detectPackageManagerFromPath(realpathSync(argv1));
|
|
10103
10276
|
} catch {
|
|
10277
|
+
return "npm";
|
|
10104
10278
|
}
|
|
10105
|
-
return "npm";
|
|
10106
10279
|
}
|
|
10107
10280
|
var execFileAsync = promisify(execFile);
|
|
10108
10281
|
async function getLatestVersionAsync(pkg) {
|
|
@@ -10129,6 +10302,9 @@ function getInstalledVersions(pm, packages) {
|
|
|
10129
10302
|
versions[pkg] = null;
|
|
10130
10303
|
}
|
|
10131
10304
|
}
|
|
10305
|
+
if (packages.includes(CLI_PACKAGE) && versions[CLI_PACKAGE] === null) {
|
|
10306
|
+
versions[CLI_PACKAGE] = CLI_VERSION;
|
|
10307
|
+
}
|
|
10132
10308
|
return versions;
|
|
10133
10309
|
}
|
|
10134
10310
|
function getInstalledPackages(pm) {
|
|
@@ -10139,9 +10315,13 @@ function getInstalledPackages(pm) {
|
|
|
10139
10315
|
});
|
|
10140
10316
|
const data = JSON.parse(output);
|
|
10141
10317
|
const deps = data.dependencies ?? {};
|
|
10142
|
-
|
|
10318
|
+
const found = Object.keys(deps).filter((name) => name.startsWith("@harness-engineering/"));
|
|
10319
|
+
if (!found.includes(CLI_PACKAGE)) {
|
|
10320
|
+
found.unshift(CLI_PACKAGE);
|
|
10321
|
+
}
|
|
10322
|
+
return found;
|
|
10143
10323
|
} catch {
|
|
10144
|
-
return [
|
|
10324
|
+
return [CLI_PACKAGE, "@harness-engineering/core"];
|
|
10145
10325
|
}
|
|
10146
10326
|
}
|
|
10147
10327
|
function prompt3(question) {
|
|
@@ -10149,13 +10329,145 @@ function prompt3(question) {
|
|
|
10149
10329
|
input: process.stdin,
|
|
10150
10330
|
output: process.stdout
|
|
10151
10331
|
});
|
|
10152
|
-
return new Promise((
|
|
10332
|
+
return new Promise((resolve42) => {
|
|
10153
10333
|
rl.question(question, (answer) => {
|
|
10154
10334
|
rl.close();
|
|
10155
|
-
|
|
10335
|
+
resolve42(answer.trim().toLowerCase());
|
|
10156
10336
|
});
|
|
10157
10337
|
});
|
|
10158
10338
|
}
|
|
10339
|
+
function findPackageDir(resolvedBin) {
|
|
10340
|
+
let dir = dirname22(resolvedBin);
|
|
10341
|
+
for (let i = 0; i < 6; i++) {
|
|
10342
|
+
if (existsSync40(join56(dir, "package.json"))) {
|
|
10343
|
+
try {
|
|
10344
|
+
const pkg = JSON.parse(readFileSync30(join56(dir, "package.json"), "utf-8"));
|
|
10345
|
+
if (pkg?.name === CLI_PACKAGE) return dir;
|
|
10346
|
+
} catch {
|
|
10347
|
+
}
|
|
10348
|
+
}
|
|
10349
|
+
const parent = dirname22(dir);
|
|
10350
|
+
if (parent === dir) return null;
|
|
10351
|
+
dir = parent;
|
|
10352
|
+
}
|
|
10353
|
+
return null;
|
|
10354
|
+
}
|
|
10355
|
+
function derivePrefix(packageDir) {
|
|
10356
|
+
const normalized = packageDir.replace(/\\/g, "/");
|
|
10357
|
+
const marker = "/lib/node_modules/@harness-engineering/cli";
|
|
10358
|
+
if (!normalized.endsWith(marker)) return null;
|
|
10359
|
+
return packageDir.slice(0, packageDir.length - marker.length);
|
|
10360
|
+
}
|
|
10361
|
+
function findAllInstalls() {
|
|
10362
|
+
const isWindows = process.platform === "win32";
|
|
10363
|
+
const cmd = isWindows ? "where" : "which";
|
|
10364
|
+
const args = isWindows ? ["harness"] : ["-a", "harness"];
|
|
10365
|
+
let output;
|
|
10366
|
+
try {
|
|
10367
|
+
const raw = execFileSync7(cmd, args, { encoding: "utf-8", timeout: 5e3 });
|
|
10368
|
+
if (typeof raw !== "string") return [];
|
|
10369
|
+
output = raw;
|
|
10370
|
+
} catch {
|
|
10371
|
+
return [];
|
|
10372
|
+
}
|
|
10373
|
+
const paths = output.split(/\r?\n/).map((p) => p.trim()).filter(Boolean);
|
|
10374
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10375
|
+
const installs = [];
|
|
10376
|
+
for (const binPath of paths) {
|
|
10377
|
+
let resolved;
|
|
10378
|
+
try {
|
|
10379
|
+
resolved = realpathSync(binPath);
|
|
10380
|
+
} catch {
|
|
10381
|
+
continue;
|
|
10382
|
+
}
|
|
10383
|
+
if (seen.has(resolved)) continue;
|
|
10384
|
+
seen.add(resolved);
|
|
10385
|
+
const packageDir = findPackageDir(resolved);
|
|
10386
|
+
if (!packageDir) continue;
|
|
10387
|
+
let version = null;
|
|
10388
|
+
try {
|
|
10389
|
+
const pkg = JSON.parse(readFileSync30(join56(packageDir, "package.json"), "utf-8"));
|
|
10390
|
+
if (typeof pkg?.version === "string") version = pkg.version;
|
|
10391
|
+
} catch {
|
|
10392
|
+
}
|
|
10393
|
+
installs.push({
|
|
10394
|
+
binPath,
|
|
10395
|
+
resolvedBin: resolved,
|
|
10396
|
+
packageDir,
|
|
10397
|
+
prefix: derivePrefix(packageDir),
|
|
10398
|
+
version,
|
|
10399
|
+
packageManager: detectPackageManagerFromPath(resolved)
|
|
10400
|
+
});
|
|
10401
|
+
}
|
|
10402
|
+
return installs;
|
|
10403
|
+
}
|
|
10404
|
+
function getActiveInstallDir() {
|
|
10405
|
+
try {
|
|
10406
|
+
const argv1 = process.argv[1];
|
|
10407
|
+
if (!argv1) return null;
|
|
10408
|
+
return findPackageDir(realpathSync(argv1));
|
|
10409
|
+
} catch {
|
|
10410
|
+
return null;
|
|
10411
|
+
}
|
|
10412
|
+
}
|
|
10413
|
+
async function offerCleanupOfOtherInstalls(activeDir) {
|
|
10414
|
+
const installs = findAllInstalls();
|
|
10415
|
+
if (installs.length <= 1) return;
|
|
10416
|
+
const others = installs.filter((i) => i.packageDir !== activeDir);
|
|
10417
|
+
if (others.length === 0) return;
|
|
10418
|
+
console.log("");
|
|
10419
|
+
logger.warn(
|
|
10420
|
+
`Found ${installs.length} harness installs on PATH. Only the active one was updated.`
|
|
10421
|
+
);
|
|
10422
|
+
for (const install of installs) {
|
|
10423
|
+
const tag = install.packageDir === activeDir ? chalk15.green(" (active, just updated)") : chalk15.yellow(" (stale)");
|
|
10424
|
+
const versionStr = install.version ? `v${install.version}` : "unknown";
|
|
10425
|
+
console.log(` ${install.binPath} -> ${versionStr}${tag}`);
|
|
10426
|
+
}
|
|
10427
|
+
console.log("");
|
|
10428
|
+
const commands = others.map((install) => buildUninstallCommand(install));
|
|
10429
|
+
console.log("Cleanup commands:");
|
|
10430
|
+
for (const { display } of commands) {
|
|
10431
|
+
console.log(` ${chalk15.cyan(display)}`);
|
|
10432
|
+
}
|
|
10433
|
+
console.log("");
|
|
10434
|
+
const answer = await prompt3(`Run these now to remove stale installs? (y/N) `);
|
|
10435
|
+
if (answer !== "y" && answer !== "yes") return;
|
|
10436
|
+
for (const cmd of commands) {
|
|
10437
|
+
if (!cmd.runnable) {
|
|
10438
|
+
logger.warn(`Skipped ${cmd.install.binPath} (no automatic uninstall for this layout).`);
|
|
10439
|
+
console.log(` Run manually: ${chalk15.cyan(cmd.display)}`);
|
|
10440
|
+
continue;
|
|
10441
|
+
}
|
|
10442
|
+
try {
|
|
10443
|
+
logger.info(`Uninstalling: ${cmd.display}`);
|
|
10444
|
+
execFileSync7(cmd.bin, cmd.args, { stdio: "inherit", timeout: 12e4 });
|
|
10445
|
+
} catch {
|
|
10446
|
+
logger.warn(`Uninstall failed for ${cmd.install.binPath}.`);
|
|
10447
|
+
console.log(` Run manually: ${chalk15.cyan(cmd.display)}`);
|
|
10448
|
+
}
|
|
10449
|
+
}
|
|
10450
|
+
}
|
|
10451
|
+
function buildUninstallCommand(install) {
|
|
10452
|
+
if (install.packageManager === "npm" && install.prefix) {
|
|
10453
|
+
const args = [`--prefix=${install.prefix}`, "uninstall", "-g", CLI_PACKAGE];
|
|
10454
|
+
return {
|
|
10455
|
+
install,
|
|
10456
|
+
runnable: true,
|
|
10457
|
+
bin: "npm",
|
|
10458
|
+
args,
|
|
10459
|
+
display: `npm ${args.join(" ")}`
|
|
10460
|
+
};
|
|
10461
|
+
}
|
|
10462
|
+
const pmCmd = install.packageManager === "yarn" ? "yarn global remove" : "pnpm remove -g";
|
|
10463
|
+
return {
|
|
10464
|
+
install,
|
|
10465
|
+
runnable: false,
|
|
10466
|
+
bin: install.packageManager,
|
|
10467
|
+
args: [],
|
|
10468
|
+
display: `${pmCmd} ${CLI_PACKAGE}`
|
|
10469
|
+
};
|
|
10470
|
+
}
|
|
10159
10471
|
async function ensureTelemetryIfNeeded() {
|
|
10160
10472
|
const cwd = process.cwd();
|
|
10161
10473
|
const result = await ensureTelemetryConfigured(cwd);
|
|
@@ -10266,6 +10578,7 @@ async function runUpdateAction(opts, globalOpts) {
|
|
|
10266
10578
|
logger.success("All packages are up to date");
|
|
10267
10579
|
refreshHooks();
|
|
10268
10580
|
await ensureTelemetryIfNeeded();
|
|
10581
|
+
await offerCleanupOfOtherInstalls(getActiveInstallDir());
|
|
10269
10582
|
await offerRegeneration();
|
|
10270
10583
|
process.exit(ExitCode.SUCCESS);
|
|
10271
10584
|
}
|
|
@@ -10286,6 +10599,7 @@ async function runUpdateAction(opts, globalOpts) {
|
|
|
10286
10599
|
execFileSync7(pm, ["install", "-g", ...installPkgs], { stdio: "inherit", timeout: 12e4 });
|
|
10287
10600
|
console.log("");
|
|
10288
10601
|
logger.success("Update complete");
|
|
10602
|
+
invalidateCheckState();
|
|
10289
10603
|
} catch {
|
|
10290
10604
|
console.log("");
|
|
10291
10605
|
logger.error("Update failed. You can try manually:");
|
|
@@ -10294,11 +10608,12 @@ async function runUpdateAction(opts, globalOpts) {
|
|
|
10294
10608
|
}
|
|
10295
10609
|
refreshHooks();
|
|
10296
10610
|
await ensureTelemetryIfNeeded();
|
|
10611
|
+
await offerCleanupOfOtherInstalls(getActiveInstallDir());
|
|
10297
10612
|
await offerRegeneration();
|
|
10298
10613
|
process.exit(ExitCode.SUCCESS);
|
|
10299
10614
|
}
|
|
10300
10615
|
function createUpdateCommand() {
|
|
10301
|
-
return new
|
|
10616
|
+
return new Command93("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(
|
|
10302
10617
|
"--regenerate",
|
|
10303
10618
|
"Only regenerate slash commands and agent definitions (skip package updates)"
|
|
10304
10619
|
).action(async (opts, cmd) => {
|
|
@@ -10308,9 +10623,9 @@ function createUpdateCommand() {
|
|
|
10308
10623
|
}
|
|
10309
10624
|
|
|
10310
10625
|
// src/commands/usage.ts
|
|
10311
|
-
import { Command as
|
|
10626
|
+
import { Command as Command94 } from "commander";
|
|
10312
10627
|
async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
|
|
10313
|
-
const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-
|
|
10628
|
+
const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-HA6IIPRC.js");
|
|
10314
10629
|
const records = readCostRecords(cwd);
|
|
10315
10630
|
if (includeClaudeSessions) {
|
|
10316
10631
|
const ccRecords = parseCCRecords();
|
|
@@ -10403,7 +10718,7 @@ function registerDailyCommand(usage) {
|
|
|
10403
10718
|
else logger.info("No usage data found. Run some harness sessions first.");
|
|
10404
10719
|
return;
|
|
10405
10720
|
}
|
|
10406
|
-
const { aggregateByDay } = await import("./dist-
|
|
10721
|
+
const { aggregateByDay } = await import("./dist-HA6IIPRC.js");
|
|
10407
10722
|
const limited = aggregateByDay(records).slice(0, days);
|
|
10408
10723
|
if (globalOpts.json) {
|
|
10409
10724
|
console.log(
|
|
@@ -10432,7 +10747,7 @@ function registerSessionsCommand(usage) {
|
|
|
10432
10747
|
}
|
|
10433
10748
|
return;
|
|
10434
10749
|
}
|
|
10435
|
-
const { aggregateBySession } = await import("./dist-
|
|
10750
|
+
const { aggregateBySession } = await import("./dist-HA6IIPRC.js");
|
|
10436
10751
|
const sessionData = aggregateBySession(records);
|
|
10437
10752
|
const limited = sessionData.slice(0, limit);
|
|
10438
10753
|
if (globalOpts.json) {
|
|
@@ -10512,7 +10827,7 @@ function registerSessionCommand(usage) {
|
|
|
10512
10827
|
cwd,
|
|
10513
10828
|
globalOpts.includeClaudeSessions
|
|
10514
10829
|
);
|
|
10515
|
-
const { aggregateBySession } = await import("./dist-
|
|
10830
|
+
const { aggregateBySession } = await import("./dist-HA6IIPRC.js");
|
|
10516
10831
|
const sessionData = aggregateBySession(records);
|
|
10517
10832
|
const match = sessionData.find((s) => s.sessionId === id);
|
|
10518
10833
|
if (!match) {
|
|
@@ -10547,7 +10862,7 @@ function registerLatestCommand(usage) {
|
|
|
10547
10862
|
}
|
|
10548
10863
|
return;
|
|
10549
10864
|
}
|
|
10550
|
-
const { aggregateBySession } = await import("./dist-
|
|
10865
|
+
const { aggregateBySession } = await import("./dist-HA6IIPRC.js");
|
|
10551
10866
|
const sessionData = aggregateBySession(records);
|
|
10552
10867
|
const latest = sessionData[0];
|
|
10553
10868
|
if (!latest) {
|
|
@@ -10573,7 +10888,7 @@ function registerLatestCommand(usage) {
|
|
|
10573
10888
|
});
|
|
10574
10889
|
}
|
|
10575
10890
|
function createUsageCommand() {
|
|
10576
|
-
const usage = new
|
|
10891
|
+
const usage = new Command94("usage").description("Token usage and cost tracking");
|
|
10577
10892
|
usage.option(
|
|
10578
10893
|
"--include-claude-sessions",
|
|
10579
10894
|
"Include Claude Code session data from ~/.claude/projects/"
|
|
@@ -10588,7 +10903,7 @@ function createUsageCommand() {
|
|
|
10588
10903
|
// src/commands/validate.ts
|
|
10589
10904
|
init_dist2();
|
|
10590
10905
|
init_dist2();
|
|
10591
|
-
import { Command as
|
|
10906
|
+
import { Command as Command95 } from "commander";
|
|
10592
10907
|
import * as path67 from "path";
|
|
10593
10908
|
async function runValidate(options) {
|
|
10594
10909
|
const configResult = resolveConfig(options.configPath);
|
|
@@ -10716,7 +11031,7 @@ function resolveValidateMode(globalOpts) {
|
|
|
10716
11031
|
return OutputMode.TEXT;
|
|
10717
11032
|
}
|
|
10718
11033
|
async function printCrossCheckWarnings(mode) {
|
|
10719
|
-
const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-
|
|
11034
|
+
const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-H3PSV4VY.js");
|
|
10720
11035
|
const cwd = process.cwd();
|
|
10721
11036
|
const crossResult = await runCrossCheck2({
|
|
10722
11037
|
specsDir: path67.join(cwd, "docs", "specs"),
|
|
@@ -10732,7 +11047,7 @@ async function printCrossCheckWarnings(mode) {
|
|
|
10732
11047
|
${crossResult.value.warnings} warnings`);
|
|
10733
11048
|
}
|
|
10734
11049
|
function createValidateCommand3() {
|
|
10735
|
-
const command = new
|
|
11050
|
+
const command = new Command95("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
|
|
10736
11051
|
"--agent-configs",
|
|
10737
11052
|
"Validate agent configs (CLAUDE.md, hooks, skills) via agnix or built-in fallback rules"
|
|
10738
11053
|
).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()));
|
|
@@ -10779,6 +11094,86 @@ Agent configs checked via ${engineLabel}${note}`);
|
|
|
10779
11094
|
}
|
|
10780
11095
|
}
|
|
10781
11096
|
|
|
11097
|
+
// src/commands/verify.ts
|
|
11098
|
+
init_dist2();
|
|
11099
|
+
import { Command as Command96 } from "commander";
|
|
11100
|
+
import { execSync as execSync6 } from "child_process";
|
|
11101
|
+
function loadBranchingConfig(configPath) {
|
|
11102
|
+
const shouldLoad = configPath !== void 0 || findConfigFile().ok;
|
|
11103
|
+
if (!shouldLoad) {
|
|
11104
|
+
return BranchingConfigSchema.parse({});
|
|
11105
|
+
}
|
|
11106
|
+
const result = resolveConfig(configPath);
|
|
11107
|
+
if (!result.ok) {
|
|
11108
|
+
logger.error(result.error.message);
|
|
11109
|
+
process.exit(result.error.exitCode);
|
|
11110
|
+
}
|
|
11111
|
+
const cfg = result.value.compliance?.branching;
|
|
11112
|
+
return cfg ?? BranchingConfigSchema.parse({});
|
|
11113
|
+
}
|
|
11114
|
+
function resolveBranchName(explicit) {
|
|
11115
|
+
if (explicit && explicit.length > 0) return explicit;
|
|
11116
|
+
const envBranch = process.env.HARNESS_BRANCH || process.env.GITHUB_HEAD_REF || process.env.CI_COMMIT_REF_NAME || process.env.BUILDKITE_BRANCH;
|
|
11117
|
+
if (envBranch && envBranch.length > 0) return envBranch;
|
|
11118
|
+
try {
|
|
11119
|
+
const out = execSync6("git rev-parse --abbrev-ref HEAD", {
|
|
11120
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
11121
|
+
}).toString().trim();
|
|
11122
|
+
if (out && out !== "HEAD") return out;
|
|
11123
|
+
} catch {
|
|
11124
|
+
return null;
|
|
11125
|
+
}
|
|
11126
|
+
return null;
|
|
11127
|
+
}
|
|
11128
|
+
async function runVerify(options) {
|
|
11129
|
+
const branchingConfig = loadBranchingConfig(options.configPath);
|
|
11130
|
+
const branchName = resolveBranchName(options.branch);
|
|
11131
|
+
if (!branchName) {
|
|
11132
|
+
const msg = "Could not determine the current branch name. Pass --branch <name>, set HARNESS_BRANCH/GITHUB_HEAD_REF, or run inside a git checkout.";
|
|
11133
|
+
if (options.json) {
|
|
11134
|
+
console.log(JSON.stringify({ valid: false, branchName: "", message: msg }));
|
|
11135
|
+
} else {
|
|
11136
|
+
logger.error(msg);
|
|
11137
|
+
}
|
|
11138
|
+
process.exit(ExitCode.ERROR);
|
|
11139
|
+
}
|
|
11140
|
+
const result = validateBranchName(branchName, branchingConfig);
|
|
11141
|
+
if (options.json) {
|
|
11142
|
+
const payload = {
|
|
11143
|
+
valid: result.valid,
|
|
11144
|
+
branchName: result.branchName,
|
|
11145
|
+
...result.message !== void 0 && { message: result.message },
|
|
11146
|
+
...result.suggestion !== void 0 && { suggestion: result.suggestion }
|
|
11147
|
+
};
|
|
11148
|
+
console.log(JSON.stringify(payload));
|
|
11149
|
+
process.exit(result.valid ? ExitCode.SUCCESS : ExitCode.VALIDATION_FAILED);
|
|
11150
|
+
}
|
|
11151
|
+
if (result.valid) {
|
|
11152
|
+
logger.success(`Branch name "${branchName}" is compliant.`);
|
|
11153
|
+
process.exit(ExitCode.SUCCESS);
|
|
11154
|
+
}
|
|
11155
|
+
logger.error(result.message || `Branch name "${branchName}" is not compliant.`);
|
|
11156
|
+
if (result.suggestion) {
|
|
11157
|
+
logger.info(`Suggestion: ${result.suggestion}`);
|
|
11158
|
+
}
|
|
11159
|
+
process.exit(ExitCode.VALIDATION_FAILED);
|
|
11160
|
+
}
|
|
11161
|
+
function createVerifyCommand() {
|
|
11162
|
+
return new Command96("verify").description(
|
|
11163
|
+
"Verify project conventions (currently: branch naming). Works with or without a harness.config.json."
|
|
11164
|
+
).option(
|
|
11165
|
+
"--branch <name>",
|
|
11166
|
+
"Branch name to verify (defaults to HARNESS_BRANCH/GITHUB_HEAD_REF/current branch)"
|
|
11167
|
+
).option("--json", "Emit machine-readable JSON output").action(async (opts, cmd) => {
|
|
11168
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
11169
|
+
await runVerify({
|
|
11170
|
+
...typeof globalOpts.config === "string" && { configPath: globalOpts.config },
|
|
11171
|
+
...typeof opts.branch === "string" && { branch: opts.branch },
|
|
11172
|
+
json: opts.json === true || globalOpts.json === true
|
|
11173
|
+
});
|
|
11174
|
+
});
|
|
11175
|
+
}
|
|
11176
|
+
|
|
10782
11177
|
// src/commands/_registry.ts
|
|
10783
11178
|
var commandCreators = [
|
|
10784
11179
|
createAddCommand,
|
|
@@ -10801,6 +11196,7 @@ var commandCreators = [
|
|
|
10801
11196
|
createDashboardCommand,
|
|
10802
11197
|
createDoctorCommand,
|
|
10803
11198
|
createFixDriftCommand,
|
|
11199
|
+
createGatewayCommand,
|
|
10804
11200
|
createGenerateAgentDefinitionsCommand,
|
|
10805
11201
|
createGenerateCommand,
|
|
10806
11202
|
createGenerateSlashCommandsCommand,
|
|
@@ -10843,12 +11239,13 @@ var commandCreators = [
|
|
|
10843
11239
|
createUninstallConstraintsCommand,
|
|
10844
11240
|
createUpdateCommand,
|
|
10845
11241
|
createUsageCommand,
|
|
10846
|
-
createValidateCommand3
|
|
11242
|
+
createValidateCommand3,
|
|
11243
|
+
createVerifyCommand
|
|
10847
11244
|
];
|
|
10848
11245
|
|
|
10849
11246
|
// src/index.ts
|
|
10850
11247
|
function createProgram() {
|
|
10851
|
-
const program = new
|
|
11248
|
+
const program = new Command97();
|
|
10852
11249
|
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");
|
|
10853
11250
|
for (const creator of commandCreators) {
|
|
10854
11251
|
program.addCommand(creator());
|