@clawops/cli 1.7.9 → 2.0.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.
- package/README.md +504 -76
- package/dist/apply-KYFPWI5U.js +27 -0
- package/dist/automation-RMAIBNVC.js +44 -0
- package/dist/bedrock-XVASJX2K.js +61 -0
- package/dist/{bootstrap-HL4DNUNG.js → bootstrap-HNGKY6WW.js} +31 -19
- package/dist/bootstrap.sh.tmpl +51 -31
- package/dist/channels-KBUR42IU.js +53 -0
- package/dist/chunk-2I7KCMXZ.js +142 -0
- package/dist/{chunk-DQDAWNGB.js → chunk-2Z7J3ERQ.js} +1 -1
- package/dist/chunk-3OLUJPCB.js +36 -0
- package/dist/chunk-5XT5IAJK.js +69 -0
- package/dist/chunk-AEEMRFZV.js +24 -0
- package/dist/chunk-BSLIYB5Q.js +106 -0
- package/dist/{chunk-3XK66DKK.js → chunk-E4NJSJ54.js} +57 -93
- package/dist/chunk-FEK7VJAY.js +16 -0
- package/dist/{chunk-UKTP332Z.js → chunk-GAZPPSKU.js} +6 -7
- package/dist/chunk-GIEVAGEK.js +126 -0
- package/dist/chunk-HSPHXG6W.js +67 -0
- package/dist/chunk-IVWP4QUJ.js +901 -0
- package/dist/{chunk-PVUVI35Y.js → chunk-JW5A7E3X.js} +5 -1
- package/dist/{chunk-GZN7PKP4.js → chunk-KC3GC3PE.js} +328 -121
- package/dist/chunk-LBE6COC4.js +244 -0
- package/dist/chunk-LEVIW2PV.js +890 -0
- package/dist/chunk-LT4XMO5D.js +50 -0
- package/dist/chunk-MC5ATCXS.js +108 -0
- package/dist/chunk-N4WZLWJ4.js +16 -0
- package/dist/chunk-NUDIHZEH.js +55 -0
- package/dist/chunk-NUL5F6YV.js +56 -0
- package/dist/chunk-RHOWYIWT.js +52 -0
- package/dist/chunk-STLRHLLV.js +193 -0
- package/dist/chunk-V25QRZRB.js +45 -0
- package/dist/chunk-VOEJYRIK.js +33 -0
- package/dist/{providers-2OABPW2E.js → chunk-VUFMZEIM.js} +3 -2
- package/dist/chunk-W3OLNNJW.js +51 -0
- package/dist/cli-WLD3EBEM.js +11 -0
- package/dist/cli-auth-GD5SK7JU.js +13 -0
- package/dist/cli.js +1296 -695
- package/dist/config-validate-K2N6XLDX.js +76 -0
- package/dist/context-7EVC6W45.js +20 -0
- package/dist/docker-3PDO4TS7.js +12 -0
- package/dist/{firewall-XQGO7HWK.js → firewall-5VKZ4WBH.js} +32 -1
- package/dist/generate-I6YQ5V2T.js +29 -0
- package/dist/{harden-URPXLSVF.js → harden-72JMRT4E.js} +51 -11
- package/dist/health-5CCOXYGG.js +11 -0
- package/dist/index.d.ts +56 -0
- package/dist/known-hosts-file-I3Q3NBYQ.js +22 -0
- package/dist/logs-5A7YYA53.js +15 -0
- package/dist/{mcp-wire-7E5JQY47.js → mcp-wire-3SWBM7D6.js} +32 -16
- package/dist/models-AGTQWYDL.js +32 -0
- package/dist/network-args-PYJRJBYO.js +64 -0
- package/dist/{package-5AR4ZPK4.js → package-5BCMEBTE.js} +11 -4
- package/dist/passphrase-MJBE45N7.js +15 -0
- package/dist/plugins-DTST3OER.js +49 -0
- package/dist/{pool-QGFQRMGU.js → pool-PIIKJ4L2.js} +3 -2
- package/dist/preflight-EF52S3WW.js +162 -0
- package/dist/preflight-MWWM5JT3.js +181 -0
- package/dist/preflight-TFD4N5ZU.js +141 -0
- package/dist/privileged-JFA6LLTV.js +17 -0
- package/dist/providers-FW6H6OPF.js +11 -0
- package/dist/ready-KDNRBNSU.js +95 -0
- package/dist/{remote-config-QDLN4UMG.js → remote-config-3HZLUWEA.js} +4 -3
- package/dist/runtime-X3KW5TCP.js +44 -0
- package/dist/server-GBA7BJGK.js +46 -0
- package/dist/spec-path-KQOOIQCA.js +9 -0
- package/dist/ssh-VAI5DU5M.js +11 -0
- package/dist/ssh-key-DUO6OKOI.js +7 -0
- package/dist/stack-config-R4SPSUQZ.js +12 -0
- package/dist/upgrade-ULD4KFYC.js +88 -0
- package/dist/validate-YVI3BJ55.js +14 -0
- package/dist/{version-guard-VUCNZXQS.js → version-guard-XVYW5WFJ.js} +2 -2
- package/dist/{versions-2UVAT6PQ.js → versions-W5LRQCAJ.js} +2 -2
- package/dist/wait-WO72TRRQ.js +79 -0
- package/package.json +11 -4
- package/spec/deploy-plan.schema.json +114 -25
- package/spec/integrations.yaml +135 -28
- package/spec/mcp-tools.yaml +89 -37
- package/spec/models.yaml +23 -3
- package/spec/openclaw-2.0.config.schema.json +1 -0
- package/spec/openclaw-versions.yaml +116 -27
- package/spec/providers.schema.json +163 -28
- package/dist/apply-F3KY2HTB.js +0 -17
- package/dist/automation-RULUSJBW.js +0 -30
- package/dist/aws-L4RR2LSE.js +0 -254
- package/dist/azure-7OXQENQL.js +0 -262
- package/dist/chunk-35WVQY3X.js +0 -122
- package/dist/chunk-6X45DDGH.js +0 -42
- package/dist/chunk-A4QR4TXW.js +0 -120
- package/dist/chunk-C5X375RO.js +0 -85
- package/dist/chunk-FNS56UQY.js +0 -741
- package/dist/chunk-P5LKWRPL.js +0 -114
- package/dist/chunk-SEZMVVAS.js +0 -156
- package/dist/context-5LCUG2QR.js +0 -10
- package/dist/gcp-UG6AWPIZ.js +0 -193
- package/dist/generate-OAGYT3VH.js +0 -15
- package/dist/local-DXBEVZ5C.js +0 -47
- package/dist/server-FIZCOLHL.js +0 -32
- package/dist/ssh-CNJNLM3E.js +0 -8
- package/dist/validate-CFQ4FH2T.js +0 -10
|
@@ -6,10 +6,12 @@ import {
|
|
|
6
6
|
OPENCLAW_TMP,
|
|
7
7
|
atomicWriteConfig,
|
|
8
8
|
deepMerge,
|
|
9
|
-
normaliseGatewayPort,
|
|
10
9
|
readRemoteConfig,
|
|
11
10
|
restartGateway
|
|
12
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-2I7KCMXZ.js";
|
|
12
|
+
import "./chunk-NUDIHZEH.js";
|
|
13
|
+
import "./chunk-GIEVAGEK.js";
|
|
14
|
+
import "./chunk-VOEJYRIK.js";
|
|
13
15
|
import "./chunk-EI7CQQ7D.js";
|
|
14
16
|
export {
|
|
15
17
|
OPENCLAW_CONFIG,
|
|
@@ -18,7 +20,6 @@ export {
|
|
|
18
20
|
OPENCLAW_TMP,
|
|
19
21
|
atomicWriteConfig,
|
|
20
22
|
deepMerge,
|
|
21
|
-
normaliseGatewayPort,
|
|
22
23
|
readRemoteConfig,
|
|
23
24
|
restartGateway
|
|
24
25
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ADD_HOST_FLAG,
|
|
4
|
+
CONFIG_FILENAME,
|
|
5
|
+
CONFIG_MOUNT_PATH,
|
|
6
|
+
CONTAINER_UID,
|
|
7
|
+
ENV_FILE_PATH,
|
|
8
|
+
PUBLISH_INSPECT_CMD,
|
|
9
|
+
SECURITY_FLAGS,
|
|
10
|
+
STATE_DIR_CONTAINER,
|
|
11
|
+
STATE_DIR_HOST_LINUX,
|
|
12
|
+
STATE_DIR_HOST_MACOS,
|
|
13
|
+
SUPERVISOR_ENV,
|
|
14
|
+
configPathForOS,
|
|
15
|
+
gatewayRunArgs,
|
|
16
|
+
gatewayRunCommand,
|
|
17
|
+
publishForRestart,
|
|
18
|
+
publishedGatewayPort,
|
|
19
|
+
stateDirForOS
|
|
20
|
+
} from "./chunk-GIEVAGEK.js";
|
|
21
|
+
import {
|
|
22
|
+
GATEWAY_PORT
|
|
23
|
+
} from "./chunk-VOEJYRIK.js";
|
|
24
|
+
import "./chunk-EI7CQQ7D.js";
|
|
25
|
+
export {
|
|
26
|
+
ADD_HOST_FLAG,
|
|
27
|
+
CONFIG_FILENAME,
|
|
28
|
+
CONFIG_MOUNT_PATH,
|
|
29
|
+
CONTAINER_UID,
|
|
30
|
+
ENV_FILE_PATH,
|
|
31
|
+
GATEWAY_PORT,
|
|
32
|
+
PUBLISH_INSPECT_CMD,
|
|
33
|
+
SECURITY_FLAGS,
|
|
34
|
+
STATE_DIR_CONTAINER,
|
|
35
|
+
STATE_DIR_HOST_LINUX,
|
|
36
|
+
STATE_DIR_HOST_MACOS,
|
|
37
|
+
SUPERVISOR_ENV,
|
|
38
|
+
configPathForOS,
|
|
39
|
+
gatewayRunArgs,
|
|
40
|
+
gatewayRunCommand,
|
|
41
|
+
publishForRestart,
|
|
42
|
+
publishedGatewayPort,
|
|
43
|
+
stateDirForOS
|
|
44
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
MCP_HTTP_PORT,
|
|
4
|
+
authRequirement,
|
|
5
|
+
bearerFrom,
|
|
6
|
+
isLoopbackBind,
|
|
7
|
+
serveMcp
|
|
8
|
+
} from "./chunk-KC3GC3PE.js";
|
|
9
|
+
import "./chunk-LBE6COC4.js";
|
|
10
|
+
import "./chunk-BOPSG2LI.js";
|
|
11
|
+
import "./chunk-6ZFIFDBJ.js";
|
|
12
|
+
import "./chunk-3QJBNAHW.js";
|
|
13
|
+
import "./chunk-2I7KCMXZ.js";
|
|
14
|
+
import "./chunk-HSPHXG6W.js";
|
|
15
|
+
import "./chunk-AEEMRFZV.js";
|
|
16
|
+
import "./chunk-STLRHLLV.js";
|
|
17
|
+
import "./chunk-BSLIYB5Q.js";
|
|
18
|
+
import "./chunk-2Z7J3ERQ.js";
|
|
19
|
+
import "./chunk-E4NJSJ54.js";
|
|
20
|
+
import "./chunk-MC5ATCXS.js";
|
|
21
|
+
import "./chunk-5XT5IAJK.js";
|
|
22
|
+
import "./chunk-IVWP4QUJ.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-LEVIW2PV.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-A2I76FTA.js";
|
|
37
|
+
import "./chunk-CX5SL5HP.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
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
writeStackConfig
|
|
4
|
+
} from "./chunk-HSPHXG6W.js";
|
|
5
|
+
import "./chunk-AEEMRFZV.js";
|
|
6
|
+
import "./chunk-VOEJYRIK.js";
|
|
7
|
+
import "./chunk-EI7CQQ7D.js";
|
|
8
|
+
import "./chunk-CX5SL5HP.js";
|
|
9
|
+
import "./chunk-KGXPLI7W.js";
|
|
10
|
+
export {
|
|
11
|
+
writeStackConfig
|
|
12
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
assertValidPlan,
|
|
4
|
+
validatePlan,
|
|
5
|
+
validatePlanConfig,
|
|
6
|
+
validatePlanNetwork
|
|
7
|
+
} from "./chunk-BSLIYB5Q.js";
|
|
8
|
+
import "./chunk-JW5A7E3X.js";
|
|
9
|
+
export {
|
|
10
|
+
assertValidPlan,
|
|
11
|
+
validatePlan,
|
|
12
|
+
validatePlanConfig,
|
|
13
|
+
validatePlanNetwork
|
|
14
|
+
};
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
assertSupportedVersion,
|
|
4
4
|
loadVersionSpec
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-GAZPPSKU.js";
|
|
6
|
+
import "./chunk-JW5A7E3X.js";
|
|
6
7
|
import "./chunk-EI7CQQ7D.js";
|
|
7
|
-
import "./chunk-PVUVI35Y.js";
|
|
8
8
|
import {
|
|
9
9
|
UsageError
|
|
10
10
|
} from "./chunk-KGXPLI7W.js";
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
isMovingTag,
|
|
10
10
|
loadVersionSpec,
|
|
11
11
|
resolveVersion
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-GAZPPSKU.js";
|
|
13
|
+
import "./chunk-JW5A7E3X.js";
|
|
13
14
|
import "./chunk-EI7CQQ7D.js";
|
|
14
|
-
import "./chunk-PVUVI35Y.js";
|
|
15
15
|
export {
|
|
16
16
|
MOVING_TAGS,
|
|
17
17
|
_resetVersionSpecCache,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
connect
|
|
4
|
+
} from "./chunk-E4NJSJ54.js";
|
|
5
|
+
import "./chunk-MC5ATCXS.js";
|
|
6
|
+
import {
|
|
7
|
+
NetworkError
|
|
8
|
+
} from "./chunk-KGXPLI7W.js";
|
|
9
|
+
|
|
10
|
+
// src/transport/wait.ts
|
|
11
|
+
var TRANSIENT = [
|
|
12
|
+
"ECONNREFUSED",
|
|
13
|
+
"ETIMEDOUT",
|
|
14
|
+
"EHOSTUNREACH",
|
|
15
|
+
"ENETUNREACH",
|
|
16
|
+
"ECONNRESET",
|
|
17
|
+
"EPIPE",
|
|
18
|
+
"ENOTFOUND",
|
|
19
|
+
"Timed out while waiting for handshake",
|
|
20
|
+
"Connection closed by server",
|
|
21
|
+
"Connection lost before handshake",
|
|
22
|
+
"All configured authentication methods failed"
|
|
23
|
+
];
|
|
24
|
+
function isTransient(message) {
|
|
25
|
+
return TRANSIENT.some((t) => message.includes(t));
|
|
26
|
+
}
|
|
27
|
+
async function waitForSsh(conn, opts = {}) {
|
|
28
|
+
const timeoutMs = opts.timeoutMs ?? 3e5;
|
|
29
|
+
const intervalMs = opts.intervalMs ?? 5e3;
|
|
30
|
+
const connect2 = opts.connect ?? connect;
|
|
31
|
+
const sleep = opts.sleep ?? defaultSleep;
|
|
32
|
+
const deadline = Date.now() + timeoutMs;
|
|
33
|
+
let attempts = 0;
|
|
34
|
+
let lastError = "no attempt completed";
|
|
35
|
+
for (; ; ) {
|
|
36
|
+
if (opts.signal?.aborted) throw new NetworkError("Waiting for SSH was aborted");
|
|
37
|
+
attempts++;
|
|
38
|
+
try {
|
|
39
|
+
const session = await connect2({ ...conn, signal: opts.signal });
|
|
40
|
+
if (attempts > 1) opts.onProgress?.(`SSH is up after ${attempts} attempts.`);
|
|
41
|
+
return session;
|
|
42
|
+
} catch (err) {
|
|
43
|
+
lastError = err instanceof Error ? err.message : String(err);
|
|
44
|
+
if (!isTransient(lastError)) {
|
|
45
|
+
throw new NetworkError(
|
|
46
|
+
`SSH to ${conn.host}:${conn.port} failed for a reason waiting will not fix: ${lastError}`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
if (attempts === 1) {
|
|
50
|
+
opts.onProgress?.(
|
|
51
|
+
`Waiting for ${conn.host}:${conn.port} to accept SSH \u2014 a new instance takes a minute.`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (Date.now() + intervalMs >= deadline) {
|
|
56
|
+
throw new NetworkError(
|
|
57
|
+
`${conn.host}:${conn.port} did not accept SSH within ${Math.round(timeoutMs / 1e3)}s (${attempts} attempts, last error: ${lastError}). The instance may still be booting, or the firewall may not admit this machine \u2014 check \`clawops doctor --stack <name>\`.`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
await sleep(intervalMs, opts.signal);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function defaultSleep(ms, signal) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const timer = setTimeout(() => {
|
|
66
|
+
signal?.removeEventListener("abort", onAbort);
|
|
67
|
+
resolve();
|
|
68
|
+
}, ms);
|
|
69
|
+
const onAbort = () => {
|
|
70
|
+
clearTimeout(timer);
|
|
71
|
+
reject(new NetworkError("Waiting for SSH was aborted"));
|
|
72
|
+
};
|
|
73
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
isTransient,
|
|
78
|
+
waitForSsh
|
|
79
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clawops/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Deploy and manage self-hosted OpenClaw instances across clouds",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,19 +32,24 @@
|
|
|
32
32
|
"test": "vitest run",
|
|
33
33
|
"test:pulumi": "vitest run tests/providers/aws/program.test.ts tests/providers/azure/program.test.ts",
|
|
34
34
|
"test:changed": "vitest --changed",
|
|
35
|
-
"test:mutation": "node scripts/dev/mutation-check.mjs",
|
|
36
35
|
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
36
|
+
"test:cloud": "bash scripts/e2e/cloud.sh",
|
|
37
37
|
"typecheck": "NODE_OPTIONS=--max-old-space-size=4096 tsc --noEmit",
|
|
38
38
|
"lint": "eslint --max-warnings=0 src tests scripts",
|
|
39
39
|
"gen:schemas": "tsx scripts/gen-schemas.ts",
|
|
40
40
|
"changeset": "changeset",
|
|
41
|
-
"release": "pnpm build && changeset publish"
|
|
41
|
+
"release": "pnpm build && changeset publish",
|
|
42
|
+
"test:mutation": "node scripts/dev/mutation-check.mjs",
|
|
43
|
+
"graph": "node scripts/dev/graph.mjs"
|
|
42
44
|
},
|
|
43
45
|
"dependencies": {
|
|
46
|
+
"@aws-sdk/client-bedrock": "^3.1063.0",
|
|
44
47
|
"@aws-sdk/client-cloudwatch-logs": "^3.1063.0",
|
|
45
48
|
"@aws-sdk/client-ec2": "^3.1063.0",
|
|
46
49
|
"@aws-sdk/client-guardduty": "^3.1063.0",
|
|
47
50
|
"@aws-sdk/client-iam": "^3.1063.0",
|
|
51
|
+
"@aws-sdk/client-s3": "3.1132.0",
|
|
52
|
+
"@aws-sdk/client-sts": "3.1132.0",
|
|
48
53
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
49
54
|
"@pulumi/aws": "^6.0.0",
|
|
50
55
|
"@pulumi/azure-native": "^2.0.0",
|
|
@@ -58,6 +63,7 @@
|
|
|
58
63
|
"chalk": "^5.0.0",
|
|
59
64
|
"citty": "^0.1.0",
|
|
60
65
|
"conf": "^12.0.0",
|
|
66
|
+
"google-auth-library": "^11.0.2",
|
|
61
67
|
"inquirer": "^9.0.0",
|
|
62
68
|
"ora": "^8.0.0",
|
|
63
69
|
"ssh2": "^1.0.0",
|
|
@@ -82,7 +88,8 @@
|
|
|
82
88
|
},
|
|
83
89
|
"pnpm": {
|
|
84
90
|
"overrides": {
|
|
85
|
-
"@pulumi/pulumi": "^3.0.0"
|
|
91
|
+
"@pulumi/pulumi": "^3.0.0",
|
|
92
|
+
"@smithy/types": "4.14.3"
|
|
86
93
|
},
|
|
87
94
|
"onlyBuiltDependencies": [
|
|
88
95
|
"@pulumi/command",
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
"title": "DeployPlan",
|
|
5
5
|
"description": "The Maker plan artifact (borrowed from Clanker pattern). Generated by `clawops plan`, applied by `clawops apply`. Reviewable, diff-able, version-controllable.",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": [
|
|
7
|
+
"required": [
|
|
8
|
+
"apiVersion",
|
|
9
|
+
"kind",
|
|
10
|
+
"metadata",
|
|
11
|
+
"spec"
|
|
12
|
+
],
|
|
8
13
|
"properties": {
|
|
9
14
|
"apiVersion": {
|
|
10
15
|
"const": "clawops.dev/v1",
|
|
@@ -15,7 +20,10 @@
|
|
|
15
20
|
},
|
|
16
21
|
"metadata": {
|
|
17
22
|
"type": "object",
|
|
18
|
-
"required": [
|
|
23
|
+
"required": [
|
|
24
|
+
"name",
|
|
25
|
+
"generatedAt"
|
|
26
|
+
],
|
|
19
27
|
"properties": {
|
|
20
28
|
"name": {
|
|
21
29
|
"type": "string",
|
|
@@ -38,7 +46,9 @@
|
|
|
38
46
|
},
|
|
39
47
|
"labels": {
|
|
40
48
|
"type": "object",
|
|
41
|
-
"additionalProperties": {
|
|
49
|
+
"additionalProperties": {
|
|
50
|
+
"type": "string"
|
|
51
|
+
},
|
|
42
52
|
"description": "User-supplied labels (env=prod, team=platform, etc.)"
|
|
43
53
|
},
|
|
44
54
|
"stackVersion": {
|
|
@@ -49,10 +59,21 @@
|
|
|
49
59
|
},
|
|
50
60
|
"spec": {
|
|
51
61
|
"type": "object",
|
|
52
|
-
"required": [
|
|
62
|
+
"required": [
|
|
63
|
+
"provider",
|
|
64
|
+
"stackName",
|
|
65
|
+
"instanceType",
|
|
66
|
+
"openclaw",
|
|
67
|
+
"network"
|
|
68
|
+
],
|
|
53
69
|
"properties": {
|
|
54
70
|
"provider": {
|
|
55
|
-
"enum": [
|
|
71
|
+
"enum": [
|
|
72
|
+
"aws",
|
|
73
|
+
"gcp",
|
|
74
|
+
"azure",
|
|
75
|
+
"local"
|
|
76
|
+
]
|
|
56
77
|
},
|
|
57
78
|
"region": {
|
|
58
79
|
"type": "string",
|
|
@@ -68,7 +89,9 @@
|
|
|
68
89
|
},
|
|
69
90
|
"openclaw": {
|
|
70
91
|
"type": "object",
|
|
71
|
-
"required": [
|
|
92
|
+
"required": [
|
|
93
|
+
"version"
|
|
94
|
+
],
|
|
72
95
|
"properties": {
|
|
73
96
|
"version": {
|
|
74
97
|
"type": "string",
|
|
@@ -81,7 +104,9 @@
|
|
|
81
104
|
"channels": {
|
|
82
105
|
"type": "object",
|
|
83
106
|
"description": "OpenClaw channel integrations keyed by provider name (e.g. {\"discord\":{\"botToken\":\"...\"}}). Values are provider-specific config objects. Sensitive fields must use $secret references.",
|
|
84
|
-
"additionalProperties": {
|
|
107
|
+
"additionalProperties": {
|
|
108
|
+
"type": "object"
|
|
109
|
+
}
|
|
85
110
|
}
|
|
86
111
|
}
|
|
87
112
|
},
|
|
@@ -90,11 +115,23 @@
|
|
|
90
115
|
"description": "Secret references (R6: never inline values)",
|
|
91
116
|
"items": {
|
|
92
117
|
"type": "object",
|
|
93
|
-
"required": [
|
|
118
|
+
"required": [
|
|
119
|
+
"name",
|
|
120
|
+
"source"
|
|
121
|
+
],
|
|
94
122
|
"properties": {
|
|
95
|
-
"name": {
|
|
123
|
+
"name": {
|
|
124
|
+
"type": "string"
|
|
125
|
+
},
|
|
96
126
|
"source": {
|
|
97
|
-
"enum": [
|
|
127
|
+
"enum": [
|
|
128
|
+
"env",
|
|
129
|
+
"aws-sm",
|
|
130
|
+
"aws-ssm",
|
|
131
|
+
"gcp-sm",
|
|
132
|
+
"azure-kv",
|
|
133
|
+
"file"
|
|
134
|
+
]
|
|
98
135
|
},
|
|
99
136
|
"ref": {
|
|
100
137
|
"type": "string",
|
|
@@ -105,26 +142,56 @@
|
|
|
105
142
|
},
|
|
106
143
|
"network": {
|
|
107
144
|
"type": "object",
|
|
108
|
-
"required": [
|
|
145
|
+
"required": [
|
|
146
|
+
"allowedSshCidrs",
|
|
147
|
+
"allowedGatewayCidrs"
|
|
148
|
+
],
|
|
109
149
|
"properties": {
|
|
110
150
|
"allowedSshCidrs": {
|
|
111
151
|
"type": "array",
|
|
112
|
-
"items": {
|
|
152
|
+
"items": {
|
|
153
|
+
"type": "string",
|
|
154
|
+
"format": "cidr"
|
|
155
|
+
},
|
|
113
156
|
"minItems": 0,
|
|
114
157
|
"description": "Empty array = no SSH access (unusual but allowed). Defaults applied at plan generation, not in schema"
|
|
115
158
|
},
|
|
116
159
|
"allowedGatewayCidrs": {
|
|
117
160
|
"type": "array",
|
|
118
|
-
"items": {
|
|
119
|
-
|
|
161
|
+
"items": {
|
|
162
|
+
"type": "string",
|
|
163
|
+
"format": "cidr"
|
|
164
|
+
},
|
|
165
|
+
"description": "CIDRs allowed to reach the gateway port. Only meaningful with publishGateway \"all\" — under \"loopback\" nothing listens on a routable interface, so these rules would admit traffic to a closed port. clawops refuses that combination rather than creating rules that do nothing."
|
|
166
|
+
},
|
|
167
|
+
"gatewayPort": {
|
|
168
|
+
"type": "integer",
|
|
169
|
+
"minimum": 1,
|
|
170
|
+
"maximum": 65535,
|
|
171
|
+
"default": 18789,
|
|
172
|
+
"description": "Host port the gateway is published on. Carried in the plan so the firewall rules, the container publish flag, the startup config and the gateway URL all come from one place; it used to be a constant redeclared in six files, which made a port change a six-file edit that could half-apply."
|
|
120
173
|
},
|
|
121
174
|
"tailscale": {
|
|
122
175
|
"type": "object",
|
|
123
176
|
"description": "Optional Tailscale sidecar (borrowed pattern from schmitthub)",
|
|
124
177
|
"properties": {
|
|
125
|
-
"enabled": {
|
|
126
|
-
|
|
178
|
+
"enabled": {
|
|
179
|
+
"type": "boolean"
|
|
180
|
+
},
|
|
181
|
+
"authKeyRef": {
|
|
182
|
+
"type": "string",
|
|
183
|
+
"description": "Reference to a secret containing the Tailscale auth key"
|
|
184
|
+
}
|
|
127
185
|
}
|
|
186
|
+
},
|
|
187
|
+
"publishGateway": {
|
|
188
|
+
"type": "string",
|
|
189
|
+
"enum": [
|
|
190
|
+
"loopback",
|
|
191
|
+
"all"
|
|
192
|
+
],
|
|
193
|
+
"default": "loopback",
|
|
194
|
+
"description": "Which interface the gateway container publishes on. \"loopback\" (default) binds 127.0.0.1 on the host, so the gateway is reachable only via `clawops tunnel` or a reverse proxy running on that host. \"all\" binds 0.0.0.0. Deliberately separate from allowedGatewayCidrs: a firewall rule says who may connect, this says whether the port is listening at all, and exposure should be an explicit choice rather than inherited from a CIDR chosen for SSH. \"all\" serves plaintext HTTP unless you front it with TLS."
|
|
128
195
|
}
|
|
129
196
|
}
|
|
130
197
|
},
|
|
@@ -135,12 +202,17 @@
|
|
|
135
202
|
"type": "string",
|
|
136
203
|
"description": "Public key contents (safe to inline). Private key never in plan"
|
|
137
204
|
},
|
|
138
|
-
"user": {
|
|
205
|
+
"user": {
|
|
206
|
+
"type": "string",
|
|
207
|
+
"default": "ubuntu"
|
|
208
|
+
}
|
|
139
209
|
}
|
|
140
210
|
},
|
|
141
211
|
"tags": {
|
|
142
212
|
"type": "object",
|
|
143
|
-
"additionalProperties": {
|
|
213
|
+
"additionalProperties": {
|
|
214
|
+
"type": "string"
|
|
215
|
+
},
|
|
144
216
|
"description": "Cloud-resource tags propagated to all created resources"
|
|
145
217
|
}
|
|
146
218
|
}
|
|
@@ -151,15 +223,23 @@
|
|
|
151
223
|
"properties": {
|
|
152
224
|
"create": {
|
|
153
225
|
"type": "array",
|
|
154
|
-
"items": {
|
|
226
|
+
"items": {
|
|
227
|
+
"$ref": "#/$defs/ResourceRef"
|
|
228
|
+
}
|
|
155
229
|
},
|
|
156
230
|
"update": {
|
|
157
231
|
"type": "array",
|
|
158
232
|
"items": {
|
|
159
233
|
"type": "object",
|
|
160
|
-
"required": [
|
|
234
|
+
"required": [
|
|
235
|
+
"resource",
|
|
236
|
+
"before",
|
|
237
|
+
"after"
|
|
238
|
+
],
|
|
161
239
|
"properties": {
|
|
162
|
-
"resource": {
|
|
240
|
+
"resource": {
|
|
241
|
+
"$ref": "#/$defs/ResourceRef"
|
|
242
|
+
},
|
|
163
243
|
"before": {},
|
|
164
244
|
"after": {}
|
|
165
245
|
}
|
|
@@ -167,16 +247,23 @@
|
|
|
167
247
|
},
|
|
168
248
|
"delete": {
|
|
169
249
|
"type": "array",
|
|
170
|
-
"items": {
|
|
250
|
+
"items": {
|
|
251
|
+
"$ref": "#/$defs/ResourceRef"
|
|
252
|
+
}
|
|
171
253
|
},
|
|
172
|
-
"totalChanges": {
|
|
254
|
+
"totalChanges": {
|
|
255
|
+
"type": "integer"
|
|
256
|
+
}
|
|
173
257
|
}
|
|
174
258
|
}
|
|
175
259
|
},
|
|
176
260
|
"$defs": {
|
|
177
261
|
"ResourceRef": {
|
|
178
262
|
"type": "object",
|
|
179
|
-
"required": [
|
|
263
|
+
"required": [
|
|
264
|
+
"urn",
|
|
265
|
+
"type"
|
|
266
|
+
],
|
|
180
267
|
"properties": {
|
|
181
268
|
"urn": {
|
|
182
269
|
"type": "string",
|
|
@@ -186,7 +273,9 @@
|
|
|
186
273
|
"type": "string",
|
|
187
274
|
"description": "Pulumi resource type token"
|
|
188
275
|
},
|
|
189
|
-
"name": {
|
|
276
|
+
"name": {
|
|
277
|
+
"type": "string"
|
|
278
|
+
}
|
|
190
279
|
}
|
|
191
280
|
}
|
|
192
281
|
}
|