coding-tool-x 3.8.4 → 3.8.5

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 (434) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +86 -15
  3. package/dist/web/assets/AgentsDrawer-BG6P3DX-.js +1 -0
  4. package/dist/web/assets/AgentsDrawer-Pw2k-ZAa.css +1 -0
  5. package/dist/web/assets/Analytics--z_FmL5P.js +1 -0
  6. package/dist/web/assets/Analytics-CyHhR126.css +1 -0
  7. package/dist/web/assets/AssetPathField-CrJtRKHy.js +1 -0
  8. package/dist/web/assets/ChatHistoryDrawer-B2qBQs9L.css +1 -0
  9. package/dist/web/assets/ChatHistoryDrawer-BiuEryJj.js +1 -0
  10. package/dist/web/assets/CollapseItem-BAYEsL_Q.js +1 -0
  11. package/dist/web/assets/CommandsDrawer-BZJxlPvV.css +1 -0
  12. package/dist/web/assets/CommandsDrawer-YJ-U7BXN.js +1 -0
  13. package/dist/web/assets/ConfigExportDrawer-Ce_hAknW.js +1 -0
  14. package/dist/web/assets/ConfigExportDrawer-dwruRKWr.css +1 -0
  15. package/dist/web/assets/ConfigTemplates-Bvr1NN6K.js +1 -0
  16. package/dist/web/assets/ConfigTemplatesDrawer-BfDi8yO3.css +1 -0
  17. package/dist/web/assets/ConfigTemplatesDrawer-BjIeHfF-.js +1 -0
  18. package/dist/web/assets/ConfigTemplatesPanel-AV00tm_D.js +1 -0
  19. package/dist/web/assets/ConfigTemplatesPanel-CWyPtk67.css +1 -0
  20. package/dist/web/assets/Divider-D28g1gwj.js +1 -0
  21. package/dist/web/assets/DrawerContent-ChXgZ1Xm.js +1 -0
  22. package/dist/web/assets/FavoritesDrawer-CG9eI9Ay.css +1 -0
  23. package/dist/web/assets/FavoritesDrawer-Cz95o4CD.js +1 -0
  24. package/dist/web/assets/GatewayConvertDrawer-CuNlf7AC.css +1 -0
  25. package/dist/web/assets/GatewayConvertDrawer-DLlbMz27.js +1 -0
  26. package/dist/web/assets/Home-CSuFuJ9Y.css +1 -0
  27. package/dist/web/assets/Home-D7CCOFQC.js +1 -0
  28. package/dist/web/assets/MarkdownEditor-qfVgSre_.css +1 -0
  29. package/dist/web/assets/MarkdownEditor-rEZ-c72L.js +1 -0
  30. package/dist/web/assets/McpDrawer-C0dnsZhQ.css +1 -0
  31. package/dist/web/assets/McpDrawer-DfoCyxU2.js +1 -0
  32. package/dist/web/assets/McpFormDrawer-BRbDcawn.css +1 -0
  33. package/dist/web/assets/McpFormDrawer-SKu8HNUR.js +1 -0
  34. package/dist/web/assets/PluginManager-BbeK-3rV.js +1 -0
  35. package/dist/web/assets/PluginsDrawer-CWVJ7yjS.js +1 -0
  36. package/dist/web/assets/PluginsDrawer-DM3QjprE.css +1 -0
  37. package/dist/web/assets/PluginsPanel-Cm2N3StG.js +1 -0
  38. package/dist/web/assets/PluginsPanel-D6ZqITcR.css +1 -0
  39. package/dist/web/assets/ProjectList-677RLZ8O.css +1 -0
  40. package/dist/web/assets/ProjectList-CsjnsNPv.js +1 -0
  41. package/dist/web/assets/PromptsDrawer-BIgiYCEQ.css +1 -0
  42. package/dist/web/assets/PromptsDrawer-EGd3djFa.js +1 -0
  43. package/dist/web/assets/RecentSessionsDrawer-CKFsOYDM.css +1 -0
  44. package/dist/web/assets/RecentSessionsDrawer-D1vtoLAs.js +1 -0
  45. package/dist/web/assets/SessionCard-BgLg49U3.js +1 -0
  46. package/dist/web/assets/SessionCard-aM2NHu6i.css +1 -0
  47. package/dist/web/assets/SessionList-BpYRz1cX.css +1 -0
  48. package/dist/web/assets/SessionList-TRiTklWk.js +1 -0
  49. package/dist/web/assets/SettingsDrawer-d5liXjHq.css +1 -0
  50. package/dist/web/assets/SettingsDrawer-rz2WejGY.js +1 -0
  51. package/dist/web/assets/SkillManager-BTjTUbHq.js +1 -0
  52. package/dist/web/assets/SkillManager-C0GCT2Kb.css +1 -0
  53. package/dist/web/assets/SkillsDrawer-BCNme-aJ.css +1 -0
  54. package/dist/web/assets/SkillsDrawer-pN0hbkK3.js +1 -0
  55. package/dist/web/assets/SkillsPanel-B3Nm5j32.css +1 -0
  56. package/dist/web/assets/SkillsPanel-gmBWEoiF.js +1 -0
  57. package/dist/web/assets/SpeedTestDrawer-Dc0WToJ_.css +1 -0
  58. package/dist/web/assets/SpeedTestDrawer-DcNzuVJk.js +1 -0
  59. package/dist/web/assets/Upload-v5rV0qTT.js +1 -0
  60. package/dist/web/assets/WorkspaceDrawer-CGnMu9p1.css +1 -0
  61. package/dist/web/assets/WorkspaceDrawer-DxmicM4U.js +1 -0
  62. package/dist/web/assets/WorkspaceManager-CJHCjARN.js +1 -0
  63. package/dist/web/assets/WorkspacePanel-D0-zHTHP.css +1 -0
  64. package/dist/web/assets/WorkspacePanel-D8_Zq-du.js +1 -0
  65. package/dist/web/assets/_plugin-vue_export-helper-BeLZJZij.js +1 -0
  66. package/dist/web/assets/client-UDwXBP9i.js +1 -0
  67. package/dist/web/assets/clipboard-B46yyoz_.js +1 -0
  68. package/dist/web/assets/headers-cf-QapUq.js +1 -0
  69. package/dist/web/assets/icons-B2Vg-IOC.js +1 -0
  70. package/dist/web/assets/index-C0EHRym0.css +1 -0
  71. package/dist/web/assets/index-DnEocV0M.js +2 -0
  72. package/dist/web/assets/light-Cp0t7v32.js +1 -0
  73. package/dist/web/assets/markdown-u082bbtj.js +1 -0
  74. package/dist/web/assets/platforms-CBkB45JP.js +1 -0
  75. package/dist/web/assets/platforms-FTpjxAT6.js +1 -0
  76. package/dist/web/assets/project-config-B2baPzYL.js +1 -0
  77. package/dist/web/assets/sessions-Cmy31slD.js +1 -0
  78. package/dist/web/assets/sessions-yC_oVVh8.js +1 -0
  79. package/dist/web/assets/skill-repo-input-B_fkGlUK.js +1 -0
  80. package/dist/web/assets/use-lock-html-scroll-DXIqmUW4.js +1 -0
  81. package/dist/web/assets/use-message-DoLM8C1C.js +1 -0
  82. package/dist/web/assets/useResponsiveDrawer-B3uojyvV.js +1 -0
  83. package/dist/web/assets/vendors-D0c_0KLP.js +1 -0
  84. package/dist/web/assets/vue-vendor-BqZbbXHA.js +1 -0
  85. package/dist/web/assets/workspaces-mjyPVGS8.js +1 -0
  86. package/dist/web/assets/xml-CgY3RMlX.js +1 -0
  87. package/dist/web/index.html +12 -8
  88. package/docs/native-log-memory-2026-09-16.md +43 -0
  89. package/docs/superpowers/plans/2026-08-26-configuration-driven-cli-platform.md +1578 -0
  90. package/docs/superpowers/plans/2026-08-30-project-scoped-config-control.md +1260 -0
  91. package/docs/superpowers/plans/2026-09-01-omp-skill-refresh-boundary.md +213 -0
  92. package/docs/superpowers/plans/2026-09-01-realtime-logs-panel.md +125 -0
  93. package/docs/superpowers/plans/2026-09-02-config-driven-platform-boundary.md +86 -0
  94. package/docs/superpowers/plans/2026-09-02-platform-implementation-drivers.md +508 -0
  95. package/docs/superpowers/plans/2026-09-03-cli-platform-correctness-boundary.md +760 -0
  96. package/docs/superpowers/plans/2026-09-03-dependency-security-remediation.md +133 -0
  97. package/docs/superpowers/plans/2026-09-04-model-catalog-pricing-sync.md +1078 -0
  98. package/docs/superpowers/plans/2026-09-05-codex-project-scan-500.md +128 -0
  99. package/docs/superpowers/plans/2026-09-06-project-skill-path-fix.md +97 -0
  100. package/docs/superpowers/specs/2026-08-26-configuration-driven-cli-platform-design.md +408 -0
  101. package/docs/superpowers/specs/2026-08-30-project-scoped-config-control-design.md +467 -0
  102. package/docs/superpowers/specs/2026-09-01-claude-session-content-repair-design.md +111 -0
  103. package/docs/superpowers/specs/2026-09-01-omp-skill-refresh-boundary-design.md +83 -0
  104. package/docs/superpowers/specs/2026-09-01-realtime-logs-panel-design.md +27 -0
  105. package/docs/superpowers/specs/2026-09-02-config-driven-platform-boundary-design.md +64 -0
  106. package/docs/superpowers/specs/2026-09-02-platform-implementation-driver-boundary-design.md +123 -0
  107. package/docs/superpowers/specs/2026-09-03-cli-platform-correctness-boundary-design.md +249 -0
  108. package/docs/superpowers/specs/2026-09-03-dependency-security-remediation-design.md +87 -0
  109. package/docs/superpowers/specs/2026-09-04-model-catalog-pricing-sync-design.md +301 -0
  110. package/docs/superpowers/specs/2026-09-05-codex-project-scan-500-design.md +24 -0
  111. package/package.json +8 -4
  112. package/src/commands/channels.js +88 -191
  113. package/src/commands/cli-type.js +19 -11
  114. package/src/commands/daemon.js +94 -32
  115. package/src/commands/doctor.js +16 -9
  116. package/src/commands/export-config.js +23 -5
  117. package/src/commands/list.js +130 -52
  118. package/src/commands/logs.js +44 -27
  119. package/src/commands/platform-command-registry.js +78 -0
  120. package/src/commands/plugin.js +11 -5
  121. package/src/commands/port-config.js +34 -52
  122. package/src/commands/proxy-control.js +207 -145
  123. package/src/commands/proxy.js +2 -2
  124. package/src/commands/resume.js +87 -91
  125. package/src/commands/search.js +137 -67
  126. package/src/commands/stats.js +30 -22
  127. package/src/commands/switch.js +1 -1
  128. package/src/commands/toggle-proxy.js +94 -111
  129. package/src/commands/ui.js +67 -6
  130. package/src/commands/workspace.js +90 -8
  131. package/src/config/default.js +6 -53
  132. package/src/config/loader.js +61 -24
  133. package/src/config/model-metadata.js +49 -59
  134. package/src/config/model-metadata.json +4095 -99
  135. package/src/config/paths.js +181 -8
  136. package/src/index.js +134 -71
  137. package/src/platforms/access.js +196 -0
  138. package/src/{server/services → platforms}/agents-service.js +354 -197
  139. package/src/platforms/channel-auth-registry.js +162 -0
  140. package/src/platforms/channel-auth-service.js +82 -0
  141. package/src/{server/services → platforms}/commands-service.js +195 -115
  142. package/src/platforms/driver-registry.js +59 -0
  143. package/src/platforms/drivers/claude/api-operations.js +62 -0
  144. package/src/{server/services/channels.js → platforms/drivers/claude/channels-implementation.js} +131 -33
  145. package/src/platforms/drivers/claude/channels.js +39 -0
  146. package/src/{server/services/config-sync-service.js → platforms/drivers/claude/config-sync.js} +29 -5
  147. package/src/{server/services → platforms/drivers/claude}/health-check.js +4 -4
  148. package/src/platforms/drivers/claude/health.js +22 -0
  149. package/src/platforms/drivers/claude/mcp.js +9 -0
  150. package/src/{server/services/settings-manager.js → platforms/drivers/claude/native-config-implementation.js} +13 -4
  151. package/src/platforms/drivers/claude/native-config.js +46 -0
  152. package/src/platforms/drivers/claude/native-logs.js +72 -0
  153. package/src/{server/services/claude-openai-gateway.js → platforms/drivers/claude/openai-gateway.js} +8 -65
  154. package/src/platforms/drivers/claude/project-config.js +21 -0
  155. package/src/platforms/drivers/claude/projects.js +62 -0
  156. package/src/platforms/drivers/claude/prompts.js +9 -0
  157. package/src/{server/proxy-server.js → platforms/drivers/claude/proxy-implementation.js} +41 -278
  158. package/src/platforms/drivers/claude/proxy.js +16 -0
  159. package/src/platforms/drivers/claude/resource-sync.js +9 -0
  160. package/src/platforms/drivers/claude/session-history-adapter.js +313 -0
  161. package/src/{server/services/sessions.js → platforms/drivers/claude/sessions-implementation.js} +145 -35
  162. package/src/platforms/drivers/claude/sessions.js +76 -0
  163. package/src/{server/services/claude-statistics-service.js → platforms/drivers/claude/statistics-implementation.js} +2 -2
  164. package/src/platforms/drivers/claude/statistics.js +16 -0
  165. package/src/{server/services/claude-wire.js → platforms/drivers/claude/wire.js} +1 -1
  166. package/src/platforms/drivers/codex/api-operations.js +9 -0
  167. package/src/{server/services/codex-channels.js → platforms/drivers/codex/channels-implementation.js} +149 -14
  168. package/src/platforms/drivers/codex/channels.js +45 -0
  169. package/src/{server/services/codex-config.js → platforms/drivers/codex/config.js} +12 -2
  170. package/src/{server/services/codex-env-manager.js → platforms/drivers/codex/env-manager.js} +1 -1
  171. package/src/platforms/drivers/codex/mcp.js +9 -0
  172. package/src/{server/services/codex-settings-manager.js → platforms/drivers/codex/native-config-implementation.js} +15 -6
  173. package/src/platforms/drivers/codex/native-config.js +47 -0
  174. package/src/platforms/drivers/codex/native-logs.js +166 -0
  175. package/src/platforms/drivers/codex/project-config.js +21 -0
  176. package/src/platforms/drivers/codex/projects.js +26 -0
  177. package/src/platforms/drivers/codex/prompts.js +9 -0
  178. package/src/{server/codex-proxy-server.js → platforms/drivers/codex/proxy-implementation.js} +30 -233
  179. package/src/platforms/drivers/codex/proxy.js +16 -0
  180. package/src/platforms/drivers/codex/resource-sync.js +9 -0
  181. package/src/{server/services/session-history-adapters/codex.js → platforms/drivers/codex/session-history-adapter.js} +37 -23
  182. package/src/{server/services/codex-sessions.js → platforms/drivers/codex/sessions-implementation.js} +81 -75
  183. package/src/platforms/drivers/codex/sessions.js +36 -0
  184. package/src/{server/services/codex-statistics-service.js → platforms/drivers/codex/statistics-implementation.js} +2 -2
  185. package/src/platforms/drivers/codex/statistics.js +16 -0
  186. package/src/platforms/drivers/gemini/api-operations.js +9 -0
  187. package/src/{server/services/gemini-channels.js → platforms/drivers/gemini/channels-implementation.js} +202 -37
  188. package/src/platforms/drivers/gemini/channels.js +39 -0
  189. package/src/{server/services/gemini-config.js → platforms/drivers/gemini/config.js} +12 -2
  190. package/src/platforms/drivers/gemini/mcp.js +9 -0
  191. package/src/{server/services/gemini-settings-manager.js → platforms/drivers/gemini/native-config-implementation.js} +14 -5
  192. package/src/platforms/drivers/gemini/native-config.js +39 -0
  193. package/src/platforms/drivers/gemini/native-logs.js +180 -0
  194. package/src/platforms/drivers/gemini/project-config.js +21 -0
  195. package/src/platforms/drivers/gemini/projects.js +26 -0
  196. package/src/platforms/drivers/gemini/prompts.js +9 -0
  197. package/src/{server/gemini-proxy-server.js → platforms/drivers/gemini/proxy-implementation.js} +36 -267
  198. package/src/platforms/drivers/gemini/proxy.js +16 -0
  199. package/src/platforms/drivers/gemini/resource-sync.js +9 -0
  200. package/src/{server/services/session-history-adapters/gemini.js → platforms/drivers/gemini/session-history-adapter.js} +70 -18
  201. package/src/{server/services/gemini-sessions.js → platforms/drivers/gemini/sessions-implementation.js} +53 -37
  202. package/src/platforms/drivers/gemini/sessions.js +47 -0
  203. package/src/{server/services/gemini-statistics-service.js → platforms/drivers/gemini/statistics-implementation.js} +2 -2
  204. package/src/platforms/drivers/gemini/statistics.js +16 -0
  205. package/src/{server/services/gemini-wire.js → platforms/drivers/gemini/wire.js} +1 -1
  206. package/src/platforms/drivers/generic-filesystem.js +166 -0
  207. package/src/platforms/drivers/generic-jsonl.js +141 -0
  208. package/src/platforms/drivers/generic-mcp.js +44 -0
  209. package/src/platforms/drivers/generic-openai-compatible.js +45 -0
  210. package/src/platforms/drivers/generic-prompt.js +41 -0
  211. package/src/platforms/drivers/legacy.js +677 -0
  212. package/src/platforms/drivers/native-config-snapshot.js +125 -0
  213. package/src/platforms/drivers/native-log-utils.js +1292 -0
  214. package/src/platforms/drivers/notification-hooks.js +578 -0
  215. package/src/{server/api/omp-config.js → platforms/drivers/omp/api-operations.js} +52 -64
  216. package/src/{server/services/omp-auth-provider-worker.js → platforms/drivers/omp/auth-provider-worker.js} +1 -1
  217. package/src/{server/services/omp-auth-providers.js → platforms/drivers/omp/auth-providers.js} +1 -1
  218. package/src/{server/services/omp-channels.js → platforms/drivers/omp/channels-implementation.js} +166 -39
  219. package/src/platforms/drivers/omp/channels.js +58 -0
  220. package/src/{server/services/omp-config.js → platforms/drivers/omp/config.js} +53 -13
  221. package/src/{server/services/omp-gateway-routing.js → platforms/drivers/omp/gateway-routing.js} +14 -7
  222. package/src/{server/services/omp-gateway.js → platforms/drivers/omp/gateway.js} +4 -262
  223. package/src/platforms/drivers/omp/mcp.js +9 -0
  224. package/src/{server/services/omp-settings-manager.js → platforms/drivers/omp/native-config-implementation.js} +75 -10
  225. package/src/platforms/drivers/omp/native-config.js +46 -0
  226. package/src/platforms/drivers/omp/native-logs.js +52 -0
  227. package/src/{server/services/omp-native-plugin-adapter.js → platforms/drivers/omp/native-plugin-adapter.js} +91 -4
  228. package/src/platforms/drivers/omp/project-config.js +29 -0
  229. package/src/platforms/drivers/omp/projects.js +20 -0
  230. package/src/platforms/drivers/omp/prompts.js +9 -0
  231. package/src/{server/omp-proxy-server.js → platforms/drivers/omp/proxy-implementation.js} +6 -15
  232. package/src/platforms/drivers/omp/proxy.js +16 -0
  233. package/src/platforms/drivers/omp/resource-sync.js +9 -0
  234. package/src/{server/services/session-history-adapters/omp.js → platforms/drivers/omp/session-history-adapter.js} +42 -18
  235. package/src/{server/services/omp-sessions.js → platforms/drivers/omp/sessions-implementation.js} +130 -94
  236. package/src/platforms/drivers/omp/sessions.js +36 -0
  237. package/src/{server/services/omp-skill-discovery.js → platforms/drivers/omp/skill-discovery.js} +159 -32
  238. package/src/{server/services/omp-skill-settings-service.js → platforms/drivers/omp/skill-settings.js} +1 -1
  239. package/src/{server/services/omp-statistics-service.js → platforms/drivers/omp/statistics-implementation.js} +3 -3
  240. package/src/platforms/drivers/omp/statistics.js +16 -0
  241. package/src/platforms/drivers/opencode/api-operations.js +9 -0
  242. package/src/{server/services/opencode-channels.js → platforms/drivers/opencode/channels-implementation.js} +28 -9
  243. package/src/platforms/drivers/opencode/channels.js +40 -0
  244. package/src/platforms/drivers/opencode/conversion.js +41 -0
  245. package/src/{server/services/opencode-gateway-converter.js → platforms/drivers/opencode/gateway-converter.js} +1 -1
  246. package/src/platforms/drivers/opencode/mcp.js +9 -0
  247. package/src/{server/services/opencode-settings-manager.js → platforms/drivers/opencode/native-config-implementation.js} +17 -6
  248. package/src/platforms/drivers/opencode/native-config.js +26 -0
  249. package/src/platforms/drivers/opencode/native-logs.js +133 -0
  250. package/src/platforms/drivers/opencode/project-config.js +98 -0
  251. package/src/platforms/drivers/opencode/projects.js +20 -0
  252. package/src/platforms/drivers/opencode/prompts.js +9 -0
  253. package/src/{server/opencode-proxy-server.js → platforms/drivers/opencode/proxy-implementation.js} +27 -362
  254. package/src/platforms/drivers/opencode/proxy.js +16 -0
  255. package/src/platforms/drivers/opencode/resource-sync.js +9 -0
  256. package/src/{server/services/opencode-sessions.js → platforms/drivers/opencode/sessions-implementation.js} +211 -64
  257. package/src/platforms/drivers/opencode/sessions.js +48 -0
  258. package/src/{server/services/opencode-statistics-service.js → platforms/drivers/opencode/statistics-implementation.js} +2 -2
  259. package/src/platforms/drivers/opencode/statistics.js +16 -0
  260. package/src/platforms/drivers/secure-file-driver.js +272 -0
  261. package/src/platforms/drivers/unsupported.js +7 -0
  262. package/src/platforms/manifest-schema.js +398 -0
  263. package/src/platforms/manifests/claude.json +489 -0
  264. package/src/platforms/manifests/codex.json +448 -0
  265. package/src/platforms/manifests/gemini.json +447 -0
  266. package/src/platforms/manifests/omp.json +496 -0
  267. package/src/platforms/manifests/opencode.json +422 -0
  268. package/src/{server/services → platforms}/native-oauth-adapters.js +87 -417
  269. package/src/{server/services → platforms}/notification-hooks.js +140 -1023
  270. package/src/platforms/oauth-credentials-service.js +506 -0
  271. package/src/platforms/path-resolver.js +179 -0
  272. package/src/platforms/platform-path-context.js +305 -0
  273. package/src/platforms/registry.js +248 -0
  274. package/src/platforms/remote-notification-providers.js +678 -0
  275. package/src/platforms/runtime.js +259 -0
  276. package/src/{server/services/session-history-adapters/index.js → platforms/session-history-adapters.js} +8 -1
  277. package/src/plugins/plugin-loader.js +2 -2
  278. package/src/plugins/plugin-manager.js +2 -2
  279. package/src/plugins/registry.js +27 -10
  280. package/src/reset-config.js +21 -5
  281. package/src/server/api/agents.js +46 -72
  282. package/src/server/api/commands.js +16 -6
  283. package/src/server/api/config-registry.js +206 -59
  284. package/src/server/api/config-sync.js +3 -2
  285. package/src/server/api/config-templates.js +20 -4
  286. package/src/server/api/config.js +111 -102
  287. package/src/server/api/convert.js +54 -178
  288. package/src/server/api/dashboard.js +168 -102
  289. package/src/server/api/hooks.js +1 -1
  290. package/src/server/api/mcp.js +224 -84
  291. package/src/server/api/platform-api-config.js +102 -0
  292. package/src/server/api/platform-route-factory.js +215 -0
  293. package/src/server/api/platform-routes.js +26 -0
  294. package/src/server/api/platforms.js +110 -0
  295. package/src/server/api/plugins.js +57 -57
  296. package/src/server/api/project-config.js +168 -0
  297. package/src/server/api/prompts.js +58 -45
  298. package/src/server/api/settings.js +55 -8
  299. package/src/server/api/skills.js +262 -133
  300. package/src/server/api/ui-config.js +2 -2
  301. package/src/server/api/validation-errors.js +18 -4
  302. package/src/server/api/workspaces.js +47 -12
  303. package/src/server/index.js +164 -213
  304. package/src/server/platform-context.js +81 -0
  305. package/src/server/services/channel-balance.js +11 -20
  306. package/src/server/services/channel-health.js +21 -6
  307. package/src/server/services/channel-scheduler.js +29 -39
  308. package/src/server/services/channel-sync-utils.js +23 -13
  309. package/src/server/services/config-export-service.js +350 -319
  310. package/src/server/services/config-registry-service.js +280 -54
  311. package/src/server/services/config-sync-manager.js +172 -944
  312. package/src/server/services/config-templates-service.js +419 -353
  313. package/src/server/services/control-manifest-store.js +206 -0
  314. package/src/server/services/dashboard-snapshot-worker.js +656 -100
  315. package/src/server/services/effective-control-service.js +557 -0
  316. package/src/server/services/local-resource-index.js +314 -0
  317. package/src/server/services/mcp-service.js +607 -977
  318. package/src/server/services/model-detector.js +15 -10
  319. package/src/server/services/native-log-channel-resolver.js +214 -0
  320. package/src/server/services/native-log-observer.js +291 -0
  321. package/src/server/services/network-access.js +1 -1
  322. package/src/server/services/platform-catalog.js +82 -0
  323. package/src/server/services/platform-resolution.js +32 -29
  324. package/src/server/services/plugins-service.js +376 -122
  325. package/src/server/services/project-config-service.js +550 -0
  326. package/src/server/services/project-path-validation.js +31 -0
  327. package/src/server/services/prompts-service.js +267 -233
  328. package/src/server/services/proxy-runtime.js +7 -4
  329. package/src/server/services/remote-credential-cache.js +43 -0
  330. package/src/server/services/repo-scanner-base.js +182 -75
  331. package/src/server/services/request-logger.js +7 -4
  332. package/src/server/services/session-history-index.js +780 -213
  333. package/src/server/services/session-history-worker.js +228 -33
  334. package/src/server/services/session-snapshot-worker.js +124 -34
  335. package/src/server/services/session-snapshots.js +4 -2
  336. package/src/server/services/skill-artifact-store.js +355 -0
  337. package/src/server/services/skill-format-adapters.js +65 -0
  338. package/src/server/services/skill-projection-service.js +323 -0
  339. package/src/server/services/skill-refresh-task-service.js +275 -0
  340. package/src/server/services/skill-service.js +2020 -677
  341. package/src/server/services/snapshot-cache.js +30 -8
  342. package/src/server/services/speed-test.js +8 -8
  343. package/src/server/services/sqlite-connection.js +19 -3
  344. package/src/server/services/statistics-service.js +240 -57
  345. package/src/server/services/ui-config.js +107 -76
  346. package/src/server/services/usage-log-utils.js +98 -0
  347. package/src/server/services/web-build.js +1 -1
  348. package/src/server/services/workspace-service.js +59 -29
  349. package/src/server/utils/pricing.js +10 -19
  350. package/src/server/websocket-server.js +153 -28
  351. package/src/{server/services/base → shared}/base-channel-service.js +156 -28
  352. package/src/shared/capability-driver.js +104 -0
  353. package/src/shared/channel-auth-policy.js +27 -0
  354. package/src/shared/channel-driver.js +161 -0
  355. package/src/shared/driver-factories/api.js +180 -0
  356. package/src/shared/driver-factories/mcp.js +244 -0
  357. package/src/shared/driver-factories/projects.js +121 -0
  358. package/src/shared/driver-factories/prompts.js +58 -0
  359. package/src/shared/driver-factories/resource-sync.js +375 -0
  360. package/src/shared/driver-result.js +78 -0
  361. package/src/shared/mcp-format.js +189 -0
  362. package/src/shared/platforms.js +104 -167
  363. package/src/shared/project-config.js +512 -0
  364. package/src/shared/proxy-driver.js +57 -0
  365. package/src/{server/services/base → shared}/response-usage-parser.js +8 -4
  366. package/src/ui/menu.js +91 -67
  367. package/src/utils/port-helper.js +35 -19
  368. package/src/utils/session.js +1 -1
  369. package/dist/web/assets/Analytics-COEUXmd4.js +0 -25
  370. package/dist/web/assets/Analytics-RNn1BUbG.css +0 -1
  371. package/dist/web/assets/ConfigTemplates-DLLkS53H.js +0 -1
  372. package/dist/web/assets/Home-DCEyLzwX.js +0 -1
  373. package/dist/web/assets/Home-DYVy4cGZ.css +0 -1
  374. package/dist/web/assets/PluginManager-Oe1ZHoMO.js +0 -1
  375. package/dist/web/assets/ProjectList-CWjuAFof.js +0 -1
  376. package/dist/web/assets/ProjectList-VeMNXfgO.css +0 -1
  377. package/dist/web/assets/SessionList-C4chCPxK.css +0 -1
  378. package/dist/web/assets/SessionList-v3ehGg9U.js +0 -1
  379. package/dist/web/assets/SkillManager-BsX8Qpj0.css +0 -1
  380. package/dist/web/assets/SkillManager-DUF_qP5S.js +0 -1
  381. package/dist/web/assets/WorkspaceManager-CjAWBosO.js +0 -1
  382. package/dist/web/assets/icons-nGdSKQn2.js +0 -1
  383. package/dist/web/assets/index-D5hyHPj7.js +0 -2
  384. package/dist/web/assets/index-bJRG3RXH.css +0 -1
  385. package/dist/web/assets/markdown-BNJfEgCA.js +0 -1
  386. package/dist/web/assets/markdown-BfC0goYb.css +0 -10
  387. package/dist/web/assets/naive-ui-BALVpMgd.js +0 -1
  388. package/dist/web/assets/vendors-DQA4Hw9v.js +0 -7
  389. package/dist/web/assets/vue-vendor-B5RqjEjQ.js +0 -45
  390. package/src/config/model-pricing.js +0 -35
  391. package/src/server/api/channels.js +0 -439
  392. package/src/server/api/claude-hooks.js +0 -56
  393. package/src/server/api/claude-statistics.js +0 -57
  394. package/src/server/api/codex-channels.js +0 -491
  395. package/src/server/api/codex-projects.js +0 -117
  396. package/src/server/api/codex-proxy.js +0 -293
  397. package/src/server/api/codex-sessions.js +0 -652
  398. package/src/server/api/codex-statistics.js +0 -57
  399. package/src/server/api/gemini-channels.js +0 -392
  400. package/src/server/api/gemini-projects.js +0 -103
  401. package/src/server/api/gemini-proxy.js +0 -231
  402. package/src/server/api/gemini-sessions.js +0 -550
  403. package/src/server/api/gemini-statistics.js +0 -57
  404. package/src/server/api/health-check.js +0 -31
  405. package/src/server/api/oauth-credentials.js +0 -198
  406. package/src/server/api/omp-channels.js +0 -575
  407. package/src/server/api/omp-projects.js +0 -88
  408. package/src/server/api/omp-proxy.js +0 -125
  409. package/src/server/api/omp-sessions.js +0 -386
  410. package/src/server/api/omp-statistics.js +0 -40
  411. package/src/server/api/opencode-channels.js +0 -471
  412. package/src/server/api/opencode-projects.js +0 -110
  413. package/src/server/api/opencode-proxy.js +0 -354
  414. package/src/server/api/opencode-sessions.js +0 -466
  415. package/src/server/api/opencode-statistics.js +0 -57
  416. package/src/server/api/projects.js +0 -120
  417. package/src/server/api/proxy.js +0 -330
  418. package/src/server/api/sessions.js +0 -810
  419. package/src/server/services/oauth-credentials-service.js +0 -945
  420. package/src/server/services/omp-session-log-observer.js +0 -138
  421. package/src/server/services/opencode-gateway-adapters.js +0 -43
  422. package/src/server/services/project-snapshots.js +0 -59
  423. package/src/server/services/proxy-log-helper.js +0 -298
  424. package/src/server/services/session-cache.js +0 -127
  425. package/src/server/services/session-converter.js +0 -582
  426. package/src/server/services/session-history-adapters/claude.js +0 -235
  427. /package/src/{server/services/claude-token-recovery.js → platforms/drivers/claude/token-recovery.js} +0 -0
  428. /package/src/{server/services/codex-parser.js → platforms/drivers/codex/parser.js} +0 -0
  429. /package/src/{server/services/codex-speed-test-template.json → platforms/drivers/codex/speed-test-template.json} +0 -0
  430. /package/src/{server/services/codex-wire.js → platforms/drivers/codex/wire.js} +0 -0
  431. /package/src/{server/services/omp-auth-gateway-client.js → platforms/drivers/omp/auth-gateway-client.js} +0 -0
  432. /package/src/{server/services/opencode-normalization.js → platforms/drivers/opencode/normalization.js} +0 -0
  433. /package/src/{server/services → shared}/config-artifact-paths.js +0 -0
  434. /package/src/{server/services/base → shared}/proxy-utils.js +0 -0
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const { createNativeSnapshotMethods } = require('../native-config-snapshot');
5
+ const implementation = require('./channels-implementation');
6
+
7
+ function createDriver({ requireImpl, ...context } = {}) {
8
+ const configuredPaths = context.pathContext?.native;
9
+ const currentNativePaths = context.pathContext?.customized && configuredPaths?.settings
10
+ ? configuredPaths
11
+ : require('../../../config/paths').NATIVE_PATHS.omp;
12
+ const managed = requireImpl
13
+ ? requireImpl('./omp/channels-implementation')
14
+ : implementation;
15
+ managed.configure?.({ pathContext: context.pathContext });
16
+ const ompDir = currentNativePaths.dir || path.dirname(currentNativePaths.settings);
17
+ const snapshotMethods = createNativeSnapshotMethods({
18
+ settings: { path: currentNativePaths.settings, format: 'yaml' },
19
+ auth: { path: currentNativePaths.auth, format: 'json', mode: 0o600 },
20
+ models: { path: currentNativePaths.models, format: 'yaml' },
21
+ commands: { path: currentNativePaths.commands || path.join(ompDir, 'commands'), format: 'directory' },
22
+ prompts: { path: currentNativePaths.prompts, format: 'directory' },
23
+ skills: { path: currentNativePaths.skills, format: 'directory' },
24
+ extensions: { path: currentNativePaths.extensions, format: 'directory' },
25
+ themes: { path: currentNativePaths.themes || path.join(ompDir, 'themes'), format: 'directory' },
26
+ packages: { path: currentNativePaths.packages || path.join(ompDir, 'packages'), format: 'directory' },
27
+ npmPackages: { path: path.join(ompDir, 'npm'), format: 'directory' },
28
+ gitPackages: { path: path.join(ompDir, 'git'), format: 'directory' }
29
+ }, { platform: 'omp', runtime: context.runtime });
30
+ return {
31
+ platform: 'omp',
32
+ capability: 'nativeConfig',
33
+ ...context,
34
+ ...snapshotMethods,
35
+ syncManagedProviders: (...args) => managed.syncManagedOmpProviders(...args),
36
+ disableManagedProviders: (...args) => managed.disableManagedOmpProviders(...args),
37
+ isManagedModeEnabled: (...args) => managed.isManagedOmpModeEnabled(...args),
38
+ clearNativeOAuth: () => {
39
+ const adapters = require('../../native-oauth-adapters');
40
+ adapters.configure?.(context);
41
+ return adapters.clearNativeOAuth('omp');
42
+ }
43
+ };
44
+ }
45
+
46
+ module.exports = { createDriver };
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ const { createOmpUsageEventCursor, getOmpSessionPaths } = require('./sessions-implementation');
4
+ const { getEnabledChannels } = require('./channels-implementation');
5
+ const { getManagedProviderId, normalizeProviderId } = require('./native-config-implementation');
6
+ const { normalizeCost, normalizeUsage } = require('../native-log-utils');
7
+ const { calculateUsageCost } = require('../../../server/services/usage-log-utils');
8
+
9
+ function resolveChannel(provider) {
10
+ const normalized = normalizeProviderId(provider || '');
11
+ const channel = getEnabledChannels().find(item => [
12
+ getManagedProviderId(item), item.providerKey, item.provider, item.name, item.id
13
+ ].map(normalizeProviderId).includes(normalized));
14
+ return channel ? { channelId: channel.id, channel: channel.name } : {};
15
+ }
16
+
17
+ function createDriver({ pathContext } = {}) {
18
+ if (pathContext?.customized) {
19
+ require('./sessions-implementation').configure?.({ pathContext });
20
+ require('./channels-implementation').configure?.({ pathContext });
21
+ }
22
+ return {
23
+ platform: 'omp',
24
+ capability: 'nativeLogs',
25
+ createNativeLogCursor({ skipInitialParse = false, onDiagnostic } = {}) {
26
+ const native = createOmpUsageEventCursor(getOmpSessionPaths().sessions, { skipInitialParse, onDiagnostic });
27
+ return {
28
+ initialize() { native.read(); },
29
+ readNewEvents() {
30
+ return native.read().map(event => ({
31
+ id: event.id,
32
+ source: 'omp',
33
+ sessionId: event.sessionId,
34
+ timestamp: event.timestamp,
35
+ provider: event.provider,
36
+ model: event.model,
37
+ tokens: normalizeUsage(event.usage),
38
+ cost: normalizeCost(event.usage?.cost)
39
+ || calculateUsageCost('omp', event.model || '', normalizeUsage(event.usage)),
40
+ ...resolveChannel(event.provider)
41
+ }));
42
+ },
43
+ read() { return this.readNewEvents(); },
44
+ reset() { native.reset(); },
45
+ close() { native.reset(); }
46
+ };
47
+ },
48
+ createCursor(options) { return this.createNativeLogCursor(options); }
49
+ };
50
+ }
51
+
52
+ module.exports = { createDriver };
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { execFileSync } = require('child_process');
4
- const { getOmpCommand, getOmpPaths } = require('./omp-config');
4
+ const { getOmpCommand, getOmpPaths } = require('./config');
5
5
 
6
6
  const VALID_SCOPES = new Set(['user', 'project']);
7
7
  const GENERIC_SOURCE_KINDS = new Set(['npm', 'link', 'linked', 'marketplace']);
@@ -143,6 +143,62 @@ function normalizeMarketplacePlugin(entry, inheritedMarketplace = '') {
143
143
  class OmpNativePluginAdapter {
144
144
  constructor(options = {}) {
145
145
  this.commandRunner = options.commandRunner || execFileSync;
146
+ this.pathContext = options.pathContext || null;
147
+ this.cacheTtlMs = Math.max(0, Number(options.cacheTtlMs) || 1000);
148
+ this._operationCache = new Map();
149
+ this._operationInflight = new Map();
150
+ }
151
+
152
+ _operationKey(operation, options = {}) {
153
+ const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();
154
+ const scope = normalizeScope(options.scope, '');
155
+ return `${operation}:${cwd}:${scope}`;
156
+ }
157
+
158
+ _clone(value) {
159
+ if (value === undefined) return value;
160
+ try {
161
+ return JSON.parse(JSON.stringify(value));
162
+ } catch (_) {
163
+ return value;
164
+ }
165
+ }
166
+
167
+ _cachedOperation(operation, options, execute) {
168
+ const key = this._operationKey(operation, options);
169
+ const now = Date.now();
170
+ const cached = this._operationCache.get(key);
171
+ if (!options.force && cached && now - cached.cachedAt < this.cacheTtlMs) {
172
+ return this._clone(cached.value);
173
+ }
174
+ if (this._operationInflight.has(key)) {
175
+ return this._operationInflight.get(key);
176
+ }
177
+ try {
178
+ const value = execute();
179
+ this._operationCache.set(key, { value: this._clone(value), cachedAt: now });
180
+ return this._clone(value);
181
+ } catch (error) {
182
+ if (cached) {
183
+ return {
184
+ ...this._clone(cached.value),
185
+ error: {
186
+ message: error.message || String(error),
187
+ retryable: true
188
+ }
189
+ };
190
+ }
191
+ throw error;
192
+ }
193
+ }
194
+
195
+ invalidate(options = {}) {
196
+ const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();
197
+ const scope = normalizeScope(options.scope, '');
198
+ const suffix = `:${cwd}:${scope}`;
199
+ for (const key of this._operationCache.keys()) {
200
+ if (key.endsWith(suffix)) this._operationCache.delete(key);
201
+ }
146
202
  }
147
203
 
148
204
  run(args, options = {}) {
@@ -169,6 +225,14 @@ class OmpNativePluginAdapter {
169
225
  }
170
226
 
171
227
  listPlugins(options = {}) {
228
+ return this._cachedOperation(
229
+ 'plugin:list',
230
+ options,
231
+ () => this._listPluginsUncached(options)
232
+ );
233
+ }
234
+
235
+ _listPluginsUncached(options = {}) {
172
236
  const payload = this.runJson(['plugin', 'list', '--json'], options);
173
237
  if (!payload || typeof payload !== 'object') {
174
238
  throw new Error('OMP plugin list returned an invalid JSON payload');
@@ -193,7 +257,10 @@ class OmpNativePluginAdapter {
193
257
  }
194
258
 
195
259
  listLooseExtensions() {
196
- const extensionsDir = getOmpPaths().extensions;
260
+ const extensionsDir = this.pathContext?.customized
261
+ ? (this.pathContext.native?.extensions
262
+ || path.join(this.pathContext.native?.dir || this.pathContext.home || process.cwd(), 'extensions'))
263
+ : getOmpPaths().extensions;
197
264
  if (!fs.existsSync(extensionsDir)) return [];
198
265
  const plugins = [];
199
266
 
@@ -256,6 +323,7 @@ class OmpNativePluginAdapter {
256
323
  if (options.force) args.push('--force');
257
324
  if (options.scope) args.push('--scope', normalizeScope(options.scope));
258
325
  this.run(args, options);
326
+ this.invalidate(options);
259
327
  const parsed = splitMarketplaceId(pluginId);
260
328
  return {
261
329
  success: true,
@@ -295,6 +363,7 @@ class OmpNativePluginAdapter {
295
363
  if (options.scope) args.push('--scope', normalizeScope(options.scope));
296
364
  this.run(args, options);
297
365
  }
366
+ this.invalidate(options);
298
367
  return {
299
368
  success: true,
300
369
  message: `Configuration updated for plugin "${target}"`
@@ -310,9 +379,18 @@ class OmpNativePluginAdapter {
310
379
  const args = ['plugin', action, target];
311
380
  if (options.scope) args.push('--scope', normalizeScope(options.scope));
312
381
  this.run(args, options);
382
+ this.invalidate(options);
313
383
  }
314
384
 
315
385
  discover(options = {}) {
386
+ return this._cachedOperation(
387
+ 'plugin:discover',
388
+ options,
389
+ () => this._discoverUncached(options)
390
+ );
391
+ }
392
+
393
+ _discoverUncached(options = {}) {
316
394
  const output = this.run(['plugin', 'discover', '--json'], options);
317
395
  const text = stripAnsi(output).trim();
318
396
  if (!text || text.includes('No plugins available')) return [];
@@ -381,6 +459,14 @@ class OmpNativePluginAdapter {
381
459
  }
382
460
 
383
461
  listMarketplaces(options = {}) {
462
+ return this._cachedOperation(
463
+ 'marketplace:list',
464
+ options,
465
+ () => this._listMarketplacesUncached(options)
466
+ );
467
+ }
468
+
469
+ _listMarketplacesUncached(options = {}) {
384
470
  const output = this.run(['plugin', 'marketplace', 'list', '--json'], options);
385
471
  const text = stripAnsi(output).trim();
386
472
  if (!text || text.includes('No marketplaces configured')) return [];
@@ -429,20 +515,21 @@ class OmpNativePluginAdapter {
429
515
  const target = String(source || '').trim();
430
516
  if (!target) throw new Error('Missing marketplace source');
431
517
  this.run(['plugin', 'marketplace', 'add', target], options);
518
+ this.invalidate(options);
432
519
  return this.listMarketplaces(options);
433
520
  }
434
521
 
435
522
  removeMarketplace(name, options = {}) {
436
523
  const target = String(name || '').trim();
437
- if (!target) throw new Error('Missing marketplace name');
438
524
  this.run(['plugin', 'marketplace', 'remove', target], options);
525
+ this.invalidate(options);
439
526
  return this.listMarketplaces(options);
440
527
  }
441
528
 
442
529
  updateMarketplaces(name = '', options = {}) {
443
530
  const args = ['plugin', 'marketplace', 'update'];
444
- if (name) args.push(name);
445
531
  this.run(args, options);
532
+ this.invalidate(options);
446
533
  return this.listMarketplaces(options);
447
534
  }
448
535
  }
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ const mcpFormat = require('../../../shared/mcp-format');
4
+ const {
5
+ createProjectAdapter,
6
+ createJsonMcpHandlers,
7
+ validateMcpId
8
+ } = require('../../../shared/project-config');
9
+
10
+ function createAdapter({ manifest, fsImpl } = {}) {
11
+ const relativePath = manifest?.projectResources?.mcp?.path;
12
+ const mcpHandlers = createJsonMcpHandlers({
13
+ relativePath,
14
+ format: manifest?.projectResources?.mcp?.format || 'omp-json',
15
+ toNative: mcpFormat.convertToOmpMcpFormat,
16
+ fromNative: mcpFormat.convertFromOmpMcpFormat,
17
+ validateId: id => {
18
+ try {
19
+ return validateMcpId(id);
20
+ } catch {
21
+ throw new Error(`OMP MCP server ID "${id}" is invalid`);
22
+ }
23
+ },
24
+ fsImpl
25
+ });
26
+ return createProjectAdapter({ manifest, fsImpl, mcpHandlers });
27
+ }
28
+
29
+ module.exports = { createAdapter };
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ const { createProjectsDriver } = require('../../../shared/driver-factories/projects');
4
+
5
+ function createDriver(context = {}) {
6
+ return createProjectsDriver({
7
+ ...context,
8
+ platform: 'omp',
9
+ servicePath: './omp/sessions-implementation',
10
+ localServicePath: '../../platforms/drivers/omp/sessions-implementation',
11
+ availabilityMethod: 'isOmpInstalled',
12
+ onSuccess: operation => {
13
+ if (['saveProjectOrder', 'createProject', 'deleteProject'].includes(operation)) {
14
+ context.sessionHistoryIndex?.invalidateSource('omp');
15
+ }
16
+ }
17
+ });
18
+ }
19
+
20
+ module.exports = { createDriver };
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ const { createPromptDriver } = require('../../../shared/driver-factories/prompts');
4
+
5
+ function createDriver(context = {}) {
6
+ return createPromptDriver({ ...context, platform: 'omp' });
7
+ }
8
+
9
+ module.exports = { createDriver };
@@ -1,5 +1,5 @@
1
- const { loadConfig } = require('../config/loader');
2
- const { saveProxyStartTime, clearProxyStartTime, getProxyStartTime, getProxyRuntime } = require('./services/proxy-runtime');
1
+ const { loadConfig } = require('../../../config/loader');
2
+ const { saveProxyStartTime, clearProxyStartTime, getProxyStartTime, getProxyRuntime } = require('../../../server/services/proxy-runtime');
3
3
  const {
4
4
  syncManagedOmpProviders,
5
5
  disableManagedOmpProviders,
@@ -11,15 +11,10 @@ const {
11
11
  loadManagedOmpActiveChannelId,
12
12
  loadManagedOmpModeState,
13
13
  getOrCreateOmpGatewaySecret
14
- } = require('./services/omp-channels');
15
- const {
16
- startOmpSessionLogObserver,
17
- stopOmpSessionLogObserver,
18
- getOmpSessionLogObserverStatus
19
- } = require('./services/omp-session-log-observer');
20
- const { createOmpGateway } = require('./services/omp-gateway');
21
- const { prepareManagedOmpChannels } = require('./services/omp-gateway-routing');
22
- const { probeOmpAuthGateways } = require('./services/omp-auth-gateway-client');
14
+ } = require('./channels-implementation');
15
+ const { createOmpGateway } = require('./gateway');
16
+ const { prepareManagedOmpChannels } = require('./gateway-routing');
17
+ const { probeOmpAuthGateways } = require('./auth-gateway-client');
23
18
 
24
19
  let currentPort = null;
25
20
  let lastSyncResult = null;
@@ -91,7 +86,6 @@ async function startOmpProxyServerUnlocked(options = {}) {
91
86
  currentPort = null;
92
87
  throw error;
93
88
  }
94
- startOmpSessionLogObserver();
95
89
  saveProxyStartTime('omp', preserveStartTime);
96
90
  return {
97
91
  success: true,
@@ -125,7 +119,6 @@ async function stopOmpProxyServerUnlocked(options = {}) {
125
119
  || enabledChannels[0]
126
120
  || null;
127
121
  gateway.beginDraining();
128
- stopOmpSessionLogObserver();
129
122
  try {
130
123
  if (!preserveManagedMode) {
131
124
  if (activeChannel) {
@@ -137,7 +130,6 @@ async function stopOmpProxyServerUnlocked(options = {}) {
137
130
  disableManagedOmpMode();
138
131
  }
139
132
  } catch (error) {
140
- startOmpSessionLogObserver();
141
133
  gateway.cancelDraining();
142
134
  throw error;
143
135
  }
@@ -189,7 +181,6 @@ function getOmpProxyStatus() {
189
181
  modelsPath: lastSyncResult?.modelsPath || lastSyncResult?.path || null,
190
182
  backupPath: lastSyncResult?.backupPath || null,
191
183
  modelsValidation: validation,
192
- sessionLogObserver: getOmpSessionLogObserverStatus(),
193
184
  warnings: lastSyncResult?.warnings || []
194
185
  };
195
186
  }
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ const { createProxyDriver } = require('../../../shared/proxy-driver');
4
+
5
+ function createDriver(context = {}) {
6
+ return createProxyDriver({
7
+ ...context,
8
+ platform: 'omp',
9
+ servicePath: './omp/proxy-implementation',
10
+ localServicePath: '../platforms/drivers/omp/proxy-implementation',
11
+ exports: { status: 'getOmpProxyStatus', start: 'startOmpProxyServer', stop: 'stopOmpProxyServer' },
12
+ cliMetadata: { managedProviderConfig: true, defaultPort: 20092 }
13
+ });
14
+ }
15
+
16
+ module.exports = { createDriver };
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ const { createResourceSyncDriver } = require('../../../shared/driver-factories/resource-sync');
4
+
5
+ function createDriver(context = {}) {
6
+ return createResourceSyncDriver({ ...context, platform: 'omp' });
7
+ }
8
+
9
+ module.exports = { createDriver };
@@ -3,9 +3,21 @@
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
5
  const { HOME_DIR } = require('../../../config/paths');
6
- const { getOmpPaths } = require('../omp-config');
6
+ const { getOmpPaths } = require('./config');
7
+ const { normalizeUsage: normalizeNativeUsage } = require('../native-log-utils');
8
+
9
+ let ompSessionPathsOverride = null;
10
+
11
+ function configure({ pathContext } = {}) {
12
+ require('./config').configure?.({ pathContext });
13
+ const native = pathContext?.customized ? (pathContext.native || {}) : {};
14
+ ompSessionPathsOverride = native.sessions
15
+ ? { ...native, agentDir: native.dir || path.dirname(native.sessions) }
16
+ : null;
17
+ }
7
18
 
8
19
  function getOmpSessionPaths() {
20
+ if (ompSessionPathsOverride?.sessions) return ompSessionPathsOverride;
9
21
  return getOmpPaths(process.env, { resolveRuntime: false });
10
22
  }
11
23
 
@@ -68,16 +80,20 @@ function extractMessageText(message = {}) {
68
80
  }
69
81
 
70
82
  function parseUsage(usage = {}) {
71
- const input = Number(usage.input ?? usage.inputTokens ?? usage.input_tokens ?? usage.prompt_tokens ?? usage.promptTokens ?? 0) || 0;
72
- const output = Number(usage.output ?? usage.outputTokens ?? usage.output_tokens ?? usage.completion_tokens ?? usage.completionTokens ?? 0) || 0;
73
- const cacheRead = Number(usage.cacheRead ?? usage.cache_read ?? usage.cachedTokens ?? usage.cached_tokens ?? usage.cache_read_input_tokens ?? 0) || 0;
74
- const cacheWrite = Number(usage.cacheWrite ?? usage.cache_write ?? usage.cacheCreation ?? usage.cache_creation ?? usage.cache_creation_input_tokens ?? 0) || 0;
75
- const reasoning = Number(usage.reasoningTokens ?? usage.reasoning_tokens ?? 0) || 0;
76
- const total = Number(usage.totalTokens ?? usage.total_tokens ?? (input + output + cacheRead + cacheWrite + reasoning)) || 0;
83
+ const normalized = normalizeNativeUsage(usage);
84
+ const input = normalized.input;
85
+ const output = normalized.output;
86
+ const cacheRead = normalized.cacheRead;
87
+ const cacheWrite = normalized.cacheCreation;
88
+ const reasoning = normalized.reasoning;
89
+ const total = normalized.total;
77
90
  const cost = typeof usage.cost === 'number'
78
91
  ? usage.cost
79
92
  : Number(usage.cost?.total ?? usage.cost?.usd ?? 0) || 0;
80
- return { input, output, cached: cacheRead, cacheRead, cacheWrite, reasoning, total, cost };
93
+ return {
94
+ input, output, cached: normalized.cached, cacheRead, cacheWrite,
95
+ cacheCreation: normalized.cacheCreation, reasoning, total, cost
96
+ };
81
97
  }
82
98
 
83
99
  function readJsonLines(filePath) {
@@ -134,30 +150,34 @@ function convertOmpEntry(entry = {}, index = 0) {
134
150
  * Inventory all OMP session files.
135
151
  * @returns {Promise<Array>}
136
152
  */
137
- async function inventory() {
153
+ async function inventory({ projectsDir } = {}) {
138
154
  const descriptors = [];
139
155
  let sessionsDir;
140
156
  try {
141
- sessionsDir = getOmpSessionPaths().sessions;
157
+ sessionsDir = projectsDir || getOmpSessionPaths().sessions;
158
+ } catch (_) {
159
+ return descriptors;
160
+ }
161
+ try {
162
+ await fs.promises.stat(sessionsDir);
142
163
  } catch (_) {
143
164
  return descriptors;
144
165
  }
145
- if (!fs.existsSync(sessionsDir)) return descriptors;
146
166
 
147
- function walk(dir) {
167
+ async function walk(dir) {
148
168
  let entries;
149
169
  try {
150
- entries = fs.readdirSync(dir, { withFileTypes: true });
170
+ entries = await fs.promises.readdir(dir, { withFileTypes: true });
151
171
  } catch {
152
172
  return;
153
173
  }
154
174
  for (const entry of entries) {
155
175
  const fullPath = path.join(dir, entry.name);
156
176
  if (entry.isDirectory()) {
157
- walk(fullPath);
177
+ await walk(fullPath);
158
178
  } else if (entry.isFile() && entry.name.endsWith('.jsonl')) {
159
179
  try {
160
- const stat = fs.statSync(fullPath);
180
+ const stat = await fs.promises.stat(fullPath);
161
181
  descriptors.push({
162
182
  filePath: fullPath,
163
183
  size: stat.size,
@@ -170,7 +190,7 @@ async function inventory() {
170
190
  }
171
191
  }
172
192
 
173
- walk(sessionsDir);
193
+ await walk(sessionsDir);
174
194
  return descriptors;
175
195
  }
176
196
 
@@ -181,7 +201,11 @@ async function parse(descriptor) {
181
201
  const { filePath, size, mtimeMs } = descriptor;
182
202
  const entries = readJsonLines(filePath);
183
203
  const header = entries.find(entry => entry?.type === 'session') || {};
184
- const cwd = header.cwd || '';
204
+ const cwd = header.cwd
205
+ || header.project?.cwd
206
+ || entries.find(entry => typeof entry?.cwd === 'string')?.cwd
207
+ || entries.find(entry => typeof entry?.message?.cwd === 'string')?.message.cwd
208
+ || '';
185
209
  const sessionId = header.id || parseOmpSessionId(filePath) || descriptor.sessionId;
186
210
 
187
211
  const parsedMessages = entries.map((entry, idx) => convertOmpEntry(entry, idx)).filter(Boolean);
@@ -253,4 +277,4 @@ async function parse(descriptor) {
253
277
  return { session, messages };
254
278
  }
255
279
 
256
- module.exports = { inventory, parse, convertOmpEntry, parseUsage, encodeProjectName: encodeProjectName, getDisplayName, readJsonLines, extractMessageText, normalizeTextContent };
280
+ module.exports = { configure, inventory, parse, convertOmpEntry, parseUsage, encodeProjectName: encodeProjectName, getDisplayName, readJsonLines, extractMessageText, normalizeTextContent };