@brainervirus/workit-cli 8.39.3 → 8.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +404 -32
- package/package.json +3 -3
package/dist/index.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.
|
|
9320
|
+
version: "8.40.0",
|
|
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.
|
|
9358
|
+
"@brainervirus/workit-cursor": "^8.40.0",
|
|
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.
|
|
9364
|
+
"@brainervirus/workit-core": "^8.40.0"
|
|
9365
9365
|
},
|
|
9366
9366
|
engines: {
|
|
9367
9367
|
node: ">=24"
|
|
@@ -21305,7 +21305,10 @@ async function payloadValue(raw, deps) {
|
|
|
21305
21305
|
}
|
|
21306
21306
|
try {
|
|
21307
21307
|
const value = JSON.parse(source);
|
|
21308
|
-
return isObject7(value) ? { ok: true, value } : {
|
|
21308
|
+
return isObject7(value) ? { ok: true, value } : {
|
|
21309
|
+
ok: false,
|
|
21310
|
+
result: failure2("invalid_input", "payload must be a JSON object")
|
|
21311
|
+
};
|
|
21309
21312
|
} catch (error) {
|
|
21310
21313
|
return {
|
|
21311
21314
|
ok: false,
|
|
@@ -21500,7 +21503,11 @@ function laneOf(root) {
|
|
|
21500
21503
|
} catch {
|
|
21501
21504
|
verification = DEFAULT_VERIFICATION;
|
|
21502
21505
|
}
|
|
21503
|
-
const lane = branchLane(root, {
|
|
21506
|
+
const lane = branchLane(root, {
|
|
21507
|
+
head: null,
|
|
21508
|
+
workingTree: true,
|
|
21509
|
+
judgment: currentJudgment(root)
|
|
21510
|
+
});
|
|
21504
21511
|
return {
|
|
21505
21512
|
lane: lane.lane,
|
|
21506
21513
|
reasons: lane.reasons,
|
|
@@ -21574,7 +21581,69 @@ function printHuman(result, deps, handoff = false) {
|
|
|
21574
21581
|
write(stream, `policy gap: ${gap.reason}`);
|
|
21575
21582
|
}
|
|
21576
21583
|
}
|
|
21584
|
+
function runFindingList(argv, deps) {
|
|
21585
|
+
let json = false;
|
|
21586
|
+
let branch;
|
|
21587
|
+
let status;
|
|
21588
|
+
const fail = (message) => {
|
|
21589
|
+
if (json)
|
|
21590
|
+
jsonResult(outOf(deps), usage(message));
|
|
21591
|
+
else
|
|
21592
|
+
write(errOf(deps), `${message}
|
|
21593
|
+
usage: ${FINDING_LIST_USAGE}`);
|
|
21594
|
+
return 2;
|
|
21595
|
+
};
|
|
21596
|
+
for (let i = 0;i < argv.length; i += 1) {
|
|
21597
|
+
const eq = argv[i].startsWith("--") ? argv[i].indexOf("=") : -1;
|
|
21598
|
+
const token = eq > 0 ? argv[i].slice(0, eq) : argv[i];
|
|
21599
|
+
if (token === "--json")
|
|
21600
|
+
json = true;
|
|
21601
|
+
else if (token === "--branch" || token === "--status") {
|
|
21602
|
+
const value = eq > 0 ? argv[i].slice(eq + 1) : argv[++i];
|
|
21603
|
+
if (value === undefined || !value.trim())
|
|
21604
|
+
return fail(`${token} requires a value`);
|
|
21605
|
+
if (token === "--branch")
|
|
21606
|
+
branch = value;
|
|
21607
|
+
else
|
|
21608
|
+
status = value;
|
|
21609
|
+
} else
|
|
21610
|
+
return fail(`unknown argument: ${argv[i]}`);
|
|
21611
|
+
}
|
|
21612
|
+
if (status !== undefined && status !== "open" && status !== "resolved")
|
|
21613
|
+
return fail(`--status is open or resolved (got ${status})`);
|
|
21614
|
+
const store = new TaskStore(workspaceRootFor(deps));
|
|
21615
|
+
const index = store.listTaskIndex();
|
|
21616
|
+
const tasks = store.listTasks();
|
|
21617
|
+
const result = !index.ok ? index : !tasks.ok ? tasks : success(null, null, null);
|
|
21618
|
+
if (!result.ok || !index.ok || !tasks.ok) {
|
|
21619
|
+
if (json)
|
|
21620
|
+
jsonResult(outOf(deps), result);
|
|
21621
|
+
else
|
|
21622
|
+
printHuman(result, deps);
|
|
21623
|
+
return 1;
|
|
21624
|
+
}
|
|
21625
|
+
const keys = new Map(index.data.map((entry) => [entry.id, entry.key]));
|
|
21626
|
+
const rows = tasks.data.filter((task) => branch === undefined || keys.get(task.id) === branch).flatMap((task) => task.findings.filter((item) => status === undefined || item.data.disposition === "open" === (status === "open")).map((item) => ({
|
|
21627
|
+
id: item.id,
|
|
21628
|
+
taskId: task.id,
|
|
21629
|
+
branch: keys.get(task.id) ?? null,
|
|
21630
|
+
disposition: item.data.disposition,
|
|
21631
|
+
recordedAt: item.recordedAt,
|
|
21632
|
+
claim: item.data.claim
|
|
21633
|
+
})));
|
|
21634
|
+
const total = tasks.data.reduce((sum, task) => sum + task.findings.length, 0);
|
|
21635
|
+
if (json)
|
|
21636
|
+
jsonResult(outOf(deps), success(null, null, { findings: rows, total }));
|
|
21637
|
+
else if (!rows.length)
|
|
21638
|
+
write(outOf(deps), total ? `no findings match the filters (${total} finding${total === 1 ? "" : "s"} in all; drop --branch/--status to list them)` : "no findings recorded (record one: workit finding record --payload '{…}'); ledger rows hold verdicts and rulings, not findings");
|
|
21639
|
+
else
|
|
21640
|
+
for (const row of rows)
|
|
21641
|
+
write(outOf(deps), `${row.id} ${row.disposition}${row.branch ? ` [${row.branch}]` : ""} (task ${row.taskId}) ${row.claim}`);
|
|
21642
|
+
return 0;
|
|
21643
|
+
}
|
|
21577
21644
|
async function runTaskCommand(argv, deps = {}) {
|
|
21645
|
+
if (argv[0] === "finding" && argv[1] === "list")
|
|
21646
|
+
return runFindingList(argv.slice(2), deps);
|
|
21578
21647
|
const parsed = await parseTaskArgs(argv, deps);
|
|
21579
21648
|
if (!parsed.ok) {
|
|
21580
21649
|
if (parsed.json)
|
|
@@ -21587,7 +21656,9 @@ async function runTaskCommand(argv, deps = {}) {
|
|
|
21587
21656
|
const store = new TaskStore(root);
|
|
21588
21657
|
try {
|
|
21589
21658
|
const now = new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
21590
|
-
closeDeliveredTasks(store, now, {
|
|
21659
|
+
closeDeliveredTasks(store, now, {
|
|
21660
|
+
cached: parsed.parsed.action !== "list"
|
|
21661
|
+
});
|
|
21591
21662
|
} catch {}
|
|
21592
21663
|
const core = new WorkitCore(store, contextFor(root, parsed.parsed.actor !== undefined ? { ...deps, actor: parsed.parsed.actor } : deps));
|
|
21593
21664
|
let result;
|
|
@@ -21678,7 +21749,7 @@ var TASK_FAMILIES, workspaceRootFor = (deps = {}) => {
|
|
|
21678
21749
|
capabilities: deps.capabilities ?? [],
|
|
21679
21750
|
constraints: deps.constraints ?? [],
|
|
21680
21751
|
now: deps.now ?? (() => new Date().toISOString())
|
|
21681
|
-
});
|
|
21752
|
+
}), FINDING_LIST_USAGE = "workit finding list [--branch <b>] [--status open|resolved] [--json]";
|
|
21682
21753
|
var init_task = __esm(() => {
|
|
21683
21754
|
init_check_config();
|
|
21684
21755
|
init_autonomy();
|
|
@@ -21695,7 +21766,7 @@ var init_task = __esm(() => {
|
|
|
21695
21766
|
task: ["start", "list", "inspect", "revise", "progress", "pause", "resume", "close"],
|
|
21696
21767
|
policy: ["assess", "preview", "explain"],
|
|
21697
21768
|
evidence: ["record"],
|
|
21698
|
-
finding: ["record", "resolve"],
|
|
21769
|
+
finding: ["record", "resolve", "list"],
|
|
21699
21770
|
decision: ["record", "revoke"],
|
|
21700
21771
|
worker: ["assign", "report", "cancel"],
|
|
21701
21772
|
state: ["export", "import"]
|
|
@@ -76963,6 +77034,7 @@ var init_uninstall2 = __esm(() => {
|
|
|
76963
77034
|
// packages/workit-cli/src/verbs/grant.ts
|
|
76964
77035
|
var exports_grant = {};
|
|
76965
77036
|
__export(exports_grant, {
|
|
77037
|
+
agentMarker: () => agentMarker,
|
|
76966
77038
|
run: () => run10,
|
|
76967
77039
|
runGrant: () => runGrant
|
|
76968
77040
|
});
|
|
@@ -77301,7 +77373,90 @@ function set2(argv, io) {
|
|
|
77301
77373
|
`${name}: ${changes.map((change) => change.path.join(".")).join(", ")} updated in ${written(data.path, data.backup)}`
|
|
77302
77374
|
]);
|
|
77303
77375
|
}
|
|
77304
|
-
async function
|
|
77376
|
+
async function rm(argv, io, deps) {
|
|
77377
|
+
const [name, extra] = argv;
|
|
77378
|
+
if (!name)
|
|
77379
|
+
return usage3(io, "rm needs <name>");
|
|
77380
|
+
if (extra)
|
|
77381
|
+
return usage3(io, `unexpected argument ${extra}`);
|
|
77382
|
+
const current = load(io);
|
|
77383
|
+
if (typeof current === "number")
|
|
77384
|
+
return current;
|
|
77385
|
+
const entries = entriesOf(current);
|
|
77386
|
+
const removed = entries.find((entry) => entry.name === name);
|
|
77387
|
+
if (!removed)
|
|
77388
|
+
return emit(io, fail2("not_found", `no workspace named "${name}" in ${current.path}`));
|
|
77389
|
+
const remaining = entries.filter((entry) => entry !== removed);
|
|
77390
|
+
if (remaining.length === 0)
|
|
77391
|
+
return emit(io, fail2("blocked", `"${name}" is the last workspace in ${current.path}: it holds your vcs, policies and grants, and without it every folder falls back to the defaults; workspace rm does not remove it`, {
|
|
77392
|
+
unblock: `add the workspace that should replace it first (workit workspace add <name> --glob <g> --from ${name}), or edit ${current.path} in your own editor`
|
|
77393
|
+
}));
|
|
77394
|
+
const before = deliveredCeilingOf(removed);
|
|
77395
|
+
const defaults = ceilingOf({});
|
|
77396
|
+
const nothing = {
|
|
77397
|
+
grants: Object.fromEntries(GRANT_KINDS.map((kind) => [kind, false])),
|
|
77398
|
+
endpoint: DEFAULT_ENDPOINT,
|
|
77399
|
+
verification: STRICTNESS[0]
|
|
77400
|
+
};
|
|
77401
|
+
const specificity = globSpecificity(removed.glob);
|
|
77402
|
+
const raised = [
|
|
77403
|
+
{ taker: "defaults", kinds: raisedKinds(before, defaults), reason: "no entry matches" },
|
|
77404
|
+
...remaining.map((entry) => ({
|
|
77405
|
+
taker: entry.name,
|
|
77406
|
+
kinds: raisedKinds(before, ceilingOf(entry)),
|
|
77407
|
+
reason: "may match a folder it covered"
|
|
77408
|
+
})),
|
|
77409
|
+
...remaining.filter((entry) => globSpecificity(entry.glob) === specificity).map((entry) => ({
|
|
77410
|
+
taker: entry.name,
|
|
77411
|
+
kinds: raisedKinds(nothing, ceilingOf(entry)),
|
|
77412
|
+
reason: "equally specific: a folder both matched was ambiguous, with nothing granted"
|
|
77413
|
+
}))
|
|
77414
|
+
].filter((raise) => raise.kinds.length > 0);
|
|
77415
|
+
if (raised.length > 0) {
|
|
77416
|
+
const kinds = [...new Set(raised.flatMap((raise) => raise.kinds))];
|
|
77417
|
+
const detail = raised.map((raise) => `${raise.taker} (${raise.reason}): ${raise.kinds.join(", ")}`).join("; ");
|
|
77418
|
+
const agent = agentMarker(io.env);
|
|
77419
|
+
if (!deps.interactive() || agent)
|
|
77420
|
+
return emit(io, fail2("blocked", `grant_raise_refused: removing "${name}" may raise ${kinds.join(", ")} for the folders it covered (${detail}); that needs the user at an interactive terminal${agent ? ` (this shell belongs to an agent: ${agent} is set)` : ""}; grants are never raised headless`, {
|
|
77421
|
+
unblock: `ask the user to run, in a terminal outside the agent host (not Claude Code's \`!\` prefix or an agent shell): workit workspace rm ${name}`
|
|
77422
|
+
}));
|
|
77423
|
+
const answer = await askOrCancel(io, () => deps.ask(`Removing workspace "${name}" may raise ${kinds.join(", ")} for the folders it covered (${detail}). An agent there may then do more without asking. Type the workspace name to confirm: `));
|
|
77424
|
+
if (answer === null)
|
|
77425
|
+
return cancelled(io);
|
|
77426
|
+
if (answer.trim() !== name)
|
|
77427
|
+
return emit(io, fail2("blocked", "workspace removal not confirmed; nothing was written"));
|
|
77428
|
+
}
|
|
77429
|
+
const result = save(current, remaining);
|
|
77430
|
+
if (!result.ok)
|
|
77431
|
+
return emit(io, fail2("invalid_input", result.error));
|
|
77432
|
+
const at = globRoot(removed.glob);
|
|
77433
|
+
let covers;
|
|
77434
|
+
try {
|
|
77435
|
+
covers = { at, workspace: resolveWorkspaceFromEntries(at, remaining)?.name ?? null };
|
|
77436
|
+
} catch (error) {
|
|
77437
|
+
covers = { at, workspace: null, error: error instanceof Error ? error.message : String(error) };
|
|
77438
|
+
}
|
|
77439
|
+
const coveringCeiling = ceilingOf(remaining.find((entry) => entry.name === covers.workspace));
|
|
77440
|
+
return emit(io, ok2({
|
|
77441
|
+
path: result.path,
|
|
77442
|
+
backup: result.backup,
|
|
77443
|
+
removed,
|
|
77444
|
+
covers: {
|
|
77445
|
+
...covers,
|
|
77446
|
+
grants: coveringCeiling.grants,
|
|
77447
|
+
defaultEndpoint: coveringCeiling.endpoint,
|
|
77448
|
+
verification: coveringCeiling.verification
|
|
77449
|
+
},
|
|
77450
|
+
takers: overlappingEntries(removed.glob, remaining).map((entry) => entry.name),
|
|
77451
|
+
raises: raised
|
|
77452
|
+
}), (data) => [
|
|
77453
|
+
`${name} (${removed.glob}) removed from ${written(data.path, data.backup)}`,
|
|
77454
|
+
data.covers.error ? ` ${data.covers.at}: ${data.covers.error}` : ` ${data.covers.at} is now ${data.covers.workspace ? `workspace ${data.covers.workspace}` : "under the defaults (no workspace)"}: ${GRANT_KINDS.map((kind) => `${kind}=${String(data.covers.grants[kind])}`).join(" ")}; default endpoint ${data.covers.defaultEndpoint}; verification ${data.covers.verification}`,
|
|
77455
|
+
...data.takers.length ? [` entries whose globs may cover its other folders: ${data.takers.join(", ")}`] : [],
|
|
77456
|
+
" workit workspace list --cwd <folder> shows which entry applies to a folder"
|
|
77457
|
+
]);
|
|
77458
|
+
}
|
|
77459
|
+
async function runWorkspace(argv, io, deps = defaultDeps2) {
|
|
77305
77460
|
const [sub, ...rest] = argv.filter((arg) => arg !== "--json" && arg !== "--");
|
|
77306
77461
|
if (sub === undefined || sub === "list")
|
|
77307
77462
|
return list2(rest, io);
|
|
@@ -77309,13 +77464,25 @@ async function runWorkspace(argv, io) {
|
|
|
77309
77464
|
return add2(rest, io);
|
|
77310
77465
|
if (sub === "set")
|
|
77311
77466
|
return set2(rest, io);
|
|
77467
|
+
if (sub === "rm")
|
|
77468
|
+
return rm(rest, io, deps);
|
|
77312
77469
|
return usage3(io, `unknown subcommand "${sub}"`);
|
|
77313
77470
|
}
|
|
77314
|
-
var USAGE5 = "workit workspace list | workspace add <name> --glob <g> [--from <parent>] | workspace set <name> <key>=<value>…", INHERITED_KEYS, GRANT_KEYS, SCOPE_KEYS, SETTABLE_KEYS, SEGMENT, UNSAFE_SEGMENTS, ceilingOf = (entry) => ({
|
|
77471
|
+
var USAGE5 = "workit workspace list | workspace add <name> --glob <g> [--from <parent>] | workspace set <name> <key>=<value>… | workspace rm <name>", INHERITED_KEYS, GRANT_KEYS, SCOPE_KEYS, SETTABLE_KEYS, SEGMENT, UNSAFE_SEGMENTS, ceilingOf = (entry) => ({
|
|
77315
77472
|
grants: { ...DEFAULT_GRANTS, ...configuredGrants(entry).grants },
|
|
77316
77473
|
endpoint: isDefaultEndpoint(entry?.defaultEndpoint) ? entry.defaultEndpoint : DEFAULT_ENDPOINT,
|
|
77317
77474
|
verification: verificationOf(entry)
|
|
77318
|
-
}),
|
|
77475
|
+
}), deliveredCeilingOf = (entry) => {
|
|
77476
|
+
const ceiling = ceilingOf(entry);
|
|
77477
|
+
const account = entry.vcs?.account;
|
|
77478
|
+
if (Object.keys(configuredGrants(entry).grants).length === 0 || account)
|
|
77479
|
+
return ceiling;
|
|
77480
|
+
return {
|
|
77481
|
+
grants: Object.fromEntries(GRANT_KINDS.map((kind) => [kind, false])),
|
|
77482
|
+
endpoint: DEFAULT_ENDPOINT,
|
|
77483
|
+
verification: ceiling.verification
|
|
77484
|
+
};
|
|
77485
|
+
}, STRICTNESS, looser = (current, next) => STRICTNESS.indexOf(next) > STRICTNESS.indexOf(current), shadowedCeiling = (shadowed) => {
|
|
77319
77486
|
if (shadowed.length === 0)
|
|
77320
77487
|
return null;
|
|
77321
77488
|
const ceilings = shadowed.map(ceilingOf);
|
|
@@ -77335,7 +77502,11 @@ var USAGE5 = "workit workspace list | workspace add <name> --glob <g> [--from <p
|
|
|
77335
77502
|
...Object.keys(autonomy).length ? { autonomy } : {},
|
|
77336
77503
|
...looser(shadowed.verification, DEFAULT_VERIFICATION) ? { verification: shadowed.verification } : {}
|
|
77337
77504
|
};
|
|
77338
|
-
},
|
|
77505
|
+
}, defaultDeps2, raisedKinds = (before, after) => [
|
|
77506
|
+
...GRANT_KINDS.filter((kind) => raises(kind, before.grants[kind], after.grants[kind])),
|
|
77507
|
+
...raisesEndpoint(before.endpoint, after.endpoint) ? ["defaultEndpoint"] : [],
|
|
77508
|
+
...looser(before.verification, after.verification) ? ["verification"] : []
|
|
77509
|
+
], usage3 = (io, message) => emit(io, fail2("invalid_input", `${message}
|
|
77339
77510
|
usage: ${USAGE5}`)), load = (io) => {
|
|
77340
77511
|
const current = readWorkspacesResult();
|
|
77341
77512
|
if (current.status === "malformed" || current.status === "invalid")
|
|
@@ -77384,6 +77555,8 @@ var init_workspace = __esm(() => {
|
|
|
77384
77555
|
init_safe_write();
|
|
77385
77556
|
init_workspaces();
|
|
77386
77557
|
init_output();
|
|
77558
|
+
init_prompt();
|
|
77559
|
+
init_grant();
|
|
77387
77560
|
INHERITED_KEYS = [
|
|
77388
77561
|
"vcs",
|
|
77389
77562
|
"issues",
|
|
@@ -77415,6 +77588,10 @@ var init_workspace = __esm(() => {
|
|
|
77415
77588
|
SEGMENT = /^[A-Za-z0-9_-]+$/u;
|
|
77416
77589
|
UNSAFE_SEGMENTS = new Set(["__proto__", "constructor", "prototype"]);
|
|
77417
77590
|
STRICTNESS = ["independent", "self", "proportional"];
|
|
77591
|
+
defaultDeps2 = {
|
|
77592
|
+
interactive: () => process.stdin.isTTY === true && process.stdout.isTTY === true,
|
|
77593
|
+
ask: (question) => askLine(question)
|
|
77594
|
+
};
|
|
77418
77595
|
});
|
|
77419
77596
|
|
|
77420
77597
|
// packages/workit-core/src/core/heavy-rules.ts
|
|
@@ -86747,10 +86924,124 @@ var init_forge_common = __esm(() => {
|
|
|
86747
86924
|
// packages/workit-cli/src/verbs/pr.ts
|
|
86748
86925
|
var exports_pr = {};
|
|
86749
86926
|
__export(exports_pr, {
|
|
86927
|
+
checkPrTitle: () => checkPrTitle,
|
|
86750
86928
|
run: () => run15
|
|
86751
86929
|
});
|
|
86752
|
-
import { readFileSync as readFileSync27 } from "node:fs";
|
|
86930
|
+
import { existsSync as existsSync26, readFileSync as readFileSync27 } from "node:fs";
|
|
86753
86931
|
import path66 from "node:path";
|
|
86932
|
+
function titleRules(cwd) {
|
|
86933
|
+
let root;
|
|
86934
|
+
try {
|
|
86935
|
+
root = checkRoot(cwd);
|
|
86936
|
+
} catch {
|
|
86937
|
+
return { rules: null, note: null };
|
|
86938
|
+
}
|
|
86939
|
+
let text = null;
|
|
86940
|
+
let name = "";
|
|
86941
|
+
for (const candidate of COMMITLINT_FILES) {
|
|
86942
|
+
const full = path66.join(root, candidate);
|
|
86943
|
+
if (!existsSync26(full))
|
|
86944
|
+
continue;
|
|
86945
|
+
text = readFileSync27(full, "utf8");
|
|
86946
|
+
name = candidate;
|
|
86947
|
+
break;
|
|
86948
|
+
}
|
|
86949
|
+
if (text === null) {
|
|
86950
|
+
try {
|
|
86951
|
+
const pkg = JSON.parse(readFileSync27(path66.join(root, "package.json"), "utf8"));
|
|
86952
|
+
if (pkg.commitlint === undefined)
|
|
86953
|
+
return { rules: null, note: null };
|
|
86954
|
+
text = JSON.stringify(pkg.commitlint);
|
|
86955
|
+
} catch {
|
|
86956
|
+
return { rules: null, note: null };
|
|
86957
|
+
}
|
|
86958
|
+
}
|
|
86959
|
+
if (/\.[cm]?[jt]s$/u.test(name))
|
|
86960
|
+
return UNCHECKED("JS/TS");
|
|
86961
|
+
let config;
|
|
86962
|
+
try {
|
|
86963
|
+
const parsed = JSON.parse(text);
|
|
86964
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
86965
|
+
return UNCHECKED("not a plain JSON object");
|
|
86966
|
+
config = parsed;
|
|
86967
|
+
} catch {
|
|
86968
|
+
return UNCHECKED(/\.ya?ml$|^\.commitlintrc$/u.test(name) ? "YAML" : "unreadable");
|
|
86969
|
+
}
|
|
86970
|
+
if (config.ignores !== undefined)
|
|
86971
|
+
return UNCHECKED("using custom ignores");
|
|
86972
|
+
const extend = config.extends === undefined ? [] : [config.extends].flat();
|
|
86973
|
+
const known = (entry) => typeof entry === "string" && /^(@commitlint\/)?config-conventional$/u.test(entry);
|
|
86974
|
+
if (!extend.every(known))
|
|
86975
|
+
return UNCHECKED("extending a shareable config");
|
|
86976
|
+
const rules = {
|
|
86977
|
+
types: null,
|
|
86978
|
+
maxHeader: null,
|
|
86979
|
+
format: 0,
|
|
86980
|
+
defaultIgnores: config.defaultIgnores !== false
|
|
86981
|
+
};
|
|
86982
|
+
if (extend.length) {
|
|
86983
|
+
rules.types = { level: 2, values: CONVENTIONAL_TYPES };
|
|
86984
|
+
rules.maxHeader = { level: 2, value: 100 };
|
|
86985
|
+
rules.format = 2;
|
|
86986
|
+
}
|
|
86987
|
+
const own = config.rules ?? {};
|
|
86988
|
+
const types = readRule(own, "type-enum");
|
|
86989
|
+
if (types === "off")
|
|
86990
|
+
rules.types = null;
|
|
86991
|
+
else if (types && Array.isArray(types.value))
|
|
86992
|
+
rules.types = { level: types.level, values: types.value.map(String) };
|
|
86993
|
+
const max = readRule(own, "header-max-length");
|
|
86994
|
+
if (max === "off")
|
|
86995
|
+
rules.maxHeader = null;
|
|
86996
|
+
else if (max && typeof max.value === "number")
|
|
86997
|
+
rules.maxHeader = { level: max.level, value: max.value };
|
|
86998
|
+
for (const rule of ["type-empty", "subject-empty"]) {
|
|
86999
|
+
const read = readRule(own, rule);
|
|
87000
|
+
if (read === "off")
|
|
87001
|
+
rules.format = 0;
|
|
87002
|
+
else if (read)
|
|
87003
|
+
rules.format = Math.max(rules.format, read.level);
|
|
87004
|
+
}
|
|
87005
|
+
return { rules, note: null };
|
|
87006
|
+
}
|
|
87007
|
+
function checkPrTitle(cwd, title) {
|
|
87008
|
+
const { rules, note } = titleRules(cwd);
|
|
87009
|
+
if (!rules)
|
|
87010
|
+
return { error: null, notes: note ? [note] : [] };
|
|
87011
|
+
const header = title.split(`
|
|
87012
|
+
`, 1)[0] ?? "";
|
|
87013
|
+
if (rules.defaultIgnores && DEFAULT_IGNORES.some((pattern) => pattern.test(title)))
|
|
87014
|
+
return { error: null, notes: [] };
|
|
87015
|
+
const problems = [];
|
|
87016
|
+
const parsed = /^(\w*)(?:\((.*)\))?!?: (.*)$/u.exec(header);
|
|
87017
|
+
if (rules.format && (!parsed || !parsed[1] || !parsed[3]?.trim()))
|
|
87018
|
+
problems.push({
|
|
87019
|
+
level: rules.format,
|
|
87020
|
+
message: `PR title ${JSON.stringify(header)} is not a Conventional Commit "<type>(<scope>): <subject>" (commitlint type-empty/subject-empty); the squash-merge title is the commit and CI lints it`
|
|
87021
|
+
});
|
|
87022
|
+
else if (parsed && rules.types && !rules.types.values.includes(parsed[1]))
|
|
87023
|
+
problems.push({
|
|
87024
|
+
level: rules.types.level,
|
|
87025
|
+
message: `PR title type "${parsed[1]}" is not allowed (commitlint type-enum: ${rules.types.values.join(", ")})`
|
|
87026
|
+
});
|
|
87027
|
+
if (rules.maxHeader && header.length > rules.maxHeader.value)
|
|
87028
|
+
problems.push({
|
|
87029
|
+
level: rules.maxHeader.level,
|
|
87030
|
+
message: `PR title is ${header.length} characters, over the ${rules.maxHeader.value} allowed (commitlint header-max-length); shorten it by ${header.length - rules.maxHeader.value}`
|
|
87031
|
+
});
|
|
87032
|
+
const refused = problems.filter((problem) => problem.level >= 2);
|
|
87033
|
+
return {
|
|
87034
|
+
error: refused.length ? refused.map((problem) => problem.message).join("; ") : null,
|
|
87035
|
+
notes: problems.filter((problem) => problem.level < 2).map((p) => `warning: ${p.message}`)
|
|
87036
|
+
};
|
|
87037
|
+
}
|
|
87038
|
+
function refuseTitle(io, title, line) {
|
|
87039
|
+
const checked = checkPrTitle(io.cwd, title);
|
|
87040
|
+
for (const note of checked.notes)
|
|
87041
|
+
io.stderr(`${note}
|
|
87042
|
+
`);
|
|
87043
|
+
return checked.error ? usage4(io, checked.error, line) : null;
|
|
87044
|
+
}
|
|
86754
87045
|
function readBodyFile(io, file) {
|
|
86755
87046
|
try {
|
|
86756
87047
|
return {
|
|
@@ -86920,6 +87211,9 @@ async function create4(argv, io) {
|
|
|
86920
87211
|
}
|
|
86921
87212
|
if (!base)
|
|
86922
87213
|
return usage4(io, "no default target branch is configured; pass --base <b>", CREATE_USAGE);
|
|
87214
|
+
const given = flags.values.title ? refuseTitle(io, flags.values.title, CREATE_USAGE) : null;
|
|
87215
|
+
if (given !== null)
|
|
87216
|
+
return given;
|
|
86923
87217
|
const connected = connect(io, branch);
|
|
86924
87218
|
if (!connected.ok)
|
|
86925
87219
|
return forgeFail(io, connected);
|
|
@@ -86931,6 +87225,11 @@ async function create4(argv, io) {
|
|
|
86931
87225
|
title ||= filled.data.title;
|
|
86932
87226
|
body ??= filled.data.body;
|
|
86933
87227
|
}
|
|
87228
|
+
if (!flags.values.title) {
|
|
87229
|
+
const filled = refuseTitle(io, title, CREATE_USAGE);
|
|
87230
|
+
if (filled !== null)
|
|
87231
|
+
return filled;
|
|
87232
|
+
}
|
|
86934
87233
|
const forge = connected.data.forge;
|
|
86935
87234
|
const planned = planIssueLinks(io.cwd, {
|
|
86936
87235
|
issues: flags.lists.issue ?? [],
|
|
@@ -87149,6 +87448,11 @@ async function edit(argv, io) {
|
|
|
87149
87448
|
return usage4(io, read, EDIT_USAGE);
|
|
87150
87449
|
body = read.body;
|
|
87151
87450
|
}
|
|
87451
|
+
if (flags.values.title !== undefined) {
|
|
87452
|
+
const edited = refuseTitle(io, flags.values.title, EDIT_USAGE);
|
|
87453
|
+
if (edited !== null)
|
|
87454
|
+
return edited;
|
|
87455
|
+
}
|
|
87152
87456
|
const connected = connect(io);
|
|
87153
87457
|
if (!connected.ok)
|
|
87154
87458
|
return forgeFail(io, connected);
|
|
@@ -87251,7 +87555,19 @@ async function run15(argv, io) {
|
|
|
87251
87555
|
return reply(rest, io);
|
|
87252
87556
|
return usage4(io, sub && !sub.startsWith("-") ? `unknown pr subcommand "${sub}"` : "missing pr subcommand", USAGE9);
|
|
87253
87557
|
}
|
|
87254
|
-
var
|
|
87558
|
+
var CONVENTIONAL_TYPES, COMMITLINT_FILES, DEFAULT_IGNORES, UNCHECKED = (what) => ({
|
|
87559
|
+
rules: null,
|
|
87560
|
+
note: `commitlint config is ${what}; title not pre-checked, CI checks it`
|
|
87561
|
+
}), readRule = (rules, name) => {
|
|
87562
|
+
const rule = rules[name];
|
|
87563
|
+
if (rule === undefined)
|
|
87564
|
+
return null;
|
|
87565
|
+
if (!Array.isArray(rule) || typeof rule[0] !== "number")
|
|
87566
|
+
return "off";
|
|
87567
|
+
if (rule[0] === 0 || rule[1] === "never")
|
|
87568
|
+
return "off";
|
|
87569
|
+
return { level: rule[0], value: rule[2] };
|
|
87570
|
+
}, 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) [--issue <#n|ID|url>]… [--refs] [--label <l>]… [--reviewer <login>]… [--draft] [--json]", MERGE_USAGE = "workit pr merge [--pr <n>] [--squash|--merge|--rebase | --method squash|merge|rebase] [--subject <s>] [--body <b> | --body-file <f|->] [--delete-branch | --keep-branch] [--unverified --reason <why>] [--base-red-ok --reason <why>] [--json]", READY_USAGE = "workit pr ready [--pr <n>] [--undo] [--json]", EDIT_USAGE = "workit pr edit [--pr <n>] [--title <t>] [--body-file <f|->] [--add-label <l>]… [--remove-label <l>]… [--add-reviewer <login>]… [--base <b>] [--json]", THREADS_USAGE = "workit pr threads [--pr <n>] [--json]", REPLY_USAGE = "workit pr reply [--pr <n>] --thread <id> [--body-file <f|->] [--resolve] [--json]", USAGE9 = "workit pr status|create|merge|ready|edit|threads|reply ... (workit help pr)", prLabel = (kind, number) => `${kind === "github" ? "PR #" : "MR !"}${number}`, NEED_TEXT, mergedVerdictLine = (landed) => landed === "untracked" ? "merged outside workit (no merge record)" : landed.unverified ? `merged unverified at ${(landed.head ?? "?").slice(0, 12)} (recorded bypass)` : landed.lane === "none" && !landed.verdictId ? `merged at ${(landed.head ?? "?").slice(0, 12)} with no verdict (lane none)` : landed.review === "self-reviewed" ? `merged self-reviewed (lane self) with the author's verdict ${landed.verdictId ?? "?"} at ${(landed.head ?? "?").slice(0, 12)}` : `merged with accepted verdict ${landed.verdictId ?? "?"} at ${(landed.head ?? "?").slice(0, 12)}${landed.intentOnly ? " (merge intent recorded; the merge call itself failed)" : ""}`, mergedOnLine = (verdict) => {
|
|
87255
87571
|
if (verdict.review === "self-reviewed")
|
|
87256
87572
|
return `self-reviewed (lane ${verdict.lane}): the author's verdict ${verdict.verdictId ?? "?"}; no independent verdict accepted for that head`;
|
|
87257
87573
|
if (!verdict.verdictId)
|
|
@@ -87275,8 +87591,48 @@ var init_pr = __esm(() => {
|
|
|
87275
87591
|
init_lane();
|
|
87276
87592
|
init_pr_lane();
|
|
87277
87593
|
init_vcs_config();
|
|
87594
|
+
init_check_config();
|
|
87278
87595
|
init_output();
|
|
87279
87596
|
init_forge_common();
|
|
87597
|
+
CONVENTIONAL_TYPES = [
|
|
87598
|
+
"build",
|
|
87599
|
+
"chore",
|
|
87600
|
+
"ci",
|
|
87601
|
+
"docs",
|
|
87602
|
+
"feat",
|
|
87603
|
+
"fix",
|
|
87604
|
+
"perf",
|
|
87605
|
+
"refactor",
|
|
87606
|
+
"revert",
|
|
87607
|
+
"style",
|
|
87608
|
+
"test"
|
|
87609
|
+
];
|
|
87610
|
+
COMMITLINT_FILES = [
|
|
87611
|
+
".commitlintrc.json",
|
|
87612
|
+
".commitlintrc",
|
|
87613
|
+
".commitlintrc.yaml",
|
|
87614
|
+
".commitlintrc.yml",
|
|
87615
|
+
".commitlintrc.js",
|
|
87616
|
+
".commitlintrc.cjs",
|
|
87617
|
+
".commitlintrc.mjs",
|
|
87618
|
+
".commitlintrc.ts",
|
|
87619
|
+
"commitlint.config.js",
|
|
87620
|
+
"commitlint.config.cjs",
|
|
87621
|
+
"commitlint.config.mjs",
|
|
87622
|
+
"commitlint.config.ts"
|
|
87623
|
+
];
|
|
87624
|
+
DEFAULT_IGNORES = [
|
|
87625
|
+
/^((Merge pull request)|(Merge (.*?) into (.*?)|(Merge branch (.*?)))(?:\r?\n)*$)/m,
|
|
87626
|
+
/^(Merge tag (.*?))(?:\r?\n)*$/m,
|
|
87627
|
+
/^(R|r)evert (.*)/,
|
|
87628
|
+
/^(R|r)eapply (.*)/,
|
|
87629
|
+
/^(amend|fixup|squash)!/,
|
|
87630
|
+
/^(Merged (.*?)(in|into) (.*)|Merged PR (.*): (.*))/,
|
|
87631
|
+
/^Merge remote-tracking branch(\s*)(.*)/,
|
|
87632
|
+
/^Automatic merge(.*)/,
|
|
87633
|
+
/^Auto-merged (.*?) into (.*)/,
|
|
87634
|
+
/^(chore(\([^)]+\))?:\s*)?v?\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?\s*$/
|
|
87635
|
+
];
|
|
87280
87636
|
NEED_TEXT = {
|
|
87281
87637
|
none: "no verdict",
|
|
87282
87638
|
self: "the author's own --self verdict (or an independent one)",
|
|
@@ -87733,10 +88089,10 @@ async function push(argv, io) {
|
|
|
87733
88089
|
});
|
|
87734
88090
|
if (typeof flags === "string")
|
|
87735
88091
|
return usage4(io, flags, PUSH_USAGE);
|
|
87736
|
-
const release = flags.lists.release;
|
|
88092
|
+
const release = flags.lists.release?.flatMap((value) => value.split(",").map((name) => name.trim()).filter(Boolean));
|
|
87737
88093
|
if (release) {
|
|
87738
88094
|
if (flags.booleans.size || flags.values.expect !== undefined || flags.positionals.length)
|
|
87739
|
-
return usage4(io, "--release takes only ref names (
|
|
88095
|
+
return usage4(io, "--release takes only ref names (a comma list or a repeated flag: --release main,v1.2.0)", PUSH_USAGE);
|
|
87740
88096
|
return releasePush(release, io);
|
|
87741
88097
|
}
|
|
87742
88098
|
if (flags.positionals.length)
|
|
@@ -87838,7 +88194,7 @@ async function run17(argv, io) {
|
|
|
87838
88194
|
return trailers(rest, io);
|
|
87839
88195
|
return usage4(io, sub && !sub.startsWith("-") ? `unknown git subcommand "${sub}"` : "missing git subcommand", USAGE10);
|
|
87840
88196
|
}
|
|
87841
|
-
var BRANCH_USAGE = "workit git branch <name> | --kind feature|bugfix|release|hotfix --slug <s> [--base <b>] [--track <t>] [--carry] [--json]", COMMIT_USAGE = "workit git commit -m|--message <msg>… | -F|--file <file|-> [--trailer <key: value>]… [--amend [--no-edit]] [--allow-empty] [-a|--all | [--] <paths…>] [--json]", PUSH_USAGE = "workit git push [--set-upstream] [--force-with-lease [--expect <sha>] [--overwrite-unintegrated]] [--release <main|develop|v-tag
|
|
88197
|
+
var BRANCH_USAGE = "workit git branch <name> | --kind feature|bugfix|release|hotfix --slug <s> [--base <b>] [--track <t>] [--carry] [--json]", COMMIT_USAGE = "workit git commit -m|--message <msg>… | -F|--file <file|-> [--trailer <key: value>]… [--amend [--no-edit]] [--allow-empty] [-a|--all | [--] <paths…>] [--json]", PUSH_USAGE = "workit git push [--set-upstream] [--force-with-lease [--expect <sha>] [--overwrite-unintegrated]] [--release <main|develop|v-tag>[,…]] [--json]", USAGE10 = "workit git branch|commit|push|trailers ... (workit help git)", short2 = (sha) => sha ? sha.slice(0, 12) : "(none)", COMMIT_SWITCHES, READ_ONLY;
|
|
87842
88198
|
var init_git2 = __esm(() => {
|
|
87843
88199
|
init_autonomy();
|
|
87844
88200
|
init_branch();
|
|
@@ -90128,7 +90484,13 @@ async function run22(argv, io) {
|
|
|
90128
90484
|
type: values.type,
|
|
90129
90485
|
last: last ?? 50
|
|
90130
90486
|
});
|
|
90131
|
-
|
|
90487
|
+
const note = values.type === "finding" && listed.length === 0 ? "findings are not ledger rows; they live in the task: workit finding list [--branch <b>] [--status open|resolved]" : undefined;
|
|
90488
|
+
return emit(io, ok2({
|
|
90489
|
+
path: ledger.value.path,
|
|
90490
|
+
skipped: ledger.value.skipped,
|
|
90491
|
+
rows: listed,
|
|
90492
|
+
...note ? { note } : {}
|
|
90493
|
+
}), (data) => note ? note : data.rows.length ? data.rows.map((row) => {
|
|
90132
90494
|
const line = summarizeRow(row);
|
|
90133
90495
|
return `#${line.seq} ${line.at} ${line.type}${line.branch ? ` [${line.branch}]` : ""}${line.labels.length ? ` (${line.labels.join(", ")})` : ""} ${line.summary}`;
|
|
90134
90496
|
}) : "ledger is empty");
|
|
@@ -106273,7 +106635,7 @@ var init_rules = __esm(() => {
|
|
|
106273
106635
|
|
|
106274
106636
|
// packages/workit-cli/src/test-audit/audit.ts
|
|
106275
106637
|
import { spawnSync as spawnSync29 } from "node:child_process";
|
|
106276
|
-
import { existsSync as
|
|
106638
|
+
import { existsSync as existsSync27, readdirSync as readdirSync14, readFileSync as readFileSync29, statSync as statSync10 } from "node:fs";
|
|
106277
106639
|
import path71 from "node:path";
|
|
106278
106640
|
function git7(cwd, args) {
|
|
106279
106641
|
const run = spawnSync29("git", ["-c", "core.quotepath=off", ...args], {
|
|
@@ -106300,7 +106662,7 @@ function expandPaths(cwd, inputs) {
|
|
|
106300
106662
|
const missing = [];
|
|
106301
106663
|
for (const input of inputs.length > 0 ? inputs : ["."]) {
|
|
106302
106664
|
const full = path71.resolve(cwd, input);
|
|
106303
|
-
if (!
|
|
106665
|
+
if (!existsSync27(full))
|
|
106304
106666
|
missing.push(input);
|
|
106305
106667
|
else if (statSync10(full).isDirectory())
|
|
106306
106668
|
walkTests(full, files);
|
|
@@ -106416,7 +106778,7 @@ var init_audit = __esm(() => {
|
|
|
106416
106778
|
// packages/workit-cli/src/test-audit/mutate.ts
|
|
106417
106779
|
import { spawn as spawn2 } from "node:child_process";
|
|
106418
106780
|
import {
|
|
106419
|
-
existsSync as
|
|
106781
|
+
existsSync as existsSync28,
|
|
106420
106782
|
lstatSync as lstatSync8,
|
|
106421
106783
|
mkdirSync as mkdirSync12,
|
|
106422
106784
|
mkdtempSync as mkdtempSync4,
|
|
@@ -106645,7 +107007,7 @@ function copyWorkingTree(repo) {
|
|
|
106645
107007
|
}
|
|
106646
107008
|
for (const parent of dirs) {
|
|
106647
107009
|
const modules = path72.join(repo, parent, "node_modules");
|
|
106648
|
-
if (
|
|
107010
|
+
if (existsSync28(modules) && !existsSync28(path72.join(tree, parent, "node_modules")))
|
|
106649
107011
|
linkNodeModules(modules, path72.join(tree, parent, "node_modules"), repo, tree);
|
|
106650
107012
|
}
|
|
106651
107013
|
return { dir, tree };
|
|
@@ -106695,7 +107057,7 @@ async function runMutation(options) {
|
|
|
106695
107057
|
const relative = toPosix(path72.relative(repo, absolute));
|
|
106696
107058
|
if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
|
|
106697
107059
|
continue;
|
|
106698
|
-
if (NOT_SOURCE.test(relative) || !
|
|
107060
|
+
if (NOT_SOURCE.test(relative) || !existsSync28(absolute))
|
|
106699
107061
|
continue;
|
|
106700
107062
|
try {
|
|
106701
107063
|
candidates.push(...mutantsFor(readFileSync30(absolute, "utf8"), relative, lines));
|
|
@@ -106885,7 +107247,7 @@ var exports_test_audit = {};
|
|
|
106885
107247
|
__export(exports_test_audit, {
|
|
106886
107248
|
run: () => run23
|
|
106887
107249
|
});
|
|
106888
|
-
import { existsSync as
|
|
107250
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
106889
107251
|
import path73 from "node:path";
|
|
106890
107252
|
function parse8(argv) {
|
|
106891
107253
|
const options = {
|
|
@@ -107009,7 +107371,7 @@ usage: ${USAGE16}`));
|
|
|
107009
107371
|
}
|
|
107010
107372
|
let files;
|
|
107011
107373
|
if (options.diff && changed)
|
|
107012
|
-
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) &&
|
|
107374
|
+
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) && existsSync29(file)).toSorted();
|
|
107013
107375
|
else {
|
|
107014
107376
|
const expanded = expandPaths(io.cwd, options.paths);
|
|
107015
107377
|
if (expanded.missing.length > 0)
|
|
@@ -107457,7 +107819,11 @@ var FAMILY_ACTIONS = {
|
|
|
107457
107819
|
explain: "Explain the policy in force"
|
|
107458
107820
|
},
|
|
107459
107821
|
evidence: { record: "Record evidence against a task's requirements" },
|
|
107460
|
-
finding: {
|
|
107822
|
+
finding: {
|
|
107823
|
+
record: "Record a finding",
|
|
107824
|
+
resolve: "Resolve a finding",
|
|
107825
|
+
list: "List findings with their ids [--branch <b>] [--status open|resolved]"
|
|
107826
|
+
},
|
|
107461
107827
|
decision: {
|
|
107462
107828
|
record: "Record a task decision",
|
|
107463
107829
|
revoke: "Revoke a task decision"
|
|
@@ -107504,7 +107870,7 @@ var familySubcommands = (name) => {
|
|
|
107504
107870
|
const implicit = name === "task" ? TASK_IMPLICIT : [];
|
|
107505
107871
|
const grammar = Object.entries(FAMILY_ACTIONS[name]).filter(([action]) => !implicit.some((entry) => entry.name === action)).map(([action, summary]) => ({
|
|
107506
107872
|
name: action,
|
|
107507
|
-
usage: name === "task" && action === "list" ? `workit task list [--status all] ${FAMILY_OPTIONS}` : name === "policy" && action !== "explain" ? `workit policy ${action} ${POLICY_JUDGE} ${FAMILY_OPTIONS}` : name === "worker" && action !== "assign" ? `workit worker ${action} [<workerId>] ${FAMILY_OPTIONS}` : `workit ${name} ${action} ${FAMILY_OPTIONS}`,
|
|
107873
|
+
usage: name === "task" && action === "list" ? `workit task list [--status all] ${FAMILY_OPTIONS}` : name === "finding" && action === "list" ? "workit finding list [--branch <b>] [--status open|resolved] [--json]" : name === "policy" && action !== "explain" ? `workit policy ${action} ${POLICY_JUDGE} ${FAMILY_OPTIONS}` : name === "worker" && action !== "assign" ? `workit worker ${action} [<workerId>] ${FAMILY_OPTIONS}` : `workit ${name} ${action} ${FAMILY_OPTIONS}`,
|
|
107508
107874
|
summary
|
|
107509
107875
|
}));
|
|
107510
107876
|
return [...implicit, ...grammar];
|
|
@@ -107622,7 +107988,7 @@ var VERBS = [
|
|
|
107622
107988
|
withSubcommands({
|
|
107623
107989
|
name: "workspace",
|
|
107624
107990
|
group: "setup",
|
|
107625
|
-
summary: "Edit workspace entries without the wizard;
|
|
107991
|
+
summary: "Edit workspace entries without the wizard; a raise (rm included) needs the user at a terminal",
|
|
107626
107992
|
subcommands: [
|
|
107627
107993
|
{
|
|
107628
107994
|
name: "list",
|
|
@@ -107638,15 +108004,21 @@ var VERBS = [
|
|
|
107638
108004
|
name: "set",
|
|
107639
108005
|
usage: "workit workspace set <name> <key>=<value>…",
|
|
107640
108006
|
summary: "Change non-grant keys (dotted paths, JSON values, null removes); grants stay with workit grant set"
|
|
108007
|
+
},
|
|
108008
|
+
{
|
|
108009
|
+
name: "rm",
|
|
108010
|
+
usage: "workit workspace rm <name>",
|
|
108011
|
+
summary: "Remove an entry; if another entry or the defaults could grant its folders more, the user confirms at their own terminal"
|
|
107641
108012
|
}
|
|
107642
108013
|
],
|
|
107643
108014
|
examples: [
|
|
107644
108015
|
"workit workspace list",
|
|
107645
108016
|
"workit workspace add kit --glob '/home/me/work/libs/kit/**' --from work",
|
|
107646
|
-
"workit workspace set kit branchPolicy.integration=merge"
|
|
108017
|
+
"workit workspace set kit branchPolicy.integration=merge",
|
|
108018
|
+
"workit workspace rm kit"
|
|
107647
108019
|
],
|
|
107648
108020
|
notes: [
|
|
107649
|
-
"A new entry starts with no grants of its own. It starts at the strictest level of every entry and the defaults, so its folders never get more than they had.
|
|
108021
|
+
"A new entry starts with no grants of its own. It starts at the strictest level of every entry and the defaults, so its folders never get more than they had. rm counts every other entry and the defaults as a possible taker of the removed folders: when any could grant more, it is refused in an agent or headless shell and the user types the name to confirm at their own terminal; it never removes the last entry. Raising a grant, defaultEndpoint or verification needs the user: workit grant set <name> <kind>=<value> in their own terminal.",
|
|
107650
108022
|
"Every write keeps the previous file as workspaces.json.bak. `workit doctor` lists overlapping globs and which entry wins."
|
|
107651
108023
|
],
|
|
107652
108024
|
load: () => Promise.resolve().then(() => (init_workspace(), exports_workspace))
|
|
@@ -107819,7 +108191,7 @@ var VERBS = [
|
|
|
107819
108191
|
{
|
|
107820
108192
|
name: "push",
|
|
107821
108193
|
deferredFlags: ["force"],
|
|
107822
|
-
usage: "workit git push [-u|--set-upstream] [--force-with-lease [--expect <sha>] [--overwrite-unintegrated]] [--release <main|develop|v-tag
|
|
108194
|
+
usage: "workit git push [-u|--set-upstream] [--force-with-lease [--expect <sha>] [--overwrite-unintegrated]] [--release <main|develop|v-tag>[,…]]",
|
|
107823
108195
|
summary: "Push the current branch and verify the remote tip (never a blind --force); --release finishes a git-flow release"
|
|
107824
108196
|
},
|
|
107825
108197
|
{
|
|
@@ -107989,7 +108361,7 @@ var VERBS = [
|
|
|
107989
108361
|
name: "list",
|
|
107990
108362
|
aliases: ["show"],
|
|
107991
108363
|
usage: "workit ledger list|show [--branch <b>] [--pr <n>] [--type <t>] [--last <n>]",
|
|
107992
|
-
summary: "List ledger rows, newest last"
|
|
108364
|
+
summary: "List ledger rows, newest last (findings live in the task: workit finding list)"
|
|
107993
108365
|
},
|
|
107994
108366
|
{
|
|
107995
108367
|
name: "check",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.40.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
6
6
|
"keywords": [
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@babel/parser": "7.29.9",
|
|
41
|
-
"@brainervirus/workit-cursor": "^8.
|
|
41
|
+
"@brainervirus/workit-cursor": "^8.40.0",
|
|
42
42
|
"@inkjs/ui": "2.0.0",
|
|
43
43
|
"ink": "7.1.1",
|
|
44
44
|
"react": "19.2.8"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@brainervirus/workit-core": "^8.
|
|
47
|
+
"@brainervirus/workit-core": "^8.40.0"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=24"
|