@clawops/cli 1.5.0 → 1.7.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 +2 -0
- package/dist/{apply-5RREMN3L.js → apply-BTZFFGAD.js} +2 -2
- package/dist/{aws-FRE2JVAZ.js → aws-D7Y6LCGK.js} +52 -90
- package/dist/{azure-PVC3AQVC.js → azure-JQAMNVHN.js} +15 -56
- package/dist/{bootstrap-G4UZ2FKH.js → bootstrap-RY4VOSDJ.js} +2 -2
- package/dist/{chunk-T5EX55GP.js → chunk-3MFZ7E74.js} +3 -3
- package/dist/{chunk-IVX62LFO.js → chunk-7KLLWDBA.js} +2 -2
- package/dist/{chunk-R5S6IXBE.js → chunk-CG3Y7Y2R.js} +41 -71
- package/dist/{chunk-4U3LTLWZ.js → chunk-GJEF6UQA.js} +1 -0
- package/dist/{chunk-ZONXY3C6.js → chunk-ISFHLA4G.js} +4 -4
- package/dist/{chunk-ZVOEQCNW.js → chunk-LCKD7L7X.js} +1 -1
- package/dist/chunk-Q7NQY5HV.js +37 -0
- package/dist/chunk-XKT42M34.js +72 -0
- package/dist/cli.js +410 -58
- package/dist/{context-PSGEX2D7.js → context-ALSJMTHE.js} +1 -1
- package/dist/firewall-XQGO7HWK.js +51 -0
- package/dist/{gcp-BXDTC6EK.js → gcp-6FT2A45S.js} +14 -63
- package/dist/{generate-2QGKYR42.js → generate-ZTD4BVVI.js} +2 -2
- package/dist/harden-BDVYW567.js +748 -0
- package/dist/human-Z44CW7TR.js +21 -0
- package/dist/{package-QLDA65A3.js → package-7WOZMHSO.js} +5 -1
- package/dist/{pool-FBFHATDG.js → pool-JZGKPP6K.js} +2 -2
- package/dist/{server-LOL2NUJ2.js → server-EXBOOIEP.js} +11 -10
- package/dist/{ssh-IQXNME3D.js → ssh-E2AMBPZY.js} +1 -1
- package/package.json +5 -1
- package/dist/firewall-YYDOWDDP.js +0 -36
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/providers/firewall.ts
|
|
4
|
+
function resolveIngressCidrs(accessMode, allowedCidrs, portOverride, egressResult) {
|
|
5
|
+
if (portOverride.trim()) {
|
|
6
|
+
return portOverride.split(",").map((s) => s.trim()).filter(Boolean);
|
|
7
|
+
}
|
|
8
|
+
switch (accessMode) {
|
|
9
|
+
case "restricted": {
|
|
10
|
+
if (!allowedCidrs.trim()) return [];
|
|
11
|
+
return allowedCidrs.split(",").map((s) => s.trim()).filter(Boolean);
|
|
12
|
+
}
|
|
13
|
+
case "auto": {
|
|
14
|
+
if (!egressResult.ok) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`accessMode=auto: egress IP detection failed \u2014 ${egressResult.error}. Set allowedCidrs explicitly or use accessMode=restricted.`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
const ip = egressResult.ip.trim();
|
|
20
|
+
if (!ip) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`accessMode=auto: egress IP detection returned an empty address. Set allowedCidrs explicitly or use accessMode=restricted.`
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return [ip.includes("/") ? ip : `${ip}/32`];
|
|
26
|
+
}
|
|
27
|
+
case "open":
|
|
28
|
+
return ["0.0.0.0/0"];
|
|
29
|
+
default:
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function detectEgressIp(checkUrl) {
|
|
34
|
+
try {
|
|
35
|
+
const res = await fetch(checkUrl, { signal: AbortSignal.timeout(3e3) });
|
|
36
|
+
if (!res.ok) {
|
|
37
|
+
return { ok: false, error: `HTTP ${res.status} from ${checkUrl}` };
|
|
38
|
+
}
|
|
39
|
+
const ip = (await res.text()).trim();
|
|
40
|
+
if (!ip) {
|
|
41
|
+
return { ok: false, error: `empty response from ${checkUrl}` };
|
|
42
|
+
}
|
|
43
|
+
return { ok: true, ip };
|
|
44
|
+
} catch (err) {
|
|
45
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
detectEgressIp,
|
|
50
|
+
resolveIngressCidrs
|
|
51
|
+
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
makeStartupScript
|
|
4
|
+
} from "./chunk-XKT42M34.js";
|
|
2
5
|
|
|
3
6
|
// src/providers/gcp/index.ts
|
|
4
7
|
import process2 from "process";
|
|
@@ -10,7 +13,7 @@ var gcpProgram = async () => {
|
|
|
10
13
|
const [pulumi, gcp, { resolveIngressCidrs, detectEgressIp }] = await Promise.all([
|
|
11
14
|
import("@pulumi/pulumi"),
|
|
12
15
|
import("@pulumi/gcp"),
|
|
13
|
-
import("./firewall-
|
|
16
|
+
import("./firewall-XQGO7HWK.js")
|
|
14
17
|
]);
|
|
15
18
|
const cfg = new pulumi.Config();
|
|
16
19
|
const instanceType = cfg.get("instanceType") ?? "e2-standard-2";
|
|
@@ -27,14 +30,14 @@ var gcpProgram = async () => {
|
|
|
27
30
|
'Stack config "sshPublicKey" is required for the GCP adapter. Set it with: pulumi config set --stack <name> sshPublicKey "ssh-ed25519 ..."'
|
|
28
31
|
);
|
|
29
32
|
}
|
|
30
|
-
const
|
|
33
|
+
const egressResult = accessMode === "auto" ? await detectEgressIp("https://ifconfig.me") : { ok: true, ip: "" };
|
|
31
34
|
if (accessMode === "open") {
|
|
32
35
|
process.stderr.write(
|
|
33
36
|
"[clawops] WARNING: accessMode=open allows 0.0.0.0/0 on SSH and gateway ports. Only use this for development/sandbox stacks.\n"
|
|
34
37
|
);
|
|
35
38
|
}
|
|
36
|
-
const sshIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, sshCidrs,
|
|
37
|
-
const gatewayIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, gatewayCidrs,
|
|
39
|
+
const sshIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, sshCidrs, egressResult);
|
|
40
|
+
const gatewayIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, gatewayCidrs, egressResult);
|
|
38
41
|
const network = new gcp.compute.Network("clawops-network", {
|
|
39
42
|
autoCreateSubnetworks: false,
|
|
40
43
|
description: "clawops managed network"
|
|
@@ -42,7 +45,7 @@ var gcpProgram = async () => {
|
|
|
42
45
|
const subnet = new gcp.compute.Subnetwork("clawops-subnet", {
|
|
43
46
|
ipCidrRange: "10.0.0.0/24",
|
|
44
47
|
region,
|
|
45
|
-
network: network.
|
|
48
|
+
network: network.selfLink
|
|
46
49
|
});
|
|
47
50
|
if (sshIngressCidrs.length > 0) {
|
|
48
51
|
new gcp.compute.Firewall("clawops-firewall-ssh", {
|
|
@@ -73,8 +76,8 @@ var gcpProgram = async () => {
|
|
|
73
76
|
},
|
|
74
77
|
networkInterfaces: [
|
|
75
78
|
{
|
|
76
|
-
network: network.
|
|
77
|
-
subnetwork: subnet.
|
|
79
|
+
network: network.selfLink,
|
|
80
|
+
subnetwork: subnet.selfLink,
|
|
78
81
|
accessConfigs: [
|
|
79
82
|
{
|
|
80
83
|
natIp: address.address,
|
|
@@ -86,7 +89,7 @@ var gcpProgram = async () => {
|
|
|
86
89
|
metadata: {
|
|
87
90
|
// GCP guest agent reads 'ssh-keys' and populates /home/<user>/.ssh/authorized_keys
|
|
88
91
|
"ssh-keys": `clawops:${sshPublicKey}`,
|
|
89
|
-
"startup-script": makeStartupScript(openclawVersion)
|
|
92
|
+
"startup-script": makeStartupScript({ openclawVersion, os: "debian" })
|
|
90
93
|
},
|
|
91
94
|
serviceAccount: {
|
|
92
95
|
scopes: ["https://www.googleapis.com/auth/cloud-platform"]
|
|
@@ -103,58 +106,6 @@ var gcpProgram = async () => {
|
|
|
103
106
|
provisionedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
104
107
|
};
|
|
105
108
|
};
|
|
106
|
-
function makeStartupScript(openclawVersion) {
|
|
107
|
-
return `#!/bin/bash
|
|
108
|
-
set -euo pipefail
|
|
109
|
-
|
|
110
|
-
# Create clawops user with SSH access
|
|
111
|
-
id -u clawops &>/dev/null || useradd -m -s /bin/bash clawops
|
|
112
|
-
mkdir -p /home/clawops/.ssh
|
|
113
|
-
chmod 700 /home/clawops/.ssh
|
|
114
|
-
|
|
115
|
-
# Install Docker if not present
|
|
116
|
-
if ! command -v docker &>/dev/null; then
|
|
117
|
-
apt-get update -q
|
|
118
|
-
apt-get install -y -q ca-certificates curl gnupg lsb-release
|
|
119
|
-
install -m 0755 -d /etc/apt/keyrings
|
|
120
|
-
curl -fsSL https://download.docker.com/linux/debian/gpg \\
|
|
121
|
-
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
|
122
|
-
chmod a+r /etc/apt/keyrings/docker.gpg
|
|
123
|
-
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \\
|
|
124
|
-
https://download.docker.com/linux/debian $(lsb_release -cs) stable" \\
|
|
125
|
-
> /etc/apt/sources.list.d/docker.list
|
|
126
|
-
apt-get update -q
|
|
127
|
-
apt-get install -y -q docker-ce docker-ce-cli containerd.io
|
|
128
|
-
systemctl enable --now docker
|
|
129
|
-
fi
|
|
130
|
-
|
|
131
|
-
usermod -aG docker clawops
|
|
132
|
-
|
|
133
|
-
# Pull OpenClaw image
|
|
134
|
-
OPENCLAW_VERSION="${openclawVersion}"
|
|
135
|
-
docker pull ghcr.io/openclaw/openclaw:\${OPENCLAW_VERSION}
|
|
136
|
-
|
|
137
|
-
# Create default openclaw.json if not present
|
|
138
|
-
OPENCLAW_CONFIG=/home/clawops/openclaw.json
|
|
139
|
-
if [ ! -f "\${OPENCLAW_CONFIG}" ]; then
|
|
140
|
-
cat > "\${OPENCLAW_CONFIG}" <<'OPENCLAWJSON'
|
|
141
|
-
{"meta":{"lastTouchedVersion":"2026.4"},"gateway":{"port":18789,"auth":{"mode":"token"}},"models":{},"channels":{}}
|
|
142
|
-
OPENCLAWJSON
|
|
143
|
-
chown clawops:clawops "\${OPENCLAW_CONFIG}"
|
|
144
|
-
fi
|
|
145
|
-
|
|
146
|
-
# Start OpenClaw container
|
|
147
|
-
docker stop openclaw 2>/dev/null || true
|
|
148
|
-
docker rm openclaw 2>/dev/null || true
|
|
149
|
-
docker run -d \\
|
|
150
|
-
--name openclaw \\
|
|
151
|
-
--restart unless-stopped \\
|
|
152
|
-
-p ${GATEWAY_PORT}:${GATEWAY_PORT} \\
|
|
153
|
-
-v "\${OPENCLAW_CONFIG}":/app/config.json:ro \\
|
|
154
|
-
ghcr.io/openclaw/openclaw:\${OPENCLAW_VERSION} \\
|
|
155
|
-
node openclaw.mjs gateway run --allow-unconfigured
|
|
156
|
-
`;
|
|
157
|
-
}
|
|
158
109
|
|
|
159
110
|
// src/providers/gcp/index.ts
|
|
160
111
|
var INSTANCE_TYPE_MAP = {
|
|
@@ -172,9 +123,9 @@ var gcpAdapter = {
|
|
|
172
123
|
},
|
|
173
124
|
getConnectionInfo(outputs) {
|
|
174
125
|
return {
|
|
175
|
-
host: String(outputs["sshHost"]),
|
|
176
|
-
port: Number(outputs["sshPort"]),
|
|
177
|
-
user: String(outputs["sshUser"]),
|
|
126
|
+
host: String(outputs["sshHost"] ?? ""),
|
|
127
|
+
port: Number(outputs["sshPort"] ?? 22),
|
|
128
|
+
user: String(outputs["sshUser"] ?? "clawops"),
|
|
178
129
|
privateKeyPath: String(outputs["privateKeyPath"] ?? ""),
|
|
179
130
|
knownHostsPath: String(outputs["knownHostsPath"] ?? "")
|
|
180
131
|
};
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
generatePlan,
|
|
4
4
|
planId
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-7KLLWDBA.js";
|
|
6
6
|
import "./chunk-YTH4L2GN.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-3MFZ7E74.js";
|
|
8
8
|
import "./chunk-A2I76FTA.js";
|
|
9
9
|
import "./chunk-CX5SL5HP.js";
|
|
10
10
|
import "./chunk-KGXPLI7W.js";
|