@clawops/cli 2.1.2 → 2.2.0

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 (63) hide show
  1. package/README.md +122 -2
  2. package/dist/agent-activity-25FAWLAI.js +16 -0
  3. package/dist/{apply-HJ5GAKHW.js → apply-F5SQ2ZOS.js} +12 -12
  4. package/dist/{automation-MKCJ46I6.js → automation-NBYQ6MFZ.js} +1 -1
  5. package/dist/backup-flows-NDP5JTR3.js +29 -0
  6. package/dist/{bootstrap-NN647RCY.js → bootstrap-32TZXVDF.js} +5 -5
  7. package/dist/bootstrap.sh.tmpl +4 -0
  8. package/dist/chunk-27335SIH.js +51 -0
  9. package/dist/{chunk-X56CQ6GB.js → chunk-4MHDW2NB.js} +1 -1
  10. package/dist/{chunk-E4NJSJ54.js → chunk-4PY6PN4G.js} +51 -7
  11. package/dist/{chunk-3Z5TDXCJ.js → chunk-55UMO37O.js} +1 -1
  12. package/dist/{chunk-IQQTB7ER.js → chunk-66R52R7K.js} +10 -14
  13. package/dist/chunk-755X5OGS.js +213 -0
  14. package/dist/{chunk-QDNFADJI.js → chunk-AVERNLUY.js} +6 -6
  15. package/dist/{chunk-R3DTA35B.js → chunk-AX65JMDZ.js} +20 -20
  16. package/dist/{chunk-T5XCMYAV.js → chunk-CQOYUWR7.js} +766 -210
  17. package/dist/chunk-E6BRQK67.js +289 -0
  18. package/dist/{chunk-64PONSA5.js → chunk-GFIR2IIJ.js} +3 -1
  19. package/dist/chunk-LV7UO5CG.js +82 -0
  20. package/dist/{chunk-GIEVAGEK.js → chunk-N5ZYUTZS.js} +16 -1
  21. package/dist/{chunk-GFUK6KDR.js → chunk-OUQVKIIA.js} +372 -34
  22. package/dist/{chunk-XFN3YDZE.js → chunk-PASAVVNS.js} +1 -1
  23. package/dist/chunk-PCSX6Y3U.js +297 -0
  24. package/dist/chunk-POYS3EVQ.js +14 -0
  25. package/dist/{chunk-ELU3XQEA.js → chunk-RDUKRIRC.js} +1 -1
  26. package/dist/chunk-SX75L2T3.js +46 -0
  27. package/dist/{chunk-2Z7J3ERQ.js → chunk-TYNMOYVM.js} +1 -1
  28. package/dist/{chunk-2I7KCMXZ.js → chunk-UAJJEDCJ.js} +2 -2
  29. package/dist/{chunk-NUDIHZEH.js → chunk-WPZIJONN.js} +14 -12
  30. package/dist/{chunk-BELTQGHT.js → chunk-YPVWF7IA.js} +4 -4
  31. package/dist/{chunk-3OLUJPCB.js → chunk-Z3XLWZWF.js} +1 -1
  32. package/dist/cli.js +383 -925
  33. package/dist/conn-M2V5HBPJ.js +9 -0
  34. package/dist/{context-7VI3R6EK.js → context-EHSLWKSH.js} +6 -6
  35. package/dist/{docker-3PDO4TS7.js → docker-IKM5GRMC.js} +2 -2
  36. package/dist/{flows-RI7FGHAM.js → flows-6B2I6TRW.js} +7 -7
  37. package/dist/{generate-Q2BGVMH7.js → generate-4YYNW3IU.js} +9 -8
  38. package/dist/{harden-3KKCR7BL.js → harden-UHAOVQMZ.js} +5 -5
  39. package/dist/init-HOPXDNWY.js +13 -0
  40. package/dist/{mcp-wire-FQOMM7MK.js → mcp-wire-BXF4DJFT.js} +26 -19
  41. package/dist/migrate-flow-24XA4GZL.js +25 -0
  42. package/dist/{package-JFVGCNKU.js → package-HYGHRX35.js} +3 -1
  43. package/dist/{pool-PIIKJ4L2.js → pool-NT4XBSUT.js} +2 -2
  44. package/dist/{privileged-JFA6LLTV.js → privileged-5Y6O4H7Z.js} +1 -1
  45. package/dist/{ready-KDNRBNSU.js → ready-IJEUBFVX.js} +2 -2
  46. package/dist/{remote-config-3HZLUWEA.js → remote-config-OZYBMBSK.js} +3 -3
  47. package/dist/{runtime-X3KW5TCP.js → runtime-VW53TU2W.js} +5 -1
  48. package/dist/server-E3YA32ND.js +53 -0
  49. package/dist/ssh-HOM7GF3M.js +13 -0
  50. package/dist/{stack-config-LUTS2XAD.js → stack-config-ICQ5YHUL.js} +2 -2
  51. package/dist/stack-delete-NTIGKWUF.js +13 -0
  52. package/dist/{state-AOAYLYY5.js → state-AKZP2S4T.js} +2 -2
  53. package/dist/{store-OVB3DAJR.js → store-YOLQYXMB.js} +1 -1
  54. package/dist/{tailscale-cutover-6YP2QKFM.js → tailscale-cutover-V42HO5UM.js} +3 -3
  55. package/dist/{validate-JXKN5WD6.js → validate-DZE6LFEB.js} +1 -1
  56. package/dist/{wait-WO72TRRQ.js → wait-DOUNNJNN.js} +2 -2
  57. package/package.json +3 -1
  58. package/spec/mcp-tools.yaml +282 -35
  59. package/dist/logs-5A7YYA53.js +0 -15
  60. package/dist/server-B7I6HBQH.js +0 -46
  61. package/dist/ssh-VAI5DU5M.js +0 -11
  62. package/dist/upgrade-ULD4KFYC.js +0 -88
  63. /package/dist/{chunk-NUL5F6YV.js → chunk-SOZ62ZXW.js} +0 -0
@@ -86,9 +86,8 @@ tools:
86
86
  actually running.
87
87
 
88
88
  Do NOT use when: you already know the problem and want to fix it. This tool only
89
- reports — it changes nothing, and never runs `openclaw doctor --fix`. No tool
90
- repairs a gateway: `clawops gateway update` is CLI-only, so tell the user to run
91
- it themselves, after `clawops backup create`.
89
+ reports — it changes nothing, and never runs `openclaw doctor --fix`. To move a
90
+ gateway to another version, use clawops_gateway_update after clawops_backup_create.
92
91
 
93
92
  Every check carries a status: fail (something is wrong that clawops can name),
94
93
  warn (worth knowing, not broken), info (did not apply). `ok` is false only when
@@ -136,8 +135,8 @@ tools:
136
135
  idempotentHint: true
137
136
  openWorldHint: true
138
137
  input:
139
- stackName: { type: string, optional: true }
140
- tailLines: { type: integer, optional: true, default: 100, max: 1000 }
138
+ stackName: { type: string, optional: true, description: "Which stack's gateway to read. Omitted = the default stack in ~/.clawops/config.json" }
139
+ tailLines: { type: integer, optional: true, default: 100, max: 1000, description: "How many of the most recent lines to return. Keep it small; output is trimmed to 8KB regardless" }
141
140
  sinceMin: { type: integer, optional: true, description: "Lines since N minutes ago" }
142
141
  output:
143
142
  lines: { type: array, items: { type: string }, description: "Trimmed log lines (R14: hard cap 8KB)" }
@@ -227,7 +226,7 @@ tools:
227
226
  idempotentHint: true
228
227
  openWorldHint: true
229
228
  input:
230
- stackName: { type: string, optional: true }
229
+ stackName: { type: string, optional: true, description: "Which stack's gateway config to read. Omitted = the default stack in ~/.clawops/config.json" }
231
230
  key: { type: string, optional: true, description: "Dot-path config key, e.g., gateway.auth.mode. Omit to dump the full config." }
232
231
  output:
233
232
  value: { type: string, description: "Stringified value; complex objects are JSON-encoded" }
@@ -240,8 +239,7 @@ tools:
240
239
  Use when: the user wants to see which agents are running, debug agent
241
240
  routing, or count active workspaces.
242
241
 
243
- Do NOT use when: the user wants one agent's logs — no tool exposes those; tell
244
- the user to run `clawops agents logs <name>`.
242
+ Do NOT use when: the user wants one agent's activity — that is clawops_agents_logs.
245
243
  annotations:
246
244
  title: List OpenClaw Agents
247
245
  readOnlyHint: true
@@ -249,7 +247,7 @@ tools:
249
247
  idempotentHint: true
250
248
  openWorldHint: true
251
249
  input:
252
- stackName: { type: string, optional: true }
250
+ stackName: { type: string, optional: true, description: "Which stack's agents to list. Omitted = the default stack in ~/.clawops/config.json" }
253
251
  output:
254
252
  agents:
255
253
  type: array
@@ -261,6 +259,84 @@ tools:
261
259
  status: { type: enum, values: [running, paused, errored, stopped] }
262
260
  channels: { type: array, items: { type: string } }
263
261
 
262
+ - name: clawops_agents_logs
263
+ toolset: [cli, read]
264
+ description: |
265
+ One agent's recent activity, read from the gateway's audit log, newest last.
266
+ Paginated: pass the returned cursor to continue.
267
+
268
+ Use when: the user asks what a specific agent did, or why it behaved as it did.
269
+
270
+ Do NOT use when: the user wants the gateway's own log stream — that is
271
+ clawops_logs_tail. Do NOT use to find agent names — that is clawops_agents_list.
272
+ annotations:
273
+ title: Read One Agent's Activity
274
+ readOnlyHint: true
275
+ destructiveHint: false
276
+ idempotentHint: true
277
+ openWorldHint: true
278
+ input:
279
+ stackName: { type: string, optional: true, description: "Which stack the agent runs on. Omitted = the default stack in ~/.clawops/config.json" }
280
+ name: { type: string, description: "The agent's name, as clawops_agents_list reports it" }
281
+ limit: { type: integer, optional: true, default: 50, description: "Maximum activity records to return. Omitted = 50" }
282
+ cursor: { type: string, optional: true, description: "The cursor a previous call returned, to continue from where it stopped. Omitted = the most recent records" }
283
+
284
+ - name: clawops_gateway_status
285
+ toolset: [cli, read]
286
+ description: |
287
+ Whether the OpenClaw gateway container is running, when it started, and which image it
288
+ runs, as docker reports it on the host.
289
+
290
+ Use when: the user asks whether the gateway is up or which OpenClaw version is deployed.
291
+
292
+ Do NOT use when: the user wants a full health check — clawops_doctor probes the gateway
293
+ itself rather than the container. Do NOT use to change anything; this only reads.
294
+ annotations:
295
+ title: Gateway Container Status
296
+ readOnlyHint: true
297
+ destructiveHint: false
298
+ idempotentHint: true
299
+ openWorldHint: true
300
+ input:
301
+ stackName: { type: string, optional: true, description: "Which stack's gateway to inspect. Omitted = the default stack in ~/.clawops/config.json" }
302
+
303
+ - name: clawops_secret_list
304
+ toolset: [cli, read]
305
+ description: |
306
+ List the secrets clawops stores locally, by name and status. Never returns a value.
307
+
308
+ Use when: the user asks which secrets are set, or before a deploy that references one.
309
+
310
+ Do NOT use when: the user wants to set or rotate a secret. No tool does that, because the
311
+ value would pass through the conversation (R6): ask the user to run
312
+ `clawops secret set <NAME>` or `clawops secret rotate <NAME>` in a terminal.
313
+ annotations:
314
+ title: List Stored Secrets
315
+ readOnlyHint: true
316
+ destructiveHint: false
317
+ idempotentHint: true
318
+ openWorldHint: false
319
+ input: {}
320
+
321
+ - name: clawops_secret_audit
322
+ toolset: [cli, read]
323
+ description: |
324
+ Report secrets that stacks reference but clawops does not have, and `$secret:` references
325
+ that cannot be resolved. Never returns a value.
326
+
327
+ Use when: a deploy or config change fails on a missing secret, or before applying a plan
328
+ whose config references secrets.
329
+
330
+ Do NOT use when: the user wants to set the missing secret — ask them to run
331
+ `clawops secret set <NAME>` in a terminal; no tool takes a secret value (R6).
332
+ annotations:
333
+ title: Audit Secret References
334
+ readOnlyHint: true
335
+ destructiveHint: false
336
+ idempotentHint: true
337
+ openWorldHint: false
338
+ input: {}
339
+
264
340
  # ────────────────────────────────────────────────────────────────────────────
265
341
  # MUTATING CLI TOOLS (destructive flagged per R10/R11; elicitation per R19)
266
342
  # ────────────────────────────────────────────────────────────────────────────
@@ -286,13 +362,13 @@ tools:
286
362
  idempotentHint: true
287
363
  openWorldHint: true
288
364
  input:
289
- stackName: { type: string, optional: true }
365
+ stackName: { type: string, optional: true, description: "Name for the stack to provision, and the name every later command refers to it by. Omitted = the default stack in ~/.clawops/config.json" }
290
366
  provider:
291
367
  type: enum
292
368
  values: [aws, gcp, azure, local]
293
369
  optional: true
294
370
  description: Defaults to provider configured for this stack
295
- region: { type: string, optional: true }
371
+ region: { type: string, optional: true, description: "Cloud region to deploy into, in the provider's own spelling (us-east-1, us-central1, eastus). Omitted = the region recorded for the stack" }
296
372
  instanceType:
297
373
  type: string
298
374
  optional: true
@@ -318,10 +394,10 @@ tools:
318
394
  optional: true
319
395
  description: Which interface the gateway binds. 'all' serves plaintext HTTP.
320
396
  openclawVersion: { type: string, optional: true, description: "semver or 'stable'/'dev'" }
321
- dryRun: { type: boolean, optional: true, default: false }
397
+ dryRun: { type: boolean, optional: true, default: false, description: "Show what would be created and change nothing. Use this first when the user has not yet approved a spend" }
322
398
  output:
323
399
  taskId: { type: string, description: "For >60s ops; poll clawops_task_status" }
324
- stackName: { type: string }
400
+ stackName: { type: string, description: "Name for the stack to provision, and the name every later command refers to it by. Omitted = the default stack in ~/.clawops/config.json" }
325
401
  gatewayUrl: { type: string, format: uri }
326
402
  resourceCount: { type: integer }
327
403
 
@@ -336,8 +412,7 @@ tools:
336
412
  remove a stack. Always confirm the stack name.
337
413
 
338
414
  Do NOT use when: the user wants to stop the gateway temporarily — that is not
339
- a destroy, and no tool stops a gateway; clawops_gateway_restart is the only
340
- gateway tool. Do NOT use when in doubt about which stack; list first with
415
+ a destroy, and no tool stops a gateway; clawops_gateway_restart restarts it. Do NOT use when in doubt about which stack; list first with
341
416
  clawops_stacks_list.
342
417
  annotations:
343
418
  title: Destroy Stack (DESTRUCTIVE)
@@ -346,7 +421,7 @@ tools:
346
421
  idempotentHint: true
347
422
  openWorldHint: true
348
423
  input:
349
- stackName: { type: string }
424
+ stackName: { type: string, description: "The stack to destroy. Required, and worth repeating back to the user before calling: this deletes every resource it provisioned" }
350
425
  yes: { type: boolean, optional: true, default: false, description: "Skip elicitation; CI/scripted use only" }
351
426
  output:
352
427
  taskId: { type: string }
@@ -371,7 +446,7 @@ tools:
371
446
  openWorldHint: true
372
447
  input:
373
448
  planPath: { type: string, description: "Absolute path to plan JSON (R7)" }
374
- yes: { type: boolean, optional: true, default: false }
449
+ yes: { type: boolean, optional: true, default: false, description: "Skip the confirmation and apply immediately. Only when the user has already approved this specific plan" }
375
450
  output:
376
451
  taskId: { type: string }
377
452
  summary: { type: string, description: "Trimmed; full output as resource (R14)" }
@@ -394,9 +469,9 @@ tools:
394
469
  idempotentHint: true
395
470
  openWorldHint: true
396
471
  input:
397
- stackName: { type: string, optional: true }
398
- provider: { type: enum, values: [aws, gcp, azure, local], optional: true }
399
- region: { type: string, optional: true }
472
+ stackName: { type: string, optional: true, description: "Which stack the plan is for. Omitted = the default stack in ~/.clawops/config.json" }
473
+ provider: { type: enum, values: [aws, gcp, azure, local], optional: true, description: "Cloud to plan against. Omitted = the provider recorded for the stack. 'local' has no plan/apply path and is refused" }
474
+ region: { type: string, optional: true, description: "Cloud region, in the provider's own spelling (us-east-1, us-central1, eastus). Omitted = the region recorded for the stack" }
400
475
  instanceType: { type: string, optional: true, description: "A clawops alias (micro|small|medium|large|gpu) or a machine type the cloud names itself, e.g. t3.small" }
401
476
  openclawVersion: { type: string, optional: true, description: "semver, or 'stable'/'dev'" }
402
477
  sshCidr: { type: string, optional: true, description: "CIDR(s) allowed to reach SSH, comma-separated, or 'auto' for this machine. Omitted = none, and nothing will be able to connect" }
@@ -428,10 +503,10 @@ tools:
428
503
  idempotentHint: true
429
504
  openWorldHint: true
430
505
  input:
431
- stackName: { type: string, optional: true }
432
- key: { type: string }
506
+ stackName: { type: string, optional: true, description: "Which stack's gateway config to write. Omitted = the default stack in ~/.clawops/config.json" }
507
+ key: { type: string, description: "Dotted path into the gateway config, e.g. models.provider or channels.slack.enabled" }
433
508
  value: { type: string, description: "Stringified; JSON for complex values" }
434
- restart: { type: boolean, optional: true, default: false }
509
+ restart: { type: boolean, optional: true, default: false, description: "Restart the gateway so the change takes effect. Without it the value is written and the running gateway keeps the old one" }
435
510
  output:
436
511
  message: { type: string, description: "Confirmation of the change applied" }
437
512
 
@@ -453,9 +528,9 @@ tools:
453
528
  idempotentHint: true
454
529
  openWorldHint: true
455
530
  input:
456
- stackName: { type: string, optional: true }
531
+ stackName: { type: string, optional: true, description: "Which stack's gateway config to write. Omitted = the default stack in ~/.clawops/config.json" }
457
532
  key: { type: string, description: "Dot-path config key to remove" }
458
- restart: { type: boolean, optional: true, default: false }
533
+ restart: { type: boolean, optional: true, default: false, description: "Restart the gateway so the removal takes effect. Without it the key is removed and the running gateway keeps the old value" }
459
534
  output:
460
535
  message: { type: string, description: "Confirmation of the key removed" }
461
536
 
@@ -477,7 +552,7 @@ tools:
477
552
  idempotentHint: true
478
553
  openWorldHint: true
479
554
  input:
480
- stackName: { type: string, optional: true }
555
+ stackName: { type: string, optional: true, description: "Which stack's deployed config to validate. Omitted = the default stack in ~/.clawops/config.json" }
481
556
  output:
482
557
  valid: { type: boolean }
483
558
  issues: { type: array, items: { type: string } }
@@ -499,15 +574,187 @@ tools:
499
574
  idempotentHint: true
500
575
  openWorldHint: true
501
576
  input:
502
- stackName: { type: string, optional: true }
577
+ stackName: { type: string, optional: true, description: "Which stack's gateway to restart. Omitted = the default stack in ~/.clawops/config.json" }
503
578
  output:
504
579
  restartedAt: { type: string, format: date-time }
505
580
  previousUptimeSec: { type: integer }
506
581
 
582
+ - name: clawops_gateway_update
583
+ toolset: [cli]
584
+ description: |
585
+ Move the gateway to a different OpenClaw version: pull the image and restart the gateway
586
+ on it. Every agent on the host restarts with it.
587
+
588
+ Use when: the user asks to upgrade or downgrade OpenClaw on a running stack, naming a
589
+ version.
590
+
591
+ Do NOT use when: the user has not named a concrete version — moving tags such as
592
+ `latest` are refused, as the CLI refuses them. Do NOT use without a backup the user can
593
+ return to: suggest clawops_backup_create first.
594
+ annotations:
595
+ title: Update OpenClaw Version
596
+ readOnlyHint: false
597
+ destructiveHint: true
598
+ idempotentHint: true
599
+ openWorldHint: true
600
+ input:
601
+ stackName: { type: string, optional: true, description: "Which stack's gateway to update. Omitted = the default stack in ~/.clawops/config.json" }
602
+ version: { type: string, description: "A concrete OpenClaw version to move to, e.g. 2026.9.2. Moving tags are refused" }
603
+ yes: { type: boolean, optional: true, default: false, description: "Skip the confirmation. Only when the user has already approved this specific update" }
604
+
605
+ - name: clawops_backup_create
606
+ toolset: [cli]
607
+ description: |
608
+ Take a backup of the gateway's state (config, database, sessions, transcripts and
609
+ installed plugins) and download it to a local archive. Live state is not changed.
610
+
611
+ Use when: the user asks for a backup, and before anything that replaces state: a
612
+ version update, a migration, a restore, or a plan that replaces the instance.
613
+
614
+ Do NOT use when: the user wants to back up cloud infrastructure — Pulumi state and plans
615
+ cover that, not this.
616
+ annotations:
617
+ title: Back Up Gateway State
618
+ readOnlyHint: false
619
+ destructiveHint: false
620
+ idempotentHint: false
621
+ openWorldHint: true
622
+ input:
623
+ stackName: { type: string, optional: true, description: "Which stack to back up. Omitted = the default stack in ~/.clawops/config.json" }
624
+ out: { type: string, optional: true, description: "Absolute local path to write the archive to. Omitted = a timestamped file under ~/.clawops/backups" }
625
+
626
+ - name: clawops_backup_restore
627
+ toolset: [cli]
628
+ description: |
629
+ Verify a backup archive and expand it on the host beside the live state, never over it.
630
+ With activate: true, also put it into service: stop the gateway, swap the restored state
631
+ in (keeping the state it replaces), restart, and roll back if the gateway does not answer.
632
+
633
+ Use when: the user asks to restore or recover from a backup, naming the archive.
634
+
635
+ Do NOT use when: the gateway is merely unhealthy — clawops_workflow_recover diagnoses that
636
+ without discarding state. Restoring is time travel: everything since the backup is lost,
637
+ and channel credentials may need relinking.
638
+ annotations:
639
+ title: Restore Gateway State (DESTRUCTIVE with activate)
640
+ readOnlyHint: false
641
+ destructiveHint: true
642
+ idempotentHint: false
643
+ openWorldHint: true
644
+ input:
645
+ stackName: { type: string, optional: true, description: "Which stack to restore onto. Omitted = the default stack in ~/.clawops/config.json" }
646
+ file: { type: string, description: "Absolute local path to the backup archive, as clawops_backup_create wrote it" }
647
+ activate: { type: boolean, optional: true, default: false, description: "Put the restored state into service. Omitted = expand into a staging directory and touch nothing live" }
648
+ yes: { type: boolean, optional: true, default: false, description: "Skip the confirmation. Only when the user has already approved this specific restore" }
649
+
650
+ - name: clawops_migrate
651
+ toolset: [cli]
652
+ description: |
653
+ Move a deployment from OpenClaw 1.x onto the 2.0 runtime contract: state ownership,
654
+ config, and the gateway's run command, in the order a real migration showed works.
655
+
656
+ Use when: a stack still runs OpenClaw 1.x and the user wants it on 2.x. clawops_doctor
657
+ and clawops_gateway_status say which line a stack runs.
658
+
659
+ Do NOT use when: the stack is already on 2.x — use clawops_gateway_update to change
660
+ versions within 2.x. Take a backup first with clawops_backup_create.
661
+ annotations:
662
+ title: Migrate 1.x to 2.0 (DESTRUCTIVE)
663
+ readOnlyHint: false
664
+ destructiveHint: true
665
+ idempotentHint: false
666
+ openWorldHint: true
667
+ input:
668
+ stackName: { type: string, optional: true, description: "Which stack to migrate. Omitted = the default stack in ~/.clawops/config.json" }
669
+ openclawVersion: { type: string, optional: true, description: "The OpenClaw 2.x version to migrate to. Omitted = the version this clawops release defaults to" }
670
+ yes: { type: boolean, optional: true, default: false, description: "Skip the confirmation. Only when the user has already approved this migration" }
671
+
672
+ - name: clawops_stacks_delete
673
+ toolset: [admin]
674
+ description: |
675
+ Remove a stack from ~/.clawops/config.json. This forgets the stack; it does not tear
676
+ down its infrastructure, and it refuses a stack that is still deployed unless forced.
677
+
678
+ Use when: the user wants to stop tracking a stack whose resources are already gone.
679
+
680
+ Do NOT use when: the user wants the infrastructure removed — that is clawops_destroy,
681
+ first. Forcing the delete of a deployed stack leaves resources running and billing that
682
+ clawops can no longer see.
683
+ annotations:
684
+ title: Forget a Stack (DESTRUCTIVE)
685
+ readOnlyHint: false
686
+ destructiveHint: true
687
+ idempotentHint: true
688
+ openWorldHint: false
689
+ input:
690
+ name: { type: string, description: "The stack to remove from config, as clawops_stacks_list reports it" }
691
+ force: { type: boolean, optional: true, default: false, description: "Skip the safety checks: allow deleting the default stack, or one still deployed. Omitted = refuse both" }
692
+ yes: { type: boolean, optional: true, default: false, description: "Skip the confirmation. Only when the user has already approved this deletion" }
693
+
694
+ - name: clawops_secret_delete
695
+ toolset: [cli]
696
+ description: |
697
+ Delete a locally stored secret by name. Warns when a stack still references it.
698
+
699
+ Use when: the user asks to remove a secret they no longer use.
700
+
701
+ Do NOT use when: the user wants to replace a value — ask them to run
702
+ `clawops secret rotate <NAME>`; no tool takes a secret value (R6).
703
+ annotations:
704
+ title: Delete a Stored Secret (DESTRUCTIVE)
705
+ readOnlyHint: false
706
+ destructiveHint: true
707
+ idempotentHint: true
708
+ openWorldHint: false
709
+ input:
710
+ name: { type: string, description: "The secret's name, as clawops_secret_list reports it" }
711
+ yes: { type: boolean, optional: true, default: false, description: "Skip the confirmation. Only when the user has already approved this deletion" }
712
+
507
713
  # ────────────────────────────────────────────────────────────────────────────
508
714
  # COMPOSITE WORKFLOW TOOLS (R2: encode user intent, not API sequences)
509
715
  # ────────────────────────────────────────────────────────────────────────────
510
716
 
717
+ - name: clawops_init
718
+ toolset: [cli]
719
+ description: |
720
+ Register a stack and write ~/.clawops/config.json: the provider, the state backend, the
721
+ region, and an SSH key pair generated if one is not already there. Nothing is provisioned
722
+ and nothing is charged; this only creates local configuration.
723
+
724
+ Use when: any other clawops tool reports that there is no config, or the user wants to add
725
+ a second stack alongside the ones they have. This is the first call on a machine that has
726
+ never run clawops — a fresh container, a new laptop, a sandbox.
727
+
728
+ Adding a stack is additive and safe: existing stacks are kept. Overwriting one needs
729
+ force: true, because changing a state backend orphans the Pulumi state it points at — the
730
+ infrastructure stays up and clawops can no longer see or destroy it.
731
+
732
+ For aws, gcp and azure, stateUrl can be omitted and clawops names a bucket from the
733
+ account it can see; that needs cloud credentials in the environment, so in a sandbox pass
734
+ stateUrl explicitly. The local provider needs host instead, and no cloud account at all.
735
+
736
+ Do NOT use when: the user wants to deploy — that is clawops_up, after this. Credentials
737
+ are never passed here: clawops reads them from the environment (R6).
738
+ annotations:
739
+ title: Initialise clawops Config
740
+ readOnlyHint: false
741
+ destructiveHint: false
742
+ idempotentHint: false
743
+ openWorldHint: false
744
+ input:
745
+ provider: { type: enum, values: [aws, gcp, azure, local], description: "Which cloud this stack deploys to, or 'local' for a machine you already have" }
746
+ stackName: { type: string, optional: true, description: "Name for the stack, used by every later call. Omitted = \"default\"" }
747
+ stateUrl: { type: string, optional: true, description: "Where Pulumi state lives, e.g. s3://bucket/clawops, gs://bucket/clawops, azblob://container. Omitted = clawops names one from the cloud account it can see, which needs credentials" }
748
+ region: { type: string, optional: true, description: "Cloud region in the provider's own spelling. Omitted = us-east-1 (aws), us-central1 (gcp), eastus (azure)" }
749
+ host: { type: string, optional: true, description: "[local only] Hostname or IP of the machine to manage. Required when provider is local" }
750
+ sshUser: { type: string, optional: true, description: "[local only] SSH login user. Omitted = root" }
751
+ sshPort: { type: integer, optional: true, description: "[local only] SSH port. Omitted = 22" }
752
+ force: { type: boolean, optional: true, description: "Overwrite a stack that already exists. Refused without it, because replacing a state backend orphans the state it points at" }
753
+ output:
754
+ configPath: { type: string }
755
+ stackName: { type: string }
756
+ stateUrl: { type: string }
757
+
511
758
  - name: clawops_harden
512
759
  toolset: [cli]
513
760
  description: |
@@ -543,7 +790,7 @@ tools:
543
790
  idempotentHint: true
544
791
  openWorldHint: true
545
792
  input:
546
- stackName: { type: string, optional: true }
793
+ stackName: { type: string, optional: true, description: "Which stack to harden. Omitted = the default stack in ~/.clawops/config.json" }
547
794
  options: { type: string, optional: true, description: "Comma-separated module IDs; default is every defaultOn module for the provider" }
548
795
  dryRun: { type: boolean, optional: true, default: false, description: "Report the current state, change nothing" }
549
796
  tailscale: { type: boolean, optional: true, default: false, description: "Join the tailnet, verify this machine reaches the host there, then use that address" }
@@ -577,14 +824,14 @@ tools:
577
824
  idempotentHint: true
578
825
  openWorldHint: true
579
826
  input:
580
- provider: { type: enum, values: [aws, gcp, azure, local] }
581
- region: { type: string, optional: true }
582
- stackName: { type: string, optional: true, default: "default" }
583
- instanceType: { type: enum, values: [micro, small, medium, large, gpu], optional: true, default: small }
827
+ provider: { type: enum, values: [aws, gcp, azure, local], description: "Cloud to deploy to. Omitted = the default provider in ~/.clawops/config.json" }
828
+ region: { type: string, optional: true, description: "Cloud region, in the provider's own spelling (us-east-1, us-central1, eastus). Omitted = the provider's default" }
829
+ stackName: { type: string, optional: true, default: "default", description: "Name for the new stack. Omitted = the default stack name in ~/.clawops/config.json" }
830
+ instanceType: { type: enum, values: [micro, small, medium, large, gpu], optional: true, default: small, description: "Machine size: a clawops alias (micro|small|medium|large|gpu) or a type the cloud names itself, e.g. t3.small" }
584
831
  output:
585
832
  taskId: { type: string }
586
833
  gatewayUrl: { type: string, format: uri }
587
- stackName: { type: string }
834
+ stackName: { type: string, description: "Name for the new stack. Omitted = the default stack name in ~/.clawops/config.json" }
588
835
 
589
836
  - name: clawops_workflow_recover
590
837
  toolset: [workflow, read]
@@ -605,7 +852,7 @@ tools:
605
852
  idempotentHint: true
606
853
  openWorldHint: true
607
854
  input:
608
- stackName: { type: string, optional: true }
855
+ stackName: { type: string, optional: true, description: "Which stack to diagnose. Omitted = the default stack in ~/.clawops/config.json" }
609
856
  output:
610
857
  report:
611
858
  type: object
@@ -633,7 +880,7 @@ tools:
633
880
  idempotentHint: true
634
881
  openWorldHint: false
635
882
  input:
636
- taskId: { type: string }
883
+ taskId: { type: string, description: "The taskId returned by a long-running tool such as clawops_up, clawops_apply or clawops_destroy" }
637
884
  output:
638
885
  status: { type: enum, values: [working, input_required, completed, failed, cancelled] }
639
886
  progress: { type: number, minimum: 0, maximum: 1 }
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- GATEWAY_LOGS_PROBE,
4
- agentAuditCommand,
5
- chooseLogSource,
6
- containerLogsCommand,
7
- gatewayLogsCommand
8
- } from "./chunk-NUL5F6YV.js";
9
- export {
10
- GATEWAY_LOGS_PROBE,
11
- agentAuditCommand,
12
- chooseLogSource,
13
- containerLogsCommand,
14
- gatewayLogsCommand
15
- };
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- MCP_HTTP_PORT,
4
- authRequirement,
5
- bearerFrom,
6
- isLoopbackBind,
7
- serveMcp
8
- } from "./chunk-T5XCMYAV.js";
9
- import "./chunk-R3DTA35B.js";
10
- import "./chunk-BOPSG2LI.js";
11
- import "./chunk-6ZFIFDBJ.js";
12
- import "./chunk-3QJBNAHW.js";
13
- import "./chunk-2I7KCMXZ.js";
14
- import "./chunk-3Z5TDXCJ.js";
15
- import "./chunk-AEEMRFZV.js";
16
- import "./chunk-IQQTB7ER.js";
17
- import "./chunk-XFN3YDZE.js";
18
- import "./chunk-2Z7J3ERQ.js";
19
- import "./chunk-E4NJSJ54.js";
20
- import "./chunk-MC5ATCXS.js";
21
- import "./chunk-QDNFADJI.js";
22
- import "./chunk-GFUK6KDR.js";
23
- import "./chunk-NUL5F6YV.js";
24
- import "./chunk-3OLUJPCB.js";
25
- import "./chunk-NUDIHZEH.js";
26
- import "./chunk-JW5A7E3X.js";
27
- import "./chunk-LT4XMO5D.js";
28
- import "./chunk-BELTQGHT.js";
29
- import "./chunk-GIEVAGEK.js";
30
- import "./chunk-VOEJYRIK.js";
31
- import "./chunk-EI7CQQ7D.js";
32
- import "./chunk-FEK7VJAY.js";
33
- import "./chunk-RHOWYIWT.js";
34
- import "./chunk-Q7NQY5HV.js";
35
- import "./chunk-N4WZLWJ4.js";
36
- import "./chunk-ELU3XQEA.js";
37
- import "./chunk-64PONSA5.js";
38
- import "./chunk-KGXPLI7W.js";
39
- import "./chunk-VUFMZEIM.js";
40
- export {
41
- MCP_HTTP_PORT,
42
- authRequirement,
43
- bearerFrom,
44
- isLoopbackBind,
45
- serveMcp
46
- };
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- connect,
4
- describeConnectError
5
- } from "./chunk-E4NJSJ54.js";
6
- import "./chunk-MC5ATCXS.js";
7
- import "./chunk-KGXPLI7W.js";
8
- export {
9
- connect,
10
- describeConnectError
11
- };
@@ -1,88 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/openclaw/upgrade.ts
4
- function judgePreflight(report) {
5
- const { targetVersion, foundVersion, status, reason } = report;
6
- if (status === "indeterminate") {
7
- return {
8
- ok: false,
9
- reason: reason ?? "the database schema could not be determined, so compatibility with the target release is unknown"
10
- };
11
- }
12
- if (typeof foundVersion === "number" && typeof targetVersion === "number") {
13
- if (foundVersion > targetVersion) {
14
- return {
15
- ok: false,
16
- reason: `the state database is at schema ${foundVersion}, but the target release understands ${targetVersion}. This is a downgrade across a schema boundary: the older release would read a database written by a newer one. Restore a backup taken before the upgrade instead.`
17
- };
18
- }
19
- if (foundVersion < targetVersion) {
20
- return { ok: true, note: `state will migrate from schema ${foundVersion} to ${targetVersion}` };
21
- }
22
- return { ok: true };
23
- }
24
- return {
25
- ok: false,
26
- reason: reason ?? `preflight returned no schema version (status: ${status ?? "unknown"})`
27
- };
28
- }
29
- function parsePreflight(stdout) {
30
- try {
31
- const parsed = JSON.parse(stdout.trim());
32
- if (parsed !== null && typeof parsed === "object") return parsed;
33
- } catch {
34
- }
35
- return void 0;
36
- }
37
- function snapshotCommand(image, stateDir, repo) {
38
- return `docker run --rm -v ${stateDir}:/home/node/.openclaw ${image} openclaw backup sqlite create --global --repository ${repo} --json`;
39
- }
40
- function preflightCommand(targetImage, stateDir, snapshotDb) {
41
- return `docker run --rm -v ${stateDir}:/home/node/.openclaw ${targetImage} openclaw database preflight ${snapshotDb} --json`;
42
- }
43
- function snapshotPathFrom(stdout) {
44
- try {
45
- const parsed = JSON.parse(stdout.trim());
46
- if (parsed.ok === true && typeof parsed.snapshotPath === "string") return parsed.snapshotPath;
47
- } catch {
48
- }
49
- return void 0;
50
- }
51
- function repairCommand(image, stateDir) {
52
- return `docker run --rm -v ${stateDir}:/home/node/.openclaw ${image} openclaw doctor --fix --non-interactive --yes`;
53
- }
54
- function describeOutcome(o, version) {
55
- switch (o.kind) {
56
- case "started":
57
- return `Gateway updated to ${version}.`;
58
- case "repaired":
59
- return `Gateway updated to ${version} after a one-shot repair (doctor --fix).`;
60
- case "rolled-back":
61
- return `Rolled back to ${o.to}: the gateway did not start on ${version} \u2014 ${o.reason}. The previous image is running again. If it also fails, restore the snapshot taken before the upgrade.`;
62
- case "failed":
63
- return `Upgrade to ${version} failed and the rollback did not come up either \u2014 ${o.reason}. The state snapshot taken before the upgrade is at ${o.snapshotPath}; restore it with \`openclaw backup sqlite restore\` before retrying.`;
64
- }
65
- }
66
- async function resolveUpgrade(steps, ctx) {
67
- const first = await steps.gate();
68
- if (first.ok) return { kind: "started" };
69
- await steps.repair();
70
- await steps.run(ctx.version);
71
- const second = await steps.gate();
72
- if (second.ok) return { kind: "repaired" };
73
- const reason = second.reason ?? first.reason ?? "unknown";
74
- if (!ctx.previousVersion) return { kind: "failed", reason, snapshotPath: ctx.snapshotPath };
75
- await steps.run(ctx.previousVersion);
76
- const back = await steps.gate();
77
- return back.ok ? { kind: "rolled-back", to: ctx.previousVersion, reason } : { kind: "failed", reason, snapshotPath: ctx.snapshotPath };
78
- }
79
- export {
80
- describeOutcome,
81
- judgePreflight,
82
- parsePreflight,
83
- preflightCommand,
84
- repairCommand,
85
- resolveUpgrade,
86
- snapshotCommand,
87
- snapshotPathFrom
88
- };
File without changes