@xopcai/xopc 0.0.84 → 0.0.86

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 (418) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  3. package/dist/extensions/feishu/src/plugin.d.ts +2 -0
  4. package/dist/extensions/feishu/src/plugin.js +10 -0
  5. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  6. package/dist/extensions/feishu/src/workflow-progress.d.ts +27 -0
  7. package/dist/extensions/feishu/src/workflow-progress.js +99 -0
  8. package/dist/extensions/feishu/src/workflow-progress.js.map +1 -0
  9. package/dist/extensions/telegram/src/plugin.d.ts +2 -0
  10. package/dist/extensions/telegram/src/plugin.js +11 -1
  11. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  12. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  13. package/dist/extensions/telegram/src/workflow-progress.d.ts +24 -0
  14. package/dist/extensions/telegram/src/workflow-progress.js +73 -0
  15. package/dist/extensions/telegram/src/workflow-progress.js.map +1 -0
  16. package/dist/extensions/telegram/xopc.extension.json +1 -1
  17. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +158 -0
  18. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +1 -0
  19. package/dist/extensions/weixin/src/api/api.js +2 -2
  20. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  21. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  22. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  23. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  24. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  25. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  26. package/dist/extensions/weixin/src/plugin.d.ts +2 -0
  27. package/dist/extensions/weixin/src/plugin.js +11 -1
  28. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  29. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  30. package/dist/extensions/weixin/src/workflow-progress.d.ts +26 -0
  31. package/dist/extensions/weixin/src/workflow-progress.js +99 -0
  32. package/dist/extensions/weixin/src/workflow-progress.js.map +1 -0
  33. package/dist/gateway/static/root/assets/agents-mS3_HpRI.js +222 -0
  34. package/dist/gateway/static/root/assets/apps-page-DrfytjOb.js +1 -0
  35. package/dist/gateway/static/root/assets/channels-settings-BG6b9KrW.js +1 -0
  36. package/dist/gateway/static/root/assets/channels-status-swr-Bs5kMCMI.js +8 -0
  37. package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +1 -0
  38. package/dist/gateway/static/root/assets/cron-api-BuVcZ5zR.js +1 -0
  39. package/dist/gateway/static/root/assets/cron-page-BMrloeFH.js +1 -0
  40. package/dist/gateway/static/root/assets/dist-BTWC-BTN.js +45 -0
  41. package/dist/gateway/static/root/assets/{dist-CqNMNhJM.js → dist-CKU1OOTf.js} +1 -1
  42. package/dist/gateway/static/root/assets/{extension-debug-page-gf2L0kY_.js → extension-debug-page-BdW_46sN.js} +1 -1
  43. package/dist/gateway/static/root/assets/extension-page-DW47KI82.js +1 -0
  44. package/dist/gateway/static/root/assets/extension-settings-page-B-W4x2xP.js +1 -0
  45. package/dist/gateway/static/root/assets/fetch-B2MYHbWg.js +1 -0
  46. package/dist/gateway/static/root/assets/{field-primitives-DTtlp-l8.js → field-primitives-DPG-oJmx.js} +1 -1
  47. package/dist/gateway/static/root/assets/heartbeat-config-api-C8dNts9i.js +1 -0
  48. package/dist/gateway/static/root/assets/index-BmVYculr.js +4700 -0
  49. package/dist/gateway/static/root/assets/index-ew_2L2We.css +1 -0
  50. package/dist/gateway/static/root/assets/logs-page-sTsVWz0X.js +1 -0
  51. package/dist/gateway/static/root/assets/sessions-page-FaG_Vlkb.js +1 -0
  52. package/dist/gateway/static/root/assets/settings-form-section-DuvRQW--.js +1 -0
  53. package/dist/gateway/static/root/assets/settings-page-Bet1OerL.js +3 -0
  54. package/dist/gateway/static/root/assets/share-preview-page-BtG2kLDh.js +2 -0
  55. package/dist/gateway/static/root/assets/skills-page-DhUO235y.js +2 -0
  56. package/dist/gateway/static/root/assets/theme-store-DryYl3qD.js +1 -0
  57. package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +3 -0
  58. package/dist/gateway/static/root/assets/utils-BY7bU1DT.js +1 -0
  59. package/dist/gateway/static/root/assets/voice-api-key-field-CGEydndO.js +1 -0
  60. package/dist/gateway/static/root/index.html +7 -6
  61. package/dist/package.js +1 -1
  62. package/dist/src/agent/agent-manager.js +7 -7
  63. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  64. package/dist/src/agent/context/workspace-seed.js +3 -3
  65. package/dist/src/agent/embedded/map-stream-events.js +6 -0
  66. package/dist/src/agent/embedded/map-stream-events.js.map +1 -1
  67. package/dist/src/agent/embedded/subscribe-session.js +24 -0
  68. package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
  69. package/dist/src/agent/embedded/types.d.ts +19 -0
  70. package/dist/src/agent/goals/goal-locale.js +2 -2
  71. package/dist/src/agent/goals/goal-run-store.js +4 -4
  72. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  73. package/dist/src/agent/goals/post-turn.js +2 -2
  74. package/dist/src/agent/image/load-image-media.js +2 -2
  75. package/dist/src/agent/ipc/bus.js +1 -1
  76. package/dist/src/agent/ipc/inbox.js +2 -2
  77. package/dist/src/agent/ipc/socket.js +1 -1
  78. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  79. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  80. package/dist/src/agent/memory/dreaming/events.js +1 -1
  81. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  82. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  83. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  84. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  85. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  86. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  87. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  88. package/dist/src/agent/models/manager.js +1 -1
  89. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  90. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  91. package/dist/src/agent/reply/startup-context.d.ts +3 -0
  92. package/dist/src/agent/reply/startup-context.js +25 -2
  93. package/dist/src/agent/reply/startup-context.js.map +1 -1
  94. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  95. package/dist/src/agent/sandbox/path-policy.js +2 -2
  96. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  97. package/dist/src/agent/service.d.ts +1 -0
  98. package/dist/src/agent/service.js +10 -4
  99. package/dist/src/agent/service.js.map +1 -1
  100. package/dist/src/agent/session/session-inspector.js +1 -1
  101. package/dist/src/agent/skills/config.js +1 -1
  102. package/dist/src/agent/skills/hub-hash.js +2 -2
  103. package/dist/src/agent/skills/hub-lock.js +1 -1
  104. package/dist/src/agent/skills/hub-pull.js +3 -3
  105. package/dist/src/agent/skills/index.js +1 -1
  106. package/dist/src/agent/skills/managed-store.js +1 -1
  107. package/dist/src/agent/skills/scanner.js +1 -1
  108. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  109. package/dist/src/agent/skills/skill-manager.js +1 -1
  110. package/dist/src/agent/tools/create-share-tool.d.ts +27 -0
  111. package/dist/src/agent/tools/create-share-tool.js +237 -0
  112. package/dist/src/agent/tools/create-share-tool.js.map +1 -0
  113. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  114. package/dist/src/agent/tools/factory.js +35 -1
  115. package/dist/src/agent/tools/factory.js.map +1 -1
  116. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  117. package/dist/src/agent/tools/index.d.ts +2 -0
  118. package/dist/src/agent/tools/index.js +3 -1
  119. package/dist/src/agent/tools/send-media.js +1 -1
  120. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  121. package/dist/src/agent/tools/workflow-tool.d.ts +41 -0
  122. package/dist/src/agent/tools/workflow-tool.js +271 -0
  123. package/dist/src/agent/tools/workflow-tool.js.map +1 -0
  124. package/dist/src/agent/tools/write.js +1 -1
  125. package/dist/src/agent/workflow/builtins/audit-repo.d.ts +13 -0
  126. package/dist/src/agent/workflow/builtins/audit-repo.js +156 -0
  127. package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -0
  128. package/dist/src/agent/workflow/builtins/debug-incident.d.ts +13 -0
  129. package/dist/src/agent/workflow/builtins/debug-incident.js +155 -0
  130. package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -0
  131. package/dist/src/agent/workflow/builtins/index.d.ts +17 -0
  132. package/dist/src/agent/workflow/builtins/index.js +38 -0
  133. package/dist/src/agent/workflow/builtins/index.js.map +1 -0
  134. package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +14 -0
  135. package/dist/src/agent/workflow/builtins/multi-perspective-review.js +149 -0
  136. package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -0
  137. package/dist/src/agent/workflow/builtins/pr-review.d.ts +12 -0
  138. package/dist/src/agent/workflow/builtins/pr-review.js +156 -0
  139. package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -0
  140. package/dist/src/agent/workflow/builtins/research.d.ts +13 -0
  141. package/dist/src/agent/workflow/builtins/research.js +160 -0
  142. package/dist/src/agent/workflow/builtins/research.js.map +1 -0
  143. package/dist/src/agent/workflow/catalog.d.ts +56 -0
  144. package/dist/src/agent/workflow/catalog.js +159 -0
  145. package/dist/src/agent/workflow/catalog.js.map +1 -0
  146. package/dist/src/agent/workflow/channel-capability.d.ts +76 -0
  147. package/dist/src/agent/workflow/channel-capability.js +1 -0
  148. package/dist/src/agent/workflow/index.d.ts +11 -0
  149. package/dist/src/agent/workflow/index.js +10 -0
  150. package/dist/src/agent/workflow/last-run-memory.d.ts +42 -0
  151. package/dist/src/agent/workflow/last-run-memory.js +60 -0
  152. package/dist/src/agent/workflow/last-run-memory.js.map +1 -0
  153. package/dist/src/agent/workflow/parser.d.ts +20 -0
  154. package/dist/src/agent/workflow/parser.js +146 -0
  155. package/dist/src/agent/workflow/parser.js.map +1 -0
  156. package/dist/src/agent/workflow/progress-broker.d.ts +80 -0
  157. package/dist/src/agent/workflow/progress-broker.js +263 -0
  158. package/dist/src/agent/workflow/progress-broker.js.map +1 -0
  159. package/dist/src/agent/workflow/runtime.d.ts +31 -0
  160. package/dist/src/agent/workflow/runtime.js +301 -0
  161. package/dist/src/agent/workflow/runtime.js.map +1 -0
  162. package/dist/src/agent/workflow/snapshot.d.ts +18 -0
  163. package/dist/src/agent/workflow/snapshot.js +144 -0
  164. package/dist/src/agent/workflow/snapshot.js.map +1 -0
  165. package/dist/src/agent/workflow/structured-output-tool.d.ts +33 -0
  166. package/dist/src/agent/workflow/structured-output-tool.js +58 -0
  167. package/dist/src/agent/workflow/structured-output-tool.js.map +1 -0
  168. package/dist/src/agent/workflow/subagent-runner.d.ts +42 -0
  169. package/dist/src/agent/workflow/subagent-runner.js +104 -0
  170. package/dist/src/agent/workflow/subagent-runner.js.map +1 -0
  171. package/dist/src/agent/workflow/types.d.ts +145 -0
  172. package/dist/src/agent/workflow/types.js +1 -0
  173. package/dist/src/auth/credentials.js +3 -3
  174. package/dist/src/auth/profiles/store.js +1 -1
  175. package/dist/src/auth/sync-provider-auth.js +1 -1
  176. package/dist/src/browser/cache-dir-policy.js +1 -1
  177. package/dist/src/browser/cdp-local-launcher.js +2 -2
  178. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  179. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  180. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  181. package/dist/src/browser/stealth.js +1 -1
  182. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  183. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  184. package/dist/src/channels/outbound/persist-store.js +1 -1
  185. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  186. package/dist/src/channels/pairing/pairing-store.js +2 -2
  187. package/dist/src/chat-commands/builtins/config.js +2 -2
  188. package/dist/src/chat-commands/builtins/model.js +40 -23
  189. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  190. package/dist/src/chat-commands/builtins/system.js +30 -15
  191. package/dist/src/chat-commands/builtins/system.js.map +1 -1
  192. package/dist/src/chat-commands/builtins/workflow.d.ts +18 -0
  193. package/dist/src/chat-commands/builtins/workflow.js +172 -0
  194. package/dist/src/chat-commands/builtins/workflow.js.map +1 -0
  195. package/dist/src/chat-commands/context.js +1 -1
  196. package/dist/src/chat-commands/format-output.d.ts +28 -0
  197. package/dist/src/chat-commands/format-output.js +45 -0
  198. package/dist/src/chat-commands/format-output.js.map +1 -0
  199. package/dist/src/chat-commands/index.d.ts +1 -0
  200. package/dist/src/chat-commands/index.js +3 -1
  201. package/dist/src/chat-commands/index.js.map +1 -1
  202. package/dist/src/cli/commands/config.js +2 -2
  203. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  204. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  205. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  206. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  207. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  208. package/dist/src/cli/commands/extension-dev.js +1 -1
  209. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  210. package/dist/src/cli/commands/extension-pack.js +1 -1
  211. package/dist/src/cli/commands/gateway/lifecycle.js +10 -4
  212. package/dist/src/cli/commands/gateway/lifecycle.js.map +1 -1
  213. package/dist/src/cli/commands/gateway/shared.js +1 -1
  214. package/dist/src/cli/commands/image.js +1 -1
  215. package/dist/src/cli/commands/init.js +4 -4
  216. package/dist/src/cli/commands/onboard.js +2 -2
  217. package/dist/src/cli/commands/tunnel.js +2 -2
  218. package/dist/src/cli/utils/gateway-client.js +1 -1
  219. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  220. package/dist/src/config/agent-profile.js +1 -1
  221. package/dist/src/config/gateway-bind.js +1 -1
  222. package/dist/src/config/index.js +5 -5
  223. package/dist/src/config/loader.js +2 -2
  224. package/dist/src/config/models-json.js +2 -2
  225. package/dist/src/config/paths-state.js +1 -1
  226. package/dist/src/config/profile.js +2 -2
  227. package/dist/src/config/public-url.d.ts +28 -0
  228. package/dist/src/config/public-url.js +103 -0
  229. package/dist/src/config/public-url.js.map +1 -0
  230. package/dist/src/config/schema.d.ts +82 -0
  231. package/dist/src/config/schema.js +130 -1
  232. package/dist/src/config/schema.js.map +1 -1
  233. package/dist/src/config/workspace-path.js +1 -1
  234. package/dist/src/cron/executor.js +2 -2
  235. package/dist/src/cron/persistence.js +1 -1
  236. package/dist/src/cron/run-log-store.js +1 -1
  237. package/dist/src/daemon/constants.js +1 -1
  238. package/dist/src/daemon/install-plan.js +3 -3
  239. package/dist/src/daemon/install-plan.js.map +1 -1
  240. package/dist/src/daemon/launchd.js +2 -2
  241. package/dist/src/daemon/schtasks.js +38 -1
  242. package/dist/src/daemon/schtasks.js.map +1 -1
  243. package/dist/src/daemon/systemd.js +2 -2
  244. package/dist/src/extensions/bundle-mcp.js +1 -1
  245. package/dist/src/extensions/discover-extensions.js +1 -1
  246. package/dist/src/extensions/health.js +1 -1
  247. package/dist/src/extensions/loader.js +1 -1
  248. package/dist/src/extensions/lockfile.js +2 -2
  249. package/dist/src/gateway/agents-admin.js +2 -2
  250. package/dist/src/gateway/file-path-classifier.js +2 -2
  251. package/dist/src/gateway/heartbeat/service.js +1 -1
  252. package/dist/src/gateway/hono/app.js +33 -2
  253. package/dist/src/gateway/hono/app.js.map +1 -1
  254. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  255. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  256. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  257. package/dist/src/gateway/hono/oauth.js +1 -1
  258. package/dist/src/gateway/hono/routes/agents.js +1 -1
  259. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  260. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  261. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  262. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  263. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  264. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  265. package/dist/src/gateway/hono/routes/models.js +1 -1
  266. package/dist/src/gateway/hono/routes/shares.js +631 -34
  267. package/dist/src/gateway/hono/routes/shares.js.map +1 -1
  268. package/dist/src/gateway/hono/routes/site-shares.d.ts +3 -0
  269. package/dist/src/gateway/hono/routes/site-shares.js +228 -0
  270. package/dist/src/gateway/hono/routes/site-shares.js.map +1 -0
  271. package/dist/src/gateway/hono/routes/tunnel.js +97 -8
  272. package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
  273. package/dist/src/gateway/hono/routes/workspace.js +5 -5
  274. package/dist/src/gateway/hono/sse.js +2 -2
  275. package/dist/src/gateway/host.d.ts +3 -1
  276. package/dist/src/gateway/host.js +3 -1
  277. package/dist/src/gateway/host.js.map +1 -1
  278. package/dist/src/gateway/lock.js +3 -3
  279. package/dist/src/gateway/ports.d.ts +6 -0
  280. package/dist/src/gateway/ports.js +38 -2
  281. package/dist/src/gateway/ports.js.map +1 -1
  282. package/dist/src/gateway/public-url.d.ts +8 -0
  283. package/dist/src/gateway/public-url.js +10 -0
  284. package/dist/src/gateway/public-url.js.map +1 -0
  285. package/dist/src/gateway/security/origin-check.d.ts +9 -1
  286. package/dist/src/gateway/security/origin-check.js +4 -0
  287. package/dist/src/gateway/security/origin-check.js.map +1 -1
  288. package/dist/src/gateway/server.js +15 -0
  289. package/dist/src/gateway/server.js.map +1 -1
  290. package/dist/src/gateway/service/agent-runner.js +2 -2
  291. package/dist/src/gateway/service/marketplace-service.js +2 -2
  292. package/dist/src/gateway/service/run-gateway-agent.js +2 -2
  293. package/dist/src/gateway/service.js +3 -2
  294. package/dist/src/gateway/service.js.map +1 -1
  295. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  296. package/dist/src/heartbeat/index.js +1 -1
  297. package/dist/src/i18n/goals-bundle.js +1 -1
  298. package/dist/src/i18n/index.d.ts +1 -0
  299. package/dist/src/i18n/index.js +2 -1
  300. package/dist/src/i18n/locales/share-tool.en.js +15 -0
  301. package/dist/src/i18n/locales/share-tool.en.js.map +1 -0
  302. package/dist/src/i18n/locales/share-tool.zh.js +15 -0
  303. package/dist/src/i18n/locales/share-tool.zh.js.map +1 -0
  304. package/dist/src/i18n/share-tool-bundle.d.ts +20 -0
  305. package/dist/src/i18n/share-tool-bundle.js +56 -0
  306. package/dist/src/i18n/share-tool-bundle.js.map +1 -0
  307. package/dist/src/infra/gateway-processes.js +1 -0
  308. package/dist/src/infra/gateway-processes.js.map +1 -1
  309. package/dist/src/infra/restart.js +2 -2
  310. package/dist/src/infra/update-check.js +1 -1
  311. package/dist/src/infra/update-lock.js +3 -3
  312. package/dist/src/infra/update-runner.js +1 -1
  313. package/dist/src/infra/update-startup.js +2 -2
  314. package/dist/src/infra/write-file-atomic.js +2 -2
  315. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  316. package/dist/src/providers/index.js +2 -2
  317. package/dist/src/providers/model-registry.js +1 -1
  318. package/dist/src/session/config-store.js +2 -2
  319. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  320. package/dist/src/session/parity/sessions-json-file.js +1 -1
  321. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  322. package/dist/src/session/parity/transcript-paths.js +1 -1
  323. package/dist/src/session/search-index-cache.js +1 -1
  324. package/dist/src/session/search-index.js +1 -1
  325. package/dist/src/session/session-title.js +3 -2
  326. package/dist/src/session/session-title.js.map +1 -1
  327. package/dist/src/session/store.js +5 -5
  328. package/dist/src/share/share-auto.d.ts +74 -0
  329. package/dist/src/share/share-auto.js +247 -0
  330. package/dist/src/share/share-auto.js.map +1 -0
  331. package/dist/src/share/share-config.js +63 -4
  332. package/dist/src/share/share-config.js.map +1 -1
  333. package/dist/src/share/share-landing.d.ts +28 -2
  334. package/dist/src/share/share-landing.js +155 -34
  335. package/dist/src/share/share-landing.js.map +1 -1
  336. package/dist/src/share/share-store.d.ts +48 -4
  337. package/dist/src/share/share-store.js +322 -51
  338. package/dist/src/share/share-store.js.map +1 -1
  339. package/dist/src/share/share-thumbnail.d.ts +35 -0
  340. package/dist/src/share/share-thumbnail.js +277 -0
  341. package/dist/src/share/share-thumbnail.js.map +1 -0
  342. package/dist/src/share/share-types.d.ts +68 -10
  343. package/dist/src/share/share-types.js +18 -1
  344. package/dist/src/share/share-types.js.map +1 -1
  345. package/dist/src/share/share-url.js +1 -1
  346. package/dist/src/share/share-zip.d.ts +35 -0
  347. package/dist/src/share/share-zip.js +303 -0
  348. package/dist/src/share/share-zip.js.map +1 -0
  349. package/dist/src/share/site-proxy.d.ts +35 -0
  350. package/dist/src/share/site-proxy.js +234 -0
  351. package/dist/src/share/site-proxy.js.map +1 -0
  352. package/dist/src/share/site-share-config.d.ts +11 -0
  353. package/dist/src/share/site-share-config.js +103 -0
  354. package/dist/src/share/site-share-config.js.map +1 -0
  355. package/dist/src/share/site-share-router.d.ts +23 -0
  356. package/dist/src/share/site-share-router.js +147 -0
  357. package/dist/src/share/site-share-router.js.map +1 -0
  358. package/dist/src/share/site-share-store.d.ts +53 -0
  359. package/dist/src/share/site-share-store.js +400 -0
  360. package/dist/src/share/site-share-store.js.map +1 -0
  361. package/dist/src/share/site-share-types.d.ts +103 -0
  362. package/dist/src/share/site-share-types.js +41 -0
  363. package/dist/src/share/site-share-types.js.map +1 -0
  364. package/dist/src/share/site-static-serve.d.ts +10 -0
  365. package/dist/src/share/site-static-serve.js +145 -0
  366. package/dist/src/share/site-static-serve.js.map +1 -0
  367. package/dist/src/tui/clipboard-image.js +3 -3
  368. package/dist/src/tui/theme-manager.js +1 -1
  369. package/dist/src/tui/tui-commands.js +18 -0
  370. package/dist/src/tui/tui-commands.js.map +1 -1
  371. package/dist/src/tui/tui-keybindings-file.js +1 -1
  372. package/dist/src/tui/tui-scoped-models.js +2 -2
  373. package/dist/src/tui/tui-settings.js +1 -1
  374. package/dist/src/tui/tui-workflow-slash.d.ts +32 -0
  375. package/dist/src/tui/tui-workflow-slash.js +63 -0
  376. package/dist/src/tui/tui-workflow-slash.js.map +1 -0
  377. package/dist/src/tui/tui.js +2 -2
  378. package/dist/src/tunnel/enable-lan-pairing.js +1 -1
  379. package/dist/src/tunnel/frpc-binary.js +3 -3
  380. package/dist/src/tunnel/frpc-config.js +1 -1
  381. package/dist/src/tunnel/frpc-extract.js +1 -1
  382. package/dist/src/tunnel/index.js +2 -2
  383. package/dist/src/tunnel/pair-context.d.ts +7 -1
  384. package/dist/src/tunnel/pair-context.js +25 -9
  385. package/dist/src/tunnel/pair-context.js.map +1 -1
  386. package/dist/src/tunnel/pair-url.d.ts +14 -1
  387. package/dist/src/tunnel/pair-url.js +14 -1
  388. package/dist/src/tunnel/pair-url.js.map +1 -1
  389. package/dist/src/tunnel/tunnel-service.js +2 -2
  390. package/dist/src/tunnel/tunnel-state.js +1 -1
  391. package/dist/src/utils/logger/audit.js +1 -1
  392. package/dist/src/utils/logger/log-store.js +1 -1
  393. package/dist/src/utils/logger/rotation.js +1 -1
  394. package/dist/src/voice/tts/audio.js +1 -1
  395. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  396. package/package.json +3 -2
  397. package/dist/gateway/static/root/assets/agents-tR-nNP04.js +0 -222
  398. package/dist/gateway/static/root/assets/apps-page-BDw6SP-d.js +0 -1
  399. package/dist/gateway/static/root/assets/button-KafIU8dx.js +0 -1
  400. package/dist/gateway/static/root/assets/channels-settings-DEFd-jj1.js +0 -1
  401. package/dist/gateway/static/root/assets/channels-status-swr-DI5FHdGe.js +0 -8
  402. package/dist/gateway/static/root/assets/cron-api-BSqY8LwW.js +0 -1
  403. package/dist/gateway/static/root/assets/cron-page-D7lVDjcR.js +0 -1
  404. package/dist/gateway/static/root/assets/dist-C57OMHW8.js +0 -48
  405. package/dist/gateway/static/root/assets/extension-page-CQo2Xsmg.js +0 -1
  406. package/dist/gateway/static/root/assets/extension-settings-page-CZf0WoZg.js +0 -1
  407. package/dist/gateway/static/root/assets/fetch-2iRFmd3n.js +0 -3
  408. package/dist/gateway/static/root/assets/heartbeat-config-api-B0drdQEJ.js +0 -1
  409. package/dist/gateway/static/root/assets/index-0Gt3TG4j.js +0 -4693
  410. package/dist/gateway/static/root/assets/index-BuFldCsB.css +0 -1
  411. package/dist/gateway/static/root/assets/logs-page-DMuORLfC.js +0 -1
  412. package/dist/gateway/static/root/assets/sessions-page-_UO8g6NN.js +0 -1
  413. package/dist/gateway/static/root/assets/settings-form-section-DkmHkknc.js +0 -1
  414. package/dist/gateway/static/root/assets/settings-page-Cz8FoW_A.js +0 -3
  415. package/dist/gateway/static/root/assets/skills-page-HrUOxF7H.js +0 -2
  416. package/dist/gateway/static/root/assets/theme-store-D01dJt95.js +0 -1
  417. package/dist/gateway/static/root/assets/utils-BFwcR6pL.js +0 -1
  418. package/dist/gateway/static/root/assets/voice-api-key-field-JF8-aqc5.js +0 -1
@@ -0,0 +1,237 @@
1
+ import { resolvePathUnderWorkspace } from "./tool-paths.js";
2
+ import { resolveGatewayEffectiveHost } from "../../config/gateway-bind.js";
3
+ import { resolveShareConfig } from "../../share/share-config.js";
4
+ import { mergeWithDefaults } from "../../share/site-share-config.js";
5
+ import { getShareStore } from "../../share/share-store.js";
6
+ import { getSiteShareStore } from "../../share/site-share-store.js";
7
+ import { loadTunnelState } from "../../tunnel/tunnel-state.js";
8
+ import { resolveShareUrl } from "../../share/share-url.js";
9
+ import { audienceDefaults, decideShareKind, makeDescription, makeTitle, probeShareTarget, rememberStagedSite, stageSingleHtmlAsSite } from "../../share/share-auto.js";
10
+ import { scheduleThumbnail } from "../../share/share-thumbnail.js";
11
+ import { resolveToolLocale, shareToolErrorLine, shareToolSuccessLines } from "../../i18n/share-tool-bundle.js";
12
+ import { createHash } from "node:crypto";
13
+ import { Type } from "@sinclair/typebox";
14
+ //#region src/agent/tools/create-share-tool.ts
15
+ /**
16
+ * Agent tool: create_share
17
+ *
18
+ * Hands a generated artefact (file, folder, HTML site) to the share-auto
19
+ * pipeline and returns a public URL the model can paste into its reply.
20
+ *
21
+ * This is the bridge between "agent produces files" and "user has something
22
+ * to share with a friend on WeChat (or anywhere)" — the model itself decides
23
+ * when to call it, with optional hints about audience.
24
+ */
25
+ const CreateShareSchema = Type.Object({
26
+ filePath: Type.String({ description: "File or folder to share. Relative paths resolve under the agent workspace; absolute paths are used as given (must be inside the workspace)." }),
27
+ audience: Type.Optional(Type.Enum({
28
+ friend: "friend",
29
+ colleague: "colleague",
30
+ public: "public"
31
+ }, { description: "Who the recipient is — controls default TTL/view caps. friend=3d unlimited, colleague=7d unlimited, public=24h capped at 100 views. Default: friend." })),
32
+ title: Type.Optional(Type.String({ description: "Override title shown on the social card. Default: file basename without extension." })),
33
+ description: Type.Optional(Type.String({ description: "Optional 1-line description for the social card." })),
34
+ mode: Type.Optional(Type.Enum({
35
+ auto: "auto",
36
+ "force-file": "force-file",
37
+ "force-site": "force-site",
38
+ "force-zip": "force-zip"
39
+ }, { description: "Override routing. Default 'auto'. Use 'force-site' to publish a single HTML as a hosted page." }))
40
+ });
41
+ /**
42
+ * Whether the create_share tool is worth registering. Returns false when:
43
+ * - no gateway config is present (sharing routes wouldn't be reachable anyway), or
44
+ * - BOTH file sharing (`gateway.share.enabled`) and site sharing
45
+ * (`gateway.siteShare.enabled`) are explicitly disabled.
46
+ *
47
+ * Reachability (`tunnel up?`) is intentionally NOT checked here — it is
48
+ * runtime state, the tool surfaces it via the `reachability` field, and the
49
+ * agent should still be able to create local-only shares when the user is
50
+ * testing or on the same network.
51
+ */
52
+ function isShareToolAvailable(cfg) {
53
+ if (!cfg || !cfg.gateway) return false;
54
+ const gw = cfg.gateway;
55
+ const fileEnabled = gw.share?.enabled !== false;
56
+ const siteEnabled = gw.siteShare?.enabled !== false;
57
+ return fileEnabled || siteEnabled;
58
+ }
59
+ function gatewayPortOf(cfg) {
60
+ return cfg?.gateway?.port ?? 18790;
61
+ }
62
+ function hashCreator(value) {
63
+ return createHash("sha256").update(value, "utf8").digest("hex").slice(0, 12);
64
+ }
65
+ function createCreateShareTool(deps) {
66
+ const { workspace, getConfig } = deps;
67
+ return {
68
+ name: "create_share",
69
+ description: "Create a public share link for a file or folder so it can be sent to a friend (e.g. via WeChat). Returns shareUrl + thumbnailUrl + expiry. HTML files are published as live pages (the recipient sees a rendered page, not a download).",
70
+ parameters: CreateShareSchema,
71
+ label: "🔗 Create Share",
72
+ async execute(_toolCallId, params, _signal) {
73
+ const p = params;
74
+ const audience = p.audience ?? "friend";
75
+ const mode = p.mode ?? "auto";
76
+ const locale = resolveToolLocale(deps.getLocale?.());
77
+ const cfg = getConfig();
78
+ const shareCfg = resolveShareConfig((cfg?.gateway)?.share);
79
+ const siteCfg = mergeWithDefaults((cfg?.gateway)?.siteShare);
80
+ const gatewayHost = cfg ? resolveGatewayEffectiveHost(cfg) : "127.0.0.1";
81
+ const gatewayPort = gatewayPortOf(cfg);
82
+ const tokenHash = hashCreator(deps.getAgentId?.() ?? "agent-tool");
83
+ const absolutePath = resolvePathUnderWorkspace(p.filePath, workspace);
84
+ if (!absolutePath.startsWith(workspace)) return errorResult(locale, "File must be inside the agent workspace.");
85
+ const relPath = absolutePath === workspace ? "" : absolutePath.slice(workspace.length).replace(/^[\\/]+/, "").replace(/\\/g, "/");
86
+ if (!relPath) return errorResult(locale, "Cannot share the workspace root itself.");
87
+ let probe;
88
+ try {
89
+ probe = await probeShareTarget(workspace, relPath);
90
+ } catch (err) {
91
+ return errorResult(locale, `Cannot read target: ${err instanceof Error ? err.message : String(err)}`);
92
+ }
93
+ let decision;
94
+ try {
95
+ decision = decideShareKind(probe, mode);
96
+ } catch (err) {
97
+ return errorResult(locale, err instanceof Error ? err.message : String(err));
98
+ }
99
+ const defaults = audienceDefaults(audience);
100
+ const ttlMs = defaults.ttlMs;
101
+ const maxViews = defaults.maxViews;
102
+ try {
103
+ const tunnelUp = !!loadTunnelState();
104
+ if (decision.kind === "site") {
105
+ const siteStore = getSiteShareStore(siteCfg);
106
+ let sitePath = relPath;
107
+ let stagedDir = null;
108
+ if (probe.kind === "file") {
109
+ const staged = await stageSingleHtmlAsSite(workspace, probe.absolutePath);
110
+ sitePath = staged.relativePath;
111
+ stagedDir = staged.stagingDir;
112
+ }
113
+ const siteRec = await siteStore.create({
114
+ kind: "static",
115
+ path: sitePath,
116
+ ttlMs,
117
+ description: p.description,
118
+ spaFallback: true,
119
+ rewriteMode: "html-css",
120
+ workspaceRoot: workspace,
121
+ gatewayTokenHash: tokenHash
122
+ });
123
+ if (stagedDir) rememberStagedSite(siteRec.id, stagedDir);
124
+ const label = siteRec.subdomain ?? siteRec.token;
125
+ const shareUrl = tunnelUp ? `https://${label}.${siteCfg.publicHostSuffix}/` : `http://${gatewayHost}:${gatewayPort}/site/${siteRec.token}/`;
126
+ const reachability = tunnelUp ? "public" : gatewayHost === "127.0.0.1" || gatewayHost === "localhost" || gatewayHost === "::1" ? "local-only" : "lan";
127
+ const thumbnailUrl = `${shareUrl.replace(/\/+$/, "")}/thumbnail`;
128
+ scheduleThumbnail({
129
+ scope: "site",
130
+ token: siteRec.token,
131
+ recordId: siteRec.id
132
+ }, {
133
+ config: shareCfg.thumbnail,
134
+ internalBaseUrl: shareCfg.thumbnail.internalGatewayUrl ?? `http://127.0.0.1:${gatewayPort}`
135
+ });
136
+ siteStore.setThumbnailStatus(siteRec.id, "pending");
137
+ return successResult(locale, {
138
+ kind: "site",
139
+ shareUrl,
140
+ thumbnailUrl,
141
+ reachability,
142
+ title: makeTitle(probe.kind === "directory" ? relPath.split("/").pop() || relPath : probe.absolutePath.split(/[\\/]/).pop() || relPath, p.title),
143
+ description: makeDescription({
144
+ audience,
145
+ expiresAt: siteRec.expiresAt,
146
+ override: p.description
147
+ }),
148
+ expiresAt: siteRec.expiresAt,
149
+ routing: {
150
+ reason: decision.reason,
151
+ hint: decision.hint
152
+ }
153
+ });
154
+ }
155
+ const fileStore = getShareStore(shareCfg);
156
+ const rec = await fileStore.create({
157
+ path: relPath,
158
+ workspaceRoot: workspace,
159
+ gatewayTokenHash: tokenHash,
160
+ ttlMs,
161
+ maxViews: maxViews === void 0 ? void 0 : maxViews,
162
+ description: p.description,
163
+ kind: probe.kind === "directory" ? "directory" : "file",
164
+ directoryMode: decision.kind === "zip" ? "zip-only" : probe.kind === "directory" ? "browse" : void 0
165
+ });
166
+ const resolved = resolveShareUrl(rec.token, {
167
+ gatewayHost,
168
+ gatewayPort
169
+ });
170
+ const thumbnailUrl = `${resolved.shareUrl}/thumbnail`;
171
+ scheduleThumbnail({
172
+ scope: "file",
173
+ token: rec.token,
174
+ recordId: rec.id
175
+ }, {
176
+ config: shareCfg.thumbnail,
177
+ internalBaseUrl: shareCfg.thumbnail.internalGatewayUrl ?? `http://127.0.0.1:${gatewayPort}`
178
+ });
179
+ fileStore.setThumbnailStatus(rec.id, "pending");
180
+ const titleOut = makeTitle(rec.fileName, p.title);
181
+ const descOut = makeDescription({
182
+ audience,
183
+ expiresAt: rec.expiresAt,
184
+ override: p.description
185
+ });
186
+ return successResult(locale, {
187
+ kind: decision.kind,
188
+ shareUrl: resolved.shareUrl,
189
+ thumbnailUrl,
190
+ reachability: resolved.reachability,
191
+ reachabilityHint: resolved.reachabilityHint,
192
+ title: titleOut,
193
+ description: descOut,
194
+ expiresAt: rec.expiresAt,
195
+ maxViews: rec.maxViews,
196
+ routing: {
197
+ reason: decision.reason,
198
+ hint: decision.hint
199
+ }
200
+ });
201
+ } catch (err) {
202
+ return errorResult(locale, err instanceof Error ? err.message : String(err));
203
+ }
204
+ }
205
+ };
206
+ }
207
+ function successResult(locale, payload) {
208
+ return {
209
+ content: [{
210
+ type: "text",
211
+ text: shareToolSuccessLines(locale, {
212
+ kind: String(payload.kind ?? ""),
213
+ shareUrl: String(payload.shareUrl ?? ""),
214
+ title: String(payload.title ?? ""),
215
+ expiresAt: String(payload.expiresAt ?? ""),
216
+ thumbnailUrl: String(payload.thumbnailUrl ?? ""),
217
+ reachability: String(payload.reachability ?? ""),
218
+ reachabilityHint: String(payload.reachabilityHint ?? ""),
219
+ isPublic: payload.reachability === "public"
220
+ }).filter(Boolean).join("\n")
221
+ }],
222
+ details: payload
223
+ };
224
+ }
225
+ function errorResult(locale, message) {
226
+ return {
227
+ content: [{
228
+ type: "text",
229
+ text: shareToolErrorLine(locale, message)
230
+ }],
231
+ details: { error: message }
232
+ };
233
+ }
234
+ //#endregion
235
+ export { createCreateShareTool, isShareToolAvailable };
236
+
237
+ //# sourceMappingURL=create-share-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-share-tool.js","names":["resolveSiteShareConfigFromRaw"],"sources":["../../../../src/agent/tools/create-share-tool.ts"],"sourcesContent":["/**\n * Agent tool: create_share\n *\n * Hands a generated artefact (file, folder, HTML site) to the share-auto\n * pipeline and returns a public URL the model can paste into its reply.\n *\n * This is the bridge between \"agent produces files\" and \"user has something\n * to share with a friend on WeChat (or anywhere)\" — the model itself decides\n * when to call it, with optional hints about audience.\n */\nimport { Type } from '@sinclair/typebox';\nimport { createHash } from 'node:crypto';\nimport { AgentTool, type AgentToolResult } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport { resolveGatewayEffectiveHost } from '../../config/gateway-bind.js';\nimport { resolveShareConfig } from '../../share/share-config.js';\nimport { mergeWithDefaults as resolveSiteShareConfigFromRaw } from '../../share/site-share-config.js';\nimport { getShareStore } from '../../share/share-store.js';\nimport { getSiteShareStore } from '../../share/site-share-store.js';\nimport { resolveShareUrl } from '../../share/share-url.js';\nimport { loadTunnelState } from '../../tunnel/tunnel-state.js';\nimport {\n audienceDefaults,\n decideShareKind,\n makeDescription,\n makeTitle,\n probeShareTarget,\n rememberStagedSite,\n stageSingleHtmlAsSite,\n type ShareAudience,\n type ShareAutoMode,\n} from '../../share/share-auto.js';\nimport { scheduleThumbnail } from '../../share/share-thumbnail.js';\nimport {\n resolveToolLocale,\n shareToolErrorLine,\n shareToolSuccessLines,\n} from '../../i18n/share-tool-bundle.js';\nimport { resolvePathUnderWorkspace } from './tool-paths.js';\n\nconst CreateShareSchema = Type.Object({\n filePath: Type.String({\n description:\n 'File or folder to share. Relative paths resolve under the agent workspace; absolute paths are used as given (must be inside the workspace).',\n }),\n audience: Type.Optional(Type.Enum(\n { friend: 'friend', colleague: 'colleague', public: 'public' },\n {\n description:\n 'Who the recipient is — controls default TTL/view caps. friend=3d unlimited, colleague=7d unlimited, public=24h capped at 100 views. Default: friend.',\n },\n )),\n title: Type.Optional(Type.String({ description: 'Override title shown on the social card. Default: file basename without extension.' })),\n description: Type.Optional(Type.String({ description: 'Optional 1-line description for the social card.' })),\n mode: Type.Optional(Type.Enum(\n { auto: 'auto', 'force-file': 'force-file', 'force-site': 'force-site', 'force-zip': 'force-zip' },\n { description: \"Override routing. Default 'auto'. Use 'force-site' to publish a single HTML as a hosted page.\" },\n )),\n});\n\ntype CreateShareParams = {\n filePath: string;\n audience?: ShareAudience;\n title?: string;\n description?: string;\n mode?: ShareAutoMode;\n};\n\nexport interface CreateShareToolDeps {\n workspace: string;\n getConfig: () => Config | undefined;\n /** Optional agent id for workspace resolution audit (currently unused but kept for parity with /api/shares). */\n getAgentId?: () => string | undefined;\n /**\n * Optional user-facing locale ('en' / 'zh' / etc.). Falls back to env LANG\n * → DEFAULT_SERVER_LOCALE when unset. Returned text follows this locale;\n * the structured `details` payload stays language-neutral.\n */\n getLocale?: () => string | undefined;\n}\n\n/**\n * Whether the create_share tool is worth registering. Returns false when:\n * - no gateway config is present (sharing routes wouldn't be reachable anyway), or\n * - BOTH file sharing (`gateway.share.enabled`) and site sharing\n * (`gateway.siteShare.enabled`) are explicitly disabled.\n *\n * Reachability (`tunnel up?`) is intentionally NOT checked here — it is\n * runtime state, the tool surfaces it via the `reachability` field, and the\n * agent should still be able to create local-only shares when the user is\n * testing or on the same network.\n */\nexport function isShareToolAvailable(cfg: Config | undefined): boolean {\n if (!cfg || !cfg.gateway) return false;\n const gw = cfg.gateway as Record<string, unknown>;\n const fileEnabled = (gw.share as { enabled?: boolean } | undefined)?.enabled !== false;\n const siteEnabled = (gw.siteShare as { enabled?: boolean } | undefined)?.enabled !== false;\n return fileEnabled || siteEnabled;\n}\n\nfunction gatewayPortOf(cfg: Config | undefined): number {\n return cfg?.gateway?.port ?? 18790;\n}\n\nfunction hashCreator(value: string): string {\n return createHash('sha256').update(value, 'utf8').digest('hex').slice(0, 12);\n}\n\nexport function createCreateShareTool(deps: CreateShareToolDeps): AgentTool {\n const { workspace, getConfig } = deps;\n\n return {\n name: 'create_share',\n description:\n 'Create a public share link for a file or folder so it can be sent to a friend (e.g. via WeChat). Returns shareUrl + thumbnailUrl + expiry. HTML files are published as live pages (the recipient sees a rendered page, not a download).',\n parameters: CreateShareSchema,\n label: '🔗 Create Share',\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<Record<string, unknown>>> {\n const p = params as CreateShareParams;\n const audience: ShareAudience = p.audience ?? 'friend';\n const mode: ShareAutoMode = p.mode ?? 'auto';\n const locale = resolveToolLocale(deps.getLocale?.());\n\n const cfg = getConfig();\n const shareCfg = resolveShareConfig(\n (cfg?.gateway as Record<string, unknown> | undefined)?.share,\n );\n const siteCfg = resolveSiteShareConfigFromRaw(\n (cfg?.gateway as Record<string, unknown> | undefined)?.siteShare,\n );\n const gatewayHost = cfg ? resolveGatewayEffectiveHost(cfg) : '127.0.0.1';\n const gatewayPort = gatewayPortOf(cfg);\n const tokenHash = hashCreator(deps.getAgentId?.() ?? 'agent-tool');\n\n // Resolve absolute path + verify it sits under the workspace root.\n const absolutePath = resolvePathUnderWorkspace(p.filePath, workspace);\n if (!absolutePath.startsWith(workspace)) {\n return errorResult(locale,'File must be inside the agent workspace.');\n }\n const relPath = absolutePath === workspace\n ? ''\n : absolutePath.slice(workspace.length).replace(/^[\\\\/]+/, '').replace(/\\\\/g, '/');\n if (!relPath) {\n return errorResult(locale,'Cannot share the workspace root itself.');\n }\n\n let probe;\n try {\n probe = await probeShareTarget(workspace, relPath);\n } catch (err) {\n return errorResult(locale,`Cannot read target: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n let decision;\n try {\n decision = decideShareKind(probe, mode);\n } catch (err) {\n return errorResult(locale,err instanceof Error ? err.message : String(err));\n }\n\n const defaults = audienceDefaults(audience);\n const ttlMs = defaults.ttlMs;\n const maxViews = defaults.maxViews;\n\n try {\n const tunnelUp = !!loadTunnelState();\n if (decision.kind === 'site') {\n const siteStore = getSiteShareStore(siteCfg);\n let sitePath = relPath;\n let stagedDir: string | null = null;\n if (probe.kind === 'file') {\n const staged = await stageSingleHtmlAsSite(workspace, probe.absolutePath);\n sitePath = staged.relativePath;\n stagedDir = staged.stagingDir;\n }\n const siteRec = await siteStore.create({\n kind: 'static',\n path: sitePath,\n ttlMs,\n description: p.description,\n spaFallback: true,\n rewriteMode: 'html-css',\n workspaceRoot: workspace,\n gatewayTokenHash: tokenHash,\n });\n if (stagedDir) rememberStagedSite(siteRec.id, stagedDir);\n\n const label = siteRec.subdomain ?? siteRec.token;\n const shareUrl = tunnelUp\n ? `https://${label}.${siteCfg.publicHostSuffix}/`\n : `http://${gatewayHost}:${gatewayPort}/site/${siteRec.token}/`;\n const reachability = tunnelUp\n ? 'public'\n : (gatewayHost === '127.0.0.1' || gatewayHost === 'localhost' || gatewayHost === '::1' ? 'local-only' : 'lan');\n const thumbnailUrl = `${shareUrl.replace(/\\/+$/, '')}/thumbnail`;\n scheduleThumbnail(\n { scope: 'site', token: siteRec.token, recordId: siteRec.id },\n {\n config: shareCfg.thumbnail,\n internalBaseUrl: shareCfg.thumbnail.internalGatewayUrl ?? `http://127.0.0.1:${gatewayPort}`,\n },\n );\n siteStore.setThumbnailStatus(siteRec.id, 'pending');\n\n const titleOut = makeTitle(probe.kind === 'directory' ? (relPath.split('/').pop() || relPath) : (probe.absolutePath.split(/[\\\\/]/).pop() || relPath), p.title);\n const descOut = makeDescription({ audience, expiresAt: siteRec.expiresAt, override: p.description });\n\n return successResult(locale, {\n kind: 'site',\n shareUrl,\n thumbnailUrl,\n reachability,\n title: titleOut,\n description: descOut,\n expiresAt: siteRec.expiresAt,\n routing: { reason: decision.reason, hint: decision.hint },\n });\n }\n\n // file or zip — uses ShareStore\n const fileStore = getShareStore(shareCfg);\n const rec = await fileStore.create({\n path: relPath,\n workspaceRoot: workspace,\n gatewayTokenHash: tokenHash,\n ttlMs,\n maxViews: maxViews === undefined ? undefined : maxViews,\n description: p.description,\n kind: probe.kind === 'directory' ? 'directory' : 'file',\n directoryMode: decision.kind === 'zip' ? 'zip-only' : (probe.kind === 'directory' ? 'browse' : undefined),\n });\n const resolved = resolveShareUrl(rec.token, { gatewayHost, gatewayPort });\n const thumbnailUrl = `${resolved.shareUrl}/thumbnail`;\n scheduleThumbnail(\n { scope: 'file', token: rec.token, recordId: rec.id },\n {\n config: shareCfg.thumbnail,\n internalBaseUrl: shareCfg.thumbnail.internalGatewayUrl ?? `http://127.0.0.1:${gatewayPort}`,\n },\n );\n fileStore.setThumbnailStatus(rec.id, 'pending');\n const titleOut = makeTitle(rec.fileName, p.title);\n const descOut = makeDescription({ audience, expiresAt: rec.expiresAt, override: p.description });\n\n return successResult(locale, {\n kind: decision.kind,\n shareUrl: resolved.shareUrl,\n thumbnailUrl,\n reachability: resolved.reachability,\n reachabilityHint: resolved.reachabilityHint,\n title: titleOut,\n description: descOut,\n expiresAt: rec.expiresAt,\n maxViews: rec.maxViews,\n routing: { reason: decision.reason, hint: decision.hint },\n });\n } catch (err) {\n return errorResult(locale,err instanceof Error ? err.message : String(err));\n }\n },\n } as any;\n}\n\nfunction successResult(\n locale: ReturnType<typeof resolveToolLocale>,\n payload: Record<string, unknown>,\n): AgentToolResult<Record<string, unknown>> {\n const lines = shareToolSuccessLines(locale, {\n kind: String(payload.kind ?? ''),\n shareUrl: String(payload.shareUrl ?? ''),\n title: String(payload.title ?? ''),\n expiresAt: String(payload.expiresAt ?? ''),\n thumbnailUrl: String(payload.thumbnailUrl ?? ''),\n reachability: String(payload.reachability ?? ''),\n reachabilityHint: String(payload.reachabilityHint ?? ''),\n isPublic: payload.reachability === 'public',\n }).filter(Boolean);\n return {\n content: [{ type: 'text', text: lines.join('\\n') }],\n details: payload,\n };\n}\n\nfunction errorResult(\n locale: ReturnType<typeof resolveToolLocale>,\n message: string,\n): AgentToolResult<Record<string, unknown>> {\n return {\n content: [{ type: 'text', text: shareToolErrorLine(locale, message) }],\n details: { error: message },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyCA,MAAM,oBAAoB,KAAK,OAAO;CACpC,UAAU,KAAK,OAAO,EACpB,aACE,+IACH,CAAC;CACF,UAAU,KAAK,SAAS,KAAK,KAC3B;EAAE,QAAQ;EAAU,WAAW;EAAa,QAAQ;EAAU,EAC9D,EACE,aACE,wJACH,CACF,CAAC;CACF,OAAO,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,sFAAsF,CAAC,CAAC;CACxI,aAAa,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,oDAAoD,CAAC,CAAC;CAC5G,MAAM,KAAK,SAAS,KAAK,KACvB;EAAE,MAAM;EAAQ,cAAc;EAAc,cAAc;EAAc,aAAa;EAAa,EAClG,EAAE,aAAa,iGAAiG,CACjH,CAAC;CACH,CAAC;;;;;;;;;;;;AAkCF,SAAgB,qBAAqB,KAAkC;AACrE,KAAI,CAAC,OAAO,CAAC,IAAI,QAAS,QAAO;CACjC,MAAM,KAAK,IAAI;CACf,MAAM,cAAe,GAAG,OAA6C,YAAY;CACjF,MAAM,cAAe,GAAG,WAAiD,YAAY;AACrF,QAAO,eAAe;;AAGxB,SAAS,cAAc,KAAiC;AACtD,QAAO,KAAK,SAAS,QAAQ;;AAG/B,SAAS,YAAY,OAAuB;AAC1C,QAAO,WAAW,SAAS,CAAC,OAAO,OAAO,OAAO,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;AAG9E,SAAgB,sBAAsB,MAAsC;CAC1E,MAAM,EAAE,WAAW,cAAc;AAEjC,QAAO;EACL,MAAM;EACN,aACE;EACF,YAAY;EACZ,OAAO;EAEP,MAAM,QACJ,aACA,QACA,SACmD;GACnD,MAAM,IAAI;GACV,MAAM,WAA0B,EAAE,YAAY;GAC9C,MAAM,OAAsB,EAAE,QAAQ;GACtC,MAAM,SAAS,kBAAkB,KAAK,aAAa,CAAC;GAEpD,MAAM,MAAM,WAAW;GACvB,MAAM,WAAW,oBACd,KAAK,UAAiD,MACxD;GACD,MAAM,UAAUA,mBACb,KAAK,UAAiD,UACxD;GACD,MAAM,cAAc,MAAM,4BAA4B,IAAI,GAAG;GAC7D,MAAM,cAAc,cAAc,IAAI;GACtC,MAAM,YAAY,YAAY,KAAK,cAAc,IAAI,aAAa;GAGlE,MAAM,eAAe,0BAA0B,EAAE,UAAU,UAAU;AACrE,OAAI,CAAC,aAAa,WAAW,UAAU,CACrC,QAAO,YAAY,QAAO,2CAA2C;GAEvE,MAAM,UAAU,iBAAiB,YAC7B,KACA,aAAa,MAAM,UAAU,OAAO,CAAC,QAAQ,WAAW,GAAG,CAAC,QAAQ,OAAO,IAAI;AACnF,OAAI,CAAC,QACH,QAAO,YAAY,QAAO,0CAA0C;GAGtE,IAAI;AACJ,OAAI;AACF,YAAQ,MAAM,iBAAiB,WAAW,QAAQ;YAC3C,KAAK;AACZ,WAAO,YAAY,QAAO,uBAAuB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;;GAGtG,IAAI;AACJ,OAAI;AACF,eAAW,gBAAgB,OAAO,KAAK;YAChC,KAAK;AACZ,WAAO,YAAY,QAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;;GAG7E,MAAM,WAAW,iBAAiB,SAAS;GAC3C,MAAM,QAAQ,SAAS;GACvB,MAAM,WAAW,SAAS;AAE1B,OAAI;IACF,MAAM,WAAW,CAAC,CAAC,iBAAiB;AACpC,QAAI,SAAS,SAAS,QAAQ;KAC5B,MAAM,YAAY,kBAAkB,QAAQ;KAC5C,IAAI,WAAW;KACf,IAAI,YAA2B;AAC/B,SAAI,MAAM,SAAS,QAAQ;MACzB,MAAM,SAAS,MAAM,sBAAsB,WAAW,MAAM,aAAa;AACzE,iBAAW,OAAO;AAClB,kBAAY,OAAO;;KAErB,MAAM,UAAU,MAAM,UAAU,OAAO;MACrC,MAAM;MACN,MAAM;MACN;MACA,aAAa,EAAE;MACf,aAAa;MACb,aAAa;MACb,eAAe;MACf,kBAAkB;MACnB,CAAC;AACF,SAAI,UAAW,oBAAmB,QAAQ,IAAI,UAAU;KAExD,MAAM,QAAQ,QAAQ,aAAa,QAAQ;KAC3C,MAAM,WAAW,WACb,WAAW,MAAM,GAAG,QAAQ,iBAAiB,KAC7C,UAAU,YAAY,GAAG,YAAY,QAAQ,QAAQ,MAAM;KAC/D,MAAM,eAAe,WACjB,WACC,gBAAgB,eAAe,gBAAgB,eAAe,gBAAgB,QAAQ,eAAe;KAC1G,MAAM,eAAe,GAAG,SAAS,QAAQ,QAAQ,GAAG,CAAC;AACrD,uBACE;MAAE,OAAO;MAAQ,OAAO,QAAQ;MAAO,UAAU,QAAQ;MAAI,EAC7D;MACE,QAAQ,SAAS;MACjB,iBAAiB,SAAS,UAAU,sBAAsB,oBAAoB;MAC/E,CACF;AACD,eAAU,mBAAmB,QAAQ,IAAI,UAAU;AAKnD,YAAO,cAAc,QAAQ;MAC3B,MAAM;MACN;MACA;MACA;MACA,OARe,UAAU,MAAM,SAAS,cAAe,QAAQ,MAAM,IAAI,CAAC,KAAK,IAAI,UAAY,MAAM,aAAa,MAAM,QAAQ,CAAC,KAAK,IAAI,SAAU,EAAE,MAQvI;MACf,aARc,gBAAgB;OAAE;OAAU,WAAW,QAAQ;OAAW,UAAU,EAAE;OAAa,CAQ7E;MACpB,WAAW,QAAQ;MACnB,SAAS;OAAE,QAAQ,SAAS;OAAQ,MAAM,SAAS;OAAM;MAC1D,CAAC;;IAIJ,MAAM,YAAY,cAAc,SAAS;IACzC,MAAM,MAAM,MAAM,UAAU,OAAO;KACjC,MAAM;KACN,eAAe;KACf,kBAAkB;KAClB;KACA,UAAU,aAAa,KAAA,IAAY,KAAA,IAAY;KAC/C,aAAa,EAAE;KACf,MAAM,MAAM,SAAS,cAAc,cAAc;KACjD,eAAe,SAAS,SAAS,QAAQ,aAAc,MAAM,SAAS,cAAc,WAAW,KAAA;KAChG,CAAC;IACF,MAAM,WAAW,gBAAgB,IAAI,OAAO;KAAE;KAAa;KAAa,CAAC;IACzE,MAAM,eAAe,GAAG,SAAS,SAAS;AAC1C,sBACE;KAAE,OAAO;KAAQ,OAAO,IAAI;KAAO,UAAU,IAAI;KAAI,EACrD;KACE,QAAQ,SAAS;KACjB,iBAAiB,SAAS,UAAU,sBAAsB,oBAAoB;KAC/E,CACF;AACD,cAAU,mBAAmB,IAAI,IAAI,UAAU;IAC/C,MAAM,WAAW,UAAU,IAAI,UAAU,EAAE,MAAM;IACjD,MAAM,UAAU,gBAAgB;KAAE;KAAU,WAAW,IAAI;KAAW,UAAU,EAAE;KAAa,CAAC;AAEhG,WAAO,cAAc,QAAQ;KAC3B,MAAM,SAAS;KACf,UAAU,SAAS;KACnB;KACA,cAAc,SAAS;KACvB,kBAAkB,SAAS;KAC3B,OAAO;KACP,aAAa;KACb,WAAW,IAAI;KACf,UAAU,IAAI;KACd,SAAS;MAAE,QAAQ,SAAS;MAAQ,MAAM,SAAS;MAAM;KAC1D,CAAC;YACK,KAAK;AACZ,WAAO,YAAY,QAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;;;EAGhF;;AAGH,SAAS,cACP,QACA,SAC0C;AAW1C,QAAO;EACL,SAAS,CAAC;GAAE,MAAM;GAAQ,MAXd,sBAAsB,QAAQ;IAC1C,MAAM,OAAO,QAAQ,QAAQ,GAAG;IAChC,UAAU,OAAO,QAAQ,YAAY,GAAG;IACxC,OAAO,OAAO,QAAQ,SAAS,GAAG;IAClC,WAAW,OAAO,QAAQ,aAAa,GAAG;IAC1C,cAAc,OAAO,QAAQ,gBAAgB,GAAG;IAChD,cAAc,OAAO,QAAQ,gBAAgB,GAAG;IAChD,kBAAkB,OAAO,QAAQ,oBAAoB,GAAG;IACxD,UAAU,QAAQ,iBAAiB;IACpC,CAAC,CAAC,OAAO,QAE6B,CAAC,KAAK,KAAK;GAAE,CAAC;EACnD,SAAS;EACV;;AAGH,SAAS,YACP,QACA,SAC0C;AAC1C,QAAO;EACL,SAAS,CAAC;GAAE,MAAM;GAAQ,MAAM,mBAAmB,QAAQ,QAAQ;GAAE,CAAC;EACtE,SAAS,EAAE,OAAO,SAAS;EAC5B"}
@@ -3,8 +3,8 @@ import { init_logger } from "../../utils/logger.js";
3
3
  import { SHORT_TERM_PROMOTION_LOCK_RELATIVE, SHORT_TERM_RECALL_STORE_RELATIVE } from "../memory/dreaming/constants.js";
4
4
  import { loadDreamingStore, saveDreamingStore } from "../memory/dreaming/short-term-store.js";
5
5
  import { resolveDreamingConfig } from "../memory/dreaming/config.js";
6
- import fs from "node:fs/promises";
7
6
  import path from "node:path";
7
+ import fs from "node:fs/promises";
8
8
  import { Type } from "@sinclair/typebox";
9
9
  //#region src/agent/tools/dreaming-tool.ts
10
10
  init_logger();
@@ -1,6 +1,6 @@
1
+ import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
4
4
  import { createReadFileTool } from "./read.js";
5
5
  import { createWriteFileTool } from "./write.js";
6
6
  import { createEditFileTool } from "./edit.js";
@@ -15,6 +15,7 @@ import { createWebFetchTool, createWebSearchTool } from "./web.js";
15
15
  import { createWebExtractTool } from "./web-extract.js";
16
16
  import { createMessageTool } from "./communication.js";
17
17
  import { createSendMediaTool } from "./send-media.js";
18
+ import { createCreateShareTool, isShareToolAvailable } from "./create-share-tool.js";
18
19
  import { createTodoTool } from "./todo-tool.js";
19
20
  import { createSessionStatusTool } from "./session-status-tool.js";
20
21
  import { createDreamingTool } from "./dreaming-tool.js";
@@ -26,6 +27,8 @@ import { checkBrowserReadiness } from "../../browser/readiness.js";
26
27
  import { CdpSupervisor } from "../../browser/cdp-supervisor.js";
27
28
  import "../../browser/index.js";
28
29
  import { createDelegateTool } from "./delegate-tool.js";
30
+ import { createWorkflowCatalog } from "../workflow/catalog.js";
31
+ import { createWorkflowTool } from "./workflow-tool.js";
29
32
  import { buildSandboxToolMap, createExecuteCodeTool } from "./execute-code-tool.js";
30
33
  import { createCronjobTool } from "./cronjob-tool.js";
31
34
  import { createSkillViewTool, createSkillsListTool } from "./skills-tools.js";
@@ -218,6 +221,10 @@ var AgentToolsFactory = class AgentToolsFactory {
218
221
  getConfig: () => this.deps.getConfig?.()
219
222
  })] : [],
220
223
  createSendMediaTool(workspace, bus, () => this.deps.getCurrentContext()),
224
+ ...isShareToolAvailable(cfg) ? [createCreateShareTool({
225
+ workspace,
226
+ getConfig: () => this.deps.getConfig?.()
227
+ })] : [],
221
228
  createMemorySearchTool({
222
229
  workspaceDir: workspace,
223
230
  memoriesDir
@@ -247,6 +254,33 @@ var AgentToolsFactory = class AgentToolsFactory {
247
254
  this.browserTaskSupervisors.delete(taskId);
248
255
  }
249
256
  })] : [],
257
+ ...cfg?.agents?.defaults?.workflow?.enabled !== false && primary ? [createWorkflowTool({
258
+ workspace,
259
+ bus: this.deps.bus,
260
+ getConfig: () => this.deps.getConfig?.(),
261
+ catalog: createWorkflowCatalog(),
262
+ getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,
263
+ getSubagentModel: () => {
264
+ const m = (options?.getPrimaryModel ?? this.deps.getPrimaryModel)?.();
265
+ if (!m) throw new Error("No primary model configured for workflow");
266
+ return m;
267
+ },
268
+ toolExecutorConfig: this.deps.toolExecutorConfig,
269
+ buildChildTools: (childOpts) => {
270
+ return new AgentToolsFactory({
271
+ workspace: childOpts.workspace,
272
+ bus: childOpts.bus,
273
+ getCurrentContext: () => null,
274
+ getConfig: childOpts.getConfig,
275
+ getPrimaryModel: () => childOpts.model,
276
+ toolExecutorConfig: childOpts.toolExecutorConfig
277
+ }).createAllTools({
278
+ workspace: childOpts.workspace,
279
+ getPrimaryModel: () => childOpts.model,
280
+ disabledTools: new Set(["extensions"])
281
+ });
282
+ }
283
+ })] : [],
250
284
  ...cfg?.agents?.defaults?.delegate?.enabled === true && primary ? [createDelegateTool({
251
285
  workspace,
252
286
  getSubagentModel: () => {
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","names":["parseRoutingSessionKey"],"sources":["../../../../src/agent/tools/factory.ts"],"sourcesContent":["/**\n * Agent Tools Factory - Creates and configures agent tools\n *\n * Centralizes tool creation logic to keep service.ts focused on orchestration.\n *\n * TTS: auto TTS is applied at the ChannelManager via maybeApplyTtsToPayload().\n * Optional \\`text_to_speech\\` tool sends explicit voice when TTS is enabled.\n */\n\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { Page } from 'playwright-core';\nimport type { Config } from '../../config/schema.js';\nimport type { MessageBus } from '../../infra/bus/index.js';\nimport {\n createReadFileTool,\n createWriteFileTool,\n createEditFileTool,\n createListDirTool,\n createGrepTool,\n createFindTool,\n createShellTool,\n createWebSearchTool,\n createWebFetchTool,\n createWebExtractTool,\n createMessageTool,\n createSendMediaTool,\n createMemorySearchTool,\n createMemoryGetTool,\n createTodoTool,\n createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\n} from './index.js';\nimport { createCuratedMemoryTool } from './curated-memory-tool.js';\nimport { createSessionSearchTool } from './session-search-tool.js';\nimport type { BuiltinMemoryStore } from '../memory/builtin-memory-store.js';\nimport type { MemoryManager } from '../memory/manager.js';\nimport { shouldRegisterCuratedMemoryTool } from '../memory/memory-config.js';\nimport type { SessionStore } from '../../session/store.js';\nimport { parseSessionKey as parseRoutingSessionKey } from '../../routing/session-key.js';\nimport type { GatewayClarifyRequestFn } from './clarify-tool.js';\nimport { createImageTool } from './image-tool.js';\nimport { createImageGenerateTool } from './image-generate-tool.js';\nimport {\n BrowserManager,\n BrowserNotReadyError,\n CdpSupervisor,\n checkBrowserReadiness,\n resolveBrowserBackendFromConfig,\n} from '../../browser/index.js';\nimport { createBrowserUseTool } from './browser/tool/browser-use-tool.js';\nimport { createDelegateTool } from './delegate-tool.js';\nimport { buildSandboxToolMap, createExecuteCodeTool } from './execute-code-tool.js';\nimport { createCronjobTool } from './cronjob-tool.js';\nimport type { CronService } from '../../cron/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport { wrapToolsWithProtection, type ToolExecutorConfig } from './executor.js';\nimport { createSkillsListTool, createSkillViewTool } from './skills-tools.js';\nimport { createSkillManageTool } from './skill-manage-tool.js';\nimport { createTextToSpeechTool } from './tts-tool.js';\nimport { mergeTtsConfigFromAppConfig } from '../../voice/tts/merge-config.js';\n\nconst log = createLogger('AgentToolsFactory');\n\n/** Channels where `clarify` can block for a user answer (web UI, Telegram, CLI readline). */\nconst CLARIFY_SUPPORTED_CHANNELS = new Set(['webchat', 'telegram', 'cli']);\n\nfunction clarifyTransportSource(sessionKey: string): string | undefined {\n const parsed = parseRoutingSessionKey(sessionKey);\n if (parsed) return parsed.source;\n // Fallback for simple `<channel>:<chatId>` keys used by webchat and CLI.\n const first = sessionKey.split(':').filter(Boolean)[0] ?? '';\n if (first === 'cli' || first === 'webchat') return first;\n return undefined;\n}\n\nexport interface ToolFactoryDeps {\n workspace: string;\n extensionRegistry?: any;\n getCurrentContext: () => { channel: string; chatId: string; sessionKey: string } | null;\n hookRunner?: import('../../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n toolExecutorConfig?: Partial<ToolExecutorConfig>;\n /** Agent defaults (image tools, etc.); use getter so hot-reloaded config applies. */\n getConfig?: () => Config | undefined;\n /** Session / default chat model for vision tool description. */\n getPrimaryModel?: () => Model<Api>;\n /** Built-in curated memory store (agent home `memories/`). */\n getBuiltinMemoryStore?: () => BuiltinMemoryStore;\n /** Memory orchestration (prefetch/sync + external tools). */\n getMemoryManager?: () => MemoryManager;\n /** Session store for `session_search`. */\n getSessionStore?: () => SessionStore;\n /** When set (gateway webchat), enables the `clarify` tool. */\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: enables the `cronjob` tool. */\n getCronService?: () => CronService | undefined;\n /** Current session skill indexing (tool gating + allowlist); used by skills_list / skill_view. */\n getSkillIndexingContext?: () =>\n | { registeredToolNames: string[]; skillAllowlist?: string[] }\n | undefined;\n /** After skill_manage mutates disk, reload skills + refresh agent prompts (optional). */\n onSkillsFilesystemMutate?: () => void;\n /** Names registered via skill_view for shell env passthrough. */\n getSkillPassthroughEnvVarNames?: () => string[];\n /** Add declared env names for the current session (no values stored). */\n registerSkillEnvPassthrough?: (names: string[]) => void;\n}\n\nexport interface CreateCoreToolsOptions {\n /** Workspace root for file/shell tools (defaults to factory workspace). */\n workspace?: string;\n /** Canonical `agents/<id>/profile/`: bare SOUL.md / IDENTITY.md resolve here after the workspace. */\n profileMarkdownRoot?: string;\n /** Tool `name` values to omit (e.g. `shell`, `extensions` for extension tools). */\n disabledTools?: Set<string>;\n /** Optional primary model for image tool heuristics. */\n getPrimaryModel?: () => Model<Api>;\n getBuiltinMemoryStore?: () => BuiltinMemoryStore;\n getMemoryManager?: () => MemoryManager;\n /** When set, registers `skills_list` and `skill_view` bound to this workspace\\'s skills. */\n getSkillManager?: () => SkillManager;\n}\n\nexport class AgentToolsFactory {\n private browserManager: BrowserManager | null = null;\n /** One dialog/console supervisor per chat session (browser tab). */\n private readonly browserTaskSupervisors = new Map<string, CdpSupervisor>();\n /** Cached readiness probe — keyed by backend mode + extension host:port. */\n private browserReadinessCache: {\n key: string;\n expiresAt: number;\n inflight?: Promise<BrowserNotReadyError | null>;\n result?: BrowserNotReadyError | null;\n } | null = null;\n\n constructor(private deps: ToolFactoryDeps) {}\n\n private browserReadinessKey(): string {\n const cfg = this.deps.getConfig?.();\n const backend = resolveBrowserBackendFromConfig(cfg);\n const ext = cfg?.agents?.defaults?.browser?.extension;\n const host = typeof ext?.host === 'string' && ext.host.trim() ? ext.host.trim() : '127.0.0.1';\n const port = typeof ext?.port === 'number' ? ext.port : 19820;\n const cdpUrl = backend.mode === 'cdp' ? backend.config.wsEndpoint : '';\n const cloudKind = backend.mode === 'cloud' ? backend.config.type : '';\n return `${backend.mode}@${host}:${port}|${cdpUrl}|${cloudKind}`;\n }\n\n private async checkBrowserReadinessCached(): Promise<BrowserNotReadyError | null> {\n const key = this.browserReadinessKey();\n const now = Date.now();\n const cached = this.browserReadinessCache;\n if (cached && cached.key === key && cached.expiresAt > now && cached.inflight === undefined) {\n return cached.result ?? null;\n }\n if (cached && cached.key === key && cached.inflight) {\n return cached.inflight;\n }\n const inflight = checkBrowserReadiness(this.deps.getConfig?.());\n this.browserReadinessCache = { key, expiresAt: now + 30_000, inflight };\n try {\n const result = await inflight;\n this.browserReadinessCache = { key, expiresAt: Date.now() + 30_000, result };\n return result;\n } catch (e) {\n // Probe should never throw, but if it does we just bypass the cache.\n this.browserReadinessCache = null;\n log.warn({ err: e }, 'browserReadiness probe failed');\n return null;\n }\n }\n\n /** Invalidate the readiness cache (config hot-reload, settings-page save, etc.). */\n invalidateBrowserReadinessCache(): void {\n this.browserReadinessCache = null;\n }\n\n private browserSupervisorForTask(taskId: string): CdpSupervisor {\n let s = this.browserTaskSupervisors.get(taskId);\n if (!s) {\n const b = this.deps.getConfig?.()?.agents?.defaults?.browser;\n const dialogPolicy =\n b?.dialogPolicy === 'must_respond' || b?.dialogPolicy === 'auto_accept' || b?.dialogPolicy === 'auto_dismiss'\n ? b.dialogPolicy\n : 'auto_dismiss';\n const dialogTimeoutSeconds =\n typeof b?.dialogTimeoutSeconds === 'number' &&\n Number.isFinite(b.dialogTimeoutSeconds) &&\n b.dialogTimeoutSeconds >= 1\n ? Math.floor(b.dialogTimeoutSeconds)\n : 300;\n s = new CdpSupervisor({ dialogPolicy, dialogTimeoutSeconds });\n this.browserTaskSupervisors.set(taskId, s);\n }\n return s;\n }\n\n private async acquireBrowserPage(): Promise<Page> {\n const taskId = this.deps.getCurrentContext()?.sessionKey ?? 'default';\n const mgr = this.ensureBrowserManager();\n await mgr.ensureConnected();\n if (mgr.getExtensionProvider()) {\n return null as unknown as Page;\n }\n const page = await mgr.getPage(taskId);\n this.browserSupervisorForTask(taskId).attach(page);\n return page;\n }\n\n private ensureBrowserManager(): BrowserManager {\n if (!this.browserManager) {\n this.browserManager = new BrowserManager({\n getHeadless: () => this.deps.getConfig?.()?.agents?.defaults?.browser?.headless === true,\n getBackend: () => resolveBrowserBackendFromConfig(this.deps.getConfig?.()),\n });\n }\n return this.browserManager;\n }\n\n /** Close Playwright and all pages (gateway stop, agent manager dispose, or config hot-reload). */\n async shutdownBrowser(): Promise<void> {\n this.browserReadinessCache = null;\n if (!this.browserManager) {\n return;\n }\n await this.browserManager.shutdown();\n this.browserManager = null;\n this.browserTaskSupervisors.clear();\n }\n\n /** Drop the tab for a session when its agent instance is removed. */\n async closeBrowserPageForSession(sessionKey: string): Promise<void> {\n this.browserTaskSupervisors.delete(sessionKey);\n await this.browserManager?.closePage(sessionKey);\n }\n\n createCoreTools(options?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const workspace = options?.workspace ?? this.deps.workspace;\n const { bus } = this.deps;\n const getPrimary = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const getBuiltin = options?.getBuiltinMemoryStore ?? this.deps.getBuiltinMemoryStore;\n const builtinStore = getBuiltin?.();\n const memoriesDir = builtinStore?.memoriesDir;\n const getMemMgr = options?.getMemoryManager ?? this.deps.getMemoryManager;\n const getSkillMgr = options?.getSkillManager;\n const disabled = options?.disabledTools;\n\n const primary = getPrimary?.();\n const modelHasVision = primary?.input?.includes('image') ?? false;\n const cfg = this.deps.getConfig?.();\n const imageTool = createImageTool({\n config: cfg,\n workspace,\n modelHasVision,\n });\n const imageGenerateTool = createImageGenerateTool({\n config: cfg,\n workspace,\n });\n\n const optionalTools = [imageTool, imageGenerateTool].filter((t) => t != null) as any[];\n\n const readTool = createReadFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n });\n const writeTool = createWriteFileTool(workspace);\n const editTool = createEditFileTool(workspace);\n const listDir = createListDirTool(workspace);\n const grep = createGrepTool(workspace);\n const find = createFindTool(workspace);\n\n const core: AgentTool<any, any>[] = [\n createSessionStatusTool(),\n createDreamingTool({\n getWorkspace: () => workspace,\n getConfig: () => this.deps.getConfig?.(),\n }),\n createClarifyTool({\n resolveAskUser: () => {\n const req = this.deps.gatewayClarify?.requestClarification;\n if (!req) return null;\n const ctx = this.deps.getCurrentContext();\n if (!ctx?.sessionKey) return null;\n const source = clarifyTransportSource(ctx.sessionKey);\n if (!source || !CLARIFY_SUPPORTED_CHANNELS.has(source)) return null;\n return (r) => req(ctx.sessionKey, r);\n },\n }),\n createTodoTool({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ...(getSkillMgr\n ? [\n createSkillsListTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n }),\n createSkillViewTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n registerSkillEnvPassthrough: this.deps.registerSkillEnvPassthrough,\n }),\n createSkillManageTool({\n getSkillManager: getSkillMgr,\n getWorkspace: () => workspace,\n onSkillsFilesystemMutate: this.deps.onSkillsFilesystemMutate,\n }),\n ]\n : []),\n readTool,\n writeTool,\n editTool,\n listDir,\n grep,\n find,\n createShellTool(workspace, {\n getSkillPassthroughEnvVarNames: this.deps.getSkillPassthroughEnvVarNames,\n }),\n createWebSearchTool(() => this.deps.getConfig?.()),\n createWebFetchTool(() => this.deps.getConfig?.()),\n createWebExtractTool({ getConfig: () => this.deps.getConfig?.() }),\n // Note: TTS is NOT handled by send_message tool anymore\n // TTS is applied at the ChannelManager dispatch layer\n createMessageTool(bus, () => this.deps.getCurrentContext()),\n ...(mergeTtsConfigFromAppConfig(cfg?.messages?.tts).enabled\n ? [\n createTextToSpeechTool({\n bus,\n getContext: () => this.deps.getCurrentContext(),\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n createSendMediaTool(workspace, bus, () => this.deps.getCurrentContext()),\n createMemorySearchTool({ workspaceDir: workspace, memoriesDir }),\n createMemoryGetTool({ workspaceDir: workspace, memoriesDir }),\n ...(getBuiltin && shouldRegisterCuratedMemoryTool(this.deps.getConfig?.())\n ? [\n createCuratedMemoryTool(getBuiltin, {\n onMemoryWrite: (action, target, content) => {\n getMemMgr?.().onMemoryWrite(action, target, content);\n },\n }),\n ]\n : []),\n ...(getMemMgr?.().getAdditionalTools() ?? []),\n ...(this.deps.getSessionStore\n ? [\n createSessionSearchTool({\n getSessionStore: this.deps.getSessionStore,\n getConfig: this.deps.getConfig,\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ]\n : []),\n ...(this.deps.getCronService\n ? [\n createCronjobTool({\n getCronService: this.deps.getCronService,\n }),\n ]\n : []),\n ...(cfg?.agents?.defaults?.browser?.enabled !== false\n ? [\n createBrowserUseTool({\n getManager: () => this.ensureBrowserManager(),\n getPageForTask: () => this.acquireBrowserPage(),\n getTaskId: () => this.deps.getCurrentContext()?.sessionKey ?? 'default',\n getConfig: () => this.deps.getConfig?.(),\n getReadiness: () => this.checkBrowserReadinessCached(),\n getSupervisor: () =>\n this.browserSupervisorForTask(this.deps.getCurrentContext()?.sessionKey ?? 'default'),\n notifyBrowserPageClosed: (taskId) => {\n this.browserTaskSupervisors.delete(taskId);\n },\n }),\n ]\n : []),\n ...(cfg?.agents?.defaults?.delegate?.enabled === true && primary\n ? [\n createDelegateTool({\n workspace,\n getSubagentModel: () => {\n const gp = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const m = gp?.();\n if (!m) {\n throw new Error('No primary model configured for delegate_task');\n }\n return m;\n },\n bus: this.deps.bus,\n getConfig: () => this.deps.getConfig?.(),\n getCurrentContext: () => this.deps.getCurrentContext?.() ?? null,\n hookRunner: this.deps.hookRunner,\n toolExecutorConfig: this.deps.toolExecutorConfig,\n // Injected so `child-agent-factory.ts` does not need to import\n // `AgentToolsFactory` directly (which would form a cycle).\n buildChildTools: (childOpts) => {\n const childFactory = new AgentToolsFactory({\n workspace: childOpts.workspace,\n bus: childOpts.bus,\n getCurrentContext: () => null,\n getConfig: childOpts.getConfig,\n getPrimaryModel: () => childOpts.model,\n toolExecutorConfig: childOpts.toolExecutorConfig,\n });\n return childFactory.createAllTools({\n workspace: childOpts.workspace,\n getPrimaryModel: () => childOpts.model,\n disabledTools: new Set(['extensions']),\n });\n },\n }),\n ]\n : []),\n ...optionalTools,\n ];\n\n return filterToolsByDisabledSet(core, disabled);\n }\n\n createAllTools(coreOptions?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const coreTools = this.createCoreTools(coreOptions);\n const disableExtensions = coreOptions?.disabledTools?.has('extensions');\n const cfg = this.deps.getConfig?.();\n\n let bundled: AgentTool<any, any>[];\n if (!this.deps.extensionRegistry || disableExtensions) {\n bundled = coreTools;\n } else {\n const extensionTools = this.deps.extensionRegistry.getAllTools();\n log.info({ count: extensionTools.length }, 'Loaded extension tools');\n bundled = [...coreTools, ...extensionTools];\n }\n\n const wrapped = wrapToolsWithProtection(bundled, this.deps.toolExecutorConfig);\n\n const executeEnabled =\n cfg?.agents?.defaults?.executeCode?.enabled === true &&\n !coreOptions?.disabledTools?.has('execute_code');\n\n if (executeEnabled) {\n const sandboxMap = buildSandboxToolMap(wrapped);\n const executeTool = createExecuteCodeTool({ getSandboxToolMap: () => sandboxMap });\n const wrappedExecute = wrapToolsWithProtection([executeTool as any], this.deps.toolExecutorConfig);\n return [...wrapped, ...wrappedExecute];\n }\n\n return wrapped;\n }\n}\n\nfunction filterToolsByDisabledSet(\n tools: any[],\n disabled: Set<string> | undefined,\n): any[] {\n if (!disabled || disabled.size === 0) {\n return tools;\n }\n return tools.filter((t) => !disabled.has(t.name));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"factory.js","names":["parseRoutingSessionKey"],"sources":["../../../../src/agent/tools/factory.ts"],"sourcesContent":["/**\n * Agent Tools Factory - Creates and configures agent tools\n *\n * Centralizes tool creation logic to keep service.ts focused on orchestration.\n *\n * TTS: auto TTS is applied at the ChannelManager via maybeApplyTtsToPayload().\n * Optional \\`text_to_speech\\` tool sends explicit voice when TTS is enabled.\n */\n\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { Page } from 'playwright-core';\nimport type { Config } from '../../config/schema.js';\nimport type { MessageBus } from '../../infra/bus/index.js';\nimport {\n createReadFileTool,\n createWriteFileTool,\n createEditFileTool,\n createListDirTool,\n createGrepTool,\n createFindTool,\n createShellTool,\n createWebSearchTool,\n createWebFetchTool,\n createWebExtractTool,\n createMessageTool,\n createSendMediaTool,\n createCreateShareTool,\n isShareToolAvailable,\n createMemorySearchTool,\n createMemoryGetTool,\n createTodoTool,\n createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\n} from './index.js';\nimport { createCuratedMemoryTool } from './curated-memory-tool.js';\nimport { createSessionSearchTool } from './session-search-tool.js';\nimport type { BuiltinMemoryStore } from '../memory/builtin-memory-store.js';\nimport type { MemoryManager } from '../memory/manager.js';\nimport { shouldRegisterCuratedMemoryTool } from '../memory/memory-config.js';\nimport type { SessionStore } from '../../session/store.js';\nimport { parseSessionKey as parseRoutingSessionKey } from '../../routing/session-key.js';\nimport type { GatewayClarifyRequestFn } from './clarify-tool.js';\nimport { createImageTool } from './image-tool.js';\nimport { createImageGenerateTool } from './image-generate-tool.js';\nimport {\n BrowserManager,\n BrowserNotReadyError,\n CdpSupervisor,\n checkBrowserReadiness,\n resolveBrowserBackendFromConfig,\n} from '../../browser/index.js';\nimport { createBrowserUseTool } from './browser/tool/browser-use-tool.js';\nimport { createDelegateTool } from './delegate-tool.js';\nimport { createWorkflowTool } from './workflow-tool.js';\nimport { createWorkflowCatalog } from '../workflow/catalog.js';\nimport { buildSandboxToolMap, createExecuteCodeTool } from './execute-code-tool.js';\nimport { createCronjobTool } from './cronjob-tool.js';\nimport type { CronService } from '../../cron/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport { wrapToolsWithProtection, type ToolExecutorConfig } from './executor.js';\nimport { createSkillsListTool, createSkillViewTool } from './skills-tools.js';\nimport { createSkillManageTool } from './skill-manage-tool.js';\nimport { createTextToSpeechTool } from './tts-tool.js';\nimport { mergeTtsConfigFromAppConfig } from '../../voice/tts/merge-config.js';\n\nconst log = createLogger('AgentToolsFactory');\n\n/** Channels where `clarify` can block for a user answer (web UI, Telegram, CLI readline). */\nconst CLARIFY_SUPPORTED_CHANNELS = new Set(['webchat', 'telegram', 'cli']);\n\nfunction clarifyTransportSource(sessionKey: string): string | undefined {\n const parsed = parseRoutingSessionKey(sessionKey);\n if (parsed) return parsed.source;\n // Fallback for simple `<channel>:<chatId>` keys used by webchat and CLI.\n const first = sessionKey.split(':').filter(Boolean)[0] ?? '';\n if (first === 'cli' || first === 'webchat') return first;\n return undefined;\n}\n\nexport interface ToolFactoryDeps {\n workspace: string;\n extensionRegistry?: any;\n getCurrentContext: () => { channel: string; chatId: string; sessionKey: string } | null;\n hookRunner?: import('../../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n toolExecutorConfig?: Partial<ToolExecutorConfig>;\n /** Agent defaults (image tools, etc.); use getter so hot-reloaded config applies. */\n getConfig?: () => Config | undefined;\n /** Session / default chat model for vision tool description. */\n getPrimaryModel?: () => Model<Api>;\n /** Built-in curated memory store (agent home `memories/`). */\n getBuiltinMemoryStore?: () => BuiltinMemoryStore;\n /** Memory orchestration (prefetch/sync + external tools). */\n getMemoryManager?: () => MemoryManager;\n /** Session store for `session_search`. */\n getSessionStore?: () => SessionStore;\n /** When set (gateway webchat), enables the `clarify` tool. */\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: enables the `cronjob` tool. */\n getCronService?: () => CronService | undefined;\n /** Current session skill indexing (tool gating + allowlist); used by skills_list / skill_view. */\n getSkillIndexingContext?: () =>\n | { registeredToolNames: string[]; skillAllowlist?: string[] }\n | undefined;\n /** After skill_manage mutates disk, reload skills + refresh agent prompts (optional). */\n onSkillsFilesystemMutate?: () => void;\n /** Names registered via skill_view for shell env passthrough. */\n getSkillPassthroughEnvVarNames?: () => string[];\n /** Add declared env names for the current session (no values stored). */\n registerSkillEnvPassthrough?: (names: string[]) => void;\n}\n\nexport interface CreateCoreToolsOptions {\n /** Workspace root for file/shell tools (defaults to factory workspace). */\n workspace?: string;\n /** Canonical `agents/<id>/profile/`: bare SOUL.md / IDENTITY.md resolve here after the workspace. */\n profileMarkdownRoot?: string;\n /** Tool `name` values to omit (e.g. `shell`, `extensions` for extension tools). */\n disabledTools?: Set<string>;\n /** Optional primary model for image tool heuristics. */\n getPrimaryModel?: () => Model<Api>;\n getBuiltinMemoryStore?: () => BuiltinMemoryStore;\n getMemoryManager?: () => MemoryManager;\n /** When set, registers `skills_list` and `skill_view` bound to this workspace\\'s skills. */\n getSkillManager?: () => SkillManager;\n}\n\nexport class AgentToolsFactory {\n private browserManager: BrowserManager | null = null;\n /** One dialog/console supervisor per chat session (browser tab). */\n private readonly browserTaskSupervisors = new Map<string, CdpSupervisor>();\n /** Cached readiness probe — keyed by backend mode + extension host:port. */\n private browserReadinessCache: {\n key: string;\n expiresAt: number;\n inflight?: Promise<BrowserNotReadyError | null>;\n result?: BrowserNotReadyError | null;\n } | null = null;\n\n constructor(private deps: ToolFactoryDeps) {}\n\n private browserReadinessKey(): string {\n const cfg = this.deps.getConfig?.();\n const backend = resolveBrowserBackendFromConfig(cfg);\n const ext = cfg?.agents?.defaults?.browser?.extension;\n const host = typeof ext?.host === 'string' && ext.host.trim() ? ext.host.trim() : '127.0.0.1';\n const port = typeof ext?.port === 'number' ? ext.port : 19820;\n const cdpUrl = backend.mode === 'cdp' ? backend.config.wsEndpoint : '';\n const cloudKind = backend.mode === 'cloud' ? backend.config.type : '';\n return `${backend.mode}@${host}:${port}|${cdpUrl}|${cloudKind}`;\n }\n\n private async checkBrowserReadinessCached(): Promise<BrowserNotReadyError | null> {\n const key = this.browserReadinessKey();\n const now = Date.now();\n const cached = this.browserReadinessCache;\n if (cached && cached.key === key && cached.expiresAt > now && cached.inflight === undefined) {\n return cached.result ?? null;\n }\n if (cached && cached.key === key && cached.inflight) {\n return cached.inflight;\n }\n const inflight = checkBrowserReadiness(this.deps.getConfig?.());\n this.browserReadinessCache = { key, expiresAt: now + 30_000, inflight };\n try {\n const result = await inflight;\n this.browserReadinessCache = { key, expiresAt: Date.now() + 30_000, result };\n return result;\n } catch (e) {\n // Probe should never throw, but if it does we just bypass the cache.\n this.browserReadinessCache = null;\n log.warn({ err: e }, 'browserReadiness probe failed');\n return null;\n }\n }\n\n /** Invalidate the readiness cache (config hot-reload, settings-page save, etc.). */\n invalidateBrowserReadinessCache(): void {\n this.browserReadinessCache = null;\n }\n\n private browserSupervisorForTask(taskId: string): CdpSupervisor {\n let s = this.browserTaskSupervisors.get(taskId);\n if (!s) {\n const b = this.deps.getConfig?.()?.agents?.defaults?.browser;\n const dialogPolicy =\n b?.dialogPolicy === 'must_respond' || b?.dialogPolicy === 'auto_accept' || b?.dialogPolicy === 'auto_dismiss'\n ? b.dialogPolicy\n : 'auto_dismiss';\n const dialogTimeoutSeconds =\n typeof b?.dialogTimeoutSeconds === 'number' &&\n Number.isFinite(b.dialogTimeoutSeconds) &&\n b.dialogTimeoutSeconds >= 1\n ? Math.floor(b.dialogTimeoutSeconds)\n : 300;\n s = new CdpSupervisor({ dialogPolicy, dialogTimeoutSeconds });\n this.browserTaskSupervisors.set(taskId, s);\n }\n return s;\n }\n\n private async acquireBrowserPage(): Promise<Page> {\n const taskId = this.deps.getCurrentContext()?.sessionKey ?? 'default';\n const mgr = this.ensureBrowserManager();\n await mgr.ensureConnected();\n if (mgr.getExtensionProvider()) {\n return null as unknown as Page;\n }\n const page = await mgr.getPage(taskId);\n this.browserSupervisorForTask(taskId).attach(page);\n return page;\n }\n\n private ensureBrowserManager(): BrowserManager {\n if (!this.browserManager) {\n this.browserManager = new BrowserManager({\n getHeadless: () => this.deps.getConfig?.()?.agents?.defaults?.browser?.headless === true,\n getBackend: () => resolveBrowserBackendFromConfig(this.deps.getConfig?.()),\n });\n }\n return this.browserManager;\n }\n\n /** Close Playwright and all pages (gateway stop, agent manager dispose, or config hot-reload). */\n async shutdownBrowser(): Promise<void> {\n this.browserReadinessCache = null;\n if (!this.browserManager) {\n return;\n }\n await this.browserManager.shutdown();\n this.browserManager = null;\n this.browserTaskSupervisors.clear();\n }\n\n /** Drop the tab for a session when its agent instance is removed. */\n async closeBrowserPageForSession(sessionKey: string): Promise<void> {\n this.browserTaskSupervisors.delete(sessionKey);\n await this.browserManager?.closePage(sessionKey);\n }\n\n createCoreTools(options?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const workspace = options?.workspace ?? this.deps.workspace;\n const { bus } = this.deps;\n const getPrimary = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const getBuiltin = options?.getBuiltinMemoryStore ?? this.deps.getBuiltinMemoryStore;\n const builtinStore = getBuiltin?.();\n const memoriesDir = builtinStore?.memoriesDir;\n const getMemMgr = options?.getMemoryManager ?? this.deps.getMemoryManager;\n const getSkillMgr = options?.getSkillManager;\n const disabled = options?.disabledTools;\n\n const primary = getPrimary?.();\n const modelHasVision = primary?.input?.includes('image') ?? false;\n const cfg = this.deps.getConfig?.();\n const imageTool = createImageTool({\n config: cfg,\n workspace,\n modelHasVision,\n });\n const imageGenerateTool = createImageGenerateTool({\n config: cfg,\n workspace,\n });\n\n const optionalTools = [imageTool, imageGenerateTool].filter((t) => t != null) as any[];\n\n const readTool = createReadFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n });\n const writeTool = createWriteFileTool(workspace);\n const editTool = createEditFileTool(workspace);\n const listDir = createListDirTool(workspace);\n const grep = createGrepTool(workspace);\n const find = createFindTool(workspace);\n\n const core: AgentTool<any, any>[] = [\n createSessionStatusTool(),\n createDreamingTool({\n getWorkspace: () => workspace,\n getConfig: () => this.deps.getConfig?.(),\n }),\n createClarifyTool({\n resolveAskUser: () => {\n const req = this.deps.gatewayClarify?.requestClarification;\n if (!req) return null;\n const ctx = this.deps.getCurrentContext();\n if (!ctx?.sessionKey) return null;\n const source = clarifyTransportSource(ctx.sessionKey);\n if (!source || !CLARIFY_SUPPORTED_CHANNELS.has(source)) return null;\n return (r) => req(ctx.sessionKey, r);\n },\n }),\n createTodoTool({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ...(getSkillMgr\n ? [\n createSkillsListTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n }),\n createSkillViewTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n registerSkillEnvPassthrough: this.deps.registerSkillEnvPassthrough,\n }),\n createSkillManageTool({\n getSkillManager: getSkillMgr,\n getWorkspace: () => workspace,\n onSkillsFilesystemMutate: this.deps.onSkillsFilesystemMutate,\n }),\n ]\n : []),\n readTool,\n writeTool,\n editTool,\n listDir,\n grep,\n find,\n createShellTool(workspace, {\n getSkillPassthroughEnvVarNames: this.deps.getSkillPassthroughEnvVarNames,\n }),\n createWebSearchTool(() => this.deps.getConfig?.()),\n createWebFetchTool(() => this.deps.getConfig?.()),\n createWebExtractTool({ getConfig: () => this.deps.getConfig?.() }),\n // Note: TTS is NOT handled by send_message tool anymore\n // TTS is applied at the ChannelManager dispatch layer\n createMessageTool(bus, () => this.deps.getCurrentContext()),\n ...(mergeTtsConfigFromAppConfig(cfg?.messages?.tts).enabled\n ? [\n createTextToSpeechTool({\n bus,\n getContext: () => this.deps.getCurrentContext(),\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n createSendMediaTool(workspace, bus, () => this.deps.getCurrentContext()),\n ...(isShareToolAvailable(cfg)\n ? [\n createCreateShareTool({\n workspace,\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n createMemorySearchTool({ workspaceDir: workspace, memoriesDir }),\n createMemoryGetTool({ workspaceDir: workspace, memoriesDir }),\n ...(getBuiltin && shouldRegisterCuratedMemoryTool(this.deps.getConfig?.())\n ? [\n createCuratedMemoryTool(getBuiltin, {\n onMemoryWrite: (action, target, content) => {\n getMemMgr?.().onMemoryWrite(action, target, content);\n },\n }),\n ]\n : []),\n ...(getMemMgr?.().getAdditionalTools() ?? []),\n ...(this.deps.getSessionStore\n ? [\n createSessionSearchTool({\n getSessionStore: this.deps.getSessionStore,\n getConfig: this.deps.getConfig,\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ]\n : []),\n ...(this.deps.getCronService\n ? [\n createCronjobTool({\n getCronService: this.deps.getCronService,\n }),\n ]\n : []),\n ...(cfg?.agents?.defaults?.browser?.enabled !== false\n ? [\n createBrowserUseTool({\n getManager: () => this.ensureBrowserManager(),\n getPageForTask: () => this.acquireBrowserPage(),\n getTaskId: () => this.deps.getCurrentContext()?.sessionKey ?? 'default',\n getConfig: () => this.deps.getConfig?.(),\n getReadiness: () => this.checkBrowserReadinessCached(),\n getSupervisor: () =>\n this.browserSupervisorForTask(this.deps.getCurrentContext()?.sessionKey ?? 'default'),\n notifyBrowserPageClosed: (taskId) => {\n this.browserTaskSupervisors.delete(taskId);\n },\n }),\n ]\n : []),\n ...(cfg?.agents?.defaults?.workflow?.enabled !== false && primary\n ? [\n createWorkflowTool({\n workspace,\n bus: this.deps.bus,\n getConfig: () => this.deps.getConfig?.(),\n catalog: createWorkflowCatalog(),\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n getSubagentModel: () => {\n const gp = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const m = gp?.();\n if (!m) {\n throw new Error('No primary model configured for workflow');\n }\n return m;\n },\n toolExecutorConfig: this.deps.toolExecutorConfig,\n // Injected so `subagent-runner.ts` doesn't import `AgentToolsFactory`\n // (which would form the same cycle delegate-tool was carved out to avoid).\n buildChildTools: (childOpts) => {\n const childFactory = new AgentToolsFactory({\n workspace: childOpts.workspace,\n bus: childOpts.bus,\n getCurrentContext: () => null,\n getConfig: childOpts.getConfig,\n getPrimaryModel: () => childOpts.model,\n toolExecutorConfig: childOpts.toolExecutorConfig,\n });\n return childFactory.createAllTools({\n workspace: childOpts.workspace,\n getPrimaryModel: () => childOpts.model,\n disabledTools: new Set(['extensions']),\n });\n },\n }),\n ]\n : []),\n ...(cfg?.agents?.defaults?.delegate?.enabled === true && primary\n ? [\n createDelegateTool({\n workspace,\n getSubagentModel: () => {\n const gp = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const m = gp?.();\n if (!m) {\n throw new Error('No primary model configured for delegate_task');\n }\n return m;\n },\n bus: this.deps.bus,\n getConfig: () => this.deps.getConfig?.(),\n getCurrentContext: () => this.deps.getCurrentContext?.() ?? null,\n hookRunner: this.deps.hookRunner,\n toolExecutorConfig: this.deps.toolExecutorConfig,\n // Injected so `child-agent-factory.ts` does not need to import\n // `AgentToolsFactory` directly (which would form a cycle).\n buildChildTools: (childOpts) => {\n const childFactory = new AgentToolsFactory({\n workspace: childOpts.workspace,\n bus: childOpts.bus,\n getCurrentContext: () => null,\n getConfig: childOpts.getConfig,\n getPrimaryModel: () => childOpts.model,\n toolExecutorConfig: childOpts.toolExecutorConfig,\n });\n return childFactory.createAllTools({\n workspace: childOpts.workspace,\n getPrimaryModel: () => childOpts.model,\n disabledTools: new Set(['extensions']),\n });\n },\n }),\n ]\n : []),\n ...optionalTools,\n ];\n\n return filterToolsByDisabledSet(core, disabled);\n }\n\n createAllTools(coreOptions?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const coreTools = this.createCoreTools(coreOptions);\n const disableExtensions = coreOptions?.disabledTools?.has('extensions');\n const cfg = this.deps.getConfig?.();\n\n let bundled: AgentTool<any, any>[];\n if (!this.deps.extensionRegistry || disableExtensions) {\n bundled = coreTools;\n } else {\n const extensionTools = this.deps.extensionRegistry.getAllTools();\n log.info({ count: extensionTools.length }, 'Loaded extension tools');\n bundled = [...coreTools, ...extensionTools];\n }\n\n const wrapped = wrapToolsWithProtection(bundled, this.deps.toolExecutorConfig);\n\n const executeEnabled =\n cfg?.agents?.defaults?.executeCode?.enabled === true &&\n !coreOptions?.disabledTools?.has('execute_code');\n\n if (executeEnabled) {\n const sandboxMap = buildSandboxToolMap(wrapped);\n const executeTool = createExecuteCodeTool({ getSandboxToolMap: () => sandboxMap });\n const wrappedExecute = wrapToolsWithProtection([executeTool as any], this.deps.toolExecutorConfig);\n return [...wrapped, ...wrappedExecute];\n }\n\n return wrapped;\n }\n}\n\nfunction filterToolsByDisabledSet(\n tools: any[],\n disabled: Set<string> | undefined,\n): any[] {\n if (!disabled || disabled.size === 0) {\n return tools;\n }\n return tools.filter((t) => !disabled.has(t.name));\n}\n"],"mappings":"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"}
@@ -4,9 +4,9 @@ import { isFailoverError } from "../failover-error.js";
4
4
  import { imageAssetFromDataUrl, imageFileExtensionForMimeType, mimeTypeFromFileName, parseImageDataUrl, sniffImageMimeType } from "../image/generation/image-assets.js";
5
5
  import { getImageGenerationProvider } from "../image/generation/provider-registry.js";
6
6
  import { generateImage, listImageGenerationProvidersSummary } from "../image/generation/runtime.js";
7
+ import path from "node:path";
7
8
  import { randomBytes } from "node:crypto";
8
9
  import { mkdir, readFile, writeFile } from "node:fs/promises";
9
- import path from "node:path";
10
10
  import { Type } from "@sinclair/typebox";
11
11
  //#region src/agent/tools/image-generate-tool.ts
12
12
  const DEFAULT_COUNT = 1;
@@ -13,6 +13,7 @@ export { createWebSearchTool, createWebFetchTool } from './web.js';
13
13
  export { createWebExtractTool, stripHtmlBoilerplate, DEFAULT_WEB_EXTRACT_MAX_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, } from './web-extract.js';
14
14
  export { createMessageTool } from './communication.js';
15
15
  export { createSendMediaTool } from './send-media.js';
16
+ export { createCreateShareTool, isShareToolAvailable, type CreateShareToolDeps, } from './create-share-tool.js';
16
17
  export { createTodoTool, TodoStore, type TodoItem, type TodoStatus } from './todo-tool.js';
17
18
  export { createSessionStatusTool } from './session-status-tool.js';
18
19
  export { createDreamingTool, type DreamingToolDeps } from './dreaming-tool.js';
@@ -20,6 +21,7 @@ export { createClarifyTool, type ClarifyRequestPayload, type GatewayClarifyReque
20
21
  export { createBrowserTools, type CreateBrowserToolsDeps } from './browser-legacy-tools.js';
21
22
  export { BrowserManager, assertBrowserUrlAllowed } from '../../browser/index.js';
22
23
  export { createDelegateTool, DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS, } from './delegate-tool.js';
24
+ export { createWorkflowTool, type WorkflowToolDeps, type WorkflowToolInput } from './workflow-tool.js';
23
25
  export { createExecuteCodeTool, buildSandboxToolMap, SANDBOX_ALLOWED_TOOLS, } from './execute-code-tool.js';
24
26
  export { createCronjobTool, scanCronPrompt } from './cronjob-tool.js';
25
27
  export { createSkillsListTool, createSkillViewTool, type SkillsToolsDeps } from './skills-tools.js';
@@ -15,6 +15,7 @@ import { createWebFetchTool, createWebSearchTool } from "./web.js";
15
15
  import { DEFAULT_WEB_EXTRACT_MAX_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, createWebExtractTool, stripHtmlBoilerplate } from "./web-extract.js";
16
16
  import { createMessageTool } from "./communication.js";
17
17
  import { createSendMediaTool } from "./send-media.js";
18
+ import { createCreateShareTool, isShareToolAvailable } from "./create-share-tool.js";
18
19
  import { TodoStore, createTodoTool } from "./todo-tool.js";
19
20
  import { createSessionStatusTool } from "./session-status-tool.js";
20
21
  import { createDreamingTool } from "./dreaming-tool.js";
@@ -26,9 +27,10 @@ import { createBrowserTools } from "./browser-legacy-tools.js";
26
27
  import { BrowserManager } from "../../browser/manager.js";
27
28
  import "../../browser/index.js";
28
29
  import { DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS, createDelegateTool } from "./delegate-tool.js";
30
+ import { createWorkflowTool } from "./workflow-tool.js";
29
31
  import { SANDBOX_ALLOWED_TOOLS, buildSandboxToolMap, createExecuteCodeTool } from "./execute-code-tool.js";
30
32
  import { createCronjobTool, scanCronPrompt } from "./cronjob-tool.js";
31
33
  import { createSkillViewTool, createSkillsListTool } from "./skills-tools.js";
32
34
  import { createSkillManageTool } from "./skill-manage-tool.js";
33
35
  import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
34
- export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, assertBrowserUrlAllowed, buildSandboxToolMap, createBrowserTools, createClarifyTool, createCronjobTool, createCuratedMemoryTool, createDelegateTool, createDreamingTool, createEditFileTool, createExecuteCodeTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createShellTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, editFileTool, findTool, formatSize, fuzzyFindText, generateDiffString, grepTool, invalidateSessionSearchIndexCache, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, restoreLineEndings, scanCronPrompt, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
36
+ export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, assertBrowserUrlAllowed, buildSandboxToolMap, createBrowserTools, createClarifyTool, createCreateShareTool, createCronjobTool, createCuratedMemoryTool, createDelegateTool, createDreamingTool, createEditFileTool, createExecuteCodeTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createShellTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, editFileTool, findTool, formatSize, fuzzyFindText, generateDiffString, grepTool, invalidateSessionSearchIndexCache, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, restoreLineEndings, scanCronPrompt, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
@@ -1,7 +1,7 @@
1
1
  import { checkFileSafety } from "../prompt/safety.js";
2
2
  import { resolvePathUnderWorkspace } from "./tool-paths.js";
3
- import { readFile } from "fs/promises";
4
3
  import { basename } from "node:path";
4
+ import { readFile } from "fs/promises";
5
5
  import { Type } from "@sinclair/typebox";
6
6
  //#region src/agent/tools/send-media.ts
7
7
  const SendMediaSchema = Type.Object({
@@ -2,9 +2,9 @@ import { resolveStateDir } from "../../config/paths-state.js";
2
2
  import { init_paths } from "../../config/paths.js";
3
3
  import { createSkillConfigManager } from "../skills/config.js";
4
4
  import { applyPatchToContent, atomicWriteUtf8, effectiveAgentWritePolicy, ensureCategorySegment, isPathInsideDir, maxSkillMdChars, maxSupportFileBytes, mutatableSkillOrNull, resolveCreateSkillDir, scanSkillDirOrError, validateSkillMdContent, validateSkillNameSegment, validateSupportingRelativePath } from "../skills/skill-manage-ops.js";
5
- import { readFile, rm } from "fs/promises";
6
5
  import { join } from "path";
7
6
  import { existsSync, rmSync } from "fs";
7
+ import { readFile, rm } from "fs/promises";
8
8
  import { Type } from "@sinclair/typebox";
9
9
  //#region src/agent/tools/skill-manage-tool.ts
10
10
  init_paths();
@@ -0,0 +1,41 @@
1
+ /**
2
+ * `workflow` — the AgentTool the parent model calls to spawn a fan-out run.
3
+ *
4
+ * Shape mirrors `delegate-tool`: factory builds a closure over deps; `execute`
5
+ * parses the script, instantiates the {@link DelegateSubagentRunner}, drives the
6
+ * {@link runWorkflow} runtime, and pushes a live text snapshot through
7
+ * `onUpdate` for streaming UIs (TUI, gateway console).
8
+ *
9
+ * Why this lives in `src/agent/tools/` (not under `src/agent/workflow/`):
10
+ * the runtime is reusable infrastructure; the AgentTool wrapping is a
11
+ * presentation concern that depends on the AgentToolsFactory wiring. Keeping
12
+ * the wrapper here matches how `delegate-tool` and `execute-code-tool` are
13
+ * organised today.
14
+ */
15
+ import type { AgentTool } from '@earendil-works/pi-agent-core';
16
+ import type { Api, Model } from '@earendil-works/pi-ai';
17
+ import type { Config } from '../../config/schema.js';
18
+ import type { MessageBus } from '../../infra/bus/index.js';
19
+ import type { BuildChildToolsOptions } from '../child-agent-factory.js';
20
+ import { type WorkflowCatalog } from '../workflow/index.js';
21
+ import type { ToolExecutorConfig } from './executor.js';
22
+ export type WorkflowToolInput = {
23
+ name?: string;
24
+ script?: string;
25
+ args?: unknown;
26
+ };
27
+ export interface WorkflowToolDeps {
28
+ workspace: string;
29
+ bus: MessageBus;
30
+ /** Returns the parent agent's primary model — subagents default to this. */
31
+ getSubagentModel: () => Model<Api>;
32
+ getConfig: () => Config | undefined;
33
+ /** Same injection point delegate-tool uses; supplied by AgentToolsFactory. */
34
+ buildChildTools: (opts: BuildChildToolsOptions) => AgentTool<any, any>[];
35
+ toolExecutorConfig?: Partial<ToolExecutorConfig>;
36
+ /** Catalog for `name` lookups (built-in + ~/.xopc/workflows/). */
37
+ catalog: WorkflowCatalog;
38
+ /** Per-call sessionKey lookup — used to record "last successful workflow" for /workflow save. */
39
+ getCurrentSessionKey?: () => string | undefined;
40
+ }
41
+ export declare function createWorkflowTool(deps: WorkflowToolDeps): AgentTool;