@ordewell/core 0.5.6 → 0.6.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 (47) hide show
  1. package/dist/{IFileSystem-C0l-4MGT.d.ts → IFileSystem-DuEiG_kA.d.ts} +1 -1
  2. package/dist/{IFileSystem-BkPX7mLD.d.mts → IFileSystem-d_SV7jAH.d.mts} +1 -1
  3. package/dist/{ModeResolver-CjpG5Wli.d.ts → ModeResolver-DIReYAOq.d.mts} +6 -2
  4. package/dist/{ModeResolver--16lh7dS.d.mts → ModeResolver-DXxV4n_V.d.ts} +6 -2
  5. package/dist/{Task-Dyxp67s2.d.mts → Task-ib_U0YP7.d.mts} +102 -16
  6. package/dist/{Task-Dyxp67s2.d.ts → Task-ib_U0YP7.d.ts} +102 -16
  7. package/dist/{chunk-ROVYWEBI.mjs → chunk-I6U3PVHL.mjs} +41 -17
  8. package/dist/chunk-I6U3PVHL.mjs.map +1 -0
  9. package/dist/{chunk-EDGUFCIR.mjs → chunk-JRZPSNRO.mjs} +7 -3
  10. package/dist/chunk-JRZPSNRO.mjs.map +1 -0
  11. package/dist/{chunk-JBEFAJ2W.mjs → chunk-M4KXBEFJ.mjs} +23 -3
  12. package/dist/chunk-M4KXBEFJ.mjs.map +1 -0
  13. package/dist/{chunk-C44UWIAD.mjs → chunk-N66ZHFGN.mjs} +2 -2
  14. package/dist/chunk-N66ZHFGN.mjs.map +1 -0
  15. package/dist/index.d.mts +325 -67
  16. package/dist/index.d.ts +325 -67
  17. package/dist/index.js +5741 -4489
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +5368 -4163
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/order-labels.d.mts +1 -1
  22. package/dist/order-labels.d.ts +1 -1
  23. package/dist/{parsing-EcmCsF1y.d.ts → parsing-C8Z22twN.d.ts} +2 -2
  24. package/dist/{parsing-DPEpAszP.d.mts → parsing-DjRJJX-y.d.mts} +2 -2
  25. package/dist/parsing.d.mts +3 -3
  26. package/dist/parsing.d.ts +3 -3
  27. package/dist/parsing.js +5 -2
  28. package/dist/parsing.js.map +1 -1
  29. package/dist/parsing.mjs +2 -2
  30. package/dist/{plan-utils-BAvW3hvl.d.mts → plan-utils-D4ioaM8q.d.mts} +25 -4
  31. package/dist/{plan-utils-BMyEiDKv.d.ts → plan-utils-DvHPzAfV.d.ts} +25 -4
  32. package/dist/plan-utils.d.mts +3 -3
  33. package/dist/plan-utils.d.ts +3 -3
  34. package/dist/plan-utils.js +2 -1
  35. package/dist/plan-utils.js.map +1 -1
  36. package/dist/plan-utils.mjs +2 -2
  37. package/dist/testing.d.mts +14 -5
  38. package/dist/testing.d.ts +14 -5
  39. package/dist/testing.js +30 -3
  40. package/dist/testing.js.map +1 -1
  41. package/dist/testing.mjs +30 -3
  42. package/dist/testing.mjs.map +1 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-C44UWIAD.mjs.map +0 -1
  45. package/dist/chunk-EDGUFCIR.mjs.map +0 -1
  46. package/dist/chunk-JBEFAJ2W.mjs.map +0 -1
  47. package/dist/chunk-ROVYWEBI.mjs.map +0 -1
@@ -10,7 +10,7 @@ import {
10
10
  renumberTasks,
11
11
  stripTrailingCommas,
12
12
  updateTaskInPlan
13
- } from "./chunk-EDGUFCIR.mjs";
13
+ } from "./chunk-JRZPSNRO.mjs";
14
14
 
15
15
  // src/models/Usage.ts
16
16
  function partedPromptUsage(parts) {
@@ -676,7 +676,8 @@ function decideApproval(view, { approvalId, decision, note }) {
676
676
  }
677
677
  function startTurn(view, { message, messageId }) {
678
678
  const queued = messageId ? view.queued.filter((m) => m.id !== messageId) : view.queued;
679
- return append({ ...view, queued, working: true }, (id) => settledMessage(id, "user", message));
679
+ const working = { ...view, queued, working: true };
680
+ return message ? append(working, (id) => settledMessage(id, "user", message)) : working;
680
681
  }
681
682
  var CUT = { completed: null, interrupted: "stopped", failed: "failed" };
682
683
  function endTurn(view, { reason }) {
@@ -849,7 +850,7 @@ function coerceAssignments(tasks, perRunnerAllowlist, allowedRunners, modelsByRu
849
850
  import { v4 as uuidv4 } from "uuid";
850
851
 
851
852
  // src/services/TaskEditValidator.ts
852
- var AI_ONLY_FIELDS = ["assignedModel", "thinkingEffort", "taskMode", "autonomy"];
853
+ var AI_ONLY_FIELDS = ["assignedModel", "thinkingEffort", "taskMode", "autonomy", "ops"];
853
854
  function checkModelAndModeValidity(runner, assignedModel, taskMode, catalog) {
854
855
  if (!catalog) return { ok: true };
855
856
  if (assignedModel) {
@@ -886,6 +887,19 @@ function typeCoherenceCheck(target, changes) {
886
887
  }
887
888
  return { ok: true, clear: target.userSteps && target.userSteps.length > 0 ? ["userSteps"] : [] };
888
889
  }
890
+ var NOT_STARTED = /* @__PURE__ */ new Set(["pending", "approved", "blocked"]);
891
+ function opsCheck(tasks, target, changes) {
892
+ if (!("ops" in changes) || !!changes.ops === !!target.ops) return null;
893
+ if (!NOT_STARTED.has(target.status)) {
894
+ return { ok: false, error: `"${target.title}" has started, so whether it is an ops task is fixed` };
895
+ }
896
+ if (!changes.ops) return null;
897
+ if ((changes.type ?? target.type) !== "ai") return { ok: false, error: `"${target.title}" is a manual task \u2014 only an AI task can be an ops task` };
898
+ if (tasks.some((t) => t.subtasks?.some((s) => s.id === target.id))) {
899
+ return { ok: false, error: `"${target.title}" is a subtask, which runs with its parent \u2014 only a top-level task can be an ops task` };
900
+ }
901
+ return null;
902
+ }
889
903
  function validateTaskEdit(actor, tasks, taskId, changes, catalog) {
890
904
  const target = tasks.find((t) => t.id === taskId);
891
905
  if (!target) return { ok: false, error: "Task not found" };
@@ -899,6 +913,8 @@ function validateTaskEdit(actor, tasks, taskId, changes, catalog) {
899
913
  }
900
914
  const coherence = typeCoherenceCheck(target, changes);
901
915
  if (coherence && !coherence.ok) return coherence;
916
+ const ops = opsCheck(tasks, target, changes);
917
+ if (ops) return ops;
902
918
  const runner = changes.assignedRunner ?? target.assignedRunner;
903
919
  const validity = checkModelAndModeValidity(runner, changes.assignedModel, changes.taskMode, catalog);
904
920
  if (!validity.ok) return validity;
@@ -918,7 +934,8 @@ var UPDATABLE_FIELDS = [
918
934
  "type",
919
935
  "userSteps",
920
936
  "autonomy",
921
- "sliceType"
937
+ "sliceType",
938
+ "ops"
922
939
  ];
923
940
  function taskOpsProtocol(executionNote = "") {
924
941
  const updateChanges = UPDATABLE_FIELDS.map((f) => f === "dependencies" ? '"dependencies"?:["<id or #order>"]' : `"${f}"?`).join(",");
@@ -926,7 +943,7 @@ function taskOpsProtocol(executionNote = "") {
926
943
  "- To modify specific tasks, reply with ONLY this JSON object:",
927
944
  ' {"taskOps": [',
928
945
  ` {"op":"update","taskId":"<id or #order>","changes":{${updateChanges}}},`,
929
- ' {"op":"add","task":{"title","description","prompt","dependencies":["<id or #order>"],"assignedRunner"?,"assignedModel"?},"handle"?:"<name>"},',
946
+ ' {"op":"add","task":{"title","description","prompt","dependencies":["<id or #order>"],"assignedRunner"?,"assignedModel"?,"ops"?},"handle"?:"<name>"},',
930
947
  ' {"op":"remove","taskId":"<id or #order>"},',
931
948
  ' {"op":"reorder","taskIds":["<id or #order>", "... every task exactly once"]}, // only to re-prioritise INDEPENDENT tasks',
932
949
  ' {"op":"merge","taskIds":["<id or #order>", "..."],"merged":{"title","description","prompt"?,"assignedRunner"?,"assignedModel"?,...},"handle"?:"<name>"},',
@@ -1029,6 +1046,14 @@ function refCollidesWithExisting(name, originalFlatAll) {
1029
1046
  if (/^\d+$/.test(orderStr) && originalFlatAll.some((t) => t.order === Number(orderStr))) return true;
1030
1047
  return originalFlatAll.some((t) => t.title === name);
1031
1048
  }
1049
+ function updatableChanges(raw) {
1050
+ const changes = {};
1051
+ for (const key of UPDATABLE_FIELDS) {
1052
+ if (raw && key in raw) changes[key] = raw[key];
1053
+ }
1054
+ if ("ops" in changes) changes.ops = changes.ops === true ? true : void 0;
1055
+ return changes;
1056
+ }
1032
1057
  function findInTasks(tasks, id) {
1033
1058
  return flattenTasks(tasks).find((t) => t.id === id);
1034
1059
  }
@@ -1210,10 +1235,7 @@ function applyTaskOps(currentTasks, ops, runners, catalog) {
1210
1235
  errors.push(`${label}: task "${op.taskId}" no longer exists in this batch (removed, merged, or split by an earlier op)`);
1211
1236
  break;
1212
1237
  }
1213
- const changes = {};
1214
- for (const key of UPDATABLE_FIELDS) {
1215
- if (op.changes && key in op.changes) changes[key] = op.changes[key];
1216
- }
1238
+ const changes = updatableChanges(op.changes);
1217
1239
  if (changes.assignedRunner && !runners.includes(changes.assignedRunner)) {
1218
1240
  errors.push(`${label}: runner "${changes.assignedRunner}" is not in this plan's runner set [${runners.join(", ")}]`);
1219
1241
  break;
@@ -1365,6 +1387,7 @@ function applyTaskOps(currentTasks, ops, runners, catalog) {
1365
1387
  taskMode: spec.taskMode ?? toMerge[0].taskMode,
1366
1388
  autonomy: spec.autonomy ?? toMerge.find((t) => t.autonomy)?.autonomy,
1367
1389
  sliceType: spec.sliceType ?? toMerge.find((t) => t.sliceType)?.sliceType,
1390
+ ops: spec.ops ?? toMerge.every((t) => t.ops),
1368
1391
  userStoriesCovered: spec.userStoriesCovered ?? (toMerge.flatMap((t) => t.userStoriesCovered ?? []).length ? [...new Set(toMerge.flatMap((t) => t.userStoriesCovered ?? []))] : void 0)
1369
1392
  });
1370
1393
  const mergedId = mergedTask.id;
@@ -1445,6 +1468,7 @@ function applyTaskOps(currentTasks, ops, runners, catalog) {
1445
1468
  taskMode: spec.taskMode ?? target.taskMode,
1446
1469
  autonomy: spec.autonomy ?? target.autonomy,
1447
1470
  sliceType: spec.sliceType ?? target.sliceType,
1471
+ ops: spec.ops ?? target.ops,
1448
1472
  userStoriesCovered: spec.userStoriesCovered ?? target.userStoriesCovered
1449
1473
  });
1450
1474
  newTasks.push(nt);
@@ -1480,10 +1504,7 @@ function applyTaskOps(currentTasks, ops, runners, catalog) {
1480
1504
  errors.push(`${label}: "${target.title}" is running and cannot be re-armed`);
1481
1505
  break;
1482
1506
  }
1483
- const changes = {};
1484
- for (const key of UPDATABLE_FIELDS) {
1485
- if (op.changes && key in op.changes) changes[key] = op.changes[key];
1486
- }
1507
+ const changes = updatableChanges(op.changes);
1487
1508
  if (changes.assignedRunner && !runners.includes(changes.assignedRunner)) {
1488
1509
  errors.push(`${label}: runner "${changes.assignedRunner}" is not in this plan's runner set [${runners.join(", ")}]`);
1489
1510
  break;
@@ -1647,10 +1668,11 @@ function serializeTask(t) {
1647
1668
  thinkingEffort: t.thinkingEffort || void 0,
1648
1669
  autonomy: t.autonomy || void 0,
1649
1670
  sliceType: t.sliceType || void 0,
1650
- userStoriesCovered: t.userStoriesCovered || void 0
1671
+ userStoriesCovered: t.userStoriesCovered || void 0,
1672
+ ...t.ops ? { ops: true } : {}
1651
1673
  };
1652
1674
  }
1653
- function serializeTaskStatus(t, idleSince = null, isolation = null, queued = [], awaitingApproval = 0) {
1675
+ function serializeTaskStatus(t, idleSince = null, isolation = null, queued = [], awaitingApproval = 0, mergeGate = []) {
1654
1676
  return {
1655
1677
  id: t.id,
1656
1678
  status: t.status,
@@ -1661,7 +1683,9 @@ function serializeTaskStatus(t, idleSince = null, isolation = null, queued = [],
1661
1683
  ...t.status === "awaiting_user" && t.awaitingReason ? { awaitingReason: t.awaitingReason } : {},
1662
1684
  ...queued.length > 0 ? { queued: queued.map((m) => ({ ...m })) } : {},
1663
1685
  ...canContinue(t) ? { continuable: true } : {},
1664
- ...awaitingApproval > 0 ? { awaitingApproval } : {}
1686
+ ...awaitingApproval > 0 ? { awaitingApproval } : {},
1687
+ ...mergeGate.length > 0 ? { mergeGate: [...mergeGate] } : {},
1688
+ ...t.forcedPastGate?.length ? { forcedPastGate: [...t.forcedPastGate] } : {}
1665
1689
  };
1666
1690
  }
1667
1691
  function serializePlan(plan) {
@@ -2112,4 +2136,4 @@ export {
2112
2136
  hasHiddenDetail,
2113
2137
  taskStartedNotice
2114
2138
  };
2115
- //# sourceMappingURL=chunk-ROVYWEBI.mjs.map
2139
+ //# sourceMappingURL=chunk-I6U3PVHL.mjs.map