@clawops/cli 1.7.0 → 1.7.2
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 +62 -0
- package/dist/{apply-BTZFFGAD.js → apply-PZ5IIU7Z.js} +5 -4
- package/dist/{aws-D7Y6LCGK.js → aws-L4RR2LSE.js} +1 -1
- package/dist/{azure-JQAMNVHN.js → azure-7OXQENQL.js} +1 -1
- package/dist/{bootstrap-RY4VOSDJ.js → bootstrap-HL4DNUNG.js} +13 -4
- package/dist/bootstrap.sh.tmpl +204 -0
- package/dist/chunk-2YOP6N7X.js +126 -0
- package/dist/{chunk-GJEF6UQA.js → chunk-3XK66DKK.js} +100 -16
- package/dist/{chunk-ISFHLA4G.js → chunk-5SPESD5N.js} +8 -6
- package/dist/{chunk-YTH4L2GN.js → chunk-6X45DDGH.js} +5 -4
- package/dist/{chunk-XKT42M34.js → chunk-C5X375RO.js} +14 -1
- package/dist/{chunk-LCKD7L7X.js → chunk-DQDAWNGB.js} +1 -1
- package/dist/{chunk-CG3Y7Y2R.js → chunk-FSUWPL7Q.js} +9 -9
- package/dist/{chunk-ZFNPM2WG.js → chunk-O3F7OGH7.js} +40 -3
- package/dist/{chunk-3MFZ7E74.js → chunk-P5LKWRPL.js} +3 -3
- package/dist/chunk-PVUVI35Y.js +29 -0
- package/dist/{chunk-7KLLWDBA.js → chunk-SEABO2UU.js} +7 -4
- package/dist/cli.js +122 -68
- package/dist/{context-ALSJMTHE.js → context-5LCUG2QR.js} +1 -1
- package/dist/{gcp-6FT2A45S.js → gcp-UG6AWPIZ.js} +1 -1
- package/dist/{generate-ZTD4BVVI.js → generate-NIF6IBZC.js} +4 -3
- package/dist/{harden-BDVYW567.js → harden-URPXLSVF.js} +2 -2
- package/dist/{mcp-wire-ZWIYMLEW.js → mcp-wire-SLL4TLSC.js} +1 -1
- package/dist/{package-7WOZMHSO.js → package-TZ2HYF5C.js} +3 -2
- package/dist/{pool-JZGKPP6K.js → pool-QGFQRMGU.js} +2 -2
- package/dist/{remote-config-QF5TT7GU.js → remote-config-PFB66RPY.js} +3 -1
- package/dist/{server-EXBOOIEP.js → server-WM3AY4PJ.js} +19 -18
- package/dist/{ssh-E2AMBPZY.js → ssh-CNJNLM3E.js} +1 -1
- package/dist/{validate-T5M5EHSJ.js → validate-CFQ4FH2T.js} +2 -1
- package/dist/version-guard-MZAO4KHS.js +25 -0
- package/dist/versions-OEPAS2EL.js +24 -0
- package/package.json +3 -2
- package/spec/_gen-schemas.md +136 -0
- package/spec/deploy-plan.schema.json +193 -0
- package/spec/errors.yaml +175 -0
- package/spec/integrations.yaml +97 -0
- package/spec/invariants.yaml +81 -0
- package/spec/mcp-tools.yaml +532 -0
- package/spec/models.yaml +113 -0
- package/spec/openclaw-versions.yaml +67 -0
- package/spec/providers.schema.json +120 -0
|
@@ -42,6 +42,17 @@ usermod -aG docker clawops
|
|
|
42
42
|
OPENCLAW_VERSION="${openclawVersion}"
|
|
43
43
|
docker pull ghcr.io/openclaw/openclaw:\${OPENCLAW_VERSION}
|
|
44
44
|
|
|
45
|
+
# \u2500\u2500 Gateway auth token \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
46
|
+
# OpenClaw refuses a non-loopback bind without auth, and in a container it always
|
|
47
|
+
# binds 0.0.0.0. Without a token the gateway exits 78 and restart-loops.
|
|
48
|
+
OPENCLAW_ENV_FILE=/home/clawops/openclaw.env
|
|
49
|
+
if [ ! -s "\${OPENCLAW_ENV_FILE}" ]; then
|
|
50
|
+
OPENCLAW_TOKEN=$(openssl rand -hex 32 2>/dev/null || head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \\n')
|
|
51
|
+
printf 'OPENCLAW_GATEWAY_TOKEN=%s\\n' "\${OPENCLAW_TOKEN}" > "\${OPENCLAW_ENV_FILE}"
|
|
52
|
+
chmod 600 "\${OPENCLAW_ENV_FILE}"
|
|
53
|
+
chown clawops:clawops "\${OPENCLAW_ENV_FILE}"
|
|
54
|
+
fi
|
|
55
|
+
|
|
45
56
|
# \u2500\u2500 Default config (apply.ts will overwrite with plan overlay) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
46
57
|
OPENCLAW_CONFIG=/home/clawops/openclaw.json
|
|
47
58
|
if [ ! -f "\${OPENCLAW_CONFIG}" ]; then
|
|
@@ -58,9 +69,11 @@ docker run -d \\
|
|
|
58
69
|
--name openclaw \\
|
|
59
70
|
--restart unless-stopped \\
|
|
60
71
|
-p 18789:18789 \\
|
|
72
|
+
-e OPENCLAW_CONFIG_PATH=/app/config.json --add-host=host.docker.internal:host-gateway \\
|
|
73
|
+
--env-file "\${OPENCLAW_ENV_FILE}" \\
|
|
61
74
|
-v "\${OPENCLAW_CONFIG}":/app/config.json:ro \\
|
|
62
75
|
${bedrockEnvBlock} ghcr.io/openclaw/openclaw:\${OPENCLAW_VERSION} \\
|
|
63
|
-
node openclaw.mjs gateway run --allow-unconfigured
|
|
76
|
+
node openclaw.mjs gateway run --allow-unconfigured --port 18789
|
|
64
77
|
`;
|
|
65
78
|
}
|
|
66
79
|
function makeBedrockEnvBlock() {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
acquireSession,
|
|
4
|
+
drainPool
|
|
5
|
+
} from "./chunk-DQDAWNGB.js";
|
|
2
6
|
import {
|
|
3
7
|
OPENCLAW_CONFIG,
|
|
4
8
|
atomicWriteConfig,
|
|
5
9
|
restartGateway
|
|
6
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-O3F7OGH7.js";
|
|
7
11
|
import {
|
|
8
12
|
buildContext
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import {
|
|
11
|
-
acquireSession,
|
|
12
|
-
drainPool
|
|
13
|
-
} from "./chunk-LCKD7L7X.js";
|
|
13
|
+
} from "./chunk-P5LKWRPL.js";
|
|
14
14
|
import {
|
|
15
15
|
chalk,
|
|
16
16
|
failure
|
|
@@ -131,7 +131,7 @@ function renderSnapshot(snap, opts) {
|
|
|
131
131
|
return lines.join("\n");
|
|
132
132
|
}
|
|
133
133
|
async function probeEntries() {
|
|
134
|
-
const { buildContext: buildContext2 } = await import("./context-
|
|
134
|
+
const { buildContext: buildContext2 } = await import("./context-5LCUG2QR.js");
|
|
135
135
|
const { getConfig } = await import("./store-SDUR52Z5.js");
|
|
136
136
|
const config = getConfig();
|
|
137
137
|
if (!config) return [];
|
|
@@ -358,8 +358,8 @@ var monitor_default = defineCommand({
|
|
|
358
358
|
const tailLines = Math.max(1, parseInt(String(args.tail ?? "10"), 10) || 10);
|
|
359
359
|
const isTTY = Boolean(process.stdout.isTTY);
|
|
360
360
|
const noColor = Boolean(args["no-color"]) || !isTTY;
|
|
361
|
-
const { buildContext: buildContext2 } = await import("./context-
|
|
362
|
-
const { acquireSession: acquireSession2, drainPool: drainPool2 } = await import("./pool-
|
|
361
|
+
const { buildContext: buildContext2 } = await import("./context-5LCUG2QR.js");
|
|
362
|
+
const { acquireSession: acquireSession2, drainPool: drainPool2 } = await import("./pool-QGFQRMGU.js");
|
|
363
363
|
const ac = new AbortController();
|
|
364
364
|
process.on("SIGINT", () => ac.abort());
|
|
365
365
|
process.on("SIGTERM", () => ac.abort());
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/openclaw/run-flags.ts
|
|
4
|
+
var CONFIG_MOUNT_PATH = "/app/config.json";
|
|
5
|
+
var GATEWAY_PORT = 18789;
|
|
6
|
+
var CONFIG_PATH_ENV = `-e OPENCLAW_CONFIG_PATH=${CONFIG_MOUNT_PATH}`;
|
|
7
|
+
var ADD_HOST_FLAG = "--add-host=host.docker.internal:host-gateway";
|
|
8
|
+
var PORT_PIN = `--port ${GATEWAY_PORT}`;
|
|
9
|
+
var COMMON_RUN_FLAGS = `${CONFIG_PATH_ENV} ${ADD_HOST_FLAG}`;
|
|
10
|
+
|
|
3
11
|
// src/plan/remote-config.ts
|
|
4
12
|
var OPENCLAW_CONFIG_LINUX = "/home/clawops/openclaw.json";
|
|
5
13
|
var OPENCLAW_CONFIG_MACOS = "~/.config/openclaw/config.json";
|
|
@@ -30,6 +38,18 @@ async function readRemoteConfig(session, signal) {
|
|
|
30
38
|
throw new Error(`Cannot parse ${configPath}: invalid JSON`);
|
|
31
39
|
}
|
|
32
40
|
}
|
|
41
|
+
function normaliseGatewayPort(cfg) {
|
|
42
|
+
const gateway = cfg["gateway"];
|
|
43
|
+
if (!gateway || typeof gateway !== "object" || Array.isArray(gateway)) return void 0;
|
|
44
|
+
const g = gateway;
|
|
45
|
+
const current = g["port"];
|
|
46
|
+
if (typeof current === "number" && current !== GATEWAY_PORT) {
|
|
47
|
+
g["port"] = GATEWAY_PORT;
|
|
48
|
+
return current;
|
|
49
|
+
}
|
|
50
|
+
if (current === void 0) g["port"] = GATEWAY_PORT;
|
|
51
|
+
return void 0;
|
|
52
|
+
}
|
|
33
53
|
async function atomicWriteConfig(session, cfg, signal) {
|
|
34
54
|
const os = await detectOS(session, signal);
|
|
35
55
|
const configPath = configPathForOS(os);
|
|
@@ -50,25 +70,41 @@ async function restartGateway(session, signal) {
|
|
|
50
70
|
const imgResult = os === "Darwin" ? await session.exec(imgCmd, signal) : await execWithFallbackSudo(session, imgCmd, signal);
|
|
51
71
|
const image = imgResult.stdout.trim();
|
|
52
72
|
const cfgResult = await session.exec(`cat ${configPath}`, signal);
|
|
53
|
-
let gatewayCmd =
|
|
73
|
+
let gatewayCmd = `node openclaw.mjs gateway run --allow-unconfigured ${PORT_PIN}`;
|
|
54
74
|
try {
|
|
55
75
|
const cfg = JSON.parse(cfgResult.stdout);
|
|
56
76
|
const token = cfg?.["gateway"]?.["auth"];
|
|
57
77
|
const tokenVal = token?.["token"];
|
|
58
78
|
if (tokenVal) {
|
|
59
|
-
gatewayCmd = `node openclaw.mjs gateway run --allow-unconfigured --token '${tokenVal}'`;
|
|
79
|
+
gatewayCmd = `node openclaw.mjs gateway run --allow-unconfigured ${PORT_PIN} --token '${tokenVal}'`;
|
|
60
80
|
}
|
|
61
81
|
} catch {
|
|
62
82
|
}
|
|
63
83
|
const restartCmd = pathPrefix + [
|
|
64
84
|
"docker stop openclaw 2>/dev/null || true",
|
|
65
85
|
"docker rm openclaw 2>/dev/null || true",
|
|
66
|
-
`docker run -d --name openclaw --restart unless-stopped -p
|
|
86
|
+
`docker run -d --name openclaw --restart unless-stopped -p ${GATEWAY_PORT}:${GATEWAY_PORT} ${COMMON_RUN_FLAGS} -v ${configPath}:/app/config.json:ro ${image} ${gatewayCmd}`
|
|
67
87
|
].join(" && ");
|
|
68
88
|
const result = os === "Darwin" ? await session.exec(restartCmd, signal) : await execWithFallbackSudo(session, restartCmd, signal);
|
|
69
89
|
if (result.code !== 0) {
|
|
70
90
|
throw new Error(`Gateway restart failed: ${result.stderr}`);
|
|
71
91
|
}
|
|
92
|
+
const healthy = await waitForGateway(session, pathPrefix, signal);
|
|
93
|
+
if (!healthy) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
`Gateway restarted but did not become healthy on port ${GATEWAY_PORT}. The previous container has already been replaced; inspect it with \`docker logs openclaw\`. If the newly-applied config is at fault, revert it and restart \u2014 before v1.7.2 this config was never applied, so a value that has sat unused may now be taking effect.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function waitForGateway(session, pathPrefix, signal, attempts = 15) {
|
|
100
|
+
const probe = `${pathPrefix}curl -fsS -m 3 http://127.0.0.1:${GATEWAY_PORT}/healthz >/dev/null 2>&1 && echo ok || echo waiting`;
|
|
101
|
+
for (let i = 0; i < attempts; i++) {
|
|
102
|
+
if (signal?.aborted) return false;
|
|
103
|
+
const r = await session.exec(probe, signal);
|
|
104
|
+
if (r.stdout.trim().endsWith("ok")) return true;
|
|
105
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
72
108
|
}
|
|
73
109
|
function deepMerge(base, overlay) {
|
|
74
110
|
const result = { ...base };
|
|
@@ -91,6 +127,7 @@ export {
|
|
|
91
127
|
OPENCLAW_CONFIG,
|
|
92
128
|
OPENCLAW_TMP,
|
|
93
129
|
readRemoteConfig,
|
|
130
|
+
normaliseGatewayPort,
|
|
94
131
|
atomicWriteConfig,
|
|
95
132
|
restartGateway,
|
|
96
133
|
deepMerge
|
|
@@ -56,17 +56,17 @@ function makeProviderProxy(name) {
|
|
|
56
56
|
if (resolved) return resolved;
|
|
57
57
|
switch (name) {
|
|
58
58
|
case "gcp": {
|
|
59
|
-
const mod = await import("./gcp-
|
|
59
|
+
const mod = await import("./gcp-UG6AWPIZ.js");
|
|
60
60
|
resolved = mod.default;
|
|
61
61
|
return resolved;
|
|
62
62
|
}
|
|
63
63
|
case "aws": {
|
|
64
|
-
const mod = await import("./aws-
|
|
64
|
+
const mod = await import("./aws-L4RR2LSE.js");
|
|
65
65
|
resolved = mod.default;
|
|
66
66
|
return resolved;
|
|
67
67
|
}
|
|
68
68
|
case "azure": {
|
|
69
|
-
const mod = await import("./azure-
|
|
69
|
+
const mod = await import("./azure-7OXQENQL.js");
|
|
70
70
|
resolved = mod.default;
|
|
71
71
|
return resolved;
|
|
72
72
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/spec-path.ts
|
|
4
|
+
import { existsSync } from "fs";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import { dirname, join, parse } from "path";
|
|
7
|
+
var MARKER = "openclaw-versions.yaml";
|
|
8
|
+
var _cached;
|
|
9
|
+
function resolveSpecDir(startUrl = import.meta.url) {
|
|
10
|
+
if (_cached) return _cached;
|
|
11
|
+
let dir = dirname(fileURLToPath(startUrl));
|
|
12
|
+
const { root } = parse(dir);
|
|
13
|
+
while (true) {
|
|
14
|
+
const candidate = join(dir, "spec");
|
|
15
|
+
if (existsSync(join(candidate, MARKER))) {
|
|
16
|
+
_cached = candidate;
|
|
17
|
+
return candidate;
|
|
18
|
+
}
|
|
19
|
+
if (dir === root) break;
|
|
20
|
+
dir = dirname(dir);
|
|
21
|
+
}
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Cannot locate the spec/ directory (searched upward from ${dirname(fileURLToPath(startUrl))}). If this is an installed package, spec/ may be missing from the published files.`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
resolveSpecDir
|
|
29
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
validatePlan
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6X45DDGH.js";
|
|
5
5
|
import {
|
|
6
6
|
buildContext
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-P5LKWRPL.js";
|
|
8
8
|
import {
|
|
9
9
|
getConfig
|
|
10
10
|
} from "./chunk-CX5SL5HP.js";
|
|
@@ -45,10 +45,13 @@ async function generatePlan(intent, _opts) {
|
|
|
45
45
|
"plan/apply is not supported for the local provider. Use `clawops up` directly."
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
|
-
const { version } = await import("./package-
|
|
48
|
+
const { version } = await import("./package-TZ2HYF5C.js");
|
|
49
49
|
const config = getConfig();
|
|
50
50
|
const instanceType = intent.instanceType ?? "small";
|
|
51
|
-
const
|
|
51
|
+
const { guardOpenclawVersion, defaultOpenclawVersion } = await import("./version-guard-MZAO4KHS.js");
|
|
52
|
+
const openclawVersion = await guardOpenclawVersion(
|
|
53
|
+
intent.openclawVersion ?? await defaultOpenclawVersion()
|
|
54
|
+
);
|
|
52
55
|
const network = intent.network ?? {
|
|
53
56
|
allowedSshCidrs: [],
|
|
54
57
|
allowedGatewayCidrs: []
|