@1claw/cli 0.34.7 → 0.35.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 +66 -5
- package/dist/bin/1claw.js +0 -0
- package/dist/src/commands/containers.d.ts +3 -0
- package/dist/src/commands/containers.d.ts.map +1 -0
- package/dist/src/commands/containers.js +130 -0
- package/dist/src/commands/containers.js.map +1 -0
- package/dist/src/commands/daemon.js +18 -9
- package/dist/src/commands/daemon.js.map +1 -1
- package/dist/src/commands/deploy.d.ts +3 -0
- package/dist/src/commands/deploy.d.ts.map +1 -0
- package/dist/src/commands/deploy.js +158 -0
- package/dist/src/commands/deploy.js.map +1 -0
- package/dist/src/commands/eject.d.ts +3 -0
- package/dist/src/commands/eject.d.ts.map +1 -0
- package/dist/src/commands/eject.js +84 -0
- package/dist/src/commands/eject.js.map +1 -0
- package/dist/src/commands/init.d.ts +3 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +490 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/local.d.ts.map +1 -1
- package/dist/src/commands/local.js +61 -14
- package/dist/src/commands/local.js.map +1 -1
- package/dist/src/commands/publish.d.ts +3 -0
- package/dist/src/commands/publish.d.ts.map +1 -0
- package/dist/src/commands/publish.js +153 -0
- package/dist/src/commands/publish.js.map +1 -0
- package/dist/src/deploy/google-cloud/main.tf +74 -0
- package/dist/src/deploy/google-cloud/outputs.tf +9 -0
- package/dist/src/deploy/google-cloud/variables.tf +44 -0
- package/dist/src/docker/base/Dockerfile +34 -0
- package/dist/src/docker/base/chat-ui/index.html +110 -0
- package/dist/src/docker/base/chat-ui/server.js +233 -0
- package/dist/src/docker/base/entrypoint.sh +61 -0
- package/dist/src/docker/base/healthcheck.sh +2 -0
- package/dist/src/docker/compose.yaml +20 -0
- package/dist/src/docker/templates/Dockerfile.tmpl +7 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/container-config.d.ts +43 -0
- package/dist/src/lib/container-config.d.ts.map +1 -0
- package/dist/src/lib/container-config.js +98 -0
- package/dist/src/lib/container-config.js.map +1 -0
- package/dist/src/lib/daemon-control.d.ts +10 -0
- package/dist/src/lib/daemon-control.d.ts.map +1 -0
- package/dist/src/lib/daemon-control.js +58 -0
- package/dist/src/lib/daemon-control.js.map +1 -0
- package/dist/src/lib/docker-client.d.ts +58 -0
- package/dist/src/lib/docker-client.d.ts.map +1 -0
- package/dist/src/lib/docker-client.js +193 -0
- package/dist/src/lib/docker-client.js.map +1 -0
- package/dist/src/lib/image-build.d.ts +30 -0
- package/dist/src/lib/image-build.d.ts.map +1 -0
- package/dist/src/lib/image-build.js +74 -0
- package/dist/src/lib/image-build.js.map +1 -0
- package/dist/src/lib/paths.d.ts +14 -0
- package/dist/src/lib/paths.d.ts.map +1 -0
- package/dist/src/lib/paths.js +38 -0
- package/dist/src/lib/paths.js.map +1 -0
- package/dist/src/modules/ampersend/config.json +8 -0
- package/dist/src/modules/ampersend/module.yaml +32 -0
- package/dist/src/modules/ampersend/startup.sh +4 -0
- package/dist/src/modules/elizaos/config.json +7 -0
- package/dist/src/modules/elizaos/module.yaml +30 -0
- package/dist/src/modules/elizaos/startup.sh +3 -0
- package/dist/src/modules/langchain/module.yaml +30 -0
- package/dist/src/modules/langchain/startup.sh +3 -0
- package/dist/src/modules/onchain/module.yaml +28 -0
- package/dist/src/modules/onchain/startup.sh +3 -0
- package/dist/src/modules/registry.d.ts +48 -0
- package/dist/src/modules/registry.d.ts.map +1 -0
- package/dist/src/modules/registry.js +201 -0
- package/dist/src/modules/registry.js.map +1 -0
- package/dist/src/modules/scaffold-agent/module.yaml +30 -0
- package/dist/src/modules/scaffold-agent/startup.sh +3 -0
- package/package.json +4 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuEpC,eAAO,MAAM,WAAW,SAoBlB,CAAC"}
|
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import inquirer from "inquirer";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import { api } from "../client.js";
|
|
6
|
+
import { getToken } from "../config.js";
|
|
7
|
+
import { loginWithDevice } from "../auth.js";
|
|
8
|
+
import { printSuccess, printError, printWarning, printInfo, printKeyValue, printTable, } from "../output.js";
|
|
9
|
+
import { vaultExists, createVault, loadVault, saveVault, addSecret, } from "../local-vault.js";
|
|
10
|
+
import { loadPolicy, savePolicy, setSecretPolicy, } from "../local-policy.js";
|
|
11
|
+
import { dockerAvailable, dockerDaemonError, dockerRun, dockerContainerStatus, dockerLogs, } from "../lib/docker-client.js";
|
|
12
|
+
import { ensureBaseImage, buildModuleImage, DEFAULT_BASE_IMAGE, } from "../lib/image-build.js";
|
|
13
|
+
import { listModules, resolveModules, } from "../modules/registry.js";
|
|
14
|
+
import { generateContainerName, isValidContainerName, sanitizeName, loadContainerState, saveContainerState, findAvailablePort, MANAGED_LABEL, } from "../lib/container-config.js";
|
|
15
|
+
import { daemonSocketPath, daemonHealthy, startDaemonDetached, } from "../lib/daemon-control.js";
|
|
16
|
+
export const initCommand = new Command("init")
|
|
17
|
+
.description("Initialize a secure agent runtime in a Docker container")
|
|
18
|
+
.option("--docker [image]", "Run in Docker container (default: 1claw/agent:stable)")
|
|
19
|
+
.option("--module <names...>", "Add modules (comma-separated or repeated): ampersend, onchain, langchain, elizaos, scaffold-agent")
|
|
20
|
+
.option("--list-modules", "List all available modules and exit")
|
|
21
|
+
.option("--port <port>", "Chat UI port", "3000")
|
|
22
|
+
.option("--name <name>", "Container name (default: auto-generated)")
|
|
23
|
+
.option("--local", "Fully offline — no cloud provisioning")
|
|
24
|
+
.option("--agent-key <key>", "Use an existing agent key (skip provisioning)")
|
|
25
|
+
.option("--detach", "Run the container in the background")
|
|
26
|
+
.action(async (opts) => {
|
|
27
|
+
try {
|
|
28
|
+
await initAction(opts);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
function parseModuleNames(input) {
|
|
36
|
+
if (!input)
|
|
37
|
+
return [];
|
|
38
|
+
const names = [];
|
|
39
|
+
for (const entry of input) {
|
|
40
|
+
for (const part of entry.split(",")) {
|
|
41
|
+
const trimmed = part.trim();
|
|
42
|
+
if (trimmed)
|
|
43
|
+
names.push(trimmed);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return [...new Set(names)];
|
|
47
|
+
}
|
|
48
|
+
function printModuleList() {
|
|
49
|
+
const modules = listModules();
|
|
50
|
+
console.log();
|
|
51
|
+
console.log(chalk.bold(" Available modules:"));
|
|
52
|
+
console.log();
|
|
53
|
+
if (modules.length === 0) {
|
|
54
|
+
printInfo("No modules bundled.");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
printTable(modules.map((m) => ({
|
|
58
|
+
name: m.name,
|
|
59
|
+
description: m.description.replace(/\s+/g, " ").slice(0, 60),
|
|
60
|
+
author: m.author,
|
|
61
|
+
})), [
|
|
62
|
+
{ key: "name", header: "Module", width: 16 },
|
|
63
|
+
{ key: "description", header: "Description", width: 62 },
|
|
64
|
+
{ key: "author", header: "Author" },
|
|
65
|
+
]);
|
|
66
|
+
console.log();
|
|
67
|
+
console.log(chalk.dim(" Usage: 1claw init --docker --module=ampersend --module=onchain\n" +
|
|
68
|
+
" or: 1claw init --docker --module=ampersend,onchain"));
|
|
69
|
+
console.log();
|
|
70
|
+
}
|
|
71
|
+
async function provisionCloudResources(containerName) {
|
|
72
|
+
const sid = sanitizeName(containerName);
|
|
73
|
+
const agentSpinner = ora("Provisioning agent...").start();
|
|
74
|
+
let agentId;
|
|
75
|
+
let apiKey;
|
|
76
|
+
try {
|
|
77
|
+
const res = await api("/agents", {
|
|
78
|
+
method: "POST",
|
|
79
|
+
body: {
|
|
80
|
+
name: `docker-agent-${sid}`.slice(0, 60),
|
|
81
|
+
description: "Created by `1claw init --docker`",
|
|
82
|
+
shroud_enabled: true,
|
|
83
|
+
intents_api_enabled: true,
|
|
84
|
+
auth_method: "api_key",
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
agentId = "agent" in res ? res.agent.id : res.id;
|
|
88
|
+
if (!res.api_key) {
|
|
89
|
+
agentSpinner.fail("Agent created but no API key returned.");
|
|
90
|
+
throw new Error("No agent API key returned by the API.");
|
|
91
|
+
}
|
|
92
|
+
apiKey = res.api_key;
|
|
93
|
+
agentSpinner.succeed(`Agent provisioned (${agentId.slice(0, 8)}…)`);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
agentSpinner.fail("Failed to provision agent.");
|
|
97
|
+
throw err;
|
|
98
|
+
}
|
|
99
|
+
const vaultSpinner = ora("Creating vault...").start();
|
|
100
|
+
let vaultId;
|
|
101
|
+
let vaultName;
|
|
102
|
+
try {
|
|
103
|
+
const vault = await api("/vaults", {
|
|
104
|
+
method: "POST",
|
|
105
|
+
body: {
|
|
106
|
+
name: `docker-vault-${sid}`.slice(0, 60),
|
|
107
|
+
description: "Created by `1claw init --docker`",
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
vaultId = vault.id;
|
|
111
|
+
vaultName = vault.name;
|
|
112
|
+
vaultSpinner.succeed(`Vault created (${vaultName})`);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
vaultSpinner.fail("Failed to create vault.");
|
|
116
|
+
throw err;
|
|
117
|
+
}
|
|
118
|
+
const policySpinner = ora("Binding vault and granting read policy...").start();
|
|
119
|
+
try {
|
|
120
|
+
await api(`/agents/${agentId}`, {
|
|
121
|
+
method: "PATCH",
|
|
122
|
+
body: { vault_ids: [vaultId] },
|
|
123
|
+
});
|
|
124
|
+
await api(`/vaults/${vaultId}/policies`, {
|
|
125
|
+
method: "POST",
|
|
126
|
+
body: {
|
|
127
|
+
principal_type: "agent",
|
|
128
|
+
principal_id: agentId,
|
|
129
|
+
secret_path_pattern: "secrets/*",
|
|
130
|
+
permissions: ["read"],
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
policySpinner.succeed("Vault bound; read policy on secrets/* granted.");
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
policySpinner.fail("Failed to bind vault / create policy.");
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
|
+
return { agentId, apiKey, vaultId, vaultName };
|
|
140
|
+
}
|
|
141
|
+
async function resolvePassphrase(confirm) {
|
|
142
|
+
if (process.env.ONECLAW_VAULT_PASSPHRASE) {
|
|
143
|
+
return process.env.ONECLAW_VAULT_PASSPHRASE;
|
|
144
|
+
}
|
|
145
|
+
const { passphrase } = await inquirer.prompt([
|
|
146
|
+
{
|
|
147
|
+
type: "password",
|
|
148
|
+
name: "passphrase",
|
|
149
|
+
message: "Local vault passphrase:",
|
|
150
|
+
mask: "*",
|
|
151
|
+
validate: (v) => v.length >= 8 ? true : "Passphrase must be at least 8 characters",
|
|
152
|
+
},
|
|
153
|
+
]);
|
|
154
|
+
if (confirm) {
|
|
155
|
+
const { confirmed } = await inquirer.prompt([
|
|
156
|
+
{
|
|
157
|
+
type: "password",
|
|
158
|
+
name: "confirmed",
|
|
159
|
+
message: "Confirm passphrase:",
|
|
160
|
+
mask: "*",
|
|
161
|
+
},
|
|
162
|
+
]);
|
|
163
|
+
if (passphrase !== confirmed) {
|
|
164
|
+
throw new Error("Passphrases do not match.");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return passphrase;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Ensure a local vault exists, optionally store the agent key + daemon policy,
|
|
171
|
+
* and make sure the daemon is running so the container can reach it.
|
|
172
|
+
*/
|
|
173
|
+
async function ensureDaemonRunning(opts) {
|
|
174
|
+
const socketPath = daemonSocketPath();
|
|
175
|
+
const alreadyRunning = await daemonHealthy(socketPath);
|
|
176
|
+
// We need the passphrase to create/unlock the vault for key storage and/or
|
|
177
|
+
// to start the daemon. If the daemon is already running and we have nothing
|
|
178
|
+
// to store, we can skip vault work entirely.
|
|
179
|
+
const needVaultWrite = !!opts.storeKey;
|
|
180
|
+
const needStart = !alreadyRunning;
|
|
181
|
+
if (!needVaultWrite && !needStart) {
|
|
182
|
+
return socketPath;
|
|
183
|
+
}
|
|
184
|
+
const creatingVault = !vaultExists();
|
|
185
|
+
let passphrase;
|
|
186
|
+
if (needVaultWrite || needStart) {
|
|
187
|
+
if (creatingVault) {
|
|
188
|
+
printInfo("No local vault found — creating one for the daemon.");
|
|
189
|
+
passphrase = await resolvePassphrase(true);
|
|
190
|
+
createVault(passphrase);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
passphrase = await resolvePassphrase(false);
|
|
194
|
+
// Verify the passphrase up front so we fail with a clear message
|
|
195
|
+
// instead of an opaque "daemon did not become ready in time".
|
|
196
|
+
try {
|
|
197
|
+
loadVault(passphrase);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
throw new Error("Wrong passphrase for the existing local vault.\n" +
|
|
201
|
+
" • If you mistyped it, re-run and enter the correct passphrase.\n" +
|
|
202
|
+
" • If you've forgotten it, reset the vault with: 1claw local destroy --force\n" +
|
|
203
|
+
" (this permanently deletes the old local vault and its secrets), then re-run.");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (needVaultWrite && passphrase) {
|
|
208
|
+
let vault;
|
|
209
|
+
try {
|
|
210
|
+
vault = loadVault(passphrase);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
throw new Error("Wrong passphrase or corrupted local vault.");
|
|
214
|
+
}
|
|
215
|
+
addSecret(vault, opts.storeKey.localVaultPath, opts.storeKey.apiKey, "api_key");
|
|
216
|
+
saveVault(vault, passphrase);
|
|
217
|
+
// Allow the daemon to inject this key toward the 1Claw API only.
|
|
218
|
+
const policy = loadPolicy();
|
|
219
|
+
setSecretPolicy(policy, opts.storeKey.localVaultPath, {
|
|
220
|
+
allowed_hosts: ["api.1claw.xyz", "*.1claw.xyz"],
|
|
221
|
+
inject_as: "bearer",
|
|
222
|
+
});
|
|
223
|
+
savePolicy(policy);
|
|
224
|
+
}
|
|
225
|
+
if (needStart) {
|
|
226
|
+
if (!passphrase)
|
|
227
|
+
passphrase = await resolvePassphrase(false);
|
|
228
|
+
const spinner = ora("Starting local daemon...").start();
|
|
229
|
+
const ok = await startDaemonDetached(passphrase, socketPath);
|
|
230
|
+
if (!ok) {
|
|
231
|
+
spinner.fail("Daemon did not become ready in time.");
|
|
232
|
+
throw new Error("Failed to start the daemon.\n" +
|
|
233
|
+
" • Check status: 1claw daemon status\n" +
|
|
234
|
+
" • Start it manually (shows errors): 1claw daemon start\n" +
|
|
235
|
+
" • Stop a stuck daemon: 1claw daemon stop\n" +
|
|
236
|
+
" • Forgot the vault passphrase? Reset it: 1claw local destroy --force");
|
|
237
|
+
}
|
|
238
|
+
spinner.succeed(`Daemon running on ${socketPath}`);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
printInfo(`Reusing running daemon at ${socketPath}`);
|
|
242
|
+
}
|
|
243
|
+
return socketPath;
|
|
244
|
+
}
|
|
245
|
+
async function waitForHealthy(port, timeoutMs = 30000) {
|
|
246
|
+
const deadline = Date.now() + timeoutMs;
|
|
247
|
+
const url = `http://localhost:${port}/health`;
|
|
248
|
+
while (Date.now() < deadline) {
|
|
249
|
+
try {
|
|
250
|
+
const res = await fetch(url);
|
|
251
|
+
if (res.ok)
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// not up yet
|
|
256
|
+
}
|
|
257
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
258
|
+
}
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
async function initAction(opts) {
|
|
262
|
+
if (opts.listModules) {
|
|
263
|
+
printModuleList();
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
console.log();
|
|
267
|
+
console.log(chalk.bold(" 1Claw — Secure Agent Runtime"));
|
|
268
|
+
console.log();
|
|
269
|
+
// ── Step 1: Preflight ────────────────────────────────────────────────
|
|
270
|
+
if (!(await dockerAvailable())) {
|
|
271
|
+
const reason = await dockerDaemonError();
|
|
272
|
+
throw new Error(reason ??
|
|
273
|
+
"Docker is required. Install Docker Desktop: https://docs.docker.com/get-docker/");
|
|
274
|
+
}
|
|
275
|
+
// ── Modules ──────────────────────────────────────────────────────────
|
|
276
|
+
const moduleNames = parseModuleNames(opts.module);
|
|
277
|
+
let modules = [];
|
|
278
|
+
if (moduleNames.length) {
|
|
279
|
+
modules = resolveModules(moduleNames);
|
|
280
|
+
printInfo(`Modules: ${modules.map((m) => m.name).join(", ")}` +
|
|
281
|
+
(modules.length > moduleNames.length
|
|
282
|
+
? chalk.dim(" (incl. dependencies)")
|
|
283
|
+
: ""));
|
|
284
|
+
}
|
|
285
|
+
// ── Container identity ───────────────────────────────────────────────
|
|
286
|
+
const containerName = opts.name ?? generateContainerName();
|
|
287
|
+
if (!isValidContainerName(containerName)) {
|
|
288
|
+
throw new Error(`Invalid container name "${containerName}". Use letters, digits, _, ., -.`);
|
|
289
|
+
}
|
|
290
|
+
if (loadContainerState(containerName)) {
|
|
291
|
+
throw new Error(`A container named "${containerName}" already exists in state. ` +
|
|
292
|
+
`Use --name to choose another, or remove it with \`1claw containers rm ${containerName}\`.`);
|
|
293
|
+
}
|
|
294
|
+
const existing = await dockerContainerStatus(containerName);
|
|
295
|
+
if (existing.exists) {
|
|
296
|
+
throw new Error(`A Docker container named "${containerName}" already exists. ` +
|
|
297
|
+
`Remove it (\`docker rm -f ${containerName}\`) or choose --name.`);
|
|
298
|
+
}
|
|
299
|
+
// ── Step 2/3: Auth + provisioning ────────────────────────────────────
|
|
300
|
+
let agentId = null;
|
|
301
|
+
let vaultId = null;
|
|
302
|
+
let agentApiKey = opts.agentKey ?? null;
|
|
303
|
+
let localVaultPath = null;
|
|
304
|
+
if (opts.local) {
|
|
305
|
+
printInfo("Local mode — no cloud account or provisioning.");
|
|
306
|
+
}
|
|
307
|
+
else if (agentApiKey) {
|
|
308
|
+
printInfo("Using provided --agent-key (skipping provisioning).");
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
if (!getToken()) {
|
|
312
|
+
printInfo("You need to log in to provision cloud resources.");
|
|
313
|
+
const { shouldLogin } = await inquirer.prompt([
|
|
314
|
+
{
|
|
315
|
+
type: "confirm",
|
|
316
|
+
name: "shouldLogin",
|
|
317
|
+
message: "Log in now? (choose No to run offline with --local)",
|
|
318
|
+
default: true,
|
|
319
|
+
},
|
|
320
|
+
]);
|
|
321
|
+
if (!shouldLogin) {
|
|
322
|
+
throw new Error("Not authenticated. Re-run with --local for offline mode, or `1claw login`.");
|
|
323
|
+
}
|
|
324
|
+
const auth = await loginWithDevice();
|
|
325
|
+
if (!auth)
|
|
326
|
+
throw new Error("Login failed.");
|
|
327
|
+
}
|
|
328
|
+
const result = await provisionCloudResources(containerName);
|
|
329
|
+
agentId = result.agentId;
|
|
330
|
+
vaultId = result.vaultId;
|
|
331
|
+
agentApiKey = result.apiKey;
|
|
332
|
+
}
|
|
333
|
+
// ── Step 4/5: Store key + start daemon ───────────────────────────────
|
|
334
|
+
if (agentApiKey && !opts.local) {
|
|
335
|
+
localVaultPath = `__docker/${sanitizeName(containerName)}/agent-key`;
|
|
336
|
+
}
|
|
337
|
+
else if (agentApiKey && opts.local) {
|
|
338
|
+
// Even in local mode, an explicitly provided key is stored for the daemon.
|
|
339
|
+
localVaultPath = `__docker/${sanitizeName(containerName)}/agent-key`;
|
|
340
|
+
}
|
|
341
|
+
const socketPath = await ensureDaemonRunning({
|
|
342
|
+
storeKey: agentApiKey && localVaultPath
|
|
343
|
+
? { localVaultPath, apiKey: agentApiKey }
|
|
344
|
+
: undefined,
|
|
345
|
+
});
|
|
346
|
+
// ── Step 6/7: Build or pull image ────────────────────────────────────
|
|
347
|
+
const baseImage = typeof opts.docker === "string" && opts.docker.length
|
|
348
|
+
? opts.docker
|
|
349
|
+
: DEFAULT_BASE_IMAGE;
|
|
350
|
+
let imageToRun = baseImage;
|
|
351
|
+
if (modules.length === 0) {
|
|
352
|
+
const spinner = ora(`Preparing image ${baseImage}...`).start();
|
|
353
|
+
try {
|
|
354
|
+
await ensureBaseImage(baseImage, (line) => {
|
|
355
|
+
spinner.text = chalk.dim(line.slice(0, 70));
|
|
356
|
+
});
|
|
357
|
+
spinner.succeed(`Image ready: ${baseImage}`);
|
|
358
|
+
}
|
|
359
|
+
catch (err) {
|
|
360
|
+
spinner.fail("Failed to prepare image.");
|
|
361
|
+
throw err;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
const baseSpinner = ora("Ensuring base image...").start();
|
|
366
|
+
try {
|
|
367
|
+
await ensureBaseImage(baseImage, (line) => {
|
|
368
|
+
baseSpinner.text = chalk.dim(line.slice(0, 70));
|
|
369
|
+
});
|
|
370
|
+
baseSpinner.succeed("Base image ready.");
|
|
371
|
+
}
|
|
372
|
+
catch (err) {
|
|
373
|
+
baseSpinner.fail("Failed to prepare base image.");
|
|
374
|
+
throw err;
|
|
375
|
+
}
|
|
376
|
+
const buildSpinner = ora("Building module image...").start();
|
|
377
|
+
try {
|
|
378
|
+
const { tag } = await buildModuleImage(baseImage, modules, (line) => {
|
|
379
|
+
buildSpinner.text = chalk.dim(line.slice(0, 70));
|
|
380
|
+
});
|
|
381
|
+
imageToRun = tag;
|
|
382
|
+
buildSpinner.succeed(`Built ${tag}`);
|
|
383
|
+
}
|
|
384
|
+
catch (err) {
|
|
385
|
+
buildSpinner.fail("Module image build failed.");
|
|
386
|
+
throw err;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
// ── Step 8: Run container ────────────────────────────────────────────
|
|
390
|
+
const requestedPort = parseInt(opts.port, 10) || 3000;
|
|
391
|
+
const port = await findAvailablePort(requestedPort);
|
|
392
|
+
if (port !== requestedPort) {
|
|
393
|
+
printWarning(`Port ${requestedPort} busy — using ${port}.`);
|
|
394
|
+
}
|
|
395
|
+
const env = {
|
|
396
|
+
ONECLAW_LOCAL_VAULT: "true",
|
|
397
|
+
ONECLAW_DAEMON_SOCKET: "/run/1claw/daemon.sock",
|
|
398
|
+
ONECLAW_CONTAINER_MODULES: modules.map((m) => m.name).join(","),
|
|
399
|
+
};
|
|
400
|
+
if (agentId)
|
|
401
|
+
env.ONECLAW_AGENT_ID = agentId;
|
|
402
|
+
const runSpinner = ora(`Starting container ${containerName}...`).start();
|
|
403
|
+
let containerId;
|
|
404
|
+
try {
|
|
405
|
+
containerId = await dockerRun({
|
|
406
|
+
image: imageToRun,
|
|
407
|
+
name: containerName,
|
|
408
|
+
ports: { [String(port)]: "3000" },
|
|
409
|
+
volumes: { [socketPath]: "/run/1claw/daemon.sock:ro" },
|
|
410
|
+
env,
|
|
411
|
+
detach: true,
|
|
412
|
+
restart: "unless-stopped",
|
|
413
|
+
labels: { [MANAGED_LABEL]: "true", "1claw.name": containerName },
|
|
414
|
+
});
|
|
415
|
+
runSpinner.succeed(`Container started (${containerId.slice(0, 12)})`);
|
|
416
|
+
}
|
|
417
|
+
catch (err) {
|
|
418
|
+
runSpinner.fail("Failed to start container.");
|
|
419
|
+
throw err;
|
|
420
|
+
}
|
|
421
|
+
// ── Step 9: Wait healthy + summary ───────────────────────────────────
|
|
422
|
+
const healthSpinner = ora("Waiting for the agent to become healthy...").start();
|
|
423
|
+
const healthy = await waitForHealthy(port);
|
|
424
|
+
if (healthy) {
|
|
425
|
+
healthSpinner.succeed("Agent is healthy.");
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
healthSpinner.warn("Health check timed out (the container may still be starting).");
|
|
429
|
+
}
|
|
430
|
+
const state = {
|
|
431
|
+
containerName,
|
|
432
|
+
containerId,
|
|
433
|
+
agentId,
|
|
434
|
+
vaultId,
|
|
435
|
+
image: baseImage,
|
|
436
|
+
modules: modules.map((m) => m.name),
|
|
437
|
+
port,
|
|
438
|
+
createdAt: new Date().toISOString(),
|
|
439
|
+
localVaultPath,
|
|
440
|
+
customImage: null,
|
|
441
|
+
mode: "local",
|
|
442
|
+
};
|
|
443
|
+
saveContainerState(state);
|
|
444
|
+
console.log();
|
|
445
|
+
printSuccess("Agent runtime is up.");
|
|
446
|
+
printKeyValue([
|
|
447
|
+
["Chat UI", chalk.cyan(`http://localhost:${port}`)],
|
|
448
|
+
["Container", containerName],
|
|
449
|
+
["Agent ID", agentId ?? chalk.dim("none (local)")],
|
|
450
|
+
["Vault", vaultId ?? chalk.dim("none (local)")],
|
|
451
|
+
["Modules", modules.map((m) => m.name).join(", ") || chalk.dim("none")],
|
|
452
|
+
["Image", imageToRun],
|
|
453
|
+
["Shroud", agentId ? "enabled" : chalk.dim("n/a")],
|
|
454
|
+
["Key injection", chalk.green("daemon (container never sees the key)")],
|
|
455
|
+
]);
|
|
456
|
+
console.log();
|
|
457
|
+
if (modules.some((m) => m.required_secrets.length)) {
|
|
458
|
+
printInfo("Some modules expect secrets in your vault:");
|
|
459
|
+
for (const m of modules) {
|
|
460
|
+
for (const s of m.required_secrets) {
|
|
461
|
+
console.log(` ${chalk.dim("•")} ${s.path} ${chalk.dim(s.optional ? "(optional)" : "(required)")} — ${s.description}`);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
console.log();
|
|
465
|
+
}
|
|
466
|
+
printInfo(`Manage it: 1claw containers logs ${containerName} | 1claw containers stop ${containerName}`);
|
|
467
|
+
console.log();
|
|
468
|
+
// Open the browser (best-effort) unless detached/headless.
|
|
469
|
+
try {
|
|
470
|
+
const open = (await import("open")).default;
|
|
471
|
+
await open(`http://localhost:${port}`);
|
|
472
|
+
}
|
|
473
|
+
catch {
|
|
474
|
+
// ignore — headless or no browser
|
|
475
|
+
}
|
|
476
|
+
if (!opts.detach) {
|
|
477
|
+
printInfo("Streaming container logs (Ctrl+C to detach; container keeps running).");
|
|
478
|
+
console.log();
|
|
479
|
+
const logs = dockerLogs(containerName, true);
|
|
480
|
+
await new Promise((resolve) => {
|
|
481
|
+
const stop = () => {
|
|
482
|
+
logs.kill();
|
|
483
|
+
resolve();
|
|
484
|
+
};
|
|
485
|
+
process.on("SIGINT", stop);
|
|
486
|
+
logs.on("close", () => resolve());
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/commands/local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/commands/local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8FpC,eAAO,MAAM,YAAY,SAExB,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
2
|
+
import { readFileSync, existsSync, unlinkSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
3
5
|
import chalk from "chalk";
|
|
4
6
|
import inquirer from "inquirer";
|
|
5
7
|
import ora from "ora";
|
|
@@ -444,29 +446,74 @@ localCommand
|
|
|
444
446
|
}
|
|
445
447
|
});
|
|
446
448
|
// ── destroy ──────────────────────────────────────────────
|
|
449
|
+
/**
|
|
450
|
+
* Best-effort: stop a running local daemon and clean up its socket/PID so a
|
|
451
|
+
* stale process isn't left holding the vault we're about to delete. Does NOT
|
|
452
|
+
* require the passphrase — this is the recovery path for a forgotten one.
|
|
453
|
+
*/
|
|
454
|
+
function stopDaemonForReset() {
|
|
455
|
+
const configDir = process.env.ONECLAW_CONFIG_DIR || join(homedir(), ".config", "1claw");
|
|
456
|
+
const pidFile = join(configDir, "daemon.pid");
|
|
457
|
+
const socketPath = process.env.ONECLAW_DAEMON_SOCKET || join(configDir, "daemon.sock");
|
|
458
|
+
if (existsSync(pidFile)) {
|
|
459
|
+
try {
|
|
460
|
+
const pid = parseInt(readFileSync(pidFile, "utf-8").trim(), 10);
|
|
461
|
+
if (pid) {
|
|
462
|
+
try {
|
|
463
|
+
process.kill(pid, "SIGTERM");
|
|
464
|
+
printInfo(`Stopped running daemon (PID ${pid}).`);
|
|
465
|
+
}
|
|
466
|
+
catch {
|
|
467
|
+
/* already gone */
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
catch {
|
|
472
|
+
/* unreadable pid file */
|
|
473
|
+
}
|
|
474
|
+
try {
|
|
475
|
+
unlinkSync(pidFile);
|
|
476
|
+
}
|
|
477
|
+
catch { /* ok */ }
|
|
478
|
+
}
|
|
479
|
+
try {
|
|
480
|
+
if (existsSync(socketPath))
|
|
481
|
+
unlinkSync(socketPath);
|
|
482
|
+
}
|
|
483
|
+
catch { /* ok */ }
|
|
484
|
+
}
|
|
447
485
|
localCommand
|
|
448
486
|
.command("destroy")
|
|
449
|
-
.
|
|
450
|
-
.
|
|
487
|
+
.alias("reset")
|
|
488
|
+
.description("Permanently delete the local vault (recovery for a forgotten passphrase — no passphrase required)")
|
|
489
|
+
.option("-f, --force", "Skip the confirmation prompt")
|
|
490
|
+
.action(async (opts) => {
|
|
451
491
|
try {
|
|
452
492
|
if (!vaultExists()) {
|
|
453
493
|
printInfo("No local vault to destroy.");
|
|
494
|
+
// Still clean up any stale daemon socket/PID.
|
|
495
|
+
stopDaemonForReset();
|
|
454
496
|
return;
|
|
455
497
|
}
|
|
456
|
-
|
|
457
|
-
{
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
498
|
+
if (!opts.force) {
|
|
499
|
+
const { confirm } = await inquirer.prompt([
|
|
500
|
+
{
|
|
501
|
+
type: "confirm",
|
|
502
|
+
name: "confirm",
|
|
503
|
+
message: chalk.red("This will permanently delete your local vault and ALL secrets in it. This cannot be undone. Continue?"),
|
|
504
|
+
default: false,
|
|
505
|
+
},
|
|
506
|
+
]);
|
|
507
|
+
if (!confirm) {
|
|
508
|
+
printInfo("Cancelled.");
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
467
511
|
}
|
|
512
|
+
// Stop any daemon holding the old vault before deleting it.
|
|
513
|
+
stopDaemonForReset();
|
|
468
514
|
deleteVault();
|
|
469
515
|
printSuccess("Local vault destroyed.");
|
|
516
|
+
printInfo("Create a fresh one with `1claw local init`, or just re-run `1claw init --docker --local`.");
|
|
470
517
|
}
|
|
471
518
|
catch (err) {
|
|
472
519
|
if (err instanceof Error)
|