shadow-claw 1.26.0 → 1.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/.agents/skills/main/skill-creator/SKILL.md +39 -0
  2. package/.agents/skills/main/skill-creator/references/declarative-pipelines.md +44 -0
  3. package/.agents/skills/main/skill-creator/references/declarative-tools.md +35 -0
  4. package/.agents/skills/main/skill-creator/references/frontmatter-spec.md +50 -0
  5. package/.well-known/agent-skills/index.json +14 -0
  6. package/README.md +5 -3
  7. package/bin/build/build.mjs +146 -15
  8. package/bin/build/build.test.mjs +57 -0
  9. package/bin/cli.mjs +26 -0
  10. package/bin/commands/mcp.mjs +277 -55
  11. package/bin/commands/mcp.test.mjs +275 -1
  12. package/bin/commands/skills-index.mjs +328 -0
  13. package/bin/commands/skills-index.test.mjs +161 -0
  14. package/bin/site-config/utils/custom-elements/get-approved-custom-element-scripts.test.mjs +2 -0
  15. package/bin/site-config/utils/custom-elements/sanitize-embedded-custom-element-scripts.test.mjs +10 -1
  16. package/dist/lib/components/index.js +25 -25
  17. package/dist/lib/components/settings/shadow-claw-accounts.js +1 -1
  18. package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
  19. package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
  20. package/dist/lib/components/settings/shadow-claw-git.js +1 -1
  21. package/dist/lib/components/settings/shadow-claw-integrations.js +1 -1
  22. package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
  23. package/dist/lib/components/settings/shadow-claw-mcp-remote.js +1 -1
  24. package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
  25. package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
  26. package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
  27. package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
  28. package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
  29. package/dist/lib/components/shadow-claw-a2ui.js +1 -1
  30. package/dist/lib/components/shadow-claw-accounts.js +1 -1
  31. package/dist/lib/components/shadow-claw-channel-config.js +1 -1
  32. package/dist/lib/components/shadow-claw-channels.js +1 -1
  33. package/dist/lib/components/shadow-claw-chat.js +1 -1
  34. package/dist/lib/components/shadow-claw-control-plane.js +1 -1
  35. package/dist/lib/components/shadow-claw-conversations.js +1 -1
  36. package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
  37. package/dist/lib/components/shadow-claw-files.js +1 -1
  38. package/dist/lib/components/shadow-claw-git.js +1 -1
  39. package/dist/lib/components/shadow-claw-integrations.js +1 -1
  40. package/dist/lib/components/shadow-claw-llm.js +1 -1
  41. package/dist/lib/components/shadow-claw-mcp-remote.js +1 -1
  42. package/dist/lib/components/shadow-claw-networking.js +1 -1
  43. package/dist/lib/components/shadow-claw-page-header.js +1 -1
  44. package/dist/lib/components/shadow-claw-pages.js +1 -1
  45. package/dist/lib/components/shadow-claw-peerjs.js +1 -1
  46. package/dist/lib/components/shadow-claw-settings.js +1 -1
  47. package/dist/lib/components/shadow-claw-storage.js +1 -1
  48. package/dist/lib/components/shadow-claw-task-server.js +1 -1
  49. package/dist/lib/components/shadow-claw-tasks.js +1 -1
  50. package/dist/lib/components/shadow-claw-terminal.js +1 -1
  51. package/dist/lib/components/shadow-claw-tools.js +1 -1
  52. package/dist/lib/components/shadow-claw-webvm.js +1 -1
  53. package/dist/lib/components/shadow-claw.js +1 -1
  54. package/dist/lib/{configurePeerJs-CrlGan0m.js → configurePeerJs-oODzltaC.js} +2 -2
  55. package/dist/lib/{configurePeerJs-CrlGan0m.js.map → configurePeerJs-oODzltaC.js.map} +1 -1
  56. package/dist/lib/core/control-plane-client.d.ts +1 -0
  57. package/dist/lib/{downloadGroupFile-DboUjmp2.js → downloadGroupFile-DmcBQU1n.js} +2 -2
  58. package/dist/lib/{downloadGroupFile-DboUjmp2.js.map → downloadGroupFile-DmcBQU1n.js.map} +1 -1
  59. package/dist/lib/{file-viewer-BrK2Wxgh.js → file-viewer-C3YKnq_-.js} +4 -3
  60. package/dist/lib/{file-viewer-BrK2Wxgh.js.map → file-viewer-C3YKnq_-.js.map} +1 -1
  61. package/dist/lib/index.js +26 -26
  62. package/dist/lib/{initControlPlane-CsO4UR6_.js → initControlPlane-C2zURVIS.js} +86 -13
  63. package/dist/lib/initControlPlane-C2zURVIS.js.map +1 -0
  64. package/dist/lib/{markdown-eeSTFnMA.js → markdown-C6EHl9zs.js} +3 -3
  65. package/dist/lib/{markdown-eeSTFnMA.js.map → markdown-C6EHl9zs.js.map} +1 -1
  66. package/dist/lib/{orchestrator-CJvoC2Uu.js → orchestrator-CACLa_Ro.js} +7 -6
  67. package/dist/lib/{orchestrator-CJvoC2Uu.js.map → orchestrator-CACLa_Ro.js.map} +1 -1
  68. package/dist/lib/{orchestrator-DCfomsn9.js → orchestrator-KRjx0eba.js} +6 -534
  69. package/dist/lib/{orchestrator-DCfomsn9.js.map → orchestrator-KRjx0eba.js.map} +1 -1
  70. package/dist/lib/parsePath-DwC_YZjw.js +16 -0
  71. package/dist/lib/parsePath-DwC_YZjw.js.map +1 -0
  72. package/dist/lib/{peerjs-Dp02bXcG.js → peerjs-DFWOBcXf.js} +4 -4
  73. package/dist/lib/{peerjs-Dp02bXcG.js.map → peerjs-DFWOBcXf.js.map} +1 -1
  74. package/dist/lib/{readGroupFileBytes-Bve-e5e_.js → readGroupFileBytes-C8oOe8Iu.js} +3 -16
  75. package/dist/lib/readGroupFileBytes-C8oOe8Iu.js.map +1 -0
  76. package/dist/lib/security/custom-element-security.d.ts +8 -0
  77. package/dist/lib/server/control-plane-types.d.ts +1 -1
  78. package/dist/lib/{shadow-claw-D8xINM3c.js → shadow-claw-6UHdiy4a.js} +5 -5
  79. package/dist/lib/{shadow-claw-D8xINM3c.js.map → shadow-claw-6UHdiy4a.js.map} +1 -1
  80. package/dist/lib/{shadow-claw-a2ui-7rJqG4Ke.js → shadow-claw-a2ui-CpZUTzlh.js} +5 -4
  81. package/dist/lib/{shadow-claw-a2ui-7rJqG4Ke.js.map → shadow-claw-a2ui-CpZUTzlh.js.map} +1 -1
  82. package/dist/lib/{shadow-claw-accounts-CdruwN8A.js → shadow-claw-accounts-03oJ__XC.js} +2 -2
  83. package/dist/lib/{shadow-claw-accounts-CdruwN8A.js.map → shadow-claw-accounts-03oJ__XC.js.map} +1 -1
  84. package/dist/lib/{shadow-claw-channel-config-Bj0-Nk3t.js → shadow-claw-channel-config-DmfwJc6G.js} +3 -3
  85. package/dist/lib/{shadow-claw-channel-config-Bj0-Nk3t.js.map → shadow-claw-channel-config-DmfwJc6G.js.map} +1 -1
  86. package/dist/lib/{shadow-claw-channels-C_jI4KhP.js → shadow-claw-channels-1N6Jl-By.js} +3 -3
  87. package/dist/lib/{shadow-claw-channels-C_jI4KhP.js.map → shadow-claw-channels-1N6Jl-By.js.map} +1 -1
  88. package/dist/lib/{shadow-claw-chat-B16MspoP.js → shadow-claw-chat-BMoqQJRK.js} +10 -10
  89. package/dist/lib/{shadow-claw-chat-B16MspoP.js.map → shadow-claw-chat-BMoqQJRK.js.map} +1 -1
  90. package/dist/lib/{shadow-claw-control-plane-x8Ldid_h.js → shadow-claw-control-plane-UG0o7pCz.js} +6 -6
  91. package/dist/lib/{shadow-claw-control-plane-x8Ldid_h.js.map → shadow-claw-control-plane-UG0o7pCz.js.map} +1 -1
  92. package/dist/lib/{shadow-claw-conversations-Ct1kAYdB.js → shadow-claw-conversations-BwXep3iu.js} +4 -3
  93. package/dist/lib/{shadow-claw-conversations-Ct1kAYdB.js.map → shadow-claw-conversations-BwXep3iu.js.map} +1 -1
  94. package/dist/lib/{shadow-claw-file-viewer-BfDHHgpA.js → shadow-claw-file-viewer-DUxzVxDT.js} +14 -10
  95. package/dist/lib/shadow-claw-file-viewer-DUxzVxDT.js.map +1 -0
  96. package/dist/lib/{shadow-claw-files-EYhOPYIH.js → shadow-claw-files-DIREEnT2.js} +7 -7
  97. package/dist/lib/{shadow-claw-files-EYhOPYIH.js.map → shadow-claw-files-DIREEnT2.js.map} +1 -1
  98. package/dist/lib/{shadow-claw-git-tcSpT-P0.js → shadow-claw-git-Bg1SWgsF.js} +4 -4
  99. package/dist/lib/{shadow-claw-git-tcSpT-P0.js.map → shadow-claw-git-Bg1SWgsF.js.map} +1 -1
  100. package/dist/lib/{shadow-claw-integrations-NbcCx_ZI.js → shadow-claw-integrations-Ds-CLPhj.js} +2 -2
  101. package/dist/lib/{shadow-claw-integrations-NbcCx_ZI.js.map → shadow-claw-integrations-Ds-CLPhj.js.map} +1 -1
  102. package/dist/lib/{shadow-claw-llm-BazJdD5f.js → shadow-claw-llm-CazBrVpM.js} +3 -3
  103. package/dist/lib/{shadow-claw-llm-BazJdD5f.js.map → shadow-claw-llm-CazBrVpM.js.map} +1 -1
  104. package/dist/lib/{shadow-claw-mcp-remote-CYmhpg7a.js → shadow-claw-mcp-remote-CT5Q-54E.js} +2 -2
  105. package/dist/lib/{shadow-claw-mcp-remote-CYmhpg7a.js.map → shadow-claw-mcp-remote-CT5Q-54E.js.map} +1 -1
  106. package/dist/lib/{shadow-claw-networking-DImPxe0H.js → shadow-claw-networking-Df85tCbO.js} +2 -2
  107. package/dist/lib/{shadow-claw-networking-DImPxe0H.js.map → shadow-claw-networking-Df85tCbO.js.map} +1 -1
  108. package/dist/lib/{shadow-claw-page-header-CcHUfFUx.js → shadow-claw-page-header-Cti2fzf-.js} +2 -2
  109. package/dist/lib/{shadow-claw-page-header-CcHUfFUx.js.map → shadow-claw-page-header-Cti2fzf-.js.map} +1 -1
  110. package/dist/lib/{shadow-claw-pages-D54jF1Qq.js → shadow-claw-pages-BgPyIEZO.js} +15 -11
  111. package/dist/lib/shadow-claw-pages-BgPyIEZO.js.map +1 -0
  112. package/dist/lib/{shadow-claw-peerjs-B9-T8Nlx.js → shadow-claw-peerjs-xkBXILed.js} +3 -3
  113. package/dist/lib/{shadow-claw-peerjs-B9-T8Nlx.js.map → shadow-claw-peerjs-xkBXILed.js.map} +1 -1
  114. package/dist/lib/{shadow-claw-settings-Bt1VAe-1.js → shadow-claw-settings-CN89xRVU.js} +4 -4
  115. package/dist/lib/{shadow-claw-settings-Bt1VAe-1.js.map → shadow-claw-settings-CN89xRVU.js.map} +1 -1
  116. package/dist/lib/{shadow-claw-storage-CFOjGf1d.js → shadow-claw-storage-VnhcObCe.js} +3 -3
  117. package/dist/lib/{shadow-claw-storage-CFOjGf1d.js.map → shadow-claw-storage-VnhcObCe.js.map} +1 -1
  118. package/dist/lib/{shadow-claw-task-server-BiKa2GOm.js → shadow-claw-task-server-jgEC2hHB.js} +2 -2
  119. package/dist/lib/{shadow-claw-task-server-BiKa2GOm.js.map → shadow-claw-task-server-jgEC2hHB.js.map} +1 -1
  120. package/dist/lib/{shadow-claw-tasks-DDHd8W4d.js → shadow-claw-tasks-i_evIufy.js} +6 -6
  121. package/dist/lib/{shadow-claw-tasks-DDHd8W4d.js.map → shadow-claw-tasks-i_evIufy.js.map} +1 -1
  122. package/dist/lib/{shadow-claw-terminal-kB6_tWKz.js → shadow-claw-terminal-CwScROlu.js} +2 -2
  123. package/dist/lib/{shadow-claw-terminal-kB6_tWKz.js.map → shadow-claw-terminal-CwScROlu.js.map} +1 -1
  124. package/dist/lib/{shadow-claw-tools-DxXIm0ku.js → shadow-claw-tools-DD3fyXP4.js} +5 -4
  125. package/dist/lib/{shadow-claw-tools-DxXIm0ku.js.map → shadow-claw-tools-DD3fyXP4.js.map} +1 -1
  126. package/dist/lib/{shadow-claw-webvm-Dc8oo7ao.js → shadow-claw-webvm-DbJq4I3-.js} +2 -2
  127. package/dist/lib/{shadow-claw-webvm-Dc8oo7ao.js.map → shadow-claw-webvm-DbJq4I3-.js.map} +1 -1
  128. package/dist/lib/{syncWebMcpRegistration-jyRGbC9w.js → syncWebMcpRegistration-DNLnQ-jz.js} +3 -2
  129. package/dist/lib/{syncWebMcpRegistration-jyRGbC9w.js.map → syncWebMcpRegistration-DNLnQ-jz.js.map} +1 -1
  130. package/dist/lib/tools-DwwB9RBa.js +546 -0
  131. package/dist/lib/tools-DwwB9RBa.js.map +1 -0
  132. package/dist/lib/{trusted-types-CkLDpLiZ.js → trusted-types-Dx0RZlrd.js} +19 -8
  133. package/dist/lib/trusted-types-Dx0RZlrd.js.map +1 -0
  134. package/dist/lib/utils/index.js +1 -1
  135. package/dist/lib/utils/utils.js +1 -1
  136. package/dist/public/.well-known/agent-skills/index.json +14 -0
  137. package/dist/public/AGENTS.md +5 -3
  138. package/dist/public/README.md +5 -3
  139. package/dist/public/agent.worker.js +1 -1
  140. package/dist/public/{configurePeerJs-COcwE0E7.js → configurePeerJs-BqgeBjP7.js} +1 -1
  141. package/dist/public/custom-element-security-FU04Cq05.js +1 -0
  142. package/dist/public/dist-B9m1QM9v.js +58 -0
  143. package/dist/public/docs/README.md +31 -31
  144. package/dist/public/docs/example/article/index.html +1 -1
  145. package/dist/public/docs/publishing/index.html +1 -1
  146. package/dist/public/docs/skill-creator/index.html +1 -1
  147. package/dist/public/docs/subsystems/a2ui.md +11 -1
  148. package/dist/public/docs/subsystems/cli.md +29 -0
  149. package/dist/public/docs/subsystems/control-plane.md +8 -2
  150. package/dist/public/docs/subsystems/custom-element-security.md +19 -9
  151. package/dist/public/docs/subsystems/mcp-server.md +39 -15
  152. package/dist/public/docs/subsystems/skills.md +30 -0
  153. package/dist/public/docs/subsystems/webmcp.md +9 -0
  154. package/dist/public/downloadGroupFile-D8KRJGGL.js +1 -0
  155. package/dist/public/e2e/README.md +7 -4
  156. package/dist/public/{e2e-bridge-CHARpbpW.js → e2e-bridge-Ceqr5kGc.js} +1 -1
  157. package/dist/public/effect-BJCrpFdp.js +1 -0
  158. package/dist/public/file-viewer-C-6Jc_tb.js +1 -0
  159. package/dist/public/index.html +1 -1
  160. package/dist/public/index.js +1 -1
  161. package/dist/public/initControlPlane-BN9cWyO0.js +1 -0
  162. package/dist/public/main/index.html +1 -1
  163. package/dist/public/main/memory/index.html +1 -1
  164. package/dist/public/{markdown-1I3O6Mmd.js → markdown-C3M4OW_A.js} +1 -1
  165. package/dist/public/{orchestrator-Cl95w2vb.js → orchestrator-CMbCTjBf.js} +7 -7
  166. package/dist/public/{orchestrator-D-xlXG92.js → orchestrator-DHjdLtqa.js} +663 -663
  167. package/dist/public/peerjs-DUCKH-m9.js +1 -0
  168. package/dist/public/service-worker.js +1 -1
  169. package/dist/public/{shadow-claw-CaoKmIIB.js → shadow-claw-EAt2ml5Y.js} +3 -3
  170. package/dist/public/{shadow-claw-accounts-CJvYC4li.js → shadow-claw-accounts-xUOLBsQZ.js} +1 -1
  171. package/dist/public/{shadow-claw-channels-3K62sU5f.js → shadow-claw-channels-XsfuWFF8.js} +4 -4
  172. package/dist/public/{shadow-claw-chat-Cu2keU2I.js → shadow-claw-chat-CbSaOZ4q.js} +7 -7
  173. package/dist/public/{shadow-claw-control-plane-D1OwlQI_.js → shadow-claw-control-plane-DHvN3Ukg.js} +2 -2
  174. package/dist/public/{shadow-claw-conversations-DDtg3BEZ.js → shadow-claw-conversations-BWs5VVfs.js} +2 -2
  175. package/dist/public/{shadow-claw-file-viewer-BR__1z9S.js → shadow-claw-file-viewer-BWsoW5QS.js} +5 -4
  176. package/dist/public/{shadow-claw-files-BJSyZ-Bl.js → shadow-claw-files-CG7MqWiV.js} +8 -8
  177. package/dist/public/{shadow-claw-git-MAjhXRLc.js → shadow-claw-git-DBRPZNav.js} +6 -6
  178. package/dist/public/{shadow-claw-integrations-82UoFuDR.js → shadow-claw-integrations-BBVnO0Fc.js} +8 -8
  179. package/dist/public/{shadow-claw-llm-R8j0lwPP.js → shadow-claw-llm-DMvLgKXo.js} +2 -2
  180. package/dist/public/{shadow-claw-mcp-remote-BzZoz4LX.js → shadow-claw-mcp-remote-Bkx0gsmF.js} +2 -2
  181. package/dist/public/{shadow-claw-networking-DLEd9cNm.js → shadow-claw-networking-Dd8Rw31D.js} +2 -2
  182. package/dist/public/{shadow-claw-notifications-1vwR7TbT.js → shadow-claw-notifications-Dbevj-lq.js} +2 -2
  183. package/dist/public/{shadow-claw-page-header-DMKbkv3s.js → shadow-claw-page-header-BccSHItx.js} +1 -1
  184. package/dist/public/{shadow-claw-pages-CjyeIV__.js → shadow-claw-pages-3_lQAv0t.js} +4 -3
  185. package/dist/public/{shadow-claw-settings-BfbT4dBU.js → shadow-claw-settings-t8TIlgrM.js} +5 -5
  186. package/dist/public/{shadow-claw-storage-C-mWQQML.js → shadow-claw-storage-CfEXoSIE.js} +2 -2
  187. package/dist/public/{shadow-claw-task-server-D3lHp0Nc.js → shadow-claw-task-server-DxQSsgRZ.js} +2 -2
  188. package/dist/public/{shadow-claw-tasks-DVVWEm-c.js → shadow-claw-tasks-DNpicQwz.js} +14 -14
  189. package/dist/public/{shadow-claw-terminal-BwuTRp-O.js → shadow-claw-terminal-DpY6zU_r.js} +1 -1
  190. package/dist/public/{shadow-claw-toast-ClCwgzFG.js → shadow-claw-toast-BkrQIP-3.js} +1 -1
  191. package/dist/public/{shadow-claw-tools-zFLk2nbV.js → shadow-claw-tools-WSwWohnk.js} +2 -2
  192. package/dist/public/{shadow-claw-webvm-qR9X7fg7.js → shadow-claw-webvm-CP6oFjg5.js} +2 -2
  193. package/dist/public/syncWebMcpRegistration-DOn9gLnD.js +1 -0
  194. package/dist/public/toast-BXgUfbyh.js +1 -0
  195. package/dist/public/tools-DvckJZG2.js +1 -0
  196. package/dist/server.js +188 -188
  197. package/package.json +3 -1
  198. package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.stories.ts +1380 -93
  199. package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.ts +11 -6
  200. package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.test.ts +8 -1
  201. package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.ts +13 -5
  202. package/src/components/shadow-claw-pages/utils/buildHtmlPageSrcdoc.ts +13 -5
  203. package/src/core/control-plane-client.ts +15 -0
  204. package/src/core/utils/initControlPlane.test.ts +187 -0
  205. package/src/core/utils/initControlPlane.ts +194 -20
  206. package/src/security/custom-element-security.test.ts +51 -0
  207. package/src/security/custom-element-security.ts +33 -15
  208. package/src/server/control-plane-types.ts +1 -0
  209. package/src/server/control-plane.test.ts +69 -0
  210. package/src/server/control-plane.ts +45 -3
  211. package/src/server/mcp/tools/built-in-tools.ts +80 -5
  212. package/src/server/mcp/tools/client-tool-relay.ts +183 -26
  213. package/src/server/mcp/tools/mcp-tools.test.ts +140 -0
  214. package/src/server/middleware/static-files.test.ts +142 -0
  215. package/src/server/middleware/static-files.ts +66 -8
  216. package/src/testing/jest-setup.ts +1 -0
  217. package/src/worker/utils/handleMessage.ts +4 -1
  218. package/dist/lib/initControlPlane-CsO4UR6_.js.map +0 -1
  219. package/dist/lib/readGroupFileBytes-Bve-e5e_.js.map +0 -1
  220. package/dist/lib/shadow-claw-file-viewer-BfDHHgpA.js.map +0 -1
  221. package/dist/lib/shadow-claw-pages-D54jF1Qq.js.map +0 -1
  222. package/dist/lib/trusted-types-CkLDpLiZ.js.map +0 -1
  223. package/dist/public/custom-element-security-NCqQ5lmC.js +0 -1
  224. package/dist/public/downloadGroupFile-G0BZQgQg.js +0 -1
  225. package/dist/public/effect-rHYr4nfu.js +0 -1
  226. package/dist/public/file-viewer-8PdCURDD.js +0 -1
  227. package/dist/public/initControlPlane-CcGXax0A.js +0 -1
  228. package/dist/public/peerjs-BZdxWQFv.js +0 -1
  229. package/dist/public/syncWebMcpRegistration-DD42YsYV.js +0 -1
  230. package/dist/public/toast-HAq8XWFj.js +0 -58
@@ -0,0 +1,546 @@
1
+ import { n as __exportAll } from "./rolldown-runtime-DZ8SGSJo.js";
2
+ import { t as Signal } from "./dist-Bxg3C_zy.js";
3
+ import { t as getGroupDir } from "./getGroupDir-m0f-ekgX.js";
4
+ import { o as DEFAULT_GROUP_ID, r as CONFIG_KEYS } from "./config--CFrw3J3.js";
5
+ import { t as getConfig } from "./getConfig-BxxXMyuM.js";
6
+ import { t as parsePath } from "./parsePath-DwC_YZjw.js";
7
+ import { t as setConfig } from "./setConfig-BFED5CXn.js";
8
+ import { t as TOOL_DEFINITIONS } from "./tools-DBaMRiEu.js";
9
+ import "./tools-D4Pp-nUw.js";
10
+
11
+ //#region src/storage/readGroupFile.ts
12
+ /**
13
+ * Read a file from a group's workspace.
14
+ */
15
+ async function readGroupFile(db, groupId, filePath) {
16
+ const groupDir = await getGroupDir(db, groupId);
17
+ const { dirs, filename } = parsePath(filePath);
18
+ let dir = groupDir;
19
+ for (const seg of dirs) dir = await dir.getDirectoryHandle(seg);
20
+ const fileHandle = await dir.getFileHandle(filename);
21
+ try {
22
+ const syncHandle = await fileHandle.createSyncAccessHandle();
23
+ const size = syncHandle.getSize();
24
+ const buf = new Uint8Array(size);
25
+ syncHandle.read(buf, { at: 0 });
26
+ syncHandle.close();
27
+ return new TextDecoder("utf-8").decode(buf);
28
+ } catch {
29
+ return (await fileHandle.getFile()).text();
30
+ }
31
+ }
32
+
33
+ //#endregion
34
+ //#region src/subsystems/tools/builtin-profiles.ts
35
+ /**
36
+ * Built-in profile optimized for Gemini Nano (Prompt API).
37
+ * Minimizes context consumption so Nano has maximum tokens for generation.
38
+ */
39
+ const DEFAULT_BUILTIN_PROFILE = {
40
+ id: "__builtin_default",
41
+ name: "Default",
42
+ providerId: "prompt_api",
43
+ enabledToolNames: [
44
+ "javascript",
45
+ "list_files",
46
+ "open_file",
47
+ "read_file",
48
+ "write_file"
49
+ ],
50
+ customTools: [],
51
+ systemPromptOverride: "You are a helpful coding assistant.\nContent intended to be rendered as a `Page` (HTML or Markdown) SHOULD include frontmatter (title, created, updated, and slug).\nHTML content intended to be rendered as a `Page` SHOULD USE `<article><h2>${subTitle}</h2>...</article>` for its main body content."
52
+ };
53
+
54
+ //#endregion
55
+ //#region src/subsystems/tools/declarative.ts
56
+ const TOOL_NAME_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
57
+ function parseDeclarativeTool(path, value) {
58
+ if (!value || typeof value !== "object") throw new Error(`Tool at ${path} must be a JSON object`);
59
+ const candidate = value;
60
+ const name = typeof candidate.name === "string" ? candidate.name.trim() : "";
61
+ const description = typeof candidate.description === "string" ? candidate.description.trim() : "";
62
+ const inputSchema = candidate.input_schema ?? candidate.parameters;
63
+ const execution = candidate.execution ?? candidate.evaluation;
64
+ if (!TOOL_NAME_PATTERN.test(name)) throw new Error(`Tool name is invalid: ${name || "(missing)"}`);
65
+ if (!description) throw new Error(`Tool ${name} requires a description`);
66
+ if (!inputSchema || typeof inputSchema !== "object") throw new Error(`Tool ${name} requires input_schema`);
67
+ if (!execution || typeof execution !== "object") throw new Error(`Tool ${name} requires execution`);
68
+ const parsedExecution = execution;
69
+ const type = parsedExecution.type;
70
+ if (type !== "bash" && type !== "javascript" && type !== "tool") throw new Error(`Tool ${name} execution type must be bash, javascript, or tool`);
71
+ if (type === "tool") {
72
+ if (typeof parsedExecution.name !== "string" || !TOOL_NAME_PATTERN.test(parsedExecution.name)) throw new Error(`Tool ${name} execution requires a valid tool name`);
73
+ return {
74
+ name,
75
+ description,
76
+ input_schema: inputSchema,
77
+ execution: {
78
+ type,
79
+ name: parsedExecution.name,
80
+ ...parsedExecution.input && typeof parsedExecution.input === "object" ? { input: parsedExecution.input } : {}
81
+ },
82
+ path
83
+ };
84
+ }
85
+ const sourceKey = type === "bash" ? "command" : "code";
86
+ const source = parsedExecution[sourceKey] ?? parsedExecution.expression;
87
+ if (typeof source !== "string" || source.trim() === "") throw new Error(`Tool ${name} execution requires ${sourceKey}`);
88
+ return {
89
+ name,
90
+ description,
91
+ input_schema: inputSchema,
92
+ execution: {
93
+ type,
94
+ [sourceKey]: source
95
+ },
96
+ path
97
+ };
98
+ }
99
+ async function loadDeclarativeTools(db, groupId = DEFAULT_GROUP_ID) {
100
+ const tools = [];
101
+ const diagnostics = [];
102
+ const groupIdsToScan = groupId === "br:main" ? [DEFAULT_GROUP_ID] : [groupId, DEFAULT_GROUP_ID];
103
+ for (const targetGroupId of groupIdsToScan) try {
104
+ const root = await getGroupDir(db, targetGroupId);
105
+ const paths = [];
106
+ async function visit(directory, relativePath) {
107
+ for await (const [name, handle] of directory.entries()) {
108
+ const childPath = `${relativePath}/${name}`;
109
+ if (handle.kind === "directory") await visit(handle, childPath);
110
+ else if (name.endsWith(".json") && childPath.startsWith(".agents/tools/")) paths.push(childPath);
111
+ }
112
+ }
113
+ try {
114
+ await visit(await (await root.getDirectoryHandle(".agents")).getDirectoryHandle("tools"), ".agents/tools");
115
+ } catch {
116
+ continue;
117
+ }
118
+ for (const path of paths.sort()) try {
119
+ const parsedTool = parseDeclarativeTool(path, JSON.parse(await readGroupFile(db, targetGroupId, path)));
120
+ if (!tools.some((t) => t.name === parsedTool.name)) tools.push(parsedTool);
121
+ } catch (error) {
122
+ diagnostics.push(error instanceof Error ? error.message : String(error));
123
+ }
124
+ } catch {}
125
+ return {
126
+ tools,
127
+ diagnostics
128
+ };
129
+ }
130
+ async function findDeclarativeTool(db, groupId = DEFAULT_GROUP_ID, name) {
131
+ try {
132
+ const { tools } = await loadDeclarativeTools(db, groupId);
133
+ const tool = tools.find((t) => t.name === name) || null;
134
+ if (!tool) return null;
135
+ const rawEnabled = await getConfig(db, CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED);
136
+ if (Array.isArray(rawEnabled) && !rawEnabled.includes(name)) return null;
137
+ return tool;
138
+ } catch {
139
+ return null;
140
+ }
141
+ }
142
+
143
+ //#endregion
144
+ //#region src/stores/tools.ts
145
+ var tools_exports = /* @__PURE__ */ __exportAll({
146
+ ToolsStore: () => ToolsStore,
147
+ toolsStore: () => toolsStore
148
+ });
149
+ var ToolsStore = class {
150
+ _activeProfile;
151
+ _activeProfileId;
152
+ _allTools;
153
+ _customTools;
154
+ _declarativeTools;
155
+ _declarativeToolNamesEnabled;
156
+ _enabledDeclarativeTools;
157
+ _enabledToolNames;
158
+ _enabledTools;
159
+ _profiles;
160
+ _systemPromptOverride;
161
+ _webSearchProxyUrl;
162
+ _webSearchUrl;
163
+ _webSearchUseProxy;
164
+ _searchFilesMaxFileBytes;
165
+ _searchFilesMaxFilesVisited;
166
+ _searchFilesSkipDirs;
167
+ constructor() {
168
+ this._enabledToolNames = new Signal.State(new Set(DEFAULT_BUILTIN_PROFILE.enabledToolNames));
169
+ this._customTools = new Signal.State([]);
170
+ this._declarativeTools = new Signal.State([]);
171
+ this._declarativeToolNamesEnabled = new Signal.State(null);
172
+ this._systemPromptOverride = new Signal.State("");
173
+ this._profiles = new Signal.State([]);
174
+ this._activeProfileId = new Signal.State(DEFAULT_BUILTIN_PROFILE.id);
175
+ this._webSearchUseProxy = new Signal.State(false);
176
+ this._webSearchProxyUrl = new Signal.State("/proxy");
177
+ this._webSearchUrl = new Signal.State("https://html.duckduckgo.com/html/?q={query}");
178
+ this._searchFilesMaxFileBytes = new Signal.State(512 * 1024);
179
+ this._searchFilesMaxFilesVisited = new Signal.State(1e3);
180
+ this._searchFilesSkipDirs = new Signal.State(".git,node_modules,dist,dist-electron,.cache,.nx,.turbo,__pycache__,.venv,venv");
181
+ this._allTools = new Signal.Computed(() => [...TOOL_DEFINITIONS, ...this._customTools.get()]);
182
+ this._enabledTools = new Signal.Computed(() => {
183
+ const enabled = this._enabledToolNames.get();
184
+ return this._allTools.get().filter((t) => enabled.has(t.name));
185
+ });
186
+ this._enabledDeclarativeTools = new Signal.Computed(() => {
187
+ const tools = this._declarativeTools.get();
188
+ const enabledSet = this._declarativeToolNamesEnabled.get();
189
+ if (enabledSet === null) return tools;
190
+ return tools.filter((t) => enabledSet.has(t.name));
191
+ });
192
+ this._activeProfile = new Signal.Computed(() => {
193
+ const id = this._activeProfileId.get();
194
+ if (!id) return null;
195
+ if (DEFAULT_BUILTIN_PROFILE.id === id) return DEFAULT_BUILTIN_PROFILE;
196
+ return this._profiles.get().find((p) => p.id === id) || null;
197
+ });
198
+ }
199
+ get activeProfile() {
200
+ return this._activeProfile.get();
201
+ }
202
+ get activeProfileId() {
203
+ return this._activeProfileId.get();
204
+ }
205
+ get allTools() {
206
+ return this._allTools.get();
207
+ }
208
+ get customTools() {
209
+ return this._customTools.get();
210
+ }
211
+ get declarativeTools() {
212
+ return this._declarativeTools.get();
213
+ }
214
+ get declarativeToolNamesEnabled() {
215
+ return this._declarativeToolNamesEnabled.get();
216
+ }
217
+ get enabledDeclarativeTools() {
218
+ return this._enabledDeclarativeTools.get();
219
+ }
220
+ get enabledToolNames() {
221
+ return this._enabledToolNames.get();
222
+ }
223
+ get enabledTools() {
224
+ return this._enabledTools.get();
225
+ }
226
+ isDeclarativeToolEnabled(name) {
227
+ const enabledSet = this._declarativeToolNamesEnabled.get();
228
+ if (enabledSet === null) return true;
229
+ return enabledSet.has(name);
230
+ }
231
+ async refreshDeclarativeTools(db, groupId) {
232
+ try {
233
+ const res = await loadDeclarativeTools(db, groupId || "br:main");
234
+ const allBuiltInAndCustom = this.allTools;
235
+ const declTools = (res?.tools || []).filter((dt) => !allBuiltInAndCustom.some((bt) => bt.name === dt.name));
236
+ const current = this._declarativeTools.get();
237
+ if (!(current.length === declTools.length && current.every((t, i) => t.name === declTools[i].name && t.description === declTools[i].description && JSON.stringify(t.execution) === JSON.stringify(declTools[i].execution)))) this._declarativeTools.set(declTools);
238
+ return declTools;
239
+ } catch {
240
+ if (this._declarativeTools.get().length > 0) this._declarativeTools.set([]);
241
+ return [];
242
+ }
243
+ }
244
+ async setDeclarativeToolEnabled(db, toolName, enabled) {
245
+ const currentEnabled = this._declarativeToolNamesEnabled.get();
246
+ const allDeclTools = this._declarativeTools.get();
247
+ const nextSet = new Set(currentEnabled === null ? allDeclTools.map((t) => t.name) : currentEnabled);
248
+ if (enabled) nextSet.add(toolName);
249
+ else nextSet.delete(toolName);
250
+ this._declarativeToolNamesEnabled.set(nextSet);
251
+ await setConfig(db, CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED, Array.from(nextSet));
252
+ }
253
+ async setAllDeclarativeEnabled(db, toolNames) {
254
+ const nextSet = new Set(toolNames);
255
+ this._declarativeToolNamesEnabled.set(nextSet);
256
+ await setConfig(db, CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED, toolNames);
257
+ }
258
+ /**
259
+ * Export tools config as JSON for backup.
260
+ */
261
+ exportBackup() {
262
+ return JSON.stringify({
263
+ enabledTools: [...this._enabledToolNames.get()],
264
+ customTools: this._customTools.get(),
265
+ declarativeToolsEnabled: this._declarativeToolNamesEnabled.get() ? Array.from(this._declarativeToolNamesEnabled.get()) : null,
266
+ systemPromptOverride: this._systemPromptOverride.get(),
267
+ profiles: this._profiles.get(),
268
+ activeProfileId: this._activeProfileId.get(),
269
+ webSearchUseProxy: this._webSearchUseProxy.get(),
270
+ webSearchProxyUrl: this._webSearchProxyUrl.get(),
271
+ webSearchUrl: this._webSearchUrl.get(),
272
+ searchFilesMaxFileBytes: this._searchFilesMaxFileBytes.get(),
273
+ searchFilesMaxFilesVisited: this._searchFilesMaxFilesVisited.get(),
274
+ searchFilesSkipDirs: this._searchFilesSkipDirs.get()
275
+ }, null, 2);
276
+ }
277
+ findProfilesForProvider(providerId, model) {
278
+ return this.profiles.filter((p) => {
279
+ if (p.providerId && p.providerId !== providerId) return false;
280
+ if (p.model && p.model !== model) return false;
281
+ return true;
282
+ });
283
+ }
284
+ get profiles() {
285
+ return [DEFAULT_BUILTIN_PROFILE, ...this._profiles.get()];
286
+ }
287
+ get systemPromptOverride() {
288
+ return this._systemPromptOverride.get();
289
+ }
290
+ get webSearchProxyUrl() {
291
+ return this._webSearchProxyUrl.get();
292
+ }
293
+ get webSearchUrl() {
294
+ return this._webSearchUrl.get();
295
+ }
296
+ get webSearchUseProxy() {
297
+ return this._webSearchUseProxy.get();
298
+ }
299
+ get searchFilesMaxFileBytes() {
300
+ return this._searchFilesMaxFileBytes.get();
301
+ }
302
+ get searchFilesMaxFilesVisited() {
303
+ return this._searchFilesMaxFilesVisited.get();
304
+ }
305
+ /** Comma-separated list of directory names to skip when walking the workspace. */
306
+ get searchFilesSkipDirs() {
307
+ return this._searchFilesSkipDirs.get();
308
+ }
309
+ /** Parsed Set of directory names to skip — derived from the comma-separated string. */
310
+ get searchFilesSkipDirsSet() {
311
+ return new Set(this._searchFilesSkipDirs.get().split(",").map((s) => s.trim()).filter(Boolean));
312
+ }
313
+ async activateProfile(db, profileId) {
314
+ const profile = this.profiles.find((p) => p.id === profileId);
315
+ if (!profile) return;
316
+ this._activeProfileId.set(profileId);
317
+ this._enabledToolNames.set(new Set(profile.enabledToolNames));
318
+ this._customTools.set(profile.customTools);
319
+ this._systemPromptOverride.set(profile.systemPromptOverride || "");
320
+ await Promise.all([
321
+ setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, profileId),
322
+ setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, profile.enabledToolNames),
323
+ setConfig(db, CONFIG_KEYS.CUSTOM_TOOLS, profile.customTools),
324
+ setConfig(db, CONFIG_KEYS.SYSTEM_PROMPT_OVERRIDE, profile.systemPromptOverride || "")
325
+ ]);
326
+ }
327
+ async addCustomTool(db, tool) {
328
+ const tools = [...this._customTools.get(), tool];
329
+ this._customTools.set(tools);
330
+ const enabled = new Set(this._enabledToolNames.get());
331
+ enabled.add(tool.name);
332
+ this._enabledToolNames.set(enabled);
333
+ await Promise.all([setConfig(db, CONFIG_KEYS.CUSTOM_TOOLS, tools), setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, [...enabled])]);
334
+ }
335
+ async addProfile(db, profile) {
336
+ const profiles = [...this._profiles.get(), profile];
337
+ this._profiles.set(profiles);
338
+ await setConfig(db, CONFIG_KEYS.TOOL_PROFILES, profiles);
339
+ }
340
+ async cloneTool(db, sourceToolName, newToolName, newDescription) {
341
+ const source = this.allTools.find((t) => t.name === sourceToolName);
342
+ if (!source) return false;
343
+ if (this.allTools.some((t) => t.name === newToolName)) return false;
344
+ const cloned = {
345
+ name: newToolName,
346
+ description: newDescription || source.description,
347
+ input_schema: JSON.parse(JSON.stringify(source.input_schema))
348
+ };
349
+ await this.addCustomTool(db, cloned);
350
+ return true;
351
+ }
352
+ async deactivateProfile(db) {
353
+ this._activeProfileId.set(null);
354
+ await setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, null);
355
+ }
356
+ async deleteProfile(db, profileId) {
357
+ if (profileId === DEFAULT_BUILTIN_PROFILE.id) return;
358
+ const profiles = this._profiles.get().filter((p) => p.id !== profileId);
359
+ this._profiles.set(profiles);
360
+ if (this._activeProfileId.get() === profileId) {
361
+ this._activeProfileId.set(null);
362
+ await setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, null);
363
+ }
364
+ await setConfig(db, CONFIG_KEYS.TOOL_PROFILES, profiles);
365
+ }
366
+ async importBackup(db, json) {
367
+ const data = JSON.parse(json);
368
+ if (Array.isArray(data.enabledTools)) {
369
+ this._enabledToolNames.set(new Set(data.enabledTools));
370
+ await setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, data.enabledTools);
371
+ }
372
+ if (Array.isArray(data.customTools)) {
373
+ this._customTools.set(data.customTools);
374
+ await setConfig(db, CONFIG_KEYS.CUSTOM_TOOLS, data.customTools);
375
+ }
376
+ if (typeof data.systemPromptOverride === "string") {
377
+ this._systemPromptOverride.set(data.systemPromptOverride);
378
+ await setConfig(db, CONFIG_KEYS.SYSTEM_PROMPT_OVERRIDE, data.systemPromptOverride);
379
+ }
380
+ if (Array.isArray(data.profiles)) {
381
+ this._profiles.set(data.profiles);
382
+ await setConfig(db, CONFIG_KEYS.TOOL_PROFILES, data.profiles);
383
+ }
384
+ if (typeof data.activeProfileId === "string" || data.activeProfileId === null) {
385
+ this._activeProfileId.set(data.activeProfileId);
386
+ await setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, data.activeProfileId);
387
+ }
388
+ if (typeof data.webSearchUseProxy === "boolean") {
389
+ this._webSearchUseProxy.set(data.webSearchUseProxy);
390
+ await setConfig(db, CONFIG_KEYS.WEB_SEARCH_USE_PROXY, data.webSearchUseProxy ? "true" : "false");
391
+ }
392
+ if (typeof data.webSearchProxyUrl === "string") {
393
+ this._webSearchProxyUrl.set(data.webSearchProxyUrl);
394
+ await setConfig(db, CONFIG_KEYS.WEB_SEARCH_PROXY_URL, data.webSearchProxyUrl);
395
+ }
396
+ if (typeof data.webSearchUrl === "string") {
397
+ this._webSearchUrl.set(data.webSearchUrl);
398
+ await setConfig(db, CONFIG_KEYS.WEB_SEARCH_URL, data.webSearchUrl);
399
+ }
400
+ if (typeof data.searchFilesMaxFileBytes === "number" && data.searchFilesMaxFileBytes > 0) {
401
+ this._searchFilesMaxFileBytes.set(data.searchFilesMaxFileBytes);
402
+ await setConfig(db, CONFIG_KEYS.SEARCH_FILES_MAX_FILE_BYTES, String(data.searchFilesMaxFileBytes));
403
+ }
404
+ if (typeof data.searchFilesMaxFilesVisited === "number" && data.searchFilesMaxFilesVisited > 0) {
405
+ this._searchFilesMaxFilesVisited.set(data.searchFilesMaxFilesVisited);
406
+ await setConfig(db, CONFIG_KEYS.SEARCH_FILES_MAX_FILES_VISITED, String(data.searchFilesMaxFilesVisited));
407
+ }
408
+ if (typeof data.searchFilesSkipDirs === "string") {
409
+ this._searchFilesSkipDirs.set(data.searchFilesSkipDirs);
410
+ await setConfig(db, CONFIG_KEYS.SEARCH_FILES_SKIP_DIRS, data.searchFilesSkipDirs);
411
+ }
412
+ if (Array.isArray(data.declarativeToolsEnabled)) {
413
+ this._declarativeToolNamesEnabled.set(new Set(data.declarativeToolsEnabled));
414
+ await setConfig(db, CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED, data.declarativeToolsEnabled);
415
+ } else if (data.declarativeToolsEnabled === null) {
416
+ this._declarativeToolNamesEnabled.set(null);
417
+ await setConfig(db, CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED, null);
418
+ }
419
+ }
420
+ /**
421
+ * Load persisted tool config from IndexedDB.
422
+ */
423
+ async load(db) {
424
+ const [enabledRaw, customRaw, promptOverride, profilesRaw, activeProfileIdRaw, webSearchUseProxyRaw, webSearchProxyUrlRaw, webSearchUrlRaw, searchFilesMaxFileBytesRaw, searchFilesMaxFilesVisitedRaw, searchFilesSkipDirsRaw, declarativeEnabledRaw] = await Promise.all([
425
+ getConfig(db, CONFIG_KEYS.ENABLED_TOOLS),
426
+ getConfig(db, CONFIG_KEYS.CUSTOM_TOOLS),
427
+ getConfig(db, CONFIG_KEYS.SYSTEM_PROMPT_OVERRIDE),
428
+ getConfig(db, CONFIG_KEYS.TOOL_PROFILES),
429
+ getConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE),
430
+ getConfig(db, CONFIG_KEYS.WEB_SEARCH_USE_PROXY),
431
+ getConfig(db, CONFIG_KEYS.WEB_SEARCH_PROXY_URL),
432
+ getConfig(db, CONFIG_KEYS.WEB_SEARCH_URL),
433
+ getConfig(db, CONFIG_KEYS.SEARCH_FILES_MAX_FILE_BYTES),
434
+ getConfig(db, CONFIG_KEYS.SEARCH_FILES_MAX_FILES_VISITED),
435
+ getConfig(db, CONFIG_KEYS.SEARCH_FILES_SKIP_DIRS),
436
+ getConfig(db, CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED)
437
+ ]);
438
+ if (Array.isArray(enabledRaw)) this._enabledToolNames.set(new Set(enabledRaw));
439
+ if (Array.isArray(customRaw)) this._customTools.set(customRaw);
440
+ if (Array.isArray(declarativeEnabledRaw)) this._declarativeToolNamesEnabled.set(new Set(declarativeEnabledRaw));
441
+ if (typeof promptOverride === "string") this._systemPromptOverride.set(promptOverride);
442
+ if (Array.isArray(profilesRaw)) this._profiles.set(profilesRaw);
443
+ if (typeof activeProfileIdRaw === "string") this._activeProfileId.set(activeProfileIdRaw);
444
+ if (webSearchUseProxyRaw !== null && webSearchUseProxyRaw !== void 0) {
445
+ const strVal = String(webSearchUseProxyRaw).toLowerCase();
446
+ this._webSearchUseProxy.set(strVal === "true" || strVal === "1");
447
+ }
448
+ if (typeof webSearchProxyUrlRaw === "string" && webSearchProxyUrlRaw.trim().length > 0) this._webSearchProxyUrl.set(webSearchProxyUrlRaw.trim());
449
+ if (typeof webSearchUrlRaw === "string" && webSearchUrlRaw.trim().length > 0) this._webSearchUrl.set(webSearchUrlRaw.trim());
450
+ if (searchFilesMaxFileBytesRaw !== null && searchFilesMaxFileBytesRaw !== void 0) {
451
+ const n = Number(searchFilesMaxFileBytesRaw);
452
+ if (Number.isFinite(n) && n > 0) this._searchFilesMaxFileBytes.set(n);
453
+ }
454
+ if (searchFilesMaxFilesVisitedRaw !== null && searchFilesMaxFilesVisitedRaw !== void 0) {
455
+ const n = Number(searchFilesMaxFilesVisitedRaw);
456
+ if (Number.isFinite(n) && n > 0) this._searchFilesMaxFilesVisited.set(n);
457
+ }
458
+ if (typeof searchFilesSkipDirsRaw === "string" && searchFilesSkipDirsRaw.trim().length > 0) this._searchFilesSkipDirs.set(searchFilesSkipDirsRaw.trim());
459
+ }
460
+ async setWebSearchProxyUrl(db, proxyUrl) {
461
+ const trimmed = proxyUrl.trim() || "/proxy";
462
+ this._webSearchProxyUrl.set(trimmed);
463
+ await setConfig(db, CONFIG_KEYS.WEB_SEARCH_PROXY_URL, trimmed);
464
+ }
465
+ async setWebSearchUrl(db, url) {
466
+ const trimmed = url.trim() || "https://html.duckduckgo.com/html/?q={query}";
467
+ this._webSearchUrl.set(trimmed);
468
+ await setConfig(db, CONFIG_KEYS.WEB_SEARCH_URL, trimmed);
469
+ }
470
+ async setWebSearchUseProxy(db, useProxy) {
471
+ const enabled = !!useProxy;
472
+ this._webSearchUseProxy.set(enabled);
473
+ await setConfig(db, CONFIG_KEYS.WEB_SEARCH_USE_PROXY, enabled ? "true" : "false");
474
+ }
475
+ async setSearchFilesMaxFileBytes(db, bytes) {
476
+ const clamped = Math.max(1, Math.round(bytes));
477
+ this._searchFilesMaxFileBytes.set(clamped);
478
+ await setConfig(db, CONFIG_KEYS.SEARCH_FILES_MAX_FILE_BYTES, String(clamped));
479
+ }
480
+ async setSearchFilesMaxFilesVisited(db, count) {
481
+ const clamped = Math.max(1, Math.round(count));
482
+ this._searchFilesMaxFilesVisited.set(clamped);
483
+ await setConfig(db, CONFIG_KEYS.SEARCH_FILES_MAX_FILES_VISITED, String(clamped));
484
+ }
485
+ async setSearchFilesSkipDirs(db, dirs) {
486
+ const trimmed = dirs.trim();
487
+ this._searchFilesSkipDirs.set(trimmed);
488
+ await setConfig(db, CONFIG_KEYS.SEARCH_FILES_SKIP_DIRS, trimmed);
489
+ }
490
+ async removeCustomTool(db, toolName) {
491
+ const tools = this._customTools.get().filter((t) => t.name !== toolName);
492
+ this._customTools.set(tools);
493
+ const enabled = new Set(this._enabledToolNames.get());
494
+ enabled.delete(toolName);
495
+ this._enabledToolNames.set(enabled);
496
+ await Promise.all([setConfig(db, CONFIG_KEYS.CUSTOM_TOOLS, tools), setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, [...enabled])]);
497
+ }
498
+ async saveToActiveProfile(db) {
499
+ const id = this._activeProfileId.get();
500
+ if (!id) return;
501
+ const profile = this._profiles.get().find((p) => p.id === id);
502
+ if (!profile) return;
503
+ const updated = {
504
+ ...profile,
505
+ enabledToolNames: [...this._enabledToolNames.get()],
506
+ customTools: [...this._customTools.get()],
507
+ systemPromptOverride: this._systemPromptOverride.get()
508
+ };
509
+ await this.updateProfile(db, updated);
510
+ }
511
+ async setAllEnabled(db, toolNames) {
512
+ this._enabledToolNames.set(new Set(toolNames));
513
+ const saves = [setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, toolNames)];
514
+ if (this._activeProfileId.get()) {
515
+ this._activeProfileId.set(null);
516
+ saves.push(setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, null));
517
+ }
518
+ await Promise.all(saves);
519
+ }
520
+ async setSystemPromptOverride(db, override) {
521
+ this._systemPromptOverride.set(override);
522
+ await setConfig(db, CONFIG_KEYS.SYSTEM_PROMPT_OVERRIDE, override);
523
+ }
524
+ async setToolEnabled(db, toolName, enabled) {
525
+ const current = new Set(this._enabledToolNames.get());
526
+ if (enabled) current.add(toolName);
527
+ else current.delete(toolName);
528
+ this._enabledToolNames.set(current);
529
+ const saves = [setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, [...current])];
530
+ if (this._activeProfileId.get()) {
531
+ this._activeProfileId.set(null);
532
+ saves.push(setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, null));
533
+ }
534
+ await Promise.all(saves);
535
+ }
536
+ async updateProfile(db, profile) {
537
+ const profiles = this._profiles.get().map((p) => p.id === profile.id ? profile : p);
538
+ this._profiles.set(profiles);
539
+ await setConfig(db, CONFIG_KEYS.TOOL_PROFILES, profiles);
540
+ }
541
+ };
542
+ const toolsStore = new ToolsStore();
543
+
544
+ //#endregion
545
+ export { DEFAULT_BUILTIN_PROFILE as a, loadDeclarativeTools as i, tools_exports as n, readGroupFile as o, findDeclarativeTool as r, toolsStore as t };
546
+ //# sourceMappingURL=tools-DwwB9RBa.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools-DwwB9RBa.js","names":[],"sources":["../../src/storage/readGroupFile.ts","../../src/subsystems/tools/builtin-profiles.ts","../../src/subsystems/tools/declarative.ts","../../src/stores/tools.ts"],"sourcesContent":["import { getGroupDir } from \"./getGroupDir.js\";\nimport { parsePath } from \"./parsePath.js\";\nimport type { ShadowClawDatabase } from \"../db/types.js\";\n\n/**\n * Read a file from a group's workspace.\n */\nexport async function readGroupFile(\n db: ShadowClawDatabase,\n groupId: string,\n filePath: string,\n): Promise<string> {\n const groupDir = await getGroupDir(db, groupId);\n const { dirs, filename } = parsePath(filePath);\n\n let dir = groupDir;\n for (const seg of dirs) {\n dir = await dir.getDirectoryHandle(seg);\n }\n\n // Re-acquire file handle and file object to force filesystem re-stat\n const fileHandle = await dir.getFileHandle(filename);\n\n try {\n const syncHandle = await (fileHandle as any).createSyncAccessHandle();\n const size = syncHandle.getSize();\n const buf = new Uint8Array(size);\n\n syncHandle.read(buf, { at: 0 });\n syncHandle.close();\n\n return new TextDecoder(\"utf-8\").decode(buf);\n } catch {\n // Not OPFS or not in a Worker — use File System Access API path\n const file = await fileHandle.getFile();\n\n return file.text();\n }\n}\n","import { ToolProfile } from \"./types.js\";\n\n/**\n * Built-in profile optimized for Gemini Nano (Prompt API).\n * Minimizes context consumption so Nano has maximum tokens for generation.\n */\nexport const DEFAULT_BUILTIN_PROFILE: ToolProfile = {\n id: \"__builtin_default\",\n name: \"Default\",\n providerId: \"prompt_api\",\n enabledToolNames: [\n \"javascript\",\n \"list_files\",\n \"open_file\",\n \"read_file\",\n \"write_file\",\n ],\n customTools: [],\n systemPromptOverride:\n \"You are a helpful coding assistant.\\n\" +\n \"Content intended to be rendered as a `Page` (HTML or Markdown) SHOULD include frontmatter (title, created, updated, and slug).\\n\" +\n \"HTML content intended to be rendered as a `Page` SHOULD USE `<article><h2>${subTitle}</h2>...</article>` for its main body content.\",\n};\n","import { CONFIG_KEYS, DEFAULT_GROUP_ID } from \"../../config/config.js\";\nimport { getConfig } from \"../../db/getConfig.js\";\nimport { getGroupDir } from \"../../storage/getGroupDir.js\";\nimport { readGroupFile } from \"../../storage/readGroupFile.js\";\n\nimport type { ShadowClawDatabase } from \"../../db/types.js\";\nimport type {\n DeclarativeToolDefinition,\n DeclarativeToolExecution,\n ToolDefinition,\n} from \"./types.js\";\n\nexport type { DeclarativeToolDefinition };\n\nconst TOOL_NAME_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;\n\nexport function parseDeclarativeTool(\n path: string,\n value: unknown,\n): DeclarativeToolDefinition {\n if (!value || typeof value !== \"object\") {\n throw new Error(`Tool at ${path} must be a JSON object`);\n }\n\n const candidate = value as Record<string, unknown>;\n const name = typeof candidate.name === \"string\" ? candidate.name.trim() : \"\";\n const description =\n typeof candidate.description === \"string\"\n ? candidate.description.trim()\n : \"\";\n const inputSchema = candidate.input_schema ?? candidate.parameters;\n const execution = candidate.execution ?? candidate.evaluation;\n\n if (!TOOL_NAME_PATTERN.test(name)) {\n throw new Error(`Tool name is invalid: ${name || \"(missing)\"}`);\n }\n if (!description) {\n throw new Error(`Tool ${name} requires a description`);\n }\n if (!inputSchema || typeof inputSchema !== \"object\") {\n throw new Error(`Tool ${name} requires input_schema`);\n }\n if (!execution || typeof execution !== \"object\") {\n throw new Error(`Tool ${name} requires execution`);\n }\n\n const parsedExecution = execution as Record<string, unknown>;\n const type = parsedExecution.type;\n if (type !== \"bash\" && type !== \"javascript\" && type !== \"tool\") {\n throw new Error(\n `Tool ${name} execution type must be bash, javascript, or tool`,\n );\n }\n if (type === \"tool\") {\n if (\n typeof parsedExecution.name !== \"string\" ||\n !TOOL_NAME_PATTERN.test(parsedExecution.name)\n ) {\n throw new Error(`Tool ${name} execution requires a valid tool name`);\n }\n\n return {\n name,\n description,\n input_schema: inputSchema as ToolDefinition[\"input_schema\"],\n execution: {\n type,\n name: parsedExecution.name,\n ...(parsedExecution.input && typeof parsedExecution.input === \"object\"\n ? { input: parsedExecution.input as Record<string, unknown> }\n : {}),\n },\n path,\n };\n }\n const sourceKey = type === \"bash\" ? \"command\" : \"code\";\n const source = parsedExecution[sourceKey] ?? parsedExecution.expression;\n if (typeof source !== \"string\" || source.trim() === \"\") {\n throw new Error(`Tool ${name} execution requires ${sourceKey}`);\n }\n\n return {\n name,\n description,\n input_schema: inputSchema as ToolDefinition[\"input_schema\"],\n execution: {\n type,\n [sourceKey]: source,\n } as DeclarativeToolExecution,\n path,\n };\n}\n\nexport async function loadDeclarativeTools(\n db: ShadowClawDatabase,\n groupId: string = DEFAULT_GROUP_ID,\n): Promise<{ tools: DeclarativeToolDefinition[]; diagnostics: string[] }> {\n const tools: DeclarativeToolDefinition[] = [];\n const diagnostics: string[] = [];\n\n const groupIdsToScan =\n groupId === DEFAULT_GROUP_ID\n ? [DEFAULT_GROUP_ID]\n : [groupId, DEFAULT_GROUP_ID];\n\n for (const targetGroupId of groupIdsToScan) {\n try {\n const root = await getGroupDir(db, targetGroupId);\n const paths: string[] = [];\n\n async function visit(\n directory: FileSystemDirectoryHandle,\n relativePath: string,\n ) {\n for await (const [name, handle] of (directory as any).entries()) {\n const childPath = `${relativePath}/${name}`;\n if (handle.kind === \"directory\") {\n await visit(handle, childPath);\n } else if (\n name.endsWith(\".json\") &&\n childPath.startsWith(\".agents/tools/\")\n ) {\n paths.push(childPath);\n }\n }\n }\n\n try {\n const agentsDir = await root.getDirectoryHandle(\".agents\");\n const toolsDir = await agentsDir.getDirectoryHandle(\"tools\");\n await visit(toolsDir, \".agents/tools\");\n } catch {\n continue;\n }\n\n for (const path of paths.sort()) {\n try {\n const parsed = JSON.parse(\n await readGroupFile(db, targetGroupId, path),\n );\n const parsedTool = parseDeclarativeTool(path, parsed);\n if (!tools.some((t) => t.name === parsedTool.name)) {\n tools.push(parsedTool);\n }\n } catch (error) {\n diagnostics.push(\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n } catch {\n // Continue to next group directory\n }\n }\n\n return { tools, diagnostics };\n}\n\nexport async function findDeclarativeTool(\n db: ShadowClawDatabase,\n groupId: string = DEFAULT_GROUP_ID,\n name: string,\n): Promise<DeclarativeToolDefinition | null> {\n try {\n const { tools } = await loadDeclarativeTools(db, groupId);\n const tool = tools.find((t) => t.name === name) || null;\n if (!tool) {\n return null;\n }\n\n const rawEnabled = await getConfig(\n db,\n CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED,\n );\n if (Array.isArray(rawEnabled) && !rawEnabled.includes(name)) {\n return null;\n }\n\n return tool;\n } catch {\n return null;\n }\n}\n","import { Signal } from \"signal-polyfill\";\n\nimport { CONFIG_KEYS } from \"../config/config.js\";\nimport { getConfig } from \"../db/getConfig.js\";\nimport { setConfig } from \"../db/setConfig.js\";\nimport { TOOL_DEFINITIONS } from \"../subsystems/tools/tools.js\";\nimport { DEFAULT_BUILTIN_PROFILE } from \"../subsystems/tools/builtin-profiles.js\";\nimport { loadDeclarativeTools } from \"../subsystems/tools/declarative.js\";\nimport type { DeclarativeToolDefinition } from \"../subsystems/tools/declarative.js\";\nimport type { ShadowClawDatabase } from \"../db/types.js\";\nimport type { ToolDefinition, ToolProfile } from \"../subsystems/tools/tools.js\";\n\nexport class ToolsStore {\n private _activeProfile: Signal.Computed<ToolProfile | null>;\n private _activeProfileId: Signal.State<string | null>;\n private _allTools: Signal.Computed<ToolDefinition[]>;\n private _customTools: Signal.State<ToolDefinition[]>;\n private _declarativeTools: Signal.State<DeclarativeToolDefinition[]>;\n private _declarativeToolNamesEnabled: Signal.State<Set<string> | null>;\n private _enabledDeclarativeTools: Signal.Computed<\n DeclarativeToolDefinition[]\n >;\n private _enabledToolNames: Signal.State<Set<string>>;\n private _enabledTools: Signal.Computed<ToolDefinition[]>;\n private _profiles: Signal.State<ToolProfile[]>;\n private _systemPromptOverride: Signal.State<string>;\n private _webSearchProxyUrl: Signal.State<string>;\n private _webSearchUrl: Signal.State<string>;\n private _webSearchUseProxy: Signal.State<boolean>;\n private _searchFilesMaxFileBytes: Signal.State<number>;\n private _searchFilesMaxFilesVisited: Signal.State<number>;\n private _searchFilesSkipDirs: Signal.State<string>;\n\n constructor() {\n this._enabledToolNames = new Signal.State(\n new Set(DEFAULT_BUILTIN_PROFILE.enabledToolNames),\n );\n this._customTools = new Signal.State([]);\n this._declarativeTools = new Signal.State([]);\n this._declarativeToolNamesEnabled = new Signal.State<Set<string> | null>(\n null,\n );\n this._systemPromptOverride = new Signal.State(\"\");\n this._profiles = new Signal.State([]);\n this._activeProfileId = new Signal.State(DEFAULT_BUILTIN_PROFILE.id);\n this._webSearchUseProxy = new Signal.State(false);\n this._webSearchProxyUrl = new Signal.State(\"/proxy\");\n this._webSearchUrl = new Signal.State(\n \"https://html.duckduckgo.com/html/?q={query}\",\n );\n this._searchFilesMaxFileBytes = new Signal.State(512 * 1024);\n this._searchFilesMaxFilesVisited = new Signal.State(1000);\n this._searchFilesSkipDirs = new Signal.State(\n \".git,node_modules,dist,dist-electron,.cache,.nx,.turbo,__pycache__,.venv,venv\",\n );\n\n // Derived signals using Signal.Computed for proper reactive propagation.\n this._allTools = new Signal.Computed(() => [\n ...TOOL_DEFINITIONS,\n ...this._customTools.get(),\n ]);\n\n this._enabledTools = new Signal.Computed(() => {\n const enabled = this._enabledToolNames.get();\n\n return this._allTools\n .get()\n .filter((t: ToolDefinition) => enabled.has(t.name));\n });\n\n this._enabledDeclarativeTools = new Signal.Computed(() => {\n const tools = this._declarativeTools.get();\n const enabledSet = this._declarativeToolNamesEnabled.get();\n if (enabledSet === null) {\n return tools;\n }\n return tools.filter((t) => enabledSet.has(t.name));\n });\n\n this._activeProfile = new Signal.Computed(() => {\n const id = this._activeProfileId.get();\n if (!id) {\n return null;\n }\n\n if (DEFAULT_BUILTIN_PROFILE.id === id) {\n return DEFAULT_BUILTIN_PROFILE;\n }\n\n return this._profiles.get().find((p: ToolProfile) => p.id === id) || null;\n });\n }\n\n get activeProfile(): ToolProfile | null {\n return this._activeProfile.get();\n }\n\n get activeProfileId(): string | null {\n return this._activeProfileId.get();\n }\n\n get allTools(): ToolDefinition[] {\n return this._allTools.get();\n }\n\n get customTools(): ToolDefinition[] {\n return this._customTools.get();\n }\n\n get declarativeTools(): DeclarativeToolDefinition[] {\n return this._declarativeTools.get();\n }\n\n get declarativeToolNamesEnabled(): Set<string> | null {\n return this._declarativeToolNamesEnabled.get();\n }\n\n get enabledDeclarativeTools(): DeclarativeToolDefinition[] {\n return this._enabledDeclarativeTools.get();\n }\n\n get enabledToolNames(): Set<string> {\n return this._enabledToolNames.get();\n }\n\n get enabledTools(): ToolDefinition[] {\n return this._enabledTools.get();\n }\n\n isDeclarativeToolEnabled(name: string): boolean {\n const enabledSet = this._declarativeToolNamesEnabled.get();\n if (enabledSet === null) {\n return true;\n }\n return enabledSet.has(name);\n }\n\n async refreshDeclarativeTools(\n db: ShadowClawDatabase,\n groupId?: string,\n ): Promise<DeclarativeToolDefinition[]> {\n try {\n const res = await loadDeclarativeTools(db, groupId || \"br:main\");\n const allBuiltInAndCustom = this.allTools;\n const declTools = (res?.tools || []).filter(\n (dt) => !allBuiltInAndCustom.some((bt) => bt.name === dt.name),\n );\n\n const current = this._declarativeTools.get();\n const isSame =\n current.length === declTools.length &&\n current.every(\n (t, i) =>\n t.name === declTools[i].name &&\n t.description === declTools[i].description &&\n JSON.stringify(t.execution) ===\n JSON.stringify(declTools[i].execution),\n );\n\n if (!isSame) {\n this._declarativeTools.set(declTools);\n }\n return declTools;\n } catch {\n if (this._declarativeTools.get().length > 0) {\n this._declarativeTools.set([]);\n }\n return [];\n }\n }\n\n async setDeclarativeToolEnabled(\n db: ShadowClawDatabase,\n toolName: string,\n enabled: boolean,\n ): Promise<void> {\n const currentEnabled = this._declarativeToolNamesEnabled.get();\n const allDeclTools = this._declarativeTools.get();\n const nextSet = new Set(\n currentEnabled === null\n ? allDeclTools.map((t) => t.name)\n : currentEnabled,\n );\n if (enabled) {\n nextSet.add(toolName);\n } else {\n nextSet.delete(toolName);\n }\n this._declarativeToolNamesEnabled.set(nextSet);\n await setConfig(\n db,\n CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED,\n Array.from(nextSet),\n );\n }\n\n async setAllDeclarativeEnabled(\n db: ShadowClawDatabase,\n toolNames: string[],\n ): Promise<void> {\n const nextSet = new Set(toolNames);\n this._declarativeToolNamesEnabled.set(nextSet);\n await setConfig(db, CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED, toolNames);\n }\n\n /**\n * Export tools config as JSON for backup.\n */\n exportBackup(): string {\n return JSON.stringify(\n {\n enabledTools: [...this._enabledToolNames.get()],\n customTools: this._customTools.get(),\n declarativeToolsEnabled: this._declarativeToolNamesEnabled.get()\n ? Array.from(this._declarativeToolNamesEnabled.get()!)\n : null,\n systemPromptOverride: this._systemPromptOverride.get(),\n profiles: this._profiles.get(),\n activeProfileId: this._activeProfileId.get(),\n webSearchUseProxy: this._webSearchUseProxy.get(),\n webSearchProxyUrl: this._webSearchProxyUrl.get(),\n webSearchUrl: this._webSearchUrl.get(),\n searchFilesMaxFileBytes: this._searchFilesMaxFileBytes.get(),\n searchFilesMaxFilesVisited: this._searchFilesMaxFilesVisited.get(),\n searchFilesSkipDirs: this._searchFilesSkipDirs.get(),\n },\n null,\n 2,\n );\n }\n\n findProfilesForProvider(providerId?: string, model?: string): ToolProfile[] {\n return this.profiles.filter((p) => {\n if (p.providerId && p.providerId !== providerId) {\n return false;\n }\n\n if (p.model && p.model !== model) {\n return false;\n }\n\n return true;\n });\n }\n\n get profiles(): ToolProfile[] {\n return [DEFAULT_BUILTIN_PROFILE, ...this._profiles.get()];\n }\n\n get systemPromptOverride(): string {\n return this._systemPromptOverride.get();\n }\n\n get webSearchProxyUrl(): string {\n return this._webSearchProxyUrl.get();\n }\n\n get webSearchUrl(): string {\n return this._webSearchUrl.get();\n }\n\n get webSearchUseProxy(): boolean {\n return this._webSearchUseProxy.get();\n }\n\n get searchFilesMaxFileBytes(): number {\n return this._searchFilesMaxFileBytes.get();\n }\n\n get searchFilesMaxFilesVisited(): number {\n return this._searchFilesMaxFilesVisited.get();\n }\n\n /** Comma-separated list of directory names to skip when walking the workspace. */\n get searchFilesSkipDirs(): string {\n return this._searchFilesSkipDirs.get();\n }\n\n /** Parsed Set of directory names to skip — derived from the comma-separated string. */\n get searchFilesSkipDirsSet(): Set<string> {\n return new Set(\n this._searchFilesSkipDirs\n .get()\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean),\n );\n }\n\n async activateProfile(\n db: ShadowClawDatabase,\n profileId: string,\n ): Promise<void> {\n const profile = this.profiles.find((p) => p.id === profileId);\n if (!profile) {\n return;\n }\n\n this._activeProfileId.set(profileId);\n this._enabledToolNames.set(new Set(profile.enabledToolNames));\n this._customTools.set(profile.customTools);\n this._systemPromptOverride.set(profile.systemPromptOverride || \"\");\n\n await Promise.all([\n setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, profileId),\n setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, profile.enabledToolNames),\n setConfig(db, CONFIG_KEYS.CUSTOM_TOOLS, profile.customTools),\n setConfig(\n db,\n CONFIG_KEYS.SYSTEM_PROMPT_OVERRIDE,\n profile.systemPromptOverride || \"\",\n ),\n ]);\n }\n\n async addCustomTool(\n db: ShadowClawDatabase,\n tool: ToolDefinition,\n ): Promise<void> {\n const tools = [...this._customTools.get(), tool];\n this._customTools.set(tools);\n // Auto-enable new tool\n const enabled = new Set(this._enabledToolNames.get());\n enabled.add(tool.name);\n this._enabledToolNames.set(enabled);\n await Promise.all([\n setConfig(db, CONFIG_KEYS.CUSTOM_TOOLS, tools),\n setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, [...enabled]),\n ]);\n }\n\n // ── Profile Management ───────────────────────────────────────────\n\n async addProfile(\n db: ShadowClawDatabase,\n profile: ToolProfile,\n ): Promise<void> {\n const profiles = [...this._profiles.get(), profile];\n this._profiles.set(profiles);\n await setConfig(db, CONFIG_KEYS.TOOL_PROFILES, profiles);\n }\n\n async cloneTool(\n db: ShadowClawDatabase,\n sourceToolName: string,\n newToolName: string,\n newDescription?: string,\n ): Promise<boolean> {\n const source = this.allTools.find((t) => t.name === sourceToolName);\n if (!source) {\n return false;\n }\n\n if (this.allTools.some((t) => t.name === newToolName)) {\n return false;\n }\n\n const cloned: ToolDefinition = {\n name: newToolName,\n description: newDescription || source.description,\n input_schema: JSON.parse(JSON.stringify(source.input_schema)),\n };\n\n await this.addCustomTool(db, cloned);\n\n return true;\n }\n\n async deactivateProfile(db: ShadowClawDatabase): Promise<void> {\n this._activeProfileId.set(null);\n await setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, null);\n }\n\n async deleteProfile(\n db: ShadowClawDatabase,\n profileId: string,\n ): Promise<void> {\n if (profileId === DEFAULT_BUILTIN_PROFILE.id) {\n return;\n }\n\n const profiles = this._profiles.get().filter((p) => p.id !== profileId);\n this._profiles.set(profiles);\n if (this._activeProfileId.get() === profileId) {\n this._activeProfileId.set(null);\n await setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, null);\n }\n\n await setConfig(db, CONFIG_KEYS.TOOL_PROFILES, profiles);\n }\n\n async importBackup(db: ShadowClawDatabase, json: string): Promise<void> {\n const data = JSON.parse(json);\n if (Array.isArray(data.enabledTools)) {\n this._enabledToolNames.set(new Set(data.enabledTools));\n await setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, data.enabledTools);\n }\n\n if (Array.isArray(data.customTools)) {\n this._customTools.set(data.customTools);\n await setConfig(db, CONFIG_KEYS.CUSTOM_TOOLS, data.customTools);\n }\n\n if (typeof data.systemPromptOverride === \"string\") {\n this._systemPromptOverride.set(data.systemPromptOverride);\n await setConfig(\n db,\n CONFIG_KEYS.SYSTEM_PROMPT_OVERRIDE,\n data.systemPromptOverride,\n );\n }\n\n if (Array.isArray(data.profiles)) {\n this._profiles.set(data.profiles);\n await setConfig(db, CONFIG_KEYS.TOOL_PROFILES, data.profiles);\n }\n\n if (\n typeof data.activeProfileId === \"string\" ||\n data.activeProfileId === null\n ) {\n this._activeProfileId.set(data.activeProfileId);\n await setConfig(\n db,\n CONFIG_KEYS.ACTIVE_TOOL_PROFILE,\n data.activeProfileId,\n );\n }\n\n if (typeof data.webSearchUseProxy === \"boolean\") {\n this._webSearchUseProxy.set(data.webSearchUseProxy);\n await setConfig(\n db,\n CONFIG_KEYS.WEB_SEARCH_USE_PROXY,\n data.webSearchUseProxy ? \"true\" : \"false\",\n );\n }\n\n if (typeof data.webSearchProxyUrl === \"string\") {\n this._webSearchProxyUrl.set(data.webSearchProxyUrl);\n await setConfig(\n db,\n CONFIG_KEYS.WEB_SEARCH_PROXY_URL,\n data.webSearchProxyUrl,\n );\n }\n\n if (typeof data.webSearchUrl === \"string\") {\n this._webSearchUrl.set(data.webSearchUrl);\n await setConfig(db, CONFIG_KEYS.WEB_SEARCH_URL, data.webSearchUrl);\n }\n\n if (\n typeof data.searchFilesMaxFileBytes === \"number\" &&\n data.searchFilesMaxFileBytes > 0\n ) {\n this._searchFilesMaxFileBytes.set(data.searchFilesMaxFileBytes);\n await setConfig(\n db,\n CONFIG_KEYS.SEARCH_FILES_MAX_FILE_BYTES,\n String(data.searchFilesMaxFileBytes),\n );\n }\n\n if (\n typeof data.searchFilesMaxFilesVisited === \"number\" &&\n data.searchFilesMaxFilesVisited > 0\n ) {\n this._searchFilesMaxFilesVisited.set(data.searchFilesMaxFilesVisited);\n await setConfig(\n db,\n CONFIG_KEYS.SEARCH_FILES_MAX_FILES_VISITED,\n String(data.searchFilesMaxFilesVisited),\n );\n }\n\n if (typeof data.searchFilesSkipDirs === \"string\") {\n this._searchFilesSkipDirs.set(data.searchFilesSkipDirs);\n await setConfig(\n db,\n CONFIG_KEYS.SEARCH_FILES_SKIP_DIRS,\n data.searchFilesSkipDirs,\n );\n }\n\n if (Array.isArray(data.declarativeToolsEnabled)) {\n this._declarativeToolNamesEnabled.set(\n new Set(data.declarativeToolsEnabled),\n );\n await setConfig(\n db,\n CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED,\n data.declarativeToolsEnabled,\n );\n } else if (data.declarativeToolsEnabled === null) {\n this._declarativeToolNamesEnabled.set(null);\n await setConfig(db, CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED, null);\n }\n }\n\n /**\n * Load persisted tool config from IndexedDB.\n */\n async load(db: ShadowClawDatabase): Promise<void> {\n const [\n enabledRaw,\n customRaw,\n promptOverride,\n profilesRaw,\n activeProfileIdRaw,\n webSearchUseProxyRaw,\n webSearchProxyUrlRaw,\n webSearchUrlRaw,\n searchFilesMaxFileBytesRaw,\n searchFilesMaxFilesVisitedRaw,\n searchFilesSkipDirsRaw,\n declarativeEnabledRaw,\n ] = await Promise.all([\n getConfig(db, CONFIG_KEYS.ENABLED_TOOLS),\n getConfig(db, CONFIG_KEYS.CUSTOM_TOOLS),\n getConfig(db, CONFIG_KEYS.SYSTEM_PROMPT_OVERRIDE),\n getConfig(db, CONFIG_KEYS.TOOL_PROFILES),\n getConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE),\n getConfig(db, CONFIG_KEYS.WEB_SEARCH_USE_PROXY),\n getConfig(db, CONFIG_KEYS.WEB_SEARCH_PROXY_URL),\n getConfig(db, CONFIG_KEYS.WEB_SEARCH_URL),\n getConfig(db, CONFIG_KEYS.SEARCH_FILES_MAX_FILE_BYTES),\n getConfig(db, CONFIG_KEYS.SEARCH_FILES_MAX_FILES_VISITED),\n getConfig(db, CONFIG_KEYS.SEARCH_FILES_SKIP_DIRS),\n getConfig(db, CONFIG_KEYS.DECLARATIVE_TOOLS_ENABLED),\n ]);\n\n if (Array.isArray(enabledRaw)) {\n this._enabledToolNames.set(new Set(enabledRaw));\n }\n\n if (Array.isArray(customRaw)) {\n this._customTools.set(customRaw);\n }\n\n if (Array.isArray(declarativeEnabledRaw)) {\n this._declarativeToolNamesEnabled.set(new Set(declarativeEnabledRaw));\n }\n\n if (typeof promptOverride === \"string\") {\n this._systemPromptOverride.set(promptOverride);\n }\n\n if (Array.isArray(profilesRaw)) {\n this._profiles.set(profilesRaw);\n }\n\n if (typeof activeProfileIdRaw === \"string\") {\n this._activeProfileId.set(activeProfileIdRaw);\n }\n\n if (webSearchUseProxyRaw !== null && webSearchUseProxyRaw !== undefined) {\n const strVal = String(webSearchUseProxyRaw).toLowerCase();\n this._webSearchUseProxy.set(strVal === \"true\" || strVal === \"1\");\n }\n\n if (\n typeof webSearchProxyUrlRaw === \"string\" &&\n webSearchProxyUrlRaw.trim().length > 0\n ) {\n this._webSearchProxyUrl.set(webSearchProxyUrlRaw.trim());\n }\n\n if (\n typeof webSearchUrlRaw === \"string\" &&\n webSearchUrlRaw.trim().length > 0\n ) {\n this._webSearchUrl.set(webSearchUrlRaw.trim());\n }\n\n if (\n searchFilesMaxFileBytesRaw !== null &&\n searchFilesMaxFileBytesRaw !== undefined\n ) {\n const n = Number(searchFilesMaxFileBytesRaw);\n if (Number.isFinite(n) && n > 0) {\n this._searchFilesMaxFileBytes.set(n);\n }\n }\n\n if (\n searchFilesMaxFilesVisitedRaw !== null &&\n searchFilesMaxFilesVisitedRaw !== undefined\n ) {\n const n = Number(searchFilesMaxFilesVisitedRaw);\n if (Number.isFinite(n) && n > 0) {\n this._searchFilesMaxFilesVisited.set(n);\n }\n }\n\n if (\n typeof searchFilesSkipDirsRaw === \"string\" &&\n searchFilesSkipDirsRaw.trim().length > 0\n ) {\n this._searchFilesSkipDirs.set(searchFilesSkipDirsRaw.trim());\n }\n }\n\n async setWebSearchProxyUrl(\n db: ShadowClawDatabase,\n proxyUrl: string,\n ): Promise<void> {\n const trimmed = proxyUrl.trim() || \"/proxy\";\n this._webSearchProxyUrl.set(trimmed);\n await setConfig(db, CONFIG_KEYS.WEB_SEARCH_PROXY_URL, trimmed);\n }\n\n async setWebSearchUrl(db: ShadowClawDatabase, url: string): Promise<void> {\n const trimmed = url.trim() || \"https://html.duckduckgo.com/html/?q={query}\";\n this._webSearchUrl.set(trimmed);\n await setConfig(db, CONFIG_KEYS.WEB_SEARCH_URL, trimmed);\n }\n\n async setWebSearchUseProxy(\n db: ShadowClawDatabase,\n useProxy: boolean,\n ): Promise<void> {\n const enabled = !!useProxy;\n this._webSearchUseProxy.set(enabled);\n await setConfig(\n db,\n CONFIG_KEYS.WEB_SEARCH_USE_PROXY,\n enabled ? \"true\" : \"false\",\n );\n }\n\n async setSearchFilesMaxFileBytes(\n db: ShadowClawDatabase,\n bytes: number,\n ): Promise<void> {\n const clamped = Math.max(1, Math.round(bytes));\n this._searchFilesMaxFileBytes.set(clamped);\n await setConfig(\n db,\n CONFIG_KEYS.SEARCH_FILES_MAX_FILE_BYTES,\n String(clamped),\n );\n }\n\n async setSearchFilesMaxFilesVisited(\n db: ShadowClawDatabase,\n count: number,\n ): Promise<void> {\n const clamped = Math.max(1, Math.round(count));\n this._searchFilesMaxFilesVisited.set(clamped);\n await setConfig(\n db,\n CONFIG_KEYS.SEARCH_FILES_MAX_FILES_VISITED,\n String(clamped),\n );\n }\n\n async setSearchFilesSkipDirs(\n db: ShadowClawDatabase,\n dirs: string,\n ): Promise<void> {\n const trimmed = dirs.trim();\n this._searchFilesSkipDirs.set(trimmed);\n await setConfig(db, CONFIG_KEYS.SEARCH_FILES_SKIP_DIRS, trimmed);\n }\n\n async removeCustomTool(\n db: ShadowClawDatabase,\n toolName: string,\n ): Promise<void> {\n const tools = this._customTools.get().filter((t) => t.name !== toolName);\n this._customTools.set(tools);\n const enabled = new Set(this._enabledToolNames.get());\n enabled.delete(toolName);\n this._enabledToolNames.set(enabled);\n await Promise.all([\n setConfig(db, CONFIG_KEYS.CUSTOM_TOOLS, tools),\n setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, [...enabled]),\n ]);\n }\n\n async saveToActiveProfile(db: ShadowClawDatabase): Promise<void> {\n const id = this._activeProfileId.get();\n if (!id) {\n return;\n }\n\n const profile = this._profiles.get().find((p) => p.id === id);\n if (!profile) {\n return;\n }\n\n const updated = {\n ...profile,\n enabledToolNames: [...this._enabledToolNames.get()],\n customTools: [...this._customTools.get()],\n systemPromptOverride: this._systemPromptOverride.get(),\n };\n await this.updateProfile(db, updated);\n }\n\n async setAllEnabled(\n db: ShadowClawDatabase,\n toolNames: string[],\n ): Promise<void> {\n this._enabledToolNames.set(new Set(toolNames));\n\n const saves = [setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, toolNames)];\n if (this._activeProfileId.get()) {\n this._activeProfileId.set(null);\n saves.push(setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, null));\n }\n\n await Promise.all(saves);\n }\n\n async setSystemPromptOverride(\n db: ShadowClawDatabase,\n override: string,\n ): Promise<void> {\n this._systemPromptOverride.set(override);\n await setConfig(db, CONFIG_KEYS.SYSTEM_PROMPT_OVERRIDE, override);\n }\n\n async setToolEnabled(\n db: ShadowClawDatabase,\n toolName: string,\n enabled: boolean,\n ): Promise<void> {\n const current = new Set(this._enabledToolNames.get());\n if (enabled) {\n current.add(toolName);\n } else {\n current.delete(toolName);\n }\n\n this._enabledToolNames.set(current);\n\n const saves = [setConfig(db, CONFIG_KEYS.ENABLED_TOOLS, [...current])];\n if (this._activeProfileId.get()) {\n this._activeProfileId.set(null);\n saves.push(setConfig(db, CONFIG_KEYS.ACTIVE_TOOL_PROFILE, null));\n }\n\n await Promise.all(saves);\n }\n\n async updateProfile(\n db: ShadowClawDatabase,\n profile: ToolProfile,\n ): Promise<void> {\n const profiles = this._profiles\n .get()\n .map((p) => (p.id === profile.id ? profile : p));\n this._profiles.set(profiles);\n await setConfig(db, CONFIG_KEYS.TOOL_PROFILES, profiles);\n }\n}\n\nexport const toolsStore = new ToolsStore();\n"],"mappings":"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"}