@jingyi0605/codingns 0.7.4 → 0.8.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 (416) hide show
  1. package/README.md +6 -0
  2. package/bin/codingns.mjs +747 -28
  3. package/bin/office-mcp-server.mjs +620 -0
  4. package/dist/public/assets/{AdaptiveButlerPage-CgBX49t-.js → AdaptiveButlerPage-BsgVNRAa.js} +1 -1
  5. package/dist/public/assets/{App-tXOqoHNl.js → App-tPcbyRdS.js} +3 -3
  6. package/dist/public/assets/{BootstrapPage-DoRMz87R.js → BootstrapPage--MDOigQi.js} +1 -1
  7. package/dist/public/assets/{ConversationPage-DXR6Hp4O.js → ConversationPage-BBss5ED8.js} +6 -6
  8. package/dist/public/assets/{DesktopDetachPreviewPage-Cyk-ZYCk.js → DesktopDetachPreviewPage-CB8DoqwU.js} +1 -1
  9. package/dist/public/assets/{DesktopWindowPage-DNVNK3hs.js → DesktopWindowPage-GtIx5m8K.js} +1 -1
  10. package/dist/public/assets/FileContextPanel-BcM7AIT4.js +1 -0
  11. package/dist/public/assets/{GitSidebar-Cr3Z9OUI.js → GitSidebar-CMtkaxuI.js} +2 -2
  12. package/dist/public/assets/{MobileCreateSessionSheet-DMW0V6GJ.js → MobileCreateSessionSheet-CrFY41_8.js} +1 -1
  13. package/dist/public/assets/{MobileTopHeaderFrame-CkdnZ_MU.js → MobileTopHeaderFrame-DGVOzXyg.js} +1 -1
  14. package/dist/public/assets/{MobileWorkspaceSwitcherHeader-KIbqBYJN.js → MobileWorkspaceSwitcherHeader-DLkACTnQ.js} +1 -1
  15. package/dist/public/assets/{RelayConnectEntryPage-DIRBH3hw.js → RelayConnectEntryPage-0MPPjxtQ.js} +1 -1
  16. package/dist/public/assets/{ServerSettingsModal-C-9RxdWP.js → ServerSettingsModal-vgOhwus4.js} +1 -1
  17. package/dist/public/assets/{SessionIndexPage-bRlIydRA.js → SessionIndexPage-KK626Ra9.js} +1 -1
  18. package/dist/public/assets/{SettingsPage-CMEt4ua9.js → SettingsPage-B3edBJIo.js} +2 -2
  19. package/dist/public/assets/{TerminalManagerPanel-2bi9wVhT.js → TerminalManagerPanel-BxlhZp8c.js} +1 -1
  20. package/dist/public/assets/{TerminalPage-DayZz2Tf.js → TerminalPage-B6Rdhylx.js} +1 -1
  21. package/dist/public/assets/{TerminalRuntimeFallbackModal-DgwYcp-Y.js → TerminalRuntimeFallbackModal-BVLfrpSa.js} +1 -1
  22. package/dist/public/assets/{ToolFilesPage-YvnP_FXW.js → ToolFilesPage-N_gwwUjD.js} +1 -1
  23. package/dist/public/assets/{ToolGitPage-GMcQKtV9.js → ToolGitPage-DOcuuWM1.js} +1 -1
  24. package/dist/public/assets/{ToolProcessesPage-DFIQ7BCd.js → ToolProcessesPage-D-FfJ7Re.js} +1 -1
  25. package/dist/public/assets/{ToolsHomePage-CSilFzXR.js → ToolsHomePage-CHfPxd20.js} +1 -1
  26. package/dist/public/assets/{WorkbenchLandingPage-1VtToSz9.js → WorkbenchLandingPage-CTTnfovY.js} +1 -1
  27. package/dist/public/assets/WorkbenchLayout-CbpJg0g1.js +244 -0
  28. package/dist/public/assets/{WorkbenchModal-BWXYSXmC.js → WorkbenchModal-Bt_1fYmM.js} +1 -1
  29. package/dist/public/assets/WorkbenchShellRoute-B4XB8SwG.css +1 -0
  30. package/dist/public/assets/WorkbenchShellRoute-DyaMnPfS.js +1 -0
  31. package/dist/public/assets/{WorkspaceDebugDetailPage-Ux8_Q7la.js → WorkspaceDebugDetailPage-s7yuDIxR.js} +1 -1
  32. package/dist/public/assets/{WorkspaceDetailPage-B402p99m.js → WorkspaceDetailPage-Cf-gVpqK.js} +1 -1
  33. package/dist/public/assets/{WorkspaceHomePage-D2pob6HI.js → WorkspaceHomePage-COf6I8sT.js} +1 -1
  34. package/dist/public/assets/{client-runtime-manager-C5D76ewj.js → client-runtime-manager-DGdKvYzx.js} +1 -1
  35. package/dist/public/assets/file-tree-icon-BeHqeru9.js +590 -0
  36. package/dist/public/assets/index-CcaQt50x.css +1 -0
  37. package/dist/public/assets/index-CuzMc7q2.js +42 -0
  38. package/dist/public/assets/{login-direct-candidate-resolver-wXSaB0i7.js → login-direct-candidate-resolver-DEP_xCmR.js} +1 -1
  39. package/dist/public/assets/{model-switch-api-CPtou49j.js → model-switch-api-c6kcbBGm.js} +1 -1
  40. package/dist/public/assets/{preferences-service-CdaK7zA8.js → preferences-service-CV6Ih0BG.js} +1 -1
  41. package/dist/public/assets/{realtime-client-BjQazYsK.js → realtime-client-CRCx5xBt.js} +1 -1
  42. package/dist/public/assets/{relay-entry-BwE5nw0l.js → relay-entry-C751A-Sm.js} +1 -1
  43. package/dist/public/assets/{terminal-runtime-meta-C-Lbyx2i.js → terminal-runtime-meta-CRAVR-8G.js} +1 -1
  44. package/dist/public/assets/{useRegisteredDebugTemplates-BM7-c-gx.js → useRegisteredDebugTemplates-D6YtNS0r.js} +1 -1
  45. package/dist/public/index.html +2 -2
  46. package/dist/server/config/env.d.ts +3 -0
  47. package/dist/server/config/env.js +67 -1
  48. package/dist/server/config/env.js.map +1 -1
  49. package/dist/server/config/opencode-base-url-resolver.d.ts +3 -2
  50. package/dist/server/config/opencode-base-url-resolver.js +64 -24
  51. package/dist/server/config/opencode-base-url-resolver.js.map +1 -1
  52. package/dist/server/middlewares/auth-guard.js +4 -0
  53. package/dist/server/middlewares/auth-guard.js.map +1 -1
  54. package/dist/server/modules/assistant-capability/assistant-capability-controller.d.ts +168 -1
  55. package/dist/server/modules/assistant-capability/assistant-capability-controller.js +205 -4
  56. package/dist/server/modules/assistant-capability/assistant-capability-controller.js.map +1 -1
  57. package/dist/server/modules/assistant-capability/assistant-capability-service.d.ts +296 -2
  58. package/dist/server/modules/assistant-capability/assistant-capability-service.js +872 -3
  59. package/dist/server/modules/assistant-capability/assistant-capability-service.js.map +1 -1
  60. package/dist/server/modules/auth/auth-service.d.ts +21 -1
  61. package/dist/server/modules/auth/auth-service.js +64 -0
  62. package/dist/server/modules/auth/auth-service.js.map +1 -1
  63. package/dist/server/modules/browser-runtime/browser-profile-service.d.ts +26 -0
  64. package/dist/server/modules/browser-runtime/browser-profile-service.js +85 -0
  65. package/dist/server/modules/browser-runtime/browser-profile-service.js.map +1 -0
  66. package/dist/server/modules/browser-runtime/browser-runtime-controller.d.ts +69 -0
  67. package/dist/server/modules/browser-runtime/browser-runtime-controller.js +83 -0
  68. package/dist/server/modules/browser-runtime/browser-runtime-controller.js.map +1 -0
  69. package/dist/server/modules/browser-runtime/browser-runtime-service.d.ts +56 -0
  70. package/dist/server/modules/browser-runtime/browser-runtime-service.js +215 -0
  71. package/dist/server/modules/browser-runtime/browser-runtime-service.js.map +1 -0
  72. package/dist/server/modules/browser-runtime/browser-task-execution-support.d.ts +65 -0
  73. package/dist/server/modules/browser-runtime/browser-task-execution-support.js +432 -0
  74. package/dist/server/modules/browser-runtime/browser-task-execution-support.js.map +1 -0
  75. package/dist/server/modules/browser-runtime/browser-task-executor-registry.d.ts +7 -0
  76. package/dist/server/modules/browser-runtime/browser-task-executor-registry.js +21 -0
  77. package/dist/server/modules/browser-runtime/browser-task-executor-registry.js.map +1 -0
  78. package/dist/server/modules/browser-runtime/browser-task-executor.d.ts +55 -0
  79. package/dist/server/modules/browser-runtime/browser-task-executor.js +2 -0
  80. package/dist/server/modules/browser-runtime/browser-task-executor.js.map +1 -0
  81. package/dist/server/modules/browser-runtime/browser-task-payload.d.ts +31 -0
  82. package/dist/server/modules/browser-runtime/browser-task-payload.js +55 -0
  83. package/dist/server/modules/browser-runtime/browser-task-payload.js.map +1 -0
  84. package/dist/server/modules/browser-runtime/opencli-bridge-browser-executor.d.ts +19 -0
  85. package/dist/server/modules/browser-runtime/opencli-bridge-browser-executor.js +219 -0
  86. package/dist/server/modules/browser-runtime/opencli-bridge-browser-executor.js.map +1 -0
  87. package/dist/server/modules/browser-runtime/opencli-browser-bridge-service.d.ts +15 -0
  88. package/dist/server/modules/browser-runtime/opencli-browser-bridge-service.js +33 -0
  89. package/dist/server/modules/browser-runtime/opencli-browser-bridge-service.js.map +1 -0
  90. package/dist/server/modules/browser-runtime/playwright-browser-executor.d.ts +16 -0
  91. package/dist/server/modules/browser-runtime/playwright-browser-executor.js +272 -0
  92. package/dist/server/modules/browser-runtime/playwright-browser-executor.js.map +1 -0
  93. package/dist/server/modules/butler/butler-auth-service.js +4 -0
  94. package/dist/server/modules/butler/butler-auth-service.js.map +1 -1
  95. package/dist/server/modules/butler/butler-inbox-instruction-adapter.js +1 -0
  96. package/dist/server/modules/butler/butler-inbox-instruction-adapter.js.map +1 -1
  97. package/dist/server/modules/butler/butler-session-summary-service.d.ts +1 -0
  98. package/dist/server/modules/butler/butler-session-summary-service.js +5 -3
  99. package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -1
  100. package/dist/server/modules/butler/butler-workspace-context.js +23 -0
  101. package/dist/server/modules/butler/butler-workspace-context.js.map +1 -1
  102. package/dist/server/modules/debug-target/debug-target-service.d.ts +2 -0
  103. package/dist/server/modules/debug-target/debug-target-service.js +14 -0
  104. package/dist/server/modules/debug-target/debug-target-service.js.map +1 -1
  105. package/dist/server/modules/document-runtime/document-docx-fallback-renderer.py +139 -0
  106. package/dist/server/modules/document-runtime/document-export-executor.d.ts +50 -0
  107. package/dist/server/modules/document-runtime/document-export-executor.js +827 -0
  108. package/dist/server/modules/document-runtime/document-export-executor.js.map +1 -0
  109. package/dist/server/modules/document-runtime/document-runtime-controller.d.ts +127 -0
  110. package/dist/server/modules/document-runtime/document-runtime-controller.js +131 -0
  111. package/dist/server/modules/document-runtime/document-runtime-controller.js.map +1 -0
  112. package/dist/server/modules/document-runtime/document-runtime-service.d.ts +125 -0
  113. package/dist/server/modules/document-runtime/document-runtime-service.js +706 -0
  114. package/dist/server/modules/document-runtime/document-runtime-service.js.map +1 -0
  115. package/dist/server/modules/office/office-controller.d.ts +77 -0
  116. package/dist/server/modules/office/office-controller.js +174 -0
  117. package/dist/server/modules/office/office-controller.js.map +1 -0
  118. package/dist/server/modules/office/office-preview-link-service.d.ts +27 -0
  119. package/dist/server/modules/office/office-preview-link-service.js +121 -0
  120. package/dist/server/modules/office/office-preview-link-service.js.map +1 -0
  121. package/dist/server/modules/office/office-service.d.ts +67 -0
  122. package/dist/server/modules/office/office-service.js +359 -0
  123. package/dist/server/modules/office/office-service.js.map +1 -0
  124. package/dist/server/modules/opencli/opencli-bridge-skill-service.js +38 -14
  125. package/dist/server/modules/opencli/opencli-bridge-skill-service.js.map +1 -1
  126. package/dist/server/modules/opencli/opencli-install-discovery.d.ts +4 -0
  127. package/dist/server/modules/opencli/opencli-install-discovery.js +94 -0
  128. package/dist/server/modules/opencli/opencli-install-discovery.js.map +1 -1
  129. package/dist/server/modules/opencli/opencli-runtime-builder.js +29 -0
  130. package/dist/server/modules/opencli/opencli-runtime-builder.js.map +1 -1
  131. package/dist/server/modules/opencli/opencli-runtime-guard.d.ts +2 -0
  132. package/dist/server/modules/opencli/opencli-runtime-guard.js +5 -0
  133. package/dist/server/modules/opencli/opencli-runtime-guard.js.map +1 -0
  134. package/dist/server/modules/ops-runtime/ops-runtime-controller.d.ts +70 -0
  135. package/dist/server/modules/ops-runtime/ops-runtime-controller.js +83 -0
  136. package/dist/server/modules/ops-runtime/ops-runtime-controller.js.map +1 -0
  137. package/dist/server/modules/ops-runtime/ops-runtime-service.d.ts +80 -0
  138. package/dist/server/modules/ops-runtime/ops-runtime-service.js +327 -0
  139. package/dist/server/modules/ops-runtime/ops-runtime-service.js.map +1 -0
  140. package/dist/server/modules/ops-runtime/ssh-ops-executor.d.ts +41 -0
  141. package/dist/server/modules/ops-runtime/ssh-ops-executor.js +478 -0
  142. package/dist/server/modules/ops-runtime/ssh-ops-executor.js.map +1 -0
  143. package/dist/server/modules/presentation/presentation-controller.d.ts +22 -0
  144. package/dist/server/modules/presentation/presentation-controller.js +59 -0
  145. package/dist/server/modules/presentation/presentation-controller.js.map +1 -0
  146. package/dist/server/modules/presentation/presentation-export-task-service.d.ts +24 -0
  147. package/dist/server/modules/presentation/presentation-export-task-service.js +137 -0
  148. package/dist/server/modules/presentation/presentation-export-task-service.js.map +1 -0
  149. package/dist/server/modules/presentation/presentation-export-types.d.ts +12 -0
  150. package/dist/server/modules/presentation/presentation-export-types.js +2 -0
  151. package/dist/server/modules/presentation/presentation-export-types.js.map +1 -0
  152. package/dist/server/modules/presentation/presentation-pdf-export-service.d.ts +20 -0
  153. package/dist/server/modules/presentation/presentation-pdf-export-service.js +29 -0
  154. package/dist/server/modules/presentation/presentation-pdf-export-service.js.map +1 -0
  155. package/dist/server/modules/presentation/presentation-pptx-export-service.d.ts +20 -0
  156. package/dist/server/modules/presentation/presentation-pptx-export-service.js +64 -0
  157. package/dist/server/modules/presentation/presentation-pptx-export-service.js.map +1 -0
  158. package/dist/server/modules/presentation/presentation-renderer.d.ts +21 -0
  159. package/dist/server/modules/presentation/presentation-renderer.js +208 -0
  160. package/dist/server/modules/presentation/presentation-renderer.js.map +1 -0
  161. package/dist/server/modules/relay-tunnel/relay-tunnel-gateway-service.js +3 -3
  162. package/dist/server/modules/relay-tunnel/relay-tunnel-gateway-service.js.map +1 -1
  163. package/dist/server/modules/relay-tunnel/relay-tunnel-service.js +6 -1
  164. package/dist/server/modules/relay-tunnel/relay-tunnel-service.js.map +1 -1
  165. package/dist/server/modules/sessions/codex-app-server-helper-process.js +2 -1
  166. package/dist/server/modules/sessions/codex-app-server-helper-process.js.map +1 -1
  167. package/dist/server/modules/sessions/session-controller.d.ts +1 -0
  168. package/dist/server/modules/sessions/session-controller.js +59 -4
  169. package/dist/server/modules/sessions/session-controller.js.map +1 -1
  170. package/dist/server/modules/sessions/session-history-service.js +17 -5
  171. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  172. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +5 -1
  173. package/dist/server/modules/sessions/session-live-runtime-service.js +86 -8
  174. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  175. package/dist/server/modules/sessions/session-provider-config-service.d.ts +25 -1
  176. package/dist/server/modules/sessions/session-provider-config-service.js +54 -5
  177. package/dist/server/modules/sessions/session-provider-config-service.js.map +1 -1
  178. package/dist/server/modules/sessions/workspace-office-mcp-config.d.ts +14 -0
  179. package/dist/server/modules/sessions/workspace-office-mcp-config.js +54 -0
  180. package/dist/server/modules/sessions/workspace-office-mcp-config.js.map +1 -0
  181. package/dist/server/modules/sessions/workspace-session-auth-service.d.ts +27 -0
  182. package/dist/server/modules/sessions/workspace-session-auth-service.js +109 -0
  183. package/dist/server/modules/sessions/workspace-session-auth-service.js.map +1 -0
  184. package/dist/server/modules/sessions/workspace-session-runtime-context-service.d.ts +50 -0
  185. package/dist/server/modules/sessions/workspace-session-runtime-context-service.js +332 -0
  186. package/dist/server/modules/sessions/workspace-session-runtime-context-service.js.map +1 -0
  187. package/dist/server/modules/skills/assistant-runtime-skill-catalog.js +5 -0
  188. package/dist/server/modules/skills/assistant-runtime-skill-catalog.js.map +1 -1
  189. package/dist/server/modules/skills/builtin-skills/codingns-workspace-session/SKILL.md +67 -0
  190. package/dist/server/modules/skills/builtin-skills/codingns-workspace-session/agents/openai.yaml +4 -0
  191. package/dist/server/modules/skills/builtin-skills/codingns-workspace-session/references/cli-workflow.md +133 -0
  192. package/dist/server/modules/skills/skill-controller.d.ts +7 -0
  193. package/dist/server/modules/skills/skill-controller.js +7 -0
  194. package/dist/server/modules/skills/skill-controller.js.map +1 -1
  195. package/dist/server/modules/skills/skill-manager-service.d.ts +61 -0
  196. package/dist/server/modules/skills/skill-manager-service.js +218 -0
  197. package/dist/server/modules/skills/skill-manager-service.js.map +1 -1
  198. package/dist/server/modules/skills/skill-name-policy.js +2 -1
  199. package/dist/server/modules/skills/skill-name-policy.js.map +1 -1
  200. package/dist/server/modules/tasks/task-helper-client.d.ts +1 -0
  201. package/dist/server/modules/tasks/task-helper-client.js +45 -9
  202. package/dist/server/modules/tasks/task-helper-client.js.map +1 -1
  203. package/dist/server/modules/tasks/task-types.d.ts +5 -0
  204. package/dist/server/modules/tasks/task-types.js +6 -1
  205. package/dist/server/modules/tasks/task-types.js.map +1 -1
  206. package/dist/server/modules/terminal/runtime/conpty-session-agent-process.js +2 -1
  207. package/dist/server/modules/terminal/runtime/conpty-session-agent-process.js.map +1 -1
  208. package/dist/server/modules/terminal/runtime/node-pty-loader.d.ts +5 -0
  209. package/dist/server/modules/terminal/runtime/node-pty-loader.js +68 -0
  210. package/dist/server/modules/terminal/runtime/node-pty-loader.js.map +1 -0
  211. package/dist/server/modules/terminal/runtime/pty-broker-agent-process.js +2 -1
  212. package/dist/server/modules/terminal/runtime/pty-broker-agent-process.js.map +1 -1
  213. package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.js +6 -9
  214. package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.js.map +1 -1
  215. package/dist/server/modules/terminal/runtime/pty-runtime-manager.js +6 -9
  216. package/dist/server/modules/terminal/runtime/pty-runtime-manager.js.map +1 -1
  217. package/dist/server/routes/assistant.d.ts +2 -1
  218. package/dist/server/routes/assistant.js +20 -1
  219. package/dist/server/routes/assistant.js.map +1 -1
  220. package/dist/server/routes/browser-runtime.d.ts +3 -0
  221. package/dist/server/routes/browser-runtime.js +14 -0
  222. package/dist/server/routes/browser-runtime.js.map +1 -0
  223. package/dist/server/routes/document-runtime.d.ts +3 -0
  224. package/dist/server/routes/document-runtime.js +18 -0
  225. package/dist/server/routes/document-runtime.js.map +1 -0
  226. package/dist/server/routes/office.d.ts +3 -0
  227. package/dist/server/routes/office.js +16 -0
  228. package/dist/server/routes/office.js.map +1 -0
  229. package/dist/server/routes/ops-runtime.d.ts +3 -0
  230. package/dist/server/routes/ops-runtime.js +13 -0
  231. package/dist/server/routes/ops-runtime.js.map +1 -0
  232. package/dist/server/routes/presentation.d.ts +3 -0
  233. package/dist/server/routes/presentation.js +5 -0
  234. package/dist/server/routes/presentation.js.map +1 -0
  235. package/dist/server/routes/skills.js +1 -0
  236. package/dist/server/routes/skills.js.map +1 -1
  237. package/dist/server/server/create-server.d.ts +36 -0
  238. package/dist/server/server/create-server.js +215 -4
  239. package/dist/server/server/create-server.js.map +1 -1
  240. package/dist/server/server/release-manifest-sync.d.ts +1 -0
  241. package/dist/server/server/release-manifest-sync.js +2 -2
  242. package/dist/server/server/release-manifest-sync.js.map +1 -1
  243. package/dist/server/server/start-host.js +1 -1
  244. package/dist/server/server/start-host.js.map +1 -1
  245. package/dist/server/storage/repositories/auth-token-repository.js +22 -6
  246. package/dist/server/storage/repositories/auth-token-repository.js.map +1 -1
  247. package/dist/server/storage/repositories/browser-profile-repository.d.ts +18 -0
  248. package/dist/server/storage/repositories/browser-profile-repository.js +134 -0
  249. package/dist/server/storage/repositories/browser-profile-repository.js.map +1 -0
  250. package/dist/server/storage/repositories/document-comment-repository.d.ts +10 -0
  251. package/dist/server/storage/repositories/document-comment-repository.js +118 -0
  252. package/dist/server/storage/repositories/document-comment-repository.js.map +1 -0
  253. package/dist/server/storage/repositories/document-repository.d.ts +16 -0
  254. package/dist/server/storage/repositories/document-repository.js +109 -0
  255. package/dist/server/storage/repositories/document-repository.js.map +1 -0
  256. package/dist/server/storage/repositories/document-revision-repository.d.ts +10 -0
  257. package/dist/server/storage/repositories/document-revision-repository.js +79 -0
  258. package/dist/server/storage/repositories/document-revision-repository.js.map +1 -0
  259. package/dist/server/storage/repositories/document-template-repository.d.ts +13 -0
  260. package/dist/server/storage/repositories/document-template-repository.js +244 -0
  261. package/dist/server/storage/repositories/document-template-repository.js.map +1 -0
  262. package/dist/server/storage/repositories/office-approval-repository.d.ts +11 -0
  263. package/dist/server/storage/repositories/office-approval-repository.js +109 -0
  264. package/dist/server/storage/repositories/office-approval-repository.js.map +1 -0
  265. package/dist/server/storage/repositories/office-artifact-repository.d.ts +10 -0
  266. package/dist/server/storage/repositories/office-artifact-repository.js +89 -0
  267. package/dist/server/storage/repositories/office-artifact-repository.js.map +1 -0
  268. package/dist/server/storage/repositories/office-audit-event-repository.d.ts +8 -0
  269. package/dist/server/storage/repositories/office-audit-event-repository.js +54 -0
  270. package/dist/server/storage/repositories/office-audit-event-repository.js.map +1 -0
  271. package/dist/server/storage/repositories/office-connector-repository.d.ts +10 -0
  272. package/dist/server/storage/repositories/office-connector-repository.js +97 -0
  273. package/dist/server/storage/repositories/office-connector-repository.js.map +1 -0
  274. package/dist/server/storage/repositories/office-receipt-repository.d.ts +8 -0
  275. package/dist/server/storage/repositories/office-receipt-repository.js +48 -0
  276. package/dist/server/storage/repositories/office-receipt-repository.js.map +1 -0
  277. package/dist/server/storage/repositories/office-rollback-record-repository.d.ts +8 -0
  278. package/dist/server/storage/repositories/office-rollback-record-repository.js +60 -0
  279. package/dist/server/storage/repositories/office-rollback-record-repository.js.map +1 -0
  280. package/dist/server/storage/repositories/office-task-repository.d.ts +19 -0
  281. package/dist/server/storage/repositories/office-task-repository.js +199 -0
  282. package/dist/server/storage/repositories/office-task-repository.js.map +1 -0
  283. package/dist/server/storage/repositories/office-task-step-repository.d.ts +10 -0
  284. package/dist/server/storage/repositories/office-task-step-repository.js +110 -0
  285. package/dist/server/storage/repositories/office-task-step-repository.js.map +1 -0
  286. package/dist/server/storage/repositories/ops-target-repository.d.ts +16 -0
  287. package/dist/server/storage/repositories/ops-target-repository.js +119 -0
  288. package/dist/server/storage/repositories/ops-target-repository.js.map +1 -0
  289. package/dist/server/storage/repositories/session-binding-repository.d.ts +4 -0
  290. package/dist/server/storage/repositories/session-binding-repository.js +70 -69
  291. package/dist/server/storage/repositories/session-binding-repository.js.map +1 -1
  292. package/dist/server/storage/repositories/session-changed-file-repository.d.ts +6 -0
  293. package/dist/server/storage/repositories/session-changed-file-repository.js +44 -43
  294. package/dist/server/storage/repositories/session-changed-file-repository.js.map +1 -1
  295. package/dist/server/storage/repositories/session-fork-repository.d.ts +2 -0
  296. package/dist/server/storage/repositories/session-fork-repository.js +42 -41
  297. package/dist/server/storage/repositories/session-fork-repository.js.map +1 -1
  298. package/dist/server/storage/repositories/session-index-repository.d.ts +5 -0
  299. package/dist/server/storage/repositories/session-index-repository.js +153 -152
  300. package/dist/server/storage/repositories/session-index-repository.js.map +1 -1
  301. package/dist/server/storage/repositories/session-message-attachment-repository.d.ts +7 -0
  302. package/dist/server/storage/repositories/session-message-attachment-repository.js +91 -90
  303. package/dist/server/storage/repositories/session-message-attachment-repository.js.map +1 -1
  304. package/dist/server/storage/repositories/session-message-origin-repository.d.ts +2 -0
  305. package/dist/server/storage/repositories/session-message-origin-repository.js +25 -24
  306. package/dist/server/storage/repositories/session-message-origin-repository.js.map +1 -1
  307. package/dist/server/storage/repositories/session-state-repository.d.ts +2 -0
  308. package/dist/server/storage/repositories/session-state-repository.js +35 -34
  309. package/dist/server/storage/repositories/session-state-repository.js.map +1 -1
  310. package/dist/server/storage/repositories/session-status-snapshot-repository.d.ts +2 -0
  311. package/dist/server/storage/repositories/session-status-snapshot-repository.js +25 -24
  312. package/dist/server/storage/repositories/session-status-snapshot-repository.js.map +1 -1
  313. package/dist/server/storage/sqlite/client.js +123 -1
  314. package/dist/server/storage/sqlite/client.js.map +1 -1
  315. package/dist/server/storage/sqlite/schema.sql +300 -1
  316. package/dist/server/types/domain.d.ts +205 -1
  317. package/package.json +14 -7
  318. package/scripts/postinstall.mjs +159 -7
  319. package/dist/public/assets/FileContextPanel-xGTYDclT.js +0 -1
  320. package/dist/public/assets/WorkbenchLayout-DScHaza9.js +0 -244
  321. package/dist/public/assets/WorkbenchShellRoute-DN6LdrqC.js +0 -1
  322. package/dist/public/assets/WorkbenchShellRoute-DhQo_0vu.css +0 -1
  323. package/dist/public/assets/file-tree-icon-lfU9Ag77.js +0 -3
  324. package/dist/public/assets/index-CFYXCsyx.css +0 -1
  325. package/dist/public/assets/index-NGxWr8Ix.js +0 -42
  326. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.d.ts +0 -42
  327. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js +0 -346
  328. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js.map +0 -1
  329. package/node_modules/@codingns/session-sync-core/dist/codex-resume-history.d.ts +0 -1
  330. package/node_modules/@codingns/session-sync-core/dist/codex-resume-history.js +0 -80
  331. package/node_modules/@codingns/session-sync-core/dist/codex-resume-history.js.map +0 -1
  332. package/node_modules/@codingns/session-sync-core/dist/index.d.ts +0 -18
  333. package/node_modules/@codingns/session-sync-core/dist/index.js +0 -19
  334. package/node_modules/@codingns/session-sync-core/dist/index.js.map +0 -1
  335. package/node_modules/@codingns/session-sync-core/dist/kimi-message-normalizer.d.ts +0 -18
  336. package/node_modules/@codingns/session-sync-core/dist/kimi-message-normalizer.js +0 -659
  337. package/node_modules/@codingns/session-sync-core/dist/kimi-message-normalizer.js.map +0 -1
  338. package/node_modules/@codingns/session-sync-core/dist/kimi-shared.d.ts +0 -11
  339. package/node_modules/@codingns/session-sync-core/dist/kimi-shared.js +0 -72
  340. package/node_modules/@codingns/session-sync-core/dist/kimi-shared.js.map +0 -1
  341. package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +0 -67
  342. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +0 -752
  343. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +0 -1
  344. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +0 -48
  345. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +0 -1184
  346. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +0 -1
  347. package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.d.ts +0 -11
  348. package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.js +0 -105
  349. package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.js.map +0 -1
  350. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +0 -84
  351. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +0 -2436
  352. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +0 -1
  353. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.d.ts +0 -47
  354. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js +0 -1480
  355. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js.map +0 -1
  356. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.d.ts +0 -33
  357. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js +0 -684
  358. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js.map +0 -1
  359. package/node_modules/@codingns/session-sync-core/dist/providers/legna-code.d.ts +0 -9
  360. package/node_modules/@codingns/session-sync-core/dist/providers/legna-code.js +0 -17
  361. package/node_modules/@codingns/session-sync-core/dist/providers/legna-code.js.map +0 -1
  362. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.d.ts +0 -1
  363. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js +0 -8
  364. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js.map +0 -1
  365. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.d.ts +0 -48
  366. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js +0 -373
  367. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js.map +0 -1
  368. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +0 -61
  369. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +0 -1191
  370. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +0 -1
  371. package/node_modules/@codingns/session-sync-core/dist/providers/utils.d.ts +0 -27
  372. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js +0 -415
  373. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js.map +0 -1
  374. package/node_modules/@codingns/session-sync-core/dist/registry.d.ts +0 -7
  375. package/node_modules/@codingns/session-sync-core/dist/registry.js +0 -22
  376. package/node_modules/@codingns/session-sync-core/dist/registry.js.map +0 -1
  377. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +0 -24
  378. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +0 -329
  379. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +0 -1
  380. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.d.ts +0 -30
  381. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +0 -939
  382. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +0 -1
  383. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-permissions.d.ts +0 -1
  384. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-permissions.js +0 -16
  385. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-permissions.js.map +0 -1
  386. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +0 -70
  387. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +0 -2571
  388. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +0 -1
  389. package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.d.ts +0 -21
  390. package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.js +0 -561
  391. package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.js.map +0 -1
  392. package/node_modules/@codingns/session-sync-core/dist/runtime/kimi-runtime.d.ts +0 -38
  393. package/node_modules/@codingns/session-sync-core/dist/runtime/kimi-runtime.js +0 -911
  394. package/node_modules/@codingns/session-sync-core/dist/runtime/kimi-runtime.js.map +0 -1
  395. package/node_modules/@codingns/session-sync-core/dist/runtime/legna-runtime.d.ts +0 -15
  396. package/node_modules/@codingns/session-sync-core/dist/runtime/legna-runtime.js +0 -16
  397. package/node_modules/@codingns/session-sync-core/dist/runtime/legna-runtime.js.map +0 -1
  398. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.d.ts +0 -37
  399. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +0 -963
  400. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +0 -1
  401. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.d.ts +0 -21
  402. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js +0 -168
  403. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js.map +0 -1
  404. package/node_modules/@codingns/session-sync-core/dist/runtime/types.d.ts +0 -152
  405. package/node_modules/@codingns/session-sync-core/dist/runtime/types.js +0 -2
  406. package/node_modules/@codingns/session-sync-core/dist/runtime/types.js.map +0 -1
  407. package/node_modules/@codingns/session-sync-core/dist/services.d.ts +0 -28
  408. package/node_modules/@codingns/session-sync-core/dist/services.js +0 -148
  409. package/node_modules/@codingns/session-sync-core/dist/services.js.map +0 -1
  410. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.d.ts +0 -6
  411. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js +0 -9
  412. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js.map +0 -1
  413. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +0 -198
  414. package/node_modules/@codingns/session-sync-core/dist/types.js +0 -2
  415. package/node_modules/@codingns/session-sync-core/dist/types.js.map +0 -1
  416. package/node_modules/@codingns/session-sync-core/package.json +0 -33
@@ -1,1480 +0,0 @@
1
- import { execFile as nodeExecFile } from "node:child_process";
2
- import { accessSync, constants, existsSync, readdirSync, readFileSync, rmSync, statSync } from "node:fs";
3
- import { basename, delimiter, dirname, extname, join } from "node:path";
4
- import { promisify } from "node:util";
5
- import { buildApplyPatchFromStructuredFileTool } from "../patch-builder.js";
6
- import { ensureText, extractTextBlocks, messageIdFromRawRef, nextTimestamp, normalizeWorkspacePath, sliceHistory, stringifyStructuredValue } from "./utils.js";
7
- const execFile = promisify(nodeExecFile);
8
- const GEMINI_RAW_STORE_PREFIX = "gemini://session/";
9
- const DEFAULT_GEMINI_TITLE_LENGTH = 48;
10
- export class GeminiAdapter {
11
- options;
12
- providerId = "gemini";
13
- parsedChatCache = new Map();
14
- localSessionCache = new Map();
15
- constructor(options) {
16
- this.options = options;
17
- }
18
- async detectSessions(workspacePath, options) {
19
- const discovery = await this.detectSessionsDetailed(workspacePath, options);
20
- return discovery.sessions;
21
- }
22
- async detectSessionsDetailed(workspacePath, options) {
23
- const startedAt = Date.now();
24
- const targetPath = normalizeWorkspacePath(workspacePath);
25
- const knownSessions = (options?.knownSessions ?? []).filter((session) => session.provider === this.providerId);
26
- const knownByProviderSessionId = new Map(knownSessions.map((session) => [session.providerSessionId, session]));
27
- const localScan = this.readLocalSessionsDetailed();
28
- const localSessions = localScan.sessions;
29
- const cliResult = await this.readCliSessions(workspacePath);
30
- const mergedByProviderSessionId = new Map();
31
- for (const localSession of localSessions) {
32
- const known = knownByProviderSessionId.get(localSession.providerSessionId);
33
- const resolvedWorkspacePath = localSession.workspacePath || ensureNonEmptyText(known?.workspacePath);
34
- if (!this.matchesWorkspace(resolvedWorkspacePath, targetPath)) {
35
- continue;
36
- }
37
- mergedByProviderSessionId.set(localSession.providerSessionId, {
38
- provider: this.providerId,
39
- providerSessionId: localSession.providerSessionId,
40
- title: localSession.title,
41
- workspacePath: resolvedWorkspacePath || workspacePath,
42
- rawStoreRef: buildGeminiRawStoreRef(localSession.providerSessionId),
43
- lastMessageAt: localSession.lastMessageAt ?? known?.lastMessageAt ?? null,
44
- messageCount: localSession.messageCount,
45
- sourceMtimeMs: localSession.sourceMtimeMs,
46
- sourceSizeBytes: localSession.sourceSizeBytes
47
- });
48
- }
49
- for (const cliSession of cliResult.sessions) {
50
- const known = knownByProviderSessionId.get(cliSession.providerSessionId);
51
- const local = mergedByProviderSessionId.get(cliSession.providerSessionId);
52
- const resolvedWorkspacePath = cliSession.workspacePath ||
53
- local?.workspacePath ||
54
- ensureNonEmptyText(known?.workspacePath);
55
- if (!this.matchesWorkspace(resolvedWorkspacePath, targetPath)) {
56
- continue;
57
- }
58
- mergedByProviderSessionId.set(cliSession.providerSessionId, {
59
- provider: this.providerId,
60
- providerSessionId: cliSession.providerSessionId,
61
- title: local?.title ||
62
- cliSession.title ||
63
- known?.title ||
64
- cliSession.providerSessionId,
65
- workspacePath: resolvedWorkspacePath || workspacePath,
66
- rawStoreRef: buildGeminiRawStoreRef(cliSession.providerSessionId),
67
- lastMessageAt: local?.lastMessageAt ??
68
- cliSession.lastMessageAt ??
69
- known?.lastMessageAt ??
70
- null,
71
- messageCount: local?.messageCount ??
72
- cliSession.messageCount ??
73
- known?.messageCount ??
74
- 0,
75
- sourceMtimeMs: local?.sourceMtimeMs ?? known?.sourceMtimeMs,
76
- sourceSizeBytes: local?.sourceSizeBytes ?? known?.sourceSizeBytes
77
- });
78
- }
79
- // 当 CLI 临时失败时,用 knownSessions 补回最近一次已发现的会话,避免列表突然丢失。
80
- if (!cliResult.isComplete) {
81
- for (const known of knownSessions) {
82
- if (mergedByProviderSessionId.has(known.providerSessionId)) {
83
- continue;
84
- }
85
- if (!this.matchesWorkspace(known.workspacePath, targetPath)) {
86
- continue;
87
- }
88
- mergedByProviderSessionId.set(known.providerSessionId, known);
89
- }
90
- }
91
- const diagnostic = {
92
- provider: this.providerId,
93
- status: cliResult.isComplete ? "success" : "partial",
94
- durationMs: Date.now() - startedAt,
95
- sessionCount: mergedByProviderSessionId.size,
96
- isComplete: cliResult.isComplete,
97
- errorMessage: null,
98
- scannedFiles: localScan.scannedFiles,
99
- skippedByMtimeSize: localScan.skippedByMtimeSize,
100
- parsedFiles: localScan.parsedFiles,
101
- bytesRead: localScan.bytesRead
102
- };
103
- return {
104
- sessions: [...mergedByProviderSessionId.values()].sort((left, right) => (right.lastMessageAt ?? "").localeCompare(left.lastMessageAt ?? "")),
105
- isComplete: cliResult.isComplete,
106
- providerDiagnostics: [diagnostic]
107
- };
108
- }
109
- async readSessionHistory(providerSessionId, rawStoreRef, cursor, limit, direction = "forward") {
110
- const resolvedProviderSessionId = this.resolveProviderSessionId(providerSessionId, rawStoreRef);
111
- const parsedChat = this.readParsedChatBySessionId(resolvedProviderSessionId, resolveGeminiScopedHomeDir(rawStoreRef));
112
- return sliceHistory(parsedChat.messages, cursor, limit, direction);
113
- }
114
- subscribeSession(providerSessionId, rawStoreRef, cursor, limit, onEvent) {
115
- const sessionRef = this.resolveSessionRef(providerSessionId, rawStoreRef);
116
- let currentCursor = cursor;
117
- let lastSeenSignature = "";
118
- let closed = false;
119
- const timer = setInterval(() => {
120
- if (closed || !sessionRef.providerSessionId) {
121
- return;
122
- }
123
- let page;
124
- try {
125
- page = this.readSessionHistorySync(sessionRef.providerSessionId, rawStoreRef, currentCursor, limit);
126
- }
127
- catch {
128
- return;
129
- }
130
- if (page.messages.length === 0) {
131
- return;
132
- }
133
- const signature = `${page.messages.at(-1)?.messageId ?? ""}:${page.cursor ?? ""}`;
134
- if (signature === lastSeenSignature) {
135
- return;
136
- }
137
- lastSeenSignature = signature;
138
- currentCursor = page.cursor;
139
- void onEvent({
140
- messages: page.messages,
141
- cursor: page.cursor
142
- });
143
- }, 700);
144
- return {
145
- close() {
146
- closed = true;
147
- clearInterval(timer);
148
- }
149
- };
150
- }
151
- async resumeSession(providerSessionId, rawStoreRef) {
152
- const resolvedProviderSessionId = this.resolveProviderSessionId(providerSessionId, rawStoreRef);
153
- this.readParsedChatBySessionId(resolvedProviderSessionId, resolveGeminiScopedHomeDir(rawStoreRef));
154
- return {
155
- provider: this.providerId,
156
- providerSessionId: resolvedProviderSessionId,
157
- resumedAt: nextTimestamp(),
158
- rawStoreRef: buildGeminiRawStoreRef(resolvedProviderSessionId, resolveGeminiScopedHomeDir(rawStoreRef))
159
- };
160
- }
161
- async startSession(_workspacePath, _options) {
162
- throw new Error("GEMINI_READ_ONLY_PROVIDER");
163
- }
164
- async sendMessage(_providerSessionId, _rawStoreRef, _content, _clientRequestId, _permissionMode) {
165
- throw new Error("GEMINI_READ_ONLY_PROVIDER");
166
- }
167
- async readSessionTitle(providerSessionId, rawStoreRef) {
168
- const resolvedProviderSessionId = this.resolveProviderSessionId(providerSessionId, rawStoreRef);
169
- const parsedChat = this.readParsedChatBySessionId(resolvedProviderSessionId, resolveGeminiScopedHomeDir(rawStoreRef));
170
- return parsedChat.title;
171
- }
172
- async renameSessionTitle(_providerSessionId, _rawStoreRef, _title) {
173
- throw new Error("GEMINI_READ_ONLY_PROVIDER");
174
- }
175
- async updateSessionArchiveState(_providerSessionId, _rawStoreRef, _isArchived) {
176
- throw new Error("GEMINI_ARCHIVE_NOT_SUPPORTED");
177
- }
178
- async deleteSession(providerSessionId, rawStoreRef) {
179
- const resolvedProviderSessionId = this.resolveProviderSessionId(providerSessionId, rawStoreRef);
180
- const matchedFilePaths = this.findLocalChatFilePathsBySessionId(resolvedProviderSessionId, resolveGeminiScopedHomeDir(rawStoreRef));
181
- let deletedAny = false;
182
- for (const filePath of matchedFilePaths) {
183
- if (!existsSync(filePath)) {
184
- continue;
185
- }
186
- rmSync(filePath, { force: true });
187
- this.parsedChatCache.delete(filePath);
188
- this.localSessionCache.delete(filePath);
189
- deletedAny = true;
190
- }
191
- if (!deletedAny) {
192
- throw new Error("PROVIDER_SESSION_NOT_FOUND");
193
- }
194
- }
195
- getProviderCapabilities() {
196
- return {
197
- provider: this.providerId,
198
- canStartSession: true,
199
- canResumeSession: true,
200
- canSendMessage: true,
201
- inRunInputMode: "none",
202
- supportsSubagents: false,
203
- supportsInterrupt: true,
204
- supportsStructuredToolCalls: true,
205
- supportsTokenUsage: false,
206
- supportsAttachments: false,
207
- supportsPermissionPrompt: false,
208
- supportsCheckpoint: false,
209
- supportsSessionDelete: true,
210
- limitations: [
211
- "当前 Gemini 仅接入会话发现与历史只读能力,运行时链路尚未启用",
212
- "本地 chats schema 属于非稳定公开协议,升级 CLI 后需要通过 fixture 回归"
213
- ]
214
- };
215
- }
216
- async getSessionCapabilities(_providerSessionId) {
217
- return this.getProviderCapabilities();
218
- }
219
- readSessionHistorySync(providerSessionId, rawStoreRef, cursor, limit, direction = "forward") {
220
- const resolvedProviderSessionId = this.resolveProviderSessionId(providerSessionId, rawStoreRef);
221
- const parsedChat = this.readParsedChatBySessionId(resolvedProviderSessionId, resolveGeminiScopedHomeDir(rawStoreRef));
222
- return sliceHistory(parsedChat.messages, cursor, limit, direction);
223
- }
224
- resolveProviderSessionId(providerSessionId, rawStoreRef) {
225
- const sessionRef = this.resolveSessionRef(providerSessionId, rawStoreRef);
226
- if (!sessionRef.providerSessionId) {
227
- throw new Error("PROVIDER_SESSION_ID_REQUIRED");
228
- }
229
- return sessionRef.providerSessionId;
230
- }
231
- resolveSessionRef(providerSessionId, rawStoreRef) {
232
- const trimmedProviderSessionId = providerSessionId.trim();
233
- if (trimmedProviderSessionId) {
234
- return {
235
- providerSessionId: trimmedProviderSessionId,
236
- homeDir: resolveGeminiScopedHomeDir(rawStoreRef),
237
- fromRawStoreRef: false
238
- };
239
- }
240
- return {
241
- providerSessionId: parseGeminiRawStoreRef(rawStoreRef),
242
- homeDir: resolveGeminiScopedHomeDir(rawStoreRef),
243
- fromRawStoreRef: true
244
- };
245
- }
246
- async readCliSessions(workspacePath) {
247
- if (this.options.listSessions) {
248
- try {
249
- return {
250
- sessions: await this.options.listSessions(),
251
- isComplete: true
252
- };
253
- }
254
- catch {
255
- return {
256
- sessions: [],
257
- isComplete: false
258
- };
259
- }
260
- }
261
- const commandPath = this.options.commandPath?.trim() || "gemini";
262
- // CLI 没装是正常场景,直接回退到本地 chats 扫描,不要把整个工作区打成 partial。
263
- if (!isCommandAvailable(commandPath)) {
264
- return {
265
- sessions: [],
266
- isComplete: true
267
- };
268
- }
269
- try {
270
- const sessions = await this.readCliSessionsFromCommand(workspacePath);
271
- return {
272
- sessions,
273
- isComplete: true
274
- };
275
- }
276
- catch {
277
- return {
278
- sessions: [],
279
- isComplete: false
280
- };
281
- }
282
- }
283
- async readCliSessionsFromCommand(workspacePath) {
284
- const commandPath = this.options.commandPath?.trim() || "gemini";
285
- const env = {
286
- ...process.env,
287
- GEMINI_HOME: this.options.homeDir
288
- };
289
- const attempts = [
290
- ["--list-sessions", "--output-format", "json"],
291
- ["--list-sessions"]
292
- ];
293
- let lastError = null;
294
- for (const args of attempts) {
295
- try {
296
- const result = await execFile(commandPath, args, {
297
- env,
298
- cwd: workspacePath,
299
- timeout: 8_000,
300
- windowsHide: true,
301
- shell: shouldUseShellForCommand(commandPath)
302
- });
303
- return parseGeminiCliSessionOutput(result.stdout, workspacePath);
304
- }
305
- catch (error) {
306
- lastError = error;
307
- }
308
- }
309
- throw lastError ?? new Error("GEMINI_LIST_SESSIONS_FAILED");
310
- }
311
- readLocalSessionsDetailed() {
312
- const sessions = [];
313
- const latestByProviderSessionId = new Map();
314
- let scannedFiles = 0;
315
- let skippedByMtimeSize = 0;
316
- let parsedFiles = 0;
317
- let bytesRead = 0;
318
- for (const filePath of listGeminiChatFiles(this.options.homeDir)) {
319
- scannedFiles += 1;
320
- let localSession;
321
- try {
322
- const stats = statSync(filePath);
323
- const cached = this.localSessionCache.get(filePath);
324
- if (cached && cached.mtimeMs === stats.mtimeMs && cached.size === stats.size) {
325
- skippedByMtimeSize += 1;
326
- localSession = cached.session;
327
- }
328
- else {
329
- parsedFiles += 1;
330
- bytesRead += stats.size;
331
- localSession = this.parseLocalSessionSummary(filePath, stats);
332
- this.localSessionCache.set(filePath, {
333
- mtimeMs: stats.mtimeMs,
334
- size: stats.size,
335
- session: localSession
336
- });
337
- }
338
- }
339
- catch {
340
- continue;
341
- }
342
- const existing = latestByProviderSessionId.get(localSession.providerSessionId);
343
- if (existing &&
344
- (existing.sourceMtimeMs > localSession.sourceMtimeMs ||
345
- (existing.sourceMtimeMs === localSession.sourceMtimeMs &&
346
- existing.sourceSizeBytes >= localSession.sourceSizeBytes))) {
347
- continue;
348
- }
349
- latestByProviderSessionId.set(localSession.providerSessionId, localSession);
350
- }
351
- sessions.push(...latestByProviderSessionId.values());
352
- return {
353
- sessions,
354
- scannedFiles,
355
- skippedByMtimeSize,
356
- parsedFiles,
357
- bytesRead
358
- };
359
- }
360
- readParsedChatBySessionId(providerSessionId, scopedHomeDir = null) {
361
- const sessionId = providerSessionId.trim();
362
- if (!sessionId) {
363
- throw new Error("PROVIDER_SESSION_ID_REQUIRED");
364
- }
365
- const chatFiles = listGeminiChatFiles(scopedHomeDir ?? this.options.homeDir);
366
- let matchedByName = null;
367
- let matchedBySessionId = null;
368
- for (const filePath of chatFiles) {
369
- if (basename(filePath, ".json") === sessionId) {
370
- matchedByName = filePath;
371
- }
372
- let summary;
373
- try {
374
- const stats = statSync(filePath);
375
- const cached = this.localSessionCache.get(filePath);
376
- if (cached && cached.mtimeMs === stats.mtimeMs && cached.size === stats.size) {
377
- summary = cached.session;
378
- }
379
- else {
380
- summary = this.parseLocalSessionSummary(filePath, stats);
381
- this.localSessionCache.set(filePath, {
382
- mtimeMs: stats.mtimeMs,
383
- size: stats.size,
384
- session: summary
385
- });
386
- }
387
- }
388
- catch (error) {
389
- if (basename(filePath, ".json") === sessionId) {
390
- throw wrapGeminiSchemaError(filePath, error);
391
- }
392
- continue;
393
- }
394
- if (summary.providerSessionId === sessionId) {
395
- matchedBySessionId = filePath;
396
- break;
397
- }
398
- }
399
- if (matchedBySessionId) {
400
- return this.readCachedLocalChatFile(matchedBySessionId);
401
- }
402
- if (matchedByName) {
403
- try {
404
- return this.readCachedLocalChatFile(matchedByName);
405
- }
406
- catch (error) {
407
- throw wrapGeminiSchemaError(matchedByName, error);
408
- }
409
- }
410
- throw new Error("GEMINI_CHAT_NOT_FOUND");
411
- }
412
- findLocalChatFilePathsBySessionId(providerSessionId, scopedHomeDir = null) {
413
- const sessionId = providerSessionId.trim();
414
- if (!sessionId) {
415
- throw new Error("PROVIDER_SESSION_ID_REQUIRED");
416
- }
417
- const matchedFilePaths = new Set();
418
- for (const filePath of listGeminiChatFiles(scopedHomeDir ?? this.options.homeDir)) {
419
- if (basename(filePath, ".json") === sessionId) {
420
- matchedFilePaths.add(filePath);
421
- continue;
422
- }
423
- try {
424
- const stats = statSync(filePath);
425
- const cached = this.localSessionCache.get(filePath);
426
- const summary = cached && cached.mtimeMs === stats.mtimeMs && cached.size === stats.size
427
- ? cached.session
428
- : this.parseLocalSessionSummary(filePath, stats);
429
- if (!cached || cached.mtimeMs !== stats.mtimeMs || cached.size !== stats.size) {
430
- this.localSessionCache.set(filePath, {
431
- mtimeMs: stats.mtimeMs,
432
- size: stats.size,
433
- session: summary
434
- });
435
- }
436
- if (summary.providerSessionId === sessionId) {
437
- matchedFilePaths.add(filePath);
438
- }
439
- }
440
- catch {
441
- continue;
442
- }
443
- }
444
- return [...matchedFilePaths];
445
- }
446
- readCachedLocalChatFile(filePath) {
447
- const stats = statSync(filePath);
448
- const cached = this.parsedChatCache.get(filePath);
449
- if (cached && cached.mtimeMs === stats.mtimeMs && cached.size === stats.size) {
450
- return cached.parsedChat;
451
- }
452
- const parsedChat = this.parseLocalChatFile(filePath, stats);
453
- this.parsedChatCache.set(filePath, {
454
- mtimeMs: stats.mtimeMs,
455
- size: stats.size,
456
- parsedChat
457
- });
458
- return parsedChat;
459
- }
460
- parseLocalChatFile(filePath, stats) {
461
- const parsedRecord = readGeminiParsedChatSource(filePath).record;
462
- const providerSessionId = this.resolveLocalProviderSessionId(parsedRecord, filePath);
463
- const messageNodes = readMessageNodes(parsedRecord);
464
- const messages = normalizeMessageNodes({
465
- sessionId: providerSessionId,
466
- filePath,
467
- messageNodes
468
- });
469
- const title = resolveStringField(parsedRecord, ["title", "name", "chatTitle"]) ||
470
- messages.find((message) => message.role === "user")?.content.slice(0, DEFAULT_GEMINI_TITLE_LENGTH) ||
471
- providerSessionId;
472
- const workspacePath = resolveWorkspacePath(parsedRecord, messageNodes, filePath);
473
- const lastMessageAt = messages.at(-1)?.timestamp ||
474
- resolveStringField(parsedRecord, [
475
- "updatedAt",
476
- "updated_at",
477
- "lastUpdated",
478
- "last_updated",
479
- "lastMessageAt",
480
- "last_message_at",
481
- "startTime",
482
- "start_time",
483
- "createdAt",
484
- "created_at"
485
- ]) ||
486
- null;
487
- return {
488
- providerSessionId,
489
- workspacePath,
490
- title,
491
- lastMessageAt,
492
- messages,
493
- sourceMtimeMs: stats.mtimeMs,
494
- sourceSizeBytes: stats.size
495
- };
496
- }
497
- parseLocalSessionSummary(filePath, stats) {
498
- const parsedRecord = readGeminiParsedChatSource(filePath).record;
499
- const providerSessionId = this.resolveLocalProviderSessionId(parsedRecord, filePath);
500
- const messageNodes = readMessageNodes(parsedRecord);
501
- const messageSummary = summarizeGeminiMessageNodes(messageNodes);
502
- const workspacePath = resolveWorkspacePath(parsedRecord, messageNodes, filePath);
503
- return {
504
- providerSessionId,
505
- workspacePath,
506
- title: resolveStringField(parsedRecord, ["title", "name", "chatTitle"]) ||
507
- messageSummary.firstUserText?.slice(0, DEFAULT_GEMINI_TITLE_LENGTH) ||
508
- providerSessionId,
509
- lastMessageAt: resolveStringField(parsedRecord, [
510
- "updatedAt",
511
- "updated_at",
512
- "lastUpdated",
513
- "last_updated",
514
- "lastMessageAt",
515
- "last_message_at",
516
- "startTime",
517
- "start_time",
518
- "createdAt",
519
- "created_at"
520
- ]) ||
521
- messageSummary.lastMessageAt,
522
- messageCount: resolveGeminiSummaryMessageCount(parsedRecord, messageSummary.messageCount),
523
- filePath,
524
- sourceMtimeMs: stats.mtimeMs,
525
- sourceSizeBytes: stats.size
526
- };
527
- }
528
- resolveLocalProviderSessionId(record, filePath) {
529
- const sessionId = resolveStringField(record, [
530
- "sessionId",
531
- "session_id",
532
- "id",
533
- "chatId",
534
- "conversationId",
535
- "conversation_id"
536
- ]) || stripGeminiChatFileExtension(filePath);
537
- if (!sessionId.trim()) {
538
- throw new Error("GEMINI_CHAT_SCHEMA_INVALID");
539
- }
540
- return sessionId.trim();
541
- }
542
- matchesWorkspace(workspacePath, targetPath) {
543
- const normalizedWorkspacePath = normalizeWorkspacePath(workspacePath ?? "");
544
- if (!normalizedWorkspacePath) {
545
- return false;
546
- }
547
- return normalizedWorkspacePath === targetPath;
548
- }
549
- }
550
- function parseGeminiRawStoreRef(rawStoreRef) {
551
- const trimmed = rawStoreRef.trim();
552
- if (!trimmed.startsWith(GEMINI_RAW_STORE_PREFIX)) {
553
- return null;
554
- }
555
- const rawSessionId = trimmed.slice(GEMINI_RAW_STORE_PREFIX.length).split(/[?#]/, 1)[0];
556
- return rawSessionId ? decodeURIComponent(rawSessionId) : null;
557
- }
558
- function resolveGeminiScopedHomeDir(rawStoreRef) {
559
- const trimmed = rawStoreRef.trim();
560
- if (!trimmed.startsWith(GEMINI_RAW_STORE_PREFIX)) {
561
- return null;
562
- }
563
- const query = trimmed.split("?", 2)[1] ?? "";
564
- const params = new URLSearchParams(query);
565
- const homeDir = params.get("homeDir")?.trim();
566
- return homeDir ? homeDir : null;
567
- }
568
- function buildGeminiRawStoreRef(providerSessionId, scopedHomeDir = null) {
569
- const encodedSessionId = encodeURIComponent(providerSessionId);
570
- if (!scopedHomeDir?.trim()) {
571
- return `${GEMINI_RAW_STORE_PREFIX}${encodedSessionId}`;
572
- }
573
- return `${GEMINI_RAW_STORE_PREFIX}${encodedSessionId}?homeDir=${encodeURIComponent(scopedHomeDir)}`;
574
- }
575
- function listGeminiChatFiles(homeDir) {
576
- const tmpRoot = join(homeDir, "tmp");
577
- if (!existsSync(tmpRoot)) {
578
- return [];
579
- }
580
- const queue = [tmpRoot];
581
- const chatFiles = [];
582
- while (queue.length > 0) {
583
- const current = queue.shift();
584
- if (!current) {
585
- continue;
586
- }
587
- const entries = readdirSync(current, { withFileTypes: true });
588
- for (const entry of entries) {
589
- const entryPath = join(current, entry.name);
590
- if (entry.isDirectory()) {
591
- queue.push(entryPath);
592
- continue;
593
- }
594
- if (!entry.isFile()
595
- || (!entry.name.endsWith(".json") && !entry.name.endsWith(".jsonl"))) {
596
- continue;
597
- }
598
- if (!isGeminiChatFile(entryPath)) {
599
- continue;
600
- }
601
- chatFiles.push(entryPath);
602
- }
603
- }
604
- return chatFiles;
605
- }
606
- function readGeminiParsedChatSource(filePath) {
607
- const raw = readFileSync(filePath, "utf8").trim();
608
- if (!raw) {
609
- throw new Error("GEMINI_CHAT_SCHEMA_INVALID");
610
- }
611
- try {
612
- if (filePath.endsWith(".jsonl")) {
613
- return {
614
- record: parseGeminiJsonlChat(raw)
615
- };
616
- }
617
- return {
618
- record: toRecord(JSON.parse(raw))
619
- };
620
- }
621
- catch (error) {
622
- throw wrapGeminiSchemaError(filePath, error);
623
- }
624
- }
625
- function parseGeminiJsonlChat(raw) {
626
- const lines = raw.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
627
- if (lines.length === 0) {
628
- throw new Error("GEMINI_CHAT_SCHEMA_INVALID");
629
- }
630
- const root = {};
631
- const messages = [];
632
- for (const line of lines) {
633
- const parsedLine = toRecord(JSON.parse(line));
634
- const patch = maybeRecord(parsedLine.$set);
635
- if (patch) {
636
- Object.assign(root, patch);
637
- continue;
638
- }
639
- if (isGeminiJsonlMessageLine(parsedLine)) {
640
- messages.push(parsedLine);
641
- continue;
642
- }
643
- Object.assign(root, parsedLine);
644
- }
645
- root.messages = messages;
646
- return root;
647
- }
648
- function isGeminiJsonlMessageLine(record) {
649
- const type = ensureText(record.type).trim().toLowerCase();
650
- if (type === "user" || type === "gemini" || type === "tool" || type === "system") {
651
- return true;
652
- }
653
- return Boolean(record.content !== undefined
654
- || record.parts !== undefined
655
- || record.toolCalls !== undefined
656
- || record.tool_calls !== undefined
657
- || record.thoughts !== undefined);
658
- }
659
- function stripGeminiChatFileExtension(filePath) {
660
- const name = basename(filePath);
661
- if (name.endsWith(".jsonl")) {
662
- return name.slice(0, -".jsonl".length);
663
- }
664
- if (name.endsWith(".json")) {
665
- return name.slice(0, -".json".length);
666
- }
667
- return name;
668
- }
669
- function isGeminiChatFile(filePath) {
670
- return filePath.replaceAll("\\", "/").includes("/chats/");
671
- }
672
- function parseGeminiCliSessionOutput(stdout, workspacePathFallback = null) {
673
- const trimmed = stdout.trim();
674
- if (!trimmed) {
675
- return [];
676
- }
677
- const parsedAsWhole = parseJsonSafe(trimmed);
678
- const normalizedWhole = normalizeCliSessionsPayload(parsedAsWhole, workspacePathFallback);
679
- if (normalizedWhole.length > 0) {
680
- return normalizedWhole;
681
- }
682
- const normalizedText = parseGeminiPlainTextSessions(trimmed, workspacePathFallback);
683
- if (normalizedText.length > 0) {
684
- return normalizedText;
685
- }
686
- const sessions = [];
687
- for (const line of trimmed.split(/\r?\n/)) {
688
- const parsedLine = parseJsonSafe(line.trim());
689
- if (!parsedLine) {
690
- continue;
691
- }
692
- sessions.push(...normalizeCliSessionsPayload(parsedLine, workspacePathFallback));
693
- }
694
- return dedupeCliSessions(sessions);
695
- }
696
- function normalizeCliSessionsPayload(payload, workspacePathFallback) {
697
- if (!payload) {
698
- return [];
699
- }
700
- if (Array.isArray(payload)) {
701
- return dedupeCliSessions(payload
702
- .map((item) => normalizeCliSessionRecord(item, workspacePathFallback))
703
- .filter((item) => item !== null));
704
- }
705
- const record = toRecord(payload);
706
- const wrappedArray = arrayFromUnknown(record.sessions) ||
707
- arrayFromUnknown(record.items) ||
708
- arrayFromUnknown(record.data);
709
- if (wrappedArray) {
710
- return dedupeCliSessions(wrappedArray
711
- .map((item) => normalizeCliSessionRecord(item, workspacePathFallback))
712
- .filter((item) => item !== null));
713
- }
714
- const single = normalizeCliSessionRecord(record, workspacePathFallback);
715
- return single ? [single] : [];
716
- }
717
- function normalizeCliSessionRecord(payload, workspacePathFallback) {
718
- const record = toRecord(payload);
719
- const providerSessionId = resolveStringField(record, [
720
- "sessionId",
721
- "session_id",
722
- "id",
723
- "conversationId",
724
- "conversation_id"
725
- ]);
726
- if (!providerSessionId) {
727
- return null;
728
- }
729
- const messageCountValue = resolveNumberField(record, ["messageCount", "message_count"]);
730
- return {
731
- providerSessionId,
732
- workspacePath: resolveStringField(record, [
733
- "workspacePath",
734
- "workspace_path",
735
- "cwd",
736
- "directory",
737
- "projectPath",
738
- "project_path"
739
- ]) || workspacePathFallback,
740
- title: resolveStringField(record, ["title", "name", "summary"]) || null,
741
- lastMessageAt: resolveStringField(record, [
742
- "updatedAt",
743
- "updated_at",
744
- "lastUpdated",
745
- "last_updated",
746
- "lastMessageAt",
747
- "last_message_at",
748
- "startTime",
749
- "start_time",
750
- "createdAt",
751
- "created_at"
752
- ]) || null,
753
- messageCount: messageCountValue === null ? null : messageCountValue
754
- };
755
- }
756
- function dedupeCliSessions(sessions) {
757
- const deduped = new Map();
758
- for (const session of sessions) {
759
- const existing = deduped.get(session.providerSessionId);
760
- if (!existing ||
761
- (existing.lastMessageAt ?? "").localeCompare(session.lastMessageAt ?? "") < 0) {
762
- deduped.set(session.providerSessionId, session);
763
- }
764
- }
765
- return [...deduped.values()];
766
- }
767
- function resolveWorkspacePath(record, messageNodes, filePath) {
768
- const directWorkspace = resolveStringField(record, [
769
- "workspacePath",
770
- "workspace_path",
771
- "cwd",
772
- "projectPath",
773
- "project_path"
774
- ]);
775
- if (directWorkspace) {
776
- return directWorkspace;
777
- }
778
- for (const node of messageNodes) {
779
- const nodeRecord = toRecord(node);
780
- const workspace = resolveStringField(nodeRecord, [
781
- "workspacePath",
782
- "workspace_path",
783
- "cwd",
784
- "projectPath",
785
- "project_path"
786
- ]);
787
- if (workspace) {
788
- return workspace;
789
- }
790
- }
791
- return resolveWorkspacePathFromChatFile(filePath);
792
- }
793
- function readMessageNodes(record) {
794
- const candidates = [
795
- record.messages,
796
- record.history,
797
- record.events,
798
- record.contents,
799
- record.turns,
800
- toRecord(record.chat).messages,
801
- toRecord(record.conversation).messages,
802
- toRecord(record.transcript).messages
803
- ];
804
- for (const candidate of candidates) {
805
- const array = arrayFromUnknown(candidate);
806
- if (array && array.length > 0) {
807
- return array;
808
- }
809
- }
810
- return [];
811
- }
812
- function normalizeMessageNodes(input) {
813
- const messages = [];
814
- let sequence = 0;
815
- const identityState = {
816
- userTextIndex: 0,
817
- assistantTextIndex: 0
818
- };
819
- for (let index = 0; index < input.messageNodes.length; index += 1) {
820
- const node = input.messageNodes[index];
821
- const nodeRecord = toRecord(node);
822
- const role = resolveGeminiRole(nodeRecord);
823
- const timestamp = resolveMessageTimestamp(nodeRecord);
824
- const descriptors = readMessageDescriptors(nodeRecord, role);
825
- if (descriptors.length === 0) {
826
- continue;
827
- }
828
- for (let descriptorIndex = 0; descriptorIndex < descriptors.length; descriptorIndex += 1) {
829
- const descriptor = descriptors[descriptorIndex];
830
- sequence += 1;
831
- const rawRef = buildGeminiMessageRawRef(input.sessionId, input.filePath, index, descriptorIndex);
832
- const messageId = buildGeminiMessageId({
833
- sessionId: input.sessionId,
834
- descriptor,
835
- rawRef,
836
- identityState
837
- });
838
- messages.push({
839
- messageId,
840
- provider: "gemini",
841
- providerSessionId: input.sessionId,
842
- role: descriptor.role,
843
- kind: descriptor.kind,
844
- content: descriptor.content,
845
- toolCall: descriptor.toolCall,
846
- timestamp: descriptor.timestamp ?? timestamp,
847
- sequence,
848
- rawRef
849
- });
850
- }
851
- }
852
- return messages;
853
- }
854
- function summarizeGeminiMessageNodes(messageNodes) {
855
- let messageCount = 0;
856
- let lastMessageAt = null;
857
- let firstUserText = null;
858
- for (const node of messageNodes) {
859
- const nodeRecord = toRecord(node);
860
- const role = resolveGeminiRole(nodeRecord);
861
- const nodeTimestamp = resolveMessageTimestamp(nodeRecord);
862
- const descriptors = readMessageDescriptors(nodeRecord, role);
863
- if (descriptors.length === 0) {
864
- continue;
865
- }
866
- messageCount += descriptors.length;
867
- lastMessageAt = descriptors.at(-1)?.timestamp ?? nodeTimestamp;
868
- if (firstUserText) {
869
- continue;
870
- }
871
- const firstUserDescriptor = descriptors.find((descriptor) => descriptor.role === "user" &&
872
- descriptor.kind === "text" &&
873
- descriptor.content.trim().length > 0);
874
- if (firstUserDescriptor) {
875
- firstUserText = firstUserDescriptor.content.trim();
876
- }
877
- }
878
- return {
879
- messageCount,
880
- lastMessageAt,
881
- firstUserText
882
- };
883
- }
884
- function resolveGeminiSummaryMessageCount(record, fallbackMessageCount) {
885
- const explicitMessageCount = firstGeminiNumber(record.messageCount, record.message_count, record.totalMessages, record.total_messages, record.messageTotal);
886
- if (explicitMessageCount !== null && explicitMessageCount >= 0) {
887
- return Math.trunc(explicitMessageCount);
888
- }
889
- return fallbackMessageCount;
890
- }
891
- function firstGeminiNumber(...values) {
892
- for (const value of values) {
893
- if (typeof value === "number" && Number.isFinite(value)) {
894
- return value;
895
- }
896
- if (typeof value === "string") {
897
- const trimmed = value.trim();
898
- if (!trimmed) {
899
- continue;
900
- }
901
- const parsed = Number(trimmed);
902
- if (Number.isFinite(parsed)) {
903
- return parsed;
904
- }
905
- }
906
- }
907
- return null;
908
- }
909
- function readMessageDescriptors(nodeRecord, fallbackRole) {
910
- const descriptors = [];
911
- descriptors.push(...readGeminiThoughtDescriptors(nodeRecord));
912
- descriptors.push(...readGeminiToolCallDescriptors(nodeRecord));
913
- const parts = arrayFromUnknown(nodeRecord.parts) ||
914
- arrayFromUnknown(nodeRecord.content) ||
915
- arrayFromUnknown(toRecord(nodeRecord.message).parts) ||
916
- null;
917
- const partDescriptors = [];
918
- if (parts && parts.length > 0) {
919
- for (const part of parts) {
920
- const descriptor = normalizeMessagePart(part, fallbackRole);
921
- if (descriptor) {
922
- partDescriptors.push(descriptor);
923
- }
924
- }
925
- }
926
- if (partDescriptors.length > 0) {
927
- descriptors.push(...partDescriptors);
928
- return descriptors;
929
- }
930
- const fallbackDescriptor = normalizeMessagePart(nodeRecord, fallbackRole);
931
- if (fallbackDescriptor) {
932
- descriptors.push(fallbackDescriptor);
933
- }
934
- return descriptors;
935
- }
936
- function normalizeMessagePart(value, fallbackRole) {
937
- const record = toRecord(value);
938
- const toolCallPayload = maybeRecord(record.tool_use) ??
939
- maybeRecord(record.toolUse) ??
940
- maybeRecord(record.functionCall) ??
941
- (record.type === "tool_use" || record.type === "function_call" ? record : null);
942
- if (toolCallPayload) {
943
- const timestamp = resolveOptionalMessageTimestamp(record);
944
- const patchText = buildGeminiApplyPatchFromInput(toolCallPayload);
945
- const callId = resolveStringField(toolCallPayload, ["id", "toolCallId", "call_id"]) || "gemini-call";
946
- const name = patchText
947
- ? "apply_patch"
948
- : resolveStringField(toolCallPayload, ["name", "toolName", "tool_name"]) || "unknown_tool";
949
- const inputPayload = toolCallPayload.input ??
950
- toolCallPayload.arguments ??
951
- toolCallPayload.args ??
952
- null;
953
- const inputText = patchText || stringifyStructuredValue(inputPayload);
954
- return {
955
- role: patchText ? "tool" : "assistant",
956
- kind: "tool_call",
957
- content: inputText,
958
- toolCall: {
959
- callId,
960
- name,
961
- input: inputText,
962
- output: null,
963
- error: null,
964
- status: "running"
965
- },
966
- timestamp
967
- };
968
- }
969
- const toolResultPayload = maybeRecord(record.tool_result) ??
970
- maybeRecord(record.toolResult) ??
971
- maybeRecord(record.functionResponse) ??
972
- (record.type === "tool_result" || record.type === "function_response" ? record : null);
973
- if (toolResultPayload) {
974
- const timestamp = resolveOptionalMessageTimestamp(record);
975
- const errorDetail = resolveStringField(toolResultPayload, ["error", "error_message"]);
976
- const outputPayload = toolResultPayload.output ??
977
- toolResultPayload.result ??
978
- toolResultPayload.content ??
979
- null;
980
- const normalizedName = resolveStringField(toolResultPayload, [
981
- "name",
982
- "tool_name",
983
- "toolName"
984
- ]) || "unknown_tool";
985
- const name = isGeminiEditableToolName(normalizedName) ? "apply_patch" : normalizedName;
986
- return {
987
- role: "tool",
988
- kind: "tool_result",
989
- content: extractTextBlocks(outputPayload).trim() || stringifyStructuredValue(outputPayload),
990
- toolCall: {
991
- callId: resolveStringField(toolResultPayload, [
992
- "tool_use_id",
993
- "toolUseId",
994
- "call_id",
995
- "callId"
996
- ]) || "gemini-tool-result",
997
- name,
998
- input: "",
999
- output: stringifyStructuredValue(outputPayload),
1000
- error: errorDetail,
1001
- status: errorDetail ? "failed" : "completed"
1002
- },
1003
- timestamp
1004
- };
1005
- }
1006
- const text = extractTextBlocks(record.text ??
1007
- record.content ??
1008
- record.output ??
1009
- record.message ??
1010
- value).trim();
1011
- if (!text) {
1012
- return null;
1013
- }
1014
- const partType = ensureText(record.type).toLowerCase();
1015
- const kind = partType.includes("think") ? "thinking" : "text";
1016
- return {
1017
- role: fallbackRole,
1018
- kind,
1019
- content: text,
1020
- toolCall: null,
1021
- timestamp: resolveOptionalMessageTimestamp(record)
1022
- };
1023
- }
1024
- function readGeminiThoughtDescriptors(nodeRecord) {
1025
- const thoughts = arrayFromUnknown(nodeRecord.thoughts) ??
1026
- arrayFromUnknown(nodeRecord.reasoning) ??
1027
- null;
1028
- if (!thoughts || thoughts.length === 0) {
1029
- return [];
1030
- }
1031
- return thoughts
1032
- .map((thought) => normalizeGeminiThoughtDescriptor(thought))
1033
- .filter((descriptor) => descriptor !== null);
1034
- }
1035
- function normalizeGeminiThoughtDescriptor(value) {
1036
- const record = toRecord(value);
1037
- const subject = resolveStringField(record, ["subject", "title", "name"]);
1038
- const description = resolveStringField(record, [
1039
- "description",
1040
- "content",
1041
- "text",
1042
- "message"
1043
- ]);
1044
- const content = [subject, description].filter((item) => Boolean(item)).join("\n\n").trim();
1045
- if (!content) {
1046
- return null;
1047
- }
1048
- return {
1049
- role: "assistant",
1050
- kind: "thinking",
1051
- content,
1052
- toolCall: null,
1053
- timestamp: resolveOptionalMessageTimestamp(record)
1054
- };
1055
- }
1056
- function readGeminiToolCallDescriptors(nodeRecord) {
1057
- const toolCalls = arrayFromUnknown(nodeRecord.toolCalls) ??
1058
- arrayFromUnknown(nodeRecord.tool_calls) ??
1059
- null;
1060
- if (!toolCalls || toolCalls.length === 0) {
1061
- return [];
1062
- }
1063
- const descriptors = [];
1064
- for (let index = 0; index < toolCalls.length; index += 1) {
1065
- const descriptorSet = normalizeGeminiToolCall(toolCalls[index], index);
1066
- if (descriptorSet.call) {
1067
- descriptors.push(descriptorSet.call);
1068
- }
1069
- if (descriptorSet.result) {
1070
- descriptors.push(descriptorSet.result);
1071
- }
1072
- }
1073
- return descriptors;
1074
- }
1075
- function normalizeGeminiToolCall(value, index) {
1076
- const record = toRecord(value);
1077
- const timestamp = resolveOptionalMessageTimestamp(record);
1078
- const patchText = buildGeminiApplyPatchFromInput(record);
1079
- const callId = resolveStringField(record, ["id", "toolCallId", "call_id"]) ||
1080
- `gemini-tool-call-${index + 1}`;
1081
- const rawName = resolveStringField(record, ["name", "toolName", "tool_name", "displayName"]) || "tool";
1082
- const name = patchText ? "apply_patch" : rawName;
1083
- const inputPayload = record.args ?? record.input ?? record.arguments ?? null;
1084
- const inputText = patchText || stringifyStructuredValue(inputPayload);
1085
- const callDescriptor = {
1086
- role: patchText ? "tool" : "assistant",
1087
- kind: "tool_call",
1088
- content: inputText || name,
1089
- toolCall: {
1090
- callId,
1091
- name,
1092
- input: inputText,
1093
- output: null,
1094
- error: null,
1095
- status: "running"
1096
- },
1097
- timestamp
1098
- };
1099
- return {
1100
- call: callDescriptor,
1101
- result: normalizeGeminiToolCallResult(record, callId, name, timestamp)
1102
- };
1103
- }
1104
- function normalizeGeminiToolCallResult(record, callId, name, fallbackTimestamp) {
1105
- const output = extractGeminiToolCallOutput(record);
1106
- const error = extractGeminiToolCallError(record);
1107
- const hasResultPayload = Array.isArray(record.result) ||
1108
- record.result !== undefined ||
1109
- record.output !== undefined ||
1110
- record.resultDisplay !== undefined ||
1111
- error !== null;
1112
- if (!hasResultPayload) {
1113
- return null;
1114
- }
1115
- const status = normalizeGeminiToolCallStatus(record, error);
1116
- const content = output || error || name;
1117
- if (!content.trim()) {
1118
- return null;
1119
- }
1120
- return {
1121
- role: "tool",
1122
- kind: "tool_result",
1123
- content,
1124
- toolCall: {
1125
- callId,
1126
- name,
1127
- input: "",
1128
- output: output || null,
1129
- error,
1130
- status
1131
- },
1132
- timestamp: resolveStringField(record, [
1133
- "timestamp",
1134
- "updatedAt",
1135
- "updated_at",
1136
- "lastUpdated",
1137
- "last_updated"
1138
- ]) || fallbackTimestamp
1139
- };
1140
- }
1141
- function extractGeminiToolCallOutput(record) {
1142
- const resultItems = arrayFromUnknown(record.result) ?? [];
1143
- for (const item of resultItems) {
1144
- const itemRecord = toRecord(item);
1145
- const functionResponse = toRecord(itemRecord.functionResponse);
1146
- const response = toRecord(functionResponse.response);
1147
- const outputText = extractTextBlocks(response.output ??
1148
- itemRecord.output ??
1149
- itemRecord.result ??
1150
- itemRecord.content).trim();
1151
- if (outputText) {
1152
- return outputText;
1153
- }
1154
- }
1155
- const directOutput = extractTextBlocks(record.output ??
1156
- record.result ??
1157
- toRecord(record.resultDisplay).fileDiff ??
1158
- toRecord(record.resultDisplay).newContent).trim();
1159
- return directOutput;
1160
- }
1161
- function extractGeminiToolCallError(record) {
1162
- const directError = resolveStringField(record, [
1163
- "error",
1164
- "error_message",
1165
- "failure",
1166
- "description"
1167
- ]);
1168
- if (directError && normalizeGeminiToolCallStatus(record, null) === "failed") {
1169
- return directError;
1170
- }
1171
- return null;
1172
- }
1173
- function normalizeGeminiToolCallStatus(record, error) {
1174
- if (error) {
1175
- return "failed";
1176
- }
1177
- const normalizedStatus = ensureText(record.status).trim().toLowerCase();
1178
- if (!normalizedStatus || normalizedStatus === "success" || normalizedStatus === "completed") {
1179
- return "completed";
1180
- }
1181
- if (["error", "failed", "failure", "cancelled", "canceled"].includes(normalizedStatus)) {
1182
- return "failed";
1183
- }
1184
- return "completed";
1185
- }
1186
- function buildGeminiApplyPatchFromInput(value) {
1187
- const input = value && typeof value === "object" && !Array.isArray(value)
1188
- ? value
1189
- : null;
1190
- if (!input) {
1191
- return null;
1192
- }
1193
- const candidates = [toRecord(input.input), toRecord(input.arguments), toRecord(input.args), input];
1194
- for (const candidate of candidates) {
1195
- const patchText = buildApplyPatchFromStructuredFileTool(candidate);
1196
- if (patchText) {
1197
- return patchText;
1198
- }
1199
- }
1200
- return null;
1201
- }
1202
- function isGeminiEditableToolName(toolName) {
1203
- const normalized = toolName.trim().toLowerCase();
1204
- return [
1205
- "write_file",
1206
- "writefile",
1207
- "create_file",
1208
- "edit_file",
1209
- "replace",
1210
- "replace_file",
1211
- "update_file",
1212
- "multi_edit",
1213
- "multiedit"
1214
- ].includes(normalized);
1215
- }
1216
- function resolveGeminiRole(record) {
1217
- const candidate = resolveStringField(record, [
1218
- "role",
1219
- "author",
1220
- "sender",
1221
- "source",
1222
- "participant",
1223
- "type"
1224
- ])?.toLowerCase();
1225
- if (!candidate) {
1226
- return "assistant";
1227
- }
1228
- if (candidate.includes("user") || candidate.includes("human")) {
1229
- return "user";
1230
- }
1231
- if (candidate.includes("tool")) {
1232
- return "tool";
1233
- }
1234
- if (candidate.includes("system")) {
1235
- return "system";
1236
- }
1237
- if (candidate.includes("assistant")
1238
- || candidate.includes("model")
1239
- || candidate.includes("gemini")) {
1240
- return "assistant";
1241
- }
1242
- return "assistant";
1243
- }
1244
- function resolveMessageTimestamp(record) {
1245
- const direct = resolveStringField(record, [
1246
- "timestamp",
1247
- "time",
1248
- "createdAt",
1249
- "created_at",
1250
- "updatedAt",
1251
- "updated_at"
1252
- ]);
1253
- if (direct) {
1254
- return direct;
1255
- }
1256
- return nextTimestamp();
1257
- }
1258
- function resolveOptionalMessageTimestamp(record) {
1259
- return resolveStringField(record, [
1260
- "timestamp",
1261
- "time",
1262
- "createdAt",
1263
- "created_at",
1264
- "updatedAt",
1265
- "updated_at",
1266
- "lastUpdated",
1267
- "last_updated"
1268
- ]);
1269
- }
1270
- function buildGeminiMessageRawRef(sessionId, filePath, messageIndex, partIndex) {
1271
- return `${GEMINI_RAW_STORE_PREFIX}${encodeURIComponent(sessionId)}#file=${encodeURIComponent(filePath.replaceAll("\\", "/"))}&index=${messageIndex}&part=${partIndex}`;
1272
- }
1273
- function buildGeminiMessageId(input) {
1274
- const { descriptor, identityState, rawRef, sessionId } = input;
1275
- if (descriptor.kind === "text" && descriptor.toolCall === null) {
1276
- if (descriptor.role === "user") {
1277
- identityState.userTextIndex += 1;
1278
- return messageIdFromRawRef(buildGeminiRuntimeTextRawRef(sessionId, "user", identityState.userTextIndex));
1279
- }
1280
- if (descriptor.role === "assistant") {
1281
- identityState.assistantTextIndex += 1;
1282
- return messageIdFromRawRef(buildGeminiRuntimeTextRawRef(sessionId, "assistant", identityState.assistantTextIndex));
1283
- }
1284
- }
1285
- if ((descriptor.kind === "tool_call" || descriptor.kind === "tool_result")
1286
- && descriptor.toolCall?.callId?.trim()) {
1287
- return messageIdFromRawRef(buildGeminiRuntimeToolRawRef(sessionId, descriptor.toolCall.callId.trim(), descriptor.kind === "tool_call" ? "call" : "result"));
1288
- }
1289
- return messageIdFromRawRef(rawRef);
1290
- }
1291
- function buildGeminiRuntimeTextRawRef(sessionId, role, index) {
1292
- return `${GEMINI_RAW_STORE_PREFIX}${encodeURIComponent(sessionId)}/message/${role}-${index}`;
1293
- }
1294
- function buildGeminiRuntimeToolRawRef(sessionId, toolId, kind) {
1295
- return `${GEMINI_RAW_STORE_PREFIX}${encodeURIComponent(sessionId)}/tool/${encodeURIComponent(toolId)}/${kind}`;
1296
- }
1297
- function resolveStringField(record, fieldNames) {
1298
- for (const fieldName of fieldNames) {
1299
- const value = ensureNonEmptyText(record[fieldName]);
1300
- if (value) {
1301
- return value;
1302
- }
1303
- }
1304
- const metadata = toRecord(record.metadata);
1305
- for (const fieldName of fieldNames) {
1306
- const value = ensureNonEmptyText(metadata[fieldName]);
1307
- if (value) {
1308
- return value;
1309
- }
1310
- }
1311
- return null;
1312
- }
1313
- function resolveNumberField(record, fieldNames) {
1314
- for (const fieldName of fieldNames) {
1315
- const value = record[fieldName];
1316
- if (typeof value === "number" && Number.isFinite(value)) {
1317
- return Math.max(0, Math.trunc(value));
1318
- }
1319
- if (typeof value === "string") {
1320
- const parsed = Number.parseInt(value, 10);
1321
- if (Number.isFinite(parsed)) {
1322
- return Math.max(0, parsed);
1323
- }
1324
- }
1325
- }
1326
- return null;
1327
- }
1328
- function parseGeminiPlainTextSessions(stdout, workspacePathFallback) {
1329
- const sessions = stdout
1330
- .split(/\r?\n/)
1331
- .map((line) => normalizePlainTextCliSessionLine(line, workspacePathFallback))
1332
- .filter((item) => item !== null);
1333
- return dedupeCliSessions(sessions);
1334
- }
1335
- function normalizePlainTextCliSessionLine(line, workspacePathFallback) {
1336
- const trimmed = line.trim();
1337
- if (!trimmed) {
1338
- return null;
1339
- }
1340
- const sessionIdMatch = trimmed.match(/\[([^\]]+)\]\s*$/);
1341
- if (!sessionIdMatch?.[1]) {
1342
- return null;
1343
- }
1344
- const providerSessionId = sessionIdMatch[1].trim();
1345
- if (!providerSessionId) {
1346
- return null;
1347
- }
1348
- let prefix = trimmed.slice(0, sessionIdMatch.index).trim();
1349
- prefix = prefix.replace(/^\d+\.\s*/, "").trim();
1350
- const timeSuffixMatch = prefix.match(/\(([^()]*)\)\s*$/);
1351
- const title = (timeSuffixMatch && typeof timeSuffixMatch.index === "number"
1352
- ? prefix.slice(0, timeSuffixMatch.index)
1353
- : prefix).trim() || providerSessionId;
1354
- return {
1355
- providerSessionId,
1356
- workspacePath: workspacePathFallback,
1357
- title,
1358
- lastMessageAt: null,
1359
- messageCount: null
1360
- };
1361
- }
1362
- function ensureNonEmptyText(value) {
1363
- const text = ensureText(value).trim();
1364
- return text.length > 0 ? text : null;
1365
- }
1366
- function parseJsonSafe(value) {
1367
- if (!value) {
1368
- return null;
1369
- }
1370
- try {
1371
- return JSON.parse(value);
1372
- }
1373
- catch {
1374
- return null;
1375
- }
1376
- }
1377
- function arrayFromUnknown(value) {
1378
- return Array.isArray(value) ? value : null;
1379
- }
1380
- function toRecord(value) {
1381
- if (value && typeof value === "object" && !Array.isArray(value)) {
1382
- return value;
1383
- }
1384
- return {};
1385
- }
1386
- function maybeRecord(value) {
1387
- if (value && typeof value === "object" && !Array.isArray(value)) {
1388
- return value;
1389
- }
1390
- return null;
1391
- }
1392
- function resolveWorkspacePathFromChatFile(filePath) {
1393
- const projectRootFile = join(dirname(dirname(filePath)), ".project_root");
1394
- if (!existsSync(projectRootFile)) {
1395
- return null;
1396
- }
1397
- try {
1398
- return ensureNonEmptyText(readFileSync(projectRootFile, "utf8"));
1399
- }
1400
- catch {
1401
- return null;
1402
- }
1403
- }
1404
- function shouldUseShellForCommand(commandPath) {
1405
- return process.platform === "win32" && [".cmd", ".bat"].includes(extname(commandPath).toLowerCase());
1406
- }
1407
- function isCommandAvailable(commandPath) {
1408
- const normalizedCommandPath = stripWrappingQuotes(commandPath);
1409
- if (!normalizedCommandPath) {
1410
- return false;
1411
- }
1412
- if (normalizedCommandPath.includes("/")
1413
- || normalizedCommandPath.includes("\\")) {
1414
- if (!existsSync(normalizedCommandPath)) {
1415
- return false;
1416
- }
1417
- const extension = extname(normalizedCommandPath).toLowerCase();
1418
- if ([".js", ".cjs", ".mjs"].includes(extension)) {
1419
- return true;
1420
- }
1421
- if (process.platform === "win32") {
1422
- return true;
1423
- }
1424
- try {
1425
- accessSync(normalizedCommandPath, constants.X_OK);
1426
- return true;
1427
- }
1428
- catch {
1429
- return false;
1430
- }
1431
- }
1432
- const pathEntries = (process.env.PATH ?? "")
1433
- .split(delimiter)
1434
- .map((entry) => entry.trim())
1435
- .filter(Boolean);
1436
- if (process.platform === "win32") {
1437
- const pathextEntries = (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM")
1438
- .split(";")
1439
- .map((entry) => entry.trim().toLowerCase())
1440
- .filter(Boolean);
1441
- const candidateNames = extname(normalizedCommandPath)
1442
- ? [normalizedCommandPath]
1443
- : pathextEntries.map((entry) => `${normalizedCommandPath}${entry.toLowerCase()}`);
1444
- for (const entry of pathEntries) {
1445
- for (const candidateName of candidateNames) {
1446
- if (existsSync(join(entry, candidateName))) {
1447
- return true;
1448
- }
1449
- }
1450
- }
1451
- return false;
1452
- }
1453
- for (const entry of pathEntries) {
1454
- const candidatePath = join(entry, normalizedCommandPath);
1455
- if (!existsSync(candidatePath)) {
1456
- continue;
1457
- }
1458
- try {
1459
- accessSync(candidatePath, constants.X_OK);
1460
- return true;
1461
- }
1462
- catch {
1463
- continue;
1464
- }
1465
- }
1466
- return false;
1467
- }
1468
- function stripWrappingQuotes(value) {
1469
- const trimmed = value.trim();
1470
- if ((trimmed.startsWith("\"") && trimmed.endsWith("\""))
1471
- || (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
1472
- return trimmed.slice(1, -1).trim();
1473
- }
1474
- return trimmed;
1475
- }
1476
- function wrapGeminiSchemaError(filePath, error) {
1477
- const detail = error instanceof Error ? error.message : ensureText(error);
1478
- return new Error(`GEMINI_CHAT_SCHEMA_INVALID: file=${filePath.replaceAll("\\", "/")} detail=${detail}`);
1479
- }
1480
- //# sourceMappingURL=gemini.js.map