@termlink/cli 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 (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -0
  3. package/dist/auth/login.d.ts +55 -0
  4. package/dist/auth/login.d.ts.map +1 -0
  5. package/dist/auth/login.js +238 -0
  6. package/dist/auth/login.js.map +1 -0
  7. package/dist/auth/oauth-defaults.d.ts +9 -0
  8. package/dist/auth/oauth-defaults.d.ts.map +1 -0
  9. package/dist/auth/oauth-defaults.js +9 -0
  10. package/dist/auth/oauth-defaults.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +319 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/errors.d.ts +8 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +13 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/index.d.ts +20 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +19 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/providers/claude/history.d.ts +15 -0
  24. package/dist/providers/claude/history.d.ts.map +1 -0
  25. package/dist/providers/claude/history.js +71 -0
  26. package/dist/providers/claude/history.js.map +1 -0
  27. package/dist/providers/claude/input-queue.d.ts +8 -0
  28. package/dist/providers/claude/input-queue.d.ts.map +1 -0
  29. package/dist/providers/claude/input-queue.js +34 -0
  30. package/dist/providers/claude/input-queue.js.map +1 -0
  31. package/dist/providers/claude/mapper.d.ts +21 -0
  32. package/dist/providers/claude/mapper.d.ts.map +1 -0
  33. package/dist/providers/claude/mapper.js +136 -0
  34. package/dist/providers/claude/mapper.js.map +1 -0
  35. package/dist/providers/claude/provider.d.ts +46 -0
  36. package/dist/providers/claude/provider.d.ts.map +1 -0
  37. package/dist/providers/claude/provider.js +148 -0
  38. package/dist/providers/claude/provider.js.map +1 -0
  39. package/dist/providers/claude/session.d.ts +27 -0
  40. package/dist/providers/claude/session.d.ts.map +1 -0
  41. package/dist/providers/claude/session.js +353 -0
  42. package/dist/providers/claude/session.js.map +1 -0
  43. package/dist/providers/codex/app-server.d.ts +24 -0
  44. package/dist/providers/codex/app-server.d.ts.map +1 -0
  45. package/dist/providers/codex/app-server.js +79 -0
  46. package/dist/providers/codex/app-server.js.map +1 -0
  47. package/dist/providers/codex/command.d.ts +12 -0
  48. package/dist/providers/codex/command.d.ts.map +1 -0
  49. package/dist/providers/codex/command.js +60 -0
  50. package/dist/providers/codex/command.js.map +1 -0
  51. package/dist/providers/codex/history.d.ts +5 -0
  52. package/dist/providers/codex/history.d.ts.map +1 -0
  53. package/dist/providers/codex/history.js +33 -0
  54. package/dist/providers/codex/history.js.map +1 -0
  55. package/dist/providers/codex/mapper.d.ts +13 -0
  56. package/dist/providers/codex/mapper.d.ts.map +1 -0
  57. package/dist/providers/codex/mapper.js +83 -0
  58. package/dist/providers/codex/mapper.js.map +1 -0
  59. package/dist/providers/codex/protocol.d.ts +223 -0
  60. package/dist/providers/codex/protocol.d.ts.map +1 -0
  61. package/dist/providers/codex/protocol.js +11 -0
  62. package/dist/providers/codex/protocol.js.map +1 -0
  63. package/dist/providers/codex/provider.d.ts +28 -0
  64. package/dist/providers/codex/provider.d.ts.map +1 -0
  65. package/dist/providers/codex/provider.js +116 -0
  66. package/dist/providers/codex/provider.js.map +1 -0
  67. package/dist/providers/codex/rpc.d.ts +23 -0
  68. package/dist/providers/codex/rpc.d.ts.map +1 -0
  69. package/dist/providers/codex/rpc.js +104 -0
  70. package/dist/providers/codex/rpc.js.map +1 -0
  71. package/dist/providers/codex/session.d.ts +16 -0
  72. package/dist/providers/codex/session.d.ts.map +1 -0
  73. package/dist/providers/codex/session.js +262 -0
  74. package/dist/providers/codex/session.js.map +1 -0
  75. package/dist/providers/display.d.ts +9 -0
  76. package/dist/providers/display.d.ts.map +1 -0
  77. package/dist/providers/display.js +21 -0
  78. package/dist/providers/display.js.map +1 -0
  79. package/dist/providers/terminal.d.ts +24 -0
  80. package/dist/providers/terminal.d.ts.map +1 -0
  81. package/dist/providers/terminal.js +33 -0
  82. package/dist/providers/terminal.js.map +1 -0
  83. package/dist/providers/types.d.ts +72 -0
  84. package/dist/providers/types.d.ts.map +1 -0
  85. package/dist/providers/types.js +2 -0
  86. package/dist/providers/types.js.map +1 -0
  87. package/dist/relay/api.d.ts +13 -0
  88. package/dist/relay/api.d.ts.map +1 -0
  89. package/dist/relay/api.js +75 -0
  90. package/dist/relay/api.js.map +1 -0
  91. package/dist/relay/device.d.ts +26 -0
  92. package/dist/relay/device.d.ts.map +1 -0
  93. package/dist/relay/device.js +83 -0
  94. package/dist/relay/device.js.map +1 -0
  95. package/dist/relay/relay-host.d.ts +41 -0
  96. package/dist/relay/relay-host.d.ts.map +1 -0
  97. package/dist/relay/relay-host.js +238 -0
  98. package/dist/relay/relay-host.js.map +1 -0
  99. package/dist/server/coalesce.d.ts +15 -0
  100. package/dist/server/coalesce.d.ts.map +1 -0
  101. package/dist/server/coalesce.js +50 -0
  102. package/dist/server/coalesce.js.map +1 -0
  103. package/dist/server/connection.d.ts +30 -0
  104. package/dist/server/connection.d.ts.map +1 -0
  105. package/dist/server/connection.js +182 -0
  106. package/dist/server/connection.js.map +1 -0
  107. package/dist/server/local-server.d.ts +27 -0
  108. package/dist/server/local-server.d.ts.map +1 -0
  109. package/dist/server/local-server.js +108 -0
  110. package/dist/server/local-server.js.map +1 -0
  111. package/dist/session/event-log.d.ts +17 -0
  112. package/dist/session/event-log.d.ts.map +1 -0
  113. package/dist/session/event-log.js +21 -0
  114. package/dist/session/event-log.js.map +1 -0
  115. package/dist/session/manager.d.ts +62 -0
  116. package/dist/session/manager.d.ts.map +1 -0
  117. package/dist/session/manager.js +282 -0
  118. package/dist/session/manager.js.map +1 -0
  119. package/dist/session/session.d.ts +43 -0
  120. package/dist/session/session.d.ts.map +1 -0
  121. package/dist/session/session.js +310 -0
  122. package/dist/session/session.js.map +1 -0
  123. package/dist/session/store.d.ts +22 -0
  124. package/dist/session/store.d.ts.map +1 -0
  125. package/dist/session/store.js +44 -0
  126. package/dist/session/store.js.map +1 -0
  127. package/dist/session/terminal-session.d.ts +52 -0
  128. package/dist/session/terminal-session.d.ts.map +1 -0
  129. package/dist/session/terminal-session.js +210 -0
  130. package/dist/session/terminal-session.js.map +1 -0
  131. package/dist/util/id.d.ts +2 -0
  132. package/dist/util/id.d.ts.map +1 -0
  133. package/dist/util/id.js +5 -0
  134. package/dist/util/id.js.map +1 -0
  135. package/dist/util/lock.d.ts +12 -0
  136. package/dist/util/lock.d.ts.map +1 -0
  137. package/dist/util/lock.js +52 -0
  138. package/dist/util/lock.js.map +1 -0
  139. package/dist/util/which.d.ts +3 -0
  140. package/dist/util/which.d.ts.map +1 -0
  141. package/dist/util/which.js +12 -0
  142. package/dist/util/which.js.map +1 -0
  143. package/dist/version.d.ts +2 -0
  144. package/dist/version.d.ts.map +1 -0
  145. package/dist/version.js +5 -0
  146. package/dist/version.js.map +1 -0
  147. package/package.json +56 -0
@@ -0,0 +1,16 @@
1
+ import type { EventSink, ProviderSession, UserInput } from "../types.js";
2
+ import type { CodexAppServer, ThreadHandler } from "./app-server.js";
3
+ import type { RequestId } from "./protocol.js";
4
+ /** One Codex thread, driven through the shared app-server. */
5
+ export declare class CodexThreadSession implements ProviderSession, ThreadHandler {
6
+ #private;
7
+ readonly threadId: string;
8
+ constructor(server: CodexAppServer, threadId: string, sink: EventSink);
9
+ send(input: UserInput): Promise<void>;
10
+ interrupt(): Promise<void>;
11
+ close(): Promise<void>;
12
+ notification(method: string, params: unknown): void;
13
+ request(method: string, params: unknown, id: RequestId): Promise<unknown>;
14
+ closed(reason: Error): void;
15
+ }
16
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/session.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAiB,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,KAAK,EASV,SAAS,EASV,MAAM,eAAe,CAAC;AAKvB,8DAA8D;AAC9D,qBAAa,kBAAmB,YAAW,eAAe,EAAE,aAAa;;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAc1B,YAAY,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAIpE;IAEK,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAS1C;IAEK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ/B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAO3B;IAED,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAoElD;IAEK,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAgC9E;IAED,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,CAO1B;CAmFF"}
@@ -0,0 +1,262 @@
1
+ import { setTimeout as sleep } from "node:timers/promises";
2
+ import { applyDelta } from "@termlink/protocol";
3
+ import { HostError } from "../../errors.js";
4
+ import { APPROVAL_DECISIONS, mapFileChange, mapItem } from "./mapper.js";
5
+ import { NO_RESPONSE, RpcError } from "./rpc.js";
6
+ const INTERRUPT_TIMEOUT_MS = 10_000;
7
+ /** One Codex thread, driven through the shared app-server. */
8
+ export class CodexThreadSession {
9
+ threadId;
10
+ #server;
11
+ #sink;
12
+ /** Mapped items still in progress, kept current with deltas. */
13
+ #items = new Map();
14
+ /** Pending approvals by JSON-RPC id. Abort reason "resolved" means Codex withdrew it. */
15
+ #requests = new Map();
16
+ #finishedTurns = new Set();
17
+ #turnId = null;
18
+ #turnWaiters = [];
19
+ #totals = null;
20
+ #totalsAtTurnStart = null;
21
+ #closed = false;
22
+ constructor(server, threadId, sink) {
23
+ this.#server = server;
24
+ this.threadId = threadId;
25
+ this.#sink = sink;
26
+ }
27
+ async send(input) {
28
+ if (this.#closed)
29
+ throw new HostError("conflict", "codex session is closed");
30
+ if (this.#turnId)
31
+ throw new HostError("conflict", "a turn is already running");
32
+ const params = {
33
+ threadId: this.threadId,
34
+ input: [{ type: "text", text: input.text, text_elements: [] }],
35
+ };
36
+ const { turn } = await this.#server.peer.request("turn/start", params);
37
+ this.#beginTurn(turn.id);
38
+ }
39
+ async interrupt() {
40
+ const turnId = this.#turnId;
41
+ if (!turnId)
42
+ return;
43
+ this.#withdrawRequests("interrupt");
44
+ const done = new Promise((resolve) => this.#turnWaiters.push(resolve));
45
+ await this.#server.peer.request("turn/interrupt", { threadId: this.threadId, turnId }).catch(() => { });
46
+ await Promise.race([done, sleep(INTERRUPT_TIMEOUT_MS)]);
47
+ if (this.#turnId === turnId)
48
+ this.#completeTurn({ id: turnId, status: "interrupted", error: null });
49
+ }
50
+ async close() {
51
+ await this.interrupt();
52
+ this.#closed = true;
53
+ this.#server.unregister(this.threadId);
54
+ if (!this.#server.peer.closed) {
55
+ await this.#server.peer.request("thread/unsubscribe", { threadId: this.threadId }).catch(() => { });
56
+ }
57
+ }
58
+ notification(method, params) {
59
+ switch (method) {
60
+ case "turn/started":
61
+ this.#beginTurn(params.turn.id);
62
+ break;
63
+ case "turn/completed":
64
+ this.#completeTurn(params.turn);
65
+ break;
66
+ case "item/started": {
67
+ const { turnId, item } = params;
68
+ this.#beginTurn(turnId);
69
+ const mapped = mapItem(item, "started");
70
+ if (!mapped)
71
+ break;
72
+ this.#items.set(mapped.id, mapped);
73
+ this.#sink.emit("item.started", { turnId, item: mapped });
74
+ break;
75
+ }
76
+ case "item/completed": {
77
+ const { turnId, item } = params;
78
+ const mapped = mapItem(item, "completed");
79
+ if (!mapped)
80
+ break;
81
+ this.#items.delete(mapped.id);
82
+ this.#sink.emit("item.completed", { turnId, item: mapped });
83
+ break;
84
+ }
85
+ case "item/agentMessage/delta":
86
+ case "item/reasoning/summaryTextDelta": {
87
+ const { itemId, delta } = params;
88
+ this.#delta(itemId, "text", delta);
89
+ break;
90
+ }
91
+ case "item/reasoning/summaryPartAdded": {
92
+ const { itemId, summaryIndex } = params;
93
+ if (summaryIndex > 0)
94
+ this.#delta(itemId, "text", "\n\n");
95
+ break;
96
+ }
97
+ case "item/commandExecution/outputDelta": {
98
+ const { itemId, delta } = params;
99
+ this.#delta(itemId, "output", delta);
100
+ break;
101
+ }
102
+ case "item/fileChange/patchUpdated": {
103
+ const { itemId, changes } = params;
104
+ const item = this.#items.get(itemId);
105
+ if (item?.kind !== "file_change")
106
+ break;
107
+ const updated = { ...item, changes: changes.map(mapFileChange) };
108
+ this.#items.set(itemId, updated);
109
+ this.#sink.emit("item.updated", { item: updated });
110
+ break;
111
+ }
112
+ case "turn/plan/updated":
113
+ this.#updatePlan(params);
114
+ break;
115
+ case "thread/tokenUsage/updated":
116
+ this.#totals = params.tokenUsage.total;
117
+ break;
118
+ case "error": {
119
+ const { error, willRetry } = params;
120
+ if (willRetry)
121
+ this.#sink.emit("provider.event", { name: "codex.retrying", data: { message: error.message } });
122
+ else
123
+ this.#sink.emit("error", { code: "codex", message: error.message });
124
+ break;
125
+ }
126
+ case "serverRequest/resolved": {
127
+ const { requestId } = params;
128
+ this.#requests.get(String(requestId))?.abort("resolved");
129
+ break;
130
+ }
131
+ }
132
+ }
133
+ async request(method, params, id) {
134
+ switch (method) {
135
+ case "item/commandExecution/requestApproval": {
136
+ const p = params;
137
+ const item = this.#items.get(p.itemId);
138
+ const command = p.command ?? (item?.kind === "command" ? item.command : undefined);
139
+ return this.#approve(id, {
140
+ kind: "command_approval",
141
+ itemId: p.itemId,
142
+ title: p.kind === "writeStdin" ? "Send input to a running command?" : "Run command?",
143
+ ...(p.reason ? { body: p.reason } : {}),
144
+ ...(command ? { command } : {}),
145
+ ...(p.cwd ? { cwd: p.cwd } : {}),
146
+ decisions: APPROVAL_DECISIONS,
147
+ });
148
+ }
149
+ case "item/fileChange/requestApproval": {
150
+ const p = params;
151
+ const item = this.#items.get(p.itemId);
152
+ return this.#approve(id, {
153
+ kind: "file_approval",
154
+ itemId: p.itemId,
155
+ title: p.grantRoot ? `Allow writes under ${p.grantRoot}?` : "Apply file changes?",
156
+ ...(p.reason ? { body: p.reason } : {}),
157
+ ...(item?.kind === "file_change" ? { changes: item.changes } : {}),
158
+ decisions: APPROVAL_DECISIONS,
159
+ });
160
+ }
161
+ default:
162
+ this.#sink.emit("provider.event", { name: "codex.unsupported_request", data: { method } });
163
+ throw new RpcError(-32601, `${method} is not supported by the TermLink host`);
164
+ }
165
+ }
166
+ closed(reason) {
167
+ this.#closed = true;
168
+ this.#withdrawRequests("resolved");
169
+ if (this.#turnId) {
170
+ this.#sink.emit("error", { code: "codex_exited", message: reason.message });
171
+ this.#completeTurn({ id: this.#turnId, status: "failed", error: { message: reason.message } });
172
+ }
173
+ }
174
+ async #approve(id, request) {
175
+ const abort = new AbortController();
176
+ this.#requests.set(String(id), abort);
177
+ let response;
178
+ try {
179
+ response = await this.#sink.requestInput(request, abort.signal);
180
+ }
181
+ catch (err) {
182
+ if (!abort.signal.aborted)
183
+ throw err;
184
+ if (abort.signal.reason === "resolved")
185
+ return NO_RESPONSE;
186
+ response = { decisionId: null, effect: "cancel" };
187
+ }
188
+ finally {
189
+ this.#requests.delete(String(id));
190
+ }
191
+ const decision = (response.decisionId ?? "cancel");
192
+ return { decision };
193
+ }
194
+ #withdrawRequests(reason) {
195
+ for (const abort of this.#requests.values())
196
+ abort.abort(reason);
197
+ }
198
+ #beginTurn(turnId) {
199
+ if (this.#turnId === turnId || this.#finishedTurns.has(turnId))
200
+ return;
201
+ this.#turnId = turnId;
202
+ this.#totalsAtTurnStart = this.#totals;
203
+ this.#sink.emit("turn.started", { turnId });
204
+ }
205
+ #completeTurn(turn) {
206
+ if (this.#finishedTurns.has(turn.id))
207
+ return;
208
+ if (this.#turnId !== turn.id)
209
+ this.#beginTurn(turn.id);
210
+ for (const item of this.#items.values()) {
211
+ const status = item.kind === "todo" || turn.status === "completed" ? "completed" : "interrupted";
212
+ this.#sink.emit("item.completed", { turnId: turn.id, item: { ...item, status } });
213
+ }
214
+ this.#items.clear();
215
+ this.#finishedTurns.add(turn.id);
216
+ this.#turnId = null;
217
+ const usage = this.#turnUsage();
218
+ const status = turn.status === "inProgress" ? "failed" : turn.status;
219
+ this.#sink.emit("turn.completed", {
220
+ turnId: turn.id,
221
+ status,
222
+ ...(usage ? { usage } : {}),
223
+ ...(turn.error ? { error: turn.error.message } : {}),
224
+ });
225
+ for (const resolve of this.#turnWaiters.splice(0))
226
+ resolve();
227
+ }
228
+ #turnUsage() {
229
+ const now = this.#totals;
230
+ if (!now)
231
+ return undefined;
232
+ const before = this.#totalsAtTurnStart;
233
+ return {
234
+ inputTokens: now.inputTokens - (before?.inputTokens ?? 0),
235
+ outputTokens: now.outputTokens - (before?.outputTokens ?? 0),
236
+ };
237
+ }
238
+ #delta(itemId, field, delta) {
239
+ const item = this.#items.get(itemId);
240
+ if (!item)
241
+ return;
242
+ this.#items.set(itemId, applyDelta(item, field, delta));
243
+ this.#sink.emit("item.delta", { itemId, field, delta });
244
+ }
245
+ // Codex reports the plan per turn rather than as an item; the host shows it as one todo item.
246
+ #updatePlan({ turnId, plan }) {
247
+ const id = `plan_${turnId}`;
248
+ const item = {
249
+ id,
250
+ kind: "todo",
251
+ entries: plan.map((step) => ({ text: step.step, done: step.status === "completed" })),
252
+ status: "in_progress",
253
+ };
254
+ const known = this.#items.has(id);
255
+ this.#items.set(id, item);
256
+ if (known)
257
+ this.#sink.emit("item.updated", { item });
258
+ else
259
+ this.#sink.emit("item.started", { turnId, item });
260
+ }
261
+ }
262
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/providers/codex/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Short form of a shell command for the timeline: the inner command of a
3
+ * PowerShell `-Command '...'` or `sh -lc '...'` wrapper, or the single parsed
4
+ * action when the provider supplies one. Undefined when there is nothing shorter.
5
+ */
6
+ export declare function displayCommand(command: string, actions?: readonly {
7
+ command: string;
8
+ }[]): string | undefined;
9
+ //# sourceMappingURL=display.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/providers/display.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,GAAG,SAAS,CAI5G"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Short form of a shell command for the timeline: the inner command of a
3
+ * PowerShell `-Command '...'` or `sh -lc '...'` wrapper, or the single parsed
4
+ * action when the provider supplies one. Undefined when there is nothing shorter.
5
+ */
6
+ export function displayCommand(command, actions) {
7
+ const single = actions?.length === 1 ? actions[0]?.command : undefined;
8
+ const shown = single ?? unwrapShell(command);
9
+ return shown && shown.trim() !== command.trim() ? shown : undefined;
10
+ }
11
+ const POWERSHELL = /^(?:"[^"]*\\?(?:powershell|pwsh)(?:\.exe)?"|\S*(?:powershell|pwsh)(?:\.exe)?)\s+(?:-\w+\s+)*?-Command\s+(['"])([\s\S]*)\1\s*$/i;
12
+ const POSIX_SHELL = /^\S*\/?(?:bash|zsh|sh)\s+-l?c\s+(['"])([\s\S]*)\1\s*$/;
13
+ function unwrapShell(command) {
14
+ const match = POWERSHELL.exec(command) ?? POSIX_SHELL.exec(command);
15
+ if (!match)
16
+ return undefined;
17
+ const [, quote, inner = ""] = match;
18
+ // Inside single quotes PowerShell doubles a quote to escape it.
19
+ return quote === "'" && POWERSHELL.test(command) ? inner.replaceAll("''", "'") : inner;
20
+ }
21
+ //# sourceMappingURL=display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display.js","sourceRoot":"","sources":["../../src/providers/display.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,OAAwC;IACtF,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,MAAM,KAAK,GAAG,MAAM,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,GAAG,gIAAgI,CAAC;AACpJ,MAAM,WAAW,GAAG,uDAAuD,CAAC;AAE5E,SAAS,WAAW,CAAC,OAAe;IAClC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpE,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;IACpC,gEAAgE;IAChE,OAAO,KAAK,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACzF,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { type Terminal } from "@termlink/terminal";
2
+ import type { OpenTerminalOptions, ProbeResult, TerminalProvider } from "./types.js";
3
+ export interface ShellProviderOptions {
4
+ /** Shell executable. Defaults to the user's shell. */
5
+ shell?: string | undefined;
6
+ /** Arguments for the shell, when `shell` is set. */
7
+ args?: string[] | undefined;
8
+ /** Lines kept above the screen for reconnects. */
9
+ scrollback?: number | undefined;
10
+ }
11
+ /**
12
+ * The terminal provider: opens the user's shell in a PTY, like an ssh login. Its
13
+ * availability is whether this platform has a PTY binary; nothing else to check.
14
+ */
15
+ export declare class ShellProvider implements TerminalProvider {
16
+ #private;
17
+ readonly id: "terminal";
18
+ readonly kind: "terminal";
19
+ readonly label = "Terminal";
20
+ constructor(options?: ShellProviderOptions);
21
+ probe(): Promise<ProbeResult>;
22
+ open(options: OpenTerminalOptions): Promise<Terminal>;
23
+ }
24
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/providers/terminal.ts"],"names":[],"mappings":"AACA,OAAO,EAA2C,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC5F,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErF,MAAM,WAAW,oBAAoB;IACnC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5B,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,aAAc,YAAW,gBAAgB;;IACpD,QAAQ,CAAC,EAAE,aAAqB;IAChC,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAU;IACpC,QAAQ,CAAC,KAAK,cAAc;IAG5B,YAAY,OAAO,GAAE,oBAAyB,EAE7C;IAEK,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC,CAKlC;IAEK,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAS1D;CACF"}
@@ -0,0 +1,33 @@
1
+ import { TERMINAL_PROVIDER } from "@termlink/protocol";
2
+ import { createTerminal, defaultShell, ptyStatus } from "@termlink/terminal";
3
+ /**
4
+ * The terminal provider: opens the user's shell in a PTY, like an ssh login. Its
5
+ * availability is whether this platform has a PTY binary; nothing else to check.
6
+ */
7
+ export class ShellProvider {
8
+ id = TERMINAL_PROVIDER;
9
+ kind = "terminal";
10
+ label = "Terminal";
11
+ #options;
12
+ constructor(options = {}) {
13
+ this.#options = options;
14
+ }
15
+ async probe() {
16
+ const status = ptyStatus();
17
+ if (!status.available)
18
+ return { available: false, version: null, detail: status.detail };
19
+ const shell = this.#options.shell ?? defaultShell().file;
20
+ return { available: true, version: null, detail: shell };
21
+ }
22
+ async open(options) {
23
+ return createTerminal({
24
+ shell: this.#options.shell,
25
+ args: this.#options.args,
26
+ scrollback: this.#options.scrollback,
27
+ cwd: options.cwd,
28
+ cols: options.cols,
29
+ rows: options.rows,
30
+ });
31
+ }
32
+ }
33
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/providers/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAiB,MAAM,oBAAoB,CAAC;AAY5F;;;GAGG;AACH,MAAM,OAAO,aAAa;IACf,EAAE,GAAG,iBAAiB,CAAC;IACvB,IAAI,GAAG,UAAmB,CAAC;IAC3B,KAAK,GAAG,UAAU,CAAC;IACnB,QAAQ,CAAuB;IAExC,YAAY,OAAO,GAAyB,EAAE;QAC5C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,MAAM,CAAC,SAAS;YAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QACzF,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,YAAY,EAAE,CAAC,IAAI,CAAC;QACzD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAA4B;QACrC,OAAO,cAAc,CAAC;YACpB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;YAC1B,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;YACxB,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU;YACpC,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,72 @@
1
+ import type { DecisionEffect, EventPayload, InputRequest, Item, ProviderId, ProviderStatus, UserInput } from "@termlink/protocol";
2
+ import type { Terminal } from "@termlink/terminal";
3
+ export type { UserInput };
4
+ /** What a probe reports; the manager adds the id, kind and label. */
5
+ export type ProbeResult = Pick<ProviderStatus, "available" | "version" | "detail">;
6
+ /** Session events an agent provider may emit. Lifecycle and input events belong to the host. */
7
+ export type ProviderEventType = "turn.started" | "turn.completed" | "item.started" | "item.delta" | "item.updated" | "item.completed" | "error" | "provider.event";
8
+ export interface InputResponse {
9
+ decisionId: string | null;
10
+ effect: DecisionEffect;
11
+ answers?: Record<string, string>;
12
+ }
13
+ /** How a provider talks back to the host session that owns it. */
14
+ export interface EventSink {
15
+ emit<T extends ProviderEventType>(type: T, payload: EventPayload<T>): void;
16
+ /**
17
+ * Blocks until a client answers. Rejects with the signal's reason if the signal aborts;
18
+ * resolves with effect "cancel" if the session closes first.
19
+ */
20
+ requestInput(request: Omit<InputRequest, "requestId">, signal?: AbortSignal): Promise<InputResponse>;
21
+ setProviderSessionId(id: string): void;
22
+ }
23
+ export interface StartOptions {
24
+ sessionId: string;
25
+ cwd: string;
26
+ /** Provider session or thread to resume instead of starting fresh. */
27
+ resumeProviderSessionId?: string;
28
+ }
29
+ export interface ProviderSession {
30
+ /** Resolves once the turn is accepted. The turn itself runs on and reports through the sink. */
31
+ send(input: UserInput): Promise<void>;
32
+ /** Resolves after the running turn has emitted turn.completed. */
33
+ interrupt(): Promise<void>;
34
+ close(): Promise<void>;
35
+ }
36
+ /** One finished turn read back from the provider's own transcript. The first item is the user message. */
37
+ export interface HistoryTurn {
38
+ turnId: string;
39
+ status: "completed" | "interrupted" | "failed";
40
+ items: Item[];
41
+ }
42
+ /** A coding agent: turns, items and approvals as JSON. Claude and Codex. */
43
+ export interface ProviderAdapter {
44
+ readonly id: ProviderId;
45
+ readonly kind: "agent";
46
+ /** What to call it on screen. */
47
+ readonly label: string;
48
+ /** Sessions can be resumed after a host restart by their providerSessionId. */
49
+ readonly resumable?: boolean;
50
+ probe(): Promise<ProbeResult>;
51
+ start(options: StartOptions, sink: EventSink): Promise<ProviderSession>;
52
+ /** Recent turns of a stored session, oldest first. */
53
+ history?(providerSessionId: string, cwd: string): Promise<HistoryTurn[]>;
54
+ /** Releases shared resources such as a long-lived child process. */
55
+ dispose?(): Promise<void>;
56
+ }
57
+ export interface OpenTerminalOptions {
58
+ sessionId: string;
59
+ cwd: string;
60
+ cols: number;
61
+ rows: number;
62
+ }
63
+ /** A shell in a PTY: bytes in, bytes out. Nothing to resume after a restart. */
64
+ export interface TerminalProvider {
65
+ readonly id: ProviderId;
66
+ readonly kind: "terminal";
67
+ readonly label: string;
68
+ probe(): Promise<ProbeResult>;
69
+ open(options: OpenTerminalOptions): Promise<Terminal>;
70
+ }
71
+ export type HostProvider = ProviderAdapter | TerminalProvider;
72
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ export type Fetch = typeof fetch;
2
+ export declare class RelayHttpError extends Error {
3
+ readonly status: number;
4
+ constructor(status: number, message: string);
5
+ }
6
+ /** wss://host:9000 -> https://host:9000 */
7
+ export declare function httpBase(server: string): string;
8
+ /** Picks the edge relay with the lowest /health latency, or the master when there are none. */
9
+ export declare function pickRelay(server: string, fetchFn: Fetch): Promise<string>;
10
+ /** Exchanges the device token for a host token bound to one relay session. */
11
+ export declare function registerHost(server: string, deviceToken: string, session: string, fetchFn: Fetch): Promise<string>;
12
+ export declare function unregisterHost(server: string, hostToken: string, session: string, fetchFn: Fetch): Promise<void>;
13
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/relay/api.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC;AAEjC,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAI1C;CACF;AAED,2CAA2C;AAC3C,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/C;AAID,+FAA+F;AAC/F,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAkB/E;AAgBD,8EAA8E;AAC9E,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAWxH;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtH"}
@@ -0,0 +1,75 @@
1
+ // HTTP calls to the TermLink master relay, matching internal/ptyhost/relay.go.
2
+ export class RelayHttpError extends Error {
3
+ status;
4
+ constructor(status, message) {
5
+ super(message);
6
+ this.name = "RelayHttpError";
7
+ this.status = status;
8
+ }
9
+ }
10
+ /** wss://host:9000 -> https://host:9000 */
11
+ export function httpBase(server) {
12
+ return server.trim().replace(/^ws(s?):\/\//i, "http$1://").replace(/\/+$/, "");
13
+ }
14
+ const trimSlash = (url) => url.trim().replace(/\/+$/, "");
15
+ /** Picks the edge relay with the lowest /health latency, or the master when there are none. */
16
+ export async function pickRelay(server, fetchFn) {
17
+ let relays = [];
18
+ try {
19
+ const res = await fetchFn(`${httpBase(server)}/relays`, { signal: AbortSignal.timeout(8_000) });
20
+ if (res.ok)
21
+ relays = await res.json();
22
+ }
23
+ catch {
24
+ // Fall back to the master.
25
+ }
26
+ const candidates = Array.isArray(relays)
27
+ ? relays.filter((r) => typeof r === "object" && r !== null && typeof r.url === "string")
28
+ : [];
29
+ if (candidates.length === 0)
30
+ return trimSlash(server);
31
+ const timed = await Promise.all(candidates.map(async (r) => ({ url: r.url, ms: await bestPing(r.url, fetchFn) })));
32
+ const best = timed
33
+ .filter((t) => t.ms !== null)
34
+ .sort((a, b) => a.ms - b.ms)[0];
35
+ return trimSlash(best?.url ?? server);
36
+ }
37
+ async function bestPing(url, fetchFn) {
38
+ let best = null;
39
+ for (let i = 0; i < 3; i++) {
40
+ const start = performance.now();
41
+ try {
42
+ const res = await fetchFn(`${httpBase(url)}/health`, { signal: AbortSignal.timeout(2_000) });
43
+ if (res.ok)
44
+ best = Math.min(best ?? Infinity, performance.now() - start);
45
+ }
46
+ catch {
47
+ // Unreachable this time.
48
+ }
49
+ }
50
+ return best;
51
+ }
52
+ /** Exchanges the device token for a host token bound to one relay session. */
53
+ export async function registerHost(server, deviceToken, session, fetchFn) {
54
+ const res = await fetchFn(`${httpBase(server)}/register`, {
55
+ method: "POST",
56
+ headers: { authorization: `Bearer ${deviceToken}`, "content-type": "application/json" },
57
+ body: JSON.stringify({ session }),
58
+ signal: AbortSignal.timeout(15_000),
59
+ });
60
+ if (!res.ok)
61
+ throw new RelayHttpError(res.status, (await res.text()).trim() || res.statusText);
62
+ const body = (await res.json());
63
+ if (typeof body.host_token !== "string")
64
+ throw new Error("the relay returned no host token");
65
+ return body.host_token;
66
+ }
67
+ export async function unregisterHost(server, hostToken, session, fetchFn) {
68
+ await fetchFn(`${httpBase(server)}/register`, {
69
+ method: "DELETE",
70
+ headers: { authorization: `Bearer ${hostToken}`, "content-type": "application/json" },
71
+ body: JSON.stringify({ session }),
72
+ signal: AbortSignal.timeout(3_000),
73
+ });
74
+ }
75
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/relay/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type Fetch } from "./api.js";
2
+ /**
3
+ * The TermLink device credential written by `termlink login` (auth/login.ts). Field
4
+ * names follow the Go CLI's internal/device/device.go, so a machine signed in with the
5
+ * old CLI stays signed in. Unknown fields are kept when the file is rewritten.
6
+ */
7
+ export interface DeviceCredential {
8
+ token: string;
9
+ id: string;
10
+ sub: string;
11
+ email?: string;
12
+ name?: string;
13
+ expires_at: string;
14
+ master: string;
15
+ [field: string]: unknown;
16
+ }
17
+ /** A problem only the user can fix, by signing in again. */
18
+ export declare class DeviceError extends Error {
19
+ constructor(message: string);
20
+ }
21
+ export declare function defaultCredentialPath(): string;
22
+ export declare function loadDevice(file: string, server: string, now?: number): Promise<DeviceCredential>;
23
+ /** Renews the device token when less than 30 days are left, like the Go CLI does at startup. */
24
+ export declare function renewIfDue(file: string, server: string, credential: DeviceCredential, fetchFn: Fetch, now?: number): Promise<DeviceCredential>;
25
+ export declare function saveDevice(file: string, credential: DeviceCredential): Promise<void>;
26
+ //# sourceMappingURL=device.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/relay/device.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,4DAA4D;AAC5D,qBAAa,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAID,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAID,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuB1G;AAED,gGAAgG;AAChG,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,gBAAgB,EAC5B,OAAO,EAAE,KAAK,EACd,GAAG,SAAa,GACf,OAAO,CAAC,gBAAgB,CAAC,CA4B3B;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1F"}