shadow-claw 1.31.0 → 1.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/.well-known/mcp/server-card.json +1 -1
  2. package/.well-known/mcp.json +1 -1
  3. package/dist/electron/main.cjs +1 -1
  4. package/dist/lib/components/index.js +26 -26
  5. package/dist/lib/components/settings/shadow-claw-accounts.js +1 -1
  6. package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
  7. package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
  8. package/dist/lib/components/settings/shadow-claw-git.js +1 -1
  9. package/dist/lib/components/settings/shadow-claw-integrations.js +1 -1
  10. package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
  11. package/dist/lib/components/settings/shadow-claw-mcp-remote.js +1 -1
  12. package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
  13. package/dist/lib/components/settings/shadow-claw-notifications.js +1 -1
  14. package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
  15. package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
  16. package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
  17. package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
  18. package/dist/lib/components/shadow-claw-a2ui.js +1 -1
  19. package/dist/lib/components/shadow-claw-accounts.js +1 -1
  20. package/dist/lib/components/shadow-claw-channel-config.js +1 -1
  21. package/dist/lib/components/shadow-claw-channels.js +1 -1
  22. package/dist/lib/components/shadow-claw-chat.js +1 -1
  23. package/dist/lib/components/shadow-claw-control-plane.js +1 -1
  24. package/dist/lib/components/shadow-claw-conversations.js +1 -1
  25. package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
  26. package/dist/lib/components/shadow-claw-files.js +1 -1
  27. package/dist/lib/components/shadow-claw-git.js +1 -1
  28. package/dist/lib/components/shadow-claw-integrations.js +1 -1
  29. package/dist/lib/components/shadow-claw-llm.js +1 -1
  30. package/dist/lib/components/shadow-claw-mcp-remote.js +1 -1
  31. package/dist/lib/components/shadow-claw-networking.js +1 -1
  32. package/dist/lib/components/shadow-claw-notifications.js +1 -1
  33. package/dist/lib/components/shadow-claw-page-header.js +1 -1
  34. package/dist/lib/components/shadow-claw-pages.js +1 -1
  35. package/dist/lib/components/shadow-claw-peerjs.js +1 -1
  36. package/dist/lib/components/shadow-claw-settings.js +1 -1
  37. package/dist/lib/components/shadow-claw-storage.js +1 -1
  38. package/dist/lib/components/shadow-claw-task-server.js +1 -1
  39. package/dist/lib/components/shadow-claw-tasks.js +1 -1
  40. package/dist/lib/components/shadow-claw-terminal.js +1 -1
  41. package/dist/lib/components/shadow-claw-tools.js +1 -1
  42. package/dist/lib/components/shadow-claw-webvm.js +1 -1
  43. package/dist/lib/components/shadow-claw.js +1 -1
  44. package/dist/lib/{config-DjZ9QWc4.js → config-BcFbkaQv.js} +21 -4
  45. package/dist/lib/config-BcFbkaQv.js.map +1 -0
  46. package/dist/lib/{configurePeerJs-u7CYSquX.js → configurePeerJs-CBMPHbwa.js} +3 -3
  47. package/dist/lib/{configurePeerJs-u7CYSquX.js.map → configurePeerJs-CBMPHbwa.js.map} +1 -1
  48. package/dist/lib/{connections-BURqMIUv.js → connections-PZrUDf49.js} +2 -2
  49. package/dist/lib/{connections-BURqMIUv.js.map → connections-PZrUDf49.js.map} +1 -1
  50. package/dist/lib/{downloadGroupFile-B8J4up2a.js → downloadGroupFile-DSRUa9Au.js} +2 -2
  51. package/dist/lib/{downloadGroupFile-B8J4up2a.js.map → downloadGroupFile-DSRUa9Au.js.map} +1 -1
  52. package/dist/lib/{file-viewer-DoHM75Jz.js → file-viewer-11VVOpJv.js} +5 -5
  53. package/dist/lib/{file-viewer-DoHM75Jz.js.map → file-viewer-11VVOpJv.js.map} +1 -1
  54. package/dist/lib/{getGroupDir-QrN2aTo8.js → getGroupDir-BxKMYPPm.js} +3 -3
  55. package/dist/lib/{getGroupDir-QrN2aTo8.js.map → getGroupDir-BxKMYPPm.js.map} +1 -1
  56. package/dist/lib/{git-DAP_EV6R.js → git-BppibnJW.js} +27 -10
  57. package/dist/lib/{git-DAP_EV6R.js.map → git-BppibnJW.js.map} +1 -1
  58. package/dist/lib/{iframe-sanitizer-Bujgq14T.js → iframe-sanitizer-Dp8EYffI.js} +2 -2
  59. package/dist/lib/{iframe-sanitizer-Bujgq14T.js.map → iframe-sanitizer-Dp8EYffI.js.map} +1 -1
  60. package/dist/lib/index.js +27 -27
  61. package/dist/lib/{initChatSplitResize-BjiWoqC_.js → initChatSplitResize-CE_kWaLf.js} +2 -2
  62. package/dist/lib/{initChatSplitResize-BjiWoqC_.js.map → initChatSplitResize-CE_kWaLf.js.map} +1 -1
  63. package/dist/lib/{initControlPlane-DCK_SHeR.js → initControlPlane-BRIIOzoH.js} +18 -17
  64. package/dist/lib/{initControlPlane-DCK_SHeR.js.map → initControlPlane-BRIIOzoH.js.map} +1 -1
  65. package/dist/lib/{markdown-BFUTPQoO.js → markdown-Cq4sVwUT.js} +4 -4
  66. package/dist/lib/{markdown-BFUTPQoO.js.map → markdown-Cq4sVwUT.js.map} +1 -1
  67. package/dist/lib/{mcp-reconnect-BxJ77WSb.js → mcp-reconnect-CoHDMjmY.js} +2 -2
  68. package/dist/lib/{mcp-reconnect-BxJ77WSb.js.map → mcp-reconnect-CoHDMjmY.js.map} +1 -1
  69. package/dist/lib/{memoryStorage-D3FBwO9T.js → memoryStorage-DcFWrn_y.js} +2 -2
  70. package/dist/lib/{memoryStorage-D3FBwO9T.js.map → memoryStorage-DcFWrn_y.js.map} +1 -1
  71. package/dist/lib/{orchestrator-DNamnY-k.js → orchestrator-C3TgDZvq.js} +100 -19
  72. package/dist/lib/{orchestrator-DNamnY-k.js.map → orchestrator-C3TgDZvq.js.map} +1 -1
  73. package/dist/lib/{orchestrator-XygttQw2.js → orchestrator-Ce9_lmL2.js} +12 -12
  74. package/dist/lib/{orchestrator-XygttQw2.js.map → orchestrator-Ce9_lmL2.js.map} +1 -1
  75. package/dist/lib/{peerjs-BgkPSHKa.js → peerjs-PTYQ7yEG.js} +6 -6
  76. package/dist/lib/{peerjs-BgkPSHKa.js.map → peerjs-PTYQ7yEG.js.map} +1 -1
  77. package/dist/lib/{push-client-C09NQEk5.js → push-client-DDV5Rcg6.js} +3 -3
  78. package/dist/lib/{push-client-C09NQEk5.js.map → push-client-DDV5Rcg6.js.map} +1 -1
  79. package/dist/lib/{readGroupFileBytes-CSA7u-nJ.js → readGroupFileBytes-7C8G-yps.js} +2 -2
  80. package/dist/lib/{readGroupFileBytes-CSA7u-nJ.js.map → readGroupFileBytes-7C8G-yps.js.map} +1 -1
  81. package/dist/lib/{shadow-claw-vzcggiax.js → shadow-claw-WrWoPqFx.js} +10 -10
  82. package/dist/lib/{shadow-claw-vzcggiax.js.map → shadow-claw-WrWoPqFx.js.map} +1 -1
  83. package/dist/lib/{shadow-claw-a2ui-2I5nffIn.js → shadow-claw-a2ui-CcmJNXQP.js} +2 -2
  84. package/dist/lib/{shadow-claw-a2ui-2I5nffIn.js.map → shadow-claw-a2ui-CcmJNXQP.js.map} +1 -1
  85. package/dist/lib/{shadow-claw-accounts-DMb0y4ca.js → shadow-claw-accounts-CcB2429E.js} +3 -3
  86. package/dist/lib/{shadow-claw-accounts-DMb0y4ca.js.map → shadow-claw-accounts-CcB2429E.js.map} +1 -1
  87. package/dist/lib/{shadow-claw-channel-config-Cl3JvxIJ.js → shadow-claw-channel-config-C4v0h8oa.js} +3 -3
  88. package/dist/lib/{shadow-claw-channel-config-Cl3JvxIJ.js.map → shadow-claw-channel-config-C4v0h8oa.js.map} +1 -1
  89. package/dist/lib/{shadow-claw-channels-kv21lr_O.js → shadow-claw-channels-CyV88k9T.js} +3 -3
  90. package/dist/lib/{shadow-claw-channels-kv21lr_O.js.map → shadow-claw-channels-CyV88k9T.js.map} +1 -1
  91. package/dist/lib/{shadow-claw-chat-Cj1fHQIl.js → shadow-claw-chat-DSYtuZod.js} +11 -11
  92. package/dist/lib/{shadow-claw-chat-Cj1fHQIl.js.map → shadow-claw-chat-DSYtuZod.js.map} +1 -1
  93. package/dist/lib/{shadow-claw-control-plane-DySeKB36.js → shadow-claw-control-plane-DBSGuDT1.js} +7 -7
  94. package/dist/lib/{shadow-claw-control-plane-DySeKB36.js.map → shadow-claw-control-plane-DBSGuDT1.js.map} +1 -1
  95. package/dist/lib/{shadow-claw-conversations-DghueOOD.js → shadow-claw-conversations-Cp8pK4PM.js} +5 -5
  96. package/dist/lib/{shadow-claw-conversations-DghueOOD.js.map → shadow-claw-conversations-Cp8pK4PM.js.map} +1 -1
  97. package/dist/lib/{shadow-claw-file-viewer-C_ITv8T6.js → shadow-claw-file-viewer-B8G8yo48.js} +8 -8
  98. package/dist/lib/{shadow-claw-file-viewer-C_ITv8T6.js.map → shadow-claw-file-viewer-B8G8yo48.js.map} +1 -1
  99. package/dist/lib/{shadow-claw-files-CWBaYt9p.js → shadow-claw-files-D1COKzuC.js} +9 -9
  100. package/dist/lib/{shadow-claw-files-CWBaYt9p.js.map → shadow-claw-files-D1COKzuC.js.map} +1 -1
  101. package/dist/lib/{shadow-claw-git-XfPBpfXd.js → shadow-claw-git-60tWU4Ee.js} +6 -6
  102. package/dist/lib/{shadow-claw-git-XfPBpfXd.js.map → shadow-claw-git-60tWU4Ee.js.map} +1 -1
  103. package/dist/lib/{shadow-claw-integrations-yT7j07TM.js → shadow-claw-integrations-Bw1cG1ze.js} +4 -4
  104. package/dist/lib/{shadow-claw-integrations-yT7j07TM.js.map → shadow-claw-integrations-Bw1cG1ze.js.map} +1 -1
  105. package/dist/lib/{shadow-claw-llm-Gzx4ufL_.js → shadow-claw-llm-By5CvsFJ.js} +6 -6
  106. package/dist/lib/{shadow-claw-llm-Gzx4ufL_.js.map → shadow-claw-llm-By5CvsFJ.js.map} +1 -1
  107. package/dist/lib/{shadow-claw-mcp-remote-DGDWjByQ.js → shadow-claw-mcp-remote-BaNODd1v.js} +4 -4
  108. package/dist/lib/{shadow-claw-mcp-remote-DGDWjByQ.js.map → shadow-claw-mcp-remote-BaNODd1v.js.map} +1 -1
  109. package/dist/lib/{shadow-claw-networking-CYEbc5TR.js → shadow-claw-networking-DtZ5bsTz.js} +2 -2
  110. package/dist/lib/{shadow-claw-networking-CYEbc5TR.js.map → shadow-claw-networking-DtZ5bsTz.js.map} +1 -1
  111. package/dist/lib/{shadow-claw-notifications-DHvkTrgv.js → shadow-claw-notifications-C3VEba_A.js} +3 -3
  112. package/dist/lib/{shadow-claw-notifications-DHvkTrgv.js.map → shadow-claw-notifications-C3VEba_A.js.map} +1 -1
  113. package/dist/lib/{shadow-claw-page-header-DrAcWCZ9.js → shadow-claw-page-header-BLowJopA.js} +2 -2
  114. package/dist/lib/{shadow-claw-page-header-DrAcWCZ9.js.map → shadow-claw-page-header-BLowJopA.js.map} +1 -1
  115. package/dist/lib/{shadow-claw-pages-Bj3w3V6Y.js → shadow-claw-pages-CpeUV-hw.js} +9 -9
  116. package/dist/lib/{shadow-claw-pages-Bj3w3V6Y.js.map → shadow-claw-pages-CpeUV-hw.js.map} +1 -1
  117. package/dist/lib/{shadow-claw-peerjs-B3sx2xLA.js → shadow-claw-peerjs-DYAzJbTy.js} +3 -3
  118. package/dist/lib/{shadow-claw-peerjs-B3sx2xLA.js.map → shadow-claw-peerjs-DYAzJbTy.js.map} +1 -1
  119. package/dist/lib/{shadow-claw-settings-DK-0kp3A.js → shadow-claw-settings-ByxwW3WK.js} +9 -9
  120. package/dist/lib/{shadow-claw-settings-DK-0kp3A.js.map → shadow-claw-settings-ByxwW3WK.js.map} +1 -1
  121. package/dist/lib/{shadow-claw-storage-p9nVMQPF.js → shadow-claw-storage-CsSPYVDJ.js} +5 -5
  122. package/dist/lib/{shadow-claw-storage-p9nVMQPF.js.map → shadow-claw-storage-CsSPYVDJ.js.map} +1 -1
  123. package/dist/lib/{shadow-claw-task-server-BNKCWG2M.js → shadow-claw-task-server-De2WCEw4.js} +2 -2
  124. package/dist/lib/{shadow-claw-task-server-BNKCWG2M.js.map → shadow-claw-task-server-De2WCEw4.js.map} +1 -1
  125. package/dist/lib/{shadow-claw-tasks-Dbq9rUku.js → shadow-claw-tasks-zHWT4GaE.js} +7 -7
  126. package/dist/lib/{shadow-claw-tasks-Dbq9rUku.js.map → shadow-claw-tasks-zHWT4GaE.js.map} +1 -1
  127. package/dist/lib/{shadow-claw-terminal-Wk2qRWJ9.js → shadow-claw-terminal-Bpawfv4N.js} +2 -2
  128. package/dist/lib/{shadow-claw-terminal-Wk2qRWJ9.js.map → shadow-claw-terminal-Bpawfv4N.js.map} +1 -1
  129. package/dist/lib/{shadow-claw-tools-C9TEf2k7.js → shadow-claw-tools-BbKdWcps.js} +7 -7
  130. package/dist/lib/{shadow-claw-tools-C9TEf2k7.js.map → shadow-claw-tools-BbKdWcps.js.map} +1 -1
  131. package/dist/lib/{shadow-claw-webvm-VoKerWW8.js → shadow-claw-webvm-DLqK0AxW.js} +3 -3
  132. package/dist/lib/{shadow-claw-webvm-VoKerWW8.js.map → shadow-claw-webvm-DLqK0AxW.js.map} +1 -1
  133. package/dist/lib/subsystems/git/git.d.ts +8 -1
  134. package/dist/lib/subsystems/git/types.d.ts +7 -1
  135. package/dist/lib/subsystems/mcp/webmcp.d.ts +37 -0
  136. package/dist/lib/subsystems/providers/model-registry.d.ts +4 -1
  137. package/dist/lib/subsystems/providers/providers.d.ts +10 -0
  138. package/dist/lib/{syncWebMcpRegistration-DEs4JjI_.js → syncWebMcpRegistration-mlbbvcdm.js} +5 -5
  139. package/dist/lib/{syncWebMcpRegistration-DEs4JjI_.js.map → syncWebMcpRegistration-mlbbvcdm.js.map} +1 -1
  140. package/dist/lib/{tools-f1WPNDSS.js → tools-Bb2ujM2E.js} +4 -4
  141. package/dist/lib/{tools-f1WPNDSS.js.map → tools-Bb2ujM2E.js.map} +1 -1
  142. package/dist/lib/utils/index.js +1 -1
  143. package/dist/lib/utils/utils.js +1 -1
  144. package/dist/lib/{utils-B99XP70b.js → utils-mpsYPfS7.js} +3 -3
  145. package/dist/lib/{utils-B99XP70b.js.map → utils-mpsYPfS7.js.map} +1 -1
  146. package/dist/lib/webmcp-BVR2lBVo.js +1544 -0
  147. package/dist/lib/webmcp-BVR2lBVo.js.map +1 -0
  148. package/dist/public/.well-known/mcp/server-card.json +1 -1
  149. package/dist/public/.well-known/mcp.json +1 -1
  150. package/dist/public/agent.worker.js +44 -44
  151. package/dist/public/config-BqecTktB.js +1 -0
  152. package/dist/public/{configurePeerJs-B68egTBd.js → configurePeerJs-BPKfWuEt.js} +1 -1
  153. package/dist/public/{connections-6575KDGE.js → connections-C_3tYsmX.js} +1 -1
  154. package/dist/public/{custom-element-security-Da_6HQ6X.js → custom-element-security-DXwU3Lae.js} +1 -1
  155. package/dist/public/docs/example/article/index.html +2 -2
  156. package/dist/public/docs/publishing/index.html +2 -2
  157. package/dist/public/docs/skill-creator/index.html +2 -2
  158. package/dist/public/docs/subsystems/tools.md +4 -3
  159. package/dist/public/docs/subsystems/webmcp.md +58 -13
  160. package/dist/public/{downloadGroupFile-Dj-AMNsd.js → downloadGroupFile-DTyf5DIC.js} +1 -1
  161. package/dist/public/{e2e-bridge-DQ4Mb_eC.js → e2e-bridge-DXwWCQKw.js} +1 -1
  162. package/dist/public/{file-viewer-BqNHyqzy.js → file-viewer-ConEyDDG.js} +1 -1
  163. package/dist/public/{getGroupDir-BwprrdrQ.js → getGroupDir-ZfZsiq6d.js} +1 -1
  164. package/dist/public/git-BtBaLC1-.js +100 -0
  165. package/dist/public/git-DgFF7xTW.js +100 -0
  166. package/dist/public/{iframe-sanitizer-viROQkRn.js → iframe-sanitizer-Corkvo_d.js} +1 -1
  167. package/dist/public/index.html +2 -2
  168. package/dist/public/index.js +1 -1
  169. package/dist/public/{initChatSplitResize-BA18wLQQ.js → initChatSplitResize-CUc-TEmT.js} +1 -1
  170. package/dist/public/{initControlPlane-DG_LcLDy.js → initControlPlane-B_uYS8a4.js} +1 -1
  171. package/dist/public/main/index.html +2 -2
  172. package/dist/public/main/memory/index.html +2 -2
  173. package/dist/public/{markdown-eFKxxpVP.js → markdown-Cfa6GuJs.js} +1 -1
  174. package/dist/public/{mcp-reconnect-CBHuaYdF.js → mcp-reconnect-CUOkdPEz.js} +1 -1
  175. package/dist/public/{memoryStorage-C1llaYus.js → memoryStorage-Bh8fjmip.js} +1 -1
  176. package/dist/public/{orchestrator-BXwxW4N2.js → orchestrator-BcSzrg6E.js} +2 -2
  177. package/dist/public/{orchestrator-DAJkyJmV.js → orchestrator-Bi5OdVZD.js} +11 -11
  178. package/dist/public/{peerjs-BaDbzfgl.js → peerjs-CzCXG-NW.js} +1 -1
  179. package/dist/public/{push-client-B1CCaldJ.js → push-client-Cr3Ruahp.js} +1 -1
  180. package/dist/public/service-worker.js +1 -1
  181. package/dist/public/{shadow-claw-CpBmveOh.js → shadow-claw-CzUYuuOa.js} +2 -2
  182. package/dist/public/{shadow-claw-accounts-D1y-zbMs.js → shadow-claw-accounts-BgIHB_aP.js} +1 -1
  183. package/dist/public/{shadow-claw-channels-7Oew09u0.js → shadow-claw-channels-Ce_trJ5D.js} +1 -1
  184. package/dist/public/{shadow-claw-chat-CskwjDzZ.js → shadow-claw-chat-CdECLLwL.js} +1 -1
  185. package/dist/public/{shadow-claw-control-plane-BqjEyhx7.js → shadow-claw-control-plane-DM62UmOz.js} +2 -2
  186. package/dist/public/{shadow-claw-conversations-ClGgBPVY.js → shadow-claw-conversations-AM5g3C00.js} +1 -1
  187. package/dist/public/{shadow-claw-file-viewer-rDepUwFJ.js → shadow-claw-file-viewer-BP7gWS5g.js} +1 -1
  188. package/dist/public/{shadow-claw-files-C0r05PYf.js → shadow-claw-files-RPPGszcK.js} +1 -1
  189. package/dist/public/{shadow-claw-git-CXrECHKy.js → shadow-claw-git-BsHEvLrb.js} +2 -2
  190. package/dist/public/{shadow-claw-integrations-CRGL78Fy.js → shadow-claw-integrations-B0vbcOqg.js} +1 -1
  191. package/dist/public/{shadow-claw-llm-jeGVNciG.js → shadow-claw-llm-FNNamrc_.js} +2 -2
  192. package/dist/public/{shadow-claw-mcp-remote-DyGnK4S_.js → shadow-claw-mcp-remote-7mDgniQu.js} +1 -1
  193. package/dist/public/{shadow-claw-networking--q6MgEAT.js → shadow-claw-networking-CGsetaLp.js} +1 -1
  194. package/dist/public/{shadow-claw-notifications-CrFUF0fl.js → shadow-claw-notifications-pnwRcR-4.js} +1 -1
  195. package/dist/public/{shadow-claw-page-header-DA-FG08G.js → shadow-claw-page-header-BUy15Poz.js} +1 -1
  196. package/dist/public/{shadow-claw-pages-_n1wVXAV.js → shadow-claw-pages-ILAjGWNk.js} +1 -1
  197. package/dist/public/{shadow-claw-settings-5yIfa3ie.js → shadow-claw-settings-Bx5IgVqN.js} +3 -3
  198. package/dist/public/{shadow-claw-storage-PLX9EFGn.js → shadow-claw-storage-PAtNykaF.js} +1 -1
  199. package/dist/public/{shadow-claw-task-server-BMps7aSr.js → shadow-claw-task-server-Cbbi_2OO.js} +1 -1
  200. package/dist/public/{shadow-claw-tasks-CHO1xvsu.js → shadow-claw-tasks-B-jKYWZJ.js} +1 -1
  201. package/dist/public/{shadow-claw-terminal-BJnSXRsb.js → shadow-claw-terminal-BRejND-Z.js} +1 -1
  202. package/dist/public/{shadow-claw-tools-BHfxRckC.js → shadow-claw-tools-DNQe3oa-.js} +1 -1
  203. package/dist/public/{shadow-claw-webvm-CyI23mQT.js → shadow-claw-webvm-BFuwRifU.js} +1 -1
  204. package/dist/public/{syncWebMcpRegistration-R0tha3kP.js → syncWebMcpRegistration-FxKAPwaz.js} +1 -1
  205. package/dist/public/theme-init.js +1 -1
  206. package/dist/public/{tools-Cp1gequ8.js → tools-BwQKGsro.js} +1 -1
  207. package/dist/public/transformers-js.worker.js +1 -1
  208. package/dist/public/webmcp-C28PAlfy.js +1 -0
  209. package/dist/server.js +1 -1
  210. package/package.json +3 -3
  211. package/src/core/utils/initControlPlane.test.ts +122 -1
  212. package/src/core/utils/initControlPlane.ts +12 -8
  213. package/src/storage/staticMainSite.ts +16 -2
  214. package/src/stores/orchestrator.test.ts +33 -0
  215. package/src/stores/orchestrator.ts +36 -0
  216. package/src/subsystems/git/git.test.ts +99 -0
  217. package/src/subsystems/git/git.ts +92 -12
  218. package/src/subsystems/git/types.ts +7 -0
  219. package/src/subsystems/mcp/webmcp.test.ts +253 -1
  220. package/src/subsystems/mcp/webmcp.ts +147 -4
  221. package/src/subsystems/providers/model-registry.test.ts +139 -0
  222. package/src/subsystems/providers/model-registry.ts +54 -2
  223. package/src/subsystems/providers/providers.test.ts +329 -0
  224. package/src/subsystems/providers/providers.ts +135 -11
  225. package/dist/lib/config-DjZ9QWc4.js.map +0 -1
  226. package/dist/lib/webmcp-BC8_WafM.js +0 -1710
  227. package/dist/lib/webmcp-BC8_WafM.js.map +0 -1
  228. package/dist/public/config-Bnwx4EfS.js +0 -1
  229. package/dist/public/git-BDaM5VT5.js +0 -100
  230. package/dist/public/git-D4n46G9B.js +0 -100
  231. package/dist/public/webmcp-DBONjQWd.js +0 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://modelcontextprotocol.io/schemas/server-card/v1.json",
3
3
  "name": "shadow-claw",
4
- "version": "1.31.0",
4
+ "version": "1.33.0",
5
5
  "description": "Browser-native personal AI assistant with local and remote LLM orchestration, Web Workers, OPFS storage, and agentic tool execution.",
6
6
  "title": "ShadowClaw MCP Server",
7
7
  "websiteUrl": "https://xt-ml.github.io/shadow-claw/",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://modelcontextprotocol.io/schemas/server-card/v1.json",
3
3
  "name": "shadow-claw",
4
- "version": "1.31.0",
4
+ "version": "1.33.0",
5
5
  "description": "Browser-native personal AI assistant with local and remote LLM orchestration, Web Workers, OPFS storage, and agentic tool execution.",
6
6
  "title": "ShadowClaw MCP Server",
7
7
  "websiteUrl": "https://xt-ml.github.io/shadow-claw/",
@@ -58,7 +58,7 @@ t.exports=a,t.exports.append=r;var n=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;function r
58
58
  )
59
59
  `);try{$e.exec(`ALTER TABLE scheduled_tasks ADD COLUMN type TEXT`)}catch{}try{$e.exec(`ALTER TABLE scheduled_tasks ADD COLUMN tools TEXT`)}catch{}try{$e.exec(`ALTER TABLE scheduled_tasks ADD COLUMN channel TEXT`)}catch{}try{$e.exec(`ALTER TABLE scheduled_tasks ADD COLUMN subscriber_id TEXT`)}catch{}try{$e.exec(`ALTER TABLE scheduled_tasks ADD COLUMN name TEXT`)}catch{}try{$e.exec(`ALTER TABLE scheduled_tasks ADD COLUMN task_order INTEGER`)}catch{}return $e}function nt(e){if(!$e)throw Error(`Task schedule store not opened. Call openTaskScheduleStore() first.`);$e.prepare(`INSERT OR REPLACE INTO scheduled_tasks
60
60
  (id, group_id, schedule, type, prompt, tools, enabled, last_run, created_at, channel, subscriber_id, name, task_order)
61
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(e.id,e.groupId,e.schedule,e.type??null,e.prompt,e.tools?JSON.stringify(e.tools):null,e.enabled===!1?0:1,e.lastRun??null,e.createdAt,e.channel??null,e.subscriberId??null,e.name??null,e.order??null)}function rt(e){if(!$e)throw Error(`Task schedule store not opened.`);$e.prepare(`DELETE FROM scheduled_tasks WHERE id = ?`).run(e)}function it(e){if(!$e)throw Error(`Task schedule store not opened.`);let t=$e.prepare(`SELECT * FROM scheduled_tasks WHERE id = ?`).get(e);return t?et(t):void 0}function at(e,t){if(!$e)throw Error(`Task schedule store not opened.`);if(e&&t){let n=$e.prepare(`SELECT * FROM scheduled_tasks WHERE group_id = ? AND (subscriber_id = ? OR subscriber_id IS NULL) ORDER BY created_at DESC`).all(e,t);return n?n.map(e=>et(e)).filter(e=>e.subscriber_id===null||e.subscriber_id===t):[]}if(e){let t=$e.prepare(`SELECT * FROM scheduled_tasks WHERE group_id = ? ORDER BY created_at DESC`).all(e);return t?t.map(e=>et(e)):[]}if(t){let e=$e.prepare(`SELECT * FROM scheduled_tasks WHERE subscriber_id = ? ORDER BY created_at DESC`).all(t);return e?e.map(e=>et(e)):[]}let n=$e.prepare(`SELECT * FROM scheduled_tasks ORDER BY created_at DESC`).all();return n?n.map(e=>et(e)):[]}function ot(){if(!$e)throw Error(`Task schedule store not opened.`);let e=$e.prepare(`SELECT * FROM scheduled_tasks WHERE enabled = 1`).all();return e?e.map(e=>et(e)):[]}function st(e,t){if(!$e)throw Error(`Task schedule store not opened.`);$e.prepare(`UPDATE scheduled_tasks SET last_run = ? WHERE id = ?`).run(t,e)}function ct(e){e.post(`/schedule/tasks`,(e,t)=>{let n=e.body;if(!n?.id||!n?.groupId||!n?.schedule)return t.status(400).json({error:`Missing required fields: id, groupId, schedule`});if(n?.type===`tools`&&(!n.tools||n.tools.length===0))return t.status(400).json({error:`Missing required fields: tools array cannot be empty for WebMCP Tools task`});if(n?.type!==`tools`&&!n?.prompt)return t.status(400).json({error:`Missing required fields: prompt is required for Prompt tasks`});nt(n),t.sendStatus(201)}),e.get(`/schedule/tasks`,(e,t)=>{let n=e.query.groupId,r=e.query.subscriberId,i=at(n,r);if(n&&r){let e=i.filter(e=>e.subscriber_id===null).length;e>0&&console.warn(`Found ${e} legacy scheduled task(s) with NULL subscriber_id for group ${n}`)}t.json(i)}),e.get(`/schedule/tasks/:id`,(e,t)=>{let n=it(e.params.id);if(!n)return t.status(404).json({error:`Task not found`});t.json(n)}),e.delete(`/schedule/tasks/:id`,(e,t)=>{let n=e.query.subscriberId;if(n){let r=it(e.params.id);if(!r||r.subscriber_id!==null&&r.subscriber_id!==n)return t.status(404).json({error:`Task not found`});rt(e.params.id)}else rt(e.params.id);t.sendStatus(200)}),e.patch(`/schedule/tasks/:id/enable`,(e,t)=>{let n=it(e.params.id);if(!n)return t.status(404).json({error:`Task not found`});nt({id:n.id,groupId:n.group_id,schedule:n.schedule,type:n.type,prompt:n.prompt,tools:n.tools?JSON.parse(n.tools):void 0,enabled:!0,lastRun:n.last_run,createdAt:n.created_at,channel:n.channel??void 0,subscriberId:n.subscriber_id??void 0,name:n.name??void 0,order:n.task_order??void 0}),t.sendStatus(200)}),e.patch(`/schedule/tasks/:id/disable`,(e,t)=>{let n=it(e.params.id);if(!n)return t.status(404).json({error:`Task not found`});nt({id:n.id,groupId:n.group_id,schedule:n.schedule,type:n.type,prompt:n.prompt,tools:n.tools?JSON.parse(n.tools):void 0,enabled:!1,lastRun:n.last_run,createdAt:n.created_at,channel:n.channel??void 0,subscriberId:n.subscriber_id??void 0,name:n.name??void 0,order:n.task_order??void 0}),t.sendStatus(200)})}function lt(e,t){if(typeof e!=`string`||!e.trim())return!1;let n=e.trim().split(/\s+/);if(n.length!==5)return!1;let[r,i,a,o,s]=n;return ut(r,t.getMinutes())&&ut(i,t.getHours())&&ut(a,t.getDate())&&ut(o,t.getMonth()+1)&&ut(s,t.getDay())}function ut(e,t){return e===`*`||e.split(`,`).some(e=>{if(e.includes(`/`)){let[n,r]=e.split(`/`),i=parseInt(r,10);if(isNaN(i)||i<=0)return!1;if(n===`*`)return t%i===0;if(n.includes(`-`)){let[e,r]=n.split(`-`).map(Number);return t>=e&&t<=r&&(t-e)%i===0}let a=parseInt(n,10);return t>=a&&(t-a)%i===0}if(e.includes(`-`)){let[n,r]=e.split(`-`).map(Number);return t>=n&&t<=r}return parseInt(e,10)===t})}var dt=class{_broadcastTaskTrigger;_getEnabledTasks;_interval;_updateLastRun;constructor({getEnabledTasks:e,updateLastRun:t,broadcastTaskTrigger:n}){this._getEnabledTasks=e,this._updateLastRun=t,this._broadcastTaskTrigger=n,this._interval=null}start(){this._interval||(this._interval=setInterval(()=>this.tick(),6e4),this._interval.unref?.(),this.tick())}stop(){this._interval&&=(clearInterval(this._interval),null)}async tick(){try{let e=this._getEnabledTasks(),t=new Date;for(let n of e)lt(n.schedule,t)&&!this._ranThisMinute(n,t)&&(this._updateLastRun(n.id,t.getTime()),this._broadcastTaskTrigger({id:n.id,groupId:n.group_id,prompt:n.prompt,type:n.type,tools:n.tools?JSON.parse(n.tools):null,channel:n.channel}).then(e=>{e?.noSubscribers&&console.warn(`Scheduled task ${n.id} fired but no push subscribers — task will not execute unless a browser tab is open.`)}).catch(e=>{console.error(`Failed to broadcast push for task ${n.id}:`,e)}))}catch(e){console.error(`Server scheduler tick error:`,e)}}_ranThisMinute(e,t){if(!e.last_run)return!1;let n=new Date(e.last_run);return n.getFullYear()===t.getFullYear()&&n.getMonth()===t.getMonth()&&n.getDate()===t.getDate()&&n.getHours()===t.getHours()&&n.getMinutes()===t.getMinutes()}};const ft=new class{loading=!1;models=new Map;getModelInfo(e){return this.models.get(e.toLowerCase())??null}registerModelInfo(e,t){this.models.set(e.toLowerCase(),t)}clear(){this.models.clear()}async fetchModelInfo(e,t,n){if(e.modelsUrl){this.loading=!0;try{let r=new Headers;if(r.set(`Content-Type`,`application/json`),e.headers)for(let[t,n]of Object.entries(e.headers))r.set(t,n);if(n)for(let[e,t]of Object.entries(n))r.set(e,t);if(t&&e.apiKeyHeader){let n=e.apiKeyHeaderFormat;r.set(e.apiKeyHeader,n?n.replace(`{key}`,t):t)}let i=await fetch(e.modelsUrl,{headers:r});if(!i.ok)throw Error(`HTTP ${i.status} ${i.statusText}`);let a=await i.json(),o=Array.isArray(a.data)?a.data:Array.isArray(a.models)?a.models:[];for(let e of o){if(!e.id)continue;let t=e.context_length??e.context_window??0,n=e.max_completion_tokens||e.per_request_limits?.completion_tokens||e.top_provider?.max_completion_tokens||null,r=typeof e.supports_tools==`boolean`?e.supports_tools:typeof e.supportsTools==`boolean`?e.supportsTools:void 0,i=this.extractModalities(e,`input`),a=this.extractModalities(e,`output`),o=this.modalitiesInclude(i,`image`,`vision`),s=this.modalitiesInclude(i,`audio`,`voice`,`hearing`),c=this.modalitiesInclude(i,`video`),l=e.id===`openrouter/free`||this.supportedParametersInclude(e,`image`,`vision`,`audio`,`tool`,`structured`),u=this.extractReasoning(e);!t&&Array.isArray(e.providers)&&e.providers.length>0&&(t=e.providers[0]?.context_length||0),this.registerModelInfo(e.id,{contextWindow:t,maxOutput:n,...r!==void 0&&{supportsTools:r},...i.length>0&&{inputModalities:i},...a.length>0&&{outputModalities:a},...o!==void 0&&{supportsImageInput:o},...s!==void 0&&{supportsAudioInput:s},...c!==void 0&&{supportsVideoInput:c},...u&&{reasoning:u},...l&&{routesByRequestFeatures:l}})}o.length>0&&console.log(`[ModelRegistry] Registered ${o.length} models for provider "${e.id}"`)}catch(t){console.error(`[ModelRegistry] Error fetching models for ${e.id}:`,t)}finally{this.loading=!1}}}extractModalities(e,t){let n=t===`input`?e.input_modalities||e.inputModalities:e.output_modalities||e.outputModalities,r=e.architecture||{},i=t===`input`?r.input_modalities||r.inputModalities:r.output_modalities||r.outputModalities,a=typeof r.modality==`string`?r.modality:``,o=this.parseArchitectureModality(a,t),s=[...this.normalizeStringArray(n),...this.normalizeStringArray(i),...o];return Array.from(new Set(s))}extractReasoning(e){let t=e?.reasoning;if(!t||typeof t!=`object`)return;let n=this.normalizeStringArray(t.supported_efforts),r=typeof t.default_effort==`string`?t.default_effort.toLowerCase():void 0,i=typeof t.default_enabled==`boolean`?t.default_enabled:void 0,a=typeof t.supports_max_tokens==`boolean`?t.supports_max_tokens:void 0,o=typeof t.mandatory==`boolean`?t.mandatory:void 0;if(!(n.length===0&&r===void 0&&i===void 0&&a===void 0&&o===void 0))return{...n.length>0&&{supportedEfforts:n},...r!==void 0&&{defaultEffort:r},...i!==void 0&&{defaultEnabled:i},...a!==void 0&&{supportsMaxTokens:a},...o!==void 0&&{mandatory:o}}}modalitiesInclude(e,...t){if(e.length!==0)return t.some(t=>e.some(e=>e.includes(t)))}normalizeStringArray(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`).map(e=>e.toLowerCase()):[]}parseArchitectureModality(e,t){if(!e)return[];let[n=``,r=``]=e.toLowerCase().split(`->`).map(e=>e.trim());return(t===`input`?n:r).split(/[+,/\s]+/).map(e=>e.trim()).filter(Boolean)}supportedParametersInclude(e,...t){let n=this.normalizeStringArray(e.supported_parameters||e.supportedParameters);return t.some(e=>n.some(t=>t.includes(e)))}};function pt(e){return e.replace(/^\/+|\/+$/g,``)}function mt(e){let t=pt(e);return t.endsWith(`/index.html`)?t=t.slice(0,-11):t.endsWith(`index.html`)&&(t=t.slice(0,-10)),pt(t)}function ht(e){let t=pt(e),n=t.split(`/`).filter(Boolean);if(n.length===0)return null;let r=n[0].toLowerCase();if(r===`pages`){if(n.length>=3){let e=n[1];return{page:`pages`,groupId:e===`main`?`br:main`:e.startsWith(`br-`)?`br:${e.slice(3)}`:e,path:n.slice(2).join(`/`)}}return{page:`pages`,groupId:`br:main`,path:n.slice(1).join(`/`)}}if(r===`files`){let e=n[1]||`main`;return{page:`files`,groupId:e===`main`?`br:main`:e.startsWith(`br-`)?`br:${e.slice(3)}`:e,path:n.slice(2).join(`/`)||void 0}}if(r===`chat`){let e=n[1]||`main`;return{page:`chat`,groupId:e===`main`?`br:main`:e.startsWith(`br-`)?`br:${e.slice(3)}`:e}}if(r===`tasks`){let e=n[1]||`main`;return{page:`tasks`,groupId:e===`main`?`br:main`:e.startsWith(`br-`)?`br:${e.slice(3)}`:e}}return r===`main`?{page:`pages`,groupId:`br:main`,path:n.slice(1).join(`/`)}:{page:`pages`,groupId:`br:main`,path:t}}function gt(){if(typeof document<`u`){let e=document.getElementById(`shadow-claw-static-routing`);if(e&&e.textContent)try{let t=JSON.parse(e.textContent);if(t&&typeof t==`object`&&t.routes)return t}catch(e){console.warn(`Failed to parse embedded static routing manifest:`,e)}}return null}function _t(e,t){let n=t||gt();if(!n||!n.routes)return null;let r=mt(e);if(!r)return null;for(let[e,t]of Object.entries(n.routes))if(!(!t||!t.prettyPath)&&mt(t.prettyPath)===r)return ht(e);return null}let vt=null;const yt=new Set([`chat`,`files`,`tasks`,`pages`,`settings`,`tools`,`channels`]);function bt(){vt=null}typeof globalThis<`u`&&(globalThis.__applyBasePathCacheReset=bt);function xt(){let e=typeof window<`u`?window:typeof self<`u`?self:globalThis;if(e&&e.__SHADOWCLAW_DEPLOY_ID__){let t=String(e.__SHADOWCLAW_DEPLOY_ID__).trim();if(t)return t.replace(/[^a-zA-Z0-9_-]/g,`-`)}let t=globalThis.process;if(t&&t.env&&t.env.SHADOWCLAW_DEPLOY_ID){let e=String(t.env.SHADOWCLAW_DEPLOY_ID).trim();if(e)return e.replace(/[^a-zA-Z0-9_-]/g,`-`)}let n=St();return!n||n===`/`?``:n.replace(/^\/+|\/+$/g,``).replace(/[^a-zA-Z0-9_-]/g,`-`)}function St(){if(vt!==null)return vt;if((typeof window>`u`||globalThis.WorkerGlobalScope!==void 0&&typeof self<`u`&&self instanceof globalThis.WorkerGlobalScope)&&typeof self<`u`&&self.location){let e=(self.location.pathname||`/`).split(`/`).filter(Boolean);if(e.length<=1)return vt=`/`,vt;let t=e[0].toLowerCase(),n=t===`service-worker.js`||t===`sw.js`||t===`manifest.json`||t===`sitemap.xml`||t===`favicon.ico`||t===`index.html`||t===`service-worker`||t===`assets`||t===`dist`||t===`public`;if(n&&e.length===2)return vt=`/`,vt;if(!n)return vt=`/`+e[0]+`/`,vt}let e=typeof window<`u`&&window.location?window.location:typeof self<`u`&&self.location?self.location:null;if(!e)return`/`;if(typeof document<`u`&&typeof document.querySelector==`function`){let t=document.querySelector(`base[href]`);if(t){let n=t.getAttribute(`href`);if(n)try{let t=new URL(n,e.origin).pathname;return t.endsWith(`/`)||(t+=`/`),vt=t,vt}catch{}}}let t=e.pathname||`/`;if(t===`/`)return vt=`/`,vt;let n=t.split(`/`).filter(Boolean),r=n.findIndex(e=>yt.has(e.toLowerCase()));return r>=0?r===0?(vt=`/`,vt):(vt=`/`+n.slice(0,r).join(`/`)+`/`,vt):_t(t)?(vt=`/`,vt):n.length===1&&!t.includes(`.`)?(vt=`/`+n[0]+`/`,vt):(vt=`/`,vt)}function Ct(e){let t=e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);return RegExp(`(^|\\s)@${t}\\b`,`i`)}Ct(`ShadowClaw`);function wt(){let e=xt();return e?`shadowclaw-${e}`:`shadowclaw`}wt();const Tt={github:{providerId:`github`,name:`GitHub`,aliases:[`github`,`api.github.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`token `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://github.com/login/oauth/authorize`,tokenUrl:`https://github.com/login/oauth/access_token`,defaultScopes:[`repo`,`read:user`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},gitlab:{providerId:`gitlab`,name:`GitLab`,aliases:[`gitlab`,`gitlab.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`PRIVATE-TOKEN`,headerPrefix:``},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},tokenAuthByServiceType:{git_remote:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}}},oauth:{authorizeUrl:`https://gitlab.com/oauth/authorize`,tokenUrl:`https://gitlab.com/oauth/token`,defaultScopes:[`read_api`,`read_user`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},figma:{providerId:`figma`,name:`Figma`,aliases:[`figma`,`api.figma.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`X-Figma-Token`,headerPrefix:``},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://www.figma.com/oauth`,tokenUrl:`https://api.figma.com/v1/oauth/token`,refreshUrl:`https://api.figma.com/v1/oauth/refresh`,defaultScopes:[],usePkce:!0,clientAuthMethod:`basic_header`,scopeSeparator:`space`}},notion:{providerId:`notion`,name:`Notion`,aliases:[`notion`,`api.notion.com`,`notion.so`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://api.notion.com/v1/oauth/authorize`,tokenUrl:`https://api.notion.com/v1/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`basic_header`,scopeSeparator:`space`}},microsoft_graph:{providerId:`microsoft_graph`,name:`Microsoft Graph`,aliases:[`microsoft`,`graph.microsoft.com`,`microsoft_graph`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://login.microsoftonline.com/common/oauth2/v2.0/authorize`,tokenUrl:`https://login.microsoftonline.com/common/oauth2/v2.0/token`,defaultScopes:[`openid`,`profile`,`offline_access`,`User.Read`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},yahoo_mail:{providerId:`yahoo_mail`,name:`Yahoo Mail`,aliases:[`yahoo`,`yahoo_mail`,`mail.yahoo.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://api.login.yahoo.com/oauth2/request_auth`,tokenUrl:`https://api.login.yahoo.com/oauth2/get_token`,defaultScopes:[`mail-r`,`mail-w`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},google:{providerId:`google`,name:`Google`,aliases:[`google`,`googleapis.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://accounts.google.com/o/oauth2/v2/auth`,tokenUrl:`https://oauth2.googleapis.com/token`,defaultScopes:[`openid`,`profile`,`email`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},atlassian:{providerId:`atlassian`,name:`Atlassian`,aliases:[`atlassian`,`api.atlassian.com`],modes:[`oauth`,`token`,`basic`],defaultMode:`basic`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`,`basic_userpass`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `},basic:{headerName:`Authorization`,headerPrefix:`Basic `}},oauth:{authorizeUrl:`https://auth.atlassian.com/authorize`,tokenUrl:`https://auth.atlassian.com/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},slack:{providerId:`slack`,name:`Slack`,aliases:[`slack`,`slack.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://slack.com/oauth/v2/authorize`,tokenUrl:`https://slack.com/api/oauth.v2.access`,defaultScopes:[],usePkce:!1,clientAuthMethod:`request_body`,scopeSeparator:`comma`}},linear:{providerId:`linear`,name:`Linear`,aliases:[`linear`,`api.linear.app`,`linear.app`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://linear.app/oauth/authorize`,tokenUrl:`https://api.linear.app/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},azure_devops:{providerId:`azure_devops`,name:`Azure DevOps`,aliases:[`azure_devops`,`dev.azure.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`,`basic_userpass`,`ssh_key`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},tokenAuthByServiceType:{git_remote:{token:{headerName:`Authorization`,headerPrefix:`Basic `},oauth:{headerName:`Authorization`,headerPrefix:`Basic `}}},oauth:{authorizeUrl:`https://app.vssps.visualstudio.com/oauth2/authorize`,tokenUrl:`https://app.vssps.visualstudio.com/oauth2/token`,defaultScopes:[`vso.code`,`vso.profile`,`offline_access`],usePkce:!1,clientAuthMethod:`request_body`,scopeSeparator:`space`}},custom_mcp:{providerId:`custom_mcp`,name:`Custom MCP`,aliases:[`custom_mcp`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`mcp_remote`,`webmcp_local`],authTypes:[`none`,`token`,`oauth`,`custom_header`,`ssh_key`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://example.com/oauth/authorize`,tokenUrl:`https://example.com/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}}},Et=Object.fromEntries(Object.values(Tt).filter(e=>!!e.oauth).map(e=>{let t=e.oauth;return[e.providerId,{id:e.providerId,name:e.name,authorizeUrl:t.authorizeUrl,tokenUrl:t.tokenUrl,redirectUri:t.redirectUri,defaultScopes:t.defaultScopes,usePkce:t.usePkce,clientAuthMethod:t.clientAuthMethod,scopeSeparator:t.scopeSeparator}]}));Object.fromEntries(Object.values(Tt).map(e=>[e.providerId,{providerId:e.providerId,modes:e.modes,defaultMode:e.defaultMode}]));function Dt(e){return Et[e]||null}function Ot(e=32){return(0,C.randomBytes)(e).toString(`base64url`)}function kt(e){return(0,C.createHash)(`sha256`).update(e).digest(`base64url`)}function At(e){if(typeof e!=`string`||!e.trim())return!1;try{let t=new URL(e);return t.protocol===`https:`||t.protocol===`http:`}catch{return!1}}function jt(e,t=`space`){let n=t===`comma`?`,`:` `;return Array.isArray(e)?e.filter(Boolean).join(n).trim():typeof e==`string`?e.trim():``}function Mt(e){return Array.isArray(e)?e.flatMap(e=>e.split(/[\s,]+/)).map(e=>e.trim()).filter(Boolean):typeof e==`string`?e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):[]}function Nt(e,t){if(!e.length||!t.length)return!0;let n=new Set(e);return t.every(e=>n.has(e))}function Pt(e,t,n){let r={"content-type":`application/x-www-form-urlencoded`,accept:`application/json`};return e===`basic_header`&&n&&(r.authorization=`Basic ${T.Buffer.from(`${t}:${n}`).toString(`base64`)}`),r}function Ft(e,t,n){let r=new URL(e.authorizeUrl);r.searchParams.set(`response_type`,`code`),r.searchParams.set(`client_id`,e.clientId),r.searchParams.set(`redirect_uri`,e.redirectUri),r.searchParams.set(`state`,t);let i=jt(e.scope,e.scopeSeparator);if(i&&r.searchParams.set(`scope`,i),e.audience&&r.searchParams.set(`audience`,e.audience),n&&(r.searchParams.set(`code_challenge`,n),r.searchParams.set(`code_challenge_method`,`S256`)),e.extraAuthorizeParams)for(let[t,n]of Object.entries(e.extraAuthorizeParams))n&&([`response_type`,`client_id`,`redirect_uri`,`state`].includes(t)||r.searchParams.set(t,n));return r.toString()}function It(e,t={}){let n=t.now||(()=>Date.now()),r=t.fetchImpl||fetch,i=t.stateTtlMs||6e5,a=new Map;function o(){let e=n();for(let[t,n]of a.entries())n.expiresAt<=e&&a.delete(t)}function s(e){o();let t=a.get(e);if(t){if(t.expiresAt<=n()){a.delete(e);return}return t}}e.post(`/oauth/authorize`,(e,t)=>{o();let r=e.body||{};if(!r.providerId||typeof r.providerId!=`string`){t.status(400).json({error:`Missing required providerId`});return}let s=Dt(r.providerId);if(!s){t.status(400).json({error:`Unsupported OAuth provider`,providerId:r.providerId});return}let c=r.providerId===`custom_mcp`,l=c&&At(r.authorizeUrl)?r.authorizeUrl:s.authorizeUrl,u=c&&At(r.tokenUrl)?r.tokenUrl:s.tokenUrl,d=c&&typeof r.usePkce==`boolean`?r.usePkce:s.usePkce;if(!At(l)){t.status(c?400:500).json({error:c?`Custom MCP requires a valid authorizeUrl`:`Invalid provider authorizeUrl configuration`});return}if(!At(u)){t.status(c?400:500).json({error:c?`Custom MCP requires a valid tokenUrl`:`Invalid provider tokenUrl configuration`});return}if(!At(r.redirectUri)){t.status(400).json({error:`Invalid redirectUri`});return}if(!r.clientId||typeof r.clientId!=`string`){t.status(400).json({error:`Missing required clientId`});return}let f=Mt(r.scope);if(!Nt(s.defaultScopes,f)){t.status(400).json({error:`Requested scopes are not allowed for this provider`});return}let p=f.length?f:s.defaultScopes,m=Ot(),h=d,g=h?Ot(48):void 0,_=g?kt(g):void 0,v=n(),y=v+i;a.set(m,{providerId:r.providerId,tokenUrl:u,clientId:r.clientId,clientSecret:r.clientSecret,redirectUri:r.redirectUri,codeVerifier:g,createdAt:v,expiresAt:y,status:`pending`});let b=Ft({...r,authorizeUrl:l,tokenUrl:u,scope:p,usePkce:d,scopeSeparator:s.scopeSeparator},m,_);t.json({state:m,providerId:r.providerId,authorizeUrl:b,expiresAt:y,pkceEnabled:h,codeChallengeMethod:h?`S256`:void 0})}),e.get(`/oauth/callback`,(e,t)=>{o();let n=typeof e.query.state==`string`?e.query.state.trim():``;if(!n){t.status(400).send(`Missing state`);return}let r=s(n);if(!r){t.status(400).send(`Invalid or expired OAuth state`);return}let i=typeof e.query.error==`string`?e.query.error:void 0,a=typeof e.query.error_description==`string`?e.query.error_description:void 0;if(i){r.status=`error`,r.authorizationError=i,r.authorizationErrorDescription=a,t.status(400).send(`OAuth authorization failed: ${i}`);return}let c=typeof e.query.code==`string`?e.query.code:``;if(!c){t.status(400).send(`Missing authorization code`);return}r.status=`authorized`,r.authorizationCode=c,t.type(`html`).send(`<!doctype html>
61
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(e.id,e.groupId,e.schedule,e.type??null,e.prompt,e.tools?JSON.stringify(e.tools):null,e.enabled===!1?0:1,e.lastRun??null,e.createdAt,e.channel??null,e.subscriberId??null,e.name??null,e.order??null)}function rt(e){if(!$e)throw Error(`Task schedule store not opened.`);$e.prepare(`DELETE FROM scheduled_tasks WHERE id = ?`).run(e)}function it(e){if(!$e)throw Error(`Task schedule store not opened.`);let t=$e.prepare(`SELECT * FROM scheduled_tasks WHERE id = ?`).get(e);return t?et(t):void 0}function at(e,t){if(!$e)throw Error(`Task schedule store not opened.`);if(e&&t){let n=$e.prepare(`SELECT * FROM scheduled_tasks WHERE group_id = ? AND (subscriber_id = ? OR subscriber_id IS NULL) ORDER BY created_at DESC`).all(e,t);return n?n.map(e=>et(e)).filter(e=>e.subscriber_id===null||e.subscriber_id===t):[]}if(e){let t=$e.prepare(`SELECT * FROM scheduled_tasks WHERE group_id = ? ORDER BY created_at DESC`).all(e);return t?t.map(e=>et(e)):[]}if(t){let e=$e.prepare(`SELECT * FROM scheduled_tasks WHERE subscriber_id = ? ORDER BY created_at DESC`).all(t);return e?e.map(e=>et(e)):[]}let n=$e.prepare(`SELECT * FROM scheduled_tasks ORDER BY created_at DESC`).all();return n?n.map(e=>et(e)):[]}function ot(){if(!$e)throw Error(`Task schedule store not opened.`);let e=$e.prepare(`SELECT * FROM scheduled_tasks WHERE enabled = 1`).all();return e?e.map(e=>et(e)):[]}function st(e,t){if(!$e)throw Error(`Task schedule store not opened.`);$e.prepare(`UPDATE scheduled_tasks SET last_run = ? WHERE id = ?`).run(t,e)}function ct(e){e.post(`/schedule/tasks`,(e,t)=>{let n=e.body;if(!n?.id||!n?.groupId||!n?.schedule)return t.status(400).json({error:`Missing required fields: id, groupId, schedule`});if(n?.type===`tools`&&(!n.tools||n.tools.length===0))return t.status(400).json({error:`Missing required fields: tools array cannot be empty for WebMCP Tools task`});if(n?.type!==`tools`&&!n?.prompt)return t.status(400).json({error:`Missing required fields: prompt is required for Prompt tasks`});nt(n),t.sendStatus(201)}),e.get(`/schedule/tasks`,(e,t)=>{let n=e.query.groupId,r=e.query.subscriberId,i=at(n,r);if(n&&r){let e=i.filter(e=>e.subscriber_id===null).length;e>0&&console.warn(`Found ${e} legacy scheduled task(s) with NULL subscriber_id for group ${n}`)}t.json(i)}),e.get(`/schedule/tasks/:id`,(e,t)=>{let n=it(e.params.id);if(!n)return t.status(404).json({error:`Task not found`});t.json(n)}),e.delete(`/schedule/tasks/:id`,(e,t)=>{let n=e.query.subscriberId;if(n){let r=it(e.params.id);if(!r||r.subscriber_id!==null&&r.subscriber_id!==n)return t.status(404).json({error:`Task not found`});rt(e.params.id)}else rt(e.params.id);t.sendStatus(200)}),e.patch(`/schedule/tasks/:id/enable`,(e,t)=>{let n=it(e.params.id);if(!n)return t.status(404).json({error:`Task not found`});nt({id:n.id,groupId:n.group_id,schedule:n.schedule,type:n.type,prompt:n.prompt,tools:n.tools?JSON.parse(n.tools):void 0,enabled:!0,lastRun:n.last_run,createdAt:n.created_at,channel:n.channel??void 0,subscriberId:n.subscriber_id??void 0,name:n.name??void 0,order:n.task_order??void 0}),t.sendStatus(200)}),e.patch(`/schedule/tasks/:id/disable`,(e,t)=>{let n=it(e.params.id);if(!n)return t.status(404).json({error:`Task not found`});nt({id:n.id,groupId:n.group_id,schedule:n.schedule,type:n.type,prompt:n.prompt,tools:n.tools?JSON.parse(n.tools):void 0,enabled:!1,lastRun:n.last_run,createdAt:n.created_at,channel:n.channel??void 0,subscriberId:n.subscriber_id??void 0,name:n.name??void 0,order:n.task_order??void 0}),t.sendStatus(200)})}function lt(e,t){if(typeof e!=`string`||!e.trim())return!1;let n=e.trim().split(/\s+/);if(n.length!==5)return!1;let[r,i,a,o,s]=n;return ut(r,t.getMinutes())&&ut(i,t.getHours())&&ut(a,t.getDate())&&ut(o,t.getMonth()+1)&&ut(s,t.getDay())}function ut(e,t){return e===`*`||e.split(`,`).some(e=>{if(e.includes(`/`)){let[n,r]=e.split(`/`),i=parseInt(r,10);if(isNaN(i)||i<=0)return!1;if(n===`*`)return t%i===0;if(n.includes(`-`)){let[e,r]=n.split(`-`).map(Number);return t>=e&&t<=r&&(t-e)%i===0}let a=parseInt(n,10);return t>=a&&(t-a)%i===0}if(e.includes(`-`)){let[n,r]=e.split(`-`).map(Number);return t>=n&&t<=r}return parseInt(e,10)===t})}var dt=class{_broadcastTaskTrigger;_getEnabledTasks;_interval;_updateLastRun;constructor({getEnabledTasks:e,updateLastRun:t,broadcastTaskTrigger:n}){this._getEnabledTasks=e,this._updateLastRun=t,this._broadcastTaskTrigger=n,this._interval=null}start(){this._interval||(this._interval=setInterval(()=>this.tick(),6e4),this._interval.unref?.(),this.tick())}stop(){this._interval&&=(clearInterval(this._interval),null)}async tick(){try{let e=this._getEnabledTasks(),t=new Date;for(let n of e)lt(n.schedule,t)&&!this._ranThisMinute(n,t)&&(this._updateLastRun(n.id,t.getTime()),this._broadcastTaskTrigger({id:n.id,groupId:n.group_id,prompt:n.prompt,type:n.type,tools:n.tools?JSON.parse(n.tools):null,channel:n.channel}).then(e=>{e?.noSubscribers&&console.warn(`Scheduled task ${n.id} fired but no push subscribers — task will not execute unless a browser tab is open.`)}).catch(e=>{console.error(`Failed to broadcast push for task ${n.id}:`,e)}))}catch(e){console.error(`Server scheduler tick error:`,e)}}_ranThisMinute(e,t){if(!e.last_run)return!1;let n=new Date(e.last_run);return n.getFullYear()===t.getFullYear()&&n.getMonth()===t.getMonth()&&n.getDate()===t.getDate()&&n.getHours()===t.getHours()&&n.getMinutes()===t.getMinutes()}};const ft=new class{loading=!1;models=new Map;getModelInfo(e){if(!e||typeof e!=`string`)return null;let t=e.toLowerCase().trim(),n=this.models.get(t);if(n)return n;if(t.includes(`/`)){let e=t.split(`/`).pop();if(e&&this.models.has(e))return this.models.get(e)}else for(let[e,n]of this.models.entries())if(e.endsWith(`/${t}`))return n;if(t.includes(`:`)){let e=t.split(`:`)[0],n=this.getModelInfo(e);if(n)return n}return null}registerModelInfo(e,t){this.models.set(e.toLowerCase(),t)}clear(){this.models.clear()}async fetchModelInfo(e,t,n){if(e.modelsUrl){this.loading=!0;try{let r=new Headers;if(r.set(`Content-Type`,`application/json`),e.headers)for(let[t,n]of Object.entries(e.headers))r.set(t,n);if(n)for(let[e,t]of Object.entries(n))r.set(e,t);if(t&&e.apiKeyHeader){let n=e.apiKeyHeaderFormat;r.set(e.apiKeyHeader,n?n.replace(`{key}`,t):t)}let i=await fetch(e.modelsUrl,{headers:r});if(!i.ok)throw Error(`HTTP ${i.status} ${i.statusText}`);let a=await i.json(),o=Array.isArray(a.data)?a.data:Array.isArray(a.models)?a.models:[];for(let e of o){if(!e.id)continue;let t=e.context_length??e.context_window??0,n=e.max_completion_tokens||e.per_request_limits?.completion_tokens||e.top_provider?.max_completion_tokens||null,r=typeof e.supports_tools==`boolean`?e.supports_tools:typeof e.supportsTools==`boolean`?e.supportsTools:void 0,i=this.extractModalities(e,`input`),a=this.extractModalities(e,`output`),o=this.modalitiesInclude(i,`image`,`vision`),s=this.modalitiesInclude(i,`audio`,`voice`,`hearing`),c=this.modalitiesInclude(i,`video`),l=e.id===`openrouter/free`||this.supportedParametersInclude(e,`image`,`vision`,`audio`,`tool`,`structured`),u=this.extractReasoning(e),d=typeof e.supports_prompt_caching==`boolean`?e.supports_prompt_caching:typeof e.supportsPromptCaching==`boolean`?e.supportsPromptCaching:this.supportedParametersInclude(e,`cache_control`,`prompt_caching`)?!0:void 0;!t&&Array.isArray(e.providers)&&e.providers.length>0&&(t=e.providers[0]?.context_length||0),this.registerModelInfo(e.id,{contextWindow:t,maxOutput:n,...r!==void 0&&{supportsTools:r},...i.length>0&&{inputModalities:i},...a.length>0&&{outputModalities:a},...o!==void 0&&{supportsImageInput:o},...s!==void 0&&{supportsAudioInput:s},...c!==void 0&&{supportsVideoInput:c},...u&&{reasoning:u},...l&&{routesByRequestFeatures:l},...d!==void 0&&{supportsPromptCaching:d}})}o.length>0&&console.log(`[ModelRegistry] Registered ${o.length} models for provider "${e.id}"`)}catch(t){console.error(`[ModelRegistry] Error fetching models for ${e.id}:`,t)}finally{this.loading=!1}}}extractModalities(e,t){let n=t===`input`?e.input_modalities||e.inputModalities:e.output_modalities||e.outputModalities,r=e.architecture||{},i=t===`input`?r.input_modalities||r.inputModalities:r.output_modalities||r.outputModalities,a=typeof r.modality==`string`?r.modality:``,o=this.parseArchitectureModality(a,t),s=[...this.normalizeStringArray(n),...this.normalizeStringArray(i),...o];return Array.from(new Set(s))}extractReasoning(e){let t=e?.reasoning;if(!t||typeof t!=`object`)return;let n=this.normalizeStringArray(t.supported_efforts),r=typeof t.default_effort==`string`?t.default_effort.toLowerCase():void 0,i=typeof t.default_enabled==`boolean`?t.default_enabled:void 0,a=typeof t.supports_max_tokens==`boolean`?t.supports_max_tokens:void 0,o=typeof t.mandatory==`boolean`?t.mandatory:void 0;if(!(n.length===0&&r===void 0&&i===void 0&&a===void 0&&o===void 0))return{...n.length>0&&{supportedEfforts:n},...r!==void 0&&{defaultEffort:r},...i!==void 0&&{defaultEnabled:i},...a!==void 0&&{supportsMaxTokens:a},...o!==void 0&&{mandatory:o}}}modalitiesInclude(e,...t){if(e.length!==0)return t.some(t=>e.some(e=>e.includes(t)))}normalizeStringArray(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`).map(e=>e.toLowerCase()):[]}parseArchitectureModality(e,t){if(!e)return[];let[n=``,r=``]=e.toLowerCase().split(`->`).map(e=>e.trim());return(t===`input`?n:r).split(/[+,/\s]+/).map(e=>e.trim()).filter(Boolean)}supportedParametersInclude(e,...t){let n=this.normalizeStringArray(e.supported_parameters||e.supportedParameters);return t.some(e=>n.some(t=>t.includes(e)))}};function pt(e){return e.replace(/^\/+|\/+$/g,``)}function mt(e){let t=pt(e);return t.endsWith(`/index.html`)?t=t.slice(0,-11):t.endsWith(`index.html`)&&(t=t.slice(0,-10)),pt(t)}function ht(e){let t=pt(e),n=t.split(`/`).filter(Boolean);if(n.length===0)return null;let r=n[0].toLowerCase();if(r===`pages`){if(n.length>=3){let e=n[1];return{page:`pages`,groupId:e===`main`?`br:main`:e.startsWith(`br-`)?`br:${e.slice(3)}`:e,path:n.slice(2).join(`/`)}}return{page:`pages`,groupId:`br:main`,path:n.slice(1).join(`/`)}}if(r===`files`){let e=n[1]||`main`;return{page:`files`,groupId:e===`main`?`br:main`:e.startsWith(`br-`)?`br:${e.slice(3)}`:e,path:n.slice(2).join(`/`)||void 0}}if(r===`chat`){let e=n[1]||`main`;return{page:`chat`,groupId:e===`main`?`br:main`:e.startsWith(`br-`)?`br:${e.slice(3)}`:e}}if(r===`tasks`){let e=n[1]||`main`;return{page:`tasks`,groupId:e===`main`?`br:main`:e.startsWith(`br-`)?`br:${e.slice(3)}`:e}}return r===`main`?{page:`pages`,groupId:`br:main`,path:n.slice(1).join(`/`)}:{page:`pages`,groupId:`br:main`,path:t}}function gt(){if(typeof document<`u`){let e=document.getElementById(`shadow-claw-static-routing`);if(e&&e.textContent)try{let t=JSON.parse(e.textContent);if(t&&typeof t==`object`&&t.routes)return t}catch(e){console.warn(`Failed to parse embedded static routing manifest:`,e)}}return null}function _t(e,t){let n=t||gt();if(!n||!n.routes)return null;let r=mt(e);if(!r)return null;for(let[e,t]of Object.entries(n.routes))if(!(!t||!t.prettyPath)&&mt(t.prettyPath)===r)return ht(e);return null}let vt=null;const yt=new Set([`chat`,`files`,`tasks`,`pages`,`settings`,`tools`,`channels`]);function bt(){vt=null}typeof globalThis<`u`&&(globalThis.__applyBasePathCacheReset=bt);function xt(){let e=typeof window<`u`?window:typeof self<`u`?self:globalThis;if(e&&e.__SHADOWCLAW_DEPLOY_ID__){let t=String(e.__SHADOWCLAW_DEPLOY_ID__).trim();if(t)return t.replace(/[^a-zA-Z0-9_-]/g,`-`)}let t=globalThis.process;if(t&&t.env&&t.env.SHADOWCLAW_DEPLOY_ID){let e=String(t.env.SHADOWCLAW_DEPLOY_ID).trim();if(e)return e.replace(/[^a-zA-Z0-9_-]/g,`-`)}let n=St();return!n||n===`/`?``:n.replace(/^\/+|\/+$/g,``).replace(/[^a-zA-Z0-9_-]/g,`-`)}function St(){if(vt!==null)return vt;if((typeof window>`u`||globalThis.WorkerGlobalScope!==void 0&&typeof self<`u`&&self instanceof globalThis.WorkerGlobalScope)&&typeof self<`u`&&self.location){let e=(self.location.pathname||`/`).split(`/`).filter(Boolean);if(e.length<=1)return vt=`/`,vt;let t=e[0].toLowerCase(),n=t===`service-worker.js`||t===`sw.js`||t===`manifest.json`||t===`sitemap.xml`||t===`favicon.ico`||t===`index.html`||t===`service-worker`||t===`assets`||t===`dist`||t===`public`;if(n&&e.length===2)return vt=`/`,vt;if(!n)return vt=`/`+e[0]+`/`,vt}let e=typeof window<`u`&&window.location?window.location:typeof self<`u`&&self.location?self.location:null;if(!e)return`/`;if(typeof document<`u`&&typeof document.querySelector==`function`){let t=document.querySelector(`base[href]`);if(t){let n=t.getAttribute(`href`);if(n)try{let t=new URL(n,e.origin).pathname;return t.endsWith(`/`)||(t+=`/`),vt=t,vt}catch{}}}let t=e.pathname||`/`;if(t===`/`)return vt=`/`,vt;let n=t.split(`/`).filter(Boolean),r=n.findIndex(e=>yt.has(e.toLowerCase()));return r>=0?r===0?(vt=`/`,vt):(vt=`/`+n.slice(0,r).join(`/`)+`/`,vt):_t(t)?(vt=`/`,vt):n.length===1&&!t.includes(`.`)?(vt=`/`+n[0]+`/`,vt):(vt=`/`,vt)}function Ct(e){let t=e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);return RegExp(`(^|\\s)@${t}\\b`,`i`)}Ct(`ShadowClaw`);function wt(){let e=xt();return e?`shadowclaw-${e}`:`shadowclaw`}wt();const Tt={github:{providerId:`github`,name:`GitHub`,aliases:[`github`,`api.github.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`token `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://github.com/login/oauth/authorize`,tokenUrl:`https://github.com/login/oauth/access_token`,defaultScopes:[`repo`,`read:user`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},gitlab:{providerId:`gitlab`,name:`GitLab`,aliases:[`gitlab`,`gitlab.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`PRIVATE-TOKEN`,headerPrefix:``},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},tokenAuthByServiceType:{git_remote:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}}},oauth:{authorizeUrl:`https://gitlab.com/oauth/authorize`,tokenUrl:`https://gitlab.com/oauth/token`,defaultScopes:[`read_api`,`read_user`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},figma:{providerId:`figma`,name:`Figma`,aliases:[`figma`,`api.figma.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`X-Figma-Token`,headerPrefix:``},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://www.figma.com/oauth`,tokenUrl:`https://api.figma.com/v1/oauth/token`,refreshUrl:`https://api.figma.com/v1/oauth/refresh`,defaultScopes:[],usePkce:!0,clientAuthMethod:`basic_header`,scopeSeparator:`space`}},notion:{providerId:`notion`,name:`Notion`,aliases:[`notion`,`api.notion.com`,`notion.so`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://api.notion.com/v1/oauth/authorize`,tokenUrl:`https://api.notion.com/v1/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`basic_header`,scopeSeparator:`space`}},microsoft_graph:{providerId:`microsoft_graph`,name:`Microsoft Graph`,aliases:[`microsoft`,`graph.microsoft.com`,`microsoft_graph`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://login.microsoftonline.com/common/oauth2/v2.0/authorize`,tokenUrl:`https://login.microsoftonline.com/common/oauth2/v2.0/token`,defaultScopes:[`openid`,`profile`,`offline_access`,`User.Read`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},yahoo_mail:{providerId:`yahoo_mail`,name:`Yahoo Mail`,aliases:[`yahoo`,`yahoo_mail`,`mail.yahoo.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://api.login.yahoo.com/oauth2/request_auth`,tokenUrl:`https://api.login.yahoo.com/oauth2/get_token`,defaultScopes:[`mail-r`,`mail-w`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},google:{providerId:`google`,name:`Google`,aliases:[`google`,`googleapis.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://accounts.google.com/o/oauth2/v2/auth`,tokenUrl:`https://oauth2.googleapis.com/token`,defaultScopes:[`openid`,`profile`,`email`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},atlassian:{providerId:`atlassian`,name:`Atlassian`,aliases:[`atlassian`,`api.atlassian.com`],modes:[`oauth`,`token`,`basic`],defaultMode:`basic`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`,`basic_userpass`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `},basic:{headerName:`Authorization`,headerPrefix:`Basic `}},oauth:{authorizeUrl:`https://auth.atlassian.com/authorize`,tokenUrl:`https://auth.atlassian.com/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},slack:{providerId:`slack`,name:`Slack`,aliases:[`slack`,`slack.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://slack.com/oauth/v2/authorize`,tokenUrl:`https://slack.com/api/oauth.v2.access`,defaultScopes:[],usePkce:!1,clientAuthMethod:`request_body`,scopeSeparator:`comma`}},linear:{providerId:`linear`,name:`Linear`,aliases:[`linear`,`api.linear.app`,`linear.app`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://linear.app/oauth/authorize`,tokenUrl:`https://api.linear.app/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},azure_devops:{providerId:`azure_devops`,name:`Azure DevOps`,aliases:[`azure_devops`,`dev.azure.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`,`basic_userpass`,`ssh_key`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},tokenAuthByServiceType:{git_remote:{token:{headerName:`Authorization`,headerPrefix:`Basic `},oauth:{headerName:`Authorization`,headerPrefix:`Basic `}}},oauth:{authorizeUrl:`https://app.vssps.visualstudio.com/oauth2/authorize`,tokenUrl:`https://app.vssps.visualstudio.com/oauth2/token`,defaultScopes:[`vso.code`,`vso.profile`,`offline_access`],usePkce:!1,clientAuthMethod:`request_body`,scopeSeparator:`space`}},custom_mcp:{providerId:`custom_mcp`,name:`Custom MCP`,aliases:[`custom_mcp`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`mcp_remote`,`webmcp_local`],authTypes:[`none`,`token`,`oauth`,`custom_header`,`ssh_key`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://example.com/oauth/authorize`,tokenUrl:`https://example.com/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}}},Et=Object.fromEntries(Object.values(Tt).filter(e=>!!e.oauth).map(e=>{let t=e.oauth;return[e.providerId,{id:e.providerId,name:e.name,authorizeUrl:t.authorizeUrl,tokenUrl:t.tokenUrl,redirectUri:t.redirectUri,defaultScopes:t.defaultScopes,usePkce:t.usePkce,clientAuthMethod:t.clientAuthMethod,scopeSeparator:t.scopeSeparator}]}));Object.fromEntries(Object.values(Tt).map(e=>[e.providerId,{providerId:e.providerId,modes:e.modes,defaultMode:e.defaultMode}]));function Dt(e){return Et[e]||null}function Ot(e=32){return(0,C.randomBytes)(e).toString(`base64url`)}function kt(e){return(0,C.createHash)(`sha256`).update(e).digest(`base64url`)}function At(e){if(typeof e!=`string`||!e.trim())return!1;try{let t=new URL(e);return t.protocol===`https:`||t.protocol===`http:`}catch{return!1}}function jt(e,t=`space`){let n=t===`comma`?`,`:` `;return Array.isArray(e)?e.filter(Boolean).join(n).trim():typeof e==`string`?e.trim():``}function Mt(e){return Array.isArray(e)?e.flatMap(e=>e.split(/[\s,]+/)).map(e=>e.trim()).filter(Boolean):typeof e==`string`?e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):[]}function Nt(e,t){if(!e.length||!t.length)return!0;let n=new Set(e);return t.every(e=>n.has(e))}function Pt(e,t,n){let r={"content-type":`application/x-www-form-urlencoded`,accept:`application/json`};return e===`basic_header`&&n&&(r.authorization=`Basic ${T.Buffer.from(`${t}:${n}`).toString(`base64`)}`),r}function Ft(e,t,n){let r=new URL(e.authorizeUrl);r.searchParams.set(`response_type`,`code`),r.searchParams.set(`client_id`,e.clientId),r.searchParams.set(`redirect_uri`,e.redirectUri),r.searchParams.set(`state`,t);let i=jt(e.scope,e.scopeSeparator);if(i&&r.searchParams.set(`scope`,i),e.audience&&r.searchParams.set(`audience`,e.audience),n&&(r.searchParams.set(`code_challenge`,n),r.searchParams.set(`code_challenge_method`,`S256`)),e.extraAuthorizeParams)for(let[t,n]of Object.entries(e.extraAuthorizeParams))n&&([`response_type`,`client_id`,`redirect_uri`,`state`].includes(t)||r.searchParams.set(t,n));return r.toString()}function It(e,t={}){let n=t.now||(()=>Date.now()),r=t.fetchImpl||fetch,i=t.stateTtlMs||6e5,a=new Map;function o(){let e=n();for(let[t,n]of a.entries())n.expiresAt<=e&&a.delete(t)}function s(e){o();let t=a.get(e);if(t){if(t.expiresAt<=n()){a.delete(e);return}return t}}e.post(`/oauth/authorize`,(e,t)=>{o();let r=e.body||{};if(!r.providerId||typeof r.providerId!=`string`){t.status(400).json({error:`Missing required providerId`});return}let s=Dt(r.providerId);if(!s){t.status(400).json({error:`Unsupported OAuth provider`,providerId:r.providerId});return}let c=r.providerId===`custom_mcp`,l=c&&At(r.authorizeUrl)?r.authorizeUrl:s.authorizeUrl,u=c&&At(r.tokenUrl)?r.tokenUrl:s.tokenUrl,d=c&&typeof r.usePkce==`boolean`?r.usePkce:s.usePkce;if(!At(l)){t.status(c?400:500).json({error:c?`Custom MCP requires a valid authorizeUrl`:`Invalid provider authorizeUrl configuration`});return}if(!At(u)){t.status(c?400:500).json({error:c?`Custom MCP requires a valid tokenUrl`:`Invalid provider tokenUrl configuration`});return}if(!At(r.redirectUri)){t.status(400).json({error:`Invalid redirectUri`});return}if(!r.clientId||typeof r.clientId!=`string`){t.status(400).json({error:`Missing required clientId`});return}let f=Mt(r.scope);if(!Nt(s.defaultScopes,f)){t.status(400).json({error:`Requested scopes are not allowed for this provider`});return}let p=f.length?f:s.defaultScopes,m=Ot(),h=d,g=h?Ot(48):void 0,_=g?kt(g):void 0,v=n(),y=v+i;a.set(m,{providerId:r.providerId,tokenUrl:u,clientId:r.clientId,clientSecret:r.clientSecret,redirectUri:r.redirectUri,codeVerifier:g,createdAt:v,expiresAt:y,status:`pending`});let b=Ft({...r,authorizeUrl:l,tokenUrl:u,scope:p,usePkce:d,scopeSeparator:s.scopeSeparator},m,_);t.json({state:m,providerId:r.providerId,authorizeUrl:b,expiresAt:y,pkceEnabled:h,codeChallengeMethod:h?`S256`:void 0})}),e.get(`/oauth/callback`,(e,t)=>{o();let n=typeof e.query.state==`string`?e.query.state.trim():``;if(!n){t.status(400).send(`Missing state`);return}let r=s(n);if(!r){t.status(400).send(`Invalid or expired OAuth state`);return}let i=typeof e.query.error==`string`?e.query.error:void 0,a=typeof e.query.error_description==`string`?e.query.error_description:void 0;if(i){r.status=`error`,r.authorizationError=i,r.authorizationErrorDescription=a,t.status(400).send(`OAuth authorization failed: ${i}`);return}let c=typeof e.query.code==`string`?e.query.code:``;if(!c){t.status(400).send(`Missing authorization code`);return}r.status=`authorized`,r.authorizationCode=c,t.type(`html`).send(`<!doctype html>
62
62
  <html>
63
63
  <head><meta charset="utf-8"><title>OAuth Complete</title></head>
64
64
  <body>
@@ -1,40 +1,40 @@
1
1
  import ShadowClawElement from "./shadow-claw-element.js";
2
2
  import { a as showSuccess, i as showInfo, l as toastStore, o as showToast, r as showError, s as showWarning } from "../toast-DZ6r7_YI.js";
3
- import { t as ShadowClaw } from "../shadow-claw-vzcggiax.js";
4
- import { t as ShadowClawChat } from "../shadow-claw-chat-Cj1fHQIl.js";
5
- import { t as ShadowClawA2UI } from "../shadow-claw-a2ui-2I5nffIn.js";
3
+ import { t as ShadowClaw } from "../shadow-claw-WrWoPqFx.js";
4
+ import { t as ShadowClawChat } from "../shadow-claw-chat-DSYtuZod.js";
5
+ import { t as ShadowClawA2UI } from "../shadow-claw-a2ui-CcmJNXQP.js";
6
6
  import { t as ShadowClawPageHeaderActionButton } from "../shadow-claw-page-header-action-button-BXXm5b5N.js";
7
7
  import { ShadowClawA2UIInterceptor } from "./shadow-claw-a2ui-interceptor.js";
8
8
  import { ShadowClawDialog } from "./shadow-claw-dialog.js";
9
- import { t as ShadowClawPageHeader } from "../shadow-claw-page-header-DrAcWCZ9.js";
10
- import { t as ShadowClawFiles } from "../shadow-claw-files-CWBaYt9p.js";
9
+ import { t as ShadowClawPageHeader } from "../shadow-claw-page-header-BLowJopA.js";
10
+ import { t as ShadowClawFiles } from "../shadow-claw-files-D1COKzuC.js";
11
11
  import { t as ShadowClawEmptyState } from "../shadow-claw-empty-state-DPfDqaMA.js";
12
- import { t as ShadowClawFileViewer } from "../shadow-claw-file-viewer-C_ITv8T6.js";
12
+ import { t as ShadowClawFileViewer } from "../shadow-claw-file-viewer-B8G8yo48.js";
13
13
  import { t as ShadowClawPdfViewer } from "../shadow-claw-pdf-viewer-D3leDhRq.js";
14
- import { t as ShadowClawTasks } from "../shadow-claw-tasks-Dbq9rUku.js";
15
- import { n as ShadowClawTerminal } from "../shadow-claw-terminal-Wk2qRWJ9.js";
16
- import { t as ShadowClawPages } from "../shadow-claw-pages-Bj3w3V6Y.js";
17
- import { t as ShadowClawSettings } from "../shadow-claw-settings-DK-0kp3A.js";
18
- import { t as ShadowClawPeerJs } from "../shadow-claw-peerjs-B3sx2xLA.js";
19
- import { t as ShadowClawChannelConfig } from "../shadow-claw-channel-config-Cl3JvxIJ.js";
20
- import { t as ShadowClawChannels } from "../shadow-claw-channels-kv21lr_O.js";
14
+ import { t as ShadowClawTasks } from "../shadow-claw-tasks-zHWT4GaE.js";
15
+ import { n as ShadowClawTerminal } from "../shadow-claw-terminal-Bpawfv4N.js";
16
+ import { t as ShadowClawPages } from "../shadow-claw-pages-CpeUV-hw.js";
17
+ import { t as ShadowClawSettings } from "../shadow-claw-settings-ByxwW3WK.js";
18
+ import { t as ShadowClawPeerJs } from "../shadow-claw-peerjs-DYAzJbTy.js";
19
+ import { t as ShadowClawChannelConfig } from "../shadow-claw-channel-config-C4v0h8oa.js";
20
+ import { t as ShadowClawChannels } from "../shadow-claw-channels-CyV88k9T.js";
21
21
  import { t as ShadowClawProviderModelPicker } from "../shadow-claw-provider-model-picker-CsA-507a.js";
22
22
  import { t as ShadowClawProviderModuleSettings } from "../shadow-claw-provider-module-settings-3sCTnCSp.js";
23
- import { t as ShadowClawConversations } from "../shadow-claw-conversations-DghueOOD.js";
23
+ import { t as ShadowClawConversations } from "../shadow-claw-conversations-Cp8pK4PM.js";
24
24
  import { t as ShadowClawToast } from "../shadow-claw-toast-C8oAkrMC.js";
25
- import { t as ShadowClawTools } from "../shadow-claw-tools-C9TEf2k7.js";
25
+ import { t as ShadowClawTools } from "../shadow-claw-tools-BbKdWcps.js";
26
26
  import { t as ShadowClawActions } from "../shadow-claw-actions-G99P9oxr.js";
27
27
  import { t as ShadowClawCard } from "../shadow-claw-card-D9azfSMu.js";
28
- import { t as ShadowClawAccounts } from "../shadow-claw-accounts-DMb0y4ca.js";
29
- import { t as ShadowClawControlPlane } from "../shadow-claw-control-plane-DySeKB36.js";
30
- import { t as ShadowClawGit } from "../shadow-claw-git-XfPBpfXd.js";
31
- import { t as ShadowClawIntegrations } from "../shadow-claw-integrations-yT7j07TM.js";
32
- import { t as ShadowClawLlm } from "../shadow-claw-llm-Gzx4ufL_.js";
33
- import { t as ShadowClawMcpRemote } from "../shadow-claw-mcp-remote-DGDWjByQ.js";
34
- import { t as ShadowClawNetworking } from "../shadow-claw-networking-CYEbc5TR.js";
35
- import { t as ShadowClawNotifications } from "../shadow-claw-notifications-DHvkTrgv.js";
36
- import { t as ShadowClawStorage } from "../shadow-claw-storage-p9nVMQPF.js";
37
- import { t as ShadowClawTaskServer } from "../shadow-claw-task-server-BNKCWG2M.js";
38
- import { t as ShadowClawWebvm } from "../shadow-claw-webvm-VoKerWW8.js";
28
+ import { t as ShadowClawAccounts } from "../shadow-claw-accounts-CcB2429E.js";
29
+ import { t as ShadowClawControlPlane } from "../shadow-claw-control-plane-DBSGuDT1.js";
30
+ import { t as ShadowClawGit } from "../shadow-claw-git-60tWU4Ee.js";
31
+ import { t as ShadowClawIntegrations } from "../shadow-claw-integrations-Bw1cG1ze.js";
32
+ import { t as ShadowClawLlm } from "../shadow-claw-llm-By5CvsFJ.js";
33
+ import { t as ShadowClawMcpRemote } from "../shadow-claw-mcp-remote-BaNODd1v.js";
34
+ import { t as ShadowClawNetworking } from "../shadow-claw-networking-DtZ5bsTz.js";
35
+ import { t as ShadowClawNotifications } from "../shadow-claw-notifications-C3VEba_A.js";
36
+ import { t as ShadowClawStorage } from "../shadow-claw-storage-CsSPYVDJ.js";
37
+ import { t as ShadowClawTaskServer } from "../shadow-claw-task-server-De2WCEw4.js";
38
+ import { t as ShadowClawWebvm } from "../shadow-claw-webvm-DLqK0AxW.js";
39
39
 
40
40
  export { ShadowClaw, ShadowClawA2UI, ShadowClawA2UIInterceptor, ShadowClawAccounts, ShadowClawActions, ShadowClawCard, ShadowClawChannelConfig, ShadowClawChannels, ShadowClawChat, ShadowClawControlPlane, ShadowClawConversations, ShadowClawDialog, ShadowClawElement, ShadowClawEmptyState, ShadowClawFileViewer, ShadowClawFiles, ShadowClawGit, ShadowClawIntegrations, ShadowClawLlm, ShadowClawMcpRemote, ShadowClawNetworking, ShadowClawNotifications, ShadowClawPageHeader, ShadowClawPageHeaderActionButton, ShadowClawPages, ShadowClawPdfViewer, ShadowClawPeerJs, ShadowClawProviderModelPicker, ShadowClawProviderModuleSettings, ShadowClawSettings, ShadowClawStorage, ShadowClawTaskServer, ShadowClawTasks, ShadowClawTerminal, ShadowClawToast, ShadowClawTools, ShadowClawWebvm, showError, showInfo, showSuccess, showToast, showWarning, toastStore };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawAccounts } from "../../shadow-claw-accounts-DMb0y4ca.js";
1
+ import { t as ShadowClawAccounts } from "../../shadow-claw-accounts-CcB2429E.js";
2
2
 
3
3
  export { ShadowClawAccounts };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawChannelConfig } from "../../shadow-claw-channel-config-Cl3JvxIJ.js";
1
+ import { t as ShadowClawChannelConfig } from "../../shadow-claw-channel-config-C4v0h8oa.js";
2
2
 
3
3
  export { ShadowClawChannelConfig };
@@ -1,3 +1,3 @@
1
- import { n as getControlPlaneTargetAddressSpace, t as ShadowClawControlPlane } from "../../shadow-claw-control-plane-DySeKB36.js";
1
+ import { n as getControlPlaneTargetAddressSpace, t as ShadowClawControlPlane } from "../../shadow-claw-control-plane-DBSGuDT1.js";
2
2
 
3
3
  export { ShadowClawControlPlane, getControlPlaneTargetAddressSpace };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawGit } from "../../shadow-claw-git-XfPBpfXd.js";
1
+ import { t as ShadowClawGit } from "../../shadow-claw-git-60tWU4Ee.js";
2
2
 
3
3
  export { ShadowClawGit };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawIntegrations } from "../../shadow-claw-integrations-yT7j07TM.js";
1
+ import { t as ShadowClawIntegrations } from "../../shadow-claw-integrations-Bw1cG1ze.js";
2
2
 
3
3
  export { ShadowClawIntegrations };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawLlm } from "../../shadow-claw-llm-Gzx4ufL_.js";
1
+ import { t as ShadowClawLlm } from "../../shadow-claw-llm-By5CvsFJ.js";
2
2
 
3
3
  export { ShadowClawLlm };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawMcpRemote } from "../../shadow-claw-mcp-remote-DGDWjByQ.js";
1
+ import { t as ShadowClawMcpRemote } from "../../shadow-claw-mcp-remote-BaNODd1v.js";
2
2
 
3
3
  export { ShadowClawMcpRemote };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawNetworking } from "../../shadow-claw-networking-CYEbc5TR.js";
1
+ import { t as ShadowClawNetworking } from "../../shadow-claw-networking-DtZ5bsTz.js";
2
2
 
3
3
  export { ShadowClawNetworking };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawNotifications } from "../../shadow-claw-notifications-DHvkTrgv.js";
1
+ import { t as ShadowClawNotifications } from "../../shadow-claw-notifications-C3VEba_A.js";
2
2
 
3
3
  export { ShadowClawNotifications };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawPeerJs } from "../../shadow-claw-peerjs-B3sx2xLA.js";
1
+ import { t as ShadowClawPeerJs } from "../../shadow-claw-peerjs-DYAzJbTy.js";
2
2
 
3
3
  export { ShadowClawPeerJs };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawStorage } from "../../shadow-claw-storage-p9nVMQPF.js";
1
+ import { t as ShadowClawStorage } from "../../shadow-claw-storage-CsSPYVDJ.js";
2
2
 
3
3
  export { ShadowClawStorage };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawTaskServer } from "../../shadow-claw-task-server-BNKCWG2M.js";
1
+ import { t as ShadowClawTaskServer } from "../../shadow-claw-task-server-De2WCEw4.js";
2
2
 
3
3
  export { ShadowClawTaskServer };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawWebvm } from "../../shadow-claw-webvm-VoKerWW8.js";
1
+ import { t as ShadowClawWebvm } from "../../shadow-claw-webvm-DLqK0AxW.js";
2
2
 
3
3
  export { ShadowClawWebvm };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawA2UI } from "../shadow-claw-a2ui-2I5nffIn.js";
1
+ import { t as ShadowClawA2UI } from "../shadow-claw-a2ui-CcmJNXQP.js";
2
2
 
3
3
  export { ShadowClawA2UI };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawAccounts } from "../shadow-claw-accounts-DMb0y4ca.js";
1
+ import { t as ShadowClawAccounts } from "../shadow-claw-accounts-CcB2429E.js";
2
2
 
3
3
  export { ShadowClawAccounts };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawChannelConfig } from "../shadow-claw-channel-config-Cl3JvxIJ.js";
1
+ import { t as ShadowClawChannelConfig } from "../shadow-claw-channel-config-C4v0h8oa.js";
2
2
 
3
3
  export { ShadowClawChannelConfig };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawChannels } from "../shadow-claw-channels-kv21lr_O.js";
1
+ import { t as ShadowClawChannels } from "../shadow-claw-channels-CyV88k9T.js";
2
2
 
3
3
  export { ShadowClawChannels };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawChat } from "../shadow-claw-chat-Cj1fHQIl.js";
1
+ import { t as ShadowClawChat } from "../shadow-claw-chat-DSYtuZod.js";
2
2
 
3
3
  export { ShadowClawChat };
@@ -1,3 +1,3 @@
1
- import { n as getControlPlaneTargetAddressSpace, t as ShadowClawControlPlane } from "../shadow-claw-control-plane-DySeKB36.js";
1
+ import { n as getControlPlaneTargetAddressSpace, t as ShadowClawControlPlane } from "../shadow-claw-control-plane-DBSGuDT1.js";
2
2
 
3
3
  export { ShadowClawControlPlane, getControlPlaneTargetAddressSpace };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawConversations } from "../shadow-claw-conversations-DghueOOD.js";
1
+ import { t as ShadowClawConversations } from "../shadow-claw-conversations-Cp8pK4PM.js";
2
2
 
3
3
  export { ShadowClawConversations };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawFileViewer } from "../shadow-claw-file-viewer-C_ITv8T6.js";
1
+ import { t as ShadowClawFileViewer } from "../shadow-claw-file-viewer-B8G8yo48.js";
2
2
 
3
3
  export { ShadowClawFileViewer };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawFiles } from "../shadow-claw-files-CWBaYt9p.js";
1
+ import { t as ShadowClawFiles } from "../shadow-claw-files-D1COKzuC.js";
2
2
 
3
3
  export { ShadowClawFiles };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawGit } from "../shadow-claw-git-XfPBpfXd.js";
1
+ import { t as ShadowClawGit } from "../shadow-claw-git-60tWU4Ee.js";
2
2
 
3
3
  export { ShadowClawGit };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawIntegrations } from "../shadow-claw-integrations-yT7j07TM.js";
1
+ import { t as ShadowClawIntegrations } from "../shadow-claw-integrations-Bw1cG1ze.js";
2
2
 
3
3
  export { ShadowClawIntegrations };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawLlm } from "../shadow-claw-llm-Gzx4ufL_.js";
1
+ import { t as ShadowClawLlm } from "../shadow-claw-llm-By5CvsFJ.js";
2
2
 
3
3
  export { ShadowClawLlm };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawMcpRemote } from "../shadow-claw-mcp-remote-DGDWjByQ.js";
1
+ import { t as ShadowClawMcpRemote } from "../shadow-claw-mcp-remote-BaNODd1v.js";
2
2
 
3
3
  export { ShadowClawMcpRemote };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawNetworking } from "../shadow-claw-networking-CYEbc5TR.js";
1
+ import { t as ShadowClawNetworking } from "../shadow-claw-networking-DtZ5bsTz.js";
2
2
 
3
3
  export { ShadowClawNetworking };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawNotifications } from "../shadow-claw-notifications-DHvkTrgv.js";
1
+ import { t as ShadowClawNotifications } from "../shadow-claw-notifications-C3VEba_A.js";
2
2
 
3
3
  export { ShadowClawNotifications };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawPageHeader } from "../shadow-claw-page-header-DrAcWCZ9.js";
1
+ import { t as ShadowClawPageHeader } from "../shadow-claw-page-header-BLowJopA.js";
2
2
 
3
3
  export { ShadowClawPageHeader };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawPages } from "../shadow-claw-pages-Bj3w3V6Y.js";
1
+ import { t as ShadowClawPages } from "../shadow-claw-pages-CpeUV-hw.js";
2
2
 
3
3
  export { ShadowClawPages };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawPeerJs } from "../shadow-claw-peerjs-B3sx2xLA.js";
1
+ import { t as ShadowClawPeerJs } from "../shadow-claw-peerjs-DYAzJbTy.js";
2
2
 
3
3
  export { ShadowClawPeerJs };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawSettings } from "../shadow-claw-settings-DK-0kp3A.js";
1
+ import { t as ShadowClawSettings } from "../shadow-claw-settings-ByxwW3WK.js";
2
2
 
3
3
  export { ShadowClawSettings };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawStorage } from "../shadow-claw-storage-p9nVMQPF.js";
1
+ import { t as ShadowClawStorage } from "../shadow-claw-storage-CsSPYVDJ.js";
2
2
 
3
3
  export { ShadowClawStorage };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawTaskServer } from "../shadow-claw-task-server-BNKCWG2M.js";
1
+ import { t as ShadowClawTaskServer } from "../shadow-claw-task-server-De2WCEw4.js";
2
2
 
3
3
  export { ShadowClawTaskServer };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawTasks } from "../shadow-claw-tasks-Dbq9rUku.js";
1
+ import { t as ShadowClawTasks } from "../shadow-claw-tasks-zHWT4GaE.js";
2
2
 
3
3
  export { ShadowClawTasks };
@@ -1,3 +1,3 @@
1
- import { n as ShadowClawTerminal, t as AUTO_SCROLL_BOTTOM_THRESHOLD_PX } from "../shadow-claw-terminal-Wk2qRWJ9.js";
1
+ import { n as ShadowClawTerminal, t as AUTO_SCROLL_BOTTOM_THRESHOLD_PX } from "../shadow-claw-terminal-Bpawfv4N.js";
2
2
 
3
3
  export { AUTO_SCROLL_BOTTOM_THRESHOLD_PX, ShadowClawTerminal };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawTools } from "../shadow-claw-tools-C9TEf2k7.js";
1
+ import { t as ShadowClawTools } from "../shadow-claw-tools-BbKdWcps.js";
2
2
 
3
3
  export { ShadowClawTools };
@@ -1,3 +1,3 @@
1
- import { t as ShadowClawWebvm } from "../shadow-claw-webvm-VoKerWW8.js";
1
+ import { t as ShadowClawWebvm } from "../shadow-claw-webvm-DLqK0AxW.js";
2
2
 
3
3
  export { ShadowClawWebvm };
@@ -1,4 +1,4 @@
1
- import { t as ShadowClaw } from "../shadow-claw-vzcggiax.js";
1
+ import { t as ShadowClaw } from "../shadow-claw-WrWoPqFx.js";
2
2
  import { n as MAX_SIDEBAR_WIDTH_PX, r as MIN_SIDEBAR_WIDTH_PX, t as DEFAULT_SIDEBAR_WIDTH_PX } from "../constants-BxxDX8j_.js";
3
3
 
4
4
  export { DEFAULT_SIDEBAR_WIDTH_PX, MAX_SIDEBAR_WIDTH_PX, MIN_SIDEBAR_WIDTH_PX, ShadowClaw };
@@ -15,10 +15,25 @@ var ModelRegistry = class {
15
15
  loading = false;
16
16
  models = /* @__PURE__ */ new Map();
17
17
  /**
18
- * Get metadata for a model ID. Lookup is case-insensitive.
18
+ * Get metadata for a model ID. Lookup is case-insensitive and resilient
19
+ * to provider prefixes (e.g. "anthropic/claude-3.7-sonnet" vs "claude-3.7-sonnet")
20
+ * and variant tags (e.g. ":thinking").
19
21
  */
20
22
  getModelInfo(modelId) {
21
- return this.models.get(modelId.toLowerCase()) ?? null;
23
+ if (!modelId || typeof modelId !== "string") return null;
24
+ const key = modelId.toLowerCase().trim();
25
+ const direct = this.models.get(key);
26
+ if (direct) return direct;
27
+ if (key.includes("/")) {
28
+ const bare = key.split("/").pop();
29
+ if (bare && this.models.has(bare)) return this.models.get(bare);
30
+ } else for (const [regKey, meta] of this.models.entries()) if (regKey.endsWith(`/${key}`)) return meta;
31
+ if (key.includes(":")) {
32
+ const withoutTag = key.split(":")[0];
33
+ const match = this.getModelInfo(withoutTag);
34
+ if (match) return match;
35
+ }
36
+ return null;
22
37
  }
23
38
  /**
24
39
  * Manually register model info. Keys are normalized to lowercase.
@@ -66,6 +81,7 @@ var ModelRegistry = class {
66
81
  const supportsVideoInput = this.modalitiesInclude(inputModalities, "video");
67
82
  const routesByRequestFeatures = model.id === "openrouter/free" || this.supportedParametersInclude(model, "image", "vision", "audio", "tool", "structured");
68
83
  const reasoning = this.extractReasoning(model);
84
+ const supportsPromptCaching = typeof model.supports_prompt_caching === "boolean" ? model.supports_prompt_caching : typeof model.supportsPromptCaching === "boolean" ? model.supportsPromptCaching : this.supportedParametersInclude(model, "cache_control", "prompt_caching") ? true : void 0;
69
85
  if (!contextLength && Array.isArray(model.providers) && model.providers.length > 0) contextLength = model.providers[0]?.context_length || 0;
70
86
  this.registerModelInfo(model.id, {
71
87
  contextWindow: contextLength,
@@ -77,7 +93,8 @@ var ModelRegistry = class {
77
93
  ...supportsAudioInput !== void 0 && { supportsAudioInput },
78
94
  ...supportsVideoInput !== void 0 && { supportsVideoInput },
79
95
  ...reasoning && { reasoning },
80
- ...routesByRequestFeatures && { routesByRequestFeatures }
96
+ ...routesByRequestFeatures && { routesByRequestFeatures },
97
+ ...supportsPromptCaching !== void 0 && { supportsPromptCaching }
81
98
  });
82
99
  }
83
100
  if (items.length > 0) console.log(`[ModelRegistry] Registered ${items.length} models for provider "${provider.id}"`);
@@ -1293,4 +1310,4 @@ const DEFAULT_TASK_SERVER_URL = "http://localhost:8888/schedule";
1293
1310
 
1294
1311
  //#endregion
1295
1312
  export { getAvailableProviders as A, PROVIDERS as C, TELEGRAM_PROXY_BASE as D, TELEGRAM_MAX_LENGTH as E, getProvider as F, getProviderApiKeyConfigKey as I, getProviderTokenAuthScheme as L, getDefaultProvider as M, getGeneralAccountProviderCapabilities as N, buildTriggerPattern as O, getModelMaxTokens as P, modelRegistry as R, PEERJS_DEFAULT_HOST as S, TELEGRAM_API_BASE as T, LEGACY_DB_NAME as _, DEFAULT_DEV_PORT as a, OAUTH_PROVIDER_DEFINITIONS as b, DEFAULT_PROMPT_API_FALLBACK_MODEL as c, DEFAULT_TASK_SERVER_URL as d, DEFAULT_VM_BOOT_HOST as f, IMESSAGE_REQUEST_TIMEOUT_MS as g, GENERAL_ACCOUNT_PROVIDER_CAPABILITIES as h, DEFAULT_DEV_HOST as i, getDbName as j, config_exports as k, DEFAULT_PROVIDER as l, FETCH_MAX_RESPONSE as m, BASH_MAX_TIMEOUT_SEC as n, DEFAULT_GROUP_ID as o, DEFAULT_VM_NETWORK_RELAY_URL as p, CONFIG_KEYS as r, DEFAULT_MAX_TOKENS as s, ASSISTANT_NAME as t, DEFAULT_SUBAGENT_WORKSPACE_MODE as u, LEGACY_OPFS_ROOT as v, SCHEDULER_INTERVAL as w, OPFS_ROOT as x, LLAMAFILE_PROXY_URL as y };
1296
- //# sourceMappingURL=config-DjZ9QWc4.js.map
1313
+ //# sourceMappingURL=config-BcFbkaQv.js.map