shadow-claw 1.51.0 → 1.52.1

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 (378) hide show
  1. package/.well-known/mcp/server-card.json +1 -1
  2. package/.well-known/mcp.json +1 -1
  3. package/README.md +10 -10
  4. package/dist/cli/build/build.js +1 -1
  5. package/dist/cli/{chunk-Dtse8rAn.js → chunk-5ryVpyup.js} +1 -1
  6. package/dist/cli/chunk-Aq3057Xo.js +1 -0
  7. package/dist/cli/{chunk-4CZJpLqA.js → chunk-BV9JBYpl.js} +2 -2
  8. package/dist/cli/{chunk-mbFAP9Ev.js → chunk-BZI3bWDA.js} +1 -1
  9. package/dist/cli/chunk-BaUCHRPD.js +1 -0
  10. package/dist/cli/{chunk-vzUrhBN5.js → chunk-BdbEt6gM.js} +1 -1
  11. package/dist/cli/{chunk-DYq-orHK.js → chunk-BgTv9w0K.js} +1 -1
  12. package/dist/cli/{chunk-BU8UG4L_.js → chunk-BiWLawPV.js} +1 -1
  13. package/dist/cli/chunk-BkLnHJeo.js +1 -0
  14. package/dist/cli/{chunk-BqfPWIBf.js → chunk-BzWY1sKE.js} +1 -1
  15. package/dist/cli/{chunk-DajM7Kro.js → chunk-C79eIU-4.js} +1 -1
  16. package/dist/cli/{chunk-CI9r1AM5.js → chunk-CDw214Zi.js} +1 -1
  17. package/dist/cli/chunk-CNqc7LLn.js +1 -0
  18. package/dist/cli/{chunk-CEhU-Ah-.js → chunk-CWW7dqIv.js} +1 -1
  19. package/dist/cli/{chunk-BT_C3OlA.js → chunk-CcSTYHtR.js} +1 -1
  20. package/dist/cli/chunk-ClOfk6Ga.js +1 -0
  21. package/dist/cli/chunk-ComXUwW0.js +1 -0
  22. package/dist/cli/{chunk-lL1BhHVe.js → chunk-CooeO4UQ.js} +1 -1
  23. package/dist/cli/{chunk-khr7--yI.js → chunk-CtfWY4G6.js} +1 -1
  24. package/dist/cli/{chunk-C4iW1XuQ.js → chunk-DFgSiYMW.js} +1 -1
  25. package/dist/cli/chunk-DGBnjngK.js +1 -0
  26. package/dist/cli/{chunk-D7bFIUK3.js → chunk-DGu1OhJs.js} +1 -1
  27. package/dist/cli/{chunk-CzfOerQR.js → chunk-DIjCY0Wf.js} +1 -1
  28. package/dist/cli/{chunk-D-iqEY5G.js → chunk-DJ_LeQtz.js} +1 -1
  29. package/dist/cli/{chunk-BmEsDkRK.js → chunk-DQRu-9wO.js} +1 -1
  30. package/dist/cli/{chunk-DojiYody.js → chunk-DToVgO9a.js} +1 -1
  31. package/dist/cli/{chunk-De5a_Rlp.js → chunk-DVbNkQRL.js} +1 -1
  32. package/dist/cli/{chunk-c8MIYB2y.js → chunk-Ddtzaj43.js} +1 -1
  33. package/dist/cli/{chunk-aJ6fufe-.js → chunk-DiqS56rD.js} +1 -1
  34. package/dist/cli/{chunk-CeUEmZNt.js → chunk-DnRcu9b4.js} +1 -1
  35. package/dist/cli/chunk-DtgZDsJA.js +1 -0
  36. package/dist/cli/{chunk-DVMcK7g6.js → chunk-Du4qvxo_.js} +2 -2
  37. package/dist/cli/{chunk-CegcvNc9.js → chunk-Dz5_hgvL.js} +8 -8
  38. package/dist/cli/{chunk-Cd4Dv5Eq.js → chunk-I3mxEelq.js} +1 -1
  39. package/dist/cli/{chunk-Do3VICh1.js → chunk-IU2SH_ti.js} +1 -1
  40. package/dist/cli/{chunk-BQveaAaD.js → chunk-NC8XsSSA.js} +1 -1
  41. package/dist/cli/{chunk-D702W_Ry.js → chunk-Q4BZ9QN9.js} +1 -1
  42. package/dist/cli/chunk-WTlDd4Ou.js +1 -0
  43. package/dist/cli/chunk-XGzq5joC.js +1 -0
  44. package/dist/cli/{chunk-ar7eAlxK.js → chunk-aJfaGe2s.js} +8 -8
  45. package/dist/cli/chunk-bPVrFlmk.js +1 -0
  46. package/dist/cli/{chunk-C6jii2Fl.js → chunk-d5hIhj8t.js} +1 -1
  47. package/dist/cli/chunk-jXJHKxdR.js +1 -0
  48. package/dist/cli/{chunk-C3dTAmV_.js → chunk-rstVU7U0.js} +1 -1
  49. package/dist/cli/{chunk-DGfTzQui.js → chunk-t72uObQ7.js} +1 -1
  50. package/dist/cli/{chunk-DDgfljzN.js → chunk-vq8xlroY.js} +1 -1
  51. package/dist/cli/cli.js +1 -1
  52. package/dist/headless-agent.js +1 -1
  53. package/dist/lib/components/common/shadow-claw-provider-model-picker.js +1 -1
  54. package/dist/lib/components/index.js +27 -27
  55. package/dist/lib/components/settings/shadow-claw-accounts.js +1 -1
  56. package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
  57. package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
  58. package/dist/lib/components/settings/shadow-claw-git.js +1 -1
  59. package/dist/lib/components/settings/shadow-claw-integrations.js +1 -1
  60. package/dist/lib/components/settings/shadow-claw-llm/model-ranking.d.ts +12 -0
  61. package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
  62. package/dist/lib/components/settings/shadow-claw-mcp-remote.js +1 -1
  63. package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
  64. package/dist/lib/components/settings/shadow-claw-notifications.js +1 -1
  65. package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
  66. package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
  67. package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
  68. package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
  69. package/dist/lib/components/shadow-claw-a2ui.js +1 -1
  70. package/dist/lib/components/shadow-claw-accounts.js +1 -1
  71. package/dist/lib/components/shadow-claw-channel-config.js +1 -1
  72. package/dist/lib/components/shadow-claw-channels.js +1 -1
  73. package/dist/lib/components/shadow-claw-chat/shadow-claw-chat.d.ts +1 -0
  74. package/dist/lib/components/shadow-claw-chat.js +1 -1
  75. package/dist/lib/components/shadow-claw-control-plane.js +1 -1
  76. package/dist/lib/components/shadow-claw-conversations.js +1 -1
  77. package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
  78. package/dist/lib/components/shadow-claw-files.js +1 -1
  79. package/dist/lib/components/shadow-claw-git.js +1 -1
  80. package/dist/lib/components/shadow-claw-integrations.js +1 -1
  81. package/dist/lib/components/shadow-claw-llm.js +1 -1
  82. package/dist/lib/components/shadow-claw-mcp-remote.js +1 -1
  83. package/dist/lib/components/shadow-claw-networking.js +1 -1
  84. package/dist/lib/components/shadow-claw-notifications.js +1 -1
  85. package/dist/lib/components/shadow-claw-page-header.js +1 -1
  86. package/dist/lib/components/shadow-claw-pages.js +1 -1
  87. package/dist/lib/components/shadow-claw-peerjs.js +1 -1
  88. package/dist/lib/components/shadow-claw-provider-model-picker.js +1 -1
  89. package/dist/lib/components/shadow-claw-settings.js +1 -1
  90. package/dist/lib/components/shadow-claw-storage.js +1 -1
  91. package/dist/lib/components/shadow-claw-task-server.js +1 -1
  92. package/dist/lib/components/shadow-claw-tasks.js +1 -1
  93. package/dist/lib/components/shadow-claw-terminal.js +1 -1
  94. package/dist/lib/components/shadow-claw-tools.js +1 -1
  95. package/dist/lib/components/shadow-claw-webvm.js +1 -1
  96. package/dist/lib/components/shadow-claw.js +1 -1
  97. package/dist/lib/config/config.d.ts +2 -1
  98. package/dist/lib/{config-DxDaVDTn.js → config-DFLs7eoC.js} +3 -2
  99. package/dist/lib/config-DFLs7eoC.js.map +1 -0
  100. package/dist/lib/{configurePeerJs-ScwZiGbF.js → configurePeerJs-DJ0H6e6s.js} +3 -3
  101. package/dist/lib/{configurePeerJs-ScwZiGbF.js.map → configurePeerJs-DJ0H6e6s.js.map} +1 -1
  102. package/dist/lib/{connections-D82zele0.js → connections-DT3nPylw.js} +2 -2
  103. package/dist/lib/{connections-D82zele0.js.map → connections-DT3nPylw.js.map} +1 -1
  104. package/dist/lib/{downloadGroupFile-D7-5y6NI.js → downloadGroupFile-DMnAiPj4.js} +2 -2
  105. package/dist/lib/{downloadGroupFile-D7-5y6NI.js.map → downloadGroupFile-DMnAiPj4.js.map} +1 -1
  106. package/dist/lib/{file-viewer-BMvvndPQ.js → file-viewer-OHmGC_l7.js} +5 -5
  107. package/dist/lib/{file-viewer-BMvvndPQ.js.map → file-viewer-OHmGC_l7.js.map} +1 -1
  108. package/dist/lib/{getGroupDir-BidwYPfP.js → getGroupDir-mTV2Iz2b.js} +3 -3
  109. package/dist/lib/{getGroupDir-BidwYPfP.js.map → getGroupDir-mTV2Iz2b.js.map} +1 -1
  110. package/dist/lib/{git-CXmWufWS.js → git-CGdKghMC.js} +3 -3
  111. package/dist/lib/{git-CXmWufWS.js.map → git-CGdKghMC.js.map} +1 -1
  112. package/dist/lib/index.js +28 -28
  113. package/dist/lib/{initChatSplitResize-tvUZ-wsp.js → initChatSplitResize-B8zHHQdm.js} +2 -2
  114. package/dist/lib/{initChatSplitResize-tvUZ-wsp.js.map → initChatSplitResize-B8zHHQdm.js.map} +1 -1
  115. package/dist/lib/{initControlPlane-Dnjkb-6J.js → initControlPlane-BczrlTf3.js} +14 -14
  116. package/dist/lib/{initControlPlane-Dnjkb-6J.js.map → initControlPlane-BczrlTf3.js.map} +1 -1
  117. package/dist/lib/{markdown-WCXar9C8.js → markdown-D-7Cjyye.js} +3 -3
  118. package/dist/lib/{markdown-WCXar9C8.js.map → markdown-D-7Cjyye.js.map} +1 -1
  119. package/dist/lib/{mcp-reconnect-WTOQONHZ.js → mcp-reconnect-Czf7QCCv.js} +2 -2
  120. package/dist/lib/{mcp-reconnect-WTOQONHZ.js.map → mcp-reconnect-Czf7QCCv.js.map} +1 -1
  121. package/dist/lib/{memoryStorage-Bo2Wpfmg.js → memoryStorage-CXyKsKMo.js} +2 -2
  122. package/dist/lib/{memoryStorage-Bo2Wpfmg.js.map → memoryStorage-CXyKsKMo.js.map} +1 -1
  123. package/dist/lib/model-ranking-Bo8CpGH1.js +116 -0
  124. package/dist/lib/model-ranking-Bo8CpGH1.js.map +1 -0
  125. package/dist/lib/{orchestrator-Crw4btGn.js → orchestrator-BK138MkV.js} +10 -10
  126. package/dist/lib/{orchestrator-Crw4btGn.js.map → orchestrator-BK138MkV.js.map} +1 -1
  127. package/dist/lib/{orchestrator-Dro541iH.js → orchestrator-BtbxiPQB.js} +17 -16
  128. package/dist/lib/{orchestrator-Dro541iH.js.map → orchestrator-BtbxiPQB.js.map} +1 -1
  129. package/dist/lib/{peerjs-D741bHrf.js → peerjs-QJr03K9F.js} +7 -7
  130. package/dist/lib/{peerjs-D741bHrf.js.map → peerjs-QJr03K9F.js.map} +1 -1
  131. package/dist/lib/{prompt-api-D9XdrCep.js → prompt-api-vf351sf2.js} +2 -19
  132. package/dist/lib/{prompt-api-D9XdrCep.js.map → prompt-api-vf351sf2.js.map} +1 -1
  133. package/dist/lib/{push-client-DKFUY_Ti.js → push-client-BOHgqHbk.js} +4 -4
  134. package/dist/lib/{push-client-DKFUY_Ti.js.map → push-client-BOHgqHbk.js.map} +1 -1
  135. package/dist/lib/{readGroupFileBytes-C8Xqlb8l.js → readGroupFileBytes-CRA6dmgT.js} +2 -2
  136. package/dist/lib/{readGroupFileBytes-C8Xqlb8l.js.map → readGroupFileBytes-CRA6dmgT.js.map} +1 -1
  137. package/dist/lib/{shadow-claw-a2ui-CPydWVdW.js → shadow-claw-a2ui-DbZa4Gxp.js} +2 -2
  138. package/dist/lib/{shadow-claw-a2ui-CPydWVdW.js.map → shadow-claw-a2ui-DbZa4Gxp.js.map} +1 -1
  139. package/dist/lib/{shadow-claw-accounts-CUypXc3I.js → shadow-claw-accounts-B6OW2NVD.js} +3 -3
  140. package/dist/lib/{shadow-claw-accounts-CUypXc3I.js.map → shadow-claw-accounts-B6OW2NVD.js.map} +1 -1
  141. package/dist/lib/{shadow-claw-channel-config-D_Vb2ous.js → shadow-claw-channel-config-F_EJ-uK2.js} +3 -3
  142. package/dist/lib/{shadow-claw-channel-config-D_Vb2ous.js.map → shadow-claw-channel-config-F_EJ-uK2.js.map} +1 -1
  143. package/dist/lib/{shadow-claw-channels-hgjjzvRr.js → shadow-claw-channels-XYylMpjg.js} +3 -3
  144. package/dist/lib/{shadow-claw-channels-hgjjzvRr.js.map → shadow-claw-channels-XYylMpjg.js.map} +1 -1
  145. package/dist/lib/{shadow-claw-chat-D69IiLXd.js → shadow-claw-chat-dbK_DGO_.js} +124 -38
  146. package/dist/lib/shadow-claw-chat-dbK_DGO_.js.map +1 -0
  147. package/dist/lib/{shadow-claw-control-plane-zBYlFvzQ.js → shadow-claw-control-plane-BJKkmahQ.js} +7 -7
  148. package/dist/lib/{shadow-claw-control-plane-zBYlFvzQ.js.map → shadow-claw-control-plane-BJKkmahQ.js.map} +1 -1
  149. package/dist/lib/{shadow-claw-conversations-1GW8_e8o.js → shadow-claw-conversations-BKSsMYTc.js} +6 -6
  150. package/dist/lib/{shadow-claw-conversations-1GW8_e8o.js.map → shadow-claw-conversations-BKSsMYTc.js.map} +1 -1
  151. package/dist/lib/{shadow-claw-D3z3tFyE.js → shadow-claw-eBB2dbpd.js} +11 -11
  152. package/dist/lib/{shadow-claw-D3z3tFyE.js.map → shadow-claw-eBB2dbpd.js.map} +1 -1
  153. package/dist/lib/{shadow-claw-file-viewer-DI4r7Th9.js → shadow-claw-file-viewer-BqChtTvM.js} +8 -8
  154. package/dist/lib/{shadow-claw-file-viewer-DI4r7Th9.js.map → shadow-claw-file-viewer-BqChtTvM.js.map} +1 -1
  155. package/dist/lib/{shadow-claw-files-BM7qW3TW.js → shadow-claw-files-Bu7VCQw6.js} +9 -9
  156. package/dist/lib/{shadow-claw-files-BM7qW3TW.js.map → shadow-claw-files-Bu7VCQw6.js.map} +1 -1
  157. package/dist/lib/{shadow-claw-git-BBTiTYIn.js → shadow-claw-git-CdPPN6Qb.js} +6 -6
  158. package/dist/lib/{shadow-claw-git-BBTiTYIn.js.map → shadow-claw-git-CdPPN6Qb.js.map} +1 -1
  159. package/dist/lib/{shadow-claw-integrations-DTY3E545.js → shadow-claw-integrations-DehqBSRe.js} +4 -4
  160. package/dist/lib/{shadow-claw-integrations-DTY3E545.js.map → shadow-claw-integrations-DehqBSRe.js.map} +1 -1
  161. package/dist/lib/{shadow-claw-llm-AJwzkOGo.js → shadow-claw-llm-COZkufA8.js} +13 -11
  162. package/dist/lib/shadow-claw-llm-COZkufA8.js.map +1 -0
  163. package/dist/lib/{shadow-claw-mcp-remote-n7YXKxmv.js → shadow-claw-mcp-remote-axF50-le.js} +4 -4
  164. package/dist/lib/{shadow-claw-mcp-remote-n7YXKxmv.js.map → shadow-claw-mcp-remote-axF50-le.js.map} +1 -1
  165. package/dist/lib/{shadow-claw-networking-B3leDgZ4.js → shadow-claw-networking-BT_Rxj36.js} +2 -2
  166. package/dist/lib/{shadow-claw-networking-B3leDgZ4.js.map → shadow-claw-networking-BT_Rxj36.js.map} +1 -1
  167. package/dist/lib/{shadow-claw-notifications-Bm2aHQ0U.js → shadow-claw-notifications-ClqAXDDN.js} +3 -3
  168. package/dist/lib/{shadow-claw-notifications-Bm2aHQ0U.js.map → shadow-claw-notifications-ClqAXDDN.js.map} +1 -1
  169. package/dist/lib/{shadow-claw-page-header-BBqSWlhP.js → shadow-claw-page-header-bigC_h6U.js} +2 -2
  170. package/dist/lib/{shadow-claw-page-header-BBqSWlhP.js.map → shadow-claw-page-header-bigC_h6U.js.map} +1 -1
  171. package/dist/lib/{shadow-claw-pages-BFOcluFY.js → shadow-claw-pages-CjHS50HN.js} +10 -10
  172. package/dist/lib/{shadow-claw-pages-BFOcluFY.js.map → shadow-claw-pages-CjHS50HN.js.map} +1 -1
  173. package/dist/lib/{shadow-claw-peerjs-BvD_MH_l.js → shadow-claw-peerjs-CvcH2DkA.js} +3 -3
  174. package/dist/lib/{shadow-claw-peerjs-BvD_MH_l.js.map → shadow-claw-peerjs-CvcH2DkA.js.map} +1 -1
  175. package/dist/lib/{shadow-claw-provider-model-picker-CsA-507a.js → shadow-claw-provider-model-picker-fcVQdDtQ.js} +2 -2
  176. package/dist/lib/{shadow-claw-provider-model-picker-CsA-507a.js.map → shadow-claw-provider-model-picker-fcVQdDtQ.js.map} +1 -1
  177. package/dist/lib/{shadow-claw-settings-CZgGMz0a.js → shadow-claw-settings-CkO6JjA4.js} +6 -6
  178. package/dist/lib/{shadow-claw-settings-CZgGMz0a.js.map → shadow-claw-settings-CkO6JjA4.js.map} +1 -1
  179. package/dist/lib/{shadow-claw-storage-BTUpEKO0.js → shadow-claw-storage-10w-y8vL.js} +5 -5
  180. package/dist/lib/{shadow-claw-storage-BTUpEKO0.js.map → shadow-claw-storage-10w-y8vL.js.map} +1 -1
  181. package/dist/lib/{shadow-claw-task-server-B1X2AYyZ.js → shadow-claw-task-server-U98sZxPu.js} +2 -2
  182. package/dist/lib/{shadow-claw-task-server-B1X2AYyZ.js.map → shadow-claw-task-server-U98sZxPu.js.map} +1 -1
  183. package/dist/lib/{shadow-claw-tasks-BYtaRUAd.js → shadow-claw-tasks-DrSVUOsP.js} +8 -8
  184. package/dist/lib/{shadow-claw-tasks-BYtaRUAd.js.map → shadow-claw-tasks-DrSVUOsP.js.map} +1 -1
  185. package/dist/lib/{shadow-claw-terminal-LGuXKu77.js → shadow-claw-terminal-B7HYLuce.js} +2 -2
  186. package/dist/lib/{shadow-claw-terminal-LGuXKu77.js.map → shadow-claw-terminal-B7HYLuce.js.map} +1 -1
  187. package/dist/lib/{shadow-claw-tools-C_S-xXVG.js → shadow-claw-tools-BKrXzZfF.js} +7 -7
  188. package/dist/lib/{shadow-claw-tools-C_S-xXVG.js.map → shadow-claw-tools-BKrXzZfF.js.map} +1 -1
  189. package/dist/lib/{shadow-claw-webvm-Cab1n1bu.js → shadow-claw-webvm-Duwa5oiW.js} +3 -3
  190. package/dist/lib/{shadow-claw-webvm-Cab1n1bu.js.map → shadow-claw-webvm-Duwa5oiW.js.map} +1 -1
  191. package/dist/lib/{syncWebMcpRegistration-Dy5NS_4G.js → syncWebMcpRegistration-BOx-0F6_.js} +5 -5
  192. package/dist/lib/{syncWebMcpRegistration-Dy5NS_4G.js.map → syncWebMcpRegistration-BOx-0F6_.js.map} +1 -1
  193. package/dist/lib/{tools-B7gC1eb_.js → tools-BEuBatUs.js} +4 -4
  194. package/dist/lib/{tools-B7gC1eb_.js.map → tools-BEuBatUs.js.map} +1 -1
  195. package/dist/lib/utils/index.js +1 -1
  196. package/dist/lib/utils/utils.js +1 -1
  197. package/dist/lib/{utils-D_ylqOY-.js → utils-D8AxCH6m.js} +2 -2
  198. package/dist/lib/{utils-D_ylqOY-.js.map → utils-D8AxCH6m.js.map} +1 -1
  199. package/dist/lib/{webmcp-CkYINKJj.js → webmcp-BjfVWX1K.js} +2 -2
  200. package/dist/lib/{webmcp-CkYINKJj.js.map → webmcp-BjfVWX1K.js.map} +1 -1
  201. package/dist/public/.well-known/mcp/server-card.json +1 -1
  202. package/dist/public/.well-known/mcp.json +1 -1
  203. package/dist/public/AGENTS.md +1 -1
  204. package/dist/public/README.md +10 -10
  205. package/dist/public/agent.worker.js +1 -1
  206. package/dist/public/components/shadow-claw-chat/shadow-claw-chat.html +1 -1
  207. package/dist/public/config-071HSho8.js +1 -0
  208. package/dist/public/{configurePeerJs-DQQ6YL-5.js → configurePeerJs-DL-LurJY.js} +1 -1
  209. package/dist/public/{connections-CRNk2FxF.js → connections-Bb0rBpV-.js} +1 -1
  210. package/dist/public/{custom-element-security-3_FKCXcg.js → custom-element-security-Td4vrRc_.js} +1 -1
  211. package/dist/public/docs/README.md +1 -1
  212. package/dist/public/docs/architecture/orchestrator.md +2 -2
  213. package/dist/public/docs/architecture/overview.md +3 -3
  214. package/dist/public/docs/architecture/worker-protocol.md +29 -29
  215. package/dist/public/docs/example/article/index.html +1 -1
  216. package/dist/public/docs/example/article.html +1 -1
  217. package/dist/public/docs/publishing/index.html +1 -1
  218. package/dist/public/docs/publishing.html +1 -1
  219. package/dist/public/docs/skill-creator/index.html +1 -1
  220. package/dist/public/docs/skill-creator.html +1 -1
  221. package/dist/public/docs/subsystems/local-models.md +1 -1
  222. package/dist/public/docs/subsystems/providers.md +12 -5
  223. package/dist/public/{downloadGroupFile-wkdhVgrZ.js → downloadGroupFile-Unq8_7D9.js} +1 -1
  224. package/dist/public/e2e/README.md +2 -2
  225. package/dist/public/{e2e-bridge-DnFHPuwg.js → e2e-bridge-Dbc9fCDq.js} +1 -1
  226. package/dist/public/{file-viewer-C92v4Ggd.js → file-viewer-QkCuknFn.js} +1 -1
  227. package/dist/public/{getGroupDir-BGGIJL4Y.js → getGroupDir-Bj5XCflQ.js} +1 -1
  228. package/dist/public/{git-BH6qyToB.js → git-Bhz4YHc8.js} +2 -2
  229. package/dist/public/index.html +1 -1
  230. package/dist/public/index.js +1 -1
  231. package/dist/public/{initChatSplitResize--RH5kzVF.js → initChatSplitResize-KNL9Oh7s.js} +1 -1
  232. package/dist/public/{initControlPlane-yPJ3ajkj.js → initControlPlane-D2fVhRFC.js} +1 -1
  233. package/dist/public/llms.txt +1 -1
  234. package/dist/public/main/index.html +1 -1
  235. package/dist/public/main/memory/index.html +1 -1
  236. package/dist/public/main/memory.html +1 -1
  237. package/dist/public/main.html +1 -1
  238. package/dist/public/{markdown-CA0v11cd.js → markdown-By6gdUvF.js} +1 -1
  239. package/dist/public/{mcp-reconnect-uyNSigzu.js → mcp-reconnect-CDRJPuoN.js} +1 -1
  240. package/dist/public/{memoryStorage-DjPNAT5t.js → memoryStorage-C-ao9y-j.js} +1 -1
  241. package/dist/public/model-ranking-DUdrFOcC.js +1 -0
  242. package/dist/public/{orchestrator-DTzgyL23.js → orchestrator-B7MpomoG.js} +2 -2
  243. package/dist/public/{orchestrator-Cmr69pMC.js → orchestrator-C8aIHbDy.js} +2 -2
  244. package/dist/public/{peerjs-Br38mUFC.js → peerjs-DwGjY5VX.js} +1 -1
  245. package/dist/public/prompt-api-BWe_j3Wg.js +1 -0
  246. package/dist/public/{push-client-CB8haOGC.js → push-client-o8g5_EOe.js} +1 -1
  247. package/dist/public/service-worker.js +1 -1
  248. package/dist/public/{shadow-claw-RuFQ2Ej5.js → shadow-claw-T9oPpqxT.js} +2 -2
  249. package/dist/public/{shadow-claw-accounts-BMsEItB6.js → shadow-claw-accounts-BbNPiiaV.js} +1 -1
  250. package/dist/public/{shadow-claw-channels-Q_AXuEaI.js → shadow-claw-channels-CHGtPkfY.js} +1 -1
  251. package/dist/public/{shadow-claw-chat-DZQ3OaH7.js → shadow-claw-chat-3TmjJA6-.js} +90 -23
  252. package/dist/public/{shadow-claw-control-plane-CyXA8tB8.js → shadow-claw-control-plane-BAFT06LL.js} +2 -2
  253. package/dist/public/{shadow-claw-conversations-BLKtlvHe.js → shadow-claw-conversations-DsQ_kxWm.js} +1 -1
  254. package/dist/public/{shadow-claw-file-viewer-CVLDfpZe.js → shadow-claw-file-viewer-hBxTknL2.js} +1 -1
  255. package/dist/public/{shadow-claw-files-DB6VVjir.js → shadow-claw-files-Daw6IIrJ.js} +1 -1
  256. package/dist/public/{shadow-claw-git-D57bTSMF.js → shadow-claw-git-CxGwyxim.js} +2 -2
  257. package/dist/public/{shadow-claw-integrations-BOwhUY-4.js → shadow-claw-integrations-DnIr6xp-.js} +1 -1
  258. package/dist/public/{shadow-claw-llm-CYenm-mm.js → shadow-claw-llm-Bc6tZ8kk.js} +3 -3
  259. package/dist/public/{shadow-claw-mcp-remote-CJ-Ckl0j.js → shadow-claw-mcp-remote-nGPpFpI-.js} +1 -1
  260. package/dist/public/{shadow-claw-networking-Cut76YQL.js → shadow-claw-networking-B6YgtiA7.js} +1 -1
  261. package/dist/public/{shadow-claw-notifications-C3kYCrIa.js → shadow-claw-notifications-BSxifptS.js} +1 -1
  262. package/dist/public/{shadow-claw-page-header-Dd7QafUk.js → shadow-claw-page-header-LzVgEn46.js} +1 -1
  263. package/dist/public/{shadow-claw-pages-BWtVtwTG.js → shadow-claw-pages-IW_LNEL_.js} +2 -2
  264. package/dist/public/{shadow-claw-settings-Bj7jnngO.js → shadow-claw-settings-DGkwt1ge.js} +2 -2
  265. package/dist/public/{shadow-claw-storage-CMSzQs1-.js → shadow-claw-storage-DX_4T7KR.js} +1 -1
  266. package/dist/public/{shadow-claw-task-server-CFclo7UX.js → shadow-claw-task-server-DTsbEs5z.js} +1 -1
  267. package/dist/public/{shadow-claw-tasks-ClDdeB6Z.js → shadow-claw-tasks-rr6fMxAM.js} +1 -1
  268. package/dist/public/{shadow-claw-terminal-3ysWZJix.js → shadow-claw-terminal-C7DhrrX6.js} +1 -1
  269. package/dist/public/{shadow-claw-tools-DQVwpTcZ.js → shadow-claw-tools-DcQroojH.js} +1 -1
  270. package/dist/public/{shadow-claw-webvm-Cnxz04Fk.js → shadow-claw-webvm-bZj44Did.js} +1 -1
  271. package/dist/public/{syncWebMcpRegistration-QwnLMAK3.js → syncWebMcpRegistration-XJjIlDNO.js} +1 -1
  272. package/dist/public/{tools-DvQ_ngXn.js → tools-BpZh7hgB.js} +1 -1
  273. package/dist/public/{webmcp-CJymew4t.js → webmcp-CkfDZfZ0.js} +1 -1
  274. package/dist/server.js +1 -1
  275. package/package.json +1 -1
  276. package/src/cli/build/build.test.ts +95 -0
  277. package/src/cli/build/build.ts +5 -1
  278. package/src/cli/commands/agent.test.ts +134 -0
  279. package/src/cli/commands/backup.test.ts +85 -0
  280. package/src/cli/commands/clients.test.ts +32 -0
  281. package/src/cli/commands/mcp.test.ts +260 -1
  282. package/src/cli/commands/send-file.test.ts +73 -0
  283. package/src/cli/commands/send.test.ts +58 -0
  284. package/src/cli/commands/tasks.test.ts +78 -0
  285. package/src/cli/commands/webrtc-listen.test.ts +74 -0
  286. package/src/cli/tools/assert-version-bump.test.ts +30 -1
  287. package/src/cli/tools/file-search-replace.test.ts +33 -1
  288. package/src/cli/tools/patch-service-worker-trusted-types.test.ts +24 -1
  289. package/src/cli/tools/touch-nojekyll.test.ts +12 -0
  290. package/src/cli/tools/version.test.ts +109 -5
  291. package/src/cli/utils/agent-core.test.ts +40 -0
  292. package/src/cli/utils/control-client.test.ts +239 -2
  293. package/src/cli/utils/load-workspace-config.test.ts +63 -0
  294. package/src/cli/utils/local-models.test.ts +98 -0
  295. package/src/cli/utils/progress-bar.test.ts +41 -2
  296. package/src/cli/utils/resolve-cache-dir.test.ts +61 -0
  297. package/src/cli/utils/resolve-project-root.test.ts +17 -0
  298. package/src/cli/utils/stdin.test.ts +38 -0
  299. package/src/cli/utils/stdio.test.ts +51 -1
  300. package/src/cli/utils/suppress-warnings.test.ts +9 -0
  301. package/src/cli/utils/webrtc-control-client.test.ts +569 -0
  302. package/src/common/utils/frontmatter.test.ts +117 -0
  303. package/src/components/common/help/providers.test.ts +67 -0
  304. package/src/components/common/shadow-claw-provider-model-picker/shadow-claw-provider-model-picker.test.ts +121 -0
  305. package/src/components/settings/shadow-claw-accounts/shadow-claw-accounts.test.ts +131 -0
  306. package/src/components/settings/shadow-claw-git/shadow-claw-git.test.ts +130 -0
  307. package/src/components/settings/shadow-claw-integrations/connection-test-auth.test.ts +12 -0
  308. package/src/components/settings/shadow-claw-integrations/shadow-claw-integrations.test.ts +328 -0
  309. package/src/components/settings/shadow-claw-llm/model-ranking.test.ts +121 -7
  310. package/src/components/settings/shadow-claw-llm/model-ranking.ts +97 -0
  311. package/src/components/settings/shadow-claw-llm/shadow-claw-llm.test.ts +565 -8
  312. package/src/components/settings/shadow-claw-llm/shadow-claw-llm.ts +15 -5
  313. package/src/components/settings/shadow-claw-mcp-remote/shadow-claw-mcp-remote.test.ts +459 -0
  314. package/src/components/settings/shadow-claw-networking/shadow-claw-networking.test.ts +88 -0
  315. package/src/components/settings/shadow-claw-notifications/shadow-claw-notifications.test.ts +92 -0
  316. package/src/components/settings/shadow-claw-peerjs/shadow-claw-peerjs.test.ts +127 -0
  317. package/src/components/settings/shadow-claw-storage/shadow-claw-storage.test.ts +173 -0
  318. package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.test.ts +62 -0
  319. package/src/components/settings/shadow-claw-webvm/shadow-claw-webvm.test.ts +104 -0
  320. package/src/components/shadow-claw/shadow-claw.test.ts +112 -0
  321. package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.test.ts +109 -0
  322. package/src/components/shadow-claw-chat/shadow-claw-chat.html +81 -14
  323. package/src/components/shadow-claw-chat/shadow-claw-chat.test.ts +73 -0
  324. package/src/components/shadow-claw-chat/shadow-claw-chat.trusted-types.test.ts +3 -0
  325. package/src/components/shadow-claw-chat/shadow-claw-chat.ts +79 -32
  326. package/src/components/shadow-claw-conversations/shadow-claw-conversations.test.ts +361 -0
  327. package/src/components/shadow-claw-dialog/shadow-claw-dialog.test.ts +76 -0
  328. package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.test.ts +307 -0
  329. package/src/components/shadow-claw-files/shadow-claw-files.test.ts +398 -1
  330. package/src/components/shadow-claw-pages/shadow-claw-pages.test.ts +85 -0
  331. package/src/components/shadow-claw-pages/shadow-claw-pages.ts +2 -1
  332. package/src/components/shadow-claw-pdf-viewer/shadow-claw-pdf-viewer.test.ts +229 -0
  333. package/src/components/shadow-claw-settings/shadow-claw-settings.test.ts +233 -0
  334. package/src/components/shadow-claw-tasks/shadow-claw-tasks.test.ts +223 -1
  335. package/src/components/shadow-claw-toast/shadow-claw-toast.test.ts +79 -0
  336. package/src/components/shadow-claw-tools/shadow-claw-tools.test.ts +229 -1
  337. package/src/config/config.test.ts +4 -4
  338. package/src/config/config.ts +2 -1
  339. package/src/core/orchestrator/orchestrator.test.ts +2 -1
  340. package/src/core/orchestrator/utils/initTasks.ts +5 -4
  341. package/src/server/logger.test.ts +57 -0
  342. package/src/server/peer.test.ts +47 -0
  343. package/src/server/routes/gemini.test.ts +244 -0
  344. package/src/server/server-peer.test.ts +245 -11
  345. package/src/server/services/llamafile-manager.test.ts +668 -0
  346. package/src/share-target/pending-shares.test.ts +90 -0
  347. package/src/shell/fs.test.ts +125 -0
  348. package/src/shell/shell.test.ts +8 -0
  349. package/src/subsystems/git/credentials.test.ts +260 -0
  350. package/src/subsystems/git/git.test.ts +64 -0
  351. package/src/subsystems/providers/executeNativeAiTask.test.ts +78 -0
  352. package/src/subsystems/providers/utils/parseLocalModelToolCall.test.ts +57 -0
  353. package/src/worker/tools/builtin-ai/builtin-ai.test.ts +88 -0
  354. package/src/worker/tools/email/email.test.ts +358 -0
  355. package/src/worker/tools/email/utils/resolveIntegrationEmailAuth.test.ts +120 -0
  356. package/src/worker/tools/email/utils/resolveUniqueAttachmentPath.test.ts +80 -0
  357. package/src/worker/tools/fetch-file/fetch-file.test.ts +111 -0
  358. package/src/worker/tools/fetch-url/fetch-url.test.ts +295 -0
  359. package/dist/cli/chunk-B3S061IE.js +0 -1
  360. package/dist/cli/chunk-BUJdF9o3.js +0 -1
  361. package/dist/cli/chunk-BX0R2gIY.js +0 -1
  362. package/dist/cli/chunk-BoiPfhwJ.js +0 -1
  363. package/dist/cli/chunk-BtJYj7vB.js +0 -1
  364. package/dist/cli/chunk-BwXrZVeU.js +0 -1
  365. package/dist/cli/chunk-CaWh9Pru.js +0 -1
  366. package/dist/cli/chunk-Ck4ePI8z.js +0 -1
  367. package/dist/cli/chunk-Ctg-SXcP.js +0 -1
  368. package/dist/cli/chunk-DTKv1-tk.js +0 -1
  369. package/dist/cli/chunk-DdYpd9Nu.js +0 -1
  370. package/dist/cli/chunk-DflhmBY2.js +0 -1
  371. package/dist/lib/config-DxDaVDTn.js.map +0 -1
  372. package/dist/lib/model-ranking-CDXs7hkK.js +0 -57
  373. package/dist/lib/model-ranking-CDXs7hkK.js.map +0 -1
  374. package/dist/lib/shadow-claw-chat-D69IiLXd.js.map +0 -1
  375. package/dist/lib/shadow-claw-llm-AJwzkOGo.js.map +0 -1
  376. package/dist/public/config-Dqn5OMfC.js +0 -1
  377. package/dist/public/model-ranking-DLIC9IDU.js +0 -1
  378. package/dist/public/prompt-api-B-8N-MRY.js +0 -11
@@ -76,4 +76,83 @@ describe("shadow-claw-toast", () => {
76
76
  await new Promise((r) => setTimeout(r, 50));
77
77
  expect(onClick).toHaveBeenCalled();
78
78
  });
79
+
80
+ it("dismisses toast on Escape key press", async () => {
81
+ toastStore.show("Dismiss on esc", { type: "info" });
82
+ await el.render();
83
+
84
+ const toastEl = el.shadowRoot?.querySelector(".toast");
85
+ expect(toastEl).not.toBeNull();
86
+
87
+ const escEvent = new KeyboardEvent("keydown", {
88
+ key: "Escape",
89
+ bubbles: true,
90
+ cancelable: true,
91
+ });
92
+ toastEl?.dispatchEvent(escEvent);
93
+
94
+ await new Promise((r) => setTimeout(r, 250));
95
+ expect(toastStore.toasts.length).toBe(0);
96
+ });
97
+
98
+ it("ignores non-Escape keydown or invalid targets", async () => {
99
+ toastStore.show("Stay open", { type: "info" });
100
+ await el.render();
101
+
102
+ const enterEvent = new KeyboardEvent("keydown", {
103
+ key: "Enter",
104
+ bubbles: true,
105
+ cancelable: true,
106
+ });
107
+ el.shadowRoot?.dispatchEvent(enterEvent);
108
+
109
+ // Event on non-toast element
110
+ const escOnRoot = new KeyboardEvent("keydown", {
111
+ key: "Escape",
112
+ bubbles: false,
113
+ });
114
+ el.shadowRoot?.dispatchEvent(escOnRoot);
115
+
116
+ expect(toastStore.toasts.length).toBe(1);
117
+ });
118
+
119
+ it("pauses and resumes on mouseenter / mouseleave", async () => {
120
+ const pauseSpy = jest.spyOn(toastStore, "pause");
121
+ const resumeSpy = jest.spyOn(toastStore, "resume");
122
+
123
+ const id = toastStore.show("Hover me", { type: "warning" });
124
+ await el.render();
125
+
126
+ const toastEl = el.shadowRoot?.querySelector(".toast");
127
+ toastEl?.dispatchEvent(new MouseEvent("mouseenter"));
128
+ expect(pauseSpy).toHaveBeenCalledWith(id);
129
+
130
+ toastEl?.dispatchEvent(new MouseEvent("mouseleave"));
131
+ expect(resumeSpy).toHaveBeenCalledWith(id);
132
+ });
133
+
134
+ it("renders appropriate icons for all toast types", () => {
135
+ expect(el.iconForType("success")).toBe("✓");
136
+ expect(el.iconForType("error")).toBe("!");
137
+ expect(el.iconForType("warning")).toBe("⚠");
138
+ expect(el.iconForType("info")).toBe("i");
139
+ });
140
+
141
+ it("delegates show() to toastStore.show", () => {
142
+ const id = el.show("Via helper", { type: "success" });
143
+ expect(id).toBeDefined();
144
+ expect(toastStore.toasts.some((t) => t.message === "Via helper")).toBe(
145
+ true,
146
+ );
147
+ });
148
+
149
+ it("returns early if toast is already exiting", async () => {
150
+ const id = toastStore.show("Exiting toast", { type: "info" });
151
+ await el.render();
152
+
153
+ el.exitingToasts.add(id);
154
+ await el.dismissWithAnimation(id);
155
+ // Should not re-add or throw
156
+ expect(el.exitingToasts.has(id)).toBe(true);
157
+ });
79
158
  });
@@ -120,7 +120,8 @@ const { ShadowClawTools } = await import("./shadow-claw-tools.js");
120
120
  const { toolsStore } = (await import("../../stores/tools.js")) as any;
121
121
  const { orchestratorStore } =
122
122
  (await import("../../stores/orchestrator.js")) as any;
123
- const { showSuccess } = (await import("../../ui/toast.js")) as any;
123
+ const { showSuccess, showInfo, showError } =
124
+ (await import("../../ui/toast.js")) as any;
124
125
 
125
126
  describe("shadow-claw-tools", () => {
126
127
  beforeEach(() => {
@@ -636,4 +637,231 @@ describe("shadow-claw-tools", () => {
636
637
 
637
638
  document.body.removeChild(el);
638
639
  });
640
+
641
+ it("handles back button, add button, restore button, and select all/none", async () => {
642
+ const el = new ShadowClawTools();
643
+ document.body.appendChild(el);
644
+ await new Promise((r) => setTimeout(r, 50));
645
+ await el.render();
646
+
647
+ const root = el.shadowRoot!;
648
+
649
+ // 1. Back button
650
+ let backNavigated = false;
651
+ el.addEventListener("navigate-back", () => {
652
+ backNavigated = true;
653
+ });
654
+ const backBtn = root.querySelector(".tools__back-btn") as HTMLButtonElement;
655
+ backBtn?.dispatchEvent(new Event("click"));
656
+ expect(backNavigated).toBe(true);
657
+
658
+ // 2. Add button
659
+ const dialog = root.querySelector("dialog") as HTMLDialogElement;
660
+ dialog.showModal = jest.fn();
661
+ const addBtn = root.querySelector(".tools__add-btn") as HTMLButtonElement;
662
+ addBtn?.dispatchEvent(new Event("click"));
663
+ expect(dialog.showModal).toHaveBeenCalled();
664
+
665
+ // 3. Restore button
666
+ const restoreBtn = root.querySelector(
667
+ ".tools__restore-btn",
668
+ ) as HTMLButtonElement;
669
+ const restoreInput = root.querySelector(
670
+ ".tools__hidden-restore",
671
+ ) as HTMLInputElement;
672
+ const clickSpy = jest
673
+ .spyOn(restoreInput, "click")
674
+ .mockImplementation(() => {});
675
+ restoreBtn?.dispatchEvent(new Event("click"));
676
+ expect(clickSpy).toHaveBeenCalled();
677
+ clickSpy.mockRestore();
678
+
679
+ // 4. Select all / none
680
+ const selectAllBtn = root.querySelector(
681
+ ".tools__select-all-btn",
682
+ ) as HTMLButtonElement;
683
+ selectAllBtn?.dispatchEvent(new Event("click"));
684
+ expect(toolsStore.setAllEnabled).toHaveBeenCalled();
685
+ expect(showInfo).toHaveBeenCalledWith("All tools enabled");
686
+
687
+ const selectNoneBtn = root.querySelector(
688
+ ".tools__select-none-btn",
689
+ ) as HTMLButtonElement;
690
+ selectNoneBtn?.dispatchEvent(new Event("click"));
691
+ expect(showInfo).toHaveBeenCalledWith("All tools disabled");
692
+
693
+ document.body.removeChild(el);
694
+ });
695
+
696
+ it("handles WebMCP, internet access, and Web Search toggles", async () => {
697
+ const el = new ShadowClawTools();
698
+ document.body.appendChild(el);
699
+ await new Promise((r) => setTimeout(r, 50));
700
+ await el.render();
701
+
702
+ const root = el.shadowRoot!;
703
+
704
+ // 1. WebMCP toggle
705
+ const webMcpToggle = root.querySelector(
706
+ ".tools__webmcp-toggle",
707
+ ) as HTMLInputElement;
708
+ if (webMcpToggle) {
709
+ webMcpToggle.checked = true;
710
+ webMcpToggle.dispatchEvent(new Event("change"));
711
+ await new Promise((r) => setTimeout(r, 20));
712
+ expect(showInfo).toHaveBeenCalledWith("WebMCP tool registration enabled");
713
+
714
+ // Without orchestrator
715
+ el.orchestrator = null;
716
+ (orchestratorStore as any).orchestrator = null;
717
+ webMcpToggle.checked = true;
718
+ webMcpToggle.dispatchEvent(new Event("change"));
719
+ await new Promise((r) => setTimeout(r, 20));
720
+ expect(showError).toHaveBeenCalledWith("Orchestrator is not ready");
721
+
722
+ // Restore orchestrator
723
+ (orchestratorStore as any).orchestrator = {
724
+ getWebMcpToolsEnabled: jest.fn(() => true),
725
+ getWebMcpMode: jest.fn(() => "native"),
726
+ setWebMcpToolsEnabled: jest.fn(),
727
+ setWebMcpMode: jest.fn(),
728
+ };
729
+ }
730
+
731
+ // 2. Internet access toggle
732
+ const internetToggle = root.querySelector(
733
+ ".tools__internet-access-toggle",
734
+ ) as HTMLInputElement;
735
+ if (internetToggle) {
736
+ internetToggle.checked = true;
737
+ internetToggle.dispatchEvent(new Event("change"));
738
+ await new Promise((r) => setTimeout(r, 20));
739
+ expect(orchestratorStore.setVMBashFullInternetAccess).toHaveBeenCalled();
740
+ expect(showInfo).toHaveBeenCalledWith(
741
+ "Full internet access enabled for Bash and JavaScript tools",
742
+ );
743
+ }
744
+
745
+ // 3. Web Search proxy toggle
746
+ const proxyToggle = root.querySelector(
747
+ ".tools__websearch-proxy-toggle",
748
+ ) as HTMLInputElement;
749
+ if (proxyToggle) {
750
+ proxyToggle.checked = true;
751
+ proxyToggle.dispatchEvent(new Event("change"));
752
+ await new Promise((r) => setTimeout(r, 20));
753
+ expect(toolsStore.setWebSearchUseProxy).toHaveBeenCalled();
754
+ expect(showInfo).toHaveBeenCalledWith("Web Search local proxy enabled");
755
+ }
756
+
757
+ document.body.removeChild(el);
758
+ });
759
+
760
+ it("handles prompt override save, clear, and dialog controls", async () => {
761
+ const el = new ShadowClawTools();
762
+ document.body.appendChild(el);
763
+ await new Promise((r) => setTimeout(r, 50));
764
+ await el.render();
765
+
766
+ const root = el.shadowRoot!;
767
+
768
+ // 1. Save and Clear prompt
769
+ const textarea = root.querySelector(
770
+ ".tools__prompt-area",
771
+ ) as HTMLTextAreaElement;
772
+ if (textarea) textarea.value = "Custom system instructions";
773
+
774
+ const savePromptBtn = root.querySelector(
775
+ ".tools__save-prompt-btn",
776
+ ) as HTMLButtonElement;
777
+ savePromptBtn?.dispatchEvent(new Event("click"));
778
+ expect(toolsStore.setSystemPromptOverride).toHaveBeenCalled();
779
+ expect(showSuccess).toHaveBeenCalledWith("System prompt override saved");
780
+
781
+ const clearPromptBtn = root.querySelector(
782
+ ".tools__clear-prompt-btn",
783
+ ) as HTMLButtonElement;
784
+ clearPromptBtn?.dispatchEvent(new Event("click"));
785
+ expect(showSuccess).toHaveBeenCalledWith("System prompt override cleared");
786
+
787
+ // 2. Dialog controls (close, cancel, backdrop)
788
+ const dialog = root.querySelector(".tools__dialog") as HTMLDialogElement;
789
+ if (dialog) {
790
+ dialog.close = jest.fn();
791
+ const closeBtn = dialog.querySelector(
792
+ ".tools__dialog-close",
793
+ ) as HTMLButtonElement;
794
+ closeBtn?.dispatchEvent(new Event("click"));
795
+ expect(dialog.close).toHaveBeenCalledTimes(1);
796
+
797
+ const cancelBtn = dialog.querySelector(
798
+ ".tools__btn-cancel",
799
+ ) as HTMLButtonElement;
800
+ cancelBtn?.dispatchEvent(new Event("click"));
801
+ expect(dialog.close).toHaveBeenCalledTimes(2);
802
+
803
+ Object.defineProperty(dialog, "target", { value: dialog });
804
+ dialog.dispatchEvent(new MouseEvent("click", { bubbles: true }));
805
+ expect(dialog.close).toHaveBeenCalledTimes(3);
806
+ }
807
+
808
+ // 3. Clone dialog controls
809
+ const cloneDialog = root.querySelector(
810
+ ".tools__clone-dialog",
811
+ ) as HTMLDialogElement;
812
+ if (cloneDialog) {
813
+ cloneDialog.close = jest.fn();
814
+ const cloneCloseBtn = root.querySelector(
815
+ ".tools__clone-dialog-close",
816
+ ) as HTMLButtonElement;
817
+ cloneCloseBtn?.dispatchEvent(new Event("click"));
818
+ expect(cloneDialog.close).toHaveBeenCalledTimes(1);
819
+
820
+ const cloneCancelBtn = root.querySelector(
821
+ ".tools__clone-cancel-btn",
822
+ ) as HTMLButtonElement;
823
+ cloneCancelBtn?.dispatchEvent(new Event("click"));
824
+ expect(cloneDialog.close).toHaveBeenCalledTimes(2);
825
+ }
826
+
827
+ // 4. Profile dialog controls and Profile select
828
+ const profileDialog = root.querySelector(
829
+ ".tools__profile-dialog",
830
+ ) as HTMLDialogElement;
831
+ if (profileDialog) {
832
+ profileDialog.close = jest.fn();
833
+ const profileCloseBtn = root.querySelector(
834
+ ".tools__profile-dialog-close",
835
+ ) as HTMLButtonElement;
836
+ profileCloseBtn?.dispatchEvent(new Event("click"));
837
+ expect(profileDialog.close).toHaveBeenCalledTimes(1);
838
+
839
+ const profileCancelBtn = root.querySelector(
840
+ ".tools__profile-cancel-btn",
841
+ ) as HTMLButtonElement;
842
+ profileCancelBtn?.dispatchEvent(new Event("click"));
843
+ expect(profileDialog.close).toHaveBeenCalledTimes(2);
844
+
845
+ Object.defineProperty(profileDialog, "target", { value: profileDialog });
846
+ profileDialog.dispatchEvent(new MouseEvent("click", { bubbles: true }));
847
+ expect(profileDialog.close).toHaveBeenCalledTimes(3);
848
+ }
849
+
850
+ const profileSelect = root.querySelector(
851
+ ".tools__profile-select",
852
+ ) as HTMLSelectElement;
853
+ if (profileSelect) {
854
+ profileSelect.value = "custom_profile";
855
+ profileSelect.dispatchEvent(new Event("change"));
856
+ expect(toolsStore.activateProfile).toHaveBeenCalled();
857
+ expect(showInfo).toHaveBeenCalledWith("Profile activated");
858
+
859
+ profileSelect.value = "";
860
+ profileSelect.dispatchEvent(new Event("change"));
861
+ expect(toolsStore.deactivateProfile).toHaveBeenCalled();
862
+ expect(showInfo).toHaveBeenCalledWith("Profile deactivated");
863
+ }
864
+
865
+ document.body.removeChild(el);
866
+ });
639
867
  });
@@ -67,7 +67,7 @@ describe("config.js", () => {
67
67
  });
68
68
 
69
69
  it("should have valid DEFAULT_PROVIDER", () => {
70
- expect(DEFAULT_PROVIDER).toBe("prompt_api");
70
+ expect(DEFAULT_PROVIDER).toBe("transformers_js_browser");
71
71
  });
72
72
 
73
73
  it("should have valid SCHEDULER_INTERVAL", () => {
@@ -561,10 +561,10 @@ describe("config.js", () => {
561
561
  expect(provider.id).toBe(DEFAULT_PROVIDER);
562
562
  });
563
563
 
564
- it("default provider should be valid prompt_api config", () => {
564
+ it("default provider should be valid transformers_js_browser config", () => {
565
565
  const provider = getDefaultProvider();
566
- expect(provider.name).toBe("Prompt API (Browser)");
567
- expect(provider.format).toBe("prompt_api");
566
+ expect(provider.name).toBe("Transformers.js (Browser)");
567
+ expect(provider.format).toBe("transformers_js");
568
568
  });
569
569
  });
570
570
 
@@ -191,7 +191,7 @@ export function getModelMaxTokens(modelId: string): number {
191
191
  }
192
192
 
193
193
  /** Default provider */
194
- export const DEFAULT_PROVIDER = "prompt_api";
194
+ export const DEFAULT_PROVIDER = "transformers_js_browser";
195
195
 
196
196
  /** Task scheduler check interval (ms) */
197
197
  export const SCHEDULER_INTERVAL = 60_000;
@@ -1129,6 +1129,7 @@ export const CONFIG_KEYS = {
1129
1129
  PROMPT_API_DTYPE_STRATEGY: "prompt_api_dtype_strategy",
1130
1130
  PROMPT_API_FALLBACK_MODEL: "prompt_api_fallback_model",
1131
1131
  PROMPT_API_ONBOARDING_SEEN: "prompt_api_onboarding_seen",
1132
+ TRANSFORMERS_JS_ONBOARDING_SEEN: "transformers_js_onboarding_seen",
1132
1133
  PEERJS_MY_ALIAS: "peerjs_my_alias",
1133
1134
  PEERJS_MY_PEER_ID: "peerjs_my_peer_id",
1134
1135
  PEERJS_PEER_ALIASES: "peerjs_peer_aliases",
@@ -1554,7 +1554,7 @@ describe("Orchestrator", () => {
1554
1554
  trustedPeerIds: [],
1555
1555
  });
1556
1556
 
1557
- expect(o.provider).toBe("prompt_api");
1557
+ expect(o.provider).toBe("transformers_js_browser");
1558
1558
  expect(o.proxyUrl).toBe("/proxy");
1559
1559
 
1560
1560
  expect(o.rateLimitAutoAdapt).toBe(true);
@@ -2424,6 +2424,7 @@ describe("Orchestrator", () => {
2424
2424
 
2425
2425
  // Active request restarted
2426
2426
  o.state = "thinking";
2427
+ o.provider = "prompt_api";
2427
2428
  o.inFlightTriggerByGroup.set("g-restart", "Original prompt");
2428
2429
  o.agentWorker = {
2429
2430
  postMessage: jest.fn(),
@@ -291,11 +291,12 @@ export async function initProviderAndModel(
291
291
  getConfig(db, CONFIG_KEYS.RATE_LIMIT_AUTO_ADAPT),
292
292
  ]);
293
293
 
294
- const matchedProvider = storedProvider
295
- ? getProvider(storedProvider)
294
+ const effectiveProvider = storedProvider || orchestrator.provider;
295
+ const matchedProvider = effectiveProvider
296
+ ? getProvider(effectiveProvider)
296
297
  : undefined;
297
- if (storedProvider && matchedProvider) {
298
- orchestrator.provider = storedProvider;
298
+ if (matchedProvider) {
299
+ orchestrator.provider = effectiveProvider;
299
300
  orchestrator.providerConfig = matchedProvider;
300
301
  }
301
302
 
@@ -0,0 +1,57 @@
1
+ import { jest } from "@jest/globals";
2
+ import { createLogger } from "./logger.js";
3
+
4
+ describe("createLogger", () => {
5
+ let logSpy: any;
6
+ let errorSpy: any;
7
+
8
+ beforeEach(() => {
9
+ logSpy = jest.spyOn(console, "log").mockImplementation(() => {});
10
+ errorSpy = jest.spyOn(console, "error").mockImplementation(() => {});
11
+ });
12
+
13
+ afterEach(() => {
14
+ logSpy.mockRestore();
15
+ errorSpy.mockRestore();
16
+ });
17
+
18
+ it("logs DEFAULT level messages in non-verbose mode", () => {
19
+ const logger = createLogger(false);
20
+ logger.log("DEFAULT", "standard log");
21
+ expect(logSpy).toHaveBeenCalledWith(
22
+ expect.stringContaining("[LOG]"),
23
+ "standard log",
24
+ );
25
+
26
+ logger.log("VERBOSE", "hidden log");
27
+ expect(logSpy).toHaveBeenCalledTimes(1);
28
+ });
29
+
30
+ it("logs VERBOSE level messages when verbose is true", () => {
31
+ const logger = createLogger(true);
32
+ logger.log("VERBOSE", "verbose log");
33
+ expect(logSpy).toHaveBeenCalledWith(
34
+ expect.stringContaining("[VERBOSE]"),
35
+ "verbose log",
36
+ );
37
+ });
38
+
39
+ it("logs errors in DEFAULT and VERBOSE levels", () => {
40
+ const logger = createLogger(false);
41
+ logger.error("DEFAULT", "standard error");
42
+ expect(errorSpy).toHaveBeenCalledWith(
43
+ expect.stringContaining("[ERROR]"),
44
+ "standard error",
45
+ );
46
+
47
+ logger.error("VERBOSE", "hidden error");
48
+ expect(errorSpy).toHaveBeenCalledTimes(1);
49
+
50
+ const verboseLogger = createLogger(true);
51
+ verboseLogger.error("VERBOSE", "verbose error");
52
+ expect(errorSpy).toHaveBeenCalledWith(
53
+ expect.stringContaining("[VERBOSE ERROR]"),
54
+ "verbose error",
55
+ );
56
+ });
57
+ });
@@ -0,0 +1,47 @@
1
+ import { jest } from "@jest/globals";
2
+ import { EventEmitter } from "node:events";
3
+
4
+ describe("attachPeerServer", () => {
5
+ it("attaches ExpressPeerServer and listens to connection and disconnect events", async () => {
6
+ const mockPeerServer: any = new EventEmitter();
7
+ const expressPeerServerMock = jest.fn(() => mockPeerServer);
8
+
9
+ jest.unstable_mockModule("peer", () => ({
10
+ ExpressPeerServer: expressPeerServerMock,
11
+ }));
12
+
13
+ const { attachPeerServer } = await import("./peer.js");
14
+
15
+ const mockHttpServer: any = {};
16
+ const mockApp: any = {
17
+ use: jest.fn(),
18
+ };
19
+
20
+ const logSpy = jest.spyOn(console, "log").mockImplementation(() => {});
21
+
22
+ try {
23
+ attachPeerServer(mockHttpServer, mockApp);
24
+
25
+ expect(expressPeerServerMock).toHaveBeenCalledWith(mockHttpServer, {
26
+ path: "/",
27
+ allow_discovery: false,
28
+ });
29
+ expect(mockApp.use).toHaveBeenCalledWith(mockPeerServer);
30
+
31
+ const mockClient = { getId: () => "peer-client-123" };
32
+ mockPeerServer.emit("connection", mockClient);
33
+ expect(logSpy).toHaveBeenCalledWith(
34
+ expect.stringContaining("PeerJS: client connected — peer-client-123"),
35
+ );
36
+
37
+ mockPeerServer.emit("disconnect", mockClient);
38
+ expect(logSpy).toHaveBeenCalledWith(
39
+ expect.stringContaining(
40
+ "PeerJS: client disconnected — peer-client-123",
41
+ ),
42
+ );
43
+ } finally {
44
+ logSpy.mockRestore();
45
+ }
46
+ });
47
+ });