@jingyi0605/codingns 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/dist/public/assets/{TerminalPage-4ulgBhv9.js → TerminalPage-BlbQuWi1.js} +1 -1
  2. package/dist/public/assets/gemini-D4G1NbrE.png +0 -0
  3. package/dist/public/assets/index-1VIm8lVL.css +1 -0
  4. package/dist/public/assets/index-Dti93O2S.js +109 -0
  5. package/dist/public/assets/kimi-BWNNSh7e.png +0 -0
  6. package/dist/public/index.html +2 -2
  7. package/dist/server/config/env.d.ts +7 -0
  8. package/dist/server/config/env.js +150 -1
  9. package/dist/server/config/env.js.map +1 -1
  10. package/dist/server/config/opencode-system-probe-helper-process.d.ts +24 -0
  11. package/dist/server/config/opencode-system-probe-helper-process.js +70 -5
  12. package/dist/server/config/opencode-system-probe-helper-process.js.map +1 -1
  13. package/dist/server/modules/butler/butler-action-context-service.d.ts +30 -0
  14. package/dist/server/modules/butler/butler-action-context-service.js +108 -0
  15. package/dist/server/modules/butler/butler-action-context-service.js.map +1 -0
  16. package/dist/server/modules/butler/butler-auth-service.d.ts +17 -0
  17. package/dist/server/modules/butler/butler-auth-service.js +91 -0
  18. package/dist/server/modules/butler/butler-auth-service.js.map +1 -0
  19. package/dist/server/modules/butler/butler-control-action-service.d.ts +65 -0
  20. package/dist/server/modules/butler/butler-control-action-service.js +296 -0
  21. package/dist/server/modules/butler/butler-control-action-service.js.map +1 -0
  22. package/dist/server/modules/butler/butler-control-session-service.d.ts +55 -0
  23. package/dist/server/modules/butler/butler-control-session-service.js +367 -0
  24. package/dist/server/modules/butler/butler-control-session-service.js.map +1 -0
  25. package/dist/server/modules/butler/butler-controller.d.ts +367 -0
  26. package/dist/server/modules/butler/butler-controller.js +475 -0
  27. package/dist/server/modules/butler/butler-controller.js.map +1 -0
  28. package/dist/server/modules/butler/butler-follow-up-evaluation-instruction-adapter.d.ts +34 -0
  29. package/dist/server/modules/butler/butler-follow-up-evaluation-instruction-adapter.js +77 -0
  30. package/dist/server/modules/butler/butler-follow-up-evaluation-instruction-adapter.js.map +1 -0
  31. package/dist/server/modules/butler/butler-follow-up-scheduler.d.ts +23 -0
  32. package/dist/server/modules/butler/butler-follow-up-scheduler.js +57 -0
  33. package/dist/server/modules/butler/butler-follow-up-scheduler.js.map +1 -0
  34. package/dist/server/modules/butler/butler-follow-up-service.d.ts +86 -0
  35. package/dist/server/modules/butler/butler-follow-up-service.js +948 -0
  36. package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -0
  37. package/dist/server/modules/butler/butler-inbox-service.d.ts +35 -0
  38. package/dist/server/modules/butler/butler-inbox-service.js +136 -0
  39. package/dist/server/modules/butler/butler-inbox-service.js.map +1 -0
  40. package/dist/server/modules/butler/butler-notification-service.d.ts +12 -0
  41. package/dist/server/modules/butler/butler-notification-service.js +45 -0
  42. package/dist/server/modules/butler/butler-notification-service.js.map +1 -0
  43. package/dist/server/modules/butler/butler-profile-service.d.ts +26 -0
  44. package/dist/server/modules/butler/butler-profile-service.js +529 -0
  45. package/dist/server/modules/butler/butler-profile-service.js.map +1 -0
  46. package/dist/server/modules/butler/butler-project-service.d.ts +48 -0
  47. package/dist/server/modules/butler/butler-project-service.js +253 -0
  48. package/dist/server/modules/butler/butler-project-service.js.map +1 -0
  49. package/dist/server/modules/butler/butler-session-service.d.ts +79 -0
  50. package/dist/server/modules/butler/butler-session-service.js +503 -0
  51. package/dist/server/modules/butler/butler-session-service.js.map +1 -0
  52. package/dist/server/modules/butler/butler-session-summary-service.d.ts +55 -0
  53. package/dist/server/modules/butler/butler-session-summary-service.js +382 -0
  54. package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -0
  55. package/dist/server/modules/butler/context-aggregator.d.ts +187 -0
  56. package/dist/server/modules/butler/context-aggregator.js +807 -0
  57. package/dist/server/modules/butler/context-aggregator.js.map +1 -0
  58. package/dist/server/modules/butler/instruction-adapter.d.ts +28 -0
  59. package/dist/server/modules/butler/instruction-adapter.js +101 -0
  60. package/dist/server/modules/butler/instruction-adapter.js.map +1 -0
  61. package/dist/server/modules/butler/patrol-execution-service.d.ts +47 -0
  62. package/dist/server/modules/butler/patrol-execution-service.js +347 -0
  63. package/dist/server/modules/butler/patrol-execution-service.js.map +1 -0
  64. package/dist/server/modules/butler/patrol-plan-service.d.ts +54 -0
  65. package/dist/server/modules/butler/patrol-plan-service.js +272 -0
  66. package/dist/server/modules/butler/patrol-plan-service.js.map +1 -0
  67. package/dist/server/modules/butler/patrol-run-service.d.ts +60 -0
  68. package/dist/server/modules/butler/patrol-run-service.js +185 -0
  69. package/dist/server/modules/butler/patrol-run-service.js.map +1 -0
  70. package/dist/server/modules/butler/patrol-scheduler.d.ts +36 -0
  71. package/dist/server/modules/butler/patrol-scheduler.js +99 -0
  72. package/dist/server/modules/butler/patrol-scheduler.js.map +1 -0
  73. package/dist/server/modules/butler/project-memory-service.d.ts +30 -0
  74. package/dist/server/modules/butler/project-memory-service.js +103 -0
  75. package/dist/server/modules/butler/project-memory-service.js.map +1 -0
  76. package/dist/server/modules/butler/provider-adapter-registry.d.ts +61 -0
  77. package/dist/server/modules/butler/provider-adapter-registry.js +430 -0
  78. package/dist/server/modules/butler/provider-adapter-registry.js.map +1 -0
  79. package/dist/server/modules/butler/session-summary-instruction-adapter.d.ts +28 -0
  80. package/dist/server/modules/butler/session-summary-instruction-adapter.js +79 -0
  81. package/dist/server/modules/butler/session-summary-instruction-adapter.js.map +1 -0
  82. package/dist/server/modules/butler/session-summary-scheduler.d.ts +23 -0
  83. package/dist/server/modules/butler/session-summary-scheduler.js +57 -0
  84. package/dist/server/modules/butler/session-summary-scheduler.js.map +1 -0
  85. package/dist/server/modules/butler/verification-run-service.d.ts +73 -0
  86. package/dist/server/modules/butler/verification-run-service.js +633 -0
  87. package/dist/server/modules/butler/verification-run-service.js.map +1 -0
  88. package/dist/server/modules/file/file-controller.d.ts +12 -1
  89. package/dist/server/modules/file/file-controller.js +72 -1
  90. package/dist/server/modules/file/file-controller.js.map +1 -1
  91. package/dist/server/modules/file/file-preview-link-service.d.ts +22 -0
  92. package/dist/server/modules/file/file-preview-link-service.js +160 -0
  93. package/dist/server/modules/file/file-preview-link-service.js.map +1 -0
  94. package/dist/server/modules/preferences/profile-service.js +8 -2
  95. package/dist/server/modules/preferences/profile-service.js.map +1 -1
  96. package/dist/server/modules/sessions/claude-runtime-helper-process.js +1 -1
  97. package/dist/server/modules/sessions/claude-runtime-helper-process.js.map +1 -1
  98. package/dist/server/modules/sessions/codex-app-server-helper-client.d.ts +7 -2
  99. package/dist/server/modules/sessions/codex-app-server-helper-client.js +113 -2
  100. package/dist/server/modules/sessions/codex-app-server-helper-client.js.map +1 -1
  101. package/dist/server/modules/sessions/codex-app-server-helper-process.js +106 -1
  102. package/dist/server/modules/sessions/codex-app-server-helper-process.js.map +1 -1
  103. package/dist/server/modules/sessions/session-controller.d.ts +24 -1
  104. package/dist/server/modules/sessions/session-controller.js +34 -3
  105. package/dist/server/modules/sessions/session-controller.js.map +1 -1
  106. package/dist/server/modules/sessions/session-history-service.d.ts +47 -2
  107. package/dist/server/modules/sessions/session-history-service.js +881 -56
  108. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  109. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +30 -2
  110. package/dist/server/modules/sessions/session-live-runtime-service.js +584 -159
  111. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  112. package/dist/server/modules/sessions/session-provider-error-mapper.js +94 -0
  113. package/dist/server/modules/sessions/session-provider-error-mapper.js.map +1 -1
  114. package/dist/server/modules/workbench/workbench-service.d.ts +7 -1
  115. package/dist/server/modules/workbench/workbench-service.js +31 -7
  116. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  117. package/dist/server/routes/butler.d.ts +3 -0
  118. package/dist/server/routes/butler.js +54 -0
  119. package/dist/server/routes/butler.js.map +1 -0
  120. package/dist/server/routes/files.js +2 -0
  121. package/dist/server/routes/files.js.map +1 -1
  122. package/dist/server/routes/sessions.js +1 -0
  123. package/dist/server/routes/sessions.js.map +1 -1
  124. package/dist/server/server/create-server.d.ts +65 -0
  125. package/dist/server/server/create-server.js +154 -5
  126. package/dist/server/server/create-server.js.map +1 -1
  127. package/dist/server/shared/utils/command-availability.d.ts +1 -0
  128. package/dist/server/shared/utils/command-availability.js +83 -0
  129. package/dist/server/shared/utils/command-availability.js.map +1 -0
  130. package/dist/server/storage/repositories/butler-control-event-repository.d.ts +8 -0
  131. package/dist/server/storage/repositories/butler-control-event-repository.js +78 -0
  132. package/dist/server/storage/repositories/butler-control-event-repository.js.map +1 -0
  133. package/dist/server/storage/repositories/butler-control-session-repository.d.ts +11 -0
  134. package/dist/server/storage/repositories/butler-control-session-repository.js +86 -0
  135. package/dist/server/storage/repositories/butler-control-session-repository.js.map +1 -0
  136. package/dist/server/storage/repositories/butler-follow-up-task-repository.d.ts +16 -0
  137. package/dist/server/storage/repositories/butler-follow-up-task-repository.js +252 -0
  138. package/dist/server/storage/repositories/butler-follow-up-task-repository.js.map +1 -0
  139. package/dist/server/storage/repositories/butler-inbox-item-repository.d.ts +15 -0
  140. package/dist/server/storage/repositories/butler-inbox-item-repository.js +111 -0
  141. package/dist/server/storage/repositories/butler-inbox-item-repository.js.map +1 -0
  142. package/dist/server/storage/repositories/butler-notification-archive-repository.d.ts +9 -0
  143. package/dist/server/storage/repositories/butler-notification-archive-repository.js +48 -0
  144. package/dist/server/storage/repositories/butler-notification-archive-repository.js.map +1 -0
  145. package/dist/server/storage/repositories/butler-profile-repository.d.ts +9 -0
  146. package/dist/server/storage/repositories/butler-profile-repository.js +86 -0
  147. package/dist/server/storage/repositories/butler-profile-repository.js.map +1 -0
  148. package/dist/server/storage/repositories/butler-project-repository.d.ts +14 -0
  149. package/dist/server/storage/repositories/butler-project-repository.js +140 -0
  150. package/dist/server/storage/repositories/butler-project-repository.js.map +1 -0
  151. package/dist/server/storage/repositories/butler-session-repository.d.ts +11 -0
  152. package/dist/server/storage/repositories/butler-session-repository.js +106 -0
  153. package/dist/server/storage/repositories/butler-session-repository.js.map +1 -0
  154. package/dist/server/storage/repositories/butler-session-summary-state-repository.d.ts +8 -0
  155. package/dist/server/storage/repositories/butler-session-summary-state-repository.js +62 -0
  156. package/dist/server/storage/repositories/butler-session-summary-state-repository.js.map +1 -0
  157. package/dist/server/storage/repositories/patrol-plan-repository.d.ts +27 -0
  158. package/dist/server/storage/repositories/patrol-plan-repository.js +119 -0
  159. package/dist/server/storage/repositories/patrol-plan-repository.js.map +1 -0
  160. package/dist/server/storage/repositories/patrol-run-repository.d.ts +28 -0
  161. package/dist/server/storage/repositories/patrol-run-repository.js +121 -0
  162. package/dist/server/storage/repositories/patrol-run-repository.js.map +1 -0
  163. package/dist/server/storage/repositories/project-memory-repository.d.ts +15 -0
  164. package/dist/server/storage/repositories/project-memory-repository.js +150 -0
  165. package/dist/server/storage/repositories/project-memory-repository.js.map +1 -0
  166. package/dist/server/storage/repositories/session-checkpoint-repository.d.ts +9 -0
  167. package/dist/server/storage/repositories/session-checkpoint-repository.js +72 -0
  168. package/dist/server/storage/repositories/session-checkpoint-repository.js.map +1 -0
  169. package/dist/server/storage/repositories/session-fork-repository.d.ts +8 -0
  170. package/dist/server/storage/repositories/session-fork-repository.js +69 -0
  171. package/dist/server/storage/repositories/session-fork-repository.js.map +1 -0
  172. package/dist/server/storage/repositories/session-index-repository.js +40 -2
  173. package/dist/server/storage/repositories/session-index-repository.js.map +1 -1
  174. package/dist/server/storage/repositories/session-message-origin-repository.d.ts +10 -0
  175. package/dist/server/storage/repositories/session-message-origin-repository.js +93 -0
  176. package/dist/server/storage/repositories/session-message-origin-repository.js.map +1 -0
  177. package/dist/server/storage/repositories/verification-run-repository.d.ts +29 -0
  178. package/dist/server/storage/repositories/verification-run-repository.js +125 -0
  179. package/dist/server/storage/repositories/verification-run-repository.js.map +1 -0
  180. package/dist/server/storage/sqlite/client.js +146 -0
  181. package/dist/server/storage/sqlite/client.js.map +1 -1
  182. package/dist/server/storage/sqlite/schema.sql +354 -0
  183. package/dist/server/types/domain.d.ts +286 -2
  184. package/dist/server/ws/ws-server.d.ts +2 -1
  185. package/dist/server/ws/ws-server.js +2 -1
  186. package/dist/server/ws/ws-server.js.map +1 -1
  187. package/node_modules/@codingns/session-sync-core/dist/index.d.ts +4 -0
  188. package/node_modules/@codingns/session-sync-core/dist/index.js +4 -0
  189. package/node_modules/@codingns/session-sync-core/dist/index.js.map +1 -1
  190. package/node_modules/@codingns/session-sync-core/dist/kimi-message-normalizer.d.ts +18 -0
  191. package/node_modules/@codingns/session-sync-core/dist/kimi-message-normalizer.js +659 -0
  192. package/node_modules/@codingns/session-sync-core/dist/kimi-message-normalizer.js.map +1 -0
  193. package/node_modules/@codingns/session-sync-core/dist/kimi-shared.d.ts +11 -0
  194. package/node_modules/@codingns/session-sync-core/dist/kimi-shared.js +72 -0
  195. package/node_modules/@codingns/session-sync-core/dist/kimi-shared.js.map +1 -0
  196. package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +8 -0
  197. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +89 -0
  198. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +1 -1
  199. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +6 -1
  200. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +228 -7
  201. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  202. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +26 -1
  203. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +499 -3
  204. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  205. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.d.ts +41 -0
  206. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js +1175 -0
  207. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js.map +1 -0
  208. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.d.ts +29 -0
  209. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js +578 -0
  210. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js.map +1 -0
  211. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +5 -1
  212. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +271 -4
  213. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  214. package/node_modules/@codingns/session-sync-core/dist/providers/utils.d.ts +1 -0
  215. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js +147 -19
  216. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js.map +1 -1
  217. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +2 -0
  218. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +43 -5
  219. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
  220. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +12 -0
  221. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +442 -71
  222. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  223. package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.d.ts +21 -0
  224. package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.js +537 -0
  225. package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.js.map +1 -0
  226. package/node_modules/@codingns/session-sync-core/dist/runtime/kimi-runtime.d.ts +38 -0
  227. package/node_modules/@codingns/session-sync-core/dist/runtime/kimi-runtime.js +911 -0
  228. package/node_modules/@codingns/session-sync-core/dist/runtime/kimi-runtime.js.map +1 -0
  229. package/node_modules/@codingns/session-sync-core/dist/services.d.ts +2 -1
  230. package/node_modules/@codingns/session-sync-core/dist/services.js +55 -8
  231. package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
  232. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.d.ts +6 -0
  233. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js +9 -0
  234. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js.map +1 -0
  235. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +27 -0
  236. package/node_modules/@codingns/session-sync-core/package.json +8 -0
  237. package/package.json +1 -1
  238. package/dist/public/assets/index-C5lu52cQ.css +0 -1
  239. package/dist/public/assets/index-WpdUo_Vs.js +0 -108
@@ -1,8 +1,8 @@
1
- import { DatabaseSync } from "node:sqlite";
2
1
  import { basename, dirname, join } from "node:path";
3
2
  import { existsSync, readFileSync, readdirSync, renameSync, statSync } from "node:fs";
4
3
  import crypto from "node:crypto";
5
4
  import { appendJsonLine, createRawRef, encodeCursor, ensureDirectory, extractTextBlocks, ensureText, messageIdFromRawRef, nextTimestamp, normalizeWorkspacePath, readFirstNonEmptyLine, readJsonLines, readTrailingJsonLines, safeDate, sliceHistory, stringifyStructuredValue, walkJsonlFiles } from "./utils.js";
5
+ import { loadDatabaseSync } from "../sqlite/node-sqlite.js";
6
6
  const CODEX_SESSION_TITLE_MAX_LENGTH = 48;
7
7
  const HISTORY_CACHE_LIMIT = 6;
8
8
  const SESSION_SUMMARY_CACHE_LIMIT = 512;
@@ -317,6 +317,80 @@ export class CodexAdapter {
317
317
  initialCursor: encodeCursor(options.initialPrompt ? 1 : 0)
318
318
  };
319
319
  }
320
+ async forkSession(providerSessionId, workspacePath, options) {
321
+ const transportFactory = this.options.forkTransportFactory;
322
+ if (!transportFactory) {
323
+ throw new Error("CODEX_FORK_TRANSPORT_NOT_CONFIGURED");
324
+ }
325
+ const transport = transportFactory();
326
+ try {
327
+ await transport.initialize();
328
+ if (options.sourceType === "session") {
329
+ const forked = await transport.forkThread(providerSessionId);
330
+ return await this.buildForkResultFromTransport({
331
+ providerSessionId: forked.providerSessionId,
332
+ rawStoreRef: forked.rawStoreRef,
333
+ workspacePath,
334
+ fallbackParentProviderSessionId: providerSessionId,
335
+ forkMethod: "native_session_fork",
336
+ forkSourceType: "session",
337
+ providerSourceMessageId: null
338
+ });
339
+ }
340
+ const targetMessageId = options.sourceMessageId?.trim();
341
+ if (!targetMessageId) {
342
+ throw new Error("FORK_SOURCE_MESSAGE_ID_REQUIRED");
343
+ }
344
+ if (options.strategy === "reconstruct-only") {
345
+ throw new Error("CODEX_RECONSTRUCTED_MESSAGE_FORK_NOT_SUPPORTED");
346
+ }
347
+ const resolvedStoreRef = this.resolveSessionFilePath(options.rawStoreRef, providerSessionId);
348
+ const parsedMessages = this.getParsedMessages(resolvedStoreRef, providerSessionId);
349
+ const targetMessage = parsedMessages.find((message) => message.messageId === targetMessageId);
350
+ if (!targetMessage) {
351
+ throw new Error("FORK_SOURCE_MESSAGE_NOT_FOUND");
352
+ }
353
+ const threadReadResult = await transport.readThread(providerSessionId);
354
+ const threadSnapshot = extractCodexThreadHistorySnapshot(threadReadResult);
355
+ if (threadSnapshot.kind === "turns") {
356
+ const rollbackPlan = buildCodexTurnRollbackPlan(threadSnapshot, parsedMessages, targetMessage);
357
+ const forked = await transport.forkThread(providerSessionId);
358
+ const finalized = rollbackPlan.numTurnsToRollback > 0
359
+ ? await transport.rollbackThread(forked.providerSessionId, rollbackPlan.numTurnsToRollback)
360
+ : forked;
361
+ return await this.buildForkResultFromTransport({
362
+ providerSessionId: finalized.providerSessionId,
363
+ rawStoreRef: finalized.rawStoreRef,
364
+ workspacePath,
365
+ fallbackParentProviderSessionId: providerSessionId,
366
+ forkMethod: "native_message_fork",
367
+ forkSourceType: "message",
368
+ providerSourceMessageId: null
369
+ });
370
+ }
371
+ const truncatedHistory = truncateCodexThreadHistory(threadSnapshot.value, parsedMessages, targetMessage);
372
+ if (truncatedHistory.length === 0) {
373
+ throw new Error("CODEX_FORK_HISTORY_EMPTY");
374
+ }
375
+ const resumed = await transport.resumeThreadFromHistory({
376
+ providerSessionId: null,
377
+ workspacePath,
378
+ history: truncatedHistory
379
+ });
380
+ return await this.buildForkResultFromTransport({
381
+ providerSessionId: resumed.providerSessionId,
382
+ rawStoreRef: resumed.rawStoreRef,
383
+ workspacePath,
384
+ fallbackParentProviderSessionId: providerSessionId,
385
+ forkMethod: "native_message_fork",
386
+ forkSourceType: "message",
387
+ providerSourceMessageId: null
388
+ });
389
+ }
390
+ finally {
391
+ transport.close();
392
+ }
393
+ }
320
394
  async sendMessage(providerSessionId, rawStoreRef, content, clientRequestId, _permissionMode) {
321
395
  const resolvedStoreRef = this.resolveSessionFilePath(rawStoreRef, providerSessionId);
322
396
  const lineNumber = readJsonLines(resolvedStoreRef).length + 1;
@@ -378,6 +452,7 @@ export class CodexAdapter {
378
452
  thread_name: nextTitle
379
453
  });
380
454
  if (stateDbPath) {
455
+ const DatabaseSync = loadDatabaseSync();
381
456
  let db = null;
382
457
  try {
383
458
  db = new DatabaseSync(stateDbPath, { open: true });
@@ -403,6 +478,7 @@ export class CodexAdapter {
403
478
  renameSync(resolvedStoreRef, nextStoreRef);
404
479
  }
405
480
  if (stateDbPath) {
481
+ const DatabaseSync = loadDatabaseSync();
406
482
  let db = null;
407
483
  try {
408
484
  db = new DatabaseSync(stateDbPath, { open: true });
@@ -437,6 +513,7 @@ export class CodexAdapter {
437
513
  supportsAttachments: true,
438
514
  supportsPermissionPrompt: true,
439
515
  supportsCheckpoint: false,
516
+ supportsSessionFork: true,
440
517
  limitations: [
441
518
  "Codex 产品原生支持将指导加入队列,但当前 SDK 0.116.0 仍未向宿主暴露运行中 queue/steer 提交入口。",
442
519
  "当前实现只维护原生会话文件,不负责直接驱动 Codex CLI 进程执行。"
@@ -543,6 +620,7 @@ export class CodexAdapter {
543
620
  };
544
621
  return index;
545
622
  }
623
+ const DatabaseSync = loadDatabaseSync();
546
624
  let db = null;
547
625
  try {
548
626
  db = new DatabaseSync(stateDbPath, { open: true, readOnly: true });
@@ -690,6 +768,37 @@ export class CodexAdapter {
690
768
  this.historyCache.delete(oldestKey);
691
769
  }
692
770
  }
771
+ async buildForkResultFromTransport(input) {
772
+ const resolvedStoreRef = input.rawStoreRef
773
+ ? this.resolveSessionFilePath(input.rawStoreRef, input.providerSessionId)
774
+ : this.findSessionFileByThreadId(input.providerSessionId)
775
+ ?? buildCodexActiveSessionPath(this.options.homeDir, `${input.providerSessionId}.jsonl`);
776
+ const messages = existsSync(resolvedStoreRef)
777
+ ? this.getParsedMessages(resolvedStoreRef, input.providerSessionId)
778
+ : [];
779
+ const threadMetadataIndex = this.readThreadMetadataIndex();
780
+ const threadMetadata = threadMetadataIndex.get(input.providerSessionId) ?? null;
781
+ const title = this.resolveIndexedTitle(threadMetadataIndex, input.providerSessionId)
782
+ ?? resolveCodexFallbackTitle(messages)
783
+ ?? "";
784
+ return {
785
+ session: {
786
+ provider: this.providerId,
787
+ providerSessionId: input.providerSessionId,
788
+ title,
789
+ workspacePath: input.workspacePath,
790
+ rawStoreRef: resolvedStoreRef,
791
+ isArchived: resolveCodexArchivedState(threadMetadata, resolvedStoreRef),
792
+ lastMessageAt: messages.at(-1)?.timestamp ?? nextTimestamp(),
793
+ messageCount: messages.length,
794
+ parentProviderSessionId: input.fallbackParentProviderSessionId
795
+ },
796
+ forkMethod: input.forkMethod,
797
+ forkSourceType: input.forkSourceType,
798
+ inheritedPrefixMessageCount: messages.length,
799
+ providerSourceMessageId: input.providerSourceMessageId
800
+ };
801
+ }
693
802
  touchSessionSummaryCache(filePath, entry) {
694
803
  this.sessionSummaryCache.delete(filePath);
695
804
  this.sessionSummaryCache.set(filePath, entry);
@@ -859,6 +968,7 @@ export class CodexAdapter {
859
968
  return this.parseMessagesFromEntries(filePath, records, providerSessionId);
860
969
  }
861
970
  parseMessagesFromEntries(filePath, records, providerSessionId) {
971
+ const effectiveRecords = filterRolledBackCodexRecords(records);
862
972
  const messages = [];
863
973
  const messageIndexesByKey = new Map();
864
974
  const toolNameById = new Map();
@@ -897,8 +1007,8 @@ export class CodexAdapter {
897
1007
  }
898
1008
  });
899
1009
  };
900
- records.forEach(({ lineNumber, data: record }) => {
901
- const rawRef = createRawRef(this.providerId, filePath, lineNumber);
1010
+ effectiveRecords.forEach(({ lineNumber, partIndex, data: record }) => {
1011
+ const rawRef = createRawRef(this.providerId, filePath, lineNumber, partIndex || undefined);
902
1012
  if (record.type === "event_msg") {
903
1013
  const payload = (record.payload ?? {});
904
1014
  const eventType = ensureText(payload.type);
@@ -1047,6 +1157,81 @@ export class CodexAdapter {
1047
1157
  return messages.map((entry) => entry.message);
1048
1158
  }
1049
1159
  }
1160
+ function filterRolledBackCodexRecords(records) {
1161
+ const completedTurnSegments = [];
1162
+ let activeTurnStartLineNumber = null;
1163
+ let sawRollbackEvent = false;
1164
+ for (const recordEntry of records) {
1165
+ const record = recordEntry.data;
1166
+ if (record.type !== "event_msg") {
1167
+ continue;
1168
+ }
1169
+ const payload = (record.payload ?? {});
1170
+ const eventType = ensureText(payload.type).trim();
1171
+ if (eventType === "task_started") {
1172
+ activeTurnStartLineNumber = recordEntry.lineNumber;
1173
+ continue;
1174
+ }
1175
+ if (eventType === "task_complete" || eventType === "task_failed") {
1176
+ if (activeTurnStartLineNumber !== null) {
1177
+ completedTurnSegments.push({
1178
+ startLineNumber: activeTurnStartLineNumber,
1179
+ endLineNumber: recordEntry.lineNumber,
1180
+ rolledBack: false
1181
+ });
1182
+ }
1183
+ activeTurnStartLineNumber = null;
1184
+ continue;
1185
+ }
1186
+ if (eventType !== "thread_rolled_back") {
1187
+ continue;
1188
+ }
1189
+ sawRollbackEvent = true;
1190
+ const requestedTurnCount = Math.max(0, Math.trunc(typeof payload.num_turns === "number"
1191
+ ? payload.num_turns
1192
+ : Number.parseInt(ensureText(payload.num_turns), 10)) || 0);
1193
+ if (requestedTurnCount <= 0) {
1194
+ continue;
1195
+ }
1196
+ let remainingTurnsToRollback = requestedTurnCount;
1197
+ for (let index = completedTurnSegments.length - 1; index >= 0; index -= 1) {
1198
+ const segment = completedTurnSegments[index];
1199
+ if (!segment || segment.rolledBack) {
1200
+ continue;
1201
+ }
1202
+ segment.rolledBack = true;
1203
+ remainingTurnsToRollback -= 1;
1204
+ if (remainingTurnsToRollback <= 0) {
1205
+ break;
1206
+ }
1207
+ }
1208
+ }
1209
+ if (!sawRollbackEvent) {
1210
+ return records;
1211
+ }
1212
+ const rolledBackSegments = completedTurnSegments
1213
+ .filter((segment) => segment.rolledBack)
1214
+ .sort((left, right) => left.startLineNumber - right.startLineNumber);
1215
+ if (rolledBackSegments.length === 0) {
1216
+ return records;
1217
+ }
1218
+ const filteredRecords = [];
1219
+ let segmentIndex = 0;
1220
+ for (const recordEntry of records) {
1221
+ while (segmentIndex < rolledBackSegments.length
1222
+ && recordEntry.lineNumber > rolledBackSegments[segmentIndex].endLineNumber) {
1223
+ segmentIndex += 1;
1224
+ }
1225
+ const activeSegment = segmentIndex < rolledBackSegments.length ? rolledBackSegments[segmentIndex] : null;
1226
+ if (activeSegment
1227
+ && recordEntry.lineNumber >= activeSegment.startLineNumber
1228
+ && recordEntry.lineNumber <= activeSegment.endLineNumber) {
1229
+ continue;
1230
+ }
1231
+ filteredRecords.push(recordEntry);
1232
+ }
1233
+ return filteredRecords;
1234
+ }
1050
1235
  function buildRecentHistoryPage(messages, totalMessageCount, limit) {
1051
1236
  const effectiveTotal = Math.max(totalMessageCount, messages.length);
1052
1237
  const pageMessages = messages.slice(-Math.min(limit, messages.length)).map((message, index, items) => ({
@@ -1362,4 +1547,315 @@ function normalizeCodexMessageTitle(content) {
1362
1547
  const normalized = normalizeCodexIndexedTitle(content);
1363
1548
  return normalized ? normalized.slice(0, CODEX_SESSION_TITLE_MAX_LENGTH) : null;
1364
1549
  }
1550
+ function extractCodexThreadHistory(result) {
1551
+ const snapshot = extractCodexThreadHistorySnapshot(result);
1552
+ return snapshot.value;
1553
+ }
1554
+ function extractCodexThreadHistorySnapshot(result) {
1555
+ const directHistory = pickCodexHistoryArray(result)
1556
+ ?? pickCodexHistoryArray(toRecord(result.thread))
1557
+ ?? pickCodexHistoryArray(toRecord(result.data));
1558
+ if (directHistory) {
1559
+ return {
1560
+ kind: "entries",
1561
+ value: directHistory,
1562
+ comparableEntries: directHistory.flatMap((entry, entryIndex) => {
1563
+ const signature = buildCodexThreadHistorySignature(entry);
1564
+ return signature ? [{ signature, entryIndex }] : [];
1565
+ })
1566
+ };
1567
+ }
1568
+ const turns = pickCodexTurnArray(result.turns)
1569
+ ?? pickCodexTurnArray(toRecord(result.thread)?.turns)
1570
+ ?? pickCodexTurnArray(toRecord(result.data)?.turns);
1571
+ if (!turns) {
1572
+ throw new Error("CODEX_THREAD_HISTORY_MISSING");
1573
+ }
1574
+ const comparableEntries = turns.flatMap((turn, turnIndex) => collectCodexTurnComparableEntries(turn, turnIndex));
1575
+ if (comparableEntries.length === 0) {
1576
+ throw new Error("CODEX_THREAD_HISTORY_MISSING");
1577
+ }
1578
+ return {
1579
+ kind: "turns",
1580
+ value: turns,
1581
+ comparableEntries
1582
+ };
1583
+ }
1584
+ function isSyntheticCodexSessionTitle(title) {
1585
+ const normalizedTitle = ensureText(title).trim();
1586
+ if (normalizedTitle.length === 0) {
1587
+ return false;
1588
+ }
1589
+ return (/^rollout-\d{4}-\d{2}-\d{2}t/i.test(normalizedTitle) ||
1590
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(normalizedTitle));
1591
+ }
1592
+ function pickCodexHistoryArray(value) {
1593
+ const record = toRecord(value);
1594
+ if (!record) {
1595
+ return null;
1596
+ }
1597
+ for (const key of ["history", "items"]) {
1598
+ const candidate = record[key];
1599
+ if (Array.isArray(candidate)
1600
+ && candidate.some((entry) => buildCodexThreadHistorySignature(entry) !== null)) {
1601
+ return candidate;
1602
+ }
1603
+ }
1604
+ return null;
1605
+ }
1606
+ function pickCodexTurnArray(value) {
1607
+ return Array.isArray(value) ? value : null;
1608
+ }
1609
+ function collectCodexTurnComparableEntries(value, turnIndex, parentPath = []) {
1610
+ const record = toRecord(value);
1611
+ if (!record) {
1612
+ return [];
1613
+ }
1614
+ for (const key of ["history", "items"]) {
1615
+ const candidate = record[key];
1616
+ if (Array.isArray(candidate)
1617
+ && candidate.some((entry) => buildCodexThreadHistorySignature(entry) !== null)) {
1618
+ const containerPath = [...parentPath, key];
1619
+ return candidate.flatMap((entry, entryIndex) => {
1620
+ const signature = buildCodexThreadHistorySignature(entry);
1621
+ return signature
1622
+ ? [{
1623
+ signature,
1624
+ turnIndex,
1625
+ containerPath,
1626
+ entryIndex
1627
+ }]
1628
+ : [];
1629
+ });
1630
+ }
1631
+ }
1632
+ return [
1633
+ ["input", record.input],
1634
+ ["output", record.output],
1635
+ ["turn", record.turn],
1636
+ ["data", record.data],
1637
+ ["result", record.result]
1638
+ ].flatMap(([key, candidate]) => collectCodexTurnComparableEntries(candidate, turnIndex, [...parentPath, key]));
1639
+ }
1640
+ function toRecord(value) {
1641
+ return typeof value === "object" && value !== null
1642
+ ? value
1643
+ : null;
1644
+ }
1645
+ function truncateCodexThreadHistory(history, parsedMessages, targetMessage) {
1646
+ const snapshot = normalizeCodexThreadHistorySnapshot(history);
1647
+ if (snapshot.kind === "entries") {
1648
+ const targetEntry = resolveCodexThreadHistoryTargetEntry(snapshot, parsedMessages, targetMessage);
1649
+ return snapshot.value.slice(0, targetEntry.entryIndex + 1);
1650
+ }
1651
+ const targetEntry = resolveCodexThreadHistoryTargetEntry(snapshot, parsedMessages, targetMessage);
1652
+ const truncatedTurns = snapshot.value.slice(0, targetEntry.turnIndex + 1);
1653
+ const lastTurn = truncatedTurns.at(-1);
1654
+ if (!lastTurn) {
1655
+ throw new Error("CODEX_FORK_SOURCE_MESSAGE_UNMAPPABLE");
1656
+ }
1657
+ return [
1658
+ ...flattenCodexTurnHistory(truncatedTurns.slice(0, -1)),
1659
+ ...collectCodexTurnHistoryItems(truncateCodexTurnAtPath(lastTurn, targetEntry.containerPath, targetEntry.entryIndex))
1660
+ ];
1661
+ }
1662
+ function normalizeCodexThreadHistorySnapshot(history) {
1663
+ const directComparableEntries = history.flatMap((entry, entryIndex) => {
1664
+ const signature = buildCodexThreadHistorySignature(entry);
1665
+ return signature ? [{ signature, entryIndex }] : [];
1666
+ });
1667
+ if (directComparableEntries.length > 0) {
1668
+ return {
1669
+ kind: "entries",
1670
+ value: history,
1671
+ comparableEntries: directComparableEntries
1672
+ };
1673
+ }
1674
+ const turnComparableEntries = history.flatMap((turn, turnIndex) => collectCodexTurnComparableEntries(turn, turnIndex));
1675
+ if (turnComparableEntries.length > 0) {
1676
+ return {
1677
+ kind: "turns",
1678
+ value: history,
1679
+ comparableEntries: turnComparableEntries
1680
+ };
1681
+ }
1682
+ throw new Error("CODEX_THREAD_HISTORY_MISSING");
1683
+ }
1684
+ function resolveCodexThreadHistoryTargetEntry(snapshot, parsedMessages, targetMessage) {
1685
+ const targetSignature = buildCodexThreadHistorySignature(targetMessage);
1686
+ if (!targetSignature) {
1687
+ throw new Error("CODEX_FORK_SOURCE_MESSAGE_UNMAPPABLE");
1688
+ }
1689
+ const matchingEntries = snapshot.comparableEntries.filter((entry) => entry.signature === targetSignature);
1690
+ if (matchingEntries.length === 0) {
1691
+ throw new Error("CODEX_FORK_SOURCE_MESSAGE_UNMAPPABLE");
1692
+ }
1693
+ const targetOccurrence = resolveCodexMessageSignatureOccurrence(parsedMessages, targetMessage);
1694
+ return matchingEntries[Math.min(targetOccurrence, matchingEntries.length) - 1] ?? matchingEntries.at(-1);
1695
+ }
1696
+ function resolveCodexMessageSignatureOccurrence(parsedMessages, targetMessage) {
1697
+ const targetSignature = buildCodexThreadHistorySignature(targetMessage);
1698
+ if (!targetSignature) {
1699
+ return 1;
1700
+ }
1701
+ let occurrence = 0;
1702
+ for (const message of parsedMessages) {
1703
+ if (buildCodexThreadHistorySignature(message) !== targetSignature) {
1704
+ continue;
1705
+ }
1706
+ occurrence += 1;
1707
+ if (message.messageId === targetMessage.messageId) {
1708
+ return occurrence;
1709
+ }
1710
+ }
1711
+ return Math.max(1, occurrence);
1712
+ }
1713
+ function buildCodexTurnRollbackPlan(snapshot, parsedMessages, targetMessage) {
1714
+ const targetEntry = resolveCodexThreadHistoryTargetEntry(snapshot, parsedMessages, targetMessage);
1715
+ const turnEntries = snapshot.comparableEntries.filter((entry) => entry.turnIndex === targetEntry.turnIndex);
1716
+ const lastComparableEntryInTurn = turnEntries.at(-1) ?? null;
1717
+ if (!lastComparableEntryInTurn) {
1718
+ throw new Error("CODEX_FORK_SOURCE_MESSAGE_UNMAPPABLE");
1719
+ }
1720
+ if (lastComparableEntryInTurn.containerPath.join("/") !== targetEntry.containerPath.join("/")
1721
+ || lastComparableEntryInTurn.entryIndex !== targetEntry.entryIndex) {
1722
+ throw new Error("CODEX_MESSAGE_FORK_TURN_BOUNDARY_REQUIRED");
1723
+ }
1724
+ return {
1725
+ targetTurnIndex: targetEntry.turnIndex,
1726
+ numTurnsToRollback: Math.max(0, snapshot.value.length - targetEntry.turnIndex - 1)
1727
+ };
1728
+ }
1729
+ function truncateCodexTurnAtPath(turn, containerPath, entryIndex) {
1730
+ if (containerPath.length === 0) {
1731
+ return turn;
1732
+ }
1733
+ const record = toRecord(turn);
1734
+ if (!record) {
1735
+ return turn;
1736
+ }
1737
+ const [head, ...rest] = containerPath;
1738
+ const current = record[head];
1739
+ if (rest.length === 0) {
1740
+ if (!Array.isArray(current)) {
1741
+ return turn;
1742
+ }
1743
+ return {
1744
+ ...record,
1745
+ [head]: current.slice(0, entryIndex + 1)
1746
+ };
1747
+ }
1748
+ return {
1749
+ ...record,
1750
+ [head]: truncateCodexTurnAtPath(current, rest, entryIndex)
1751
+ };
1752
+ }
1753
+ function flattenCodexTurnHistory(turns) {
1754
+ return turns.flatMap((turn) => collectCodexTurnHistoryItems(turn));
1755
+ }
1756
+ function collectCodexTurnHistoryItems(value) {
1757
+ const direct = pickCodexHistoryArray(value);
1758
+ if (direct) {
1759
+ return direct;
1760
+ }
1761
+ const record = toRecord(value);
1762
+ if (!record) {
1763
+ return [];
1764
+ }
1765
+ return [
1766
+ record.input,
1767
+ record.output,
1768
+ record.turn,
1769
+ record.data,
1770
+ record.result
1771
+ ].flatMap((candidate) => collectCodexTurnHistoryItems(candidate));
1772
+ }
1773
+ function buildCodexThreadHistorySignature(value) {
1774
+ if (!value || typeof value !== "object") {
1775
+ return null;
1776
+ }
1777
+ const item = value;
1778
+ const normalizedKind = ensureText(item.kind).trim();
1779
+ const normalizedRole = ensureText(item.role).trim();
1780
+ const normalizedContent = ensureText(item.content).trim();
1781
+ if (normalizedKind && normalizedRole) {
1782
+ return `${normalizedRole}:${normalizedKind}:${normalizedContent}`;
1783
+ }
1784
+ const type = ensureText(item.type).trim();
1785
+ if (type === "userMessage") {
1786
+ const content = stringifyCodexThreadMessageContent(item.content);
1787
+ return content ? `user:text:${content}` : null;
1788
+ }
1789
+ if (type === "agentMessage") {
1790
+ const content = ensureText(item.text).trim() || stringifyCodexThreadMessageContent(item.content);
1791
+ return content ? `assistant:text:${content}` : null;
1792
+ }
1793
+ if (type === "message") {
1794
+ const role = ensureText(item.role).trim();
1795
+ const content = stringifyCodexThreadMessageContent(item.content);
1796
+ if (!role || !content) {
1797
+ return null;
1798
+ }
1799
+ return `${role}:text:${content}`;
1800
+ }
1801
+ if (type === "reasoning") {
1802
+ const content = stringifyCodexReasoningContent(item.summary ?? item.content);
1803
+ return content ? `assistant:thinking:${content}` : null;
1804
+ }
1805
+ if (type === "function_call" || type === "tool_call") {
1806
+ const name = ensureText(item.name).trim();
1807
+ const inputValue = item.arguments ?? item.input;
1808
+ const content = stringifyStructuredValue(inputValue);
1809
+ return name || content ? `assistant:tool_call:${name}:${content}` : null;
1810
+ }
1811
+ if (type === "function_call_output" || type === "tool_result") {
1812
+ const content = ensureText(item.output ?? item.content).trim();
1813
+ return content ? `tool:tool_result:${content}` : null;
1814
+ }
1815
+ if (normalizedRole && normalizedContent) {
1816
+ return `${normalizedRole}:text:${normalizedContent}`;
1817
+ }
1818
+ return null;
1819
+ }
1820
+ function stringifyCodexThreadMessageContent(content) {
1821
+ if (typeof content === "string") {
1822
+ return content.trim();
1823
+ }
1824
+ if (!Array.isArray(content)) {
1825
+ return "";
1826
+ }
1827
+ return content
1828
+ .map((part) => {
1829
+ if (!part || typeof part !== "object") {
1830
+ return "";
1831
+ }
1832
+ const record = part;
1833
+ return ensureText(record.text
1834
+ ?? record.input_text
1835
+ ?? record.output_text
1836
+ ?? (ensureText(record.type).trim() === "text" ? record.text : null)).trim();
1837
+ })
1838
+ .filter((value) => value.length > 0)
1839
+ .join("\n")
1840
+ .trim();
1841
+ }
1842
+ function stringifyCodexReasoningContent(content) {
1843
+ if (typeof content === "string") {
1844
+ return content.trim();
1845
+ }
1846
+ if (!Array.isArray(content)) {
1847
+ return "";
1848
+ }
1849
+ return content
1850
+ .map((part) => {
1851
+ if (!part || typeof part !== "object") {
1852
+ return "";
1853
+ }
1854
+ const record = part;
1855
+ return ensureText(record.text ?? record.summary_text).trim();
1856
+ })
1857
+ .filter((value) => value.length > 0)
1858
+ .join("\n")
1859
+ .trim();
1860
+ }
1365
1861
  //# sourceMappingURL=codex.js.map