shadow-claw 1.23.3 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -5
- package/bin/assert-version-bump.mjs +60 -38
- package/bin/assert-version-bump.test.mjs +74 -11
- package/bin/cli.mjs +166 -0
- package/bin/cli.test.mjs +60 -0
- package/bin/commands/backup.mjs +70 -0
- package/bin/commands/clients.mjs +41 -0
- package/bin/commands/peer-id.mjs +76 -0
- package/bin/commands/peer-id.test.mjs +104 -0
- package/bin/commands/send.mjs +51 -0
- package/bin/commands/tasks.mjs +59 -0
- package/bin/commands/webrtc-listen.mjs +254 -0
- package/bin/prerender-dsd-shell/prerender-dsd-shell.test.mjs +46 -0
- package/bin/rolldown.config.test.mjs +401 -8
- package/bin/utils/control-client.mjs +243 -0
- package/bin/utils/control-client.test.mjs +83 -0
- package/bin/utils/ulid.mjs +45 -0
- package/bin/utils/webrtc-control-client.mjs +699 -0
- package/bin/utils/webrtc-control-client.test.mjs +318 -0
- package/dist/electron/main.cjs +1 -1
- package/dist/public/AGENTS.md +5 -3
- package/dist/public/README.md +42 -5
- package/dist/public/agent.worker.js +6 -6
- package/dist/public/{app-routes-B0ePT49v.js → app-routes-Bs-riIvr.js} +1 -1
- package/dist/public/backup-controller-C_s9in2t.js +1 -0
- package/dist/public/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.css +1 -0
- package/dist/public/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.html +1 -0
- package/dist/public/components/settings/shadow-claw-storage/shadow-claw-storage.html +1 -1
- package/dist/public/components/settings/shadow-claw-task-server/shadow-claw-task-server.css +1 -1
- package/dist/public/components/settings/shadow-claw-task-server/shadow-claw-task-server.html +1 -1
- package/dist/public/components/shadow-claw-files/shadow-claw-files.css +1 -1
- package/dist/public/components/shadow-claw-files/shadow-claw-files.html +1 -1
- package/dist/public/components/shadow-claw-settings/shadow-claw-settings.html +1 -1
- package/dist/public/config-CrHchneq.js +1 -0
- package/dist/public/{configurePeerJs-B7kNU8AQ.js → configurePeerJs-CxpZeDJJ.js} +1 -1
- package/dist/public/{connections-xd_66YVU.js → connections-DvbgdkaB.js} +1 -1
- package/dist/public/{custom-element-security-CZ92anB8.js → custom-element-security-NCqQ5lmC.js} +1 -1
- package/dist/public/docs/README.md +3 -1
- package/dist/public/docs/architecture/overview.md +12 -12
- package/dist/public/docs/architecture/storage.md +5 -2
- package/dist/public/docs/decisions/bundled-typescript-architecture.md +1 -1
- package/dist/public/docs/decisions/indexeddb-and-opfs-storage.md +6 -3
- package/dist/public/docs/decisions/native-web-components-and-signals.md +1 -1
- package/dist/public/docs/example/article/index.html +2 -2
- package/dist/public/docs/guides/configuring-messaging-channels.md +41 -6
- package/dist/public/docs/guides/server-development-configuration.md +24 -0
- package/dist/public/docs/publishing/index.html +19 -76
- package/dist/public/docs/skill-creator/index.html +2 -2
- package/dist/public/docs/subsystems/backup.md +56 -0
- package/dist/public/docs/subsystems/cli.md +124 -0
- package/dist/public/docs/subsystems/control-plane.md +158 -0
- package/dist/public/docs/subsystems/notifications.md +54 -2
- package/dist/public/docs/subsystems/reactive-ui.md +1 -0
- package/dist/public/downloadGroupFile-By0GR6eV.js +1 -0
- package/dist/public/e2e/README.md +5 -1
- package/dist/public/{e2e-bridge-DkS5xFGX.js → e2e-bridge-IGWsRl4i.js} +1 -1
- package/dist/public/file-viewer-D0eflgt6.js +1 -0
- package/dist/public/files/main/~/docs/publishing-to-github-pages.md +17 -82
- package/dist/public/getAllTasks-vpBlgGsc.js +1 -0
- package/dist/public/getGroupDir-P1h9wl6S.js +1 -0
- package/dist/public/{git-BkjrsRXX.js → git-7Vq_SJSp.js} +2 -2
- package/dist/public/{iframe-sanitizer-L6Jyu__Z.js → iframe-sanitizer-y2Z1pPwY.js} +1 -1
- package/dist/public/index.html +2 -2
- package/dist/public/index.js +1 -1
- package/dist/public/{initChatSplitResize-BslPXAXS.js → initChatSplitResize-CzV2E7Ul.js} +1 -1
- package/dist/public/initControlPlane-C9jpnWev.js +1 -0
- package/dist/public/llms.txt +1 -1
- package/dist/public/main/index.html +2 -2
- package/dist/public/main/memory/index.html +2 -2
- package/dist/public/{markdown-6MBrIo-S.js → markdown-BnpKxSxl.js} +1 -1
- package/dist/public/mcp-reconnect-9emsqGRe.js +1 -0
- package/dist/public/{memoryStorage-CjGseKI1.js → memoryStorage-C0KvLNUp.js} +1 -1
- package/dist/public/{orchestrator-B9KmIj8Q.js → orchestrator-3h9xxHUm.js} +676 -676
- package/dist/public/orchestrator-nJj59RqD.js +15 -0
- package/dist/public/pages/main/~/docs/publishing-to-github-pages.md +17 -82
- package/dist/public/{peerjs-Dv8JNm7v.js → peerjs-BP4laMXj.js} +1 -1
- package/dist/public/{push-client-Dqq06wbB.js → push-client-CrjEXK3U.js} +1 -1
- package/dist/public/service-worker/fetch-proxy.js +1 -1
- package/dist/public/service-worker/push-handler.js +1 -1
- package/dist/public/service-worker.js +1 -1
- package/dist/public/{shadow-claw-Bd1rfuVC.js → shadow-claw-CbwETBWf.js} +2 -2
- package/dist/public/{shadow-claw-accounts-DL2l3oM0.js → shadow-claw-accounts-B4sBTQEj.js} +3 -3
- package/dist/public/{shadow-claw-channels-BGXDsQ38.js → shadow-claw-channels-BDWG5Qa3.js} +1 -1
- package/dist/public/{shadow-claw-chat-NXg6zz_l.js → shadow-claw-chat-Crv0DTCY.js} +6 -6
- package/dist/public/shadow-claw-control-plane-CX1IGbh9.js +199 -0
- package/dist/public/{shadow-claw-conversations-C8eqGpP9.js → shadow-claw-conversations-_9qAaRXk.js} +1 -1
- package/dist/public/shadow-claw-dialog-BrOwAOdk.js +1 -0
- package/dist/public/shadow-claw-file-viewer-Blf6yGVD.js +577 -0
- package/dist/public/shadow-claw-files-CYySBDCl.js +840 -0
- package/dist/public/{shadow-claw-git-C0ntz7aX.js → shadow-claw-git-v8S0JjuR.js} +3 -3
- package/dist/public/{shadow-claw-integrations-DCXV2r69.js → shadow-claw-integrations-D7ufpwhX.js} +1 -1
- package/dist/public/{shadow-claw-llm-CudgFQsS.js → shadow-claw-llm-GWgoVfhI.js} +2 -2
- package/dist/public/{shadow-claw-mcp-remote-B8RkpX28.js → shadow-claw-mcp-remote-kY4LMFNN.js} +1 -1
- package/dist/public/{shadow-claw-networking-BLiRsrsK.js → shadow-claw-networking-qHbP95z9.js} +1 -1
- package/dist/public/{shadow-claw-notifications-CQhQcjtL.js → shadow-claw-notifications-YyHOK2Fr.js} +1 -1
- package/dist/public/{shadow-claw-page-header-NeRD0tKU.js → shadow-claw-page-header-DMKbkv3s.js} +1 -1
- package/dist/public/{shadow-claw-pages-DCHnFh6r.js → shadow-claw-pages-DFZHhzFZ.js} +3 -3
- package/dist/public/{shadow-claw-settings-VAfjKFQg.js → shadow-claw-settings-DhxrKIfA.js} +10 -3
- package/dist/public/shadow-claw-storage-BFynbP0j.js +219 -0
- package/dist/public/{shadow-claw-task-server-Dk33N_1G.js → shadow-claw-task-server-3BIeb5oZ.js} +25 -4
- package/dist/public/{shadow-claw-tasks-xA1VfmWN.js → shadow-claw-tasks-Caxc9atL.js} +4 -4
- package/dist/public/{shadow-claw-terminal-Du2r0ciq.js → shadow-claw-terminal-Beb5qF-U.js} +1 -1
- package/dist/public/{shadow-claw-tools-CZj4rq7l.js → shadow-claw-tools-BfJx3A9W.js} +2 -2
- package/dist/public/{shadow-claw-webvm-JYUkWICG.js → shadow-claw-webvm-BCS8ykeP.js} +1 -1
- package/dist/public/static-main/~/docs/publishing-to-github-pages.md +17 -82
- package/dist/public/static-main-manifest.json +1 -1
- package/dist/public/{syncWebMcpRegistration-DfpvASnh.js → syncWebMcpRegistration-B_M2fCjH.js} +1 -1
- package/dist/server.js +286 -189
- package/package.json +2 -1
- package/src/__mocks__/jszip.cjs +15 -5
- package/src/components/settings/shadow-claw-accounts/shadow-claw-accounts.test.ts +35 -0
- package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.css +117 -0
- package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.html +81 -0
- package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.test.ts +127 -0
- package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.ts +292 -0
- package/src/components/settings/shadow-claw-git/shadow-claw-git.test.ts +72 -0
- package/src/components/settings/shadow-claw-integrations/connection-test-auth.test.ts +20 -30
- package/src/components/settings/shadow-claw-integrations/shadow-claw-integrations.test.ts +116 -0
- package/src/components/settings/shadow-claw-llm/model-ranking.test.ts +143 -51
- package/src/components/settings/shadow-claw-llm/shadow-claw-llm.test.ts +307 -4
- package/src/components/settings/shadow-claw-llm/shadow-claw-llm.ts +8 -8
- package/src/components/settings/shadow-claw-mcp-remote/shadow-claw-mcp-remote.test.ts +31 -0
- package/src/components/settings/shadow-claw-peerjs/shadow-claw-peerjs.test.ts +186 -0
- package/src/components/settings/shadow-claw-storage/shadow-claw-storage.html +17 -0
- package/src/components/settings/shadow-claw-storage/shadow-claw-storage.test.ts +120 -0
- package/src/components/settings/shadow-claw-storage/shadow-claw-storage.ts +56 -0
- package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.css +23 -2
- package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.html +1 -1
- package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.test.ts +19 -0
- package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.ts +2 -1
- package/src/components/shadow-claw/utils/initChatSplitResize.test.ts +180 -13
- package/src/components/shadow-claw/utils/setupEffects.test.ts +39 -0
- package/src/components/shadow-claw-a2ui/catalog/basic/shared.test.ts +117 -0
- package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.test.ts +1159 -1
- package/src/components/shadow-claw-chat/shadow-claw-chat.test.ts +1523 -19
- package/src/components/shadow-claw-chat/utils/escapeHtml.test.ts +13 -0
- package/src/components/shadow-claw-chat/utils/getPeerChatDisplayStatus.test.ts +20 -0
- package/src/components/shadow-claw-conversations/shadow-claw-conversations.test.ts +494 -0
- package/src/components/shadow-claw-dialog/shadow-claw-dialog.ts +13 -2
- package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.test.ts +378 -0
- package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.ts +11 -9
- package/src/components/shadow-claw-files/shadow-claw-files.css +41 -17
- package/src/components/shadow-claw-files/shadow-claw-files.html +35 -0
- package/src/components/shadow-claw-files/shadow-claw-files.test.ts +627 -1
- package/src/components/shadow-claw-files/shadow-claw-files.ts +170 -6
- package/src/components/shadow-claw-pages/utils/resolveWorkspaceLinkPath.test.ts +31 -0
- package/src/components/shadow-claw-pages/utils/resolveWorkspaceLinkPath.ts +2 -1
- package/src/components/shadow-claw-pages/utils/rewriteWorkspacePreviewHtml.test.ts +15 -0
- package/src/components/shadow-claw-pdf-viewer/utils/installGetOrInsertComputedPolyfill.test.ts +65 -0
- package/src/components/shadow-claw-settings/shadow-claw-settings.html +7 -0
- package/src/components/shadow-claw-settings/shadow-claw-settings.test.ts +221 -0
- package/src/components/shadow-claw-settings/shadow-claw-settings.ts +2 -0
- package/src/components/shadow-claw-tasks/shadow-claw-tasks.test.ts +407 -0
- package/src/components/shadow-claw-terminal/utils/consumeEscapeSequence.test.ts +58 -0
- package/src/components/shadow-claw-tools/shadow-claw-tools.test.ts +80 -0
- package/src/config/config.test.ts +9 -0
- package/src/config/config.ts +15 -0
- package/src/core/app-routes.test.ts +56 -0
- package/src/core/app-routes.ts +8 -1
- package/src/core/backup-controller.test.ts +101 -0
- package/src/core/backup-controller.ts +137 -0
- package/src/core/control-plane-client.test.ts +408 -0
- package/src/core/control-plane-client.ts +425 -0
- package/src/core/orchestrator/orchestrator.ts +4 -0
- package/src/core/orchestrator/utils/compactContext.test.ts +78 -0
- package/src/core/orchestrator/utils/operations/channel.test.ts +254 -9
- package/src/core/orchestrator/utils/operations/provider.test.ts +326 -34
- package/src/core/orchestrator/utils/operations/vm.test.ts +114 -2
- package/src/core/orchestrator/utils/syncProxyConfigToServiceWorker.test.ts +60 -0
- package/src/core/utils/initControlPlane.test.ts +276 -0
- package/src/core/utils/initControlPlane.ts +437 -0
- package/src/core/utils/initializeApp.ts +18 -0
- package/src/db/getSession.test.ts +13 -1
- package/src/db/openDatabase.test.ts +10 -1
- package/src/db/openDatabase.ts +3 -1
- package/src/server/app.test.ts +12 -0
- package/src/server/app.ts +18 -8
- package/src/server/client-registry.test.ts +250 -0
- package/src/server/client-registry.ts +477 -0
- package/src/server/config.ts +15 -0
- package/src/server/control-plane-types.ts +120 -0
- package/src/server/control-plane.test.ts +472 -0
- package/src/server/control-plane.ts +581 -0
- package/src/server/routes/backup.test.ts +263 -0
- package/src/server/routes/backup.ts +262 -0
- package/src/server/routes/integrations-email.test.ts +532 -0
- package/src/server/routes/llamafile.test.ts +172 -48
- package/src/server/routes/mesh-llm.test.ts +192 -0
- package/src/server/routes/ollama.test.ts +49 -0
- package/src/server/server-peer.test.ts +86 -0
- package/src/server/server-peer.ts +330 -0
- package/src/server/server.ts +35 -0
- package/src/server/services/llamafile-manager.test.ts +230 -6
- package/src/server/services/transformers-runtime.test.ts +186 -18
- package/src/server/webrtc.test.ts +21 -0
- package/src/server/webrtc.ts +72 -0
- package/src/service-worker/fetch-proxy.test.ts +64 -1
- package/src/service-worker/push-handler.ts +39 -0
- package/src/shell/vm.test.ts +744 -12
- package/src/storage/ensureMainGroupIndex.test.ts +153 -0
- package/src/storage/getGroupFile.test.ts +66 -0
- package/src/storage/memoryStorage.test.ts +82 -2
- package/src/storage/migrateLegacyOpfs.test.ts +327 -0
- package/src/storage/migrateLegacyOpfs.ts +117 -0
- package/src/storage/writeGroupFileBytes.test.ts +143 -0
- package/src/stores/chat-ui.test.ts +20 -0
- package/src/stores/orchestrator.test.ts +134 -0
- package/src/stores/toast.test.ts +50 -0
- package/src/stores/tools.test.ts +147 -10
- package/src/subsystems/channels/imessage.test.ts +59 -0
- package/src/subsystems/channels/peerjs.test.ts +500 -62
- package/src/subsystems/channels/peerjs.ts +71 -4
- package/src/subsystems/channels/telegram.test.ts +177 -0
- package/src/subsystems/email/catalog.test.ts +1 -0
- package/src/subsystems/email/connections.test.ts +39 -1
- package/src/subsystems/git/credentials.test.ts +160 -825
- package/src/subsystems/git/git.test.ts +463 -0
- package/src/subsystems/notifications/__mocks__/node-sqlite.cjs +12 -1
- package/src/subsystems/notifications/push-routes.test.ts +33 -0
- package/src/subsystems/notifications/push-routes.ts +23 -0
- package/src/subsystems/notifications/push-store.ts +1 -1
- package/src/subsystems/providers/builtin-ai-tasks.test.ts +74 -0
- package/src/subsystems/providers/litert-lm-provider.test.ts +212 -51
- package/src/subsystems/providers/model-registry.test.ts +115 -0
- package/src/subsystems/providers/providers.test.ts +94 -1
- package/src/subsystems/providers/transformers-js-provider.test.ts +279 -0
- package/src/subsystems/providers/utils/createModelCacheFetch.test.ts +2 -2
- package/src/subsystems/providers/utils/downloadModelToCache.test.ts +2 -2
- package/src/subsystems/providers/utils/loadModelStream.test.ts +2 -2
- package/src/subsystems/skills/activateSkill.test.ts +101 -0
- package/src/subsystems/skills/discoverSkills.test.ts +251 -0
- package/src/subsystems/tools/cron.test.ts +64 -0
- package/src/subsystems/tools/declarative.test.ts +255 -89
- package/src/testing/assets/v86.9pfs/libv86.mjs +63 -0
- package/src/testing/assets/v86.ext2/libv86.mjs +3 -0
- package/src/testing/assets_missing_v86/assets/v86.9pfs/libv86.mjs +1 -0
- package/src/testing/jest-setup.ts +328 -40
- package/src/testing/mock-v86.mjs +49 -0
- package/src/ui/a2ui/types.ts +4 -3
- package/src/ui/a2ui/utils/normaliseComponentsToMap.test.ts +102 -0
- package/src/ui/a2ui/utils/resolveChildIds.test.ts +63 -0
- package/src/ui/a2ui/utils/resolveDynamicNumber.test.ts +13 -1
- package/src/worker/tools/bash/utils/waitForVMReady.test.ts +40 -0
- package/src/worker/tools/email/email.test.ts +193 -8
- package/src/worker/tools/email/utils/asEmailAttachmentInputs.test.ts +47 -0
- package/src/worker/tools/git/git.test.ts +214 -3
- package/src/worker/tools/rooms/invite-to-room.test.ts +54 -0
- package/src/worker/tools/rooms/leave-room.test.ts +40 -0
- package/src/worker/tools/rooms/list-room-members.test.ts +75 -0
- package/src/worker/tools/tasks/tasks-utils.test.ts +22 -0
- package/src/worker/tools/ui/ask-user.test.ts +50 -0
- package/src/worker/tools/ui/clear-chat.test.ts +19 -0
- package/src/worker/tools/ui/get-current-time.test.ts +19 -0
- package/src/worker/tools/ui/javascript.test.ts +116 -0
- package/src/worker/tools/ui/list-components.test.ts +10 -0
- package/src/worker/tools/ui/list-tool-profiles.test.ts +42 -0
- package/src/worker/tools/ui/manage-tools.test.ts +34 -0
- package/src/worker/tools/ui/render-component.test.ts +346 -0
- package/src/worker/tools/ui/send-notification.test.ts +40 -0
- package/src/worker/tools/ui/utils/getAllowFullInternetAccess.test.ts +31 -0
- package/src/worker/tools/ui/utils/parseBooleanConfig.test.ts +25 -0
- package/src/worker/tools/workspace/attach-file.test.ts +84 -0
- package/src/worker/tools/workspace/copy-file.test.ts +69 -0
- package/src/worker/tools/workspace/create-directory.test.ts +40 -0
- package/src/worker/tools/workspace/delete-file.test.ts +73 -0
- package/src/worker/tools/workspace/diff-files.test.ts +94 -0
- package/src/worker/tools/workspace/list-files.test.ts +36 -0
- package/src/worker/tools/workspace/move-file.test.ts +66 -0
- package/src/worker/tools/workspace/open-file.test.ts +57 -0
- package/src/worker/tools/workspace/patch-file.test.ts +81 -0
- package/src/worker/tools/workspace/read-file.test.ts +116 -0
- package/src/worker/tools/workspace/send-file.test.ts +82 -0
- package/src/worker/tools/workspace/update-memory.test.ts +29 -0
- package/src/worker/tools/workspace/write-file.test.ts +28 -0
- package/src/worker/utils/rate-limit.test.ts +199 -0
- package/src/worker/utils/tool-state.test.ts +29 -0
- package/src/worker/utils/transformers-js-utils.test.ts +59 -0
- package/dist/public/config-AL77QAx4.js +0 -1
- package/dist/public/downloadGroupFile-BABv_1mJ.js +0 -1
- package/dist/public/file-viewer-CCSABMsE.js +0 -1
- package/dist/public/mcp-reconnect-DoicazQd.js +0 -1
- package/dist/public/orchestrator-4su7iyWj.js +0 -15
- package/dist/public/shadow-claw-dialog-ByyHgxM9.js +0 -1
- package/dist/public/shadow-claw-file-viewer-9Qkwc30T.js +0 -577
- package/dist/public/shadow-claw-files-aDyq6Hv7.js +0 -781
- package/dist/public/shadow-claw-storage-Cf31np81.js +0 -202
|
@@ -1 +1 @@
|
|
|
1
|
-
<template><shadow-claw-page-header icon="⚙️" title="Settings"> <shadow-claw-page-header-action-button slot="actions" data-action="backup-settings" title="Backup settings"> 💾 Backup </shadow-claw-page-header-action-button> <shadow-claw-page-header-action-button slot="actions" data-action="restore-settings" title="Restore settings"> ♻️ Restore </shadow-claw-page-header-action-button> <shadow-claw-page-header-action-button slot="actions" data-action="clear-settings" title="Clear all settings" variant="danger"> 🗑️ Clear </shadow-claw-page-header-action-button> </shadow-claw-page-header><input class="settings__restore-input" type="file" accept=".json,application/json" aria-label="Restore settings from JSON backup" hidden><shadow-claw-dialog dialog-class="settings__confirm-dialog settings__backup-dialog" dialog-aria-label="Backup settings"> <form class="settings__confirm-form" method="dialog"> <h3 class="settings__confirm-title">Backup Settings</h3> <p class="settings__confirm-message"> Create a backup of all saved settings, accounts, integrations, and profiles. </p> <label class="settings__confirm-checkbox-row"> <input type="checkbox" data-setting="include-plaintext-passwords"> <span>Include passwords in plaintext</span> </label> <p class="settings__confirm-note"> Default is off. When disabled, password fields are excluded from the backup. </p> <div class="settings__confirm-actions"> <button type="button" data-action="cancel-backup-settings"> Cancel </button> <button type="button" data-action="confirm-backup-settings"> Backup </button> </div> </form> </shadow-claw-dialog><shadow-claw-dialog dialog-class="settings__confirm-dialog settings__restore-dialog" dialog-aria-label="Restore settings"> <form class="settings__confirm-form" method="dialog"> <h3 class="settings__confirm-title">Restore Settings</h3> <p class="settings__confirm-message"> Restoring will replace all current settings, accounts, integrations, and profiles. </p> <p class="settings__confirm-note" data-info="restore-filename"> No file selected. </p> <div class="settings__confirm-actions"> <button type="button" data-action="cancel-restore-settings"> Cancel </button> <button type="button" data-action="confirm-restore-settings"> Restore </button> </div> </form> </shadow-claw-dialog><shadow-claw-dialog dialog-class="settings__confirm-dialog settings__clear-dialog" dialog-aria-label="Clear settings"> <form class="settings__confirm-form" method="dialog"> <h3 class="settings__confirm-title">Clear Settings</h3> <p class="settings__confirm-message"> This will permanently remove all settings, accounts, integrations, and profiles. </p> <div class="settings__confirm-actions"> <button type="button" data-action="cancel-clear-settings"> Cancel </button> <button type="button" data-action="confirm-clear-settings" class="settings__danger-btn"> Clear </button> </div> </form> </shadow-claw-dialog><div class="settings-page"> <div class="settings-tab-nav" role="tablist" aria-label="Settings groups" aria-orientation="horizontal"> <button class="settings-tab-btn" role="tab" id="settings-tab-ai" data-tab-target="ai" aria-controls="settings-panel-ai"> AI </button> <button class="settings-tab-btn" role="tab" id="settings-tab-environment" data-tab-target="environment" aria-controls="settings-panel-environment"> Environment </button> <button class="settings-tab-btn" role="tab" id="settings-tab-integrations" data-tab-target="integrations" aria-controls="settings-panel-integrations"> Integrations </button> </div> <div class="settings-tab-panels"> <section class="settings-tab-panel" role="tabpanel" id="settings-panel-ai" data-tab-panel="ai" aria-labelledby="settings-tab-ai"> <details class="settings-collapsible"> <summary>🤖 AI</summary> <div class="settings-collapsible-content"> <div class="settings-section"> <h3>👤 Assistant</h3> <div class="form-group"> <label class="form-label">Name</label> <input class="form-input" data-setting="assistant-name-input" placeholder="ShadowClaw" type="text" value="ShadowClaw"> <div class="form-helper"> Used to mention the assistant in chat (@name) </div> </div> <button class="save-btn" data-action="save-assistant-name"> 💾 Save Name </button> </div> <div class="settings-section"> <h3>📝 Activity Log</h3> <div class="form-group"> <div class="form-toggle"> <input data-setting="activity-log-disk-logging-toggle" id="activity-log-disk-logging-toggle" type="checkbox"> <label class="form-label" for="activity-log-disk-logging-toggle"> Log activity details to disk </label> </div> <div class="form-helper"> When enabled, activity log entries are automatically written to a plain text file under .cache/logs in the app data directory. Default: disabled. </div> </div> </div> </div> </details> <details class="settings-collapsible"> <summary>🔑 Model Provider</summary> <div class="settings-collapsible-content"> <shadow-claw-llm></shadow-claw-llm> </div> </details> <details class="settings-collapsible"> <summary>🛠️ Tools</summary> <div class="settings-collapsible-content"> <div class="settings-section"> <div class="form-group"> <div class="form-helper"> Configure which tools are available to the AI, edit the system prompt, and manage custom tools. </div> </div> <button class="save-btn" data-action="show-tools-config"> 🛠️ Configure Tools </button> </div> </div> </details> </section> <section class="settings-tab-panel" role="tabpanel" id="settings-panel-environment" data-tab-panel="environment" aria-labelledby="settings-tab-environment" hidden> <details class="settings-collapsible"> <summary>🌐 Networking</summary> <div class="settings-collapsible-content"> <shadow-claw-networking></shadow-claw-networking> </div> </details> <details class="settings-collapsible"> <summary>🖥️ WebVM</summary> <div class="settings-collapsible-content"> <shadow-claw-webvm></shadow-claw-webvm> </div> </details> <details class="settings-collapsible"> <summary>🗃️ Misc</summary> <div class="settings-collapsible-content"> <div class="settings-section"> <h3>🧭 Navigation</h3> <div class="form-group"> <div class="form-toggle"> <input data-setting="sidebar-hide-pages-toggle" id="sidebar-hide-pages-toggle" type="checkbox"> <label class="form-label" for="sidebar-hide-pages-toggle"> Hide Pages in sidebar </label> </div> <div class="form-helper"> When enabled, the Pages item is hidden from the sidebar. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="sidebar-hide-chat-toggle" id="sidebar-hide-chat-toggle" type="checkbox"> <label class="form-label" for="sidebar-hide-chat-toggle"> Hide Chat in sidebar </label> </div> <div class="form-helper"> When enabled, the Chat item is hidden from the sidebar. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="sidebar-hide-tasks-toggle" id="sidebar-hide-tasks-toggle" type="checkbox"> <label class="form-label" for="sidebar-hide-tasks-toggle"> Hide Tasks in sidebar </label> </div> <div class="form-helper"> When enabled, the Tasks item is hidden from the sidebar. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="sidebar-hide-files-toggle" id="sidebar-hide-files-toggle" type="checkbox"> <label class="form-label" for="sidebar-hide-files-toggle"> Hide Files in sidebar </label> </div> <div class="form-helper"> When enabled, the Files item is hidden from the sidebar. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="chat-split-view-toggle" id="chat-split-view-toggle" type="checkbox"> <label class="form-label" for="chat-split-view-toggle"> Horizontal Chat split view </label> </div> <div class="form-helper"> When enabled, pins the Chat panel at the bottom of the main view alongside other pages. </div> </div> <div class="form-group"> <label class="form-label" for="pages-auto-refresh-input"> Pages Automatic Refresh (seconds, 0-86400) </label> <input class="form-input" data-setting="pages-auto-refresh-input" id="pages-auto-refresh-input" type="number" min="0" max="86400" step="1" placeholder="0"> <div class="form-helper"> Interval in seconds (0 to 86400, e.g. 5 = 5s, 60 = 1 min, 3600 = 1 hr) to automatically refresh the content of the pinned page (billboard style). Set to 0 to disable automatic refresh. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="override-prerender-skeleton-toggle" id="override-prerender-skeleton-toggle" type="checkbox"> <label class="form-label" for="override-prerender-skeleton-toggle"> Override pre-rendered content with workspace skeleton loader </label> </div> <div class="form-helper"> When enabled, pre-rendered static content is hidden on startup and replaced with the workspace skeleton loader until app initialization completes. </div> </div> </div> <div class="settings-section"> <h3>🖼️ DOM</h3> <div class="settings-section"> <h4>📝 Markdown Frontmatter</h4> <div class="form-group"> <div class="form-toggle"> <input data-setting="markdown-frontmatter-pages-toggle" id="markdown-frontmatter-pages-toggle" type="checkbox"> <label class="form-label" for="markdown-frontmatter-pages-toggle"> Render frontmatter in Pages previews </label> </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="markdown-frontmatter-file-viewer-toggle" id="markdown-frontmatter-file-viewer-toggle" type="checkbox"> <label class="form-label" for="markdown-frontmatter-file-viewer-toggle"> Render frontmatter in File Viewer previews </label> </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="markdown-frontmatter-chat-toggle" id="markdown-frontmatter-chat-toggle" type="checkbox"> <label class="form-label" for="markdown-frontmatter-chat-toggle"> Render frontmatter in Chat messages </label> </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="markdown-frontmatter-tasks-toggle" id="markdown-frontmatter-tasks-toggle" type="checkbox"> <label class="form-label" for="markdown-frontmatter-tasks-toggle"> Render frontmatter in Tasks previews </label> </div> </div> </div> <div class="form-group"> <label class="form-label" for="dom-allowed-iframe-hosts"> Allowed Iframe Embed Hosts </label> <textarea class="form-textarea" id="dom-allowed-iframe-hosts" data-setting="dom-allowed-iframe-hosts" rows="5" placeholder="youtube.com youtube-nocookie.com youtu.be xt-ml.github.io kherrick.github.io"></textarea> <div class="form-helper"> Specify hostnames or regex patterns (one per line) allowed for iframe embeds. Default: YouTube and github.io pages. </div> </div> <button class="save-btn" data-action="save-dom-allowed-iframe-hosts"> 💾 Save DOM Settings </button> </div> <shadow-claw-storage></shadow-claw-storage> </div> </details> </section> <section class="settings-tab-panel" role="tabpanel" id="settings-panel-integrations" data-tab-panel="integrations" aria-labelledby="settings-tab-integrations" hidden> <details class="settings-collapsible"> <summary>🔐 Git Credentials</summary> <div class="settings-collapsible-content"> <shadow-claw-git></shadow-claw-git> </div> </details> <details class="settings-collapsible"> <summary>👤 Accounts</summary> <div class="settings-collapsible-content"> <shadow-claw-accounts></shadow-claw-accounts> </div> </details> <details class="settings-collapsible"> <summary>🔌 Remote MCP Connections</summary> <div class="settings-collapsible-content"> <shadow-claw-mcp-remote></shadow-claw-mcp-remote> </div> </details> <details class="settings-collapsible"> <summary>📧 Email</summary> <div class="settings-collapsible-content"> <shadow-claw-integrations></shadow-claw-integrations> </div> </details> <details class="settings-collapsible"> <summary>📅 Server Task Scheduling</summary> <div class="settings-collapsible-content"> <shadow-claw-task-server></shadow-claw-task-server> </div> </details> <details class="settings-collapsible"> <summary>🔔 Notifications</summary> <div class="settings-collapsible-content"> <shadow-claw-notifications></shadow-claw-notifications> </div> </details> <details class="settings-collapsible"> <summary>💬 Messaging Channels</summary> <div class="settings-collapsible-content"> <div class="settings-section"> <div class="form-group"> <div class="form-helper"> Configure Telegram and iMessage bridge integrations in a dedicated channel configuration interface. </div> </div> <button class="save-btn" data-action="show-channels-config"> 💬 Configure Channels </button> </div> </div> </details> </section> </div> <div class="settings-version-text" data-info="deployed-revision"> Deployed revision: unknown </div> </div></template>
|
|
1
|
+
<template><shadow-claw-page-header icon="⚙️" title="Settings"> <shadow-claw-page-header-action-button slot="actions" data-action="backup-settings" title="Backup settings"> 💾 Backup </shadow-claw-page-header-action-button> <shadow-claw-page-header-action-button slot="actions" data-action="restore-settings" title="Restore settings"> ♻️ Restore </shadow-claw-page-header-action-button> <shadow-claw-page-header-action-button slot="actions" data-action="clear-settings" title="Clear all settings" variant="danger"> 🗑️ Clear </shadow-claw-page-header-action-button> </shadow-claw-page-header><input class="settings__restore-input" type="file" accept=".json,application/json" aria-label="Restore settings from JSON backup" hidden><shadow-claw-dialog dialog-class="settings__confirm-dialog settings__backup-dialog" dialog-aria-label="Backup settings"> <form class="settings__confirm-form" method="dialog"> <h3 class="settings__confirm-title">Backup Settings</h3> <p class="settings__confirm-message"> Create a backup of all saved settings, accounts, integrations, and profiles. </p> <label class="settings__confirm-checkbox-row"> <input type="checkbox" data-setting="include-plaintext-passwords"> <span>Include passwords in plaintext</span> </label> <p class="settings__confirm-note"> Default is off. When disabled, password fields are excluded from the backup. </p> <div class="settings__confirm-actions"> <button type="button" data-action="cancel-backup-settings"> Cancel </button> <button type="button" data-action="confirm-backup-settings"> Backup </button> </div> </form> </shadow-claw-dialog><shadow-claw-dialog dialog-class="settings__confirm-dialog settings__restore-dialog" dialog-aria-label="Restore settings"> <form class="settings__confirm-form" method="dialog"> <h3 class="settings__confirm-title">Restore Settings</h3> <p class="settings__confirm-message"> Restoring will replace all current settings, accounts, integrations, and profiles. </p> <p class="settings__confirm-note" data-info="restore-filename"> No file selected. </p> <div class="settings__confirm-actions"> <button type="button" data-action="cancel-restore-settings"> Cancel </button> <button type="button" data-action="confirm-restore-settings"> Restore </button> </div> </form> </shadow-claw-dialog><shadow-claw-dialog dialog-class="settings__confirm-dialog settings__clear-dialog" dialog-aria-label="Clear settings"> <form class="settings__confirm-form" method="dialog"> <h3 class="settings__confirm-title">Clear Settings</h3> <p class="settings__confirm-message"> This will permanently remove all settings, accounts, integrations, and profiles. </p> <div class="settings__confirm-actions"> <button type="button" data-action="cancel-clear-settings"> Cancel </button> <button type="button" data-action="confirm-clear-settings" class="settings__danger-btn"> Clear </button> </div> </form> </shadow-claw-dialog><div class="settings-page"> <div class="settings-tab-nav" role="tablist" aria-label="Settings groups" aria-orientation="horizontal"> <button class="settings-tab-btn" role="tab" id="settings-tab-ai" data-tab-target="ai" aria-controls="settings-panel-ai"> AI </button> <button class="settings-tab-btn" role="tab" id="settings-tab-environment" data-tab-target="environment" aria-controls="settings-panel-environment"> Environment </button> <button class="settings-tab-btn" role="tab" id="settings-tab-integrations" data-tab-target="integrations" aria-controls="settings-panel-integrations"> Integrations </button> </div> <div class="settings-tab-panels"> <section class="settings-tab-panel" role="tabpanel" id="settings-panel-ai" data-tab-panel="ai" aria-labelledby="settings-tab-ai"> <details class="settings-collapsible"> <summary>🤖 AI</summary> <div class="settings-collapsible-content"> <div class="settings-section"> <h3>👤 Assistant</h3> <div class="form-group"> <label class="form-label">Name</label> <input class="form-input" data-setting="assistant-name-input" placeholder="ShadowClaw" type="text" value="ShadowClaw"> <div class="form-helper"> Used to mention the assistant in chat (@name) </div> </div> <button class="save-btn" data-action="save-assistant-name"> 💾 Save Name </button> </div> <div class="settings-section"> <h3>📝 Activity Log</h3> <div class="form-group"> <div class="form-toggle"> <input data-setting="activity-log-disk-logging-toggle" id="activity-log-disk-logging-toggle" type="checkbox"> <label class="form-label" for="activity-log-disk-logging-toggle"> Log activity details to disk </label> </div> <div class="form-helper"> When enabled, activity log entries are automatically written to a plain text file under .cache/logs in the app data directory. Default: disabled. </div> </div> </div> </div> </details> <details class="settings-collapsible"> <summary>🔑 Model Provider</summary> <div class="settings-collapsible-content"> <shadow-claw-llm></shadow-claw-llm> </div> </details> <details class="settings-collapsible"> <summary>🛠️ Tools</summary> <div class="settings-collapsible-content"> <div class="settings-section"> <div class="form-group"> <div class="form-helper"> Configure which tools are available to the AI, edit the system prompt, and manage custom tools. </div> </div> <button class="save-btn" data-action="show-tools-config"> 🛠️ Configure Tools </button> </div> </div> </details> </section> <section class="settings-tab-panel" role="tabpanel" id="settings-panel-environment" data-tab-panel="environment" aria-labelledby="settings-tab-environment" hidden> <details class="settings-collapsible"> <summary>🌐 Networking</summary> <div class="settings-collapsible-content"> <shadow-claw-networking></shadow-claw-networking> </div> </details> <details class="settings-collapsible"> <summary>🖥️ WebVM</summary> <div class="settings-collapsible-content"> <shadow-claw-webvm></shadow-claw-webvm> </div> </details> <details class="settings-collapsible"> <summary>🗃️ Misc</summary> <div class="settings-collapsible-content"> <div class="settings-section"> <h3>🧭 Navigation</h3> <div class="form-group"> <div class="form-toggle"> <input data-setting="sidebar-hide-pages-toggle" id="sidebar-hide-pages-toggle" type="checkbox"> <label class="form-label" for="sidebar-hide-pages-toggle"> Hide Pages in sidebar </label> </div> <div class="form-helper"> When enabled, the Pages item is hidden from the sidebar. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="sidebar-hide-chat-toggle" id="sidebar-hide-chat-toggle" type="checkbox"> <label class="form-label" for="sidebar-hide-chat-toggle"> Hide Chat in sidebar </label> </div> <div class="form-helper"> When enabled, the Chat item is hidden from the sidebar. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="sidebar-hide-tasks-toggle" id="sidebar-hide-tasks-toggle" type="checkbox"> <label class="form-label" for="sidebar-hide-tasks-toggle"> Hide Tasks in sidebar </label> </div> <div class="form-helper"> When enabled, the Tasks item is hidden from the sidebar. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="sidebar-hide-files-toggle" id="sidebar-hide-files-toggle" type="checkbox"> <label class="form-label" for="sidebar-hide-files-toggle"> Hide Files in sidebar </label> </div> <div class="form-helper"> When enabled, the Files item is hidden from the sidebar. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="chat-split-view-toggle" id="chat-split-view-toggle" type="checkbox"> <label class="form-label" for="chat-split-view-toggle"> Horizontal Chat split view </label> </div> <div class="form-helper"> When enabled, pins the Chat panel at the bottom of the main view alongside other pages. </div> </div> <div class="form-group"> <label class="form-label" for="pages-auto-refresh-input"> Pages Automatic Refresh (seconds, 0-86400) </label> <input class="form-input" data-setting="pages-auto-refresh-input" id="pages-auto-refresh-input" type="number" min="0" max="86400" step="1" placeholder="0"> <div class="form-helper"> Interval in seconds (0 to 86400, e.g. 5 = 5s, 60 = 1 min, 3600 = 1 hr) to automatically refresh the content of the pinned page (billboard style). Set to 0 to disable automatic refresh. </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="override-prerender-skeleton-toggle" id="override-prerender-skeleton-toggle" type="checkbox"> <label class="form-label" for="override-prerender-skeleton-toggle"> Override pre-rendered content with workspace skeleton loader </label> </div> <div class="form-helper"> When enabled, pre-rendered static content is hidden on startup and replaced with the workspace skeleton loader until app initialization completes. </div> </div> </div> <div class="settings-section"> <h3>🖼️ DOM</h3> <div class="settings-section"> <h4>📝 Markdown Frontmatter</h4> <div class="form-group"> <div class="form-toggle"> <input data-setting="markdown-frontmatter-pages-toggle" id="markdown-frontmatter-pages-toggle" type="checkbox"> <label class="form-label" for="markdown-frontmatter-pages-toggle"> Render frontmatter in Pages previews </label> </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="markdown-frontmatter-file-viewer-toggle" id="markdown-frontmatter-file-viewer-toggle" type="checkbox"> <label class="form-label" for="markdown-frontmatter-file-viewer-toggle"> Render frontmatter in File Viewer previews </label> </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="markdown-frontmatter-chat-toggle" id="markdown-frontmatter-chat-toggle" type="checkbox"> <label class="form-label" for="markdown-frontmatter-chat-toggle"> Render frontmatter in Chat messages </label> </div> </div> <div class="form-group"> <div class="form-toggle"> <input data-setting="markdown-frontmatter-tasks-toggle" id="markdown-frontmatter-tasks-toggle" type="checkbox"> <label class="form-label" for="markdown-frontmatter-tasks-toggle"> Render frontmatter in Tasks previews </label> </div> </div> </div> <div class="form-group"> <label class="form-label" for="dom-allowed-iframe-hosts"> Allowed Iframe Embed Hosts </label> <textarea class="form-textarea" id="dom-allowed-iframe-hosts" data-setting="dom-allowed-iframe-hosts" rows="5" placeholder="youtube.com youtube-nocookie.com youtu.be xt-ml.github.io kherrick.github.io"></textarea> <div class="form-helper"> Specify hostnames or regex patterns (one per line) allowed for iframe embeds. Default: YouTube and github.io pages. </div> </div> <button class="save-btn" data-action="save-dom-allowed-iframe-hosts"> 💾 Save DOM Settings </button> </div> <shadow-claw-storage></shadow-claw-storage> </div> </details> </section> <section class="settings-tab-panel" role="tabpanel" id="settings-panel-integrations" data-tab-panel="integrations" aria-labelledby="settings-tab-integrations" hidden> <details class="settings-collapsible"> <summary>🔐 Git Credentials</summary> <div class="settings-collapsible-content"> <shadow-claw-git></shadow-claw-git> </div> </details> <details class="settings-collapsible"> <summary>👤 Accounts</summary> <div class="settings-collapsible-content"> <shadow-claw-accounts></shadow-claw-accounts> </div> </details> <details class="settings-collapsible"> <summary>🔌 Remote MCP Connections</summary> <div class="settings-collapsible-content"> <shadow-claw-mcp-remote></shadow-claw-mcp-remote> </div> </details> <details class="settings-collapsible"> <summary>🎛️ Control Plane</summary> <div class="settings-collapsible-content"> <shadow-claw-control-plane></shadow-claw-control-plane> </div> </details> <details class="settings-collapsible"> <summary>📧 Email</summary> <div class="settings-collapsible-content"> <shadow-claw-integrations></shadow-claw-integrations> </div> </details> <details class="settings-collapsible"> <summary>📅 Server Task Scheduling</summary> <div class="settings-collapsible-content"> <shadow-claw-task-server></shadow-claw-task-server> </div> </details> <details class="settings-collapsible"> <summary>🔔 Notifications</summary> <div class="settings-collapsible-content"> <shadow-claw-notifications></shadow-claw-notifications> </div> </details> <details class="settings-collapsible"> <summary>💬 Messaging Channels</summary> <div class="settings-collapsible-content"> <div class="settings-section"> <div class="form-group"> <div class="form-helper"> Configure Telegram and iMessage bridge integrations in a dedicated channel configuration interface. </div> </div> <button class="save-btn" data-action="show-channels-config"> 💬 Configure Channels </button> </div> </div> </details> </section> </div> <div class="settings-version-text" data-info="deployed-revision"> Deployed revision: unknown </div> </div></template>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-aKtaBQYM.js";import{i as t}from"./app-routes-Bs-riIvr.js";const n=new class{loading=!1;models=new Map;getModelInfo(e){return this.models.get(e.toLowerCase())??null}registerModelInfo(e,t){this.models.set(e.toLowerCase(),t)}clear(){this.models.clear()}async fetchModelInfo(e,t,n){if(e.modelsUrl){this.loading=!0;try{let r=new Headers;if(r.set(`Content-Type`,`application/json`),e.headers)for(let[t,n]of Object.entries(e.headers))r.set(t,n);if(n)for(let[e,t]of Object.entries(n))r.set(e,t);if(t&&e.apiKeyHeader){let n=e.apiKeyHeaderFormat;r.set(e.apiKeyHeader,n?n.replace(`{key}`,t):t)}let i=await fetch(e.modelsUrl,{headers:r});if(!i.ok)throw Error(`HTTP ${i.status} ${i.statusText}`);let a=await i.json(),o=Array.isArray(a.data)?a.data:Array.isArray(a.models)?a.models:[];for(let e of o){if(!e.id)continue;let t=e.context_length??e.context_window??0,n=e.max_completion_tokens||e.per_request_limits?.completion_tokens||e.top_provider?.max_completion_tokens||null,r=typeof e.supports_tools==`boolean`?e.supports_tools:typeof e.supportsTools==`boolean`?e.supportsTools:void 0,i=this.extractModalities(e,`input`),a=this.extractModalities(e,`output`),o=this.modalitiesInclude(i,`image`,`vision`),s=this.modalitiesInclude(i,`audio`,`voice`,`hearing`),c=this.modalitiesInclude(i,`video`),l=e.id===`openrouter/free`||this.supportedParametersInclude(e,`image`,`vision`,`audio`,`tool`,`structured`),u=this.extractReasoning(e);!t&&Array.isArray(e.providers)&&e.providers.length>0&&(t=e.providers[0]?.context_length||0),this.registerModelInfo(e.id,{contextWindow:t,maxOutput:n,...r!==void 0&&{supportsTools:r},...i.length>0&&{inputModalities:i},...a.length>0&&{outputModalities:a},...o!==void 0&&{supportsImageInput:o},...s!==void 0&&{supportsAudioInput:s},...c!==void 0&&{supportsVideoInput:c},...u&&{reasoning:u},...l&&{routesByRequestFeatures:l}})}o.length>0&&console.log(`[ModelRegistry] Registered ${o.length} models for provider "${e.id}"`)}catch(t){console.error(`[ModelRegistry] Error fetching models for ${e.id}:`,t)}finally{this.loading=!1}}}extractModalities(e,t){let n=t===`input`?e.input_modalities||e.inputModalities:e.output_modalities||e.outputModalities,r=e.architecture||{},i=t===`input`?r.input_modalities||r.inputModalities:r.output_modalities||r.outputModalities,a=typeof r.modality==`string`?r.modality:``,o=this.parseArchitectureModality(a,t),s=[...this.normalizeStringArray(n),...this.normalizeStringArray(i),...o];return Array.from(new Set(s))}extractReasoning(e){let t=e?.reasoning;if(!t||typeof t!=`object`)return;let n=this.normalizeStringArray(t.supported_efforts),r=typeof t.default_effort==`string`?t.default_effort.toLowerCase():void 0,i=typeof t.default_enabled==`boolean`?t.default_enabled:void 0,a=typeof t.supports_max_tokens==`boolean`?t.supports_max_tokens:void 0,o=typeof t.mandatory==`boolean`?t.mandatory:void 0;if(!(n.length===0&&r===void 0&&i===void 0&&a===void 0&&o===void 0))return{...n.length>0&&{supportedEfforts:n},...r!==void 0&&{defaultEffort:r},...i!==void 0&&{defaultEnabled:i},...a!==void 0&&{supportsMaxTokens:a},...o!==void 0&&{mandatory:o}}}modalitiesInclude(e,...t){if(e.length!==0)return t.some(t=>e.some(e=>e.includes(t)))}normalizeStringArray(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`).map(e=>e.toLowerCase()):[]}parseArchitectureModality(e,t){if(!e)return[];let[n=``,r=``]=e.toLowerCase().split(`->`).map(e=>e.trim());return(t===`input`?n:r).split(/[+,/\s]+/).map(e=>e.trim()).filter(Boolean)}supportedParametersInclude(e,...t){let n=this.normalizeStringArray(e.supported_parameters||e.supportedParameters);return t.some(e=>n.some(t=>t.includes(e)))}};var r=e({ASSISTANT_NAME:()=>i,BASH_DEFAULT_TIMEOUT_SEC:()=>900,BASH_MAX_TIMEOUT_SEC:()=>f,BEDROCK_PROXY_MODELS_URL:()=>E,BEDROCK_PROXY_URL:()=>T,CONFIG_KEYS:()=>H,CONTEXT_WINDOW_SIZE:()=>50,DB_VERSION:()=>2,DEFAULT_CONTROL_PLANE_ENABLED:()=>!1,DEFAULT_CONTROL_PLANE_TRANSPORT:()=>`sse`,DEFAULT_DEV_HOST:()=>U,DEFAULT_DEV_IP:()=>DEFAULT_DEV_IP,DEFAULT_DEV_PORT:()=>W,DEFAULT_FILES_UPLOAD_APPEND_ULID:()=>!1,DEFAULT_GROUP_ID:()=>y,DEFAULT_MAX_ITERATIONS:()=>50,DEFAULT_MAX_TOKENS:()=>o,DEFAULT_PROMPT_API_BACKEND:()=>DEFAULT_PROMPT_API_BACKEND,DEFAULT_PROMPT_API_DTYPE_STRATEGY:()=>DEFAULT_PROMPT_API_DTYPE_STRATEGY,DEFAULT_PROMPT_API_FALLBACK_MODEL:()=>K,DEFAULT_PROVIDER:()=>l,DEFAULT_SUBAGENT_MAX_PARALLEL:()=>5,DEFAULT_SUBAGENT_WORKSPACE_MODE:()=>G,DEFAULT_TASK_SERVER_ENABLED:()=>!1,DEFAULT_TASK_SERVER_URL:()=>q,DEFAULT_TRANSFORMERS_JS_BACKEND:()=>DEFAULT_TRANSFORMERS_JS_BACKEND,DEFAULT_TRANSFORMERS_JS_DTYPE_STRATEGY:()=>DEFAULT_TRANSFORMERS_JS_DTYPE_STRATEGY,DEFAULT_TRANSFORMERS_JS_MODEL:()=>DEFAULT_TRANSFORMERS_JS_MODEL,DEFAULT_VM_BOOT_HOST:()=>m,DEFAULT_VM_NETWORK_RELAY_URL:()=>p,FETCH_MAX_RESPONSE:()=>d,GENERAL_ACCOUNT_PROVIDER_CAPABILITIES:()=>N,IMESSAGE_POLL_TIMEOUT:()=>25,IMESSAGE_REQUEST_TIMEOUT_MS:()=>C,LEGACY_DB_NAME:()=>h,LEGACY_OPFS_ROOT:()=>_,LLAMAFILE_PROXY_MODELS_URL:()=>A,LLAMAFILE_PROXY_URL:()=>k,MODEL_OUTPUT_LIMITS:()=>s,OAUTH_PROVIDER_DEFINITIONS:()=>P,OLLAMA_PROXY_MODELS_URL:()=>M,OLLAMA_PROXY_URL:()=>j,OPFS_ROOT:()=>v,PEERJS_DEFAULT_HOST:()=>w,PEERJS_DEFAULT_PATH:()=>`/`,PEERJS_DEFAULT_PORT:()=>443,PEERJS_DEFAULT_SECURE:()=>!0,PROCESS_LOOP_INTERVAL:()=>100,PROVIDERS:()=>F,SCHEDULER_INTERVAL:()=>u,TELEGRAM_API_BASE:()=>b,TELEGRAM_MAX_LENGTH:()=>S,TELEGRAM_POLL_TIMEOUT:()=>30,TELEGRAM_PROXY_BASE:()=>x,TRANSFORMERS_JS_PROXY_MODELS_URL:()=>O,TRANSFORMERS_JS_PROXY_URL:()=>D,buildTriggerPattern:()=>a,getAvailableProviders:()=>R,getDbName:()=>g,getDefaultProvider:()=>L,getGeneralAccountProviderCapabilities:()=>B,getModelMaxTokens:()=>c,getProvider:()=>I,getProviderApiKeyConfigKey:()=>z,getProviderTokenAuthScheme:()=>V});const i=`ShadowClaw`;function a(e){let t=e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);return RegExp(`(^|\\s)@${t}\\b`,`i`)}a(i);const o=8192,s=[{pattern:`claude-fable-5`,maxTokens:128e3},{pattern:`claude-sonnet-5`,maxTokens:128e3},{pattern:`claude-opus-5`,maxTokens:128e3},{pattern:`claude-opus-4-8`,maxTokens:128e3},{pattern:`claude-opus-4`,maxTokens:128e3},{pattern:`claude-sonnet-4`,maxTokens:64e3},{pattern:`claude-haiku-4`,maxTokens:64e3},{pattern:`claude-3-5`,maxTokens:8192},{pattern:`claude-3`,maxTokens:4096},{pattern:`gpt-5`,maxTokens:128e3},{pattern:`gpt-4o`,maxTokens:16384},{pattern:`gpt-4.1`,maxTokens:32768},{pattern:`gpt-4-turbo`,maxTokens:4096},{pattern:`gpt-4`,maxTokens:8192},{pattern:`gpt-3.5`,maxTokens:4096},{pattern:`qwen-2.5`,maxTokens:32768},{pattern:`Qwen3.5`,maxTokens:32768},{pattern:`qwen3.5`,maxTokens:32768},{pattern:`Qwen3`,maxTokens:32768},{pattern:`qwen3`,maxTokens:32768},{pattern:`gemma-4`,maxTokens:16384},{pattern:`gemini-nano`,maxTokens:4096},{pattern:`phi-mini`,maxTokens:9216},{pattern:`aion`,maxTokens:9216},{pattern:`gemma-3-1b-it-ONNX-GQA`,maxTokens:32768},{pattern:`gemma-3-1b-it-ONNX`,maxTokens:32768},{pattern:`gemma-3`,maxTokens:32768},{pattern:`Qwen3-0.6B-ONNX`,maxTokens:32768},{pattern:`Qwen3.5`,maxTokens:32768},{pattern:`Llama-3.2`,maxTokens:32768},{pattern:`SmolLM`,maxTokens:8192},{pattern:`DeepSeek-R1`,maxTokens:32768},{pattern:`Phi-4`,maxTokens:16384},{pattern:`Phi-3.5`,maxTokens:16384},{pattern:`LFM2`,maxTokens:16384},{pattern:`gpt-oss`,maxTokens:32768},{pattern:`browser-built-in`,maxTokens:4096},{pattern:`mesh`,maxTokens:32768},{pattern:`openrouter/free`,maxTokens:32768},{pattern:`qwen3:8b`,maxTokens:4096},{pattern:`llama3:8b`,maxTokens:8192}];function c(e){if(!e)return o;let t=n.getModelInfo(e);if(t){if(typeof t.maxOutput==`number`){let e=t.contextWindow?Math.max(8192,Math.floor(t.contextWindow/2)):32768;return Math.min(t.maxOutput,e)}if(t.contextWindow){let e;return e=t.contextWindow>=2e5?131072:t.contextWindow>=1e5?65536:32768,Math.min(e,Math.floor(t.contextWindow/2))}}for(let{pattern:t,maxTokens:n}of s)if(e.includes(t))return n;return o}const l=`prompt_api`,u=6e4,d=102400,f=1800,p=`wss://relay.widgetry.org/`,m=`http://localhost:8888`,h=`shadowclaw`;function g(){let e=t();return e?`shadowclaw-${e}`:h}g();const _=`shadowclaw`,v=`shadowclaw`,y=`br:main`,b=`https://api.telegram.org/bot`,x=`/telegram/bot`,S=4096,C=15e3,w=`0.peerjs.com`,T=`http://localhost:8888/bedrock-proxy/invoke`,E=`http://localhost:8888/bedrock-proxy/models`,D=`http://localhost:8888/transformers-js-proxy/chat/completions`,O=`http://localhost:8888/transformers-js-proxy/models`,k=`http://localhost:8888/llamafile-proxy/chat/completions`,A=`http://localhost:8888/llamafile-proxy/models`,j=`http://localhost:8888/ollama-proxy/chat/completions`,M=`http://localhost:8888/ollama-proxy/models`,N={github:{providerId:`github`,name:`GitHub`,aliases:[`github`,`api.github.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`token `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://github.com/login/oauth/authorize`,tokenUrl:`https://github.com/login/oauth/access_token`,defaultScopes:[`repo`,`read:user`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},gitlab:{providerId:`gitlab`,name:`GitLab`,aliases:[`gitlab`,`gitlab.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`PRIVATE-TOKEN`,headerPrefix:``},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},tokenAuthByServiceType:{git_remote:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}}},oauth:{authorizeUrl:`https://gitlab.com/oauth/authorize`,tokenUrl:`https://gitlab.com/oauth/token`,defaultScopes:[`read_api`,`read_user`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},figma:{providerId:`figma`,name:`Figma`,aliases:[`figma`,`api.figma.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`X-Figma-Token`,headerPrefix:``},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://www.figma.com/oauth`,tokenUrl:`https://api.figma.com/v1/oauth/token`,refreshUrl:`https://api.figma.com/v1/oauth/refresh`,defaultScopes:[],usePkce:!0,clientAuthMethod:`basic_header`,scopeSeparator:`space`}},notion:{providerId:`notion`,name:`Notion`,aliases:[`notion`,`api.notion.com`,`notion.so`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://api.notion.com/v1/oauth/authorize`,tokenUrl:`https://api.notion.com/v1/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`basic_header`,scopeSeparator:`space`}},microsoft_graph:{providerId:`microsoft_graph`,name:`Microsoft Graph`,aliases:[`microsoft`,`graph.microsoft.com`,`microsoft_graph`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://login.microsoftonline.com/common/oauth2/v2.0/authorize`,tokenUrl:`https://login.microsoftonline.com/common/oauth2/v2.0/token`,defaultScopes:[`openid`,`profile`,`offline_access`,`User.Read`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},yahoo_mail:{providerId:`yahoo_mail`,name:`Yahoo Mail`,aliases:[`yahoo`,`yahoo_mail`,`mail.yahoo.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://api.login.yahoo.com/oauth2/request_auth`,tokenUrl:`https://api.login.yahoo.com/oauth2/get_token`,defaultScopes:[`mail-r`,`mail-w`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},google:{providerId:`google`,name:`Google`,aliases:[`google`,`googleapis.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://accounts.google.com/o/oauth2/v2/auth`,tokenUrl:`https://oauth2.googleapis.com/token`,defaultScopes:[`openid`,`profile`,`email`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},atlassian:{providerId:`atlassian`,name:`Atlassian`,aliases:[`atlassian`,`api.atlassian.com`],modes:[`oauth`,`token`,`basic`],defaultMode:`basic`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`,`basic_userpass`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `},basic:{headerName:`Authorization`,headerPrefix:`Basic `}},oauth:{authorizeUrl:`https://auth.atlassian.com/authorize`,tokenUrl:`https://auth.atlassian.com/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},slack:{providerId:`slack`,name:`Slack`,aliases:[`slack`,`slack.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://slack.com/oauth/v2/authorize`,tokenUrl:`https://slack.com/api/oauth.v2.access`,defaultScopes:[],usePkce:!1,clientAuthMethod:`request_body`,scopeSeparator:`comma`}},linear:{providerId:`linear`,name:`Linear`,aliases:[`linear`,`api.linear.app`,`linear.app`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://linear.app/oauth/authorize`,tokenUrl:`https://api.linear.app/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},azure_devops:{providerId:`azure_devops`,name:`Azure DevOps`,aliases:[`azure_devops`,`dev.azure.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`,`basic_userpass`,`ssh_key`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},tokenAuthByServiceType:{git_remote:{token:{headerName:`Authorization`,headerPrefix:`Basic `},oauth:{headerName:`Authorization`,headerPrefix:`Basic `}}},oauth:{authorizeUrl:`https://app.vssps.visualstudio.com/oauth2/authorize`,tokenUrl:`https://app.vssps.visualstudio.com/oauth2/token`,defaultScopes:[`vso.code`,`vso.profile`,`offline_access`],usePkce:!1,clientAuthMethod:`request_body`,scopeSeparator:`space`}},custom_mcp:{providerId:`custom_mcp`,name:`Custom MCP`,aliases:[`custom_mcp`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`mcp_remote`,`webmcp_local`],authTypes:[`none`,`token`,`oauth`,`custom_header`,`ssh_key`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://example.com/oauth/authorize`,tokenUrl:`https://example.com/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}}},P=Object.fromEntries(Object.values(N).filter(e=>!!e.oauth).map(e=>{let t=e.oauth;return[e.providerId,{id:e.providerId,name:e.name,authorizeUrl:t.authorizeUrl,tokenUrl:t.tokenUrl,redirectUri:t.redirectUri,defaultScopes:t.defaultScopes,usePkce:t.usePkce,clientAuthMethod:t.clientAuthMethod,scopeSeparator:t.scopeSeparator}]}));Object.fromEntries(Object.values(N).map(e=>[e.providerId,{providerId:e.providerId,modes:e.modes,defaultMode:e.defaultMode}]));const F={openrouter:{id:`openrouter`,name:`OpenRouter`,baseUrl:`https://openrouter.ai/api/v1/chat/completions`,format:`openai`,apiKeyHeader:`Authorization`,apiKeyHeaderFormat:`Bearer {key}`,headers:{"HTTP-Referer":`https://xt-ml.github.io/shadow-claw/`,"X-OpenRouter-Title":`ShadowClaw`},defaultModel:`openrouter/free`,modelsUrl:`https://openrouter.ai/api/v1/models`,requiresApiKey:!0,supportsStreaming:!0,reasoningParam:`reasoning`},huggingface:{id:`huggingface`,name:`HuggingFace`,baseUrl:`https://router.huggingface.co/v1/chat/completions`,format:`openai`,apiKeyHeader:`Authorization`,apiKeyHeaderFormat:`Bearer {key}`,headers:{},defaultModel:`meta-llama/Llama-3.1-8B-Instruct`,modelsUrl:`https://router.huggingface.co/v1/models`,requiresApiKey:!0,supportsStreaming:!0},bedrock_proxy:{id:`bedrock_proxy`,name:`AWS Bedrock (Local Proxy)`,baseUrl:T,format:`anthropic`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`anthropic.claude-sonnet-4-6-v1:0`,modelsUrl:E,requiresApiKey:!1,supportsStreaming:!0,reasoningParam:`thinking`},gemini_proxy:{id:`gemini_proxy`,name:`Gemini (Local Proxy)`,baseUrl:`http://localhost:8888/gemini-proxy/chat/completions`,format:`openai`,apiKeyHeader:`x-goog-api-key`,headers:{},defaultModel:`gemini-2.0-flash`,modelsUrl:`http://localhost:8888/gemini-proxy/models`,requiresApiKey:!0,supportsStreaming:!0,reasoningParam:`thinkingConfig`},vertex_ai:{id:`vertex_ai`,name:`Vertex AI (Local Proxy)`,baseUrl:`http://localhost:8888/vertex-ai-proxy/chat/completions`,format:`openai`,apiKeyHeader:`x-vertex-project`,headers:{},defaultModel:`gemini-2.5-flash`,modelsUrl:`http://localhost:8888/vertex-ai-proxy/models`,requiresApiKey:!0,supportsStreaming:!0,reasoningParam:`thinkingConfig`},"mesh-llm":{id:`mesh-llm`,name:`Mesh LLM (Local Proxy)`,baseUrl:`http://localhost:8888/mesh-llm-proxy/chat/completions`,format:`mesh-llm`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`mesh`,modelsUrl:`http://localhost:8888/mesh-llm-proxy/models`,requiresApiKey:!1,supportsStreaming:!0},ollama:{id:`ollama`,name:`Ollama (Local Proxy)`,baseUrl:j,format:`openai`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`qwen3:8b`,modelsUrl:M,requiresApiKey:!1,supportsStreaming:!0},llamafile:{id:`llamafile`,name:`Llamafile (Local Proxy)`,baseUrl:k,format:`openai`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`Qwen3.5-9B-Q5_K_S`,modelsUrl:A,requiresApiKey:!1,supportsStreaming:!0},transformers_js_local:{id:`transformers_js_local`,name:`Transformers.js (Local Proxy)`,baseUrl:D,format:`openai`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`onnx-community/Qwen3-0.6B-ONNX`,modelsUrl:O,models:[`onnx-community/DeepSeek-R1-Distill-Qwen-1.5B-ONNX`,`onnx-community/gemma-3-1b-it-ONNX-GQA`,`onnx-community/gemma-3-1b-it-ONNX`,`onnx-community/gemma-4-E2B-it-ONNX`,`onnx-community/gemma-4-E2B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-E4B-it-ONNX`,`onnx-community/gemma-4-E4B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-E9B-it-ONNX`,`onnx-community/gemma-4-12B-it-ONNX`,`onnx-community/gemma-4-12B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-E27B-it-ONNX`,`onnx-community/gpt-oss-20b-ONNX`,`onnx-community/LFM2-1.2B-ONNX`,`onnx-community/Llama-3.2-1B-Instruct-ONNX`,`onnx-community/Llama-3.2-3B-Instruct-ONNX`,`onnx-community/Phi-3.5-mini-instruct-onnx-web`,`onnx-community/Phi-4-mini-instruct-ONNX`,`onnx-community/Qwen3-0.6B-ONNX`,`onnx-community/Qwen3.5-0.8B-ONNX-OPT`,`onnx-community/Qwen3.5-4B-ONNX-OPT`,`HuggingFaceTB/SmolLM3-3B-ONNX`,`LiquidAI/LFM2.5-1.2B-Thinking-ONNX`,`webgpu/Qwen3-4B-ONNX`],requiresApiKey:!1,supportsStreaming:!0},transformers_js_browser:{id:`transformers_js_browser`,name:`Transformers.js (Browser)`,baseUrl:`local://transformers-js`,format:`transformers_js`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`onnx-community/Qwen3-0.6B-ONNX`,modelsUrl:`https://huggingface.co/api/models?author=onnx-community`,models:[`onnx-community/Qwen3-0.6B-ONNX`,`onnx-community/gemma-3-1b-it-ONNX`,`onnx-community/gemma-3-1b-it-ONNX-GQA`,`onnx-community/gemma-4-E2B-it-ONNX`,`onnx-community/gemma-4-E4B-it-ONNX`,`onnx-community/gemma-4-E9B-it-ONNX`,`onnx-community/gemma-4-E27B-it-ONNX`,`onnx-community/gemma-4-12B-it-ONNX`,`onnx-community/gemma-4-E2B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-E4B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-12B-it-qat-mobile-ONNX`,`onnx-community/Phi-3.5-mini-instruct-onnx-web`,`onnx-community/Phi-4-mini-instruct-ONNX`,`onnx-community/Llama-3.2-1B-Instruct-ONNX`,`onnx-community/Llama-3.2-3B-Instruct-ONNX`,`webgpu/Qwen3-4B-ONNX`,`onnx-community/DeepSeek-R1-Distill-Qwen-1.5B-ONNX`,`onnx-community/gpt-oss-20b-ONNX`,`onnx-community/LFM2-1.2B-ONNX`,`LiquidAI/LFM2.5-1.2B-Thinking-ONNX`,`HuggingFaceTB/SmolLM3-3B-ONNX`,`onnx-community/Qwen3.5-0.8B-ONNX-OPT`,`onnx-community/Qwen3.5-4B-ONNX-OPT`],requiresApiKey:!1,supportsStreaming:!1},litert_lm_browser:{id:`litert_lm_browser`,name:`LiteRT-LM (Browser)`,baseUrl:`local://litert-lm`,format:`transformers_js`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`litert-community/gemma-4-E2B-it-litert-lm`,models:[`litert-community/gemma-4-E2B-it-litert-lm`,`litert-community/gemma-4-E4B-it-litert-lm`],requiresApiKey:!1,supportsStreaming:!1},prompt_api:{id:`prompt_api`,name:`Prompt API (Browser)`,baseUrl:`builtin://language-model`,format:`prompt_api`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`browser-built-in`,models:[`browser-built-in`],requiresApiKey:!1,supportsStreaming:!1}};function I(e){return F[e]||null}function L(){return F[l]}function R(){return Object.keys(F)}function z(e){return`api_key:${e}`}function B(e){return N[e]||null}function V(e,t,n=`http_api`){let r=B(e);return r&&(r.tokenAuthByServiceType?.[n]?.[t]||r.tokenAuth[t])||null}const H={ACTIVE_TOOL_PROFILE:`active_tool_profile`,ACTIVITY_LOG_DISK_LOGGING_ENABLED:`activity_log_disk_logging_enabled`,ALLOWED_CUSTOM_ELEMENTS:`allowed_custom_elements`,ALLOWED_CUSTOM_ELEMENT_HOST_PATTERNS:`allowed_custom_element_host_patterns`,ALLOWED_IFRAME_HOST_PATTERNS:`allowed_iframe_host_patterns`,API_KEY:`api_key`,ASSISTANT_NAME:`assistant_name`,BEDROCK_AUTH_MODE:`bedrock_auth_mode`,BEDROCK_PROFILE_FALLBACK:`bedrock_profile_fallback`,BEDROCK_REGION_FALLBACK:`bedrock_region_fallback`,BUILTIN_AI_SUBAGENT_ROUTING:`builtin_ai_subagent_routing`,BUILTIN_AI_TOOLS_BACKEND:`builtin_ai_tools_backend`,CHANNEL_ENABLED_PREFIX:`channel_enabled:`,CHAT_INPUT_AREA_HEIGHT:`chat_input_area_height`,CHAT_SPLIT_VIEW_ENABLED:`chat_split_view_enabled`,CHAT_SPLIT_VIEW_HEIGHT:`chat_split_view_height`,COMPACTION_ENGINE_PREFERENCE:`compaction_engine_preference`,CONTEXT_COMPRESSION_ENABLED:`context_compression_enabled`,CONTROL_PLANE_CLIENT_ID:`control_plane_client_id`,CONTROL_PLANE_ENABLED:`control_plane_enabled`,CONTROL_PLANE_TRANSPORT:`control_plane_transport`,CONTROL_PLANE_URL:`control_plane_url`,CONVERSATIONS_HEIGHT:`conversations_height`,CUSTOM_TOOLS:`custom_tools`,DB_MIGRATED_FROM_LEGACY:`db_migrated_from_legacy`,DECLARATIVE_TOOLS_ENABLED:`declarative_tools_enabled`,DEFAULT_PINNED_PAGE:`default_pinned_page`,DIRECT_TOOL_COMMAND_POLICY:`direct_tool_command_policy`,ENABLED_TOOLS:`enabled_tools`,FILES_UPLOAD_APPEND_ULID:`files_upload_append_ulid`,GIT_ACCOUNTS:`git_accounts`,GIT_AUTHOR_EMAIL:`git_author_email`,GIT_AUTHOR_NAME:`git_author_name`,GIT_CORS_PROXY:`git_cors_proxy`,GIT_DEFAULT_ACCOUNT:`git_default_account`,GIT_PASSWORD:`git_password`,GIT_PROXY_URL:`git_proxy_url`,GIT_TOKEN:`git_token`,GIT_USERNAME:`git_username`,IMESSAGE_API_KEY:`imessage_api_key`,IMESSAGE_CHAT_IDS:`imessage_chat_ids`,IMESSAGE_SERVER_URL:`imessage_server_url`,INTEGRATION_CONNECTIONS:`integration_connections`,MARKDOWN_FRONTMATTER_CHAT:`markdown_frontmatter_chat`,MARKDOWN_FRONTMATTER_FILE_VIEWER:`markdown_frontmatter_file_viewer`,MARKDOWN_FRONTMATTER_PAGES:`markdown_frontmatter_pages`,MARKDOWN_FRONTMATTER_TASKS:`markdown_frontmatter_tasks`,LAST_ACTIVE_GROUP:`last_active_group`,LAST_ACTIVE_PAGE:`last_active_page`,LAST_SELECTED_PINNED_PAGE:`last_selected_pinned_page`,LLAMAFILE_HOST:`llamafile_host`,LLAMAFILE_MODE:`llamafile_mode`,LLAMAFILE_OFFLINE:`llamafile_offline`,LLAMAFILE_PORT:`llamafile_port`,MAIN_GROUP_INDEX_SUPPRESSED:`main_group_index_suppressed`,MAIN_GROUP_README_SUPPRESSED:`main_group_readme_suppressed`,MAX_ITERATIONS:`max_iterations`,MAX_TOKENS:`max_tokens`,MESH_LLM_HOST:`mesh_llm_host`,MODEL:`model`,OAUTH_PROVIDER_DEFINITIONS:`oauth_provider_definitions`,OPFS_MIGRATED_FROM_LEGACY:`opfs_migrated_from_legacy`,OVERRIDE_PRERENDER_SKELETON:`override_prerender_skeleton`,PAGES_AUTO_REFRESH_INTERVAL:`pages_auto_refresh_interval`,PAGES_LIST:`pages_list`,PASSPHRASE_SALT:`passphrase_salt`,PASSPHRASE_VERIFY:`passphrase_verify`,PROMPT_API_BACKEND:`prompt_api_backend`,PROMPT_API_DTYPE_STRATEGY:`prompt_api_dtype_strategy`,PROMPT_API_FALLBACK_MODEL:`prompt_api_fallback_model`,PROMPT_API_ONBOARDING_SEEN:`prompt_api_onboarding_seen`,PEERJS_MY_ALIAS:`peerjs_my_alias`,PEERJS_MY_PEER_ID:`peerjs_my_peer_id`,PEERJS_PEER_ALIASES:`peerjs_peer_aliases`,PEERJS_SERVER_HOST:`peerjs_server_host`,PEERJS_SERVER_PATH:`peerjs_server_path`,PEERJS_SERVER_PORT:`peerjs_server_port`,PEERJS_SERVER_SECURE:`peerjs_server_secure`,PEERJS_TRUSTED_PEER_IDS:`peerjs_trusted_peer_ids`,PROVIDER:`provider`,PROXY_URL:`proxy_url`,PUSH_PROXY_URL:`push_proxy_url`,RATE_LIMIT_AUTO_ADAPT:`rate_limit_auto_adapt`,RATE_LIMIT_CALLS_PER_MINUTE:`rate_limit_calls_per_minute`,REASONING_EFFORT:`reasoning_effort`,REMOTE_MCP_CONNECTIONS:`remote_mcp_connections`,SERVICE_ACCOUNTS:`service_accounts`,SERVICE_DEFAULT_ACCOUNT:`service_default_account`,SIDEBAR_CHAT_HIDDEN:`sidebar_chat_hidden`,SIDEBAR_DEFAULT_PAGE:`sidebar_default_page`,SIDEBAR_FILES_HIDDEN:`sidebar_files_hidden`,SIDEBAR_PAGES_HIDDEN:`sidebar_pages_hidden`,SIDEBAR_TASKS_HIDDEN:`sidebar_tasks_hidden`,SIDEBAR_WIDTH:`sidebar_width`,SITE_CONFIG_SEEDED:`site_config_seeded`,STATIC_MAIN_SITE_SEEDED:`static_main_site_seeded`,STORAGE_HANDLE:`storage_handle`,SUBSCRIBER_ID:`subscriber_id`,STREAMING_ENABLED:`streaming_enabled`,SUBAGENT_MAX_PARALLEL:`subagent_max_parallel`,SUBAGENT_WORKSPACE_MODE:`subagent_workspace_mode`,SUPPRESSED_PAGES_LIST:`suppressed_pages_list`,SYSTEM_PROMPT_OVERRIDE:`system_prompt_override`,TASK_SERVER_ENABLED:`task_server_enabled`,TASK_SERVER_URL:`task_server_url`,TASK_SYNC_OUTBOX:`task_sync_outbox`,TELEGRAM_BOT_TOKEN:`telegram_bot_token`,TELEGRAM_CHAT_IDS:`telegram_chat_ids`,TELEGRAM_USE_PROXY:`telegram_use_proxy`,TOOL_PROFILES:`tool_profiles`,TRANSFORMERS_JS_BACKEND:`transformers_js_backend`,TRANSFORMERS_JS_DTYPE_STRATEGY:`transformers_js_dtype_strategy`,TRIGGER_PATTERN:`trigger_pattern`,USE_PROXY:`use_proxy`,VAPID_SUBJECT:`vapid_subject`,VM_BASH_FULL_INTERNET_ACCESS:`vm_bash_full_internet_access`,VM_BASH_TIMEOUT_SEC:`vm_bash_timeout_sec`,VM_BOOT_HOST:`vm_boot_host`,VM_BOOT_MODE:`vm_boot_mode`,VM_NETWORK_RELAY_URL:`vm_network_relay_url`,WEBMCP_MODE:`webmcp_mode`,WEBMCP_TOOLS_ENABLED:`webmcp_tools_enabled`,WEB_SEARCH_PROXY_URL:`web_search_proxy_url`,WEB_SEARCH_URL:`web_search_url`,WEB_SEARCH_USE_PROXY:`web_search_use_proxy`,SEARCH_FILES_MAX_FILE_BYTES:`search_files_max_file_bytes`,SEARCH_FILES_MAX_FILES_VISITED:`search_files_max_files_visited`,SEARCH_FILES_SKIP_DIRS:`search_files_skip_dirs`},U=`localhost`,W=8888,G=`automatic`,K=`onnx-community/Qwen3-0.6B-ONNX`,q=`http://localhost:8888/schedule`;export{R as A,F as C,x as D,S as E,I as F,z as I,V as L,L as M,B as N,a as O,c as P,n as R,w as S,b as T,h as _,W as a,P as b,K as c,q as d,m as f,C as g,N as h,U as i,g as j,r as k,l,d as m,f as n,y as o,p,H as r,o as s,i as t,G as u,_ as v,u as w,v as x,k as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./config-
|
|
1
|
+
import{r as e}from"./config-CrHchneq.js";import{Ct as t,ht as n}from"./orchestrator-3h9xxHUm.js";import{t as r}from"./setConfig-DFMYnYLE.js";async function i(i,a,o,s,c=``,l=0,u=``,d=!0){let f=o.trim(),p=t(s),m=c.trim(),h=Number.isFinite(l)?Math.max(0,Math.floor(l)):0,g=u.trim(),_=!!d;i.peerjsMyPeerId=f,i.peerjsTrustedPeerIds=p,i.peerjsServerHost=m,i.peerjsServerPort=h,i.peerjsServerPath=g,i.peerjsServerSecure=_,await r(a,e.PEERJS_MY_PEER_ID,f),await r(a,e.PEERJS_TRUSTED_PEER_IDS,JSON.stringify(p)),await r(a,e.PEERJS_SERVER_HOST,m),await r(a,e.PEERJS_SERVER_PORT,h?String(h):``),await r(a,e.PEERJS_SERVER_PATH,g),await r(a,e.PEERJS_SERVER_SECURE,_?`true`:`false`);let v=m?{host:m,path:g||void 0,port:h||void 0,secure:_}:{};i.peerjs.stop(),i.peerjs.configure(f,p,v),f&&n(i,`peerjs`)&&i.peerjs.start()}export{i as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./config-
|
|
1
|
+
import{r as e}from"./config-CrHchneq.js";import{t}from"./getConfig-D89uJgo5.js";import{t as n}from"./setConfig-DFMYnYLE.js";import{t as r}from"./ulid-BY7rQVLN.js";const i=[{id:`imap`,name:`IMAP Mail`,protocol:`imap`,description:`Read mailboxes and fetch message metadata/content.`,version:`0.1.0`,actions:[`messages.read`,`messages.send`],authTypes:[`basic_userpass`,`oauth`],serviceTypes:[`http_api`],configurableFields:[`host`,`port`,`secure`,`mailboxPath`,`smtpHost`,`smtpPort`,`smtpSecure`,`fromAddress`,`executionMode`,`pollIntervalSec`]}];function a(){return[...i].sort((e,t)=>e.id.localeCompare(t.id))}function o(e){return e&&i.find(t=>t.id===e)||null}function s(e){if(!e||typeof e!=`object`)return null;let t=e;return!t.serviceType||!t.authType?null:{serviceType:t.serviceType,authType:t.authType,providerId:t.providerId||void 0,accountId:t.accountId||void 0,username:t.username||void 0,headerName:t.headerName||void 0,encryptedSecret:t.encryptedSecret||void 0}}function c(e){if(!e||typeof e!=`object`)return null;let t=e;return!t.id||!t.label||!t.pluginId||typeof t.enabled!=`boolean`||typeof t.createdAt!=`number`||typeof t.updatedAt!=`number`||!o(t.pluginId)?null:{id:t.id,label:t.label,pluginId:t.pluginId,enabled:t.enabled,config:t.config&&typeof t.config==`object`?{...t.config}:{},credentialRef:s(t.credentialRef),createdAt:t.createdAt,updatedAt:t.updatedAt}}async function l(n){let r=await t(n,e.INTEGRATION_CONNECTIONS);if(!Array.isArray(r))return[];let i=[];for(let e of r){let t=c(e);t&&i.push(t)}return i}async function u(t,r){await n(t,e.INTEGRATION_CONNECTIONS,r)}async function d(e){return l(e)}async function f(e,t){if(!t)return null;let n=await l(e);return n.find(e=>e.id===t)||n.find(e=>e.label.toLowerCase()===t.toLowerCase())||null}async function p(e,t){if(!t.label?.trim())throw Error(`Email connection label is required`);let n=o(t.pluginId);if(!n)throw Error(`Unknown email plugin: ${t.pluginId}`);let i=await l(e),a=Date.now();if(t.id){let r=i.findIndex(e=>e.id===t.id);if(r!==-1){let o=i[r],s={...o,label:t.label.trim(),pluginId:n.id,enabled:t.enabled??o.enabled,config:t.config?{...t.config}:o.config,updatedAt:a};return i[r]=s,await u(e,i),s}}let s={id:t.id||r(),label:t.label.trim(),pluginId:n.id,enabled:t.enabled??!0,config:t.config?{...t.config}:{},credentialRef:null,createdAt:a,updatedAt:a};return i.push(s),await u(e,i),s}async function m(e,t,n){if(!t)return null;let r=await l(e),i=r.findIndex(e=>e.id===t);if(i===-1)return null;let a={...r[i],credentialRef:n?s(n):null,updatedAt:Date.now()};return r[i]=a,await u(e,r),a}async function h(e,t){if(!t)return!1;let n=await l(e),r=n.filter(e=>e.id!==t);return r.length===n.length?!1:(await u(e,r),!0)}export{p as a,d as i,h as n,o,f as r,a as s,m as t};
|
package/dist/public/{custom-element-security-CZ92anB8.js → custom-element-security-NCqQ5lmC.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./config-
|
|
1
|
+
import{r as e}from"./config-CrHchneq.js";import{c as t}from"./app-routes-Bs-riIvr.js";import{n}from"./txPromise-EBECky1b.js";import{t as r}from"./getConfig-D89uJgo5.js";import{i,n as a,t as o}from"./iframe-sanitizer-y2Z1pPwY.js";function s(e=new Date){let t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}_${t(e.getHours())}-${t(e.getMinutes())}-${t(e.getSeconds())}`}function c(e){let t=new Date(e);return new Intl.DateTimeFormat(`en-US`,{weekday:`short`,month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,hour12:!0}).format(t)}function l(e){let t=document.createElement(`div`);return t.textContent=e,t.innerHTML}function u(e=``,t={}){return o(),ie(),a().sanitize(e,{ADD_TAGS:[`iframe`,`figure`,`figcaption`],ADD_ATTR:[`allow`,`allowfullscreen`,`frameborder`,`scrolling`,`referrerpolicy`,`loading`],CUSTOM_ELEMENT_HANDLING:{tagNameCheck:e=>M(e),attributeNameCheck:()=>!0,allowCustomizedBuiltInElements:!1},...t})}function d(e,n=``,r){let i=e.trim();if(!i)return!1;let a=i.indexOf(`?`);if(a!==-1&&(i=i.slice(0,a+1)+i.slice(a+1).replace(/\?/g,`&`)),i.startsWith(`/#`)||i.startsWith(`#`)){let e=(i.startsWith(`/#`)?i.slice(2):i.slice(1)).split(/[?#]/,1)[0].toLowerCase();if([`chat`,`files`,`tasks`,`pages`,`settings`].includes(e)){let t=i.startsWith(`/#`)?i.replace(/^\/#/,`http://local/`):i.replace(/^#/,`http://local/`),n=new URL(t,`http://local/`),a=n.searchParams.get(`groupId`)||n.searchParams.get(`conversationId`)||r,o=n.searchParams.get(`file`)||n.searchParams.get(`path`)||void 0,s=n.searchParams.get(`anchor`)||(n.hash?n.hash.slice(1):void 0),c={page:e,groupId:a||void 0,path:o||void 0,anchor:s||void 0};return document.dispatchEvent(new CustomEvent(`shadow-claw-navigate`,{detail:c,bubbles:!0,composed:!0})),!0}}if(i.startsWith(`/`))try{let e=new URL(i,window.location.origin),n=t(e,r);if(n)return document.dispatchEvent(new CustomEvent(`shadow-claw-navigate`,{detail:{page:n.page,groupId:n.groupId,path:n.path,anchor:n.anchor||(e.hash?e.hash.slice(1):void 0)},bubbles:!0,composed:!0})),!0}catch{}if(!/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(i)&&!i.startsWith(`//`)&&!i.startsWith(`javascript:`)){let e=i.split(/[?#]/,1)[0].replace(/\\/g,`/`),t=e.startsWith(`/`);e=e.replace(/^\/+/,``);let a=new URL(i,`http://local/`),o=a.hash?a.hash.slice(1):void 0,s=e;if(!t&&n){let t=n.replace(/\\/g,`/`).replace(/^\/+/,``).split(`/`).filter(Boolean);t.pop();let r=e.split(`/`),i=[...t];for(let e of r)!e||e===`.`||(e===`..`?i.pop():i.push(e));s=i.join(`/`)}if(s){let e={page:`files`,groupId:r||void 0,path:s,anchor:o||void 0};return document.dispatchEvent(new CustomEvent(`shadow-claw-navigate`,{detail:e,bubbles:!0,composed:!0})),!0}}return!1}const f=`shadowclaw`;let p;function m(){let e=globalThis.trustedTypes;return!e||typeof e.createPolicy!=`function`?null:e}function h(){if(p!==void 0)return p;let e=m();if(!e)return p=null,p;if(typeof e.getPolicy==`function`){let t=e.getPolicy(f);if(t)return p=t,p}try{p=e.createPolicy(f,{createHTML:e=>e,createScriptURL:e=>e})}catch{p=typeof e.getPolicy==`function`?e.getPolicy(f)??null:null}return p}function g(e=``,t={}){let n=u(e,t),r=h();return r?r.createHTML(n):n}function _(e,t={}){return u(e,t)}function v(e){let t=h();return t?t.createHTML(e):e}function y(e,t=``,n={}){let r=g(t,n);return e.innerHTML=r,r}function ee(e,t){let n=v(t);return e.srcdoc=n,n}function b(e){let t=h();return!t||typeof t.createScriptURL!=`function`?e:t.createScriptURL(e)}const x=[],S=[];let C=new Set(x.map(e=>e.toLowerCase().trim())),w=[...S],T=[];function E(e){T=e.map(e=>i(e)).filter(Boolean)}E(w);function D(e){return Array.isArray(e)?e.map(e=>typeof e==`string`?e.toLowerCase().trim():``).filter(Boolean):typeof e==`string`?e.split(/[\n,]+/).map(e=>e.toLowerCase().trim()).filter(Boolean):[]}function O(e){return Array.isArray(e)?e.map(e=>typeof e==`string`?e.trim():``).filter(Boolean):typeof e==`string`?e.split(/[\n,]+/).map(e=>e.trim()).filter(Boolean):[]}function k(e){let t=D(e);C=new Set(t)}function A(e){let t=O(e);w=t,E(t)}function j(){return[...w]}function M(e){if(!e||typeof e!=`string`)return!1;let t=e.trim().toLowerCase();return!t.includes(`-`)||t===`shadow-claw`||t.startsWith(`shadow-claw-`)?!0:C.has(t)}function te(e){if(!e||typeof e!=`string`)return!1;let t=e.trim();if(!t||/^(?:javascript|data|vbscript):/i.test(t))return!1;if(/^blob:/i.test(t))return!0;try{let e=typeof window<`u`&&window.location?.origin&&window.location.origin!==`null`?window.location.origin:`http://localhost`,n=new URL(t,e);if(n.protocol!==`http:`&&n.protocol!==`https:`)return!1;if(typeof window<`u`&&window.location?.origin&&window.location.origin!==`null`&&n.origin===window.location.origin)return!0;let r=n.hostname.toLowerCase();return T.some(e=>e(r))}catch{return!1}}const N=`allow-modals allow-scripts allow-popups allow-popups-to-escape-sandbox`,P=[`'self'`,`blob:`,`data:`],F=[`'self'`,`blob:`,`data:`],I=[`'self'`,`'unsafe-inline'`,`https:`,`http:`],L=[`'self'`,`blob:`,`data:`,`https:`,`http:`];let R=N,z=[...P],B=[...F],V=[],H=[...I],U=[...L];function W(){return R}function G(e){R=Array.isArray(e)?e.map(e=>typeof e==`string`?e.trim():``).filter(Boolean).join(` `):typeof e==`string`&&e.trim()?e.trim():N}function K(e){let t=j(),n=Y(),r=new Set;for(let e of t)e&&/^(\*\.)?[a-zA-Z0-9.-]+(?::[0-9]+)?$/.test(e)&&(r.add(`https://${e}`),r.add(`http://${e}`));for(let e of n)try{let t=new URL(e,typeof window<`u`&&window.location?.origin?window.location.origin:`http://localhost`);r.add(t.origin)}catch{}let i=[`'nonce-${e}'`,...Array.from(r),...V],a=[...B,...Array.from(r)];return[`script-src ${Array.from(new Set(i)).join(` `)}`,`worker-src ${Array.from(new Set(z)).join(` `)}`,`connect-src ${Array.from(new Set(a)).join(` `)}`,`style-src ${Array.from(new Set(H)).join(` `)}`,`img-src ${Array.from(new Set(U)).join(` `)}`].join(`; `)}function q(e){if(!e||typeof e!=`object`)return;let t=e.allowedCustomElements||(typeof e.customElements==`object`&&!Array.isArray(e.customElements)?e.customElements?.allowedElements:void 0);t!==void 0&&k(t);let n=e.allowedCustomElementDomains||(typeof e.customElements==`object`&&!Array.isArray(e.customElements)?e.customElements?.allowedDomains:void 0);n!==void 0&&A(n),e.security?.iframeSandbox===void 0?(e.security?.allowSameOrigin===!0||e.security?.allowIframeSameOrigin===!0)&&(R.includes(`allow-same-origin`)||(R=`${R} allow-same-origin`.trim())):G(e.security.iframeSandbox),e.security?.workerSrc!==void 0&&(z=O(e.security.workerSrc)),e.security?.connectSrc!==void 0&&(B=O(e.security.connectSrc)),e.security?.scriptSrc!==void 0&&(V=O(e.security.scriptSrc)),e.security?.styleSrc!==void 0&&(H=O(e.security.styleSrc)),e.security?.imgSrc!==void 0&&(U=O(e.security.imgSrc))}function J(){if(typeof document>`u`)return;let e=document.getElementById(`shadow-claw-site-config`);if(e&&e.textContent)try{q(JSON.parse(e.textContent))}catch{}}function Y(){if(typeof document>`u`)return[];let e=document.getElementById(`shadow-claw-site-config`);if(!e||!e.textContent)return[];try{let t=JSON.parse(e.textContent),n=typeof t.customElements==`object`&&!Array.isArray(t.customElements)?t.customElements?.scripts:void 0;if(Array.isArray(n))return n.map(e=>typeof e==`string`?e:e?.src).filter(e=>typeof e==`string`&&te(e))}catch{}return[]}async function X(t){try{let i=t??await n();if(!i)return;let[a,o]=await Promise.all([r(i,e.ALLOWED_CUSTOM_ELEMENTS),r(i,e.ALLOWED_CUSTOM_ELEMENT_HOST_PATTERNS)]);if(typeof a==`string`&&a.trim())try{k(JSON.parse(a))}catch{k(a)}if(typeof o==`string`&&o.trim())try{A(JSON.parse(o))}catch{A(o)}}catch(e){console.warn(`Failed to load custom element security from db:`,e)}}let Z=null,Q=!1;function ne(){J(),!(Q||typeof customElements>`u`||typeof customElements.define!=`function`)&&(Z=customElements.define.bind(customElements),customElements.define=function(e,t,n){if(!M((e||``).toLowerCase().trim())){let t=`[Security] Registration blocked: <${e}> is not an approved custom element.`;throw console.error(t),Error(t)}return Z(e,t,n)},Q=!0)}function re(e=typeof document<`u`?document.documentElement:null){if(typeof MutationObserver>`u`||!e)return null;if(typeof e.querySelectorAll==`function`)try{e.querySelectorAll(`*`).forEach(e=>{let t=e.tagName?e.tagName.toLowerCase():``;t.includes(`-`)&&!M(t)&&(console.warn(`[Security] Removing existing unapproved custom element: <${t}>`),e.remove())})}catch{}let t=new MutationObserver(e=>{for(let t of e)t.addedNodes.forEach(e=>{if(e.nodeType===1){let t=e,n=t.tagName?t.tagName.toLowerCase():``;n.includes(`-`)&&!M(n)&&(console.warn(`[Security] Removing unapproved custom element: <${n}>`),t.remove())}})});return t.observe(e,{childList:!0,subtree:!0}),t}let $=!1;function ie(){if($)return;let e=a();if(e&&typeof e.addHook==`function`){let t=e=>{if(e&&e.nodeType===1){let t=e,n=(t.tagName||``).toLowerCase();n.includes(`-`)&&!M(n)&&(typeof t.remove==`function`&&t.remove(),t.parentNode&&t.parentNode.removeChild(t))}};e.addHook(`uponSanitizeElement`,t),e.addHook(`afterSanitizeElements`,t),$=!0}}export{d as _,re as a,X as c,ee as d,v as f,c as g,s as h,W as i,_ as l,l as m,Y as n,ne as o,b as p,K as r,M as s,q as t,y as u};
|
|
@@ -47,7 +47,9 @@ Detailed docs for each major subsystem.
|
|
|
47
47
|
| [Pages System](subsystems/pages.md) | Workspace-relative pages rendering, sidebar navigation, static site seeding, pretty paths, same-origin route validation, and production asset inlining |
|
|
48
48
|
| [Custom Element Security](subsystems/custom-element-security.md) | Custom element registry & DOM guards, allowlists, iframe sandbox policies, and nonce-gated CSP |
|
|
49
49
|
| [LiteRT Provider](subsystems/providers.md) | In-browser WebGPU inference provider using Google LiteRT-LM |
|
|
50
|
-
| [CLI & Static Site Publishing](subsystems/cli.md) | `shadow-claw` CLI commands (`build`, `dev`, `serve`, `init`), dual-root path resolution, and npm packaging
|
|
50
|
+
| [CLI & Static Site Publishing](subsystems/cli.md) | `shadow-claw` CLI commands (`build`, `dev`, `serve`, `init`, `clients`, `send`, `backup`, `tasks`), dual-root path resolution, and npm packaging |
|
|
51
|
+
| [Control Plane & Client Bridge](subsystems/control-plane.md) | Dual SSE/WebSocket control plane for CLI driving and persistent execution surface |
|
|
52
|
+
| [File Backup Subsystem](subsystems/backup.md) | Remote workspace and OPFS file backups to server storage |
|
|
51
53
|
|
|
52
54
|
### Guides
|
|
53
55
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## What is ShadowClaw?
|
|
8
8
|
|
|
9
|
-
ShadowClaw is a **browser-native AI assistant** — a fully functional agent runtime
|
|
9
|
+
ShadowClaw is a **browser-native AI assistant** — a fully functional agent runtime whose orchestration and tool-use loop run client-side, with AI inference routing to remote APIs, local servers, or in-browser models depending on your configuration. It runs as a PWA in any modern browser, as a native desktop app via Electron, as a standalone Node.js server, and is driven via the `shadow-claw` CLI.
|
|
10
10
|
|
|
11
11
|
**Stack at a glance:**
|
|
12
12
|
|
|
@@ -52,7 +52,7 @@ graph TD
|
|
|
52
52
|
|
|
53
53
|
### 1. Browser-native first
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
The AI runtime and UI are built on browser-native technology regardless of deployment target. The Express server provides a suite of backend services including:
|
|
56
56
|
|
|
57
57
|
- CORS proxying for LLM providers (Bedrock, Vertex AI, Gemini, etc.)
|
|
58
58
|
- Web Push notification delivery and VAPID management
|
|
@@ -159,15 +159,15 @@ sequenceDiagram
|
|
|
159
159
|
|
|
160
160
|
## Entry Points
|
|
161
161
|
|
|
162
|
-
| File | Thread | Role
|
|
163
|
-
| ------------------------------------ | ------- |
|
|
164
|
-
| `src/core/index.ts` | Main | App bootstrap — opens IndexedDB, boots orchestrator, registers service worker
|
|
165
|
-
| `src/worker/worker.ts` | Worker | Agent worker — owns LLM tool-use loop, VM, tool execution
|
|
166
|
-
| `src/server/server.ts` | Node.js | Express dev/prod server — proxy, push, scheduling, static files
|
|
167
|
-
| `electron/main.ts` | Node.js | Electron main process — same Express server in-process
|
|
168
|
-
| `src/service-worker/init.ts` | SW | Service worker bootstrap — Workbox cache registration
|
|
169
|
-
| `src/service-worker/push-handler.ts` | SW | Web Push event handler
|
|
170
|
-
| `src/service-worker/fetch-proxy.ts` | SW | Fetch interception
|
|
162
|
+
| File | Thread | Role |
|
|
163
|
+
| ------------------------------------ | ------- | ------------------------------------------------------------------------------ |
|
|
164
|
+
| `src/core/index.ts` | Main | App bootstrap — opens IndexedDB, boots orchestrator, registers service worker |
|
|
165
|
+
| `src/worker/worker.ts` | Worker | Agent worker — owns LLM tool-use loop, VM, tool execution |
|
|
166
|
+
| `src/server/server.ts` | Node.js | Express dev/prod server — proxy, push, scheduling, control plane, static files |
|
|
167
|
+
| `electron/main.ts` | Node.js | Electron main process — same Express server in-process |
|
|
168
|
+
| `src/service-worker/init.ts` | SW | Service worker bootstrap — Workbox cache registration |
|
|
169
|
+
| `src/service-worker/push-handler.ts` | SW | Web Push event handler |
|
|
170
|
+
| `src/service-worker/fetch-proxy.ts` | SW | Fetch interception |
|
|
171
171
|
|
|
172
172
|
## Key Directories
|
|
173
173
|
|
|
@@ -181,7 +181,7 @@ sequenceDiagram
|
|
|
181
181
|
| `src/components/settings/` | Recommended home for settings feature components (incremental migration) |
|
|
182
182
|
| `src/context/` | Token estimation, dynamic windowing, output truncation |
|
|
183
183
|
| `src/db/` | IndexedDB layer (granular modules for each DB operation) |
|
|
184
|
-
| `src/server/` | Express server
|
|
184
|
+
| `src/server/` | Express server, control plane, proxy routes, WebRTC, and backup APIs |
|
|
185
185
|
| `src/service-worker/` | Service worker modules |
|
|
186
186
|
| `src/shell/` | JS shell emulator + OPFS bridge |
|
|
187
187
|
| `src/storage/` | OPFS + File System Access API abstractions |
|
|
@@ -213,7 +213,10 @@ To prevent storage state leakage when multiple instances are deployed under subp
|
|
|
213
213
|
Computes database names as `shadowclaw-${namespace}` (falling back to legacy `"shadowclaw"` when unnamespaced).
|
|
214
214
|
3. **OPFS Root Directory Scope (`getOpfsRootName()`):**
|
|
215
215
|
Computes OPFS root directory handles as `shadow-claw-opfs-${namespace}` (falling back to `"shadowclaw"` when unnamespaced).
|
|
216
|
-
4. **Automated Legacy Migration (`migrateLegacyDatabase.ts`):**
|
|
217
|
-
When booting a namespaced
|
|
216
|
+
4. **Automated Legacy Migration (`migrateLegacyDatabase.ts` & `migrateLegacyOpfs.ts`):**
|
|
217
|
+
When booting a namespaced deployment for the first time, ShadowClaw checks if data was previously stored under `"shadowclaw"`.
|
|
218
|
+
- **IndexedDB**: Copies all object stores into the new namespaced database in a single non-destructive pass, setting `DB_MIGRATED_FROM_LEGACY`.
|
|
219
|
+
- **OPFS**: Recursively copies all legacy workspace directories and files from `"shadowclaw"` into `"shadowclaw-${namespace}"` (with Safari worker write fallback), setting `OPFS_MIGRATED_FROM_LEGACY`.
|
|
220
|
+
The legacy storage is left intact as a fallback seed.
|
|
218
221
|
5. **Namespaced `localStorage` (`namespacedStorage.ts`):**
|
|
219
222
|
Key pattern `shadowclaw:${namespace}:${key}` with automatic one-time copy-on-read from legacy unprefixed keys.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Context
|
|
8
8
|
|
|
9
|
-
ShadowClaw originally shipped as a collection of browser-native ES modules (`.mjs` files) loaded directly by the browser with no build step. This approach allowed for a rapid development loop (edit and refresh).
|
|
9
|
+
ShadowClaw originally shipped as a collection of browser-native ES modules (`.mjs` files) loaded directly by the browser with no build step — before Electron, a Node.js server, CLI tooling, and a production build pipeline were added. This approach allowed for a rapid development loop (edit and refresh).
|
|
10
10
|
|
|
11
11
|
## Decision
|
|
12
12
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
## Context
|
|
7
7
|
|
|
8
|
-
ShadowClaw is browser-native. It needs to persist:
|
|
8
|
+
ShadowClaw is browser-native — its storage layer uses Web Platform APIs whether running as a PWA, via Electron, or against a Node.js backend. It needs to persist:
|
|
9
9
|
|
|
10
10
|
1. **Message history** — structured data: role, content, timestamps, groupId
|
|
11
11
|
2. **Configuration** — API keys, provider selection, model, settings
|
|
@@ -136,8 +136,11 @@ To prevent storage state leakage when multiple instances are deployed under subp
|
|
|
136
136
|
Derived automatically from subpath routing (`getAppBasePath()`) or explicit overrides (`window.__SHADOWCLAW_DEPLOY_ID__` / `process.env.SHADOWCLAW_DEPLOY_ID`).
|
|
137
137
|
2. **IndexedDB Scope (`getDbName()`):**
|
|
138
138
|
Computes database names as `shadowclaw-${namespace}` (falling back to legacy `"shadowclaw"` when unnamespaced).
|
|
139
|
-
3. **Automated Legacy Migration (`migrateLegacyDatabase.ts`):**
|
|
140
|
-
When booting a namespaced
|
|
139
|
+
3. **Automated Legacy Migration (`migrateLegacyDatabase.ts` & `migrateLegacyOpfs.ts`):**
|
|
140
|
+
When booting a namespaced deployment for the first time, ShadowClaw checks if data was previously stored under `"shadowclaw"`.
|
|
141
|
+
- **IndexedDB**: Copies all object stores into the new namespaced database in a single non-destructive pass, setting `DB_MIGRATED_FROM_LEGACY`.
|
|
142
|
+
- **OPFS**: Recursively copies all legacy workspace directories and files from `"shadowclaw"` into `"shadowclaw-${namespace}"` (with Safari worker write fallback), setting `OPFS_MIGRATED_FROM_LEGACY`.
|
|
143
|
+
The legacy storage is left intact as a fallback seed.
|
|
141
144
|
4. **Namespaced `localStorage` (`namespacedStorage.ts`):**
|
|
142
145
|
Key pattern `shadowclaw:${namespace}:${key}` with automatic one-time copy-on-read from legacy unprefixed keys.
|
|
143
146
|
5. **Isolation Assurance:**
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Context
|
|
8
8
|
|
|
9
|
-
Building a browser-native AI assistant requires a reactive UI that updates when async operations complete (streaming tokens, tool results, typing indicators). The question was: what framework (if any) to use?
|
|
9
|
+
Building a browser-native AI assistant (one that runs as a PWA, Electron desktop app, Node.js server, and via the CLI) requires a reactive UI that updates when async operations complete (streaming tokens, tool results, typing indicators). The question was: what framework (if any) to use?
|
|
10
10
|
|
|
11
11
|
The original options were:
|
|
12
12
|
|