@cleocode/cleo 2026.5.102 → 2026.5.104

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/cli/index.js CHANGED
@@ -4021,6 +4021,35 @@ var init_operations_registry = __esm({
4021
4021
  }
4022
4022
  ]
4023
4023
  },
4024
+ {
4025
+ // T10121 — idempotent cron-safe saga auto-close repair. Re-applies
4026
+ // T10116 logic for sagas whose members reached 100% terminal via paths
4027
+ // OTHER than completeTask (bulk SQL, crash recovery, manual edits).
4028
+ // Supersedes T10098 standalone scope.
4029
+ gateway: "mutate",
4030
+ domain: "tasks",
4031
+ operation: "saga.reconcile",
4032
+ description: "tasks.saga.reconcile (mutate) \u2014 idempotent cron-safe saga auto-close repair; per-saga advisory lock + audit log; supersedes T10098",
4033
+ tier: 0,
4034
+ idempotent: true,
4035
+ sessionRequired: false,
4036
+ requiredParams: [],
4037
+ params: [
4038
+ {
4039
+ name: "sagaId",
4040
+ type: "string",
4041
+ required: false,
4042
+ description: "Optional saga task ID. Omit to walk every saga.",
4043
+ cli: { positional: true }
4044
+ },
4045
+ {
4046
+ name: "dryRun",
4047
+ type: "boolean",
4048
+ required: false,
4049
+ description: "Report what would happen without mutating rows or writing audit log"
4050
+ }
4051
+ ]
4052
+ },
4024
4053
  {
4025
4054
  gateway: "mutate",
4026
4055
  domain: "tasks",
@@ -30755,6 +30784,7 @@ import {
30755
30784
  detachSagaMember as coreSagaDetach,
30756
30785
  sagaList as coreSagaList,
30757
30786
  sagaMembers as coreSagaMembers,
30787
+ reconcileSaga as coreSagaReconcile,
30758
30788
  repairSaga as coreSagaRepair,
30759
30789
  sagaRollup as coreSagaRollup
30760
30790
  } from "@cleocode/core/sagas";
@@ -30816,6 +30846,14 @@ async function sagaRepair(params) {
30816
30846
  const sagaId = typeof params.sagaId === "string" ? params.sagaId : "";
30817
30847
  return wrapCoreResult(await coreSagaRepair(getProjectRoot18(), { sagaId }), "saga.repair");
30818
30848
  }
30849
+ async function sagaReconcile(params) {
30850
+ const sagaId = typeof params.sagaId === "string" && params.sagaId.length > 0 ? params.sagaId : void 0;
30851
+ const dryRun = params.dryRun === true;
30852
+ return wrapCoreResult(
30853
+ await coreSagaReconcile(getProjectRoot18(), { sagaId, dryRun }),
30854
+ "saga.reconcile"
30855
+ );
30856
+ }
30819
30857
  var _tasksTypedHandler, QUERY_OPS11, MUTATE_OPS10, TasksHandler;
30820
30858
  var init_tasks3 = __esm({
30821
30859
  "packages/cleo/src/dispatch/domains/tasks.ts"() {
@@ -31275,7 +31313,9 @@ var init_tasks3 = __esm({
31275
31313
  // T10117 — repair an I5-violating saga (detach parentId, write groups edge).
31276
31314
  "saga.repair",
31277
31315
  // T10118 — repair verb for ADR-073 §1.2 I7 violations (detach saga member).
31278
- "saga.detach"
31316
+ "saga.detach",
31317
+ // T10121 — idempotent cron-safe auto-close repair (supersedes T10098 scope).
31318
+ "saga.reconcile"
31279
31319
  ]);
31280
31320
  TasksHandler = class {
31281
31321
  // -----------------------------------------------------------------------
@@ -31392,6 +31432,16 @@ var init_tasks3 = __esm({
31392
31432
  startTime
31393
31433
  );
31394
31434
  }
31435
+ if (operation === "saga.reconcile") {
31436
+ const envelope = await sagaReconcile(params ?? {});
31437
+ return wrapResult(
31438
+ envelopeToEngineResult(envelope),
31439
+ "mutate",
31440
+ "tasks",
31441
+ operation,
31442
+ startTime
31443
+ );
31444
+ }
31395
31445
  } catch (error) {
31396
31446
  getLogger15("domain:tasks").error(
31397
31447
  { gateway: "mutate", domain: "tasks", operation, err: error },
@@ -31468,7 +31518,9 @@ var init_tasks3 = __esm({
31468
31518
  // T10117 — repair an I5-violating saga.
31469
31519
  "saga.repair",
31470
31520
  // T10118 — repair verb for ADR-073 §1.2 I7 violations
31471
- "saga.detach"
31521
+ "saga.detach",
31522
+ // T10121 — idempotent cron-safe auto-close repair.
31523
+ "saga.reconcile"
31472
31524
  ]
31473
31525
  };
31474
31526
  }
@@ -40648,6 +40700,10 @@ var init_complete = __esm({
40648
40700
  if (Array.isArray(unblockedTasks) && unblockedTasks.length > 0) {
40649
40701
  output2["unblockedTasks"] = unblockedTasks;
40650
40702
  }
40703
+ const worktreeAutoComplete = data?.worktreeAutoComplete;
40704
+ if (worktreeAutoComplete && typeof worktreeAutoComplete === "object") {
40705
+ output2["worktreeAutoComplete"] = worktreeAutoComplete;
40706
+ }
40651
40707
  cliOutput(output2, { command: "complete", operation: "tasks.complete" });
40652
40708
  }
40653
40709
  });
@@ -59811,7 +59867,7 @@ __export(saga_exports, {
59811
59867
  sagaCommand: () => sagaCommand
59812
59868
  });
59813
59869
  import { parseAcceptanceCriteria } from "@cleocode/core";
59814
- var createCommand3, addCommand11, detachCommand2, listCommand22, membersCommand, repairCommand, rollupCommand2, sagaCommand;
59870
+ var createCommand3, addCommand11, detachCommand2, listCommand22, membersCommand, repairCommand, reconcileCommand5, rollupCommand2, sagaCommand;
59815
59871
  var init_saga = __esm({
59816
59872
  "packages/cleo/src/cli/commands/saga.ts"() {
59817
59873
  "use strict";
@@ -59968,6 +60024,34 @@ var init_saga = __esm({
59968
60024
  );
59969
60025
  }
59970
60026
  });
60027
+ reconcileCommand5 = defineCommand({
60028
+ meta: {
60029
+ name: "reconcile",
60030
+ description: "Idempotent cron-safe saga auto-close repair \u2014 re-applies T10116 logic for state changed outside completeTask"
60031
+ },
60032
+ args: {
60033
+ sagaId: {
60034
+ type: "positional",
60035
+ description: "Optional saga task ID. Omit to walk every saga.",
60036
+ required: false
60037
+ },
60038
+ "dry-run": {
60039
+ type: "boolean",
60040
+ description: "Report what would happen without mutating rows or writing audit log",
60041
+ required: false
60042
+ }
60043
+ },
60044
+ async run({ args }) {
60045
+ const sagaId = typeof args.sagaId === "string" && args.sagaId.length > 0 ? args.sagaId : void 0;
60046
+ await dispatchFromCli(
60047
+ "mutate",
60048
+ "tasks",
60049
+ "saga.reconcile",
60050
+ { sagaId, dryRun: args["dry-run"] === true },
60051
+ { command: "saga", operation: "tasks.saga.reconcile" }
60052
+ );
60053
+ }
60054
+ });
59971
60055
  rollupCommand2 = defineCommand({
59972
60056
  meta: {
59973
60057
  name: "rollup",
@@ -60000,7 +60084,8 @@ var init_saga = __esm({
60000
60084
  list: listCommand22,
60001
60085
  members: membersCommand,
60002
60086
  rollup: rollupCommand2,
60003
- repair: repairCommand
60087
+ repair: repairCommand,
60088
+ reconcile: reconcileCommand5
60004
60089
  },
60005
60090
  async run({ cmd, rawArgs }) {
60006
60091
  const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
@@ -64358,7 +64443,7 @@ var sync_exports = {};
64358
64443
  __export(sync_exports, {
64359
64444
  syncCommand: () => syncCommand6
64360
64445
  });
64361
- var linksRemoveCommand, linksCommand2, reconcileCommand5, syncCommand6;
64446
+ var linksRemoveCommand, linksCommand2, reconcileCommand6, syncCommand6;
64362
64447
  var init_sync = __esm({
64363
64448
  "packages/cleo/src/cli/commands/sync.ts"() {
64364
64449
  "use strict";
@@ -64420,7 +64505,7 @@ var init_sync = __esm({
64420
64505
  );
64421
64506
  }
64422
64507
  });
64423
- reconcileCommand5 = defineCommand({
64508
+ reconcileCommand6 = defineCommand({
64424
64509
  meta: {
64425
64510
  name: "reconcile",
64426
64511
  description: "Reconcile external tasks from a JSON file against CLEO tasks"
@@ -64475,7 +64560,7 @@ var init_sync = __esm({
64475
64560
  meta: { name: "sync", description: "External task synchronisation management" },
64476
64561
  subCommands: {
64477
64562
  links: linksCommand2,
64478
- reconcile: reconcileCommand5
64563
+ reconcile: reconcileCommand6
64479
64564
  },
64480
64565
  async run({ cmd, rawArgs }) {
64481
64566
  const firstArg = rawArgs?.find((a) => !a.startsWith("-"));