@cleocode/cleo 2026.9.25 → 2026.10.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 (59) hide show
  1. package/dist/cli/index.js +1014 -196
  2. package/package.json +13 -13
  3. package/studio-dist/client/_app/immutable/chunks/BhBqZa2S.js +3 -0
  4. package/studio-dist/client/_app/immutable/chunks/{Dj9Ite4c.js → BpRY8_m9.js} +1 -1
  5. package/studio-dist/client/_app/immutable/chunks/{CcEmirN4.js → CMfYgGYJ.js} +1 -1
  6. package/studio-dist/client/_app/immutable/chunks/Cltvu8Dg.js +1 -0
  7. package/studio-dist/client/_app/immutable/entry/{app.tPQyYZoK.js → app.DKqdTuYA.js} +2 -2
  8. package/studio-dist/client/_app/immutable/entry/start.DTRTU1pq.js +1 -0
  9. package/studio-dist/client/_app/immutable/nodes/{0.BVYdqJjU.js → 0.BuXCTiZp.js} +1 -1
  10. package/studio-dist/client/_app/immutable/nodes/{1.DJbQn5Aq.js → 1.CsO1BGsz.js} +1 -1
  11. package/studio-dist/client/_app/immutable/nodes/{15.DFLciLwG.js → 15.Bp-qXNPk.js} +1 -1
  12. package/studio-dist/client/_app/immutable/nodes/{16.BgshH5yX.js → 16.DMXWbK7I.js} +1 -1
  13. package/studio-dist/client/_app/immutable/nodes/{17.BQZJRQ5A.js → 17.CVLdfMFL.js} +1 -1
  14. package/studio-dist/client/_app/immutable/nodes/{18.B_YK1P9Z.js → 18.CyQUos9v.js} +1 -1
  15. package/studio-dist/client/_app/immutable/nodes/{20.Dls8MCe1.js → 20.Dx3wZ86J.js} +1 -1
  16. package/studio-dist/client/_app/immutable/nodes/{24.IXvinnru.js → 24.CXGl5ZJ3.js} +1 -1
  17. package/studio-dist/client/_app/immutable/nodes/25.BKYmiCU1.js +39 -0
  18. package/studio-dist/client/_app/immutable/nodes/{26.B7CS0G5p.js → 26.U1MxbYsk.js} +1 -1
  19. package/studio-dist/client/_app/immutable/nodes/{3.CdayxXUQ.js → 3.CUHmTi6Q.js} +1 -1
  20. package/studio-dist/client/_app/version.json +1 -1
  21. package/studio-dist/server/chunks/{0-AF3xrUkn.js → 0-Ban8NQ70.js} +3 -3
  22. package/studio-dist/server/chunks/1-CZPXu25_.js +9 -0
  23. package/studio-dist/server/chunks/{15-D0fpXhAY.js → 15-C2ukbZuI.js} +3 -3
  24. package/studio-dist/server/chunks/{16-DvOEuR2L.js → 16-C-gWtKZb.js} +3 -3
  25. package/studio-dist/server/chunks/{17-B0jymkfA.js → 17-CzQ5BDNx.js} +3 -3
  26. package/studio-dist/server/chunks/{18-s4VnOMua.js → 18-Cnqp0uMS.js} +3 -3
  27. package/studio-dist/server/chunks/{20-B1I-AIgl.js → 20-D9243OmI.js} +3 -3
  28. package/studio-dist/server/chunks/{24-Cd9TIy6S.js → 24-D-3OyyjO.js} +3 -3
  29. package/studio-dist/server/chunks/{25-CqxPBOK6.js → 25-BC8dXyIT.js} +4 -4
  30. package/studio-dist/server/chunks/{26-CSVz9wrd.js → 26-DIYVHPeE.js} +3 -3
  31. package/studio-dist/server/chunks/{3-CnvKWYCF.js → 3-DDNPJWI0.js} +3 -3
  32. package/studio-dist/server/chunks/{_layout.svelte-DHaVs7sR.js → _layout.svelte-ouauc7nn.js} +4 -4
  33. package/studio-dist/server/chunks/{_page.svelte-Birr_Gmr.js → _page.svelte-B7CTgxGI.js} +4 -4
  34. package/studio-dist/server/chunks/{_page.svelte-3f1I0RBM.js → _page.svelte-BKEo8OSf.js} +3 -3
  35. package/studio-dist/server/chunks/{_page.svelte-B4hpnUVn.js → _page.svelte-Ba45egd6.js} +3 -3
  36. package/studio-dist/server/chunks/{_page.svelte-C2xIuyWy.js → _page.svelte-BlIGw3KR.js} +3 -3
  37. package/studio-dist/server/chunks/{_page.svelte-CW--O2H7.js → _page.svelte-CkagR7NW.js} +3 -3
  38. package/studio-dist/server/chunks/{_page.svelte-BQ3d309E.js → _page.svelte-DS8uziG5.js} +3 -3
  39. package/studio-dist/server/chunks/{_page.svelte-CHQ7E1xk.js → _page.svelte-DU-KSkGO.js} +3 -3
  40. package/studio-dist/server/chunks/{_page.svelte-Do5ujrFm.js → _page.svelte-ZzSjr8MT.js} +5 -5
  41. package/studio-dist/server/chunks/{_page.svelte-DHso8H-7.js → _page.svelte-ez5VvNrn.js} +3 -3
  42. package/studio-dist/server/chunks/{_server.ts-DvaFTJ0E.js → _server.ts-CBaXrLT0.js} +2 -2
  43. package/studio-dist/server/chunks/{_server.ts-10Z9UtEP.js → _server.ts-D0rSedle.js} +3 -3
  44. package/studio-dist/server/chunks/{_server.ts-DrRXPeYo.js → _server.ts-DMqfOwim.js} +3 -3
  45. package/studio-dist/server/chunks/{_server.ts-BNaQ_u-J.js → _server.ts-DNL_pHM3.js} +3 -3
  46. package/studio-dist/server/chunks/{_server.ts-BF8dYynr.js → _server.ts-DYCIQvnl.js} +3 -3
  47. package/studio-dist/server/chunks/{client-CPa0CHb-.js → client-CM2Un2n3.js} +2 -2
  48. package/studio-dist/server/chunks/{dist-b2dqLZbk.js → dist-BUqYzm8B.js} +255 -1
  49. package/studio-dist/server/chunks/{error.svelte-B4-aI-CN.js → error.svelte-ZYrc30ps.js} +3 -3
  50. package/studio-dist/server/chunks/{http-C8NM9yzE.js → http-Dc9ezTZW.js} +2 -2
  51. package/studio-dist/server/chunks/{internal-Ba4D4YGm.js → internal-BkiUrFap.js} +2 -2
  52. package/studio-dist/server/chunks/{stores-DsgjOOHe.js → stores-C00-wTzq.js} +2 -2
  53. package/studio-dist/server/index.js +1 -1
  54. package/studio-dist/server/manifest.js +17 -17
  55. package/studio-dist/client/_app/immutable/chunks/BeqrF76J.js +0 -3
  56. package/studio-dist/client/_app/immutable/chunks/DRFhIGr1.js +0 -1
  57. package/studio-dist/client/_app/immutable/entry/start.TCOC0qnN.js +0 -1
  58. package/studio-dist/client/_app/immutable/nodes/25.BEebPQVq.js +0 -39
  59. package/studio-dist/server/chunks/1-DcpAzosv.js +0 -9
package/dist/cli/index.js CHANGED
@@ -395,6 +395,16 @@ function resolveFieldContext(opts) {
395
395
  };
396
396
  return resolveFieldExtraction(input2);
397
397
  }
398
+ async function withoutOutputPointer(step) {
399
+ const saved = currentContext;
400
+ const { field: _field, ...rest } = saved;
401
+ currentContext = rest;
402
+ try {
403
+ return await step();
404
+ } finally {
405
+ currentContext = saved;
406
+ }
407
+ }
398
408
  var currentContext;
399
409
  var init_field_context = __esm({
400
410
  "packages/cleo/src/cli/field-context.ts"() {
@@ -1234,7 +1244,6 @@ var init_tree = __esm({
1234
1244
  // packages/animations/src/render/index.ts
1235
1245
  var init_render = __esm({
1236
1246
  "packages/animations/src/render/index.ts"() {
1237
- "use strict";
1238
1247
  init_legend();
1239
1248
  init_tree();
1240
1249
  }
@@ -1352,6 +1361,7 @@ var init_spinner_handle = __esm({
1352
1361
  var init_src = __esm({
1353
1362
  "packages/animations/src/index.ts"() {
1354
1363
  init_animate_context();
1364
+ init_render();
1355
1365
  init_spinner_handle();
1356
1366
  }
1357
1367
  });
@@ -4968,7 +4978,7 @@ var init_output_contracts_data = __esm({
4968
4978
  // T12503: the optimistic-concurrency version agents pass to --if-match.
4969
4979
  updatedAt: {
4970
4980
  type: ["string", "null"],
4971
- description: "Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`."
4981
+ description: "Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`. A stale version fails with E_CONFLICT (23); E_TASK_RENAMED (26) when sync re-numbered the task you read (details.expected is its new id)."
4972
4982
  },
4973
4983
  // T12502: the human assignee and the agent claim lease are separate.
4974
4984
  assignee: {
@@ -16454,6 +16464,7 @@ var init_exit_codes = __esm({
16454
16464
  ExitCode2[ExitCode2["VERSION_CONFLICT"] = 23] = "VERSION_CONFLICT";
16455
16465
  ExitCode2[ExitCode2["SESSION_UNBOUND"] = 24] = "SESSION_UNBOUND";
16456
16466
  ExitCode2[ExitCode2["WORKTREE_LOCKED"] = 25] = "WORKTREE_LOCKED";
16467
+ ExitCode2[ExitCode2["TASK_RENAMED"] = 26] = "TASK_RENAMED";
16457
16468
  ExitCode2[ExitCode2["SESSION_EXISTS"] = 30] = "SESSION_EXISTS";
16458
16469
  ExitCode2[ExitCode2["SESSION_NOT_FOUND"] = 31] = "SESSION_NOT_FOUND";
16459
16470
  ExitCode2[ExitCode2["SCOPE_CONFLICT"] = 32] = "SCOPE_CONFLICT";
@@ -22728,7 +22739,30 @@ var init_nexus_account = __esm({
22728
22739
  "E_NEXUS_REVOKE_FAILED",
22729
22740
  "E_NEXUS_REQUEST_FAILED",
22730
22741
  "E_NEXUS_NOT_A_PROJECT",
22731
- "E_NEXUS_INVALID_LABEL"
22742
+ "E_NEXUS_INVALID_LABEL",
22743
+ // Device credentials (cleo-nexus device contract §3.3, §4.0.4; T12868).
22744
+ /** No answer from the API (network error or timeout). */
22745
+ "E_NEXUS_UNREACHABLE",
22746
+ /** `cleo login nexus` while a revoke of this device is unconfirmed (§3.3, v2.9). */
22747
+ "E_NEXUS_REVOKE_PENDING",
22748
+ /** The device was signed out (E9, E11): 401 `device-signed-out`. */
22749
+ "E_NEXUS_DEVICE_SIGNED_OUT",
22750
+ /** The device was revoked (E10, E12): 401 `device-revoked`. */
22751
+ "E_NEXUS_DEVICE_REVOKED",
22752
+ /** A credential replaced or revoked elsewhere, or a `rotation-conflict` (R2). */
22753
+ "E_NEXUS_CREDENTIAL_COMPROMISED",
22754
+ /** The device credential lacks the scope (a read-only device): 403 `insufficient-scope`. */
22755
+ "E_NEXUS_INSUFFICIENT_SCOPE",
22756
+ /** A replica attach from a second device: 409 `replica-copied`. */
22757
+ "E_NEXUS_REPLICA_COPIED",
22758
+ /** Another cleo process holds the device file or an upgrade in flight; retry. */
22759
+ "E_NEXUS_BUSY",
22760
+ /** Several accounts hold a device credential on one origin and none was named. */
22761
+ "E_NEXUS_ACCOUNT_AMBIGUOUS",
22762
+ /** An option that needs device credentials (`--read-only`) with `CLEO_NEXUS_DEVICE=0`. */
22763
+ "E_NEXUS_DEVICE_REQUIRED",
22764
+ /** `.cleo/nexus-link.json` is in a format this CLEO cannot update (written by a newer CLEO). */
22765
+ "E_NEXUS_LINK_FILE_UNSUPPORTED"
22732
22766
  ];
22733
22767
  nexusAccountUserSchema = z25.object({
22734
22768
  id: z25.string(),
@@ -22750,6 +22784,340 @@ var init_nexus_account = __esm({
22750
22784
  }
22751
22785
  });
22752
22786
 
22787
+ // packages/contracts/src/nexus-cloud.ts
22788
+ import { z as z26 } from "zod";
22789
+ var NEXUS_DEVICE_STATES, NEXUS_CLOUD_PROFILES, NEXUS_DEVICE_LIST_STATES, NEXUS_PAGE_LIMIT_MAX, NEXUS_CLOUD_MAX_PAGES, NEXUS_PRESENCE_FRESH_SECONDS, NEXUS_DEVICE_STATE_UNKNOWN, isoTime, profile, deviceState, nexusCloudCredentialSchema, nexusCloudDeviceSchema, nexusCloudOrganizationSchema, nexusCloudUserSchema, nexusCloudWhoamiSchema, nexusCloudDevicePageSchema, nexusCloudPresenceSchema, nexusCloudReplicaSchema, nexusCloudDeviceCountsSchema, projectFields, nexusCloudProjectListItemSchema, nexusCloudProjectPageSchema, nexusCloudProjectDetailSchema, nexusCloudReplicaPageSchema, NEXUS_STATUS_CHECK_IDS, NEXUS_STATUS_VERDICTS, CLOUD_STATUS_VERDICTS, knownCheckId, nexusCloudStatusCheckSchema, nexusCloudStatusSchema, NEXUS_UNAUTHENTICATED_REASONS, NEXUS_FORBIDDEN_REASONS, NEXUS_REVOKED_REASONS, LOGIN, COMPROMISED, DEVICE_REVOKED, SESSION_EXPIRED_LOGIN, SERVER_REFUSED, NEXUS_REVOKED_REASON_ERRORS, NEXUS_UNAUTHENTICATED_ERRORS, NEXUS_FORBIDDEN_ERRORS, NEXUS_CONFLICT_ERRORS, NEXUS_UNREACHABLE_ERROR;
22790
+ var init_nexus_cloud = __esm({
22791
+ "packages/contracts/src/nexus-cloud.ts"() {
22792
+ "use strict";
22793
+ NEXUS_DEVICE_STATES = ["active", "signed-out", "revoked"];
22794
+ NEXUS_CLOUD_PROFILES = ["device", "read-only"];
22795
+ NEXUS_DEVICE_LIST_STATES = ["active", "signed-out", "revoked", "all"];
22796
+ NEXUS_PAGE_LIMIT_MAX = 200;
22797
+ NEXUS_CLOUD_MAX_PAGES = 25;
22798
+ NEXUS_PRESENCE_FRESH_SECONDS = 86400;
22799
+ NEXUS_DEVICE_STATE_UNKNOWN = "unknown";
22800
+ isoTime = z26.iso.datetime({ offset: true });
22801
+ profile = z26.enum(NEXUS_CLOUD_PROFILES).nullable().catch(null);
22802
+ deviceState = z26.enum([...NEXUS_DEVICE_STATES, NEXUS_DEVICE_STATE_UNKNOWN]).catch(NEXUS_DEVICE_STATE_UNKNOWN);
22803
+ nexusCloudCredentialSchema = z26.object({
22804
+ kind: z26.enum(["device", "session"]),
22805
+ credentialId: z26.string().nullable().optional(),
22806
+ profile: profile.optional(),
22807
+ scopes: z26.array(z26.string()).default([]),
22808
+ createdAt: isoTime.nullable().optional(),
22809
+ lastUsedAt: isoTime.nullable().optional(),
22810
+ /** When the credential expires if it is not used again; null for sessions. */
22811
+ idleExpiresAt: isoTime.nullable().optional()
22812
+ });
22813
+ nexusCloudDeviceSchema = z26.object({
22814
+ deviceId: z26.string(),
22815
+ name: z26.string(),
22816
+ platform: z26.string().optional(),
22817
+ arch: z26.string().nullable().optional(),
22818
+ cliVersion: z26.string().nullable().optional(),
22819
+ createdAt: isoTime.optional(),
22820
+ lastSeenAt: isoTime.nullable().optional(),
22821
+ state: deviceState,
22822
+ signedOutAt: isoTime.nullable().optional(),
22823
+ /** Base64 device certificate; null until the device holds a key grant. */
22824
+ certificate: z26.string().nullable().optional(),
22825
+ /** The current credential's profile, or null with none (signed out or revoked). */
22826
+ profile: profile.optional(),
22827
+ /** True for the device whose credential made this request. */
22828
+ current: z26.boolean().default(false),
22829
+ projects: z26.number().int().nonnegative().optional(),
22830
+ replicas: z26.number().int().nonnegative().optional(),
22831
+ lastSyncAt: isoTime.nullable().optional(),
22832
+ lastPresenceAt: isoTime.nullable().optional()
22833
+ });
22834
+ nexusCloudOrganizationSchema = z26.object({
22835
+ id: z26.string(),
22836
+ name: z26.string(),
22837
+ slug: z26.string().nullable().optional(),
22838
+ role: z26.string().optional(),
22839
+ personal: z26.boolean().optional()
22840
+ });
22841
+ nexusCloudUserSchema = z26.object({
22842
+ id: z26.string(),
22843
+ email: z26.string(),
22844
+ name: z26.string().nullable().optional()
22845
+ });
22846
+ nexusCloudWhoamiSchema = z26.object({
22847
+ serverTime: isoTime.optional(),
22848
+ user: nexusCloudUserSchema,
22849
+ organizations: z26.array(nexusCloudOrganizationSchema).default([]),
22850
+ credential: nexusCloudCredentialSchema,
22851
+ /** The calling device; null for a session caller. */
22852
+ device: nexusCloudDeviceSchema.nullable()
22853
+ });
22854
+ nexusCloudDevicePageSchema = z26.object({
22855
+ devices: z26.array(nexusCloudDeviceSchema),
22856
+ nextCursor: z26.string().max(512).nullable().default(null),
22857
+ truncated: z26.boolean().default(false)
22858
+ });
22859
+ nexusCloudPresenceSchema = z26.looseObject({
22860
+ observedAt: isoTime.optional(),
22861
+ sync: z26.object({ enabled: z26.boolean() }).optional()
22862
+ });
22863
+ nexusCloudReplicaSchema = z26.object({
22864
+ projectId: z26.string(),
22865
+ replicaId: z26.string(),
22866
+ deviceId: z26.string(),
22867
+ deviceName: z26.string(),
22868
+ deviceState: deviceState.optional(),
22869
+ attachedAt: isoTime.optional(),
22870
+ lastSyncAt: isoTime.nullable(),
22871
+ presence: nexusCloudPresenceSchema.nullable(),
22872
+ presenceAt: isoTime.nullable()
22873
+ });
22874
+ nexusCloudDeviceCountsSchema = z26.object({
22875
+ active: z26.number().int().nonnegative(),
22876
+ total: z26.number().int().nonnegative()
22877
+ });
22878
+ projectFields = {
22879
+ projectId: z26.string(),
22880
+ label: z26.string().nullable(),
22881
+ organizationId: z26.string(),
22882
+ organizationName: z26.string().optional(),
22883
+ remoteUrl: z26.string().nullable().optional(),
22884
+ createdAt: isoTime.optional()
22885
+ };
22886
+ nexusCloudProjectListItemSchema = z26.object({
22887
+ ...projectFields,
22888
+ role: z26.string(),
22889
+ streamId: z26.string().optional(),
22890
+ headSeq: z26.number().int().nonnegative().nullable().optional(),
22891
+ openConflicts: z26.number().int().nonnegative().optional(),
22892
+ replicas: z26.array(nexusCloudReplicaSchema).default([]),
22893
+ devices: nexusCloudDeviceCountsSchema.optional(),
22894
+ replicaCount: z26.number().int().nonnegative().optional(),
22895
+ lastSyncAt: isoTime.nullable().optional(),
22896
+ lastPresenceAt: isoTime.nullable().optional(),
22897
+ /** This project's replica list was cut at 50 (T12858). */
22898
+ replicasTruncated: z26.boolean().default(false)
22899
+ });
22900
+ nexusCloudProjectPageSchema = z26.object({
22901
+ projects: z26.array(nexusCloudProjectListItemSchema),
22902
+ nextCursor: z26.string().max(512).nullable().default(null),
22903
+ /** Anything in the page was cut (the project list or a replica list). */
22904
+ truncated: z26.boolean().default(false),
22905
+ /** The project list itself was cut at 1000 (T12858). */
22906
+ projectsTruncated: z26.boolean().default(false)
22907
+ });
22908
+ nexusCloudProjectDetailSchema = z26.object({
22909
+ project: z26.object({ ...projectFields, deletedAt: isoTime.nullable().optional() }),
22910
+ role: z26.string(),
22911
+ canTrash: z26.boolean().optional(),
22912
+ openConflicts: z26.number().int().nonnegative(),
22913
+ /** At most 50, oldest attachment first. */
22914
+ replicas: z26.array(nexusCloudReplicaSchema),
22915
+ devices: nexusCloudDeviceCountsSchema,
22916
+ replicaCount: z26.number().int().nonnegative().optional(),
22917
+ lastSyncAt: isoTime.nullable().optional(),
22918
+ /** `replicas` was cut at 50. */
22919
+ truncated: z26.boolean().default(false),
22920
+ stream: z26.object({
22921
+ streamId: z26.string(),
22922
+ headSeq: z26.number().int().nonnegative(),
22923
+ headCheckpointId: z26.string().nullable()
22924
+ }).nullable()
22925
+ });
22926
+ nexusCloudReplicaPageSchema = z26.object({
22927
+ replicas: z26.array(nexusCloudReplicaSchema),
22928
+ devices: nexusCloudDeviceCountsSchema.optional(),
22929
+ nextCursor: z26.string().max(512).nullable().default(null),
22930
+ truncated: z26.boolean().default(false)
22931
+ });
22932
+ NEXUS_STATUS_CHECK_IDS = [
22933
+ "credential.valid",
22934
+ "device.registered",
22935
+ "device.active",
22936
+ "device.certified",
22937
+ "project.registered",
22938
+ "project.writable",
22939
+ "replica.attached",
22940
+ "presence.fresh",
22941
+ "replica.synced",
22942
+ "conflicts.none"
22943
+ ];
22944
+ NEXUS_STATUS_VERDICTS = ["ok", "attention", "not-linked", "not-registered"];
22945
+ CLOUD_STATUS_VERDICTS = [...NEXUS_STATUS_VERDICTS, "not-signed-in"];
22946
+ knownCheckId = z26.enum(NEXUS_STATUS_CHECK_IDS);
22947
+ nexusCloudStatusCheckSchema = z26.object({
22948
+ id: z26.enum(NEXUS_STATUS_CHECK_IDS),
22949
+ ok: z26.boolean(),
22950
+ required: z26.boolean(),
22951
+ detail: z26.string()
22952
+ });
22953
+ nexusCloudStatusSchema = z26.object({
22954
+ serverTime: isoTime.optional(),
22955
+ apiVersion: z26.string().optional(),
22956
+ user: nexusCloudUserSchema,
22957
+ credential: nexusCloudCredentialSchema,
22958
+ device: nexusCloudDeviceSchema.nullable(),
22959
+ project: z26.object({
22960
+ projectId: z26.string(),
22961
+ registered: z26.boolean(),
22962
+ organizationId: z26.string().nullable(),
22963
+ organizationName: z26.string().nullable(),
22964
+ role: z26.string().nullable()
22965
+ }).nullable(),
22966
+ replica: z26.object({
22967
+ replicaId: z26.string(),
22968
+ attached: z26.boolean(),
22969
+ attachedElsewhere: z26.boolean(),
22970
+ attachedAt: isoTime.nullable(),
22971
+ lastSyncAt: isoTime.nullable(),
22972
+ presenceAt: isoTime.nullable(),
22973
+ lastReplicaSeq: z26.number().int().nonnegative().nullable().optional()
22974
+ }).nullable(),
22975
+ stream: z26.object({
22976
+ streamId: z26.string(),
22977
+ headSeq: z26.number().int().nonnegative(),
22978
+ headCheckpointId: z26.string().nullable(),
22979
+ openConflicts: z26.number().int().nonnegative(),
22980
+ devices: nexusCloudDeviceCountsSchema
22981
+ }).nullable(),
22982
+ /** Check ids added by a newer server are dropped, never a parse failure. */
22983
+ checks: z26.array(nexusCloudStatusCheckSchema.extend({ id: z26.string() })).transform(
22984
+ (list) => list.flatMap((c) => {
22985
+ const id = knownCheckId.safeParse(c.id);
22986
+ return id.success ? [{ ...c, id: id.data }] : [];
22987
+ })
22988
+ ),
22989
+ /** A verdict added by a newer server reads as `attention`: never `ok` by accident. */
22990
+ verdict: z26.enum(NEXUS_STATUS_VERDICTS).catch("attention")
22991
+ });
22992
+ NEXUS_UNAUTHENTICATED_REASONS = [
22993
+ "missing",
22994
+ "invalid",
22995
+ "credential-revoked",
22996
+ "credential-expired",
22997
+ "device-signed-out",
22998
+ "device-revoked",
22999
+ "session-bearer-retired",
23000
+ "session-used"
23001
+ ];
23002
+ NEXUS_FORBIDDEN_REASONS = [
23003
+ "insufficient-scope",
23004
+ "session-required",
23005
+ "device-required",
23006
+ "device-mismatch",
23007
+ "not-self",
23008
+ "project-role",
23009
+ "route-undeclared",
23010
+ "bearer-session-required",
23011
+ "session-not-fresh",
23012
+ "device-limit"
23013
+ ];
23014
+ NEXUS_REVOKED_REASONS = ["signed-out", "revoked", "rotated", "reenrolled"];
23015
+ LOGIN = "run `cleo login nexus`";
23016
+ COMPROMISED = {
23017
+ code: "E_NEXUS_CREDENTIAL_COMPROMISED",
23018
+ message: "this device's credential was replaced or revoked elsewhere, possibly used from another machine",
23019
+ fix: "revoke this device on cleocode.dev and sign in again with `cleo login nexus`"
23020
+ };
23021
+ DEVICE_REVOKED = {
23022
+ code: "E_NEXUS_DEVICE_REVOKED",
23023
+ message: "this device was revoked",
23024
+ fix: "run `cleo login nexus` to enrol this machine as a new device"
23025
+ };
23026
+ SESSION_EXPIRED_LOGIN = {
23027
+ code: "E_NEXUS_SESSION_EXPIRED",
23028
+ message: "the session is too old for this request",
23029
+ fix: "run `cleo login nexus` (needs a browser: on a headless machine a human must complete the login)"
23030
+ };
23031
+ SERVER_REFUSED = {
23032
+ code: "E_NEXUS_REQUEST_FAILED",
23033
+ message: null,
23034
+ fix: null
23035
+ };
23036
+ NEXUS_REVOKED_REASON_ERRORS = {
23037
+ reenrolled: {
23038
+ code: "E_NEXUS_NOT_SIGNED_IN",
23039
+ message: "this device's credential was replaced by a newer login of the same device",
23040
+ fix: LOGIN
23041
+ },
23042
+ "signed-out": {
23043
+ code: "E_NEXUS_NOT_SIGNED_IN",
23044
+ message: "this device was signed out and later signed in again with another credential",
23045
+ fix: LOGIN
23046
+ },
23047
+ revoked: DEVICE_REVOKED,
23048
+ rotated: COMPROMISED
23049
+ };
23050
+ NEXUS_UNAUTHENTICATED_ERRORS = {
23051
+ missing: {
23052
+ code: "E_NEXUS_NOT_SIGNED_IN",
23053
+ message: "not signed in to Cleo Nexus (the credential is missing or invalid)",
23054
+ fix: LOGIN
23055
+ },
23056
+ invalid: {
23057
+ code: "E_NEXUS_NOT_SIGNED_IN",
23058
+ message: "not signed in to Cleo Nexus (the credential is missing or invalid)",
23059
+ fix: LOGIN
23060
+ },
23061
+ // Resolved by `details.revokedReason` through NEXUS_REVOKED_REASON_ERRORS.
23062
+ "credential-revoked": COMPROMISED,
23063
+ "credential-expired": {
23064
+ code: "E_NEXUS_SESSION_EXPIRED",
23065
+ message: "the device credential expired after 90 days without use",
23066
+ fix: LOGIN
23067
+ },
23068
+ "device-signed-out": {
23069
+ code: "E_NEXUS_DEVICE_SIGNED_OUT",
23070
+ message: "this device was signed out",
23071
+ fix: LOGIN
23072
+ },
23073
+ "device-revoked": DEVICE_REVOKED,
23074
+ "session-bearer-retired": {
23075
+ code: "E_NEXUS_SESSION_EXPIRED",
23076
+ message: "bearer sessions are no longer accepted",
23077
+ fix: "run `cleo login nexus` with the current CLI"
23078
+ },
23079
+ "session-used": {
23080
+ code: "E_NEXUS_SESSION_EXPIRED",
23081
+ message: "the 9.24 session was already used by another enrolment",
23082
+ fix: LOGIN
23083
+ }
23084
+ };
23085
+ NEXUS_FORBIDDEN_ERRORS = {
23086
+ "insufficient-scope": {
23087
+ code: "E_NEXUS_INSUFFICIENT_SCOPE",
23088
+ message: "this device's credential lacks the scope for that request",
23089
+ fix: "run `cleo login nexus` without --read-only to enrol with the full device profile"
23090
+ },
23091
+ "session-required": SERVER_REFUSED,
23092
+ "device-required": SERVER_REFUSED,
23093
+ "device-mismatch": SERVER_REFUSED,
23094
+ "not-self": SERVER_REFUSED,
23095
+ "project-role": SERVER_REFUSED,
23096
+ "route-undeclared": SERVER_REFUSED,
23097
+ "bearer-session-required": SESSION_EXPIRED_LOGIN,
23098
+ "session-not-fresh": SESSION_EXPIRED_LOGIN,
23099
+ "device-limit": {
23100
+ code: "E_NEXUS_REQUEST_FAILED",
23101
+ message: "the account has reached its device limit",
23102
+ fix: "revoke unused devices on cleocode.dev, then retry"
23103
+ }
23104
+ };
23105
+ NEXUS_CONFLICT_ERRORS = {
23106
+ "replica-copied": {
23107
+ code: "E_NEXUS_REPLICA_COPIED",
23108
+ message: "this project store is attached from another device (a copied store)",
23109
+ fix: null
23110
+ },
23111
+ "rotation-conflict": COMPROMISED
23112
+ };
23113
+ NEXUS_UNREACHABLE_ERROR = {
23114
+ code: "E_NEXUS_UNREACHABLE",
23115
+ message: null,
23116
+ fix: "check your network and retry"
23117
+ };
23118
+ }
23119
+ });
23120
+
22753
23121
  // packages/contracts/src/task-id.ts
22754
23122
  function isTaskId(value) {
22755
23123
  return typeof value === "string" && TASK_ID_REGEX.test(value);
@@ -22817,6 +23185,7 @@ __export(src_exports, {
22817
23185
  CHANNEL_BOUNDARY_REGISTRY: () => CHANNEL_BOUNDARY_REGISTRY,
22818
23186
  CLEO_CONFIG_MANIFEST: () => CLEO_CONFIG_MANIFEST,
22819
23187
  CLI_CATEGORY_ORDER: () => CLI_CATEGORY_ORDER,
23188
+ CLOUD_STATUS_VERDICTS: () => CLOUD_STATUS_VERDICTS,
22820
23189
  COLLECTION_IDENTITY_FIELDS: () => COLLECTION_IDENTITY_FIELDS,
22821
23190
  COLLECTION_KEYS: () => COLLECTION_KEYS,
22822
23191
  CONFIG_MANIFEST_ENTRIES: () => CONFIG_MANIFEST_ENTRIES,
@@ -22931,10 +23300,27 @@ __export(src_exports, {
22931
23300
  MonitorResponseSchema: () => MonitorResponseSchema,
22932
23301
  NEXUS_ACCOUNT_ERROR_CODES: () => NEXUS_ACCOUNT_ERROR_CODES,
22933
23302
  NEXUS_CLI_CLIENT_ID: () => NEXUS_CLI_CLIENT_ID,
23303
+ NEXUS_CLOUD_MAX_PAGES: () => NEXUS_CLOUD_MAX_PAGES,
23304
+ NEXUS_CLOUD_PROFILES: () => NEXUS_CLOUD_PROFILES,
23305
+ NEXUS_CONFLICT_ERRORS: () => NEXUS_CONFLICT_ERRORS,
22934
23306
  NEXUS_DEFAULT_API_URL: () => NEXUS_DEFAULT_API_URL,
23307
+ NEXUS_DEVICE_LIST_STATES: () => NEXUS_DEVICE_LIST_STATES,
23308
+ NEXUS_DEVICE_STATES: () => NEXUS_DEVICE_STATES,
23309
+ NEXUS_DEVICE_STATE_UNKNOWN: () => NEXUS_DEVICE_STATE_UNKNOWN,
22935
23310
  NEXUS_FLEET_SCHEMA_VERSION: () => NEXUS_FLEET_SCHEMA_VERSION,
23311
+ NEXUS_FORBIDDEN_ERRORS: () => NEXUS_FORBIDDEN_ERRORS,
23312
+ NEXUS_FORBIDDEN_REASONS: () => NEXUS_FORBIDDEN_REASONS,
22936
23313
  NEXUS_LOGIN_TARGET: () => NEXUS_LOGIN_TARGET,
23314
+ NEXUS_PAGE_LIMIT_MAX: () => NEXUS_PAGE_LIMIT_MAX,
23315
+ NEXUS_PRESENCE_FRESH_SECONDS: () => NEXUS_PRESENCE_FRESH_SECONDS,
23316
+ NEXUS_REVOKED_REASONS: () => NEXUS_REVOKED_REASONS,
23317
+ NEXUS_REVOKED_REASON_ERRORS: () => NEXUS_REVOKED_REASON_ERRORS,
22937
23318
  NEXUS_SCOPE_MAP: () => NEXUS_SCOPE_MAP,
23319
+ NEXUS_STATUS_CHECK_IDS: () => NEXUS_STATUS_CHECK_IDS,
23320
+ NEXUS_STATUS_VERDICTS: () => NEXUS_STATUS_VERDICTS,
23321
+ NEXUS_UNAUTHENTICATED_ERRORS: () => NEXUS_UNAUTHENTICATED_ERRORS,
23322
+ NEXUS_UNAUTHENTICATED_REASONS: () => NEXUS_UNAUTHENTICATED_REASONS,
23323
+ NEXUS_UNREACHABLE_ERROR: () => NEXUS_UNREACHABLE_ERROR,
22938
23324
  OPEN_SYSTEM_KEY_PREFIXES: () => OPEN_SYSTEM_KEY_PREFIXES,
22939
23325
  OPERATIONS: () => OPERATIONS,
22940
23326
  OPERATION_RESULT_SCHEMAS: () => OPERATION_RESULT_SCHEMAS,
@@ -23214,6 +23600,21 @@ __export(src_exports, {
23214
23600
  nexusAccountMeSchema: () => nexusAccountMeSchema,
23215
23601
  nexusAccountOrganizationSchema: () => nexusAccountOrganizationSchema,
23216
23602
  nexusAccountUserSchema: () => nexusAccountUserSchema,
23603
+ nexusCloudCredentialSchema: () => nexusCloudCredentialSchema,
23604
+ nexusCloudDeviceCountsSchema: () => nexusCloudDeviceCountsSchema,
23605
+ nexusCloudDevicePageSchema: () => nexusCloudDevicePageSchema,
23606
+ nexusCloudDeviceSchema: () => nexusCloudDeviceSchema,
23607
+ nexusCloudOrganizationSchema: () => nexusCloudOrganizationSchema,
23608
+ nexusCloudPresenceSchema: () => nexusCloudPresenceSchema,
23609
+ nexusCloudProjectDetailSchema: () => nexusCloudProjectDetailSchema,
23610
+ nexusCloudProjectListItemSchema: () => nexusCloudProjectListItemSchema,
23611
+ nexusCloudProjectPageSchema: () => nexusCloudProjectPageSchema,
23612
+ nexusCloudReplicaPageSchema: () => nexusCloudReplicaPageSchema,
23613
+ nexusCloudReplicaSchema: () => nexusCloudReplicaSchema,
23614
+ nexusCloudStatusCheckSchema: () => nexusCloudStatusCheckSchema,
23615
+ nexusCloudStatusSchema: () => nexusCloudStatusSchema,
23616
+ nexusCloudUserSchema: () => nexusCloudUserSchema,
23617
+ nexusCloudWhoamiSchema: () => nexusCloudWhoamiSchema,
23217
23618
  normalizeError: () => normalizeError,
23218
23619
  noteAtomSchema: () => noteAtomSchema,
23219
23620
  noulDecisionAnswerSchema: () => noulDecisionAnswerSchema,
@@ -23394,6 +23795,7 @@ var init_src2 = __esm({
23394
23795
  init_decide();
23395
23796
  init_decide_sites();
23396
23797
  init_nexus_account();
23798
+ init_nexus_cloud();
23397
23799
  init_task_id();
23398
23800
  }
23399
23801
  });
@@ -36321,7 +36723,7 @@ function parseAgenticNode(raw, base, index) {
36321
36723
  inputs = acc;
36322
36724
  }
36323
36725
  const context_files = parseStringArray(raw.context_files, `nodes[${index}].context_files`);
36324
- const profile = parseOptionalNonEmptyString(raw.profile, `nodes[${index}].profile`);
36726
+ const profile2 = parseOptionalNonEmptyString(raw.profile, `nodes[${index}].profile`);
36325
36727
  const model = parseOptionalNonEmptyString(raw.model, `nodes[${index}].model`);
36326
36728
  const provider = parseOptionalNonEmptyString(raw.provider, `nodes[${index}].provider`);
36327
36729
  const allowed_skills = parseStringArray(raw.allowed_skills, `nodes[${index}].allowed_skills`);
@@ -36334,7 +36736,7 @@ function parseAgenticNode(raw, base, index) {
36334
36736
  role,
36335
36737
  inputs,
36336
36738
  ...context_files !== void 0 ? { context_files } : {},
36337
- ...profile !== void 0 ? { profile } : {},
36739
+ ...profile2 !== void 0 ? { profile: profile2 } : {},
36338
36740
  ...model !== void 0 ? { model } : {},
36339
36741
  ...provider !== void 0 ? { provider } : {},
36340
36742
  ...allowed_skills !== void 0 ? { allowed_skills } : {},
@@ -37997,8 +38399,8 @@ async function loadPlaybookByName(name) {
37997
38399
  return null;
37998
38400
  }
37999
38401
  try {
38000
- const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/internal");
38001
- const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot74();
38402
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/internal");
38403
+ const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot75();
38002
38404
  const resolved = resolvePlaybook(name, {
38003
38405
  projectRoot,
38004
38406
  globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
@@ -38043,7 +38445,7 @@ async function buildDefaultDispatcher() {
38043
38445
  if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
38044
38446
  const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await import("@cleocode/runtime/gateway");
38045
38447
  const {
38046
- getProjectRoot: getProjectRoot74,
38448
+ getProjectRoot: getProjectRoot75,
38047
38449
  createToolGuard,
38048
38450
  runSkillNodeOrSpawn,
38049
38451
  maybeCreatePiRunner,
@@ -38051,7 +38453,7 @@ async function buildDefaultDispatcher() {
38051
38453
  hasCantbookProfilePin,
38052
38454
  DEFAULT_DETERMINISTIC_DENIED_COMMANDS
38053
38455
  } = await import("@cleocode/core/internal");
38054
- const projectRoot = getProjectRoot74();
38456
+ const projectRoot = getProjectRoot75();
38055
38457
  const tools = createToolGuard({
38056
38458
  allowedRoots: [projectRoot],
38057
38459
  deniedCommands: DEFAULT_DETERMINISTIC_DENIED_COMMANDS,
@@ -38144,12 +38546,12 @@ async function buildDefaultDeterministicRunner() {
38144
38546
  return void 0;
38145
38547
  }
38146
38548
  const {
38147
- getProjectRoot: getProjectRoot74,
38549
+ getProjectRoot: getProjectRoot75,
38148
38550
  createToolGuard,
38149
38551
  createGuardedDeterministicRunner,
38150
38552
  DEFAULT_DETERMINISTIC_DENIED_COMMANDS
38151
38553
  } = await import("@cleocode/core/internal");
38152
- const projectRoot = getProjectRoot74();
38554
+ const projectRoot = getProjectRoot75();
38153
38555
  const tools = createToolGuard({
38154
38556
  allowedRoots: [projectRoot],
38155
38557
  deniedCommands: DEFAULT_DETERMINISTIC_DENIED_COMMANDS,
@@ -38307,8 +38709,8 @@ var init_playbook2 = __esm({
38307
38709
  projectRoot = __playbookRuntimeOverrides.projectRoot;
38308
38710
  } else {
38309
38711
  try {
38310
- const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/internal");
38311
- projectRoot = getProjectRoot74();
38712
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/internal");
38713
+ projectRoot = getProjectRoot75();
38312
38714
  } catch {
38313
38715
  projectRoot = void 0;
38314
38716
  }
@@ -38373,14 +38775,14 @@ var init_playbook2 = __esm({
38373
38775
  const deterministicRunner = await buildDefaultDeterministicRunner();
38374
38776
  let result;
38375
38777
  try {
38376
- const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/internal");
38778
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/internal");
38377
38779
  const opts = {
38378
38780
  db,
38379
38781
  playbook: parsed.definition,
38380
38782
  playbookHash: parsed.sourceHash,
38381
38783
  initialContext,
38382
38784
  dispatcher,
38383
- projectRoot: getProjectRoot74()
38785
+ projectRoot: getProjectRoot75()
38384
38786
  };
38385
38787
  if (deterministicRunner !== void 0) opts.deterministicRunner = deterministicRunner;
38386
38788
  if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
@@ -38739,6 +39141,7 @@ async function orchestratePivotOp(params) {
38739
39141
  else if (code === 38) errorCode = "E_NOT_ACTIVE";
38740
39142
  else if (code === 35) errorCode = "E_TASK_CLAIMED";
38741
39143
  else if (code === 24) errorCode = "E_SESSION_UNBOUND";
39144
+ else if (code === 26) errorCode = "E_TASK_RENAMED";
38742
39145
  const cleo = err instanceof CleoError ? err : void 0;
38743
39146
  return {
38744
39147
  success: false,
@@ -45718,11 +46121,11 @@ var init_security = __esm({
45718
46121
  });
45719
46122
 
45720
46123
  // packages/cleo/src/dispatch/middleware/sanitizer.ts
45721
- function createSanitizer(getProjectRoot74) {
46124
+ function createSanitizer(getProjectRoot75) {
45722
46125
  return async (req, next) => {
45723
46126
  if (req.params) {
45724
46127
  try {
45725
- const root = getProjectRoot74 ? getProjectRoot74() : void 0;
46128
+ const root = getProjectRoot75 ? getProjectRoot75() : void 0;
45726
46129
  req.params = sanitizeParams(req.params, root, {
45727
46130
  domain: req.domain,
45728
46131
  operation: req.operation
@@ -45824,14 +46227,14 @@ var init_session_resolver = __esm({
45824
46227
  });
45825
46228
 
45826
46229
  // packages/cleo/src/dispatch/middleware/store-write-guard.ts
45827
- function createStoreWriteGuard(getProjectRoot74) {
46230
+ function createStoreWriteGuard(getProjectRoot75) {
45828
46231
  return async (req, next) => {
45829
46232
  if (req.gateway !== "mutate" || ALLOWED_WHILE_READ_ONLY.has(`${req.domain}.${req.operation}`)) {
45830
46233
  return next();
45831
46234
  }
45832
46235
  let projectRoot;
45833
46236
  try {
45834
- projectRoot = getProjectRoot74();
46237
+ projectRoot = getProjectRoot75();
45835
46238
  } catch {
45836
46239
  return next();
45837
46240
  }
@@ -46258,6 +46661,7 @@ var init_cli = __esm({
46258
46661
  E_CONFLICT: 23,
46259
46662
  E_SESSION_UNBOUND: 24,
46260
46663
  E_WORKTREE_LOCKED: 25,
46664
+ E_TASK_RENAMED: 26,
46261
46665
  E_TWIN_COLLAPSE_FAILED: 55,
46262
46666
  E_SESSION_EXISTS: 30,
46263
46667
  E_SESSION_NOT_FOUND: 31,
@@ -47576,8 +47980,8 @@ var init_agent_outputs = __esm({
47576
47980
  });
47577
47981
 
47578
47982
  // packages/cleo/src/cli/commands/agent-profile-status.ts
47579
- function computeProfileStatus(profile, validation) {
47580
- if (profile === null) return "none";
47983
+ function computeProfileStatus(profile2, validation) {
47984
+ if (profile2 === null) return "none";
47581
47985
  if (validation === null) return "loaded (unvalidated)";
47582
47986
  if (validation.valid) return "validated";
47583
47987
  return `invalid (${validation.errors.length} errors)`;
@@ -47882,16 +48286,16 @@ agent ${agentId}:
47882
48286
  process.exitCode = 1;
47883
48287
  return;
47884
48288
  }
47885
- let profile = null;
48289
+ let profile2 = null;
47886
48290
  let cantValidation = null;
47887
48291
  const cantPath = args.cant ?? join40(CLEO_DIR_NAME3, AGENTS_SUBDIR, `${args.agentId}.cant`);
47888
48292
  if (existsSync22(cantPath)) {
47889
- profile = readFileSync22(cantPath, "utf-8");
48293
+ profile2 = readFileSync22(cantPath, "utf-8");
47890
48294
  try {
47891
48295
  const cantModule = await import("@cleocode/cant");
47892
48296
  const validate = "validate" in cantModule ? cantModule.validate : null;
47893
48297
  if (validate) {
47894
- const result = validate(profile);
48298
+ const result = validate(profile2);
47895
48299
  cantValidation = {
47896
48300
  valid: result.valid,
47897
48301
  errors: result.diagnostics?.map((d) => d.message) ?? []
@@ -47934,7 +48338,7 @@ agent ${agentId}:
47934
48338
  transport: runtime.transport.name,
47935
48339
  // Surfaced for operator visibility only — see
47936
48340
  // computeProfileStatus tsdoc for the four possible values.
47937
- profile: computeProfileStatus(profile, cantValidation),
48341
+ profile: computeProfileStatus(profile2, cantValidation),
47938
48342
  services: {
47939
48343
  poller: "running",
47940
48344
  heartbeat: runtime.heartbeat ? "running" : "disabled",
@@ -50613,15 +51017,24 @@ function nexusApiUrlArg(args) {
50613
51017
  function failNexus(err, operation) {
50614
51018
  const code = err instanceof Error && "code" in err && typeof err.code === "string" ? err.code : void 0;
50615
51019
  const fix = err instanceof Error && "fix" in err && typeof err.fix === "string" ? err.fix : void 0;
50616
- const exitCode = code === "E_NEXUS_INVALID_API_URL" || code === "E_NEXUS_INVALID_LABEL" ? 6 : 1;
51020
+ const exitCode = code === "E_NEXUS_INVALID_API_URL" || code === "E_NEXUS_INVALID_LABEL" || code === "E_NEXUS_DEVICE_REQUIRED" || code === "E_VALIDATION" ? 6 : 1;
51021
+ const details = err instanceof Error && "publicDetails" in err && typeof err.publicDetails === "object" && err.publicDetails ? err.publicDetails : void 0;
50617
51022
  cliError(
50618
51023
  err instanceof Error ? err.message : String(err),
50619
51024
  exitCode,
50620
- { name: code ?? "E_NEXUS_REQUEST_FAILED", ...fix ? { fix } : {} },
51025
+ {
51026
+ name: code ?? "E_NEXUS_REQUEST_FAILED",
51027
+ ...fix ? { fix } : {},
51028
+ ...details ? { details } : {}
51029
+ },
50621
51030
  { operation }
50622
51031
  );
50623
51032
  process.exit(exitCode);
50624
51033
  }
51034
+ function writeNexusWarnings(warnings) {
51035
+ for (const warning of warnings) process.stderr.write(`warning: ${warning}
51036
+ `);
51037
+ }
50625
51038
  function emitNexusResult(data, summary, command, operation) {
50626
51039
  if (isHumanOutput()) humanLine(summary);
50627
51040
  else cliOutput(data, { command, operation });
@@ -50631,17 +51044,65 @@ async function runNexusLogin(args, openBrowser2) {
50631
51044
  /* webpackIgnore: true */
50632
51045
  "@cleocode/core/cloud/nexus-auth.js"
50633
51046
  );
51047
+ const { isNexusDeviceEnabled } = await import(
51048
+ /* webpackIgnore: true */
51049
+ "@cleocode/core/cloud/nexus-device.js"
51050
+ );
50634
51051
  const noBrowser = negatedFlag(args, "browser");
51052
+ let codeShown = false;
51053
+ const hooks2 = {
51054
+ apiUrl: nexusApiUrlArg(args),
51055
+ onCode: (code) => {
51056
+ codeShown = true;
51057
+ writeDeviceCodePrompt(code, SERVICE_NAME);
51058
+ if (!noBrowser) openBrowser2(code.verificationUriComplete ?? code.verificationUri);
51059
+ },
51060
+ onPending: writeDeviceCodePending
51061
+ };
51062
+ const readOnly = args["read-only"] === true;
51063
+ const name = typeof args["name"] === "string" && args["name"] !== "" ? args["name"] : void 0;
51064
+ if (readOnly && !isNexusDeviceEnabled()) {
51065
+ throw Object.assign(
51066
+ new Error(
51067
+ "--read-only needs device credentials, which are not enabled; nothing was signed in"
51068
+ ),
51069
+ {
51070
+ code: "E_NEXUS_DEVICE_REQUIRED",
51071
+ fix: "unset CLEO_NEXUS_DEVICE (=0 turns device credentials off) to enrol a read-only device, or log in without --read-only"
51072
+ }
51073
+ );
51074
+ }
50635
51075
  try {
50636
- const result = await loginToNexus({
50637
- apiUrl: nexusApiUrlArg(args),
50638
- onCode: (code) => {
50639
- writeDeviceCodePrompt(code, SERVICE_NAME);
50640
- if (!noBrowser) openBrowser2(code.verificationUriComplete ?? code.verificationUri);
50641
- },
50642
- onPending: writeDeviceCodePending
50643
- });
50644
- writeDeviceCodeApproved(SERVICE_NAME);
51076
+ let result;
51077
+ if (isNexusDeviceEnabled()) {
51078
+ const { loginToNexusDevice } = await import(
51079
+ /* webpackIgnore: true */
51080
+ "@cleocode/core/cloud/nexus-enrol.js"
51081
+ );
51082
+ result = await loginToNexusDevice({
51083
+ ...hooks2,
51084
+ readOnly,
51085
+ ...name !== void 0 ? { name } : {}
51086
+ });
51087
+ } else {
51088
+ if (name !== void 0) {
51089
+ process.stderr.write(
51090
+ "warning: --name needs device credentials, which CLEO_NEXUS_DEVICE=0 turns off; ignored\n"
51091
+ );
51092
+ }
51093
+ const { NEXUS_TEST_BEARER_ENV, W_NEXUS_TEST_BEARER_IGNORED } = await import(
51094
+ /* webpackIgnore: true */
51095
+ "@cleocode/core/cloud/nexus-enrol.js"
51096
+ );
51097
+ if ((process.env[NEXUS_TEST_BEARER_ENV]?.trim() ?? "") !== "") {
51098
+ process.stderr.write(
51099
+ `warning: ${W_NEXUS_TEST_BEARER_IGNORED}: ${NEXUS_TEST_BEARER_ENV} needs device credentials, which CLEO_NEXUS_DEVICE turns off; ignored
51100
+ `
51101
+ );
51102
+ }
51103
+ result = await loginToNexus(hooks2);
51104
+ }
51105
+ if (codeShown) writeDeviceCodeApproved(SERVICE_NAME);
50645
51106
  for (const warning of result.warnings) process.stderr.write(`warning: ${warning}
50646
51107
  `);
50647
51108
  return result;
@@ -50653,7 +51114,43 @@ async function runNexusLogin(args, openBrowser2) {
50653
51114
  function nexusLoginSummary(r) {
50654
51115
  const who = r.user?.email ?? "your account";
50655
51116
  const org = r.organization ? ` (${r.organization.name})` : "";
50656
- return `Signed in to ${r.apiUrl} as ${who}${org}.`;
51117
+ const device = r.device ? ` This machine is device ${r.device.deviceId}${r.device.name ? ` (${r.device.name})` : ""}, profile ${r.device.profile ?? "unknown"}.` : "";
51118
+ return `Signed in to ${r.apiUrl} as ${who}${org}.${device}`;
51119
+ }
51120
+ function nexusDeviceLogoutSummary(r) {
51121
+ const count = (o) => r.devices.filter((d) => d.outcome === o).length;
51122
+ const confirmed = count("confirmed");
51123
+ const open2 = r.devices.length - confirmed;
51124
+ const what = r.action === "revoke" ? "Revoke" : "Sign-out";
51125
+ if (r.devices.length === 0 && r.session === null) {
51126
+ return r.warnings.length > 0 ? `${what} on ${r.apiUrl}: nothing was sent (see warnings).` : `Not signed in to ${r.apiUrl}; nothing to do.`;
51127
+ }
51128
+ const parts = [];
51129
+ if (r.devices.length > 0)
51130
+ parts.push(`${confirmed} of ${r.devices.length} device request(s) confirmed`);
51131
+ if (open2 > 0) parts.push(`${open2} NOT confirmed (see warnings)`);
51132
+ if (r.session !== null) parts.push(`9.24 session ${r.session.revocation}`);
51133
+ const notConfirmed = open2 > 0 || r.devices.length > 0 && confirmed === 0 || r.session?.revocation === "failed";
51134
+ const lead = notConfirmed ? `${what} NOT fully confirmed on` : `${what} confirmed on`;
51135
+ return `${lead} ${r.apiUrl}: ${parts.join("; ")}.`;
51136
+ }
51137
+ async function runNexusDeviceLogout(args) {
51138
+ let result;
51139
+ try {
51140
+ const { logoutNexusDevice } = await import(
51141
+ /* webpackIgnore: true */
51142
+ "@cleocode/core/cloud/nexus-logout.js"
51143
+ );
51144
+ result = await logoutNexusDevice({
51145
+ apiUrl: nexusApiUrlArg(args),
51146
+ revoke: args["revoke"] === true
51147
+ });
51148
+ } catch (err) {
51149
+ failNexus(err, "logout.run");
51150
+ }
51151
+ for (const warning of result.warnings) process.stderr.write(`warning: ${warning}
51152
+ `);
51153
+ emitNexusResult(result, nexusDeviceLogoutSummary(result), "logout", "logout.run");
50657
51154
  }
50658
51155
  var SERVICE_NAME, NEXUS_API_URL_ARG;
50659
51156
  var init_nexus_account_cli = __esm({
@@ -51000,13 +51497,13 @@ function _errorResult(code, message, meta) {
51000
51497
  }
51001
51498
  async function runLlmLogin(provider, opts) {
51002
51499
  const meta = { operation: "llm.login", timestamp: (/* @__PURE__ */ new Date()).toISOString() };
51003
- const profile = await getProviderProfile(provider);
51004
- const oauthMode = profile?.oauth?.mode;
51500
+ const profile2 = await getProviderProfile(provider);
51501
+ const oauthMode = profile2?.oauth?.mode;
51005
51502
  if (provider === "kimi-code" || oauthMode === "device-code") {
51006
51503
  return _runKimiCodeLogin(opts, meta);
51007
51504
  }
51008
51505
  if (oauthMode === "pkce") {
51009
- return _runPkceLogin(profile.name, profile.oauth, opts, meta);
51506
+ return _runPkceLogin(profile2.name, profile2.oauth, opts, meta);
51010
51507
  }
51011
51508
  return _errorResult(
51012
51509
  "E_NOT_IMPLEMENTED",
@@ -51542,6 +52039,14 @@ var init_login = __esm({
51542
52039
  description: "Open the verification URL in a browser (nexus). --no-browser only prints it (SSH, containers).",
51543
52040
  default: true
51544
52041
  },
52042
+ "read-only": {
52043
+ type: "boolean",
52044
+ description: "nexus: enrol this machine with the read-only device profile (account, devices and project reads only). Refused with CLEO_NEXUS_DEVICE=0."
52045
+ },
52046
+ name: {
52047
+ type: "string",
52048
+ description: "nexus: device name shown on cleocode.dev (default: OS, arch and a short id; never the hostname). Ignored with CLEO_NEXUS_DEVICE=0."
52049
+ },
51545
52050
  auth: {
51546
52051
  type: "string",
51547
52052
  description: "Auth method: 'oauth' (browser) or 'api_key'. Inferred from the provider when omitted."
@@ -52846,14 +53351,14 @@ var init_backup = __esm({
52846
53351
  return;
52847
53352
  }
52848
53353
  const { exportPortableBundle, PortableBundleError } = await import("@cleocode/core/store/portable-bundle.js");
52849
- const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
53354
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
52850
53355
  const passphrase = args.encrypt === true ? await resolvePassphrase() : void 0;
52851
53356
  if (args.encrypt === true && passphrase === void 0) return;
52852
53357
  const encSuffix = args.encrypt === true ? "enc." : "";
52853
53358
  try {
52854
53359
  const result = await exportPortableBundle({
52855
53360
  scope,
52856
- projectRoot: scope === "project" || scope === "all" ? getProjectRoot74() : void 0,
53361
+ projectRoot: scope === "project" || scope === "all" ? getProjectRoot75() : void 0,
52857
53362
  outputPath: args.out ?? `./${args.name}.${encSuffix}cleobundle.tar.gz`,
52858
53363
  encrypt: args.encrypt === true,
52859
53364
  passphrase,
@@ -52910,12 +53415,12 @@ var init_backup = __esm({
52910
53415
  );
52911
53416
  return;
52912
53417
  }
52913
- const { getProjectRoot: getProjectRoot74, getCleoHome: getCleoHome8, getCleoVersion } = await import("@cleocode/core");
53418
+ const { getProjectRoot: getProjectRoot75, getCleoHome: getCleoHome8, getCleoVersion } = await import("@cleocode/core");
52914
53419
  const { BundleError, cleanupStaging, unpackBundle } = await import("@cleocode/core/store/backup-unpack.js");
52915
53420
  const { regenerateConfigJson, regenerateProjectContextJson, regenerateProjectInfoJson } = await import("@cleocode/core/store/regenerators.js");
52916
53421
  const { regenerateAndCompare } = await import("@cleocode/core/store/restore-json-merge.js");
52917
53422
  const { buildConflictReport, writeConflictReport } = await import("@cleocode/core/store/restore-conflict-report.js");
52918
- const projectRoot = getProjectRoot74();
53423
+ const projectRoot = getProjectRoot75();
52919
53424
  const { assertOwnerStoreRewriteConfirmed } = await import("@cleocode/core/store/worktree-isolation-guard.js");
52920
53425
  try {
52921
53426
  assertOwnerStoreRewriteConfirmed("backup import", path2.join(projectRoot, ".cleo"), {
@@ -55560,6 +56065,252 @@ var init_classify = __esm({
55560
56065
  }
55561
56066
  });
55562
56067
 
56068
+ // packages/cleo/src/cli/lib/nexus-cloud-cli.ts
56069
+ function stringArg(args, name) {
56070
+ const raw = args[name];
56071
+ return typeof raw === "string" && raw !== "" ? raw : void 0;
56072
+ }
56073
+ function writeWarnings(warnings) {
56074
+ for (const w of warnings) process.stderr.write(`warning: ${w.message} (${w.code})
56075
+ `);
56076
+ }
56077
+ function deviceStateArg(args) {
56078
+ const raw = stringArg(args, "state");
56079
+ if (raw === void 0) return void 0;
56080
+ const known = NEXUS_DEVICE_LIST_STATES.find((s) => s === raw);
56081
+ if (known !== void 0) return known;
56082
+ throw Object.assign(new Error(`unknown --state '${raw}'`), {
56083
+ code: "E_VALIDATION",
56084
+ fix: `use one of: ${NEXUS_DEVICE_LIST_STATES.join(", ")}`
56085
+ });
56086
+ }
56087
+ function cloudStatusSummary(r) {
56088
+ if (r.verdict === "not-signed-in") {
56089
+ return `Cloud status: not signed in to ${r.local.apiUrl}. Run \`cleo login nexus\`.`;
56090
+ }
56091
+ const s = r.summary;
56092
+ const parts = [`device ${r.local.nexusDeviceId ?? "unknown"} (${s.profile ?? "no profile"})`];
56093
+ if (r.local.projectId !== null) {
56094
+ parts.push(`project ${r.local.projectId} ${s.linked ? "linked" : "NOT linked"}`);
56095
+ parts.push(s.replicaAttached ? "replica attached" : "replica NOT attached");
56096
+ parts.push(`${s.devices} device(s)`);
56097
+ if (s.headSeq !== null) parts.push(`head ${s.headSeq}`);
56098
+ if (s.openConflicts !== null) parts.push(`${s.openConflicts} open conflict(s)`);
56099
+ }
56100
+ return `Cloud status: ${r.verdict}. ${parts.join("; ")}.`;
56101
+ }
56102
+ async function runCloudRead(operation, call, summary) {
56103
+ let result;
56104
+ try {
56105
+ result = await call();
56106
+ } catch (err) {
56107
+ const { NexusCloudOfflineError } = await import(
56108
+ /* webpackIgnore: true */
56109
+ "@cleocode/core/cloud/nexus-cloud-status.js"
56110
+ );
56111
+ if (err instanceof NexusCloudOfflineError) writeWarnings(err.publicDetails.warnings);
56112
+ failNexus(err, operation);
56113
+ }
56114
+ writeWarnings(result.warnings);
56115
+ emitNexusResult(result, summary(result), "cloud", operation);
56116
+ }
56117
+ async function runCloudStatus(args) {
56118
+ await runCloudRead(
56119
+ "cloud.status",
56120
+ async () => {
56121
+ const { getNexusCloudStatus } = await import(
56122
+ /* webpackIgnore: true */
56123
+ "@cleocode/core/cloud/nexus-cloud-status.js"
56124
+ );
56125
+ const projectId = stringArg(args, "project");
56126
+ return getNexusCloudStatus({
56127
+ apiUrl: nexusApiUrlArg(args),
56128
+ ...projectId !== void 0 ? { projectId } : {}
56129
+ });
56130
+ },
56131
+ cloudStatusSummary
56132
+ );
56133
+ }
56134
+ async function runCloudWhoami(args) {
56135
+ await runCloudRead(
56136
+ "cloud.whoami",
56137
+ async () => {
56138
+ const { nexusCloudWhoami } = await import(
56139
+ /* webpackIgnore: true */
56140
+ "@cleocode/core/cloud/nexus-cloud.js"
56141
+ );
56142
+ return nexusCloudWhoami({ apiUrl: nexusApiUrlArg(args) });
56143
+ },
56144
+ (r) => `Signed in to ${r.apiUrl} as ${r.user.email} with a ${r.credential.kind} credential${r.device ? ` (device ${r.device.deviceId}, profile ${r.credential.profile ?? "none"})` : ""}.`
56145
+ );
56146
+ }
56147
+ async function runCloudDevices(args) {
56148
+ await runCloudRead(
56149
+ "cloud.devices.list",
56150
+ async () => {
56151
+ const state = deviceStateArg(args);
56152
+ const { listNexusCloudDevices } = await import(
56153
+ /* webpackIgnore: true */
56154
+ "@cleocode/core/cloud/nexus-cloud.js"
56155
+ );
56156
+ return listNexusCloudDevices({
56157
+ apiUrl: nexusApiUrlArg(args),
56158
+ ...state !== void 0 ? { state } : {}
56159
+ });
56160
+ },
56161
+ (r) => `${r.count} device(s) on ${r.apiUrl}${r.state ? ` (state ${r.state})` : ""}: ${r.devices.map((d) => `${d.name} ${d.deviceId} ${d.state}${d.current ? " (this machine)" : ""}`).join("; ")}`
56162
+ );
56163
+ }
56164
+ async function runCloudProjects(args) {
56165
+ const action = stringArg(args, "action");
56166
+ if (action === "show") {
56167
+ await runCloudRead(
56168
+ "cloud.projects.show",
56169
+ async () => {
56170
+ const projectId = stringArg(args, "id");
56171
+ const { showNexusCloudProject } = await import(
56172
+ /* webpackIgnore: true */
56173
+ "@cleocode/core/cloud/nexus-cloud.js"
56174
+ );
56175
+ return showNexusCloudProject({
56176
+ apiUrl: nexusApiUrlArg(args),
56177
+ ...projectId !== void 0 ? { projectId } : {}
56178
+ });
56179
+ },
56180
+ (r) => `Project ${r.projectId} "${r.project.label ?? ""}" (${r.role}): ${r.devices.active} active device(s), ${r.replicas.length} replica(s), head ${r.stream?.headSeq ?? "none"}, ${r.openConflicts} open conflict(s).`
56181
+ );
56182
+ return;
56183
+ }
56184
+ if (action !== void 0 && action !== "list") {
56185
+ failNexus(
56186
+ Object.assign(new Error(`unknown action '${action}'`), {
56187
+ code: "E_VALIDATION",
56188
+ fix: "use `cleo cloud projects` or `cleo cloud projects show [<id>]`"
56189
+ }),
56190
+ "cloud.projects.list"
56191
+ );
56192
+ }
56193
+ await runCloudRead(
56194
+ "cloud.projects.list",
56195
+ async () => {
56196
+ const organizationId = stringArg(args, "org");
56197
+ const { listNexusCloudProjects } = await import(
56198
+ /* webpackIgnore: true */
56199
+ "@cleocode/core/cloud/nexus-cloud.js"
56200
+ );
56201
+ return listNexusCloudProjects({
56202
+ apiUrl: nexusApiUrlArg(args),
56203
+ ...organizationId !== void 0 ? { organizationId } : {}
56204
+ });
56205
+ },
56206
+ (r) => `${r.count} project(s) on ${r.apiUrl}: ${r.projects.map((p) => `${p.label ?? p.projectId} (${p.role})`).join("; ")}`
56207
+ );
56208
+ }
56209
+ var init_nexus_cloud_cli = __esm({
56210
+ "packages/cleo/src/cli/lib/nexus-cloud-cli.ts"() {
56211
+ "use strict";
56212
+ init_src2();
56213
+ init_nexus_account_cli();
56214
+ }
56215
+ });
56216
+
56217
+ // packages/cleo/src/cli/commands/cloud.ts
56218
+ var cloud_exports = {};
56219
+ __export(cloud_exports, {
56220
+ cloudCommand: () => cloudCommand
56221
+ });
56222
+ var JSON_ARG, statusSubCommand, whoamiSubCommand, devicesSubCommand, projectsSubCommand, cloudCommand;
56223
+ var init_cloud = __esm({
56224
+ "packages/cleo/src/cli/commands/cloud.ts"() {
56225
+ "use strict";
56226
+ init_src2();
56227
+ init_define_cli_command();
56228
+ init_nexus_account_cli();
56229
+ init_nexus_cloud_cli();
56230
+ JSON_ARG = { type: "boolean", description: "Output as JSON envelope" };
56231
+ statusSubCommand = defineCommand({
56232
+ meta: {
56233
+ name: "status",
56234
+ description: "Verify this machine against Cleo Nexus in one call: device, credential, project link, replica and stream. Returns { verdict, summary, local, remote, warnings }; verdict is ok, attention, not-linked, not-registered or not-signed-in. Reads only (GET; never binds a replica), except that getting the credential may upgrade a 9.24 session (E1) and retry unsettled logouts (E9/E10)."
56235
+ },
56236
+ args: {
56237
+ project: {
56238
+ type: "string",
56239
+ description: "Project id to check (default: the current project)."
56240
+ },
56241
+ "api-url": NEXUS_API_URL_ARG,
56242
+ json: JSON_ARG
56243
+ },
56244
+ async run({ args }) {
56245
+ await runCloudStatus(args);
56246
+ }
56247
+ });
56248
+ whoamiSubCommand = defineCommand({
56249
+ meta: {
56250
+ name: "whoami",
56251
+ description: "Show the Cleo Nexus user, organizations, credential and device for this machine."
56252
+ },
56253
+ args: { "api-url": NEXUS_API_URL_ARG, json: JSON_ARG },
56254
+ async run({ args }) {
56255
+ await runCloudWhoami(args);
56256
+ }
56257
+ });
56258
+ devicesSubCommand = defineCommand({
56259
+ meta: {
56260
+ name: "devices",
56261
+ description: "List the account's devices (newest first), following every page; reports truncation."
56262
+ },
56263
+ args: {
56264
+ state: {
56265
+ type: "string",
56266
+ description: `Filter: ${NEXUS_DEVICE_LIST_STATES.join(", ")} (default: active).`
56267
+ },
56268
+ "api-url": NEXUS_API_URL_ARG,
56269
+ json: JSON_ARG
56270
+ },
56271
+ async run({ args }) {
56272
+ await runCloudDevices(args);
56273
+ }
56274
+ });
56275
+ projectsSubCommand = defineCommand({
56276
+ meta: {
56277
+ name: "projects",
56278
+ description: "List visible Cleo Nexus projects, following every page (cleo cloud projects [--org <id>]), or show one with its replicas and device counts (cleo cloud projects show [<id>], default: the current project)."
56279
+ },
56280
+ args: {
56281
+ action: {
56282
+ type: "positional",
56283
+ description: "'list' (default) or 'show'.",
56284
+ required: false
56285
+ },
56286
+ id: {
56287
+ type: "positional",
56288
+ description: "Project id for show (default: the current project).",
56289
+ required: false
56290
+ },
56291
+ org: { type: "string", description: "Only this organization id (list)." },
56292
+ "api-url": NEXUS_API_URL_ARG,
56293
+ json: JSON_ARG
56294
+ },
56295
+ async run({ args }) {
56296
+ await runCloudProjects(args);
56297
+ }
56298
+ });
56299
+ cloudCommand = defineCommand({
56300
+ meta: {
56301
+ name: "cloud",
56302
+ description: "Cleo Nexus reads with the device credential (GET only; getting the credential may upgrade a 9.24 session or retry unsettled logouts): status (one-call verification), whoami, devices, projects [show]."
56303
+ },
56304
+ subCommands: {
56305
+ status: statusSubCommand,
56306
+ whoami: whoamiSubCommand,
56307
+ devices: devicesSubCommand,
56308
+ projects: projectsSubCommand
56309
+ }
56310
+ });
56311
+ }
56312
+ });
56313
+
55563
56314
  // packages/cleo/src/cli/commands/code.ts
55564
56315
  var code_exports = {};
55565
56316
  __export(code_exports, {
@@ -63477,6 +64228,40 @@ var init_doctor_db_substrate = __esm({
63477
64228
  }
63478
64229
  });
63479
64230
 
64231
+ // packages/cleo/src/cli/commands/doctor-dep-cycles.ts
64232
+ var doctor_dep_cycles_exports = {};
64233
+ __export(doctor_dep_cycles_exports, {
64234
+ doctorDepCyclesCommand: () => doctorDepCyclesCommand
64235
+ });
64236
+ import { scanDependencyCycles } from "@cleocode/core/doctor/dependency-cycles.js";
64237
+ import { getProjectRoot as getProjectRoot45 } from "@cleocode/core/paths.js";
64238
+ var doctorDepCyclesCommand;
64239
+ var init_doctor_dep_cycles = __esm({
64240
+ "packages/cleo/src/cli/commands/doctor-dep-cycles.ts"() {
64241
+ "use strict";
64242
+ init_define_cli_command();
64243
+ init_renderers();
64244
+ doctorDepCyclesCommand = defineCommand({
64245
+ meta: {
64246
+ name: "dep-cycles",
64247
+ description: "Report task dependency cycles already stored (edges written before the T12886 cycle guard) with a repair plan: the edges whose removal breaks every cycle, each with its `cleo update <id> --remove-depends <dep>` command. Read-only; never removes an edge."
64248
+ },
64249
+ args: {
64250
+ json: { type: "boolean", description: "Output as JSON" },
64251
+ human: { type: "boolean", description: "Force human-readable output" },
64252
+ quiet: { type: "boolean", description: "Suppress non-essential output" }
64253
+ },
64254
+ async run() {
64255
+ const report = await scanDependencyCycles(getProjectRoot45());
64256
+ cliOutput(report, { command: "doctor", operation: "doctor.dep-cycles.run" });
64257
+ if (report.cycleCount > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
64258
+ process.exitCode = 2;
64259
+ }
64260
+ }
64261
+ });
64262
+ }
64263
+ });
64264
+
63480
64265
  // packages/cleo/src/cli/commands/doctor-exodus-residue.ts
63481
64266
  var doctor_exodus_residue_exports = {};
63482
64267
  __export(doctor_exodus_residue_exports, {
@@ -63794,7 +64579,7 @@ var doctor_legacy_backups_exports = {};
63794
64579
  __export(doctor_legacy_backups_exports, {
63795
64580
  doctorLegacyBackupsCommand: () => doctorLegacyBackupsCommand
63796
64581
  });
63797
- import { getProjectRoot as getProjectRoot45 } from "@cleocode/core";
64582
+ import { getProjectRoot as getProjectRoot46 } from "@cleocode/core";
63798
64583
  import { pruneLegacyBackups, scanLegacyBackups } from "@cleocode/core/doctor/legacy-backups.js";
63799
64584
  function parsePositiveInt(raw, fallback) {
63800
64585
  if (raw === void 0 || raw === null) return fallback;
@@ -63838,7 +64623,7 @@ var init_doctor_legacy_backups = __esm({
63838
64623
  async run({ args }) {
63839
64624
  const softRetentionDays = parsePositiveInt(args["soft-retention-days"], 30);
63840
64625
  const hardRetentionDays = parsePositiveInt(args["hard-retention-days"], 90);
63841
- const projectRoot = getProjectRoot45();
64626
+ const projectRoot = getProjectRoot46();
63842
64627
  let result;
63843
64628
  if (args.prune === true) {
63844
64629
  const dryRun = args["dry-run"] !== false;
@@ -63904,7 +64689,7 @@ var doctor_malformed_ids_exports = {};
63904
64689
  __export(doctor_malformed_ids_exports, {
63905
64690
  doctorMalformedIdsCommand: () => doctorMalformedIdsCommand
63906
64691
  });
63907
- import { getProjectRoot as getProjectRoot46 } from "@cleocode/core";
64692
+ import { getProjectRoot as getProjectRoot47 } from "@cleocode/core";
63908
64693
  import { scanMalformedTaskIds } from "@cleocode/core/doctor/malformed-task-ids.js";
63909
64694
  var doctorMalformedIdsCommand;
63910
64695
  var init_doctor_malformed_ids = __esm({
@@ -63927,7 +64712,7 @@ var init_doctor_malformed_ids = __esm({
63927
64712
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63928
64713
  },
63929
64714
  async run({ args }) {
63930
- const report = await scanMalformedTaskIds(getProjectRoot46(), { fix: args.fix === true });
64715
+ const report = await scanMalformedTaskIds(getProjectRoot47(), { fix: args.fix === true });
63931
64716
  cliOutput(report, {
63932
64717
  command: "doctor",
63933
64718
  operation: "doctor.malformed-ids.run"
@@ -63954,7 +64739,7 @@ import {
63954
64739
  repairMalformedManifestRows,
63955
64740
  rollbackManifestRepair
63956
64741
  } from "@cleocode/core/memory/pipeline-manifest-sqlite.js";
63957
- import { getProjectRoot as getProjectRoot47 } from "@cleocode/core/paths.js";
64742
+ import { getProjectRoot as getProjectRoot48 } from "@cleocode/core/paths.js";
63958
64743
  var doctorManifestRowsCommand;
63959
64744
  var init_doctor_manifest_rows = __esm({
63960
64745
  "packages/cleo/src/cli/commands/doctor-manifest-rows.ts"() {
@@ -63985,7 +64770,7 @@ var init_doctor_manifest_rows = __esm({
63985
64770
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63986
64771
  },
63987
64772
  async run({ args }) {
63988
- const projectRoot = getProjectRoot47();
64773
+ const projectRoot = getProjectRoot48();
63989
64774
  if (typeof args.rollback === "string" && args.rollback !== "") {
63990
64775
  const result = await rollbackManifestRepair(args.rollback, projectRoot);
63991
64776
  cliOutput(result, { command: "doctor", operation: "doctor.manifest-rows.rollback" });
@@ -64087,7 +64872,7 @@ var doctor_nexus_residency_exports = {};
64087
64872
  __export(doctor_nexus_residency_exports, {
64088
64873
  doctorNexusResidencyCommand: () => doctorNexusResidencyCommand
64089
64874
  });
64090
- import { getCleoHome as getCleoHome6, getProjectRoot as getProjectRoot48 } from "@cleocode/core";
64875
+ import { getCleoHome as getCleoHome6, getProjectRoot as getProjectRoot49 } from "@cleocode/core";
64091
64876
  import { scanNexusSchemaResidency } from "@cleocode/core/doctor/nexus-schema-residency.js";
64092
64877
  var doctorNexusResidencyCommand;
64093
64878
  var init_doctor_nexus_residency = __esm({
@@ -64106,7 +64891,7 @@ var init_doctor_nexus_residency = __esm({
64106
64891
  quiet: { type: "boolean", description: "Suppress non-essential output" }
64107
64892
  },
64108
64893
  async run() {
64109
- const result = scanNexusSchemaResidency(getProjectRoot48(), getCleoHome6());
64894
+ const result = scanNexusSchemaResidency(getProjectRoot49(), getCleoHome6());
64110
64895
  cliOutput(result, {
64111
64896
  command: "doctor",
64112
64897
  operation: "doctor.nexus-residency.run"
@@ -64124,7 +64909,7 @@ var doctor_project_identity_exports = {};
64124
64909
  __export(doctor_project_identity_exports, {
64125
64910
  doctorProjectIdentityCommand: () => doctorProjectIdentityCommand
64126
64911
  });
64127
- import { getProjectRoot as getProjectRoot49 } from "@cleocode/core";
64912
+ import { getProjectRoot as getProjectRoot50 } from "@cleocode/core";
64128
64913
  import {
64129
64914
  inspectProjectIdentity,
64130
64915
  inspectProjectNameDrift,
@@ -64149,7 +64934,7 @@ var init_doctor_project_identity = __esm({
64149
64934
  quiet: { type: "boolean", description: "Suppress non-essential output" }
64150
64935
  },
64151
64936
  async run({ args }) {
64152
- const projectRoot = getProjectRoot49();
64937
+ const projectRoot = getProjectRoot50();
64153
64938
  if (!args.resolve) {
64154
64939
  const report = inspectProjectIdentity(projectRoot);
64155
64940
  const nameDrift = await inspectProjectNameDrift(projectRoot);
@@ -64688,7 +65473,7 @@ var doctor_repair_exports = {};
64688
65473
  __export(doctor_repair_exports, {
64689
65474
  doctorRepairCommand: () => doctorRepairCommand
64690
65475
  });
64691
- import { getLogger as getLogger21, getProjectRoot as getProjectRoot50 } from "@cleocode/core";
65476
+ import { getLogger as getLogger21, getProjectRoot as getProjectRoot51 } from "@cleocode/core";
64692
65477
  import { repairMalformedDbs } from "@cleocode/core/store/repair-malformed-dbs.js";
64693
65478
  var doctorRepairCommand;
64694
65479
  var init_doctor_repair = __esm({
@@ -64737,7 +65522,7 @@ var init_doctor_repair = __esm({
64737
65522
  return;
64738
65523
  }
64739
65524
  const result = repairMalformedDbs({
64740
- projectRoot: getProjectRoot50(),
65525
+ projectRoot: getProjectRoot51(),
64741
65526
  roles: roleArg.length > 0 ? [roleArg] : void 0,
64742
65527
  dryRun,
64743
65528
  logger: getLogger21("doctor-repair"),
@@ -64939,7 +65724,7 @@ var doctor_superseded_store_exports = {};
64939
65724
  __export(doctor_superseded_store_exports, {
64940
65725
  doctorSupersededStoreCommand: () => doctorSupersededStoreCommand
64941
65726
  });
64942
- import { getProjectRoot as getProjectRoot51 } from "@cleocode/core";
65727
+ import { getProjectRoot as getProjectRoot52 } from "@cleocode/core";
64943
65728
  import { scanSupersededStores } from "@cleocode/core/doctor/superseded-store.js";
64944
65729
  import { reconcileSupersededStores } from "@cleocode/core/store/exodus/index.js";
64945
65730
  var doctorSupersededStoreCommand;
@@ -64972,7 +65757,7 @@ var init_doctor_superseded_store = __esm({
64972
65757
  },
64973
65758
  async run({ args }) {
64974
65759
  if (args.reconcile === true) {
64975
- const receipt = await reconcileSupersededStores(getProjectRoot51(), {
65760
+ const receipt = await reconcileSupersededStores(getProjectRoot52(), {
64976
65761
  dryRun: args["dry-run"] === true,
64977
65762
  additive: args.additive === true
64978
65763
  });
@@ -64994,7 +65779,7 @@ var init_doctor_superseded_store = __esm({
64994
65779
  );
64995
65780
  return;
64996
65781
  }
64997
- const result = scanSupersededStores(getProjectRoot51());
65782
+ const result = scanSupersededStores(getProjectRoot52());
64998
65783
  cliOutput(result, {
64999
65784
  command: "doctor",
65000
65785
  operation: "doctor.superseded-store.run"
@@ -65095,7 +65880,7 @@ import {
65095
65880
  rollbackTwinCollapse
65096
65881
  } from "@cleocode/core/doctor/twin-collapse.js";
65097
65882
  import { CleoError as CleoError8 } from "@cleocode/core/errors";
65098
- import { getProjectRoot as getProjectRoot52 } from "@cleocode/core/paths.js";
65883
+ import { getProjectRoot as getProjectRoot53 } from "@cleocode/core/paths.js";
65099
65884
  function reportTwinCollapseError(error, retry) {
65100
65885
  if (retry && !(error instanceof CleoError8)) throw error;
65101
65886
  const message = error instanceof Error ? error.message : String(error);
@@ -65166,7 +65951,7 @@ var init_doctor_twin_collapse = __esm({
65166
65951
  quiet: { type: "boolean", description: "Suppress non-essential output" }
65167
65952
  },
65168
65953
  async run({ args }) {
65169
- const projectRoot = getProjectRoot52();
65954
+ const projectRoot = getProjectRoot53();
65170
65955
  const guard = { cwd: process.cwd(), confirmOwnerStore: args["confirm-owner-store"] === true };
65171
65956
  const actions = twinCollapseActions(args);
65172
65957
  if (actions.length > 1) {
@@ -65244,7 +66029,7 @@ __export(doctor_worktree_stores_exports, {
65244
66029
  doctorWorktreeStoresCommand: () => doctorWorktreeStoresCommand
65245
66030
  });
65246
66031
  import { scanWorktreeStores } from "@cleocode/core/doctor/worktree-stores.js";
65247
- import { getProjectRoot as getProjectRoot53, resolveStoreOwnerRoot } from "@cleocode/core/paths.js";
66032
+ import { getProjectRoot as getProjectRoot54, resolveStoreOwnerRoot } from "@cleocode/core/paths.js";
65248
66033
  var doctorWorktreeStoresCommand;
65249
66034
  var init_doctor_worktree_stores = __esm({
65250
66035
  "packages/cleo/src/cli/commands/doctor-worktree-stores.ts"() {
@@ -65266,7 +66051,7 @@ var init_doctor_worktree_stores = __esm({
65266
66051
  quiet: { type: "boolean", description: "Suppress non-essential output" }
65267
66052
  },
65268
66053
  async run({ args }) {
65269
- const projectRoot = resolveStoreOwnerRoot(getProjectRoot53());
66054
+ const projectRoot = resolveStoreOwnerRoot(getProjectRoot54());
65270
66055
  const result = scanWorktreeStores(projectRoot, { skipCompare: args["skip-compare"] === true });
65271
66056
  cliOutput(result, {
65272
66057
  command: "doctor",
@@ -65418,7 +66203,7 @@ import {
65418
66203
  resumePreparedKnowledgeRepair,
65419
66204
  runKnowledgeDoctor as runKnowledgeDoctor2
65420
66205
  } from "@cleocode/core/doctor/knowledge.js";
65421
- import { getProjectRoot as getProjectRoot54 } from "@cleocode/core/paths.js";
66206
+ import { getProjectRoot as getProjectRoot55 } from "@cleocode/core/paths.js";
65422
66207
  var doctorKnowledgeSubcommand;
65423
66208
  var init_doctor_knowledge = __esm({
65424
66209
  "packages/cleo/src/cli/commands/doctor-knowledge.ts"() {
@@ -65493,7 +66278,7 @@ var init_doctor_knowledge = __esm({
65493
66278
  },
65494
66279
  async run({ args }) {
65495
66280
  const startedAt = Date.now();
65496
- const root = getProjectRoot54();
66281
+ const root = getProjectRoot55();
65497
66282
  let context;
65498
66283
  let pending;
65499
66284
  try {
@@ -65661,7 +66446,7 @@ import { join as join24 } from "node:path";
65661
66446
  import {
65662
66447
  ensureGlobalAgentRegistryDb,
65663
66448
  getGlobalAgentRegistryNativeDb,
65664
- getProjectRoot as getProjectRoot55,
66449
+ getProjectRoot as getProjectRoot56,
65665
66450
  installAgentFromCant
65666
66451
  } from "@cleocode/core/internal";
65667
66452
  function sha256Hex(bytes) {
@@ -65849,7 +66634,7 @@ var init_migrate_agents_v2 = __esm({
65849
66634
  }
65850
66635
  },
65851
66636
  async run({ args }) {
65852
- const projectRoot = getProjectRoot55();
66637
+ const projectRoot = getProjectRoot56();
65853
66638
  const verbose = args.quiet !== true;
65854
66639
  if (verbose) {
65855
66640
  humanInfo("Scanning .cleo/cant/agents/ and .cleo/agents/ for unregistered agents...");
@@ -65893,7 +66678,7 @@ __export(doctor_exports, {
65893
66678
  });
65894
66679
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
65895
66680
  import { join as join25 } from "node:path";
65896
- import { getProjectRoot as getProjectRoot56, pushWarning as pushWarning5 } from "@cleocode/core";
66681
+ import { getProjectRoot as getProjectRoot57, pushWarning as pushWarning5 } from "@cleocode/core";
65897
66682
  import { renderInvariantAuditLines } from "@cleocode/core/doctor/invariant-audit-render.js";
65898
66683
  import {
65899
66684
  quarantineRogueCleoDir,
@@ -66013,6 +66798,7 @@ var init_doctor = __esm({
66013
66798
  init_doctor_acceptance_drift();
66014
66799
  init_doctor_credentials();
66015
66800
  init_doctor_db_substrate();
66801
+ init_doctor_dep_cycles();
66016
66802
  init_doctor_exodus();
66017
66803
  init_doctor_exodus_residue();
66018
66804
  init_doctor_fk_check();
@@ -66079,6 +66865,8 @@ var init_doctor = __esm({
66079
66865
  "acceptance-drift": doctorAcceptanceDriftCommand,
66080
66866
  // T12790 — evidence bindings whose AC row is gone (no FK): report + --fix (audited)
66081
66867
  "ac-bindings": doctorAcBindingsCommand,
66868
+ // T12886 — stored task dependency cycles + repair plan (read-only)
66869
+ "dep-cycles": doctorDepCyclesCommand,
66082
66870
  // T12158 — tables nexus resolves by bare name must actually live where it assumes
66083
66871
  "nexus-residency": doctorNexusResidencyCommand,
66084
66872
  // T12113 (gh#1222) — evidence-tool semaphore holders + orphan reaping
@@ -66297,7 +67085,7 @@ var init_doctor = __esm({
66297
67085
  const { join: pathJoin } = await import("node:path");
66298
67086
  const { existsSync: existsSync22 } = await import("node:fs");
66299
67087
  const { detectAndHealCoreWorktreeLeak } = await import("@cleocode/worktree");
66300
- const projectRoot = getProjectRoot56();
67088
+ const projectRoot = getProjectRoot57();
66301
67089
  let gitRoot = projectRoot;
66302
67090
  try {
66303
67091
  gitRoot = execFile2("git", ["rev-parse", "--show-toplevel"], {
@@ -66349,7 +67137,7 @@ var init_doctor = __esm({
66349
67137
  }
66350
67138
  if (args.brain) {
66351
67139
  const { computeBrainHealthDashboard } = await import("@cleocode/core/memory/brain-health-dashboard.js");
66352
- const projectRoot = getProjectRoot56();
67140
+ const projectRoot = getProjectRoot57();
66353
67141
  const dashboard = await computeBrainHealthDashboard(projectRoot);
66354
67142
  cliOutput(dashboard, { command: "doctor", operation: "doctor.brain" });
66355
67143
  if (dashboard.hasP0Failure) {
@@ -66358,7 +67146,7 @@ var init_doctor = __esm({
66358
67146
  return;
66359
67147
  }
66360
67148
  if (args["scan-test-fixtures-in-prod"]) {
66361
- const projectRoot = getProjectRoot56();
67149
+ const projectRoot = getProjectRoot57();
66362
67150
  const matches = await scanTestFixturesInProd(projectRoot);
66363
67151
  const dryRun = args["dry-run"] !== false && args.quarantine !== true;
66364
67152
  const quarantined = !dryRun && matches.length > 0 ? await quarantineTestFixtures(projectRoot, matches) : void 0;
@@ -66446,7 +67234,7 @@ var init_doctor = __esm({
66446
67234
  progress.complete("Comprehensive diagnostics complete");
66447
67235
  } else if (args["scan-rogue-cleo-dirs"]) {
66448
67236
  progress.step(0, "Scanning for rogue .cleo/ directories");
66449
- const projectRoot = getProjectRoot56();
67237
+ const projectRoot = getProjectRoot57();
66450
67238
  const reports = scanRogueCleoDirs(projectRoot);
66451
67239
  progress.complete(
66452
67240
  `Found ${reports.length} rogue .cleo/ director${reports.length === 1 ? "y" : "ies"}`
@@ -66455,7 +67243,7 @@ var init_doctor = __esm({
66455
67243
  } else if (args["quarantine-rogue-cleo-dirs"]) {
66456
67244
  const isDryRun = args["dry-run"] === true;
66457
67245
  progress.step(0, `${isDryRun ? "[DRY RUN] " : ""}Scanning for rogue .cleo/ directories`);
66458
- const projectRoot = getProjectRoot56();
67246
+ const projectRoot = getProjectRoot57();
66459
67247
  const reports = scanRogueCleoDirs(projectRoot);
66460
67248
  if (reports.length === 0) {
66461
67249
  progress.complete("No rogue .cleo/ directories found \u2014 nothing to quarantine");
@@ -66509,7 +67297,7 @@ var init_doctor = __esm({
66509
67297
  const { detectAndRemoveLegacyGlobalFiles, detectAndRemoveStrayProjectNexus } = await import("@cleocode/core/store/cleanup-legacy.js");
66510
67298
  const { getCleoHome: getCleoHome8 } = await import("@cleocode/core");
66511
67299
  const cleoHome = getCleoHome8();
66512
- const projectRoot = getProjectRoot56();
67300
+ const projectRoot = getProjectRoot57();
66513
67301
  const legacyResult = detectAndRemoveLegacyGlobalFiles(cleoHome);
66514
67302
  const strayResult = detectAndRemoveStrayProjectNexus(projectRoot);
66515
67303
  const isDryRun = args["dry-run"] === true;
@@ -66542,7 +67330,7 @@ var init_doctor = __esm({
66542
67330
  } else if (args["audit-worktree-orphans"]) {
66543
67331
  progress.step(0, "Comprehensive worktree anomaly audit (T9808 / council D009)");
66544
67332
  const { auditWorktreeOrphansComprehensive, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
66545
- const projectRoot = getProjectRoot56();
67333
+ const projectRoot = getProjectRoot57();
66546
67334
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
66547
67335
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
66548
67336
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -66599,7 +67387,7 @@ var init_doctor = __esm({
66599
67387
  `${isDryRun ? "[DRY RUN] " : ""}Scanning + pruning worktree-orphan .cleo/ directories`
66600
67388
  );
66601
67389
  const { pruneWorktreeOrphans, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
66602
- const projectRoot = getProjectRoot56();
67390
+ const projectRoot = getProjectRoot57();
66603
67391
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
66604
67392
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
66605
67393
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -66678,7 +67466,7 @@ var init_doctor = __esm({
66678
67466
  `${isDryRun ? "[DRY RUN] " : ""}Migrating .cleo/worktree-include \u2192 .worktreeinclude`
66679
67467
  );
66680
67468
  const { migrateWorktreeIncludeFile } = await import("@cleocode/core");
66681
- const projectRoot = getProjectRoot56();
67469
+ const projectRoot = getProjectRoot57();
66682
67470
  const result = await migrateWorktreeIncludeFile(projectRoot, { dryRun: isDryRun });
66683
67471
  progress.complete(`Migration ${result.action}`);
66684
67472
  cliOutput(result, { command: "doctor", operation: "doctor.migrate-worktree-include" });
@@ -66697,7 +67485,7 @@ var init_doctor = __esm({
66697
67485
  const stepLabel = isFocusedAlias ? "Auditing Saga hierarchy for ADR-073 invariants" : "Walking central INVARIANTS_REGISTRY";
66698
67486
  progress.step(0, stepLabel);
66699
67487
  const { auditInvariantRegistry } = await import("@cleocode/core/doctor/invariant-audit.js");
66700
- const projectRoot = getProjectRoot56();
67488
+ const projectRoot = getProjectRoot57();
66701
67489
  const result = await auditInvariantRegistry(projectRoot, { adrFilter });
66702
67490
  const operation = isFocusedAlias ? "doctor.audit-sagas" : "doctor.audit-invariants";
66703
67491
  const summary = `Invariant audit complete \u2014 ${result.totalCount} entries walked, ${result.errorCount} error / ${result.warningCount} warning / ${result.infoCount} info violation(s), ${result.notApplicableCount} not-applicable, ${result.documentedCount} documented`;
@@ -66719,7 +67507,7 @@ var init_doctor = __esm({
66719
67507
  { command: "doctor", operation: "admin.health" }
66720
67508
  );
66721
67509
  try {
66722
- const projectRoot = getProjectRoot56();
67510
+ const projectRoot = getProjectRoot57();
66723
67511
  const conflicts = readMigrationConflicts(projectRoot);
66724
67512
  if (conflicts.length > 0) {
66725
67513
  progress.complete(
@@ -66750,7 +67538,7 @@ var init_doctor = __esm({
66750
67538
  progress.complete("Health check complete");
66751
67539
  }
66752
67540
  try {
66753
- const projectRoot = getProjectRoot56();
67541
+ const projectRoot = getProjectRoot57();
66754
67542
  const { auditSagaHierarchy } = await import("@cleocode/core/doctor/saga-audit.js");
66755
67543
  const sagaAudit = await auditSagaHierarchy(projectRoot);
66756
67544
  if (sagaAudit.sagas.length === 0) {
@@ -66777,6 +67565,26 @@ Saga Hierarchy (${sagaAudit.sagas.length} saga(s), ${sagaAudit.count} violation(
66777
67565
  humanLine(`
66778
67566
  Saga Hierarchy: audit skipped (${msg})`);
66779
67567
  }
67568
+ try {
67569
+ const { scanDependencyCycles: scanDependencyCycles2 } = await import("@cleocode/core/doctor/dependency-cycles.js");
67570
+ const cycles = await scanDependencyCycles2(getProjectRoot57());
67571
+ humanLine(
67572
+ `
67573
+ Dependency cycles: ${cycles.cycleCount} (${cycles.edgeCount} edge(s) checked)`
67574
+ );
67575
+ for (const c of cycles.components) humanLine(` ${c.cycle.join(" \u2192 ")}`);
67576
+ if (cycles.repairPlan.length > 0) {
67577
+ humanLine(" Repair plan (review first; `cleo doctor dep-cycles` for JSON):");
67578
+ for (const r of cycles.repairPlan) humanLine(` ${r.command}`);
67579
+ }
67580
+ if (cycles.cycleCount > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
67581
+ process.exitCode = 2;
67582
+ }
67583
+ } catch (err) {
67584
+ const msg = err instanceof Error ? err.message : String(err);
67585
+ humanLine(`
67586
+ Dependency cycles: check skipped (${msg})`);
67587
+ }
66780
67588
  }
66781
67589
  } catch (err) {
66782
67590
  progress.error("Health check failed");
@@ -66798,7 +67606,7 @@ async function batchEntry(taskId, result, args) {
66798
67606
  return { taskId, completed: false, error: code, message, next: fix };
66799
67607
  }
66800
67608
  const params = completeDispatchParams({ ...args, taskId, "if-match": void 0 });
66801
- const done = await dispatchRaw("mutate", "tasks", "complete", params);
67609
+ const done = await withoutOutputPointer(() => dispatchRaw("mutate", "tasks", "complete", params));
66802
67610
  const recordedGates = result.data.recordedGates;
66803
67611
  if (done.success) return { taskId, recordedGates, completed: true };
66804
67612
  const failure = { error: "E_DONE_BLOCKED", message: done.error?.message, next: done.error?.fix };
@@ -66834,6 +67642,7 @@ var init_done = __esm({
66834
67642
  "packages/cleo/src/cli/commands/done.ts"() {
66835
67643
  "use strict";
66836
67644
  init_cli();
67645
+ init_field_context();
66837
67646
  init_define_cli_command();
66838
67647
  init_renderers();
66839
67648
  init_complete();
@@ -66869,8 +67678,8 @@ var init_done = __esm({
66869
67678
  process.exitCode = 2;
66870
67679
  return;
66871
67680
  }
66872
- const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/paths.js");
66873
- const options = { projectRoot: getProjectRoot74(), ...parsed.options };
67681
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/paths.js");
67682
+ const options = { projectRoot: getProjectRoot75(), ...parsed.options };
66874
67683
  const requested = [
66875
67684
  ...new Set([args.taskId, ...args._ ?? []].map(String))
66876
67685
  ];
@@ -66920,11 +67729,13 @@ var init_done = __esm({
66920
67729
  process.exitCode = recorded.error.exitCode ?? 1;
66921
67730
  return;
66922
67731
  }
66923
- const completed = await dispatchRaw(
66924
- "mutate",
66925
- "tasks",
66926
- "complete",
66927
- completeDispatchParams({ ...args, "if-match": void 0 })
67732
+ const completed = await withoutOutputPointer(
67733
+ () => dispatchRaw(
67734
+ "mutate",
67735
+ "tasks",
67736
+ "complete",
67737
+ completeDispatchParams({ ...args, "if-match": void 0 })
67738
+ )
66928
67739
  );
66929
67740
  if (!completed.success) {
66930
67741
  const details = {
@@ -67420,7 +68231,7 @@ function showStatus() {
67420
68231
  }
67421
68232
  cliOutput(result, { command: "exodus status" });
67422
68233
  }
67423
- var migrateSubCommand, verifySubCommand, sealSubCommand, statusSubCommand, exodusCommand;
68234
+ var migrateSubCommand, verifySubCommand, sealSubCommand, statusSubCommand2, exodusCommand;
67424
68235
  var init_exodus = __esm({
67425
68236
  "packages/cleo/src/cli/commands/exodus.ts"() {
67426
68237
  "use strict";
@@ -67730,7 +68541,7 @@ Passing tables (${passing.length}):`);
67730
68541
  );
67731
68542
  }
67732
68543
  });
67733
- statusSubCommand = defineCommand({
68544
+ statusSubCommand2 = defineCommand({
67734
68545
  meta: {
67735
68546
  name: "status",
67736
68547
  description: "Show exodus migration status (staging, source DBs, target DBs)"
@@ -67748,7 +68559,7 @@ Passing tables (${passing.length}):`);
67748
68559
  migrate: migrateSubCommand,
67749
68560
  verify: verifySubCommand,
67750
68561
  seal: sealSubCommand,
67751
- status: statusSubCommand
68562
+ status: statusSubCommand2
67752
68563
  },
67753
68564
  async run({ cmd, rawArgs }) {
67754
68565
  if (isSubCommandDispatch(rawArgs, cmd.subCommands)) return;
@@ -68230,7 +69041,7 @@ __export(gateway_exports, {
68230
69041
  gatewayOpenapiSubCommand: () => gatewayOpenapiSubCommand
68231
69042
  });
68232
69043
  import { resolve as resolve8 } from "node:path";
68233
- import { generateOpenApi, getProjectRoot as getProjectRoot57 } from "@cleocode/core";
69044
+ import { generateOpenApi, getProjectRoot as getProjectRoot58 } from "@cleocode/core";
68234
69045
  var gatewayOpenapiSubCommand, gatewayCommand;
68235
69046
  var init_gateway = __esm({
68236
69047
  "packages/cleo/src/cli/commands/gateway.ts"() {
@@ -68262,7 +69073,7 @@ var init_gateway = __esm({
68262
69073
  const pathCount = Object.keys(doc.paths).length;
68263
69074
  if (typeof args.out === "string" && args.out.length > 0) {
68264
69075
  const { writeFileSync: writeFileSync8 } = await import("node:fs");
68265
- const target = resolve8(getProjectRoot57(), args.out);
69076
+ const target = resolve8(getProjectRoot58(), args.out);
68266
69077
  writeFileSync8(target, json2, "utf8");
68267
69078
  cliOutput(
68268
69079
  { out: target, pathCount, version: doc.info.version, openapi: doc.openapi },
@@ -68723,7 +69534,7 @@ var go_exports = {};
68723
69534
  __export(go_exports, {
68724
69535
  goCommand: () => goCommand
68725
69536
  });
68726
- import { getProjectRoot as getProjectRoot58, go } from "@cleocode/core";
69537
+ import { getProjectRoot as getProjectRoot59, go } from "@cleocode/core";
68727
69538
  var goCommand;
68728
69539
  var init_go = __esm({
68729
69540
  "packages/cleo/src/cli/commands/go.ts"() {
@@ -68749,7 +69560,7 @@ var init_go = __esm({
68749
69560
  }
68750
69561
  },
68751
69562
  async run({ args }) {
68752
- const projectRoot = getProjectRoot58();
69563
+ const projectRoot = getProjectRoot59();
68753
69564
  const { getCurrentSessionId, resolveBoundSessionId } = await import("@cleocode/core/internal");
68754
69565
  let sessionId = getCurrentSessionId(projectRoot) ?? void 0;
68755
69566
  if (sessionId === void 0) {
@@ -68777,7 +69588,7 @@ var goal_exports = {};
68777
69588
  __export(goal_exports, {
68778
69589
  goalCommand: () => goalCommand
68779
69590
  });
68780
- import { getProjectRoot as getProjectRoot59, goal } from "@cleocode/core";
69591
+ import { getProjectRoot as getProjectRoot60, goal } from "@cleocode/core";
68781
69592
  function resolveGoalKind(task) {
68782
69593
  if (typeof task === "string" && task.length > 0) {
68783
69594
  if (!isValidGoalTargetTaskId(task)) {
@@ -68824,7 +69635,7 @@ var init_goal2 = __esm({
68824
69635
  }
68825
69636
  const record = await goal.createGoal(
68826
69637
  { goalKind: kindResult.kind, intent, turnBudget: resolveTurnBudget(args.turns) },
68827
- getProjectRoot59()
69638
+ getProjectRoot60()
68828
69639
  );
68829
69640
  cliOutput(record, { command: "goal set", operation: "goal.set" });
68830
69641
  }
@@ -68835,7 +69646,7 @@ var init_goal2 = __esm({
68835
69646
  description: "Show the current agent's active goal (per-agent scoped)."
68836
69647
  },
68837
69648
  async run() {
68838
- const record = await goal.getActiveGoal(getProjectRoot59());
69649
+ const record = await goal.getActiveGoal(getProjectRoot60());
68839
69650
  cliOutput(record ?? { active: null }, { command: "goal status", operation: "goal.status" });
68840
69651
  }
68841
69652
  });
@@ -68857,7 +69668,7 @@ var init_goal2 = __esm({
68857
69668
  });
68858
69669
  return;
68859
69670
  }
68860
- const cwd = getProjectRoot59();
69671
+ const cwd = getProjectRoot60();
68861
69672
  const parent = await goal.getActiveGoal(cwd);
68862
69673
  if (!parent) {
68863
69674
  cliError(
@@ -68905,7 +69716,7 @@ var init_goal2 = __esm({
68905
69716
  });
68906
69717
  return;
68907
69718
  }
68908
- const cwd = getProjectRoot59();
69719
+ const cwd = getProjectRoot60();
68909
69720
  const result = await goal.advanceGoalWithPersist(goalId, { cwd });
68910
69721
  if (!result) {
68911
69722
  cliError(`Goal '${goalId}' not found.`, 4 /* NOT_FOUND */, { name: "E_NOT_FOUND" });
@@ -68930,7 +69741,7 @@ var init_goal2 = __esm({
68930
69741
  });
68931
69742
  return;
68932
69743
  }
68933
- const cwd = getProjectRoot59();
69744
+ const cwd = getProjectRoot60();
68934
69745
  const active = await goal.getActiveGoal(cwd);
68935
69746
  if (!active) {
68936
69747
  cliError(
@@ -69977,7 +70788,7 @@ var hygiene_exports = {};
69977
70788
  __export(hygiene_exports, {
69978
70789
  hygieneCommand: () => hygieneCommand
69979
70790
  });
69980
- import { getProjectRoot as getProjectRoot60 } from "@cleocode/core";
70791
+ import { getProjectRoot as getProjectRoot61 } from "@cleocode/core";
69981
70792
  import { runSpawnReadinessHygieneCli } from "@cleocode/core/hygiene/validate-spawn-readiness.js";
69982
70793
  var hygieneCommand;
69983
70794
  var init_hygiene = __esm({
@@ -70006,7 +70817,7 @@ var init_hygiene = __esm({
70006
70817
  }
70007
70818
  },
70008
70819
  async run({ args }) {
70009
- const projectRoot = args["project-root"] || getProjectRoot60() || process.cwd();
70820
+ const projectRoot = args["project-root"] || getProjectRoot61() || process.cwd();
70010
70821
  const worktreePath = args["worktree-path"];
70011
70822
  await runSpawnReadinessHygieneCli(projectRoot, worktreePath);
70012
70823
  }
@@ -71349,7 +72160,7 @@ var llm_cost_exports = {};
71349
72160
  __export(llm_cost_exports, {
71350
72161
  costCommand: () => costCommand
71351
72162
  });
71352
- import { getProjectRoot as getProjectRoot61 } from "@cleocode/core/internal";
72163
+ import { getProjectRoot as getProjectRoot62 } from "@cleocode/core/internal";
71353
72164
  import { computeCost } from "@cleocode/core/llm/usage-pricing";
71354
72165
  function resolveSessionId(raw) {
71355
72166
  if (raw === "current") {
@@ -71422,7 +72233,7 @@ var init_llm_cost = __esm({
71422
72233
  process.exit(6);
71423
72234
  }
71424
72235
  const sessionId = resolveSessionId(rawSessionId);
71425
- const projectRoot = getProjectRoot61(process.cwd());
72236
+ const projectRoot = getProjectRoot62(process.cwd());
71426
72237
  let breakdown;
71427
72238
  try {
71428
72239
  breakdown = await loadSessionCostBreakdown(projectRoot, sessionId);
@@ -71521,8 +72332,8 @@ async function resolveDefaultModel(provider) {
71521
72332
  "@cleocode/core/llm/role-resolver.js"
71522
72333
  )
71523
72334
  ]);
71524
- const profile = await getProviderProfile2(provider);
71525
- return profile?.defaultModel ?? IMPLICIT_FALLBACK_MODEL;
72335
+ const profile2 = await getProviderProfile2(provider);
72336
+ return profile2?.defaultModel ?? IMPLICIT_FALLBACK_MODEL;
71526
72337
  }
71527
72338
  async function runLlmStream(opts) {
71528
72339
  const stdout2 = opts.stdout ?? process.stdout;
@@ -72380,14 +73191,8 @@ var init_log = __esm({
72380
73191
  // packages/cleo/src/cli/commands/logout.ts
72381
73192
  var logout_exports = {};
72382
73193
  __export(logout_exports, {
72383
- logoutCommand: () => logoutCommand,
72384
- nexusLogoutSummary: () => nexusLogoutSummary
73194
+ logoutCommand: () => logoutCommand
72385
73195
  });
72386
- function nexusLogoutSummary(r) {
72387
- if (!r.removedLocally) return `Not signed in to ${r.apiUrl}; nothing to do.`;
72388
- const server = r.revocation === "revoked" ? "session revoked" : r.revocation === "already-invalid" ? "session was already invalid" : "server-side revocation FAILED (the session ends when it expires)";
72389
- return `Signed out of ${r.apiUrl}: ${server}; local token deleted.`;
72390
- }
72391
73196
  var logoutCommand;
72392
73197
  var init_logout = __esm({
72393
73198
  "packages/cleo/src/cli/commands/logout.ts"() {
@@ -72399,7 +73204,7 @@ var init_logout = __esm({
72399
73204
  logoutCommand = defineCommand({
72400
73205
  meta: {
72401
73206
  name: "logout",
72402
- description: "Sign out. cleo logout [nexus] revokes the Cleo Nexus session server-side and deletes the stored token; cleo logout <provider> [label] removes an LLM credential exactly like cleo auth remove (the label may be omitted when the provider has one credential)."
73207
+ description: "Sign out. cleo logout [nexus] signs this machine out of Cleo Nexus (the device keeps its id for the next login; --revoke burns it), confirmed by the server; cleo logout <provider> [label] removes an LLM credential exactly like cleo auth remove (the label may be omitted when the provider has one credential)."
72403
73208
  },
72404
73209
  args: {
72405
73210
  target: {
@@ -72413,6 +73218,10 @@ var init_logout = __esm({
72413
73218
  required: false
72414
73219
  },
72415
73220
  "api-url": NEXUS_API_URL_ARG,
73221
+ revoke: {
73222
+ type: "boolean",
73223
+ description: "Hard-revoke this device: destroys its key grant and burns the device id; the next login enrols a new device. Without it, logout signs the device out and keeps it for the next login."
73224
+ },
72416
73225
  json: { type: "boolean", description: "Output as JSON envelope" }
72417
73226
  },
72418
73227
  async run({ args }) {
@@ -72427,17 +73236,7 @@ var init_logout = __esm({
72427
73236
  emitLlmCredentialRemoval(await removeLlmCredential(target, label), "logout", "logout.run");
72428
73237
  return;
72429
73238
  }
72430
- const { logoutFromNexus } = await import(
72431
- /* webpackIgnore: true */
72432
- "@cleocode/core/cloud/nexus-auth.js"
72433
- );
72434
- let result;
72435
- try {
72436
- result = await logoutFromNexus({ apiUrl: nexusApiUrlArg(a) });
72437
- } catch (err) {
72438
- failNexus(err, "logout.run");
72439
- }
72440
- emitNexusResult(result, nexusLogoutSummary(result), "logout", "logout.run");
73239
+ await runNexusDeviceLogout(a);
72441
73240
  }
72442
73241
  });
72443
73242
  }
@@ -72811,7 +73610,7 @@ var memory_exports = {};
72811
73610
  __export(memory_exports, {
72812
73611
  memoryCommand: () => memoryCommand
72813
73612
  });
72814
- import { getProjectRoot as getProjectRoot62 } from "@cleocode/core";
73613
+ import { getProjectRoot as getProjectRoot63 } from "@cleocode/core";
72815
73614
  import {
72816
73615
  getBrainDb as getBrainDb2,
72817
73616
  getDreamStatus,
@@ -73769,7 +74568,7 @@ var init_memory3 = __esm({
73769
74568
  },
73770
74569
  args: {},
73771
74570
  async run() {
73772
- const root = getProjectRoot62();
74571
+ const root = getProjectRoot63();
73773
74572
  try {
73774
74573
  const result = await runConsolidation(root);
73775
74574
  cliOutput(result, { command: "memory-consolidate", operation: "memory.consolidate" });
@@ -73793,7 +74592,7 @@ var init_memory3 = __esm({
73793
74592
  }
73794
74593
  },
73795
74594
  async run({ args }) {
73796
- const root = getProjectRoot62();
74595
+ const root = getProjectRoot63();
73797
74596
  if (args.status) {
73798
74597
  try {
73799
74598
  const status = await getDreamStatus(root);
@@ -73830,7 +74629,7 @@ var init_memory3 = __esm({
73830
74629
  }
73831
74630
  },
73832
74631
  async run({ args }) {
73833
- const root = getProjectRoot62();
74632
+ const root = getProjectRoot63();
73834
74633
  try {
73835
74634
  const { runObserver, runReflector } = await import("@cleocode/core/memory");
73836
74635
  const observerResult = await runObserver(root, args.session, {
@@ -73870,7 +74669,7 @@ var init_memory3 = __esm({
73870
74669
  }
73871
74670
  },
73872
74671
  async run({ args }) {
73873
- const root = getProjectRoot62();
74672
+ const root = getProjectRoot63();
73874
74673
  await getBrainDb2(root);
73875
74674
  const { getBrainNativeDb: getBrainNativeDb3 } = await import("@cleocode/core/internal");
73876
74675
  const nativeDb = getBrainNativeDb3();
@@ -73908,7 +74707,7 @@ var init_memory3 = __esm({
73908
74707
  },
73909
74708
  async run({ args }) {
73910
74709
  const core2 = await import("@cleocode/core/internal");
73911
- const nexusDb = await core2.getNexusDb(getProjectRoot62());
74710
+ const nexusDb = await core2.getNexusDb(getProjectRoot63());
73912
74711
  const result = args.restore ? await core2.restorePrunedTraits(
73913
74712
  nexusDb,
73914
74713
  String(args.restore),
@@ -73938,7 +74737,7 @@ var init_memory3 = __esm({
73938
74737
  return;
73939
74738
  }
73940
74739
  const core2 = await import("@cleocode/core/internal");
73941
- const nexusDb = await core2.getNexusDb(getProjectRoot62());
74740
+ const nexusDb = await core2.getNexusDb(getProjectRoot63());
73942
74741
  const previous = await core2.setUserProfileTraitScope(nexusDb, String(args.key), scope);
73943
74742
  if (previous === null) {
73944
74743
  cliError(`No user-profile trait "${args.key}"`, "E_NOT_FOUND", { name: "E_NOT_FOUND" });
@@ -73962,7 +74761,7 @@ var init_memory3 = __esm({
73962
74761
  }
73963
74762
  },
73964
74763
  async run({ args }) {
73965
- const root = getProjectRoot62();
74764
+ const root = getProjectRoot63();
73966
74765
  try {
73967
74766
  await getBrainDb2(root);
73968
74767
  const { totalDuplicateRows, groups } = await scanDuplicateEntries();
@@ -74008,7 +74807,7 @@ var init_memory3 = __esm({
74008
74807
  async run({ args }) {
74009
74808
  const sourceDir = args.from;
74010
74809
  const isDryRun = !!args["dry-run"];
74011
- const projectRoot = getProjectRoot62();
74810
+ const projectRoot = getProjectRoot63();
74012
74811
  try {
74013
74812
  const result = await importMemoryFiles({
74014
74813
  sourceDir,
@@ -74159,7 +74958,7 @@ var init_memory3 = __esm({
74159
74958
  },
74160
74959
  args: {},
74161
74960
  async run() {
74162
- const root = getProjectRoot62();
74961
+ const root = getProjectRoot63();
74163
74962
  try {
74164
74963
  await getBrainDb2(root);
74165
74964
  const result = await getTierStats(root);
@@ -74202,7 +75001,7 @@ var init_memory3 = __esm({
74202
75001
  }
74203
75002
  },
74204
75003
  async run({ args }) {
74205
- const root = getProjectRoot62();
75004
+ const root = getProjectRoot63();
74206
75005
  const targetTier = args.to;
74207
75006
  const reason = args.reason;
74208
75007
  const validTiers = ["medium", "long"];
@@ -74268,7 +75067,7 @@ var init_memory3 = __esm({
74268
75067
  }
74269
75068
  },
74270
75069
  async run({ args }) {
74271
- const root = getProjectRoot62();
75070
+ const root = getProjectRoot63();
74272
75071
  const targetTier = args.to;
74273
75072
  const reason = args.reason;
74274
75073
  const validTiers = ["short", "medium"];
@@ -74741,7 +75540,7 @@ var migrate_claude_mem_exports = {};
74741
75540
  __export(migrate_claude_mem_exports, {
74742
75541
  migrateClaudeMemCommand: () => migrateClaudeMemCommand
74743
75542
  });
74744
- import { getProjectRoot as getProjectRoot63, migrateClaudeMem } from "@cleocode/core/internal";
75543
+ import { getProjectRoot as getProjectRoot64, migrateClaudeMem } from "@cleocode/core/internal";
74745
75544
  import { ingestLooseAgentOutputs, ingestRcasdDirectories } from "@cleocode/core/memory";
74746
75545
  import { getDb as getDb2 } from "@cleocode/core/store/sqlite";
74747
75546
  var storageCommand, claudeMemCommand, manifestIngestCommand, migrateClaudeMemCommand;
@@ -74804,7 +75603,7 @@ var init_migrate_claude_mem = __esm({
74804
75603
  }
74805
75604
  },
74806
75605
  async run({ args }) {
74807
- const root = getProjectRoot63();
75606
+ const root = getProjectRoot64();
74808
75607
  try {
74809
75608
  const result = await migrateClaudeMem(root, {
74810
75609
  sourcePath: args.source,
@@ -74853,7 +75652,7 @@ var init_migrate_claude_mem = __esm({
74853
75652
  }
74854
75653
  },
74855
75654
  async run({ args }) {
74856
- const projectRoot = getProjectRoot63();
75655
+ const projectRoot = getProjectRoot64();
74857
75656
  try {
74858
75657
  const db = await getDb2(projectRoot);
74859
75658
  const rcasdFlag = Boolean(args.rcasd);
@@ -74971,7 +75770,7 @@ __export(nexus_exports, {
74971
75770
  import { statSync as statSync2 } from "node:fs";
74972
75771
  import { appendFile as appendFile2, mkdir as mkdir5 } from "node:fs/promises";
74973
75772
  import path4 from "node:path";
74974
- import { getProjectRoot as getProjectRoot64 } from "@cleocode/core";
75773
+ import { getProjectRoot as getProjectRoot65 } from "@cleocode/core";
74975
75774
  import { getSymbolImpact } from "@cleocode/core/nexus";
74976
75775
  import { runNexusAnalysis } from "@cleocode/core/nexus/analyze-orchestrator.js";
74977
75776
  import {
@@ -75142,7 +75941,7 @@ var init_nexus3 = __esm({
75142
75941
  async run({ args }) {
75143
75942
  applyJsonFlag2(args.json);
75144
75943
  const projectIdOverride = args["project-id"];
75145
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
75944
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
75146
75945
  const startTime = Date.now();
75147
75946
  if (args.path) {
75148
75947
  let isDir = false;
@@ -75202,7 +76001,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648), so the coun
75202
76001
  process.exitCode = 2 /* INVALID_INPUT */;
75203
76002
  return;
75204
76003
  }
75205
- const currentRoot = getProjectRoot64();
76004
+ const currentRoot = getProjectRoot65();
75206
76005
  if (args.path && path4.resolve(repoPath) !== path4.resolve(currentRoot)) {
75207
76006
  cliError(
75208
76007
  `nexus status cannot report on '${repoPath}' from this project.
@@ -75756,7 +76555,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75756
76555
  applyJsonFlag2(args.json);
75757
76556
  const startTime = Date.now();
75758
76557
  const projectIdOverride = args["project-id"];
75759
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
76558
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
75760
76559
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75761
76560
  const response = await dispatchRaw("query", "nexus", "clusters", { projectId, repoPath });
75762
76561
  const durationMs = Date.now() - startTime;
@@ -75800,7 +76599,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75800
76599
  applyJsonFlag2(args.json);
75801
76600
  const startTime = Date.now();
75802
76601
  const projectIdOverride = args["project-id"];
75803
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
76602
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
75804
76603
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75805
76604
  const response = await dispatchRaw("query", "nexus", "flows", { projectId, repoPath });
75806
76605
  const durationMs = Date.now() - startTime;
@@ -75843,7 +76642,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75843
76642
  void appendDeprecationTelemetry("nexus.context", "cleo graph context");
75844
76643
  const startTime = Date.now();
75845
76644
  const projectIdOverride = args["project-id"];
75846
- const repoPath = getProjectRoot64();
76645
+ const repoPath = getProjectRoot65();
75847
76646
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75848
76647
  const limit = parseInt(args.limit, 10);
75849
76648
  const symbolName = args.symbol;
@@ -75906,7 +76705,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75906
76705
  const startTime = Date.now();
75907
76706
  const whyFlag = !!args.why;
75908
76707
  const projectIdOverride = args["project-id"];
75909
- const repoPath = getProjectRoot64();
76708
+ const repoPath = getProjectRoot65();
75910
76709
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75911
76710
  const maxDepth = Math.min(parseInt(args.depth, 10), 5);
75912
76711
  const symbolName = args.symbol;
@@ -76010,7 +76809,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76010
76809
  const projectIdOverride = args["project-id"];
76011
76810
  const full = !!args.full;
76012
76811
  const ctx = getFormatContext();
76013
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
76812
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76014
76813
  if (args.incremental)
76015
76814
  humanWarn(
76016
76815
  "[nexus] --incremental is deprecated and has no effect: incremental is the default."
@@ -76140,7 +76939,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76140
76939
  async run({ args }) {
76141
76940
  applyJsonFlag2(args.json);
76142
76941
  const startTime = Date.now();
76143
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
76942
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76144
76943
  const name = args.name;
76145
76944
  const response = await dispatchRaw("mutate", "nexus", "projects.register", {
76146
76945
  path: repoPath,
@@ -76659,7 +77458,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76659
77458
  applyJsonFlag2(args.json);
76660
77459
  const startTime = Date.now();
76661
77460
  const projectIdOverride = args["project-id"];
76662
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
77461
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76663
77462
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
76664
77463
  const response = await dispatchRaw("mutate", "nexus", "refresh-bridge", {
76665
77464
  repoPath,
@@ -76765,7 +77564,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76765
77564
  async run({ args }) {
76766
77565
  applyJsonFlag2(args.json);
76767
77566
  const startTime = Date.now();
76768
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
77567
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76769
77568
  const projectIdOverride = args["project-id"];
76770
77569
  const beforeRef = args.before ?? "HEAD~1";
76771
77570
  const afterRef = args.after ?? "HEAD";
@@ -76883,7 +77682,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76883
77682
  applyJsonFlag2(args.json);
76884
77683
  const startTime = Date.now();
76885
77684
  const projectIdOverride = args["project-id"];
76886
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
77685
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76887
77686
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
76888
77687
  const response = await dispatchRaw("query", "nexus", "route-map", { projectId });
76889
77688
  const durationMs = Date.now() - startTime;
@@ -76939,7 +77738,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76939
77738
  const startTime = Date.now();
76940
77739
  const routeSymbol = args.routeSymbol;
76941
77740
  const projectIdOverride = args["project-id"];
76942
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
77741
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76943
77742
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
76944
77743
  const response = await dispatchRaw("query", "nexus", "shape-check", { routeSymbol, projectId });
76945
77744
  const durationMs = Date.now() - startTime;
@@ -77335,7 +78134,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
77335
78134
  async run({ args }) {
77336
78135
  applyJsonFlag2(args.json);
77337
78136
  const startTime = Date.now();
77338
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
78137
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
77339
78138
  const projectIdOverride = args["project-id"];
77340
78139
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
77341
78140
  const response = await dispatchRaw("mutate", "nexus", "contracts-sync", {
@@ -77445,7 +78244,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
77445
78244
  async run({ args }) {
77446
78245
  applyJsonFlag2(args.json);
77447
78246
  const startTime = Date.now();
77448
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
78247
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
77449
78248
  const projectId = Buffer.from(repoPath).toString("base64url").slice(0, 32);
77450
78249
  const response = await dispatchRaw("mutate", "nexus", "contracts-link-tasks", {
77451
78250
  projectId,
@@ -77529,7 +78328,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
77529
78328
  const isIncremental = !!args.incremental;
77530
78329
  try {
77531
78330
  const result = await runNexusWiki({
77532
- projectRoot: getProjectRoot64(),
78331
+ projectRoot: getProjectRoot65(),
77533
78332
  outputDir,
77534
78333
  communityFilter,
77535
78334
  incremental: isIncremental
@@ -77879,7 +78678,7 @@ __export(orchestrate_exports, {
77879
78678
  });
77880
78679
  import { execFileSync as execFileSync5 } from "node:child_process";
77881
78680
  import { orchestration } from "@cleocode/core";
77882
- import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot65 } from "@cleocode/core/internal";
78681
+ import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot66 } from "@cleocode/core/internal";
77883
78682
  function formatRollupTable(rollup) {
77884
78683
  const waves = "waves" in rollup ? rollup.waves : [rollup];
77885
78684
  const lines = [];
@@ -78022,7 +78821,7 @@ var init_orchestrate3 = __esm({
78022
78821
  },
78023
78822
  async run({ args }) {
78024
78823
  const rateWindowHours = args.window !== void 0 ? Number.parseFloat(String(args.window)) : void 0;
78025
- const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot65(), {
78824
+ const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot66(), {
78026
78825
  ...rateWindowHours !== void 0 && Number.isFinite(rateWindowHours) && rateWindowHours > 0 ? { rateWindowHours } : {}
78027
78826
  });
78028
78827
  cliOutput(metrics, {
@@ -79482,7 +80281,7 @@ __export(project_exports, {
79482
80281
  import { resolve as resolve9 } from "node:path";
79483
80282
  import {
79484
80283
  CleoError as CleoError11,
79485
- getProjectRoot as getProjectRoot66,
80284
+ getProjectRoot as getProjectRoot67,
79486
80285
  moveProject,
79487
80286
  projectLifecycle,
79488
80287
  renameProject,
@@ -79504,7 +80303,7 @@ function emitEngineFailure(error, operation) {
79504
80303
  }
79505
80304
  function resolveRootOrFail(operation) {
79506
80305
  try {
79507
- return getProjectRoot66();
80306
+ return getProjectRoot67();
79508
80307
  } catch (err) {
79509
80308
  const code = err instanceof CleoError11 && typeof err.details?.["code"] === "string" ? err.details["code"] : "E_NOT_CLEO_PROJECT";
79510
80309
  emitEngineFailure(
@@ -79735,6 +80534,10 @@ var init_project = __esm({
79735
80534
  type: "string",
79736
80535
  description: "Name shown in Nexus, sent in plaintext (default: the project name). A name, never a path."
79737
80536
  },
80537
+ rebind: {
80538
+ type: "boolean",
80539
+ description: "Use only after E_NEXUS_REPLICA_COPIED: give this copy of the project a new replica id before attaching it (this machine was re-enrolled, or the store was copied). Each run mints a new id and leaves the old one on the server as stale history."
80540
+ },
79738
80541
  "api-url": NEXUS_API_URL_ARG,
79739
80542
  json: { type: "boolean", description: "Output raw JSON envelope.", default: false }
79740
80543
  },
@@ -79747,14 +80550,17 @@ var init_project = __esm({
79747
80550
  try {
79748
80551
  result = await linkProjectToNexus({
79749
80552
  apiUrl: nexusApiUrlArg(args),
79750
- ...typeof args["label"] === "string" && args["label"] ? { label: args["label"] } : {}
80553
+ ...typeof args["label"] === "string" && args["label"] ? { label: args["label"] } : {},
80554
+ ...args["rebind"] === true ? { rebind: true } : {}
79751
80555
  });
79752
80556
  } catch (err) {
79753
80557
  failNexus(err, "project.link");
79754
80558
  }
79755
- const { link } = result;
80559
+ const { link, replica } = result;
79756
80560
  const verb = result.alreadyLinked ? "Already linked" : "Linked";
79757
- const summary = `${verb}: project ${link.localProjectId} as "${link.label ?? ""}" on ${link.apiUrl}.`;
80561
+ const attached = replica ? ` This machine (device ${replica.deviceId}) holds it as replica ${replica.replicaId}${replica.reboundFrom ? ` (rebound from ${replica.reboundFrom})` : ""}${replica.presenceAt ? "; presence reported" : ""}.` : "";
80562
+ const summary = `${verb}: project ${link.localProjectId} as "${link.label ?? ""}" on ${link.apiUrl}.${attached}`;
80563
+ writeNexusWarnings(result.warnings);
79758
80564
  emitNexusResult(result, summary, "project", "project.link");
79759
80565
  }
79760
80566
  });
@@ -80332,7 +81138,7 @@ var refresh_memory_exports = {};
80332
81138
  __export(refresh_memory_exports, {
80333
81139
  refreshMemoryCommand: () => refreshMemoryCommand
80334
81140
  });
80335
- import { getProjectRoot as getProjectRoot67 } from "@cleocode/core";
81141
+ import { getProjectRoot as getProjectRoot68 } from "@cleocode/core";
80336
81142
  var refreshMemoryCommand;
80337
81143
  var init_refresh_memory = __esm({
80338
81144
  "packages/cleo/src/cli/commands/refresh-memory.ts"() {
@@ -80345,7 +81151,7 @@ var init_refresh_memory = __esm({
80345
81151
  description: "Regenerate .cleo/memory-bridge.md from brain.db"
80346
81152
  },
80347
81153
  async run() {
80348
- const projectDir = getProjectRoot67();
81154
+ const projectDir = getProjectRoot68();
80349
81155
  const { writeMemoryBridge } = await import("@cleocode/core/internal");
80350
81156
  const result = await writeMemoryBridge(projectDir);
80351
81157
  if (result.written) {
@@ -81931,7 +82737,7 @@ import fs3 from "node:fs";
81931
82737
  import path5 from "node:path";
81932
82738
  import {
81933
82739
  CleoError as CleoError13,
81934
- getProjectRoot as getProjectRoot68,
82740
+ getProjectRoot as getProjectRoot69,
81935
82741
  getTaskAccessor as getTaskAccessor3,
81936
82742
  parseConflictReport,
81937
82743
  setAtPath
@@ -81952,7 +82758,7 @@ var init_restore = __esm({
81952
82758
  description: "Apply manually-resolved conflicts from .cleo/restore-conflicts.md"
81953
82759
  },
81954
82760
  async run() {
81955
- const projectRoot = getProjectRoot68();
82761
+ const projectRoot = getProjectRoot69();
81956
82762
  const reportPath = path5.join(projectRoot, CLEO_DIR_NAME3, RESTORE_CONFLICTS_MD);
81957
82763
  if (!fs3.existsSync(reportPath)) {
81958
82764
  humanLine("No pending restore conflicts. Nothing to finalize.");
@@ -82881,8 +83687,8 @@ var init_saga = __esm({
82881
83687
  }
82882
83688
  },
82883
83689
  async run({ args }) {
82884
- const { sagas: sagas2, getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
82885
- const projectRoot = getProjectRoot74();
83690
+ const { sagas: sagas2, getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
83691
+ const projectRoot = getProjectRoot75();
82886
83692
  const sagaId = typeof args.sagaId === "string" && args.sagaId.length > 0 ? args.sagaId : void 0;
82887
83693
  const result = await sagas2.sagaNext(projectRoot, { sagaId });
82888
83694
  cliOutput(result.success ? result.data : result, { command: "saga", operation: "saga.next" });
@@ -84713,7 +85519,7 @@ var sequence_exports = {};
84713
85519
  __export(sequence_exports, {
84714
85520
  sequenceCommand: () => sequenceCommand
84715
85521
  });
84716
- import { getProjectRoot as getProjectRoot69 } from "@cleocode/core/internal";
85522
+ import { getProjectRoot as getProjectRoot70 } from "@cleocode/core/internal";
84717
85523
  var showCommand12, checkCommand7, repairCommand3, sequenceCommand;
84718
85524
  var init_sequence = __esm({
84719
85525
  "packages/cleo/src/cli/commands/sequence.ts"() {
@@ -84749,7 +85555,7 @@ var init_sequence = __esm({
84749
85555
  meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
84750
85556
  async run() {
84751
85557
  const { repairSequence } = await import("@cleocode/core/internal");
84752
- const projectRoot = getProjectRoot69();
85558
+ const projectRoot = getProjectRoot70();
84753
85559
  const repair = await repairSequence(projectRoot);
84754
85560
  const result = {
84755
85561
  repaired: repair.repaired,
@@ -85346,8 +86152,8 @@ var init_session4 = __esm({
85346
86152
  "audit-scope": { type: "string", description: "Audit log scope (global|local)" }
85347
86153
  },
85348
86154
  async run({ args }) {
85349
- const { detectSessionDrift, getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
85350
- const projectRoot = await getProjectRoot74();
86155
+ const { detectSessionDrift, getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
86156
+ const projectRoot = await getProjectRoot75();
85351
86157
  const scope = args["audit-scope"] === "local" ? "local" : "global";
85352
86158
  const report = await detectSessionDrift({ projectRoot, auditScope: scope });
85353
86159
  cliOutput(report, { command: "session drift", operation: "session.drift" });
@@ -88048,13 +88854,13 @@ var init_telemetry2 = __esm({
88048
88854
  // packages/cleo/src/cli/commands/templates/lib.ts
88049
88855
  import { readFileSync as readFileSync13 } from "node:fs";
88050
88856
  import { isAbsolute as isAbsolute3, resolve as resolve10 } from "node:path";
88051
- import { getProjectRoot as getProjectRoot70 } from "@cleocode/core";
88857
+ import { getProjectRoot as getProjectRoot71 } from "@cleocode/core";
88052
88858
  import { resolveSourcePathAbsolute } from "@cleocode/core/templates/registry";
88053
88859
  function resolveProjectRoot6(raw) {
88054
88860
  if (typeof raw === "string" && raw.length > 0) {
88055
88861
  return isAbsolute3(raw) ? raw : resolve10(process.cwd(), raw);
88056
88862
  }
88057
- return getProjectRoot70();
88863
+ return getProjectRoot71();
88058
88864
  }
88059
88865
  function readTemplateSource(entry) {
88060
88866
  const sourceAbsolute = resolveSourcePathAbsolute(entry);
@@ -88838,7 +89644,7 @@ __export(token_exports, {
88838
89644
  tokenCommand: () => tokenCommand
88839
89645
  });
88840
89646
  import { readFileSync as readFileSync17 } from "node:fs";
88841
- import { getProjectRoot as getProjectRoot71, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
89647
+ import { getProjectRoot as getProjectRoot72, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
88842
89648
  function readPayload(args, textKey, fileKey) {
88843
89649
  const text = args[textKey];
88844
89650
  const file = args[fileKey];
@@ -89002,7 +89808,7 @@ var init_token = __esm({
89002
89808
  domain: args.domain,
89003
89809
  operation: args.operation
89004
89810
  };
89005
- const result = args.record ? await recordTokenExchange2(getProjectRoot71(), input2) : await measureTokenExchange(input2);
89811
+ const result = args.record ? await recordTokenExchange2(getProjectRoot72(), input2) : await measureTokenExchange(input2);
89006
89812
  cliOutput(result, {
89007
89813
  command: "token",
89008
89814
  operation: args.record ? "admin.token.record" : "token.estimate"
@@ -89038,7 +89844,7 @@ __export(transcript_exports, {
89038
89844
  });
89039
89845
  import { homedir as homedir3 } from "node:os";
89040
89846
  import { join as join35 } from "node:path";
89041
- import { getProjectRoot as getProjectRoot72 } from "@cleocode/core";
89847
+ import { getProjectRoot as getProjectRoot73 } from "@cleocode/core";
89042
89848
  import {
89043
89849
  parseDurationMs,
89044
89850
  pruneTranscripts,
@@ -89068,7 +89874,7 @@ var init_transcript = __esm({
89068
89874
  async run({ args }) {
89069
89875
  if (args.pending) {
89070
89876
  try {
89071
- const projectRoot = getProjectRoot72();
89877
+ const projectRoot = getProjectRoot73();
89072
89878
  const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
89073
89879
  const pending = await scanPendingTranscripts(projectRoot);
89074
89880
  cliOutput(
@@ -89165,7 +89971,7 @@ var init_transcript = __esm({
89165
89971
  async run({ args }) {
89166
89972
  const tier = args.tier ?? "warm";
89167
89973
  const dryRun = args["dry-run"] ?? false;
89168
- const projectRoot = getProjectRoot72();
89974
+ const projectRoot = getProjectRoot73();
89169
89975
  try {
89170
89976
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
89171
89977
  const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -89281,7 +90087,7 @@ var init_transcript = __esm({
89281
90087
  const dryRun = args["dry-run"] ?? false;
89282
90088
  const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
89283
90089
  const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
89284
- const projectRoot = getProjectRoot72();
90090
+ const projectRoot = getProjectRoot73();
89285
90091
  try {
89286
90092
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
89287
90093
  const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -91219,9 +92025,9 @@ var init_verify = __esm({
91219
92025
  return;
91220
92026
  }
91221
92027
  const { recordTaskDone } = await import("@cleocode/core/tasks/done-record.js");
91222
- const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/paths.js");
92028
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/paths.js");
91223
92029
  const r = await recordTaskDone(args.taskId, {
91224
- projectRoot: getProjectRoot74(),
92030
+ projectRoot: getProjectRoot75(),
91225
92031
  ...parsed.options,
91226
92032
  ...args.agent ? { agent: args.agent } : {}
91227
92033
  });
@@ -91644,9 +92450,9 @@ var init_workgraph2 = __esm({
91644
92450
  },
91645
92451
  async run({ args }) {
91646
92452
  const { generatePlanningDoc } = await import("@cleocode/core/workgraph");
91647
- const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
92453
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
91648
92454
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
91649
- const projectRoot = getProjectRoot74();
92455
+ const projectRoot = getProjectRoot75();
91650
92456
  const audience = String(args.audience) === "agent" ? "agent" : "maintainer";
91651
92457
  const result = await generatePlanningDoc(projectRoot, {
91652
92458
  sagaId: String(args.sagaId),
@@ -91663,9 +92469,9 @@ var init_workgraph2 = __esm({
91663
92469
  async run() {
91664
92470
  const { validateWorkGraphStructure } = await import("@cleocode/core/workgraph");
91665
92471
  const { taskList: taskList2 } = await import("@cleocode/core/internal");
91666
- const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
92472
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
91667
92473
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
91668
- const projectRoot = getProjectRoot74();
92474
+ const projectRoot = getProjectRoot75();
91669
92475
  const listResult = await taskList2(projectRoot, { limit: 5e3 });
91670
92476
  const tasks = listResult.success ? listResult.data?.tasks ?? [] : [];
91671
92477
  const nodes = tasks.map((t) => ({
@@ -91684,9 +92490,9 @@ var init_workgraph2 = __esm({
91684
92490
  description: "One-shot saga-to-saga workgraph dashboard (tracking checklist)"
91685
92491
  },
91686
92492
  async run() {
91687
- const { sagas: sagas2, getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
92493
+ const { sagas: sagas2, getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
91688
92494
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
91689
- const projectRoot = getProjectRoot74();
92495
+ const projectRoot = getProjectRoot75();
91690
92496
  const listResult = await sagas2.sagaList(projectRoot);
91691
92497
  if (!listResult.success) {
91692
92498
  cliOutput2(listResult, { command: "workgraph", operation: "workgraph.status" });
@@ -91752,7 +92558,7 @@ __export(worktree_exports, {
91752
92558
  worktreeCommand: () => worktreeCommand
91753
92559
  });
91754
92560
  import readline4 from "node:readline";
91755
- import { getProjectRoot as getProjectRoot73, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
92561
+ import { getProjectRoot as getProjectRoot74, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
91756
92562
  async function promptYesNo2(question) {
91757
92563
  return new Promise((resolve13) => {
91758
92564
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
@@ -91857,7 +92663,7 @@ var init_worktree3 = __esm({
91857
92663
  const staleDays = staleDaysRaw !== void 0 ? Number.parseInt(staleDaysRaw, 10) : void 0;
91858
92664
  const idleDaysRaw = typeof args["idle-days"] === "string" ? args["idle-days"] : void 0;
91859
92665
  const idleDays = idleDaysRaw !== void 0 ? Number.parseInt(idleDaysRaw, 10) : void 0;
91860
- const projectRoot = getProjectRoot73();
92666
+ const projectRoot = getProjectRoot74();
91861
92667
  const listResult = await listWorktrees2({
91862
92668
  projectRoot,
91863
92669
  ...staleDays !== void 0 && !Number.isNaN(staleDays) ? { staleDays } : {}
@@ -92307,6 +93113,12 @@ var COMMAND_MANIFEST = [
92307
93113
  description: "Classify a task: readiness verdict (proceed|grill) + persona routing (agent, confidence)",
92308
93114
  load: async () => (await Promise.resolve().then(() => (init_classify(), classify_exports))).classifyCommand
92309
93115
  },
93116
+ {
93117
+ exportName: "cloudCommand",
93118
+ name: "cloud",
93119
+ description: "Cleo Nexus reads with the device credential (GET only; getting the credential may upgrade a 9.24 session or retry unsettled logouts): status (one-call verification), whoami, devices, projects [show].",
93120
+ load: async () => (await Promise.resolve().then(() => (init_cloud(), cloud_exports))).cloudCommand
93121
+ },
92310
93122
  {
92311
93123
  exportName: "codeCommand",
92312
93124
  name: "code",
@@ -92475,6 +93287,12 @@ var COMMAND_MANIFEST = [
92475
93287
  description: "Walk every DB in the inventory + report integrity, row counts, orphan dirs. ",
92476
93288
  load: async () => (await Promise.resolve().then(() => (init_doctor_db_substrate(), doctor_db_substrate_exports))).doctorDbSubstrateCommand
92477
93289
  },
93290
+ {
93291
+ exportName: "doctorDepCyclesCommand",
93292
+ name: "dep-cycles",
93293
+ description: "Report task dependency cycles already stored (edges written before the T12886 cycle ",
93294
+ load: async () => (await Promise.resolve().then(() => (init_doctor_dep_cycles(), doctor_dep_cycles_exports))).doctorDepCyclesCommand
93295
+ },
92478
93296
  {
92479
93297
  exportName: "doctorExodusResidueCommand",
92480
93298
  name: "exodus-residue",
@@ -92826,7 +93644,7 @@ var COMMAND_MANIFEST = [
92826
93644
  {
92827
93645
  exportName: "logoutCommand",
92828
93646
  name: "logout",
92829
- description: "Sign out. cleo logout [nexus] revokes the Cleo Nexus session server-side and deletes the stored token; cleo logout <provider> [label] removes an LLM credential exactly like cleo auth remove (the label may be omitted when the provider has one credential).",
93647
+ description: "Sign out. cleo logout [nexus] signs this machine out of Cleo Nexus (the device keeps its id for the next login; --revoke burns it), confirmed by the server; cleo logout <provider> [label] removes an LLM credential exactly like cleo auth remove (the label may be omitted when the provider has one credential).",
92830
93648
  load: async () => (await Promise.resolve().then(() => (init_logout(), logout_exports))).logoutCommand
92831
93649
  },
92832
93650
  {
@@ -93823,7 +94641,7 @@ async function runStartupMaintenance() {
93823
94641
  detectAndRemoveStrayProjectNexus,
93824
94642
  getGlobalSalt,
93825
94643
  getLogger: getLogger22,
93826
- getProjectRoot: getProjectRoot74,
94644
+ getProjectRoot: getProjectRoot75,
93827
94645
  isCleanupMarkerSet,
93828
94646
  isMissingProjectError,
93829
94647
  migrateSignaldockToConduit,
@@ -93833,7 +94651,7 @@ async function runStartupMaintenance() {
93833
94651
  } = await import("@cleocode/core/internal");
93834
94652
  let projectRootForCleanup = "";
93835
94653
  try {
93836
- projectRootForCleanup = getProjectRoot74();
94654
+ projectRootForCleanup = getProjectRoot75();
93837
94655
  } catch {
93838
94656
  }
93839
94657
  if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
@@ -93853,7 +94671,7 @@ async function runStartupMaintenance() {
93853
94671
  const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
93854
94672
  if (!isInitInvocation) {
93855
94673
  try {
93856
- const _projectRootForMigration = getProjectRoot74();
94674
+ const _projectRootForMigration = getProjectRoot75();
93857
94675
  if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
93858
94676
  const migrationResult = await migrateSignaldockToConduit(_projectRootForMigration);
93859
94677
  if (migrationResult.status === "failed") {