@brainervirus/workit-mcp 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.
Files changed (2) hide show
  1. package/dist/index.js +49 -9
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -16611,6 +16611,8 @@ var text = string2().check((ctx) => {
16611
16611
  ctx.issues.push({ code: "custom", input: ctx.value, message: "invalid Unicode", path: [] });
16612
16612
  });
16613
16613
  var id = text.regex(uuidPattern, "expected lowercase UUID");
16614
+ var idRefPattern = /^[0-9a-f][0-9a-f-]{7,35}$/;
16615
+ var idRef = text.regex(idRefPattern, "expected a UUID or an id prefix of 8+ characters");
16614
16616
  var digest = text.regex(digestPattern, "expected lowercase SHA-256 digest");
16615
16617
  var revision = text.regex(uuidPattern, "expected UUID revision");
16616
16618
  var validUtc = (value) => {
@@ -16988,7 +16990,7 @@ var workerReportSchema = object2({
16988
16990
  outcome: _enum(["completed", "failed", "cancelled"]),
16989
16991
  summary: text,
16990
16992
  evidenceIds: array(id),
16991
- findingIds: array(id)
16993
+ findingIds: array(idRef)
16992
16994
  }).strict();
16993
16995
  var workerSchema = object2({
16994
16996
  assignment: assignmentSchema,
@@ -17234,7 +17236,7 @@ var findingOperations = {
17234
17236
  action: literal("resolve"),
17235
17237
  ...taskId,
17236
17238
  expectedRevision: revision.optional(),
17237
- findingId: id,
17239
+ findingId: idRef,
17238
17240
  disposition: _enum(["open", "fixed", "dismissed", "deferred"]),
17239
17241
  reason: text,
17240
17242
  evidenceIds: array(id),
@@ -17275,7 +17277,7 @@ var workerOperations = {
17275
17277
  ...taskId,
17276
17278
  expectedRevision: revision.optional(),
17277
17279
  expectedWorkspaceRevision: revision.optional(),
17278
- workerId: id,
17280
+ workerId: idRef,
17279
17281
  report: workerReportSchema
17280
17282
  }),
17281
17283
  cancel: operation({
@@ -17283,7 +17285,7 @@ var workerOperations = {
17283
17285
  ...taskId,
17284
17286
  ...revisions,
17285
17287
  expectedWorkspaceRevision: revision.optional(),
17286
- workerId: id,
17288
+ workerId: idRef,
17287
17289
  reason: text
17288
17290
  })
17289
17291
  };
@@ -17333,6 +17335,16 @@ var success = (revisionValue, workspaceRevisionValue, data) => ({
17333
17335
  data
17334
17336
  });
17335
17337
  var failure2 = (code, error, details = {}) => ({ ok: false, schemaVersion: 1, code, error, details });
17338
+ function resolveIdRef(kind, ref, ids) {
17339
+ if (ids.includes(ref))
17340
+ return success(null, null, ref);
17341
+ const matches = ids.filter((candidate) => candidate.startsWith(ref));
17342
+ if (matches.length === 1)
17343
+ return success(null, null, matches[0]);
17344
+ if (matches.length === 0)
17345
+ return failure2("not_found", `${kind} not found`);
17346
+ return failure2("invalid_input", `${kind} prefix ${ref} is ambiguous; candidates: ${matches.join(", ")}`);
17347
+ }
17336
17348
  function parseOperation(family, input) {
17337
17349
  if (typeof input === "object" && input !== null && "schemaVersion" in input && input.schemaVersion !== SCHEMA_VERSION)
17338
17350
  return failure2("unsupported_version", "unsupported schema version", { operation: family });
@@ -19851,20 +19863,26 @@ class TaskStore {
19851
19863
  return success(null, null, { key: key.data, bound: bound.data });
19852
19864
  }
19853
19865
  taskForWorker(workerId) {
19854
- if (typeof workerId !== "string" || !validId(workerId))
19866
+ if (typeof workerId !== "string" || !idRefPattern.test(workerId))
19855
19867
  return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
19856
19868
  const listed = this.listTaskIndex();
19857
19869
  if (!listed.ok)
19858
19870
  return listed;
19871
+ const owners = new Map;
19859
19872
  for (const entry of listed.data) {
19860
19873
  if (entry.status === "closed")
19861
19874
  continue;
19862
19875
  const loaded = this.load(entry.id);
19863
19876
  if (!loaded.ok)
19864
19877
  return loaded;
19865
- if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
19866
- return success(null, null, entry.id);
19878
+ for (const worker of loaded.data?.record.workers ?? [])
19879
+ owners.set(worker.id, entry.id);
19867
19880
  }
19881
+ const resolved = resolveIdRef("worker", workerId, [...owners.keys()]);
19882
+ if (resolved.ok)
19883
+ return success(null, null, owners.get(resolved.data) ?? null);
19884
+ if (resolved.code !== "not_found")
19885
+ return resolved;
19868
19886
  return success(null, null, null);
19869
19887
  }
19870
19888
  originTaskEntry() {
@@ -25582,6 +25600,8 @@ var TASK_SCOPED_ACTIONS = new Set([
25582
25600
  "worker.cancel",
25583
25601
  "state.export"
25584
25602
  ]);
25603
+ var ONLY_OWN_REPORT = "workers can submit only their own report";
25604
+ var NO_HELPER_CONTROL = "helpers cannot cancel or control workers";
25585
25605
  var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
25586
25606
  var workerCommand = (taskId, request) => {
25587
25607
  const { action, workerId, reason, report } = request;
@@ -26479,6 +26499,10 @@ class WorkitCore {
26479
26499
  }
26480
26500
  if (helper?.ok)
26481
26501
  return failure2("permission_denied", "helpers cannot resolve findings");
26502
+ const findingRef = resolveIdRef("finding", input.findingId, task.data.findings.map((entry) => entry.id));
26503
+ if (!findingRef.ok)
26504
+ return findingRef;
26505
+ input.findingId = findingRef.data;
26482
26506
  const finding = task.data.findings.find((entry) => entry.id === input.findingId);
26483
26507
  if (!finding)
26484
26508
  return failure2("not_found", "finding not found");
@@ -26630,15 +26654,31 @@ class WorkitCore {
26630
26654
  return changed;
26631
26655
  return success(changed.data.task.revision, changed.data.workspace.revision, changed.data.task.workers.at(-1));
26632
26656
  }
26657
+ const workerRef = resolveIdRef("worker", input.workerId, helperId === null ? task.data.workers.map((candidate) => candidate.id) : [helperId]);
26658
+ if (!workerRef.ok)
26659
+ return helperId === null ? workerRef : failure2("permission_denied", input.action === "report" ? ONLY_OWN_REPORT : NO_HELPER_CONTROL);
26660
+ input.workerId = workerRef.data;
26633
26661
  const entry = task.data.workers.find((candidate) => candidate.id === input.workerId);
26634
26662
  if (!entry)
26635
26663
  return failure2("not_found", "worker not found");
26636
26664
  if (input.action === "report") {
26637
26665
  if (helperId === null || helperId !== input.workerId)
26638
- return failure2("permission_denied", "workers can submit only their own report");
26666
+ return failure2("permission_denied", ONLY_OWN_REPORT);
26639
26667
  const helper = this.helperEntry(task.data, true, true);
26640
26668
  if (!helper.ok)
26641
26669
  return helper;
26670
+ const ownFindings = task.data.findings.filter((candidate) => candidate.provenance.workerId === helperId).map((candidate) => candidate.id);
26671
+ const reported = [];
26672
+ for (const findingRef of input.report.findingIds) {
26673
+ const found = resolveIdRef("finding", findingRef, ownFindings);
26674
+ if (found.ok)
26675
+ reported.push(found.data);
26676
+ else if (found.code === "not_found")
26677
+ reported.push(findingRef);
26678
+ else
26679
+ return found;
26680
+ }
26681
+ input.report.findingIds = reported;
26642
26682
  const evidence = task.data.evidence.filter((candidate) => input.report.evidenceIds.includes(candidate.id));
26643
26683
  const findings = task.data.findings.filter((candidate) => input.report.findingIds.includes(candidate.id));
26644
26684
  if (evidence.length !== input.report.evidenceIds.length || findings.length !== input.report.findingIds.length)
@@ -26666,7 +26706,7 @@ class WorkitCore {
26666
26706
  return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during report");
26667
26707
  }
26668
26708
  if (helperId !== null)
26669
- return failure2("permission_denied", "helpers cannot cancel or control workers");
26709
+ return failure2("permission_denied", NO_HELPER_CONTROL);
26670
26710
  if (task.data.status === "closed")
26671
26711
  return failure2("invalid_transition", "closed task cannot cancel workers");
26672
26712
  if (entry.data.state === "stopped") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-mcp",
3
- "version": "8.14.0",
3
+ "version": "8.14.1",
4
4
  "private": false,
5
5
  "description": "Workit shared MCP transport for the eight task and policy operation families",
6
6
  "keywords": [
@@ -42,7 +42,7 @@
42
42
  "build": "bun scripts/build.ts"
43
43
  },
44
44
  "dependencies": {
45
- "@brainervirus/workit-core": "^8.14.0",
45
+ "@brainervirus/workit-core": "^8.14.1",
46
46
  "@modelcontextprotocol/sdk": "1.32.0",
47
47
  "zod": "4.6.5"
48
48
  },