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
package/dist/lib/{shadow-claw-accounts-CdruwN8A.js.map → shadow-claw-accounts-03oJ__XC.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-claw-accounts-CdruwN8A.js","names":["shadowClawAccountsStyles","shadowClawAccountsTemplate"],"sources":["../../src/components/settings/shadow-claw-accounts/utils/resolveAccountAuthMode.ts","../../src/components/settings/shadow-claw-accounts/shadow-claw-accounts.ts"],"sourcesContent":["import type { ServiceAccount } from \"../../../../subsystems/accounts/service-accounts.js\";\n\nexport function resolveAccountAuthMode(\n account: ServiceAccount | null,\n): \"token\" | \"basic\" | \"oauth\" {\n if (!account) {\n return \"token\";\n }\n\n if (\n account.authMode === \"token\" ||\n (account.authMode as string) === \"token\"\n ) {\n return \"token\";\n }\n\n if (account.authMode === \"basic\") {\n return \"basic\";\n }\n\n if (account.authMode === \"oauth\") {\n return \"oauth\";\n }\n\n if (\n account.oauthProviderId ||\n account.oauthClientId ||\n account.oauthClientSecret ||\n account.refreshToken ||\n account.accessTokenExpiresAt ||\n account.tokenType ||\n account.oauthReauthRequired\n ) {\n return \"oauth\";\n }\n\n return \"token\";\n}\n","import {\n CONFIG_KEYS,\n OAUTH_PROVIDER_DEFINITIONS,\n} from \"../../../config/config.js\";\n\nimport { getDb, type ShadowClawDatabase } from \"../../../db/db.js\";\nimport { getConfig } from \"../../../db/getConfig.js\";\nimport { setSanitizedHtml } from \"../../../security/trusted-types.js\";\nimport { showError, showSuccess } from \"../../../ui/toast.js\";\nimport { escapeHtml } from \"../../../utils/utils.js\";\nimport { resolveAccountAuthMode } from \"./utils/resolveAccountAuthMode.js\";\n\nimport type { ServiceAccount } from \"../../../subsystems/accounts/service-accounts.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\n\nimport \"../../common/shadow-claw-actions/shadow-claw-actions.js\";\nimport \"../../common/shadow-claw-card/shadow-claw-card.js\";\nimport \"../../common/shadow-claw-empty-state/shadow-claw-empty-state.js\";\nimport shadowClawAccountsStyles from \"./shadow-claw-accounts.css\" with { type: \"css\" };\nimport shadowClawAccountsTemplate from \"./shadow-claw-accounts.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-accounts\";\n\nexport class ShadowClawAccounts extends ShadowClawElement {\n static styles = shadowClawAccountsStyles;\n static template = shadowClawAccountsTemplate;\n\n accounts: ServiceAccount[] = [];\n db: ShadowClawDatabase | null = null;\n defaultAccountId = \"\";\n editingAccountId: string | null = null;\n pendingOauthResult: {\n providerId: string;\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n scope?: string;\n tokenType?: string;\n } | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n this.db = await getDb();\n\n await this.render();\n\n this.bindEventListeners();\n }\n\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"add-account\"]')\n ?.addEventListener(\"click\", () => this.showAccountForm(\"new\"));\n\n root\n .querySelector('[data-region=\"account-list\"]')\n ?.addEventListener(\"settings-action\", (event) => {\n const detail = (event as CustomEvent<{ action: string; id: string }>)\n .detail;\n const { action, id } = detail || { action: \"\", id: \"\" };\n\n if (!id) {\n return;\n }\n\n if (action === \"edit-account\") {\n this.showAccountForm(id);\n } else if (action === \"delete-account\") {\n void this.deleteAccount(id);\n } else if (action === \"set-default\") {\n void this.setDefaultAccount(id);\n }\n });\n }\n\n hideAccountForm() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const slot = root.querySelector('[data-region=\"account-form-slot\"]');\n if (slot) {\n slot.replaceChildren();\n }\n }\n\n renderAccountList() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const listEl = root.querySelector('[data-region=\"account-list\"]');\n if (!listEl) {\n return;\n }\n\n listEl.replaceChildren();\n\n if (this.accounts.length === 0) {\n const emptyState = document.createElement(\"shadow-claw-empty-state\");\n emptyState.setAttribute(\"message\", \"No additional accounts configured.\");\n emptyState.setAttribute(\n \"hint\",\n \"Click '+ Add Non-Git Account' to get started.\",\n );\n listEl.append(emptyState);\n\n return;\n }\n\n const fragment = document.createDocumentFragment();\n\n this.accounts.forEach((acct) => {\n const isDefault = acct.id === this.defaultAccountId;\n const hasToken = !!acct.token;\n const authMode = resolveAccountAuthMode(acct);\n const needsReauth = authMode === \"oauth\" && !!acct.oauthReauthRequired;\n const authLabel =\n authMode === \"oauth\"\n ? `OAuth${acct.oauthProviderId ? ` (${acct.oauthProviderId})` : \"\"}`\n : authMode === \"basic\"\n ? \"Basic Auth\"\n : \"Token\";\n const credentialLabel = hasToken\n ? authMode === \"oauth\"\n ? needsReauth\n ? \"Reconnect required\"\n : \"OAuth token saved\"\n : \"Token saved\"\n : \"No token\";\n const cardMeta = `${acct.service} · ${acct.hostPattern} · ${authLabel} · ${credentialLabel}`;\n\n const card = document.createElement(\"shadow-claw-card\");\n card.setAttribute(\"data-account-id\", acct.id);\n card.setAttribute(\"label\", acct.label);\n card.setAttribute(\"meta\", cardMeta);\n if (isDefault) {\n card.setAttribute(\"highlight\", \"\");\n card.setAttribute(\"badge\", \"Default\");\n }\n\n const actions = document.createElement(\"shadow-claw-actions\");\n actions.setAttribute(\"slot\", \"actions\");\n actions.setAttribute(\"kind\", \"account\");\n actions.setAttribute(\"item-id\", acct.id);\n if (isDefault) {\n actions.setAttribute(\"is-default\", \"\");\n }\n\n card.append(actions);\n fragment.append(card);\n });\n\n listEl.append(fragment);\n }\n\n showAccountForm(accountId: string) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n this.editingAccountId = accountId;\n this.pendingOauthResult = null;\n const isNew = accountId === \"new\";\n const existing = isNew\n ? null\n : this.accounts.find((account) => account.id === accountId);\n const selectedAuthMode = resolveAccountAuthMode(existing || null);\n const oauthProviderId =\n existing?.oauthProviderId &&\n OAUTH_PROVIDER_DEFINITIONS[existing.oauthProviderId]\n ? existing.oauthProviderId\n : \"github\";\n const oauthScope = existing?.scopes?.join(\" \") || \"\";\n const oauthProviderOptions = Object.values(OAUTH_PROVIDER_DEFINITIONS)\n .map(\n (provider) =>\n `<option value=\"${provider.id}\"${provider.id === oauthProviderId ? \" selected\" : \"\"}>${escapeHtml(provider.name)}</option>`,\n )\n .join(\"\");\n\n const slot = root.querySelector('[data-region=\"account-form-slot\"]');\n if (!slot) {\n return;\n }\n\n setSanitizedHtml(\n slot,\n `\n <div class=\"account-form\">\n <h4>${isNew ? \"Add Account\" : \"Edit Account\"}</h4>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Label</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-label\"\n placeholder=\"e.g. Design Team Figma\"\n value=\"${escapeHtml(existing?.label || \"\")}\" />\n <div class=\"form-helper\">A friendly name to identify this account.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Service</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-service\"\n placeholder=\"e.g. Figma\"\n value=\"${escapeHtml(existing?.service || \"\")}\" />\n <div class=\"form-helper\">The external service this token belongs to.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Host Pattern</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-host\"\n placeholder=\"e.g. figma.com or api.figma.com\"\n value=\"${escapeHtml(existing?.hostPattern || \"\")}\" />\n <div class=\"form-helper\">Used to identify the service endpoint or host.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Auth Mode</label>\n <select class=\"form-input\" data-field=\"acct-auth-mode\">\n <option value=\"token\"${selectedAuthMode === \"token\" ? \" selected\" : \"\"}>Token (PAT)</option>\n <option value=\"basic\"${selectedAuthMode === \"basic\" ? \" selected\" : \"\"}>Basic Auth</option>\n <option value=\"oauth\"${selectedAuthMode === \"oauth\" ? \" selected\" : \"\"}>OAuth</option>\n </select>\n <div class=\"form-helper\">Use Token for generic tokens, Basic for user/password, or OAuth for provider-managed access.</div>\n </div>\n\n <div class=\"oauth-fields\" data-region=\"oauth-fields\">\n <div class=\"form-group\">\n <label class=\"form-label\">OAuth Provider</label>\n <select class=\"form-input\" data-field=\"acct-oauth-provider\">${oauthProviderOptions}</select>\n </div>\n\n <div class=\"custom-mcp-oauth-fields\" data-region=\"custom-mcp-oauth-fields\">\n <div class=\"form-group\">\n <label class=\"form-label\">Authorize URL</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-authorize-url\" value=\"${escapeHtml(existing?.oauthCustomAuthorizeUrl || \"\")}\" placeholder=\"https://example.com/oauth/authorize\" />\n <div class=\"form-helper\">The OAuth authorization endpoint of the MCP server.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Token URL</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-token-url\" value=\"${escapeHtml(existing?.oauthCustomTokenUrl || \"\")}\" placeholder=\"https://example.com/oauth/token\" />\n <div class=\"form-helper\">The OAuth token exchange endpoint of the MCP server.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">\n <input type=\"checkbox\" data-field=\"acct-oauth-use-pkce\" ${existing?.oauthCustomUsePkce !== false ? \"checked\" : \"\"} />\n Use PKCE (S256)\n </label>\n <div class=\"form-helper\">Most servers require PKCE. Uncheck only if the server doesn't support it.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Redirect URI</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-redirect-uri\" value=\"${escapeHtml(existing?.oauthCustomRedirectUri || \"\")}\" placeholder=\"https://localhost/callback\" />\n <div class=\"form-helper\">Must match the redirect URI registered with the OAuth server. Leave blank to use default.</div>\n </div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">OAuth Client ID</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-client-id\" value=\"${escapeHtml(existing?.oauthClientId || \"\")}\" placeholder=\"Enter provider OAuth app client ID\" />\n <div class=\"form-helper\">Required for OAuth connect. Register an OAuth app with the selected provider first.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">OAuth Client Secret (if required)</label>\n <input type=\"password\" class=\"form-input\" data-field=\"acct-oauth-client-secret\" placeholder=\"${existing?.oauthClientSecret ? \"•••••••••••• (Saved)\" : \"Enter client secret if provider requires it\"}\" />\n <div class=\"form-helper\">Stored encrypted locally. Needed by some providers for token exchange/refresh.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">OAuth Scope (if required)</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-scope\" value=\"${escapeHtml(oauthScope)}\" placeholder=\"space-separated scopes\" />\n <div class=\"form-helper\">Leave blank to use provider defaults.</div>\n </div>\n\n <div class=\"form-group oauth-connect-row\">\n <button class=\"confirm-btn oauth-connect-btn\" data-action=\"connect-oauth\" type=\"button\">Connect OAuth</button>\n <span class=\"oauth-status\" data-region=\"oauth-status\">${selectedAuthMode === \"oauth\" && existing?.oauthReauthRequired ? \"Reconnect required\" : selectedAuthMode === \"oauth\" && existing?.token ? \"OAuth token already saved\" : \"Not connected\"}</span>\n </div>\n </div>\n\n <div class=\"form-group\" data-region=\"basic-username-field\">\n <label class=\"form-label\">Username or Email</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-basic-username\"\n placeholder=\"e.g. user@example.com\"\n value=\"${escapeHtml(existing?.basicUsername || \"\")}\" />\n <div class=\"form-helper\">Required for Basic Auth.</div>\n </div>\n\n <div class=\"form-group\" data-region=\"pat-fields\">\n <label class=\"form-label\" data-region=\"pat-label\">Access Token</label>\n <input type=\"password\" class=\"form-input\" data-field=\"acct-token\"\n placeholder=\"${existing?.token ? \"•••••••••••• (Saved)\" : \"Paste Token\"}\" />\n <div class=\"form-helper\">Stored encrypted locally. Leave blank to keep the existing token.</div>\n </div>\n\n <div class=\"account-form-actions\">\n <button class=\"confirm-btn\" data-action=\"save-account\">\n ${isNew ? \"Add Account\" : \"Update Account\"}\n </button>\n <button class=\"cancel-btn\" data-action=\"cancel-account-form\">Cancel</button>\n </div>\n </div>`,\n );\n\n slot\n .querySelector('[data-action=\"save-account\"]')\n ?.addEventListener(\"click\", () => void this.saveAccountForm());\n slot\n .querySelector('[data-action=\"cancel-account-form\"]')\n ?.addEventListener(\"click\", () => this.hideAccountForm());\n slot\n .querySelector('[data-field=\"acct-auth-mode\"]')\n ?.addEventListener(\"change\", () => this.updateAuthModeVisibility(slot));\n slot\n .querySelector('[data-field=\"acct-oauth-provider\"]')\n ?.addEventListener(\"change\", () =>\n this.updateCustomMcpFieldsVisibility(slot),\n );\n slot\n .querySelector('[data-action=\"connect-oauth\"]')\n ?.addEventListener(\"click\", () => void this.connectOAuthFromForm(slot));\n\n this.updateAuthModeVisibility(slot);\n this.updateCustomMcpFieldsVisibility(slot);\n }\n\n updateAuthModeVisibility(slot: Element) {\n const mode = (\n slot.querySelector('[data-field=\"acct-auth-mode\"]') as HTMLSelectElement\n )?.value;\n const isOAuth = mode === \"oauth\";\n const isBasic = mode === \"basic\";\n\n const oauthRegion = slot.querySelector('[data-region=\"oauth-fields\"]');\n const patRegion = slot.querySelector('[data-region=\"pat-fields\"]');\n const basicUsernameRegion = slot.querySelector(\n '[data-region=\"basic-username-field\"]',\n );\n const patLabel = slot.querySelector('[data-region=\"pat-label\"]');\n\n if (oauthRegion instanceof HTMLElement) {\n oauthRegion.style.display = isOAuth ? \"block\" : \"none\";\n }\n\n if (patRegion instanceof HTMLElement) {\n patRegion.style.display = isOAuth ? \"none\" : \"block\";\n }\n\n if (patLabel) {\n patLabel.textContent = isBasic ? \"Password / API Token\" : \"Access Token\";\n }\n\n if (basicUsernameRegion instanceof HTMLElement) {\n basicUsernameRegion.style.display = isBasic ? \"block\" : \"none\";\n }\n }\n\n updateCustomMcpFieldsVisibility(slot: Element) {\n const providerId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-provider\"]',\n ) as HTMLSelectElement\n )?.value;\n const isCustomMcp = providerId === \"custom_mcp\";\n\n const customFields = slot.querySelector(\n '[data-region=\"custom-mcp-oauth-fields\"]',\n );\n if (customFields instanceof HTMLElement) {\n customFields.style.display = isCustomMcp ? \"block\" : \"none\";\n }\n }\n\n async connectOAuthFromForm(slot: Element) {\n const providerId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-provider\"]',\n ) as HTMLSelectElement\n )?.value;\n const clientId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-client-id\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const clientSecret = (\n slot.querySelector(\n '[data-field=\"acct-oauth-client-secret\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const scopeRaw = (\n slot.querySelector('[data-field=\"acct-oauth-scope\"]') as HTMLInputElement\n )?.value.trim();\n\n if (!providerId) {\n showError(\"OAuth provider is required.\", 4000);\n\n return;\n }\n\n if (!clientId) {\n showError(\"OAuth client ID is required.\", 4000);\n\n return;\n }\n\n const oauthStatus = slot.querySelector('[data-region=\"oauth-status\"]');\n const connectBtn = slot.querySelector(\n '[data-action=\"connect-oauth\"]',\n ) as HTMLButtonElement | null;\n\n if (oauthStatus) {\n oauthStatus.textContent = \"Starting OAuth...\";\n }\n\n if (connectBtn) {\n connectBtn.disabled = true;\n }\n\n try {\n const scope = scopeRaw\n ? scopeRaw\n .split(/[\\s,]+/)\n .map((token) => token.trim())\n .filter(Boolean)\n : undefined;\n\n // For custom_mcp, pass user-supplied OAuth URLs.\n const isCustomMcp = providerId === \"custom_mcp\";\n const customAuthorizeUrl = isCustomMcp\n ? (\n slot.querySelector(\n '[data-field=\"acct-oauth-authorize-url\"]',\n ) as HTMLInputElement\n )?.value.trim()\n : undefined;\n const customTokenUrl = isCustomMcp\n ? (\n slot.querySelector(\n '[data-field=\"acct-oauth-token-url\"]',\n ) as HTMLInputElement\n )?.value.trim()\n : undefined;\n const customUsePkce = isCustomMcp\n ? (\n slot.querySelector(\n '[data-field=\"acct-oauth-use-pkce\"]',\n ) as HTMLInputElement\n )?.checked\n : undefined;\n const customRedirectUri = isCustomMcp\n ? (\n slot.querySelector(\n '[data-field=\"acct-oauth-redirect-uri\"]',\n ) as HTMLInputElement\n )?.value.trim()\n : undefined;\n\n // Resolve redirectUri: custom field > provider config > app default.\n const providerDef = OAUTH_PROVIDER_DEFINITIONS[providerId];\n const resolvedRedirectUri =\n isCustomMcp && customRedirectUri\n ? customRedirectUri\n : providerDef?.redirectUri\n ? providerDef.redirectUri\n : `${window.location.origin}/oauth/callback`;\n\n const authorizeRes = await fetch(\"/oauth/authorize\", {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n providerId,\n clientId,\n clientSecret: clientSecret || undefined,\n redirectUri: resolvedRedirectUri,\n scope,\n ...(isCustomMcp && customAuthorizeUrl\n ? { authorizeUrl: customAuthorizeUrl }\n : {}),\n ...(isCustomMcp && customTokenUrl\n ? { tokenUrl: customTokenUrl }\n : {}),\n ...(isCustomMcp && typeof customUsePkce === \"boolean\"\n ? { usePkce: customUsePkce }\n : {}),\n }),\n });\n\n const authorizePayload = (await authorizeRes.json()) as {\n state?: string;\n authorizeUrl?: string;\n error?: string;\n };\n\n if (\n !authorizeRes.ok ||\n !authorizePayload.state ||\n !authorizePayload.authorizeUrl\n ) {\n throw new Error(authorizePayload.error || \"OAuth authorize failed\");\n }\n\n window.open(\n authorizePayload.authorizeUrl,\n \"shadowclaw-oauth\",\n \"popup=yes,width=540,height=720\",\n );\n\n const state = authorizePayload.state;\n let status = \"pending\";\n for (let attempt = 0; attempt < 60; attempt++) {\n const sessionRes = await fetch(\n `/oauth/session/${encodeURIComponent(state)}`,\n );\n const sessionPayload = (await sessionRes.json()) as {\n status?: string;\n error?: string;\n };\n\n if (!sessionRes.ok) {\n throw new Error(sessionPayload.error || \"OAuth session not found\");\n }\n\n status = sessionPayload.status || \"pending\";\n\n if (status === \"authorized\") {\n break;\n }\n\n if (status === \"error\") {\n throw new Error(sessionPayload.error || \"OAuth authorization failed\");\n }\n\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n\n if (status !== \"authorized\") {\n throw new Error(\"OAuth authorization timed out\");\n }\n\n const tokenRes = await fetch(\"/oauth/token\", {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ state }),\n });\n\n const tokenPayload = (await tokenRes.json()) as {\n accessToken?: string;\n refreshToken?: string;\n expiresIn?: number;\n scope?: string;\n tokenType?: string;\n error?: string;\n };\n\n if (!tokenRes.ok || !tokenPayload.accessToken) {\n throw new Error(tokenPayload.error || \"OAuth token exchange failed\");\n }\n\n this.pendingOauthResult = {\n providerId,\n accessToken: tokenPayload.accessToken,\n refreshToken: tokenPayload.refreshToken,\n expiresAt: tokenPayload.expiresIn\n ? Date.now() + tokenPayload.expiresIn * 1000\n : undefined,\n scope: tokenPayload.scope,\n tokenType: tokenPayload.tokenType,\n };\n\n if (oauthStatus) {\n oauthStatus.textContent = \"OAuth connected\";\n }\n\n showSuccess(\"OAuth connected\", 3000);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (oauthStatus) {\n oauthStatus.textContent = \"OAuth failed\";\n }\n\n showError(`OAuth connect failed: ${message}`, 6000);\n } finally {\n if (connectBtn) {\n connectBtn.disabled = false;\n }\n }\n }\n\n async deleteAccount(id: string) {\n if (!this.db) {\n return;\n }\n\n this.accounts = this.accounts.filter((account) => account.id !== id);\n\n if (this.defaultAccountId === id) {\n this.defaultAccountId = this.accounts[0]?.id || \"\";\n }\n\n try {\n const { setConfig } = await import(\"../../../db/setConfig.js\");\n await setConfig(this.db, CONFIG_KEYS.SERVICE_ACCOUNTS, this.accounts);\n await setConfig(\n this.db,\n CONFIG_KEYS.SERVICE_DEFAULT_ACCOUNT,\n this.defaultAccountId,\n );\n } catch (err) {\n console.warn(\"Error persisting account deletion:\", err);\n }\n\n this.renderAccountList();\n\n showSuccess(\"Account deleted\", 3000);\n }\n\n async render() {\n const root = this.shadowRoot;\n if (!root || !this.db) {\n return;\n }\n\n try {\n const raw = await getConfig(this.db, CONFIG_KEYS.SERVICE_ACCOUNTS);\n this.accounts = Array.isArray(raw) ? raw : [];\n this.defaultAccountId =\n (await getConfig(this.db, CONFIG_KEYS.SERVICE_DEFAULT_ACCOUNT)) || \"\";\n\n this.renderAccountList();\n } catch (e) {\n console.warn(\"Could not load service accounts:\", e);\n }\n }\n\n async saveAccountForm() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const slot = root.querySelector('[data-region=\"account-form-slot\"]');\n if (!slot) {\n return;\n }\n\n const label = (\n slot.querySelector('[data-field=\"acct-label\"]') as HTMLInputElement\n )?.value.trim();\n const service = (\n slot.querySelector('[data-field=\"acct-service\"]') as HTMLInputElement\n )?.value.trim();\n const hostPattern = (\n slot.querySelector('[data-field=\"acct-host\"]') as HTMLInputElement\n )?.value.trim();\n const authMode = (\n slot.querySelector('[data-field=\"acct-auth-mode\"]') as HTMLSelectElement\n )?.value as ServiceAccount[\"authMode\"];\n const basicUsername = (\n slot.querySelector(\n '[data-field=\"acct-basic-username\"]',\n ) as HTMLInputElement\n )?.value.trim();\n\n if (!label || !service || !hostPattern) {\n showError(\"Label, Service, and Host Pattern are required.\", 4000);\n\n return;\n }\n\n try {\n const { encryptValue } = await import(\"../../../security/crypto.js\");\n const { setConfig } = await import(\"../../../db/setConfig.js\");\n\n const tokenRaw = (\n slot.querySelector('[data-field=\"acct-token\"]') as HTMLInputElement\n )?.value.trim();\n\n const isNew = this.editingAccountId === \"new\";\n const existing = isNew\n ? null\n : this.accounts.find((account) => account.id === this.editingAccountId);\n\n let token = existing?.token || \"\";\n let refreshToken = existing?.refreshToken;\n let accessTokenExpiresAt = existing?.accessTokenExpiresAt;\n let scopes = existing?.scopes;\n let tokenType = existing?.tokenType;\n let oauthProviderId = existing?.oauthProviderId;\n let oauthClientId = existing?.oauthClientId;\n let oauthClientSecret = existing?.oauthClientSecret;\n let oauthRefreshFailureCount = existing?.oauthRefreshFailureCount;\n let oauthReauthRequired = existing?.oauthReauthRequired;\n let oauthReauthRequiredAt = existing?.oauthReauthRequiredAt;\n\n let oauthCustomAuthorizeUrl = existing?.oauthCustomAuthorizeUrl;\n let oauthCustomTokenUrl = existing?.oauthCustomTokenUrl;\n let oauthCustomUsePkce = existing?.oauthCustomUsePkce;\n let oauthCustomRedirectUri = existing?.oauthCustomRedirectUri;\n\n if (authMode === \"oauth\") {\n oauthProviderId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-provider\"]',\n ) as HTMLSelectElement\n )?.value;\n oauthClientId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-client-id\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const oauthClientSecretRaw = (\n slot.querySelector(\n '[data-field=\"acct-oauth-client-secret\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const oauthScopeRaw = (\n slot.querySelector(\n '[data-field=\"acct-oauth-scope\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const configuredScopes = oauthScopeRaw\n ? oauthScopeRaw\n .split(/[\\s,]+/)\n .map((entry) => entry.trim())\n .filter(Boolean)\n : undefined;\n\n if (!oauthProviderId) {\n showError(\"OAuth provider is required for OAuth mode.\", 4000);\n\n return;\n }\n\n if (!oauthClientId) {\n showError(\"OAuth client ID is required for OAuth mode.\", 4000);\n\n return;\n }\n\n // Read custom MCP OAuth URL fields.\n if (oauthProviderId === \"custom_mcp\") {\n oauthCustomAuthorizeUrl =\n (\n slot.querySelector(\n '[data-field=\"acct-oauth-authorize-url\"]',\n ) as HTMLInputElement\n )?.value.trim() || undefined;\n oauthCustomTokenUrl =\n (\n slot.querySelector(\n '[data-field=\"acct-oauth-token-url\"]',\n ) as HTMLInputElement\n )?.value.trim() || undefined;\n oauthCustomUsePkce = (\n slot.querySelector(\n '[data-field=\"acct-oauth-use-pkce\"]',\n ) as HTMLInputElement\n )?.checked;\n oauthCustomRedirectUri =\n (\n slot.querySelector(\n '[data-field=\"acct-oauth-redirect-uri\"]',\n ) as HTMLInputElement\n )?.value.trim() || undefined;\n } else {\n oauthCustomAuthorizeUrl = undefined;\n oauthCustomTokenUrl = undefined;\n oauthCustomUsePkce = undefined;\n oauthCustomRedirectUri = undefined;\n }\n\n if (oauthClientSecretRaw) {\n const encryptedClientSecret =\n await encryptValue(oauthClientSecretRaw);\n if (encryptedClientSecret) {\n oauthClientSecret = encryptedClientSecret;\n }\n }\n\n if (this.pendingOauthResult?.accessToken) {\n const encryptedAccessToken = await encryptValue(\n this.pendingOauthResult.accessToken,\n );\n if (encryptedAccessToken) {\n token = encryptedAccessToken;\n }\n\n if (this.pendingOauthResult.refreshToken) {\n const encryptedRefreshToken = await encryptValue(\n this.pendingOauthResult.refreshToken,\n );\n if (encryptedRefreshToken) {\n refreshToken = encryptedRefreshToken;\n }\n }\n\n accessTokenExpiresAt = this.pendingOauthResult.expiresAt;\n scopes = this.pendingOauthResult.scope\n ? this.pendingOauthResult.scope\n .split(/[\\s,]+/)\n .map((entry) => entry.trim())\n .filter(Boolean)\n : configuredScopes || scopes;\n tokenType = this.pendingOauthResult.tokenType;\n oauthRefreshFailureCount = 0;\n oauthReauthRequired = false;\n oauthReauthRequiredAt = undefined;\n } else {\n scopes = configuredScopes || scopes;\n }\n\n if (!token) {\n showError(\n \"Connect OAuth first to obtain an access token for this account.\",\n 5000,\n );\n\n return;\n }\n } else {\n if (tokenRaw) {\n const encrypted = await encryptValue(tokenRaw);\n if (encrypted) {\n token = encrypted;\n }\n }\n\n refreshToken = undefined;\n accessTokenExpiresAt = undefined;\n scopes = undefined;\n tokenType = undefined;\n oauthProviderId = undefined;\n oauthClientId = undefined;\n oauthClientSecret = undefined;\n oauthRefreshFailureCount = undefined;\n oauthReauthRequired = undefined;\n oauthReauthRequiredAt = undefined;\n oauthCustomAuthorizeUrl = undefined;\n oauthCustomTokenUrl = undefined;\n oauthCustomUsePkce = undefined;\n oauthCustomRedirectUri = undefined;\n }\n\n if (isNew) {\n const { ulid } = await import(\"../../../utils/ulid.js\");\n const account: ServiceAccount = {\n id: ulid(),\n label,\n service,\n hostPattern,\n token,\n basicUsername: authMode === \"basic\" ? basicUsername : undefined,\n authMode: authMode || \"token\",\n oauthProviderId,\n oauthClientId,\n oauthClientSecret,\n accessTokenExpiresAt,\n refreshToken,\n scopes,\n tokenType,\n oauthRefreshFailureCount,\n oauthReauthRequired,\n oauthReauthRequiredAt,\n oauthCustomAuthorizeUrl,\n oauthCustomTokenUrl,\n oauthCustomUsePkce,\n oauthCustomRedirectUri,\n };\n\n this.accounts.push(account);\n\n if (this.accounts.length === 1) {\n this.defaultAccountId = account.id;\n await setConfig(\n this.db,\n CONFIG_KEYS.SERVICE_DEFAULT_ACCOUNT,\n account.id,\n );\n }\n } else if (existing) {\n existing.label = label;\n existing.service = service;\n existing.hostPattern = hostPattern;\n existing.token = token;\n existing.basicUsername =\n authMode === \"basic\" ? basicUsername : undefined;\n existing.authMode = authMode || \"token\";\n existing.oauthProviderId = oauthProviderId;\n existing.oauthClientId = oauthClientId;\n existing.oauthClientSecret = oauthClientSecret;\n existing.accessTokenExpiresAt = accessTokenExpiresAt;\n existing.refreshToken = refreshToken;\n existing.scopes = scopes;\n existing.tokenType = tokenType;\n existing.oauthRefreshFailureCount = oauthRefreshFailureCount;\n existing.oauthReauthRequired = oauthReauthRequired;\n existing.oauthReauthRequiredAt = oauthReauthRequiredAt;\n existing.oauthCustomAuthorizeUrl = oauthCustomAuthorizeUrl;\n existing.oauthCustomTokenUrl = oauthCustomTokenUrl;\n existing.oauthCustomUsePkce = oauthCustomUsePkce;\n existing.oauthCustomRedirectUri = oauthCustomRedirectUri;\n }\n\n await setConfig(this.db, CONFIG_KEYS.SERVICE_ACCOUNTS, this.accounts);\n\n this.hideAccountForm();\n this.renderAccountList();\n\n showSuccess(isNew ? \"Account added\" : \"Account updated\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving account: \" + errorMsg, 6000);\n }\n }\n\n async setDefaultAccount(id: string) {\n if (!this.db) {\n return;\n }\n\n this.defaultAccountId = id;\n\n try {\n const { setConfig } = await import(\"../../../db/setConfig.js\");\n await setConfig(this.db, CONFIG_KEYS.SERVICE_DEFAULT_ACCOUNT, id);\n } catch (err) {\n console.warn(\"Error setting default account:\", err);\n }\n\n this.renderAccountList();\n\n showSuccess(\"Default account updated\", 3000);\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawAccounts);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shadow-claw-accounts-03oJ__XC.js","names":["shadowClawAccountsStyles","shadowClawAccountsTemplate"],"sources":["../../src/components/settings/shadow-claw-accounts/utils/resolveAccountAuthMode.ts","../../src/components/settings/shadow-claw-accounts/shadow-claw-accounts.ts"],"sourcesContent":["import type { ServiceAccount } from \"../../../../subsystems/accounts/service-accounts.js\";\n\nexport function resolveAccountAuthMode(\n account: ServiceAccount | null,\n): \"token\" | \"basic\" | \"oauth\" {\n if (!account) {\n return \"token\";\n }\n\n if (\n account.authMode === \"token\" ||\n (account.authMode as string) === \"token\"\n ) {\n return \"token\";\n }\n\n if (account.authMode === \"basic\") {\n return \"basic\";\n }\n\n if (account.authMode === \"oauth\") {\n return \"oauth\";\n }\n\n if (\n account.oauthProviderId ||\n account.oauthClientId ||\n account.oauthClientSecret ||\n account.refreshToken ||\n account.accessTokenExpiresAt ||\n account.tokenType ||\n account.oauthReauthRequired\n ) {\n return \"oauth\";\n }\n\n return \"token\";\n}\n","import {\n CONFIG_KEYS,\n OAUTH_PROVIDER_DEFINITIONS,\n} from \"../../../config/config.js\";\n\nimport { getDb, type ShadowClawDatabase } from \"../../../db/db.js\";\nimport { getConfig } from \"../../../db/getConfig.js\";\nimport { setSanitizedHtml } from \"../../../security/trusted-types.js\";\nimport { showError, showSuccess } from \"../../../ui/toast.js\";\nimport { escapeHtml } from \"../../../utils/utils.js\";\nimport { resolveAccountAuthMode } from \"./utils/resolveAccountAuthMode.js\";\n\nimport type { ServiceAccount } from \"../../../subsystems/accounts/service-accounts.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\n\nimport \"../../common/shadow-claw-actions/shadow-claw-actions.js\";\nimport \"../../common/shadow-claw-card/shadow-claw-card.js\";\nimport \"../../common/shadow-claw-empty-state/shadow-claw-empty-state.js\";\nimport shadowClawAccountsStyles from \"./shadow-claw-accounts.css\" with { type: \"css\" };\nimport shadowClawAccountsTemplate from \"./shadow-claw-accounts.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-accounts\";\n\nexport class ShadowClawAccounts extends ShadowClawElement {\n static styles = shadowClawAccountsStyles;\n static template = shadowClawAccountsTemplate;\n\n accounts: ServiceAccount[] = [];\n db: ShadowClawDatabase | null = null;\n defaultAccountId = \"\";\n editingAccountId: string | null = null;\n pendingOauthResult: {\n providerId: string;\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n scope?: string;\n tokenType?: string;\n } | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n this.db = await getDb();\n\n await this.render();\n\n this.bindEventListeners();\n }\n\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"add-account\"]')\n ?.addEventListener(\"click\", () => this.showAccountForm(\"new\"));\n\n root\n .querySelector('[data-region=\"account-list\"]')\n ?.addEventListener(\"settings-action\", (event) => {\n const detail = (event as CustomEvent<{ action: string; id: string }>)\n .detail;\n const { action, id } = detail || { action: \"\", id: \"\" };\n\n if (!id) {\n return;\n }\n\n if (action === \"edit-account\") {\n this.showAccountForm(id);\n } else if (action === \"delete-account\") {\n void this.deleteAccount(id);\n } else if (action === \"set-default\") {\n void this.setDefaultAccount(id);\n }\n });\n }\n\n hideAccountForm() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const slot = root.querySelector('[data-region=\"account-form-slot\"]');\n if (slot) {\n slot.replaceChildren();\n }\n }\n\n renderAccountList() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const listEl = root.querySelector('[data-region=\"account-list\"]');\n if (!listEl) {\n return;\n }\n\n listEl.replaceChildren();\n\n if (this.accounts.length === 0) {\n const emptyState = document.createElement(\"shadow-claw-empty-state\");\n emptyState.setAttribute(\"message\", \"No additional accounts configured.\");\n emptyState.setAttribute(\n \"hint\",\n \"Click '+ Add Non-Git Account' to get started.\",\n );\n listEl.append(emptyState);\n\n return;\n }\n\n const fragment = document.createDocumentFragment();\n\n this.accounts.forEach((acct) => {\n const isDefault = acct.id === this.defaultAccountId;\n const hasToken = !!acct.token;\n const authMode = resolveAccountAuthMode(acct);\n const needsReauth = authMode === \"oauth\" && !!acct.oauthReauthRequired;\n const authLabel =\n authMode === \"oauth\"\n ? `OAuth${acct.oauthProviderId ? ` (${acct.oauthProviderId})` : \"\"}`\n : authMode === \"basic\"\n ? \"Basic Auth\"\n : \"Token\";\n const credentialLabel = hasToken\n ? authMode === \"oauth\"\n ? needsReauth\n ? \"Reconnect required\"\n : \"OAuth token saved\"\n : \"Token saved\"\n : \"No token\";\n const cardMeta = `${acct.service} · ${acct.hostPattern} · ${authLabel} · ${credentialLabel}`;\n\n const card = document.createElement(\"shadow-claw-card\");\n card.setAttribute(\"data-account-id\", acct.id);\n card.setAttribute(\"label\", acct.label);\n card.setAttribute(\"meta\", cardMeta);\n if (isDefault) {\n card.setAttribute(\"highlight\", \"\");\n card.setAttribute(\"badge\", \"Default\");\n }\n\n const actions = document.createElement(\"shadow-claw-actions\");\n actions.setAttribute(\"slot\", \"actions\");\n actions.setAttribute(\"kind\", \"account\");\n actions.setAttribute(\"item-id\", acct.id);\n if (isDefault) {\n actions.setAttribute(\"is-default\", \"\");\n }\n\n card.append(actions);\n fragment.append(card);\n });\n\n listEl.append(fragment);\n }\n\n showAccountForm(accountId: string) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n this.editingAccountId = accountId;\n this.pendingOauthResult = null;\n const isNew = accountId === \"new\";\n const existing = isNew\n ? null\n : this.accounts.find((account) => account.id === accountId);\n const selectedAuthMode = resolveAccountAuthMode(existing || null);\n const oauthProviderId =\n existing?.oauthProviderId &&\n OAUTH_PROVIDER_DEFINITIONS[existing.oauthProviderId]\n ? existing.oauthProviderId\n : \"github\";\n const oauthScope = existing?.scopes?.join(\" \") || \"\";\n const oauthProviderOptions = Object.values(OAUTH_PROVIDER_DEFINITIONS)\n .map(\n (provider) =>\n `<option value=\"${provider.id}\"${provider.id === oauthProviderId ? \" selected\" : \"\"}>${escapeHtml(provider.name)}</option>`,\n )\n .join(\"\");\n\n const slot = root.querySelector('[data-region=\"account-form-slot\"]');\n if (!slot) {\n return;\n }\n\n setSanitizedHtml(\n slot,\n `\n <div class=\"account-form\">\n <h4>${isNew ? \"Add Account\" : \"Edit Account\"}</h4>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Label</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-label\"\n placeholder=\"e.g. Design Team Figma\"\n value=\"${escapeHtml(existing?.label || \"\")}\" />\n <div class=\"form-helper\">A friendly name to identify this account.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Service</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-service\"\n placeholder=\"e.g. Figma\"\n value=\"${escapeHtml(existing?.service || \"\")}\" />\n <div class=\"form-helper\">The external service this token belongs to.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Host Pattern</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-host\"\n placeholder=\"e.g. figma.com or api.figma.com\"\n value=\"${escapeHtml(existing?.hostPattern || \"\")}\" />\n <div class=\"form-helper\">Used to identify the service endpoint or host.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Auth Mode</label>\n <select class=\"form-input\" data-field=\"acct-auth-mode\">\n <option value=\"token\"${selectedAuthMode === \"token\" ? \" selected\" : \"\"}>Token (PAT)</option>\n <option value=\"basic\"${selectedAuthMode === \"basic\" ? \" selected\" : \"\"}>Basic Auth</option>\n <option value=\"oauth\"${selectedAuthMode === \"oauth\" ? \" selected\" : \"\"}>OAuth</option>\n </select>\n <div class=\"form-helper\">Use Token for generic tokens, Basic for user/password, or OAuth for provider-managed access.</div>\n </div>\n\n <div class=\"oauth-fields\" data-region=\"oauth-fields\">\n <div class=\"form-group\">\n <label class=\"form-label\">OAuth Provider</label>\n <select class=\"form-input\" data-field=\"acct-oauth-provider\">${oauthProviderOptions}</select>\n </div>\n\n <div class=\"custom-mcp-oauth-fields\" data-region=\"custom-mcp-oauth-fields\">\n <div class=\"form-group\">\n <label class=\"form-label\">Authorize URL</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-authorize-url\" value=\"${escapeHtml(existing?.oauthCustomAuthorizeUrl || \"\")}\" placeholder=\"https://example.com/oauth/authorize\" />\n <div class=\"form-helper\">The OAuth authorization endpoint of the MCP server.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Token URL</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-token-url\" value=\"${escapeHtml(existing?.oauthCustomTokenUrl || \"\")}\" placeholder=\"https://example.com/oauth/token\" />\n <div class=\"form-helper\">The OAuth token exchange endpoint of the MCP server.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">\n <input type=\"checkbox\" data-field=\"acct-oauth-use-pkce\" ${existing?.oauthCustomUsePkce !== false ? \"checked\" : \"\"} />\n Use PKCE (S256)\n </label>\n <div class=\"form-helper\">Most servers require PKCE. Uncheck only if the server doesn't support it.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Redirect URI</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-redirect-uri\" value=\"${escapeHtml(existing?.oauthCustomRedirectUri || \"\")}\" placeholder=\"https://localhost/callback\" />\n <div class=\"form-helper\">Must match the redirect URI registered with the OAuth server. Leave blank to use default.</div>\n </div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">OAuth Client ID</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-client-id\" value=\"${escapeHtml(existing?.oauthClientId || \"\")}\" placeholder=\"Enter provider OAuth app client ID\" />\n <div class=\"form-helper\">Required for OAuth connect. Register an OAuth app with the selected provider first.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">OAuth Client Secret (if required)</label>\n <input type=\"password\" class=\"form-input\" data-field=\"acct-oauth-client-secret\" placeholder=\"${existing?.oauthClientSecret ? \"•••••••••••• (Saved)\" : \"Enter client secret if provider requires it\"}\" />\n <div class=\"form-helper\">Stored encrypted locally. Needed by some providers for token exchange/refresh.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">OAuth Scope (if required)</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-oauth-scope\" value=\"${escapeHtml(oauthScope)}\" placeholder=\"space-separated scopes\" />\n <div class=\"form-helper\">Leave blank to use provider defaults.</div>\n </div>\n\n <div class=\"form-group oauth-connect-row\">\n <button class=\"confirm-btn oauth-connect-btn\" data-action=\"connect-oauth\" type=\"button\">Connect OAuth</button>\n <span class=\"oauth-status\" data-region=\"oauth-status\">${selectedAuthMode === \"oauth\" && existing?.oauthReauthRequired ? \"Reconnect required\" : selectedAuthMode === \"oauth\" && existing?.token ? \"OAuth token already saved\" : \"Not connected\"}</span>\n </div>\n </div>\n\n <div class=\"form-group\" data-region=\"basic-username-field\">\n <label class=\"form-label\">Username or Email</label>\n <input type=\"text\" class=\"form-input\" data-field=\"acct-basic-username\"\n placeholder=\"e.g. user@example.com\"\n value=\"${escapeHtml(existing?.basicUsername || \"\")}\" />\n <div class=\"form-helper\">Required for Basic Auth.</div>\n </div>\n\n <div class=\"form-group\" data-region=\"pat-fields\">\n <label class=\"form-label\" data-region=\"pat-label\">Access Token</label>\n <input type=\"password\" class=\"form-input\" data-field=\"acct-token\"\n placeholder=\"${existing?.token ? \"•••••••••••• (Saved)\" : \"Paste Token\"}\" />\n <div class=\"form-helper\">Stored encrypted locally. Leave blank to keep the existing token.</div>\n </div>\n\n <div class=\"account-form-actions\">\n <button class=\"confirm-btn\" data-action=\"save-account\">\n ${isNew ? \"Add Account\" : \"Update Account\"}\n </button>\n <button class=\"cancel-btn\" data-action=\"cancel-account-form\">Cancel</button>\n </div>\n </div>`,\n );\n\n slot\n .querySelector('[data-action=\"save-account\"]')\n ?.addEventListener(\"click\", () => void this.saveAccountForm());\n slot\n .querySelector('[data-action=\"cancel-account-form\"]')\n ?.addEventListener(\"click\", () => this.hideAccountForm());\n slot\n .querySelector('[data-field=\"acct-auth-mode\"]')\n ?.addEventListener(\"change\", () => this.updateAuthModeVisibility(slot));\n slot\n .querySelector('[data-field=\"acct-oauth-provider\"]')\n ?.addEventListener(\"change\", () =>\n this.updateCustomMcpFieldsVisibility(slot),\n );\n slot\n .querySelector('[data-action=\"connect-oauth\"]')\n ?.addEventListener(\"click\", () => void this.connectOAuthFromForm(slot));\n\n this.updateAuthModeVisibility(slot);\n this.updateCustomMcpFieldsVisibility(slot);\n }\n\n updateAuthModeVisibility(slot: Element) {\n const mode = (\n slot.querySelector('[data-field=\"acct-auth-mode\"]') as HTMLSelectElement\n )?.value;\n const isOAuth = mode === \"oauth\";\n const isBasic = mode === \"basic\";\n\n const oauthRegion = slot.querySelector('[data-region=\"oauth-fields\"]');\n const patRegion = slot.querySelector('[data-region=\"pat-fields\"]');\n const basicUsernameRegion = slot.querySelector(\n '[data-region=\"basic-username-field\"]',\n );\n const patLabel = slot.querySelector('[data-region=\"pat-label\"]');\n\n if (oauthRegion instanceof HTMLElement) {\n oauthRegion.style.display = isOAuth ? \"block\" : \"none\";\n }\n\n if (patRegion instanceof HTMLElement) {\n patRegion.style.display = isOAuth ? \"none\" : \"block\";\n }\n\n if (patLabel) {\n patLabel.textContent = isBasic ? \"Password / API Token\" : \"Access Token\";\n }\n\n if (basicUsernameRegion instanceof HTMLElement) {\n basicUsernameRegion.style.display = isBasic ? \"block\" : \"none\";\n }\n }\n\n updateCustomMcpFieldsVisibility(slot: Element) {\n const providerId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-provider\"]',\n ) as HTMLSelectElement\n )?.value;\n const isCustomMcp = providerId === \"custom_mcp\";\n\n const customFields = slot.querySelector(\n '[data-region=\"custom-mcp-oauth-fields\"]',\n );\n if (customFields instanceof HTMLElement) {\n customFields.style.display = isCustomMcp ? \"block\" : \"none\";\n }\n }\n\n async connectOAuthFromForm(slot: Element) {\n const providerId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-provider\"]',\n ) as HTMLSelectElement\n )?.value;\n const clientId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-client-id\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const clientSecret = (\n slot.querySelector(\n '[data-field=\"acct-oauth-client-secret\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const scopeRaw = (\n slot.querySelector('[data-field=\"acct-oauth-scope\"]') as HTMLInputElement\n )?.value.trim();\n\n if (!providerId) {\n showError(\"OAuth provider is required.\", 4000);\n\n return;\n }\n\n if (!clientId) {\n showError(\"OAuth client ID is required.\", 4000);\n\n return;\n }\n\n const oauthStatus = slot.querySelector('[data-region=\"oauth-status\"]');\n const connectBtn = slot.querySelector(\n '[data-action=\"connect-oauth\"]',\n ) as HTMLButtonElement | null;\n\n if (oauthStatus) {\n oauthStatus.textContent = \"Starting OAuth...\";\n }\n\n if (connectBtn) {\n connectBtn.disabled = true;\n }\n\n try {\n const scope = scopeRaw\n ? scopeRaw\n .split(/[\\s,]+/)\n .map((token) => token.trim())\n .filter(Boolean)\n : undefined;\n\n // For custom_mcp, pass user-supplied OAuth URLs.\n const isCustomMcp = providerId === \"custom_mcp\";\n const customAuthorizeUrl = isCustomMcp\n ? (\n slot.querySelector(\n '[data-field=\"acct-oauth-authorize-url\"]',\n ) as HTMLInputElement\n )?.value.trim()\n : undefined;\n const customTokenUrl = isCustomMcp\n ? (\n slot.querySelector(\n '[data-field=\"acct-oauth-token-url\"]',\n ) as HTMLInputElement\n )?.value.trim()\n : undefined;\n const customUsePkce = isCustomMcp\n ? (\n slot.querySelector(\n '[data-field=\"acct-oauth-use-pkce\"]',\n ) as HTMLInputElement\n )?.checked\n : undefined;\n const customRedirectUri = isCustomMcp\n ? (\n slot.querySelector(\n '[data-field=\"acct-oauth-redirect-uri\"]',\n ) as HTMLInputElement\n )?.value.trim()\n : undefined;\n\n // Resolve redirectUri: custom field > provider config > app default.\n const providerDef = OAUTH_PROVIDER_DEFINITIONS[providerId];\n const resolvedRedirectUri =\n isCustomMcp && customRedirectUri\n ? customRedirectUri\n : providerDef?.redirectUri\n ? providerDef.redirectUri\n : `${window.location.origin}/oauth/callback`;\n\n const authorizeRes = await fetch(\"/oauth/authorize\", {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n providerId,\n clientId,\n clientSecret: clientSecret || undefined,\n redirectUri: resolvedRedirectUri,\n scope,\n ...(isCustomMcp && customAuthorizeUrl\n ? { authorizeUrl: customAuthorizeUrl }\n : {}),\n ...(isCustomMcp && customTokenUrl\n ? { tokenUrl: customTokenUrl }\n : {}),\n ...(isCustomMcp && typeof customUsePkce === \"boolean\"\n ? { usePkce: customUsePkce }\n : {}),\n }),\n });\n\n const authorizePayload = (await authorizeRes.json()) as {\n state?: string;\n authorizeUrl?: string;\n error?: string;\n };\n\n if (\n !authorizeRes.ok ||\n !authorizePayload.state ||\n !authorizePayload.authorizeUrl\n ) {\n throw new Error(authorizePayload.error || \"OAuth authorize failed\");\n }\n\n window.open(\n authorizePayload.authorizeUrl,\n \"shadowclaw-oauth\",\n \"popup=yes,width=540,height=720\",\n );\n\n const state = authorizePayload.state;\n let status = \"pending\";\n for (let attempt = 0; attempt < 60; attempt++) {\n const sessionRes = await fetch(\n `/oauth/session/${encodeURIComponent(state)}`,\n );\n const sessionPayload = (await sessionRes.json()) as {\n status?: string;\n error?: string;\n };\n\n if (!sessionRes.ok) {\n throw new Error(sessionPayload.error || \"OAuth session not found\");\n }\n\n status = sessionPayload.status || \"pending\";\n\n if (status === \"authorized\") {\n break;\n }\n\n if (status === \"error\") {\n throw new Error(sessionPayload.error || \"OAuth authorization failed\");\n }\n\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n\n if (status !== \"authorized\") {\n throw new Error(\"OAuth authorization timed out\");\n }\n\n const tokenRes = await fetch(\"/oauth/token\", {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ state }),\n });\n\n const tokenPayload = (await tokenRes.json()) as {\n accessToken?: string;\n refreshToken?: string;\n expiresIn?: number;\n scope?: string;\n tokenType?: string;\n error?: string;\n };\n\n if (!tokenRes.ok || !tokenPayload.accessToken) {\n throw new Error(tokenPayload.error || \"OAuth token exchange failed\");\n }\n\n this.pendingOauthResult = {\n providerId,\n accessToken: tokenPayload.accessToken,\n refreshToken: tokenPayload.refreshToken,\n expiresAt: tokenPayload.expiresIn\n ? Date.now() + tokenPayload.expiresIn * 1000\n : undefined,\n scope: tokenPayload.scope,\n tokenType: tokenPayload.tokenType,\n };\n\n if (oauthStatus) {\n oauthStatus.textContent = \"OAuth connected\";\n }\n\n showSuccess(\"OAuth connected\", 3000);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (oauthStatus) {\n oauthStatus.textContent = \"OAuth failed\";\n }\n\n showError(`OAuth connect failed: ${message}`, 6000);\n } finally {\n if (connectBtn) {\n connectBtn.disabled = false;\n }\n }\n }\n\n async deleteAccount(id: string) {\n if (!this.db) {\n return;\n }\n\n this.accounts = this.accounts.filter((account) => account.id !== id);\n\n if (this.defaultAccountId === id) {\n this.defaultAccountId = this.accounts[0]?.id || \"\";\n }\n\n try {\n const { setConfig } = await import(\"../../../db/setConfig.js\");\n await setConfig(this.db, CONFIG_KEYS.SERVICE_ACCOUNTS, this.accounts);\n await setConfig(\n this.db,\n CONFIG_KEYS.SERVICE_DEFAULT_ACCOUNT,\n this.defaultAccountId,\n );\n } catch (err) {\n console.warn(\"Error persisting account deletion:\", err);\n }\n\n this.renderAccountList();\n\n showSuccess(\"Account deleted\", 3000);\n }\n\n async render() {\n const root = this.shadowRoot;\n if (!root || !this.db) {\n return;\n }\n\n try {\n const raw = await getConfig(this.db, CONFIG_KEYS.SERVICE_ACCOUNTS);\n this.accounts = Array.isArray(raw) ? raw : [];\n this.defaultAccountId =\n (await getConfig(this.db, CONFIG_KEYS.SERVICE_DEFAULT_ACCOUNT)) || \"\";\n\n this.renderAccountList();\n } catch (e) {\n console.warn(\"Could not load service accounts:\", e);\n }\n }\n\n async saveAccountForm() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const slot = root.querySelector('[data-region=\"account-form-slot\"]');\n if (!slot) {\n return;\n }\n\n const label = (\n slot.querySelector('[data-field=\"acct-label\"]') as HTMLInputElement\n )?.value.trim();\n const service = (\n slot.querySelector('[data-field=\"acct-service\"]') as HTMLInputElement\n )?.value.trim();\n const hostPattern = (\n slot.querySelector('[data-field=\"acct-host\"]') as HTMLInputElement\n )?.value.trim();\n const authMode = (\n slot.querySelector('[data-field=\"acct-auth-mode\"]') as HTMLSelectElement\n )?.value as ServiceAccount[\"authMode\"];\n const basicUsername = (\n slot.querySelector(\n '[data-field=\"acct-basic-username\"]',\n ) as HTMLInputElement\n )?.value.trim();\n\n if (!label || !service || !hostPattern) {\n showError(\"Label, Service, and Host Pattern are required.\", 4000);\n\n return;\n }\n\n try {\n const { encryptValue } = await import(\"../../../security/crypto.js\");\n const { setConfig } = await import(\"../../../db/setConfig.js\");\n\n const tokenRaw = (\n slot.querySelector('[data-field=\"acct-token\"]') as HTMLInputElement\n )?.value.trim();\n\n const isNew = this.editingAccountId === \"new\";\n const existing = isNew\n ? null\n : this.accounts.find((account) => account.id === this.editingAccountId);\n\n let token = existing?.token || \"\";\n let refreshToken = existing?.refreshToken;\n let accessTokenExpiresAt = existing?.accessTokenExpiresAt;\n let scopes = existing?.scopes;\n let tokenType = existing?.tokenType;\n let oauthProviderId = existing?.oauthProviderId;\n let oauthClientId = existing?.oauthClientId;\n let oauthClientSecret = existing?.oauthClientSecret;\n let oauthRefreshFailureCount = existing?.oauthRefreshFailureCount;\n let oauthReauthRequired = existing?.oauthReauthRequired;\n let oauthReauthRequiredAt = existing?.oauthReauthRequiredAt;\n\n let oauthCustomAuthorizeUrl = existing?.oauthCustomAuthorizeUrl;\n let oauthCustomTokenUrl = existing?.oauthCustomTokenUrl;\n let oauthCustomUsePkce = existing?.oauthCustomUsePkce;\n let oauthCustomRedirectUri = existing?.oauthCustomRedirectUri;\n\n if (authMode === \"oauth\") {\n oauthProviderId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-provider\"]',\n ) as HTMLSelectElement\n )?.value;\n oauthClientId = (\n slot.querySelector(\n '[data-field=\"acct-oauth-client-id\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const oauthClientSecretRaw = (\n slot.querySelector(\n '[data-field=\"acct-oauth-client-secret\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const oauthScopeRaw = (\n slot.querySelector(\n '[data-field=\"acct-oauth-scope\"]',\n ) as HTMLInputElement\n )?.value.trim();\n const configuredScopes = oauthScopeRaw\n ? oauthScopeRaw\n .split(/[\\s,]+/)\n .map((entry) => entry.trim())\n .filter(Boolean)\n : undefined;\n\n if (!oauthProviderId) {\n showError(\"OAuth provider is required for OAuth mode.\", 4000);\n\n return;\n }\n\n if (!oauthClientId) {\n showError(\"OAuth client ID is required for OAuth mode.\", 4000);\n\n return;\n }\n\n // Read custom MCP OAuth URL fields.\n if (oauthProviderId === \"custom_mcp\") {\n oauthCustomAuthorizeUrl =\n (\n slot.querySelector(\n '[data-field=\"acct-oauth-authorize-url\"]',\n ) as HTMLInputElement\n )?.value.trim() || undefined;\n oauthCustomTokenUrl =\n (\n slot.querySelector(\n '[data-field=\"acct-oauth-token-url\"]',\n ) as HTMLInputElement\n )?.value.trim() || undefined;\n oauthCustomUsePkce = (\n slot.querySelector(\n '[data-field=\"acct-oauth-use-pkce\"]',\n ) as HTMLInputElement\n )?.checked;\n oauthCustomRedirectUri =\n (\n slot.querySelector(\n '[data-field=\"acct-oauth-redirect-uri\"]',\n ) as HTMLInputElement\n )?.value.trim() || undefined;\n } else {\n oauthCustomAuthorizeUrl = undefined;\n oauthCustomTokenUrl = undefined;\n oauthCustomUsePkce = undefined;\n oauthCustomRedirectUri = undefined;\n }\n\n if (oauthClientSecretRaw) {\n const encryptedClientSecret =\n await encryptValue(oauthClientSecretRaw);\n if (encryptedClientSecret) {\n oauthClientSecret = encryptedClientSecret;\n }\n }\n\n if (this.pendingOauthResult?.accessToken) {\n const encryptedAccessToken = await encryptValue(\n this.pendingOauthResult.accessToken,\n );\n if (encryptedAccessToken) {\n token = encryptedAccessToken;\n }\n\n if (this.pendingOauthResult.refreshToken) {\n const encryptedRefreshToken = await encryptValue(\n this.pendingOauthResult.refreshToken,\n );\n if (encryptedRefreshToken) {\n refreshToken = encryptedRefreshToken;\n }\n }\n\n accessTokenExpiresAt = this.pendingOauthResult.expiresAt;\n scopes = this.pendingOauthResult.scope\n ? this.pendingOauthResult.scope\n .split(/[\\s,]+/)\n .map((entry) => entry.trim())\n .filter(Boolean)\n : configuredScopes || scopes;\n tokenType = this.pendingOauthResult.tokenType;\n oauthRefreshFailureCount = 0;\n oauthReauthRequired = false;\n oauthReauthRequiredAt = undefined;\n } else {\n scopes = configuredScopes || scopes;\n }\n\n if (!token) {\n showError(\n \"Connect OAuth first to obtain an access token for this account.\",\n 5000,\n );\n\n return;\n }\n } else {\n if (tokenRaw) {\n const encrypted = await encryptValue(tokenRaw);\n if (encrypted) {\n token = encrypted;\n }\n }\n\n refreshToken = undefined;\n accessTokenExpiresAt = undefined;\n scopes = undefined;\n tokenType = undefined;\n oauthProviderId = undefined;\n oauthClientId = undefined;\n oauthClientSecret = undefined;\n oauthRefreshFailureCount = undefined;\n oauthReauthRequired = undefined;\n oauthReauthRequiredAt = undefined;\n oauthCustomAuthorizeUrl = undefined;\n oauthCustomTokenUrl = undefined;\n oauthCustomUsePkce = undefined;\n oauthCustomRedirectUri = undefined;\n }\n\n if (isNew) {\n const { ulid } = await import(\"../../../utils/ulid.js\");\n const account: ServiceAccount = {\n id: ulid(),\n label,\n service,\n hostPattern,\n token,\n basicUsername: authMode === \"basic\" ? basicUsername : undefined,\n authMode: authMode || \"token\",\n oauthProviderId,\n oauthClientId,\n oauthClientSecret,\n accessTokenExpiresAt,\n refreshToken,\n scopes,\n tokenType,\n oauthRefreshFailureCount,\n oauthReauthRequired,\n oauthReauthRequiredAt,\n oauthCustomAuthorizeUrl,\n oauthCustomTokenUrl,\n oauthCustomUsePkce,\n oauthCustomRedirectUri,\n };\n\n this.accounts.push(account);\n\n if (this.accounts.length === 1) {\n this.defaultAccountId = account.id;\n await setConfig(\n this.db,\n CONFIG_KEYS.SERVICE_DEFAULT_ACCOUNT,\n account.id,\n );\n }\n } else if (existing) {\n existing.label = label;\n existing.service = service;\n existing.hostPattern = hostPattern;\n existing.token = token;\n existing.basicUsername =\n authMode === \"basic\" ? basicUsername : undefined;\n existing.authMode = authMode || \"token\";\n existing.oauthProviderId = oauthProviderId;\n existing.oauthClientId = oauthClientId;\n existing.oauthClientSecret = oauthClientSecret;\n existing.accessTokenExpiresAt = accessTokenExpiresAt;\n existing.refreshToken = refreshToken;\n existing.scopes = scopes;\n existing.tokenType = tokenType;\n existing.oauthRefreshFailureCount = oauthRefreshFailureCount;\n existing.oauthReauthRequired = oauthReauthRequired;\n existing.oauthReauthRequiredAt = oauthReauthRequiredAt;\n existing.oauthCustomAuthorizeUrl = oauthCustomAuthorizeUrl;\n existing.oauthCustomTokenUrl = oauthCustomTokenUrl;\n existing.oauthCustomUsePkce = oauthCustomUsePkce;\n existing.oauthCustomRedirectUri = oauthCustomRedirectUri;\n }\n\n await setConfig(this.db, CONFIG_KEYS.SERVICE_ACCOUNTS, this.accounts);\n\n this.hideAccountForm();\n this.renderAccountList();\n\n showSuccess(isNew ? \"Account added\" : \"Account updated\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving account: \" + errorMsg, 6000);\n }\n }\n\n async setDefaultAccount(id: string) {\n if (!this.db) {\n return;\n }\n\n this.defaultAccountId = id;\n\n try {\n const { setConfig } = await import(\"../../../db/setConfig.js\");\n await setConfig(this.db, CONFIG_KEYS.SERVICE_DEFAULT_ACCOUNT, id);\n } catch (err) {\n console.warn(\"Error setting default account:\", err);\n }\n\n this.renderAccountList();\n\n showSuccess(\"Default account updated\", 3000);\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawAccounts);\n}\n"],"mappings":"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"}
|
package/dist/lib/{shadow-claw-channel-config-Bj0-Nk3t.js → shadow-claw-channel-config-DmfwJc6G.js}
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import ShadowClawElement from "./components/shadow-claw-element.js";
|
|
2
2
|
import { n as getDb } from "./txPromise-CuGh-TGK.js";
|
|
3
|
-
import { _t as setChannelEnabled, ht as getTelegramConfig, lt as configureIMessage, pt as getIMessageConfig, t as orchestratorStore, ut as configureTelegram } from "./orchestrator-
|
|
3
|
+
import { _t as setChannelEnabled, ht as getTelegramConfig, lt as configureIMessage, pt as getIMessageConfig, t as orchestratorStore, ut as configureTelegram } from "./orchestrator-KRjx0eba.js";
|
|
4
4
|
import { a as showSuccess, r as showError, s as showWarning } from "./toast-DZ6r7_YI.js";
|
|
5
5
|
import { t as effect } from "./effect-DL6j9HJp.js";
|
|
6
|
-
import "./shadow-claw-peerjs-
|
|
6
|
+
import "./shadow-claw-peerjs-xkBXILed.js";
|
|
7
7
|
|
|
8
8
|
//#region src/components/settings/shadow-claw-channel-config/shadow-claw-channel-config.css
|
|
9
9
|
const sheet = new CSSStyleSheet();
|
|
@@ -464,4 +464,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
|
|
|
464
464
|
|
|
465
465
|
//#endregion
|
|
466
466
|
export { ShadowClawChannelConfig as t };
|
|
467
|
-
//# sourceMappingURL=shadow-claw-channel-config-
|
|
467
|
+
//# sourceMappingURL=shadow-claw-channel-config-DmfwJc6G.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-claw-channel-config-Bj0-Nk3t.js","names":["shadowClawChannelConfigStyles","shadowClawChannelConfigTemplate"],"sources":["../../src/components/settings/shadow-claw-channel-config/shadow-claw-channel-config.ts"],"sourcesContent":["import { effect } from \"../../../core/effect.js\";\n\nimport {\n configureIMessage,\n configureTelegram,\n getIMessageConfig,\n getTelegramConfig,\n setChannelEnabled,\n} from \"../../../core/orchestrator/utils/operations/channel.js\";\n\nimport { getDb } from \"../../../db/db.js\";\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess, showWarning } from \"../../../ui/toast.js\";\n\nimport type { Orchestrator } from \"../../../core/orchestrator/orchestrator.js\";\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport \"../shadow-claw-peerjs/shadow-claw-peerjs.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawChannelConfigStyles from \"./shadow-claw-channel-config.css\" with { type: \"css\" };\nimport shadowClawChannelConfigTemplate from \"./shadow-claw-channel-config.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-channel-config\";\n\nexport class ShadowClawChannelConfig extends ShadowClawElement {\n static styles = shadowClawChannelConfigStyles;\n static template = shadowClawChannelConfigTemplate;\n\n db: ShadowClawDatabase | null = null;\n orchestrator: Orchestrator | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n this.db = await getDb();\n this.orchestrator = orchestratorStore.orchestrator;\n\n this.bindEventListeners();\n this.setupEffects();\n await this.render();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"save-telegram-config\"]')\n ?.addEventListener(\"click\", () => this.saveTelegramConfig());\n\n root\n .querySelector('[data-action=\"save-imessage-config\"]')\n ?.addEventListener(\"click\", () => this.saveIMessageConfig());\n\n root\n .querySelector('[data-action=\"verify-telegram-config\"]')\n ?.addEventListener(\"click\", () => this.verifyTelegramConfig());\n }\n\n getOrchestrator(): Orchestrator | null {\n const current = orchestratorStore.orchestrator;\n if (current) {\n this.orchestrator = current;\n }\n\n return this.orchestrator;\n }\n\n setLoadingState(root: ShadowRoot) {\n const telegramTokenStatus = root.querySelector(\n '[data-info=\"telegram-token-status\"]',\n );\n if (telegramTokenStatus) {\n telegramTokenStatus.textContent = \"Loading Telegram settings...\";\n }\n\n const telegramChatIdsStatus = root.querySelector(\n '[data-info=\"telegram-chat-ids-status\"]',\n );\n if (telegramChatIdsStatus) {\n telegramChatIdsStatus.textContent = \"Loading Telegram settings...\";\n }\n\n const imessageChatIdsStatus = root.querySelector(\n '[data-info=\"imessage-chat-ids-status\"]',\n );\n if (imessageChatIdsStatus) {\n imessageChatIdsStatus.textContent = \"Loading iMessage settings...\";\n }\n }\n\n setupEffects() {\n this.addCleanup(\n effect(() => {\n const ready = orchestratorStore.ready;\n if (!ready) {\n return;\n }\n\n void this.render();\n }),\n );\n }\n\n updateChannelFieldAvailability(\n root: ShadowRoot,\n telegramEnabled: boolean,\n imessageEnabled: boolean,\n ) {\n const telegramTokenInput = root.querySelector(\n '[data-setting=\"telegram-token-input\"]',\n ) as HTMLInputElement | null;\n const telegramChatIdsInput = root.querySelector(\n '[data-setting=\"telegram-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const telegramUseProxyToggle = root.querySelector(\n '[data-setting=\"telegram-use-proxy-toggle\"]',\n ) as HTMLInputElement | null;\n const verifyTelegramButton = root.querySelector(\n '[data-action=\"verify-telegram-config\"]',\n ) as HTMLButtonElement | null;\n\n if (telegramTokenInput) {\n telegramTokenInput.disabled = !telegramEnabled;\n }\n\n if (telegramChatIdsInput) {\n telegramChatIdsInput.disabled = !telegramEnabled;\n }\n\n if (telegramUseProxyToggle) {\n telegramUseProxyToggle.disabled = !telegramEnabled;\n }\n\n if (verifyTelegramButton) {\n verifyTelegramButton.disabled = !telegramEnabled;\n }\n\n const imessageServerUrlInput = root.querySelector(\n '[data-setting=\"imessage-server-url-input\"]',\n ) as HTMLInputElement | null;\n const imessageApiKeyInput = root.querySelector(\n '[data-setting=\"imessage-api-key-input\"]',\n ) as HTMLInputElement | null;\n const imessageChatIdsInput = root.querySelector(\n '[data-setting=\"imessage-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n\n if (imessageServerUrlInput) {\n imessageServerUrlInput.disabled = !imessageEnabled;\n }\n\n if (imessageApiKeyInput) {\n imessageApiKeyInput.disabled = !imessageEnabled;\n }\n\n if (imessageChatIdsInput) {\n imessageChatIdsInput.disabled = !imessageEnabled;\n }\n\n root\n .querySelectorAll(\".form-group\")\n .forEach((group) => group.classList.remove(\"form-group--disabled\"));\n\n if (!telegramEnabled) {\n root\n .querySelector('[data-setting=\"telegram-token-input\"]')\n ?.closest(\".form-group\")\n ?.classList.add(\"form-group--disabled\");\n }\n\n if (!imessageEnabled) {\n root\n .querySelector('[data-setting=\"imessage-server-url-input\"]')\n ?.closest(\".form-group\")\n ?.classList.add(\"form-group--disabled\");\n }\n }\n\n async render() {\n const orchestrator = this.getOrchestrator();\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n if (!orchestrator) {\n this.setLoadingState(root);\n\n return;\n }\n\n const telegram = getTelegramConfig(orchestrator);\n const imessage = getIMessageConfig(orchestrator);\n\n const telegramTokenInput = root.querySelector(\n '[data-setting=\"telegram-token-input\"]',\n ) as HTMLInputElement | null;\n const telegramChatIdsInput = root.querySelector(\n '[data-setting=\"telegram-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const telegramUseProxyToggle = root.querySelector(\n '[data-setting=\"telegram-use-proxy-toggle\"]',\n ) as HTMLInputElement | null;\n const telegramEnabledToggle = root.querySelector(\n '[data-setting=\"telegram-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n const imessageServerUrlInput = root.querySelector(\n '[data-setting=\"imessage-server-url-input\"]',\n ) as HTMLInputElement | null;\n const imessageApiKeyInput = root.querySelector(\n '[data-setting=\"imessage-api-key-input\"]',\n ) as HTMLInputElement | null;\n const imessageChatIdsInput = root.querySelector(\n '[data-setting=\"imessage-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const imessageEnabledToggle = root.querySelector(\n '[data-setting=\"imessage-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n\n if (telegramEnabledToggle) {\n telegramEnabledToggle.checked = telegram.enabled;\n }\n\n const telegramChannelStatus = root.querySelector(\n '[data-info=\"telegram-channel-status\"]',\n );\n if (telegramChannelStatus) {\n telegramChannelStatus.textContent = telegram.enabled\n ? \"Telegram channel is enabled.\"\n : \"Telegram channel is disabled. Saved settings are retained.\";\n }\n\n if (telegramTokenInput) {\n telegramTokenInput.value = telegram.botToken;\n }\n\n const telegramTokenStatus = root.querySelector(\n '[data-info=\"telegram-token-status\"]',\n );\n if (telegramTokenStatus) {\n telegramTokenStatus.textContent = telegram.botToken\n ? \"Telegram token saved.\"\n : \"No Telegram token saved.\";\n }\n\n if (telegramChatIdsInput) {\n telegramChatIdsInput.value = telegram.chatIds.join(\", \");\n }\n\n const telegramChatIdsStatus = root.querySelector(\n '[data-info=\"telegram-chat-ids-status\"]',\n );\n if (telegramChatIdsStatus) {\n telegramChatIdsStatus.textContent = telegram.chatIds.length\n ? `Allowed Telegram chat IDs saved: ${telegram.chatIds.join(\", \")}`\n : \"No Telegram chat IDs saved.\";\n }\n\n if (telegramUseProxyToggle) {\n telegramUseProxyToggle.checked = !!telegram.useProxy;\n }\n\n const telegramProxyStatus = root.querySelector(\n '[data-info=\"telegram-proxy-status\"]',\n );\n if (telegramProxyStatus) {\n telegramProxyStatus.textContent = telegram.useProxy\n ? \"Telegram API calls are proxied through this server.\"\n : \"Telegram API calls go directly to Telegram.\";\n }\n\n if (imessageServerUrlInput) {\n imessageServerUrlInput.value = imessage.serverUrl;\n }\n\n if (imessageApiKeyInput) {\n imessageApiKeyInput.value = imessage.apiKey;\n }\n\n if (imessageChatIdsInput) {\n imessageChatIdsInput.value = imessage.chatIds.join(\", \");\n }\n\n if (imessageEnabledToggle) {\n imessageEnabledToggle.checked = imessage.enabled;\n }\n\n const imessageChannelStatus = root.querySelector(\n '[data-info=\"imessage-channel-status\"]',\n );\n if (imessageChannelStatus) {\n imessageChannelStatus.textContent = imessage.enabled\n ? \"iMessage channel is enabled.\"\n : \"iMessage channel is disabled. Saved settings are retained.\";\n }\n\n const imessageChatIdsStatus = root.querySelector(\n '[data-info=\"imessage-chat-ids-status\"]',\n );\n if (imessageChatIdsStatus) {\n imessageChatIdsStatus.textContent = imessage.chatIds.length\n ? `Allowed iMessage chat IDs saved: ${imessage.chatIds.join(\", \")}`\n : \"No iMessage chat IDs saved.\";\n }\n\n this.updateChannelFieldAvailability(\n root,\n telegram.enabled,\n imessage.enabled,\n );\n }\n\n async saveIMessageConfig() {\n const orchestrator = this.getOrchestrator();\n if (!orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const serverUrlInput = root.querySelector(\n '[data-setting=\"imessage-server-url-input\"]',\n ) as HTMLInputElement | null;\n const apiKeyInput = root.querySelector(\n '[data-setting=\"imessage-api-key-input\"]',\n ) as HTMLInputElement | null;\n const chatIdsInput = root.querySelector(\n '[data-setting=\"imessage-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const enabledToggle = root.querySelector(\n '[data-setting=\"imessage-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n\n try {\n await configureIMessage(\n orchestrator,\n this.db,\n serverUrlInput?.value || \"\",\n apiKeyInput?.value || \"\",\n parseCommaSeparatedList(chatIdsInput?.value || \"\"),\n );\n await setChannelEnabled(\n orchestrator,\n this.db,\n \"imessage\",\n !!enabledToggle?.checked,\n );\n await this.render();\n showSuccess(\"iMessage channel settings saved\", 3000);\n } catch (error) {\n showError(\n `Error saving iMessage settings: ${error instanceof Error ? error.message : String(error)}`,\n 6000,\n );\n }\n }\n\n async saveTelegramConfig() {\n const orchestrator = this.getOrchestrator();\n if (!orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const tokenInput = root.querySelector(\n '[data-setting=\"telegram-token-input\"]',\n ) as HTMLInputElement | null;\n const chatIdsInput = root.querySelector(\n '[data-setting=\"telegram-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const useProxyToggle = root.querySelector(\n '[data-setting=\"telegram-use-proxy-toggle\"]',\n ) as HTMLInputElement | null;\n const enabledToggle = root.querySelector(\n '[data-setting=\"telegram-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n\n try {\n await configureTelegram(\n orchestrator,\n this.db,\n tokenInput?.value || \"\",\n parseCommaSeparatedList(chatIdsInput?.value || \"\"),\n !!useProxyToggle?.checked,\n );\n await setChannelEnabled(\n orchestrator,\n this.db,\n \"telegram\",\n !!enabledToggle?.checked,\n );\n await this.render();\n showSuccess(\"Telegram channel settings saved\", 3000);\n } catch (error) {\n showError(\n `Error saving Telegram settings: ${error instanceof Error ? error.message : String(error)}`,\n 6000,\n );\n }\n }\n\n async verifyTelegramConfig() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const tokenInput = root.querySelector(\n '[data-setting=\"telegram-token-input\"]',\n ) as HTMLInputElement | null;\n const token = tokenInput?.value?.trim() || \"\";\n const telegramUseProxyToggle = root.querySelector(\n '[data-setting=\"telegram-use-proxy-toggle\"]',\n ) as HTMLInputElement | null;\n const apiBase = telegramUseProxyToggle?.checked\n ? \"/telegram/bot\"\n : \"https://api.telegram.org/bot\";\n\n if (!token) {\n showError(\"Telegram bot token is empty. Save the token first.\", 5000);\n\n return;\n }\n\n try {\n const meRes = await fetch(`${apiBase}${token}/getMe`);\n const meJson = (await meRes.json()) as {\n ok?: boolean;\n description?: string;\n result?: { username?: string };\n };\n\n if (!meRes.ok || !meJson.ok) {\n throw new Error(meJson.description || `HTTP ${meRes.status}`);\n }\n\n const webhookRes = await fetch(`${apiBase}${token}/getWebhookInfo`);\n const webhookJson = (await webhookRes.json()) as {\n ok?: boolean;\n description?: string;\n result?: { url?: string };\n };\n\n if (!webhookRes.ok || !webhookJson.ok) {\n throw new Error(webhookJson.description || `HTTP ${webhookRes.status}`);\n }\n\n const webhookUrl = webhookJson.result?.url?.trim() || \"\";\n if (webhookUrl) {\n showWarning(\n `Telegram bot is valid (${meJson.result?.username || \"unknown\"}), but a webhook is enabled. Clear it with deleteWebhook before relying on getUpdates polling.`,\n 7000,\n );\n\n return;\n }\n\n showSuccess(\n `Telegram setup looks good for @${meJson.result?.username || \"unknown\"}. Token works and no webhook is active.`,\n 5000,\n );\n } catch (error) {\n showError(\n `Telegram verification failed: ${error instanceof Error ? error.message : String(error)}`,\n 7000,\n );\n }\n }\n}\n\nfunction parseCommaSeparatedList(value: string): string[] {\n return Array.from(\n new Set(\n value\n .split(\",\")\n .map((entry) => entry.trim())\n .filter(Boolean),\n ),\n );\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawChannelConfig);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shadow-claw-channel-config-DmfwJc6G.js","names":["shadowClawChannelConfigStyles","shadowClawChannelConfigTemplate"],"sources":["../../src/components/settings/shadow-claw-channel-config/shadow-claw-channel-config.ts"],"sourcesContent":["import { effect } from \"../../../core/effect.js\";\n\nimport {\n configureIMessage,\n configureTelegram,\n getIMessageConfig,\n getTelegramConfig,\n setChannelEnabled,\n} from \"../../../core/orchestrator/utils/operations/channel.js\";\n\nimport { getDb } from \"../../../db/db.js\";\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess, showWarning } from \"../../../ui/toast.js\";\n\nimport type { Orchestrator } from \"../../../core/orchestrator/orchestrator.js\";\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport \"../shadow-claw-peerjs/shadow-claw-peerjs.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawChannelConfigStyles from \"./shadow-claw-channel-config.css\" with { type: \"css\" };\nimport shadowClawChannelConfigTemplate from \"./shadow-claw-channel-config.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-channel-config\";\n\nexport class ShadowClawChannelConfig extends ShadowClawElement {\n static styles = shadowClawChannelConfigStyles;\n static template = shadowClawChannelConfigTemplate;\n\n db: ShadowClawDatabase | null = null;\n orchestrator: Orchestrator | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n this.db = await getDb();\n this.orchestrator = orchestratorStore.orchestrator;\n\n this.bindEventListeners();\n this.setupEffects();\n await this.render();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"save-telegram-config\"]')\n ?.addEventListener(\"click\", () => this.saveTelegramConfig());\n\n root\n .querySelector('[data-action=\"save-imessage-config\"]')\n ?.addEventListener(\"click\", () => this.saveIMessageConfig());\n\n root\n .querySelector('[data-action=\"verify-telegram-config\"]')\n ?.addEventListener(\"click\", () => this.verifyTelegramConfig());\n }\n\n getOrchestrator(): Orchestrator | null {\n const current = orchestratorStore.orchestrator;\n if (current) {\n this.orchestrator = current;\n }\n\n return this.orchestrator;\n }\n\n setLoadingState(root: ShadowRoot) {\n const telegramTokenStatus = root.querySelector(\n '[data-info=\"telegram-token-status\"]',\n );\n if (telegramTokenStatus) {\n telegramTokenStatus.textContent = \"Loading Telegram settings...\";\n }\n\n const telegramChatIdsStatus = root.querySelector(\n '[data-info=\"telegram-chat-ids-status\"]',\n );\n if (telegramChatIdsStatus) {\n telegramChatIdsStatus.textContent = \"Loading Telegram settings...\";\n }\n\n const imessageChatIdsStatus = root.querySelector(\n '[data-info=\"imessage-chat-ids-status\"]',\n );\n if (imessageChatIdsStatus) {\n imessageChatIdsStatus.textContent = \"Loading iMessage settings...\";\n }\n }\n\n setupEffects() {\n this.addCleanup(\n effect(() => {\n const ready = orchestratorStore.ready;\n if (!ready) {\n return;\n }\n\n void this.render();\n }),\n );\n }\n\n updateChannelFieldAvailability(\n root: ShadowRoot,\n telegramEnabled: boolean,\n imessageEnabled: boolean,\n ) {\n const telegramTokenInput = root.querySelector(\n '[data-setting=\"telegram-token-input\"]',\n ) as HTMLInputElement | null;\n const telegramChatIdsInput = root.querySelector(\n '[data-setting=\"telegram-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const telegramUseProxyToggle = root.querySelector(\n '[data-setting=\"telegram-use-proxy-toggle\"]',\n ) as HTMLInputElement | null;\n const verifyTelegramButton = root.querySelector(\n '[data-action=\"verify-telegram-config\"]',\n ) as HTMLButtonElement | null;\n\n if (telegramTokenInput) {\n telegramTokenInput.disabled = !telegramEnabled;\n }\n\n if (telegramChatIdsInput) {\n telegramChatIdsInput.disabled = !telegramEnabled;\n }\n\n if (telegramUseProxyToggle) {\n telegramUseProxyToggle.disabled = !telegramEnabled;\n }\n\n if (verifyTelegramButton) {\n verifyTelegramButton.disabled = !telegramEnabled;\n }\n\n const imessageServerUrlInput = root.querySelector(\n '[data-setting=\"imessage-server-url-input\"]',\n ) as HTMLInputElement | null;\n const imessageApiKeyInput = root.querySelector(\n '[data-setting=\"imessage-api-key-input\"]',\n ) as HTMLInputElement | null;\n const imessageChatIdsInput = root.querySelector(\n '[data-setting=\"imessage-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n\n if (imessageServerUrlInput) {\n imessageServerUrlInput.disabled = !imessageEnabled;\n }\n\n if (imessageApiKeyInput) {\n imessageApiKeyInput.disabled = !imessageEnabled;\n }\n\n if (imessageChatIdsInput) {\n imessageChatIdsInput.disabled = !imessageEnabled;\n }\n\n root\n .querySelectorAll(\".form-group\")\n .forEach((group) => group.classList.remove(\"form-group--disabled\"));\n\n if (!telegramEnabled) {\n root\n .querySelector('[data-setting=\"telegram-token-input\"]')\n ?.closest(\".form-group\")\n ?.classList.add(\"form-group--disabled\");\n }\n\n if (!imessageEnabled) {\n root\n .querySelector('[data-setting=\"imessage-server-url-input\"]')\n ?.closest(\".form-group\")\n ?.classList.add(\"form-group--disabled\");\n }\n }\n\n async render() {\n const orchestrator = this.getOrchestrator();\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n if (!orchestrator) {\n this.setLoadingState(root);\n\n return;\n }\n\n const telegram = getTelegramConfig(orchestrator);\n const imessage = getIMessageConfig(orchestrator);\n\n const telegramTokenInput = root.querySelector(\n '[data-setting=\"telegram-token-input\"]',\n ) as HTMLInputElement | null;\n const telegramChatIdsInput = root.querySelector(\n '[data-setting=\"telegram-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const telegramUseProxyToggle = root.querySelector(\n '[data-setting=\"telegram-use-proxy-toggle\"]',\n ) as HTMLInputElement | null;\n const telegramEnabledToggle = root.querySelector(\n '[data-setting=\"telegram-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n const imessageServerUrlInput = root.querySelector(\n '[data-setting=\"imessage-server-url-input\"]',\n ) as HTMLInputElement | null;\n const imessageApiKeyInput = root.querySelector(\n '[data-setting=\"imessage-api-key-input\"]',\n ) as HTMLInputElement | null;\n const imessageChatIdsInput = root.querySelector(\n '[data-setting=\"imessage-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const imessageEnabledToggle = root.querySelector(\n '[data-setting=\"imessage-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n\n if (telegramEnabledToggle) {\n telegramEnabledToggle.checked = telegram.enabled;\n }\n\n const telegramChannelStatus = root.querySelector(\n '[data-info=\"telegram-channel-status\"]',\n );\n if (telegramChannelStatus) {\n telegramChannelStatus.textContent = telegram.enabled\n ? \"Telegram channel is enabled.\"\n : \"Telegram channel is disabled. Saved settings are retained.\";\n }\n\n if (telegramTokenInput) {\n telegramTokenInput.value = telegram.botToken;\n }\n\n const telegramTokenStatus = root.querySelector(\n '[data-info=\"telegram-token-status\"]',\n );\n if (telegramTokenStatus) {\n telegramTokenStatus.textContent = telegram.botToken\n ? \"Telegram token saved.\"\n : \"No Telegram token saved.\";\n }\n\n if (telegramChatIdsInput) {\n telegramChatIdsInput.value = telegram.chatIds.join(\", \");\n }\n\n const telegramChatIdsStatus = root.querySelector(\n '[data-info=\"telegram-chat-ids-status\"]',\n );\n if (telegramChatIdsStatus) {\n telegramChatIdsStatus.textContent = telegram.chatIds.length\n ? `Allowed Telegram chat IDs saved: ${telegram.chatIds.join(\", \")}`\n : \"No Telegram chat IDs saved.\";\n }\n\n if (telegramUseProxyToggle) {\n telegramUseProxyToggle.checked = !!telegram.useProxy;\n }\n\n const telegramProxyStatus = root.querySelector(\n '[data-info=\"telegram-proxy-status\"]',\n );\n if (telegramProxyStatus) {\n telegramProxyStatus.textContent = telegram.useProxy\n ? \"Telegram API calls are proxied through this server.\"\n : \"Telegram API calls go directly to Telegram.\";\n }\n\n if (imessageServerUrlInput) {\n imessageServerUrlInput.value = imessage.serverUrl;\n }\n\n if (imessageApiKeyInput) {\n imessageApiKeyInput.value = imessage.apiKey;\n }\n\n if (imessageChatIdsInput) {\n imessageChatIdsInput.value = imessage.chatIds.join(\", \");\n }\n\n if (imessageEnabledToggle) {\n imessageEnabledToggle.checked = imessage.enabled;\n }\n\n const imessageChannelStatus = root.querySelector(\n '[data-info=\"imessage-channel-status\"]',\n );\n if (imessageChannelStatus) {\n imessageChannelStatus.textContent = imessage.enabled\n ? \"iMessage channel is enabled.\"\n : \"iMessage channel is disabled. Saved settings are retained.\";\n }\n\n const imessageChatIdsStatus = root.querySelector(\n '[data-info=\"imessage-chat-ids-status\"]',\n );\n if (imessageChatIdsStatus) {\n imessageChatIdsStatus.textContent = imessage.chatIds.length\n ? `Allowed iMessage chat IDs saved: ${imessage.chatIds.join(\", \")}`\n : \"No iMessage chat IDs saved.\";\n }\n\n this.updateChannelFieldAvailability(\n root,\n telegram.enabled,\n imessage.enabled,\n );\n }\n\n async saveIMessageConfig() {\n const orchestrator = this.getOrchestrator();\n if (!orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const serverUrlInput = root.querySelector(\n '[data-setting=\"imessage-server-url-input\"]',\n ) as HTMLInputElement | null;\n const apiKeyInput = root.querySelector(\n '[data-setting=\"imessage-api-key-input\"]',\n ) as HTMLInputElement | null;\n const chatIdsInput = root.querySelector(\n '[data-setting=\"imessage-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const enabledToggle = root.querySelector(\n '[data-setting=\"imessage-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n\n try {\n await configureIMessage(\n orchestrator,\n this.db,\n serverUrlInput?.value || \"\",\n apiKeyInput?.value || \"\",\n parseCommaSeparatedList(chatIdsInput?.value || \"\"),\n );\n await setChannelEnabled(\n orchestrator,\n this.db,\n \"imessage\",\n !!enabledToggle?.checked,\n );\n await this.render();\n showSuccess(\"iMessage channel settings saved\", 3000);\n } catch (error) {\n showError(\n `Error saving iMessage settings: ${error instanceof Error ? error.message : String(error)}`,\n 6000,\n );\n }\n }\n\n async saveTelegramConfig() {\n const orchestrator = this.getOrchestrator();\n if (!orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const tokenInput = root.querySelector(\n '[data-setting=\"telegram-token-input\"]',\n ) as HTMLInputElement | null;\n const chatIdsInput = root.querySelector(\n '[data-setting=\"telegram-chat-ids-input\"]',\n ) as HTMLInputElement | null;\n const useProxyToggle = root.querySelector(\n '[data-setting=\"telegram-use-proxy-toggle\"]',\n ) as HTMLInputElement | null;\n const enabledToggle = root.querySelector(\n '[data-setting=\"telegram-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n\n try {\n await configureTelegram(\n orchestrator,\n this.db,\n tokenInput?.value || \"\",\n parseCommaSeparatedList(chatIdsInput?.value || \"\"),\n !!useProxyToggle?.checked,\n );\n await setChannelEnabled(\n orchestrator,\n this.db,\n \"telegram\",\n !!enabledToggle?.checked,\n );\n await this.render();\n showSuccess(\"Telegram channel settings saved\", 3000);\n } catch (error) {\n showError(\n `Error saving Telegram settings: ${error instanceof Error ? error.message : String(error)}`,\n 6000,\n );\n }\n }\n\n async verifyTelegramConfig() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const tokenInput = root.querySelector(\n '[data-setting=\"telegram-token-input\"]',\n ) as HTMLInputElement | null;\n const token = tokenInput?.value?.trim() || \"\";\n const telegramUseProxyToggle = root.querySelector(\n '[data-setting=\"telegram-use-proxy-toggle\"]',\n ) as HTMLInputElement | null;\n const apiBase = telegramUseProxyToggle?.checked\n ? \"/telegram/bot\"\n : \"https://api.telegram.org/bot\";\n\n if (!token) {\n showError(\"Telegram bot token is empty. Save the token first.\", 5000);\n\n return;\n }\n\n try {\n const meRes = await fetch(`${apiBase}${token}/getMe`);\n const meJson = (await meRes.json()) as {\n ok?: boolean;\n description?: string;\n result?: { username?: string };\n };\n\n if (!meRes.ok || !meJson.ok) {\n throw new Error(meJson.description || `HTTP ${meRes.status}`);\n }\n\n const webhookRes = await fetch(`${apiBase}${token}/getWebhookInfo`);\n const webhookJson = (await webhookRes.json()) as {\n ok?: boolean;\n description?: string;\n result?: { url?: string };\n };\n\n if (!webhookRes.ok || !webhookJson.ok) {\n throw new Error(webhookJson.description || `HTTP ${webhookRes.status}`);\n }\n\n const webhookUrl = webhookJson.result?.url?.trim() || \"\";\n if (webhookUrl) {\n showWarning(\n `Telegram bot is valid (${meJson.result?.username || \"unknown\"}), but a webhook is enabled. Clear it with deleteWebhook before relying on getUpdates polling.`,\n 7000,\n );\n\n return;\n }\n\n showSuccess(\n `Telegram setup looks good for @${meJson.result?.username || \"unknown\"}. Token works and no webhook is active.`,\n 5000,\n );\n } catch (error) {\n showError(\n `Telegram verification failed: ${error instanceof Error ? error.message : String(error)}`,\n 7000,\n );\n }\n }\n}\n\nfunction parseCommaSeparatedList(value: string): string[] {\n return Array.from(\n new Set(\n value\n .split(\",\")\n .map((entry) => entry.trim())\n .filter(Boolean),\n ),\n );\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawChannelConfig);\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ShadowClawElement from "./components/shadow-claw-element.js";
|
|
2
2
|
import "./shadow-claw-page-header-action-button-BXXm5b5N.js";
|
|
3
|
-
import "./shadow-claw-page-header-
|
|
4
|
-
import "./shadow-claw-channel-config-
|
|
3
|
+
import "./shadow-claw-page-header-Cti2fzf-.js";
|
|
4
|
+
import "./shadow-claw-channel-config-DmfwJc6G.js";
|
|
5
5
|
|
|
6
6
|
//#region src/components/shadow-claw-channels/shadow-claw-channels.css
|
|
7
7
|
const sheet = new CSSStyleSheet();
|
|
@@ -110,4 +110,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
|
|
|
110
110
|
|
|
111
111
|
//#endregion
|
|
112
112
|
export { ShadowClawChannels as t };
|
|
113
|
-
//# sourceMappingURL=shadow-claw-channels-
|
|
113
|
+
//# sourceMappingURL=shadow-claw-channels-1N6Jl-By.js.map
|
package/dist/lib/{shadow-claw-channels-C_jI4KhP.js.map → shadow-claw-channels-1N6Jl-By.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-claw-channels-
|
|
1
|
+
{"version":3,"file":"shadow-claw-channels-1N6Jl-By.js","names":["shadowClawChannelsStyles","shadowClawChannelsTemplate"],"sources":["../../src/components/shadow-claw-channels/shadow-claw-channels.ts"],"sourcesContent":["import \"../common/shadow-claw-page-header-action-button/shadow-claw-page-header-action-button.js\";\nimport \"../settings/shadow-claw-channel-config/shadow-claw-channel-config.js\";\nimport \"../shadow-claw-page-header/shadow-claw-page-header.js\";\n\nimport ShadowClawElement from \"../shadow-claw-element.js\";\nimport shadowClawChannelsStyles from \"./shadow-claw-channels.css\" with { type: \"css\" };\nimport shadowClawChannelsTemplate from \"./shadow-claw-channels.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-channels\";\n\nexport class ShadowClawChannels extends ShadowClawElement {\n static styles = shadowClawChannelsStyles;\n static template = shadowClawChannelsTemplate;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n await this.render();\n }\n\n async render() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"back-to-settings\"]')\n ?.addEventListener(\"click\", () => {\n this.dispatchEvent(\n new CustomEvent(\"navigate-back\", {\n bubbles: true,\n composed: true,\n }),\n );\n });\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawChannels);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,MAAM,cAAc;AAEpB,IAAa,qBAAb,cAAwC,kBAAkB;CACxD,OAAO,SAASA;CAChB,OAAO,WAAWC;CAElB,cAAc;EACZ,MAAM;CACR;CAEA,MAAM,oBAAoB;EAExB,IAAI,CADS,KAAK,YAEhB,MAAM,IAAI,MAAM,sBAAsB;EAGxC,MAAM,KAAK,OAAO;CACpB;CAEA,MAAM,SAAS;EACb,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,KACG,cAAc,oCAAkC,CAAC,EAChD,iBAAiB,eAAe;GAChC,KAAK,cACH,IAAI,YAAY,iBAAiB;IAC/B,SAAS;IACT,UAAU;GACZ,CAAC,CACH;EACF,CAAC;CACL;AACF;AAEA,IAAI,CAAC,eAAe,IAAI,WAAW,GACjC,eAAe,OAAO,aAAa,kBAAkB"}
|
|
@@ -3,26 +3,26 @@ import ShadowClawElement from "./components/shadow-claw-element.js";
|
|
|
3
3
|
import { n as getDb, t as txPromise } from "./txPromise-CuGh-TGK.js";
|
|
4
4
|
import { c as DEFAULT_PROMPT_API_FALLBACK_MODEL, l as DEFAULT_PROVIDER, r as CONFIG_KEYS } from "./config--CFrw3J3.js";
|
|
5
5
|
import { t as getConfig } from "./getConfig-BxxXMyuM.js";
|
|
6
|
-
import { t as readGroupFileBytes } from "./readGroupFileBytes-
|
|
7
|
-
import {
|
|
8
|
-
import { t as
|
|
6
|
+
import { t as readGroupFileBytes } from "./readGroupFileBytes-C8oOe8Iu.js";
|
|
7
|
+
import { t as fileViewerStore } from "./file-viewer-C3YKnq_-.js";
|
|
8
|
+
import { bt as saveMessage, dn as formatModelAttachmentCapabilitySummary, fn as getAttachmentCategory, o as clearGroupMessages, pn as getModelAttachmentCapabilities, t as orchestratorStore } from "./orchestrator-KRjx0eba.js";
|
|
9
9
|
import { t as setConfig } from "./setConfig-BFED5CXn.js";
|
|
10
|
-
import { d as handleSpecialLinkNavigation, l as formatDateForFilename, n as setSanitizedHtml, u as formatTimestamp } from "./trusted-types-
|
|
10
|
+
import { d as handleSpecialLinkNavigation, l as formatDateForFilename, n as setSanitizedHtml, u as formatTimestamp } from "./trusted-types-Dx0RZlrd.js";
|
|
11
11
|
import { t as require_browser } from "./browser-FvTfy_Ym.js";
|
|
12
12
|
import { t as require_buffer } from "./buffer-BEXn271X.js";
|
|
13
13
|
import { a as showSuccess, i as showInfo, r as showError, s as showWarning } from "./toast-DZ6r7_YI.js";
|
|
14
14
|
import { getNamespacedItem } from "./utils/namespacedStorage.js";
|
|
15
15
|
import { i as renderPromptApiStatusHtml, n as isNativePromptApiSupported, r as isPromptApiPotentiallySupported } from "./prompt-api-DJvb1BN7.js";
|
|
16
16
|
import { t as effect } from "./effect-DL6j9HJp.js";
|
|
17
|
-
import { t as renderMarkdown } from "./markdown-
|
|
18
|
-
import { i as inferAttachmentMimeType, n as transferProgressSignal, o as shouldInlineAttachmentInChat } from "./peerjs-
|
|
19
|
-
import { t as downloadGroupFile } from "./downloadGroupFile-
|
|
20
|
-
import { n as chatUiStore } from "./shadow-claw-a2ui-
|
|
17
|
+
import { t as renderMarkdown } from "./markdown-C6EHl9zs.js";
|
|
18
|
+
import { i as inferAttachmentMimeType, n as transferProgressSignal, o as shouldInlineAttachmentInChat } from "./peerjs-DFWOBcXf.js";
|
|
19
|
+
import { t as downloadGroupFile } from "./downloadGroupFile-DmcBQU1n.js";
|
|
20
|
+
import { n as chatUiStore } from "./shadow-claw-a2ui-CpZUTzlh.js";
|
|
21
21
|
import { t as isTruthyConfigValue } from "./config-value-Cxggje2K.js";
|
|
22
22
|
import "./shadow-claw-page-header-action-button-BXXm5b5N.js";
|
|
23
23
|
import "./components/shadow-claw-a2ui-interceptor.js";
|
|
24
24
|
import "./components/shadow-claw-dialog.js";
|
|
25
|
-
import "./shadow-claw-page-header-
|
|
25
|
+
import "./shadow-claw-page-header-Cti2fzf-.js";
|
|
26
26
|
|
|
27
27
|
//#region node_modules/jszip/dist/jszip.min.js
|
|
28
28
|
var require_jszip_min = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -6558,4 +6558,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
|
|
|
6558
6558
|
|
|
6559
6559
|
//#endregion
|
|
6560
6560
|
export { ShadowClawChat as t };
|
|
6561
|
-
//# sourceMappingURL=shadow-claw-chat-
|
|
6561
|
+
//# sourceMappingURL=shadow-claw-chat-BMoqQJRK.js.map
|