shadow-claw 1.34.5 → 1.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/.well-known/mcp/server-card.json +1 -1
  2. package/.well-known/mcp.json +1 -1
  3. package/README.md +5 -1
  4. package/dist/cli/build/build.js +1 -1
  5. package/dist/cli/{chunk-B4a6SyOL.js → chunk-6dsqmo6-.js} +3 -3
  6. package/dist/cli/chunk-BCLxzLO92.js +5 -0
  7. package/dist/cli/chunk-BHNCi3ui2.js +1 -0
  8. package/dist/cli/chunk-BMPhLSn8.js +1 -0
  9. package/dist/cli/chunk-BMW6QB5-2.js +27 -0
  10. package/dist/cli/chunk-BQCWtrzh.js +1 -0
  11. package/dist/cli/chunk-BQCWtrzh2.js +1 -0
  12. package/dist/cli/chunk-BT2f5jvi.js +1 -0
  13. package/dist/cli/chunk-BdJUjMuz.js +1 -0
  14. package/dist/cli/{chunk-DoHbMaWn.js → chunk-BwtEsB9s.js} +6 -6
  15. package/dist/cli/chunk-C47WdxKx2.js +1 -0
  16. package/dist/cli/{chunk-BRiGkTIi.js → chunk-CAqvQuGr.js} +1 -1
  17. package/dist/cli/{chunk-DoVxObGa2.js → chunk-CHzhUS1N2.js} +1 -1
  18. package/dist/cli/chunk-CUMlq7Jw2.js +263 -0
  19. package/dist/cli/chunk-CXi9LU9e2.js +110 -0
  20. package/dist/cli/chunk-ChefnX-r.js +110 -0
  21. package/dist/cli/{chunk-zvi71-77.js → chunk-D3JxbzjI2.js} +15 -15
  22. package/dist/cli/chunk-D7VYMl092.js +1 -0
  23. package/dist/cli/chunk-DMRbWmO2.js +1 -0
  24. package/dist/cli/chunk-DNIduiJ82.js +91 -0
  25. package/dist/cli/{chunk-C4UfzPK4.js → chunk-DTbrldk_.js} +1 -1
  26. package/dist/cli/chunk-DZ8YBXax.js +969 -0
  27. package/dist/cli/chunk-DduRvw8B2.js +1 -0
  28. package/dist/cli/chunk-DnYxGjdu2.js +1 -0
  29. package/dist/cli/chunk-Du5qiUIk.js +2 -0
  30. package/dist/cli/chunk-Ea7nXmgb2.js +1 -0
  31. package/dist/cli/{chunk-D9dku_3t.js → chunk-EohNY8vW.js} +1 -1
  32. package/dist/cli/chunk-LIIpZlwP2.js +1 -0
  33. package/dist/cli/chunk-LIJZHJml2.js +1 -0
  34. package/dist/cli/chunk-MHBh2BgF2.js +91 -0
  35. package/dist/cli/{chunk-BQ7lHA7c.js → chunk-SKgLGyTY.js} +1 -1
  36. package/dist/cli/chunk-kcJSXcbq2.js +1 -0
  37. package/dist/cli/chunk-rJtMBaNB.js +2 -0
  38. package/dist/cli/cli.js +12 -11
  39. package/dist/headless-agent.js +191 -187
  40. package/dist/lib/components/index.js +21 -21
  41. package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
  42. package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
  43. package/dist/lib/components/settings/shadow-claw-git.js +1 -1
  44. package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
  45. package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
  46. package/dist/lib/components/settings/shadow-claw-notifications.js +1 -1
  47. package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
  48. package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
  49. package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
  50. package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
  51. package/dist/lib/components/shadow-claw-channel-config.js +1 -1
  52. package/dist/lib/components/shadow-claw-channels.js +1 -1
  53. package/dist/lib/components/shadow-claw-chat.js +1 -1
  54. package/dist/lib/components/shadow-claw-control-plane.js +1 -1
  55. package/dist/lib/components/shadow-claw-conversations.js +1 -1
  56. package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
  57. package/dist/lib/components/shadow-claw-files.js +1 -1
  58. package/dist/lib/components/shadow-claw-git.js +1 -1
  59. package/dist/lib/components/shadow-claw-llm.js +1 -1
  60. package/dist/lib/components/shadow-claw-networking.js +1 -1
  61. package/dist/lib/components/shadow-claw-notifications.js +1 -1
  62. package/dist/lib/components/shadow-claw-pages.js +1 -1
  63. package/dist/lib/components/shadow-claw-peerjs.js +1 -1
  64. package/dist/lib/components/shadow-claw-settings.js +1 -1
  65. package/dist/lib/components/shadow-claw-storage.js +1 -1
  66. package/dist/lib/components/shadow-claw-task-server.js +1 -1
  67. package/dist/lib/components/shadow-claw-tasks.js +1 -1
  68. package/dist/lib/components/shadow-claw-terminal.js +1 -1
  69. package/dist/lib/components/shadow-claw-tools.js +1 -1
  70. package/dist/lib/components/shadow-claw-webvm.js +1 -1
  71. package/dist/lib/components/shadow-claw.js +1 -1
  72. package/dist/lib/{configurePeerJs-DSRcNp3v.js → configurePeerJs-CdPzmpyI.js} +2 -2
  73. package/dist/lib/{configurePeerJs-DSRcNp3v.js.map → configurePeerJs-CdPzmpyI.js.map} +1 -1
  74. package/dist/lib/index.js +21 -21
  75. package/dist/lib/{initControlPlane-CWfE_Oan.js → initControlPlane-BLymRW34.js} +7 -7
  76. package/dist/lib/{initControlPlane-CWfE_Oan.js.map → initControlPlane-BLymRW34.js.map} +1 -1
  77. package/dist/lib/{orchestrator-BEUug1TW.js → orchestrator-DZkhJj7f.js} +13 -2
  78. package/dist/lib/{orchestrator-BEUug1TW.js.map → orchestrator-DZkhJj7f.js.map} +1 -1
  79. package/dist/lib/{orchestrator-CGUzfGbE.js → orchestrator-ZsQTRknI.js} +5 -5
  80. package/dist/lib/{orchestrator-CGUzfGbE.js.map → orchestrator-ZsQTRknI.js.map} +1 -1
  81. package/dist/lib/{peerjs-BSD88rT3.js → peerjs-CJYfnR5V.js} +3 -3
  82. package/dist/lib/{peerjs-BSD88rT3.js.map → peerjs-CJYfnR5V.js.map} +1 -1
  83. package/dist/lib/{push-client-CC3qifgc.js → push-client-C9hIPqLZ.js} +2 -2
  84. package/dist/lib/{push-client-CC3qifgc.js.map → push-client-C9hIPqLZ.js.map} +1 -1
  85. package/dist/lib/{shadow-claw-BWS-UVnE.js → shadow-claw-8qL2-QoK.js} +4 -4
  86. package/dist/lib/{shadow-claw-BWS-UVnE.js.map → shadow-claw-8qL2-QoK.js.map} +1 -1
  87. package/dist/lib/{shadow-claw-channel-config-DwMn3nFJ.js → shadow-claw-channel-config-CvnbqGBy.js} +3 -3
  88. package/dist/lib/{shadow-claw-channel-config-DwMn3nFJ.js.map → shadow-claw-channel-config-CvnbqGBy.js.map} +1 -1
  89. package/dist/lib/{shadow-claw-channels-BdE4cUlx.js → shadow-claw-channels-CkCvjWn1.js} +2 -2
  90. package/dist/lib/{shadow-claw-channels-BdE4cUlx.js.map → shadow-claw-channels-CkCvjWn1.js.map} +1 -1
  91. package/dist/lib/{shadow-claw-chat-DqaMoE9C.js → shadow-claw-chat-B1YEHKN3.js} +3 -3
  92. package/dist/lib/{shadow-claw-chat-DqaMoE9C.js.map → shadow-claw-chat-B1YEHKN3.js.map} +1 -1
  93. package/dist/lib/{shadow-claw-control-plane-D3DUDO29.js → shadow-claw-control-plane-jjo789IE.js} +6 -6
  94. package/dist/lib/{shadow-claw-control-plane-D3DUDO29.js.map → shadow-claw-control-plane-jjo789IE.js.map} +1 -1
  95. package/dist/lib/{shadow-claw-conversations-XT-OXogj.js → shadow-claw-conversations-MMT7wYH3.js} +2 -2
  96. package/dist/lib/{shadow-claw-conversations-XT-OXogj.js.map → shadow-claw-conversations-MMT7wYH3.js.map} +1 -1
  97. package/dist/lib/{shadow-claw-file-viewer-DJqxyd97.js → shadow-claw-file-viewer-qSkD1RQK.js} +2 -2
  98. package/dist/lib/{shadow-claw-file-viewer-DJqxyd97.js.map → shadow-claw-file-viewer-qSkD1RQK.js.map} +1 -1
  99. package/dist/lib/{shadow-claw-files-CUEJlA1o.js → shadow-claw-files-Cg8ycQ_N.js} +2 -2
  100. package/dist/lib/{shadow-claw-files-CUEJlA1o.js.map → shadow-claw-files-Cg8ycQ_N.js.map} +1 -1
  101. package/dist/lib/{shadow-claw-git-D_iVcb86.js → shadow-claw-git-gaClz-ZC.js} +3 -3
  102. package/dist/lib/{shadow-claw-git-D_iVcb86.js.map → shadow-claw-git-gaClz-ZC.js.map} +1 -1
  103. package/dist/lib/{shadow-claw-llm-C2msAsyU.js → shadow-claw-llm-DyOz0qzT.js} +2 -2
  104. package/dist/lib/{shadow-claw-llm-C2msAsyU.js.map → shadow-claw-llm-DyOz0qzT.js.map} +1 -1
  105. package/dist/lib/{shadow-claw-networking-D2NvodC-.js → shadow-claw-networking-B2xx0UUR.js} +2 -2
  106. package/dist/lib/{shadow-claw-networking-D2NvodC-.js.map → shadow-claw-networking-B2xx0UUR.js.map} +1 -1
  107. package/dist/lib/{shadow-claw-notifications-BcvVn_vu.js → shadow-claw-notifications-BjKfZy0k.js} +2 -2
  108. package/dist/lib/{shadow-claw-notifications-BcvVn_vu.js.map → shadow-claw-notifications-BjKfZy0k.js.map} +1 -1
  109. package/dist/lib/{shadow-claw-pages-CTMXRhEX.js → shadow-claw-pages-CJ2tsMtL.js} +2 -2
  110. package/dist/lib/{shadow-claw-pages-CTMXRhEX.js.map → shadow-claw-pages-CJ2tsMtL.js.map} +1 -1
  111. package/dist/lib/{shadow-claw-peerjs-C2YvypqM.js → shadow-claw-peerjs-CazCkXQ1.js} +3 -3
  112. package/dist/lib/{shadow-claw-peerjs-C2YvypqM.js.map → shadow-claw-peerjs-CazCkXQ1.js.map} +1 -1
  113. package/dist/lib/{shadow-claw-settings-B0hiDwEt.js → shadow-claw-settings-qro6pO9I.js} +2 -2
  114. package/dist/lib/{shadow-claw-settings-B0hiDwEt.js.map → shadow-claw-settings-qro6pO9I.js.map} +1 -1
  115. package/dist/lib/{shadow-claw-storage-Dt4yg4Q4.js → shadow-claw-storage-ewDdvCGa.js} +2 -2
  116. package/dist/lib/{shadow-claw-storage-Dt4yg4Q4.js.map → shadow-claw-storage-ewDdvCGa.js.map} +1 -1
  117. package/dist/lib/{shadow-claw-task-server-B2gbZaz4.js → shadow-claw-task-server-DpqQcNIs.js} +2 -2
  118. package/dist/lib/{shadow-claw-task-server-B2gbZaz4.js.map → shadow-claw-task-server-DpqQcNIs.js.map} +1 -1
  119. package/dist/lib/{shadow-claw-tasks-Bxq-niuM.js → shadow-claw-tasks-B2fMF4qE.js} +2 -2
  120. package/dist/lib/{shadow-claw-tasks-Bxq-niuM.js.map → shadow-claw-tasks-B2fMF4qE.js.map} +1 -1
  121. package/dist/lib/{shadow-claw-terminal-BfbW3xtg.js → shadow-claw-terminal-B25kQJC3.js} +2 -2
  122. package/dist/lib/{shadow-claw-terminal-BfbW3xtg.js.map → shadow-claw-terminal-B25kQJC3.js.map} +1 -1
  123. package/dist/lib/{shadow-claw-tools-BNSAaK0Y.js → shadow-claw-tools-B0y8JzoA.js} +10 -3
  124. package/dist/lib/{shadow-claw-tools-BNSAaK0Y.js.map → shadow-claw-tools-B0y8JzoA.js.map} +1 -1
  125. package/dist/lib/{shadow-claw-webvm-Dc2KmEXq.js → shadow-claw-webvm-CoCedIza.js} +2 -2
  126. package/dist/lib/{shadow-claw-webvm-Dc2KmEXq.js.map → shadow-claw-webvm-CoCedIza.js.map} +1 -1
  127. package/dist/lib/{syncWebMcpRegistration-BIL83P0Q.js → syncWebMcpRegistration-JKLALq4e.js} +2 -2
  128. package/dist/lib/{syncWebMcpRegistration-BIL83P0Q.js.map → syncWebMcpRegistration-JKLALq4e.js.map} +1 -1
  129. package/dist/lib/worker/utils/sandboxedEval.d.ts +8 -0
  130. package/dist/public/.well-known/mcp/server-card.json +1 -1
  131. package/dist/public/.well-known/mcp.json +1 -1
  132. package/dist/public/AGENTS.md +1 -1
  133. package/dist/public/README.md +5 -1
  134. package/dist/public/agent.worker.js +1 -1
  135. package/dist/public/components/shadow-claw-tools/shadow-claw-tools.html +1 -1
  136. package/dist/public/{configurePeerJs-B925t9C7.js → configurePeerJs-BrHeJGw1.js} +1 -1
  137. package/dist/public/docs/decisions/headless-cli-agent-participant.md +1 -1
  138. package/dist/public/docs/example/article/index.html +1 -1
  139. package/dist/public/docs/publishing/index.html +1 -1
  140. package/dist/public/docs/skill-creator/index.html +1 -1
  141. package/dist/public/docs/subsystems/cli.md +43 -32
  142. package/dist/public/docs/subsystems/skills.md +17 -0
  143. package/dist/public/docs/subsystems/tools.md +1 -1
  144. package/dist/public/e2e/README.md +2 -2
  145. package/dist/public/{e2e-bridge-CE1xleGn.js → e2e-bridge-D_lyH__p.js} +1 -1
  146. package/dist/public/{executeTool-DtTrsZHV.js → executeTool-b6DnRhcv.js} +2 -1
  147. package/dist/public/{file-viewer-LEEStSq-.js → file-viewer-CKrQoxZi.js} +1 -1
  148. package/dist/public/index.html +1 -1
  149. package/dist/public/index.js +1 -1
  150. package/dist/public/{initControlPlane-e2JgxXEb.js → initControlPlane-Dn-XFuxg.js} +1 -1
  151. package/dist/public/llms.txt +2 -0
  152. package/dist/public/main/index.html +1 -1
  153. package/dist/public/main/memory/index.html +1 -1
  154. package/dist/public/{orchestrator-Baif6kmu.js → orchestrator-0BnBtxHO.js} +3 -2
  155. package/dist/public/{orchestrator-TndREZPL.js → orchestrator-C3GKZriH.js} +1 -1
  156. package/dist/public/{peerjs-DE6WF3h2.js → peerjs-CgfLEp2N.js} +1 -1
  157. package/dist/public/{push-client-B_IkTpNm.js → push-client-D6DLiY1s.js} +1 -1
  158. package/dist/public/service-worker.js +1 -1
  159. package/dist/public/{shadow-claw-channels-BCGz36Zl.js → shadow-claw-channels-DSijinZ9.js} +1 -1
  160. package/dist/public/{shadow-claw-chat-H9U9jbqD.js → shadow-claw-chat-BeHlAjnA.js} +1 -1
  161. package/dist/public/{shadow-claw-control-plane-CeKh64s2.js → shadow-claw-control-plane-BfF_AZSg.js} +2 -2
  162. package/dist/public/{shadow-claw-conversations-C26t1HXN.js → shadow-claw-conversations-Bb_2bVLJ.js} +1 -1
  163. package/dist/public/{shadow-claw-DBeXILmk.js → shadow-claw-f71DlRdV.js} +2 -2
  164. package/dist/public/{shadow-claw-file-viewer-DWUoTjkr.js → shadow-claw-file-viewer-B67000Mm.js} +1 -1
  165. package/dist/public/{shadow-claw-files-BQ8DSX-z.js → shadow-claw-files-DeZZYt01.js} +1 -1
  166. package/dist/public/{shadow-claw-git-CIXyISw-.js → shadow-claw-git-Ccy25LuW.js} +2 -2
  167. package/dist/public/{shadow-claw-llm-D_GpOSZE.js → shadow-claw-llm-XjYcTlXT.js} +1 -1
  168. package/dist/public/{shadow-claw-networking-BYp5K3B7.js → shadow-claw-networking-efXQtydQ.js} +1 -1
  169. package/dist/public/{shadow-claw-notifications-ZiXmPweY.js → shadow-claw-notifications-Cq2ZSeJa.js} +1 -1
  170. package/dist/public/{shadow-claw-pages-BHXwf3BD.js → shadow-claw-pages-BVFNSSb1.js} +1 -1
  171. package/dist/public/{shadow-claw-settings-BfvDvt9c.js → shadow-claw-settings-B3sHxPh9.js} +2 -2
  172. package/dist/public/{shadow-claw-storage-Bvn85DII.js → shadow-claw-storage-DNdlzCgC.js} +1 -1
  173. package/dist/public/{shadow-claw-task-server-DZL_d8FC.js → shadow-claw-task-server-BJq0rpju.js} +1 -1
  174. package/dist/public/{shadow-claw-tasks-Cy8jzd8q.js → shadow-claw-tasks-CkF1uMeZ.js} +1 -1
  175. package/dist/public/{shadow-claw-terminal-BgEXr82T.js → shadow-claw-terminal-CnHhcpA-.js} +1 -1
  176. package/dist/public/{shadow-claw-tools-BjnssRSi.js → shadow-claw-tools-iw0fljud.js} +8 -1
  177. package/dist/public/{shadow-claw-webvm-tZ1VDoVA.js → shadow-claw-webvm-Bliu4V__.js} +1 -1
  178. package/dist/public/{syncWebMcpRegistration-CLMvJ4kV.js → syncWebMcpRegistration-D91usEMu.js} +1 -1
  179. package/package.json +1 -1
  180. package/src/cli/build/build.test.ts +11 -0
  181. package/src/cli/build/build.ts +10 -9
  182. package/src/cli/cli.ts +31 -2
  183. package/src/cli/commands/agent.test.ts +421 -0
  184. package/src/cli/commands/agent.ts +270 -20
  185. package/src/cli/commands/skills-index.test.ts +84 -2
  186. package/src/cli/commands/skills-index.ts +20 -2
  187. package/src/components/shadow-claw-tools/shadow-claw-tools.html +7 -0
  188. package/src/worker/headless-agent.ts +14 -0
  189. package/src/worker/headless-types.ts +39 -0
  190. package/src/worker/utils/native-eval-executor.test.ts +36 -0
  191. package/src/worker/utils/native-eval-executor.ts +58 -0
  192. package/src/worker/utils/sandboxedEval.ts +36 -0
  193. package/dist/cli/chunk-1BmpU7jO2.js +0 -1
  194. package/dist/cli/chunk-54Euq8Ji2.js +0 -1
  195. package/dist/cli/chunk-BTitwCgT2.js +0 -88
  196. package/dist/cli/chunk-Bjh76Dai.js +0 -1081
  197. package/dist/cli/chunk-C2HeZQ6K.js +0 -1
  198. package/dist/cli/chunk-Cdq9DIrc.js +0 -1
  199. package/dist/cli/chunk-CxdpafWg.js +0 -1
  200. package/dist/cli/chunk-DBk6e4N-.js +0 -1
  201. package/dist/cli/chunk-DEy72ZNV2.js +0 -88
  202. package/dist/cli/chunk-Da1BZyqf.js +0 -1
  203. package/dist/cli/chunk-FHsJD-Sf2.js +0 -27
  204. package/dist/cli/chunk-JBAAPRpe.js +0 -2
  205. package/dist/cli/chunk-aWgoVB7x2.js +0 -1
  206. package/dist/cli/chunk-hOceZVB92.js +0 -371
  207. package/dist/cli/chunk-pwNc6VtC2.js +0 -1
  208. package/dist/cli/chunk-uOnw3tuc.js +0 -2
@@ -2,7 +2,7 @@ import ShadowClawElement from "./components/shadow-claw-element.js";
2
2
  import { n as isSqliteDatabase, r as getDb } from "./txPromise-DdeRXi7G.js";
3
3
  import { r as CONFIG_KEYS, t as ASSISTANT_NAME } from "./config-CPHDmyTx.js";
4
4
  import { s as writeFileHandle } from "./tools-B3ImRBd3.js";
5
- import { q as setAssistantName, t as orchestratorStore } from "./orchestrator-BEUug1TW.js";
5
+ import { q as setAssistantName, t as orchestratorStore } from "./orchestrator-DZkhJj7f.js";
6
6
  import { i as formatDateForFilename } from "./utils-JdK2r116.js";
7
7
  import { n as decryptValue, r as encryptValue } from "./crypto-BPECyFrG.js";
8
8
  import { a as showSuccess, i as showInfo, r as showError } from "./toast-DZ6r7_YI.js";
@@ -1721,4 +1721,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
1721
1721
 
1722
1722
  //#endregion
1723
1723
  export { ShadowClawSettings as t };
1724
- //# sourceMappingURL=shadow-claw-settings-B0hiDwEt.js.map
1724
+ //# sourceMappingURL=shadow-claw-settings-qro6pO9I.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-claw-settings-B0hiDwEt.js","names":["shadowClawSettingsStyles","shadowClawSettingsTemplate"],"sources":["../../src/config/settings-backup.ts","../../src/components/shadow-claw-settings/shadow-claw-settings.ts"],"sourcesContent":["import { CONFIG_KEYS } from \"./config.js\";\nimport { decryptValue, encryptValue } from \"../security/crypto.js\";\nimport { writeFileHandle } from \"../storage/writeFileHandle.js\";\n\nexport type ConfigEntryRecord = { key: string; value: unknown };\nexport type PasswordPathSegment = string | number;\n\nexport interface PlaintextPasswordEntry {\n key: string;\n path: PasswordPathSegment[];\n value: string;\n}\n\nexport interface SettingsBackupPayload {\n kind: \"shadowclaw-settings-backup\";\n version: 1;\n exportedAt: number;\n includePlaintextPasswords: boolean;\n configEntries: ConfigEntryRecord[];\n plaintextPasswords?: PlaintextPasswordEntry[];\n}\n\nfunction cloneConfigValue(value: unknown): unknown {\n try {\n return JSON.parse(JSON.stringify(value));\n } catch {\n return null;\n }\n}\n\nasync function collectAndStripPasswordData(\n entries: ConfigEntryRecord[],\n includePlaintextPasswords: boolean,\n): Promise<{\n configEntries: ConfigEntryRecord[];\n plaintextPasswords: PlaintextPasswordEntry[];\n}> {\n const nextEntries: ConfigEntryRecord[] = [];\n const plaintextPasswords: PlaintextPasswordEntry[] = [];\n\n for (const entry of entries) {\n const key = entry.key;\n\n if (key === CONFIG_KEYS.STORAGE_HANDLE) {\n continue;\n }\n\n if (\n key === CONFIG_KEYS.GIT_PASSWORD ||\n key === CONFIG_KEYS.API_KEY ||\n key.startsWith(\"api_key:\") ||\n key === CONFIG_KEYS.IMESSAGE_API_KEY ||\n key === CONFIG_KEYS.TELEGRAM_BOT_TOKEN\n ) {\n if (includePlaintextPasswords && typeof entry.value === \"string\") {\n const decrypted = await decryptValue(entry.value);\n if (decrypted) {\n plaintextPasswords.push({ key, path: [], value: decrypted });\n }\n }\n\n continue;\n }\n\n const value = cloneConfigValue(entry.value);\n\n if (key === CONFIG_KEYS.GIT_ACCOUNTS && Array.isArray(value)) {\n for (let i = 0; i < value.length; i += 1) {\n const account = value[i] as Record<string, unknown>;\n if (!account || typeof account !== \"object\") {\n continue;\n }\n\n const encryptedPassword = account.password;\n if (typeof encryptedPassword === \"string\" && encryptedPassword) {\n if (includePlaintextPasswords) {\n const decrypted = await decryptValue(encryptedPassword);\n if (decrypted) {\n plaintextPasswords.push({\n key,\n path: [i, \"password\"],\n value: decrypted,\n });\n }\n }\n\n delete account.password;\n }\n }\n }\n\n if (key === CONFIG_KEYS.INTEGRATION_CONNECTIONS && Array.isArray(value)) {\n for (let i = 0; i < value.length; i += 1) {\n const record = value[i] as Record<string, unknown>;\n const credentialRef = record?.credentialRef as\n | Record<string, unknown>\n | undefined;\n\n const encryptedSecret = credentialRef?.encryptedSecret;\n if (typeof encryptedSecret === \"string\" && encryptedSecret) {\n if (includePlaintextPasswords) {\n const decrypted = await decryptValue(encryptedSecret);\n if (decrypted) {\n plaintextPasswords.push({\n key,\n path: [i, \"credentialRef\", \"encryptedSecret\"],\n value: decrypted,\n });\n }\n }\n\n delete credentialRef.encryptedSecret;\n }\n }\n }\n\n if (key === CONFIG_KEYS.REMOTE_MCP_CONNECTIONS && Array.isArray(value)) {\n for (let i = 0; i < value.length; i += 1) {\n const record = value[i] as Record<string, unknown>;\n const credentialRef = record?.credentialRef as\n | Record<string, unknown>\n | undefined;\n\n const encryptedValue = credentialRef?.encryptedValue;\n if (typeof encryptedValue === \"string\" && encryptedValue) {\n if (includePlaintextPasswords) {\n const decrypted = await decryptValue(encryptedValue);\n if (decrypted) {\n plaintextPasswords.push({\n key,\n path: [i, \"credentialRef\", \"encryptedValue\"],\n value: decrypted,\n });\n }\n }\n\n delete credentialRef.encryptedValue;\n }\n }\n }\n\n nextEntries.push({ key, value });\n }\n\n return { configEntries: nextEntries, plaintextPasswords };\n}\n\nfunction applyPathValue(\n rootValue: unknown,\n path: PasswordPathSegment[],\n nextValue: string,\n): unknown {\n if (path.length === 0) {\n return nextValue;\n }\n\n let current = rootValue as Record<string, unknown> | unknown[] | null;\n\n for (let i = 0; i < path.length - 1; i += 1) {\n const segment = path[i];\n if (typeof segment === \"number\") {\n if (!Array.isArray(current) || !current[segment]) {\n return rootValue;\n }\n\n current = current[segment] as Record<string, unknown>;\n } else {\n if (!current || typeof current !== \"object\") {\n return rootValue;\n }\n\n const next = (current as Record<string, unknown>)[segment];\n if (!next || typeof next !== \"object\") {\n return rootValue;\n }\n\n current = next as Record<string, unknown>;\n }\n }\n\n const leaf = path[path.length - 1];\n if (typeof leaf === \"number\") {\n if (!Array.isArray(current)) {\n return rootValue;\n }\n\n current[leaf] = nextValue;\n } else {\n if (!current || typeof current !== \"object\") {\n return rootValue;\n }\n\n (current as Record<string, unknown>)[leaf] = nextValue;\n }\n\n return rootValue;\n}\n\nasync function buildSettingsBackupPayload(\n entries: ConfigEntryRecord[],\n includePlaintextPasswords: boolean,\n): Promise<SettingsBackupPayload> {\n const transformed = await collectAndStripPasswordData(\n entries,\n includePlaintextPasswords,\n );\n\n return {\n kind: \"shadowclaw-settings-backup\",\n version: 1,\n exportedAt: Date.now(),\n includePlaintextPasswords,\n configEntries: transformed.configEntries,\n plaintextPasswords: includePlaintextPasswords\n ? transformed.plaintextPasswords\n : undefined,\n };\n}\n\nexport async function createSettingsBackupBlob(\n entries: ConfigEntryRecord[],\n includePlaintextPasswords: boolean,\n): Promise<Blob> {\n const payload = await buildSettingsBackupPayload(\n entries,\n includePlaintextPasswords,\n );\n\n return new Blob([JSON.stringify(payload, null, 2)], {\n type: \"application/json\",\n });\n}\n\nexport async function writeSettingsBackupToFileHandle(\n fileHandle: FileSystemFileHandle,\n entries: ConfigEntryRecord[],\n includePlaintextPasswords: boolean,\n): Promise<void> {\n const payload = await buildSettingsBackupPayload(\n entries,\n includePlaintextPasswords,\n );\n\n await writeFileHandle(fileHandle, JSON.stringify(payload, null, 2));\n}\n\nexport async function reapplyPlaintextPasswords(\n configEntries: ConfigEntryRecord[],\n plaintextPasswords: PlaintextPasswordEntry[],\n): Promise<ConfigEntryRecord[]> {\n if (!plaintextPasswords.length) {\n return configEntries;\n }\n\n const nextEntries = configEntries.map((entry) => ({\n key: entry.key,\n value: cloneConfigValue(entry.value),\n }));\n\n for (const secret of plaintextPasswords) {\n const encrypted = await encryptValue(secret.value);\n if (!encrypted) {\n continue;\n }\n\n const existingEntry = nextEntries.find((entry) => entry.key === secret.key);\n if (existingEntry) {\n existingEntry.value = applyPathValue(\n existingEntry.value,\n secret.path,\n encrypted,\n );\n } else if (secret.path.length === 0) {\n nextEntries.push({ key: secret.key, value: encrypted });\n }\n }\n\n return nextEntries;\n}\n\nexport function parseSettingsBackupPayload(raw: string): SettingsBackupPayload {\n const parsed = JSON.parse(raw) as Partial<SettingsBackupPayload>;\n\n if (\n parsed?.kind !== \"shadowclaw-settings-backup\" ||\n parsed.version !== 1 ||\n !Array.isArray(parsed.configEntries)\n ) {\n throw new Error(\"Invalid settings backup file\");\n }\n\n const plaintextPasswords = Array.isArray(parsed.plaintextPasswords)\n ? parsed.plaintextPasswords.filter((entry) => {\n return (\n entry &&\n typeof entry.key === \"string\" &&\n Array.isArray(entry.path) &&\n typeof entry.value === \"string\"\n );\n })\n : [];\n\n return {\n kind: \"shadowclaw-settings-backup\",\n version: 1,\n exportedAt:\n typeof parsed.exportedAt === \"number\" ? parsed.exportedAt : Date.now(),\n includePlaintextPasswords: !!parsed.includePlaintextPasswords,\n configEntries: parsed.configEntries\n .filter((entry) => entry && typeof entry.key === \"string\")\n .map((entry) => ({ key: entry.key, value: entry.value })),\n plaintextPasswords,\n };\n}\n","import { ASSISTANT_NAME, CONFIG_KEYS } from \"../../config/config.js\";\nimport {\n getNamespacedItem,\n setNamespacedItem,\n} from \"../../utils/namespacedStorage.js\";\n\nimport {\n createSettingsBackupBlob,\n parseSettingsBackupPayload,\n reapplyPlaintextPasswords,\n writeSettingsBackupToFileHandle,\n} from \"../../config/settings-backup.js\";\n\nimport { setAssistantName } from \"../../core/orchestrator/utils/operations/provider.js\";\nimport { getDb } from \"../../db/db.js\";\nimport { orchestratorStore } from \"../../stores/orchestrator.js\";\nimport { showError, showInfo, showSuccess } from \"../../ui/toast.js\";\nimport { formatDateForFilename } from \"../../utils/utils.js\";\nimport { isTruthyConfigValue } from \"../../common/utils/config-value.mjs\";\n\nimport type { ConfigEntryRecord } from \"../../config/settings-backup.js\";\nimport type { Orchestrator } from \"../../core/orchestrator/orchestrator.js\";\nimport { isSqliteDatabase } from \"../../db/sqlite/types.js\";\nimport type { ShadowClawDatabase } from \"../../db/types.js\";\n\nimport \"../shadow-claw-dialog/shadow-claw-dialog.js\";\nimport \"../shadow-claw-page-header/shadow-claw-page-header.js\";\n\nconst settingsTabLoaders: Record<string, (() => Promise<unknown>)[]> = {\n ai: [() => import(\"../settings/shadow-claw-llm/shadow-claw-llm.js\")],\n environment: [\n () =>\n import(\"../settings/shadow-claw-networking/shadow-claw-networking.js\"),\n () => import(\"../settings/shadow-claw-webvm/shadow-claw-webvm.js\"),\n () => import(\"../settings/shadow-claw-storage/shadow-claw-storage.js\"),\n ],\n integrations: [\n () => import(\"../settings/shadow-claw-git/shadow-claw-git.js\"),\n () => import(\"../settings/shadow-claw-accounts/shadow-claw-accounts.js\"),\n () =>\n import(\"../settings/shadow-claw-mcp-remote/shadow-claw-mcp-remote.js\"),\n () =>\n import(\"../settings/shadow-claw-control-plane/shadow-claw-control-plane.js\"),\n () =>\n import(\"../settings/shadow-claw-integrations/shadow-claw-integrations.js\"),\n () =>\n import(\"../settings/shadow-claw-task-server/shadow-claw-task-server.js\"),\n () =>\n import(\"../settings/shadow-claw-notifications/shadow-claw-notifications.js\"),\n ],\n};\n\nconst loadedSettingsTabs = new Set<string>();\n\nasync function ensureSettingsTabLoaded(tabId: string): Promise<void> {\n if (loadedSettingsTabs.has(tabId)) {\n return;\n }\n const loaders = settingsTabLoaders[tabId];\n if (loaders) {\n loadedSettingsTabs.add(tabId);\n await Promise.all(loaders.map((loader) => loader()));\n }\n}\n\nimport ShadowClawElement from \"../shadow-claw-element.js\";\nimport shadowClawSettingsStyles from \"./shadow-claw-settings.css\" with { type: \"css\" };\nimport shadowClawSettingsTemplate from \"./shadow-claw-settings.html\" with { type: \"html\" };\n\ndeclare const __PRERENDER_MAIN_MEMORY__: boolean | undefined;\n\nconst elementName = \"shadow-claw-settings\";\n\n/**\n * Parent settings component that composes the dedicated sub-components:\n *\n * - <shadow-claw-llm> — Provider, model, API key, and runtime controls\n * - <shadow-claw-networking> — CORS proxy toggle and proxy URL\n * - <shadow-claw-webvm> — VM boot mode, timeout, host, relay\n * - <shadow-claw-git> — PAT, author config\n * - <shadow-claw-storage>— OPFS, persistent, directory\n *\n * - Channels button — navigates to the channels config page\n * - Tools button — navigates to the tools config page\n * - Deployed revision footer\n */\nexport class ShadowClawSettings extends ShadowClawElement {\n static styles = shadowClawSettingsStyles;\n static template = shadowClawSettingsTemplate;\n\n activeTab = \"ai\";\n db: ShadowClawDatabase | null = null;\n orchestrator: Orchestrator | null = null;\n pendingRestoreFile: File | 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 await this.render();\n }\n\n activateTab(tabId: string | undefined) {\n if (!tabId || this.activeTab === tabId) {\n return;\n }\n\n this.activeTab = tabId;\n this.applyTabState();\n }\n\n applyTabState() {\n ensureSettingsTabLoaded(this.activeTab).catch(console.error);\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const tabButtons =\n root.querySelectorAll<HTMLButtonElement>(\"[data-tab-target]\");\n tabButtons.forEach((tabButton) => {\n const isActive = tabButton.dataset.tabTarget === this.activeTab;\n tabButton.classList.toggle(\"active\", isActive);\n tabButton.setAttribute(\"aria-selected\", String(isActive));\n tabButton.tabIndex = isActive ? 0 : -1;\n });\n\n const tabPanels = root.querySelectorAll<HTMLElement>(\"[data-tab-panel]\");\n tabPanels.forEach((tabPanel) => {\n const isActive = tabPanel.dataset.tabPanel === this.activeTab;\n tabPanel.hidden = !isActive;\n });\n }\n\n bindSettingsActions() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"backup-settings\"]')\n ?.addEventListener(\"click\", () => this.openBackupDialog());\n\n const restoreInput = root.querySelector(\n \".settings__restore-input\",\n ) as HTMLInputElement | null;\n\n root\n .querySelector('[data-action=\"restore-settings\"]')\n ?.addEventListener(\"click\", () => {\n if (restoreInput instanceof HTMLInputElement) {\n restoreInput.value = \"\";\n restoreInput.click();\n }\n });\n\n restoreInput?.addEventListener(\"change\", (event) => {\n const target = event.target;\n if (!(target instanceof HTMLInputElement)) {\n return;\n }\n\n const file = target.files?.[0] || null;\n if (!file) {\n return;\n }\n\n this.pendingRestoreFile = file;\n this.openRestoreDialog(file.name);\n });\n\n root\n .querySelector('[data-action=\"clear-settings\"]')\n ?.addEventListener(\"click\", () => this.openClearDialog());\n\n root\n .querySelector('[data-action=\"cancel-backup-settings\"]')\n ?.addEventListener(\"click\", () =>\n this.closeDialog(\".settings__backup-dialog\"),\n );\n\n root\n .querySelector('[data-action=\"confirm-backup-settings\"]')\n ?.addEventListener(\"click\", () => {\n void this.confirmBackup();\n });\n\n root\n .querySelector('[data-action=\"cancel-restore-settings\"]')\n ?.addEventListener(\"click\", () => {\n this.pendingRestoreFile = null;\n this.closeDialog(\".settings__restore-dialog\");\n });\n\n root\n .querySelector('[data-action=\"confirm-restore-settings\"]')\n ?.addEventListener(\"click\", () => {\n void this.confirmRestore();\n });\n\n root\n .querySelector('[data-action=\"cancel-clear-settings\"]')\n ?.addEventListener(\"click\", () =>\n this.closeDialog(\".settings__clear-dialog\"),\n );\n\n root\n .querySelector('[data-action=\"confirm-clear-settings\"]')\n ?.addEventListener(\"click\", () => {\n void this.confirmClear();\n });\n\n root\n .querySelector('[data-action=\"save-assistant-name\"]')\n ?.addEventListener(\"click\", () => this.saveAssistantName());\n\n root\n .querySelector('[data-setting=\"activity-log-disk-logging-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onActivityLogDiskLoggingToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"sidebar-hide-pages-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onSidebarHidePagesToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"sidebar-hide-chat-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onSidebarHideChatToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"sidebar-hide-tasks-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onSidebarHideTasksToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"sidebar-hide-files-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onSidebarHideFilesToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"chat-split-view-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onChatSplitViewToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"pages-auto-refresh-input\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n const val = parseInt(target.value, 10);\n void this.onPagesAutoRefreshInputChange(isNaN(val) ? 0 : val);\n }\n });\n\n root\n .querySelector('[data-setting=\"override-prerender-skeleton-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onOverridePrerenderSkeletonToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-action=\"save-dom-allowed-iframe-hosts\"]')\n ?.addEventListener(\"click\", () => {\n void this.saveDomAllowedIframeHosts();\n });\n }\n\n closeDialog(selector: string) {\n this.getDialog(selector)?.close();\n }\n\n getDialog(selector: string): HTMLDialogElement | null {\n const root = this.shadowRoot;\n if (!root) {\n return null;\n }\n\n const dialog = root.querySelector(selector);\n if (!(dialog instanceof HTMLDialogElement)) {\n return null;\n }\n\n return dialog;\n }\n\n handleTabKeydown(event: KeyboardEvent, currentButton: HTMLButtonElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const tabButtons = Array.from(\n root.querySelectorAll<HTMLButtonElement>(\"[data-tab-target]\"),\n );\n\n const currentIndex = tabButtons.indexOf(currentButton);\n if (currentIndex < 0) {\n return;\n }\n\n let nextIndex = -1;\n\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n nextIndex = (currentIndex + 1) % tabButtons.length;\n\n break;\n case \"ArrowLeft\":\n case \"ArrowUp\":\n nextIndex = (currentIndex - 1 + tabButtons.length) % tabButtons.length;\n\n break;\n case \"Home\":\n nextIndex = 0;\n\n break;\n case \"End\":\n nextIndex = tabButtons.length - 1;\n\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextButton = tabButtons[nextIndex];\n nextButton.focus();\n this.activateTab(nextButton.dataset.tabTarget);\n }\n\n openBackupDialog() {\n const root = this.shadowRoot;\n const includePlaintextToggle = root?.querySelector(\n '[data-setting=\"include-plaintext-passwords\"]',\n );\n\n if (includePlaintextToggle instanceof HTMLInputElement) {\n includePlaintextToggle.checked = false;\n }\n\n this.showDialog(\".settings__backup-dialog\");\n }\n\n openClearDialog() {\n this.showDialog(\".settings__clear-dialog\");\n }\n\n openRestoreDialog(fileName: string) {\n const root = this.shadowRoot;\n const info = root?.querySelector('[data-info=\"restore-filename\"]');\n if (info instanceof HTMLElement) {\n info.textContent = `Selected file: ${fileName}`;\n }\n\n this.showDialog(\".settings__restore-dialog\");\n }\n\n showDialog(selector: string) {\n const dialog = this.getDialog(selector);\n if (!dialog) {\n return;\n }\n\n if (typeof dialog.showModal === \"function\") {\n dialog.showModal();\n\n return;\n }\n\n dialog.setAttribute(\"open\", \"\");\n }\n\n async confirmBackup() {\n if (!this.db) {\n showError(\"Settings database is unavailable\", 5000);\n\n return;\n }\n\n const root = this.shadowRoot;\n const includePlaintextToggle = root?.querySelector(\n '[data-setting=\"include-plaintext-passwords\"]',\n );\n\n const includePlaintextPasswords =\n includePlaintextToggle instanceof HTMLInputElement\n ? includePlaintextToggle.checked\n : false;\n\n try {\n if (includePlaintextPasswords) {\n const fileHandle = await this.promptForPlaintextBackupHandle();\n if (!fileHandle) {\n return;\n }\n\n const entries = await this.getAllConfigEntries();\n\n await writeSettingsBackupToFileHandle(\n fileHandle,\n entries,\n includePlaintextPasswords,\n );\n\n this.closeDialog(\".settings__backup-dialog\");\n showSuccess(\"Settings backup saved\", 3000);\n\n return;\n }\n\n const entries = await this.getAllConfigEntries();\n const blob = await createSettingsBackupBlob(\n entries,\n includePlaintextPasswords,\n );\n\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `shadowclaw-settings-backup-${Date.now()}.json`;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n\n this.closeDialog(\".settings__backup-dialog\");\n showSuccess(\"Settings backup downloaded\", 3000);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n showError(`Failed to backup settings: ${message}`, 6000);\n }\n }\n\n async confirmClear() {\n if (!this.db) {\n showError(\"Settings database is unavailable\", 5000);\n\n return;\n }\n\n try {\n await this.replaceConfigEntries([]);\n this.closeDialog(\".settings__clear-dialog\");\n showInfo(\"Settings cleared. Reloading app...\", 3200);\n\n setTimeout(() => {\n window.location.reload();\n }, 250);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n showError(`Failed to clear settings: ${message}`, 6000);\n }\n }\n\n async confirmRestore() {\n if (!this.db) {\n showError(\"Settings database is unavailable\", 5000);\n\n return;\n }\n\n const file = this.pendingRestoreFile;\n if (!file) {\n showError(\"No backup file selected\", 4000);\n\n return;\n }\n\n try {\n const text = await file.text();\n const backup = parseSettingsBackupPayload(text);\n const mergedEntries = await reapplyPlaintextPasswords(\n backup.configEntries,\n backup.plaintextPasswords || [],\n );\n\n await this.replaceConfigEntries(mergedEntries);\n this.pendingRestoreFile = null;\n this.closeDialog(\".settings__restore-dialog\");\n\n showSuccess(\"Settings restored. Reloading app...\", 3200);\n setTimeout(() => {\n window.location.reload();\n }, 250);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n showError(`Failed to restore settings: ${message}`, 6000);\n }\n }\n\n async getAllConfigEntries(): Promise<ConfigEntryRecord[]> {\n if (!this.db) {\n throw new Error(\"Database is unavailable\");\n }\n\n if (isSqliteDatabase(this.db)) {\n const raw = this.db.db;\n const rows = (raw\n .prepare(\"SELECT key, value FROM config ORDER BY key\")\n .all() ?? []) as any[];\n return rows\n .filter((row) => row && typeof row.key === \"string\")\n .map((row) => ({ key: row.key, value: row.value }));\n }\n\n const idb = this.db as IDBDatabase;\n return await new Promise((resolve, reject) => {\n try {\n const tx = idb.transaction(\"config\", \"readonly\");\n if (!tx) {\n reject(new Error(\"Failed to open read transaction\"));\n\n return;\n }\n\n const store = tx.objectStore(\"config\");\n const request = store.getAll();\n\n request.onsuccess = () => {\n const rows = Array.isArray(request.result) ? request.result : [];\n resolve(\n rows\n .filter((row) => row && typeof row.key === \"string\")\n .map((row) => ({ key: row.key, value: row.value })),\n );\n };\n\n request.onerror = () => {\n reject(request.error || new Error(\"Failed to read settings config\"));\n };\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async onActivityLogDiskLoggingToggle(enabled: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.ACTIVITY_LOG_DISK_LOGGING_ENABLED,\n enabled ? \"true\" : \"false\",\n );\n\n showSuccess(\n enabled\n ? \"Activity log disk logging enabled\"\n : \"Activity log disk logging disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\n \"Error saving activity log disk logging setting: \" + errorMsg,\n 6000,\n );\n }\n }\n\n async onChatSplitViewToggle(enabled: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.CHAT_SPLIT_VIEW_ENABLED,\n enabled ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"chat-split-view-change\", {\n detail: { enabled },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n enabled\n ? \"Horizontal Chat split view enabled\"\n : \"Horizontal Chat split view disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Chat split view setting: \" + errorMsg, 6000);\n }\n }\n\n async onOverridePrerenderSkeletonToggle(enabled: boolean) {\n try {\n setNamespacedItem(\n \"shadow-claw-override-prerender-skeleton\",\n enabled ? \"true\" : \"false\",\n );\n } catch (e) {\n console.warn(\"Unable to save setting to localStorage:\", e);\n }\n\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.OVERRIDE_PRERENDER_SKELETON,\n enabled ? \"true\" : \"false\",\n );\n\n showSuccess(\n enabled\n ? \"Pre-rendered content override enabled\"\n : \"Pre-rendered content override disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\n \"Error saving pre-rendered content override setting: \" + errorMsg,\n 6000,\n );\n }\n }\n\n async onPagesAutoRefreshInputChange(valSec: number) {\n if (!this.db) {\n return;\n }\n\n const sec = Math.max(0, Math.min(valSec, 86400));\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.PAGES_AUTO_REFRESH_INTERVAL,\n String(sec),\n );\n\n window.dispatchEvent(\n new CustomEvent(\"shadow-claw-pages-auto-refresh-change\", {\n detail: { interval: sec },\n }),\n );\n\n showSuccess(\n sec > 0\n ? `Pages auto refresh set to ${sec}s`\n : \"Pages auto refresh disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Pages auto refresh interval: \" + errorMsg, 6000);\n }\n }\n\n async onSidebarHideChatToggle(hidden: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_CHAT_HIDDEN,\n hidden ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"sidebar-chat-visibility-change\", {\n detail: { hidden },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n hidden ? \"Chat hidden in sidebar\" : \"Chat shown in sidebar\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving sidebar Chat visibility: \" + errorMsg, 6000);\n }\n }\n\n async onSidebarHideFilesToggle(hidden: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_FILES_HIDDEN,\n hidden ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"sidebar-files-visibility-change\", {\n detail: { hidden },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n hidden ? \"Files hidden in sidebar\" : \"Files shown in sidebar\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving sidebar Files visibility: \" + errorMsg, 6000);\n }\n }\n\n async onSidebarHidePagesToggle(hidden: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_PAGES_HIDDEN,\n hidden ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"sidebar-pages-visibility-change\", {\n detail: { hidden },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n hidden ? \"Pages hidden in sidebar\" : \"Pages shown in sidebar\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving sidebar Pages visibility: \" + errorMsg, 6000);\n }\n }\n\n async onSidebarHideTasksToggle(hidden: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_TASKS_HIDDEN,\n hidden ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"sidebar-tasks-visibility-change\", {\n detail: { hidden },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n hidden ? \"Tasks hidden in sidebar\" : \"Tasks shown in sidebar\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving sidebar Tasks visibility: \" + errorMsg, 6000);\n }\n }\n\n async populateAssistantSettings() {\n const root = this.shadowRoot;\n if (!root || !this.db) {\n return;\n }\n\n const nameInput = root.querySelector(\n '[data-setting=\"assistant-name-input\"]',\n ) as HTMLInputElement | null;\n if (nameInput) {\n const { getConfig } = await import(\"../../db/getConfig.js\");\n const storedAssistantName = await getConfig(\n this.db,\n CONFIG_KEYS.ASSISTANT_NAME,\n );\n const orchestratorName =\n this.orchestrator?.assistantName ||\n orchestratorStore.orchestrator?.assistantName;\n\n nameInput.value =\n (typeof storedAssistantName === \"string\" && storedAssistantName) ||\n orchestratorName ||\n ASSISTANT_NAME;\n }\n\n const { getConfig } = await import(\"../../db/getConfig.js\");\n const rawActivityLogDiskLoggingEnabled = (await getConfig(\n this.db,\n CONFIG_KEYS.ACTIVITY_LOG_DISK_LOGGING_ENABLED,\n )) as unknown;\n const activityLogDiskLoggingEnabled =\n rawActivityLogDiskLoggingEnabled === true ||\n rawActivityLogDiskLoggingEnabled === \"true\" ||\n rawActivityLogDiskLoggingEnabled === 1 ||\n rawActivityLogDiskLoggingEnabled === \"1\";\n\n const activityLogToggle = root.querySelector(\n '[data-setting=\"activity-log-disk-logging-toggle\"]',\n ) as HTMLInputElement | null;\n if (activityLogToggle) {\n activityLogToggle.checked = activityLogDiskLoggingEnabled;\n }\n\n const rawSidebarPagesHidden = (await getConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_PAGES_HIDDEN,\n )) as unknown;\n const sidebarPagesHidden =\n rawSidebarPagesHidden === true ||\n rawSidebarPagesHidden === \"true\" ||\n rawSidebarPagesHidden === 1 ||\n rawSidebarPagesHidden === \"1\";\n\n const sidebarHidePagesToggle = root.querySelector(\n '[data-setting=\"sidebar-hide-pages-toggle\"]',\n ) as HTMLInputElement | null;\n if (sidebarHidePagesToggle) {\n sidebarHidePagesToggle.checked = sidebarPagesHidden;\n }\n\n const rawSidebarChatHidden = (await getConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_CHAT_HIDDEN,\n )) as unknown;\n const sidebarChatHidden =\n rawSidebarChatHidden === true ||\n rawSidebarChatHidden === \"true\" ||\n rawSidebarChatHidden === 1 ||\n rawSidebarChatHidden === \"1\";\n\n const sidebarHideChatToggle = root.querySelector(\n '[data-setting=\"sidebar-hide-chat-toggle\"]',\n ) as HTMLInputElement | null;\n if (sidebarHideChatToggle) {\n sidebarHideChatToggle.checked = sidebarChatHidden;\n }\n\n const rawSidebarTasksHidden = (await getConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_TASKS_HIDDEN,\n )) as unknown;\n const sidebarTasksHidden =\n rawSidebarTasksHidden === true ||\n rawSidebarTasksHidden === \"true\" ||\n rawSidebarTasksHidden === 1 ||\n rawSidebarTasksHidden === \"1\";\n\n const sidebarHideTasksToggle = root.querySelector(\n '[data-setting=\"sidebar-hide-tasks-toggle\"]',\n ) as HTMLInputElement | null;\n if (sidebarHideTasksToggle) {\n sidebarHideTasksToggle.checked = sidebarTasksHidden;\n }\n\n const rawSidebarFilesHidden = (await getConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_FILES_HIDDEN,\n )) as unknown;\n const sidebarFilesHidden =\n rawSidebarFilesHidden === true ||\n rawSidebarFilesHidden === \"true\" ||\n rawSidebarFilesHidden === 1 ||\n rawSidebarFilesHidden === \"1\";\n\n const sidebarHideFilesToggle = root.querySelector(\n '[data-setting=\"sidebar-hide-files-toggle\"]',\n ) as HTMLInputElement | null;\n if (sidebarHideFilesToggle) {\n sidebarHideFilesToggle.checked = sidebarFilesHidden;\n }\n\n const rawChatSplitViewEnabled = (await getConfig(\n this.db,\n CONFIG_KEYS.CHAT_SPLIT_VIEW_ENABLED,\n )) as unknown;\n const chatSplitViewEnabled = isTruthyConfigValue(\n rawChatSplitViewEnabled,\n false,\n );\n\n const chatSplitViewToggle = root.querySelector(\n '[data-setting=\"chat-split-view-toggle\"]',\n ) as HTMLInputElement | null;\n if (chatSplitViewToggle) {\n chatSplitViewToggle.checked = chatSplitViewEnabled;\n }\n\n const pagesAutoRefreshInput = root.querySelector(\n '[data-setting=\"pages-auto-refresh-input\"]',\n ) as HTMLInputElement | null;\n if (pagesAutoRefreshInput) {\n const storedInterval = await getConfig(\n this.db,\n CONFIG_KEYS.PAGES_AUTO_REFRESH_INTERVAL,\n );\n if (\n typeof storedInterval === \"string\" ||\n typeof storedInterval === \"number\"\n ) {\n const parsed = parseInt(String(storedInterval), 10);\n pagesAutoRefreshInput.value =\n !isNaN(parsed) && parsed >= 0 ? String(parsed) : \"0\";\n } else {\n pagesAutoRefreshInput.value = \"0\";\n }\n }\n\n const rawOverridePrerenderSkeleton = (await getConfig(\n this.db,\n CONFIG_KEYS.OVERRIDE_PRERENDER_SKELETON,\n )) as unknown;\n let storedLocalStorage: string | null = null;\n try {\n storedLocalStorage = getNamespacedItem(\n \"shadow-claw-override-prerender-skeleton\",\n );\n } catch {\n // Ignore\n }\n\n // @ts-ignore\n const defaultOverride =\n typeof __PRERENDER_MAIN_MEMORY__ !== \"undefined\"\n ? __PRERENDER_MAIN_MEMORY__\n : true;\n\n let overridePrerenderSkeleton = defaultOverride;\n if (\n rawOverridePrerenderSkeleton !== null &&\n rawOverridePrerenderSkeleton !== undefined\n ) {\n overridePrerenderSkeleton = isTruthyConfigValue(\n rawOverridePrerenderSkeleton,\n );\n } else if (storedLocalStorage !== null) {\n overridePrerenderSkeleton = storedLocalStorage === \"true\";\n }\n\n if (overridePrerenderSkeleton) {\n try {\n setNamespacedItem(\"shadow-claw-override-prerender-skeleton\", \"true\");\n } catch {\n // Ignore localStorage quota / access errors\n }\n }\n\n const overridePrerenderSkeletonToggle = root.querySelector(\n '[data-setting=\"override-prerender-skeleton-toggle\"]',\n ) as HTMLInputElement | null;\n if (overridePrerenderSkeletonToggle) {\n overridePrerenderSkeletonToggle.checked = overridePrerenderSkeleton;\n }\n\n const domHostsTextarea = root.querySelector(\n '[data-setting=\"dom-allowed-iframe-hosts\"]',\n ) as HTMLTextAreaElement | null;\n if (domHostsTextarea) {\n const storedDomHosts = await getConfig(\n this.db,\n CONFIG_KEYS.ALLOWED_IFRAME_HOST_PATTERNS,\n );\n\n if (\n typeof storedDomHosts === \"string\" &&\n storedDomHosts.trim().length > 0\n ) {\n domHostsTextarea.value = storedDomHosts;\n const { setAllowedIframeHostPatterns } =\n await import(\"../../security/iframe-sanitizer.js\");\n setAllowedIframeHostPatterns(storedDomHosts);\n } else {\n const { DEFAULT_ALLOWED_IFRAME_HOST_PATTERNS } =\n await import(\"../../security/iframe-sanitizer.js\");\n domHostsTextarea.value =\n DEFAULT_ALLOWED_IFRAME_HOST_PATTERNS.join(\"\\n\");\n }\n }\n\n const markdownFrontmatterPagesToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-pages-toggle\"]',\n ) as HTMLInputElement | null;\n if (markdownFrontmatterPagesToggle) {\n markdownFrontmatterPagesToggle.checked = isTruthyConfigValue(\n await getConfig(this.db, CONFIG_KEYS.MARKDOWN_FRONTMATTER_PAGES),\n true,\n );\n }\n\n const markdownFrontmatterFileViewerToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-file-viewer-toggle\"]',\n ) as HTMLInputElement | null;\n if (markdownFrontmatterFileViewerToggle) {\n markdownFrontmatterFileViewerToggle.checked = isTruthyConfigValue(\n await getConfig(this.db, CONFIG_KEYS.MARKDOWN_FRONTMATTER_FILE_VIEWER),\n true,\n );\n }\n\n const markdownFrontmatterChatToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-chat-toggle\"]',\n ) as HTMLInputElement | null;\n if (markdownFrontmatterChatToggle) {\n markdownFrontmatterChatToggle.checked = isTruthyConfigValue(\n await getConfig(this.db, CONFIG_KEYS.MARKDOWN_FRONTMATTER_CHAT),\n true,\n );\n }\n\n const markdownFrontmatterTasksToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-tasks-toggle\"]',\n ) as HTMLInputElement | null;\n if (markdownFrontmatterTasksToggle) {\n markdownFrontmatterTasksToggle.checked = isTruthyConfigValue(\n await getConfig(this.db, CONFIG_KEYS.MARKDOWN_FRONTMATTER_TASKS),\n true,\n );\n }\n }\n\n async promptForPlaintextBackupHandle(): Promise<FileSystemFileHandle | null> {\n const pickerMaybe = Reflect.get(globalThis, \"showSaveFilePicker\");\n const picker =\n typeof pickerMaybe === \"function\" ? pickerMaybe.bind(globalThis) : null;\n\n if (!picker) {\n throw new Error(\n \"Plaintext settings backup requires the File System Access API.\",\n );\n }\n\n try {\n return await picker({\n id: \"shadowclaw-settings-backup\",\n suggestedName: `shadowclaw-settings-backup-${formatDateForFilename()}.json`,\n types: [\n {\n description: \"JSON Files\",\n accept: {\n \"application/json\": [\".json\"],\n },\n },\n ],\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return null;\n }\n\n throw error;\n }\n }\n\n async render() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const showChannelsConfigButton = root.querySelector(\n '[data-action=\"show-channels-config\"]',\n );\n showChannelsConfigButton?.addEventListener(\"click\", () => {\n this.dispatchEvent(\n new CustomEvent(\"navigate\", {\n detail: { page: \"channels\" },\n bubbles: true,\n composed: true,\n }),\n );\n });\n\n const showToolsConfigButton = root.querySelector(\n '[data-action=\"show-tools-config\"]',\n );\n showToolsConfigButton?.addEventListener(\"click\", () => {\n this.dispatchEvent(\n new CustomEvent(\"navigate\", {\n detail: { page: \"tools\" },\n bubbles: true,\n composed: true,\n }),\n );\n });\n\n const tabButtons =\n root.querySelectorAll<HTMLButtonElement>(\"[data-tab-target]\");\n tabButtons.forEach((tabButton) => {\n tabButton.addEventListener(\"click\", () => {\n this.activateTab(tabButton.dataset.tabTarget);\n });\n\n tabButton.addEventListener(\"keydown\", (event) => {\n this.handleTabKeydown(event, tabButton);\n });\n });\n this.applyTabState();\n\n this.bindSettingsActions();\n\n const revisionEl = root.querySelector('[data-info=\"deployed-revision\"]');\n if (revisionEl) {\n const revision =\n document\n .querySelector('meta[name=\"revision\"]')\n ?.getAttribute(\"content\")\n ?.trim() || \"\";\n revisionEl.textContent = `Deployed revision: ${revision || \"unknown\"}`;\n }\n\n await this.populateAssistantSettings();\n }\n\n async replaceConfigEntries(entries: ConfigEntryRecord[]): Promise<void> {\n if (!this.db) {\n throw new Error(\"Database is unavailable\");\n }\n\n if (isSqliteDatabase(this.db)) {\n const raw = this.db.db;\n raw.prepare(\"DELETE FROM config\").run();\n const insertStmt = raw.prepare(\n \"INSERT OR REPLACE INTO config (key, value) VALUES (?, ?)\",\n );\n for (const entry of entries) {\n insertStmt.run(\n entry.key,\n typeof entry.value === \"string\"\n ? entry.value\n : JSON.stringify(entry.value),\n );\n }\n return;\n }\n\n const idb = this.db as IDBDatabase;\n await new Promise<void>((resolve, reject) => {\n try {\n const tx = idb.transaction(\"config\", \"readwrite\");\n if (!tx) {\n reject(new Error(\"Failed to open write transaction\"));\n\n return;\n }\n\n const store = tx.objectStore(\"config\");\n store.clear();\n for (const entry of entries) {\n store.put({ key: entry.key, value: entry.value });\n }\n\n tx.oncomplete = () => resolve();\n tx.onerror = () =>\n reject(tx.error || new Error(\"Failed to update config\"));\n tx.onabort = () =>\n reject(tx.error || new Error(\"Config update aborted\"));\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async saveAssistantName() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const nameInput = root.querySelector(\n '[data-setting=\"assistant-name-input\"]',\n ) as HTMLInputElement | null;\n if (!nameInput) {\n return;\n }\n\n const name = nameInput.value.trim();\n if (!name) {\n const { showWarning } = await import(\"../../ui/toast.js\");\n showWarning(\"Please enter a name\", 3000);\n\n return;\n }\n\n setNamespacedItem(\"assistantName\", name);\n\n try {\n const orchestrator = this.orchestrator || orchestratorStore.orchestrator;\n if (orchestrator) {\n this.orchestrator = orchestrator;\n await setAssistantName(orchestrator, this.db, name);\n } else {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(this.db, CONFIG_KEYS.ASSISTANT_NAME, name);\n }\n } catch (e) {\n console.warn(\"Could not update orchestrator:\", e);\n }\n\n showSuccess(\"Assistant name saved\", 3000);\n }\n\n async saveDomAllowedIframeHosts() {\n const root = this.shadowRoot;\n if (!root || !this.db) {\n return;\n }\n\n const textarea = root.querySelector(\n '[data-setting=\"dom-allowed-iframe-hosts\"]',\n ) as HTMLTextAreaElement | null;\n if (!textarea) {\n return;\n }\n\n const rawText = textarea.value;\n const lines = rawText\n .split(\"\\n\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n const markdownFrontmatterPagesToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-pages-toggle\"]',\n ) as HTMLInputElement | null;\n const markdownFrontmatterFileViewerToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-file-viewer-toggle\"]',\n ) as HTMLInputElement | null;\n const markdownFrontmatterChatToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-chat-toggle\"]',\n ) as HTMLInputElement | null;\n const markdownFrontmatterTasksToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-tasks-toggle\"]',\n ) as HTMLInputElement | null;\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n const valueToSave = lines.join(\"\\n\");\n await setConfig(\n this.db,\n CONFIG_KEYS.ALLOWED_IFRAME_HOST_PATTERNS,\n valueToSave,\n );\n\n await setConfig(\n this.db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_PAGES,\n String(markdownFrontmatterPagesToggle?.checked ?? true),\n );\n\n await setConfig(\n this.db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_FILE_VIEWER,\n String(markdownFrontmatterFileViewerToggle?.checked ?? true),\n );\n\n await setConfig(\n this.db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_CHAT,\n String(markdownFrontmatterChatToggle?.checked ?? true),\n );\n\n await setConfig(\n this.db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_TASKS,\n String(markdownFrontmatterTasksToggle?.checked ?? true),\n );\n\n const { setAllowedIframeHostPatterns } =\n await import(\"../../security/iframe-sanitizer.js\");\n setAllowedIframeHostPatterns(lines);\n\n showSuccess(\"DOM iframe embed settings saved\", 2500);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving DOM iframe embed settings: \" + errorMsg, 6000);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawSettings);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shadow-claw-settings-qro6pO9I.js","names":["shadowClawSettingsStyles","shadowClawSettingsTemplate"],"sources":["../../src/config/settings-backup.ts","../../src/components/shadow-claw-settings/shadow-claw-settings.ts"],"sourcesContent":["import { CONFIG_KEYS } from \"./config.js\";\nimport { decryptValue, encryptValue } from \"../security/crypto.js\";\nimport { writeFileHandle } from \"../storage/writeFileHandle.js\";\n\nexport type ConfigEntryRecord = { key: string; value: unknown };\nexport type PasswordPathSegment = string | number;\n\nexport interface PlaintextPasswordEntry {\n key: string;\n path: PasswordPathSegment[];\n value: string;\n}\n\nexport interface SettingsBackupPayload {\n kind: \"shadowclaw-settings-backup\";\n version: 1;\n exportedAt: number;\n includePlaintextPasswords: boolean;\n configEntries: ConfigEntryRecord[];\n plaintextPasswords?: PlaintextPasswordEntry[];\n}\n\nfunction cloneConfigValue(value: unknown): unknown {\n try {\n return JSON.parse(JSON.stringify(value));\n } catch {\n return null;\n }\n}\n\nasync function collectAndStripPasswordData(\n entries: ConfigEntryRecord[],\n includePlaintextPasswords: boolean,\n): Promise<{\n configEntries: ConfigEntryRecord[];\n plaintextPasswords: PlaintextPasswordEntry[];\n}> {\n const nextEntries: ConfigEntryRecord[] = [];\n const plaintextPasswords: PlaintextPasswordEntry[] = [];\n\n for (const entry of entries) {\n const key = entry.key;\n\n if (key === CONFIG_KEYS.STORAGE_HANDLE) {\n continue;\n }\n\n if (\n key === CONFIG_KEYS.GIT_PASSWORD ||\n key === CONFIG_KEYS.API_KEY ||\n key.startsWith(\"api_key:\") ||\n key === CONFIG_KEYS.IMESSAGE_API_KEY ||\n key === CONFIG_KEYS.TELEGRAM_BOT_TOKEN\n ) {\n if (includePlaintextPasswords && typeof entry.value === \"string\") {\n const decrypted = await decryptValue(entry.value);\n if (decrypted) {\n plaintextPasswords.push({ key, path: [], value: decrypted });\n }\n }\n\n continue;\n }\n\n const value = cloneConfigValue(entry.value);\n\n if (key === CONFIG_KEYS.GIT_ACCOUNTS && Array.isArray(value)) {\n for (let i = 0; i < value.length; i += 1) {\n const account = value[i] as Record<string, unknown>;\n if (!account || typeof account !== \"object\") {\n continue;\n }\n\n const encryptedPassword = account.password;\n if (typeof encryptedPassword === \"string\" && encryptedPassword) {\n if (includePlaintextPasswords) {\n const decrypted = await decryptValue(encryptedPassword);\n if (decrypted) {\n plaintextPasswords.push({\n key,\n path: [i, \"password\"],\n value: decrypted,\n });\n }\n }\n\n delete account.password;\n }\n }\n }\n\n if (key === CONFIG_KEYS.INTEGRATION_CONNECTIONS && Array.isArray(value)) {\n for (let i = 0; i < value.length; i += 1) {\n const record = value[i] as Record<string, unknown>;\n const credentialRef = record?.credentialRef as\n | Record<string, unknown>\n | undefined;\n\n const encryptedSecret = credentialRef?.encryptedSecret;\n if (typeof encryptedSecret === \"string\" && encryptedSecret) {\n if (includePlaintextPasswords) {\n const decrypted = await decryptValue(encryptedSecret);\n if (decrypted) {\n plaintextPasswords.push({\n key,\n path: [i, \"credentialRef\", \"encryptedSecret\"],\n value: decrypted,\n });\n }\n }\n\n delete credentialRef.encryptedSecret;\n }\n }\n }\n\n if (key === CONFIG_KEYS.REMOTE_MCP_CONNECTIONS && Array.isArray(value)) {\n for (let i = 0; i < value.length; i += 1) {\n const record = value[i] as Record<string, unknown>;\n const credentialRef = record?.credentialRef as\n | Record<string, unknown>\n | undefined;\n\n const encryptedValue = credentialRef?.encryptedValue;\n if (typeof encryptedValue === \"string\" && encryptedValue) {\n if (includePlaintextPasswords) {\n const decrypted = await decryptValue(encryptedValue);\n if (decrypted) {\n plaintextPasswords.push({\n key,\n path: [i, \"credentialRef\", \"encryptedValue\"],\n value: decrypted,\n });\n }\n }\n\n delete credentialRef.encryptedValue;\n }\n }\n }\n\n nextEntries.push({ key, value });\n }\n\n return { configEntries: nextEntries, plaintextPasswords };\n}\n\nfunction applyPathValue(\n rootValue: unknown,\n path: PasswordPathSegment[],\n nextValue: string,\n): unknown {\n if (path.length === 0) {\n return nextValue;\n }\n\n let current = rootValue as Record<string, unknown> | unknown[] | null;\n\n for (let i = 0; i < path.length - 1; i += 1) {\n const segment = path[i];\n if (typeof segment === \"number\") {\n if (!Array.isArray(current) || !current[segment]) {\n return rootValue;\n }\n\n current = current[segment] as Record<string, unknown>;\n } else {\n if (!current || typeof current !== \"object\") {\n return rootValue;\n }\n\n const next = (current as Record<string, unknown>)[segment];\n if (!next || typeof next !== \"object\") {\n return rootValue;\n }\n\n current = next as Record<string, unknown>;\n }\n }\n\n const leaf = path[path.length - 1];\n if (typeof leaf === \"number\") {\n if (!Array.isArray(current)) {\n return rootValue;\n }\n\n current[leaf] = nextValue;\n } else {\n if (!current || typeof current !== \"object\") {\n return rootValue;\n }\n\n (current as Record<string, unknown>)[leaf] = nextValue;\n }\n\n return rootValue;\n}\n\nasync function buildSettingsBackupPayload(\n entries: ConfigEntryRecord[],\n includePlaintextPasswords: boolean,\n): Promise<SettingsBackupPayload> {\n const transformed = await collectAndStripPasswordData(\n entries,\n includePlaintextPasswords,\n );\n\n return {\n kind: \"shadowclaw-settings-backup\",\n version: 1,\n exportedAt: Date.now(),\n includePlaintextPasswords,\n configEntries: transformed.configEntries,\n plaintextPasswords: includePlaintextPasswords\n ? transformed.plaintextPasswords\n : undefined,\n };\n}\n\nexport async function createSettingsBackupBlob(\n entries: ConfigEntryRecord[],\n includePlaintextPasswords: boolean,\n): Promise<Blob> {\n const payload = await buildSettingsBackupPayload(\n entries,\n includePlaintextPasswords,\n );\n\n return new Blob([JSON.stringify(payload, null, 2)], {\n type: \"application/json\",\n });\n}\n\nexport async function writeSettingsBackupToFileHandle(\n fileHandle: FileSystemFileHandle,\n entries: ConfigEntryRecord[],\n includePlaintextPasswords: boolean,\n): Promise<void> {\n const payload = await buildSettingsBackupPayload(\n entries,\n includePlaintextPasswords,\n );\n\n await writeFileHandle(fileHandle, JSON.stringify(payload, null, 2));\n}\n\nexport async function reapplyPlaintextPasswords(\n configEntries: ConfigEntryRecord[],\n plaintextPasswords: PlaintextPasswordEntry[],\n): Promise<ConfigEntryRecord[]> {\n if (!plaintextPasswords.length) {\n return configEntries;\n }\n\n const nextEntries = configEntries.map((entry) => ({\n key: entry.key,\n value: cloneConfigValue(entry.value),\n }));\n\n for (const secret of plaintextPasswords) {\n const encrypted = await encryptValue(secret.value);\n if (!encrypted) {\n continue;\n }\n\n const existingEntry = nextEntries.find((entry) => entry.key === secret.key);\n if (existingEntry) {\n existingEntry.value = applyPathValue(\n existingEntry.value,\n secret.path,\n encrypted,\n );\n } else if (secret.path.length === 0) {\n nextEntries.push({ key: secret.key, value: encrypted });\n }\n }\n\n return nextEntries;\n}\n\nexport function parseSettingsBackupPayload(raw: string): SettingsBackupPayload {\n const parsed = JSON.parse(raw) as Partial<SettingsBackupPayload>;\n\n if (\n parsed?.kind !== \"shadowclaw-settings-backup\" ||\n parsed.version !== 1 ||\n !Array.isArray(parsed.configEntries)\n ) {\n throw new Error(\"Invalid settings backup file\");\n }\n\n const plaintextPasswords = Array.isArray(parsed.plaintextPasswords)\n ? parsed.plaintextPasswords.filter((entry) => {\n return (\n entry &&\n typeof entry.key === \"string\" &&\n Array.isArray(entry.path) &&\n typeof entry.value === \"string\"\n );\n })\n : [];\n\n return {\n kind: \"shadowclaw-settings-backup\",\n version: 1,\n exportedAt:\n typeof parsed.exportedAt === \"number\" ? parsed.exportedAt : Date.now(),\n includePlaintextPasswords: !!parsed.includePlaintextPasswords,\n configEntries: parsed.configEntries\n .filter((entry) => entry && typeof entry.key === \"string\")\n .map((entry) => ({ key: entry.key, value: entry.value })),\n plaintextPasswords,\n };\n}\n","import { ASSISTANT_NAME, CONFIG_KEYS } from \"../../config/config.js\";\nimport {\n getNamespacedItem,\n setNamespacedItem,\n} from \"../../utils/namespacedStorage.js\";\n\nimport {\n createSettingsBackupBlob,\n parseSettingsBackupPayload,\n reapplyPlaintextPasswords,\n writeSettingsBackupToFileHandle,\n} from \"../../config/settings-backup.js\";\n\nimport { setAssistantName } from \"../../core/orchestrator/utils/operations/provider.js\";\nimport { getDb } from \"../../db/db.js\";\nimport { orchestratorStore } from \"../../stores/orchestrator.js\";\nimport { showError, showInfo, showSuccess } from \"../../ui/toast.js\";\nimport { formatDateForFilename } from \"../../utils/utils.js\";\nimport { isTruthyConfigValue } from \"../../common/utils/config-value.mjs\";\n\nimport type { ConfigEntryRecord } from \"../../config/settings-backup.js\";\nimport type { Orchestrator } from \"../../core/orchestrator/orchestrator.js\";\nimport { isSqliteDatabase } from \"../../db/sqlite/types.js\";\nimport type { ShadowClawDatabase } from \"../../db/types.js\";\n\nimport \"../shadow-claw-dialog/shadow-claw-dialog.js\";\nimport \"../shadow-claw-page-header/shadow-claw-page-header.js\";\n\nconst settingsTabLoaders: Record<string, (() => Promise<unknown>)[]> = {\n ai: [() => import(\"../settings/shadow-claw-llm/shadow-claw-llm.js\")],\n environment: [\n () =>\n import(\"../settings/shadow-claw-networking/shadow-claw-networking.js\"),\n () => import(\"../settings/shadow-claw-webvm/shadow-claw-webvm.js\"),\n () => import(\"../settings/shadow-claw-storage/shadow-claw-storage.js\"),\n ],\n integrations: [\n () => import(\"../settings/shadow-claw-git/shadow-claw-git.js\"),\n () => import(\"../settings/shadow-claw-accounts/shadow-claw-accounts.js\"),\n () =>\n import(\"../settings/shadow-claw-mcp-remote/shadow-claw-mcp-remote.js\"),\n () =>\n import(\"../settings/shadow-claw-control-plane/shadow-claw-control-plane.js\"),\n () =>\n import(\"../settings/shadow-claw-integrations/shadow-claw-integrations.js\"),\n () =>\n import(\"../settings/shadow-claw-task-server/shadow-claw-task-server.js\"),\n () =>\n import(\"../settings/shadow-claw-notifications/shadow-claw-notifications.js\"),\n ],\n};\n\nconst loadedSettingsTabs = new Set<string>();\n\nasync function ensureSettingsTabLoaded(tabId: string): Promise<void> {\n if (loadedSettingsTabs.has(tabId)) {\n return;\n }\n const loaders = settingsTabLoaders[tabId];\n if (loaders) {\n loadedSettingsTabs.add(tabId);\n await Promise.all(loaders.map((loader) => loader()));\n }\n}\n\nimport ShadowClawElement from \"../shadow-claw-element.js\";\nimport shadowClawSettingsStyles from \"./shadow-claw-settings.css\" with { type: \"css\" };\nimport shadowClawSettingsTemplate from \"./shadow-claw-settings.html\" with { type: \"html\" };\n\ndeclare const __PRERENDER_MAIN_MEMORY__: boolean | undefined;\n\nconst elementName = \"shadow-claw-settings\";\n\n/**\n * Parent settings component that composes the dedicated sub-components:\n *\n * - <shadow-claw-llm> — Provider, model, API key, and runtime controls\n * - <shadow-claw-networking> — CORS proxy toggle and proxy URL\n * - <shadow-claw-webvm> — VM boot mode, timeout, host, relay\n * - <shadow-claw-git> — PAT, author config\n * - <shadow-claw-storage>— OPFS, persistent, directory\n *\n * - Channels button — navigates to the channels config page\n * - Tools button — navigates to the tools config page\n * - Deployed revision footer\n */\nexport class ShadowClawSettings extends ShadowClawElement {\n static styles = shadowClawSettingsStyles;\n static template = shadowClawSettingsTemplate;\n\n activeTab = \"ai\";\n db: ShadowClawDatabase | null = null;\n orchestrator: Orchestrator | null = null;\n pendingRestoreFile: File | 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 await this.render();\n }\n\n activateTab(tabId: string | undefined) {\n if (!tabId || this.activeTab === tabId) {\n return;\n }\n\n this.activeTab = tabId;\n this.applyTabState();\n }\n\n applyTabState() {\n ensureSettingsTabLoaded(this.activeTab).catch(console.error);\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const tabButtons =\n root.querySelectorAll<HTMLButtonElement>(\"[data-tab-target]\");\n tabButtons.forEach((tabButton) => {\n const isActive = tabButton.dataset.tabTarget === this.activeTab;\n tabButton.classList.toggle(\"active\", isActive);\n tabButton.setAttribute(\"aria-selected\", String(isActive));\n tabButton.tabIndex = isActive ? 0 : -1;\n });\n\n const tabPanels = root.querySelectorAll<HTMLElement>(\"[data-tab-panel]\");\n tabPanels.forEach((tabPanel) => {\n const isActive = tabPanel.dataset.tabPanel === this.activeTab;\n tabPanel.hidden = !isActive;\n });\n }\n\n bindSettingsActions() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"backup-settings\"]')\n ?.addEventListener(\"click\", () => this.openBackupDialog());\n\n const restoreInput = root.querySelector(\n \".settings__restore-input\",\n ) as HTMLInputElement | null;\n\n root\n .querySelector('[data-action=\"restore-settings\"]')\n ?.addEventListener(\"click\", () => {\n if (restoreInput instanceof HTMLInputElement) {\n restoreInput.value = \"\";\n restoreInput.click();\n }\n });\n\n restoreInput?.addEventListener(\"change\", (event) => {\n const target = event.target;\n if (!(target instanceof HTMLInputElement)) {\n return;\n }\n\n const file = target.files?.[0] || null;\n if (!file) {\n return;\n }\n\n this.pendingRestoreFile = file;\n this.openRestoreDialog(file.name);\n });\n\n root\n .querySelector('[data-action=\"clear-settings\"]')\n ?.addEventListener(\"click\", () => this.openClearDialog());\n\n root\n .querySelector('[data-action=\"cancel-backup-settings\"]')\n ?.addEventListener(\"click\", () =>\n this.closeDialog(\".settings__backup-dialog\"),\n );\n\n root\n .querySelector('[data-action=\"confirm-backup-settings\"]')\n ?.addEventListener(\"click\", () => {\n void this.confirmBackup();\n });\n\n root\n .querySelector('[data-action=\"cancel-restore-settings\"]')\n ?.addEventListener(\"click\", () => {\n this.pendingRestoreFile = null;\n this.closeDialog(\".settings__restore-dialog\");\n });\n\n root\n .querySelector('[data-action=\"confirm-restore-settings\"]')\n ?.addEventListener(\"click\", () => {\n void this.confirmRestore();\n });\n\n root\n .querySelector('[data-action=\"cancel-clear-settings\"]')\n ?.addEventListener(\"click\", () =>\n this.closeDialog(\".settings__clear-dialog\"),\n );\n\n root\n .querySelector('[data-action=\"confirm-clear-settings\"]')\n ?.addEventListener(\"click\", () => {\n void this.confirmClear();\n });\n\n root\n .querySelector('[data-action=\"save-assistant-name\"]')\n ?.addEventListener(\"click\", () => this.saveAssistantName());\n\n root\n .querySelector('[data-setting=\"activity-log-disk-logging-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onActivityLogDiskLoggingToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"sidebar-hide-pages-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onSidebarHidePagesToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"sidebar-hide-chat-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onSidebarHideChatToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"sidebar-hide-tasks-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onSidebarHideTasksToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"sidebar-hide-files-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onSidebarHideFilesToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"chat-split-view-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onChatSplitViewToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-setting=\"pages-auto-refresh-input\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n const val = parseInt(target.value, 10);\n void this.onPagesAutoRefreshInputChange(isNaN(val) ? 0 : val);\n }\n });\n\n root\n .querySelector('[data-setting=\"override-prerender-skeleton-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onOverridePrerenderSkeletonToggle(target.checked);\n }\n });\n\n root\n .querySelector('[data-action=\"save-dom-allowed-iframe-hosts\"]')\n ?.addEventListener(\"click\", () => {\n void this.saveDomAllowedIframeHosts();\n });\n }\n\n closeDialog(selector: string) {\n this.getDialog(selector)?.close();\n }\n\n getDialog(selector: string): HTMLDialogElement | null {\n const root = this.shadowRoot;\n if (!root) {\n return null;\n }\n\n const dialog = root.querySelector(selector);\n if (!(dialog instanceof HTMLDialogElement)) {\n return null;\n }\n\n return dialog;\n }\n\n handleTabKeydown(event: KeyboardEvent, currentButton: HTMLButtonElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const tabButtons = Array.from(\n root.querySelectorAll<HTMLButtonElement>(\"[data-tab-target]\"),\n );\n\n const currentIndex = tabButtons.indexOf(currentButton);\n if (currentIndex < 0) {\n return;\n }\n\n let nextIndex = -1;\n\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n nextIndex = (currentIndex + 1) % tabButtons.length;\n\n break;\n case \"ArrowLeft\":\n case \"ArrowUp\":\n nextIndex = (currentIndex - 1 + tabButtons.length) % tabButtons.length;\n\n break;\n case \"Home\":\n nextIndex = 0;\n\n break;\n case \"End\":\n nextIndex = tabButtons.length - 1;\n\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextButton = tabButtons[nextIndex];\n nextButton.focus();\n this.activateTab(nextButton.dataset.tabTarget);\n }\n\n openBackupDialog() {\n const root = this.shadowRoot;\n const includePlaintextToggle = root?.querySelector(\n '[data-setting=\"include-plaintext-passwords\"]',\n );\n\n if (includePlaintextToggle instanceof HTMLInputElement) {\n includePlaintextToggle.checked = false;\n }\n\n this.showDialog(\".settings__backup-dialog\");\n }\n\n openClearDialog() {\n this.showDialog(\".settings__clear-dialog\");\n }\n\n openRestoreDialog(fileName: string) {\n const root = this.shadowRoot;\n const info = root?.querySelector('[data-info=\"restore-filename\"]');\n if (info instanceof HTMLElement) {\n info.textContent = `Selected file: ${fileName}`;\n }\n\n this.showDialog(\".settings__restore-dialog\");\n }\n\n showDialog(selector: string) {\n const dialog = this.getDialog(selector);\n if (!dialog) {\n return;\n }\n\n if (typeof dialog.showModal === \"function\") {\n dialog.showModal();\n\n return;\n }\n\n dialog.setAttribute(\"open\", \"\");\n }\n\n async confirmBackup() {\n if (!this.db) {\n showError(\"Settings database is unavailable\", 5000);\n\n return;\n }\n\n const root = this.shadowRoot;\n const includePlaintextToggle = root?.querySelector(\n '[data-setting=\"include-plaintext-passwords\"]',\n );\n\n const includePlaintextPasswords =\n includePlaintextToggle instanceof HTMLInputElement\n ? includePlaintextToggle.checked\n : false;\n\n try {\n if (includePlaintextPasswords) {\n const fileHandle = await this.promptForPlaintextBackupHandle();\n if (!fileHandle) {\n return;\n }\n\n const entries = await this.getAllConfigEntries();\n\n await writeSettingsBackupToFileHandle(\n fileHandle,\n entries,\n includePlaintextPasswords,\n );\n\n this.closeDialog(\".settings__backup-dialog\");\n showSuccess(\"Settings backup saved\", 3000);\n\n return;\n }\n\n const entries = await this.getAllConfigEntries();\n const blob = await createSettingsBackupBlob(\n entries,\n includePlaintextPasswords,\n );\n\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `shadowclaw-settings-backup-${Date.now()}.json`;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n\n this.closeDialog(\".settings__backup-dialog\");\n showSuccess(\"Settings backup downloaded\", 3000);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n showError(`Failed to backup settings: ${message}`, 6000);\n }\n }\n\n async confirmClear() {\n if (!this.db) {\n showError(\"Settings database is unavailable\", 5000);\n\n return;\n }\n\n try {\n await this.replaceConfigEntries([]);\n this.closeDialog(\".settings__clear-dialog\");\n showInfo(\"Settings cleared. Reloading app...\", 3200);\n\n setTimeout(() => {\n window.location.reload();\n }, 250);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n showError(`Failed to clear settings: ${message}`, 6000);\n }\n }\n\n async confirmRestore() {\n if (!this.db) {\n showError(\"Settings database is unavailable\", 5000);\n\n return;\n }\n\n const file = this.pendingRestoreFile;\n if (!file) {\n showError(\"No backup file selected\", 4000);\n\n return;\n }\n\n try {\n const text = await file.text();\n const backup = parseSettingsBackupPayload(text);\n const mergedEntries = await reapplyPlaintextPasswords(\n backup.configEntries,\n backup.plaintextPasswords || [],\n );\n\n await this.replaceConfigEntries(mergedEntries);\n this.pendingRestoreFile = null;\n this.closeDialog(\".settings__restore-dialog\");\n\n showSuccess(\"Settings restored. Reloading app...\", 3200);\n setTimeout(() => {\n window.location.reload();\n }, 250);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n showError(`Failed to restore settings: ${message}`, 6000);\n }\n }\n\n async getAllConfigEntries(): Promise<ConfigEntryRecord[]> {\n if (!this.db) {\n throw new Error(\"Database is unavailable\");\n }\n\n if (isSqliteDatabase(this.db)) {\n const raw = this.db.db;\n const rows = (raw\n .prepare(\"SELECT key, value FROM config ORDER BY key\")\n .all() ?? []) as any[];\n return rows\n .filter((row) => row && typeof row.key === \"string\")\n .map((row) => ({ key: row.key, value: row.value }));\n }\n\n const idb = this.db as IDBDatabase;\n return await new Promise((resolve, reject) => {\n try {\n const tx = idb.transaction(\"config\", \"readonly\");\n if (!tx) {\n reject(new Error(\"Failed to open read transaction\"));\n\n return;\n }\n\n const store = tx.objectStore(\"config\");\n const request = store.getAll();\n\n request.onsuccess = () => {\n const rows = Array.isArray(request.result) ? request.result : [];\n resolve(\n rows\n .filter((row) => row && typeof row.key === \"string\")\n .map((row) => ({ key: row.key, value: row.value })),\n );\n };\n\n request.onerror = () => {\n reject(request.error || new Error(\"Failed to read settings config\"));\n };\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async onActivityLogDiskLoggingToggle(enabled: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.ACTIVITY_LOG_DISK_LOGGING_ENABLED,\n enabled ? \"true\" : \"false\",\n );\n\n showSuccess(\n enabled\n ? \"Activity log disk logging enabled\"\n : \"Activity log disk logging disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\n \"Error saving activity log disk logging setting: \" + errorMsg,\n 6000,\n );\n }\n }\n\n async onChatSplitViewToggle(enabled: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.CHAT_SPLIT_VIEW_ENABLED,\n enabled ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"chat-split-view-change\", {\n detail: { enabled },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n enabled\n ? \"Horizontal Chat split view enabled\"\n : \"Horizontal Chat split view disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Chat split view setting: \" + errorMsg, 6000);\n }\n }\n\n async onOverridePrerenderSkeletonToggle(enabled: boolean) {\n try {\n setNamespacedItem(\n \"shadow-claw-override-prerender-skeleton\",\n enabled ? \"true\" : \"false\",\n );\n } catch (e) {\n console.warn(\"Unable to save setting to localStorage:\", e);\n }\n\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.OVERRIDE_PRERENDER_SKELETON,\n enabled ? \"true\" : \"false\",\n );\n\n showSuccess(\n enabled\n ? \"Pre-rendered content override enabled\"\n : \"Pre-rendered content override disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\n \"Error saving pre-rendered content override setting: \" + errorMsg,\n 6000,\n );\n }\n }\n\n async onPagesAutoRefreshInputChange(valSec: number) {\n if (!this.db) {\n return;\n }\n\n const sec = Math.max(0, Math.min(valSec, 86400));\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.PAGES_AUTO_REFRESH_INTERVAL,\n String(sec),\n );\n\n window.dispatchEvent(\n new CustomEvent(\"shadow-claw-pages-auto-refresh-change\", {\n detail: { interval: sec },\n }),\n );\n\n showSuccess(\n sec > 0\n ? `Pages auto refresh set to ${sec}s`\n : \"Pages auto refresh disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Pages auto refresh interval: \" + errorMsg, 6000);\n }\n }\n\n async onSidebarHideChatToggle(hidden: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_CHAT_HIDDEN,\n hidden ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"sidebar-chat-visibility-change\", {\n detail: { hidden },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n hidden ? \"Chat hidden in sidebar\" : \"Chat shown in sidebar\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving sidebar Chat visibility: \" + errorMsg, 6000);\n }\n }\n\n async onSidebarHideFilesToggle(hidden: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_FILES_HIDDEN,\n hidden ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"sidebar-files-visibility-change\", {\n detail: { hidden },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n hidden ? \"Files hidden in sidebar\" : \"Files shown in sidebar\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving sidebar Files visibility: \" + errorMsg, 6000);\n }\n }\n\n async onSidebarHidePagesToggle(hidden: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_PAGES_HIDDEN,\n hidden ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"sidebar-pages-visibility-change\", {\n detail: { hidden },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n hidden ? \"Pages hidden in sidebar\" : \"Pages shown in sidebar\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving sidebar Pages visibility: \" + errorMsg, 6000);\n }\n }\n\n async onSidebarHideTasksToggle(hidden: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_TASKS_HIDDEN,\n hidden ? \"true\" : \"false\",\n );\n\n this.dispatchEvent(\n new CustomEvent(\"sidebar-tasks-visibility-change\", {\n detail: { hidden },\n bubbles: true,\n composed: true,\n }),\n );\n\n showSuccess(\n hidden ? \"Tasks hidden in sidebar\" : \"Tasks shown in sidebar\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving sidebar Tasks visibility: \" + errorMsg, 6000);\n }\n }\n\n async populateAssistantSettings() {\n const root = this.shadowRoot;\n if (!root || !this.db) {\n return;\n }\n\n const nameInput = root.querySelector(\n '[data-setting=\"assistant-name-input\"]',\n ) as HTMLInputElement | null;\n if (nameInput) {\n const { getConfig } = await import(\"../../db/getConfig.js\");\n const storedAssistantName = await getConfig(\n this.db,\n CONFIG_KEYS.ASSISTANT_NAME,\n );\n const orchestratorName =\n this.orchestrator?.assistantName ||\n orchestratorStore.orchestrator?.assistantName;\n\n nameInput.value =\n (typeof storedAssistantName === \"string\" && storedAssistantName) ||\n orchestratorName ||\n ASSISTANT_NAME;\n }\n\n const { getConfig } = await import(\"../../db/getConfig.js\");\n const rawActivityLogDiskLoggingEnabled = (await getConfig(\n this.db,\n CONFIG_KEYS.ACTIVITY_LOG_DISK_LOGGING_ENABLED,\n )) as unknown;\n const activityLogDiskLoggingEnabled =\n rawActivityLogDiskLoggingEnabled === true ||\n rawActivityLogDiskLoggingEnabled === \"true\" ||\n rawActivityLogDiskLoggingEnabled === 1 ||\n rawActivityLogDiskLoggingEnabled === \"1\";\n\n const activityLogToggle = root.querySelector(\n '[data-setting=\"activity-log-disk-logging-toggle\"]',\n ) as HTMLInputElement | null;\n if (activityLogToggle) {\n activityLogToggle.checked = activityLogDiskLoggingEnabled;\n }\n\n const rawSidebarPagesHidden = (await getConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_PAGES_HIDDEN,\n )) as unknown;\n const sidebarPagesHidden =\n rawSidebarPagesHidden === true ||\n rawSidebarPagesHidden === \"true\" ||\n rawSidebarPagesHidden === 1 ||\n rawSidebarPagesHidden === \"1\";\n\n const sidebarHidePagesToggle = root.querySelector(\n '[data-setting=\"sidebar-hide-pages-toggle\"]',\n ) as HTMLInputElement | null;\n if (sidebarHidePagesToggle) {\n sidebarHidePagesToggle.checked = sidebarPagesHidden;\n }\n\n const rawSidebarChatHidden = (await getConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_CHAT_HIDDEN,\n )) as unknown;\n const sidebarChatHidden =\n rawSidebarChatHidden === true ||\n rawSidebarChatHidden === \"true\" ||\n rawSidebarChatHidden === 1 ||\n rawSidebarChatHidden === \"1\";\n\n const sidebarHideChatToggle = root.querySelector(\n '[data-setting=\"sidebar-hide-chat-toggle\"]',\n ) as HTMLInputElement | null;\n if (sidebarHideChatToggle) {\n sidebarHideChatToggle.checked = sidebarChatHidden;\n }\n\n const rawSidebarTasksHidden = (await getConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_TASKS_HIDDEN,\n )) as unknown;\n const sidebarTasksHidden =\n rawSidebarTasksHidden === true ||\n rawSidebarTasksHidden === \"true\" ||\n rawSidebarTasksHidden === 1 ||\n rawSidebarTasksHidden === \"1\";\n\n const sidebarHideTasksToggle = root.querySelector(\n '[data-setting=\"sidebar-hide-tasks-toggle\"]',\n ) as HTMLInputElement | null;\n if (sidebarHideTasksToggle) {\n sidebarHideTasksToggle.checked = sidebarTasksHidden;\n }\n\n const rawSidebarFilesHidden = (await getConfig(\n this.db,\n CONFIG_KEYS.SIDEBAR_FILES_HIDDEN,\n )) as unknown;\n const sidebarFilesHidden =\n rawSidebarFilesHidden === true ||\n rawSidebarFilesHidden === \"true\" ||\n rawSidebarFilesHidden === 1 ||\n rawSidebarFilesHidden === \"1\";\n\n const sidebarHideFilesToggle = root.querySelector(\n '[data-setting=\"sidebar-hide-files-toggle\"]',\n ) as HTMLInputElement | null;\n if (sidebarHideFilesToggle) {\n sidebarHideFilesToggle.checked = sidebarFilesHidden;\n }\n\n const rawChatSplitViewEnabled = (await getConfig(\n this.db,\n CONFIG_KEYS.CHAT_SPLIT_VIEW_ENABLED,\n )) as unknown;\n const chatSplitViewEnabled = isTruthyConfigValue(\n rawChatSplitViewEnabled,\n false,\n );\n\n const chatSplitViewToggle = root.querySelector(\n '[data-setting=\"chat-split-view-toggle\"]',\n ) as HTMLInputElement | null;\n if (chatSplitViewToggle) {\n chatSplitViewToggle.checked = chatSplitViewEnabled;\n }\n\n const pagesAutoRefreshInput = root.querySelector(\n '[data-setting=\"pages-auto-refresh-input\"]',\n ) as HTMLInputElement | null;\n if (pagesAutoRefreshInput) {\n const storedInterval = await getConfig(\n this.db,\n CONFIG_KEYS.PAGES_AUTO_REFRESH_INTERVAL,\n );\n if (\n typeof storedInterval === \"string\" ||\n typeof storedInterval === \"number\"\n ) {\n const parsed = parseInt(String(storedInterval), 10);\n pagesAutoRefreshInput.value =\n !isNaN(parsed) && parsed >= 0 ? String(parsed) : \"0\";\n } else {\n pagesAutoRefreshInput.value = \"0\";\n }\n }\n\n const rawOverridePrerenderSkeleton = (await getConfig(\n this.db,\n CONFIG_KEYS.OVERRIDE_PRERENDER_SKELETON,\n )) as unknown;\n let storedLocalStorage: string | null = null;\n try {\n storedLocalStorage = getNamespacedItem(\n \"shadow-claw-override-prerender-skeleton\",\n );\n } catch {\n // Ignore\n }\n\n // @ts-ignore\n const defaultOverride =\n typeof __PRERENDER_MAIN_MEMORY__ !== \"undefined\"\n ? __PRERENDER_MAIN_MEMORY__\n : true;\n\n let overridePrerenderSkeleton = defaultOverride;\n if (\n rawOverridePrerenderSkeleton !== null &&\n rawOverridePrerenderSkeleton !== undefined\n ) {\n overridePrerenderSkeleton = isTruthyConfigValue(\n rawOverridePrerenderSkeleton,\n );\n } else if (storedLocalStorage !== null) {\n overridePrerenderSkeleton = storedLocalStorage === \"true\";\n }\n\n if (overridePrerenderSkeleton) {\n try {\n setNamespacedItem(\"shadow-claw-override-prerender-skeleton\", \"true\");\n } catch {\n // Ignore localStorage quota / access errors\n }\n }\n\n const overridePrerenderSkeletonToggle = root.querySelector(\n '[data-setting=\"override-prerender-skeleton-toggle\"]',\n ) as HTMLInputElement | null;\n if (overridePrerenderSkeletonToggle) {\n overridePrerenderSkeletonToggle.checked = overridePrerenderSkeleton;\n }\n\n const domHostsTextarea = root.querySelector(\n '[data-setting=\"dom-allowed-iframe-hosts\"]',\n ) as HTMLTextAreaElement | null;\n if (domHostsTextarea) {\n const storedDomHosts = await getConfig(\n this.db,\n CONFIG_KEYS.ALLOWED_IFRAME_HOST_PATTERNS,\n );\n\n if (\n typeof storedDomHosts === \"string\" &&\n storedDomHosts.trim().length > 0\n ) {\n domHostsTextarea.value = storedDomHosts;\n const { setAllowedIframeHostPatterns } =\n await import(\"../../security/iframe-sanitizer.js\");\n setAllowedIframeHostPatterns(storedDomHosts);\n } else {\n const { DEFAULT_ALLOWED_IFRAME_HOST_PATTERNS } =\n await import(\"../../security/iframe-sanitizer.js\");\n domHostsTextarea.value =\n DEFAULT_ALLOWED_IFRAME_HOST_PATTERNS.join(\"\\n\");\n }\n }\n\n const markdownFrontmatterPagesToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-pages-toggle\"]',\n ) as HTMLInputElement | null;\n if (markdownFrontmatterPagesToggle) {\n markdownFrontmatterPagesToggle.checked = isTruthyConfigValue(\n await getConfig(this.db, CONFIG_KEYS.MARKDOWN_FRONTMATTER_PAGES),\n true,\n );\n }\n\n const markdownFrontmatterFileViewerToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-file-viewer-toggle\"]',\n ) as HTMLInputElement | null;\n if (markdownFrontmatterFileViewerToggle) {\n markdownFrontmatterFileViewerToggle.checked = isTruthyConfigValue(\n await getConfig(this.db, CONFIG_KEYS.MARKDOWN_FRONTMATTER_FILE_VIEWER),\n true,\n );\n }\n\n const markdownFrontmatterChatToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-chat-toggle\"]',\n ) as HTMLInputElement | null;\n if (markdownFrontmatterChatToggle) {\n markdownFrontmatterChatToggle.checked = isTruthyConfigValue(\n await getConfig(this.db, CONFIG_KEYS.MARKDOWN_FRONTMATTER_CHAT),\n true,\n );\n }\n\n const markdownFrontmatterTasksToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-tasks-toggle\"]',\n ) as HTMLInputElement | null;\n if (markdownFrontmatterTasksToggle) {\n markdownFrontmatterTasksToggle.checked = isTruthyConfigValue(\n await getConfig(this.db, CONFIG_KEYS.MARKDOWN_FRONTMATTER_TASKS),\n true,\n );\n }\n }\n\n async promptForPlaintextBackupHandle(): Promise<FileSystemFileHandle | null> {\n const pickerMaybe = Reflect.get(globalThis, \"showSaveFilePicker\");\n const picker =\n typeof pickerMaybe === \"function\" ? pickerMaybe.bind(globalThis) : null;\n\n if (!picker) {\n throw new Error(\n \"Plaintext settings backup requires the File System Access API.\",\n );\n }\n\n try {\n return await picker({\n id: \"shadowclaw-settings-backup\",\n suggestedName: `shadowclaw-settings-backup-${formatDateForFilename()}.json`,\n types: [\n {\n description: \"JSON Files\",\n accept: {\n \"application/json\": [\".json\"],\n },\n },\n ],\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return null;\n }\n\n throw error;\n }\n }\n\n async render() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const showChannelsConfigButton = root.querySelector(\n '[data-action=\"show-channels-config\"]',\n );\n showChannelsConfigButton?.addEventListener(\"click\", () => {\n this.dispatchEvent(\n new CustomEvent(\"navigate\", {\n detail: { page: \"channels\" },\n bubbles: true,\n composed: true,\n }),\n );\n });\n\n const showToolsConfigButton = root.querySelector(\n '[data-action=\"show-tools-config\"]',\n );\n showToolsConfigButton?.addEventListener(\"click\", () => {\n this.dispatchEvent(\n new CustomEvent(\"navigate\", {\n detail: { page: \"tools\" },\n bubbles: true,\n composed: true,\n }),\n );\n });\n\n const tabButtons =\n root.querySelectorAll<HTMLButtonElement>(\"[data-tab-target]\");\n tabButtons.forEach((tabButton) => {\n tabButton.addEventListener(\"click\", () => {\n this.activateTab(tabButton.dataset.tabTarget);\n });\n\n tabButton.addEventListener(\"keydown\", (event) => {\n this.handleTabKeydown(event, tabButton);\n });\n });\n this.applyTabState();\n\n this.bindSettingsActions();\n\n const revisionEl = root.querySelector('[data-info=\"deployed-revision\"]');\n if (revisionEl) {\n const revision =\n document\n .querySelector('meta[name=\"revision\"]')\n ?.getAttribute(\"content\")\n ?.trim() || \"\";\n revisionEl.textContent = `Deployed revision: ${revision || \"unknown\"}`;\n }\n\n await this.populateAssistantSettings();\n }\n\n async replaceConfigEntries(entries: ConfigEntryRecord[]): Promise<void> {\n if (!this.db) {\n throw new Error(\"Database is unavailable\");\n }\n\n if (isSqliteDatabase(this.db)) {\n const raw = this.db.db;\n raw.prepare(\"DELETE FROM config\").run();\n const insertStmt = raw.prepare(\n \"INSERT OR REPLACE INTO config (key, value) VALUES (?, ?)\",\n );\n for (const entry of entries) {\n insertStmt.run(\n entry.key,\n typeof entry.value === \"string\"\n ? entry.value\n : JSON.stringify(entry.value),\n );\n }\n return;\n }\n\n const idb = this.db as IDBDatabase;\n await new Promise<void>((resolve, reject) => {\n try {\n const tx = idb.transaction(\"config\", \"readwrite\");\n if (!tx) {\n reject(new Error(\"Failed to open write transaction\"));\n\n return;\n }\n\n const store = tx.objectStore(\"config\");\n store.clear();\n for (const entry of entries) {\n store.put({ key: entry.key, value: entry.value });\n }\n\n tx.oncomplete = () => resolve();\n tx.onerror = () =>\n reject(tx.error || new Error(\"Failed to update config\"));\n tx.onabort = () =>\n reject(tx.error || new Error(\"Config update aborted\"));\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async saveAssistantName() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const nameInput = root.querySelector(\n '[data-setting=\"assistant-name-input\"]',\n ) as HTMLInputElement | null;\n if (!nameInput) {\n return;\n }\n\n const name = nameInput.value.trim();\n if (!name) {\n const { showWarning } = await import(\"../../ui/toast.js\");\n showWarning(\"Please enter a name\", 3000);\n\n return;\n }\n\n setNamespacedItem(\"assistantName\", name);\n\n try {\n const orchestrator = this.orchestrator || orchestratorStore.orchestrator;\n if (orchestrator) {\n this.orchestrator = orchestrator;\n await setAssistantName(orchestrator, this.db, name);\n } else {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n await setConfig(this.db, CONFIG_KEYS.ASSISTANT_NAME, name);\n }\n } catch (e) {\n console.warn(\"Could not update orchestrator:\", e);\n }\n\n showSuccess(\"Assistant name saved\", 3000);\n }\n\n async saveDomAllowedIframeHosts() {\n const root = this.shadowRoot;\n if (!root || !this.db) {\n return;\n }\n\n const textarea = root.querySelector(\n '[data-setting=\"dom-allowed-iframe-hosts\"]',\n ) as HTMLTextAreaElement | null;\n if (!textarea) {\n return;\n }\n\n const rawText = textarea.value;\n const lines = rawText\n .split(\"\\n\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n const markdownFrontmatterPagesToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-pages-toggle\"]',\n ) as HTMLInputElement | null;\n const markdownFrontmatterFileViewerToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-file-viewer-toggle\"]',\n ) as HTMLInputElement | null;\n const markdownFrontmatterChatToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-chat-toggle\"]',\n ) as HTMLInputElement | null;\n const markdownFrontmatterTasksToggle = root.querySelector(\n '[data-setting=\"markdown-frontmatter-tasks-toggle\"]',\n ) as HTMLInputElement | null;\n\n try {\n const { setConfig } = await import(\"../../db/setConfig.js\");\n const valueToSave = lines.join(\"\\n\");\n await setConfig(\n this.db,\n CONFIG_KEYS.ALLOWED_IFRAME_HOST_PATTERNS,\n valueToSave,\n );\n\n await setConfig(\n this.db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_PAGES,\n String(markdownFrontmatterPagesToggle?.checked ?? true),\n );\n\n await setConfig(\n this.db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_FILE_VIEWER,\n String(markdownFrontmatterFileViewerToggle?.checked ?? true),\n );\n\n await setConfig(\n this.db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_CHAT,\n String(markdownFrontmatterChatToggle?.checked ?? true),\n );\n\n await setConfig(\n this.db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_TASKS,\n String(markdownFrontmatterTasksToggle?.checked ?? true),\n );\n\n const { setAllowedIframeHostPatterns } =\n await import(\"../../security/iframe-sanitizer.js\");\n setAllowedIframeHostPatterns(lines);\n\n showSuccess(\"DOM iframe embed settings saved\", 2500);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving DOM iframe embed settings: \" + errorMsg, 6000);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawSettings);\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { r as getDb } from "./txPromise-DdeRXi7G.js";
3
3
  import { c as resetStorageDirectory } from "./getGroupDir-DF-RZO8X.js";
4
4
  import { r as CONFIG_KEYS } from "./config-CPHDmyTx.js";
5
5
  import { t as getConfig } from "./getConfig-B7JdRqIY.js";
6
- import { Bt as ensureMainGroupMemory, t as orchestratorStore, zt as ensureMainGroupIndex } from "./orchestrator-BEUug1TW.js";
6
+ import { Bt as ensureMainGroupMemory, t as orchestratorStore, zt as ensureMainGroupIndex } from "./orchestrator-DZkhJj7f.js";
7
7
  import { t as setConfig } from "./setConfig-CmvLryM3.js";
8
8
  import { v as setSanitizedHtml } from "./utils-JdK2r116.js";
9
9
  import { a as showSuccess, r as showError, s as showWarning } from "./toast-DZ6r7_YI.js";
@@ -525,4 +525,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
525
525
 
526
526
  //#endregion
527
527
  export { ShadowClawStorage as t };
528
- //# sourceMappingURL=shadow-claw-storage-Dt4yg4Q4.js.map
528
+ //# sourceMappingURL=shadow-claw-storage-ewDdvCGa.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-claw-storage-Dt4yg4Q4.js","names":["shadowClawStorageStyles","shadowClawStorageTemplate"],"sources":["../../src/storage/getStorageEstimate.ts","../../src/storage/isPersistent.ts","../../src/storage/requestPersistentStorage.ts","../../src/storage/selectStorageDirectory.ts","../../src/components/settings/shadow-claw-storage/shadow-claw-storage.ts"],"sourcesContent":["/**\n * Get storage usage estimate.\n */\nexport async function getStorageEstimate(): Promise<{\n usage: number;\n quota: number;\n}> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.estimate\n ) {\n const estimate = await navigator.storage.estimate();\n\n return {\n usage: estimate.usage || 0,\n quota: estimate.quota || 0,\n };\n }\n } catch (err) {\n console.warn(\"Failed to get storage estimate:\", err);\n }\n\n return { usage: 0, quota: 0 };\n}\n","/**\n * Check if the current storage is persistent.\n */\nexport async function isPersistent(): Promise<boolean> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.persisted\n ) {\n return await navigator.storage.persisted();\n }\n } catch (err) {\n console.warn(\"Failed to check persistent storage:\", err);\n }\n\n return false;\n}\n","/**\n * Request persistent storage so the browser doesn't evict our data.\n */\nexport async function requestPersistentStorage(): Promise<boolean> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.persist\n ) {\n return await navigator.storage.persist();\n }\n } catch (err) {\n console.warn(\"Failed to request persistent storage:\", err);\n }\n\n return false;\n}\n","import { CONFIG_KEYS } from \"../config/config.js\";\nimport { setConfig } from \"../db/setConfig.js\";\nimport { ensureMainGroupMemory } from \"./ensureMainGroupMemory.js\";\nimport { ensureMainGroupIndex } from \"./ensureMainGroupIndex.js\";\nimport type { ShadowClawDatabase } from \"../db/types.js\";\n\n/**\n * Select a local directory for storage using the File System Access API.\n */\nexport async function selectStorageDirectory(\n db: ShadowClawDatabase,\n): Promise<boolean> {\n const pickerMaybe = Reflect.get(globalThis, \"showDirectoryPicker\");\n const picker =\n typeof pickerMaybe === \"function\" ? pickerMaybe.bind(globalThis) : null;\n\n if (!picker) {\n throw new Error(\n \"Local folder picker is unavailable in this browser/context.\",\n );\n }\n\n try {\n const handle = await picker({\n mode: \"readwrite\",\n id: \"shadowclaw-storage\",\n });\n\n // Verify it's not the same as OPFS or something restricted\n // (Most browsers handle this, but good to have a handle)\n await setConfig(db, CONFIG_KEYS.STORAGE_HANDLE, handle);\n await ensureMainGroupMemory(db);\n await ensureMainGroupIndex(db);\n\n return true;\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return false;\n }\n\n throw err;\n }\n}\n","import { CONFIG_KEYS } from \"../../../config/config.js\";\nimport { effect } from \"../../../core/effect.js\";\n\nimport { getDb } from \"../../../db/db.js\";\nimport { getConfig } from \"../../../db/getConfig.js\";\n\nimport { setSanitizedHtml } from \"../../../security/trusted-types.js\";\nimport { getStorageEstimate } from \"../../../storage/getStorageEstimate.js\";\nimport { isPersistent } from \"../../../storage/isPersistent.js\";\nimport { requestPersistentStorage } from \"../../../storage/requestPersistentStorage.js\";\nimport { selectStorageDirectory } from \"../../../storage/selectStorageDirectory.js\";\nimport { resetStorageDirectory } from \"../../../storage/storage.js\";\n\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess, showWarning } from \"../../../ui/toast.js\";\nimport { isTruthyConfigValue } from \"../../../common/utils/config-value.mjs\";\n\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawStorageStyles from \"./shadow-claw-storage.css\" with { type: \"css\" };\nimport shadowClawStorageTemplate from \"./shadow-claw-storage.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-storage\";\n\n/**\n * Settings sub-component for Storage configuration:\n * usage display, persistent storage, directory selection.\n */\nexport class ShadowClawStorage extends ShadowClawElement {\n static styles = shadowClawStorageStyles;\n static template = shadowClawStorageTemplate;\n\n public db: ShadowClawDatabase | 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 this.bindEventListeners();\n this.setupEffects();\n\n await this.updateStorageInfo();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n /**\n * Bind all event listeners.\n */\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"request-persistent\"]')\n ?.addEventListener(\"click\", () => this.handleRequestPersistent());\n\n root\n .querySelector('[data-action=\"change-storage-dir\"]')\n ?.addEventListener(\"click\", () => this.handleChangeStorageDir());\n\n root\n .querySelector('[data-action=\"reset-storage-dir\"]')\n ?.addEventListener(\"click\", () => this.handleResetStorageDir());\n\n root\n .querySelector('[data-action=\"reset-site-config\"]')\n ?.addEventListener(\"click\", () => this.handleResetSiteConfig());\n\n root\n .querySelector('[data-action=\"grant-storage-permission\"]')\n ?.addEventListener(\"click\", () => {\n if (this.db) {\n orchestratorStore.grantStorageAccess(this.db);\n }\n });\n\n root\n .querySelector('[data-setting=\"files-upload-append-ulid-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onUploadAppendUlidToggle(target.checked);\n }\n });\n }\n\n /**\n * Format bytes to human readable string.\n */\n formatBytes(bytes: number): string {\n if (bytes === 0) {\n return \"0 B\";\n }\n\n const k = 1024;\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + \" \" + units[i];\n }\n\n /**\n * Setup reactive effects for storage status from orchestratorStore.\n */\n setupEffects() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n this.addCleanup(\n effect(() => {\n const status = orchestratorStore.storageStatus;\n if (!status) {\n return;\n }\n\n const typeEl = root.querySelector('[data-info=\"storage-type\"]');\n const statusBadge = root.querySelector(\n '[data-info=\"storage-status-badge\"]',\n ) as HTMLElement | null;\n const grantBtn = root.querySelector(\n '[data-action=\"grant-storage-permission\"]',\n ) as HTMLElement | null;\n\n if (typeEl) {\n typeEl.textContent =\n status.type === \"local\"\n ? \"Local Directory\"\n : \"Browser Internal (OPFS)\";\n }\n\n if (statusBadge) {\n statusBadge.style.display =\n status.type === \"local\" ? \"inline-block\" : \"none\";\n if (status.type === \"local\") {\n statusBadge.textContent =\n status.permission === \"granted\"\n ? \"CONNECTED\"\n : \"NEEDS PERMISSION\";\n statusBadge.style.backgroundColor =\n status.permission === \"granted\"\n ? \"var(--shadow-claw-success-color)\"\n : \"var(--shadow-claw-error-color)\";\n statusBadge.style.color = \"white\";\n }\n }\n\n if (grantBtn) {\n grantBtn.style.display =\n status.type === \"local\" && status.permission !== \"granted\"\n ? \"inline-block\"\n : \"none\";\n }\n }),\n );\n }\n\n /**\n * Handle changing storage directory.\n */\n async handleChangeStorageDir() {\n if (!this.db) {\n return;\n }\n\n try {\n const success = await selectStorageDirectory(this.db);\n if (success) {\n showSuccess(\n \"Storage location changed. Existing OPFS files were not moved.\",\n 4500,\n );\n\n await this.updateStorageInfo();\n await orchestratorStore.loadFiles(this.db);\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to change storage location: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle persistent storage request.\n */\n async handleRequestPersistent() {\n if (!this.db) {\n return;\n }\n\n try {\n const granted = await requestPersistentStorage();\n if (granted) {\n showSuccess(\"Persistent storage granted\", 3500);\n } else {\n showWarning(\n \"Persistent storage was not granted. Browsers may deny this based on site usage.\",\n 5500,\n );\n }\n\n await this.updateStorageInfo();\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Storage request failed: ${errorMsg}`, 6000);\n }\n }\n\n async handleResetSiteConfig() {\n if (!this.db) {\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Reset Site Config\",\n message:\n \"Allow embedded site-config.json defaults to apply again after the next reload?\",\n confirmLabel: \"Reset\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await orchestratorStore.resetSiteConfigSeed(this.db);\n showSuccess(\n \"Site config reset. Reload to apply its defaults again.\",\n 5000,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to reset site config: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle resetting storage directory.\n */\n async handleResetStorageDir() {\n if (!this.db) {\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Reset Storage Location\",\n message: \"Revert storage to browser-internal (OPFS)?\",\n confirmLabel: \"Revert\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await resetStorageDirectory(this.db);\n\n showSuccess(\"Reverted to browser-internal storage\", 3500);\n\n await this.updateStorageInfo();\n await orchestratorStore.loadFiles(this.db);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to reset storage location: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle toggling unique ID prefix for uploaded files.\n */\n async onUploadAppendUlidToggle(enabled: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.FILES_UPLOAD_APPEND_ULID,\n enabled ? \"true\" : \"false\",\n );\n\n showSuccess(\n enabled\n ? \"Unique ID prefix on file upload enabled\"\n : \"Unique ID prefix on file upload disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\n \"Error saving unique ID file upload setting: \" + errorMsg,\n 6000,\n );\n }\n }\n\n async requestConfirmation(options: {\n title: string;\n message: string;\n confirmLabel?: string;\n cancelLabel?: string;\n }): Promise<boolean> {\n const appShell = document.querySelector(\"shadow-claw\") as any;\n if (appShell && typeof appShell.requestDialog === \"function\") {\n return await appShell.requestDialog({ mode: \"confirm\", ...options });\n }\n\n showWarning(options.message, 4500);\n\n return false;\n }\n\n /**\n * Update storage information in UI.\n */\n async updateStorageInfo() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n try {\n const estimate = await getStorageEstimate();\n const usageStr = this.formatBytes(estimate.usage);\n const quotaStr = this.formatBytes(estimate.quota);\n const percent =\n estimate.quota > 0 ? (estimate.usage / estimate.quota) * 100 : 0;\n\n const usageEl = root.querySelector('[data-info=\"storage-usage\"]');\n const quotaEl = root.querySelector('[data-info=\"storage-quota\"]');\n const progressEl = root.querySelector(\n '[data-info=\"storage-progress\"]',\n ) as HTMLElement | null;\n\n const typeEl = root.querySelector('[data-info=\"storage-type\"]');\n const persistentBadge = root.querySelector(\n '[data-info=\"storage-persistent-badge\"]',\n ) as HTMLElement | null;\n\n if (usageEl) {\n usageEl.textContent = `${usageStr} used`;\n }\n\n if (quotaEl) {\n quotaEl.textContent = `of ${quotaStr}`;\n }\n\n if (progressEl) {\n progressEl.style.width = `${percent}%`;\n }\n\n // Check storage type\n const handle = await getConfig(this.db, CONFIG_KEYS.STORAGE_HANDLE);\n if (typeEl) {\n typeEl.textContent = handle\n ? \"Local Directory\"\n : \"Browser Internal (OPFS)\";\n }\n\n // Check persistence\n const persistent = await isPersistent();\n if (persistentBadge) {\n persistentBadge.style.display = persistent ? \"inline-block\" : \"none\";\n }\n\n // Update help text\n const helpGeneralEl = root.querySelector(\n '[data-info=\"storage-help-general\"]',\n );\n\n const helpLocalEl = root.querySelector(\n '[data-info=\"storage-help-local\"]',\n );\n\n if (helpGeneralEl) {\n setSanitizedHtml(\n helpGeneralEl,\n handle\n ? `Persistent storage protects your <b>chat history, tasks, and settings</b> in the browser database.\n Without it, the browser might clear this data if your disk is almost full.`\n : `Persistent storage protects your <b>files, chat history, and settings</b> in the browser.\n Without it, the browser might clear your data if your disk is almost full.`,\n );\n }\n\n if (helpLocalEl) {\n setSanitizedHtml(\n helpLocalEl,\n handle\n ? `ShadowClaw is currently <b>connected to a local folder</b>. Your files are safe on your disk,\n but browser persistence is still recommended for your chat history.`\n : `You can use a local folder on your computer for storage. This makes files directly accessible\n on your disk and independent of browser storage limits.`,\n );\n }\n\n // Disable persistent button if already persistent\n const requestPersistentBtn = root.querySelector(\n '[data-action=\"request-persistent\"]',\n ) as HTMLButtonElement | null;\n if (requestPersistentBtn) {\n requestPersistentBtn.disabled = persistent;\n }\n\n // Sync upload append ULID toggle\n const uploadAppendUlidVal = await getConfig(\n this.db,\n CONFIG_KEYS.FILES_UPLOAD_APPEND_ULID,\n );\n const uploadAppendUlidToggle = root.querySelector(\n '[data-setting=\"files-upload-append-ulid-toggle\"]',\n ) as HTMLInputElement | null;\n if (uploadAppendUlidToggle) {\n uploadAppendUlidToggle.checked = isTruthyConfigValue(\n uploadAppendUlidVal,\n false,\n );\n }\n } catch (err) {\n console.warn(\"Failed to update storage info:\", err);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawStorage);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shadow-claw-storage-ewDdvCGa.js","names":["shadowClawStorageStyles","shadowClawStorageTemplate"],"sources":["../../src/storage/getStorageEstimate.ts","../../src/storage/isPersistent.ts","../../src/storage/requestPersistentStorage.ts","../../src/storage/selectStorageDirectory.ts","../../src/components/settings/shadow-claw-storage/shadow-claw-storage.ts"],"sourcesContent":["/**\n * Get storage usage estimate.\n */\nexport async function getStorageEstimate(): Promise<{\n usage: number;\n quota: number;\n}> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.estimate\n ) {\n const estimate = await navigator.storage.estimate();\n\n return {\n usage: estimate.usage || 0,\n quota: estimate.quota || 0,\n };\n }\n } catch (err) {\n console.warn(\"Failed to get storage estimate:\", err);\n }\n\n return { usage: 0, quota: 0 };\n}\n","/**\n * Check if the current storage is persistent.\n */\nexport async function isPersistent(): Promise<boolean> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.persisted\n ) {\n return await navigator.storage.persisted();\n }\n } catch (err) {\n console.warn(\"Failed to check persistent storage:\", err);\n }\n\n return false;\n}\n","/**\n * Request persistent storage so the browser doesn't evict our data.\n */\nexport async function requestPersistentStorage(): Promise<boolean> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.persist\n ) {\n return await navigator.storage.persist();\n }\n } catch (err) {\n console.warn(\"Failed to request persistent storage:\", err);\n }\n\n return false;\n}\n","import { CONFIG_KEYS } from \"../config/config.js\";\nimport { setConfig } from \"../db/setConfig.js\";\nimport { ensureMainGroupMemory } from \"./ensureMainGroupMemory.js\";\nimport { ensureMainGroupIndex } from \"./ensureMainGroupIndex.js\";\nimport type { ShadowClawDatabase } from \"../db/types.js\";\n\n/**\n * Select a local directory for storage using the File System Access API.\n */\nexport async function selectStorageDirectory(\n db: ShadowClawDatabase,\n): Promise<boolean> {\n const pickerMaybe = Reflect.get(globalThis, \"showDirectoryPicker\");\n const picker =\n typeof pickerMaybe === \"function\" ? pickerMaybe.bind(globalThis) : null;\n\n if (!picker) {\n throw new Error(\n \"Local folder picker is unavailable in this browser/context.\",\n );\n }\n\n try {\n const handle = await picker({\n mode: \"readwrite\",\n id: \"shadowclaw-storage\",\n });\n\n // Verify it's not the same as OPFS or something restricted\n // (Most browsers handle this, but good to have a handle)\n await setConfig(db, CONFIG_KEYS.STORAGE_HANDLE, handle);\n await ensureMainGroupMemory(db);\n await ensureMainGroupIndex(db);\n\n return true;\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return false;\n }\n\n throw err;\n }\n}\n","import { CONFIG_KEYS } from \"../../../config/config.js\";\nimport { effect } from \"../../../core/effect.js\";\n\nimport { getDb } from \"../../../db/db.js\";\nimport { getConfig } from \"../../../db/getConfig.js\";\n\nimport { setSanitizedHtml } from \"../../../security/trusted-types.js\";\nimport { getStorageEstimate } from \"../../../storage/getStorageEstimate.js\";\nimport { isPersistent } from \"../../../storage/isPersistent.js\";\nimport { requestPersistentStorage } from \"../../../storage/requestPersistentStorage.js\";\nimport { selectStorageDirectory } from \"../../../storage/selectStorageDirectory.js\";\nimport { resetStorageDirectory } from \"../../../storage/storage.js\";\n\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess, showWarning } from \"../../../ui/toast.js\";\nimport { isTruthyConfigValue } from \"../../../common/utils/config-value.mjs\";\n\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawStorageStyles from \"./shadow-claw-storage.css\" with { type: \"css\" };\nimport shadowClawStorageTemplate from \"./shadow-claw-storage.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-storage\";\n\n/**\n * Settings sub-component for Storage configuration:\n * usage display, persistent storage, directory selection.\n */\nexport class ShadowClawStorage extends ShadowClawElement {\n static styles = shadowClawStorageStyles;\n static template = shadowClawStorageTemplate;\n\n public db: ShadowClawDatabase | 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 this.bindEventListeners();\n this.setupEffects();\n\n await this.updateStorageInfo();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n /**\n * Bind all event listeners.\n */\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"request-persistent\"]')\n ?.addEventListener(\"click\", () => this.handleRequestPersistent());\n\n root\n .querySelector('[data-action=\"change-storage-dir\"]')\n ?.addEventListener(\"click\", () => this.handleChangeStorageDir());\n\n root\n .querySelector('[data-action=\"reset-storage-dir\"]')\n ?.addEventListener(\"click\", () => this.handleResetStorageDir());\n\n root\n .querySelector('[data-action=\"reset-site-config\"]')\n ?.addEventListener(\"click\", () => this.handleResetSiteConfig());\n\n root\n .querySelector('[data-action=\"grant-storage-permission\"]')\n ?.addEventListener(\"click\", () => {\n if (this.db) {\n orchestratorStore.grantStorageAccess(this.db);\n }\n });\n\n root\n .querySelector('[data-setting=\"files-upload-append-ulid-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onUploadAppendUlidToggle(target.checked);\n }\n });\n }\n\n /**\n * Format bytes to human readable string.\n */\n formatBytes(bytes: number): string {\n if (bytes === 0) {\n return \"0 B\";\n }\n\n const k = 1024;\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + \" \" + units[i];\n }\n\n /**\n * Setup reactive effects for storage status from orchestratorStore.\n */\n setupEffects() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n this.addCleanup(\n effect(() => {\n const status = orchestratorStore.storageStatus;\n if (!status) {\n return;\n }\n\n const typeEl = root.querySelector('[data-info=\"storage-type\"]');\n const statusBadge = root.querySelector(\n '[data-info=\"storage-status-badge\"]',\n ) as HTMLElement | null;\n const grantBtn = root.querySelector(\n '[data-action=\"grant-storage-permission\"]',\n ) as HTMLElement | null;\n\n if (typeEl) {\n typeEl.textContent =\n status.type === \"local\"\n ? \"Local Directory\"\n : \"Browser Internal (OPFS)\";\n }\n\n if (statusBadge) {\n statusBadge.style.display =\n status.type === \"local\" ? \"inline-block\" : \"none\";\n if (status.type === \"local\") {\n statusBadge.textContent =\n status.permission === \"granted\"\n ? \"CONNECTED\"\n : \"NEEDS PERMISSION\";\n statusBadge.style.backgroundColor =\n status.permission === \"granted\"\n ? \"var(--shadow-claw-success-color)\"\n : \"var(--shadow-claw-error-color)\";\n statusBadge.style.color = \"white\";\n }\n }\n\n if (grantBtn) {\n grantBtn.style.display =\n status.type === \"local\" && status.permission !== \"granted\"\n ? \"inline-block\"\n : \"none\";\n }\n }),\n );\n }\n\n /**\n * Handle changing storage directory.\n */\n async handleChangeStorageDir() {\n if (!this.db) {\n return;\n }\n\n try {\n const success = await selectStorageDirectory(this.db);\n if (success) {\n showSuccess(\n \"Storage location changed. Existing OPFS files were not moved.\",\n 4500,\n );\n\n await this.updateStorageInfo();\n await orchestratorStore.loadFiles(this.db);\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to change storage location: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle persistent storage request.\n */\n async handleRequestPersistent() {\n if (!this.db) {\n return;\n }\n\n try {\n const granted = await requestPersistentStorage();\n if (granted) {\n showSuccess(\"Persistent storage granted\", 3500);\n } else {\n showWarning(\n \"Persistent storage was not granted. Browsers may deny this based on site usage.\",\n 5500,\n );\n }\n\n await this.updateStorageInfo();\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Storage request failed: ${errorMsg}`, 6000);\n }\n }\n\n async handleResetSiteConfig() {\n if (!this.db) {\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Reset Site Config\",\n message:\n \"Allow embedded site-config.json defaults to apply again after the next reload?\",\n confirmLabel: \"Reset\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await orchestratorStore.resetSiteConfigSeed(this.db);\n showSuccess(\n \"Site config reset. Reload to apply its defaults again.\",\n 5000,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to reset site config: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle resetting storage directory.\n */\n async handleResetStorageDir() {\n if (!this.db) {\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Reset Storage Location\",\n message: \"Revert storage to browser-internal (OPFS)?\",\n confirmLabel: \"Revert\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await resetStorageDirectory(this.db);\n\n showSuccess(\"Reverted to browser-internal storage\", 3500);\n\n await this.updateStorageInfo();\n await orchestratorStore.loadFiles(this.db);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to reset storage location: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle toggling unique ID prefix for uploaded files.\n */\n async onUploadAppendUlidToggle(enabled: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../../db/setConfig.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.FILES_UPLOAD_APPEND_ULID,\n enabled ? \"true\" : \"false\",\n );\n\n showSuccess(\n enabled\n ? \"Unique ID prefix on file upload enabled\"\n : \"Unique ID prefix on file upload disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\n \"Error saving unique ID file upload setting: \" + errorMsg,\n 6000,\n );\n }\n }\n\n async requestConfirmation(options: {\n title: string;\n message: string;\n confirmLabel?: string;\n cancelLabel?: string;\n }): Promise<boolean> {\n const appShell = document.querySelector(\"shadow-claw\") as any;\n if (appShell && typeof appShell.requestDialog === \"function\") {\n return await appShell.requestDialog({ mode: \"confirm\", ...options });\n }\n\n showWarning(options.message, 4500);\n\n return false;\n }\n\n /**\n * Update storage information in UI.\n */\n async updateStorageInfo() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n try {\n const estimate = await getStorageEstimate();\n const usageStr = this.formatBytes(estimate.usage);\n const quotaStr = this.formatBytes(estimate.quota);\n const percent =\n estimate.quota > 0 ? (estimate.usage / estimate.quota) * 100 : 0;\n\n const usageEl = root.querySelector('[data-info=\"storage-usage\"]');\n const quotaEl = root.querySelector('[data-info=\"storage-quota\"]');\n const progressEl = root.querySelector(\n '[data-info=\"storage-progress\"]',\n ) as HTMLElement | null;\n\n const typeEl = root.querySelector('[data-info=\"storage-type\"]');\n const persistentBadge = root.querySelector(\n '[data-info=\"storage-persistent-badge\"]',\n ) as HTMLElement | null;\n\n if (usageEl) {\n usageEl.textContent = `${usageStr} used`;\n }\n\n if (quotaEl) {\n quotaEl.textContent = `of ${quotaStr}`;\n }\n\n if (progressEl) {\n progressEl.style.width = `${percent}%`;\n }\n\n // Check storage type\n const handle = await getConfig(this.db, CONFIG_KEYS.STORAGE_HANDLE);\n if (typeEl) {\n typeEl.textContent = handle\n ? \"Local Directory\"\n : \"Browser Internal (OPFS)\";\n }\n\n // Check persistence\n const persistent = await isPersistent();\n if (persistentBadge) {\n persistentBadge.style.display = persistent ? \"inline-block\" : \"none\";\n }\n\n // Update help text\n const helpGeneralEl = root.querySelector(\n '[data-info=\"storage-help-general\"]',\n );\n\n const helpLocalEl = root.querySelector(\n '[data-info=\"storage-help-local\"]',\n );\n\n if (helpGeneralEl) {\n setSanitizedHtml(\n helpGeneralEl,\n handle\n ? `Persistent storage protects your <b>chat history, tasks, and settings</b> in the browser database.\n Without it, the browser might clear this data if your disk is almost full.`\n : `Persistent storage protects your <b>files, chat history, and settings</b> in the browser.\n Without it, the browser might clear your data if your disk is almost full.`,\n );\n }\n\n if (helpLocalEl) {\n setSanitizedHtml(\n helpLocalEl,\n handle\n ? `ShadowClaw is currently <b>connected to a local folder</b>. Your files are safe on your disk,\n but browser persistence is still recommended for your chat history.`\n : `You can use a local folder on your computer for storage. This makes files directly accessible\n on your disk and independent of browser storage limits.`,\n );\n }\n\n // Disable persistent button if already persistent\n const requestPersistentBtn = root.querySelector(\n '[data-action=\"request-persistent\"]',\n ) as HTMLButtonElement | null;\n if (requestPersistentBtn) {\n requestPersistentBtn.disabled = persistent;\n }\n\n // Sync upload append ULID toggle\n const uploadAppendUlidVal = await getConfig(\n this.db,\n CONFIG_KEYS.FILES_UPLOAD_APPEND_ULID,\n );\n const uploadAppendUlidToggle = root.querySelector(\n '[data-setting=\"files-upload-append-ulid-toggle\"]',\n ) as HTMLInputElement | null;\n if (uploadAppendUlidToggle) {\n uploadAppendUlidToggle.checked = isTruthyConfigValue(\n uploadAppendUlidVal,\n false,\n );\n }\n } catch (err) {\n console.warn(\"Failed to update storage info:\", err);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawStorage);\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import ShadowClawElement from "./components/shadow-claw-element.js";
2
2
  import { r as getDb } from "./txPromise-DdeRXi7G.js";
3
- import { g as setTaskServerUrl, h as setTaskServerEnabled, t as orchestratorStore } from "./orchestrator-BEUug1TW.js";
3
+ import { g as setTaskServerUrl, h as setTaskServerEnabled, t as orchestratorStore } from "./orchestrator-DZkhJj7f.js";
4
4
  import { a as showSuccess, r as showError } from "./toast-DZ6r7_YI.js";
5
5
  import { t as effect } from "./effect-DL6j9HJp.js";
6
6
 
@@ -266,4 +266,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
266
266
 
267
267
  //#endregion
268
268
  export { ShadowClawTaskServer as t };
269
- //# sourceMappingURL=shadow-claw-task-server-B2gbZaz4.js.map
269
+ //# sourceMappingURL=shadow-claw-task-server-DpqQcNIs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-claw-task-server-B2gbZaz4.js","names":["shadowClawTaskServerStyles","shadowClawTaskServerTemplate"],"sources":["../../src/components/settings/shadow-claw-task-server/shadow-claw-task-server.ts"],"sourcesContent":["import { effect } from \"../../../core/effect.js\";\nimport {\n setTaskServerEnabled,\n setTaskServerUrl,\n} from \"../../../core/orchestrator/utils/settings.js\";\nimport { getDb } from \"../../../db/db.js\";\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess } from \"../../../ui/toast.js\";\n\nimport type { Orchestrator } from \"../../../core/orchestrator/orchestrator.js\";\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawTaskServerStyles from \"./shadow-claw-task-server.css\" with { type: \"css\" };\nimport shadowClawTaskServerTemplate from \"./shadow-claw-task-server.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-task-server\";\n\n/**\n * Settings sub-component for Task Server URL and server-side task scheduling configuration.\n */\nexport class ShadowClawTaskServer extends ShadowClawElement {\n static styles = shadowClawTaskServerStyles;\n static template = shadowClawTaskServerTemplate;\n\n db: ShadowClawDatabase | null;\n orchestrator: Orchestrator | null;\n\n constructor() {\n super();\n\n this.db = null;\n this.orchestrator = null;\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 bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"save-task-server-url\"]')\n ?.addEventListener(\"click\", () => {\n void this.saveTaskServerUrl();\n });\n\n root\n .querySelector('[data-setting=\"task-server-enabled-toggle\"]')\n ?.addEventListener(\"change\", (e) => {\n const target = e.target as HTMLInputElement;\n void this.saveTaskServerEnabled(target.checked);\n });\n }\n\n setupEffects() {\n effect(() => {\n if (orchestratorStore.ready) {\n this.orchestrator = orchestratorStore.orchestrator;\n this.render();\n }\n });\n }\n\n async render() {\n if (!this.orchestrator) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"task-server-url-input\"]',\n ) as HTMLInputElement | null;\n if (input) {\n input.value = this.orchestrator.taskServerUrl;\n }\n\n const enabledToggle = root.querySelector(\n '[data-setting=\"task-server-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n if (enabledToggle) {\n enabledToggle.checked = this.orchestrator.taskServerEnabled;\n }\n }\n\n async saveTaskServerEnabled(enabled: boolean) {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n try {\n await setTaskServerEnabled(this.orchestrator, this.db, enabled);\n if (\n enabled &&\n typeof this.orchestrator.ensureAllConnections === \"function\"\n ) {\n void this.orchestrator.ensureAllConnections();\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Task Server setting: \" + errorMsg, 6000);\n }\n }\n\n async saveTaskServerUrl() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"task-server-url-input\"]',\n ) as HTMLInputElement | null;\n if (!input) {\n return;\n }\n\n const url = input.value.trim();\n\n try {\n await setTaskServerUrl(this.orchestrator, this.db, url || \"/schedule\");\n if (\n this.orchestrator.taskServerEnabled &&\n typeof this.orchestrator.ensureAllConnections === \"function\"\n ) {\n void this.orchestrator.ensureAllConnections();\n }\n showSuccess(\"Task Server URL saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Task Server URL: \" + errorMsg, 6000);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawTaskServer);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,MAAM,cAAc;;;;AAKpB,IAAa,uBAAb,cAA0C,kBAAkB;CAC1D,OAAO,SAASA;CAChB,OAAO,WAAWC;CAElB;CACA;CAEA,cAAc;EACZ,MAAM;EAEN,KAAK,KAAK;EACV,KAAK,eAAe;CACtB;CAEA,MAAM,oBAAoB;EAExB,IAAI,CADS,KAAK,YAEhB,MAAM,IAAI,MAAM,sBAAsB;EAGxC,KAAK,KAAK,MAAM,MAAM;EACtB,KAAK,eAAe,kBAAkB;EAEtC,KAAK,mBAAmB;EACxB,KAAK,aAAa;EAClB,MAAM,KAAK,OAAO;CACpB;CAEA,qBAAqB;EACnB,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,KACG,cAAc,wCAAsC,CAAC,EACpD,iBAAiB,eAAe;GAChC,AAAK,KAAK,kBAAkB;EAC9B,CAAC;EAEH,KACG,cAAc,+CAA6C,CAAC,EAC3D,iBAAiB,WAAW,MAAM;GAClC,MAAM,SAAS,EAAE;GACjB,AAAK,KAAK,sBAAsB,OAAO,OAAO;EAChD,CAAC;CACL;CAEA,eAAe;EACb,aAAa;GACX,IAAI,kBAAkB,OAAO;IAC3B,KAAK,eAAe,kBAAkB;IACtC,KAAK,OAAO;GACd;EACF,CAAC;CACH;CAEA,MAAM,SAAS;EACb,IAAI,CAAC,KAAK,cACR;EAGF,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,MAAM,QAAQ,KAAK,cACjB,0CACF;EACA,IAAI,OACF,MAAM,QAAQ,KAAK,aAAa;EAGlC,MAAM,gBAAgB,KAAK,cACzB,+CACF;EACA,IAAI,eACF,cAAc,UAAU,KAAK,aAAa;CAE9C;CAEA,MAAM,sBAAsB,SAAkB;EAC5C,IAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,IAC9B;EAGF,IAAI;GACF,MAAM,qBAAqB,KAAK,cAAc,KAAK,IAAI,OAAO;GAC9D,IACE,WACA,OAAO,KAAK,aAAa,yBAAyB,YAElD,AAAK,KAAK,aAAa,qBAAqB;EAEhD,SAAS,KAAK;GAEZ,UAAU,wCADO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,IACL,GAAI;EACjE;CACF;CAEA,MAAM,oBAAoB;EACxB,IAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,IAC9B;EAGF,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,MAAM,QAAQ,KAAK,cACjB,0CACF;EACA,IAAI,CAAC,OACH;EAGF,MAAM,MAAM,MAAM,MAAM,KAAK;EAE7B,IAAI;GACF,MAAM,iBAAiB,KAAK,cAAc,KAAK,IAAI,OAAO,WAAW;GACrE,IACE,KAAK,aAAa,qBAClB,OAAO,KAAK,aAAa,yBAAyB,YAElD,AAAK,KAAK,aAAa,qBAAqB;GAE9C,YAAY,yBAAyB,GAAI;EAC3C,SAAS,KAAK;GAEZ,UAAU,oCADO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,IACT,GAAI;EAC7D;CACF;AACF;AAEA,IAAI,CAAC,eAAe,IAAI,WAAW,GACjC,eAAe,OAAO,aAAa,oBAAoB"}
1
+ {"version":3,"file":"shadow-claw-task-server-DpqQcNIs.js","names":["shadowClawTaskServerStyles","shadowClawTaskServerTemplate"],"sources":["../../src/components/settings/shadow-claw-task-server/shadow-claw-task-server.ts"],"sourcesContent":["import { effect } from \"../../../core/effect.js\";\nimport {\n setTaskServerEnabled,\n setTaskServerUrl,\n} from \"../../../core/orchestrator/utils/settings.js\";\nimport { getDb } from \"../../../db/db.js\";\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess } from \"../../../ui/toast.js\";\n\nimport type { Orchestrator } from \"../../../core/orchestrator/orchestrator.js\";\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawTaskServerStyles from \"./shadow-claw-task-server.css\" with { type: \"css\" };\nimport shadowClawTaskServerTemplate from \"./shadow-claw-task-server.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-task-server\";\n\n/**\n * Settings sub-component for Task Server URL and server-side task scheduling configuration.\n */\nexport class ShadowClawTaskServer extends ShadowClawElement {\n static styles = shadowClawTaskServerStyles;\n static template = shadowClawTaskServerTemplate;\n\n db: ShadowClawDatabase | null;\n orchestrator: Orchestrator | null;\n\n constructor() {\n super();\n\n this.db = null;\n this.orchestrator = null;\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 bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"save-task-server-url\"]')\n ?.addEventListener(\"click\", () => {\n void this.saveTaskServerUrl();\n });\n\n root\n .querySelector('[data-setting=\"task-server-enabled-toggle\"]')\n ?.addEventListener(\"change\", (e) => {\n const target = e.target as HTMLInputElement;\n void this.saveTaskServerEnabled(target.checked);\n });\n }\n\n setupEffects() {\n effect(() => {\n if (orchestratorStore.ready) {\n this.orchestrator = orchestratorStore.orchestrator;\n this.render();\n }\n });\n }\n\n async render() {\n if (!this.orchestrator) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"task-server-url-input\"]',\n ) as HTMLInputElement | null;\n if (input) {\n input.value = this.orchestrator.taskServerUrl;\n }\n\n const enabledToggle = root.querySelector(\n '[data-setting=\"task-server-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n if (enabledToggle) {\n enabledToggle.checked = this.orchestrator.taskServerEnabled;\n }\n }\n\n async saveTaskServerEnabled(enabled: boolean) {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n try {\n await setTaskServerEnabled(this.orchestrator, this.db, enabled);\n if (\n enabled &&\n typeof this.orchestrator.ensureAllConnections === \"function\"\n ) {\n void this.orchestrator.ensureAllConnections();\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Task Server setting: \" + errorMsg, 6000);\n }\n }\n\n async saveTaskServerUrl() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"task-server-url-input\"]',\n ) as HTMLInputElement | null;\n if (!input) {\n return;\n }\n\n const url = input.value.trim();\n\n try {\n await setTaskServerUrl(this.orchestrator, this.db, url || \"/schedule\");\n if (\n this.orchestrator.taskServerEnabled &&\n typeof this.orchestrator.ensureAllConnections === \"function\"\n ) {\n void this.orchestrator.ensureAllConnections();\n }\n showSuccess(\"Task Server URL saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Task Server URL: \" + errorMsg, 6000);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawTaskServer);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,MAAM,cAAc;;;;AAKpB,IAAa,uBAAb,cAA0C,kBAAkB;CAC1D,OAAO,SAASA;CAChB,OAAO,WAAWC;CAElB;CACA;CAEA,cAAc;EACZ,MAAM;EAEN,KAAK,KAAK;EACV,KAAK,eAAe;CACtB;CAEA,MAAM,oBAAoB;EAExB,IAAI,CADS,KAAK,YAEhB,MAAM,IAAI,MAAM,sBAAsB;EAGxC,KAAK,KAAK,MAAM,MAAM;EACtB,KAAK,eAAe,kBAAkB;EAEtC,KAAK,mBAAmB;EACxB,KAAK,aAAa;EAClB,MAAM,KAAK,OAAO;CACpB;CAEA,qBAAqB;EACnB,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,KACG,cAAc,wCAAsC,CAAC,EACpD,iBAAiB,eAAe;GAChC,AAAK,KAAK,kBAAkB;EAC9B,CAAC;EAEH,KACG,cAAc,+CAA6C,CAAC,EAC3D,iBAAiB,WAAW,MAAM;GAClC,MAAM,SAAS,EAAE;GACjB,AAAK,KAAK,sBAAsB,OAAO,OAAO;EAChD,CAAC;CACL;CAEA,eAAe;EACb,aAAa;GACX,IAAI,kBAAkB,OAAO;IAC3B,KAAK,eAAe,kBAAkB;IACtC,KAAK,OAAO;GACd;EACF,CAAC;CACH;CAEA,MAAM,SAAS;EACb,IAAI,CAAC,KAAK,cACR;EAGF,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,MAAM,QAAQ,KAAK,cACjB,0CACF;EACA,IAAI,OACF,MAAM,QAAQ,KAAK,aAAa;EAGlC,MAAM,gBAAgB,KAAK,cACzB,+CACF;EACA,IAAI,eACF,cAAc,UAAU,KAAK,aAAa;CAE9C;CAEA,MAAM,sBAAsB,SAAkB;EAC5C,IAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,IAC9B;EAGF,IAAI;GACF,MAAM,qBAAqB,KAAK,cAAc,KAAK,IAAI,OAAO;GAC9D,IACE,WACA,OAAO,KAAK,aAAa,yBAAyB,YAElD,AAAK,KAAK,aAAa,qBAAqB;EAEhD,SAAS,KAAK;GAEZ,UAAU,wCADO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,IACL,GAAI;EACjE;CACF;CAEA,MAAM,oBAAoB;EACxB,IAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,IAC9B;EAGF,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,MAAM,QAAQ,KAAK,cACjB,0CACF;EACA,IAAI,CAAC,OACH;EAGF,MAAM,MAAM,MAAM,MAAM,KAAK;EAE7B,IAAI;GACF,MAAM,iBAAiB,KAAK,cAAc,KAAK,IAAI,OAAO,WAAW;GACrE,IACE,KAAK,aAAa,qBAClB,OAAO,KAAK,aAAa,yBAAyB,YAElD,AAAK,KAAK,aAAa,qBAAqB;GAE9C,YAAY,yBAAyB,GAAI;EAC3C,SAAS,KAAK;GAEZ,UAAU,oCADO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,IACT,GAAI;EAC7D;CACF;AACF;AAEA,IAAI,CAAC,eAAe,IAAI,WAAW,GACjC,eAAe,OAAO,aAAa,oBAAoB"}
@@ -4,7 +4,7 @@ import { r as CONFIG_KEYS } from "./config-CPHDmyTx.js";
4
4
  import { i as decodePathSegment } from "./app-routes-BAEMLu9g.js";
5
5
  import { t as getConfig } from "./getConfig-B7JdRqIY.js";
6
6
  import { t as fileViewerStore } from "./file-viewer-D8zbtvkU.js";
7
- import { t as orchestratorStore } from "./orchestrator-BEUug1TW.js";
7
+ import { t as orchestratorStore } from "./orchestrator-DZkhJj7f.js";
8
8
  import { r as escapeHtml, v as setSanitizedHtml } from "./utils-JdK2r116.js";
9
9
  import { a as showSuccess, i as showInfo, r as showError } from "./toast-DZ6r7_YI.js";
10
10
  import { t as effect } from "./effect-DL6j9HJp.js";
@@ -1842,4 +1842,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
1842
1842
 
1843
1843
  //#endregion
1844
1844
  export { ShadowClawTasks as t };
1845
- //# sourceMappingURL=shadow-claw-tasks-Bxq-niuM.js.map
1845
+ //# sourceMappingURL=shadow-claw-tasks-B2fMF4qE.js.map