@cleocode/cleo 2026.5.100 → 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 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();
@@ -14606,7 +14667,7 @@ var init_job_manager_accessor = __esm({
14606
14667
  });
14607
14668
 
14608
14669
  // packages/cleo/src/cli/paths.ts
14609
- var CLEO_DIR_NAME, AGENTS_SUBDIR, CANT_AGENTS_SUBDIR, WORKFLOWS_SUBDIR, TEMPLATES_SUBDIR, RESTORE_IMPORTED_SUBDIR, TASKS_DB_FILENAME, BRAIN_DB_FILENAME, CONDUIT_DB_FILENAME, NEXUS_DB_FILENAME, SIGNALDOCK_DB_FILENAME, CONFIG_JSON, PROJECT_INFO_JSON, PROJECT_CONTEXT_JSON, RESTORE_CONFLICTS_MD, MIGRATE_MEMORY_HASHES_JSON, CLEO_INJECTION_MD, CLI_PROJECT_BACKUP_FILES, CLI_GLOBAL_BACKUP_FILES, RESTORE_VALID_JSON_FILENAMES, RESTORE_DEFAULT_FILE;
14670
+ var CLEO_DIR_NAME, AGENTS_SUBDIR, CANT_AGENTS_SUBDIR, WORKFLOWS_SUBDIR, TEMPLATES_SUBDIR, RESTORE_IMPORTED_SUBDIR, TASKS_DB_FILENAME, BRAIN_DB_FILENAME, CONDUIT_DB_FILENAME, NEXUS_DB_FILENAME, SIGNALDOCK_DB_FILENAME, CONFIG_JSON, PROJECT_INFO_JSON, PROJECT_CONTEXT_JSON, RESTORE_CONFLICTS_MD, MIGRATE_MEMORY_HASHES_JSON, CLEO_INJECTION_MD, CLI_PROJECT_BACKUP_FILES, CLI_GLOBAL_BACKUP_FILES, RESTORE_DEFAULT_FILE;
14610
14671
  var init_paths = __esm({
14611
14672
  "packages/cleo/src/cli/paths.ts"() {
14612
14673
  "use strict";
@@ -14636,11 +14697,6 @@ var init_paths = __esm({
14636
14697
  `${CLEO_DIR_NAME}/${PROJECT_CONTEXT_JSON}`
14637
14698
  ];
14638
14699
  CLI_GLOBAL_BACKUP_FILES = [NEXUS_DB_FILENAME, SIGNALDOCK_DB_FILENAME];
14639
- RESTORE_VALID_JSON_FILENAMES = /* @__PURE__ */ new Set([
14640
- CONFIG_JSON,
14641
- PROJECT_INFO_JSON,
14642
- PROJECT_CONTEXT_JSON
14643
- ]);
14644
14700
  RESTORE_DEFAULT_FILE = TASKS_DB_FILENAME;
14645
14701
  }
14646
14702
  });
@@ -30693,6 +30749,15 @@ var init_sticky2 = __esm({
30693
30749
  // packages/cleo/src/dispatch/domains/tasks.ts
30694
30750
  import { getLogger as getLogger15, getProjectRoot as getProjectRoot18 } from "@cleocode/core";
30695
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";
30696
30761
  async function fetchTaskAttachments(projectRoot, taskId) {
30697
30762
  try {
30698
30763
  const store = createAttachmentStore4();
@@ -30714,137 +30779,42 @@ async function fetchTaskAttachments(projectRoot, taskId) {
30714
30779
  }
30715
30780
  }
30716
30781
  async function sagaCreate(params) {
30717
- const projectRoot = getProjectRoot18();
30718
30782
  const title = typeof params.title === "string" ? params.title : "";
30719
30783
  const description = typeof params.description === "string" ? params.description : void 0;
30720
30784
  const acceptance = Array.isArray(params.acceptance) ? params.acceptance : void 0;
30721
30785
  return wrapCoreResult(
30722
- await addTaskWithSessionScope(projectRoot, {
30723
- title,
30724
- description,
30725
- labels: ["saga"],
30726
- type: "epic",
30727
- acceptance
30728
- }),
30786
+ await coreSagaCreate(getProjectRoot18(), { title, description, acceptance }),
30729
30787
  "saga.create"
30730
30788
  );
30731
30789
  }
30732
30790
  async function sagaAdd(params) {
30733
- const projectRoot = getProjectRoot18();
30734
30791
  const sagaId = typeof params.sagaId === "string" ? params.sagaId : "";
30735
30792
  const epicId = typeof params.epicId === "string" ? params.epicId : "";
30736
- if (!sagaId || !epicId) {
30737
- return lafsError("E_INVALID_INPUT", "sagaId and epicId are required", "saga.add");
30738
- }
30739
- const sagaResult = await taskShow(projectRoot, sagaId);
30740
- if (!sagaResult.success || !sagaResult.data) {
30741
- return lafsError("E_NOT_FOUND", `Saga not found: ${sagaId}`, "saga.add");
30742
- }
30743
- const sagaTask = sagaResult.data.task;
30744
- const sagaLabels = sagaTask?.labels ?? [];
30745
- if (!sagaLabels.includes("saga")) {
30746
- return lafsError("E_INVALID_INPUT", `Task ${sagaId} does not have label='saga'`, "saga.add");
30747
- }
30748
- const epicResult = await taskShow(projectRoot, epicId);
30749
- if (!epicResult.success || !epicResult.data) {
30750
- return lafsError("E_NOT_FOUND", `Epic not found: ${epicId}`, "saga.add");
30751
- }
30752
- const epicType = epicResult.data.task?.type;
30753
- if (epicType !== "epic") {
30754
- return lafsError(
30755
- "E_INVALID_INPUT",
30756
- `Task ${epicId} has type='${String(epicType)}', expected type='epic'`,
30757
- "saga.add"
30758
- );
30759
- }
30760
- const relResult = await taskRelatesAdd(projectRoot, sagaId, epicId, "groups", void 0);
30761
- if (!relResult.success) {
30762
- return lafsError(
30763
- "E_GENERAL",
30764
- relResult.error?.message ?? "Failed to link Epic to Saga",
30765
- "saga.add"
30766
- );
30767
- }
30768
- 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
+ );
30769
30803
  }
30770
30804
  async function sagaList() {
30771
- const projectRoot = getProjectRoot18();
30772
- const result = await taskList(projectRoot, { type: "epic", label: "saga" });
30773
- if (!result.success) {
30774
- return lafsError("E_GENERAL", result.error?.message ?? "Failed to list Sagas", "saga.list");
30775
- }
30776
- const tasks = result.data?.tasks ?? [];
30777
- const topLevel = tasks.filter((t) => {
30778
- const parentId = t.parentId;
30779
- return !parentId;
30780
- });
30781
- return lafsSuccess({ sagas: topLevel, total: topLevel.length }, "saga.list");
30805
+ return wrapCoreResult(await coreSagaList(getProjectRoot18()), "saga.list");
30782
30806
  }
30783
30807
  async function sagaMembers(params) {
30784
- const projectRoot = getProjectRoot18();
30785
30808
  const sagaId = typeof params.sagaId === "string" ? params.sagaId : "";
30786
- if (!sagaId) {
30787
- return lafsError("E_INVALID_INPUT", "sagaId is required", "saga.members");
30788
- }
30789
- const result = await taskRelates(projectRoot, sagaId);
30790
- if (!result.success) {
30791
- return lafsError(
30792
- "E_GENERAL",
30793
- result.error?.message ?? "Failed to list Saga members",
30794
- "saga.members"
30795
- );
30796
- }
30797
- const relations = result.data?.relations ?? [];
30798
- const members = relations.filter((r) => r.type === "groups");
30799
- return lafsSuccess(
30800
- {
30801
- sagaId,
30802
- members: members.map((r) => ({ epicId: r.taskId, type: r.type, reason: r.reason })),
30803
- total: members.length
30804
- },
30805
- "saga.members"
30806
- );
30809
+ return wrapCoreResult(await coreSagaMembers(getProjectRoot18(), { sagaId }), "saga.members");
30807
30810
  }
30808
30811
  async function sagaRollup(params) {
30809
- const projectRoot = getProjectRoot18();
30810
30812
  const sagaId = typeof params.sagaId === "string" ? params.sagaId : "";
30811
- if (!sagaId) {
30812
- return lafsError("E_INVALID_INPUT", "sagaId is required", "saga.rollup");
30813
- }
30814
- const relResult = await taskRelates(projectRoot, sagaId);
30815
- if (!relResult.success) {
30816
- return lafsError(
30817
- "E_GENERAL",
30818
- relResult.error?.message ?? "Failed to fetch Saga members for rollup",
30819
- "saga.rollup"
30820
- );
30821
- }
30822
- const members = (relResult.data?.relations ?? []).filter((r) => r.type === "groups");
30823
- const total = members.length;
30824
- if (total === 0) {
30825
- return lafsSuccess(
30826
- { sagaId, total: 0, done: 0, active: 0, blocked: 0, pending: 0, completionPct: 0 },
30827
- "saga.rollup"
30828
- );
30829
- }
30830
- const shows = await Promise.all(members.map((m) => taskShow(projectRoot, m.taskId)));
30831
- let done = 0;
30832
- let active = 0;
30833
- let blocked = 0;
30834
- let pending = 0;
30835
- for (const r of shows) {
30836
- if (!r.success) continue;
30837
- const status = r.data?.task?.status ?? "pending";
30838
- if (status === "done") done++;
30839
- else if (status === "active") active++;
30840
- else if (status === "blocked") blocked++;
30841
- else pending++;
30842
- }
30843
- const completionPct = total > 0 ? Math.round(done / total * 100) : 0;
30844
- return lafsSuccess(
30845
- { sagaId, total, done, active, blocked, pending, completionPct },
30846
- "saga.rollup"
30847
- );
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");
30848
30818
  }
30849
30819
  var _tasksTypedHandler, QUERY_OPS11, MUTATE_OPS10, TasksHandler;
30850
30820
  var init_tasks3 = __esm({
@@ -31301,7 +31271,11 @@ var init_tasks3 = __esm({
31301
31271
  "unclaim",
31302
31272
  // Saga sub-domain (ADR-073)
31303
31273
  "saga.create",
31304
- "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"
31305
31279
  ]);
31306
31280
  TasksHandler = class {
31307
31281
  // -----------------------------------------------------------------------
@@ -31398,6 +31372,26 @@ var init_tasks3 = __esm({
31398
31372
  startTime
31399
31373
  );
31400
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
+ }
31401
31395
  } catch (error) {
31402
31396
  getLogger15("domain:tasks").error(
31403
31397
  { gateway: "mutate", domain: "tasks", operation, err: error },
@@ -31470,7 +31464,11 @@ var init_tasks3 = __esm({
31470
31464
  "unclaim",
31471
31465
  // Saga sub-domain (ADR-073)
31472
31466
  "saga.create",
31473
- "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"
31474
31472
  ]
31475
31473
  };
31476
31474
  }
@@ -32235,13 +32233,13 @@ var init_upgrade = __esm({
32235
32233
  // packages/cleo/src/dispatch/domains/worktree.ts
32236
32234
  import {
32237
32235
  adoptWorktree,
32236
+ destroyWorktree,
32238
32237
  forceUnlockWorktree,
32239
32238
  getLogger as getLogger18,
32240
32239
  getProjectRoot as getProjectRoot21,
32241
32240
  listWorktrees,
32242
32241
  pruneOrphanedWorktreesByStatus
32243
32242
  } from "@cleocode/core/internal";
32244
- import { destroyWorktree } from "@cleocode/worktree";
32245
32243
  function coerceStatusFilter(value) {
32246
32244
  if (value === void 0 || value === null) return void 0;
32247
32245
  const raw = Array.isArray(value) ? value.filter((v) => typeof v === "string") : typeof value === "string" ? value.split(",").map((s) => s.trim()) : [];
@@ -37755,66 +37753,19 @@ var backup_inspect_exports = {};
37755
37753
  __export(backup_inspect_exports, {
37756
37754
  backupInspectSubCommand: () => backupInspectSubCommand
37757
37755
  });
37758
- import crypto2 from "node:crypto";
37759
37756
  import fs from "node:fs";
37760
37757
  import os from "node:os";
37761
37758
  import path from "node:path";
37762
37759
  import zlib from "node:zlib";
37763
- function extractManifestFromTar(tarBuf) {
37764
- let offset = 0;
37765
- while (offset + TAR_BLOCK_SIZE <= tarBuf.length) {
37766
- const header = tarBuf.subarray(offset, offset + TAR_BLOCK_SIZE);
37767
- if (header.every((b) => b === 0)) {
37768
- break;
37769
- }
37770
- const rawName = header.subarray(TAR_NAME_OFFSET, TAR_NAME_OFFSET + TAR_NAME_LENGTH);
37771
- const nullIdx = rawName.indexOf(0);
37772
- const entryName = rawName.subarray(0, nullIdx === -1 ? TAR_NAME_LENGTH : nullIdx).toString("utf8");
37773
- const typeFlag = String.fromCharCode(header[TAR_TYPE_OFFSET] ?? 0);
37774
- const isRegular = typeFlag === "0" || typeFlag === "\0";
37775
- const rawSize = header.subarray(TAR_SIZE_OFFSET, TAR_SIZE_OFFSET + TAR_SIZE_LENGTH).toString("utf8").replace(/\0/g, "").trim();
37776
- const fileSize = parseInt(rawSize, 8);
37777
- offset += TAR_BLOCK_SIZE;
37778
- const normalizedName = entryName.replace(/^\.\//, "");
37779
- if (isRegular && normalizedName === "manifest.json") {
37780
- if (offset + fileSize > tarBuf.length) {
37781
- return null;
37782
- }
37783
- return tarBuf.subarray(offset, offset + fileSize).toString("utf8");
37784
- }
37785
- if (!Number.isNaN(fileSize) && fileSize > 0) {
37786
- offset += Math.ceil(fileSize / TAR_BLOCK_SIZE) * TAR_BLOCK_SIZE;
37787
- }
37788
- }
37789
- return null;
37790
- }
37791
- function verifyManifestHash(raw, manifest) {
37792
- const integrity = manifest["integrity"];
37793
- if (!integrity || typeof integrity["manifestHash"] !== "string") {
37794
- return false;
37795
- }
37796
- const expectedHash = integrity["manifestHash"];
37797
- let obj;
37798
- try {
37799
- obj = JSON.parse(raw);
37800
- } catch {
37801
- return false;
37802
- }
37803
- const intObj = obj["integrity"];
37804
- intObj["manifestHash"] = "";
37805
- const forHashing = JSON.stringify(obj);
37806
- const computed = crypto2.createHash("sha256").update(forHashing).digest("hex");
37807
- return computed === expectedHash;
37808
- }
37809
- function fmtBytes(bytes) {
37810
- if (bytes >= 1024 * 1024) {
37811
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
37812
- }
37813
- if (bytes >= 1024) {
37814
- return `${(bytes / 1024).toFixed(1)} KB`;
37815
- }
37816
- return `${bytes} B`;
37817
- }
37760
+ import {
37761
+ detectEncryption,
37762
+ ENC_MIN_LENGTH,
37763
+ ENC_VERSION_OFFSET,
37764
+ ENC_VERSION_SUPPORTED,
37765
+ extractManifestFromTar,
37766
+ fmtBytes,
37767
+ verifyManifestHash
37768
+ } from "@cleocode/core";
37818
37769
  function printInspectReport(bundlePath, bundleSize, encrypted, manifest, integrityOk) {
37819
37770
  const backup = manifest["backup"] ?? {};
37820
37771
  const databases = manifest["databases"] ?? [];
@@ -37870,16 +37821,6 @@ function printInspectReport(bundlePath, bundleSize, encrypted, manifest, integri
37870
37821
  lines.push(`Manifest integrity: [${integrityOk ? "OK" : "TAMPERED"}]`);
37871
37822
  humanLine(lines.join("\n"));
37872
37823
  }
37873
- function detectEncryption(filePath) {
37874
- const header = Buffer.alloc(8);
37875
- const fd = fs.openSync(filePath, "r");
37876
- try {
37877
- fs.readSync(fd, header, 0, 8, 0);
37878
- } finally {
37879
- fs.closeSync(fd);
37880
- }
37881
- return header.toString("utf8") === CLEO_ENC_MAGIC;
37882
- }
37883
37824
  async function inspectAction(bundlePath) {
37884
37825
  const resolved = path.resolve(bundlePath);
37885
37826
  if (!fs.existsSync(resolved)) {
@@ -37980,22 +37921,12 @@ async function inspectTarball(tarPath, displayPath, encrypted) {
37980
37921
  printInspectReport(displayPath, stat3.size, encrypted, manifest, integrityOk);
37981
37922
  process.exitCode = 0;
37982
37923
  }
37983
- var CLEO_ENC_MAGIC, ENC_VERSION_OFFSET, ENC_VERSION_SUPPORTED, ENC_MIN_LENGTH, TAR_BLOCK_SIZE, TAR_NAME_OFFSET, TAR_NAME_LENGTH, TAR_SIZE_OFFSET, TAR_SIZE_LENGTH, TAR_TYPE_OFFSET, backupInspectSubCommand;
37924
+ var backupInspectSubCommand;
37984
37925
  var init_backup_inspect = __esm({
37985
37926
  "packages/cleo/src/cli/commands/backup-inspect.ts"() {
37986
37927
  "use strict";
37987
37928
  init_dist();
37988
37929
  init_renderers();
37989
- CLEO_ENC_MAGIC = "CLEOENC1";
37990
- ENC_VERSION_OFFSET = 8;
37991
- ENC_VERSION_SUPPORTED = 1;
37992
- ENC_MIN_LENGTH = 8 + 1 + 7 + 32 + 12 + 16;
37993
- TAR_BLOCK_SIZE = 512;
37994
- TAR_NAME_OFFSET = 0;
37995
- TAR_NAME_LENGTH = 100;
37996
- TAR_SIZE_OFFSET = 124;
37997
- TAR_SIZE_LENGTH = 12;
37998
- TAR_TYPE_OFFSET = 156;
37999
37930
  backupInspectSubCommand = defineCommand({
38000
37931
  meta: {
38001
37932
  name: "inspect",
@@ -38020,7 +37951,7 @@ var backup_exports = {};
38020
37951
  __export(backup_exports, {
38021
37952
  backupCommand: () => backupCommand
38022
37953
  });
38023
- import crypto3 from "node:crypto";
37954
+ import crypto2 from "node:crypto";
38024
37955
  import fs2 from "node:fs";
38025
37956
  import path2 from "node:path";
38026
37957
  import readline from "node:readline";
@@ -38074,7 +38005,7 @@ function sha256OfMachineKey(cleoHome) {
38074
38005
  if (!fs2.existsSync(keyPath)) {
38075
38006
  return "0".repeat(64);
38076
38007
  }
38077
- return crypto3.createHash("sha256").update(fs2.readFileSync(keyPath)).digest("hex");
38008
+ return crypto2.createHash("sha256").update(fs2.readFileSync(keyPath)).digest("hex");
38078
38009
  }
38079
38010
  var addCommand2, listCommand4, exportCommand, importCommand, backupCommand;
38080
38011
  var init_backup = __esm({
@@ -45916,6 +45847,31 @@ var init_doctor = __esm({
45916
45847
  type: "boolean",
45917
45848
  description: "Audit orphaned CLEO-generated temp directories and report what cleo gc --temp would remove (T9043)"
45918
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
+ },
45864
+ /**
45865
+ * T9983: migrate the worktree-include file location from
45866
+ * `<root>/.cleo/worktree-include` (legacy) to `<root>/.worktreeinclude`
45867
+ * (canonical, matches Claude Code Desktop + worktrunk-core). Backs the
45868
+ * legacy file up to `.cleo/backups/worktree-include-<iso>.bak` before
45869
+ * removing it from the legacy path. Combine with `--dry-run` to preview.
45870
+ */
45871
+ "migrate-worktree-include": {
45872
+ type: "boolean",
45873
+ description: "Migrate <root>/.cleo/worktree-include (legacy) \u2192 <root>/.worktreeinclude (canonical, T9983). Combine with --dry-run to preview."
45874
+ },
45919
45875
  "dry-run": {
45920
45876
  type: "boolean",
45921
45877
  description: "With --quarantine-rogue-cleo-dirs or --scan-stray-nexus-dbs: print what would be done without acting"
@@ -46291,6 +46247,17 @@ var init_doctor = __esm({
46291
46247
  if (result.rejected.length > 0) {
46292
46248
  process.exitCode = 1;
46293
46249
  }
46250
+ } else if (args["migrate-worktree-include"]) {
46251
+ const isDryRun = args["dry-run"] === true;
46252
+ progress.step(
46253
+ 0,
46254
+ `${isDryRun ? "[DRY RUN] " : ""}Migrating .cleo/worktree-include \u2192 .worktreeinclude`
46255
+ );
46256
+ const { migrateWorktreeIncludeFile } = await import("@cleocode/core");
46257
+ const projectRoot = getProjectRoot33();
46258
+ const result = await migrateWorktreeIncludeFile(projectRoot, { dryRun: isDryRun });
46259
+ progress.complete(`Migration ${result.action}`);
46260
+ cliOutput(result, { command: "doctor", operation: "doctor.migrate-worktree-include" });
46294
46261
  } else if (args["audit-temp"]) {
46295
46262
  progress.step(0, "Auditing orphaned CLEO temp directories");
46296
46263
  const { auditOrphanTempDirs } = await import("@cleocode/core/gc/index.js");
@@ -46300,6 +46267,17 @@ var init_doctor = __esm({
46300
46267
  if (checkResult.details?.["orphans"] && checkResult.details["orphans"].length > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
46301
46268
  process.exitCode = 2;
46302
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
+ }
46303
46281
  } else {
46304
46282
  progress.step(0, "Checking CLEO directory");
46305
46283
  await dispatchFromCli(
@@ -46340,6 +46318,34 @@ var init_doctor = __esm({
46340
46318
  } catch {
46341
46319
  progress.complete("Health check complete");
46342
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
+ }
46343
46349
  }
46344
46350
  } catch (err) {
46345
46351
  progress.error("Health check failed");
@@ -59079,116 +59085,19 @@ var init_research2 = __esm({
59079
59085
  // packages/cleo/src/cli/commands/restore.ts
59080
59086
  var restore_exports = {};
59081
59087
  __export(restore_exports, {
59082
- parseConflictReport: () => parseConflictReport,
59088
+ parseConflictReport: () => parseConflictReport2,
59083
59089
  restoreCommand: () => restoreCommand
59084
59090
  });
59085
59091
  import fs3 from "node:fs";
59086
59092
  import path5 from "node:path";
59087
- import { CleoError as CleoError7, getProjectRoot as getProjectRoot39, getTaskAccessor as getTaskAccessor3 } from "@cleocode/core";
59088
- function parseMarkdownValue(raw) {
59089
- const trimmed = raw.trim();
59090
- if (trimmed === "_(not present)_" || trimmed === "") return void 0;
59091
- const stripped = trimmed.replace(/^`([\s\S]*)`$/, "$1").trim();
59092
- try {
59093
- return JSON.parse(stripped);
59094
- } catch {
59095
- return stripped;
59096
- }
59097
- }
59098
- function setAtPath(obj, dotPath, value) {
59099
- const parts = dotPath.split(".");
59100
- let curr = obj;
59101
- for (let i = 0; i < parts.length - 1; i++) {
59102
- const key = parts[i];
59103
- if (curr[key] === void 0 || typeof curr[key] !== "object" || curr[key] === null) {
59104
- curr[key] = {};
59105
- }
59106
- curr = curr[key];
59107
- }
59108
- const lastKey = parts[parts.length - 1];
59109
- curr[lastKey] = value;
59110
- }
59111
- function parseConflictReport(md) {
59112
- const results = [];
59113
- const VALID_FILENAMES = RESTORE_VALID_JSON_FILENAMES;
59114
- const lines = md.split("\n");
59115
- let currentFilename = null;
59116
- let currentSection = null;
59117
- let entryField = null;
59118
- let entryLocalRaw = null;
59119
- let entryImportedRaw = null;
59120
- let entryResolution = null;
59121
- function flushEntry() {
59122
- if (entryField !== null && entryResolution !== null && currentFilename !== null && currentSection !== null) {
59123
- results.push({
59124
- section: currentSection,
59125
- filename: currentFilename,
59126
- fieldPath: entryField,
59127
- localValue: entryLocalRaw !== null ? parseMarkdownValue(entryLocalRaw) : void 0,
59128
- importedValue: entryImportedRaw !== null ? parseMarkdownValue(entryImportedRaw) : void 0,
59129
- resolution: entryResolution
59130
- });
59131
- }
59132
- entryField = null;
59133
- entryLocalRaw = null;
59134
- entryImportedRaw = null;
59135
- entryResolution = null;
59136
- }
59137
- for (const line of lines) {
59138
- const fileHeading = /^##\s+(.+\.json)\s*$/.exec(line);
59139
- if (fileHeading) {
59140
- flushEntry();
59141
- const name = fileHeading[1]?.trim() ?? "";
59142
- currentFilename = VALID_FILENAMES.has(name) ? name : null;
59143
- currentSection = null;
59144
- continue;
59145
- }
59146
- const sectionHeading = /^###\s+(.+)$/.exec(line);
59147
- if (sectionHeading) {
59148
- flushEntry();
59149
- const headingText = (sectionHeading[1] ?? "").toLowerCase();
59150
- if (headingText.includes("manual")) {
59151
- currentSection = "manual";
59152
- } else if (headingText.includes("resolved") || headingText.includes("auto")) {
59153
- currentSection = "auto";
59154
- } else {
59155
- currentSection = null;
59156
- }
59157
- continue;
59158
- }
59159
- if (currentFilename === null || currentSection === null) continue;
59160
- const fieldLine = /^-\s+`([^`]+)`\s*$/.exec(line);
59161
- if (fieldLine) {
59162
- flushEntry();
59163
- entryField = fieldLine[1] ?? null;
59164
- continue;
59165
- }
59166
- if (entryField === null) continue;
59167
- const localLine = /^\s+-\s+Local\s+\(A\):\s+(.+)$/.exec(line);
59168
- if (localLine) {
59169
- entryLocalRaw = localLine[1] ?? "";
59170
- continue;
59171
- }
59172
- const importedLine = /^\s+-\s+Imported\s+\(B\):\s+(.+)$/.exec(line);
59173
- if (importedLine) {
59174
- entryImportedRaw = importedLine[1] ?? "";
59175
- continue;
59176
- }
59177
- const resolutionLine = /^\s+-\s+Resolution:\s+\*\*([^*]+)\*\*/.exec(line);
59178
- if (resolutionLine) {
59179
- const resText = (resolutionLine[1] ?? "").trim();
59180
- if (resText === "A") {
59181
- entryResolution = "A";
59182
- } else if (resText === "B") {
59183
- entryResolution = "B";
59184
- } else {
59185
- entryResolution = "manual-review";
59186
- }
59187
- }
59188
- }
59189
- flushEntry();
59190
- return results;
59191
- }
59093
+ import {
59094
+ CleoError as CleoError7,
59095
+ getProjectRoot as getProjectRoot39,
59096
+ getTaskAccessor as getTaskAccessor3,
59097
+ parseConflictReport,
59098
+ setAtPath
59099
+ } from "@cleocode/core";
59100
+ import { parseConflictReport as parseConflictReport2 } from "@cleocode/core";
59192
59101
  var finalizeCommand, backupSubCommand, taskSubCommand, restoreCommand;
59193
59102
  var init_restore = __esm({
59194
59103
  "packages/cleo/src/cli/commands/restore.ts"() {
@@ -59902,7 +59811,7 @@ __export(saga_exports, {
59902
59811
  sagaCommand: () => sagaCommand
59903
59812
  });
59904
59813
  import { parseAcceptanceCriteria } from "@cleocode/core";
59905
- var createCommand3, addCommand11, listCommand22, membersCommand, rollupCommand2, sagaCommand;
59814
+ var createCommand3, addCommand11, detachCommand2, listCommand22, membersCommand, repairCommand, rollupCommand2, sagaCommand;
59906
59815
  var init_saga = __esm({
59907
59816
  "packages/cleo/src/cli/commands/saga.ts"() {
59908
59817
  "use strict";
@@ -59974,6 +59883,38 @@ var init_saga = __esm({
59974
59883
  );
59975
59884
  }
59976
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
+ });
59977
59918
  listCommand22 = defineCommand({
59978
59919
  meta: {
59979
59920
  name: "list",
@@ -60005,6 +59946,28 @@ var init_saga = __esm({
60005
59946
  );
60006
59947
  }
60007
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
+ });
60008
59971
  rollupCommand2 = defineCommand({
60009
59972
  meta: {
60010
59973
  name: "rollup",
@@ -60033,9 +59996,11 @@ var init_saga = __esm({
60033
59996
  subCommands: {
60034
59997
  create: createCommand3,
60035
59998
  add: addCommand11,
59999
+ detach: detachCommand2,
60036
60000
  list: listCommand22,
60037
60001
  members: membersCommand,
60038
- rollup: rollupCommand2
60002
+ rollup: rollupCommand2,
60003
+ repair: repairCommand
60039
60004
  },
60040
60005
  async run({ cmd, rawArgs }) {
60041
60006
  const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
@@ -61611,7 +61576,7 @@ __export(sequence_exports, {
61611
61576
  sequenceCommand: () => sequenceCommand
61612
61577
  });
61613
61578
  import { getProjectRoot as getProjectRoot40 } from "@cleocode/core/internal";
61614
- var showCommand12, checkCommand6, repairCommand, sequenceCommand;
61579
+ var showCommand12, checkCommand6, repairCommand2, sequenceCommand;
61615
61580
  var init_sequence = __esm({
61616
61581
  "packages/cleo/src/cli/commands/sequence.ts"() {
61617
61582
  "use strict";
@@ -61642,7 +61607,7 @@ var init_sequence = __esm({
61642
61607
  );
61643
61608
  }
61644
61609
  });
61645
- repairCommand = defineCommand({
61610
+ repairCommand2 = defineCommand({
61646
61611
  meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
61647
61612
  async run() {
61648
61613
  const { repairSequence } = await import("@cleocode/core/internal");
@@ -61666,7 +61631,7 @@ var init_sequence = __esm({
61666
61631
  subCommands: {
61667
61632
  show: showCommand12,
61668
61633
  check: checkCommand6,
61669
- repair: repairCommand
61634
+ repair: repairCommand2
61670
61635
  },
61671
61636
  async run({ cmd, rawArgs }) {
61672
61637
  const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
@@ -62539,119 +62504,11 @@ __export(setup_exports, {
62539
62504
  runSetup: () => runSetup,
62540
62505
  setupCommand: () => setupCommand2
62541
62506
  });
62542
- import { createDefaultWizardRunner, WizardInterruptError as WizardInterruptError2 } from "@cleocode/core/setup";
62543
- function mergeConfigJson(parsed, out) {
62544
- out.configJson = parsed;
62545
- for (const [sectionId, sectionOpts] of Object.entries(parsed)) {
62546
- if (!WIZARD_SECTION_IDS.has(sectionId)) continue;
62547
- if (typeof sectionOpts !== "object" || sectionOpts === null) continue;
62548
- if ("provider" in sectionOpts && out.provider === void 0) {
62549
- if (typeof sectionOpts["provider"] === "string" && sectionOpts["provider"] !== "") {
62550
- out.provider = sectionOpts["provider"];
62551
- }
62552
- }
62553
- if ("apiKey" in sectionOpts && out.apiKey === void 0) {
62554
- if (typeof sectionOpts["apiKey"] === "string" && sectionOpts["apiKey"] !== "") {
62555
- out.apiKey = sectionOpts["apiKey"];
62556
- }
62557
- }
62558
- if ("label" in sectionOpts && out.label === void 0) {
62559
- if (typeof sectionOpts["label"] === "string" && sectionOpts["label"] !== "") {
62560
- out.label = sectionOpts["label"];
62561
- }
62562
- }
62563
- if ("agentName" in sectionOpts && out.agentName === void 0) {
62564
- if (typeof sectionOpts["agentName"] === "string" && sectionOpts["agentName"] !== "") {
62565
- out.agentName = sectionOpts["agentName"];
62566
- }
62567
- }
62568
- if ("soulMdContent" in sectionOpts && out.soulMdContent === void 0) {
62569
- if (typeof sectionOpts["soulMdContent"] === "string" && sectionOpts["soulMdContent"] !== "") {
62570
- out.soulMdContent = sectionOpts["soulMdContent"];
62571
- }
62572
- }
62573
- if ("strictness" in sectionOpts && out.strictness === void 0) {
62574
- const s = sectionOpts["strictness"];
62575
- if (s === "strict" || s === "standard" || s === "minimal") {
62576
- out.strictness = s;
62577
- }
62578
- }
62579
- if ("harness" in sectionOpts && out.harness === void 0) {
62580
- const h = sectionOpts["harness"];
62581
- if (h === "pi" || h === "claude-code") {
62582
- out.harness = h;
62583
- }
62584
- }
62585
- if ("brainBridgeMode" in sectionOpts && out.brainBridgeMode === void 0) {
62586
- const b = sectionOpts["brainBridgeMode"];
62587
- if (b === "digest" || b === "file" || b === "disabled") {
62588
- out.brainBridgeMode = b;
62589
- }
62590
- }
62591
- if ("sentientEnabled" in sectionOpts && out.sentientEnabled === void 0) {
62592
- if (typeof sectionOpts["sentientEnabled"] === "boolean") {
62593
- out.sentientEnabled = sectionOpts["sentientEnabled"];
62594
- }
62595
- }
62596
- if ("tier2Enabled" in sectionOpts && out.tier2Enabled === void 0) {
62597
- if (typeof sectionOpts["tier2Enabled"] === "boolean") {
62598
- out.tier2Enabled = sectionOpts["tier2Enabled"];
62599
- }
62600
- }
62601
- if ("signaldockAutoConnect" in sectionOpts && out.signaldockAutoConnect === void 0) {
62602
- if (typeof sectionOpts["signaldockAutoConnect"] === "boolean") {
62603
- out.signaldockAutoConnect = sectionOpts["signaldockAutoConnect"];
62604
- }
62605
- }
62606
- if ("brainRetentionDays" in sectionOpts && out.brainRetentionDays === void 0) {
62607
- const v = sectionOpts["brainRetentionDays"];
62608
- if (typeof v === "number" && Number.isInteger(v) && v >= 0) {
62609
- out.brainRetentionDays = v;
62610
- }
62611
- }
62612
- if ("brainEmbeddingEnabled" in sectionOpts && out.brainEmbeddingEnabled === void 0) {
62613
- if (typeof sectionOpts["brainEmbeddingEnabled"] === "boolean") {
62614
- out.brainEmbeddingEnabled = sectionOpts["brainEmbeddingEnabled"];
62615
- }
62616
- }
62617
- if ("signaldockEnabled" in sectionOpts && out.signaldockEnabled === void 0) {
62618
- if (typeof sectionOpts["signaldockEnabled"] === "boolean") {
62619
- out.signaldockEnabled = sectionOpts["signaldockEnabled"];
62620
- }
62621
- }
62622
- if ("signaldockEndpoint" in sectionOpts && out.signaldockEndpoint === void 0) {
62623
- if (typeof sectionOpts["signaldockEndpoint"] === "string" && sectionOpts["signaldockEndpoint"] !== "") {
62624
- out.signaldockEndpoint = sectionOpts["signaldockEndpoint"];
62625
- }
62626
- }
62627
- if ("studioEnabled" in sectionOpts && out.studioEnabled === void 0) {
62628
- if (typeof sectionOpts["studioEnabled"] === "boolean") {
62629
- out.studioEnabled = sectionOpts["studioEnabled"];
62630
- }
62631
- }
62632
- if ("conduitPath" in sectionOpts && out.conduitPath === void 0) {
62633
- if (typeof sectionOpts["conduitPath"] === "string" && sectionOpts["conduitPath"] !== "") {
62634
- out.conduitPath = sectionOpts["conduitPath"];
62635
- }
62636
- }
62637
- if ("poolSeedingConsent" in sectionOpts && out.poolSeedingConsent === void 0) {
62638
- if (typeof sectionOpts["poolSeedingConsent"] === "boolean") {
62639
- out.poolSeedingConsent = sectionOpts["poolSeedingConsent"];
62640
- }
62641
- }
62642
- if ("acEnforcementMode" in sectionOpts && out.acEnforcementMode === void 0) {
62643
- const m = sectionOpts["acEnforcementMode"];
62644
- if (m === "block" || m === "warn" || m === "off") {
62645
- out.acEnforcementMode = m;
62646
- }
62647
- }
62648
- if ("sessionAutoStart" in sectionOpts && out.sessionAutoStart === void 0) {
62649
- if (typeof sectionOpts["sessionAutoStart"] === "boolean") {
62650
- out.sessionAutoStart = sectionOpts["sessionAutoStart"];
62651
- }
62652
- }
62653
- }
62654
- }
62507
+ import {
62508
+ createDefaultWizardRunner,
62509
+ mergeConfigJson,
62510
+ WizardInterruptError as WizardInterruptError2
62511
+ } from "@cleocode/core/setup";
62655
62512
  function buildWizardOptions(args) {
62656
62513
  const out = {};
62657
62514
  const configJsonRaw = args["config-json"] ?? args["configJson"];
@@ -62781,23 +62638,13 @@ async function runSetup(args, io) {
62781
62638
  ok: isOk(runResult)
62782
62639
  };
62783
62640
  }
62784
- var WIZARD_SECTION_IDS, setupCommand2;
62641
+ var setupCommand2;
62785
62642
  var init_setup = __esm({
62786
62643
  "packages/cleo/src/cli/commands/setup.ts"() {
62787
62644
  "use strict";
62788
62645
  init_dist();
62789
62646
  init_readline_wizard_io();
62790
62647
  init_renderers();
62791
- WIZARD_SECTION_IDS = /* @__PURE__ */ new Set([
62792
- "llm",
62793
- "identity",
62794
- "harness",
62795
- "sentient",
62796
- "project-conventions",
62797
- "brain",
62798
- "integrations",
62799
- "verification"
62800
- ]);
62801
62648
  setupCommand2 = defineCommand({
62802
62649
  meta: {
62803
62650
  name: "setup",