@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.
- package/README.md +136 -0
- package/dist/{apply-DLNE2JYZ.js → apply-5RREMN3L.js} +3 -3
- package/dist/automation-RULUSJBW.js +0 -0
- package/dist/{aws-KQBWY43W.js → aws-FRE2JVAZ.js} +9 -4
- package/dist/{azure-4EJFVJZL.js → azure-PVC3AQVC.js} +11 -4
- package/dist/bootstrap-G4UZ2FKH.js +0 -0
- package/dist/chunk-3QJBNAHW.js +0 -0
- package/dist/chunk-4U3LTLWZ.js +0 -0
- package/dist/chunk-6ZFIFDBJ.js +0 -0
- package/dist/chunk-A2I76FTA.js +0 -0
- package/dist/chunk-BOPSG2LI.js +0 -0
- package/dist/chunk-CX5SL5HP.js +0 -0
- package/dist/{chunk-ZDPBBYYV.js → chunk-IVX62LFO.js} +2 -2
- package/dist/chunk-KGXPLI7W.js +0 -0
- package/dist/chunk-OIGTOLB3.js +0 -0
- package/dist/chunk-R5S6IXBE.js +771 -0
- package/dist/{chunk-JDN6PLH2.js → chunk-T5EX55GP.js} +3 -3
- package/dist/chunk-YTH4L2GN.js +0 -0
- package/dist/{chunk-UDNZUSKA.js → chunk-ZFNPM2WG.js} +1 -1
- package/dist/{chunk-JCUZU5BH.js → chunk-ZONXY3C6.js} +2 -2
- package/dist/chunk-ZVOEQCNW.js +0 -0
- package/dist/cli.js +207 -53
- package/dist/{context-M2RMDHX6.js → context-PSGEX2D7.js} +1 -1
- package/dist/errors-OK47MQFD.js +0 -0
- package/dist/firewall-YYDOWDDP.js +0 -0
- package/dist/{gcp-SKURG3L6.js → gcp-BXDTC6EK.js} +60 -17
- package/dist/{generate-U7PJ5LRG.js → generate-2QGKYR42.js} +2 -2
- package/dist/js-yaml-PTEEG4FO.js +0 -0
- package/dist/local-DXBEVZ5C.js +0 -0
- package/dist/mcp-apps-KY44ED3Y.js +0 -0
- package/dist/mcp-wire-ZWIYMLEW.js +45 -0
- package/dist/outputs-DJHBY7EE.js +0 -0
- package/dist/overlay-store-ADZPD7EU.js +0 -0
- package/dist/{package-AFUTH62F.js → package-QLDA65A3.js} +2 -1
- package/dist/pool-FBFHATDG.js +0 -0
- package/dist/providers-2OABPW2E.js +0 -0
- package/dist/{remote-config-JQ77SRC2.js → remote-config-QF5TT7GU.js} +1 -1
- package/dist/secrets-SVZWNAPK.js +0 -0
- package/dist/{server-I62UES5V.js → server-LOL2NUJ2.js} +92 -19
- package/dist/ssh-IQXNME3D.js +0 -0
- package/dist/state-PRBIIN7I.js +0 -0
- package/dist/store-SDUR52Z5.js +0 -0
- package/dist/validate-T5M5EHSJ.js +0 -0
- package/package.json +27 -14
- 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
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
{
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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(
|
|
170
|
-
const
|
|
171
|
-
|
|
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-
|
|
5
|
+
} from "./chunk-IVX62LFO.js";
|
|
6
6
|
import "./chunk-YTH4L2GN.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-T5EX55GP.js";
|
|
8
8
|
import "./chunk-A2I76FTA.js";
|
|
9
9
|
import "./chunk-CX5SL5HP.js";
|
|
10
10
|
import "./chunk-KGXPLI7W.js";
|
package/dist/js-yaml-PTEEG4FO.js
CHANGED
|
File without changes
|
package/dist/local-DXBEVZ5C.js
CHANGED
|
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
|
+
};
|
package/dist/outputs-DJHBY7EE.js
CHANGED
|
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.
|
|
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",
|
package/dist/pool-FBFHATDG.js
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/secrets-SVZWNAPK.js
CHANGED
|
File without changes
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
} from "./chunk-3QJBNAHW.js";
|
|
5
5
|
import {
|
|
6
6
|
generatePlan
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IVX62LFO.js";
|
|
8
8
|
import {
|
|
9
9
|
applyPlan
|
|
10
|
-
} from "./chunk-
|
|
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-
|
|
26
|
+
} from "./chunk-R5S6IXBE.js";
|
|
25
27
|
import {
|
|
26
28
|
buildContext
|
|
27
|
-
} from "./chunk-
|
|
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-
|
|
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
|
|
1135
|
+
let text3;
|
|
1063
1136
|
try {
|
|
1064
1137
|
const raw = readFileSync2(filePath, "utf-8");
|
|
1065
1138
|
const parsed = JSON.parse(raw);
|
|
1066
|
-
|
|
1139
|
+
text3 = parsed.output ?? "(no output recorded)";
|
|
1067
1140
|
} catch {
|
|
1068
|
-
|
|
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:
|
|
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-
|
|
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);
|
package/dist/ssh-IQXNME3D.js
CHANGED
|
File without changes
|
package/dist/state-PRBIIN7I.js
CHANGED
|
File without changes
|
package/dist/store-SDUR52Z5.js
CHANGED
|
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
|
+
"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
|
-
"
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
+
}
|