linkshell-cli 0.10.7 → 0.10.9

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.
Files changed (89) hide show
  1. package/dist/cli/tsconfig.tsbuildinfo +1 -1
  2. package/dist/gateway/src/main.js +4 -0
  3. package/dist/gateway/src/main.js.map +1 -1
  4. package/dist/gateway/src/serve.d.ts +3 -1
  5. package/dist/gateway/src/serve.js +5 -1
  6. package/dist/gateway/src/serve.js.map +1 -1
  7. package/dist/gateway/src/web.d.ts +12 -0
  8. package/dist/gateway/src/web.js +53 -0
  9. package/dist/gateway/src/web.js.map +1 -0
  10. package/dist/host/src/computer-preview-capture.d.ts +11 -0
  11. package/dist/host/src/computer-preview-capture.js +87 -0
  12. package/dist/host/src/computer-preview-capture.js.map +1 -0
  13. package/dist/host/src/computer-preview.d.ts +73 -0
  14. package/dist/host/src/computer-preview.js +335 -0
  15. package/dist/host/src/computer-preview.js.map +1 -0
  16. package/dist/host/src/drivers/acp/connection.d.ts +2 -0
  17. package/dist/host/src/drivers/acp/connection.js +14 -1
  18. package/dist/host/src/drivers/acp/connection.js.map +1 -1
  19. package/dist/host/src/drivers/acp/driver.d.ts +4 -0
  20. package/dist/host/src/drivers/acp/driver.js +45 -1
  21. package/dist/host/src/drivers/acp/driver.js.map +1 -1
  22. package/dist/host/src/drivers/acp/mapper.js +11 -1
  23. package/dist/host/src/drivers/acp/mapper.js.map +1 -1
  24. package/dist/host/src/drivers/claude/activity.d.ts +1 -0
  25. package/dist/host/src/drivers/claude/activity.js +1 -0
  26. package/dist/host/src/drivers/claude/activity.js.map +1 -1
  27. package/dist/host/src/drivers/claude/driver.d.ts +6 -0
  28. package/dist/host/src/drivers/claude/driver.js +30 -2
  29. package/dist/host/src/drivers/claude/driver.js.map +1 -1
  30. package/dist/host/src/drivers/claude/tasks.d.ts +33 -0
  31. package/dist/host/src/drivers/claude/tasks.js +138 -0
  32. package/dist/host/src/drivers/claude/tasks.js.map +1 -0
  33. package/dist/host/src/drivers/claude/transcript.d.ts +31 -3
  34. package/dist/host/src/drivers/claude/transcript.js +20 -1
  35. package/dist/host/src/drivers/claude/transcript.js.map +1 -1
  36. package/dist/host/src/drivers/codex/app-server.js +0 -3
  37. package/dist/host/src/drivers/codex/app-server.js.map +1 -1
  38. package/dist/host/src/drivers/codex/commands.js +7 -1
  39. package/dist/host/src/drivers/codex/commands.js.map +1 -1
  40. package/dist/host/src/drivers/codex/computer-preview.d.ts +3 -0
  41. package/dist/host/src/drivers/codex/computer-preview.js +44 -0
  42. package/dist/host/src/drivers/codex/computer-preview.js.map +1 -0
  43. package/dist/host/src/drivers/codex/driver.d.ts +16 -1
  44. package/dist/host/src/drivers/codex/driver.js +262 -6
  45. package/dist/host/src/drivers/codex/driver.js.map +1 -1
  46. package/dist/host/src/drivers/codex/mapper.js +38 -3
  47. package/dist/host/src/drivers/codex/mapper.js.map +1 -1
  48. package/dist/host/src/drivers/registry.js +1 -1
  49. package/dist/host/src/drivers/registry.js.map +1 -1
  50. package/dist/host/src/drivers/types.d.ts +23 -1
  51. package/dist/host/src/hub.d.ts +18 -1
  52. package/dist/host/src/hub.js +102 -1
  53. package/dist/host/src/hub.js.map +1 -1
  54. package/dist/host/src/input.d.ts +9 -0
  55. package/dist/host/src/input.js +15 -0
  56. package/dist/host/src/input.js.map +1 -1
  57. package/dist/host/src/rpc/server.d.ts +1 -0
  58. package/dist/host/src/rpc/server.js +20 -2
  59. package/dist/host/src/rpc/server.js.map +1 -1
  60. package/dist/host/src/screen-viewer.js +641 -109
  61. package/dist/host/src/screen-viewer.js.map +1 -1
  62. package/dist/host/src/store.d.ts +10 -0
  63. package/dist/host/src/store.js +29 -0
  64. package/dist/host/src/store.js.map +1 -1
  65. package/dist/host/src/task-output.d.ts +6 -0
  66. package/dist/host/src/task-output.js +22 -0
  67. package/dist/host/src/task-output.js.map +1 -0
  68. package/dist/host/src/terminals.d.ts +37 -2
  69. package/dist/host/src/terminals.js +54 -14
  70. package/dist/host/src/terminals.js.map +1 -1
  71. package/dist/wire/src/computer-preview.d.ts +35 -0
  72. package/dist/wire/src/computer-preview.js +51 -0
  73. package/dist/wire/src/computer-preview.js.map +1 -0
  74. package/dist/wire/src/goal.d.ts +66 -0
  75. package/dist/wire/src/goal.js +19 -0
  76. package/dist/wire/src/goal.js.map +1 -0
  77. package/dist/wire/src/index.d.ts +2 -0
  78. package/dist/wire/src/index.js +2 -0
  79. package/dist/wire/src/index.js.map +1 -1
  80. package/dist/wire/src/model.d.ts +78 -0
  81. package/dist/wire/src/model.js +31 -0
  82. package/dist/wire/src/model.js.map +1 -1
  83. package/dist/wire/src/rpc.d.ts +1289 -60
  84. package/dist/wire/src/rpc.js +53 -3
  85. package/dist/wire/src/rpc.js.map +1 -1
  86. package/dist/wire/src/updates.d.ts +334 -22
  87. package/dist/wire/src/updates.js +11 -1
  88. package/dist/wire/src/updates.js.map +1 -1
  89. package/package.json +5 -5
@@ -27,6 +27,10 @@ const gateway = await startGateway({
27
27
  port,
28
28
  databasePath,
29
29
  version,
30
+ web: {
31
+ account: supabase.url && supabase.anonKey ? { url: supabase.url, anonKey: supabase.anonKey } : undefined,
32
+ previewOrigin: process.env.WEB_PREVIEW_ORIGIN,
33
+ },
30
34
  log: (message) => log("info", `[relay] ${message}`),
31
35
  verifyToken: supabase.url && supabase.anonKey ? supabaseVerifier(supabase.url, supabase.anonKey) : undefined,
32
36
  admit: process.env.AUTH_REQUIRED === "true"
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../gateway/src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../gateway/src/main.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
+ import { type WebOptions } from "./web.js";
1
2
  import type { VerifyToken } from "./accounts.js";
2
3
  import { Gateway, type GatewayOptions } from "./relay.js";
3
4
  export interface StartGatewayOptions {
4
5
  port: number;
6
+ web?: WebOptions;
5
7
  /** The interface to listen on; all of them when omitted. */
6
8
  host?: string;
7
9
  /** SQLite file holding pairings and peers' public keys. Losing it unpairs every phone. */
@@ -27,7 +29,7 @@ export interface RunningGateway {
27
29
  }
28
30
  /**
29
31
  * The gateway as it is deployed: one HTTP server with the relay on
30
- * `RELAY_PATH` and a health check on `/healthz`. Nothing else is served.
32
+ * `RELAY_PATH`, a health check on `/healthz`, and the bundled browser client.
31
33
  */
32
34
  export declare function startGateway(options: StartGatewayOptions): Promise<RunningGateway>;
33
35
  /** This package's version, so `/healthz` says which build is deployed. */
@@ -3,11 +3,12 @@ import { createServer } from "node:http";
3
3
  import { createRequire } from "node:module";
4
4
  import { dirname } from "node:path";
5
5
  import { RELAY_PATH } from "@linkshell/wire";
6
+ import { webHandler } from "./web.js";
6
7
  import { clientIp, isLoopback, normalizeIp, RateLimiter, trustedProxySet } from "./rate-limit.js";
7
8
  import { Gateway } from "./relay.js";
8
9
  /**
9
10
  * The gateway as it is deployed: one HTTP server with the relay on
10
- * `RELAY_PATH` and a health check on `/healthz`. Nothing else is served.
11
+ * `RELAY_PATH`, a health check on `/healthz`, and the bundled browser client.
11
12
  */
12
13
  export async function startGateway(options) {
13
14
  mkdirSync(dirname(options.databasePath), { recursive: true });
@@ -35,12 +36,15 @@ export async function startGateway(options) {
35
36
  untrustedProxies.add(peer);
36
37
  options.log?.(`a connection from ${peer} carries X-Forwarded-For, which is ignored: if ${peer} is your reverse proxy, add it to TRUSTED_PROXIES so each user gets their own connection limit`);
37
38
  };
39
+ const serveWeb = webHandler(options.web);
38
40
  const server = createServer((request, response) => {
39
41
  if (request.method === "GET" && pathOf(request) === "/healthz") {
40
42
  // memoryMb: what the process holds, to watch against the container's limit.
41
43
  json(response, 200, { ok: true, version, relay: relay.connected, memoryMb: Math.round(process.memoryUsage.rss() / 1048576) });
42
44
  return;
43
45
  }
46
+ if (serveWeb(request, response, pathOf(request)))
47
+ return;
44
48
  json(response, 404, { error: "not_found" });
45
49
  });
46
50
  server.on("upgrade", (request, socket, head) => {
@@ -1 +1 @@
1
- {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../../gateway/src/serve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../../gateway/src/serve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ export interface WebOptions {
3
+ /** Override bundled assets for development, or disable the web client. */
4
+ directory?: string | false;
5
+ /** Only public account configuration belongs in the browser. */
6
+ account?: {
7
+ url: string;
8
+ anonKey: string;
9
+ };
10
+ previewOrigin?: string;
11
+ }
12
+ export declare function webHandler(options?: WebOptions): (request: IncomingMessage, response: ServerResponse, path: string | undefined) => boolean;
@@ -0,0 +1,53 @@
1
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
2
+ import { extname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const types = {
5
+ ".html": "text/html; charset=utf-8", ".js": "text/javascript; charset=utf-8",
6
+ ".css": "text/css; charset=utf-8", ".svg": "image/svg+xml", ".png": "image/png",
7
+ ".ico": "image/x-icon", ".woff2": "font/woff2", ".json": "application/json",
8
+ };
9
+ export function webHandler(options = {}) {
10
+ const directory = options.directory === false ? undefined : options.directory ??
11
+ ["../web-client", "../../../web-client"].map((path) => fileURLToPath(new URL(path, import.meta.url)))
12
+ .find((path) => existsSync(join(path, "index.html")));
13
+ // Assets are immutable for this process; an allowlist also keeps URL paths away from the filesystem.
14
+ const assets = new Map();
15
+ function load(path, prefix = "") {
16
+ for (const item of readdirSync(path, { withFileTypes: true })) {
17
+ if (item.isDirectory())
18
+ load(join(path, item.name), `${prefix}/${item.name}`);
19
+ else if (item.isFile())
20
+ assets.set(`${prefix}/${item.name}`, readFileSync(join(path, item.name)));
21
+ }
22
+ }
23
+ if (directory)
24
+ load(directory);
25
+ return (request, response, path) => {
26
+ if (!assets.has("/index.html") || !path || !["GET", "HEAD"].includes(request.method ?? ""))
27
+ return false;
28
+ let body;
29
+ if (path === "/config.js") {
30
+ const config = {
31
+ deployment: options.account ? "official" : "self-hosted",
32
+ ...(options.account ? { account: { url: options.account.url, anonKey: options.account.anonKey } } : {}),
33
+ ...(options.previewOrigin ? { previewOrigin: options.previewOrigin } : {}),
34
+ };
35
+ body = `window.__LINKSHELL_CONFIG__ = ${JSON.stringify(config).replaceAll("<", "\\u003c")};\n`;
36
+ }
37
+ else {
38
+ body = assets.get(path === "/" ? "/index.html" : path);
39
+ }
40
+ if (body === undefined)
41
+ return false;
42
+ response.writeHead(200, {
43
+ "content-type": types[extname(path === "/" ? "/index.html" : path)] ?? "application/octet-stream",
44
+ "content-length": Buffer.byteLength(body),
45
+ "cache-control": path.startsWith("/assets/") ? "public, max-age=31536000, immutable" : "no-store",
46
+ "x-content-type-options": "nosniff",
47
+ "referrer-policy": "no-referrer",
48
+ });
49
+ response.end(request.method === "HEAD" ? undefined : body);
50
+ return true;
51
+ };
52
+ }
53
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../../../gateway/src/web.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { PreviewCaptureTarget } from "./computer-preview.js";
2
+ /** The helper instance belongs exclusively to previews, never to screen sharing or input. */
3
+ export declare class MacPreviewCapture {
4
+ private readonly log;
5
+ private app?;
6
+ private opening?;
7
+ private users;
8
+ constructor(log: (message: string) => void);
9
+ private getApp;
10
+ capture(target: PreviewCaptureTarget, frame: (dataUrl: string) => void, failed?: () => void): Promise<() => void>;
11
+ }
@@ -0,0 +1,87 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { previewApp } from "./input.js";
3
+ /** The helper instance belongs exclusively to previews, never to screen sharing or input. */
4
+ export class MacPreviewCapture {
5
+ log;
6
+ app;
7
+ opening;
8
+ users = 0;
9
+ constructor(log) {
10
+ this.log = log;
11
+ }
12
+ getApp() {
13
+ return this.opening ??= (async () => {
14
+ const app = previewApp(this.log);
15
+ if (!app)
16
+ throw new Error("当前电脑没有窗口采集组件");
17
+ this.app = app;
18
+ let timer;
19
+ try {
20
+ const status = await Promise.race([app.access(), new Promise((_, reject) => { timer = setTimeout(() => reject(new Error("窗口采集组件启动超时")), 8000); })]);
21
+ if (!status.recording)
22
+ throw new Error("电脑未允许 LinkShell 录制屏幕");
23
+ if (!status.preview)
24
+ throw new Error("请更新电脑端窗口采集组件");
25
+ return app;
26
+ }
27
+ catch (error) {
28
+ app.close();
29
+ this.app = undefined;
30
+ this.opening = undefined;
31
+ throw error;
32
+ }
33
+ finally {
34
+ if (timer)
35
+ clearTimeout(timer);
36
+ }
37
+ })();
38
+ }
39
+ async capture(target, frame, failed = () => { }) {
40
+ if (this.users >= 4)
41
+ throw new Error("同时观看的窗口预览已达上限");
42
+ this.users++;
43
+ let released = false;
44
+ const release = () => {
45
+ if (released)
46
+ return;
47
+ released = true;
48
+ this.users--;
49
+ if (!this.users) {
50
+ this.app?.close();
51
+ this.app = undefined;
52
+ this.opening = undefined;
53
+ }
54
+ };
55
+ try {
56
+ const app = await this.getApp();
57
+ const id = randomBytes(12).toString("hex");
58
+ let last = "", problem = "";
59
+ await app.preview(id, target, message => {
60
+ if (released)
61
+ return;
62
+ if (message.t === "preview.frame" && typeof message.data === "string" && message.data.length <= 256 * 1024) {
63
+ const hash = createHash("sha256").update(message.data).digest("hex");
64
+ if (last === hash)
65
+ return;
66
+ last = hash;
67
+ frame(`data:image/jpeg;base64,${message.data}`);
68
+ }
69
+ else if (message.t === "preview.paused" && typeof message.error === "string" && problem !== message.error) {
70
+ problem = message.error;
71
+ this.log(`[computer-preview] ${problem}`);
72
+ }
73
+ else if (message.t === "gone") {
74
+ this.log("[computer-preview] capture process ended; last frame retained");
75
+ release();
76
+ failed();
77
+ }
78
+ });
79
+ return () => { app.endPreview(id); release(); };
80
+ }
81
+ catch (error) {
82
+ release();
83
+ throw error;
84
+ }
85
+ }
86
+ }
87
+ //# sourceMappingURL=computer-preview-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computer-preview-capture.js","sourceRoot":"","sources":["../../../../host/src/computer-preview-capture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { type PreviewFrame } from "@linkshell/wire";
2
+ import { z } from "zod";
3
+ export declare const previewCaptureSchema: z.ZodObject<{
4
+ bundleId: z.ZodString;
5
+ title: z.ZodOptional<z.ZodString>;
6
+ app: z.ZodOptional<z.ZodBoolean>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ bundleId: string;
9
+ title?: string | undefined;
10
+ app?: boolean | undefined;
11
+ }, {
12
+ bundleId: string;
13
+ title?: string | undefined;
14
+ app?: boolean | undefined;
15
+ }>;
16
+ export type PreviewCaptureTarget = z.infer<typeof previewCaptureSchema>;
17
+ export interface PreviewInput {
18
+ sourceId: string;
19
+ target: string;
20
+ capturedAt: number;
21
+ dataUrl?: string;
22
+ capture?: PreviewCaptureTarget;
23
+ }
24
+ interface Persistence {
25
+ load(sessionId: string): string | undefined;
26
+ save(sessionId: string, value: string): void;
27
+ exists(sessionId: string): boolean;
28
+ log(message: string): void;
29
+ capture?(target: PreviewCaptureTarget, frame: (dataUrl: string) => void, failed: () => void): Promise<() => void>;
30
+ }
31
+ /** One durable latest frame per session; images never enter conversation history. */
32
+ export declare class ComputerPreviews {
33
+ private readonly persistence;
34
+ private readonly cache;
35
+ private readonly pending;
36
+ private readonly listeners;
37
+ private draining?;
38
+ private closed;
39
+ private readonly captures;
40
+ private readonly captureRetries;
41
+ private readonly captureFailures;
42
+ constructor(persistence: Persistence);
43
+ get(sessionId: string): PreviewFrame | undefined;
44
+ getRelay(sessionId: string): PreviewFrame | undefined;
45
+ private read;
46
+ private remember;
47
+ put(sessionId: string, input: PreviewInput): Promise<void>;
48
+ private drain;
49
+ subscribe(id: string, listener: () => void): () => void;
50
+ private readonly savedAt;
51
+ private persist;
52
+ private startCapture;
53
+ private endCapture;
54
+ forget(id: string): void;
55
+ stop(): Promise<void>;
56
+ }
57
+ /** Read-only, one-use grants; existing proxy/direct transports carry these sockets. */
58
+ export declare class ComputerPreviewServer {
59
+ private readonly frames;
60
+ private server?;
61
+ private opening?;
62
+ private readonly grants;
63
+ private readonly sockets;
64
+ private relayNextAt;
65
+ constructor(frames: ComputerPreviews);
66
+ open(sessionId: string, direct?: boolean): Promise<{
67
+ port: number;
68
+ token: string;
69
+ }>;
70
+ private accept;
71
+ stop(): void;
72
+ }
73
+ export {};