@brainervirus/workit-claude-code 7.7.0 → 8.0.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/.claude-plugin/plugin.json +1 -1
- package/dist/workit-hook.js +38 -38
- package/dist/workit.js +667 -137
- package/package.json +3 -3
- package/skills/ship/SKILL.md +2 -2
package/dist/workit.js
CHANGED
|
@@ -65,7 +65,7 @@ var package_default;
|
|
|
65
65
|
var init_package = __esm(() => {
|
|
66
66
|
package_default = {
|
|
67
67
|
name: "@brainervirus/workit-cli",
|
|
68
|
-
version: "
|
|
68
|
+
version: "8.0.1",
|
|
69
69
|
private: false,
|
|
70
70
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
71
71
|
keywords: [
|
|
@@ -103,9 +103,9 @@ var init_package = __esm(() => {
|
|
|
103
103
|
},
|
|
104
104
|
dependencies: {
|
|
105
105
|
"@babel/parser": "7.29.9",
|
|
106
|
-
"@brainervirus/workit-core": "^
|
|
107
|
-
"@brainervirus/workit-cursor": "^
|
|
108
|
-
"@brainervirus/workit-opencode": "^
|
|
106
|
+
"@brainervirus/workit-core": "^8.0.1",
|
|
107
|
+
"@brainervirus/workit-cursor": "^8.0.1",
|
|
108
|
+
"@brainervirus/workit-opencode": "^8.0.1",
|
|
109
109
|
"@inkjs/ui": "2.0.0",
|
|
110
110
|
ink: "7.1.1",
|
|
111
111
|
react: "19.2.8"
|
|
@@ -13267,7 +13267,7 @@ function authorSessions(cwd, rows, branch, range = { base: null, head: null }) {
|
|
|
13267
13267
|
sessions.add(session);
|
|
13268
13268
|
return sessions;
|
|
13269
13269
|
}
|
|
13270
|
-
function effectiveOf(rows, authors) {
|
|
13270
|
+
function effectiveOf(rows, authors, sameCode) {
|
|
13271
13271
|
let effective = null;
|
|
13272
13272
|
for (const row of rows) {
|
|
13273
13273
|
if (!effective) {
|
|
@@ -13278,7 +13278,7 @@ function effectiveOf(rows, authors) {
|
|
|
13278
13278
|
const effIndependent = independenceReasons(effective, authors).length === 0;
|
|
13279
13279
|
if (effIndependent && !rowIndependent)
|
|
13280
13280
|
continue;
|
|
13281
|
-
if (effIndependent && FAILING.has(String(effective.result)) && row.actor.session === effective.actor.session)
|
|
13281
|
+
if (effIndependent && FAILING.has(String(effective.result)) && row.actor.session === effective.actor.session && sameCode(effective, row))
|
|
13282
13282
|
continue;
|
|
13283
13283
|
effective = row;
|
|
13284
13284
|
}
|
|
@@ -13309,16 +13309,22 @@ function checkVerdicts(cwd, branch, rows) {
|
|
|
13309
13309
|
const head = branchHead(cwd, branch);
|
|
13310
13310
|
const fallbackBase = defaultBase(cwd);
|
|
13311
13311
|
const keyCache = new Map;
|
|
13312
|
-
const
|
|
13313
|
-
if (!base || !
|
|
13312
|
+
const keysAt = (base, at) => {
|
|
13313
|
+
if (!base || !at)
|
|
13314
13314
|
return { patchId: null, diffHash: null };
|
|
13315
|
-
|
|
13315
|
+
const cacheKey = `${base}\x00${at}`;
|
|
13316
|
+
let key = keyCache.get(cacheKey);
|
|
13316
13317
|
if (!key) {
|
|
13317
|
-
key = { patchId: patchId(cwd, base,
|
|
13318
|
-
keyCache.set(
|
|
13318
|
+
key = { patchId: patchId(cwd, base, at), diffHash: diffHash(cwd, base, at) };
|
|
13319
|
+
keyCache.set(cacheKey, key);
|
|
13319
13320
|
}
|
|
13320
13321
|
return key;
|
|
13321
13322
|
};
|
|
13323
|
+
const keyFor = (base) => keysAt(base, head);
|
|
13324
|
+
const sameCode = (failed, row) => verdictBasis(failed, {
|
|
13325
|
+
head: row.head,
|
|
13326
|
+
...keysAt(failed.base ?? fallbackBase, row.head)
|
|
13327
|
+
}) !== "stale" || restackCarries(rows, branch, failed.head, row.head);
|
|
13322
13328
|
const authors = authorSessions(cwd, rows, branch, { base: fallbackBase, head });
|
|
13323
13329
|
const byKind = new Map;
|
|
13324
13330
|
for (const row of rows)
|
|
@@ -13328,7 +13334,7 @@ function checkVerdicts(cwd, branch, rows) {
|
|
|
13328
13334
|
}
|
|
13329
13335
|
const verdicts = [];
|
|
13330
13336
|
for (const [kind, list] of byKind) {
|
|
13331
|
-
const row = effectiveOf(list, authors);
|
|
13337
|
+
const row = effectiveOf(list, authors, sameCode);
|
|
13332
13338
|
if (!row)
|
|
13333
13339
|
continue;
|
|
13334
13340
|
let basis = verdictBasis(row, { head, ...keyFor(row.base ?? fallbackBase) });
|
|
@@ -13354,11 +13360,11 @@ function checkVerdicts(cwd, branch, rows) {
|
|
|
13354
13360
|
verdicts.sort((a, b) => a.verdict.seq - b.verdict.seq);
|
|
13355
13361
|
const newestCurrent = verdicts.findLast((entry) => entry.current) ?? verdicts.at(-1) ?? null;
|
|
13356
13362
|
const failing = verdicts.find((entry) => entry.current && entry.independent && FAILING.has(String(entry.verdict.result)));
|
|
13357
|
-
const newestAccepted = verdicts.findLast((entry) => entry.accepted) ?? null;
|
|
13363
|
+
const newestAccepted = verdicts.findLast((entry) => entry.accepted && STRONG_RESULTS.has(String(entry.verdict.result))) ?? null;
|
|
13358
13364
|
const accepted = newestAccepted && !failing ? { accepted: true, verdict: newestAccepted.verdict, reasons: [] } : {
|
|
13359
13365
|
accepted: false,
|
|
13360
13366
|
verdict: failing?.verdict ?? null,
|
|
13361
|
-
reasons: failing ? ["failing_verdict"] : newestCurrent
|
|
13367
|
+
reasons: failing ? ["failing_verdict"] : !newestCurrent ? ["no_verdict"] : newestCurrent.reasons.length ? newestCurrent.reasons : ["type_check_only"]
|
|
13362
13368
|
};
|
|
13363
13369
|
const selfEntry = failing ? undefined : verdicts.findLast((entry) => entry.current && !entry.independent && STRONG_RESULTS.has(String(entry.verdict.result)));
|
|
13364
13370
|
return {
|
|
@@ -13587,6 +13593,9 @@ function summarizeRow(row) {
|
|
|
13587
13593
|
case "pr.merged":
|
|
13588
13594
|
summary = `#${row.pr ?? "?"} ${text("method")} at ${(row.head ?? "?").slice(0, 12)}${text("mergeSha") ? ` -> ${text("mergeSha").slice(0, 12)}` : ""}`;
|
|
13589
13595
|
break;
|
|
13596
|
+
case "merge.unverified":
|
|
13597
|
+
summary = `#${row.pr ?? "?"} unverified merge requested at ${(row.head ?? "?").slice(0, 12)} (reason: ${text("reason")})`;
|
|
13598
|
+
break;
|
|
13590
13599
|
case "delivery.verified":
|
|
13591
13600
|
summary = `${text("expect")} delivered at ${(row.head ?? "?").slice(0, 12)}`;
|
|
13592
13601
|
break;
|
|
@@ -13911,7 +13920,7 @@ var init_ledger = __esm(() => {
|
|
|
13911
13920
|
return false;
|
|
13912
13921
|
}
|
|
13913
13922
|
};
|
|
13914
|
-
OBSERVED_ONLY = new Set(["check", ...PR_ROW_TYPES]);
|
|
13923
|
+
OBSERVED_ONLY = new Set(["check", "merge.unverified", ...PR_ROW_TYPES]);
|
|
13915
13924
|
});
|
|
13916
13925
|
|
|
13917
13926
|
// packages/workit-core/src/core/policy/derive.ts
|
|
@@ -16656,7 +16665,7 @@ function requireGrant(cwd, kind, options = {}) {
|
|
|
16656
16665
|
allowed: true,
|
|
16657
16666
|
kind,
|
|
16658
16667
|
source: configured ? autonomy.source : "default",
|
|
16659
|
-
|
|
16668
|
+
allowUnverified: kind === "merge" && value === true,
|
|
16660
16669
|
workspace
|
|
16661
16670
|
};
|
|
16662
16671
|
}
|
|
@@ -19123,20 +19132,30 @@ async function parseTaskArgs(argv, deps) {
|
|
|
19123
19132
|
const judge = [];
|
|
19124
19133
|
const seen = new Set;
|
|
19125
19134
|
for (let i = 2;i < argv.length; i += 1) {
|
|
19126
|
-
|
|
19135
|
+
if (argv[i] === "--") {
|
|
19136
|
+
const extra = argv.slice(i + 1);
|
|
19137
|
+
if (extra.length)
|
|
19138
|
+
return parseUsage(`${family} ${actionName} takes no positional arguments (got: ${extra.join(" ")})`, json);
|
|
19139
|
+
break;
|
|
19140
|
+
}
|
|
19141
|
+
const eq = argv[i].startsWith("--") ? argv[i].indexOf("=") : -1;
|
|
19142
|
+
const token = eq > 0 ? argv[i].slice(0, eq) : argv[i];
|
|
19143
|
+
const inline = eq > 0 ? argv[i].slice(eq + 1) : undefined;
|
|
19127
19144
|
if (family === "policy" && (token === "--judge" || token === "--ref")) {
|
|
19128
19145
|
if (token === "--ref") {
|
|
19129
|
-
const value = argv[++i];
|
|
19146
|
+
const value = inline ?? argv[++i];
|
|
19130
19147
|
if (value === undefined || !value.trim())
|
|
19131
19148
|
return parseUsage("--ref requires a value", json);
|
|
19132
19149
|
judge.push(`ref=${value}`);
|
|
19133
19150
|
continue;
|
|
19134
19151
|
}
|
|
19152
|
+
if (inline !== undefined)
|
|
19153
|
+
judge.push(inline);
|
|
19135
19154
|
while (argv[i + 1] !== undefined && !argv[i + 1].startsWith("--"))
|
|
19136
19155
|
judge.push(argv[++i]);
|
|
19137
19156
|
continue;
|
|
19138
19157
|
}
|
|
19139
|
-
if (token === "--json" || token === "--confirm") {
|
|
19158
|
+
if ((token === "--json" || token === "--confirm") && inline === undefined) {
|
|
19140
19159
|
if (seen.has(token))
|
|
19141
19160
|
return parseUsage(`duplicate argument: ${token}`, json);
|
|
19142
19161
|
seen.add(token);
|
|
@@ -19145,8 +19164,8 @@ async function parseTaskArgs(argv, deps) {
|
|
|
19145
19164
|
continue;
|
|
19146
19165
|
}
|
|
19147
19166
|
if (!["--payload", "--task", "--revision", "--workspace-revision", "--view", "--actor"].includes(token))
|
|
19148
|
-
return parseUsage(`unknown argument: ${
|
|
19149
|
-
const value = argv[++i];
|
|
19167
|
+
return parseUsage(`unknown argument: ${argv[i]}`, json);
|
|
19168
|
+
const value = inline ?? argv[++i];
|
|
19150
19169
|
if (value === undefined || value.trim() === "" && token !== "--workspace-revision")
|
|
19151
19170
|
return parseUsage(`${token} requires a value`, json);
|
|
19152
19171
|
if (seen.has(token))
|
|
@@ -19205,6 +19224,12 @@ async function parseHandoffArgs(argv, deps) {
|
|
|
19205
19224
|
const seen = new Set;
|
|
19206
19225
|
for (let i = 0;i < argv.length; i += 1) {
|
|
19207
19226
|
const token = argv[i];
|
|
19227
|
+
if (token === "--") {
|
|
19228
|
+
const extra = argv.slice(i + 1);
|
|
19229
|
+
if (extra.length)
|
|
19230
|
+
return parseUsage(`handoff takes no positional arguments (got: ${extra.join(" ")})`, json);
|
|
19231
|
+
break;
|
|
19232
|
+
}
|
|
19208
19233
|
if (token === "--json") {
|
|
19209
19234
|
if (seen.has(token))
|
|
19210
19235
|
return parseUsage(`duplicate argument: ${token}`, json);
|
|
@@ -19212,14 +19237,18 @@ async function parseHandoffArgs(argv, deps) {
|
|
|
19212
19237
|
json = true;
|
|
19213
19238
|
continue;
|
|
19214
19239
|
}
|
|
19215
|
-
|
|
19240
|
+
const inline = token.startsWith("--task=") ? token.slice("--task=".length) : undefined;
|
|
19241
|
+
if (token !== "--task" && inline === undefined)
|
|
19216
19242
|
return parseUsage(`unknown argument: ${token}`, json);
|
|
19217
|
-
|
|
19243
|
+
const value = inline ?? argv[i + 1];
|
|
19244
|
+
if (taskId !== undefined || value === undefined || value.trim() === "")
|
|
19218
19245
|
return parseUsage("--task requires one non-empty value", json);
|
|
19219
|
-
if (seen.has(
|
|
19220
|
-
return parseUsage(
|
|
19221
|
-
seen.add(
|
|
19222
|
-
taskId =
|
|
19246
|
+
if (seen.has("--task"))
|
|
19247
|
+
return parseUsage("duplicate argument: --task", json);
|
|
19248
|
+
seen.add("--task");
|
|
19249
|
+
taskId = value;
|
|
19250
|
+
if (inline === undefined)
|
|
19251
|
+
i += 1;
|
|
19223
19252
|
}
|
|
19224
19253
|
if (!taskId)
|
|
19225
19254
|
return parseUsage("handoff requires --task <id>", json);
|
|
@@ -19406,13 +19435,14 @@ var init_task = __esm(() => {
|
|
|
19406
19435
|
|
|
19407
19436
|
// packages/workit-cli/src/verbs/task.ts
|
|
19408
19437
|
function isImplicitTaskForm(argv) {
|
|
19409
|
-
const [action,
|
|
19438
|
+
const [action, ...rest] = argv;
|
|
19410
19439
|
if (!action)
|
|
19411
19440
|
return false;
|
|
19412
19441
|
if (IMPLICIT2.has(action))
|
|
19413
19442
|
return true;
|
|
19443
|
+
const first = rest.find((arg) => arg !== "--json");
|
|
19414
19444
|
if (action === "start")
|
|
19415
|
-
return first !== undefined && !first.startsWith("--");
|
|
19445
|
+
return first !== undefined && (first === "--" || !first.startsWith("--"));
|
|
19416
19446
|
if (action === "close")
|
|
19417
19447
|
return !argv.includes("--task") && !argv.includes("--payload");
|
|
19418
19448
|
return false;
|
|
@@ -19421,6 +19451,10 @@ function parse4(argv) {
|
|
|
19421
19451
|
const flags = { positionals: [], values: new Map, switches: new Set };
|
|
19422
19452
|
for (let index = 0;index < argv.length; index += 1) {
|
|
19423
19453
|
const arg = argv[index];
|
|
19454
|
+
if (arg === "--") {
|
|
19455
|
+
flags.positionals.push(...argv.slice(index + 1));
|
|
19456
|
+
break;
|
|
19457
|
+
}
|
|
19424
19458
|
const [flag, inline] = arg.startsWith("--") && arg.includes("=") ? arg.split(/=(.*)/su) : [arg];
|
|
19425
19459
|
if (SWITCHES.has(flag)) {
|
|
19426
19460
|
flags.switches.add(flag);
|
|
@@ -34280,7 +34314,7 @@ function getSgrPrefix(code) {
|
|
|
34280
34314
|
if (code.startsWith("")) {
|
|
34281
34315
|
return "";
|
|
34282
34316
|
}
|
|
34283
|
-
return `${
|
|
34317
|
+
return `${ESCAPE2}${ANSI_CSI2}`;
|
|
34284
34318
|
}
|
|
34285
34319
|
function createSgrCode(prefix, values) {
|
|
34286
34320
|
return `${prefix}${values.join(";")}${ANSI_SGR_TERMINATOR2}`;
|
|
@@ -34289,7 +34323,7 @@ function getSgrFragments(code) {
|
|
|
34289
34323
|
const fragments = [];
|
|
34290
34324
|
const sgrPrefix = getSgrPrefix(code);
|
|
34291
34325
|
let parameterString;
|
|
34292
|
-
if (code.startsWith(`${
|
|
34326
|
+
if (code.startsWith(`${ESCAPE2}${ANSI_CSI2}`)) {
|
|
34293
34327
|
parameterString = code.slice(2, -1);
|
|
34294
34328
|
} else if (code.startsWith("")) {
|
|
34295
34329
|
parameterString = code.slice(1, -1);
|
|
@@ -34450,7 +34484,7 @@ function parseHyperlinkCode(string, index) {
|
|
|
34450
34484
|
endIndex: sequenceIndex + 1
|
|
34451
34485
|
};
|
|
34452
34486
|
}
|
|
34453
|
-
if (character ===
|
|
34487
|
+
if (character === ESCAPE2 && string[sequenceIndex + 1] === ANSI_OSC_TERMINATOR) {
|
|
34454
34488
|
const code = string.slice(index, sequenceIndex + 2);
|
|
34455
34489
|
const action = sequenceIndex === uriStart + 1 ? "close" : "open";
|
|
34456
34490
|
return {
|
|
@@ -34533,7 +34567,7 @@ function parseControlStringCode(string, index) {
|
|
|
34533
34567
|
if (supportsBellTerminator && string[sequenceIndex] === ANSI_BELL) {
|
|
34534
34568
|
return createControlParseResult(string.slice(index, sequenceIndex + 1), sequenceIndex + 1);
|
|
34535
34569
|
}
|
|
34536
|
-
if (string[sequenceIndex] ===
|
|
34570
|
+
if (string[sequenceIndex] === ESCAPE2 && string[sequenceIndex + 1] === ANSI_OSC_TERMINATOR) {
|
|
34537
34571
|
return createControlParseResult(string.slice(index, sequenceIndex + 2), sequenceIndex + 2);
|
|
34538
34572
|
}
|
|
34539
34573
|
if (string[sequenceIndex] === C1_STRING_TERMINATOR) {
|
|
@@ -34758,7 +34792,7 @@ function tokenizeAnsi(string, { endCharacter = Number.POSITIVE_INFINITY } = {})
|
|
|
34758
34792
|
}
|
|
34759
34793
|
return tokens;
|
|
34760
34794
|
}
|
|
34761
|
-
var ESCAPE_CODE_POINT = 27, C1_DCS_CODE_POINT = 144, C1_SOS_CODE_POINT = 152, C1_CSI_CODE_POINT = 155, C1_ST_CODE_POINT = 156, C1_OSC_CODE_POINT = 157, C1_PM_CODE_POINT = 158, C1_APC_CODE_POINT = 159, ESCAPES2,
|
|
34795
|
+
var ESCAPE_CODE_POINT = 27, C1_DCS_CODE_POINT = 144, C1_SOS_CODE_POINT = 152, C1_CSI_CODE_POINT = 155, C1_ST_CODE_POINT = 156, C1_OSC_CODE_POINT = 157, C1_PM_CODE_POINT = 158, C1_APC_CODE_POINT = 159, ESCAPES2, ESCAPE2 = "\x1B", ANSI_BELL = "\x07", ANSI_CSI2 = "[", ANSI_OSC2 = "]", ANSI_DCS = "P", ANSI_SOS = "X", ANSI_PM = "^", ANSI_APC = "_", ANSI_SGR_TERMINATOR2 = "m", ANSI_OSC_TERMINATOR = "\\", ANSI_STRING_TERMINATOR, C1_OSC = "", C1_STRING_TERMINATOR = "", ANSI_HYPERLINK_ESC_PREFIX, ANSI_HYPERLINK_C1_PREFIX, ANSI_HYPERLINK_ESC_CLOSE, ANSI_HYPERLINK_C1_CLOSE, CODE_POINT_0, CODE_POINT_9, CODE_POINT_SEMICOLON, CODE_POINT_COLON, CODE_POINT_CSI_PARAMETER_START, CODE_POINT_CSI_PARAMETER_END, CODE_POINT_CSI_INTERMEDIATE_START, CODE_POINT_CSI_INTERMEDIATE_END, CODE_POINT_CSI_FINAL_START, CODE_POINT_CSI_FINAL_END, REGIONAL_INDICATOR_SYMBOL_LETTER_A = 127462, REGIONAL_INDICATOR_SYMBOL_LETTER_Z = 127487, SGR_RESET_CODE = 0, SGR_EXTENDED_FOREGROUND_CODE = 38, SGR_DEFAULT_FOREGROUND_CODE = 39, SGR_EXTENDED_BACKGROUND_CODE = 48, SGR_DEFAULT_BACKGROUND_CODE = 49, SGR_COLOR_TYPE_ANSI_256 = 5, SGR_COLOR_TYPE_TRUECOLOR = 2, SGR_ANSI_256_FRAGMENT_LENGTH = 3, SGR_TRUECOLOR_FRAGMENT_LENGTH = 5, SGR_ANSI_256_LAST_PARAMETER_OFFSET = 2, SGR_TRUECOLOR_LAST_PARAMETER_OFFSET = 4, VARIATION_SELECTOR_16_CODE_POINT = 65039, COMBINING_ENCLOSING_KEYCAP_CODE_POINT = 8419, EMOJI_PRESENTATION_GRAPHEME_REGEX, GRAPHEME_SEGMENTER, endCodeNumbers;
|
|
34762
34796
|
var init_tokenize_ansi = __esm(() => {
|
|
34763
34797
|
init_ansi_styles();
|
|
34764
34798
|
init_is_fullwidth_code_point();
|
|
@@ -34772,8 +34806,8 @@ var init_tokenize_ansi = __esm(() => {
|
|
|
34772
34806
|
C1_PM_CODE_POINT,
|
|
34773
34807
|
C1_APC_CODE_POINT
|
|
34774
34808
|
]);
|
|
34775
|
-
ANSI_STRING_TERMINATOR = `${
|
|
34776
|
-
ANSI_HYPERLINK_ESC_PREFIX = `${
|
|
34809
|
+
ANSI_STRING_TERMINATOR = `${ESCAPE2}${ANSI_OSC_TERMINATOR}`;
|
|
34810
|
+
ANSI_HYPERLINK_ESC_PREFIX = `${ESCAPE2}${ANSI_OSC2}8;`;
|
|
34777
34811
|
ANSI_HYPERLINK_C1_PREFIX = `${C1_OSC}8;`;
|
|
34778
34812
|
ANSI_HYPERLINK_ESC_CLOSE = `${ANSI_HYPERLINK_ESC_PREFIX};`;
|
|
34779
34813
|
ANSI_HYPERLINK_C1_CLOSE = `${ANSI_HYPERLINK_C1_PREFIX};`;
|
|
@@ -71015,18 +71049,14 @@ async function change(verb, argv, io, deps) {
|
|
|
71015
71049
|
]);
|
|
71016
71050
|
}
|
|
71017
71051
|
async function runGrant(argv, io, deps = defaultDeps) {
|
|
71018
|
-
const
|
|
71052
|
+
const end = argv.indexOf("--");
|
|
71053
|
+
const [sub, ...rest] = end < 0 ? argv : [...argv.slice(0, end), ...argv.slice(end + 1)];
|
|
71019
71054
|
if (sub === "show")
|
|
71020
71055
|
return show(rest, io);
|
|
71021
|
-
if (sub === undefined || sub.startsWith("--")
|
|
71056
|
+
if (sub === undefined || sub.startsWith("--"))
|
|
71022
71057
|
return show(argv, io);
|
|
71023
71058
|
if (sub === "set" || sub === "unset")
|
|
71024
71059
|
return change(sub, rest, io, deps);
|
|
71025
|
-
if (sub === "--help" || sub === "-h") {
|
|
71026
|
-
io.stdout(`usage: ${USAGE2}
|
|
71027
|
-
`);
|
|
71028
|
-
return 0;
|
|
71029
|
-
}
|
|
71030
71060
|
return usage2(io, `unknown subcommand "${sub}"`);
|
|
71031
71061
|
}
|
|
71032
71062
|
var USAGE2 = "workit grant show [<workspace>] [--all] | grant set <workspace> <kind>=<true|false|verified>… [defaultEndpoint=commit|pr|green|merged] [verification=self|independent] | grant unset <workspace> <kind>… (kinds: push, pr, merge, release, rerun, defaultEndpoint, verification)", AGENT_ENV, agentMarker = (env) => AGENT_ENV.find((name) => env[name]) ?? Object.keys(env).find((name) => name.startsWith("CODEX_") && env[name]), defaultDeps, parseValue = (raw) => raw === "true" || raw === "yes" || raw === "on" ? true : raw === "false" || raw === "no" || raw === "off" ? false : raw === "verified" ? "verified" : null, STOPS_AT, endpointLabel = (view) => view.effectiveEndpoint === view.defaultEndpoint ? view.defaultEndpoint : `${view.defaultEndpoint} (effective: ${view.effectiveEndpoint}${view.endpointReason ? `, ${view.endpointReason}` : ""})`, describe2 = (grants, configured, endpoint, verification) => [
|
|
@@ -72339,13 +72369,19 @@ async function createPullRequest(cwd, resolved, input, sleep) {
|
|
|
72339
72369
|
head: sha,
|
|
72340
72370
|
created,
|
|
72341
72371
|
draft: input.draft,
|
|
72342
|
-
recorded: row.ok ? { id: String(row.value.id) } : { error: row.error }
|
|
72372
|
+
recorded: row.ok ? { id: String(row.value.id) } : { error: row.error },
|
|
72373
|
+
next: createNext(cwd)
|
|
72343
72374
|
});
|
|
72344
72375
|
}
|
|
72345
72376
|
async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
72346
72377
|
const grant = requireGrant(cwd, "merge");
|
|
72347
72378
|
if (!grant.allowed)
|
|
72348
72379
|
return refuse(grant.error, grant.unblock, { reason: "grant_required" });
|
|
72380
|
+
const bypass = input.unverified ?? null;
|
|
72381
|
+
if (bypass && !bypass.reason.trim())
|
|
72382
|
+
return failure3("invalid_input", "--unverified needs --reason <why the user asked for it>");
|
|
72383
|
+
if (bypass && !grant.allowUnverified)
|
|
72384
|
+
return refuse(`unverified_refused: workspace ${grant.workspace ? `"${grant.workspace}"` : "(none)"} grants merge: "verified", which never merges without an accepted independent verdict`, "a non-author session verifies the head (workit-review), then merge without --unverified", { reason: "unverified_refused" });
|
|
72349
72385
|
const number = selectPr(cwd, resolved, { pr: input.pr });
|
|
72350
72386
|
if (!number.ok)
|
|
72351
72387
|
return number;
|
|
@@ -72379,27 +72415,40 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
72379
72415
|
if (reason)
|
|
72380
72416
|
return refuse(`protected_branch: --delete-branch would delete ${branch}, which ${reason}; workit never deletes it`, `workit pr merge${input.pr ? ` --pr ${doc.number}` : ""} --method ${input.method} # without --delete-branch`, { reason: "protected_branch" });
|
|
72381
72417
|
}
|
|
72418
|
+
const ledger = readLedger(cwd);
|
|
72419
|
+
if (!ledger.ok)
|
|
72420
|
+
return ledger;
|
|
72421
|
+
const check = checkVerdicts(cwd, branch, ledger.value.rows);
|
|
72422
|
+
const summary = { head: check.head, accepted: check.accepted, authors: check.authors };
|
|
72423
|
+
const covered = check.head === head && check.accepted.accepted;
|
|
72382
72424
|
let verdict = {
|
|
72383
|
-
required:
|
|
72384
|
-
accepted:
|
|
72385
|
-
verdictId: null
|
|
72425
|
+
required: true,
|
|
72426
|
+
accepted: covered,
|
|
72427
|
+
verdictId: covered && typeof check.accepted.verdict?.id === "string" ? check.accepted.verdict.id : null
|
|
72386
72428
|
};
|
|
72387
|
-
|
|
72388
|
-
|
|
72389
|
-
|
|
72390
|
-
|
|
72391
|
-
const
|
|
72392
|
-
const
|
|
72393
|
-
|
|
72394
|
-
|
|
72395
|
-
|
|
72396
|
-
|
|
72397
|
-
|
|
72398
|
-
|
|
72399
|
-
|
|
72400
|
-
|
|
72401
|
-
};
|
|
72402
|
-
|
|
72429
|
+
let unverified = null;
|
|
72430
|
+
if (!covered && bypass && check.accepted.reasons.includes("failing_verdict"))
|
|
72431
|
+
return refuse(`failed_verdict: ${label} has a current independent failed verdict${typeof check.accepted.verdict?.id === "string" ? ` (${check.accepted.verdict.id})` : ""}; --unverified never merges over a rejection`, "a new independent verdict on the head supersedes it", { reason: "failed_verdict", verdict: summary });
|
|
72432
|
+
if (!covered && bypass) {
|
|
72433
|
+
const reason = bypass.reason.trim();
|
|
72434
|
+
const recorded = appendObserved(cwd, {
|
|
72435
|
+
type: "merge.unverified",
|
|
72436
|
+
actor: input.actor,
|
|
72437
|
+
branch,
|
|
72438
|
+
head,
|
|
72439
|
+
pr: doc.number,
|
|
72440
|
+
base: doc.base,
|
|
72441
|
+
reason,
|
|
72442
|
+
grant: grant.source
|
|
72443
|
+
});
|
|
72444
|
+
if (!recorded.ok)
|
|
72445
|
+
return failure3("failed", `unverified_unrecorded: the --unverified bypass could not be recorded (${recorded.error}); nothing was merged`);
|
|
72446
|
+
verdict = { required: false, accepted: false, verdictId: null };
|
|
72447
|
+
unverified = { reason, recorded: String(recorded.value.id) };
|
|
72448
|
+
} else if (check.head !== head)
|
|
72449
|
+
return refuse(`head_mismatch: the verdict check reads ${branch} at ${check.head?.slice(0, 12) ?? "(missing)"} but ${label} is at ${head.slice(0, 12)}`, `git fetch && git switch ${branch} && git merge --ff-only @{u} # then re-verify that head`, { reason: "head_mismatch", verdict: summary });
|
|
72450
|
+
else if (!covered)
|
|
72451
|
+
return refuse(`NEEDS_VERDICT: ${label} has no accepted independent verdict for ${head.slice(0, 12)} (${check.accepted.reasons.join(", ")})`, `an independent session verifies the head and runs: workit ledger verdict verified --how "<what was exercised>" --branch ${branch}${grant.allowUnverified ? `; or, only if the user asks to merge unverified: workit pr merge --unverified --reason "<why>"` : ""}`, { reason: "needs_verdict", verdict: summary });
|
|
72403
72452
|
const merged = resolved.forge.merge(doc.number, { sha: head, method: input.method });
|
|
72404
72453
|
if (!merged.ok)
|
|
72405
72454
|
return merged;
|
|
@@ -72437,6 +72486,7 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
72437
72486
|
mergeSha: merged.data.mergeSha,
|
|
72438
72487
|
method: input.method,
|
|
72439
72488
|
verdictId: verdict.verdictId,
|
|
72489
|
+
...unverified ? { unverified: unverified.recorded } : {},
|
|
72440
72490
|
grant: grant.source
|
|
72441
72491
|
});
|
|
72442
72492
|
return {
|
|
@@ -72450,6 +72500,7 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
72450
72500
|
method: input.method,
|
|
72451
72501
|
mergeSha: merged.data.mergeSha,
|
|
72452
72502
|
verdict,
|
|
72503
|
+
unverified,
|
|
72453
72504
|
grant: { source: grant.source },
|
|
72454
72505
|
deletedBranch,
|
|
72455
72506
|
recorded: row.ok ? { id: String(row.value.id) } : { error: row.error },
|
|
@@ -72458,7 +72509,10 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
72458
72509
|
}
|
|
72459
72510
|
};
|
|
72460
72511
|
}
|
|
72461
|
-
var VERIFY_DELAYS_MS, noun = (resolved) => resolved.forge.kind === "github" ? "pull request" : "merge request", grantBlocked = (decision) => failure3("blocked", decision.error, decision.unblock),
|
|
72512
|
+
var VERIFY_DELAYS_MS, noun = (resolved) => resolved.forge.kind === "github" ? "pull request" : "merge request", grantBlocked = (decision) => failure3("blocked", decision.error, decision.unblock), AFTER_REVIEW, createNext = (cwd) => {
|
|
72513
|
+
const endpoint = resolveAutonomy(cwd).effectiveEndpoint;
|
|
72514
|
+
return `a non-author verifies the head (workit-review); the endpoint is ${endpoint}, so ${AFTER_REVIEW[endpoint]}`;
|
|
72515
|
+
}, mergeBackFor = (cwd, base) => {
|
|
72462
72516
|
try {
|
|
72463
72517
|
const owners = workspaceReleaseTracks(cwd).tracks.filter((track) => track.productionBranch === base);
|
|
72464
72518
|
if (owners.length !== 1)
|
|
@@ -72487,6 +72541,12 @@ var init_pr_ops = __esm(() => {
|
|
|
72487
72541
|
init_ledger();
|
|
72488
72542
|
init_report();
|
|
72489
72543
|
VERIFY_DELAYS_MS = [1000, 2000, 4000];
|
|
72544
|
+
AFTER_REVIEW = {
|
|
72545
|
+
commit: "stop here; review comes when the user asks",
|
|
72546
|
+
pr: "stop here; review comes when the user asks",
|
|
72547
|
+
green: "babysit it to merge-ready, never merging",
|
|
72548
|
+
merged: "babysit it, then land it after verification"
|
|
72549
|
+
};
|
|
72490
72550
|
NEXT_HINTS = {
|
|
72491
72551
|
RESOLVE_CONFLICTS: "rebase onto the base, resolve, then workit git push --force-with-lease",
|
|
72492
72552
|
REBASE: "rebase onto the base, then workit git push --force-with-lease",
|
|
@@ -73358,6 +73418,10 @@ function parseFlags(argv, spec) {
|
|
|
73358
73418
|
const parsed = { values: {}, booleans: new Set, lists: {}, positionals: [] };
|
|
73359
73419
|
for (let index = 0;index < argv.length; index += 1) {
|
|
73360
73420
|
const arg = argv[index];
|
|
73421
|
+
if (arg === "--") {
|
|
73422
|
+
parsed.positionals.push(...argv.slice(index + 1));
|
|
73423
|
+
break;
|
|
73424
|
+
}
|
|
73361
73425
|
if (arg === "--json")
|
|
73362
73426
|
continue;
|
|
73363
73427
|
if (!arg.startsWith("--")) {
|
|
@@ -73385,6 +73449,14 @@ function parseFlags(argv, spec) {
|
|
|
73385
73449
|
}
|
|
73386
73450
|
return parsed;
|
|
73387
73451
|
}
|
|
73452
|
+
function unverifiedFlag(flags) {
|
|
73453
|
+
const reason = flags.values.reason?.trim();
|
|
73454
|
+
if (!flags.booleans.has("unverified"))
|
|
73455
|
+
return reason === undefined ? null : "--reason is only used with --unverified";
|
|
73456
|
+
if (!reason)
|
|
73457
|
+
return "--unverified needs --reason <why the user asked for it>";
|
|
73458
|
+
return reason.length > MAX_REASON ? `--reason is capped at ${MAX_REASON} characters` : { reason };
|
|
73459
|
+
}
|
|
73388
73460
|
function positiveInt(value, flag) {
|
|
73389
73461
|
if (value === undefined)
|
|
73390
73462
|
return null;
|
|
@@ -73468,7 +73540,7 @@ function renderStatus(doc) {
|
|
|
73468
73540
|
lines.push(`next: ${doc.next}`);
|
|
73469
73541
|
return lines;
|
|
73470
73542
|
}
|
|
73471
|
-
var forgeDeps, usage3 = (io, message, line) => emit(io, fail("invalid_input", message, { unblock: line })), forgeFail = (io, result, data) => emit(io, fail(result.code, result.error, { data, unblock: result.unblock })), short = (sha) => sha ? sha.slice(0, 7) : "?";
|
|
73543
|
+
var forgeDeps, MAX_REASON = 500, usage3 = (io, message, line) => emit(io, fail("invalid_input", message, { unblock: line })), forgeFail = (io, result, data) => emit(io, fail(result.code, result.error, { data, unblock: result.unblock })), short = (sha) => sha ? sha.slice(0, 7) : "?";
|
|
73472
73544
|
var init_forge_common = __esm(() => {
|
|
73473
73545
|
init_resolve();
|
|
73474
73546
|
init_vcs_config();
|
|
@@ -73614,13 +73686,23 @@ async function create4(argv, io) {
|
|
|
73614
73686
|
...data.releaseTrack?.name ? [`release track: ${data.releaseTrack.name} (${data.releaseTrack.detail})`] : [],
|
|
73615
73687
|
...(data.releaseTrack?.warnings ?? []).map((warning) => `note: ${warning}`),
|
|
73616
73688
|
`head ${data.head.slice(0, 12)} verified on the forge`,
|
|
73617
|
-
..."error" in data.recorded ? [`ledger: not recorded (${data.recorded.error})`] : []
|
|
73689
|
+
..."error" in data.recorded ? [`ledger: not recorded (${data.recorded.error})`] : [],
|
|
73690
|
+
`next: ${data.next}`
|
|
73618
73691
|
]);
|
|
73619
73692
|
}
|
|
73620
73693
|
async function merge3(argv, io) {
|
|
73621
|
-
const flags = parseFlags(argv, {
|
|
73694
|
+
const flags = parseFlags(argv, {
|
|
73695
|
+
pr: "value",
|
|
73696
|
+
method: "value",
|
|
73697
|
+
"delete-branch": "boolean",
|
|
73698
|
+
unverified: "boolean",
|
|
73699
|
+
reason: "value"
|
|
73700
|
+
});
|
|
73622
73701
|
if (typeof flags === "string")
|
|
73623
73702
|
return usage3(io, flags, MERGE_USAGE);
|
|
73703
|
+
const unverified = unverifiedFlag(flags);
|
|
73704
|
+
if (typeof unverified === "string")
|
|
73705
|
+
return usage3(io, unverified, MERGE_USAGE);
|
|
73624
73706
|
if (flags.positionals.length)
|
|
73625
73707
|
return usage3(io, `unexpected argument ${flags.positionals[0]}`, MERGE_USAGE);
|
|
73626
73708
|
const pr = positiveInt(flags.values.pr, "--pr");
|
|
@@ -73632,7 +73714,13 @@ async function merge3(argv, io) {
|
|
|
73632
73714
|
const connected = connect(io);
|
|
73633
73715
|
if (!connected.ok)
|
|
73634
73716
|
return forgeFail(io, connected);
|
|
73635
|
-
const result = await mergePullRequest(io.cwd, connected.data, {
|
|
73717
|
+
const result = await mergePullRequest(io.cwd, connected.data, {
|
|
73718
|
+
pr,
|
|
73719
|
+
method,
|
|
73720
|
+
deleteBranch: flags.booleans.has("delete-branch"),
|
|
73721
|
+
actor: actorFromEnv(io.env),
|
|
73722
|
+
...unverified ? { unverified } : {}
|
|
73723
|
+
}, forgeDeps.sleep);
|
|
73636
73724
|
if (!result.ok)
|
|
73637
73725
|
return emit(io, fail(result.code, result.error, {
|
|
73638
73726
|
unblock: result.unblock,
|
|
@@ -73640,7 +73728,7 @@ async function merge3(argv, io) {
|
|
|
73640
73728
|
}));
|
|
73641
73729
|
return emit(io, ok(result.data), (data) => [
|
|
73642
73730
|
`merged ${connected.data.forge.kind === "github" ? "PR #" : "MR !"}${data.number} (${data.method}) at head ${data.head.slice(0, 12)}${data.mergeSha ? ` -> ${data.mergeSha.slice(0, 12)}` : ""}`,
|
|
73643
|
-
data.verdict.
|
|
73731
|
+
data.unverified ? `UNVERIFIED: merged without a verdict (--unverified: ${data.unverified.reason}); ledger ${data.unverified.recorded}` : `verdict ${data.verdict.verdictId ?? "?"} accepted for that head`,
|
|
73644
73732
|
...data.mergeBack.length ? [
|
|
73645
73733
|
`merge back: ${data.base} is the ${data.mergeBackTrack} production branch; bring it into ${data.mergeBack.join(", ")}`
|
|
73646
73734
|
] : [],
|
|
@@ -73658,7 +73746,7 @@ async function run10(argv, io) {
|
|
|
73658
73746
|
return merge3(rest, io);
|
|
73659
73747
|
return usage3(io, sub && !sub.startsWith("-") ? `unknown pr subcommand "${sub}"` : "missing pr subcommand", USAGE4);
|
|
73660
73748
|
}
|
|
73661
|
-
var STATUS_USAGE = "workit pr status [--pr <n> | --branch <b>] [--log-lines 60] [--json]", CREATE_USAGE = "workit pr create [--base <b> | --track <t>] (--title <t> [--body <text> | --body-file <f>] | --fill) [--draft] [--json]", MERGE_USAGE = "workit pr merge [--pr <n>] [--method squash|merge|rebase] [--delete-branch] [--json]", USAGE4 = "workit pr status|create|merge ... (workit help pr)", METHODS2;
|
|
73749
|
+
var STATUS_USAGE = "workit pr status [--pr <n> | --branch <b>] [--log-lines 60] [--json]", CREATE_USAGE = "workit pr create [--base <b> | --track <t>] (--title <t> [--body <text> | --body-file <f>] | --fill) [--draft] [--json]", MERGE_USAGE = "workit pr merge [--pr <n>] [--method squash|merge|rebase] [--delete-branch] [--unverified --reason <why>] [--json]", USAGE4 = "workit pr status|create|merge ... (workit help pr)", METHODS2;
|
|
73662
73750
|
var init_pr = __esm(() => {
|
|
73663
73751
|
init_pr_body();
|
|
73664
73752
|
init_pr_ops();
|
|
@@ -74945,7 +75033,7 @@ function repoMismatch(ctx, stack) {
|
|
|
74945
75033
|
return stackFail("blocked", `repo_mismatch: stack ${stack.name} was planned on ${stack.forge ?? "?"} ${stack.repo ?? "?"}, but this checkout resolves to ${kind} ${repo}`, `workit stack plan --name ${stack.name} <branch…> # re-plan it here, or run from the right checkout`, { planned: { forge: stack.forge, repo: stack.repo }, resolved: { forge: kind, repo } });
|
|
74946
75034
|
return null;
|
|
74947
75035
|
}
|
|
74948
|
-
function qualify(ctx, stack, entry, doc, verdict, grant, binding = null) {
|
|
75036
|
+
function qualify(ctx, stack, entry, doc, verdict, grant, binding = null, bypass = false) {
|
|
74949
75037
|
const label = entry.pr ? noun2(ctx.resolved, entry.pr) : entry.branch;
|
|
74950
75038
|
const stop = (reason, detail, unblock, ready = false) => ({
|
|
74951
75039
|
ok: false,
|
|
@@ -74964,9 +75052,11 @@ function qualify(ctx, stack, entry, doc, verdict, grant, binding = null) {
|
|
|
74964
75052
|
return stop("base_not_trunk", `${label} targets ${doc.base}, not ${stack.trunk}`, "workit stack sync");
|
|
74965
75053
|
if (doc.next !== "READY")
|
|
74966
75054
|
return stop("not_ready", `${label} is ${doc.next}${doc.blockers.length ? ` (${doc.blockers.join(", ")})` : ""}`, doc.next === "WAITING_CI" ? `workit ci wait --pr ${entry.pr}` : `workit pr status --pr ${entry.pr}`);
|
|
74967
|
-
const
|
|
74968
|
-
if (
|
|
74969
|
-
return stop(
|
|
75055
|
+
const allowUnverified = grant.allowed && grant.allowUnverified;
|
|
75056
|
+
if (bypass && allowUnverified && verdict.reasons.includes("failing_verdict"))
|
|
75057
|
+
return stop("failed_verdict", `${label} has a current independent failed verdict for ${doc.head.sha.slice(0, 12)}; --unverified never lands over a rejection`, "a new independent verdict on the head supersedes it");
|
|
75058
|
+
if (!(bypass && allowUnverified) && !verdict.accepted)
|
|
75059
|
+
return stop(verdict.reasons.includes("no_verdict") ? "no_verdict" : "needs_verdict", `${label} has no accepted independent verdict for ${doc.head.sha.slice(0, 12)} (${verdict.reasons.join(", ") || "none"})`, `an independent session verifies ${entry.branch} and runs: workit ledger verdict verified --how "<what was exercised>" --branch ${entry.branch}${allowUnverified ? `; or, only if the user asks to land unverified: workit stack land --unverified --reason "<why>"` : ""}`);
|
|
74970
75060
|
if (!grant.allowed)
|
|
74971
75061
|
return stop("grant_required", `${label} is verified and ready, but ${grant.error}`, grant.unblock, true);
|
|
74972
75062
|
return { ok: true };
|
|
@@ -75384,6 +75474,14 @@ async function landStack(ctx, stack, options) {
|
|
|
75384
75474
|
const mismatch = repoMismatch(ctx, stack);
|
|
75385
75475
|
if (mismatch)
|
|
75386
75476
|
return failWith(mismatch);
|
|
75477
|
+
const bypass = options.unverified ?? null;
|
|
75478
|
+
if (bypass) {
|
|
75479
|
+
const grant = requireGrant(ctx.cwd, "merge");
|
|
75480
|
+
if (!grant.allowed)
|
|
75481
|
+
return failWith(stackFail("blocked", grant.error, grant.unblock, { reason: "grant_required" }));
|
|
75482
|
+
if (!grant.allowUnverified)
|
|
75483
|
+
return failWith(stackFail("blocked", `unverified_refused: workspace ${grant.workspace ? `"${grant.workspace}"` : "(none)"} grants merge: "verified", which never lands without an accepted independent verdict`, "a non-author session verifies each head (workit-review), then land without --unverified", { reason: "unverified_refused" }));
|
|
75484
|
+
}
|
|
75387
75485
|
if (!options.dryRun) {
|
|
75388
75486
|
const synced = syncStack(ctx.cwd, ctx, stack, { publish: true, dryRun: false, limit: 1 }, ctx.actor);
|
|
75389
75487
|
if (!synced.ok)
|
|
@@ -75429,7 +75527,7 @@ async function landStack(ctx, stack, options) {
|
|
|
75429
75527
|
const grant = requireGrant(ctx.cwd, "merge");
|
|
75430
75528
|
const verdict = verdictOf(ctx.cwd, entry.branch, ledgerRows());
|
|
75431
75529
|
const effective = options.dryRun && simulated.size > 0 && doc ? { ...doc, base: stack.trunk } : doc;
|
|
75432
|
-
const q = qualify(ctx, stack, entry, effective, verdict, grant, doc ? prBinding(ctx, entry, doc) : null);
|
|
75530
|
+
const q = qualify(ctx, stack, entry, effective, verdict, grant, doc ? prBinding(ctx, entry, doc) : null, bypass !== null);
|
|
75433
75531
|
if (!q.ok) {
|
|
75434
75532
|
outcome.stoppedAt = {
|
|
75435
75533
|
pr: entry.pr,
|
|
@@ -75452,7 +75550,8 @@ async function landStack(ctx, stack, options) {
|
|
|
75452
75550
|
method: options.method,
|
|
75453
75551
|
deleteBranch: false,
|
|
75454
75552
|
actor: ctx.actor,
|
|
75455
|
-
expect: { base: stack.trunk, branch: entry.branch }
|
|
75553
|
+
expect: { base: stack.trunk, branch: entry.branch },
|
|
75554
|
+
...bypass && !verdict.accepted ? { unverified: bypass } : {}
|
|
75456
75555
|
}, ctx.sleep);
|
|
75457
75556
|
if (!merged.ok) {
|
|
75458
75557
|
if (merged.code === "blocked" && "refusal" in merged && merged.refusal) {
|
|
@@ -75468,7 +75567,12 @@ async function landStack(ctx, stack, options) {
|
|
|
75468
75567
|
}
|
|
75469
75568
|
return failWith(stackFail(merged.code, merged.error, merged.unblock));
|
|
75470
75569
|
}
|
|
75471
|
-
outcome.landed.push({
|
|
75570
|
+
outcome.landed.push({
|
|
75571
|
+
pr,
|
|
75572
|
+
branch: entry.branch,
|
|
75573
|
+
mergeSha: merged.data.mergeSha,
|
|
75574
|
+
unverified: merged.data.unverified?.recorded ?? null
|
|
75575
|
+
});
|
|
75472
75576
|
entry.merged = { pr, mergeSha: merged.data.mergeSha, at: new Date().toISOString() };
|
|
75473
75577
|
const written = writeStack(ctx.cwd, stack);
|
|
75474
75578
|
if (!written.ok)
|
|
@@ -75701,10 +75805,15 @@ async function land(argv, io) {
|
|
|
75701
75805
|
max: "value",
|
|
75702
75806
|
method: "value",
|
|
75703
75807
|
timeout: "value",
|
|
75704
|
-
interval: "value"
|
|
75808
|
+
interval: "value",
|
|
75809
|
+
unverified: "boolean",
|
|
75810
|
+
reason: "value"
|
|
75705
75811
|
});
|
|
75706
75812
|
if (typeof flags === "string")
|
|
75707
75813
|
return usage3(io, flags, LAND_USAGE);
|
|
75814
|
+
const unverified = unverifiedFlag(flags);
|
|
75815
|
+
if (typeof unverified === "string")
|
|
75816
|
+
return usage3(io, unverified, LAND_USAGE);
|
|
75708
75817
|
if (flags.positionals.length)
|
|
75709
75818
|
return usage3(io, `unexpected argument ${flags.positionals[0]}`, LAND_USAGE);
|
|
75710
75819
|
const max = positiveInt(flags.values.max, "--max");
|
|
@@ -75735,7 +75844,7 @@ async function land(argv, io) {
|
|
|
75735
75844
|
resolved: connected.data,
|
|
75736
75845
|
actor: actorFromEnv(io.env),
|
|
75737
75846
|
sleep: forgeDeps.sleep
|
|
75738
|
-
}, fresh.data ?? selected.data, { dryRun: flags.booleans.has("dry-run"), max, method, timeoutMs, intervalMs });
|
|
75847
|
+
}, fresh.data ?? selected.data, { dryRun: flags.booleans.has("dry-run"), max, method, timeoutMs, intervalMs, unverified });
|
|
75739
75848
|
});
|
|
75740
75849
|
if (!result.ok)
|
|
75741
75850
|
return stackFailed(io, result);
|
|
@@ -75744,7 +75853,7 @@ async function land(argv, io) {
|
|
|
75744
75853
|
...data.dryRun ? [
|
|
75745
75854
|
data.wouldLand.length ? `would land: ${data.wouldLand.map((item) => `${label(kind, item.pr)} (${item.branch})`).join(", ")}` : "would land nothing"
|
|
75746
75855
|
] : [
|
|
75747
|
-
data.landed.length ? `landed: ${data.landed.map((item) => `${label(kind, item.pr)} (${item.branch}) -> ${short4(item.mergeSha)}`).join(", ")}` : "landed nothing"
|
|
75856
|
+
data.landed.length ? `landed: ${data.landed.map((item) => `${label(kind, item.pr)} (${item.branch}) -> ${short4(item.mergeSha)}${item.unverified ? ` UNVERIFIED (ledger ${item.unverified})` : ""}`).join(", ")}` : "landed nothing"
|
|
75748
75857
|
],
|
|
75749
75858
|
...data.retargeted.length ? [`retargeted: ${data.retargeted.map((pr) => label(kind, pr)).join(", ")}`] : [],
|
|
75750
75859
|
...data.restacked.length ? [`restacked: ${data.restacked.join(", ")}`] : [],
|
|
@@ -75764,7 +75873,7 @@ async function run14(argv, io) {
|
|
|
75764
75873
|
return land(rest, io);
|
|
75765
75874
|
return usage3(io, sub && !sub.startsWith("-") ? `unknown stack subcommand "${sub}"` : "missing stack subcommand", USAGE7);
|
|
75766
75875
|
}
|
|
75767
|
-
var PLAN_USAGE = "workit stack plan [--name <n>] [--trunk <b> | --track <t>] [<bottom> … <top>] [--json]", STATUS_USAGE2 = "workit stack status [--name <n>] [--json]", SYNC_USAGE = "workit stack sync [--name <n>] [--local] [--dry-run] [--force <branch>]… [--json]", LAND_USAGE = "workit stack land [--name <n>] [--dry-run] [--max <n>] [--method squash|merge|rebase] [--timeout 20m] [--interval 30s] [--json]", USAGE7 = "workit stack plan|status|sync|land ... (workit help stack)", short4 = (sha) => sha ? sha.slice(0, 12) : "?", stackFailed = (io, result) => emit(io, fail(result.code, result.error, { unblock: result.unblock, data: result.data ?? {} })), label = (forge, pr) => pr === null ? "no PR" : `${forge === "gitlab" ? "MR !" : "PR #"}${pr}`, renderSync = (data) => [
|
|
75876
|
+
var PLAN_USAGE = "workit stack plan [--name <n>] [--trunk <b> | --track <t>] [<bottom> … <top>] [--json]", STATUS_USAGE2 = "workit stack status [--name <n>] [--json]", SYNC_USAGE = "workit stack sync [--name <n>] [--local] [--dry-run] [--force <branch>]… [--json]", LAND_USAGE = "workit stack land [--name <n>] [--dry-run] [--max <n>] [--method squash|merge|rebase] [--unverified --reason <why>] [--timeout 20m] [--interval 30s] [--json]", USAGE7 = "workit stack plan|status|sync|land ... (workit help stack)", short4 = (sha) => sha ? sha.slice(0, 12) : "?", stackFailed = (io, result) => emit(io, fail(result.code, result.error, { unblock: result.unblock, data: result.data ?? {} })), label = (forge, pr) => pr === null ? "no PR" : `${forge === "gitlab" ? "MR !" : "PR #"}${pr}`, renderSync = (data) => [
|
|
75768
75877
|
`${data.dryRun ? "would sync" : "synced"} stack ${data.name}${data.merged.length ? `; merged: ${data.merged.map((item) => item.branch).join(", ")}` : ""}`,
|
|
75769
75878
|
...data.steps.map((step) => [
|
|
75770
75879
|
` ${step.branch} on ${step.parent}:`,
|
|
@@ -94739,6 +94848,10 @@ function parse7(argv) {
|
|
|
94739
94848
|
};
|
|
94740
94849
|
for (let index = 0;index < argv.length; index += 1) {
|
|
94741
94850
|
const raw = argv[index];
|
|
94851
|
+
if (raw === "--") {
|
|
94852
|
+
options.paths.push(...argv.slice(index + 1));
|
|
94853
|
+
break;
|
|
94854
|
+
}
|
|
94742
94855
|
const [flag, inline] = raw.startsWith("--") && raw.includes("=") ? [raw.slice(0, raw.indexOf("=")), raw.slice(raw.indexOf("=") + 1)] : [raw, undefined];
|
|
94743
94856
|
if (flag === "--json")
|
|
94744
94857
|
continue;
|
|
@@ -95310,7 +95423,7 @@ async function resumeBrief(argv, io) {
|
|
|
95310
95423
|
return emit(io, ok({ ...data, recorded }), human2);
|
|
95311
95424
|
}
|
|
95312
95425
|
async function run21(argv, io) {
|
|
95313
|
-
if (!argv.
|
|
95426
|
+
if (!argv.some((arg) => arg === "--task" || arg.startsWith("--task=")))
|
|
95314
95427
|
return resumeBrief(argv, io);
|
|
95315
95428
|
await Promise.resolve().then(() => init_task());
|
|
95316
95429
|
return runTaskCommand(["handoff", ...argv]);
|
|
@@ -95323,9 +95436,99 @@ var init_handoff = __esm(() => {
|
|
|
95323
95436
|
|
|
95324
95437
|
// packages/workit-cli/src/main.ts
|
|
95325
95438
|
init_package();
|
|
95326
|
-
init_output();
|
|
95327
95439
|
import path52 from "node:path";
|
|
95328
95440
|
|
|
95441
|
+
// packages/workit-cli/src/help.ts
|
|
95442
|
+
var HELP_FLAGS = new Set(["--help", "-h"]);
|
|
95443
|
+
var ESCAPE = "A value that starts with - goes as --flag=value (or after a bare --).";
|
|
95444
|
+
var options = (args) => {
|
|
95445
|
+
const end = args.indexOf("--");
|
|
95446
|
+
return end < 0 ? args : args.slice(0, end);
|
|
95447
|
+
};
|
|
95448
|
+
var wantsHelp = (args) => options(args).some((arg) => HELP_FLAGS.has(arg));
|
|
95449
|
+
var firstWord = (args) => options(args).find((arg) => !arg.startsWith("-"));
|
|
95450
|
+
var valueFlags = (lines) => {
|
|
95451
|
+
const out = new Map;
|
|
95452
|
+
const group = /(?<![\w-])(--?[a-zA-Z][\w-]*(?:\|--?[a-zA-Z][\w-]*)*) (?=[<"a-z0-9])/gu;
|
|
95453
|
+
for (const line of lines)
|
|
95454
|
+
for (const match of line.matchAll(group)) {
|
|
95455
|
+
const names = match[1].split("|");
|
|
95456
|
+
const long = names.find((name) => name.startsWith("--")) ?? names[0];
|
|
95457
|
+
for (const name of names)
|
|
95458
|
+
out.set(name, long);
|
|
95459
|
+
}
|
|
95460
|
+
return out;
|
|
95461
|
+
};
|
|
95462
|
+
function helpAsValue(args, lines) {
|
|
95463
|
+
const before = options(args);
|
|
95464
|
+
const takes = valueFlags(lines);
|
|
95465
|
+
for (let index = 1;index < before.length; index += 1) {
|
|
95466
|
+
const flag = before[index];
|
|
95467
|
+
const long = takes.get(before[index - 1]);
|
|
95468
|
+
if (HELP_FLAGS.has(flag) && long)
|
|
95469
|
+
return `\`${flag}\` looks like the value of ${before[index - 1]}; use ${long}=${flag} or put it after --`;
|
|
95470
|
+
}
|
|
95471
|
+
return null;
|
|
95472
|
+
}
|
|
95473
|
+
function takesPositionals(lines) {
|
|
95474
|
+
const flag = /(?<![\w-])--?[a-zA-Z][\w-]*(?:\|--?[a-zA-Z][\w-]*)*(?:[ =](?!-)(?:<[^>]*>|"[^"]*"|[\w.,@/|=-]+)…?)?/gu;
|
|
95475
|
+
return lines.some((line) => /<|"|\w…|\s…/u.test(line.replace(flag, "")));
|
|
95476
|
+
}
|
|
95477
|
+
var usageLines = (entry) => entry.subcommands?.length ? entry.subcommands.map((sub) => sub.usage) : [entry.usage];
|
|
95478
|
+
var examplesFor = (entry, sub) => (entry.examples ?? []).filter((example) => sub ? new RegExp(`^workit ${entry.name} ${sub.name}(?![\\w-])`, "u").test(example) : true);
|
|
95479
|
+
var exampleBlock = (examples) => examples.length ? ["", "examples:", ...examples.map((line) => ` ${line}`)] : [];
|
|
95480
|
+
function verbHelp(entry) {
|
|
95481
|
+
const subs = entry.subcommands ?? [];
|
|
95482
|
+
const usages = usageLines(entry);
|
|
95483
|
+
const examples = examplesFor(entry);
|
|
95484
|
+
const text = [
|
|
95485
|
+
...subs.length ? [
|
|
95486
|
+
`workit ${entry.name}: ${entry.summary}`,
|
|
95487
|
+
"",
|
|
95488
|
+
...subs.flatMap((sub) => [`usage: ${sub.usage}`, ` ${sub.summary}`])
|
|
95489
|
+
] : [`usage: ${entry.usage}`, "", entry.summary],
|
|
95490
|
+
...exampleBlock(examples),
|
|
95491
|
+
"",
|
|
95492
|
+
...subs.length ? [`More: workit help ${entry.name} <${subs.map((sub) => sub.name).join("|")}>`] : [],
|
|
95493
|
+
ESCAPE
|
|
95494
|
+
].join(`
|
|
95495
|
+
`);
|
|
95496
|
+
return {
|
|
95497
|
+
name: entry.name,
|
|
95498
|
+
group: entry.group,
|
|
95499
|
+
usage: usages[0],
|
|
95500
|
+
usages,
|
|
95501
|
+
summary: entry.summary,
|
|
95502
|
+
examples,
|
|
95503
|
+
text
|
|
95504
|
+
};
|
|
95505
|
+
}
|
|
95506
|
+
function subcommandHelp(entry, sub) {
|
|
95507
|
+
const examples = examplesFor(entry, sub);
|
|
95508
|
+
return {
|
|
95509
|
+
name: entry.name,
|
|
95510
|
+
group: entry.group,
|
|
95511
|
+
subcommand: sub.name,
|
|
95512
|
+
usage: sub.usage,
|
|
95513
|
+
usages: [sub.usage],
|
|
95514
|
+
summary: sub.summary,
|
|
95515
|
+
examples,
|
|
95516
|
+
text: [
|
|
95517
|
+
`usage: ${sub.usage}`,
|
|
95518
|
+
"",
|
|
95519
|
+
sub.summary,
|
|
95520
|
+
...exampleBlock(examples),
|
|
95521
|
+
"",
|
|
95522
|
+
...sub.aliases?.length ? [`aliases: ${sub.aliases.join(", ")}`] : [],
|
|
95523
|
+
ESCAPE
|
|
95524
|
+
].join(`
|
|
95525
|
+
`)
|
|
95526
|
+
};
|
|
95527
|
+
}
|
|
95528
|
+
|
|
95529
|
+
// packages/workit-cli/src/main.ts
|
|
95530
|
+
init_output();
|
|
95531
|
+
|
|
95329
95532
|
// packages/workit-cli/src/verbs/registry.ts
|
|
95330
95533
|
var TASK_FAMILY_NAMES = [
|
|
95331
95534
|
"task",
|
|
@@ -95336,13 +95539,97 @@ var TASK_FAMILY_NAMES = [
|
|
|
95336
95539
|
"worker",
|
|
95337
95540
|
"state"
|
|
95338
95541
|
];
|
|
95339
|
-
var
|
|
95542
|
+
var FAMILY_OPTIONS = "[--task <id>] [--payload <JSON|@file|->] [--revision <r>] [--workspace-revision <r|null>] [--view <v>] [--actor <a>] [--confirm]";
|
|
95543
|
+
var FAMILY_ACTIONS = {
|
|
95544
|
+
task: {
|
|
95545
|
+
list: "List the workspace's tasks",
|
|
95546
|
+
inspect: "Show one task's full state",
|
|
95547
|
+
revise: "Change a task's intent or scope",
|
|
95548
|
+
progress: "Record progress on a task",
|
|
95549
|
+
pause: "Pause a task",
|
|
95550
|
+
resume: "Resume a paused task",
|
|
95551
|
+
start: "Start a task from a full payload",
|
|
95552
|
+
close: "Close a task by id"
|
|
95553
|
+
},
|
|
95554
|
+
policy: {
|
|
95555
|
+
assess: "Judge the branch's work and record the derived checks, verdicts and gates",
|
|
95556
|
+
preview: "Show what a judgment would derive, without recording it",
|
|
95557
|
+
explain: "Explain the policy in force"
|
|
95558
|
+
},
|
|
95559
|
+
evidence: { record: "Record evidence against a task's requirements" },
|
|
95560
|
+
finding: { record: "Record a finding", resolve: "Resolve a finding" },
|
|
95561
|
+
decision: { record: "Record a task decision", revoke: "Revoke a task decision" },
|
|
95562
|
+
worker: {
|
|
95563
|
+
assign: "Assign a worker to a task",
|
|
95564
|
+
report: "Report a worker's result",
|
|
95565
|
+
cancel: "Cancel a worker assignment"
|
|
95566
|
+
},
|
|
95567
|
+
state: { export: "Export a task's state (v1)", import: "Import an exported task state" }
|
|
95568
|
+
};
|
|
95569
|
+
var POLICY_JUDGE = "--judge risk=trivial|normal|high behavior=yes|no product-choice=yes|no plan=yes|no [--ref <path>]…";
|
|
95570
|
+
var TASK_IMPLICIT = [
|
|
95571
|
+
{
|
|
95572
|
+
name: "status",
|
|
95573
|
+
usage: "workit task status [--all]",
|
|
95574
|
+
summary: "The current branch's task, or every task with --all"
|
|
95575
|
+
},
|
|
95576
|
+
{
|
|
95577
|
+
name: "start",
|
|
95578
|
+
usage: `workit task start "<objective>" | task start ${FAMILY_OPTIONS}`,
|
|
95579
|
+
summary: "Start tracking the current branch's task (idempotent per branch)"
|
|
95580
|
+
},
|
|
95581
|
+
{
|
|
95582
|
+
name: "note",
|
|
95583
|
+
usage: 'workit task note [--next "<t>"] [--objective "<t>"] [--] "<text>"',
|
|
95584
|
+
summary: "Add a progress note to the current branch's task (creates it if needed)"
|
|
95585
|
+
},
|
|
95586
|
+
{
|
|
95587
|
+
name: "close",
|
|
95588
|
+
usage: `workit task close [--outcome verified|limited|stopped] [--summary "<t>"] [--confirm] | task close ${FAMILY_OPTIONS}`,
|
|
95589
|
+
summary: "Close the current branch's task, or a task by id"
|
|
95590
|
+
},
|
|
95591
|
+
{
|
|
95592
|
+
name: "adopt",
|
|
95593
|
+
usage: "workit task adopt <id>",
|
|
95594
|
+
summary: "Bind a migrated or other task to the current branch"
|
|
95595
|
+
}
|
|
95596
|
+
];
|
|
95597
|
+
var familySubcommands = (name) => {
|
|
95598
|
+
const implicit = name === "task" ? TASK_IMPLICIT : [];
|
|
95599
|
+
const grammar = Object.entries(FAMILY_ACTIONS[name]).filter(([action]) => !implicit.some((entry) => entry.name === action)).map(([action, summary]) => ({
|
|
95600
|
+
name: action,
|
|
95601
|
+
usage: name === "policy" && action !== "explain" ? `workit policy ${action} ${POLICY_JUDGE} ${FAMILY_OPTIONS}` : `workit ${name} ${action} ${FAMILY_OPTIONS}`,
|
|
95602
|
+
summary
|
|
95603
|
+
}));
|
|
95604
|
+
return [...implicit, ...grammar];
|
|
95605
|
+
};
|
|
95606
|
+
var family = (name) => withSubcommands({
|
|
95340
95607
|
name,
|
|
95341
95608
|
group: "task",
|
|
95342
|
-
usage: name === "task" ? 'workit task status [--all] | task start "<objective>" | task note "<text>" [--next "<t>"] | task close [--outcome verified|limited|stopped] | task adopt <id> | task <action> --payload <JSON>' : name === "policy" ? "workit policy assess|preview --judge risk=trivial|normal|high behavior=yes|no product-choice=yes|no plan=yes|no [--ref <path>] | policy explain" : `workit ${name} <action> [options]`,
|
|
95343
95609
|
summary: name === "task" ? "The current branch's task (created by its first note, check or recording; no ids needed), or the task family" : name === "policy" ? "Judge the branch's work; Workit derives its checks, verdicts, decision and plan gates" : `Inspect and control a Workit task (${name} family)`,
|
|
95610
|
+
subcommands: familySubcommands(name),
|
|
95611
|
+
...name === "task" ? {
|
|
95612
|
+
examples: [
|
|
95613
|
+
'workit task note "parser done; wiring the router" --next "add the router test"',
|
|
95614
|
+
"workit task close --outcome verified"
|
|
95615
|
+
]
|
|
95616
|
+
} : name === "policy" ? {
|
|
95617
|
+
examples: [
|
|
95618
|
+
"workit policy assess --judge risk=normal behavior=yes product-choice=no plan=no"
|
|
95619
|
+
]
|
|
95620
|
+
} : {},
|
|
95344
95621
|
load: async () => (await Promise.resolve().then(() => (init_family(), exports_family))).familyVerb(name)
|
|
95345
95622
|
});
|
|
95623
|
+
function withSubcommands(entry, options = {}) {
|
|
95624
|
+
const names = entry.subcommands.map((sub) => sub.name).join("|");
|
|
95625
|
+
return {
|
|
95626
|
+
...entry,
|
|
95627
|
+
usage: `workit ${entry.name} ${options.optional ? `[${names}]` : names} [options]`,
|
|
95628
|
+
...options.optional ? { optionalSubcommand: true } : {}
|
|
95629
|
+
};
|
|
95630
|
+
}
|
|
95631
|
+
var VERIFY_OPTIONS = "[--expect pushed|pr|merged|released] [--pr <n> | --branch <b>] [--sha <sha>] [--tag <t>] [--package <name[@version]>]";
|
|
95632
|
+
var LEDGER_ACTOR = "[--branch <b> | --pr <n>] [--supersedes <id>] [--session <id> | --as <role>]";
|
|
95346
95633
|
var VERBS = [
|
|
95347
95634
|
{
|
|
95348
95635
|
name: "init",
|
|
@@ -95354,28 +95641,28 @@ var VERBS = [
|
|
|
95354
95641
|
{
|
|
95355
95642
|
name: "upgrade",
|
|
95356
95643
|
group: "setup",
|
|
95357
|
-
usage: "workit upgrade [--hosts=a,b|none] [--cli] [--preview | --apply --confirm]
|
|
95644
|
+
usage: "workit upgrade [--hosts=a,b|none] [--cli] [--preview | --apply --confirm]",
|
|
95358
95645
|
summary: "Preview upgrades (--apply --confirm to apply)",
|
|
95359
95646
|
load: () => Promise.resolve().then(() => (init_upgrade2(), exports_upgrade))
|
|
95360
95647
|
},
|
|
95361
95648
|
{
|
|
95362
95649
|
name: "launch",
|
|
95363
95650
|
group: "setup",
|
|
95364
|
-
usage: "workit launch <host> [--auto-upgrade] [-- args]",
|
|
95651
|
+
usage: "workit launch <host> [--auto-upgrade] [-- <host args…>]",
|
|
95365
95652
|
summary: "Upgrade before host startup, then start the host",
|
|
95366
95653
|
load: () => Promise.resolve().then(() => (init_launch(), exports_launch))
|
|
95367
95654
|
},
|
|
95368
95655
|
{
|
|
95369
95656
|
name: "doctor",
|
|
95370
95657
|
group: "setup",
|
|
95371
|
-
usage: "workit doctor [--
|
|
95658
|
+
usage: "workit doctor [--fix-lock [--force [--yes]]]",
|
|
95372
95659
|
summary: "Verify the offline installation health (--fix-lock clears a stale workit store lock)",
|
|
95373
95660
|
load: () => Promise.resolve().then(() => (init_doctor2(), exports_doctor))
|
|
95374
95661
|
},
|
|
95375
95662
|
{
|
|
95376
95663
|
name: "gc",
|
|
95377
95664
|
group: "setup",
|
|
95378
|
-
usage: "workit gc [--dry-run] [--prune-recovery --yes]
|
|
95665
|
+
usage: "workit gc [--dry-run] [--prune-recovery --yes]",
|
|
95379
95666
|
summary: "Compact long task event logs, drop unreferenced blobs and old check logs; report (or prune) 2.x recovery copies",
|
|
95380
95667
|
load: () => Promise.resolve().then(() => (init_gc(), exports_gc))
|
|
95381
95668
|
},
|
|
@@ -95386,108 +95673,312 @@ var VERBS = [
|
|
|
95386
95673
|
summary: "Remove workit host registrations interactively (~/.config/workit is kept)",
|
|
95387
95674
|
load: () => Promise.resolve().then(() => (init_uninstall2(), exports_uninstall))
|
|
95388
95675
|
},
|
|
95389
|
-
{
|
|
95676
|
+
withSubcommands({
|
|
95390
95677
|
name: "grant",
|
|
95391
95678
|
group: "setup",
|
|
95392
|
-
usage: "workit grant show [<workspace>] [--all] | grant set <workspace> <kind>=<true|false|verified>… | grant unset <workspace> <kind>…",
|
|
95393
95679
|
summary: "Show or change a workspace's autonomy grants (push, pr, merge, release, rerun) and default endpoint; raising needs the user at a terminal",
|
|
95680
|
+
subcommands: [
|
|
95681
|
+
{
|
|
95682
|
+
name: "show",
|
|
95683
|
+
usage: "workit grant show [<workspace>] [--all]",
|
|
95684
|
+
summary: "Show the grants of the current (or named) workspace, or of every workspace"
|
|
95685
|
+
},
|
|
95686
|
+
{
|
|
95687
|
+
name: "set",
|
|
95688
|
+
usage: "workit grant set <workspace> <kind>=<true|false|verified>… [defaultEndpoint=commit|pr|green|merged] [verification=self|independent]",
|
|
95689
|
+
summary: "Change grants (kinds: push, pr, merge, release, rerun); raising one asks the user to confirm at a terminal"
|
|
95690
|
+
},
|
|
95691
|
+
{
|
|
95692
|
+
name: "unset",
|
|
95693
|
+
usage: "workit grant unset <workspace> <kind>…",
|
|
95694
|
+
summary: "Remove grants, falling back to the defaults"
|
|
95695
|
+
}
|
|
95696
|
+
],
|
|
95697
|
+
examples: ["workit grant show", "workit grant set my-repo push=true pr=true"],
|
|
95394
95698
|
load: () => Promise.resolve().then(() => (init_grant(), exports_grant))
|
|
95395
|
-
},
|
|
95699
|
+
}, { optional: true }),
|
|
95396
95700
|
...TASK_FAMILY_NAMES.map(family),
|
|
95397
95701
|
{
|
|
95398
95702
|
name: "check",
|
|
95399
95703
|
group: "delivery",
|
|
95400
|
-
usage: "workit check <name> | workit check [--name <n>] [--shell] [--timeout <s>] [--task <id>] -- <cmd…>",
|
|
95704
|
+
usage: "workit check <name> [--task <id>] [--base <ref>] | workit check [--name <n>] [--shell] [--timeout <s>] [--task <id>] [--base <ref>] -- <cmd…>",
|
|
95401
95705
|
summary: "Run a configured or ad-hoc check and record CLI-observed evidence (exit = the command's)",
|
|
95706
|
+
examples: ["workit check test", "workit check --name unit -- bun test test/unit"],
|
|
95402
95707
|
load: () => Promise.resolve().then(() => (init_check(), exports_check))
|
|
95403
95708
|
},
|
|
95404
|
-
{
|
|
95709
|
+
withSubcommands({
|
|
95405
95710
|
name: "pr",
|
|
95406
95711
|
group: "delivery",
|
|
95407
|
-
usage: "workit pr status [--pr <n>] | pr create [--base <b> | --track <t>] (--title <t> | --fill) [--draft] | pr merge [--pr <n>] [--method squash|merge|rebase] [--delete-branch]",
|
|
95408
95712
|
summary: "PR/MR state with failing log tails and next action; open a SHA-verified PR; merge only when READY, verified and granted",
|
|
95713
|
+
subcommands: [
|
|
95714
|
+
{
|
|
95715
|
+
name: "status",
|
|
95716
|
+
usage: "workit pr status [--pr <n> | --branch <b>] [--log-lines 60]",
|
|
95717
|
+
summary: "PR/MR state, failing check log tails and the next action"
|
|
95718
|
+
},
|
|
95719
|
+
{
|
|
95720
|
+
name: "create",
|
|
95721
|
+
usage: "workit pr create [--base <b> | --track <t>] (--title <t> [--body <text> | --body-file <f>] | --fill) [--draft]",
|
|
95722
|
+
summary: "Open a PR/MR for the pushed branch, verified against the local HEAD"
|
|
95723
|
+
},
|
|
95724
|
+
{
|
|
95725
|
+
name: "merge",
|
|
95726
|
+
usage: "workit pr merge [--pr <n>] [--method squash|merge|rebase] [--delete-branch] [--unverified --reason <why>]",
|
|
95727
|
+
summary: "Merge when READY, verified by a non-author and granted"
|
|
95728
|
+
}
|
|
95729
|
+
],
|
|
95730
|
+
examples: [
|
|
95731
|
+
'workit pr create --title "fix(cli): answer help flags first" --body-file pr.md',
|
|
95732
|
+
"workit pr merge --method squash --delete-branch"
|
|
95733
|
+
],
|
|
95409
95734
|
load: () => Promise.resolve().then(() => (init_pr(), exports_pr))
|
|
95410
|
-
},
|
|
95411
|
-
{
|
|
95735
|
+
}),
|
|
95736
|
+
withSubcommands({
|
|
95412
95737
|
name: "ci",
|
|
95413
95738
|
group: "delivery",
|
|
95414
|
-
usage: "workit ci wait [--pr <n>] [--head <sha>] [--timeout 20m] | ci rerun [--failed | --check <name>…] --reason flake|infra [--force]",
|
|
95415
95739
|
summary: "Wait for CI on the PR head (exit 0/1/3/4), or rerun failed jobs once per head",
|
|
95740
|
+
subcommands: [
|
|
95741
|
+
{
|
|
95742
|
+
name: "wait",
|
|
95743
|
+
usage: "workit ci wait [--pr <n> | --branch <b>] [--head <sha>] [--timeout 20m] [--interval 30s]",
|
|
95744
|
+
summary: "Wait for CI on the PR head; exit 0 green, 1 red, 3 blocked, 4 still pending"
|
|
95745
|
+
},
|
|
95746
|
+
{
|
|
95747
|
+
name: "rerun",
|
|
95748
|
+
usage: "workit ci rerun [--pr <n> | --branch <b>] [--check <name>… | --failed] --reason flake|infra [--force]",
|
|
95749
|
+
summary: "Rerun failed jobs once per head, with a recorded reason"
|
|
95750
|
+
}
|
|
95751
|
+
],
|
|
95752
|
+
examples: ["workit ci wait --timeout 30m", "workit ci rerun --failed --reason flake"],
|
|
95416
95753
|
load: () => Promise.resolve().then(() => (init_ci(), exports_ci))
|
|
95417
|
-
},
|
|
95418
|
-
{
|
|
95754
|
+
}),
|
|
95755
|
+
withSubcommands({
|
|
95419
95756
|
name: "git",
|
|
95420
95757
|
group: "delivery",
|
|
95421
|
-
usage: "workit git branch <name> [--base <b>] [--track <t>] | git commit -m <msg> [--all | -- <paths…>] | git push [--set-upstream] [--force-with-lease]",
|
|
95422
95758
|
summary: "Policy-checked branch and commit (Workit-Session trailer); push with a lease and a verified remote tip",
|
|
95759
|
+
subcommands: [
|
|
95760
|
+
{
|
|
95761
|
+
name: "branch",
|
|
95762
|
+
usage: "workit git branch <name> | git branch --kind feature|bugfix|hotfix --slug <s> [--base <b>] [--track <t>] [--carry]",
|
|
95763
|
+
summary: "Create and switch to a branch from the trunk or a release track"
|
|
95764
|
+
},
|
|
95765
|
+
{
|
|
95766
|
+
name: "commit",
|
|
95767
|
+
usage: "workit git commit -m|--message <msg>… [-a|--all | [--] <paths…>]",
|
|
95768
|
+
summary: "Commit with a linted Conventional Commit message and the session trailer"
|
|
95769
|
+
},
|
|
95770
|
+
{
|
|
95771
|
+
name: "push",
|
|
95772
|
+
usage: "workit git push [-u|--set-upstream] [--force-with-lease [--expect <sha>] [--overwrite-unintegrated]]",
|
|
95773
|
+
summary: "Push the current branch and verify the remote tip (never a blind --force)"
|
|
95774
|
+
}
|
|
95775
|
+
],
|
|
95776
|
+
examples: [
|
|
95777
|
+
"workit git branch --kind feature --slug help-everywhere",
|
|
95778
|
+
'workit git commit -m "fix(cli): answer help flags first" --all',
|
|
95779
|
+
"workit git push --set-upstream"
|
|
95780
|
+
],
|
|
95423
95781
|
load: () => Promise.resolve().then(() => (init_git2(), exports_git))
|
|
95424
|
-
},
|
|
95425
|
-
{
|
|
95782
|
+
}),
|
|
95783
|
+
withSubcommands({
|
|
95426
95784
|
name: "verify-delivery",
|
|
95427
95785
|
group: "delivery",
|
|
95428
|
-
usage: "workit verify-delivery [push|pr|merge|release] [--pr <n> | --branch <b>] [--sha <s>] [--tag <t>] [--package <p>]",
|
|
95429
95786
|
summary: "Observe that a push, PR head, merge or release really landed on the remote (exit 1 when not)",
|
|
95787
|
+
subcommands: [
|
|
95788
|
+
["push", "pushed", "the branch's remote tip is the local HEAD"],
|
|
95789
|
+
["pr", null, "the PR head is the local HEAD"],
|
|
95790
|
+
["merge", "merged", "the PR merged into its base"],
|
|
95791
|
+
["release", "released", "the release tag and package exist"]
|
|
95792
|
+
].map(([name, alias, what]) => ({
|
|
95793
|
+
name,
|
|
95794
|
+
...alias ? { aliases: [alias] } : {},
|
|
95795
|
+
usage: `workit verify-delivery ${name} ${VERIFY_OPTIONS}`,
|
|
95796
|
+
summary: `Observe that ${what}`
|
|
95797
|
+
})),
|
|
95798
|
+
examples: ["workit verify-delivery push", "workit verify-delivery merge --pr 42"],
|
|
95430
95799
|
load: () => Promise.resolve().then(() => (init_verify_delivery(), exports_verify_delivery))
|
|
95431
|
-
},
|
|
95432
|
-
{
|
|
95800
|
+
}, { optional: true }),
|
|
95801
|
+
withSubcommands({
|
|
95433
95802
|
name: "stack",
|
|
95434
95803
|
group: "delivery",
|
|
95435
|
-
usage: "workit stack plan [<bottom> … <top>] | status | sync [--local] | land [--dry-run] [--max <n>] [--json]",
|
|
95436
95804
|
summary: "Plan, restack (lease push + retarget) and land a base-branch stack of PRs, root first",
|
|
95805
|
+
subcommands: [
|
|
95806
|
+
{
|
|
95807
|
+
name: "plan",
|
|
95808
|
+
usage: "workit stack plan [--name <n>] [--trunk <b> | --track <t>] [<bottom> … <top>]",
|
|
95809
|
+
summary: "Record the stack's branches, bottom first"
|
|
95810
|
+
},
|
|
95811
|
+
{
|
|
95812
|
+
name: "status",
|
|
95813
|
+
usage: "workit stack status [--name <n>]",
|
|
95814
|
+
summary: "Each stacked PR's base, head, CI and verdict"
|
|
95815
|
+
},
|
|
95816
|
+
{
|
|
95817
|
+
name: "sync",
|
|
95818
|
+
usage: "workit stack sync [--name <n>] [--local] [--dry-run] [--force <branch>]…",
|
|
95819
|
+
summary: "Restack onto the moved bases, lease-push and retarget the PRs"
|
|
95820
|
+
},
|
|
95821
|
+
{
|
|
95822
|
+
name: "land",
|
|
95823
|
+
usage: "workit stack land [--name <n>] [--dry-run] [--max <n>] [--method squash|merge|rebase] [--unverified --reason <why>] [--timeout 20m] [--interval 30s]",
|
|
95824
|
+
summary: "Merge the stack root first, restacking the rest as each lands"
|
|
95825
|
+
}
|
|
95826
|
+
],
|
|
95827
|
+
examples: ["workit stack plan feature/a feature/b feature/c", "workit stack land --dry-run"],
|
|
95437
95828
|
load: () => Promise.resolve().then(() => (init_stack2(), exports_stack))
|
|
95438
|
-
},
|
|
95439
|
-
{
|
|
95829
|
+
}),
|
|
95830
|
+
withSubcommands({
|
|
95440
95831
|
name: "fanout",
|
|
95441
95832
|
group: "delivery",
|
|
95442
|
-
usage: "workit fanout plan <plan.json> [--name <n>] [--trunk <b> | --track <t>] [--take-lead] | fanout brief <slice> [--mode new|resume] [--attempt <n>] | fanout check [<slice>…] [--name <n>] [--base <ref>] [--offline] | fanout status [--name <n>] [--stuck-after 30m] [--offline] | fanout worktree create|release <slice> [--force] [--json]",
|
|
95443
95833
|
summary: "Register parallel slices (complete briefs, disjoint scopes, shared-file owners), render each worker's brief with the standing orders, watch them (STUCK, PR, CI, verdict, landed, landing order), make and release slice worktrees, and gate fan-in: out-of-scope edits, trunk and sibling merge conflicts",
|
|
95834
|
+
subcommands: [
|
|
95835
|
+
{
|
|
95836
|
+
name: "plan",
|
|
95837
|
+
usage: "workit fanout plan <plan.json> [--name <n>] [--trunk <b> | --track <t>] [--take-lead]",
|
|
95838
|
+
summary: "Register the slices of a plan file"
|
|
95839
|
+
},
|
|
95840
|
+
{
|
|
95841
|
+
name: "brief",
|
|
95842
|
+
usage: "workit fanout brief <slice> [--mode new|resume] [--attempt <n>] [--name <n>]",
|
|
95843
|
+
summary: "Render one worker's brief with the standing orders"
|
|
95844
|
+
},
|
|
95845
|
+
{
|
|
95846
|
+
name: "check",
|
|
95847
|
+
usage: "workit fanout check [<slice>…] [--name <n>] [--base <ref>] [--offline]",
|
|
95848
|
+
summary: "Gate fan-in: out-of-scope edits, trunk and sibling merge conflicts"
|
|
95849
|
+
},
|
|
95850
|
+
{
|
|
95851
|
+
name: "status",
|
|
95852
|
+
usage: "workit fanout status [--name <n>] [--stuck-after 30m] [--offline]",
|
|
95853
|
+
summary: "Each slice's state: STUCK, PR, CI, verdict, landed, landing order"
|
|
95854
|
+
},
|
|
95855
|
+
{
|
|
95856
|
+
name: "worktree",
|
|
95857
|
+
usage: "workit fanout worktree create|release <slice> [--name <n>] [--force]",
|
|
95858
|
+
summary: "Make or release a slice's worktree (--force applies to release only)"
|
|
95859
|
+
}
|
|
95860
|
+
],
|
|
95861
|
+
examples: [
|
|
95862
|
+
"workit fanout plan plan.json --take-lead",
|
|
95863
|
+
"workit fanout status --stuck-after 20m"
|
|
95864
|
+
],
|
|
95444
95865
|
load: () => Promise.resolve().then(() => (init_fanout2(), exports_fanout))
|
|
95445
|
-
},
|
|
95446
|
-
{
|
|
95866
|
+
}),
|
|
95867
|
+
withSubcommands({
|
|
95447
95868
|
name: "ledger",
|
|
95448
95869
|
group: "delivery",
|
|
95449
|
-
usage: "workit ledger decision|ruling|verdict|standing|list|check ...",
|
|
95450
95870
|
summary: "Record and query decisions, rulings, SHA-keyed verdicts (patch-id carry-over across rebases) and a fanout's standing orders",
|
|
95871
|
+
subcommands: [
|
|
95872
|
+
{
|
|
95873
|
+
name: "decision",
|
|
95874
|
+
usage: `workit ledger decision "<what>" --why "<why>" [--ref <path|url>]… ${LEDGER_ACTOR}`,
|
|
95875
|
+
summary: "Record a decision and why"
|
|
95876
|
+
},
|
|
95877
|
+
{
|
|
95878
|
+
name: "ruling",
|
|
95879
|
+
usage: `workit ledger ruling "<what>" --why "<why>" --cost-if-wrong "<cost>" [--ref <path|url>]… ${LEDGER_ACTOR}`,
|
|
95880
|
+
summary: "Record a ruling on an open choice, with the cost of being wrong"
|
|
95881
|
+
},
|
|
95882
|
+
{
|
|
95883
|
+
name: "verdict",
|
|
95884
|
+
usage: `workit ledger verdict <result> --how "<method/evidence>" [--kind unit|live|perf|review] [--base <ref>] [--surface ui|cli|api] [--evidence <ref>]… [--self] ${LEDGER_ACTOR} | ledger verdict [<branch>]`,
|
|
95885
|
+
summary: "Record a SHA-keyed verdict on the branch head (result: verified, tests-verified, type-check-only, blocked, failed), or show the current verdicts"
|
|
95886
|
+
},
|
|
95887
|
+
{
|
|
95888
|
+
name: "list",
|
|
95889
|
+
aliases: ["show"],
|
|
95890
|
+
usage: "workit ledger list|show [--branch <b>] [--pr <n>] [--type <t>] [--last <n>]",
|
|
95891
|
+
summary: "List ledger rows, newest last"
|
|
95892
|
+
},
|
|
95893
|
+
{
|
|
95894
|
+
name: "check",
|
|
95895
|
+
usage: "workit ledger check [--pr <n> | --branch <b>]",
|
|
95896
|
+
summary: "Whether the branch head carries an accepted non-author verdict"
|
|
95897
|
+
},
|
|
95898
|
+
{
|
|
95899
|
+
name: "standing",
|
|
95900
|
+
usage: `workit ledger standing add "<order>" | standing list | standing clear [<id>] [--fanout <name>] [--supersedes <id>] [--session <id> | --as <role>]`,
|
|
95901
|
+
summary: "The lead's standing orders for a fanout's workers"
|
|
95902
|
+
},
|
|
95903
|
+
{
|
|
95904
|
+
name: "add",
|
|
95905
|
+
usage: 'workit ledger add decision|ruling|verdict "<what>" …',
|
|
95906
|
+
summary: "Same as the bare decision, ruling and verdict forms"
|
|
95907
|
+
}
|
|
95908
|
+
],
|
|
95909
|
+
examples: [
|
|
95910
|
+
'workit ledger decision "keep the registry as the help source" --why "one place to update"',
|
|
95911
|
+
'workit ledger verdict verified --how "ran the CLI against a scratch repo" --kind live --as verifier'
|
|
95912
|
+
],
|
|
95451
95913
|
load: () => Promise.resolve().then(() => (init_ledger2(), exports_ledger))
|
|
95452
|
-
},
|
|
95914
|
+
}),
|
|
95453
95915
|
{
|
|
95454
95916
|
name: "test-audit",
|
|
95455
95917
|
group: "delivery",
|
|
95456
|
-
usage: "workit test-audit [paths…] [--diff [base]] [--rule <ids>] [--min-severity <level>] [--fail-on <level>] [--mutate [--test-cmd <cmd {files}>] [--max-mutants <n>] [--budget <s>]
|
|
95918
|
+
usage: "workit test-audit [paths…] [--diff [<base>]] [--rule <ids>] [--min-severity <level>] [--fail-on <level>] [--mutate [--test-cmd <cmd {files}>] [--max-mutants <n>] [--budget <s>] [--timeout <s>]]",
|
|
95457
95919
|
summary: "Flag tautological and low-value tests with a suggested independent oracle; --mutate checks changed lines with diff-scoped mutation",
|
|
95458
95920
|
load: () => Promise.resolve().then(() => (init_test_audit(), exports_test_audit))
|
|
95459
95921
|
},
|
|
95460
|
-
{
|
|
95922
|
+
withSubcommands({
|
|
95461
95923
|
name: "knowledge",
|
|
95462
95924
|
group: "delivery",
|
|
95463
|
-
usage: "workit knowledge lint [--json]",
|
|
95464
95925
|
summary: "Lint agent knowledge files: AGENTS.md byte budget, broken local links, scaffold-only files, duplicated rules (exit 1 on findings)",
|
|
95926
|
+
subcommands: [
|
|
95927
|
+
{
|
|
95928
|
+
name: "lint",
|
|
95929
|
+
usage: "workit knowledge lint",
|
|
95930
|
+
summary: "Lint AGENTS.md and the knowledge files it links"
|
|
95931
|
+
}
|
|
95932
|
+
],
|
|
95465
95933
|
load: () => Promise.resolve().then(() => (init_knowledge2(), exports_knowledge))
|
|
95466
|
-
},
|
|
95467
|
-
{
|
|
95934
|
+
}),
|
|
95935
|
+
withSubcommands({
|
|
95468
95936
|
name: "youtrack",
|
|
95469
95937
|
group: "delivery",
|
|
95470
|
-
usage: "workit youtrack note <ISSUE> (--markdown <t> | --file <p>) [--minutes <n>] | youtrack time|meeting <ISSUE> --minutes <n> [--text <t>] [--date auto|YYYY-MM-DD]",
|
|
95471
95938
|
summary: "Post a YouTrack comment or log work time (host permission, no grant)",
|
|
95939
|
+
subcommands: [
|
|
95940
|
+
{
|
|
95941
|
+
name: "note",
|
|
95942
|
+
usage: "workit youtrack note <ISSUE> (--markdown <t> | --file <p>) [--minutes <n>] [--date auto|YYYY-MM-DD]",
|
|
95943
|
+
summary: "Post a comment, optionally logging time"
|
|
95944
|
+
},
|
|
95945
|
+
{
|
|
95946
|
+
name: "time",
|
|
95947
|
+
usage: "workit youtrack time <ISSUE> --minutes <n> [--text <t>] [--date auto|YYYY-MM-DD]",
|
|
95948
|
+
summary: "Log work time"
|
|
95949
|
+
},
|
|
95950
|
+
{
|
|
95951
|
+
name: "meeting",
|
|
95952
|
+
usage: "workit youtrack meeting <ISSUE> --minutes <n> --text <t> [--date auto|YYYY-MM-DD]",
|
|
95953
|
+
summary: "Log meeting time"
|
|
95954
|
+
}
|
|
95955
|
+
],
|
|
95472
95956
|
load: () => Promise.resolve().then(() => (init_youtrack2(), exports_youtrack))
|
|
95473
|
-
},
|
|
95474
|
-
{
|
|
95957
|
+
}),
|
|
95958
|
+
withSubcommands({
|
|
95475
95959
|
name: "changelog",
|
|
95476
95960
|
group: "delivery",
|
|
95477
|
-
usage: "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]",
|
|
95478
95961
|
summary: "Add entries under the Unreleased section of the changelog",
|
|
95962
|
+
subcommands: [
|
|
95963
|
+
{
|
|
95964
|
+
name: "apply",
|
|
95965
|
+
usage: "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]",
|
|
95966
|
+
summary: "Add entries (or only normalize the file)"
|
|
95967
|
+
}
|
|
95968
|
+
],
|
|
95479
95969
|
load: () => Promise.resolve().then(() => (init_changelog2(), exports_changelog))
|
|
95480
|
-
},
|
|
95970
|
+
}),
|
|
95481
95971
|
{
|
|
95482
95972
|
name: "handoff",
|
|
95483
95973
|
group: "delivery",
|
|
95484
|
-
usage: "workit handoff [--note <t>] [--next <t>] [--record] | workit handoff --task <id>",
|
|
95974
|
+
usage: "workit handoff [--note <t>] [--next <t>] [--record] [--last <n>] | workit handoff --task <id>",
|
|
95485
95975
|
summary: "Print a resume brief (branch, HEAD, dirty state, verdict, rulings, next command); --task exports v1 task state",
|
|
95486
95976
|
load: () => Promise.resolve().then(() => (init_handoff(), exports_handoff))
|
|
95487
95977
|
}
|
|
95488
95978
|
];
|
|
95489
95979
|
var BY_NAME = new Map(VERBS.map((entry) => [entry.name, entry]));
|
|
95490
95980
|
var findVerb = (name) => BY_NAME.get(name);
|
|
95981
|
+
var findSubcommand = (entry, name) => entry.subcommands?.find((sub) => sub.name === name || sub.aliases?.includes(name));
|
|
95491
95982
|
|
|
95492
95983
|
// packages/workit-cli/src/main.ts
|
|
95493
95984
|
var GROUP_TITLES = {
|
|
@@ -95519,20 +96010,17 @@ ${sections.join(`
|
|
|
95519
96010
|
`)}
|
|
95520
96011
|
|
|
95521
96012
|
Global flags:
|
|
95522
|
-
--json
|
|
95523
|
-
--cwd <dir>
|
|
95524
|
-
--version
|
|
95525
|
-
help
|
|
96013
|
+
--json Machine-readable output: {"ok","code","data","error"?,"unblock"?}
|
|
96014
|
+
--cwd <dir> Run as if started in <dir>
|
|
96015
|
+
--version Print the CLI version
|
|
96016
|
+
-h, --help Show usage for the command and subcommand before it (runs nothing)
|
|
96017
|
+
help <cmd> [<sub>] The same, as a command
|
|
95526
96018
|
|
|
95527
96019
|
Exit codes: 0 ok · 1 failed · 2 usage · 3 blocked · 4 busy/pending · 5 unavailable
|
|
95528
96020
|
|
|
95529
96021
|
Run \`npx @brainervirus/workit-cli init\` to configure platforms, YouTrack, VCS and project hygiene.
|
|
95530
96022
|
`;
|
|
95531
96023
|
}
|
|
95532
|
-
var verbHelp = (entry) => `usage: ${entry.usage}
|
|
95533
|
-
|
|
95534
|
-
${entry.summary}${entry.planned ? ` (coming in ${entry.planned})` : ""}
|
|
95535
|
-
`;
|
|
95536
96024
|
function parseGlobals(argv) {
|
|
95537
96025
|
const rest = [];
|
|
95538
96026
|
let json = false;
|
|
@@ -95578,18 +96066,38 @@ async function main(argv, overrides = {}, options = {}) {
|
|
|
95578
96066
|
return emit(io, ok({ version: package_default.version }), (data) => data.version);
|
|
95579
96067
|
}
|
|
95580
96068
|
if (command === undefined || command === "help" || command === "--help" || command === "-h") {
|
|
95581
|
-
const topic = command === "help" ? args
|
|
96069
|
+
const [topic, sub] = command === "help" ? words2(args) : [];
|
|
95582
96070
|
if (topic) {
|
|
95583
96071
|
const entry = findVerb(topic);
|
|
95584
96072
|
if (!entry)
|
|
95585
96073
|
return unknown2(io, topic);
|
|
95586
|
-
|
|
96074
|
+
if (sub === undefined)
|
|
96075
|
+
return help(io, verbHelp(entry));
|
|
96076
|
+
const found = findSubcommand(entry, sub);
|
|
96077
|
+
if (!found)
|
|
96078
|
+
return emit(io, fail("invalid_input", `unknown ${topic} subcommand "${sub}"`, {
|
|
96079
|
+
unblock: `workit help ${topic}`
|
|
96080
|
+
}));
|
|
96081
|
+
return help(io, subcommandHelp(entry, found));
|
|
95587
96082
|
}
|
|
95588
96083
|
return emit(io, ok({ version: package_default.version, verbs: listed().map(describe3) }), () => helpText());
|
|
95589
96084
|
}
|
|
95590
96085
|
const entry = findVerb(command);
|
|
95591
96086
|
if (!entry)
|
|
95592
96087
|
return unknown2(io, command);
|
|
96088
|
+
if (wantsHelp(verbArgs)) {
|
|
96089
|
+
const word = firstWord(verbArgs);
|
|
96090
|
+
const sub = word === undefined ? undefined : findSubcommand(entry, word);
|
|
96091
|
+
const asValue = helpAsValue(verbArgs, sub ? [sub.usage] : usageLines(entry));
|
|
96092
|
+
if (asValue)
|
|
96093
|
+
return emit(io, fail("invalid_input", asValue, {
|
|
96094
|
+
unblock: `workit help ${entry.name}${sub ? ` ${sub.name}` : ""}`
|
|
96095
|
+
}));
|
|
96096
|
+
return help(io, sub ? subcommandHelp(entry, sub) : verbHelp(entry));
|
|
96097
|
+
}
|
|
96098
|
+
const ended = endOfOptions(io, entry, args);
|
|
96099
|
+
if (typeof ended === "number")
|
|
96100
|
+
return ended;
|
|
95593
96101
|
if (parsed.cwd !== null) {
|
|
95594
96102
|
try {
|
|
95595
96103
|
process.chdir(io.cwd);
|
|
@@ -95607,8 +96115,8 @@ async function main(argv, overrides = {}, options = {}) {
|
|
|
95607
96115
|
`);
|
|
95608
96116
|
const verb = await entry.load();
|
|
95609
96117
|
if (!io.json)
|
|
95610
|
-
return verb.run(
|
|
95611
|
-
return runJsonPure(io, command, (pure) => verb.run(
|
|
96118
|
+
return verb.run(ended, io);
|
|
96119
|
+
return runJsonPure(io, command, (pure) => verb.run(ended, pure));
|
|
95612
96120
|
}
|
|
95613
96121
|
var CODE_FOR_EXIT = {
|
|
95614
96122
|
1: "failed",
|
|
@@ -95671,10 +96179,32 @@ var withJsonFlag = (args) => {
|
|
|
95671
96179
|
return end < 0 ? [...args, "--json"] : [...args.slice(0, end), "--json", ...args.slice(end)];
|
|
95672
96180
|
};
|
|
95673
96181
|
var listed = () => VERBS.filter((entry) => !entry.planned);
|
|
96182
|
+
function endOfOptions(io, entry, args) {
|
|
96183
|
+
const end = args.indexOf("--");
|
|
96184
|
+
if (end < 0)
|
|
96185
|
+
return args;
|
|
96186
|
+
const word = firstWord(args);
|
|
96187
|
+
const sub = word === undefined ? undefined : findSubcommand(entry, word);
|
|
96188
|
+
const unblock = `workit help ${entry.name}${sub ? ` ${sub.name}` : ""}`;
|
|
96189
|
+
if (entry.subcommands?.length && !sub) {
|
|
96190
|
+
if (entry.optionalSubcommand || word !== undefined)
|
|
96191
|
+
return args;
|
|
96192
|
+
return emit(io, fail("invalid_input", `missing ${entry.name} subcommand`, { unblock }));
|
|
96193
|
+
}
|
|
96194
|
+
if (takesPositionals(sub ? [sub.usage] : [entry.usage]))
|
|
96195
|
+
return args;
|
|
96196
|
+
const extra = args.slice(end + 1);
|
|
96197
|
+
if (extra.length)
|
|
96198
|
+
return emit(io, fail("invalid_input", `${entry.name}${sub ? ` ${sub.name}` : ""} takes no positional arguments (got: ${extra.join(" ")})`, { unblock }));
|
|
96199
|
+
return args.slice(0, end);
|
|
96200
|
+
}
|
|
96201
|
+
var words2 = (args) => args.filter((arg) => !arg.startsWith("-"));
|
|
96202
|
+
var help = (io, doc) => emit(io, ok(doc), (data) => data.text);
|
|
95674
96203
|
var describe3 = (entry) => ({
|
|
95675
96204
|
name: entry.name,
|
|
95676
96205
|
group: entry.group,
|
|
95677
96206
|
usage: entry.usage,
|
|
96207
|
+
usages: usageLines(entry),
|
|
95678
96208
|
summary: entry.summary,
|
|
95679
96209
|
...entry.planned ? { planned: entry.planned } : {}
|
|
95680
96210
|
});
|