@clawops/cli 1.3.0 → 1.5.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 (45) hide show
  1. package/README.md +136 -0
  2. package/dist/{apply-DLNE2JYZ.js → apply-5RREMN3L.js} +3 -3
  3. package/dist/automation-RULUSJBW.js +0 -0
  4. package/dist/{aws-KQBWY43W.js → aws-FRE2JVAZ.js} +9 -4
  5. package/dist/{azure-4EJFVJZL.js → azure-PVC3AQVC.js} +11 -4
  6. package/dist/bootstrap-G4UZ2FKH.js +0 -0
  7. package/dist/chunk-3QJBNAHW.js +0 -0
  8. package/dist/chunk-4U3LTLWZ.js +0 -0
  9. package/dist/chunk-6ZFIFDBJ.js +0 -0
  10. package/dist/chunk-A2I76FTA.js +0 -0
  11. package/dist/chunk-BOPSG2LI.js +0 -0
  12. package/dist/chunk-CX5SL5HP.js +0 -0
  13. package/dist/{chunk-ZDPBBYYV.js → chunk-IVX62LFO.js} +2 -2
  14. package/dist/chunk-KGXPLI7W.js +0 -0
  15. package/dist/chunk-OIGTOLB3.js +0 -0
  16. package/dist/chunk-R5S6IXBE.js +771 -0
  17. package/dist/{chunk-JDN6PLH2.js → chunk-T5EX55GP.js} +3 -3
  18. package/dist/chunk-YTH4L2GN.js +0 -0
  19. package/dist/{chunk-UDNZUSKA.js → chunk-ZFNPM2WG.js} +1 -1
  20. package/dist/{chunk-JCUZU5BH.js → chunk-ZONXY3C6.js} +2 -2
  21. package/dist/chunk-ZVOEQCNW.js +0 -0
  22. package/dist/cli.js +207 -53
  23. package/dist/{context-M2RMDHX6.js → context-PSGEX2D7.js} +1 -1
  24. package/dist/errors-OK47MQFD.js +0 -0
  25. package/dist/firewall-YYDOWDDP.js +0 -0
  26. package/dist/{gcp-SKURG3L6.js → gcp-BXDTC6EK.js} +60 -17
  27. package/dist/{generate-U7PJ5LRG.js → generate-2QGKYR42.js} +2 -2
  28. package/dist/js-yaml-PTEEG4FO.js +0 -0
  29. package/dist/local-DXBEVZ5C.js +0 -0
  30. package/dist/mcp-apps-KY44ED3Y.js +0 -0
  31. package/dist/mcp-wire-ZWIYMLEW.js +45 -0
  32. package/dist/outputs-DJHBY7EE.js +0 -0
  33. package/dist/overlay-store-ADZPD7EU.js +0 -0
  34. package/dist/{package-AFUTH62F.js → package-QLDA65A3.js} +2 -1
  35. package/dist/pool-FBFHATDG.js +0 -0
  36. package/dist/providers-2OABPW2E.js +0 -0
  37. package/dist/{remote-config-JQ77SRC2.js → remote-config-QF5TT7GU.js} +1 -1
  38. package/dist/secrets-SVZWNAPK.js +0 -0
  39. package/dist/{server-I62UES5V.js → server-LOL2NUJ2.js} +92 -19
  40. package/dist/ssh-IQXNME3D.js +0 -0
  41. package/dist/state-PRBIIN7I.js +0 -0
  42. package/dist/store-SDUR52Z5.js +0 -0
  43. package/dist/validate-T5M5EHSJ.js +0 -0
  44. package/package.json +27 -14
  45. package/dist/chunk-LVIIYY27.js +0 -266
@@ -1,21 +1,40 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/providers/gcp/index.ts
4
- import process from "process";
4
+ import process2 from "process";
5
5
 
6
6
  // src/providers/gcp/program.ts
7
7
  var GATEWAY_PORT = 18789;
8
8
  var SSH_PORT = 22;
9
9
  var gcpProgram = async () => {
10
- const [pulumi, gcp] = await Promise.all([
10
+ const [pulumi, gcp, { resolveIngressCidrs, detectEgressIp }] = await Promise.all([
11
11
  import("@pulumi/pulumi"),
12
- import("@pulumi/gcp")
12
+ import("@pulumi/gcp"),
13
+ import("./firewall-YYDOWDDP.js")
13
14
  ]);
14
15
  const cfg = new pulumi.Config();
15
16
  const instanceType = cfg.get("instanceType") ?? "e2-standard-2";
16
17
  const region = cfg.get("region") ?? "us-central1";
17
18
  const openclawVersion = cfg.get("openclawVersion") ?? "latest";
18
19
  const zone = cfg.get("zone") ?? `${region}-a`;
20
+ const accessMode = cfg.get("accessMode") ?? "restricted";
21
+ const allowedCidrs = cfg.get("allowedCidrs") ?? "";
22
+ const sshCidrs = cfg.get("sshCidrs") ?? "";
23
+ const gatewayCidrs = cfg.get("gatewayCidrs") ?? "";
24
+ const sshPublicKey = cfg.get("sshPublicKey");
25
+ if (!sshPublicKey) {
26
+ throw new Error(
27
+ 'Stack config "sshPublicKey" is required for the GCP adapter. Set it with: pulumi config set --stack <name> sshPublicKey "ssh-ed25519 ..."'
28
+ );
29
+ }
30
+ const detectedIp = accessMode === "auto" ? await detectEgressIp("https://checkip.amazonaws.com") : "";
31
+ if (accessMode === "open") {
32
+ process.stderr.write(
33
+ "[clawops] WARNING: accessMode=open allows 0.0.0.0/0 on SSH and gateway ports. Only use this for development/sandbox stacks.\n"
34
+ );
35
+ }
36
+ const sshIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, sshCidrs, detectedIp);
37
+ const gatewayIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, gatewayCidrs, detectedIp);
19
38
  const network = new gcp.compute.Network("clawops-network", {
20
39
  autoCreateSubnetworks: false,
21
40
  description: "clawops managed network"
@@ -25,17 +44,22 @@ var gcpProgram = async () => {
25
44
  region,
26
45
  network: network.id
27
46
  });
28
- new gcp.compute.Firewall("clawops-firewall", {
29
- network: network.selfLink,
30
- allows: [
31
- {
32
- protocol: "tcp",
33
- ports: [String(SSH_PORT), String(GATEWAY_PORT)]
34
- }
35
- ],
36
- sourceRanges: ["0.0.0.0/0"],
37
- targetTags: ["clawops"]
38
- });
47
+ if (sshIngressCidrs.length > 0) {
48
+ new gcp.compute.Firewall("clawops-firewall-ssh", {
49
+ network: network.selfLink,
50
+ allows: [{ protocol: "tcp", ports: [String(SSH_PORT)] }],
51
+ sourceRanges: sshIngressCidrs,
52
+ targetTags: ["clawops"]
53
+ });
54
+ }
55
+ if (gatewayIngressCidrs.length > 0) {
56
+ new gcp.compute.Firewall("clawops-firewall-gateway", {
57
+ network: network.selfLink,
58
+ allows: [{ protocol: "tcp", ports: [String(GATEWAY_PORT)] }],
59
+ sourceRanges: gatewayIngressCidrs,
60
+ targetTags: ["clawops"]
61
+ });
62
+ }
39
63
  const address = new gcp.compute.Address("clawops-address", { region });
40
64
  const instance = new gcp.compute.Instance("clawops-instance", {
41
65
  machineType: instanceType,
@@ -60,6 +84,8 @@ var gcpProgram = async () => {
60
84
  }
61
85
  ],
62
86
  metadata: {
87
+ // GCP guest agent reads 'ssh-keys' and populates /home/<user>/.ssh/authorized_keys
88
+ "ssh-keys": `clawops:${sshPublicKey}`,
63
89
  "startup-script": makeStartupScript(openclawVersion)
64
90
  },
65
91
  serviceAccount: {
@@ -154,6 +180,11 @@ var gcpAdapter = {
154
180
  };
155
181
  },
156
182
  normalizeInstanceType(alias) {
183
+ if (alias === "gpu") {
184
+ throw new Error(
185
+ "GPU instances are not yet supported on GCP. Use --provider aws (g4dn.xlarge) or --provider azure (Standard_NC6s_v3) for GPU workloads."
186
+ );
187
+ }
157
188
  const mapped = INSTANCE_TYPE_MAP[alias];
158
189
  if (!mapped) throw new Error(`Unknown instance alias: ${alias}`);
159
190
  return mapped;
@@ -166,9 +197,10 @@ var gcpAdapter = {
166
197
  },
167
198
  async validateConfig() {
168
199
  const errors = [];
169
- const hasKeyFile = Boolean(process.env["GOOGLE_APPLICATION_CREDENTIALS"]);
170
- const hasUserCreds = Boolean(process.env["CLOUDSDK_AUTH_ACCESS_TOKEN"]);
171
- if (!hasKeyFile && !hasUserCreds) {
200
+ const hasKeyFile = Boolean(process2.env["GOOGLE_APPLICATION_CREDENTIALS"]);
201
+ const hasToken = Boolean(process2.env["GOOGLE_OAUTH_ACCESS_TOKEN"]);
202
+ const hasAdcFile = await checkAdcFile();
203
+ if (!hasKeyFile && !hasToken && !hasAdcFile) {
172
204
  const onGcp = await checkInstanceMetadata();
173
205
  if (!onGcp) {
174
206
  errors.push(
@@ -179,6 +211,17 @@ var gcpAdapter = {
179
211
  return { ok: errors.length === 0, errors };
180
212
  }
181
213
  };
214
+ async function checkAdcFile() {
215
+ try {
216
+ const { accessSync } = await import("fs");
217
+ const { join } = await import("path");
218
+ const home = process2.env["HOME"] ?? process2.env["USERPROFILE"] ?? "";
219
+ accessSync(join(home, ".config", "gcloud", "application_default_credentials.json"));
220
+ return true;
221
+ } catch {
222
+ return false;
223
+ }
224
+ }
182
225
  async function checkInstanceMetadata() {
183
226
  try {
184
227
  const res = await fetch(
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  generatePlan,
4
4
  planId
5
- } from "./chunk-ZDPBBYYV.js";
5
+ } from "./chunk-IVX62LFO.js";
6
6
  import "./chunk-YTH4L2GN.js";
7
- import "./chunk-JDN6PLH2.js";
7
+ import "./chunk-T5EX55GP.js";
8
8
  import "./chunk-A2I76FTA.js";
9
9
  import "./chunk-CX5SL5HP.js";
10
10
  import "./chunk-KGXPLI7W.js";
File without changes
File without changes
File without changes
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ atomicWriteConfig,
4
+ deepMerge,
5
+ readRemoteConfig,
6
+ restartGateway
7
+ } from "./chunk-ZFNPM2WG.js";
8
+
9
+ // src/cli/mcp-wire.ts
10
+ var GATEWAY_MCP_MIN_VERSION = "2026.4";
11
+ var GATEWAY_MCP_ENTRY = {
12
+ command: "clawops",
13
+ args: ["mcp", "serve"],
14
+ transport: "stdio"
15
+ };
16
+ function versionAtLeast(version, min) {
17
+ const [vy = 0, vm = 0] = version.split(".").map(Number);
18
+ const [my = 0, mm = 0] = min.split(".").map(Number);
19
+ if (vy !== my) return vy > my;
20
+ return vm >= mm;
21
+ }
22
+ async function wireGatewayMcp(session, signal, opts = {}) {
23
+ const cfg = await readRemoteConfig(session, signal);
24
+ const version = cfg["meta"]?.["lastTouchedVersion"];
25
+ if (version && !versionAtLeast(version, GATEWAY_MCP_MIN_VERSION) && !opts.force) {
26
+ return { status: "version-blocked", version };
27
+ }
28
+ const mcpClients = cfg["gateway"]?.["mcpClients"];
29
+ const rewired = !!mcpClients?.["clawops"];
30
+ const updated = deepMerge(cfg, {
31
+ gateway: {
32
+ mcpClients: {
33
+ clawops: GATEWAY_MCP_ENTRY
34
+ }
35
+ }
36
+ });
37
+ await atomicWriteConfig(session, updated, signal);
38
+ await restartGateway(session, signal);
39
+ return { status: "wired", rewired };
40
+ }
41
+ export {
42
+ GATEWAY_MCP_ENTRY,
43
+ GATEWAY_MCP_MIN_VERSION,
44
+ wireGatewayMcp
45
+ };
File without changes
File without changes
@@ -2,7 +2,7 @@
2
2
 
3
3
  // package.json
4
4
  var name = "@clawops/cli";
5
- var version = "1.3.0";
5
+ var version = "1.5.0";
6
6
  var description = "Deploy and manage self-hosted OpenClaw instances across clouds";
7
7
  var type = "module";
8
8
  var bin = {
@@ -48,6 +48,7 @@ var dependencies = {
48
48
  "@pulumi/docker": "^4.0.0",
49
49
  "@pulumi/gcp": "^7.0.0",
50
50
  "@pulumi/pulumi": "^3.0.0",
51
+ "@pulumi/random": "^4.20.0",
51
52
  ajv: "^8.0.0",
52
53
  "ajv-formats": "^3.0.0",
53
54
  chalk: "^5.0.0",
File without changes
File without changes
@@ -8,7 +8,7 @@ import {
8
8
  deepMerge,
9
9
  readRemoteConfig,
10
10
  restartGateway
11
- } from "./chunk-UDNZUSKA.js";
11
+ } from "./chunk-ZFNPM2WG.js";
12
12
  export {
13
13
  OPENCLAW_CONFIG,
14
14
  OPENCLAW_CONFIG_LINUX,
File without changes
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-3QJBNAHW.js";
5
5
  import {
6
6
  generatePlan
7
- } from "./chunk-ZDPBBYYV.js";
7
+ } from "./chunk-IVX62LFO.js";
8
8
  import {
9
9
  applyPlan
10
- } from "./chunk-JCUZU5BH.js";
10
+ } from "./chunk-ZONXY3C6.js";
11
11
  import {
12
12
  validatePlan
13
13
  } from "./chunk-YTH4L2GN.js";
@@ -15,22 +15,24 @@ import "./chunk-6ZFIFDBJ.js";
15
15
  import "./chunk-BOPSG2LI.js";
16
16
  import {
17
17
  errText,
18
+ formatUptime,
19
+ gatherSnapshot,
18
20
  handleConfigGet,
19
21
  handleConfigSet,
20
22
  handleConfigUnset,
21
23
  handleConfigValidate,
22
24
  okText,
23
25
  resolveConn
24
- } from "./chunk-LVIIYY27.js";
26
+ } from "./chunk-R5S6IXBE.js";
25
27
  import {
26
28
  buildContext
27
- } from "./chunk-JDN6PLH2.js";
29
+ } from "./chunk-T5EX55GP.js";
28
30
  import {
29
31
  acquireSession,
30
32
  drainPool
31
33
  } from "./chunk-ZVOEQCNW.js";
32
34
  import "./chunk-4U3LTLWZ.js";
33
- import "./chunk-UDNZUSKA.js";
35
+ import "./chunk-ZFNPM2WG.js";
34
36
  import "./chunk-A2I76FTA.js";
35
37
  import {
36
38
  getConfig,
@@ -140,7 +142,7 @@ var clawops_statusAnnotations = {
140
142
  };
141
143
  var clawops_logs_tailSchema = z.object({
142
144
  stackName: z.string().optional(),
143
- tailLines: z.number().int().default(100),
145
+ tailLines: z.number().int().optional().default(100),
144
146
  sinceMin: z.number().int().optional()
145
147
  });
146
148
  var clawops_logs_tailAnnotations = {
@@ -151,6 +153,18 @@ var clawops_logs_tailAnnotations = {
151
153
  openWorldHint: true,
152
154
  toolsets: ["cli", "read"]
153
155
  };
156
+ var clawops_monitorSchema = z.object({
157
+ stackName: z.string().optional(),
158
+ tailLines: z.number().int().optional().default(5)
159
+ });
160
+ var clawops_monitorAnnotations = {
161
+ title: "Monitor Stack Health",
162
+ readOnlyHint: true,
163
+ destructiveHint: false,
164
+ idempotentHint: true,
165
+ openWorldHint: true,
166
+ toolsets: ["cli", "read"]
167
+ };
154
168
  var clawops_stacks_listSchema = z.object({});
155
169
  var clawops_stacks_listAnnotations = {
156
170
  title: "List Stacks",
@@ -187,9 +201,9 @@ var clawops_upSchema = z.object({
187
201
  stackName: z.string().optional(),
188
202
  provider: z.enum(["aws", "gcp", "azure", "local"]).optional(),
189
203
  region: z.string().optional(),
190
- instanceType: z.enum(["micro", "small", "medium", "large", "gpu"]).default("small"),
204
+ instanceType: z.enum(["micro", "small", "medium", "large", "gpu"]).optional().default("small"),
191
205
  openclawVersion: z.string().optional(),
192
- dryRun: z.boolean().default(false)
206
+ dryRun: z.boolean().optional().default(false)
193
207
  });
194
208
  var clawops_upAnnotations = {
195
209
  title: "Provision and Deploy Stack",
@@ -201,7 +215,7 @@ var clawops_upAnnotations = {
201
215
  };
202
216
  var clawops_destroySchema = z.object({
203
217
  stackName: z.string(),
204
- yes: z.boolean().default(false)
218
+ yes: z.boolean().optional().default(false)
205
219
  });
206
220
  var clawops_destroyAnnotations = {
207
221
  title: "Destroy Stack (DESTRUCTIVE)",
@@ -213,7 +227,7 @@ var clawops_destroyAnnotations = {
213
227
  };
214
228
  var clawops_applySchema = z.object({
215
229
  planPath: z.string(),
216
- yes: z.boolean().default(false)
230
+ yes: z.boolean().optional().default(false)
217
231
  });
218
232
  var clawops_applyAnnotations = {
219
233
  title: "Apply Maker Plan",
@@ -242,7 +256,7 @@ var clawops_config_setSchema = z.object({
242
256
  stackName: z.string().optional(),
243
257
  key: z.string(),
244
258
  value: z.string(),
245
- restart: z.boolean().default(false)
259
+ restart: z.boolean().optional().default(false)
246
260
  });
247
261
  var clawops_config_setAnnotations = {
248
262
  title: "Set OpenClaw Config Value",
@@ -255,7 +269,7 @@ var clawops_config_setAnnotations = {
255
269
  var clawops_config_unsetSchema = z.object({
256
270
  stackName: z.string().optional(),
257
271
  key: z.string(),
258
- restart: z.boolean().default(false)
272
+ restart: z.boolean().optional().default(false)
259
273
  });
260
274
  var clawops_config_unsetAnnotations = {
261
275
  title: "Unset OpenClaw Config Key",
@@ -302,8 +316,8 @@ var clawops_gateway_restartAnnotations = {
302
316
  var clawops_workflow_deploy_appSchema = z.object({
303
317
  provider: z.enum(["aws", "gcp", "azure", "local"]),
304
318
  region: z.string().optional(),
305
- stackName: z.string().default("default"),
306
- instanceType: z.enum(["micro", "small", "medium", "large", "gpu"]).default("small")
319
+ stackName: z.string().optional().default("default"),
320
+ instanceType: z.enum(["micro", "small", "medium", "large", "gpu"]).optional().default("small")
307
321
  });
308
322
  var clawops_workflow_deploy_appAnnotations = {
309
323
  title: "Deploy OpenClaw (End-to-End Workflow)",
@@ -339,6 +353,7 @@ var TOOLSETS = {
339
353
  cli: [
340
354
  "clawops_status",
341
355
  "clawops_logs_tail",
356
+ "clawops_monitor",
342
357
  "clawops_config_get",
343
358
  "clawops_agents_list",
344
359
  "clawops_up",
@@ -359,6 +374,7 @@ var TOOLSETS = {
359
374
  read: [
360
375
  "clawops_status",
361
376
  "clawops_logs_tail",
377
+ "clawops_monitor",
362
378
  "clawops_stacks_list",
363
379
  "clawops_config_get",
364
380
  "clawops_agents_list",
@@ -835,6 +851,62 @@ async function handleTaskStatus(input, _server) {
835
851
  return { content: [{ type: "text", text: JSON.stringify(record, null, 2) }] };
836
852
  }
837
853
 
854
+ // src/mcp/tools/cli/monitor.ts
855
+ async function handleMonitor(input, _server) {
856
+ const { acquireSession: acquireSession2, drainPool: drainPool2 } = await import("./pool-FBFHATDG.js");
857
+ const ctx = buildContext({ stack: input.stackName });
858
+ const tailLines = input.tailLines ?? 5;
859
+ let conn;
860
+ if (ctx.adapter.name === "local") {
861
+ if (!ctx.localState) {
862
+ return text2(JSON.stringify({ error: "Stack is not bootstrapped. Run `clawops up` first." }));
863
+ }
864
+ const ls = ctx.localState;
865
+ conn = { host: ls.sshHost, port: ls.sshPort, user: ls.sshUser, privateKeyPath: ls.privateKeyPath, knownHostsPath: ls.knownHostsPath };
866
+ } else {
867
+ const stack = await ctx.getStack();
868
+ const outputMap = await stack.outputs();
869
+ const outputs = Object.fromEntries(
870
+ Object.entries(outputMap).map(([k, v]) => [k, v.value])
871
+ );
872
+ if (!outputs["publicIp"]) {
873
+ return text2(JSON.stringify({ error: "Stack has no outputs. Run `clawops up` first." }));
874
+ }
875
+ const base = extractBaseOutputs(outputs);
876
+ conn = ctx.adapter.getConnectionInfo({
877
+ ...base,
878
+ privateKeyPath: ctx.config.ssh.keyPath,
879
+ knownHostsPath: ctx.config.ssh.knownHostsPath
880
+ });
881
+ }
882
+ const ac = new AbortController();
883
+ const { session, release } = await acquireSession2({ ...conn, signal: ac.signal });
884
+ try {
885
+ const snap = await gatherSnapshot(session, ac.signal, tailLines);
886
+ return text2(JSON.stringify({
887
+ gateway: snap.gateway,
888
+ container: {
889
+ status: snap.container.status,
890
+ image: snap.container.image,
891
+ restartCount: snap.container.restartCount,
892
+ memUsage: snap.container.memUsage,
893
+ cpuPct: snap.container.cpuPct,
894
+ uptime: formatUptime(snap.container.startedAt)
895
+ },
896
+ disk: snap.disk,
897
+ logLines: snap.logLines,
898
+ capturedAt: snap.capturedAt.toISOString()
899
+ }, null, 2));
900
+ } finally {
901
+ release();
902
+ drainPool2();
903
+ ac.abort();
904
+ }
905
+ }
906
+ function text2(t) {
907
+ return { content: [{ type: "text", text: t }] };
908
+ }
909
+
838
910
  // src/mcp/tools/workflow/deploy_app.ts
839
911
  async function handleWorkflowDeployApp(input, server) {
840
912
  const parts = [`## Deployment Workflow \u2014 ${input.provider} / ${input.stackName}
@@ -947,6 +1019,7 @@ function makeEntry(schema, annotations, handler) {
947
1019
  var TOOL_REGISTRY = {
948
1020
  clawops_status: makeEntry(clawops_statusSchema, clawops_statusAnnotations, handleStatus),
949
1021
  clawops_logs_tail: makeEntry(clawops_logs_tailSchema, clawops_logs_tailAnnotations, handleLogsTail),
1022
+ clawops_monitor: makeEntry(clawops_monitorSchema, clawops_monitorAnnotations, handleMonitor),
950
1023
  clawops_stacks_list: makeEntry(clawops_stacks_listSchema, clawops_stacks_listAnnotations, handleStacksList),
951
1024
  clawops_config_get: makeEntry(clawops_config_getSchema, clawops_config_getAnnotations, handleConfigGet),
952
1025
  clawops_agents_list: makeEntry(clawops_agents_listSchema, clawops_agents_listAnnotations, handleAgentsList),
@@ -1059,19 +1132,19 @@ function registerResources(server) {
1059
1132
  async (uri, { name }) => {
1060
1133
  const stackName = Array.isArray(name) ? name[0] : name;
1061
1134
  const filePath = path3.join(getConfigDir(), "state", `${stackName}.last-run.json`);
1062
- let text2;
1135
+ let text3;
1063
1136
  try {
1064
1137
  const raw = readFileSync2(filePath, "utf-8");
1065
1138
  const parsed = JSON.parse(raw);
1066
- text2 = parsed.output ?? "(no output recorded)";
1139
+ text3 = parsed.output ?? "(no output recorded)";
1067
1140
  } catch {
1068
- text2 = `No last-run output found for stack "${stackName}".`;
1141
+ text3 = `No last-run output found for stack "${stackName}".`;
1069
1142
  }
1070
1143
  return {
1071
1144
  contents: [{
1072
1145
  uri: uri.href,
1073
1146
  mimeType: "text/plain",
1074
- text: text2
1147
+ text: text3
1075
1148
  }]
1076
1149
  };
1077
1150
  }
@@ -1232,7 +1305,7 @@ If none of the above resolves the issue:
1232
1305
 
1233
1306
  // src/mcp/server.ts
1234
1307
  async function serveMcp(opts) {
1235
- const { version } = await import("./package-AFUTH62F.js");
1308
+ const { version } = await import("./package-QLDA65A3.js");
1236
1309
  const server = new McpServer({ name: "clawops", version });
1237
1310
  registerTools(server, opts);
1238
1311
  registerResources(server);
File without changes
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawops/cli",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "Deploy and manage self-hosted OpenClaw instances across clouds",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,6 +24,19 @@
24
24
  "engines": {
25
25
  "node": ">=22"
26
26
  },
27
+ "scripts": {
28
+ "dev": "tsx src/cli/index.ts",
29
+ "build": "tsup",
30
+ "test": "vitest run",
31
+ "test:pulumi": "vitest run tests/providers/aws/program.test.ts tests/providers/azure/program.test.ts",
32
+ "test:changed": "vitest --changed",
33
+ "test:integration": "vitest run --config vitest.integration.config.ts",
34
+ "typecheck": "NODE_OPTIONS=--max-old-space-size=4096 tsc --noEmit",
35
+ "lint": "eslint --max-warnings=0 src tests scripts",
36
+ "gen:schemas": "tsx scripts/gen-schemas.ts",
37
+ "changeset": "changeset",
38
+ "release": "pnpm build && changeset publish"
39
+ },
27
40
  "dependencies": {
28
41
  "@modelcontextprotocol/sdk": "^1.0.0",
29
42
  "@pulumi/aws": "^6.0.0",
@@ -32,6 +45,7 @@
32
45
  "@pulumi/docker": "^4.0.0",
33
46
  "@pulumi/gcp": "^7.0.0",
34
47
  "@pulumi/pulumi": "^3.0.0",
48
+ "@pulumi/random": "^4.20.0",
35
49
  "ajv": "^8.0.0",
36
50
  "ajv-formats": "^3.0.0",
37
51
  "chalk": "^5.0.0",
@@ -59,17 +73,16 @@
59
73
  "typescript-eslint": "^8.0.0",
60
74
  "vitest": "^2.0.0"
61
75
  },
62
- "scripts": {
63
- "dev": "tsx src/cli/index.ts",
64
- "build": "tsup",
65
- "test": "vitest run",
66
- "test:pulumi": "vitest run tests/providers/aws/program.test.ts tests/providers/azure/program.test.ts",
67
- "test:changed": "vitest --changed",
68
- "test:integration": "vitest run --config vitest.integration.config.ts",
69
- "typecheck": "NODE_OPTIONS=--max-old-space-size=4096 tsc --noEmit",
70
- "lint": "eslint --max-warnings=0 src tests scripts",
71
- "gen:schemas": "tsx scripts/gen-schemas.ts",
72
- "changeset": "changeset",
73
- "release": "pnpm build && changeset publish"
76
+ "pnpm": {
77
+ "overrides": {
78
+ "@pulumi/pulumi": "^3.0.0"
79
+ },
80
+ "onlyBuiltDependencies": [
81
+ "@pulumi/command",
82
+ "cpu-features",
83
+ "esbuild",
84
+ "protobufjs",
85
+ "ssh2"
86
+ ]
74
87
  }
75
- }
88
+ }