@brainervirus/workit-claude-code 8.40.0 → 8.40.2
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 +84 -84
- package/dist/workit.js +161 -59
- package/package.json +3 -3
- package/skills/ship/SKILL.md +1 -0
package/dist/workit.js
CHANGED
|
@@ -9317,7 +9317,7 @@ var package_default;
|
|
|
9317
9317
|
var init_package = __esm(() => {
|
|
9318
9318
|
package_default = {
|
|
9319
9319
|
name: "@brainervirus/workit-cli",
|
|
9320
|
-
version: "8.40.
|
|
9320
|
+
version: "8.40.2",
|
|
9321
9321
|
private: false,
|
|
9322
9322
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
9323
9323
|
keywords: [
|
|
@@ -9355,13 +9355,13 @@ var init_package = __esm(() => {
|
|
|
9355
9355
|
},
|
|
9356
9356
|
dependencies: {
|
|
9357
9357
|
"@babel/parser": "7.29.9",
|
|
9358
|
-
"@brainervirus/workit-cursor": "^8.40.
|
|
9358
|
+
"@brainervirus/workit-cursor": "^8.40.2",
|
|
9359
9359
|
"@inkjs/ui": "2.0.0",
|
|
9360
9360
|
ink: "7.1.1",
|
|
9361
9361
|
react: "19.2.8"
|
|
9362
9362
|
},
|
|
9363
9363
|
devDependencies: {
|
|
9364
|
-
"@brainervirus/workit-core": "^8.40.
|
|
9364
|
+
"@brainervirus/workit-core": "^8.40.2"
|
|
9365
9365
|
},
|
|
9366
9366
|
engines: {
|
|
9367
9367
|
node: ">=24"
|
|
@@ -9779,34 +9779,20 @@ function configuredGrants(entry) {
|
|
|
9779
9779
|
const legacy = fromAutoApprove(record.autoApprove);
|
|
9780
9780
|
return legacy ? { grants: legacy, source: "autoApprove" } : { grants: {}, source: "default" };
|
|
9781
9781
|
}
|
|
9782
|
-
function
|
|
9783
|
-
const override = grantsOverride();
|
|
9784
|
-
if (override)
|
|
9785
|
-
return {
|
|
9786
|
-
workspace: null,
|
|
9787
|
-
grants: { ...DEFAULT_GRANTS },
|
|
9788
|
-
configured: [],
|
|
9789
|
-
source: "default",
|
|
9790
|
-
accountConfigured: false,
|
|
9791
|
-
defaultEndpoint: DEFAULT_ENDPOINT,
|
|
9792
|
-
configuredEndpoint: null,
|
|
9793
|
-
effectiveEndpoint: DEFAULT_ENDPOINT,
|
|
9794
|
-
verification: DEFAULT_VERIFICATION,
|
|
9795
|
-
note: override
|
|
9796
|
-
};
|
|
9797
|
-
const workspace = resolveWorkspaceFrom(cwd, grantsDir(), process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
|
|
9782
|
+
function autonomyOf(workspace) {
|
|
9798
9783
|
const { grants, source } = configuredGrants(workspace);
|
|
9799
9784
|
const full = { ...DEFAULT_GRANTS, ...grants };
|
|
9800
9785
|
const configured = GRANT_KINDS.filter((kind) => grants[kind] !== undefined);
|
|
9801
9786
|
const accountConfigured = Boolean(workspace?.vcs?.account);
|
|
9787
|
+
const name = workspace?.name ?? null;
|
|
9802
9788
|
return {
|
|
9803
|
-
workspace:
|
|
9789
|
+
workspace: name,
|
|
9804
9790
|
grants: full,
|
|
9805
9791
|
configured,
|
|
9806
9792
|
source,
|
|
9807
9793
|
accountConfigured,
|
|
9808
9794
|
...endpointView(workspace, {
|
|
9809
|
-
workspace:
|
|
9795
|
+
workspace: name,
|
|
9810
9796
|
grants: full,
|
|
9811
9797
|
configured,
|
|
9812
9798
|
accountConfigured
|
|
@@ -9814,6 +9800,64 @@ function resolveAutonomy(cwd) {
|
|
|
9814
9800
|
verification: verificationOf(workspace)
|
|
9815
9801
|
};
|
|
9816
9802
|
}
|
|
9803
|
+
function capByFolder(named, folder, name) {
|
|
9804
|
+
if (folder?.workspace === named.workspace)
|
|
9805
|
+
return named;
|
|
9806
|
+
const nothing = !folder || folder.configured.length > 0 && !folder.accountConfigured;
|
|
9807
|
+
const grants = { ...named.grants };
|
|
9808
|
+
const lowered = [];
|
|
9809
|
+
for (const kind of GRANT_KINDS) {
|
|
9810
|
+
const floor = !nothing && folder.grants[kind];
|
|
9811
|
+
if (!raises(kind, floor, grants[kind]))
|
|
9812
|
+
continue;
|
|
9813
|
+
grants[kind] = floor;
|
|
9814
|
+
lowered.push(kind);
|
|
9815
|
+
}
|
|
9816
|
+
const ceiling = !nothing && folder.effectiveEndpoint || DEFAULT_ENDPOINT;
|
|
9817
|
+
const endpoint = raisesEndpoint(ceiling, named.effectiveEndpoint);
|
|
9818
|
+
if (endpoint)
|
|
9819
|
+
lowered.push("defaultEndpoint");
|
|
9820
|
+
const strict = folder?.verification ?? "independent";
|
|
9821
|
+
const looser = VERIFICATION_MODES.indexOf(named.verification) < VERIFICATION_MODES.indexOf(strict);
|
|
9822
|
+
if (looser)
|
|
9823
|
+
lowered.push("verification");
|
|
9824
|
+
if (lowered.length === 0)
|
|
9825
|
+
return named;
|
|
9826
|
+
return {
|
|
9827
|
+
...named,
|
|
9828
|
+
grants,
|
|
9829
|
+
...endpoint ? { effectiveEndpoint: ceiling, endpointReason: undefined } : {},
|
|
9830
|
+
verification: looser ? strict : named.verification,
|
|
9831
|
+
note: `WORKFLOW_WORKSPACE_NAME=${name}: ${lowered.join(", ")} capped at ${folder ? `workspace ${folder.workspace}` : "nothing (tied workspaces)"}; a name never raises grants`
|
|
9832
|
+
};
|
|
9833
|
+
}
|
|
9834
|
+
function resolveAutonomy(cwd) {
|
|
9835
|
+
const override = grantsOverride();
|
|
9836
|
+
if (override)
|
|
9837
|
+
return {
|
|
9838
|
+
workspace: null,
|
|
9839
|
+
grants: { ...DEFAULT_GRANTS },
|
|
9840
|
+
configured: [],
|
|
9841
|
+
source: "default",
|
|
9842
|
+
accountConfigured: false,
|
|
9843
|
+
defaultEndpoint: DEFAULT_ENDPOINT,
|
|
9844
|
+
configuredEndpoint: null,
|
|
9845
|
+
effectiveEndpoint: DEFAULT_ENDPOINT,
|
|
9846
|
+
verification: DEFAULT_VERIFICATION,
|
|
9847
|
+
note: override
|
|
9848
|
+
};
|
|
9849
|
+
const name = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
9850
|
+
const named = autonomyOf(resolveWorkspaceFrom(cwd, grantsDir(), name));
|
|
9851
|
+
if (name === undefined)
|
|
9852
|
+
return named;
|
|
9853
|
+
let folder;
|
|
9854
|
+
try {
|
|
9855
|
+
folder = autonomyOf(resolveWorkspaceFrom(cwd, grantsDir()));
|
|
9856
|
+
} catch {
|
|
9857
|
+
folder = null;
|
|
9858
|
+
}
|
|
9859
|
+
return capByFolder(named, folder, name);
|
|
9860
|
+
}
|
|
9817
9861
|
function requireGrant(cwd, kind, options = {}) {
|
|
9818
9862
|
let autonomy;
|
|
9819
9863
|
try {
|
|
@@ -21793,13 +21837,51 @@ function emit(io, envelope, human) {
|
|
|
21793
21837
|
}
|
|
21794
21838
|
return exitCodeFor(envelope.code);
|
|
21795
21839
|
}
|
|
21840
|
+
async function withFailureLine(io, command, run, outcome) {
|
|
21841
|
+
let wrote = false;
|
|
21842
|
+
let reason = null;
|
|
21843
|
+
const code = await run({
|
|
21844
|
+
...io,
|
|
21845
|
+
stdout: (text) => {
|
|
21846
|
+
wrote ||= text.length > 0;
|
|
21847
|
+
io.stdout(text);
|
|
21848
|
+
},
|
|
21849
|
+
stderr: (text) => {
|
|
21850
|
+
wrote ||= text.length > 0;
|
|
21851
|
+
reason ??= /^workit: ([a-z][a-z_]*):/u.exec(text)?.[1] ?? null;
|
|
21852
|
+
io.stderr(text);
|
|
21853
|
+
}
|
|
21854
|
+
});
|
|
21855
|
+
if (code === 0)
|
|
21856
|
+
return code;
|
|
21857
|
+
if (outcome)
|
|
21858
|
+
io.stderr(`workit: error: ${outcome} (${reason ?? EXIT_NAMES[code] ?? "failed"}, exit ${code})
|
|
21859
|
+
`);
|
|
21860
|
+
else if (!wrote)
|
|
21861
|
+
io.stderr(`workit: error: ${command} failed (exit ${code})
|
|
21862
|
+
`);
|
|
21863
|
+
return code;
|
|
21864
|
+
}
|
|
21796
21865
|
var EXIT, EXIT_BY_CODE, exitCodeFor = (code) => EXIT_BY_CODE[code], ok2 = (data) => ({ ok: true, code: "ok", data }), fail2 = (code, error, extra = {}) => ({
|
|
21797
21866
|
ok: false,
|
|
21798
21867
|
code,
|
|
21799
21868
|
data: extra.data ?? {},
|
|
21800
21869
|
error,
|
|
21801
21870
|
...extra.unblock ? { unblock: extra.unblock } : {}
|
|
21802
|
-
})
|
|
21871
|
+
}), EXIT_NAMES, flushStreams = async (streams = [process.stdout, process.stderr], timeoutMs = 2000) => {
|
|
21872
|
+
await Promise.all(streams.map((stream) => new Promise((resolve) => {
|
|
21873
|
+
const timer = setTimeout(resolve, timeoutMs);
|
|
21874
|
+
const done = () => {
|
|
21875
|
+
clearTimeout(timer);
|
|
21876
|
+
resolve();
|
|
21877
|
+
};
|
|
21878
|
+
try {
|
|
21879
|
+
stream.write("", done);
|
|
21880
|
+
} catch {
|
|
21881
|
+
done();
|
|
21882
|
+
}
|
|
21883
|
+
})));
|
|
21884
|
+
};
|
|
21803
21885
|
var init_output = __esm(() => {
|
|
21804
21886
|
EXIT = {
|
|
21805
21887
|
ok: 0,
|
|
@@ -21820,6 +21902,13 @@ var init_output = __esm(() => {
|
|
|
21820
21902
|
pending: EXIT.busy,
|
|
21821
21903
|
unavailable: EXIT.unavailable
|
|
21822
21904
|
};
|
|
21905
|
+
EXIT_NAMES = {
|
|
21906
|
+
1: "failed",
|
|
21907
|
+
2: "invalid_input",
|
|
21908
|
+
3: "blocked",
|
|
21909
|
+
4: "busy",
|
|
21910
|
+
5: "unavailable"
|
|
21911
|
+
};
|
|
21823
21912
|
});
|
|
21824
21913
|
|
|
21825
21914
|
// packages/workit-cli/src/verbs/task.ts
|
|
@@ -81597,7 +81686,7 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
81597
81686
|
return {
|
|
81598
81687
|
ok: false,
|
|
81599
81688
|
code: "failed",
|
|
81600
|
-
error: `merge_unverified: the forge accepted the merge of ${label} but still reports it ${state}${"id" in recorded ? `; recorded as pr.merged ${recorded.id} (verified: false)` : `; the pr.merged row could not be written (${recorded.error})`}`,
|
|
81689
|
+
error: `merge_unverified: the forge accepted the merge of ${label} but still reports it ${state}${state === "open" ? ", so it is not merged yet (a merge queue or auto-merge may hold it)" : ""}${"id" in recorded ? `; recorded as pr.merged ${recorded.id} (verified: false)` : `; the pr.merged row could not be written (${recorded.error})`}`,
|
|
81601
81690
|
unblock: `workit verify-delivery merged --pr ${doc.number}`,
|
|
81602
81691
|
recorded
|
|
81603
81692
|
};
|
|
@@ -108755,43 +108844,54 @@ async function main(argv, overrides = {}, options = {}) {
|
|
|
108755
108844
|
const entry = findVerb(command);
|
|
108756
108845
|
if (!entry)
|
|
108757
108846
|
return unknown2(io, command);
|
|
108758
|
-
|
|
108759
|
-
|
|
108760
|
-
|
|
108761
|
-
|
|
108762
|
-
|
|
108763
|
-
|
|
108764
|
-
|
|
108765
|
-
|
|
108766
|
-
|
|
108767
|
-
|
|
108768
|
-
|
|
108769
|
-
|
|
108770
|
-
|
|
108771
|
-
|
|
108772
|
-
|
|
108773
|
-
|
|
108774
|
-
|
|
108775
|
-
|
|
108776
|
-
|
|
108777
|
-
|
|
108778
|
-
|
|
108779
|
-
|
|
108780
|
-
|
|
108781
|
-
process.env.WORKFLOW_WORKSPACE_ROOT
|
|
108782
|
-
|
|
108847
|
+
const route = async (routed) => {
|
|
108848
|
+
if (wantsHelp(verbArgs)) {
|
|
108849
|
+
const word = firstWord(verbArgs);
|
|
108850
|
+
const sub = word === undefined ? undefined : findSubcommand(entry, word);
|
|
108851
|
+
const asValue = helpAsValue(verbArgs, sub ? [sub.usage] : usageLines(entry));
|
|
108852
|
+
if (asValue)
|
|
108853
|
+
return emit(routed, fail2("invalid_input", asValue, {
|
|
108854
|
+
unblock: `workit help ${entry.name}${sub ? ` ${sub.name}` : ""}`
|
|
108855
|
+
}));
|
|
108856
|
+
return help(routed, sub ? subcommandHelp(entry, sub) : verbHelp(entry));
|
|
108857
|
+
}
|
|
108858
|
+
const ended = endOfOptions(routed, entry, args);
|
|
108859
|
+
if (typeof ended === "number")
|
|
108860
|
+
return ended;
|
|
108861
|
+
const checked = checkFlags(entry, ended);
|
|
108862
|
+
if ("error" in checked)
|
|
108863
|
+
return emit(routed, fail2("invalid_input", checked.error, { unblock: checked.unblock }));
|
|
108864
|
+
if (parsed.cwd !== null) {
|
|
108865
|
+
try {
|
|
108866
|
+
process.chdir(routed.cwd);
|
|
108867
|
+
} catch {
|
|
108868
|
+
return emit(routed, fail2("invalid_input", `--cwd: cannot enter ${routed.cwd}`));
|
|
108869
|
+
}
|
|
108870
|
+
if (process.env.WORKFLOW_WORKSPACE_ROOT !== undefined) {
|
|
108871
|
+
process.env.WORKFLOW_WORKSPACE_ROOT = routed.cwd;
|
|
108872
|
+
routed.env = process.env;
|
|
108873
|
+
}
|
|
108783
108874
|
}
|
|
108784
|
-
|
|
108785
|
-
|
|
108786
|
-
(
|
|
108787
|
-
globalThis[Symbol.for("workit.migrationReporter")] = (report) => io.stderr(`workit: migrated ${report.tasks} task${report.tasks === 1 ? "" : "s"} from ${report.from} to ${report.to} (backup: ${report.backup})
|
|
108875
|
+
if (options.diagnostics)
|
|
108876
|
+
(await Promise.resolve().then(() => (init_diagnostics(), exports_diagnostics))).installDiagnostics(command);
|
|
108877
|
+
globalThis[Symbol.for("workit.migrationReporter")] = (report) => routed.stderr(`workit: migrated ${report.tasks} task${report.tasks === 1 ? "" : "s"} from ${report.from} to ${report.to} (backup: ${report.backup})
|
|
108788
108878
|
`);
|
|
108789
|
-
|
|
108790
|
-
|
|
108791
|
-
|
|
108792
|
-
|
|
108793
|
-
|
|
108794
|
-
|
|
108879
|
+
const verb = await entry.load();
|
|
108880
|
+
const runVerb = (target) => guarded(target, () => verb.run(checked.args, target));
|
|
108881
|
+
return routed.json ? runJsonPure(routed, command, runVerb) : runVerb(routed);
|
|
108882
|
+
};
|
|
108883
|
+
if (io.json)
|
|
108884
|
+
return route(io);
|
|
108885
|
+
const verbWord = firstWord(verbArgs);
|
|
108886
|
+
const outcome = verbWord ? OUTCOMES2[`${entry.name} ${verbWord}`] : undefined;
|
|
108887
|
+
return withFailureLine(io, command, route, outcome);
|
|
108888
|
+
}
|
|
108889
|
+
var OUTCOMES2 = {
|
|
108890
|
+
"pr merge": "PR not merged",
|
|
108891
|
+
"pr create": "PR not created",
|
|
108892
|
+
"stack land": "stack not landed",
|
|
108893
|
+
"git push": "not pushed"
|
|
108894
|
+
};
|
|
108795
108895
|
async function guarded(io, run) {
|
|
108796
108896
|
try {
|
|
108797
108897
|
return await run();
|
|
@@ -108895,7 +108995,9 @@ var describe4 = (entry) => ({
|
|
|
108895
108995
|
});
|
|
108896
108996
|
var unknown2 = (io, command) => emit(io, fail2("invalid_input", `unknown command "${command}"`, { unblock: commandUnblock(command) }));
|
|
108897
108997
|
if (__require.main == __require.module) {
|
|
108898
|
-
|
|
108998
|
+
const code = await main(process.argv.slice(2), {}, { diagnostics: true });
|
|
108999
|
+
await flushStreams();
|
|
109000
|
+
process.exit(code);
|
|
108899
109001
|
}
|
|
108900
109002
|
export {
|
|
108901
109003
|
main,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-claude-code",
|
|
3
|
-
"version": "8.40.
|
|
3
|
+
"version": "8.40.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit Claude Code plugin — session and per-turn task context, branch policy on git shell commands, workit method skills, and verifier/reviewer/implementer agents",
|
|
6
6
|
"keywords": [
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"build": "bun scripts/build.ts"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@brainervirus/workit-cli": "^8.40.
|
|
43
|
-
"@brainervirus/workit-core": "^8.40.
|
|
42
|
+
"@brainervirus/workit-cli": "^8.40.2",
|
|
43
|
+
"@brainervirus/workit-core": "^8.40.2"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"node": ">=24"
|
package/skills/ship/SKILL.md
CHANGED
|
@@ -52,6 +52,7 @@ the same check. Fix round and recheck both failed: a decider (call the Skill too
|
|
|
52
52
|
with `workit check`, fix the root cause, batch every fix in one push. A tool warning is a finding: fix it in this PR in the right layer, or record the false positive with evidence; pre-existing ones get their own PR.
|
|
53
53
|
6. **Verified.** The lane in `workit pr status` decides: none, no verdict; self, your `--self` verdict; focused or full (or `verification: self|independent`), one non-author verifier per PR after the last push, never per push (call the Skill tool with `workit:review`), on Claude Code with the `model` and `effort` of `workit models show --role verifier`. A docs-only push (or test-only under a unit verdict) keeps the verdict (`carried`); `reverify: focused` re-checks only the new diff, reusing green CI; one verdict at a stack's top covers its unchanged lower PRs. Land only when
|
|
54
54
|
granted: `workit stack land` or `workit pr merge`; `--unverified --reason` if user-asked.
|
|
55
|
+
Never pipe a delivery verb through `grep`: read its exit code, or use `--json`.
|
|
55
56
|
7. **Observe it landed:** `workit verify-delivery pr` or `merge`. After a failed
|
|
56
57
|
verdict or a check red 3+ times, at any endpoint: offer `/wk-retro` in one
|
|
57
58
|
line of the final or stop report; never pause the babysit loop for it.
|