@clawops/cli 2.0.0 → 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.
Files changed (75) hide show
  1. package/README.md +98 -12
  2. package/dist/apply-KYFPWI5U.js +27 -0
  3. package/dist/automation-RMAIBNVC.js +44 -0
  4. package/dist/bedrock-XVASJX2K.js +61 -0
  5. package/dist/{bootstrap-DMRPWJGN.js → bootstrap-HNGKY6WW.js} +11 -8
  6. package/dist/{chunk-N44K3LHE.js → chunk-2I7KCMXZ.js} +6 -4
  7. package/dist/{chunk-3WYA2QDM.js → chunk-2Z7J3ERQ.js} +1 -1
  8. package/dist/chunk-3OLUJPCB.js +36 -0
  9. package/dist/chunk-5XT5IAJK.js +69 -0
  10. package/dist/chunk-AEEMRFZV.js +24 -0
  11. package/dist/{chunk-YR3O2I3S.js → chunk-BSLIYB5Q.js} +6 -1
  12. package/dist/{chunk-AHAAEXWC.js → chunk-E4NJSJ54.js} +16 -93
  13. package/dist/chunk-FEK7VJAY.js +16 -0
  14. package/dist/{chunk-6TIYVHPX.js → chunk-GIEVAGEK.js} +7 -33
  15. package/dist/chunk-HSPHXG6W.js +67 -0
  16. package/dist/{chunk-GYV4KNW7.js → chunk-IVWP4QUJ.js} +133 -40
  17. package/dist/{chunk-AX74VXTV.js → chunk-KC3GC3PE.js} +58 -49
  18. package/dist/{chunk-UFRO4H5W.js → chunk-LBE6COC4.js} +56 -40
  19. package/dist/chunk-LEVIW2PV.js +890 -0
  20. package/dist/chunk-MC5ATCXS.js +108 -0
  21. package/dist/chunk-N4WZLWJ4.js +16 -0
  22. package/dist/{chunk-SBLQH2TJ.js → chunk-NUL5F6YV.js} +1 -1
  23. package/dist/chunk-RHOWYIWT.js +52 -0
  24. package/dist/{chunk-WHJMKDV7.js → chunk-STLRHLLV.js} +65 -12
  25. package/dist/chunk-V25QRZRB.js +45 -0
  26. package/dist/chunk-VOEJYRIK.js +33 -0
  27. package/dist/{providers-2OABPW2E.js → chunk-VUFMZEIM.js} +3 -2
  28. package/dist/chunk-W3OLNNJW.js +51 -0
  29. package/dist/cli-WLD3EBEM.js +11 -0
  30. package/dist/cli-auth-GD5SK7JU.js +13 -0
  31. package/dist/cli.js +518 -206
  32. package/dist/context-7EVC6W45.js +20 -0
  33. package/dist/docker-3PDO4TS7.js +12 -0
  34. package/dist/{firewall-T3NTPZJD.js → firewall-5VKZ4WBH.js} +22 -1
  35. package/dist/generate-I6YQ5V2T.js +29 -0
  36. package/dist/{harden-PCDK3UQ5.js → harden-72JMRT4E.js} +8 -5
  37. package/dist/index.d.ts +56 -0
  38. package/dist/known-hosts-file-I3Q3NBYQ.js +22 -0
  39. package/dist/{logs-P7YCKVF4.js → logs-5A7YYA53.js} +1 -1
  40. package/dist/{mcp-wire-BFEY2Y6H.js → mcp-wire-3SWBM7D6.js} +25 -15
  41. package/dist/models-AGTQWYDL.js +32 -0
  42. package/dist/network-args-PYJRJBYO.js +64 -0
  43. package/dist/{package-3HUW57XH.js → package-5BCMEBTE.js} +10 -3
  44. package/dist/passphrase-MJBE45N7.js +15 -0
  45. package/dist/{pool-EX4ZTA5P.js → pool-PIIKJ4L2.js} +3 -2
  46. package/dist/preflight-EF52S3WW.js +162 -0
  47. package/dist/preflight-MWWM5JT3.js +181 -0
  48. package/dist/preflight-TFD4N5ZU.js +141 -0
  49. package/dist/providers-FW6H6OPF.js +11 -0
  50. package/dist/ready-KDNRBNSU.js +95 -0
  51. package/dist/{remote-config-Z6IIZR3D.js → remote-config-3HZLUWEA.js} +3 -2
  52. package/dist/{runtime-LZ7NA53V.js → runtime-X3KW5TCP.js} +4 -2
  53. package/dist/server-GBA7BJGK.js +46 -0
  54. package/dist/ssh-VAI5DU5M.js +11 -0
  55. package/dist/ssh-key-DUO6OKOI.js +7 -0
  56. package/dist/stack-config-R4SPSUQZ.js +12 -0
  57. package/dist/{validate-BOQRWX4F.js → validate-YVI3BJ55.js} +1 -1
  58. package/dist/wait-WO72TRRQ.js +79 -0
  59. package/package.json +10 -3
  60. package/spec/mcp-tools.yaml +21 -2
  61. package/spec/models.yaml +14 -3
  62. package/spec/providers.schema.json +163 -28
  63. package/dist/apply-AM5HERE7.js +0 -19
  64. package/dist/automation-RULUSJBW.js +0 -30
  65. package/dist/aws-AMON7DA7.js +0 -265
  66. package/dist/azure-T4G6OBJQ.js +0 -273
  67. package/dist/chunk-CKSPROD5.js +0 -129
  68. package/dist/chunk-LU2V3LXA.js +0 -114
  69. package/dist/context-KHKWJJMC.js +0 -10
  70. package/dist/gcp-2JBTD7ZM.js +0 -204
  71. package/dist/generate-2XV2GSP2.js +0 -15
  72. package/dist/local-DXBEVZ5C.js +0 -47
  73. package/dist/server-A5AB67GQ.js +0 -36
  74. package/dist/ssh-B3NZAU4I.js +0 -8
  75. package/dist/{version-guard-GPSTCPT7.js → version-guard-XVYW5WFJ.js} +1 -1
@@ -1,273 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- makeStartupScript
4
- } from "./chunk-CKSPROD5.js";
5
- import {
6
- GATEWAY_PORT
7
- } from "./chunk-6TIYVHPX.js";
8
- import "./chunk-EI7CQQ7D.js";
9
-
10
- // src/providers/azure/index.ts
11
- import process2 from "process";
12
-
13
- // src/providers/azure/program.ts
14
- import { createHash } from "crypto";
15
- var SSH_PORT = 22;
16
- var azureProgram = async () => {
17
- const [pulumi, azure, random, { resolveIngressCidrs, resolveGatewayIngressCidrs, resolveGatewayPort, detectEgressIp }] = await Promise.all([
18
- import("@pulumi/pulumi"),
19
- import("@pulumi/azure-native"),
20
- import("@pulumi/random"),
21
- import("./firewall-T3NTPZJD.js")
22
- ]);
23
- const cfg = new pulumi.Config();
24
- const stackName = pulumi.getStack();
25
- const instanceType = cfg.get("instanceType") ?? "Standard_B2s";
26
- const location = cfg.get("region") ?? "eastus";
27
- const openclawVersion = cfg.get("openclawVersion") ?? "latest";
28
- const publishGateway = cfg.get("publishGateway") === "all" ? "all" : "loopback";
29
- const gatewayPort = resolveGatewayPort(cfg.get("gatewayPort"), GATEWAY_PORT);
30
- const accessMode = cfg.get("accessMode") ?? "restricted";
31
- const allowedCidrs = cfg.get("allowedCidrs") ?? "";
32
- const sshCidrs = cfg.get("sshCidrs") ?? "";
33
- const gatewayCidrs = cfg.get("gatewayCidrs") ?? "";
34
- const keyVaultEnabled = cfg.get("keyVaultEnabled") === "true";
35
- const resourceGroupName = cfg.get("resourceGroupName") ?? `clawops-${stackName}`;
36
- const sshPublicKey = cfg.get("sshPublicKey");
37
- if (!sshPublicKey) {
38
- throw new Error(
39
- 'Stack config "sshPublicKey" is required for the Azure adapter. Set it with: pulumi config set --stack <name> sshPublicKey "ssh-ed25519 ..."'
40
- );
41
- }
42
- const clientConfig = await azure.authorization.getClientConfig({});
43
- const egressResult = accessMode === "auto" ? await detectEgressIp("https://ifconfig.me") : { ok: true, ip: "" };
44
- if (accessMode === "open") {
45
- process.stderr.write(
46
- "[clawops] WARNING: accessMode=open allows 0.0.0.0/0 on SSH and gateway ports. Only use this for development/sandbox stacks.\n"
47
- );
48
- }
49
- const sshIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, sshCidrs, egressResult);
50
- const gatewayIngressCidrs = resolveGatewayIngressCidrs(
51
- publishGateway,
52
- accessMode,
53
- allowedCidrs,
54
- gatewayCidrs,
55
- egressResult
56
- );
57
- const rg = new azure.resources.ResourceGroup("clawops-rg", {
58
- resourceGroupName,
59
- location
60
- });
61
- const vnet = new azure.network.VirtualNetwork("clawops-vnet", {
62
- resourceGroupName: rg.name,
63
- location: rg.location,
64
- addressSpace: { addressPrefixes: ["10.0.0.0/16"] }
65
- });
66
- const subnet = new azure.network.Subnet("clawops-subnet", {
67
- resourceGroupName: rg.name,
68
- virtualNetworkName: vnet.name,
69
- addressPrefix: "10.0.1.0/24"
70
- });
71
- const securityRules = [];
72
- let priority = 100;
73
- for (const cidr of sshIngressCidrs) {
74
- securityRules.push({
75
- name: `allow-ssh-${priority}`,
76
- priority: priority++,
77
- direction: "Inbound",
78
- access: "Allow",
79
- protocol: "Tcp",
80
- sourceAddressPrefix: cidr,
81
- sourcePortRange: "*",
82
- destinationAddressPrefix: "*",
83
- destinationPortRange: String(SSH_PORT)
84
- });
85
- }
86
- for (const cidr of gatewayIngressCidrs) {
87
- securityRules.push({
88
- name: `allow-gateway-${priority}`,
89
- priority: priority++,
90
- direction: "Inbound",
91
- access: "Allow",
92
- protocol: "Tcp",
93
- sourceAddressPrefix: cidr,
94
- sourcePortRange: "*",
95
- destinationAddressPrefix: "*",
96
- destinationPortRange: String(gatewayPort)
97
- });
98
- }
99
- const nsg = new azure.network.NetworkSecurityGroup("clawops-nsg", {
100
- resourceGroupName: rg.name,
101
- location: rg.location,
102
- securityRules
103
- });
104
- const publicIp = new azure.network.PublicIPAddress("clawops-pip", {
105
- resourceGroupName: rg.name,
106
- location: rg.location,
107
- publicIPAllocationMethod: "Static",
108
- sku: { name: "Standard" }
109
- });
110
- const nic = new azure.network.NetworkInterface("clawops-nic", {
111
- resourceGroupName: rg.name,
112
- location: rg.location,
113
- networkSecurityGroup: { id: nsg.id },
114
- ipConfigurations: [{
115
- name: "clawops-ipconfig",
116
- subnet: { id: subnet.id },
117
- publicIPAddress: { id: publicIp.id },
118
- privateIPAllocationMethod: "Dynamic"
119
- }]
120
- });
121
- const vm = new azure.compute.VirtualMachine("clawops-vm", {
122
- resourceGroupName: rg.name,
123
- location: rg.location,
124
- hardwareProfile: { vmSize: instanceType },
125
- identity: { type: "SystemAssigned" },
126
- osProfile: {
127
- adminUsername: "clawops",
128
- computerName: "clawops",
129
- customData: Buffer.from(makeStartupScript({ openclawVersion, os: "ubuntu", publishGateway, gatewayPort })).toString("base64"),
130
- linuxConfiguration: {
131
- disablePasswordAuthentication: true,
132
- ssh: {
133
- publicKeys: [{
134
- keyData: sshPublicKey,
135
- path: "/home/clawops/.ssh/authorized_keys"
136
- }]
137
- }
138
- }
139
- },
140
- storageProfile: {
141
- imageReference: {
142
- publisher: "Canonical",
143
- // Ubuntu 22.04 LTS — Canonical migrated from the legacy 'UbuntuServer'
144
- // offer to this naming scheme. 22_04-lts-gen2 is available in all regions.
145
- offer: "0001-com-ubuntu-server-jammy",
146
- sku: "22_04-lts-gen2",
147
- version: "latest"
148
- },
149
- osDisk: {
150
- createOption: "FromImage",
151
- managedDisk: { storageAccountType: "Premium_LRS" },
152
- diskSizeGB: 30
153
- }
154
- },
155
- networkProfile: {
156
- networkInterfaces: [{ id: nic.id, primary: true }]
157
- }
158
- });
159
- if (keyVaultEnabled) {
160
- const safeName = stackName.replace(/[^a-zA-Z0-9-]/g, "-");
161
- const rawKvName = `clawops-${safeName}-kv`;
162
- const kvName = rawKvName.length > 24 ? `cl-${createHash("sha256").update(stackName).digest("hex").slice(0, 20)}` : rawKvName;
163
- const kv = new azure.keyvault.Vault("clawops-kv", {
164
- resourceGroupName: rg.name,
165
- location: rg.location,
166
- vaultName: kvName,
167
- properties: {
168
- sku: { family: "A", name: "standard" },
169
- tenantId: pulumi.output(vm.identity).apply((i) => i?.tenantId ?? ""),
170
- enableRbacAuthorization: true
171
- }
172
- });
173
- const kvSecretsUserRoleId = `/subscriptions/${clientConfig.subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6`;
174
- new azure.authorization.RoleAssignment("clawops-kv-role", {
175
- scope: kv.id,
176
- roleDefinitionId: kvSecretsUserRoleId,
177
- principalId: pulumi.output(vm.identity).apply((i) => i?.principalId ?? ""),
178
- principalType: "ServicePrincipal"
179
- });
180
- const gatewayToken = new random.RandomPassword("clawops-kv-gateway-token", {
181
- length: 32,
182
- special: false
183
- });
184
- new azure.keyvault.Secret("clawops-gateway-token", {
185
- resourceGroupName: rg.name,
186
- vaultName: kv.name,
187
- secretName: "gateway-token",
188
- properties: { value: gatewayToken.result }
189
- });
190
- }
191
- const resolvedIp = pulumi.output(publicIp.ipAddress).apply((ip) => ip ?? "");
192
- return {
193
- instanceId: vm.id,
194
- publicIp: resolvedIp,
195
- gatewayUrl: pulumi.interpolate`https://${resolvedIp}:${gatewayPort}`,
196
- sshHost: resolvedIp,
197
- sshPort: SSH_PORT,
198
- sshUser: "clawops",
199
- region: location,
200
- provisionedAt: (/* @__PURE__ */ new Date()).toISOString()
201
- };
202
- };
203
-
204
- // src/providers/azure/index.ts
205
- var INSTANCE_TYPE_MAP = {
206
- micro: "Standard_B1s",
207
- small: "Standard_B2s",
208
- medium: "Standard_B4ms",
209
- large: "Standard_B8ms",
210
- gpu: "Standard_NC6s_v3"
211
- };
212
- var azureAdapter = {
213
- name: "azure",
214
- get program() {
215
- return azureProgram;
216
- },
217
- getConnectionInfo(outputs) {
218
- return {
219
- host: String(outputs["sshHost"] ?? ""),
220
- port: Number(outputs["sshPort"] ?? 22),
221
- user: String(outputs["sshUser"] ?? "clawops"),
222
- privateKeyPath: String(outputs["privateKeyPath"] ?? ""),
223
- knownHostsPath: String(outputs["knownHostsPath"] ?? "")
224
- };
225
- },
226
- normalizeInstanceType(alias) {
227
- const mapped = INSTANCE_TYPE_MAP[alias];
228
- if (!mapped) throw new Error(`Unknown instance alias: ${alias}`);
229
- return mapped;
230
- },
231
- defaultRegion() {
232
- return "eastus";
233
- },
234
- stateBackendUrl(bucket) {
235
- return `azblob://${bucket}`;
236
- },
237
- async validateConfig() {
238
- const errors = [];
239
- const clientId = process2.env["AZURE_CLIENT_ID"];
240
- const tenantId = process2.env["AZURE_TENANT_ID"];
241
- const clientSecret = process2.env["AZURE_CLIENT_SECRET"];
242
- const federatedToken = process2.env["AZURE_FEDERATED_TOKEN_FILE"];
243
- const hasServicePrincipal = Boolean(clientId && tenantId && clientSecret);
244
- const hasOidc = Boolean(clientId && tenantId && federatedToken);
245
- if (!hasServicePrincipal && !hasOidc) {
246
- const onAzure = await checkImds();
247
- if (!onAzure) {
248
- errors.push(
249
- "No Azure credentials found. Set AZURE_CLIENT_ID + AZURE_TENANT_ID + AZURE_CLIENT_SECRET (service principal), or AZURE_CLIENT_ID + AZURE_TENANT_ID + AZURE_FEDERATED_TOKEN_FILE (OIDC), or run on an Azure VM with a managed identity."
250
- );
251
- }
252
- }
253
- return { ok: errors.length === 0, errors };
254
- }
255
- };
256
- async function checkImds() {
257
- try {
258
- const res = await fetch(
259
- "http://169.254.169.254/metadata/instance?api-version=2021-02-01",
260
- {
261
- headers: { Metadata: "true" },
262
- signal: AbortSignal.timeout(1e3)
263
- }
264
- );
265
- return res.ok;
266
- } catch {
267
- return false;
268
- }
269
- }
270
- var azure_default = azureAdapter;
271
- export {
272
- azure_default as default
273
- };
@@ -1,129 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- CONFIG_FILENAME,
4
- CONTAINER_UID,
5
- GATEWAY_PORT,
6
- STATE_DIR_HOST_LINUX,
7
- gatewayRunCommand
8
- } from "./chunk-6TIYVHPX.js";
9
-
10
- // src/providers/startup.ts
11
- function makeStartupScript(opts) {
12
- const {
13
- openclawVersion,
14
- os,
15
- bedrockEnabled = false,
16
- publishGateway = "loopback",
17
- gatewayPort = GATEWAY_PORT
18
- } = opts;
19
- const dockerDistro = os === "ubuntu" ? "ubuntu" : "debian";
20
- const bedrockEnvBlock = bedrockEnabled ? makeBedrockEnvBlock() : "";
21
- return `#!/bin/bash
22
- set -euo pipefail
23
-
24
- # \u2500\u2500 User setup \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
25
- id -u clawops &>/dev/null || useradd -m -s /bin/bash clawops
26
- mkdir -p /home/clawops/.ssh
27
- chmod 700 /home/clawops/.ssh
28
- chown clawops:clawops /home/clawops/.ssh
29
-
30
- # \u2500\u2500 Docker installation \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
31
- if ! command -v docker &>/dev/null; then
32
- export DEBIAN_FRONTEND=noninteractive
33
- apt-get update -q
34
- apt-get install -y -q ca-certificates curl gnupg lsb-release
35
- install -m 0755 -d /etc/apt/keyrings
36
- curl -fsSL https://download.docker.com/linux/${dockerDistro}/gpg \\
37
- -o /etc/apt/keyrings/docker.asc
38
- chmod a+r /etc/apt/keyrings/docker.asc
39
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \\
40
- https://download.docker.com/linux/${dockerDistro} $(lsb_release -cs) stable" \\
41
- > /etc/apt/sources.list.d/docker.list
42
- apt-get update -q
43
- apt-get install -y -q \\
44
- docker-ce \\
45
- docker-ce-cli \\
46
- containerd.io \\
47
- docker-buildx-plugin \\
48
- docker-compose-plugin
49
- systemctl enable --now docker
50
- fi
51
-
52
- usermod -aG docker clawops
53
-
54
- # \u2500\u2500 OpenClaw image \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\u2500\u2500\u2500\u2500
55
- OPENCLAW_VERSION="${openclawVersion}"
56
- docker pull ghcr.io/openclaw/openclaw:\${OPENCLAW_VERSION}
57
-
58
- # \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
59
- # OpenClaw refuses a non-loopback bind without auth, and in a container it always
60
- # binds 0.0.0.0. Without a token the gateway exits 78 and restart-loops.
61
- OPENCLAW_ENV_FILE=/home/clawops/openclaw.env
62
- if [ ! -s "\${OPENCLAW_ENV_FILE}" ]; then
63
- OPENCLAW_TOKEN=$(openssl rand -hex 32 2>/dev/null || head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \\n')
64
- printf 'OPENCLAW_GATEWAY_TOKEN=%s\\n' "\${OPENCLAW_TOKEN}" > "\${OPENCLAW_ENV_FILE}"
65
- chmod 600 "\${OPENCLAW_ENV_FILE}"
66
- chown clawops:clawops "\${OPENCLAW_ENV_FILE}"
67
- fi
68
-
69
- # \u2500\u2500 State directory \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\u2500\u2500\u2500
70
- # One directory holds config, the SQLite state and any plugins installed below.
71
- # Owned NUMERICALLY by the uid the container runs as: useradd clawops gets 1001 on
72
- # Ubuntu 24.04 (the ubuntu user already holds 1000), and a 1001-owned state dir makes the
73
- # gateway exit 1 with EACCES on its own SQLite WAL. There is no degraded mode.
74
- OPENCLAW_STATE_DIR=${STATE_DIR_HOST_LINUX}
75
- OPENCLAW_CONFIG="\${OPENCLAW_STATE_DIR}/${CONFIG_FILENAME}"
76
- mkdir -p "\${OPENCLAW_STATE_DIR}"
77
-
78
- # Migrate a pre-2.0 deployment: the config used to be a bare file in the service user's
79
- # home. Without this an in-place upgrade comes up with no configuration at all. Guarded on
80
- # the target being absent, so re-running provisioning never clobbers a later edit.
81
- OPENCLAW_LEGACY_CONFIG=/home/clawops/openclaw.json
82
- if [ -f "\${OPENCLAW_LEGACY_CONFIG}" ] && [ ! -f "\${OPENCLAW_CONFIG}" ]; then
83
- cp -p "\${OPENCLAW_LEGACY_CONFIG}" "\${OPENCLAW_CONFIG}"
84
- mv "\${OPENCLAW_LEGACY_CONFIG}" "\${OPENCLAW_LEGACY_CONFIG}.migrated"
85
- echo "clawops: migrated config from \${OPENCLAW_LEGACY_CONFIG}"
86
- OPENCLAW_MIGRATED=1
87
- fi
88
-
89
- # \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
90
- if [ ! -f "\${OPENCLAW_CONFIG}" ]; then
91
- cat > "\${OPENCLAW_CONFIG}" <<'OPENCLAWJSON'
92
- {"meta":{"lastTouchedVersion":"2026.9"},"gateway":{"mode":"local","port":${gatewayPort},"auth":{"mode":"token"}},"models":{},"channels":{}}
93
- OPENCLAWJSON
94
- fi
95
-
96
- # Numeric, and last, so it covers the config and anything migrated above.
97
- chown -R ${CONTAINER_UID}:${CONTAINER_UID} "\${OPENCLAW_STATE_DIR}"
98
-
99
- # A 1.x config has no gateway.mode, and clawops no longer passes --allow-unconfigured \u2014
100
- # so a migrated deployment would exit 78 with "existing config is missing gateway.mode".
101
- # Normalised with OpenClaw's own tooling rather than by editing JSON in shell: it is
102
- # schema-aware, writes atomically, and applies OpenClaw's internal config migrations at the
103
- # same time. Runs after the chown so the container can write.
104
- if [ "\${OPENCLAW_MIGRATED:-0}" = "1" ]; then
105
- docker run --rm -v "\${OPENCLAW_STATE_DIR}":/home/node/.openclaw \\
106
- ghcr.io/openclaw/openclaw:\${OPENCLAW_VERSION} \\
107
- openclaw config set gateway.mode local || \\
108
- echo "clawops: WARNING could not set gateway.mode; gateway may refuse to start" >&2
109
- fi
110
-
111
- # \u2500\u2500 Start OpenClaw container \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
112
- # Built by src/openclaw/runtime.ts, so this cannot drift from the restart paths.
113
- ${gatewayRunCommand({
114
- image: "ghcr.io/openclaw/openclaw:${OPENCLAW_VERSION}",
115
- stateDir: '"${OPENCLAW_STATE_DIR}"',
116
- envFilePath: '"${OPENCLAW_ENV_FILE}"',
117
- extraArgs: bedrockEnvBlock.trim(),
118
- publish: publishGateway,
119
- port: gatewayPort
120
- })}
121
- `;
122
- }
123
- function makeBedrockEnvBlock() {
124
- return ' -e AWS_DEFAULT_REGION=$( \\\n IMDS_TOKEN=$(curl -sf -X PUT \\\n "http://169.254.169.254/latest/api/token" \\\n -H "X-aws-ec2-metadata-token-ttl-seconds: 60") && \\\n curl -sf \\\n -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" \\\n "http://169.254.169.254/latest/meta-data/placement/region" \\\n || echo us-east-1) \\\n';
125
- }
126
-
127
- export {
128
- makeStartupScript
129
- };
@@ -1,114 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- readLocalState
4
- } from "./chunk-A2I76FTA.js";
5
- import {
6
- getConfigDir,
7
- requireConfig
8
- } from "./chunk-CX5SL5HP.js";
9
- import {
10
- UsageError
11
- } from "./chunk-KGXPLI7W.js";
12
-
13
- // src/cli/context.ts
14
- function buildContext(args) {
15
- const config = requireConfig();
16
- const stackName = typeof args.stack === "string" ? args.stack : config.defaults.stack;
17
- const providerName = typeof args.provider === "string" ? args.provider : config.stacks[stackName]?.provider ?? config.defaults.provider;
18
- const adapter = loadProvider(providerName);
19
- const localState = providerName === "local" ? readLocalState(stackName) : void 0;
20
- let stackCache = null;
21
- return {
22
- config,
23
- adapter,
24
- stackName,
25
- localState,
26
- async getStack() {
27
- if (providerName === "local") {
28
- throw new UsageError(
29
- "The local provider does not use Pulumi stacks. Use `clawops up` to bootstrap the host instead."
30
- );
31
- }
32
- if (stackCache) return stackCache;
33
- const stackConfig = config.stacks[stackName];
34
- if (!stackConfig) {
35
- throw new UsageError(
36
- `Stack "${stackName}" not found in config. Run \`clawops init\` or use \`--stack\` to specify a different stack.`
37
- );
38
- }
39
- const { getOrCreateStack } = await import("./automation-RULUSJBW.js");
40
- stackCache = await getOrCreateStack({
41
- stack: stackName,
42
- stateUrl: stackConfig.stateUrl,
43
- program: adapter.program,
44
- configDir: getConfigDir()
45
- });
46
- return stackCache;
47
- }
48
- };
49
- }
50
- function loadProvider(name) {
51
- return makeProviderProxy(name);
52
- }
53
- function makeProviderProxy(name) {
54
- let resolved = null;
55
- const resolve = async () => {
56
- if (resolved) return resolved;
57
- switch (name) {
58
- case "gcp": {
59
- const mod = await import("./gcp-2JBTD7ZM.js");
60
- resolved = mod.default;
61
- return resolved;
62
- }
63
- case "aws": {
64
- const mod = await import("./aws-AMON7DA7.js");
65
- resolved = mod.default;
66
- return resolved;
67
- }
68
- case "azure": {
69
- const mod = await import("./azure-T4G6OBJQ.js");
70
- resolved = mod.default;
71
- return resolved;
72
- }
73
- case "local": {
74
- const mod = await import("./local-DXBEVZ5C.js");
75
- resolved = mod.default;
76
- return resolved;
77
- }
78
- default:
79
- throw new UsageError(
80
- `Provider "${name}" is not yet supported. Supported providers: gcp, aws, azure, local`
81
- );
82
- }
83
- };
84
- return {
85
- name,
86
- get program() {
87
- return async () => {
88
- const adapter = await resolve();
89
- return adapter.program();
90
- };
91
- },
92
- getConnectionInfo: (outputs) => {
93
- if (!resolved) throw new UsageError("Provider not yet loaded. Call getStack() first.");
94
- return resolved.getConnectionInfo(outputs);
95
- },
96
- normalizeInstanceType: (alias) => {
97
- if (!resolved) throw new UsageError("Provider not yet loaded. Call getStack() first.");
98
- return resolved.normalizeInstanceType(alias);
99
- },
100
- defaultRegion: () => {
101
- if (!resolved) throw new UsageError("Provider not yet loaded. Call getStack() first.");
102
- return resolved.defaultRegion();
103
- },
104
- stateBackendUrl: (bucket) => {
105
- if (!resolved) throw new UsageError("Provider not yet loaded. Call getStack() first.");
106
- return resolved.stateBackendUrl(bucket);
107
- },
108
- validateConfig: () => resolve().then((a) => a.validateConfig())
109
- };
110
- }
111
-
112
- export {
113
- buildContext
114
- };
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- buildContext
4
- } from "./chunk-LU2V3LXA.js";
5
- import "./chunk-A2I76FTA.js";
6
- import "./chunk-CX5SL5HP.js";
7
- import "./chunk-KGXPLI7W.js";
8
- export {
9
- buildContext
10
- };