@jingyi0605/codingns 0.1.1 → 0.1.2

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 (238) hide show
  1. package/README.md +14 -0
  2. package/dist/public/assets/{TerminalPage-CVG1cGAJ.js → TerminalPage-Dr7knYq2.js} +19 -19
  3. package/dist/public/assets/index-BpUi6zoT.js +108 -0
  4. package/dist/public/assets/index-NMtdQNda.css +1 -0
  5. package/dist/public/index.html +2 -2
  6. package/dist/server/config/env.js +24 -3
  7. package/dist/server/config/env.js.map +1 -1
  8. package/dist/server/config/opencode-base-url-resolver.d.ts +13 -8
  9. package/dist/server/config/opencode-base-url-resolver.js +117 -147
  10. package/dist/server/config/opencode-base-url-resolver.js.map +1 -1
  11. package/dist/server/config/opencode-system-probe-helper-client.d.ts +18 -0
  12. package/dist/server/config/opencode-system-probe-helper-client.js +127 -0
  13. package/dist/server/config/opencode-system-probe-helper-client.js.map +1 -0
  14. package/dist/server/config/opencode-system-probe-helper-process.d.ts +1 -0
  15. package/dist/server/config/opencode-system-probe-helper-process.js +208 -0
  16. package/dist/server/config/opencode-system-probe-helper-process.js.map +1 -0
  17. package/dist/server/modules/git/git-command-helper-client.d.ts +25 -0
  18. package/dist/server/modules/git/git-command-helper-client.js +143 -0
  19. package/dist/server/modules/git/git-command-helper-client.js.map +1 -0
  20. package/dist/server/modules/git/git-command-helper-process.d.ts +1 -0
  21. package/dist/server/modules/git/git-command-helper-process.js +237 -0
  22. package/dist/server/modules/git/git-command-helper-process.js.map +1 -0
  23. package/dist/server/modules/git/git-command-runner.d.ts +8 -0
  24. package/dist/server/modules/git/git-command-runner.js +77 -6
  25. package/dist/server/modules/git/git-command-runner.js.map +1 -1
  26. package/dist/server/modules/git/git-controller.d.ts +4 -0
  27. package/dist/server/modules/git/git-controller.js +4 -1
  28. package/dist/server/modules/git/git-controller.js.map +1 -1
  29. package/dist/server/modules/git/git-read-service.d.ts +2 -1
  30. package/dist/server/modules/git/git-read-service.js +30 -0
  31. package/dist/server/modules/git/git-read-service.js.map +1 -1
  32. package/dist/server/modules/git/git-write-service.d.ts +1 -1
  33. package/dist/server/modules/git/git-write-service.js +8 -7
  34. package/dist/server/modules/git/git-write-service.js.map +1 -1
  35. package/dist/server/modules/git/types.d.ts +5 -0
  36. package/dist/server/modules/preferences/common.d.ts +2 -0
  37. package/dist/server/modules/preferences/common.js +13 -0
  38. package/dist/server/modules/preferences/common.js.map +1 -0
  39. package/dist/server/modules/preferences/profile-controller.d.ts +11 -0
  40. package/dist/server/modules/preferences/profile-controller.js +14 -0
  41. package/dist/server/modules/preferences/profile-controller.js.map +1 -0
  42. package/dist/server/modules/preferences/profile-service.d.ts +17 -0
  43. package/dist/server/modules/preferences/profile-service.js +213 -0
  44. package/dist/server/modules/preferences/profile-service.js.map +1 -0
  45. package/dist/server/modules/preferences/quick-phrase-controller.js +2 -12
  46. package/dist/server/modules/preferences/quick-phrase-controller.js.map +1 -1
  47. package/dist/server/modules/provider/codex-model-options.js +26 -165
  48. package/dist/server/modules/provider/codex-model-options.js.map +1 -1
  49. package/dist/server/modules/provider/opencode-model-options.js +6 -71
  50. package/dist/server/modules/provider/opencode-model-options.js.map +1 -1
  51. package/dist/server/modules/provider/provider-controller.d.ts +2 -0
  52. package/dist/server/modules/provider/provider-controller.js +21 -1
  53. package/dist/server/modules/provider/provider-controller.js.map +1 -1
  54. package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +25 -0
  55. package/dist/server/modules/provider/provider-discovery-helper-client.js +114 -0
  56. package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -0
  57. package/dist/server/modules/provider/provider-discovery-helper-process.d.ts +1 -0
  58. package/dist/server/modules/provider/provider-discovery-helper-process.js +296 -0
  59. package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -0
  60. package/dist/server/modules/sessions/claude-runtime-helper-client.d.ts +28 -0
  61. package/dist/server/modules/sessions/claude-runtime-helper-client.js +221 -0
  62. package/dist/server/modules/sessions/claude-runtime-helper-client.js.map +1 -0
  63. package/dist/server/modules/sessions/claude-runtime-helper-process.d.ts +1 -0
  64. package/dist/server/modules/sessions/claude-runtime-helper-process.js +146 -0
  65. package/dist/server/modules/sessions/claude-runtime-helper-process.js.map +1 -0
  66. package/dist/server/modules/sessions/codex-app-server-helper-client.d.ts +16 -0
  67. package/dist/server/modules/sessions/codex-app-server-helper-client.js +237 -0
  68. package/dist/server/modules/sessions/codex-app-server-helper-client.js.map +1 -0
  69. package/dist/server/modules/sessions/codex-app-server-helper-process.d.ts +1 -0
  70. package/dist/server/modules/sessions/codex-app-server-helper-process.js +484 -0
  71. package/dist/server/modules/sessions/codex-app-server-helper-process.js.map +1 -0
  72. package/dist/server/modules/sessions/session-activity-authority-service.d.ts +52 -0
  73. package/dist/server/modules/sessions/session-activity-authority-service.js +377 -0
  74. package/dist/server/modules/sessions/session-activity-authority-service.js.map +1 -0
  75. package/dist/server/modules/sessions/session-activity-inspector.js +80 -40
  76. package/dist/server/modules/sessions/session-activity-inspector.js.map +1 -1
  77. package/dist/server/modules/sessions/session-controller.d.ts +15 -1
  78. package/dist/server/modules/sessions/session-controller.js +14 -1
  79. package/dist/server/modules/sessions/session-controller.js.map +1 -1
  80. package/dist/server/modules/sessions/session-history-service.d.ts +4 -2
  81. package/dist/server/modules/sessions/session-history-service.js +151 -29
  82. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  83. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +40 -4
  84. package/dist/server/modules/sessions/session-live-runtime-service.js +330 -44
  85. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  86. package/dist/server/modules/sessions/session-permission-request-service.d.ts +175 -0
  87. package/dist/server/modules/sessions/session-permission-request-service.js +1615 -0
  88. package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -0
  89. package/dist/server/modules/sessions/session-provider-error-mapper.js +14 -0
  90. package/dist/server/modules/sessions/session-provider-error-mapper.js.map +1 -1
  91. package/dist/server/modules/terminal/command-template-service.d.ts +2 -2
  92. package/dist/server/modules/terminal/command-template-service.js +3 -3
  93. package/dist/server/modules/terminal/command-template-service.js.map +1 -1
  94. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-client.d.ts +24 -0
  95. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-client.js +104 -0
  96. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-client.js.map +1 -0
  97. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-process.d.ts +1 -0
  98. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-process.js +96 -0
  99. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-process.js.map +1 -0
  100. package/dist/server/modules/terminal/runtime/adapters/conpty-runtime-adapter.d.ts +37 -0
  101. package/dist/server/modules/terminal/runtime/adapters/conpty-runtime-adapter.js +123 -0
  102. package/dist/server/modules/terminal/runtime/adapters/conpty-runtime-adapter.js.map +1 -0
  103. package/dist/server/modules/terminal/runtime/adapters/embedded-pty-runtime-adapter.d.ts +12 -5
  104. package/dist/server/modules/terminal/runtime/adapters/embedded-pty-runtime-adapter.js +44 -4
  105. package/dist/server/modules/terminal/runtime/adapters/embedded-pty-runtime-adapter.js.map +1 -1
  106. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-client.d.ts +14 -0
  107. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-client.js +105 -0
  108. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-client.js.map +1 -0
  109. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-process.d.ts +1 -0
  110. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-process.js +67 -0
  111. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-process.js.map +1 -0
  112. package/dist/server/modules/terminal/runtime/adapters/tmux-runtime-adapter.d.ts +8 -12
  113. package/dist/server/modules/terminal/runtime/adapters/tmux-runtime-adapter.js +112 -21
  114. package/dist/server/modules/terminal/runtime/adapters/tmux-runtime-adapter.js.map +1 -1
  115. package/dist/server/modules/terminal/runtime/conpty-runtime-shared.d.ts +25 -0
  116. package/dist/server/modules/terminal/runtime/conpty-runtime-shared.js +124 -0
  117. package/dist/server/modules/terminal/runtime/conpty-runtime-shared.js.map +1 -0
  118. package/dist/server/modules/terminal/runtime/conpty-session-agent-process.d.ts +1 -0
  119. package/dist/server/modules/terminal/runtime/conpty-session-agent-process.js +205 -0
  120. package/dist/server/modules/terminal/runtime/conpty-session-agent-process.js.map +1 -0
  121. package/dist/server/modules/terminal/runtime/conpty-session-attach-client.d.ts +1 -0
  122. package/dist/server/modules/terminal/runtime/conpty-session-attach-client.js +108 -0
  123. package/dist/server/modules/terminal/runtime/conpty-session-attach-client.js.map +1 -0
  124. package/dist/server/modules/terminal/runtime/conpty-session-control-client.d.ts +1 -0
  125. package/dist/server/modules/terminal/runtime/conpty-session-control-client.js +90 -0
  126. package/dist/server/modules/terminal/runtime/conpty-session-control-client.js.map +1 -0
  127. package/dist/server/modules/terminal/runtime/pty-broker-agent-process.d.ts +1 -0
  128. package/dist/server/modules/terminal/runtime/pty-broker-agent-process.js +179 -0
  129. package/dist/server/modules/terminal/runtime/pty-broker-agent-process.js.map +1 -0
  130. package/dist/server/modules/terminal/runtime/pty-broker-client.d.ts +29 -0
  131. package/dist/server/modules/terminal/runtime/pty-broker-client.js +169 -0
  132. package/dist/server/modules/terminal/runtime/pty-broker-client.js.map +1 -0
  133. package/dist/server/modules/terminal/runtime/pty-broker-shared.d.ts +22 -0
  134. package/dist/server/modules/terminal/runtime/pty-broker-shared.js +123 -0
  135. package/dist/server/modules/terminal/runtime/pty-broker-shared.js.map +1 -0
  136. package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.d.ts +1 -0
  137. package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.js +11 -1
  138. package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.js.map +1 -1
  139. package/dist/server/modules/terminal/runtime/terminal-log-file-store.d.ts +1 -0
  140. package/dist/server/modules/terminal/runtime/terminal-log-file-store.js +7 -1
  141. package/dist/server/modules/terminal/runtime/terminal-log-file-store.js.map +1 -1
  142. package/dist/server/modules/terminal/runtime/terminal-log-spooler.js +3 -2
  143. package/dist/server/modules/terminal/runtime/terminal-log-spooler.js.map +1 -1
  144. package/dist/server/modules/terminal/runtime/terminal-runtime-adapter.d.ts +5 -3
  145. package/dist/server/modules/terminal/runtime/terminal-runtime-manager.d.ts +11 -5
  146. package/dist/server/modules/terminal/runtime/terminal-runtime-manager.js +110 -13
  147. package/dist/server/modules/terminal/runtime/terminal-runtime-manager.js.map +1 -1
  148. package/dist/server/modules/terminal/terminal-controller.js +7 -7
  149. package/dist/server/modules/terminal/terminal-controller.js.map +1 -1
  150. package/dist/server/modules/terminal/terminal-service.d.ts +30 -14
  151. package/dist/server/modules/terminal/terminal-service.js +260 -51
  152. package/dist/server/modules/terminal/terminal-service.js.map +1 -1
  153. package/dist/server/modules/terminal/terminal-shell.d.ts +4 -0
  154. package/dist/server/modules/terminal/terminal-shell.js +165 -18
  155. package/dist/server/modules/terminal/terminal-shell.js.map +1 -1
  156. package/dist/server/modules/workbench/workspace-file-watcher.d.ts +30 -0
  157. package/dist/server/modules/workbench/workspace-file-watcher.js +137 -0
  158. package/dist/server/modules/workbench/workspace-file-watcher.js.map +1 -0
  159. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +43 -7
  160. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  161. package/dist/server/routes/git.js +1 -0
  162. package/dist/server/routes/git.js.map +1 -1
  163. package/dist/server/routes/preferences.d.ts +2 -1
  164. package/dist/server/routes/preferences.js +3 -1
  165. package/dist/server/routes/preferences.js.map +1 -1
  166. package/dist/server/routes/sessions.js +2 -0
  167. package/dist/server/routes/sessions.js.map +1 -1
  168. package/dist/server/server/create-server.d.ts +4 -0
  169. package/dist/server/server/create-server.js +22 -5
  170. package/dist/server/server/create-server.js.map +1 -1
  171. package/dist/server/shared/utils/command-launch.d.ts +6 -0
  172. package/dist/server/shared/utils/command-launch.js +39 -0
  173. package/dist/server/shared/utils/command-launch.js.map +1 -0
  174. package/dist/server/shared/utils/perf-log.d.ts +1 -0
  175. package/dist/server/shared/utils/perf-log.js +8 -2
  176. package/dist/server/shared/utils/perf-log.js.map +1 -1
  177. package/dist/server/shared/utils/permission-debug-log.d.ts +2 -0
  178. package/dist/server/shared/utils/permission-debug-log.js +40 -0
  179. package/dist/server/shared/utils/permission-debug-log.js.map +1 -0
  180. package/dist/server/shared/utils/terminal-debug-log.d.ts +4 -0
  181. package/dist/server/shared/utils/terminal-debug-log.js +71 -0
  182. package/dist/server/shared/utils/terminal-debug-log.js.map +1 -0
  183. package/dist/server/storage/repositories/user-preference-profile-repository.d.ts +8 -0
  184. package/dist/server/storage/repositories/user-preference-profile-repository.js +46 -0
  185. package/dist/server/storage/repositories/user-preference-profile-repository.js.map +1 -0
  186. package/dist/server/storage/sqlite/schema.sql +13 -0
  187. package/dist/server/types/domain.d.ts +28 -1
  188. package/dist/server/ws/terminal-ws-hub.d.ts +2 -0
  189. package/dist/server/ws/terminal-ws-hub.js +42 -5
  190. package/dist/server/ws/terminal-ws-hub.js.map +1 -1
  191. package/dist/server/ws/workbench-ws-hub.d.ts +9 -1
  192. package/dist/server/ws/workbench-ws-hub.js +132 -21
  193. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  194. package/dist/server/ws/ws-server.d.ts +22 -1
  195. package/dist/server/ws/ws-server.js +79 -43
  196. package/dist/server/ws/ws-server.js.map +1 -1
  197. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js +42 -0
  198. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js.map +1 -1
  199. package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +30 -0
  200. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +103 -0
  201. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +1 -0
  202. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +1 -1
  203. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +2 -1
  204. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  205. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +1 -1
  206. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +1 -1
  207. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  208. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.d.ts +1 -0
  209. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js +8 -0
  210. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js.map +1 -0
  211. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js +31 -0
  212. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js.map +1 -1
  213. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +1 -1
  214. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +8 -4
  215. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  216. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +1 -0
  217. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +5 -0
  218. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
  219. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.d.ts +5 -0
  220. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +82 -1
  221. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  222. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +23 -0
  223. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +688 -17
  224. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  225. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.d.ts +3 -0
  226. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +106 -23
  227. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +1 -1
  228. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.d.ts +1 -0
  229. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js +3 -0
  230. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js.map +1 -1
  231. package/node_modules/@codingns/session-sync-core/dist/services.d.ts +1 -1
  232. package/node_modules/@codingns/session-sync-core/dist/services.js +2 -2
  233. package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
  234. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +1 -1
  235. package/package.json +3 -2
  236. package/scripts/postinstall.mjs +15 -8
  237. package/dist/public/assets/index-BUPByQPG.css +0 -1
  238. package/dist/public/assets/index-D1CwTkI2.js +0 -106
@@ -1,7 +1,9 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import { spawn } from "node:child_process";
2
3
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
3
4
  import { homedir } from "node:os";
4
5
  import { basename, dirname, join, resolve } from "node:path";
6
+ import { createInterface } from "node:readline";
5
7
  import { DatabaseSync } from "node:sqlite";
6
8
  import { fileURLToPath, pathToFileURL } from "node:url";
7
9
  import { appendJsonLine, createRawRef, ensureDirectory, extractTextBlocks, messageIdFromRawRef, nextTimestamp, normalizeWorkspacePath } from "../providers/utils.js";
@@ -14,29 +16,59 @@ export class CodexRuntimeAdapter {
14
16
  }
15
17
  async startSession(request, sink) {
16
18
  const launchedAtMs = Date.now();
17
- const client = await loadCodexClient();
18
- const thread = client.startThread(createThreadOptions(request));
19
+ const transport = this.options.transportFactory
20
+ ? this.options.transportFactory()
21
+ : createCodexAppServerTransport(this.options);
22
+ await transport.initialize();
19
23
  const abortController = new AbortController();
20
- const streamed = await thread.runStreamed(createCodexInput(request), {
21
- signal: abortController.signal
22
- });
23
- const events = streamed.events[Symbol.asyncIterator]();
24
- const startedSession = await this.awaitThreadStarted(thread, events, request.workspacePath, request.options.content, launchedAtMs);
24
+ const eventQueue = createAsyncEventQueue();
25
+ const startedSession = await transport.startThread(request);
25
26
  const providerSessionId = startedSession.providerSessionId;
26
- const fallbackRawStoreRef = request.rawStoreRef ?? buildRuntimeRawStoreRef(resolveRuntimeStoreKey(providerSessionId, request.sessionId));
27
+ const fallbackRawStoreRef = startedSession.rawStoreRef ??
28
+ request.rawStoreRef ??
29
+ buildRuntimeRawStoreRef(resolveRuntimeStoreKey(providerSessionId, request.sessionId));
27
30
  const resolvedBinding = await this.resolveExistingSessionBinding(providerSessionId, fallbackRawStoreRef, request.workspacePath);
28
31
  const rawStoreRef = resolvedBinding?.rawStoreRef ?? fallbackRawStoreRef;
29
32
  sink.updateSessionBinding({
30
33
  providerSessionId,
31
34
  rawStoreRef
32
35
  });
36
+ transport.setNotificationHandler(async (notification) => {
37
+ const translated = translateCodexAppServerNotification(notification);
38
+ if (translated.turnId) {
39
+ eventQueue.setTurnId(translated.turnId);
40
+ }
41
+ if (translated.event) {
42
+ eventQueue.push(translated.event);
43
+ }
44
+ if (translated.terminal) {
45
+ eventQueue.close();
46
+ }
47
+ });
48
+ transport.setServerRequestHandler(async (serverRequest) => {
49
+ if (!this.options.handleServerRequest) {
50
+ throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
51
+ }
52
+ return this.options.handleServerRequest({
53
+ sessionId: request.sessionId,
54
+ providerSessionId,
55
+ request: serverRequest
56
+ });
57
+ });
58
+ await transport.startTurn(request, providerSessionId);
33
59
  return {
34
60
  providerSessionId,
35
61
  rawStoreRef,
36
62
  interrupt: async () => {
37
63
  abortController.abort();
64
+ await transport.interruptTurn().catch(() => {
65
+ return;
66
+ });
67
+ transport.close();
38
68
  },
39
- completed: this.runTurn(null, request, sink, providerSessionId, rawStoreRef, abortController, events, startedSession.bufferedEvents, launchedAtMs)
69
+ completed: this.runTurn(null, request, sink, providerSessionId, rawStoreRef, abortController, eventQueue.iterator, [], launchedAtMs).finally(() => {
70
+ transport.close();
71
+ })
40
72
  };
41
73
  }
42
74
  async continueSession(request, sink) {
@@ -44,31 +76,66 @@ export class CodexRuntimeAdapter {
44
76
  if (!providerSessionId) {
45
77
  throw new Error("PROVIDER_SESSION_ID_REQUIRED");
46
78
  }
47
- const client = await loadCodexClient();
48
- const thread = client.resumeThread(providerSessionId, createThreadOptions(request));
79
+ const transport = this.options.transportFactory
80
+ ? this.options.transportFactory()
81
+ : createCodexAppServerTransport(this.options);
82
+ await transport.initialize();
49
83
  const fallbackRawStoreRef = request.rawStoreRef ?? buildRuntimeRawStoreRef(providerSessionId);
50
84
  const resolvedBinding = await this.resolveExistingSessionBinding(providerSessionId, fallbackRawStoreRef, request.workspacePath);
51
85
  const resolvedSessionId = resolvedBinding?.providerSessionId ?? providerSessionId;
52
- const rawStoreRef = resolvedBinding?.rawStoreRef ?? fallbackRawStoreRef;
86
+ const resumed = await transport.resumeThread(request, resolvedSessionId);
87
+ const rawStoreRef = resolvedBinding?.rawStoreRef ?? resumed.rawStoreRef ?? fallbackRawStoreRef;
53
88
  const abortController = new AbortController();
89
+ const eventQueue = createAsyncEventQueue();
54
90
  sink.updateSessionBinding({
55
91
  providerSessionId: resolvedSessionId,
56
92
  rawStoreRef
57
93
  });
94
+ transport.setNotificationHandler(async (notification) => {
95
+ const translated = translateCodexAppServerNotification(notification);
96
+ if (translated.turnId) {
97
+ eventQueue.setTurnId(translated.turnId);
98
+ }
99
+ if (translated.event) {
100
+ eventQueue.push(translated.event);
101
+ }
102
+ if (translated.terminal) {
103
+ eventQueue.close();
104
+ }
105
+ });
106
+ transport.setServerRequestHandler(async (serverRequest) => {
107
+ if (!this.options.handleServerRequest) {
108
+ throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
109
+ }
110
+ return this.options.handleServerRequest({
111
+ sessionId: request.sessionId,
112
+ providerSessionId: resolvedSessionId,
113
+ request: serverRequest
114
+ });
115
+ });
116
+ await transport.startTurn(request, resolvedSessionId);
58
117
  return {
59
118
  providerSessionId: resolvedSessionId,
60
119
  rawStoreRef,
61
120
  interrupt: async () => {
62
121
  abortController.abort();
122
+ await transport.interruptTurn().catch(() => {
123
+ return;
124
+ });
125
+ transport.close();
63
126
  },
64
- completed: this.runTurn(thread, request, sink, resolvedSessionId, rawStoreRef, abortController, undefined, [], Date.now())
127
+ completed: this.runTurn(null, request, sink, resolvedSessionId, rawStoreRef, abortController, eventQueue.iterator, [], Date.now()).finally(() => {
128
+ transport.close();
129
+ })
65
130
  };
66
131
  }
67
132
  async runTurn(thread, request, sink, providerSessionId, rawStoreRef, abortController, preparedEvents, bufferedEvents = [], launchedAtMs = Date.now()) {
68
133
  const context = {
69
134
  providerSessionId,
70
135
  rawStoreRef,
71
- sequence: 0,
136
+ // 运行时消息必须接在历史消息后面,不能每轮都从 1 重新编号,
137
+ // 否则前端会把新 assistant/tool 消息排到旧消息前面,表现成用户消息一直挂在底部。
138
+ sequence: Math.max(0, request.sequenceBase ?? 0),
72
139
  toolNameByCallId: new Map(),
73
140
  sink,
74
141
  workspacePath: request.workspacePath,
@@ -148,12 +215,23 @@ export class CodexRuntimeAdapter {
148
215
  status: "failed",
149
216
  providerSessionId: context.providerSessionId,
150
217
  rawStoreRef: context.rawStoreRef,
151
- errorCode: "CODEX_CLI_TURN_FAILED",
218
+ errorCode: classifyCodexDetailErrorCode(detail, "CODEX_CLI_TURN_FAILED"),
152
219
  detail,
153
220
  timestamp: pickTimestamp(event)
154
221
  });
155
222
  return;
156
223
  }
224
+ if (eventType === "turn.interrupted") {
225
+ await context.sink.emit({
226
+ type: "interrupted",
227
+ status: "interrupted",
228
+ providerSessionId: context.providerSessionId,
229
+ rawStoreRef: context.rawStoreRef,
230
+ detail: "codex turn interrupted",
231
+ timestamp: pickTimestamp(event)
232
+ });
233
+ return;
234
+ }
157
235
  if (interrupted) {
158
236
  return;
159
237
  }
@@ -451,6 +529,392 @@ export class CodexRuntimeAdapter {
451
529
  }
452
530
  }
453
531
  }
532
+ function createCodexAppServerTransport(options) {
533
+ const commandPath = resolveCodexCommand(options.commandPath);
534
+ const launch = resolveCodexCommandLaunch(commandPath, ["app-server"]);
535
+ const child = spawn(launch.command, launch.args, {
536
+ env: process.env,
537
+ stdio: ["pipe", "pipe", "pipe"],
538
+ shell: launch.shell,
539
+ windowsHide: true
540
+ });
541
+ const stdout = createInterface({ input: child.stdout });
542
+ let notificationHandler = () => undefined;
543
+ let serverRequestHandler = async () => {
544
+ throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
545
+ };
546
+ let requestSequence = 0;
547
+ let closed = false;
548
+ let activeTurnId = null;
549
+ let activeThreadId = null;
550
+ const pendingResponses = new Map();
551
+ const finalize = (error) => {
552
+ if (closed) {
553
+ return;
554
+ }
555
+ closed = true;
556
+ stdout.close();
557
+ for (const pending of pendingResponses.values()) {
558
+ pending.reject(error ?? new Error("CODEX_APP_SERVER_CLOSED"));
559
+ }
560
+ pendingResponses.clear();
561
+ };
562
+ child.on("error", (error) => {
563
+ finalize(error);
564
+ });
565
+ child.on("exit", (code, signal) => {
566
+ if (closed) {
567
+ return;
568
+ }
569
+ const detail = signal
570
+ ? `codex app-server exited with signal ${signal}`
571
+ : `codex app-server exited with code ${String(code ?? "unknown")}`;
572
+ finalize(new Error(detail));
573
+ });
574
+ stdout.on("line", (line) => {
575
+ const trimmed = line.trim();
576
+ if (!trimmed) {
577
+ return;
578
+ }
579
+ let parsed;
580
+ try {
581
+ parsed = JSON.parse(trimmed);
582
+ }
583
+ catch {
584
+ return;
585
+ }
586
+ if (typeof parsed.method === "string" && parsed.id !== undefined) {
587
+ void Promise.resolve(serverRequestHandler(parsed))
588
+ .then((result) => {
589
+ writeJsonRpcMessage(child, {
590
+ jsonrpc: "2.0",
591
+ id: parsed.id,
592
+ result
593
+ });
594
+ })
595
+ .catch((error) => {
596
+ writeJsonRpcMessage(child, {
597
+ jsonrpc: "2.0",
598
+ id: parsed.id,
599
+ error: {
600
+ code: -32000,
601
+ message: error instanceof Error ? error.message : "CODEX_APP_SERVER_REQUEST_FAILED"
602
+ }
603
+ });
604
+ });
605
+ return;
606
+ }
607
+ if (typeof parsed.method === "string") {
608
+ const method = parsed.method.trim();
609
+ const params = readJsonRpcParams(parsed);
610
+ if (method === "turn/started") {
611
+ activeTurnId = ensureText(readProp(readProp(params, "turn"), "id")).trim() || activeTurnId;
612
+ }
613
+ if (method === "thread/started") {
614
+ activeThreadId = ensureText(readProp(readProp(params, "thread"), "id")).trim() || activeThreadId;
615
+ }
616
+ void notificationHandler({
617
+ method,
618
+ params
619
+ });
620
+ return;
621
+ }
622
+ const responseId = String(parsed.id ?? "");
623
+ const pending = pendingResponses.get(responseId);
624
+ if (!pending) {
625
+ return;
626
+ }
627
+ pendingResponses.delete(responseId);
628
+ if (parsed.error && typeof parsed.error === "object") {
629
+ const message = ensureText(readProp(parsed.error, "message")).trim() || "CODEX_APP_SERVER_ERROR";
630
+ pending.reject(new Error(message));
631
+ return;
632
+ }
633
+ pending.resolve(readJsonRpcResult(parsed));
634
+ });
635
+ return {
636
+ async initialize() {
637
+ await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("initialize", () => ++requestSequence), {
638
+ method: "initialize",
639
+ params: {
640
+ clientInfo: {
641
+ name: "codingns-runtime",
642
+ version: "0.0.0"
643
+ },
644
+ capabilities: null
645
+ }
646
+ });
647
+ writeJsonRpcMessage(child, {
648
+ jsonrpc: "2.0",
649
+ method: "initialized",
650
+ params: {}
651
+ });
652
+ },
653
+ async startThread(request) {
654
+ const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("thread-start", () => ++requestSequence), {
655
+ method: "thread/start",
656
+ params: createThreadStartParams(request)
657
+ });
658
+ const thread = toRecord(result.thread);
659
+ const providerSessionId = ensureText(thread?.id).trim();
660
+ if (!providerSessionId) {
661
+ throw new Error("CODEX_APP_SERVER_THREAD_ID_MISSING");
662
+ }
663
+ activeThreadId = providerSessionId;
664
+ return {
665
+ providerSessionId,
666
+ rawStoreRef: normalizeText(thread?.path) || null
667
+ };
668
+ },
669
+ async resumeThread(request, providerSessionId) {
670
+ const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("thread-resume", () => ++requestSequence), {
671
+ method: "thread/resume",
672
+ params: createThreadResumeParams(request, providerSessionId)
673
+ });
674
+ const thread = toRecord(result.thread);
675
+ activeThreadId = ensureText(thread?.id).trim() || providerSessionId;
676
+ return {
677
+ providerSessionId: activeThreadId,
678
+ rawStoreRef: normalizeText(thread?.path) || null
679
+ };
680
+ },
681
+ async startTurn(request, providerSessionId) {
682
+ const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("turn-start", () => ++requestSequence), {
683
+ method: "turn/start",
684
+ params: createTurnStartParams(request, providerSessionId)
685
+ });
686
+ activeTurnId = ensureText(readProp(readProp(result, "turn"), "id")).trim() || activeTurnId;
687
+ },
688
+ async interruptTurn() {
689
+ if (!activeThreadId || !activeTurnId) {
690
+ return;
691
+ }
692
+ await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("turn-interrupt", () => ++requestSequence), {
693
+ method: "turn/interrupt",
694
+ params: {
695
+ threadId: activeThreadId,
696
+ turnId: activeTurnId
697
+ }
698
+ });
699
+ },
700
+ setNotificationHandler(handler) {
701
+ notificationHandler = handler;
702
+ },
703
+ setServerRequestHandler(handler) {
704
+ serverRequestHandler = handler;
705
+ },
706
+ close() {
707
+ if (closed) {
708
+ return;
709
+ }
710
+ finalize(null);
711
+ if (!child.stdin.destroyed) {
712
+ child.stdin.end();
713
+ }
714
+ if (!child.killed) {
715
+ child.kill("SIGTERM");
716
+ }
717
+ }
718
+ };
719
+ }
720
+ function createAsyncEventQueue() {
721
+ const values = [];
722
+ const waiters = [];
723
+ let closed = false;
724
+ let turnId = null;
725
+ return {
726
+ iterator: {
727
+ next() {
728
+ if (values.length > 0) {
729
+ return Promise.resolve({
730
+ done: false,
731
+ value: values.shift()
732
+ });
733
+ }
734
+ if (closed) {
735
+ return Promise.resolve({
736
+ done: true,
737
+ value: undefined
738
+ });
739
+ }
740
+ return new Promise((resolve) => {
741
+ waiters.push(resolve);
742
+ });
743
+ }
744
+ },
745
+ push(value) {
746
+ if (closed) {
747
+ return;
748
+ }
749
+ const waiter = waiters.shift();
750
+ if (waiter) {
751
+ waiter({
752
+ done: false,
753
+ value
754
+ });
755
+ return;
756
+ }
757
+ values.push(value);
758
+ },
759
+ close() {
760
+ if (closed) {
761
+ return;
762
+ }
763
+ closed = true;
764
+ while (waiters.length > 0) {
765
+ waiters.shift()?.({
766
+ done: true,
767
+ value: undefined
768
+ });
769
+ }
770
+ },
771
+ setTurnId(nextTurnId) {
772
+ turnId = nextTurnId;
773
+ },
774
+ getTurnId() {
775
+ return turnId;
776
+ }
777
+ };
778
+ }
779
+ function translateCodexAppServerNotification(notification) {
780
+ const method = ensureText(notification.method).trim();
781
+ const params = toRecord(notification.params) ?? {};
782
+ if (method === "turn/started") {
783
+ return {
784
+ event: null,
785
+ terminal: false,
786
+ turnId: ensureText(readProp(readProp(params, "turn"), "id")).trim() || null
787
+ };
788
+ }
789
+ if (method === "turn/completed") {
790
+ const turn = toRecord(params.turn);
791
+ const status = ensureText(turn?.status).trim();
792
+ if (status === "failed") {
793
+ return {
794
+ event: {
795
+ type: "turn.failed",
796
+ timestamp: nextTimestamp(),
797
+ error: ensureText(readProp(turn?.error, "message")).trim() || "codex turn failed"
798
+ },
799
+ terminal: true,
800
+ turnId: ensureText(turn?.id).trim() || null
801
+ };
802
+ }
803
+ if (status === "interrupted") {
804
+ return {
805
+ event: {
806
+ type: "turn.interrupted",
807
+ timestamp: nextTimestamp()
808
+ },
809
+ terminal: true,
810
+ turnId: ensureText(turn?.id).trim() || null
811
+ };
812
+ }
813
+ return {
814
+ event: {
815
+ type: "turn.completed",
816
+ timestamp: nextTimestamp()
817
+ },
818
+ terminal: true,
819
+ turnId: ensureText(turn?.id).trim() || null
820
+ };
821
+ }
822
+ if (method === "item/started" || method === "item/completed") {
823
+ const item = translateCodexAppServerItem(toRecord(params.item));
824
+ if (!item) {
825
+ return {
826
+ event: null,
827
+ terminal: false,
828
+ turnId: null
829
+ };
830
+ }
831
+ return {
832
+ event: {
833
+ type: method === "item/started" ? "item.started" : "item.completed",
834
+ item,
835
+ timestamp: nextTimestamp()
836
+ },
837
+ terminal: false,
838
+ turnId: null
839
+ };
840
+ }
841
+ return {
842
+ event: null,
843
+ terminal: false,
844
+ turnId: null
845
+ };
846
+ }
847
+ function translateCodexAppServerItem(item) {
848
+ if (!item) {
849
+ return null;
850
+ }
851
+ const itemType = ensureText(item.type).trim();
852
+ if (!itemType) {
853
+ return null;
854
+ }
855
+ if (itemType === "agentMessage") {
856
+ return {
857
+ type: "agent_message",
858
+ id: item.id,
859
+ text: item.text
860
+ };
861
+ }
862
+ if (itemType === "reasoning") {
863
+ return {
864
+ type: "reasoning",
865
+ id: item.id,
866
+ text: Array.isArray(item.content) ? item.content.join("\n") : "",
867
+ summary: Array.isArray(item.summary) ? item.summary.join("\n") : ""
868
+ };
869
+ }
870
+ if (itemType === "commandExecution") {
871
+ return {
872
+ type: "command_execution",
873
+ id: item.id,
874
+ command: item.command,
875
+ cwd: item.cwd,
876
+ status: normalizeCodexItemStatus(item.status),
877
+ commandActions: item.commandActions,
878
+ aggregated_output: item.aggregatedOutput,
879
+ exit_code: item.exitCode
880
+ };
881
+ }
882
+ if (itemType === "fileChange") {
883
+ const diffText = buildCodexFileChangeOutput(item.changes);
884
+ return {
885
+ type: "custom_tool_call",
886
+ id: item.id,
887
+ tool: "apply_patch",
888
+ input: diffText,
889
+ output: diffText,
890
+ status: normalizeCodexItemStatus(item.status)
891
+ };
892
+ }
893
+ if (itemType === "mcpToolCall") {
894
+ return {
895
+ type: "mcp_tool_call",
896
+ id: item.id,
897
+ tool: item.tool,
898
+ server: item.server,
899
+ arguments: item.arguments,
900
+ result: item.result,
901
+ error: item.error,
902
+ status: normalizeCodexItemStatus(item.status)
903
+ };
904
+ }
905
+ if (itemType === "dynamicToolCall") {
906
+ return {
907
+ type: "custom_tool_call",
908
+ id: item.id,
909
+ tool: item.tool,
910
+ input: item.arguments,
911
+ output: item.contentItems,
912
+ success: item.success,
913
+ status: normalizeCodexItemStatus(item.status)
914
+ };
915
+ }
916
+ return null;
917
+ }
454
918
  export function createThreadOptions(request) {
455
919
  const options = {
456
920
  workingDirectory: request.workspacePath,
@@ -470,6 +934,61 @@ export function createThreadOptions(request) {
470
934
  }
471
935
  return options;
472
936
  }
937
+ function createThreadStartParams(request) {
938
+ const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
939
+ const params = {
940
+ cwd: request.workspacePath,
941
+ approvalsReviewer: "user"
942
+ };
943
+ if (permissionOptions.approvalPolicy) {
944
+ params.approvalPolicy = permissionOptions.approvalPolicy;
945
+ }
946
+ if (permissionOptions.sandboxMode) {
947
+ params.sandbox = permissionOptions.sandboxMode;
948
+ }
949
+ if (request.options.model) {
950
+ params.model = request.options.model;
951
+ }
952
+ return params;
953
+ }
954
+ function createThreadResumeParams(request, providerSessionId) {
955
+ const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
956
+ const params = {
957
+ threadId: providerSessionId,
958
+ cwd: request.workspacePath,
959
+ approvalsReviewer: "user"
960
+ };
961
+ if (permissionOptions.approvalPolicy) {
962
+ params.approvalPolicy = permissionOptions.approvalPolicy;
963
+ }
964
+ if (permissionOptions.sandboxMode) {
965
+ params.sandbox = permissionOptions.sandboxMode;
966
+ }
967
+ if (request.options.model) {
968
+ params.model = request.options.model;
969
+ }
970
+ return params;
971
+ }
972
+ function createTurnStartParams(request, providerSessionId) {
973
+ const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
974
+ const params = {
975
+ threadId: providerSessionId,
976
+ input: createCodexAppServerInput(request),
977
+ cwd: request.workspacePath,
978
+ approvalsReviewer: "user"
979
+ };
980
+ if (permissionOptions.approvalPolicy) {
981
+ params.approvalPolicy = permissionOptions.approvalPolicy;
982
+ }
983
+ if (request.options.model) {
984
+ params.model = request.options.model;
985
+ }
986
+ const reasoningEffort = normalizeCodexReasoningEffort(request.options.reasoningLevel);
987
+ if (reasoningEffort) {
988
+ params.effort = reasoningEffort;
989
+ }
990
+ return params;
991
+ }
473
992
  function normalizeCodexReasoningEffort(value) {
474
993
  const normalized = value?.trim().toLowerCase() ?? null;
475
994
  if (!normalized) {
@@ -507,6 +1026,23 @@ function createCodexInput(request) {
507
1026
  });
508
1027
  return input;
509
1028
  }
1029
+ function createCodexAppServerInput(request) {
1030
+ const input = [];
1031
+ const promptText = (request.options.providerPrompt ?? request.options.content).trim();
1032
+ if (promptText.length > 0) {
1033
+ input.push({
1034
+ type: "text",
1035
+ text: promptText
1036
+ });
1037
+ }
1038
+ for (const attachment of request.options.attachments) {
1039
+ input.push({
1040
+ type: "localImage",
1041
+ path: attachment.filePath
1042
+ });
1043
+ }
1044
+ return input;
1045
+ }
510
1046
  async function loadCodexClient() {
511
1047
  const moduleName = "@openai/codex-sdk";
512
1048
  const runtimeImport = new Function("name", "return import(name);");
@@ -553,6 +1089,80 @@ function buildRuntimeRawStoreRef(providerSessionId) {
553
1089
  function resolveRuntimeStoreKey(providerSessionId, sessionId) {
554
1090
  return providerSessionId.trim() || sessionId;
555
1091
  }
1092
+ function resolveCodexCommand(explicitPath) {
1093
+ const explicitCandidate = explicitPath?.trim() ||
1094
+ process.env.CODINGNS_CODEX_COMMAND?.trim() ||
1095
+ "codex";
1096
+ return explicitCandidate;
1097
+ }
1098
+ function resolveCodexCommandLaunch(commandPath, args) {
1099
+ const normalizedCommandPath = commandPath.trim();
1100
+ if (isNodeScriptPath(normalizedCommandPath)) {
1101
+ return {
1102
+ command: process.execPath,
1103
+ args: [normalizedCommandPath, ...args],
1104
+ shell: false
1105
+ };
1106
+ }
1107
+ return {
1108
+ command: normalizedCommandPath,
1109
+ args: [...args],
1110
+ shell: shouldSpawnViaShellOnWindows(normalizedCommandPath)
1111
+ };
1112
+ }
1113
+ function isNodeScriptPath(commandPath) {
1114
+ return /\.(?:c|m)?js$/i.test(commandPath);
1115
+ }
1116
+ function shouldSpawnViaShellOnWindows(commandPath) {
1117
+ if (process.platform !== "win32") {
1118
+ return false;
1119
+ }
1120
+ if (/\.(cmd|bat)$/i.test(commandPath)) {
1121
+ return true;
1122
+ }
1123
+ // Windows 上裸名命令(无扩展名、无路径分隔符)需要 shell 才能从 PATH 解析 .cmd 文件
1124
+ const extension = commandPath.split(".").pop()?.toLowerCase();
1125
+ const hasPathSep = commandPath.includes("\\") || commandPath.includes("/");
1126
+ if (!extension || extension === commandPath.toLowerCase()) {
1127
+ if (!hasPathSep) {
1128
+ return true;
1129
+ }
1130
+ }
1131
+ return false;
1132
+ }
1133
+ function nextJsonRpcId(prefix, allocate) {
1134
+ return `${prefix}:${allocate()}`;
1135
+ }
1136
+ function writeJsonRpcMessage(child, payload) {
1137
+ if (!child.stdin || child.stdin.destroyed || !child.stdin.writable) {
1138
+ throw new Error("CODEX_APP_SERVER_STDIN_UNAVAILABLE");
1139
+ }
1140
+ child.stdin.write(`${JSON.stringify(payload)}\n`, "utf8");
1141
+ }
1142
+ function sendJsonRpcRequest(child, pendingResponses, createRequestId, input) {
1143
+ const id = createRequestId();
1144
+ return new Promise((resolve, reject) => {
1145
+ pendingResponses.set(id, { resolve, reject });
1146
+ try {
1147
+ writeJsonRpcMessage(child, {
1148
+ jsonrpc: "2.0",
1149
+ id,
1150
+ method: input.method,
1151
+ params: input.params
1152
+ });
1153
+ }
1154
+ catch (error) {
1155
+ pendingResponses.delete(id);
1156
+ reject(error instanceof Error ? error : new Error("CODEX_APP_SERVER_REQUEST_WRITE_FAILED"));
1157
+ }
1158
+ });
1159
+ }
1160
+ function readJsonRpcParams(parsed) {
1161
+ return toRecord(parsed.params) ?? {};
1162
+ }
1163
+ function readJsonRpcResult(parsed) {
1164
+ return toRecord(parsed.result) ?? {};
1165
+ }
556
1166
  function resolveResumeThreadId(providerSessionId, rawStoreRef) {
557
1167
  const normalizedProviderSessionId = ensureText(providerSessionId).trim();
558
1168
  const fromRawStore = readThreadIdFromRawStore(rawStoreRef);
@@ -570,6 +1180,12 @@ function readProp(value, key) {
570
1180
  }
571
1181
  return value[key];
572
1182
  }
1183
+ function toRecord(value) {
1184
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1185
+ return null;
1186
+ }
1187
+ return value;
1188
+ }
573
1189
  function ensureText(value) {
574
1190
  if (typeof value === "string") {
575
1191
  return value;
@@ -584,6 +1200,10 @@ function ensureText(value) {
584
1200
  return String(value);
585
1201
  }
586
1202
  }
1203
+ function normalizeText(value) {
1204
+ const normalized = ensureText(value).trim();
1205
+ return normalized.length > 0 ? normalized : null;
1206
+ }
587
1207
  function readThreadIdFromRawStore(rawStoreRef) {
588
1208
  const filePath = ensureText(rawStoreRef).trim();
589
1209
  if (!filePath || !existsSync(filePath)) {
@@ -715,9 +1335,14 @@ function pickFirstNonEmpty(...values) {
715
1335
  }
716
1336
  function isToolItem(itemType) {
717
1337
  return (itemType === "command_execution" ||
1338
+ itemType === "file_change" ||
718
1339
  itemType === "mcp_tool_call" ||
719
1340
  itemType === "function_call" ||
720
- itemType === "custom_tool_call");
1341
+ itemType === "custom_tool_call" ||
1342
+ itemType === "commandExecution" ||
1343
+ itemType === "fileChange" ||
1344
+ itemType === "mcpToolCall" ||
1345
+ itemType === "dynamicToolCall");
721
1346
  }
722
1347
  function inferToolSuccess(item, output) {
723
1348
  const status = ensureText(readProp(item, "status")).trim().toLowerCase();
@@ -758,10 +1383,23 @@ function classifyCodexRuntimeFailure(error) {
758
1383
  };
759
1384
  }
760
1385
  return {
761
- errorCode: "CODEX_RUNTIME_ERROR",
1386
+ errorCode: classifyCodexDetailErrorCode(detail, "CODEX_RUNTIME_ERROR"),
762
1387
  detail
763
1388
  };
764
1389
  }
1390
+ function classifyCodexDetailErrorCode(detail, fallback) {
1391
+ const normalized = detail.trim();
1392
+ if (!normalized) {
1393
+ return fallback;
1394
+ }
1395
+ const statusMatch = normalized.match(/\bstatus\s+(\d{3})\b/i)
1396
+ ?? normalized.match(/\bHTTP\s+(\d{3})\b/i)
1397
+ ?? normalized.match(/\b(\d{3})\s+(?:Bad Gateway|Too Many Requests|Gateway Timeout|Service Unavailable)\b/i);
1398
+ if (!statusMatch) {
1399
+ return fallback;
1400
+ }
1401
+ return `CODEX_HTTP_${statusMatch[1]}`;
1402
+ }
765
1403
  function persistSyntheticUserMessageIfNeeded(rawStoreRef, providerSessionId, input) {
766
1404
  if (!isSyntheticRawStoreRef(rawStoreRef) || input.content.trim().length === 0) {
767
1405
  return;
@@ -921,4 +1559,37 @@ function mapToolStartItemType(itemType) {
921
1559
  function mapToolResultItemType(itemType) {
922
1560
  return itemType === "custom_tool_call" ? "custom_tool_call_output" : "function_call_output";
923
1561
  }
1562
+ function normalizeCodexItemStatus(value) {
1563
+ const normalized = ensureText(value).trim();
1564
+ if (!normalized) {
1565
+ return "in_progress";
1566
+ }
1567
+ if (normalized === "inProgress") {
1568
+ return "running";
1569
+ }
1570
+ if (normalized === "declined") {
1571
+ return "failed";
1572
+ }
1573
+ return normalized;
1574
+ }
1575
+ function buildCodexFileChangeOutput(value) {
1576
+ if (!Array.isArray(value)) {
1577
+ return "";
1578
+ }
1579
+ return value
1580
+ .map((change) => {
1581
+ const record = toRecord(change);
1582
+ if (!record) {
1583
+ return "";
1584
+ }
1585
+ const diff = ensureText(record.diff).trim();
1586
+ if (diff.length > 0) {
1587
+ return diff;
1588
+ }
1589
+ const path = ensureText(record.path).trim();
1590
+ return path.length > 0 ? `Updated ${path}` : "";
1591
+ })
1592
+ .filter((entry) => entry.length > 0)
1593
+ .join("\n\n");
1594
+ }
924
1595
  //# sourceMappingURL=codex-runtime.js.map