agentroam 0.2.0-preview.2 → 0.2.0-preview.4
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/README.md +12 -11
- package/dist/args.js +24 -8
- package/dist/args.test.js +25 -1
- package/dist/cli.js +112 -52
- package/dist/cloudflared/bundled-asset.js +37 -0
- package/dist/cloudflared/bundled-asset.test.js +50 -0
- package/dist/cloudflared/installer.js +83 -40
- package/dist/cloudflared/installer.test.js +63 -4
- package/dist/cloudflared/manifest.js +3 -5
- package/dist/tunnel/child-process.js +23 -0
- package/dist/tunnel/cloudflare-provider.js +59 -8
- package/dist/tunnel/cloudflare-provider.test.js +33 -0
- package/dist/tunnel/custom-command-provider.js +54 -4
- package/dist/tunnel/pinggy-provider.js +84 -0
- package/dist/tunnel/pinggy-provider.test.js +40 -0
- package/dist/tunnel/proxy-settings.js +141 -0
- package/dist/tunnel/proxy-settings.test.js +111 -0
- package/dist/tunnel/public-readiness.js +82 -0
- package/dist/tunnel/public-readiness.test.js +104 -0
- package/dist/tunnel/relay-orchestrator.js +43 -0
- package/dist/tunnel/relay-orchestrator.test.js +72 -0
- package/package.json +29 -8
- package/runtime/.next/BUILD_ID +1 -1
- package/runtime/.next/app-build-manifest.json +4 -4
- package/runtime/.next/app-path-routes-manifest.json +1 -1
- package/runtime/.next/build-manifest.json +7 -7
- package/runtime/.next/prerender-manifest.json +1 -1
- package/runtime/.next/react-loadable-manifest.json +2 -2
- package/runtime/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/runtime/.next/server/app/_not-found.html +1 -1
- package/runtime/.next/server/app/_not-found.rsc +1 -1
- package/runtime/.next/server/app/api/agent/abort/route.js +1 -1
- package/runtime/.next/server/app/api/agent/answer/route.js +1 -1
- package/runtime/.next/server/app/api/agent/model/route.js +1 -0
- package/runtime/.next/server/app/api/agent/model/route.js.nft.json +1 -0
- package/runtime/.next/server/app/api/agent/model.body +1 -0
- package/runtime/.next/server/app/api/agent/model.meta +1 -0
- package/runtime/.next/server/app/api/agent/run/route.js +1 -1
- package/runtime/.next/server/app/api/agent/steer/route.js +1 -0
- package/runtime/.next/server/app/api/agent/steer/route.js.nft.json +1 -0
- package/runtime/.next/server/app/api/agent/stream/route.js +3 -2
- package/runtime/.next/server/app/api/mcp/connect/route.js +1 -1
- package/runtime/.next/server/app/api/plugins/load/route.js +1 -1
- package/runtime/.next/server/app/api/remote-tools/register/route.js +1 -1
- package/runtime/.next/server/app/api/sessions/[id]/route.js +1 -1
- package/runtime/.next/server/app/api/sessions/route.js +1 -1
- package/runtime/.next/server/app/api/skills/route.js +1 -1
- package/runtime/.next/server/app/api/tools/route.js +1 -1
- package/runtime/.next/server/app/api/web-auth/login/route.js +1 -1
- package/runtime/.next/server/app/api/web-auth/logout/route.js +1 -1
- package/runtime/.next/server/app/api/web-auth/revoke-all/route.js +1 -1
- package/runtime/.next/server/app/api/web-auth/setup/route.js +1 -1
- package/runtime/.next/server/app/api/web-auth/status/route.js +1 -1
- package/runtime/.next/server/app/api/web-console/bootstrap/route.js +1 -1
- package/runtime/.next/server/app/api/web-console/device-state/route.js +1 -1
- package/runtime/.next/server/app/api/web-console/history/route.js +1 -1
- package/runtime/.next/server/app/api/web-console/history/route.js.nft.json +1 -1
- package/runtime/.next/server/app/api/web-console/preferences/route.js +1 -1
- package/runtime/.next/server/app/web/page.js +10 -10
- package/runtime/.next/server/app/web/page_client-reference-manifest.js +1 -1
- package/runtime/.next/server/app/web.html +1 -1
- package/runtime/.next/server/app/web.rsc +2 -2
- package/runtime/.next/server/app-paths-manifest.json +15 -13
- package/runtime/.next/server/chunks/322.js +28 -12
- package/runtime/.next/server/middleware-build-manifest.js +1 -1
- package/runtime/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/runtime/.next/server/pages/404.html +1 -1
- package/runtime/.next/server/pages/500.html +1 -1
- package/runtime/.next/server/server-reference-manifest.json +1 -1
- package/runtime/.next/static/chunks/982.9e87a5cc0e6b13cf.js +1 -0
- package/runtime/.next/static/chunks/app/web/page-02e0df331bb14489.js +1 -0
- package/runtime/.next/static/chunks/{main-a7dd8c98b48af038.js → main-30618c50527ce4e9.js} +1 -1
- package/runtime/.next/static/chunks/{webpack-e56f3a1950168597.js → webpack-0c872a6ee48cbbdf.js} +1 -1
- package/runtime/node_modules/.package-lock.json +3 -3
- package/runtime/node_modules/@agent/core/dist/domain/context/ContextLoader.d.ts +2 -0
- package/runtime/node_modules/@agent/core/dist/domain/context/ContextLoader.d.ts.map +1 -1
- package/runtime/node_modules/@agent/core/dist/index.js +114 -12
- package/runtime/node_modules/@agent/core/dist/index.js.map +7 -6
- package/runtime/node_modules/@agent/core/dist/infrastructure/SQLiteAnonymousWebStore.d.ts +13 -0
- package/runtime/node_modules/@agent/core/dist/infrastructure/SQLiteAnonymousWebStore.d.ts.map +1 -0
- package/runtime/node_modules/@agent/core/dist/infrastructure/SQLiteAnonymousWebStore.test.d.ts +2 -0
- package/runtime/node_modules/@agent/core/dist/infrastructure/SQLiteAnonymousWebStore.test.d.ts.map +1 -0
- package/runtime/node_modules/@agent/core/dist/infrastructure/SQLiteDatabase.d.ts.map +1 -1
- package/runtime/node_modules/@agent/core/dist/infrastructure/SQLiteSessionStore.d.ts.map +1 -1
- package/runtime/node_modules/@agent/core/dist/infrastructure/index.d.ts +1 -0
- package/runtime/node_modules/@agent/core/dist/infrastructure/index.d.ts.map +1 -1
- package/runtime/node_modules/node-abi/abi_registry.json +7 -0
- package/runtime/node_modules/node-abi/package.json +1 -1
- package/runtime/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
- package/runtime/package-lock.json +3 -3
- package/runtime/webapp/dist/assets/App-lXIeMH5u.js +52 -0
- package/runtime/webapp/dist/assets/index-BAFMhDtY.js +42 -0
- package/runtime/webapp/dist/assets/index-Beg9M2xI.css +1 -0
- package/runtime/webapp/dist/index.html +17 -0
- package/runtime/webapp/dist/pcm-audio-worklet.js +126 -0
- package/runtime/ws-server.mjs +148 -18
- package/runtime/.next/static/chunks/804.0e20fa702013ffef.js +0 -1
- package/runtime/.next/static/chunks/app/web/page-800bcc7d84eb45e4.js +0 -1
- /package/runtime/.next/static/{47UkTmBGxP5qz2mnMbNEp → dclalTmecO-HMVQvSKG7g}/_buildManifest.js +0 -0
- /package/runtime/.next/static/{47UkTmBGxP5qz2mnMbNEp → dclalTmecO-HMVQvSKG7g}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
class PcmStreamProcessor extends AudioWorkletProcessor {
|
|
2
|
+
constructor() {
|
|
3
|
+
super();
|
|
4
|
+
this.ring = new Float32Array(1);
|
|
5
|
+
this.capacity = 1;
|
|
6
|
+
this.readIndex = 0;
|
|
7
|
+
this.writeIndex = 0;
|
|
8
|
+
this.size = 0;
|
|
9
|
+
this.phase = 0;
|
|
10
|
+
this.inputSampleRate = 24000;
|
|
11
|
+
this.startThreshold = 2880;
|
|
12
|
+
this.generation = null;
|
|
13
|
+
this.playing = false;
|
|
14
|
+
this.inputEnded = false;
|
|
15
|
+
this.underrunReported = false;
|
|
16
|
+
this.terminalReported = false;
|
|
17
|
+
this.port.onmessage = (event) => this.handleMessage(event.data);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
resetBuffer() {
|
|
21
|
+
this.readIndex = 0;
|
|
22
|
+
this.writeIndex = 0;
|
|
23
|
+
this.size = 0;
|
|
24
|
+
this.phase = 0;
|
|
25
|
+
this.playing = false;
|
|
26
|
+
this.inputEnded = false;
|
|
27
|
+
this.underrunReported = false;
|
|
28
|
+
this.terminalReported = false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
handleMessage(message) {
|
|
32
|
+
if (message.type === "start") {
|
|
33
|
+
this.inputSampleRate = message.sampleRate;
|
|
34
|
+
this.capacity = message.sampleRate;
|
|
35
|
+
this.startThreshold = Math.ceil(message.sampleRate * 0.12);
|
|
36
|
+
this.ring = new Float32Array(this.capacity);
|
|
37
|
+
this.generation = message.generation;
|
|
38
|
+
this.resetBuffer();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (message.generation !== this.generation) return;
|
|
42
|
+
if (message.type === "chunk") {
|
|
43
|
+
const samples = message.samples;
|
|
44
|
+
if (!(samples instanceof Float32Array) || samples.length > this.capacity - this.size) {
|
|
45
|
+
const generation = this.generation;
|
|
46
|
+
this.resetBuffer();
|
|
47
|
+
this.generation = null;
|
|
48
|
+
this.port.postMessage({ type: "overflow", generation });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
for (let index = 0; index < samples.length; index += 1) {
|
|
52
|
+
this.ring[this.writeIndex] = samples[index];
|
|
53
|
+
this.writeIndex = (this.writeIndex + 1) % this.capacity;
|
|
54
|
+
}
|
|
55
|
+
this.size += samples.length;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (message.type === "finish") {
|
|
59
|
+
this.inputEnded = true;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (message.type === "flush") {
|
|
63
|
+
const generation = this.generation;
|
|
64
|
+
this.resetBuffer();
|
|
65
|
+
this.generation = null;
|
|
66
|
+
this.port.postMessage({ type: "stopped", generation });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
sampleAt(offset) {
|
|
71
|
+
return this.ring[(this.readIndex + offset) % this.capacity];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
reportDrained() {
|
|
75
|
+
if (this.terminalReported || this.generation === null) return;
|
|
76
|
+
this.terminalReported = true;
|
|
77
|
+
const generation = this.generation;
|
|
78
|
+
this.generation = null;
|
|
79
|
+
this.port.postMessage({ type: "drained", generation });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
process(_inputs, outputs) {
|
|
83
|
+
const output = outputs[0][0];
|
|
84
|
+
output.fill(0);
|
|
85
|
+
if (this.generation === null) return true;
|
|
86
|
+
if (!this.playing) {
|
|
87
|
+
if (this.size >= this.startThreshold || (this.inputEnded && this.size > 0)) {
|
|
88
|
+
this.playing = true;
|
|
89
|
+
this.underrunReported = false;
|
|
90
|
+
} else if (this.inputEnded && this.size === 0) {
|
|
91
|
+
this.reportDrained();
|
|
92
|
+
return true;
|
|
93
|
+
} else {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const ratio = this.inputSampleRate / sampleRate;
|
|
99
|
+
for (let index = 0; index < output.length; index += 1) {
|
|
100
|
+
if (this.size === 0) {
|
|
101
|
+
if (this.inputEnded) this.reportDrained();
|
|
102
|
+
else {
|
|
103
|
+
this.playing = false;
|
|
104
|
+
if (!this.underrunReported) {
|
|
105
|
+
this.underrunReported = true;
|
|
106
|
+
this.port.postMessage({ type: "underrun", generation: this.generation });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
const first = this.sampleAt(0);
|
|
112
|
+
const second = this.size > 1 ? this.sampleAt(1) : first;
|
|
113
|
+
output[index] = first + (second - first) * this.phase;
|
|
114
|
+
this.phase += ratio;
|
|
115
|
+
const consumed = Math.min(Math.floor(this.phase), this.size);
|
|
116
|
+
if (consumed > 0) {
|
|
117
|
+
this.readIndex = (this.readIndex + consumed) % this.capacity;
|
|
118
|
+
this.size -= consumed;
|
|
119
|
+
this.phase -= consumed;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
registerProcessor("pcm-stream-player", PcmStreamProcessor);
|
package/runtime/ws-server.mjs
CHANGED
|
@@ -21,18 +21,19 @@ import os from "node:os";
|
|
|
21
21
|
import path from "node:path";
|
|
22
22
|
import fsSync from "node:fs";
|
|
23
23
|
import fsp from "node:fs/promises";
|
|
24
|
+
import zlib from "node:zlib";
|
|
24
25
|
import next from "next";
|
|
25
26
|
import { WebSocketServer } from "ws";
|
|
26
27
|
import pty from "node-pty";
|
|
27
28
|
import chokidar from "chokidar";
|
|
28
|
-
import {
|
|
29
|
+
import { SQLiteAnonymousWebStore, SQLiteWebConsoleStore } from "@agent/core";
|
|
29
30
|
|
|
30
31
|
const dev = process.env.NODE_ENV !== "production";
|
|
31
32
|
const port = Number(process.env.PORT || 3000);
|
|
32
33
|
const dir = path.dirname(new URL(import.meta.url).pathname);
|
|
33
34
|
|
|
34
35
|
const serverBaseDir = path.resolve(process.env.AGENT_DATA_DIR?.trim() || dir);
|
|
35
|
-
const
|
|
36
|
+
const anonymousWebStore = new SQLiteAnonymousWebStore(serverBaseDir);
|
|
36
37
|
const consoleStore = new SQLiteWebConsoleStore(serverBaseDir);
|
|
37
38
|
consoleStore.markStaleTerminalsExited(new Date().toISOString());
|
|
38
39
|
const roots = (process.env.AGENT_WEB_ROOTS || os.homedir())
|
|
@@ -40,6 +41,18 @@ const roots = (process.env.AGENT_WEB_ROOTS || os.homedir())
|
|
|
40
41
|
.map((p) => path.resolve(p.trim()))
|
|
41
42
|
.filter(Boolean);
|
|
42
43
|
|
|
44
|
+
// bun install drops the executable bit on node-pty's prebuilt spawn-helper,
|
|
45
|
+
// which makes every pty.spawn fail with "posix_spawnp failed". Repair on boot
|
|
46
|
+
// (same fix as packages/cli repairNativeRuntimePermissions, for the dev path).
|
|
47
|
+
try {
|
|
48
|
+
if (process.platform !== "win32") {
|
|
49
|
+
const { createRequire } = await import("node:module");
|
|
50
|
+
const nodePtyRoot = path.dirname(createRequire(import.meta.url).resolve("node-pty/package.json"));
|
|
51
|
+
const helper = path.join(nodePtyRoot, "prebuilds", `${process.platform}-${process.arch}`, "spawn-helper");
|
|
52
|
+
if (fsSync.existsSync(helper) && !(fsSync.statSync(helper).mode & 0o111)) fsSync.chmodSync(helper, 0o755);
|
|
53
|
+
}
|
|
54
|
+
} catch { /* best effort — pty.spawn reports its own error */ }
|
|
55
|
+
|
|
43
56
|
function clampInt(v, min, max, dflt) {
|
|
44
57
|
const n = Math.floor(Number(v));
|
|
45
58
|
if (!Number.isFinite(n)) return dflt;
|
|
@@ -218,6 +231,11 @@ function startTerminal(id, { userId, cols = 80, rows = 24, cwd, command } = {})
|
|
|
218
231
|
p.onExit(({ exitCode }) => {
|
|
219
232
|
session.exited = true;
|
|
220
233
|
if (!session.closed) consoleStore.updateTab(session.id, session.userId, { status: "exited", exitedAt: new Date().toISOString(), lastActiveAt: new Date().toISOString() });
|
|
234
|
+
// Tell attached clients the process is gone — otherwise the tab lives on
|
|
235
|
+
// as an unresponsive zombie (no input, no output) until a page refresh.
|
|
236
|
+
for (const conn of connections) {
|
|
237
|
+
if (conn.attachedTo.has(id)) conn.sendJson({ type: "term:exited", id, code: exitCode });
|
|
238
|
+
}
|
|
221
239
|
for (const cb of [...session.cwdWatchers]) {
|
|
222
240
|
try { cb(null); } catch {}
|
|
223
241
|
}
|
|
@@ -444,6 +462,13 @@ function makeConn(ws) {
|
|
|
444
462
|
frame[0] = 1; frame[1] = 2; frame.writeUInt32BE(channelId, 2); payload.copy(frame, 6);
|
|
445
463
|
ws.send(frame);
|
|
446
464
|
},
|
|
465
|
+
sendTerminalReset(terminalId) {
|
|
466
|
+
if (ws.readyState !== ws.OPEN) return;
|
|
467
|
+
const channelId = assignChannel(this, terminalId);
|
|
468
|
+
const frame = Buffer.allocUnsafe(6);
|
|
469
|
+
frame[0] = 1; frame[1] = 3; frame.writeUInt32BE(channelId, 2);
|
|
470
|
+
ws.send(frame);
|
|
471
|
+
},
|
|
447
472
|
};
|
|
448
473
|
}
|
|
449
474
|
|
|
@@ -514,7 +539,10 @@ const requestHandlers = {
|
|
|
514
539
|
session.cwdWatchers.add(cwdForward);
|
|
515
540
|
conn.cwdForwards.set(id, cwdForward);
|
|
516
541
|
|
|
517
|
-
//
|
|
542
|
+
// Replay scrollback to restore the screen after reconnect. Reset the client
|
|
543
|
+
// pane first: a reconnecting client still holds the old buffer, and
|
|
544
|
+
// appending the replay onto it duplicates all the content.
|
|
545
|
+
conn.sendTerminalReset(id);
|
|
518
546
|
const snap = session.scrollback.snapshot();
|
|
519
547
|
if (snap.byteLength > 0) setImmediate(() => conn.sendTerminal(id, new Uint8Array(snap)));
|
|
520
548
|
|
|
@@ -585,6 +613,8 @@ const requestHandlers = {
|
|
|
585
613
|
return null;
|
|
586
614
|
},
|
|
587
615
|
|
|
616
|
+
"ping": async () => ({ pong: true, t: Date.now() }),
|
|
617
|
+
|
|
588
618
|
"term:kill": async (msg, conn) => {
|
|
589
619
|
const id = msg.id || conn.focusId;
|
|
590
620
|
if (!id) return null;
|
|
@@ -593,7 +623,9 @@ const requestHandlers = {
|
|
|
593
623
|
try { session.pty.kill(); } catch {}
|
|
594
624
|
consoleStore.updateTab(id, conn.principal.userId, { status: "closed", closedAt: new Date().toISOString(), lastActiveAt: new Date().toISOString() });
|
|
595
625
|
detachTerminal(conn, id);
|
|
596
|
-
|
|
626
|
+
// Acknowledge (not fire-and-forget) so a client awaiting this rpc resolves
|
|
627
|
+
// immediately instead of hanging until its 15s timeout.
|
|
628
|
+
return { closed: true };
|
|
597
629
|
},
|
|
598
630
|
|
|
599
631
|
"fs:list": async (msg, conn) => ({ entries: await fsList(msg.path, conn.principal.userId) }),
|
|
@@ -670,17 +702,113 @@ const handle = app.getRequestHandler();
|
|
|
670
702
|
|
|
671
703
|
await app.prepare();
|
|
672
704
|
|
|
673
|
-
|
|
674
|
-
|
|
705
|
+
// ── static hosting for the web shell (@agent/webapp build) at /app ─────────
|
|
706
|
+
// Built by `bun run --cwd packages/webapp build`; override the artifact dir
|
|
707
|
+
// with AGENT_WEB_APP_DIST when staging for the CLI/tunnel runtime.
|
|
708
|
+
// Resolution order: env override → staged CLI runtime layout → repo workspace.
|
|
709
|
+
const webAppDistCandidates = [
|
|
710
|
+
process.env.AGENT_WEB_APP_DIST?.trim(),
|
|
711
|
+
path.join(dir, "webapp", "dist"),
|
|
712
|
+
path.join(dir, "..", "webapp", "dist"),
|
|
713
|
+
].filter(Boolean).map((candidate) => path.resolve(candidate));
|
|
714
|
+
const webAppDist = webAppDistCandidates.find((candidate) => fsSync.existsSync(candidate))
|
|
715
|
+
?? webAppDistCandidates[webAppDistCandidates.length - 1];
|
|
716
|
+
|
|
717
|
+
// Build id = entry chunk filename; clients compare against their own script
|
|
718
|
+
// URL and force-reload themselves when a newer build has been deployed.
|
|
719
|
+
let webAppBuildId = "";
|
|
720
|
+
function refreshWebAppBuildId() {
|
|
721
|
+
try {
|
|
722
|
+
const html = fsSync.readFileSync(path.join(webAppDist, "index.html"), "utf8");
|
|
723
|
+
const match = html.match(/assets\/(index-[^"']+\.js)/);
|
|
724
|
+
if (match) {
|
|
725
|
+
webAppBuildId = match[1];
|
|
726
|
+
globalThis.__webAppBuildId = webAppBuildId;
|
|
727
|
+
}
|
|
728
|
+
} catch { /* keep previous */ }
|
|
729
|
+
}
|
|
730
|
+
refreshWebAppBuildId();
|
|
731
|
+
setInterval(refreshWebAppBuildId, 30000);
|
|
732
|
+
|
|
733
|
+
const WEB_APP_MIME = {
|
|
734
|
+
".html": "text/html; charset=utf-8",
|
|
735
|
+
".js": "text/javascript",
|
|
736
|
+
".mjs": "text/javascript",
|
|
737
|
+
".css": "text/css",
|
|
738
|
+
".json": "application/json",
|
|
739
|
+
".svg": "image/svg+xml",
|
|
740
|
+
".png": "image/png",
|
|
741
|
+
".jpg": "image/jpeg",
|
|
742
|
+
".jpeg": "image/jpeg",
|
|
743
|
+
".gif": "image/gif",
|
|
744
|
+
".webp": "image/webp",
|
|
745
|
+
".ico": "image/x-icon",
|
|
746
|
+
".woff": "font/woff",
|
|
747
|
+
".woff2": "font/woff2",
|
|
748
|
+
".map": "application/json",
|
|
749
|
+
};
|
|
675
750
|
|
|
676
|
-
function
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
751
|
+
async function serveWebApp(req, res) {
|
|
752
|
+
const url = new URL(req.url, `http://${req.headers.host || "localhost"}`);
|
|
753
|
+
if (url.pathname !== "/app" && !url.pathname.startsWith("/app/")) return false;
|
|
754
|
+
const remoteAddr = req.socket.remoteAddress;
|
|
755
|
+
// The build uses relative asset URLs — redirect to the trailing-slash form
|
|
756
|
+
// so ./assets/... resolves under /app/ instead of the site root.
|
|
757
|
+
if (url.pathname === "/app") {
|
|
758
|
+
console.log(`[web-app] ${remoteAddr} → /app (redirect)`);
|
|
759
|
+
res.writeHead(301, { location: "/app/" + url.search }).end();
|
|
760
|
+
return true;
|
|
680
761
|
}
|
|
681
|
-
|
|
762
|
+
const relative = url.pathname.replace(/^\/app\/?/, "") || "index.html";
|
|
763
|
+
if (relative === "index.html") console.log(`[web-app] ${remoteAddr} → /app/ shell`);
|
|
764
|
+
let filePath = path.resolve(webAppDist, relative);
|
|
765
|
+
if (filePath !== webAppDist && !filePath.startsWith(webAppDist + path.sep)) {
|
|
766
|
+
res.writeHead(403).end();
|
|
767
|
+
return true;
|
|
768
|
+
}
|
|
769
|
+
try {
|
|
770
|
+
const stats = await fsp.stat(filePath);
|
|
771
|
+
if (stats.isDirectory()) filePath = path.join(filePath, "index.html");
|
|
772
|
+
} catch {
|
|
773
|
+
// Unknown extension-less path → shell (deep links); missing assets → 404.
|
|
774
|
+
if (!path.extname(relative)) filePath = path.join(webAppDist, "index.html");
|
|
775
|
+
else {
|
|
776
|
+
res.writeHead(404).end("Not found");
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
try {
|
|
781
|
+
let data = await fsp.readFile(filePath);
|
|
782
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
783
|
+
const headers = {
|
|
784
|
+
"content-type": WEB_APP_MIME[ext] || "application/octet-stream",
|
|
785
|
+
// Hashed filenames change per build — never let devices pin old bundles.
|
|
786
|
+
"cache-control": "no-cache",
|
|
787
|
+
};
|
|
788
|
+
// Compress the big text assets — remote links (tailscale relay, tunnels)
|
|
789
|
+
// are the slow path for phones.
|
|
790
|
+
const compressible = [".js", ".mjs", ".css", ".html", ".json", ".svg", ".map"].includes(ext)
|
|
791
|
+
&& String(req.headers["accept-encoding"] || "").includes("gzip")
|
|
792
|
+
&& data.length > 1024;
|
|
793
|
+
if (compressible) {
|
|
794
|
+
data = zlib.gzipSync(data);
|
|
795
|
+
headers["content-encoding"] = "gzip";
|
|
796
|
+
}
|
|
797
|
+
res.writeHead(200, headers);
|
|
798
|
+
res.end(data);
|
|
799
|
+
} catch {
|
|
800
|
+
res.writeHead(404).end("Not found");
|
|
801
|
+
}
|
|
802
|
+
return true;
|
|
682
803
|
}
|
|
683
804
|
|
|
805
|
+
const server = createServer((req, res) => {
|
|
806
|
+
void serveWebApp(req, res).then((handled) => {
|
|
807
|
+
if (!handled) handle(req, res);
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
const wss = new WebSocketServer({ noServer: true, maxPayload: 1024 * 1024 });
|
|
811
|
+
|
|
684
812
|
function originAllowed(req) {
|
|
685
813
|
const origin = req.headers.origin;
|
|
686
814
|
if (!origin) return false;
|
|
@@ -696,14 +824,13 @@ server.on("upgrade", (req, socket, head) => {
|
|
|
696
824
|
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
697
825
|
if (url.pathname !== "/ws") return; // leave HMR etc. to Next's own listeners
|
|
698
826
|
if (!originAllowed(req)) { socket.write("HTTP/1.1 403 Forbidden\r\n\r\n"); socket.destroy(); return; }
|
|
699
|
-
const rawToken = cookieValue(req.headers.cookie, "customer_agent_session");
|
|
700
827
|
const nonce = url.searchParams.get("nonce") || "";
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
wss.handleUpgrade(req, socket, head, (ws) => ws.close(error?.code === "UNAUTHENTICATED" ? 4001 : 4003, "authentication failed"));
|
|
828
|
+
const userId = anonymousWebStore.consumeWsNonce(nonce);
|
|
829
|
+
if (!userId) {
|
|
830
|
+
wss.handleUpgrade(req, socket, head, (ws) => ws.close(4003, "invalid nonce"));
|
|
705
831
|
return;
|
|
706
832
|
}
|
|
833
|
+
const principal = { userId, username: "local", deviceId: "browser" };
|
|
707
834
|
wss.handleUpgrade(req, socket, head, (ws) => wss.emit("connection", ws, req, principal));
|
|
708
835
|
});
|
|
709
836
|
|
|
@@ -719,7 +846,10 @@ wss.on("connection", (ws, _req, principal) => {
|
|
|
719
846
|
if (frame.byteLength < 6 || frame[0] !== 1 || frame[1] !== 1) return;
|
|
720
847
|
const terminalId = conn.channelToTerminal.get(frame.readUInt32BE(2));
|
|
721
848
|
if (!terminalId) return;
|
|
722
|
-
|
|
849
|
+
// Input frames race the terminal's own close (in-flight keystrokes while
|
|
850
|
+
// the tab tears down) — drop them silently instead of throwing.
|
|
851
|
+
const session = terminals.get(terminalId);
|
|
852
|
+
if (!session || session.exited || session.userId !== conn.principal?.userId) return;
|
|
723
853
|
if (session.inputOwner && session.inputOwner !== conn.id) return;
|
|
724
854
|
session.inputOwner = conn.id;
|
|
725
855
|
session.pty.write(frame.subarray(6).toString("utf8"));
|
|
@@ -753,6 +883,6 @@ server.listen(port, () => {
|
|
|
753
883
|
console.log(`▲ AgentRoam web gateway`);
|
|
754
884
|
console.log(` local http://localhost:${port}/web`);
|
|
755
885
|
for (const u of urls) console.log(` network ${u}`);
|
|
756
|
-
console.log(` auth
|
|
886
|
+
console.log(` auth passwordless local console`);
|
|
757
887
|
console.log(` roots ${roots.join(" : ")}`);
|
|
758
888
|
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[804],{6584:function(e,t,r){"use strict";var n,l;e.exports=(null==(n=r.g.process)?void 0:n.env)&&"object"==typeof(null==(l=r.g.process)?void 0:l.env)?r.g.process:r(3307)},3307:function(e){!function(){var t={229:function(e){var t,r,n,l=e.exports={};function i(){throw Error("setTimeout has not been defined")}function o(){throw Error("clearTimeout has not been defined")}function u(e){if(t===setTimeout)return setTimeout(e,0);if((t===i||!t)&&setTimeout)return t=setTimeout,setTimeout(e,0);try{return t(e,0)}catch(r){try{return t.call(null,e,0)}catch(r){return t.call(this,e,0)}}}!function(){try{t="function"==typeof setTimeout?setTimeout:i}catch(e){t=i}try{r="function"==typeof clearTimeout?clearTimeout:o}catch(e){r=o}}();var c=[],a=!1,s=-1;function d(){a&&n&&(a=!1,n.length?c=n.concat(c):s=-1,c.length&&f())}function f(){if(!a){var e=u(d);a=!0;for(var t=c.length;t;){for(n=c,c=[];++s<t;)n&&n[s].run();s=-1,t=c.length}n=null,a=!1,function(e){if(r===clearTimeout)return clearTimeout(e);if((r===o||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(e);try{r(e)}catch(t){try{return r.call(null,e)}catch(t){return r.call(this,e)}}}(e)}}function p(e,t){this.fun=e,this.array=t}function v(){}l.nextTick=function(e){var t=Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)t[r-1]=arguments[r];c.push(new p(e,t)),1!==c.length||a||u(f)},p.prototype.run=function(){this.fun.apply(null,this.array)},l.title="browser",l.browser=!0,l.env={},l.argv=[],l.version="",l.versions={},l.on=v,l.addListener=v,l.once=v,l.off=v,l.removeListener=v,l.removeAllListeners=v,l.emit=v,l.prependListener=v,l.prependOnceListener=v,l.listeners=function(e){return[]},l.binding=function(e){throw Error("process.binding is not supported")},l.cwd=function(){return"/"},l.chdir=function(e){throw Error("process.chdir is not supported")},l.umask=function(){return 0}}},r={};function n(e){var l=r[e];if(void 0!==l)return l.exports;var i=r[e]={exports:{}},o=!0;try{t[e](i,i.exports,n),o=!1}finally{o&&delete r[e]}return i.exports}n.ab="//";var l=n(229);e.exports=l}()},1587:function(e,t,r){"use strict";r.r(t),r.d(t,{default:function(){return s}});var n=r(1996),l=r(6121),i=r(8918),o=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(0===e.css.cell.width||0===e.css.cell.height)return;let t=0===this._terminal.options.scrollback?0:this._terminal.options.overviewRuler?.width||14,r=window.getComputedStyle(this._terminal.element.parentElement),n=parseInt(r.getPropertyValue("height")),l=Math.max(0,parseInt(r.getPropertyValue("width"))),i=window.getComputedStyle(this._terminal.element),o={top:parseInt(i.getPropertyValue("padding-top")),bottom:parseInt(i.getPropertyValue("padding-bottom")),right:parseInt(i.getPropertyValue("padding-right")),left:parseInt(i.getPropertyValue("padding-left"))},u=o.top+o.bottom;return{cols:Math.max(2,Math.floor((l-(o.right+o.left)-t)/e.css.cell.width)),rows:Math.max(1,Math.floor((n-u)/e.css.cell.height))}}};r(8810);let u={minWidth:34,height:30,borderRadius:7,fontSize:11.5,padding:"0 7px",touchAction:"none",userSelect:"none",flexShrink:0},c=["ctrl","esc","tab","up","down","left","right","pgup","pgdown","end","enter","pipe","tilde","dash","slash","ctrlc","ctrld","ctrll","hide"],a={ctrl:"Ctrl",esc:"Esc",tab:"Tab",up:"↑",down:"↓",left:"←",right:"→",pgup:"Pg↑",pgdown:"Pg↓",end:"End",enter:"↵",pipe:"|",tilde:"~",dash:"-",slash:"/",ctrlc:"^C",ctrld:"^D",ctrll:"^L",hide:"隐藏"};function s(e){let{terminalId:t,title:r,visible:s,state:d,rpc:f,onEvent:p,onTerminalData:v,sendTerminalInput:m,keyOrder:h,keybarHidden:y,onKeyOrderChange:b,onKeybarHiddenChange:g,onCwdChange:w,initialScrollLine:x,onScrollLineChange:k,onRegisterFill:E,terminalTheme:T}=e,L=(0,l.useRef)(null),M=(0,l.useRef)(null),C=(0,l.useRef)(null),[R,S]=(0,l.useState)(!1),[Y,D]=(0,l.useState)(null),[P,I]=(0,l.useState)(!1),A=(0,l.useRef)(!1),[_,X]=(0,l.useState)(!1),z=(0,l.useRef)(t),B=(0,l.useRef)(null),H=(0,l.useRef)(null),W=(0,l.useRef)(()=>{}),j=(0,l.useRef)(null),O=(0,l.useRef)(!0),q=(0,l.useRef)(0),N=(0,l.useRef)(null),U=(0,l.useRef)(null),V=(0,l.useRef)(!1),K=(0,l.useRef)(null),F=(0,l.useRef)(0),Z=(0,l.useRef)(null),G=(0,l.useRef)(!1),J=(0,l.useRef)(!1),[Q,$]=(0,l.useState)(null),ee=(0,l.useCallback)(e=>{null!=B.current&&m(B.current,e)||f("term:input",{id:z.current,data:e}).catch(()=>{})},[f,m]);(0,l.useRef)(ee).current=ee;let et=(0,l.useRef)(()=>{}),er=(0,l.useRef)(T);er.current=T;let en={...u,border:"1px solid ".concat(T.keybar.keyBorder),background:T.keybar.keyBg,color:T.keybar.keyText},el=(0,l.useRef)(E);el.current=E;let ei=(0,l.useCallback)(e=>{(async()=>{var t,r;O.current=!0,null===(t=M.current)||void 0===t||t.scrollToBottom();try{await f("term:focus",{id:z.current}),I(!1)}catch(e){if((null==e?void 0:e.code)==="EWRITELOCK"){I(!0);return}}null===(r=M.current)||void 0===r||r.focus(),ee("\x15"),window.setTimeout(()=>{let t=M.current;t&&("function"==typeof t.paste?t.paste(e):ee(e))},20)})()},[f,ee]);et.current=ei;let eo=(0,l.useCallback)(()=>{let e=M.current;e&&k&&k(O.current?e.buffer.active.baseY:e.buffer.active.viewportY)},[k]),eu=(0,l.useRef)(eo);eu.current=eo;let ec=(0,l.useRef)(e=>{let t=M.current;t&&"alternate"!==t.buffer.active.type&&0!==e&&(O.current=!1,t.scrollLines(e),q.current=t.buffer.active.viewportY,O.current=t.buffer.active.viewportY>=t.buffer.active.baseY,eu.current())}),ea=(0,l.useRef)(e=>{let t=M.current;t&&"alternate"!==t.buffer.active.type&&0!==e&&(e<0&&(O.current=!1),t.scrollPages(e),q.current=t.buffer.active.viewportY,O.current=t.buffer.active.viewportY>=t.buffer.active.baseY,eu.current())}),es=(0,l.useCallback)(()=>{let e=M.current;if(e&&null!=x){if(x>=e.buffer.active.baseY){O.current=!0,e.scrollToBottom();return}O.current=!1,q.current=x,e.scrollToLine(x)}},[x]);(0,l.useEffect)(()=>{var e;let t;let r=new i.o({fontFamily:'"SF Mono", Menlo, Consolas, monospace',fontSize:window.innerWidth<=768?11:12,lineHeight:1.12,letterSpacing:0,cursorBlink:!0,allowProposedApi:!0,scrollback:5e3,scrollOnUserInput:!1,smoothScrollDuration:0,scrollSensitivity:1,theme:er.current.xterm}),n=new o;r.loadAddon(n),r.open(L.current),M.current=r,C.current=n;try{n.fit()}catch(e){}let l=r.parser.registerOscHandler(7,e=>{try{let t=e.startsWith("file://")?e:"file://".concat(e),r=new URL(t);if("file:"!==r.protocol)return!1;let n=decodeURIComponent(r.pathname);return/^\/[A-Za-z]:\//.test(n)&&(n=n.slice(1)),(n.startsWith("/")||/^[A-Za-z]:\//.test(n))&&(null==w||w(n),f("term:set-cwd",{id:z.current,cwd:n}).catch(()=>{})),!0}catch(e){return!1}});W.current=e=>{r.write(e,()=>{var e;if("alternate"===r.buffer.active.type)return;let t=null===(e=L.current)||void 0===e?void 0:e.querySelector(".xterm");(null==t?void 0:t.style.transform)&&(t.style.transform="",t.style.willChange=""),O.current?r.scrollToBottom():r.scrollToLine(Math.min(q.current,r.buffer.active.baseY))})},r.onData(e=>{if(!d.connected||J.current&&("\x1b[A"===e||"\x1b[B"===e||"\x1b[5~"===e||"\x1b[6~"===e))return;let t=Date.now(),n=Z.current;if(!n||n.text!==e||!(t-n.at<500)){if(Z.current={text:e,at:t},O.current=!0,"alternate"!==r.buffer.active.type&&r.scrollToBottom(),eo(),A.current&&1===e.length){let t=e.toLowerCase().charCodeAt(0);t>=97&&t<=122?e=String.fromCharCode(t-96):" "===e?e="\0":"["===e?e="\x1b":"\\"===e?e="\x1c":"]"===e&&(e="\x1d"),ed()}ee(e)}}),r.onResize(e=>{let{cols:r,rows:n}=e;clearTimeout(t),t=setTimeout(()=>{f("term:resize",{id:z.current,cols:r,rows:n}).catch(()=>{})},120)});let u=r.onScroll(e=>{let t=e>=r.buffer.active.baseY;O.current=t,t||(q.current=e),eu.current()});r.attachCustomKeyEventHandler(e=>{if("alternate"===r.buffer.active.type||"keydown"!==e.type)return!0;let t=r.buffer.active.viewportY>=r.buffer.active.baseY;return"ArrowUp"!==e.key&&"ArrowDown"!==e.key&&"PageUp"!==e.key&&"PageDown"!==e.key||!!t&&!J.current||("ArrowUp"===e.key?(ec.current(-1),e.preventDefault(),!1):"ArrowDown"===e.key?(ec.current(1),e.preventDefault(),!1):"PageUp"===e.key?(ea.current(-1),e.preventDefault(),!1):"PageDown"!==e.key||(ea.current(1),e.preventDefault(),!1))}),r.attachCustomWheelEventHandler(e=>{var t,n;if("alternate"===r.buffer.active.type||!e.deltaY)return!0;let l=Math.max(8,(null!==(n=null===(t=L.current)||void 0===t?void 0:t.clientHeight)&&void 0!==n?n:14*r.rows)/Math.max(r.rows,1)),i=Math.trunc(e.deltaY/l)||(e.deltaY>0?1:-1);return ec.current(i),!1});let c=null,a=0,s=0,p=0,v=0,m=!1,h="pending",y=0,b=null!==(e=r.element)&&void 0!==e?e:L.current,g=e=>{if("touch"===e.pointerType&&e.isPrimary){c=e.pointerId,a=e.clientX,s=e.clientY,p=e.clientY,v=0,h="pending",m=!0,J.current=!0,"alternate"!==r.buffer.active.type&&(O.current=!1);try{null==b||b.setPointerCapture(e.pointerId)}catch(e){}}},x=e=>{var t;if(!m||e.pointerId!==c)return;let n=e.clientX-a,l=e.clientY-s;if("pending"===h&&Math.max(Math.abs(n),Math.abs(l))>8&&(h=Math.abs(n)>1.2*Math.abs(l)?"horizontal":"vertical"),"vertical"!==h)return;let i=p-e.clientY;if(p=e.clientY,v+=i,"alternate"===r.buffer.active.type){let t=null==b?void 0:b.getBoundingClientRect(),n=t?Math.max(1,Math.min(r.cols,Math.floor((e.clientX-t.left)/Math.max(t.width,1)*r.cols)+1)):1,l=t?Math.max(1,Math.min(r.rows,Math.floor((e.clientY-t.top)/Math.max(t.height,1)*r.rows)+1)):1;if("none"!==r.modes.mouseTrackingMode){let e=Math.trunc(v/18),t=performance.now();if(0!==e&&t-y>=32){let r=Math.sign(e)*Math.min(2,Math.abs(e));v-=18*r,y=t,ee("\x1b[<".concat(e<0?64:65,";").concat(n,";").concat(l,"M").repeat(Math.abs(r)))}}else{let e=Math.trunc(v/64),t=performance.now();if(0!==e&&t-y>=80){let r=Math.sign(e);v-=64*r,y=t,ee(r<0?"\x1b[5~":"\x1b[6~")}}e.preventDefault(),G.current=!0;return}let o=Math.max(8,(null!==(t=null==b?void 0:b.clientHeight)&&void 0!==t?t:14*r.rows)/Math.max(r.rows,1)|0),u=Math.trunc(v/o);0!==u&&(v-=u*o,ec.current(u),e.preventDefault(),G.current=!0)},k=e=>{if(e.pointerId===c){try{null==b||b.releasePointerCapture(e.pointerId)}catch(e){}Math.abs(v)>8&&window.setTimeout(()=>{G.current=!1},400),m=!1,c=null,h="pending",window.setTimeout(()=>{J.current=!1},450)}};return null==b||b.addEventListener("pointerdown",g,{capture:!0}),null==b||b.addEventListener("pointermove",x,{capture:!0,passive:!1}),null==b||b.addEventListener("pointerup",k,{capture:!0}),null==b||b.addEventListener("pointercancel",k,{capture:!0}),()=>{var e;clearTimeout(t),u.dispose(),r.attachCustomKeyEventHandler(()=>!0),r.attachCustomWheelEventHandler(()=>!0),null==b||b.removeEventListener("pointerdown",g,{capture:!0}),null==b||b.removeEventListener("pointermove",x,{capture:!0}),null==b||b.removeEventListener("pointerup",k,{capture:!0}),null==b||b.removeEventListener("pointercancel",k,{capture:!0}),l.dispose(),null===(e=H.current)||void 0===e||e.call(H),null==w||w(null),r.dispose(),M.current=null}},[]),(0,l.useEffect)(()=>{let e=M.current;e&&(e.options.theme=T.xterm,e.refresh(0,e.rows-1))},[T]);let ed=()=>{A.current=!1,X(!1)},ef=(0,l.useCallback)(()=>{var e;let t=C.current,r=M.current;if(!t||!r||!(null===(e=L.current)||void 0===e?void 0:e.isConnected))return!1;try{let e=t.proposeDimensions();if(!e||e.cols===r.cols&&e.rows===r.rows)return!1;return t.fit(),!0}catch(e){return!1}},[]),ep=(0,l.useCallback)(e=>{var t,r;let n=null!==(t=null==e?void 0:e.restoreScroll)&&void 0!==t&&t,l=null!==(r=null==e?void 0:e.forceLive)&&void 0!==r&&r;ef();let i=M.current;if(!i)return;let o="alternate"===i.buffer.active.type;n&&null!=x&&!o?es():!o&&(l||O.current)&&(l&&(O.current=!0),i.scrollToBottom()),i.focus(),eo(),f("term:focus",{id:z.current}).then(()=>I(!1)).catch(e=>{(null==e?void 0:e.code)==="EWRITELOCK"&&I(!0)})},[es,ef,x,eo,f]);(0,l.useEffect)(()=>{var e,n,l,i,o,u;if(!d.connected){j.current=null,B.current=null,null===(l=H.current)||void 0===l||l.call(H),H.current=null,S(!1),D(null),F.current=0;return}let c=!1;return D(null),ef(),requestAnimationFrame(ef),(null!==(u=j.current)&&void 0!==u?u:j.current=f("term:start",{id:t,title:r,cols:null!==(i=null===(e=M.current)||void 0===e?void 0:e.cols)&&void 0!==i?i:80,rows:null!==(o=null===(n=M.current)||void 0===n?void 0:n.rows)&&void 0!==o?o:24})).then(e=>{var t,r;c||(z.current=e.sessionId,B.current=e.channelId,null===(t=H.current)||void 0===t||t.call(H),H.current=v(e.channelId,e=>W.current(e)),S(!0),null==w||w(null!==(r=e.cwd)&&void 0!==r?r:null),window.setTimeout(()=>ef(),80),window.setTimeout(()=>{let e=M.current;e&&f("term:resize",{id:z.current,cols:e.cols,rows:e.rows}).catch(()=>{})},400))}).catch(e=>{j.current=null,c||D((null==e?void 0:e.message)||"终端启动失败")}),()=>{c=!0}},[d.connected,t,r,v]),(0,l.useEffect)(()=>{if(!E)return;let e=el.current;if(e)return e(e=>et.current(e))},[t]),(0,l.useEffect)(()=>{if(!s||!R)return;F.current+=1;let e=F.current>1,t=window.setTimeout(()=>{var t;let r=(null===(t=M.current)||void 0===t?void 0:t.buffer.active.type)==="alternate";ep({restoreScroll:e,forceLive:!e&&!r})},350);return()=>window.clearTimeout(t)},[s,R,ep]),(0,l.useEffect)(()=>p("term:cwd",e=>{e.id===z.current&&e.cwd&&(null==w||w(e.cwd))}),[p]),(0,l.useEffect)(()=>{var e;let t=window.visualViewport,r=null,n=()=>{var e;let t=M.current,r=L.current,n=null==r?void 0:r.querySelector(".xterm"),l=null==r?void 0:r.querySelector(".xterm-screen");if(!t||!r||!n)return!1;if("alternate"!==t.buffer.active.type)return n.style.transform&&(n.style.transform=""),!1;let i=Math.max(0,(null!==(e=null==l?void 0:l.getBoundingClientRect().height)&&void 0!==e?e:r.clientHeight)-r.clientHeight);return n.style.transform=i>0?"translate3d(0,-".concat(Math.round(i),"px,0)"):"",n.style.willChange=i>0?"transform":"",!0},l=()=>{r=null,requestAnimationFrame(()=>{if(n()||!ef())return;let e=M.current;e&&"alternate"!==e.buffer.active.type&&(O.current?e.buffer.active.viewportY<e.buffer.active.baseY&&e.scrollToBottom():e.buffer.active.viewportY!==q.current&&e.scrollToLine(Math.min(q.current,e.buffer.active.baseY)))})},i=()=>{var e,i;let o=null!==(e=null==t?void 0:t.height)&&void 0!==e?e:window.innerHeight,u=null!==(i=null==t?void 0:t.offsetTop)&&void 0!==i?i:0;document.documentElement.style.setProperty("--vv-height","".concat(Math.round(o),"px")),document.documentElement.style.setProperty("--vv-top","".concat(Math.round(u),"px")),requestAnimationFrame(n),r&&clearTimeout(r),r=setTimeout(l,180)};i(),null==t||t.addEventListener("resize",i),null==t||t.addEventListener("scroll",i),window.addEventListener("orientationchange",i),window.addEventListener("resize",i);let o=new ResizeObserver(i);return(null===(e=L.current)||void 0===e?void 0:e.parentElement)&&o.observe(L.current.parentElement),()=>{null==t||t.removeEventListener("resize",i),null==t||t.removeEventListener("scroll",i),window.removeEventListener("orientationchange",i),window.removeEventListener("resize",i),r&&clearTimeout(r),o.disconnect(),document.documentElement.style.removeProperty("--vv-height"),document.documentElement.style.removeProperty("--vv-top")}},[ef]),(0,l.useEffect)(()=>{let e=L.current;if(!e)return;e.style.display="flex",e.style.flexDirection="column",e.style.minHeight="0",e.style.overflow="hidden";let t=e.querySelector(".xterm");null==t||t.style.setProperty("flex","1"),null==t||t.style.setProperty("height","100%");let r=e.querySelector(".xterm-scrollable-element, .xterm-viewport");null==r||r.style.setProperty("touch-action","pan-y"),null==r||r.style.setProperty("-webkit-overflow-scrolling","touch")},[R]),(0,l.useEffect)(()=>{let e=N.current;if(!e||y)return;let t=0,r=!1,n=null,l=null,i=e=>e instanceof Element?e.closest("button[data-key]"):null,o=e=>{if("touch"!==e.pointerType||!e.isPrimary)return;let l=i(e.target);if(l){e.preventDefault();try{l.setPointerCapture(e.pointerId)}catch(e){}let t=l.dataset.key;K.current={key:t,dragged:!1};let r={key:t,timer:null,active:!1,startX:e.clientX,startY:e.clientY,lastX:e.clientX,scrolling:!1};r.timer=setTimeout(()=>{var e,n;r.scrolling||(r.active=!0,K.current&&(K.current.dragged=!0),$(t),null===(e=(n=navigator).vibrate)||void 0===e||e.call(n,20))},280),U.current=r;return}n=e.pointerId,t=e.clientX,r=!0},u=l=>{var i;let o=U.current;if(o){if(!o.active){let e=l.clientX-o.startX,t=l.clientY-o.startY;if(!o.scrolling&&Math.abs(e)>10&&Math.abs(e)>1.2*Math.abs(t))o.timer&&clearTimeout(o.timer),o.timer=null,o.scrolling=!0,K.current&&(K.current.dragged=!0);else if(!o.scrolling)return}if(o.scrolling){l.preventDefault();let t=o.lastX-l.clientX;o.lastX=l.clientX,e.scrollLeft+=t;return}l.preventDefault();let t=Array.from(e.querySelectorAll("button[data-key]")).find(e=>{let t=e.getBoundingClientRect();return l.clientX>=t.left&&l.clientX<=t.right}),r=null==t?void 0:t.dataset.key;if(!r||r===o.key)return;let n=[...em],i=n.indexOf(o.key),u=n.indexOf(r);if(i<0||u<0)return;n.splice(i,1),n.splice(u,0,o.key),b(n);return}if(!r||l.pointerId!==n||(null===(i=U.current)||void 0===i?void 0:i.active))return;let u=t-l.clientX;t=l.clientX,Math.abs(u)>1&&(e.scrollLeft+=u,l.preventDefault())},c=e=>{let t=U.current;if("touch"===e.pointerType&&t){t.timer&&clearTimeout(t.timer),(t.active||t.scrolling)&&(V.current=!0,setTimeout(()=>{V.current=!1},0)),U.current=null,K.current=null,$(null);return}e.pointerId===n&&(r=!1,n=null)},a=e=>{"touch"===e.pointerType&&eb(),r=!1,n=null},s=e=>{let t=i(e.target),r=null==t?void 0:t.dataset.key;r&&!V.current&&(e.preventDefault(),ev(()=>eh(r)))},d=e=>{let t=l;if(l=null,!t)return;let r=performance.now()-t.startedAt;t.moved||r>=280||(e.preventDefault(),V.current=!0,ev(()=>eh(t.key)),setTimeout(()=>{V.current=!1},0))},f=e=>{let t=i(e.target),r=e.touches[0];t&&r&&(l={key:t.dataset.key,startedAt:performance.now(),x:r.clientX,y:r.clientY,moved:!1})},p=e=>{let t=e.touches[0];l&&t&&(Math.abs(t.clientX-l.x)>8||Math.abs(t.clientY-l.y)>8)&&(l.moved=!0)};return e.addEventListener("pointerdown",o,{passive:!1}),e.addEventListener("pointermove",u,{passive:!1}),e.addEventListener("pointerup",c,{passive:!0}),e.addEventListener("pointercancel",a,{passive:!0}),e.addEventListener("click",s),e.addEventListener("touchstart",f,{passive:!0}),e.addEventListener("touchmove",p,{passive:!0}),e.addEventListener("touchend",d,{passive:!1}),()=>{e.removeEventListener("pointerdown",o),e.removeEventListener("pointermove",u),e.removeEventListener("pointerup",c),e.removeEventListener("pointercancel",a),e.removeEventListener("click",s),e.removeEventListener("touchstart",f),e.removeEventListener("touchmove",p),e.removeEventListener("touchend",d)}},[y,h.join("|")]);let ev=e=>{e()},em=[...h.filter(e=>c.includes(e)),...c.filter(e=>!h.includes(e))],eh=e=>{let t={esc:"\x1b",tab:" ",enter:"\r",pipe:"|",tilde:"~",dash:"-",slash:"/",ctrlc:"\x03",ctrld:"\x04",ctrll:"\f"},r=M.current,n=e=>(null==r?void 0:r.modes.applicationCursorKeysMode)?"\x1bO".concat(e):"\x1b[".concat(e);if("up"===e){if(!r)return;"alternate"===r.buffer.active.type?ee(n("A")):ec.current(-1);return}if("down"===e){if(!r)return;"alternate"===r.buffer.active.type?ee(n("B")):ec.current(1);return}if("right"===e){r&&ee(n("C"));return}if("left"===e){r&&ee(n("D"));return}if(t[e])return ee(t[e]);if("ctrl"===e){A.current=!A.current,X(A.current);return}if("hide"===e){g(!0);return}r&&("pgup"===e&&("alternate"===r.buffer.active.type?ee("\x1b[5~"):ea.current(-1)),"pgdown"===e&&("alternate"===r.buffer.active.type?ee("\x1b[6~"):ea.current(1)),"end"===e&&(O.current=!0,r.scrollToBottom(),eo()))},ey=e=>{let t=U.current;t&&(t.timer&&clearTimeout(t.timer),V.current=!0,"touch"!==e.pointerType||t.active||t.scrolling||ev(()=>eh(t.key)),setTimeout(()=>{V.current=!1},0),U.current=null,K.current=null,$(null))},eb=()=>{let e=U.current;(null==e?void 0:e.timer)&&clearTimeout(e.timer),U.current=null,$(null)},eg=async function(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];try{var t;await f(e?"term:request-write":"term:focus",{id:z.current,force:e}),I(!1),null===(t=M.current)||void 0===t||t.focus()}catch(e){(null==e?void 0:e.code)==="EWRITELOCK"&&I(!0)}};return(0,n.jsxs)("div",{style:{display:"flex",flexDirection:"column",height:"100%",minHeight:0,position:"relative"},children:[(0,n.jsx)("div",{ref:L,className:"terminal-screen",onClick:()=>{var e;null===(e=M.current)||void 0===e||e.focus(),!G.current&&O.current&&ep({forceLive:!0}),eg(!1)},style:{flex:1,minHeight:90,padding:"3px 5px 3px 9px",background:T.termHostBg,touchAction:"none",overflow:"hidden"}}),Y&&s&&(0,n.jsxs)("div",{role:"alert",style:{position:"absolute",inset:"42% auto auto 50%",transform:"translate(-50%,-50%)",zIndex:47,maxWidth:"min(420px,calc(100% - 32px))",padding:"10px 12px",border:"1px solid ".concat(T.keybar.keyBorder),borderRadius:7,background:"rgba(24,24,29,.96)",color:T.xterm.foreground,fontSize:12,lineHeight:1.5,textAlign:"center"},children:["终端启动失败:",Y]}),P&&s&&(0,n.jsxs)("div",{style:{position:"absolute",top:10,right:10,zIndex:48,display:"flex",alignItems:"center",gap:7,padding:"7px 9px",border:"1px solid #6b5634",borderRadius:8,background:"rgba(39,32,22,.95)",color:"#d9b56c",fontSize:11},children:["其他设备正在输入 ",(0,n.jsx)("button",{style:{border:0,borderRadius:5,padding:"4px 7px",background:"#e0af68",color:"#17120a",fontSize:10},onClick:()=>eg(!0),children:"接管输入"})]}),y?(0,n.jsx)("div",{className:"keybar",style:{display:"flex",justifyContent:"center",padding:"5px 7px calc(env(safe-area-inset-bottom) + 5px)",borderTop:"1px solid ".concat(T.keybar.border),background:T.keybar.bg,flexShrink:0},children:(0,n.jsx)("button",{className:"keybar-restore",style:{...en,minWidth:80},onPointerDown:e=>e.preventDefault(),onClick:()=>g(!1),children:"⌨ 显示快捷键"})}):(0,n.jsx)("div",{ref:N,className:"keybar keybar-scroll",style:{background:T.keybar.bg,display:"flex",gap:5,overflowX:"auto",padding:"5px calc(env(safe-area-inset-right) + 7px) calc(env(safe-area-inset-bottom) + 5px)",borderTop:"1px solid ".concat(T.keybar.border),flexShrink:0,WebkitOverflowScrolling:"touch",scrollbarWidth:"none",touchAction:"pan-x"},children:em.map(e=>(0,n.jsx)("button",{"data-key":e,"data-dragging":Q===e?"1":void 0,tabIndex:-1,style:{...en,minWidth:"enter"===e?44:en.minWidth,background:Q===e?T.keybar.drag:"ctrl"===e&&_?T.keybar.accent:en.background,color:Q===e||"ctrl"===e&&_?T.keybar.accentText:en.color,cursor:Q===e?"grabbing":"grab",transform:Q===e?"scale(1.08)":"none",transition:"transform .12s, background .12s"},onPointerUpCapture:ey,onPointerCancel:eb,onContextMenu:e=>e.preventDefault(),onMouseDown:e=>e.preventDefault(),children:a[e]},e))})]})}},8810:function(){}}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[541],{6736:function(e,t,r){Promise.resolve().then(r.bind(r,5153))},6302:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return i}});let n=r(684);r(1996),r(6121);let a=n._(r(6729));function i(e,t){var r;let n={loading:e=>{let{error:t,isLoading:r,pastDelay:n}=e;return null}};"function"==typeof e&&(n.loader=e);let i={...n,...t};return(0,a.default)({...i,modules:null==(r=i.loadableGenerated)?void 0:r.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},4352:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return a}});let n=r(2723);function a(e){let{reason:t,children:r}=e;if("undefined"==typeof window)throw new n.BailoutToCSRError(t);return r}},6729:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return d}});let n=r(1996),a=r(6121),i=r(4352),o=r(5882);function l(e){return{default:e&&"default"in e?e.default:e}}let c={loader:()=>Promise.resolve(l(()=>null)),loading:null,ssr:!0},d=function(e){let t={...c,...e},r=(0,a.lazy)(()=>t.loader().then(l)),d=t.loading;function s(e){let l=d?(0,n.jsx)(d,{isLoading:!0,pastDelay:!0,error:null}):null,c=t.ssr?(0,n.jsxs)(n.Fragment,{children:["undefined"==typeof window?(0,n.jsx)(o.PreloadCss,{moduleIds:t.modules}):null,(0,n.jsx)(r,{...e})]}):(0,n.jsx)(i.BailoutToCSR,{reason:"next/dynamic",children:(0,n.jsx)(r,{...e})});return(0,n.jsx)(a.Suspense,{fallback:l,children:c})}return s.displayName="LoadableComponent",s}},5882:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadCss",{enumerable:!0,get:function(){return i}});let n=r(1996),a=r(7994);function i(e){let{moduleIds:t}=e;if("undefined"!=typeof window)return null;let r=(0,a.getExpectedRequestStore)("next/dynamic css"),i=[];if(r.reactLoadableManifest&&t){let e=r.reactLoadableManifest;for(let r of t){if(!e[r])continue;let t=e[r].files.filter(e=>e.endsWith(".css"));i.push(...t)}}return 0===i.length?null:(0,n.jsx)(n.Fragment,{children:i.map(e=>(0,n.jsx)("link",{precedence:"dynamic",rel:"stylesheet",href:r.assetPrefix+"/_next/"+encodeURI(e),as:"style"},e))})}},5153:function(e,t,r){"use strict";r.r(t),r.d(t,{default:function(){return m}});var n=r(1996),a=r(6302),i=r.n(a),o=r(6121);function l(e){let{children:t}=e,r=function(){let[e,t]=(0,o.useState)("loading"),[r,n]=(0,o.useState)(null),[a,i]=(0,o.useState)(""),[l,c]=(0,o.useState)(null),d=(0,o.useRef)(!1),s=(0,o.useCallback)(async()=>{t("loading"),c(null);let e=async()=>{let e=await fetch("/api/web-auth/status",{credentials:"same-origin",cache:"no-store"});if(!e.ok)throw Error("HTTP ".concat(e.status));return e.json()};try{let r;try{r=await e()}catch(t){r=await e()}if(r.needsSetup){t("needsSetup"),n(null);return}if(!r.authenticated){t("needsLogin"),n(null);return}n(r.user),i(r.csrfToken),t("authenticated")}catch(n){let e="undefined"!=typeof location?location.host:"",r=e.startsWith("localhost")||e.startsWith("127.0.0.1")?"请确认 dev:server 已启动(bun run dev:server)":"请确认 ".concat(e," 可访问且 Gateway 未在重启中");c("无法连接认证服务:".concat(r)),t("needsLogin")}},[]);(0,o.useEffect)(()=>{d.current||(d.current=!0,s())},[s]);let u=(0,o.useCallback)(async(e,r,a)=>{c(null);let o="setup"===e&&new URLSearchParams(location.search).get("pair")||void 0,l=await fetch("/api/web-auth/".concat(e),{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({username:r,password:a,pairingToken:o})}),d=await l.json();if(!l.ok){var s;return c((null===(s=d.error)||void 0===s?void 0:s.message)||"认证失败"),!1}return n(d.user),i(d.csrfToken),t("authenticated"),o&&history.replaceState(null,"",location.pathname),!0},[]),b=(0,o.useCallback)(async()=>{let e=await fetch("/api/web-console/bootstrap",{credentials:"same-origin",cache:"no-store"});if(401===e.status)throw t("needsLogin"),Error("unauthenticated");if(!e.ok)throw Error("bootstrap failed");return(await e.json()).wsNonce},[]),f=(0,o.useCallback)(async()=>{await fetch("/api/web-auth/logout",{method:"POST",credentials:"same-origin",headers:{"x-csrf-token":a}}),n(null),i(""),t("needsLogin")},[a]);return{status:e,user:r,error:l,csrfToken:a,setup:(e,t)=>u("setup",e,t),login:(e,t)=>u("login",e,t),logout:f,refresh:s,getWsNonce:b}}(),[a,i]=(0,o.useState)(""),[l,d]=(0,o.useState)(""),[s,u]=(0,o.useState)(!1);if("authenticated"===r.status)return(0,n.jsx)(n.Fragment,{children:t(r)});if("loading"===r.status)return(0,n.jsx)("main",{style:c.page,children:(0,n.jsx)("div",{style:c.card,children:"正在加载…"})});let b="needsSetup"===r.status,f=async e=>{e.preventDefault(),u(!0);try{await (b?r.setup(a,l):r.login(a,l))}finally{u(!1)}};return(0,n.jsx)("main",{style:c.page,children:(0,n.jsxs)("form",{style:c.card,onSubmit:f,children:[(0,n.jsx)("div",{style:c.mark,children:"CA"}),(0,n.jsx)("h1",{style:c.title,children:b?"初始化管理员":"登录远程控制台"}),(0,n.jsx)("p",{style:c.copy,children:b?"创建唯一管理员账号。完成后初始化入口将关闭。":"登录后 30 天内自动续期,无需再次输入 token。"}),(0,n.jsx)("label",{style:c.label,children:"用户名"}),(0,n.jsx)("input",{style:c.input,autoComplete:"username",value:a,onChange:e=>i(e.target.value),required:!0,minLength:3}),(0,n.jsx)("label",{style:c.label,children:"密码"}),(0,n.jsx)("input",{style:c.input,type:"password",autoComplete:b?"new-password":"current-password",value:l,onChange:e=>d(e.target.value),required:!0,minLength:10}),r.error&&(0,n.jsx)("div",{style:c.error,children:r.error}),(0,n.jsx)("button",{style:c.button,disabled:s,children:s?"请稍候…":b?"创建并进入":"登录"})]})})}let c={page:{minHeight:"100dvh",display:"grid",placeItems:"center",padding:20,boxSizing:"border-box",background:"#0b0b10",color:"#e8e8ee",fontFamily:'-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif'},card:{width:"min(380px,100%)",padding:24,border:"1px solid #292c36",borderRadius:12,background:"#14161d",boxSizing:"border-box",boxShadow:"0 18px 50px rgba(0,0,0,.35)"},mark:{width:40,height:40,display:"grid",placeItems:"center",borderRadius:8,background:"#7aa2f7",color:"#0b0b10",fontWeight:800,marginBottom:16},title:{margin:"0 0 8px",fontSize:20,letterSpacing:0},copy:{margin:"0 0 20px",color:"#858999",fontSize:12.5,lineHeight:1.6},label:{display:"block",color:"#9a9ead",fontSize:11,margin:"12px 0 6px"},input:{width:"100%",height:40,boxSizing:"border-box",border:"1px solid #343844",borderRadius:7,padding:"0 10px",background:"#0e1016",color:"#eceef4",fontSize:14,outline:"none"},error:{marginTop:12,color:"#f7768e",fontSize:12},button:{width:"100%",height:40,marginTop:18,border:0,borderRadius:7,background:"#7aa2f7",color:"#0b0b10",fontWeight:700,fontSize:13}};function d(e){let{csrfToken:t,terminalId:r,onFill:a}=e,[i,l]=(0,o.useState)([]),[c,d]=(0,o.useState)(""),s=(0,o.useCallback)(async()=>{let e=new URLSearchParams({q:c,limit:"200"}),t=await fetch("/api/web-console/history?".concat(e),{credentials:"same-origin"});t.ok&&l((await t.json()).history)},[c]);(0,o.useEffect)(()=>{let e=setTimeout(s,200);return()=>clearTimeout(e)},[s]);let u=async e=>{await fetch("/api/web-console/history",{method:"DELETE",credentials:"same-origin",headers:{"content-type":"application/json","x-csrf-token":t},body:JSON.stringify({id:e})}),s()},b=e=>{r&&a(e)};return(0,n.jsxs)("div",{className:"history-panel",children:[(0,n.jsxs)("div",{className:"history-search",children:[(0,n.jsx)("input",{value:c,onChange:e=>d(e.target.value),placeholder:"搜索命令"}),(0,n.jsx)("button",{onClick:s,children:"刷新"})]}),i.map(e=>(0,n.jsxs)("div",{className:"history-item".concat(r?"":" history-item-disabled"),role:"button",tabIndex:r?0:-1,onClick:()=>b(e.command),onKeyDown:t=>{("Enter"===t.key||" "===t.key)&&r&&(t.preventDefault(),b(e.command))},children:[(0,n.jsx)("code",{children:e.command}),(0,n.jsxs)("small",{children:[e.cwd," \xb7 ",new Date(e.executedAt).toLocaleString()]}),(0,n.jsxs)("div",{className:"history-item-actions",onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),children:[(0,n.jsx)("button",{onClick:()=>navigator.clipboard.writeText(e.command),children:"复制"}),(0,n.jsx)("button",{disabled:!r,onClick:()=>b(e.command),children:"填入"}),(0,n.jsx)("button",{onClick:()=>u(e.id),children:"删除"})]})]},e.id)),!i.length&&(0,n.jsx)("div",{className:"history-empty",children:"暂无 Shell 命令历史"}),!r&&!!i.length&&(0,n.jsx)("div",{className:"history-empty",children:"请先打开一个终端页签"})]})}let s=[{id:"black",label:"黑",swatch:"#1a1b26",cssVars:{"--ui-root-bg":"#0b0b10","--ui-text":"#e8e8ee","--ui-tabbar-bg":"#12141b","--ui-tabbar-border":"#282b36","--ui-tab-bg":"#1b1e28","--ui-tab-text":"#8f93a4","--ui-tab-active-bg":"#262b38","--ui-tab-active-text":"#edf0f7","--ui-tab-accent":"#7aa2f7","--ui-connection-bg":"#12141b","--ui-connection-text":"#777b8c","--ui-tree-bg":"#121218","--ui-tree-border":"#1e1e26","--ui-term-col-bg":"#101014","--ui-fab-bg":"#1b1b26","--ui-fab-border":"#2c2c38","--ui-muted-surface":"#171920","--ui-muted-border":"#2d303a","--ui-muted-text":"#8c909f","--ui-panel-input-bg":"#0f0f15","--ui-panel-input-text":"#d8d8df","--ui-panel-input-border":"#30303b","--ui-drawer-tab-text":"#74798a","--ui-drawer-tab-active":"#e4e7ef","--ui-history-item-text":"#d3d6df","--ui-history-meta":"#656a79","--ui-success":"#9ece6a","--ui-error":"#f7768e"},termHostBg:"#101014",keybar:{bg:"#171922",border:"#1e1e26",keyBg:"#17171e",keyBorder:"#2c2c36",keyText:"#ccc",accent:"#7aa2f7",accentText:"#0b0b10",drag:"#536b9e"},xterm:{background:"#101014",foreground:"#d8d8de",cursor:"#7aa2f7",selectionBackground:"#33467c",black:"#15151a",red:"#f7768e",green:"#9ece6a",yellow:"#e0af68",blue:"#7aa2f7",magenta:"#bb9af7",cyan:"#7dcfff",white:"#a9b1d6",brightBlack:"#414868",brightWhite:"#c0caf5"}},{id:"white",label:"白",swatch:"#fdf6e3",cssVars:{"--ui-root-bg":"#eee8d5","--ui-text":"#073642","--ui-tabbar-bg":"#e6dfcc","--ui-tabbar-border":"#d3cbb8","--ui-tab-bg":"#ddd6c1","--ui-tab-text":"#586e75","--ui-tab-active-bg":"#fdf6e3","--ui-tab-active-text":"#073642","--ui-tab-accent":"#268bd2","--ui-connection-bg":"#e6dfcc","--ui-connection-text":"#657b83","--ui-tree-bg":"#f5f0dc","--ui-tree-border":"#d3cbb8","--ui-term-col-bg":"#fdf6e3","--ui-fab-bg":"#eee8d5","--ui-fab-border":"#93a1a1","--ui-muted-surface":"#e8e2cf","--ui-muted-border":"#c9c2ae","--ui-muted-text":"#657b83","--ui-panel-input-bg":"#fdf6e3","--ui-panel-input-text":"#073642","--ui-panel-input-border":"#c9c2ae","--ui-drawer-tab-text":"#657b83","--ui-drawer-tab-active":"#073642","--ui-history-item-text":"#073642","--ui-history-meta":"#657b83","--ui-success":"#859900","--ui-error":"#dc322f"},termHostBg:"#fdf6e3",keybar:{bg:"#eee8d5",border:"#d3cbb8",keyBg:"#fdf6e3",keyBorder:"#c9c2ae",keyText:"#073642",accent:"#268bd2",accentText:"#fdf6e3",drag:"#2aa198"},xterm:{background:"#fdf6e3",foreground:"#586e75",cursor:"#268bd2",selectionBackground:"#93a1a1",black:"#073642",red:"#dc322f",green:"#859900",yellow:"#b58900",blue:"#268bd2",magenta:"#d33682",cyan:"#2aa198",white:"#eee8d5",brightBlack:"#657b83",brightWhite:"#fdf6e3"}},{id:"red",label:"红",swatch:"#282a36",cssVars:{"--ui-root-bg":"#1e1f29","--ui-text":"#f8f8f2","--ui-tabbar-bg":"#21222c","--ui-tabbar-border":"#44475a","--ui-tab-bg":"#282a36","--ui-tab-text":"#9496a8","--ui-tab-active-bg":"#343746","--ui-tab-active-text":"#f8f8f2","--ui-tab-accent":"#ff5555","--ui-connection-bg":"#21222c","--ui-connection-text":"#9496a8","--ui-tree-bg":"#282a36","--ui-tree-border":"#44475a","--ui-term-col-bg":"#282a36","--ui-fab-bg":"#343746","--ui-fab-border":"#6272a4","--ui-muted-surface":"#343746","--ui-muted-border":"#44475a","--ui-muted-text":"#bd93f9","--ui-panel-input-bg":"#21222c","--ui-panel-input-text":"#f8f8f2","--ui-panel-input-border":"#44475a","--ui-drawer-tab-text":"#9496a8","--ui-drawer-tab-active":"#ff79c6","--ui-history-item-text":"#f8f8f2","--ui-history-meta":"#9496a8","--ui-success":"#50fa7b","--ui-error":"#ff5555"},termHostBg:"#282a36",keybar:{bg:"#21222c",border:"#44475a",keyBg:"#282a36",keyBorder:"#44475a",keyText:"#f8f8f2",accent:"#ff5555",accentText:"#282a36",drag:"#6272a4"},xterm:{background:"#282a36",foreground:"#f8f8f2",cursor:"#ff5555",selectionBackground:"#44475a",black:"#21222c",red:"#ff5555",green:"#50fa7b",yellow:"#f1fa8c",blue:"#bd93f9",magenta:"#ff79c6",cyan:"#8be9fd",white:"#f8f8f2",brightBlack:"#6272a4",brightWhite:"#ffffff"}},{id:"yellow",label:"黄",swatch:"#282828",cssVars:{"--ui-root-bg":"#1d2021","--ui-text":"#ebdbb2","--ui-tabbar-bg":"#1d2021","--ui-tabbar-border":"#504945","--ui-tab-bg":"#282828","--ui-tab-text":"#a89984","--ui-tab-active-bg":"#32302f","--ui-tab-active-text":"#ebdbb2","--ui-tab-accent":"#fabd2f","--ui-connection-bg":"#1d2021","--ui-connection-text":"#a89984","--ui-tree-bg":"#282828","--ui-tree-border":"#504945","--ui-term-col-bg":"#282828","--ui-fab-bg":"#32302f","--ui-fab-border":"#665c54","--ui-muted-surface":"#32302f","--ui-muted-border":"#504945","--ui-muted-text":"#bdae93","--ui-panel-input-bg":"#1d2021","--ui-panel-input-text":"#ebdbb2","--ui-panel-input-border":"#504945","--ui-drawer-tab-text":"#a89984","--ui-drawer-tab-active":"#fabd2f","--ui-history-item-text":"#ebdbb2","--ui-history-meta":"#928374","--ui-success":"#b8bb26","--ui-error":"#fb4934"},termHostBg:"#282828",keybar:{bg:"#1d2021",border:"#504945",keyBg:"#282828",keyBorder:"#504945",keyText:"#ebdbb2",accent:"#fabd2f",accentText:"#1d2021",drag:"#665c54"},xterm:{background:"#282828",foreground:"#ebdbb2",cursor:"#fabd2f",selectionBackground:"#504945",black:"#282828",red:"#fb4934",green:"#b8bb26",yellow:"#fabd2f",blue:"#83a598",magenta:"#d3869b",cyan:"#8ec07c",white:"#ebdbb2",brightBlack:"#928374",brightWhite:"#fbf1c7"}},{id:"blue",label:"蓝",swatch:"#2e3440",cssVars:{"--ui-root-bg":"#242933","--ui-text":"#eceff4","--ui-tabbar-bg":"#2e3440","--ui-tabbar-border":"#434c5e","--ui-tab-bg":"#3b4252","--ui-tab-text":"#a3b1c2","--ui-tab-active-bg":"#434c5e","--ui-tab-active-text":"#eceff4","--ui-tab-accent":"#88c0d0","--ui-connection-bg":"#2e3440","--ui-connection-text":"#a3b1c2","--ui-tree-bg":"#2e3440","--ui-tree-border":"#434c5e","--ui-term-col-bg":"#2e3440","--ui-fab-bg":"#3b4252","--ui-fab-border":"#5e81ac","--ui-muted-surface":"#3b4252","--ui-muted-border":"#434c5e","--ui-muted-text":"#81a1c1","--ui-panel-input-bg":"#242933","--ui-panel-input-text":"#eceff4","--ui-panel-input-border":"#434c5e","--ui-drawer-tab-text":"#a3b1c2","--ui-drawer-tab-active":"#88c0d0","--ui-history-item-text":"#eceff4","--ui-history-meta":"#7b88a1","--ui-success":"#a3be8c","--ui-error":"#bf616a"},termHostBg:"#2e3440",keybar:{bg:"#242933",border:"#434c5e",keyBg:"#3b4252",keyBorder:"#434c5e",keyText:"#eceff4",accent:"#88c0d0",accentText:"#242933",drag:"#5e81ac"},xterm:{background:"#2e3440",foreground:"#d8dee9",cursor:"#88c0d0",selectionBackground:"#434c5e",black:"#3b4252",red:"#bf616a",green:"#a3be8c",yellow:"#ebcb8b",blue:"#81a1c1",magenta:"#b48ead",cyan:"#88c0d0",white:"#e5e9f0",brightBlack:"#4c566a",brightWhite:"#eceff4"}},{id:"gray",label:"灰",swatch:"#1e1e1e",cssVars:{"--ui-root-bg":"#181818","--ui-text":"#d4d4d4","--ui-tabbar-bg":"#1e1e1e","--ui-tabbar-border":"#3c3c3c","--ui-tab-bg":"#252526","--ui-tab-text":"#969696","--ui-tab-active-bg":"#2d2d2d","--ui-tab-active-text":"#ffffff","--ui-tab-accent":"#cccccc","--ui-connection-bg":"#1e1e1e","--ui-connection-text":"#969696","--ui-tree-bg":"#252526","--ui-tree-border":"#3c3c3c","--ui-term-col-bg":"#1e1e1e","--ui-fab-bg":"#2d2d2d","--ui-fab-border":"#555555","--ui-muted-surface":"#2d2d2d","--ui-muted-border":"#3c3c3c","--ui-muted-text":"#b0b0b0","--ui-panel-input-bg":"#181818","--ui-panel-input-text":"#d4d4d4","--ui-panel-input-border":"#3c3c3c","--ui-drawer-tab-text":"#969696","--ui-drawer-tab-active":"#ffffff","--ui-history-item-text":"#d4d4d4","--ui-history-meta":"#808080","--ui-success":"#89d185","--ui-error":"#f48771"},termHostBg:"#1e1e1e",keybar:{bg:"#252526",border:"#3c3c3c",keyBg:"#2d2d2d",keyBorder:"#3c3c3c",keyText:"#d4d4d4",accent:"#cccccc",accentText:"#1e1e1e",drag:"#555555"},xterm:{background:"#1e1e1e",foreground:"#d4d4d4",cursor:"#aeafad",selectionBackground:"#264f78",black:"#1e1e1e",red:"#f48771",green:"#89d185",yellow:"#dcdcaa",blue:"#569cd6",magenta:"#c586c0",cyan:"#4ec9b0",white:"#d4d4d4",brightBlack:"#808080",brightWhite:"#ffffff"}},{id:"green",label:"绿",swatch:"#0a120a",cssVars:{"--ui-root-bg":"#050805","--ui-text":"#b8ffb8","--ui-tabbar-bg":"#0a120a","--ui-tabbar-border":"#1a3a1a","--ui-tab-bg":"#0f180f","--ui-tab-text":"#5a9a5a","--ui-tab-active-bg":"#142014","--ui-tab-active-text":"#d4ffd4","--ui-tab-accent":"#33ff66","--ui-connection-bg":"#0a120a","--ui-connection-text":"#5a9a5a","--ui-tree-bg":"#0f180f","--ui-tree-border":"#1a3a1a","--ui-term-col-bg":"#0a120a","--ui-fab-bg":"#142014","--ui-fab-border":"#2a5a2a","--ui-muted-surface":"#142014","--ui-muted-border":"#1a3a1a","--ui-muted-text":"#6aaa6a","--ui-panel-input-bg":"#050805","--ui-panel-input-text":"#b8ffb8","--ui-panel-input-border":"#1a3a1a","--ui-drawer-tab-text":"#5a9a5a","--ui-drawer-tab-active":"#33ff66","--ui-history-item-text":"#b8ffb8","--ui-history-meta":"#4a8a4a","--ui-success":"#33ff66","--ui-error":"#ff5555"},termHostBg:"#0a120a",keybar:{bg:"#0a120a",border:"#1a3a1a",keyBg:"#0f180f",keyBorder:"#1a3a1a",keyText:"#b8ffb8",accent:"#33ff66",accentText:"#050805",drag:"#2a5a2a"},xterm:{background:"#0a120a",foreground:"#33ff66",cursor:"#33ff66",selectionBackground:"#1a4a1a",black:"#050805",red:"#ff5555",green:"#33ff66",yellow:"#ffff66",blue:"#66ccff",magenta:"#ff66ff",cyan:"#66ffff",white:"#b8ffb8",brightBlack:"#2a5a2a",brightWhite:"#d4ffd4"}}],u="black",b=Object.fromEntries(s.map(e=>[e.id,e]));function f(e){let t="dark"===e?u:e;return t&&t in b?b[t]:b[u]}function p(e){var t;let{username:r,themeId:a,onThemeChange:i,accent:l,accentText:c}=e,[d,u]=(0,o.useState)(!1),b=(0,o.useRef)(null),f=(0,o.useRef)(null),[p,h]=(0,o.useState)(null),g=(null!==(t=r.trim()[0])&&void 0!==t?t:"?").toUpperCase(),x=()=>{let e=f.current;if(!e)return;let t=e.getBoundingClientRect(),r=Math.max(8,Math.min(window.innerWidth-168-8,t.right-168));h({top:t.bottom+6,left:r})};return(0,o.useLayoutEffect)(()=>{if(!d){h(null);return}return x(),window.addEventListener("resize",x),window.addEventListener("scroll",x,!0),()=>{window.removeEventListener("resize",x),window.removeEventListener("scroll",x,!0)}},[d]),(0,o.useEffect)(()=>{if(!d)return;let e=e=>{var t;let r=e.target;null!==(t=b.current)&&void 0!==t&&t.contains(r)||u(!1)},t=e=>{"Escape"===e.key&&u(!1)},r=window.setTimeout(()=>{window.addEventListener("pointerdown",e,!0)},0);return window.addEventListener("keydown",t),()=>{window.clearTimeout(r),window.removeEventListener("pointerdown",e,!0),window.removeEventListener("keydown",t)}},[d]),(0,n.jsxs)("div",{ref:b,className:"theme-picker",children:[(0,n.jsx)("button",{ref:f,type:"button",className:"theme-avatar","aria-label":"换肤(".concat(r,")"),title:r,"aria-expanded":d,onPointerDown:e=>e.stopPropagation(),onClick:e=>{e.preventDefault(),e.stopPropagation(),u(e=>!e)},style:{width:28,height:28,borderRadius:99,border:"1px solid ".concat(l),background:l,color:c,fontSize:12,fontWeight:700,padding:0,cursor:"pointer",flexShrink:0,touchAction:"manipulation"},children:g}),d&&p&&(0,n.jsxs)("div",{className:"theme-popover",role:"dialog","aria-label":"选择皮肤",style:{position:"fixed",top:p.top,left:p.left,zIndex:200,width:168,padding:10,borderRadius:10,border:"1px solid var(--ui-tabbar-border, #282b36)",background:"var(--ui-tab-active-bg, #262b38)",boxShadow:"0 10px 28px rgba(0,0,0,.45)"},children:[(0,n.jsx)("div",{style:{fontSize:10,color:"var(--ui-connection-text, #777b8c)",marginBottom:8,letterSpacing:.5},children:"经典皮肤"}),(0,n.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:7},children:s.map(e=>{let t=e.id===a;return(0,n.jsxs)("button",{type:"button",title:e.label,"aria-label":e.label,"aria-pressed":t,onPointerDown:e=>e.stopPropagation(),onClick:()=>{i(e.id),u(!1)},style:{display:"flex",flexDirection:"column",alignItems:"center",gap:4,padding:"6px 2px",borderRadius:8,border:t?"2px solid var(--ui-tab-accent, #7aa2f7)":"1px solid var(--ui-tabbar-border, #282b36)",background:"var(--ui-tab-bg, #1b1e28)",cursor:"pointer",touchAction:"manipulation"},children:[(0,n.jsx)("span",{style:{width:22,height:22,borderRadius:6,background:e.swatch,boxShadow:t?"0 0 0 1px var(--ui-tab-accent, #7aa2f7)":"inset 0 0 0 1px rgba(255,255,255,.08)"}}),(0,n.jsx)("span",{style:{fontSize:9.5,color:t?"var(--ui-tab-active-text, #edf0f7)":"var(--ui-tab-text, #8f93a4)"},children:e.label})]},e.id)})})]})]})}let h=i()(()=>Promise.all([r.e(118),r.e(658),r.e(804)]).then(r.bind(r,1587)),{loadableGenerated:{webpack:()=>[1587]},ssr:!1}),g=i()(()=>r.e(691).then(r.bind(r,9691)),{loadableGenerated:{webpack:()=>[9691]},ssr:!1}),x=i()(()=>r.e(945).then(r.bind(r,1945)),{loadableGenerated:{webpack:()=>[1945]},ssr:!1});function m(){return(0,n.jsx)(l,{children:e=>(0,n.jsx)(v,{auth:e})})}function v(e){var t,r,a;let{auth:i}=e,{state:l,epoch:c,rpc:s,onEvent:b,onTerminalData:m,sendTerminalInput:v}=function(e,t,r){let[n,a]=(0,o.useState)({connected:!1,error:null}),[i,l]=(0,o.useState)(0),c=(0,o.useRef)(null),d=(0,o.useRef)(0),s=(0,o.useRef)(new Map),u=(0,o.useRef)([]),b=(0,o.useRef)(0),f=(0,o.useRef)(new Map),p=(0,o.useRef)(new Map),h=(0,o.useRef)(1e3),g=(0,o.useRef)(!1),x=(0,o.useRef)(e),m=(0,o.useRef)(t),v=(0,o.useRef)(r);x.current=e,m.current=t,v.current=r;let y=(0,o.useCallback)((e,t)=>{let r=f.current.get(e);return r||f.current.set(e,r=new Set),r.add(t),()=>r.delete(t)},[]),w=(0,o.useCallback)((e,t)=>{let r=p.current.get(e);return r||p.current.set(e,r=new Set),r.add(t),()=>r.delete(t)},[]),k=(0,o.useCallback)((e,t)=>{let r=c.current;if(!r||r.readyState!==WebSocket.OPEN)return!1;let n=new TextEncoder().encode(t),a=new Uint8Array(6+n.byteLength),i=new DataView(a.buffer);return a[0]=1,a[1]=1,i.setUint32(2,e),a.set(n,6),r.send(a),!0},[]),S=(0,o.useCallback)(e=>{let t=c.current;(null==t?void 0:t.readyState)===WebSocket.OPEN?t.send(e):u.current.push(e)},[]),j=(0,o.useCallback)(function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:15e3;return new Promise((n,a)=>{let i=++b.current,o=setTimeout(()=>{s.current.delete(i),a(Error("".concat(e," timeout")))},r);s.current.set(i,{resolve:n,reject:a,timer:o}),S(JSON.stringify({type:e,_req:i,...t}))})},[S]),T=(0,o.useCallback)(async()=>{let e,t;g.current=!1;let r=++d.current,n=c.current;if(n){n.onopen=n.onmessage=n.onerror=n.onclose=null;try{n.close()}catch(e){}}try{e=await m.current()}catch(e){r===d.current&&v.current();return}if(r===d.current&&!g.current){try{t=new WebSocket("".concat("".concat("https:"===location.protocol?"wss:":"ws:","//").concat(location.host,"/ws"),"?nonce=").concat(encodeURIComponent(e)))}catch(e){a({connected:!1,error:String(e)});return}t.binaryType="arraybuffer",c.current=t,t.onopen=()=>{if(r===d.current&&c.current===t)for(let e of(h.current=1e3,a({connected:!0,error:null}),l(e=>e+1),u.current.splice(0)))t.send(e)},t.onmessage=e=>{var n,a;let i;if(r===d.current&&c.current===t){if("string"!=typeof e.data){let t=new Uint8Array(e.data);if(t.byteLength>=6&&1===t[0]&&2===t[1]){let e=new DataView(t.buffer,t.byteOffset,t.byteLength).getUint32(2);null===(a=p.current.get(e))||void 0===a||a.forEach(e=>e(t.subarray(6)))}else x.current(t);return}try{i=JSON.parse(e.data)}catch(e){return}if("error"===i.type&&null!=i.id){let e=s.current.get(i.id);if(e){s.current.delete(i.id),clearTimeout(e.timer);let t=Object.assign(Error(i.error||"gateway error"),{code:i.code});e.reject(t)}return}if(null!=i.id&&"string"==typeof i.type&&i.type.endsWith(":result")){let e=s.current.get(i.id);e&&(s.current.delete(i.id),clearTimeout(e.timer),e.resolve(i));return}null===(n=f.current.get(i.type))||void 0===n||n.forEach(e=>e(i))}},t.onclose=e=>{if(r!==d.current||c.current!==t)return;if(c.current=null,a({connected:!1,error:null}),4001===e.code||4003===e.code){v.current();return}if(g.current)return;let n=h.current;h.current=Math.min(2*n,8e3),setTimeout(()=>{g.current||r!==d.current||T()},n)},t.onerror=()=>{}}},[]);return(0,o.useEffect)(()=>(T(),()=>{g.current=!0,d.current++;let e=c.current;if(c.current=null,e){e.onopen=e.onmessage=e.onerror=e.onclose=null;try{e.close()}catch(e){}}}),[T]),{state:n,epoch:i,rpc:j,onEvent:y,onTerminalData:w,sendTerminalInput:k,reconnect:T}}(()=>{},i.getWsNonce,i.refresh),[k,S]=(0,o.useState)([]),[j,T]=(0,o.useState)(null),[C,R]=(0,o.useState)({}),z=(0,o.useRef)(!1),B=(0,o.useRef)(null),P=(0,o.useRef)(new Map),E=(0,o.useCallback)((e,t)=>(P.current.set(e,t),()=>P.current.delete(e)),[]),M=(0,o.useCallback)(e=>{if(!j)return;let t=P.current.get(j);t?t(e):s("term:input",{id:j,data:"\x15".concat(e)}).catch(()=>{}),H(!1)},[j,s]),[N,L]=(0,o.useState)(!1),[O,D]=(0,o.useState)({}),[W,F]=(0,o.useState)(null),[I,H]=(0,o.useState)(!1),[_,U]=(0,o.useState)("files"),[V,A]=(0,o.useState)(null),[q,X]=(0,o.useState)(!0),[J,G]=(0,o.useState)({xRatio:.94,yRatio:.65,anchor:"right"}),[K,Y]=(0,o.useState)(!1),[Q,Z]=(0,o.useState)([]),[$,ee]=(0,o.useState)(u),[et,er]=(0,o.useState)(!1),en=f($),ea=(0,o.useRef)(null),ei=(0,o.useRef)(null),[eo,el]=(0,o.useState)(0),[ec,ed]=(0,o.useState)(!1),es=(0,o.useRef)(null),eu=(0,o.useRef)(null),eb=(0,o.useRef)(0),ef=j&&null!==(r=C[j])&&void 0!==r?r:null;(0,o.useEffect)(()=>{fetch("/api/web-console/preferences",{credentials:"same-origin"}).then(e=>e.json()).then(e=>{var t,r,n,a;(null===(t=e.preferences)||void 0===t?void 0:t.fileButtonPosition)&&G(e.preferences.fileButtonPosition),"boolean"==typeof(null===(r=e.preferences)||void 0===r?void 0:r.keybarHidden)&&Y(e.preferences.keybarHidden),Array.isArray(null===(n=e.preferences)||void 0===n?void 0:n.keyOrder)&&Z(e.preferences.keyOrder),(null===(a=e.preferences)||void 0===a?void 0:a.theme)&&ee(f(e.preferences.theme).id)}).catch(()=>{}).finally(()=>er(!0)),fetch("/api/web-console/device-state",{credentials:"same-origin"}).then(e=>e.json()).then(e=>{let t=e.deviceState;(null==t?void 0:t.drawerTab)&&U(t.drawerTab),(null==t?void 0:t.activeTerminalId)&&(B.current=t.activeTerminalId),"boolean"==typeof(null==t?void 0:t.drawerOpen)&&H(t.drawerOpen),(null==t?void 0:t.fileTreeRoot)&&A(t.fileTreeRoot),"boolean"==typeof(null==t?void 0:t.fileTreeFollowMode)&&X(t.fileTreeFollowMode),(null==t?void 0:t.selectedFile)&&F(t.selectedFile),(null==t?void 0:t.terminalScroll)&&"object"==typeof t.terminalScroll&&D(t.terminalScroll)}).catch(()=>{}).finally(()=>L(!0))},[]);let ep=(0,o.useCallback)(e=>{fetch("/api/web-console/preferences",{method:"PATCH",credentials:"same-origin",headers:{"content-type":"application/json","x-csrf-token":i.csrfToken},body:JSON.stringify(e)}).catch(()=>{})},[i.csrfToken]);(0,o.useEffect)(()=>{if(!et)return;let e=setTimeout(()=>ep({fileButtonPosition:J,keybarHidden:K,keyOrder:Q,theme:$}),500);return()=>clearTimeout(e)},[J,K,Q,$,et,ep]);let eh=(0,o.useCallback)(e=>{i.csrfToken&&fetch("/api/web-console/device-state",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json","x-csrf-token":i.csrfToken},body:JSON.stringify(e)}).catch(()=>{})},[i.csrfToken]);(0,o.useEffect)(()=>{if(!i.csrfToken)return;let e=setTimeout(()=>eh({activeTerminalId:j,drawerOpen:I,drawerTab:_,fileTreeRoot:V,fileTreeFollowMode:q,selectedFile:W,terminalScroll:O}),500);return()=>clearTimeout(e)},[j,I,_,V,q,W,O,i.csrfToken,eh]),(0,o.useEffect)(()=>{if(!i.csrfToken)return;let e=()=>eh({activeTerminalId:j,drawerOpen:I,drawerTab:_,fileTreeRoot:V,fileTreeFollowMode:q,selectedFile:W,terminalScroll:O});return window.addEventListener("pagehide",e),()=>window.removeEventListener("pagehide",e)},[j,I,_,V,q,W,O,i.csrfToken,eh]);let eg=(0,o.useCallback)(e=>{F(e),H(!1)},[]),ex=(0,o.useCallback)(()=>{let e=null;S(t=>t.length>=8?t:[...t,{id:e="t-web-".concat(Date.now().toString(36),"-").concat(Math.random().toString(36).slice(2,8)),title:"Terminal ".concat(t.length+1)}]),e&&T(e)},[]);(0,o.useEffect)(()=>{l.connected&&N&&!z.current&&(z.current=!0,s("term:list").then(e=>{let t=e.tabs.filter(e=>"active"===e.status||"detached"===e.status).map(e=>{let{id:t,title:r}=e;return{id:t,title:r}});t.length?(S(t),T(e=>{let r=B.current||e;return r&&t.some(e=>e.id===r)?r:t[0].id})):ex()}).catch(ex))},[l.connected,N,s,ex]);let em=async e=>{window.confirm("关闭页签会终止该终端进程,确认关闭?")&&(await s("term:kill",{id:e}).catch(()=>{}),S(t=>{var r,n;let a=t.filter(t=>t.id!==e);return j===e&&T(null!==(n=null===(r=a[0])||void 0===r?void 0:r.id)&&void 0!==n?n:null),a}))},ev=(0,o.useCallback)(e=>{if(!j||k.length<2)return;let t=(k.findIndex(e=>e.id===j)+e+k.length)%k.length;T(k[t].id)},[j,k]),ey=Math.max(0,k.findIndex(e=>e.id===j)),ew=(0,o.useCallback)(()=>{ei.current=null,el(0),ed(!1)},[]),ek=(0,o.useCallback)(e=>{Math.abs(e)>=64&&k.length>1&&ev(e<0?1:-1),ew()},[k.length,ev,ew]),eS=e=>e instanceof Element&&!!e.closest(".terminal-screen"),ej=(0,o.useCallback)(function(){var e;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"smooth",r=eu.current;if(!r||!j)return;let n=r.querySelector('[data-terminal-id="'.concat(j,'"]'));if(!n)return;let a=r.querySelector(".terminal-connection"),i=null!==(e=null==a?void 0:a.offsetWidth)&&void 0!==e?e:0,o=n.offsetLeft,l=o+n.offsetWidth,c=r.scrollLeft,d=c+r.clientWidth-i;o<c+8?r.scrollTo({left:Math.max(0,o-8),behavior:t}):l>d-8&&r.scrollTo({left:l-r.clientWidth+i+8,behavior:t})},[j]);return(0,o.useLayoutEffect)(()=>{if(!j)return;let e=k.length>eb.current;eb.current=k.length,ej(e?"auto":"smooth")},[j,k.length,ej]),(0,n.jsxs)("div",{className:"web-root",style:{...w.root,...en.cssVars,background:"var(--ui-root-bg)",color:"var(--ui-text)"},children:[(0,n.jsx)("style",{dangerouslySetInnerHTML:{__html:y}}),(0,n.jsxs)("div",{className:"terminal-tabs",ref:eu,children:[k.map(e=>(0,n.jsxs)("div",{"data-terminal-id":e.id,draggable:!0,className:"terminal-tab ".concat(e.id===j?"active":""),onDragStart:()=>{es.current=e.id},onDragOver:e=>e.preventDefault(),onDrop:t=>{t.preventDefault();let r=es.current;es.current=null,r&&r!==e.id&&S(t=>{let n=t.findIndex(e=>e.id===r),a=t.findIndex(t=>t.id===e.id);if(n<0||a<0)return t;let i=[...t],[o]=i.splice(n,1);return i.splice(a,0,o),s("term:reorder",{ids:i.map(e=>e.id)}).catch(()=>{}),i})},onClick:()=>T(e.id),onDoubleClick:()=>{var t;let r=null===(t=window.prompt("页签名称",e.title))||void 0===t?void 0:t.trim();r&&s("term:rename",{id:e.id,title:r}).then(()=>S(t=>t.map(t=>t.id===e.id?{...t,title:r}:t))).catch(()=>{})},children:[(0,n.jsx)("span",{children:e.title}),(0,n.jsx)("button",{tabIndex:-1,onClick:t=>{t.stopPropagation(),em(e.id)},children:"\xd7"})]},e.id)),(0,n.jsx)("button",{className:"terminal-add",disabled:k.length>=8,onClick:ex,children:"+"}),(0,n.jsxs)("div",{className:"terminal-connection",children:[(0,n.jsx)("span",{style:{width:8,height:8,borderRadius:99,background:l.connected?"var(--ui-success)":"var(--ui-error)"}}),(0,n.jsx)(p,{username:null!==(a=null===(t=i.user)||void 0===t?void 0:t.username)&&void 0!==a?a:"?",themeId:$,onThemeChange:ee,accent:en.keybar.accent,accentText:en.keybar.accentText}),(0,n.jsx)("button",{style:w.logoutBtn,onClick:i.logout,title:"退出登录","aria-label":"退出登录",children:"退出"})]})]}),(0,n.jsxs)("main",{className:"workspace ".concat(I?"show-tree":""," ").concat(W?"has-preview":""),style:w.workspace,children:[(0,n.jsx)("section",{className:"term-col",style:w.termCol,onPointerDownCapture:e=>{"touch"===e.pointerType&&eS(e.target)&&(ei.current={x:e.clientX,y:e.clientY,axis:"pending"})},onPointerMoveCapture:e=>{let t=ei.current;if(!t||"touch"!==e.pointerType)return;let r=e.clientX-t.x,n=e.clientY-t.y;if("pending"===t.axis){if(8>=Math.max(Math.abs(r),Math.abs(n)))return;if(Math.abs(n)>=1.2*Math.abs(r)){ei.current=null;return}t.axis="horizontal",ed(!0)}"horizontal"===t.axis&&(e.preventDefault(),el(r))},onPointerUpCapture:e=>{let t=ei.current;if(!t||"touch"!==e.pointerType)return;let r=e.clientX-t.x;"horizontal"===t.axis&&Math.abs(r)>=64?ek(r):ew()},onPointerCancelCapture:ew,children:(0,n.jsx)("div",{className:"terminal-track",style:{transform:"translate3d(calc(".concat(-(100*ey),"% + ").concat(eo,"px),0,0)"),transition:ec?"none":"transform 260ms cubic-bezier(.22,.8,.32,1)"},children:k.map(e=>{var t;return(0,n.jsx)("div",{className:"terminal-slide",children:(0,n.jsx)(h,{terminalId:e.id,title:e.title,visible:e.id===j,state:l,rpc:s,onEvent:b,onTerminalData:m,sendTerminalInput:v,keyOrder:Q,keybarHidden:K,onKeyOrderChange:Z,onKeybarHiddenChange:Y,terminalTheme:en,initialScrollLine:null!==(t=O[e.id])&&void 0!==t?t:null,onScrollLineChange:t=>D(r=>r[e.id]===t?r:{...r,[e.id]:t}),onRegisterFill:t=>E(e.id,t),onCwdChange:t=>t&&R(r=>({...r,[e.id]:t}))})},e.id)})})}),I&&(0,n.jsx)("div",{className:"drawer-mask",onClick:()=>H(!1)}),(0,n.jsxs)("aside",{className:"tree-col ".concat(I?"tree-col-open":""),style:w.treeCol,children:[(0,n.jsxs)("div",{className:"tree-head",style:w.treeHead,children:[(0,n.jsx)("button",{className:"files"===_?"drawer-tab-active":"",onClick:()=>U("files"),children:"文件"}),(0,n.jsx)("button",{className:"history"===_?"drawer-tab-active":"",onClick:()=>U("history"),children:"历史"}),(0,n.jsx)("span",{className:"tree-cwd",style:w.treeCwd,children:null!=ef?ef:""}),(0,n.jsx)("button",{style:{...w.iconBtn,marginLeft:"auto",flexShrink:0},onClick:()=>H(!1),"aria-label":"close drawer",children:"✕"})]}),"files"===_?(0,n.jsx)(g,{ready:c>0,followCwd:!0,cwd:ef,rpc:s,onEvent:b,onOpenFile:eg,selectedPath:W,initialRoot:V,initialFollow:q,onTreeStateChange:(e,t)=>{A(e),X(t)}}):(0,n.jsx)(d,{csrfToken:i.csrfToken,terminalId:j,onFill:M}),(0,n.jsxs)("div",{style:w.treeFoot,children:[(0,n.jsx)("span",{style:w.treeFootDot}),(0,n.jsx)("span",{children:"实时同步"})]})]}),W&&(0,n.jsx)("section",{className:"preview-col",style:w.previewCol,children:(0,n.jsx)(x,{path:W,rpc:s,onClose:()=>F(null)})})]}),(0,n.jsx)("button",{className:"fab-files",style:{...w.fabFiles,left:"".concat(100*J.xRatio,"%"),top:"".concat(100*J.yRatio,"%"),right:"auto",bottom:"auto",transform:"translate(-50%,-50%)"},onPointerDown:e=>{ea.current={moved:!1},e.currentTarget.setPointerCapture(e.pointerId)},onPointerMove:e=>{if(!ea.current)return;ea.current.moved=!0;let t=window.visualViewport;G({xRatio:Math.max(.05,Math.min(.95,e.clientX/((null==t?void 0:t.width)||innerWidth))),yRatio:Math.max(.08,Math.min(.92,(e.clientY-((null==t?void 0:t.offsetTop)||0))/((null==t?void 0:t.height)||innerHeight))),anchor:e.clientX<((null==t?void 0:t.width)||innerWidth)/2?"left":"right"})},onPointerUp:e=>{var t;e.currentTarget.releasePointerCapture(e.pointerId),(null===(t=ea.current)||void 0===t?void 0:t.moved)||H(e=>!e),ea.current=null},"aria-label":"files",children:"\uD83D\uDCC2"})]})}let y='\n html, body { margin: 0; background: var(--ui-root-bg, #0b0b10); overscroll-behavior: none; color: var(--ui-text, #e8e8ee); }\n * { -webkit-tap-highlight-color: transparent; }\n .terminal-tabs { display:flex; align-items:end; gap:4px; min-height:38px; padding:0 8px; overflow-x:auto; overflow-y:hidden; touch-action:pan-x; overscroll-behavior-x:contain; -webkit-overflow-scrolling:touch; scroll-behavior:smooth; background:var(--ui-tabbar-bg, #12141b); border-bottom:1px solid var(--ui-tabbar-border, #282b36); scrollbar-width:none; flex-shrink:0; }\n .terminal-tab { display:flex; align-items:center; gap:7px; min-width:74px; max-width:130px; height:32px; padding:0 7px 0 10px; border-radius:7px 7px 0 0; background:var(--ui-tab-bg, #1b1e28); color:var(--ui-tab-text, #8f93a4); font-size:11px; cursor:pointer; box-sizing:border-box; transition:background .2s ease,color .2s ease,box-shadow .2s ease; }\n .terminal-tab.active { color:var(--ui-tab-active-text, #edf0f7); background:var(--ui-tab-active-bg, #262b38); box-shadow:inset 0 2px var(--ui-tab-accent, #7aa2f7); }\n .terminal-tab span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; }\n .terminal-tab button { width:18px; height:18px; border:0; border-radius:4px; background:transparent; color:var(--ui-tab-text, #707586); padding:0; }\n .terminal-add { min-width:30px; height:28px; margin-bottom:2px; border:1px solid var(--ui-tabbar-border, #303442); border-radius:6px; background:var(--ui-tab-bg, #1b1e28); color:var(--ui-tab-text, #9da2b2); }\n .terminal-connection { position:sticky; right:-8px; margin-left:auto; align-self:stretch; display:flex; align-items:center; gap:7px; padding:0 9px; background:var(--ui-connection-bg, #12141b); color:var(--ui-connection-text, #777b8c); font-size:10.5px; flex-shrink:0; z-index:5; box-shadow:-8px 0 12px color-mix(in srgb, var(--ui-connection-bg, #12141b) 90%, transparent); }\n .theme-picker { position:relative; flex-shrink:0; z-index:6; }\n .theme-avatar { -webkit-tap-highlight-color:transparent; }\n .terminal-track { display:flex; width:100%; height:100%; will-change:transform; }\n .terminal-slide { flex:0 0 100%; width:100%; height:100%; min-width:0; }\n .terminal-screen { display:flex; flex-direction:column; min-height:0; overflow:hidden; }\n .terminal-screen .xterm { flex:1; height:100%; }\n .terminal-screen .xterm-scrollable-element { touch-action:pan-y; -webkit-overflow-scrolling:touch; }\n @media (prefers-reduced-motion: reduce) { .terminal-track,.terminal-tab { transition:none !important; } }\n .web-root {\n position: fixed;\n top: var(--vv-top, 0px);\n left: 0;\n right: 0;\n height: var(--vv-height, 100dvh) !important;\n }\n .tree-scroll {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n overscroll-behavior: contain;\n touch-action: pan-y;\n -webkit-overflow-scrolling: touch;\n padding: 6px;\n }\n .tree-location {\n position: sticky;\n top: -6px;\n z-index: 3;\n display: flex;\n align-items: center;\n gap: 5px;\n margin: -1px -1px 0;\n padding: 7px 7px 5px;\n background: color-mix(in srgb, var(--ui-tree-bg, #121218) 98%, transparent);\n }\n .tree-location input {\n flex: 1;\n min-width: 0;\n height: 28px;\n border: 1px solid var(--ui-panel-input-border, #30303b);\n border-radius: 6px;\n outline: none;\n padding: 0 8px;\n background: var(--ui-panel-input-bg, #0f0f15);\n color: var(--ui-panel-input-text, #d8d8df);\n font-family: "SF Mono", Menlo, monospace;\n font-size: 10.5px;\n }\n .tree-location input:focus { border-color: var(--ui-tab-accent, #536b9e); }\n .tree-location button {\n width: 28px;\n height: 28px;\n flex-shrink: 0;\n border: 1px solid var(--ui-panel-input-border, #30303a);\n border-radius: 6px;\n background: var(--ui-tab-bg, #202029);\n color: var(--ui-tab-text, #aaaab8);\n font-size: 12px;\n }\n .tree-location button[data-active="1"] {\n border-color: var(--ui-success, #4f6f58);\n color: var(--ui-success, #9ece6a);\n background: color-mix(in srgb, var(--ui-success, #9ece6a) 12%, var(--ui-tree-bg, #18221b));\n }\n .tree-head button { height:26px; padding:0 10px; border:0; border-radius:6px 6px 0 0; background:transparent; color:var(--ui-drawer-tab-text, #74798a); font-size:11px; }\n .tree-head button.drawer-tab-active { color:var(--ui-drawer-tab-active, #e4e7ef); box-shadow:inset 0 -2px var(--ui-tab-accent, #7aa2f7); }\n .history-panel { flex:1; min-height:0; overflow:auto; padding:7px; }\n .history-search { position:sticky; top:0; display:flex; gap:5px; padding:5px; background:var(--ui-tree-bg, #121218); z-index:2; }\n .history-search input { flex:1; min-width:0; height:28px; border:1px solid var(--ui-panel-input-border, #30303a); border-radius:6px; padding:0 8px; background:var(--ui-panel-input-bg, #0f0f15); color:var(--ui-panel-input-text, #ddd); font-size:11px; }\n .history-search button,.history-item button { border:1px solid var(--ui-panel-input-border, #30303a); border-radius:5px; background:var(--ui-tab-bg, #202029); color:var(--ui-connection-text, #999dab); font-size:10px; }\n .history-item { padding:9px 7px; border-bottom:1px solid var(--ui-tabbar-border, #242731); cursor:pointer; border-radius:6px; }\n .history-item:hover { background:color-mix(in srgb, var(--ui-tab-active-bg, #181b24) 80%, transparent); }\n .history-item:active { background:var(--ui-tab-active-bg, #1f2430); }\n .history-item-disabled { cursor:not-allowed; opacity:.55; }\n .history-item-disabled:hover { background:transparent; }\n .history-item:focus-visible { outline:1px solid var(--ui-tab-accent, #536b9e); outline-offset:-1px; }\n .history-item code { display:block; color:var(--ui-history-item-text, #d3d6df); font-size:11px; overflow-wrap:anywhere; }\n .history-item small { display:block; margin:4px 0 7px; color:var(--ui-history-meta, #656a79); font-size:9.5px; }\n .history-item-actions { display:flex; gap:5px; }\n .history-empty { padding:18px; color:#5d6270; font-size:11px; text-align:center; }\n .keybar-scroll { scrollbar-width:none; }\n .keybar-scroll::-webkit-scrollbar { display:none; }\n .tree-filter {\n position: sticky;\n top: 34px;\n z-index: 2;\n display: flex;\n align-items: center;\n gap: 6px;\n margin: -1px -1px 7px;\n padding: 7px 8px;\n border-bottom: 1px solid var(--ui-tabbar-border, #25252e);\n background: color-mix(in srgb, var(--ui-tree-bg, #121218) 97%, transparent);\n color: var(--ui-history-meta, #666678);\n backdrop-filter: blur(8px);\n }\n .tree-filter input {\n flex: 1;\n min-width: 0;\n height: 27px;\n border: 1px solid var(--ui-panel-input-border, #30303a);\n border-radius: 6px;\n outline: none;\n padding: 0 8px;\n background: var(--ui-panel-input-bg, #0f0f15);\n color: var(--ui-panel-input-text, #d8d8df);\n font-size: 11px;\n }\n .tree-filter input:focus { border-color: var(--ui-tab-accent, #536b9e); }\n .tree-filter button {\n width: 25px;\n height: 25px;\n padding: 0;\n border: 0;\n border-radius: 5px;\n background: var(--ui-tab-bg, #24242d);\n color: var(--ui-connection-text, #9999a6);\n font-size: 10px;\n }\n .tree-row {\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: 31px;\n padding-right: 7px;\n border-radius: 6px;\n font-size: 12px;\n white-space: nowrap;\n cursor: pointer;\n }\n .tree-row[data-selected="1"] { background: color-mix(in srgb, var(--ui-tab-accent, #26304a) 24%, transparent); }\n .tree-size { margin-left: auto; color: var(--ui-history-meta, #555); font-size: 10px; flex-shrink: 0; }\n\n /* phone-first: terminal is THE screen */\n .workspace { display: grid !important; grid-template-columns: 1fr; }\n .tree-col {\n position: fixed;\n top: var(--vv-top, 0px);\n height: var(--vv-height, 100dvh);\n right: 0;\n width: min(82vw, 320px); z-index: 40;\n transform: translateX(102%); transition: transform .22s ease;\n box-shadow: -12px 0 32px rgba(0,0,0,.5);\n }\n .tree-col-open { transform: translateX(0); }\n .drawer-mask { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 39; }\n .preview-col {\n position: fixed;\n top: var(--vv-top, 0px);\n left: 0;\n right: 0;\n height: var(--vv-height, 100dvh);\n z-index: 50;\n background: var(--ui-term-col-bg, #101014);\n }\n .fab-files { display: grid; place-items: center; }\n .cwd-hint { max-width: 40vw; }\n\n @media (min-width: 900px) {\n .workspace.has-preview { grid-template-columns: 1fr minmax(220px, 264px) minmax(320px, 34%); }\n .workspace:not(.has-preview) { grid-template-columns: 1fr minmax(220px, 264px); }\n /* desktop: tree is a persistent right column; hidden only via transform off */\n .tree-col {\n position: static; top: auto; height: auto; width: auto; transform: none;\n box-shadow: none; border-left: 1px solid var(--ui-tree-border, #1e1e26);\n }\n .workspace:not(.show-tree) .tree-col { display: none; }\n .preview-col { position: relative; inset: auto; height: auto; border-left: 1px solid var(--ui-tree-border, #1e1e26); }\n .fab-files { display: none; }\n .drawer-mask { display: none; }\n }\n',w={root:{height:"100dvh",display:"flex",flexDirection:"column",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", sans-serif',overflow:"hidden"},iconBtn:{minWidth:28,height:28,borderRadius:7,border:"1px solid #333",background:"#17171d",color:"#ccc",fontSize:13},workspace:{flex:1,minHeight:0,display:"grid",gridTemplateColumns:"1fr",position:"relative"},treeCol:{background:"var(--ui-tree-bg, #121218)",minHeight:0,display:"flex",flexDirection:"column"},treeHead:{display:"flex",alignItems:"center",gap:8,padding:"10px 12px 4px",fontSize:11,textTransform:"uppercase",letterSpacing:1,color:"#778",flexShrink:0},treeCwd:{fontSize:10,color:"#556",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:150,textTransform:"none",letterSpacing:0},treeFoot:{display:"flex",alignItems:"center",gap:7,minHeight:31,padding:"6px 11px calc(env(safe-area-inset-bottom) + 6px)",borderTop:"1px solid var(--ui-tabbar-border, #282832)",boxShadow:"0 -5px 16px rgba(0,0,0,.22)",background:"var(--ui-tab-bg, #15151c)",color:"var(--ui-connection-text, #777789)",fontSize:10.5,flexShrink:0},treeFootDot:{width:6,height:6,borderRadius:99,background:"var(--ui-success, #9ece6a)",boxShadow:"0 0 0 2px color-mix(in srgb, var(--ui-success, #9ece6a) 12%, transparent)",flexShrink:0},termCol:{minWidth:0,minHeight:0,display:"flex",flexDirection:"column",background:"var(--ui-term-col-bg, #101014)",gridColumn:1,overflow:"hidden"},previewCol:{minWidth:0,minHeight:0},fabFiles:{position:"fixed",right:14,bottom:"calc(env(safe-area-inset-bottom) + 64px)",width:44,height:44,borderRadius:99,border:"1px solid var(--ui-fab-border, #2c2c38)",background:"var(--ui-fab-bg, #1b1b26)",color:"var(--ui-text, #dde)",fontSize:18,zIndex:45,boxShadow:"0 4px 16px rgba(0,0,0,.45)"},logoutBtn:{height:24,padding:"0 8px",border:"1px solid var(--ui-muted-border, #2d303a)",borderRadius:6,background:"var(--ui-muted-surface, #171920)",color:"var(--ui-muted-text, #8c909f)",fontSize:10.5}}}},function(e){e.O(0,[37,183,744],function(){return e(e.s=6736)}),_N_E=e.O()}]);
|
/package/runtime/.next/static/{47UkTmBGxP5qz2mnMbNEp → dclalTmecO-HMVQvSKG7g}/_buildManifest.js
RENAMED
|
File without changes
|
/package/runtime/.next/static/{47UkTmBGxP5qz2mnMbNEp → dclalTmecO-HMVQvSKG7g}/_ssgManifest.js
RENAMED
|
File without changes
|