@cleocode/cleo 2026.5.101 → 2026.5.102
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 +232 -120
- package/dist/cli/index.js.map +3 -3
- package/package.json +11 -11
package/dist/cli/index.js
CHANGED
|
@@ -1531,6 +1531,13 @@ var init_attachment_schema = __esm({
|
|
|
1531
1531
|
}
|
|
1532
1532
|
});
|
|
1533
1533
|
|
|
1534
|
+
// packages/contracts/src/boundary.ts
|
|
1535
|
+
var init_boundary = __esm({
|
|
1536
|
+
"packages/contracts/src/boundary.ts"() {
|
|
1537
|
+
"use strict";
|
|
1538
|
+
}
|
|
1539
|
+
});
|
|
1540
|
+
|
|
1534
1541
|
// packages/contracts/src/branch-lock.ts
|
|
1535
1542
|
var init_branch_lock = __esm({
|
|
1536
1543
|
"packages/contracts/src/branch-lock.ts"() {
|
|
@@ -3912,6 +3919,38 @@ var init_operations_registry = __esm({
|
|
|
3912
3919
|
}
|
|
3913
3920
|
]
|
|
3914
3921
|
},
|
|
3922
|
+
{
|
|
3923
|
+
gateway: "mutate",
|
|
3924
|
+
domain: "tasks",
|
|
3925
|
+
operation: "saga.detach",
|
|
3926
|
+
description: "tasks.saga.detach (mutate) \u2014 remove a Saga member relation (task_relations type=groups); idempotent; appends to .cleo/audit/saga-detach.jsonl (T10118)",
|
|
3927
|
+
tier: 0,
|
|
3928
|
+
idempotent: true,
|
|
3929
|
+
sessionRequired: false,
|
|
3930
|
+
requiredParams: ["sagaId", "memberId"],
|
|
3931
|
+
params: [
|
|
3932
|
+
{
|
|
3933
|
+
name: "sagaId",
|
|
3934
|
+
type: "string",
|
|
3935
|
+
required: true,
|
|
3936
|
+
description: "Saga task ID",
|
|
3937
|
+
cli: { positional: true }
|
|
3938
|
+
},
|
|
3939
|
+
{
|
|
3940
|
+
name: "memberId",
|
|
3941
|
+
type: "string",
|
|
3942
|
+
required: true,
|
|
3943
|
+
description: "Member task ID to detach from the Saga",
|
|
3944
|
+
cli: { positional: true }
|
|
3945
|
+
},
|
|
3946
|
+
{
|
|
3947
|
+
name: "reason",
|
|
3948
|
+
type: "string",
|
|
3949
|
+
required: false,
|
|
3950
|
+
description: "Human-readable reason recorded in the audit log entry"
|
|
3951
|
+
}
|
|
3952
|
+
]
|
|
3953
|
+
},
|
|
3915
3954
|
{
|
|
3916
3955
|
gateway: "query",
|
|
3917
3956
|
domain: "tasks",
|
|
@@ -3961,6 +4000,27 @@ var init_operations_registry = __esm({
|
|
|
3961
4000
|
}
|
|
3962
4001
|
]
|
|
3963
4002
|
},
|
|
4003
|
+
{
|
|
4004
|
+
// T10117 — detach I5-violating parentId and re-attach via task_relations
|
|
4005
|
+
// type=groups (ADR-073 §1.2 invariant I5). Idempotent.
|
|
4006
|
+
gateway: "mutate",
|
|
4007
|
+
domain: "tasks",
|
|
4008
|
+
operation: "saga.repair",
|
|
4009
|
+
description: "tasks.saga.repair (mutate) \u2014 detach I5-violating parentId and re-attach via task_relations type=groups; idempotent",
|
|
4010
|
+
tier: 0,
|
|
4011
|
+
idempotent: true,
|
|
4012
|
+
sessionRequired: false,
|
|
4013
|
+
requiredParams: ["sagaId"],
|
|
4014
|
+
params: [
|
|
4015
|
+
{
|
|
4016
|
+
name: "sagaId",
|
|
4017
|
+
type: "string",
|
|
4018
|
+
required: true,
|
|
4019
|
+
description: "Saga task ID (must have label=saga)",
|
|
4020
|
+
cli: { positional: true }
|
|
4021
|
+
}
|
|
4022
|
+
]
|
|
4023
|
+
},
|
|
3964
4024
|
{
|
|
3965
4025
|
gateway: "mutate",
|
|
3966
4026
|
domain: "tasks",
|
|
@@ -11081,6 +11141,7 @@ var init_src2 = __esm({
|
|
|
11081
11141
|
"packages/contracts/src/index.ts"() {
|
|
11082
11142
|
init_acceptance_gate_schema();
|
|
11083
11143
|
init_attachment_schema();
|
|
11144
|
+
init_boundary();
|
|
11084
11145
|
init_branch_lock();
|
|
11085
11146
|
init_changesets();
|
|
11086
11147
|
init_cli_category();
|
|
@@ -30688,6 +30749,15 @@ var init_sticky2 = __esm({
|
|
|
30688
30749
|
// packages/cleo/src/dispatch/domains/tasks.ts
|
|
30689
30750
|
import { getLogger as getLogger15, getProjectRoot as getProjectRoot18 } from "@cleocode/core";
|
|
30690
30751
|
import { createAttachmentStore as createAttachmentStore4 } from "@cleocode/core/internal";
|
|
30752
|
+
import {
|
|
30753
|
+
sagaAdd as coreSagaAdd,
|
|
30754
|
+
sagaCreate as coreSagaCreate,
|
|
30755
|
+
detachSagaMember as coreSagaDetach,
|
|
30756
|
+
sagaList as coreSagaList,
|
|
30757
|
+
sagaMembers as coreSagaMembers,
|
|
30758
|
+
repairSaga as coreSagaRepair,
|
|
30759
|
+
sagaRollup as coreSagaRollup
|
|
30760
|
+
} from "@cleocode/core/sagas";
|
|
30691
30761
|
async function fetchTaskAttachments(projectRoot, taskId) {
|
|
30692
30762
|
try {
|
|
30693
30763
|
const store = createAttachmentStore4();
|
|
@@ -30709,137 +30779,42 @@ async function fetchTaskAttachments(projectRoot, taskId) {
|
|
|
30709
30779
|
}
|
|
30710
30780
|
}
|
|
30711
30781
|
async function sagaCreate(params) {
|
|
30712
|
-
const projectRoot = getProjectRoot18();
|
|
30713
30782
|
const title = typeof params.title === "string" ? params.title : "";
|
|
30714
30783
|
const description = typeof params.description === "string" ? params.description : void 0;
|
|
30715
30784
|
const acceptance = Array.isArray(params.acceptance) ? params.acceptance : void 0;
|
|
30716
30785
|
return wrapCoreResult(
|
|
30717
|
-
await
|
|
30718
|
-
title,
|
|
30719
|
-
description,
|
|
30720
|
-
labels: ["saga"],
|
|
30721
|
-
type: "epic",
|
|
30722
|
-
acceptance
|
|
30723
|
-
}),
|
|
30786
|
+
await coreSagaCreate(getProjectRoot18(), { title, description, acceptance }),
|
|
30724
30787
|
"saga.create"
|
|
30725
30788
|
);
|
|
30726
30789
|
}
|
|
30727
30790
|
async function sagaAdd(params) {
|
|
30728
|
-
const projectRoot = getProjectRoot18();
|
|
30729
30791
|
const sagaId = typeof params.sagaId === "string" ? params.sagaId : "";
|
|
30730
30792
|
const epicId = typeof params.epicId === "string" ? params.epicId : "";
|
|
30731
|
-
|
|
30732
|
-
|
|
30733
|
-
|
|
30734
|
-
const
|
|
30735
|
-
|
|
30736
|
-
|
|
30737
|
-
|
|
30738
|
-
|
|
30739
|
-
|
|
30740
|
-
|
|
30741
|
-
return lafsError("E_INVALID_INPUT", `Task ${sagaId} does not have label='saga'`, "saga.add");
|
|
30742
|
-
}
|
|
30743
|
-
const epicResult = await taskShow(projectRoot, epicId);
|
|
30744
|
-
if (!epicResult.success || !epicResult.data) {
|
|
30745
|
-
return lafsError("E_NOT_FOUND", `Epic not found: ${epicId}`, "saga.add");
|
|
30746
|
-
}
|
|
30747
|
-
const epicType = epicResult.data.task?.type;
|
|
30748
|
-
if (epicType !== "epic") {
|
|
30749
|
-
return lafsError(
|
|
30750
|
-
"E_INVALID_INPUT",
|
|
30751
|
-
`Task ${epicId} has type='${String(epicType)}', expected type='epic'`,
|
|
30752
|
-
"saga.add"
|
|
30753
|
-
);
|
|
30754
|
-
}
|
|
30755
|
-
const relResult = await taskRelatesAdd(projectRoot, sagaId, epicId, "groups", void 0);
|
|
30756
|
-
if (!relResult.success) {
|
|
30757
|
-
return lafsError(
|
|
30758
|
-
"E_GENERAL",
|
|
30759
|
-
relResult.error?.message ?? "Failed to link Epic to Saga",
|
|
30760
|
-
"saga.add"
|
|
30761
|
-
);
|
|
30762
|
-
}
|
|
30763
|
-
return lafsSuccess({ sagaId, epicId, added: relResult.data?.added ?? true }, "saga.add");
|
|
30793
|
+
return wrapCoreResult(await coreSagaAdd(getProjectRoot18(), { sagaId, epicId }), "saga.add");
|
|
30794
|
+
}
|
|
30795
|
+
async function sagaDetach(params) {
|
|
30796
|
+
const sagaId = typeof params.sagaId === "string" ? params.sagaId : "";
|
|
30797
|
+
const memberId = typeof params.memberId === "string" ? params.memberId : "";
|
|
30798
|
+
const reason = typeof params.reason === "string" ? params.reason : void 0;
|
|
30799
|
+
return wrapCoreResult(
|
|
30800
|
+
await coreSagaDetach(getProjectRoot18(), { sagaId, memberId, reason }),
|
|
30801
|
+
"saga.detach"
|
|
30802
|
+
);
|
|
30764
30803
|
}
|
|
30765
30804
|
async function sagaList() {
|
|
30766
|
-
|
|
30767
|
-
const result = await taskList(projectRoot, { type: "epic", label: "saga" });
|
|
30768
|
-
if (!result.success) {
|
|
30769
|
-
return lafsError("E_GENERAL", result.error?.message ?? "Failed to list Sagas", "saga.list");
|
|
30770
|
-
}
|
|
30771
|
-
const tasks = result.data?.tasks ?? [];
|
|
30772
|
-
const topLevel = tasks.filter((t) => {
|
|
30773
|
-
const parentId = t.parentId;
|
|
30774
|
-
return !parentId;
|
|
30775
|
-
});
|
|
30776
|
-
return lafsSuccess({ sagas: topLevel, total: topLevel.length }, "saga.list");
|
|
30805
|
+
return wrapCoreResult(await coreSagaList(getProjectRoot18()), "saga.list");
|
|
30777
30806
|
}
|
|
30778
30807
|
async function sagaMembers(params) {
|
|
30779
|
-
const projectRoot = getProjectRoot18();
|
|
30780
30808
|
const sagaId = typeof params.sagaId === "string" ? params.sagaId : "";
|
|
30781
|
-
|
|
30782
|
-
return lafsError("E_INVALID_INPUT", "sagaId is required", "saga.members");
|
|
30783
|
-
}
|
|
30784
|
-
const result = await taskRelates(projectRoot, sagaId);
|
|
30785
|
-
if (!result.success) {
|
|
30786
|
-
return lafsError(
|
|
30787
|
-
"E_GENERAL",
|
|
30788
|
-
result.error?.message ?? "Failed to list Saga members",
|
|
30789
|
-
"saga.members"
|
|
30790
|
-
);
|
|
30791
|
-
}
|
|
30792
|
-
const relations = result.data?.relations ?? [];
|
|
30793
|
-
const members = relations.filter((r) => r.type === "groups");
|
|
30794
|
-
return lafsSuccess(
|
|
30795
|
-
{
|
|
30796
|
-
sagaId,
|
|
30797
|
-
members: members.map((r) => ({ epicId: r.taskId, type: r.type, reason: r.reason })),
|
|
30798
|
-
total: members.length
|
|
30799
|
-
},
|
|
30800
|
-
"saga.members"
|
|
30801
|
-
);
|
|
30809
|
+
return wrapCoreResult(await coreSagaMembers(getProjectRoot18(), { sagaId }), "saga.members");
|
|
30802
30810
|
}
|
|
30803
30811
|
async function sagaRollup(params) {
|
|
30804
|
-
const projectRoot = getProjectRoot18();
|
|
30805
30812
|
const sagaId = typeof params.sagaId === "string" ? params.sagaId : "";
|
|
30806
|
-
|
|
30807
|
-
|
|
30808
|
-
|
|
30809
|
-
const
|
|
30810
|
-
|
|
30811
|
-
return lafsError(
|
|
30812
|
-
"E_GENERAL",
|
|
30813
|
-
relResult.error?.message ?? "Failed to fetch Saga members for rollup",
|
|
30814
|
-
"saga.rollup"
|
|
30815
|
-
);
|
|
30816
|
-
}
|
|
30817
|
-
const members = (relResult.data?.relations ?? []).filter((r) => r.type === "groups");
|
|
30818
|
-
const total = members.length;
|
|
30819
|
-
if (total === 0) {
|
|
30820
|
-
return lafsSuccess(
|
|
30821
|
-
{ sagaId, total: 0, done: 0, active: 0, blocked: 0, pending: 0, completionPct: 0 },
|
|
30822
|
-
"saga.rollup"
|
|
30823
|
-
);
|
|
30824
|
-
}
|
|
30825
|
-
const shows = await Promise.all(members.map((m) => taskShow(projectRoot, m.taskId)));
|
|
30826
|
-
let done = 0;
|
|
30827
|
-
let active = 0;
|
|
30828
|
-
let blocked = 0;
|
|
30829
|
-
let pending = 0;
|
|
30830
|
-
for (const r of shows) {
|
|
30831
|
-
if (!r.success) continue;
|
|
30832
|
-
const status = r.data?.task?.status ?? "pending";
|
|
30833
|
-
if (status === "done") done++;
|
|
30834
|
-
else if (status === "active") active++;
|
|
30835
|
-
else if (status === "blocked") blocked++;
|
|
30836
|
-
else pending++;
|
|
30837
|
-
}
|
|
30838
|
-
const completionPct = total > 0 ? Math.round(done / total * 100) : 0;
|
|
30839
|
-
return lafsSuccess(
|
|
30840
|
-
{ sagaId, total, done, active, blocked, pending, completionPct },
|
|
30841
|
-
"saga.rollup"
|
|
30842
|
-
);
|
|
30813
|
+
return wrapCoreResult(await coreSagaRollup(getProjectRoot18(), { sagaId }), "saga.rollup");
|
|
30814
|
+
}
|
|
30815
|
+
async function sagaRepair(params) {
|
|
30816
|
+
const sagaId = typeof params.sagaId === "string" ? params.sagaId : "";
|
|
30817
|
+
return wrapCoreResult(await coreSagaRepair(getProjectRoot18(), { sagaId }), "saga.repair");
|
|
30843
30818
|
}
|
|
30844
30819
|
var _tasksTypedHandler, QUERY_OPS11, MUTATE_OPS10, TasksHandler;
|
|
30845
30820
|
var init_tasks3 = __esm({
|
|
@@ -31296,7 +31271,11 @@ var init_tasks3 = __esm({
|
|
|
31296
31271
|
"unclaim",
|
|
31297
31272
|
// Saga sub-domain (ADR-073)
|
|
31298
31273
|
"saga.create",
|
|
31299
|
-
"saga.add"
|
|
31274
|
+
"saga.add",
|
|
31275
|
+
// T10117 — repair an I5-violating saga (detach parentId, write groups edge).
|
|
31276
|
+
"saga.repair",
|
|
31277
|
+
// T10118 — repair verb for ADR-073 §1.2 I7 violations (detach saga member).
|
|
31278
|
+
"saga.detach"
|
|
31300
31279
|
]);
|
|
31301
31280
|
TasksHandler = class {
|
|
31302
31281
|
// -----------------------------------------------------------------------
|
|
@@ -31393,6 +31372,26 @@ var init_tasks3 = __esm({
|
|
|
31393
31372
|
startTime
|
|
31394
31373
|
);
|
|
31395
31374
|
}
|
|
31375
|
+
if (operation === "saga.repair") {
|
|
31376
|
+
const envelope = await sagaRepair(params ?? {});
|
|
31377
|
+
return wrapResult(
|
|
31378
|
+
envelopeToEngineResult(envelope),
|
|
31379
|
+
"mutate",
|
|
31380
|
+
"tasks",
|
|
31381
|
+
operation,
|
|
31382
|
+
startTime
|
|
31383
|
+
);
|
|
31384
|
+
}
|
|
31385
|
+
if (operation === "saga.detach") {
|
|
31386
|
+
const envelope = await sagaDetach(params ?? {});
|
|
31387
|
+
return wrapResult(
|
|
31388
|
+
envelopeToEngineResult(envelope),
|
|
31389
|
+
"mutate",
|
|
31390
|
+
"tasks",
|
|
31391
|
+
operation,
|
|
31392
|
+
startTime
|
|
31393
|
+
);
|
|
31394
|
+
}
|
|
31396
31395
|
} catch (error) {
|
|
31397
31396
|
getLogger15("domain:tasks").error(
|
|
31398
31397
|
{ gateway: "mutate", domain: "tasks", operation, err: error },
|
|
@@ -31465,7 +31464,11 @@ var init_tasks3 = __esm({
|
|
|
31465
31464
|
"unclaim",
|
|
31466
31465
|
// Saga sub-domain (ADR-073)
|
|
31467
31466
|
"saga.create",
|
|
31468
|
-
"saga.add"
|
|
31467
|
+
"saga.add",
|
|
31468
|
+
// T10117 — repair an I5-violating saga.
|
|
31469
|
+
"saga.repair",
|
|
31470
|
+
// T10118 — repair verb for ADR-073 §1.2 I7 violations
|
|
31471
|
+
"saga.detach"
|
|
31469
31472
|
]
|
|
31470
31473
|
};
|
|
31471
31474
|
}
|
|
@@ -45844,6 +45847,20 @@ var init_doctor = __esm({
|
|
|
45844
45847
|
type: "boolean",
|
|
45845
45848
|
description: "Audit orphaned CLEO-generated temp directories and report what cleo gc --temp would remove (T9043)"
|
|
45846
45849
|
},
|
|
45850
|
+
/**
|
|
45851
|
+
* T10119: audit every Saga (`type='epic'` + `label='saga'`) for
|
|
45852
|
+
* ADR-073 §1.2 invariant violations (I5/I7 + depth ladder) and
|
|
45853
|
+
* auto-close drift. Read-only; non-zero exit when any I-invariant
|
|
45854
|
+
* fails so the check is CI-gateable.
|
|
45855
|
+
*
|
|
45856
|
+
* @task T10119
|
|
45857
|
+
* @saga T10113
|
|
45858
|
+
* @epic T10209
|
|
45859
|
+
*/
|
|
45860
|
+
"audit-sagas": {
|
|
45861
|
+
type: "boolean",
|
|
45862
|
+
description: "Audit every Saga for ADR-073 \xA71.2 invariant violations (I5/I7/depth) + auto-close drift (T10119)"
|
|
45863
|
+
},
|
|
45847
45864
|
/**
|
|
45848
45865
|
* T9983: migrate the worktree-include file location from
|
|
45849
45866
|
* `<root>/.cleo/worktree-include` (legacy) to `<root>/.worktreeinclude`
|
|
@@ -46250,6 +46267,17 @@ var init_doctor = __esm({
|
|
|
46250
46267
|
if (checkResult.details?.["orphans"] && checkResult.details["orphans"].length > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
|
|
46251
46268
|
process.exitCode = 2;
|
|
46252
46269
|
}
|
|
46270
|
+
} else if (args["audit-sagas"]) {
|
|
46271
|
+
progress.step(0, "Auditing Saga hierarchy for ADR-073 invariants");
|
|
46272
|
+
const { auditSagaHierarchy } = await import("@cleocode/core/doctor/saga-audit.js");
|
|
46273
|
+
const projectRoot = getProjectRoot33();
|
|
46274
|
+
const result = await auditSagaHierarchy(projectRoot);
|
|
46275
|
+
const summary = `Saga audit complete \u2014 ${result.sagas.length} saga(s) inspected, ${result.count} invariant violation(s), ${result.driftCount} drift warning(s)`;
|
|
46276
|
+
progress.complete(summary);
|
|
46277
|
+
cliOutput(result, { command: "doctor", operation: "doctor.audit-sagas" });
|
|
46278
|
+
if (result.count > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
|
|
46279
|
+
process.exitCode = 2;
|
|
46280
|
+
}
|
|
46253
46281
|
} else {
|
|
46254
46282
|
progress.step(0, "Checking CLEO directory");
|
|
46255
46283
|
await dispatchFromCli(
|
|
@@ -46290,6 +46318,34 @@ var init_doctor = __esm({
|
|
|
46290
46318
|
} catch {
|
|
46291
46319
|
progress.complete("Health check complete");
|
|
46292
46320
|
}
|
|
46321
|
+
try {
|
|
46322
|
+
const projectRoot = getProjectRoot33();
|
|
46323
|
+
const { auditSagaHierarchy } = await import("@cleocode/core/doctor/saga-audit.js");
|
|
46324
|
+
const sagaAudit = await auditSagaHierarchy(projectRoot);
|
|
46325
|
+
if (sagaAudit.sagas.length === 0) {
|
|
46326
|
+
humanLine("\nSaga Hierarchy: no sagas found in tasks.db");
|
|
46327
|
+
} else {
|
|
46328
|
+
const header = `
|
|
46329
|
+
Saga Hierarchy (${sagaAudit.sagas.length} saga(s), ${sagaAudit.count} violation(s), ${sagaAudit.driftCount} drift warning(s)):`;
|
|
46330
|
+
humanLine(header);
|
|
46331
|
+
for (const s of sagaAudit.sagas) {
|
|
46332
|
+
const violationSuffix = s.violations.length > 0 ? `, ${s.violations.length} violation(s)` : "";
|
|
46333
|
+
humanLine(
|
|
46334
|
+
` ${s.sagaId} \xB7 status=${s.status} \xB7 ${s.doneCount}/${s.memberCount} members done${violationSuffix}`
|
|
46335
|
+
);
|
|
46336
|
+
for (const v of s.violations) {
|
|
46337
|
+
humanLine(` [${v.kind}] ${v.message}`);
|
|
46338
|
+
}
|
|
46339
|
+
}
|
|
46340
|
+
}
|
|
46341
|
+
if (sagaAudit.count > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
|
|
46342
|
+
process.exitCode = 2;
|
|
46343
|
+
}
|
|
46344
|
+
} catch (err) {
|
|
46345
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
46346
|
+
humanLine(`
|
|
46347
|
+
Saga Hierarchy: audit skipped (${msg})`);
|
|
46348
|
+
}
|
|
46293
46349
|
}
|
|
46294
46350
|
} catch (err) {
|
|
46295
46351
|
progress.error("Health check failed");
|
|
@@ -59755,7 +59811,7 @@ __export(saga_exports, {
|
|
|
59755
59811
|
sagaCommand: () => sagaCommand
|
|
59756
59812
|
});
|
|
59757
59813
|
import { parseAcceptanceCriteria } from "@cleocode/core";
|
|
59758
|
-
var createCommand3, addCommand11, listCommand22, membersCommand, rollupCommand2, sagaCommand;
|
|
59814
|
+
var createCommand3, addCommand11, detachCommand2, listCommand22, membersCommand, repairCommand, rollupCommand2, sagaCommand;
|
|
59759
59815
|
var init_saga = __esm({
|
|
59760
59816
|
"packages/cleo/src/cli/commands/saga.ts"() {
|
|
59761
59817
|
"use strict";
|
|
@@ -59827,6 +59883,38 @@ var init_saga = __esm({
|
|
|
59827
59883
|
);
|
|
59828
59884
|
}
|
|
59829
59885
|
});
|
|
59886
|
+
detachCommand2 = defineCommand({
|
|
59887
|
+
meta: {
|
|
59888
|
+
name: "detach",
|
|
59889
|
+
description: "Remove a Saga member relation (task_relations type=groups) \u2014 idempotent, audit-logged"
|
|
59890
|
+
},
|
|
59891
|
+
args: {
|
|
59892
|
+
sagaId: {
|
|
59893
|
+
type: "positional",
|
|
59894
|
+
description: "Saga task ID",
|
|
59895
|
+
required: true
|
|
59896
|
+
},
|
|
59897
|
+
memberId: {
|
|
59898
|
+
type: "positional",
|
|
59899
|
+
description: "Member task ID to detach from the Saga",
|
|
59900
|
+
required: true
|
|
59901
|
+
},
|
|
59902
|
+
reason: {
|
|
59903
|
+
type: "string",
|
|
59904
|
+
description: "Human-readable reason recorded in the audit log entry",
|
|
59905
|
+
required: false
|
|
59906
|
+
}
|
|
59907
|
+
},
|
|
59908
|
+
async run({ args }) {
|
|
59909
|
+
await dispatchFromCli(
|
|
59910
|
+
"mutate",
|
|
59911
|
+
"tasks",
|
|
59912
|
+
"saga.detach",
|
|
59913
|
+
{ sagaId: args.sagaId, memberId: args.memberId, reason: args.reason },
|
|
59914
|
+
{ command: "saga", operation: "tasks.saga.detach" }
|
|
59915
|
+
);
|
|
59916
|
+
}
|
|
59917
|
+
});
|
|
59830
59918
|
listCommand22 = defineCommand({
|
|
59831
59919
|
meta: {
|
|
59832
59920
|
name: "list",
|
|
@@ -59858,6 +59946,28 @@ var init_saga = __esm({
|
|
|
59858
59946
|
);
|
|
59859
59947
|
}
|
|
59860
59948
|
});
|
|
59949
|
+
repairCommand = defineCommand({
|
|
59950
|
+
meta: {
|
|
59951
|
+
name: "repair",
|
|
59952
|
+
description: "Detach an I5-violating parentId from a Saga and re-attach via task_relations.type='groups' (ADR-073 \xA71.2). Idempotent."
|
|
59953
|
+
},
|
|
59954
|
+
args: {
|
|
59955
|
+
sagaId: {
|
|
59956
|
+
type: "positional",
|
|
59957
|
+
description: "Saga task ID (must have label=saga)",
|
|
59958
|
+
required: true
|
|
59959
|
+
}
|
|
59960
|
+
},
|
|
59961
|
+
async run({ args }) {
|
|
59962
|
+
await dispatchFromCli(
|
|
59963
|
+
"mutate",
|
|
59964
|
+
"tasks",
|
|
59965
|
+
"saga.repair",
|
|
59966
|
+
{ sagaId: args.sagaId },
|
|
59967
|
+
{ command: "saga", operation: "tasks.saga.repair" }
|
|
59968
|
+
);
|
|
59969
|
+
}
|
|
59970
|
+
});
|
|
59861
59971
|
rollupCommand2 = defineCommand({
|
|
59862
59972
|
meta: {
|
|
59863
59973
|
name: "rollup",
|
|
@@ -59886,9 +59996,11 @@ var init_saga = __esm({
|
|
|
59886
59996
|
subCommands: {
|
|
59887
59997
|
create: createCommand3,
|
|
59888
59998
|
add: addCommand11,
|
|
59999
|
+
detach: detachCommand2,
|
|
59889
60000
|
list: listCommand22,
|
|
59890
60001
|
members: membersCommand,
|
|
59891
|
-
rollup: rollupCommand2
|
|
60002
|
+
rollup: rollupCommand2,
|
|
60003
|
+
repair: repairCommand
|
|
59892
60004
|
},
|
|
59893
60005
|
async run({ cmd, rawArgs }) {
|
|
59894
60006
|
const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
|
|
@@ -61464,7 +61576,7 @@ __export(sequence_exports, {
|
|
|
61464
61576
|
sequenceCommand: () => sequenceCommand
|
|
61465
61577
|
});
|
|
61466
61578
|
import { getProjectRoot as getProjectRoot40 } from "@cleocode/core/internal";
|
|
61467
|
-
var showCommand12, checkCommand6,
|
|
61579
|
+
var showCommand12, checkCommand6, repairCommand2, sequenceCommand;
|
|
61468
61580
|
var init_sequence = __esm({
|
|
61469
61581
|
"packages/cleo/src/cli/commands/sequence.ts"() {
|
|
61470
61582
|
"use strict";
|
|
@@ -61495,7 +61607,7 @@ var init_sequence = __esm({
|
|
|
61495
61607
|
);
|
|
61496
61608
|
}
|
|
61497
61609
|
});
|
|
61498
|
-
|
|
61610
|
+
repairCommand2 = defineCommand({
|
|
61499
61611
|
meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
|
|
61500
61612
|
async run() {
|
|
61501
61613
|
const { repairSequence } = await import("@cleocode/core/internal");
|
|
@@ -61519,7 +61631,7 @@ var init_sequence = __esm({
|
|
|
61519
61631
|
subCommands: {
|
|
61520
61632
|
show: showCommand12,
|
|
61521
61633
|
check: checkCommand6,
|
|
61522
|
-
repair:
|
|
61634
|
+
repair: repairCommand2
|
|
61523
61635
|
},
|
|
61524
61636
|
async run({ cmd, rawArgs }) {
|
|
61525
61637
|
const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
|