@silicaclaw/cli 1.0.0-beta.15 → 1.0.0-beta.17
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/package.json +1 -1
- package/scripts/silicaclaw-cli.mjs +31 -15
- package/scripts/silicaclaw-gateway.mjs +96 -7
package/package.json
CHANGED
|
@@ -87,31 +87,28 @@ function showUpdateGuide(current, latest, beta) {
|
|
|
87
87
|
console.log("Update available.");
|
|
88
88
|
}
|
|
89
89
|
console.log("");
|
|
90
|
-
console.log("
|
|
91
|
-
console.log("1)
|
|
92
|
-
console.log("
|
|
93
|
-
console.log("
|
|
94
|
-
console.log("
|
|
95
|
-
console.log("");
|
|
96
|
-
console.log("
|
|
97
|
-
console.log(" alias silicaclaw='npx -y @silicaclaw/cli@beta'");
|
|
98
|
-
console.log(" silicaclaw version");
|
|
90
|
+
console.log("Quick next commands:");
|
|
91
|
+
console.log("1) Start local gateway");
|
|
92
|
+
console.log(" silicaclaw gateway start --mode=local");
|
|
93
|
+
console.log("2) Check gateway status");
|
|
94
|
+
console.log(" silicaclaw gateway status");
|
|
95
|
+
console.log("3) npx one-shot (no alias/global install)");
|
|
96
|
+
console.log(" npx -y @silicaclaw/cli@beta gateway start --mode=local");
|
|
99
97
|
console.log("");
|
|
98
|
+
|
|
100
99
|
const writableGlobal = canWriteGlobalPrefix();
|
|
101
100
|
if (!npxRuntime && writableGlobal) {
|
|
102
|
-
console.log("
|
|
101
|
+
console.log("Optional global install:");
|
|
103
102
|
console.log(" npm i -g @silicaclaw/cli@beta");
|
|
104
103
|
console.log(" silicaclaw version");
|
|
105
104
|
console.log("");
|
|
106
105
|
} else if (!npxRuntime) {
|
|
107
|
-
console.log("Global install skipped:
|
|
108
|
-
console.log("Use npx or alias mode above.");
|
|
106
|
+
console.log("Global install skipped: npm global directory is not writable (likely EACCES).");
|
|
109
107
|
console.log("");
|
|
110
108
|
}
|
|
111
109
|
if (npxRuntime) {
|
|
112
|
-
console.log("Detected npx runtime
|
|
113
|
-
console.log("If `silicaclaw
|
|
114
|
-
console.log("alias silicaclaw='npx -y @silicaclaw/cli@beta'");
|
|
110
|
+
console.log("Detected npx runtime.");
|
|
111
|
+
console.log("If `silicaclaw` is unavailable in this shell, use the npx one-shot command above.");
|
|
115
112
|
}
|
|
116
113
|
}
|
|
117
114
|
|
|
@@ -146,6 +143,11 @@ Usage:
|
|
|
146
143
|
silicaclaw onboard
|
|
147
144
|
silicaclaw connect
|
|
148
145
|
silicaclaw update
|
|
146
|
+
silicaclaw start [--mode=local|lan|global-preview]
|
|
147
|
+
silicaclaw stop
|
|
148
|
+
silicaclaw restart [--mode=local|lan|global-preview]
|
|
149
|
+
silicaclaw status
|
|
150
|
+
silicaclaw logs [local-console|signaling]
|
|
149
151
|
silicaclaw gateway <start|stop|restart|status|logs>
|
|
150
152
|
silicaclaw local-console
|
|
151
153
|
silicaclaw explorer
|
|
@@ -158,6 +160,11 @@ Commands:
|
|
|
158
160
|
onboard Interactive step-by-step onboarding (recommended)
|
|
159
161
|
connect Cross-network connect wizard (global-preview first)
|
|
160
162
|
update Check latest npm version and show upgrade commands
|
|
163
|
+
start Start gateway-managed background services
|
|
164
|
+
stop Stop gateway-managed background services
|
|
165
|
+
restart Restart gateway-managed background services
|
|
166
|
+
status Show gateway-managed service status
|
|
167
|
+
logs Show gateway-managed service logs
|
|
161
168
|
gateway Manage background services (start/stop/restart/status/logs)
|
|
162
169
|
local-console Start local console (http://localhost:4310)
|
|
163
170
|
explorer Start public explorer (http://localhost:4311)
|
|
@@ -191,6 +198,15 @@ switch (cmd) {
|
|
|
191
198
|
cwd: process.cwd(),
|
|
192
199
|
});
|
|
193
200
|
break;
|
|
201
|
+
case "start":
|
|
202
|
+
case "stop":
|
|
203
|
+
case "restart":
|
|
204
|
+
case "status":
|
|
205
|
+
case "logs":
|
|
206
|
+
run("node", [resolve(ROOT_DIR, "scripts", "silicaclaw-gateway.mjs"), cmd, ...process.argv.slice(3)], {
|
|
207
|
+
cwd: process.cwd(),
|
|
208
|
+
});
|
|
209
|
+
break;
|
|
194
210
|
case "local-console":
|
|
195
211
|
case "console":
|
|
196
212
|
run("npm", ["run", "local-console"]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { spawn } from "node:child_process";
|
|
3
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
4
4
|
import { existsSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -13,6 +13,25 @@ const ROOT_DIR = resolve(__dirname, "..");
|
|
|
13
13
|
const argv = process.argv.slice(2);
|
|
14
14
|
const cmd = String(argv[0] || "help").toLowerCase();
|
|
15
15
|
|
|
16
|
+
function readJson(file) {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(String(readFileSync(file, "utf8")));
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isSilicaClawDir(dir) {
|
|
25
|
+
const pkgPath = join(dir, "package.json");
|
|
26
|
+
if (!existsSync(pkgPath)) return false;
|
|
27
|
+
const pkg = readJson(pkgPath);
|
|
28
|
+
if (!pkg || typeof pkg !== "object") return false;
|
|
29
|
+
const name = String(pkg.name || "");
|
|
30
|
+
if (name === "@silicaclaw/cli" || name === "silicaclaw") return true;
|
|
31
|
+
const scripts = pkg.scripts && typeof pkg.scripts === "object" ? pkg.scripts : {};
|
|
32
|
+
return Boolean(scripts.gateway || scripts["local-console"] || scripts["public-explorer"]);
|
|
33
|
+
}
|
|
34
|
+
|
|
16
35
|
function parseFlag(name, fallback = "") {
|
|
17
36
|
const prefix = `--${name}=`;
|
|
18
37
|
for (const item of argv) {
|
|
@@ -27,17 +46,17 @@ function hasFlag(name) {
|
|
|
27
46
|
|
|
28
47
|
function detectAppDir() {
|
|
29
48
|
const envDir = process.env.SILICACLAW_APP_DIR;
|
|
30
|
-
if (envDir &&
|
|
49
|
+
if (envDir && isSilicaClawDir(envDir)) {
|
|
31
50
|
return resolve(envDir);
|
|
32
51
|
}
|
|
33
52
|
|
|
34
53
|
const cwd = process.cwd();
|
|
35
|
-
if (
|
|
54
|
+
if (isSilicaClawDir(cwd)) {
|
|
36
55
|
return resolve(cwd);
|
|
37
56
|
}
|
|
38
57
|
|
|
39
58
|
const homeCandidate = join(homedir(), "silicaclaw");
|
|
40
|
-
if (
|
|
59
|
+
if (isSilicaClawDir(homeCandidate)) {
|
|
41
60
|
return resolve(homeCandidate);
|
|
42
61
|
}
|
|
43
62
|
|
|
@@ -193,6 +212,74 @@ function showStatus() {
|
|
|
193
212
|
updated_at: state?.updated_at || null,
|
|
194
213
|
};
|
|
195
214
|
console.log(JSON.stringify(payload, null, 2));
|
|
215
|
+
return payload;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function printConnectionSummary(status) {
|
|
219
|
+
if (!status?.local_console?.running) return;
|
|
220
|
+
console.log("");
|
|
221
|
+
console.log("Gateway connection summary:");
|
|
222
|
+
console.log(`- local-console: http://localhost:4310`);
|
|
223
|
+
console.log(`- mode: ${status.mode}`);
|
|
224
|
+
console.log(`- adapter: ${status.adapter}`);
|
|
225
|
+
if (status.mode === "global-preview") {
|
|
226
|
+
const signalingUrl = status?.signaling?.url || "http://localhost:4510";
|
|
227
|
+
const room = status?.signaling?.room || "silicaclaw-demo";
|
|
228
|
+
console.log(`- signaling: ${signalingUrl} (room=${room})`);
|
|
229
|
+
}
|
|
230
|
+
console.log(`- local-console log: ${status?.local_console?.log_file || CONSOLE_LOG_FILE}`);
|
|
231
|
+
console.log(`- status: silicaclaw gateway status`);
|
|
232
|
+
console.log(`- logs: silicaclaw gateway logs local-console`);
|
|
233
|
+
console.log(`- stop: silicaclaw gateway stop`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function listeningProcessOnPort(port) {
|
|
237
|
+
try {
|
|
238
|
+
const pidRes = spawnSync("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-t"], {
|
|
239
|
+
encoding: "utf8",
|
|
240
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
241
|
+
});
|
|
242
|
+
const pid = String(pidRes.stdout || "")
|
|
243
|
+
.split(/\r?\n/)
|
|
244
|
+
.map((s) => s.trim())
|
|
245
|
+
.find(Boolean);
|
|
246
|
+
if (!pid) return null;
|
|
247
|
+
|
|
248
|
+
const cmdRes = spawnSync("ps", ["-p", pid, "-o", "command="], {
|
|
249
|
+
encoding: "utf8",
|
|
250
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
251
|
+
});
|
|
252
|
+
const command = String(cmdRes.stdout || "").trim() || "unknown";
|
|
253
|
+
return { pid, command };
|
|
254
|
+
} catch {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function printStopSummary() {
|
|
260
|
+
const localListener = listeningProcessOnPort(4310);
|
|
261
|
+
const signalingListener = listeningProcessOnPort(4510);
|
|
262
|
+
console.log("");
|
|
263
|
+
console.log("Gateway stop summary:");
|
|
264
|
+
if (!localListener) {
|
|
265
|
+
console.log("- local-console port 4310: stopped");
|
|
266
|
+
} else {
|
|
267
|
+
console.log(`- local-console port 4310: still in use by pid=${localListener.pid}`);
|
|
268
|
+
console.log(` command: ${localListener.command}`);
|
|
269
|
+
console.log(" this is likely another process not started by gateway");
|
|
270
|
+
console.log(` inspect: lsof -nP -iTCP:4310 -sTCP:LISTEN`);
|
|
271
|
+
console.log(` stop it: kill ${localListener.pid}`);
|
|
272
|
+
}
|
|
273
|
+
if (!signalingListener) {
|
|
274
|
+
console.log("- signaling port 4510: stopped");
|
|
275
|
+
} else {
|
|
276
|
+
console.log(`- signaling port 4510: still in use by pid=${signalingListener.pid}`);
|
|
277
|
+
console.log(` command: ${signalingListener.command}`);
|
|
278
|
+
console.log(" this is likely another process not started by gateway");
|
|
279
|
+
console.log(` inspect: lsof -nP -iTCP:4510 -sTCP:LISTEN`);
|
|
280
|
+
console.log(` stop it: kill ${signalingListener.pid}`);
|
|
281
|
+
}
|
|
282
|
+
console.log(`- check status: silicaclaw gateway status`);
|
|
196
283
|
}
|
|
197
284
|
|
|
198
285
|
function tailFile(file, lines = 80) {
|
|
@@ -287,18 +374,21 @@ async function main() {
|
|
|
287
374
|
}
|
|
288
375
|
if (cmd === "start") {
|
|
289
376
|
startAll();
|
|
290
|
-
showStatus();
|
|
377
|
+
const status = showStatus();
|
|
378
|
+
printConnectionSummary(status);
|
|
291
379
|
return;
|
|
292
380
|
}
|
|
293
381
|
if (cmd === "stop") {
|
|
294
382
|
await stopAll();
|
|
295
383
|
showStatus();
|
|
384
|
+
printStopSummary();
|
|
296
385
|
return;
|
|
297
386
|
}
|
|
298
387
|
if (cmd === "restart") {
|
|
299
388
|
await stopAll();
|
|
300
389
|
startAll();
|
|
301
|
-
showStatus();
|
|
390
|
+
const status = showStatus();
|
|
391
|
+
printConnectionSummary(status);
|
|
302
392
|
return;
|
|
303
393
|
}
|
|
304
394
|
if (cmd === "logs") {
|
|
@@ -318,4 +408,3 @@ main().catch((error) => {
|
|
|
318
408
|
console.error(error?.message || String(error));
|
|
319
409
|
process.exit(1);
|
|
320
410
|
});
|
|
321
|
-
|