@ornncompute/cli 1.0.72 → 1.0.75

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 (34) hide show
  1. package/README.md +24 -20
  2. package/package.json +1 -1
  3. package/src/admin-capacity-reservations.mjs +2 -12
  4. package/src/admin-command-handlers.mjs +0 -1
  5. package/src/admin-credits.mjs +1 -2
  6. package/src/admin-enrollment.mjs +22 -30
  7. package/src/admin-mutations.mjs +6 -56
  8. package/src/admin-node-diagnostics.mjs +2 -36
  9. package/src/admin-node-lifecycle.mjs +25 -43
  10. package/src/admin-shell.mjs +39 -32
  11. package/src/external-bucket-commands.mjs +5 -73
  12. package/src/interaction-runtime.mjs +2 -37
  13. package/src/kubernetes-commands.mjs +9 -100
  14. package/src/launch-mode-handlers.mjs +0 -1
  15. package/src/mount-commands.mjs +25 -131
  16. package/src/storage-commands.mjs +2 -87
  17. package/src/vm-commands.mjs +9 -42
  18. package/vendor/capabilities/capabilities/admin-enrollment.js +18 -17
  19. package/vendor/capabilities/capabilities/admin-nodes-lifecycle.js +3 -101
  20. package/vendor/capabilities/capabilities/admin.js +3 -3
  21. package/vendor/capabilities/capabilities/clusters.js +3 -3
  22. package/vendor/capabilities/capabilities/commerce-market.js +9 -9
  23. package/vendor/capabilities/capabilities/compute.js +7 -7
  24. package/vendor/capabilities/capabilities/credits.js +7 -2
  25. package/vendor/capabilities/capabilities/external-buckets.js +4 -4
  26. package/vendor/capabilities/capabilities/fleet.js +109 -29
  27. package/vendor/capabilities/capabilities/market-shared.js +1 -1
  28. package/vendor/capabilities/capabilities/markets.js +12 -12
  29. package/vendor/capabilities/capabilities/mounts.js +4 -4
  30. package/vendor/capabilities/capabilities/networks.js +5 -5
  31. package/vendor/capabilities/capabilities/observability.js +49 -14
  32. package/vendor/capabilities/capabilities/tokens.js +5 -9
  33. package/vendor/capabilities/capabilities/users.js +8 -10
  34. package/vendor/capabilities/capabilities/volumes.js +5 -5
@@ -18,16 +18,10 @@ const rebootInput = z.object({
18
18
  const hardResetInput = rebootInput.extend({
19
19
  erase_local_data: z.literal(true),
20
20
  });
21
- const terminationInput = z.object({
22
- ...commonInput,
23
- delete_node_record: z.literal(true),
24
- skip_cleanup: z.boolean().optional(),
25
- });
26
21
  const assignmentInput = z.object({
27
22
  ...commonInput,
28
23
  reservation_id: z.string().trim().min(1),
29
24
  });
30
- const managementInput = z.object(commonInput);
31
25
  function adminLifecycleHelp(command, outcome, human, automation, review) {
32
26
  return {
33
27
  audience: "admin",
@@ -83,7 +77,7 @@ export const adminNodeRebootCapability = defineCapability({
83
77
  http: { method: "POST", path: "/nodes/{id}/reboot" },
84
78
  cli: {
85
79
  command: ["admin", "nodes", "reboot"],
86
- vnext: adminLifecycleHelp(["admin", "nodes", "reboot"], "Reboot one exact live machine while preserving local data and access configuration.", "ornn admin nodes reboot <node-ref> [--yes] [--no-wait] [--timeout SECONDS]", "Unsupported: reboot requires an eligible human terminal.", "Node and live-machine identities, supplier, facility, capacity assignment, and preserved access."),
80
+ vnext: adminLifecycleHelp(["admin", "nodes", "reboot"], "Reboot one exact live machine while preserving local data and access configuration.", "ornn admin nodes reboot <node-ref> [] [--no-wait] [--timeout SECONDS]", "Unsupported: reboot requires an eligible human terminal.", "Node and live-machine identities, supplier, facility, capacity assignment, and preserved access."),
87
81
  },
88
82
  mcp: false,
89
83
  slack: false,
@@ -99,102 +93,13 @@ export const adminNodeHardResetCapability = defineCapability({
99
93
  http: { method: "POST", path: "/nodes/{id}/reboot" },
100
94
  cli: {
101
95
  command: ["admin", "nodes", "hard-reset"],
102
- vnext: adminLifecycleHelp(["admin", "nodes", "hard-reset"], "Erase local tenant data and hard reset one exact live machine.", "ornn admin nodes hard-reset <node-ref> --erase-local-data [--yes] [--no-wait] [--timeout SECONDS]", "Unsupported: hard reset requires an eligible human terminal.", "Node and live-machine identities, supplier, facility, capacity assignment, erased local data, and restored keys."),
96
+ vnext: adminLifecycleHelp(["admin", "nodes", "hard-reset"], "Erase local tenant data and hard reset one exact live machine.", "ornn admin nodes hard-reset <node-ref> --erase-local-data [] [--no-wait] [--timeout SECONDS]", "Unsupported: hard reset requires an eligible human terminal.", "Node and live-machine identities, supplier, facility, capacity assignment, erased local data, and restored keys."),
103
97
  },
104
98
  mcp: false,
105
99
  slack: false,
106
100
  input: hardResetInput,
107
101
  execute: (ctx, input) => reboot(ctx, input, "hard_reset"),
108
102
  });
109
- export const adminNodeSuspendManagementCapability = defineCapability({
110
- id: "nodes.suspend_management",
111
- domain: "fleet",
112
- roles: ["admin"],
113
- description: "Suspend Ornn management while leaving the exact host powered on.",
114
- mutation: "preview-confirm",
115
- http: { method: "POST", path: "/nodes/{id}/off-grid" },
116
- cli: {
117
- command: ["admin", "nodes", "suspend-management"],
118
- vnext: adminLifecycleHelp(["admin", "nodes", "suspend-management"], "Remove Ornn management and managed access from one powered-on node.", "ornn admin nodes suspend-management <node-ref> [--reason TEXT] [--yes] [--no-wait]", "ornn admin nodes suspend-management <node-id> --yes --idempotency-key KEY --format json", "Node, supplier, facility, capacity assignment, management removal, and managed-access loss."),
119
- },
120
- mcp: false,
121
- slack: false,
122
- input: managementInput,
123
- execute: async (ctx, input) => {
124
- const parsed = managementInput.parse(input);
125
- const id = nodeId(parsed);
126
- const body = {
127
- ...(parsed.idempotency_key ? { request_id: parsed.idempotency_key } : {}),
128
- ...(parsed.reason ? { reason: parsed.reason } : {}),
129
- };
130
- if (!ctx.confirmed)
131
- return preview("nodes.suspend_management", { node_id: id, ...body });
132
- return ctx.fetch(`/nodes/${encodeURIComponent(id)}/off-grid`, {
133
- method: "POST",
134
- body,
135
- headers: requestHeaders(parsed.idempotency_key),
136
- });
137
- },
138
- });
139
- export const adminNodeResumeManagementCapability = defineCapability({
140
- id: "nodes.resume_management",
141
- domain: "fleet",
142
- roles: ["admin"],
143
- description: "Resume Ornn management for one exact off-grid node.",
144
- mutation: "preview-confirm",
145
- http: { method: "POST", path: "/nodes/{id}/on-grid" },
146
- cli: {
147
- command: ["admin", "nodes", "resume-management"],
148
- vnext: adminLifecycleHelp(["admin", "nodes", "resume-management"], "Restore Ornn management and managed access on one off-grid node.", "ornn admin nodes resume-management <node-ref> [--yes] [--no-wait]", "ornn admin nodes resume-management <node-id> --yes --idempotency-key KEY --format json", "Node, supplier, facility, capacity assignment, remote re-enrollment, and restored managed access."),
149
- },
150
- mcp: false,
151
- slack: false,
152
- input: managementInput,
153
- execute: async (ctx, input) => {
154
- const parsed = managementInput.parse(input);
155
- const id = nodeId(parsed);
156
- if (!ctx.confirmed)
157
- return preview("nodes.resume_management", { node_id: id });
158
- return ctx.fetch(`/nodes/${encodeURIComponent(id)}/on-grid`, {
159
- method: "POST",
160
- body: {
161
- ...(parsed.idempotency_key ? { request_id: parsed.idempotency_key } : {}),
162
- },
163
- headers: requestHeaders(parsed.idempotency_key),
164
- });
165
- },
166
- });
167
- export const adminNodeTerminateCapability = defineCapability({
168
- id: "nodes.terminate",
169
- domain: "fleet",
170
- roles: ["admin"],
171
- description: "Delete one exact node record with explicit cleanup scope and consequence review.",
172
- mutation: "preview-confirm",
173
- http: { method: "POST", path: "/nodes/{id}/terminate" },
174
- cli: {
175
- command: ["admin", "nodes", "terminate"],
176
- vnext: adminLifecycleHelp(["admin", "nodes", "terminate"], "End managed access and permanently delete one exact node record.", "ornn admin nodes terminate <node-ref> --delete-node-record [--skip-cleanup] [--reason TEXT] [--yes]", "ornn admin nodes terminate <node-id> --delete-node-record --yes --idempotency-key KEY --format json", "Node, supplier, facility, reservation/capacity, host cleanup, node-record deletion, and access loss."),
177
- },
178
- mcp: false,
179
- slack: false,
180
- input: terminationInput,
181
- execute: async (ctx, input) => {
182
- const parsed = terminationInput.parse(input);
183
- const id = nodeId(parsed);
184
- const body = {
185
- force: parsed.skip_cleanup === true,
186
- ...(parsed.idempotency_key ? { request_id: parsed.idempotency_key } : {}),
187
- ...(parsed.reason ? { reason: parsed.reason } : {}),
188
- };
189
- if (!ctx.confirmed)
190
- return preview("nodes.terminate", { node_id: id, ...body });
191
- return ctx.fetch(`/nodes/${encodeURIComponent(id)}/terminate`, {
192
- method: "POST",
193
- body,
194
- headers: requestHeaders(parsed.idempotency_key),
195
- });
196
- },
197
- });
198
103
  export const adminNodeAssignCapability = defineCapability({
199
104
  id: "nodes.assign",
200
105
  domain: "fleet",
@@ -204,7 +109,7 @@ export const adminNodeAssignCapability = defineCapability({
204
109
  http: { method: "POST", path: "/nodes/{id}/assign" },
205
110
  cli: {
206
111
  command: ["admin", "nodes", "assign"],
207
- vnext: adminLifecycleHelp(["admin", "nodes", "assign"], "Assign one exact node to one exact capacity reservation.", "ornn admin nodes assign <node-ref> --reservation <reservation-id> [--yes] [--no-wait]", "ornn admin nodes assign <node-id> --reservation <reservation-id> --yes --idempotency-key KEY --format json", "Node, supplier, facility, previous and requested capacity assignments, and tenant access change."),
112
+ vnext: adminLifecycleHelp(["admin", "nodes", "assign"], "Assign one exact node to one exact capacity reservation.", "ornn admin nodes assign <node-ref> --reservation <reservation-id> [] [--no-wait]", "ornn admin nodes assign <node-id> --reservation <reservation-id> --idempotency-key KEY --format json", "Node, supplier, facility, previous and requested capacity assignments, and tenant access change."),
208
113
  },
209
114
  mcp: false,
210
115
  slack: false,
@@ -228,8 +133,5 @@ export const adminNodeAssignCapability = defineCapability({
228
133
  export const adminNodeLifecycleCapabilities = [
229
134
  adminNodeRebootCapability,
230
135
  adminNodeHardResetCapability,
231
- adminNodeSuspendManagementCapability,
232
- adminNodeResumeManagementCapability,
233
- adminNodeTerminateCapability,
234
136
  adminNodeAssignCapability,
235
137
  ];
@@ -36,9 +36,9 @@ function withAdminBinding(capability, help) {
36
36
  },
37
37
  };
38
38
  }
39
- export const adminUsersListCapability = withAdminBinding(usersListCapability, adminHelp(["admin", "users", "list"], "List users belonging to organizations in the Authorization directory.", "ornn admin users list [--query QUERY] [--organization UUID] [--limit 25] [--offset OFFSET] [--cursor CURSOR]", "ornn admin users list --query QUERY --limit 25 [--cursor CURSOR] --format json"));
40
- export const adminOrganizationsListCapability = withAdminBinding(organizationListCapability, adminHelp(["admin", "organizations", "list"], "List organizations in the Authorization directory.", "ornn admin organizations list [--query QUERY] [--role consumer|supplier] [--approved true|false] [--ids UUID,...] [--limit 25] [--offset OFFSET] [--cursor CURSOR]", "ornn admin organizations list --query QUERY --limit 25 [--cursor CURSOR] --format json"));
41
- export const adminSuppliersListCapability = withAdminBinding(listSuppliersCapability, adminHelp(["admin", "suppliers", "list"], "List supplier organizations visible to staff.", "ornn admin suppliers list [--limit 50] [--cursor CURSOR]", "ornn admin suppliers list --limit 50 --format json"));
39
+ export const adminUsersListCapability = withAdminBinding(usersListCapability, adminHelp(["admin", "users", "list"], "List users in the Authorization directory; pass next_offset as --offset to continue.", "ornn admin users list [--query QUERY] [--organization UUID] [--limit 25] [--offset OFFSET]", "ornn admin users list --query QUERY --limit 25 [--offset OFFSET] --format json"));
40
+ export const adminOrganizationsListCapability = withAdminBinding(organizationListCapability, adminHelp(["admin", "organizations", "list"], "List organizations in the Authorization directory; pass next_offset as --offset to continue.", "ornn admin organizations list [--query QUERY] [--role consumer|supplier] [--approved true|false] [--ids UUID,...] [--limit 25] [--offset OFFSET]", "ornn admin organizations list --query QUERY --limit 25 [--offset OFFSET] --format json"));
41
+ export const adminSuppliersListCapability = withAdminBinding(listSuppliersCapability, adminHelp(["admin", "suppliers", "list"], "List supplier organizations visible to staff; pass next_offset as --offset to continue.", "ornn admin suppliers list [--limit 50] [--offset OFFSET]", "ornn admin suppliers list --limit 50 --offset OFFSET --format json"));
42
42
  export const adminFacilitiesListCapability = withAdminBinding(listFacilitiesCapability, adminHelp(["admin", "facilities", "list"], "List facilities visible to staff.", "ornn admin facilities list [--supplier UUID] [--limit 50] [--cursor CURSOR]", "ornn admin facilities list --limit 50 --format json"));
43
43
  export const adminNodesListCapability = withAdminBinding(listNodesCapability, adminHelp(["admin", "nodes", "list"], "List enrolled, ghost, and off-grid nodes.", "ornn admin nodes list [--supplier UUID] [--facility FACILITY] [--status STATUS] [--reservation UUID] [--limit 50] [--cursor CURSOR]", "ornn admin nodes list --limit 50 [--cursor CURSOR] --format json"));
44
44
  const nodeInput = z.object({ node_id: z.string().min(1) });
@@ -204,7 +204,7 @@ export const clusterCliCapabilities = [
204
204
  mutation: "preview-confirm",
205
205
  outcome: "Add one currently eligible machine, or rediscover that exact membership goal.",
206
206
  human: "ornn clusters add-node [<cluster-id>] [<machine-id-or-hostname>] [--guided] [--no-wait]",
207
- automation: "ornn clusters add-node <cluster-id> <machine-id> --yes --idempotency-key <key> --format json",
207
+ automation: "ornn clusters add-node <cluster-id> <machine-id> --idempotency-key <key> --format json",
208
208
  acceptedReferences: [
209
209
  "canonical cluster ID",
210
210
  "canonical machine ID",
@@ -221,7 +221,7 @@ export const clusterCliCapabilities = [
221
221
  mutation: "preview-confirm",
222
222
  outcome: "Remove one exact member, or rediscover that exact membership goal.",
223
223
  human: "ornn clusters remove-node [<cluster-id>] [<machine-id-or-hostname>] [--guided] [--no-wait]",
224
- automation: "ornn clusters remove-node <cluster-id> <machine-id> --yes --idempotency-key <key> --format json",
224
+ automation: "ornn clusters remove-node <cluster-id> <machine-id> --idempotency-key <key> --format json",
225
225
  acceptedReferences: [
226
226
  "canonical cluster ID",
227
227
  "canonical machine ID",
@@ -238,7 +238,7 @@ export const clusterCliCapabilities = [
238
238
  mutation: "preview-confirm",
239
239
  outcome: "End cluster lifecycle while reporting partial member failures and continuing reservation charges.",
240
240
  human: "ornn clusters teardown [<cluster-id>] [--guided] [--no-wait]",
241
- automation: "ornn clusters teardown <cluster-id> --yes --idempotency-key <key> --format json",
241
+ automation: "ornn clusters teardown <cluster-id> --idempotency-key <key> --format json",
242
242
  acceptedReferences: ["canonical cluster ID", "invocation-local guided choice"],
243
243
  review: "The cluster and native access end; the capacity reservation and its charges remain.",
244
244
  related: ["clusters show", "reservations show"],
@@ -33,7 +33,7 @@ export const listingsListCapability = defineCapability({
33
33
  id: "listings.list",
34
34
  domain: "listings",
35
35
  roles: ["user"],
36
- description: "List native capacity listings. Primary listings require organization approval. Returns capacityListingId, hardware, capacity and availability; read listings.terms separately for prices and durations.",
36
+ description: "List native capacity listings. Primary listings require organization approval. Returns capacityListingId, hardware, capacity and availability; when nextCursor is present, pass it back as cursor for the next page. Read listings.terms separately for prices and durations.",
37
37
  mutation: "read",
38
38
  http: { method: "GET", path: "/commerce/v2/listings" },
39
39
  input: listingsListInput,
@@ -142,13 +142,13 @@ export const listingRelistCapability = defineCapability({
142
142
  id: "listings.relist",
143
143
  domain: "listings",
144
144
  roles: ["user"],
145
- description: "Relist whole nodes of a reservation's capacity using a native availability window, nodeCount and financial terms. Buyers run on nodes Ornn assigns when their rental starts. Requires confirm: true.",
145
+ description: "Relist whole nodes of a reservation's capacity using a native availability window, nodeCount and financial terms. Buyers run on nodes Ornn assigns when their rental starts..",
146
146
  mutation: "preview-confirm",
147
147
  http: { method: "POST", path: "/commerce/reservations/{reservationId}/relist" },
148
148
  input: listingRelistInput,
149
149
  cli: {
150
150
  command: ["capacity-offers", "relist"],
151
- vnext: help(["capacity-offers", "relist"], "Relist reserved capacity with explicit financial terms.", "ornn capacity-offers relist --reservation-id UUID --node-count COUNT --starts-at TIME --ends-at TIME --terms JSON", "ornn capacity-offers relist --reservation-id UUID --node-count 1 --starts-at TIME --ends-at TIME --terms JSON --idempotency-key KEY --yes --format json", ["capacity-offers terms", "capacity-offers delist"], 24, ["reservation ID"]),
151
+ vnext: help(["capacity-offers", "relist"], "Relist reserved capacity with explicit financial terms.", "ornn capacity-offers relist --reservation-id UUID --node-count COUNT --starts-at TIME --ends-at TIME --terms JSON", "ornn capacity-offers relist --reservation-id UUID --node-count 1 --starts-at TIME --ends-at TIME --terms JSON --idempotency-key KEY --format json", ["capacity-offers terms", "capacity-offers delist"], 24, ["reservation ID"]),
152
152
  },
153
153
  slack: false,
154
154
  execute: async (ctx, input) => {
@@ -179,7 +179,7 @@ export const listingUpdateCapability = defineCapability({
179
179
  id: "listings.update",
180
180
  domain: "listings",
181
181
  roles: ["admin"],
182
- description: "Staff only: edit one advertised native financial term with its complete financial fields. Reuse idempotencyKey on retries. Requires confirm: true.",
182
+ description: "Staff only: edit one advertised native financial term with its complete financial fields. Reuse idempotencyKey on retries..",
183
183
  mutation: "preview-confirm",
184
184
  http: { method: "PATCH", path: "/commerce/v2/listings/{listingId}/terms/{listingTermsId}" },
185
185
  input: listingUpdateInput,
@@ -212,13 +212,13 @@ export const listingDelistCapability = defineCapability({
212
212
  id: "listings.delist",
213
213
  domain: "listings",
214
214
  roles: ["user"],
215
- description: "Delist a listing you own. Its unsold time leaves the market, its spot asks are cancelled and running spot reservations on it end. Windows already bought stay sold. Requires confirm: true.",
215
+ description: "Delist a listing you own. Its unsold time leaves the market, its spot asks are cancelled and running spot reservations on it end. Windows already bought stay sold..",
216
216
  mutation: "preview-confirm",
217
217
  http: { method: "POST", path: "/commerce/v2/listings/{listingId}/delist" },
218
218
  input: listingDelistInput,
219
219
  cli: {
220
220
  command: ["capacity-offers", "delist"],
221
- vnext: help(["capacity-offers", "delist"], "Delist a listing you relisted.", "ornn capacity-offers delist --listing-id <id>", "ornn capacity-offers delist --listing-id <id> --yes --format json", ["capacity-offers relist"], 26, ["listing ID"]),
221
+ vnext: help(["capacity-offers", "delist"], "Delist a listing you relisted.", "ornn capacity-offers delist --listing-id <id>", "ornn capacity-offers delist --listing-id <id> --format json", ["capacity-offers relist"], 26, ["listing ID"]),
222
222
  },
223
223
  slack: false,
224
224
  execute: async (ctx, input) => {
@@ -256,7 +256,7 @@ export const reservationsListCapability = defineCapability({
256
256
  id: "reservations.list",
257
257
  domain: "reservations",
258
258
  roles: ["user"],
259
- description: "List this organization's reservations, schedule and spot alike (a running spot reservation has no end time). With listingId, list the trades on a listing you own.",
259
+ description: "List this organization's reservations, schedule and spot alike (a running spot reservation has no end time). With listingId, list the trades on a listing you own. When nextCursor is present, pass it back as cursor for the next page.",
260
260
  mutation: "read",
261
261
  http: { method: "GET", path: "/commerce/reservations" },
262
262
  input: reservationsListInput,
@@ -348,13 +348,13 @@ export const reservationPurchaseCapability = defineCapability({
348
348
  id: "reservations.purchase",
349
349
  domain: "reservations",
350
350
  roles: ["user"],
351
- description: "Book a window of a relisted (secondary) listing on one of its terms at the term's price. The GPUs are held for you until the window starts; then it becomes your reservation, with the booking's ID. Nothing is charged when you book. Primary listings take offers instead (offers.post). Requires confirm: true.",
351
+ description: "Book a window of a relisted (secondary) listing on one of its terms at the term's price. The GPUs are held for you until the window starts; then it becomes your reservation, with the booking's ID. Nothing is charged when you book. Primary listings take offers instead (offers.post)..",
352
352
  mutation: "preview-confirm",
353
353
  http: { method: "POST", path: "/v1/markets/bookings" },
354
354
  input: reservationPurchaseInput,
355
355
  cli: {
356
356
  command: ["reservations", "buy"],
357
- vnext: help(["reservations", "buy"], "Book a window of relisted capacity at its term's price.", "ornn reservations buy --listing-id <id> --listing-term-id <id> --starts-at <time> --ends-at <time> --price-per-gpu-hour-micro-usd <n> [--node-count <n>]", "ornn reservations buy --listing-id <id> --listing-term-id <id> --starts-at <time> --ends-at <time> --price-per-gpu-hour-micro-usd 4000000 --idempotency-key <key> --yes --format json", ["capacity-offers availability", "capacity-offers terms", "reservations show"], 30, ["listingTermsId from capacity-offers terms"]),
357
+ vnext: help(["reservations", "buy"], "Book a window of relisted capacity at its term's price.", "ornn reservations buy --listing-id <id> --listing-term-id <id> --starts-at <time> --ends-at <time> --price-per-gpu-hour-micro-usd <n> [--node-count <n>]", "ornn reservations buy --listing-id <id> --listing-term-id <id> --starts-at <time> --ends-at <time> --price-per-gpu-hour-micro-usd 4000000 --idempotency-key <key> --format json", ["capacity-offers availability", "capacity-offers terms", "reservations show"], 30, ["listingTermsId from capacity-offers terms"]),
358
358
  },
359
359
  slack: false,
360
360
  execute: async (ctx, input) => {
@@ -140,7 +140,7 @@ export const launchCapability = cliOnly({
140
140
  order: 2,
141
141
  outcome: "Launch one reviewed VM, Bare Metal machine, Kubernetes cluster, or Slurm cluster from active reserved capacity, including a declared durable Bare Metal workspace.",
142
142
  human: "ornn launch [<capacity-reservation>] --mode vm|bare-metal|kubernetes|slurm [--key <ssh-key>]; Bare Metal may add --network shared --volume <managed-volume> --mount-access read-only|read-write; Kubernetes/Slurm prompt for missing --network public|private and --nodes <membership-count>, and may add running VMs with --vms <vm-ids>",
143
- automation: "ornn launch <canonical-reservation-id> --mode vm|bare-metal|kubernetes|slurm --yes --idempotency-key <key> --format json; VM/Bare Metal/Slurm require --key <canonical-key-id>; Bare Metal may add --network shared --volume <canonical-volume-id> --mount-access read-only|read-write; Kubernetes/Slurm require --network public|private --nodes <membership-count> --machines <canonical-machine-ids>, and may add --vms <canonical-vm-ids> (with --nodes 0 for a cluster of VMs only)",
143
+ automation: "ornn launch <canonical-reservation-id> --mode vm|bare-metal|kubernetes|slurm --idempotency-key <key> --format json; VM/Bare Metal/Slurm require --key <canonical-key-id>; Bare Metal may add --network shared --volume <canonical-volume-id> --mount-access read-only|read-write; Kubernetes/Slurm require --network public|private --nodes <membership-count> --machines <canonical-machine-ids>, and may add --vms <canonical-vm-ids> (with --nodes 0 for a cluster of VMs only)",
144
144
  acceptedReferences: [
145
145
  "canonical capacity-reservation ID",
146
146
  "canonical eligible machine IDs",
@@ -262,7 +262,7 @@ export const machineSwitchCapability = cliOnly({
262
262
  order: 463,
263
263
  outcome: "Change only the explicitly requested VM, Bare Metal, or network goal while retaining SSH-key intent.",
264
264
  human: "ornn machines switch <canonical-reservation-id> [--mode vm|bare-metal] [--network public|private] [--erase-local-data]",
265
- automation: "ornn machines switch <canonical-reservation-id> [--mode vm|bare-metal] [--network public|private] [--erase-local-data] --yes --idempotency-key <key> --format json",
265
+ automation: "ornn machines switch <canonical-reservation-id> [--mode vm|bare-metal] [--network public|private] [--erase-local-data] --idempotency-key <key> --format json",
266
266
  acceptedReferences: ["canonical capacity-reservation ID"],
267
267
  review: "exact reservation, current and requested access mode, network intent, retained SSH keys, access interruption, and permanent local-data erasure for cross-mode changes",
268
268
  resumableStates: ["switch accepted", "SSH ready"],
@@ -287,7 +287,7 @@ export const machineRebootCapability = cliOnly({
287
287
  order: 464,
288
288
  outcome: "Reboot one exact machine and normally wait for restored SSH readiness.",
289
289
  human: "ornn machines reboot <canonical-machine-id|exact-hostname> [--no-wait]",
290
- automation: "ornn machines reboot <canonical-machine-id> --yes --idempotency-key <key> --format json",
290
+ automation: "ornn machines reboot <canonical-machine-id> --idempotency-key <key> --format json",
291
291
  acceptedReferences: [
292
292
  "canonical machine ID",
293
293
  "exact unique hostname",
@@ -316,7 +316,7 @@ export const machineResetCapability = cliOnly({
316
316
  order: 465,
317
317
  outcome: "Hard reset one exact machine only with explicit local-data erasure scope and final consent.",
318
318
  human: "ornn machines reset <canonical-machine-id|exact-hostname> --erase-local-data [--no-wait]",
319
- automation: "ornn machines reset <canonical-machine-id> --erase-local-data --yes --idempotency-key <key> --format json",
319
+ automation: "ornn machines reset <canonical-machine-id> --erase-local-data --idempotency-key <key> --format json",
320
320
  acceptedReferences: [
321
321
  "canonical machine ID",
322
322
  "exact unique hostname",
@@ -392,7 +392,7 @@ export const sshKeyDeleteCapability = cliOnly({
392
392
  order: 452,
393
393
  outcome: "Delete one exact organization SSH key without implying machine delivery.",
394
394
  human: "ornn ssh-keys delete <exact-key-id-or-label>",
395
- automation: "ornn ssh-keys delete <canonical-key-id> --yes --idempotency-key <key> --format json",
395
+ automation: "ornn ssh-keys delete <canonical-key-id> --idempotency-key <key> --format json",
396
396
  acceptedReferences: [
397
397
  "canonical SSH-key ID",
398
398
  "exact unique key label in an eligible terminal",
@@ -443,7 +443,7 @@ export const sshKeyAssignmentAssignCapability = cliOnly({
443
443
  order: 454,
444
444
  outcome: "Assign or replay one exact SSH-key relationship.",
445
445
  human: "ornn ssh-keys assignments assign <canonical-reservation-id> --key <exact-key-id-or-label>",
446
- automation: "ornn ssh-keys assignments assign <canonical-reservation-id> --key <canonical-key-id> --yes --idempotency-key <key> --format json",
446
+ automation: "ornn ssh-keys assignments assign <canonical-reservation-id> --key <canonical-key-id> --idempotency-key <key> --format json",
447
447
  acceptedReferences: [
448
448
  "canonical capacity-reservation ID",
449
449
  "canonical SSH-key ID",
@@ -472,7 +472,7 @@ export const sshKeyAssignmentSyncCapability = cliOnly({
472
472
  order: 455,
473
473
  outcome: "Queue idempotent SSH-key synchronization and report delayed delivery honestly.",
474
474
  human: "ornn ssh-keys assignments sync <canonical-reservation-id>",
475
- automation: "ornn ssh-keys assignments sync <canonical-reservation-id> --yes --idempotency-key <key> --format json",
475
+ automation: "ornn ssh-keys assignments sync <canonical-reservation-id> --idempotency-key <key> --format json",
476
476
  acceptedReferences: ["canonical capacity-reservation ID"],
477
477
  review: "reservation, assigned keys, and target machines",
478
478
  resumableStates: ["queued", "installed", "failed"],
@@ -37,7 +37,7 @@ export const creditGrantCapability = defineCapability({
37
37
  category: "resource",
38
38
  command: ["admin", "organizations", "grant-credit"],
39
39
  outcome: "Grant Ornn credits to a customer organization.",
40
- human: "ornn admin organizations grant-credit --organization UUID --amount-cents N --note TEXT --idempotency-key UUID [--yes]",
40
+ human: "ornn admin organizations grant-credit --organization UUID --amount-cents N --note TEXT --idempotency-key UUID []",
41
41
  automation: "Requires an eligible human terminal.",
42
42
  acceptedReferences: ["organization UUID from admin organizations list"],
43
43
  review: "Review the organization, USD amount, note, and grant UUID before default-no consent.",
@@ -53,6 +53,11 @@ export const creditGrantCapability = defineCapability({
53
53
  format: "uuid",
54
54
  description: "Exact customer organization UUID from organization_list.",
55
55
  },
56
+ adjustmentId: {
57
+ type: "string",
58
+ format: "uuid",
59
+ description: "a new UUID per grant, reused on retries",
60
+ },
56
61
  amountCents: {
57
62
  type: "integer",
58
63
  minimum: 1,
@@ -64,7 +69,7 @@ export const creditGrantCapability = defineCapability({
64
69
  description: "Reason for the credit grant, at most 500 UTF-8 bytes.",
65
70
  },
66
71
  },
67
- required: ["organizationId", "amountCents", "note"],
72
+ required: ["organizationId", "adjustmentId", "amountCents", "note"],
68
73
  },
69
74
  },
70
75
  input: creditGrantInput,
@@ -131,7 +131,7 @@ export const externalBucketCapabilities = [
131
131
  input: connectInput,
132
132
  outcome: "Create or rediscover one external bucket connection with verification kept separate.",
133
133
  human: "ornn external-buckets connect <gcs|s3|r2> --bucket <bucket> [--name <name>] [--prefix <prefix>] [--region <region>] [--account-id <id>|--endpoint-url <url>] [--access-key-id <id> --secret-access-key-file <path>] [--read-only|--read-write]",
134
- automation: "ornn external-buckets connect <gcs|s3|r2> --bucket <bucket> <provider-inputs> --yes --idempotency-key <key> --format json",
134
+ automation: "ornn external-buckets connect <gcs|s3|r2> --bucket <bucket> <provider-inputs> --idempotency-key <key> --format json",
135
135
  review: `Review the exact source, access mode, and credential presence before connecting it. ${gcsImportGuidance}`,
136
136
  related: ["external-buckets verify", "external-buckets import"],
137
137
  }),
@@ -143,7 +143,7 @@ export const externalBucketCapabilities = [
143
143
  input: credentialInput,
144
144
  outcome: "Update one connection's credentials and require a separate verification.",
145
145
  human: "ornn external-buckets update-credentials <external-bucket> --access-key-id <id> --secret-access-key-file <path>",
146
- automation: "ornn external-buckets update-credentials <external-bucket-id> --access-key-id <id> --secret-access-key-file <path> --yes --idempotency-key <key> --format json",
146
+ automation: "ornn external-buckets update-credentials <external-bucket-id> --access-key-id <id> --secret-access-key-file <path> --idempotency-key <key> --format json",
147
147
  acceptedReferences: ["canonical external bucket ID", "exact unique external bucket name"],
148
148
  review: "Credential changes invalidate the prior verification and require renewed review.",
149
149
  related: ["external-buckets verify"],
@@ -169,7 +169,7 @@ export const externalBucketCapabilities = [
169
169
  input: importInput,
170
170
  outcome: "Create or replay exactly one managed working copy with source writeback disabled.",
171
171
  human: "ornn external-buckets import <gcs|s3|r2> <external-bucket> --reservation <canonical-reservation-id> [--no-wait] [--timeout <duration>]",
172
- automation: "ornn external-buckets import <gcs|s3> <external-bucket-id> --reservation <canonical-reservation-id> --yes --idempotency-key <key> [--wait --timeout <duration>] --format json",
172
+ automation: "ornn external-buckets import <gcs|s3> <external-bucket-id> --reservation <canonical-reservation-id> --idempotency-key <key> [--wait --timeout <duration>] --format json",
173
173
  acceptedReferences: ["canonical external bucket ID", "exact unique external bucket name"],
174
174
  review: `Review the isolated destination and explicit no-writeback guarantee before importing. ${gcsImportGuidance}`,
175
175
  resumableStates: ["pending", "working", "partial", "failed", "interrupted"],
@@ -183,7 +183,7 @@ export const externalBucketCapabilities = [
183
183
  input: disconnectInput,
184
184
  outcome: "Remove one external source connection without writing to its source bucket.",
185
185
  human: "ornn external-buckets disconnect <external-bucket>",
186
- automation: "ornn external-buckets disconnect <external-bucket-id> --yes --idempotency-key <key> --format json",
186
+ automation: "ornn external-buckets disconnect <external-bucket-id> --idempotency-key <key> --format json",
187
187
  acceptedReferences: ["canonical external bucket ID", "exact unique external bucket name"],
188
188
  review: "Disconnecting reduces access to the source and is blocked while mounts remain.",
189
189
  related: ["storage detach", "external-buckets show"],