@brainervirus/workit-cli 8.14.0 → 8.14.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 +52 -14
- package/package.json +3 -3
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.14.
|
|
68
|
+
version: "8.14.1",
|
|
69
69
|
private: false,
|
|
70
70
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
71
71
|
keywords: [
|
|
@@ -103,13 +103,13 @@ var init_package = __esm(() => {
|
|
|
103
103
|
},
|
|
104
104
|
dependencies: {
|
|
105
105
|
"@babel/parser": "7.29.9",
|
|
106
|
-
"@brainervirus/workit-cursor": "^8.14.
|
|
106
|
+
"@brainervirus/workit-cursor": "^8.14.1",
|
|
107
107
|
"@inkjs/ui": "2.0.0",
|
|
108
108
|
ink: "7.1.1",
|
|
109
109
|
react: "19.2.8"
|
|
110
110
|
},
|
|
111
111
|
devDependencies: {
|
|
112
|
-
"@brainervirus/workit-core": "^8.14.
|
|
112
|
+
"@brainervirus/workit-core": "^8.14.1"
|
|
113
113
|
},
|
|
114
114
|
engines: {
|
|
115
115
|
node: ">=24"
|
|
@@ -7977,6 +7977,16 @@ var init_zod = __esm(() => {
|
|
|
7977
7977
|
|
|
7978
7978
|
// packages/workit-core/src/core/task-contract.ts
|
|
7979
7979
|
import { createHash, randomUUID } from "node:crypto";
|
|
7980
|
+
function resolveIdRef(kind, ref, ids) {
|
|
7981
|
+
if (ids.includes(ref))
|
|
7982
|
+
return success(null, null, ref);
|
|
7983
|
+
const matches = ids.filter((candidate) => candidate.startsWith(ref));
|
|
7984
|
+
if (matches.length === 1)
|
|
7985
|
+
return success(null, null, matches[0]);
|
|
7986
|
+
if (matches.length === 0)
|
|
7987
|
+
return failure2("not_found", `${kind} not found`);
|
|
7988
|
+
return failure2("invalid_input", `${kind} prefix ${ref} is ambiguous; candidates: ${matches.join(", ")}`);
|
|
7989
|
+
}
|
|
7980
7990
|
function parseOperation(family, input) {
|
|
7981
7991
|
if (typeof input === "object" && input !== null && "schemaVersion" in input && input.schemaVersion !== SCHEMA_VERSION)
|
|
7982
7992
|
return failure2("unsupported_version", "unsupported schema version", { operation: family });
|
|
@@ -8079,7 +8089,7 @@ var SCHEMA_VERSION = 1, POLICY_VERSION = "1.0.0", OPERATION_FAMILIES, uuidPatter
|
|
|
8079
8089
|
return true;
|
|
8080
8090
|
}
|
|
8081
8091
|
return false;
|
|
8082
|
-
}, text, id, digest, revision, validUtc = (value) => {
|
|
8092
|
+
}, text, id, idRefPattern, idRef, digest, revision, validUtc = (value) => {
|
|
8083
8093
|
const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?Z$/.exec(value);
|
|
8084
8094
|
if (!match)
|
|
8085
8095
|
return false;
|
|
@@ -8262,6 +8272,8 @@ var init_task_contract = __esm(() => {
|
|
|
8262
8272
|
ctx.issues.push({ code: "custom", input: ctx.value, message: "invalid Unicode", path: [] });
|
|
8263
8273
|
});
|
|
8264
8274
|
id = text.regex(uuidPattern, "expected lowercase UUID");
|
|
8275
|
+
idRefPattern = /^[0-9a-f][0-9a-f-]{7,35}$/;
|
|
8276
|
+
idRef = text.regex(idRefPattern, "expected a UUID or an id prefix of 8+ characters");
|
|
8265
8277
|
digest = text.regex(digestPattern, "expected lowercase SHA-256 digest");
|
|
8266
8278
|
revision = text.regex(uuidPattern, "expected UUID revision");
|
|
8267
8279
|
utcSchema = text.check((ctx) => {
|
|
@@ -8530,7 +8542,7 @@ var init_task_contract = __esm(() => {
|
|
|
8530
8542
|
outcome: _enum(["completed", "failed", "cancelled"]),
|
|
8531
8543
|
summary: text,
|
|
8532
8544
|
evidenceIds: array(id),
|
|
8533
|
-
findingIds: array(
|
|
8545
|
+
findingIds: array(idRef)
|
|
8534
8546
|
}).strict();
|
|
8535
8547
|
workerSchema = object({
|
|
8536
8548
|
assignment: assignmentSchema,
|
|
@@ -8722,7 +8734,7 @@ var init_task_contract = __esm(() => {
|
|
|
8722
8734
|
action: literal("resolve"),
|
|
8723
8735
|
...taskId,
|
|
8724
8736
|
expectedRevision: revision.optional(),
|
|
8725
|
-
findingId:
|
|
8737
|
+
findingId: idRef,
|
|
8726
8738
|
disposition: _enum(["open", "fixed", "dismissed", "deferred"]),
|
|
8727
8739
|
reason: text,
|
|
8728
8740
|
evidenceIds: array(id),
|
|
@@ -8763,7 +8775,7 @@ var init_task_contract = __esm(() => {
|
|
|
8763
8775
|
...taskId,
|
|
8764
8776
|
expectedRevision: revision.optional(),
|
|
8765
8777
|
expectedWorkspaceRevision: revision.optional(),
|
|
8766
|
-
workerId:
|
|
8778
|
+
workerId: idRef,
|
|
8767
8779
|
report: workerReportSchema
|
|
8768
8780
|
}),
|
|
8769
8781
|
cancel: operation({
|
|
@@ -8771,7 +8783,7 @@ var init_task_contract = __esm(() => {
|
|
|
8771
8783
|
...taskId,
|
|
8772
8784
|
...revisions,
|
|
8773
8785
|
expectedWorkspaceRevision: revision.optional(),
|
|
8774
|
-
workerId:
|
|
8786
|
+
workerId: idRef,
|
|
8775
8787
|
reason: text
|
|
8776
8788
|
})
|
|
8777
8789
|
};
|
|
@@ -11453,20 +11465,26 @@ class TaskStore {
|
|
|
11453
11465
|
return success(null, null, { key: key.data, bound: bound.data });
|
|
11454
11466
|
}
|
|
11455
11467
|
taskForWorker(workerId) {
|
|
11456
|
-
if (typeof workerId !== "string" || !
|
|
11468
|
+
if (typeof workerId !== "string" || !idRefPattern.test(workerId))
|
|
11457
11469
|
return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
|
|
11458
11470
|
const listed = this.listTaskIndex();
|
|
11459
11471
|
if (!listed.ok)
|
|
11460
11472
|
return listed;
|
|
11473
|
+
const owners = new Map;
|
|
11461
11474
|
for (const entry of listed.data) {
|
|
11462
11475
|
if (entry.status === "closed")
|
|
11463
11476
|
continue;
|
|
11464
11477
|
const loaded = this.load(entry.id);
|
|
11465
11478
|
if (!loaded.ok)
|
|
11466
11479
|
return loaded;
|
|
11467
|
-
|
|
11468
|
-
|
|
11480
|
+
for (const worker of loaded.data?.record.workers ?? [])
|
|
11481
|
+
owners.set(worker.id, entry.id);
|
|
11469
11482
|
}
|
|
11483
|
+
const resolved = resolveIdRef("worker", workerId, [...owners.keys()]);
|
|
11484
|
+
if (resolved.ok)
|
|
11485
|
+
return success(null, null, owners.get(resolved.data) ?? null);
|
|
11486
|
+
if (resolved.code !== "not_found")
|
|
11487
|
+
return resolved;
|
|
11470
11488
|
return success(null, null, null);
|
|
11471
11489
|
}
|
|
11472
11490
|
originTaskEntry() {
|
|
@@ -18818,6 +18836,10 @@ class WorkitCore {
|
|
|
18818
18836
|
}
|
|
18819
18837
|
if (helper?.ok)
|
|
18820
18838
|
return failure2("permission_denied", "helpers cannot resolve findings");
|
|
18839
|
+
const findingRef = resolveIdRef("finding", input.findingId, task.data.findings.map((entry) => entry.id));
|
|
18840
|
+
if (!findingRef.ok)
|
|
18841
|
+
return findingRef;
|
|
18842
|
+
input.findingId = findingRef.data;
|
|
18821
18843
|
const finding = task.data.findings.find((entry) => entry.id === input.findingId);
|
|
18822
18844
|
if (!finding)
|
|
18823
18845
|
return failure2("not_found", "finding not found");
|
|
@@ -18969,15 +18991,31 @@ class WorkitCore {
|
|
|
18969
18991
|
return changed;
|
|
18970
18992
|
return success(changed.data.task.revision, changed.data.workspace.revision, changed.data.task.workers.at(-1));
|
|
18971
18993
|
}
|
|
18994
|
+
const workerRef = resolveIdRef("worker", input.workerId, helperId === null ? task.data.workers.map((candidate) => candidate.id) : [helperId]);
|
|
18995
|
+
if (!workerRef.ok)
|
|
18996
|
+
return helperId === null ? workerRef : failure2("permission_denied", input.action === "report" ? ONLY_OWN_REPORT : NO_HELPER_CONTROL);
|
|
18997
|
+
input.workerId = workerRef.data;
|
|
18972
18998
|
const entry = task.data.workers.find((candidate) => candidate.id === input.workerId);
|
|
18973
18999
|
if (!entry)
|
|
18974
19000
|
return failure2("not_found", "worker not found");
|
|
18975
19001
|
if (input.action === "report") {
|
|
18976
19002
|
if (helperId === null || helperId !== input.workerId)
|
|
18977
|
-
return failure2("permission_denied",
|
|
19003
|
+
return failure2("permission_denied", ONLY_OWN_REPORT);
|
|
18978
19004
|
const helper = this.helperEntry(task.data, true, true);
|
|
18979
19005
|
if (!helper.ok)
|
|
18980
19006
|
return helper;
|
|
19007
|
+
const ownFindings = task.data.findings.filter((candidate) => candidate.provenance.workerId === helperId).map((candidate) => candidate.id);
|
|
19008
|
+
const reported = [];
|
|
19009
|
+
for (const findingRef of input.report.findingIds) {
|
|
19010
|
+
const found = resolveIdRef("finding", findingRef, ownFindings);
|
|
19011
|
+
if (found.ok)
|
|
19012
|
+
reported.push(found.data);
|
|
19013
|
+
else if (found.code === "not_found")
|
|
19014
|
+
reported.push(findingRef);
|
|
19015
|
+
else
|
|
19016
|
+
return found;
|
|
19017
|
+
}
|
|
19018
|
+
input.report.findingIds = reported;
|
|
18981
19019
|
const evidence = task.data.evidence.filter((candidate) => input.report.evidenceIds.includes(candidate.id));
|
|
18982
19020
|
const findings = task.data.findings.filter((candidate) => input.report.findingIds.includes(candidate.id));
|
|
18983
19021
|
if (evidence.length !== input.report.evidenceIds.length || findings.length !== input.report.findingIds.length)
|
|
@@ -19005,7 +19043,7 @@ class WorkitCore {
|
|
|
19005
19043
|
return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during report");
|
|
19006
19044
|
}
|
|
19007
19045
|
if (helperId !== null)
|
|
19008
|
-
return failure2("permission_denied",
|
|
19046
|
+
return failure2("permission_denied", NO_HELPER_CONTROL);
|
|
19009
19047
|
if (task.data.status === "closed")
|
|
19010
19048
|
return failure2("invalid_transition", "closed task cannot cancel workers");
|
|
19011
19049
|
if (entry.data.state === "stopped") {
|
|
@@ -19534,7 +19572,7 @@ var MAX_JUDGED_REFS = 5, workspaceVerification = (root) => {
|
|
|
19534
19572
|
return changed;
|
|
19535
19573
|
const updated = changed.data.task.workers.find((candidate) => candidate.id === input.workerId);
|
|
19536
19574
|
return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during lifecycle observation");
|
|
19537
|
-
}, 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) => {
|
|
19575
|
+
}, refsWithinScope = (refs, scope) => refs.every((ref) => ref.kind !== "file" || scopeCovers(scope, { description: "", paths: [ref.path], exclusions: [] })), TASK_SCOPED_ACTIONS, ONLY_OWN_REPORT = "workers can submit only their own report", NO_HELPER_CONTROL = "helpers cannot cancel or control workers", WORKER_ADDRESSED_ACTIONS, workerCommand = (taskId, request) => {
|
|
19538
19576
|
const { action, workerId, reason, report } = request;
|
|
19539
19577
|
const rest = JSON.stringify({ reason, report });
|
|
19540
19578
|
const payload = rest === "{}" ? "" : ` --payload '${rest.replace(/'/gu, "'\\''")}'`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cli",
|
|
3
|
-
"version": "8.14.
|
|
3
|
+
"version": "8.14.1",
|
|
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.14.
|
|
41
|
+
"@brainervirus/workit-cursor": "^8.14.1",
|
|
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.14.
|
|
47
|
+
"@brainervirus/workit-core": "^8.14.1"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=24"
|