@skaile/workspaces 3.16.2 → 3.17.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 (47) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/bridge/codex-app-server.d.ts +2 -0
  4. package/dist/bridge/codex-app-server.js +206 -0
  5. package/dist/bridge/codex-app-server.js.map +1 -0
  6. package/dist/bridge/src/codex/native-protocol.generated.d.ts +1325 -0
  7. package/dist/bridge/src/codex/native-protocol.generated.d.ts.map +1 -0
  8. package/dist/bridge/src/codex-app-server.d.ts +55 -0
  9. package/dist/bridge/src/codex-app-server.d.ts.map +1 -0
  10. package/dist/{chunk-GRVSSAAQ.js → chunk-2XGFQKNJ.js} +2 -2
  11. package/dist/{chunk-GRVSSAAQ.js.map → chunk-2XGFQKNJ.js.map} +1 -1
  12. package/dist/{chunk-2KBA5OO2.js → chunk-BCOGOM6F.js} +4 -4
  13. package/dist/{chunk-2KBA5OO2.js.map → chunk-BCOGOM6F.js.map} +1 -1
  14. package/dist/{chunk-DUMD4AA2.js → chunk-HEKLK4NG.js} +2 -2
  15. package/dist/{chunk-DUMD4AA2.js.map → chunk-HEKLK4NG.js.map} +1 -1
  16. package/dist/{chunk-I3COVVFB.js → chunk-KCI7DAKE.js} +111 -40
  17. package/dist/chunk-KCI7DAKE.js.map +1 -0
  18. package/dist/{chunk-4W2OOVN5.js → chunk-NMAICJUA.js} +3 -3
  19. package/dist/{chunk-4W2OOVN5.js.map → chunk-NMAICJUA.js.map} +1 -1
  20. package/dist/{chunk-L2UE4YJO.js → chunk-PYX4WZLJ.js} +4 -4
  21. package/dist/{chunk-L2UE4YJO.js.map → chunk-PYX4WZLJ.js.map} +1 -1
  22. package/dist/cli/index.js +7 -7
  23. package/dist/factory-assets/connectors/flow/run-flow.js +1 -1
  24. package/dist/runner/index.js +4 -4
  25. package/dist/runner/src/codex-init.d.ts +14 -0
  26. package/dist/runner/src/codex-init.d.ts.map +1 -0
  27. package/dist/runner/src/serve.d.ts.map +1 -1
  28. package/dist/sdk/index.js +4 -4
  29. package/dist/sdk/runner.js +4 -4
  30. package/dist/sdk/session.js +2 -2
  31. package/dist/sdk/types.js +1 -1
  32. package/dist/session/index.js +2 -2
  33. package/dist/{source-6PBVTACZ.js → source-ODR4IU6R.js} +3 -3
  34. package/dist/{source-6PBVTACZ.js.map → source-ODR4IU6R.js.map} +1 -1
  35. package/dist/{source-manifest-publish-VBVNW7KL.js → source-manifest-publish-WCJY3GAM.js} +3 -3
  36. package/dist/{source-manifest-publish-VBVNW7KL.js.map → source-manifest-publish-WCJY3GAM.js.map} +1 -1
  37. package/dist/tui/index.js +4 -4
  38. package/dist/types/index.js +1 -1
  39. package/dist/types/src/index.d.ts +1 -1
  40. package/dist/types/src/index.d.ts.map +1 -1
  41. package/dist/types/src/lifecycle.d.ts +43 -0
  42. package/dist/types/src/lifecycle.d.ts.map +1 -1
  43. package/dist/types/src/version.d.ts +1 -1
  44. package/dist/workspace-plugin/adapters/mcp.js +1 -1
  45. package/dist/workspace-plugin/index.js +1 -1
  46. package/package.json +8 -1
  47. package/dist/chunk-I3COVVFB.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#653](https://github.com/skaile-ai/workspaces/pull/653) [`f648965`](https://github.com/skaile-ai/workspaces/commit/f64896576ecea955c540494033745e6a301252ba) Thanks [@peteralbert](https://github.com/peteralbert)! - Add a narrow production Codex App Server stdio client derived from the retained native protocol, with bounded requests, native callbacks and safe terminal disposal. Extend protocol 3.11 with optional runtime feature requirements, explicit OpenAI auth mode, dedicated AI credential delivery and subscription refresh contracts. Unsupported managed Codex initialization fails before credentials are consumed; existing Claude and standalone Codex behavior remains unchanged. This does not advertise or enable a Codex runtime.
8
+
3
9
  ## 3.16.2
4
10
 
5
11
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { PROTOCOL_VERSION_STRING } from '../chunk-2KBA5OO2.js';
1
+ import { PROTOCOL_VERSION_STRING } from '../chunk-BCOGOM6F.js';
2
2
  import '../chunk-NSBPE2FW.js';
3
3
  import * as z from 'zod';
4
4
 
@@ -0,0 +1,2 @@
1
+ // Auto-generated by _scripts/emit-dts-sidecars.ts — do not edit by hand.
2
+ export * from "./src/codex-app-server.js";
@@ -0,0 +1,206 @@
1
+ import '../chunk-NSBPE2FW.js';
2
+ import { spawn } from 'child_process';
3
+
4
+ var CodexAppServerError = class extends Error {
5
+ constructor(code) {
6
+ super(`Codex App Server ${code}`);
7
+ this.code = code;
8
+ this.name = "CodexAppServerError";
9
+ }
10
+ code;
11
+ };
12
+ var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
13
+ var validId = (value) => typeof value === "string" || typeof value === "number" && Number.isSafeInteger(value);
14
+ function bound(value, fallback, maximum) {
15
+ const result = value ?? fallback;
16
+ if (!Number.isSafeInteger(result) || result <= 0 || result > maximum)
17
+ throw new CodexAppServerError("protocol");
18
+ return result;
19
+ }
20
+ var CodexAppServerClient = class _CodexAppServerClient {
21
+ constructor(options) {
22
+ this.options = options;
23
+ this.timeout = bound(options.requestTimeoutMs, 15e3, 3e5);
24
+ this.callbackTimeout = bound(options.serverRequestTimeoutMs, 3e4, 3e5);
25
+ this.capacity = bound(options.maxPendingRequests, 64, 1024);
26
+ this.frameLimit = bound(options.maxFrameBytes, 1024 * 1024, 16 * 1024 * 1024);
27
+ this.child = spawn(options.command, options.args, {
28
+ cwd: options.cwd,
29
+ env: options.env,
30
+ stdio: "pipe"
31
+ });
32
+ this.closed = new Promise((resolve) => this.child.once("close", () => resolve()));
33
+ this.child.stdout.setEncoding("utf8");
34
+ this.child.stdout.on("data", (chunk) => this.receive(chunk));
35
+ this.child.stderr.resume();
36
+ this.child.on("error", () => this.fail("process"));
37
+ this.child.stdin.on("error", () => this.fail("process"));
38
+ this.child.stdout.on("error", () => this.fail("process"));
39
+ this.child.stderr.on("error", () => this.fail("process"));
40
+ this.child.once("exit", () => this.fail("process"));
41
+ }
42
+ options;
43
+ pending = /* @__PURE__ */ new Map();
44
+ callbacks = /* @__PURE__ */ new Map();
45
+ timeout;
46
+ callbackTimeout;
47
+ capacity;
48
+ frameLimit;
49
+ child;
50
+ closed;
51
+ terminal = false;
52
+ nextId = 1;
53
+ buffer = "";
54
+ /** Spawn and finish the native initialize/initialized handshake before returning. */
55
+ static async connect(options) {
56
+ let client;
57
+ try {
58
+ client = new _CodexAppServerClient(options);
59
+ await client.request("initialize", {
60
+ clientInfo: options.clientInfo,
61
+ capabilities: { experimentalApi: true }
62
+ });
63
+ client.write({ method: "initialized" });
64
+ return client;
65
+ } catch (error) {
66
+ await client?.dispose();
67
+ throw error instanceof CodexAppServerError ? error : new CodexAppServerError("process");
68
+ }
69
+ }
70
+ /** Timeout closes this generation, so late replies can never satisfy a later request. */
71
+ request(method, params) {
72
+ if (this.terminal) return Promise.reject(new CodexAppServerError("closed"));
73
+ if (this.pending.size >= this.capacity)
74
+ return Promise.reject(new CodexAppServerError("capacity"));
75
+ const id = this.nextId++;
76
+ return new Promise((resolve, reject) => {
77
+ const timer = setTimeout(() => this.fail("timeout"), this.timeout);
78
+ this.pending.set(id, { resolve, reject, timer });
79
+ try {
80
+ this.write({ id, method, params });
81
+ } catch {
82
+ this.fail("protocol");
83
+ }
84
+ });
85
+ }
86
+ /** Reject pending work immediately and wait a bounded interval for process shutdown. */
87
+ async dispose() {
88
+ this.fail("closed");
89
+ let timer;
90
+ await Promise.race([
91
+ this.closed,
92
+ new Promise((resolve) => {
93
+ timer = setTimeout(resolve, 1e3);
94
+ })
95
+ ]);
96
+ clearTimeout(timer);
97
+ }
98
+ fail(code) {
99
+ if (this.terminal) return;
100
+ this.terminal = true;
101
+ this.buffer = "";
102
+ for (const request of this.pending.values()) {
103
+ clearTimeout(request.timer);
104
+ request.reject(new CodexAppServerError(code));
105
+ }
106
+ this.pending.clear();
107
+ for (const controller of this.callbacks.values()) controller.abort();
108
+ this.callbacks.clear();
109
+ this.child.kill("SIGKILL");
110
+ try {
111
+ this.options.onClose?.(new CodexAppServerError(code));
112
+ } catch {
113
+ }
114
+ }
115
+ write(frame) {
116
+ if (this.terminal) throw new CodexAppServerError("closed");
117
+ const line = `${JSON.stringify(frame)}
118
+ `;
119
+ if (Buffer.byteLength(line) > this.frameLimit) throw new CodexAppServerError("protocol");
120
+ this.child.stdin.write(line);
121
+ }
122
+ receive(chunk) {
123
+ if (this.terminal) return;
124
+ this.buffer += chunk;
125
+ try {
126
+ for (; ; ) {
127
+ const end = this.buffer.indexOf("\n");
128
+ if (end < 0) break;
129
+ const line = this.buffer.slice(0, end);
130
+ this.buffer = this.buffer.slice(end + 1);
131
+ if (Buffer.byteLength(line) > this.frameLimit) throw new CodexAppServerError("protocol");
132
+ if (!line.trim()) continue;
133
+ const frame = JSON.parse(line);
134
+ if (!record(frame)) throw new CodexAppServerError("protocol");
135
+ if (typeof frame.method === "string") {
136
+ if ("id" in frame) {
137
+ if (!validId(frame.id)) throw new CodexAppServerError("protocol");
138
+ void this.handleServerRequest(frame.id, frame.method, frame.params);
139
+ } else this.options.onNotification?.(frame.method, frame.params);
140
+ } else {
141
+ if (typeof frame.id !== "number" || !Number.isSafeInteger(frame.id) || "error" in frame === "result" in frame)
142
+ throw new CodexAppServerError("protocol");
143
+ const request = this.pending.get(frame.id);
144
+ if (!request) throw new CodexAppServerError("protocol");
145
+ clearTimeout(request.timer);
146
+ this.pending.delete(frame.id);
147
+ if ("error" in frame) request.reject(new CodexAppServerError("rejected"));
148
+ else request.resolve(frame.result);
149
+ }
150
+ if (this.terminal) return;
151
+ }
152
+ if (Buffer.byteLength(this.buffer) > this.frameLimit)
153
+ throw new CodexAppServerError("protocol");
154
+ } catch {
155
+ this.fail("protocol");
156
+ }
157
+ }
158
+ async handleServerRequest(id, method, params) {
159
+ if (this.callbacks.has(id) || this.callbacks.size >= this.capacity)
160
+ return this.fail("protocol");
161
+ const controller = new AbortController();
162
+ this.callbacks.set(id, controller);
163
+ let timer;
164
+ try {
165
+ const handler = Object.hasOwn(this.options.onServerRequest ?? {}, method) ? this.options.onServerRequest?.[method] : void 0;
166
+ if (!handler) throw new CodexAppServerError("rejected");
167
+ const result = await Promise.race([
168
+ Promise.resolve().then(() => {
169
+ if (this.terminal || controller.signal.aborted) throw new CodexAppServerError("closed");
170
+ return handler(
171
+ params,
172
+ controller.signal
173
+ );
174
+ }),
175
+ new Promise((_, reject) => {
176
+ controller.signal.addEventListener(
177
+ "abort",
178
+ () => reject(new CodexAppServerError("closed")),
179
+ { once: true }
180
+ );
181
+ timer = setTimeout(() => {
182
+ controller.abort();
183
+ reject(new CodexAppServerError("timeout"));
184
+ }, this.callbackTimeout);
185
+ })
186
+ ]);
187
+ this.write({ id, result });
188
+ } catch {
189
+ if (!this.terminal) {
190
+ try {
191
+ this.write({ id, error: { code: -32603, message: "Codex client request failed" } });
192
+ } catch {
193
+ this.fail("protocol");
194
+ }
195
+ }
196
+ } finally {
197
+ clearTimeout(timer);
198
+ controller.abort();
199
+ this.callbacks.delete(id);
200
+ }
201
+ }
202
+ };
203
+
204
+ export { CodexAppServerClient, CodexAppServerError };
205
+ //# sourceMappingURL=codex-app-server.js.map
206
+ //# sourceMappingURL=codex-app-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../bridge/src/codex-app-server.ts"],"names":[],"mappings":"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","file":"codex-app-server.js","sourcesContent":["import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport type { NativeRequests, NativeServerRequests } from \"./codex/native-protocol.generated.js\";\n\n/** The retained native request types, exposed only through this client surface. */\nexport type CodexRequestMethod = keyof NativeRequests;\n/** Native callback handlers receive cancellation when their process is disposed. */\nexport type CodexServerRequestHandlers = {\n [M in keyof NativeServerRequests]?: (\n params: NativeServerRequests[M][\"params\"],\n signal: AbortSignal,\n ) => Promise<NativeServerRequests[M][\"result\"]>;\n};\n/** Explicit process inputs keep managed callers from inheriting ambient credentials. */\nexport interface CodexAppServerOptions {\n command: string;\n args: string[];\n cwd: string;\n env: Record<string, string>;\n clientInfo: NativeRequests[\"initialize\"][\"params\"][\"clientInfo\"];\n requestTimeoutMs?: number;\n serverRequestTimeoutMs?: number;\n maxPendingRequests?: number;\n maxFrameBytes?: number;\n onServerRequest?: CodexServerRequestHandlers;\n onNotification?: (method: string, params: unknown) => void;\n /** Exactly once on terminal failure or disposal, even with no RPC pending. */\n onClose?: (error: CodexAppServerError) => void;\n}\n/** Safe error codes never contain stderr, native errors, RPC payloads or credentials. */\nexport class CodexAppServerError extends Error {\n constructor(\n readonly code: \"closed\" | \"process\" | \"protocol\" | \"timeout\" | \"rejected\" | \"capacity\",\n ) {\n super(`Codex App Server ${code}`);\n this.name = \"CodexAppServerError\";\n }\n}\ntype Pending = {\n resolve: (value: unknown) => void;\n reject: (error: CodexAppServerError) => void;\n timer: ReturnType<typeof setTimeout>;\n};\nconst record = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\nconst validId = (value: unknown): value is string | number =>\n typeof value === \"string\" || (typeof value === \"number\" && Number.isSafeInteger(value));\nfunction bound(value: number | undefined, fallback: number, maximum: number): number {\n const result = value ?? fallback;\n if (!Number.isSafeInteger(result) || result <= 0 || result > maximum)\n throw new CodexAppServerError(\"protocol\");\n return result;\n}\n\n/** One initialized stdio process with correlated, bounded requests and terminal disposal. */\nexport class CodexAppServerClient {\n private readonly pending = new Map<number, Pending>();\n private readonly callbacks = new Map<string | number, AbortController>();\n private readonly timeout: number;\n private readonly callbackTimeout: number;\n private readonly capacity: number;\n private readonly frameLimit: number;\n private readonly child: ChildProcessWithoutNullStreams;\n private readonly closed: Promise<void>;\n private terminal = false;\n private nextId = 1;\n private buffer = \"\";\n\n private constructor(private readonly options: CodexAppServerOptions) {\n this.timeout = bound(options.requestTimeoutMs, 15_000, 300_000);\n this.callbackTimeout = bound(options.serverRequestTimeoutMs, 30_000, 300_000);\n this.capacity = bound(options.maxPendingRequests, 64, 1024);\n this.frameLimit = bound(options.maxFrameBytes, 1024 * 1024, 16 * 1024 * 1024);\n this.child = spawn(options.command, options.args, {\n cwd: options.cwd,\n env: options.env,\n stdio: \"pipe\",\n });\n this.closed = new Promise((resolve) => this.child.once(\"close\", () => resolve()));\n this.child.stdout.setEncoding(\"utf8\");\n this.child.stdout.on(\"data\", (chunk: string) => this.receive(chunk));\n // Drain without retaining raw diagnostic output: native stderr can contain secrets.\n this.child.stderr.resume();\n this.child.on(\"error\", () => this.fail(\"process\"));\n this.child.stdin.on(\"error\", () => this.fail(\"process\"));\n this.child.stdout.on(\"error\", () => this.fail(\"process\"));\n this.child.stderr.on(\"error\", () => this.fail(\"process\"));\n this.child.once(\"exit\", () => this.fail(\"process\"));\n }\n\n /** Spawn and finish the native initialize/initialized handshake before returning. */\n static async connect(options: CodexAppServerOptions): Promise<CodexAppServerClient> {\n let client: CodexAppServerClient | undefined;\n try {\n client = new CodexAppServerClient(options);\n await client.request(\"initialize\", {\n clientInfo: options.clientInfo,\n capabilities: { experimentalApi: true },\n });\n client.write({ method: \"initialized\" });\n return client;\n } catch (error) {\n await client?.dispose();\n throw error instanceof CodexAppServerError ? error : new CodexAppServerError(\"process\");\n }\n }\n\n /** Timeout closes this generation, so late replies can never satisfy a later request. */\n request<M extends CodexRequestMethod>(\n method: M,\n params: NativeRequests[M][\"params\"],\n ): Promise<NativeRequests[M][\"result\"]> {\n if (this.terminal) return Promise.reject(new CodexAppServerError(\"closed\"));\n if (this.pending.size >= this.capacity)\n return Promise.reject(new CodexAppServerError(\"capacity\"));\n const id = this.nextId++;\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => this.fail(\"timeout\"), this.timeout);\n this.pending.set(id, { resolve: resolve as (value: unknown) => void, reject, timer });\n try {\n this.write({ id, method, params });\n } catch {\n this.fail(\"protocol\");\n }\n });\n }\n\n /** Reject pending work immediately and wait a bounded interval for process shutdown. */\n async dispose(): Promise<void> {\n this.fail(\"closed\");\n let timer: ReturnType<typeof setTimeout> | undefined;\n await Promise.race([\n this.closed,\n new Promise<void>((resolve) => {\n timer = setTimeout(resolve, 1000);\n }),\n ]);\n clearTimeout(timer);\n }\n\n private fail(code: CodexAppServerError[\"code\"]): void {\n if (this.terminal) return;\n this.terminal = true;\n this.buffer = \"\";\n for (const request of this.pending.values()) {\n clearTimeout(request.timer);\n request.reject(new CodexAppServerError(code));\n }\n this.pending.clear();\n for (const controller of this.callbacks.values()) controller.abort();\n this.callbacks.clear();\n this.child.kill(\"SIGKILL\");\n try {\n this.options.onClose?.(new CodexAppServerError(code));\n } catch {\n // Observer failures cannot interrupt transport cleanup.\n }\n }\n\n private write(frame: unknown): void {\n if (this.terminal) throw new CodexAppServerError(\"closed\");\n const line = `${JSON.stringify(frame)}\\n`;\n if (Buffer.byteLength(line) > this.frameLimit) throw new CodexAppServerError(\"protocol\");\n this.child.stdin.write(line);\n }\n\n private receive(chunk: string): void {\n if (this.terminal) return;\n this.buffer += chunk;\n try {\n for (;;) {\n const end = this.buffer.indexOf(\"\\n\");\n if (end < 0) break;\n const line = this.buffer.slice(0, end);\n this.buffer = this.buffer.slice(end + 1);\n if (Buffer.byteLength(line) > this.frameLimit) throw new CodexAppServerError(\"protocol\");\n if (!line.trim()) continue;\n const frame: unknown = JSON.parse(line);\n if (!record(frame)) throw new CodexAppServerError(\"protocol\");\n if (typeof frame.method === \"string\") {\n if (\"id\" in frame) {\n if (!validId(frame.id)) throw new CodexAppServerError(\"protocol\");\n void this.handleServerRequest(frame.id, frame.method, frame.params);\n } else this.options.onNotification?.(frame.method, frame.params);\n } else {\n if (\n typeof frame.id !== \"number\" ||\n !Number.isSafeInteger(frame.id) ||\n \"error\" in frame === \"result\" in frame\n )\n throw new CodexAppServerError(\"protocol\");\n const request = this.pending.get(frame.id);\n if (!request) throw new CodexAppServerError(\"protocol\");\n clearTimeout(request.timer);\n this.pending.delete(frame.id);\n if (\"error\" in frame) request.reject(new CodexAppServerError(\"rejected\"));\n else request.resolve(frame.result);\n }\n if (this.terminal) return;\n }\n if (Buffer.byteLength(this.buffer) > this.frameLimit)\n throw new CodexAppServerError(\"protocol\");\n } catch {\n this.fail(\"protocol\");\n }\n }\n\n private async handleServerRequest(\n id: string | number,\n method: string,\n params: unknown,\n ): Promise<void> {\n if (this.callbacks.has(id) || this.callbacks.size >= this.capacity)\n return this.fail(\"protocol\");\n const controller = new AbortController();\n this.callbacks.set(id, controller);\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const handler = Object.hasOwn(this.options.onServerRequest ?? {}, method)\n ? this.options.onServerRequest?.[method as keyof NativeServerRequests]\n : undefined;\n if (!handler) throw new CodexAppServerError(\"rejected\");\n const result = await Promise.race([\n Promise.resolve().then(() => {\n if (this.terminal || controller.signal.aborted) throw new CodexAppServerError(\"closed\");\n return (handler as (params: unknown, signal: AbortSignal) => Promise<unknown>)(\n params,\n controller.signal,\n );\n }),\n new Promise<never>((_, reject) => {\n controller.signal.addEventListener(\n \"abort\",\n () => reject(new CodexAppServerError(\"closed\")),\n { once: true },\n );\n timer = setTimeout(() => {\n controller.abort();\n reject(new CodexAppServerError(\"timeout\"));\n }, this.callbackTimeout);\n }),\n ]);\n this.write({ id, result });\n } catch {\n if (!this.terminal) {\n try {\n this.write({ id, error: { code: -32603, message: \"Codex client request failed\" } });\n } catch {\n this.fail(\"protocol\");\n }\n }\n } finally {\n clearTimeout(timer);\n controller.abort();\n this.callbacks.delete(id);\n }\n }\n}\n"]}