@jingyi0605/codingns 0.1.1 → 0.1.3

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 (251) hide show
  1. package/README.md +14 -0
  2. package/dist/public/assets/{TerminalPage-CVG1cGAJ.js → TerminalPage-Nq5sPc5c.js} +19 -19
  3. package/dist/public/assets/index-9hnprhO7.css +1 -0
  4. package/dist/public/assets/index-BTpmuKhG.js +108 -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 +17 -0
  67. package/dist/server/modules/sessions/codex-app-server-helper-client.js +260 -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 +167 -44
  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 +42 -4
  84. package/dist/server/modules/sessions/session-live-runtime-service.js +343 -51
  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 +6 -2
  92. package/dist/server/modules/terminal/command-template-service.js +91 -5
  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/template-reverse-proxy-service.d.ts +10 -0
  149. package/dist/server/modules/terminal/template-reverse-proxy-service.js +320 -0
  150. package/dist/server/modules/terminal/template-reverse-proxy-service.js.map +1 -0
  151. package/dist/server/modules/terminal/terminal-controller.d.ts +1 -0
  152. package/dist/server/modules/terminal/terminal-controller.js +23 -7
  153. package/dist/server/modules/terminal/terminal-controller.js.map +1 -1
  154. package/dist/server/modules/terminal/terminal-service.d.ts +30 -14
  155. package/dist/server/modules/terminal/terminal-service.js +260 -51
  156. package/dist/server/modules/terminal/terminal-service.js.map +1 -1
  157. package/dist/server/modules/terminal/terminal-shell.d.ts +4 -0
  158. package/dist/server/modules/terminal/terminal-shell.js +165 -18
  159. package/dist/server/modules/terminal/terminal-shell.js.map +1 -1
  160. package/dist/server/modules/workbench/workspace-file-watcher.d.ts +30 -0
  161. package/dist/server/modules/workbench/workspace-file-watcher.js +137 -0
  162. package/dist/server/modules/workbench/workspace-file-watcher.js.map +1 -0
  163. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +48 -7
  164. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  165. package/dist/server/routes/git.js +1 -0
  166. package/dist/server/routes/git.js.map +1 -1
  167. package/dist/server/routes/preferences.d.ts +2 -1
  168. package/dist/server/routes/preferences.js +3 -1
  169. package/dist/server/routes/preferences.js.map +1 -1
  170. package/dist/server/routes/proxy.d.ts +3 -0
  171. package/dist/server/routes/proxy.js +24 -0
  172. package/dist/server/routes/proxy.js.map +1 -0
  173. package/dist/server/routes/sessions.js +2 -0
  174. package/dist/server/routes/sessions.js.map +1 -1
  175. package/dist/server/server/create-server.d.ts +4 -0
  176. package/dist/server/server/create-server.js +29 -5
  177. package/dist/server/server/create-server.js.map +1 -1
  178. package/dist/server/shared/utils/command-launch.d.ts +6 -0
  179. package/dist/server/shared/utils/command-launch.js +39 -0
  180. package/dist/server/shared/utils/command-launch.js.map +1 -0
  181. package/dist/server/shared/utils/perf-log.d.ts +1 -0
  182. package/dist/server/shared/utils/perf-log.js +8 -2
  183. package/dist/server/shared/utils/perf-log.js.map +1 -1
  184. package/dist/server/shared/utils/permission-debug-log.d.ts +2 -0
  185. package/dist/server/shared/utils/permission-debug-log.js +40 -0
  186. package/dist/server/shared/utils/permission-debug-log.js.map +1 -0
  187. package/dist/server/shared/utils/terminal-debug-log.d.ts +4 -0
  188. package/dist/server/shared/utils/terminal-debug-log.js +71 -0
  189. package/dist/server/shared/utils/terminal-debug-log.js.map +1 -0
  190. package/dist/server/storage/repositories/terminal-command-template-repository.d.ts +1 -0
  191. package/dist/server/storage/repositories/terminal-command-template-repository.js +34 -3
  192. package/dist/server/storage/repositories/terminal-command-template-repository.js.map +1 -1
  193. package/dist/server/storage/repositories/user-preference-profile-repository.d.ts +8 -0
  194. package/dist/server/storage/repositories/user-preference-profile-repository.js +46 -0
  195. package/dist/server/storage/repositories/user-preference-profile-repository.js.map +1 -0
  196. package/dist/server/storage/sqlite/client.js +27 -0
  197. package/dist/server/storage/sqlite/client.js.map +1 -1
  198. package/dist/server/storage/sqlite/schema.sql +15 -0
  199. package/dist/server/types/domain.d.ts +30 -1
  200. package/dist/server/ws/terminal-ws-hub.d.ts +2 -0
  201. package/dist/server/ws/terminal-ws-hub.js +42 -5
  202. package/dist/server/ws/terminal-ws-hub.js.map +1 -1
  203. package/dist/server/ws/workbench-ws-hub.d.ts +9 -1
  204. package/dist/server/ws/workbench-ws-hub.js +132 -21
  205. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  206. package/dist/server/ws/ws-server.d.ts +22 -1
  207. package/dist/server/ws/ws-server.js +82 -44
  208. package/dist/server/ws/ws-server.js.map +1 -1
  209. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js +42 -0
  210. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js.map +1 -1
  211. package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +30 -0
  212. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +103 -0
  213. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +1 -0
  214. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +1 -1
  215. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +167 -7
  216. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  217. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +1 -1
  218. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +1 -1
  219. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  220. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.d.ts +1 -0
  221. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js +8 -0
  222. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js.map +1 -0
  223. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js +31 -0
  224. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js.map +1 -1
  225. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +1 -1
  226. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +8 -4
  227. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  228. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +1 -0
  229. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +15 -0
  230. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
  231. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.d.ts +5 -0
  232. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +85 -1
  233. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  234. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +25 -0
  235. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +718 -17
  236. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  237. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.d.ts +3 -0
  238. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +106 -23
  239. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +1 -1
  240. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.d.ts +3 -0
  241. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js +19 -0
  242. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js.map +1 -1
  243. package/node_modules/@codingns/session-sync-core/dist/runtime/types.d.ts +3 -0
  244. package/node_modules/@codingns/session-sync-core/dist/services.d.ts +1 -1
  245. package/node_modules/@codingns/session-sync-core/dist/services.js +2 -2
  246. package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
  247. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +1 -1
  248. package/package.json +3 -2
  249. package/scripts/postinstall.mjs +15 -8
  250. package/dist/public/assets/index-BUPByQPG.css +0 -1
  251. 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,70 @@ 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
+ transport.setOnClose((error) => {
59
+ if (error) {
60
+ eventQueue.push({
61
+ type: "turn.failed",
62
+ timestamp: nextTimestamp(),
63
+ error: error.message
64
+ });
65
+ }
66
+ eventQueue.close();
67
+ });
68
+ await transport.startTurn(request, providerSessionId);
33
69
  return {
34
70
  providerSessionId,
35
71
  rawStoreRef,
36
72
  interrupt: async () => {
37
73
  abortController.abort();
74
+ await transport.interruptTurn().catch(() => {
75
+ return;
76
+ });
77
+ transport.close();
38
78
  },
39
- completed: this.runTurn(null, request, sink, providerSessionId, rawStoreRef, abortController, events, startedSession.bufferedEvents, launchedAtMs)
79
+ isAlive: () => transport.isClosed() === false,
80
+ completed: this.runTurn(null, request, sink, providerSessionId, rawStoreRef, abortController, eventQueue.iterator, [], launchedAtMs).finally(() => {
81
+ transport.close();
82
+ })
40
83
  };
41
84
  }
42
85
  async continueSession(request, sink) {
@@ -44,31 +87,77 @@ export class CodexRuntimeAdapter {
44
87
  if (!providerSessionId) {
45
88
  throw new Error("PROVIDER_SESSION_ID_REQUIRED");
46
89
  }
47
- const client = await loadCodexClient();
48
- const thread = client.resumeThread(providerSessionId, createThreadOptions(request));
90
+ const transport = this.options.transportFactory
91
+ ? this.options.transportFactory()
92
+ : createCodexAppServerTransport(this.options);
93
+ await transport.initialize();
49
94
  const fallbackRawStoreRef = request.rawStoreRef ?? buildRuntimeRawStoreRef(providerSessionId);
50
95
  const resolvedBinding = await this.resolveExistingSessionBinding(providerSessionId, fallbackRawStoreRef, request.workspacePath);
51
96
  const resolvedSessionId = resolvedBinding?.providerSessionId ?? providerSessionId;
52
- const rawStoreRef = resolvedBinding?.rawStoreRef ?? fallbackRawStoreRef;
97
+ const resumed = await transport.resumeThread(request, resolvedSessionId);
98
+ const rawStoreRef = resolvedBinding?.rawStoreRef ?? resumed.rawStoreRef ?? fallbackRawStoreRef;
53
99
  const abortController = new AbortController();
100
+ const eventQueue = createAsyncEventQueue();
54
101
  sink.updateSessionBinding({
55
102
  providerSessionId: resolvedSessionId,
56
103
  rawStoreRef
57
104
  });
105
+ transport.setNotificationHandler(async (notification) => {
106
+ const translated = translateCodexAppServerNotification(notification);
107
+ if (translated.turnId) {
108
+ eventQueue.setTurnId(translated.turnId);
109
+ }
110
+ if (translated.event) {
111
+ eventQueue.push(translated.event);
112
+ }
113
+ if (translated.terminal) {
114
+ eventQueue.close();
115
+ }
116
+ });
117
+ transport.setServerRequestHandler(async (serverRequest) => {
118
+ if (!this.options.handleServerRequest) {
119
+ throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
120
+ }
121
+ return this.options.handleServerRequest({
122
+ sessionId: request.sessionId,
123
+ providerSessionId: resolvedSessionId,
124
+ request: serverRequest
125
+ });
126
+ });
127
+ transport.setOnClose((error) => {
128
+ if (error) {
129
+ eventQueue.push({
130
+ type: "turn.failed",
131
+ timestamp: nextTimestamp(),
132
+ error: error.message
133
+ });
134
+ }
135
+ eventQueue.close();
136
+ });
137
+ await transport.startTurn(request, resolvedSessionId);
58
138
  return {
59
139
  providerSessionId: resolvedSessionId,
60
140
  rawStoreRef,
61
141
  interrupt: async () => {
62
142
  abortController.abort();
143
+ await transport.interruptTurn().catch(() => {
144
+ return;
145
+ });
146
+ transport.close();
63
147
  },
64
- completed: this.runTurn(thread, request, sink, resolvedSessionId, rawStoreRef, abortController, undefined, [], Date.now())
148
+ isAlive: () => transport.isClosed() === false,
149
+ completed: this.runTurn(null, request, sink, resolvedSessionId, rawStoreRef, abortController, eventQueue.iterator, [], Date.now()).finally(() => {
150
+ transport.close();
151
+ })
65
152
  };
66
153
  }
67
154
  async runTurn(thread, request, sink, providerSessionId, rawStoreRef, abortController, preparedEvents, bufferedEvents = [], launchedAtMs = Date.now()) {
68
155
  const context = {
69
156
  providerSessionId,
70
157
  rawStoreRef,
71
- sequence: 0,
158
+ // 运行时消息必须接在历史消息后面,不能每轮都从 1 重新编号,
159
+ // 否则前端会把新 assistant/tool 消息排到旧消息前面,表现成用户消息一直挂在底部。
160
+ sequence: Math.max(0, request.sequenceBase ?? 0),
72
161
  toolNameByCallId: new Map(),
73
162
  sink,
74
163
  workspacePath: request.workspacePath,
@@ -148,12 +237,23 @@ export class CodexRuntimeAdapter {
148
237
  status: "failed",
149
238
  providerSessionId: context.providerSessionId,
150
239
  rawStoreRef: context.rawStoreRef,
151
- errorCode: "CODEX_CLI_TURN_FAILED",
240
+ errorCode: classifyCodexDetailErrorCode(detail, "CODEX_CLI_TURN_FAILED"),
152
241
  detail,
153
242
  timestamp: pickTimestamp(event)
154
243
  });
155
244
  return;
156
245
  }
246
+ if (eventType === "turn.interrupted") {
247
+ await context.sink.emit({
248
+ type: "interrupted",
249
+ status: "interrupted",
250
+ providerSessionId: context.providerSessionId,
251
+ rawStoreRef: context.rawStoreRef,
252
+ detail: "codex turn interrupted",
253
+ timestamp: pickTimestamp(event)
254
+ });
255
+ return;
256
+ }
157
257
  if (interrupted) {
158
258
  return;
159
259
  }
@@ -451,6 +551,400 @@ export class CodexRuntimeAdapter {
451
551
  }
452
552
  }
453
553
  }
554
+ function createCodexAppServerTransport(options) {
555
+ const commandPath = resolveCodexCommand(options.commandPath);
556
+ const launch = resolveCodexCommandLaunch(commandPath, ["app-server"]);
557
+ const child = spawn(launch.command, launch.args, {
558
+ env: process.env,
559
+ stdio: ["pipe", "pipe", "pipe"],
560
+ shell: launch.shell,
561
+ windowsHide: true
562
+ });
563
+ const stdout = createInterface({ input: child.stdout });
564
+ let notificationHandler = () => undefined;
565
+ let serverRequestHandler = async () => {
566
+ throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
567
+ };
568
+ let requestSequence = 0;
569
+ let closed = false;
570
+ let activeTurnId = null;
571
+ let activeThreadId = null;
572
+ let closeHandler = null;
573
+ const pendingResponses = new Map();
574
+ const finalize = (error) => {
575
+ if (closed) {
576
+ return;
577
+ }
578
+ closed = true;
579
+ stdout.close();
580
+ for (const pending of pendingResponses.values()) {
581
+ pending.reject(error ?? new Error("CODEX_APP_SERVER_CLOSED"));
582
+ }
583
+ pendingResponses.clear();
584
+ closeHandler?.(error);
585
+ };
586
+ child.on("error", (error) => {
587
+ finalize(error);
588
+ });
589
+ child.on("exit", (code, signal) => {
590
+ if (closed) {
591
+ return;
592
+ }
593
+ const detail = signal
594
+ ? `codex app-server exited with signal ${signal}`
595
+ : `codex app-server exited with code ${String(code ?? "unknown")}`;
596
+ finalize(new Error(detail));
597
+ });
598
+ stdout.on("line", (line) => {
599
+ const trimmed = line.trim();
600
+ if (!trimmed) {
601
+ return;
602
+ }
603
+ let parsed;
604
+ try {
605
+ parsed = JSON.parse(trimmed);
606
+ }
607
+ catch {
608
+ return;
609
+ }
610
+ if (typeof parsed.method === "string" && parsed.id !== undefined) {
611
+ void Promise.resolve(serverRequestHandler(parsed))
612
+ .then((result) => {
613
+ writeJsonRpcMessage(child, {
614
+ jsonrpc: "2.0",
615
+ id: parsed.id,
616
+ result
617
+ });
618
+ })
619
+ .catch((error) => {
620
+ writeJsonRpcMessage(child, {
621
+ jsonrpc: "2.0",
622
+ id: parsed.id,
623
+ error: {
624
+ code: -32000,
625
+ message: error instanceof Error ? error.message : "CODEX_APP_SERVER_REQUEST_FAILED"
626
+ }
627
+ });
628
+ });
629
+ return;
630
+ }
631
+ if (typeof parsed.method === "string") {
632
+ const method = parsed.method.trim();
633
+ const params = readJsonRpcParams(parsed);
634
+ if (method === "turn/started") {
635
+ activeTurnId = ensureText(readProp(readProp(params, "turn"), "id")).trim() || activeTurnId;
636
+ }
637
+ if (method === "thread/started") {
638
+ activeThreadId = ensureText(readProp(readProp(params, "thread"), "id")).trim() || activeThreadId;
639
+ }
640
+ void notificationHandler({
641
+ method,
642
+ params
643
+ });
644
+ return;
645
+ }
646
+ const responseId = String(parsed.id ?? "");
647
+ const pending = pendingResponses.get(responseId);
648
+ if (!pending) {
649
+ return;
650
+ }
651
+ pendingResponses.delete(responseId);
652
+ if (parsed.error && typeof parsed.error === "object") {
653
+ const message = ensureText(readProp(parsed.error, "message")).trim() || "CODEX_APP_SERVER_ERROR";
654
+ pending.reject(new Error(message));
655
+ return;
656
+ }
657
+ pending.resolve(readJsonRpcResult(parsed));
658
+ });
659
+ return {
660
+ async initialize() {
661
+ await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("initialize", () => ++requestSequence), {
662
+ method: "initialize",
663
+ params: {
664
+ clientInfo: {
665
+ name: "codingns-runtime",
666
+ version: "0.0.0"
667
+ },
668
+ capabilities: null
669
+ }
670
+ });
671
+ writeJsonRpcMessage(child, {
672
+ jsonrpc: "2.0",
673
+ method: "initialized",
674
+ params: {}
675
+ });
676
+ },
677
+ async startThread(request) {
678
+ const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("thread-start", () => ++requestSequence), {
679
+ method: "thread/start",
680
+ params: createThreadStartParams(request)
681
+ });
682
+ const thread = toRecord(result.thread);
683
+ const providerSessionId = ensureText(thread?.id).trim();
684
+ if (!providerSessionId) {
685
+ throw new Error("CODEX_APP_SERVER_THREAD_ID_MISSING");
686
+ }
687
+ activeThreadId = providerSessionId;
688
+ return {
689
+ providerSessionId,
690
+ rawStoreRef: normalizeText(thread?.path) || null
691
+ };
692
+ },
693
+ async resumeThread(request, providerSessionId) {
694
+ const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("thread-resume", () => ++requestSequence), {
695
+ method: "thread/resume",
696
+ params: createThreadResumeParams(request, providerSessionId)
697
+ });
698
+ const thread = toRecord(result.thread);
699
+ activeThreadId = ensureText(thread?.id).trim() || providerSessionId;
700
+ return {
701
+ providerSessionId: activeThreadId,
702
+ rawStoreRef: normalizeText(thread?.path) || null
703
+ };
704
+ },
705
+ async startTurn(request, providerSessionId) {
706
+ const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("turn-start", () => ++requestSequence), {
707
+ method: "turn/start",
708
+ params: createTurnStartParams(request, providerSessionId)
709
+ });
710
+ activeTurnId = ensureText(readProp(readProp(result, "turn"), "id")).trim() || activeTurnId;
711
+ },
712
+ async interruptTurn() {
713
+ if (!activeThreadId || !activeTurnId) {
714
+ return;
715
+ }
716
+ await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("turn-interrupt", () => ++requestSequence), {
717
+ method: "turn/interrupt",
718
+ params: {
719
+ threadId: activeThreadId,
720
+ turnId: activeTurnId
721
+ }
722
+ });
723
+ },
724
+ setNotificationHandler(handler) {
725
+ notificationHandler = handler;
726
+ },
727
+ setServerRequestHandler(handler) {
728
+ serverRequestHandler = handler;
729
+ },
730
+ setOnClose(handler) {
731
+ closeHandler = handler;
732
+ },
733
+ isClosed() {
734
+ return closed;
735
+ },
736
+ close() {
737
+ if (closed) {
738
+ return;
739
+ }
740
+ finalize(null);
741
+ if (!child.stdin.destroyed) {
742
+ child.stdin.end();
743
+ }
744
+ if (!child.killed) {
745
+ child.kill("SIGTERM");
746
+ }
747
+ }
748
+ };
749
+ }
750
+ function createAsyncEventQueue() {
751
+ const values = [];
752
+ const waiters = [];
753
+ let closed = false;
754
+ let turnId = null;
755
+ return {
756
+ iterator: {
757
+ next() {
758
+ if (values.length > 0) {
759
+ return Promise.resolve({
760
+ done: false,
761
+ value: values.shift()
762
+ });
763
+ }
764
+ if (closed) {
765
+ return Promise.resolve({
766
+ done: true,
767
+ value: undefined
768
+ });
769
+ }
770
+ return new Promise((resolve) => {
771
+ waiters.push(resolve);
772
+ });
773
+ }
774
+ },
775
+ push(value) {
776
+ if (closed) {
777
+ return;
778
+ }
779
+ const waiter = waiters.shift();
780
+ if (waiter) {
781
+ waiter({
782
+ done: false,
783
+ value
784
+ });
785
+ return;
786
+ }
787
+ values.push(value);
788
+ },
789
+ close() {
790
+ if (closed) {
791
+ return;
792
+ }
793
+ closed = true;
794
+ while (waiters.length > 0) {
795
+ waiters.shift()?.({
796
+ done: true,
797
+ value: undefined
798
+ });
799
+ }
800
+ },
801
+ setTurnId(nextTurnId) {
802
+ turnId = nextTurnId;
803
+ },
804
+ getTurnId() {
805
+ return turnId;
806
+ }
807
+ };
808
+ }
809
+ function translateCodexAppServerNotification(notification) {
810
+ const method = ensureText(notification.method).trim();
811
+ const params = toRecord(notification.params) ?? {};
812
+ if (method === "turn/started") {
813
+ return {
814
+ event: null,
815
+ terminal: false,
816
+ turnId: ensureText(readProp(readProp(params, "turn"), "id")).trim() || null
817
+ };
818
+ }
819
+ if (method === "turn/completed") {
820
+ const turn = toRecord(params.turn);
821
+ const status = ensureText(turn?.status).trim();
822
+ if (status === "failed") {
823
+ return {
824
+ event: {
825
+ type: "turn.failed",
826
+ timestamp: nextTimestamp(),
827
+ error: ensureText(readProp(turn?.error, "message")).trim() || "codex turn failed"
828
+ },
829
+ terminal: true,
830
+ turnId: ensureText(turn?.id).trim() || null
831
+ };
832
+ }
833
+ if (status === "interrupted") {
834
+ return {
835
+ event: {
836
+ type: "turn.interrupted",
837
+ timestamp: nextTimestamp()
838
+ },
839
+ terminal: true,
840
+ turnId: ensureText(turn?.id).trim() || null
841
+ };
842
+ }
843
+ return {
844
+ event: {
845
+ type: "turn.completed",
846
+ timestamp: nextTimestamp()
847
+ },
848
+ terminal: true,
849
+ turnId: ensureText(turn?.id).trim() || null
850
+ };
851
+ }
852
+ if (method === "item/started" || method === "item/completed") {
853
+ const item = translateCodexAppServerItem(toRecord(params.item));
854
+ if (!item) {
855
+ return {
856
+ event: null,
857
+ terminal: false,
858
+ turnId: null
859
+ };
860
+ }
861
+ return {
862
+ event: {
863
+ type: method === "item/started" ? "item.started" : "item.completed",
864
+ item,
865
+ timestamp: nextTimestamp()
866
+ },
867
+ terminal: false,
868
+ turnId: null
869
+ };
870
+ }
871
+ return {
872
+ event: null,
873
+ terminal: false,
874
+ turnId: null
875
+ };
876
+ }
877
+ function translateCodexAppServerItem(item) {
878
+ if (!item) {
879
+ return null;
880
+ }
881
+ const itemType = ensureText(item.type).trim();
882
+ if (!itemType) {
883
+ return null;
884
+ }
885
+ if (itemType === "agentMessage") {
886
+ return {
887
+ type: "agent_message",
888
+ id: item.id,
889
+ text: item.text
890
+ };
891
+ }
892
+ if (itemType === "reasoning") {
893
+ return {
894
+ type: "reasoning",
895
+ id: item.id,
896
+ text: Array.isArray(item.content) ? item.content.join("\n") : "",
897
+ summary: Array.isArray(item.summary) ? item.summary.join("\n") : ""
898
+ };
899
+ }
900
+ if (itemType === "commandExecution") {
901
+ return {
902
+ type: "command_execution",
903
+ id: item.id,
904
+ command: item.command,
905
+ cwd: item.cwd,
906
+ status: normalizeCodexItemStatus(item.status),
907
+ commandActions: item.commandActions,
908
+ aggregated_output: item.aggregatedOutput,
909
+ exit_code: item.exitCode
910
+ };
911
+ }
912
+ if (itemType === "fileChange") {
913
+ const diffText = buildCodexFileChangeOutput(item.changes);
914
+ return {
915
+ type: "custom_tool_call",
916
+ id: item.id,
917
+ tool: "apply_patch",
918
+ input: diffText,
919
+ output: diffText,
920
+ status: normalizeCodexItemStatus(item.status)
921
+ };
922
+ }
923
+ if (itemType === "mcpToolCall") {
924
+ return {
925
+ type: "mcp_tool_call",
926
+ id: item.id,
927
+ tool: item.tool,
928
+ server: item.server,
929
+ arguments: item.arguments,
930
+ result: item.result,
931
+ error: item.error,
932
+ status: normalizeCodexItemStatus(item.status)
933
+ };
934
+ }
935
+ if (itemType === "dynamicToolCall") {
936
+ return {
937
+ type: "custom_tool_call",
938
+ id: item.id,
939
+ tool: item.tool,
940
+ input: item.arguments,
941
+ output: item.contentItems,
942
+ success: item.success,
943
+ status: normalizeCodexItemStatus(item.status)
944
+ };
945
+ }
946
+ return null;
947
+ }
454
948
  export function createThreadOptions(request) {
455
949
  const options = {
456
950
  workingDirectory: request.workspacePath,
@@ -470,6 +964,61 @@ export function createThreadOptions(request) {
470
964
  }
471
965
  return options;
472
966
  }
967
+ function createThreadStartParams(request) {
968
+ const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
969
+ const params = {
970
+ cwd: request.workspacePath,
971
+ approvalsReviewer: "user"
972
+ };
973
+ if (permissionOptions.approvalPolicy) {
974
+ params.approvalPolicy = permissionOptions.approvalPolicy;
975
+ }
976
+ if (permissionOptions.sandboxMode) {
977
+ params.sandbox = permissionOptions.sandboxMode;
978
+ }
979
+ if (request.options.model) {
980
+ params.model = request.options.model;
981
+ }
982
+ return params;
983
+ }
984
+ function createThreadResumeParams(request, providerSessionId) {
985
+ const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
986
+ const params = {
987
+ threadId: providerSessionId,
988
+ cwd: request.workspacePath,
989
+ approvalsReviewer: "user"
990
+ };
991
+ if (permissionOptions.approvalPolicy) {
992
+ params.approvalPolicy = permissionOptions.approvalPolicy;
993
+ }
994
+ if (permissionOptions.sandboxMode) {
995
+ params.sandbox = permissionOptions.sandboxMode;
996
+ }
997
+ if (request.options.model) {
998
+ params.model = request.options.model;
999
+ }
1000
+ return params;
1001
+ }
1002
+ function createTurnStartParams(request, providerSessionId) {
1003
+ const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
1004
+ const params = {
1005
+ threadId: providerSessionId,
1006
+ input: createCodexAppServerInput(request),
1007
+ cwd: request.workspacePath,
1008
+ approvalsReviewer: "user"
1009
+ };
1010
+ if (permissionOptions.approvalPolicy) {
1011
+ params.approvalPolicy = permissionOptions.approvalPolicy;
1012
+ }
1013
+ if (request.options.model) {
1014
+ params.model = request.options.model;
1015
+ }
1016
+ const reasoningEffort = normalizeCodexReasoningEffort(request.options.reasoningLevel);
1017
+ if (reasoningEffort) {
1018
+ params.effort = reasoningEffort;
1019
+ }
1020
+ return params;
1021
+ }
473
1022
  function normalizeCodexReasoningEffort(value) {
474
1023
  const normalized = value?.trim().toLowerCase() ?? null;
475
1024
  if (!normalized) {
@@ -507,6 +1056,23 @@ function createCodexInput(request) {
507
1056
  });
508
1057
  return input;
509
1058
  }
1059
+ function createCodexAppServerInput(request) {
1060
+ const input = [];
1061
+ const promptText = (request.options.providerPrompt ?? request.options.content).trim();
1062
+ if (promptText.length > 0) {
1063
+ input.push({
1064
+ type: "text",
1065
+ text: promptText
1066
+ });
1067
+ }
1068
+ for (const attachment of request.options.attachments) {
1069
+ input.push({
1070
+ type: "localImage",
1071
+ path: attachment.filePath
1072
+ });
1073
+ }
1074
+ return input;
1075
+ }
510
1076
  async function loadCodexClient() {
511
1077
  const moduleName = "@openai/codex-sdk";
512
1078
  const runtimeImport = new Function("name", "return import(name);");
@@ -553,6 +1119,80 @@ function buildRuntimeRawStoreRef(providerSessionId) {
553
1119
  function resolveRuntimeStoreKey(providerSessionId, sessionId) {
554
1120
  return providerSessionId.trim() || sessionId;
555
1121
  }
1122
+ function resolveCodexCommand(explicitPath) {
1123
+ const explicitCandidate = explicitPath?.trim() ||
1124
+ process.env.CODINGNS_CODEX_COMMAND?.trim() ||
1125
+ "codex";
1126
+ return explicitCandidate;
1127
+ }
1128
+ function resolveCodexCommandLaunch(commandPath, args) {
1129
+ const normalizedCommandPath = commandPath.trim();
1130
+ if (isNodeScriptPath(normalizedCommandPath)) {
1131
+ return {
1132
+ command: process.execPath,
1133
+ args: [normalizedCommandPath, ...args],
1134
+ shell: false
1135
+ };
1136
+ }
1137
+ return {
1138
+ command: normalizedCommandPath,
1139
+ args: [...args],
1140
+ shell: shouldSpawnViaShellOnWindows(normalizedCommandPath)
1141
+ };
1142
+ }
1143
+ function isNodeScriptPath(commandPath) {
1144
+ return /\.(?:c|m)?js$/i.test(commandPath);
1145
+ }
1146
+ function shouldSpawnViaShellOnWindows(commandPath) {
1147
+ if (process.platform !== "win32") {
1148
+ return false;
1149
+ }
1150
+ if (/\.(cmd|bat)$/i.test(commandPath)) {
1151
+ return true;
1152
+ }
1153
+ // Windows 上裸名命令(无扩展名、无路径分隔符)需要 shell 才能从 PATH 解析 .cmd 文件
1154
+ const extension = commandPath.split(".").pop()?.toLowerCase();
1155
+ const hasPathSep = commandPath.includes("\\") || commandPath.includes("/");
1156
+ if (!extension || extension === commandPath.toLowerCase()) {
1157
+ if (!hasPathSep) {
1158
+ return true;
1159
+ }
1160
+ }
1161
+ return false;
1162
+ }
1163
+ function nextJsonRpcId(prefix, allocate) {
1164
+ return `${prefix}:${allocate()}`;
1165
+ }
1166
+ function writeJsonRpcMessage(child, payload) {
1167
+ if (!child.stdin || child.stdin.destroyed || !child.stdin.writable) {
1168
+ throw new Error("CODEX_APP_SERVER_STDIN_UNAVAILABLE");
1169
+ }
1170
+ child.stdin.write(`${JSON.stringify(payload)}\n`, "utf8");
1171
+ }
1172
+ function sendJsonRpcRequest(child, pendingResponses, createRequestId, input) {
1173
+ const id = createRequestId();
1174
+ return new Promise((resolve, reject) => {
1175
+ pendingResponses.set(id, { resolve, reject });
1176
+ try {
1177
+ writeJsonRpcMessage(child, {
1178
+ jsonrpc: "2.0",
1179
+ id,
1180
+ method: input.method,
1181
+ params: input.params
1182
+ });
1183
+ }
1184
+ catch (error) {
1185
+ pendingResponses.delete(id);
1186
+ reject(error instanceof Error ? error : new Error("CODEX_APP_SERVER_REQUEST_WRITE_FAILED"));
1187
+ }
1188
+ });
1189
+ }
1190
+ function readJsonRpcParams(parsed) {
1191
+ return toRecord(parsed.params) ?? {};
1192
+ }
1193
+ function readJsonRpcResult(parsed) {
1194
+ return toRecord(parsed.result) ?? {};
1195
+ }
556
1196
  function resolveResumeThreadId(providerSessionId, rawStoreRef) {
557
1197
  const normalizedProviderSessionId = ensureText(providerSessionId).trim();
558
1198
  const fromRawStore = readThreadIdFromRawStore(rawStoreRef);
@@ -570,6 +1210,12 @@ function readProp(value, key) {
570
1210
  }
571
1211
  return value[key];
572
1212
  }
1213
+ function toRecord(value) {
1214
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1215
+ return null;
1216
+ }
1217
+ return value;
1218
+ }
573
1219
  function ensureText(value) {
574
1220
  if (typeof value === "string") {
575
1221
  return value;
@@ -584,6 +1230,10 @@ function ensureText(value) {
584
1230
  return String(value);
585
1231
  }
586
1232
  }
1233
+ function normalizeText(value) {
1234
+ const normalized = ensureText(value).trim();
1235
+ return normalized.length > 0 ? normalized : null;
1236
+ }
587
1237
  function readThreadIdFromRawStore(rawStoreRef) {
588
1238
  const filePath = ensureText(rawStoreRef).trim();
589
1239
  if (!filePath || !existsSync(filePath)) {
@@ -715,9 +1365,14 @@ function pickFirstNonEmpty(...values) {
715
1365
  }
716
1366
  function isToolItem(itemType) {
717
1367
  return (itemType === "command_execution" ||
1368
+ itemType === "file_change" ||
718
1369
  itemType === "mcp_tool_call" ||
719
1370
  itemType === "function_call" ||
720
- itemType === "custom_tool_call");
1371
+ itemType === "custom_tool_call" ||
1372
+ itemType === "commandExecution" ||
1373
+ itemType === "fileChange" ||
1374
+ itemType === "mcpToolCall" ||
1375
+ itemType === "dynamicToolCall");
721
1376
  }
722
1377
  function inferToolSuccess(item, output) {
723
1378
  const status = ensureText(readProp(item, "status")).trim().toLowerCase();
@@ -758,10 +1413,23 @@ function classifyCodexRuntimeFailure(error) {
758
1413
  };
759
1414
  }
760
1415
  return {
761
- errorCode: "CODEX_RUNTIME_ERROR",
1416
+ errorCode: classifyCodexDetailErrorCode(detail, "CODEX_RUNTIME_ERROR"),
762
1417
  detail
763
1418
  };
764
1419
  }
1420
+ function classifyCodexDetailErrorCode(detail, fallback) {
1421
+ const normalized = detail.trim();
1422
+ if (!normalized) {
1423
+ return fallback;
1424
+ }
1425
+ const statusMatch = normalized.match(/\bstatus\s+(\d{3})\b/i)
1426
+ ?? normalized.match(/\bHTTP\s+(\d{3})\b/i)
1427
+ ?? normalized.match(/\b(\d{3})\s+(?:Bad Gateway|Too Many Requests|Gateway Timeout|Service Unavailable)\b/i);
1428
+ if (!statusMatch) {
1429
+ return fallback;
1430
+ }
1431
+ return `CODEX_HTTP_${statusMatch[1]}`;
1432
+ }
765
1433
  function persistSyntheticUserMessageIfNeeded(rawStoreRef, providerSessionId, input) {
766
1434
  if (!isSyntheticRawStoreRef(rawStoreRef) || input.content.trim().length === 0) {
767
1435
  return;
@@ -921,4 +1589,37 @@ function mapToolStartItemType(itemType) {
921
1589
  function mapToolResultItemType(itemType) {
922
1590
  return itemType === "custom_tool_call" ? "custom_tool_call_output" : "function_call_output";
923
1591
  }
1592
+ function normalizeCodexItemStatus(value) {
1593
+ const normalized = ensureText(value).trim();
1594
+ if (!normalized) {
1595
+ return "in_progress";
1596
+ }
1597
+ if (normalized === "inProgress") {
1598
+ return "running";
1599
+ }
1600
+ if (normalized === "declined") {
1601
+ return "failed";
1602
+ }
1603
+ return normalized;
1604
+ }
1605
+ function buildCodexFileChangeOutput(value) {
1606
+ if (!Array.isArray(value)) {
1607
+ return "";
1608
+ }
1609
+ return value
1610
+ .map((change) => {
1611
+ const record = toRecord(change);
1612
+ if (!record) {
1613
+ return "";
1614
+ }
1615
+ const diff = ensureText(record.diff).trim();
1616
+ if (diff.length > 0) {
1617
+ return diff;
1618
+ }
1619
+ const path = ensureText(record.path).trim();
1620
+ return path.length > 0 ? `Updated ${path}` : "";
1621
+ })
1622
+ .filter((entry) => entry.length > 0)
1623
+ .join("\n\n");
1624
+ }
924
1625
  //# sourceMappingURL=codex-runtime.js.map