@brainervirus/workit-cursor 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.
@@ -2,7 +2,7 @@
2
2
  "name": "workit",
3
3
  "displayName": "Workit",
4
4
  "description": "Adaptive Workit workflow with shared MCP tools and native Cursor hooks",
5
- "version": "8.14.0",
5
+ "version": "8.14.1",
6
6
  "author": {
7
7
  "name": "Cristhofer Pincetti"
8
8
  },
@@ -7624,6 +7624,16 @@ var init_zod = __esm(() => {
7624
7624
 
7625
7625
  // packages/workit-core/src/core/task-contract.ts
7626
7626
  import { createHash, randomUUID } from "node:crypto";
7627
+ function resolveIdRef(kind, ref, ids) {
7628
+ if (ids.includes(ref))
7629
+ return success(null, null, ref);
7630
+ const matches = ids.filter((candidate) => candidate.startsWith(ref));
7631
+ if (matches.length === 1)
7632
+ return success(null, null, matches[0]);
7633
+ if (matches.length === 0)
7634
+ return failure2("not_found", `${kind} not found`);
7635
+ return failure2("invalid_input", `${kind} prefix ${ref} is ambiguous; candidates: ${matches.join(", ")}`);
7636
+ }
7627
7637
  function parseOperation(family, input) {
7628
7638
  if (typeof input === "object" && input !== null && "schemaVersion" in input && input.schemaVersion !== SCHEMA_VERSION)
7629
7639
  return failure2("unsupported_version", "unsupported schema version", { operation: family });
@@ -7726,7 +7736,7 @@ var SCHEMA_VERSION = 1, POLICY_VERSION = "1.0.0", OPERATION_FAMILIES, uuidPatter
7726
7736
  return true;
7727
7737
  }
7728
7738
  return false;
7729
- }, text, id, digest, revision, validUtc = (value) => {
7739
+ }, text, id, idRefPattern, idRef, digest, revision, validUtc = (value) => {
7730
7740
  const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?Z$/.exec(value);
7731
7741
  if (!match)
7732
7742
  return false;
@@ -7909,6 +7919,8 @@ var init_task_contract = __esm(() => {
7909
7919
  ctx.issues.push({ code: "custom", input: ctx.value, message: "invalid Unicode", path: [] });
7910
7920
  });
7911
7921
  id = text.regex(uuidPattern, "expected lowercase UUID");
7922
+ idRefPattern = /^[0-9a-f][0-9a-f-]{7,35}$/;
7923
+ idRef = text.regex(idRefPattern, "expected a UUID or an id prefix of 8+ characters");
7912
7924
  digest = text.regex(digestPattern, "expected lowercase SHA-256 digest");
7913
7925
  revision = text.regex(uuidPattern, "expected UUID revision");
7914
7926
  utcSchema = text.check((ctx) => {
@@ -8177,7 +8189,7 @@ var init_task_contract = __esm(() => {
8177
8189
  outcome: _enum(["completed", "failed", "cancelled"]),
8178
8190
  summary: text,
8179
8191
  evidenceIds: array(id),
8180
- findingIds: array(id)
8192
+ findingIds: array(idRef)
8181
8193
  }).strict();
8182
8194
  workerSchema = object({
8183
8195
  assignment: assignmentSchema,
@@ -8369,7 +8381,7 @@ var init_task_contract = __esm(() => {
8369
8381
  action: literal("resolve"),
8370
8382
  ...taskId,
8371
8383
  expectedRevision: revision.optional(),
8372
- findingId: id,
8384
+ findingId: idRef,
8373
8385
  disposition: _enum(["open", "fixed", "dismissed", "deferred"]),
8374
8386
  reason: text,
8375
8387
  evidenceIds: array(id),
@@ -8410,7 +8422,7 @@ var init_task_contract = __esm(() => {
8410
8422
  ...taskId,
8411
8423
  expectedRevision: revision.optional(),
8412
8424
  expectedWorkspaceRevision: revision.optional(),
8413
- workerId: id,
8425
+ workerId: idRef,
8414
8426
  report: workerReportSchema
8415
8427
  }),
8416
8428
  cancel: operation({
@@ -8418,7 +8430,7 @@ var init_task_contract = __esm(() => {
8418
8430
  ...taskId,
8419
8431
  ...revisions,
8420
8432
  expectedWorkspaceRevision: revision.optional(),
8421
- workerId: id,
8433
+ workerId: idRef,
8422
8434
  reason: text
8423
8435
  })
8424
8436
  };
@@ -13462,20 +13474,26 @@ class TaskStore {
13462
13474
  return success(null, null, { key: key.data, bound: bound.data });
13463
13475
  }
13464
13476
  taskForWorker(workerId) {
13465
- if (typeof workerId !== "string" || !validId(workerId))
13477
+ if (typeof workerId !== "string" || !idRefPattern.test(workerId))
13466
13478
  return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
13467
13479
  const listed = this.listTaskIndex();
13468
13480
  if (!listed.ok)
13469
13481
  return listed;
13482
+ const owners = new Map;
13470
13483
  for (const entry of listed.data) {
13471
13484
  if (entry.status === "closed")
13472
13485
  continue;
13473
13486
  const loaded = this.load(entry.id);
13474
13487
  if (!loaded.ok)
13475
13488
  return loaded;
13476
- if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
13477
- return success(null, null, entry.id);
13489
+ for (const worker of loaded.data?.record.workers ?? [])
13490
+ owners.set(worker.id, entry.id);
13478
13491
  }
13492
+ const resolved = resolveIdRef("worker", workerId, [...owners.keys()]);
13493
+ if (resolved.ok)
13494
+ return success(null, null, owners.get(resolved.data) ?? null);
13495
+ if (resolved.code !== "not_found")
13496
+ return resolved;
13479
13497
  return success(null, null, null);
13480
13498
  }
13481
13499
  originTaskEntry() {
@@ -16734,6 +16752,10 @@ class WorkitCore {
16734
16752
  }
16735
16753
  if (helper?.ok)
16736
16754
  return failure2("permission_denied", "helpers cannot resolve findings");
16755
+ const findingRef = resolveIdRef("finding", input.findingId, task.data.findings.map((entry) => entry.id));
16756
+ if (!findingRef.ok)
16757
+ return findingRef;
16758
+ input.findingId = findingRef.data;
16737
16759
  const finding = task.data.findings.find((entry) => entry.id === input.findingId);
16738
16760
  if (!finding)
16739
16761
  return failure2("not_found", "finding not found");
@@ -16885,15 +16907,31 @@ class WorkitCore {
16885
16907
  return changed;
16886
16908
  return success(changed.data.task.revision, changed.data.workspace.revision, changed.data.task.workers.at(-1));
16887
16909
  }
16910
+ const workerRef = resolveIdRef("worker", input.workerId, helperId === null ? task.data.workers.map((candidate) => candidate.id) : [helperId]);
16911
+ if (!workerRef.ok)
16912
+ return helperId === null ? workerRef : failure2("permission_denied", input.action === "report" ? ONLY_OWN_REPORT : NO_HELPER_CONTROL);
16913
+ input.workerId = workerRef.data;
16888
16914
  const entry = task.data.workers.find((candidate) => candidate.id === input.workerId);
16889
16915
  if (!entry)
16890
16916
  return failure2("not_found", "worker not found");
16891
16917
  if (input.action === "report") {
16892
16918
  if (helperId === null || helperId !== input.workerId)
16893
- return failure2("permission_denied", "workers can submit only their own report");
16919
+ return failure2("permission_denied", ONLY_OWN_REPORT);
16894
16920
  const helper = this.helperEntry(task.data, true, true);
16895
16921
  if (!helper.ok)
16896
16922
  return helper;
16923
+ const ownFindings = task.data.findings.filter((candidate) => candidate.provenance.workerId === helperId).map((candidate) => candidate.id);
16924
+ const reported = [];
16925
+ for (const findingRef of input.report.findingIds) {
16926
+ const found = resolveIdRef("finding", findingRef, ownFindings);
16927
+ if (found.ok)
16928
+ reported.push(found.data);
16929
+ else if (found.code === "not_found")
16930
+ reported.push(findingRef);
16931
+ else
16932
+ return found;
16933
+ }
16934
+ input.report.findingIds = reported;
16897
16935
  const evidence = task.data.evidence.filter((candidate) => input.report.evidenceIds.includes(candidate.id));
16898
16936
  const findings = task.data.findings.filter((candidate) => input.report.findingIds.includes(candidate.id));
16899
16937
  if (evidence.length !== input.report.evidenceIds.length || findings.length !== input.report.findingIds.length)
@@ -16921,7 +16959,7 @@ class WorkitCore {
16921
16959
  return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during report");
16922
16960
  }
16923
16961
  if (helperId !== null)
16924
- return failure2("permission_denied", "helpers cannot cancel or control workers");
16962
+ return failure2("permission_denied", NO_HELPER_CONTROL);
16925
16963
  if (task.data.status === "closed")
16926
16964
  return failure2("invalid_transition", "closed task cannot cancel workers");
16927
16965
  if (entry.data.state === "stopped") {
@@ -17450,7 +17488,7 @@ var MAX_JUDGED_REFS = 5, workspaceVerification = (root) => {
17450
17488
  return changed;
17451
17489
  const updated = changed.data.task.workers.find((candidate) => candidate.id === input.workerId);
17452
17490
  return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during lifecycle observation");
17453
- }, 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) => {
17491
+ }, 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) => {
17454
17492
  const { action, workerId, reason, report } = request;
17455
17493
  const rest = JSON.stringify({ reason, report });
17456
17494
  const payload = rest === "{}" ? "" : ` --payload '${rest.replace(/'/gu, "'\\''")}'`;
@@ -16617,6 +16617,8 @@ var text = string2().check((ctx) => {
16617
16617
  ctx.issues.push({ code: "custom", input: ctx.value, message: "invalid Unicode", path: [] });
16618
16618
  });
16619
16619
  var id = text.regex(uuidPattern, "expected lowercase UUID");
16620
+ var idRefPattern = /^[0-9a-f][0-9a-f-]{7,35}$/;
16621
+ var idRef = text.regex(idRefPattern, "expected a UUID or an id prefix of 8+ characters");
16620
16622
  var digest = text.regex(digestPattern, "expected lowercase SHA-256 digest");
16621
16623
  var revision = text.regex(uuidPattern, "expected UUID revision");
16622
16624
  var validUtc = (value) => {
@@ -16994,7 +16996,7 @@ var workerReportSchema = object2({
16994
16996
  outcome: _enum(["completed", "failed", "cancelled"]),
16995
16997
  summary: text,
16996
16998
  evidenceIds: array(id),
16997
- findingIds: array(id)
16999
+ findingIds: array(idRef)
16998
17000
  }).strict();
16999
17001
  var workerSchema = object2({
17000
17002
  assignment: assignmentSchema,
@@ -17240,7 +17242,7 @@ var findingOperations = {
17240
17242
  action: literal("resolve"),
17241
17243
  ...taskId,
17242
17244
  expectedRevision: revision.optional(),
17243
- findingId: id,
17245
+ findingId: idRef,
17244
17246
  disposition: _enum(["open", "fixed", "dismissed", "deferred"]),
17245
17247
  reason: text,
17246
17248
  evidenceIds: array(id),
@@ -17281,7 +17283,7 @@ var workerOperations = {
17281
17283
  ...taskId,
17282
17284
  expectedRevision: revision.optional(),
17283
17285
  expectedWorkspaceRevision: revision.optional(),
17284
- workerId: id,
17286
+ workerId: idRef,
17285
17287
  report: workerReportSchema
17286
17288
  }),
17287
17289
  cancel: operation({
@@ -17289,7 +17291,7 @@ var workerOperations = {
17289
17291
  ...taskId,
17290
17292
  ...revisions,
17291
17293
  expectedWorkspaceRevision: revision.optional(),
17292
- workerId: id,
17294
+ workerId: idRef,
17293
17295
  reason: text
17294
17296
  })
17295
17297
  };
@@ -17339,6 +17341,16 @@ var success = (revisionValue, workspaceRevisionValue, data) => ({
17339
17341
  data
17340
17342
  });
17341
17343
  var failure2 = (code, error, details = {}) => ({ ok: false, schemaVersion: 1, code, error, details });
17344
+ function resolveIdRef(kind, ref, ids) {
17345
+ if (ids.includes(ref))
17346
+ return success(null, null, ref);
17347
+ const matches = ids.filter((candidate) => candidate.startsWith(ref));
17348
+ if (matches.length === 1)
17349
+ return success(null, null, matches[0]);
17350
+ if (matches.length === 0)
17351
+ return failure2("not_found", `${kind} not found`);
17352
+ return failure2("invalid_input", `${kind} prefix ${ref} is ambiguous; candidates: ${matches.join(", ")}`);
17353
+ }
17342
17354
  function parseOperation(family, input) {
17343
17355
  if (typeof input === "object" && input !== null && "schemaVersion" in input && input.schemaVersion !== SCHEMA_VERSION)
17344
17356
  return failure2("unsupported_version", "unsupported schema version", { operation: family });
@@ -19857,20 +19869,26 @@ class TaskStore {
19857
19869
  return success(null, null, { key: key.data, bound: bound.data });
19858
19870
  }
19859
19871
  taskForWorker(workerId) {
19860
- if (typeof workerId !== "string" || !validId(workerId))
19872
+ if (typeof workerId !== "string" || !idRefPattern.test(workerId))
19861
19873
  return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
19862
19874
  const listed = this.listTaskIndex();
19863
19875
  if (!listed.ok)
19864
19876
  return listed;
19877
+ const owners = new Map;
19865
19878
  for (const entry of listed.data) {
19866
19879
  if (entry.status === "closed")
19867
19880
  continue;
19868
19881
  const loaded = this.load(entry.id);
19869
19882
  if (!loaded.ok)
19870
19883
  return loaded;
19871
- if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
19872
- return success(null, null, entry.id);
19884
+ for (const worker of loaded.data?.record.workers ?? [])
19885
+ owners.set(worker.id, entry.id);
19873
19886
  }
19887
+ const resolved = resolveIdRef("worker", workerId, [...owners.keys()]);
19888
+ if (resolved.ok)
19889
+ return success(null, null, owners.get(resolved.data) ?? null);
19890
+ if (resolved.code !== "not_found")
19891
+ return resolved;
19874
19892
  return success(null, null, null);
19875
19893
  }
19876
19894
  originTaskEntry() {
@@ -25588,6 +25606,8 @@ var TASK_SCOPED_ACTIONS = new Set([
25588
25606
  "worker.cancel",
25589
25607
  "state.export"
25590
25608
  ]);
25609
+ var ONLY_OWN_REPORT = "workers can submit only their own report";
25610
+ var NO_HELPER_CONTROL = "helpers cannot cancel or control workers";
25591
25611
  var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
25592
25612
  var workerCommand = (taskId, request) => {
25593
25613
  const { action, workerId, reason, report } = request;
@@ -26485,6 +26505,10 @@ class WorkitCore {
26485
26505
  }
26486
26506
  if (helper?.ok)
26487
26507
  return failure2("permission_denied", "helpers cannot resolve findings");
26508
+ const findingRef = resolveIdRef("finding", input.findingId, task.data.findings.map((entry) => entry.id));
26509
+ if (!findingRef.ok)
26510
+ return findingRef;
26511
+ input.findingId = findingRef.data;
26488
26512
  const finding = task.data.findings.find((entry) => entry.id === input.findingId);
26489
26513
  if (!finding)
26490
26514
  return failure2("not_found", "finding not found");
@@ -26636,15 +26660,31 @@ class WorkitCore {
26636
26660
  return changed;
26637
26661
  return success(changed.data.task.revision, changed.data.workspace.revision, changed.data.task.workers.at(-1));
26638
26662
  }
26663
+ const workerRef = resolveIdRef("worker", input.workerId, helperId === null ? task.data.workers.map((candidate) => candidate.id) : [helperId]);
26664
+ if (!workerRef.ok)
26665
+ return helperId === null ? workerRef : failure2("permission_denied", input.action === "report" ? ONLY_OWN_REPORT : NO_HELPER_CONTROL);
26666
+ input.workerId = workerRef.data;
26639
26667
  const entry = task.data.workers.find((candidate) => candidate.id === input.workerId);
26640
26668
  if (!entry)
26641
26669
  return failure2("not_found", "worker not found");
26642
26670
  if (input.action === "report") {
26643
26671
  if (helperId === null || helperId !== input.workerId)
26644
- return failure2("permission_denied", "workers can submit only their own report");
26672
+ return failure2("permission_denied", ONLY_OWN_REPORT);
26645
26673
  const helper = this.helperEntry(task.data, true, true);
26646
26674
  if (!helper.ok)
26647
26675
  return helper;
26676
+ const ownFindings = task.data.findings.filter((candidate) => candidate.provenance.workerId === helperId).map((candidate) => candidate.id);
26677
+ const reported = [];
26678
+ for (const findingRef of input.report.findingIds) {
26679
+ const found = resolveIdRef("finding", findingRef, ownFindings);
26680
+ if (found.ok)
26681
+ reported.push(found.data);
26682
+ else if (found.code === "not_found")
26683
+ reported.push(findingRef);
26684
+ else
26685
+ return found;
26686
+ }
26687
+ input.report.findingIds = reported;
26648
26688
  const evidence = task.data.evidence.filter((candidate) => input.report.evidenceIds.includes(candidate.id));
26649
26689
  const findings = task.data.findings.filter((candidate) => input.report.findingIds.includes(candidate.id));
26650
26690
  if (evidence.length !== input.report.evidenceIds.length || findings.length !== input.report.findingIds.length)
@@ -26672,7 +26712,7 @@ class WorkitCore {
26672
26712
  return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during report");
26673
26713
  }
26674
26714
  if (helperId !== null)
26675
- return failure2("permission_denied", "helpers cannot cancel or control workers");
26715
+ return failure2("permission_denied", NO_HELPER_CONTROL);
26676
26716
  if (task.data.status === "closed")
26677
26717
  return failure2("invalid_transition", "closed task cannot cancel workers");
26678
26718
  if (entry.data.state === "stopped") {
@@ -7548,6 +7548,8 @@ var text = string2().check((ctx) => {
7548
7548
  ctx.issues.push({ code: "custom", input: ctx.value, message: "invalid Unicode", path: [] });
7549
7549
  });
7550
7550
  var id = text.regex(uuidPattern, "expected lowercase UUID");
7551
+ var idRefPattern = /^[0-9a-f][0-9a-f-]{7,35}$/;
7552
+ var idRef = text.regex(idRefPattern, "expected a UUID or an id prefix of 8+ characters");
7551
7553
  var digest = text.regex(digestPattern, "expected lowercase SHA-256 digest");
7552
7554
  var revision = text.regex(uuidPattern, "expected UUID revision");
7553
7555
  var validUtc = (value) => {
@@ -7925,7 +7927,7 @@ var workerReportSchema = object({
7925
7927
  outcome: _enum(["completed", "failed", "cancelled"]),
7926
7928
  summary: text,
7927
7929
  evidenceIds: array(id),
7928
- findingIds: array(id)
7930
+ findingIds: array(idRef)
7929
7931
  }).strict();
7930
7932
  var workerSchema = object({
7931
7933
  assignment: assignmentSchema,
@@ -8171,7 +8173,7 @@ var findingOperations = {
8171
8173
  action: literal("resolve"),
8172
8174
  ...taskId,
8173
8175
  expectedRevision: revision.optional(),
8174
- findingId: id,
8176
+ findingId: idRef,
8175
8177
  disposition: _enum(["open", "fixed", "dismissed", "deferred"]),
8176
8178
  reason: text,
8177
8179
  evidenceIds: array(id),
@@ -8212,7 +8214,7 @@ var workerOperations = {
8212
8214
  ...taskId,
8213
8215
  expectedRevision: revision.optional(),
8214
8216
  expectedWorkspaceRevision: revision.optional(),
8215
- workerId: id,
8217
+ workerId: idRef,
8216
8218
  report: workerReportSchema
8217
8219
  }),
8218
8220
  cancel: operation({
@@ -8220,7 +8222,7 @@ var workerOperations = {
8220
8222
  ...taskId,
8221
8223
  ...revisions,
8222
8224
  expectedWorkspaceRevision: revision.optional(),
8223
- workerId: id,
8225
+ workerId: idRef,
8224
8226
  reason: text
8225
8227
  })
8226
8228
  };
@@ -8270,6 +8272,16 @@ var success = (revisionValue, workspaceRevisionValue, data) => ({
8270
8272
  data
8271
8273
  });
8272
8274
  var failure2 = (code, error, details = {}) => ({ ok: false, schemaVersion: 1, code, error, details });
8275
+ function resolveIdRef(kind, ref, ids) {
8276
+ if (ids.includes(ref))
8277
+ return success(null, null, ref);
8278
+ const matches = ids.filter((candidate) => candidate.startsWith(ref));
8279
+ if (matches.length === 1)
8280
+ return success(null, null, matches[0]);
8281
+ if (matches.length === 0)
8282
+ return failure2("not_found", `${kind} not found`);
8283
+ return failure2("invalid_input", `${kind} prefix ${ref} is ambiguous; candidates: ${matches.join(", ")}`);
8284
+ }
8273
8285
  function parseOperation(family, input) {
8274
8286
  if (typeof input === "object" && input !== null && "schemaVersion" in input && input.schemaVersion !== SCHEMA_VERSION)
8275
8287
  return failure2("unsupported_version", "unsupported schema version", { operation: family });
@@ -13631,20 +13643,26 @@ class TaskStore {
13631
13643
  return success(null, null, { key: key.data, bound: bound.data });
13632
13644
  }
13633
13645
  taskForWorker(workerId) {
13634
- if (typeof workerId !== "string" || !validId(workerId))
13646
+ if (typeof workerId !== "string" || !idRefPattern.test(workerId))
13635
13647
  return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
13636
13648
  const listed = this.listTaskIndex();
13637
13649
  if (!listed.ok)
13638
13650
  return listed;
13651
+ const owners = new Map;
13639
13652
  for (const entry of listed.data) {
13640
13653
  if (entry.status === "closed")
13641
13654
  continue;
13642
13655
  const loaded = this.load(entry.id);
13643
13656
  if (!loaded.ok)
13644
13657
  return loaded;
13645
- if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
13646
- return success(null, null, entry.id);
13658
+ for (const worker of loaded.data?.record.workers ?? [])
13659
+ owners.set(worker.id, entry.id);
13647
13660
  }
13661
+ const resolved = resolveIdRef("worker", workerId, [...owners.keys()]);
13662
+ if (resolved.ok)
13663
+ return success(null, null, owners.get(resolved.data) ?? null);
13664
+ if (resolved.code !== "not_found")
13665
+ return resolved;
13648
13666
  return success(null, null, null);
13649
13667
  }
13650
13668
  originTaskEntry() {
@@ -16270,6 +16288,8 @@ var TASK_SCOPED_ACTIONS = new Set([
16270
16288
  "worker.cancel",
16271
16289
  "state.export"
16272
16290
  ]);
16291
+ var ONLY_OWN_REPORT = "workers can submit only their own report";
16292
+ var NO_HELPER_CONTROL = "helpers cannot cancel or control workers";
16273
16293
  var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
16274
16294
  var workerCommand = (taskId, request) => {
16275
16295
  const { action, workerId, reason, report } = request;
@@ -17167,6 +17187,10 @@ class WorkitCore {
17167
17187
  }
17168
17188
  if (helper?.ok)
17169
17189
  return failure2("permission_denied", "helpers cannot resolve findings");
17190
+ const findingRef = resolveIdRef("finding", input.findingId, task.data.findings.map((entry) => entry.id));
17191
+ if (!findingRef.ok)
17192
+ return findingRef;
17193
+ input.findingId = findingRef.data;
17170
17194
  const finding = task.data.findings.find((entry) => entry.id === input.findingId);
17171
17195
  if (!finding)
17172
17196
  return failure2("not_found", "finding not found");
@@ -17318,15 +17342,31 @@ class WorkitCore {
17318
17342
  return changed;
17319
17343
  return success(changed.data.task.revision, changed.data.workspace.revision, changed.data.task.workers.at(-1));
17320
17344
  }
17345
+ const workerRef = resolveIdRef("worker", input.workerId, helperId === null ? task.data.workers.map((candidate) => candidate.id) : [helperId]);
17346
+ if (!workerRef.ok)
17347
+ return helperId === null ? workerRef : failure2("permission_denied", input.action === "report" ? ONLY_OWN_REPORT : NO_HELPER_CONTROL);
17348
+ input.workerId = workerRef.data;
17321
17349
  const entry = task.data.workers.find((candidate) => candidate.id === input.workerId);
17322
17350
  if (!entry)
17323
17351
  return failure2("not_found", "worker not found");
17324
17352
  if (input.action === "report") {
17325
17353
  if (helperId === null || helperId !== input.workerId)
17326
- return failure2("permission_denied", "workers can submit only their own report");
17354
+ return failure2("permission_denied", ONLY_OWN_REPORT);
17327
17355
  const helper = this.helperEntry(task.data, true, true);
17328
17356
  if (!helper.ok)
17329
17357
  return helper;
17358
+ const ownFindings = task.data.findings.filter((candidate) => candidate.provenance.workerId === helperId).map((candidate) => candidate.id);
17359
+ const reported = [];
17360
+ for (const findingRef of input.report.findingIds) {
17361
+ const found = resolveIdRef("finding", findingRef, ownFindings);
17362
+ if (found.ok)
17363
+ reported.push(found.data);
17364
+ else if (found.code === "not_found")
17365
+ reported.push(findingRef);
17366
+ else
17367
+ return found;
17368
+ }
17369
+ input.report.findingIds = reported;
17330
17370
  const evidence = task.data.evidence.filter((candidate) => input.report.evidenceIds.includes(candidate.id));
17331
17371
  const findings = task.data.findings.filter((candidate) => input.report.findingIds.includes(candidate.id));
17332
17372
  if (evidence.length !== input.report.evidenceIds.length || findings.length !== input.report.findingIds.length)
@@ -17354,7 +17394,7 @@ class WorkitCore {
17354
17394
  return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during report");
17355
17395
  }
17356
17396
  if (helperId !== null)
17357
- return failure2("permission_denied", "helpers cannot cancel or control workers");
17397
+ return failure2("permission_denied", NO_HELPER_CONTROL);
17358
17398
  if (task.data.status === "closed")
17359
17399
  return failure2("invalid_transition", "closed task cannot cancel workers");
17360
17400
  if (entry.data.state === "stopped") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-cursor",
3
- "version": "8.14.0",
3
+ "version": "8.14.1",
4
4
  "private": false,
5
5
  "description": "Workit Cursor plugin — shared MCP transport, native hooks, and sixteen method skills",
6
6
  "keywords": [
@@ -46,8 +46,8 @@
46
46
  "build": "bun scripts/build.ts"
47
47
  },
48
48
  "devDependencies": {
49
- "@brainervirus/workit-core": "^8.14.0",
50
- "@brainervirus/workit-mcp": "^8.14.0"
49
+ "@brainervirus/workit-core": "^8.14.1",
50
+ "@brainervirus/workit-mcp": "^8.14.1"
51
51
  },
52
52
  "engines": {
53
53
  "node": ">=24"