@mquan/portal 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +168 -0
  2. package/dist/src/api.d.ts +5 -0
  3. package/dist/src/api.js +357 -0
  4. package/dist/src/api.js.map +1 -0
  5. package/dist/src/cli.d.ts +17 -0
  6. package/dist/src/cli.js +618 -0
  7. package/dist/src/cli.js.map +1 -0
  8. package/dist/src/daemon-lifecycle.d.ts +24 -0
  9. package/dist/src/daemon-lifecycle.js +107 -0
  10. package/dist/src/daemon-lifecycle.js.map +1 -0
  11. package/dist/src/daemon.d.ts +17 -0
  12. package/dist/src/daemon.js +90 -0
  13. package/dist/src/daemon.js.map +1 -0
  14. package/dist/src/doctor.d.ts +14 -0
  15. package/dist/src/doctor.js +51 -0
  16. package/dist/src/doctor.js.map +1 -0
  17. package/dist/src/entrypoint.d.ts +2 -0
  18. package/dist/src/entrypoint.js +14 -0
  19. package/dist/src/entrypoint.js.map +1 -0
  20. package/dist/src/index.d.ts +5 -0
  21. package/dist/src/index.js +5 -0
  22. package/dist/src/index.js.map +1 -0
  23. package/dist/src/launch.d.ts +41 -0
  24. package/dist/src/launch.js +186 -0
  25. package/dist/src/launch.js.map +1 -0
  26. package/dist/src/mcp.d.ts +9 -0
  27. package/dist/src/mcp.js +132 -0
  28. package/dist/src/mcp.js.map +1 -0
  29. package/dist/src/network/client.d.ts +67 -0
  30. package/dist/src/network/client.js +540 -0
  31. package/dist/src/network/client.js.map +1 -0
  32. package/dist/src/network/coordinator.d.ts +83 -0
  33. package/dist/src/network/coordinator.js +225 -0
  34. package/dist/src/network/coordinator.js.map +1 -0
  35. package/dist/src/network/protocol.d.ts +1352 -0
  36. package/dist/src/network/protocol.js +360 -0
  37. package/dist/src/network/protocol.js.map +1 -0
  38. package/dist/src/network/server.d.ts +28 -0
  39. package/dist/src/network/server.js +474 -0
  40. package/dist/src/network/server.js.map +1 -0
  41. package/dist/src/network/tasks.d.ts +65 -0
  42. package/dist/src/network/tasks.js +276 -0
  43. package/dist/src/network/tasks.js.map +1 -0
  44. package/dist/src/portal-index.d.ts +21 -0
  45. package/dist/src/portal-index.js +140 -0
  46. package/dist/src/portal-index.js.map +1 -0
  47. package/dist/src/provider/claude-managed.d.ts +34 -0
  48. package/dist/src/provider/claude-managed.js +125 -0
  49. package/dist/src/provider/claude-managed.js.map +1 -0
  50. package/dist/src/provider/claude.d.ts +24 -0
  51. package/dist/src/provider/claude.js +114 -0
  52. package/dist/src/provider/claude.js.map +1 -0
  53. package/dist/src/provider/codex/app-server-client.d.ts +43 -0
  54. package/dist/src/provider/codex/app-server-client.js +143 -0
  55. package/dist/src/provider/codex/app-server-client.js.map +1 -0
  56. package/dist/src/provider/codex/index.d.ts +3 -0
  57. package/dist/src/provider/codex/index.js +4 -0
  58. package/dist/src/provider/codex/index.js.map +1 -0
  59. package/dist/src/provider/codex/managed-runner.d.ts +12 -0
  60. package/dist/src/provider/codex/managed-runner.js +162 -0
  61. package/dist/src/provider/codex/managed-runner.js.map +1 -0
  62. package/dist/src/provider/codex/probe.d.ts +2 -0
  63. package/dist/src/provider/codex/probe.js +33 -0
  64. package/dist/src/provider/codex/probe.js.map +1 -0
  65. package/dist/src/provider/codex/protocol.d.ts +193 -0
  66. package/dist/src/provider/codex/protocol.js +10 -0
  67. package/dist/src/provider/codex/protocol.js.map +1 -0
  68. package/dist/src/provider/codex/provider.d.ts +35 -0
  69. package/dist/src/provider/codex/provider.js +289 -0
  70. package/dist/src/provider/codex/provider.js.map +1 -0
  71. package/dist/src/provider/codex/remote-app-server.d.ts +16 -0
  72. package/dist/src/provider/codex/remote-app-server.js +80 -0
  73. package/dist/src/provider/codex/remote-app-server.js.map +1 -0
  74. package/dist/src/provider/codex/websocket-client.d.ts +40 -0
  75. package/dist/src/provider/codex/websocket-client.js +174 -0
  76. package/dist/src/provider/codex/websocket-client.js.map +1 -0
  77. package/dist/src/provider/types.d.ts +35 -0
  78. package/dist/src/provider/types.js +2 -0
  79. package/dist/src/provider/types.js.map +1 -0
  80. package/dist/src/recall/embedding.d.ts +28 -0
  81. package/dist/src/recall/embedding.js +142 -0
  82. package/dist/src/recall/embedding.js.map +1 -0
  83. package/dist/src/recall/types.d.ts +35 -0
  84. package/dist/src/recall/types.js +2 -0
  85. package/dist/src/recall/types.js.map +1 -0
  86. package/dist/src/rpc/client.d.ts +6 -0
  87. package/dist/src/rpc/client.js +58 -0
  88. package/dist/src/rpc/client.js.map +1 -0
  89. package/dist/src/rpc/protocol.d.ts +21 -0
  90. package/dist/src/rpc/protocol.js +11 -0
  91. package/dist/src/rpc/protocol.js.map +1 -0
  92. package/dist/src/rpc/server.d.ts +12 -0
  93. package/dist/src/rpc/server.js +154 -0
  94. package/dist/src/rpc/server.js.map +1 -0
  95. package/dist/src/runtime/paths.d.ts +8 -0
  96. package/dist/src/runtime/paths.js +18 -0
  97. package/dist/src/runtime/paths.js.map +1 -0
  98. package/dist/src/service.d.ts +127 -0
  99. package/dist/src/service.js +637 -0
  100. package/dist/src/service.js.map +1 -0
  101. package/dist/src/session-profile.d.ts +39 -0
  102. package/dist/src/session-profile.js +186 -0
  103. package/dist/src/session-profile.js.map +1 -0
  104. package/dist/src/storage/database.d.ts +9 -0
  105. package/dist/src/storage/database.js +354 -0
  106. package/dist/src/storage/database.js.map +1 -0
  107. package/dist/src/storage/repository.d.ts +275 -0
  108. package/dist/src/storage/repository.js +1291 -0
  109. package/dist/src/storage/repository.js.map +1 -0
  110. package/dist/src/version.d.ts +1 -0
  111. package/dist/src/version.js +2 -0
  112. package/dist/src/version.js.map +1 -0
  113. package/docs/architecture-plan.md +191 -0
  114. package/docs/mvp-plan.md +111 -0
  115. package/docs/remote-demo.md +346 -0
  116. package/package.json +47 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Hand-maintained subset of the Codex app-server protocol used by Portal.
3
+ *
4
+ * The installed Codex CLI can generate the complete version-specific bindings
5
+ * with `codex app-server generate-ts`. Keeping this read-only subset local makes
6
+ * the adapter tolerant of additive protocol changes without vendoring hundreds
7
+ * of generated files.
8
+ */
9
+ export interface InitializeParams {
10
+ clientInfo: {
11
+ name: string;
12
+ title: string;
13
+ version: string;
14
+ };
15
+ capabilities: null;
16
+ }
17
+ export interface InitializeResponse {
18
+ userAgent: string;
19
+ codexHome: string;
20
+ platformFamily: string;
21
+ platformOs: string;
22
+ }
23
+ export type CodexThreadSourceKind = "cli" | "vscode" | "exec" | "appServer" | "subAgent" | "subAgentReview" | "subAgentCompact" | "subAgentThreadSpawn" | "subAgentOther" | "unknown";
24
+ export interface ThreadListParams {
25
+ cursor?: string | null;
26
+ limit?: number | null;
27
+ sortKey?: "created_at" | "updated_at" | "recency_at" | null;
28
+ sortDirection?: "asc" | "desc" | null;
29
+ sourceKinds?: CodexThreadSourceKind[] | null;
30
+ archived?: boolean | null;
31
+ useStateDbOnly?: boolean;
32
+ }
33
+ export interface ThreadLoadedListParams {
34
+ cursor?: string | null;
35
+ limit?: number | null;
36
+ }
37
+ export interface ThreadReadParams {
38
+ threadId: string;
39
+ includeTurns?: boolean;
40
+ }
41
+ export type CodexThreadStatus = {
42
+ type: "notLoaded";
43
+ } | {
44
+ type: "idle";
45
+ } | {
46
+ type: "systemError";
47
+ } | {
48
+ type: "active";
49
+ activeFlags: Array<"waitingOnApproval" | "waitingOnUserInput">;
50
+ };
51
+ export type CodexUserInput = {
52
+ type: "text";
53
+ text: string;
54
+ } | {
55
+ type: "image";
56
+ url: string;
57
+ } | {
58
+ type: "localImage";
59
+ path: string;
60
+ } | {
61
+ type: "audio";
62
+ url: string;
63
+ } | {
64
+ type: "localAudio";
65
+ path: string;
66
+ } | {
67
+ type: "skill";
68
+ name: string;
69
+ path: string;
70
+ } | {
71
+ type: "mention";
72
+ name: string;
73
+ path: string;
74
+ } | {
75
+ type: string;
76
+ [key: string]: unknown;
77
+ };
78
+ export interface CodexThreadItem {
79
+ type: string;
80
+ id?: string;
81
+ [key: string]: unknown;
82
+ }
83
+ export interface CodexTurn {
84
+ id: string;
85
+ items: CodexThreadItem[];
86
+ status: "completed" | "interrupted" | "failed" | "inProgress";
87
+ startedAt: number | null;
88
+ completedAt: number | null;
89
+ }
90
+ export interface ThreadStatusChangedNotification {
91
+ threadId: string;
92
+ status: CodexThreadStatus;
93
+ }
94
+ export interface ThreadStartedNotification {
95
+ thread: CodexThread;
96
+ }
97
+ export interface TurnStartedNotification {
98
+ threadId: string;
99
+ turn: CodexTurn;
100
+ }
101
+ export interface ItemCompletedNotification {
102
+ threadId: string;
103
+ turnId: string;
104
+ item: CodexThreadItem;
105
+ /** Unix timestamp in milliseconds. */
106
+ completedAtMs: number;
107
+ }
108
+ export interface TurnCompletedNotification {
109
+ threadId: string;
110
+ turn: CodexTurn;
111
+ }
112
+ /** Notifications consumed by Portal's managed Codex runner. */
113
+ export interface CodexAppServerNotifications {
114
+ "thread/started": ThreadStartedNotification;
115
+ "thread/status/changed": ThreadStatusChangedNotification;
116
+ "turn/started": TurnStartedNotification;
117
+ "item/completed": ItemCompletedNotification;
118
+ "turn/completed": TurnCompletedNotification;
119
+ }
120
+ export type CodexAppServerNotification = keyof CodexAppServerNotifications;
121
+ export interface CodexThread {
122
+ id: string;
123
+ sessionId: string;
124
+ preview: string;
125
+ ephemeral: boolean;
126
+ modelProvider: string;
127
+ createdAt: number;
128
+ updatedAt: number;
129
+ status: CodexThreadStatus;
130
+ cwd: string;
131
+ name: string | null;
132
+ canAcceptDirectInput: boolean | null;
133
+ turns: CodexTurn[];
134
+ }
135
+ export interface ThreadListResponse {
136
+ data: CodexThread[];
137
+ nextCursor: string | null;
138
+ backwardsCursor?: string | null;
139
+ }
140
+ export interface ThreadLoadedListResponse {
141
+ data: string[];
142
+ nextCursor: string | null;
143
+ }
144
+ export interface ThreadReadResponse {
145
+ thread: CodexThread;
146
+ }
147
+ export interface ThreadStartParams {
148
+ cwd?: string | null;
149
+ ephemeral?: boolean | null;
150
+ baseInstructions?: string | null;
151
+ developerInstructions?: string | null;
152
+ config?: Record<string, unknown> | null;
153
+ }
154
+ export interface ThreadStartResponse {
155
+ thread: CodexThread;
156
+ model: string;
157
+ modelProvider: string;
158
+ cwd: string;
159
+ }
160
+ export interface TurnStartParams {
161
+ threadId: string;
162
+ input: CodexUserInput[];
163
+ }
164
+ export interface TurnStartResponse {
165
+ turn: CodexTurn;
166
+ }
167
+ export interface CodexAppServerMethods {
168
+ initialize: {
169
+ params: InitializeParams;
170
+ result: InitializeResponse;
171
+ };
172
+ "thread/list": {
173
+ params: ThreadListParams;
174
+ result: ThreadListResponse;
175
+ };
176
+ "thread/loaded/list": {
177
+ params: ThreadLoadedListParams;
178
+ result: ThreadLoadedListResponse;
179
+ };
180
+ "thread/read": {
181
+ params: ThreadReadParams;
182
+ result: ThreadReadResponse;
183
+ };
184
+ "thread/start": {
185
+ params: ThreadStartParams;
186
+ result: ThreadStartResponse;
187
+ };
188
+ "turn/start": {
189
+ params: TurnStartParams;
190
+ result: TurnStartResponse;
191
+ };
192
+ }
193
+ export type CodexAppServerMethod = keyof CodexAppServerMethods;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hand-maintained subset of the Codex app-server protocol used by Portal.
3
+ *
4
+ * The installed Codex CLI can generate the complete version-specific bindings
5
+ * with `codex app-server generate-ts`. Keeping this read-only subset local makes
6
+ * the adapter tolerant of additive protocol changes without vendoring hundreds
7
+ * of generated files.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../../src/provider/codex/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,35 @@
1
+ import type { ProviderAdapter, ProviderDiagnostic, ProviderSession, TranscriptEntry } from "../types.js";
2
+ import { CodexAppServerClient } from "./app-server-client.js";
3
+ export interface CodexAppServerApi {
4
+ readonly initializeResult: {
5
+ userAgent: string;
6
+ platformFamily: string;
7
+ platformOs: string;
8
+ };
9
+ request: CodexAppServerClient["request"];
10
+ close(): void;
11
+ }
12
+ export interface CodexProviderOptions {
13
+ clientFactory?: () => Promise<CodexAppServerApi>;
14
+ pageSize?: number;
15
+ }
16
+ export declare class CodexProvider implements ProviderAdapter {
17
+ readonly name: "codex";
18
+ private readonly clientFactory;
19
+ private readonly pageSize;
20
+ private clientPromise;
21
+ constructor(options?: CodexProviderOptions);
22
+ doctor(): Promise<ProviderDiagnostic>;
23
+ listSessions(): Promise<ProviderSession[]>;
24
+ readTranscript(vendorSessionId: string): Promise<TranscriptEntry[]>;
25
+ sendInput(vendorSessionId: string, text: string): Promise<string>;
26
+ createSession(options: {
27
+ cwd: string;
28
+ instructions?: string;
29
+ }): Promise<ProviderSession>;
30
+ close(): void;
31
+ private client;
32
+ private invalidateClient;
33
+ private listAllThreads;
34
+ private listAllLoadedThreadIds;
35
+ }
@@ -0,0 +1,289 @@
1
+ import { CodexAppServerClient } from "./app-server-client.js";
2
+ const ALL_THREAD_SOURCES = [
3
+ "cli",
4
+ "vscode",
5
+ "exec",
6
+ "appServer",
7
+ "subAgent",
8
+ "subAgentReview",
9
+ "subAgentCompact",
10
+ "subAgentThreadSpawn",
11
+ "subAgentOther",
12
+ "unknown",
13
+ ];
14
+ export class CodexProvider {
15
+ name = "codex";
16
+ clientFactory;
17
+ pageSize;
18
+ clientPromise;
19
+ constructor(options = {}) {
20
+ this.clientFactory = options.clientFactory ?? (() => CodexAppServerClient.connect());
21
+ this.pageSize = options.pageSize ?? 100;
22
+ }
23
+ async doctor() {
24
+ try {
25
+ const client = await this.client();
26
+ return {
27
+ provider: "codex",
28
+ available: true,
29
+ version: extractVersion(client.initializeResult.userAgent),
30
+ detail: `${client.initializeResult.userAgent} (${client.initializeResult.platformOs}/${client.initializeResult.platformFamily}); app-server read API ready`,
31
+ };
32
+ }
33
+ catch (error) {
34
+ return {
35
+ provider: "codex",
36
+ available: false,
37
+ version: null,
38
+ detail: error instanceof Error ? error.message : String(error),
39
+ };
40
+ }
41
+ }
42
+ async listSessions() {
43
+ const client = await this.client();
44
+ try {
45
+ const [activeThreads, archivedThreads, loadedIds] = await Promise.all([
46
+ this.listAllThreads(client, false),
47
+ this.listAllThreads(client, true),
48
+ this.listAllLoadedThreadIds(client),
49
+ ]);
50
+ const threads = [...new Map([...activeThreads, ...archivedThreads].map((thread) => [thread.id, thread])).values()];
51
+ const loaded = new Set(loadedIds);
52
+ return threads.map((thread) => mapSession(thread, loaded.has(thread.id)));
53
+ }
54
+ catch (error) {
55
+ this.invalidateClient(client);
56
+ throw error;
57
+ }
58
+ }
59
+ async readTranscript(vendorSessionId) {
60
+ const client = await this.client();
61
+ try {
62
+ const response = await client.request("thread/read", {
63
+ threadId: vendorSessionId,
64
+ includeTurns: true,
65
+ });
66
+ return response.thread.turns.flatMap((turn) => mapTurn(response.thread.id, turn));
67
+ }
68
+ catch (error) {
69
+ this.invalidateClient(client);
70
+ throw error;
71
+ }
72
+ }
73
+ async sendInput(vendorSessionId, text) {
74
+ if (text.trim().length === 0)
75
+ throw new TypeError("Codex input cannot be empty");
76
+ const client = await this.client();
77
+ const response = await client.request("turn/start", {
78
+ threadId: vendorSessionId,
79
+ input: [{ type: "text", text }],
80
+ });
81
+ return response.turn.id;
82
+ }
83
+ async createSession(options) {
84
+ const client = await this.client();
85
+ const response = await client.request("thread/start", {
86
+ cwd: options.cwd,
87
+ ephemeral: false,
88
+ ...(options.instructions === undefined ? {} : { baseInstructions: options.instructions }),
89
+ });
90
+ return mapSession(response.thread, true);
91
+ }
92
+ close() {
93
+ const clientPromise = this.clientPromise;
94
+ this.clientPromise = undefined;
95
+ void clientPromise?.then((client) => client.close(), () => undefined);
96
+ }
97
+ client() {
98
+ if (this.clientPromise === undefined) {
99
+ const pending = this.clientFactory();
100
+ this.clientPromise = pending;
101
+ void pending.catch(() => {
102
+ if (this.clientPromise === pending)
103
+ this.clientPromise = undefined;
104
+ });
105
+ }
106
+ return this.clientPromise;
107
+ }
108
+ invalidateClient(client) {
109
+ this.clientPromise = undefined;
110
+ client.close();
111
+ }
112
+ async listAllThreads(client, archived) {
113
+ const threads = [];
114
+ let cursor = null;
115
+ do {
116
+ const page = await client.request("thread/list", {
117
+ cursor,
118
+ limit: this.pageSize,
119
+ sortKey: "updated_at",
120
+ sortDirection: "desc",
121
+ sourceKinds: ALL_THREAD_SOURCES,
122
+ archived,
123
+ });
124
+ threads.push(...page.data);
125
+ cursor = page.nextCursor;
126
+ } while (cursor !== null);
127
+ return threads;
128
+ }
129
+ async listAllLoadedThreadIds(client) {
130
+ const ids = [];
131
+ let cursor = null;
132
+ do {
133
+ const page = await client.request("thread/loaded/list", {
134
+ cursor,
135
+ limit: this.pageSize,
136
+ });
137
+ ids.push(...page.data);
138
+ cursor = page.nextCursor;
139
+ } while (cursor !== null);
140
+ return ids;
141
+ }
142
+ }
143
+ function mapSession(thread, loaded) {
144
+ const state = mapState(thread, loaded);
145
+ return {
146
+ provider: "codex",
147
+ vendorSessionId: thread.id,
148
+ workspace: thread.cwd || null,
149
+ title: nonEmpty(thread.name) ?? nonEmpty(thread.preview),
150
+ createdAt: fromEpochSeconds(thread.createdAt),
151
+ updatedAt: fromEpochSeconds(thread.updatedAt),
152
+ state: state.state,
153
+ stateConfidence: state.confidence,
154
+ indexed: false,
155
+ // An app-server's loaded-thread set does not prove that it owns a separate
156
+ // interactive TUI. Portal only marks MCP-authenticated leases connected.
157
+ connected: false,
158
+ messageable: false,
159
+ };
160
+ }
161
+ function mapState(thread, loaded) {
162
+ switch (thread.status.type) {
163
+ case "active":
164
+ return { state: "active", confidence: "verified" };
165
+ case "idle":
166
+ return { state: "idle", confidence: "verified" };
167
+ case "systemError":
168
+ return { state: "unknown", confidence: "verified" };
169
+ case "notLoaded":
170
+ return { state: "unknown", confidence: loaded ? "inferred" : "unavailable" };
171
+ }
172
+ }
173
+ function mapTurn(vendorSessionId, turn) {
174
+ return turn.items.map((item, index) => {
175
+ const mapped = mapItem(item);
176
+ const itemId = typeof item.id === "string" ? item.id : String(index);
177
+ const occurredAt = fromEpochSeconds(mapped.role === "user" ? turn.startedAt : (turn.completedAt ?? turn.startedAt));
178
+ return {
179
+ sourceId: `${turn.id}:${itemId}`,
180
+ vendorSessionId,
181
+ role: mapped.role,
182
+ text: mapped.text,
183
+ occurredAt,
184
+ };
185
+ });
186
+ }
187
+ function mapItem(item) {
188
+ switch (item.type) {
189
+ case "userMessage":
190
+ return { role: "user", text: formatUserInputs(asArray(item.content)) };
191
+ case "hookPrompt":
192
+ return {
193
+ role: "system",
194
+ text: asArray(item.fragments)
195
+ .map((fragment) => stringValue(fragment.text))
196
+ .filter(Boolean)
197
+ .join("\n"),
198
+ };
199
+ case "agentMessage":
200
+ case "plan":
201
+ return { role: "assistant", text: stringValue(item.text) };
202
+ case "reasoning":
203
+ return {
204
+ role: "assistant",
205
+ text: asStringArray(item.summary).join("\n"),
206
+ };
207
+ case "commandExecution":
208
+ return {
209
+ role: "tool",
210
+ text: [stringValue(item.command), stringValue(item.aggregatedOutput)].filter(Boolean).join("\n"),
211
+ };
212
+ case "fileChange":
213
+ return {
214
+ role: "tool",
215
+ text: asArray(item.changes)
216
+ .map((change) => [stringValue(change.path), stringValue(change.diff)].filter(Boolean).join("\n"))
217
+ .join("\n"),
218
+ };
219
+ case "mcpToolCall":
220
+ case "dynamicToolCall":
221
+ case "collabAgentToolCall":
222
+ case "webSearch":
223
+ case "imageView":
224
+ case "imageGeneration":
225
+ return { role: "tool", text: compactJson(item) };
226
+ case "enteredReviewMode":
227
+ case "exitedReviewMode":
228
+ case "contextCompaction":
229
+ return { role: "system", text: compactJson(item) };
230
+ default:
231
+ return { role: "other", text: compactJson(item) };
232
+ }
233
+ }
234
+ function formatUserInputs(inputs) {
235
+ return inputs
236
+ .map((input) => {
237
+ switch (input.type) {
238
+ case "text":
239
+ return stringValue(input.text);
240
+ case "image":
241
+ return `[image: ${stringValue(input.url)}]`;
242
+ case "localImage":
243
+ return `[local image: ${stringValue(input.path)}]`;
244
+ case "audio":
245
+ return `[audio: ${stringValue(input.url)}]`;
246
+ case "localAudio":
247
+ return `[local audio: ${stringValue(input.path)}]`;
248
+ case "skill":
249
+ return `[skill: ${stringValue(input.name)} (${stringValue(input.path)})]`;
250
+ case "mention":
251
+ return `@${stringValue(input.name)} (${stringValue(input.path)})`;
252
+ default:
253
+ return compactJson(input);
254
+ }
255
+ })
256
+ .filter(Boolean)
257
+ .join("\n");
258
+ }
259
+ function extractVersion(userAgent) {
260
+ return userAgent.match(/\b\d+\.\d+\.\d+(?:[-+][\w.-]+)?\b/)?.[0] ?? null;
261
+ }
262
+ function fromEpochSeconds(value) {
263
+ if (typeof value !== "number" || !Number.isFinite(value))
264
+ return null;
265
+ const date = new Date(value * 1_000);
266
+ return Number.isNaN(date.getTime()) ? null : date;
267
+ }
268
+ function nonEmpty(value) {
269
+ const trimmed = value?.trim();
270
+ return trimmed ? trimmed : null;
271
+ }
272
+ function asArray(value) {
273
+ return Array.isArray(value) ? value : [];
274
+ }
275
+ function asStringArray(value) {
276
+ return asArray(value).map(stringValue).filter(Boolean);
277
+ }
278
+ function stringValue(value) {
279
+ return typeof value === "string" ? value : "";
280
+ }
281
+ function compactJson(value) {
282
+ try {
283
+ return JSON.stringify(value);
284
+ }
285
+ catch {
286
+ return String(value);
287
+ }
288
+ }
289
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../../src/provider/codex/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type ChildProcessWithoutNullStreams } from "node:child_process";
2
+ import { CodexWebSocketClient } from "./websocket-client.js";
3
+ export interface RemoteCodexAppServer {
4
+ address: string;
5
+ client: CodexWebSocketClient;
6
+ close(): Promise<void>;
7
+ }
8
+ export interface RemoteCodexAppServerOptions {
9
+ executable?: string;
10
+ startupTimeoutMs?: number;
11
+ args?: readonly string[];
12
+ environment?: NodeJS.ProcessEnv;
13
+ processFactory?: (command: string, args: readonly string[], environment: NodeJS.ProcessEnv | undefined) => ChildProcessWithoutNullStreams;
14
+ }
15
+ /** Starts a loopback-only app-server that Portal and one Codex TUI share. */
16
+ export declare function startRemoteCodexAppServer(options?: RemoteCodexAppServerOptions): Promise<RemoteCodexAppServer>;
@@ -0,0 +1,80 @@
1
+ import { spawn } from "node:child_process";
2
+ import { CodexWebSocketClient } from "./websocket-client.js";
3
+ /** Starts a loopback-only app-server that Portal and one Codex TUI share. */
4
+ export async function startRemoteCodexAppServer(options = {}) {
5
+ const processFactory = options.processFactory ?? ((command, args, environment) => spawn(command, [...args], { stdio: ["pipe", "pipe", "pipe"], ...(environment === undefined ? {} : { env: environment }) }));
6
+ const child = processFactory(options.executable ?? "codex", [
7
+ "app-server",
8
+ "--listen",
9
+ "ws://127.0.0.1:0",
10
+ ...(options.args ?? []),
11
+ ], options.environment);
12
+ try {
13
+ const address = await waitForAddress(child, options.startupTimeoutMs ?? 10_000);
14
+ const client = await CodexWebSocketClient.connect(address, {
15
+ requestTimeoutMs: options.startupTimeoutMs ?? 10_000,
16
+ });
17
+ return {
18
+ address,
19
+ client,
20
+ async close() {
21
+ client.close();
22
+ await stopProcess(child);
23
+ },
24
+ };
25
+ }
26
+ catch (error) {
27
+ await stopProcess(child);
28
+ throw error;
29
+ }
30
+ }
31
+ function waitForAddress(child, timeoutMs) {
32
+ return new Promise((resolve, reject) => {
33
+ let output = "";
34
+ let settled = false;
35
+ const finish = (error, address) => {
36
+ if (settled)
37
+ return;
38
+ settled = true;
39
+ clearTimeout(timer);
40
+ child.off("error", onError);
41
+ child.off("exit", onExit);
42
+ child.stdout.off("data", inspect);
43
+ child.stderr.off("data", inspect);
44
+ if (error !== undefined)
45
+ reject(error);
46
+ else
47
+ resolve(address);
48
+ };
49
+ const inspect = (chunk) => {
50
+ output = `${output}${String(chunk)}`.slice(-8_192);
51
+ const address = output.match(/listening on:\s+(ws:\/\/127\.0\.0\.1:\d+)/)?.[1];
52
+ if (address !== undefined)
53
+ finish(undefined, address);
54
+ };
55
+ const onError = (error) => finish(error);
56
+ const onExit = (code, signal) => finish(new Error(`Codex app-server exited before becoming ready (${code ?? signal ?? "unknown"}): ${output.trim()}`));
57
+ const timer = setTimeout(() => finish(new Error(`Codex app-server did not become ready within ${timeoutMs}ms: ${output.trim()}`)), timeoutMs);
58
+ timer.unref();
59
+ child.stdout.on("data", inspect);
60
+ child.stderr.on("data", inspect);
61
+ child.once("error", onError);
62
+ child.once("exit", onExit);
63
+ });
64
+ }
65
+ async function stopProcess(child) {
66
+ if (child.exitCode !== null || child.signalCode !== null)
67
+ return;
68
+ child.kill("SIGTERM");
69
+ await new Promise((resolve) => {
70
+ const deadline = setTimeout(() => {
71
+ child.kill("SIGKILL");
72
+ }, 1_000);
73
+ deadline.unref();
74
+ child.once("exit", () => {
75
+ clearTimeout(deadline);
76
+ resolve();
77
+ });
78
+ });
79
+ }
80
+ //# sourceMappingURL=remote-app-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-app-server.js","sourceRoot":"","sources":["../../../../src/provider/codex/remote-app-server.ts"],"names":[],"mappings":"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"}