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
@@ -1,5 +1,16 @@
1
1
  import { jest } from "@jest/globals";
2
2
 
3
+ jest.unstable_mockModule("../../storage/readGroupFileBytes.js", () => ({
4
+ readGroupFileBytes: jest.fn(
5
+ async (_db: any, _groupId: string, filePath: string) => {
6
+ if (filePath.includes("error")) {
7
+ throw new Error("File read error");
8
+ }
9
+ return new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
10
+ },
11
+ ),
12
+ }));
13
+
3
14
  import { setDB } from "../../db/db.js";
4
15
  import { registerBasicFunctions } from "../../ui/a2ui/registries/basicFunctions.js";
5
16
  import { A2UI_BASIC_CATALOG_ID } from "../../ui/a2ui/types.js";
@@ -1791,4 +1802,102 @@ describe("Basic catalog components unit tests", () => {
1791
1802
 
1792
1803
  document.body.removeChild(el);
1793
1804
  });
1805
+
1806
+ it("resolves workspace media and poster paths to blob URLs", async () => {
1807
+ const el = document.createElement("shadow-claw-a2ui") as any;
1808
+ el.groupId = "peer:media-group";
1809
+ document.body.appendChild(el);
1810
+
1811
+ await (el as any).onTemplateReady;
1812
+
1813
+ el.applyEnvelope({
1814
+ version: "v1.0" as const,
1815
+ type: "createSurface",
1816
+ surfaceId: "media-blob-surface",
1817
+ catalogId: A2UI_BASIC_CATALOG_ID,
1818
+ components: [
1819
+ {
1820
+ id: "root",
1821
+ component: "Column",
1822
+ children: ["img-png", "img-gif", "img-webp", "vid-mp4", "aud-mp3"],
1823
+ },
1824
+ {
1825
+ id: "img-png",
1826
+ component: "Image",
1827
+ url: "sample.png",
1828
+ },
1829
+ {
1830
+ id: "img-gif",
1831
+ component: "Image",
1832
+ url: "sample.gif",
1833
+ },
1834
+ {
1835
+ id: "img-webp",
1836
+ component: "Image",
1837
+ url: "sample.webp",
1838
+ },
1839
+ {
1840
+ id: "vid-mp4",
1841
+ component: "Video",
1842
+ url: "sample.mp4",
1843
+ posterUrl: "poster.jpg",
1844
+ },
1845
+ {
1846
+ id: "aud-mp3",
1847
+ component: "AudioPlayer",
1848
+ url: "sample.mp3",
1849
+ },
1850
+ ] as any,
1851
+ dataModel: {},
1852
+ });
1853
+
1854
+ // Wait for async media resolution
1855
+ await new Promise((resolve) => setTimeout(resolve, 80));
1856
+
1857
+ const root = el.shadowRoot;
1858
+ const imgs = root?.querySelectorAll("img");
1859
+ const video = root?.querySelector("video");
1860
+ const audio = root?.querySelector("audio");
1861
+
1862
+ expect(imgs?.length).toBeGreaterThanOrEqual(3);
1863
+ imgs?.forEach((img: HTMLImageElement) => {
1864
+ expect(img.src).toContain("mock-blob");
1865
+ expect(img.hasAttribute("data-a2ui-workspace-src")).toBe(false);
1866
+ });
1867
+
1868
+ expect(video?.src).toContain("mock-blob");
1869
+ expect(video?.poster).toContain("mock-blob");
1870
+ expect(audio?.src).toContain("mock-blob");
1871
+
1872
+ // Test error handling in resolveSingleMediaToBlobUrl and resolveVideoPosterToBlobUrl
1873
+ el.applyEnvelope({
1874
+ version: "v1.0" as const,
1875
+ type: "createSurface",
1876
+ surfaceId: "media-error-surface",
1877
+ catalogId: A2UI_BASIC_CATALOG_ID,
1878
+ components: [
1879
+ {
1880
+ id: "root",
1881
+ component: "Column",
1882
+ children: ["img-err", "vid-err"],
1883
+ },
1884
+ {
1885
+ id: "img-err",
1886
+ component: "Image",
1887
+ url: "error.png",
1888
+ },
1889
+ {
1890
+ id: "vid-err",
1891
+ component: "Video",
1892
+ url: "error.mp4",
1893
+ posterUrl: "error-poster.jpg",
1894
+ },
1895
+ ] as any,
1896
+ dataModel: {},
1897
+ });
1898
+
1899
+ await new Promise((resolve) => setTimeout(resolve, 80));
1900
+
1901
+ document.body.removeChild(el);
1902
+ });
1794
1903
  });
@@ -153,14 +153,14 @@
153
153
 
154
154
  <shadow-claw-dialog
155
155
  dialog-class="chat__prompt-api-dialog"
156
- dialog-aria-label="Prompt API Onboarding"
156
+ dialog-aria-label="Local AI Onboarding"
157
157
  >
158
158
  <form class="chat__prompt-api-form" method="dialog">
159
159
  <div class="chat__prompt-api-header">
160
160
  <div class="chat__prompt-api-icon" aria-hidden="true">&#10024;</div>
161
161
  <div>
162
162
  <h3 class="chat__prompt-api-title">
163
- Welcome to Local AI (Prompt API)
163
+ Welcome to Local AI (Transformers.js)
164
164
  </h3>
165
165
  <p class="chat__prompt-api-subtitle">
166
166
  On-device intelligence built directly into your browser.
@@ -172,13 +172,16 @@
172
172
  <section class="chat__prompt-api-card">
173
173
  <h4>&#128274; 100% On-Device</h4>
174
174
  <p>
175
- ShadowClaw defaults to the browser-native
176
- <strong>Prompt API</strong>. Models execute directly on your
175
+ ShadowClaw defaults to
176
+ <strong>Transformers.js</strong>. Models execute directly on your
177
177
  hardware with no API keys and no subscription costs.
178
178
  </p>
179
179
  </section>
180
180
 
181
- <section class="chat__prompt-api-card chat__prompt-api-status-card">
181
+ <section
182
+ class="chat__prompt-api-card chat__prompt-api-status-card"
183
+ hidden
184
+ >
182
185
  <h4>&#127760; Browser Capabilities</h4>
183
186
  <div
184
187
  class="chat__prompt-api-status-content"
@@ -199,11 +202,10 @@
199
202
  </section>
200
203
 
201
204
  <section class="chat__prompt-api-card chat__prompt-api-fallback-card">
202
- <h4>&#9881;&#65039; Default Prompt API Model</h4>
205
+ <h4>&#9881;&#65039; Default Transformers.js Model</h4>
203
206
  <p class="chat__prompt-api-model-desc">
204
- Choose your default Prompt API fallback model. If native browser
205
- Prompt API is not enabled, ShadowClaw will run this local model
206
- directly in the browser:
207
+ Choose your default Transformers.js model. ShadowClaw will run
208
+ this local model directly in the browser:
207
209
  </p>
208
210
  <div class="chat__prompt-api-select-group">
209
211
  <label class="form-label" for="prompt-api-fallback-model-select"
@@ -230,6 +232,71 @@
230
232
  onnx-community/gemma-4-E4B-it-ONNX &mdash; Alternative (4B
231
233
  Parameters, 128k Context)
232
234
  </option>
235
+ <hr />
236
+ <option value="HuggingFaceTB/SmolLM3-3B-ONNX">
237
+ HuggingFaceTB/SmolLM3-3B-ONNX
238
+ </option>
239
+ <option value="LiquidAI/LFM2.5-1.2B-Thinking-ONNX">
240
+ LiquidAI/LFM2.5-1.2B-Thinking-ONNX &#128736;&#65039;
241
+ </option>
242
+ <option
243
+ value="onnx-community/DeepSeek-R1-Distill-Qwen-1.5B-ONNX"
244
+ >
245
+ onnx-community/DeepSeek-R1-Distill-Qwen-1.5B-ONNX
246
+ &#128736;&#65039;
247
+ </option>
248
+ <option value="onnx-community/LFM2-1.2B-ONNX">
249
+ onnx-community/LFM2-1.2B-ONNX
250
+ </option>
251
+ <option value="onnx-community/Llama-3.2-1B-Instruct-ONNX">
252
+ onnx-community/Llama-3.2-1B-Instruct-ONNX &#128736;&#65039;
253
+ </option>
254
+ <option value="onnx-community/Llama-3.2-3B-Instruct-ONNX">
255
+ onnx-community/Llama-3.2-3B-Instruct-ONNX &#128736;&#65039;
256
+ </option>
257
+ <option value="onnx-community/Phi-3.5-mini-instruct-onnx-web">
258
+ onnx-community/Phi-3.5-mini-instruct-onnx-web
259
+ &#128736;&#65039;
260
+ </option>
261
+ <option value="onnx-community/Phi-4-mini-instruct-ONNX">
262
+ onnx-community/Phi-4-mini-instruct-ONNX &#128736;&#65039;
263
+ </option>
264
+ <option value="onnx-community/Qwen3.5-0.8B-ONNX-OPT">
265
+ onnx-community/Qwen3.5-0.8B-ONNX-OPT
266
+ </option>
267
+ <option value="onnx-community/Qwen3.5-4B-ONNX-OPT">
268
+ onnx-community/Qwen3.5-4B-ONNX-OPT
269
+ </option>
270
+ <option value="onnx-community/gemma-3-1b-it-ONNX">
271
+ onnx-community/gemma-3-1b-it-ONNX &#128736;&#65039;
272
+ </option>
273
+ <option value="onnx-community/gemma-4-12B-it-ONNX">
274
+ onnx-community/gemma-4-12B-it-ONNX &#128736;&#65039;
275
+ </option>
276
+ <option value="onnx-community/gemma-4-12B-it-qat-mobile-ONNX">
277
+ onnx-community/gemma-4-12B-it-qat-mobile-ONNX
278
+ &#128736;&#65039;
279
+ </option>
280
+ <option value="onnx-community/gemma-4-E27B-it-ONNX">
281
+ onnx-community/gemma-4-E27B-it-ONNX &#128736;&#65039;
282
+ </option>
283
+ <option value="onnx-community/gemma-4-E2B-it-qat-mobile-ONNX">
284
+ onnx-community/gemma-4-E2B-it-qat-mobile-ONNX
285
+ &#128736;&#65039;
286
+ </option>
287
+ <option value="onnx-community/gemma-4-E4B-it-qat-mobile-ONNX">
288
+ onnx-community/gemma-4-E4B-it-qat-mobile-ONNX
289
+ &#128736;&#65039;
290
+ </option>
291
+ <option value="onnx-community/gemma-4-E9B-it-ONNX">
292
+ onnx-community/gemma-4-E9B-it-ONNX &#128736;&#65039;
293
+ </option>
294
+ <option value="onnx-community/gpt-oss-20b-ONNX">
295
+ onnx-community/gpt-oss-20b-ONNX
296
+ </option>
297
+ <option value="webgpu/Qwen3-4B-ONNX">
298
+ webgpu/Qwen3-4B-ONNX
299
+ </option>
233
300
  </select>
234
301
  </div>
235
302
  </section>
@@ -237,10 +304,10 @@
237
304
  <section class="chat__prompt-api-card">
238
305
  <h4>&#127760; Prefer Cloud AI or Another Provider?</h4>
239
306
  <p>
240
- Local AI with Prompt API is free and private, but not your only
241
- option. ShadowClaw also supports OpenRouter, Anthropic, OpenAI,
242
- Google Gemini, and AWS Bedrock. You can configure any provider at
243
- any time in Settings.
307
+ Local AI with Transformers.js is free and private, but not your
308
+ only option. ShadowClaw also supports OpenRouter, Anthropic,
309
+ OpenAI, Google Gemini, and AWS Bedrock. You can configure any
310
+ provider at any time in Settings.
244
311
  </p>
245
312
  </section>
246
313
  </div>
@@ -258,7 +325,7 @@
258
325
  class="chat__prompt-api-confirm-btn"
259
326
  data-action="confirm-prompt-api-onboarding"
260
327
  >
261
- Continue with Prompt API
328
+ Continue with Transformers.js
262
329
  </button>
263
330
  </div>
264
331
  </form>
@@ -415,6 +415,15 @@ describe("shadow-claw-chat UX enhancements (issue #10)", () => {
415
415
  'value="onnx-community/gemma-4-E4B-it-ONNX"',
416
416
  );
417
417
  });
418
+
419
+ it("should reword onboarding dialog to Transformers.js and local AI", () => {
420
+ expect(templateHtml).toContain("Welcome to Local AI (Transformers.js)");
421
+ expect(templateHtml).toContain("Continue with Transformers.js");
422
+ expect(templateHtml).toContain("ShadowClaw defaults to");
423
+ expect(templateHtml).toContain("Transformers.js");
424
+ expect(templateHtml).not.toContain("Welcome to Local AI (Prompt API)");
425
+ expect(templateHtml).not.toContain("Continue with Prompt API");
426
+ });
418
427
  });
419
428
 
420
429
  describe("AUTO_SCROLL_THRESHOLD constant", () => {
@@ -1355,6 +1364,9 @@ describe("shadow-claw-chat prompt api onboarding", () => {
1355
1364
  expect(storedConfig["prompt_api_fallback_model"]).toBe(
1356
1365
  "onnx-community/Qwen3-0.6B-ONNX",
1357
1366
  );
1367
+ expect(storedConfig["provider"]).toBe("transformers_js_browser");
1368
+ expect(storedConfig["model"]).toBe("onnx-community/Qwen3-0.6B-ONNX");
1369
+ expect(storedConfig["transformers_js_onboarding_seen"]).toBe("true");
1358
1370
  expect(storedConfig["prompt_api_onboarding_seen"]).toBe("true");
1359
1371
  expect(mockDialog.close).toHaveBeenCalledTimes(1);
1360
1372
  });
@@ -1433,6 +1445,67 @@ describe("shadow-claw-chat prompt api onboarding", () => {
1433
1445
  }
1434
1446
  });
1435
1447
 
1448
+ it("should populate onboarding model select with top 4 prompt api models and alphabetized remainder", () => {
1449
+ const instance = Object.create(ShadowClawChat.prototype);
1450
+ const mockSelectEl: any = {
1451
+ innerHTML: "",
1452
+ value: "",
1453
+ };
1454
+
1455
+ instance.populateOnboardingModelSelect(
1456
+ mockSelectEl,
1457
+ "onnx-community/Qwen3-0.6B-ONNX",
1458
+ );
1459
+
1460
+ expect(mockSelectEl.value).toBe("onnx-community/Qwen3-0.6B-ONNX");
1461
+ // Ensure top 4 models are rendered
1462
+ expect(mockSelectEl.innerHTML).toContain(
1463
+ 'value="onnx-community/Qwen3-0.6B-ONNX"',
1464
+ );
1465
+ expect(mockSelectEl.innerHTML).toContain(
1466
+ 'value="onnx-community/gemma-3-1b-it-ONNX-GQA"',
1467
+ );
1468
+ expect(mockSelectEl.innerHTML).toContain(
1469
+ 'value="onnx-community/gemma-4-E2B-it-ONNX"',
1470
+ );
1471
+ expect(mockSelectEl.innerHTML).toContain(
1472
+ 'value="onnx-community/gemma-4-E4B-it-ONNX"',
1473
+ );
1474
+ // Ensure remainder models are present
1475
+ expect(mockSelectEl.innerHTML).toContain(
1476
+ 'value="HuggingFaceTB/SmolLM3-3B-ONNX"',
1477
+ );
1478
+ expect(mockSelectEl.innerHTML).toContain('value="webgpu/Qwen3-4B-ONNX"');
1479
+
1480
+ // Verify ordering in rendered HTML
1481
+ const idxQwen3 = mockSelectEl.innerHTML.indexOf(
1482
+ 'value="onnx-community/Qwen3-0.6B-ONNX"',
1483
+ );
1484
+ const idxGemma3 = mockSelectEl.innerHTML.indexOf(
1485
+ 'value="onnx-community/gemma-3-1b-it-ONNX-GQA"',
1486
+ );
1487
+ const idxGemma4E2B = mockSelectEl.innerHTML.indexOf(
1488
+ 'value="onnx-community/gemma-4-E2B-it-ONNX"',
1489
+ );
1490
+ const idxGemma4E4B = mockSelectEl.innerHTML.indexOf(
1491
+ 'value="onnx-community/gemma-4-E4B-it-ONNX"',
1492
+ );
1493
+ const idxSmol = mockSelectEl.innerHTML.indexOf(
1494
+ 'value="HuggingFaceTB/SmolLM3-3B-ONNX"',
1495
+ );
1496
+ const idxWebgpu = mockSelectEl.innerHTML.indexOf(
1497
+ 'value="webgpu/Qwen3-4B-ONNX"',
1498
+ );
1499
+
1500
+ expect(idxQwen3).toBeLessThan(idxGemma3);
1501
+ expect(idxGemma3).toBeLessThan(idxGemma4E2B);
1502
+ expect(idxGemma4E2B).toBeLessThan(idxGemma4E4B);
1503
+ const idxHr = mockSelectEl.innerHTML.indexOf("<hr>");
1504
+ expect(idxHr).toBeGreaterThan(idxGemma4E4B);
1505
+ expect(idxHr).toBeLessThan(idxSmol);
1506
+ expect(idxSmol).toBeLessThan(idxWebgpu);
1507
+ });
1508
+
1436
1509
  describe("ShadowClawChat helper methods", () => {
1437
1510
  let instance: any;
1438
1511
 
@@ -108,6 +108,9 @@ jest.unstable_mockModule("../../utils/utils.js", () => ({
108
108
  formatTimestamp: jest.fn(() => "now"),
109
109
  handleSpecialLinkNavigation: jest.fn(() => false),
110
110
  computeSha256: jest.fn(async (_: ArrayBuffer) => "mock-hash"),
111
+ escapeHtml: jest.fn((text: string) => text.replace(/</g, "&lt;")),
112
+ sanitizeGroupId: jest.fn((id: string) => id.replace(/[^a-zA-Z0-9-]/g, "-")),
113
+ sanitizeHtml: jest.fn((html: string) => html),
111
114
  }));
112
115
 
113
116
  jest.unstable_mockModule(
@@ -5,6 +5,7 @@ import {
5
5
  CONFIG_KEYS,
6
6
  DEFAULT_PROMPT_API_FALLBACK_MODEL,
7
7
  DEFAULT_PROVIDER,
8
+ PROVIDERS,
8
9
  } from "../../config/config.js";
9
10
  import { decodePathSegment } from "../../core/app-routes.js";
10
11
 
@@ -64,10 +65,7 @@ import {
64
65
  handleSpecialLinkNavigation,
65
66
  } from "../../utils/utils.js";
66
67
  import { isTruthyConfigValue } from "../../utils/parseBooleanConfig.js";
67
- import {
68
- isNativePromptApiAvailable,
69
- renderPromptApiStatusHtml,
70
- } from "../common/help/prompt-api.js";
68
+ import { renderTransformersJsBrowserModelOptions } from "../settings/shadow-claw-llm/model-ranking.js";
71
69
 
72
70
  import { computeTokenDisplayValues } from "./utils/computeTokenDisplayValues.js";
73
71
  import { escapeHtml } from "./utils/escapeHtml.js";
@@ -1979,6 +1977,11 @@ export class ShadowClawChat extends ShadowClawElement {
1979
1977
 
1980
1978
  if (this.db) {
1981
1979
  try {
1980
+ await setConfig(
1981
+ this.db,
1982
+ CONFIG_KEYS.TRANSFORMERS_JS_ONBOARDING_SEEN,
1983
+ "true",
1984
+ );
1982
1985
  await setConfig(
1983
1986
  this.db,
1984
1987
  CONFIG_KEYS.PROMPT_API_ONBOARDING_SEEN,
@@ -2031,14 +2034,16 @@ export class ShadowClawChat extends ShadowClawElement {
2031
2034
  typeof provider === "string" && provider.trim()
2032
2035
  ? provider.trim()
2033
2036
  : DEFAULT_PROVIDER;
2034
- if (effectiveProvider !== "prompt_api") {
2037
+ if (effectiveProvider !== "transformers_js_browser") {
2035
2038
  return;
2036
2039
  }
2037
2040
 
2038
- const seen = await getConfig(
2039
- this.db,
2040
- CONFIG_KEYS.PROMPT_API_ONBOARDING_SEEN,
2041
- );
2041
+ const seen =
2042
+ (await getConfig(
2043
+ this.db,
2044
+ CONFIG_KEYS.TRANSFORMERS_JS_ONBOARDING_SEEN,
2045
+ )) ||
2046
+ (await getConfig(this.db, CONFIG_KEYS.PROMPT_API_ONBOARDING_SEEN));
2042
2047
  if (isTruthyConfigValue(seen, false)) {
2043
2048
  return;
2044
2049
  }
@@ -2050,42 +2055,53 @@ export class ShadowClawChat extends ShadowClawElement {
2050
2055
 
2051
2056
  this.ensureShadowDialogs();
2052
2057
 
2053
- const isNativeSupported = await isNativePromptApiAvailable();
2054
- const isAvailable = isNativeSupported;
2055
-
2056
2058
  const statusCard = root.querySelector(".chat__prompt-api-status-card");
2057
2059
  if (statusCard) {
2058
- (statusCard as HTMLElement).hidden = !isAvailable;
2059
- }
2060
-
2061
- const statusEl = root.querySelector('[data-info="prompt-api-status"]');
2062
- if (statusEl) {
2063
- setSanitizedHtml(
2064
- statusEl as HTMLElement,
2065
- renderPromptApiStatusHtml(isNativeSupported),
2066
- );
2060
+ (statusCard as HTMLElement).hidden = true;
2067
2061
  }
2068
2062
 
2069
2063
  const fallbackCard = root.querySelector(
2070
2064
  ".chat__prompt-api-fallback-card",
2071
2065
  );
2072
2066
  if (fallbackCard) {
2073
- (fallbackCard as HTMLElement).hidden = isAvailable;
2067
+ (fallbackCard as HTMLElement).hidden = false;
2074
2068
  }
2075
2069
 
2076
2070
  const modelSelect = root.querySelector(
2077
2071
  '[data-setting="prompt-api-onboarding-fallback-model"]',
2078
2072
  ) as HTMLSelectElement | null;
2079
2073
  if (modelSelect) {
2080
- const storedFallbackModel = await getConfig(
2081
- this.db,
2082
- CONFIG_KEYS.PROMPT_API_FALLBACK_MODEL,
2083
- );
2074
+ const storedModel =
2075
+ (await getConfig(this.db, CONFIG_KEYS.MODEL)) ||
2076
+ (await getConfig(this.db, CONFIG_KEYS.PROMPT_API_FALLBACK_MODEL));
2084
2077
  const currentModel =
2085
- typeof storedFallbackModel === "string" && storedFallbackModel.trim()
2086
- ? storedFallbackModel.trim()
2087
- : DEFAULT_PROMPT_API_FALLBACK_MODEL;
2088
- modelSelect.value = currentModel;
2078
+ typeof storedModel === "string" && storedModel.trim()
2079
+ ? storedModel.trim()
2080
+ : PROVIDERS.transformers_js_browser?.defaultModel ||
2081
+ "onnx-community/Qwen3-0.6B-ONNX";
2082
+
2083
+ this.populateOnboardingModelSelect(modelSelect, currentModel);
2084
+
2085
+ const modelsUrl = PROVIDERS.transformers_js_browser?.modelsUrl;
2086
+ if (modelsUrl && typeof fetch === "function") {
2087
+ fetch(modelsUrl)
2088
+ .then((r) => (r.ok ? r.json() : null))
2089
+ .then((data) => {
2090
+ if (!data) return;
2091
+ const items = Array.isArray(data)
2092
+ ? data
2093
+ : data.models || data.data || [];
2094
+ if (Array.isArray(items) && items.length > 0) {
2095
+ const currentSelected = modelSelect.value || currentModel;
2096
+ this.populateOnboardingModelSelect(
2097
+ modelSelect,
2098
+ currentSelected,
2099
+ items,
2100
+ );
2101
+ }
2102
+ })
2103
+ .catch(() => {});
2104
+ }
2089
2105
  }
2090
2106
 
2091
2107
  const shadowDialog = root.querySelector(
@@ -2111,6 +2127,19 @@ export class ShadowClawChat extends ShadowClawElement {
2111
2127
  }
2112
2128
  }
2113
2129
 
2130
+ populateOnboardingModelSelect(
2131
+ modelSelect: HTMLSelectElement,
2132
+ selectedModel: string,
2133
+ modelItems?: any[],
2134
+ ): void {
2135
+ const html = renderTransformersJsBrowserModelOptions(
2136
+ selectedModel,
2137
+ modelItems,
2138
+ );
2139
+ setSanitizedHtml(modelSelect, html);
2140
+ modelSelect.value = selectedModel;
2141
+ }
2142
+
2114
2143
  async confirmPromptApiOnboarding(): Promise<void> {
2115
2144
  const root = this.shadowRoot;
2116
2145
  if (!root) {
@@ -2125,15 +2154,28 @@ export class ShadowClawChat extends ShadowClawElement {
2125
2154
  '[data-setting="prompt-api-onboarding-fallback-model"]',
2126
2155
  ) as HTMLSelectElement | null;
2127
2156
  const selectedModel =
2128
- modelSelect?.value?.trim() || DEFAULT_PROMPT_API_FALLBACK_MODEL;
2157
+ modelSelect?.value?.trim() ||
2158
+ PROVIDERS.transformers_js_browser?.defaultModel ||
2159
+ DEFAULT_PROMPT_API_FALLBACK_MODEL;
2129
2160
 
2130
2161
  if (this.db) {
2131
2162
  try {
2163
+ await setConfig(
2164
+ this.db,
2165
+ CONFIG_KEYS.PROVIDER,
2166
+ "transformers_js_browser",
2167
+ );
2168
+ await setConfig(this.db, CONFIG_KEYS.MODEL, selectedModel);
2132
2169
  await setConfig(
2133
2170
  this.db,
2134
2171
  CONFIG_KEYS.PROMPT_API_FALLBACK_MODEL,
2135
2172
  selectedModel,
2136
2173
  );
2174
+ await setConfig(
2175
+ this.db,
2176
+ CONFIG_KEYS.TRANSFORMERS_JS_ONBOARDING_SEEN,
2177
+ "true",
2178
+ );
2137
2179
  await setConfig(
2138
2180
  this.db,
2139
2181
  CONFIG_KEYS.PROMPT_API_ONBOARDING_SEEN,
@@ -2144,6 +2186,11 @@ export class ShadowClawChat extends ShadowClawElement {
2144
2186
  }
2145
2187
  }
2146
2188
 
2189
+ if (orchestratorStore.orchestrator) {
2190
+ orchestratorStore.orchestrator.provider = "transformers_js_browser";
2191
+ orchestratorStore.orchestrator.model = selectedModel;
2192
+ }
2193
+
2147
2194
  const shadowDialog = root.querySelector(
2148
2195
  'shadow-claw-dialog[dialog-class="chat__prompt-api-dialog"]',
2149
2196
  );
@@ -2156,7 +2203,7 @@ export class ShadowClawChat extends ShadowClawElement {
2156
2203
  }
2157
2204
  }
2158
2205
 
2159
- showSuccess("Prompt API configured", 2500);
2206
+ showSuccess("Transformers.js configured", 2500);
2160
2207
  }
2161
2208
 
2162
2209
  async downloadAttachment(groupId: string, attachment: MessageAttachment) {