@synap-core/cli 0.9.5 → 1.0.0
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/dist/commands/finish.d.ts +3 -1
- package/dist/commands/finish.js +45 -10
- package/dist/commands/finish.js.map +1 -1
- package/dist/commands/init.js +54 -40
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/openclaw.d.ts +23 -0
- package/dist/commands/openclaw.js +487 -0
- package/dist/commands/openclaw.js.map +1 -0
- package/dist/commands/status.js +53 -24
- package/dist/commands/status.js.map +1 -1
- package/dist/index.js +54 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/hardening.js +19 -8
- package/dist/lib/hardening.js.map +1 -1
- package/dist/lib/openclaw.js +5 -1
- package/dist/lib/openclaw.js.map +1 -1
- package/dist/lib/pod.d.ts +2 -2
- package/dist/lib/pod.js +8 -8
- package/dist/lib/pod.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* synap openclaw
|
|
3
|
+
*
|
|
4
|
+
* Everything you need to access, configure, and connect OpenClaw
|
|
5
|
+
* after installation. Subcommands:
|
|
6
|
+
*
|
|
7
|
+
* synap openclaw — overview: gateway status, AI key, next steps
|
|
8
|
+
* synap openclaw connect — show MCP client configs for Claude Desktop, Cursor, etc.
|
|
9
|
+
* synap openclaw configure — set AI provider key interactively
|
|
10
|
+
* synap openclaw logs — tail container logs
|
|
11
|
+
* synap openclaw restart — restart the container
|
|
12
|
+
*/
|
|
13
|
+
import chalk from "chalk";
|
|
14
|
+
import { execSync } from "child_process";
|
|
15
|
+
import prompts from "prompts";
|
|
16
|
+
import fs from "node:fs";
|
|
17
|
+
import { log, banner } from "../utils/logger.js";
|
|
18
|
+
import { detectOpenClaw } from "../lib/openclaw.js";
|
|
19
|
+
import { findSynapDeployDir } from "../lib/pod.js";
|
|
20
|
+
// ─── Overview ────────────────────────────────────────────────────────────────
|
|
21
|
+
export async function openclawOverview() {
|
|
22
|
+
banner();
|
|
23
|
+
const oc = detectOpenClaw();
|
|
24
|
+
if (!oc.found) {
|
|
25
|
+
log.warn("OpenClaw is not running.");
|
|
26
|
+
log.blank();
|
|
27
|
+
log.dim("Start it: docker compose --profile openclaw up -d openclaw");
|
|
28
|
+
log.dim("Or run: synap init");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// ── Gateway status ──────────────────────────────────────────────────────
|
|
32
|
+
log.heading("Gateway");
|
|
33
|
+
const gatewayPort = oc.gatewayPort ?? 18789;
|
|
34
|
+
if (oc.gatewayRunning) {
|
|
35
|
+
log.success(`Running on port ${gatewayPort}`);
|
|
36
|
+
log.info(`MCP endpoint: ${chalk.cyan(`http://localhost:${gatewayPort}/mcp`)}`);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
log.warn(`Port ${gatewayPort} not responding — OpenClaw may still be starting`);
|
|
40
|
+
log.dim("Give it a minute, then: synap openclaw");
|
|
41
|
+
}
|
|
42
|
+
if (oc.runtime === "docker") {
|
|
43
|
+
log.dim(`Container: ${oc.containerName ?? "openclaw"}`);
|
|
44
|
+
}
|
|
45
|
+
if (oc.version)
|
|
46
|
+
log.dim(`Version: ${oc.version}`);
|
|
47
|
+
// ── AI provider ─────────────────────────────────────────────────────────
|
|
48
|
+
log.heading("AI Provider");
|
|
49
|
+
const apiKeyStatus = getAiKeyStatus();
|
|
50
|
+
if (apiKeyStatus.configured) {
|
|
51
|
+
log.success(`${apiKeyStatus.provider} key configured`);
|
|
52
|
+
log.dim(`Model: ${apiKeyStatus.model ?? "default"}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
log.warn("No AI API key configured — OpenClaw cannot process requests");
|
|
56
|
+
log.blank();
|
|
57
|
+
if (oc.runtime === "docker") {
|
|
58
|
+
log.dim("Set your key: synap openclaw configure");
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
log.dim("Set your key: openclaw configure (or: synap openclaw configure)");
|
|
62
|
+
}
|
|
63
|
+
log.blank();
|
|
64
|
+
log.dim("Supported: Anthropic (Claude), OpenAI, Google, or Synap IS");
|
|
65
|
+
}
|
|
66
|
+
// ── Skill ───────────────────────────────────────────────────────────────
|
|
67
|
+
log.heading("Synap Skill");
|
|
68
|
+
const skillInstalled = checkSkillInstalled(oc);
|
|
69
|
+
if (skillInstalled) {
|
|
70
|
+
log.success("synap skill installed");
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
log.warn("Synap skill not installed");
|
|
74
|
+
const containerName = oc.containerName ?? "openclaw";
|
|
75
|
+
log.dim(oc.runtime === "docker"
|
|
76
|
+
? `Install: docker exec ${containerName} openclaw skills install synap`
|
|
77
|
+
: "Install: openclaw skills install synap");
|
|
78
|
+
}
|
|
79
|
+
// ── Dashboard ────────────────────────────────────────────────────────────
|
|
80
|
+
log.heading("Dashboard");
|
|
81
|
+
if (oc.runtime === "docker") {
|
|
82
|
+
const containerName = oc.containerName ?? "openclaw";
|
|
83
|
+
log.info(`Web UI: ${chalk.cyan(`http://localhost:${oc.gatewayPort ?? 18789}`)}`);
|
|
84
|
+
log.dim("If on a remote server, tunnel first:");
|
|
85
|
+
log.dim(` ssh -N -L 18789:localhost:18789 user@your-server`);
|
|
86
|
+
log.dim(` Then open: http://localhost:18789`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
log.info(`Web UI: ${chalk.cyan(`http://localhost:${oc.gatewayPort ?? 18789}`)}`);
|
|
90
|
+
log.dim("Open: openclaw dashboard — or just open the URL above");
|
|
91
|
+
}
|
|
92
|
+
// ── How to connect ───────────────────────────────────────────────────────
|
|
93
|
+
log.heading("AI Client (MCP)");
|
|
94
|
+
log.info("Connect Claude Desktop, Cursor, or Windsurf:");
|
|
95
|
+
log.blank();
|
|
96
|
+
log.dim(" Claude Desktop synap openclaw connect --client claude");
|
|
97
|
+
log.dim(" Cursor synap openclaw connect --client cursor");
|
|
98
|
+
log.dim(" Windsurf synap openclaw connect --client windsurf");
|
|
99
|
+
log.blank();
|
|
100
|
+
// ── Next steps ───────────────────────────────────────────────────────────
|
|
101
|
+
log.heading("Next Steps");
|
|
102
|
+
if (!apiKeyStatus.configured) {
|
|
103
|
+
log.info("1. Set your AI key: synap openclaw configure");
|
|
104
|
+
log.info("2. Connect a client: synap openclaw connect");
|
|
105
|
+
}
|
|
106
|
+
else if (!skillInstalled) {
|
|
107
|
+
const containerName = oc.containerName ?? "openclaw";
|
|
108
|
+
log.info(oc.runtime === "docker"
|
|
109
|
+
? `1. Install skill: docker exec ${containerName} openclaw skills install synap`
|
|
110
|
+
: "1. Install skill: openclaw skills install synap");
|
|
111
|
+
log.info("2. Connect a client: synap openclaw connect");
|
|
112
|
+
}
|
|
113
|
+
else if (!oc.gatewayRunning) {
|
|
114
|
+
log.info("1. Wait for gateway (it may still be starting)");
|
|
115
|
+
log.info("2. Connect a client: synap openclaw connect");
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
log.success("Everything looks good.");
|
|
119
|
+
log.info("Connect an AI client: synap openclaw connect");
|
|
120
|
+
}
|
|
121
|
+
log.blank();
|
|
122
|
+
}
|
|
123
|
+
// ─── Connect: show MCP client configs ────────────────────────────────────────
|
|
124
|
+
export async function openclawConnect(opts) {
|
|
125
|
+
const oc = detectOpenClaw();
|
|
126
|
+
const gatewayPort = oc.gatewayPort ?? 18789;
|
|
127
|
+
const isDocker = oc.runtime === "docker";
|
|
128
|
+
// OpenClaw MCP is stdio-based — clients run `openclaw mcp serve` as a local process
|
|
129
|
+
// which connects to the gateway over WebSocket.
|
|
130
|
+
// For Docker/remote setups the gateway is at ws://localhost:<port> after SSH tunnel.
|
|
131
|
+
const client = opts.client?.toLowerCase();
|
|
132
|
+
if (!client || client === "claude") {
|
|
133
|
+
printMcpConfig("Claude Desktop", gatewayPort, isDocker, "claude");
|
|
134
|
+
}
|
|
135
|
+
if (!client || client === "cursor") {
|
|
136
|
+
printMcpConfig("Cursor", gatewayPort, isDocker, "cursor");
|
|
137
|
+
}
|
|
138
|
+
if (!client || client === "windsurf") {
|
|
139
|
+
printMcpConfig("Windsurf", gatewayPort, isDocker, "windsurf");
|
|
140
|
+
}
|
|
141
|
+
if (client && !["claude", "cursor", "windsurf"].includes(client)) {
|
|
142
|
+
log.warn(`Unknown client "${client}". Showing generic config.`);
|
|
143
|
+
printMcpConfig("MCP Client", gatewayPort, isDocker, "generic");
|
|
144
|
+
}
|
|
145
|
+
if (isDocker) {
|
|
146
|
+
log.blank();
|
|
147
|
+
log.info("Remote server? Tunnel the gateway port first:");
|
|
148
|
+
log.dim(" ssh -N -L 18789:localhost:18789 user@your-server");
|
|
149
|
+
log.dim(" Then use the configs above (they point to localhost:18789)");
|
|
150
|
+
log.blank();
|
|
151
|
+
log.dim("openclaw must be installed locally: npm i -g openclaw");
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function printMcpConfig(label, gatewayPort, isRemote, client) {
|
|
155
|
+
log.heading(label);
|
|
156
|
+
// MCP config: stdio command that connects to the local (or tunneled) gateway
|
|
157
|
+
const args = isRemote
|
|
158
|
+
? ["mcp", "serve", "--url", `ws://localhost:${gatewayPort}`]
|
|
159
|
+
: ["mcp", "serve"];
|
|
160
|
+
const config = JSON.stringify({ mcpServers: { openclaw: { command: "openclaw", args } } }, null, 2);
|
|
161
|
+
const paths = {
|
|
162
|
+
claude: "macOS: ~/Library/Application Support/Claude/claude_desktop_config.json",
|
|
163
|
+
cursor: "~/.cursor/mcp.json",
|
|
164
|
+
windsurf: "~/.windsurf/mcp.json",
|
|
165
|
+
generic: "<your MCP client config file>",
|
|
166
|
+
};
|
|
167
|
+
log.dim(`Config file: ${paths[client]}`);
|
|
168
|
+
log.blank();
|
|
169
|
+
console.log(chalk.cyan(config));
|
|
170
|
+
log.blank();
|
|
171
|
+
if (client === "claude") {
|
|
172
|
+
log.dim("After saving: quit and reopen Claude Desktop");
|
|
173
|
+
log.dim('Ask: "What tools do you have?" — OpenClaw tools should appear');
|
|
174
|
+
}
|
|
175
|
+
if (client === "cursor") {
|
|
176
|
+
log.dim("After saving: Cmd+Shift+P → MCP: Restart Servers");
|
|
177
|
+
}
|
|
178
|
+
log.blank();
|
|
179
|
+
}
|
|
180
|
+
// ─── Dashboard ───────────────────────────────────────────────────────────────
|
|
181
|
+
export function openclawDashboard() {
|
|
182
|
+
const oc = detectOpenClaw();
|
|
183
|
+
const port = oc.gatewayPort ?? 18789;
|
|
184
|
+
const url = `http://localhost:${port}`;
|
|
185
|
+
if (oc.runtime === "docker") {
|
|
186
|
+
// On a remote server the browser can't open — give SSH tunnel instructions
|
|
187
|
+
const isRemoteServer = !process.env.DISPLAY && process.platform === "linux";
|
|
188
|
+
if (isRemoteServer) {
|
|
189
|
+
log.info(`OpenClaw dashboard: ${chalk.cyan(url)}`);
|
|
190
|
+
log.blank();
|
|
191
|
+
log.info("You're on a remote server. Tunnel the port to your laptop:");
|
|
192
|
+
log.blank();
|
|
193
|
+
console.log(chalk.cyan(` ssh -N -L ${port}:localhost:${port} user@$(hostname)`));
|
|
194
|
+
log.blank();
|
|
195
|
+
log.dim(`Then open ${url} in your browser.`);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// Local Docker — just open it
|
|
199
|
+
log.info(`Opening ${chalk.cyan(url)} ...`);
|
|
200
|
+
try {
|
|
201
|
+
const open = process.platform === "darwin" ? "open" : "xdg-open";
|
|
202
|
+
execSync(`${open} ${url}`, { stdio: "ignore" });
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
log.dim(`Open manually: ${url}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
// Local install — use openclaw's own command
|
|
211
|
+
log.info(`Opening dashboard...`);
|
|
212
|
+
try {
|
|
213
|
+
execSync("openclaw dashboard", { stdio: "inherit", timeout: 5000 });
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// Fallback: open URL directly
|
|
217
|
+
try {
|
|
218
|
+
const open = process.platform === "darwin" ? "open" : "xdg-open";
|
|
219
|
+
execSync(`${open} ${url}`, { stdio: "ignore" });
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
log.info(`Dashboard: ${chalk.cyan(url)}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// ─── Configure: set AI provider key ──────────────────────────────────────────
|
|
228
|
+
export async function openclawConfigure() {
|
|
229
|
+
banner();
|
|
230
|
+
log.heading("Configure AI Provider");
|
|
231
|
+
const deployDir = findSynapDeployDir();
|
|
232
|
+
// Show current status
|
|
233
|
+
const current = getAiKeyStatus();
|
|
234
|
+
if (current.configured) {
|
|
235
|
+
log.success(`Currently using: ${current.provider}`);
|
|
236
|
+
log.dim(`Model: ${current.model ?? "default"}`);
|
|
237
|
+
log.blank();
|
|
238
|
+
}
|
|
239
|
+
const { provider } = await prompts({
|
|
240
|
+
type: "select",
|
|
241
|
+
name: "provider",
|
|
242
|
+
message: "Which AI provider?",
|
|
243
|
+
choices: [
|
|
244
|
+
{
|
|
245
|
+
title: "Anthropic (Claude)",
|
|
246
|
+
description: "claude-sonnet-4-6 — best quality, recommended",
|
|
247
|
+
value: "anthropic",
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
title: "OpenAI (GPT-4o)",
|
|
251
|
+
value: "openai",
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
title: "Google (Gemini)",
|
|
255
|
+
value: "google",
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
title: "Synap IS (via pod)",
|
|
259
|
+
description: "Uses your pod AI — no external key needed",
|
|
260
|
+
value: "synap",
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
});
|
|
264
|
+
if (!provider)
|
|
265
|
+
return;
|
|
266
|
+
if (provider === "synap") {
|
|
267
|
+
log.blank();
|
|
268
|
+
log.info("Synap IS uses your pod's AI subscription.");
|
|
269
|
+
log.dim("Make sure IS is provisioned: synap finish");
|
|
270
|
+
log.dim("Then OpenClaw will use your pod URL as the AI endpoint.");
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const envKey = provider === "anthropic"
|
|
274
|
+
? "ANTHROPIC_API_KEY"
|
|
275
|
+
: provider === "openai"
|
|
276
|
+
? "OPENAI_API_KEY"
|
|
277
|
+
: "GEMINI_API_KEY";
|
|
278
|
+
const modelDefault = provider === "anthropic"
|
|
279
|
+
? "anthropic/claude-sonnet-4-6"
|
|
280
|
+
: provider === "openai"
|
|
281
|
+
? "openai/gpt-4o"
|
|
282
|
+
: "google/gemini-2.0-flash";
|
|
283
|
+
const { apiKey } = await prompts({
|
|
284
|
+
type: "password",
|
|
285
|
+
name: "apiKey",
|
|
286
|
+
message: `${envKey}:`,
|
|
287
|
+
});
|
|
288
|
+
if (!apiKey)
|
|
289
|
+
return;
|
|
290
|
+
const { model } = await prompts({
|
|
291
|
+
type: "text",
|
|
292
|
+
name: "model",
|
|
293
|
+
message: "Model (leave blank for default):",
|
|
294
|
+
initial: modelDefault,
|
|
295
|
+
});
|
|
296
|
+
if (deployDir) {
|
|
297
|
+
// Write to .env file
|
|
298
|
+
const envFile = `${deployDir}/.env`;
|
|
299
|
+
writeEnvVar(envFile, envKey, apiKey);
|
|
300
|
+
if (model && model !== modelDefault) {
|
|
301
|
+
writeEnvVar(envFile, "OPENCLAW_MODEL", model);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
writeEnvVar(envFile, "OPENCLAW_MODEL", modelDefault);
|
|
305
|
+
}
|
|
306
|
+
log.blank();
|
|
307
|
+
log.success(`${envKey} written to ${deployDir}/.env`);
|
|
308
|
+
// Restart container to pick up new env vars
|
|
309
|
+
const oc = detectOpenClaw();
|
|
310
|
+
const containerName = oc.containerName ?? "openclaw";
|
|
311
|
+
const { doRestart } = await prompts({
|
|
312
|
+
type: "confirm",
|
|
313
|
+
name: "doRestart",
|
|
314
|
+
message: `Restart ${containerName} to apply?`,
|
|
315
|
+
initial: true,
|
|
316
|
+
});
|
|
317
|
+
if (doRestart) {
|
|
318
|
+
try {
|
|
319
|
+
log.info(`Restarting ${containerName}...`);
|
|
320
|
+
execSync(`docker restart ${containerName}`, { stdio: "pipe", timeout: 30000 });
|
|
321
|
+
log.success("Restarted. Give it 30s to come back up.");
|
|
322
|
+
log.dim(`Check: synap openclaw`);
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
log.warn("Restart failed — restart manually:");
|
|
326
|
+
log.dim(` docker restart ${containerName}`);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
// No deploy dir — show env export instructions
|
|
332
|
+
log.blank();
|
|
333
|
+
log.warn("Could not find deploy directory. Set the key manually:");
|
|
334
|
+
log.blank();
|
|
335
|
+
console.log(chalk.cyan(` export ${envKey}="${apiKey}"`));
|
|
336
|
+
if (model) {
|
|
337
|
+
console.log(chalk.cyan(` export OPENCLAW_MODEL="${model}"`));
|
|
338
|
+
}
|
|
339
|
+
log.blank();
|
|
340
|
+
log.dim("Or add to your pod .env file, then: docker restart openclaw");
|
|
341
|
+
}
|
|
342
|
+
log.blank();
|
|
343
|
+
}
|
|
344
|
+
// ─── Logs: tail container output ─────────────────────────────────────────────
|
|
345
|
+
export function openclawLogs(opts) {
|
|
346
|
+
const oc = detectOpenClaw();
|
|
347
|
+
if (oc.runtime !== "docker") {
|
|
348
|
+
log.warn("Log tailing only available for Docker runtime.");
|
|
349
|
+
log.dim("OpenClaw logs: check your process manager or journald");
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const containerName = oc.containerName ?? "openclaw";
|
|
353
|
+
const lines = opts.lines ?? 50;
|
|
354
|
+
const flag = opts.follow ? "-f" : `--tail ${lines}`;
|
|
355
|
+
try {
|
|
356
|
+
log.dim(`docker logs ${containerName} ${flag}`);
|
|
357
|
+
log.blank();
|
|
358
|
+
execSync(`docker logs ${containerName} ${flag}`, { stdio: "inherit", timeout: opts.follow ? 0 : 30000 });
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
log.error(`Could not get logs for container "${containerName}"`);
|
|
362
|
+
log.dim(`Try: docker logs ${containerName} --tail 50`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// ─── Restart ─────────────────────────────────────────────────────────────────
|
|
366
|
+
export async function openclawRestart() {
|
|
367
|
+
const oc = detectOpenClaw();
|
|
368
|
+
if (oc.runtime !== "docker") {
|
|
369
|
+
log.warn("Restart only available for Docker runtime.");
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const containerName = oc.containerName ?? "openclaw";
|
|
373
|
+
const { confirm } = await prompts({
|
|
374
|
+
type: "confirm",
|
|
375
|
+
name: "confirm",
|
|
376
|
+
message: `Restart ${containerName}?`,
|
|
377
|
+
initial: true,
|
|
378
|
+
});
|
|
379
|
+
if (!confirm)
|
|
380
|
+
return;
|
|
381
|
+
try {
|
|
382
|
+
execSync(`docker restart ${containerName}`, { stdio: "pipe", timeout: 30000 });
|
|
383
|
+
log.success(`${containerName} restarted — give it ~30s to come back up`);
|
|
384
|
+
log.dim("Check: synap openclaw");
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
log.error("Restart failed");
|
|
388
|
+
log.dim(`Try: docker restart ${containerName}`);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function getAiKeyStatus() {
|
|
392
|
+
// Check deploy dir .env first (most accurate for Docker deployments)
|
|
393
|
+
const deployDir = findSynapDeployDir();
|
|
394
|
+
if (deployDir) {
|
|
395
|
+
const envFile = `${deployDir}/.env`;
|
|
396
|
+
try {
|
|
397
|
+
const envContent = fs.readFileSync(envFile, "utf-8");
|
|
398
|
+
const vars = parseEnvFile(envContent);
|
|
399
|
+
if (vars.ANTHROPIC_API_KEY) {
|
|
400
|
+
return { configured: true, provider: "Anthropic", model: vars.OPENCLAW_MODEL };
|
|
401
|
+
}
|
|
402
|
+
if (vars.OPENAI_API_KEY) {
|
|
403
|
+
return { configured: true, provider: "OpenAI", model: vars.OPENCLAW_MODEL };
|
|
404
|
+
}
|
|
405
|
+
if (vars.GEMINI_API_KEY) {
|
|
406
|
+
return { configured: true, provider: "Google", model: vars.OPENCLAW_MODEL };
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
catch {
|
|
410
|
+
// unreadable
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// Fallback: check live container env (via docker inspect)
|
|
414
|
+
const oc = detectOpenClaw();
|
|
415
|
+
if (oc.runtime === "docker") {
|
|
416
|
+
try {
|
|
417
|
+
const containerName = oc.containerName ?? "openclaw";
|
|
418
|
+
const raw = execSync(`docker inspect --format '{{range .Config.Env}}{{.}}\\n{{end}}' ${containerName} 2>/dev/null`, { encoding: "utf-8", timeout: 5000 });
|
|
419
|
+
const envLines = raw.split("\\n").filter(Boolean);
|
|
420
|
+
const env = {};
|
|
421
|
+
for (const line of envLines) {
|
|
422
|
+
const idx = line.indexOf("=");
|
|
423
|
+
if (idx > 0)
|
|
424
|
+
env[line.slice(0, idx)] = line.slice(idx + 1);
|
|
425
|
+
}
|
|
426
|
+
if (env.ANTHROPIC_API_KEY)
|
|
427
|
+
return { configured: true, provider: "Anthropic", model: env.OPENCLAW_MODEL };
|
|
428
|
+
if (env.OPENAI_API_KEY)
|
|
429
|
+
return { configured: true, provider: "OpenAI", model: env.OPENCLAW_MODEL };
|
|
430
|
+
if (env.GEMINI_API_KEY)
|
|
431
|
+
return { configured: true, provider: "Google", model: env.OPENCLAW_MODEL };
|
|
432
|
+
}
|
|
433
|
+
catch {
|
|
434
|
+
// docker not available
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return { configured: false };
|
|
438
|
+
}
|
|
439
|
+
function checkSkillInstalled(oc) {
|
|
440
|
+
if (!oc.found)
|
|
441
|
+
return false;
|
|
442
|
+
if (oc.runtime === "docker") {
|
|
443
|
+
try {
|
|
444
|
+
const containerName = oc.containerName ?? "openclaw";
|
|
445
|
+
const out = execSync(`docker exec ${containerName} openclaw skills list 2>/dev/null`, { encoding: "utf-8", timeout: 10000 });
|
|
446
|
+
return /synap/i.test(out);
|
|
447
|
+
}
|
|
448
|
+
catch {
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
// Local install — check skills directory
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
function writeEnvVar(envFile, key, value) {
|
|
456
|
+
let content = "";
|
|
457
|
+
try {
|
|
458
|
+
content = fs.existsSync(envFile) ? fs.readFileSync(envFile, "utf-8") : "";
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
// start fresh
|
|
462
|
+
}
|
|
463
|
+
const regex = new RegExp(`^${key}=.*`, "m");
|
|
464
|
+
const line = `${key}=${value}`;
|
|
465
|
+
content = regex.test(content)
|
|
466
|
+
? content.replace(regex, line)
|
|
467
|
+
: content.endsWith("\n") || content === ""
|
|
468
|
+
? content + line + "\n"
|
|
469
|
+
: content + "\n" + line + "\n";
|
|
470
|
+
fs.writeFileSync(envFile, content, { mode: 0o600 });
|
|
471
|
+
}
|
|
472
|
+
function parseEnvFile(content) {
|
|
473
|
+
const result = {};
|
|
474
|
+
for (const line of content.split("\n")) {
|
|
475
|
+
const trimmed = line.trim();
|
|
476
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
477
|
+
continue;
|
|
478
|
+
const idx = trimmed.indexOf("=");
|
|
479
|
+
if (idx > 0) {
|
|
480
|
+
const key = trimmed.slice(0, idx);
|
|
481
|
+
const val = trimmed.slice(idx + 1).replace(/^["']|["']$/g, "");
|
|
482
|
+
result[key] = val;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return result;
|
|
486
|
+
}
|
|
487
|
+
//# sourceMappingURL=openclaw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/commands/openclaw.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/status.js
CHANGED
|
@@ -103,23 +103,39 @@ export async function status() {
|
|
|
103
103
|
// Hoist creds so all sections can use it
|
|
104
104
|
const creds = getStoredToken();
|
|
105
105
|
// Auth status
|
|
106
|
+
// Strategy: show what we know locally first (email from stored creds),
|
|
107
|
+
// then validate with the server. If the server is unreachable, trust the
|
|
108
|
+
// local token as long as it hasn't locally expired. Only prompt to re-login
|
|
109
|
+
// when the server explicitly rejects it (401) or the local expiry has passed.
|
|
106
110
|
log.heading("Account");
|
|
107
111
|
let loggedIn = false;
|
|
108
112
|
if (creds) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
// Always show local identity immediately — don't wait for server
|
|
114
|
+
log.success(`Logged in as ${chalk.bold(creds.email)}`);
|
|
115
|
+
log.dim(`User ID: ${creds.userId}`);
|
|
116
|
+
if (isTokenLocallyExpired(creds)) {
|
|
117
|
+
// Local expiry passed — validate against server to confirm
|
|
118
|
+
const authStatus = await isLoggedIn();
|
|
119
|
+
if (authStatus.valid) {
|
|
120
|
+
loggedIn = true;
|
|
121
|
+
log.dim(`Token refreshed (valid until ${new Date(creds.expiresAt).toLocaleDateString()})`);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
log.warn("Session expired — run: synap login");
|
|
125
|
+
log.dim("On a server without a browser? Use: synap login --token <token>");
|
|
126
|
+
}
|
|
119
127
|
}
|
|
120
128
|
else {
|
|
121
|
-
|
|
122
|
-
|
|
129
|
+
// Token is locally fresh — validate in background but don't block on failure
|
|
130
|
+
loggedIn = true;
|
|
131
|
+
const authStatus = await isLoggedIn().catch(() => ({ valid: false }));
|
|
132
|
+
if (authStatus.valid) {
|
|
133
|
+
log.dim(`Token valid until ${new Date(creds.expiresAt).toLocaleDateString()}`);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// CP unreachable but token is fresh — trust it, just note it
|
|
137
|
+
log.dim(`Token fresh (CP unreachable — cached credentials in use)`);
|
|
138
|
+
}
|
|
123
139
|
}
|
|
124
140
|
}
|
|
125
141
|
else {
|
|
@@ -175,28 +191,41 @@ export async function status() {
|
|
|
175
191
|
}
|
|
176
192
|
}
|
|
177
193
|
else if (localConfig?.podId && creds) {
|
|
178
|
-
// No Docker container visible — check CP remote
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
log.dim(
|
|
194
|
+
// No Docker container visible here — check CP for remote provisioning state
|
|
195
|
+
const remoteStatus = await getOpenClawRemoteStatus(creds.token, localConfig.podId).catch(() => null);
|
|
196
|
+
if (remoteStatus === null) {
|
|
197
|
+
// CP unreachable — show what we know locally
|
|
198
|
+
log.dim(`Pod ID: ${localConfig.podId}`);
|
|
199
|
+
log.dim("CP unreachable — cannot check remote OpenClaw state");
|
|
200
|
+
log.dim("If on the pod server, run: docker ps | grep openclaw");
|
|
201
|
+
}
|
|
202
|
+
else if (remoteStatus.status === "not_provisioned") {
|
|
203
|
+
log.dim("Not provisioned on pod server. Run: synap init");
|
|
183
204
|
}
|
|
184
205
|
else if (remoteStatus.status === "provisioning") {
|
|
185
|
-
log.info(`
|
|
186
|
-
log.dim("Check
|
|
206
|
+
log.info(`Pod server: ${chalk.yellow("provisioning")} — still starting up`);
|
|
207
|
+
log.dim("Check: docker logs openclaw --tail 30");
|
|
208
|
+
log.dim("Once ready: synap finish");
|
|
187
209
|
}
|
|
188
210
|
else if (remoteStatus.status === "running") {
|
|
189
|
-
log.success(`
|
|
190
|
-
|
|
211
|
+
log.success(`Pod server: ${chalk.green("running")}`);
|
|
212
|
+
if (remoteStatus.url)
|
|
213
|
+
log.dim(`URL: ${remoteStatus.url}`);
|
|
214
|
+
log.dim("Run synap finish to install the skill");
|
|
191
215
|
}
|
|
192
216
|
else if (remoteStatus.status === "error") {
|
|
193
|
-
log.warn(`
|
|
217
|
+
log.warn(`Pod server: ${chalk.red("error")} — provisioning failed`);
|
|
194
218
|
log.dim("Re-run: synap init");
|
|
195
219
|
}
|
|
196
220
|
}
|
|
197
221
|
else {
|
|
198
|
-
log.dim("Not detected
|
|
199
|
-
|
|
222
|
+
log.dim("Not detected locally");
|
|
223
|
+
if (!localConfig) {
|
|
224
|
+
log.dim("Run synap init to connect to a pod");
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
log.dim("Run synap init to set up OpenClaw");
|
|
228
|
+
}
|
|
200
229
|
}
|
|
201
230
|
}
|
|
202
231
|
// Pod status
|