@cleocode/cleo 2026.9.26 → 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 +721 -48
  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/{CobI0XAU.js → BpRY8_m9.js} +1 -1
  5. package/studio-dist/client/_app/immutable/chunks/{BhOwHRY9.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.DaDdqQTe.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.CKHiZeuP.js → 0.BuXCTiZp.js} +1 -1
  10. package/studio-dist/client/_app/immutable/nodes/{1.CmaYPYrk.js → 1.CsO1BGsz.js} +1 -1
  11. package/studio-dist/client/_app/immutable/nodes/{15.D23qtyoz.js → 15.Bp-qXNPk.js} +1 -1
  12. package/studio-dist/client/_app/immutable/nodes/{16.Dtt6exbd.js → 16.DMXWbK7I.js} +1 -1
  13. package/studio-dist/client/_app/immutable/nodes/{17.CPZ22rBo.js → 17.CVLdfMFL.js} +1 -1
  14. package/studio-dist/client/_app/immutable/nodes/{18.Qm_fekS5.js → 18.CyQUos9v.js} +1 -1
  15. package/studio-dist/client/_app/immutable/nodes/{20.DjGgB4KD.js → 20.Dx3wZ86J.js} +1 -1
  16. package/studio-dist/client/_app/immutable/nodes/{24.CgMoobl_.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.C1oRqB1b.js → 26.U1MxbYsk.js} +1 -1
  19. package/studio-dist/client/_app/immutable/nodes/{3.Cy4T6zbv.js → 3.CUHmTi6Q.js} +1 -1
  20. package/studio-dist/client/_app/version.json +1 -1
  21. package/studio-dist/server/chunks/{0-G8NhADpo.js → 0-Ban8NQ70.js} +3 -3
  22. package/studio-dist/server/chunks/1-CZPXu25_.js +9 -0
  23. package/studio-dist/server/chunks/{15-o63WM4MZ.js → 15-C2ukbZuI.js} +3 -3
  24. package/studio-dist/server/chunks/{16-7h8G4VoG.js → 16-C-gWtKZb.js} +3 -3
  25. package/studio-dist/server/chunks/{17-DcShICKv.js → 17-CzQ5BDNx.js} +3 -3
  26. package/studio-dist/server/chunks/{18-BER3ZYEh.js → 18-Cnqp0uMS.js} +3 -3
  27. package/studio-dist/server/chunks/{20-DErTM2qU.js → 20-D9243OmI.js} +3 -3
  28. package/studio-dist/server/chunks/{24-BZh7ZC1u.js → 24-D-3OyyjO.js} +3 -3
  29. package/studio-dist/server/chunks/{25-qqsEYb5C.js → 25-BC8dXyIT.js} +4 -4
  30. package/studio-dist/server/chunks/{26-C424QBHc.js → 26-DIYVHPeE.js} +3 -3
  31. package/studio-dist/server/chunks/{3-DDisSHuV.js → 3-DDNPJWI0.js} +3 -3
  32. package/studio-dist/server/chunks/{_layout.svelte-DcfphVWO.js → _layout.svelte-ouauc7nn.js} +4 -4
  33. package/studio-dist/server/chunks/{_page.svelte-B4hg1b3p.js → _page.svelte-B7CTgxGI.js} +4 -4
  34. package/studio-dist/server/chunks/{_page.svelte-DBbdqQsp.js → _page.svelte-BKEo8OSf.js} +3 -3
  35. package/studio-dist/server/chunks/{_page.svelte-BjX_VPfv.js → _page.svelte-Ba45egd6.js} +3 -3
  36. package/studio-dist/server/chunks/{_page.svelte-C8Ybsn2v.js → _page.svelte-BlIGw3KR.js} +3 -3
  37. package/studio-dist/server/chunks/{_page.svelte-CWNRWa2L.js → _page.svelte-CkagR7NW.js} +3 -3
  38. package/studio-dist/server/chunks/{_page.svelte-EPu-M4nY.js → _page.svelte-DS8uziG5.js} +3 -3
  39. package/studio-dist/server/chunks/{_page.svelte-DdaHffLO.js → _page.svelte-DU-KSkGO.js} +3 -3
  40. package/studio-dist/server/chunks/{_page.svelte-CPdHIklX.js → _page.svelte-ZzSjr8MT.js} +5 -5
  41. package/studio-dist/server/chunks/{_page.svelte-DuD1vdhl.js → _page.svelte-ez5VvNrn.js} +3 -3
  42. package/studio-dist/server/chunks/{_server.ts-BjIJy4O3.js → _server.ts-CBaXrLT0.js} +2 -2
  43. package/studio-dist/server/chunks/{_server.ts-C4WHkBZ_.js → _server.ts-D0rSedle.js} +3 -3
  44. package/studio-dist/server/chunks/{_server.ts-wZKCwtFH.js → _server.ts-DMqfOwim.js} +3 -3
  45. package/studio-dist/server/chunks/{_server.ts-CmiJfYD5.js → _server.ts-DNL_pHM3.js} +3 -3
  46. package/studio-dist/server/chunks/{_server.ts-BGuhOntH.js → _server.ts-DYCIQvnl.js} +3 -3
  47. package/studio-dist/server/chunks/{client-ARinjJG0.js → client-CM2Un2n3.js} +2 -2
  48. package/studio-dist/server/chunks/{dist-CLTFgJWk.js → dist-BUqYzm8B.js} +246 -1
  49. package/studio-dist/server/chunks/{error.svelte-m5N9iUFN.js → error.svelte-ZYrc30ps.js} +3 -3
  50. package/studio-dist/server/chunks/{http-DKP1pqq1.js → http-Dc9ezTZW.js} +2 -2
  51. package/studio-dist/server/chunks/{internal-BF6KxfEH.js → internal-BkiUrFap.js} +2 -2
  52. package/studio-dist/server/chunks/{stores-UvZbmzhQ.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/B2oT_qgu.js +0 -3
  56. package/studio-dist/client/_app/immutable/chunks/B7RPHy-R.js +0 -1
  57. package/studio-dist/client/_app/immutable/entry/start.BjuNqpl1.js +0 -1
  58. package/studio-dist/client/_app/immutable/nodes/25.DkFAoI4l.js +0 -39
  59. package/studio-dist/server/chunks/1-CfXNxnLm.js +0 -9
package/dist/cli/index.js CHANGED
@@ -22759,8 +22759,10 @@ var init_nexus_account = __esm({
22759
22759
  "E_NEXUS_BUSY",
22760
22760
  /** Several accounts hold a device credential on one origin and none was named. */
22761
22761
  "E_NEXUS_ACCOUNT_AMBIGUOUS",
22762
- /** An option that needs device credentials (`--read-only`) without `CLEO_NEXUS_DEVICE=1`. */
22763
- "E_NEXUS_DEVICE_REQUIRED"
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"
22764
22766
  ];
22765
22767
  nexusAccountUserSchema = z25.object({
22766
22768
  id: z25.string(),
@@ -22782,6 +22784,340 @@ var init_nexus_account = __esm({
22782
22784
  }
22783
22785
  });
22784
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
+
22785
23121
  // packages/contracts/src/task-id.ts
22786
23122
  function isTaskId(value) {
22787
23123
  return typeof value === "string" && TASK_ID_REGEX.test(value);
@@ -22849,6 +23185,7 @@ __export(src_exports, {
22849
23185
  CHANNEL_BOUNDARY_REGISTRY: () => CHANNEL_BOUNDARY_REGISTRY,
22850
23186
  CLEO_CONFIG_MANIFEST: () => CLEO_CONFIG_MANIFEST,
22851
23187
  CLI_CATEGORY_ORDER: () => CLI_CATEGORY_ORDER,
23188
+ CLOUD_STATUS_VERDICTS: () => CLOUD_STATUS_VERDICTS,
22852
23189
  COLLECTION_IDENTITY_FIELDS: () => COLLECTION_IDENTITY_FIELDS,
22853
23190
  COLLECTION_KEYS: () => COLLECTION_KEYS,
22854
23191
  CONFIG_MANIFEST_ENTRIES: () => CONFIG_MANIFEST_ENTRIES,
@@ -22963,10 +23300,27 @@ __export(src_exports, {
22963
23300
  MonitorResponseSchema: () => MonitorResponseSchema,
22964
23301
  NEXUS_ACCOUNT_ERROR_CODES: () => NEXUS_ACCOUNT_ERROR_CODES,
22965
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,
22966
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,
22967
23310
  NEXUS_FLEET_SCHEMA_VERSION: () => NEXUS_FLEET_SCHEMA_VERSION,
23311
+ NEXUS_FORBIDDEN_ERRORS: () => NEXUS_FORBIDDEN_ERRORS,
23312
+ NEXUS_FORBIDDEN_REASONS: () => NEXUS_FORBIDDEN_REASONS,
22968
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,
22969
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,
22970
23324
  OPEN_SYSTEM_KEY_PREFIXES: () => OPEN_SYSTEM_KEY_PREFIXES,
22971
23325
  OPERATIONS: () => OPERATIONS,
22972
23326
  OPERATION_RESULT_SCHEMAS: () => OPERATION_RESULT_SCHEMAS,
@@ -23246,6 +23600,21 @@ __export(src_exports, {
23246
23600
  nexusAccountMeSchema: () => nexusAccountMeSchema,
23247
23601
  nexusAccountOrganizationSchema: () => nexusAccountOrganizationSchema,
23248
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,
23249
23618
  normalizeError: () => normalizeError,
23250
23619
  noteAtomSchema: () => noteAtomSchema,
23251
23620
  noulDecisionAnswerSchema: () => noulDecisionAnswerSchema,
@@ -23426,6 +23795,7 @@ var init_src2 = __esm({
23426
23795
  init_decide();
23427
23796
  init_decide_sites();
23428
23797
  init_nexus_account();
23798
+ init_nexus_cloud();
23429
23799
  init_task_id();
23430
23800
  }
23431
23801
  });
@@ -36353,7 +36723,7 @@ function parseAgenticNode(raw, base, index) {
36353
36723
  inputs = acc;
36354
36724
  }
36355
36725
  const context_files = parseStringArray(raw.context_files, `nodes[${index}].context_files`);
36356
- const profile = parseOptionalNonEmptyString(raw.profile, `nodes[${index}].profile`);
36726
+ const profile2 = parseOptionalNonEmptyString(raw.profile, `nodes[${index}].profile`);
36357
36727
  const model = parseOptionalNonEmptyString(raw.model, `nodes[${index}].model`);
36358
36728
  const provider = parseOptionalNonEmptyString(raw.provider, `nodes[${index}].provider`);
36359
36729
  const allowed_skills = parseStringArray(raw.allowed_skills, `nodes[${index}].allowed_skills`);
@@ -36366,7 +36736,7 @@ function parseAgenticNode(raw, base, index) {
36366
36736
  role,
36367
36737
  inputs,
36368
36738
  ...context_files !== void 0 ? { context_files } : {},
36369
- ...profile !== void 0 ? { profile } : {},
36739
+ ...profile2 !== void 0 ? { profile: profile2 } : {},
36370
36740
  ...model !== void 0 ? { model } : {},
36371
36741
  ...provider !== void 0 ? { provider } : {},
36372
36742
  ...allowed_skills !== void 0 ? { allowed_skills } : {},
@@ -47610,8 +47980,8 @@ var init_agent_outputs = __esm({
47610
47980
  });
47611
47981
 
47612
47982
  // packages/cleo/src/cli/commands/agent-profile-status.ts
47613
- function computeProfileStatus(profile, validation) {
47614
- if (profile === null) return "none";
47983
+ function computeProfileStatus(profile2, validation) {
47984
+ if (profile2 === null) return "none";
47615
47985
  if (validation === null) return "loaded (unvalidated)";
47616
47986
  if (validation.valid) return "validated";
47617
47987
  return `invalid (${validation.errors.length} errors)`;
@@ -47916,16 +48286,16 @@ agent ${agentId}:
47916
48286
  process.exitCode = 1;
47917
48287
  return;
47918
48288
  }
47919
- let profile = null;
48289
+ let profile2 = null;
47920
48290
  let cantValidation = null;
47921
48291
  const cantPath = args.cant ?? join40(CLEO_DIR_NAME3, AGENTS_SUBDIR, `${args.agentId}.cant`);
47922
48292
  if (existsSync22(cantPath)) {
47923
- profile = readFileSync22(cantPath, "utf-8");
48293
+ profile2 = readFileSync22(cantPath, "utf-8");
47924
48294
  try {
47925
48295
  const cantModule = await import("@cleocode/cant");
47926
48296
  const validate = "validate" in cantModule ? cantModule.validate : null;
47927
48297
  if (validate) {
47928
- const result = validate(profile);
48298
+ const result = validate(profile2);
47929
48299
  cantValidation = {
47930
48300
  valid: result.valid,
47931
48301
  errors: result.diagnostics?.map((d) => d.message) ?? []
@@ -47968,7 +48338,7 @@ agent ${agentId}:
47968
48338
  transport: runtime.transport.name,
47969
48339
  // Surfaced for operator visibility only — see
47970
48340
  // computeProfileStatus tsdoc for the four possible values.
47971
- profile: computeProfileStatus(profile, cantValidation),
48341
+ profile: computeProfileStatus(profile2, cantValidation),
47972
48342
  services: {
47973
48343
  poller: "running",
47974
48344
  heartbeat: runtime.heartbeat ? "running" : "disabled",
@@ -50647,15 +51017,24 @@ function nexusApiUrlArg(args) {
50647
51017
  function failNexus(err, operation) {
50648
51018
  const code = err instanceof Error && "code" in err && typeof err.code === "string" ? err.code : void 0;
50649
51019
  const fix = err instanceof Error && "fix" in err && typeof err.fix === "string" ? err.fix : void 0;
50650
- const exitCode = code === "E_NEXUS_INVALID_API_URL" || code === "E_NEXUS_INVALID_LABEL" || code === "E_NEXUS_DEVICE_REQUIRED" ? 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;
50651
51022
  cliError(
50652
51023
  err instanceof Error ? err.message : String(err),
50653
51024
  exitCode,
50654
- { name: code ?? "E_NEXUS_REQUEST_FAILED", ...fix ? { fix } : {} },
51025
+ {
51026
+ name: code ?? "E_NEXUS_REQUEST_FAILED",
51027
+ ...fix ? { fix } : {},
51028
+ ...details ? { details } : {}
51029
+ },
50655
51030
  { operation }
50656
51031
  );
50657
51032
  process.exit(exitCode);
50658
51033
  }
51034
+ function writeNexusWarnings(warnings) {
51035
+ for (const warning of warnings) process.stderr.write(`warning: ${warning}
51036
+ `);
51037
+ }
50659
51038
  function emitNexusResult(data, summary, command, operation) {
50660
51039
  if (isHumanOutput()) humanLine(summary);
50661
51040
  else cliOutput(data, { command, operation });
@@ -50670,9 +51049,11 @@ async function runNexusLogin(args, openBrowser2) {
50670
51049
  "@cleocode/core/cloud/nexus-device.js"
50671
51050
  );
50672
51051
  const noBrowser = negatedFlag(args, "browser");
51052
+ let codeShown = false;
50673
51053
  const hooks2 = {
50674
51054
  apiUrl: nexusApiUrlArg(args),
50675
51055
  onCode: (code) => {
51056
+ codeShown = true;
50676
51057
  writeDeviceCodePrompt(code, SERVICE_NAME);
50677
51058
  if (!noBrowser) openBrowser2(code.verificationUriComplete ?? code.verificationUri);
50678
51059
  },
@@ -50687,7 +51068,7 @@ async function runNexusLogin(args, openBrowser2) {
50687
51068
  ),
50688
51069
  {
50689
51070
  code: "E_NEXUS_DEVICE_REQUIRED",
50690
- fix: "set CLEO_NEXUS_DEVICE=1 to enrol a read-only device, or log in without --read-only"
51071
+ fix: "unset CLEO_NEXUS_DEVICE (=0 turns device credentials off) to enrol a read-only device, or log in without --read-only"
50691
51072
  }
50692
51073
  );
50693
51074
  }
@@ -50706,12 +51087,22 @@ async function runNexusLogin(args, openBrowser2) {
50706
51087
  } else {
50707
51088
  if (name !== void 0) {
50708
51089
  process.stderr.write(
50709
- "warning: --name needs device credentials (CLEO_NEXUS_DEVICE=1); ignored\n"
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
+ `
50710
51101
  );
50711
51102
  }
50712
51103
  result = await loginToNexus(hooks2);
50713
51104
  }
50714
- writeDeviceCodeApproved(SERVICE_NAME);
51105
+ if (codeShown) writeDeviceCodeApproved(SERVICE_NAME);
50715
51106
  for (const warning of result.warnings) process.stderr.write(`warning: ${warning}
50716
51107
  `);
50717
51108
  return result;
@@ -50726,6 +51117,41 @@ function nexusLoginSummary(r) {
50726
51117
  const device = r.device ? ` This machine is device ${r.device.deviceId}${r.device.name ? ` (${r.device.name})` : ""}, profile ${r.device.profile ?? "unknown"}.` : "";
50727
51118
  return `Signed in to ${r.apiUrl} as ${who}${org}.${device}`;
50728
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");
51154
+ }
50729
51155
  var SERVICE_NAME, NEXUS_API_URL_ARG;
50730
51156
  var init_nexus_account_cli = __esm({
50731
51157
  "packages/cleo/src/cli/lib/nexus-account-cli.ts"() {
@@ -51071,13 +51497,13 @@ function _errorResult(code, message, meta) {
51071
51497
  }
51072
51498
  async function runLlmLogin(provider, opts) {
51073
51499
  const meta = { operation: "llm.login", timestamp: (/* @__PURE__ */ new Date()).toISOString() };
51074
- const profile = await getProviderProfile(provider);
51075
- const oauthMode = profile?.oauth?.mode;
51500
+ const profile2 = await getProviderProfile(provider);
51501
+ const oauthMode = profile2?.oauth?.mode;
51076
51502
  if (provider === "kimi-code" || oauthMode === "device-code") {
51077
51503
  return _runKimiCodeLogin(opts, meta);
51078
51504
  }
51079
51505
  if (oauthMode === "pkce") {
51080
- return _runPkceLogin(profile.name, profile.oauth, opts, meta);
51506
+ return _runPkceLogin(profile2.name, profile2.oauth, opts, meta);
51081
51507
  }
51082
51508
  return _errorResult(
51083
51509
  "E_NOT_IMPLEMENTED",
@@ -51615,11 +52041,11 @@ var init_login = __esm({
51615
52041
  },
51616
52042
  "read-only": {
51617
52043
  type: "boolean",
51618
- description: "nexus with CLEO_NEXUS_DEVICE=1: enrol this machine with the read-only device profile (account, devices and project reads only). Refused without CLEO_NEXUS_DEVICE=1."
52044
+ description: "nexus: enrol this machine with the read-only device profile (account, devices and project reads only). Refused with CLEO_NEXUS_DEVICE=0."
51619
52045
  },
51620
52046
  name: {
51621
52047
  type: "string",
51622
- description: "nexus with CLEO_NEXUS_DEVICE=1: device name shown on cleocode.dev (default: OS, arch and a short id; never the hostname)."
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."
51623
52049
  },
51624
52050
  auth: {
51625
52051
  type: "string",
@@ -55639,6 +56065,252 @@ var init_classify = __esm({
55639
56065
  }
55640
56066
  });
55641
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
+
55642
56314
  // packages/cleo/src/cli/commands/code.ts
55643
56315
  var code_exports = {};
55644
56316
  __export(code_exports, {
@@ -67559,7 +68231,7 @@ function showStatus() {
67559
68231
  }
67560
68232
  cliOutput(result, { command: "exodus status" });
67561
68233
  }
67562
- var migrateSubCommand, verifySubCommand, sealSubCommand, statusSubCommand, exodusCommand;
68234
+ var migrateSubCommand, verifySubCommand, sealSubCommand, statusSubCommand2, exodusCommand;
67563
68235
  var init_exodus = __esm({
67564
68236
  "packages/cleo/src/cli/commands/exodus.ts"() {
67565
68237
  "use strict";
@@ -67869,7 +68541,7 @@ Passing tables (${passing.length}):`);
67869
68541
  );
67870
68542
  }
67871
68543
  });
67872
- statusSubCommand = defineCommand({
68544
+ statusSubCommand2 = defineCommand({
67873
68545
  meta: {
67874
68546
  name: "status",
67875
68547
  description: "Show exodus migration status (staging, source DBs, target DBs)"
@@ -67887,7 +68559,7 @@ Passing tables (${passing.length}):`);
67887
68559
  migrate: migrateSubCommand,
67888
68560
  verify: verifySubCommand,
67889
68561
  seal: sealSubCommand,
67890
- status: statusSubCommand
68562
+ status: statusSubCommand2
67891
68563
  },
67892
68564
  async run({ cmd, rawArgs }) {
67893
68565
  if (isSubCommandDispatch(rawArgs, cmd.subCommands)) return;
@@ -71660,8 +72332,8 @@ async function resolveDefaultModel(provider) {
71660
72332
  "@cleocode/core/llm/role-resolver.js"
71661
72333
  )
71662
72334
  ]);
71663
- const profile = await getProviderProfile2(provider);
71664
- return profile?.defaultModel ?? IMPLICIT_FALLBACK_MODEL;
72335
+ const profile2 = await getProviderProfile2(provider);
72336
+ return profile2?.defaultModel ?? IMPLICIT_FALLBACK_MODEL;
71665
72337
  }
71666
72338
  async function runLlmStream(opts) {
71667
72339
  const stdout2 = opts.stdout ?? process.stdout;
@@ -72519,14 +73191,8 @@ var init_log = __esm({
72519
73191
  // packages/cleo/src/cli/commands/logout.ts
72520
73192
  var logout_exports = {};
72521
73193
  __export(logout_exports, {
72522
- logoutCommand: () => logoutCommand,
72523
- nexusLogoutSummary: () => nexusLogoutSummary
73194
+ logoutCommand: () => logoutCommand
72524
73195
  });
72525
- function nexusLogoutSummary(r) {
72526
- if (!r.removedLocally) return `Not signed in to ${r.apiUrl}; nothing to do.`;
72527
- 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)";
72528
- return `Signed out of ${r.apiUrl}: ${server}; local token deleted.`;
72529
- }
72530
73196
  var logoutCommand;
72531
73197
  var init_logout = __esm({
72532
73198
  "packages/cleo/src/cli/commands/logout.ts"() {
@@ -72538,7 +73204,7 @@ var init_logout = __esm({
72538
73204
  logoutCommand = defineCommand({
72539
73205
  meta: {
72540
73206
  name: "logout",
72541
- 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)."
72542
73208
  },
72543
73209
  args: {
72544
73210
  target: {
@@ -72552,6 +73218,10 @@ var init_logout = __esm({
72552
73218
  required: false
72553
73219
  },
72554
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
+ },
72555
73225
  json: { type: "boolean", description: "Output as JSON envelope" }
72556
73226
  },
72557
73227
  async run({ args }) {
@@ -72566,17 +73236,7 @@ var init_logout = __esm({
72566
73236
  emitLlmCredentialRemoval(await removeLlmCredential(target, label), "logout", "logout.run");
72567
73237
  return;
72568
73238
  }
72569
- const { logoutFromNexus } = await import(
72570
- /* webpackIgnore: true */
72571
- "@cleocode/core/cloud/nexus-auth.js"
72572
- );
72573
- let result;
72574
- try {
72575
- result = await logoutFromNexus({ apiUrl: nexusApiUrlArg(a) });
72576
- } catch (err) {
72577
- failNexus(err, "logout.run");
72578
- }
72579
- emitNexusResult(result, nexusLogoutSummary(result), "logout", "logout.run");
73239
+ await runNexusDeviceLogout(a);
72580
73240
  }
72581
73241
  });
72582
73242
  }
@@ -79874,6 +80534,10 @@ var init_project = __esm({
79874
80534
  type: "string",
79875
80535
  description: "Name shown in Nexus, sent in plaintext (default: the project name). A name, never a path."
79876
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
+ },
79877
80541
  "api-url": NEXUS_API_URL_ARG,
79878
80542
  json: { type: "boolean", description: "Output raw JSON envelope.", default: false }
79879
80543
  },
@@ -79886,14 +80550,17 @@ var init_project = __esm({
79886
80550
  try {
79887
80551
  result = await linkProjectToNexus({
79888
80552
  apiUrl: nexusApiUrlArg(args),
79889
- ...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 } : {}
79890
80555
  });
79891
80556
  } catch (err) {
79892
80557
  failNexus(err, "project.link");
79893
80558
  }
79894
- const { link } = result;
80559
+ const { link, replica } = result;
79895
80560
  const verb = result.alreadyLinked ? "Already linked" : "Linked";
79896
- 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);
79897
80564
  emitNexusResult(result, summary, "project", "project.link");
79898
80565
  }
79899
80566
  });
@@ -92446,6 +93113,12 @@ var COMMAND_MANIFEST = [
92446
93113
  description: "Classify a task: readiness verdict (proceed|grill) + persona routing (agent, confidence)",
92447
93114
  load: async () => (await Promise.resolve().then(() => (init_classify(), classify_exports))).classifyCommand
92448
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
+ },
92449
93122
  {
92450
93123
  exportName: "codeCommand",
92451
93124
  name: "code",
@@ -92971,7 +93644,7 @@ var COMMAND_MANIFEST = [
92971
93644
  {
92972
93645
  exportName: "logoutCommand",
92973
93646
  name: "logout",
92974
- 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).",
92975
93648
  load: async () => (await Promise.resolve().then(() => (init_logout(), logout_exports))).logoutCommand
92976
93649
  },
92977
93650
  {