clay-server 5.1.1-beta.1 → 5.2.0-beta.10
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/lib/account-auth-policy.js +21 -0
- package/lib/account-auth-socket.js +30 -0
- package/lib/account-auth-throttle.js +44 -0
- package/lib/account-auth-transport.js +48 -0
- package/lib/account-login-page.js +28 -0
- package/lib/account-passkey-challenges.js +31 -0
- package/lib/account-passkey-page.js +89 -0
- package/lib/account-passkey-policy.js +39 -0
- package/lib/account-password-page.js +69 -0
- package/lib/account-passwords.js +36 -0
- package/lib/account-remembered.js +77 -0
- package/lib/account-session-page.js +51 -0
- package/lib/account-session-store.js +82 -0
- package/lib/builtin-mates.js +19 -16
- package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
- package/lib/canonical-clay-record-authority.js +15 -0
- package/lib/canonical-clay-scheduling-authority.js +19 -0
- package/lib/claude-hook-installer.js +1 -239
- package/lib/claude-jsonl-watcher.js +1 -204
- package/lib/clay-control-presentation-binding.js +96 -0
- package/lib/clay-control-presentation.js +128 -0
- package/lib/clay-control-target-projection.js +26 -0
- package/lib/clay-mate-chat-receipts.js +26 -0
- package/lib/clay-mate-chat.js +88 -0
- package/lib/clay-mate-knowledge-input.js +26 -0
- package/lib/clay-mate-knowledge.js +95 -0
- package/lib/clay-mate-lifecycle.js +95 -0
- package/lib/clay-product-control-input.js +33 -0
- package/lib/clay-product-control-tools.js +51 -0
- package/lib/clay-product-control.js +247 -0
- package/lib/clay-project-lifecycle.js +154 -0
- package/lib/clay-project-record-input.js +44 -0
- package/lib/clay-project-records.js +84 -0
- package/lib/clay-scheduling-input.js +21 -0
- package/lib/clay-scheduling-receipts.js +26 -0
- package/lib/clay-scheduling.js +119 -0
- package/lib/clay-screen-controls.js +104 -0
- package/lib/clay-skill-install.js +1 -33
- package/lib/clay-workspace-controls.js +84 -0
- package/lib/clay-workspace-input.js +17 -0
- package/lib/clay-workspace-receipts.js +26 -0
- package/lib/cli-sessions.js +1 -300
- package/lib/codex-defaults.js +1 -28
- package/lib/context-usage.js +3 -2
- package/lib/contextual-screen-snapshot.js +38 -0
- package/lib/daemon-project-access.js +11 -0
- package/lib/daemon-project-lifecycle-callbacks.js +15 -0
- package/lib/daemon-project-lifecycle.js +262 -0
- package/lib/daemon-projects.js +1 -1
- package/lib/daemon.js +80 -276
- package/lib/default-ai-runtime.js +4 -8
- package/lib/dm-digest-cursor.js +120 -0
- package/lib/email-mcp-server.js +1 -1
- package/lib/issues-service.js +29 -15
- package/lib/kiro-defaults.js +1 -22
- package/lib/knowledge-db-import-validation.js +46 -0
- package/lib/knowledge-db-import.js +99 -0
- package/lib/knowledge-db-service.js +24 -33
- package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
- package/lib/knowledge-db-storage-nedb.js +66 -0
- package/lib/knowledge-db-storage.js +72 -0
- package/lib/knowledge-db-validation.js +0 -0
- package/lib/knowledge-document-index.js +2 -1
- package/lib/knowledge-file-store.js +7 -1
- package/lib/knowledge-product-operations.js +46 -0
- package/lib/mate-avatar-catalog.js +12 -0
- package/lib/mate-avatar-migration.js +41 -0
- package/lib/mate-context-service.js +138 -0
- package/lib/mate-context-tools.js +21 -0
- package/lib/mate-creation-mcp-server.js +2 -0
- package/lib/mate-knowledge-canonical-access.js +10 -0
- package/lib/mate-knowledge-mate-bound.js +53 -0
- package/lib/mate-knowledge-mcp-server.js +55 -8
- package/lib/mate-knowledge-service.js +16 -34
- package/lib/mate-knowledge-text-tools.js +106 -0
- package/lib/mate-lifecycle-service.js +94 -0
- package/lib/mate-message-delivery.js +43 -0
- package/lib/mate-ready-creation.js +9 -1
- package/lib/mate-schedule-input.js +29 -0
- package/lib/mate-schedule-lifecycle.js +151 -0
- package/lib/mate-scheduling.js +103 -0
- package/lib/mates.js +18 -6
- package/lib/mcp-agent-tools.js +117 -0
- package/lib/mcp-connection-store.js +119 -15
- package/lib/mcp-import-credentials.js +31 -0
- package/lib/mcp-local-transport.js +13 -0
- package/lib/mcp-oauth.js +8 -6
- package/lib/mcp-proxy.js +2 -32
- package/lib/mcp-query-bridge.js +30 -0
- package/lib/mcp-remote-connections.js +74 -20
- package/lib/mcp-source-adapters.js +1 -0
- package/lib/mcp-source-context.js +1 -0
- package/lib/mcp-source-discovery.js +1 -0
- package/lib/mcp-source-plugins.js +1 -0
- package/lib/mcp-source-restrictions.js +1 -0
- package/lib/mcp-tool-policy.js +9 -0
- package/lib/migrate-single-user.js +3 -23
- package/lib/notes-checklist.js +50 -0
- package/lib/notes.js +49 -3
- package/lib/os-user-diagnostics.js +2 -4
- package/lib/os-users.js +24 -70
- package/lib/pane-pending-interactions.js +20 -0
- package/lib/pane-session-activation.js +114 -0
- package/lib/pane-session-transport.js +26 -0
- package/lib/project-admin-overview.js +51 -0
- package/lib/project-ask-user.js +8 -4
- package/lib/project-connection.js +14 -10
- package/lib/project-control-git-view.js +12 -0
- package/lib/project-debate.js +1 -0
- package/lib/project-delegated-follow-up.js +2 -1
- package/lib/project-directory-claim.js +65 -0
- package/lib/project-file-operations.js +61 -0
- package/lib/project-filesystem.js +15 -85
- package/lib/project-full-access.js +23 -2
- package/lib/project-http.js +7 -4
- package/lib/project-knowledge.js +32 -18
- package/lib/project-lifecycle-operations.js +98 -0
- package/lib/project-lifecycle-process-witness.js +32 -0
- package/lib/project-lifecycle-runtime.js +50 -0
- package/lib/project-linux-access.js +22 -0
- package/lib/project-logs-canonical-clay.js +27 -0
- package/lib/project-logs-clay-query.js +16 -0
- package/lib/project-logs-schema.js +4 -2
- package/lib/project-logs-service.js +8 -7
- package/lib/project-logs.js +1 -0
- package/lib/project-loop.js +1 -0
- package/lib/project-mate-chat-control.js +55 -0
- package/lib/project-mate-creation-proposal.js +18 -3
- package/lib/project-mate-interaction.js +40 -62
- package/lib/project-mcp.js +54 -16
- package/lib/project-models.js +14 -31
- package/lib/project-notifications.js +76 -17
- package/lib/project-ownership.js +77 -0
- package/lib/project-pair-result-delivery.js +14 -3
- package/lib/project-pair-usage.js +12 -13
- package/lib/project-pending-message-queue.js +4 -1
- package/lib/project-product-control.js +89 -0
- package/lib/project-product-session-queue.js +46 -0
- package/lib/project-push-access.js +28 -0
- package/lib/project-scheduled-message-queue.js +30 -0
- package/lib/project-scheduled-messages.js +67 -68
- package/lib/project-scheduled-task-control.js +83 -0
- package/lib/project-scheduled-tasks.js +13 -2
- package/lib/project-scheduling-access.js +10 -0
- package/lib/project-server-settings.js +1 -0
- package/lib/project-session-actions.js +65 -0
- package/lib/project-session-delete.js +8 -1
- package/lib/project-session-document.js +27 -7
- package/lib/project-session-github.js +63 -19
- package/lib/project-session-history-actions.js +167 -0
- package/lib/project-session-linear.js +14 -6
- package/lib/project-session-notes.js +7 -3
- package/lib/project-session-pair.js +1 -1
- package/lib/project-session-runtime-actions.js +64 -0
- package/lib/project-session-spawn.js +2 -3
- package/lib/project-session-vendor.js +55 -0
- package/lib/project-sessions.js +103 -272
- package/lib/project-shared-browser.js +78 -17
- package/lib/project-studio-presentation.js +58 -0
- package/lib/project-user-knowledge.js +2 -1
- package/lib/project-user-message.js +67 -1
- package/lib/project-vendor-login.js +6 -36
- package/lib/project-workspace-operations.js +126 -0
- package/lib/project-workspace-query.js +19 -2
- package/lib/project.js +178 -45
- package/lib/public/app.js +46 -0
- package/lib/public/appearance-bootstrap.js +16 -0
- package/lib/public/auth/account-login.css +98 -0
- package/lib/public/auth/account-login.js +104 -0
- package/lib/public/css/clay-tool-activity.css +51 -0
- package/lib/public/css/clay-workspace.css +29 -0
- package/lib/public/css/command-palette.css +12 -33
- package/lib/public/css/contextual-clay.css +240 -0
- package/lib/public/css/home-debate-planning.css +2 -0
- package/lib/public/css/home-mate-creation.css +5 -0
- package/lib/public/css/input.css +6 -0
- package/lib/public/css/mate-avatar-gallery.css +12 -0
- package/lib/public/css/mate-conversation.css +10 -5
- package/lib/public/css/messages.css +6 -2
- package/lib/public/css/overlays.css +4 -2
- package/lib/public/css/project-admin-overview.css +13 -0
- package/lib/public/css/session-folders.css +11 -0
- package/lib/public/css/session-github.css +46 -1
- package/lib/public/css/shared-browser.css +35 -1
- package/lib/public/css/sticky-notes.css +87 -1
- package/lib/public/css/user-settings-sessions.css +42 -0
- package/lib/public/index.html +28 -10
- package/lib/public/mate-avatars/B01.png +0 -0
- package/lib/public/mate-avatars/B02.png +0 -0
- package/lib/public/mate-avatars/B03.png +0 -0
- package/lib/public/mate-avatars/B04.png +0 -0
- package/lib/public/mate-avatars/B05.png +0 -0
- package/lib/public/mate-avatars/B06.png +0 -0
- package/lib/public/mate-avatars/B07.png +0 -0
- package/lib/public/mate-avatars/B08.png +0 -0
- package/lib/public/mate-avatars/B09.png +0 -0
- package/lib/public/mate-avatars/B10.png +0 -0
- package/lib/public/mate-avatars/B11.png +0 -0
- package/lib/public/mate-avatars/B12.png +0 -0
- package/lib/public/mate-avatars/B13.png +0 -0
- package/lib/public/mate-avatars/B14.png +0 -0
- package/lib/public/mate-avatars/B15.png +0 -0
- package/lib/public/mate-avatars/B16.png +0 -0
- package/lib/public/mate-avatars/B17.png +0 -0
- package/lib/public/mate-avatars/B18.png +0 -0
- package/lib/public/mate-avatars/B19.png +0 -0
- package/lib/public/mate-avatars/B20.png +0 -0
- package/lib/public/mate-avatars/B21.png +0 -0
- package/lib/public/mate-avatars/B22.png +0 -0
- package/lib/public/mate-avatars/B23.png +0 -0
- package/lib/public/mate-avatars/B24.png +0 -0
- package/lib/public/mate-avatars/B25.png +0 -0
- package/lib/public/mate-avatars/B26.png +0 -0
- package/lib/public/mate-avatars/B27.png +0 -0
- package/lib/public/mate-avatars/B28.png +0 -0
- package/lib/public/mate-avatars/B29.png +0 -0
- package/lib/public/mate-avatars/B30.png +0 -0
- package/lib/public/mate-avatars/B31.png +0 -0
- package/lib/public/mate-avatars/B32.png +0 -0
- package/lib/public/mate-avatars/B33.png +0 -0
- package/lib/public/mate-avatars/B34.png +0 -0
- package/lib/public/mate-avatars/B35.png +0 -0
- package/lib/public/mate-avatars/B36.png +0 -0
- package/lib/public/mate-avatars/B37.png +0 -0
- package/lib/public/mate-avatars/B38.png +0 -0
- package/lib/public/mate-avatars/B39.png +0 -0
- package/lib/public/mate-avatars/B40.png +0 -0
- package/lib/public/mate-avatars/B41.png +0 -0
- package/lib/public/mate-avatars/B42.png +0 -0
- package/lib/public/mate-avatars/B43.png +0 -0
- package/lib/public/mate-avatars/B44.png +0 -0
- package/lib/public/mate-avatars/B45.png +0 -0
- package/lib/public/mate-avatars/B46.png +0 -0
- package/lib/public/mate-avatars/B47.png +0 -0
- package/lib/public/mate-avatars/B48.png +0 -0
- package/lib/public/mate-avatars/C01.png +0 -0
- package/lib/public/mate-avatars/C02.png +0 -0
- package/lib/public/mate-avatars/C03.png +0 -0
- package/lib/public/mate-avatars/C04.png +0 -0
- package/lib/public/mate-avatars/C05.png +0 -0
- package/lib/public/mate-avatars/C06.png +0 -0
- package/lib/public/mate-avatars/C07.png +0 -0
- package/lib/public/mate-avatars/C08.png +0 -0
- package/lib/public/mate-avatars/C09.png +0 -0
- package/lib/public/mate-avatars/C10.png +0 -0
- package/lib/public/mate-avatars/C11.png +0 -0
- package/lib/public/mate-avatars/C12.png +0 -0
- package/lib/public/mate-avatars/C13.png +0 -0
- package/lib/public/mate-avatars/C14.png +0 -0
- package/lib/public/mate-avatars/C15.png +0 -0
- package/lib/public/mate-avatars/C16.png +0 -0
- package/lib/public/mate-avatars/C17.png +0 -0
- package/lib/public/mate-avatars/C18.png +0 -0
- package/lib/public/mate-avatars/C19.png +0 -0
- package/lib/public/mate-avatars/C20.png +0 -0
- package/lib/public/mate-avatars/C21.png +0 -0
- package/lib/public/mate-avatars/C22.png +0 -0
- package/lib/public/mate-avatars/C23.png +0 -0
- package/lib/public/mate-avatars/C24.png +0 -0
- package/lib/public/mate-avatars/C25.png +0 -0
- package/lib/public/mate-avatars/C26.png +0 -0
- package/lib/public/mate-avatars/C27.png +0 -0
- package/lib/public/mate-avatars/C28.png +0 -0
- package/lib/public/mate-avatars/C29.png +0 -0
- package/lib/public/mate-avatars/C30.png +0 -0
- package/lib/public/mate-avatars/C31.png +0 -0
- package/lib/public/mate-avatars/C32.png +0 -0
- package/lib/public/mate-avatars/C33.png +0 -0
- package/lib/public/mate-avatars/C34.png +0 -0
- package/lib/public/mate-avatars/C35.png +0 -0
- package/lib/public/mate-avatars/C36.png +0 -0
- package/lib/public/mate-avatars/C37.png +0 -0
- package/lib/public/mate-avatars/C38.png +0 -0
- package/lib/public/mate-avatars/C39.png +0 -0
- package/lib/public/mate-avatars/C40.png +0 -0
- package/lib/public/mate-avatars/C41.png +0 -0
- package/lib/public/mate-avatars/C42.png +0 -0
- package/lib/public/mate-avatars/C43.png +0 -0
- package/lib/public/mate-avatars/C44.png +0 -0
- package/lib/public/mate-avatars/C45.png +0 -0
- package/lib/public/mate-avatars/C46.png +0 -0
- package/lib/public/mate-avatars/C47.png +0 -0
- package/lib/public/mate-avatars/C48.png +0 -0
- package/lib/public/mate-avatars/catalog.json +482 -0
- package/lib/public/mate-avatars/lead-clay.png +0 -0
- package/lib/public/modules/account-auth-settings.js +71 -0
- package/lib/public/modules/account-transport-settings.js +51 -0
- package/lib/public/modules/admin-settings-projects.js +6 -2
- package/lib/public/modules/app-connection.js +11 -1
- package/lib/public/modules/app-favicon.js +18 -9
- package/lib/public/modules/app-header.js +7 -4
- package/lib/public/modules/app-loop-ui.js +2 -0
- package/lib/public/modules/app-message-router.js +22 -1
- package/lib/public/modules/app-messages.js +119 -17
- package/lib/public/modules/app-misc.js +3 -1
- package/lib/public/modules/app-notifications.js +11 -5
- package/lib/public/modules/app-panels.js +61 -123
- package/lib/public/modules/app-projects.js +13 -0
- package/lib/public/modules/app-rate-limit.js +7 -27
- package/lib/public/modules/app-rendering.js +4 -3
- package/lib/public/modules/avatar.js +15 -41
- package/lib/public/modules/chat-render-runtime.js +20 -0
- package/lib/public/modules/clay-browser-links.js +47 -0
- package/lib/public/modules/clay-control-activity.js +214 -0
- package/lib/public/modules/clay-control-copy.js +36 -0
- package/lib/public/modules/clay-control-detail-targets.js +44 -0
- package/lib/public/modules/clay-control-object-targets.js +52 -0
- package/lib/public/modules/clay-control-target-visibility.js +12 -0
- package/lib/public/modules/clay-control-targets.js +44 -0
- package/lib/public/modules/clay-log-links.js +23 -0
- package/lib/public/modules/clay-navigation-render.js +52 -0
- package/lib/public/modules/clay-owner-navigation.js +33 -0
- package/lib/public/modules/clay-session-links.js +31 -0
- package/lib/public/modules/clay-studio-bridge.js +20 -0
- package/lib/public/modules/clay-studio-document.js +67 -0
- package/lib/public/modules/clay-studio-render.js +146 -0
- package/lib/public/modules/clay-tool-activity.js +140 -0
- package/lib/public/modules/clay-tool-presentation.js +342 -0
- package/lib/public/modules/command-palette.js +162 -40
- package/lib/public/modules/contextual-ask-session.js +26 -0
- package/lib/public/modules/contextual-clay-geometry.js +155 -0
- package/lib/public/modules/contextual-clay-session.js +130 -0
- package/lib/public/modules/contextual-clay-workspace.js +169 -0
- package/lib/public/modules/contextual-clay.js +250 -0
- package/lib/public/modules/contextual-composer.js +91 -0
- package/lib/public/modules/contextual-mate-context.js +117 -0
- package/lib/public/modules/contextual-mate-hint.js +40 -0
- package/lib/public/modules/contextual-mate-identity.js +23 -0
- package/lib/public/modules/contextual-mate-sessions.js +134 -0
- package/lib/public/modules/contextual-search.js +137 -0
- package/lib/public/modules/contextual-session-citations.js +58 -0
- package/lib/public/modules/debate.js +1 -0
- package/lib/public/modules/default-ai.js +11 -3
- package/lib/public/modules/elicitation-form.js +5 -0
- package/lib/public/modules/filebrowser.js +20 -1
- package/lib/public/modules/generation-stop.js +8 -5
- package/lib/public/modules/git-panel.js +3 -1
- package/lib/public/modules/history-replay-batch.js +13 -1
- package/lib/public/modules/home-debate-live.js +2 -0
- package/lib/public/modules/home-debate-planning.js +7 -7
- package/lib/public/modules/home-mate-avatar-editor.js +127 -208
- package/lib/public/modules/home-mate-chat.js +8 -6
- package/lib/public/modules/home-mate-creation.js +73 -1
- package/lib/public/modules/home-mate-settings.js +19 -12
- package/lib/public/modules/icon-strip-tooltip.js +2 -1
- package/lib/public/modules/input.js +88 -10
- package/lib/public/modules/issues-render.js +3 -2
- package/lib/public/modules/knowledge-db-workbench.js +4 -4
- package/lib/public/modules/markdown.js +6 -34
- package/lib/public/modules/mate-avatar-catalog.js +97 -0
- package/lib/public/modules/mate-knowledge-workbench.js +1 -1
- package/lib/public/modules/mate-management.js +40 -7
- package/lib/public/modules/mcp-connection-view.js +31 -13
- package/lib/public/modules/mcp-discovery-view.js +31 -0
- package/lib/public/modules/mcp-ui.js +23 -4
- package/lib/public/modules/mention.js +3 -0
- package/lib/public/modules/message-delivery.js +20 -2
- package/lib/public/modules/model-picker.js +2 -0
- package/lib/public/modules/pane-activation.js +214 -0
- package/lib/public/modules/pane-binding.js +82 -0
- package/lib/public/modules/pane-bridge.js +7 -4
- package/lib/public/modules/pane-browser-bridge.js +22 -0
- package/lib/public/modules/pane-file-bridge.js +4 -0
- package/lib/public/modules/pane-issue-bridge.js +4 -1
- package/lib/public/modules/passkey-browser.js +69 -0
- package/lib/public/modules/passkey-server-settings.js +57 -0
- package/lib/public/modules/pending-message-queue.js +1 -0
- package/lib/public/modules/permission-control.js +5 -4
- package/lib/public/modules/personal-settings-dialog.js +7 -1
- package/lib/public/modules/product-review.js +26 -0
- package/lib/public/modules/profile.js +1 -238
- package/lib/public/modules/project-access-recovery.js +17 -0
- package/lib/public/modules/project-admin-overview.js +21 -0
- package/lib/public/modules/project-chat-identity.js +13 -4
- package/lib/public/modules/project-logs-render.js +6 -2
- package/lib/public/modules/project-mate-navigation.js +144 -22
- package/lib/public/modules/rewind.js +5 -0
- package/lib/public/modules/scheduled-tasks.js +2 -0
- package/lib/public/modules/scheduler.js +2 -0
- package/lib/public/modules/search-clay-chat.js +5 -440
- package/lib/public/modules/server-settings-controls.js +10 -0
- package/lib/public/modules/server-settings.js +7 -2
- package/lib/public/modules/session-actions.js +5 -2
- package/lib/public/modules/session-context-menu.js +5 -0
- package/lib/public/modules/session-create-form.js +10 -10
- package/lib/public/modules/session-folder-layout.js +1 -1
- package/lib/public/modules/session-folder-view-menu.js +9 -0
- package/lib/public/modules/session-github.js +85 -14
- package/lib/public/modules/session-rich-drafts.js +21 -0
- package/lib/public/modules/session-switch-defer.js +67 -0
- package/lib/public/modules/session-work-primary.js +51 -0
- package/lib/public/modules/settings-defaults.js +27 -28
- package/lib/public/modules/shared-browser-settings.js +112 -0
- package/lib/public/modules/shared-browser-tabs.js +13 -3
- package/lib/public/modules/shared-browser.js +29 -6
- package/lib/public/modules/sidebar-mobile.js +4 -3
- package/lib/public/modules/sidebar-projects.js +1 -0
- package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
- package/lib/public/modules/sidebar-sessions.js +1 -0
- package/lib/public/modules/split-group-restore.js +68 -0
- package/lib/public/modules/split-pair-ui.js +1 -0
- package/lib/public/modules/split-pane-reconciler.js +15 -0
- package/lib/public/modules/split-pane-renderer.js +87 -6
- package/lib/public/modules/split-session-boundary.js +1 -1
- package/lib/public/modules/split-view.js +60 -68
- package/lib/public/modules/sticky-note-markdown.js +72 -6
- package/lib/public/modules/sticky-notes-actions.js +30 -0
- package/lib/public/modules/sticky-notes-browser.js +9 -2
- package/lib/public/modules/sticky-notes-card.js +23 -7
- package/lib/public/modules/sticky-notes-checklist.js +116 -0
- package/lib/public/modules/sticky-notes-editor.js +108 -44
- package/lib/public/modules/sticky-notes-shared.js +50 -2
- package/lib/public/modules/sticky-notes-state.js +66 -0
- package/lib/public/modules/sticky-notes.js +34 -51
- package/lib/public/modules/stt-controller.js +4 -1
- package/lib/public/modules/stt-recording.js +1 -1
- package/lib/public/modules/stt.js +7 -2
- package/lib/public/modules/terminal.js +9 -0
- package/lib/public/modules/theme.js +8 -1
- package/lib/public/modules/thinking-lifecycle.js +33 -3
- package/lib/public/modules/thinking-view.js +23 -1
- package/lib/public/modules/tools.js +60 -11
- package/lib/public/modules/tui-grab.js +1 -2
- package/lib/public/modules/user-settings-account.js +14 -1
- package/lib/public/modules/user-settings-appearance.js +10 -3
- package/lib/public/modules/user-settings-editors.js +1 -1
- package/lib/public/modules/user-settings-layout.js +11 -2
- package/lib/public/modules/user-settings-preferences.js +6 -2
- package/lib/public/modules/user-settings-profile.js +12 -2
- package/lib/public/modules/user-settings-sessions.js +120 -0
- package/lib/public/modules/user-settings.js +6 -2
- package/lib/public/modules/vendor-login-browser.js +5 -3
- package/lib/public/modules/vendor-login.js +2 -2
- package/lib/public/modules/vendor-priority.js +15 -1
- package/lib/public/modules/wireframe-workbench.js +5 -2
- package/lib/public/modules/you-activity.js +3 -1
- package/lib/public/modules/you.js +91 -6
- package/lib/public/muse-avatar.svg +4 -0
- package/lib/public/style.css +6 -0
- package/lib/public/sw.js +3 -1
- package/lib/safe-bash-commands.js +3 -45
- package/lib/scheduled-task-records.js +3 -1
- package/lib/scheduler.js +2 -0
- package/lib/sdk-bridge.js +342 -401
- package/lib/sdk-foreground-admission.js +16 -0
- package/lib/sdk-mcp-descriptors.js +2 -37
- package/lib/sdk-message-processor.js +52 -17
- package/lib/sdk-quota-snapshot.js +1 -1
- package/lib/sdk-response-recovery.js +1 -0
- package/lib/sdk-worker.js +2 -677
- package/lib/server-account-passkeys.js +186 -0
- package/lib/server-account-passwords.js +127 -0
- package/lib/server-account-security.js +53 -0
- package/lib/server-admin.js +63 -16
- package/lib/server-appearance-settings.js +13 -1
- package/lib/server-auth.js +107 -79
- package/lib/server-contextual-clay-settings.js +40 -0
- package/lib/server-contextual-mate-sessions.js +70 -0
- package/lib/server-dm.js +2 -1
- package/lib/server-global-ws.js +10 -20
- package/lib/server-home-chat-events.js +18 -4
- package/lib/server-home-chat.js +22 -20
- package/lib/server-home-clay-entry.js +23 -4
- package/lib/server-home-clay-session-links.js +29 -9
- package/lib/server-home-mate-creation.js +1 -0
- package/lib/server-home-mcp-consent.js +14 -0
- package/lib/server-mates.js +25 -62
- package/lib/server-owner-ui.js +118 -0
- package/lib/server-path-access.js +38 -0
- package/lib/server-project-removal.js +22 -0
- package/lib/server-settings.js +8 -2
- package/lib/server.js +165 -43
- package/lib/session-config-transition.js +45 -0
- package/lib/session-folders.js +7 -2
- package/lib/session-fork-history.js +21 -0
- package/lib/session-github.js +9 -2
- package/lib/session-hygiene.js +3 -35
- package/lib/session-permission-mode.js +4 -3
- package/lib/session-skill-scope.js +11 -0
- package/lib/session-visibility.js +5 -2
- package/lib/session-work-primary.js +50 -0
- package/lib/sessions.js +64 -99
- package/lib/shared-browser-cookie-sync.js +32 -0
- package/lib/shared-browser-cookies.js +79 -0
- package/lib/shared-browser-runtime.js +25 -9
- package/lib/shared-browser-storage-sync.js +43 -0
- package/lib/shared-browser-storage.js +101 -0
- package/lib/shared-browser-tools.js +2 -1
- package/lib/shared-browser-worker.js +46 -10
- package/lib/terminal-manager.js +65 -6
- package/lib/tool-llm.js +1 -1
- package/lib/tui-transcript-index.js +1 -132
- package/lib/user-knowledge-service.js +23 -1
- package/lib/users-auth.js +38 -3
- package/lib/users-contextual-clay-preferences.js +31 -0
- package/lib/users-create.js +97 -0
- package/lib/users-permissions.js +2 -8
- package/lib/users-server-pin.js +37 -0
- package/lib/users.js +18 -84
- package/lib/vendor-login-browser.js +1 -11
- package/lib/workspace-assignment-service.js +25 -0
- package/lib/workspace-query-access.js +4 -1
- package/lib/workspace-query-mcp-server.js +1 -1
- package/lib/workspace-query-service.js +13 -2
- package/lib/ws-request.js +1 -0
- package/lib/ws-schema.js +18 -2
- package/lib/yoke/acp-agent-profiles.js +7 -5
- package/lib/yoke/adapters/antigravity.js +3 -14
- package/lib/yoke/adapters/claude-query-contract.js +9 -0
- package/lib/yoke/adapters/claude.js +54 -50
- package/lib/yoke/adapters/codex-query-contract.js +24 -0
- package/lib/yoke/adapters/codex.js +53 -111
- package/lib/yoke/adapters/kiro.js +3 -1
- package/lib/yoke/adapters/muse-query-contract.js +7 -0
- package/lib/yoke/adapters/muse.js +122 -0
- package/lib/yoke/auth-events.js +17 -0
- package/lib/yoke/claude-hook-installer.js +271 -0
- package/lib/yoke/claude-jsonl-watcher.js +204 -0
- package/lib/yoke/claude-maintenance.js +55 -0
- package/lib/yoke/claude-permission-patterns.js +53 -0
- package/lib/yoke/claude-response-recovery.js +155 -0
- package/lib/yoke/claude-transcript-hygiene.js +34 -0
- package/lib/yoke/claude-worker-startup.js +28 -0
- package/lib/yoke/clay-skill-install.js +33 -0
- package/lib/yoke/cli-sessions.js +300 -0
- package/lib/yoke/codex-app-server.js +7 -12
- package/lib/yoke/codex-idle-recovery.js +81 -1
- package/lib/yoke/codex-recovery-admission.js +164 -0
- package/lib/yoke/configuration.js +13 -0
- package/lib/yoke/discovery.js +70 -0
- package/lib/yoke/errors.js +8 -0
- package/lib/yoke/host-environment.js +7 -0
- package/lib/yoke/index.js +9 -51
- package/lib/yoke/interface.js +116 -0
- package/lib/yoke/kiro-acp-server.js +5 -5
- package/lib/yoke/legacy-sessions.js +89 -0
- package/lib/yoke/login-protocol.js +25 -0
- package/lib/yoke/maintenance.js +12 -0
- package/lib/yoke/mcp-proxy.js +32 -0
- package/lib/yoke/mcp-source-adapters.js +91 -0
- package/lib/yoke/mcp-source-context.js +42 -0
- package/lib/yoke/mcp-source-discovery.js +169 -0
- package/lib/yoke/mcp-source-plugins.js +68 -0
- package/lib/yoke/mcp-source-restrictions.js +47 -0
- package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
- package/lib/yoke/model-preferences.js +6 -0
- package/lib/yoke/muse-artifacts.js +36 -0
- package/lib/yoke/muse-controls.js +50 -0
- package/lib/yoke/muse-input.js +64 -0
- package/lib/yoke/muse-items.js +157 -0
- package/lib/yoke/muse-policy.js +52 -0
- package/lib/yoke/muse-query.js +428 -0
- package/lib/yoke/muse-runtime.js +211 -0
- package/lib/yoke/muse-services.js +79 -0
- package/lib/yoke/muse-skills.js +79 -0
- package/lib/yoke/muse-turns.js +71 -0
- package/lib/yoke/options/acp.js +2 -0
- package/lib/yoke/options/antigravity.js +2 -0
- package/lib/yoke/options/claude.js +21 -0
- package/lib/yoke/options/codex-defaults.js +29 -0
- package/lib/yoke/options/codex-settings.js +21 -0
- package/lib/yoke/options/codex.js +6 -0
- package/lib/yoke/options/kiro-defaults.js +22 -0
- package/lib/yoke/options/kiro.js +5 -0
- package/lib/yoke/options/muse.js +5 -0
- package/lib/yoke/provider-contract.js +5 -0
- package/lib/yoke/providers/antigravity-executable.js +8 -0
- package/lib/yoke/providers/claude-executable.js +40 -0
- package/lib/yoke/providers/claude-model-descriptions.js +14 -0
- package/lib/yoke/providers/claude-process.js +97 -0
- package/lib/yoke/providers/claude-provision.js +75 -0
- package/lib/yoke/providers/codex-errors.js +8 -0
- package/lib/yoke/providers/muse-executable.js +17 -0
- package/lib/yoke/provisioning.js +6 -0
- package/lib/yoke/query-options.js +10 -0
- package/lib/yoke/response-recovery.js +41 -0
- package/lib/yoke/sdk-mcp-descriptors.js +37 -0
- package/lib/yoke/sdk-server-factory.js +7 -0
- package/lib/yoke/session-history.js +8 -0
- package/lib/yoke/session-tool-transport.js +34 -13
- package/lib/yoke/settings.js +23 -0
- package/lib/yoke/source-locations.js +4 -0
- package/lib/yoke/title-query.js +18 -7
- package/lib/yoke/tui-transcript-index.js +132 -0
- package/lib/yoke/usage.js +48 -0
- package/lib/yoke/user-input.js +13 -0
- package/lib/yoke/vendor-registry.js +81 -1
- package/package.json +11 -4
|
@@ -93,42 +93,6 @@ var MODE_OPTIONS = [
|
|
|
93
93
|
var MODE_FULL_AUTO = { value: "auto", label: "Auto" };
|
|
94
94
|
var MODE_SKIP = { value: "bypassPermissions", label: "Skip permissions" };
|
|
95
95
|
var EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
|
|
96
|
-
var EFFORT_LEVELS_BY_VENDOR = {
|
|
97
|
-
claude: ["low", "medium", "high", "xhigh", "max"],
|
|
98
|
-
codex: ["low", "medium", "high", "xhigh", "max"],
|
|
99
|
-
antigravity: [],
|
|
100
|
-
opencode: [],
|
|
101
|
-
kiro: ["low", "medium", "high", "xhigh", "max"],
|
|
102
|
-
};
|
|
103
|
-
var THINKING_OPTIONS = ["disabled", "adaptive", "budget"];
|
|
104
|
-
var CODEX_APPROVAL_OPTIONS = [
|
|
105
|
-
{ value: "never", label: "Auto" },
|
|
106
|
-
{ value: "untrusted", label: "Untrusted" },
|
|
107
|
-
{ value: "on-request", label: "Ask" },
|
|
108
|
-
];
|
|
109
|
-
var CODEX_SANDBOX_OPTIONS = [
|
|
110
|
-
{ value: "read-only", label: "Read Only" },
|
|
111
|
-
{ value: "workspace-write", label: "Workspace" },
|
|
112
|
-
{ value: "danger-full-access", label: "Full Access" },
|
|
113
|
-
];
|
|
114
|
-
var CODEX_WEBSEARCH_OPTIONS = [
|
|
115
|
-
{ value: "disabled", label: "Off" },
|
|
116
|
-
{ value: "cached", label: "Cached" },
|
|
117
|
-
{ value: "live", label: "Live" },
|
|
118
|
-
];
|
|
119
|
-
var KNOWN_CONTEXT_WINDOWS = {
|
|
120
|
-
"opus-4-6": 1000000,
|
|
121
|
-
"claude-sonnet-4": 1000000,
|
|
122
|
-
"gpt-6-astra": 1050000,
|
|
123
|
-
"gpt-5.6": 1050000,
|
|
124
|
-
"gpt-5.5": 1048576,
|
|
125
|
-
"gpt-5.4": 1048576,
|
|
126
|
-
"gpt-5.3": 1048576,
|
|
127
|
-
"gpt-5.2": 1048576,
|
|
128
|
-
"gpt-4.1": 1047576,
|
|
129
|
-
"o3": 200000,
|
|
130
|
-
"o4-mini": 200000,
|
|
131
|
-
};
|
|
132
96
|
// Categories to hide from the legend (noise, not actionable)
|
|
133
97
|
var CTX_HIDDEN_CATS = { "Free space": 1, "Autocompact buffer": 1 };
|
|
134
98
|
|
|
@@ -160,12 +124,12 @@ export function effortDisplayName(value) {
|
|
|
160
124
|
// uses this for sessions other than the active one). Falls back from the
|
|
161
125
|
// model's own supportedEffortLevels to the vendor table.
|
|
162
126
|
export function effortLevelsFor(vendor, models, modelValue) {
|
|
163
|
-
var defaults =
|
|
127
|
+
var defaults = ((store.get("vendorInfo") || {})[vendor] || {}).effortLevels || [];
|
|
164
128
|
var list = models || [];
|
|
165
129
|
for (var i = 0; i < list.length; i++) {
|
|
166
130
|
var value = typeof list[i] === "string" ? list[i] : (list[i] && (list[i].value || list[i].id)) || "";
|
|
167
131
|
if (value === modelValue) {
|
|
168
|
-
if (
|
|
132
|
+
if (Array.isArray(list[i].supportedEffortLevels)) {
|
|
169
133
|
return list[i].supportedEffortLevels;
|
|
170
134
|
}
|
|
171
135
|
return defaults;
|
|
@@ -182,9 +146,8 @@ function thinkingDisplayName(value) {
|
|
|
182
146
|
}
|
|
183
147
|
|
|
184
148
|
function isSonnetModel(model) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
return lower.indexOf("sonnet") !== -1;
|
|
149
|
+
var models = store.get("currentModels") || [];
|
|
150
|
+
return models.some(function(entry) { return entry && entry.value === model && entry.supportsBetaContext === true; });
|
|
188
151
|
}
|
|
189
152
|
|
|
190
153
|
function hasBeta(name) {
|
|
@@ -198,7 +161,7 @@ function hasBeta(name) {
|
|
|
198
161
|
function rebuildModeList() {
|
|
199
162
|
if (!configModeList) return;
|
|
200
163
|
configModeList.innerHTML = "";
|
|
201
|
-
var options =
|
|
164
|
+
var options = (providerConfiguration().permissionModes || []).slice();
|
|
202
165
|
options.push(MODE_FULL_AUTO);
|
|
203
166
|
options.push(MODE_SKIP);
|
|
204
167
|
var autoSupported = store.get('permissionCapabilities').auto === true;
|
|
@@ -212,8 +175,8 @@ function rebuildModeList() {
|
|
|
212
175
|
btn.textContent = opt.label;
|
|
213
176
|
if (opt.value === "auto" && !autoSupported) {
|
|
214
177
|
btn.disabled = true;
|
|
215
|
-
btn.title = "Auto permissions
|
|
216
|
-
btn.setAttribute("aria-description", "
|
|
178
|
+
btn.title = "Auto permissions are unavailable for this session.";
|
|
179
|
+
btn.setAttribute("aria-description", "The current runtime does not support Auto permissions.");
|
|
217
180
|
}
|
|
218
181
|
if (globallyForced) {
|
|
219
182
|
btn.disabled = true;
|
|
@@ -232,13 +195,13 @@ function rebuildModeList() {
|
|
|
232
195
|
function rebuildEffortBar() {
|
|
233
196
|
if (!configEffortBar || !configEffortSection) return;
|
|
234
197
|
var supportsEffort = getModelSupportsEffort();
|
|
235
|
-
|
|
198
|
+
var levels = getModelEffortLevels();
|
|
199
|
+
if (!supportsEffort || !levels.length) {
|
|
236
200
|
configEffortSection.style.display = "none";
|
|
237
201
|
return;
|
|
238
202
|
}
|
|
239
203
|
configEffortSection.style.display = "";
|
|
240
204
|
configEffortBar.innerHTML = "";
|
|
241
|
-
var levels = getModelEffortLevels();
|
|
242
205
|
for (var i = 0; i < levels.length; i++) {
|
|
243
206
|
var level = levels[i];
|
|
244
207
|
var btn = document.createElement("button");
|
|
@@ -277,8 +240,9 @@ function rebuildThinkingSection() {
|
|
|
277
240
|
configThinkingSection.style.display = "";
|
|
278
241
|
configThinkingBar.innerHTML = "";
|
|
279
242
|
var s = store.snap();
|
|
280
|
-
|
|
281
|
-
|
|
243
|
+
var thinkingOptions = (providerConfiguration().thinking || {}).options || [];
|
|
244
|
+
for (var i = 0; i < thinkingOptions.length; i++) {
|
|
245
|
+
var opt = thinkingOptions[i];
|
|
282
246
|
var btn = document.createElement("button");
|
|
283
247
|
btn.className = "config-segment-btn";
|
|
284
248
|
if (opt === s.currentThinking) btn.classList.add("active");
|
|
@@ -329,22 +293,21 @@ function buildSegmentedBar(barEl, options, currentValue, msgType, msgKey) {
|
|
|
329
293
|
}
|
|
330
294
|
}
|
|
331
295
|
|
|
332
|
-
function
|
|
333
|
-
var
|
|
334
|
-
|
|
296
|
+
function providerConfiguration() {
|
|
297
|
+
var state = store.snap();
|
|
298
|
+
return ((state.vendorInfo || {})[state.currentVendor] || {}).configuration || {};
|
|
299
|
+
}
|
|
335
300
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
if (isCodex) buildSegmentedBar(configSandboxBar, CODEX_SANDBOX_OPTIONS, s.codexSandbox, "set_codex_sandbox", "sandbox");
|
|
343
|
-
}
|
|
344
|
-
if (configWebsearchSection) {
|
|
345
|
-
configWebsearchSection.style.display = isCodex ? "" : "none";
|
|
346
|
-
if (isCodex) buildSegmentedBar(configWebsearchBar, CODEX_WEBSEARCH_OPTIONS, s.codexWebSearch, "set_codex_websearch", "webSearch");
|
|
301
|
+
function rebuildProviderSections() {
|
|
302
|
+
var state = store.snap(), config = providerConfiguration();
|
|
303
|
+
function section(element, bar, description) {
|
|
304
|
+
if (!element) return;
|
|
305
|
+
element.style.display = description ? "" : "none";
|
|
306
|
+
if (description) buildSegmentedBar(bar, description.options || [], state[description.state], description.message, description.key);
|
|
347
307
|
}
|
|
308
|
+
section(configApprovalSection, configApprovalBar, config.approval);
|
|
309
|
+
section(configSandboxSection, configSandboxBar, config.sandbox);
|
|
310
|
+
section(configWebsearchSection, configWebsearchBar, config.webSearch);
|
|
348
311
|
}
|
|
349
312
|
|
|
350
313
|
function escHtml(s) {
|
|
@@ -584,25 +547,17 @@ export function updateConfigChip() {
|
|
|
584
547
|
if (!configChipWrap || !configChip) return;
|
|
585
548
|
configChipWrap.classList.remove("hidden");
|
|
586
549
|
var s = store.snap();
|
|
587
|
-
var vendor = s.currentVendor || "claude";
|
|
588
550
|
configChipLabel.textContent = modelDisplayName(s.currentModel, s.currentModels);
|
|
589
551
|
renderModelPicker();
|
|
590
552
|
rebuildModeList();
|
|
591
553
|
rebuildEffortBar();
|
|
592
554
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
if (configModeList && configModeList.parentElement) configModeList.parentElement.style.display = isClaude ? "" : "none";
|
|
555
|
+
var configuration = providerConfiguration();
|
|
556
|
+
if (configModeList && configModeList.parentElement) configModeList.parentElement.style.display = configuration.permissionModes ? "" : "none";
|
|
596
557
|
rebuildThinkingSection();
|
|
597
|
-
|
|
598
|
-
// vendor), NOT "accepts thinking config". The adaptive/extended toggle and
|
|
599
|
-
// budget only feed Claude queries (sm.currentThinking), so the section
|
|
600
|
-
// stays Claude-only until a dedicated thinkingConfig capability exists.
|
|
601
|
-
if (configThinkingSection) configThinkingSection.style.display = isClaude ? "" : "none";
|
|
602
|
-
// BETA section deprecated (1M context is now standard)
|
|
558
|
+
if (configThinkingSection) configThinkingSection.style.display = configuration.thinking ? "" : "none";
|
|
603
559
|
if (configBetaSection) configBetaSection.style.display = "none";
|
|
604
|
-
|
|
605
|
-
rebuildCodexSections();
|
|
560
|
+
rebuildProviderSections();
|
|
606
561
|
}
|
|
607
562
|
|
|
608
563
|
export function getModelSupportsEffort() {
|
|
@@ -645,10 +600,10 @@ export function accumulateUsage(cost, usage) {
|
|
|
645
600
|
// Assign directly instead of summing to avoid overcounting.
|
|
646
601
|
if (cost != null) sessionUsage.cost = cost;
|
|
647
602
|
if (usage) {
|
|
648
|
-
sessionUsage.input += usage.
|
|
649
|
-
sessionUsage.output += usage.
|
|
650
|
-
sessionUsage.cacheRead += usage.
|
|
651
|
-
sessionUsage.cacheWrite += usage.
|
|
603
|
+
sessionUsage.input += usage.inputTokens || 0;
|
|
604
|
+
sessionUsage.output += usage.outputTokens || 0;
|
|
605
|
+
sessionUsage.cacheRead += usage.cacheReadInputTokens || 0;
|
|
606
|
+
sessionUsage.cacheWrite += usage.cacheCreationInputTokens || 0;
|
|
652
607
|
}
|
|
653
608
|
sessionUsage.turns++;
|
|
654
609
|
if (!store.get('replayingHistory')) updateUsagePanel();
|
|
@@ -724,14 +679,8 @@ export function toggleStatusPanel() {
|
|
|
724
679
|
|
|
725
680
|
// --- Context panel ---
|
|
726
681
|
|
|
727
|
-
export function resolveContextWindow(model,
|
|
728
|
-
|
|
729
|
-
if (lc.includes("[1m]")) return 1000000;
|
|
730
|
-
if (sdkValue) return sdkValue;
|
|
731
|
-
for (var key in KNOWN_CONTEXT_WINDOWS) {
|
|
732
|
-
if (lc.includes(key)) return KNOWN_CONTEXT_WINDOWS[key];
|
|
733
|
-
}
|
|
734
|
-
return 200000;
|
|
682
|
+
export function resolveContextWindow(model, reported) {
|
|
683
|
+
return typeof reported === "number" && reported > 0 ? reported : 0;
|
|
735
684
|
}
|
|
736
685
|
|
|
737
686
|
export function contextPctClass(pct) {
|
|
@@ -744,21 +693,21 @@ export function updateContextPanel() {
|
|
|
744
693
|
// only supplies currentInput from a verified last-turn snapshot; rich
|
|
745
694
|
// context usage is more authoritative when available.
|
|
746
695
|
var rich = store.get('richContextUsage');
|
|
747
|
-
var
|
|
748
|
-
|
|
749
|
-
(typeof rich.input_tokens === "number" && typeof rich.contextWindow === "number" && rich.contextWindow > 0)
|
|
750
|
-
);
|
|
696
|
+
var richContext = rich && rich.context;
|
|
697
|
+
var hasRich = richContext && typeof richContext.usedTokens === "number" && typeof richContext.windowTokens === "number" && richContext.windowTokens > 0;
|
|
751
698
|
var hasCurrent = typeof contextData.currentInput === "number";
|
|
752
699
|
var hasContext = !!(hasRich || hasCurrent);
|
|
753
|
-
var used = hasRich ?
|
|
754
|
-
var win = hasRich ?
|
|
700
|
+
var used = hasRich ? richContext.usedTokens : (hasCurrent ? contextData.currentInput : 0);
|
|
701
|
+
var win = hasRich ? richContext.windowTokens : (hasCurrent ? contextData.contextWindow : 0);
|
|
702
|
+
hasContext = hasContext && win > 0;
|
|
703
|
+
var measurement = hasRich ? richContext.measurement : store.get("contextMeasurement");
|
|
755
704
|
var pct = win > 0 ? Math.min(100, (used / win) * 100) : 0;
|
|
756
705
|
var cls = contextPctClass(pct);
|
|
757
706
|
reportPaneContext({ pct: pct, used: used, win: win, cls: cls, model: contextData.model, cost: contextData.cost });
|
|
758
707
|
// Panel bar
|
|
759
708
|
contextBarFill.style.width = pct.toFixed(1) + "%";
|
|
760
709
|
contextBarFill.className = "context-bar-fill" + cls;
|
|
761
|
-
contextBarPct.textContent = pct.toFixed(0) + "%";
|
|
710
|
+
contextBarPct.textContent = hasContext ? pct.toFixed(0) + "%" : "-";
|
|
762
711
|
// Mini bar
|
|
763
712
|
if (contextMiniFill) {
|
|
764
713
|
contextMiniFill.style.width = pct.toFixed(1) + "%";
|
|
@@ -807,7 +756,8 @@ export function updateContextPanel() {
|
|
|
807
756
|
}
|
|
808
757
|
}
|
|
809
758
|
}
|
|
810
|
-
contextUsedEl.textContent = formatTokens(used);
|
|
759
|
+
contextUsedEl.textContent = hasRich || hasCurrent ? (measurement === "estimated" ? "~" : "") + formatTokens(used) : "-";
|
|
760
|
+
contextUsedEl.title = hasRich || hasCurrent ? (measurement === "estimated" ? "Estimated current context" : "Observed current context") : "Current context unavailable";
|
|
811
761
|
contextWindowEl.textContent = win > 0 ? formatTokens(win) : "-";
|
|
812
762
|
contextMaxOutputEl.textContent = contextData.maxOutputTokens > 0 ? formatTokens(contextData.maxOutputTokens) : "-";
|
|
813
763
|
contextInputEl.textContent = formatTokens(contextData.input);
|
|
@@ -829,7 +779,13 @@ export function updateContextPanel() {
|
|
|
829
779
|
contextTurnsEl.textContent = String(contextData.turns);
|
|
830
780
|
}
|
|
831
781
|
|
|
832
|
-
export function accumulateContext(cost, usage, modelUsage, lastStreamInputTokens) {
|
|
782
|
+
export function accumulateContext(cost, usage, modelUsage, lastStreamInputTokens, context) {
|
|
783
|
+
if (context) {
|
|
784
|
+
if (context.source === "last_turn") store.set({ richContextUsage: null });
|
|
785
|
+
store.set({ contextMeasurement: context.measurement || "unavailable" });
|
|
786
|
+
contextData.currentInput = typeof context.usedTokens === "number" ? context.usedTokens : null;
|
|
787
|
+
if (typeof context.windowTokens === "number") contextData.contextWindow = context.windowTokens;
|
|
788
|
+
}
|
|
833
789
|
// cost is the SDK's total_cost_usd -- a cumulative running total, not a delta.
|
|
834
790
|
if (cost != null) contextData.cost = cost;
|
|
835
791
|
// Use latest turn values (not cumulative) since each turn's input_tokens
|
|
@@ -842,17 +798,14 @@ export function accumulateContext(cost, usage, modelUsage, lastStreamInputTokens
|
|
|
842
798
|
if (typeof lastStreamInputTokens === "number") {
|
|
843
799
|
contextData.input = lastStreamInputTokens;
|
|
844
800
|
} else {
|
|
845
|
-
contextData.input = (usage.
|
|
846
|
-
+ (usage.
|
|
847
|
-
}
|
|
848
|
-
contextData.output = usage.output_tokens || usage.outputTokens || 0;
|
|
849
|
-
contextData.cacheRead = usage.cache_read_input_tokens || usage.cacheReadInputTokens || 0;
|
|
850
|
-
contextData.cacheWrite = usage.cache_creation_input_tokens || usage.cacheCreationInputTokens || 0;
|
|
851
|
-
if (store.get('currentVendor') === "codex") {
|
|
852
|
-
contextData.currentInput = typeof lastStreamInputTokens === "number" ? lastStreamInputTokens : null;
|
|
853
|
-
} else {
|
|
854
|
-
contextData.currentInput = typeof lastStreamInputTokens === "number" ? lastStreamInputTokens : contextData.input;
|
|
801
|
+
contextData.input = (usage.inputTokens || 0)
|
|
802
|
+
+ (usage.cacheReadInputTokens || 0);
|
|
855
803
|
}
|
|
804
|
+
contextData.output = usage.outputTokens || 0;
|
|
805
|
+
contextData.cacheRead = usage.cacheReadInputTokens || 0;
|
|
806
|
+
contextData.cacheWrite = usage.cacheCreationInputTokens || 0;
|
|
807
|
+
contextData.currentInput = context && typeof context.usedTokens === "number" ? context.usedTokens : null;
|
|
808
|
+
if (context && typeof context.windowTokens === "number") contextData.contextWindow = context.windowTokens;
|
|
856
809
|
}
|
|
857
810
|
contextData.turns++;
|
|
858
811
|
if (modelUsage) {
|
|
@@ -864,23 +817,8 @@ export function accumulateContext(cost, usage, modelUsage, lastStreamInputTokens
|
|
|
864
817
|
// (e.g. CLI reports "claude-sonnet-4-6" even when running as opus[1m])
|
|
865
818
|
var displayModel = store.get('currentModel') || m;
|
|
866
819
|
contextData.model = displayModel;
|
|
867
|
-
contextData.contextWindow = resolveContextWindow(displayModel, mu.contextWindow);
|
|
820
|
+
contextData.contextWindow = context && typeof context.windowTokens === "number" ? context.windowTokens : resolveContextWindow(displayModel, mu.contextWindow);
|
|
868
821
|
if (mu.maxOutputTokens) contextData.maxOutputTokens = mu.maxOutputTokens;
|
|
869
|
-
if (store.get('currentVendor') === "codex") {
|
|
870
|
-
var snapshot = mu.contextSnapshot;
|
|
871
|
-
if (snapshot) store.set({ richContextUsage: null });
|
|
872
|
-
if (snapshot && snapshot.valid === true
|
|
873
|
-
&& typeof snapshot.inputTokens === "number"
|
|
874
|
-
&& typeof snapshot.contextWindow === "number"
|
|
875
|
-
&& snapshot.contextWindow > 0) {
|
|
876
|
-
contextData.currentInput = snapshot.inputTokens;
|
|
877
|
-
contextData.contextWindow = snapshot.contextWindow;
|
|
878
|
-
} else {
|
|
879
|
-
// An explicit invalid marker is authoritative: do not retain an
|
|
880
|
-
// occupancy value from the previous live turn or history replay.
|
|
881
|
-
contextData.currentInput = null;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
822
|
|
|
885
823
|
// thinkingTokens and costBasis are per-model and optional: absent on
|
|
886
824
|
// older CLI builds and, for a resumed session, on the turns that ran
|
|
@@ -1009,8 +947,8 @@ export function renderCtxPopover() {
|
|
|
1009
947
|
if (!ctxPopoverEl || !richContextUsage) return;
|
|
1010
948
|
var d = richContextUsage;
|
|
1011
949
|
var cats = d.categories || [];
|
|
1012
|
-
var total = d.
|
|
1013
|
-
var max = d.
|
|
950
|
+
var total = d.context && d.context.usedTokens || 0;
|
|
951
|
+
var max = d.context && d.context.windowTokens || 0;
|
|
1014
952
|
var pct = d.percentage != null ? d.percentage : (max > 0 ? (total / max) * 100 : 0);
|
|
1015
953
|
|
|
1016
954
|
var html = "";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { prepareContextualWorkspaceDeparture } from './contextual-clay-workspace.js';
|
|
2
|
+
import { checkComposerDeparture, saveSessionRichDraft } from './session-rich-drafts.js';
|
|
1
3
|
// app-projects.js - Project list, switching, add/remove project modals
|
|
2
4
|
// Extracted from app.js (PR-29)
|
|
3
5
|
|
|
@@ -311,6 +313,7 @@ export function renderProjectList() {
|
|
|
311
313
|
}).map(function (p) {
|
|
312
314
|
return {
|
|
313
315
|
slug: p.slug,
|
|
316
|
+
controlRuntimeId: p.controlRuntimeId || null,
|
|
314
317
|
name: p.title || p.project,
|
|
315
318
|
icon: p.icon || null,
|
|
316
319
|
isProcessing: p.isProcessing,
|
|
@@ -389,6 +392,16 @@ export function resetClientState() {
|
|
|
389
392
|
|
|
390
393
|
export function switchProject(slug) {
|
|
391
394
|
if (!slug) return;
|
|
395
|
+
if (slug !== store.get('currentSlug')) {
|
|
396
|
+
try { checkComposerDeparture(); saveSessionRichDraft(); }
|
|
397
|
+
catch (error) { showToast(error.message, 'warn'); return; }
|
|
398
|
+
}
|
|
399
|
+
if (prepareContextualWorkspaceDeparture(slug) === false) return;
|
|
400
|
+
var target = cachedProjects.find(function (project) { return project.slug === slug; });
|
|
401
|
+
if (target && target.contentAccess === false && target.administrativeAccess === true) {
|
|
402
|
+
window.location.assign("/p/" + encodeURIComponent(slug) + "/");
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
392
405
|
document.cookie = "clay_last_project=" + encodeURIComponent(slug) + "; Path=/; SameSite=Strict; Max-Age=31536000";
|
|
393
406
|
var st = store.snap();
|
|
394
407
|
var ws = getWs();
|
|
@@ -22,34 +22,15 @@ function getVendorUsageMeta(vendor) {
|
|
|
22
22
|
var vendors = store.get('vendorInfo') || {};
|
|
23
23
|
var info = vendors[vendor];
|
|
24
24
|
if (info && info.usageDashboard) return info.usageDashboard;
|
|
25
|
-
|
|
26
|
-
codex: {
|
|
27
|
-
icon: "/codex-avatar.png",
|
|
28
|
-
alt: "Codex",
|
|
29
|
-
href: "https://chatgpt.com/codex/settings/usage",
|
|
30
|
-
title: "Check usage on ChatGPT",
|
|
31
|
-
},
|
|
32
|
-
claude: {
|
|
33
|
-
icon: "/claude-code-avatar.png",
|
|
34
|
-
alt: "Claude Code",
|
|
35
|
-
href: "https://claude.ai/settings/usage",
|
|
36
|
-
title: "Check usage on claude.ai",
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
return fallbacks[vendor] || null;
|
|
25
|
+
return null;
|
|
40
26
|
}
|
|
41
27
|
|
|
42
28
|
function vendorTracksRateLimits(vendor) {
|
|
43
|
-
|
|
44
|
-
var info = vendors[vendor];
|
|
45
|
-
if (info) return info.rateLimitTracking !== false;
|
|
46
|
-
var legacyTrackedVendors = ["claude", "codex"];
|
|
47
|
-
return legacyTrackedVendors.indexOf(vendor) !== -1;
|
|
29
|
+
return ((store.get('vendorInfo') || {})[vendor] || {}).rateLimitTracking === true;
|
|
48
30
|
}
|
|
49
31
|
|
|
50
32
|
function vendorSupportsScheduledMessages(vendor) {
|
|
51
|
-
|
|
52
|
-
return scheduledMessageVendors.indexOf(vendor) !== -1;
|
|
33
|
+
return ((store.get('vendorInfo') || {})[vendor] || {}).rateLimitScheduling === true;
|
|
53
34
|
}
|
|
54
35
|
|
|
55
36
|
function rateLimitEventAppliesToPane(msg, state) {
|
|
@@ -60,7 +41,7 @@ function rateLimitEventAppliesToPane(msg, state) {
|
|
|
60
41
|
if (msg.vendor) return msg.vendor === activeVendor;
|
|
61
42
|
// Legacy Claude records predate vendor/session stamps. Never project them
|
|
62
43
|
// into a non-Claude pane, where they would look like Claude usage.
|
|
63
|
-
return activeVendor ===
|
|
44
|
+
return ((state.vendorInfo || {})[activeVendor] || {}).acceptsUnstampedQuota === true;
|
|
64
45
|
}
|
|
65
46
|
|
|
66
47
|
function rateLimitStateKey(sessionId, vendor) {
|
|
@@ -84,7 +65,6 @@ function setActiveRateLimitState(next) {
|
|
|
84
65
|
}
|
|
85
66
|
|
|
86
67
|
function extraUsageDescription(msg) {
|
|
87
|
-
if (msg.vendor && msg.vendor !== "claude") return "";
|
|
88
68
|
var reason = msg.overageDisabledReason;
|
|
89
69
|
if (reason === "out_of_credits") return "Extra usage has no credits remaining";
|
|
90
70
|
if (reason === "fetch_error") return "Extra usage availability could not be checked";
|
|
@@ -350,7 +330,7 @@ export function initRateLimit() {
|
|
|
350
330
|
export function handleRateLimitEvent(msg) {
|
|
351
331
|
if (!rateLimitEventAppliesToPane(msg, store.snap())) return;
|
|
352
332
|
// Old Codex history contains quota snapshots misrecorded as rejections.
|
|
353
|
-
if (msg.
|
|
333
|
+
if (msg.ignored === true) return;
|
|
354
334
|
if (msg.resetsAt && msg.resetsAt <= Date.now()) {
|
|
355
335
|
var expiredState = Object.assign({}, getActiveRateLimitState());
|
|
356
336
|
if (msg.rateLimitType) delete expiredState[msg.rateLimitType];
|
|
@@ -408,12 +388,12 @@ export function handleRateLimitEvent(msg) {
|
|
|
408
388
|
|
|
409
389
|
export function updateRateLimitUsage(msg) {
|
|
410
390
|
if (!rateLimitEventAppliesToPane(msg, store.snap())) return;
|
|
411
|
-
if (msg.
|
|
391
|
+
if (msg.source === "account_snapshot" && Array.isArray(msg.quotaWindows)) {
|
|
412
392
|
applyQuotaSnapshot(msg);
|
|
413
393
|
renderRateLimitUsage();
|
|
414
394
|
return;
|
|
415
395
|
}
|
|
416
|
-
if (msg.
|
|
396
|
+
if (msg.ignored === true) return;
|
|
417
397
|
var activeVendor = store.get('currentVendor') || "claude";
|
|
418
398
|
if (!vendorTracksRateLimits(activeVendor)) {
|
|
419
399
|
renderRateLimitUsage();
|
|
@@ -8,10 +8,10 @@ import { refreshIcons } from './icons.js';
|
|
|
8
8
|
import { closeToolGroup } from './tools.js';
|
|
9
9
|
import { sendMessage, hasSendableContent } from './input.js';
|
|
10
10
|
import { getChatLayout } from './theme.js';
|
|
11
|
-
import { addToMessages, scrollToBottom, forceScrollToBottom, getMsgTime, shouldGroupMessage, getTurnCounter, getActivityEl } from './chat-render-runtime.js';
|
|
11
|
+
import { addToMessages, addHistoryIndex, scrollToBottom, forceScrollToBottom, getMsgTime, shouldGroupMessage, getTurnCounter, getActivityEl } from './chat-render-runtime.js';
|
|
12
12
|
import { resolveProjectAssistantIdentity, applyProjectAssistantIdentity } from './project-chat-identity.js';
|
|
13
13
|
export { VENDOR_ORDER, EXPERIMENTAL_VENDORS, isExperimentalVendor } from './vendor-priority.js';
|
|
14
|
-
export { initRendering, addToMessages, scrollToBottom, forceScrollToBottom, getMsgTime, shouldGroupMessage, getTurnCounter, setTurnCounter, getPrependAnchor, setPrependAnchor, getActivityEl, setActivityEl, getIsUserScrolledUp, setIsUserScrolledUp, getStickyBottom, armStickyBottom, disarmStickyBottom, VENDOR_AVATARS, VENDOR_NAMES, VENDOR_HOMEPAGES } from './chat-render-runtime.js';
|
|
14
|
+
export { initRendering, addToMessages, addHistoryIndex, scrollToBottom, forceScrollToBottom, getMsgTime, shouldGroupMessage, getTurnCounter, setTurnCounter, getPrependAnchor, setPrependAnchor, getActivityEl, setActivityEl, getIsUserScrolledUp, setIsUserScrolledUp, getStickyBottom, armStickyBottom, disarmStickyBottom, VENDOR_AVATARS, VENDOR_NAMES, VENDOR_HOMEPAGES } from './chat-render-runtime.js';
|
|
15
15
|
export { addUserMessage, addSystemMessage, addConflictMessage, addContextOverflowMessage } from './app-message-cards.js';
|
|
16
16
|
|
|
17
17
|
// --- Module-owned state (not in store) ---
|
|
@@ -44,7 +44,8 @@ export function addCopyHandler(msgEl, rawText) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export function appendDelta(text) {
|
|
47
|
-
ensureAssistantBlock();
|
|
47
|
+
var assistantEl = ensureAssistantBlock();
|
|
48
|
+
if (store.get('replayingHistory')) addHistoryIndex(assistantEl, store.get('currentHistoryIndexes') || store.get('currentHistoryIndex'));
|
|
48
49
|
streamBuffer += text;
|
|
49
50
|
if (store.get('replayingHistory')) {
|
|
50
51
|
store.set({ currentFullText: store.get('currentFullText') + streamBuffer });
|
|
@@ -1,37 +1,11 @@
|
|
|
1
1
|
// Centralized local avatar URL builder for people and Mates.
|
|
2
|
-
import { imprintDataUrl
|
|
3
|
-
|
|
4
|
-
var mateMarkCache = new Map();
|
|
5
|
-
|
|
6
|
-
// Historical DiceBear 9.x choices, now generated by Clay's local server.
|
|
7
|
-
export var MATE_AVATAR_STYLES = [
|
|
8
|
-
{ id: 'thumbs', name: 'Thumbs' },
|
|
9
|
-
{ id: 'bottts', name: 'Bots' },
|
|
10
|
-
{ id: 'pixel-art', name: 'Pixel' },
|
|
11
|
-
{ id: 'adventurer', name: 'Adventurer' },
|
|
12
|
-
{ id: 'micah', name: 'Micah' },
|
|
13
|
-
{ id: 'fun-emoji', name: 'Emoji' },
|
|
14
|
-
{ id: 'icons', name: 'Icons' },
|
|
15
|
-
];
|
|
2
|
+
import { imprintDataUrl } from './avatar-imprint.js';
|
|
16
3
|
|
|
17
4
|
export function avatarUrl(style, seed, size) {
|
|
18
5
|
// Legacy user styles remain part of the seed identity, never the artwork.
|
|
19
6
|
return imprintDataUrl({ style: style || 'imprint', seed: seed || 'anonymous', size: size || 64 });
|
|
20
7
|
}
|
|
21
8
|
|
|
22
|
-
export function mateStyleAvatarUrl(style, seed, size) {
|
|
23
|
-
var normalizedStyle = style || 'imprint';
|
|
24
|
-
var normalizedSeed = seed || 'anonymous';
|
|
25
|
-
var normalizedSize = size || 64;
|
|
26
|
-
var isHistorical = MATE_AVATAR_STYLES.some(function (entry) { return entry.id === normalizedStyle; });
|
|
27
|
-
if (isHistorical) {
|
|
28
|
-
return '/api/generated-avatar?style=' + encodeURIComponent(normalizedStyle)
|
|
29
|
-
+ '&seed=' + encodeURIComponent(normalizedSeed)
|
|
30
|
-
+ '&size=' + encodeURIComponent(normalizedSize);
|
|
31
|
-
}
|
|
32
|
-
return imprintDataUrl({ style: normalizedStyle, seed: normalizedSeed, size: normalizedSize });
|
|
33
|
-
}
|
|
34
|
-
|
|
35
9
|
// Use the same bounded account identity for fresh fallbacks across every surface.
|
|
36
10
|
export function userAvatarSeed(user) {
|
|
37
11
|
var profile = user && user.profile ? user.profile : user;
|
|
@@ -48,24 +22,24 @@ export function userAvatarUrl(user, size) {
|
|
|
48
22
|
return avatarUrl(style, userAvatarSeed(user), size);
|
|
49
23
|
}
|
|
50
24
|
|
|
51
|
-
|
|
52
|
-
var
|
|
53
|
-
|
|
54
|
-
var
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return
|
|
25
|
+
function mappedMateAvatarId(mate) {
|
|
26
|
+
var p = mate.profile || mate;
|
|
27
|
+
var key = JSON.stringify([mate.id || '', p.avatarStyle || 'imprint', p.avatarSeed || mate.id || p.displayName || mate.name || 'Mate']);
|
|
28
|
+
var hash = 2166136261;
|
|
29
|
+
for (var i = 0; i < key.length; i++) hash = Math.imul(hash ^ key.charCodeAt(i), 16777619) >>> 0;
|
|
30
|
+
var index = hash % 96;
|
|
31
|
+
return (index < 48 ? 'B' : 'C') + String(index % 48 + 1).padStart(2, '0');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function mateCatalogAvatarUrl(id) {
|
|
35
|
+
if (id === 'lead-clay') return '/mate-avatars/lead-clay.png?v=4';
|
|
36
|
+
return typeof id === 'string' && /^[BC](0[1-9]|[1-3][0-9]|4[0-8])$/.test(id) ? '/mate-avatars/' + id + '.png?v=4' : '';
|
|
58
37
|
}
|
|
59
38
|
|
|
60
39
|
// Build avatar URL for a mate object, preferring custom avatar if set.
|
|
61
40
|
export function mateAvatarUrl(mate, size) {
|
|
62
|
-
if (!mate) return
|
|
41
|
+
if (!mate) return mateCatalogAvatarUrl('B01');
|
|
63
42
|
var p = mate.profile || mate;
|
|
64
43
|
if (p.avatarCustom || mate.avatarCustom) return p.avatarCustom || mate.avatarCustom;
|
|
65
|
-
|
|
66
|
-
var style = p.avatarStyle || mate.avatarStyle || 'imprint';
|
|
67
|
-
if (style !== 'imprint' && style !== 'initial') {
|
|
68
|
-
return mateStyleAvatarUrl(style, p.avatarSeed || mate.avatarSeed || mate.id || identity, size);
|
|
69
|
-
}
|
|
70
|
-
return mateMarkUrl(identity, size);
|
|
44
|
+
return mateCatalogAvatarUrl(p.avatarCatalogId) || mateCatalogAvatarUrl(mate.builtinKey === 'clay' ? 'lead-clay' : mappedMateAvatarId(mate));
|
|
71
45
|
}
|
|
@@ -7,6 +7,7 @@ import { getProjectAssistantPlaceholder } from './project-chat-identity.js';
|
|
|
7
7
|
export var VENDOR_AVATARS = {
|
|
8
8
|
claude: "/claude-code-avatar.png",
|
|
9
9
|
codex: "/codex-avatar.png",
|
|
10
|
+
muse: "/muse-avatar.svg",
|
|
10
11
|
antigravity: "/antigravity-avatar.png",
|
|
11
12
|
opencode: "/opencode-avatar.svg",
|
|
12
13
|
kimi: "/kimi-avatar.svg",
|
|
@@ -20,6 +21,7 @@ export var VENDOR_AVATARS = {
|
|
|
20
21
|
export var VENDOR_NAMES = {
|
|
21
22
|
claude: "Claude Code",
|
|
22
23
|
codex: "Codex",
|
|
24
|
+
muse: "Muse Code",
|
|
23
25
|
antigravity: "Antigravity CLI",
|
|
24
26
|
opencode: "OpenCode",
|
|
25
27
|
kimi: "Kimi Code",
|
|
@@ -33,6 +35,7 @@ export var VENDOR_NAMES = {
|
|
|
33
35
|
export var VENDOR_HOMEPAGES = {
|
|
34
36
|
claude: "https://claude.com/product/claude-code",
|
|
35
37
|
codex: "https://openai.com/codex/",
|
|
38
|
+
muse: "https://dev.meta.ai/docs/muse-code",
|
|
36
39
|
antigravity: "https://antigravity.google/product/antigravity-cli",
|
|
37
40
|
opencode: "https://opencode.ai/",
|
|
38
41
|
kimi: "https://www.kimi.com/code/",
|
|
@@ -155,11 +158,28 @@ export function setIsUserScrolledUp(value) { isUserScrolledUp = value; }
|
|
|
155
158
|
|
|
156
159
|
export function addToMessages(element) {
|
|
157
160
|
var messagesEl = getMessagesEl();
|
|
161
|
+
addHistoryIndex(element, store.get('currentHistoryIndexes') || store.get('currentHistoryIndex'));
|
|
158
162
|
if (prependAnchor) messagesEl.insertBefore(element, prependAnchor);
|
|
159
163
|
else messagesEl.appendChild(element);
|
|
160
164
|
keepActiveThinkingAtTail();
|
|
161
165
|
}
|
|
162
166
|
|
|
167
|
+
export function addHistoryIndex(element, historyIndex) {
|
|
168
|
+
if (Array.isArray(historyIndex)) {
|
|
169
|
+
if (!element) return;
|
|
170
|
+
var indexes = new Set((element.dataset.historyIndexes || "").split(",").filter(Boolean));
|
|
171
|
+
for (var i = 0; i < historyIndex.length; i++) {
|
|
172
|
+
if (Number.isSafeInteger(historyIndex[i]) && historyIndex[i] >= 0) indexes.add(String(historyIndex[i]));
|
|
173
|
+
}
|
|
174
|
+
element.dataset.historyIndexes = Array.from(indexes).join(",");
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (!element || !Number.isSafeInteger(historyIndex) || historyIndex < 0) return;
|
|
178
|
+
var existing = element.dataset.historyIndexes || "";
|
|
179
|
+
if (existing.split(",").indexOf(String(historyIndex)) !== -1) return;
|
|
180
|
+
element.dataset.historyIndexes = existing ? existing + "," + historyIndex : String(historyIndex);
|
|
181
|
+
}
|
|
182
|
+
|
|
163
183
|
// Thinking is a single accumulating record for the active turn. Other live
|
|
164
184
|
// transcript entries may arrive between reasoning segments, so keep only the
|
|
165
185
|
// currently active record after the tail activity indicator.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { store } from './store.js';
|
|
2
|
+
import { iconHtml, refreshIcons } from './icons.js';
|
|
3
|
+
import { showToast } from './utils.js';
|
|
4
|
+
import { forwardPaneBrowserLink } from './pane-browser-bridge.js';
|
|
5
|
+
|
|
6
|
+
function escape(value) { return String(value).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, '''); }
|
|
7
|
+
export function browserLinkTarget(href) {
|
|
8
|
+
if (typeof href !== 'string' || !href.startsWith('browser:') || href.length > 8200) return null;
|
|
9
|
+
var raw = href.slice(8);
|
|
10
|
+
if (!/^https?:\/\//i.test(raw) || /[\u0000-\u0020]/.test(raw)) return null;
|
|
11
|
+
try {
|
|
12
|
+
var url = new URL(raw);
|
|
13
|
+
if (url.username || url.password || !['http:', 'https:'].includes(url.protocol)) return null;
|
|
14
|
+
return url.href;
|
|
15
|
+
} catch (error) { return null; }
|
|
16
|
+
}
|
|
17
|
+
export function renderBrowserLink(href, title, text) {
|
|
18
|
+
var url = browserLinkTarget(href);
|
|
19
|
+
if (!url) return null;
|
|
20
|
+
var label = String(text || '').replace(/<[^>]*>/g, '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").trim();
|
|
21
|
+
if (!label || label === href || label === url) label = new URL(url).host;
|
|
22
|
+
return '<button type="button" class="clay-browser-link clayos-record-link" data-browser-url="' + escape(url) + '" data-browser-project="' + escape(store.get('currentSlug') || '') + '" title="' + escape('Open in Clay Browser · ' + url) + '" aria-label="' + escape('Open in Clay Browser: ' + label) + '">' + iconHtml('globe') + '<span>Browser</span><small>' + escape(label) + '</small></button>';
|
|
23
|
+
}
|
|
24
|
+
export function enhanceBrowserLinks(root) {
|
|
25
|
+
if (!root || typeof document === 'undefined') return;
|
|
26
|
+
root.querySelectorAll('a[href]').forEach(function (anchor) {
|
|
27
|
+
if (anchor.closest('pre, code, button')) return;
|
|
28
|
+
var html = renderBrowserLink(anchor.getAttribute('href'), '', anchor.textContent);
|
|
29
|
+
if (html) { var template = document.createElement('template'); template.innerHTML = html; anchor.replaceWith(template.content); }
|
|
30
|
+
});
|
|
31
|
+
initBrowserLinks();
|
|
32
|
+
refreshIcons();
|
|
33
|
+
}
|
|
34
|
+
export function initBrowserLinks() {
|
|
35
|
+
if (store.get('browserLinksBound')) return;
|
|
36
|
+
store.set({ browserLinksBound: true });
|
|
37
|
+
document.addEventListener('click', function (event) {
|
|
38
|
+
var button = event.target.closest && event.target.closest('.clay-browser-link');
|
|
39
|
+
if (!button) return;
|
|
40
|
+
event.preventDefault(); event.stopPropagation();
|
|
41
|
+
var url = browserLinkTarget('browser:' + button.dataset.browserUrl);
|
|
42
|
+
if (!url) { showToast('This browser link is invalid.', 'warn'); return; }
|
|
43
|
+
if (button.dataset.browserProject && button.dataset.browserProject !== store.get('currentSlug')) { showToast('Open this link from its original project.', 'warn'); return; }
|
|
44
|
+
if (forwardPaneBrowserLink(url)) return;
|
|
45
|
+
import('./shared-browser.js').then(function (module) { module.openSharedBrowserAt(url); }).catch(function (error) { showToast(error.message || 'Could not open the browser.', 'warn'); });
|
|
46
|
+
});
|
|
47
|
+
}
|