agent-console-server 3.7.0 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,19 +1,112 @@
1
- import { B as getSignedText, V as serverMessageSchema, _ as driverCommandSchema, et as agentEventSchema, ft as todoStatusSchema, g as EphemeralAgentEventTypes, in as DEFAULT_HOSTNAME, l as commandSchema, ln as SCHEME_PAIRING_CODE_DURATION, n as handshakeMessageSchema, on as HOST_SCHEME, un as SHELL_OUTPUT_LENGTH, wt as permissionModeSchema } from "./HostCloseCode-eTYq6aIa.js";
1
+ import { B as getSignedText, V as serverMessageSchema, _ as driverCommandSchema, an as DEFAULT_APP_ORIGIN, cn as HOST_SCHEME, dn as SCHEME_PAIRING_CODE_DURATION, et as agentEventSchema, fn as SHELL_OUTPUT_LENGTH, ft as todoStatusSchema, ln as PAIRING_CODE_PARAMETER, on as DEFAULT_HOSTNAME, r as handshakeMessageSchema, sn as DEFAULT_PORT, t as EphemeralAgentEventTypes, u as commandSchema, un as PAIRING_HASH_PARAMETER, wt as permissionModeSchema } from "./EphemeralAgentEventTypes-Ctmqlyvj.js";
2
2
  import { createRequire } from "node:module";
3
- import { z } from "zod";
4
- import { ID_SEPARATOR, InvalidOperationError, Operation, SITE_NAME, createUniqueArraySchema, exhaustiveGuard, getOrCreate, getResult, getResultAsync, noop, withFinalizerAsync } from "@esposter/shared";
5
- import { homedir } from "node:os";
6
- import { delimiter, dirname, join, relative, win32 } from "node:path";
3
+ import { homedir, hostname } from "node:os";
4
+ import { ID_SEPARATOR, InvalidOperationError, Operation, RoutePath, SITE_NAME, createUniqueArraySchema, exhaustiveGuard, getOrCreate, getResult, getResultAsync, noop, withFinalizerAsync } from "@esposter/shared";
5
+ import { basename, delimiter, dirname, join, relative, win32 } from "node:path";
6
+ import { execFileSync, spawn } from "node:child_process";
7
7
  import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
8
+ import { getAssetKeys, getRawAsset, isSea } from "node:sea";
8
9
  import { createHash, createPrivateKey, createPublicKey, generateKeyPairSync, randomBytes, sign, timingSafeEqual, verify } from "node:crypto";
10
+ import { z } from "zod";
9
11
  import { once } from "node:events";
10
12
  import { WebSocket, WebSocketServer } from "ws";
13
+ import { parseArgs } from "node:util";
11
14
  import { getSessionInfo, getSessionMessages, listSessions, query } from "@anthropic-ai/claude-agent-sdk";
12
15
  import { readFile, readdir } from "node:fs/promises";
13
- import { getAssetKeys, getRawAsset, isSea } from "node:sea";
14
16
  import { createServer } from "node:http";
15
- import { execFileSync, spawn } from "node:child_process";
16
17
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
18
+ //#region src/services/cli/getReachableHostname.ts
19
+ const getReachableHostname = (hostname$1) => hostname$1 === "0.0.0.0" ? hostname() : hostname$1;
20
+ //#endregion
21
+ //#region src/services/cli/hostArgs.ts
22
+ const hostArgs = {
23
+ hostname: {
24
+ default: DEFAULT_HOSTNAME,
25
+ description: "The address the host listens on",
26
+ type: "string"
27
+ },
28
+ origin: {
29
+ default: DEFAULT_APP_ORIGIN,
30
+ description: "The app's origin the printed link opens",
31
+ type: "string"
32
+ },
33
+ port: {
34
+ default: String(DEFAULT_PORT),
35
+ description: "The port the host listens on",
36
+ type: "string"
37
+ }
38
+ };
39
+ //#endregion
40
+ //#region src/services/installer/constants.ts
41
+ const HOST_EXECUTABLE_FILENAME = "agent-console-host.exe";
42
+ const CLAUDE_CODE_EXECUTABLE_FILENAME = "claude.exe";
43
+ const HOST_SCHEME_REGISTRY_KEY = win32.join("HKCU", "Software", "Classes", HOST_SCHEME);
44
+ const HOST_DIRECTORY_ENVIRONMENT_VARIABLE = `${SITE_NAME.toUpperCase()}_HOST_DIRECTORY`;
45
+ const HOST_INSTALL_DIRECTORY_SEGMENTS = [SITE_NAME, "Host"];
46
+ const NODE_PTY_DIRECTORY_NAME = "node-pty";
47
+ //#endregion
48
+ //#region src/services/installer/getHostInstallDirectory.ts
49
+ const getHostInstallDirectory = () => join(process.env.LOCALAPPDATA ?? join(homedir(), "AppData", "Local"), ...HOST_INSTALL_DIRECTORY_SEGMENTS);
50
+ //#endregion
51
+ //#region src/services/installer/checkIsHostInstalled.ts
52
+ const checkIsHostInstalled = () => relative(getHostInstallDirectory(), dirname(process.execPath)) === "";
53
+ //#endregion
54
+ //#region src/services/installer/installHost.ts
55
+ const installHost = () => {
56
+ const installDirectory = getHostInstallDirectory();
57
+ const executablePath = join(installDirectory, HOST_EXECUTABLE_FILENAME);
58
+ mkdirSync(installDirectory, { recursive: true });
59
+ copyFileSync(process.execPath, executablePath);
60
+ writeFileSync(join(installDirectory, CLAUDE_CODE_EXECUTABLE_FILENAME), new Uint8Array(getRawAsset(CLAUDE_CODE_EXECUTABLE_FILENAME)));
61
+ for (const assetKey of getAssetKeys().filter((key) => key.startsWith(`${NODE_PTY_DIRECTORY_NAME}/`))) {
62
+ const assetPath = join(installDirectory, ...assetKey.split("/"));
63
+ mkdirSync(dirname(assetPath), { recursive: true });
64
+ writeFileSync(assetPath, new Uint8Array(getRawAsset(assetKey)));
65
+ }
66
+ for (const registryArguments of [
67
+ [
68
+ HOST_SCHEME_REGISTRY_KEY,
69
+ "/ve",
70
+ "/d",
71
+ `URL:${SITE_NAME} Host`
72
+ ],
73
+ [
74
+ HOST_SCHEME_REGISTRY_KEY,
75
+ "/v",
76
+ "URL Protocol",
77
+ "/d",
78
+ ""
79
+ ],
80
+ [
81
+ win32.join(HOST_SCHEME_REGISTRY_KEY, "shell", "open", "command"),
82
+ "/ve",
83
+ "/d",
84
+ `"${executablePath}" "%1"`
85
+ ]
86
+ ]) execFileSync("reg", [
87
+ "add",
88
+ ...registryArguments,
89
+ "/f"
90
+ ], { stdio: "ignore" });
91
+ return installDirectory;
92
+ };
93
+ //#endregion
94
+ //#region src/services/cli/installDownloadedHost.ts
95
+ const installDownloadedHost = () => {
96
+ if (!isSea() || checkIsHostInstalled()) return;
97
+ getResult(() => installHost()).match((installDirectory) => {
98
+ process.stdout.write(`Installed the host in ${installDirectory}. The page's Connect starts it from now on.\n\n`);
99
+ }, (error) => {
100
+ process.stderr.write(`Could not install the host: ${error.message}\nClose any other host window, then open this file again.\n`);
101
+ process.exit(1);
102
+ });
103
+ };
104
+ //#endregion
105
+ //#region src/services/cli/writeLine.ts
106
+ const writeLine = (line) => {
107
+ process.stdout.write(`${line}\n`);
108
+ };
109
+ //#endregion
17
110
  //#region src/services/device/constants.ts
18
111
  const STATE_DIRECTORY_NAME = ".agent-console-server";
19
112
  const DEVICES_FILENAME = "devices.json";
@@ -135,6 +228,506 @@ const runDevicesCommand = async ({ hostKey, hostname, port, revokeDeviceId, stat
135
228
  return true;
136
229
  };
137
230
  //#endregion
231
+ //#region ../../node_modules/.pnpm/citty@0.2.2/node_modules/citty/dist/_chunks/libs/scule.mjs
232
+ const NUMBER_CHAR_RE = /\d/;
233
+ const STR_SPLITTERS = [
234
+ "-",
235
+ "_",
236
+ "/",
237
+ "."
238
+ ];
239
+ function isUppercase(char = "") {
240
+ if (NUMBER_CHAR_RE.test(char)) return;
241
+ return char !== char.toLowerCase();
242
+ }
243
+ function splitByCase(str, separators) {
244
+ const splitters = separators ?? STR_SPLITTERS;
245
+ const parts = [];
246
+ if (!str || typeof str !== "string") return parts;
247
+ let buff = "";
248
+ let previousUpper;
249
+ let previousSplitter;
250
+ for (const char of str) {
251
+ const isSplitter = splitters.includes(char);
252
+ if (isSplitter === true) {
253
+ parts.push(buff);
254
+ buff = "";
255
+ previousUpper = void 0;
256
+ continue;
257
+ }
258
+ const isUpper = isUppercase(char);
259
+ if (previousSplitter === false) {
260
+ if (previousUpper === false && isUpper === true) {
261
+ parts.push(buff);
262
+ buff = char;
263
+ previousUpper = isUpper;
264
+ continue;
265
+ }
266
+ if (previousUpper === true && isUpper === false && buff.length > 1) {
267
+ const lastChar = buff.at(-1);
268
+ parts.push(buff.slice(0, Math.max(0, buff.length - 1)));
269
+ buff = lastChar + char;
270
+ previousUpper = isUpper;
271
+ continue;
272
+ }
273
+ }
274
+ buff += char;
275
+ previousUpper = isUpper;
276
+ previousSplitter = isSplitter;
277
+ }
278
+ parts.push(buff);
279
+ return parts;
280
+ }
281
+ function upperFirst(str) {
282
+ return str ? str[0].toUpperCase() + str.slice(1) : "";
283
+ }
284
+ function lowerFirst(str) {
285
+ return str ? str[0].toLowerCase() + str.slice(1) : "";
286
+ }
287
+ function pascalCase(str, opts) {
288
+ return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p) => upperFirst(opts?.normalize ? p.toLowerCase() : p)).join("") : "";
289
+ }
290
+ function camelCase(str, opts) {
291
+ return lowerFirst(pascalCase(str || "", opts));
292
+ }
293
+ function kebabCase(str, joiner) {
294
+ return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p) => p.toLowerCase()).join(joiner ?? "-") : "";
295
+ }
296
+ function snakeCase(str) {
297
+ return kebabCase(str || "", "_");
298
+ }
299
+ //#endregion
300
+ //#region ../../node_modules/.pnpm/citty@0.2.2/node_modules/citty/dist/index.mjs
301
+ function toArray(val) {
302
+ if (Array.isArray(val)) return val;
303
+ return val === void 0 ? [] : [val];
304
+ }
305
+ function formatLineColumns(lines, linePrefix = "") {
306
+ const maxLength = [];
307
+ for (const line of lines) for (const [i, element] of line.entries()) maxLength[i] = Math.max(maxLength[i] || 0, element.length);
308
+ return lines.map((l) => l.map((c, i) => linePrefix + c[i === 0 ? "padStart" : "padEnd"](maxLength[i])).join(" ")).join("\n");
309
+ }
310
+ function resolveValue(input) {
311
+ return typeof input === "function" ? input() : input;
312
+ }
313
+ var CLIError = class extends Error {
314
+ code;
315
+ constructor(message, code) {
316
+ super(message);
317
+ this.name = "CLIError";
318
+ this.code = code;
319
+ }
320
+ };
321
+ function parseRawArgs(args = [], opts = {}) {
322
+ const booleans = new Set(opts.boolean || []);
323
+ const strings = new Set(opts.string || []);
324
+ const aliasMap = opts.alias || {};
325
+ const defaults = opts.default || {};
326
+ const aliasToMain = /* @__PURE__ */ new Map();
327
+ const mainToAliases = /* @__PURE__ */ new Map();
328
+ for (const [key, value] of Object.entries(aliasMap)) {
329
+ const targets = value;
330
+ for (const target of targets) {
331
+ aliasToMain.set(key, target);
332
+ if (!mainToAliases.has(target)) mainToAliases.set(target, []);
333
+ mainToAliases.get(target).push(key);
334
+ aliasToMain.set(target, key);
335
+ if (!mainToAliases.has(key)) mainToAliases.set(key, []);
336
+ mainToAliases.get(key).push(target);
337
+ }
338
+ }
339
+ const options = {};
340
+ function getType(name) {
341
+ if (booleans.has(name)) return "boolean";
342
+ const aliases = mainToAliases.get(name) || [];
343
+ for (const alias of aliases) if (booleans.has(alias)) return "boolean";
344
+ return "string";
345
+ }
346
+ function isStringType(name) {
347
+ if (strings.has(name)) return true;
348
+ const aliases = mainToAliases.get(name) || [];
349
+ for (const alias of aliases) if (strings.has(alias)) return true;
350
+ return false;
351
+ }
352
+ const allOptions = /* @__PURE__ */ new Set([
353
+ ...booleans,
354
+ ...strings,
355
+ ...Object.keys(aliasMap),
356
+ ...Object.values(aliasMap).flat(),
357
+ ...Object.keys(defaults)
358
+ ]);
359
+ for (const name of allOptions) if (!options[name]) options[name] = {
360
+ type: getType(name),
361
+ default: defaults[name]
362
+ };
363
+ for (const [alias, main] of aliasToMain.entries()) if (alias.length === 1 && options[main] && !options[main].short) options[main].short = alias;
364
+ const processedArgs = [];
365
+ const negatedFlags = {};
366
+ for (let i = 0; i < args.length; i++) {
367
+ const arg = args[i];
368
+ if (arg === "--") {
369
+ processedArgs.push(...args.slice(i));
370
+ break;
371
+ }
372
+ if (arg.startsWith("--no-")) {
373
+ const flagName = arg.slice(5);
374
+ negatedFlags[flagName] = true;
375
+ continue;
376
+ }
377
+ processedArgs.push(arg);
378
+ }
379
+ let parsed;
380
+ try {
381
+ parsed = parseArgs({
382
+ args: processedArgs,
383
+ options: Object.keys(options).length > 0 ? options : void 0,
384
+ allowPositionals: true,
385
+ strict: false
386
+ });
387
+ } catch {
388
+ parsed = {
389
+ values: {},
390
+ positionals: processedArgs
391
+ };
392
+ }
393
+ const out = { _: [] };
394
+ out._ = parsed.positionals;
395
+ for (const [key, value] of Object.entries(parsed.values)) {
396
+ let coerced = value;
397
+ if (getType(key) === "boolean" && typeof value === "string") coerced = value !== "false";
398
+ else if (isStringType(key) && typeof value === "boolean") coerced = "";
399
+ out[key] = coerced;
400
+ }
401
+ for (const [name] of Object.entries(negatedFlags)) {
402
+ out[name] = false;
403
+ const mainName = aliasToMain.get(name);
404
+ if (mainName) out[mainName] = false;
405
+ const aliases = mainToAliases.get(name);
406
+ if (aliases) for (const alias of aliases) out[alias] = false;
407
+ }
408
+ for (const [alias, main] of aliasToMain.entries()) {
409
+ if (out[alias] !== void 0 && out[main] === void 0) out[main] = out[alias];
410
+ if (out[main] !== void 0 && out[alias] === void 0) out[alias] = out[main];
411
+ if (out[alias] !== out[main] && defaults[main] === out[main]) out[main] = out[alias];
412
+ }
413
+ return out;
414
+ }
415
+ const noColor = /* @__PURE__ */ (() => {
416
+ const env = globalThis.process?.env ?? {};
417
+ return env.NO_COLOR === "1" || env.TERM === "dumb" || env.TEST || env.CI;
418
+ })();
419
+ const _c = (c, r = 39) => (t) => noColor ? t : `\u001B[${c}m${t}\u001B[${r}m`;
420
+ const bold = /* @__PURE__ */ _c(1, 22);
421
+ const cyan = /* @__PURE__ */ _c(36);
422
+ const gray = /* @__PURE__ */ _c(90);
423
+ const underline = /* @__PURE__ */ _c(4, 24);
424
+ function parseArgs$1(rawArgs, argsDef) {
425
+ const parseOptions = {
426
+ boolean: [],
427
+ string: [],
428
+ alias: {},
429
+ default: {}
430
+ };
431
+ const args = resolveArgs(argsDef);
432
+ for (const arg of args) {
433
+ if (arg.type === "positional") continue;
434
+ if (arg.type === "string" || arg.type === "enum") parseOptions.string.push(arg.name);
435
+ else if (arg.type === "boolean") parseOptions.boolean.push(arg.name);
436
+ if (arg.default !== void 0) parseOptions.default[arg.name] = arg.default;
437
+ if (arg.alias) parseOptions.alias[arg.name] = arg.alias;
438
+ const camelName = camelCase(arg.name);
439
+ const kebabName = kebabCase(arg.name);
440
+ if (camelName !== arg.name || kebabName !== arg.name) {
441
+ const existingAliases = toArray(parseOptions.alias[arg.name] || []);
442
+ if (camelName !== arg.name && !existingAliases.includes(camelName)) existingAliases.push(camelName);
443
+ if (kebabName !== arg.name && !existingAliases.includes(kebabName)) existingAliases.push(kebabName);
444
+ if (existingAliases.length > 0) parseOptions.alias[arg.name] = existingAliases;
445
+ }
446
+ }
447
+ const parsed = parseRawArgs(rawArgs, parseOptions);
448
+ const [ ...positionalArguments] = parsed._;
449
+ const parsedArgsProxy = new Proxy(parsed, { get(target, prop) {
450
+ return target[prop] ?? target[camelCase(prop)] ?? target[kebabCase(prop)];
451
+ } });
452
+ for (const [, arg] of args.entries()) if (arg.type === "positional") {
453
+ const nextPositionalArgument = positionalArguments.shift();
454
+ if (nextPositionalArgument !== void 0) parsedArgsProxy[arg.name] = nextPositionalArgument;
455
+ else if (arg.default === void 0 && arg.required !== false) throw new CLIError(`Missing required positional argument: ${arg.name.toUpperCase()}`, "EARG");
456
+ else parsedArgsProxy[arg.name] = arg.default;
457
+ } else if (arg.type === "enum") {
458
+ const argument = parsedArgsProxy[arg.name];
459
+ const options = arg.options || [];
460
+ if (argument !== void 0 && options.length > 0 && !options.includes(argument)) throw new CLIError(`Invalid value for argument: ${cyan(`--${arg.name}`)} (${cyan(argument)}). Expected one of: ${options.map((o) => cyan(o)).join(", ")}.`, "EARG");
461
+ } else if (arg.required && parsedArgsProxy[arg.name] === void 0) throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
462
+ return parsedArgsProxy;
463
+ }
464
+ function resolveArgs(argsDef) {
465
+ const args = [];
466
+ for (const [name, argDef] of Object.entries(argsDef || {})) args.push({
467
+ ...argDef,
468
+ name,
469
+ alias: toArray(argDef.alias)
470
+ });
471
+ return args;
472
+ }
473
+ async function resolvePlugins(plugins) {
474
+ return Promise.all(plugins.map((p) => resolveValue(p)));
475
+ }
476
+ function defineCommand(def) {
477
+ return def;
478
+ }
479
+ async function runCommand(cmd, opts) {
480
+ const cmdArgs = await resolveValue(cmd.args || {});
481
+ const parsedArgs = parseArgs$1(opts.rawArgs, cmdArgs);
482
+ const context = {
483
+ rawArgs: opts.rawArgs,
484
+ args: parsedArgs,
485
+ data: opts.data,
486
+ cmd
487
+ };
488
+ const plugins = await resolvePlugins(cmd.plugins ?? []);
489
+ let result;
490
+ let runError;
491
+ try {
492
+ for (const plugin of plugins) await plugin.setup?.(context);
493
+ if (typeof cmd.setup === "function") await cmd.setup(context);
494
+ const subCommands = await resolveValue(cmd.subCommands);
495
+ if (subCommands && Object.keys(subCommands).length > 0) {
496
+ const subCommandArgIndex = findSubCommandIndex(opts.rawArgs, cmdArgs);
497
+ const explicitName = opts.rawArgs[subCommandArgIndex];
498
+ if (explicitName) {
499
+ const subCommand = await _findSubCommand(subCommands, explicitName);
500
+ if (!subCommand) throw new CLIError(`Unknown command ${cyan(explicitName)}`, "E_UNKNOWN_COMMAND");
501
+ await runCommand(subCommand, { rawArgs: opts.rawArgs.slice(subCommandArgIndex + 1) });
502
+ } else {
503
+ const defaultSubCommand = await resolveValue(cmd.default);
504
+ if (defaultSubCommand) {
505
+ if (cmd.run) throw new CLIError(`Cannot specify both 'run' and 'default' on the same command.`, "E_DEFAULT_CONFLICT");
506
+ const subCommand = await _findSubCommand(subCommands, defaultSubCommand);
507
+ if (!subCommand) throw new CLIError(`Default sub command ${cyan(defaultSubCommand)} not found in subCommands.`, "E_UNKNOWN_COMMAND");
508
+ await runCommand(subCommand, { rawArgs: opts.rawArgs });
509
+ } else if (!cmd.run) throw new CLIError(`No command specified.`, "E_NO_COMMAND");
510
+ }
511
+ }
512
+ if (typeof cmd.run === "function") result = await cmd.run(context);
513
+ } catch (error) {
514
+ runError = error;
515
+ }
516
+ const cleanupErrors = [];
517
+ if (typeof cmd.cleanup === "function") try {
518
+ await cmd.cleanup(context);
519
+ } catch (error) {
520
+ cleanupErrors.push(error);
521
+ }
522
+ for (const plugin of [...plugins].reverse()) try {
523
+ await plugin.cleanup?.(context);
524
+ } catch (error) {
525
+ cleanupErrors.push(error);
526
+ }
527
+ if (runError) throw runError;
528
+ if (cleanupErrors.length === 1) throw cleanupErrors[0];
529
+ if (cleanupErrors.length > 1) throw new Error("Multiple cleanup errors", { cause: cleanupErrors });
530
+ return { result };
531
+ }
532
+ async function resolveSubCommand(cmd, rawArgs, parent) {
533
+ const subCommands = await resolveValue(cmd.subCommands);
534
+ if (subCommands && Object.keys(subCommands).length > 0) {
535
+ const subCommandArgIndex = findSubCommandIndex(rawArgs, await resolveValue(cmd.args || {}));
536
+ const subCommandName = rawArgs[subCommandArgIndex];
537
+ const subCommand = await _findSubCommand(subCommands, subCommandName);
538
+ if (subCommand) return resolveSubCommand(subCommand, rawArgs.slice(subCommandArgIndex + 1), cmd);
539
+ }
540
+ return [cmd, parent];
541
+ }
542
+ async function _findSubCommand(subCommands, name) {
543
+ if (name in subCommands) return resolveValue(subCommands[name]);
544
+ for (const sub of Object.values(subCommands)) {
545
+ const resolved = await resolveValue(sub);
546
+ const meta = await resolveValue(resolved?.meta);
547
+ if (meta?.alias) {
548
+ if (toArray(meta.alias).includes(name)) return resolved;
549
+ }
550
+ }
551
+ }
552
+ function findSubCommandIndex(rawArgs, argsDef) {
553
+ for (let i = 0; i < rawArgs.length; i++) {
554
+ const arg = rawArgs[i];
555
+ if (arg === "--") return -1;
556
+ if (arg.startsWith("-")) {
557
+ if (!arg.includes("=") && _isValueFlag(arg, argsDef)) i++;
558
+ continue;
559
+ }
560
+ return i;
561
+ }
562
+ return -1;
563
+ }
564
+ function _isValueFlag(flag, argsDef) {
565
+ const name = flag.replace(/^-{1,2}/, "");
566
+ const normalized = camelCase(name);
567
+ for (const [key, def] of Object.entries(argsDef)) {
568
+ if (def.type !== "string" && def.type !== "enum") continue;
569
+ if (normalized === camelCase(key)) return true;
570
+ if ((Array.isArray(def.alias) ? def.alias : def.alias ? [def.alias] : []).includes(name)) return true;
571
+ }
572
+ return false;
573
+ }
574
+ async function showUsage(cmd, parent) {
575
+ try {
576
+ console.log(await renderUsage(cmd, parent) + "\n");
577
+ } catch (error) {
578
+ console.error(error);
579
+ }
580
+ }
581
+ const negativePrefixRe = /^no[-A-Z]/;
582
+ async function renderUsage(cmd, parent) {
583
+ const cmdMeta = await resolveValue(cmd.meta || {});
584
+ const cmdArgs = resolveArgs(await resolveValue(cmd.args || {}));
585
+ const parentMeta = await resolveValue(parent?.meta || {});
586
+ const commandName = `${parentMeta.name ? `${parentMeta.name} ` : ""}` + (cmdMeta.name || process.argv[1]);
587
+ const argLines = [];
588
+ const posLines = [];
589
+ const commandsLines = [];
590
+ const usageLine = [];
591
+ for (const arg of cmdArgs) if (arg.type === "positional") {
592
+ const name = arg.name.toUpperCase();
593
+ const isRequired = arg.required !== false && arg.default === void 0;
594
+ posLines.push([cyan(name + renderValueHint(arg)), renderDescription(arg, isRequired)]);
595
+ usageLine.push(isRequired ? `<${name}>` : `[${name}]`);
596
+ } else {
597
+ const isRequired = arg.required === true && arg.default === void 0;
598
+ const argStr = [...(arg.alias || []).map((a) => `-${a}`), `--${arg.name}`].join(", ") + renderValueHint(arg);
599
+ argLines.push([cyan(argStr), renderDescription(arg, isRequired)]);
600
+ /**
601
+ * print negative boolean arg variant usage when
602
+ * - enabled by default or has `negativeDescription`
603
+ * - not prefixed with `no-` or `no[A-Z]`
604
+ */
605
+ if (arg.type === "boolean" && (arg.default === true || arg.negativeDescription) && !negativePrefixRe.test(arg.name)) {
606
+ const negativeArgStr = [...(arg.alias || []).map((a) => `--no-${a}`), `--no-${arg.name}`].join(", ");
607
+ argLines.push([cyan(negativeArgStr), [arg.negativeDescription, isRequired ? gray("(Required)") : ""].filter(Boolean).join(" ")]);
608
+ }
609
+ if (isRequired) usageLine.push(`--${arg.name}` + renderValueHint(arg));
610
+ }
611
+ if (cmd.subCommands) {
612
+ const commandNames = [];
613
+ const subCommands = await resolveValue(cmd.subCommands);
614
+ for (const [name, sub] of Object.entries(subCommands)) {
615
+ const meta = await resolveValue((await resolveValue(sub))?.meta);
616
+ if (meta?.hidden) continue;
617
+ const aliases = toArray(meta?.alias);
618
+ const label = [name, ...aliases].join(", ");
619
+ commandsLines.push([cyan(label), meta?.description || ""]);
620
+ commandNames.push(name, ...aliases);
621
+ }
622
+ usageLine.push(commandNames.join("|"));
623
+ }
624
+ const usageLines = [];
625
+ const version = cmdMeta.version || parentMeta.version;
626
+ usageLines.push(gray(`${cmdMeta.description} (${commandName + (version ? ` v${version}` : "")})`), "");
627
+ const hasOptions = argLines.length > 0 || posLines.length > 0;
628
+ usageLines.push(`${underline(bold("USAGE"))} ${cyan(`${commandName}${hasOptions ? " [OPTIONS]" : ""} ${usageLine.join(" ")}`)}`, "");
629
+ if (posLines.length > 0) {
630
+ usageLines.push(underline(bold("ARGUMENTS")), "");
631
+ usageLines.push(formatLineColumns(posLines, " "));
632
+ usageLines.push("");
633
+ }
634
+ if (argLines.length > 0) {
635
+ usageLines.push(underline(bold("OPTIONS")), "");
636
+ usageLines.push(formatLineColumns(argLines, " "));
637
+ usageLines.push("");
638
+ }
639
+ if (commandsLines.length > 0) {
640
+ usageLines.push(underline(bold("COMMANDS")), "");
641
+ usageLines.push(formatLineColumns(commandsLines, " "));
642
+ usageLines.push("", `Use ${cyan(`${commandName} <command> --help`)} for more information about a command.`);
643
+ }
644
+ return usageLines.filter((l) => typeof l === "string").join("\n");
645
+ }
646
+ function renderValueHint(arg) {
647
+ const valueHint = arg.valueHint ? `=<${arg.valueHint}>` : "";
648
+ const fallbackValueHint = valueHint || `=<${snakeCase(arg.name)}>`;
649
+ if (!arg.type || arg.type === "positional" || arg.type === "boolean") return valueHint;
650
+ if (arg.type === "enum" && arg.options?.length) return `=<${arg.options.join("|")}>`;
651
+ return fallbackValueHint;
652
+ }
653
+ function renderDescription(arg, required) {
654
+ const requiredHint = required ? gray("(Required)") : "";
655
+ const defaultHint = arg.default === void 0 ? "" : gray(`(Default: ${arg.default})`);
656
+ return [
657
+ arg.description,
658
+ requiredHint,
659
+ defaultHint
660
+ ].filter(Boolean).join(" ");
661
+ }
662
+ async function runMain(cmd, opts = {}) {
663
+ const rawArgs = opts.rawArgs || process.argv.slice(2);
664
+ const showUsage$1 = opts.showUsage || showUsage;
665
+ try {
666
+ const builtinFlags = await _resolveBuiltinFlags(cmd);
667
+ if (builtinFlags.help.length > 0 && rawArgs.some((arg) => builtinFlags.help.includes(arg))) {
668
+ await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
669
+ process.exit(0);
670
+ } else if (rawArgs.length === 1 && builtinFlags.version.includes(rawArgs[0])) {
671
+ const meta = typeof cmd.meta === "function" ? await cmd.meta() : await cmd.meta;
672
+ if (!meta?.version) throw new CLIError("No version specified", "E_NO_VERSION");
673
+ console.log(meta.version);
674
+ } else await runCommand(cmd, { rawArgs });
675
+ } catch (error) {
676
+ if (error instanceof CLIError) {
677
+ await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
678
+ console.error(error.message);
679
+ } else console.error(error, "\n");
680
+ process.exit(1);
681
+ }
682
+ }
683
+ async function _resolveBuiltinFlags(cmd) {
684
+ const argsDef = await resolveValue(cmd.args || {});
685
+ const userNames = /* @__PURE__ */ new Set();
686
+ const userAliases = /* @__PURE__ */ new Set();
687
+ for (const [name, def] of Object.entries(argsDef)) {
688
+ userNames.add(name);
689
+ for (const alias of toArray(def.alias)) userAliases.add(alias);
690
+ }
691
+ return {
692
+ help: _getBuiltinFlags("help", "h", userNames, userAliases),
693
+ version: _getBuiltinFlags("version", "v", userNames, userAliases)
694
+ };
695
+ }
696
+ function _getBuiltinFlags(long, short, userNames, userAliases) {
697
+ if (userNames.has(long) || userAliases.has(long)) return [];
698
+ if (userNames.has(short) || userAliases.has(short)) return [`--${long}`];
699
+ return [`--${long}`, `-${short}`];
700
+ }
701
+ //#endregion
702
+ //#region src/services/cli/commands/devicesCommand.ts
703
+ const devicesCommand = defineCommand({
704
+ args: {
705
+ hostname: hostArgs.hostname,
706
+ port: hostArgs.port,
707
+ revoke: {
708
+ default: "",
709
+ description: "A paired page's id, to remove it",
710
+ type: "string"
711
+ }
712
+ },
713
+ meta: {
714
+ description: "List the pages paired with this host, or remove one",
715
+ name: "devices"
716
+ },
717
+ run: async ({ args }) => {
718
+ installDownloadedHost();
719
+ const stateDirectory = getStateDirectory();
720
+ const isDone = await runDevicesCommand({
721
+ hostKey: readHostKey(stateDirectory),
722
+ hostname: getReachableHostname(args.hostname),
723
+ port: Number(args.port),
724
+ revokeDeviceId: args.revoke,
725
+ stateDirectory
726
+ }, writeLine);
727
+ process.exit(isDone ? 0 : 1);
728
+ }
729
+ });
730
+ //#endregion
138
731
  //#region src/services/drivers/claudeAgentSdk/getEventId.ts
139
732
  const getEventId = (sourceId, suffix) => `${sourceId}${ID_SEPARATOR}${suffix}`;
140
733
  //#endregion
@@ -980,17 +1573,6 @@ const watchSession = async (sessionId, openSession, { emit, onSessionsChange, op
980
1573
  ]);
981
1574
  };
982
1575
  //#endregion
983
- //#region src/services/installer/constants.ts
984
- const HOST_EXECUTABLE_FILENAME = "agent-console-host.exe";
985
- const CLAUDE_CODE_EXECUTABLE_FILENAME = "claude.exe";
986
- const HOST_SCHEME_REGISTRY_KEY = win32.join("HKCU", "Software", "Classes", HOST_SCHEME);
987
- const HOST_DIRECTORY_ENVIRONMENT_VARIABLE = `${SITE_NAME.toUpperCase()}_HOST_DIRECTORY`;
988
- const HOST_INSTALL_DIRECTORY_SEGMENTS = [SITE_NAME, "Host"];
989
- const NODE_PTY_DIRECTORY_NAME = "node-pty";
990
- //#endregion
991
- //#region src/services/installer/getHostInstallDirectory.ts
992
- const getHostInstallDirectory = () => join(process.env.LOCALAPPDATA ?? join(homedir(), "AppData", "Local"), ...HOST_INSTALL_DIRECTORY_SEGMENTS);
993
- //#endregion
994
1576
  //#region src/services/installer/getClaudeCodeExecutablePath.ts
995
1577
  const getClaudeCodeExecutablePath = () => isSea() ? join(getHostInstallDirectory(), CLAUDE_CODE_EXECUTABLE_FILENAME) : void 0;
996
1578
  //#endregion
@@ -1308,15 +1890,6 @@ const createClaudeAgentSdkDriver = ({ onEvents, onSessionOpen, onSessionsChange
1308
1890
  };
1309
1891
  };
1310
1892
  //#endregion
1311
- //#region src/services/drivers/window/constants.ts
1312
- const SESSION_SUBCOMMAND = "session";
1313
- const SESSION_SECRET_ENVIRONMENT_VARIABLE = `${SITE_NAME.toUpperCase()}_SESSION_SECRET`;
1314
- const SESSION_SECRET_BYTE_LENGTH = 32;
1315
- const SESSION_WINDOW_CONNECT_TIMEOUT = Temporal.Duration.from({ seconds: 30 }).total("milliseconds");
1316
- const SESSION_WINDOWS_FILENAME = "session-windows.json";
1317
- const SESSION_WINDOW_REJOIN_DURATION = Temporal.Duration.from({ minutes: 1 }).total("milliseconds");
1318
- const SESSION_WINDOW_RECONNECT_DELAY = Temporal.Duration.from({ seconds: 1 }).total("milliseconds");
1319
- //#endregion
1320
1893
  //#region src/models/window/BaseChildMessage.ts
1321
1894
  const createBaseChildMessageSchema = (typeSchema) => z.object({ type: typeSchema });
1322
1895
  //#endregion
@@ -1391,6 +1964,15 @@ let SessionWindowCloseCode = /* @__PURE__ */ function(SessionWindowCloseCode) {
1391
1964
  //#region src/services/device/hashCredential.ts
1392
1965
  const hashCredential = (credential) => createHash("sha256").update(credential).digest("base64url");
1393
1966
  //#endregion
1967
+ //#region src/services/drivers/window/constants.ts
1968
+ const SESSION_SUBCOMMAND = "session";
1969
+ const SESSION_SECRET_ENVIRONMENT_VARIABLE = `${SITE_NAME.toUpperCase()}_SESSION_SECRET`;
1970
+ const SESSION_SECRET_BYTE_LENGTH = 32;
1971
+ const SESSION_WINDOW_CONNECT_TIMEOUT = Temporal.Duration.from({ seconds: 30 }).total("milliseconds");
1972
+ const SESSION_WINDOWS_FILENAME = "session-windows.json";
1973
+ const SESSION_WINDOW_REJOIN_DURATION = Temporal.Duration.from({ minutes: 1 }).total("milliseconds");
1974
+ const SESSION_WINDOW_RECONNECT_DELAY = Temporal.Duration.from({ seconds: 1 }).total("milliseconds");
1975
+ //#endregion
1394
1976
  //#region src/models/window/SessionWindows.ts
1395
1977
  const sessionWindowsSchema = z.object({
1396
1978
  port: z.int().min(0),
@@ -1762,296 +2344,51 @@ const launchSessionWindow = ({ port, secret }) => {
1762
2344
  }).on("error", console.error);
1763
2345
  };
1764
2346
  //#endregion
1765
- //#region src/services/drivers/window/formatSessionLogLine.ts
1766
- const formatSessionLogLine = (event) => {
1767
- switch (event.type) {
1768
- case "AssistantMessage": return event.parentToolUseId ? "" : `Claude: ${event.text}`;
1769
- case "HostError": return `Error: ${event.message}`;
1770
- case "PermissionRequest": return `Claude asks to use ${event.toolName}. Answer in the page.`;
1771
- case "ToolUse": return event.parentToolUseId ? "" : `Claude uses ${event.name}`;
1772
- case "UserMessage": return event.parentToolUseId ? "" : `You: ${event.text}`;
1773
- default: return "";
1774
- }
2347
+ //#region src/services/device/findDevice.ts
2348
+ const findDevice = (devices, credential) => {
2349
+ const credentialHash = hashCredential(credential);
2350
+ return devices.find((device) => checkIsTokenValid(credentialHash, device.credentialHash));
1775
2351
  };
1776
2352
  //#endregion
1777
- //#region src/services/server/handleCommand.ts
1778
- const handleCommand = async (driver, command) => {
1779
- switch (command.type) {
1780
- case "BackgroundTasks":
1781
- await driver.backgroundTasks(command.sessionId);
1782
- return "";
1783
- case "CloseSession":
1784
- driver.closeSession(command.sessionId);
1785
- return "";
1786
- case "CreateSession": return driver.createSession(command.cwd);
1787
- case "Fork": return driver.forkSession(command.sessionId, command.messageUuid);
1788
- case "Interrupt":
1789
- await driver.interrupt(command.sessionId);
1790
- return "";
1791
- case "ListSessions": return "";
1792
- case "PermissionVerdict":
1793
- driver.resolvePermission(command.sessionId, command.requestId, command.behavior, command.message);
1794
- return "";
1795
- case "Prompt":
1796
- driver.prompt(command.sessionId, command.text, command.attachments);
1797
- return "";
1798
- case "Resume": return driver.resumeSession(command.sessionId);
1799
- case "ResumeAt": return driver.resumeAt(command.sessionId, command.messageUuid);
1800
- case "RewindFiles":
1801
- await driver.rewindFiles(command.sessionId, command.messageUuid);
1802
- return "";
1803
- case "SetModel":
1804
- await driver.setModel(command.sessionId, command.model);
1805
- return "";
1806
- case "SetPermissionMode":
1807
- await driver.setPermissionMode(command.sessionId, command.permissionMode);
1808
- return "";
1809
- case "SlashCommand":
1810
- driver.runSlashCommand(command.sessionId, command.name, command.arguments);
1811
- return "";
1812
- case "StopTask":
1813
- await driver.stopTask(command.sessionId, command.taskId);
1814
- return "";
1815
- default: return exhaustiveGuard(command);
2353
+ //#region src/services/device/getDeviceName.ts
2354
+ const BrowserNames = [
2355
+ [/Edg\//u, "Edge"],
2356
+ [/Firefox\//u, "Firefox"],
2357
+ [/Chrome\//u, "Chrome"],
2358
+ [/Safari\//u, "Safari"]
2359
+ ];
2360
+ const SystemNames = [
2361
+ [/Windows/u, "Windows"],
2362
+ [/Android/u, "Android"],
2363
+ [/iPhone|iPad/u, "iOS"],
2364
+ [/Mac OS X/u, "macOS"],
2365
+ [/Linux/u, "Linux"]
2366
+ ];
2367
+ const getDeviceName = (userAgent) => {
2368
+ const browserName = BrowserNames.find(([pattern]) => pattern.test(userAgent))?.[1] ?? "A browser";
2369
+ const systemName = SystemNames.find(([pattern]) => pattern.test(userAgent))?.[1];
2370
+ return systemName ? `${browserName} on ${systemName}` : browserName;
2371
+ };
2372
+ //#endregion
2373
+ //#region src/services/handshake/getPublicKeyText.ts
2374
+ const getPublicKeyText = (privateKey) => createPublicKey(privateKey).export({ format: "jwk" }).x ?? "";
2375
+ //#endregion
2376
+ //#region src/services/server/answerHttpRequest.ts
2377
+ const answerHttpRequest = ({ headers, method }, response) => {
2378
+ if (method !== "OPTIONS") {
2379
+ response.writeHead(405).end();
2380
+ return;
1816
2381
  }
2382
+ response.setHeader("Access-Control-Allow-Origin", headers.origin ?? "*");
2383
+ response.setHeader("Access-Control-Allow-Private-Network", "true");
2384
+ response.setHeader("Access-Control-Allow-Methods", "GET");
2385
+ response.setHeader("Access-Control-Allow-Headers", headers["access-control-request-headers"] ?? "*");
2386
+ response.setHeader("Vary", "Origin");
2387
+ response.writeHead(204).end();
1817
2388
  };
1818
2389
  //#endregion
1819
- //#region src/services/drivers/window/serveSessionChild.ts
1820
- const serveSessionChild = async (connect, createDriver, writeLine, signal) => {
1821
- const taskRegistry = createTaskRegistry();
1822
- const sessionEventMap = /* @__PURE__ */ new Map();
1823
- let webSocket;
1824
- const send = (childMessage) => {
1825
- if (webSocket?.readyState === WebSocket.OPEN) webSocket.send(JSON.stringify(childMessage));
1826
- };
1827
- const driver = createDriver({
1828
- onEvents: (sessionId, events) => {
1829
- for (const event of events) {
1830
- const line = formatSessionLogLine(event);
1831
- if (line) writeLine(line);
1832
- }
1833
- getOrCreate(sessionEventMap, sessionId, () => []).push(...events.filter(({ type }) => !EphemeralAgentEventTypes.includes(type)));
1834
- if (events.some((event) => event.type === "SessionState" && event.state === "Closed")) sessionEventMap.delete(sessionId);
1835
- send({
1836
- events,
1837
- sessionId,
1838
- type: "Events"
1839
- });
1840
- },
1841
- onSessionOpen: (sessionId) => {
1842
- sessionEventMap.set(sessionId, []);
1843
- send({
1844
- sessionId,
1845
- type: "SessionOpen"
1846
- });
1847
- },
1848
- onSessionsChange: () => {
1849
- send({ type: "SessionsChange" });
1850
- }
1851
- });
1852
- const receive = async (text) => {
1853
- const command = getResult(() => driverCommandSchema.parse(JSON.parse(text))).orTee((error) => {
1854
- send({
1855
- commandId: "",
1856
- message: error.message,
1857
- type: "CommandError"
1858
- });
1859
- }).unwrapOr(void 0);
1860
- if (!command) return;
1861
- await getResultAsync(() => handleCommand(driver, command)).match((sessionId) => {
1862
- send({
1863
- commandId: command.id,
1864
- sessionId,
1865
- type: "CommandResult"
1866
- });
1867
- }, (error) => {
1868
- send({
1869
- commandId: command.id,
1870
- message: error.message,
1871
- type: "CommandError"
1872
- });
1873
- });
1874
- };
1875
- signal.addEventListener("abort", () => {
1876
- webSocket?.close();
1877
- });
1878
- let isRejoining = false;
1879
- while (!signal.aborted) {
1880
- const currentWebSocket = connect();
1881
- webSocket = currentWebSocket;
1882
- let isRefused = false;
1883
- currentWebSocket.on("message", (data) => {
1884
- taskRegistry.run(() => receive(readMessageText(data)));
1885
- });
1886
- currentWebSocket.on("error", noop);
1887
- currentWebSocket.on("unexpected-response", () => {
1888
- isRefused = true;
1889
- currentWebSocket.terminate();
1890
- });
1891
- if (isRejoining) currentWebSocket.once("open", () => {
1892
- writeLine("The host is back, and has this session again.");
1893
- send({
1894
- sessions: Array.from(sessionEventMap, ([sessionId, events]) => ({
1895
- events,
1896
- sessionId
1897
- })),
1898
- type: "Rejoin"
1899
- });
1900
- });
1901
- const [code] = await once(currentWebSocket, "close");
1902
- if (isRefused && isRejoining) writeLine("The host did not take this session back, so it ends here.");
1903
- if (signal.aborted || isRefused || code === 4e3 || sessionEventMap.size === 0) break;
1904
- if (!isRejoining) writeLine("The host went away. This session keeps running, and comes back when the host is started again.");
1905
- isRejoining = true;
1906
- await setTimeout$1(SESSION_WINDOW_RECONNECT_DELAY);
1907
- }
1908
- await driver.close();
1909
- await taskRegistry.drain();
1910
- };
1911
- //#endregion
1912
- //#region src/services/drivers/window/runSessionChild.ts
1913
- const runSessionChild = async (port, writeLine) => {
1914
- const secret = process.env[SESSION_SECRET_ENVIRONMENT_VARIABLE] ?? "";
1915
- Reflect.deleteProperty(process.env, SESSION_SECRET_ENVIRONMENT_VARIABLE);
1916
- process.title = `${SITE_NAME} session`;
1917
- const stateDirectory = getStateDirectory();
1918
- let isFirstConnection = true;
1919
- const connect = () => {
1920
- const hostPort = isFirstConnection ? port : readSessionWindows(stateDirectory).port;
1921
- isFirstConnection = false;
1922
- return new WebSocket(`ws://${DEFAULT_HOSTNAME}:${hostPort}`, { headers: { authorization: `Bearer ${secret}` } });
1923
- };
1924
- const abortController = new AbortController();
1925
- const stop = () => {
1926
- abortController.abort();
1927
- };
1928
- process.once("SIGINT", stop);
1929
- process.once("SIGHUP", stop);
1930
- writeLine("This window shows one session as it runs. Type to it in the page.\nTo stop it, close this window.\n");
1931
- await serveSessionChild(connect, createClaudeAgentSdkDriver, writeLine, abortController.signal);
1932
- };
1933
- //#endregion
1934
- //#region src/services/installer/checkIsHostInstalled.ts
1935
- const checkIsHostInstalled = () => relative(getHostInstallDirectory(), dirname(process.execPath)) === "";
1936
- //#endregion
1937
- //#region src/services/installer/checkIsSchemeLaunchTampered.ts
1938
- const checkIsSchemeLaunchTampered = (commandLineArguments) => commandLineArguments.length > 1 && commandLineArguments.some((commandLineArgument) => commandLineArgument.startsWith(`${HOST_SCHEME}:`));
1939
- //#endregion
1940
- //#region src/services/installer/getSchemeLaunch.ts
1941
- const getSchemeLaunch = (argument) => {
1942
- if (!URL.canParse(argument)) return void 0;
1943
- const url = new URL(argument);
1944
- if (url.protocol !== `${HOST_SCHEME}:`) return void 0;
1945
- return { code: url.searchParams.get("code") ?? "" };
1946
- };
1947
- //#endregion
1948
- //#region src/services/installer/installHost.ts
1949
- const installHost = () => {
1950
- const installDirectory = getHostInstallDirectory();
1951
- const executablePath = join(installDirectory, HOST_EXECUTABLE_FILENAME);
1952
- mkdirSync(installDirectory, { recursive: true });
1953
- copyFileSync(process.execPath, executablePath);
1954
- writeFileSync(join(installDirectory, CLAUDE_CODE_EXECUTABLE_FILENAME), new Uint8Array(getRawAsset(CLAUDE_CODE_EXECUTABLE_FILENAME)));
1955
- for (const assetKey of getAssetKeys().filter((key) => key.startsWith(`${NODE_PTY_DIRECTORY_NAME}/`))) {
1956
- const assetPath = join(installDirectory, ...assetKey.split("/"));
1957
- mkdirSync(dirname(assetPath), { recursive: true });
1958
- writeFileSync(assetPath, new Uint8Array(getRawAsset(assetKey)));
1959
- }
1960
- for (const registryArguments of [
1961
- [
1962
- HOST_SCHEME_REGISTRY_KEY,
1963
- "/ve",
1964
- "/d",
1965
- `URL:${SITE_NAME} Host`
1966
- ],
1967
- [
1968
- HOST_SCHEME_REGISTRY_KEY,
1969
- "/v",
1970
- "URL Protocol",
1971
- "/d",
1972
- ""
1973
- ],
1974
- [
1975
- win32.join(HOST_SCHEME_REGISTRY_KEY, "shell", "open", "command"),
1976
- "/ve",
1977
- "/d",
1978
- `"${executablePath}" "%1"`
1979
- ]
1980
- ]) execFileSync("reg", [
1981
- "add",
1982
- ...registryArguments,
1983
- "/f"
1984
- ], { stdio: "ignore" });
1985
- return installDirectory;
1986
- };
1987
- //#endregion
1988
- //#region src/services/installer/uninstallHost.ts
1989
- const uninstallHost = () => {
1990
- execFileSync("reg", [
1991
- "delete",
1992
- HOST_SCHEME_REGISTRY_KEY,
1993
- "/f"
1994
- ], { stdio: "ignore" });
1995
- spawn("powershell.exe", [
1996
- "-NoProfile",
1997
- "-Command",
1998
- `Start-Sleep -Seconds 2; Remove-Item -LiteralPath $env:${HOST_DIRECTORY_ENVIRONMENT_VARIABLE} -Recurse -Force`
1999
- ], {
2000
- detached: true,
2001
- env: {
2002
- ...process.env,
2003
- [HOST_DIRECTORY_ENVIRONMENT_VARIABLE]: getHostInstallDirectory()
2004
- },
2005
- stdio: "ignore",
2006
- windowsHide: true
2007
- }).unref();
2008
- };
2009
- //#endregion
2010
- //#region src/services/device/findDevice.ts
2011
- const findDevice = (devices, credential) => {
2012
- const credentialHash = hashCredential(credential);
2013
- return devices.find((device) => checkIsTokenValid(credentialHash, device.credentialHash));
2014
- };
2015
- //#endregion
2016
- //#region src/services/device/getDeviceName.ts
2017
- const BrowserNames = [
2018
- [/Edg\//u, "Edge"],
2019
- [/Firefox\//u, "Firefox"],
2020
- [/Chrome\//u, "Chrome"],
2021
- [/Safari\//u, "Safari"]
2022
- ];
2023
- const SystemNames = [
2024
- [/Windows/u, "Windows"],
2025
- [/Android/u, "Android"],
2026
- [/iPhone|iPad/u, "iOS"],
2027
- [/Mac OS X/u, "macOS"],
2028
- [/Linux/u, "Linux"]
2029
- ];
2030
- const getDeviceName = (userAgent) => {
2031
- const browserName = BrowserNames.find(([pattern]) => pattern.test(userAgent))?.[1] ?? "A browser";
2032
- const systemName = SystemNames.find(([pattern]) => pattern.test(userAgent))?.[1];
2033
- return systemName ? `${browserName} on ${systemName}` : browserName;
2034
- };
2035
- //#endregion
2036
- //#region src/services/handshake/getPublicKeyText.ts
2037
- const getPublicKeyText = (privateKey) => createPublicKey(privateKey).export({ format: "jwk" }).x ?? "";
2038
- //#endregion
2039
- //#region src/services/server/answerHttpRequest.ts
2040
- const answerHttpRequest = ({ headers, method }, response) => {
2041
- if (method !== "OPTIONS") {
2042
- response.writeHead(405).end();
2043
- return;
2044
- }
2045
- response.setHeader("Access-Control-Allow-Origin", headers.origin ?? "*");
2046
- response.setHeader("Access-Control-Allow-Private-Network", "true");
2047
- response.setHeader("Access-Control-Allow-Methods", "GET");
2048
- response.setHeader("Access-Control-Allow-Headers", headers["access-control-request-headers"] ?? "*");
2049
- response.setHeader("Vary", "Origin");
2050
- response.writeHead(204).end();
2051
- };
2052
- //#endregion
2053
- //#region src/services/server/createEventLog.ts
2054
- const createEventLog = () => {
2390
+ //#region src/services/server/createEventLog.ts
2391
+ const createEventLog = () => {
2055
2392
  const sessionEventMap = /* @__PURE__ */ new Map();
2056
2393
  return {
2057
2394
  append: (sessionId, events) => {
@@ -2103,6 +2440,48 @@ const createPairingCodes = () => {
2103
2440
  };
2104
2441
  };
2105
2442
  //#endregion
2443
+ //#region src/services/server/handleCommand.ts
2444
+ const handleCommand = async (driver, command) => {
2445
+ switch (command.type) {
2446
+ case "BackgroundTasks":
2447
+ await driver.backgroundTasks(command.sessionId);
2448
+ return "";
2449
+ case "CloseSession":
2450
+ driver.closeSession(command.sessionId);
2451
+ return "";
2452
+ case "CreateSession": return driver.createSession(command.cwd);
2453
+ case "Fork": return driver.forkSession(command.sessionId, command.messageUuid);
2454
+ case "Interrupt":
2455
+ await driver.interrupt(command.sessionId);
2456
+ return "";
2457
+ case "ListSessions": return "";
2458
+ case "PermissionVerdict":
2459
+ driver.resolvePermission(command.sessionId, command.requestId, command.behavior, command.message);
2460
+ return "";
2461
+ case "Prompt":
2462
+ driver.prompt(command.sessionId, command.text, command.attachments);
2463
+ return "";
2464
+ case "Resume": return driver.resumeSession(command.sessionId);
2465
+ case "ResumeAt": return driver.resumeAt(command.sessionId, command.messageUuid);
2466
+ case "RewindFiles":
2467
+ await driver.rewindFiles(command.sessionId, command.messageUuid);
2468
+ return "";
2469
+ case "SetModel":
2470
+ await driver.setModel(command.sessionId, command.model);
2471
+ return "";
2472
+ case "SetPermissionMode":
2473
+ await driver.setPermissionMode(command.sessionId, command.permissionMode);
2474
+ return "";
2475
+ case "SlashCommand":
2476
+ driver.runSlashCommand(command.sessionId, command.name, command.arguments);
2477
+ return "";
2478
+ case "StopTask":
2479
+ await driver.stopTask(command.sessionId, command.taskId);
2480
+ return "";
2481
+ default: return exhaustiveGuard(command);
2482
+ }
2483
+ };
2484
+ //#endregion
2106
2485
  //#region src/services/server/handleShellCommand.ts
2107
2486
  const handleShellCommand = async (shellRegistry, command) => {
2108
2487
  switch (command.type) {
@@ -2455,16 +2834,6 @@ const createAgentConsoleServer = async ({ createDriver, hostKey, hostname, origi
2455
2834
  };
2456
2835
  };
2457
2836
  //#endregion
2458
- //#region src/services/shell/constants.ts
2459
- const CONSOLE_LIST_AGENT_NAME = "conpty_console_list_agent";
2460
- //#endregion
2461
- //#region src/services/shell/runConsoleListAgent.ts
2462
- const runConsoleListAgent = (shellPid) => {
2463
- const installDirectory = getHostInstallDirectory();
2464
- const { getConsoleProcessList } = createRequire(join(installDirectory, "package.json"))(join(installDirectory, NODE_PTY_DIRECTORY_NAME, "prebuilds", "win32-x64", "conpty_console_list.node"));
2465
- process.send?.({ consoleProcessList: getConsoleProcessList(shellPid) });
2466
- };
2467
- //#endregion
2468
2837
  //#region src/services/shell/getShellFile.ts
2469
2838
  const POWERSHELL_FILE = "pwsh.exe";
2470
2839
  const WINDOWS_POWERSHELL_FILE = "powershell.exe";
@@ -2495,4 +2864,303 @@ const spawnPtyShell = async ({ cols, cwd, rows }) => {
2495
2864
  });
2496
2865
  };
2497
2866
  //#endregion
2498
- export { toContentBlockParam as $, writeStateFile as $t, readSessionWindows as A, createStreamTracker as At, childCommandErrorMessageSchema as B, closeOpenSession as Bt, handleCommand as C, mapSystemMessage as Ct, checkIsTokenValid as D, toUnknownEvent as Dt, createWindowDriver as E, mapAssistantContent as Et, childSessionsChangeMessageSchema as F, createInputQueue as Ft, SESSION_SECRET_ENVIRONMENT_VARIABLE as G, readMessageText as Gt, childMessageTypeSchema as H, getEventId as Ht, childSessionOpenMessageSchema as I, DEFAULT_DENY_MESSAGE as It, SESSION_WINDOW_CONNECT_TIMEOUT as J, checkIsSignatureValid as Jt, SESSION_SUBCOMMAND as K, HOST_PROBE_TIMEOUT_MS as Kt, childRejoinMessageSchema as L, IGNORED_SDK_MESSAGE_TYPES as Lt, hashCredential as M, createPermissionBridge as Mt, SessionWindowCloseCode as N, toPermissionResult as Nt, takeChildReply as O, createTodoTracker as Ot, childMessageSchema as P, toPermissionRequestEvent as Pt, createTaskRegistry as Q, readHostKey as Qt, childEventsMessageSchema as R, SESSION_LIST_LIMIT as Rt, serveSessionChild as S, toToolResultText as St, launchSessionWindow as T, mapHookMessage as Tt, createBaseChildMessageSchema as U, runDevicesCommand as Ut, ChildMessageType as V, toSessionClosedEvents as Vt, SESSION_SECRET_BYTE_LENGTH as W, sendToRunningHost as Wt, SESSION_WINDOW_REJOIN_DURATION as X, readDevices as Xt, SESSION_WINDOW_RECONNECT_DELAY as Y, writeDevices as Yt, createClaudeAgentSdkDriver as Z, deviceSchema as Zt, installHost as _, createSdkMessageMapper as _t, CONSOLE_LIST_AGENT_NAME as a, STATE_DIRECTORY_NAME as an, CLAUDE_CODE_EXECUTABLE_FILENAME as at, checkIsHostInstalled as b, parseMessageBody as bt, sendServerMessage as c, HOST_INSTALL_DIRECTORY_SEGMENTS as ct, createEventLog as d, watchSession as dt, getStateDirectory as en, readSessionCwd as et, answerHttpRequest as f, toContextUsageEvent as ft, uninstallHost as g, readSessionHistory as gt, findDevice as h, readToolUseResultMap as ht, runConsoleListAgent as i, SECRET_BYTE_LENGTH as in, getHostInstallDirectory as it, sessionWindowsSchema as j, createFileOriginTracker as jt, sendChildCommand as k, TodoToolName as kt, handleShellCommand as l, HOST_SCHEME_REGISTRY_KEY as lt, getDeviceName as m, getSessionTitle as mt, loadNodePty as n, HOST_KEY_FILENAME as nn, createSessionOpener as nt, createAgentConsoleServer as o, HOST_DIRECTORY_ENVIRONMENT_VARIABLE as ot, getPublicKeyText as p, toCapabilitiesEvent as pt, SESSION_WINDOWS_FILENAME as q, signNonce as qt, getShellFile as r, PRINTED_PAIRING_CODE_DURATION as rn, getClaudeCodeExecutablePath as rt, createShellRegistry as s, HOST_EXECUTABLE_FILENAME as st, spawnPtyShell as t, DEVICES_FILENAME as tn, listSessionSummaries as tt, createPairingCodes as u, NODE_PTY_DIRECTORY_NAME as ut, getSchemeLaunch as v, toTurnResultEvents as vt, formatSessionLogLine as w, mapTaskMessage as wt, runSessionChild as x, mapUserContent as xt, checkIsSchemeLaunchTampered as y, toSessionInitEvent as yt, childCommandResultMessageSchema as z, SETTING_SOURCES as zt };
2867
+ //#region src/services/cli/serveHost.ts
2868
+ const serveHost = async ({ hostname, origin, port, schemeLaunch }) => {
2869
+ installDownloadedHost();
2870
+ const stateDirectory = getStateDirectory();
2871
+ const hostKey = readHostKey(stateDirectory);
2872
+ const reachableHostname = getReachableHostname(hostname);
2873
+ const server = await getResultAsync(() => createAgentConsoleServer({
2874
+ createDriver: (callbacks) => process.platform === "win32" && hostname === "127.0.0.1" ? createWindowDriver(callbacks, {
2875
+ launchSessionWindow,
2876
+ stateDirectory,
2877
+ writeLine
2878
+ }) : createClaudeAgentSdkDriver(callbacks),
2879
+ hostKey,
2880
+ hostname,
2881
+ origin,
2882
+ port,
2883
+ spawnShell: spawnPtyShell,
2884
+ stateDirectory,
2885
+ writeLine
2886
+ })).match((agentConsoleServer) => agentConsoleServer, async (error) => {
2887
+ if (!schemeLaunch || !("code" in error) || error.code !== "EADDRINUSE") throw error;
2888
+ const { code } = schemeLaunch;
2889
+ if (await sendToRunningHost(reachableHostname, port, hostKey, code ? (signature) => ({
2890
+ code,
2891
+ signature,
2892
+ type: "HandOff"
2893
+ }) : void 0)) {
2894
+ process.stdout.write("The host is already running in another window.\n");
2895
+ process.exit(0);
2896
+ }
2897
+ process.stderr.write(`Another program is using port ${port}, so the host cannot start. Close it and connect again.\n`);
2898
+ process.exit(1);
2899
+ });
2900
+ if (schemeLaunch) {
2901
+ if (schemeLaunch.code) server.addPairingCode(schemeLaunch.code, SCHEME_PAIRING_CODE_DURATION);
2902
+ process.stdout.write("The host is running. Keep this window open.\n\nTo stop, close this window.\n");
2903
+ } else {
2904
+ const code = randomBytes(32).toString("base64url");
2905
+ server.addPairingCode(code, PRINTED_PAIRING_CODE_DURATION);
2906
+ const hostAddress = `ws://${reachableHostname}:${server.port}`;
2907
+ const pairingUrl = `${origin}${RoutePath.Genshin}#${new URLSearchParams({
2908
+ [PAIRING_CODE_PARAMETER]: code,
2909
+ [PAIRING_HASH_PARAMETER]: hostAddress
2910
+ })}`;
2911
+ process.stdout.write(`The host is running. Keep this window open.\n\nTo connect, press Connect on the page, or hold Ctrl and click this link in the next ten minutes:\n ${pairingUrl}\n\nTo add this machine from another computer, enter its address and this code in the page's sessions tab:\n ${code}\n\nTo stop, close this window.\n`);
2912
+ }
2913
+ await Promise.race([once(process, "SIGINT"), once(process, "SIGHUP")]);
2914
+ await server.close();
2915
+ };
2916
+ //#endregion
2917
+ //#region src/services/cli/commands/serveCommand.ts
2918
+ const serveCommand = defineCommand({
2919
+ args: { ...hostArgs },
2920
+ meta: {
2921
+ description: "Start the host and print the link that pairs a page with it",
2922
+ name: "serve"
2923
+ },
2924
+ run: ({ args }) => serveHost({
2925
+ hostname: args.hostname,
2926
+ origin: args.origin,
2927
+ port: Number(args.port)
2928
+ })
2929
+ });
2930
+ //#endregion
2931
+ //#region src/services/drivers/window/formatSessionLogLine.ts
2932
+ const formatSessionLogLine = (event) => {
2933
+ switch (event.type) {
2934
+ case "AssistantMessage": return event.parentToolUseId ? "" : `Claude: ${event.text}`;
2935
+ case "HostError": return `Error: ${event.message}`;
2936
+ case "PermissionRequest": return `Claude asks to use ${event.toolName}. Answer in the page.`;
2937
+ case "ToolUse": return event.parentToolUseId ? "" : `Claude uses ${event.name}`;
2938
+ case "UserMessage": return event.parentToolUseId ? "" : `You: ${event.text}`;
2939
+ default: return "";
2940
+ }
2941
+ };
2942
+ //#endregion
2943
+ //#region src/services/drivers/window/serveSessionChild.ts
2944
+ const serveSessionChild = async (connect, createDriver, writeLine, signal) => {
2945
+ const taskRegistry = createTaskRegistry();
2946
+ const sessionEventMap = /* @__PURE__ */ new Map();
2947
+ let webSocket;
2948
+ const send = (childMessage) => {
2949
+ if (webSocket?.readyState === WebSocket.OPEN) webSocket.send(JSON.stringify(childMessage));
2950
+ };
2951
+ const driver = createDriver({
2952
+ onEvents: (sessionId, events) => {
2953
+ for (const event of events) {
2954
+ const line = formatSessionLogLine(event);
2955
+ if (line) writeLine(line);
2956
+ }
2957
+ getOrCreate(sessionEventMap, sessionId, () => []).push(...events.filter(({ type }) => !EphemeralAgentEventTypes.includes(type)));
2958
+ if (events.some((event) => event.type === "SessionState" && event.state === "Closed")) sessionEventMap.delete(sessionId);
2959
+ send({
2960
+ events,
2961
+ sessionId,
2962
+ type: "Events"
2963
+ });
2964
+ },
2965
+ onSessionOpen: (sessionId) => {
2966
+ sessionEventMap.set(sessionId, []);
2967
+ send({
2968
+ sessionId,
2969
+ type: "SessionOpen"
2970
+ });
2971
+ },
2972
+ onSessionsChange: () => {
2973
+ send({ type: "SessionsChange" });
2974
+ }
2975
+ });
2976
+ const receive = async (text) => {
2977
+ const command = getResult(() => driverCommandSchema.parse(JSON.parse(text))).orTee((error) => {
2978
+ send({
2979
+ commandId: "",
2980
+ message: error.message,
2981
+ type: "CommandError"
2982
+ });
2983
+ }).unwrapOr(void 0);
2984
+ if (!command) return;
2985
+ await getResultAsync(() => handleCommand(driver, command)).match((sessionId) => {
2986
+ send({
2987
+ commandId: command.id,
2988
+ sessionId,
2989
+ type: "CommandResult"
2990
+ });
2991
+ }, (error) => {
2992
+ send({
2993
+ commandId: command.id,
2994
+ message: error.message,
2995
+ type: "CommandError"
2996
+ });
2997
+ });
2998
+ };
2999
+ signal.addEventListener("abort", () => {
3000
+ webSocket?.close();
3001
+ });
3002
+ let isRejoining = false;
3003
+ while (!signal.aborted) {
3004
+ const currentWebSocket = connect();
3005
+ webSocket = currentWebSocket;
3006
+ let isRefused = false;
3007
+ currentWebSocket.on("message", (data) => {
3008
+ taskRegistry.run(() => receive(readMessageText(data)));
3009
+ });
3010
+ currentWebSocket.on("error", noop);
3011
+ currentWebSocket.on("unexpected-response", () => {
3012
+ isRefused = true;
3013
+ currentWebSocket.terminate();
3014
+ });
3015
+ if (isRejoining) currentWebSocket.once("open", () => {
3016
+ writeLine("The host is back, and has this session again.");
3017
+ send({
3018
+ sessions: Array.from(sessionEventMap, ([sessionId, events]) => ({
3019
+ events,
3020
+ sessionId
3021
+ })),
3022
+ type: "Rejoin"
3023
+ });
3024
+ });
3025
+ const [code] = await once(currentWebSocket, "close");
3026
+ if (isRefused && isRejoining) writeLine("The host did not take this session back, so it ends here.");
3027
+ if (signal.aborted || isRefused || code === 4e3 || sessionEventMap.size === 0) break;
3028
+ if (!isRejoining) writeLine("The host went away. This session keeps running, and comes back when the host is started again.");
3029
+ isRejoining = true;
3030
+ await setTimeout$1(SESSION_WINDOW_RECONNECT_DELAY);
3031
+ }
3032
+ await driver.close();
3033
+ await taskRegistry.drain();
3034
+ };
3035
+ //#endregion
3036
+ //#region src/services/drivers/window/runSessionChild.ts
3037
+ const runSessionChild = async (port, writeLine) => {
3038
+ const secret = process.env[SESSION_SECRET_ENVIRONMENT_VARIABLE] ?? "";
3039
+ Reflect.deleteProperty(process.env, SESSION_SECRET_ENVIRONMENT_VARIABLE);
3040
+ process.title = `${SITE_NAME} session`;
3041
+ const stateDirectory = getStateDirectory();
3042
+ let isFirstConnection = true;
3043
+ const connect = () => {
3044
+ const hostPort = isFirstConnection ? port : readSessionWindows(stateDirectory).port;
3045
+ isFirstConnection = false;
3046
+ return new WebSocket(`ws://${DEFAULT_HOSTNAME}:${hostPort}`, { headers: { authorization: `Bearer ${secret}` } });
3047
+ };
3048
+ const abortController = new AbortController();
3049
+ const stop = () => {
3050
+ abortController.abort();
3051
+ };
3052
+ process.once("SIGINT", stop);
3053
+ process.once("SIGHUP", stop);
3054
+ writeLine("This window shows one session as it runs. Type to it in the page.\nTo stop it, close this window.\n");
3055
+ await serveSessionChild(connect, createClaudeAgentSdkDriver, writeLine, abortController.signal);
3056
+ };
3057
+ //#endregion
3058
+ //#region src/services/cli/commands/sessionCommand.ts
3059
+ const sessionCommand = defineCommand({
3060
+ args: { port: {
3061
+ description: "The port of the host that started this window",
3062
+ required: true,
3063
+ type: "string"
3064
+ } },
3065
+ meta: {
3066
+ description: "Serve one session in a window of its own, for the host that started it",
3067
+ name: SESSION_SUBCOMMAND
3068
+ },
3069
+ run: async ({ args }) => {
3070
+ await runSessionChild(Number(args.port), writeLine);
3071
+ process.exit(0);
3072
+ }
3073
+ });
3074
+ //#endregion
3075
+ //#region src/services/installer/uninstallHost.ts
3076
+ const uninstallHost = () => {
3077
+ execFileSync("reg", [
3078
+ "delete",
3079
+ HOST_SCHEME_REGISTRY_KEY,
3080
+ "/f"
3081
+ ], { stdio: "ignore" });
3082
+ spawn("powershell.exe", [
3083
+ "-NoProfile",
3084
+ "-Command",
3085
+ `Start-Sleep -Seconds 2; Remove-Item -LiteralPath $env:${HOST_DIRECTORY_ENVIRONMENT_VARIABLE} -Recurse -Force`
3086
+ ], {
3087
+ detached: true,
3088
+ env: {
3089
+ ...process.env,
3090
+ [HOST_DIRECTORY_ENVIRONMENT_VARIABLE]: getHostInstallDirectory()
3091
+ },
3092
+ stdio: "ignore",
3093
+ windowsHide: true
3094
+ }).unref();
3095
+ };
3096
+ //#endregion
3097
+ //#region src/services/cli/commands/uninstallCommand.ts
3098
+ const uninstallCommand = defineCommand({
3099
+ meta: {
3100
+ description: "Remove the installed host, its link and its folder",
3101
+ name: "uninstall"
3102
+ },
3103
+ run: () => {
3104
+ uninstallHost();
3105
+ process.stdout.write("The host is uninstalled, and its folder is removed once this window closes.\n");
3106
+ process.exit(0);
3107
+ }
3108
+ });
3109
+ //#endregion
3110
+ //#region src/services/installer/checkIsSchemeLaunchTampered.ts
3111
+ const checkIsSchemeLaunchTampered = (commandLineArguments) => commandLineArguments.length > 1 && commandLineArguments.some((commandLineArgument) => commandLineArgument.startsWith(`${HOST_SCHEME}:`));
3112
+ //#endregion
3113
+ //#region src/services/installer/getSchemeLaunch.ts
3114
+ const getSchemeLaunch = (argument) => {
3115
+ if (!URL.canParse(argument)) return void 0;
3116
+ const url = new URL(argument);
3117
+ if (url.protocol !== `${HOST_SCHEME}:`) return void 0;
3118
+ return { code: url.searchParams.get("code") ?? "" };
3119
+ };
3120
+ //#endregion
3121
+ //#region src/services/shell/constants.ts
3122
+ const CONSOLE_LIST_AGENT_NAME = "conpty_console_list_agent";
3123
+ //#endregion
3124
+ //#region src/services/shell/runConsoleListAgent.ts
3125
+ const runConsoleListAgent = (shellPid) => {
3126
+ const installDirectory = getHostInstallDirectory();
3127
+ const { getConsoleProcessList } = createRequire(join(installDirectory, "package.json"))(join(installDirectory, NODE_PTY_DIRECTORY_NAME, "prebuilds", "win32-x64", "conpty_console_list.node"));
3128
+ process.send?.({ consoleProcessList: getConsoleProcessList(shellPid) });
3129
+ };
3130
+ //#endregion
3131
+ //#region src/services/cli/commands/agentConsoleServerCommand.ts
3132
+ const agentConsoleServerCommand = defineCommand({
3133
+ default: "serve",
3134
+ meta: {
3135
+ description: "The agent console's host: Claude Code sessions for a paired page",
3136
+ name: "agent-console-server"
3137
+ },
3138
+ setup: async ({ rawArgs }) => {
3139
+ if (checkIsSchemeLaunchTampered(rawArgs)) {
3140
+ process.stderr.write("This link tried to start the host with settings of its own, so it was not started.\n");
3141
+ process.exit(1);
3142
+ }
3143
+ const [firstArgument = "", secondArgument = ""] = rawArgs;
3144
+ if (basename(firstArgument) === "conpty_console_list_agent") {
3145
+ runConsoleListAgent(Number(secondArgument));
3146
+ process.exit(0);
3147
+ }
3148
+ const schemeLaunch = getSchemeLaunch(firstArgument);
3149
+ if (!schemeLaunch) return;
3150
+ await serveHost({
3151
+ hostname: DEFAULT_HOSTNAME,
3152
+ origin: DEFAULT_APP_ORIGIN,
3153
+ port: DEFAULT_PORT,
3154
+ schemeLaunch
3155
+ });
3156
+ process.exit(0);
3157
+ },
3158
+ subCommands: {
3159
+ devices: devicesCommand,
3160
+ serve: serveCommand,
3161
+ [SESSION_SUBCOMMAND]: sessionCommand,
3162
+ uninstall: uninstallCommand
3163
+ }
3164
+ });
3165
+ //#endregion
3166
+ export { createBaseChildMessageSchema as $, DEVICES_FILENAME as $t, checkIsTokenValid as A, toPermissionRequestEvent as At, SESSION_WINDOW_RECONNECT_DELAY as B, runMain as Bt, createEventLog as C, toUnknownEvent as Ct, findDevice as D, createFileOriginTracker as Dt, getDeviceName as E, createStreamTracker as Et, SESSION_SECRET_BYTE_LENGTH as F, SETTING_SOURCES as Ft, childSessionsChangeMessageSchema as G, signNonce as Gt, hashCredential as H, sendToRunningHost as Ht, SESSION_SECRET_ENVIRONMENT_VARIABLE as I, closeOpenSession as It, childEventsMessageSchema as J, readDevices as Jt, childSessionOpenMessageSchema as K, checkIsSignatureValid as Kt, SESSION_SUBCOMMAND as L, toSessionClosedEvents as Lt, sendChildCommand as M, DEFAULT_DENY_MESSAGE as Mt, readSessionWindows as N, IGNORED_SDK_MESSAGE_TYPES as Nt, launchSessionWindow as O, createPermissionBridge as Ot, sessionWindowsSchema as P, SESSION_LIST_LIMIT as Pt, childMessageTypeSchema as Q, getStateDirectory as Qt, SESSION_WINDOWS_FILENAME as R, getEventId as Rt, createPairingCodes as S, mapAssistantContent as St, getPublicKeyText as T, TodoToolName as Tt, SessionWindowCloseCode as U, readMessageText as Ut, SESSION_WINDOW_REJOIN_DURATION as V, runDevicesCommand as Vt, childMessageSchema as W, HOST_PROBE_TIMEOUT_MS as Wt, childCommandErrorMessageSchema as X, readHostKey as Xt, childCommandResultMessageSchema as Y, deviceSchema as Yt, ChildMessageType as Z, writeStateFile as Zt, createAgentConsoleServer as _, mapUserContent as _t, checkIsSchemeLaunchTampered as a, installDownloadedHost as an, createSessionOpener as at, handleShellCommand as b, mapTaskMessage as bt, sessionCommand as c, getHostInstallDirectory as cn, toContextUsageEvent as ct, formatSessionLogLine as d, HOST_EXECUTABLE_FILENAME as dn, readToolUseResultMap as dt, HOST_KEY_FILENAME as en, createClaudeAgentSdkDriver as et, serveCommand as f, HOST_INSTALL_DIRECTORY_SEGMENTS as fn, readSessionHistory as ft, getShellFile as g, getReachableHostname as gn, parseMessageBody as gt, loadNodePty as h, hostArgs as hn, toSessionInitEvent as ht, getSchemeLaunch as i, writeLine as in, listSessionSummaries as it, takeChildReply as j, createInputQueue as jt, createWindowDriver as k, toPermissionResult as kt, runSessionChild as l, CLAUDE_CODE_EXECUTABLE_FILENAME as ln, toCapabilitiesEvent as lt, spawnPtyShell as m, NODE_PTY_DIRECTORY_NAME as mn, toTurnResultEvents as mt, runConsoleListAgent as n, SECRET_BYTE_LENGTH as nn, toContentBlockParam as nt, uninstallCommand as o, installHost as on, getClaudeCodeExecutablePath as ot, serveHost as p, HOST_SCHEME_REGISTRY_KEY as pn, createSdkMessageMapper as pt, childRejoinMessageSchema as q, writeDevices as qt, CONSOLE_LIST_AGENT_NAME as r, STATE_DIRECTORY_NAME as rn, readSessionCwd as rt, uninstallHost as s, checkIsHostInstalled as sn, watchSession as st, agentConsoleServerCommand as t, PRINTED_PAIRING_CODE_DURATION as tn, createTaskRegistry as tt, serveSessionChild as u, HOST_DIRECTORY_ENVIRONMENT_VARIABLE as un, getSessionTitle as ut, createShellRegistry as v, toToolResultText as vt, answerHttpRequest as w, createTodoTracker as wt, handleCommand as x, mapHookMessage as xt, sendServerMessage as y, mapSystemMessage as yt, SESSION_WINDOW_CONNECT_TIMEOUT as z, devicesCommand as zt };