@xopcai/xopc 0.0.113 → 0.0.114

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 (327) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CBlklyNr.js → agent-avatar-dicebear-Fp-p7bP1.js} +1 -1
  4. package/dist/gateway/static/root/assets/agent-browser-settings-page-CWh7trjd.js +6 -0
  5. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-kC8OuLoj.js +1 -0
  6. package/dist/gateway/static/root/assets/agents-DJWG26Si.js +71 -0
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-28E_WfMe.js → app-management-settings-panel-v24i25Oj.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-Do1z0XgJ.js → appearance-settings-ycbdJRuZ.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-0V3DXZ7J.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-BAFlsov_.js → archive-plugin-CJzSADJo.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-V3qGPC3x.js → attachment-load-BTAB4zGS.js} +1 -1
  12. package/dist/gateway/static/root/assets/{binary-plugins-DT8NvA6W.js → binary-plugins-DXR1-mct.js} +1 -1
  13. package/dist/gateway/static/root/assets/{block-editor-CdLMEcHd.js → block-editor-CzQri9h2.js} +44 -44
  14. package/dist/gateway/static/root/assets/channels-settings-CIKOkYdO.js +1 -0
  15. package/dist/gateway/static/root/assets/{config-api-Bf5mjpu7.js → config-api-DRqjEvAx.js} +1 -1
  16. package/dist/gateway/static/root/assets/connectors-settings-ClrDS5jH.js +2 -0
  17. package/dist/gateway/static/root/assets/{cron-api--pAB_rps.js → cron-api-BXaZXv1o.js} +1 -1
  18. package/dist/gateway/static/root/assets/cron-page-Chi_4u4P.js +3 -0
  19. package/dist/gateway/static/root/assets/dreaming-settings-B0_rs2tj.js +1 -0
  20. package/dist/gateway/static/root/assets/{extension-debug-page-BGhE7msg.js → extension-debug-page-DSkqMYo7.js} +1 -1
  21. package/dist/gateway/static/root/assets/{extension-page-CvpI45WG.js → extension-page-h2dGDbMN.js} +1 -1
  22. package/dist/gateway/static/root/assets/{extension-settings-page-DAmR5FUe.js → extension-settings-page-hN99RhOi.js} +1 -1
  23. package/dist/gateway/static/root/assets/{fetch-NZmjSXLl.js → fetch-D9QqUtzZ.js} +1 -1
  24. package/dist/gateway/static/root/assets/{format-interval-label-qhth3BMV.js → format-interval-label-D6E687rG.js} +1 -1
  25. package/dist/gateway/static/root/assets/{gateway-config-api-CaXBt-9R.js → gateway-config-api-CLt_SKTC.js} +1 -1
  26. package/dist/gateway/static/root/assets/{gateway-settings-DphpbLBc.js → gateway-settings-1PDi4lI0.js} +1 -1
  27. package/dist/gateway/static/root/assets/{gateway-startup-retry-Be1omjh3.js → gateway-startup-retry-N7Z_sz7p.js} +1 -1
  28. package/dist/gateway/static/root/assets/goal-detail-page-D_wwXL-t.js +1 -0
  29. package/dist/gateway/static/root/assets/goals-page-DZ2toZ8y.js +2 -0
  30. package/dist/gateway/static/root/assets/{goals-settings-ceEBjnfc.js → goals-settings-LFlwtIKE.js} +1 -1
  31. package/dist/gateway/static/root/assets/{heartbeat-config-api-BzO6G4fD.js → heartbeat-config-api-DGPadTw-.js} +1 -1
  32. package/dist/gateway/static/root/assets/{heartbeat-settings-DCST9-du.js → heartbeat-settings-BHHAs8ZX.js} +1 -1
  33. package/dist/gateway/static/root/assets/index-DefIdW9q.js +122 -0
  34. package/dist/gateway/static/root/assets/index-DzmWBkq-.css +1 -0
  35. package/dist/gateway/static/root/assets/{interval-presets-DJmshV8n.js → interval-presets-CEklPQ_r.js} +1 -1
  36. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-9AUUlQ5Q.js → keyboard-shortcuts-settings-Ce_aQ8Iv.js} +1 -1
  37. package/dist/gateway/static/root/assets/logs-page-j_D2QTuQ.js +2 -0
  38. package/dist/gateway/static/root/assets/{markdown-split-CYYELqAr.js → markdown-split-BMz3xPXO.js} +1 -1
  39. package/dist/gateway/static/root/assets/{media-plugins-BEcMR2M8.js → media-plugins-BalOSoz9.js} +1 -1
  40. package/dist/gateway/static/root/assets/messages-BN_WiUg0.js +3 -0
  41. package/dist/gateway/static/root/assets/models-hub-panel-CMH_TmZz.js +2 -0
  42. package/dist/gateway/static/root/assets/note-detail-page-O18BrQPq.js +2 -0
  43. package/dist/gateway/static/root/assets/{note-image-lightbox-DNAoPcmm.js → note-image-lightbox-C5D1Q5mY.js} +1 -1
  44. package/dist/gateway/static/root/assets/notes-page-B_ZYCmY9.js +1 -0
  45. package/dist/gateway/static/root/assets/{preview-open-alternatives-BPLz0AIv.js → preview-open-alternatives-CYFR5U9l.js} +1 -1
  46. package/dist/gateway/static/root/assets/remote-access-hub-CwKgWixY.js +1 -0
  47. package/dist/gateway/static/root/assets/{save-bar-controls-CrWwWRVK.js → save-bar-controls-BQ79Z5IP.js} +1 -1
  48. package/dist/gateway/static/root/assets/{schedule-field-CF2sadvN.js → schedule-field-Bgk6Emue.js} +1 -1
  49. package/dist/gateway/static/root/assets/{schema-form-Di5cKjYE.js → schema-form-DzS36TMa.js} +1 -1
  50. package/dist/gateway/static/root/assets/sessions-page-C4fcD-7B.js +1 -0
  51. package/dist/gateway/static/root/assets/settings-advanced-gate-Ad2OJ86w.js +1 -0
  52. package/dist/gateway/static/root/assets/{settings-collapsible-section-Chh282jW.js → settings-collapsible-section-CdjFnSAy.js} +1 -1
  53. package/dist/gateway/static/root/assets/{settings-form-section-Dq-83cQd.js → settings-form-section-DZLy_exu.js} +1 -1
  54. package/dist/gateway/static/root/assets/settings-page-D2BMY5wo.js +1 -0
  55. package/dist/gateway/static/root/assets/setup-status-panel-aWwxl_E1.js +1 -0
  56. package/dist/gateway/static/root/assets/{share-preview-page-0FXYnSUA.js → share-preview-page-_qRDr4g_.js} +1 -1
  57. package/dist/gateway/static/root/assets/shares-settings-DUE83uIf.js +1 -0
  58. package/dist/gateway/static/root/assets/skill-reload-api-mWKJcrog.js +1 -0
  59. package/dist/gateway/static/root/assets/skills-page-0Sx1Q58n.js +2 -0
  60. package/dist/gateway/static/root/assets/{system-settings-panel-W1pTcojB.js → system-settings-panel-hqaBF5aG.js} +1 -1
  61. package/dist/gateway/static/root/assets/{use-agent-defaults-form-BVRvkK7m.js → use-agent-defaults-form-zbVIQLOA.js} +1 -1
  62. package/dist/gateway/static/root/assets/{use-channel-catalog-CgJibfMM.js → use-channel-catalog-CbXq97rT.js} +1 -1
  63. package/dist/gateway/static/root/assets/{use-settings-tab-guard-Bw_qkRQE.js → use-settings-tab-guard-DwS3drWK.js} +1 -1
  64. package/dist/gateway/static/root/assets/voice-api-key-field-D6HR0hR2.js +1 -0
  65. package/dist/gateway/static/root/assets/{voice-player-store-C7lziaAx.js → voice-player-store-DSuOd9zy.js} +1 -1
  66. package/dist/gateway/static/root/assets/workflow-page.utils-C0Uq3xyq.js +1 -0
  67. package/dist/gateway/static/root/assets/workflows-page-DW0fmWhQ.js +18 -0
  68. package/dist/gateway/static/root/index.html +5 -5
  69. package/dist/package.js +1 -1
  70. package/dist/src/agent/agent-manager.d.ts +8 -0
  71. package/dist/src/agent/agent-manager.js +57 -22
  72. package/dist/src/agent/agent-manager.js.map +1 -1
  73. package/dist/src/agent/bootstrap/project-agents-context.d.ts +2 -0
  74. package/dist/src/agent/bootstrap/project-agents-context.js +32 -0
  75. package/dist/src/agent/bootstrap/project-agents-context.js.map +1 -0
  76. package/dist/src/agent/goals/persistent-goal-service.js +2 -4
  77. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  78. package/dist/src/agent/inbound/inbound-loop.js +5 -1
  79. package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
  80. package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -2
  81. package/dist/src/agent/inbound/turn-dispatcher.js +2 -2
  82. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  83. package/dist/src/agent/mcp/bundle-mcp-materialize.d.ts +27 -0
  84. package/dist/src/agent/mcp/bundle-mcp-materialize.js +49 -1
  85. package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
  86. package/dist/src/agent/mcp/bundle-mcp-runtime.js +78 -3
  87. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  88. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +19 -0
  89. package/dist/src/agent/service/btw-query.js +11 -3
  90. package/dist/src/agent/service/btw-query.js.map +1 -1
  91. package/dist/src/agent/service/parse-outbound-session-key.js +13 -8
  92. package/dist/src/agent/service/parse-outbound-session-key.js.map +1 -1
  93. package/dist/src/agent/service/process-direct-one-shot.d.ts +2 -2
  94. package/dist/src/agent/service/process-direct-one-shot.js +1 -1
  95. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  96. package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
  97. package/dist/src/agent/service/process-direct-streaming.js +1 -1
  98. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  99. package/dist/src/agent/service.d.ts +1 -1
  100. package/dist/src/agent/service.js +9 -5
  101. package/dist/src/agent/service.js.map +1 -1
  102. package/dist/src/agent/service.types.d.ts +5 -0
  103. package/dist/src/agent/skills/filesystem-watcher.js +4 -3
  104. package/dist/src/agent/skills/filesystem-watcher.js.map +1 -1
  105. package/dist/src/agent/skills/index.js +2 -1
  106. package/dist/src/agent/skills/index.js.map +1 -1
  107. package/dist/src/agent/skills/skill-manage-ops.js +2 -1
  108. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  109. package/dist/src/agent/skills/types.d.ts +1 -1
  110. package/dist/src/agent/skills/watcher.js +2 -5
  111. package/dist/src/agent/skills/watcher.js.map +1 -1
  112. package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
  113. package/dist/src/agent/skills/workspace-skills-dir.js +11 -0
  114. package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -0
  115. package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
  116. package/dist/src/agent/tool-manuals/browser.js +62 -3
  117. package/dist/src/agent/tool-manuals/browser.js.map +1 -1
  118. package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -1
  119. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +13 -4
  120. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  121. package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -2
  122. package/dist/src/agent/tools/browser/tool/schemas.js +1 -2
  123. package/dist/src/agent/tools/browser/tool/schemas.js.map +1 -1
  124. package/dist/src/agent/tools/factory.js +1 -10
  125. package/dist/src/agent/tools/factory.js.map +1 -1
  126. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  127. package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
  128. package/dist/src/agent/workflow/subagent-runner.js +18 -1
  129. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  130. package/dist/src/browser/actions/extension-registry-bridge.js +91 -7
  131. package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
  132. package/dist/src/browser/actions/registry.js +383 -7
  133. package/dist/src/browser/actions/registry.js.map +1 -1
  134. package/dist/src/browser/actions/types.d.ts +11 -3
  135. package/dist/src/browser/index.js +2 -2
  136. package/dist/src/browser/pipeline/output.d.ts +18 -16
  137. package/dist/src/browser/pipeline/output.js +28 -20
  138. package/dist/src/browser/pipeline/output.js.map +1 -1
  139. package/dist/src/browser/pipeline/runner.d.ts +7 -14
  140. package/dist/src/browser/pipeline/runner.js +349 -102
  141. package/dist/src/browser/pipeline/runner.js.map +1 -1
  142. package/dist/src/browser/pipeline/schema.d.ts +1 -0
  143. package/dist/src/browser/pipeline/schema.js +35 -58
  144. package/dist/src/browser/pipeline/schema.js.map +1 -1
  145. package/dist/src/browser/pipeline/source.d.ts +2 -0
  146. package/dist/src/browser/pipeline/source.js +10 -1
  147. package/dist/src/browser/pipeline/source.js.map +1 -1
  148. package/dist/src/browser/pipeline/template.d.ts +10 -2
  149. package/dist/src/browser/pipeline/template.js +50 -8
  150. package/dist/src/browser/pipeline/template.js.map +1 -1
  151. package/dist/src/chat-commands/builtins/config.js +3 -5
  152. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  153. package/dist/src/chat-commands/context.d.ts +5 -0
  154. package/dist/src/chat-commands/context.js +18 -9
  155. package/dist/src/chat-commands/context.js.map +1 -1
  156. package/dist/src/chat-commands/index.d.ts +1 -1
  157. package/dist/src/chat-commands/index.js +2 -2
  158. package/dist/src/chat-commands/index.js.map +1 -1
  159. package/dist/src/chat-commands/processor.js +22 -21
  160. package/dist/src/chat-commands/processor.js.map +1 -1
  161. package/dist/src/chat-commands/session-key.d.ts +3 -15
  162. package/dist/src/chat-commands/session-key.js +3 -49
  163. package/dist/src/chat-commands/session-key.js.map +1 -1
  164. package/dist/src/chat-commands/types.d.ts +4 -0
  165. package/dist/src/cli/commands/browser-cli-helpers.js +11 -5
  166. package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
  167. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  168. package/dist/src/cli/commands/doctor/checks/session-integrity.js +8 -8
  169. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  170. package/dist/src/config/rules.js +5 -0
  171. package/dist/src/config/rules.js.map +1 -1
  172. package/dist/src/connectors/builtin-catalog.js +180 -1
  173. package/dist/src/connectors/builtin-catalog.js.map +1 -1
  174. package/dist/src/connectors/health.js +18 -9
  175. package/dist/src/connectors/health.js.map +1 -1
  176. package/dist/src/connectors/types.d.ts +19 -0
  177. package/dist/src/connectors/usage.js +12 -4
  178. package/dist/src/connectors/usage.js.map +1 -1
  179. package/dist/src/extensions/types/tui.d.ts +2 -0
  180. package/dist/src/gateway/heartbeat/service.js +13 -1
  181. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  182. package/dist/src/gateway/hono/app.js +13 -4
  183. package/dist/src/gateway/hono/app.js.map +1 -1
  184. package/dist/src/gateway/hono/oauth-async.js +1 -1
  185. package/dist/src/gateway/hono/routes/agent-stream.js +6 -6
  186. package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
  187. package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +1 -1
  188. package/dist/src/gateway/hono/routes/config-patch/gateway.js +6 -0
  189. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  190. package/dist/src/gateway/hono/routes/goals.js +16 -3
  191. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  192. package/dist/src/gateway/hono/routes/logs.js +1 -0
  193. package/dist/src/gateway/hono/routes/logs.js.map +1 -1
  194. package/dist/src/gateway/hono/routes/mcp.js +27 -8
  195. package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
  196. package/dist/src/gateway/hono/routes/notes.js +14 -2
  197. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  198. package/dist/src/gateway/hono/routes/sessions.js +62 -4
  199. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  200. package/dist/src/gateway/hono/routes/workspace.js +3 -66
  201. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  202. package/dist/src/gateway/hono/sse.d.ts +2 -2
  203. package/dist/src/gateway/hono/sse.js +7 -15
  204. package/dist/src/gateway/hono/sse.js.map +1 -1
  205. package/dist/src/gateway/resolve-webchat-session-key.d.ts +2 -6
  206. package/dist/src/gateway/resolve-webchat-session-key.js +5 -31
  207. package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -1
  208. package/dist/src/gateway/service/agent-runner.d.ts +2 -3
  209. package/dist/src/gateway/service/agent-runner.js +9 -22
  210. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  211. package/dist/src/gateway/service/run-gateway-agent.js +9 -7
  212. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  213. package/dist/src/gateway/service/sessions-api.d.ts +9 -0
  214. package/dist/src/gateway/service/sessions-api.js +11 -0
  215. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  216. package/dist/src/gateway/service.d.ts +1 -1
  217. package/dist/src/gateway/service.js +19 -5
  218. package/dist/src/gateway/service.js.map +1 -1
  219. package/dist/src/gateway/workspace-file-search.d.ts +9 -0
  220. package/dist/src/gateway/workspace-file-search.js +76 -0
  221. package/dist/src/gateway/workspace-file-search.js.map +1 -0
  222. package/dist/src/goals/goal-notifications.d.ts +2 -0
  223. package/dist/src/goals/goal-notifications.js +16 -11
  224. package/dist/src/goals/goal-notifications.js.map +1 -1
  225. package/dist/src/goals/goal-service.js +1 -6
  226. package/dist/src/goals/goal-service.js.map +1 -1
  227. package/dist/src/project-trust/trust-store.js +2 -0
  228. package/dist/src/project-trust/trust-store.js.map +1 -1
  229. package/dist/src/session/index.d.ts +1 -1
  230. package/dist/src/session/index.js +2 -2
  231. package/dist/src/session/init-session-turn.js +6 -9
  232. package/dist/src/session/init-session-turn.js.map +1 -1
  233. package/dist/src/session/manager.d.ts +5 -1
  234. package/dist/src/session/manager.js +5 -2
  235. package/dist/src/session/manager.js.map +1 -1
  236. package/dist/src/session/reset-type.d.ts +0 -2
  237. package/dist/src/session/reset-type.js +3 -9
  238. package/dist/src/session/reset-type.js.map +1 -1
  239. package/dist/src/session/resolve-session.js +9 -20
  240. package/dist/src/session/resolve-session.js.map +1 -1
  241. package/dist/src/session/store.d.ts +11 -3
  242. package/dist/src/session/store.js +29 -13
  243. package/dist/src/session/store.js.map +1 -1
  244. package/dist/src/session/types.d.ts +2 -4
  245. package/dist/src/session/types.js.map +1 -1
  246. package/dist/src/storage/sqlite/index.d.ts +2 -2
  247. package/dist/src/storage/sqlite/index.js +3 -3
  248. package/dist/src/storage/sqlite/migrations/010_session_id_identity.sql +30 -0
  249. package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
  250. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  251. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  252. package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
  253. package/dist/src/storage/sqlite/row-mappers.d.ts +4 -4
  254. package/dist/src/storage/sqlite/row-mappers.js +11 -14
  255. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  256. package/dist/src/storage/sqlite/schema.js +3 -3
  257. package/dist/src/storage/sqlite/schema.js.map +1 -1
  258. package/dist/src/storage/sqlite/schema.sql +37 -10
  259. package/dist/src/storage/sqlite/session-metadata.d.ts +2 -7
  260. package/dist/src/storage/sqlite/session-metadata.js +18 -72
  261. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  262. package/dist/src/storage/sqlite/session-repository.d.ts +6 -5
  263. package/dist/src/storage/sqlite/session-repository.js +34 -40
  264. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  265. package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -2
  266. package/dist/src/storage/sqlite/transcript-repository.js +52 -52
  267. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
  268. package/dist/src/tui/backends/embedded-backend.d.ts +11 -4
  269. package/dist/src/tui/backends/embedded-backend.js +27 -1
  270. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  271. package/dist/src/tui/backends/gateway-sse-backend.d.ts +4 -1
  272. package/dist/src/tui/backends/gateway-sse-backend.js +21 -2
  273. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  274. package/dist/src/tui/extension-host/autocomplete.js +13 -10
  275. package/dist/src/tui/extension-host/autocomplete.js.map +1 -1
  276. package/dist/src/tui/extension-host/runtime.d.ts +7 -0
  277. package/dist/src/tui/extension-host/runtime.js +6 -4
  278. package/dist/src/tui/extension-host/runtime.js.map +1 -1
  279. package/dist/src/tui/tui-backend.d.ts +9 -0
  280. package/dist/src/tui/tui-commands.js +85 -6
  281. package/dist/src/tui/tui-commands.js.map +1 -1
  282. package/dist/src/tui/tui-file-autocomplete.d.ts +5 -0
  283. package/dist/src/tui/tui-file-autocomplete.js +26 -0
  284. package/dist/src/tui/tui-file-autocomplete.js.map +1 -0
  285. package/dist/src/tui/tui-picker-overlay.js +1 -1
  286. package/dist/src/tui/tui.js +29 -11
  287. package/dist/src/tui/tui.js.map +1 -1
  288. package/dist/src/utils/logger/context.d.ts +2 -2
  289. package/dist/src/utils/logger/context.js +2 -1
  290. package/dist/src/utils/logger/context.js.map +1 -1
  291. package/dist/src/utils/logger/log-store.js +1 -0
  292. package/dist/src/utils/logger/log-store.js.map +1 -1
  293. package/dist/src/utils/logger/pino-record.js +3 -0
  294. package/dist/src/utils/logger/pino-record.js.map +1 -1
  295. package/dist/src/utils/logger/types.d.ts +5 -0
  296. package/dist/src/utils/logger/types.js.map +1 -1
  297. package/dist/src/workflows/service/workflow-session-bridge.js +13 -1
  298. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  299. package/package.json +1 -1
  300. package/dist/gateway/static/root/assets/agent-browser-settings-page-rGbKc2Hh.js +0 -6
  301. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-CtwVbjOA.js +0 -1
  302. package/dist/gateway/static/root/assets/agents-CCBmGcwc.js +0 -71
  303. package/dist/gateway/static/root/assets/apps-page-xwCsJS15.js +0 -1
  304. package/dist/gateway/static/root/assets/channels-settings-C044DcYk.js +0 -1
  305. package/dist/gateway/static/root/assets/connectors-settings-8VEWUOTj.js +0 -2
  306. package/dist/gateway/static/root/assets/cron-page-DqmNGNOy.js +0 -3
  307. package/dist/gateway/static/root/assets/dreaming-settings-6UZE1FSK.js +0 -1
  308. package/dist/gateway/static/root/assets/goal-detail-page-bv0VRDaf.js +0 -1
  309. package/dist/gateway/static/root/assets/goals-page-1Ywnt4Cb.js +0 -2
  310. package/dist/gateway/static/root/assets/index-Cxm6xsps.js +0 -122
  311. package/dist/gateway/static/root/assets/index-b_R4tKqt.css +0 -1
  312. package/dist/gateway/static/root/assets/logs-page-B_wrxhee.js +0 -2
  313. package/dist/gateway/static/root/assets/messages-CkT-lcgP.js +0 -3
  314. package/dist/gateway/static/root/assets/models-hub-panel-D0JDSbNu.js +0 -2
  315. package/dist/gateway/static/root/assets/note-detail-page-DpFV-EO6.js +0 -2
  316. package/dist/gateway/static/root/assets/notes-page-CdkjTch8.js +0 -1
  317. package/dist/gateway/static/root/assets/remote-access-hub-DSYVAi96.js +0 -1
  318. package/dist/gateway/static/root/assets/sessions-page-CenkcVjF.js +0 -1
  319. package/dist/gateway/static/root/assets/settings-advanced-gate-D9sva86V.js +0 -1
  320. package/dist/gateway/static/root/assets/settings-page-DL35U0x0.js +0 -1
  321. package/dist/gateway/static/root/assets/setup-status-panel-Ctwbp9Er.js +0 -1
  322. package/dist/gateway/static/root/assets/shares-settings-DIM3JNsr.js +0 -1
  323. package/dist/gateway/static/root/assets/skill-reload-api-DAlNaNzL.js +0 -1
  324. package/dist/gateway/static/root/assets/skills-page-CLrHVzAt.js +0 -2
  325. package/dist/gateway/static/root/assets/voice-api-key-field-vYAO71Gn.js +0 -1
  326. package/dist/gateway/static/root/assets/workflow-page.utils-sgHjOXOm.js +0 -1
  327. package/dist/gateway/static/root/assets/workflows-page-DYyOTmFx.js +0 -18
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { LogContext } from './types.js';
6
6
  /** Correlation fields merged into every log line while the store is active (via pino mixin). */
7
- declare const ASYNC_LOG_CORRELATION_KEYS: readonly ["requestId", "sessionId", "userId", "correlationId"];
7
+ declare const ASYNC_LOG_CORRELATION_KEYS: readonly ["requestId", "sessionKey", "sessionId", "userId", "correlationId"];
8
8
  type AsyncLogCorrelationKey = (typeof ASYNC_LOG_CORRELATION_KEYS)[number];
9
9
  /**
10
10
  * Run *fn* with merged async log context. Propagates through async/await (Node AsyncLocalStorage).
@@ -14,7 +14,7 @@ export declare function runWithLogContext<T>(context: LogContext, fn: () => T):
14
14
  /** Current async log context, if any. */
15
15
  export declare function getAsyncLogContext(): LogContext | undefined;
16
16
  /**
17
- * Shallow-merge fields into the current async log context (e.g. set sessionId after parsing a body).
17
+ * Shallow-merge fields into the current async log context (e.g. set session identifiers after parsing a body).
18
18
  * No-op when not inside {@link runWithLogContext}.
19
19
  */
20
20
  export declare function updateAsyncLogContext(partial: LogContext): void;
@@ -19,7 +19,7 @@ function getAsyncLogContext() {
19
19
  return logContextStorage.getStore()?.ctx;
20
20
  }
21
21
  /**
22
- * Shallow-merge fields into the current async log context (e.g. set sessionId after parsing a body).
22
+ * Shallow-merge fields into the current async log context (e.g. set session identifiers after parsing a body).
23
23
  * No-op when not inside {@link runWithLogContext}.
24
24
  */
25
25
  function updateAsyncLogContext(partial) {
@@ -51,6 +51,7 @@ var ASYNC_LOG_CORRELATION_KEYS, logContextStorage, INBOUND_METADATA_FROM_ASYNC;
51
51
  var init_context = __esmMin((() => {
52
52
  ASYNC_LOG_CORRELATION_KEYS = [
53
53
  "requestId",
54
+ "sessionKey",
54
55
  "sessionId",
55
56
  "userId",
56
57
  "correlationId"
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../../../../src/utils/logger/context.ts"],"sourcesContent":["/**\n * Logger Context\n * AsyncLocalStorage correlation for structured logging\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nimport type { LogContext } from './types.js';\n\n/** Correlation fields merged into every log line while the store is active (via pino mixin). */\nconst ASYNC_LOG_CORRELATION_KEYS = ['requestId', 'sessionId', 'userId', 'correlationId'] as const;\n\ntype AsyncLogCorrelationKey = (typeof ASYNC_LOG_CORRELATION_KEYS)[number];\n\nconst logContextStorage = new AsyncLocalStorage<{ ctx: LogContext }>();\n\n/**\n * Run *fn* with merged async log context. Propagates through async/await (Node AsyncLocalStorage).\n * Nested calls merge over the parent context (shallow per key).\n */\nexport function runWithLogContext<T>(context: LogContext, fn: () => T): T {\n const parent = logContextStorage.getStore();\n const merged = parent ? mergeContext(parent.ctx, context) : { ...context };\n return logContextStorage.run({ ctx: { ...merged } }, fn);\n}\n\n/** Current async log context, if any. */\nexport function getAsyncLogContext(): LogContext | undefined {\n return logContextStorage.getStore()?.ctx;\n}\n\n/**\n * Shallow-merge fields into the current async log context (e.g. set sessionId after parsing a body).\n * No-op when not inside {@link runWithLogContext}.\n */\nexport function updateAsyncLogContext(partial: LogContext): void {\n const ref = logContextStorage.getStore();\n if (ref) {\n ref.ctx = mergeContext(ref.ctx, partial);\n }\n}\n\n/** Keys injected from async context into log records (used by logger mixin). */\nexport function getAsyncLogCorrelationKeys(): readonly AsyncLogCorrelationKey[] {\n return ASYNC_LOG_CORRELATION_KEYS;\n}\n\n/**\n * Fields to copy from ALS onto {@link InboundMessage.metadata} when the gateway enqueues\n * a message for the agent bus. Omits `sessionId` so channel routing / sessionKey stays\n * authoritative; the agent sets log sessionId after `routeMessage`.\n */\nconst INBOUND_METADATA_FROM_ASYNC: readonly (keyof LogContext)[] = [\n 'requestId',\n 'correlationId',\n 'userId',\n];\n\nexport function inboundCorrelationMetadataFromAsyncLogContext(): Record<string, unknown> | undefined {\n const ctx = getAsyncLogContext();\n if (!ctx) return undefined;\n const meta: Record<string, unknown> = {};\n for (const key of INBOUND_METADATA_FROM_ASYNC) {\n const v = ctx[key];\n if (v !== undefined && v !== '') {\n meta[key] = v;\n }\n }\n return Object.keys(meta).length > 0 ? meta : undefined;\n}\n\n/** Shallow-merge two log context objects. */\nexport function mergeContext(base: LogContext, additional: LogContext): LogContext {\n return { ...base, ...additional };\n}\n"],"mappings":";;;;;;;;;;;AAoBA,SAAgB,kBAAqB,SAAqB,IAAgB;CACxE,MAAM,SAAS,kBAAkB,UAAU;CAC3C,MAAM,SAAS,SAAS,aAAa,OAAO,KAAK,QAAQ,GAAG,EAAE,GAAG,SAAS;AAC1E,QAAO,kBAAkB,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,EAAE,GAAG;;;AAI1D,SAAgB,qBAA6C;AAC3D,QAAO,kBAAkB,UAAU,EAAE;;;;;;AAOvC,SAAgB,sBAAsB,SAA2B;CAC/D,MAAM,MAAM,kBAAkB,UAAU;AACxC,KAAI,IACF,KAAI,MAAM,aAAa,IAAI,KAAK,QAAQ;;;AAK5C,SAAgB,6BAAgE;AAC9E,QAAO;;AAcT,SAAgB,gDAAqF;CACnG,MAAM,MAAM,oBAAoB;AAChC,KAAI,CAAC,IAAK,QAAO,KAAA;CACjB,MAAM,OAAgC,EAAE;AACxC,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,IAAI,IAAI;AACd,MAAI,MAAM,KAAA,KAAa,MAAM,GAC3B,MAAK,OAAO;;AAGhB,QAAO,OAAO,KAAK,KAAK,CAAC,SAAS,IAAI,OAAO,KAAA;;;AAI/C,SAAgB,aAAa,MAAkB,YAAoC;AACjF,QAAO;EAAE,GAAG;EAAM,GAAG;EAAY;;;;AA/D7B,8BAA6B;EAAC;EAAa;EAAa;EAAU;EAAgB;AAIlF,qBAAoB,IAAI,mBAAwC;AAsChE,+BAA6D;EACjE;EACA;EACA;EACD"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../../../src/utils/logger/context.ts"],"sourcesContent":["/**\n * Logger Context\n * AsyncLocalStorage correlation for structured logging\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nimport type { LogContext } from './types.js';\n\n/** Correlation fields merged into every log line while the store is active (via pino mixin). */\nconst ASYNC_LOG_CORRELATION_KEYS = ['requestId', 'sessionKey', 'sessionId', 'userId', 'correlationId'] as const;\n\ntype AsyncLogCorrelationKey = (typeof ASYNC_LOG_CORRELATION_KEYS)[number];\n\nconst logContextStorage = new AsyncLocalStorage<{ ctx: LogContext }>();\n\n/**\n * Run *fn* with merged async log context. Propagates through async/await (Node AsyncLocalStorage).\n * Nested calls merge over the parent context (shallow per key).\n */\nexport function runWithLogContext<T>(context: LogContext, fn: () => T): T {\n const parent = logContextStorage.getStore();\n const merged = parent ? mergeContext(parent.ctx, context) : { ...context };\n return logContextStorage.run({ ctx: { ...merged } }, fn);\n}\n\n/** Current async log context, if any. */\nexport function getAsyncLogContext(): LogContext | undefined {\n return logContextStorage.getStore()?.ctx;\n}\n\n/**\n * Shallow-merge fields into the current async log context (e.g. set session identifiers after parsing a body).\n * No-op when not inside {@link runWithLogContext}.\n */\nexport function updateAsyncLogContext(partial: LogContext): void {\n const ref = logContextStorage.getStore();\n if (ref) {\n ref.ctx = mergeContext(ref.ctx, partial);\n }\n}\n\n/** Keys injected from async context into log records (used by logger mixin). */\nexport function getAsyncLogCorrelationKeys(): readonly AsyncLogCorrelationKey[] {\n return ASYNC_LOG_CORRELATION_KEYS;\n}\n\n/**\n * Fields to copy from ALS onto {@link InboundMessage.metadata} when the gateway enqueues\n * a message for the agent bus. Omits session identifiers so channel routing / session metadata stays\n * authoritative; the agent sets log sessionKey/sessionId after `routeMessage`.\n */\nconst INBOUND_METADATA_FROM_ASYNC: readonly (keyof LogContext)[] = [\n 'requestId',\n 'correlationId',\n 'userId',\n];\n\nexport function inboundCorrelationMetadataFromAsyncLogContext(): Record<string, unknown> | undefined {\n const ctx = getAsyncLogContext();\n if (!ctx) return undefined;\n const meta: Record<string, unknown> = {};\n for (const key of INBOUND_METADATA_FROM_ASYNC) {\n const v = ctx[key];\n if (v !== undefined && v !== '') {\n meta[key] = v;\n }\n }\n return Object.keys(meta).length > 0 ? meta : undefined;\n}\n\n/** Shallow-merge two log context objects. */\nexport function mergeContext(base: LogContext, additional: LogContext): LogContext {\n return { ...base, ...additional };\n}\n"],"mappings":";;;;;;;;;;;AAoBA,SAAgB,kBAAqB,SAAqB,IAAgB;CACxE,MAAM,SAAS,kBAAkB,UAAU;CAC3C,MAAM,SAAS,SAAS,aAAa,OAAO,KAAK,QAAQ,GAAG,EAAE,GAAG,SAAS;AAC1E,QAAO,kBAAkB,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,EAAE,GAAG;;;AAI1D,SAAgB,qBAA6C;AAC3D,QAAO,kBAAkB,UAAU,EAAE;;;;;;AAOvC,SAAgB,sBAAsB,SAA2B;CAC/D,MAAM,MAAM,kBAAkB,UAAU;AACxC,KAAI,IACF,KAAI,MAAM,aAAa,IAAI,KAAK,QAAQ;;;AAK5C,SAAgB,6BAAgE;AAC9E,QAAO;;AAcT,SAAgB,gDAAqF;CACnG,MAAM,MAAM,oBAAoB;AAChC,KAAI,CAAC,IAAK,QAAO,KAAA;CACjB,MAAM,OAAgC,EAAE;AACxC,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,IAAI,IAAI;AACd,MAAI,MAAM,KAAA,KAAa,MAAM,GAC3B,MAAK,OAAO;;AAGhB,QAAO,OAAO,KAAK,KAAK,CAAC,SAAS,IAAI,OAAO,KAAA;;;AAI/C,SAAgB,aAAa,MAAkB,YAAoC;AACjF,QAAO;EAAE,GAAG;EAAM,GAAG;EAAY;;;;AA/D7B,8BAA6B;EAAC;EAAa;EAAc;EAAa;EAAU;EAAgB;AAIhG,qBAAoB,IAAI,mBAAwC;AAsChE,+BAA6D;EACjE;EACA;EACA;EACD"}
@@ -139,6 +139,7 @@ function matchesQuery(entry, query) {
139
139
  if (query.extension && entry.extension !== query.extension) return false;
140
140
  if (query.service && entry.service !== query.service) return false;
141
141
  if (query.requestId && entry.requestId !== query.requestId) return false;
142
+ if (query.sessionKey && entry.sessionKey !== query.sessionKey) return false;
142
143
  if (query.sessionId && entry.sessionId !== query.sessionId) return false;
143
144
  return true;
144
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"log-store.js","names":[],"sources":["../../../../src/utils/logger/log-store.ts"],"sourcesContent":["/**\n * Log Store - Enhanced File-based Log Storage\n * \n * Features:\n * - Query logs across multiple files with filtering\n * - Support for compressed (.gz) log files\n * - Pagination and sorting\n * - Statistics and analytics\n * - Safe log cleanup with actual deletion\n */\n\nimport { \n existsSync, \n mkdirSync, \n readdirSync, \n statSync, \n createReadStream,\n} from 'fs';\nimport { readFile } from 'fs/promises';\nimport { join, basename } from 'path';\nimport { createInterface } from 'readline';\nimport { gunzip } from 'zlib';\nimport { promisify } from 'util';\nimport { Readable } from 'stream';\nimport type { LogLevel, LogFileMeta, LogQuery, LogStats, LogEntry } from './types.js';\nimport { logEntrySearchText, pinoRecordToLogEntry } from './pino-record.js';\n\nconst gunzipAsync = promisify(gunzip);\n\n// ============================================\n// Types\n// ============================================\n\ninterface ParsedLogEntry extends LogEntry {\n _source?: string;\n _lineNumber?: number;\n}\n\n// ============================================\n// Configuration\n// ============================================\n\nconst LOG_DIR = process.env.XOPC_LOG_DIR || join(process.env.HOME || '.', '.xopc', 'logs');\n\nfunction ensureLogDir(): void {\n if (!existsSync(LOG_DIR)) {\n mkdirSync(LOG_DIR, { recursive: true });\n }\n}\n\n// ============================================\n// File Management\n// ============================================\n\n/**\n * Get all log files (including compressed)\n */\nexport function getLogFiles(): LogFileMeta[] {\n ensureLogDir();\n\n const files = readdirSync(LOG_DIR)\n .filter(f => f.endsWith('.log') || f.endsWith('.log.gz'))\n .map(f => {\n const filePath = join(LOG_DIR, f);\n const stats = statSync(filePath);\n \n let type: LogFileMeta['type'] = 'app';\n if (f.includes('error')) type = 'error';\n else if (f.includes('audit')) type = 'audit';\n else if (f.includes('access')) type = 'access';\n\n return {\n name: f,\n path: filePath,\n size: stats.size,\n created: stats.birthtime.toISOString(),\n modified: stats.mtime.toISOString(),\n type,\n };\n })\n .sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());\n\n return files;\n}\n\n/**\n * Get log file path for a specific date and type\n */\nexport function getLogPath(\n date: Date = new Date(), \n type: 'app' | 'error' | 'audit' | 'access' = 'app'\n): string {\n ensureLogDir();\n const dateStr = date.toISOString().split('T')[0];\n return join(LOG_DIR, `${type}-${dateStr}.log`);\n}\n\n/**\n * Get available log files for a date range\n */\nfunction getLogFilesForRange(from: Date, to: Date): LogFileMeta[] {\n const allFiles = getLogFiles();\n \n return allFiles.filter(f => {\n // Extract date from filename (e.g., app-2024-01-01.log)\n const match = f.name.match(/(\\d{4}-\\d{2}-\\d{2})/);\n if (!match) return false;\n \n const fileDate = new Date(match[1]);\n return fileDate >= from && fileDate <= to;\n });\n}\n\n// ============================================\n// Log Parsing\n// ============================================\n\n/**\n * Parse a single log line (JSON format from pino)\n */\nfunction parseLogLine(line: string, source?: string, lineNumber?: number): ParsedLogEntry | null {\n const trimmed = line.trim();\n if (!trimmed) return null;\n\n try {\n const parsed = JSON.parse(trimmed) as Record<string, unknown>;\n const entry = pinoRecordToLogEntry(parsed) as ParsedLogEntry;\n entry._source = source;\n entry._lineNumber = lineNumber;\n return entry;\n } catch {\n return null;\n }\n}\n\n// ============================================\n// Streaming\n// ============================================\n\n/**\n * Create a readable stream for a log file (handles .gz files)\n */\nasync function createLogFileStream(filePath: string): Promise<Readable> {\n if (filePath.endsWith('.gz')) {\n const compressed = await readFile(filePath);\n const decompressed = await gunzipAsync(compressed);\n return Readable.from(decompressed.toString('utf-8').split('\\n'));\n }\n \n return createReadStream(filePath, { encoding: 'utf-8' });\n}\n\n/**\n * Stream and filter log entries from a file\n */\nasync function* streamLogFile(\n filePath: string,\n query: LogQuery = {}\n): AsyncGenerator<ParsedLogEntry> {\n if (!existsSync(filePath)) return;\n\n const fileName = basename(filePath);\n let stream: Readable;\n \n try {\n stream = await createLogFileStream(filePath);\n } catch {\n return;\n }\n\n const rl = createInterface({ \n input: stream,\n crlfDelay: Infinity \n });\n\n let lineNumber = 0;\n\n try {\n for await (const line of rl) {\n lineNumber++;\n const entry = parseLogLine(line, fileName, lineNumber);\n if (!entry) continue;\n\n // Apply filters\n if (!matchesQuery(entry, query)) continue;\n\n yield entry;\n }\n } finally {\n rl.close();\n }\n}\n\n/**\n * Check if a log entry matches the query filters\n */\nfunction matchesQuery(entry: ParsedLogEntry, query: LogQuery): boolean {\n // Filter by levels\n if (query.levels?.length && !query.levels.includes(entry.level as LogLevel)) {\n return false;\n }\n\n // Filter by time range\n if (query.from) {\n const fromDate = new Date(query.from);\n const entryDate = new Date(entry.timestamp);\n if (entryDate < fromDate) return false;\n }\n if (query.to) {\n const toDate = new Date(query.to);\n const entryDate = new Date(entry.timestamp);\n if (entryDate > toDate) return false;\n }\n\n // Filter by keyword (search message, module, phase, err, structured fields)\n if (query.q) {\n const keyword = query.q.toLowerCase();\n if (!logEntrySearchText(entry).includes(keyword)) return false;\n }\n\n if (query.module && entry.module !== query.module) return false;\n if (query.extension && entry.extension !== query.extension) return false;\n if (query.service && entry.service !== query.service) return false;\n if (query.requestId && entry.requestId !== query.requestId) return false;\n if (query.sessionId && entry.sessionId !== query.sessionId) return false;\n\n return true;\n}\n\n// ============================================\n// Query API\n// ============================================\n\n/** Cap matched rows before sort/slice so query stays bounded on huge log dirs. */\nconst QUERY_LOGS_MAX_MATCHED = 25_000;\n\n/**\n * Query logs across multiple files\n */\nexport async function queryLogs(query: LogQuery = {}): Promise<LogEntry[]> {\n ensureLogDir();\n\n const results: ParsedLogEntry[] = [];\n const files = getLogFiles();\n\n // Filter files by date range if specified\n let relevantFiles = files;\n if (query.from || query.to) {\n const fromDate = query.from ? new Date(query.from) : new Date(0);\n const toDate = query.to ? new Date(query.to) : new Date();\n relevantFiles = getLogFilesForRange(fromDate, toDate);\n }\n\n // Collect all matches (files are newest-first; lines in each file are time-asc).\n // Do not stop at `limit` while streaming — that only captured the oldest tail of\n // early files and made \"newest first\" wrong after sort.\n for (const file of relevantFiles) {\n if (results.length >= QUERY_LOGS_MAX_MATCHED) break;\n for await (const entry of streamLogFile(file.path, query)) {\n results.push(entry);\n if (results.length >= QUERY_LOGS_MAX_MATCHED) break;\n }\n }\n\n // Sort by timestamp\n const order = query.order || 'desc';\n results.sort((a, b) => {\n const diff = new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();\n return order === 'desc' ? diff : -diff;\n });\n\n // Apply offset/limit\n const offset = query.offset || 0;\n const limit = query.limit || 100;\n return results.slice(offset, offset + limit).map(({ _source, _lineNumber, ...rest }) => rest);\n}\n\n// ============================================\n// Statistics\n// ============================================\nexport async function getLogModules(): Promise<string[]> {\n const modules = new Set<string>();\n const files = getLogFiles().slice(0, 7);\n\n for (const file of files) {\n for await (const entry of streamLogFile(file.path, { limit: 1000 })) {\n if (entry.module) modules.add(entry.module);\n }\n }\n\n return Array.from(modules).filter(Boolean).sort();\n}\n\n/**\n * Get log statistics by level (sampled from recent files)\n */\nexport async function getFileLogStats(): Promise<LogStats> {\n const files = getLogFiles();\n\n // Count by level (sample from recent files)\n const byLevel: Record<LogLevel, number> = {\n trace: 0,\n debug: 0,\n info: 0,\n warn: 0,\n error: 0,\n fatal: 0,\n silent: 0,\n };\n\n for (const file of files.slice(0, 7)) {\n for await (const entry of streamLogFile(file.path, { limit: 1000 })) {\n if (entry.level in byLevel) {\n byLevel[entry.level as LogLevel]++;\n }\n }\n }\n\n return { byLevel };\n}\n\n// ============================================\n// Error aggregation\n// ============================================\n\nexport interface LogErrorSummaryItem {\n key: string;\n errName: string;\n phase?: string;\n module?: string;\n count: number;\n lastSeen: string;\n sampleMessage: string;\n}\n\nfunction entryMeta(entry: ParsedLogEntry): Record<string, unknown> | undefined {\n if (!entry.meta || typeof entry.meta !== 'object') return undefined;\n return entry.meta as Record<string, unknown>;\n}\n\nfunction extractErrName(entry: ParsedLogEntry): string {\n const meta = entryMeta(entry);\n const raw = entry.err ?? meta?.err;\n if (raw && typeof raw === 'object' && raw !== null) {\n const name = (raw as Record<string, unknown>).name;\n if (typeof name === 'string' && name.trim()) return name;\n const message = (raw as Record<string, unknown>).message;\n if (typeof message === 'string' && message.trim()) return message.slice(0, 120);\n }\n if (typeof entry.errorMessage === 'string' && entry.errorMessage.trim()) {\n return entry.errorMessage.slice(0, 120);\n }\n return entry.message?.slice(0, 120) || 'Error';\n}\n\nfunction summaryKey(entry: ParsedLogEntry): string {\n const errName = extractErrName(entry);\n const meta = entryMeta(entry);\n const phase =\n typeof entry.phase === 'string'\n ? entry.phase\n : typeof meta?.phase === 'string'\n ? meta.phase\n : '';\n const module = entry.module || '';\n return `${errName}::${phase}::${module}`;\n}\n\n/**\n * Aggregate recent error/fatal logs by err name + phase + module.\n */\nexport async function getLogErrorSummary(options?: {\n from?: string;\n to?: string;\n limit?: number;\n}): Promise<LogErrorSummaryItem[]> {\n const limit = options?.limit ?? 20;\n const groups = new Map<string, LogErrorSummaryItem>();\n\n const entries = await queryLogs({\n levels: ['error', 'fatal'],\n from: options?.from,\n to: options?.to,\n limit: 5000,\n order: 'desc',\n });\n\n for (const entry of entries) {\n const key = summaryKey(entry as ParsedLogEntry);\n const parsed = entry as ParsedLogEntry;\n const existing = groups.get(key);\n if (existing) {\n existing.count += 1;\n if (entry.timestamp > existing.lastSeen) {\n existing.lastSeen = entry.timestamp;\n existing.sampleMessage = entry.message;\n }\n continue;\n }\n groups.set(key, {\n key,\n errName: extractErrName(parsed),\n phase:\n typeof parsed.phase === 'string'\n ? parsed.phase\n : typeof entryMeta(parsed)?.phase === 'string'\n ? String(entryMeta(parsed)?.phase)\n : undefined,\n module: parsed.module,\n count: 1,\n lastSeen: entry.timestamp,\n sampleMessage: entry.message,\n });\n }\n\n return Array.from(groups.values())\n .sort((a, b) => b.count - a.count || b.lastSeen.localeCompare(a.lastSeen))\n .slice(0, limit);\n}\n\n// ============================================\n// Log Levels\n// ============================================\n\nconst LOG_LEVELS: LogLevel[] = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n\n/**\n * Get available log levels\n */\nexport function getLogLevels(): LogLevel[] {\n return [...LOG_LEVELS];\n}\n\n// ============================================\n// Exports\n// ============================================\n\nexport { LOG_DIR };\nexport type { LogEntry, LogQuery, LogFileMeta, LogStats } from './types.js';\n"],"mappings":"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"}
1
+ {"version":3,"file":"log-store.js","names":[],"sources":["../../../../src/utils/logger/log-store.ts"],"sourcesContent":["/**\n * Log Store - Enhanced File-based Log Storage\n * \n * Features:\n * - Query logs across multiple files with filtering\n * - Support for compressed (.gz) log files\n * - Pagination and sorting\n * - Statistics and analytics\n * - Safe log cleanup with actual deletion\n */\n\nimport { \n existsSync, \n mkdirSync, \n readdirSync, \n statSync, \n createReadStream,\n} from 'fs';\nimport { readFile } from 'fs/promises';\nimport { join, basename } from 'path';\nimport { createInterface } from 'readline';\nimport { gunzip } from 'zlib';\nimport { promisify } from 'util';\nimport { Readable } from 'stream';\nimport type { LogLevel, LogFileMeta, LogQuery, LogStats, LogEntry } from './types.js';\nimport { logEntrySearchText, pinoRecordToLogEntry } from './pino-record.js';\n\nconst gunzipAsync = promisify(gunzip);\n\n// ============================================\n// Types\n// ============================================\n\ninterface ParsedLogEntry extends LogEntry {\n _source?: string;\n _lineNumber?: number;\n}\n\n// ============================================\n// Configuration\n// ============================================\n\nconst LOG_DIR = process.env.XOPC_LOG_DIR || join(process.env.HOME || '.', '.xopc', 'logs');\n\nfunction ensureLogDir(): void {\n if (!existsSync(LOG_DIR)) {\n mkdirSync(LOG_DIR, { recursive: true });\n }\n}\n\n// ============================================\n// File Management\n// ============================================\n\n/**\n * Get all log files (including compressed)\n */\nexport function getLogFiles(): LogFileMeta[] {\n ensureLogDir();\n\n const files = readdirSync(LOG_DIR)\n .filter(f => f.endsWith('.log') || f.endsWith('.log.gz'))\n .map(f => {\n const filePath = join(LOG_DIR, f);\n const stats = statSync(filePath);\n \n let type: LogFileMeta['type'] = 'app';\n if (f.includes('error')) type = 'error';\n else if (f.includes('audit')) type = 'audit';\n else if (f.includes('access')) type = 'access';\n\n return {\n name: f,\n path: filePath,\n size: stats.size,\n created: stats.birthtime.toISOString(),\n modified: stats.mtime.toISOString(),\n type,\n };\n })\n .sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());\n\n return files;\n}\n\n/**\n * Get log file path for a specific date and type\n */\nexport function getLogPath(\n date: Date = new Date(), \n type: 'app' | 'error' | 'audit' | 'access' = 'app'\n): string {\n ensureLogDir();\n const dateStr = date.toISOString().split('T')[0];\n return join(LOG_DIR, `${type}-${dateStr}.log`);\n}\n\n/**\n * Get available log files for a date range\n */\nfunction getLogFilesForRange(from: Date, to: Date): LogFileMeta[] {\n const allFiles = getLogFiles();\n \n return allFiles.filter(f => {\n // Extract date from filename (e.g., app-2024-01-01.log)\n const match = f.name.match(/(\\d{4}-\\d{2}-\\d{2})/);\n if (!match) return false;\n \n const fileDate = new Date(match[1]);\n return fileDate >= from && fileDate <= to;\n });\n}\n\n// ============================================\n// Log Parsing\n// ============================================\n\n/**\n * Parse a single log line (JSON format from pino)\n */\nfunction parseLogLine(line: string, source?: string, lineNumber?: number): ParsedLogEntry | null {\n const trimmed = line.trim();\n if (!trimmed) return null;\n\n try {\n const parsed = JSON.parse(trimmed) as Record<string, unknown>;\n const entry = pinoRecordToLogEntry(parsed) as ParsedLogEntry;\n entry._source = source;\n entry._lineNumber = lineNumber;\n return entry;\n } catch {\n return null;\n }\n}\n\n// ============================================\n// Streaming\n// ============================================\n\n/**\n * Create a readable stream for a log file (handles .gz files)\n */\nasync function createLogFileStream(filePath: string): Promise<Readable> {\n if (filePath.endsWith('.gz')) {\n const compressed = await readFile(filePath);\n const decompressed = await gunzipAsync(compressed);\n return Readable.from(decompressed.toString('utf-8').split('\\n'));\n }\n \n return createReadStream(filePath, { encoding: 'utf-8' });\n}\n\n/**\n * Stream and filter log entries from a file\n */\nasync function* streamLogFile(\n filePath: string,\n query: LogQuery = {}\n): AsyncGenerator<ParsedLogEntry> {\n if (!existsSync(filePath)) return;\n\n const fileName = basename(filePath);\n let stream: Readable;\n \n try {\n stream = await createLogFileStream(filePath);\n } catch {\n return;\n }\n\n const rl = createInterface({ \n input: stream,\n crlfDelay: Infinity \n });\n\n let lineNumber = 0;\n\n try {\n for await (const line of rl) {\n lineNumber++;\n const entry = parseLogLine(line, fileName, lineNumber);\n if (!entry) continue;\n\n // Apply filters\n if (!matchesQuery(entry, query)) continue;\n\n yield entry;\n }\n } finally {\n rl.close();\n }\n}\n\n/**\n * Check if a log entry matches the query filters\n */\nfunction matchesQuery(entry: ParsedLogEntry, query: LogQuery): boolean {\n // Filter by levels\n if (query.levels?.length && !query.levels.includes(entry.level as LogLevel)) {\n return false;\n }\n\n // Filter by time range\n if (query.from) {\n const fromDate = new Date(query.from);\n const entryDate = new Date(entry.timestamp);\n if (entryDate < fromDate) return false;\n }\n if (query.to) {\n const toDate = new Date(query.to);\n const entryDate = new Date(entry.timestamp);\n if (entryDate > toDate) return false;\n }\n\n // Filter by keyword (search message, module, phase, err, structured fields)\n if (query.q) {\n const keyword = query.q.toLowerCase();\n if (!logEntrySearchText(entry).includes(keyword)) return false;\n }\n\n if (query.module && entry.module !== query.module) return false;\n if (query.extension && entry.extension !== query.extension) return false;\n if (query.service && entry.service !== query.service) return false;\n if (query.requestId && entry.requestId !== query.requestId) return false;\n if (query.sessionKey && entry.sessionKey !== query.sessionKey) return false;\n if (query.sessionId && entry.sessionId !== query.sessionId) return false;\n\n return true;\n}\n\n// ============================================\n// Query API\n// ============================================\n\n/** Cap matched rows before sort/slice so query stays bounded on huge log dirs. */\nconst QUERY_LOGS_MAX_MATCHED = 25_000;\n\n/**\n * Query logs across multiple files\n */\nexport async function queryLogs(query: LogQuery = {}): Promise<LogEntry[]> {\n ensureLogDir();\n\n const results: ParsedLogEntry[] = [];\n const files = getLogFiles();\n\n // Filter files by date range if specified\n let relevantFiles = files;\n if (query.from || query.to) {\n const fromDate = query.from ? new Date(query.from) : new Date(0);\n const toDate = query.to ? new Date(query.to) : new Date();\n relevantFiles = getLogFilesForRange(fromDate, toDate);\n }\n\n // Collect all matches (files are newest-first; lines in each file are time-asc).\n // Do not stop at `limit` while streaming — that only captured the oldest tail of\n // early files and made \"newest first\" wrong after sort.\n for (const file of relevantFiles) {\n if (results.length >= QUERY_LOGS_MAX_MATCHED) break;\n for await (const entry of streamLogFile(file.path, query)) {\n results.push(entry);\n if (results.length >= QUERY_LOGS_MAX_MATCHED) break;\n }\n }\n\n // Sort by timestamp\n const order = query.order || 'desc';\n results.sort((a, b) => {\n const diff = new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();\n return order === 'desc' ? diff : -diff;\n });\n\n // Apply offset/limit\n const offset = query.offset || 0;\n const limit = query.limit || 100;\n return results.slice(offset, offset + limit).map(({ _source, _lineNumber, ...rest }) => rest);\n}\n\n// ============================================\n// Statistics\n// ============================================\nexport async function getLogModules(): Promise<string[]> {\n const modules = new Set<string>();\n const files = getLogFiles().slice(0, 7);\n\n for (const file of files) {\n for await (const entry of streamLogFile(file.path, { limit: 1000 })) {\n if (entry.module) modules.add(entry.module);\n }\n }\n\n return Array.from(modules).filter(Boolean).sort();\n}\n\n/**\n * Get log statistics by level (sampled from recent files)\n */\nexport async function getFileLogStats(): Promise<LogStats> {\n const files = getLogFiles();\n\n // Count by level (sample from recent files)\n const byLevel: Record<LogLevel, number> = {\n trace: 0,\n debug: 0,\n info: 0,\n warn: 0,\n error: 0,\n fatal: 0,\n silent: 0,\n };\n\n for (const file of files.slice(0, 7)) {\n for await (const entry of streamLogFile(file.path, { limit: 1000 })) {\n if (entry.level in byLevel) {\n byLevel[entry.level as LogLevel]++;\n }\n }\n }\n\n return { byLevel };\n}\n\n// ============================================\n// Error aggregation\n// ============================================\n\nexport interface LogErrorSummaryItem {\n key: string;\n errName: string;\n phase?: string;\n module?: string;\n count: number;\n lastSeen: string;\n sampleMessage: string;\n}\n\nfunction entryMeta(entry: ParsedLogEntry): Record<string, unknown> | undefined {\n if (!entry.meta || typeof entry.meta !== 'object') return undefined;\n return entry.meta as Record<string, unknown>;\n}\n\nfunction extractErrName(entry: ParsedLogEntry): string {\n const meta = entryMeta(entry);\n const raw = entry.err ?? meta?.err;\n if (raw && typeof raw === 'object' && raw !== null) {\n const name = (raw as Record<string, unknown>).name;\n if (typeof name === 'string' && name.trim()) return name;\n const message = (raw as Record<string, unknown>).message;\n if (typeof message === 'string' && message.trim()) return message.slice(0, 120);\n }\n if (typeof entry.errorMessage === 'string' && entry.errorMessage.trim()) {\n return entry.errorMessage.slice(0, 120);\n }\n return entry.message?.slice(0, 120) || 'Error';\n}\n\nfunction summaryKey(entry: ParsedLogEntry): string {\n const errName = extractErrName(entry);\n const meta = entryMeta(entry);\n const phase =\n typeof entry.phase === 'string'\n ? entry.phase\n : typeof meta?.phase === 'string'\n ? meta.phase\n : '';\n const module = entry.module || '';\n return `${errName}::${phase}::${module}`;\n}\n\n/**\n * Aggregate recent error/fatal logs by err name + phase + module.\n */\nexport async function getLogErrorSummary(options?: {\n from?: string;\n to?: string;\n limit?: number;\n}): Promise<LogErrorSummaryItem[]> {\n const limit = options?.limit ?? 20;\n const groups = new Map<string, LogErrorSummaryItem>();\n\n const entries = await queryLogs({\n levels: ['error', 'fatal'],\n from: options?.from,\n to: options?.to,\n limit: 5000,\n order: 'desc',\n });\n\n for (const entry of entries) {\n const key = summaryKey(entry as ParsedLogEntry);\n const parsed = entry as ParsedLogEntry;\n const existing = groups.get(key);\n if (existing) {\n existing.count += 1;\n if (entry.timestamp > existing.lastSeen) {\n existing.lastSeen = entry.timestamp;\n existing.sampleMessage = entry.message;\n }\n continue;\n }\n groups.set(key, {\n key,\n errName: extractErrName(parsed),\n phase:\n typeof parsed.phase === 'string'\n ? parsed.phase\n : typeof entryMeta(parsed)?.phase === 'string'\n ? String(entryMeta(parsed)?.phase)\n : undefined,\n module: parsed.module,\n count: 1,\n lastSeen: entry.timestamp,\n sampleMessage: entry.message,\n });\n }\n\n return Array.from(groups.values())\n .sort((a, b) => b.count - a.count || b.lastSeen.localeCompare(a.lastSeen))\n .slice(0, limit);\n}\n\n// ============================================\n// Log Levels\n// ============================================\n\nconst LOG_LEVELS: LogLevel[] = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n\n/**\n * Get available log levels\n */\nexport function getLogLevels(): LogLevel[] {\n return [...LOG_LEVELS];\n}\n\n// ============================================\n// Exports\n// ============================================\n\nexport { LOG_DIR };\nexport type { LogEntry, LogQuery, LogFileMeta, LogStats } from './types.js';\n"],"mappings":"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"}
@@ -18,6 +18,7 @@ function pinoRecordToLogEntry(parsed) {
18
18
  "module",
19
19
  "extension",
20
20
  "requestId",
21
+ "sessionKey",
21
22
  "sessionId",
22
23
  "userId",
23
24
  "correlationId"
@@ -32,6 +33,7 @@ function pinoRecordToLogEntry(parsed) {
32
33
  service: typeof parsed.service === "string" ? parsed.service : void 0,
33
34
  extension: typeof parsed.extension === "string" ? parsed.extension : void 0,
34
35
  requestId: typeof parsed.requestId === "string" ? parsed.requestId : void 0,
36
+ sessionKey: typeof parsed.sessionKey === "string" ? parsed.sessionKey : void 0,
35
37
  sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
36
38
  userId: typeof parsed.userId === "string" ? parsed.userId : void 0,
37
39
  correlationId: typeof parsed.correlationId === "string" ? parsed.correlationId : void 0
@@ -47,6 +49,7 @@ function logEntrySearchText(entry) {
47
49
  entry.service,
48
50
  entry.extension,
49
51
  entry.requestId,
52
+ entry.sessionKey,
50
53
  entry.sessionId,
51
54
  typeof entry.phase === "string" ? entry.phase : void 0,
52
55
  typeof entry.errorMessage === "string" ? entry.errorMessage : void 0
@@ -1 +1 @@
1
- {"version":3,"file":"pino-record.js","names":[],"sources":["../../../../src/utils/logger/pino-record.ts"],"sourcesContent":["/**\n * Shared Pino JSON record → LogEntry conversion for file query and live SSE.\n */\n\nimport type { LogEntry, LogLevel } from './types.js';\n\nconst VALID_LEVELS = new Set<LogLevel>(['trace', 'debug', 'info', 'warn', 'error', 'fatal']);\n\nfunction resolveLevel(parsed: Record<string, unknown>): LogLevel {\n if (typeof parsed.level !== 'string') {\n return 'info';\n }\n const lv = parsed.level.toLowerCase() as LogLevel;\n return VALID_LEVELS.has(lv) ? lv : 'info';\n}\n\n/** Convert a parsed Pino JSON object into a normalized LogEntry. */\nexport function pinoRecordToLogEntry(parsed: Record<string, unknown>): LogEntry {\n const reserved = new Set([\n 'time',\n 'level',\n 'msg',\n 'pid',\n 'host',\n 'service',\n 'version',\n 'module',\n 'extension',\n 'requestId',\n 'sessionId',\n 'userId',\n 'correlationId',\n ]);\n\n const meta: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (!reserved.has(key)) {\n meta[key] = value;\n }\n }\n\n const entry: LogEntry = {\n timestamp: String(parsed.time ?? new Date().toISOString()),\n level: resolveLevel(parsed),\n message: String(parsed.msg ?? ''),\n module: typeof parsed.module === 'string' ? parsed.module : undefined,\n service: typeof parsed.service === 'string' ? parsed.service : undefined,\n extension: typeof parsed.extension === 'string' ? parsed.extension : undefined,\n requestId: typeof parsed.requestId === 'string' ? parsed.requestId : undefined,\n sessionId: typeof parsed.sessionId === 'string' ? parsed.sessionId : undefined,\n userId: typeof parsed.userId === 'string' ? parsed.userId : undefined,\n correlationId: typeof parsed.correlationId === 'string' ? parsed.correlationId : undefined,\n };\n\n if (Object.keys(meta).length > 0) {\n entry.meta = meta;\n }\n\n return entry;\n}\n\n/** Build searchable text from a log entry (query + client-side filter). */\nexport function logEntrySearchText(entry: LogEntry): string {\n const parts: string[] = [\n entry.message,\n entry.module,\n entry.service,\n entry.extension,\n entry.requestId,\n entry.sessionId,\n typeof entry.phase === 'string' ? entry.phase : undefined,\n typeof entry.errorMessage === 'string' ? entry.errorMessage : undefined,\n ];\n\n const meta =\n entry.meta && typeof entry.meta === 'object'\n ? (entry.meta as Record<string, unknown>)\n : undefined;\n const err = entry.err ?? meta?.err;\n if (err && typeof err === 'object' && err !== null) {\n const e = err as Record<string, unknown>;\n if (typeof e.message === 'string') parts.push(e.message);\n if (typeof e.name === 'string') parts.push(e.name);\n if (typeof e.stack === 'string') parts.push(e.stack);\n }\n\n if (entry.meta && typeof entry.meta === 'object') {\n for (const [key, value] of Object.entries(entry.meta)) {\n if (key === 'err') continue;\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n parts.push(String(value));\n }\n }\n }\n\n return parts.filter(Boolean).map(String).join(' ').toLowerCase();\n}\n"],"mappings":";;AAQA,SAAS,aAAa,QAA2C;AAC/D,KAAI,OAAO,OAAO,UAAU,SAC1B,QAAO;CAET,MAAM,KAAK,OAAO,MAAM,aAAa;AACrC,QAAO,aAAa,IAAI,GAAG,GAAG,KAAK;;;AAIrC,SAAgB,qBAAqB,QAA2C;CAC9E,MAAM,WAAW,IAAI,IAAI;EACvB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,OAAgC,EAAE;AACxC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,CAC/C,KAAI,CAAC,SAAS,IAAI,IAAI,CACpB,MAAK,OAAO;CAIhB,MAAM,QAAkB;EACtB,WAAW,OAAO,OAAO,yBAAQ,IAAI,MAAM,EAAC,aAAa,CAAC;EAC1D,OAAO,aAAa,OAAO;EAC3B,SAAS,OAAO,OAAO,OAAO,GAAG;EACjC,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,KAAA;EAC5D,SAAS,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU,KAAA;EAC/D,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY,KAAA;EACrE,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY,KAAA;EACrE,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY,KAAA;EACrE,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,KAAA;EAC5D,eAAe,OAAO,OAAO,kBAAkB,WAAW,OAAO,gBAAgB,KAAA;EAClF;AAED,KAAI,OAAO,KAAK,KAAK,CAAC,SAAS,EAC7B,OAAM,OAAO;AAGf,QAAO;;;AAIT,SAAgB,mBAAmB,OAAyB;CAC1D,MAAM,QAAkB;EACtB,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAA;EAChD,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe,KAAA;EAC/D;CAED,MAAM,OACJ,MAAM,QAAQ,OAAO,MAAM,SAAS,WAC/B,MAAM,OACP,KAAA;CACN,MAAM,MAAM,MAAM,OAAO,MAAM;AAC/B,KAAI,OAAO,OAAO,QAAQ,YAAY,QAAQ,MAAM;EAClD,MAAM,IAAI;AACV,MAAI,OAAO,EAAE,YAAY,SAAU,OAAM,KAAK,EAAE,QAAQ;AACxD,MAAI,OAAO,EAAE,SAAS,SAAU,OAAM,KAAK,EAAE,KAAK;AAClD,MAAI,OAAO,EAAE,UAAU,SAAU,OAAM,KAAK,EAAE,MAAM;;AAGtD,KAAI,MAAM,QAAQ,OAAO,MAAM,SAAS,SACtC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,KAAK,EAAE;AACrD,MAAI,QAAQ,MAAO;AACnB,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,UAC7E,OAAM,KAAK,OAAO,MAAM,CAAC;;AAK/B,QAAO,MAAM,OAAO,QAAQ,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,aAAa;;;;AAzF5D,gBAAe,IAAI,IAAc;EAAC;EAAS;EAAS;EAAQ;EAAQ;EAAS;EAAQ,CAAC"}
1
+ {"version":3,"file":"pino-record.js","names":[],"sources":["../../../../src/utils/logger/pino-record.ts"],"sourcesContent":["/**\n * Shared Pino JSON record → LogEntry conversion for file query and live SSE.\n */\n\nimport type { LogEntry, LogLevel } from './types.js';\n\nconst VALID_LEVELS = new Set<LogLevel>(['trace', 'debug', 'info', 'warn', 'error', 'fatal']);\n\nfunction resolveLevel(parsed: Record<string, unknown>): LogLevel {\n if (typeof parsed.level !== 'string') {\n return 'info';\n }\n const lv = parsed.level.toLowerCase() as LogLevel;\n return VALID_LEVELS.has(lv) ? lv : 'info';\n}\n\n/** Convert a parsed Pino JSON object into a normalized LogEntry. */\nexport function pinoRecordToLogEntry(parsed: Record<string, unknown>): LogEntry {\n const reserved = new Set([\n 'time',\n 'level',\n 'msg',\n 'pid',\n 'host',\n 'service',\n 'version',\n 'module',\n 'extension',\n 'requestId',\n 'sessionKey',\n 'sessionId',\n 'userId',\n 'correlationId',\n ]);\n\n const meta: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (!reserved.has(key)) {\n meta[key] = value;\n }\n }\n\n const entry: LogEntry = {\n timestamp: String(parsed.time ?? new Date().toISOString()),\n level: resolveLevel(parsed),\n message: String(parsed.msg ?? ''),\n module: typeof parsed.module === 'string' ? parsed.module : undefined,\n service: typeof parsed.service === 'string' ? parsed.service : undefined,\n extension: typeof parsed.extension === 'string' ? parsed.extension : undefined,\n requestId: typeof parsed.requestId === 'string' ? parsed.requestId : undefined,\n sessionKey: typeof parsed.sessionKey === 'string' ? parsed.sessionKey : undefined,\n sessionId: typeof parsed.sessionId === 'string' ? parsed.sessionId : undefined,\n userId: typeof parsed.userId === 'string' ? parsed.userId : undefined,\n correlationId: typeof parsed.correlationId === 'string' ? parsed.correlationId : undefined,\n };\n\n if (Object.keys(meta).length > 0) {\n entry.meta = meta;\n }\n\n return entry;\n}\n\n/** Build searchable text from a log entry (query + client-side filter). */\nexport function logEntrySearchText(entry: LogEntry): string {\n const parts: string[] = [\n entry.message,\n entry.module,\n entry.service,\n entry.extension,\n entry.requestId,\n entry.sessionKey,\n entry.sessionId,\n typeof entry.phase === 'string' ? entry.phase : undefined,\n typeof entry.errorMessage === 'string' ? entry.errorMessage : undefined,\n ];\n\n const meta =\n entry.meta && typeof entry.meta === 'object'\n ? (entry.meta as Record<string, unknown>)\n : undefined;\n const err = entry.err ?? meta?.err;\n if (err && typeof err === 'object' && err !== null) {\n const e = err as Record<string, unknown>;\n if (typeof e.message === 'string') parts.push(e.message);\n if (typeof e.name === 'string') parts.push(e.name);\n if (typeof e.stack === 'string') parts.push(e.stack);\n }\n\n if (entry.meta && typeof entry.meta === 'object') {\n for (const [key, value] of Object.entries(entry.meta)) {\n if (key === 'err') continue;\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n parts.push(String(value));\n }\n }\n }\n\n return parts.filter(Boolean).map(String).join(' ').toLowerCase();\n}\n"],"mappings":";;AAQA,SAAS,aAAa,QAA2C;AAC/D,KAAI,OAAO,OAAO,UAAU,SAC1B,QAAO;CAET,MAAM,KAAK,OAAO,MAAM,aAAa;AACrC,QAAO,aAAa,IAAI,GAAG,GAAG,KAAK;;;AAIrC,SAAgB,qBAAqB,QAA2C;CAC9E,MAAM,WAAW,IAAI,IAAI;EACvB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,OAAgC,EAAE;AACxC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,CAC/C,KAAI,CAAC,SAAS,IAAI,IAAI,CACpB,MAAK,OAAO;CAIhB,MAAM,QAAkB;EACtB,WAAW,OAAO,OAAO,yBAAQ,IAAI,MAAM,EAAC,aAAa,CAAC;EAC1D,OAAO,aAAa,OAAO;EAC3B,SAAS,OAAO,OAAO,OAAO,GAAG;EACjC,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,KAAA;EAC5D,SAAS,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU,KAAA;EAC/D,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY,KAAA;EACrE,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY,KAAA;EACrE,YAAY,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa,KAAA;EACxE,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY,KAAA;EACrE,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,KAAA;EAC5D,eAAe,OAAO,OAAO,kBAAkB,WAAW,OAAO,gBAAgB,KAAA;EAClF;AAED,KAAI,OAAO,KAAK,KAAK,CAAC,SAAS,EAC7B,OAAM,OAAO;AAGf,QAAO;;;AAIT,SAAgB,mBAAmB,OAAyB;CAC1D,MAAM,QAAkB;EACtB,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAA;EAChD,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe,KAAA;EAC/D;CAED,MAAM,OACJ,MAAM,QAAQ,OAAO,MAAM,SAAS,WAC/B,MAAM,OACP,KAAA;CACN,MAAM,MAAM,MAAM,OAAO,MAAM;AAC/B,KAAI,OAAO,OAAO,QAAQ,YAAY,QAAQ,MAAM;EAClD,MAAM,IAAI;AACV,MAAI,OAAO,EAAE,YAAY,SAAU,OAAM,KAAK,EAAE,QAAQ;AACxD,MAAI,OAAO,EAAE,SAAS,SAAU,OAAM,KAAK,EAAE,KAAK;AAClD,MAAI,OAAO,EAAE,UAAU,SAAU,OAAM,KAAK,EAAE,MAAM;;AAGtD,KAAI,MAAM,QAAQ,OAAO,MAAM,SAAS,SACtC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,KAAK,EAAE;AACrD,MAAI,QAAQ,MAAO;AACnB,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,UAC7E,OAAM,KAAK,OAAO,MAAM,CAAC;;AAK/B,QAAO,MAAM,OAAO,QAAQ,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,aAAa;;;;AA5F5D,gBAAe,IAAI,IAAc;EAAC;EAAS;EAAS;EAAQ;EAAQ;EAAS;EAAQ,CAAC"}
@@ -15,6 +15,7 @@ export interface LogEntry {
15
15
  service?: string;
16
16
  extension?: string;
17
17
  requestId?: string;
18
+ sessionKey?: string;
18
19
  sessionId?: string;
19
20
  userId?: string;
20
21
  [key: string]: unknown;
@@ -43,6 +44,8 @@ export interface LogContext {
43
44
  /** Request/operation ID for tracing */
44
45
  requestId?: string;
45
46
  /** Session ID for user tracking */
47
+ sessionKey?: string;
48
+ /** Active transcript/session instance id */
46
49
  sessionId?: string;
47
50
  /** Cross-service trace id when distinct from requestId */
48
51
  correlationId?: string;
@@ -120,6 +123,8 @@ export interface LogQuery {
120
123
  /** Filter by request ID */
121
124
  requestId?: string;
122
125
  /** Filter by session ID */
126
+ sessionKey?: string;
127
+ /** Filter by active transcript/session instance id */
123
128
  sessionId?: string;
124
129
  /** Pagination offset */
125
130
  offset?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../../src/utils/logger/types.ts"],"sourcesContent":["/**\n * Logger Types\n * \n * Centralized type definitions for the logging system.\n */\n\nimport type { Logger } from 'pino';\n\n/**\n * Basic log entry structure\n */\nexport interface LogEntry {\n timestamp: string;\n level: LogLevel;\n message: string;\n module?: string;\n service?: string;\n extension?: string;\n requestId?: string;\n sessionId?: string;\n userId?: string;\n [key: string]: unknown;\n}\n\n/**\n * Log levels in order of severity\n */\nexport const LogLevel = {\n TRACE: 'trace',\n DEBUG: 'debug',\n INFO: 'info',\n WARN: 'warn',\n ERROR: 'error',\n FATAL: 'fatal',\n SILENT: 'silent',\n} as const;\n\nexport type LogLevel = typeof LogLevel[keyof typeof LogLevel];\n\n/**\n * Log level numeric values (for comparison)\n */\nexport const LogLevelValue: Record<LogLevel, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n silent: Number.MAX_VALUE,\n};\n\n/**\n * Common log context fields\n */\nexport interface LogContext {\n /** Request/operation ID for tracing */\n requestId?: string;\n /** Session ID for user tracking */\n sessionId?: string;\n /** Cross-service trace id when distinct from requestId */\n correlationId?: string;\n /** User ID */\n userId?: string;\n /** Module/component name */\n module?: string;\n /** Extension name */\n extension?: string;\n /** Service name */\n service?: string;\n /** Additional context */\n [key: string]: unknown;\n}\n\n/**\n * Extended logger with context support\n */\nexport interface ContextualLogger extends Logger {\n /**\n * Set default context for all subsequent logs\n */\n withContext(context: LogContext): ContextualLogger;\n}\n\n/**\n * Logger configuration options\n */\nexport interface LoggerConfig {\n /** Minimum log level */\n level: LogLevel;\n /** Log directory */\n logDir: string;\n /** Enable console output */\n consoleOutput: boolean;\n /** Enable file output */\n fileOutput: boolean;\n /** Enable error-only file output */\n errorFileOutput: boolean;\n /** Log rotation: max days to keep */\n retentionDays: number;\n /** Log rotation: max file size in MB */\n maxFileSizeMB: number;\n /** Enable pretty print for console (dev only) */\n prettyPrint: boolean;\n}\n\n/**\n * Log file metadata\n */\nexport interface LogFileMeta {\n name: string;\n path: string;\n size: number;\n created: string;\n modified: string;\n type: 'app' | 'error' | 'audit' | 'access';\n lines?: number;\n}\n\n/**\n * Log query options\n */\nexport interface LogQuery {\n /** Filter by log levels */\n levels?: LogLevel[];\n /** Start timestamp (ISO 8601) */\n from?: string;\n /** End timestamp (ISO 8601) */\n to?: string;\n /** Keyword search */\n q?: string;\n /** Filter by module */\n module?: string;\n /** Filter by extension */\n extension?: string;\n /** Filter by service */\n service?: string;\n /** Filter by request ID */\n requestId?: string;\n /** Filter by session ID */\n sessionId?: string;\n /** Pagination offset */\n offset?: number;\n /** Pagination limit */\n limit?: number;\n /** Sort order: 'asc' | 'desc' */\n order?: 'asc' | 'desc';\n}\n\n/**\n * Log statistics\n */\nexport interface LogStats {\n byLevel: Record<LogLevel, number>;\n}\n\n/**\n * Log rotation result\n */\nexport interface RotationResult {\n rotated: number;\n deleted: number;\n compressed: number;\n errors: string[];\n}\n"],"mappings":";;;;AA2BA,MAAa,WAAW;CACtB,OAAO;CACP,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;CACP,QAAQ;CACT;;;;AAOD,MAAa,gBAA0C;CACrD,OAAO;CACP,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;CACP,QAAQ,OAAO;CAChB"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../../src/utils/logger/types.ts"],"sourcesContent":["/**\n * Logger Types\n * \n * Centralized type definitions for the logging system.\n */\n\nimport type { Logger } from 'pino';\n\n/**\n * Basic log entry structure\n */\nexport interface LogEntry {\n timestamp: string;\n level: LogLevel;\n message: string;\n module?: string;\n service?: string;\n extension?: string;\n requestId?: string;\n sessionKey?: string;\n sessionId?: string;\n userId?: string;\n [key: string]: unknown;\n}\n\n/**\n * Log levels in order of severity\n */\nexport const LogLevel = {\n TRACE: 'trace',\n DEBUG: 'debug',\n INFO: 'info',\n WARN: 'warn',\n ERROR: 'error',\n FATAL: 'fatal',\n SILENT: 'silent',\n} as const;\n\nexport type LogLevel = typeof LogLevel[keyof typeof LogLevel];\n\n/**\n * Log level numeric values (for comparison)\n */\nexport const LogLevelValue: Record<LogLevel, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n silent: Number.MAX_VALUE,\n};\n\n/**\n * Common log context fields\n */\nexport interface LogContext {\n /** Request/operation ID for tracing */\n requestId?: string;\n /** Session ID for user tracking */\n sessionKey?: string;\n /** Active transcript/session instance id */\n sessionId?: string;\n /** Cross-service trace id when distinct from requestId */\n correlationId?: string;\n /** User ID */\n userId?: string;\n /** Module/component name */\n module?: string;\n /** Extension name */\n extension?: string;\n /** Service name */\n service?: string;\n /** Additional context */\n [key: string]: unknown;\n}\n\n/**\n * Extended logger with context support\n */\nexport interface ContextualLogger extends Logger {\n /**\n * Set default context for all subsequent logs\n */\n withContext(context: LogContext): ContextualLogger;\n}\n\n/**\n * Logger configuration options\n */\nexport interface LoggerConfig {\n /** Minimum log level */\n level: LogLevel;\n /** Log directory */\n logDir: string;\n /** Enable console output */\n consoleOutput: boolean;\n /** Enable file output */\n fileOutput: boolean;\n /** Enable error-only file output */\n errorFileOutput: boolean;\n /** Log rotation: max days to keep */\n retentionDays: number;\n /** Log rotation: max file size in MB */\n maxFileSizeMB: number;\n /** Enable pretty print for console (dev only) */\n prettyPrint: boolean;\n}\n\n/**\n * Log file metadata\n */\nexport interface LogFileMeta {\n name: string;\n path: string;\n size: number;\n created: string;\n modified: string;\n type: 'app' | 'error' | 'audit' | 'access';\n lines?: number;\n}\n\n/**\n * Log query options\n */\nexport interface LogQuery {\n /** Filter by log levels */\n levels?: LogLevel[];\n /** Start timestamp (ISO 8601) */\n from?: string;\n /** End timestamp (ISO 8601) */\n to?: string;\n /** Keyword search */\n q?: string;\n /** Filter by module */\n module?: string;\n /** Filter by extension */\n extension?: string;\n /** Filter by service */\n service?: string;\n /** Filter by request ID */\n requestId?: string;\n /** Filter by session ID */\n sessionKey?: string;\n /** Filter by active transcript/session instance id */\n sessionId?: string;\n /** Pagination offset */\n offset?: number;\n /** Pagination limit */\n limit?: number;\n /** Sort order: 'asc' | 'desc' */\n order?: 'asc' | 'desc';\n}\n\n/**\n * Log statistics\n */\nexport interface LogStats {\n byLevel: Record<LogLevel, number>;\n}\n\n/**\n * Log rotation result\n */\nexport interface RotationResult {\n rotated: number;\n deleted: number;\n compressed: number;\n errors: string[];\n}\n"],"mappings":";;;;AA4BA,MAAa,WAAW;CACtB,OAAO;CACP,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;CACP,QAAQ;CACT;;;;AAOD,MAAa,gBAA0C;CACrD,OAAO;CACP,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;CACP,QAAQ,OAAO;CAChB"}
@@ -20,7 +20,19 @@ var WorkflowSessionBridge = class {
20
20
  const goalText = formatWorkflowGoalUserMessage(params.definitionId, params.goal);
21
21
  const sessionName = truncateSessionName(params.goal.trim() || params.definitionTitle || params.definitionId);
22
22
  const store = this.gateway.sessionIndexInstance.getStore();
23
- await store.resolveTranscriptPath(sessionKey);
23
+ await store.resolveTranscriptPath(sessionKey, { metadata: {
24
+ sessionType: WORKFLOW_SESSION_TYPE,
25
+ hiddenFromSessionList: true,
26
+ sourceChannel: "workflow",
27
+ sourceChatId: params.runId,
28
+ routing: {
29
+ agentId: params.agentId,
30
+ source: "workflow",
31
+ accountId: "default",
32
+ peerKind: "run",
33
+ peerId: params.runId
34
+ }
35
+ } });
24
36
  await store.updateMetadata(sessionKey, {
25
37
  sessionType: WORKFLOW_SESSION_TYPE,
26
38
  hiddenFromSessionList: true,
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-session-bridge.js","names":[],"sources":["../../../../src/workflows/service/workflow-session-bridge.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { renderWorkflowText } from '../../agent/workflow/snapshot.js';\nimport type { SessionStore } from '../../session/store.js';\nimport { SessionStatus } from '../../session/types.js';\nimport type { WorkflowRunView } from '../domain/index.js';\nimport { isTerminalWorkflowRunStatus } from '../domain/index.js';\nimport { GoalWorkflowJudge } from '../../goals/index.js';\n\nimport { runViewToSnapshot } from './run-view-to-snapshot.js';\nimport { buildWorkflowRunSessionKey } from './workflow-session-key.js';\n\nexport const WORKFLOW_SESSION_TYPE = 'workflow-run';\nexport const WORKFLOW_RUN_LINK_CONTEXT_KIND = 'workflow-run-link';\n\nexport interface PrepareWorkflowRunSessionParams {\n runId: string;\n agentId: string;\n definitionId: string;\n definitionTitle: string;\n goal: string;\n parentSessionKey?: string;\n}\n\nexport interface PrepareWorkflowRunSessionResult {\n sessionKey: string;\n}\n\nexport class WorkflowSessionBridge {\n private readonly terminalPersistedRunIds = new Set<string>();\n\n constructor(private readonly gateway: GatewayWorkflowHost) {}\n\n async prepareRunSession(params: PrepareWorkflowRunSessionParams): Promise<PrepareWorkflowRunSessionResult> {\n const sessionKey = buildWorkflowRunSessionKey(params.agentId, params.runId);\n const goalText = formatWorkflowGoalUserMessage(params.definitionId, params.goal);\n const sessionName = truncateSessionName(params.goal.trim() || params.definitionTitle || params.definitionId);\n\n const store = this.gateway.sessionIndexInstance.getStore();\n await store.resolveTranscriptPath(sessionKey);\n await store.updateMetadata(sessionKey, {\n sessionType: WORKFLOW_SESSION_TYPE,\n hiddenFromSessionList: true,\n workflowRunId: params.runId,\n workflowDefinitionId: params.definitionId,\n name: sessionName,\n tags: ['workflow', params.definitionId],\n customData: {\n workflowRunId: params.runId,\n workflowDefinitionId: params.definitionId,\n workflowGoal: params.goal,\n ...(params.parentSessionKey ? { parentSessionKey: params.parentSessionKey } : {}),\n },\n });\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'user',\n content: [{ type: 'text', text: goalText }],\n timestamp: Date.now(),\n });\n\n if (params.parentSessionKey?.trim()) {\n await this.writeParentRunLink({\n parentSessionKey: params.parentSessionKey.trim(),\n runId: params.runId,\n workflowSessionKey: sessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: 'running',\n });\n }\n\n this.gateway.emit('session.updated', { key: sessionKey, name: sessionName });\n return { sessionKey };\n }\n\n async handleRunViewUpdated(view: WorkflowRunView): Promise<void> {\n const runId = view.run.id;\n const sessionKey = view.run.metadata?.sessionKey?.trim();\n if (!sessionKey || !isTerminalWorkflowRunStatus(view.run.status)) {\n return;\n }\n if (this.terminalPersistedRunIds.has(runId)) {\n return;\n }\n this.terminalPersistedRunIds.add(runId);\n\n await this.persistTerminalTranscript(sessionKey, view);\n\n const parentSessionKey = readParentSessionKey(view);\n if (parentSessionKey) {\n await this.writeParentRunLink({\n parentSessionKey,\n runId,\n workflowSessionKey: sessionKey,\n definitionId: view.run.definitionId,\n goal: view.run.goal,\n status: view.run.status,\n });\n }\n await new GoalWorkflowJudge().handleTerminalWorkflowRun({\n config: this.gateway.currentConfig,\n view,\n sessionKey,\n });\n }\n\n private async persistTerminalTranscript(sessionKey: string, view: WorkflowRunView): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const snapshot = runViewToSnapshot(view);\n const toolCallId = randomUUID();\n const completed = view.run.status === 'succeeded';\n const resultText = renderWorkflowText(snapshot, completed, { showResultPreviews: true });\n const envelope = {\n content: [{ type: 'text', text: resultText }],\n details: snapshot,\n };\n const isError = view.run.status === 'failed' || view.run.status === 'timeout';\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'assistant',\n content: [\n {\n type: 'toolCall',\n id: toolCallId,\n name: 'workflow',\n arguments: { name: view.run.definitionId },\n },\n ],\n timestamp: Date.now(),\n } as unknown as Parameters<SessionStore['appendTranscriptMessage']>[1]);\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'toolResult',\n toolCallId,\n content: [{ type: 'text', text: JSON.stringify(envelope) }],\n details: snapshot,\n isError,\n timestamp: Date.now(),\n } as unknown as Parameters<SessionStore['appendTranscriptMessage']>[1]);\n\n await store.updateMetadata(sessionKey, {\n status: SessionStatus.ACTIVE,\n });\n }\n\n private async writeParentRunLink(params: {\n parentSessionKey: string;\n runId: string;\n workflowSessionKey: string;\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n }): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const text = formatParentRunLinkText(params);\n await store.appendTranscriptContextEntry(params.parentSessionKey, {\n kind: 'context',\n id: `workflow-run-link:${params.runId}`,\n text,\n data: {\n kind: WORKFLOW_RUN_LINK_CONTEXT_KIND,\n runId: params.runId,\n workflowSessionKey: params.workflowSessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: params.status,\n },\n createdAt: new Date().toISOString(),\n });\n }\n}\n\nfunction formatWorkflowGoalUserMessage(definitionId: string, goal: string): string {\n const trimmedGoal = goal.trim();\n if (trimmedGoal) {\n return `Run workflow \\`${definitionId}\\`:\\n\\n${trimmedGoal}`;\n }\n return `Run workflow \\`${definitionId}\\``;\n}\n\nfunction truncateSessionName(name: string): string {\n const trimmed = name.trim();\n if (trimmed.length <= 80) return trimmed;\n return `${trimmed.slice(0, 77)}…`;\n}\n\nfunction readParentSessionKey(view: WorkflowRunView): string | null {\n if (view.run.source.kind === 'chat') {\n const originKey = view.run.source.sessionKey?.trim();\n if (originKey) return originKey;\n }\n const customParent = view.run.metadata?.origin?.sessionKey?.trim();\n if (customParent && view.run.metadata?.triggerSource === 'chat') {\n return customParent;\n }\n return null;\n}\n\nexport function formatParentRunLinkText(params: {\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n}): string {\n const label = params.goal.trim() || params.definitionId;\n if (params.status === 'running' || params.status === 'queued') {\n return `Workflow \\`${params.definitionId}\\` is running: ${label}`;\n }\n if (params.status === 'succeeded') {\n return `Workflow \\`${params.definitionId}\\` completed: ${label}`;\n }\n return `Workflow \\`${params.definitionId}\\` finished (${params.status}): ${label}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"workflow-session-bridge.js","names":[],"sources":["../../../../src/workflows/service/workflow-session-bridge.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { renderWorkflowText } from '../../agent/workflow/snapshot.js';\nimport type { SessionStore } from '../../session/store.js';\nimport { SessionStatus } from '../../session/types.js';\nimport type { WorkflowRunView } from '../domain/index.js';\nimport { isTerminalWorkflowRunStatus } from '../domain/index.js';\nimport { GoalWorkflowJudge } from '../../goals/index.js';\n\nimport { runViewToSnapshot } from './run-view-to-snapshot.js';\nimport { buildWorkflowRunSessionKey } from './workflow-session-key.js';\n\nexport const WORKFLOW_SESSION_TYPE = 'workflow-run';\nexport const WORKFLOW_RUN_LINK_CONTEXT_KIND = 'workflow-run-link';\n\nexport interface PrepareWorkflowRunSessionParams {\n runId: string;\n agentId: string;\n definitionId: string;\n definitionTitle: string;\n goal: string;\n parentSessionKey?: string;\n}\n\nexport interface PrepareWorkflowRunSessionResult {\n sessionKey: string;\n}\n\nexport class WorkflowSessionBridge {\n private readonly terminalPersistedRunIds = new Set<string>();\n\n constructor(private readonly gateway: GatewayWorkflowHost) {}\n\n async prepareRunSession(params: PrepareWorkflowRunSessionParams): Promise<PrepareWorkflowRunSessionResult> {\n const sessionKey = buildWorkflowRunSessionKey(params.agentId, params.runId);\n const goalText = formatWorkflowGoalUserMessage(params.definitionId, params.goal);\n const sessionName = truncateSessionName(params.goal.trim() || params.definitionTitle || params.definitionId);\n\n const store = this.gateway.sessionIndexInstance.getStore();\n await store.resolveTranscriptPath(sessionKey, {\n metadata: {\n sessionType: WORKFLOW_SESSION_TYPE,\n hiddenFromSessionList: true,\n sourceChannel: 'workflow',\n sourceChatId: params.runId,\n routing: {\n agentId: params.agentId,\n source: 'workflow',\n accountId: 'default',\n peerKind: 'run',\n peerId: params.runId,\n },\n },\n });\n await store.updateMetadata(sessionKey, {\n sessionType: WORKFLOW_SESSION_TYPE,\n hiddenFromSessionList: true,\n workflowRunId: params.runId,\n workflowDefinitionId: params.definitionId,\n name: sessionName,\n tags: ['workflow', params.definitionId],\n customData: {\n workflowRunId: params.runId,\n workflowDefinitionId: params.definitionId,\n workflowGoal: params.goal,\n ...(params.parentSessionKey ? { parentSessionKey: params.parentSessionKey } : {}),\n },\n });\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'user',\n content: [{ type: 'text', text: goalText }],\n timestamp: Date.now(),\n });\n\n if (params.parentSessionKey?.trim()) {\n await this.writeParentRunLink({\n parentSessionKey: params.parentSessionKey.trim(),\n runId: params.runId,\n workflowSessionKey: sessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: 'running',\n });\n }\n\n this.gateway.emit('session.updated', { key: sessionKey, name: sessionName });\n return { sessionKey };\n }\n\n async handleRunViewUpdated(view: WorkflowRunView): Promise<void> {\n const runId = view.run.id;\n const sessionKey = view.run.metadata?.sessionKey?.trim();\n if (!sessionKey || !isTerminalWorkflowRunStatus(view.run.status)) {\n return;\n }\n if (this.terminalPersistedRunIds.has(runId)) {\n return;\n }\n this.terminalPersistedRunIds.add(runId);\n\n await this.persistTerminalTranscript(sessionKey, view);\n\n const parentSessionKey = readParentSessionKey(view);\n if (parentSessionKey) {\n await this.writeParentRunLink({\n parentSessionKey,\n runId,\n workflowSessionKey: sessionKey,\n definitionId: view.run.definitionId,\n goal: view.run.goal,\n status: view.run.status,\n });\n }\n await new GoalWorkflowJudge().handleTerminalWorkflowRun({\n config: this.gateway.currentConfig,\n view,\n sessionKey,\n });\n }\n\n private async persistTerminalTranscript(sessionKey: string, view: WorkflowRunView): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const snapshot = runViewToSnapshot(view);\n const toolCallId = randomUUID();\n const completed = view.run.status === 'succeeded';\n const resultText = renderWorkflowText(snapshot, completed, { showResultPreviews: true });\n const envelope = {\n content: [{ type: 'text', text: resultText }],\n details: snapshot,\n };\n const isError = view.run.status === 'failed' || view.run.status === 'timeout';\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'assistant',\n content: [\n {\n type: 'toolCall',\n id: toolCallId,\n name: 'workflow',\n arguments: { name: view.run.definitionId },\n },\n ],\n timestamp: Date.now(),\n } as unknown as Parameters<SessionStore['appendTranscriptMessage']>[1]);\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'toolResult',\n toolCallId,\n content: [{ type: 'text', text: JSON.stringify(envelope) }],\n details: snapshot,\n isError,\n timestamp: Date.now(),\n } as unknown as Parameters<SessionStore['appendTranscriptMessage']>[1]);\n\n await store.updateMetadata(sessionKey, {\n status: SessionStatus.ACTIVE,\n });\n }\n\n private async writeParentRunLink(params: {\n parentSessionKey: string;\n runId: string;\n workflowSessionKey: string;\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n }): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const text = formatParentRunLinkText(params);\n await store.appendTranscriptContextEntry(params.parentSessionKey, {\n kind: 'context',\n id: `workflow-run-link:${params.runId}`,\n text,\n data: {\n kind: WORKFLOW_RUN_LINK_CONTEXT_KIND,\n runId: params.runId,\n workflowSessionKey: params.workflowSessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: params.status,\n },\n createdAt: new Date().toISOString(),\n });\n }\n}\n\nfunction formatWorkflowGoalUserMessage(definitionId: string, goal: string): string {\n const trimmedGoal = goal.trim();\n if (trimmedGoal) {\n return `Run workflow \\`${definitionId}\\`:\\n\\n${trimmedGoal}`;\n }\n return `Run workflow \\`${definitionId}\\``;\n}\n\nfunction truncateSessionName(name: string): string {\n const trimmed = name.trim();\n if (trimmed.length <= 80) return trimmed;\n return `${trimmed.slice(0, 77)}…`;\n}\n\nfunction readParentSessionKey(view: WorkflowRunView): string | null {\n if (view.run.source.kind === 'chat') {\n const originKey = view.run.source.sessionKey?.trim();\n if (originKey) return originKey;\n }\n const customParent = view.run.metadata?.origin?.sessionKey?.trim();\n if (customParent && view.run.metadata?.triggerSource === 'chat') {\n return customParent;\n }\n return null;\n}\n\nexport function formatParentRunLinkText(params: {\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n}): string {\n const label = params.goal.trim() || params.definitionId;\n if (params.status === 'running' || params.status === 'queued') {\n return `Workflow \\`${params.definitionId}\\` is running: ${label}`;\n }\n if (params.status === 'succeeded') {\n return `Workflow \\`${params.definitionId}\\` completed: ${label}`;\n }\n return `Workflow \\`${params.definitionId}\\` finished (${params.status}): ${label}`;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xopcai/xopc",
3
- "version": "0.0.113",
3
+ "version": "0.0.114",
4
4
  "description": "Local-first Goal Loop OS for long-term AI work across terminal, web, desktop, mobile app, and messengers.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -1,6 +0,0 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{a as t,n,t as r}from"./vendor-react-BOUWij0V.js";import{t as i}from"./cn-JdwAhgNB.js";import{t as a}from"./messages-CkT-lcgP.js";import{t as o}from"./locale-store-DjbfSsfA.js";import{i as s,t as c}from"./fetch-NZmjSXLl.js";import{r as l}from"./toast-z0toXu32.js";import{B as u,Da as d,Ds as f,Go as p,Jo as m,Mo as h,Ni as g,Oa as _,Vi as v,Wo as y,Xt as b,Zo as x,_i as S,aa as C,ba as w,ca as T,ci as E,ea as D,gi as O,ka as k,ko as A,mi as j,p as M,qa as N,sa as P,ts as F,wa as I,xi as L,yo as R,za as ee,zi as z,zo as B}from"./index-Cxm6xsps.js";import{t as te}from"./settings-advanced-gate-D9sva86V.js";import{n as V,t as H}from"./settings-form-section-Dq-83cQd.js";import{i as U,n as W,o as G}from"./use-settings-tab-guard-Bw_qkRQE.js";import{l as K}from"./config-api-Bf5mjpu7.js";import{a as q,i as J,n as Y,t as ne}from"./use-agent-defaults-form-BVRvkK7m.js";import{i as re}from"./gateway-config-api-CaXBt-9R.js";var X=e(t(),1),Z=n(),Q=r();function ie(e){switch(e){case`ready`:return`bg-emerald-500`;case`not_installed`:case`checking`:return`bg-amber-500`;case`error`:return`bg-red-500`;default:return`bg-fg-subtle/60`}}function ae(e){let t=(0,Z.c)(28),{value:n,onChange:r,onOpenConfig:a,options:o,m:s}=e,c;if(t[0]!==s.browserGoToConfigure||t[1]!==s.browserPickerSubtitle||t[2]!==s.browserPickerTitle||t[3]!==r||t[4]!==a||t[5]!==o||t[6]!==n){let e=o.find(e=>e.value===n)??o[0],l;t[8]===s.browserPickerTitle?l=t[9]:(l=(0,Q.jsx)(`label`,{htmlFor:`browser-backend-select`,className:`text-sm font-medium text-fg`,children:s.browserPickerTitle}),t[8]=s.browserPickerTitle,t[9]=l);let u;t[10]===s.browserPickerSubtitle?u=t[11]:(u=(0,Q.jsx)(`p`,{className:`text-xs leading-relaxed text-fg-muted`,children:s.browserPickerSubtitle}),t[10]=s.browserPickerSubtitle,t[11]=u);let d;t[12]!==l||t[13]!==u?(d=(0,Q.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[l,u]}),t[12]=l,t[13]=u,t[14]=d):d=t[14];let f;t[15]===Symbol.for(`react.memo_cache_sentinel`)?(f=i(q(),`min-w-0 flex-1 sm:max-w-md`),t[15]=f):f=t[15];let p;t[16]===r?p=t[17]:(p=e=>r(e.target.value),t[16]=r,t[17]=p);let m=s.browserPickerTitle,h;t[18]===o?h=t[19]:(h=o.map(oe),t[18]=o,t[19]=h);let g;t[20]!==s.browserPickerTitle||t[21]!==p||t[22]!==h||t[23]!==n?(g=(0,Q.jsx)(`select`,{id:`browser-backend-select`,className:f,value:n,onChange:p,"aria-label":m,children:h}),t[20]=s.browserPickerTitle,t[21]=p,t[22]=h,t[23]=n,t[24]=g):g=t[24];let _=a?(0,Q.jsxs)(`button`,{type:`button`,className:i(`inline-flex shrink-0 items-center justify-center gap-1 rounded-lg border border-edge bg-surface-panel px-3 py-2 text-xs font-medium text-accent`,`transition-colors hover:border-edge-strong hover:bg-surface-hover`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-base`),onClick:()=>a(n),"aria-label":`${e?.name??n} — ${s.browserGoToConfigure}`,children:[(0,Q.jsx)(`span`,{children:s.browserGoToConfigure}),(0,Q.jsx)(F,{className:`size-4 shrink-0`,"aria-hidden":!0})]}):null,v;t[25]!==_||t[26]!==g?(v=(0,Q.jsxs)(`div`,{className:`flex flex-col gap-2 sm:flex-row sm:items-start sm:gap-2`,children:[g,_]}),t[25]=_,t[26]=g,t[27]=v):v=t[27],c=(0,Q.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[d,v,e?(0,Q.jsxs)(`div`,{className:`flex flex-col gap-1.5 rounded-lg border border-edge-subtle bg-surface-panel px-3 py-2.5`,children:[(0,Q.jsx)(`div`,{className:`flex flex-wrap items-center gap-2`,children:e.statusLabel?(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-[11px] font-medium text-fg-muted`,"aria-label":e.statusLabel,children:[(0,Q.jsx)(`span`,{className:i(`inline-block size-1.5 rounded-full`,ie(e.status)),"aria-hidden":!0}),e.statusLabel]}):null}),(0,Q.jsx)(`p`,{className:`text-xs leading-relaxed text-fg-muted`,children:e.tagline})]}):null]}),t[0]=s.browserGoToConfigure,t[1]=s.browserPickerSubtitle,t[2]=s.browserPickerTitle,t[3]=r,t[4]=a,t[5]=o,t[6]=n,t[7]=c}else c=t[7];return c}function oe(e){return(0,Q.jsx)(`option`,{value:e.value,children:e.name},e.value)}function se(e){return`browser-focus-${e}`}function ce(e){switch(e){case`connection`:case`extension`:case`local`:case`cloak`:case`cdp`:case`cloud`:case`runtime`:case`security`:return e;default:return null}}function le(e){let t=(0,Z.c)(89),{a:n,form:r,update:i}=e,a;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(a=se(`runtime`),t[0]=a):a=t[0];let o;t[1]===n.browserBehaviorShow?o=t[2]:(o=(0,Q.jsx)(V,{icon:C,title:n.browserBehaviorShow}),t[1]=n.browserBehaviorShow,t[2]=o);let s;t[3]===i?s=t[4]:(s=e=>i({browserHeadless:e.target.checked}),t[3]=i,t[4]=s);let c;t[5]!==r.browserHeadless||t[6]!==s?(c=(0,Q.jsx)(`input`,{type:`checkbox`,className:`size-3.5 shrink-0 rounded border-edge`,checked:r.browserHeadless,onChange:s}),t[5]=r.browserHeadless,t[6]=s,t[7]=c):c=t[7];let l;t[8]===n.browserHeadlessOn?l=t[9]:(l=(0,Q.jsx)(`span`,{children:n.browserHeadlessOn}),t[8]=n.browserHeadlessOn,t[9]=l);let u;t[10]!==c||t[11]!==l?(u=(0,Q.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-fg`,children:[c,l]}),t[10]=c,t[11]=l,t[12]=u):u=t[12];let d;t[13]!==n.desc.browserHeadless||t[14]!==n.label.browserHeadless||t[15]!==u?(d=(0,Q.jsx)(K,{label:n.label.browserHeadless,description:n.desc.browserHeadless,children:u}),t[13]=n.desc.browserHeadless,t[14]=n.label.browserHeadless,t[15]=u,t[16]=d):d=t[16];let f=n.label.browserDialogPolicy,p=n.desc.browserDialogPolicy,m;t[17]===Symbol.for(`react.memo_cache_sentinel`)?(m=q(),t[17]=m):m=t[17];let h;t[18]===i?h=t[19]:(h=e=>i({browserDialogPolicy:e.target.value}),t[18]=i,t[19]=h);let g;t[20]===n.browserDialogPolicyMustRespond?g=t[21]:(g=(0,Q.jsx)(`option`,{value:`must_respond`,children:n.browserDialogPolicyMustRespond}),t[20]=n.browserDialogPolicyMustRespond,t[21]=g);let _;t[22]===n.browserDialogPolicyAutoDismiss?_=t[23]:(_=(0,Q.jsx)(`option`,{value:`auto_dismiss`,children:n.browserDialogPolicyAutoDismiss}),t[22]=n.browserDialogPolicyAutoDismiss,t[23]=_);let v;t[24]===n.browserDialogPolicyAutoAccept?v=t[25]:(v=(0,Q.jsx)(`option`,{value:`auto_accept`,children:n.browserDialogPolicyAutoAccept}),t[24]=n.browserDialogPolicyAutoAccept,t[25]=v);let y;t[26]!==r.browserDialogPolicy||t[27]!==h||t[28]!==g||t[29]!==_||t[30]!==v?(y=(0,Q.jsxs)(`select`,{className:m,value:r.browserDialogPolicy,onChange:h,children:[g,_,v]}),t[26]=r.browserDialogPolicy,t[27]=h,t[28]=g,t[29]=_,t[30]=v,t[31]=y):y=t[31];let b;t[32]!==n.desc.browserDialogPolicy||t[33]!==n.label.browserDialogPolicy||t[34]!==y?(b=(0,Q.jsx)(K,{label:f,description:p,children:y}),t[32]=n.desc.browserDialogPolicy,t[33]=n.label.browserDialogPolicy,t[34]=y,t[35]=b):b=t[35];let x=n.label.browserDialogTimeout,S=n.desc.browserDialogTimeout,w;t[36]===Symbol.for(`react.memo_cache_sentinel`)?(w=J(),t[36]=w):w=t[36];let E=r.browserDialogTimeout??``,D;t[37]===i?D=t[38]:(D=e=>{let t=e.target.value;i({browserDialogTimeout:t===``?void 0:Number.parseInt(t,10)})},t[37]=i,t[38]=D);let O;t[39]!==E||t[40]!==D?(O=(0,Q.jsx)(`input`,{type:`number`,className:w,min:1,value:E,placeholder:`300`,onChange:D}),t[39]=E,t[40]=D,t[41]=O):O=t[41];let k;t[42]!==n.desc.browserDialogTimeout||t[43]!==n.label.browserDialogTimeout||t[44]!==O?(k=(0,Q.jsx)(K,{label:x,description:S,children:O}),t[42]=n.desc.browserDialogTimeout,t[43]=n.label.browserDialogTimeout,t[44]=O,t[45]=k):k=t[45];let A;t[46]!==b||t[47]!==k||t[48]!==d?(A=(0,Q.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[d,b,k]}),t[46]=b,t[47]=k,t[48]=d,t[49]=A):A=t[49];let j;t[50]!==o||t[51]!==A?(j=(0,Q.jsx)(`div`,{id:a,className:`scroll-mt-24`,children:(0,Q.jsxs)(H,{children:[o,A]})}),t[50]=o,t[51]=A,t[52]=j):j=t[52];let M;t[53]===Symbol.for(`react.memo_cache_sentinel`)?(M=se(`security`),t[53]=M):M=t[53];let N;t[54]===n.browserSecurityShow?N=t[55]:(N=(0,Q.jsx)(V,{icon:T,title:n.browserSecurityShow}),t[54]=n.browserSecurityShow,t[55]=N);let P;t[56]===i?P=t[57]:(P=e=>i({browserAllowPrivateUrls:e.target.checked}),t[56]=i,t[57]=P);let F;t[58]!==r.browserAllowPrivateUrls||t[59]!==P?(F=(0,Q.jsx)(`input`,{type:`checkbox`,className:`size-3.5 shrink-0 rounded border-edge`,checked:r.browserAllowPrivateUrls,onChange:P}),t[58]=r.browserAllowPrivateUrls,t[59]=P,t[60]=F):F=t[60];let I;t[61]===n.browserAllowPrivateOn?I=t[62]:(I=(0,Q.jsx)(`span`,{children:n.browserAllowPrivateOn}),t[61]=n.browserAllowPrivateOn,t[62]=I);let L;t[63]!==F||t[64]!==I?(L=(0,Q.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-fg`,children:[F,I]}),t[63]=F,t[64]=I,t[65]=L):L=t[65];let R;t[66]!==n.desc.browserAllowPrivateUrls||t[67]!==n.label.browserAllowPrivateUrls||t[68]!==L?(R=(0,Q.jsx)(K,{label:n.label.browserAllowPrivateUrls,description:n.desc.browserAllowPrivateUrls,children:L}),t[66]=n.desc.browserAllowPrivateUrls,t[67]=n.label.browserAllowPrivateUrls,t[68]=L,t[69]=R):R=t[69];let ee=n.label.browserCommandTimeout,z=n.desc.browserCommandTimeout,B;t[70]===Symbol.for(`react.memo_cache_sentinel`)?(B=J(),t[70]=B):B=t[70];let te=r.browserCommandTimeout??``,U;t[71]===i?U=t[72]:(U=e=>{let t=e.target.value;i({browserCommandTimeout:t===``?void 0:Number.parseInt(t,10)})},t[71]=i,t[72]=U);let W;t[73]!==te||t[74]!==U?(W=(0,Q.jsx)(`input`,{type:`number`,className:B,min:5,value:te,placeholder:`30`,onChange:U}),t[73]=te,t[74]=U,t[75]=W):W=t[75];let G;t[76]!==n.desc.browserCommandTimeout||t[77]!==n.label.browserCommandTimeout||t[78]!==W?(G=(0,Q.jsx)(K,{label:ee,description:z,children:W}),t[76]=n.desc.browserCommandTimeout,t[77]=n.label.browserCommandTimeout,t[78]=W,t[79]=G):G=t[79];let Y;t[80]!==R||t[81]!==G?(Y=(0,Q.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[R,G]}),t[80]=R,t[81]=G,t[82]=Y):Y=t[82];let ne;t[83]!==N||t[84]!==Y?(ne=(0,Q.jsx)(`div`,{id:M,className:`scroll-mt-24`,children:(0,Q.jsxs)(H,{className:`border border-amber-500/20`,children:[N,Y]})}),t[83]=N,t[84]=Y,t[85]=ne):ne=t[85];let re;return t[86]!==j||t[87]!==ne?(re=(0,Q.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[j,ne]}),t[86]=j,t[87]=ne,t[88]=re):re=t[88],re}function ue(e){let t=(0,Z.c)(9),{language:n,label:r,className:a}=e,o;t[0]===n?o=t[1]:(o=E(n),t[0]=n,t[1]=o);let s;t[2]===a?s=t[3]:(s=i(`inline-flex items-center gap-1 text-xs font-medium text-accent hover:underline`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,a),t[2]=a,t[3]=s);let c;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,Q.jsx)(A,{className:`size-3 shrink-0`,"aria-hidden":!0}),t[4]=c):c=t[4];let l;return t[5]!==r||t[6]!==o||t[7]!==s?(l=(0,Q.jsxs)(`a`,{href:o,target:`_blank`,rel:`noreferrer`,className:s,children:[r,c]}),t[5]=r,t[6]=o,t[7]=s,t[8]=l):l=t[8],l}function de(e){let t=(0,Z.c)(27),{title:n,description:r,recommended:a,recommendedLabel:o,icon:s,onSelect:c,selectLabel:l}=e,u=`${n} — ${l}`,d;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(d=i(`group flex w-full flex-col rounded-xl border border-edge bg-surface-panel px-3 py-3 text-left transition-colors`,`hover:border-edge-strong hover:bg-surface-hover/40`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`),t[0]=d):d=t[0];let f;t[1]===s?f=t[2]:(f=(0,Q.jsx)(`span`,{className:`flex size-8 shrink-0 items-center justify-center rounded-lg bg-surface-hover text-fg-muted`,children:(0,Q.jsx)(s,{className:`size-4`,strokeWidth:1.75,"aria-hidden":!0})}),t[1]=s,t[2]=f);let p;t[3]===n?p=t[4]:(p=(0,Q.jsx)(`h3`,{className:`text-sm font-semibold text-fg`,children:n}),t[3]=n,t[4]=p);let m;t[5]!==a||t[6]!==o?(m=a&&o?(0,Q.jsx)(`span`,{className:`rounded-full bg-accent/15 px-2 py-0.5 text-[10px] font-medium text-accent`,children:o}):null,t[5]=a,t[6]=o,t[7]=m):m=t[7];let h;t[8]!==p||t[9]!==m?(h=(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[p,m]}),t[8]=p,t[9]=m,t[10]=h):h=t[10];let g;t[11]===r?g=t[12]:(g=(0,Q.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-fg-muted`,children:r}),t[11]=r,t[12]=g);let _;t[13]!==h||t[14]!==g?(_=(0,Q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[h,g]}),t[13]=h,t[14]=g,t[15]=_):_=t[15];let v;t[16]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,Q.jsx)(F,{className:`mt-0.5 size-4 shrink-0 text-fg-subtle transition-transform group-hover:translate-x-0.5`,"aria-hidden":!0}),t[16]=v):v=t[16];let y;t[17]!==f||t[18]!==_?(y=(0,Q.jsxs)(`div`,{className:`flex items-start gap-3`,children:[f,_,v]}),t[17]=f,t[18]=_,t[19]=y):y=t[19];let b;t[20]===l?b=t[21]:(b=(0,Q.jsx)(`span`,{className:`mt-2 text-[11px] font-medium text-accent`,children:l}),t[20]=l,t[21]=b);let x;return t[22]!==c||t[23]!==u||t[24]!==y||t[25]!==b?(x=(0,Q.jsxs)(`button`,{type:`button`,onClick:c,"aria-label":u,className:d,children:[y,b]}),t[22]=c,t[23]=u,t[24]=y,t[25]=b,t[26]=x):x=t[26],x}function fe(e){let t=(0,Z.c)(25),{m:n,onStart:r}=e,i=b(pe),a;t[0]!==n.browserBackendCloakBrowser||t[1]!==n.browserModeCloakTagline||t[2]!==n.browserSetupCloudDesc||t[3]!==n.browserSetupCloudTitle||t[4]!==n.browserSetupExtDesc||t[5]!==n.browserSetupExtTitle||t[6]!==n.browserSetupLocalDesc||t[7]!==n.browserSetupLocalTitle||t[8]!==i?(a=[{id:`extension`,icon:I,title:n.browserSetupExtTitle,description:n.browserSetupExtDesc,recommended:!0},{id:`cloakbrowser`,icon:P,title:n.browserBackendCloakBrowser,description:n.browserModeCloakTagline},{id:`local`,icon:ee,title:n.browserSetupLocalTitle,description:n.browserSetupLocalDesc},{id:`cloud`,icon:B,title:n.browserSetupCloudTitle,description:n.browserSetupCloudDesc}].filter(e=>U(e.id,i)),t[0]=n.browserBackendCloakBrowser,t[1]=n.browserModeCloakTagline,t[2]=n.browserSetupCloudDesc,t[3]=n.browserSetupCloudTitle,t[4]=n.browserSetupExtDesc,t[5]=n.browserSetupExtTitle,t[6]=n.browserSetupLocalDesc,t[7]=n.browserSetupLocalTitle,t[8]=i,t[9]=a):a=t[9];let o=a,s;t[10]===n.browserSetupTitle?s=t[11]:(s=(0,Q.jsx)(`h2`,{className:`text-sm font-semibold text-fg`,children:n.browserSetupTitle}),t[10]=n.browserSetupTitle,t[11]=s);let c;t[12]===n.browserSetupSubtitle?c=t[13]:(c=(0,Q.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-fg-muted`,children:n.browserSetupSubtitle}),t[12]=n.browserSetupSubtitle,t[13]=c);let l;t[14]!==s||t[15]!==c?(l=(0,Q.jsxs)(`div`,{children:[s,c]}),t[14]=s,t[15]=c,t[16]=l):l=t[16];let u;t[17]!==n.browserSetupRecommended||t[18]!==n.browserSetupSelect||t[19]!==o||t[20]!==r?(u=(0,Q.jsx)(`div`,{className:`flex flex-col gap-2`,children:o.map(e=>(0,Q.jsx)(de,{icon:e.icon,title:e.title,description:e.description,recommended:e.recommended,recommendedLabel:n.browserSetupRecommended,selectLabel:n.browserSetupSelect,onSelect:()=>r(e.id)},e.id))}),t[17]=n.browserSetupRecommended,t[18]=n.browserSetupSelect,t[19]=o,t[20]=r,t[21]=u):u=t[21];let d;return t[22]!==l||t[23]!==u?(d=(0,Q.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-xl border border-edge-subtle bg-surface-base px-4 py-4`,children:[l,u]}),t[22]=l,t[23]=u,t[24]=d):d=t[24],d}function pe(e){return e.mode}function me(e){if(e.kind===`loading`)return`checking`;if(e.kind===`error`)return`error`;if(e.kind===`ok`)return e.data.installed?`ready`:`not_installed`}function he(e,t){if(e)return{ready:t.browserStatusReady,not_installed:t.browserStatusNotInstalled,checking:t.browserStatusChecking,unknown:t.browserStatusUnknown,error:t.browserStatusError}[e]}function ge(e){if(e.kind!==`idle`)return e.kind===`loading`?`checking`:e.kind===`error`?`error`:e.data.connected?`ready`:(e.data.running,`not_installed`)}function _e(e,t){if(e.kind!==`idle`)return e.kind===`loading`?t.browserStatusChecking:e.kind===`error`?t.browserStatusError:e.data.connected?t.browserExtensionConnected:e.data.running?t.browserExtensionWaiting:t.browserExtensionServerOff}var ve=[`overview`,`extension`,`local`,`cloakbrowser`,`cdp`,`cloud`],ye=[`extension`,`local`,`cloakbrowser`,`cdp`,`cloud`],be={connection:`overview`,extension:`extension`,local:`local`,cloak:`cloakbrowser`,cdp:`cdp`,cloud:`cloud`,runtime:`overview`,security:`overview`};function xe(e){let t=(e??``).trim();return t===`behavior`?`overview`:ve.includes(t)?t:`overview`}function Se(e){return ye.includes(e)}function Ce(e){let t=(0,Z.c)(46),{icon:n,title:r,description:i,status:a,statusDetail:o,primaryAction:s,children:c,advanced:l,m:u,embedded:d,sectionTitle:f,advancedTitle:p}=e,m=d===void 0?!1:d,h;t[0]!==l||t[1]!==p?(h=l?(0,Q.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[p?(0,Q.jsx)(`h4`,{className:`text-sm font-medium text-fg`,children:p}):null,l]}):null,t[0]=l,t[1]=p,t[2]=h):h=t[2];let g=h;if(m){let e;t[3]!==i||t[4]!==f?(e=f?(0,Q.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,Q.jsx)(`h4`,{className:`text-sm font-medium text-fg`,children:f}),i?(0,Q.jsx)(`p`,{className:`text-xs leading-relaxed text-fg-muted`,children:i}):null]}):null,t[3]=i,t[4]=f,t[5]=e):e=t[5];let n;t[6]!==u||t[7]!==s||t[8]!==a||t[9]!==o?(n=a||s?(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[a?(0,Q.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,Q.jsx)(we,{kind:a,detail:o,m:u})}):(0,Q.jsx)(`span`,{}),s?(0,Q.jsx)(`div`,{className:`shrink-0`,children:s}):null]}):null,t[6]=u,t[7]=s,t[8]=a,t[9]=o,t[10]=n):n=t[10];let r;t[11]===c?r=t[12]:(r=c?(0,Q.jsx)(`div`,{className:`flex flex-col gap-4`,children:c}):null,t[11]=c,t[12]=r);let l;return t[13]!==g||t[14]!==e||t[15]!==n||t[16]!==r?(l=(0,Q.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[e,n,r,g]}),t[13]=g,t[14]=e,t[15]=n,t[16]=r,t[17]=l):l=t[17],l}let _;t[18]===n?_=t[19]:(_=(0,Q.jsx)(`div`,{className:`flex size-9 shrink-0 items-center justify-center rounded-lg bg-surface-hover text-fg-muted`,children:(0,Q.jsx)(n,{className:`size-4`,strokeWidth:1.75})}),t[18]=n,t[19]=_);let v;t[20]===r?v=t[21]:(v=(0,Q.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:r}),t[20]=r,t[21]=v);let y;t[22]!==u||t[23]!==a||t[24]!==o?(y=a?(0,Q.jsx)(we,{kind:a,detail:o,m:u}):null,t[22]=u,t[23]=a,t[24]=o,t[25]=y):y=t[25];let b;t[26]!==v||t[27]!==y?(b=(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[v,y]}),t[26]=v,t[27]=y,t[28]=b):b=t[28];let x;t[29]===i?x=t[30]:(x=(0,Q.jsx)(`p`,{className:`text-xs leading-relaxed text-fg-muted`,children:i}),t[29]=i,t[30]=x);let S;t[31]!==b||t[32]!==x?(S=(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-1`,children:[b,x]}),t[31]=b,t[32]=x,t[33]=S):S=t[33];let C;t[34]===s?C=t[35]:(C=s?(0,Q.jsx)(`div`,{className:`shrink-0`,children:s}):null,t[34]=s,t[35]=C);let w;t[36]!==_||t[37]!==S||t[38]!==C?(w=(0,Q.jsxs)(`div`,{className:`flex items-start gap-3`,children:[_,S,C]}),t[36]=_,t[37]=S,t[38]=C,t[39]=w):w=t[39];let T;t[40]===c?T=t[41]:(T=c?(0,Q.jsx)(`div`,{className:`flex flex-col gap-4`,children:c}):null,t[40]=c,t[41]=T);let E;return t[42]!==g||t[43]!==w||t[44]!==T?(E=(0,Q.jsxs)(`div`,{className:`flex flex-col gap-4 rounded-xl border border-edge bg-surface-panel p-4`,children:[w,T,g]}),t[42]=g,t[43]=w,t[44]=T,t[45]=E):E=t[45],E}function we(e){let t=(0,Z.c)(27),{kind:n,detail:r,m:a}=e,o,s,c,l;if(t[0]!==n||t[1]!==a.browserStatusChecking||t[2]!==a.browserStatusError||t[3]!==a.browserStatusNotInstalled||t[4]!==a.browserStatusReady||t[5]!==a.browserStatusUnknown){let{icon:e,color:r,label:u}={ready:{icon:x,color:`text-green-600 dark:text-green-400`,label:a.browserStatusReady},not_installed:{icon:v,color:`text-amber-600 dark:text-amber-400`,label:a.browserStatusNotInstalled},checking:{icon:N,color:`text-fg-muted`,label:a.browserStatusChecking},unknown:{icon:m,color:`text-fg-muted`,label:a.browserStatusUnknown},error:{icon:p,color:`text-red-600 dark:text-red-400`,label:a.browserStatusError}}[n];o=e,s=u,l=`inline-flex min-w-0 flex-col items-start gap-1`,c=i(`inline-flex shrink-0 items-center gap-1 whitespace-nowrap text-xs font-medium`,r),t[0]=n,t[1]=a.browserStatusChecking,t[2]=a.browserStatusError,t[3]=a.browserStatusNotInstalled,t[4]=a.browserStatusReady,t[5]=a.browserStatusUnknown,t[6]=o,t[7]=s,t[8]=c,t[9]=l}else o=t[6],s=t[7],c=t[8],l=t[9];let u=n===`checking`&&`animate-spin`,d;t[10]===u?d=t[11]:(d=i(`size-3.5 shrink-0`,u),t[10]=u,t[11]=d);let f;t[12]!==o||t[13]!==d?(f=(0,Q.jsx)(o,{className:d}),t[12]=o,t[13]=d,t[14]=f):f=t[14];let h;t[15]===s?h=t[16]:(h=(0,Q.jsx)(`span`,{children:s}),t[15]=s,t[16]=h);let g;t[17]!==c||t[18]!==f||t[19]!==h?(g=(0,Q.jsxs)(`span`,{className:c,children:[f,h]}),t[17]=c,t[18]=f,t[19]=h,t[20]=g):g=t[20];let _;t[21]===r?_=t[22]:(_=r?(0,Q.jsx)(`span`,{className:`break-all font-mono text-[11px] leading-snug text-fg-subtle`,children:r}):null,t[21]=r,t[22]=_);let y;return t[23]!==l||t[24]!==g||t[25]!==_?(y=(0,Q.jsxs)(`span`,{className:l,children:[g,_]}),t[23]=l,t[24]=g,t[25]=_,t[26]=y):y=t[26],y}function Te(e){let t=(0,Z.c)(5),{kind:n,message:r}=e,a=n===`success`?`border-green-500/30 bg-green-500/10 text-green-700 dark:text-green-300`:`border-red-500/30 bg-red-500/10 text-red-600 dark:text-red-300`,o;t[0]===a?o=t[1]:(o=i(`rounded-lg border px-3 py-2 text-xs leading-relaxed`,a),t[0]=a,t[1]=o);let s;return t[2]!==r||t[3]!==o?(s=(0,Q.jsx)(`div`,{className:o,children:r}),t[2]=r,t[3]=o,t[4]=s):s=t[4],s}var Ee={instances:[],launchStatus:`idle`,launchMessage:null,testStatus:`idle`,testMessage:null,executablePath:``};function De({m:e,cdpUrl:t,onCdpUrlChange:n,launch:r,stop:i,listInstances:a,ping:o,embedded:s=!1}){let[c,l]=(0,X.useReducer)(u,Ee),{instances:f,launchStatus:p,launchMessage:m,testStatus:h,testMessage:v,executablePath:y}=c,b=(0,X.useCallback)(async()=>{try{l({type:`patch`,patch:{instances:await a()}})}catch{}},[a]);(0,X.useEffect)(()=>{b();let e=setInterval(()=>void b(),8e3);return()=>clearInterval(e)},[b]);let x=(0,X.useCallback)(async()=>{if(p!==`pending`){l({type:`patch`,patch:{launchStatus:`pending`,launchMessage:null}});try{let t=await r(y.trim()||void 0);l({type:`patch`,patch:{launchStatus:`ok`,launchMessage:e.browserCdpLaunchedAtPort.replace(`{{port}}`,String(t.port))}}),n(t.wsEndpoint),await b()}catch(e){l({type:`patch`,patch:{launchStatus:`error`,launchMessage:e instanceof Error?e.message:String(e)}})}}},[y,r,p,e.browserCdpLaunchedAtPort,n,b]),S=(0,X.useCallback)(async e=>{await i(e),await b()},[b,i]),C=(0,X.useCallback)(async()=>{if(t.trim()){l({type:`patch`,patch:{testStatus:`pending`,testMessage:null}});try{let n=await o(t.trim());n.reachable?l({type:`patch`,patch:{testStatus:`ok`,testMessage:e.browserCdpReachable.replace(`{{browser}}`,n.browser??`—`)}}):l({type:`patch`,patch:{testStatus:`error`,testMessage:e.browserCdpUnreachable.replace(`{{error}}`,n.error??`—`)}})}catch(t){l({type:`patch`,patch:{testStatus:`error`,testMessage:e.browserCdpUnreachable.replace(`{{error}}`,t instanceof Error?t.message:String(t))}})}}},[t,e.browserCdpReachable,e.browserCdpUnreachable,o]);return(0,Q.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,Q.jsxs)(Ce,{icon:_,title:e.browserCdpLaunchLocal,description:e.browserCdpLaunchLocalDesc,m:e,embedded:s,sectionTitle:s?e.browserCdpLaunchLocal:void 0,primaryAction:(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:p===`pending`,onClick:()=>void x(),children:[p===`pending`?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):(0,Q.jsx)(_,{className:`size-3.5`}),p===`pending`?e.browserCdpLaunching:e.browserCdpLaunchLocal]}),children:[m?(0,Q.jsx)(Te,{kind:p===`error`?`error`:`success`,message:m}):null,(0,Q.jsx)(K,{label:e.browserCdpChromePath,description:e.browserCdpChromePathDesc,children:(0,Q.jsx)(`input`,{type:`text`,className:J(),value:y,placeholder:`/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`,onChange:e=>l({type:`patch`,patch:{executablePath:e.target.value}}),autoComplete:`off`})}),f.length>0?(0,Q.jsx)(`div`,{className:`flex flex-col gap-2 rounded-lg border border-edge bg-surface-base p-3 text-xs`,children:f.map(t=>(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-col`,children:[(0,Q.jsxs)(`span`,{className:`font-mono text-fg`,children:[`port `,t.port,` · pid `,t.pid]}),(0,Q.jsx)(`span`,{className:`truncate text-fg-subtle`,children:t.wsEndpoint})]}),(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1 rounded-md border border-edge bg-surface-panel px-2 py-1 text-xs font-medium text-fg hover:bg-surface-raised`,onClick:()=>void S(t.port),children:[(0,Q.jsx)(D,{className:`size-3`}),e.browserCdpStopLocal]})]},t.port))}):null]}),(0,Q.jsxs)(Ce,{icon:g,title:e.label.browserCdpUrl,description:e.desc.browserCdpUrl,m:e,embedded:s,sectionTitle:s?e.label.browserCdpUrl:void 0,primaryAction:(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:!t.trim()||h===`pending`,onClick:()=>void C(),children:[h===`pending`?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):(0,Q.jsx)(d,{className:`size-3.5`}),h===`pending`?e.browserCdpTesting:e.browserCdpTestConnection]}),children:[(0,Q.jsx)(`input`,{type:`text`,className:J(),value:t,placeholder:`ws://127.0.0.1:9222`,onChange:e=>n(e.target.value),autoComplete:`off`}),(0,Q.jsx)(`p`,{className:`text-[11px] text-fg-subtle`,children:e.browserCdpLoopbackOnly}),v?(0,Q.jsx)(Te,{kind:h===`error`?`error`:`success`,message:v}):null]})]})}function Oe(e,t){let n=t.phase;if(!n)return e.browserInstallPhaseStarting;if(n===`downloading`)return t.percent==null?e.browserInstallPhaseDownloading:e.browserInstallPhaseDownloadingPercent.replace(`{{percent}}`,String(t.percent));switch(n){case`starting`:return e.browserInstallPhaseStarting;case`verifying`:return e.browserInstallPhaseVerifying;case`extracting`:return e.browserInstallPhaseExtracting;case`running`:return t.message??e.browserInstallPhaseRunning;case`ready`:return e.browserInstallPhaseReady;default:return t.message??e.browserInstallPhaseRunning}}function ke(e){let t=(0,Z.c)(32),{m:n,progress:r,showLogs:i,onCancel:a,cancelling:o}=e,s=i===void 0?!1:i,c=o===void 0?!1:o;if(!r.phase)return null;let l;t[0]!==n||t[1]!==r?(l=Oe(n,r),t[0]=n,t[1]=r,t[2]=l):l=t[2];let u=l,d=r.percent==null?(r.phase===`extracting`||r.phase===`verifying`||r.phase===`running`||r.phase,null):Math.min(100,Math.max(0,r.percent)),f;t[3]===u?f=t[4]:(f=(0,Q.jsx)(`span`,{className:`text-fg`,children:u}),t[3]=u,t[4]=f);let p;t[5]===d?p=t[6]:(p=d==null?null:(0,Q.jsxs)(`span`,{className:`tabular-nums`,children:[d,`%`]}),t[5]=d,t[6]=p);let m;t[7]!==c||t[8]!==n||t[9]!==a?(m=a?(0,Q.jsx)(`button`,{type:`button`,className:`rounded-md border border-edge px-2 py-0.5 text-[11px] font-medium text-fg-muted hover:bg-surface-raised hover:text-fg disabled:cursor-not-allowed disabled:opacity-60`,disabled:c,onClick:()=>void a(),children:c?n.browserInstallCancelling:n.browserInstallCancel}):null,t[7]=c,t[8]=n,t[9]=a,t[10]=m):m=t[10];let h;t[11]!==p||t[12]!==m?(h=(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[p,m]}),t[11]=p,t[12]=m,t[13]=h):h=t[13];let g;t[14]!==f||t[15]!==h?(g=(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-2 text-xs text-fg-muted`,children:[f,h]}),t[14]=f,t[15]=h,t[16]=g):g=t[16];let _;t[17]===d?_=t[18]:(_=(0,Q.jsx)(`div`,{className:`h-1.5 overflow-hidden rounded-full bg-surface-raised`,children:d==null?(0,Q.jsx)(`div`,{className:`h-full w-1/3 animate-pulse rounded-full bg-accent/70`}):(0,Q.jsx)(`div`,{className:`h-full rounded-full bg-accent transition-[width] duration-300 ease-out`,style:{width:`${d}%`}})}),t[17]=d,t[18]=_);let v;t[19]!==r.lines||t[20]!==s?(v=s&&r.lines.length>0?(0,Q.jsx)(`div`,{className:`max-h-28 overflow-y-auto rounded-md border border-edge bg-surface-panel px-2 py-1.5 font-mono text-[10px] leading-relaxed text-fg-muted`,children:r.lines.map(Ae)}):null,t[19]=r.lines,t[20]=s,t[21]=v):v=t[21];let y;t[22]!==r.message||t[23]!==r.percent||t[24]!==r.phase||t[25]!==s?(y=!s&&r.phase===`downloading`&&r.message&&r.percent==null?(0,Q.jsx)(`p`,{className:`text-[11px] text-fg-subtle`,children:r.message}):null,t[22]=r.message,t[23]=r.percent,t[24]=r.phase,t[25]=s,t[26]=y):y=t[26];let b;return t[27]!==v||t[28]!==y||t[29]!==g||t[30]!==_?(b=(0,Q.jsxs)(`div`,{className:`space-y-2 rounded-lg border border-edge bg-surface-base px-3 py-2.5`,children:[g,_,v,y]}),t[27]=v,t[28]=y,t[29]=g,t[30]=_,t[31]=b):b=t[31],b}function Ae(e){return(0,Q.jsx)(`div`,{className:`truncate`,children:e},e)}var je={confirmOpen:!1,installStatus:`idle`,installMessage:null,openStatus:`idle`,openMessage:null,runtime:null};function Me({m:e,doctor:t,refetch:n,applyDoctor:r,installStream:i,fetchRuntimeStatus:a,launchCloak:o,form:s,onChange:c,embedded:l=!1}){let[d,f]=(0,X.useReducer)(u,je),{confirmOpen:p,installStatus:m,installMessage:g,openStatus:v,openMessage:y,runtime:b}=d,{progress:S,running:C,cancelling:T,run:E,reset:D,cancel:O}=i,k=t.kind===`ok`?t.data:null,A=k?.installed===!0,j=m===`installing`||C,F=(0,X.useCallback)(async()=>{if(A)try{f({type:`patch`,patch:{runtime:await a()}})}catch{}},[a,A]);(0,X.useEffect)(()=>{if(!A){f({type:`patch`,patch:{runtime:null}});return}F();let e=setInterval(()=>void F(),8e3);return()=>clearInterval(e)},[A,F]);let I=(0,X.useCallback)(async()=>{f({type:`patch`,patch:{confirmOpen:!1,installStatus:`installing`,installMessage:null}}),D();let t=await E({body:{cacheDir:s.cacheDir.trim()||void 0,binaryPath:s.binaryPath.trim()||void 0},fallbackError:e.browserCloakInstallFailed});if(!t.ok){if(t.error===`busy`){f({type:`patch`,patch:{installStatus:`installing`}});return}if(t.error===`cancelled`){f({type:`patch`,patch:{installStatus:`idle`,installMessage:null}}),D();return}f({type:`patch`,patch:{installStatus:`failed`,installMessage:t.errorMessage??e.browserCloakInstallFailed}});return}t.payload&&r?.(t.payload),f({type:`patch`,patch:{installStatus:`installed`,installMessage:t.payload?.binaryPath?`${e.browserCloakInstalled}: ${t.payload.binaryPath}`:e.browserCloakInstalled}}),await n({cacheDir:s.cacheDir,binaryPath:s.binaryPath}),await F()},[r,s.binaryPath,s.cacheDir,e.browserCloakInstallFailed,e.browserCloakInstalled,n,F,D,E]),L=(0,X.useCallback)(async()=>{if(v!==`pending`){f({type:`patch`,patch:{openStatus:`pending`,openMessage:null}});try{let t=await o();f({type:`patch`,patch:{openStatus:`ok`,openMessage:t.reused?e.browserCloakOpenReused.replace(`{{port}}`,String(t.port)):e.browserCloakOpenLaunched.replace(`{{port}}`,String(t.port)),runtime:t}})}catch(e){f({type:`patch`,patch:{openStatus:`error`,openMessage:e instanceof Error?e.message:String(e)}})}}},[o,e.browserCloakOpenLaunched,e.browserCloakOpenReused,v]),R=t.kind===`loading`?`checking`:t.kind===`error`?`error`:A?`ready`:`not_installed`,ee=A&&k?.version?`v${k.version} (${k.platform})`:void 0;return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(Ce,{icon:P,title:e.browserCloakGuideTitle,description:e.browserCloakGuideDesc,status:R,statusDetail:ee,m:e,embedded:l,primaryAction:(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[A?(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:v===`pending`,onClick:()=>void L(),children:[v===`pending`?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):(0,Q.jsx)(_,{className:`size-3.5`}),v===`pending`?e.browserCloakOpening:e.browserCloakOpen]}):null,(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:j,onClick:()=>f({type:`patch`,patch:{confirmOpen:!0}}),children:[j?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):A?(0,Q.jsx)(w,{className:`size-3.5`}):m===`installed`?(0,Q.jsx)(x,{className:`size-3.5 text-green-500`}):(0,Q.jsx)(h,{className:`size-3.5`}),j?e.browserCloakInstalling:A?e.browserReinstall:e.browserCloakDownload]})]}),children:[C?(0,Q.jsx)(ke,{m:e,progress:S,cancelling:T,onCancel:()=>void O()}):null,g?(0,Q.jsx)(Te,{kind:m===`failed`?`error`:`success`,message:g}):null,y?(0,Q.jsx)(Te,{kind:v===`error`?`error`:`success`,message:y}):null,A&&b?(0,Q.jsxs)(`div`,{className:`flex flex-col gap-2 rounded-lg border border-edge bg-surface-base p-3 text-xs`,children:[(0,Q.jsx)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:(0,Q.jsx)(`span`,{className:`font-medium text-fg`,children:b.running?e.browserCloakRuntimeRunning.replace(`{{port}}`,String(b.port)):e.browserCloakRuntimeOff})}),(0,Q.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,Q.jsx)(`span`,{className:`text-fg-subtle`,children:e.browserCloakProfileLabel}),(0,Q.jsx)(`span`,{className:`break-all font-mono text-[11px] text-fg-muted`,children:b.userDataDir})]}),(0,Q.jsx)(`p`,{className:`text-[11px] leading-relaxed text-fg-subtle`,children:e.browserCloakProfileAgentHint}),b.temporaryProfile?(0,Q.jsx)(`p`,{className:`text-[11px] text-amber-600 dark:text-amber-400`,children:e.browserCloakTemporaryProfileHint}):null]}):null,(0,Q.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,Q.jsx)(K,{label:e.label.browserCloakKeepOpen,description:e.desc.browserCloakKeepOpen,children:(0,Q.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-fg`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,className:`size-3.5 shrink-0 rounded border-edge`,checked:s.keepOpen,onChange:e=>c({keepOpen:e.target.checked})}),(0,Q.jsx)(`span`,{children:e.browserCloakKeepOpenOn})]})}),(0,Q.jsx)(K,{label:e.label.browserCloakTemporaryProfile,description:e.desc.browserCloakTemporaryProfile,children:(0,Q.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-fg`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,className:`size-3.5 shrink-0 rounded border-edge`,checked:s.temporaryProfile,onChange:e=>c({temporaryProfile:e.target.checked})}),(0,Q.jsx)(`span`,{children:e.browserCloakTemporaryProfileOn})]})}),(0,Q.jsx)(K,{label:e.label.browserHumanize,description:e.desc.browserHumanize,children:(0,Q.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-fg`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,className:`size-3.5 shrink-0 rounded border-edge`,checked:s.humanize,onChange:e=>c({humanize:e.target.checked})}),(0,Q.jsx)(`span`,{children:e.browserHumanizeOn})]})}),(0,Q.jsx)(K,{label:e.label.browserHumanPreset,description:e.desc.browserHumanPreset,children:(0,Q.jsxs)(`select`,{className:q(),value:s.humanPreset,onChange:e=>c({humanPreset:e.target.value}),children:[(0,Q.jsx)(`option`,{value:`careful`,children:e.browserHumanPresetCareful}),(0,Q.jsx)(`option`,{value:`default`,children:e.browserHumanPresetDefault})]})})]})]}),(0,Q.jsxs)(H,{className:`mt-4 border border-edge-subtle`,children:[(0,Q.jsx)(V,{icon:P,title:e.browserCloakAdvancedShow}),(0,Q.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,Q.jsxs)(K,{label:e.label.browserCloakCacheDir,description:e.desc.browserCloakCacheDir,children:[(0,Q.jsx)(`input`,{type:`text`,className:J(),value:s.cacheDir,placeholder:`~/.xopc/bin/cloakbrowser`,onChange:e=>c({cacheDir:e.target.value}),autoComplete:`off`}),(0,Q.jsx)(`p`,{className:`text-[11px] text-fg-subtle`,children:e.browserCacheDirHomeOnly})]}),(0,Q.jsxs)(K,{label:e.label.browserCloakBinaryPath,description:e.desc.browserCloakBinaryPath,children:[(0,Q.jsx)(`input`,{type:`text`,className:J(),value:s.binaryPath,placeholder:`~/.xopc/bin/cloakbrowser/chromium-v.../Chromium.app/Contents/MacOS/Chromium`,onChange:e=>c({binaryPath:e.target.value}),autoComplete:`off`}),s.binaryPath.trim()?(0,Q.jsx)(`p`,{className:`text-[11px] text-amber-600 dark:text-amber-400`,children:e.browserBinaryPathWarning}):null]}),(0,Q.jsx)(K,{label:e.label.browserCloakTimezone,description:e.desc.browserCloakTimezone,children:(0,Q.jsx)(`input`,{type:`text`,className:J(),value:s.timezone,placeholder:`America/New_York`,onChange:e=>c({timezone:e.target.value}),autoComplete:`off`})}),(0,Q.jsx)(K,{label:e.label.browserCloakLocale,description:e.desc.browserCloakLocale,children:(0,Q.jsx)(`input`,{type:`text`,className:J(),value:s.locale,placeholder:`en-US`,onChange:e=>c({locale:e.target.value}),autoComplete:`off`})}),(0,Q.jsx)(K,{label:e.label.browserCloakWebrtcIp,description:e.desc.browserCloakWebrtcIp,children:(0,Q.jsx)(`input`,{type:`text`,className:J(),value:s.webrtcIp,placeholder:`203.0.113.10`,onChange:e=>c({webrtcIp:e.target.value}),autoComplete:`off`})}),(0,Q.jsx)(K,{label:e.label.browserCloakFingerprintPlatform,description:e.desc.browserCloakFingerprintPlatform,children:(0,Q.jsx)(`input`,{type:`text`,className:J(),value:s.fingerprintPlatform,placeholder:`macos`,onChange:e=>c({fingerprintPlatform:e.target.value}),autoComplete:`off`})}),(0,Q.jsx)(`div`,{className:`sm:col-span-2`,children:(0,Q.jsx)(K,{label:e.label.browserCloakExtraArgs,description:e.desc.browserCloakExtraArgs,children:(0,Q.jsx)(`textarea`,{className:Ne(),value:s.extraArgs,placeholder:`--disable-dev-shm-usage`,rows:3,onChange:e=>c({extraArgs:e.target.value})})})})]})]}),(0,Q.jsx)(M,{open:p,title:e.browserConfirmDownloadTitle,description:Pe(e,k),confirmLabel:e.browserConfirmDownloadConfirm,cancelLabel:e.browserConfirmDownloadCancel,onConfirm:()=>void I(),onCancel:()=>f({type:`patch`,patch:{confirmOpen:!1}})})]})}function Ne(){return`${J()} min-h-[4.5rem] resize-y font-mono text-xs`}function Pe(e,t){if(!t)return e.browserConfirmDownloadBody;let n=[e.browserConfirmDownloadBody.replace(`{{version}}`,t.version??`—`).replace(`{{platform}}`,t.platform).replace(`{{url}}`,t.downloadUrl||`—`)];return t.expectedSha256?n.push(`SHA-256: ${t.expectedSha256.slice(0,16)}…`):n.push(e.browserCloakSha256Skipped),n.join(`
2
- `)}function Fe({m:e,form:t,onChange:n,testCloud:r,embedded:i=!1}){let[s,c]=(0,X.useState)(`idle`),[l,u]=(0,X.useState)(null),f=t.provider===`local`?`browserbase`:t.provider,p=a(o(e=>e.language)).providersSettings,m=j({show:p.show,hide:p.hide,copy:p.copy,copied:p.copied}),h=(0,X.useCallback)(()=>re().then(e=>e.apiKey??null),[]),g=(0,X.useCallback)(async()=>{c(`pending`),u(null);try{let n=await r(f,t.apiKey);n.reachable?(c(`ok`),u(e.browserCloudTestOk)):(c(`error`),u(e.browserCloudTestFailed.replace(`{{error}}`,n.error??`—`)))}catch(t){c(`error`),u(e.browserCloudTestFailed.replace(`{{error}}`,t instanceof Error?t.message:String(t)))}},[t.apiKey,e.browserCloudTestFailed,e.browserCloudTestOk,f,r]);return(0,Q.jsxs)(Ce,{icon:B,title:e.label.browserCloudProvider,description:e.desc.browserCloudProvider,m:e,embedded:i,primaryAction:(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:s===`pending`,onClick:()=>void g(),children:[s===`pending`?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):(0,Q.jsx)(d,{className:`size-3.5`}),e.browserCloudTestConnection]}),children:[(0,Q.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,Q.jsx)(K,{label:e.label.browserCloudProvider,description:e.desc.browserCloudProvider,children:(0,Q.jsxs)(`select`,{className:q(),value:f,onChange:e=>n({provider:e.target.value}),children:[(0,Q.jsx)(`option`,{value:`browserbase`,children:e.browserCloudProviderBrowserbase}),(0,Q.jsx)(`option`,{value:`browser-use`,children:e.browserCloudProviderBrowserUse})]})}),(0,Q.jsx)(K,{label:e.label.browserCloudApiKey,description:e.desc.browserCloudApiKey,children:(0,Q.jsx)(O,{value:t.apiKey,onChange:e=>n({apiKey:e}),placeholder:f===`browserbase`?`BROWSERBASE_API_KEY`:`BROWSER_USE_API_KEY`,labels:m,reveal:h,loadFailedLabel:`Failed to load key`})}),f===`browserbase`?(0,Q.jsx)(K,{label:e.label.browserCloudProjectId,description:e.desc.browserCloudProjectId,children:(0,Q.jsx)(`input`,{type:`text`,className:J(),value:t.projectId,placeholder:`BROWSERBASE_PROJECT_ID`,onChange:e=>n({projectId:e.target.value}),autoComplete:`off`})}):null,(0,Q.jsx)(K,{label:e.label.browserCloudRegion,description:e.desc.browserCloudRegion,children:(0,Q.jsx)(`input`,{type:`text`,className:J(),value:t.region,placeholder:`us-west-2`,onChange:e=>n({region:e.target.value}),autoComplete:`off`})})]}),l?(0,Q.jsx)(Te,{kind:s===`error`?`error`:`success`,message:l}):null]})}function Ie(e){let t=(0,Z.c)(48),{m:n,installed:r,extensionDir:a,connected:o,busy:s,onOpenChrome:c,onCopyPath:l,onRevealFolder:u,pathBusy:d,folderBusy:f}=e,p;t[0]!==r||t[1]!==n.browserExtensionInstallStep1?(p={id:`install`,label:n.browserExtensionInstallStep1,done:r},t[0]=r,t[1]=n.browserExtensionInstallStep1,t[2]=p):p=t[2];let m=!!a&&o,h;t[3]!==s||t[4]!==a||t[5]!==f||t[6]!==n.browserExtensionCopyPath||t[7]!==n.browserExtensionInstallStep2FolderLabel||t[8]!==n.browserExtensionInstalling||t[9]!==n.browserExtensionOpenChrome||t[10]!==n.browserExtensionRevealFolder||t[11]!==l||t[12]!==c||t[13]!==u||t[14]!==d?(h=a?(0,Q.jsxs)(`div`,{className:`mt-2 rounded-md border border-edge bg-surface-raised px-2.5 py-2`,children:[(0,Q.jsx)(`p`,{className:`text-[10px] font-medium uppercase tracking-wide text-fg-subtle`,children:n.browserExtensionInstallStep2FolderLabel}),(0,Q.jsx)(`p`,{className:`mt-1 break-all font-mono text-[11px] text-fg`,children:a}),(0,Q.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-3`,children:[(0,Q.jsx)(`button`,{type:`button`,className:`inline-flex items-center gap-1 text-[11px] text-accent hover:underline disabled:opacity-60`,disabled:s,onClick:c,children:n.browserExtensionOpenChrome}),(0,Q.jsx)(`button`,{type:`button`,className:`inline-flex items-center gap-1 text-[11px] text-accent hover:underline disabled:opacity-60`,disabled:s,onClick:l,title:a,children:d?n.browserExtensionInstalling:n.browserExtensionCopyPath}),(0,Q.jsx)(`button`,{type:`button`,className:`inline-flex items-center gap-1 text-[11px] text-accent hover:underline disabled:opacity-60`,disabled:s,onClick:u,title:a,children:f?n.browserExtensionInstalling:n.browserExtensionRevealFolder})]})]}):null,t[3]=s,t[4]=a,t[5]=f,t[6]=n.browserExtensionCopyPath,t[7]=n.browserExtensionInstallStep2FolderLabel,t[8]=n.browserExtensionInstalling,t[9]=n.browserExtensionOpenChrome,t[10]=n.browserExtensionRevealFolder,t[11]=l,t[12]=c,t[13]=u,t[14]=d,t[15]=h):h=t[15];let g;t[16]!==n.browserExtensionInstallStep2||t[17]!==m||t[18]!==h?(g={id:`load`,label:n.browserExtensionInstallStep2,done:m,detail:h},t[16]=n.browserExtensionInstallStep2,t[17]=m,t[18]=h,t[19]=g):g=t[19];let _;t[20]!==o||t[21]!==n.browserExtensionInstallStep3?(_={id:`connect`,label:n.browserExtensionInstallStep3,done:o},t[20]=o,t[21]=n.browserExtensionInstallStep3,t[22]=_):_=t[22];let v;t[23]!==p||t[24]!==g||t[25]!==_?(v=[p,g,_],t[23]=p,t[24]=g,t[25]=_,t[26]=v):v=t[26];let b=v,S;t[27]===b?S=t[28]:(S=b.filter(Le),t[27]=b,t[28]=S);let C=S.length,w=n.browserExtensionInstallGuideTitle,T;t[29]===n.browserExtensionInstallGuideTitle?T=t[30]:(T=(0,Q.jsx)(`h4`,{className:`text-sm font-medium text-fg`,children:n.browserExtensionInstallGuideTitle}),t[29]=n.browserExtensionInstallGuideTitle,t[30]=T);let E;t[31]!==C||t[32]!==n.browserExtensionChecklistProgress||t[33]!==b.length?(E=n.browserExtensionChecklistProgress.replace(`{{done}}`,String(C)).replace(`{{total}}`,String(b.length)),t[31]=C,t[32]=n.browserExtensionChecklistProgress,t[33]=b.length,t[34]=E):E=t[34];let D;t[35]===E?D=t[36]:(D=(0,Q.jsx)(`span`,{className:`ml-auto text-xs font-normal text-fg-muted`,children:E}),t[35]=E,t[36]=D);let O;t[37]!==D||t[38]!==T?(O=(0,Q.jsxs)(`div`,{className:`mb-3 flex items-center gap-2`,children:[T,D]}),t[37]=D,t[38]=T,t[39]=O):O=t[39];let k;t[40]!==n.browserExtensionChecklistDone||t[41]!==n.browserExtensionChecklistPending||t[42]!==b?(k=(0,Q.jsx)(`ol`,{className:`flex flex-col gap-3`,children:b.map((e,t)=>(0,Q.jsxs)(`li`,{className:`flex gap-2.5`,children:[(0,Q.jsx)(`span`,{className:`mt-0.5 shrink-0`,"aria-hidden":!0,children:e.done?(0,Q.jsx)(x,{className:`size-4 text-emerald-500`,strokeWidth:2}):(0,Q.jsx)(y,{className:`size-4 text-fg-subtle`,strokeWidth:1.75})}),(0,Q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Q.jsxs)(`p`,{className:i(`text-[11px] leading-relaxed`,e.done?`text-fg-muted line-through decoration-fg-subtle/60`:`text-fg`),children:[(0,Q.jsxs)(`span`,{className:`sr-only`,children:[e.done?n.browserExtensionChecklistDone:n.browserExtensionChecklistPending,` `]}),t+1,`. `,e.label]}),e.detail]})]},e.id))}),t[40]=n.browserExtensionChecklistDone,t[41]=n.browserExtensionChecklistPending,t[42]=b,t[43]=k):k=t[43];let A;return t[44]!==n.browserExtensionInstallGuideTitle||t[45]!==O||t[46]!==k?(A=(0,Q.jsxs)(`div`,{"aria-label":w,className:`rounded-xl border border-edge bg-surface-base px-3 py-3`,children:[O,k]}),t[44]=n.browserExtensionInstallGuideTitle,t[45]=O,t[46]=k,t[47]=A):A=t[47],A}function Le(e){return e.done}var Re=19820,ze=3e4;function Be({m:e,probe:t,artifacts:n,onChange:r,startBridge:i,stopBridge:a,disconnectExtension:o,installArtifacts:s,refetchArtifacts:c,openExtensionChrome:u,revealExtensionFolder:f,form:p,embedded:m=!1}){let[g,v]=(0,X.useState)(null),[y,b]=(0,X.useState)(null),[x,C]=(0,X.useState)(null),w=p.port??Re,T=p.host||`127.0.0.1`,E=`ws://${T}:${w}/browser-ext`,O=t.kind===`ok`&&t.data.running,A=t.kind===`ok`&&t.data.connected,j=t.kind===`ok`&&t.data.bridgeHeld===!0,M=t.kind===`ok`&&t.data.portConflict===!0,P=O||j,F=n.kind===`ok`?n.data:t.kind===`ok`?t.data.artifacts:void 0,L=F?.installed===!0,R=F?.extensionDir,ee=F?.needsChromeReload===!0,B=t.kind===`ok`?A?{icon:k,color:`text-green-500`,label:e.browserExtensionConnected}:O?{icon:d,color:`text-amber-500`,label:e.browserExtensionWaiting}:{icon:z,color:`text-fg-muted`,label:e.browserExtensionServerOff}:{icon:z,color:`text-fg-muted`,label:`…`},te=B.icon,V=(0,X.useCallback)(async()=>{if(!g){v(`start`),b(null);try{await i({host:T,port:w})}catch(e){b(e instanceof Error?e.message:String(e))}finally{v(null)}}},[g,T,w,i]),H=(0,X.useCallback)(async()=>{if(!g){v(`stop`),b(null);try{await a()}catch(e){b(e instanceof Error?e.message:String(e))}finally{v(null)}}},[g,a]),U=(0,X.useCallback)(async()=>{if(!g){v(`disconnect`),b(null);try{await o()}catch(e){b(e instanceof Error?e.message:String(e))}finally{v(null)}}},[g,o]),W=(0,X.useCallback)(async()=>{if(!g){v(`install`),b(null),C(null);try{let t=await s({force:L});t?.extensionDir?C(`${e.browserExtensionInstalled}: ${t.extensionDir}`):C(e.browserExtensionInstalled),await c()}catch(e){b(e instanceof Error?e.message:String(e))}finally{v(null)}}},[g,s,L,e.browserExtensionInstalled,c]),G=(0,X.useCallback)(async()=>{if(!g){v(`open`),b(null);try{await u()}catch(e){b(e instanceof Error?e.message:String(e))}finally{v(null)}}},[g,u]),q=(0,X.useCallback)(async()=>{if(!(!R||g)){v(`path`),b(null),C(null);try{await S(R)?l({type:`success`,title:e.browserExtensionPathCopied}):C(e.browserExtensionPathCopyFailed)}catch(e){b(e instanceof Error?e.message:String(e))}finally{v(null)}}},[g,R,e.browserExtensionPathCopied,e.browserExtensionPathCopyFailed]),Y=(0,X.useCallback)(async()=>{if(!(!R||g)){v(`folder`),b(null),C(null);try{await f(),l({type:`success`,title:e.browserExtensionFolderOpened})}catch(e){b(e instanceof Error?e.message:String(e))}finally{v(null)}}},[g,R,e.browserExtensionFolderOpened,f]),ne=(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:g!==null,onClick:()=>void W(),children:[g===`install`?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):(0,Q.jsx)(h,{className:`size-3.5`}),g===`install`?e.browserExtensionInstalling:e.browserExtensionInstall]}),P?(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:g!==null,onClick:()=>void H(),children:[g===`stop`?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):(0,Q.jsx)(D,{className:`size-3.5`}),e.browserExtensionStopBridge]}):(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:g!==null,onClick:()=>void V(),children:[g===`start`?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):(0,Q.jsx)(_,{className:`size-3.5`}),g===`start`?e.browserExtensionStarting:e.browserExtensionStartBridge]}),A?(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:g!==null,onClick:()=>void U(),children:[g===`disconnect`?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):(0,Q.jsx)(z,{className:`size-3.5`}),e.browserExtensionDisconnect]}):null]});return(0,Q.jsx)(Ce,{icon:I,title:e.browserBackendExtension,description:e.browserExtensionDownloadHint,m:e,embedded:m,primaryAction:ne,advancedTitle:e.browserAdvancedShow,advanced:(0,Q.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,Q.jsx)(K,{label:e.label.browserExtensionPort,description:e.desc.browserExtensionPort,children:(0,Q.jsx)(`input`,{type:`number`,className:J(),min:1024,max:65535,value:p.port??``,placeholder:String(Re),onChange:e=>{let t=e.target.value;r({port:t===``?void 0:Number.parseInt(t,10)})}})}),(0,Q.jsx)(K,{label:e.label.browserExtensionHost,description:e.desc.browserExtensionHost,children:(0,Q.jsx)(`input`,{type:`text`,className:J(),value:p.host,placeholder:`127.0.0.1`,onChange:e=>r({host:e.target.value}),autoComplete:`off`})}),(0,Q.jsx)(K,{label:e.label.browserExtensionConnectionTimeout,description:e.desc.browserExtensionConnectionTimeout,children:(0,Q.jsx)(`input`,{type:`number`,className:J(),min:1,step:1,value:p.connectionTimeoutMs==null?``:Math.round(p.connectionTimeoutMs/1e3),placeholder:String(ze/1e3),onChange:e=>{let t=e.target.value;r({connectionTimeoutMs:t===``?void 0:Math.max(1,Number.parseInt(t,10))*1e3})}})})]}),children:(0,Q.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-lg border border-edge bg-surface-base px-3 py-2`,children:[(0,Q.jsx)(`span`,{className:`font-mono text-xs text-fg-muted`,children:E}),(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-xs ${B.color}`,children:[(0,Q.jsx)(te,{className:`size-3.5`}),(0,Q.jsx)(`span`,{children:B.label})]})]}),(0,Q.jsx)(Ie,{m:e,installed:L,extensionDir:R,connected:A,busy:g!==null,pathBusy:g===`path`,folderBusy:g===`folder`,onOpenChrome:()=>void G(),onCopyPath:()=>void q(),onRevealFolder:()=>void Y()}),ee?(0,Q.jsx)(`div`,{className:`rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs leading-relaxed text-amber-800 dark:text-amber-200`,children:e.browserExtensionNeedsChromeReload}):null,M?(0,Q.jsx)(`div`,{className:`rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs leading-relaxed text-amber-800 dark:text-amber-200`,children:e.browserExtensionPortConflict.replace(`{{port}}`,String(w))}):null,x?(0,Q.jsx)(Te,{kind:`success`,message:x}):null,y?(0,Q.jsx)(Te,{kind:`error`,message:y}):null]})})}function Ve(e){let t=(0,Z.c)(41),{m:n,doctor:r,refetch:i,applyDoctor:a,installStream:o,embedded:s}=e,c=s===void 0?!1:s,[l,u]=(0,X.useState)(`idle`),[d,f]=(0,X.useState)(null),{progress:p,running:m,cancelling:g,run:_,reset:v,cancel:y}=o,b;t[0]!==a||t[1]!==n.browserPlaywrightInstallFailed||t[2]!==n.browserPlaywrightInstalled||t[3]!==i||t[4]!==v||t[5]!==_?(b=async()=>{u(`installing`),f(null),v();let e=await _({fallbackError:n.browserPlaywrightInstallFailed});if(!e.ok){if(e.error===`busy`){u(`installing`);return}if(e.error===`cancelled`){u(`idle`),f(null),v();return}u(`failed`),f(e.errorMessage??n.browserPlaywrightInstallFailed);return}e.payload&&a?.(e.payload),u(`installed`),f(e.payload?.executablePath?`${n.browserPlaywrightInstalled}: ${e.payload.executablePath}`:n.browserPlaywrightInstalled),await i()},t[0]=a,t[1]=n.browserPlaywrightInstallFailed,t[2]=n.browserPlaywrightInstalled,t[3]=i,t[4]=v,t[5]=_,t[6]=b):b=t[6];let S=b,C=r.kind===`loading`?`checking`:r.kind===`error`?`error`:r.kind===`ok`?r.data.installed?`ready`:`not_installed`:`unknown`,T=r.kind===`ok`&&r.data.installed&&r.data.executablePath?r.data.executablePath:void 0,E=r.kind===`ok`&&r.data.installed,D=l===`installing`||m,O;t[7]===S?O=t[8]:(O=()=>void S(),t[7]=S,t[8]=O);let k;t[9]!==E||t[10]!==D||t[11]!==l?(k=D?(0,Q.jsx)(N,{className:`size-3.5 animate-spin`}):E?(0,Q.jsx)(w,{className:`size-3.5`}):l===`installed`?(0,Q.jsx)(x,{className:`size-3.5 text-green-500`}):(0,Q.jsx)(h,{className:`size-3.5`}),t[9]=E,t[10]=D,t[11]=l,t[12]=k):k=t[12];let A=D?n.browserPlaywrightInstalling:E?n.browserReinstall:n.browserPlaywrightInstall,j;t[13]!==D||t[14]!==O||t[15]!==k||t[16]!==A?(j=(0,Q.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-panel px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-raised disabled:cursor-not-allowed disabled:opacity-60`,disabled:D,onClick:O,children:[k,A]}),t[13]=D,t[14]=O,t[15]=k,t[16]=A,t[17]=j):j=t[17];let M;t[18]===n.browserPlaywrightManualInstall?M=t[19]:(M=(0,Q.jsx)(`p`,{className:`text-fg-muted`,children:n.browserPlaywrightManualInstall}),t[18]=n.browserPlaywrightManualInstall,t[19]=M);let P;t[20]===Symbol.for(`react.memo_cache_sentinel`)?(P=(0,Q.jsx)(`code`,{className:`mt-2 block w-fit rounded-md border border-edge bg-surface-base px-2 py-1 text-xs text-fg`,children:`node node_modules/playwright-core/cli.js install chromium`}),t[20]=P):P=t[20];let F;t[21]===M?F=t[22]:(F=(0,Q.jsxs)(`div`,{className:`text-xs`,children:[M,P]}),t[21]=M,t[22]=F);let I;t[23]!==y||t[24]!==g||t[25]!==n||t[26]!==p||t[27]!==m?(I=m?(0,Q.jsx)(ke,{m:n,progress:p,showLogs:!0,cancelling:g,onCancel:()=>void y()}):null,t[23]=y,t[24]=g,t[25]=n,t[26]=p,t[27]=m,t[28]=I):I=t[28];let L;t[29]!==d||t[30]!==l?(L=d?(0,Q.jsx)(Te,{kind:l===`failed`?`error`:`success`,message:d}):null,t[29]=d,t[30]=l,t[31]=L):L=t[31];let R;return t[32]!==c||t[33]!==n||t[34]!==T||t[35]!==C||t[36]!==I||t[37]!==L||t[38]!==j||t[39]!==F?(R=(0,Q.jsxs)(Ce,{icon:ee,title:n.browserPlaywrightGuideTitle,description:n.browserPlaywrightGuideDesc,status:C,statusDetail:T,m:n,embedded:c,primaryAction:j,children:[F,I,L]}),t[32]=c,t[33]=n,t[34]=T,t[35]=C,t[36]=I,t[37]=L,t[38]=j,t[39]=F,t[40]=R):R=t[40],R}async function He(e){let t=await c(e),n=await t.json().catch(()=>({}));if(!t.ok||n.ok===!1){let e=typeof n.error==`string`?n.error:n.error?.message;throw Error(e||`Request failed: ${t.status}`)}if(n.payload===void 0)throw Error(`Empty payload`);return n.payload}async function $(e,t){let n=await c(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t??{})}),r=await n.json().catch(()=>({}));if(!n.ok||r.ok===!1){let e=typeof r.error==`string`?r.error:r.error?.message;throw Error(e||`Request failed: ${n.status}`)}if(r.payload===void 0)throw Error(`Empty payload`);return r.payload}var Ue={playwright:{kind:`idle`},cloak:{kind:`idle`},extension:{kind:`idle`},extensionArtifacts:{kind:`idle`}};function We(e,t){switch(t.type){case`playwright`:return{...e,playwright:t.state};case`cloak`:return{...e,cloak:t.state};case`extension`:return{...e,extension:t.state};case`extension-artifacts`:return{...e,extensionArtifacts:t.state};case`playwright-idle`:return{...e,playwright:{kind:`idle`}};case`cloak-idle`:return{...e,cloak:{kind:`idle`}};case`extension-idle`:return{...e,extension:{kind:`idle`},extensionArtifacts:{kind:`idle`}};case`extension-start-probe`:return{...e,extension:e.extension.kind===`ok`?e.extension:{kind:`loading`}};case`extension-artifacts-start-probe`:return{...e,extensionArtifacts:e.extensionArtifacts.kind===`ok`?e.extensionArtifacts:{kind:`loading`}}}}function Ge(e){let[t,n]=(0,X.useReducer)(We,Ue),{playwright:r,cloak:i,extension:a,extensionArtifacts:o}=t,l=(0,X.useCallback)(async()=>{n({type:`playwright`,state:{kind:`loading`}});try{n({type:`playwright`,state:{kind:`ok`,data:await He(s(`/api/browser/playwright/doctor`))}})}catch(e){n({type:`playwright`,state:{kind:`error`,message:e instanceof Error?e.message:String(e)}})}},[]),u=(0,X.useCallback)(async t=>{n({type:`cloak`,state:{kind:`loading`}});let r=(t?.cacheDir??e.cacheDir??``).trim(),i=(t?.binaryPath??e.binaryPath??``).trim(),a=new URLSearchParams;r&&a.set(`cacheDir`,r),i&&a.set(`binaryPath`,i);try{let e=await He(s(`/api/browser/cloakbrowser/doctor${a.size?`?${a}`:``}`));return n({type:`cloak`,state:{kind:`ok`,data:e}}),e}catch(e){return n({type:`cloak`,state:{kind:`error`,message:e instanceof Error?e.message:String(e)}}),null}},[e.binaryPath,e.cacheDir]),d=(0,X.useCallback)(e=>{n({type:`playwright`,state:{kind:`ok`,data:e}})},[]),f=(0,X.useCallback)(e=>{n({type:`cloak`,state:{kind:`ok`,data:e}})},[]),p=(0,X.useCallback)(async()=>He(s(`/api/browser/cloakbrowser/status`)),[]),m=(0,X.useCallback)(async()=>$(s(`/api/browser/cloakbrowser/launch`),{}),[]),h=e.browserEnabled===!0&&e.probeExtension===!0,g=e.browserEnabled===!0&&e.probeLocal===!0,_=e.browserEnabled===!0&&e.probeCloak===!0,{extensionHost:v,extensionPort:y}=e,b=(0,X.useCallback)(async()=>{let e=new URLSearchParams({probe:`1`});v&&e.set(`host`,v),y!==void 0&&e.set(`port`,String(y)),n({type:`extension-start-probe`});try{let t=await c(s(`/api/browser/extension-status?${e}`),{signal:AbortSignal.timeout(3e3)}),r=await t.json().catch(()=>({}));if(!t.ok){n({type:`extension`,state:{kind:`error`,message:`HTTP ${t.status}`}});return}n({type:`extension`,state:{kind:`ok`,data:{running:r.running===!0,connected:r.connected===!0,backend:r.backend,artifacts:r.artifacts,bridgeHeld:r.bridgeHeld===!0,refCount:typeof r.refCount==`number`?r.refCount:void 0,manualBridge:r.manualBridge===!0,portConflict:r.portConflict===!0}}})}catch(e){n({type:`extension`,state:{kind:`error`,message:e instanceof Error?e.message:String(e)}})}},[v,y]),x=(0,X.useCallback)(async()=>{n({type:`extension-artifacts-start-probe`});try{let e=await He(s(`/api/browser/extension/doctor`));return n({type:`extension-artifacts`,state:{kind:`ok`,data:e}}),e}catch(e){return n({type:`extension-artifacts`,state:{kind:`error`,message:e instanceof Error?e.message:String(e)}}),null}},[]),S=(0,X.useCallback)(async e=>{let t=(await $(s(`/api/browser/extension/install`),{force:e?.force??!1})).doctor;return n({type:`extension-artifacts`,state:{kind:`ok`,data:t}}),await b(),t},[b]),C=(0,X.useCallback)(async()=>{await $(s(`/api/browser/extension/open`),{action:`chrome`})},[]),w=(0,X.useCallback)(async()=>{await $(s(`/api/browser/extension/open`),{action:`folder`})},[]);(0,X.useEffect)(()=>{if(!g){n({type:`playwright-idle`});return}l()},[g,l]),(0,X.useEffect)(()=>{if(!_){n({type:`cloak-idle`});return}u()},[_,u]);let T=(0,X.useRef)(h);T.current!==h&&(T.current=h,h||n({type:`extension-idle`})),(0,X.useEffect)(()=>{if(!h)return;b(),x();let e=setInterval(()=>void b(),5e3);return()=>clearInterval(e)},[h,b,x]);let E=(0,X.useCallback)(async e=>{await $(s(`/api/browser/extension/start`),{host:e?.host??v,port:e?.port??y}),await b()},[v,y,b]),D=(0,X.useCallback)(async()=>{await $(s(`/api/browser/extension/stop`),{}),await b()},[b]),O=(0,X.useCallback)(async()=>{await $(s(`/api/browser/extension/disconnect`),{}),await b()},[b]),k=(0,X.useRef)(null);return(0,X.useEffect)(()=>{if(!h||e.activeBackend!==`extension`){k.current=null;return}if(a.kind!==`ok`||a.data.running||a.data.bridgeHeld)return;let t=`${v}:${y??19820}`;k.current!==t&&(k.current=t,E({host:v,port:y}).catch(()=>{k.current=null}))},[h,a,v,y,e.activeBackend,E]),{playwright:r,cloak:i,extension:a,extensionArtifacts:o,refetchPlaywright:l,applyPlaywrightDoctor:d,refetchCloak:u,applyCloakDoctor:f,fetchCloakRuntimeStatus:p,launchCloak:m,refetchExtension:b,refetchExtensionArtifacts:x,installExtensionArtifacts:S,openExtensionChrome:C,revealExtensionFolder:w,pingCdp:(0,X.useCallback)(async e=>$(s(`/api/browser/cdp/ping`),{cdpUrl:e}),[]),testCloud:(0,X.useCallback)(async(e,t)=>$(s(`/api/browser/cloud/test-connection`),{provider:e,apiKey:t}),[]),launchCdp:(0,X.useCallback)(async e=>$(s(`/api/browser/cdp/launch`),{executablePath:e}),[]),stopCdp:(0,X.useCallback)(async e=>{await $(s(`/api/browser/cdp/stop`),{port:e})},[]),listCdpInstances:(0,X.useCallback)(async()=>(await He(s(`/api/browser/cdp/instances`))).instances,[]),startExtensionBridge:E,stopExtensionBridge:D,disconnectExtension:O}}var Ke=`
3
-
4
- `,qe=/\r\n/g,Je={playwright:`/api/browser/playwright/install/stream`,cloakbrowser:`/api/browser/cloakbrowser/install/stream`},Ye={playwright:`/api/browser/playwright/install/cancel`,cloakbrowser:`/api/browser/cloakbrowser/install/cancel`},Xe=8;function Ze(){return{phase:null,message:null,percent:null,lines:[]}}function Qe(e,t){let n={phase:t.phase,message:t.message??t.line??e.message,percent:t.percent??e.percent,lines:e.lines};if(t.line){let r=[...e.lines,t.line];n.lines=r.length>Xe?r.slice(-8):r}return n}async function $e(e,t,n){let r=e.getReader(),i=new TextDecoder,a=``,o=null,s=e=>{let n=``,r=``;for(let t of e.split(`
5
- `)){let e=t.replace(/\r$/,``);e.startsWith(`event:`)?n=e.slice(6).trim():e.startsWith(`data:`)&&(r+=e.slice(5).trimStart())}if(r){if(n===`progress`){try{let e=JSON.parse(r);e&&typeof e==`object`&&typeof e.phase==`string`&&t(e)}catch{}return}if(n===`result`)try{let e=JSON.parse(r);o=e.ok?{ok:!0,payload:e.payload}:{ok:!1,error:String(e.error??`unknown`),message:typeof e.message==`string`?e.message:void 0,status:e.error===`busy`?409:e.error===`cancelled`?499:500}}catch{o={ok:!1,error:`parse`,status:0}}}};try{let e=async()=>{if(o!==null)return o;if(n?.aborted)return await r.cancel().catch(()=>{}),{ok:!1,error:`cancelled`,status:499};let{done:t,value:c}=await r.read();if(t)return o??{ok:!1,error:`no-result`,status:0};a+=i.decode(c,{stream:!0}),a=a.replace(qe,`
6
- `);let l=a.split(Ke);a=l.pop()??``;for(let e of l)e.length&&s(e);return e()},t=await e();if(t)return t}catch(e){if(n?.aborted||e instanceof DOMException&&e.name===`AbortError`)return{ok:!1,error:`cancelled`,status:499};throw e}finally{r.releaseLock()}return o||(n?.aborted?{ok:!1,error:`cancelled`,status:499}:{ok:!1,error:`no-result`,status:0})}function et(e){let[t,n]=(0,X.useState)(Ze),[r,i]=(0,X.useState)(!1),[a,o]=(0,X.useState)(!1),l=(0,X.useRef)(!1),u=(0,X.useRef)(null),d=(0,X.useCallback)(()=>{l.current||n(Ze())},[]),f=(0,X.useCallback)(async()=>{if(l.current){o(!0);try{await c(s(Ye[e]),{method:`POST`}).catch(()=>{}),u.current?.abort()}finally{o(!1)}}},[e]);return{progress:t,running:r,cancelling:a,run:(0,X.useCallback)(async t=>{if(l.current)return{ok:!1,error:`busy`,status:409,errorMessage:`An install for this browser type is already in progress.`};let r=new AbortController;u.current=r,l.current=!0,i(!0),n(Ze());try{let i=await c(s(Je[e]),{method:`POST`,headers:{Accept:`text/event-stream`,...t.body===void 0?{}:{"Content-Type":`application/json`}},body:t.body===void 0?void 0:JSON.stringify(t.body),signal:r.signal});if(!i.ok||!i.body){let e=await i.text().catch(()=>``),t=`HTTP ${i.status}`;try{let n=JSON.parse(e);typeof n.message==`string`?t=n.message:typeof n.error==`string`&&(t=n.error)}catch{e&&(t=e.slice(0,500))}return{ok:!1,error:i.status===409?`busy`:`http`,status:i.status,errorMessage:t}}let a=await $e(i.body,e=>{n(t=>Qe(t,e))},r.signal);return a.ok?a:a.error===`cancelled`?{...a,errorMessage:void 0}:{...a,errorMessage:a.message??(a.error===`busy`?`An install for this browser type is already in progress.`:t.fallbackError)}}catch(e){return r.signal.aborted||e instanceof DOMException&&e.name===`AbortError`?{ok:!1,error:`cancelled`,status:499}:{ok:!1,error:`network`,errorMessage:e instanceof Error?e.message:t.fallbackError}}finally{u.current===r&&(u.current=null),l.current=!1,i(!1),o(!1)}},[e]),reset:d,cancel:f}}function tt(e){let t=(0,Z.c)(150),{a:n,form:r,update:a,activeTab:s,setActiveTab:c}=e,l=o(rt),u=b(nt),d=et(`playwright`),f=et(`cloakbrowser`),p=r.browserEnabled&&(s===`overview`||s===`extension`),m=r.browserEnabled&&(s===`overview`||s===`local`),h=r.browserEnabled&&(s===`overview`||s===`cloakbrowser`),_;t[0]!==r.browserBackend||t[1]!==r.browserCloakBinaryPath||t[2]!==r.browserCloakCacheDir||t[3]!==r.browserEnabled||t[4]!==r.browserExtensionHost||t[5]!==r.browserExtensionPort||t[6]!==h||t[7]!==p||t[8]!==m?(_={cacheDir:r.browserCloakCacheDir,binaryPath:r.browserCloakBinaryPath,browserEnabled:r.browserEnabled,activeBackend:r.browserBackend,probeExtension:p,probeLocal:m,probeCloak:h,extensionHost:r.browserExtensionHost,extensionPort:r.browserExtensionPort},t[0]=r.browserBackend,t[1]=r.browserCloakBinaryPath,t[2]=r.browserCloakCacheDir,t[3]=r.browserEnabled,t[4]=r.browserExtensionHost,t[5]=r.browserExtensionPort,t[6]=h,t[7]=p,t[8]=m,t[9]=_):_=t[9];let v=Ge(_),y;t[10]===v.playwright?y=t[11]:(y=me(v.playwright),t[10]=v.playwright,t[11]=y);let x=y,S;t[12]===v.cloak?S=t[13]:(S=me(v.cloak),t[12]=v.cloak,t[13]=S);let C=S,w;t[14]===v.extension?w=t[15]:(w=ge(v.extension),t[14]=v.extension,t[15]=w);let T=w,E;t[16]!==n||t[17]!==v.extension?(E=_e(v.extension,n),t[16]=n,t[17]=v.extension,t[18]=E):E=t[18];let D=E,O;t[19]!==n||t[20]!==C||t[21]!==T||t[22]!==D||t[23]!==x||t[24]!==u?(O=[{value:`extension`,icon:I,name:n.browserBackendExtension,tagline:n.browserModeExtTagline,status:T,statusLabel:D},{value:`local`,icon:ee,name:n.browserBackendLocal,tagline:n.browserModeLocalTagline,status:x,statusLabel:he(x,n)},{value:`cloakbrowser`,icon:P,name:n.browserBackendCloakBrowser,tagline:n.browserModeCloakTagline,status:C,statusLabel:he(C,n)},{value:`cdp`,icon:g,name:n.browserBackendCdp,tagline:n.browserModeCdpTagline},{value:`cloud`,icon:B,name:n.browserBackendCloud,tagline:n.browserModeCloudTagline}].filter(e=>U(e.value,u)),t[19]=n,t[20]=C,t[21]=T,t[22]=D,t[23]=x,t[24]=u,t[25]=O):O=t[25];let k=O,A;t[26]!==c||t[27]!==a?(A=e=>{a({browserEnabled:!0,browserBackend:e}),c(e)},t[26]=c,t[27]=a,t[28]=A):A=t[28];let j=A,M=!r.browserEnabled&&`pointer-events-none opacity-40`,N;t[29]===M?N=t[30]:(N=i(`flex flex-col gap-5 transition-opacity`,M),t[29]=M,t[30]=N);let F=!r.browserEnabled,L;t[31]!==n||t[32]!==s||t[33]!==v.disconnectExtension||t[34]!==v.extension||t[35]!==v.extensionArtifacts||t[36]!==v.installExtensionArtifacts||t[37]!==v.openExtensionChrome||t[38]!==v.refetchExtensionArtifacts||t[39]!==v.revealExtensionFolder||t[40]!==v.startExtensionBridge||t[41]!==v.stopExtensionBridge||t[42]!==r.browserExtensionConnectionTimeout||t[43]!==r.browserExtensionHost||t[44]!==r.browserExtensionPort||t[45]!==a?(L=s===`extension`?(0,Q.jsx)(H,{children:(0,Q.jsx)(Be,{embedded:!0,m:n,probe:v.extension,artifacts:v.extensionArtifacts,form:{port:r.browserExtensionPort,host:r.browserExtensionHost,connectionTimeoutMs:r.browserExtensionConnectionTimeout},onChange:e=>a({...e.port===void 0?{}:{browserExtensionPort:e.port},...e.host===void 0?{}:{browserExtensionHost:e.host},...e.connectionTimeoutMs===void 0?{}:{browserExtensionConnectionTimeout:e.connectionTimeoutMs}}),startBridge:v.startExtensionBridge,stopBridge:v.stopExtensionBridge,disconnectExtension:v.disconnectExtension,installArtifacts:v.installExtensionArtifacts,refetchArtifacts:v.refetchExtensionArtifacts,openExtensionChrome:v.openExtensionChrome,revealExtensionFolder:v.revealExtensionFolder})}):null,t[31]=n,t[32]=s,t[33]=v.disconnectExtension,t[34]=v.extension,t[35]=v.extensionArtifacts,t[36]=v.installExtensionArtifacts,t[37]=v.openExtensionChrome,t[38]=v.refetchExtensionArtifacts,t[39]=v.revealExtensionFolder,t[40]=v.startExtensionBridge,t[41]=v.stopExtensionBridge,t[42]=r.browserExtensionConnectionTimeout,t[43]=r.browserExtensionHost,t[44]=r.browserExtensionPort,t[45]=a,t[46]=L):L=t[46];let z;t[47]!==n||t[48]!==s||t[49]!==v.applyPlaywrightDoctor||t[50]!==v.playwright||t[51]!==v.refetchPlaywright||t[52]!==d?(z=s===`local`?(0,Q.jsx)(H,{children:(0,Q.jsx)(Ve,{embedded:!0,m:n,doctor:v.playwright,refetch:v.refetchPlaywright,applyDoctor:v.applyPlaywrightDoctor,installStream:d})}):null,t[47]=n,t[48]=s,t[49]=v.applyPlaywrightDoctor,t[50]=v.playwright,t[51]=v.refetchPlaywright,t[52]=d,t[53]=z):z=t[53];let V;t[54]!==n||t[55]!==s||t[56]!==f||t[57]!==v.applyCloakDoctor||t[58]!==v.cloak||t[59]!==v.fetchCloakRuntimeStatus||t[60]!==v.launchCloak||t[61]!==v.refetchCloak||t[62]!==r.browserCloakBinaryPath||t[63]!==r.browserCloakCacheDir||t[64]!==r.browserCloakExtraArgs||t[65]!==r.browserCloakFingerprintPlatform||t[66]!==r.browserCloakKeepOpen||t[67]!==r.browserCloakLocale||t[68]!==r.browserCloakTemporaryProfile||t[69]!==r.browserCloakTimezone||t[70]!==r.browserCloakWebrtcIp||t[71]!==r.browserHumanPreset||t[72]!==r.browserHumanize||t[73]!==a?(V=s===`cloakbrowser`?(0,Q.jsx)(H,{children:(0,Q.jsx)(Me,{embedded:!0,m:n,doctor:v.cloak,refetch:v.refetchCloak,applyDoctor:v.applyCloakDoctor,installStream:f,fetchRuntimeStatus:v.fetchCloakRuntimeStatus,launchCloak:v.launchCloak,form:{cacheDir:r.browserCloakCacheDir,binaryPath:r.browserCloakBinaryPath,keepOpen:r.browserCloakKeepOpen,temporaryProfile:r.browserCloakTemporaryProfile,humanize:r.browserHumanize,humanPreset:r.browserHumanPreset,timezone:r.browserCloakTimezone,locale:r.browserCloakLocale,webrtcIp:r.browserCloakWebrtcIp,fingerprintPlatform:r.browserCloakFingerprintPlatform,extraArgs:r.browserCloakExtraArgs},onChange:e=>a({...e.cacheDir===void 0?{}:{browserCloakCacheDir:e.cacheDir},...e.binaryPath===void 0?{}:{browserCloakBinaryPath:e.binaryPath},...e.keepOpen===void 0?{}:{browserCloakKeepOpen:e.keepOpen},...e.temporaryProfile===void 0?{}:{browserCloakTemporaryProfile:e.temporaryProfile},...e.humanize===void 0?{}:{browserHumanize:e.humanize},...e.humanPreset===void 0?{}:{browserHumanPreset:e.humanPreset},...e.timezone===void 0?{}:{browserCloakTimezone:e.timezone},...e.locale===void 0?{}:{browserCloakLocale:e.locale},...e.webrtcIp===void 0?{}:{browserCloakWebrtcIp:e.webrtcIp},...e.fingerprintPlatform===void 0?{}:{browserCloakFingerprintPlatform:e.fingerprintPlatform},...e.extraArgs===void 0?{}:{browserCloakExtraArgs:e.extraArgs}})})}):null,t[54]=n,t[55]=s,t[56]=f,t[57]=v.applyCloakDoctor,t[58]=v.cloak,t[59]=v.fetchCloakRuntimeStatus,t[60]=v.launchCloak,t[61]=v.refetchCloak,t[62]=r.browserCloakBinaryPath,t[63]=r.browserCloakCacheDir,t[64]=r.browserCloakExtraArgs,t[65]=r.browserCloakFingerprintPlatform,t[66]=r.browserCloakKeepOpen,t[67]=r.browserCloakLocale,t[68]=r.browserCloakTemporaryProfile,t[69]=r.browserCloakTimezone,t[70]=r.browserCloakWebrtcIp,t[71]=r.browserHumanPreset,t[72]=r.browserHumanize,t[73]=a,t[74]=V):V=t[74];let W;t[75]!==n||t[76]!==s||t[77]!==v.launchCdp||t[78]!==v.listCdpInstances||t[79]!==v.pingCdp||t[80]!==v.stopCdp||t[81]!==r.browserCdpUrl||t[82]!==a?(W=s===`cdp`?(0,Q.jsx)(H,{children:(0,Q.jsx)(De,{embedded:!0,m:n,cdpUrl:r.browserCdpUrl,onCdpUrlChange:e=>a({browserCdpUrl:e}),launch:v.launchCdp,stop:v.stopCdp,listInstances:v.listCdpInstances,ping:v.pingCdp})}):null,t[75]=n,t[76]=s,t[77]=v.launchCdp,t[78]=v.listCdpInstances,t[79]=v.pingCdp,t[80]=v.stopCdp,t[81]=r.browserCdpUrl,t[82]=a,t[83]=W):W=t[83];let G;t[84]!==n||t[85]!==s||t[86]!==v.testCloud||t[87]!==r.browserCloudApiKey||t[88]!==r.browserCloudProjectId||t[89]!==r.browserCloudProvider||t[90]!==r.browserCloudRegion||t[91]!==a?(G=s===`cloud`?(0,Q.jsx)(H,{children:(0,Q.jsx)(Fe,{embedded:!0,m:n,form:{provider:r.browserCloudProvider,apiKey:r.browserCloudApiKey,projectId:r.browserCloudProjectId,region:r.browserCloudRegion},onChange:e=>a({...e.provider===void 0?{}:{browserCloudProvider:e.provider},...e.apiKey===void 0?{}:{browserCloudApiKey:e.apiKey},...e.projectId===void 0?{}:{browserCloudProjectId:e.projectId},...e.region===void 0?{}:{browserCloudRegion:e.region}}),testCloud:v.testCloud})}):null,t[84]=n,t[85]=s,t[86]=v.testCloud,t[87]=r.browserCloudApiKey,t[88]=r.browserCloudProjectId,t[89]=r.browserCloudProvider,t[90]=r.browserCloudRegion,t[91]=a,t[92]=G):G=t[92];let q;t[93]!==L||t[94]!==z||t[95]!==V||t[96]!==W||t[97]!==G||t[98]!==N||t[99]!==F?(q=(0,Q.jsxs)(`div`,{className:N,"aria-hidden":F,children:[L,z,V,W,G]}),t[93]=L,t[94]=z,t[95]=V,t[96]=W,t[97]=G,t[98]=N,t[99]=F,t[100]=q):q=t[100];let J=q;if(s===`overview`){let e;t[101]!==n||t[102]!==r.browserEnabled||t[103]!==j?(e=r.browserEnabled?null:(0,Q.jsx)(fe,{m:n,onStart:j}),t[101]=n,t[102]=r.browserEnabled,t[103]=j,t[104]=e):e=t[104];let o;t[105]===Symbol.for(`react.memo_cache_sentinel`)?(o=(0,Q.jsx)(`div`,{className:`flex size-9 shrink-0 items-center justify-center rounded-lg bg-surface-hover/90 text-fg-muted`,"aria-hidden":!0,children:(0,Q.jsx)(R,{className:`size-4`,strokeWidth:1.75})}),t[105]=o):o=t[105];let s;t[106]===a?s=t[107]:(s=e=>a({browserEnabled:e.target.checked}),t[106]=a,t[107]=s);let u;t[108]!==r.browserEnabled||t[109]!==s?(u=(0,Q.jsx)(`input`,{type:`checkbox`,className:`size-3.5 shrink-0 rounded border-edge`,checked:r.browserEnabled,onChange:s}),t[108]=r.browserEnabled,t[109]=s,t[110]=u):u=t[110];let d;t[111]===n.browserEnabledOn?d=t[112]:(d=(0,Q.jsx)(`span`,{children:n.browserEnabledOn}),t[111]=n.browserEnabledOn,t[112]=d);let f;t[113]!==u||t[114]!==d?(f=(0,Q.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm font-medium text-fg`,children:[u,d]}),t[113]=u,t[114]=d,t[115]=f):f=t[115];let p;t[116]!==n.desc.browserEnabled||t[117]!==n.label.browserEnabled||t[118]!==f?(p=(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-1 items-start gap-3`,children:[o,(0,Q.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,Q.jsx)(K,{label:n.label.browserEnabled,description:n.desc.browserEnabled,children:f})})]}),t[116]=n.desc.browserEnabled,t[117]=n.label.browserEnabled,t[118]=f,t[119]=p):p=t[119];let m;t[120]!==n.browserDocsLink||t[121]!==l?(m=(0,Q.jsx)(ue,{language:l,label:n.browserDocsLink,className:`shrink-0 pt-1`}),t[120]=n.browserDocsLink,t[121]=l,t[122]=m):m=t[122];let h;t[123]!==p||t[124]!==m?(h=(0,Q.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[p,m]}),t[123]=p,t[124]=m,t[125]=h):h=t[125];let g;t[126]!==n||t[127]!==r.browserBackend||t[128]!==r.browserEnabled||t[129]!==k||t[130]!==c||t[131]!==a?(g=r.browserEnabled?(0,Q.jsx)(`div`,{id:se(`connection`),className:i(`scroll-mt-24 transition-opacity`,!r.browserEnabled&&`pointer-events-none opacity-40`),children:(0,Q.jsx)(ae,{m:n,value:r.browserBackend,onChange:e=>a({browserBackend:e}),onOpenConfig:c,options:k})}):(0,Q.jsx)(`p`,{className:`text-xs text-fg-muted`,children:n.browserDisabledHint}),t[126]=n,t[127]=r.browserBackend,t[128]=r.browserEnabled,t[129]=k,t[130]=c,t[131]=a,t[132]=g):g=t[132];let _;t[133]!==h||t[134]!==g?(_=(0,Q.jsx)(H,{children:(0,Q.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[h,g]})}),t[133]=h,t[134]=g,t[135]=_):_=t[135];let v=!r.browserEnabled&&`pointer-events-none opacity-40`,y;t[136]===v?y=t[137]:(y=i(`transition-opacity`,v),t[136]=v,t[137]=y);let b=!r.browserEnabled,x;t[138]!==n||t[139]!==r||t[140]!==a?(x=(0,Q.jsx)(le,{a:n,form:r,update:a}),t[138]=n,t[139]=r,t[140]=a,t[141]=x):x=t[141];let S;t[142]!==y||t[143]!==b||t[144]!==x?(S=(0,Q.jsx)(te,{children:(0,Q.jsx)(`div`,{className:y,"aria-hidden":b,children:x})}),t[142]=y,t[143]=b,t[144]=x,t[145]=S):S=t[145];let C;return t[146]!==e||t[147]!==_||t[148]!==S?(C=(0,Q.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[e,_,S]}),t[146]=e,t[147]=_,t[148]=S,t[149]=C):C=t[149],C}return Se(s)?J:null}function nt(e){return e.mode}function rt(e){return e.language}function it(e,t){return e.browserTabs[t]}function at(){let e=(0,Z.c)(52),t=o(st),n;e[0]===t?n=e[1]:(n=a(t),e[0]=t,e[1]=n);let r=n,s=r.agentSettings,c=r.chat,l=b(ot),u=ne(s),[d,p]=f(),m;e[2]===l?m=e[3]:(m=G(ve,l),e[2]=l,e[3]=m);let h=m,g;e[4]===d?g=e[5]:(g=ce(d.get(`focus`)),e[4]=d,e[5]=g);let _=g,v;e[6]!==_||e[7]!==d?(v=_?be[_]??xe(d.get(`tab`)):xe(d.get(`tab`)),e[6]=_,e[7]=d,e[8]=v):v=e[8];let y=v,x;bb0:{if(!u.form){x=null;break bb0}let t;e[9]!==s||e[10]!==c||e[11]!==u.form||e[12]!==u.update?(t={form:u.form,update:u.update,a:s,chat:c},e[9]=s,e[10]=c,e[11]=u.form,e[12]=u.update,e[13]=t):t=e[13],x=t}let S=x,C;e[14]===p?C=e[15]:(C=e=>{p(t=>{let n=new URLSearchParams(t);return n.delete(`focus`),e===`overview`?n.delete(`tab`):n.set(`tab`,e),n},{replace:!0})},e[14]=p,e[15]=C);let w=C;W(y,w);let T,E;e[16]!==_||e[17]!==d||e[18]!==p?(T=()=>{if(!_)return;let e=be[_]??xe(d.get(`tab`));p(t=>{let n=new URLSearchParams(t);return n.delete(`focus`),e===`overview`?n.delete(`tab`):n.set(`tab`,e),n},{replace:!0});let t=_===`runtime`||_===`security`?se(_):null;if(!t)return;let n=window.setTimeout(()=>{document.getElementById(t)?.scrollIntoView({behavior:`smooth`,block:`start`})},80);return()=>window.clearTimeout(n)},E=[_,d,p],e[16]=_,e[17]=d,e[18]=p,e[19]=T,e[20]=E):(T=e[19],E=e[20]),(0,X.useEffect)(T,E);let D=s.browserTabsAria,O;e[21]!==y||e[22]!==w||e[23]!==h?(O=e=>{if(e.key!==`ArrowLeft`&&e.key!==`ArrowRight`)return;e.preventDefault();let t=h.indexOf(y);if(t<0)return;let n=h[(t+(e.key===`ArrowRight`?1:-1)+h.length)%h.length];w(n)},e[21]=y,e[22]=w,e[23]=h,e[24]=O):O=e[24];let k;if(e[25]!==y||e[26]!==s||e[27]!==w||e[28]!==h){let t;e[30]!==y||e[31]!==s||e[32]!==w?(t=e=>{let t=e===y;return(0,Q.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":t,id:`agent-browser-tab-${e}`,"aria-controls":`agent-browser-panel-${e}`,className:i(`shrink-0 rounded-lg px-3 py-2 text-sm font-medium transition-colors`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,L.press,t?`bg-accent-soft text-accent-fg`:`text-fg-muted hover:bg-surface-hover hover:text-fg`),onClick:()=>w(e),children:it(s,e)},e)},e[30]=y,e[31]=s,e[32]=w,e[33]=t):t=e[33],k=h.map(t),e[25]=y,e[26]=s,e[27]=w,e[28]=h,e[29]=k}else k=e[29];let A;e[34]===k?A=e[35]:(A=(0,Q.jsx)(`div`,{className:`-mx-1 flex gap-1 overflow-x-auto px-1 pb-1`,children:k}),e[34]=k,e[35]=A);let j=`agent-browser-panel-${y}`,M=`agent-browser-tab-${y}`,N;e[36]!==y||e[37]!==S||e[38]!==w?(N=S?(0,Q.jsx)(tt,{...S,activeTab:y,setActiveTab:w}):null,e[36]=y,e[37]=S,e[38]=w,e[39]=N):N=e[39];let P;e[40]!==j||e[41]!==M||e[42]!==N?(P=(0,Q.jsx)(`div`,{role:`tabpanel`,id:j,"aria-labelledby":M,className:`min-w-0`,children:N}),e[40]=j,e[41]=M,e[42]=N,e[43]=P):P=e[43];let F;e[44]!==s.browserTabsAria||e[45]!==A||e[46]!==P||e[47]!==O?(F=(0,Q.jsxs)(`div`,{className:`flex flex-col gap-5`,role:`tablist`,"aria-label":D,onKeyDown:O,children:[A,P]}),e[44]=s.browserTabsAria,e[45]=A,e[46]=P,e[47]=O,e[48]=F):F=e[48];let I;return e[49]!==F||e[50]!==u?(I=(0,Q.jsx)(Y,{sectionId:`agent-browser`,intro:``,vm:u,tabbed:!0,children:F}),e[49]=F,e[50]=u,e[51]=I):I=e[51],I}function ot(e){return e.mode}function st(e){return e.language}export{at as AgentBrowserSettingsPage};