shadow-claw 1.26.0 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/main/skill-creator/SKILL.md +39 -0
- package/.agents/skills/main/skill-creator/references/declarative-pipelines.md +44 -0
- package/.agents/skills/main/skill-creator/references/declarative-tools.md +35 -0
- package/.agents/skills/main/skill-creator/references/frontmatter-spec.md +50 -0
- package/.well-known/agent-skills/index.json +14 -0
- package/README.md +5 -3
- package/bin/build/build.mjs +146 -15
- package/bin/build/build.test.mjs +57 -0
- package/bin/cli.mjs +26 -0
- package/bin/commands/mcp.mjs +277 -55
- package/bin/commands/mcp.test.mjs +275 -1
- package/bin/commands/skills-index.mjs +328 -0
- package/bin/commands/skills-index.test.mjs +161 -0
- package/bin/site-config/utils/custom-elements/get-approved-custom-element-scripts.test.mjs +2 -0
- package/bin/site-config/utils/custom-elements/sanitize-embedded-custom-element-scripts.test.mjs +10 -1
- package/dist/lib/components/index.js +25 -25
- package/dist/lib/components/settings/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/settings/shadow-claw-git.js +1 -1
- package/dist/lib/components/settings/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
- package/dist/lib/components/settings/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
- package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
- package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw-a2ui.js +1 -1
- package/dist/lib/components/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/shadow-claw-channels.js +1 -1
- package/dist/lib/components/shadow-claw-chat.js +1 -1
- package/dist/lib/components/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/shadow-claw-conversations.js +1 -1
- package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
- package/dist/lib/components/shadow-claw-files.js +1 -1
- package/dist/lib/components/shadow-claw-git.js +1 -1
- package/dist/lib/components/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/shadow-claw-llm.js +1 -1
- package/dist/lib/components/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/shadow-claw-networking.js +1 -1
- package/dist/lib/components/shadow-claw-page-header.js +1 -1
- package/dist/lib/components/shadow-claw-pages.js +1 -1
- package/dist/lib/components/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/shadow-claw-settings.js +1 -1
- package/dist/lib/components/shadow-claw-storage.js +1 -1
- package/dist/lib/components/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/shadow-claw-tasks.js +1 -1
- package/dist/lib/components/shadow-claw-terminal.js +1 -1
- package/dist/lib/components/shadow-claw-tools.js +1 -1
- package/dist/lib/components/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw.js +1 -1
- package/dist/lib/{configurePeerJs-CrlGan0m.js → configurePeerJs-oODzltaC.js} +2 -2
- package/dist/lib/{configurePeerJs-CrlGan0m.js.map → configurePeerJs-oODzltaC.js.map} +1 -1
- package/dist/lib/core/control-plane-client.d.ts +1 -0
- package/dist/lib/{downloadGroupFile-DboUjmp2.js → downloadGroupFile-DmcBQU1n.js} +2 -2
- package/dist/lib/{downloadGroupFile-DboUjmp2.js.map → downloadGroupFile-DmcBQU1n.js.map} +1 -1
- package/dist/lib/{file-viewer-BrK2Wxgh.js → file-viewer-C3YKnq_-.js} +4 -3
- package/dist/lib/{file-viewer-BrK2Wxgh.js.map → file-viewer-C3YKnq_-.js.map} +1 -1
- package/dist/lib/index.js +26 -26
- package/dist/lib/{initControlPlane-CsO4UR6_.js → initControlPlane-C2zURVIS.js} +86 -13
- package/dist/lib/initControlPlane-C2zURVIS.js.map +1 -0
- package/dist/lib/{markdown-eeSTFnMA.js → markdown-C6EHl9zs.js} +3 -3
- package/dist/lib/{markdown-eeSTFnMA.js.map → markdown-C6EHl9zs.js.map} +1 -1
- package/dist/lib/{orchestrator-CJvoC2Uu.js → orchestrator-CACLa_Ro.js} +7 -6
- package/dist/lib/{orchestrator-CJvoC2Uu.js.map → orchestrator-CACLa_Ro.js.map} +1 -1
- package/dist/lib/{orchestrator-DCfomsn9.js → orchestrator-KRjx0eba.js} +6 -534
- package/dist/lib/{orchestrator-DCfomsn9.js.map → orchestrator-KRjx0eba.js.map} +1 -1
- package/dist/lib/parsePath-DwC_YZjw.js +16 -0
- package/dist/lib/parsePath-DwC_YZjw.js.map +1 -0
- package/dist/lib/{peerjs-Dp02bXcG.js → peerjs-DFWOBcXf.js} +4 -4
- package/dist/lib/{peerjs-Dp02bXcG.js.map → peerjs-DFWOBcXf.js.map} +1 -1
- package/dist/lib/{readGroupFileBytes-Bve-e5e_.js → readGroupFileBytes-C8oOe8Iu.js} +3 -16
- package/dist/lib/readGroupFileBytes-C8oOe8Iu.js.map +1 -0
- package/dist/lib/security/custom-element-security.d.ts +8 -0
- package/dist/lib/server/control-plane-types.d.ts +1 -1
- package/dist/lib/{shadow-claw-D8xINM3c.js → shadow-claw-6UHdiy4a.js} +5 -5
- package/dist/lib/{shadow-claw-D8xINM3c.js.map → shadow-claw-6UHdiy4a.js.map} +1 -1
- package/dist/lib/{shadow-claw-a2ui-7rJqG4Ke.js → shadow-claw-a2ui-CpZUTzlh.js} +5 -4
- package/dist/lib/{shadow-claw-a2ui-7rJqG4Ke.js.map → shadow-claw-a2ui-CpZUTzlh.js.map} +1 -1
- package/dist/lib/{shadow-claw-accounts-CdruwN8A.js → shadow-claw-accounts-03oJ__XC.js} +2 -2
- package/dist/lib/{shadow-claw-accounts-CdruwN8A.js.map → shadow-claw-accounts-03oJ__XC.js.map} +1 -1
- package/dist/lib/{shadow-claw-channel-config-Bj0-Nk3t.js → shadow-claw-channel-config-DmfwJc6G.js} +3 -3
- package/dist/lib/{shadow-claw-channel-config-Bj0-Nk3t.js.map → shadow-claw-channel-config-DmfwJc6G.js.map} +1 -1
- package/dist/lib/{shadow-claw-channels-C_jI4KhP.js → shadow-claw-channels-1N6Jl-By.js} +3 -3
- package/dist/lib/{shadow-claw-channels-C_jI4KhP.js.map → shadow-claw-channels-1N6Jl-By.js.map} +1 -1
- package/dist/lib/{shadow-claw-chat-B16MspoP.js → shadow-claw-chat-BMoqQJRK.js} +10 -10
- package/dist/lib/{shadow-claw-chat-B16MspoP.js.map → shadow-claw-chat-BMoqQJRK.js.map} +1 -1
- package/dist/lib/{shadow-claw-control-plane-x8Ldid_h.js → shadow-claw-control-plane-UG0o7pCz.js} +6 -6
- package/dist/lib/{shadow-claw-control-plane-x8Ldid_h.js.map → shadow-claw-control-plane-UG0o7pCz.js.map} +1 -1
- package/dist/lib/{shadow-claw-conversations-Ct1kAYdB.js → shadow-claw-conversations-BwXep3iu.js} +4 -3
- package/dist/lib/{shadow-claw-conversations-Ct1kAYdB.js.map → shadow-claw-conversations-BwXep3iu.js.map} +1 -1
- package/dist/lib/{shadow-claw-file-viewer-BfDHHgpA.js → shadow-claw-file-viewer-DUxzVxDT.js} +14 -10
- package/dist/lib/shadow-claw-file-viewer-DUxzVxDT.js.map +1 -0
- package/dist/lib/{shadow-claw-files-EYhOPYIH.js → shadow-claw-files-DIREEnT2.js} +7 -7
- package/dist/lib/{shadow-claw-files-EYhOPYIH.js.map → shadow-claw-files-DIREEnT2.js.map} +1 -1
- package/dist/lib/{shadow-claw-git-tcSpT-P0.js → shadow-claw-git-Bg1SWgsF.js} +4 -4
- package/dist/lib/{shadow-claw-git-tcSpT-P0.js.map → shadow-claw-git-Bg1SWgsF.js.map} +1 -1
- package/dist/lib/{shadow-claw-integrations-NbcCx_ZI.js → shadow-claw-integrations-Ds-CLPhj.js} +2 -2
- package/dist/lib/{shadow-claw-integrations-NbcCx_ZI.js.map → shadow-claw-integrations-Ds-CLPhj.js.map} +1 -1
- package/dist/lib/{shadow-claw-llm-BazJdD5f.js → shadow-claw-llm-CazBrVpM.js} +3 -3
- package/dist/lib/{shadow-claw-llm-BazJdD5f.js.map → shadow-claw-llm-CazBrVpM.js.map} +1 -1
- package/dist/lib/{shadow-claw-mcp-remote-CYmhpg7a.js → shadow-claw-mcp-remote-CT5Q-54E.js} +2 -2
- package/dist/lib/{shadow-claw-mcp-remote-CYmhpg7a.js.map → shadow-claw-mcp-remote-CT5Q-54E.js.map} +1 -1
- package/dist/lib/{shadow-claw-networking-DImPxe0H.js → shadow-claw-networking-Df85tCbO.js} +2 -2
- package/dist/lib/{shadow-claw-networking-DImPxe0H.js.map → shadow-claw-networking-Df85tCbO.js.map} +1 -1
- package/dist/lib/{shadow-claw-page-header-CcHUfFUx.js → shadow-claw-page-header-Cti2fzf-.js} +2 -2
- package/dist/lib/{shadow-claw-page-header-CcHUfFUx.js.map → shadow-claw-page-header-Cti2fzf-.js.map} +1 -1
- package/dist/lib/{shadow-claw-pages-D54jF1Qq.js → shadow-claw-pages-BgPyIEZO.js} +15 -11
- package/dist/lib/shadow-claw-pages-BgPyIEZO.js.map +1 -0
- package/dist/lib/{shadow-claw-peerjs-B9-T8Nlx.js → shadow-claw-peerjs-xkBXILed.js} +3 -3
- package/dist/lib/{shadow-claw-peerjs-B9-T8Nlx.js.map → shadow-claw-peerjs-xkBXILed.js.map} +1 -1
- package/dist/lib/{shadow-claw-settings-Bt1VAe-1.js → shadow-claw-settings-CN89xRVU.js} +4 -4
- package/dist/lib/{shadow-claw-settings-Bt1VAe-1.js.map → shadow-claw-settings-CN89xRVU.js.map} +1 -1
- package/dist/lib/{shadow-claw-storage-CFOjGf1d.js → shadow-claw-storage-VnhcObCe.js} +3 -3
- package/dist/lib/{shadow-claw-storage-CFOjGf1d.js.map → shadow-claw-storage-VnhcObCe.js.map} +1 -1
- package/dist/lib/{shadow-claw-task-server-BiKa2GOm.js → shadow-claw-task-server-jgEC2hHB.js} +2 -2
- package/dist/lib/{shadow-claw-task-server-BiKa2GOm.js.map → shadow-claw-task-server-jgEC2hHB.js.map} +1 -1
- package/dist/lib/{shadow-claw-tasks-DDHd8W4d.js → shadow-claw-tasks-i_evIufy.js} +6 -6
- package/dist/lib/{shadow-claw-tasks-DDHd8W4d.js.map → shadow-claw-tasks-i_evIufy.js.map} +1 -1
- package/dist/lib/{shadow-claw-terminal-kB6_tWKz.js → shadow-claw-terminal-CwScROlu.js} +2 -2
- package/dist/lib/{shadow-claw-terminal-kB6_tWKz.js.map → shadow-claw-terminal-CwScROlu.js.map} +1 -1
- package/dist/lib/{shadow-claw-tools-DxXIm0ku.js → shadow-claw-tools-DD3fyXP4.js} +5 -4
- package/dist/lib/{shadow-claw-tools-DxXIm0ku.js.map → shadow-claw-tools-DD3fyXP4.js.map} +1 -1
- package/dist/lib/{shadow-claw-webvm-Dc8oo7ao.js → shadow-claw-webvm-DbJq4I3-.js} +2 -2
- package/dist/lib/{shadow-claw-webvm-Dc8oo7ao.js.map → shadow-claw-webvm-DbJq4I3-.js.map} +1 -1
- package/dist/lib/{syncWebMcpRegistration-jyRGbC9w.js → syncWebMcpRegistration-DNLnQ-jz.js} +3 -2
- package/dist/lib/{syncWebMcpRegistration-jyRGbC9w.js.map → syncWebMcpRegistration-DNLnQ-jz.js.map} +1 -1
- package/dist/lib/tools-DwwB9RBa.js +546 -0
- package/dist/lib/tools-DwwB9RBa.js.map +1 -0
- package/dist/lib/{trusted-types-CkLDpLiZ.js → trusted-types-Dx0RZlrd.js} +19 -8
- package/dist/lib/trusted-types-Dx0RZlrd.js.map +1 -0
- package/dist/lib/utils/index.js +1 -1
- package/dist/lib/utils/utils.js +1 -1
- package/dist/public/.well-known/agent-skills/index.json +14 -0
- package/dist/public/AGENTS.md +5 -3
- package/dist/public/README.md +5 -3
- package/dist/public/agent.worker.js +1 -1
- package/dist/public/{configurePeerJs-COcwE0E7.js → configurePeerJs-BqgeBjP7.js} +1 -1
- package/dist/public/custom-element-security-FU04Cq05.js +1 -0
- package/dist/public/dist-B9m1QM9v.js +58 -0
- package/dist/public/docs/README.md +31 -31
- package/dist/public/docs/example/article/index.html +1 -1
- package/dist/public/docs/publishing/index.html +1 -1
- package/dist/public/docs/skill-creator/index.html +1 -1
- package/dist/public/docs/subsystems/a2ui.md +11 -1
- package/dist/public/docs/subsystems/cli.md +29 -0
- package/dist/public/docs/subsystems/control-plane.md +8 -2
- package/dist/public/docs/subsystems/custom-element-security.md +19 -9
- package/dist/public/docs/subsystems/mcp-server.md +39 -15
- package/dist/public/docs/subsystems/skills.md +30 -0
- package/dist/public/docs/subsystems/webmcp.md +9 -0
- package/dist/public/downloadGroupFile-D8KRJGGL.js +1 -0
- package/dist/public/e2e/README.md +7 -4
- package/dist/public/{e2e-bridge-CHARpbpW.js → e2e-bridge-Ceqr5kGc.js} +1 -1
- package/dist/public/effect-BJCrpFdp.js +1 -0
- package/dist/public/file-viewer-C-6Jc_tb.js +1 -0
- package/dist/public/index.html +1 -1
- package/dist/public/index.js +1 -1
- package/dist/public/initControlPlane-BN9cWyO0.js +1 -0
- package/dist/public/main/index.html +1 -1
- package/dist/public/main/memory/index.html +1 -1
- package/dist/public/{markdown-1I3O6Mmd.js → markdown-C3M4OW_A.js} +1 -1
- package/dist/public/{orchestrator-Cl95w2vb.js → orchestrator-CMbCTjBf.js} +7 -7
- package/dist/public/{orchestrator-D-xlXG92.js → orchestrator-DHjdLtqa.js} +663 -663
- package/dist/public/peerjs-DUCKH-m9.js +1 -0
- package/dist/public/service-worker.js +1 -1
- package/dist/public/{shadow-claw-CaoKmIIB.js → shadow-claw-EAt2ml5Y.js} +3 -3
- package/dist/public/{shadow-claw-accounts-CJvYC4li.js → shadow-claw-accounts-xUOLBsQZ.js} +1 -1
- package/dist/public/{shadow-claw-channels-3K62sU5f.js → shadow-claw-channels-XsfuWFF8.js} +4 -4
- package/dist/public/{shadow-claw-chat-Cu2keU2I.js → shadow-claw-chat-CbSaOZ4q.js} +7 -7
- package/dist/public/{shadow-claw-control-plane-D1OwlQI_.js → shadow-claw-control-plane-DHvN3Ukg.js} +2 -2
- package/dist/public/{shadow-claw-conversations-DDtg3BEZ.js → shadow-claw-conversations-BWs5VVfs.js} +2 -2
- package/dist/public/{shadow-claw-file-viewer-BR__1z9S.js → shadow-claw-file-viewer-BWsoW5QS.js} +5 -4
- package/dist/public/{shadow-claw-files-BJSyZ-Bl.js → shadow-claw-files-CG7MqWiV.js} +8 -8
- package/dist/public/{shadow-claw-git-MAjhXRLc.js → shadow-claw-git-DBRPZNav.js} +6 -6
- package/dist/public/{shadow-claw-integrations-82UoFuDR.js → shadow-claw-integrations-BBVnO0Fc.js} +8 -8
- package/dist/public/{shadow-claw-llm-R8j0lwPP.js → shadow-claw-llm-DMvLgKXo.js} +2 -2
- package/dist/public/{shadow-claw-mcp-remote-BzZoz4LX.js → shadow-claw-mcp-remote-Bkx0gsmF.js} +2 -2
- package/dist/public/{shadow-claw-networking-DLEd9cNm.js → shadow-claw-networking-Dd8Rw31D.js} +2 -2
- package/dist/public/{shadow-claw-notifications-1vwR7TbT.js → shadow-claw-notifications-Dbevj-lq.js} +2 -2
- package/dist/public/{shadow-claw-page-header-DMKbkv3s.js → shadow-claw-page-header-BccSHItx.js} +1 -1
- package/dist/public/{shadow-claw-pages-CjyeIV__.js → shadow-claw-pages-3_lQAv0t.js} +4 -3
- package/dist/public/{shadow-claw-settings-BfbT4dBU.js → shadow-claw-settings-t8TIlgrM.js} +5 -5
- package/dist/public/{shadow-claw-storage-C-mWQQML.js → shadow-claw-storage-CfEXoSIE.js} +2 -2
- package/dist/public/{shadow-claw-task-server-D3lHp0Nc.js → shadow-claw-task-server-DxQSsgRZ.js} +2 -2
- package/dist/public/{shadow-claw-tasks-DVVWEm-c.js → shadow-claw-tasks-DNpicQwz.js} +14 -14
- package/dist/public/{shadow-claw-terminal-BwuTRp-O.js → shadow-claw-terminal-DpY6zU_r.js} +1 -1
- package/dist/public/{shadow-claw-toast-ClCwgzFG.js → shadow-claw-toast-BkrQIP-3.js} +1 -1
- package/dist/public/{shadow-claw-tools-zFLk2nbV.js → shadow-claw-tools-WSwWohnk.js} +2 -2
- package/dist/public/{shadow-claw-webvm-qR9X7fg7.js → shadow-claw-webvm-CP6oFjg5.js} +2 -2
- package/dist/public/syncWebMcpRegistration-DOn9gLnD.js +1 -0
- package/dist/public/toast-BXgUfbyh.js +1 -0
- package/dist/public/tools-DvckJZG2.js +1 -0
- package/dist/server.js +188 -188
- package/package.json +3 -1
- package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.stories.ts +1380 -93
- package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.ts +11 -6
- package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.test.ts +8 -1
- package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.ts +13 -5
- package/src/components/shadow-claw-pages/utils/buildHtmlPageSrcdoc.ts +13 -5
- package/src/core/control-plane-client.ts +15 -0
- package/src/core/utils/initControlPlane.test.ts +187 -0
- package/src/core/utils/initControlPlane.ts +194 -20
- package/src/security/custom-element-security.test.ts +51 -0
- package/src/security/custom-element-security.ts +33 -15
- package/src/server/control-plane-types.ts +1 -0
- package/src/server/control-plane.test.ts +69 -0
- package/src/server/control-plane.ts +45 -3
- package/src/server/mcp/tools/built-in-tools.ts +80 -5
- package/src/server/mcp/tools/client-tool-relay.ts +183 -26
- package/src/server/mcp/tools/mcp-tools.test.ts +140 -0
- package/src/server/middleware/static-files.test.ts +142 -0
- package/src/server/middleware/static-files.ts +66 -8
- package/src/testing/jest-setup.ts +1 -0
- package/src/worker/utils/handleMessage.ts +4 -1
- package/dist/lib/initControlPlane-CsO4UR6_.js.map +0 -1
- package/dist/lib/readGroupFileBytes-Bve-e5e_.js.map +0 -1
- package/dist/lib/shadow-claw-file-viewer-BfDHHgpA.js.map +0 -1
- package/dist/lib/shadow-claw-pages-D54jF1Qq.js.map +0 -1
- package/dist/lib/trusted-types-CkLDpLiZ.js.map +0 -1
- package/dist/public/custom-element-security-NCqQ5lmC.js +0 -1
- package/dist/public/downloadGroupFile-G0BZQgQg.js +0 -1
- package/dist/public/effect-rHYr4nfu.js +0 -1
- package/dist/public/file-viewer-8PdCURDD.js +0 -1
- package/dist/public/initControlPlane-CcGXax0A.js +0 -1
- package/dist/public/peerjs-BZdxWQFv.js +0 -1
- package/dist/public/syncWebMcpRegistration-DD42YsYV.js +0 -1
- package/dist/public/toast-HAq8XWFj.js +0 -58
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as e,r as t}from"./config-CrHchneq.js";import{n}from"./txPromise-EBECky1b.js";import{t as r}from"./getConfig-D89uJgo5.js";import{m as i,u as a}from"./custom-element-security-
|
|
1
|
+
import{b as e,r as t}from"./config-CrHchneq.js";import{n}from"./txPromise-EBECky1b.js";import{t as r}from"./getConfig-D89uJgo5.js";import{m as i,u as a}from"./custom-element-security-FU04Cq05.js";import{t as o}from"./orchestrator-DHjdLtqa.js";import{f as s,h as c}from"./mcp-reconnect-9emsqGRe.js";import{a as l,r as u}from"./toast-BXgUfbyh.js";import{t as d}from"./shadow-claw-element-DIrv3P6A.js";import"./shadow-claw-card-DCxWEHgX.js";import"./shadow-claw-empty-state-Bl52dGQ0.js";const f=new CSSStyleSheet;f.replaceSync(`*,
|
|
2
2
|
*::before,
|
|
3
3
|
*::after {
|
|
4
4
|
font-family: var(--shadow-claw-font-sans);
|
|
@@ -334,7 +334,7 @@ import{b as e,r as t}from"./config-CrHchneq.js";import{n}from"./txPromise-EBECky
|
|
|
334
334
|
<div class="account-list" data-region="account-list"></div>
|
|
335
335
|
</div>
|
|
336
336
|
</template>
|
|
337
|
-
`,`text/html`),m=p.querySelector(`template`);let h=[];h=m?Array.from(m.content.children):Array.from(p.head.children).concat(Array.from(p.body.children));var g=h;const _=`shadow-claw-git`,v=[`github`,`gitlab`,`azure_devops`];function y(e){if(e===`azure-devops`)return`azure_devops`;if(e===`github`||e===`gitlab`)return e}function b(e){return
|
|
337
|
+
`,`text/html`),m=p.querySelector(`template`);let h=[];h=m?Array.from(m.content.children):Array.from(p.head.children).concat(Array.from(p.body.children));var g=h;const _=`shadow-claw-git`,v=[`github`,`gitlab`,`azure_devops`];function y(e){if(e===`azure-devops`)return`azure_devops`;if(e===`github`||e===`gitlab`)return e}function b(e){return c(e)}var x=class extends d{static styles=f;static template=g;accounts=[];db=null;defaultAccountId=``;editingAccountId=null;pendingOauthResult=null;constructor(){super()}async connectedCallback(){if(!this.shadowRoot)throw Error(`shadowRoot not found`);this.db=await n(),await this.render(),this.bindEventListeners()}bindEventListeners(){let e=this.shadowRoot;e&&(e.querySelector(`[data-action="save-git-settings"]`)?.addEventListener(`click`,()=>this.saveGitSettings()),e.querySelectorAll(`input[name="git-proxy"]`).forEach(e=>{e.addEventListener(`change`,()=>{this.updateGitWarning(),this.updateCustomProxyVisibility()})}),e.querySelector(`[data-action="add-account"]`)?.addEventListener(`click`,()=>this.showAccountForm(`new`)),e.querySelector(`[data-region="account-list"]`)?.addEventListener(`settings-action`,e=>{let{action:t,id:n}=e.detail||{action:``,id:``};n&&(t===`edit-account`?this.showAccountForm(n):t===`delete-account`?this.deleteAccount(n):t===`set-default`&&this.setDefaultAccount(n))}))}hideAccountForm(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-region="account-form-slot"]`);t&&t.replaceChildren(),this.editingAccountId=null,this.pendingOauthResult=null}renderAccountList(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-region="account-list"]`);if(!t)return;if(t.replaceChildren(),this.accounts.length===0){let e=document.createElement(`shadow-claw-empty-state`);e.setAttribute(`message`,`No Git accounts configured.`),e.setAttribute(`hint`,`Click '+ Add Git Account' to get started.`),t.append(e);return}let n=document.createDocumentFragment();this.accounts.forEach(e=>{let t=e.id===this.defaultAccountId,r=!!e.token,i=!!e.username,a=b(e),o=r?a===`oauth`?e.oauthReauthRequired?`Reconnect required`:`OAuth token saved${e.oauthProviderId?` (${e.oauthProviderId})`:``}`:`Token (PAT)`:i?`Username: ${e.username}`:`No credentials`,s=`${e.hostPattern} · ${o}`,c=document.createElement(`shadow-claw-card`);c.setAttribute(`data-account-id`,e.id),c.setAttribute(`label`,e.label),c.setAttribute(`meta`,s),t&&(c.setAttribute(`highlight`,``),c.setAttribute(`badge`,`Default`));let l=document.createElement(`shadow-claw-actions`);l.setAttribute(`slot`,`actions`),l.setAttribute(`kind`,`account`),l.setAttribute(`item-id`,e.id),t&&l.setAttribute(`is-default`,``),c.append(l),n.append(c)}),t.append(n)}showAccountForm(t){let n=this.shadowRoot;if(!n)return;this.editingAccountId=t,this.pendingOauthResult=null;let r=t===`new`,o=r?null:this.accounts.find(e=>e.id===t),c=b(o||null),l=o?.oauthProviderId?o.oauthProviderId:y(s(o?.hostPattern||``)),u=l&&e[l]?l:`github`,d=o?.scopes?.join(` `)||``,f=v.filter(t=>!!e[t]).map(t=>{let n=e[t];return`<option value="${n.id}"${n.id===u?` selected`:``}>${i(n.name)}</option>`}).join(``),p=n.querySelector(`[data-region="account-form-slot"]`);p&&(a(p,`
|
|
338
338
|
<div class="account-form">
|
|
339
339
|
<h4>${r?`Add Git Account`:`Edit Account`}</h4>
|
|
340
340
|
|
|
@@ -359,8 +359,8 @@ import{b as e,r as t}from"./config-CrHchneq.js";import{n}from"./txPromise-EBECky
|
|
|
359
359
|
<div class="form-group">
|
|
360
360
|
<label class="form-label">Auth Mode</label>
|
|
361
361
|
<select class="form-input" data-field="acct-auth-mode">
|
|
362
|
-
<option value="token"${
|
|
363
|
-
<option value="oauth"${
|
|
362
|
+
<option value="token"${c===`token`?` selected`:``}>PAT / Username</option>
|
|
363
|
+
<option value="oauth"${c===`oauth`?` selected`:``}>OAuth</option>
|
|
364
364
|
</select>
|
|
365
365
|
<div class="form-helper">Use OAuth for provider-managed access tokens or PAT for manual Git credentials.</div>
|
|
366
366
|
</div>
|
|
@@ -395,7 +395,7 @@ import{b as e,r as t}from"./config-CrHchneq.js";import{n}from"./txPromise-EBECky
|
|
|
395
395
|
|
|
396
396
|
<div class="form-group oauth-connect-row">
|
|
397
397
|
<button class="confirm-btn oauth-connect-btn" data-action="connect-oauth" type="button">Connect OAuth</button>
|
|
398
|
-
<span class="oauth-status" data-region="oauth-status">${
|
|
398
|
+
<span class="oauth-status" data-region="oauth-status">${c===`oauth`&&o?.oauthReauthRequired?`Reconnect required`:c===`oauth`&&o?.token?`OAuth token already saved`:`Not connected`}</span>
|
|
399
399
|
</div>
|
|
400
400
|
</div>
|
|
401
401
|
|
|
@@ -444,4 +444,4 @@ import{b as e,r as t}from"./config-CrHchneq.js";import{n}from"./txPromise-EBECky
|
|
|
444
444
|
</button>
|
|
445
445
|
<button class="cancel-btn" data-action="cancel-account-form">Cancel</button>
|
|
446
446
|
</div>
|
|
447
|
-
</div>`),p.querySelector(`[data-action="save-account"]`)?.addEventListener(`click`,()=>this.saveAccountForm()),p.querySelector(`[data-action="cancel-account-form"]`)?.addEventListener(`click`,()=>this.hideAccountForm()),p.querySelector(`[data-field="acct-auth-mode"]`)?.addEventListener(`change`,()=>this.updateAuthModeVisibility(p)),p.querySelector(`[data-action="connect-oauth"]`)?.addEventListener(`click`,()=>void this.connectOAuthFromForm(p)),this.updateAuthModeVisibility(p))}updateAuthModeVisibility(e){let t=e.querySelector(`[data-field="acct-auth-mode"]`)?.value===`oauth`,n=e.querySelector(`[data-region="oauth-fields"]`),r=e.querySelector(`[data-region="pat-fields"]`);n instanceof HTMLElement&&(n.style.display=t?`block`:`none`),r instanceof HTMLElement&&(r.style.display=t?`none`:`block`)}updateCustomProxyVisibility(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="git-proxy-custom"]`),n=e.querySelector(`[data-region="git-custom-proxy-field"]`);n instanceof HTMLElement&&(n.style.display=t?.checked?`block`:`none`)}async connectOAuthFromForm(e){let t=e.querySelector(`[data-field="acct-oauth-provider"]`)?.value,n=e.querySelector(`[data-field="acct-oauth-client-id"]`)?.value.trim(),r=e.querySelector(`[data-field="acct-oauth-client-secret"]`)?.value.trim(),i=e.querySelector(`[data-field="acct-oauth-scope"]`)?.value.trim();if(!t){s(`OAuth provider is required.`,4e3);return}if(!n){s(`OAuth client ID is required.`,4e3);return}let a=e.querySelector(`[data-region="oauth-status"]`),c=e.querySelector(`[data-action="connect-oauth"]`);a&&(a.textContent=`Starting OAuth...`),c&&(c.disabled=!0);try{let e=i?i.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):void 0,s=await fetch(`/oauth/authorize`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({providerId:t,clientId:n,clientSecret:r||void 0,redirectUri:`${window.location.origin}/oauth/callback`,scope:e})}),c=await s.json();if(!s.ok||!c.state||!c.authorizeUrl)throw Error(c.error||`OAuth authorize failed`);window.open(c.authorizeUrl,`shadowclaw-oauth`,`popup=yes,width=540,height=720`);let l=c.state,u=`pending`;for(let e=0;e<60;e++){let e=await fetch(`/oauth/session/${encodeURIComponent(l)}`),t=await e.json();if(!e.ok)throw Error(t.error||`OAuth session not found`);if(u=t.status||`pending`,u===`authorized`)break;if(u===`error`)throw Error(t.error||`OAuth authorization failed`);await new Promise(e=>setTimeout(e,1e3))}if(u!==`authorized`)throw Error(`OAuth authorization timed out`);let d=await fetch(`/oauth/token`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({state:l})}),f=await d.json();if(!d.ok||!f.accessToken)throw Error(f.error||`OAuth token exchange failed`);this.pendingOauthResult={providerId:t,accessToken:f.accessToken,refreshToken:f.refreshToken,expiresAt:f.expiresIn?Date.now()+f.expiresIn*1e3:void 0,scope:f.scope,tokenType:f.tokenType},a&&(a.textContent=`OAuth connected`),o(`OAuth connected`,3e3)}catch(e){let t=e instanceof Error?e.message:String(e);a&&(a.textContent=`OAuth failed`),s(`OAuth connect failed: ${t}`,6e3)}finally{c&&(c.disabled=!1)}}async deleteAccount(e){if(this.db){this.accounts=this.accounts.filter(t=>t.id!==e),this.defaultAccountId===e&&(this.defaultAccountId=this.accounts[0]?.id||``);try{let{setConfig:e}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n);await e(this.db,t.GIT_ACCOUNTS,this.accounts),await e(this.db,t.GIT_DEFAULT_ACCOUNT,this.defaultAccountId)}catch(e){console.warn(`Error persisting account deletion:`,e)}this.renderAccountList(),this.updateGitWarning(),o(`Account deleted`,3e3)}}async migrateLegacyAccount(){if(!this.db)return;let e=await r(this.db,t.GIT_TOKEN),n=await r(this.db,t.GIT_USERNAME);if(!e&&!n)return;let i=await r(this.db,t.GIT_PASSWORD)||``,a={id:`legacy-migrated`,label:`GitHub`,hostPattern:`github.com`,token:e||``,username:n||``,password:i,authorName:``,authorEmail:``};this.accounts=[a],this.defaultAccountId=a.id;let{setConfig:o}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n);await o(this.db,t.GIT_ACCOUNTS,this.accounts),await o(this.db,t.GIT_DEFAULT_ACCOUNT,a.id)}async render(){let e=this.shadowRoot;if(e)try{let n=await r(this.db,t.GIT_CORS_PROXY)||`local`,i=e.querySelector(`[data-setting="git-proxy-local"]`),a=e.querySelector(`[data-setting="git-proxy-public"]`),o=e.querySelector(`[data-setting="git-proxy-custom"]`),s=e.querySelector(`[data-setting="git-proxy-url-input"]`);i&&a&&o&&(i.checked=n===`local`,a.checked=n===`public`,o.checked=n===`custom`),s&&(s.value=c.gitProxyUrl||`/git-proxy`),this.updateCustomProxyVisibility();let l=e.querySelector(`[data-setting="git-author-name-input"]`);l&&(l.value=await r(this.db,t.GIT_AUTHOR_NAME)||`ShadowClaw`);let u=e.querySelector(`[data-setting="git-author-email-input"]`);u&&(u.value=await r(this.db,t.GIT_AUTHOR_EMAIL)||`agent@example.com`);let d=await r(this.db,t.GIT_ACCOUNTS);this.accounts=Array.isArray(d)?d:[],this.defaultAccountId=await r(this.db,t.GIT_DEFAULT_ACCOUNT)||``,this.accounts.length===0&&await this.migrateLegacyAccount(),this.renderAccountList(),this.updateGitWarning()}catch(e){console.warn(`Could not load git settings:`,e)}}async saveAccountForm(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let n=e.querySelector(`[data-region="account-form-slot"]`);if(!n)return;let r=n.querySelector(`[data-field="acct-label"]`)?.value.trim(),i=n.querySelector(`[data-field="acct-host"]`)?.value.trim(),a=n.querySelector(`[data-field="acct-auth-mode"]`)?.value;if(!r||!i){s(`Label and Host Pattern are required.`,4e3);return}try{let{encryptValue:e}=await import(`./crypto-C8c5wMzN.js`).then(e=>e.t),{setConfig:c}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n),l=n.querySelector(`[data-field="acct-token"]`)?.value.trim(),u=n.querySelector(`[data-field="acct-password"]`)?.value.trim(),d=n.querySelector(`[data-field="acct-username"]`)?.value.trim()||``,f=n.querySelector(`[data-field="acct-author-name"]`)?.value.trim()||``,p=n.querySelector(`[data-field="acct-author-email"]`)?.value.trim()||``,m=this.editingAccountId===`new`,h=m?null:this.accounts.find(e=>e.id===this.editingAccountId),g=h?.token||``,_=h?.password||``,v=h?.oauthProviderId,y=h?.oauthClientId,b=h?.oauthClientSecret,x=h?.accessTokenExpiresAt,S=h?.refreshToken,C=h?.scopes,w=h?.tokenType,T=h?.oauthRefreshFailureCount,E=h?.oauthReauthRequired,D=h?.oauthReauthRequiredAt;if(a===`oauth`){v=n.querySelector(`[data-field="acct-oauth-provider"]`)?.value,y=n.querySelector(`[data-field="acct-oauth-client-id"]`)?.value.trim();let t=n.querySelector(`[data-field="acct-oauth-client-secret"]`)?.value.trim(),r=n.querySelector(`[data-field="acct-oauth-scope"]`)?.value.trim(),i=r?r.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):void 0;if(!v){s(`OAuth provider is required for OAuth mode.`,4e3);return}if(!y){s(`OAuth client ID is required for OAuth mode.`,4e3);return}if(t){let n=await e(t);n&&(b=n)}if(this.pendingOauthResult?.accessToken){let t=await e(this.pendingOauthResult.accessToken);if(t&&(g=t),this.pendingOauthResult.refreshToken){let t=await e(this.pendingOauthResult.refreshToken);t&&(S=t)}x=this.pendingOauthResult.expiresAt,C=this.pendingOauthResult.scope?this.pendingOauthResult.scope.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):i||C,w=this.pendingOauthResult.tokenType,T=0,E=!1,D=void 0}else C=i||C;if(!g){s(`Connect OAuth first to obtain an access token for this account.`,5e3);return}_=``}else{if(l){let t=await e(l);t&&(g=t)}if(u){let t=await e(u);t&&(_=t)}v=void 0,y=void 0,b=void 0,x=void 0,S=void 0,C=void 0,w=void 0,T=void 0,E=void 0,D=void 0}if(m){let{ulid:e}=await import(`./ulid-BY7rQVLN.js`).then(e=>e.n),n={id:e(),label:r,hostPattern:i,token:g,username:a===`oauth`?``:d,password:_,authorName:f,authorEmail:p,authMode:a||`token`,oauthProviderId:v,oauthClientId:y,oauthClientSecret:b,accessTokenExpiresAt:x,refreshToken:S,scopes:C,tokenType:w,oauthRefreshFailureCount:T,oauthReauthRequired:E,oauthReauthRequiredAt:D};this.accounts.push(n),this.accounts.length===1&&(this.defaultAccountId=n.id,await c(this.db,t.GIT_DEFAULT_ACCOUNT,n.id))}else h&&(h.label=r,h.hostPattern=i,h.token=g,h.username=a===`oauth`?``:d,h.password=_,h.authorName=f,h.authorEmail=p,h.authMode=a||`token`,h.oauthProviderId=v,h.oauthClientId=y,h.oauthClientSecret=b,h.accessTokenExpiresAt=x,h.refreshToken=S,h.scopes=C,h.tokenType=w,h.oauthRefreshFailureCount=T,h.oauthReauthRequired=E,h.oauthReauthRequiredAt=D);await c(this.db,t.GIT_ACCOUNTS,this.accounts),this.hideAccountForm(),this.renderAccountList(),this.updateGitWarning(),o(m?`Account added`:`Account updated`,3e3)}catch(e){s(`Error saving account: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveGitSettings(){if(!this.db)return;let e=this.shadowRoot;if(e)try{let{setConfig:n}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n),r=e.querySelector(`[data-setting="git-proxy-public"]`),i=e.querySelector(`[data-setting="git-proxy-custom"]`),a=r?.checked?`public`:i?.checked?`custom`:`local`;if(await n(this.db,t.GIT_CORS_PROXY,a),a===`custom`){let t=e.querySelector(`[data-setting="git-proxy-url-input"]`)?.value.trim()||`/git-proxy`,{orchestratorStore:n}=await import(`./orchestrator-D-xlXG92.js`).then(e=>e.n);await n.setGitProxyUrl(this.db,t)}let s=e.querySelector(`[data-setting="git-author-name-input"]`);s&&await n(this.db,t.GIT_AUTHOR_NAME,s.value.trim()||`ShadowClaw`);let c=e.querySelector(`[data-setting="git-author-email-input"]`);c&&await n(this.db,t.GIT_AUTHOR_EMAIL,c.value.trim()||`agent@example.com`),o(`Git settings saved`,3e3),this.updateGitWarning()}catch(e){s(`Error saving Git settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async setDefaultAccount(e){if(this.db){this.defaultAccountId=e;try{let{setConfig:n}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n);await n(this.db,t.GIT_DEFAULT_ACCOUNT,e)}catch(e){console.warn(`Error setting default account:`,e)}this.renderAccountList(),o(`Default account updated`,3e3)}}async updateGitWarning(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="git-proxy-warning"]`);if(!t)return;let n=e.querySelector(`[data-setting="git-proxy-public"]`),r=this.accounts.some(e=>!!e.token);t.style.display=n?.checked&&r?`block`:`none`}};customElements.get(_)||customElements.define(_,x);export{x as ShadowClawGit};
|
|
447
|
+
</div>`),p.querySelector(`[data-action="save-account"]`)?.addEventListener(`click`,()=>this.saveAccountForm()),p.querySelector(`[data-action="cancel-account-form"]`)?.addEventListener(`click`,()=>this.hideAccountForm()),p.querySelector(`[data-field="acct-auth-mode"]`)?.addEventListener(`change`,()=>this.updateAuthModeVisibility(p)),p.querySelector(`[data-action="connect-oauth"]`)?.addEventListener(`click`,()=>void this.connectOAuthFromForm(p)),this.updateAuthModeVisibility(p))}updateAuthModeVisibility(e){let t=e.querySelector(`[data-field="acct-auth-mode"]`)?.value===`oauth`,n=e.querySelector(`[data-region="oauth-fields"]`),r=e.querySelector(`[data-region="pat-fields"]`);n instanceof HTMLElement&&(n.style.display=t?`block`:`none`),r instanceof HTMLElement&&(r.style.display=t?`none`:`block`)}updateCustomProxyVisibility(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="git-proxy-custom"]`),n=e.querySelector(`[data-region="git-custom-proxy-field"]`);n instanceof HTMLElement&&(n.style.display=t?.checked?`block`:`none`)}async connectOAuthFromForm(e){let t=e.querySelector(`[data-field="acct-oauth-provider"]`)?.value,n=e.querySelector(`[data-field="acct-oauth-client-id"]`)?.value.trim(),r=e.querySelector(`[data-field="acct-oauth-client-secret"]`)?.value.trim(),i=e.querySelector(`[data-field="acct-oauth-scope"]`)?.value.trim();if(!t){u(`OAuth provider is required.`,4e3);return}if(!n){u(`OAuth client ID is required.`,4e3);return}let a=e.querySelector(`[data-region="oauth-status"]`),o=e.querySelector(`[data-action="connect-oauth"]`);a&&(a.textContent=`Starting OAuth...`),o&&(o.disabled=!0);try{let e=i?i.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):void 0,o=await fetch(`/oauth/authorize`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({providerId:t,clientId:n,clientSecret:r||void 0,redirectUri:`${window.location.origin}/oauth/callback`,scope:e})}),s=await o.json();if(!o.ok||!s.state||!s.authorizeUrl)throw Error(s.error||`OAuth authorize failed`);window.open(s.authorizeUrl,`shadowclaw-oauth`,`popup=yes,width=540,height=720`);let c=s.state,u=`pending`;for(let e=0;e<60;e++){let e=await fetch(`/oauth/session/${encodeURIComponent(c)}`),t=await e.json();if(!e.ok)throw Error(t.error||`OAuth session not found`);if(u=t.status||`pending`,u===`authorized`)break;if(u===`error`)throw Error(t.error||`OAuth authorization failed`);await new Promise(e=>setTimeout(e,1e3))}if(u!==`authorized`)throw Error(`OAuth authorization timed out`);let d=await fetch(`/oauth/token`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({state:c})}),f=await d.json();if(!d.ok||!f.accessToken)throw Error(f.error||`OAuth token exchange failed`);this.pendingOauthResult={providerId:t,accessToken:f.accessToken,refreshToken:f.refreshToken,expiresAt:f.expiresIn?Date.now()+f.expiresIn*1e3:void 0,scope:f.scope,tokenType:f.tokenType},a&&(a.textContent=`OAuth connected`),l(`OAuth connected`,3e3)}catch(e){let t=e instanceof Error?e.message:String(e);a&&(a.textContent=`OAuth failed`),u(`OAuth connect failed: ${t}`,6e3)}finally{o&&(o.disabled=!1)}}async deleteAccount(e){if(this.db){this.accounts=this.accounts.filter(t=>t.id!==e),this.defaultAccountId===e&&(this.defaultAccountId=this.accounts[0]?.id||``);try{let{setConfig:e}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n);await e(this.db,t.GIT_ACCOUNTS,this.accounts),await e(this.db,t.GIT_DEFAULT_ACCOUNT,this.defaultAccountId)}catch(e){console.warn(`Error persisting account deletion:`,e)}this.renderAccountList(),this.updateGitWarning(),l(`Account deleted`,3e3)}}async migrateLegacyAccount(){if(!this.db)return;let e=await r(this.db,t.GIT_TOKEN),n=await r(this.db,t.GIT_USERNAME);if(!e&&!n)return;let i=await r(this.db,t.GIT_PASSWORD)||``,a={id:`legacy-migrated`,label:`GitHub`,hostPattern:`github.com`,token:e||``,username:n||``,password:i,authorName:``,authorEmail:``};this.accounts=[a],this.defaultAccountId=a.id;let{setConfig:o}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n);await o(this.db,t.GIT_ACCOUNTS,this.accounts),await o(this.db,t.GIT_DEFAULT_ACCOUNT,a.id)}async render(){let e=this.shadowRoot;if(e)try{let n=await r(this.db,t.GIT_CORS_PROXY)||`local`,i=e.querySelector(`[data-setting="git-proxy-local"]`),a=e.querySelector(`[data-setting="git-proxy-public"]`),s=e.querySelector(`[data-setting="git-proxy-custom"]`),c=e.querySelector(`[data-setting="git-proxy-url-input"]`);i&&a&&s&&(i.checked=n===`local`,a.checked=n===`public`,s.checked=n===`custom`),c&&(c.value=o.gitProxyUrl||`/git-proxy`),this.updateCustomProxyVisibility();let l=e.querySelector(`[data-setting="git-author-name-input"]`);l&&(l.value=await r(this.db,t.GIT_AUTHOR_NAME)||`ShadowClaw`);let u=e.querySelector(`[data-setting="git-author-email-input"]`);u&&(u.value=await r(this.db,t.GIT_AUTHOR_EMAIL)||`agent@example.com`);let d=await r(this.db,t.GIT_ACCOUNTS);this.accounts=Array.isArray(d)?d:[],this.defaultAccountId=await r(this.db,t.GIT_DEFAULT_ACCOUNT)||``,this.accounts.length===0&&await this.migrateLegacyAccount(),this.renderAccountList(),this.updateGitWarning()}catch(e){console.warn(`Could not load git settings:`,e)}}async saveAccountForm(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let n=e.querySelector(`[data-region="account-form-slot"]`);if(!n)return;let r=n.querySelector(`[data-field="acct-label"]`)?.value.trim(),i=n.querySelector(`[data-field="acct-host"]`)?.value.trim(),a=n.querySelector(`[data-field="acct-auth-mode"]`)?.value;if(!r||!i){u(`Label and Host Pattern are required.`,4e3);return}try{let{encryptValue:e}=await import(`./crypto-C8c5wMzN.js`).then(e=>e.t),{setConfig:o}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n),s=n.querySelector(`[data-field="acct-token"]`)?.value.trim(),c=n.querySelector(`[data-field="acct-password"]`)?.value.trim(),d=n.querySelector(`[data-field="acct-username"]`)?.value.trim()||``,f=n.querySelector(`[data-field="acct-author-name"]`)?.value.trim()||``,p=n.querySelector(`[data-field="acct-author-email"]`)?.value.trim()||``,m=this.editingAccountId===`new`,h=m?null:this.accounts.find(e=>e.id===this.editingAccountId),g=h?.token||``,_=h?.password||``,v=h?.oauthProviderId,y=h?.oauthClientId,b=h?.oauthClientSecret,x=h?.accessTokenExpiresAt,S=h?.refreshToken,C=h?.scopes,w=h?.tokenType,T=h?.oauthRefreshFailureCount,E=h?.oauthReauthRequired,D=h?.oauthReauthRequiredAt;if(a===`oauth`){v=n.querySelector(`[data-field="acct-oauth-provider"]`)?.value,y=n.querySelector(`[data-field="acct-oauth-client-id"]`)?.value.trim();let t=n.querySelector(`[data-field="acct-oauth-client-secret"]`)?.value.trim(),r=n.querySelector(`[data-field="acct-oauth-scope"]`)?.value.trim(),i=r?r.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):void 0;if(!v){u(`OAuth provider is required for OAuth mode.`,4e3);return}if(!y){u(`OAuth client ID is required for OAuth mode.`,4e3);return}if(t){let n=await e(t);n&&(b=n)}if(this.pendingOauthResult?.accessToken){let t=await e(this.pendingOauthResult.accessToken);if(t&&(g=t),this.pendingOauthResult.refreshToken){let t=await e(this.pendingOauthResult.refreshToken);t&&(S=t)}x=this.pendingOauthResult.expiresAt,C=this.pendingOauthResult.scope?this.pendingOauthResult.scope.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):i||C,w=this.pendingOauthResult.tokenType,T=0,E=!1,D=void 0}else C=i||C;if(!g){u(`Connect OAuth first to obtain an access token for this account.`,5e3);return}_=``}else{if(s){let t=await e(s);t&&(g=t)}if(c){let t=await e(c);t&&(_=t)}v=void 0,y=void 0,b=void 0,x=void 0,S=void 0,C=void 0,w=void 0,T=void 0,E=void 0,D=void 0}if(m){let{ulid:e}=await import(`./ulid-BY7rQVLN.js`).then(e=>e.n),n={id:e(),label:r,hostPattern:i,token:g,username:a===`oauth`?``:d,password:_,authorName:f,authorEmail:p,authMode:a||`token`,oauthProviderId:v,oauthClientId:y,oauthClientSecret:b,accessTokenExpiresAt:x,refreshToken:S,scopes:C,tokenType:w,oauthRefreshFailureCount:T,oauthReauthRequired:E,oauthReauthRequiredAt:D};this.accounts.push(n),this.accounts.length===1&&(this.defaultAccountId=n.id,await o(this.db,t.GIT_DEFAULT_ACCOUNT,n.id))}else h&&(h.label=r,h.hostPattern=i,h.token=g,h.username=a===`oauth`?``:d,h.password=_,h.authorName=f,h.authorEmail=p,h.authMode=a||`token`,h.oauthProviderId=v,h.oauthClientId=y,h.oauthClientSecret=b,h.accessTokenExpiresAt=x,h.refreshToken=S,h.scopes=C,h.tokenType=w,h.oauthRefreshFailureCount=T,h.oauthReauthRequired=E,h.oauthReauthRequiredAt=D);await o(this.db,t.GIT_ACCOUNTS,this.accounts),this.hideAccountForm(),this.renderAccountList(),this.updateGitWarning(),l(m?`Account added`:`Account updated`,3e3)}catch(e){u(`Error saving account: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveGitSettings(){if(!this.db)return;let e=this.shadowRoot;if(e)try{let{setConfig:n}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n),r=e.querySelector(`[data-setting="git-proxy-public"]`),i=e.querySelector(`[data-setting="git-proxy-custom"]`),a=r?.checked?`public`:i?.checked?`custom`:`local`;if(await n(this.db,t.GIT_CORS_PROXY,a),a===`custom`){let t=e.querySelector(`[data-setting="git-proxy-url-input"]`)?.value.trim()||`/git-proxy`,{orchestratorStore:n}=await import(`./orchestrator-DHjdLtqa.js`).then(e=>e.n);await n.setGitProxyUrl(this.db,t)}let o=e.querySelector(`[data-setting="git-author-name-input"]`);o&&await n(this.db,t.GIT_AUTHOR_NAME,o.value.trim()||`ShadowClaw`);let s=e.querySelector(`[data-setting="git-author-email-input"]`);s&&await n(this.db,t.GIT_AUTHOR_EMAIL,s.value.trim()||`agent@example.com`),l(`Git settings saved`,3e3),this.updateGitWarning()}catch(e){u(`Error saving Git settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async setDefaultAccount(e){if(this.db){this.defaultAccountId=e;try{let{setConfig:n}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n);await n(this.db,t.GIT_DEFAULT_ACCOUNT,e)}catch(e){console.warn(`Error setting default account:`,e)}this.renderAccountList(),l(`Default account updated`,3e3)}}async updateGitWarning(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="git-proxy-warning"]`);if(!t)return;let n=e.querySelector(`[data-setting="git-proxy-public"]`),r=this.accounts.some(e=>!!e.token);t.style.display=n?.checked&&r?`block`:`none`}};customElements.get(_)||customElements.define(_,x);export{x as ShadowClawGit};
|
package/dist/public/{shadow-claw-integrations-82UoFuDR.js → shadow-claw-integrations-BBVnO0Fc.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b.js";import{t as n}from"./getConfig-D89uJgo5.js";import{u as r}from"./custom-element-security-
|
|
1
|
+
import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b.js";import{t as n}from"./getConfig-D89uJgo5.js";import{u as r}from"./custom-element-security-FU04Cq05.js";import{t as i}from"./setConfig-DFMYnYLE.js";import{t as a}from"./ulid-BY7rQVLN.js";import{r as o}from"./crypto-C8c5wMzN.js";import{a as s,i as c,n as l,o as u,s as d,t as f}from"./connections-DvbgdkaB.js";import{a as p,r as m}from"./toast-BXgUfbyh.js";import{t as h}from"./shadow-claw-element-DIrv3P6A.js";function g(e){if(e.authMode===`oauth`){let t=(e.pendingOauthAccessToken||``).trim();return t?{authType:`oauth`,accessToken:t}:{error:`OAuth access token is missing. Click Connect OAuth first (or save and reconnect).`}}let t=(e.passwordInput||``).trim();return t?{authType:`basic_userpass`,password:t}:{error:`Password/app password is missing. Enter it to test this connection.`}}const _=new CSSStyleSheet;_.replaceSync(`*,
|
|
2
2
|
*::before,
|
|
3
3
|
*::after {
|
|
4
4
|
font-family: var(--shadow-claw-font-sans);
|
|
@@ -283,7 +283,7 @@ import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b
|
|
|
283
283
|
<div class="connection-list" data-region="connection-list"></div>
|
|
284
284
|
</div>
|
|
285
285
|
</template>
|
|
286
|
-
`,`text/html`),y=v.querySelector(`template`);let b=[];b=y?Array.from(y.content.children):Array.from(v.head.children).concat(Array.from(v.body.children));var x=b;const S=`shadow-claw-integrations`,C={google:{id:`google`,label:`Gmail (Google OAuth)`,serviceName:`Google`,hostPattern:`gmail.com`,defaultScopes:[`https://mail.google.com/`],scopePlaceholder:`https://mail.google.com/`,scopeHelpText:`Use https://mail.google.com/ for Gmail IMAP/SMTP access.`,connectButtonLabel:`Connect Google OAuth`},microsoft_graph:{id:`microsoft_graph`,label:`Microsoft (Outlook / M365 OAuth)`,serviceName:`Microsoft`,hostPattern:`outlook.office365.com`,defaultScopes:[`offline_access`,`https://outlook.office.com/IMAP.AccessAsUser.All`,`https://outlook.office.com/SMTP.Send`],scopePlaceholder:`offline_access https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send`,scopeHelpText:`For Outlook/M365 IMAP+SMTP, include offline_access plus IMAP.AccessAsUser.All and SMTP.Send scopes.`,connectButtonLabel:`Connect Microsoft OAuth`},yahoo_mail:{id:`yahoo_mail`,label:`Yahoo Mail OAuth`,serviceName:`Yahoo`,hostPattern:`mail.yahoo.com`,defaultScopes:[`mail-r`,`mail-w`],scopePlaceholder:`mail-r mail-w`,scopeHelpText:`Yahoo commonly uses mail-r and mail-w scopes for IMAP/SMTP style access.`,connectButtonLabel:`Connect Yahoo OAuth`}},w={gmail:{imapHost:`imap.gmail.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.gmail.com`,smtpPort:465,smtpSecure:!0},outlook:{imapHost:`outlook.office365.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.office365.com`,smtpPort:587,smtpSecure:!1},yahoo:{imapHost:`imap.mail.yahoo.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.mail.yahoo.com`,smtpPort:465,smtpSecure:!0},icloud:{imapHost:`imap.mail.me.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.mail.me.com`,smtpPort:587,smtpSecure:!1},fastmail:{imapHost:`imap.fastmail.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.fastmail.com`,smtpPort:465,smtpSecure:!0}},T={host:`IMAP host`,port:`IMAP port`,secure:`IMAP TLS`,mailboxPath:`Mailbox path`,smtpHost:`SMTP host`,smtpPort:`SMTP port`,smtpSecure:`SMTP TLS`,fromAddress:`From address`,executionMode:`Execution mode`,pollIntervalSec:`Poll interval (seconds)`},E={host:`imap.example.com`,port:`993`,mailboxPath:`INBOX`,smtpHost:`smtp.example.com`,smtpPort:`465`,fromAddress:`you@example.com`,pollIntervalSec:`300`};var D=class extends h{static styles=_;static template=x;accounts=[];connections=[];db=null;editingConnectionId=null;manifests=[];pendingOauthResult=null;async connectedCallback(){this.db=await t(),this.bindEventListeners(),await this.reload()}applyImapPreset(e){let t=e.querySelector(`#int-imap-preset`),n=e.querySelector(`#int-username`),r=t?.value||`auto`,
|
|
286
|
+
`,`text/html`),y=v.querySelector(`template`);let b=[];b=y?Array.from(y.content.children):Array.from(v.head.children).concat(Array.from(v.body.children));var x=b;const S=`shadow-claw-integrations`,C={google:{id:`google`,label:`Gmail (Google OAuth)`,serviceName:`Google`,hostPattern:`gmail.com`,defaultScopes:[`https://mail.google.com/`],scopePlaceholder:`https://mail.google.com/`,scopeHelpText:`Use https://mail.google.com/ for Gmail IMAP/SMTP access.`,connectButtonLabel:`Connect Google OAuth`},microsoft_graph:{id:`microsoft_graph`,label:`Microsoft (Outlook / M365 OAuth)`,serviceName:`Microsoft`,hostPattern:`outlook.office365.com`,defaultScopes:[`offline_access`,`https://outlook.office.com/IMAP.AccessAsUser.All`,`https://outlook.office.com/SMTP.Send`],scopePlaceholder:`offline_access https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send`,scopeHelpText:`For Outlook/M365 IMAP+SMTP, include offline_access plus IMAP.AccessAsUser.All and SMTP.Send scopes.`,connectButtonLabel:`Connect Microsoft OAuth`},yahoo_mail:{id:`yahoo_mail`,label:`Yahoo Mail OAuth`,serviceName:`Yahoo`,hostPattern:`mail.yahoo.com`,defaultScopes:[`mail-r`,`mail-w`],scopePlaceholder:`mail-r mail-w`,scopeHelpText:`Yahoo commonly uses mail-r and mail-w scopes for IMAP/SMTP style access.`,connectButtonLabel:`Connect Yahoo OAuth`}},w={gmail:{imapHost:`imap.gmail.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.gmail.com`,smtpPort:465,smtpSecure:!0},outlook:{imapHost:`outlook.office365.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.office365.com`,smtpPort:587,smtpSecure:!1},yahoo:{imapHost:`imap.mail.yahoo.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.mail.yahoo.com`,smtpPort:465,smtpSecure:!0},icloud:{imapHost:`imap.mail.me.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.mail.me.com`,smtpPort:587,smtpSecure:!1},fastmail:{imapHost:`imap.fastmail.com`,imapPort:993,imapSecure:!0,smtpHost:`smtp.fastmail.com`,smtpPort:465,smtpSecure:!0}},T={host:`IMAP host`,port:`IMAP port`,secure:`IMAP TLS`,mailboxPath:`Mailbox path`,smtpHost:`SMTP host`,smtpPort:`SMTP port`,smtpSecure:`SMTP TLS`,fromAddress:`From address`,executionMode:`Execution mode`,pollIntervalSec:`Poll interval (seconds)`},E={host:`imap.example.com`,port:`993`,mailboxPath:`INBOX`,smtpHost:`smtp.example.com`,smtpPort:`465`,fromAddress:`you@example.com`,pollIntervalSec:`300`};var D=class extends h{static styles=_;static template=x;accounts=[];connections=[];db=null;editingConnectionId=null;manifests=[];pendingOauthResult=null;async connectedCallback(){this.db=await t(),this.bindEventListeners(),await this.reload()}applyImapPreset(e){let t=e.querySelector(`#int-imap-preset`),n=e.querySelector(`#int-username`),r=t?.value||`auto`,i=this.resolveImapPreset(r,n?.value||``);if(!i){m(`Could not auto-detect IMAP settings from this email domain. Choose a preset or enter settings manually.`,5e3);return}this.setConfigFieldValue(e,`host`,i.imapHost),this.setConfigFieldValue(e,`port`,String(i.imapPort)),this.setConfigFieldValue(e,`secure`,String(i.imapSecure)),this.setConfigFieldValue(e,`smtpHost`,i.smtpHost),this.setConfigFieldValue(e,`smtpPort`,String(i.smtpPort)),this.setConfigFieldValue(e,`smtpSecure`,String(i.smtpSecure));let a=(n?.value||``).trim();a&&this.setConfigFieldValue(e,`fromAddress`,a);let o=e.querySelector(`#cfg-mailboxPath`);o&&!o.value.trim()&&(o.value=`INBOX`),p(`Applied IMAP preset defaults`,2500)}bindEventListeners(){let e=this.shadowRoot;e&&e.querySelector(`[data-action="add-connection"]`)?.addEventListener(`click`,()=>this.showForm(null))}escapeHtml(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/\"/g,`"`).replace(/'/g,`'`)}getEmailOAuthProvider(e){return e&&C[e]?C[e]:C.google}getInitialPluginId(e){return e?.pluginId?e.pluginId:this.manifests.some(e=>e.id===`imap`)?`imap`:this.manifests[0]?.id||``}renderConfigFieldRows(e,t){return e.configurableFields.map(n=>{let r=t[n],i=e.id===`imap`?T[n]??n:n;if(n===`secure`||n===`smtpSecure`){let e=typeof r!=`boolean`||r;return`
|
|
287
287
|
<div class="form-row">
|
|
288
288
|
<label for="cfg-${this.escapeHtml(n)}">${this.escapeHtml(i)}</label>
|
|
289
289
|
<select id="cfg-${this.escapeHtml(n)}" data-config-field="${this.escapeHtml(n)}">
|
|
@@ -301,7 +301,7 @@ import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b
|
|
|
301
301
|
placeholder="${this.escapeHtml(a)}"
|
|
302
302
|
/>
|
|
303
303
|
</div>
|
|
304
|
-
`}).join(``)}renderConnectionList(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-region="connection-list"]`);if(!t)return;if(t.replaceChildren(),!this.connections.length){let e=document.createElement(`div`);e.className=`empty`,e.textContent=`No email connections configured. Click Add Email Connection to start.`,t.append(e);return}let n=document.createDocumentFragment();for(let e of this.connections){let t=
|
|
304
|
+
`}).join(``)}renderConnectionList(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-region="connection-list"]`);if(!t)return;if(t.replaceChildren(),!this.connections.length){let e=document.createElement(`div`);e.className=`empty`,e.textContent=`No email connections configured. Click Add Email Connection to start.`,t.append(e);return}let n=document.createDocumentFragment();for(let e of this.connections){let t=u(e.pluginId),i=document.createElement(`article`);i.className=`connection-card`;let a=typeof e.config.executionMode==`string`?e.config.executionMode:`manual`,o=typeof e.config.pollIntervalSec==`number`?e.config.pollIntervalSec:null,s=!!e.credentialRef?.encryptedSecret||e.credentialRef?.authType===`oauth`&&!!e.credentialRef?.accountId;r(i,`
|
|
305
305
|
<header>
|
|
306
306
|
<div>
|
|
307
307
|
<div class="connection-title">${this.escapeHtml(e.label)}</div>
|
|
@@ -319,7 +319,7 @@ import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b
|
|
|
319
319
|
<button class="btn secondary" data-action="toggle" data-id="${this.escapeHtml(e.id)}">${e.enabled?`Disable`:`Enable`}</button>
|
|
320
320
|
<button class="btn secondary" data-action="delete" data-id="${this.escapeHtml(e.id)}">Delete</button>
|
|
321
321
|
</div>
|
|
322
|
-
`),i.querySelectorAll(`button[data-action]`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.dataset.action,n=e.dataset.id;!t||!n||(t===`edit`?this.showForm(n):t===`toggle`?this.toggleConnection(n):t===`delete`&&this.deleteConnection(n))})}),n.append(i)}t.append(n)}resolveImapPreset(e,t){if(e!==`auto`)return w[e]||null;let n=t.split(`@`)[1]?.trim().toLowerCase()||``;return n?n===`gmail.com`||n.endsWith(`.gmail.com`)||n.endsWith(`.googlemail.com`)?w.gmail:n===`outlook.com`||n===`hotmail.com`||n===`live.com`||n===`msn.com`||n.endsWith(`.onmicrosoft.com`)?w.outlook:n===`yahoo.com`||n.endsWith(`.yahoo.com`)?w.yahoo:n===`icloud.com`||n===`me.com`||n===`mac.com`?w.icloud:n===`fastmail.com`||n.endsWith(`.fastmail.com`)?w.fastmail:null:null}setConfigFieldValue(e,t,n){let r=e.querySelector(`#cfg-${t}`);r&&(r.value=n)}showForm(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-region="connection-form"]`);if(!n)return;this.editingConnectionId=e;let i=e&&this.connections.find(t=>t.id===e)||null,a=this.getInitialPluginId(i),o=
|
|
322
|
+
`),i.querySelectorAll(`button[data-action]`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.dataset.action,n=e.dataset.id;!t||!n||(t===`edit`?this.showForm(n):t===`toggle`?this.toggleConnection(n):t===`delete`&&this.deleteConnection(n))})}),n.append(i)}t.append(n)}resolveImapPreset(e,t){if(e!==`auto`)return w[e]||null;let n=t.split(`@`)[1]?.trim().toLowerCase()||``;return n?n===`gmail.com`||n.endsWith(`.gmail.com`)||n.endsWith(`.googlemail.com`)?w.gmail:n===`outlook.com`||n===`hotmail.com`||n===`live.com`||n===`msn.com`||n.endsWith(`.onmicrosoft.com`)?w.outlook:n===`yahoo.com`||n.endsWith(`.yahoo.com`)?w.yahoo:n===`icloud.com`||n===`me.com`||n===`mac.com`?w.icloud:n===`fastmail.com`||n.endsWith(`.fastmail.com`)?w.fastmail:null:null}setConfigFieldValue(e,t,n){let r=e.querySelector(`#cfg-${t}`);r&&(r.value=n)}showForm(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-region="connection-form"]`);if(!n)return;this.editingConnectionId=e;let i=e&&this.connections.find(t=>t.id===e)||null,a=this.getInitialPluginId(i),o=u(a),s=i?.config||{},c=i?.credentialRef?.accountId&&this.accounts.find(e=>e.id===i.credentialRef?.accountId)||null,l=typeof s.executionMode==`string`?String(s.executionMode):`manual`,d=typeof s.pollIntervalSec==`number`?s.pollIntervalSec:300,f=i?.credentialRef?.authType===`oauth`?`oauth`:`basic_userpass`,p=i?.credentialRef?.providerId||c?.oauthProviderId||`google`,m=this.getEmailOAuthProvider(p),h=c?.oauthClientId||``,g=c?.scopes?.join(` `)||m.defaultScopes.join(` `),_=f===`oauth`?c?.oauthReauthRequired?`Reconnect required`:c?.token?`OAuth token already saved`:`Not connected`:`Not connected`,v=a===`imap`;r(n,`
|
|
323
323
|
<h4>${i?`Edit Email Connection`:`Add Email Connection`}</h4>
|
|
324
324
|
<div class="form-row">
|
|
325
325
|
<label for="int-label">Label</label>
|
|
@@ -335,7 +335,7 @@ import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b
|
|
|
335
335
|
</div>
|
|
336
336
|
<div class="form-row">
|
|
337
337
|
<label for="int-poll">Poll interval (seconds)</label>
|
|
338
|
-
<input id="int-poll" type="number" min="5" value="${this.escapeHtml(String(
|
|
338
|
+
<input id="int-poll" type="number" min="5" value="${this.escapeHtml(String(d))}" />
|
|
339
339
|
</div>
|
|
340
340
|
<div class="form-row checkbox-row">
|
|
341
341
|
<label class="checkbox-inline" for="int-unread-only">
|
|
@@ -350,8 +350,8 @@ import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b
|
|
|
350
350
|
<div class="form-row">
|
|
351
351
|
<label for="int-auth-mode">Authentication</label>
|
|
352
352
|
<select id="int-auth-mode">
|
|
353
|
-
<option value="basic_userpass" ${
|
|
354
|
-
<option value="oauth" ${
|
|
353
|
+
<option value="basic_userpass" ${f===`basic_userpass`?`selected`:``}>App password / password</option>
|
|
354
|
+
<option value="oauth" ${f===`oauth`?`selected`:``}>OAuth</option>
|
|
355
355
|
</select>
|
|
356
356
|
</div>
|
|
357
357
|
<div data-region="password-auth-fields">
|
|
@@ -413,4 +413,4 @@ import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b
|
|
|
413
413
|
<button class="btn secondary" data-action="test-connection">Test Connection</button>
|
|
414
414
|
<button class="btn" data-action="save">Save</button>
|
|
415
415
|
</div>
|
|
416
|
-
`);let y=n;y.hidden=!1,this.pendingOauthResult=null,n.querySelector(`#int-auth-mode`)?.addEventListener(`change`,()=>this.updateAuthModeVisibility(n)),n.querySelector(`[data-action="imap-autofill"]`)?.addEventListener(`click`,()=>this.applyImapPreset(n)),n.querySelector(`[data-action="connect-oauth"]`)?.addEventListener(`click`,()=>void this.connectOAuthFromForm(n)),n.querySelector(`#int-oauth-provider`)?.addEventListener(`change`,()=>this.updateOAuthProviderHelp(n)),n.querySelector(`[data-action="cancel"]`)?.addEventListener(`click`,()=>{y.hidden=!0,y.replaceChildren(),this.editingConnectionId=null}),n.querySelector(`[data-action="save"]`)?.addEventListener(`click`,()=>{this.saveForm()}),n.querySelector(`[data-action="test-connection"]`)?.addEventListener(`click`,()=>{this.testConnectionFromForm(n)}),this.updateAuthModeVisibility(n),this.updateOAuthProviderHelp(n)}updateAuthModeVisibility(e){let t=e.querySelector(`#int-auth-mode`)?.value,n=e.querySelector(`[data-region="password-auth-fields"]`),r=e.querySelector(`[data-region="oauth-auth-fields"]`);n&&(n.style.display=t===`oauth`?`none`:`block`),r&&(r.style.display=t===`oauth`?`block`:`none`)}updateOAuthProviderHelp(e){let t=e.querySelector(`#int-oauth-provider`)?.value,n=this.getEmailOAuthProvider(t),r=e.querySelector(`#int-oauth-scope`),i=e.querySelector(`[data-region="oauth-scope-help"]`),a=e.querySelector(`[data-action="connect-oauth"]`);r&&(r.placeholder=n.scopePlaceholder,r.value.trim()||(r.value=n.defaultScopes.join(` `))),i&&(i.textContent=n.scopeHelpText),a&&(a.textContent=n.connectButtonLabel)}async buildCredentialRef(e,t){let n=e.querySelector(`#int-auth-mode`)?.value,r=e.querySelector(`#int-username`),i=e.querySelector(`#int-password`),a=r?.value.trim()||``,o=i?.value.trim()||``,s=this.connections.find(e=>e.id===t.id);if(n===`oauth`){if(!a)throw Error(`Email login address is required for OAuth authentication.`);let n=await this.upsertLinkedOAuthAccount(e,t);return{serviceType:`http_api`,authType:`oauth`,providerId:n.oauthProviderId||`google`,accountId:n.id,username:a}}let l;if(o){if(l=await c(o)||void 0,!l)throw Error(`Could not encrypt email password.`)}else l=s?.credentialRef?.encryptedSecret;if(!a&&!l)return null;if(!a)throw Error(`Auth username is required when a password is configured.`);if(!l)throw Error(`Auth password is required when username is configured.`);return{serviceType:`http_api`,authType:`basic_userpass`,username:a,encryptedSecret:l}}async connectOAuthFromForm(e){let t=e.querySelector(`#int-oauth-provider`)?.value,n=this.getEmailOAuthProvider(t),r=e.querySelector(`#int-oauth-client-id`)?.value.trim(),o=e.querySelector(`#int-oauth-client-secret`)?.value.trim(),s=e.querySelector(`#int-oauth-scope`)?.value.trim(),c=e.querySelector(`[data-region="oauth-status"]`),l=e.querySelector(`[data-action="connect-oauth"]`);if(!r){a(`OAuth client ID is required.`,4e3);return}c&&(c.textContent=`Starting OAuth...`),l&&(l.disabled=!0);try{let e=s?s.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):n.defaultScopes,t=`${window.location.origin}/oauth/callback`,a=await fetch(`/oauth/authorize`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({providerId:n.id,clientId:r,clientSecret:o||void 0,redirectUri:t,scope:e,extraAuthorizeParams:{access_type:`offline`,prompt:`consent`}})}),l=await a.json();if(!a.ok||!l.state||!l.authorizeUrl)throw Error(l.error||`OAuth authorize failed`);window.open(l.authorizeUrl,`shadowclaw-google-oauth`,`popup=yes,width=540,height=720`);let u=l.state,d=`pending`;for(let e=0;e<60;e++){let e=await fetch(`/oauth/session/${encodeURIComponent(u)}`),t=await e.json();if(!e.ok)throw Error(t.error||`OAuth session not found`);if(d=t.status||`pending`,d===`authorized`)break;if(d===`error`)throw Error(t.error||`OAuth authorization failed`);await new Promise(e=>setTimeout(e,1e3))}if(d!==`authorized`)throw Error(`OAuth authorization timed out`);let f=await fetch(`/oauth/token`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({state:u})}),p=await f.json();if(!f.ok||!p.accessToken)throw Error(p.error||`OAuth token exchange failed`);this.pendingOauthResult={providerId:n.id,accessToken:p.accessToken,refreshToken:p.refreshToken,expiresAt:p.expiresIn?Date.now()+p.expiresIn*1e3:void 0,scope:p.scope,tokenType:p.tokenType},c&&(c.textContent=`OAuth connected`),i(`${n.label} connected`,3e3)}catch(e){let t=e instanceof Error?e.message:String(e);c&&(c.textContent=`OAuth failed`),a(`${n.label} connect failed: ${t}`,6e3)}finally{l&&(l.disabled=!1)}}async deleteConnection(e){if(!this.db)return;let t=this.connections.find(t=>t.id===e);if(t&&await this.requestConfirmation({title:`Delete Email Connection`,message:`Delete email connection \"${t.label}\"?`,confirmLabel:`Delete`,cancelLabel:`Cancel`}))try{if(!await d(this.db,e)){a(`Failed to delete email connection.`,5e3);return}i(`Email connection deleted`,2500),await this.reload()}catch(e){a(`Failed to delete email connection: ${e instanceof Error?e.message:String(e)}`,6e3)}}async reload(){if(!this.db)return;this.manifests=p().filter(e=>e.id===`imap`),this.connections=await u(this.db);let t=await n(this.db,e.SERVICE_ACCOUNTS);this.accounts=Array.isArray(t)?t:[],this.renderConnectionList()}async requestConfirmation(e){let t=document.querySelector(`shadow-claw`);return t&&typeof t.requestDialog==`function`?await t.requestDialog({mode:`confirm`,...e}):!1}async saveForm(){let e=this.shadowRoot;if(!e||!this.db)return;let t=e.querySelector(`[data-region="connection-form"]`);if(!t)return;let n=t.querySelector(`#int-label`),r=t.querySelector(`#int-mode`),o=t.querySelector(`#int-poll`),s=t.querySelector(`#int-extra-config`);if(!n||!r||!o)return;let c=n.value.trim(),u=this.getInitialPluginId(null);if(!c||!u){a(`Label is required.`,4e3);return}let d={executionMode:r.value},f=Number(o.value);Number.isFinite(f)&&f>0&&(d.pollIntervalSec=Math.floor(f)),d.unreadOnly=t.querySelector(`#int-unread-only`)?.checked===!0,t.querySelectorAll(`[data-config-field]`).forEach(e=>{let t=e.dataset.configField;if(!t)return;let n=e.value.trim();n&&(/^\d+$/.test(n)?d[t]=Number(n):n===`true`||n===`false`?d[t]=n===`true`:d[t]=n)});let p=s?.value.trim()||``;if(p)try{let e=JSON.parse(p);e&&typeof e==`object`&&Object.assign(d,e)}catch{a(`Extra config JSON is invalid.`,5e3);return}try{let e=await l(this.db,{id:this.editingConnectionId||void 0,label:c,pluginId:u,config:d}),n=await this.buildCredentialRef(t,e);await m(this.db,e.id,n),i(this.editingConnectionId?`Email connection updated`:`Email connection created`,3e3),t.hidden=!0,t.replaceChildren(),this.editingConnectionId=null,await this.reload()}catch(e){a(`Failed to save email connection: ${e instanceof Error?e.message:String(e)}`,6e3)}}async testConnectionFromForm(e){let t=e.querySelector(`[data-action="test-connection"]`);t&&(t.disabled=!0);try{let t=e.querySelector(`#int-username`)?.value.trim(),n=e.querySelector(`#cfg-host`)?.value.trim(),r=e.querySelector(`#cfg-mailboxPath`)?.value.trim()||`INBOX`,o=e.querySelector(`#cfg-port`)?.value.trim(),s=e.querySelector(`#cfg-secure`)?.value,c=e.querySelector(`#int-unread-only`)?.checked,l=e.querySelector(`#int-auth-mode`)?.value;if(!t){a(`Auth username (email login) is required.`,4e3);return}if(!n){a(`IMAP host is required.`,4e3);return}let u=Number(o),d=Number.isFinite(u)&&u>0?u:993,f=s!==`false`,p=`basic_userpass`,m,h,_=this.editingConnectionId?this.connections.find(e=>e.id===this.editingConnectionId):null;if(l===`oauth`){let t=e.querySelector(`#int-oauth-provider`)?.value,n=g({authMode:l,pendingOauthAccessToken:this.pendingOauthResult?.accessToken&&(!t||this.pendingOauthResult.providerId===t)?this.pendingOauthResult.accessToken:``,hasStoredOauthCredential:!!_?.credentialRef?.accountId});if(`error`in n){a(n.error,6e3);return}p=n.authType,n.authType===`oauth`&&(h=n.accessToken)}else{let t=e.querySelector(`#int-password`)?.value,n=g({authMode:l,passwordInput:t,hasStoredPasswordCredential:!!_?.credentialRef?.encryptedSecret});if(`error`in n){a(n.error,6e3);return}p=n.authType,n.authType===`basic_userpass`&&(m=n.password)}let v=await fetch(`/integrations/email/read`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({authType:p,host:n,port:d,secure:f,username:t,password:m,accessToken:h,mailboxPath:r,limit:1,unreadOnly:c===!0})}),y=await v.json().catch(()=>({}));if(!v.ok){a(`Connection test failed (${v.status}): ${y.error||v.statusText}`,7e3);return}i(`Connection test passed. IMAP login succeeded${typeof y.count==`number`?` (${y.count} messages returned).`:`.`}`,4500)}catch(e){a(`Connection test failed: ${e instanceof Error?e.message:String(e)}`,7e3)}finally{t&&(t.disabled=!1)}}async toggleConnection(e){if(!this.db)return;let t=this.connections.find(t=>t.id===e);if(!t){a(`Email connection not found.`,4e3);return}try{await l(this.db,{id:t.id,label:t.label,pluginId:t.pluginId,enabled:!t.enabled,config:t.config}),i(`Email ${t.enabled?`disabled`:`enabled`}`,2500),await this.reload()}catch(e){a(`Failed to update email connection: ${e instanceof Error?e.message:String(e)}`,6e3)}}async upsertLinkedOAuthAccount(t,n){if(!this.db)throw Error(`Database is not ready.`);let r=t.querySelector(`#int-username`)?.value.trim(),i=t.querySelector(`#int-oauth-client-id`)?.value.trim(),a=t.querySelector(`#int-oauth-client-secret`)?.value.trim(),l=t.querySelector(`#int-oauth-scope`)?.value.trim(),u=t.querySelector(`#int-oauth-provider`)?.value,d=this.getEmailOAuthProvider(u);if(!r)throw Error(`Email login address is required for OAuth authentication.`);if(!i)throw Error(`OAuth client ID is required for OAuth authentication.`);let f=this.connections.find(e=>e.id===n.id)?.credentialRef?.accountId,p=f&&this.accounts.find(e=>e.id===f)||null,m=p?.token||``,h=p?.refreshToken,g=p?.accessTokenExpiresAt,_=p?.scopes,v=p?.tokenType,y=p?.oauthClientSecret,b=p?.oauthRefreshFailureCount,x=p?.oauthReauthRequired,S=p?.oauthReauthRequiredAt;if(a){let e=await c(a);e&&(y=e)}if(this.pendingOauthResult?.accessToken){let e=await c(this.pendingOauthResult.accessToken);if(!e)throw Error(`Failed to encrypt OAuth access token.`);if(m=e,this.pendingOauthResult.refreshToken){let e=await c(this.pendingOauthResult.refreshToken);e&&(h=e)}g=this.pendingOauthResult.expiresAt,_=this.pendingOauthResult.scope?this.pendingOauthResult.scope.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):l?l.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):d.defaultScopes,v=this.pendingOauthResult.tokenType,b=0,x=!1,S=void 0}if(!m)throw Error(`Connect OAuth first to obtain an access token.`);let C=p?.id||s(),w={id:C,label:`${n.label} ${d.label}`,service:d.serviceName,hostPattern:d.hostPattern,token:m,authMode:`oauth`,oauthProviderId:d.id,oauthClientId:i,oauthClientSecret:y,accessTokenExpiresAt:g,refreshToken:h,scopes:_||d.defaultScopes,tokenType:v,oauthRefreshFailureCount:b,oauthReauthRequired:x,oauthReauthRequiredAt:S},T=[...this.accounts],E=T.findIndex(e=>e.id===C);return E===-1?T.push(w):T[E]=w,await o(this.db,e.SERVICE_ACCOUNTS,T),this.accounts=T,w}};customElements.get(S)||customElements.define(S,D);export{D as ShadowClawIntegrations};
|
|
416
|
+
`);let y=n;y.hidden=!1,this.pendingOauthResult=null,n.querySelector(`#int-auth-mode`)?.addEventListener(`change`,()=>this.updateAuthModeVisibility(n)),n.querySelector(`[data-action="imap-autofill"]`)?.addEventListener(`click`,()=>this.applyImapPreset(n)),n.querySelector(`[data-action="connect-oauth"]`)?.addEventListener(`click`,()=>void this.connectOAuthFromForm(n)),n.querySelector(`#int-oauth-provider`)?.addEventListener(`change`,()=>this.updateOAuthProviderHelp(n)),n.querySelector(`[data-action="cancel"]`)?.addEventListener(`click`,()=>{y.hidden=!0,y.replaceChildren(),this.editingConnectionId=null}),n.querySelector(`[data-action="save"]`)?.addEventListener(`click`,()=>{this.saveForm()}),n.querySelector(`[data-action="test-connection"]`)?.addEventListener(`click`,()=>{this.testConnectionFromForm(n)}),this.updateAuthModeVisibility(n),this.updateOAuthProviderHelp(n)}updateAuthModeVisibility(e){let t=e.querySelector(`#int-auth-mode`)?.value,n=e.querySelector(`[data-region="password-auth-fields"]`),r=e.querySelector(`[data-region="oauth-auth-fields"]`);n&&(n.style.display=t===`oauth`?`none`:`block`),r&&(r.style.display=t===`oauth`?`block`:`none`)}updateOAuthProviderHelp(e){let t=e.querySelector(`#int-oauth-provider`)?.value,n=this.getEmailOAuthProvider(t),r=e.querySelector(`#int-oauth-scope`),i=e.querySelector(`[data-region="oauth-scope-help"]`),a=e.querySelector(`[data-action="connect-oauth"]`);r&&(r.placeholder=n.scopePlaceholder,r.value.trim()||(r.value=n.defaultScopes.join(` `))),i&&(i.textContent=n.scopeHelpText),a&&(a.textContent=n.connectButtonLabel)}async buildCredentialRef(e,t){let n=e.querySelector(`#int-auth-mode`)?.value,r=e.querySelector(`#int-username`),i=e.querySelector(`#int-password`),a=r?.value.trim()||``,s=i?.value.trim()||``,c=this.connections.find(e=>e.id===t.id);if(n===`oauth`){if(!a)throw Error(`Email login address is required for OAuth authentication.`);let n=await this.upsertLinkedOAuthAccount(e,t);return{serviceType:`http_api`,authType:`oauth`,providerId:n.oauthProviderId||`google`,accountId:n.id,username:a}}let l;if(s){if(l=await o(s)||void 0,!l)throw Error(`Could not encrypt email password.`)}else l=c?.credentialRef?.encryptedSecret;if(!a&&!l)return null;if(!a)throw Error(`Auth username is required when a password is configured.`);if(!l)throw Error(`Auth password is required when username is configured.`);return{serviceType:`http_api`,authType:`basic_userpass`,username:a,encryptedSecret:l}}async connectOAuthFromForm(e){let t=e.querySelector(`#int-oauth-provider`)?.value,n=this.getEmailOAuthProvider(t),r=e.querySelector(`#int-oauth-client-id`)?.value.trim(),i=e.querySelector(`#int-oauth-client-secret`)?.value.trim(),a=e.querySelector(`#int-oauth-scope`)?.value.trim(),o=e.querySelector(`[data-region="oauth-status"]`),s=e.querySelector(`[data-action="connect-oauth"]`);if(!r){m(`OAuth client ID is required.`,4e3);return}o&&(o.textContent=`Starting OAuth...`),s&&(s.disabled=!0);try{let e=a?a.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):n.defaultScopes,t=`${window.location.origin}/oauth/callback`,s=await fetch(`/oauth/authorize`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({providerId:n.id,clientId:r,clientSecret:i||void 0,redirectUri:t,scope:e,extraAuthorizeParams:{access_type:`offline`,prompt:`consent`}})}),c=await s.json();if(!s.ok||!c.state||!c.authorizeUrl)throw Error(c.error||`OAuth authorize failed`);window.open(c.authorizeUrl,`shadowclaw-google-oauth`,`popup=yes,width=540,height=720`);let l=c.state,u=`pending`;for(let e=0;e<60;e++){let e=await fetch(`/oauth/session/${encodeURIComponent(l)}`),t=await e.json();if(!e.ok)throw Error(t.error||`OAuth session not found`);if(u=t.status||`pending`,u===`authorized`)break;if(u===`error`)throw Error(t.error||`OAuth authorization failed`);await new Promise(e=>setTimeout(e,1e3))}if(u!==`authorized`)throw Error(`OAuth authorization timed out`);let d=await fetch(`/oauth/token`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({state:l})}),f=await d.json();if(!d.ok||!f.accessToken)throw Error(f.error||`OAuth token exchange failed`);this.pendingOauthResult={providerId:n.id,accessToken:f.accessToken,refreshToken:f.refreshToken,expiresAt:f.expiresIn?Date.now()+f.expiresIn*1e3:void 0,scope:f.scope,tokenType:f.tokenType},o&&(o.textContent=`OAuth connected`),p(`${n.label} connected`,3e3)}catch(e){let t=e instanceof Error?e.message:String(e);o&&(o.textContent=`OAuth failed`),m(`${n.label} connect failed: ${t}`,6e3)}finally{s&&(s.disabled=!1)}}async deleteConnection(e){if(!this.db)return;let t=this.connections.find(t=>t.id===e);if(t&&await this.requestConfirmation({title:`Delete Email Connection`,message:`Delete email connection \"${t.label}\"?`,confirmLabel:`Delete`,cancelLabel:`Cancel`}))try{if(!await l(this.db,e)){m(`Failed to delete email connection.`,5e3);return}p(`Email connection deleted`,2500),await this.reload()}catch(e){m(`Failed to delete email connection: ${e instanceof Error?e.message:String(e)}`,6e3)}}async reload(){if(!this.db)return;this.manifests=d().filter(e=>e.id===`imap`),this.connections=await c(this.db);let t=await n(this.db,e.SERVICE_ACCOUNTS);this.accounts=Array.isArray(t)?t:[],this.renderConnectionList()}async requestConfirmation(e){let t=document.querySelector(`shadow-claw`);return t&&typeof t.requestDialog==`function`?await t.requestDialog({mode:`confirm`,...e}):!1}async saveForm(){let e=this.shadowRoot;if(!e||!this.db)return;let t=e.querySelector(`[data-region="connection-form"]`);if(!t)return;let n=t.querySelector(`#int-label`),r=t.querySelector(`#int-mode`),i=t.querySelector(`#int-poll`),a=t.querySelector(`#int-extra-config`);if(!n||!r||!i)return;let o=n.value.trim(),c=this.getInitialPluginId(null);if(!o||!c){m(`Label is required.`,4e3);return}let l={executionMode:r.value},u=Number(i.value);Number.isFinite(u)&&u>0&&(l.pollIntervalSec=Math.floor(u)),l.unreadOnly=t.querySelector(`#int-unread-only`)?.checked===!0,t.querySelectorAll(`[data-config-field]`).forEach(e=>{let t=e.dataset.configField;if(!t)return;let n=e.value.trim();n&&(/^\d+$/.test(n)?l[t]=Number(n):n===`true`||n===`false`?l[t]=n===`true`:l[t]=n)});let d=a?.value.trim()||``;if(d)try{let e=JSON.parse(d);e&&typeof e==`object`&&Object.assign(l,e)}catch{m(`Extra config JSON is invalid.`,5e3);return}try{let e=await s(this.db,{id:this.editingConnectionId||void 0,label:o,pluginId:c,config:l}),n=await this.buildCredentialRef(t,e);await f(this.db,e.id,n),p(this.editingConnectionId?`Email connection updated`:`Email connection created`,3e3),t.hidden=!0,t.replaceChildren(),this.editingConnectionId=null,await this.reload()}catch(e){m(`Failed to save email connection: ${e instanceof Error?e.message:String(e)}`,6e3)}}async testConnectionFromForm(e){let t=e.querySelector(`[data-action="test-connection"]`);t&&(t.disabled=!0);try{let t=e.querySelector(`#int-username`)?.value.trim(),n=e.querySelector(`#cfg-host`)?.value.trim(),r=e.querySelector(`#cfg-mailboxPath`)?.value.trim()||`INBOX`,i=e.querySelector(`#cfg-port`)?.value.trim(),a=e.querySelector(`#cfg-secure`)?.value,o=e.querySelector(`#int-unread-only`)?.checked,s=e.querySelector(`#int-auth-mode`)?.value;if(!t){m(`Auth username (email login) is required.`,4e3);return}if(!n){m(`IMAP host is required.`,4e3);return}let c=Number(i),l=Number.isFinite(c)&&c>0?c:993,u=a!==`false`,d=`basic_userpass`,f,h,_=this.editingConnectionId?this.connections.find(e=>e.id===this.editingConnectionId):null;if(s===`oauth`){let t=e.querySelector(`#int-oauth-provider`)?.value,n=g({authMode:s,pendingOauthAccessToken:this.pendingOauthResult?.accessToken&&(!t||this.pendingOauthResult.providerId===t)?this.pendingOauthResult.accessToken:``,hasStoredOauthCredential:!!_?.credentialRef?.accountId});if(`error`in n){m(n.error,6e3);return}d=n.authType,n.authType===`oauth`&&(h=n.accessToken)}else{let t=e.querySelector(`#int-password`)?.value,n=g({authMode:s,passwordInput:t,hasStoredPasswordCredential:!!_?.credentialRef?.encryptedSecret});if(`error`in n){m(n.error,6e3);return}d=n.authType,n.authType===`basic_userpass`&&(f=n.password)}let v=await fetch(`/integrations/email/read`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({authType:d,host:n,port:l,secure:u,username:t,password:f,accessToken:h,mailboxPath:r,limit:1,unreadOnly:o===!0})}),y=await v.json().catch(()=>({}));if(!v.ok){m(`Connection test failed (${v.status}): ${y.error||v.statusText}`,7e3);return}p(`Connection test passed. IMAP login succeeded${typeof y.count==`number`?` (${y.count} messages returned).`:`.`}`,4500)}catch(e){m(`Connection test failed: ${e instanceof Error?e.message:String(e)}`,7e3)}finally{t&&(t.disabled=!1)}}async toggleConnection(e){if(!this.db)return;let t=this.connections.find(t=>t.id===e);if(!t){m(`Email connection not found.`,4e3);return}try{await s(this.db,{id:t.id,label:t.label,pluginId:t.pluginId,enabled:!t.enabled,config:t.config}),p(`Email ${t.enabled?`disabled`:`enabled`}`,2500),await this.reload()}catch(e){m(`Failed to update email connection: ${e instanceof Error?e.message:String(e)}`,6e3)}}async upsertLinkedOAuthAccount(t,n){if(!this.db)throw Error(`Database is not ready.`);let r=t.querySelector(`#int-username`)?.value.trim(),s=t.querySelector(`#int-oauth-client-id`)?.value.trim(),c=t.querySelector(`#int-oauth-client-secret`)?.value.trim(),l=t.querySelector(`#int-oauth-scope`)?.value.trim(),u=t.querySelector(`#int-oauth-provider`)?.value,d=this.getEmailOAuthProvider(u);if(!r)throw Error(`Email login address is required for OAuth authentication.`);if(!s)throw Error(`OAuth client ID is required for OAuth authentication.`);let f=this.connections.find(e=>e.id===n.id)?.credentialRef?.accountId,p=f&&this.accounts.find(e=>e.id===f)||null,m=p?.token||``,h=p?.refreshToken,g=p?.accessTokenExpiresAt,_=p?.scopes,v=p?.tokenType,y=p?.oauthClientSecret,b=p?.oauthRefreshFailureCount,x=p?.oauthReauthRequired,S=p?.oauthReauthRequiredAt;if(c){let e=await o(c);e&&(y=e)}if(this.pendingOauthResult?.accessToken){let e=await o(this.pendingOauthResult.accessToken);if(!e)throw Error(`Failed to encrypt OAuth access token.`);if(m=e,this.pendingOauthResult.refreshToken){let e=await o(this.pendingOauthResult.refreshToken);e&&(h=e)}g=this.pendingOauthResult.expiresAt,_=this.pendingOauthResult.scope?this.pendingOauthResult.scope.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):l?l.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):d.defaultScopes,v=this.pendingOauthResult.tokenType,b=0,x=!1,S=void 0}if(!m)throw Error(`Connect OAuth first to obtain an access token.`);let C=p?.id||a(),w={id:C,label:`${n.label} ${d.label}`,service:d.serviceName,hostPattern:d.hostPattern,token:m,authMode:`oauth`,oauthProviderId:d.id,oauthClientId:s,oauthClientSecret:y,accessTokenExpiresAt:g,refreshToken:h,scopes:_||d.defaultScopes,tokenType:v,oauthRefreshFailureCount:b,oauthReauthRequired:x,oauthReauthRequiredAt:S},T=[...this.accounts],E=T.findIndex(e=>e.id===C);return E===-1?T.push(w):T[E]=w,await i(this.db,e.SERVICE_ACCOUNTS,T),this.accounts=T,w}};customElements.get(S)||customElements.define(S,D);export{D as ShadowClawIntegrations};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{P as e,R as t,c as n,r,u as i}from"./config-CrHchneq.js";import{n as a}from"./txPromise-EBECky1b.js";import{t as o}from"./getConfig-D89uJgo5.js";import{u as s}from"./custom-element-security-
|
|
1
|
+
import{P as e,R as t,c as n,r,u as i}from"./config-CrHchneq.js";import{n as a}from"./txPromise-EBECky1b.js";import{t as o}from"./getConfig-D89uJgo5.js";import{u as s}from"./custom-element-security-FU04Cq05.js";import{$ as c,J as l,K as u,Nt as d,Q as f,Ut as p,W as m,_ as h,ct as g,d as _,et as v,f as y,g as b,h as x,it as S,lt as C,p as w,q as T,t as E,tt as D,v as O}from"./orchestrator-DHjdLtqa.js";import{t as k}from"./setConfig-DFMYnYLE.js";import{a as A,r as j,s as M}from"./toast-BXgUfbyh.js";import{t as N}from"./shadow-claw-element-DIrv3P6A.js";import{t as P}from"./effect-BJCrpFdp.js";import{n as F,r as I}from"./prompt-api-OUOP-B-R.js";import{n as L,t as R}from"./model-ranking-C60HgQ2c.js";const z=[{pattern:`gemma-3-1b-it-ONNX-GQA`,contextWindow:128e3},{pattern:`gemma-3-1b-it-ONNX`,contextWindow:128e3},{pattern:`Qwen3-0.6B-ONNX`,contextWindow:131072},{pattern:`Qwen3.5`,contextWindow:32768},{pattern:`Llama-3.2`,contextWindow:128e3},{pattern:`Phi-4`,contextWindow:128e3},{pattern:`Phi-3.5`,contextWindow:128e3},{pattern:`SmolLM`,contextWindow:8192},{pattern:`DeepSeek-R1`,contextWindow:128e3},{pattern:`LFM2`,contextWindow:32768},{pattern:`gpt-oss`,contextWindow:32768},{pattern:`gemma-4`,contextWindow:128e3},{pattern:`browser-built-in`,contextWindow:4096}];function B(e){let n=t.getModelInfo(e);if(n&&typeof n.contextWindow==`number`&&n.contextWindow>0)return n.contextWindow;for(let{pattern:t,contextWindow:n}of z)if(e.includes(t))return n;return null}function V(t,r,i){let a=r;t===`prompt_api`&&(r===`browser-built-in`||!r)&&(i?a=i:d()||(a=n));let o=e(a),s=typeof navigator>`u`?null:navigator,c=typeof s?.deviceMemory==`number`?s.deviceMemory:null,l=typeof s?.hardwareConcurrency==`number`?s.hardwareConcurrency:null;if(t===`prompt_api`||t===`transformers_js_browser`||t===`litert_lm_browser`||t===`ollama`){let e=B(a),t=o;c!==null&&(t=c>=32?Math.min(t,16384):c>=16?Math.min(t,8192):c>=8?Math.min(t,4096):Math.min(t,2048)),l!==null&&(l<=4?t=Math.min(t,2048):l>=16?t=Math.min(o,Math.max(t,8192)):l>=8&&(t=Math.min(o,Math.max(t,4096)))),/thinking|reasoning/i.test(a)&&(t=Math.min(t,4096)),t=Math.max(512,Math.min(t,o));let n=[];return e!==null&&n.push(`native context: ${e.toLocaleString()} tokens`),c!==null&&n.push(`${c} GB browser-reported memory`),l!==null&&n.push(`${l} CPU threads`),/thinking|reasoning/i.test(a)&&n.push(`reasoning model`),{recommended:t,detail:n.length>0?`Recommended for this device: ${t.toLocaleString()} tokens (${n.join(`, `)}). Model ceiling: ${o.toLocaleString()}.`:`Recommended for local inference: ${t.toLocaleString()} tokens. Model ceiling: ${o.toLocaleString()}.`}}return{recommended:o,detail:`Model-aware ceiling: ${o.toLocaleString()} tokens.`}}const H=new CSSStyleSheet;H.replaceSync(`*,
|
|
2
2
|
*::before,
|
|
3
3
|
*::after {
|
|
4
4
|
font-family: var(--shadow-claw-font-sans);
|
|
@@ -663,4 +663,4 @@ import{P as e,R as t,c as n,r,u as i}from"./config-CrHchneq.js";import{n as a}fr
|
|
|
663
663
|
</button>
|
|
664
664
|
</div>
|
|
665
665
|
</template>
|
|
666
|
-
`,`text/html`),W=U.querySelector(`template`);let G=[];G=W?Array.from(W.content.children):Array.from(U.head.children).concat(Array.from(U.body.children));var K=G;const q=`shadow-claw-llm`;var J=class extends N{static styles=H;static template=K;db;lastLlamafileHelpKey;llamafileDiscoveredModelIds;llamafileModelLoadError;modelFetchToken;orchestrator;constructor(){super(),this.db=null,this.orchestrator=null,this.llamafileDiscoveredModelIds=[],this.llamafileModelLoadError=null,this.lastLlamafileHelpKey=``,this.modelFetchToken=0}async connectedCallback(){if(!this.shadowRoot)throw Error(`shadowRoot not found`);this.db=await a(),this.orchestrator=k.orchestrator,this.bindEventListeners(),this.setupEffects()}applyRecommendedMaxTokens(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="max-tokens-input"]`);if(!t)return;let n=this.orchestrator.provider,r=this.orchestrator.model,i;n===`prompt_api`&&(i=e.querySelector(`[data-setting="prompt-api-fallback-select"]`)?.value||`onnx-community/Qwen3-0.6B-ONNX`);let a=V(n,r,i);t.value=String(a.recommended)}bindEventListeners(){let e=this.shadowRoot;e&&(e.querySelector(`[data-setting="provider-select"]`)?.addEventListener(`change`,()=>this.onProviderChange()),e.querySelector(`[data-setting="prompt-api-fallback-select"]`)?.addEventListener(`change`,e=>{let t=e.target;t?.value&&g(t.value).then(()=>this.updateMaxTokensUI()).catch(()=>{}),this.updateMaxTokensUI()}),e.querySelector(`[data-action="save-llm-provider"]`)?.addEventListener(`click`,()=>this.saveApiKey()),e.querySelector(`[data-action="save-model"]`)?.addEventListener(`click`,()=>this.saveModel()),e.querySelector(`[data-action="refresh-models"]`)?.addEventListener(`click`,()=>this.updateModelSelector()),e.querySelector(`[data-setting="model-select"]`)?.addEventListener(`change`,t=>{let n=e.querySelector(`[data-setting="custom-model-input"]`),r=t.target;n&&r&&(n.style.display=r.value===`__custom__`?`block`:`none`)}),e.querySelector(`[data-setting="streaming-toggle"]`)?.addEventListener(`change`,e=>{e.target instanceof HTMLInputElement&&this.onStreamingToggle(e.target.checked)}),e.querySelector(`[data-setting="context-compression-toggle"]`)?.addEventListener(`change`,e=>{e.target instanceof HTMLInputElement&&this.onContextCompressionToggle(e.target.checked)}),e.querySelector(`[data-action="save-max-iterations"]`)?.addEventListener(`click`,()=>this.saveMaxIterations()),e.querySelector(`[data-action="save-subagent-max-parallel"]`)?.addEventListener(`click`,()=>this.saveSubagentMaxParallel()),e.querySelector(`[data-action="save-subagent-workspace-mode"]`)?.addEventListener(`click`,()=>this.saveSubagentWorkspaceMode()),e.querySelector(`[data-action="save-rate-limit-settings"]`)?.addEventListener(`click`,()=>this.saveRateLimitSettings()),e.querySelector(`[data-action="save-max-tokens"]`)?.addEventListener(`click`,()=>this.saveMaxTokens()),e.querySelector(`[data-action="save-reasoning-effort"]`)?.addEventListener(`click`,()=>this.saveReasoningEffort()),e.querySelector(`[data-action="apply-recommended-max-tokens"]`)?.addEventListener(`click`,()=>this.applyRecommendedMaxTokens()),e.querySelector(`[data-action="save-llamafile-settings"]`)?.addEventListener(`click`,()=>this.saveLlamafileSettings()),e.querySelector(`[data-action="save-bedrock-settings"]`)?.addEventListener(`click`,()=>this.saveBedrockSettings()),e.querySelector(`[data-action="save-mesh-llm-settings"]`)?.addEventListener(`click`,()=>this.saveMeshLlmSettings()),e.querySelector(`[data-action="save-transformers-js-settings"]`)?.addEventListener(`click`,()=>this.saveTransformersJsSettings()),e.querySelector(`[data-action="save-builtin-ai-settings"]`)?.addEventListener(`click`,()=>this.saveBuiltinAiSettings()),e.querySelector(`[data-setting="llamafile-mode"]`)?.addEventListener(`change`,()=>{this.updateLlamafileModeVisibility(),this.updateLlamafileModelSectionVisibility(),this.updateModelSelector()}))}renderBedrockSettings(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=this.orchestrator?O(this.orchestrator):null,n=e.querySelector(`[data-setting="bedrock-region-input"]`),r=e.querySelector(`[data-setting="bedrock-profile-input"]`),i=e.querySelector(`[data-setting="bedrock-auth-mode"]`);n&&(n.value=t?.region||``),r&&(r.value=t?.profile||``),i&&(i.value=t?.authMode||`provider_chain`)}renderLlamafileSettings(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=f(this.orchestrator);if(!t)return;let n=e.querySelector(`[data-setting="llamafile-mode"], [data-setting="llamafile-mode-select"]`),r=e.querySelector(`[data-setting="llamafile-host"], [data-setting="llamafile-host-input"]`),i=e.querySelector(`[data-setting="llamafile-port"], [data-setting="llamafile-port-input"]`),a=e.querySelector(`[data-setting="llamafile-offline"], [data-setting="llamafile-offline-toggle"]`);n&&(n.value=t.mode),r&&(r.value=t.host),i&&(i.value=String(t.port)),a&&(a.checked=t.offline)}renderMeshLlmSettings(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=this.orchestrator.getMeshLlmSettings?.(),n=e.querySelector(`[data-setting="mesh-llm-host-input"]`);n&&(n.value=t?.host||``)}setupEffects(){P(()=>{k.ready&&(this.orchestrator=k.orchestrator,this.render())})}updateBedrockSettingsVisibility(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-setting="bedrock-settings"]`);n&&(n.style.display=e===`bedrock_proxy`?`block`:`none`)}updateLlamafileModelSectionVisibility(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="model-settings"]`);if(!t)return;let n=f(this.orchestrator);t.style.display=n?.mode===`server`?`none`:`block`}updateLlamafileModeVisibility(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="llamafile-server-only"]`),n=e.querySelector(`[data-setting="llamafile-cli-only"]`);if(!t&&!n)return;let r=this.orchestrator.provider===`llamafile`&&f(this.orchestrator)?.mode===`server`;t&&(t.style.display=r?`block`:`none`),n&&(n.style.display=r?`none`:`block`)}updateLlamafileSettingsVisibility(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-setting="llamafile-settings"]`);n&&(n.style.display=e===`llamafile`?`block`:`none`)}updateMaxTokensUI(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="max-tokens-input"]`),n=e.querySelector(`[data-setting="max-tokens-helper"]`),r=this.orchestrator.provider,i=this.orchestrator.model,a;r===`prompt_api`&&(a=e.querySelector(`[data-setting="prompt-api-fallback-select"]`)?.value||`onnx-community/Qwen3-0.6B-ONNX`);let o=this.orchestrator.maxTokens,s=V(r,i,a);t&&(t.value=String(o),t.removeAttribute(`max`)),n&&(n.textContent=`${s.detail} Current value: ${o.toLocaleString()}.`)}updateMeshLlmSettingsVisibility(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-setting="mesh-llm-settings"]`);n&&(n.style.display=e===`mesh-llm`?`block`:`none`)}updateModelProviderHelperText(){let e=this.shadowRoot;if(!e||!this.orchestrator)return;let t=e.querySelector(`[data-setting="model-provider-helper"]`);if(!t)return;let n=this.orchestrator.provider,r=f(this.orchestrator);if(n!==`llamafile`||r?.mode===`server`){t.hidden=!0,t.textContent=``;return}if(t.hidden=!1,this.llamafileDiscoveredModelIds.length>0){t.textContent=`Discovered ${this.llamafileDiscoveredModelIds.length} *.llamafile model${this.llamafileDiscoveredModelIds.length===1?``:`s`} in ${y}. Choose Custom Model ID to target a file name that is not listed yet.`;return}if(this.llamafileModelLoadError){t.textContent=`Could not load llamafile models from ${y}. You can still enter a custom model id, but the file must exist there.`;return}t.textContent=`ShadowClaw looks for *.llamafile binaries in ${y}.`}updateModelSelector(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=p(),n=this.orchestrator.provider,r=t.find(e=>e.id===n),i=++this.modelFetchToken;n!==`llamafile`&&(this.llamafileDiscoveredModelIds=[],this.llamafileModelLoadError=null);let a=!1;if(n===`llamafile`&&f(this.orchestrator)?.mode===`server`){let t=e.querySelector(`[data-setting="model-select"]`);t&&(s(t,`<option value="">Model is served by local llamafile server</option>`),t.disabled=!0),a=!0}this.updateModelProviderHelperText();let o=e.querySelector(`[data-setting="prompt-api-fallback-group"]`);if(o){let e=F()||I();o.style.display=n===`prompt_api`&&!e?`block`:`none`}let c=e.querySelector(`[data-setting="model-select"]`),u=e.querySelector(`[data-setting="custom-model-input"]`),d=this.orchestrator.model,m=new Set([`transformers_js_local`,`transformers_js_browser`,`ollama`,`llamafile`,`prompt_api`]),h=e=>e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/\"/g,`"`).replace(/'/g,`'`),g=e=>m.has(n)||n===`mesh-llm`?!0:typeof e==`string`?!1:Array.isArray(e.providers)?e.providers.some(e=>e.provider===`hf-inference`||!e.pricing||parseFloat(String(e.pricing.input||e.pricing.prompt||0))===0&&parseFloat(String(e.pricing.output||e.pricing.completion||0))===0):e.pricing?parseFloat(String(e.pricing.prompt||0))===0&&parseFloat(String(e.pricing.completion||0))===0:!1,v=e=>{let t=typeof e==`string`?e:e.id||e.name;return m.has(n)?L(t):typeof e==`string`?!1:e.supports_tools===!0||e.supportsTools===!0?!0:Array.isArray(e.providers)?e.providers.some(e=>e.supports_tools===!0):Array.isArray(e.supported_parameters)?e.supported_parameters.includes(`tools`):!1},b=e=>{let t=typeof e==`string`?e:e.id||e.name;if(m.has(n))return L(t)?` 🛠️`:` ❔🛠️`;if(typeof e==`string`)return` ❔🛠️`;if(e.supports_tools===!0||e.supportsTools===!0)return` 🛠️`;if(e.supports_tools===!1||e.supportsTools===!1)return` 🚫🛠️`;if(Array.isArray(e.providers)){let t=e.providers.some(e=>e.supports_tools===!0),n=e.providers.some(e=>e.supports_tools===!1);if(t)return` 🛠️`;if(n)return` 🚫🛠️`}return Array.isArray(e.supported_parameters)?e.supported_parameters.includes(`tools`)?` 🛠️`:` 🚫🛠️`:` ❔🛠️`},x=e=>typeof e==`string`?0:typeof e.context_length==`number`?e.context_length:typeof e.context_window==`number`?e.context_window:Array.isArray(e.providers)?Math.max(...e.providers.map(e=>e.context_length||0),0):0,S=e=>{if(!c||!u)return;if(!Array.isArray(e)||e.length===0){let e=this.orchestrator?.model||``,t=n===`llamafile`?`No *.llamafile models found in ${y}`:`No models available`;s(c,[`<option value="" ${e?``:`selected`}>${h(t)}</option>`,`<option value="__custom__">-- Custom Model ID --</option>`].join(``)),e?(c.value=`__custom__`,u.value=e,u.style.display=`block`):(c.value=``,u.value=``,u.style.display=`none`),n===`llamafile`&&!e&&this.showLlamafileHelpDialog(this.llamafileModelLoadError?`Failed to load *.llamafile models: ${this.llamafileModelLoadError}`:`No *.llamafile files were found in ${y}.`),this.updateModelProviderHelperText();return}let t=[],r=[];for(let n of e)!n||typeof n!=`string`&&!n.id||(g(n)?t.push(n):r.push(n));let i=(e,t)=>{if(m.has(n)){let r=typeof e==`string`?e:e.id||e.name,i=typeof t==`string`?t:t.id||t.name;return R({id:r,supportsTools:v(e),contextLength:x(e)},{id:i,supportsTools:v(t),contextLength:x(t)},n)}let r=v(e),i=v(t);if(r!==i)return i?1:-1;let a=x(e),o=x(t);if(a!==o)return o-a;let s=typeof e==`string`?e:e.id||e.name,c=typeof t==`string`?t:t.id||t.name;return s.localeCompare(c)};t.sort(i),r.sort(i);let a=e=>{let t=typeof e==`string`?e:e.id||e.name,n=typeof e==`string`?t:typeof e.displayName==`string`&&e.displayName.trim()?e.displayName.trim():typeof e.name==`string`&&e.name.trim()?e.name.trim():t,r=b(e),i=x(e),a=``;i>=1e6?a=` (${(i/1e6).toFixed(1)}M)`:i>=1e3?a=` (${Math.round(i/1024)}k)`:i>0&&(a=` (${i})`);let o=n===t?t:`${n} - ${t}`;return`<option value="${h(t)}">${h(o)}${a}${r}</option>`},o=``;if(m.has(n)){let e=[...t,...r].sort(i);e.length>0&&(o+=`<optgroup label="${n===`prompt_api`?`Built-in`:`Local / Self-hosted`}">`,o+=e.map(a).join(``),o+=`</optgroup>`)}else t.length>0&&(o+=`<optgroup label="Free / Included">`,o+=t.map(a).join(``),o+=`</optgroup>`),r.length>0&&(o+=`<optgroup label="Paid / Pro">`,o+=r.map(a).join(``),o+=`</optgroup>`);o+=`<option value="__custom__">-- Custom Model ID --</option>`,s(c,o),e.map(e=>typeof e==`string`?e:e.id||e.name).includes(d)?(c.value=d,u.style.display=`none`):(c.value=`__custom__`,u.value=d||``,u.style.display=`block`),this.updateModelProviderHelperText()};if(!a)if(r?.modelsUrl&&c){let e=i;s(c,`<option>Loading models…</option>`),c.disabled=!0;let t={...r.headers};if(n===`llamafile`){let e=f(this.orchestrator);e&&(t[`x-llamafile-mode`]=e.mode,t[`x-llamafile-host`]=e.host,t[`x-llamafile-port`]=String(e.port),t[`x-llamafile-offline`]=e.offline?`true`:`false`)}else if(n===`bedrock_proxy`){let e=this.orchestrator?O(this.orchestrator):null;e?.region&&(t[`x-bedrock-region`]=e.region),e?.profile&&(t[`x-bedrock-profile`]=e.profile),e?.authMode&&(t[`x-bedrock-auth-mode`]=e.authMode)}_(this.orchestrator).then(i=>{if(i&&r.apiKeyHeader){let e=(r.apiKeyHeaderFormat||`{key}`).replace(`{key}`,i);t[r.apiKeyHeader]=e}r.modelsUrl&&fetch(r.modelsUrl,{headers:t}).then(e=>{if(!e.ok)throw Error(`HTTP ${e.status}`);return e.json()}).then(t=>{if(e!==this.modelFetchToken||this.orchestrator?.provider!==n)return;let i=[];if(Array.isArray(t))i=t;else if(t&&typeof t==`object`){if(i=t.models||t.data||[],i.length===0){for(let e in t)if(Array.isArray(t[e])&&t[e].length>0){i=t[e];break}}i.length===0&&t.id&&(i=[t])}if(Array.isArray(r.models)){let e=new Set(i.map(e=>typeof e==`string`?e:e.id||e.name));i=[...r.models.filter(t=>{let n=typeof t==`string`?t:t.id||t.name;return!e.has(n)}),...i]}n===`llamafile`&&(this.llamafileModelLoadError=null,this.llamafileDiscoveredModelIds=i.map(e=>typeof e==`string`?e:String(e?.id||e?.name||``)).filter(Boolean)),c.disabled=!1,S(i)}).catch(t=>{if(e!==this.modelFetchToken||this.orchestrator?.provider!==n)return;console.error(`[ShadowClaw] Failed to load models from`,r.modelsUrl,t);let i=t instanceof Error?t.message:String(t);if(n===`llamafile`){this.llamafileDiscoveredModelIds=[],this.llamafileModelLoadError=i,c.disabled=!1,S([]);return}s(c,`<option>Failed to load models</option>`),r?.models?(console.warn(`Falling back to statically configured models due to fetch failure.`),c.disabled=!1,S(r.models)):l(`Could not reach the model server — or proxy configuration is wrong`,5e3)})})}else r?.models&&c?(c.disabled=!1,S(r.models)):c&&(c.disabled=!1,S([]));let C=e.querySelector(`[data-setting="api-key-helper"]`),w=e.querySelector(`[data-setting="provider-select"]`);if(C&&w){let e=w.selectedOptions[0]?.text||`Provider`,t=r?.requiresApiKey!==!1;C.textContent=n===`llamafile`?`Runs local .llamafile binaries through the local proxy. No API key required.`:t?`Enter your ${e} API key. It is encrypted and stored locally.`:`This provider does not require an API key.`}let T=e.querySelector(`[data-setting="api-key-input"]`);if(T){let e=r?.requiresApiKey===!1;T.disabled=e,T.placeholder=e?`No API key required`:`sk-...`}}updateTransformersJsSettingsVisibility(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-setting="transformers-js-settings"]`);n&&(n.style.display=e===`transformers_js_browser`?`block`:`none`)}async onContextCompressionToggle(e){if(!(!this.orchestrator||!this.db))try{await b(this.orchestrator,this.db,e),c(e?`Context compression enabled`:`Context compression disabled`,2500)}catch(e){l(`Error saving context compression setting: `+(e instanceof Error?e.message:String(e)),6e3)}}async onProviderChange(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="provider-select"]`);if(!t)return;let n=t.value,r=this.orchestrator.provider;if(n!==r)try{await T(this.orchestrator,this.db,n,{loadApiKeyForProvider:this.orchestrator.loadApiKeyForProvider.bind(this.orchestrator),getApiKeyForHeaders:()=>_(this.orchestrator)}),this.updateModelSelector(),this.updateMaxTokensUI(),this.updateLlamafileSettingsVisibility(n),this.renderLlamafileSettings(),this.updateLlamafileModeVisibility(),this.updateLlamafileModelSectionVisibility(),this.updateBedrockSettingsVisibility(n),this.updateBedrockSettingsVisibility(n),this.updateMeshLlmSettingsVisibility(n),this.updateTransformersJsSettingsVisibility(n),await this.renderTransformersJsSettings(),c(`Switched to ${t.selectedOptions[0]?.text||n}`,3e3)}catch(e){l(`Error switching provider: `+(e instanceof Error?e.message:String(e)),6e3),t.value=r}}async onStreamingToggle(e){if(!(!this.orchestrator||!this.db))try{await j(this.orchestrator,this.db,e),c(e?`Streaming enabled`:`Streaming disabled`,2500)}catch(e){l(`Error saving streaming setting: `+(e instanceof Error?e.message:String(e)),6e3)}}async render(){let e=this.shadowRoot;if(!e||!this.orchestrator||!this.db)return;this.bindEventListeners();let t=p(),n=this.orchestrator.provider,a=e.querySelector(`[data-setting="provider-select"]`);a&&s(a,t.map(e=>`<option value="${e.id}" ${e.id===n?`selected`:``}>${e.name}</option>`).join(``)),this.updateModelSelector(),this.updateLlamafileSettingsVisibility(n),this.renderLlamafileSettings(),this.updateLlamafileModeVisibility(),this.updateLlamafileModelSectionVisibility(),this.updateModelProviderHelperText(),this.updateBedrockSettingsVisibility(n),this.renderBedrockSettings(),this.updateMeshLlmSettingsVisibility(n),this.renderMeshLlmSettings(),this.updateTransformersJsSettingsVisibility(n),await this.renderTransformersJsSettings(),this.renderBuiltinAiSettings();let c=e.querySelector(`[data-setting="prompt-api-fallback-select"]`);c&&(c.value=await o(this.db,r.PROMPT_API_FALLBACK_MODEL)||`onnx-community/Qwen3-0.6B-ONNX`,this.updateMaxTokensUI(),c.value&&g(c.value).then(()=>{this.updateMaxTokensUI()}).catch(()=>{}));let l=e.querySelector(`[data-setting="prompt-api-device-select"]`);l&&(l.value=await o(this.db,r.PROMPT_API_BACKEND)||`auto`);let u=e.querySelector(`[data-setting="prompt-api-dtype-select"]`);u&&(u.value=await o(this.db,r.PROMPT_API_DTYPE_STRATEGY)||`auto`);let d=e.querySelector(`[data-setting="streaming-toggle"]`);d&&(d.checked=this.orchestrator.streamingEnabled);let f=e.querySelector(`[data-setting="context-compression-toggle"]`);f&&(f.checked=this.orchestrator.contextCompressionEnabled);let m=e.querySelector(`[data-setting="reasoning-effort-select"]`);m&&(m.value=this.orchestrator.reasoningEffort||`none`);let h=e.querySelector(`[data-setting="max-iterations-input"]`);h&&this.orchestrator&&(h.value=String(this.orchestrator.maxIterations));let _=e.querySelector(`[data-setting="subagent-max-parallel-input"]`);if(_){let e=await o(this.db,r.SUBAGENT_MAX_PARALLEL),t=Number(e);_.value=String(Number.isFinite(t)&&t>0?t:5)}let v=e.querySelector(`[data-setting="subagent-workspace-mode-select"]`);if(v){let e=await o(this.db,r.SUBAGENT_WORKSPACE_MODE);v.value=e===`parent`||e===`isolated`||e===`automatic`?e:i}let y=e.querySelector(`[data-setting="rate-limit-calls-per-minute-input"]`);y&&this.orchestrator&&(y.value=String(this.orchestrator.rateLimitCallsPerMinute||0));let b=e.querySelector(`[data-setting="rate-limit-auto-adapt-toggle"]`);b&&this.orchestrator&&(b.checked=this.orchestrator.rateLimitAutoAdapt!==!1),this.updateMaxTokensUI()}async renderBuiltinAiSettings(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="compaction-engine-select"]`),n=e.querySelector(`[data-setting="builtin-ai-tools-backend-select"]`),i=await o(this.db,r.COMPACTION_ENGINE_PREFERENCE),a=await o(this.db,r.BUILTIN_AI_TOOLS_BACKEND);t&&(t.value=i||`auto`),n&&(n.value=a||`active_provider`)}async renderTransformersJsSettings(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let{getConfig:t}=await import(`./getConfig-D89uJgo5.js`).then(e=>e.n),{CONFIG_KEYS:n}=await import(`./config-CrHchneq.js`).then(e=>e.k),r=await t(this.db,n.TRANSFORMERS_JS_BACKEND)||`auto`,i=await t(this.db,n.TRANSFORMERS_JS_DTYPE_STRATEGY)||`auto`,a=e.querySelector(`[data-setting="transformers-js-backend"], [data-setting="transformers-js-device-select"]`);a&&(a.value=r);let o=e.querySelector(`[data-setting="transformers-js-dtype-strategy"], [data-setting="transformers-js-dtype-select"]`);o&&(o.value=i)}async requestAppDialog(e){let t=document.querySelector(`shadow-claw`);return t&&typeof t.requestDialog==`function`?await t.requestDialog(e):!1}async saveApiKey(){if(!this.orchestrator||!this.db){l(`Orchestrator not initialized`,5e3);return}let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="api-key-input"]`),n=e.querySelector(`[data-setting="provider-select"]`);if(!t||!n)return;let r=t.value.trim(),i=n.value;if(p().find(e=>e.id===i)?.requiresApiKey===!1){try{await T(this.orchestrator,this.db,i,{loadApiKeyForProvider:this.orchestrator.loadApiKeyForProvider.bind(this.orchestrator),getApiKeyForHeaders:()=>_(this.orchestrator)}),t.value=``,c(`Provider saved (no API key required)`,3e3)}catch(e){l(`Error saving provider: `+(e instanceof Error?e.message:String(e)),6e3)}return}if(!r){u(`Please enter an API key`,3e3);return}try{await this.orchestrator.setApiKey(this.db,r),t.value=``,c(`API key and provider saved`,3e3)}catch(e){l(`Error saving API key: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveBedrockSettings(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="bedrock-region-input"]`),n=e.querySelector(`[data-setting="bedrock-profile-input"]`),r=e.querySelector(`[data-setting="bedrock-auth-mode"]`);if(!t||!n)return;let i=t.value.trim(),a=n.value.trim(),o=r?.value||`provider_chain`;if(i&&!a||!i&&a){u(`Enter both Bedrock region and profile (or leave both blank to rely on environment variables)`,4e3);return}try{await h(this.orchestrator,this.db,{region:i,profile:a,authMode:o}),c(`Bedrock fallback settings saved`,3e3),this.orchestrator.provider===`bedrock_proxy`&&this.updateModelSelector()}catch(e){l(`Error saving Bedrock fallback settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveBuiltinAiSettings(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="compaction-engine-select"]`),n=e.querySelector(`[data-setting="builtin-ai-tools-backend-select"]`);try{t&&await M(this.db,r.COMPACTION_ENGINE_PREFERENCE,t.value),n&&await M(this.db,r.BUILTIN_AI_TOOLS_BACKEND,n.value),c(`Built-in AI settings saved successfully`,2500)}catch(e){l(`Error saving Built-in AI settings: `+(e instanceof Error?e.message:String(e)),5e3)}}async saveLlamafileSettings(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="llamafile-mode"], [data-setting="llamafile-mode-select"]`),n=e.querySelector(`[data-setting="llamafile-host"], [data-setting="llamafile-host-input"]`),r=e.querySelector(`[data-setting="llamafile-port"], [data-setting="llamafile-port-input"]`),i=e.querySelector(`[data-setting="llamafile-offline"], [data-setting="llamafile-offline-toggle"]`);if(!t||!n||!r||!i)return;let a=t.value===`cli`?`cli`:`server`,o=n.value.trim(),s=parseInt(r.value,10);if(!o){u(`Please enter a host`,3e3);return}if(!Number.isFinite(s)||s<1||s>65535){u(`Please enter a valid port (1-65535)`,3e3);return}try{if(await d(this.orchestrator,this.db,{mode:a,host:o,port:s,offline:i.checked}),this.updateLlamafileModeVisibility(),this.updateLlamafileModelSectionVisibility(),this.updateModelSelector(),this.orchestrator.provider===`llamafile`){c(await k.restartCurrentRequest()?`Llamafile settings saved, request restarted`:`Llamafile settings saved`,3e3);return}c(`Llamafile settings saved`,3e3)}catch(e){l(`Error saving llamafile settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveMaxIterations(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="max-iterations-input"]`);if(!t)return;let n=parseInt(t.value,10);if(!n||n<1){u(`Please enter a valid number (1 or higher)`,3e3);return}try{await S(this.orchestrator,this.db,n),c(`Max iterations saved`,3e3)}catch(e){l(`Error saving max iterations: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveMaxTokens(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="max-tokens-input"]`);if(!t)return;let n=parseInt(t.value,10);if(!n||n<1){u(`Please enter a valid number (1 or higher)`,3e3);return}try{await D(this.orchestrator,this.db,n),this.updateMaxTokensUI(),c(`Max tokens saved`,3e3)}catch(e){l(`Error saving max tokens: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveMeshLlmSettings(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="mesh-llm-host-input"]`);if(!t)return;let n=t.value.trim();try{this.orchestrator&&(await x(this.orchestrator,this.db,{host:n}),c(`Mesh LLM settings saved`,3e3),this.orchestrator.provider===`mesh-llm`&&this.updateModelSelector())}catch(e){l(`Error saving Mesh LLM settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveModel(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="model-select"]`),n=e.querySelector(`[data-setting="custom-model-input"]`);if(!t||!n)return;let i=t.value;if(i===`__custom__`&&(i=n.value.trim()),this.orchestrator.provider===`llamafile`&&f(this.orchestrator).mode===`cli`&&!i){await this.showLlamafileHelpDialog(`Select a discovered *.llamafile model or enter a custom model id that matches a file in the ${y} folder.`);return}if(this.orchestrator.provider===`prompt_api`){let t=e.querySelector(`[data-setting="prompt-api-fallback-select"]`);if(t)try{await M(this.db,r.PROMPT_API_FALLBACK_MODEL,t.value)}catch(e){console.warn(`Error saving prompt api fallback model`,e)}let n=e.querySelector(`[data-setting="prompt-api-device-select"]`);if(n)try{await M(this.db,r.PROMPT_API_BACKEND,n.value)}catch(e){console.warn(`Error saving prompt api backend`,e)}let i=e.querySelector(`[data-setting="prompt-api-dtype-select"]`);if(i)try{await M(this.db,r.PROMPT_API_DTYPE_STRATEGY,i.value)}catch(e){console.warn(`Error saving prompt api dtype strategy`,e)}}try{if(await A(this.orchestrator,this.db,i),this.updateMaxTokensUI(),this.orchestrator.provider===`llamafile`){c(await k.restartCurrentRequest()?`Model saved, request restarted`:`Model saved`,3e3);return}c(`Model saved`,3e3)}catch(e){l(`Error saving model: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveRateLimitSettings(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="rate-limit-calls-per-minute-input"]`),n=e.querySelector(`[data-setting="rate-limit-auto-adapt-toggle"]`);if(!t||!n)return;let r=parseInt(t.value,10);if(!Number.isFinite(r)||r<0){u(`Please enter a valid non-negative calls-per-minute value`,3e3);return}try{await C(this.orchestrator,this.db,r),await w(this.orchestrator,this.db,n.checked),c(`Rate limit settings saved`,3e3)}catch(e){l(`Error saving rate limit settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveReasoningEffort(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="reasoning-effort-select"]`);if(t)try{await v(this.orchestrator,this.db,t.value||`none`),c(`Reasoning effort saved`,3e3)}catch(e){l(`Error saving reasoning effort: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveSubagentMaxParallel(){if(!this.db){l(`Database not initialized`,3e3);return}let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="subagent-max-parallel-input"]`);if(!t)return;let n=parseInt(t.value,10);if(!n||n<1){u(`Please enter a valid number (1 or higher)`,3e3);return}try{await M(this.db,r.SUBAGENT_MAX_PARALLEL,String(n)),c(`Subagent limit saved`,3e3)}catch(e){l(`Error saving subagent limit: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveSubagentWorkspaceMode(){if(!this.db){l(`Database not initialized`,3e3);return}let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="subagent-workspace-mode-select"]`);if(!t)return;let n=t.value;if(n!==`automatic`&&n!==`parent`&&n!==`isolated`){u(`Please select a valid subagent workspace mode`,3e3);return}try{await M(this.db,r.SUBAGENT_WORKSPACE_MODE,n),c(`Subagent workspace mode saved`,3e3)}catch(e){l(`Error saving subagent workspace mode: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveTransformersJsSettings(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="transformers-js-backend"], [data-setting="transformers-js-device-select"]`)?.value||`auto`,n=e.querySelector(`[data-setting="transformers-js-dtype-strategy"], [data-setting="transformers-js-dtype-select"]`)?.value||`auto`,{setConfig:r}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n),{CONFIG_KEYS:i}=await import(`./config-CrHchneq.js`).then(e=>e.k);await r(this.db,i.TRANSFORMERS_JS_BACKEND,t),await r(this.db,i.TRANSFORMERS_JS_DTYPE_STRATEGY,n),c(`Transformers.js settings saved.`)}async showLlamafileHelpDialog(e){let t=`${e||``}|${this.orchestrator?.model||``}`;this.lastLlamafileHelpKey!==t&&(this.lastLlamafileHelpKey=t,await this.requestAppDialog(E(e)))}};customElements.get(q)||customElements.define(q,J);export{J as ShadowClawLlm};
|
|
666
|
+
`,`text/html`),W=U.querySelector(`template`);let G=[];G=W?Array.from(W.content.children):Array.from(U.head.children).concat(Array.from(U.body.children));var K=G;const q=`shadow-claw-llm`;var J=class extends N{static styles=H;static template=K;db;lastLlamafileHelpKey;llamafileDiscoveredModelIds;llamafileModelLoadError;modelFetchToken;orchestrator;constructor(){super(),this.db=null,this.orchestrator=null,this.llamafileDiscoveredModelIds=[],this.llamafileModelLoadError=null,this.lastLlamafileHelpKey=``,this.modelFetchToken=0}async connectedCallback(){if(!this.shadowRoot)throw Error(`shadowRoot not found`);this.db=await a(),this.orchestrator=E.orchestrator,this.bindEventListeners(),this.setupEffects()}applyRecommendedMaxTokens(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="max-tokens-input"]`);if(!t)return;let n=this.orchestrator.provider,r=this.orchestrator.model,i;n===`prompt_api`&&(i=e.querySelector(`[data-setting="prompt-api-fallback-select"]`)?.value||`onnx-community/Qwen3-0.6B-ONNX`);let a=V(n,r,i);t.value=String(a.recommended)}bindEventListeners(){let e=this.shadowRoot;e&&(e.querySelector(`[data-setting="provider-select"]`)?.addEventListener(`change`,()=>this.onProviderChange()),e.querySelector(`[data-setting="prompt-api-fallback-select"]`)?.addEventListener(`change`,e=>{let t=e.target;t?.value&&p(t.value).then(()=>this.updateMaxTokensUI()).catch(()=>{}),this.updateMaxTokensUI()}),e.querySelector(`[data-action="save-llm-provider"]`)?.addEventListener(`click`,()=>this.saveApiKey()),e.querySelector(`[data-action="save-model"]`)?.addEventListener(`click`,()=>this.saveModel()),e.querySelector(`[data-action="refresh-models"]`)?.addEventListener(`click`,()=>this.updateModelSelector()),e.querySelector(`[data-setting="model-select"]`)?.addEventListener(`change`,t=>{let n=e.querySelector(`[data-setting="custom-model-input"]`),r=t.target;n&&r&&(n.style.display=r.value===`__custom__`?`block`:`none`)}),e.querySelector(`[data-setting="streaming-toggle"]`)?.addEventListener(`change`,e=>{e.target instanceof HTMLInputElement&&this.onStreamingToggle(e.target.checked)}),e.querySelector(`[data-setting="context-compression-toggle"]`)?.addEventListener(`change`,e=>{e.target instanceof HTMLInputElement&&this.onContextCompressionToggle(e.target.checked)}),e.querySelector(`[data-action="save-max-iterations"]`)?.addEventListener(`click`,()=>this.saveMaxIterations()),e.querySelector(`[data-action="save-subagent-max-parallel"]`)?.addEventListener(`click`,()=>this.saveSubagentMaxParallel()),e.querySelector(`[data-action="save-subagent-workspace-mode"]`)?.addEventListener(`click`,()=>this.saveSubagentWorkspaceMode()),e.querySelector(`[data-action="save-rate-limit-settings"]`)?.addEventListener(`click`,()=>this.saveRateLimitSettings()),e.querySelector(`[data-action="save-max-tokens"]`)?.addEventListener(`click`,()=>this.saveMaxTokens()),e.querySelector(`[data-action="save-reasoning-effort"]`)?.addEventListener(`click`,()=>this.saveReasoningEffort()),e.querySelector(`[data-action="apply-recommended-max-tokens"]`)?.addEventListener(`click`,()=>this.applyRecommendedMaxTokens()),e.querySelector(`[data-action="save-llamafile-settings"]`)?.addEventListener(`click`,()=>this.saveLlamafileSettings()),e.querySelector(`[data-action="save-bedrock-settings"]`)?.addEventListener(`click`,()=>this.saveBedrockSettings()),e.querySelector(`[data-action="save-mesh-llm-settings"]`)?.addEventListener(`click`,()=>this.saveMeshLlmSettings()),e.querySelector(`[data-action="save-transformers-js-settings"]`)?.addEventListener(`click`,()=>this.saveTransformersJsSettings()),e.querySelector(`[data-action="save-builtin-ai-settings"]`)?.addEventListener(`click`,()=>this.saveBuiltinAiSettings()),e.querySelector(`[data-setting="llamafile-mode"]`)?.addEventListener(`change`,()=>{this.updateLlamafileModeVisibility(),this.updateLlamafileModelSectionVisibility(),this.updateModelSelector()}))}renderBedrockSettings(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=this.orchestrator?T(this.orchestrator):null,n=e.querySelector(`[data-setting="bedrock-region-input"]`),r=e.querySelector(`[data-setting="bedrock-profile-input"]`),i=e.querySelector(`[data-setting="bedrock-auth-mode"]`);n&&(n.value=t?.region||``),r&&(r.value=t?.profile||``),i&&(i.value=t?.authMode||`provider_chain`)}renderLlamafileSettings(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=l(this.orchestrator);if(!t)return;let n=e.querySelector(`[data-setting="llamafile-mode"], [data-setting="llamafile-mode-select"]`),r=e.querySelector(`[data-setting="llamafile-host"], [data-setting="llamafile-host-input"]`),i=e.querySelector(`[data-setting="llamafile-port"], [data-setting="llamafile-port-input"]`),a=e.querySelector(`[data-setting="llamafile-offline"], [data-setting="llamafile-offline-toggle"]`);n&&(n.value=t.mode),r&&(r.value=t.host),i&&(i.value=String(t.port)),a&&(a.checked=t.offline)}renderMeshLlmSettings(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=this.orchestrator.getMeshLlmSettings?.(),n=e.querySelector(`[data-setting="mesh-llm-host-input"]`);n&&(n.value=t?.host||``)}setupEffects(){P(()=>{E.ready&&(this.orchestrator=E.orchestrator,this.render())})}updateBedrockSettingsVisibility(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-setting="bedrock-settings"]`);n&&(n.style.display=e===`bedrock_proxy`?`block`:`none`)}updateLlamafileModelSectionVisibility(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="model-settings"]`);if(!t)return;let n=l(this.orchestrator);t.style.display=n?.mode===`server`?`none`:`block`}updateLlamafileModeVisibility(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="llamafile-server-only"]`),n=e.querySelector(`[data-setting="llamafile-cli-only"]`);if(!t&&!n)return;let r=this.orchestrator.provider===`llamafile`&&l(this.orchestrator)?.mode===`server`;t&&(t.style.display=r?`block`:`none`),n&&(n.style.display=r?`none`:`block`)}updateLlamafileSettingsVisibility(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-setting="llamafile-settings"]`);n&&(n.style.display=e===`llamafile`?`block`:`none`)}updateMaxTokensUI(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="max-tokens-input"]`),n=e.querySelector(`[data-setting="max-tokens-helper"]`),r=this.orchestrator.provider,i=this.orchestrator.model,a;r===`prompt_api`&&(a=e.querySelector(`[data-setting="prompt-api-fallback-select"]`)?.value||`onnx-community/Qwen3-0.6B-ONNX`);let o=this.orchestrator.maxTokens,s=V(r,i,a);t&&(t.value=String(o),t.removeAttribute(`max`)),n&&(n.textContent=`${s.detail} Current value: ${o.toLocaleString()}.`)}updateMeshLlmSettingsVisibility(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-setting="mesh-llm-settings"]`);n&&(n.style.display=e===`mesh-llm`?`block`:`none`)}updateModelProviderHelperText(){let e=this.shadowRoot;if(!e||!this.orchestrator)return;let t=e.querySelector(`[data-setting="model-provider-helper"]`);if(!t)return;let n=this.orchestrator.provider,r=l(this.orchestrator);if(n!==`llamafile`||r?.mode===`server`){t.hidden=!0,t.textContent=``;return}if(t.hidden=!1,this.llamafileDiscoveredModelIds.length>0){t.textContent=`Discovered ${this.llamafileDiscoveredModelIds.length} *.llamafile model${this.llamafileDiscoveredModelIds.length===1?``:`s`} in ${g}. Choose Custom Model ID to target a file name that is not listed yet.`;return}if(this.llamafileModelLoadError){t.textContent=`Could not load llamafile models from ${g}. You can still enter a custom model id, but the file must exist there.`;return}t.textContent=`ShadowClaw looks for *.llamafile binaries in ${g}.`}updateModelSelector(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=u(),n=this.orchestrator.provider,r=t.find(e=>e.id===n),i=++this.modelFetchToken;n!==`llamafile`&&(this.llamafileDiscoveredModelIds=[],this.llamafileModelLoadError=null);let a=!1;if(n===`llamafile`&&l(this.orchestrator)?.mode===`server`){let t=e.querySelector(`[data-setting="model-select"]`);t&&(s(t,`<option value="">Model is served by local llamafile server</option>`),t.disabled=!0),a=!0}this.updateModelProviderHelperText();let o=e.querySelector(`[data-setting="prompt-api-fallback-group"]`);if(o){let e=F()||I();o.style.display=n===`prompt_api`&&!e?`block`:`none`}let c=e.querySelector(`[data-setting="model-select"]`),d=e.querySelector(`[data-setting="custom-model-input"]`),f=this.orchestrator.model,p=new Set([`transformers_js_local`,`transformers_js_browser`,`ollama`,`llamafile`,`prompt_api`]),h=e=>e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/\"/g,`"`).replace(/'/g,`'`),_=e=>p.has(n)||n===`mesh-llm`?!0:typeof e==`string`?!1:Array.isArray(e.providers)?e.providers.some(e=>e.provider===`hf-inference`||!e.pricing||parseFloat(String(e.pricing.input||e.pricing.prompt||0))===0&&parseFloat(String(e.pricing.output||e.pricing.completion||0))===0):e.pricing?parseFloat(String(e.pricing.prompt||0))===0&&parseFloat(String(e.pricing.completion||0))===0:!1,v=e=>{let t=typeof e==`string`?e:e.id||e.name;return p.has(n)?L(t):typeof e==`string`?!1:e.supports_tools===!0||e.supportsTools===!0?!0:Array.isArray(e.providers)?e.providers.some(e=>e.supports_tools===!0):Array.isArray(e.supported_parameters)?e.supported_parameters.includes(`tools`):!1},y=e=>{let t=typeof e==`string`?e:e.id||e.name;if(p.has(n))return L(t)?` 🛠️`:` ❔🛠️`;if(typeof e==`string`)return` ❔🛠️`;if(e.supports_tools===!0||e.supportsTools===!0)return` 🛠️`;if(e.supports_tools===!1||e.supportsTools===!1)return` 🚫🛠️`;if(Array.isArray(e.providers)){let t=e.providers.some(e=>e.supports_tools===!0),n=e.providers.some(e=>e.supports_tools===!1);if(t)return` 🛠️`;if(n)return` 🚫🛠️`}return Array.isArray(e.supported_parameters)?e.supported_parameters.includes(`tools`)?` 🛠️`:` 🚫🛠️`:` ❔🛠️`},b=e=>typeof e==`string`?0:typeof e.context_length==`number`?e.context_length:typeof e.context_window==`number`?e.context_window:Array.isArray(e.providers)?Math.max(...e.providers.map(e=>e.context_length||0),0):0,x=e=>{if(!c||!d)return;if(!Array.isArray(e)||e.length===0){let e=this.orchestrator?.model||``,t=n===`llamafile`?`No *.llamafile models found in ${g}`:`No models available`;s(c,[`<option value="" ${e?``:`selected`}>${h(t)}</option>`,`<option value="__custom__">-- Custom Model ID --</option>`].join(``)),e?(c.value=`__custom__`,d.value=e,d.style.display=`block`):(c.value=``,d.value=``,d.style.display=`none`),n===`llamafile`&&!e&&this.showLlamafileHelpDialog(this.llamafileModelLoadError?`Failed to load *.llamafile models: ${this.llamafileModelLoadError}`:`No *.llamafile files were found in ${g}.`),this.updateModelProviderHelperText();return}let t=[],r=[];for(let n of e)!n||typeof n!=`string`&&!n.id||(_(n)?t.push(n):r.push(n));let i=(e,t)=>{if(p.has(n)){let r=typeof e==`string`?e:e.id||e.name,i=typeof t==`string`?t:t.id||t.name;return R({id:r,supportsTools:v(e),contextLength:b(e)},{id:i,supportsTools:v(t),contextLength:b(t)},n)}let r=v(e),i=v(t);if(r!==i)return i?1:-1;let a=b(e),o=b(t);if(a!==o)return o-a;let s=typeof e==`string`?e:e.id||e.name,c=typeof t==`string`?t:t.id||t.name;return s.localeCompare(c)};t.sort(i),r.sort(i);let a=e=>{let t=typeof e==`string`?e:e.id||e.name,n=typeof e==`string`?t:typeof e.displayName==`string`&&e.displayName.trim()?e.displayName.trim():typeof e.name==`string`&&e.name.trim()?e.name.trim():t,r=y(e),i=b(e),a=``;i>=1e6?a=` (${(i/1e6).toFixed(1)}M)`:i>=1e3?a=` (${Math.round(i/1024)}k)`:i>0&&(a=` (${i})`);let o=n===t?t:`${n} - ${t}`;return`<option value="${h(t)}">${h(o)}${a}${r}</option>`},o=``;if(p.has(n)){let e=[...t,...r].sort(i);e.length>0&&(o+=`<optgroup label="${n===`prompt_api`?`Built-in`:`Local / Self-hosted`}">`,o+=e.map(a).join(``),o+=`</optgroup>`)}else t.length>0&&(o+=`<optgroup label="Free / Included">`,o+=t.map(a).join(``),o+=`</optgroup>`),r.length>0&&(o+=`<optgroup label="Paid / Pro">`,o+=r.map(a).join(``),o+=`</optgroup>`);o+=`<option value="__custom__">-- Custom Model ID --</option>`,s(c,o),e.map(e=>typeof e==`string`?e:e.id||e.name).includes(f)?(c.value=f,d.style.display=`none`):(c.value=`__custom__`,d.value=f||``,d.style.display=`block`),this.updateModelProviderHelperText()};if(!a)if(r?.modelsUrl&&c){let e=i;s(c,`<option>Loading models…</option>`),c.disabled=!0;let t={...r.headers};if(n===`llamafile`){let e=l(this.orchestrator);e&&(t[`x-llamafile-mode`]=e.mode,t[`x-llamafile-host`]=e.host,t[`x-llamafile-port`]=String(e.port),t[`x-llamafile-offline`]=e.offline?`true`:`false`)}else if(n===`bedrock_proxy`){let e=this.orchestrator?T(this.orchestrator):null;e?.region&&(t[`x-bedrock-region`]=e.region),e?.profile&&(t[`x-bedrock-profile`]=e.profile),e?.authMode&&(t[`x-bedrock-auth-mode`]=e.authMode)}m(this.orchestrator).then(i=>{if(i&&r.apiKeyHeader){let e=(r.apiKeyHeaderFormat||`{key}`).replace(`{key}`,i);t[r.apiKeyHeader]=e}r.modelsUrl&&fetch(r.modelsUrl,{headers:t}).then(e=>{if(!e.ok)throw Error(`HTTP ${e.status}`);return e.json()}).then(t=>{if(e!==this.modelFetchToken||this.orchestrator?.provider!==n)return;let i=[];if(Array.isArray(t))i=t;else if(t&&typeof t==`object`){if(i=t.models||t.data||[],i.length===0){for(let e in t)if(Array.isArray(t[e])&&t[e].length>0){i=t[e];break}}i.length===0&&t.id&&(i=[t])}if(Array.isArray(r.models)){let e=new Set(i.map(e=>typeof e==`string`?e:e.id||e.name));i=[...r.models.filter(t=>{let n=typeof t==`string`?t:t.id||t.name;return!e.has(n)}),...i]}n===`llamafile`&&(this.llamafileModelLoadError=null,this.llamafileDiscoveredModelIds=i.map(e=>typeof e==`string`?e:String(e?.id||e?.name||``)).filter(Boolean)),c.disabled=!1,x(i)}).catch(t=>{if(e!==this.modelFetchToken||this.orchestrator?.provider!==n)return;console.error(`[ShadowClaw] Failed to load models from`,r.modelsUrl,t);let i=t instanceof Error?t.message:String(t);if(n===`llamafile`){this.llamafileDiscoveredModelIds=[],this.llamafileModelLoadError=i,c.disabled=!1,x([]);return}s(c,`<option>Failed to load models</option>`),r?.models?(console.warn(`Falling back to statically configured models due to fetch failure.`),c.disabled=!1,x(r.models)):j(`Could not reach the model server — or proxy configuration is wrong`,5e3)})})}else r?.models&&c?(c.disabled=!1,x(r.models)):c&&(c.disabled=!1,x([]));let S=e.querySelector(`[data-setting="api-key-helper"]`),C=e.querySelector(`[data-setting="provider-select"]`);if(S&&C){let e=C.selectedOptions[0]?.text||`Provider`,t=r?.requiresApiKey!==!1;S.textContent=n===`llamafile`?`Runs local .llamafile binaries through the local proxy. No API key required.`:t?`Enter your ${e} API key. It is encrypted and stored locally.`:`This provider does not require an API key.`}let w=e.querySelector(`[data-setting="api-key-input"]`);if(w){let e=r?.requiresApiKey===!1;w.disabled=e,w.placeholder=e?`No API key required`:`sk-...`}}updateTransformersJsSettingsVisibility(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`[data-setting="transformers-js-settings"]`);n&&(n.style.display=e===`transformers_js_browser`?`block`:`none`)}async onContextCompressionToggle(e){if(!(!this.orchestrator||!this.db))try{await _(this.orchestrator,this.db,e),A(e?`Context compression enabled`:`Context compression disabled`,2500)}catch(e){j(`Error saving context compression setting: `+(e instanceof Error?e.message:String(e)),6e3)}}async onProviderChange(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="provider-select"]`);if(!t)return;let n=t.value,r=this.orchestrator.provider;if(n!==r)try{await S(this.orchestrator,this.db,n,{loadApiKeyForProvider:this.orchestrator.loadApiKeyForProvider.bind(this.orchestrator),getApiKeyForHeaders:()=>m(this.orchestrator)}),this.updateModelSelector(),this.updateMaxTokensUI(),this.updateLlamafileSettingsVisibility(n),this.renderLlamafileSettings(),this.updateLlamafileModeVisibility(),this.updateLlamafileModelSectionVisibility(),this.updateBedrockSettingsVisibility(n),this.updateBedrockSettingsVisibility(n),this.updateMeshLlmSettingsVisibility(n),this.updateTransformersJsSettingsVisibility(n),await this.renderTransformersJsSettings(),A(`Switched to ${t.selectedOptions[0]?.text||n}`,3e3)}catch(e){j(`Error switching provider: `+(e instanceof Error?e.message:String(e)),6e3),t.value=r}}async onStreamingToggle(e){if(!(!this.orchestrator||!this.db))try{await O(this.orchestrator,this.db,e),A(e?`Streaming enabled`:`Streaming disabled`,2500)}catch(e){j(`Error saving streaming setting: `+(e instanceof Error?e.message:String(e)),6e3)}}async render(){let e=this.shadowRoot;if(!e||!this.orchestrator||!this.db)return;this.bindEventListeners();let t=u(),n=this.orchestrator.provider,a=e.querySelector(`[data-setting="provider-select"]`);a&&s(a,t.map(e=>`<option value="${e.id}" ${e.id===n?`selected`:``}>${e.name}</option>`).join(``)),this.updateModelSelector(),this.updateLlamafileSettingsVisibility(n),this.renderLlamafileSettings(),this.updateLlamafileModeVisibility(),this.updateLlamafileModelSectionVisibility(),this.updateModelProviderHelperText(),this.updateBedrockSettingsVisibility(n),this.renderBedrockSettings(),this.updateMeshLlmSettingsVisibility(n),this.renderMeshLlmSettings(),this.updateTransformersJsSettingsVisibility(n),await this.renderTransformersJsSettings(),this.renderBuiltinAiSettings();let c=e.querySelector(`[data-setting="prompt-api-fallback-select"]`);c&&(c.value=await o(this.db,r.PROMPT_API_FALLBACK_MODEL)||`onnx-community/Qwen3-0.6B-ONNX`,this.updateMaxTokensUI(),c.value&&p(c.value).then(()=>{this.updateMaxTokensUI()}).catch(()=>{}));let l=e.querySelector(`[data-setting="prompt-api-device-select"]`);l&&(l.value=await o(this.db,r.PROMPT_API_BACKEND)||`auto`);let d=e.querySelector(`[data-setting="prompt-api-dtype-select"]`);d&&(d.value=await o(this.db,r.PROMPT_API_DTYPE_STRATEGY)||`auto`);let f=e.querySelector(`[data-setting="streaming-toggle"]`);f&&(f.checked=this.orchestrator.streamingEnabled);let m=e.querySelector(`[data-setting="context-compression-toggle"]`);m&&(m.checked=this.orchestrator.contextCompressionEnabled);let h=e.querySelector(`[data-setting="reasoning-effort-select"]`);h&&(h.value=this.orchestrator.reasoningEffort||`none`);let g=e.querySelector(`[data-setting="max-iterations-input"]`);g&&this.orchestrator&&(g.value=String(this.orchestrator.maxIterations));let _=e.querySelector(`[data-setting="subagent-max-parallel-input"]`);if(_){let e=await o(this.db,r.SUBAGENT_MAX_PARALLEL),t=Number(e);_.value=String(Number.isFinite(t)&&t>0?t:5)}let v=e.querySelector(`[data-setting="subagent-workspace-mode-select"]`);if(v){let e=await o(this.db,r.SUBAGENT_WORKSPACE_MODE);v.value=e===`parent`||e===`isolated`||e===`automatic`?e:i}let y=e.querySelector(`[data-setting="rate-limit-calls-per-minute-input"]`);y&&this.orchestrator&&(y.value=String(this.orchestrator.rateLimitCallsPerMinute||0));let b=e.querySelector(`[data-setting="rate-limit-auto-adapt-toggle"]`);b&&this.orchestrator&&(b.checked=this.orchestrator.rateLimitAutoAdapt!==!1),this.updateMaxTokensUI()}async renderBuiltinAiSettings(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="compaction-engine-select"]`),n=e.querySelector(`[data-setting="builtin-ai-tools-backend-select"]`),i=await o(this.db,r.COMPACTION_ENGINE_PREFERENCE),a=await o(this.db,r.BUILTIN_AI_TOOLS_BACKEND);t&&(t.value=i||`auto`),n&&(n.value=a||`active_provider`)}async renderTransformersJsSettings(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let{getConfig:t}=await import(`./getConfig-D89uJgo5.js`).then(e=>e.n),{CONFIG_KEYS:n}=await import(`./config-CrHchneq.js`).then(e=>e.k),r=await t(this.db,n.TRANSFORMERS_JS_BACKEND)||`auto`,i=await t(this.db,n.TRANSFORMERS_JS_DTYPE_STRATEGY)||`auto`,a=e.querySelector(`[data-setting="transformers-js-backend"], [data-setting="transformers-js-device-select"]`);a&&(a.value=r);let o=e.querySelector(`[data-setting="transformers-js-dtype-strategy"], [data-setting="transformers-js-dtype-select"]`);o&&(o.value=i)}async requestAppDialog(e){let t=document.querySelector(`shadow-claw`);return t&&typeof t.requestDialog==`function`?await t.requestDialog(e):!1}async saveApiKey(){if(!this.orchestrator||!this.db){j(`Orchestrator not initialized`,5e3);return}let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="api-key-input"]`),n=e.querySelector(`[data-setting="provider-select"]`);if(!t||!n)return;let r=t.value.trim(),i=n.value;if(u().find(e=>e.id===i)?.requiresApiKey===!1){try{await S(this.orchestrator,this.db,i,{loadApiKeyForProvider:this.orchestrator.loadApiKeyForProvider.bind(this.orchestrator),getApiKeyForHeaders:()=>m(this.orchestrator)}),t.value=``,A(`Provider saved (no API key required)`,3e3)}catch(e){j(`Error saving provider: `+(e instanceof Error?e.message:String(e)),6e3)}return}if(!r){M(`Please enter an API key`,3e3);return}try{await this.orchestrator.setApiKey(this.db,r),t.value=``,A(`API key and provider saved`,3e3)}catch(e){j(`Error saving API key: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveBedrockSettings(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="bedrock-region-input"]`),n=e.querySelector(`[data-setting="bedrock-profile-input"]`),r=e.querySelector(`[data-setting="bedrock-auth-mode"]`);if(!t||!n)return;let i=t.value.trim(),a=n.value.trim(),o=r?.value||`provider_chain`;if(i&&!a||!i&&a){M(`Enter both Bedrock region and profile (or leave both blank to rely on environment variables)`,4e3);return}try{await f(this.orchestrator,this.db,{region:i,profile:a,authMode:o}),A(`Bedrock fallback settings saved`,3e3),this.orchestrator.provider===`bedrock_proxy`&&this.updateModelSelector()}catch(e){j(`Error saving Bedrock fallback settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveBuiltinAiSettings(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="compaction-engine-select"]`),n=e.querySelector(`[data-setting="builtin-ai-tools-backend-select"]`);try{t&&await k(this.db,r.COMPACTION_ENGINE_PREFERENCE,t.value),n&&await k(this.db,r.BUILTIN_AI_TOOLS_BACKEND,n.value),A(`Built-in AI settings saved successfully`,2500)}catch(e){j(`Error saving Built-in AI settings: `+(e instanceof Error?e.message:String(e)),5e3)}}async saveLlamafileSettings(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="llamafile-mode"], [data-setting="llamafile-mode-select"]`),n=e.querySelector(`[data-setting="llamafile-host"], [data-setting="llamafile-host-input"]`),r=e.querySelector(`[data-setting="llamafile-port"], [data-setting="llamafile-port-input"]`),i=e.querySelector(`[data-setting="llamafile-offline"], [data-setting="llamafile-offline-toggle"]`);if(!t||!n||!r||!i)return;let a=t.value===`cli`?`cli`:`server`,o=n.value.trim(),s=parseInt(r.value,10);if(!o){M(`Please enter a host`,3e3);return}if(!Number.isFinite(s)||s<1||s>65535){M(`Please enter a valid port (1-65535)`,3e3);return}try{if(await c(this.orchestrator,this.db,{mode:a,host:o,port:s,offline:i.checked}),this.updateLlamafileModeVisibility(),this.updateLlamafileModelSectionVisibility(),this.updateModelSelector(),this.orchestrator.provider===`llamafile`){A(await E.restartCurrentRequest()?`Llamafile settings saved, request restarted`:`Llamafile settings saved`,3e3);return}A(`Llamafile settings saved`,3e3)}catch(e){j(`Error saving llamafile settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveMaxIterations(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="max-iterations-input"]`);if(!t)return;let n=parseInt(t.value,10);if(!n||n<1){M(`Please enter a valid number (1 or higher)`,3e3);return}try{await y(this.orchestrator,this.db,n),A(`Max iterations saved`,3e3)}catch(e){j(`Error saving max iterations: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveMaxTokens(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="max-tokens-input"]`);if(!t)return;let n=parseInt(t.value,10);if(!n||n<1){M(`Please enter a valid number (1 or higher)`,3e3);return}try{await w(this.orchestrator,this.db,n),this.updateMaxTokensUI(),A(`Max tokens saved`,3e3)}catch(e){j(`Error saving max tokens: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveMeshLlmSettings(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="mesh-llm-host-input"]`);if(!t)return;let n=t.value.trim();try{this.orchestrator&&(await v(this.orchestrator,this.db,{host:n}),A(`Mesh LLM settings saved`,3e3),this.orchestrator.provider===`mesh-llm`&&this.updateModelSelector())}catch(e){j(`Error saving Mesh LLM settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveModel(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="model-select"]`),n=e.querySelector(`[data-setting="custom-model-input"]`);if(!t||!n)return;let i=t.value;if(i===`__custom__`&&(i=n.value.trim()),this.orchestrator.provider===`llamafile`&&l(this.orchestrator).mode===`cli`&&!i){await this.showLlamafileHelpDialog(`Select a discovered *.llamafile model or enter a custom model id that matches a file in the ${g} folder.`);return}if(this.orchestrator.provider===`prompt_api`){let t=e.querySelector(`[data-setting="prompt-api-fallback-select"]`);if(t)try{await k(this.db,r.PROMPT_API_FALLBACK_MODEL,t.value)}catch(e){console.warn(`Error saving prompt api fallback model`,e)}let n=e.querySelector(`[data-setting="prompt-api-device-select"]`);if(n)try{await k(this.db,r.PROMPT_API_BACKEND,n.value)}catch(e){console.warn(`Error saving prompt api backend`,e)}let i=e.querySelector(`[data-setting="prompt-api-dtype-select"]`);if(i)try{await k(this.db,r.PROMPT_API_DTYPE_STRATEGY,i.value)}catch(e){console.warn(`Error saving prompt api dtype strategy`,e)}}try{if(await D(this.orchestrator,this.db,i),this.updateMaxTokensUI(),this.orchestrator.provider===`llamafile`){A(await E.restartCurrentRequest()?`Model saved, request restarted`:`Model saved`,3e3);return}A(`Model saved`,3e3)}catch(e){j(`Error saving model: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveRateLimitSettings(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="rate-limit-calls-per-minute-input"]`),n=e.querySelector(`[data-setting="rate-limit-auto-adapt-toggle"]`);if(!t||!n)return;let r=parseInt(t.value,10);if(!Number.isFinite(r)||r<0){M(`Please enter a valid non-negative calls-per-minute value`,3e3);return}try{await b(this.orchestrator,this.db,r),await x(this.orchestrator,this.db,n.checked),A(`Rate limit settings saved`,3e3)}catch(e){j(`Error saving rate limit settings: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveReasoningEffort(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="reasoning-effort-select"]`);if(t)try{await h(this.orchestrator,this.db,t.value||`none`),A(`Reasoning effort saved`,3e3)}catch(e){j(`Error saving reasoning effort: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveSubagentMaxParallel(){if(!this.db){j(`Database not initialized`,3e3);return}let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="subagent-max-parallel-input"]`);if(!t)return;let n=parseInt(t.value,10);if(!n||n<1){M(`Please enter a valid number (1 or higher)`,3e3);return}try{await k(this.db,r.SUBAGENT_MAX_PARALLEL,String(n)),A(`Subagent limit saved`,3e3)}catch(e){j(`Error saving subagent limit: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveSubagentWorkspaceMode(){if(!this.db){j(`Database not initialized`,3e3);return}let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="subagent-workspace-mode-select"]`);if(!t)return;let n=t.value;if(n!==`automatic`&&n!==`parent`&&n!==`isolated`){M(`Please select a valid subagent workspace mode`,3e3);return}try{await k(this.db,r.SUBAGENT_WORKSPACE_MODE,n),A(`Subagent workspace mode saved`,3e3)}catch(e){j(`Error saving subagent workspace mode: `+(e instanceof Error?e.message:String(e)),6e3)}}async saveTransformersJsSettings(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="transformers-js-backend"], [data-setting="transformers-js-device-select"]`)?.value||`auto`,n=e.querySelector(`[data-setting="transformers-js-dtype-strategy"], [data-setting="transformers-js-dtype-select"]`)?.value||`auto`,{setConfig:r}=await import(`./setConfig-DFMYnYLE.js`).then(e=>e.n),{CONFIG_KEYS:i}=await import(`./config-CrHchneq.js`).then(e=>e.k);await r(this.db,i.TRANSFORMERS_JS_BACKEND,t),await r(this.db,i.TRANSFORMERS_JS_DTYPE_STRATEGY,n),A(`Transformers.js settings saved.`)}async showLlamafileHelpDialog(e){let t=`${e||``}|${this.orchestrator?.model||``}`;this.lastLlamafileHelpKey!==t&&(this.lastLlamafileHelpKey=t,await this.requestAppDialog(C(e)))}};customElements.get(q)||customElements.define(q,J);export{J as ShadowClawLlm};
|
package/dist/public/{shadow-claw-mcp-remote-BzZoz4LX.js → shadow-claw-mcp-remote-Bkx0gsmF.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b.js";import{t as n}from"./getConfig-D89uJgo5.js";import{m as r,u as i}from"./custom-element-security-
|
|
1
|
+
import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b.js";import{t as n}from"./getConfig-D89uJgo5.js";import{m as r,u as i}from"./custom-element-security-FU04Cq05.js";import{r as a}from"./crypto-C8c5wMzN.js";import{a as o,l as s,o as c,s as l,t as u,u as d}from"./mcp-reconnect-9emsqGRe.js";import{a as f,r as p}from"./toast-BXgUfbyh.js";import{t as m}from"./shadow-claw-element-DIrv3P6A.js";import"./shadow-claw-card-DCxWEHgX.js";import"./shadow-claw-empty-state-Bl52dGQ0.js";const h=new CSSStyleSheet;h.replaceSync(`*,
|
|
2
2
|
*::before,
|
|
3
3
|
*::after {
|
|
4
4
|
font-family: var(--shadow-claw-font-sans);
|
|
@@ -435,4 +435,4 @@ select.form-input {
|
|
|
435
435
|
<button class="cancel-btn" data-action="cancel-connection-form">Cancel</button>
|
|
436
436
|
</div>
|
|
437
437
|
</div>
|
|
438
|
-
`),c.querySelector(`[data-action="save-connection"]`)?.addEventListener(`click`,()=>void this.saveConnectionForm()),c.querySelector(`[data-action="cancel-connection-form"]`)?.addEventListener(`click`,()=>this.hideConnectionForm()),c.querySelector(`[data-field="auth-selection"]`)?.addEventListener(`change`,()=>this.updateAuthFieldsVisibility(c)),this.updateAuthFieldsVisibility(c))}updateAuthFieldsVisibility(e){let t=e.querySelector(`[data-field="auth-selection"]`)?.value,n=e.querySelector(`[data-region="service-account-region"]`),r=e.querySelector(`[data-region="git-account-region"]`),i=e.querySelector(`[data-region="custom-header-region"]`),a=e.querySelector(`[data-region="auto-reconnect-region"]`),o=t===`service_pat`||t===`service_oauth`,s=t===`git_pat`||t===`git_oauth`,c=t===`custom_header`,l=t===`service_oauth`||t===`git_oauth`;n instanceof HTMLElement&&(n.style.display=o?`block`:`none`),r instanceof HTMLElement&&(r.style.display=s?`block`:`none`),i instanceof HTMLElement&&(i.style.display=c?`block`:`none`),a instanceof HTMLElement&&(a.style.display=l?`flex`:`none`)}async buildCredentialRef(e,t,n){if(t===`none`)return null;if(t===`service_pat`||t===`service_oauth`){let n=e.querySelector(`[data-field="service-account-id"]`)?.value;if(!n)throw Error(`Select a service account for this authentication mode.`);return{serviceType:`mcp_remote`,authType:t===`service_oauth`?`oauth`:`token`,providerId:`custom_mcp`,accountId:n}}if(t===`git_pat`||t===`git_oauth`){let n=e.querySelector(`[data-field="git-account-id"]`)?.value;if(!n)throw Error(`Select a git account for this authentication mode.`);return{serviceType:`mcp_remote`,authType:t===`git_oauth`?`oauth`:`token`,providerId:`custom_mcp`,gitAccountId:n}}let r=e.querySelector(`[data-field="custom-header-name"]`)?.value.trim(),i=e.querySelector(`[data-field="custom-header-value"]`)?.value.trim();if(!r)throw Error(`Header name is required for custom header authentication.`);let
|
|
438
|
+
`),c.querySelector(`[data-action="save-connection"]`)?.addEventListener(`click`,()=>void this.saveConnectionForm()),c.querySelector(`[data-action="cancel-connection-form"]`)?.addEventListener(`click`,()=>this.hideConnectionForm()),c.querySelector(`[data-field="auth-selection"]`)?.addEventListener(`change`,()=>this.updateAuthFieldsVisibility(c)),this.updateAuthFieldsVisibility(c))}updateAuthFieldsVisibility(e){let t=e.querySelector(`[data-field="auth-selection"]`)?.value,n=e.querySelector(`[data-region="service-account-region"]`),r=e.querySelector(`[data-region="git-account-region"]`),i=e.querySelector(`[data-region="custom-header-region"]`),a=e.querySelector(`[data-region="auto-reconnect-region"]`),o=t===`service_pat`||t===`service_oauth`,s=t===`git_pat`||t===`git_oauth`,c=t===`custom_header`,l=t===`service_oauth`||t===`git_oauth`;n instanceof HTMLElement&&(n.style.display=o?`block`:`none`),r instanceof HTMLElement&&(r.style.display=s?`block`:`none`),i instanceof HTMLElement&&(i.style.display=c?`block`:`none`),a instanceof HTMLElement&&(a.style.display=l?`flex`:`none`)}async buildCredentialRef(e,t,n){if(t===`none`)return null;if(t===`service_pat`||t===`service_oauth`){let n=e.querySelector(`[data-field="service-account-id"]`)?.value;if(!n)throw Error(`Select a service account for this authentication mode.`);return{serviceType:`mcp_remote`,authType:t===`service_oauth`?`oauth`:`token`,providerId:`custom_mcp`,accountId:n}}if(t===`git_pat`||t===`git_oauth`){let n=e.querySelector(`[data-field="git-account-id"]`)?.value;if(!n)throw Error(`Select a git account for this authentication mode.`);return{serviceType:`mcp_remote`,authType:t===`git_oauth`?`oauth`:`token`,providerId:`custom_mcp`,gitAccountId:n}}let r=e.querySelector(`[data-field="custom-header-name"]`)?.value.trim(),i=e.querySelector(`[data-field="custom-header-value"]`)?.value.trim();if(!r)throw Error(`Header name is required for custom header authentication.`);let o;if(i&&(o=await a(i)||void 0),!o)if(n?.credentialRef?.authType===`custom_header`&&n.credentialRef.encryptedValue)o=n.credentialRef.encryptedValue;else throw Error(`Header value is required for custom header authentication.`);return{serviceType:`mcp_remote`,authType:`custom_header`,providerId:`custom_mcp`,headerName:r,encryptedValue:o}}async deleteConnection(e){if(this.db)try{if(!await l(this.db,e)){p(`Remote MCP connection not found.`,4e3);return}await this.render(),this.editingConnectionId===e&&this.hideConnectionForm(),f(`Remote MCP connection deleted`,3e3)}catch(e){p(`Failed to delete remote MCP connection: ${e instanceof Error?e.message:String(e)}`,6e3)}}async reconnectOAuth(e){if(!this.db)return;let t=this.connections.find(t=>t.id===e)?.label||e,n=await u(this.db,e);n.success?f(`OAuth reconnected for "${t}"`,4e3):p(`OAuth reconnect failed: ${n.error}`,6e3)}async render(){if(!(!this.shadowRoot||!this.db))try{this.connections=await s(this.db);let t=await n(this.db,e.SERVICE_ACCOUNTS);this.serviceAccounts=Array.isArray(t)?t:[];let r=await n(this.db,e.GIT_ACCOUNTS);this.gitAccounts=Array.isArray(r)?r:[],this.renderConnectionList()}catch(e){console.warn(`Could not load remote MCP connections:`,e)}}async saveConnectionForm(){if(!this.db)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-region="connection-form-slot"]`);if(!t)return;let n=t.querySelector(`[data-field="connection-label"]`)?.value.trim(),r=t.querySelector(`[data-field="connection-url"]`)?.value.trim(),i=t.querySelector(`[data-field="connection-transport"]`)?.value,a=t.querySelector(`[data-field="connection-enabled"]`)?.checked,o=t.querySelector(`[data-field="connection-auto-reconnect"]`)?.checked,s=t.querySelector(`[data-field="auth-selection"]`)?.value;if(!n||!r){p(`Connection label and server URL are required.`,4e3);return}let l=this.editingConnectionId===`new`,u=l?null:this.connections.find(e=>e.id===this.editingConnectionId)||null;try{let e=await d(this.db,{id:l?void 0:u?.id,label:n,serviceType:`mcp_remote`,serverUrl:r,transport:i,enabled:a,autoReconnectOAuth:o}),p=await this.buildCredentialRef(t,s,u);await c(this.db,e.id,p),await this.render(),this.hideConnectionForm(),f(l?`Remote MCP connection added`:`Remote MCP connection updated`,3e3)}catch(e){p(`Failed to save remote MCP connection: ${e instanceof Error?e.message:String(e)}`,6e3)}}async testConnection(e){if(!this.db)return;let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`.connection-card[data-connection-id="${e}"]`),r=n?.querySelector(`.connection-diagnostic`);r&&r.remove();let i=document.createElement(`div`);i.className=`connection-diagnostic`;let a=document.createElement(`div`);a.className=`diagnostic-loading`,a.textContent=`Testing connection…`,i.appendChild(a),n?.appendChild(i);let s=await o(this.db,e);this.renderDiagnostic(i,s)}};customElements.get(b)||customElements.define(b,x);export{x as ShadowClawMcpRemote};
|
package/dist/public/{shadow-claw-networking-DLEd9cNm.js → shadow-claw-networking-Dd8Rw31D.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e}from"./txPromise-EBECky1b.js";import{
|
|
1
|
+
import{n as e}from"./txPromise-EBECky1b.js";import{m as t,t as n,x as r}from"./orchestrator-DHjdLtqa.js";import{a as i,r as a,s as o}from"./toast-BXgUfbyh.js";import{t as s}from"./shadow-claw-element-DIrv3P6A.js";import{t as c}from"./effect-BJCrpFdp.js";const l=new CSSStyleSheet;l.replaceSync(`*,
|
|
2
2
|
*::before,
|
|
3
3
|
*::after {
|
|
4
4
|
font-family: var(--shadow-claw-font-sans);
|
|
@@ -131,4 +131,4 @@ import{n as e}from"./txPromise-EBECky1b.js";import{a as t,r as n,s as r}from"./t
|
|
|
131
131
|
</div>
|
|
132
132
|
</div>
|
|
133
133
|
</template>
|
|
134
|
-
`,`text/html`),d=u.querySelector(`template`);let f=[];f=d?Array.from(d.content.children):Array.from(u.head.children).concat(Array.from(u.body.children));var p=f;const m=`shadow-claw-networking`;var h=class extends s{static styles=l;static template=p;db;orchestrator;constructor(){super(),this.db=null,this.orchestrator=null}async connectedCallback(){if(!this.shadowRoot)throw Error(`shadowRoot not found`);this.db=await e(),this.orchestrator=
|
|
134
|
+
`,`text/html`),d=u.querySelector(`template`);let f=[];f=d?Array.from(d.content.children):Array.from(u.head.children).concat(Array.from(u.body.children));var p=f;const m=`shadow-claw-networking`;var h=class extends s{static styles=l;static template=p;db;orchestrator;constructor(){super(),this.db=null,this.orchestrator=null}async connectedCallback(){if(!this.shadowRoot)throw Error(`shadowRoot not found`);this.db=await e(),this.orchestrator=n.orchestrator,this.bindEventListeners(),this.setupEffects(),await this.render()}bindEventListeners(){let e=this.shadowRoot;e&&(e.querySelector(`[data-setting="proxy-toggle"]`)?.addEventListener(`change`,e=>{e.target instanceof HTMLInputElement&&this.onProxyToggle(e.target.checked)}),e.querySelector(`[data-action="save-proxy-url"]`)?.addEventListener(`click`,()=>{this.saveProxyUrl()}))}setupEffects(){c(()=>{n.ready&&(this.orchestrator=n.orchestrator,this.render())})}async onProxyToggle(e){if(!(!this.orchestrator||!this.db))try{await r(this.orchestrator,this.db,e),i(e?`CORS Proxy enabled`:`CORS Proxy disabled`,2500)}catch(e){a(`Error saving proxy setting: `+(e instanceof Error?e.message:String(e)),6e3)}}async render(){if(!this.orchestrator)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-setting="proxy-toggle"]`);t&&(t.checked=this.orchestrator.useProxy);let n=e.querySelector(`[data-setting="proxy-url-input"]`);n&&(n.value=this.orchestrator.proxyUrl)}async saveProxyUrl(){if(!this.orchestrator||!this.db)return;let e=this.shadowRoot;if(!e)return;let n=e.querySelector(`[data-setting="proxy-url-input"]`);if(!n)return;let r=n.value.trim();if(!r){o(`Please enter a proxy URL (e.g. /proxy)`,3e3);return}try{await t(this.orchestrator,this.db,r),i(`Proxy URL saved`,3e3)}catch(e){a(`Error saving proxy URL: `+(e instanceof Error?e.message:String(e)),6e3)}}};customElements.get(m)||customElements.define(m,h);export{h as ShadowClawNetworking};
|
package/dist/public/{shadow-claw-notifications-1vwR7TbT.js → shadow-claw-notifications-Dbevj-lq.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b.js";import{t as n}from"./getConfig-D89uJgo5.js";import{
|
|
1
|
+
import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b.js";import{t as n}from"./getConfig-D89uJgo5.js";import{t as r}from"./setConfig-DFMYnYLE.js";import{a as i,i as a,n as o,r as s,t as c}from"./push-client-D0lkwrK0.js";import{a as l,r as u}from"./toast-BXgUfbyh.js";import{t as d}from"./shadow-claw-element-DIrv3P6A.js";import"./shadow-claw-empty-state-Bl52dGQ0.js";const f=new CSSStyleSheet;f.replaceSync(`*,
|
|
2
2
|
*::before,
|
|
3
3
|
*::after {
|
|
4
4
|
font-family: var(--shadow-claw-font-sans);
|
|
@@ -250,4 +250,4 @@ import{r as e}from"./config-CrHchneq.js";import{n as t}from"./txPromise-EBECky1b
|
|
|
250
250
|
</div>
|
|
251
251
|
</div>
|
|
252
252
|
</template>
|
|
253
|
-
`,`text/html`),m=p.querySelector(`template`);let h=[];h=m?Array.from(m.content.children):Array.from(p.head.children).concat(Array.from(p.body.children));var g=h,_=class extends d{static styles=f;static template=g;_backendAvailable=!0;_selectedId=null;_subscribed=!1;_subscriptions=[];constructor(){super()}async connectedCallback(){if(!this.shadowRoot)throw Error(`shadowRoot not found`);await this.refreshState(),await this.loadProxyConfig(),await this.loadSubscriptions(),this.bindEventListeners()}bindEventListeners(){let e=this.shadowRoot;e&&(e.querySelector(`[data-action="toggle-push"]`)?.addEventListener(`click`,()=>this.handleToggle()),e.querySelector(`[data-action="send-notification"]`)?.addEventListener(`click`,()=>this.handleSendNotification()),e.querySelector(`[data-action="delete-subscription"]`)?.addEventListener(`click`,()=>this.handleDeleteSubscription()),e.querySelector(`[data-action="refresh-subscriptions"]`)?.addEventListener(`click`,()=>this.loadSubscriptions()),e.querySelector(`[data-input="push-proxy-url"]`)?.addEventListener(`change`,e=>this.handleProxyUrlChange(e)))}renderSubscriptionList(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-info="subscription-list"]`);if(t){if(t.replaceChildren(),this._subscriptions.length===0){let e=this._backendAvailable?`No subscriptions stored.`:`⚠️ Backend services unavailable (push notification server is not running).`,n=document.createElement(`shadow-claw-empty-state`);n.setAttribute(`compact`,``),n.setAttribute(`message`,e),t.append(n);return}this._subscriptions.forEach(e=>{let n=`#${e.id}`,r=e.endpoint.length>60?`…${e.endpoint.slice(-56)}`:e.endpoint,i=e.created_at||``,a=document.createElement(`div`);a.className=`subscription-item${this._selectedId===e.id?` selected`:``}`,a.setAttribute(`data-sub-id`,String(e.id)),a.setAttribute(`data-endpoint`,e.endpoint);let o=document.createElement(`span`);o.className=`subscription-id`,o.title=e.endpoint,o.textContent=`${n} ${r}`;let s=document.createElement(`span`);s.className=`subscription-date`,s.textContent=i,a.append(o,s),a.addEventListener(`click`,()=>{this._selectedId=e.id,this.renderSubscriptionList(),this.updateActionButtons()}),t.append(a)})}}updateActionButtons(){let e=this.shadowRoot;if(!e)return;let t=this._selectedId!=null,n=e.querySelector(`[data-action="send-notification"]`),r=e.querySelector(`[data-action="delete-subscription"]`);n&&(n.disabled=!t),r&&(r.disabled=!t)}updateToggle(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-action="toggle-push"]`),n=e.querySelector(`[data-info="subscription-status"]`);t&&t.setAttribute(`aria-checked`,String(this._subscribed)),n&&(n.textContent=this._subscribed?`Enabled`:`Disabled`)}async handleDeleteSubscription(){if(this._selectedId!=null)try{let e=await
|
|
253
|
+
`,`text/html`),m=p.querySelector(`template`);let h=[];h=m?Array.from(m.content.children):Array.from(p.head.children).concat(Array.from(p.body.children));var g=h,_=class extends d{static styles=f;static template=g;_backendAvailable=!0;_selectedId=null;_subscribed=!1;_subscriptions=[];constructor(){super()}async connectedCallback(){if(!this.shadowRoot)throw Error(`shadowRoot not found`);await this.refreshState(),await this.loadProxyConfig(),await this.loadSubscriptions(),this.bindEventListeners()}bindEventListeners(){let e=this.shadowRoot;e&&(e.querySelector(`[data-action="toggle-push"]`)?.addEventListener(`click`,()=>this.handleToggle()),e.querySelector(`[data-action="send-notification"]`)?.addEventListener(`click`,()=>this.handleSendNotification()),e.querySelector(`[data-action="delete-subscription"]`)?.addEventListener(`click`,()=>this.handleDeleteSubscription()),e.querySelector(`[data-action="refresh-subscriptions"]`)?.addEventListener(`click`,()=>this.loadSubscriptions()),e.querySelector(`[data-input="push-proxy-url"]`)?.addEventListener(`change`,e=>this.handleProxyUrlChange(e)))}renderSubscriptionList(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-info="subscription-list"]`);if(t){if(t.replaceChildren(),this._subscriptions.length===0){let e=this._backendAvailable?`No subscriptions stored.`:`⚠️ Backend services unavailable (push notification server is not running).`,n=document.createElement(`shadow-claw-empty-state`);n.setAttribute(`compact`,``),n.setAttribute(`message`,e),t.append(n);return}this._subscriptions.forEach(e=>{let n=`#${e.id}`,r=e.endpoint.length>60?`…${e.endpoint.slice(-56)}`:e.endpoint,i=e.created_at||``,a=document.createElement(`div`);a.className=`subscription-item${this._selectedId===e.id?` selected`:``}`,a.setAttribute(`data-sub-id`,String(e.id)),a.setAttribute(`data-endpoint`,e.endpoint);let o=document.createElement(`span`);o.className=`subscription-id`,o.title=e.endpoint,o.textContent=`${n} ${r}`;let s=document.createElement(`span`);s.className=`subscription-date`,s.textContent=i,a.append(o,s),a.addEventListener(`click`,()=>{this._selectedId=e.id,this.renderSubscriptionList(),this.updateActionButtons()}),t.append(a)})}}updateActionButtons(){let e=this.shadowRoot;if(!e)return;let t=this._selectedId!=null,n=e.querySelector(`[data-action="send-notification"]`),r=e.querySelector(`[data-action="delete-subscription"]`);n&&(n.disabled=!t),r&&(r.disabled=!t)}updateToggle(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-action="toggle-push"]`),n=e.querySelector(`[data-info="subscription-status"]`);t&&t.setAttribute(`aria-checked`,String(this._subscribed)),n&&(n.textContent=this._subscribed?`Enabled`:`Disabled`)}async handleDeleteSubscription(){if(this._selectedId!=null)try{let e=await s(`/push/subscription/${this._selectedId}`);(await fetch(e,o(e,{method:`DELETE`}))).ok?(l(`Subscription deleted.`),await this.loadSubscriptions()):u(`Failed to delete subscription.`)}catch(e){u(`Delete failed: ${e.message}`)}}async handleProxyUrlChange(n){let i=n.target.value.trim();try{await r(await t(),e.PUSH_PROXY_URL,i),l(`Push proxy URL updated.`),await this.loadSubscriptions()}catch(e){u(`Failed to save proxy URL: ${e.message}`)}}async handleSendNotification(){if(this._selectedId==null)return;let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`[data-input="notification-text"]`)?.value?.trim()||`Test notification from ShadowClaw`,n=this._subscriptions.find(e=>e.id===this._selectedId);if(n)try{let e=await s(`/push/send`),r=await fetch(e,o(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({endpoint:n.endpoint,payload:t})}));r.ok?l(`Notification sent!`):r.status===410?(u(`Subscription expired and was removed.`),await this.loadSubscriptions()):u(`Failed to send: ${(await r.json().catch(()=>({}))).error||r.statusText}`)}catch(e){u(`Send failed: ${e.message}`)}}async handleToggle(){try{this._subscribed?(await i(),this._subscribed=!1,l(`Push notifications disabled.`)):(await a(),this._subscribed=!0,l(`Push notifications enabled!`)),this.updateToggle(),await this.loadSubscriptions()}catch(e){u(`Push notification error: ${e.message}`)}}async loadProxyConfig(){let r=this.shadowRoot;if(!r)return;let i=await n(await t(),e.PUSH_PROXY_URL),a=r.querySelector(`[data-input="push-proxy-url"]`);a&&(a.value=i||``)}async loadSubscriptions(){if(this.shadowRoot){try{let r=typeof location<`u`&&(location.protocol===`file:`||location.hostname.endsWith(`.github.io`)||location.hostname.endsWith(`.pages.dev`)),i=await n(await t(),e.PUSH_PROXY_URL)||(typeof localStorage<`u`?localStorage.getItem(e.PUSH_PROXY_URL):null);if(r&&!i){this._subscriptions=[],this._backendAvailable=!1,this._selectedId=null,this.renderSubscriptionList(),this.updateActionButtons();return}let a=await s(`/push/subscriptions`),c=await fetch(a,o(a));if(!c.ok){this._subscriptions=[],this._backendAvailable=!1,this._selectedId=null,this.renderSubscriptionList(),this.updateActionButtons();return}this._subscriptions=await c.json(),this._backendAvailable=!0}catch{this._subscriptions=[],this._backendAvailable=!1}this._selectedId=null,this.renderSubscriptionList(),this.updateActionButtons()}}async refreshState(){try{let e=await c();this._subscribed=!!e,this.updateToggle()}catch{this._subscribed=!1,this.updateToggle()}}};customElements.define(`shadow-claw-notifications`,_);export{_ as ShadowClawNotifications};
|
package/dist/public/{shadow-claw-page-header-DMKbkv3s.js → shadow-claw-page-header-BccSHItx.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{u as e}from"./custom-element-security-
|
|
1
|
+
import{u as e}from"./custom-element-security-FU04Cq05.js";import{t}from"./shadow-claw-element-DIrv3P6A.js";const n=new CSSStyleSheet;n.replaceSync(`*,
|
|
2
2
|
*::before,
|
|
3
3
|
*::after {
|
|
4
4
|
box-sizing: border-box;
|