@adhdev/daemon-standalone 0.7.5 → 0.7.7

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/dist/index.js CHANGED
@@ -30,6 +30,102 @@ var path = __toESM(require("path"));
30
30
  var fs = __toESM(require("fs"));
31
31
  var os = __toESM(require("os"));
32
32
  var import_daemon_core = require("@adhdev/daemon-core");
33
+
34
+ // src/session-host.ts
35
+ var import_child_process = require("child_process");
36
+ var import_session_host_core = require("@adhdev/session-host-core");
37
+ var STARTUP_TIMEOUT_MS = 8e3;
38
+ var STARTUP_POLL_MS = 200;
39
+ var SESSION_HOST_APP_NAME = process.env.ADHDEV_SESSION_HOST_NAME || "adhdev";
40
+ async function canConnect(endpoint) {
41
+ const client = new import_session_host_core.SessionHostClient({ endpoint });
42
+ try {
43
+ await client.connect();
44
+ await client.close();
45
+ return true;
46
+ } catch {
47
+ return false;
48
+ }
49
+ }
50
+ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
51
+ const deadline = Date.now() + timeoutMs;
52
+ while (Date.now() < deadline) {
53
+ if (await canConnect(endpoint)) return;
54
+ await new Promise((resolve) => setTimeout(resolve, STARTUP_POLL_MS));
55
+ }
56
+ throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
57
+ }
58
+ function resolveSessionHostEntry() {
59
+ return require.resolve("@adhdev/session-host-daemon");
60
+ }
61
+ async function runSessionHostCli(args) {
62
+ const entry = resolveSessionHostEntry();
63
+ const child = (0, import_child_process.spawn)(process.execPath, [entry, ...args], {
64
+ stdio: "inherit",
65
+ env: {
66
+ ...process.env,
67
+ ADHDEV_SESSION_HOST_NAME: SESSION_HOST_APP_NAME
68
+ }
69
+ });
70
+ return await new Promise((resolve, reject) => {
71
+ child.on("error", reject);
72
+ child.on("exit", (code) => resolve(code ?? 0));
73
+ });
74
+ }
75
+ async function ensureSessionHostReady() {
76
+ const endpoint = (0, import_session_host_core.getDefaultSessionHostEndpoint)(SESSION_HOST_APP_NAME);
77
+ if (await canConnect(endpoint)) return endpoint;
78
+ const entry = resolveSessionHostEntry();
79
+ const child = (0, import_child_process.spawn)(process.execPath, [entry], {
80
+ detached: true,
81
+ stdio: "ignore",
82
+ windowsHide: true
83
+ });
84
+ child.unref();
85
+ await waitForReady(endpoint);
86
+ return endpoint;
87
+ }
88
+ async function listHostedCliRuntimes(endpoint) {
89
+ const client = new import_session_host_core.SessionHostClient({ endpoint });
90
+ try {
91
+ const response = await client.request({
92
+ type: "list_sessions",
93
+ payload: {}
94
+ });
95
+ if (!response.success || !response.result) {
96
+ return [];
97
+ }
98
+ return response.result.filter((record) => record.category === "cli" && ["running", "interrupted"].includes(record.lifecycle)).sort((a, b) => b.lastActivityAt - a.lastActivityAt).map((record) => ({
99
+ runtimeId: record.sessionId,
100
+ runtimeKey: record.runtimeKey,
101
+ displayName: record.displayName,
102
+ workspaceLabel: record.workspaceLabel,
103
+ lifecycle: record.lifecycle,
104
+ recoveryState: typeof record.meta?.runtimeRecoveryState === "string" ? String(record.meta.runtimeRecoveryState) : null,
105
+ cliType: record.providerType,
106
+ workspace: record.workspace,
107
+ cliArgs: Array.isArray(record.meta?.cliArgs) ? record.meta.cliArgs : []
108
+ }));
109
+ } finally {
110
+ await client.close().catch(() => {
111
+ });
112
+ }
113
+ }
114
+ async function proxySessionHostList(showAll = false) {
115
+ await ensureSessionHostReady();
116
+ return runSessionHostCli(["list", ...showAll ? ["--all"] : []]);
117
+ }
118
+ async function proxySessionHostAttach(target, options = {}) {
119
+ await ensureSessionHostReady();
120
+ const args = ["attach", target];
121
+ if (options.readOnly) args.push("--read-only");
122
+ if (options.takeover) args.push("--takeover");
123
+ return runSessionHostCli(args);
124
+ }
125
+
126
+ // src/index.ts
127
+ var import_session_host_core2 = require("@adhdev/session-host-core");
128
+ var import_api = require("@adhdev/terminal-mux-control/api");
33
129
  var DEFAULT_PORT = 3847;
34
130
  var STATUS_INTERVAL = 2e3;
35
131
  var pkgVersion = process.env.ADHDEV_PKG_VERSION || "unknown";
@@ -61,9 +157,12 @@ var StandaloneServer = class {
61
157
  running = false;
62
158
  components = null;
63
159
  devServer = null;
160
+ sessionHostEndpoint = null;
64
161
  async start(options = {}) {
65
162
  const port = options.port || DEFAULT_PORT;
66
163
  const host = options.host || "127.0.0.1";
164
+ const sessionHostEndpoint = await ensureSessionHostReady();
165
+ this.sessionHostEndpoint = sessionHostEndpoint;
67
166
  this.authToken = options.token || process.env.ADHDEV_TOKEN || null;
68
167
  this.components = await (0, import_daemon_core.initDaemonComponents)({
69
168
  cliManagerDeps: {
@@ -81,7 +180,20 @@ var StandaloneServer = class {
81
180
  }),
82
181
  onStatusChange: () => this.broadcastStatus(),
83
182
  removeAgentTracking: () => {
84
- }
183
+ },
184
+ createPtyTransportFactory: ({ runtimeId, providerType, workspace, cliArgs, attachExisting }) => new import_daemon_core.SessionHostPtyTransportFactory({
185
+ endpoint: sessionHostEndpoint,
186
+ clientId: `daemon-${process.pid}`,
187
+ runtimeId,
188
+ providerType,
189
+ workspace,
190
+ attachExisting,
191
+ meta: {
192
+ cliArgs: cliArgs || [],
193
+ managedBy: "adhdev-standalone"
194
+ }
195
+ }),
196
+ listHostedCliRuntimes: async () => listHostedCliRuntimes(sessionHostEndpoint)
85
197
  },
86
198
  onStatusChange: () => this.broadcastStatus(),
87
199
  onStreamsUpdated: (ideType, streams) => {
@@ -92,6 +204,7 @@ var StandaloneServer = class {
92
204
  tickIntervalMs: 3e3,
93
205
  cdpScanIntervalMs: 15e3
94
206
  });
207
+ await this.components.cliManager.restoreHostedSessions();
95
208
  if (options.dev) {
96
209
  this.devServer = await (0, import_daemon_core.startDaemonDevSupport)({
97
210
  components: this.components,
@@ -190,12 +303,116 @@ var StandaloneServer = class {
190
303
  }
191
304
  }
192
305
  const apiPath = url.startsWith("/api/v1/") ? url.slice(7) : null;
306
+ const parsedUrl = new URL(url, `http://${req.headers.host || "localhost"}`);
193
307
  if (apiPath === "/status" && method === "GET") {
194
308
  const status = this.getStatus(getSharedSnapshot());
195
309
  res.writeHead(200, { "Content-Type": "application/json" });
196
310
  res.end(JSON.stringify(status));
197
311
  return;
198
312
  }
313
+ if (apiPath?.startsWith("/mux/")) {
314
+ const muxParts = parsedUrl.pathname.replace(/^\/api\/v1\/mux\//, "").split("/").filter(Boolean);
315
+ const [workspaceSegment, action] = muxParts;
316
+ const workspaceName = workspaceSegment ? decodeURIComponent(workspaceSegment) : "";
317
+ if (!workspaceName || !action) {
318
+ res.writeHead(400, { "Content-Type": "application/json" });
319
+ res.end(JSON.stringify({ error: "Invalid mux route" }));
320
+ return;
321
+ }
322
+ if (action === "state" && method === "GET") {
323
+ void (async () => {
324
+ const result = await (0, import_api.getWorkspaceState)(workspaceName);
325
+ if (!result?.success || !result.result) {
326
+ res.writeHead(404, { "Content-Type": "application/json" });
327
+ res.end(JSON.stringify({ error: result?.error || "Workspace not available" }));
328
+ return;
329
+ }
330
+ res.writeHead(200, { "Content-Type": "application/json" });
331
+ res.end(JSON.stringify(result.result));
332
+ })().catch((error) => {
333
+ res.writeHead(500, { "Content-Type": "application/json" });
334
+ res.end(JSON.stringify({ error: error?.message || String(error) }));
335
+ });
336
+ return;
337
+ }
338
+ if (action === "socket-info" && method === "GET") {
339
+ void (async () => {
340
+ const result = await (0, import_api.getWorkspaceSocketInfo)(workspaceName);
341
+ res.writeHead(200, { "Content-Type": "application/json" });
342
+ res.end(JSON.stringify(result));
343
+ })().catch((error) => {
344
+ res.writeHead(500, { "Content-Type": "application/json" });
345
+ res.end(JSON.stringify({ error: error?.message || String(error) }));
346
+ });
347
+ return;
348
+ }
349
+ if (action === "control" && method === "POST") {
350
+ let body = "";
351
+ req.on("data", (chunk) => {
352
+ body += chunk;
353
+ });
354
+ req.on("end", async () => {
355
+ try {
356
+ const { type, payload } = JSON.parse(body || "{}");
357
+ const result = await (0, import_api.requestWorkspaceControl)(workspaceName, { type, payload });
358
+ if (!result?.success) {
359
+ res.writeHead(404, { "Content-Type": "application/json" });
360
+ res.end(JSON.stringify({ error: result?.error || "Workspace control unavailable" }));
361
+ return;
362
+ }
363
+ res.writeHead(200, { "Content-Type": "application/json" });
364
+ res.end(JSON.stringify(result.result ?? { success: true }));
365
+ } catch (error) {
366
+ res.writeHead(400, { "Content-Type": "application/json" });
367
+ res.end(JSON.stringify({ error: error?.message || String(error) }));
368
+ }
369
+ });
370
+ return;
371
+ }
372
+ if (action === "events" && method === "GET") {
373
+ void this.handleMuxEvents(req, res, workspaceName);
374
+ return;
375
+ }
376
+ }
377
+ if (apiPath?.startsWith("/runtime/")) {
378
+ const runtimeParts = parsedUrl.pathname.replace(/^\/api\/v1\/runtime\//, "").split("/").filter(Boolean);
379
+ const [sessionSegment, action] = runtimeParts;
380
+ const sessionId = sessionSegment ? decodeURIComponent(sessionSegment) : "";
381
+ if (!sessionId || !action) {
382
+ res.writeHead(400, { "Content-Type": "application/json" });
383
+ res.end(JSON.stringify({ error: "Invalid runtime route" }));
384
+ return;
385
+ }
386
+ if (action === "snapshot" && method === "GET") {
387
+ void (async () => {
388
+ const client = new import_session_host_core2.SessionHostClient({ endpoint: this.sessionHostEndpoint || void 0 });
389
+ try {
390
+ const snapshot = await client.request({
391
+ type: "get_snapshot",
392
+ payload: { sessionId }
393
+ });
394
+ if (!snapshot.success || !snapshot.result) {
395
+ res.writeHead(404, { "Content-Type": "application/json" });
396
+ res.end(JSON.stringify({ error: snapshot.error || "Runtime snapshot unavailable" }));
397
+ return;
398
+ }
399
+ res.writeHead(200, { "Content-Type": "application/json" });
400
+ res.end(JSON.stringify({ sessionId, ...snapshot.result }));
401
+ } finally {
402
+ await client.close().catch(() => {
403
+ });
404
+ }
405
+ })().catch((error) => {
406
+ res.writeHead(500, { "Content-Type": "application/json" });
407
+ res.end(JSON.stringify({ error: error?.message || String(error) }));
408
+ });
409
+ return;
410
+ }
411
+ if (action === "events" && method === "GET") {
412
+ void this.handleRuntimeEvents(req, res, sessionId);
413
+ return;
414
+ }
415
+ }
199
416
  if (apiPath === "/command" && method === "POST") {
200
417
  let body = "";
201
418
  req.on("data", (chunk) => {
@@ -243,6 +460,90 @@ var StandaloneServer = class {
243
460
  res.writeHead(404, { "Content-Type": "application/json" });
244
461
  res.end(JSON.stringify({ error: "Not found" }));
245
462
  }
463
+ async handleMuxEvents(req, res, workspaceName) {
464
+ const socketInfo = await (0, import_api.getWorkspaceSocketInfo)(workspaceName);
465
+ if (!socketInfo.live) {
466
+ res.writeHead(404, { "Content-Type": "application/json" });
467
+ res.end(JSON.stringify({ error: "Workspace control socket unavailable" }));
468
+ return;
469
+ }
470
+ const client = new import_api.AdhMuxControlClient(workspaceName);
471
+ await client.connect();
472
+ res.writeHead(200, {
473
+ "Content-Type": "text/event-stream",
474
+ "Cache-Control": "no-cache, no-transform",
475
+ Connection: "keep-alive",
476
+ "X-Accel-Buffering": "no"
477
+ });
478
+ const writeEvent = (event) => {
479
+ res.write(`event: ${event.type}
480
+ `);
481
+ res.write(`data: ${JSON.stringify(event)}
482
+
483
+ `);
484
+ };
485
+ const initial = await client.request({
486
+ type: "workspace_state"
487
+ });
488
+ if (initial.success && initial.result) {
489
+ writeEvent({
490
+ type: "workspace_update",
491
+ payload: initial.result
492
+ });
493
+ }
494
+ const unsubscribe = client.onEvent(writeEvent);
495
+ const heartbeat = setInterval(() => {
496
+ res.write(": ping\n\n");
497
+ }, 15e3);
498
+ const cleanup = () => {
499
+ clearInterval(heartbeat);
500
+ unsubscribe();
501
+ void client.close().catch(() => {
502
+ });
503
+ };
504
+ req.on("close", cleanup);
505
+ req.on("aborted", cleanup);
506
+ }
507
+ async handleRuntimeEvents(req, res, sessionId) {
508
+ const client = new import_session_host_core2.SessionHostClient({ endpoint: this.sessionHostEndpoint || void 0 });
509
+ await client.connect();
510
+ res.writeHead(200, {
511
+ "Content-Type": "text/event-stream",
512
+ "Cache-Control": "no-cache, no-transform",
513
+ Connection: "keep-alive",
514
+ "X-Accel-Buffering": "no"
515
+ });
516
+ const snapshot = await client.request({
517
+ type: "get_snapshot",
518
+ payload: { sessionId }
519
+ });
520
+ if (snapshot.success && snapshot.result) {
521
+ res.write("event: runtime_snapshot\n");
522
+ res.write(`data: ${JSON.stringify({ sessionId, ...snapshot.result })}
523
+
524
+ `);
525
+ }
526
+ const writeEvent = (event) => {
527
+ if (event.sessionId !== sessionId) return;
528
+ res.write(`event: ${event.type}
529
+ `);
530
+ res.write(`data: ${JSON.stringify(event)}
531
+
532
+ `);
533
+ };
534
+ const unsubscribe = client.onEvent(writeEvent);
535
+ const heartbeat = setInterval(() => {
536
+ res.write(": ping\n\n");
537
+ }, 15e3);
538
+ const cleanup = () => {
539
+ clearInterval(heartbeat);
540
+ unsubscribe();
541
+ void client.close().catch(() => {
542
+ });
543
+ };
544
+ req.on("close", cleanup);
545
+ req.on("aborted", cleanup);
546
+ }
246
547
  // ─── WebSocket Handler ───
247
548
  handleWsConnection(ws) {
248
549
  const MAX_WS_CLIENTS = 10;
@@ -391,6 +692,23 @@ var StandaloneServer = class {
391
692
  };
392
693
  async function main() {
393
694
  const args = process.argv.slice(2);
695
+ const primaryCommand = args[0] || "";
696
+ if (primaryCommand === "attach") {
697
+ const target = args[1];
698
+ if (!target) {
699
+ console.error("Usage: adhdev attach <sessionId> [--read-only|--takeover]");
700
+ process.exit(1);
701
+ }
702
+ const readOnly = args.includes("--read-only");
703
+ const takeover = args.includes("--takeover");
704
+ const exitCode = await proxySessionHostAttach(target, { readOnly, takeover });
705
+ process.exit(exitCode);
706
+ }
707
+ if (primaryCommand === "list" || primaryCommand === "runtimes") {
708
+ const showAll = args.includes("--all");
709
+ const exitCode = await proxySessionHostList(showAll);
710
+ process.exit(exitCode);
711
+ }
394
712
  const options = {};
395
713
  for (let i = 0; i < args.length; i++) {
396
714
  if ((args[i] === "--port" || args[i] === "-p") && args[i + 1]) {
@@ -417,6 +735,8 @@ async function main() {
417
735
  if (args[i] === "--help" || args[i] === "-h") {
418
736
  console.log(`
419
737
  Usage: adhdev-standalone [options]
738
+ adhdev-standalone list [--all]
739
+ adhdev-standalone attach <sessionId> [--read-only|--takeover]
420
740
 
421
741
  Options:
422
742
  --port, -p <port> Port to run the standalone server on (default: 3847)
@@ -426,6 +746,11 @@ Options:
426
746
  --public <path> Custom path to the web dashboard distribution
427
747
  --no-open Do not automatically open the browser on startup
428
748
  --help, -h Show this help message
749
+
750
+ Runtime commands:
751
+ list, runtimes Show hosted CLI runtimes
752
+ attach Attach local terminal to a runtime
753
+ open Open a local terminal window running adhmux for a runtime
429
754
  `);
430
755
  process.exit(0);
431
756
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * daemon-standalone — Embedded HTTP/WS server for local dashboard\n *\n * Standalone-only server:\n * 1. DaemonCore init (IDE detection, CDP connection, Provider loading)\n * 2. HTTP REST API — /api/v1/status, /api/v1/command\n * 3. WebSocket — ws://localhost:3847/ws (real-time status broadcast + command execution)\n * 4. Static file serving — web-standalone build output\n *\n * Usage:\n * npx @adhdev/daemon-standalone\n * npx @adhdev/daemon-standalone --port 4000\n */\n\nimport { createServer, type IncomingMessage } from 'http';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\n\nimport {\n LOG,\n initDaemonComponents,\n startDaemonDevSupport,\n shutdownDaemonComponents,\n loadConfig,\n buildStatusSnapshot,\n forwardAgentStreamsToIdeInstance,\n type DaemonComponents,\n type StatusResponse,\n type AgentEntry,\n} from '@adhdev/daemon-core';\n\n// ─── Constants ───\nconst DEFAULT_PORT = 3847;\nconst STATUS_INTERVAL = 2000;\n\nlet pkgVersion = process.env.ADHDEV_PKG_VERSION || 'unknown';\nif (pkgVersion === 'unknown') {\n try {\n const possiblePaths = [\n path.join(__dirname, '..', 'package.json'),\n path.join(__dirname, 'package.json'),\n ];\n for (const candidate of possiblePaths) {\n try {\n const data = JSON.parse(fs.readFileSync(candidate, 'utf-8'));\n if (data.version) {\n pkgVersion = data.version;\n break;\n }\n } catch { /* noop */ }\n }\n } catch { /* noop */ }\n}\n\n// ─── Types ───\ninterface StandaloneOptions {\n port?: number;\n host?: string;\n publicDir?: string;\n open?: boolean;\n token?: string;\n dev?: boolean;\n}\n\ninterface WsMessage {\n type: string;\n requestId?: string;\n data?: Record<string, any>;\n}\n\n\n// ─── Standalone Server ───\n\nclass StandaloneServer {\n private httpServer: ReturnType<typeof createServer> | null = null;\n private wss: WebSocketServer | null = null;\n private clients = new Set<WebSocket>();\n private authToken: string | null = null;\n private statusTimer: NodeJS.Timeout | null = null;\n private running = false;\n private components: DaemonComponents | null = null;\n private devServer: Awaited<ReturnType<typeof startDaemonDevSupport>> | null = null;\n\n async start(options: StandaloneOptions = {}): Promise<void> {\n const port = options.port || DEFAULT_PORT;\n const host = options.host || '127.0.0.1';\n\n // Auth token setup (opt-in only)\n this.authToken = options.token || process.env.ADHDEV_TOKEN || null;\n\n // Initialize all core components via daemon-core bootstrapper\n this.components = await initDaemonComponents({\n cliManagerDeps: {\n getServerConn: () => null,\n getP2p: () => ({\n broadcastPtyOutput: (key: string, data: string) => {\n if (this.clients.size === 0) return;\n const msg = JSON.stringify({ type: 'pty_output', cliId: key, data });\n for (const client of this.clients) {\n if (client.readyState === 1) { // OPEN\n client.send(msg);\n }\n }\n }\n }),\n onStatusChange: () => this.broadcastStatus(),\n removeAgentTracking: () => {},\n },\n onStatusChange: () => this.broadcastStatus(),\n onStreamsUpdated: (ideType: string, streams: any[]) => {\n if (!this.components) return;\n forwardAgentStreamsToIdeInstance(this.components.instanceManager, ideType, streams);\n this.broadcastStatus();\n },\n tickIntervalMs: 3000,\n cdpScanIntervalMs: 15_000,\n });\n\n // DevServer (optional)\n if (options.dev) {\n this.devServer = await startDaemonDevSupport({\n components: this.components,\n logFn: (msg: string) => console.log(msg),\n });\n }\n\n // 5. HTTP Server\n this.httpServer = createServer((req, res) => {\n this.handleHttp(req, res, options.publicDir);\n });\n\n // 6. WebSocket Server (upgrade)\n this.wss = new WebSocketServer({ noServer: true });\n this.httpServer.on('upgrade', (req, socket, head) => {\n const wsUrl = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);\n if (wsUrl.pathname === '/ws') {\n // Token auth for WS\n if (this.authToken) {\n const urlToken = wsUrl.searchParams.get('token');\n if (urlToken !== this.authToken) {\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n }\n this.wss!.handleUpgrade(req, socket, head, (ws) => {\n this.handleWsConnection(ws);\n });\n } else {\n socket.destroy();\n }\n });\n\n // 7. Status broadcast timer\n this.statusTimer = setInterval(() => {\n this.broadcastStatus();\n }, STATUS_INTERVAL);\n\n // 8. Start listening\n this.running = true;\n await new Promise<void>((resolve) => {\n this.httpServer!.listen(port, host, () => {\n resolve();\n });\n });\n\n console.log('');\n console.log('🚀 ADHDev Standalone Server');\n console.log(` http://${host === '0.0.0.0' ? 'localhost' : host}:${port}`);\n console.log(` ws://${host === '0.0.0.0' ? 'localhost' : host}:${port}/ws`);\n if (host === '0.0.0.0') {\n const lanIps = this.getLanIPs();\n for (const ip of lanIps) {\n console.log(` http://${ip}:${port} (LAN)`);\n }\n }\n if (this.authToken) {\n console.log(` 🔑 Token: ${this.authToken}`);\n }\n console.log('');\n\n const cdpCount = [...this.components.cdpManagers.values()].filter(m => m.isConnected).length;\n console.log(` CDP: ${cdpCount > 0 ? `✅ ${cdpCount} connected` : '❌ none'}`);\n console.log(` Providers: ${this.components.providerLoader.getAll().length} loaded`);\n if (options.dev) {\n console.log(` 🛠️ DevConsole: http://127.0.0.1:19280`);\n }\n console.log('');\n console.log(' Press Ctrl+C to stop.');\n console.log('');\n\n // Open browser\n if (options.open !== false) {\n try {\n const open = (await import('open')).default;\n await open(`http://localhost:${port}`);\n } catch { /* noop */ }\n }\n\n // Signal handling\n process.on('SIGINT', () => this.stop());\n process.on('SIGTERM', () => this.stop());\n }\n\n // ─── HTTP Handler ───\n\n private handleHttp(\n req: IncomingMessage,\n res: import('http').ServerResponse,\n publicDir?: string\n ): void {\n const url = req.url || '/';\n const method = req.method || 'GET';\n let sharedSnapshotCache: ReturnType<StandaloneServer['buildSharedSnapshot']> | null = null;\n const getSharedSnapshot = () => {\n if (!sharedSnapshotCache) sharedSnapshotCache = this.buildSharedSnapshot();\n return sharedSnapshotCache;\n };\n\n // CORS\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n if (method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n // Token auth for API routes\n if (this.authToken && url.startsWith('/api/')) {\n const authHeader = req.headers['authorization'];\n const bearerToken = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null;\n const queryToken = new URL(url, `http://${req.headers.host || 'localhost'}`).searchParams.get('token');\n if (bearerToken !== this.authToken && queryToken !== this.authToken) {\n res.writeHead(401, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Unauthorized. Provide token via Authorization header or ?token= query.' }));\n return;\n }\n }\n\n // ─── API Routes (v1) ───\n const apiPath = url.startsWith('/api/v1/') ? url.slice(7) : null; // /api/v1/status → /status\n\n if (apiPath === '/status' && method === 'GET') {\n const status = this.getStatus(getSharedSnapshot());\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(status));\n return;\n }\n\n if (apiPath === '/command' && method === 'POST') {\n let body = '';\n req.on('data', (chunk) => { body += chunk; });\n req.on('end', async () => {\n try {\n const { type, payload } = JSON.parse(body);\n const result = await this.executeCommand(type, payload || {});\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(result));\n } catch (e: any) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ success: false, error: e.message }));\n }\n });\n return;\n }\n\n // ─── Static Files ───\n if (publicDir) {\n const filePath = url === '/' ? '/index.html' : url;\n const fullPath = path.join(publicDir, filePath);\n if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {\n const ext = path.extname(fullPath);\n const mimeTypes: Record<string, string> = {\n '.html': 'text/html',\n '.js': 'application/javascript',\n '.css': 'text/css',\n '.json': 'application/json',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n };\n res.writeHead(200, { 'Content-Type': mimeTypes[ext] || 'application/octet-stream' });\n fs.createReadStream(fullPath).pipe(res);\n return;\n }\n // SPA fallback → index.html\n const indexPath = path.join(publicDir, 'index.html');\n if (fs.existsSync(indexPath) && !url.startsWith('/api/')) {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n fs.createReadStream(indexPath).pipe(res);\n return;\n }\n }\n\n // 404\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n }\n\n // ─── WebSocket Handler ───\n\n private handleWsConnection(ws: WebSocket): void {\n // Max client limit to prevent connection storms\n const MAX_WS_CLIENTS = 10;\n if (this.clients.size >= MAX_WS_CLIENTS) {\n // Close oldest connection\n const oldest = this.clients.values().next().value;\n if (oldest) {\n try { (oldest as WebSocket).close(1000, 'Too many connections'); } catch {}\n this.clients.delete(oldest);\n }\n }\n this.clients.add(ws);\n console.log(`[WS] Client connected (total: ${this.clients.size})`);\n\n // Send initial status immediately\n const status = this.getStatus();\n ws.send(JSON.stringify({ type: 'status', data: status }));\n\n ws.on('message', async (raw) => {\n try {\n const msg: WsMessage = JSON.parse(raw.toString());\n if (msg.type === 'command' && msg.data) {\n const { type, payload } = msg.data;\n const requestId = msg.requestId;\n const result = await this.executeCommand(type, payload || {});\n ws.send(JSON.stringify({ type: 'command_result', requestId, data: result }));\n }\n } catch (e: any) {\n const requestId = (() => { try { return JSON.parse(raw.toString()).requestId; } catch { return undefined; } })();\n ws.send(JSON.stringify({ type: 'error', requestId, data: { message: e.message } }));\n }\n });\n\n ws.on('close', () => {\n this.clients.delete(ws);\n console.log(`[WS] Client disconnected (total: ${this.clients.size})`);\n });\n\n ws.on('error', () => {\n this.clients.delete(ws);\n });\n }\n\n // ─── Core Logic ───\n\n private buildSharedSnapshot() {\n const cfgSnap = loadConfig();\n const machineId = cfgSnap.machineId || 'mach_unknown';\n const allStates = this.components!.instanceManager.collectAllStates();\n\n return buildStatusSnapshot({\n allStates,\n cdpManagers: this.components!.cdpManagers as Map<string, unknown>,\n providerLoader: this.components!.providerLoader,\n detectedIdes: this.components!.detectedIdes.value,\n instanceId: `standalone_${machineId}`,\n version: pkgVersion,\n daemonMode: false,\n });\n }\n\n private getStatus(snapshot: ReturnType<StandaloneServer['buildSharedSnapshot']> = this.buildSharedSnapshot()): StatusResponse {\n const cfgSnap = loadConfig();\n\n return {\n ...snapshot,\n id: snapshot.instanceId,\n daemonMode: false,\n type: 'standalone',\n platform: snapshot.machine.platform,\n hostname: snapshot.machine.hostname,\n userName: cfgSnap.userName || undefined,\n system: {\n cpus: snapshot.machine.cpus,\n totalMem: snapshot.machine.totalMem,\n freeMem: snapshot.machine.freeMem,\n availableMem: snapshot.machine.availableMem,\n loadavg: snapshot.machine.loadavg,\n uptime: snapshot.machine.uptime,\n arch: snapshot.machine.arch,\n },\n };\n }\n\n private async executeCommand(type: string, args: any): Promise<any> {\n if (!this.components) {\n return { success: false, error: 'Components not initialized' };\n }\n const result = await this.components.router.execute(type, args, 'standalone');\n if (type.startsWith('workspace_')) this.broadcastStatus();\n return result;\n }\n\n private broadcastStatus(): void {\n if (this.clients.size === 0) return;\n const status = this.getStatus();\n const msg = JSON.stringify({ type: 'status', data: status });\n const cdpCount = [...this.components!.cdpManagers.values()].filter(m => m.isConnected).length;\n LOG.debug('Broadcast', `status → ${this.clients.size} client(s), ${(status as any).sessions?.length || 0} session(s), ${cdpCount} CDP`);\n for (const client of this.clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(msg);\n }\n }\n }\n\n // ─── Network ───\n\n private getLanIPs(): string[] {\n const interfaces = os.networkInterfaces();\n const ips: string[] = [];\n for (const iface of Object.values(interfaces)) {\n if (!iface) continue;\n for (const info of iface) {\n if (info.family === 'IPv4' && !info.internal) {\n ips.push(info.address);\n }\n }\n }\n return ips;\n }\n\n // ─── Lifecycle ───\n\n async stop(): Promise<void> {\n if (!this.running) return;\n this.running = false;\n\n console.log('\\n Shutting down...');\n\n if (this.statusTimer) {\n clearInterval(this.statusTimer);\n this.statusTimer = null;\n }\n\n // Close WS clients\n for (const ws of this.clients) {\n try { ws.close(); } catch { /* noop */ }\n }\n this.clients.clear();\n\n // Close WSS\n if (this.wss) {\n this.wss.close();\n this.wss = null;\n }\n\n // Shutdown core components\n if (this.components) {\n await shutdownDaemonComponents(this.components);\n }\n\n // HTTP server\n if (this.httpServer) {\n this.httpServer.close();\n this.httpServer = null;\n }\n\n console.log(' ✓ ADHDev Standalone stopped.\\n');\n process.exit(0);\n }\n}\n\n// ─── CLI ───\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const options: StandaloneOptions = {};\n\n // Parse simple args\n for (let i = 0; i < args.length; i++) {\n if ((args[i] === '--port' || args[i] === '-p') && args[i + 1]) {\n options.port = parseInt(args[i + 1]);\n i++;\n }\n if (args[i] === '--host' || args[i] === '-H') {\n options.host = '0.0.0.0';\n }\n if (args[i] === '--public' && args[i + 1]) {\n options.publicDir = args[i + 1];\n i++;\n }\n if (args[i] === '--no-open') {\n options.open = false;\n }\n if (args[i] === '--dev') {\n (options as any).dev = true;\n }\n if (args[i] === '--token' && args[i + 1]) {\n options.token = args[i + 1];\n i++;\n }\n if (args[i] === '--help' || args[i] === '-h') {\n console.log(`\nUsage: adhdev-standalone [options]\n\nOptions:\n --port, -p <port> Port to run the standalone server on (default: 3847)\n --host, -H Allow external network connections (binds to 0.0.0.0)\n --token <token> Set an authentication token for the dashboard UI\n --dev Enable DevConsole to debug and test providers\n --public <path> Custom path to the web dashboard distribution\n --no-open Do not automatically open the browser on startup\n --help, -h Show this help message\n`);\n process.exit(0);\n }\n }\n\n // Try to find web-standalone build\n if (!options.publicDir) {\n const candidates = [\n path.join(__dirname, '../../web-standalone/dist'),\n path.join(__dirname, '../public'),\n path.join(process.cwd(), 'public'),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(path.join(candidate, 'index.html'))) {\n options.publicDir = candidate;\n break;\n }\n }\n }\n\n const server = new StandaloneServer();\n await server.start(options);\n\n // Keep process alive\n await new Promise<void>(() => {});\n}\n\nmain().catch((e) => {\n console.error('Fatal error:', e);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/session-host.ts"],"sourcesContent":["/**\n * daemon-standalone — Embedded HTTP/WS server for local dashboard\n *\n * Standalone-only server:\n * 1. DaemonCore init (IDE detection, CDP connection, Provider loading)\n * 2. HTTP REST API — /api/v1/status, /api/v1/command\n * 3. WebSocket — ws://localhost:3847/ws (real-time status broadcast + command execution)\n * 4. Static file serving — web-standalone build output\n *\n * Usage:\n * npx @adhdev/daemon-standalone\n * npx @adhdev/daemon-standalone --port 4000\n */\n\nimport { createServer, type IncomingMessage } from 'http';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\n\nimport {\n LOG,\n initDaemonComponents,\n startDaemonDevSupport,\n shutdownDaemonComponents,\n loadConfig,\n buildStatusSnapshot,\n forwardAgentStreamsToIdeInstance,\n SessionHostPtyTransportFactory,\n type DaemonComponents,\n type HostedCliRuntimeDescriptor,\n type StatusResponse,\n type AgentEntry,\n} from '@adhdev/daemon-core';\nimport {\n ensureSessionHostReady,\n listHostedCliRuntimes,\n proxySessionHostAttach,\n proxySessionHostList,\n} from './session-host.js';\nimport { SessionHostClient, type SessionHostEndpoint, type SessionHostEvent } from '@adhdev/session-host-core';\nimport {\n AdhMuxControlClient,\n getWorkspaceSocketInfo,\n getWorkspaceState,\n requestWorkspaceControl,\n type AdhMuxControlEvent,\n} from '@adhdev/terminal-mux-control/api';\n\n// ─── Constants ───\nconst DEFAULT_PORT = 3847;\nconst STATUS_INTERVAL = 2000;\n\nlet pkgVersion = process.env.ADHDEV_PKG_VERSION || 'unknown';\nif (pkgVersion === 'unknown') {\n try {\n const possiblePaths = [\n path.join(__dirname, '..', 'package.json'),\n path.join(__dirname, 'package.json'),\n ];\n for (const candidate of possiblePaths) {\n try {\n const data = JSON.parse(fs.readFileSync(candidate, 'utf-8'));\n if (data.version) {\n pkgVersion = data.version;\n break;\n }\n } catch { /* noop */ }\n }\n } catch { /* noop */ }\n}\n\n// ─── Types ───\ninterface StandaloneOptions {\n port?: number;\n host?: string;\n publicDir?: string;\n open?: boolean;\n token?: string;\n dev?: boolean;\n}\n\ninterface WsMessage {\n type: string;\n requestId?: string;\n data?: Record<string, any>;\n}\n\n\n// ─── Standalone Server ───\n\nclass StandaloneServer {\n private httpServer: ReturnType<typeof createServer> | null = null;\n private wss: WebSocketServer | null = null;\n private clients = new Set<WebSocket>();\n private authToken: string | null = null;\n private statusTimer: NodeJS.Timeout | null = null;\n private running = false;\n private components: DaemonComponents | null = null;\n private devServer: Awaited<ReturnType<typeof startDaemonDevSupport>> | null = null;\n private sessionHostEndpoint: SessionHostEndpoint | null = null;\n\n async start(options: StandaloneOptions = {}): Promise<void> {\n const port = options.port || DEFAULT_PORT;\n const host = options.host || '127.0.0.1';\n const sessionHostEndpoint = await ensureSessionHostReady();\n this.sessionHostEndpoint = sessionHostEndpoint;\n\n // Auth token setup (opt-in only)\n this.authToken = options.token || process.env.ADHDEV_TOKEN || null;\n\n // Initialize all core components via daemon-core bootstrapper\n this.components = await initDaemonComponents({\n cliManagerDeps: {\n getServerConn: () => null,\n getP2p: () => ({\n broadcastPtyOutput: (key: string, data: string) => {\n if (this.clients.size === 0) return;\n const msg = JSON.stringify({ type: 'pty_output', cliId: key, data });\n for (const client of this.clients) {\n if (client.readyState === 1) { // OPEN\n client.send(msg);\n }\n }\n }\n }),\n onStatusChange: () => this.broadcastStatus(),\n removeAgentTracking: () => {},\n createPtyTransportFactory: ({ runtimeId, providerType, workspace, cliArgs, attachExisting }) => (\n new SessionHostPtyTransportFactory({\n endpoint: sessionHostEndpoint,\n clientId: `daemon-${process.pid}`,\n runtimeId,\n providerType,\n workspace,\n attachExisting,\n meta: {\n cliArgs: cliArgs || [],\n managedBy: 'adhdev-standalone',\n },\n })\n ),\n listHostedCliRuntimes: async (): Promise<HostedCliRuntimeDescriptor[]> => (\n listHostedCliRuntimes(sessionHostEndpoint)\n ),\n },\n onStatusChange: () => this.broadcastStatus(),\n onStreamsUpdated: (ideType: string, streams: any[]) => {\n if (!this.components) return;\n forwardAgentStreamsToIdeInstance(this.components.instanceManager, ideType, streams);\n this.broadcastStatus();\n },\n tickIntervalMs: 3000,\n cdpScanIntervalMs: 15_000,\n });\n\n await this.components.cliManager.restoreHostedSessions();\n\n // DevServer (optional)\n if (options.dev) {\n this.devServer = await startDaemonDevSupport({\n components: this.components,\n logFn: (msg: string) => console.log(msg),\n });\n }\n\n // 5. HTTP Server\n this.httpServer = createServer((req, res) => {\n this.handleHttp(req, res, options.publicDir);\n });\n\n // 6. WebSocket Server (upgrade)\n this.wss = new WebSocketServer({ noServer: true });\n this.httpServer.on('upgrade', (req, socket, head) => {\n const wsUrl = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);\n if (wsUrl.pathname === '/ws') {\n // Token auth for WS\n if (this.authToken) {\n const urlToken = wsUrl.searchParams.get('token');\n if (urlToken !== this.authToken) {\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n }\n this.wss!.handleUpgrade(req, socket, head, (ws) => {\n this.handleWsConnection(ws);\n });\n } else {\n socket.destroy();\n }\n });\n\n // 7. Status broadcast timer\n this.statusTimer = setInterval(() => {\n this.broadcastStatus();\n }, STATUS_INTERVAL);\n\n // 8. Start listening\n this.running = true;\n await new Promise<void>((resolve) => {\n this.httpServer!.listen(port, host, () => {\n resolve();\n });\n });\n\n console.log('');\n console.log('🚀 ADHDev Standalone Server');\n console.log(` http://${host === '0.0.0.0' ? 'localhost' : host}:${port}`);\n console.log(` ws://${host === '0.0.0.0' ? 'localhost' : host}:${port}/ws`);\n if (host === '0.0.0.0') {\n const lanIps = this.getLanIPs();\n for (const ip of lanIps) {\n console.log(` http://${ip}:${port} (LAN)`);\n }\n }\n if (this.authToken) {\n console.log(` 🔑 Token: ${this.authToken}`);\n }\n console.log('');\n\n const cdpCount = [...this.components.cdpManagers.values()].filter(m => m.isConnected).length;\n console.log(` CDP: ${cdpCount > 0 ? `✅ ${cdpCount} connected` : '❌ none'}`);\n console.log(` Providers: ${this.components.providerLoader.getAll().length} loaded`);\n if (options.dev) {\n console.log(` 🛠️ DevConsole: http://127.0.0.1:19280`);\n }\n console.log('');\n console.log(' Press Ctrl+C to stop.');\n console.log('');\n\n // Open browser\n if (options.open !== false) {\n try {\n const open = (await import('open')).default;\n await open(`http://localhost:${port}`);\n } catch { /* noop */ }\n }\n\n // Signal handling\n process.on('SIGINT', () => this.stop());\n process.on('SIGTERM', () => this.stop());\n }\n\n // ─── HTTP Handler ───\n\n private handleHttp(\n req: IncomingMessage,\n res: import('http').ServerResponse,\n publicDir?: string\n ): void {\n const url = req.url || '/';\n const method = req.method || 'GET';\n let sharedSnapshotCache: ReturnType<StandaloneServer['buildSharedSnapshot']> | null = null;\n const getSharedSnapshot = () => {\n if (!sharedSnapshotCache) sharedSnapshotCache = this.buildSharedSnapshot();\n return sharedSnapshotCache;\n };\n\n // CORS\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n if (method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n // Token auth for API routes\n if (this.authToken && url.startsWith('/api/')) {\n const authHeader = req.headers['authorization'];\n const bearerToken = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null;\n const queryToken = new URL(url, `http://${req.headers.host || 'localhost'}`).searchParams.get('token');\n if (bearerToken !== this.authToken && queryToken !== this.authToken) {\n res.writeHead(401, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Unauthorized. Provide token via Authorization header or ?token= query.' }));\n return;\n }\n }\n\n // ─── API Routes (v1) ───\n const apiPath = url.startsWith('/api/v1/') ? url.slice(7) : null; // /api/v1/status → /status\n const parsedUrl = new URL(url, `http://${req.headers.host || 'localhost'}`);\n\n if (apiPath === '/status' && method === 'GET') {\n const status = this.getStatus(getSharedSnapshot());\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(status));\n return;\n }\n\n if (apiPath?.startsWith('/mux/')) {\n const muxParts = parsedUrl.pathname.replace(/^\\/api\\/v1\\/mux\\//, '').split('/').filter(Boolean);\n const [workspaceSegment, action] = muxParts;\n const workspaceName = workspaceSegment ? decodeURIComponent(workspaceSegment) : '';\n\n if (!workspaceName || !action) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Invalid mux route' }));\n return;\n }\n\n if (action === 'state' && method === 'GET') {\n void (async () => {\n const result = await getWorkspaceState(workspaceName);\n if (!result?.success || !result.result) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: result?.error || 'Workspace not available' }));\n return;\n }\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(result.result));\n })().catch((error: any) => {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: error?.message || String(error) }));\n });\n return;\n }\n\n if (action === 'socket-info' && method === 'GET') {\n void (async () => {\n const result = await getWorkspaceSocketInfo(workspaceName);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(result));\n })().catch((error: any) => {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: error?.message || String(error) }));\n });\n return;\n }\n\n if (action === 'control' && method === 'POST') {\n let body = '';\n req.on('data', (chunk) => { body += chunk; });\n req.on('end', async () => {\n try {\n const { type, payload } = JSON.parse(body || '{}');\n const result = await requestWorkspaceControl(workspaceName, { type, payload });\n if (!result?.success) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: result?.error || 'Workspace control unavailable' }));\n return;\n }\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(result.result ?? { success: true }));\n } catch (error: any) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: error?.message || String(error) }));\n }\n });\n return;\n }\n\n if (action === 'events' && method === 'GET') {\n void this.handleMuxEvents(req, res, workspaceName);\n return;\n }\n }\n\n if (apiPath?.startsWith('/runtime/')) {\n const runtimeParts = parsedUrl.pathname.replace(/^\\/api\\/v1\\/runtime\\//, '').split('/').filter(Boolean);\n const [sessionSegment, action] = runtimeParts;\n const sessionId = sessionSegment ? decodeURIComponent(sessionSegment) : '';\n\n if (!sessionId || !action) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Invalid runtime route' }));\n return;\n }\n\n if (action === 'snapshot' && method === 'GET') {\n void (async () => {\n const client = new SessionHostClient({ endpoint: this.sessionHostEndpoint || undefined });\n try {\n const snapshot = await client.request<{ seq: number; text: string; truncated: boolean }>({\n type: 'get_snapshot',\n payload: { sessionId },\n });\n if (!snapshot.success || !snapshot.result) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: snapshot.error || 'Runtime snapshot unavailable' }));\n return;\n }\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ sessionId, ...snapshot.result }));\n } finally {\n await client.close().catch(() => {});\n }\n })().catch((error: any) => {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: error?.message || String(error) }));\n });\n return;\n }\n\n if (action === 'events' && method === 'GET') {\n void this.handleRuntimeEvents(req, res, sessionId);\n return;\n }\n\n }\n\n if (apiPath === '/command' && method === 'POST') {\n let body = '';\n req.on('data', (chunk) => { body += chunk; });\n req.on('end', async () => {\n try {\n const { type, payload } = JSON.parse(body);\n const result = await this.executeCommand(type, payload || {});\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(result));\n } catch (e: any) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ success: false, error: e.message }));\n }\n });\n return;\n }\n\n // ─── Static Files ───\n if (publicDir) {\n const filePath = url === '/' ? '/index.html' : url;\n const fullPath = path.join(publicDir, filePath);\n if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {\n const ext = path.extname(fullPath);\n const mimeTypes: Record<string, string> = {\n '.html': 'text/html',\n '.js': 'application/javascript',\n '.css': 'text/css',\n '.json': 'application/json',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n };\n res.writeHead(200, { 'Content-Type': mimeTypes[ext] || 'application/octet-stream' });\n fs.createReadStream(fullPath).pipe(res);\n return;\n }\n // SPA fallback → index.html\n const indexPath = path.join(publicDir, 'index.html');\n if (fs.existsSync(indexPath) && !url.startsWith('/api/')) {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n fs.createReadStream(indexPath).pipe(res);\n return;\n }\n }\n\n // 404\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n }\n\n private async handleMuxEvents(\n req: IncomingMessage,\n res: import('http').ServerResponse,\n workspaceName: string,\n ): Promise<void> {\n const socketInfo = await getWorkspaceSocketInfo(workspaceName);\n if (!socketInfo.live) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Workspace control socket unavailable' }));\n return;\n }\n\n const client = new AdhMuxControlClient(workspaceName);\n await client.connect();\n\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache, no-transform',\n Connection: 'keep-alive',\n 'X-Accel-Buffering': 'no',\n });\n\n const writeEvent = (event: AdhMuxControlEvent) => {\n res.write(`event: ${event.type}\\n`);\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n };\n\n const initial = await client.request<{ workspaceName: string; workspace: unknown; panes: unknown[] }>({\n type: 'workspace_state',\n });\n if (initial.success && initial.result) {\n writeEvent({\n type: 'workspace_update',\n payload: initial.result as Record<string, unknown>,\n });\n }\n\n const unsubscribe = client.onEvent(writeEvent);\n const heartbeat = setInterval(() => {\n res.write(': ping\\n\\n');\n }, 15000);\n\n const cleanup = () => {\n clearInterval(heartbeat);\n unsubscribe();\n void client.close().catch(() => {});\n };\n\n req.on('close', cleanup);\n req.on('aborted', cleanup);\n }\n\n private async handleRuntimeEvents(\n req: IncomingMessage,\n res: import('http').ServerResponse,\n sessionId: string,\n ): Promise<void> {\n const client = new SessionHostClient({ endpoint: this.sessionHostEndpoint || undefined });\n await client.connect();\n\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache, no-transform',\n Connection: 'keep-alive',\n 'X-Accel-Buffering': 'no',\n });\n\n const snapshot = await client.request<{ seq: number; text: string; truncated: boolean }>({\n type: 'get_snapshot',\n payload: { sessionId },\n });\n if (snapshot.success && snapshot.result) {\n res.write('event: runtime_snapshot\\n');\n res.write(`data: ${JSON.stringify({ sessionId, ...snapshot.result })}\\n\\n`);\n }\n\n const writeEvent = (event: SessionHostEvent) => {\n if (event.sessionId !== sessionId) return;\n res.write(`event: ${event.type}\\n`);\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n };\n\n const unsubscribe = client.onEvent(writeEvent);\n const heartbeat = setInterval(() => {\n res.write(': ping\\n\\n');\n }, 15000);\n\n const cleanup = () => {\n clearInterval(heartbeat);\n unsubscribe();\n void client.close().catch(() => {});\n };\n\n req.on('close', cleanup);\n req.on('aborted', cleanup);\n }\n\n // ─── WebSocket Handler ───\n\n private handleWsConnection(ws: WebSocket): void {\n // Max client limit to prevent connection storms\n const MAX_WS_CLIENTS = 10;\n if (this.clients.size >= MAX_WS_CLIENTS) {\n // Close oldest connection\n const oldest = this.clients.values().next().value;\n if (oldest) {\n try { (oldest as WebSocket).close(1000, 'Too many connections'); } catch {}\n this.clients.delete(oldest);\n }\n }\n this.clients.add(ws);\n console.log(`[WS] Client connected (total: ${this.clients.size})`);\n\n // Send initial status immediately\n const status = this.getStatus();\n ws.send(JSON.stringify({ type: 'status', data: status }));\n\n ws.on('message', async (raw) => {\n try {\n const msg: WsMessage = JSON.parse(raw.toString());\n if (msg.type === 'command' && msg.data) {\n const { type, payload } = msg.data;\n const requestId = msg.requestId;\n const result = await this.executeCommand(type, payload || {});\n ws.send(JSON.stringify({ type: 'command_result', requestId, data: result }));\n }\n } catch (e: any) {\n const requestId = (() => { try { return JSON.parse(raw.toString()).requestId; } catch { return undefined; } })();\n ws.send(JSON.stringify({ type: 'error', requestId, data: { message: e.message } }));\n }\n });\n\n ws.on('close', () => {\n this.clients.delete(ws);\n console.log(`[WS] Client disconnected (total: ${this.clients.size})`);\n });\n\n ws.on('error', () => {\n this.clients.delete(ws);\n });\n }\n\n // ─── Core Logic ───\n\n private buildSharedSnapshot() {\n const cfgSnap = loadConfig();\n const machineId = cfgSnap.machineId || 'mach_unknown';\n const allStates = this.components!.instanceManager.collectAllStates();\n\n return buildStatusSnapshot({\n allStates,\n cdpManagers: this.components!.cdpManagers as Map<string, unknown>,\n providerLoader: this.components!.providerLoader,\n detectedIdes: this.components!.detectedIdes.value,\n instanceId: `standalone_${machineId}`,\n version: pkgVersion,\n daemonMode: false,\n });\n }\n\n private getStatus(snapshot: ReturnType<StandaloneServer['buildSharedSnapshot']> = this.buildSharedSnapshot()): StatusResponse {\n const cfgSnap = loadConfig();\n\n return {\n ...snapshot,\n id: snapshot.instanceId,\n daemonMode: false,\n type: 'standalone',\n platform: snapshot.machine.platform,\n hostname: snapshot.machine.hostname,\n userName: cfgSnap.userName || undefined,\n system: {\n cpus: snapshot.machine.cpus,\n totalMem: snapshot.machine.totalMem,\n freeMem: snapshot.machine.freeMem,\n availableMem: snapshot.machine.availableMem,\n loadavg: snapshot.machine.loadavg,\n uptime: snapshot.machine.uptime,\n arch: snapshot.machine.arch,\n },\n };\n }\n\n private async executeCommand(type: string, args: any): Promise<any> {\n if (!this.components) {\n return { success: false, error: 'Components not initialized' };\n }\n const result = await this.components.router.execute(type, args, 'standalone');\n if (type.startsWith('workspace_')) this.broadcastStatus();\n return result;\n }\n\n private broadcastStatus(): void {\n if (this.clients.size === 0) return;\n const status = this.getStatus();\n const msg = JSON.stringify({ type: 'status', data: status });\n const cdpCount = [...this.components!.cdpManagers.values()].filter(m => m.isConnected).length;\n LOG.debug('Broadcast', `status → ${this.clients.size} client(s), ${(status as any).sessions?.length || 0} session(s), ${cdpCount} CDP`);\n for (const client of this.clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(msg);\n }\n }\n }\n\n // ─── Network ───\n\n private getLanIPs(): string[] {\n const interfaces = os.networkInterfaces();\n const ips: string[] = [];\n for (const iface of Object.values(interfaces)) {\n if (!iface) continue;\n for (const info of iface) {\n if (info.family === 'IPv4' && !info.internal) {\n ips.push(info.address);\n }\n }\n }\n return ips;\n }\n\n // ─── Lifecycle ───\n\n async stop(): Promise<void> {\n if (!this.running) return;\n this.running = false;\n\n console.log('\\n Shutting down...');\n\n if (this.statusTimer) {\n clearInterval(this.statusTimer);\n this.statusTimer = null;\n }\n\n // Close WS clients\n for (const ws of this.clients) {\n try { ws.close(); } catch { /* noop */ }\n }\n this.clients.clear();\n\n // Close WSS\n if (this.wss) {\n this.wss.close();\n this.wss = null;\n }\n\n // Shutdown core components\n if (this.components) {\n await shutdownDaemonComponents(this.components);\n }\n\n // HTTP server\n if (this.httpServer) {\n this.httpServer.close();\n this.httpServer = null;\n }\n\n console.log(' ✓ ADHDev Standalone stopped.\\n');\n process.exit(0);\n }\n}\n\n// ─── CLI ───\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const primaryCommand = args[0] || '';\n if (primaryCommand === 'attach') {\n const target = args[1];\n if (!target) {\n console.error('Usage: adhdev attach <sessionId> [--read-only|--takeover]');\n process.exit(1);\n }\n const readOnly = args.includes('--read-only');\n const takeover = args.includes('--takeover');\n const exitCode = await proxySessionHostAttach(target, { readOnly, takeover });\n process.exit(exitCode);\n }\n if (primaryCommand === 'list' || primaryCommand === 'runtimes') {\n const showAll = args.includes('--all');\n const exitCode = await proxySessionHostList(showAll);\n process.exit(exitCode);\n }\n const options: StandaloneOptions = {};\n\n // Parse simple args\n for (let i = 0; i < args.length; i++) {\n if ((args[i] === '--port' || args[i] === '-p') && args[i + 1]) {\n options.port = parseInt(args[i + 1]);\n i++;\n }\n if (args[i] === '--host' || args[i] === '-H') {\n options.host = '0.0.0.0';\n }\n if (args[i] === '--public' && args[i + 1]) {\n options.publicDir = args[i + 1];\n i++;\n }\n if (args[i] === '--no-open') {\n options.open = false;\n }\n if (args[i] === '--dev') {\n (options as any).dev = true;\n }\n if (args[i] === '--token' && args[i + 1]) {\n options.token = args[i + 1];\n i++;\n }\n if (args[i] === '--help' || args[i] === '-h') {\n console.log(`\nUsage: adhdev-standalone [options]\n adhdev-standalone list [--all]\n adhdev-standalone attach <sessionId> [--read-only|--takeover]\n\nOptions:\n --port, -p <port> Port to run the standalone server on (default: 3847)\n --host, -H Allow external network connections (binds to 0.0.0.0)\n --token <token> Set an authentication token for the dashboard UI\n --dev Enable DevConsole to debug and test providers\n --public <path> Custom path to the web dashboard distribution\n --no-open Do not automatically open the browser on startup\n --help, -h Show this help message\n\nRuntime commands:\n list, runtimes Show hosted CLI runtimes\n attach Attach local terminal to a runtime\n open Open a local terminal window running adhmux for a runtime\n`);\n process.exit(0);\n }\n }\n\n // Try to find web-standalone build\n if (!options.publicDir) {\n const candidates = [\n path.join(__dirname, '../../web-standalone/dist'),\n path.join(__dirname, '../public'),\n path.join(process.cwd(), 'public'),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(path.join(candidate, 'index.html'))) {\n options.publicDir = candidate;\n break;\n }\n }\n }\n\n const server = new StandaloneServer();\n await server.start(options);\n\n // Keep process alive\n await new Promise<void>(() => {});\n}\n\nmain().catch((e) => {\n console.error('Fatal error:', e);\n process.exit(1);\n});\n","import { spawn } from 'child_process';\nimport {\n SessionHostClient,\n getDefaultSessionHostEndpoint,\n type SessionHostEndpoint,\n type SessionHostRecord,\n} from '@adhdev/session-host-core';\nimport type { HostedCliRuntimeDescriptor } from '@adhdev/daemon-core';\n\nconst STARTUP_TIMEOUT_MS = 8000;\nconst STARTUP_POLL_MS = 200;\nconst SESSION_HOST_APP_NAME = process.env.ADHDEV_SESSION_HOST_NAME || 'adhdev';\n\nasync function canConnect(endpoint: SessionHostEndpoint): Promise<boolean> {\n const client = new SessionHostClient({ endpoint });\n try {\n await client.connect();\n await client.close();\n return true;\n } catch {\n return false;\n }\n}\n\nasync function waitForReady(endpoint: SessionHostEndpoint, timeoutMs = STARTUP_TIMEOUT_MS): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (await canConnect(endpoint)) return;\n await new Promise((resolve) => setTimeout(resolve, STARTUP_POLL_MS));\n }\n throw new Error(`Session host did not become ready within ${timeoutMs}ms`);\n}\n\nfunction resolveSessionHostEntry(): string {\n return require.resolve('@adhdev/session-host-daemon');\n}\n\nasync function runSessionHostCli(args: string[]): Promise<number> {\n const entry = resolveSessionHostEntry();\n const child = spawn(process.execPath, [entry, ...args], {\n stdio: 'inherit',\n env: {\n ...process.env,\n ADHDEV_SESSION_HOST_NAME: SESSION_HOST_APP_NAME,\n },\n });\n return await new Promise<number>((resolve, reject) => {\n child.on('error', reject);\n child.on('exit', (code) => resolve(code ?? 0));\n });\n}\n\nexport async function ensureSessionHostReady(): Promise<SessionHostEndpoint> {\n const endpoint = getDefaultSessionHostEndpoint(SESSION_HOST_APP_NAME);\n if (await canConnect(endpoint)) return endpoint;\n\n const entry = resolveSessionHostEntry();\n const child = spawn(process.execPath, [entry], {\n detached: true,\n stdio: 'ignore',\n windowsHide: true,\n });\n child.unref();\n\n await waitForReady(endpoint);\n return endpoint;\n}\n\nexport async function listHostedCliRuntimes(endpoint: SessionHostEndpoint): Promise<HostedCliRuntimeDescriptor[]> {\n const client = new SessionHostClient({ endpoint });\n try {\n const response = await client.request<SessionHostRecord[]>({\n type: 'list_sessions',\n payload: {},\n });\n if (!response.success || !response.result) {\n return [];\n }\n return response.result\n .filter((record) => record.category === 'cli' && ['running', 'interrupted'].includes(record.lifecycle))\n .sort((a, b) => b.lastActivityAt - a.lastActivityAt)\n .map((record) => ({\n runtimeId: record.sessionId,\n runtimeKey: record.runtimeKey,\n displayName: record.displayName,\n workspaceLabel: record.workspaceLabel,\n lifecycle: record.lifecycle,\n recoveryState: typeof record.meta?.runtimeRecoveryState === 'string' ? String(record.meta.runtimeRecoveryState) : null,\n cliType: record.providerType,\n workspace: record.workspace,\n cliArgs: Array.isArray(record.meta?.cliArgs) ? (record.meta.cliArgs as string[]) : [],\n }));\n } finally {\n await client.close().catch(() => {});\n }\n}\n\nexport async function proxySessionHostList(showAll = false): Promise<number> {\n await ensureSessionHostReady();\n return runSessionHostCli(['list', ...(showAll ? ['--all'] : [])]);\n}\n\nexport async function proxySessionHostAttach(\n target: string,\n options: { readOnly?: boolean; takeover?: boolean } = {},\n): Promise<number> {\n await ensureSessionHostReady();\n const args = ['attach', target];\n if (options.readOnly) args.push('--read-only');\n if (options.takeover) args.push('--takeover');\n return runSessionHostCli(args);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,kBAAmD;AACnD,gBAA2C;AAC3C,WAAsB;AACtB,SAAoB;AACpB,SAAoB;AAEpB,yBAaO;;;ACjCP,2BAAsB;AACtB,+BAKO;AAGP,IAAM,qBAAqB;AAC3B,IAAM,kBAAkB;AACxB,IAAM,wBAAwB,QAAQ,IAAI,4BAA4B;AAEtE,eAAe,WAAW,UAAiD;AACzE,QAAM,SAAS,IAAI,2CAAkB,EAAE,SAAS,CAAC;AACjD,MAAI;AACF,UAAM,OAAO,QAAQ;AACrB,UAAM,OAAO,MAAM;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,aAAa,UAA+B,YAAY,oBAAmC;AACxG,QAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,SAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,QAAI,MAAM,WAAW,QAAQ,EAAG;AAChC,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,eAAe,CAAC;AAAA,EACrE;AACA,QAAM,IAAI,MAAM,4CAA4C,SAAS,IAAI;AAC3E;AAEA,SAAS,0BAAkC;AACzC,SAAO,gBAAgB,6BAA6B;AACtD;AAEA,eAAe,kBAAkB,MAAiC;AAChE,QAAM,QAAQ,wBAAwB;AACtC,QAAM,YAAQ,4BAAM,QAAQ,UAAU,CAAC,OAAO,GAAG,IAAI,GAAG;AAAA,IACtD,OAAO;AAAA,IACP,KAAK;AAAA,MACH,GAAG,QAAQ;AAAA,MACX,0BAA0B;AAAA,IAC5B;AAAA,EACF,CAAC;AACD,SAAO,MAAM,IAAI,QAAgB,CAAC,SAAS,WAAW;AACpD,UAAM,GAAG,SAAS,MAAM;AACxB,UAAM,GAAG,QAAQ,CAAC,SAAS,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAC/C,CAAC;AACH;AAEA,eAAsB,yBAAuD;AAC3E,QAAM,eAAW,wDAA8B,qBAAqB;AACpE,MAAI,MAAM,WAAW,QAAQ,EAAG,QAAO;AAEvC,QAAM,QAAQ,wBAAwB;AACtC,QAAM,YAAQ,4BAAM,QAAQ,UAAU,CAAC,KAAK,GAAG;AAAA,IAC7C,UAAU;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,EACf,CAAC;AACD,QAAM,MAAM;AAEZ,QAAM,aAAa,QAAQ;AAC3B,SAAO;AACT;AAEA,eAAsB,sBAAsB,UAAsE;AAChH,QAAM,SAAS,IAAI,2CAAkB,EAAE,SAAS,CAAC;AACjD,MAAI;AACF,UAAM,WAAW,MAAM,OAAO,QAA6B;AAAA,MACzD,MAAM;AAAA,MACN,SAAS,CAAC;AAAA,IACZ,CAAC;AACD,QAAI,CAAC,SAAS,WAAW,CAAC,SAAS,QAAQ;AACzC,aAAO,CAAC;AAAA,IACV;AACA,WAAO,SAAS,OACb,OAAO,CAAC,WAAW,OAAO,aAAa,SAAS,CAAC,WAAW,aAAa,EAAE,SAAS,OAAO,SAAS,CAAC,EACrG,KAAK,CAAC,GAAG,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAClD,IAAI,CAAC,YAAY;AAAA,MAChB,WAAW,OAAO;AAAA,MAClB,YAAY,OAAO;AAAA,MACnB,aAAa,OAAO;AAAA,MACpB,gBAAgB,OAAO;AAAA,MACvB,WAAW,OAAO;AAAA,MAClB,eAAe,OAAO,OAAO,MAAM,yBAAyB,WAAW,OAAO,OAAO,KAAK,oBAAoB,IAAI;AAAA,MAClH,SAAS,OAAO;AAAA,MAChB,WAAW,OAAO;AAAA,MAClB,SAAS,MAAM,QAAQ,OAAO,MAAM,OAAO,IAAK,OAAO,KAAK,UAAuB,CAAC;AAAA,IACtF,EAAE;AAAA,EACN,UAAE;AACA,UAAM,OAAO,MAAM,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACrC;AACF;AAEA,eAAsB,qBAAqB,UAAU,OAAwB;AAC3E,QAAM,uBAAuB;AAC7B,SAAO,kBAAkB,CAAC,QAAQ,GAAI,UAAU,CAAC,OAAO,IAAI,CAAC,CAAE,CAAC;AAClE;AAEA,eAAsB,uBACpB,QACA,UAAsD,CAAC,GACtC;AACjB,QAAM,uBAAuB;AAC7B,QAAM,OAAO,CAAC,UAAU,MAAM;AAC9B,MAAI,QAAQ,SAAU,MAAK,KAAK,aAAa;AAC7C,MAAI,QAAQ,SAAU,MAAK,KAAK,YAAY;AAC5C,SAAO,kBAAkB,IAAI;AAC/B;;;ADvEA,IAAAA,4BAAmF;AACnF,iBAMO;AAGP,IAAM,eAAe;AACrB,IAAM,kBAAkB;AAExB,IAAI,aAAa,QAAQ,IAAI,sBAAsB;AACnD,IAAI,eAAe,WAAW;AAC5B,MAAI;AACF,UAAM,gBAAgB;AAAA,MACf,UAAK,WAAW,MAAM,cAAc;AAAA,MACpC,UAAK,WAAW,cAAc;AAAA,IACrC;AACA,eAAW,aAAa,eAAe;AACrC,UAAI;AACF,cAAM,OAAO,KAAK,MAAS,gBAAa,WAAW,OAAO,CAAC;AAC3D,YAAI,KAAK,SAAS;AAChB,uBAAa,KAAK;AAClB;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAAa;AAAA,IACvB;AAAA,EACF,QAAQ;AAAA,EAAa;AACvB;AAqBA,IAAM,mBAAN,MAAuB;AAAA,EACb,aAAqD;AAAA,EACrD,MAA8B;AAAA,EAC9B,UAAU,oBAAI,IAAe;AAAA,EAC7B,YAA2B;AAAA,EAC3B,cAAqC;AAAA,EACrC,UAAU;AAAA,EACV,aAAsC;AAAA,EACtC,YAAsE;AAAA,EACtE,sBAAkD;AAAA,EAE1D,MAAM,MAAM,UAA6B,CAAC,GAAkB;AAC1D,UAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAM,sBAAsB,MAAM,uBAAuB;AACzD,SAAK,sBAAsB;AAG3B,SAAK,YAAY,QAAQ,SAAS,QAAQ,IAAI,gBAAgB;AAG9D,SAAK,aAAa,UAAM,yCAAqB;AAAA,MAC3C,gBAAgB;AAAA,QACd,eAAe,MAAM;AAAA,QACrB,QAAQ,OAAO;AAAA,UACb,oBAAoB,CAAC,KAAa,SAAiB;AACjD,gBAAI,KAAK,QAAQ,SAAS,EAAG;AAC7B,kBAAM,MAAM,KAAK,UAAU,EAAE,MAAM,cAAc,OAAO,KAAK,KAAK,CAAC;AACnE,uBAAW,UAAU,KAAK,SAAS;AACjC,kBAAI,OAAO,eAAe,GAAG;AAC3B,uBAAO,KAAK,GAAG;AAAA,cACjB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,gBAAgB,MAAM,KAAK,gBAAgB;AAAA,QAC3C,qBAAqB,MAAM;AAAA,QAAC;AAAA,QAC5B,2BAA2B,CAAC,EAAE,WAAW,cAAc,WAAW,SAAS,eAAe,MACxF,IAAI,kDAA+B;AAAA,UACjC,UAAU;AAAA,UACV,UAAU,UAAU,QAAQ,GAAG;AAAA,UAC/B;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,YACJ,SAAS,WAAW,CAAC;AAAA,YACrB,WAAW;AAAA,UACb;AAAA,QACF,CAAC;AAAA,QAEH,uBAAuB,YACrB,sBAAsB,mBAAmB;AAAA,MAE7C;AAAA,MACA,gBAAgB,MAAM,KAAK,gBAAgB;AAAA,MAC3C,kBAAkB,CAAC,SAAiB,YAAmB;AACrD,YAAI,CAAC,KAAK,WAAY;AACtB,iEAAiC,KAAK,WAAW,iBAAiB,SAAS,OAAO;AAClF,aAAK,gBAAgB;AAAA,MACvB;AAAA,MACA,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,IACrB,CAAC;AAED,UAAM,KAAK,WAAW,WAAW,sBAAsB;AAGvD,QAAI,QAAQ,KAAK;AACf,WAAK,YAAY,UAAM,0CAAsB;AAAA,QAC3C,YAAY,KAAK;AAAA,QACjB,OAAO,CAAC,QAAgB,QAAQ,IAAI,GAAG;AAAA,MACzC,CAAC;AAAA,IACH;AAGA,SAAK,iBAAa,0BAAa,CAAC,KAAK,QAAQ;AAC3C,WAAK,WAAW,KAAK,KAAK,QAAQ,SAAS;AAAA,IAC7C,CAAC;AAGD,SAAK,MAAM,IAAI,0BAAgB,EAAE,UAAU,KAAK,CAAC;AACjD,SAAK,WAAW,GAAG,WAAW,CAAC,KAAK,QAAQ,SAAS;AACnD,YAAM,QAAQ,IAAI,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI,QAAQ,QAAQ,WAAW,EAAE;AACjF,UAAI,MAAM,aAAa,OAAO;AAE5B,YAAI,KAAK,WAAW;AAClB,gBAAM,WAAW,MAAM,aAAa,IAAI,OAAO;AAC/C,cAAI,aAAa,KAAK,WAAW;AAC/B,mBAAO,MAAM,mCAAmC;AAChD,mBAAO,QAAQ;AACf;AAAA,UACF;AAAA,QACF;AACA,aAAK,IAAK,cAAc,KAAK,QAAQ,MAAM,CAAC,OAAO;AACjD,eAAK,mBAAmB,EAAE;AAAA,QAC5B,CAAC;AAAA,MACH,OAAO;AACL,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF,CAAC;AAGD,SAAK,cAAc,YAAY,MAAM;AACnC,WAAK,gBAAgB;AAAA,IACvB,GAAG,eAAe;AAGlB,SAAK,UAAU;AACf,UAAM,IAAI,QAAc,CAAC,YAAY;AACnC,WAAK,WAAY,OAAO,MAAM,MAAM,MAAM;AACxC,gBAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAED,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,oCAA6B;AACzC,YAAQ,IAAI,aAAa,SAAS,YAAY,cAAc,IAAI,IAAI,IAAI,EAAE;AAC1E,YAAQ,IAAI,WAAW,SAAS,YAAY,cAAc,IAAI,IAAI,IAAI,KAAK;AAC3E,QAAI,SAAS,WAAW;AACtB,YAAM,SAAS,KAAK,UAAU;AAC9B,iBAAW,MAAM,QAAQ;AACvB,gBAAQ,IAAI,aAAa,EAAE,IAAI,IAAI,SAAS;AAAA,MAC9C;AAAA,IACF;AACA,QAAI,KAAK,WAAW;AAClB,cAAQ,IAAI,uBAAgB,KAAK,SAAS,EAAE;AAAA,IAC9C;AACA,YAAQ,IAAI,EAAE;AAEd,UAAM,WAAW,CAAC,GAAG,KAAK,WAAW,YAAY,OAAO,CAAC,EAAE,OAAO,OAAK,EAAE,WAAW,EAAE;AACtF,YAAQ,IAAI,WAAW,WAAW,IAAI,UAAK,QAAQ,eAAe,aAAQ,EAAE;AAC5E,YAAQ,IAAI,iBAAiB,KAAK,WAAW,eAAe,OAAO,EAAE,MAAM,SAAS;AACpF,QAAI,QAAQ,KAAK;AACf,cAAQ,IAAI,wDAA4C;AAAA,IAC1D;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,0BAA0B;AACtC,YAAQ,IAAI,EAAE;AAGd,QAAI,QAAQ,SAAS,OAAO;AAC1B,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,MAAM,GAAG;AACpC,cAAM,KAAK,oBAAoB,IAAI,EAAE;AAAA,MACvC,QAAQ;AAAA,MAAa;AAAA,IACvB;AAGA,YAAQ,GAAG,UAAU,MAAM,KAAK,KAAK,CAAC;AACtC,YAAQ,GAAG,WAAW,MAAM,KAAK,KAAK,CAAC;AAAA,EACzC;AAAA;AAAA,EAIQ,WACN,KACA,KACA,WACM;AACN,UAAM,MAAM,IAAI,OAAO;AACvB,UAAM,SAAS,IAAI,UAAU;AAC7B,QAAI,sBAAkF;AACtF,UAAM,oBAAoB,MAAM;AAC9B,UAAI,CAAC,oBAAqB,uBAAsB,KAAK,oBAAoB;AACzE,aAAO;AAAA,IACT;AAGA,QAAI,UAAU,+BAA+B,GAAG;AAChD,QAAI,UAAU,gCAAgC,oBAAoB;AAClE,QAAI,UAAU,gCAAgC,6BAA6B;AAC3E,QAAI,WAAW,WAAW;AACxB,UAAI,UAAU,GAAG;AACjB,UAAI,IAAI;AACR;AAAA,IACF;AAGA,QAAI,KAAK,aAAa,IAAI,WAAW,OAAO,GAAG;AAC7C,YAAM,aAAa,IAAI,QAAQ,eAAe;AAC9C,YAAM,cAAc,YAAY,WAAW,SAAS,IAAI,WAAW,MAAM,CAAC,IAAI;AAC9E,YAAM,aAAa,IAAI,IAAI,KAAK,UAAU,IAAI,QAAQ,QAAQ,WAAW,EAAE,EAAE,aAAa,IAAI,OAAO;AACrG,UAAI,gBAAgB,KAAK,aAAa,eAAe,KAAK,WAAW;AACnE,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,EAAE,OAAO,yEAAyE,CAAC,CAAC;AAC3G;AAAA,MACF;AAAA,IACF;AAGA,UAAM,UAAU,IAAI,WAAW,UAAU,IAAI,IAAI,MAAM,CAAC,IAAI;AAC5D,UAAM,YAAY,IAAI,IAAI,KAAK,UAAU,IAAI,QAAQ,QAAQ,WAAW,EAAE;AAE1E,QAAI,YAAY,aAAa,WAAW,OAAO;AAC7C,YAAM,SAAS,KAAK,UAAU,kBAAkB,CAAC;AACjD,UAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,UAAI,IAAI,KAAK,UAAU,MAAM,CAAC;AAC9B;AAAA,IACF;AAEA,QAAI,SAAS,WAAW,OAAO,GAAG;AAChC,YAAM,WAAW,UAAU,SAAS,QAAQ,qBAAqB,EAAE,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO;AAC9F,YAAM,CAAC,kBAAkB,MAAM,IAAI;AACnC,YAAM,gBAAgB,mBAAmB,mBAAmB,gBAAgB,IAAI;AAEhF,UAAI,CAAC,iBAAiB,CAAC,QAAQ;AAC7B,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,EAAE,OAAO,oBAAoB,CAAC,CAAC;AACtD;AAAA,MACF;AAEA,UAAI,WAAW,WAAW,WAAW,OAAO;AAC1C,cAAM,YAAY;AAChB,gBAAM,SAAS,UAAM,8BAAkB,aAAa;AACpD,cAAI,CAAC,QAAQ,WAAW,CAAC,OAAO,QAAQ;AACtC,gBAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,gBAAI,IAAI,KAAK,UAAU,EAAE,OAAO,QAAQ,SAAS,0BAA0B,CAAC,CAAC;AAC7E;AAAA,UACF;AACA,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,QACvC,GAAG,EAAE,MAAM,CAAC,UAAe;AACzB,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,KAAK,EAAE,CAAC,CAAC;AAAA,QACpE,CAAC;AACD;AAAA,MACF;AAEA,UAAI,WAAW,iBAAiB,WAAW,OAAO;AAChD,cAAM,YAAY;AAChB,gBAAM,SAAS,UAAM,mCAAuB,aAAa;AACzD,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,QAChC,GAAG,EAAE,MAAM,CAAC,UAAe;AACzB,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,KAAK,EAAE,CAAC,CAAC;AAAA,QACpE,CAAC;AACD;AAAA,MACF;AAEA,UAAI,WAAW,aAAa,WAAW,QAAQ;AAC7C,YAAI,OAAO;AACX,YAAI,GAAG,QAAQ,CAAC,UAAU;AAAE,kBAAQ;AAAA,QAAO,CAAC;AAC5C,YAAI,GAAG,OAAO,YAAY;AACxB,cAAI;AACF,kBAAM,EAAE,MAAM,QAAQ,IAAI,KAAK,MAAM,QAAQ,IAAI;AACjD,kBAAM,SAAS,UAAM,oCAAwB,eAAe,EAAE,MAAM,QAAQ,CAAC;AAC7E,gBAAI,CAAC,QAAQ,SAAS;AACpB,kBAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,kBAAI,IAAI,KAAK,UAAU,EAAE,OAAO,QAAQ,SAAS,gCAAgC,CAAC,CAAC;AACnF;AAAA,YACF;AACA,gBAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,gBAAI,IAAI,KAAK,UAAU,OAAO,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,UAC5D,SAAS,OAAY;AACnB,gBAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,gBAAI,IAAI,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,KAAK,EAAE,CAAC,CAAC;AAAA,UACpE;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAEA,UAAI,WAAW,YAAY,WAAW,OAAO;AAC3C,aAAK,KAAK,gBAAgB,KAAK,KAAK,aAAa;AACjD;AAAA,MACF;AAAA,IACF;AAEA,QAAI,SAAS,WAAW,WAAW,GAAG;AACpC,YAAM,eAAe,UAAU,SAAS,QAAQ,yBAAyB,EAAE,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO;AACtG,YAAM,CAAC,gBAAgB,MAAM,IAAI;AACjC,YAAM,YAAY,iBAAiB,mBAAmB,cAAc,IAAI;AAExE,UAAI,CAAC,aAAa,CAAC,QAAQ;AACzB,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,EAAE,OAAO,wBAAwB,CAAC,CAAC;AAC1D;AAAA,MACF;AAEA,UAAI,WAAW,cAAc,WAAW,OAAO;AAC7C,cAAM,YAAY;AAChB,gBAAM,SAAS,IAAI,4CAAkB,EAAE,UAAU,KAAK,uBAAuB,OAAU,CAAC;AACxF,cAAI;AACF,kBAAM,WAAW,MAAM,OAAO,QAA2D;AAAA,cACvF,MAAM;AAAA,cACN,SAAS,EAAE,UAAU;AAAA,YACvB,CAAC;AACD,gBAAI,CAAC,SAAS,WAAW,CAAC,SAAS,QAAQ;AACzC,kBAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,kBAAI,IAAI,KAAK,UAAU,EAAE,OAAO,SAAS,SAAS,+BAA+B,CAAC,CAAC;AACnF;AAAA,YACF;AACA,gBAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,gBAAI,IAAI,KAAK,UAAU,EAAE,WAAW,GAAG,SAAS,OAAO,CAAC,CAAC;AAAA,UAC3D,UAAE;AACA,kBAAM,OAAO,MAAM,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACrC;AAAA,QACF,GAAG,EAAE,MAAM,CAAC,UAAe;AACzB,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,KAAK,EAAE,CAAC,CAAC;AAAA,QACpE,CAAC;AACD;AAAA,MACF;AAEA,UAAI,WAAW,YAAY,WAAW,OAAO;AAC3C,aAAK,KAAK,oBAAoB,KAAK,KAAK,SAAS;AACjD;AAAA,MACF;AAAA,IAEF;AAEA,QAAI,YAAY,cAAc,WAAW,QAAQ;AAC/C,UAAI,OAAO;AACX,UAAI,GAAG,QAAQ,CAAC,UAAU;AAAE,gBAAQ;AAAA,MAAO,CAAC;AAC5C,UAAI,GAAG,OAAO,YAAY;AACxB,YAAI;AACF,gBAAM,EAAE,MAAM,QAAQ,IAAI,KAAK,MAAM,IAAI;AACzC,gBAAM,SAAS,MAAM,KAAK,eAAe,MAAM,WAAW,CAAC,CAAC;AAC5D,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,QAChC,SAAS,GAAQ;AACf,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,EAAE,SAAS,OAAO,OAAO,EAAE,QAAQ,CAAC,CAAC;AAAA,QAC9D;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAGA,QAAI,WAAW;AACb,YAAM,WAAW,QAAQ,MAAM,gBAAgB;AAC/C,YAAM,WAAgB,UAAK,WAAW,QAAQ;AAC9C,UAAO,cAAW,QAAQ,KAAQ,YAAS,QAAQ,EAAE,OAAO,GAAG;AAC7D,cAAM,MAAW,aAAQ,QAAQ;AACjC,cAAM,YAAoC;AAAA,UACxC,SAAS;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ;AACA,YAAI,UAAU,KAAK,EAAE,gBAAgB,UAAU,GAAG,KAAK,2BAA2B,CAAC;AACnF,QAAG,oBAAiB,QAAQ,EAAE,KAAK,GAAG;AACtC;AAAA,MACF;AAEA,YAAM,YAAiB,UAAK,WAAW,YAAY;AACnD,UAAO,cAAW,SAAS,KAAK,CAAC,IAAI,WAAW,OAAO,GAAG;AACxD,YAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,QAAG,oBAAiB,SAAS,EAAE,KAAK,GAAG;AACvC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,QAAI,IAAI,KAAK,UAAU,EAAE,OAAO,YAAY,CAAC,CAAC;AAAA,EAChD;AAAA,EAEA,MAAc,gBACZ,KACA,KACA,eACe;AACf,UAAM,aAAa,UAAM,mCAAuB,aAAa;AAC7D,QAAI,CAAC,WAAW,MAAM;AACpB,UAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,UAAI,IAAI,KAAK,UAAU,EAAE,OAAO,uCAAuC,CAAC,CAAC;AACzE;AAAA,IACF;AAEA,UAAM,SAAS,IAAI,+BAAoB,aAAa;AACpD,UAAM,OAAO,QAAQ;AAErB,QAAI,UAAU,KAAK;AAAA,MACjB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,qBAAqB;AAAA,IACvB,CAAC;AAED,UAAM,aAAa,CAAC,UAA8B;AAChD,UAAI,MAAM,UAAU,MAAM,IAAI;AAAA,CAAI;AAClC,UAAI,MAAM,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA;AAAA,CAAM;AAAA,IAChD;AAEA,UAAM,UAAU,MAAM,OAAO,QAAyE;AAAA,MACpG,MAAM;AAAA,IACR,CAAC;AACD,QAAI,QAAQ,WAAW,QAAQ,QAAQ;AACrC,iBAAW;AAAA,QACT,MAAM;AAAA,QACN,SAAS,QAAQ;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,UAAM,cAAc,OAAO,QAAQ,UAAU;AAC7C,UAAM,YAAY,YAAY,MAAM;AAClC,UAAI,MAAM,YAAY;AAAA,IACxB,GAAG,IAAK;AAER,UAAM,UAAU,MAAM;AACpB,oBAAc,SAAS;AACvB,kBAAY;AACZ,WAAK,OAAO,MAAM,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACpC;AAEA,QAAI,GAAG,SAAS,OAAO;AACvB,QAAI,GAAG,WAAW,OAAO;AAAA,EAC3B;AAAA,EAEA,MAAc,oBACZ,KACA,KACA,WACe;AACf,UAAM,SAAS,IAAI,4CAAkB,EAAE,UAAU,KAAK,uBAAuB,OAAU,CAAC;AACxF,UAAM,OAAO,QAAQ;AAErB,QAAI,UAAU,KAAK;AAAA,MACjB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,qBAAqB;AAAA,IACvB,CAAC;AAED,UAAM,WAAW,MAAM,OAAO,QAA2D;AAAA,MACvF,MAAM;AAAA,MACN,SAAS,EAAE,UAAU;AAAA,IACvB,CAAC;AACD,QAAI,SAAS,WAAW,SAAS,QAAQ;AACvC,UAAI,MAAM,2BAA2B;AACrC,UAAI,MAAM,SAAS,KAAK,UAAU,EAAE,WAAW,GAAG,SAAS,OAAO,CAAC,CAAC;AAAA;AAAA,CAAM;AAAA,IAC5E;AAEA,UAAM,aAAa,CAAC,UAA4B;AAC9C,UAAI,MAAM,cAAc,UAAW;AACnC,UAAI,MAAM,UAAU,MAAM,IAAI;AAAA,CAAI;AAClC,UAAI,MAAM,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA;AAAA,CAAM;AAAA,IAChD;AAEA,UAAM,cAAc,OAAO,QAAQ,UAAU;AAC7C,UAAM,YAAY,YAAY,MAAM;AAClC,UAAI,MAAM,YAAY;AAAA,IACxB,GAAG,IAAK;AAER,UAAM,UAAU,MAAM;AACpB,oBAAc,SAAS;AACvB,kBAAY;AACZ,WAAK,OAAO,MAAM,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACpC;AAEA,QAAI,GAAG,SAAS,OAAO;AACvB,QAAI,GAAG,WAAW,OAAO;AAAA,EAC3B;AAAA;AAAA,EAIQ,mBAAmB,IAAqB;AAE9C,UAAM,iBAAiB;AACvB,QAAI,KAAK,QAAQ,QAAQ,gBAAgB;AAEvC,YAAM,SAAS,KAAK,QAAQ,OAAO,EAAE,KAAK,EAAE;AAC5C,UAAI,QAAQ;AACV,YAAI;AAAE,UAAC,OAAqB,MAAM,KAAM,sBAAsB;AAAA,QAAG,QAAQ;AAAA,QAAC;AAC1E,aAAK,QAAQ,OAAO,MAAM;AAAA,MAC5B;AAAA,IACF;AACA,SAAK,QAAQ,IAAI,EAAE;AACnB,YAAQ,IAAI,iCAAiC,KAAK,QAAQ,IAAI,GAAG;AAGjE,UAAM,SAAS,KAAK,UAAU;AAC9B,OAAG,KAAK,KAAK,UAAU,EAAE,MAAM,UAAU,MAAM,OAAO,CAAC,CAAC;AAExD,OAAG,GAAG,WAAW,OAAO,QAAQ;AAC9B,UAAI;AACF,cAAM,MAAiB,KAAK,MAAM,IAAI,SAAS,CAAC;AAChD,YAAI,IAAI,SAAS,aAAa,IAAI,MAAM;AACtC,gBAAM,EAAE,MAAM,QAAQ,IAAI,IAAI;AAC9B,gBAAM,YAAY,IAAI;AACtB,gBAAM,SAAS,MAAM,KAAK,eAAe,MAAM,WAAW,CAAC,CAAC;AAC5D,aAAG,KAAK,KAAK,UAAU,EAAE,MAAM,kBAAkB,WAAW,MAAM,OAAO,CAAC,CAAC;AAAA,QAC7E;AAAA,MACF,SAAS,GAAQ;AACf,cAAM,aAAa,MAAM;AAAE,cAAI;AAAE,mBAAO,KAAK,MAAM,IAAI,SAAS,CAAC,EAAE;AAAA,UAAW,QAAQ;AAAE,mBAAO;AAAA,UAAW;AAAA,QAAE,GAAG;AAC/G,WAAG,KAAK,KAAK,UAAU,EAAE,MAAM,SAAS,WAAW,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;AAAA,MACpF;AAAA,IACF,CAAC;AAED,OAAG,GAAG,SAAS,MAAM;AACnB,WAAK,QAAQ,OAAO,EAAE;AACtB,cAAQ,IAAI,oCAAoC,KAAK,QAAQ,IAAI,GAAG;AAAA,IACtE,CAAC;AAED,OAAG,GAAG,SAAS,MAAM;AACnB,WAAK,QAAQ,OAAO,EAAE;AAAA,IACxB,CAAC;AAAA,EACH;AAAA;AAAA,EAIQ,sBAAsB;AAC5B,UAAM,cAAU,+BAAW;AAC3B,UAAM,YAAY,QAAQ,aAAa;AACvC,UAAM,YAAY,KAAK,WAAY,gBAAgB,iBAAiB;AAEpE,eAAO,wCAAoB;AAAA,MACzB;AAAA,MACA,aAAa,KAAK,WAAY;AAAA,MAC9B,gBAAgB,KAAK,WAAY;AAAA,MACjC,cAAc,KAAK,WAAY,aAAa;AAAA,MAC5C,YAAY,cAAc,SAAS;AAAA,MACnC,SAAS;AAAA,MACT,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AAAA,EAEQ,UAAU,WAAgE,KAAK,oBAAoB,GAAmB;AAC5H,UAAM,cAAU,+BAAW;AAE3B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,IAAI,SAAS;AAAA,MACb,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,UAAU,SAAS,QAAQ;AAAA,MAC3B,UAAU,SAAS,QAAQ;AAAA,MAC3B,UAAU,QAAQ,YAAY;AAAA,MAC9B,QAAQ;AAAA,QACN,MAAM,SAAS,QAAQ;AAAA,QACvB,UAAU,SAAS,QAAQ;AAAA,QAC3B,SAAS,SAAS,QAAQ;AAAA,QAC1B,cAAc,SAAS,QAAQ;AAAA,QAC/B,SAAS,SAAS,QAAQ;AAAA,QAC1B,QAAQ,SAAS,QAAQ;AAAA,QACzB,MAAM,SAAS,QAAQ;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,eAAe,MAAc,MAAyB;AAClE,QAAI,CAAC,KAAK,YAAY;AACpB,aAAO,EAAE,SAAS,OAAO,OAAO,6BAA6B;AAAA,IAC/D;AACA,UAAM,SAAS,MAAM,KAAK,WAAW,OAAO,QAAQ,MAAM,MAAM,YAAY;AAC5E,QAAI,KAAK,WAAW,YAAY,EAAG,MAAK,gBAAgB;AACxD,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAwB;AAC9B,QAAI,KAAK,QAAQ,SAAS,EAAG;AAC7B,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,MAAM,KAAK,UAAU,EAAE,MAAM,UAAU,MAAM,OAAO,CAAC;AAC3D,UAAM,WAAW,CAAC,GAAG,KAAK,WAAY,YAAY,OAAO,CAAC,EAAE,OAAO,OAAK,EAAE,WAAW,EAAE;AACvF,2BAAI,MAAM,aAAa,iBAAY,KAAK,QAAQ,IAAI,eAAgB,OAAe,UAAU,UAAU,CAAC,gBAAgB,QAAQ,MAAM;AACtI,eAAW,UAAU,KAAK,SAAS;AACjC,UAAI,OAAO,eAAe,oBAAU,MAAM;AACxC,eAAO,KAAK,GAAG;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIQ,YAAsB;AAC5B,UAAM,aAAgB,qBAAkB;AACxC,UAAM,MAAgB,CAAC;AACvB,eAAW,SAAS,OAAO,OAAO,UAAU,GAAG;AAC7C,UAAI,CAAC,MAAO;AACZ,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,WAAW,UAAU,CAAC,KAAK,UAAU;AAC5C,cAAI,KAAK,KAAK,OAAO;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,OAAsB;AAC1B,QAAI,CAAC,KAAK,QAAS;AACnB,SAAK,UAAU;AAEf,YAAQ,IAAI,uBAAuB;AAEnC,QAAI,KAAK,aAAa;AACpB,oBAAc,KAAK,WAAW;AAC9B,WAAK,cAAc;AAAA,IACrB;AAGA,eAAW,MAAM,KAAK,SAAS;AAC7B,UAAI;AAAE,WAAG,MAAM;AAAA,MAAG,QAAQ;AAAA,MAAa;AAAA,IACzC;AACA,SAAK,QAAQ,MAAM;AAGnB,QAAI,KAAK,KAAK;AACZ,WAAK,IAAI,MAAM;AACf,WAAK,MAAM;AAAA,IACb;AAGA,QAAI,KAAK,YAAY;AACnB,gBAAM,6CAAyB,KAAK,UAAU;AAAA,IAChD;AAGA,QAAI,KAAK,YAAY;AACnB,WAAK,WAAW,MAAM;AACtB,WAAK,aAAa;AAAA,IACpB;AAEA,YAAQ,IAAI,wCAAmC;AAC/C,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAIA,eAAe,OAAsB;AACnC,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,QAAM,iBAAiB,KAAK,CAAC,KAAK;AAClC,MAAI,mBAAmB,UAAU;AAC/B,UAAM,SAAS,KAAK,CAAC;AACrB,QAAI,CAAC,QAAQ;AACX,cAAQ,MAAM,2DAA2D;AACzE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,UAAM,WAAW,KAAK,SAAS,aAAa;AAC5C,UAAM,WAAW,KAAK,SAAS,YAAY;AAC3C,UAAM,WAAW,MAAM,uBAAuB,QAAQ,EAAE,UAAU,SAAS,CAAC;AAC5E,YAAQ,KAAK,QAAQ;AAAA,EACvB;AACA,MAAI,mBAAmB,UAAU,mBAAmB,YAAY;AAC9D,UAAM,UAAU,KAAK,SAAS,OAAO;AACrC,UAAM,WAAW,MAAM,qBAAqB,OAAO;AACnD,YAAQ,KAAK,QAAQ;AAAA,EACvB;AACA,QAAM,UAA6B,CAAC;AAGpC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,SAAK,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,SAAS,KAAK,IAAI,CAAC,GAAG;AAC7D,cAAQ,OAAO,SAAS,KAAK,IAAI,CAAC,CAAC;AACnC;AAAA,IACF;AACA,QAAI,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,MAAM;AAC5C,cAAQ,OAAO;AAAA,IACjB;AACA,QAAI,KAAK,CAAC,MAAM,cAAc,KAAK,IAAI,CAAC,GAAG;AACzC,cAAQ,YAAY,KAAK,IAAI,CAAC;AAC9B;AAAA,IACF;AACA,QAAI,KAAK,CAAC,MAAM,aAAa;AAC3B,cAAQ,OAAO;AAAA,IACjB;AACA,QAAI,KAAK,CAAC,MAAM,SAAS;AACvB,MAAC,QAAgB,MAAM;AAAA,IACzB;AACA,QAAI,KAAK,CAAC,MAAM,aAAa,KAAK,IAAI,CAAC,GAAG;AACxC,cAAQ,QAAQ,KAAK,IAAI,CAAC;AAC1B;AAAA,IACF;AACA,QAAI,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,MAAM;AAC5C,cAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAkBjB;AACK,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAGA,MAAI,CAAC,QAAQ,WAAW;AACtB,UAAM,aAAa;AAAA,MACZ,UAAK,WAAW,2BAA2B;AAAA,MAC3C,UAAK,WAAW,WAAW;AAAA,MAC3B,UAAK,QAAQ,IAAI,GAAG,QAAQ;AAAA,IACnC;AACA,eAAW,aAAa,YAAY;AAClC,UAAO,cAAgB,UAAK,WAAW,YAAY,CAAC,GAAG;AACrD,gBAAQ,YAAY;AACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,IAAI,iBAAiB;AACpC,QAAM,OAAO,MAAM,OAAO;AAG1B,QAAM,IAAI,QAAc,MAAM;AAAA,EAAC,CAAC;AAClC;AAEA,KAAK,EAAE,MAAM,CAAC,MAAM;AAClB,UAAQ,MAAM,gBAAgB,CAAC;AAC/B,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["import_session_host_core"]}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-standalone",
3
- "version": "0.7.5",
3
+ "version": "0.7.7",
4
4
  "description": "ADHDev standalone daemon — embedded HTTP/WS server for local dashboard",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
- "adhdev-standalone": "./dist/index.js"
7
+ "adhdev-standalone": "./dist/index.js",
8
+ "adhdev": "./dist/index.js"
8
9
  },
9
10
  "scripts": {
10
11
  "build": "tsup",
@@ -31,6 +32,10 @@
31
32
  "license": "AGPL-3.0-or-later",
32
33
  "dependencies": {
33
34
  "@adhdev/daemon-core": "*",
35
+ "@adhdev/session-host-core": "*",
36
+ "@adhdev/session-host-daemon": "*",
37
+ "@adhdev/terminal-mux-cli": "*",
38
+ "@adhdev/terminal-mux-control": "*",
34
39
  "open": "^10.1.0",
35
40
  "ws": "^8.19.0"
36
41
  },