@silicaclaw/cli 1.0.0-beta.29 → 1.0.0-beta.30
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 +46 -50
- package/scripts/silicaclaw-gateway.mjs +18 -26
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
-
import { accessSync, constants, cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { accessSync, constants, cpSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { dirname, resolve } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
@@ -29,7 +29,7 @@ function paint(text, ...styles) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
function headline() {
|
|
32
|
-
console.log(`${paint("SilicaClaw", COLOR.bold, COLOR.orange)} ${paint(
|
|
32
|
+
console.log(`${paint("SilicaClaw", COLOR.bold, COLOR.orange)} ${paint(readPackageVersion(), COLOR.dim)}`);
|
|
33
33
|
console.log(paint("Public identity and discovery for OpenClaw agents.", COLOR.dim));
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -137,6 +137,24 @@ function ensureLineInFile(filePath, block) {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
function describeFileOwner(filePath) {
|
|
141
|
+
try {
|
|
142
|
+
if (!existsSync(filePath)) return null;
|
|
143
|
+
const stat = statSync(filePath);
|
|
144
|
+
return String(stat.uid);
|
|
145
|
+
} catch {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function currentUid() {
|
|
151
|
+
try {
|
|
152
|
+
return typeof process.getuid === "function" ? String(process.getuid()) : null;
|
|
153
|
+
} catch {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
140
158
|
function shellInitTargets() {
|
|
141
159
|
const home = homedir();
|
|
142
160
|
const shell = String(process.env.SHELL || "");
|
|
@@ -197,11 +215,15 @@ function installPersistentCommand() {
|
|
|
197
215
|
);
|
|
198
216
|
const rcFiles = shellInitTargets();
|
|
199
217
|
const updatedFiles = [];
|
|
218
|
+
const configuredFiles = [];
|
|
200
219
|
const failedFiles = [];
|
|
201
220
|
for (const filePath of rcFiles) {
|
|
202
221
|
const result = ensureLineInFile(filePath, rcBlock);
|
|
203
222
|
if (result.changed) {
|
|
204
223
|
updatedFiles.push(filePath);
|
|
224
|
+
configuredFiles.push(filePath);
|
|
225
|
+
} else if (!result.error) {
|
|
226
|
+
configuredFiles.push(filePath);
|
|
205
227
|
}
|
|
206
228
|
if (result.error) {
|
|
207
229
|
failedFiles.push({ filePath, error: result.error });
|
|
@@ -210,24 +232,29 @@ function installPersistentCommand() {
|
|
|
210
232
|
|
|
211
233
|
headline();
|
|
212
234
|
console.log("");
|
|
213
|
-
console.log(`${paint("Installed", COLOR.bold)}
|
|
235
|
+
console.log(`${paint("Installed", COLOR.bold)} \`silicaclaw\` command`);
|
|
214
236
|
kv("Command", "silicaclaw");
|
|
215
|
-
kv("Shim", shimPath);
|
|
216
|
-
kv("Env", envFile);
|
|
217
|
-
kv("Shell init", rcFiles.join(", "));
|
|
218
237
|
console.log("");
|
|
219
238
|
kv("Activate", `source "${envFile}"`);
|
|
220
|
-
if (
|
|
221
|
-
kv("Startup", "
|
|
239
|
+
if (configuredFiles.length > 0) {
|
|
240
|
+
kv("Startup", "configured");
|
|
241
|
+
} else {
|
|
242
|
+
kv("Startup", "manual setup required");
|
|
222
243
|
}
|
|
223
244
|
if (failedFiles.length > 0) {
|
|
224
245
|
console.log("");
|
|
225
|
-
console.log(paint("Shell files
|
|
246
|
+
console.log(paint("Shell files skipped", COLOR.bold, COLOR.yellow));
|
|
247
|
+
const uid = currentUid();
|
|
226
248
|
for (const item of failedFiles) {
|
|
227
|
-
|
|
249
|
+
const owner = describeFileOwner(item.filePath);
|
|
250
|
+
const reason =
|
|
251
|
+
owner && uid && owner !== uid
|
|
252
|
+
? `${item.error} (owned by another user)`
|
|
253
|
+
: item.error;
|
|
254
|
+
kv(item.filePath, reason);
|
|
228
255
|
}
|
|
229
256
|
console.log("");
|
|
230
|
-
kv("Manual
|
|
257
|
+
kv("Manual", '[ -f "$HOME/.silicaclaw/env.sh" ] && . "$HOME/.silicaclaw/env.sh"');
|
|
231
258
|
}
|
|
232
259
|
}
|
|
233
260
|
|
|
@@ -250,44 +277,17 @@ function canWriteGlobalPrefix() {
|
|
|
250
277
|
}
|
|
251
278
|
|
|
252
279
|
function showUpdateGuide(current, latest, beta) {
|
|
253
|
-
const npxRuntime = isNpxRun();
|
|
254
280
|
headline();
|
|
255
281
|
console.log("");
|
|
256
|
-
console.log(paint("Update check", COLOR.bold));
|
|
257
|
-
kv("Current", current);
|
|
258
|
-
kv("Latest", latest || "-");
|
|
259
|
-
kv("Beta", beta || "-");
|
|
260
|
-
console.log("");
|
|
261
|
-
|
|
262
282
|
const upToDate = Boolean(beta) && current === beta;
|
|
263
283
|
if (upToDate) {
|
|
264
|
-
|
|
284
|
+
kv("Status", `up to date (${current})`);
|
|
265
285
|
} else {
|
|
266
|
-
|
|
286
|
+
kv("Status", `beta update available (${beta || "-"})`);
|
|
267
287
|
}
|
|
268
288
|
console.log("");
|
|
269
|
-
|
|
270
|
-
kv("Start", "silicaclaw start --mode=global-preview");
|
|
289
|
+
kv("Start", "silicaclaw start");
|
|
271
290
|
kv("Status", "silicaclaw status");
|
|
272
|
-
kv("Install", "npx -y @silicaclaw/cli@beta install");
|
|
273
|
-
kv("One-shot", "npx -y @silicaclaw/cli@beta start --mode=global-preview");
|
|
274
|
-
console.log("");
|
|
275
|
-
|
|
276
|
-
const writableGlobal = canWriteGlobalPrefix();
|
|
277
|
-
if (!npxRuntime && writableGlobal) {
|
|
278
|
-
console.log(paint("Optional global install", COLOR.bold));
|
|
279
|
-
kv("Install", "npm i -g @silicaclaw/cli@beta");
|
|
280
|
-
kv("Verify", "silicaclaw version");
|
|
281
|
-
console.log("");
|
|
282
|
-
} else if (!npxRuntime) {
|
|
283
|
-
console.log(paint("Global install skipped", COLOR.bold, COLOR.yellow));
|
|
284
|
-
console.log("npm global directory is not writable on this machine.");
|
|
285
|
-
console.log("");
|
|
286
|
-
}
|
|
287
|
-
if (npxRuntime) {
|
|
288
|
-
console.log(paint("Detected npx runtime", COLOR.bold));
|
|
289
|
-
console.log("Run `npx -y @silicaclaw/cli@beta install` once to make `silicaclaw` available in new shells.");
|
|
290
|
-
}
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
function getGatewayStatus() {
|
|
@@ -352,15 +352,11 @@ function syncCurrentPackageToAppDir(appDir) {
|
|
|
352
352
|
function restartGatewayIfRunning() {
|
|
353
353
|
const status = getGatewayStatus();
|
|
354
354
|
const appDir = status?.app_dir ? String(status.app_dir) : "";
|
|
355
|
-
|
|
356
|
-
if (synced) {
|
|
357
|
-
kv("Synced", appDir);
|
|
358
|
-
}
|
|
355
|
+
syncCurrentPackageToAppDir(appDir);
|
|
359
356
|
|
|
360
357
|
const localRunning = Boolean(status?.local_console?.running);
|
|
361
358
|
const signalingRunning = Boolean(status?.signaling?.running);
|
|
362
359
|
if (!localRunning && !signalingRunning) {
|
|
363
|
-
kv("Runtime", "gateway not running; no refresh needed");
|
|
364
360
|
return;
|
|
365
361
|
}
|
|
366
362
|
|
|
@@ -374,7 +370,7 @@ function restartGatewayIfRunning() {
|
|
|
374
370
|
}
|
|
375
371
|
|
|
376
372
|
console.log("");
|
|
377
|
-
console.log(paint("Refreshing
|
|
373
|
+
console.log(paint("Refreshing services", COLOR.bold));
|
|
378
374
|
runInherit("node", args, { cwd: process.cwd() });
|
|
379
375
|
}
|
|
380
376
|
|
|
@@ -409,11 +405,11 @@ function update() {
|
|
|
409
405
|
|
|
410
406
|
if (hasNewBeta) {
|
|
411
407
|
if (npxRuntime) {
|
|
412
|
-
kv("Update", `
|
|
408
|
+
kv("Update", `next run will use ${beta}`);
|
|
413
409
|
} else if (tryGlobalUpgrade(beta)) {
|
|
414
|
-
kv("
|
|
410
|
+
kv("Update", `installed ${beta}`);
|
|
415
411
|
} else {
|
|
416
|
-
kv("
|
|
412
|
+
kv("Update", `install ${beta} manually if needed`);
|
|
417
413
|
}
|
|
418
414
|
}
|
|
419
415
|
|
|
@@ -33,7 +33,18 @@ function paint(text, ...styles) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function headline() {
|
|
36
|
-
const
|
|
36
|
+
const pkgPath = join(ROOT_DIR, "package.json");
|
|
37
|
+
let version = "unknown";
|
|
38
|
+
if (existsSync(pkgPath)) {
|
|
39
|
+
try {
|
|
40
|
+
const pkg = JSON.parse(String(readFileSync(pkgPath, "utf8")));
|
|
41
|
+
version = String(pkg.version || "unknown");
|
|
42
|
+
} catch {
|
|
43
|
+
version = "unknown";
|
|
44
|
+
}
|
|
45
|
+
} else if (existsSync(join(ROOT_DIR, "VERSION"))) {
|
|
46
|
+
version = String(readFileSync(join(ROOT_DIR, "VERSION"), "utf8")).trim() || "unknown";
|
|
47
|
+
}
|
|
37
48
|
console.log(`${paint("SilicaClaw", COLOR.bold, COLOR.orange)} ${paint(version, COLOR.dim)}`);
|
|
38
49
|
console.log(paint("Public identity and discovery for OpenClaw agents.", COLOR.dim));
|
|
39
50
|
}
|
|
@@ -253,27 +264,17 @@ function showStatusHuman() {
|
|
|
253
264
|
const payload = buildStatusPayload();
|
|
254
265
|
headline();
|
|
255
266
|
console.log("");
|
|
256
|
-
console.log(paint("Gateway status", COLOR.bold));
|
|
257
|
-
kv("App dir", payload.app_dir);
|
|
258
|
-
kv("Mode", payload.mode);
|
|
259
|
-
kv("Adapter", payload.adapter);
|
|
260
267
|
kv(
|
|
261
|
-
"
|
|
268
|
+
"Status",
|
|
262
269
|
payload.local_console.running
|
|
263
|
-
? `${paint("running", COLOR.green)}
|
|
264
|
-
: paint("stopped", COLOR.dim)
|
|
270
|
+
? `${paint("running", COLOR.green)} · ${payload.mode}`
|
|
271
|
+
: `${paint("stopped", COLOR.dim)} · ${payload.mode}`
|
|
265
272
|
);
|
|
266
273
|
if (payload.mode === "global-preview") {
|
|
267
274
|
kv("Relay", payload.signaling.url || "https://relay.silicaclaw.com");
|
|
268
275
|
kv("Room", payload.signaling.room || "silicaclaw-global-preview");
|
|
269
276
|
}
|
|
270
|
-
if (payload.
|
|
271
|
-
kv("Signaling", `${paint("running", COLOR.green)} (pid=${payload.signaling.pid})`);
|
|
272
|
-
}
|
|
273
|
-
console.log("");
|
|
274
|
-
kv("Open", "http://localhost:4310");
|
|
275
|
-
kv("Logs", "silicaclaw logs local-console");
|
|
276
|
-
kv("Stop", "silicaclaw stop");
|
|
277
|
+
if (payload.local_console.running) kv("Open", "http://localhost:4310");
|
|
277
278
|
return payload;
|
|
278
279
|
}
|
|
279
280
|
|
|
@@ -281,21 +282,14 @@ function printConnectionSummary(status, verb = "Started") {
|
|
|
281
282
|
if (!status?.local_console?.running) return;
|
|
282
283
|
headline();
|
|
283
284
|
console.log("");
|
|
284
|
-
|
|
285
|
+
kv("Status", `${verb.toLowerCase()} · ${status.mode}`);
|
|
285
286
|
kv("Console", `http://localhost:4310`);
|
|
286
|
-
kv("Console pid", String(status?.local_console?.pid || "-"));
|
|
287
|
-
kv("Mode", status.mode);
|
|
288
|
-
kv("Adapter", status.adapter);
|
|
289
287
|
if (status.mode === "global-preview") {
|
|
290
288
|
const signalingUrl = status?.signaling?.url || "https://relay.silicaclaw.com";
|
|
291
289
|
const room = status?.signaling?.room || "silicaclaw-global-preview";
|
|
292
290
|
kv("Relay", signalingUrl);
|
|
293
291
|
kv("Room", room);
|
|
294
292
|
}
|
|
295
|
-
console.log("");
|
|
296
|
-
kv("Status", "silicaclaw status");
|
|
297
|
-
kv("Logs", "silicaclaw logs local-console");
|
|
298
|
-
kv("Stop", "silicaclaw stop");
|
|
299
293
|
}
|
|
300
294
|
|
|
301
295
|
function listeningProcessOnPort(port) {
|
|
@@ -326,7 +320,7 @@ function printStopSummary() {
|
|
|
326
320
|
const signalingListener = listeningProcessOnPort(4510);
|
|
327
321
|
headline();
|
|
328
322
|
console.log("");
|
|
329
|
-
|
|
323
|
+
kv("Status", "stopped");
|
|
330
324
|
if (!localListener) {
|
|
331
325
|
kv("Console", paint("stopped", COLOR.green));
|
|
332
326
|
} else {
|
|
@@ -341,8 +335,6 @@ function printStopSummary() {
|
|
|
341
335
|
kv("Inspect", "lsof -nP -iTCP:4510 -sTCP:LISTEN");
|
|
342
336
|
kv("Stop pid", `kill ${signalingListener.pid}`);
|
|
343
337
|
}
|
|
344
|
-
console.log("");
|
|
345
|
-
kv("Status", "silicaclaw status");
|
|
346
338
|
}
|
|
347
339
|
|
|
348
340
|
function tailFile(file, lines = 80) {
|