@xopcai/xopc 0.0.112 → 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 (351) hide show
  1. package/dist/browser-ext/icons/icon-128.png +0 -0
  2. package/dist/browser-ext/icons/icon-16.png +0 -0
  3. package/dist/browser-ext/icons/icon-32.png +0 -0
  4. package/dist/browser-ext/icons/icon-48.png +0 -0
  5. package/dist/browser-ext/manifest.json +1 -1
  6. package/dist/extensions/telegram/xopc.extension.json +1 -1
  7. package/dist/extensions/weixin/src/delivery-to.d.ts +3 -3
  8. package/dist/extensions/weixin/src/delivery-to.js.map +1 -1
  9. package/dist/gateway/static/root/apple-touch-icon.png +0 -0
  10. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-EhRp-ZMa.js → agent-avatar-dicebear-Fp-p7bP1.js} +1 -1
  11. package/dist/gateway/static/root/assets/agent-browser-settings-page-CWh7trjd.js +6 -0
  12. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-kC8OuLoj.js +1 -0
  13. package/dist/gateway/static/root/assets/agents-DJWG26Si.js +71 -0
  14. package/dist/gateway/static/root/assets/{app-management-settings-panel-BIy7KEsM.js → app-management-settings-panel-v24i25Oj.js} +1 -1
  15. package/dist/gateway/static/root/assets/{appearance-settings-DGQG8NwA.js → appearance-settings-ycbdJRuZ.js} +1 -1
  16. package/dist/gateway/static/root/assets/apps-page-0V3DXZ7J.js +1 -0
  17. package/dist/gateway/static/root/assets/{archive-plugin-uuQPupqx.js → archive-plugin-CJzSADJo.js} +1 -1
  18. package/dist/gateway/static/root/assets/{attachment-load-DBkv0cAv.js → attachment-load-BTAB4zGS.js} +1 -1
  19. package/dist/gateway/static/root/assets/{binary-plugins-DxxN_VAR.js → binary-plugins-DXR1-mct.js} +1 -1
  20. package/dist/gateway/static/root/assets/{block-editor-CwnUlRmO.js → block-editor-CzQri9h2.js} +44 -44
  21. package/dist/gateway/static/root/assets/channels-settings-CIKOkYdO.js +1 -0
  22. package/dist/gateway/static/root/assets/{config-api-BD-NcD5d.js → config-api-DRqjEvAx.js} +1 -1
  23. package/dist/gateway/static/root/assets/connectors-settings-ClrDS5jH.js +2 -0
  24. package/dist/gateway/static/root/assets/{cron-api-C5DoipZA.js → cron-api-BXaZXv1o.js} +1 -1
  25. package/dist/gateway/static/root/assets/cron-page-Chi_4u4P.js +3 -0
  26. package/dist/gateway/static/root/assets/dreaming-settings-B0_rs2tj.js +1 -0
  27. package/dist/gateway/static/root/assets/{extension-debug-page-BDHA9o_e.js → extension-debug-page-DSkqMYo7.js} +1 -1
  28. package/dist/gateway/static/root/assets/{extension-page-DmDLVSPE.js → extension-page-h2dGDbMN.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-settings-page-1124aHw_.js → extension-settings-page-hN99RhOi.js} +1 -1
  30. package/dist/gateway/static/root/assets/{fetch-DOe56Wmy.js → fetch-D9QqUtzZ.js} +1 -1
  31. package/dist/gateway/static/root/assets/{format-interval-label-tsMSvBSR.js → format-interval-label-D6E687rG.js} +1 -1
  32. package/dist/gateway/static/root/assets/{gateway-config-api-CsD4FC9D.js → gateway-config-api-CLt_SKTC.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-settings-HQ8FBhY2.js → gateway-settings-1PDi4lI0.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-startup-retry-C1zg7pH3.js → gateway-startup-retry-N7Z_sz7p.js} +1 -1
  35. package/dist/gateway/static/root/assets/goal-detail-page-D_wwXL-t.js +1 -0
  36. package/dist/gateway/static/root/assets/goals-page-DZ2toZ8y.js +2 -0
  37. package/dist/gateway/static/root/assets/{goals-settings-B5nI6lgz.js → goals-settings-LFlwtIKE.js} +1 -1
  38. package/dist/gateway/static/root/assets/{heartbeat-config-api-CIv42nJD.js → heartbeat-config-api-DGPadTw-.js} +1 -1
  39. package/dist/gateway/static/root/assets/{heartbeat-settings-DFcVuJ3M.js → heartbeat-settings-BHHAs8ZX.js} +1 -1
  40. package/dist/gateway/static/root/assets/index-DefIdW9q.js +122 -0
  41. package/dist/gateway/static/root/assets/index-DzmWBkq-.css +1 -0
  42. package/dist/gateway/static/root/assets/{interval-presets-DGP3S7OB.js → interval-presets-CEklPQ_r.js} +1 -1
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-fETaDYQP.js → keyboard-shortcuts-settings-Ce_aQ8Iv.js} +1 -1
  44. package/dist/gateway/static/root/assets/logs-page-j_D2QTuQ.js +2 -0
  45. package/dist/gateway/static/root/assets/{markdown-split-CgeBJMOD.js → markdown-split-BMz3xPXO.js} +1 -1
  46. package/dist/gateway/static/root/assets/{media-plugins-C30GzlV2.js → media-plugins-BalOSoz9.js} +1 -1
  47. package/dist/gateway/static/root/assets/messages-BN_WiUg0.js +3 -0
  48. package/dist/gateway/static/root/assets/models-hub-panel-CMH_TmZz.js +2 -0
  49. package/dist/gateway/static/root/assets/note-detail-page-O18BrQPq.js +2 -0
  50. package/dist/gateway/static/root/assets/{note-image-lightbox-t1g0qZYh.js → note-image-lightbox-C5D1Q5mY.js} +1 -1
  51. package/dist/gateway/static/root/assets/notes-page-B_ZYCmY9.js +1 -0
  52. package/dist/gateway/static/root/assets/{preview-open-alternatives-DeWp9x5g.js → preview-open-alternatives-CYFR5U9l.js} +1 -1
  53. package/dist/gateway/static/root/assets/remote-access-hub-CwKgWixY.js +1 -0
  54. package/dist/gateway/static/root/assets/{save-bar-controls-BOaAOJI3.js → save-bar-controls-BQ79Z5IP.js} +1 -1
  55. package/dist/gateway/static/root/assets/{schedule-field-BLWLKqgw.js → schedule-field-Bgk6Emue.js} +1 -1
  56. package/dist/gateway/static/root/assets/{schema-form-plqRFYT8.js → schema-form-DzS36TMa.js} +1 -1
  57. package/dist/gateway/static/root/assets/sessions-page-C4fcD-7B.js +1 -0
  58. package/dist/gateway/static/root/assets/settings-advanced-gate-Ad2OJ86w.js +1 -0
  59. package/dist/gateway/static/root/assets/{settings-collapsible-section-BP5zRrDI.js → settings-collapsible-section-CdjFnSAy.js} +1 -1
  60. package/dist/gateway/static/root/assets/{settings-form-section-Bv8MZplG.js → settings-form-section-DZLy_exu.js} +1 -1
  61. package/dist/gateway/static/root/assets/settings-page-D2BMY5wo.js +1 -0
  62. package/dist/gateway/static/root/assets/setup-status-panel-aWwxl_E1.js +1 -0
  63. package/dist/gateway/static/root/assets/{share-preview-page-4OX1YCgp.js → share-preview-page-_qRDr4g_.js} +1 -1
  64. package/dist/gateway/static/root/assets/shares-settings-DUE83uIf.js +1 -0
  65. package/dist/gateway/static/root/assets/skill-reload-api-mWKJcrog.js +1 -0
  66. package/dist/gateway/static/root/assets/skills-page-0Sx1Q58n.js +2 -0
  67. package/dist/gateway/static/root/assets/{system-settings-panel-CGy4f_s2.js → system-settings-panel-hqaBF5aG.js} +1 -1
  68. package/dist/gateway/static/root/assets/use-agent-defaults-form-zbVIQLOA.js +1 -0
  69. package/dist/gateway/static/root/assets/{use-channel-catalog-CjGHnDvN.js → use-channel-catalog-CbXq97rT.js} +1 -1
  70. package/dist/gateway/static/root/assets/{use-settings-tab-guard-BMMFa0oA.js → use-settings-tab-guard-DwS3drWK.js} +1 -1
  71. package/dist/gateway/static/root/assets/voice-api-key-field-D6HR0hR2.js +1 -0
  72. package/dist/gateway/static/root/assets/{voice-player-store-D5vzWwls.js → voice-player-store-DSuOd9zy.js} +1 -1
  73. package/dist/gateway/static/root/assets/workflow-page.utils-C0Uq3xyq.js +1 -0
  74. package/dist/gateway/static/root/assets/workflows-page-DW0fmWhQ.js +18 -0
  75. package/dist/gateway/static/root/favicon-16x16.png +0 -0
  76. package/dist/gateway/static/root/favicon-32x32.png +0 -0
  77. package/dist/gateway/static/root/favicon-icon.svg +1 -0
  78. package/dist/gateway/static/root/favicon.ico +0 -0
  79. package/dist/gateway/static/root/favicon.png +0 -0
  80. package/dist/gateway/static/root/favicon.svg +24 -17
  81. package/dist/gateway/static/root/index.html +5 -5
  82. package/dist/gateway/static/root/logo-dark.svg +23 -15
  83. package/dist/gateway/static/root/logo.svg +23 -16
  84. package/dist/package.js +1 -1
  85. package/dist/src/agent/agent-manager.d.ts +8 -0
  86. package/dist/src/agent/agent-manager.js +57 -22
  87. package/dist/src/agent/agent-manager.js.map +1 -1
  88. package/dist/src/agent/bootstrap/project-agents-context.d.ts +2 -0
  89. package/dist/src/agent/bootstrap/project-agents-context.js +32 -0
  90. package/dist/src/agent/bootstrap/project-agents-context.js.map +1 -0
  91. package/dist/src/agent/goals/persistent-goal-service.js +2 -4
  92. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  93. package/dist/src/agent/inbound/inbound-loop.js +5 -1
  94. package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
  95. package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -2
  96. package/dist/src/agent/inbound/turn-dispatcher.js +2 -2
  97. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  98. package/dist/src/agent/mcp/bundle-mcp-materialize.d.ts +27 -0
  99. package/dist/src/agent/mcp/bundle-mcp-materialize.js +49 -1
  100. package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
  101. package/dist/src/agent/mcp/bundle-mcp-runtime.js +78 -3
  102. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  103. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +19 -0
  104. package/dist/src/agent/service/btw-query.js +11 -3
  105. package/dist/src/agent/service/btw-query.js.map +1 -1
  106. package/dist/src/agent/service/parse-outbound-session-key.js +13 -8
  107. package/dist/src/agent/service/parse-outbound-session-key.js.map +1 -1
  108. package/dist/src/agent/service/process-direct-one-shot.d.ts +2 -2
  109. package/dist/src/agent/service/process-direct-one-shot.js +1 -1
  110. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  111. package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
  112. package/dist/src/agent/service/process-direct-streaming.js +10 -5
  113. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  114. package/dist/src/agent/service.d.ts +1 -1
  115. package/dist/src/agent/service.js +9 -5
  116. package/dist/src/agent/service.js.map +1 -1
  117. package/dist/src/agent/service.types.d.ts +5 -0
  118. package/dist/src/agent/skills/filesystem-watcher.js +4 -3
  119. package/dist/src/agent/skills/filesystem-watcher.js.map +1 -1
  120. package/dist/src/agent/skills/index.js +2 -1
  121. package/dist/src/agent/skills/index.js.map +1 -1
  122. package/dist/src/agent/skills/skill-manage-ops.js +2 -1
  123. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  124. package/dist/src/agent/skills/types.d.ts +1 -1
  125. package/dist/src/agent/skills/watcher.js +2 -5
  126. package/dist/src/agent/skills/watcher.js.map +1 -1
  127. package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
  128. package/dist/src/agent/skills/workspace-skills-dir.js +11 -0
  129. package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -0
  130. package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
  131. package/dist/src/agent/tool-manuals/browser.js +62 -3
  132. package/dist/src/agent/tool-manuals/browser.js.map +1 -1
  133. package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -1
  134. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +13 -4
  135. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  136. package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -2
  137. package/dist/src/agent/tools/browser/tool/schemas.js +1 -2
  138. package/dist/src/agent/tools/browser/tool/schemas.js.map +1 -1
  139. package/dist/src/agent/tools/factory.js +1 -10
  140. package/dist/src/agent/tools/factory.js.map +1 -1
  141. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  142. package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
  143. package/dist/src/agent/workflow/subagent-runner.js +18 -1
  144. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  145. package/dist/src/ai-assist/text-assist.d.ts +3 -0
  146. package/dist/src/ai-assist/text-assist.js +25 -7
  147. package/dist/src/ai-assist/text-assist.js.map +1 -1
  148. package/dist/src/browser/actions/extension-registry-bridge.js +91 -7
  149. package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
  150. package/dist/src/browser/actions/registry.js +383 -7
  151. package/dist/src/browser/actions/registry.js.map +1 -1
  152. package/dist/src/browser/actions/types.d.ts +11 -3
  153. package/dist/src/browser/index.js +2 -2
  154. package/dist/src/browser/pipeline/output.d.ts +18 -16
  155. package/dist/src/browser/pipeline/output.js +28 -20
  156. package/dist/src/browser/pipeline/output.js.map +1 -1
  157. package/dist/src/browser/pipeline/runner.d.ts +7 -14
  158. package/dist/src/browser/pipeline/runner.js +349 -102
  159. package/dist/src/browser/pipeline/runner.js.map +1 -1
  160. package/dist/src/browser/pipeline/schema.d.ts +1 -0
  161. package/dist/src/browser/pipeline/schema.js +35 -58
  162. package/dist/src/browser/pipeline/schema.js.map +1 -1
  163. package/dist/src/browser/pipeline/source.d.ts +2 -0
  164. package/dist/src/browser/pipeline/source.js +10 -1
  165. package/dist/src/browser/pipeline/source.js.map +1 -1
  166. package/dist/src/browser/pipeline/template.d.ts +10 -2
  167. package/dist/src/browser/pipeline/template.js +50 -8
  168. package/dist/src/browser/pipeline/template.js.map +1 -1
  169. package/dist/src/channels/plugins/types.adapters.d.ts +2 -2
  170. package/dist/src/chat-commands/builtins/config.js +3 -5
  171. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  172. package/dist/src/chat-commands/context.d.ts +5 -0
  173. package/dist/src/chat-commands/context.js +18 -9
  174. package/dist/src/chat-commands/context.js.map +1 -1
  175. package/dist/src/chat-commands/index.d.ts +1 -1
  176. package/dist/src/chat-commands/index.js +2 -2
  177. package/dist/src/chat-commands/index.js.map +1 -1
  178. package/dist/src/chat-commands/processor.js +22 -21
  179. package/dist/src/chat-commands/processor.js.map +1 -1
  180. package/dist/src/chat-commands/session-key.d.ts +3 -15
  181. package/dist/src/chat-commands/session-key.js +3 -49
  182. package/dist/src/chat-commands/session-key.js.map +1 -1
  183. package/dist/src/chat-commands/types.d.ts +4 -0
  184. package/dist/src/cli/commands/browser-cli-helpers.js +11 -5
  185. package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
  186. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  187. package/dist/src/cli/commands/doctor/checks/session-integrity.js +8 -8
  188. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  189. package/dist/src/config/rules.js +5 -0
  190. package/dist/src/config/rules.js.map +1 -1
  191. package/dist/src/connectors/builtin-catalog.js +180 -1
  192. package/dist/src/connectors/builtin-catalog.js.map +1 -1
  193. package/dist/src/connectors/health.js +18 -9
  194. package/dist/src/connectors/health.js.map +1 -1
  195. package/dist/src/connectors/types.d.ts +19 -0
  196. package/dist/src/connectors/usage.js +12 -4
  197. package/dist/src/connectors/usage.js.map +1 -1
  198. package/dist/src/cron/executor.js.map +1 -1
  199. package/dist/src/cron/types.d.ts +2 -2
  200. package/dist/src/extensions/types/tui.d.ts +2 -0
  201. package/dist/src/gateway/heartbeat/service.js +13 -1
  202. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  203. package/dist/src/gateway/hono/app.js +13 -4
  204. package/dist/src/gateway/hono/app.js.map +1 -1
  205. package/dist/src/gateway/hono/oauth-async.js +1 -1
  206. package/dist/src/gateway/hono/routes/agent-stream.js +6 -6
  207. package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
  208. package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +1 -1
  209. package/dist/src/gateway/hono/routes/config-patch/gateway.js +6 -0
  210. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  211. package/dist/src/gateway/hono/routes/goals.js +16 -3
  212. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  213. package/dist/src/gateway/hono/routes/logs.js +1 -0
  214. package/dist/src/gateway/hono/routes/logs.js.map +1 -1
  215. package/dist/src/gateway/hono/routes/mcp.js +27 -8
  216. package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
  217. package/dist/src/gateway/hono/routes/notes.js +14 -2
  218. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  219. package/dist/src/gateway/hono/routes/sessions.js +62 -4
  220. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  221. package/dist/src/gateway/hono/routes/workspace.js +3 -66
  222. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  223. package/dist/src/gateway/hono/sse.d.ts +2 -2
  224. package/dist/src/gateway/hono/sse.js +7 -15
  225. package/dist/src/gateway/hono/sse.js.map +1 -1
  226. package/dist/src/gateway/resolve-webchat-session-key.d.ts +2 -6
  227. package/dist/src/gateway/resolve-webchat-session-key.js +5 -31
  228. package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -1
  229. package/dist/src/gateway/service/agent-runner.d.ts +2 -3
  230. package/dist/src/gateway/service/agent-runner.js +9 -22
  231. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  232. package/dist/src/gateway/service/run-gateway-agent.js +9 -7
  233. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  234. package/dist/src/gateway/service/sessions-api.d.ts +9 -0
  235. package/dist/src/gateway/service/sessions-api.js +11 -0
  236. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  237. package/dist/src/gateway/service.d.ts +1 -1
  238. package/dist/src/gateway/service.js +19 -5
  239. package/dist/src/gateway/service.js.map +1 -1
  240. package/dist/src/gateway/workspace-file-search.d.ts +9 -0
  241. package/dist/src/gateway/workspace-file-search.js +76 -0
  242. package/dist/src/gateway/workspace-file-search.js.map +1 -0
  243. package/dist/src/goals/goal-notifications.d.ts +2 -0
  244. package/dist/src/goals/goal-notifications.js +16 -11
  245. package/dist/src/goals/goal-notifications.js.map +1 -1
  246. package/dist/src/goals/goal-service.js +1 -6
  247. package/dist/src/goals/goal-service.js.map +1 -1
  248. package/dist/src/project-trust/trust-store.js +2 -0
  249. package/dist/src/project-trust/trust-store.js.map +1 -1
  250. package/dist/src/session/index.d.ts +1 -1
  251. package/dist/src/session/index.js +2 -2
  252. package/dist/src/session/init-session-turn.js +6 -9
  253. package/dist/src/session/init-session-turn.js.map +1 -1
  254. package/dist/src/session/manager.d.ts +5 -1
  255. package/dist/src/session/manager.js +5 -2
  256. package/dist/src/session/manager.js.map +1 -1
  257. package/dist/src/session/reset-type.d.ts +0 -2
  258. package/dist/src/session/reset-type.js +3 -9
  259. package/dist/src/session/reset-type.js.map +1 -1
  260. package/dist/src/session/resolve-session.js +9 -20
  261. package/dist/src/session/resolve-session.js.map +1 -1
  262. package/dist/src/session/store-reader.d.ts +5 -0
  263. package/dist/src/session/store-reader.js +1 -0
  264. package/dist/src/session/store.d.ts +11 -3
  265. package/dist/src/session/store.js +29 -13
  266. package/dist/src/session/store.js.map +1 -1
  267. package/dist/src/session/types.d.ts +2 -4
  268. package/dist/src/session/types.js.map +1 -1
  269. package/dist/src/storage/sqlite/index.d.ts +2 -2
  270. package/dist/src/storage/sqlite/index.js +3 -3
  271. package/dist/src/storage/sqlite/migrations/010_session_id_identity.sql +30 -0
  272. package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
  273. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  274. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  275. package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
  276. package/dist/src/storage/sqlite/row-mappers.d.ts +4 -4
  277. package/dist/src/storage/sqlite/row-mappers.js +11 -14
  278. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  279. package/dist/src/storage/sqlite/schema.js +3 -3
  280. package/dist/src/storage/sqlite/schema.js.map +1 -1
  281. package/dist/src/storage/sqlite/schema.sql +37 -10
  282. package/dist/src/storage/sqlite/session-metadata.d.ts +2 -7
  283. package/dist/src/storage/sqlite/session-metadata.js +18 -72
  284. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  285. package/dist/src/storage/sqlite/session-repository.d.ts +6 -5
  286. package/dist/src/storage/sqlite/session-repository.js +34 -40
  287. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  288. package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -2
  289. package/dist/src/storage/sqlite/transcript-repository.js +52 -52
  290. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
  291. package/dist/src/tui/backends/embedded-backend.d.ts +11 -4
  292. package/dist/src/tui/backends/embedded-backend.js +27 -1
  293. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  294. package/dist/src/tui/backends/gateway-sse-backend.d.ts +4 -1
  295. package/dist/src/tui/backends/gateway-sse-backend.js +21 -2
  296. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  297. package/dist/src/tui/extension-host/autocomplete.js +13 -10
  298. package/dist/src/tui/extension-host/autocomplete.js.map +1 -1
  299. package/dist/src/tui/extension-host/runtime.d.ts +7 -0
  300. package/dist/src/tui/extension-host/runtime.js +6 -4
  301. package/dist/src/tui/extension-host/runtime.js.map +1 -1
  302. package/dist/src/tui/tui-backend.d.ts +9 -0
  303. package/dist/src/tui/tui-commands.js +85 -6
  304. package/dist/src/tui/tui-commands.js.map +1 -1
  305. package/dist/src/tui/tui-file-autocomplete.d.ts +5 -0
  306. package/dist/src/tui/tui-file-autocomplete.js +26 -0
  307. package/dist/src/tui/tui-file-autocomplete.js.map +1 -0
  308. package/dist/src/tui/tui-picker-overlay.js +1 -1
  309. package/dist/src/tui/tui.js +29 -11
  310. package/dist/src/tui/tui.js.map +1 -1
  311. package/dist/src/utils/logger/context.d.ts +2 -2
  312. package/dist/src/utils/logger/context.js +2 -1
  313. package/dist/src/utils/logger/context.js.map +1 -1
  314. package/dist/src/utils/logger/log-store.js +1 -0
  315. package/dist/src/utils/logger/log-store.js.map +1 -1
  316. package/dist/src/utils/logger/pino-record.js +3 -0
  317. package/dist/src/utils/logger/pino-record.js.map +1 -1
  318. package/dist/src/utils/logger/types.d.ts +5 -0
  319. package/dist/src/utils/logger/types.js.map +1 -1
  320. package/dist/src/workflows/service/workflow-session-bridge.js +13 -1
  321. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  322. package/package.json +1 -1
  323. package/dist/gateway/static/root/assets/agent-browser-settings-page-H4foVCiS.js +0 -6
  324. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-DDNw2oNU.js +0 -1
  325. package/dist/gateway/static/root/assets/agents-E_X2kzS1.js +0 -71
  326. package/dist/gateway/static/root/assets/apps-page-BZLvInLr.js +0 -1
  327. package/dist/gateway/static/root/assets/channels-settings-BHvUKlzw.js +0 -1
  328. package/dist/gateway/static/root/assets/connectors-settings-VBzXcEXL.js +0 -2
  329. package/dist/gateway/static/root/assets/cron-page-BLTpdm34.js +0 -3
  330. package/dist/gateway/static/root/assets/dreaming-settings-DSVhXTPq.js +0 -1
  331. package/dist/gateway/static/root/assets/goal-detail-page-BG3Onph0.js +0 -1
  332. package/dist/gateway/static/root/assets/goals-page-DgeKn8zL.js +0 -2
  333. package/dist/gateway/static/root/assets/index-5A_ZaABy.css +0 -1
  334. package/dist/gateway/static/root/assets/index-BTmbp2AU.js +0 -121
  335. package/dist/gateway/static/root/assets/logs-page-B1-b27lK.js +0 -2
  336. package/dist/gateway/static/root/assets/messages-BUUfPaZ9.js +0 -3
  337. package/dist/gateway/static/root/assets/models-hub-panel-DPcTS1-u.js +0 -2
  338. package/dist/gateway/static/root/assets/note-detail-page-xeGb4owe.js +0 -2
  339. package/dist/gateway/static/root/assets/notes-page-C_TdnKBe.js +0 -1
  340. package/dist/gateway/static/root/assets/remote-access-hub-BtkPmJIN.js +0 -1
  341. package/dist/gateway/static/root/assets/sessions-page-DOUjxzJm.js +0 -1
  342. package/dist/gateway/static/root/assets/settings-advanced-gate-qK_bnTrw.js +0 -1
  343. package/dist/gateway/static/root/assets/settings-page-DmDfE1ww.js +0 -1
  344. package/dist/gateway/static/root/assets/setup-status-panel-BEFwNcIZ.js +0 -1
  345. package/dist/gateway/static/root/assets/shares-settings-CbKmJZot.js +0 -1
  346. package/dist/gateway/static/root/assets/skill-reload-api-YdtnUHtK.js +0 -1
  347. package/dist/gateway/static/root/assets/skills-page-DwW1IzQ0.js +0 -2
  348. package/dist/gateway/static/root/assets/use-agent-defaults-form-BMuMvzl_.js +0 -1
  349. package/dist/gateway/static/root/assets/voice-api-key-field-DnRbhMNq.js +0 -1
  350. package/dist/gateway/static/root/assets/workflow-page.utils-tjGpRVnw.js +0 -1
  351. package/dist/gateway/static/root/assets/workflows-page-DqqHKGj2.js +0 -18
@@ -14,6 +14,7 @@ import { resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession }
14
14
  import { extractTextContent, loadProfileMarkdownFiles } from "./context/workspace.js";
15
15
  import { clearBootstrapSnapshot } from "./bootstrap/bootstrap-cache.js";
16
16
  import { resolveBootstrapContextSync } from "./bootstrap/bootstrap-files.js";
17
+ import { loadProjectAgentsContextFile } from "./bootstrap/project-agents-context.js";
17
18
  import { createSkillConfigManager, isSkillEnabled, resolveSkillConfig } from "./skills/config.js";
18
19
  import { isMemorySubsystemEnabled, shouldRegisterCuratedMemoryTool } from "./memory/memory-config.js";
19
20
  import { AgentToolsFactory } from "./tools/factory.js";
@@ -29,6 +30,7 @@ import { WorkspaceRuntimeRegistry } from "./workspace-runtime/registry.js";
29
30
  import { BackgroundReviewCoordinator } from "./background-review/coordinator.js";
30
31
  import { maybeRequestChannelExecApproval } from "../channels/exec-approval-runtime.js";
31
32
  import { SkillFilesystemWatcher } from "./skills/filesystem-watcher.js";
33
+ import { ProjectTrustStore, hasTrustRequiringProjectResources } from "../project-trust/trust-store.js";
32
34
  import { basename, resolve, sep } from "node:path";
33
35
  import { Agent } from "@earendil-works/pi-agent-core";
34
36
  //#region src/agent/agent-manager.ts
@@ -71,6 +73,7 @@ var AgentManager = class {
71
73
  lastExplicitSkillDiskRefreshAt = 0;
72
74
  skillsUpdatedTimer;
73
75
  pendingSkillsUpdatedReason;
76
+ projectTrustStore = new ProjectTrustStore();
74
77
  constructor(config) {
75
78
  this.config = config;
76
79
  this.baseWorkspacePath = this.computeBaseWorkspacePath();
@@ -121,6 +124,13 @@ var AgentManager = class {
121
124
  if (fromMap !== void 0) return fromMap;
122
125
  return resolveEffectiveAgentProfileForSession(cfg, sessionKey).resolvedWorkspacePath;
123
126
  }
127
+ getWorkspaceRuntimeForSession(sessionKey) {
128
+ const resolvedPath = sessionKey ? this.getResolvedWorkspaceForSession(sessionKey) : this.baseWorkspacePath;
129
+ return this.workspaceRuntimes.getOrCreate(resolvedPath);
130
+ }
131
+ getCurrentWorkspaceRuntime() {
132
+ return this.getWorkspaceRuntimeForSession(this.config.getCurrentContext?.()?.sessionKey);
133
+ }
124
134
  /**
125
135
  * Sync in-memory workspace override from session config (after load or PATCH).
126
136
  * Pass `null` to clear when the session has no `workingDirectoryOverride` on disk.
@@ -184,8 +194,8 @@ var AgentManager = class {
184
194
  bus: this.config.bus,
185
195
  getConfig: () => this.mergedConfig(),
186
196
  getPrimaryModel: () => this.resolveModelStringToModel(this.pickDefaultModelRef()),
187
- getBuiltinMemoryStore: () => this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).builtinMemoryStore,
188
- getMemoryManager: () => this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).memoryManager,
197
+ getBuiltinMemoryStore: () => this.getCurrentWorkspaceRuntime().builtinMemoryStore,
198
+ getMemoryManager: () => this.getCurrentWorkspaceRuntime().memoryManager,
189
199
  getSessionStore: this.config.getSessionStore,
190
200
  gatewayClarify: this.config.gatewayClarify,
191
201
  getCronService: this.config.getCronService,
@@ -218,11 +228,10 @@ var AgentManager = class {
218
228
  };
219
229
  }
220
230
  getMemoryManager() {
221
- return this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).memoryManager;
231
+ return this.getCurrentWorkspaceRuntime().memoryManager;
222
232
  }
223
233
  getMemoryManagerForSession(sessionKey) {
224
- const path = this.getResolvedWorkspaceForSession(sessionKey);
225
- return this.workspaceRuntimes.getOrCreate(path).memoryManager;
234
+ return this.getWorkspaceRuntimeForSession(sessionKey).memoryManager;
226
235
  }
227
236
  /**
228
237
  * Prefix the user turn with fenced prefetched memory (external providers).
@@ -259,9 +268,9 @@ var AgentManager = class {
259
268
  agent: inst.agent,
260
269
  registeredToolNames: inst.registeredToolNames,
261
270
  skillAllowlist: inst.effectiveProfile.skillsAllowlist,
262
- workspacePath: inst.resolvedWorkspacePath,
271
+ workspacePath: this.getResolvedWorkspaceForSession(sessionKey),
263
272
  lastAssistantText: this.getLastAssistantContent(sessionKey),
264
- workspaceRuntime: this.workspaceRuntimes.getOrCreate(inst.resolvedWorkspacePath)
273
+ workspaceRuntime: this.getWorkspaceRuntimeForSession(sessionKey)
265
274
  });
266
275
  }
267
276
  /**
@@ -269,16 +278,15 @@ var AgentManager = class {
269
278
  */
270
279
  expandSkillUserText(text) {
271
280
  const sessionKey = (this.config.getCurrentContext?.())?.sessionKey;
272
- const path = sessionKey ? this.getResolvedWorkspaceForSession(sessionKey) : this.baseWorkspacePath;
273
281
  const inst = sessionKey ? this.agents.get(sessionKey) : void 0;
274
- return this.workspaceRuntimes.getOrCreate(path).skillManager.expandCommand(text, {
282
+ return this.getWorkspaceRuntimeForSession(sessionKey).skillManager.expandCommand(text, {
275
283
  skillAllowlist: inst?.effectiveProfile.skillsAllowlist,
276
284
  registeredToolNames: inst?.registeredToolNames
277
285
  });
278
286
  }
279
287
  /** Structured SKILL.md preview for the gateway console. */
280
288
  getSkillMarkdownSource(skillName) {
281
- const skill = this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).skillManager.findSkill(skillName);
289
+ const skill = this.getCurrentWorkspaceRuntime().skillManager.findSkill(skillName);
282
290
  if (!skill) return null;
283
291
  return {
284
292
  name: skill.name,
@@ -294,6 +302,23 @@ var AgentManager = class {
294
302
  const cfg = this.config.config;
295
303
  return loadProfileMarkdownFiles(resolveAgentProfileDir(cfg, profile.agentId));
296
304
  }
305
+ isProjectWorkspaceTrusted(workspaceDir) {
306
+ if (!hasTrustRequiringProjectResources(workspaceDir)) return false;
307
+ const persisted = this.projectTrustStore.get(workspaceDir);
308
+ if (persisted === false) return false;
309
+ if (persisted === true) return true;
310
+ try {
311
+ return this.config.isWorkspaceTrusted?.(workspaceDir) === true;
312
+ } catch (err) {
313
+ const errorMessage = err instanceof Error ? err.message : String(err);
314
+ log.warn({
315
+ err,
316
+ workspaceDir,
317
+ errorMessage
318
+ }, `Workspace trust override failed: ${errorMessage}`);
319
+ return false;
320
+ }
321
+ }
297
322
  resolveContextFilesForSession(sessionKey, profile, excludeHeartbeat) {
298
323
  const cfg = this.config.config;
299
324
  const profileDir = resolveAgentProfileDir(cfg, profile.agentId);
@@ -306,6 +331,12 @@ var AgentManager = class {
306
331
  excludeHeartbeat: excludeHeartbeat ?? !heartbeatEnabled,
307
332
  contextInjection
308
333
  });
334
+ const shouldAppendProjectContext = contextInjection === "always" || contextInjection === "continuation-skip" && contextFiles.length > 0;
335
+ const workspaceDir = this.getResolvedWorkspaceForSession(sessionKey);
336
+ if (shouldAppendProjectContext && this.isProjectWorkspaceTrusted(workspaceDir)) {
337
+ const projectAgentsFile = loadProjectAgentsContextFile(workspaceDir);
338
+ if (projectAgentsFile) contextFiles.push(projectAgentsFile);
339
+ }
309
340
  return contextFiles;
310
341
  }
311
342
  skillCatalogEntryFromSkill(s, skillsConfig = createSkillConfigManager(resolveStateDir()).load(), lock = loadSkillsLock()) {
@@ -334,7 +365,7 @@ var AgentManager = class {
334
365
  getSkillCatalogSnapshot() {
335
366
  const skillsConfig = createSkillConfigManager(resolveStateDir()).load();
336
367
  const lock = loadSkillsLock();
337
- const rt = this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath);
368
+ const rt = this.getCurrentWorkspaceRuntime();
338
369
  return {
339
370
  catalog: rt.skillManager.getSkills().map((s) => this.skillCatalogEntryFromSkill(s, skillsConfig, lock)),
340
371
  version: rt.skillManager.getVersion(),
@@ -387,15 +418,16 @@ var AgentManager = class {
387
418
  touched.add(resolvedPath);
388
419
  }
389
420
  for (const instance of this.agents.values()) {
390
- const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);
391
- if (!touched.has(instance.resolvedWorkspacePath)) {
421
+ const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);
422
+ const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);
423
+ if (!touched.has(resolvedWorkspacePath)) {
392
424
  rt.skillManager.refreshPromptFromConfig();
393
- touched.add(instance.resolvedWorkspacePath);
425
+ touched.add(resolvedWorkspacePath);
394
426
  }
395
427
  const contextFiles = this.resolveContextFilesForSession(instance.sessionKey, instance.effectiveProfile);
396
428
  const newPrompt = rt.systemPromptBuilder.build(contextFiles, {
397
429
  externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),
398
- workspaceOverride: instance.resolvedWorkspacePath,
430
+ workspaceOverride: resolvedWorkspacePath,
399
431
  profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),
400
432
  systemPromptOverride: instance.effectiveProfile.systemPromptOverride,
401
433
  skillAllowlist: instance.effectiveProfile.skillsAllowlist,
@@ -452,12 +484,13 @@ var AgentManager = class {
452
484
  for (const rt of this.workspaceRuntimes.values()) rt.skillManager.reload();
453
485
  const touched = /* @__PURE__ */ new Set();
454
486
  for (const instance of this.agents.values()) {
455
- const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);
456
- if (!touched.has(instance.resolvedWorkspacePath)) touched.add(instance.resolvedWorkspacePath);
487
+ const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);
488
+ const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);
489
+ if (!touched.has(resolvedWorkspacePath)) touched.add(resolvedWorkspacePath);
457
490
  const contextFiles = this.resolveContextFilesForSession(instance.sessionKey, instance.effectiveProfile);
458
491
  const newPrompt = rt.systemPromptBuilder.rebuild(contextFiles, {
459
492
  externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),
460
- workspaceOverride: instance.resolvedWorkspacePath,
493
+ workspaceOverride: resolvedWorkspacePath,
461
494
  profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),
462
495
  systemPromptOverride: instance.effectiveProfile.systemPromptOverride,
463
496
  skillAllowlist: instance.effectiveProfile.skillsAllowlist,
@@ -572,13 +605,14 @@ var AgentManager = class {
572
605
  const instance = this.agents.get(sessionKey);
573
606
  if (!instance) return;
574
607
  const cfg = this.config.config;
575
- const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);
608
+ const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(sessionKey);
609
+ const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);
576
610
  const contextFiles = this.resolveContextFilesForSession(sessionKey, instance.effectiveProfile);
577
611
  const modelRef = instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel;
578
612
  const thinkingLevel = instance.effectiveProfile.thinkingDefault ?? this.config.thinkingLevel ?? "medium";
579
613
  instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {
580
614
  externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),
581
- workspaceOverride: instance.resolvedWorkspacePath,
615
+ workspaceOverride: resolvedWorkspacePath,
582
616
  profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),
583
617
  systemPromptOverride: instance.effectiveProfile.systemPromptOverride,
584
618
  skillAllowlist: instance.effectiveProfile.skillsAllowlist,
@@ -743,12 +777,13 @@ var AgentManager = class {
743
777
  const model = resolveModel(modelId);
744
778
  instance.agent.state.model = model;
745
779
  const cfg = this.config.config;
746
- const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);
780
+ const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(sessionKey);
781
+ const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);
747
782
  const contextFiles = this.resolveContextFilesForSession(sessionKey, instance.effectiveProfile);
748
783
  const thinkingLevel = instance.agent.state.thinkingLevel ?? instance.effectiveProfile.thinkingDefault ?? this.config.thinkingLevel ?? "medium";
749
784
  instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {
750
785
  externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),
751
- workspaceOverride: instance.resolvedWorkspacePath,
786
+ workspaceOverride: resolvedWorkspacePath,
752
787
  profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),
753
788
  systemPromptOverride: instance.effectiveProfile.systemPromptOverride,
754
789
  skillAllowlist: instance.effectiveProfile.skillsAllowlist,
@@ -1 +1 @@
1
- {"version":3,"file":"agent-manager.js","names":[],"sources":["../../../src/agent/agent-manager.ts"],"sourcesContent":["/**\n * Agent Manager - Manages Agent instances per session\n *\n * Each session gets its own Agent instance for true isolation\n * and concurrent processing across sessions.\n */\n\nimport {\n Agent,\n type AgentMessage,\n type AgentEvent,\n type ThinkingLevel,\n} from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { AgentInstanceGateway } from './agent-instance-gateway.js';\nimport { type Config, getAgentDefaultModelRef } from '../config/schema.js';\nimport { applyConfigOverrides } from '../config/runtime-overrides.js';\nimport { resolveAgentProfileDir } from './agent-scope.js';\nimport {\n type EffectiveAgentProfile,\n resolveEffectiveAgentProfile,\n resolveEffectiveAgentProfileForSession,\n} from '../config/agent-profile.js';\nimport { expandWorkspacePathString } from '../config/workspace-path.js';\nimport type { ModelManager } from './models/manager.js';\nimport { createLogger } from '../utils/logger.js';\nimport { resolveProviderApiKeySync } from '../auth/sync-provider-auth.js';\nimport { resolveModel, getDefaultModelSync, getApiKeySync } from '../providers/index.js';\nimport { createExtensionAwareStreamFn } from '../providers/extension-stream-bridge.js';\nimport { CredentialResolver } from '../auth/credentials.js';\nimport { resolveBundledSkillsDir, resolveStateDir } from '../config/paths.js';\nimport { loadProfileMarkdownFiles, extractTextContent } from './context/workspace.js';\nimport { clearBootstrapSnapshot, resolveBootstrapContextSync } from './bootstrap/bootstrap-files.js';\nimport type { EmbeddedContextFile } from './bootstrap/types.js';\nimport { AgentToolsFactory } from './tools/factory.js';\nimport { parseMcpToolName } from './mcp/bundle-mcp-policy.js';\nimport {\n disposeAllSessionMcpRuntimes,\n retireSessionMcpRuntimeForSessionKey,\n} from './mcp/bundle-mcp-tools.js';\nimport { evictAllEmbeddedSessionRunners, evictEmbeddedSessionRunner } from './embedded/session-runner.js';\nimport type { GatewayClarifyRequestFn } from './tools/clarify-tool.js';\nimport type { ExtensionRegistryImpl as ExtensionRegistry } from '../extensions/index.js';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { CronService } from '../cron/index.js';\nimport type { SessionStore } from '../session/store.js';\nimport { isValidSkillEnvVarName } from './skills/required-env-vars.js';\nimport type { SessionContext } from './session/session-context.js';\nimport type {\n Skill,\n SkillDiagnostic,\n SkillMarkdownPreviewPayload,\n SkillRuntimeStatus,\n} from './skills/types.js';\nimport { createSkillConfigManager, isSkillEnabled, resolveSkillConfig } from './skills/config.js';\nimport { isUnderManagedSkillsDir } from './skills/managed-store.js';\nimport { loadSkillsLock, type SkillHubLockEntry } from './skills/hub-lock.js';\nimport { basename, resolve, sep } from 'node:path';\n\nimport {\n isMemorySubsystemEnabled,\n shouldRegisterCuratedMemoryTool,\n} from './memory/memory-config.js';\nimport type { MemoryManager } from './memory/manager.js';\nimport { MemoryPrefetchCoordinator } from './memory/prefetch-coordinator.js';\nimport { WorkspaceRuntimeRegistry, type WorkspaceRuntime } from './workspace-runtime/registry.js';\nimport { BackgroundReviewCoordinator } from './background-review/coordinator.js';\nimport { maybeRequestChannelExecApproval } from '../channels/exec-approval-runtime.js';\nimport { SkillFilesystemWatcher } from './skills/filesystem-watcher.js';\n\nconst log = createLogger('AgentManager');\n\nexport interface SkillCatalogEntry {\n directoryId: string;\n name: string;\n description: string;\n category?: string;\n source: Skill['source'];\n path: string;\n managed: boolean;\n /** User toggle in ~/.xopc/skills.json (`entries[name].enabled`). Default true. */\n enabled: boolean;\n /** When true, skill is never injected into `<available_skills>` (SKILL.md frontmatter). */\n disableModelInvocation: boolean;\n /** Hub install provenance when under ~/.xopc/skills and listed in skills-lock.json. */\n hub?: SkillHubLockEntry;\n}\n\nexport interface SkillCatalogRuntimeMeta {\n version: string;\n loadedAt: number;\n diagnostics: SkillDiagnostic[];\n status: SkillRuntimeStatus;\n}\n\nexport interface SkillCatalogSnapshot extends SkillCatalogRuntimeMeta {\n catalog: SkillCatalogEntry[];\n}\n\nexport type AgentSkillUnavailableReason = 'agent-denied' | 'disabled' | 'requirements-unmet' | 'model-invocation-disabled';\n\nexport interface AgentSkillAvailabilityEntry extends SkillCatalogEntry {\n availableForCurrentAgent: boolean;\n unavailableReason: AgentSkillUnavailableReason | null;\n}\n\nexport interface AgentSkillAvailabilityPayload {\n agentId: string;\n version: string;\n loadedAt: number;\n diagnostics: SkillDiagnostic[];\n status: SkillRuntimeStatus;\n defaultsAllowlist?: string[];\n agentAllowlist?: string[];\n effectiveAllowlist?: string[];\n skills: AgentSkillAvailabilityEntry[];\n}\n\nexport interface AgentManagerConfig {\n workspace: string;\n model?: string;\n config?: Config;\n extensionRegistry?: ExtensionRegistry;\n hookRunner?: import('../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n getCurrentContext: () => SessionContext | null;\n /** Session persistence (enables `session_search` when set). */\n getSessionStore?: () => SessionStore;\n /** Clears per-session profile default on teardown. */\n getModelManager?: () => ModelManager;\n // Thinking configuration\n thinkingLevel?: ThinkingLevel;\n reasoningLevel?: 'off' | 'on' | 'stream';\n verboseLevel?: 'off' | 'on' | 'full';\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: exposes CronService for the `cronjob` tool. */\n getCronService?: () => CronService | undefined;\n /** Gateway: starts persisted workflow runs (dedicated chat session per run). */\n getWorkflowRunService?: () => import('../workflows/service/workflow-run-service.types.js').WorkflowRunServiceLike | undefined;\n /** Runtime notification for UI/CLI shells that cache skill catalogs. */\n onSkillsUpdated?: (payload: { reason: 'disk' | 'config' }) => void;\n}\n\nexport interface AgentInstance {\n agent: Agent;\n sessionKey: string;\n createdAt: number;\n lastUsedAt: number;\n effectiveProfile: EffectiveAgentProfile;\n resolvedWorkspacePath: string;\n /** Tool names registered on this agent (for skill indexing / tool gating). */\n registeredToolNames: string[];\n /** Declared env var names from skill_view; shell reads values from process.env at spawn time. */\n skillEnvPassthroughKeys: Set<string>;\n}\n\n\nexport class AgentManager implements AgentInstanceGateway {\n private agents = new Map<string, AgentInstance>();\n private config: AgentManagerConfig;\n private toolsFactory: AgentToolsFactory;\n\n private mergedConfig(): Config | undefined {\n const base = this.config.config;\n return base ? applyConfigOverrides(base) : undefined;\n }\n /** Default agent workspace (effective profile for `getDefaultAgentId`). */\n private baseWorkspacePath: string;\n /** Per-session absolute markdown workspace when `SessionAgentConfig.workingDirectoryOverride` is set. */\n private sessionWorkspaceOverrides = new Map<string, string>();\n private defaultModel: string;\n private credentialCache = new Map<string, string>();\n private credentialResolver: CredentialResolver;\n private workspaceRuntimes: WorkspaceRuntimeRegistry;\n private memoryPrefetch: MemoryPrefetchCoordinator;\n private backgroundReview: BackgroundReviewCoordinator;\n private skillFilesystemWatcher: SkillFilesystemWatcher;\n private skillDiskRefreshInProgress = false;\n private skillDiskRefreshPending = false;\n private lastExplicitSkillDiskRefreshAt = 0;\n private skillsUpdatedTimer: NodeJS.Timeout | undefined;\n private pendingSkillsUpdatedReason: 'disk' | 'config' | undefined;\n\n constructor(config: AgentManagerConfig) {\n this.config = config;\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.skillFilesystemWatcher = new SkillFilesystemWatcher({\n onChange: (event) => {\n log.info({ changedPath: event.changedPath }, 'Skill filesystem changed; refreshing skills');\n this.refreshSkillsAfterDiskChange('watch');\n },\n });\n this.skillFilesystemWatcher.refreshPrimaryWorkspace(this.baseWorkspacePath);\n this.workspaceRuntimes = new WorkspaceRuntimeRegistry({\n getConfig: () => this.config.config!,\n bundledSkillsDir: resolveBundledSkillsDir(),\n onRuntimeCreated: (resolvedPath) => {\n this.skillFilesystemWatcher.watchWorkspace(resolvedPath);\n },\n });\n this.memoryPrefetch = new MemoryPrefetchCoordinator({\n getConfig: () => this.config.config,\n getMemoryManagerForSession: (sk) => this.getMemoryManagerForSession(sk),\n getLastAssistantContent: (sk) => this.getLastAssistantContent(sk),\n });\n this.backgroundReview = new BackgroundReviewCoordinator({\n getConfig: () => this.mergedConfig(),\n onSkillsFilesystemMutate: () => this.refreshSkillsAfterDiskChange('explicit'),\n });\n this.toolsFactory = new AgentToolsFactory(this.buildToolsFactoryDeps());\n\n this.defaultModel = config.model || getDefaultModelSync(config.config);\n\n this.credentialResolver = new CredentialResolver();\n this.warmCredentialCache().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Credential cache pre-warm failed: ${em}`);\n });\n }\n\n private computeBaseWorkspacePath(): string {\n const cfg = this.config.config;\n if (!cfg) {\n return expandWorkspacePathString(this.config.workspace);\n }\n return resolveEffectiveAgentProfileForSession(cfg, null).resolvedWorkspacePath;\n }\n\n /**\n * Workspace root for inbound attachments / side effects for this session's agent id.\n * Uses in-memory session workspace overrides when the session has a persisted `workingDirectoryOverride`.\n */\n getResolvedWorkspaceForSession(sessionKey: string): string {\n const cfg = this.config.config!;\n const fromMap = this.sessionWorkspaceOverrides.get(sessionKey);\n if (fromMap !== undefined) {\n return fromMap;\n }\n return resolveEffectiveAgentProfileForSession(cfg, sessionKey).resolvedWorkspacePath;\n }\n\n /**\n * Sync in-memory workspace override from session config (after load or PATCH).\n * Pass `null` to clear when the session has no `workingDirectoryOverride` on disk.\n */\n setSessionWorkspaceOverride(sessionKey: string, absolutePath: string | null): void {\n if (absolutePath === null || absolutePath === '') {\n this.sessionWorkspaceOverrides.delete(sessionKey);\n } else {\n this.sessionWorkspaceOverrides.set(sessionKey, absolutePath);\n }\n }\n\n /** Merged `thinkingDefault` for this session's agent id (defaults + `agents.list`). */\n getThinkingDefaultForSession(\n sessionKey: string,\n ): import('./transcript/thinking-types.js').ThinkLevel | undefined {\n const cfg = this.mergedConfig();\n if (!cfg) {\n return undefined;\n }\n return resolveEffectiveAgentProfileForSession(cfg, sessionKey).thinkingDefault;\n }\n\n private pickDefaultModelRef(): string {\n const cfg = this.mergedConfig();\n const ref = getAgentDefaultModelRef(cfg);\n return ref?.trim() || getDefaultModelSync(cfg);\n }\n\n private resolveModelStringToModel(modelRef: string): Model<Api> {\n try {\n return resolveModel(modelRef);\n } catch {\n const fallback = getDefaultModelSync(this.mergedConfig());\n log.warn({ modelRef, fallback }, 'Model not found, using default');\n return resolveModel(fallback);\n }\n }\n\n /**\n * Keep defaults in sync when config is hot-reloaded or saved from the UI.\n *\n * The previous implementation rebuilt the entire `AgentToolsFactory` (80+ lines\n * of dependency wiring) on every reload. The factory's deps are now built from\n * a single helper ({@link buildToolsFactoryDeps}) and read `this.*` through\n * closures, so existing instances automatically see the new config without\n * reconstruction. The browser is still shut down because its cached settings\n * (headless mode, backend choice) come from the config snapshot at connect time.\n */\n updateAgentDefaults(config: Config): void {\n this.config.config = config;\n const ref = getAgentDefaultModelRef(config);\n this.config.model = ref;\n this.defaultModel = ref || getDefaultModelSync(config);\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.skillFilesystemWatcher.refreshPrimaryWorkspace(this.baseWorkspacePath);\n void this.toolsFactory.shutdownBrowser();\n void this.workspaceRuntimes.clearAll();\n }\n\n /**\n * Construct the dep bag passed to `AgentToolsFactory`. Closures reference\n * `this.*` so they remain valid across hot reloads (no rebuild needed).\n */\n private buildToolsFactoryDeps(): ConstructorParameters<typeof AgentToolsFactory>[0] {\n return {\n workspace: this.baseWorkspacePath,\n extensionRegistry: this.config.extensionRegistry,\n getCurrentContext: this.config.getCurrentContext,\n hookRunner: this.config.hookRunner,\n bus: this.config.bus,\n getConfig: () => this.mergedConfig(),\n getPrimaryModel: () => this.resolveModelStringToModel(this.pickDefaultModelRef()),\n getBuiltinMemoryStore: () =>\n this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).builtinMemoryStore,\n getMemoryManager: () =>\n this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).memoryManager,\n getSessionStore: this.config.getSessionStore,\n gatewayClarify: this.config.gatewayClarify,\n getCronService: this.config.getCronService,\n getWorkflowRunService: this.config.getWorkflowRunService,\n getSkillIndexingContext: () => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return undefined;\n const inst = this.agents.get(ctx.sessionKey);\n if (!inst) return undefined;\n return {\n registeredToolNames: inst.registeredToolNames,\n skillAllowlist: inst.effectiveProfile.skillsAllowlist,\n };\n },\n onSkillsFilesystemMutate: () => {\n this.refreshSkillsAfterDiskChange('explicit');\n },\n getSkillPassthroughEnvVarNames: () => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return [];\n return [...(this.agents.get(ctx.sessionKey)?.skillEnvPassthroughKeys ?? [])];\n },\n registerSkillEnvPassthrough: (names: string[]) => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return;\n const inst = this.agents.get(ctx.sessionKey);\n if (!inst) return;\n for (const n of names) {\n if (isValidSkillEnvVarName(n)) {\n inst.skillEnvPassthroughKeys.add(n.trim());\n }\n }\n },\n };\n }\n\n getMemoryManager(): MemoryManager {\n return this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).memoryManager;\n }\n\n private getMemoryManagerForSession(sessionKey: string): MemoryManager {\n const path = this.getResolvedWorkspaceForSession(sessionKey);\n return this.workspaceRuntimes.getOrCreate(path).memoryManager;\n }\n\n /**\n * Prefix the user turn with fenced prefetched memory (external providers).\n * Delegates to {@link MemoryPrefetchCoordinator}.\n */\n applyMemoryPrefetchToUserMessage(\n userMessage: AgentMessage,\n sessionKey: string,\n ): Promise<AgentMessage> {\n return this.memoryPrefetch.applyToUserMessage(userMessage, sessionKey);\n }\n\n /**\n * After a completed turn: sync external providers and queue next-turn prefetch.\n * Delegates to {@link MemoryPrefetchCoordinator}.\n */\n afterAgentTurn(sessionKey: string, userPlainText: string): void {\n this.memoryPrefetch.afterTurn(sessionKey, userPlainText);\n }\n\n /**\n * Call once per user turn before the main `agent.prompt` (via {@link runAgentTurnWithModelFallbacks} `beforeUserPrompt`).\n * Delegates to {@link BackgroundReviewCoordinator}.\n */\n beginBackgroundReviewUserTurn(sessionKey: string): void {\n const inst = this.agents.get(sessionKey);\n if (!inst) return;\n this.backgroundReview.beginUserTurn(sessionKey, inst.registeredToolNames);\n }\n\n /**\n * After a successful main turn (after memory sync via `afterAgentTurn`), may run a quiet follow-up for memory/skills.\n * Delegates to {@link BackgroundReviewCoordinator}.\n */\n scheduleBackgroundReviewAfterUserTurn(sessionKey: string): void {\n const inst = this.agents.get(sessionKey);\n if (!inst) return;\n this.backgroundReview.scheduleAfterUserTurn({\n sessionKey,\n agent: inst.agent,\n registeredToolNames: inst.registeredToolNames,\n skillAllowlist: inst.effectiveProfile.skillsAllowlist,\n workspacePath: inst.resolvedWorkspacePath,\n lastAssistantText: this.getLastAssistantContent(sessionKey),\n workspaceRuntime: this.workspaceRuntimes.getOrCreate(inst.resolvedWorkspacePath),\n });\n }\n\n /**\n * Expand `/skill:name` user text into the full skill block for the current turn (WebChat, channels).\n */\n expandSkillUserText(text: string): string {\n const ctx = this.config.getCurrentContext?.();\n const sessionKey = ctx?.sessionKey;\n const path = sessionKey\n ? this.getResolvedWorkspaceForSession(sessionKey)\n : this.baseWorkspacePath;\n const inst = sessionKey ? this.agents.get(sessionKey) : undefined;\n return this.workspaceRuntimes.getOrCreate(path).skillManager.expandCommand(text, {\n skillAllowlist: inst?.effectiveProfile.skillsAllowlist,\n registeredToolNames: inst?.registeredToolNames,\n });\n }\n\n /** Structured SKILL.md preview for the gateway console. */\n getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null {\n const skill = this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).skillManager.findSkill(skillName);\n if (!skill) return null;\n\n return {\n name: skill.name,\n description: skill.description,\n bodyMarkdown: skill.content,\n disableModelInvocation: skill.disableModelInvocation,\n metadata: skill.metadata,\n toolConditions: skill.toolConditions,\n requiredEnvVarNames: skill.requiredEnvVarNames,\n };\n }\n\n private loadProfileMarkdownForProfile(profile: EffectiveAgentProfile): ReturnType<typeof loadProfileMarkdownFiles> {\n const cfg = this.config.config!;\n const profileDir = resolveAgentProfileDir(cfg, profile.agentId);\n return loadProfileMarkdownFiles(profileDir);\n }\n\n private resolveContextFilesForSession(\n sessionKey: string,\n profile: EffectiveAgentProfile,\n excludeHeartbeat?: boolean,\n ): EmbeddedContextFile[] {\n const cfg = this.config.config!;\n const profileDir = resolveAgentProfileDir(cfg, profile.agentId);\n const heartbeatEnabled = cfg.gateway?.heartbeat?.includeSystemPromptSection ?? false;\n const contextInjection = cfg.agents?.defaults?.contextInjection ?? 'always';\n const { contextFiles } = resolveBootstrapContextSync({\n profileDir,\n config: cfg,\n sessionKey,\n excludeHeartbeat: excludeHeartbeat ?? !heartbeatEnabled,\n contextInjection,\n });\n return contextFiles;\n }\n\n private skillCatalogEntryFromSkill(s: Skill, skillsConfig = createSkillConfigManager(resolveStateDir()).load(), lock = loadSkillsLock()): SkillCatalogEntry {\n const base = resolve(s.baseDir);\n const managed = isUnderManagedSkillsDir(s.baseDir);\n const directoryId = base.split(sep).filter(Boolean).pop() || s.name;\n const enabled = !(skillsConfig.entries?.[s.name]?.enabled === false);\n const hubKey = managed ? basename(base) : '';\n const hub = managed && hubKey ? lock.entries[hubKey] : undefined;\n\n return {\n directoryId,\n name: s.name,\n description: s.description,\n category: s.category,\n source: s.source,\n path: s.baseDir,\n managed,\n enabled,\n disableModelInvocation: s.disableModelInvocation,\n ...(hub ? { hub } : {}),\n };\n }\n\n getSkillCatalog(): SkillCatalogEntry[] {\n return this.getSkillCatalogSnapshot().catalog;\n }\n\n getSkillCatalogSnapshot(): SkillCatalogSnapshot {\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n const rt = this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath);\n return {\n catalog: rt.skillManager\n .getSkills()\n .map((s) => this.skillCatalogEntryFromSkill(s, skillsConfig, lock)),\n version: rt.skillManager.getVersion(),\n loadedAt: rt.skillManager.getLoadedAt(),\n diagnostics: rt.skillManager.getDiagnostics(),\n status: rt.skillManager.getStatus(),\n };\n }\n\n getAgentSkillAvailability(agentId: string): AgentSkillAvailabilityPayload {\n const cfg = this.config.config!;\n const defaultsAllowlist = cfg.agents?.defaults?.skills;\n const entry = Array.isArray(cfg.agents?.list)\n ? cfg.agents.list.find((a) => a && a.enabled !== false && a.id.toLowerCase() === agentId.toLowerCase())\n : undefined;\n const profile = resolveEffectiveAgentProfile(cfg, agentId);\n const rt = this.workspaceRuntimes.getOrCreate(profile.resolvedWorkspacePath);\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n const allow = profile.skillsAllowlist === undefined ? undefined : new Set(profile.skillsAllowlist.map((s) => s.toLowerCase()));\n\n const skills = rt.skillManager.getSkills().map((s) => {\n let unavailableReason: AgentSkillUnavailableReason | null = null;\n const skillConfig = resolveSkillConfig(s, skillsConfig);\n if (skillConfig.enabled === false) {\n unavailableReason = 'disabled';\n } else if (s.disableModelInvocation) {\n unavailableReason = 'model-invocation-disabled';\n } else if (!isSkillEnabled(s, skillsConfig)) {\n unavailableReason = 'requirements-unmet';\n } else if (allow !== undefined && !allow.has(s.name.toLowerCase())) {\n unavailableReason = 'agent-denied';\n }\n\n return {\n ...this.skillCatalogEntryFromSkill(s, skillsConfig, lock),\n availableForCurrentAgent: unavailableReason === null,\n unavailableReason,\n };\n });\n\n return {\n agentId: profile.agentId,\n version: rt.skillManager.getVersion(),\n loadedAt: rt.skillManager.getLoadedAt(),\n diagnostics: rt.skillManager.getDiagnostics(),\n status: rt.skillManager.getStatus(),\n ...(defaultsAllowlist !== undefined ? { defaultsAllowlist: [...defaultsAllowlist] } : {}),\n ...(entry?.skills !== undefined ? { agentAllowlist: [...entry.skills] } : {}),\n ...(profile.skillsAllowlist !== undefined ? { effectiveAllowlist: [...profile.skillsAllowlist] } : {}),\n skills,\n };\n }\n\n /**\n * After ~/.xopc/skills.json changes (enable/disable), refresh `<available_skills>` on active agents.\n */\n refreshSkillsAfterSkillConfigChange(): void {\n const cfg = this.config.config!;\n const touched = new Set<string>();\n for (const [resolvedPath, rt] of this.workspaceRuntimes.entries()) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(resolvedPath);\n }\n for (const instance of this.agents.values()) {\n const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);\n if (!touched.has(instance.resolvedWorkspacePath)) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(instance.resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n const newPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel:\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium',\n });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skill toggles applied; system prompt updated');\n this.scheduleSkillsUpdated('config');\n }\n\n /**\n * Reload skills from disk and refresh system prompt on all active Agent instances.\n */\n refreshSkillsAfterDiskChange(source: 'explicit' | 'watch' = 'explicit'): void {\n const now = Date.now();\n if (source === 'watch' && now - this.lastExplicitSkillDiskRefreshAt < 2500) {\n log.debug({ changedWithinMs: now - this.lastExplicitSkillDiskRefreshAt }, 'Ignoring skill watcher echo after explicit refresh');\n return;\n }\n if (source === 'explicit') {\n this.lastExplicitSkillDiskRefreshAt = now;\n }\n\n if (this.skillDiskRefreshInProgress) {\n this.skillDiskRefreshPending = true;\n return;\n }\n\n this.skillDiskRefreshInProgress = true;\n let refreshed = false;\n try {\n do {\n this.skillDiskRefreshPending = false;\n this.applySkillsAfterDiskChange();\n refreshed = true;\n } while (this.skillDiskRefreshPending);\n } finally {\n this.skillDiskRefreshInProgress = false;\n }\n\n if (refreshed) {\n this.scheduleSkillsUpdated('disk');\n }\n }\n\n private scheduleSkillsUpdated(reason: 'disk' | 'config'): void {\n this.pendingSkillsUpdatedReason = reason === 'disk' ? 'disk' : this.pendingSkillsUpdatedReason ?? 'config';\n if (this.skillsUpdatedTimer) clearTimeout(this.skillsUpdatedTimer);\n this.skillsUpdatedTimer = setTimeout(() => {\n const nextReason = this.pendingSkillsUpdatedReason ?? reason;\n this.pendingSkillsUpdatedReason = undefined;\n this.skillsUpdatedTimer = undefined;\n this.config.onSkillsUpdated?.({ reason: nextReason });\n }, 250);\n }\n\n private applySkillsAfterDiskChange(): void {\n const cfg = this.config.config!;\n // Reload every workspace SkillManager first. When there are no active agent sessions\n // (e.g. gateway UI only), the loop below runs zero times — without this, `getSkillCatalog()`\n // and delete flows still see stale in-memory skills after ~/.xopc/skills changes.\n for (const rt of this.workspaceRuntimes.values()) {\n rt.skillManager.reload();\n }\n\n const touched = new Set<string>();\n for (const instance of this.agents.values()) {\n const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);\n if (!touched.has(instance.resolvedWorkspacePath)) {\n touched.add(instance.resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n const newPrompt = rt.systemPromptBuilder.rebuild(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel:\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium',\n });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skills refreshed; system prompt updated');\n }\n\n /**\n * Get or create an Agent instance for a session\n */\n getOrCreateAgent(sessionKey: string): Agent {\n const cfg = this.config.config!;\n const targetPath = this.getResolvedWorkspaceForSession(sessionKey);\n const existing = this.agents.get(sessionKey);\n if (existing) {\n if (existing.resolvedWorkspacePath !== targetPath) {\n this.removeAgent(sessionKey);\n } else {\n existing.lastUsedAt = Date.now();\n log.debug({ sessionKey }, 'Reusing existing agent instance');\n return existing.agent;\n }\n }\n\n const profile = resolveEffectiveAgentProfileForSession(cfg, sessionKey);\n const resolvedPath = targetPath;\n const rt = this.workspaceRuntimes.getOrCreate(resolvedPath);\n\n if (isMemorySubsystemEnabled(cfg)) {\n void rt.memoryManager\n .initializeAll(sessionKey, { workspace: resolvedPath })\n .catch((err) => log.warn({ err, sessionKey }, 'memory initializeAll failed'));\n }\n\n if (isMemorySubsystemEnabled(cfg) && shouldRegisterCuratedMemoryTool(cfg)) {\n rt.builtinMemoryStore.loadFromDiskSync();\n }\n\n const { agent, registeredToolNames } = this.createAgentForProfile(\n sessionKey,\n profile,\n resolvedPath,\n rt,\n );\n\n this.agents.set(sessionKey, {\n agent,\n sessionKey,\n createdAt: Date.now(),\n lastUsedAt: Date.now(),\n effectiveProfile: profile,\n resolvedWorkspacePath: resolvedPath,\n registeredToolNames,\n skillEnvPassthroughKeys: new Set<string>(),\n });\n\n this.backgroundReview.attachToAgent(sessionKey, agent, registeredToolNames);\n\n const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;\n this.config.getModelManager?.().setSessionProfileDefault(sessionKey, modelRef);\n\n log.debug({ sessionKey, totalAgents: this.agents.size, agentId: profile.agentId }, 'Created new agent instance');\n return agent;\n }\n\n /**\n * Get existing agent for a session (if any)\n */\n getAgent(sessionKey: string): Agent | undefined {\n return this.agents.get(sessionKey)?.agent;\n }\n\n /**\n * Check if an agent exists for a session\n */\n hasAgent(sessionKey: string): boolean {\n return this.agents.has(sessionKey);\n }\n\n /**\n * Remove an agent instance\n */\n removeAgent(sessionKey: string): boolean {\n const instance = this.agents.get(sessionKey);\n if (instance) {\n this.backgroundReview.forgetSession(sessionKey);\n void this.toolsFactory.closeBrowserPageForSession(sessionKey);\n void retireSessionMcpRuntimeForSessionKey({ sessionKey, reason: 'agent-evict' });\n instance.agent.abort();\n evictEmbeddedSessionRunner(sessionKey, 'agent_removed');\n this.agents.delete(sessionKey);\n this.memoryPrefetch.forgetSession(sessionKey);\n clearBootstrapSnapshot(sessionKey);\n this.config.getModelManager?.().clearSessionProfileDefault(sessionKey);\n log.info({ sessionKey, totalAgents: this.agents.size }, 'Removed agent instance');\n return true;\n }\n return false;\n }\n\n /**\n * Get all active session keys\n */\n getActiveSessions(): string[] {\n return Array.from(this.agents.keys());\n }\n\n /**\n * Get agent count\n */\n getAgentCount(): number {\n return this.agents.size;\n }\n\n /**\n * Merge per-turn channel system prompt (e.g. Telegram group/topic override) into the agent.\n */\n applyTurnChannelSystemPrompt(sessionKey: string, channelSystemPrompt: string): void {\n const trimmed = channelSystemPrompt.trim();\n if (!trimmed) return;\n\n const instance = this.agents.get(sessionKey);\n if (!instance) return;\n\n const cfg = this.config.config!;\n const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(sessionKey, instance.effectiveProfile);\n const modelRef = instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel;\n const thinkingLevel =\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey,\n modelRef,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n extraSystemPrompt: trimmed,\n });\n }\n\n /**\n * Set thinking level for a session's agent\n */\n setThinkingLevel(sessionKey: string, level: ThinkingLevel): void {\n const instance = this.agents.get(sessionKey);\n if (instance) {\n instance.agent.state.thinkingLevel = level;\n log.debug({ sessionKey, thinkingLevel: level }, 'Set thinking level for agent');\n }\n }\n\n /**\n * Dispose all agents\n */\n dispose(): void {\n if (this.skillsUpdatedTimer) clearTimeout(this.skillsUpdatedTimer);\n this.skillFilesystemWatcher.dispose();\n void this.toolsFactory.shutdownBrowser();\n void disposeAllSessionMcpRuntimes().catch(() => {});\n evictAllEmbeddedSessionRunners('agent_manager_dispose');\n this.backgroundReview.clear();\n for (const instance of this.agents.values()) {\n instance.agent.abort();\n }\n this.agents.clear();\n this.memoryPrefetch.clear();\n this.sessionWorkspaceOverrides.clear();\n void this.workspaceRuntimes.clearAll();\n log.debug('All agent instances disposed');\n }\n\n async warmCredentialCache(): Promise<void> {\n const profiles = await this.credentialResolver.listProfiles();\n for (const profile of profiles) {\n const secret = profile.key?.trim()\n ? profile.key.trim()\n : profile.envVar\n ? process.env[profile.envVar]?.trim()\n : undefined;\n if (secret) {\n this.credentialCache.set(profile.provider.toLowerCase(), secret);\n }\n }\n log.debug({ count: this.credentialCache.size }, 'Credential cache warmed');\n }\n\n async refreshCredentials(): Promise<void> {\n this.credentialCache.clear();\n await this.warmCredentialCache();\n }\n\n private resolveApiKeyWithCache(provider: string): string | undefined {\n const key = provider.toLowerCase();\n const cached = this.credentialCache.get(key);\n if (cached) return cached;\n\n const fromDisk = resolveProviderApiKeySync(provider);\n if (fromDisk) {\n this.credentialCache.set(key, fromDisk);\n return fromDisk;\n }\n\n const fromRegistryOrEnv = getApiKeySync(provider);\n if (fromRegistryOrEnv) {\n this.credentialCache.set(key, fromRegistryOrEnv);\n return fromRegistryOrEnv;\n }\n return undefined;\n }\n\n private createAgentForProfile(\n sessionKey: string,\n profile: EffectiveAgentProfile,\n resolvedWorkspacePath: string,\n rt: WorkspaceRuntime,\n ): { agent: Agent; registeredToolNames: string[] } {\n const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;\n const model = this.resolveModelStringToModel(modelRef);\n\n const contextFiles = this.resolveContextFilesForSession(sessionKey, profile);\n const tools = this.toolsFactory.createAllTools({\n workspace: resolvedWorkspacePath,\n profileMarkdownRoot: resolveAgentProfileDir(this.config.config!, profile.agentId),\n disabledTools: profile.tools.disable,\n getPrimaryModel: () => this.resolveModelStringToModel(modelRef),\n getBuiltinMemoryStore: () => rt.builtinMemoryStore,\n getMemoryManager: () => rt.memoryManager,\n getSkillManager: () => rt.skillManager,\n });\n const registeredToolNames = tools.map((t) => t.name);\n\n const thinkingLevel =\n (profile.thinkingDefault as ThinkingLevel | undefined) ?? this.config.thinkingLevel ?? 'medium';\n\n const agent = new Agent({\n initialState: {\n systemPrompt: rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(this.config.config!, profile.agentId),\n systemPromptOverride: profile.systemPromptOverride,\n skillAllowlist: profile.skillsAllowlist,\n registeredToolNames,\n sessionKey,\n modelRef,\n agentId: profile.agentId,\n thinkingLevel,\n }),\n model,\n thinkingLevel,\n tools,\n messages: [],\n },\n streamFn: createExtensionAwareStreamFn(),\n getApiKey: (provider: string) => this.resolveApiKeyWithCache(provider),\n beforeToolCall: async ({ toolCall, args }) => {\n const toolName = toolCall.name;\n\n if (toolName === 'shell') {\n const ctx = this.config.getCurrentContext();\n const cfg = this.mergedConfig();\n if (ctx && cfg) {\n const command =\n typeof (args as { command?: unknown })?.command === 'string'\n ? (args as { command: string }).command\n : JSON.stringify(args ?? {});\n const accountId =\n typeof ctx.metadata?.accountId === 'string' ? ctx.metadata.accountId : undefined;\n const approval = await maybeRequestChannelExecApproval({\n cfg,\n payload: {\n sessionKey: ctx.sessionKey,\n channel: ctx.channel,\n chatId: ctx.chatId,\n accountId,\n toolName,\n summary: command.slice(0, 500),\n details: { command: command.slice(0, 2000) },\n },\n });\n if (approval.required && !approval.approved) {\n return {\n block: true,\n reason: approval.reason ?? 'Exec approval denied or timed out.',\n };\n }\n }\n }\n\n if (!this.config.hookRunner) {\n return undefined;\n }\n const parsed = parseMcpToolName(toolName);\n const hookResult = await this.config.hookRunner.runBeforeToolCall(\n toolName,\n (args ?? {}) as Record<string, unknown>,\n {\n sessionKey,\n isMcpTool: parsed !== null,\n mcpServerId: parsed?.serverId,\n },\n );\n if (!hookResult.allowed) {\n return { block: true, reason: hookResult.reason ?? 'Tool call blocked by policy hook.' };\n }\n return undefined;\n },\n });\n return { agent, registeredToolNames };\n }\n\n /**\n * Set model for a specific session\n */\n setModelForSession(sessionKey: string, modelId: string): boolean {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n log.warn(\n { sessionKey, modelId, activeSessionCount: this.agents.size },\n `setModelForSession: no agent instance for session (create session / run turn first); modelId=${modelId}`,\n );\n return false;\n }\n\n try {\n const model = resolveModel(modelId);\n instance.agent.state.model = model;\n\n const cfg = this.config.config!;\n const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(\n sessionKey,\n instance.effectiveProfile,\n );\n const thinkingLevel =\n (instance.agent.state.thinkingLevel as ThinkingLevel | undefined) ??\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey,\n modelRef: modelId,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n });\n\n log.info({ sessionKey, modelId }, 'Model set for session');\n return true;\n } catch (err) {\n log.error({ err, sessionKey, modelId }, 'Failed to set model for session');\n return false;\n }\n }\n\n /**\n * Get last assistant content from a session's agent\n */\n getLastAssistantContent(sessionKey: string): string | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n const messages = instance.agent.state.messages;\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'assistant') {\n const content = msg.content;\n if (Array.isArray(content)) {\n return extractTextContent(content as Array<{ type: string; text?: string }>);\n }\n return String(content);\n }\n }\n return null;\n }\n\n /**\n * Replace messages for a session's agent\n */\n replaceMessages(sessionKey: string, messages: AgentMessage[]): boolean {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return false;\n }\n\n instance.agent.state.messages = messages;\n return true;\n }\n\n /**\n * Get messages for a session's agent\n */\n getMessages(sessionKey: string): AgentMessage[] | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n return instance.agent.state.messages;\n }\n\n /**\n * Subscribe to agent events for a session\n */\n subscribeToSession(sessionKey: string, callback: (event: AgentEvent) => void): (() => void) | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n return instance.agent.subscribe(callback);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAe2E;kBAEjB;qBAMc;aAEtB;yBACwB;gBACe;kBAE7B;YACkB;AAwC9E,MAAM,MAAM,aAAa,eAAe;AAuFxC,IAAa,eAAb,MAA0D;CACxD,yBAAiB,IAAI,KAA4B;CACjD;CACA;CAEA,eAA2C;EACzC,MAAM,OAAO,KAAK,OAAO;AACzB,SAAO,OAAO,qBAAqB,KAAK,GAAG,KAAA;;;CAG7C;;CAEA,4CAAoC,IAAI,KAAqB;CAC7D;CACA,kCAA0B,IAAI,KAAqB;CACnD;CACA;CACA;CACA;CACA;CACA,6BAAqC;CACrC,0BAAkC;CAClC,iCAAyC;CACzC;CACA;CAEA,YAAY,QAA4B;AACtC,OAAK,SAAS;AACd,OAAK,oBAAoB,KAAK,0BAA0B;AACxD,OAAK,yBAAyB,IAAI,uBAAuB,EACvD,WAAW,UAAU;AACnB,OAAI,KAAK,EAAE,aAAa,MAAM,aAAa,EAAE,8CAA8C;AAC3F,QAAK,6BAA6B,QAAQ;KAE7C,CAAC;AACF,OAAK,uBAAuB,wBAAwB,KAAK,kBAAkB;AAC3E,OAAK,oBAAoB,IAAI,yBAAyB;GACpD,iBAAiB,KAAK,OAAO;GAC7B,kBAAkB,yBAAyB;GAC3C,mBAAmB,iBAAiB;AAClC,SAAK,uBAAuB,eAAe,aAAa;;GAE3D,CAAC;AACF,OAAK,iBAAiB,IAAI,0BAA0B;GAClD,iBAAiB,KAAK,OAAO;GAC7B,6BAA6B,OAAO,KAAK,2BAA2B,GAAG;GACvE,0BAA0B,OAAO,KAAK,wBAAwB,GAAG;GAClE,CAAC;AACF,OAAK,mBAAmB,IAAI,4BAA4B;GACtD,iBAAiB,KAAK,cAAc;GACpC,gCAAgC,KAAK,6BAA6B,WAAW;GAC9E,CAAC;AACF,OAAK,eAAe,IAAI,kBAAkB,KAAK,uBAAuB,CAAC;AAEvE,OAAK,eAAe,OAAO,SAAS,oBAAoB,OAAO,OAAO;AAEtE,OAAK,qBAAqB,IAAI,oBAAoB;AAClD,OAAK,qBAAqB,CAAC,OAAO,QAAQ;GACxC,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC3D,OAAI,KAAK;IAAE;IAAK,cAAc;IAAI,EAAE,qCAAqC,KAAK;IAC9E;;CAGJ,2BAA2C;EACzC,MAAM,MAAM,KAAK,OAAO;AACxB,MAAI,CAAC,IACH,QAAO,0BAA0B,KAAK,OAAO,UAAU;AAEzD,SAAO,uCAAuC,KAAK,KAAK,CAAC;;;;;;CAO3D,+BAA+B,YAA4B;EACzD,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,UAAU,KAAK,0BAA0B,IAAI,WAAW;AAC9D,MAAI,YAAY,KAAA,EACd,QAAO;AAET,SAAO,uCAAuC,KAAK,WAAW,CAAC;;;;;;CAOjE,4BAA4B,YAAoB,cAAmC;AACjF,MAAI,iBAAiB,QAAQ,iBAAiB,GAC5C,MAAK,0BAA0B,OAAO,WAAW;MAEjD,MAAK,0BAA0B,IAAI,YAAY,aAAa;;;CAKhE,6BACE,YACiE;EACjE,MAAM,MAAM,KAAK,cAAc;AAC/B,MAAI,CAAC,IACH;AAEF,SAAO,uCAAuC,KAAK,WAAW,CAAC;;CAGjE,sBAAsC;EACpC,MAAM,MAAM,KAAK,cAAc;AAE/B,SADY,wBAAwB,IAC1B,EAAE,MAAM,IAAI,oBAAoB,IAAI;;CAGhD,0BAAkC,UAA8B;AAC9D,MAAI;AACF,UAAO,aAAa,SAAS;UACvB;GACN,MAAM,WAAW,oBAAoB,KAAK,cAAc,CAAC;AACzD,OAAI,KAAK;IAAE;IAAU;IAAU,EAAE,iCAAiC;AAClE,UAAO,aAAa,SAAS;;;;;;;;;;;;;CAcjC,oBAAoB,QAAsB;AACxC,OAAK,OAAO,SAAS;EACrB,MAAM,MAAM,wBAAwB,OAAO;AAC3C,OAAK,OAAO,QAAQ;AACpB,OAAK,eAAe,OAAO,oBAAoB,OAAO;AACtD,OAAK,oBAAoB,KAAK,0BAA0B;AACxD,OAAK,uBAAuB,wBAAwB,KAAK,kBAAkB;AACtE,OAAK,aAAa,iBAAiB;AACnC,OAAK,kBAAkB,UAAU;;;;;;CAOxC,wBAAoF;AAClF,SAAO;GACL,WAAW,KAAK;GAChB,mBAAmB,KAAK,OAAO;GAC/B,mBAAmB,KAAK,OAAO;GAC/B,YAAY,KAAK,OAAO;GACxB,KAAK,KAAK,OAAO;GACjB,iBAAiB,KAAK,cAAc;GACpC,uBAAuB,KAAK,0BAA0B,KAAK,qBAAqB,CAAC;GACjF,6BACE,KAAK,kBAAkB,YAAY,KAAK,kBAAkB,CAAC;GAC7D,wBACE,KAAK,kBAAkB,YAAY,KAAK,kBAAkB,CAAC;GAC7D,iBAAiB,KAAK,OAAO;GAC7B,gBAAgB,KAAK,OAAO;GAC5B,gBAAgB,KAAK,OAAO;GAC5B,uBAAuB,KAAK,OAAO;GACnC,+BAA+B;IAC7B,MAAM,MAAM,KAAK,OAAO,qBAAqB;AAC7C,QAAI,CAAC,KAAK,WAAY,QAAO,KAAA;IAC7B,MAAM,OAAO,KAAK,OAAO,IAAI,IAAI,WAAW;AAC5C,QAAI,CAAC,KAAM,QAAO,KAAA;AAClB,WAAO;KACL,qBAAqB,KAAK;KAC1B,gBAAgB,KAAK,iBAAiB;KACvC;;GAEH,gCAAgC;AAC9B,SAAK,6BAA6B,WAAW;;GAE/C,sCAAsC;IACpC,MAAM,MAAM,KAAK,OAAO,qBAAqB;AAC7C,QAAI,CAAC,KAAK,WAAY,QAAO,EAAE;AAC/B,WAAO,CAAC,GAAI,KAAK,OAAO,IAAI,IAAI,WAAW,EAAE,2BAA2B,EAAE,CAAE;;GAE9E,8BAA8B,UAAoB;IAChD,MAAM,MAAM,KAAK,OAAO,qBAAqB;AAC7C,QAAI,CAAC,KAAK,WAAY;IACtB,MAAM,OAAO,KAAK,OAAO,IAAI,IAAI,WAAW;AAC5C,QAAI,CAAC,KAAM;AACX,SAAK,MAAM,KAAK,MACd,KAAI,uBAAuB,EAAE,CAC3B,MAAK,wBAAwB,IAAI,EAAE,MAAM,CAAC;;GAIjD;;CAGH,mBAAkC;AAChC,SAAO,KAAK,kBAAkB,YAAY,KAAK,kBAAkB,CAAC;;CAGpE,2BAAmC,YAAmC;EACpE,MAAM,OAAO,KAAK,+BAA+B,WAAW;AAC5D,SAAO,KAAK,kBAAkB,YAAY,KAAK,CAAC;;;;;;CAOlD,iCACE,aACA,YACuB;AACvB,SAAO,KAAK,eAAe,mBAAmB,aAAa,WAAW;;;;;;CAOxE,eAAe,YAAoB,eAA6B;AAC9D,OAAK,eAAe,UAAU,YAAY,cAAc;;;;;;CAO1D,8BAA8B,YAA0B;EACtD,MAAM,OAAO,KAAK,OAAO,IAAI,WAAW;AACxC,MAAI,CAAC,KAAM;AACX,OAAK,iBAAiB,cAAc,YAAY,KAAK,oBAAoB;;;;;;CAO3E,sCAAsC,YAA0B;EAC9D,MAAM,OAAO,KAAK,OAAO,IAAI,WAAW;AACxC,MAAI,CAAC,KAAM;AACX,OAAK,iBAAiB,sBAAsB;GAC1C;GACA,OAAO,KAAK;GACZ,qBAAqB,KAAK;GAC1B,gBAAgB,KAAK,iBAAiB;GACtC,eAAe,KAAK;GACpB,mBAAmB,KAAK,wBAAwB,WAAW;GAC3D,kBAAkB,KAAK,kBAAkB,YAAY,KAAK,sBAAsB;GACjF,CAAC;;;;;CAMJ,oBAAoB,MAAsB;EAExC,MAAM,cADM,KAAK,OAAO,qBAAqB,GACrB;EACxB,MAAM,OAAO,aACT,KAAK,+BAA+B,WAAW,GAC/C,KAAK;EACT,MAAM,OAAO,aAAa,KAAK,OAAO,IAAI,WAAW,GAAG,KAAA;AACxD,SAAO,KAAK,kBAAkB,YAAY,KAAK,CAAC,aAAa,cAAc,MAAM;GAC/E,gBAAgB,MAAM,iBAAiB;GACvC,qBAAqB,MAAM;GAC5B,CAAC;;;CAIJ,uBAAuB,WAAuD;EAC5E,MAAM,QAAQ,KAAK,kBAAkB,YAAY,KAAK,kBAAkB,CAAC,aAAa,UAAU,UAAU;AAC1G,MAAI,CAAC,MAAO,QAAO;AAEnB,SAAO;GACL,MAAM,MAAM;GACZ,aAAa,MAAM;GACnB,cAAc,MAAM;GACpB,wBAAwB,MAAM;GAC9B,UAAU,MAAM;GAChB,gBAAgB,MAAM;GACtB,qBAAqB,MAAM;GAC5B;;CAGH,8BAAsC,SAA6E;EACjH,MAAM,MAAM,KAAK,OAAO;AAExB,SAAO,yBADY,uBAAuB,KAAK,QAAQ,QACb,CAAC;;CAG7C,8BACE,YACA,SACA,kBACuB;EACvB,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,aAAa,uBAAuB,KAAK,QAAQ,QAAQ;EAC/D,MAAM,mBAAmB,IAAI,SAAS,WAAW,8BAA8B;EAC/E,MAAM,mBAAmB,IAAI,QAAQ,UAAU,oBAAoB;EACnE,MAAM,EAAE,iBAAiB,4BAA4B;GACnD;GACA,QAAQ;GACR;GACA,kBAAkB,oBAAoB,CAAC;GACvC;GACD,CAAC;AACF,SAAO;;CAGT,2BAAmC,GAAU,eAAe,yBAAyB,iBAAiB,CAAC,CAAC,MAAM,EAAE,OAAO,gBAAgB,EAAqB;EAC1J,MAAM,OAAO,QAAQ,EAAE,QAAQ;EAC/B,MAAM,UAAU,wBAAwB,EAAE,QAAQ;EAClD,MAAM,cAAc,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,EAAE;EAC/D,MAAM,UAAU,EAAE,aAAa,UAAU,EAAE,OAAO,YAAY;EAC9D,MAAM,SAAS,UAAU,SAAS,KAAK,GAAG;EAC1C,MAAM,MAAM,WAAW,SAAS,KAAK,QAAQ,UAAU,KAAA;AAEvD,SAAO;GACL;GACA,MAAM,EAAE;GACR,aAAa,EAAE;GACf,UAAU,EAAE;GACZ,QAAQ,EAAE;GACV,MAAM,EAAE;GACR;GACA;GACA,wBAAwB,EAAE;GAC1B,GAAI,MAAM,EAAE,KAAK,GAAG,EAAE;GACvB;;CAGH,kBAAuC;AACrC,SAAO,KAAK,yBAAyB,CAAC;;CAGxC,0BAAgD;EAC9C,MAAM,eAAe,yBAAyB,iBAAiB,CAAC,CAAC,MAAM;EACvE,MAAM,OAAO,gBAAgB;EAC7B,MAAM,KAAK,KAAK,kBAAkB,YAAY,KAAK,kBAAkB;AACrE,SAAO;GACL,SAAS,GAAG,aACT,WAAW,CACX,KAAK,MAAM,KAAK,2BAA2B,GAAG,cAAc,KAAK,CAAC;GACrE,SAAS,GAAG,aAAa,YAAY;GACrC,UAAU,GAAG,aAAa,aAAa;GACvC,aAAa,GAAG,aAAa,gBAAgB;GAC7C,QAAQ,GAAG,aAAa,WAAW;GACpC;;CAGH,0BAA0B,SAAgD;EACxE,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,oBAAoB,IAAI,QAAQ,UAAU;EAChD,MAAM,QAAQ,MAAM,QAAQ,IAAI,QAAQ,KAAK,GACzC,IAAI,OAAO,KAAK,MAAM,MAAM,KAAK,EAAE,YAAY,SAAS,EAAE,GAAG,aAAa,KAAK,QAAQ,aAAa,CAAC,GACrG,KAAA;EACJ,MAAM,UAAU,6BAA6B,KAAK,QAAQ;EAC1D,MAAM,KAAK,KAAK,kBAAkB,YAAY,QAAQ,sBAAsB;EAC5E,MAAM,eAAe,yBAAyB,iBAAiB,CAAC,CAAC,MAAM;EACvE,MAAM,OAAO,gBAAgB;EAC7B,MAAM,QAAQ,QAAQ,oBAAoB,KAAA,IAAY,KAAA,IAAY,IAAI,IAAI,QAAQ,gBAAgB,KAAK,MAAM,EAAE,aAAa,CAAC,CAAC;EAE9H,MAAM,SAAS,GAAG,aAAa,WAAW,CAAC,KAAK,MAAM;GACpD,IAAI,oBAAwD;AAE5D,OADoB,mBAAmB,GAAG,aAC3B,CAAC,YAAY,MAC1B,qBAAoB;YACX,EAAE,uBACX,qBAAoB;YACX,CAAC,eAAe,GAAG,aAAa,CACzC,qBAAoB;YACX,UAAU,KAAA,KAAa,CAAC,MAAM,IAAI,EAAE,KAAK,aAAa,CAAC,CAChE,qBAAoB;AAGtB,UAAO;IACL,GAAG,KAAK,2BAA2B,GAAG,cAAc,KAAK;IACzD,0BAA0B,sBAAsB;IAChD;IACD;IACD;AAEF,SAAO;GACL,SAAS,QAAQ;GACjB,SAAS,GAAG,aAAa,YAAY;GACrC,UAAU,GAAG,aAAa,aAAa;GACvC,aAAa,GAAG,aAAa,gBAAgB;GAC7C,QAAQ,GAAG,aAAa,WAAW;GACnC,GAAI,sBAAsB,KAAA,IAAY,EAAE,mBAAmB,CAAC,GAAG,kBAAkB,EAAE,GAAG,EAAE;GACxF,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,gBAAgB,CAAC,GAAG,MAAM,OAAO,EAAE,GAAG,EAAE;GAC5E,GAAI,QAAQ,oBAAoB,KAAA,IAAY,EAAE,oBAAoB,CAAC,GAAG,QAAQ,gBAAgB,EAAE,GAAG,EAAE;GACrG;GACD;;;;;CAMH,sCAA4C;EAC1C,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,0BAAU,IAAI,KAAa;AACjC,OAAK,MAAM,CAAC,cAAc,OAAO,KAAK,kBAAkB,SAAS,EAAE;AACjE,MAAG,aAAa,yBAAyB;AACzC,WAAQ,IAAI,aAAa;;AAE3B,OAAK,MAAM,YAAY,KAAK,OAAO,QAAQ,EAAE;GAC3C,MAAM,KAAK,KAAK,kBAAkB,YAAY,SAAS,sBAAsB;AAC7E,OAAI,CAAC,QAAQ,IAAI,SAAS,sBAAsB,EAAE;AAChD,OAAG,aAAa,yBAAyB;AACzC,YAAQ,IAAI,SAAS,sBAAsB;;GAE7C,MAAM,eAAe,KAAK,8BACxB,SAAS,YACT,SAAS,iBACV;GACD,MAAM,YAAY,GAAG,oBAAoB,MAAM,cAAc;IAC3D,4BAA4B,GAAG,cAAc,2BAA2B;IACxE,mBAAmB,SAAS;IAC5B,yBAAyB,uBAAuB,KAAK,SAAS,iBAAiB,QAAQ;IACvF,sBAAsB,SAAS,iBAAiB;IAChD,gBAAgB,SAAS,iBAAiB;IAC1C,qBAAqB,SAAS;IAC9B,YAAY,SAAS;IACrB,UAAU,SAAS,iBAAiB,iBAAiB,MAAM,IAAI,KAAK;IACpE,SAAS,SAAS,iBAAiB;IACnC,eACG,SAAS,iBAAiB,mBAC3B,KAAK,OAAO,iBACZ;IACH,CAAC;AACF,YAAS,MAAM,MAAM,eAAe;;AAEtC,MAAI,KAAK,EAAE,QAAQ,KAAK,OAAO,MAAM,EAAE,+CAA+C;AACtF,OAAK,sBAAsB,SAAS;;;;;CAMtC,6BAA6B,SAA+B,YAAkB;EAC5E,MAAM,MAAM,KAAK,KAAK;AACtB,MAAI,WAAW,WAAW,MAAM,KAAK,iCAAiC,MAAM;AAC1E,OAAI,MAAM,EAAE,iBAAiB,MAAM,KAAK,gCAAgC,EAAE,qDAAqD;AAC/H;;AAEF,MAAI,WAAW,WACb,MAAK,iCAAiC;AAGxC,MAAI,KAAK,4BAA4B;AACnC,QAAK,0BAA0B;AAC/B;;AAGF,OAAK,6BAA6B;EAClC,IAAI,YAAY;AAChB,MAAI;AACF,MAAG;AACD,SAAK,0BAA0B;AAC/B,SAAK,4BAA4B;AACjC,gBAAY;YACL,KAAK;YACN;AACR,QAAK,6BAA6B;;AAGpC,MAAI,UACF,MAAK,sBAAsB,OAAO;;CAItC,sBAA8B,QAAiC;AAC7D,OAAK,6BAA6B,WAAW,SAAS,SAAS,KAAK,8BAA8B;AAClG,MAAI,KAAK,mBAAoB,cAAa,KAAK,mBAAmB;AAClE,OAAK,qBAAqB,iBAAiB;GACzC,MAAM,aAAa,KAAK,8BAA8B;AACtD,QAAK,6BAA6B,KAAA;AAClC,QAAK,qBAAqB,KAAA;AAC1B,QAAK,OAAO,kBAAkB,EAAE,QAAQ,YAAY,CAAC;KACpD,IAAI;;CAGT,6BAA2C;EACzC,MAAM,MAAM,KAAK,OAAO;AAIxB,OAAK,MAAM,MAAM,KAAK,kBAAkB,QAAQ,CAC9C,IAAG,aAAa,QAAQ;EAG1B,MAAM,0BAAU,IAAI,KAAa;AACjC,OAAK,MAAM,YAAY,KAAK,OAAO,QAAQ,EAAE;GAC3C,MAAM,KAAK,KAAK,kBAAkB,YAAY,SAAS,sBAAsB;AAC7E,OAAI,CAAC,QAAQ,IAAI,SAAS,sBAAsB,CAC9C,SAAQ,IAAI,SAAS,sBAAsB;GAE7C,MAAM,eAAe,KAAK,8BACxB,SAAS,YACT,SAAS,iBACV;GACD,MAAM,YAAY,GAAG,oBAAoB,QAAQ,cAAc;IAC7D,4BAA4B,GAAG,cAAc,2BAA2B;IACxE,mBAAmB,SAAS;IAC5B,yBAAyB,uBAAuB,KAAK,SAAS,iBAAiB,QAAQ;IACvF,sBAAsB,SAAS,iBAAiB;IAChD,gBAAgB,SAAS,iBAAiB;IAC1C,qBAAqB,SAAS;IAC9B,YAAY,SAAS;IACrB,UAAU,SAAS,iBAAiB,iBAAiB,MAAM,IAAI,KAAK;IACpE,SAAS,SAAS,iBAAiB;IACnC,eACG,SAAS,iBAAiB,mBAC3B,KAAK,OAAO,iBACZ;IACH,CAAC;AACF,YAAS,MAAM,MAAM,eAAe;;AAEtC,MAAI,KAAK,EAAE,QAAQ,KAAK,OAAO,MAAM,EAAE,0CAA0C;;;;;CAMnF,iBAAiB,YAA2B;EAC1C,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,aAAa,KAAK,+BAA+B,WAAW;EAClE,MAAM,WAAW,KAAK,OAAO,IAAI,WAAW;AAC5C,MAAI,SACF,KAAI,SAAS,0BAA0B,WACrC,MAAK,YAAY,WAAW;OACvB;AACL,YAAS,aAAa,KAAK,KAAK;AAChC,OAAI,MAAM,EAAE,YAAY,EAAE,kCAAkC;AAC5D,UAAO,SAAS;;EAIpB,MAAM,UAAU,uCAAuC,KAAK,WAAW;EACvE,MAAM,eAAe;EACrB,MAAM,KAAK,KAAK,kBAAkB,YAAY,aAAa;AAE3D,MAAI,yBAAyB,IAAI,CAC1B,IAAG,cACL,cAAc,YAAY,EAAE,WAAW,cAAc,CAAC,CACtD,OAAO,QAAQ,IAAI,KAAK;GAAE;GAAK;GAAY,EAAE,8BAA8B,CAAC;AAGjF,MAAI,yBAAyB,IAAI,IAAI,gCAAgC,IAAI,CACvE,IAAG,mBAAmB,kBAAkB;EAG1C,MAAM,EAAE,OAAO,wBAAwB,KAAK,sBAC1C,YACA,SACA,cACA,GACD;AAED,OAAK,OAAO,IAAI,YAAY;GAC1B;GACA;GACA,WAAW,KAAK,KAAK;GACrB,YAAY,KAAK,KAAK;GACtB,kBAAkB;GAClB,uBAAuB;GACvB;GACA,yCAAyB,IAAI,KAAa;GAC3C,CAAC;AAEF,OAAK,iBAAiB,cAAc,YAAY,OAAO,oBAAoB;EAE3E,MAAM,WAAW,QAAQ,iBAAiB,MAAM,IAAI,KAAK;AACzD,OAAK,OAAO,mBAAmB,CAAC,yBAAyB,YAAY,SAAS;AAE9E,MAAI,MAAM;GAAE;GAAY,aAAa,KAAK,OAAO;GAAM,SAAS,QAAQ;GAAS,EAAE,6BAA6B;AAChH,SAAO;;;;;CAMT,SAAS,YAAuC;AAC9C,SAAO,KAAK,OAAO,IAAI,WAAW,EAAE;;;;;CAMtC,SAAS,YAA6B;AACpC,SAAO,KAAK,OAAO,IAAI,WAAW;;;;;CAMpC,YAAY,YAA6B;EACvC,MAAM,WAAW,KAAK,OAAO,IAAI,WAAW;AAC5C,MAAI,UAAU;AACZ,QAAK,iBAAiB,cAAc,WAAW;AAC1C,QAAK,aAAa,2BAA2B,WAAW;AACxD,wCAAqC;IAAE;IAAY,QAAQ;IAAe,CAAC;AAChF,YAAS,MAAM,OAAO;AACtB,8BAA2B,YAAY,gBAAgB;AACvD,QAAK,OAAO,OAAO,WAAW;AAC9B,QAAK,eAAe,cAAc,WAAW;AAC7C,0BAAuB,WAAW;AAClC,QAAK,OAAO,mBAAmB,CAAC,2BAA2B,WAAW;AACtE,OAAI,KAAK;IAAE;IAAY,aAAa,KAAK,OAAO;IAAM,EAAE,yBAAyB;AACjF,UAAO;;AAET,SAAO;;;;;CAMT,oBAA8B;AAC5B,SAAO,MAAM,KAAK,KAAK,OAAO,MAAM,CAAC;;;;;CAMvC,gBAAwB;AACtB,SAAO,KAAK,OAAO;;;;;CAMrB,6BAA6B,YAAoB,qBAAmC;EAClF,MAAM,UAAU,oBAAoB,MAAM;AAC1C,MAAI,CAAC,QAAS;EAEd,MAAM,WAAW,KAAK,OAAO,IAAI,WAAW;AAC5C,MAAI,CAAC,SAAU;EAEf,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,KAAK,KAAK,kBAAkB,YAAY,SAAS,sBAAsB;EAC7E,MAAM,eAAe,KAAK,8BAA8B,YAAY,SAAS,iBAAiB;EAC9F,MAAM,WAAW,SAAS,iBAAiB,iBAAiB,MAAM,IAAI,KAAK;EAC3E,MAAM,gBACH,SAAS,iBAAiB,mBAC3B,KAAK,OAAO,iBACZ;AAEF,WAAS,MAAM,MAAM,eAAe,GAAG,oBAAoB,MAAM,cAAc;GAC7E,4BAA4B,GAAG,cAAc,2BAA2B;GACxE,mBAAmB,SAAS;GAC5B,yBAAyB,uBAAuB,KAAK,SAAS,iBAAiB,QAAQ;GACvF,sBAAsB,SAAS,iBAAiB;GAChD,gBAAgB,SAAS,iBAAiB;GAC1C,qBAAqB,SAAS;GAC9B;GACA;GACA,SAAS,SAAS,iBAAiB;GACnC;GACA,mBAAmB;GACpB,CAAC;;;;;CAMJ,iBAAiB,YAAoB,OAA4B;EAC/D,MAAM,WAAW,KAAK,OAAO,IAAI,WAAW;AAC5C,MAAI,UAAU;AACZ,YAAS,MAAM,MAAM,gBAAgB;AACrC,OAAI,MAAM;IAAE;IAAY,eAAe;IAAO,EAAE,+BAA+B;;;;;;CAOnF,UAAgB;AACd,MAAI,KAAK,mBAAoB,cAAa,KAAK,mBAAmB;AAClE,OAAK,uBAAuB,SAAS;AAChC,OAAK,aAAa,iBAAiB;AACnC,gCAA8B,CAAC,YAAY,GAAG;AACnD,iCAA+B,wBAAwB;AACvD,OAAK,iBAAiB,OAAO;AAC7B,OAAK,MAAM,YAAY,KAAK,OAAO,QAAQ,CACzC,UAAS,MAAM,OAAO;AAExB,OAAK,OAAO,OAAO;AACnB,OAAK,eAAe,OAAO;AAC3B,OAAK,0BAA0B,OAAO;AACjC,OAAK,kBAAkB,UAAU;AACtC,MAAI,MAAM,+BAA+B;;CAG3C,MAAM,sBAAqC;EACzC,MAAM,WAAW,MAAM,KAAK,mBAAmB,cAAc;AAC7D,OAAK,MAAM,WAAW,UAAU;GAC9B,MAAM,SAAS,QAAQ,KAAK,MAAM,GAC9B,QAAQ,IAAI,MAAM,GAClB,QAAQ,SACN,QAAQ,IAAI,QAAQ,SAAS,MAAM,GACnC,KAAA;AACN,OAAI,OACF,MAAK,gBAAgB,IAAI,QAAQ,SAAS,aAAa,EAAE,OAAO;;AAGpE,MAAI,MAAM,EAAE,OAAO,KAAK,gBAAgB,MAAM,EAAE,0BAA0B;;CAG5E,MAAM,qBAAoC;AACxC,OAAK,gBAAgB,OAAO;AAC5B,QAAM,KAAK,qBAAqB;;CAGlC,uBAA+B,UAAsC;EACnE,MAAM,MAAM,SAAS,aAAa;EAClC,MAAM,SAAS,KAAK,gBAAgB,IAAI,IAAI;AAC5C,MAAI,OAAQ,QAAO;EAEnB,MAAM,WAAW,0BAA0B,SAAS;AACpD,MAAI,UAAU;AACZ,QAAK,gBAAgB,IAAI,KAAK,SAAS;AACvC,UAAO;;EAGT,MAAM,oBAAoB,cAAc,SAAS;AACjD,MAAI,mBAAmB;AACrB,QAAK,gBAAgB,IAAI,KAAK,kBAAkB;AAChD,UAAO;;;CAKX,sBACE,YACA,SACA,uBACA,IACiD;EACjD,MAAM,WAAW,QAAQ,iBAAiB,MAAM,IAAI,KAAK;EACzD,MAAM,QAAQ,KAAK,0BAA0B,SAAS;EAEtD,MAAM,eAAe,KAAK,8BAA8B,YAAY,QAAQ;EAC5E,MAAM,QAAQ,KAAK,aAAa,eAAe;GAC7C,WAAW;GACX,qBAAqB,uBAAuB,KAAK,OAAO,QAAS,QAAQ,QAAQ;GACjF,eAAe,QAAQ,MAAM;GAC7B,uBAAuB,KAAK,0BAA0B,SAAS;GAC/D,6BAA6B,GAAG;GAChC,wBAAwB,GAAG;GAC3B,uBAAuB,GAAG;GAC3B,CAAC;EACF,MAAM,sBAAsB,MAAM,KAAK,MAAM,EAAE,KAAK;EAEpD,MAAM,gBACH,QAAQ,mBAAiD,KAAK,OAAO,iBAAiB;AA4EzF,SAAO;GAAE,OAAA,IA1ES,MAAM;IACtB,cAAc;KACZ,cAAc,GAAG,oBAAoB,MAAM,cAAc;MACvD,4BAA4B,GAAG,cAAc,2BAA2B;MACxE,mBAAmB;MACnB,yBAAyB,uBAAuB,KAAK,OAAO,QAAS,QAAQ,QAAQ;MACrF,sBAAsB,QAAQ;MAC9B,gBAAgB,QAAQ;MACxB;MACA;MACA;MACA,SAAS,QAAQ;MACjB;MACD,CAAC;KACF;KACA;KACA;KACA,UAAU,EAAE;KACb;IACD,UAAU,8BAA8B;IACxC,YAAY,aAAqB,KAAK,uBAAuB,SAAS;IACtE,gBAAgB,OAAO,EAAE,UAAU,WAAW;KAC5C,MAAM,WAAW,SAAS;AAE1B,SAAI,aAAa,SAAS;MACxB,MAAM,MAAM,KAAK,OAAO,mBAAmB;MAC3C,MAAM,MAAM,KAAK,cAAc;AAC/B,UAAI,OAAO,KAAK;OACd,MAAM,UACJ,OAAQ,MAAgC,YAAY,WAC/C,KAA6B,UAC9B,KAAK,UAAU,QAAQ,EAAE,CAAC;OAChC,MAAM,YACJ,OAAO,IAAI,UAAU,cAAc,WAAW,IAAI,SAAS,YAAY,KAAA;OACzE,MAAM,WAAW,MAAM,gCAAgC;QACrD;QACA,SAAS;SACP,YAAY,IAAI;SAChB,SAAS,IAAI;SACb,QAAQ,IAAI;SACZ;SACA;SACA,SAAS,QAAQ,MAAM,GAAG,IAAI;SAC9B,SAAS,EAAE,SAAS,QAAQ,MAAM,GAAG,IAAK,EAAE;SAC7C;QACF,CAAC;AACF,WAAI,SAAS,YAAY,CAAC,SAAS,SACjC,QAAO;QACL,OAAO;QACP,QAAQ,SAAS,UAAU;QAC5B;;;AAKP,SAAI,CAAC,KAAK,OAAO,WACf;KAEF,MAAM,SAAS,iBAAiB,SAAS;KACzC,MAAM,aAAa,MAAM,KAAK,OAAO,WAAW,kBAC9C,UACC,QAAQ,EAAE,EACX;MACE;MACA,WAAW,WAAW;MACtB,aAAa,QAAQ;MACtB,CACF;AACD,SAAI,CAAC,WAAW,QACd,QAAO;MAAE,OAAO;MAAM,QAAQ,WAAW,UAAU;MAAqC;;IAI7F,CACa;GAAE;GAAqB;;;;;CAMvC,mBAAmB,YAAoB,SAA0B;EAC/D,MAAM,WAAW,KAAK,OAAO,IAAI,WAAW;AAC5C,MAAI,CAAC,UAAU;AACb,OAAI,KACF;IAAE;IAAY;IAAS,oBAAoB,KAAK,OAAO;IAAM,EAC7D,gGAAgG,UACjG;AACD,UAAO;;AAGT,MAAI;GACF,MAAM,QAAQ,aAAa,QAAQ;AACnC,YAAS,MAAM,MAAM,QAAQ;GAE7B,MAAM,MAAM,KAAK,OAAO;GACxB,MAAM,KAAK,KAAK,kBAAkB,YAAY,SAAS,sBAAsB;GAC7E,MAAM,eAAe,KAAK,8BACxB,YACA,SAAS,iBACV;GACD,MAAM,gBACH,SAAS,MAAM,MAAM,iBACrB,SAAS,iBAAiB,mBAC3B,KAAK,OAAO,iBACZ;AAEF,YAAS,MAAM,MAAM,eAAe,GAAG,oBAAoB,MAAM,cAAc;IAC7E,4BAA4B,GAAG,cAAc,2BAA2B;IACxE,mBAAmB,SAAS;IAC5B,yBAAyB,uBAAuB,KAAK,SAAS,iBAAiB,QAAQ;IACvF,sBAAsB,SAAS,iBAAiB;IAChD,gBAAgB,SAAS,iBAAiB;IAC1C,qBAAqB,SAAS;IAC9B;IACA,UAAU;IACV,SAAS,SAAS,iBAAiB;IACnC;IACD,CAAC;AAEF,OAAI,KAAK;IAAE;IAAY;IAAS,EAAE,wBAAwB;AAC1D,UAAO;WACA,KAAK;AACZ,OAAI,MAAM;IAAE;IAAK;IAAY;IAAS,EAAE,kCAAkC;AAC1E,UAAO;;;;;;CAOX,wBAAwB,YAAmC;EACzD,MAAM,WAAW,KAAK,OAAO,IAAI,WAAW;AAC5C,MAAI,CAAC,SACH,QAAO;EAGT,MAAM,WAAW,SAAS,MAAM,MAAM;AACtC,OAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;GAC7C,MAAM,MAAM,SAAS;AACrB,OAAI,IAAI,SAAS,aAAa;IAC5B,MAAM,UAAU,IAAI;AACpB,QAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,mBAAmB,QAAkD;AAE9E,WAAO,OAAO,QAAQ;;;AAG1B,SAAO;;;;;CAMT,gBAAgB,YAAoB,UAAmC;EACrE,MAAM,WAAW,KAAK,OAAO,IAAI,WAAW;AAC5C,MAAI,CAAC,SACH,QAAO;AAGT,WAAS,MAAM,MAAM,WAAW;AAChC,SAAO;;;;;CAMT,YAAY,YAA2C;EACrD,MAAM,WAAW,KAAK,OAAO,IAAI,WAAW;AAC5C,MAAI,CAAC,SACH,QAAO;AAGT,SAAO,SAAS,MAAM,MAAM;;;;;CAM9B,mBAAmB,YAAoB,UAA4D;EACjG,MAAM,WAAW,KAAK,OAAO,IAAI,WAAW;AAC5C,MAAI,CAAC,SACH,QAAO;AAGT,SAAO,SAAS,MAAM,UAAU,SAAS"}
1
+ {"version":3,"file":"agent-manager.js","names":[],"sources":["../../../src/agent/agent-manager.ts"],"sourcesContent":["/**\n * Agent Manager - Manages Agent instances per session\n *\n * Each session gets its own Agent instance for true isolation\n * and concurrent processing across sessions.\n */\n\nimport {\n Agent,\n type AgentMessage,\n type AgentEvent,\n type ThinkingLevel,\n} from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { AgentInstanceGateway } from './agent-instance-gateway.js';\nimport { type Config, getAgentDefaultModelRef } from '../config/schema.js';\nimport { applyConfigOverrides } from '../config/runtime-overrides.js';\nimport { resolveAgentProfileDir } from './agent-scope.js';\nimport {\n type EffectiveAgentProfile,\n resolveEffectiveAgentProfile,\n resolveEffectiveAgentProfileForSession,\n} from '../config/agent-profile.js';\nimport { expandWorkspacePathString } from '../config/workspace-path.js';\nimport type { ModelManager } from './models/manager.js';\nimport { createLogger } from '../utils/logger.js';\nimport { resolveProviderApiKeySync } from '../auth/sync-provider-auth.js';\nimport { resolveModel, getDefaultModelSync, getApiKeySync } from '../providers/index.js';\nimport { createExtensionAwareStreamFn } from '../providers/extension-stream-bridge.js';\nimport { CredentialResolver } from '../auth/credentials.js';\nimport { resolveBundledSkillsDir, resolveStateDir } from '../config/paths.js';\nimport { loadProfileMarkdownFiles, extractTextContent } from './context/workspace.js';\nimport { clearBootstrapSnapshot, resolveBootstrapContextSync } from './bootstrap/bootstrap-files.js';\nimport { loadProjectAgentsContextFile } from './bootstrap/project-agents-context.js';\nimport type { EmbeddedContextFile } from './bootstrap/types.js';\nimport { AgentToolsFactory } from './tools/factory.js';\nimport { parseMcpToolName } from './mcp/bundle-mcp-policy.js';\nimport {\n disposeAllSessionMcpRuntimes,\n retireSessionMcpRuntimeForSessionKey,\n} from './mcp/bundle-mcp-tools.js';\nimport { evictAllEmbeddedSessionRunners, evictEmbeddedSessionRunner } from './embedded/session-runner.js';\nimport type { GatewayClarifyRequestFn } from './tools/clarify-tool.js';\nimport type { ExtensionRegistryImpl as ExtensionRegistry } from '../extensions/index.js';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { CronService } from '../cron/index.js';\nimport type { SessionStore } from '../session/store.js';\nimport { isValidSkillEnvVarName } from './skills/required-env-vars.js';\nimport type { SessionContext } from './session/session-context.js';\nimport type {\n Skill,\n SkillDiagnostic,\n SkillMarkdownPreviewPayload,\n SkillRuntimeStatus,\n} from './skills/types.js';\nimport { createSkillConfigManager, isSkillEnabled, resolveSkillConfig } from './skills/config.js';\nimport { isUnderManagedSkillsDir } from './skills/managed-store.js';\nimport { loadSkillsLock, type SkillHubLockEntry } from './skills/hub-lock.js';\nimport { basename, resolve, sep } from 'node:path';\n\nimport {\n isMemorySubsystemEnabled,\n shouldRegisterCuratedMemoryTool,\n} from './memory/memory-config.js';\nimport type { MemoryManager } from './memory/manager.js';\nimport { MemoryPrefetchCoordinator } from './memory/prefetch-coordinator.js';\nimport { WorkspaceRuntimeRegistry, type WorkspaceRuntime } from './workspace-runtime/registry.js';\nimport { BackgroundReviewCoordinator } from './background-review/coordinator.js';\nimport { maybeRequestChannelExecApproval } from '../channels/exec-approval-runtime.js';\nimport { SkillFilesystemWatcher } from './skills/filesystem-watcher.js';\nimport { ProjectTrustStore, hasTrustRequiringProjectResources } from '../project-trust/trust-store.js';\n\nconst log = createLogger('AgentManager');\n\nexport interface SkillCatalogEntry {\n directoryId: string;\n name: string;\n description: string;\n category?: string;\n source: Skill['source'];\n path: string;\n managed: boolean;\n /** User toggle in ~/.xopc/skills.json (`entries[name].enabled`). Default true. */\n enabled: boolean;\n /** When true, skill is never injected into `<available_skills>` (SKILL.md frontmatter). */\n disableModelInvocation: boolean;\n /** Hub install provenance when under ~/.xopc/skills and listed in skills-lock.json. */\n hub?: SkillHubLockEntry;\n}\n\nexport interface SkillCatalogRuntimeMeta {\n version: string;\n loadedAt: number;\n diagnostics: SkillDiagnostic[];\n status: SkillRuntimeStatus;\n}\n\nexport interface SkillCatalogSnapshot extends SkillCatalogRuntimeMeta {\n catalog: SkillCatalogEntry[];\n}\n\nexport type AgentSkillUnavailableReason = 'agent-denied' | 'disabled' | 'requirements-unmet' | 'model-invocation-disabled';\n\nexport interface AgentSkillAvailabilityEntry extends SkillCatalogEntry {\n availableForCurrentAgent: boolean;\n unavailableReason: AgentSkillUnavailableReason | null;\n}\n\nexport interface AgentSkillAvailabilityPayload {\n agentId: string;\n version: string;\n loadedAt: number;\n diagnostics: SkillDiagnostic[];\n status: SkillRuntimeStatus;\n defaultsAllowlist?: string[];\n agentAllowlist?: string[];\n effectiveAllowlist?: string[];\n skills: AgentSkillAvailabilityEntry[];\n}\n\nexport interface AgentManagerConfig {\n workspace: string;\n model?: string;\n config?: Config;\n extensionRegistry?: ExtensionRegistry;\n hookRunner?: import('../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n getCurrentContext: () => SessionContext | null;\n /** Session persistence (enables `session_search` when set). */\n getSessionStore?: () => SessionStore;\n /** Clears per-session profile default on teardown. */\n getModelManager?: () => ModelManager;\n // Thinking configuration\n thinkingLevel?: ThinkingLevel;\n reasoningLevel?: 'off' | 'on' | 'stream';\n verboseLevel?: 'off' | 'on' | 'full';\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: exposes CronService for the `cronjob` tool. */\n getCronService?: () => CronService | undefined;\n /** Gateway: starts persisted workflow runs (dedicated chat session per run). */\n getWorkflowRunService?: () => import('../workflows/service/workflow-run-service.types.js').WorkflowRunServiceLike | undefined;\n /** Runtime notification for UI/CLI shells that cache skill catalogs. */\n onSkillsUpdated?: (payload: { reason: 'disk' | 'config' }) => void;\n /**\n * Runtime trust override. Persistent \"do not trust\" entries still take precedence.\n */\n isWorkspaceTrusted?: (workspaceDir: string) => boolean | null | undefined;\n}\n\nexport interface AgentInstance {\n agent: Agent;\n sessionKey: string;\n createdAt: number;\n lastUsedAt: number;\n effectiveProfile: EffectiveAgentProfile;\n resolvedWorkspacePath: string;\n /** Tool names registered on this agent (for skill indexing / tool gating). */\n registeredToolNames: string[];\n /** Declared env var names from skill_view; shell reads values from process.env at spawn time. */\n skillEnvPassthroughKeys: Set<string>;\n}\n\n\nexport class AgentManager implements AgentInstanceGateway {\n private agents = new Map<string, AgentInstance>();\n private config: AgentManagerConfig;\n private toolsFactory: AgentToolsFactory;\n\n private mergedConfig(): Config | undefined {\n const base = this.config.config;\n return base ? applyConfigOverrides(base) : undefined;\n }\n /** Default agent workspace (effective profile for `getDefaultAgentId`). */\n private baseWorkspacePath: string;\n /** Per-session absolute markdown workspace when `SessionAgentConfig.workingDirectoryOverride` is set. */\n private sessionWorkspaceOverrides = new Map<string, string>();\n private defaultModel: string;\n private credentialCache = new Map<string, string>();\n private credentialResolver: CredentialResolver;\n private workspaceRuntimes: WorkspaceRuntimeRegistry;\n private memoryPrefetch: MemoryPrefetchCoordinator;\n private backgroundReview: BackgroundReviewCoordinator;\n private skillFilesystemWatcher: SkillFilesystemWatcher;\n private skillDiskRefreshInProgress = false;\n private skillDiskRefreshPending = false;\n private lastExplicitSkillDiskRefreshAt = 0;\n private skillsUpdatedTimer: NodeJS.Timeout | undefined;\n private pendingSkillsUpdatedReason: 'disk' | 'config' | undefined;\n private projectTrustStore = new ProjectTrustStore();\n\n constructor(config: AgentManagerConfig) {\n this.config = config;\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.skillFilesystemWatcher = new SkillFilesystemWatcher({\n onChange: (event) => {\n log.info({ changedPath: event.changedPath }, 'Skill filesystem changed; refreshing skills');\n this.refreshSkillsAfterDiskChange('watch');\n },\n });\n this.skillFilesystemWatcher.refreshPrimaryWorkspace(this.baseWorkspacePath);\n this.workspaceRuntimes = new WorkspaceRuntimeRegistry({\n getConfig: () => this.config.config!,\n bundledSkillsDir: resolveBundledSkillsDir(),\n onRuntimeCreated: (resolvedPath) => {\n this.skillFilesystemWatcher.watchWorkspace(resolvedPath);\n },\n });\n this.memoryPrefetch = new MemoryPrefetchCoordinator({\n getConfig: () => this.config.config,\n getMemoryManagerForSession: (sk) => this.getMemoryManagerForSession(sk),\n getLastAssistantContent: (sk) => this.getLastAssistantContent(sk),\n });\n this.backgroundReview = new BackgroundReviewCoordinator({\n getConfig: () => this.mergedConfig(),\n onSkillsFilesystemMutate: () => this.refreshSkillsAfterDiskChange('explicit'),\n });\n this.toolsFactory = new AgentToolsFactory(this.buildToolsFactoryDeps());\n\n this.defaultModel = config.model || getDefaultModelSync(config.config);\n\n this.credentialResolver = new CredentialResolver();\n this.warmCredentialCache().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Credential cache pre-warm failed: ${em}`);\n });\n }\n\n private computeBaseWorkspacePath(): string {\n const cfg = this.config.config;\n if (!cfg) {\n return expandWorkspacePathString(this.config.workspace);\n }\n return resolveEffectiveAgentProfileForSession(cfg, null).resolvedWorkspacePath;\n }\n\n /**\n * Workspace root for inbound attachments / side effects for this session's agent id.\n * Uses in-memory session workspace overrides when the session has a persisted `workingDirectoryOverride`.\n */\n getResolvedWorkspaceForSession(sessionKey: string): string {\n const cfg = this.config.config!;\n const fromMap = this.sessionWorkspaceOverrides.get(sessionKey);\n if (fromMap !== undefined) {\n return fromMap;\n }\n return resolveEffectiveAgentProfileForSession(cfg, sessionKey).resolvedWorkspacePath;\n }\n\n private getWorkspaceRuntimeForSession(sessionKey: string | undefined): WorkspaceRuntime {\n const resolvedPath = sessionKey\n ? this.getResolvedWorkspaceForSession(sessionKey)\n : this.baseWorkspacePath;\n return this.workspaceRuntimes.getOrCreate(resolvedPath);\n }\n\n private getCurrentWorkspaceRuntime(): WorkspaceRuntime {\n return this.getWorkspaceRuntimeForSession(this.config.getCurrentContext?.()?.sessionKey);\n }\n\n /**\n * Sync in-memory workspace override from session config (after load or PATCH).\n * Pass `null` to clear when the session has no `workingDirectoryOverride` on disk.\n */\n setSessionWorkspaceOverride(sessionKey: string, absolutePath: string | null): void {\n if (absolutePath === null || absolutePath === '') {\n this.sessionWorkspaceOverrides.delete(sessionKey);\n } else {\n this.sessionWorkspaceOverrides.set(sessionKey, absolutePath);\n }\n }\n\n /** Merged `thinkingDefault` for this session's agent id (defaults + `agents.list`). */\n getThinkingDefaultForSession(\n sessionKey: string,\n ): import('./transcript/thinking-types.js').ThinkLevel | undefined {\n const cfg = this.mergedConfig();\n if (!cfg) {\n return undefined;\n }\n return resolveEffectiveAgentProfileForSession(cfg, sessionKey).thinkingDefault;\n }\n\n private pickDefaultModelRef(): string {\n const cfg = this.mergedConfig();\n const ref = getAgentDefaultModelRef(cfg);\n return ref?.trim() || getDefaultModelSync(cfg);\n }\n\n private resolveModelStringToModel(modelRef: string): Model<Api> {\n try {\n return resolveModel(modelRef);\n } catch {\n const fallback = getDefaultModelSync(this.mergedConfig());\n log.warn({ modelRef, fallback }, 'Model not found, using default');\n return resolveModel(fallback);\n }\n }\n\n /**\n * Keep defaults in sync when config is hot-reloaded or saved from the UI.\n *\n * The previous implementation rebuilt the entire `AgentToolsFactory` (80+ lines\n * of dependency wiring) on every reload. The factory's deps are now built from\n * a single helper ({@link buildToolsFactoryDeps}) and read `this.*` through\n * closures, so existing instances automatically see the new config without\n * reconstruction. The browser is still shut down because its cached settings\n * (headless mode, backend choice) come from the config snapshot at connect time.\n */\n updateAgentDefaults(config: Config): void {\n this.config.config = config;\n const ref = getAgentDefaultModelRef(config);\n this.config.model = ref;\n this.defaultModel = ref || getDefaultModelSync(config);\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.skillFilesystemWatcher.refreshPrimaryWorkspace(this.baseWorkspacePath);\n void this.toolsFactory.shutdownBrowser();\n void this.workspaceRuntimes.clearAll();\n }\n\n /**\n * Construct the dep bag passed to `AgentToolsFactory`. Closures reference\n * `this.*` so they remain valid across hot reloads (no rebuild needed).\n */\n private buildToolsFactoryDeps(): ConstructorParameters<typeof AgentToolsFactory>[0] {\n return {\n workspace: this.baseWorkspacePath,\n extensionRegistry: this.config.extensionRegistry,\n getCurrentContext: this.config.getCurrentContext,\n hookRunner: this.config.hookRunner,\n bus: this.config.bus,\n getConfig: () => this.mergedConfig(),\n getPrimaryModel: () => this.resolveModelStringToModel(this.pickDefaultModelRef()),\n getBuiltinMemoryStore: () => this.getCurrentWorkspaceRuntime().builtinMemoryStore,\n getMemoryManager: () => this.getCurrentWorkspaceRuntime().memoryManager,\n getSessionStore: this.config.getSessionStore,\n gatewayClarify: this.config.gatewayClarify,\n getCronService: this.config.getCronService,\n getWorkflowRunService: this.config.getWorkflowRunService,\n getSkillIndexingContext: () => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return undefined;\n const inst = this.agents.get(ctx.sessionKey);\n if (!inst) return undefined;\n return {\n registeredToolNames: inst.registeredToolNames,\n skillAllowlist: inst.effectiveProfile.skillsAllowlist,\n };\n },\n onSkillsFilesystemMutate: () => {\n this.refreshSkillsAfterDiskChange('explicit');\n },\n getSkillPassthroughEnvVarNames: () => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return [];\n return [...(this.agents.get(ctx.sessionKey)?.skillEnvPassthroughKeys ?? [])];\n },\n registerSkillEnvPassthrough: (names: string[]) => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return;\n const inst = this.agents.get(ctx.sessionKey);\n if (!inst) return;\n for (const n of names) {\n if (isValidSkillEnvVarName(n)) {\n inst.skillEnvPassthroughKeys.add(n.trim());\n }\n }\n },\n };\n }\n\n getMemoryManager(): MemoryManager {\n return this.getCurrentWorkspaceRuntime().memoryManager;\n }\n\n private getMemoryManagerForSession(sessionKey: string): MemoryManager {\n return this.getWorkspaceRuntimeForSession(sessionKey).memoryManager;\n }\n\n /**\n * Prefix the user turn with fenced prefetched memory (external providers).\n * Delegates to {@link MemoryPrefetchCoordinator}.\n */\n applyMemoryPrefetchToUserMessage(\n userMessage: AgentMessage,\n sessionKey: string,\n ): Promise<AgentMessage> {\n return this.memoryPrefetch.applyToUserMessage(userMessage, sessionKey);\n }\n\n /**\n * After a completed turn: sync external providers and queue next-turn prefetch.\n * Delegates to {@link MemoryPrefetchCoordinator}.\n */\n afterAgentTurn(sessionKey: string, userPlainText: string): void {\n this.memoryPrefetch.afterTurn(sessionKey, userPlainText);\n }\n\n /**\n * Call once per user turn before the main `agent.prompt` (via {@link runAgentTurnWithModelFallbacks} `beforeUserPrompt`).\n * Delegates to {@link BackgroundReviewCoordinator}.\n */\n beginBackgroundReviewUserTurn(sessionKey: string): void {\n const inst = this.agents.get(sessionKey);\n if (!inst) return;\n this.backgroundReview.beginUserTurn(sessionKey, inst.registeredToolNames);\n }\n\n /**\n * After a successful main turn (after memory sync via `afterAgentTurn`), may run a quiet follow-up for memory/skills.\n * Delegates to {@link BackgroundReviewCoordinator}.\n */\n scheduleBackgroundReviewAfterUserTurn(sessionKey: string): void {\n const inst = this.agents.get(sessionKey);\n if (!inst) return;\n this.backgroundReview.scheduleAfterUserTurn({\n sessionKey,\n agent: inst.agent,\n registeredToolNames: inst.registeredToolNames,\n skillAllowlist: inst.effectiveProfile.skillsAllowlist,\n workspacePath: this.getResolvedWorkspaceForSession(sessionKey),\n lastAssistantText: this.getLastAssistantContent(sessionKey),\n workspaceRuntime: this.getWorkspaceRuntimeForSession(sessionKey),\n });\n }\n\n /**\n * Expand `/skill:name` user text into the full skill block for the current turn (WebChat, channels).\n */\n expandSkillUserText(text: string): string {\n const ctx = this.config.getCurrentContext?.();\n const sessionKey = ctx?.sessionKey;\n const inst = sessionKey ? this.agents.get(sessionKey) : undefined;\n return this.getWorkspaceRuntimeForSession(sessionKey).skillManager.expandCommand(text, {\n skillAllowlist: inst?.effectiveProfile.skillsAllowlist,\n registeredToolNames: inst?.registeredToolNames,\n });\n }\n\n /** Structured SKILL.md preview for the gateway console. */\n getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null {\n const skill = this.getCurrentWorkspaceRuntime().skillManager.findSkill(skillName);\n if (!skill) return null;\n\n return {\n name: skill.name,\n description: skill.description,\n bodyMarkdown: skill.content,\n disableModelInvocation: skill.disableModelInvocation,\n metadata: skill.metadata,\n toolConditions: skill.toolConditions,\n requiredEnvVarNames: skill.requiredEnvVarNames,\n };\n }\n\n private loadProfileMarkdownForProfile(profile: EffectiveAgentProfile): ReturnType<typeof loadProfileMarkdownFiles> {\n const cfg = this.config.config!;\n const profileDir = resolveAgentProfileDir(cfg, profile.agentId);\n return loadProfileMarkdownFiles(profileDir);\n }\n\n private isProjectWorkspaceTrusted(workspaceDir: string): boolean {\n if (!hasTrustRequiringProjectResources(workspaceDir)) {\n return false;\n }\n\n const persisted = this.projectTrustStore.get(workspaceDir);\n if (persisted === false) {\n return false;\n }\n if (persisted === true) {\n return true;\n }\n\n try {\n return this.config.isWorkspaceTrusted?.(workspaceDir) === true;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, workspaceDir, errorMessage }, `Workspace trust override failed: ${errorMessage}`);\n return false;\n }\n }\n\n private resolveContextFilesForSession(\n sessionKey: string,\n profile: EffectiveAgentProfile,\n excludeHeartbeat?: boolean,\n ): EmbeddedContextFile[] {\n const cfg = this.config.config!;\n const profileDir = resolveAgentProfileDir(cfg, profile.agentId);\n const heartbeatEnabled = cfg.gateway?.heartbeat?.includeSystemPromptSection ?? false;\n const contextInjection = cfg.agents?.defaults?.contextInjection ?? 'always';\n const { contextFiles } = resolveBootstrapContextSync({\n profileDir,\n config: cfg,\n sessionKey,\n excludeHeartbeat: excludeHeartbeat ?? !heartbeatEnabled,\n contextInjection,\n });\n const shouldAppendProjectContext =\n contextInjection === 'always' ||\n (contextInjection === 'continuation-skip' && contextFiles.length > 0);\n const workspaceDir = this.getResolvedWorkspaceForSession(sessionKey);\n if (\n shouldAppendProjectContext &&\n this.isProjectWorkspaceTrusted(workspaceDir)\n ) {\n const projectAgentsFile = loadProjectAgentsContextFile(workspaceDir);\n if (projectAgentsFile) {\n contextFiles.push(projectAgentsFile);\n }\n }\n return contextFiles;\n }\n\n private skillCatalogEntryFromSkill(s: Skill, skillsConfig = createSkillConfigManager(resolveStateDir()).load(), lock = loadSkillsLock()): SkillCatalogEntry {\n const base = resolve(s.baseDir);\n const managed = isUnderManagedSkillsDir(s.baseDir);\n const directoryId = base.split(sep).filter(Boolean).pop() || s.name;\n const enabled = !(skillsConfig.entries?.[s.name]?.enabled === false);\n const hubKey = managed ? basename(base) : '';\n const hub = managed && hubKey ? lock.entries[hubKey] : undefined;\n\n return {\n directoryId,\n name: s.name,\n description: s.description,\n category: s.category,\n source: s.source,\n path: s.baseDir,\n managed,\n enabled,\n disableModelInvocation: s.disableModelInvocation,\n ...(hub ? { hub } : {}),\n };\n }\n\n getSkillCatalog(): SkillCatalogEntry[] {\n return this.getSkillCatalogSnapshot().catalog;\n }\n\n getSkillCatalogSnapshot(): SkillCatalogSnapshot {\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n const rt = this.getCurrentWorkspaceRuntime();\n return {\n catalog: rt.skillManager\n .getSkills()\n .map((s) => this.skillCatalogEntryFromSkill(s, skillsConfig, lock)),\n version: rt.skillManager.getVersion(),\n loadedAt: rt.skillManager.getLoadedAt(),\n diagnostics: rt.skillManager.getDiagnostics(),\n status: rt.skillManager.getStatus(),\n };\n }\n\n getAgentSkillAvailability(agentId: string): AgentSkillAvailabilityPayload {\n const cfg = this.config.config!;\n const defaultsAllowlist = cfg.agents?.defaults?.skills;\n const entry = Array.isArray(cfg.agents?.list)\n ? cfg.agents.list.find((a) => a && a.enabled !== false && a.id.toLowerCase() === agentId.toLowerCase())\n : undefined;\n const profile = resolveEffectiveAgentProfile(cfg, agentId);\n const rt = this.workspaceRuntimes.getOrCreate(profile.resolvedWorkspacePath);\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n const allow = profile.skillsAllowlist === undefined ? undefined : new Set(profile.skillsAllowlist.map((s) => s.toLowerCase()));\n\n const skills = rt.skillManager.getSkills().map((s) => {\n let unavailableReason: AgentSkillUnavailableReason | null = null;\n const skillConfig = resolveSkillConfig(s, skillsConfig);\n if (skillConfig.enabled === false) {\n unavailableReason = 'disabled';\n } else if (s.disableModelInvocation) {\n unavailableReason = 'model-invocation-disabled';\n } else if (!isSkillEnabled(s, skillsConfig)) {\n unavailableReason = 'requirements-unmet';\n } else if (allow !== undefined && !allow.has(s.name.toLowerCase())) {\n unavailableReason = 'agent-denied';\n }\n\n return {\n ...this.skillCatalogEntryFromSkill(s, skillsConfig, lock),\n availableForCurrentAgent: unavailableReason === null,\n unavailableReason,\n };\n });\n\n return {\n agentId: profile.agentId,\n version: rt.skillManager.getVersion(),\n loadedAt: rt.skillManager.getLoadedAt(),\n diagnostics: rt.skillManager.getDiagnostics(),\n status: rt.skillManager.getStatus(),\n ...(defaultsAllowlist !== undefined ? { defaultsAllowlist: [...defaultsAllowlist] } : {}),\n ...(entry?.skills !== undefined ? { agentAllowlist: [...entry.skills] } : {}),\n ...(profile.skillsAllowlist !== undefined ? { effectiveAllowlist: [...profile.skillsAllowlist] } : {}),\n skills,\n };\n }\n\n /**\n * After ~/.xopc/skills.json changes (enable/disable), refresh `<available_skills>` on active agents.\n */\n refreshSkillsAfterSkillConfigChange(): void {\n const cfg = this.config.config!;\n const touched = new Set<string>();\n for (const [resolvedPath, rt] of this.workspaceRuntimes.entries()) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(resolvedPath);\n }\n for (const instance of this.agents.values()) {\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n if (!touched.has(resolvedWorkspacePath)) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n const newPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel:\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium',\n });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skill toggles applied; system prompt updated');\n this.scheduleSkillsUpdated('config');\n }\n\n /**\n * Reload skills from disk and refresh system prompt on all active Agent instances.\n */\n refreshSkillsAfterDiskChange(source: 'explicit' | 'watch' = 'explicit'): void {\n const now = Date.now();\n if (source === 'watch' && now - this.lastExplicitSkillDiskRefreshAt < 2500) {\n log.debug({ changedWithinMs: now - this.lastExplicitSkillDiskRefreshAt }, 'Ignoring skill watcher echo after explicit refresh');\n return;\n }\n if (source === 'explicit') {\n this.lastExplicitSkillDiskRefreshAt = now;\n }\n\n if (this.skillDiskRefreshInProgress) {\n this.skillDiskRefreshPending = true;\n return;\n }\n\n this.skillDiskRefreshInProgress = true;\n let refreshed = false;\n try {\n do {\n this.skillDiskRefreshPending = false;\n this.applySkillsAfterDiskChange();\n refreshed = true;\n } while (this.skillDiskRefreshPending);\n } finally {\n this.skillDiskRefreshInProgress = false;\n }\n\n if (refreshed) {\n this.scheduleSkillsUpdated('disk');\n }\n }\n\n private scheduleSkillsUpdated(reason: 'disk' | 'config'): void {\n this.pendingSkillsUpdatedReason = reason === 'disk' ? 'disk' : this.pendingSkillsUpdatedReason ?? 'config';\n if (this.skillsUpdatedTimer) clearTimeout(this.skillsUpdatedTimer);\n this.skillsUpdatedTimer = setTimeout(() => {\n const nextReason = this.pendingSkillsUpdatedReason ?? reason;\n this.pendingSkillsUpdatedReason = undefined;\n this.skillsUpdatedTimer = undefined;\n this.config.onSkillsUpdated?.({ reason: nextReason });\n }, 250);\n }\n\n private applySkillsAfterDiskChange(): void {\n const cfg = this.config.config!;\n // Reload every workspace SkillManager first. When there are no active agent sessions\n // (e.g. gateway UI only), the loop below runs zero times — without this, `getSkillCatalog()`\n // and delete flows still see stale in-memory skills after ~/.xopc/skills changes.\n for (const rt of this.workspaceRuntimes.values()) {\n rt.skillManager.reload();\n }\n\n const touched = new Set<string>();\n for (const instance of this.agents.values()) {\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n if (!touched.has(resolvedWorkspacePath)) {\n touched.add(resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n const newPrompt = rt.systemPromptBuilder.rebuild(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel:\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium',\n });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skills refreshed; system prompt updated');\n }\n\n /**\n * Get or create an Agent instance for a session\n */\n getOrCreateAgent(sessionKey: string): Agent {\n const cfg = this.config.config!;\n const targetPath = this.getResolvedWorkspaceForSession(sessionKey);\n const existing = this.agents.get(sessionKey);\n if (existing) {\n if (existing.resolvedWorkspacePath !== targetPath) {\n this.removeAgent(sessionKey);\n } else {\n existing.lastUsedAt = Date.now();\n log.debug({ sessionKey }, 'Reusing existing agent instance');\n return existing.agent;\n }\n }\n\n const profile = resolveEffectiveAgentProfileForSession(cfg, sessionKey);\n const resolvedPath = targetPath;\n const rt = this.workspaceRuntimes.getOrCreate(resolvedPath);\n\n if (isMemorySubsystemEnabled(cfg)) {\n void rt.memoryManager\n .initializeAll(sessionKey, { workspace: resolvedPath })\n .catch((err) => log.warn({ err, sessionKey }, 'memory initializeAll failed'));\n }\n\n if (isMemorySubsystemEnabled(cfg) && shouldRegisterCuratedMemoryTool(cfg)) {\n rt.builtinMemoryStore.loadFromDiskSync();\n }\n\n const { agent, registeredToolNames } = this.createAgentForProfile(\n sessionKey,\n profile,\n resolvedPath,\n rt,\n );\n\n this.agents.set(sessionKey, {\n agent,\n sessionKey,\n createdAt: Date.now(),\n lastUsedAt: Date.now(),\n effectiveProfile: profile,\n resolvedWorkspacePath: resolvedPath,\n registeredToolNames,\n skillEnvPassthroughKeys: new Set<string>(),\n });\n\n this.backgroundReview.attachToAgent(sessionKey, agent, registeredToolNames);\n\n const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;\n this.config.getModelManager?.().setSessionProfileDefault(sessionKey, modelRef);\n\n log.debug({ sessionKey, totalAgents: this.agents.size, agentId: profile.agentId }, 'Created new agent instance');\n return agent;\n }\n\n /**\n * Get existing agent for a session (if any)\n */\n getAgent(sessionKey: string): Agent | undefined {\n return this.agents.get(sessionKey)?.agent;\n }\n\n /**\n * Check if an agent exists for a session\n */\n hasAgent(sessionKey: string): boolean {\n return this.agents.has(sessionKey);\n }\n\n /**\n * Remove an agent instance\n */\n removeAgent(sessionKey: string): boolean {\n const instance = this.agents.get(sessionKey);\n if (instance) {\n this.backgroundReview.forgetSession(sessionKey);\n void this.toolsFactory.closeBrowserPageForSession(sessionKey);\n void retireSessionMcpRuntimeForSessionKey({ sessionKey, reason: 'agent-evict' });\n instance.agent.abort();\n evictEmbeddedSessionRunner(sessionKey, 'agent_removed');\n this.agents.delete(sessionKey);\n this.memoryPrefetch.forgetSession(sessionKey);\n clearBootstrapSnapshot(sessionKey);\n this.config.getModelManager?.().clearSessionProfileDefault(sessionKey);\n log.info({ sessionKey, totalAgents: this.agents.size }, 'Removed agent instance');\n return true;\n }\n return false;\n }\n\n /**\n * Get all active session keys\n */\n getActiveSessions(): string[] {\n return Array.from(this.agents.keys());\n }\n\n /**\n * Get agent count\n */\n getAgentCount(): number {\n return this.agents.size;\n }\n\n /**\n * Merge per-turn channel system prompt (e.g. Telegram group/topic override) into the agent.\n */\n applyTurnChannelSystemPrompt(sessionKey: string, channelSystemPrompt: string): void {\n const trimmed = channelSystemPrompt.trim();\n if (!trimmed) return;\n\n const instance = this.agents.get(sessionKey);\n if (!instance) return;\n\n const cfg = this.config.config!;\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(sessionKey, instance.effectiveProfile);\n const modelRef = instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel;\n const thinkingLevel =\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey,\n modelRef,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n extraSystemPrompt: trimmed,\n });\n }\n\n /**\n * Set thinking level for a session's agent\n */\n setThinkingLevel(sessionKey: string, level: ThinkingLevel): void {\n const instance = this.agents.get(sessionKey);\n if (instance) {\n instance.agent.state.thinkingLevel = level;\n log.debug({ sessionKey, thinkingLevel: level }, 'Set thinking level for agent');\n }\n }\n\n /**\n * Dispose all agents\n */\n dispose(): void {\n if (this.skillsUpdatedTimer) clearTimeout(this.skillsUpdatedTimer);\n this.skillFilesystemWatcher.dispose();\n void this.toolsFactory.shutdownBrowser();\n void disposeAllSessionMcpRuntimes().catch(() => {});\n evictAllEmbeddedSessionRunners('agent_manager_dispose');\n this.backgroundReview.clear();\n for (const instance of this.agents.values()) {\n instance.agent.abort();\n }\n this.agents.clear();\n this.memoryPrefetch.clear();\n this.sessionWorkspaceOverrides.clear();\n void this.workspaceRuntimes.clearAll();\n log.debug('All agent instances disposed');\n }\n\n async warmCredentialCache(): Promise<void> {\n const profiles = await this.credentialResolver.listProfiles();\n for (const profile of profiles) {\n const secret = profile.key?.trim()\n ? profile.key.trim()\n : profile.envVar\n ? process.env[profile.envVar]?.trim()\n : undefined;\n if (secret) {\n this.credentialCache.set(profile.provider.toLowerCase(), secret);\n }\n }\n log.debug({ count: this.credentialCache.size }, 'Credential cache warmed');\n }\n\n async refreshCredentials(): Promise<void> {\n this.credentialCache.clear();\n await this.warmCredentialCache();\n }\n\n private resolveApiKeyWithCache(provider: string): string | undefined {\n const key = provider.toLowerCase();\n const cached = this.credentialCache.get(key);\n if (cached) return cached;\n\n const fromDisk = resolveProviderApiKeySync(provider);\n if (fromDisk) {\n this.credentialCache.set(key, fromDisk);\n return fromDisk;\n }\n\n const fromRegistryOrEnv = getApiKeySync(provider);\n if (fromRegistryOrEnv) {\n this.credentialCache.set(key, fromRegistryOrEnv);\n return fromRegistryOrEnv;\n }\n return undefined;\n }\n\n private createAgentForProfile(\n sessionKey: string,\n profile: EffectiveAgentProfile,\n resolvedWorkspacePath: string,\n rt: WorkspaceRuntime,\n ): { agent: Agent; registeredToolNames: string[] } {\n const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;\n const model = this.resolveModelStringToModel(modelRef);\n\n const contextFiles = this.resolveContextFilesForSession(sessionKey, profile);\n const tools = this.toolsFactory.createAllTools({\n workspace: resolvedWorkspacePath,\n profileMarkdownRoot: resolveAgentProfileDir(this.config.config!, profile.agentId),\n disabledTools: profile.tools.disable,\n getPrimaryModel: () => this.resolveModelStringToModel(modelRef),\n getBuiltinMemoryStore: () => rt.builtinMemoryStore,\n getMemoryManager: () => rt.memoryManager,\n getSkillManager: () => rt.skillManager,\n });\n const registeredToolNames = tools.map((t) => t.name);\n\n const thinkingLevel =\n (profile.thinkingDefault as ThinkingLevel | undefined) ?? this.config.thinkingLevel ?? 'medium';\n\n const agent = new Agent({\n initialState: {\n systemPrompt: rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(this.config.config!, profile.agentId),\n systemPromptOverride: profile.systemPromptOverride,\n skillAllowlist: profile.skillsAllowlist,\n registeredToolNames,\n sessionKey,\n modelRef,\n agentId: profile.agentId,\n thinkingLevel,\n }),\n model,\n thinkingLevel,\n tools,\n messages: [],\n },\n streamFn: createExtensionAwareStreamFn(),\n getApiKey: (provider: string) => this.resolveApiKeyWithCache(provider),\n beforeToolCall: async ({ toolCall, args }) => {\n const toolName = toolCall.name;\n\n if (toolName === 'shell') {\n const ctx = this.config.getCurrentContext();\n const cfg = this.mergedConfig();\n if (ctx && cfg) {\n const command =\n typeof (args as { command?: unknown })?.command === 'string'\n ? (args as { command: string }).command\n : JSON.stringify(args ?? {});\n const accountId =\n typeof ctx.metadata?.accountId === 'string' ? ctx.metadata.accountId : undefined;\n const approval = await maybeRequestChannelExecApproval({\n cfg,\n payload: {\n sessionKey: ctx.sessionKey,\n channel: ctx.channel,\n chatId: ctx.chatId,\n accountId,\n toolName,\n summary: command.slice(0, 500),\n details: { command: command.slice(0, 2000) },\n },\n });\n if (approval.required && !approval.approved) {\n return {\n block: true,\n reason: approval.reason ?? 'Exec approval denied or timed out.',\n };\n }\n }\n }\n\n if (!this.config.hookRunner) {\n return undefined;\n }\n const parsed = parseMcpToolName(toolName);\n const hookResult = await this.config.hookRunner.runBeforeToolCall(\n toolName,\n (args ?? {}) as Record<string, unknown>,\n {\n sessionKey,\n isMcpTool: parsed !== null,\n mcpServerId: parsed?.serverId,\n },\n );\n if (!hookResult.allowed) {\n return { block: true, reason: hookResult.reason ?? 'Tool call blocked by policy hook.' };\n }\n return undefined;\n },\n });\n return { agent, registeredToolNames };\n }\n\n /**\n * Set model for a specific session\n */\n setModelForSession(sessionKey: string, modelId: string): boolean {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n log.warn(\n { sessionKey, modelId, activeSessionCount: this.agents.size },\n `setModelForSession: no agent instance for session (create session / run turn first); modelId=${modelId}`,\n );\n return false;\n }\n\n try {\n const model = resolveModel(modelId);\n instance.agent.state.model = model;\n\n const cfg = this.config.config!;\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(\n sessionKey,\n instance.effectiveProfile,\n );\n const thinkingLevel =\n (instance.agent.state.thinkingLevel as ThinkingLevel | undefined) ??\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey,\n modelRef: modelId,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n });\n\n log.info({ sessionKey, modelId }, 'Model set for session');\n return true;\n } catch (err) {\n log.error({ err, sessionKey, modelId }, 'Failed to set model for session');\n return false;\n }\n }\n\n /**\n * Get last assistant content from a session's agent\n */\n getLastAssistantContent(sessionKey: string): string | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n const messages = instance.agent.state.messages;\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'assistant') {\n const content = msg.content;\n if (Array.isArray(content)) {\n return extractTextContent(content as Array<{ type: string; text?: string }>);\n }\n return String(content);\n }\n }\n return null;\n }\n\n /**\n * Replace messages for a session's agent\n */\n replaceMessages(sessionKey: string, messages: AgentMessage[]): boolean {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return false;\n }\n\n instance.agent.state.messages = messages;\n return true;\n }\n\n /**\n * Get messages for a session's agent\n */\n getMessages(sessionKey: string): AgentMessage[] | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n return instance.agent.state.messages;\n }\n\n /**\n * Subscribe to agent events for a session\n */\n subscribeToSession(sessionKey: string, callback: (event: AgentEvent) => void): (() => void) | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n return instance.agent.subscribe(callback);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { EmbeddedContextFile } from './types.js';
2
+ export declare function loadProjectAgentsContextFile(workspaceDir: string): EmbeddedContextFile | null;
@@ -0,0 +1,32 @@
1
+ import { DEFAULT_AGENTS_FILENAME, stripFrontMatter } from "../context/workspace.js";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+ //#region src/agent/bootstrap/project-agents-context.ts
5
+ const PROJECT_AGENTS_MAX_CHARS = 2e4;
6
+ function truncateProjectAgentsContent(content) {
7
+ if (content.length <= PROJECT_AGENTS_MAX_CHARS) return content;
8
+ const suffix = `\n\n[Project AGENTS.md truncated to ${PROJECT_AGENTS_MAX_CHARS} characters]`;
9
+ return `${content.slice(0, Math.max(0, PROJECT_AGENTS_MAX_CHARS - suffix.length)).trimEnd()}${suffix}`;
10
+ }
11
+ function loadProjectAgentsContextFile(workspaceDir) {
12
+ const agentsPath = resolve(join(workspaceDir, DEFAULT_AGENTS_FILENAME));
13
+ if (!existsSync(agentsPath)) return null;
14
+ try {
15
+ const content = truncateProjectAgentsContent(stripFrontMatter(readFileSync(agentsPath, "utf-8")).trim());
16
+ if (!content) return null;
17
+ return {
18
+ path: agentsPath,
19
+ content: [
20
+ "Workspace AGENTS.md contains project-local instructions. Follow it for this workspace's coding conventions, commands, tests, and repository-specific workflows. If it conflicts with higher-priority system instructions, tool safety, or the user's explicit request, follow the higher-priority instruction.",
21
+ "",
22
+ content
23
+ ].join("\n")
24
+ };
25
+ } catch {
26
+ return null;
27
+ }
28
+ }
29
+ //#endregion
30
+ export { loadProjectAgentsContextFile };
31
+
32
+ //# sourceMappingURL=project-agents-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-agents-context.js","names":[],"sources":["../../../../src/agent/bootstrap/project-agents-context.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { stripFrontMatter, DEFAULT_AGENTS_FILENAME } from '../context/workspace.js';\nimport type { EmbeddedContextFile } from './types.js';\n\nconst PROJECT_AGENTS_MAX_CHARS = 20_000;\n\nfunction truncateProjectAgentsContent(content: string): string {\n if (content.length <= PROJECT_AGENTS_MAX_CHARS) {\n return content;\n }\n const suffix = `\\n\\n[Project AGENTS.md truncated to ${PROJECT_AGENTS_MAX_CHARS} characters]`;\n return `${content.slice(0, Math.max(0, PROJECT_AGENTS_MAX_CHARS - suffix.length)).trimEnd()}${suffix}`;\n}\n\nexport function loadProjectAgentsContextFile(workspaceDir: string): EmbeddedContextFile | null {\n const agentsPath = resolve(join(workspaceDir, DEFAULT_AGENTS_FILENAME));\n if (!existsSync(agentsPath)) {\n return null;\n }\n\n try {\n const content = truncateProjectAgentsContent(stripFrontMatter(readFileSync(agentsPath, 'utf-8')).trim());\n if (!content) {\n return null;\n }\n return {\n path: agentsPath,\n content: [\n 'Workspace AGENTS.md contains project-local instructions. Follow it for this workspace\\'s coding conventions, commands, tests, and repository-specific workflows. If it conflicts with higher-priority system instructions, tool safety, or the user\\'s explicit request, follow the higher-priority instruction.',\n '',\n content,\n ].join('\\n'),\n };\n } catch {\n return null;\n }\n}\n"],"mappings":";;;;AAMA,MAAM,2BAA2B;AAEjC,SAAS,6BAA6B,SAAyB;AAC7D,KAAI,QAAQ,UAAU,yBACpB,QAAO;CAET,MAAM,SAAS,uCAAuC,yBAAyB;AAC/E,QAAO,GAAG,QAAQ,MAAM,GAAG,KAAK,IAAI,GAAG,2BAA2B,OAAO,OAAO,CAAC,CAAC,SAAS,GAAG;;AAGhG,SAAgB,6BAA6B,cAAkD;CAC7F,MAAM,aAAa,QAAQ,KAAK,cAAc,wBAAwB,CAAC;AACvE,KAAI,CAAC,WAAW,WAAW,CACzB,QAAO;AAGT,KAAI;EACF,MAAM,UAAU,6BAA6B,iBAAiB,aAAa,YAAY,QAAQ,CAAC,CAAC,MAAM,CAAC;AACxG,MAAI,CAAC,QACH,QAAO;AAET,SAAO;GACL,MAAM;GACN,SAAS;IACP;IACA;IACA;IACD,CAAC,KAAK,KAAK;GACb;SACK;AACN,SAAO"}
@@ -1,9 +1,7 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
4
3
  import { handlePersistentGoalPostTurn } from "./post-turn.js";
5
4
  //#region src/agent/goals/persistent-goal-service.ts
6
- init_session_key();
7
5
  init_logger();
8
6
  const log = createLogger("PersistentGoalService");
9
7
  var PersistentGoalService = class {
@@ -23,7 +21,7 @@ var PersistentGoalService = class {
23
21
  * follow-up message as an inbound bus event so the existing inbound loop picks it up.
24
22
  */
25
23
  scheduleContinuation(sessionKey, message, routing) {
26
- if (parseSessionKey(sessionKey)?.source === "webchat" && this.webchatContinuationScheduler) {
24
+ if (routing.channel === "webchat" && this.webchatContinuationScheduler) {
27
25
  this.webchatContinuationScheduler(sessionKey, message);
28
26
  return;
29
27
  }
@@ -94,7 +92,7 @@ var PersistentGoalService = class {
94
92
  chatId: payload.chatId,
95
93
  inboundMetadata: payload.outboundMetadata
96
94
  });
97
- const publishVerdict = !(parseSessionKey(payload.sessionKey)?.source === "webchat") && payload.channel !== "cli" ? async (text) => {
95
+ const publishVerdict = !(payload.channel === "webchat") && payload.channel !== "cli" ? async (text) => {
98
96
  await this.opts.bus.publishOutbound({
99
97
  channel: payload.channel,
100
98
  chat_id: payload.chatId,