@jingyi0605/codingns 0.3.6 → 0.5.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 (369) hide show
  1. package/README.md +3 -0
  2. package/bin/codingns.mjs +913 -1
  3. package/dist/public/assets/AdaptiveButlerPage-B153lk5H.css +1 -0
  4. package/dist/public/assets/AdaptiveButlerPage-R-XZw7pd.js +3 -0
  5. package/dist/public/assets/App-DUAg5urj.css +1 -0
  6. package/dist/public/assets/App-DkvE5EyM.js +30 -0
  7. package/dist/public/assets/BootstrapPage-Vu5oEJ8z.js +1 -0
  8. package/dist/public/assets/ConversationPage-Cjpg6g0J.js +2 -0
  9. package/dist/public/assets/DesktopDetachPreviewPage-BgeEqbc5.js +1 -0
  10. package/dist/public/assets/DesktopWindowPage-1WelvxdH.js +2 -0
  11. package/dist/public/assets/FileContextPanel-D_ghXJuW.js +1 -0
  12. package/dist/public/assets/GitSidebar-D9f9Jxwr.js +6 -0
  13. package/dist/public/assets/MobileCreateSessionSheet-DLq5qPkx.js +1 -0
  14. package/dist/public/assets/MobileSheet-DLg-gX1t.js +1 -0
  15. package/dist/public/assets/MobileTopHeaderFrame-DArgZI7L.js +1 -0
  16. package/dist/public/assets/MobileWorkspaceSwitcherHeader-0ywJKfBQ.js +1 -0
  17. package/dist/public/assets/ServerSettingsModal-izoYMx9U.js +1 -0
  18. package/dist/public/assets/SessionIndexPage-C5aG8FIv.js +1 -0
  19. package/dist/public/assets/SettingsPage-HJIC-P-4.js +1 -0
  20. package/dist/public/assets/TerminalManagerPanel-DpyUTo9k.js +1 -0
  21. package/dist/public/assets/{TerminalPage-D00S4KM6.js → TerminalPage-CtKXIU0h.js} +19 -19
  22. package/dist/public/assets/TerminalRuntimeFallbackModal-CRhOQOsT.js +1 -0
  23. package/dist/public/assets/ToolFilesPage-DcYPsS-e.js +1 -0
  24. package/dist/public/assets/ToolGitPage-CsPl89ty.js +1 -0
  25. package/dist/public/assets/ToolProcessesPage-D0dvR8xK.js +1 -0
  26. package/dist/public/assets/ToolsHomePage-4fP-KRiv.js +1 -0
  27. package/dist/public/assets/WorkbenchLandingPage-kvlfyxRo.js +1 -0
  28. package/dist/public/assets/WorkbenchLayout-ByFw4eeu.js +3 -0
  29. package/dist/public/assets/WorkbenchModal-Ctob14VR.js +1 -0
  30. package/dist/public/assets/WorkbenchShellRoute-BUITtdAg.css +1 -0
  31. package/dist/public/assets/WorkbenchShellRoute-Kw7JEZI3.js +1 -0
  32. package/dist/public/assets/WorkspaceDebugDetailPage-Com5kEXJ.js +1 -0
  33. package/dist/public/assets/WorkspaceDetailPage-D0Lrx4Uz.js +1 -0
  34. package/dist/public/assets/WorkspaceHomePage-wR8d3aP9.js +1 -0
  35. package/dist/public/assets/butler-records-events-DgWCG364.js +1 -0
  36. package/dist/public/assets/default-session-permission-mode-CcGwR4Kk.js +1 -0
  37. package/dist/public/assets/event-DvH9tcej.js +1 -0
  38. package/dist/public/assets/file-tree-icon-UFVoVzhM.js +31 -0
  39. package/dist/public/assets/index-Byp9hJ0c.js +42 -0
  40. package/dist/public/assets/index-_52jxu4a.css +1 -0
  41. package/dist/public/assets/preferences-service-KIYeE2gk.js +1 -0
  42. package/dist/public/assets/session-runtime-machine-0KNSSPp5.js +17 -0
  43. package/dist/public/assets/styles-BWPBZvze.css +1 -0
  44. package/dist/public/assets/styles-CSUx5LGe.js +1 -0
  45. package/dist/public/assets/terminal-runtime-meta-AWXJpN4r.js +1 -0
  46. package/dist/public/assets/useRegisteredDebugTemplates-DBDRdptr.js +1 -0
  47. package/dist/public/assets/window-BWqRixxq.js +1 -0
  48. package/dist/public/index.html +2 -2
  49. package/dist/server/middlewares/auth-guard.d.ts +4 -0
  50. package/dist/server/middlewares/auth-guard.js +42 -4
  51. package/dist/server/middlewares/auth-guard.js.map +1 -1
  52. package/dist/server/modules/assistant-capability/assistant-capability-controller.d.ts +234 -0
  53. package/dist/server/modules/assistant-capability/assistant-capability-controller.js +365 -0
  54. package/dist/server/modules/assistant-capability/assistant-capability-controller.js.map +1 -1
  55. package/dist/server/modules/assistant-capability/assistant-capability-service.d.ts +262 -2
  56. package/dist/server/modules/assistant-capability/assistant-capability-service.js +737 -3
  57. package/dist/server/modules/assistant-capability/assistant-capability-service.js.map +1 -1
  58. package/dist/server/modules/auth/auth-controller.d.ts +11 -1
  59. package/dist/server/modules/auth/auth-controller.js +61 -2
  60. package/dist/server/modules/auth/auth-controller.js.map +1 -1
  61. package/dist/server/modules/auth/auth-device-display-name.d.ts +10 -0
  62. package/dist/server/modules/auth/auth-device-display-name.js +190 -0
  63. package/dist/server/modules/auth/auth-device-display-name.js.map +1 -0
  64. package/dist/server/modules/auth/auth-service.d.ts +80 -5
  65. package/dist/server/modules/auth/auth-service.js +333 -23
  66. package/dist/server/modules/auth/auth-service.js.map +1 -1
  67. package/dist/server/modules/butler/assistant-automation-service.d.ts +112 -0
  68. package/dist/server/modules/butler/assistant-automation-service.js +832 -0
  69. package/dist/server/modules/butler/assistant-automation-service.js.map +1 -0
  70. package/dist/server/modules/butler/assistant-automation-trigger.d.ts +94 -0
  71. package/dist/server/modules/butler/assistant-automation-trigger.js +400 -0
  72. package/dist/server/modules/butler/assistant-automation-trigger.js.map +1 -0
  73. package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.d.ts +32 -0
  74. package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.js +93 -0
  75. package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.js.map +1 -0
  76. package/dist/server/modules/butler/assistant-sandbox-service.d.ts +69 -0
  77. package/dist/server/modules/butler/assistant-sandbox-service.js +399 -0
  78. package/dist/server/modules/butler/assistant-sandbox-service.js.map +1 -0
  79. package/dist/server/modules/butler/butler-action-context-service.d.ts +4 -1
  80. package/dist/server/modules/butler/butler-action-context-service.js +8 -2
  81. package/dist/server/modules/butler/butler-action-context-service.js.map +1 -1
  82. package/dist/server/modules/butler/butler-auth-service.js +7 -2
  83. package/dist/server/modules/butler/butler-auth-service.js.map +1 -1
  84. package/dist/server/modules/butler/butler-control-session-service.d.ts +11 -1
  85. package/dist/server/modules/butler/butler-control-session-service.js +173 -40
  86. package/dist/server/modules/butler/butler-control-session-service.js.map +1 -1
  87. package/dist/server/modules/butler/butler-control-timer-scheduler.d.ts +32 -0
  88. package/dist/server/modules/butler/butler-control-timer-scheduler.js +93 -0
  89. package/dist/server/modules/butler/butler-control-timer-scheduler.js.map +1 -0
  90. package/dist/server/modules/butler/butler-control-timer-service.d.ts +42 -0
  91. package/dist/server/modules/butler/butler-control-timer-service.js +132 -0
  92. package/dist/server/modules/butler/butler-control-timer-service.js.map +1 -0
  93. package/dist/server/modules/butler/butler-controller.d.ts +42 -2
  94. package/dist/server/modules/butler/butler-controller.js +79 -12
  95. package/dist/server/modules/butler/butler-controller.js.map +1 -1
  96. package/dist/server/modules/butler/butler-follow-up-evaluation-instruction-adapter.d.ts +2 -1
  97. package/dist/server/modules/butler/butler-follow-up-evaluation-instruction-adapter.js +27 -25
  98. package/dist/server/modules/butler/butler-follow-up-evaluation-instruction-adapter.js.map +1 -1
  99. package/dist/server/modules/butler/butler-follow-up-service.d.ts +41 -5
  100. package/dist/server/modules/butler/butler-follow-up-service.js +568 -371
  101. package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -1
  102. package/dist/server/modules/butler/butler-inbox-analysis-service.d.ts +4 -1
  103. package/dist/server/modules/butler/butler-inbox-analysis-service.js +18 -4
  104. package/dist/server/modules/butler/butler-inbox-analysis-service.js.map +1 -1
  105. package/dist/server/modules/butler/butler-inbox-service.js +1 -0
  106. package/dist/server/modules/butler/butler-inbox-service.js.map +1 -1
  107. package/dist/server/modules/butler/butler-profile-service.js +2 -5
  108. package/dist/server/modules/butler/butler-profile-service.js.map +1 -1
  109. package/dist/server/modules/butler/butler-project-service.d.ts +3 -1
  110. package/dist/server/modules/butler/butler-project-service.js +7 -1
  111. package/dist/server/modules/butler/butler-project-service.js.map +1 -1
  112. package/dist/server/modules/butler/butler-session-service.d.ts +5 -1
  113. package/dist/server/modules/butler/butler-session-service.js +26 -1
  114. package/dist/server/modules/butler/butler-session-service.js.map +1 -1
  115. package/dist/server/modules/butler/butler-session-summary-service.js +2 -1
  116. package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -1
  117. package/dist/server/modules/butler/butler-workspace-context.d.ts +4 -1
  118. package/dist/server/modules/butler/butler-workspace-context.js +204 -58
  119. package/dist/server/modules/butler/butler-workspace-context.js.map +1 -1
  120. package/dist/server/modules/butler/patrol-execution-service.js +2 -1
  121. package/dist/server/modules/butler/patrol-execution-service.js.map +1 -1
  122. package/dist/server/modules/butler/provider-adapter-registry.d.ts +3 -0
  123. package/dist/server/modules/butler/provider-adapter-registry.js +18 -1
  124. package/dist/server/modules/butler/provider-adapter-registry.js.map +1 -1
  125. package/dist/server/modules/butler/verification-run-service.d.ts +9 -2
  126. package/dist/server/modules/butler/verification-run-service.js +188 -34
  127. package/dist/server/modules/butler/verification-run-service.js.map +1 -1
  128. package/dist/server/modules/debug-target/debug-target-controller.js +1 -1
  129. package/dist/server/modules/debug-target/debug-target-controller.js.map +1 -1
  130. package/dist/server/modules/debug-target/debug-target-service.d.ts +7 -2
  131. package/dist/server/modules/debug-target/debug-target-service.js +563 -100
  132. package/dist/server/modules/debug-target/debug-target-service.js.map +1 -1
  133. package/dist/server/modules/git/git-command-helper-client.d.ts +1 -0
  134. package/dist/server/modules/git/git-command-helper-client.js +19 -26
  135. package/dist/server/modules/git/git-command-helper-client.js.map +1 -1
  136. package/dist/server/modules/git/git-command-runner.js +19 -1
  137. package/dist/server/modules/git/git-command-runner.js.map +1 -1
  138. package/dist/server/modules/preferences/profile-service.d.ts +3 -1
  139. package/dist/server/modules/preferences/profile-service.js +74 -3
  140. package/dist/server/modules/preferences/profile-service.js.map +1 -1
  141. package/dist/server/modules/provider/provider-controller.d.ts +1 -1
  142. package/dist/server/modules/provider/provider-controller.js.map +1 -1
  143. package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +5 -3
  144. package/dist/server/modules/provider/provider-discovery-helper-client.js +129 -43
  145. package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -1
  146. package/dist/server/modules/provider/provider-discovery-helper-process.js +44 -0
  147. package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -1
  148. package/dist/server/modules/provider/provider-discovery-runtime.js +83 -3
  149. package/dist/server/modules/provider/provider-discovery-runtime.js.map +1 -1
  150. package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-identity-service.d.ts +10 -0
  151. package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-identity-service.js +48 -0
  152. package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-identity-service.js.map +1 -0
  153. package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-packets.d.ts +48 -0
  154. package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-packets.js +11 -0
  155. package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-packets.js.map +1 -0
  156. package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-protocol.d.ts +74 -0
  157. package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-protocol.js +302 -0
  158. package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-protocol.js.map +1 -0
  159. package/dist/server/modules/relay-tunnel/relay-tunnel-controller.d.ts +33 -0
  160. package/dist/server/modules/relay-tunnel/relay-tunnel-controller.js +57 -0
  161. package/dist/server/modules/relay-tunnel/relay-tunnel-controller.js.map +1 -0
  162. package/dist/server/modules/relay-tunnel/relay-tunnel-edge-proof.d.ts +9 -0
  163. package/dist/server/modules/relay-tunnel/relay-tunnel-edge-proof.js +25 -0
  164. package/dist/server/modules/relay-tunnel/relay-tunnel-edge-proof.js.map +1 -0
  165. package/dist/server/modules/relay-tunnel/relay-tunnel-gateway-service.d.ts +18 -0
  166. package/dist/server/modules/relay-tunnel/relay-tunnel-gateway-service.js +230 -0
  167. package/dist/server/modules/relay-tunnel/relay-tunnel-gateway-service.js.map +1 -0
  168. package/dist/server/modules/relay-tunnel/relay-tunnel-runtime-adapter.d.ts +41 -0
  169. package/dist/server/modules/relay-tunnel/relay-tunnel-runtime-adapter.js +443 -0
  170. package/dist/server/modules/relay-tunnel/relay-tunnel-runtime-adapter.js.map +1 -0
  171. package/dist/server/modules/relay-tunnel/relay-tunnel-service.d.ts +111 -0
  172. package/dist/server/modules/relay-tunnel/relay-tunnel-service.js +771 -0
  173. package/dist/server/modules/relay-tunnel/relay-tunnel-service.js.map +1 -0
  174. package/dist/server/modules/sessions/claude-runtime-helper-client.js +23 -1
  175. package/dist/server/modules/sessions/claude-runtime-helper-client.js.map +1 -1
  176. package/dist/server/modules/sessions/codex-app-server-helper-client.d.ts +2 -1
  177. package/dist/server/modules/sessions/codex-app-server-helper-client.js +78 -0
  178. package/dist/server/modules/sessions/codex-app-server-helper-client.js.map +1 -1
  179. package/dist/server/modules/sessions/codex-app-server-helper-process.js +84 -2
  180. package/dist/server/modules/sessions/codex-app-server-helper-process.js.map +1 -1
  181. package/dist/server/modules/sessions/provider-session-delete-cli.d.ts +15 -0
  182. package/dist/server/modules/sessions/provider-session-delete-cli.js +148 -0
  183. package/dist/server/modules/sessions/provider-session-delete-cli.js.map +1 -0
  184. package/dist/server/modules/sessions/session-controller.d.ts +4 -1
  185. package/dist/server/modules/sessions/session-controller.js +4 -0
  186. package/dist/server/modules/sessions/session-controller.js.map +1 -1
  187. package/dist/server/modules/sessions/session-history-service.d.ts +24 -1
  188. package/dist/server/modules/sessions/session-history-service.js +401 -42
  189. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  190. package/dist/server/modules/sessions/session-live-runtime-router-service.d.ts +25 -0
  191. package/dist/server/modules/sessions/session-live-runtime-router-service.js +42 -0
  192. package/dist/server/modules/sessions/session-live-runtime-router-service.js.map +1 -0
  193. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +6 -0
  194. package/dist/server/modules/sessions/session-live-runtime-service.js +130 -28
  195. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  196. package/dist/server/modules/sessions/session-message-attachment-service.d.ts +1 -0
  197. package/dist/server/modules/sessions/session-message-attachment-service.js +22 -0
  198. package/dist/server/modules/sessions/session-message-attachment-service.js.map +1 -1
  199. package/dist/server/modules/sessions/session-message-origin-utils.d.ts +12 -0
  200. package/dist/server/modules/sessions/session-message-origin-utils.js +45 -0
  201. package/dist/server/modules/sessions/session-message-origin-utils.js.map +1 -0
  202. package/dist/server/modules/sessions/session-permission-request-service.d.ts +1 -0
  203. package/dist/server/modules/sessions/session-permission-request-service.js +367 -5
  204. package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -1
  205. package/dist/server/modules/sessions/session-provider-error-mapper.js +32 -0
  206. package/dist/server/modules/sessions/session-provider-error-mapper.js.map +1 -1
  207. package/dist/server/modules/sessions/session-provider-usage-guard-service.d.ts +37 -0
  208. package/dist/server/modules/sessions/session-provider-usage-guard-service.js +179 -0
  209. package/dist/server/modules/sessions/session-provider-usage-guard-service.js.map +1 -0
  210. package/dist/server/modules/sessions/session-provider-usage-limit.d.ts +17 -0
  211. package/dist/server/modules/sessions/session-provider-usage-limit.js +465 -0
  212. package/dist/server/modules/sessions/session-provider-usage-limit.js.map +1 -0
  213. package/dist/server/modules/skills/assistant-runtime-skill-catalog.d.ts +8 -0
  214. package/dist/server/modules/skills/assistant-runtime-skill-catalog.js +26 -0
  215. package/dist/server/modules/skills/assistant-runtime-skill-catalog.js.map +1 -0
  216. package/dist/server/modules/skills/assistant-runtime-skill-cleanup.d.ts +9 -0
  217. package/dist/server/modules/skills/assistant-runtime-skill-cleanup.js +55 -0
  218. package/dist/server/modules/skills/assistant-runtime-skill-cleanup.js.map +1 -0
  219. package/dist/server/modules/skills/builtin-skill-service.js +1 -6
  220. package/dist/server/modules/skills/builtin-skill-service.js.map +1 -1
  221. package/dist/server/modules/skills/builtin-skills/codingns-assistant/SKILL.md +19 -12
  222. package/dist/server/modules/skills/builtin-skills/codingns-assistant/references/cli-workflow.md +9 -3
  223. package/dist/server/modules/skills/skill-controller.d.ts +2 -2
  224. package/dist/server/modules/skills/skill-controller.js +9 -1
  225. package/dist/server/modules/skills/skill-controller.js.map +1 -1
  226. package/dist/server/modules/skills/skill-manager-service.d.ts +26 -1
  227. package/dist/server/modules/skills/skill-manager-service.js +346 -90
  228. package/dist/server/modules/skills/skill-manager-service.js.map +1 -1
  229. package/dist/server/modules/skills/skill-name-policy.d.ts +2 -0
  230. package/dist/server/modules/skills/skill-name-policy.js +10 -0
  231. package/dist/server/modules/skills/skill-name-policy.js.map +1 -0
  232. package/dist/server/modules/tailscale/tailscale-service.d.ts +2 -0
  233. package/dist/server/modules/tailscale/tailscale-service.js +21 -8
  234. package/dist/server/modules/tailscale/tailscale-service.js.map +1 -1
  235. package/dist/server/modules/tasks/task-helper-client.d.ts +5 -2
  236. package/dist/server/modules/tasks/task-helper-client.js +118 -38
  237. package/dist/server/modules/tasks/task-helper-client.js.map +1 -1
  238. package/dist/server/modules/tasks/task-helper-process.js +94 -3
  239. package/dist/server/modules/tasks/task-helper-process.js.map +1 -1
  240. package/dist/server/modules/tasks/task-types.d.ts +6 -0
  241. package/dist/server/modules/tasks/task-types.js +7 -1
  242. package/dist/server/modules/tasks/task-types.js.map +1 -1
  243. package/dist/server/modules/terminal/command-template-service.d.ts +9 -0
  244. package/dist/server/modules/terminal/command-template-service.js +87 -5
  245. package/dist/server/modules/terminal/command-template-service.js.map +1 -1
  246. package/dist/server/modules/terminal/template-reverse-proxy-service.js +71 -3
  247. package/dist/server/modules/terminal/template-reverse-proxy-service.js.map +1 -1
  248. package/dist/server/modules/terminal/terminal-controller.d.ts +3 -0
  249. package/dist/server/modules/terminal/terminal-controller.js +41 -0
  250. package/dist/server/modules/terminal/terminal-controller.js.map +1 -1
  251. package/dist/server/modules/workbench/workbench-service.d.ts +3 -0
  252. package/dist/server/modules/workbench/workbench-service.js +4 -3
  253. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  254. package/dist/server/modules/workbench/workspace-file-watcher.d.ts +14 -6
  255. package/dist/server/modules/workbench/workspace-file-watcher.js +267 -57
  256. package/dist/server/modules/workbench/workspace-file-watcher.js.map +1 -1
  257. package/dist/server/modules/workbench/workspace-panel-snapshot-service.d.ts +2 -0
  258. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +32 -3
  259. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  260. package/dist/server/modules/worktree/worktree-manager.d.ts +9 -1
  261. package/dist/server/modules/worktree/worktree-manager.js +9 -1
  262. package/dist/server/modules/worktree/worktree-manager.js.map +1 -1
  263. package/dist/server/routes/assistant.js +49 -0
  264. package/dist/server/routes/assistant.js.map +1 -1
  265. package/dist/server/routes/auth.js +4 -0
  266. package/dist/server/routes/auth.js.map +1 -1
  267. package/dist/server/routes/butler.js +5 -0
  268. package/dist/server/routes/butler.js.map +1 -1
  269. package/dist/server/routes/sessions.js +1 -0
  270. package/dist/server/routes/sessions.js.map +1 -1
  271. package/dist/server/routes/system.d.ts +2 -1
  272. package/dist/server/routes/system.js +13 -1
  273. package/dist/server/routes/system.js.map +1 -1
  274. package/dist/server/server/create-server.d.ts +18 -0
  275. package/dist/server/server/create-server.js +113 -20
  276. package/dist/server/server/create-server.js.map +1 -1
  277. package/dist/server/shared/utils/tokens.d.ts +3 -1
  278. package/dist/server/shared/utils/tokens.js +9 -2
  279. package/dist/server/shared/utils/tokens.js.map +1 -1
  280. package/dist/server/storage/repositories/assistant-automation-run-repository.d.ts +12 -0
  281. package/dist/server/storage/repositories/assistant-automation-run-repository.js +139 -0
  282. package/dist/server/storage/repositories/assistant-automation-run-repository.js.map +1 -0
  283. package/dist/server/storage/repositories/assistant-automation-task-repository.d.ts +17 -0
  284. package/dist/server/storage/repositories/assistant-automation-task-repository.js +179 -0
  285. package/dist/server/storage/repositories/assistant-automation-task-repository.js.map +1 -0
  286. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.d.ts +18 -0
  287. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js +191 -0
  288. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js.map +1 -0
  289. package/dist/server/storage/repositories/auth-device-repository.d.ts +22 -0
  290. package/dist/server/storage/repositories/auth-device-repository.js +97 -0
  291. package/dist/server/storage/repositories/auth-device-repository.js.map +1 -0
  292. package/dist/server/storage/repositories/auth-device-session-repository.d.ts +17 -0
  293. package/dist/server/storage/repositories/auth-device-session-repository.js +82 -0
  294. package/dist/server/storage/repositories/auth-device-session-repository.js.map +1 -0
  295. package/dist/server/storage/repositories/auth-login-event-repository.d.ts +9 -0
  296. package/dist/server/storage/repositories/auth-login-event-repository.js +53 -0
  297. package/dist/server/storage/repositories/auth-login-event-repository.js.map +1 -0
  298. package/dist/server/storage/repositories/auth-token-repository.d.ts +4 -0
  299. package/dist/server/storage/repositories/auth-token-repository.js +58 -5
  300. package/dist/server/storage/repositories/auth-token-repository.js.map +1 -1
  301. package/dist/server/storage/repositories/butler-control-session-repository.js +27 -3
  302. package/dist/server/storage/repositories/butler-control-session-repository.js.map +1 -1
  303. package/dist/server/storage/repositories/butler-control-timer-repository.d.ts +15 -0
  304. package/dist/server/storage/repositories/butler-control-timer-repository.js +157 -0
  305. package/dist/server/storage/repositories/butler-control-timer-repository.js.map +1 -0
  306. package/dist/server/storage/repositories/butler-follow-up-task-repository.js +21 -3
  307. package/dist/server/storage/repositories/butler-follow-up-task-repository.js.map +1 -1
  308. package/dist/server/storage/repositories/instance-relay-tunnel-identity-repository.d.ts +8 -0
  309. package/dist/server/storage/repositories/instance-relay-tunnel-identity-repository.js +52 -0
  310. package/dist/server/storage/repositories/instance-relay-tunnel-identity-repository.js.map +1 -0
  311. package/dist/server/storage/repositories/instance-relay-tunnel-repository.d.ts +10 -0
  312. package/dist/server/storage/repositories/instance-relay-tunnel-repository.js +153 -0
  313. package/dist/server/storage/repositories/instance-relay-tunnel-repository.js.map +1 -0
  314. package/dist/server/storage/repositories/instance-tailscale-repository.js +6 -3
  315. package/dist/server/storage/repositories/instance-tailscale-repository.js.map +1 -1
  316. package/dist/server/storage/repositories/managed-skill-repository.d.ts +2 -1
  317. package/dist/server/storage/repositories/managed-skill-repository.js +14 -4
  318. package/dist/server/storage/repositories/managed-skill-repository.js.map +1 -1
  319. package/dist/server/storage/repositories/session-message-attachment-repository.d.ts +2 -0
  320. package/dist/server/storage/repositories/session-message-attachment-repository.js +24 -0
  321. package/dist/server/storage/repositories/session-message-attachment-repository.js.map +1 -1
  322. package/dist/server/storage/repositories/user-preference-profile-repository.js +6 -3
  323. package/dist/server/storage/repositories/user-preference-profile-repository.js.map +1 -1
  324. package/dist/server/storage/sqlite/client.js +534 -2
  325. package/dist/server/storage/sqlite/client.js.map +1 -1
  326. package/dist/server/storage/sqlite/schema.sql +228 -4
  327. package/dist/server/types/domain.d.ts +170 -2
  328. package/dist/server/ws/workbench-ws-hub.d.ts +14 -8
  329. package/dist/server/ws/workbench-ws-hub.js +369 -209
  330. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  331. package/dist/server/ws/ws-auth-guard.js +1 -4
  332. package/dist/server/ws/ws-auth-guard.js.map +1 -1
  333. package/dist/server/ws/ws-server.d.ts +1 -1
  334. package/dist/server/ws/ws-server.js.map +1 -1
  335. package/node_modules/@codingns/session-sync-core/dist/codex-resume-history.d.ts +1 -0
  336. package/node_modules/@codingns/session-sync-core/dist/codex-resume-history.js +80 -0
  337. package/node_modules/@codingns/session-sync-core/dist/codex-resume-history.js.map +1 -0
  338. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +5 -1
  339. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +122 -4
  340. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  341. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +17 -1
  342. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +437 -51
  343. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  344. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.d.ts +7 -1
  345. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js +240 -27
  346. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js.map +1 -1
  347. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.d.ts +5 -1
  348. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js +108 -2
  349. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js.map +1 -1
  350. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +3 -0
  351. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +101 -8
  352. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  353. package/node_modules/@codingns/session-sync-core/dist/providers/utils.d.ts +1 -0
  354. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js +4 -1
  355. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js.map +1 -1
  356. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +44 -0
  357. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  358. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +5 -1
  359. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +153 -60
  360. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  361. package/node_modules/@codingns/session-sync-core/dist/runtime/types.d.ts +1 -0
  362. package/node_modules/@codingns/session-sync-core/dist/services.d.ts +1 -0
  363. package/node_modules/@codingns/session-sync-core/dist/services.js +24 -8
  364. package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
  365. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +6 -0
  366. package/package.json +1 -1
  367. package/scripts/postinstall.mjs +0 -33
  368. package/dist/public/assets/index-BlOinYqR.js +0 -122
  369. package/dist/public/assets/index-Dg_7g6lA.css +0 -1
@@ -1,11 +1,13 @@
1
1
  import { basename, dirname, join } from "node:path";
2
- import { existsSync, readFileSync, readdirSync, renameSync, statSync } from "node:fs";
2
+ import { existsSync, readFileSync, readdirSync, renameSync, rmSync, statSync } from "node:fs";
3
3
  import crypto from "node:crypto";
4
- import { appendJsonLine, createRawRef, encodeCursor, ensureDirectory, extractTextBlocks, ensureText, messageIdFromRawRef, nextTimestamp, normalizeWorkspacePath, readFirstNonEmptyLine, readJsonLines, readTrailingJsonLines, safeDate, sliceHistory, stringifyStructuredValue, walkJsonlFiles } from "./utils.js";
4
+ import { appendJsonLine, createRawRef, encodeCursor, ensureDirectory, extractTextBlocks, ensureText, messageIdFromRawRef, messageIdFromStableKey, nextTimestamp, normalizeWorkspacePath, readFirstNonEmptyLine, readJsonLines, readTrailingJsonLines, safeDate, sliceHistory, stringifyStructuredValue, walkJsonlFiles } from "./utils.js";
5
+ import { buildCodexResumeHistoryFromRawStore } from "../codex-resume-history.js";
5
6
  import { loadDatabaseSync } from "../sqlite/node-sqlite.js";
6
7
  const CODEX_SESSION_TITLE_MAX_LENGTH = 48;
7
8
  const HISTORY_CACHE_LIMIT = 6;
8
9
  const SESSION_SUMMARY_CACHE_LIMIT = 512;
10
+ const SPAWN_RELATION_SCAN_CACHE_LIMIT = 512;
9
11
  const RECENT_HISTORY_INITIAL_BYTES = 256 * 1024;
10
12
  const RECENT_HISTORY_MAX_BYTES = 4 * 1024 * 1024;
11
13
  const RECENT_HISTORY_BUFFER_MESSAGES = 24;
@@ -19,20 +21,32 @@ export class CodexAdapter {
19
21
  providerId = "codex";
20
22
  historyCache = new Map();
21
23
  sessionSummaryCache = new Map();
24
+ spawnRelationScanCache = new Map();
22
25
  threadMetadataIndexCache = null;
23
26
  constructor(options) {
24
27
  this.options = options;
25
28
  }
26
29
  async detectSessions(workspacePath, options) {
30
+ const discovery = await this.detectSessionsDetailed(workspacePath, options);
31
+ return discovery.sessions;
32
+ }
33
+ async detectSessionsDetailed(workspacePath, options) {
34
+ const startedAt = Date.now();
27
35
  const targetPath = normalizeWorkspacePath(workspacePath);
28
- const files = this.listSessionFiles();
29
36
  const knownSessions = (options?.knownSessions ?? []).filter((session) => session.provider === this.providerId);
37
+ const threadMetadataIndex = this.readThreadMetadataIndex();
38
+ const files = this.listSessionFiles(targetPath, threadMetadataIndex, knownSessions);
30
39
  const knownByRawStoreRef = new Map(knownSessions.map((session) => [session.rawStoreRef, session]));
31
40
  const knownByProviderSessionId = new Map(knownSessions.map((session) => [session.providerSessionId, session]));
32
41
  const sessionsByProviderSessionId = new Map();
33
42
  const retainedSummaries = [];
34
43
  const pendingFiles = [];
44
+ let scannedFiles = 0;
45
+ let skippedByMtimeSize = 0;
46
+ let parsedFiles = 0;
47
+ let bytesRead = 0;
35
48
  for (const filePath of files) {
49
+ scannedFiles += 1;
36
50
  const stats = statSync(filePath);
37
51
  const cachedSummary = this.sessionSummaryCache.get(filePath);
38
52
  const fileSessionId = basename(filePath, ".jsonl");
@@ -47,6 +61,7 @@ export class CodexAdapter {
47
61
  if (cachedSummary.summary
48
62
  && hasUsableCodexTitle(cachedSummary.summary.title)
49
63
  && normalizeWorkspacePath(cachedSummary.summary.workspacePath) === targetPath) {
64
+ skippedByMtimeSize += 1;
50
65
  retainedSummaries.push({
51
66
  filePath,
52
67
  stats,
@@ -67,6 +82,7 @@ export class CodexAdapter {
67
82
  && hasUsableCodexTitle(knownByPath.title)
68
83
  && (!sessionIdentity
69
84
  || knownByPath.providerSessionId === sessionIdentity.threadId)) {
85
+ skippedByMtimeSize += 1;
70
86
  if (normalizeWorkspacePath(knownByPath.workspacePath) === targetPath) {
71
87
  retainedSummaries.push({
72
88
  filePath,
@@ -81,6 +97,8 @@ export class CodexAdapter {
81
97
  mtimeMs: stats.mtimeMs,
82
98
  size: stats.size,
83
99
  workspacePath: knownByPath.workspacePath,
100
+ providerSessionId: knownByPath.providerSessionId,
101
+ title: null,
84
102
  summary: null
85
103
  });
86
104
  continue;
@@ -92,6 +110,8 @@ export class CodexAdapter {
92
110
  mtimeMs: stats.mtimeMs,
93
111
  size: stats.size,
94
112
  workspacePath: sessionIdentity.cwd,
113
+ providerSessionId: sessionIdentity.threadId,
114
+ title: null,
95
115
  summary: null
96
116
  });
97
117
  continue;
@@ -107,13 +127,33 @@ export class CodexAdapter {
107
127
  });
108
128
  }
109
129
  if (pendingFiles.length === 0 && retainedSummaries.length === 0) {
110
- return [...sessionsByProviderSessionId.values()].sort((left, right) => (left.lastMessageAt ?? "").localeCompare(right.lastMessageAt ?? ""));
130
+ const sessions = [...sessionsByProviderSessionId.values()].sort((left, right) => (left.lastMessageAt ?? "").localeCompare(right.lastMessageAt ?? ""));
131
+ const diagnostic = {
132
+ provider: this.providerId,
133
+ status: "success",
134
+ durationMs: Date.now() - startedAt,
135
+ sessionCount: sessions.length,
136
+ isComplete: true,
137
+ errorMessage: null,
138
+ scannedFiles,
139
+ skippedByMtimeSize,
140
+ parsedFiles,
141
+ bytesRead
142
+ };
143
+ return {
144
+ sessions,
145
+ isComplete: true,
146
+ providerDiagnostics: [diagnostic]
147
+ };
111
148
  }
112
- const threadMetadataIndex = this.readThreadMetadataIndex();
113
149
  const pendingThreadIds = new Set([...pendingFiles, ...retainedSummaries]
114
150
  .map((entry) => entry.sessionIdentity?.threadId ?? null)
115
151
  .filter((value) => value !== null));
116
- const spawnedAgentRelationIndex = this.readSpawnedAgentRelationIndex([...pendingFiles, ...retainedSummaries].map((entry) => entry.filePath), targetPath, threadMetadataIndex, pendingThreadIds);
152
+ const spawnedAgentRelationIndex = this.readSpawnedAgentRelationIndex([...pendingFiles, ...retainedSummaries].map((entry) => ({
153
+ filePath: entry.filePath,
154
+ stats: entry.stats,
155
+ sessionIdentity: entry.sessionIdentity
156
+ })), targetPath, threadMetadataIndex, pendingThreadIds);
117
157
  for (const entry of retainedSummaries) {
118
158
  const currentThreadId = entry.sessionIdentity?.threadId ?? entry.summary.providerSessionId;
119
159
  const currentThreadMetadata = threadMetadataIndex.get(currentThreadId) ?? null;
@@ -127,21 +167,28 @@ export class CodexAdapter {
127
167
  mtimeMs: entry.stats.mtimeMs,
128
168
  size: entry.stats.size,
129
169
  workspacePath: summary.workspacePath,
170
+ providerSessionId: summary.providerSessionId,
171
+ title: summary.title,
130
172
  summary
131
173
  });
132
174
  sessionsByProviderSessionId.set(summary.providerSessionId, summary);
133
175
  }
134
176
  for (const entry of pendingFiles) {
135
177
  const { filePath, fileSessionId, stats, sessionIdentity } = entry;
178
+ parsedFiles += 1;
179
+ bytesRead += stats.size;
136
180
  const records = readJsonLines(filePath);
137
181
  const meta = records.find((record) => record.data.type === "session_meta")?.data;
138
182
  const metaPayload = (meta?.payload ?? {});
183
+ const codexSessionId = this.resolveCodexSessionId(metaPayload, fileSessionId);
139
184
  if (shouldIgnoreCodingNsDraftSession(metaPayload)) {
140
185
  this.touchSessionSummaryCache(filePath, {
141
186
  filePath,
142
187
  mtimeMs: stats.mtimeMs,
143
188
  size: stats.size,
144
189
  workspacePath: null,
190
+ providerSessionId: codexSessionId,
191
+ title: null,
145
192
  summary: null
146
193
  });
147
194
  continue;
@@ -155,11 +202,12 @@ export class CodexAdapter {
155
202
  mtimeMs: stats.mtimeMs,
156
203
  size: stats.size,
157
204
  workspacePath: cachedWorkspacePath,
205
+ providerSessionId: codexSessionId,
206
+ title: null,
158
207
  summary: null
159
208
  });
160
209
  continue;
161
210
  }
162
- const codexSessionId = this.resolveCodexSessionId(metaPayload, fileSessionId);
163
211
  const currentThreadMetadata = threadMetadataIndex.get(codexSessionId) ??
164
212
  (sessionIdentity ? threadMetadataIndex.get(sessionIdentity.threadId) : null);
165
213
  const currentSpawnRelation = spawnedAgentRelationIndex.get(codexSessionId) ??
@@ -178,6 +226,8 @@ export class CodexAdapter {
178
226
  mtimeMs: stats.mtimeMs,
179
227
  size: stats.size,
180
228
  workspacePath: sessionWorkspacePath,
229
+ providerSessionId: summary.providerSessionId,
230
+ title: summary.title,
181
231
  summary
182
232
  });
183
233
  sessionsByProviderSessionId.set(codexSessionId, summary);
@@ -204,10 +254,29 @@ export class CodexAdapter {
204
254
  mtimeMs: stats.mtimeMs,
205
255
  size: stats.size,
206
256
  workspacePath: sessionWorkspacePath,
257
+ providerSessionId: summary.providerSessionId,
258
+ title: summary.title,
207
259
  summary
208
260
  });
209
261
  }
210
- return [...sessionsByProviderSessionId.values()].sort((left, right) => (left.lastMessageAt ?? "").localeCompare(right.lastMessageAt ?? ""));
262
+ const sessions = [...sessionsByProviderSessionId.values()].sort((left, right) => (left.lastMessageAt ?? "").localeCompare(right.lastMessageAt ?? ""));
263
+ const diagnostic = {
264
+ provider: this.providerId,
265
+ status: "success",
266
+ durationMs: Date.now() - startedAt,
267
+ sessionCount: sessions.length,
268
+ isComplete: true,
269
+ errorMessage: null,
270
+ scannedFiles,
271
+ skippedByMtimeSize,
272
+ parsedFiles,
273
+ bytesRead
274
+ };
275
+ return {
276
+ sessions,
277
+ isComplete: true,
278
+ providerDiagnostics: [diagnostic]
279
+ };
211
280
  }
212
281
  async readSessionHistory(providerSessionId, rawStoreRef, cursor, limit, direction = "forward") {
213
282
  const resolvedStoreRef = this.resolveSessionFilePath(rawStoreRef, providerSessionId);
@@ -345,7 +414,7 @@ export class CodexAdapter {
345
414
  try {
346
415
  await transport.initialize();
347
416
  if (options.sourceType === "session") {
348
- const forked = await transport.forkThread(providerSessionId);
417
+ const forked = await this.forkThreadWithHistoryFallback(transport, providerSessionId, workspacePath, options.rawStoreRef);
349
418
  return await this.buildForkResultFromTransport({
350
419
  providerSessionId: forked.providerSessionId,
351
420
  rawStoreRef: forked.rawStoreRef,
@@ -439,20 +508,50 @@ export class CodexAdapter {
439
508
  }
440
509
  async readSessionTitle(providerSessionId, rawStoreRef) {
441
510
  const resolvedStoreRef = this.resolveSessionFilePath(rawStoreRef, providerSessionId);
442
- const records = readJsonLines(resolvedStoreRef);
443
511
  const fileSessionId = basename(resolvedStoreRef, ".jsonl");
444
- const meta = records.find((record) => record.data.type === "session_meta")?.data;
445
- const metaPayload = (meta?.payload ?? {});
446
512
  const sessionIdentity = this.readSessionIdentity(resolvedStoreRef, fileSessionId);
447
- const codexSessionId = this.resolveCodexSessionId(metaPayload, providerSessionId || fileSessionId);
448
513
  const threadMetadataIndex = this.readThreadMetadataIndex();
449
- const messages = this.parseMessagesFromEntries(resolvedStoreRef, records, codexSessionId);
450
- return (this.resolveIndexedTitle(threadMetadataIndex, codexSessionId) ??
514
+ const indexedTitle = this.resolveIndexedTitle(threadMetadataIndex, providerSessionId) ??
451
515
  (sessionIdentity
452
516
  ? this.resolveIndexedTitle(threadMetadataIndex, sessionIdentity.threadId)
453
- : null) ??
517
+ : null);
518
+ if (indexedTitle) {
519
+ return indexedTitle;
520
+ }
521
+ const stats = statSync(resolvedStoreRef);
522
+ const cachedSummary = this.sessionSummaryCache.get(resolvedStoreRef);
523
+ if (cachedSummary
524
+ && cachedSummary.mtimeMs === stats.mtimeMs
525
+ && cachedSummary.size === stats.size
526
+ && (cachedSummary.providerSessionId === providerSessionId
527
+ || (sessionIdentity
528
+ && cachedSummary.providerSessionId === sessionIdentity.threadId))) {
529
+ this.touchSessionSummaryCache(resolvedStoreRef, cachedSummary);
530
+ if (cachedSummary.title) {
531
+ return cachedSummary.title;
532
+ }
533
+ if (cachedSummary.summary) {
534
+ return cachedSummary.summary.title;
535
+ }
536
+ }
537
+ const records = readJsonLines(resolvedStoreRef);
538
+ const meta = records.find((record) => record.data.type === "session_meta")?.data;
539
+ const metaPayload = (meta?.payload ?? {});
540
+ const codexSessionId = this.resolveCodexSessionId(metaPayload, providerSessionId || fileSessionId);
541
+ const messages = this.parseMessagesFromEntries(resolvedStoreRef, records, codexSessionId);
542
+ const resolvedTitle = (this.resolveIndexedTitle(threadMetadataIndex, codexSessionId) ??
454
543
  resolveCodexFallbackTitle(messages) ??
455
544
  fileSessionId);
545
+ this.touchSessionSummaryCache(resolvedStoreRef, {
546
+ filePath: resolvedStoreRef,
547
+ mtimeMs: stats.mtimeMs,
548
+ size: stats.size,
549
+ workspacePath: (sessionIdentity?.cwd ?? ensureText(metaPayload.cwd)) || null,
550
+ providerSessionId: codexSessionId,
551
+ title: resolvedTitle,
552
+ summary: null
553
+ });
554
+ return resolvedTitle;
456
555
  }
457
556
  async renameSessionTitle(providerSessionId, rawStoreRef, title) {
458
557
  const nextTitle = title.trim();
@@ -485,33 +584,112 @@ export class CodexAdapter {
485
584
  const nextStoreRef = isArchived
486
585
  ? join(this.options.homeDir, "archived_sessions", currentFileName)
487
586
  : buildCodexActiveSessionPath(this.options.homeDir, currentFileName);
587
+ const controlResult = await this.updateArchiveStateViaThreadControlTransport(providerSessionId, resolvedStoreRef, nextStoreRef, isArchived);
588
+ let finalStoreRef = nextStoreRef;
589
+ if (controlResult) {
590
+ finalStoreRef = controlResult.rawStoreRef;
591
+ }
592
+ else {
593
+ const stateDbPath = findLatestCodexStateDatabase(this.options.homeDir);
594
+ statSync(resolvedStoreRef);
595
+ if (resolvedStoreRef !== nextStoreRef) {
596
+ ensureDirectory(dirname(nextStoreRef));
597
+ renameSync(resolvedStoreRef, nextStoreRef);
598
+ }
599
+ if (stateDbPath) {
600
+ const DatabaseSync = loadDatabaseSync();
601
+ let db = null;
602
+ try {
603
+ db = new DatabaseSync(stateDbPath, { open: true });
604
+ db.prepare(`UPDATE threads
605
+ SET archived = ?,
606
+ archived_at = ?,
607
+ rollout_path = ?
608
+ WHERE id = ?`).run(isArchived ? 1 : 0, isArchived ? Math.floor(Date.now() / 1000) : null, nextStoreRef, providerSessionId);
609
+ }
610
+ finally {
611
+ db?.close();
612
+ }
613
+ }
614
+ }
615
+ this.sessionSummaryCache.delete(resolvedStoreRef);
616
+ this.sessionSummaryCache.delete(finalStoreRef);
617
+ // 归档切换后线程索引的 archived / rollout_path 也变了,不能继续赌文件系统 mtime 一定会跳。
618
+ this.invalidateThreadMetadataIndexCache();
619
+ return {
620
+ rawStoreRef: finalStoreRef,
621
+ isArchived
622
+ };
623
+ }
624
+ async deleteSession(providerSessionId, rawStoreRef) {
625
+ const resolvedStoreRef = this.resolveSessionFilePath(rawStoreRef, providerSessionId);
626
+ const threadMetadata = this.readThreadMetadataIndex().get(providerSessionId) ?? null;
627
+ const resolvedMetadataStoreRef = threadMetadata?.rolloutPath && threadMetadata.rolloutPath.trim()
628
+ ? this.resolveSessionFilePath(threadMetadata.rolloutPath, providerSessionId)
629
+ : null;
630
+ const candidateFilePaths = new Set([resolvedStoreRef, resolvedMetadataStoreRef].filter((value) => typeof value === "string" && value.trim().length > 0));
488
631
  const stateDbPath = findLatestCodexStateDatabase(this.options.homeDir);
489
- statSync(resolvedStoreRef);
490
- if (resolvedStoreRef !== nextStoreRef) {
491
- ensureDirectory(dirname(nextStoreRef));
492
- renameSync(resolvedStoreRef, nextStoreRef);
632
+ let deletedAny = false;
633
+ for (const filePath of candidateFilePaths) {
634
+ if (!existsSync(filePath)) {
635
+ continue;
636
+ }
637
+ rmSync(filePath, { force: true });
638
+ this.historyCache.delete(filePath);
639
+ this.sessionSummaryCache.delete(filePath);
640
+ deletedAny = true;
493
641
  }
494
642
  if (stateDbPath) {
495
643
  const DatabaseSync = loadDatabaseSync();
496
644
  let db = null;
497
645
  try {
498
646
  db = new DatabaseSync(stateDbPath, { open: true });
499
- db.prepare(`UPDATE threads
500
- SET archived = ?,
501
- archived_at = ?,
502
- rollout_path = ?
503
- WHERE id = ?`).run(isArchived ? 1 : 0, isArchived ? Math.floor(Date.now() / 1000) : null, nextStoreRef, providerSessionId);
647
+ const result = db.prepare("DELETE FROM threads WHERE id = ?").run(providerSessionId);
648
+ deletedAny = deletedAny || result.changes > 0;
504
649
  }
505
650
  finally {
506
651
  db?.close();
507
652
  }
508
653
  }
509
- this.sessionSummaryCache.delete(resolvedStoreRef);
510
- this.sessionSummaryCache.delete(nextStoreRef);
511
- return {
512
- rawStoreRef: nextStoreRef,
513
- isArchived
514
- };
654
+ this.invalidateThreadMetadataIndexCache();
655
+ if (!deletedAny) {
656
+ throw new Error("PROVIDER_SESSION_NOT_FOUND");
657
+ }
658
+ }
659
+ async updateArchiveStateViaThreadControlTransport(providerSessionId, resolvedStoreRef, nextStoreRef, isArchived) {
660
+ const createTransport = this.options.threadControlTransportFactory;
661
+ if (!createTransport) {
662
+ return null;
663
+ }
664
+ const transport = createTransport();
665
+ try {
666
+ await transport.initialize();
667
+ if (isArchived) {
668
+ await transport.archiveThread(providerSessionId);
669
+ }
670
+ else {
671
+ await transport.unarchiveThread(providerSessionId);
672
+ }
673
+ const result = await transport.readThread(providerSessionId).catch(() => null);
674
+ const thread = result && typeof result === "object"
675
+ ? (result.thread ?? null)
676
+ : null;
677
+ const appServerRawStoreRef = ensureText(thread?.path).trim();
678
+ const resolvedNextStoreRef = appServerRawStoreRef.length > 0
679
+ ? this.resolveSessionFilePath(appServerRawStoreRef, providerSessionId)
680
+ : this.resolveSessionFilePath(nextStoreRef, providerSessionId);
681
+ this.sessionSummaryCache.delete(resolvedStoreRef);
682
+ this.sessionSummaryCache.delete(resolvedNextStoreRef);
683
+ return {
684
+ rawStoreRef: resolvedNextStoreRef
685
+ };
686
+ }
687
+ catch {
688
+ return null;
689
+ }
690
+ finally {
691
+ transport.close();
692
+ }
515
693
  }
516
694
  getProviderCapabilities() {
517
695
  return {
@@ -519,7 +697,7 @@ export class CodexAdapter {
519
697
  canStartSession: true,
520
698
  canResumeSession: true,
521
699
  canSendMessage: true,
522
- inRunInputMode: "none",
700
+ inRunInputMode: "streaming_guidance",
523
701
  supportsSubagents: true,
524
702
  supportsInterrupt: true,
525
703
  supportsStructuredToolCalls: true,
@@ -528,9 +706,10 @@ export class CodexAdapter {
528
706
  supportsPermissionPrompt: true,
529
707
  supportsCheckpoint: false,
530
708
  supportsSessionFork: true,
709
+ supportsSessionDelete: true,
531
710
  limitations: [
532
- "Codex 产品原生支持将指导加入队列,但当前 SDK 0.116.0 仍未向宿主暴露运行中 queue/steer 提交入口。",
533
- "当前实现只维护原生会话文件,不负责直接驱动 Codex CLI 进程执行。"
711
+ "运行中追加消息依赖 Codex CLI app-server 暴露 turn/steer;当前项目实测 codex-cli 0.118.0 可用。",
712
+ "当前 npm SDK 仍只有 run/runStreamed 轮询式接口,宿主运行时需经由 Codex CLI app-server 才能直发 steer。"
534
713
  ]
535
714
  };
536
715
  }
@@ -617,7 +796,8 @@ export class CodexAdapter {
617
796
  firstUserMessage: null,
618
797
  agentNickname: null,
619
798
  agentRole: null,
620
- isArchived: null
799
+ isArchived: null,
800
+ rolloutPath: null
621
801
  });
622
802
  }
623
803
  catch {
@@ -666,6 +846,7 @@ export class CodexAdapter {
666
846
  firstUserMessage: ensureText(row.first_user_message).trim() || (current?.firstUserMessage ?? null),
667
847
  agentNickname: ensureText(row.agent_nickname).trim() || (current?.agentNickname ?? null),
668
848
  agentRole: ensureText(row.agent_role).trim() || (current?.agentRole ?? null),
849
+ rolloutPath: ensureText(row.rollout_path).trim() || (current?.rolloutPath ?? null),
669
850
  isArchived: typeof row.archived === "number"
670
851
  ? row.archived === 1
671
852
  : ensureText(row.rollout_path).includes("archived_sessions")
@@ -694,11 +875,40 @@ export class CodexAdapter {
694
875
  };
695
876
  return index;
696
877
  }
697
- listSessionFiles() {
878
+ listSessionFiles(targetPath, threadMetadataIndex, knownSessions) {
698
879
  const activeFiles = walkJsonlFiles(join(this.options.homeDir, "sessions"));
699
- const archivedFiles = walkJsonlFiles(join(this.options.homeDir, "archived_sessions"));
880
+ const archivedFiles = this.listArchivedSessionFiles(targetPath, threadMetadataIndex, knownSessions);
700
881
  return [...activeFiles, ...archivedFiles];
701
882
  }
883
+ listArchivedSessionFiles(targetPath, threadMetadataIndex, knownSessions) {
884
+ const archivedFiles = new Set();
885
+ for (const metadata of threadMetadataIndex.values()) {
886
+ if (metadata.isArchived !== true
887
+ || !metadata.rolloutPath) {
888
+ continue;
889
+ }
890
+ if (targetPath.length > 0
891
+ && normalizeWorkspacePath(metadata.cwd ?? "") !== targetPath) {
892
+ continue;
893
+ }
894
+ archivedFiles.add(metadata.rolloutPath);
895
+ }
896
+ for (const session of knownSessions) {
897
+ if (session.isArchived !== true
898
+ || normalizeWorkspacePath(session.workspacePath) !== targetPath
899
+ || !isCodexArchivedFilePath(session.rawStoreRef)) {
900
+ continue;
901
+ }
902
+ archivedFiles.add(session.rawStoreRef);
903
+ }
904
+ if (archivedFiles.size > 0) {
905
+ return [...archivedFiles].filter((filePath) => existsSync(filePath));
906
+ }
907
+ if (threadMetadataIndex.size === 0) {
908
+ return walkJsonlFiles(join(this.options.homeDir, "archived_sessions"));
909
+ }
910
+ return [];
911
+ }
702
912
  resolveSessionFilePath(rawStoreRef, providerSessionId) {
703
913
  const matchedByThreadId = this.findSessionFileByThreadId(providerSessionId);
704
914
  if (existsSync(rawStoreRef)) {
@@ -732,7 +942,10 @@ export class CodexAdapter {
732
942
  return buildSyntheticCodexHistoryPath(this.options.homeDir, providerSessionId);
733
943
  }
734
944
  findSessionFileByThreadId(providerSessionId) {
735
- for (const filePath of this.listSessionFiles()) {
945
+ const threadMetadataIndex = this.readThreadMetadataIndex();
946
+ const activeFiles = walkJsonlFiles(join(this.options.homeDir, "sessions"));
947
+ const archivedFiles = this.listArchivedSessionFiles("", threadMetadataIndex, []);
948
+ for (const filePath of [...activeFiles, ...archivedFiles]) {
736
949
  const threadId = this.readThreadIdFromRawStore(filePath);
737
950
  if (threadId === providerSessionId) {
738
951
  return filePath;
@@ -823,6 +1036,26 @@ export class CodexAdapter {
823
1036
  providerSourceMessageId: input.providerSourceMessageId
824
1037
  };
825
1038
  }
1039
+ async forkThreadWithHistoryFallback(transport, providerSessionId, workspacePath, rawStoreRef) {
1040
+ try {
1041
+ return await transport.forkThread(providerSessionId);
1042
+ }
1043
+ catch (error) {
1044
+ const history = buildCodexResumeHistoryFromRawStore(rawStoreRef);
1045
+ if (!shouldFallbackCodexForkFromHistory(error, history)) {
1046
+ throw error;
1047
+ }
1048
+ // app-server 的 thread/fork 依赖源 thread 已经挂在当前连接上。
1049
+ // 这个前提跨请求就会失效,所以这里退回到本地 transcript 冷恢复一次。
1050
+ const rebuilt = await transport.resumeThreadFromHistory({
1051
+ providerSessionId: null,
1052
+ workspacePath,
1053
+ history,
1054
+ model: null
1055
+ });
1056
+ return await transport.forkThread(rebuilt.providerSessionId);
1057
+ }
1058
+ }
826
1059
  touchSessionSummaryCache(filePath, entry) {
827
1060
  this.sessionSummaryCache.delete(filePath);
828
1061
  this.sessionSummaryCache.set(filePath, entry);
@@ -834,6 +1067,20 @@ export class CodexAdapter {
834
1067
  this.sessionSummaryCache.delete(oldestKey);
835
1068
  }
836
1069
  }
1070
+ invalidateThreadMetadataIndexCache() {
1071
+ this.threadMetadataIndexCache = null;
1072
+ }
1073
+ touchSpawnRelationScanCache(filePath, entry) {
1074
+ this.spawnRelationScanCache.delete(filePath);
1075
+ this.spawnRelationScanCache.set(filePath, entry);
1076
+ while (this.spawnRelationScanCache.size > SPAWN_RELATION_SCAN_CACHE_LIMIT) {
1077
+ const oldestKey = this.spawnRelationScanCache.keys().next().value;
1078
+ if (!oldestKey) {
1079
+ break;
1080
+ }
1081
+ this.spawnRelationScanCache.delete(oldestKey);
1082
+ }
1083
+ }
837
1084
  isForkedChildHistoryAligned(childThreadReadResult, expectedHistory) {
838
1085
  const expectedSignatures = collectCodexForkComparableSignatures(expectedHistory);
839
1086
  if (expectedSignatures.length === 0) {
@@ -880,22 +1127,65 @@ export class CodexAdapter {
880
1127
  readSpawnedAgentRelationIndex(files, targetPath, threadMetadataIndex, candidateThreadIds) {
881
1128
  const directRelations = new Map();
882
1129
  const spawnRecords = [];
883
- for (const filePath of files) {
884
- const sessionIdentity = this.readSessionIdentity(filePath, basename(filePath, ".jsonl"));
1130
+ for (const entry of files) {
1131
+ const { filePath, stats } = entry;
1132
+ const cached = this.spawnRelationScanCache.get(filePath);
1133
+ if (cached
1134
+ && cached.mtimeMs === stats.mtimeMs
1135
+ && cached.size === stats.size) {
1136
+ this.touchSpawnRelationScanCache(filePath, cached);
1137
+ if (cached.workspacePath !== targetPath) {
1138
+ continue;
1139
+ }
1140
+ for (const [threadId, relation] of cached.directRelations) {
1141
+ directRelations.set(threadId, relation);
1142
+ }
1143
+ spawnRecords.push(...cached.spawnRecords);
1144
+ continue;
1145
+ }
1146
+ const sessionIdentity = entry.sessionIdentity ?? this.readSessionIdentity(filePath, basename(filePath, ".jsonl"));
885
1147
  if (!sessionIdentity) {
1148
+ this.touchSpawnRelationScanCache(filePath, {
1149
+ filePath,
1150
+ mtimeMs: stats.mtimeMs,
1151
+ size: stats.size,
1152
+ workspacePath: null,
1153
+ directRelations: [],
1154
+ spawnRecords: []
1155
+ });
886
1156
  continue;
887
1157
  }
888
- if (normalizeWorkspacePath(sessionIdentity.cwd) !== targetPath) {
1158
+ const workspacePath = normalizeWorkspacePath(sessionIdentity.cwd);
1159
+ if (workspacePath !== targetPath) {
1160
+ this.touchSpawnRelationScanCache(filePath, {
1161
+ filePath,
1162
+ mtimeMs: stats.mtimeMs,
1163
+ size: stats.size,
1164
+ workspacePath,
1165
+ directRelations: [],
1166
+ spawnRecords: []
1167
+ });
889
1168
  continue;
890
1169
  }
891
1170
  if (sessionIdentity.parentThreadId) {
892
- directRelations.set(sessionIdentity.threadId, {
1171
+ const relation = {
893
1172
  parentProviderSessionId: sessionIdentity.parentThreadId
1173
+ };
1174
+ directRelations.set(sessionIdentity.threadId, relation);
1175
+ this.touchSpawnRelationScanCache(filePath, {
1176
+ filePath,
1177
+ mtimeMs: stats.mtimeMs,
1178
+ size: stats.size,
1179
+ workspacePath,
1180
+ directRelations: [[sessionIdentity.threadId, relation]],
1181
+ spawnRecords: []
894
1182
  });
895
1183
  continue;
896
1184
  }
897
1185
  const records = readJsonLines(filePath).map((record) => record.data);
898
1186
  const spawnCallById = new Map();
1187
+ const fileSpawnRecords = [];
1188
+ const fileDirectRelations = [];
899
1189
  for (const record of records) {
900
1190
  if (record.type !== "response_item") {
901
1191
  continue;
@@ -916,6 +1206,7 @@ export class CodexAdapter {
916
1206
  timestampMs: toTimestampMs(record.timestamp)
917
1207
  };
918
1208
  spawnCallById.set(callId, spawnRecord);
1209
+ fileSpawnRecords.push(spawnRecord);
919
1210
  spawnRecords.push(spawnRecord);
920
1211
  continue;
921
1212
  }
@@ -931,10 +1222,20 @@ export class CodexAdapter {
931
1222
  if (!agentId) {
932
1223
  continue;
933
1224
  }
934
- directRelations.set(agentId, {
1225
+ const relation = {
935
1226
  parentProviderSessionId: spawnRecord.parentProviderSessionId
936
- });
1227
+ };
1228
+ directRelations.set(agentId, relation);
1229
+ fileDirectRelations.push([agentId, relation]);
937
1230
  }
1231
+ this.touchSpawnRelationScanCache(filePath, {
1232
+ filePath,
1233
+ mtimeMs: stats.mtimeMs,
1234
+ size: stats.size,
1235
+ workspacePath,
1236
+ directRelations: fileDirectRelations,
1237
+ spawnRecords: fileSpawnRecords
1238
+ });
938
1239
  }
939
1240
  const relationCandidates = candidateThreadIds === undefined
940
1241
  ? [...threadMetadataIndex.entries()]
@@ -1058,7 +1359,13 @@ export class CodexAdapter {
1058
1359
  const content = ensureText(payload.message);
1059
1360
  if (content.length > 0) {
1060
1361
  pushMessage("event_msg", {
1061
- messageId: messageIdFromRawRef(rawRef),
1362
+ messageId: resolveCodexParsedMessageId({
1363
+ providerSessionId,
1364
+ rawRef,
1365
+ role: "user",
1366
+ kind: "text",
1367
+ payloadId: payload.id
1368
+ }),
1062
1369
  provider: this.providerId,
1063
1370
  providerSessionId,
1064
1371
  role: "user",
@@ -1074,7 +1381,13 @@ export class CodexAdapter {
1074
1381
  const content = ensureText(payload.message);
1075
1382
  if (content.length > 0) {
1076
1383
  pushMessage("event_msg", {
1077
- messageId: messageIdFromRawRef(rawRef),
1384
+ messageId: resolveCodexParsedMessageId({
1385
+ providerSessionId,
1386
+ rawRef,
1387
+ role: "assistant",
1388
+ kind: "text",
1389
+ payloadId: payload.id
1390
+ }),
1078
1391
  provider: this.providerId,
1079
1392
  providerSessionId,
1080
1393
  role: "assistant",
@@ -1090,7 +1403,13 @@ export class CodexAdapter {
1090
1403
  const content = extractTextBlocks(payload.text ?? payload.message).trim();
1091
1404
  if (content.length > 0) {
1092
1405
  pushMessage("event_msg", {
1093
- messageId: messageIdFromRawRef(rawRef),
1406
+ messageId: resolveCodexParsedMessageId({
1407
+ providerSessionId,
1408
+ rawRef,
1409
+ role: "assistant",
1410
+ kind: "thinking",
1411
+ payloadId: payload.id
1412
+ }),
1094
1413
  provider: this.providerId,
1095
1414
  providerSessionId,
1096
1415
  role: "assistant",
@@ -1112,7 +1431,13 @@ export class CodexAdapter {
1112
1431
  return;
1113
1432
  }
1114
1433
  pushMessage("response_item", {
1115
- messageId: messageIdFromRawRef(rawRef),
1434
+ messageId: resolveCodexParsedMessageId({
1435
+ providerSessionId,
1436
+ rawRef,
1437
+ role: "assistant",
1438
+ kind: "thinking",
1439
+ payloadId: payload.id
1440
+ }),
1116
1441
  provider: this.providerId,
1117
1442
  providerSessionId,
1118
1443
  role: "assistant",
@@ -1131,7 +1456,13 @@ export class CodexAdapter {
1131
1456
  const input = stringifyStructuredValue(inputSource);
1132
1457
  toolNameById.set(callId, name);
1133
1458
  pushMessage("response_item", {
1134
- messageId: messageIdFromRawRef(rawRef),
1459
+ messageId: resolveCodexParsedMessageId({
1460
+ providerSessionId,
1461
+ rawRef,
1462
+ role: "tool",
1463
+ kind: "tool_call",
1464
+ callId
1465
+ }),
1135
1466
  provider: this.providerId,
1136
1467
  providerSessionId,
1137
1468
  role: "tool",
@@ -1156,7 +1487,13 @@ export class CodexAdapter {
1156
1487
  const output = extractTextBlocks(payload.output).trim() || stringifyStructuredValue(payload.output);
1157
1488
  const resultState = resolveToolResultState(payload, output);
1158
1489
  pushMessage("response_item", {
1159
- messageId: messageIdFromRawRef(rawRef),
1490
+ messageId: resolveCodexParsedMessageId({
1491
+ providerSessionId,
1492
+ rawRef,
1493
+ role: "tool",
1494
+ kind: "tool_result",
1495
+ callId
1496
+ }),
1160
1497
  provider: this.providerId,
1161
1498
  providerSessionId,
1162
1499
  role: "tool",
@@ -1184,7 +1521,13 @@ export class CodexAdapter {
1184
1521
  return;
1185
1522
  }
1186
1523
  pushMessage("response_item", {
1187
- messageId: messageIdFromRawRef(rawRef),
1524
+ messageId: resolveCodexParsedMessageId({
1525
+ providerSessionId,
1526
+ rawRef,
1527
+ role,
1528
+ kind: "text",
1529
+ payloadId: payload.id
1530
+ }),
1188
1531
  provider: this.providerId,
1189
1532
  providerSessionId,
1190
1533
  role,
@@ -1380,6 +1723,37 @@ function areCodexTimestampsNear(left, right) {
1380
1723
  }
1381
1724
  return Math.abs(leftMs - rightMs) <= 1000;
1382
1725
  }
1726
+ function resolveCodexParsedMessageId(input) {
1727
+ const stableIdentity = resolveCodexStableIdentity(input);
1728
+ if (!stableIdentity) {
1729
+ return messageIdFromRawRef(input.rawRef);
1730
+ }
1731
+ return messageIdFromStableKey(buildCodexStableMessageKey(input.providerSessionId, stableIdentity));
1732
+ }
1733
+ function resolveCodexStableIdentity(input) {
1734
+ if (input.kind === "tool_call" || input.kind === "tool_result") {
1735
+ const normalizedCallId = ensureText(input.callId).trim();
1736
+ if (!normalizedCallId) {
1737
+ return null;
1738
+ }
1739
+ return input.kind === "tool_call"
1740
+ ? `tool:call:${normalizedCallId}`
1741
+ : `tool:result:${normalizedCallId}`;
1742
+ }
1743
+ if (input.role !== "assistant"
1744
+ && input.role !== "user") {
1745
+ return null;
1746
+ }
1747
+ const normalizedPayloadId = ensureText(input.payloadId).trim();
1748
+ if (!normalizedPayloadId) {
1749
+ return null;
1750
+ }
1751
+ const identityKind = input.kind === "thinking" ? "thinking" : "text";
1752
+ return `${input.role}:${identityKind}:${normalizedPayloadId}`;
1753
+ }
1754
+ function buildCodexStableMessageKey(providerSessionId, stableIdentity) {
1755
+ return `codex:${providerSessionId}:${stableIdentity}`;
1756
+ }
1383
1757
  function extractTextFromArray(value) {
1384
1758
  if (!Array.isArray(value)) {
1385
1759
  return "";
@@ -1926,4 +2300,16 @@ function stringifyCodexReasoningContent(content) {
1926
2300
  .join("\n")
1927
2301
  .trim();
1928
2302
  }
2303
+ function shouldFallbackCodexForkFromHistory(error, history) {
2304
+ if (history.length === 0) {
2305
+ return false;
2306
+ }
2307
+ return isCodexThreadLoadError(error);
2308
+ }
2309
+ function isCodexThreadLoadError(error) {
2310
+ const message = error instanceof Error ? error.message : String(error);
2311
+ const normalized = message.trim().toLowerCase();
2312
+ return (normalized.includes("thread not loaded") ||
2313
+ normalized.includes("no rollout found for thread id"));
2314
+ }
1929
2315
  //# sourceMappingURL=codex.js.map