@brainervirus/workit-claude-code 8.28.1 → 8.29.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 +78 -78
- package/dist/workit.js +251 -49
- package/package.json +3 -3
package/dist/workit.js
CHANGED
|
@@ -9144,12 +9144,15 @@ function sessionClaimRefusal(env, claimed, cwd, options = {}) {
|
|
|
9144
9144
|
};
|
|
9145
9145
|
if (real.kind === "none" || !real.session)
|
|
9146
9146
|
return null;
|
|
9147
|
-
const ownShell =
|
|
9148
|
-
if (ownShell)
|
|
9149
|
-
|
|
9147
|
+
const ownShell = isOwnShellClaim(real, claimed);
|
|
9148
|
+
if (ownShell) {
|
|
9149
|
+
if (!options.flag || real.kind === "derived")
|
|
9150
|
+
return null;
|
|
9151
|
+
return {
|
|
9150
9152
|
error: `session_flag: --session ${claimed} names this shell's own ${real.host} session; on a host only an issued subagent id is passed as --session`,
|
|
9151
9153
|
unblock: "drop --session: the shell's own session is already the acting one"
|
|
9152
|
-
}
|
|
9154
|
+
};
|
|
9155
|
+
}
|
|
9153
9156
|
const issuedClaim = claimed === real.session || claimed.startsWith(`${real.session}:`);
|
|
9154
9157
|
if (issuedClaim) {
|
|
9155
9158
|
const binding = issuedBinding(cwd, claimed);
|
|
@@ -9213,7 +9216,10 @@ var HOST_SESSION_VARS, family = (host) => host?.replace(/_(?:cli|desktop)$/, "")
|
|
|
9213
9216
|
} catch {
|
|
9214
9217
|
return { stored: null, leadBound: safeList(dir).length > 0 };
|
|
9215
9218
|
}
|
|
9216
|
-
}, leadOf = (session) => session.slice(0, session.lastIndexOf(":")), OWN_CHILD_SHELL,
|
|
9219
|
+
}, leadOf = (session) => session.slice(0, session.lastIndexOf(":")), OWN_CHILD_SHELL, isOwnShellClaim = (real, claimed) => claimed === real.session && !(real.kind === "declared" && claimed.includes(":")) || real.kind === "derived" && claimed.endsWith(`:${real.session}`), namesOwnDerivedSession = (env, claimed) => {
|
|
9220
|
+
const real = realHostSession(env);
|
|
9221
|
+
return real.kind === "derived" && isOwnShellClaim(real, claimed);
|
|
9222
|
+
}, HOST_SET_VARIABLE;
|
|
9217
9223
|
var init_host_session = __esm(() => {
|
|
9218
9224
|
init_branch();
|
|
9219
9225
|
init_logger();
|
|
@@ -9245,7 +9251,7 @@ var package_default;
|
|
|
9245
9251
|
var init_package = __esm(() => {
|
|
9246
9252
|
package_default = {
|
|
9247
9253
|
name: "@brainervirus/workit-cli",
|
|
9248
|
-
version: "8.
|
|
9254
|
+
version: "8.29.1",
|
|
9249
9255
|
private: false,
|
|
9250
9256
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
9251
9257
|
keywords: [
|
|
@@ -9283,13 +9289,13 @@ var init_package = __esm(() => {
|
|
|
9283
9289
|
},
|
|
9284
9290
|
dependencies: {
|
|
9285
9291
|
"@babel/parser": "7.29.9",
|
|
9286
|
-
"@brainervirus/workit-cursor": "^8.
|
|
9292
|
+
"@brainervirus/workit-cursor": "^8.29.1",
|
|
9287
9293
|
"@inkjs/ui": "2.0.0",
|
|
9288
9294
|
ink: "7.1.1",
|
|
9289
9295
|
react: "19.2.8"
|
|
9290
9296
|
},
|
|
9291
9297
|
devDependencies: {
|
|
9292
|
-
"@brainervirus/workit-core": "^8.
|
|
9298
|
+
"@brainervirus/workit-core": "^8.29.1"
|
|
9293
9299
|
},
|
|
9294
9300
|
engines: {
|
|
9295
9301
|
node: ">=24"
|
|
@@ -9403,9 +9409,22 @@ function detectedChecks(root) {
|
|
|
9403
9409
|
add(plain("test", ["make", "test"]));
|
|
9404
9410
|
return checks;
|
|
9405
9411
|
}
|
|
9412
|
+
function configFileFor(root) {
|
|
9413
|
+
const own = checksConfigFile(root);
|
|
9414
|
+
if (fs5.existsSync(own))
|
|
9415
|
+
return own;
|
|
9416
|
+
const common = git3(root, ["rev-parse", "--path-format=absolute", "--git-common-dir"]);
|
|
9417
|
+
if (!common || path9.basename(common) !== ".git")
|
|
9418
|
+
return own;
|
|
9419
|
+
const main = path9.dirname(common);
|
|
9420
|
+
if (path9.resolve(main) === path9.resolve(root))
|
|
9421
|
+
return own;
|
|
9422
|
+
const shared = checksConfigFile(main);
|
|
9423
|
+
return fs5.existsSync(shared) ? shared : own;
|
|
9424
|
+
}
|
|
9406
9425
|
function loadCheckConfig(cwd) {
|
|
9407
9426
|
const root = checkRoot(cwd);
|
|
9408
|
-
const file =
|
|
9427
|
+
const file = configFileFor(root);
|
|
9409
9428
|
const legacy = path9.basename(file) === LEGACY_CHECKS_FILE;
|
|
9410
9429
|
const label = legacy ? LEGACY_CHECKS_FILE : CHECKS_FILE;
|
|
9411
9430
|
const note = legacy ? {
|
|
@@ -18139,17 +18158,21 @@ function workitCheckTail(words) {
|
|
|
18139
18158
|
return null;
|
|
18140
18159
|
return args.slice(0, split).includes("--shell") ? { script: tail.join(" "), cwd } : { argv: tail, cwd };
|
|
18141
18160
|
}
|
|
18142
|
-
function simpleCommand(command, dialect = "posix", depth = 0) {
|
|
18161
|
+
function simpleCommand(command, dialect = "posix", depth = 0, shaped = false) {
|
|
18143
18162
|
let segments;
|
|
18144
18163
|
try {
|
|
18145
18164
|
segments = segmentsOf(command, dialect);
|
|
18146
18165
|
} catch {
|
|
18147
18166
|
return null;
|
|
18148
18167
|
}
|
|
18149
|
-
|
|
18168
|
+
const filter = shaped && segments.length === 2 ? segments[1] : null;
|
|
18169
|
+
if (filter) {
|
|
18170
|
+
if (!segments[0].pipe || !OUTPUT_FILTERS.has(commandName(filter.words[0])) || filter.group || filter.pipe || filter.unanalyzable || filter.subs?.length || filter.stdin?.length)
|
|
18171
|
+
return null;
|
|
18172
|
+
} else if (segments.length !== 1)
|
|
18150
18173
|
return null;
|
|
18151
18174
|
const [segment] = segments;
|
|
18152
|
-
if (segment.group || segment.pipe || segment.unanalyzable || segment.redirects.length || segment.subs?.length || segment.stdin?.length)
|
|
18175
|
+
if (segment.group || segment.pipe && !filter || segment.unanalyzable || segment.redirects.length && !shaped || segment.subs?.length || segment.stdin?.length)
|
|
18153
18176
|
return null;
|
|
18154
18177
|
const { words } = stripPrefixes(segment.words);
|
|
18155
18178
|
const name = commandName(words[0]);
|
|
@@ -18485,7 +18508,7 @@ var SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLARATIONS
|
|
|
18485
18508
|
...Object.keys(env).length ? { env } : {},
|
|
18486
18509
|
...stdin === undefined ? {} : { stdin }
|
|
18487
18510
|
};
|
|
18488
|
-
}, RECENT, LAUNCHERS, WORKIT_PACKAGE, PACKAGE_RUNNERS, WORKIT_GLOBAL, PUSH_VALUE_OPTIONS, VALUE_OPTIONS, API_VALUES, API_FIELDS, GIT_COMMANDS;
|
|
18511
|
+
}, RECENT, LAUNCHERS, WORKIT_PACKAGE, PACKAGE_RUNNERS, OUTPUT_FILTERS, WORKIT_GLOBAL, PUSH_VALUE_OPTIONS, VALUE_OPTIONS, API_VALUES, API_FIELDS, GIT_COMMANDS;
|
|
18489
18512
|
var init_raw_git = __esm(() => {
|
|
18490
18513
|
init_branch();
|
|
18491
18514
|
init_branch_policy();
|
|
@@ -18569,6 +18592,7 @@ var init_raw_git = __esm(() => {
|
|
|
18569
18592
|
]);
|
|
18570
18593
|
WORKIT_PACKAGE = /^@brainervirus\/workit-cli(?:@\S*)?$/;
|
|
18571
18594
|
PACKAGE_RUNNERS = new Set(["npx", "bunx", "pnpx"]);
|
|
18595
|
+
OUTPUT_FILTERS = new Set(["tail", "head", "grep"]);
|
|
18572
18596
|
WORKIT_GLOBAL = /^--(?:cwd|session|token|as)(=|$)/;
|
|
18573
18597
|
PUSH_VALUE_OPTIONS = new Set(["-o", "--push-option", "--receive-pack", "--exec", "--repo"]);
|
|
18574
18598
|
VALUE_OPTIONS = {
|
|
@@ -66801,7 +66825,7 @@ function permissionHealth(host, options = {}) {
|
|
|
66801
66825
|
detail: `${target.file} lacks ${missing.length} Workit entr${missing.length === 1 ? "y" : "ies"} (${missing[0]}${missing.length > 1 ? ", …" : ""})`
|
|
66802
66826
|
};
|
|
66803
66827
|
}
|
|
66804
|
-
var PERMISSION_HOSTS, CLAUDE_ALLOW, CLAUDE_ASK, AUTO_MODE_ENVIRONMENT = "Org-specific CLIs: workit — the user's delivery CLI. Its push, pr merge, release and PR-thread verbs run only under per-workspace grants and non-author verdicts the user configured in ~/.config/workit, outside the agent's reach.", AUTO_MODE_ALLOW = "Workit-gated delivery: `workit pr merge`, `workit git push --force-with-lease` on the session's own branch, `workit release` and `workit pr reply/resolve` on the session's repo are authorized by the user's standing Workit grants; not Merge Without Review, Git Destructive or External System Writes. Does NOT cover `--unverified`, `--admin` or any bypass flag.", DEFAULTS2 = "$defaults", CURSOR_ALLOW, CODEX_HEADER, codexRulesText = () => {
|
|
66828
|
+
var PERMISSION_HOSTS, CLAUDE_ALLOW, CLAUDE_ASK, AUTO_MODE_ENVIRONMENT = "Org-specific CLIs: workit — the user's delivery CLI. Its push, pr merge, release and PR-thread verbs run only under per-workspace grants and non-author verdicts the user configured in ~/.config/workit, outside the agent's reach.", AUTO_MODE_ALLOW = "Workit-gated delivery: `workit pr merge`, `workit git push --force-with-lease` on the session's own branch, `workit release` and `workit pr reply/resolve` on the session's repo are authorized by the user's standing Workit grants; not Merge Without Review, Git Destructive or External System Writes. Does NOT cover `--unverified`, `--admin` or any bypass flag.", DEFAULTS2 = "$defaults", CHECK_NAMES, LOCK_VERBS, LEASE_PREFIXES, CURSOR_ALLOW, CODEX_HEADER, codexRulesText = () => {
|
|
66805
66829
|
const rules = [...WORKIT_ALLOWED_VERBS, "--version"].map((verb) => {
|
|
66806
66830
|
const examples = verb === "git" ? `
|
|
66807
66831
|
match = [["workit", "git", "push", "--cwd", "/w"]],
|
|
@@ -66813,6 +66837,12 @@ var PERMISSION_HOSTS, CLAUDE_ALLOW, CLAUDE_ASK, AUTO_MODE_ENVIRONMENT = "Org-spe
|
|
|
66813
66837
|
)
|
|
66814
66838
|
`;
|
|
66815
66839
|
});
|
|
66840
|
+
const lease = LEASE_PREFIXES.map((rest) => `prefix_rule(
|
|
66841
|
+
pattern = ${JSON.stringify(["workit", ...rest])},
|
|
66842
|
+
decision = "allow",
|
|
66843
|
+
justification = "Workit heavy-check lease: runs the repo's configured check, or reads the lease",
|
|
66844
|
+
)
|
|
66845
|
+
`);
|
|
66816
66846
|
const grant = `prefix_rule(
|
|
66817
66847
|
pattern = ["workit", "grant"],
|
|
66818
66848
|
decision = "prompt",
|
|
@@ -66820,7 +66850,7 @@ var PERMISSION_HOSTS, CLAUDE_ALLOW, CLAUDE_ASK, AUTO_MODE_ENVIRONMENT = "Org-spe
|
|
|
66820
66850
|
)
|
|
66821
66851
|
`;
|
|
66822
66852
|
return `${CODEX_HEADER}
|
|
66823
|
-
${[...rules, grant].join(`
|
|
66853
|
+
${[...rules, ...lease, grant].join(`
|
|
66824
66854
|
`)}`;
|
|
66825
66855
|
}, isRecord5 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), emptyOwned = () => ({ lists: {}, created: [], env: {} }), clone4 = (value) => structuredClone(value), objectAt = (root, keys, owned) => {
|
|
66826
66856
|
let node = root;
|
|
@@ -66971,8 +67001,15 @@ var init_host_permissions = __esm(() => {
|
|
|
66971
67001
|
"Bash(workit * --unverified*)",
|
|
66972
67002
|
"Bash(workit * --overwrite-unintegrated*)"
|
|
66973
67003
|
];
|
|
67004
|
+
CHECK_NAMES = ["test", "lint", "typecheck", "build", "format", "docs"];
|
|
67005
|
+
LOCK_VERBS = ["status", "wait"];
|
|
67006
|
+
LEASE_PREFIXES = [
|
|
67007
|
+
...CHECK_NAMES.map((name) => ["check", name]),
|
|
67008
|
+
...LOCK_VERBS.map((verb) => ["lock", verb])
|
|
67009
|
+
];
|
|
66974
67010
|
CURSOR_ALLOW = [
|
|
66975
67011
|
...WORKIT_ALLOWED_VERBS.map((verb) => `Shell(workit ${verb})`),
|
|
67012
|
+
...LEASE_PREFIXES.map((rest) => `Shell(workit ${rest.join(" ")})`),
|
|
66976
67013
|
"Shell(workit --version)"
|
|
66977
67014
|
];
|
|
66978
67015
|
CODEX_HEADER = "# Workit-owned: written by `workit setup`, removed by `workit uninstall`.\n" + `# Workit's own grants, verdict gates and branch policy decide these verbs.
|
|
@@ -76211,7 +76248,7 @@ function heavyPlan(command, options) {
|
|
|
76211
76248
|
const heavy = heavyLines(lines, options);
|
|
76212
76249
|
if (!heavy.length)
|
|
76213
76250
|
return { kind: "none" };
|
|
76214
|
-
const simple = simpleCommand(command, dialect);
|
|
76251
|
+
const simple = simpleCommand(command, dialect, 0, true);
|
|
76215
76252
|
const single = simple && !WORKIT.test(baseName2(simple[0])) && heavyLines([simple], options)[0];
|
|
76216
76253
|
const judged = single ? [{ words: lines.flat(), text: command }] : heavy.map((match) => ({
|
|
76217
76254
|
words: match.line,
|
|
@@ -76223,7 +76260,7 @@ function heavyPlan(command, options) {
|
|
|
76223
76260
|
if (!verdict.ok)
|
|
76224
76261
|
return {
|
|
76225
76262
|
kind: "passthrough",
|
|
76226
|
-
note:
|
|
76263
|
+
note: ""
|
|
76227
76264
|
};
|
|
76228
76265
|
}
|
|
76229
76266
|
if (single) {
|
|
@@ -76233,7 +76270,7 @@ function heavyPlan(command, options) {
|
|
|
76233
76270
|
const parts = heavy.map((match) => leaseCommand(match.line));
|
|
76234
76271
|
return {
|
|
76235
76272
|
kind: "split",
|
|
76236
|
-
reason: `heavy_command: \`${command.trim()}\` chains heavy work (${heavy.map((match) => match.reason).join("; ")}) with other commands, and a chain cannot run under the machine-wide heavy-check lease. Run
|
|
76273
|
+
reason: `heavy_command: \`${command.trim()}\` chains heavy work (${heavy.map((match) => match.reason).join("; ")}) with other commands, and a chain cannot run under the machine-wide heavy-check lease. Run the heavy part alone, now: \`${parts[0]}\`; then run the other parts as their own commands${parts.length > 1 ? ", each heavy one the same way" : ""}.`,
|
|
76237
76274
|
unblock: parts[0] ?? null
|
|
76238
76275
|
};
|
|
76239
76276
|
}
|
|
@@ -76836,6 +76873,8 @@ var init_resources = __esm(() => {
|
|
|
76836
76873
|
// packages/workit-cli/src/verbs/check.ts
|
|
76837
76874
|
var exports_check = {};
|
|
76838
76875
|
__export(exports_check, {
|
|
76876
|
+
OUTPUT_LINES: () => OUTPUT_LINES,
|
|
76877
|
+
boundedOutput: () => boundedOutput,
|
|
76839
76878
|
hostToolWaitCapMs: () => hostToolWaitCapMs,
|
|
76840
76879
|
run: () => run11,
|
|
76841
76880
|
workspaceResources: () => workspaceResources
|
|
@@ -76849,6 +76888,7 @@ function parse6(argv) {
|
|
|
76849
76888
|
name: null,
|
|
76850
76889
|
shell: false,
|
|
76851
76890
|
heavy: false,
|
|
76891
|
+
full: false,
|
|
76852
76892
|
noLease: false,
|
|
76853
76893
|
reason: null,
|
|
76854
76894
|
waitMs: null,
|
|
@@ -76867,8 +76907,11 @@ function parse6(argv) {
|
|
|
76867
76907
|
};
|
|
76868
76908
|
if (flag === "--json")
|
|
76869
76909
|
continue;
|
|
76870
|
-
if (flag === "--shell") {
|
|
76871
|
-
|
|
76910
|
+
if (flag === "--shell" || flag === "--full") {
|
|
76911
|
+
if (flag === "--shell")
|
|
76912
|
+
options.shell = true;
|
|
76913
|
+
else
|
|
76914
|
+
options.full = true;
|
|
76872
76915
|
continue;
|
|
76873
76916
|
}
|
|
76874
76917
|
if (flag === "--heavy" || flag === "--no-lease") {
|
|
@@ -77016,6 +77059,17 @@ function boundedArgv(argv) {
|
|
|
77016
77059
|
const truncated = cut.length !== argv.length || cut.some((item, index) => item !== argv[index]);
|
|
77017
77060
|
return { argv: cut, truncated };
|
|
77018
77061
|
}
|
|
77062
|
+
function boundedOutput(log, lines) {
|
|
77063
|
+
const all = tailLines(log, Number.MAX_SAFE_INTEGER);
|
|
77064
|
+
if (all.length === 0)
|
|
77065
|
+
return "";
|
|
77066
|
+
const shown = all.slice(-lines);
|
|
77067
|
+
const omitted = all.length - shown.length;
|
|
77068
|
+
return `${omitted ? `… ${omitted} earlier line${omitted === 1 ? "" : "s"} omitted (the full log is named below; --full streams it)
|
|
77069
|
+
` : ""}${shown.join(`
|
|
77070
|
+
`)}
|
|
77071
|
+
`;
|
|
77072
|
+
}
|
|
77019
77073
|
function hostToolWaitCapMs(env) {
|
|
77020
77074
|
if (!env.CLAUDECODE && !env.OPENCODE && !env.OPENCODE_SESSION_ID)
|
|
77021
77075
|
return null;
|
|
@@ -77145,6 +77199,10 @@ async function run11(argv, io) {
|
|
|
77145
77199
|
}
|
|
77146
77200
|
const relCwd = posix(path49.relative(top, runCwd));
|
|
77147
77201
|
const configured = !options.shell && matchesNamedCheck(config, name, command, relCwd);
|
|
77202
|
+
const shadowed = !configured && name !== null ? config.checks.find((item) => item.name === name) : undefined;
|
|
77203
|
+
if (shadowed)
|
|
77204
|
+
io.stderr(`note: "${name}" is configured as \`${shadowed.argv.join(" ")}\`; this ad-hoc run does not satisfy a configured gate (run workit check ${name})
|
|
77205
|
+
`);
|
|
77148
77206
|
const actor = actorFromEnv(io.env);
|
|
77149
77207
|
const branchKey = codeKey(io.cwd, { base: options.base });
|
|
77150
77208
|
const detached = branchKey.tree === null ? worktreeTree(io.cwd) : null;
|
|
@@ -77187,7 +77245,7 @@ async function run11(argv, io) {
|
|
|
77187
77245
|
...sinks,
|
|
77188
77246
|
...wrapper ? { wrapper } : {},
|
|
77189
77247
|
...lease ? { onSpawn: (pid) => updateLease(lease, { pgid: pid }) } : {}
|
|
77190
|
-
}), heavy?.wrapper ?? null, { onStdout: io.json ? io.stderr : io.stdout, onStderr: io.stderr });
|
|
77248
|
+
}), heavy?.wrapper ?? null, options.full ? { onStdout: io.json ? io.stderr : io.stdout, onStderr: io.stderr } : { onStdout: () => {}, onStderr: () => {} });
|
|
77191
77249
|
result = scoped.result;
|
|
77192
77250
|
if (heavy && scoped.fallback) {
|
|
77193
77251
|
io.stderr(`workit: the memory/CPU scope could not start (${scoped.fallback}); ran without it
|
|
@@ -77201,6 +77259,7 @@ async function run11(argv, io) {
|
|
|
77201
77259
|
const modifiedWorktree = key.tree !== null && treeAfter !== key.tree;
|
|
77202
77260
|
const store = storeRoot(io.cwd);
|
|
77203
77261
|
const blob = store.ok ? storeLog(store.value.root, result.log) : null;
|
|
77262
|
+
const logPath = store.ok && blob ? path49.join(store.value.root, blob.ref) : null;
|
|
77204
77263
|
const tail = tailLines(result.log, TAIL_LINES);
|
|
77205
77264
|
const passed = result.exitCode === 0 && !result.timedOut;
|
|
77206
77265
|
const bounded = boundedArgv(command);
|
|
@@ -77273,6 +77332,7 @@ async function run11(argv, io) {
|
|
|
77273
77332
|
patchId: key.patchId,
|
|
77274
77333
|
logDigest: observation.logDigest,
|
|
77275
77334
|
logRef: observation.logRef,
|
|
77335
|
+
logPath,
|
|
77276
77336
|
logTail: tail,
|
|
77277
77337
|
outputBytes: result.outputBytes,
|
|
77278
77338
|
logTruncated: result.truncated,
|
|
@@ -77289,18 +77349,21 @@ async function run11(argv, io) {
|
|
|
77289
77349
|
const code = !passed ? "failed" : recordError ? recordError.code : "ok";
|
|
77290
77350
|
const error = !passed ? result.timedOut ? `timed out after ${options.timeoutMs} ms` : result.spawnError ? `cannot start ${command[0]}: ${result.spawnError}` : `exited ${result.exitCode}` : recordError?.message;
|
|
77291
77351
|
const label = name ?? command.join(" ");
|
|
77292
|
-
const summary = `workit check ${label}: ${passed ? "passed" : error ?? "failed"} in ${result.durationMs} ms (${configured ? "configured" : "ad-hoc"}${name && !configured && config.checks.some((item) => item.name === name) ? `; not the configured command for "${name}"` : ""}); ${task.evidenceId ? `evidence ${task.evidenceId} on task ${task.task?.id}` : task.note ?? (task.error ? `task: ${task.error.message}` : "ledger only")}
|
|
77352
|
+
const summary = `workit check ${label}: ${passed ? "passed, exit 0" : error ?? "failed"} in ${result.durationMs} ms (${configured ? "configured" : "ad-hoc"}${name && !configured && config.checks.some((item) => item.name === name) ? `; not the configured command for "${name}"` : ""}); ${task.evidenceId ? `evidence ${task.evidenceId} on task ${task.task?.id}` : task.note ?? (task.error ? `task: ${task.error.message}` : "ledger only")}; log: ${logPath ?? "not stored"}`;
|
|
77293
77353
|
if (io.json)
|
|
77294
77354
|
io.stdout(`${JSON.stringify({ ok: code === "ok", code, data, ...error ? { error } : {}, ...task.stillUnsatisfied[0] ? { unblock: task.stillUnsatisfied[0].unblock } : {} })}
|
|
77295
77355
|
`);
|
|
77296
77356
|
else {
|
|
77357
|
+
if (!options.full)
|
|
77358
|
+
io.stdout(boundedOutput(result.log, OUTPUT_LINES));
|
|
77297
77359
|
io.stderr(`${summary}
|
|
77298
77360
|
`);
|
|
77299
77361
|
if (recordError && passed)
|
|
77300
77362
|
io.stderr(`workit: ${recordError.message}
|
|
77301
77363
|
`);
|
|
77302
|
-
|
|
77303
|
-
|
|
77364
|
+
if (!shadowed)
|
|
77365
|
+
for (const gap of task.stillUnsatisfied)
|
|
77366
|
+
io.stderr(` still unsatisfied: ${gap.ruleId}: ${gap.reason}
|
|
77304
77367
|
`);
|
|
77305
77368
|
}
|
|
77306
77369
|
if (!passed)
|
|
@@ -77309,7 +77372,7 @@ async function run11(argv, io) {
|
|
|
77309
77372
|
return recordError.code === "busy" ? 4 : recordError.code === "invalid_input" ? 2 : 5;
|
|
77310
77373
|
return 0;
|
|
77311
77374
|
}
|
|
77312
|
-
var USAGE4 = 'workit check <name> [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--wait <s>] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(path49.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, HOST_TOOL_WAIT_CAP_MS = 1e5;
|
|
77375
|
+
var USAGE4 = 'workit check <name> [--full] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <s>] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', OUTPUT_LINES = 60, MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(path49.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, HOST_TOOL_WAIT_CAP_MS = 1e5;
|
|
77313
77376
|
var init_check = __esm(() => {
|
|
77314
77377
|
init_check_config();
|
|
77315
77378
|
init_checks3();
|
|
@@ -78578,18 +78641,18 @@ var COMMIT_TIMEOUT_MS, PUSH_TIMEOUT_MS = 120000, git5 = (cwd, args, options = {}
|
|
|
78578
78641
|
const lines = redactText(`${run.stderr}
|
|
78579
78642
|
${run.stdout ?? ""}`).split(/\r?\n/u).map((value) => value.trim()).filter((value) => value && !value.startsWith("hint:"));
|
|
78580
78643
|
return lines.slice(-max).join(" / ").slice(0, 400) || "git failed";
|
|
78581
|
-
},
|
|
78644
|
+
}, OUTPUT_LINES2 = 200, OUTPUT_LINE_CHARS = 1000, gitOutput = (run) => {
|
|
78582
78645
|
const lines = redactText(`${run.stderr}
|
|
78583
78646
|
${run.stdout ?? ""}`).split(/\r?\n/u).map((value) => value.trimEnd()).filter((value) => value.trim() && !value.trimStart().startsWith("hint:")).map((value) => value.length > OUTPUT_LINE_CHARS ? `${value.slice(0, OUTPUT_LINE_CHARS)}…` : value);
|
|
78584
78647
|
if (!lines.length)
|
|
78585
78648
|
return "git failed";
|
|
78586
|
-
if (lines.length <=
|
|
78649
|
+
if (lines.length <= OUTPUT_LINES2)
|
|
78587
78650
|
return lines.join(`
|
|
78588
78651
|
`);
|
|
78589
|
-
const half =
|
|
78652
|
+
const half = OUTPUT_LINES2 / 2;
|
|
78590
78653
|
return [
|
|
78591
78654
|
...lines.slice(0, half),
|
|
78592
|
-
`… ${lines.length -
|
|
78655
|
+
`… ${lines.length - OUTPUT_LINES2} lines omitted …`,
|
|
78593
78656
|
...lines.slice(-half)
|
|
78594
78657
|
].join(`
|
|
78595
78658
|
`);
|
|
@@ -84336,16 +84399,66 @@ async function rerun(argv, io) {
|
|
|
84336
84399
|
"next: workit ci wait"
|
|
84337
84400
|
]);
|
|
84338
84401
|
}
|
|
84402
|
+
async function logs(argv, io) {
|
|
84403
|
+
const flags = parseFlags(argv, { pr: "value", branch: "value", failed: "boolean" });
|
|
84404
|
+
if (typeof flags === "string")
|
|
84405
|
+
return usage3(io, flags, LOGS_USAGE);
|
|
84406
|
+
if (flags.positionals.length)
|
|
84407
|
+
return usage3(io, `unexpected argument ${flags.positionals[0]}`, LOGS_USAGE);
|
|
84408
|
+
if (!flags.booleans.has("failed"))
|
|
84409
|
+
return usage3(io, "pass --failed: only the failing steps' tails are printed", LOGS_USAGE);
|
|
84410
|
+
const pr = positiveInt(flags.values.pr, "--pr");
|
|
84411
|
+
if (typeof pr === "string")
|
|
84412
|
+
return usage3(io, pr, LOGS_USAGE);
|
|
84413
|
+
if (pr && flags.values.branch)
|
|
84414
|
+
return usage3(io, "pass --pr or --branch, not both", LOGS_USAGE);
|
|
84415
|
+
const connected = connect(io, flags.values.branch);
|
|
84416
|
+
if (!connected.ok)
|
|
84417
|
+
return forgeFail(io, connected);
|
|
84418
|
+
const resolved = connected.data;
|
|
84419
|
+
const number = selectPr(io.cwd, resolved, { pr, branch: flags.values.branch ?? null });
|
|
84420
|
+
if (!number.ok)
|
|
84421
|
+
return forgeFail(io, number);
|
|
84422
|
+
const status = resolved.forge.prStatus(number.data);
|
|
84423
|
+
if (!status.ok)
|
|
84424
|
+
return forgeFail(io, status);
|
|
84425
|
+
const doc = buildStatusDoc(io.cwd, resolved, status.data, { logLines: LOG_LINES, behind: false });
|
|
84426
|
+
if (!doc.ok)
|
|
84427
|
+
return forgeFail(io, doc);
|
|
84428
|
+
const data = {
|
|
84429
|
+
pr: doc.data.number,
|
|
84430
|
+
head: status.data.head.sha,
|
|
84431
|
+
failing: doc.data.checks.failing.map((check) => ({
|
|
84432
|
+
name: check.name,
|
|
84433
|
+
url: check.url,
|
|
84434
|
+
conclusion: check.conclusion,
|
|
84435
|
+
logTail: check.logTail,
|
|
84436
|
+
...check.logError ? { logError: check.logError } : {}
|
|
84437
|
+
}))
|
|
84438
|
+
};
|
|
84439
|
+
return emit(io, ok2(data), () => data.failing.length ? [
|
|
84440
|
+
`PR #${data.pr} head ${data.head.slice(0, 7)}: ${data.failing.length} failing check${data.failing.length === 1 ? "" : "s"} (last ${LOG_LINES} log lines each)`,
|
|
84441
|
+
...data.failing.flatMap((check) => [
|
|
84442
|
+
`x ${check.name}${check.conclusion ? ` (${check.conclusion})` : ""}${check.url ? ` ${check.url}` : ""}`,
|
|
84443
|
+
...check.logTail.length ? check.logTail.map((line) => ` ${line}`) : [
|
|
84444
|
+
` (no log: ${check.logError ?? "not an Actions job, or beyond the tails fetched"})`
|
|
84445
|
+
]
|
|
84446
|
+
])
|
|
84447
|
+
] : [`PR #${data.pr} head ${data.head.slice(0, 7)}: no failing checks`]);
|
|
84448
|
+
}
|
|
84339
84449
|
async function run15(argv, io) {
|
|
84340
84450
|
const [sub, ...rest] = argv;
|
|
84341
84451
|
if (sub === "wait")
|
|
84342
84452
|
return wait2(rest, io);
|
|
84343
84453
|
if (sub === "rerun")
|
|
84344
84454
|
return rerun(rest, io);
|
|
84455
|
+
if (sub === "logs")
|
|
84456
|
+
return logs(rest, io);
|
|
84345
84457
|
return usage3(io, sub && !sub.startsWith("-") ? `unknown ci subcommand "${sub}"` : "missing ci subcommand", `${WAIT_USAGE}
|
|
84346
|
-
${RERUN_USAGE}
|
|
84458
|
+
${RERUN_USAGE}
|
|
84459
|
+
${LOGS_USAGE}`);
|
|
84347
84460
|
}
|
|
84348
|
-
var WAIT_USAGE = "workit ci wait [--pr <n> | --branch <b>] [--head <sha>] [--timeout 20m] [--interval 30s] [--json]", RERUN_USAGE = "workit ci rerun [--pr <n> | --branch <b>] [--check <name>… | --failed] --reason flake|infra [--force] [--json]", ONE_POLL_MS = 20000, MAX_POLL_ERRORS = 3, seconds = (ms) => `${Math.round(ms / 1000)}s`;
|
|
84461
|
+
var WAIT_USAGE = "workit ci wait [--pr <n> | --branch <b>] [--head <sha>] [--timeout 20m] [--interval 30s] [--json]", RERUN_USAGE = "workit ci rerun [--pr <n> | --branch <b>] [--check <name>… | --failed] --reason flake|infra [--force] [--json]", LOGS_USAGE = "workit ci logs --failed [--pr <n> | --branch <b>] [--json]", LOG_LINES = 60, ONE_POLL_MS = 20000, MAX_POLL_ERRORS = 3, seconds = (ms) => `${Math.round(ms / 1000)}s`;
|
|
84349
84462
|
var init_ci = __esm(() => {
|
|
84350
84463
|
init_report();
|
|
84351
84464
|
init_ledger();
|
|
@@ -86179,6 +86292,27 @@ function excludeScratch(cwd) {
|
|
|
86179
86292
|
${EXCLUDE_LINE}
|
|
86180
86293
|
`);
|
|
86181
86294
|
}
|
|
86295
|
+
function worktreeDependencies(main, worktree) {
|
|
86296
|
+
for (const [name, install] of LOCKFILES2) {
|
|
86297
|
+
const ours = readBytes(path62.join(main, name));
|
|
86298
|
+
const theirs = readBytes(path62.join(worktree, name));
|
|
86299
|
+
if (ours === null && theirs === null)
|
|
86300
|
+
continue;
|
|
86301
|
+
if (ours !== null && theirs !== null && ours.equals(theirs))
|
|
86302
|
+
continue;
|
|
86303
|
+
if (fs33.existsSync(path62.join(worktree, "node_modules")))
|
|
86304
|
+
break;
|
|
86305
|
+
const command = install(worktree);
|
|
86306
|
+
return {
|
|
86307
|
+
linked: null,
|
|
86308
|
+
install: command,
|
|
86309
|
+
notes: [
|
|
86310
|
+
`${name} differs from the main checkout's (${main}), so its node_modules was not linked; install dependencies first: ${command}`
|
|
86311
|
+
]
|
|
86312
|
+
};
|
|
86313
|
+
}
|
|
86314
|
+
return { ...linkWorktreeDependencies(main, worktree), install: null };
|
|
86315
|
+
}
|
|
86182
86316
|
function ensureScratch(worktree) {
|
|
86183
86317
|
const scratch = path62.join(worktree, SCRATCH_DIR);
|
|
86184
86318
|
fs33.mkdirSync(scratch, { recursive: true });
|
|
@@ -86208,7 +86342,7 @@ function createSliceWorktree(cwd, plan, input) {
|
|
|
86208
86342
|
if (!createdRow(cwd, plan, slice, target))
|
|
86209
86343
|
return fanoutFail("blocked", `${target} is a worktree that workit fanout worktree create did not make for slice ${slice.id}`, `remove it yourself (git worktree remove ${target}) once you know what it holds`);
|
|
86210
86344
|
excludeScratch(cwd);
|
|
86211
|
-
const deps =
|
|
86345
|
+
const deps = worktreeDependencies(mainCheckout(cwd), target);
|
|
86212
86346
|
return {
|
|
86213
86347
|
ok: true,
|
|
86214
86348
|
data: {
|
|
@@ -86218,6 +86352,7 @@ function createSliceWorktree(cwd, plan, input) {
|
|
|
86218
86352
|
mode: resolveRef(cwd, localRef) ? "resume" : "new",
|
|
86219
86353
|
created: false,
|
|
86220
86354
|
dependencies: deps.linked,
|
|
86355
|
+
install: deps.install,
|
|
86221
86356
|
notes: [
|
|
86222
86357
|
deps.linked ? "the worktree already exists; only its missing dependencies were linked" : "the worktree already exists; nothing was changed",
|
|
86223
86358
|
...deps.notes
|
|
@@ -86271,7 +86406,7 @@ function createSliceWorktree(cwd, plan, input) {
|
|
|
86271
86406
|
}
|
|
86272
86407
|
excludeScratch(cwd);
|
|
86273
86408
|
const scratch = ensureScratch(target);
|
|
86274
|
-
const deps =
|
|
86409
|
+
const deps = worktreeDependencies(mainCheckout(cwd), target);
|
|
86275
86410
|
notes.push(...deps.notes);
|
|
86276
86411
|
const head = gitRun4(target, ["rev-parse", "HEAD"]).stdout.trim();
|
|
86277
86412
|
const baseSha = mode === "new" ? head : null;
|
|
@@ -86294,7 +86429,16 @@ function createSliceWorktree(cwd, plan, input) {
|
|
|
86294
86429
|
});
|
|
86295
86430
|
return {
|
|
86296
86431
|
ok: true,
|
|
86297
|
-
data: {
|
|
86432
|
+
data: {
|
|
86433
|
+
...base,
|
|
86434
|
+
scratch,
|
|
86435
|
+
head,
|
|
86436
|
+
mode,
|
|
86437
|
+
created: true,
|
|
86438
|
+
dependencies: deps.linked,
|
|
86439
|
+
install: deps.install,
|
|
86440
|
+
notes
|
|
86441
|
+
}
|
|
86298
86442
|
};
|
|
86299
86443
|
}
|
|
86300
86444
|
function releaseSliceWorktree(cwd, plan, input) {
|
|
@@ -86433,7 +86577,13 @@ var SLOW, SCRATCH_DIR = ".workit-scratch", EXCLUDE_LINE, DIRTY_ROW_BYTES = 2000,
|
|
|
86433
86577
|
}, inside3 = (child, parent) => {
|
|
86434
86578
|
const relative = path62.relative(canonical2(parent), canonical2(child));
|
|
86435
86579
|
return relative === "" || !relative.startsWith("..") && !path62.isAbsolute(relative);
|
|
86436
|
-
}, slicePath = (cwd, slice) => path62.isAbsolute(slice.worktree) ? slice.worktree : path62.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps,
|
|
86580
|
+
}, slicePath = (cwd, slice) => path62.isAbsolute(slice.worktree) ? slice.worktree : path62.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, LOCKFILES2, readBytes = (file) => {
|
|
86581
|
+
try {
|
|
86582
|
+
return fs33.readFileSync(file);
|
|
86583
|
+
} catch {
|
|
86584
|
+
return null;
|
|
86585
|
+
}
|
|
86586
|
+
}, worktreeFailed = (stderr) => fanoutFail("failed", `git worktree add failed: ${stderr.trim().split(`
|
|
86437
86587
|
`)[0] || "unknown error"}`);
|
|
86438
86588
|
var init_fanout_worktree = __esm(() => {
|
|
86439
86589
|
init_ops();
|
|
@@ -86447,6 +86597,13 @@ var init_fanout_worktree = __esm(() => {
|
|
|
86447
86597
|
worktreeDeps = {
|
|
86448
86598
|
stat: (file) => fs33.statSync(file, { bigint: true })
|
|
86449
86599
|
};
|
|
86600
|
+
LOCKFILES2 = [
|
|
86601
|
+
["bun.lock", (dir) => `bun install --frozen-lockfile --cwd ${dir}`],
|
|
86602
|
+
["bun.lockb", (dir) => `bun install --frozen-lockfile --cwd ${dir}`],
|
|
86603
|
+
["pnpm-lock.yaml", (dir) => `pnpm install --frozen-lockfile --dir ${dir}`],
|
|
86604
|
+
["yarn.lock", (dir) => `yarn install --frozen-lockfile --cwd ${dir}`],
|
|
86605
|
+
["package-lock.json", (dir) => `npm ci --prefix ${dir}`]
|
|
86606
|
+
];
|
|
86450
86607
|
});
|
|
86451
86608
|
|
|
86452
86609
|
// packages/workit-core/src/fanout-brief.ts
|
|
@@ -87805,6 +87962,8 @@ var USAGE13 = "workit ledger decision|ruling|verdict|standing|list|check ... (wo
|
|
|
87805
87962
|
if (values.session !== undefined) {
|
|
87806
87963
|
if (!SESSION_SAFE2.test(values.session))
|
|
87807
87964
|
return new Error("--session must be 1-128 characters of [A-Za-z0-9_.:@/+-]");
|
|
87965
|
+
if (namesOwnDerivedSession(io.env, values.session))
|
|
87966
|
+
return { actor, source: "env" };
|
|
87808
87967
|
return { actor: { ...actor, session: values.session }, source: "flag" };
|
|
87809
87968
|
}
|
|
87810
87969
|
if (values.as !== undefined) {
|
|
@@ -104787,10 +104946,13 @@ var init_changelog2 = __esm(() => {
|
|
|
104787
104946
|
// packages/workit-cli/src/verbs/handoff.ts
|
|
104788
104947
|
var exports_handoff = {};
|
|
104789
104948
|
__export(exports_handoff, {
|
|
104949
|
+
MAX_BRIEF_BYTES: () => MAX_BRIEF_BYTES,
|
|
104790
104950
|
run: () => run26
|
|
104791
104951
|
});
|
|
104952
|
+
import fs35 from "node:fs";
|
|
104953
|
+
import path70 from "node:path";
|
|
104792
104954
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
104793
|
-
function
|
|
104955
|
+
function render3(brief) {
|
|
104794
104956
|
const lines = [
|
|
104795
104957
|
`branch: ${brief.branch ?? "(detached)"} @ ${short7(brief.head)}${brief.subject ? ` ${brief.subject}` : ""}`
|
|
104796
104958
|
];
|
|
@@ -104810,14 +104972,42 @@ function human2(brief) {
|
|
|
104810
104972
|
lines.push(`last handoff (${brief.lastHandoff.at}): ${brief.lastHandoff.next}${brief.lastHandoff.note ? ` (note: ${brief.lastHandoff.note})` : ""}`);
|
|
104811
104973
|
if (brief.recent.length)
|
|
104812
104974
|
lines.push("recent ledger:", ...brief.recent.map((row) => ` #${row.seq} ${row.type}${row.branch ? ` [${row.branch}]` : ""}${row.labels.length ? ` (${row.labels.join(", ")})` : ""} ${row.summary}`));
|
|
104975
|
+
const tail = [];
|
|
104813
104976
|
if (brief.note)
|
|
104814
|
-
|
|
104815
|
-
|
|
104977
|
+
tail.push(`note: ${brief.note}`);
|
|
104978
|
+
tail.push(`next: ${brief.next}`);
|
|
104816
104979
|
if (brief.next !== brief.nextCommand)
|
|
104817
|
-
|
|
104980
|
+
tail.push(`next command: ${brief.nextCommand}`);
|
|
104818
104981
|
if (brief.recorded)
|
|
104819
|
-
|
|
104820
|
-
return lines;
|
|
104982
|
+
tail.push(`recorded handoff ${brief.recorded}`);
|
|
104983
|
+
return { body: lines, tail };
|
|
104984
|
+
}
|
|
104985
|
+
function bounded(brief, cwd) {
|
|
104986
|
+
const { body, tail } = render3(brief);
|
|
104987
|
+
if (bytes([...body, ...tail]) <= MAX_BRIEF_BYTES)
|
|
104988
|
+
return [...body, ...tail];
|
|
104989
|
+
const store = storeRoot(cwd);
|
|
104990
|
+
let file = null;
|
|
104991
|
+
if (store.ok)
|
|
104992
|
+
try {
|
|
104993
|
+
const dir = path70.join(store.value.root, "handoff");
|
|
104994
|
+
fs35.mkdirSync(dir, { recursive: true });
|
|
104995
|
+
file = path70.join(dir, `${(brief.branch ?? "detached").replaceAll(/[^\w.-]+/gu, "-")}.txt`);
|
|
104996
|
+
fs35.writeFileSync(file, `${[...body, ...tail].join(`
|
|
104997
|
+
`)}
|
|
104998
|
+
`, { mode: 384 });
|
|
104999
|
+
} catch {
|
|
105000
|
+
file = null;
|
|
105001
|
+
}
|
|
105002
|
+
const pointer = `… cut to ${MAX_BRIEF_BYTES} bytes; full brief: ${file ?? "not written (workit handoff --json has it all)"}`;
|
|
105003
|
+
const kept = [];
|
|
105004
|
+
for (const line of body) {
|
|
105005
|
+
const cut = line.length > 400 ? `${line.slice(0, 400)}…` : line;
|
|
105006
|
+
if (bytes([...kept, cut, pointer, ...tail]) > MAX_BRIEF_BYTES)
|
|
105007
|
+
break;
|
|
105008
|
+
kept.push(cut);
|
|
105009
|
+
}
|
|
105010
|
+
return [...kept, pointer, ...tail];
|
|
104821
105011
|
}
|
|
104822
105012
|
async function resumeBrief(argv, io) {
|
|
104823
105013
|
let values;
|
|
@@ -104855,7 +105045,7 @@ async function resumeBrief(argv, io) {
|
|
|
104855
105045
|
return emit(io, fail2(row.code, row.error, { data: { ...data, recorded } }));
|
|
104856
105046
|
recorded = row.value.id;
|
|
104857
105047
|
}
|
|
104858
|
-
return emit(io, ok2({ ...data, recorded }),
|
|
105048
|
+
return emit(io, ok2({ ...data, recorded }), (brief) => bounded(brief, io.cwd));
|
|
104859
105049
|
}
|
|
104860
105050
|
async function run26(argv, io) {
|
|
104861
105051
|
if (!argv.some((arg) => arg === "--task" || arg.startsWith("--task=")))
|
|
@@ -104863,7 +105053,9 @@ async function run26(argv, io) {
|
|
|
104863
105053
|
await Promise.resolve().then(() => init_task());
|
|
104864
105054
|
return runTaskCommand(["handoff", ...argv]);
|
|
104865
105055
|
}
|
|
104866
|
-
var USAGE18 = "workit handoff [--note <text>] [--next <text>] [--record] [--last <n>] [--json]", short7 = (sha) => sha ? sha.slice(0, 12) : "no commit"
|
|
105056
|
+
var USAGE18 = "workit handoff [--note <text>] [--next <text>] [--record] [--last <n>] [--json]", MAX_BRIEF_BYTES = 4096, short7 = (sha) => sha ? sha.slice(0, 12) : "no commit", bytes = (lines) => Buffer.byteLength(`${lines.join(`
|
|
105057
|
+
`)}
|
|
105058
|
+
`);
|
|
104867
105059
|
var init_handoff = __esm(() => {
|
|
104868
105060
|
init_ledger();
|
|
104869
105061
|
init_output();
|
|
@@ -104872,7 +105064,7 @@ var init_handoff = __esm(() => {
|
|
|
104872
105064
|
// packages/workit-cli/src/main.ts
|
|
104873
105065
|
init_host_session();
|
|
104874
105066
|
init_package();
|
|
104875
|
-
import
|
|
105067
|
+
import path71 from "node:path";
|
|
104876
105068
|
|
|
104877
105069
|
// packages/workit-cli/src/verbs/registry.ts
|
|
104878
105070
|
var TASK_FAMILY_NAMES = [
|
|
@@ -104977,7 +105169,8 @@ var LEASE_NOTES = [
|
|
|
104977
105169
|
"The heavy-check lease: heavy work (tests, builds, lint, typecheck, installs, image builds) shares one machine-wide lease, so parallel agents and worktrees never exhaust this machine's memory and CPU. `slots` (default 1) heavy checks run at once; on Linux each also runs in a systemd scope with MemoryMax and CPUQuota.",
|
|
104978
105170
|
"Waiting: a heavy check that finds every slot held prints one `waiting for the heavy-check lease` line naming the holder (check, pid, session, age, directory), polls once a second, and exits 4 (busy) after `--wait <s>`, else `resources.wait` seconds (default 600, capped at 100 inside a Claude Code or OpenCode shell). `workit lock status` shows the holders; `workit lock wait` waits for a free slot.",
|
|
104979
105171
|
"--heavy: an ad-hoc `workit check -- <cmd>` takes the lease only with --heavy; the named checks test, build and typecheck always do. The shell hook runs a raw heavy command (`npx jest`, `npm run test:ci`, `cargo test`, `docker build`) as `workit check --heavy -- <cmd>` on Claude Code, OpenCode and Pi, and denies it with that exact command on Codex and Cursor.",
|
|
104980
|
-
'--no-lease skips the lease and needs --reason "<why>". Never hand-roll a flock: the lease already queues every agent on the machine.'
|
|
105172
|
+
'--no-lease skips the lease and needs --reason "<why>". Never hand-roll a flock: the lease already queues every agent on the machine.',
|
|
105173
|
+
"Output: a check prints the last 60 lines of its output and one summary line with `log: <path>` to the full log; --full streams all of it."
|
|
104981
105174
|
];
|
|
104982
105175
|
var VERIFY_OPTIONS = "[--expect pushed|pr|merged|released] [--pr <n> | --branch <b>] [--sha <sha>] [--tag <t>] [--package <name[@version]>]";
|
|
104983
105176
|
var LEDGER_ACTOR = "[--branch <b> | --pr <n>] [--supersedes <id>] [--session <id> [--token <t>] | --as <role>]";
|
|
@@ -105060,7 +105253,7 @@ var VERBS = [
|
|
|
105060
105253
|
{
|
|
105061
105254
|
name: "check",
|
|
105062
105255
|
group: "delivery",
|
|
105063
|
-
usage: 'workit check <name> [--task <id>] [--base <ref>] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--timeout <s>] [--task <id>] [--base <ref>] [--heavy [--wait <s>]] [--no-lease --reason "<why>"] -- <cmd…>',
|
|
105256
|
+
usage: 'workit check <name> [--full] [--task <id>] [--base <ref>] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--full] [--timeout <s>] [--task <id>] [--base <ref>] [--heavy [--wait <s>]] [--no-lease --reason "<why>"] -- <cmd…>',
|
|
105064
105257
|
flagHints: {
|
|
105065
105258
|
list: "workit check <name> runs a configured check; a name that is not configured prints the valid ones (workit check test|lint|typecheck|check)"
|
|
105066
105259
|
},
|
|
@@ -105180,7 +105373,7 @@ var VERBS = [
|
|
|
105180
105373
|
withSubcommands({
|
|
105181
105374
|
name: "ci",
|
|
105182
105375
|
group: "delivery",
|
|
105183
|
-
summary: "Wait for CI on the PR head (exit 0/1/3/4), or rerun failed jobs once per head",
|
|
105376
|
+
summary: "Wait for CI on the PR head (exit 0/1/3/4), read the failing jobs' log tails, or rerun failed jobs once per head",
|
|
105184
105377
|
subcommands: [
|
|
105185
105378
|
{
|
|
105186
105379
|
name: "wait",
|
|
@@ -105191,9 +105384,18 @@ var VERBS = [
|
|
|
105191
105384
|
name: "rerun",
|
|
105192
105385
|
usage: "workit ci rerun [--pr <n> | --branch <b>] [--check <name>… | --failed] --reason flake|infra [--force]",
|
|
105193
105386
|
summary: "Rerun failed jobs once per head, with a recorded reason"
|
|
105387
|
+
},
|
|
105388
|
+
{
|
|
105389
|
+
name: "logs",
|
|
105390
|
+
usage: "workit ci logs --failed [--pr <n> | --branch <b>]",
|
|
105391
|
+
summary: "The failing checks of the PR head, each with its job log's last 60 lines"
|
|
105194
105392
|
}
|
|
105195
105393
|
],
|
|
105196
|
-
examples: [
|
|
105394
|
+
examples: [
|
|
105395
|
+
"workit ci wait --timeout 30m",
|
|
105396
|
+
"workit ci logs --failed",
|
|
105397
|
+
"workit ci rerun --failed --reason flake"
|
|
105398
|
+
],
|
|
105197
105399
|
load: () => Promise.resolve().then(() => (init_ci(), exports_ci))
|
|
105198
105400
|
}),
|
|
105199
105401
|
withSubcommands({
|
|
@@ -105734,7 +105936,7 @@ var defaultIo = (json) => ({
|
|
|
105734
105936
|
});
|
|
105735
105937
|
async function main(argv, overrides = {}, options = {}) {
|
|
105736
105938
|
const parsed = parseGlobals(argv);
|
|
105737
|
-
const cwd =
|
|
105939
|
+
const cwd = path71.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
|
|
105738
105940
|
const io = { ...defaultIo(parsed.json), ...overrides, json: parsed.json, cwd };
|
|
105739
105941
|
if (parsed.error)
|
|
105740
105942
|
return emit(io, fail2("invalid_input", parsed.error));
|