@linkshell/host 0.1.0

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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/dist/host/src/drivers/acp/connection.d.ts +61 -0
  4. package/dist/host/src/drivers/acp/connection.js +121 -0
  5. package/dist/host/src/drivers/acp/connection.js.map +1 -0
  6. package/dist/host/src/drivers/acp/driver.d.ts +110 -0
  7. package/dist/host/src/drivers/acp/driver.js +438 -0
  8. package/dist/host/src/drivers/acp/driver.js.map +1 -0
  9. package/dist/host/src/drivers/acp/mapper.d.ts +49 -0
  10. package/dist/host/src/drivers/acp/mapper.js +411 -0
  11. package/dist/host/src/drivers/acp/mapper.js.map +1 -0
  12. package/dist/host/src/drivers/auth.d.ts +7 -0
  13. package/dist/host/src/drivers/auth.js +57 -0
  14. package/dist/host/src/drivers/auth.js.map +1 -0
  15. package/dist/host/src/drivers/claude/driver.d.ts +76 -0
  16. package/dist/host/src/drivers/claude/driver.js +331 -0
  17. package/dist/host/src/drivers/claude/driver.js.map +1 -0
  18. package/dist/host/src/drivers/claude/transcript.d.ts +335 -0
  19. package/dist/host/src/drivers/claude/transcript.js +516 -0
  20. package/dist/host/src/drivers/claude/transcript.js.map +1 -0
  21. package/dist/host/src/drivers/codex/app-server.d.ts +36 -0
  22. package/dist/host/src/drivers/codex/app-server.js +144 -0
  23. package/dist/host/src/drivers/codex/app-server.js.map +1 -0
  24. package/dist/host/src/drivers/codex/driver.d.ts +89 -0
  25. package/dist/host/src/drivers/codex/driver.js +452 -0
  26. package/dist/host/src/drivers/codex/driver.js.map +1 -0
  27. package/dist/host/src/drivers/codex/mapper.d.ts +61 -0
  28. package/dist/host/src/drivers/codex/mapper.js +623 -0
  29. package/dist/host/src/drivers/codex/mapper.js.map +1 -0
  30. package/dist/host/src/drivers/codex/settings.d.ts +51 -0
  31. package/dist/host/src/drivers/codex/settings.js +107 -0
  32. package/dist/host/src/drivers/codex/settings.js.map +1 -0
  33. package/dist/host/src/drivers/images.d.ts +11 -0
  34. package/dist/host/src/drivers/images.js +34 -0
  35. package/dist/host/src/drivers/images.js.map +1 -0
  36. package/dist/host/src/drivers/nesting.d.ts +6 -0
  37. package/dist/host/src/drivers/nesting.js +25 -0
  38. package/dist/host/src/drivers/nesting.js.map +1 -0
  39. package/dist/host/src/drivers/registry.d.ts +21 -0
  40. package/dist/host/src/drivers/registry.js +30 -0
  41. package/dist/host/src/drivers/registry.js.map +1 -0
  42. package/dist/host/src/drivers/types.d.ts +105 -0
  43. package/dist/host/src/drivers/types.js +2 -0
  44. package/dist/host/src/drivers/types.js.map +1 -0
  45. package/dist/host/src/fs.d.ts +69 -0
  46. package/dist/host/src/fs.js +198 -0
  47. package/dist/host/src/fs.js.map +1 -0
  48. package/dist/host/src/gateway.d.ts +55 -0
  49. package/dist/host/src/gateway.js +263 -0
  50. package/dist/host/src/gateway.js.map +1 -0
  51. package/dist/host/src/host.d.ts +51 -0
  52. package/dist/host/src/host.js +133 -0
  53. package/dist/host/src/host.js.map +1 -0
  54. package/dist/host/src/hub.d.ts +89 -0
  55. package/dist/host/src/hub.js +592 -0
  56. package/dist/host/src/hub.js.map +1 -0
  57. package/dist/host/src/index.d.ts +10 -0
  58. package/dist/host/src/index.js +10 -0
  59. package/dist/host/src/index.js.map +1 -0
  60. package/dist/host/src/ports.d.ts +24 -0
  61. package/dist/host/src/ports.js +201 -0
  62. package/dist/host/src/ports.js.map +1 -0
  63. package/dist/host/src/rpc/client.d.ts +9 -0
  64. package/dist/host/src/rpc/client.js +42 -0
  65. package/dist/host/src/rpc/client.js.map +1 -0
  66. package/dist/host/src/rpc/server.d.ts +52 -0
  67. package/dist/host/src/rpc/server.js +293 -0
  68. package/dist/host/src/rpc/server.js.map +1 -0
  69. package/dist/host/src/screen.d.ts +30 -0
  70. package/dist/host/src/screen.js +230 -0
  71. package/dist/host/src/screen.js.map +1 -0
  72. package/dist/host/src/shell-env.d.ts +8 -0
  73. package/dist/host/src/shell-env.js +39 -0
  74. package/dist/host/src/shell-env.js.map +1 -0
  75. package/dist/host/src/store.d.ts +75 -0
  76. package/dist/host/src/store.js +265 -0
  77. package/dist/host/src/store.js.map +1 -0
  78. package/dist/host/src/terminals.d.ts +55 -0
  79. package/dist/host/src/terminals.js +367 -0
  80. package/dist/host/src/terminals.js.map +1 -0
  81. package/dist/host/tsconfig.tsbuildinfo +1 -0
  82. package/dist/wire/src/crypto.d.ts +65 -0
  83. package/dist/wire/src/crypto.js +253 -0
  84. package/dist/wire/src/crypto.js.map +1 -0
  85. package/dist/wire/src/index.d.ts +8 -0
  86. package/dist/wire/src/index.js +9 -0
  87. package/dist/wire/src/index.js.map +1 -0
  88. package/dist/wire/src/model.d.ts +704 -0
  89. package/dist/wire/src/model.js +163 -0
  90. package/dist/wire/src/model.js.map +1 -0
  91. package/dist/wire/src/peer.d.ts +42 -0
  92. package/dist/wire/src/peer.js +143 -0
  93. package/dist/wire/src/peer.js.map +1 -0
  94. package/dist/wire/src/relay-client.d.ts +82 -0
  95. package/dist/wire/src/relay-client.js +259 -0
  96. package/dist/wire/src/relay-client.js.map +1 -0
  97. package/dist/wire/src/relay.d.ts +481 -0
  98. package/dist/wire/src/relay.js +129 -0
  99. package/dist/wire/src/relay.js.map +1 -0
  100. package/dist/wire/src/rpc.d.ts +4170 -0
  101. package/dist/wire/src/rpc.js +332 -0
  102. package/dist/wire/src/rpc.js.map +1 -0
  103. package/dist/wire/src/shell.d.ts +2 -0
  104. package/dist/wire/src/shell.js +62 -0
  105. package/dist/wire/src/shell.js.map +1 -0
  106. package/dist/wire/src/updates.d.ts +3325 -0
  107. package/dist/wire/src/updates.js +210 -0
  108. package/dist/wire/src/updates.js.map +1 -0
  109. package/package.json +53 -0
@@ -0,0 +1,163 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * How far LinkShell can take a given agent. The UI renders capabilities from
4
+ * this instead of guessing:
5
+ * - multi_client: desktop TUI and remote devices are live clients of one agent
6
+ * server (Codex app-server, OpenCode server).
7
+ * - handoff: the native TUI owns the session on the desktop; a remote device can
8
+ * take it over and the session continues headlessly under the same id.
9
+ * - remote: structured control only; the desktop uses LinkShell's own UI.
10
+ * - terminal: PTY only.
11
+ */
12
+ export const agentTierSchema = z.enum(["multi_client", "handoff", "remote", "terminal"]);
13
+ export const agentCapabilitiesSchema = z.object({
14
+ interrupt: z.boolean(),
15
+ /** Inject a message into a running turn instead of queueing it. */
16
+ steer: z.boolean(),
17
+ permissions: z.boolean(),
18
+ images: z.boolean(),
19
+ fork: z.boolean(),
20
+ models: z.boolean(),
21
+ modes: z.boolean(),
22
+ });
23
+ /**
24
+ * How the agent authenticates on this machine, as the agent itself reports it
25
+ * (e.g. `claude auth status`, `codex login status`). LinkShell never handles
26
+ * the credentials; it runs agents with the user's own environment and config.
27
+ */
28
+ export const agentAuthSchema = z.object({
29
+ state: z.enum(["ok", "missing", "unknown"]),
30
+ /** e.g. "claude.ai", "api_key", "oauth_token", "chatgpt", "bedrock". */
31
+ method: z.string().optional(),
32
+ /** What the user should do when state is "missing". */
33
+ hint: z.string().optional(),
34
+ });
35
+ export const agentInfoSchema = z.object({
36
+ id: z.string().min(1),
37
+ label: z.string().min(1),
38
+ tier: agentTierSchema,
39
+ installed: z.boolean(),
40
+ version: z.string().optional(),
41
+ /** Human-readable reason when the agent is installed but unusable. */
42
+ problem: z.string().optional(),
43
+ auth: agentAuthSchema.optional(),
44
+ capabilities: agentCapabilitiesSchema,
45
+ });
46
+ /**
47
+ * Who is driving a handoff session right now: the desktop's native UI, this
48
+ * host on behalf of a device, or nobody (either side can continue).
49
+ */
50
+ export const sessionDriverSchema = z.enum(["desktop", "remote", "none"]);
51
+ export const sessionStateSchema = z.enum(["idle", "running", "waiting", "error", "offline"]);
52
+ export const toolKindSchema = z.enum([
53
+ "read",
54
+ "edit",
55
+ "delete",
56
+ "move",
57
+ "search",
58
+ "execute",
59
+ "think",
60
+ "fetch",
61
+ "other",
62
+ ]);
63
+ export const permissionOptionSchema = z.object({
64
+ optionId: z.string().min(1),
65
+ name: z.string().min(1),
66
+ kind: z.enum(["allow_once", "allow_always", "reject_once", "reject_always"]),
67
+ });
68
+ /** What a running session is doing right now, for list rows. Live only. */
69
+ export const sessionActivitySchema = z.object({
70
+ kind: z.enum(["thinking", "responding", "tool"]),
71
+ title: z.string().optional(),
72
+ toolKind: toolKindSchema.optional(),
73
+ });
74
+ /** The oldest unanswered permission request, so lists can offer approval inline. Live only. */
75
+ export const pendingPermissionSchema = z.object({
76
+ requestId: z.string(),
77
+ toolCallId: z.string().optional(),
78
+ title: z.string(),
79
+ detail: z.string().optional(),
80
+ options: z.array(permissionOptionSchema).min(1),
81
+ });
82
+ export const sessionSummarySchema = z.object({
83
+ /** `${agent}:${nativeId}` — stable across daemon restarts and rediscovery. */
84
+ id: z.string().min(1),
85
+ agent: z.string().min(1),
86
+ nativeId: z.string().min(1),
87
+ title: z.string().optional(),
88
+ preview: z.string().optional(),
89
+ cwd: z.string(),
90
+ state: sessionStateSchema,
91
+ driver: sessionDriverSchema.optional(),
92
+ pendingPermissions: z.number().int().nonnegative(),
93
+ model: z.string().optional(),
94
+ createdAt: z.number(),
95
+ updatedAt: z.number(),
96
+ lastSeq: z.number().int().nonnegative(),
97
+ archived: z.boolean(),
98
+ activity: sessionActivitySchema.optional(),
99
+ permission: pendingPermissionSchema.optional(),
100
+ });
101
+ export function sessionIdFor(agent, nativeId) {
102
+ return `${agent}:${nativeId}`;
103
+ }
104
+ export function parseSessionId(id) {
105
+ const index = id.indexOf(":");
106
+ if (index <= 0 || index === id.length - 1)
107
+ return null;
108
+ return { agent: id.slice(0, index), nativeId: id.slice(index + 1) };
109
+ }
110
+ export const projectSummarySchema = z.object({
111
+ cwd: z.string(),
112
+ name: z.string(),
113
+ lastActiveAt: z.number(),
114
+ sessionCount: z.number().int().nonnegative(),
115
+ });
116
+ export const machineInfoSchema = z.object({
117
+ machineId: z.string().min(1),
118
+ hostname: z.string(),
119
+ platform: z.string(),
120
+ hostVersion: z.string(),
121
+ agents: z.array(agentInfoSchema),
122
+ });
123
+ /** A server listening on the host, which a device can preview through the encrypted channel. */
124
+ export const portInfoSchema = z.object({
125
+ port: z.number().int().min(1).max(65535),
126
+ /** The listening process ("node", "python3.12"). */
127
+ process: z.string(),
128
+ pid: z.number().int().optional(),
129
+ /** The process's working directory: which project the server belongs to. */
130
+ cwd: z.string().optional(),
131
+ /** The page title, when the port answers HTTP with an HTML page. */
132
+ title: z.string().optional(),
133
+ /** Answers HTTP at all (a dev server, not a database). */
134
+ http: z.boolean(),
135
+ });
136
+ /** A shell the host keeps open, independent of any device connection. */
137
+ export const terminalInfoSchema = z.object({
138
+ id: z.string(),
139
+ /** What's running in the foreground (the shell or its current command). */
140
+ title: z.string(),
141
+ cwd: z.string(),
142
+ cols: z.number().int(),
143
+ rows: z.number().int(),
144
+ createdAt: z.number(),
145
+ /** Last output time. */
146
+ activeAt: z.number(),
147
+ /** The command it was started to run, if any (else it's a plain shell). */
148
+ command: z.string().optional(),
149
+ /** Set once the shell ended; the terminal and its output stay until deleted. */
150
+ exitCode: z.number().int().nullable().optional(),
151
+ /** Ended without an exit code: the host stopped while it ran. */
152
+ interrupted: z.boolean().optional(),
153
+ });
154
+ /** The host's link to a v2 gateway, for `linkshell status` and the app's computer page. */
155
+ export const gatewayStatusSchema = z.object({
156
+ url: z.string().optional(),
157
+ status: z.enum(["off", "connecting", "online", "offline"]),
158
+ error: z.object({ code: z.string(), message: z.string() }).optional(),
159
+ machine: z.object({ id: z.string(), name: z.string() }).optional(),
160
+ account: z.object({ userId: z.string(), email: z.string().optional() }).optional(),
161
+ devices: z.array(z.object({ id: z.string(), name: z.string(), pairedAt: z.number(), online: z.boolean() })),
162
+ });
163
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../wire/src/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { RpcErrorObject, RpcId } from "./rpc.js";
2
+ /** An error that crosses the wire as a JSON-RPC error object. */
3
+ export declare class RpcError extends Error {
4
+ readonly code: number;
5
+ readonly data?: unknown | undefined;
6
+ constructor(code: number, message: string, data?: unknown | undefined);
7
+ static app(appCode: string, message: string, extra?: Record<string, unknown>): RpcError;
8
+ /** The `data.code` of an application error, if any. */
9
+ get appCode(): string | undefined;
10
+ toObject(): RpcErrorObject;
11
+ }
12
+ /** Returned by a request handler to leave a request unanswered for good. */
13
+ export declare const ABANDON: unique symbol;
14
+ export type RequestHandler = (method: string, params: unknown, id: RpcId) => unknown | Promise<unknown>;
15
+ export type NotificationHandler = (method: string, params: unknown) => void;
16
+ export interface RpcPeerOptions {
17
+ /** Sends one serialized JSON-RPC message. */
18
+ send: (text: string) => void;
19
+ onRequest?: RequestHandler;
20
+ onNotification?: NotificationHandler;
21
+ /** Default timeout for outgoing requests; 0 disables it. */
22
+ requestTimeoutMs?: number;
23
+ }
24
+ /**
25
+ * Transport-agnostic JSON-RPC 2.0 peer: both sides can issue requests and
26
+ * notifications. Feed incoming text frames to `receive()`.
27
+ */
28
+ export declare class RpcPeer {
29
+ private readonly options;
30
+ private nextId;
31
+ private readonly pending;
32
+ private closed;
33
+ constructor(options: RpcPeerOptions);
34
+ request<T = unknown>(method: string, params?: unknown, timeoutMs?: number): Promise<T>;
35
+ notify(method: string, params?: unknown): void;
36
+ receive(text: string): void;
37
+ /** Rejects every in-flight request; later calls fail immediately. */
38
+ close(reason?: string): void;
39
+ get isClosed(): boolean;
40
+ private dispatch;
41
+ private write;
42
+ }
@@ -0,0 +1,143 @@
1
+ import { RPC_APP_ERROR, RPC_METHOD_NOT_FOUND } from "./rpc.js";
2
+ /** An error that crosses the wire as a JSON-RPC error object. */
3
+ export class RpcError extends Error {
4
+ code;
5
+ data;
6
+ constructor(code, message, data) {
7
+ super(message);
8
+ this.code = code;
9
+ this.data = data;
10
+ this.name = "RpcError";
11
+ }
12
+ static app(appCode, message, extra) {
13
+ return new RpcError(RPC_APP_ERROR, message, { code: appCode, ...extra });
14
+ }
15
+ /** The `data.code` of an application error, if any. */
16
+ get appCode() {
17
+ const data = this.data;
18
+ return typeof data?.code === "string" ? data.code : undefined;
19
+ }
20
+ toObject() {
21
+ return this.data === undefined
22
+ ? { code: this.code, message: this.message }
23
+ : { code: this.code, message: this.message, data: this.data };
24
+ }
25
+ }
26
+ /** Returned by a request handler to leave a request unanswered for good. */
27
+ export const ABANDON = Symbol("rpc.abandon");
28
+ /**
29
+ * Transport-agnostic JSON-RPC 2.0 peer: both sides can issue requests and
30
+ * notifications. Feed incoming text frames to `receive()`.
31
+ */
32
+ export class RpcPeer {
33
+ options;
34
+ nextId = 1;
35
+ pending = new Map();
36
+ closed = false;
37
+ constructor(options) {
38
+ this.options = options;
39
+ }
40
+ request(method, params, timeoutMs) {
41
+ if (this.closed)
42
+ return Promise.reject(new RpcError(RPC_APP_ERROR, `connection closed (${method})`));
43
+ const id = this.nextId++;
44
+ return new Promise((resolve, reject) => {
45
+ const entry = { resolve: resolve, reject, method };
46
+ const limit = timeoutMs ?? this.options.requestTimeoutMs ?? 30_000;
47
+ if (limit > 0) {
48
+ entry.timer = setTimeout(() => {
49
+ this.pending.delete(id);
50
+ reject(new RpcError(RPC_APP_ERROR, `${method} timed out after ${limit}ms`, { code: "timeout" }));
51
+ }, limit);
52
+ }
53
+ this.pending.set(id, entry);
54
+ this.write({ jsonrpc: "2.0", id, method, params: params ?? {} });
55
+ });
56
+ }
57
+ notify(method, params) {
58
+ if (this.closed)
59
+ return;
60
+ this.write({ jsonrpc: "2.0", method, params: params ?? {} });
61
+ }
62
+ receive(text) {
63
+ for (const line of text.split("\n")) {
64
+ if (!line.trim())
65
+ continue;
66
+ let message;
67
+ try {
68
+ message = JSON.parse(line);
69
+ }
70
+ catch {
71
+ continue;
72
+ }
73
+ this.dispatch(message);
74
+ }
75
+ }
76
+ /** Rejects every in-flight request; later calls fail immediately. */
77
+ close(reason = "connection closed") {
78
+ if (this.closed)
79
+ return;
80
+ this.closed = true;
81
+ for (const [id, entry] of this.pending) {
82
+ if (entry.timer)
83
+ clearTimeout(entry.timer);
84
+ entry.reject(new RpcError(RPC_APP_ERROR, `${reason} (${entry.method})`, { code: "closed" }));
85
+ this.pending.delete(id);
86
+ }
87
+ }
88
+ get isClosed() {
89
+ return this.closed;
90
+ }
91
+ dispatch(message) {
92
+ const id = message.id;
93
+ const method = typeof message.method === "string" ? message.method : undefined;
94
+ if (method === undefined) {
95
+ if (id === undefined)
96
+ return;
97
+ const entry = this.pending.get(id);
98
+ if (!entry)
99
+ return;
100
+ this.pending.delete(id);
101
+ if (entry.timer)
102
+ clearTimeout(entry.timer);
103
+ const error = message.error;
104
+ if (error)
105
+ entry.reject(new RpcError(error.code, error.message, error.data));
106
+ else
107
+ entry.resolve(message.result);
108
+ return;
109
+ }
110
+ if (id === undefined) {
111
+ this.options.onNotification?.(method, message.params);
112
+ return;
113
+ }
114
+ const handler = this.options.onRequest;
115
+ if (!handler) {
116
+ this.write({ jsonrpc: "2.0", id, error: { code: RPC_METHOD_NOT_FOUND, message: `no handler for ${method}` } });
117
+ return;
118
+ }
119
+ Promise.resolve()
120
+ .then(() => handler(method, message.params, id))
121
+ .then((result) => {
122
+ if (result === ABANDON)
123
+ return;
124
+ this.write({ jsonrpc: "2.0", id, result: result ?? {} });
125
+ }, (error) => {
126
+ const rpcError = error instanceof RpcError
127
+ ? error
128
+ : new RpcError(RPC_APP_ERROR, error instanceof Error ? error.message : String(error), { code: "internal" });
129
+ this.write({ jsonrpc: "2.0", id, error: rpcError.toObject() });
130
+ });
131
+ }
132
+ write(message) {
133
+ if (this.closed)
134
+ return;
135
+ try {
136
+ this.options.send(JSON.stringify(message));
137
+ }
138
+ catch {
139
+ this.close("send failed");
140
+ }
141
+ }
142
+ }
143
+ //# sourceMappingURL=peer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer.js","sourceRoot":"","sources":["../../../../wire/src/peer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { type Identity, type PublicIdentity } from "./crypto.js";
2
+ import { type PeerRole, type RelayEvents, type RelayMethod, type RelayMethods, type TunnelFrame } from "./relay.js";
3
+ export interface RelaySocket {
4
+ readonly readyState: number;
5
+ send(data: string): void;
6
+ close(code?: number, reason?: string): void;
7
+ onopen: ((event: unknown) => void) | null;
8
+ onmessage: ((event: {
9
+ data: unknown;
10
+ }) => void) | null;
11
+ onclose: ((event: {
12
+ code?: number;
13
+ reason?: string;
14
+ }) => void) | null;
15
+ onerror: ((event: unknown) => void) | null;
16
+ }
17
+ export type RelayStatus = "connecting" | "online" | "offline" | "stopped";
18
+ export interface RelayClientOptions {
19
+ url: string;
20
+ identity: Identity;
21
+ role: PeerRole;
22
+ name: string;
23
+ platform?: string;
24
+ /** Account token, fetched fresh for each connection. */
25
+ token?: () => Promise<string | undefined> | string | undefined;
26
+ createSocket: (url: string) => RelaySocket;
27
+ minBackoffMs?: number;
28
+ maxBackoffMs?: number;
29
+ requestTimeoutMs?: number;
30
+ }
31
+ export declare class RelayRequestError extends Error {
32
+ readonly code: string;
33
+ constructor(code: string, message: string);
34
+ }
35
+ export declare class RelayClient {
36
+ private readonly options;
37
+ private socket?;
38
+ private statusValue;
39
+ private attempt;
40
+ private timer?;
41
+ private nextId;
42
+ private readonly pending;
43
+ private readonly statusListeners;
44
+ private readonly frameListeners;
45
+ private readonly undeliverableListeners;
46
+ private readonly eventListeners;
47
+ private readonly waiters;
48
+ /** Account the gateway recognised on the last connection. */
49
+ account?: {
50
+ userId: string;
51
+ email?: string;
52
+ };
53
+ lastError?: {
54
+ code: string;
55
+ message: string;
56
+ };
57
+ constructor(options: RelayClientOptions);
58
+ get status(): RelayStatus;
59
+ get identity(): PublicIdentity;
60
+ onStatus(listener: (status: RelayStatus, error?: {
61
+ code: string;
62
+ message: string;
63
+ }) => void): () => void;
64
+ onFrame(listener: (from: PublicIdentity, via: "paired" | "account", frame: TunnelFrame) => void): () => void;
65
+ onUndeliverable(listener: (to: string, reason: string) => void): () => void;
66
+ on<N extends keyof RelayEvents>(name: N, listener: (data: RelayEvents[N]) => void): () => void;
67
+ start(): void;
68
+ stop(): void;
69
+ /** Reconnect now instead of waiting out the backoff (app foregrounded, network back). */
70
+ reconnectNow(): void;
71
+ /** Waits (up to `timeoutMs`) for the gateway connection. */
72
+ waitOnline(timeoutMs: number): Promise<boolean>;
73
+ request<M extends RelayMethod>(method: M, params: RelayMethods[M]["params"], timeoutMs?: number): Promise<RelayMethods[M]["result"]>;
74
+ /** Sends a tunnel frame to a peer. Returns false when not connected. */
75
+ send(to: string, frame: TunnelFrame): boolean;
76
+ private sendFrame;
77
+ private setStatus;
78
+ private failPending;
79
+ private open;
80
+ private authenticate;
81
+ private scheduleReconnect;
82
+ }