clawcrib 0.1.0 → 0.1.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/bin/clawcrib.mjs +313 -25
- package/dist/.next/BUILD_ID +1 -1
- package/dist/.next/build-manifest.json +2 -2
- package/dist/.next/server/app/_global-error.html +2 -2
- package/dist/.next/server/app/_global-error.rsc +1 -1
- package/dist/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/_not-found.html +2 -2
- package/dist/.next/server/app/_not-found.rsc +2 -2
- package/dist/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/agent/[name]/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/browse/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/browse.html +2 -2
- package/dist/.next/server/app/browse.rsc +2 -2
- package/dist/.next/server/app/browse.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/browse.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/browse.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/browse.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/browse.segments/browse/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/browse.segments/browse.segment.rsc +1 -1
- package/dist/.next/server/app/builder/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/builder.html +2 -2
- package/dist/.next/server/app/builder.rsc +2 -2
- package/dist/.next/server/app/builder.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/builder.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/builder.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/builder.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/builder.segments/builder/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/builder.segments/builder.segment.rsc +1 -1
- package/dist/.next/server/app/crib/[slug]/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/crib/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/crib.html +1 -1
- package/dist/.next/server/app/crib.rsc +2 -2
- package/dist/.next/server/app/crib.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/crib.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/crib.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/crib.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/crib.segments/crib/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/crib.segments/crib.segment.rsc +1 -1
- package/dist/.next/server/app/demo/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/demo.html +1 -1
- package/dist/.next/server/app/demo.rsc +2 -2
- package/dist/.next/server/app/demo.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/demo.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/demo.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/demo.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/demo.segments/demo/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/demo.segments/demo.segment.rsc +1 -1
- package/dist/.next/server/app/feedback/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/feedback.html +2 -2
- package/dist/.next/server/app/feedback.rsc +2 -2
- package/dist/.next/server/app/feedback.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/feedback.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/feedback.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/feedback.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/feedback.segments/feedback/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/feedback.segments/feedback.segment.rsc +1 -1
- package/dist/.next/server/app/gltest/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/gltest.html +1 -1
- package/dist/.next/server/app/gltest.rsc +2 -2
- package/dist/.next/server/app/gltest.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/gltest.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/gltest.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/gltest.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/gltest.segments/gltest/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/gltest.segments/gltest.segment.rsc +1 -1
- package/dist/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/help.html +2 -2
- package/dist/.next/server/app/help.rsc +2 -2
- package/dist/.next/server/app/help.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/help.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/help.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/help.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/help.segments/help/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/help.segments/help.segment.rsc +1 -1
- package/dist/.next/server/app/index.html +1 -1
- package/dist/.next/server/app/index.rsc +3 -3
- package/dist/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/dist/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/learn/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/learn.html +2 -2
- package/dist/.next/server/app/learn.rsc +2 -2
- package/dist/.next/server/app/learn.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/learn.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/learn.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/learn.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/learn.segments/learn/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/learn.segments/learn.segment.rsc +1 -1
- package/dist/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/privacy.html +2 -2
- package/dist/.next/server/app/privacy.rsc +2 -2
- package/dist/.next/server/app/privacy.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/privacy.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/privacy.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/privacy.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/privacy.segments/privacy/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/privacy.segments/privacy.segment.rsc +1 -1
- package/dist/.next/server/app/terms/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/terms.html +2 -2
- package/dist/.next/server/app/terms.rsc +2 -2
- package/dist/.next/server/app/terms.segments/_full.segment.rsc +2 -2
- package/dist/.next/server/app/terms.segments/_head.segment.rsc +1 -1
- package/dist/.next/server/app/terms.segments/_index.segment.rsc +2 -2
- package/dist/.next/server/app/terms.segments/_tree.segment.rsc +2 -2
- package/dist/.next/server/app/terms.segments/terms/__PAGE__.segment.rsc +1 -1
- package/dist/.next/server/app/terms.segments/terms.segment.rsc +1 -1
- package/dist/.next/server/chunks/ssr/_a46dee72._.js +1 -1
- package/dist/.next/server/middleware-manifest.json +1 -1
- package/dist/.next/server/pages/404.html +2 -2
- package/dist/.next/server/pages/500.html +2 -2
- package/dist/.next/static/chunks/{123ff9bd00156eb9.css → 1a8b8355b176018c.css} +1 -1
- package/dist/.next/static/chunks/eda8b4c24ac1f12f.js +1 -0
- package/package.json +1 -1
- package/dist/.next/static/chunks/46b6f1723e3c2623.js +0 -1
- /package/dist/.next/static/{LDs2QlURjFsxe6doQgQaH → 7d4fjIFyjViUDWgLnLDuG}/_buildManifest.js +0 -0
- /package/dist/.next/static/{LDs2QlURjFsxe6doQgQaH → 7d4fjIFyjViUDWgLnLDuG}/_clientMiddlewareManifest.json +0 -0
- /package/dist/.next/static/{LDs2QlURjFsxe6doQgQaH → 7d4fjIFyjViUDWgLnLDuG}/_ssgManifest.js +0 -0
package/bin/clawcrib.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
|
-
import { existsSync } from "node:fs";
|
|
4
|
+
import { existsSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
|
+
import net from "node:net";
|
|
7
|
+
import os from "node:os";
|
|
6
8
|
import path from "node:path";
|
|
7
9
|
import { fileURLToPath } from "node:url";
|
|
8
10
|
|
|
@@ -14,13 +16,23 @@ const HELP = `
|
|
|
14
16
|
ClawCrib — the live 3D office for your OpenClaw agents
|
|
15
17
|
|
|
16
18
|
Usage
|
|
17
|
-
npx clawcrib [options]
|
|
19
|
+
npx clawcrib [command] [options]
|
|
20
|
+
|
|
21
|
+
Commands
|
|
22
|
+
(none) Run in the foreground until you press Ctrl-C
|
|
23
|
+
start Run in the background; survives closing the terminal
|
|
24
|
+
stop Stop the background instance
|
|
25
|
+
restart Stop, then start
|
|
26
|
+
status Is it running, and is it responding?
|
|
27
|
+
install-service Keep it running across reboots (systemd / launchd)
|
|
28
|
+
uninstall-service Remove that service file
|
|
18
29
|
|
|
19
30
|
Options
|
|
20
31
|
-p, --port <port> Port to listen on (default: 18787)
|
|
21
32
|
-g, --gateway <url> OpenClaw gateway WebSocket URL (e.g. ws://127.0.0.1:18789)
|
|
22
33
|
-t, --token <token> Gateway auth token
|
|
23
|
-
--host <host> Host to bind (default: 127.0.0.1
|
|
34
|
+
--host <host> Host to bind (default: 127.0.0.1 — use 0.0.0.0 to
|
|
35
|
+
reach it from another machine over LAN/SSH)
|
|
24
36
|
--no-open Don't open the browser
|
|
25
37
|
-v, --version Print version
|
|
26
38
|
-h, --help Show this help
|
|
@@ -30,8 +42,11 @@ const HELP = `
|
|
|
30
42
|
are honored when flags are not given.
|
|
31
43
|
`;
|
|
32
44
|
|
|
45
|
+
const COMMANDS = new Set(["start", "stop", "restart", "status", "install-service", "uninstall-service"]);
|
|
46
|
+
|
|
33
47
|
function parseArgs(argv) {
|
|
34
|
-
const opts = { port: 18787, host: "127.0.0.1", open: true, gateway: null, token: null };
|
|
48
|
+
const opts = { port: 18787, host: "127.0.0.1", open: true, gateway: null, token: null, cmd: "run" };
|
|
49
|
+
if (argv.length && COMMANDS.has(argv[0])) opts.cmd = argv.shift();
|
|
35
50
|
for (let i = 0; i < argv.length; i++) {
|
|
36
51
|
const a = argv[i];
|
|
37
52
|
switch (a) {
|
|
@@ -112,38 +127,311 @@ const env = {
|
|
|
112
127
|
// tells the app it is a self-hosted dashboard, not the marketing site:
|
|
113
128
|
// the office is served at / and the website-only pages 404 (src/middleware.ts)
|
|
114
129
|
CLAWCRIB_APP: "1",
|
|
130
|
+
// a transitive dep still calls util._extend; the DEP0060 notice reads like a
|
|
131
|
+
// crash to someone running this for the first time and it is not actionable
|
|
132
|
+
NODE_OPTIONS: [process.env.NODE_OPTIONS, "--no-deprecation"].filter(Boolean).join(" "),
|
|
115
133
|
};
|
|
116
134
|
if (opts.gateway) env.OPENCLAW_GATEWAY_URL = opts.gateway;
|
|
117
135
|
if (opts.token) env.OPENCLAW_GATEWAY_TOKEN = opts.token;
|
|
118
136
|
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
137
|
+
const LOOPBACK = new Set(["127.0.0.1", "localhost", "::1"]);
|
|
138
|
+
const GATEWAY_PORT = 18789;
|
|
139
|
+
|
|
140
|
+
// The gateway almost always runs on the same box as the crib, so probe for a
|
|
141
|
+
// listener and say so rather than leaving someone in demo mode wondering why.
|
|
142
|
+
// TCP connect only: this never opens a session, so no device-pairing request
|
|
143
|
+
// is raised on the gateway.
|
|
144
|
+
function probePort(host, port, timeoutMs = 700) {
|
|
145
|
+
return new Promise((resolve) => {
|
|
146
|
+
const sock = net.connect({ host, port });
|
|
147
|
+
const finish = (ok) => {
|
|
148
|
+
sock.destroy();
|
|
149
|
+
resolve(ok);
|
|
150
|
+
};
|
|
151
|
+
sock.setTimeout(timeoutMs);
|
|
152
|
+
sock.once("connect", () => finish(true));
|
|
153
|
+
sock.once("timeout", () => finish(false));
|
|
154
|
+
sock.once("error", () => finish(false));
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// first non-internal IPv4, so a remote box can print a URL you can actually open
|
|
159
|
+
function lanAddress() {
|
|
160
|
+
for (const ifaces of Object.values(os.networkInterfaces())) {
|
|
161
|
+
for (const i of ifaces ?? []) {
|
|
162
|
+
if (i.family === "IPv4" && !i.internal) return i.address;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Must stay in step with device-identity.ts / api/crib/profiles: keyed off the
|
|
169
|
+
// user's home, never cwd (under npx the cwd is a throwaway cache directory).
|
|
170
|
+
const CONFIG_DIR = process.env.CLAWCRIB_CONFIG_DIR || path.join(os.homedir(), ".clawcrib");
|
|
171
|
+
const PID_FILE = path.join(CONFIG_DIR, "clawcrib.pid");
|
|
172
|
+
const LOG_FILE = path.join(CONFIG_DIR, "clawcrib.log");
|
|
125
173
|
|
|
126
174
|
const url = `http://${opts.host === "0.0.0.0" ? "localhost" : opts.host}:${opts.port}`;
|
|
127
175
|
const mode = env.OPENCLAW_GATEWAY_URL
|
|
128
176
|
? `live gateway: ${env.OPENCLAW_GATEWAY_URL}`
|
|
129
177
|
: "demo mode (no gateway configured — pass --gateway ws://... for live data)";
|
|
130
178
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
179
|
+
function readPid() {
|
|
180
|
+
try {
|
|
181
|
+
const pid = Number(readFileSync(PID_FILE, "utf8").trim());
|
|
182
|
+
// signal 0 tests for existence without touching the process
|
|
183
|
+
process.kill(pid, 0);
|
|
184
|
+
return pid;
|
|
185
|
+
} catch {
|
|
186
|
+
return null; // no pid file, or the process died without cleaning up
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async function printDetails() {
|
|
191
|
+
if (LOOPBACK.has(opts.host)) {
|
|
192
|
+
const lan = lanAddress();
|
|
193
|
+
console.log(` Note: bound to ${opts.host} — reachable only from this machine.`);
|
|
194
|
+
console.log(` For LAN/SSH access, use --host 0.0.0.0`);
|
|
195
|
+
if (lan) console.log(` then open http://${lan}:${opts.port}`);
|
|
196
|
+
}
|
|
197
|
+
if (!env.OPENCLAW_GATEWAY_URL && (await probePort("127.0.0.1", GATEWAY_PORT))) {
|
|
198
|
+
console.log(`\n Found an OpenClaw gateway on 127.0.0.1:${GATEWAY_PORT}. For live agents:`);
|
|
199
|
+
console.log(` clawcrib --gateway ws://127.0.0.1:${GATEWAY_PORT}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function spawnServer(detached) {
|
|
204
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
205
|
+
const out = detached ? openSync(LOG_FILE, "a") : "pipe";
|
|
206
|
+
return spawn(process.execPath, [serverJs], {
|
|
207
|
+
cwd: path.dirname(serverJs),
|
|
208
|
+
env,
|
|
209
|
+
detached,
|
|
210
|
+
stdio: detached ? ["ignore", out, out] : ["ignore", "pipe", "inherit"],
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async function cmdStart() {
|
|
215
|
+
const running = readPid();
|
|
216
|
+
if (running) {
|
|
217
|
+
console.log(`\n ClawCrib is already running (pid ${running}) at ${url}\n`);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const child = spawnServer(true);
|
|
221
|
+
child.unref(); // survives this shell exiting
|
|
222
|
+
writeFileSync(PID_FILE, String(child.pid));
|
|
223
|
+
if (!(await waitForServer(url))) {
|
|
224
|
+
console.error(`ClawCrib did not come up within 30s. Log: ${LOG_FILE}`);
|
|
225
|
+
try {
|
|
226
|
+
process.kill(child.pid);
|
|
227
|
+
} catch {
|
|
228
|
+
/* already gone */
|
|
229
|
+
}
|
|
230
|
+
rmSync(PID_FILE, { force: true });
|
|
135
231
|
process.exit(1);
|
|
136
232
|
}
|
|
137
|
-
console.log(`\n ClawCrib v${pkg.version}`);
|
|
233
|
+
console.log(`\n ClawCrib v${pkg.version} started in the background (pid ${child.pid})`);
|
|
138
234
|
console.log(` Crib: ${url}`);
|
|
139
|
-
console.log(` Mode: ${mode}
|
|
140
|
-
|
|
141
|
-
});
|
|
235
|
+
console.log(` Mode: ${mode}`);
|
|
236
|
+
await printDetails();
|
|
237
|
+
console.log(`\n Log: ${LOG_FILE}`);
|
|
238
|
+
console.log(` Stop: clawcrib stop\n`);
|
|
239
|
+
}
|
|
142
240
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
241
|
+
async function cmdStop() {
|
|
242
|
+
const pid = readPid();
|
|
243
|
+
if (!pid) {
|
|
244
|
+
console.log("\n ClawCrib is not running.\n");
|
|
245
|
+
rmSync(PID_FILE, { force: true });
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
process.kill(pid, "SIGTERM");
|
|
249
|
+
for (let i = 0; i < 40; i++) {
|
|
250
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
251
|
+
if (!readPid()) break;
|
|
252
|
+
}
|
|
253
|
+
if (readPid()) {
|
|
254
|
+
try {
|
|
255
|
+
process.kill(pid, "SIGKILL");
|
|
256
|
+
} catch {
|
|
257
|
+
/* raced with exit */
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
rmSync(PID_FILE, { force: true });
|
|
261
|
+
console.log(`\n ClawCrib stopped (pid ${pid}).\n`);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async function cmdStatus() {
|
|
265
|
+
const pid = readPid();
|
|
266
|
+
if (!pid) {
|
|
267
|
+
console.log("\n ClawCrib is not running.\n");
|
|
268
|
+
process.exitCode = 1;
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const responding = await waitForServer(url, 3000);
|
|
272
|
+
console.log(`\n ClawCrib is running (pid ${pid})`);
|
|
273
|
+
console.log(` Crib: ${url} — ${responding ? "responding" : "NOT responding"}`);
|
|
274
|
+
console.log(` Log: ${LOG_FILE}\n`);
|
|
275
|
+
if (!responding) process.exitCode = 1;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Keeps it alive across reboots. Uses the resolved bin path, which is why a
|
|
279
|
+
// global install matters: an npx path points into a cache that gets evicted.
|
|
280
|
+
function serviceFiles() {
|
|
281
|
+
const binPath = process.argv[1];
|
|
282
|
+
// Deliberately the FOREGROUND run, not `start`: systemd and launchd want to
|
|
283
|
+
// supervise the process themselves. Pointing them at `start` — which forks
|
|
284
|
+
// and exits — makes launchd's KeepAlive treat every launch as a crash and
|
|
285
|
+
// respawn in a loop.
|
|
286
|
+
const args = [binPath, "--no-open"];
|
|
287
|
+
if (opts.port !== 18787) args.push("--port", String(opts.port));
|
|
288
|
+
if (opts.host !== "127.0.0.1") args.push("--host", opts.host);
|
|
289
|
+
if (opts.gateway) args.push("--gateway", opts.gateway);
|
|
290
|
+
if (opts.token) args.push("--token", opts.token);
|
|
291
|
+
return { binPath, args };
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function cmdInstallService() {
|
|
295
|
+
const { binPath, args } = serviceFiles();
|
|
296
|
+
if (binPath.includes("_npx") || binPath.includes("npm/_cacache")) {
|
|
297
|
+
console.error(
|
|
298
|
+
"\n Refusing to install a service pointing at an npx cache path — it will be evicted.\n" +
|
|
299
|
+
" Install globally first: npm i -g clawcrib\n"
|
|
300
|
+
);
|
|
301
|
+
process.exit(1);
|
|
302
|
+
}
|
|
303
|
+
const exec = [process.execPath, ...args].map((a) => JSON.stringify(a)).join(" ");
|
|
304
|
+
|
|
305
|
+
if (process.platform === "linux") {
|
|
306
|
+
const unit = `[Unit]
|
|
307
|
+
Description=ClawCrib — live 3D office for OpenClaw agents
|
|
308
|
+
After=network-online.target
|
|
309
|
+
|
|
310
|
+
[Service]
|
|
311
|
+
Type=simple
|
|
312
|
+
ExecStart=${exec}
|
|
313
|
+
Restart=on-failure
|
|
314
|
+
RestartSec=5
|
|
315
|
+
Environment=CLAWCRIB_CONFIG_DIR=${CONFIG_DIR}
|
|
316
|
+
|
|
317
|
+
[Install]
|
|
318
|
+
WantedBy=default.target
|
|
319
|
+
`;
|
|
320
|
+
const dir = path.join(os.homedir(), ".config", "systemd", "user");
|
|
321
|
+
mkdirSync(dir, { recursive: true });
|
|
322
|
+
const file = path.join(dir, "clawcrib.service");
|
|
323
|
+
writeFileSync(file, unit);
|
|
324
|
+
console.log(`\n Wrote ${file}\n`);
|
|
325
|
+
console.log(" Enable it (starts now and on every boot):");
|
|
326
|
+
console.log(" systemctl --user daemon-reload");
|
|
327
|
+
console.log(" systemctl --user enable --now clawcrib");
|
|
328
|
+
console.log("\n So it keeps running after you log out of SSH:");
|
|
329
|
+
console.log(" sudo loginctl enable-linger $USER\n");
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (process.platform === "darwin") {
|
|
334
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
335
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
336
|
+
<plist version="1.0">
|
|
337
|
+
<dict>
|
|
338
|
+
<key>Label</key><string>ai.clearmud.clawcrib</string>
|
|
339
|
+
<key>ProgramArguments</key>
|
|
340
|
+
<array>
|
|
341
|
+
${[process.execPath, ...args].map((a) => ` <string>${a}</string>`).join("\n")}
|
|
342
|
+
</array>
|
|
343
|
+
<key>RunAtLoad</key><true/>
|
|
344
|
+
<key>KeepAlive</key><true/>
|
|
345
|
+
<key>StandardOutPath</key><string>${LOG_FILE}</string>
|
|
346
|
+
<key>StandardErrorPath</key><string>${LOG_FILE}</string>
|
|
347
|
+
</dict>
|
|
348
|
+
</plist>
|
|
349
|
+
`;
|
|
350
|
+
const dir = path.join(os.homedir(), "Library", "LaunchAgents");
|
|
351
|
+
mkdirSync(dir, { recursive: true });
|
|
352
|
+
const file = path.join(dir, "ai.clearmud.clawcrib.plist");
|
|
353
|
+
writeFileSync(file, plist);
|
|
354
|
+
console.log(`\n Wrote ${file}\n`);
|
|
355
|
+
console.log(" Enable it (starts now and on every login):");
|
|
356
|
+
console.log(` launchctl load -w ${file}\n`);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
console.error(`\n install-service supports linux (systemd) and macOS (launchd), not ${process.platform}.\n`);
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function cmdUninstallService() {
|
|
365
|
+
const file =
|
|
366
|
+
process.platform === "linux"
|
|
367
|
+
? path.join(os.homedir(), ".config", "systemd", "user", "clawcrib.service")
|
|
368
|
+
: path.join(os.homedir(), "Library", "LaunchAgents", "ai.clearmud.clawcrib.plist");
|
|
369
|
+
if (!existsSync(file)) {
|
|
370
|
+
console.log("\n No service file installed.\n");
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
console.log(`\n Disable it first:`);
|
|
374
|
+
console.log(
|
|
375
|
+
process.platform === "linux"
|
|
376
|
+
? " systemctl --user disable --now clawcrib"
|
|
377
|
+
: ` launchctl unload -w ${file}`
|
|
378
|
+
);
|
|
379
|
+
rmSync(file, { force: true });
|
|
380
|
+
console.log(`\n Removed ${file}\n`);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function cmdRun() {
|
|
384
|
+
const child = spawnServer(false);
|
|
385
|
+
child.stdout.on("data", () => {}); // keep Next's own listen log quiet; we print our own
|
|
386
|
+
|
|
387
|
+
waitForServer(url).then(async (up) => {
|
|
388
|
+
if (!up) {
|
|
389
|
+
console.error("ClawCrib server did not come up within 30s.");
|
|
390
|
+
child.kill();
|
|
391
|
+
process.exit(1);
|
|
392
|
+
}
|
|
393
|
+
console.log(`\n ClawCrib v${pkg.version}`);
|
|
394
|
+
console.log(` Crib: ${url}`);
|
|
395
|
+
console.log(` Mode: ${mode}`);
|
|
396
|
+
await printDetails();
|
|
397
|
+
console.log(`\n Serving. Press Ctrl-C to stop.`);
|
|
398
|
+
console.log(` Prefer it always-on? clawcrib start (background)\n`);
|
|
399
|
+
|
|
400
|
+
// A headless box has no browser to open; spawning xdg-open just fails quietly.
|
|
401
|
+
const headless =
|
|
402
|
+
process.platform === "linux" && !process.env.DISPLAY && !process.env.WAYLAND_DISPLAY;
|
|
403
|
+
if (opts.open && !headless) openBrowser(url);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
const shutdown = () => {
|
|
407
|
+
child.kill("SIGTERM");
|
|
408
|
+
process.exit(0);
|
|
409
|
+
};
|
|
410
|
+
process.on("SIGINT", shutdown);
|
|
411
|
+
process.on("SIGTERM", shutdown);
|
|
412
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
switch (opts.cmd) {
|
|
416
|
+
case "start":
|
|
417
|
+
await cmdStart();
|
|
418
|
+
break;
|
|
419
|
+
case "stop":
|
|
420
|
+
await cmdStop();
|
|
421
|
+
break;
|
|
422
|
+
case "restart":
|
|
423
|
+
await cmdStop();
|
|
424
|
+
await cmdStart();
|
|
425
|
+
break;
|
|
426
|
+
case "status":
|
|
427
|
+
await cmdStatus();
|
|
428
|
+
break;
|
|
429
|
+
case "install-service":
|
|
430
|
+
cmdInstallService();
|
|
431
|
+
break;
|
|
432
|
+
case "uninstall-service":
|
|
433
|
+
cmdUninstallService();
|
|
434
|
+
break;
|
|
435
|
+
default:
|
|
436
|
+
cmdRun();
|
|
437
|
+
}
|
package/dist/.next/BUILD_ID
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
7d4fjIFyjViUDWgLnLDuG
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"static/chunks/a6dad97d9634a72d.js"
|
|
8
8
|
],
|
|
9
9
|
"lowPriorityFiles": [
|
|
10
|
-
"static/
|
|
11
|
-
"static/
|
|
10
|
+
"static/7d4fjIFyjViUDWgLnLDuG/_ssgManifest.js",
|
|
11
|
+
"static/7d4fjIFyjViUDWgLnLDuG/_buildManifest.js"
|
|
12
12
|
],
|
|
13
13
|
"rootMainFiles": [
|
|
14
14
|
"static/chunks/251e16428085edaf.js",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<!DOCTYPE html><!--
|
|
2
|
-
@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/251e16428085edaf.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"ViewportBoundary\"]\n9:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"MetadataBoundary\"]\nb:I[68027,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"
|
|
1
|
+
<!DOCTYPE html><!--7d4fjIFyjViUDWgLnLDuG--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/251e16428085edaf.js"/><script src="/_next/static/chunks/f188e57e58a39d0f.js" async=""></script><script src="/_next/static/chunks/045c83caa4d15373.js" async=""></script><script src="/_next/static/chunks/619d93506b5beb32.js" async=""></script><script src="/_next/static/chunks/82abf2d65f5428ae.js" async=""></script><script src="/_next/static/chunks/turbopack-aadb2fcebd6885bc.js" async=""></script><script src="/_next/static/chunks/ff1a16fafef87110.js" async=""></script><script src="/_next/static/chunks/0bd6498bda341889.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
|
|
2
|
+
@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/251e16428085edaf.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"ViewportBoundary\"]\n9:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"MetadataBoundary\"]\nb:I[68027,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"7d4fjIFyjViUDWgLnLDuG\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/ff1a16fafef87110.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0bd6498bda341889.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
7:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"ViewportBoundary"]
|
|
7
7
|
9:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"MetadataBoundary"]
|
|
8
8
|
b:I[68027,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"default"]
|
|
9
|
-
0:{"P":null,"b":"
|
|
9
|
+
0:{"P":null,"b":"7d4fjIFyjViUDWgLnLDuG","c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":["$","title",null,{"children":"500: Internal Server Error."}]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"lineHeight":"48px"},"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","paddingRight":23,"fontSize":24,"fontWeight":500,"verticalAlign":"top"},"children":"500"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"28px"},"children":"Internal Server Error."}]}]]}]}]}]]}],[["$","script","script-0",{"src":"/_next/static/chunks/ff1a16fafef87110.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/0bd6498bda341889.js","async":true,"nonce":"$undefined"}]],["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L7",null,{"children":"$L8"}],["$","div",null,{"hidden":true,"children":["$","$L9",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$La"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$b","$undefined"],"S":true}
|
|
10
10
|
8:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
|
11
11
|
6:null
|
|
12
12
|
a:[]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
1:"$Sreact.fragment"
|
|
2
2
|
2:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"OutletBoundary"]
|
|
3
3
|
3:"$Sreact.suspense"
|
|
4
|
-
0:{"buildId":"
|
|
4
|
+
0:{"buildId":"7d4fjIFyjViUDWgLnLDuG","rsc":["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":["$","title",null,{"children":"500: Internal Server Error."}]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"lineHeight":"48px"},"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","paddingRight":23,"fontSize":24,"fontWeight":500,"verticalAlign":"top"},"children":"500"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"28px"},"children":"Internal Server Error."}]}]]}]}]}]]}],[["$","script","script-0",{"src":"/_next/static/chunks/ff1a16fafef87110.js","async":true}],["$","script","script-1",{"src":"/_next/static/chunks/0bd6498bda341889.js","async":true}]],["$","$L2",null,{"children":["$","$3",null,{"name":"Next.MetadataOutlet","children":"$@4"}]}]]}],"loading":null,"isPartial":false}
|
|
5
5
|
4:null
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
7:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"ViewportBoundary"]
|
|
7
7
|
9:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"MetadataBoundary"]
|
|
8
8
|
b:I[68027,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"default"]
|
|
9
|
-
0:{"P":null,"b":"
|
|
9
|
+
0:{"P":null,"b":"7d4fjIFyjViUDWgLnLDuG","c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":["$","title",null,{"children":"500: Internal Server Error."}]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"lineHeight":"48px"},"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","paddingRight":23,"fontSize":24,"fontWeight":500,"verticalAlign":"top"},"children":"500"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"28px"},"children":"Internal Server Error."}]}]]}]}]}]]}],[["$","script","script-0",{"src":"/_next/static/chunks/ff1a16fafef87110.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/0bd6498bda341889.js","async":true,"nonce":"$undefined"}]],["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L7",null,{"children":"$L8"}],["$","div",null,{"hidden":true,"children":["$","$L9",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$La"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$b","$undefined"],"S":true}
|
|
10
10
|
8:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
|
11
11
|
6:null
|
|
12
12
|
a:[]
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
2:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"ViewportBoundary"]
|
|
3
3
|
3:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"MetadataBoundary"]
|
|
4
4
|
4:"$Sreact.suspense"
|
|
5
|
-
0:{"buildId":"
|
|
5
|
+
0:{"buildId":"7d4fjIFyjViUDWgLnLDuG","rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"loading":null,"isPartial":false}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
1:"$Sreact.fragment"
|
|
2
2
|
2:I[39756,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"default"]
|
|
3
3
|
3:I[37457,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/0bd6498bda341889.js"],"default"]
|
|
4
|
-
0:{"buildId":"
|
|
4
|
+
0:{"buildId":"7d4fjIFyjViUDWgLnLDuG","rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"loading":null,"isPartial":false}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0:{"buildId":"
|
|
1
|
+
0:{"buildId":"7d4fjIFyjViUDWgLnLDuG","tree":{"name":"","paramType":null,"paramKey":"","hasRuntimePrefetch":false,"slots":{"children":{"name":"__PAGE__","paramType":null,"paramKey":"__PAGE__","hasRuntimePrefetch":false,"slots":null,"isRootLayout":false}},"isRootLayout":false},"staleTime":300}
|