@silicaclaw/cli 1.0.0-beta.21 → 1.0.0-beta.23
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/CHANGELOG.md +33 -0
- package/INSTALL.md +1 -1
- package/README.md +54 -22
- package/apps/local-console/public/index.html +246 -26
- package/apps/local-console/src/server.ts +44 -8
- package/docs/CLOUDFLARE_RELAY.md +3 -3
- package/docs/NEW_USER_INSTALL.md +164 -0
- package/package.json +1 -1
- package/packages/core/dist/socialConfig.js +1 -1
- package/packages/core/src/socialConfig.ts +1 -1
- package/packages/network/dist/relayPreview.d.ts +24 -0
- package/packages/network/dist/relayPreview.js +82 -18
- package/packages/network/src/relayPreview.ts +97 -18
- package/packages/storage/dist/socialRuntimeRepo.js +1 -1
- package/packages/storage/src/socialRuntimeRepo.ts +1 -1
- package/scripts/quickstart.sh +3 -3
- package/scripts/silicaclaw-cli.mjs +76 -5
- package/scripts/silicaclaw-gateway.mjs +5 -5
- package/scripts/webrtc-signaling-server.mjs +29 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
-
import { accessSync, constants, cpSync, existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { accessSync, constants, cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { homedir } from "node:os";
|
|
5
6
|
import { dirname, resolve } from "node:path";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
8
|
|
|
@@ -67,6 +68,69 @@ function readPackageVersion() {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
function preferredShellRcFile() {
|
|
72
|
+
const shell = String(process.env.SHELL || "");
|
|
73
|
+
if (shell.endsWith("/zsh")) return resolve(homedir(), ".zshrc");
|
|
74
|
+
if (shell.endsWith("/bash")) return resolve(homedir(), ".bashrc");
|
|
75
|
+
if (process.env.ZSH_VERSION) return resolve(homedir(), ".zshrc");
|
|
76
|
+
return resolve(homedir(), ".bashrc");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function userShimDir() {
|
|
80
|
+
return resolve(homedir(), ".silicaclaw", "bin");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function userShimPath() {
|
|
84
|
+
return resolve(userShimDir(), "silicaclaw");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function ensureLineInFile(filePath, block) {
|
|
88
|
+
const current = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
|
|
89
|
+
if (current.includes(block.trim())) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const next = `${current.replace(/\s*$/, "")}\n\n${block}\n`;
|
|
93
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
94
|
+
writeFileSync(filePath, next, "utf8");
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function installPersistentCommand() {
|
|
99
|
+
const binDir = userShimDir();
|
|
100
|
+
const shimPath = userShimPath();
|
|
101
|
+
const rcFile = preferredShellRcFile();
|
|
102
|
+
const markerBlock = [
|
|
103
|
+
"# >>> silicaclaw >>>",
|
|
104
|
+
'export PATH="$HOME/.silicaclaw/bin:$PATH"',
|
|
105
|
+
"# <<< silicaclaw <<<",
|
|
106
|
+
].join("\n");
|
|
107
|
+
|
|
108
|
+
mkdirSync(binDir, { recursive: true });
|
|
109
|
+
writeFileSync(
|
|
110
|
+
shimPath,
|
|
111
|
+
[
|
|
112
|
+
"#!/usr/bin/env bash",
|
|
113
|
+
"set -euo pipefail",
|
|
114
|
+
'exec npx -y @silicaclaw/cli@beta "$@"',
|
|
115
|
+
"",
|
|
116
|
+
].join("\n"),
|
|
117
|
+
{ encoding: "utf8", mode: 0o755 }
|
|
118
|
+
);
|
|
119
|
+
const rcUpdated = ensureLineInFile(rcFile, markerBlock);
|
|
120
|
+
|
|
121
|
+
console.log("Installed persistent `silicaclaw` command.");
|
|
122
|
+
console.log(`- shim: ${shimPath}`);
|
|
123
|
+
console.log(`- shell rc: ${rcFile}`);
|
|
124
|
+
console.log("");
|
|
125
|
+
if (rcUpdated) {
|
|
126
|
+
console.log("To activate in the current shell:");
|
|
127
|
+
console.log(`source "${rcFile}"`);
|
|
128
|
+
} else {
|
|
129
|
+
console.log("Shell PATH entry already existed.");
|
|
130
|
+
console.log(`If needed, run: source "${rcFile}"`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
70
134
|
function isNpxRun() {
|
|
71
135
|
return ROOT_DIR.includes("/.npm/_npx/");
|
|
72
136
|
}
|
|
@@ -102,11 +166,13 @@ function showUpdateGuide(current, latest, beta) {
|
|
|
102
166
|
console.log("");
|
|
103
167
|
console.log("Quick next commands:");
|
|
104
168
|
console.log("1) Start internet gateway");
|
|
105
|
-
console.log(" silicaclaw start --mode=global-preview
|
|
169
|
+
console.log(" silicaclaw start --mode=global-preview");
|
|
106
170
|
console.log("2) Check gateway status");
|
|
107
171
|
console.log(" silicaclaw status");
|
|
108
|
-
console.log("3)
|
|
109
|
-
console.log(" npx -y @silicaclaw/cli@beta
|
|
172
|
+
console.log("3) Install persistent command (recommended once)");
|
|
173
|
+
console.log(" npx -y @silicaclaw/cli@beta install");
|
|
174
|
+
console.log("4) npx one-shot (no install)");
|
|
175
|
+
console.log(" npx -y @silicaclaw/cli@beta start --mode=global-preview");
|
|
110
176
|
console.log("");
|
|
111
177
|
|
|
112
178
|
const writableGlobal = canWriteGlobalPrefix();
|
|
@@ -121,7 +187,7 @@ function showUpdateGuide(current, latest, beta) {
|
|
|
121
187
|
}
|
|
122
188
|
if (npxRuntime) {
|
|
123
189
|
console.log("Detected npx runtime.");
|
|
124
|
-
console.log("
|
|
190
|
+
console.log("Run `npx -y @silicaclaw/cli@beta install` once to make `silicaclaw` available in new shells.");
|
|
125
191
|
}
|
|
126
192
|
}
|
|
127
193
|
|
|
@@ -265,6 +331,7 @@ Usage:
|
|
|
265
331
|
silicaclaw onboard
|
|
266
332
|
silicaclaw connect
|
|
267
333
|
silicaclaw update
|
|
334
|
+
silicaclaw install
|
|
268
335
|
silicaclaw start [--mode=local|lan|global-preview]
|
|
269
336
|
silicaclaw stop
|
|
270
337
|
silicaclaw restart [--mode=local|lan|global-preview]
|
|
@@ -282,6 +349,7 @@ Commands:
|
|
|
282
349
|
onboard Interactive step-by-step onboarding (recommended)
|
|
283
350
|
connect Cross-network connect wizard (global-preview first)
|
|
284
351
|
update Check latest npm version and show upgrade commands
|
|
352
|
+
install Install persistent silicaclaw command for future shells
|
|
285
353
|
start Start gateway-managed background services
|
|
286
354
|
stop Stop gateway-managed background services
|
|
287
355
|
restart Restart gateway-managed background services
|
|
@@ -315,6 +383,9 @@ switch (cmd) {
|
|
|
315
383
|
case "update":
|
|
316
384
|
update();
|
|
317
385
|
break;
|
|
386
|
+
case "install":
|
|
387
|
+
installPersistentCommand();
|
|
388
|
+
break;
|
|
318
389
|
case "gateway":
|
|
319
390
|
run("node", [resolve(ROOT_DIR, "scripts", "silicaclaw-gateway.mjs"), ...process.argv.slice(3)], {
|
|
320
391
|
cwd: process.cwd(),
|
|
@@ -176,7 +176,7 @@ function printHelp() {
|
|
|
176
176
|
SilicaClaw Gateway
|
|
177
177
|
|
|
178
178
|
Usage:
|
|
179
|
-
silicaclaw gateway start [--mode=local|lan|global-preview] [--signaling-url=
|
|
179
|
+
silicaclaw gateway start [--mode=local|lan|global-preview] [--signaling-url=https://relay.silicaclaw.com] [--room=silicaclaw-global-preview]
|
|
180
180
|
silicaclaw gateway stop
|
|
181
181
|
silicaclaw gateway restart [--mode=...]
|
|
182
182
|
silicaclaw gateway status
|
|
@@ -224,8 +224,8 @@ function printConnectionSummary(status) {
|
|
|
224
224
|
console.log(`- mode: ${status.mode}`);
|
|
225
225
|
console.log(`- adapter: ${status.adapter}`);
|
|
226
226
|
if (status.mode === "global-preview") {
|
|
227
|
-
const signalingUrl = status?.signaling?.url || "
|
|
228
|
-
const room = status?.signaling?.room || "silicaclaw-
|
|
227
|
+
const signalingUrl = status?.signaling?.url || "https://relay.silicaclaw.com";
|
|
228
|
+
const room = status?.signaling?.room || "silicaclaw-global-preview";
|
|
229
229
|
console.log(`- signaling: ${signalingUrl} (room=${room})`);
|
|
230
230
|
}
|
|
231
231
|
console.log(`- local-console log: ${status?.local_console?.log_file || CONSOLE_LOG_FILE}`);
|
|
@@ -312,8 +312,8 @@ function startAll() {
|
|
|
312
312
|
|
|
313
313
|
const mode = parseMode(parseFlag("mode", process.env.NETWORK_MODE || "global-preview"));
|
|
314
314
|
const adapter = adapterForMode(mode);
|
|
315
|
-
const signalingUrl = parseFlag("signaling-url", process.env.WEBRTC_SIGNALING_URL || "
|
|
316
|
-
const room = parseFlag("room", process.env.WEBRTC_ROOM || "silicaclaw-
|
|
315
|
+
const signalingUrl = parseFlag("signaling-url", process.env.WEBRTC_SIGNALING_URL || "https://relay.silicaclaw.com");
|
|
316
|
+
const room = parseFlag("room", process.env.WEBRTC_ROOM || "silicaclaw-global-preview");
|
|
317
317
|
const shouldDisableSignaling = hasFlag("no-signaling");
|
|
318
318
|
|
|
319
319
|
const currentLocalPid = readPid(CONSOLE_PID_FILE);
|
|
@@ -153,7 +153,35 @@ const server = http.createServer(async (req, res) => {
|
|
|
153
153
|
const roomId = String(url.searchParams.get('room') || 'silicaclaw-room');
|
|
154
154
|
const room = getRoom(roomId);
|
|
155
155
|
cleanupRoom(roomId);
|
|
156
|
-
return json(res, 200, {
|
|
156
|
+
return json(res, 200, {
|
|
157
|
+
ok: true,
|
|
158
|
+
room: roomId,
|
|
159
|
+
peer_count: room.peers.size,
|
|
160
|
+
peers: Array.from(room.peers.keys()),
|
|
161
|
+
peer_details: Array.from(room.peers.entries()).map(([peerId, peer]) => ({
|
|
162
|
+
peer_id: peerId,
|
|
163
|
+
last_seen_at: peer.last_seen_at,
|
|
164
|
+
signal_queue_size: (room.queues.get(peerId) || []).length,
|
|
165
|
+
relay_queue_size: (room.relay_queues.get(peerId) || []).length,
|
|
166
|
+
})),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (req.method === 'GET' && url.pathname === '/room') {
|
|
171
|
+
const roomId = String(url.searchParams.get('room') || 'silicaclaw-room');
|
|
172
|
+
const room = getRoom(roomId);
|
|
173
|
+
cleanupRoom(roomId);
|
|
174
|
+
return json(res, 200, {
|
|
175
|
+
ok: true,
|
|
176
|
+
room: roomId,
|
|
177
|
+
peer_count: room.peers.size,
|
|
178
|
+
peers: Array.from(room.peers.entries()).map(([peerId, peer]) => ({
|
|
179
|
+
peer_id: peerId,
|
|
180
|
+
last_seen_at: peer.last_seen_at,
|
|
181
|
+
signal_queue_size: (room.queues.get(peerId) || []).length,
|
|
182
|
+
relay_queue_size: (room.relay_queues.get(peerId) || []).length,
|
|
183
|
+
})),
|
|
184
|
+
});
|
|
157
185
|
}
|
|
158
186
|
|
|
159
187
|
if (req.method === 'GET' && url.pathname === '/poll') {
|