@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
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
resolveSecrets
|
|
4
|
+
} from "./chunk-BOPSG2LI.js";
|
|
5
|
+
import {
|
|
6
|
+
saveOverlay
|
|
7
|
+
} from "./chunk-6ZFIFDBJ.js";
|
|
8
|
+
import {
|
|
9
|
+
atomicWriteConfig,
|
|
10
|
+
deepMerge,
|
|
11
|
+
readRemoteConfig,
|
|
12
|
+
restartGateway
|
|
13
|
+
} from "./chunk-2I7KCMXZ.js";
|
|
14
|
+
import {
|
|
15
|
+
writeStackConfig
|
|
16
|
+
} from "./chunk-HSPHXG6W.js";
|
|
17
|
+
import {
|
|
18
|
+
validatePlan
|
|
19
|
+
} from "./chunk-BSLIYB5Q.js";
|
|
20
|
+
import {
|
|
21
|
+
buildContext
|
|
22
|
+
} from "./chunk-5XT5IAJK.js";
|
|
23
|
+
import {
|
|
24
|
+
GATEWAY_PORT
|
|
25
|
+
} from "./chunk-VOEJYRIK.js";
|
|
26
|
+
import {
|
|
27
|
+
UsageError
|
|
28
|
+
} from "./chunk-KGXPLI7W.js";
|
|
29
|
+
|
|
30
|
+
// src/plan/apply.ts
|
|
31
|
+
import process from "process";
|
|
32
|
+
async function applyPlan(plan, opts) {
|
|
33
|
+
const validation = validatePlan(plan);
|
|
34
|
+
if (!validation.ok) {
|
|
35
|
+
throw new UsageError(
|
|
36
|
+
`Invalid deploy plan:
|
|
37
|
+
${validation.errors.join("\n")}`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
if (plan.spec.provider === "local") {
|
|
41
|
+
throw new UsageError(
|
|
42
|
+
"plan/apply is not supported for the local provider. Use `clawops up` directly."
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
const { guardOpenclawVersion } = await import("./version-guard-XVYW5WFJ.js");
|
|
46
|
+
await guardOpenclawVersion(plan.spec.openclaw.version);
|
|
47
|
+
const ctx = buildContext({
|
|
48
|
+
stack: plan.spec.stackName,
|
|
49
|
+
provider: plan.spec.provider
|
|
50
|
+
});
|
|
51
|
+
const stack = await ctx.getStack();
|
|
52
|
+
await writeStackConfig(stack, plan);
|
|
53
|
+
if (plan.metadata.stackVersion !== void 0) {
|
|
54
|
+
const currentInfo = await stack.info();
|
|
55
|
+
if (currentInfo !== void 0 && currentInfo.version !== plan.metadata.stackVersion) {
|
|
56
|
+
process.stderr.write(
|
|
57
|
+
`
|
|
58
|
+
Warning: stack "${plan.spec.stackName}" has changed since this plan was generated (plan version: ${plan.metadata.stackVersion}, current: ${currentInfo.version}).
|
|
59
|
+
The diff you reviewed may no longer reflect what will be applied.
|
|
60
|
+
|
|
61
|
+
`
|
|
62
|
+
);
|
|
63
|
+
if (opts?.confirmDrift) {
|
|
64
|
+
await opts.confirmDrift();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const start = Date.now();
|
|
69
|
+
const result = await stack.up({ onOutput: opts?.onOutput, signal: opts?.signal });
|
|
70
|
+
const outputs = Object.fromEntries(
|
|
71
|
+
Object.entries(result.outputs).map(([k, v]) => [k, v.value])
|
|
72
|
+
);
|
|
73
|
+
const changeSummary = {};
|
|
74
|
+
if (result.summary.resourceChanges) {
|
|
75
|
+
for (const [op, count] of Object.entries(result.summary.resourceChanges)) {
|
|
76
|
+
changeSummary[op] = count;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const { waitForSsh } = await import("./wait-WO72TRRQ.js");
|
|
80
|
+
const conn = await connectionInfoFor(ctx, outputs);
|
|
81
|
+
if (opts?.skipReadiness) {
|
|
82
|
+
return { outputs, changeSummary, durationMs: Date.now() - start };
|
|
83
|
+
}
|
|
84
|
+
const readySession = await waitForSsh(conn, {
|
|
85
|
+
signal: opts?.signal,
|
|
86
|
+
onProgress: (line) => reportProgress(opts, line)
|
|
87
|
+
});
|
|
88
|
+
const { waitForGateway } = await import("./ready-KDNRBNSU.js");
|
|
89
|
+
try {
|
|
90
|
+
await waitForGateway(readySession, {
|
|
91
|
+
signal: opts?.signal,
|
|
92
|
+
port: plan.spec.network?.gatewayPort ?? GATEWAY_PORT,
|
|
93
|
+
onProgress: (line) => reportProgress(opts, line)
|
|
94
|
+
});
|
|
95
|
+
} finally {
|
|
96
|
+
readySession.close();
|
|
97
|
+
}
|
|
98
|
+
const hasOverlay = plan.spec.openclaw.config !== void 0 || plan.spec.openclaw.channels !== void 0;
|
|
99
|
+
if (hasOverlay) {
|
|
100
|
+
await applyConfigOverlay(plan, outputs, ctx, opts?.signal);
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
outputs,
|
|
104
|
+
changeSummary,
|
|
105
|
+
durationMs: Date.now() - start
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function reportProgress(opts, line) {
|
|
109
|
+
if (opts?.onProgress) opts.onProgress(line);
|
|
110
|
+
else opts?.onOutput?.(line);
|
|
111
|
+
}
|
|
112
|
+
async function connectionInfoFor(ctx, outputs) {
|
|
113
|
+
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
114
|
+
return ctx.adapter.getConnectionInfo({
|
|
115
|
+
...extractBaseOutputs(outputs),
|
|
116
|
+
privateKeyPath: expandHome(ctx.config.ssh.keyPath),
|
|
117
|
+
knownHostsPath: expandHome(ctx.config.ssh.knownHostsPath)
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function expandHome(p) {
|
|
121
|
+
return p.replace(/^~/, process.env["HOME"] ?? "~");
|
|
122
|
+
}
|
|
123
|
+
async function applyConfigOverlay(plan, outputs, ctx, signal) {
|
|
124
|
+
const { connect } = await import("./ssh-VAI5DU5M.js");
|
|
125
|
+
const session = await connect({ ...await connectionInfoFor(ctx, outputs), signal });
|
|
126
|
+
try {
|
|
127
|
+
const remote = await readRemoteConfig(session, signal);
|
|
128
|
+
const configOverlay = plan.spec.openclaw.config ?? {};
|
|
129
|
+
const resolvedOverlay = resolveSecrets(
|
|
130
|
+
configOverlay,
|
|
131
|
+
plan.spec.secrets ?? []
|
|
132
|
+
);
|
|
133
|
+
const merged = deepMerge(remote, {
|
|
134
|
+
...resolvedOverlay,
|
|
135
|
+
...plan.spec.openclaw.channels !== void 0 ? { channels: plan.spec.openclaw.channels } : {}
|
|
136
|
+
});
|
|
137
|
+
await atomicWriteConfig(session, merged, signal, {
|
|
138
|
+
openclawVersion: plan.spec.openclaw.version
|
|
139
|
+
});
|
|
140
|
+
await installProviderPlugins(session, merged, plan.spec.openclaw.version, signal);
|
|
141
|
+
await installChannelPlugins(session, merged, plan.spec.openclaw.version, signal);
|
|
142
|
+
await restartGateway(session, signal);
|
|
143
|
+
await verifyProviders(session, merged, signal);
|
|
144
|
+
await verifyChannels(session, merged, signal);
|
|
145
|
+
saveOverlay(plan.spec.stackName, configOverlay, plan.spec.secrets ?? []);
|
|
146
|
+
} finally {
|
|
147
|
+
session.close();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async function installProviderPlugins(session, cfg, openclawVersion, signal) {
|
|
151
|
+
const [{ requiredPlugins, installCommand }, { STATE_DIR_HOST_LINUX }, yaml, { readFileSync }, { join }, { resolveSpecDir }] = await Promise.all([
|
|
152
|
+
import("./plugins-DTST3OER.js"),
|
|
153
|
+
import("./runtime-X3KW5TCP.js"),
|
|
154
|
+
import("./js-yaml-PTEEG4FO.js"),
|
|
155
|
+
import("fs"),
|
|
156
|
+
import("path"),
|
|
157
|
+
import("./spec-path-KQOOIQCA.js")
|
|
158
|
+
]);
|
|
159
|
+
const catalog = yaml.load(
|
|
160
|
+
readFileSync(join(resolveSpecDir(), "models.yaml"), "utf-8")
|
|
161
|
+
);
|
|
162
|
+
const needed = requiredPlugins(cfg, catalog);
|
|
163
|
+
if (needed.length === 0) return;
|
|
164
|
+
const { execPrivileged } = await import("./privileged-JFA6LLTV.js");
|
|
165
|
+
const image = `ghcr.io/openclaw/openclaw:${openclawVersion}`;
|
|
166
|
+
for (const plugin of needed) {
|
|
167
|
+
const result = await execPrivileged(
|
|
168
|
+
session,
|
|
169
|
+
installCommand(plugin, image, STATE_DIR_HOST_LINUX),
|
|
170
|
+
signal
|
|
171
|
+
);
|
|
172
|
+
if (result.code !== 0) {
|
|
173
|
+
process.stderr.write(
|
|
174
|
+
`[clawops] warning: could not install ${plugin.package}@${plugin.version} for provider "${plugin.providerId}": ${result.stderr || result.stdout}
|
|
175
|
+
`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async function verifyProviders(session, cfg, signal) {
|
|
181
|
+
const { missingProviders } = await import("./plugins-DTST3OER.js");
|
|
182
|
+
const { execPrivileged } = await import("./privileged-JFA6LLTV.js");
|
|
183
|
+
const result = await execPrivileged(
|
|
184
|
+
session,
|
|
185
|
+
"docker exec openclaw openclaw plugins list --json",
|
|
186
|
+
signal
|
|
187
|
+
);
|
|
188
|
+
if (result.code !== 0) return;
|
|
189
|
+
const missing = missingProviders(cfg, result.stdout);
|
|
190
|
+
if (missing.length > 0) {
|
|
191
|
+
process.stderr.write(
|
|
192
|
+
`[clawops] warning: the gateway is running, but these configured model providers did not load: ${missing.join(", ")}.
|
|
193
|
+
[clawops] The deployment will look healthy and fail on first use. Check egress to ClawHub, then re-run apply.
|
|
194
|
+
`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async function loadChannelCatalog() {
|
|
199
|
+
const [yaml, { readFileSync }, { join }, { resolveSpecDir }] = await Promise.all([
|
|
200
|
+
import("./js-yaml-PTEEG4FO.js"),
|
|
201
|
+
import("fs"),
|
|
202
|
+
import("path"),
|
|
203
|
+
import("./spec-path-KQOOIQCA.js")
|
|
204
|
+
]);
|
|
205
|
+
return yaml.load(readFileSync(join(resolveSpecDir(), "integrations.yaml"), "utf-8"));
|
|
206
|
+
}
|
|
207
|
+
async function installChannelPlugins(session, cfg, openclawVersion, signal) {
|
|
208
|
+
const [{ requiredChannelPlugins, channelInstallCommand }, { STATE_DIR_HOST_LINUX }] = await Promise.all([import("./channels-KBUR42IU.js"), import("./runtime-X3KW5TCP.js")]);
|
|
209
|
+
const needed = requiredChannelPlugins(cfg, await loadChannelCatalog());
|
|
210
|
+
if (needed.length === 0) return;
|
|
211
|
+
const { execPrivileged } = await import("./privileged-JFA6LLTV.js");
|
|
212
|
+
const image = `ghcr.io/openclaw/openclaw:${openclawVersion}`;
|
|
213
|
+
for (const plugin of needed) {
|
|
214
|
+
const result = await execPrivileged(
|
|
215
|
+
session,
|
|
216
|
+
channelInstallCommand(plugin, image, STATE_DIR_HOST_LINUX),
|
|
217
|
+
signal
|
|
218
|
+
);
|
|
219
|
+
if (result.code !== 0) {
|
|
220
|
+
process.stderr.write(
|
|
221
|
+
`[clawops] warning: could not install ${plugin.package}@${plugin.version} for channel "${plugin.channelKey}": ${result.stderr || result.stdout}
|
|
222
|
+
`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
async function verifyChannels(session, cfg, signal) {
|
|
228
|
+
const { missingChannels, CHANNELS_LIST_CMD } = await import("./channels-KBUR42IU.js");
|
|
229
|
+
const { execPrivileged } = await import("./privileged-JFA6LLTV.js");
|
|
230
|
+
const result = await execPrivileged(session, CHANNELS_LIST_CMD, signal);
|
|
231
|
+
if (result.code !== 0) return;
|
|
232
|
+
const missing = missingChannels(cfg, result.stdout, await loadChannelCatalog());
|
|
233
|
+
if (missing.length > 0) {
|
|
234
|
+
process.stderr.write(
|
|
235
|
+
`[clawops] warning: the gateway is running, but these configured channels are not installed: ${missing.join(", ")}.
|
|
236
|
+
[clawops] They will never connect. Check egress to registry.npmjs.org, then re-run apply.
|
|
237
|
+
`
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export {
|
|
243
|
+
applyPlan
|
|
244
|
+
};
|