@brainervirus/workit-cli 8.9.0 → 8.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +179 -46
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -65,7 +65,7 @@ var package_default;
|
|
|
65
65
|
var init_package = __esm(() => {
|
|
66
66
|
package_default = {
|
|
67
67
|
name: "@brainervirus/workit-cli",
|
|
68
|
-
version: "8.9.
|
|
68
|
+
version: "8.9.1",
|
|
69
69
|
private: false,
|
|
70
70
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
71
71
|
keywords: [
|
|
@@ -103,9 +103,9 @@ var init_package = __esm(() => {
|
|
|
103
103
|
},
|
|
104
104
|
dependencies: {
|
|
105
105
|
"@babel/parser": "7.29.9",
|
|
106
|
-
"@brainervirus/workit-core": "^8.9.
|
|
107
|
-
"@brainervirus/workit-cursor": "^8.9.
|
|
108
|
-
"@brainervirus/workit-opencode": "^8.9.
|
|
106
|
+
"@brainervirus/workit-core": "^8.9.1",
|
|
107
|
+
"@brainervirus/workit-cursor": "^8.9.1",
|
|
108
|
+
"@brainervirus/workit-opencode": "^8.9.1",
|
|
109
109
|
"@inkjs/ui": "2.0.0",
|
|
110
110
|
ink: "7.1.1",
|
|
111
111
|
react: "19.2.8"
|
|
@@ -11079,6 +11079,66 @@ class TaskStore {
|
|
|
11079
11079
|
return bound;
|
|
11080
11080
|
return success(null, null, { key: key.data, bound: bound.data });
|
|
11081
11081
|
}
|
|
11082
|
+
taskForWorker(workerId) {
|
|
11083
|
+
if (typeof workerId !== "string" || !validId(workerId))
|
|
11084
|
+
return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
|
|
11085
|
+
const listed = this.listTaskIndex();
|
|
11086
|
+
if (!listed.ok)
|
|
11087
|
+
return listed;
|
|
11088
|
+
for (const entry of listed.data) {
|
|
11089
|
+
if (entry.status === "closed")
|
|
11090
|
+
continue;
|
|
11091
|
+
const loaded = this.load(entry.id);
|
|
11092
|
+
if (!loaded.ok)
|
|
11093
|
+
return loaded;
|
|
11094
|
+
if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
|
|
11095
|
+
return success(null, null, entry.id);
|
|
11096
|
+
}
|
|
11097
|
+
return success(null, null, null);
|
|
11098
|
+
}
|
|
11099
|
+
originTaskEntry() {
|
|
11100
|
+
const key = this.currentKey();
|
|
11101
|
+
const location = this.location();
|
|
11102
|
+
const branch = key.ok ? key.data.branch : null;
|
|
11103
|
+
if (!branch || !location.ok)
|
|
11104
|
+
return success(null, null, null);
|
|
11105
|
+
const common = path8.dirname(location.data.dir);
|
|
11106
|
+
const heads = path8.join(common, "logs", "refs", "heads");
|
|
11107
|
+
const headLog = location.data.git ? path8.join(location.data.git.gitDir, "logs", "HEAD") : "";
|
|
11108
|
+
const signatures = [
|
|
11109
|
+
path8.join(heads, branch),
|
|
11110
|
+
headLog,
|
|
11111
|
+
heads,
|
|
11112
|
+
path8.join(common, "packed-refs")
|
|
11113
|
+
].map((file) => fileSignature(file) ?? "-");
|
|
11114
|
+
const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
|
|
11115
|
+
let resolved = origins.get(slot);
|
|
11116
|
+
if (resolved?.signature !== signatures.join("|")) {
|
|
11117
|
+
const renames = branchRenames(location.data);
|
|
11118
|
+
const aliases = [branch];
|
|
11119
|
+
for (const rename of renames.toReversed())
|
|
11120
|
+
if (rename.to === aliases.at(-1))
|
|
11121
|
+
aliases.push(rename.from);
|
|
11122
|
+
const start = branchStart(location.data, branch, aliases);
|
|
11123
|
+
const slash = start?.indexOf("/") ?? -1;
|
|
11124
|
+
const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(path8.join(common, "config")).includes(`[remote "${start.slice(0, slash)}"]`));
|
|
11125
|
+
const name = start && (remote ? start.slice(slash + 1) : start);
|
|
11126
|
+
resolved = {
|
|
11127
|
+
signature: signatures.join("|"),
|
|
11128
|
+
name: name && !aliases.includes(name) ? name : null,
|
|
11129
|
+
renames
|
|
11130
|
+
};
|
|
11131
|
+
origins.set(slot, resolved);
|
|
11132
|
+
}
|
|
11133
|
+
const entry = resolved.name ? this.openTasksForKey(resolved.name, resolved.renames) : null;
|
|
11134
|
+
if (entry && !entry.ok)
|
|
11135
|
+
return entry;
|
|
11136
|
+
return success(null, null, entry?.data[0] ? { origin: `branch ${resolved.name}`, entry: entry.data[0] } : null);
|
|
11137
|
+
}
|
|
11138
|
+
readStoreTask(taskId) {
|
|
11139
|
+
const loaded = this.load(taskId);
|
|
11140
|
+
return loaded.ok ? success(null, null, loaded.data?.record ?? null) : loaded;
|
|
11141
|
+
}
|
|
11082
11142
|
create(input, provenance, expectedWorkspaceRevision) {
|
|
11083
11143
|
const value = "intent" in input ? input : {
|
|
11084
11144
|
intent: input,
|
|
@@ -11748,12 +11808,12 @@ class TaskStore {
|
|
|
11748
11808
|
return 0;
|
|
11749
11809
|
}
|
|
11750
11810
|
}
|
|
11751
|
-
openTasksForKey(key) {
|
|
11811
|
+
openTasksForKey(key, known) {
|
|
11752
11812
|
const all = this.listStoreIndex();
|
|
11753
11813
|
if (!all.ok)
|
|
11754
11814
|
return all;
|
|
11755
|
-
const location = this.location();
|
|
11756
|
-
const renames = location
|
|
11815
|
+
const location = known ? null : this.location();
|
|
11816
|
+
const renames = known ?? (location?.ok ? branchRenames(location.data) : []);
|
|
11757
11817
|
return success(null, null, all.data.filter((entry) => entry.key !== null && entry.status !== "closed").filter((entry) => (renames.length ? followRenames(entry.key, entry.boundAt ?? entry.createdAt, renames) : entry.key) === key).toSorted(oldestFirst));
|
|
11758
11818
|
}
|
|
11759
11819
|
openTaskForKey(key) {
|
|
@@ -12440,7 +12500,34 @@ var MIGRATION_PENDING = "workit migration pending", STORE_FORMAT = 3, STORE_MIN_
|
|
|
12440
12500
|
return left > right;
|
|
12441
12501
|
}
|
|
12442
12502
|
return false;
|
|
12443
|
-
}, validId = (value) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value),
|
|
12503
|
+
}, validId = (value) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value), readText = (file) => {
|
|
12504
|
+
try {
|
|
12505
|
+
return fs8.readFileSync(file, "utf8");
|
|
12506
|
+
} catch {
|
|
12507
|
+
return "";
|
|
12508
|
+
}
|
|
12509
|
+
}, REFLOG_LINE, branchStart = (location, branch, aliases) => {
|
|
12510
|
+
const first = readText(path8.join(path8.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
|
|
12511
|
+
`, 1)[0];
|
|
12512
|
+
const created = REFLOG_LINE.exec(first);
|
|
12513
|
+
const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
|
|
12514
|
+
if (!created || !start)
|
|
12515
|
+
return null;
|
|
12516
|
+
if (start !== "HEAD")
|
|
12517
|
+
return start;
|
|
12518
|
+
if (!location.git)
|
|
12519
|
+
return null;
|
|
12520
|
+
for (const line of readText(path8.join(location.git.gitDir, "logs", "HEAD")).split(`
|
|
12521
|
+
`)) {
|
|
12522
|
+
const entry = REFLOG_LINE.exec(line);
|
|
12523
|
+
const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
|
|
12524
|
+
const seconds = entry ? Number(entry[2]) - Number(created[2]) : -1;
|
|
12525
|
+
if (moved && entry[1] === created[1] && seconds >= 0 && seconds <= 1 && aliases.includes(moved[2]))
|
|
12526
|
+
return moved[1];
|
|
12527
|
+
}
|
|
12528
|
+
return null;
|
|
12529
|
+
}, refExists = (common, ref) => fs8.existsSync(path8.join(common, ref)) || readText(path8.join(common, "packed-refs")).includes(` ${ref}
|
|
12530
|
+
`), origins, sameDirectoryIdentity = (left, right) => {
|
|
12444
12531
|
if (!path8.isAbsolute(left) || !path8.isAbsolute(right))
|
|
12445
12532
|
return false;
|
|
12446
12533
|
const normalizedLeft = path8.resolve(left);
|
|
@@ -12488,6 +12575,8 @@ var init_task_store = __esm(() => {
|
|
|
12488
12575
|
AUTO_COMPACT_BYTES = 2 * 1024 * 1024;
|
|
12489
12576
|
TOMBSTONE = Symbol("tombstone");
|
|
12490
12577
|
STALE_TEMPORARY_MS = 60 * 60000;
|
|
12578
|
+
REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
|
|
12579
|
+
origins = new Map;
|
|
12491
12580
|
heldInProcess = new Map;
|
|
12492
12581
|
});
|
|
12493
12582
|
|
|
@@ -16442,38 +16531,29 @@ function reconcileResume(view, observations = []) {
|
|
|
16442
16531
|
reassessmentRequired: view.task.policy?.policyVersion !== POLICY_VERSION
|
|
16443
16532
|
});
|
|
16444
16533
|
}
|
|
16445
|
-
function compactTaskContext(view) {
|
|
16446
|
-
const decisions =
|
|
16447
|
-
|
|
16448
|
-
|
|
16449
|
-
|
|
16450
|
-
|
|
16451
|
-
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
16452
|
-
}).slice(0, COMPACT_MAX_ITEMS).map((entry) => ({
|
|
16453
|
-
id: entry.id,
|
|
16454
|
-
purpose: entry.data.purpose,
|
|
16455
|
-
status: entry.data.response,
|
|
16456
|
-
digest: entry.data.digest,
|
|
16457
|
-
choice: compactDecisionChoice(entry) || `task.inspect taskId=${view.task.id} view=full; decision=${entry.id}`,
|
|
16458
|
-
references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference)
|
|
16459
|
-
}));
|
|
16460
|
-
const methods = view.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
|
|
16534
|
+
function compactTaskContext(view, inherited = null) {
|
|
16535
|
+
const decisions = compactDecisions([
|
|
16536
|
+
view && { origin: null, taskId: view.task.id, decisions: view.task.decisions },
|
|
16537
|
+
inherited
|
|
16538
|
+
]);
|
|
16539
|
+
const methods = view?.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
|
|
16461
16540
|
id: method.id,
|
|
16462
16541
|
assurance: method.assurance,
|
|
16463
16542
|
reason: compactText(method.reason, COMPACT_TEXT_BYTES) ?? ""
|
|
16464
16543
|
})) : [];
|
|
16544
|
+
const stale = view?.evidence.filter((entry) => entry.status === "stale").length;
|
|
16465
16545
|
const gaps = Array.from(new Set([
|
|
16466
|
-
...
|
|
16467
|
-
...view
|
|
16468
|
-
...view
|
|
16546
|
+
...stale ? [`stale evidence: ${stale}; workit task inspect --task ${view.task.id} --view full`] : [],
|
|
16547
|
+
...(view?.requirements ?? []).filter((entry) => entry.status !== "satisfied").map((entry) => entry.reason),
|
|
16548
|
+
...(view?.task.progress.blockers ?? []).map((entry) => entry.reason)
|
|
16469
16549
|
])).toSorted().slice(0, COMPACT_MAX_ITEMS).map((gap) => compactText(gap, COMPACT_TEXT_BYTES));
|
|
16470
16550
|
const context = {
|
|
16471
|
-
objective: compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "",
|
|
16472
|
-
status: view
|
|
16551
|
+
objective: view ? compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "" : "no task on this branch yet",
|
|
16552
|
+
status: view?.task.status ?? null,
|
|
16473
16553
|
decisions,
|
|
16474
16554
|
methods,
|
|
16475
16555
|
gaps,
|
|
16476
|
-
nextAction: compactText(view
|
|
16556
|
+
nextAction: compactText(view?.task.progress.nextAction ?? null, COMPACT_TEXT_BYTES)
|
|
16477
16557
|
};
|
|
16478
16558
|
let encoded = JSON.stringify(context);
|
|
16479
16559
|
while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.methods.length || context.gaps.length)) {
|
|
@@ -16516,7 +16596,21 @@ var COMPACT_MAX_BYTES = 4096, COMPACT_MAX_ITEMS = 8, COMPACT_TEXT_BYTES = 128, s
|
|
|
16516
16596
|
id: ref.id
|
|
16517
16597
|
};
|
|
16518
16598
|
return { kind: ref.kind };
|
|
16519
|
-
},
|
|
16599
|
+
}, newestDecisionFirst = (left, right) => {
|
|
16600
|
+
const leftAt = compactTimestamp(left.recordedAt);
|
|
16601
|
+
const rightAt = compactTimestamp(right.recordedAt);
|
|
16602
|
+
if (leftAt !== rightAt)
|
|
16603
|
+
return leftAt > rightAt ? -1 : 1;
|
|
16604
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
16605
|
+
}, compactDecisions = (sources) => sources.flatMap((source) => source ? source.decisions.toSorted(newestDecisionFirst).map((entry) => ({
|
|
16606
|
+
id: entry.id,
|
|
16607
|
+
purpose: entry.data.purpose,
|
|
16608
|
+
status: entry.data.response,
|
|
16609
|
+
digest: entry.data.digest,
|
|
16610
|
+
choice: compactDecisionChoice(entry) || `task.inspect taskId=${source.taskId} view=full; decision=${entry.id}`,
|
|
16611
|
+
references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference),
|
|
16612
|
+
origin: source.origin ?? undefined
|
|
16613
|
+
})) : []).slice(0, COMPACT_MAX_ITEMS), exportDigest = (bundle) => sha256({
|
|
16520
16614
|
schemaVersion: bundle.schemaVersion,
|
|
16521
16615
|
exportedAt: bundle.exportedAt,
|
|
16522
16616
|
sourceWorkspaceId: bundle.sourceWorkspaceId,
|
|
@@ -17256,6 +17350,17 @@ class WorkitCore {
|
|
|
17256
17350
|
const root = this.contextRootError();
|
|
17257
17351
|
if (!root.ok)
|
|
17258
17352
|
return root;
|
|
17353
|
+
const addressed = WORKER_ADDRESSED_ACTIONS.has(action);
|
|
17354
|
+
const workerId = addressed ? value.workerId : this.context.workerId ?? null;
|
|
17355
|
+
if (workerId !== null) {
|
|
17356
|
+
const owner = this.store.taskForWorker(workerId);
|
|
17357
|
+
if (!owner.ok)
|
|
17358
|
+
return owner;
|
|
17359
|
+
if (owner.data)
|
|
17360
|
+
return success(null, null, { ...request, taskId: owner.data });
|
|
17361
|
+
if (addressed)
|
|
17362
|
+
return failure2("not_found", `worker ${workerId} is on no open task; find its task with \`workit task status --all\`, then run \`${workerCommand("<task-id>", request)}\``);
|
|
17363
|
+
}
|
|
17259
17364
|
const create = CREATING_ACTIONS.has(action) && (this.context.workerId ?? null) === null;
|
|
17260
17365
|
const found = this.store.implicitTask({
|
|
17261
17366
|
provenance: provenance(this.context),
|
|
@@ -17962,7 +18067,9 @@ class WorkitCore {
|
|
|
17962
18067
|
if (!resolved.ok)
|
|
17963
18068
|
return resolved;
|
|
17964
18069
|
const value = resolved.data;
|
|
17965
|
-
|
|
18070
|
+
const result = this.retryOmittedRevisions(value, () => this.workerOnce(value));
|
|
18071
|
+
const { action, taskId } = value ?? {};
|
|
18072
|
+
return result.ok || request?.taskId !== undefined || typeof taskId !== "string" || !WORKER_ADDRESSED_ACTIONS.has(`worker.${String(action)}`) ? result : { ...result, error: `${result.error}; run \`${workerCommand(taskId, value)}\`` };
|
|
17966
18073
|
}
|
|
17967
18074
|
workerOnce(request) {
|
|
17968
18075
|
const root = this.contextRootError();
|
|
@@ -18167,10 +18274,18 @@ class WorkitCore {
|
|
|
18167
18274
|
requirements
|
|
18168
18275
|
});
|
|
18169
18276
|
}
|
|
18170
|
-
compactContext(taskId, freshness) {
|
|
18277
|
+
compactContext(taskId, freshness, origin = null) {
|
|
18171
18278
|
const root = this.contextRootError();
|
|
18172
18279
|
if (!root.ok)
|
|
18173
18280
|
return root;
|
|
18281
|
+
const base = origin && this.store.readStoreTask(origin.taskId);
|
|
18282
|
+
const inherited = base?.ok && base.data ? {
|
|
18283
|
+
origin: origin.origin,
|
|
18284
|
+
taskId: base.data.id,
|
|
18285
|
+
decisions: base.data.decisions.filter((entry) => entry.data.revoked === null)
|
|
18286
|
+
} : null;
|
|
18287
|
+
if (taskId === null)
|
|
18288
|
+
return success(null, null, inherited?.decisions.length ? compactTaskContext(null, inherited) : "");
|
|
18174
18289
|
const task = this.store.readTask(taskId);
|
|
18175
18290
|
if (!task.ok)
|
|
18176
18291
|
return task;
|
|
@@ -18180,7 +18295,7 @@ class WorkitCore {
|
|
|
18180
18295
|
const view = this.view(task.data, false, freshness ?? signalFreshness(this.store.root));
|
|
18181
18296
|
if (!view.ok)
|
|
18182
18297
|
return view;
|
|
18183
|
-
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data));
|
|
18298
|
+
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data, inherited));
|
|
18184
18299
|
}
|
|
18185
18300
|
view(task, capture = true, freshness = treeFreshness(this.store.root)) {
|
|
18186
18301
|
const workspace = this.store.readWorkspace();
|
|
@@ -18591,7 +18706,12 @@ var MAX_JUDGED_REFS = 5, workspaceVerification = (root) => {
|
|
|
18591
18706
|
return changed;
|
|
18592
18707
|
const updated = changed.data.task.workers.find((candidate) => candidate.id === input.workerId);
|
|
18593
18708
|
return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during lifecycle observation");
|
|
18594
|
-
}, refsWithinScope = (refs, scope) => refs.every((ref) => ref.kind !== "file" || scopeCovers(scope, { description: "", paths: [ref.path], exclusions: [] })), TASK_SCOPED_ACTIONS,
|
|
18709
|
+
}, refsWithinScope = (refs, scope) => refs.every((ref) => ref.kind !== "file" || scopeCovers(scope, { description: "", paths: [ref.path], exclusions: [] })), TASK_SCOPED_ACTIONS, WORKER_ADDRESSED_ACTIONS, workerCommand = (taskId, request) => {
|
|
18710
|
+
const { action, workerId, reason, report } = request;
|
|
18711
|
+
const rest = JSON.stringify({ reason, report });
|
|
18712
|
+
const payload = rest === "{}" ? "" : ` --payload '${rest.replace(/'/gu, "'\\''")}'`;
|
|
18713
|
+
return `workit worker ${String(action)} ${String(workerId)} --task ${taskId}${payload}`;
|
|
18714
|
+
}, CREATING_ACTIONS, REVISION_RETRY_ATTEMPTS = 8, retryPause, filledRevisions = (request) => {
|
|
18595
18715
|
const value = typeof request === "object" && request !== null ? request : {};
|
|
18596
18716
|
return {
|
|
18597
18717
|
task: value.expectedRevision === undefined,
|
|
@@ -18813,6 +18933,7 @@ var init_task_engine = __esm(() => {
|
|
|
18813
18933
|
"worker.cancel",
|
|
18814
18934
|
"state.export"
|
|
18815
18935
|
]);
|
|
18936
|
+
WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
|
|
18816
18937
|
CREATING_ACTIONS = new Set([
|
|
18817
18938
|
"task.revise",
|
|
18818
18939
|
"task.progress",
|
|
@@ -19533,9 +19654,10 @@ async function payloadValue(raw, deps) {
|
|
|
19533
19654
|
}
|
|
19534
19655
|
}
|
|
19535
19656
|
function inject(request, key, value) {
|
|
19657
|
+
const given = key === "workerId" ? "positional worker id" : "explicit flag";
|
|
19536
19658
|
if (key in request && !same(request[key], value))
|
|
19537
|
-
return failure2("invalid_input", `payload ${key} conflicts with the
|
|
19538
|
-
fields: [{ path: key, reason:
|
|
19659
|
+
return failure2("invalid_input", `payload ${key} conflicts with the ${given}`, {
|
|
19660
|
+
fields: [{ path: key, reason: `${given} conflicts with payload` }]
|
|
19539
19661
|
});
|
|
19540
19662
|
request[key] = value;
|
|
19541
19663
|
return success(null, null, null);
|
|
@@ -19558,12 +19680,18 @@ async function parseTaskArgs(argv, deps) {
|
|
|
19558
19680
|
let workspaceRevision;
|
|
19559
19681
|
let view;
|
|
19560
19682
|
let actor;
|
|
19683
|
+
let workerId;
|
|
19684
|
+
const takesWorkerId = family === "worker" && (action === "cancel" || action === "report");
|
|
19561
19685
|
let json = jsonRequested;
|
|
19562
19686
|
const judge = [];
|
|
19563
19687
|
const seen = new Set;
|
|
19564
19688
|
for (let i = 2;i < argv.length; i += 1) {
|
|
19565
19689
|
if (argv[i] === "--") {
|
|
19566
19690
|
const extra = argv.slice(i + 1);
|
|
19691
|
+
if (takesWorkerId && workerId === undefined && extra.length === 1) {
|
|
19692
|
+
workerId = extra[0];
|
|
19693
|
+
break;
|
|
19694
|
+
}
|
|
19567
19695
|
if (extra.length)
|
|
19568
19696
|
return parseUsage(`${family} ${actionName} takes no positional arguments (got: ${extra.join(" ")})`, json);
|
|
19569
19697
|
break;
|
|
@@ -19593,6 +19721,10 @@ async function parseTaskArgs(argv, deps) {
|
|
|
19593
19721
|
json = true;
|
|
19594
19722
|
continue;
|
|
19595
19723
|
}
|
|
19724
|
+
if (takesWorkerId && workerId === undefined && !argv[i].startsWith("-")) {
|
|
19725
|
+
workerId = argv[i];
|
|
19726
|
+
continue;
|
|
19727
|
+
}
|
|
19596
19728
|
if (!["--payload", "--task", "--revision", "--workspace-revision", "--view", "--actor"].includes(token))
|
|
19597
19729
|
return parseUsage(`unknown argument: ${argv[i]}`, json);
|
|
19598
19730
|
const value = inline ?? argv[++i];
|
|
@@ -19628,6 +19760,7 @@ async function parseTaskArgs(argv, deps) {
|
|
|
19628
19760
|
for (const [key, value] of [
|
|
19629
19761
|
["action", action],
|
|
19630
19762
|
...taskId === undefined ? [] : [["taskId", taskId]],
|
|
19763
|
+
...workerId === undefined ? [] : [["workerId", workerId]],
|
|
19631
19764
|
...revision === undefined ? [] : [["expectedRevision", revision]],
|
|
19632
19765
|
...workspaceRevision === undefined ? [] : [["expectedWorkspaceRevision", workspaceRevision]],
|
|
19633
19766
|
...view === undefined ? [] : [["view", view]]
|
|
@@ -63965,12 +64098,12 @@ function inspectSessionHook(cwd, env = process.env) {
|
|
|
63965
64098
|
return { state: "not_git", ...none };
|
|
63966
64099
|
const hookPath = path30.join(hooksDir, SESSION_HOOK_NAME);
|
|
63967
64100
|
const helperPath = path30.join(commonDir, ...HELPER);
|
|
63968
|
-
const helperCurrent =
|
|
64101
|
+
const helperCurrent = readText2(helperPath) === SESSION_TRAILER_SCRIPT;
|
|
63969
64102
|
const leftover = leftoverOf(hooksDir);
|
|
63970
64103
|
const base = { hooksDir, hookPath, helperPath, helperCurrent, ...leftover ? { leftover } : {} };
|
|
63971
64104
|
const blocked = (reason, owner, text = "") => {
|
|
63972
64105
|
const old = `${hookPath}.old`;
|
|
63973
|
-
const displaced =
|
|
64106
|
+
const displaced = readText2(old)?.includes(SESSION_HOOK_MARKER) ? old : null;
|
|
63974
64107
|
const input = { owner, text, hooksDir, hookPath, top: top.out, displaced };
|
|
63975
64108
|
const manualTarget = manualTargetOf(input);
|
|
63976
64109
|
const owned = text ? { owner } : {};
|
|
@@ -63993,7 +64126,7 @@ function inspectSessionHook(cwd, env = process.env) {
|
|
|
63993
64126
|
};
|
|
63994
64127
|
if (!inside2(hooksDir, commonDir) && !inside2(hooksDir, top.out))
|
|
63995
64128
|
return blocked(`core.hooksPath ${hooksDir} is outside the repository; a hook there runs in every repository that uses it`, "other");
|
|
63996
|
-
const text = exists(hookPath) ?
|
|
64129
|
+
const text = exists(hookPath) ? readText2(hookPath) ?? "" : null;
|
|
63997
64130
|
if (text !== null) {
|
|
63998
64131
|
if (text === SESSION_HOOK_SCRIPT)
|
|
63999
64132
|
return { state: helperCurrent ? "installed" : "outdated", ...base };
|
|
@@ -64044,7 +64177,7 @@ function installSessionHook(cwd, env = process.env) {
|
|
|
64044
64177
|
detail: `${status.reason}${helper}`
|
|
64045
64178
|
};
|
|
64046
64179
|
const fresh = status.state === "missing";
|
|
64047
|
-
const slotCurrent =
|
|
64180
|
+
const slotCurrent = readText2(status.hookPath) === SESSION_HOOK_SCRIPT;
|
|
64048
64181
|
if (!slotCurrent)
|
|
64049
64182
|
writeExecutable(status.hookPath, SESSION_HOOK_SCRIPT);
|
|
64050
64183
|
const verb = fresh ? "installed" : "updated";
|
|
@@ -64113,7 +64246,7 @@ exit 0
|
|
|
64113
64246
|
}, inside2 = (child, parent) => {
|
|
64114
64247
|
const rel = path30.relative(path30.resolve(parent), path30.resolve(child));
|
|
64115
64248
|
return rel === "" || !rel.startsWith("..") && !path30.isAbsolute(rel);
|
|
64116
|
-
},
|
|
64249
|
+
}, readText2 = (file) => {
|
|
64117
64250
|
try {
|
|
64118
64251
|
return readFileSync13(file, "utf8");
|
|
64119
64252
|
} catch {
|
|
@@ -64171,10 +64304,10 @@ exit 0
|
|
|
64171
64304
|
}, manualInPlace = (input, target) => {
|
|
64172
64305
|
if (input.owner === "lefthook")
|
|
64173
64306
|
return LEFTHOOK_YAML.some((name) => {
|
|
64174
|
-
const text =
|
|
64307
|
+
const text = readText2(path30.join(input.top, name));
|
|
64175
64308
|
return text !== null && lefthookRunsHelper(text);
|
|
64176
64309
|
});
|
|
64177
|
-
const text =
|
|
64310
|
+
const text = readText2(target);
|
|
64178
64311
|
if (text === null || !runsHelperText(text))
|
|
64179
64312
|
return false;
|
|
64180
64313
|
return input.owner === "husky" && target !== input.hookPath || isExecutable(target);
|
|
@@ -64209,7 +64342,7 @@ exit 0
|
|
|
64209
64342
|
}, leftoverOf = (hooksDir) => {
|
|
64210
64343
|
const chained = path30.join(hooksDir, LEGACY_CHAINED);
|
|
64211
64344
|
const commitMsg = path30.join(hooksDir, "commit-msg");
|
|
64212
|
-
const oldOurs =
|
|
64345
|
+
const oldOurs = readText2(commitMsg)?.includes(SESSION_HOOK_MARKER) ?? false;
|
|
64213
64346
|
if (exists(chained))
|
|
64214
64347
|
return oldOurs ? `${chained} was left by an earlier Workit build: move it back to ${commitMsg} (replacing Workit's old hook there)` : `${chained} was left by an earlier Workit build and nothing runs it: if it is your original commit-msg hook, move it back to ${commitMsg}; otherwise delete it`;
|
|
64215
64348
|
if (oldOurs)
|
|
@@ -98111,7 +98244,7 @@ var familySubcommands = (name) => {
|
|
|
98111
98244
|
const implicit = name === "task" ? TASK_IMPLICIT : [];
|
|
98112
98245
|
const grammar = Object.entries(FAMILY_ACTIONS[name]).filter(([action]) => !implicit.some((entry) => entry.name === action)).map(([action, summary]) => ({
|
|
98113
98246
|
name: action,
|
|
98114
|
-
usage: name === "policy" && action !== "explain" ? `workit policy ${action} ${POLICY_JUDGE} ${FAMILY_OPTIONS}` : `workit ${name} ${action} ${FAMILY_OPTIONS}`,
|
|
98247
|
+
usage: 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}`,
|
|
98115
98248
|
summary
|
|
98116
98249
|
}));
|
|
98117
98250
|
return [...implicit, ...grammar];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cli",
|
|
3
|
-
"version": "8.9.
|
|
3
|
+
"version": "8.9.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
6
6
|
"keywords": [
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@babel/parser": "7.29.9",
|
|
41
|
-
"@brainervirus/workit-core": "^8.9.
|
|
42
|
-
"@brainervirus/workit-cursor": "^8.9.
|
|
43
|
-
"@brainervirus/workit-opencode": "^8.9.
|
|
41
|
+
"@brainervirus/workit-core": "^8.9.1",
|
|
42
|
+
"@brainervirus/workit-cursor": "^8.9.1",
|
|
43
|
+
"@brainervirus/workit-opencode": "^8.9.1",
|
|
44
44
|
"@inkjs/ui": "2.0.0",
|
|
45
45
|
"ink": "7.1.1",
|
|
46
46
|
"react": "19.2.8"
|