@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,353 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { setTimeout as sleep } from "node:timers/promises";
3
+ import { applyDelta } from "@termlink/protocol";
4
+ import { HostError } from "../../errors.js";
5
+ import { VERSION } from "../../version.js";
6
+ import { InputQueue } from "./input-queue.js";
7
+ import { completeToolItem, mapToolUse } from "./mapper.js";
8
+ const INTERRUPT_TIMEOUT_MS = 10_000;
9
+ /**
10
+ * One long-lived Claude Code session in streaming-input mode. Each send() pushes a
11
+ * user message; the turn ends at the matching result message.
12
+ */
13
+ export class ClaudeSession {
14
+ sessionId;
15
+ #sink;
16
+ #cwd;
17
+ #input = new InputQueue();
18
+ #query;
19
+ /** Items still in progress, by id: streamed text/thinking blocks and tool uses. */
20
+ #items = new Map();
21
+ /** Streamed block item ids per message and kind, in order, to pair with the full assistant message. */
22
+ #streamed = new Map();
23
+ #blockIds = new Map();
24
+ #declined = new Set();
25
+ #requests = new Set();
26
+ #messageId = null;
27
+ #turnId = null;
28
+ #turnCount = 0;
29
+ #turnWaiters = [];
30
+ #interrupting = false;
31
+ #closing = false;
32
+ #dead = null;
33
+ #costSoFar = 0;
34
+ constructor(sink, options) {
35
+ this.#sink = sink;
36
+ this.#cwd = options.cwd;
37
+ this.sessionId = options.resume ?? randomUUID();
38
+ this.#query = options.queryFn({
39
+ prompt: this.#input,
40
+ options: {
41
+ cwd: options.cwd,
42
+ includePartialMessages: true,
43
+ canUseTool: (tool, input, opts) => this.#canUseTool(tool, input, opts),
44
+ env: { ...process.env, CLAUDE_AGENT_SDK_CLIENT_APP: `termlink-node/${VERSION}` },
45
+ ...(options.resume ? { resume: options.resume } : { sessionId: this.sessionId }),
46
+ ...(options.model ? { model: options.model } : {}),
47
+ ...(options.permissionMode ? { permissionMode: options.permissionMode } : {}),
48
+ ...(options.executable ? { pathToClaudeCodeExecutable: options.executable } : {}),
49
+ },
50
+ });
51
+ void this.#consume();
52
+ }
53
+ async send(input) {
54
+ if (this.#dead)
55
+ throw new HostError("conflict", `claude session ended: ${this.#dead.message}`);
56
+ if (this.#turnId)
57
+ throw new HostError("conflict", "a turn is already running");
58
+ const turnId = `turn_${++this.#turnCount}`;
59
+ this.#turnId = turnId;
60
+ this.#interrupting = false;
61
+ this.#sink.emit("turn.started", { turnId });
62
+ this.#input.push({ type: "user", message: { role: "user", content: input.text }, parent_tool_use_id: null });
63
+ }
64
+ async interrupt() {
65
+ const turnId = this.#turnId;
66
+ if (!turnId)
67
+ return;
68
+ this.#interrupting = true;
69
+ for (const abort of this.#requests)
70
+ abort.abort();
71
+ const done = new Promise((resolve) => this.#turnWaiters.push(resolve));
72
+ await this.#query.interrupt().catch(() => undefined);
73
+ await Promise.race([done, sleep(INTERRUPT_TIMEOUT_MS)]);
74
+ if (this.#turnId === turnId)
75
+ this.#completeTurn("interrupted");
76
+ }
77
+ async close() {
78
+ await this.interrupt();
79
+ this.#closing = true;
80
+ this.#input.end();
81
+ this.#query.close();
82
+ }
83
+ async #consume() {
84
+ try {
85
+ for await (const message of this.#query)
86
+ this.#handle(message);
87
+ this.#end(new Error("claude process exited"));
88
+ }
89
+ catch (err) {
90
+ this.#end(err instanceof Error ? err : new Error(String(err)));
91
+ }
92
+ }
93
+ #end(reason) {
94
+ if (this.#dead)
95
+ return;
96
+ this.#dead = reason;
97
+ if (this.#closing || !this.#turnId)
98
+ return;
99
+ this.#sink.emit("error", { code: "claude_exited", message: reason.message });
100
+ this.#completeTurn("failed", reason.message);
101
+ }
102
+ #handle(message) {
103
+ switch (message.type) {
104
+ case "stream_event":
105
+ if (message.parent_tool_use_id === null)
106
+ this.#stream(message.event);
107
+ break;
108
+ case "assistant":
109
+ // Sub-agent internals stay behind the Task tool item that started them.
110
+ if (message.parent_tool_use_id === null)
111
+ this.#assistant(message.message.id, message.message.content);
112
+ break;
113
+ case "user":
114
+ if (!("isReplay" in message && message.isReplay))
115
+ this.#toolResults(message);
116
+ break;
117
+ case "result":
118
+ this.#result(message);
119
+ break;
120
+ case "system":
121
+ if (message.subtype === "compact_boundary")
122
+ this.#sink.emit("provider.event", { name: "claude.compacted", data: {} });
123
+ break;
124
+ }
125
+ }
126
+ #stream(event) {
127
+ switch (event.type) {
128
+ case "message_start":
129
+ this.#messageId = event.message.id;
130
+ this.#blockIds.clear();
131
+ break;
132
+ case "content_block_start": {
133
+ const kind = event.content_block.type === "text" ? "message" : event.content_block.type === "thinking" ? "reasoning" : null;
134
+ if (!kind || !this.#messageId)
135
+ break;
136
+ const id = `${this.#messageId}:${event.index}`;
137
+ this.#blockIds.set(event.index, id);
138
+ this.#pushStreamed(this.#messageId, kind, id);
139
+ // Thinking may be omitted entirely, so its item starts with the first delta.
140
+ if (kind === "message")
141
+ this.#start({ id, kind: "message", role: "assistant", text: "", status: "in_progress" });
142
+ break;
143
+ }
144
+ case "content_block_delta": {
145
+ const id = this.#blockIds.get(event.index);
146
+ if (!id)
147
+ break;
148
+ if (event.delta.type === "text_delta" && event.delta.text)
149
+ this.#delta(id, event.delta.text);
150
+ if (event.delta.type === "thinking_delta" && event.delta.thinking) {
151
+ if (!this.#items.has(id))
152
+ this.#start({ id, kind: "reasoning", text: "", status: "in_progress" });
153
+ this.#delta(id, event.delta.thinking);
154
+ }
155
+ break;
156
+ }
157
+ }
158
+ }
159
+ #assistant(messageId, blocks) {
160
+ for (const block of blocks) {
161
+ if (block.type === "text") {
162
+ const { text } = block;
163
+ const id = this.#takeStreamed(messageId, "message") ?? `${messageId}:${randomUUID()}`;
164
+ this.#complete({ id, kind: "message", role: "assistant", text, status: "completed" });
165
+ }
166
+ else if (block.type === "thinking") {
167
+ const { thinking } = block;
168
+ const id = this.#takeStreamed(messageId, "reasoning");
169
+ if (id && this.#items.has(id))
170
+ this.#complete({ id, kind: "reasoning", text: thinking, status: "completed" });
171
+ else if (thinking)
172
+ this.#complete({ id: id ?? `${messageId}:${randomUUID()}`, kind: "reasoning", text: thinking, status: "completed" });
173
+ }
174
+ else if (block.type === "tool_use") {
175
+ const { id, name, input } = block;
176
+ this.#start(mapToolUse(id, name, input, this.#cwd));
177
+ }
178
+ }
179
+ }
180
+ #toolResults(message) {
181
+ const { content } = message.message;
182
+ if (!Array.isArray(content))
183
+ return;
184
+ const results = content.filter((b) => b.type === "tool_result");
185
+ const structured = results.length === 1 && "tool_use_result" in message ? message.tool_use_result : undefined;
186
+ for (const result of results) {
187
+ const item = this.#items.get(result.tool_use_id);
188
+ if (!item)
189
+ continue;
190
+ this.#complete(completeToolItem(item, result, structured, this.#declined.has(result.tool_use_id)));
191
+ }
192
+ }
193
+ #result(message) {
194
+ if (!this.#turnId)
195
+ return;
196
+ const failed = message.subtype !== "success" || message.is_error;
197
+ const status = this.#interrupting ? "interrupted" : failed ? "failed" : "completed";
198
+ const error = status !== "failed"
199
+ ? undefined
200
+ : message.subtype === "success"
201
+ ? message.result
202
+ : message.errors.join("; ") || message.subtype;
203
+ const { usage } = message;
204
+ const turnUsage = {
205
+ inputTokens: usage.input_tokens + (usage.cache_read_input_tokens ?? 0) + (usage.cache_creation_input_tokens ?? 0),
206
+ outputTokens: usage.output_tokens,
207
+ // total_cost_usd is cumulative for the session.
208
+ costUsd: Math.max(0, message.total_cost_usd - this.#costSoFar),
209
+ };
210
+ this.#costSoFar = message.total_cost_usd;
211
+ this.#completeTurn(status, error, turnUsage);
212
+ }
213
+ #completeTurn(status, error, usage) {
214
+ const turnId = this.#turnId;
215
+ if (!turnId)
216
+ return;
217
+ for (const item of this.#items.values()) {
218
+ this.#sink.emit("item.completed", { turnId, item: { ...item, status: status === "completed" ? "completed" : "interrupted" } });
219
+ }
220
+ this.#items.clear();
221
+ this.#streamed.clear();
222
+ this.#blockIds.clear();
223
+ this.#declined.clear();
224
+ this.#turnId = null;
225
+ this.#sink.emit("turn.completed", { turnId, status, ...(usage ? { usage } : {}), ...(error ? { error } : {}) });
226
+ for (const resolve of this.#turnWaiters.splice(0))
227
+ resolve();
228
+ }
229
+ #start(item) {
230
+ this.#items.set(item.id, item);
231
+ this.#sink.emit("item.started", { turnId: this.#turnId, item });
232
+ }
233
+ #complete(item) {
234
+ this.#items.delete(item.id);
235
+ this.#sink.emit("item.completed", { turnId: this.#turnId, item });
236
+ }
237
+ #delta(itemId, delta) {
238
+ const item = this.#items.get(itemId);
239
+ if (!item)
240
+ return;
241
+ this.#items.set(itemId, applyDelta(item, "text", delta));
242
+ this.#sink.emit("item.delta", { itemId, field: "text", delta });
243
+ }
244
+ #pushStreamed(messageId, kind, id) {
245
+ const key = `${messageId}:${kind}`;
246
+ const ids = this.#streamed.get(key) ?? [];
247
+ ids.push(id);
248
+ this.#streamed.set(key, ids);
249
+ }
250
+ #takeStreamed(messageId, kind) {
251
+ return this.#streamed.get(`${messageId}:${kind}`)?.shift();
252
+ }
253
+ async #canUseTool(tool, input, options) {
254
+ const abort = new AbortController();
255
+ const onAbort = () => abort.abort();
256
+ options.signal.addEventListener("abort", onAbort, { once: true });
257
+ this.#requests.add(abort);
258
+ try {
259
+ if (tool === "AskUserQuestion")
260
+ return await this.#askQuestions(input, abort.signal);
261
+ if (tool === "ExitPlanMode")
262
+ return await this.#approvePlan(input, abort.signal);
263
+ return await this.#approveTool(tool, input, options, abort.signal);
264
+ }
265
+ catch {
266
+ return { behavior: "deny", message: "The request was cancelled.", interrupt: true };
267
+ }
268
+ finally {
269
+ this.#requests.delete(abort);
270
+ options.signal.removeEventListener("abort", onAbort);
271
+ }
272
+ }
273
+ async #approveTool(tool, input, options, signal) {
274
+ // The tool_use item was mapped already; its kind says whether this is a shell command or a file edit.
275
+ const item = this.#items.get(options.toolUseID) ?? mapToolUse(options.toolUseID, tool, input, this.#cwd);
276
+ const command = item.kind === "command" ? item.command : undefined;
277
+ const changes = item.kind === "file_change" ? item.changes : undefined;
278
+ const kind = command !== undefined ? "command_approval" : changes ? "file_approval" : "tool_approval";
279
+ const offerSession = (options.suggestions?.length ?? 0) > 0 && !options.suppressAlwaysAllowRule;
280
+ const decisions = [
281
+ { id: "allow", label: "Allow", effect: "allow" },
282
+ ...(offerSession ? [{ id: "allow_session", label: "Allow for this session", effect: "allow_session" }] : []),
283
+ { id: "deny", label: "Deny", effect: "deny" },
284
+ { id: "stop", label: "Deny and stop", effect: "cancel" },
285
+ ];
286
+ const body = options.decisionReason ?? options.description;
287
+ const request = {
288
+ kind,
289
+ itemId: options.toolUseID,
290
+ title: options.title ?? (command !== undefined ? "Run command?" : `Allow ${options.displayName ?? tool}?`),
291
+ ...(body ? { body } : {}),
292
+ ...(command !== undefined ? { command, cwd: this.#cwd } : {}),
293
+ ...(changes ? { changes } : {}),
294
+ ...(kind === "tool_approval" ? { toolName: tool, toolInput: input } : {}),
295
+ decisions,
296
+ };
297
+ const answer = await this.#sink.requestInput(request, signal);
298
+ if (answer.effect === "allow")
299
+ return { behavior: "allow", updatedInput: input };
300
+ if (answer.effect === "allow_session") {
301
+ return { behavior: "allow", updatedInput: input, updatedPermissions: options.suggestions ?? [] };
302
+ }
303
+ this.#declined.add(options.toolUseID);
304
+ return {
305
+ behavior: "deny",
306
+ message: "The user denied this action.",
307
+ ...(answer.effect === "cancel" ? { interrupt: true } : {}),
308
+ };
309
+ }
310
+ async #askQuestions(input, signal) {
311
+ const questions = Array.isArray(input.questions) ? input.questions : [];
312
+ const answer = await this.#sink.requestInput({
313
+ kind: "question",
314
+ title: questions.length === 1 && questions[0] ? questions[0].question : "Claude has some questions",
315
+ questions: questions.map((q, i) => ({
316
+ id: String(i),
317
+ question: q.question,
318
+ options: q.options.map((o) => (o.description ? { label: o.label, description: o.description } : { label: o.label })),
319
+ multiSelect: q.multiSelect === true,
320
+ })),
321
+ decisions: [
322
+ { id: "submit", label: "Submit", effect: "allow" },
323
+ { id: "skip", label: "Skip", effect: "deny" },
324
+ ],
325
+ }, signal);
326
+ if (answer.effect !== "allow")
327
+ return { behavior: "deny", message: "The user skipped the question." };
328
+ // Claude expects answers keyed by question text; multi-select answers are comma-separated.
329
+ const answers = {};
330
+ questions.forEach((q, i) => {
331
+ const value = answer.answers?.[String(i)];
332
+ if (value)
333
+ answers[q.question] = value;
334
+ });
335
+ return { behavior: "allow", updatedInput: { ...input, answers } };
336
+ }
337
+ async #approvePlan(input, signal) {
338
+ const plan = typeof input.plan === "string" ? input.plan : undefined;
339
+ const answer = await this.#sink.requestInput({
340
+ kind: "plan_approval",
341
+ title: "Approve the plan?",
342
+ ...(plan ? { body: plan } : {}),
343
+ decisions: [
344
+ { id: "approve", label: "Approve", effect: "allow" },
345
+ { id: "keep_planning", label: "Keep planning", effect: "deny" },
346
+ ],
347
+ }, signal);
348
+ return answer.effect === "allow"
349
+ ? { behavior: "allow", updatedInput: input }
350
+ : { behavior: "deny", message: "The user wants to keep planning." };
351
+ }
352
+ }
353
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/providers/claude/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { CodexCommand } from "./command.js";
2
+ import type { RequestId } from "./protocol.js";
3
+ import { JsonRpcPeer } from "./rpc.js";
4
+ /** Receives the notifications and server requests that belong to one thread. */
5
+ export interface ThreadHandler {
6
+ notification(method: string, params: unknown): void;
7
+ request(method: string, params: unknown, id: RequestId): Promise<unknown>;
8
+ /** The app-server went away. */
9
+ closed(reason: Error): void;
10
+ }
11
+ /**
12
+ * One long-lived `codex app-server` process shared by every Codex session on this host.
13
+ * Routes notifications and server requests to threads by their threadId.
14
+ */
15
+ export declare class CodexAppServer {
16
+ #private;
17
+ readonly peer: JsonRpcPeer;
18
+ private constructor();
19
+ static start(command: CodexCommand, onExit: (reason: Error) => void): Promise<CodexAppServer>;
20
+ register(threadId: string, handler: ThreadHandler): void;
21
+ unregister(threadId: string): void;
22
+ close(): void;
23
+ }
24
+ //# sourceMappingURL=app-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-server.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/app-server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAwC,SAAS,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,WAAW,EAAY,MAAM,UAAU,CAAC;AAEjD,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,gCAAgC;IAChC,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC;CAC7B;AAED;;;GAGG;AACH,qBAAa,cAAc;;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAM3B,OAAO,eA0BN;IAED,OAAa,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAgBlG;IAED,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAEvD;IAED,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEjC;IAED,KAAK,IAAI,IAAI,CAKZ;CAMF"}
@@ -0,0 +1,79 @@
1
+ import { spawn } from "node:child_process";
2
+ import { VERSION } from "../../version.js";
3
+ import { JsonRpcPeer, RpcError } from "./rpc.js";
4
+ /**
5
+ * One long-lived `codex app-server` process shared by every Codex session on this host.
6
+ * Routes notifications and server requests to threads by their threadId.
7
+ */
8
+ export class CodexAppServer {
9
+ peer;
10
+ #child;
11
+ #threads = new Map();
12
+ #stderrTail = [];
13
+ #onExit = () => { };
14
+ constructor(child) {
15
+ this.#child = child;
16
+ this.peer = new JsonRpcPeer(child.stdout, child.stdin);
17
+ this.peer.onNotification = (method, params) => this.#threadFor(params)?.notification(method, params);
18
+ this.peer.onRequest = async (method, params, id) => {
19
+ const thread = this.#threadFor(params);
20
+ if (!thread)
21
+ throw new RpcError(-32601, `${method} has no thread on this client`);
22
+ return thread.request(method, params, id);
23
+ };
24
+ this.peer.onClose = (reason) => {
25
+ for (const thread of this.#threads.values())
26
+ thread.closed(reason);
27
+ this.#threads.clear();
28
+ this.#onExit(reason);
29
+ };
30
+ child.stdin.on("error", () => { });
31
+ child.stderr.setEncoding("utf8");
32
+ child.stderr.on("data", (chunk) => {
33
+ this.#stderrTail.push(...chunk.split(/\r?\n/).filter(Boolean));
34
+ this.#stderrTail.splice(0, Math.max(0, this.#stderrTail.length - 20));
35
+ });
36
+ child.on("error", (err) => this.peer.close(err));
37
+ child.on("exit", (code, signal) => {
38
+ const tail = this.#stderrTail.at(-1);
39
+ this.peer.close(new Error(`codex app-server exited (${signal ?? code})${tail ? `: ${tail}` : ""}`));
40
+ });
41
+ }
42
+ static async start(command, onExit) {
43
+ const child = spawn(command.file, [...command.args, "app-server"], { stdio: "pipe", windowsHide: true });
44
+ const server = new CodexAppServer(child);
45
+ server.#onExit = onExit;
46
+ try {
47
+ const params = {
48
+ clientInfo: { name: "termlink_host", title: "TermLink", version: VERSION },
49
+ capabilities: { experimentalApi: false, requestAttestation: false },
50
+ };
51
+ await server.peer.request("initialize", params);
52
+ server.peer.notify("initialized");
53
+ }
54
+ catch (err) {
55
+ server.close();
56
+ throw err;
57
+ }
58
+ return server;
59
+ }
60
+ register(threadId, handler) {
61
+ this.#threads.set(threadId, handler);
62
+ }
63
+ unregister(threadId) {
64
+ this.#threads.delete(threadId);
65
+ }
66
+ close() {
67
+ this.#onExit = () => { };
68
+ this.peer.close(new Error("codex app-server closed by host"));
69
+ this.#child.stdin.end();
70
+ if (this.#child.exitCode === null)
71
+ this.#child.kill();
72
+ }
73
+ #threadFor(params) {
74
+ if (typeof params !== "object" || params === null || !("threadId" in params))
75
+ return undefined;
76
+ return typeof params.threadId === "string" ? this.#threads.get(params.threadId) : undefined;
77
+ }
78
+ }
79
+ //# sourceMappingURL=app-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-server.js","sourceRoot":"","sources":["../../../src/providers/codex/app-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /** How to launch codex: `file ...args <subcommand>`. */
2
+ export interface CodexCommand {
3
+ file: string;
4
+ args: string[];
5
+ }
6
+ /**
7
+ * Finds the codex the user already installed. Inside an npm install it returns the native
8
+ * binary rather than the codex.js launcher: on Windows, killing the launcher would leave the
9
+ * native process running.
10
+ */
11
+ export declare function resolveCodexCommand(env?: NodeJS.ProcessEnv): CodexCommand | null;
12
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/command.ts"],"names":[],"mappings":"AAIA,wDAAwD;AACxD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAWD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,YAAY,GAAG,IAAI,CAc7F"}
@@ -0,0 +1,60 @@
1
+ import { existsSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import path from "node:path";
4
+ const TARGET_TRIPLES = {
5
+ "win32-x64": "x86_64-pc-windows-msvc",
6
+ "win32-arm64": "aarch64-pc-windows-msvc",
7
+ "darwin-x64": "x86_64-apple-darwin",
8
+ "darwin-arm64": "aarch64-apple-darwin",
9
+ "linux-x64": "x86_64-unknown-linux-musl",
10
+ "linux-arm64": "aarch64-unknown-linux-musl",
11
+ };
12
+ /**
13
+ * Finds the codex the user already installed. Inside an npm install it returns the native
14
+ * binary rather than the codex.js launcher: on Windows, killing the launcher would leave the
15
+ * native process running.
16
+ */
17
+ export function resolveCodexCommand(env = process.env) {
18
+ const override = env.TERMLINK_CODEX_PATH;
19
+ if (override) {
20
+ return override.endsWith(".js") ? { file: process.execPath, args: [override] } : { file: override, args: [] };
21
+ }
22
+ const exe = process.platform === "win32" ? "codex.exe" : "codex";
23
+ const dirs = (env.PATH ?? env.Path ?? "").split(path.delimiter).filter(Boolean);
24
+ for (const dir of dirs) {
25
+ const native = nativeBinaryNear(dir);
26
+ if (native)
27
+ return { file: native, args: [] };
28
+ const direct = path.join(dir, exe);
29
+ if (existsSync(direct))
30
+ return { file: direct, args: [] };
31
+ }
32
+ return null;
33
+ }
34
+ // npm puts global packages in <prefix>/node_modules on Windows and <prefix>/lib/node_modules
35
+ // elsewhere, with the shims in <prefix> and <prefix>/bin respectively.
36
+ function nativeBinaryNear(dir) {
37
+ const triple = TARGET_TRIPLES[`${process.platform}-${process.arch}`];
38
+ if (!triple)
39
+ return null;
40
+ const platformPackage = `@openai/codex-${process.platform}-${process.arch}`;
41
+ const candidates = [
42
+ path.join(dir, "node_modules", "@openai", "codex", "package.json"),
43
+ path.join(dir, "..", "lib", "node_modules", "@openai", "codex", "package.json"),
44
+ ];
45
+ for (const codexPackageJson of candidates) {
46
+ if (!existsSync(codexPackageJson))
47
+ continue;
48
+ try {
49
+ const platformPackageJson = createRequire(codexPackageJson).resolve(`${platformPackage}/package.json`);
50
+ const binary = path.join(path.dirname(platformPackageJson), "vendor", triple, "bin", process.platform === "win32" ? "codex.exe" : "codex");
51
+ if (existsSync(binary))
52
+ return binary;
53
+ }
54
+ catch {
55
+ // Platform package missing; fall back to whatever is on PATH.
56
+ }
57
+ }
58
+ return null;
59
+ }
60
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/providers/codex/command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { HistoryTurn } from "../types.js";
2
+ import type { CodexAppServer } from "./app-server.js";
3
+ /** Recent finished turns of a stored thread, oldest first, read with thread/turns/list. */
4
+ export declare function codexHistory(server: CodexAppServer, threadId: string, maxTurns?: number): Promise<HistoryTurn[]>;
5
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/history.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAItD,2FAA2F;AAC3F,wBAAsB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAqBlH"}
@@ -0,0 +1,33 @@
1
+ import { mapItem } from "./mapper.js";
2
+ /** Recent finished turns of a stored thread, oldest first, read with thread/turns/list. */
3
+ export async function codexHistory(server, threadId, maxTurns = 30) {
4
+ const { data } = await server.peer.request("thread/turns/list", {
5
+ threadId,
6
+ sortDirection: "desc",
7
+ itemsView: "full",
8
+ limit: maxTurns,
9
+ });
10
+ const turns = [];
11
+ for (const turn of [...data].reverse()) {
12
+ if (turn.status === "inProgress")
13
+ continue;
14
+ const items = (turn.items ?? []).flatMap((item) => {
15
+ if (item.type === "userMessage") {
16
+ const text = userText(item);
17
+ return text ? [{ id: item.id, kind: "message", role: "user", text, status: "completed" }] : [];
18
+ }
19
+ const mapped = mapItem(item, "completed");
20
+ return mapped ? [mapped] : [];
21
+ });
22
+ turns.push({ turnId: turn.id, status: turn.status, items });
23
+ }
24
+ return turns;
25
+ }
26
+ function userText(item) {
27
+ const content = item.content ?? [];
28
+ return content
29
+ .filter((c) => c.type === "text")
30
+ .map((c) => c.text ?? "")
31
+ .join("\n");
32
+ }
33
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../../src/providers/codex/history.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,2FAA2F;AAC3F,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAsB,EAAE,QAAgB,EAAE,QAAQ,GAAG,EAAE;IACxF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAmB,mBAAmB,EAAE;QAChF,QAAQ;QACR,aAAa,EAAE,MAAM;QACrB,SAAS,EAAE,MAAM;QACjB,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IACH,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY;YAAE,SAAS;QAC3C,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAU,EAAE;YACxD,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC5B,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjG,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC1C,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,IAAgB;IAChC,MAAM,OAAO,GAAI,IAAyD,CAAC,OAAO,IAAI,EAAE,CAAC;IACzF,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}