@clawops/cli 1.1.0 → 1.2.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 (39) hide show
  1. package/README.md +115 -44
  2. package/dist/apply-KBF7OPWL.js +14 -0
  3. package/dist/{automation-JG2YBEL7.js → automation-RULUSJBW.js} +2 -2
  4. package/dist/{aws-A3323GNM.js → aws-KQBWY43W.js} +12 -10
  5. package/dist/{azure-LNWBK2ZI.js → azure-4EJFVJZL.js} +4 -3
  6. package/dist/{bootstrap-7ZS2GLFJ.js → bootstrap-UYCOEJQX.js} +48 -12
  7. package/dist/{chunk-LT24GUUO.js → chunk-3QJBNAHW.js} +1 -1
  8. package/dist/{chunk-BA6MDFZK.js → chunk-4U3LTLWZ.js} +2 -83
  9. package/dist/{chunk-PERSDQMT.js → chunk-ACYJBSLJ.js} +7 -7
  10. package/dist/chunk-BOPSG2LI.js +77 -0
  11. package/dist/{chunk-PRYLTCS4.js → chunk-BRPU7AQC.js} +1 -1
  12. package/dist/{chunk-ALSUDYA7.js → chunk-CX5SL5HP.js} +1 -1
  13. package/dist/{chunk-ZSE4QRKE.js → chunk-KGXPLI7W.js} +19 -1
  14. package/dist/chunk-LU63NZD3.js +116 -0
  15. package/dist/chunk-OIGTOLB3.js +99 -0
  16. package/dist/chunk-QJ6ERXHN.js +266 -0
  17. package/dist/{chunk-D4UAHAKI.js → chunk-SSB6SGPQ.js} +10 -6
  18. package/dist/chunk-UDNZUSKA.js +97 -0
  19. package/dist/chunk-ZVOEQCNW.js +92 -0
  20. package/dist/cli.js +1340 -115
  21. package/dist/context-VUAYRAJY.js +10 -0
  22. package/dist/errors-OK47MQFD.js +21 -0
  23. package/dist/{gcp-OHWCTFLL.js → gcp-SKURG3L6.js} +4 -3
  24. package/dist/generate-PZPLG3ZM.js +14 -0
  25. package/dist/js-yaml-PTEEG4FO.js +2647 -0
  26. package/dist/mcp-apps-KY44ED3Y.js +11 -0
  27. package/dist/{outputs-6DAVEEAZ.js → outputs-DJHBY7EE.js} +2 -2
  28. package/dist/{package-FA6UOG2I.js → package-SE3M4NJA.js} +1 -1
  29. package/dist/{pool-FAVU7WCW.js → pool-FBFHATDG.js} +3 -2
  30. package/dist/remote-config-JQ77SRC2.js +21 -0
  31. package/dist/secrets-SVZWNAPK.js +7 -0
  32. package/dist/{server-V5ZFL76Y.js → server-4DNHLGEG.js} +64 -150
  33. package/dist/ssh-IQXNME3D.js +8 -0
  34. package/dist/{store-ARJ2EO6L.js → store-SDUR52Z5.js} +2 -2
  35. package/package.json +1 -1
  36. package/dist/apply-DPS23GLL.js +0 -12
  37. package/dist/chunk-UCIVU24B.js +0 -56
  38. package/dist/context-T52JWL3P.js +0 -10
  39. package/dist/generate-55MITRXU.js +0 -14
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ MCP_APPS,
4
+ buildMcpEntry,
5
+ writeAppConfigs
6
+ } from "./chunk-OIGTOLB3.js";
7
+ export {
8
+ MCP_APPS,
9
+ buildMcpEntry,
10
+ writeAppConfigs
11
+ };
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  extractBaseOutputs
4
- } from "./chunk-LT24GUUO.js";
5
- import "./chunk-ZSE4QRKE.js";
4
+ } from "./chunk-3QJBNAHW.js";
5
+ import "./chunk-KGXPLI7W.js";
6
6
  export {
7
7
  extractBaseOutputs
8
8
  };
@@ -2,7 +2,7 @@
2
2
 
3
3
  // package.json
4
4
  var name = "@clawops/cli";
5
- var version = "1.1.0";
5
+ var version = "1.2.1";
6
6
  var description = "Deploy and manage self-hosted OpenClaw instances across clouds";
7
7
  var type = "module";
8
8
  var bin = {
@@ -2,8 +2,9 @@
2
2
  import {
3
3
  acquireSession,
4
4
  drainPool
5
- } from "./chunk-BA6MDFZK.js";
6
- import "./chunk-ZSE4QRKE.js";
5
+ } from "./chunk-ZVOEQCNW.js";
6
+ import "./chunk-4U3LTLWZ.js";
7
+ import "./chunk-KGXPLI7W.js";
7
8
  export {
8
9
  acquireSession,
9
10
  drainPool
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ OPENCLAW_CONFIG,
4
+ OPENCLAW_CONFIG_LINUX,
5
+ OPENCLAW_CONFIG_MACOS,
6
+ OPENCLAW_TMP,
7
+ atomicWriteConfig,
8
+ deepMerge,
9
+ readRemoteConfig,
10
+ restartGateway
11
+ } from "./chunk-UDNZUSKA.js";
12
+ export {
13
+ OPENCLAW_CONFIG,
14
+ OPENCLAW_CONFIG_LINUX,
15
+ OPENCLAW_CONFIG_MACOS,
16
+ OPENCLAW_TMP,
17
+ atomicWriteConfig,
18
+ deepMerge,
19
+ readRemoteConfig,
20
+ restartGateway
21
+ };
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveSecrets
4
+ } from "./chunk-BOPSG2LI.js";
5
+ export {
6
+ resolveSecrets
7
+ };
@@ -1,32 +1,44 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- acquireSession,
4
- drainPool
5
- } from "./chunk-BA6MDFZK.js";
6
- import {
7
- extractBaseOutputs
8
- } from "./chunk-LT24GUUO.js";
9
2
  import {
10
3
  generatePlan
11
- } from "./chunk-D4UAHAKI.js";
4
+ } from "./chunk-SSB6SGPQ.js";
12
5
  import {
13
6
  applyPlan
14
- } from "./chunk-UCIVU24B.js";
15
- import {
16
- buildContext
17
- } from "./chunk-PERSDQMT.js";
18
- import "./chunk-PRYLTCS4.js";
7
+ } from "./chunk-LU63NZD3.js";
19
8
  import {
20
9
  validatePlan
21
10
  } from "./chunk-YTH4L2GN.js";
11
+ import "./chunk-BOPSG2LI.js";
12
+ import {
13
+ extractBaseOutputs
14
+ } from "./chunk-3QJBNAHW.js";
15
+ import {
16
+ errText,
17
+ handleConfigGet,
18
+ handleConfigSet,
19
+ handleConfigUnset,
20
+ handleConfigValidate,
21
+ okText,
22
+ resolveConn
23
+ } from "./chunk-QJ6ERXHN.js";
24
+ import {
25
+ buildContext
26
+ } from "./chunk-ACYJBSLJ.js";
27
+ import "./chunk-BRPU7AQC.js";
28
+ import {
29
+ acquireSession,
30
+ drainPool
31
+ } from "./chunk-ZVOEQCNW.js";
32
+ import "./chunk-4U3LTLWZ.js";
33
+ import "./chunk-UDNZUSKA.js";
22
34
  import {
23
35
  getConfig,
24
36
  getConfigDir
25
- } from "./chunk-ALSUDYA7.js";
37
+ } from "./chunk-CX5SL5HP.js";
26
38
  import {
27
39
  StateError,
28
40
  UsageError
29
- } from "./chunk-ZSE4QRKE.js";
41
+ } from "./chunk-KGXPLI7W.js";
30
42
 
31
43
  // src/mcp/server.ts
32
44
  import { createServer } from "http";
@@ -45,7 +57,7 @@ function getSessionId() {
45
57
  if (!_sessionId) _sessionId = randomUUID();
46
58
  return _sessionId;
47
59
  }
48
- var SENSITIVE_KEYS = ["token", "secret", "password", "connectionstring", "authorization"];
60
+ var SENSITIVE_KEYS = ["token", "secret", "key", "password", "connectionstring", "authorization"];
49
61
  var EXEMPT_KEYS = ["keyname", "keypath", "privateKeyPath", "knownHostsPath"];
50
62
  var ARN_RE = /arn:aws:[a-z0-9\-*]+:[a-z0-9\-]*:[0-9]*:[^\s,'"]+/gi;
51
63
  function sanitize(args) {
@@ -60,6 +72,10 @@ function sanitize(args) {
60
72
  result[k] = v.replace(ARN_RE, "arn:aws:***:<region>:<account>:***");
61
73
  } else if (v !== null && typeof v === "object" && !Array.isArray(v)) {
62
74
  result[k] = sanitize(v);
75
+ } else if (Array.isArray(v)) {
76
+ result[k] = v.map(
77
+ (item) => item !== null && typeof item === "object" && !Array.isArray(item) ? sanitize(item) : item
78
+ );
63
79
  } else {
64
80
  result[k] = v;
65
81
  }
@@ -145,7 +161,7 @@ var clawops_stacks_listAnnotations = {
145
161
  };
146
162
  var clawops_config_getSchema = z.object({
147
163
  stackName: z.string().optional(),
148
- key: z.string()
164
+ key: z.string().optional()
149
165
  });
150
166
  var clawops_config_getAnnotations = {
151
167
  title: "Get OpenClaw Config Value",
@@ -235,6 +251,30 @@ var clawops_config_setAnnotations = {
235
251
  openWorldHint: true,
236
252
  toolsets: ["cli"]
237
253
  };
254
+ var clawops_config_unsetSchema = z.object({
255
+ stackName: z.string().optional(),
256
+ key: z.string(),
257
+ restart: z.boolean().default(false)
258
+ });
259
+ var clawops_config_unsetAnnotations = {
260
+ title: "Unset OpenClaw Config Key",
261
+ readOnlyHint: false,
262
+ destructiveHint: true,
263
+ idempotentHint: true,
264
+ openWorldHint: true,
265
+ toolsets: ["cli"]
266
+ };
267
+ var clawops_config_validateSchema = z.object({
268
+ stackName: z.string().optional()
269
+ });
270
+ var clawops_config_validateAnnotations = {
271
+ title: "Validate OpenClaw Config",
272
+ readOnlyHint: true,
273
+ destructiveHint: false,
274
+ idempotentHint: true,
275
+ openWorldHint: true,
276
+ toolsets: ["cli", "read"]
277
+ };
238
278
  var clawops_agents_restartSchema = z.object({
239
279
  stackName: z.string().optional(),
240
280
  agentId: z.string()
@@ -305,6 +345,8 @@ var TOOLSETS = {
305
345
  "clawops_apply",
306
346
  "clawops_plan",
307
347
  "clawops_config_set",
348
+ "clawops_config_unset",
349
+ "clawops_config_validate",
308
350
  "clawops_agents_restart",
309
351
  "clawops_gateway_restart",
310
352
  "clawops_task_status"
@@ -320,6 +362,7 @@ var TOOLSETS = {
320
362
  "clawops_config_get",
321
363
  "clawops_agents_list",
322
364
  "clawops_plan",
365
+ "clawops_config_validate",
323
366
  "clawops_workflow_recover",
324
367
  "clawops_task_status"
325
368
  ],
@@ -360,42 +403,6 @@ function text(t) {
360
403
  return { content: [{ type: "text", text: t }] };
361
404
  }
362
405
 
363
- // src/mcp/tools/_conn.ts
364
- async function resolveConn(ctx) {
365
- if (ctx.adapter.name === "local") {
366
- const state = ctx.localState;
367
- if (!state) throw new StateError("Stack has no local state \u2014 run `clawops up` first.");
368
- return {
369
- host: state.sshHost,
370
- port: state.sshPort,
371
- user: state.sshUser,
372
- privateKeyPath: state.privateKeyPath,
373
- knownHostsPath: state.knownHostsPath
374
- };
375
- }
376
- const { extractBaseOutputs: extractBaseOutputs2 } = await import("./outputs-6DAVEEAZ.js");
377
- const stack = await ctx.getStack();
378
- const outputMap = await stack.outputs();
379
- const outputs = Object.fromEntries(
380
- Object.entries(outputMap).map(([k, v]) => [k, v.value])
381
- );
382
- if (!outputs["publicIp"]) {
383
- throw new StateError("Stack has no outputs \u2014 run `clawops up` first.");
384
- }
385
- const base = extractBaseOutputs2(outputs);
386
- return ctx.adapter.getConnectionInfo({
387
- ...base,
388
- privateKeyPath: ctx.config.ssh.keyPath,
389
- knownHostsPath: ctx.config.ssh.knownHostsPath
390
- });
391
- }
392
- function errText(message) {
393
- return { content: [{ type: "text", text: message }], isError: true };
394
- }
395
- function okText(t) {
396
- return { content: [{ type: "text", text: t }] };
397
- }
398
-
399
406
  // src/mcp/tools/cli/logs.ts
400
407
  var MAX_BYTES = 8 * 1024;
401
408
  async function handleLogsTail(input, _server) {
@@ -444,101 +451,6 @@ async function handleStacksList(_input, _server) {
444
451
  return { content: [{ type: "text", text: JSON.stringify({ stacks }, null, 2) }] };
445
452
  }
446
453
 
447
- // src/mcp/tools/cli/config.ts
448
- var OPENCLAW_CONFIG = "/home/clawops/openclaw.json";
449
- var OPENCLAW_TMP = "/tmp/clawops-config.json.tmp";
450
- async function handleConfigGet(input, _server) {
451
- const ctx = buildContext({ stack: input.stackName });
452
- const conn = await resolveConn(ctx);
453
- const { session, release } = await acquireSession(conn);
454
- try {
455
- const result = await session.exec(`cat ${OPENCLAW_CONFIG}`);
456
- let cfg;
457
- try {
458
- cfg = JSON.parse(result.stdout);
459
- } catch {
460
- return errText(`Cannot parse ${OPENCLAW_CONFIG}: ${result.stderr || result.stdout}`);
461
- }
462
- const value = input.key ? getPath(cfg, input.key) : cfg;
463
- return okText(JSON.stringify(value, null, 2));
464
- } finally {
465
- release();
466
- drainPool();
467
- }
468
- }
469
- async function handleConfigSet(input, server) {
470
- const elicit = await server.server.elicitInput({
471
- message: `Set ${input.key} = ${input.value} on stack "${input.stackName ?? "default"}"?`,
472
- requestedSchema: {
473
- type: "object",
474
- properties: { confirmed: { type: "boolean", title: "Confirm config change" } },
475
- required: ["confirmed"]
476
- }
477
- });
478
- if (elicit.action !== "accept" || !elicit.content?.["confirmed"]) {
479
- return okText("Config change cancelled.");
480
- }
481
- const ctx = buildContext({ stack: input.stackName });
482
- const conn = await resolveConn(ctx);
483
- const { session, release } = await acquireSession(conn);
484
- try {
485
- const readResult = await session.exec(`cat ${OPENCLAW_CONFIG}`);
486
- let cfg;
487
- try {
488
- cfg = JSON.parse(readResult.stdout);
489
- } catch {
490
- return errText(`Cannot parse ${OPENCLAW_CONFIG}: ${readResult.stderr}`);
491
- }
492
- let parsedValue = input.value;
493
- try {
494
- parsedValue = JSON.parse(input.value);
495
- } catch {
496
- }
497
- setPath(cfg, input.key, parsedValue);
498
- const json = JSON.stringify(cfg, null, 2);
499
- const b64 = Buffer.from(json, "utf-8").toString("base64");
500
- const writeCmd = `echo '${b64}' | base64 -d > ${OPENCLAW_TMP} && mv ${OPENCLAW_TMP} ${OPENCLAW_CONFIG} && chown clawops:clawops ${OPENCLAW_CONFIG}`;
501
- const writeResult = await session.exec(writeCmd);
502
- if (writeResult.code !== 0) {
503
- return errText(`Failed to write config: ${writeResult.stderr}`);
504
- }
505
- let note = "";
506
- if (input.restart) {
507
- const imgResult = await session.exec(
508
- `docker inspect openclaw --format '{{.Config.Image}}' 2>/dev/null || echo 'ghcr.io/openclaw/openclaw:stable'`
509
- );
510
- const image = imgResult.stdout.trim();
511
- const restartCmd = [
512
- "docker stop openclaw 2>/dev/null || true",
513
- "docker rm openclaw 2>/dev/null || true",
514
- `docker run -d --name openclaw --restart unless-stopped -p 18789:18789 -v ${OPENCLAW_CONFIG}:/app/config.json:ro ${image}`
515
- ].join(" && ");
516
- await session.exec(restartCmd);
517
- note = " (gateway restarted)";
518
- }
519
- return okText(`Config set: ${input.key}${note}`);
520
- } finally {
521
- release();
522
- drainPool();
523
- }
524
- }
525
- function getPath(obj, dotKey) {
526
- return dotKey.split(".").reduce((cur, k) => {
527
- if (cur !== null && typeof cur === "object") return cur[k];
528
- return void 0;
529
- }, obj);
530
- }
531
- function setPath(obj, dotKey, value) {
532
- const keys = dotKey.split(".");
533
- let cur = obj;
534
- for (let i = 0; i < keys.length - 1; i++) {
535
- const k = keys[i];
536
- if (typeof cur[k] !== "object" || cur[k] === null) cur[k] = {};
537
- cur = cur[k];
538
- }
539
- cur[keys[keys.length - 1]] = value;
540
- }
541
-
542
454
  // src/mcp/tools/cli/agents.ts
543
455
  async function handleAgentsList(input, _server) {
544
456
  const ctx = buildContext({ stack: input.stackName });
@@ -701,7 +613,7 @@ async function handleUp(input, server) {
701
613
  );
702
614
  }
703
615
  const { localOpts } = stackConfig;
704
- const { localBootstrap } = await import("./bootstrap-7ZS2GLFJ.js");
616
+ const { localBootstrap } = await import("./bootstrap-UYCOEJQX.js");
705
617
  const ac = new AbortController();
706
618
  const state = await localBootstrap({
707
619
  host: localOpts.host,
@@ -1042,6 +954,8 @@ var TOOL_REGISTRY = {
1042
954
  clawops_apply: makeEntry(clawops_applySchema, clawops_applyAnnotations, handleApply),
1043
955
  clawops_plan: makeEntry(clawops_planSchema, clawops_planAnnotations, handlePlan),
1044
956
  clawops_config_set: makeEntry(clawops_config_setSchema, clawops_config_setAnnotations, handleConfigSet),
957
+ clawops_config_unset: makeEntry(clawops_config_unsetSchema, clawops_config_unsetAnnotations, handleConfigUnset),
958
+ clawops_config_validate: makeEntry(clawops_config_validateSchema, clawops_config_validateAnnotations, handleConfigValidate),
1045
959
  clawops_agents_restart: makeEntry(clawops_agents_restartSchema, clawops_agents_restartAnnotations, handleAgentsRestart),
1046
960
  clawops_gateway_restart: makeEntry(clawops_gateway_restartSchema, clawops_gateway_restartAnnotations, handleGatewayRestart),
1047
961
  clawops_workflow_deploy_app: makeEntry(clawops_workflow_deploy_appSchema, clawops_workflow_deploy_appAnnotations, handleWorkflowDeployApp),
@@ -1317,7 +1231,7 @@ If none of the above resolves the issue:
1317
1231
 
1318
1232
  // src/mcp/server.ts
1319
1233
  async function serveMcp(opts) {
1320
- const { version } = await import("./package-FA6UOG2I.js");
1234
+ const { version } = await import("./package-SE3M4NJA.js");
1321
1235
  const server = new McpServer({ name: "clawops", version });
1322
1236
  registerTools(server, opts);
1323
1237
  registerResources(server);
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ connect
4
+ } from "./chunk-4U3LTLWZ.js";
5
+ import "./chunk-KGXPLI7W.js";
6
+ export {
7
+ connect
8
+ };
@@ -5,8 +5,8 @@ import {
5
5
  getConfigPath,
6
6
  requireConfig,
7
7
  setConfig
8
- } from "./chunk-ALSUDYA7.js";
9
- import "./chunk-ZSE4QRKE.js";
8
+ } from "./chunk-CX5SL5HP.js";
9
+ import "./chunk-KGXPLI7W.js";
10
10
  export {
11
11
  getConfig,
12
12
  getConfigDir,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawops/cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Deploy and manage self-hosted OpenClaw instances across clouds",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- applyPlan
4
- } from "./chunk-UCIVU24B.js";
5
- import "./chunk-PERSDQMT.js";
6
- import "./chunk-PRYLTCS4.js";
7
- import "./chunk-YTH4L2GN.js";
8
- import "./chunk-ALSUDYA7.js";
9
- import "./chunk-ZSE4QRKE.js";
10
- export {
11
- applyPlan
12
- };
@@ -1,56 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- buildContext
4
- } from "./chunk-PERSDQMT.js";
5
- import {
6
- validatePlan
7
- } from "./chunk-YTH4L2GN.js";
8
- import {
9
- UsageError
10
- } from "./chunk-ZSE4QRKE.js";
11
-
12
- // src/plan/apply.ts
13
- async function applyPlan(plan, opts) {
14
- const validation = validatePlan(plan);
15
- if (!validation.ok) {
16
- throw new UsageError(
17
- `Invalid deploy plan:
18
- ${validation.errors.join("\n")}`
19
- );
20
- }
21
- if (plan.spec.provider === "local") {
22
- throw new UsageError(
23
- "plan/apply is not supported for the local provider. Use `clawops up` directly."
24
- );
25
- }
26
- const ctx = buildContext({
27
- stack: plan.spec.stackName,
28
- provider: plan.spec.provider
29
- });
30
- const stack = await ctx.getStack();
31
- await stack.setConfig("instanceType", { value: plan.spec.instanceType });
32
- if (plan.spec.region) {
33
- await stack.setConfig("region", { value: plan.spec.region });
34
- }
35
- await stack.setConfig("openclawVersion", { value: plan.spec.openclaw.version });
36
- const start = Date.now();
37
- const result = await stack.up({ onOutput: opts?.onOutput, signal: opts?.signal });
38
- const outputs = Object.fromEntries(
39
- Object.entries(result.outputs).map(([k, v]) => [k, v.value])
40
- );
41
- const changeSummary = {};
42
- if (result.summary.resourceChanges) {
43
- for (const [op, count] of Object.entries(result.summary.resourceChanges)) {
44
- changeSummary[op] = count;
45
- }
46
- }
47
- return {
48
- outputs,
49
- changeSummary,
50
- durationMs: Date.now() - start
51
- };
52
- }
53
-
54
- export {
55
- applyPlan
56
- };
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- buildContext
4
- } from "./chunk-PERSDQMT.js";
5
- import "./chunk-PRYLTCS4.js";
6
- import "./chunk-ALSUDYA7.js";
7
- import "./chunk-ZSE4QRKE.js";
8
- export {
9
- buildContext
10
- };
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- generatePlan,
4
- planId
5
- } from "./chunk-D4UAHAKI.js";
6
- import "./chunk-PERSDQMT.js";
7
- import "./chunk-PRYLTCS4.js";
8
- import "./chunk-YTH4L2GN.js";
9
- import "./chunk-ALSUDYA7.js";
10
- import "./chunk-ZSE4QRKE.js";
11
- export {
12
- generatePlan,
13
- planId
14
- };