clay-server 5.2.0-beta.1 → 5.2.0-beta.11
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 +0 -4
- package/lib/account-auth-socket.js +1 -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 +52 -0
- package/lib/clay-product-control.js +250 -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-vendor-usage.js +44 -0
- 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 +78 -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/github-star-count.js +147 -0
- 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/notes-checklist.js +92 -0
- package/lib/notes.js +51 -4
- 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-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 +40 -11
- 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 +160 -290
- package/lib/project-shared-browser.js +78 -17
- package/lib/project-start-protocol.js +29 -0
- package/lib/project-studio-presentation.js +58 -0
- package/lib/project-user-message.js +67 -1
- package/lib/project-vendor-login.js +8 -36
- package/lib/project-workspace-operations.js +126 -0
- package/lib/project-workspace-query.js +19 -2
- package/lib/project.js +181 -45
- package/lib/public/app.js +71 -17
- package/lib/public/appearance-bootstrap.js +16 -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/filebrowser.css +1 -1
- 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/mate-loading-scene.css +21 -0
- package/lib/public/css/messages.css +6 -2
- package/lib/public/css/overlays.css +68 -258
- package/lib/public/css/project-admin-overview.css +13 -0
- package/lib/public/css/project-mate-creation.css +5 -6
- package/lib/public/css/project-start.css +108 -0
- package/lib/public/css/projects-hub.css +53 -14
- package/lib/public/css/session-folders.css +11 -0
- package/lib/public/css/session-github.css +46 -1
- package/lib/public/css/settings-shell.css +103 -0
- package/lib/public/css/shared-browser.css +35 -1
- package/lib/public/css/sidebar.css +7 -0
- package/lib/public/css/sticky-notes.css +87 -1
- package/lib/public/css/title-bar.css +79 -0
- package/lib/public/index.html +61 -68
- 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/admin-settings-invitations.js +2 -2
- package/lib/public/modules/admin-settings-projects.js +8 -4
- package/lib/public/modules/admin-settings-ui.js +20 -4
- package/lib/public/modules/admin-settings-users.js +4 -4
- 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-home-hub.js +2 -1
- 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 +125 -19
- 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 +14 -407
- package/lib/public/modules/app-rate-limit.js +19 -28
- 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 +343 -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 +252 -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/github-star.js +66 -0
- 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-loading-scene.js +17 -0
- 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/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 +12 -241
- 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 +3 -0
- package/lib/public/modules/project-mate-creation-workspace.js +13 -4
- package/lib/public/modules/project-mate-navigation.js +144 -22
- package/lib/public/modules/project-session-visibility-settings.js +19 -16
- package/lib/public/modules/project-settings.js +119 -129
- package/lib/public/modules/project-start-dialog.js +130 -0
- package/lib/public/modules/project-start-folder-state.js +78 -0
- package/lib/public/modules/project-start-folder-view.js +190 -0
- package/lib/public/modules/project-start-forms.js +66 -0
- package/lib/public/modules/project-start-path.js +60 -0
- package/lib/public/modules/project-start-state.js +54 -0
- package/lib/public/modules/project-start-submit.js +67 -0
- package/lib/public/modules/projects-hub-view.js +33 -14
- package/lib/public/modules/projects-hub.js +10 -6
- 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.js +36 -91
- 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/settings-project-target.js +56 -0
- package/lib/public/modules/settings-select.js +1 -1
- package/lib/public/modules/settings-shell-registry.js +88 -0
- package/lib/public/modules/settings-shell-view.js +104 -0
- package/lib/public/modules/settings-shell.js +342 -0
- 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 +12 -33
- package/lib/public/modules/sidebar-projects.js +3 -1
- 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 +18 -3
- 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-appearance.js +10 -3
- package/lib/public/modules/user-settings-editors.js +1 -1
- package/lib/public/modules/user-settings-layout.js +14 -30
- package/lib/public/modules/user-settings-preferences.js +6 -2
- package/lib/public/modules/user-settings-profile.js +13 -3
- package/lib/public/modules/user-settings.js +18 -84
- 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/vendor-usage-format.js +93 -0
- package/lib/public/modules/vendor-usage-list.js +45 -0
- package/lib/public/modules/vendor-usage-model.js +215 -0
- package/lib/public/modules/vendor-usage-overview.js +312 -0
- package/lib/public/modules/wireframe-workbench.js +5 -2
- package/lib/public/muse-avatar.svg +4 -0
- package/lib/public/style.css +14 -6
- package/lib/public/sw.js +3 -1
- package/lib/public/welcome-art/conversation-desk.png +0 -0
- package/lib/public/welcome-art/mate-clay.png +0 -0
- package/lib/public/welcome-art/project-clay.png +0 -0
- 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 +348 -402
- package/lib/sdk-foreground-admission.js +16 -0
- package/lib/sdk-mcp-descriptors.js +2 -37
- package/lib/sdk-message-processor.js +61 -18
- package/lib/sdk-quota-snapshot.js +21 -3
- package/lib/sdk-response-recovery.js +1 -0
- package/lib/sdk-worker.js +2 -677
- package/lib/server-admin.js +63 -16
- package/lib/server-appearance-settings.js +13 -1
- 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-github-stars.js +39 -0
- package/lib/server-global-ws.js +26 -32
- 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 +6 -1
- package/lib/server.js +167 -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-notes-mcp-server.js +26 -4
- package/lib/session-notes-writes.js +88 -0
- package/lib/session-permission-mode.js +4 -3
- package/lib/session-skill-scope.js +11 -0
- package/lib/session-visibility.js +25 -10
- package/lib/session-work-primary.js +50 -0
- package/lib/sessions.js +66 -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/users-contextual-clay-preferences.js +31 -0
- package/lib/users-permissions.js +2 -8
- package/lib/users.js +7 -0
- package/lib/vendor-login-browser.js +1 -11
- package/lib/vendor-usage-acp-readers.js +97 -0
- package/lib/vendor-usage-capabilities.js +88 -0
- package/lib/vendor-usage-http-readers.js +214 -0
- package/lib/vendor-usage-metrics.js +47 -0
- package/lib/vendor-usage-native-readers.js +106 -0
- package/lib/vendor-usage-overview.js +406 -0
- package/lib/vendor-usage-service.js +281 -0
- 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 +22 -4
- 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 +66 -50
- package/lib/yoke/adapters/codex-query-contract.js +25 -0
- package/lib/yoke/adapters/codex.js +98 -123
- 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 +272 -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-dynamic-tool-names.js +80 -0
- package/lib/yoke/codex-idle-recovery.js +81 -1
- package/lib/yoke/codex-model-catalog.js +37 -3
- 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 +92 -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 +34 -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 +87 -3
- package/package.json +11 -4
- package/lib/public/modules/server-settings-navigation.js +0 -39
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { store } from './store.js';
|
|
2
|
+
import { getWs } from './ws-ref.js';
|
|
3
|
+
|
|
4
|
+
export function captureSessionAction() {
|
|
5
|
+
var state = store.snap();
|
|
6
|
+
return { projectSlug: state.currentSlug, ownerId: state.myUserId, sessionId: state.activeSessionId,
|
|
7
|
+
origin: state.sessionOriginId, socket: getWs(), binding: state.paneCommittedBinding || null,
|
|
8
|
+
epoch: state.sessionActionEpoch || 0 };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function sessionActionCurrent(action, draftCompletion) {
|
|
12
|
+
var state = store.snap();
|
|
13
|
+
return !!action && action.socket === getWs() && state.connected &&
|
|
14
|
+
action.projectSlug === state.currentSlug && action.ownerId === state.myUserId &&
|
|
15
|
+
action.sessionId === state.activeSessionId && action.origin === state.sessionOriginId &&
|
|
16
|
+
action.epoch === (state.sessionActionEpoch || 0) &&
|
|
17
|
+
(draftCompletion || !state.deferredSessionSwitch) && !state.panePendingBinding && !state.paneSuspended &&
|
|
18
|
+
(action.binding ? state.paneReady && samePaneBinding(action.binding, state.paneCommittedBinding) : !state.paneCommittedBinding);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Capture at callback creation, never when an old callback eventually sends.
|
|
22
|
+
export function sessionCallback(callback, draftCompletion) {
|
|
23
|
+
var action = captureSessionAction();
|
|
24
|
+
return function () {
|
|
25
|
+
if (!sessionActionCurrent(action, draftCompletion)) return;
|
|
26
|
+
var previous = store.get('paneCallbackBinding');
|
|
27
|
+
store.set({ paneCallbackBinding: action.binding });
|
|
28
|
+
try { return callback.apply(this, arguments); }
|
|
29
|
+
finally { store.set({ paneCallbackBinding: previous }); }
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function samePaneBinding(a, b) {
|
|
34
|
+
return !!a && !!b && ['requestId', 'generation', 'projectSlug', 'viewerId', 'ownerId', 'sessionId', 'sessionOriginId', 'role', 'workerGeneration', 'groupStamp', 'parentSessionOriginId'].every(function (key) { return a[key] === b[key]; });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function samePaneTarget(a, b) {
|
|
38
|
+
return !!a && !!b && ['projectSlug', 'viewerId', 'ownerId', 'sessionId', 'sessionOriginId', 'role', 'workerGeneration', 'groupStamp', 'parentSessionOriginId'].every(function (key) { return a[key] === b[key]; });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function paneTarget(state, sessions, id) {
|
|
42
|
+
var session = (sessions || []).find(function (item) { return item.id === id; });
|
|
43
|
+
if (!session || session.isMate || !session.sessionOriginId || (session.runtimeMode || session.mode || 'gui') !== 'gui' || session.tuiSuspended) return null;
|
|
44
|
+
var group = (state.splitGroups || []).find(function (item) { return item.members.indexOf(id) >= 0; });
|
|
45
|
+
var parent = session.sessionRole === 'worker' && sessions.find(function (item) { return item.id === session.parentSessionId; });
|
|
46
|
+
if (session.sessionRole === 'worker' && (!parent || !session.parentAvailable || !Number.isSafeInteger(session.workerGeneration) || !parent.sessionOriginId || parent.ownerId !== session.ownerId || !group || !group.pair || group.pair.driverId !== parent.id)) return null;
|
|
47
|
+
return {
|
|
48
|
+
projectSlug: state.currentSlug, viewerId: state.myUserId || null, ownerId: session.ownerId || null,
|
|
49
|
+
sessionId: session.id, sessionOriginId: session.sessionOriginId,
|
|
50
|
+
role: session.sessionRole === 'worker' ? 'worker' : 'driver', workerGeneration: session.workerGeneration || null,
|
|
51
|
+
parentSessionOriginId: parent ? parent.sessionOriginId : null,
|
|
52
|
+
groupStamp: group ? JSON.stringify({ id: group.id, members: group.members, pair: group.pair || null }) : null,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Ordinary reusable panes have a live document binding; legacy/canonical frames
|
|
57
|
+
// retain their existing URL and receipt checks in their own bridge paths.
|
|
58
|
+
export function livePaneBinding(frame, message) {
|
|
59
|
+
if (!frame || !frame.clayPane) return false;
|
|
60
|
+
var api = frame.clayPane, live = api.identity();
|
|
61
|
+
var state = store.snap(), split = state.splitPanes;
|
|
62
|
+
var target = live && paneTarget(state, state.paneBindingSessions || [], live.sessionId);
|
|
63
|
+
return api.source === frame.contentWindow && api.document === frame.contentDocument && live && live.ready &&
|
|
64
|
+
samePaneTarget(target, live.binding) &&
|
|
65
|
+
live.ownerId === (state.myUserId || null) && live.projectSlug === state.currentSlug &&
|
|
66
|
+
split && split.panes.some(function (pane) { return pane.slug === live.projectSlug && pane.sessionId === live.sessionId; }) &&
|
|
67
|
+
(!message || samePaneBinding(live.binding, message.paneBinding));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function paneMessageBinding() {
|
|
71
|
+
return store.get('paneReady') && !store.get('paneSuspended') ? store.get('paneCommittedBinding') : null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function currentPaneReview(container) {
|
|
75
|
+
if (!container || !container.paneBinding) return true;
|
|
76
|
+
return container.isConnected !== false && store.get('paneReady') && !store.get('paneSuspended') && samePaneBinding(container.paneBinding, store.get('paneCommittedBinding'));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function paneCallbackCurrent(binding) {
|
|
80
|
+
var current = store.get('panePendingBinding') || store.get('paneCommittedBinding');
|
|
81
|
+
return current ? samePaneBinding(current, binding) : !binding;
|
|
82
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { forwardStudioPresentation } from './clay-studio-render.js';
|
|
1
2
|
// Pane-side postMessage bridge for the split-view shell. A chrome-less pane
|
|
2
3
|
// iframe reports its context usage up to the parent (which renders a chip in
|
|
3
4
|
// the pane header) and honors panel-toggle requests coming back down.
|
|
4
5
|
// Same-origin messages only, both directions.
|
|
5
6
|
|
|
6
7
|
import { store } from './store.js';
|
|
8
|
+
import { paneMessageBinding, samePaneBinding } from './pane-binding.js';
|
|
7
9
|
import { getEffectiveContextView } from './context-view-preference.js';
|
|
8
10
|
import { forceExternalLinkToNewTab } from './pane-links.js';
|
|
9
11
|
|
|
@@ -11,6 +13,7 @@ export function reportPaneContext(data) {
|
|
|
11
13
|
if (!store.get('paneMode') || window.parent === window) return;
|
|
12
14
|
window.parent.postMessage({
|
|
13
15
|
type: "clay-pane-context",
|
|
16
|
+
paneBinding: paneMessageBinding(),
|
|
14
17
|
sessionId: store.get('activeSessionId'),
|
|
15
18
|
pct: data.pct,
|
|
16
19
|
used: data.used,
|
|
@@ -26,19 +29,18 @@ export function reportPaneContext(data) {
|
|
|
26
29
|
// Hand the event to the parent shell, which owns the single flow.
|
|
27
30
|
export function forwardPaneAuthRequired(message) {
|
|
28
31
|
if (!store.get('paneMode') || window.parent === window) return false;
|
|
29
|
-
window.parent.postMessage({ type: "clay-pane-auth-required", message: message }, window.location.origin);
|
|
32
|
+
window.parent.postMessage({ type: "clay-pane-auth-required", paneBinding: paneMessageBinding(), message: message }, window.location.origin);
|
|
30
33
|
return true;
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
export function forwardPaneMarkdownPresentation(message) {
|
|
34
37
|
if (!store.get('paneMode') || window.parent === window) return false;
|
|
35
|
-
|
|
36
|
-
return true;
|
|
38
|
+
return forwardStudioPresentation(message, "clay-pane-present-markdown");
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
export function forwardPaneIssueReference(ref, projectSlug) {
|
|
40
42
|
if (!store.get('paneMode') || window.parent === window) return false;
|
|
41
|
-
window.parent.postMessage({ type: "clay-pane-open-issue", ref: ref, projectSlug: projectSlug || store.get('currentSlug') }, window.location.origin);
|
|
43
|
+
window.parent.postMessage({ type: "clay-pane-open-issue", paneBinding: paneMessageBinding(), ref: ref, projectSlug: projectSlug || store.get('currentSlug') }, window.location.origin);
|
|
42
44
|
return true;
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -70,6 +72,7 @@ export function initPaneBridge() {
|
|
|
70
72
|
if (event.origin !== window.location.origin) return;
|
|
71
73
|
var msg = event.data;
|
|
72
74
|
if (!msg || msg.type !== "clay-pane-toggle-context") return;
|
|
75
|
+
if (event.source !== window.parent || store.get('paneCommittedBinding') && !samePaneBinding(paneMessageBinding(), msg.paneBinding)) return;
|
|
73
76
|
togglePaneContextPanel();
|
|
74
77
|
});
|
|
75
78
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { store } from './store.js';
|
|
2
|
+
import { livePaneBinding, paneMessageBinding } from './pane-binding.js';
|
|
3
|
+
import { showToast } from './utils.js';
|
|
4
|
+
|
|
5
|
+
export function forwardPaneBrowserLink(url) {
|
|
6
|
+
if (!store.get('paneMode') || window.parent === window) return false;
|
|
7
|
+
window.parent.postMessage({ type: 'clay-pane-open-browser', paneBinding: paneMessageBinding(), url: url, projectSlug: store.get('currentSlug'), sessionId: String(store.get('activeSessionId')) }, window.location.origin);
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
export function handlePaneBrowserMessage(event, host) {
|
|
11
|
+
if (!event || event.origin !== window.location.origin || !host || !event.data || event.data.type !== 'clay-pane-open-browser') return false;
|
|
12
|
+
var msg = event.data, s = store.snap();
|
|
13
|
+
var frame = Array.from(host.querySelectorAll('.split-pane-frame')).find(function (item) { return item.contentWindow === event.source; });
|
|
14
|
+
var pane = frame && s.splitPanes && s.splitPanes.panes && s.splitPanes.panes.find(function (item) { return String(item.slug) === frame.dataset.projectSlug && String(item.sessionId) === frame.dataset.sessionId; });
|
|
15
|
+
if (!pane || msg.projectSlug !== s.currentSlug || msg.projectSlug !== frame.dataset.projectSlug || String(msg.sessionId) !== frame.dataset.sessionId) return true;
|
|
16
|
+
var expected = new URL('/p/' + encodeURIComponent(pane.slug) + '/?pane=1&session=' + encodeURIComponent(pane.sessionId), window.location.href).href;
|
|
17
|
+
if (frame.clayPane ? !livePaneBinding(frame, msg) : frame.src !== expected) return true;
|
|
18
|
+
// The authenticated host owns the browser; a live same-project pane supplies only a URL.
|
|
19
|
+
var binding = frame.clayPane && frame.clayPane.identity().binding;
|
|
20
|
+
import('./shared-browser.js').then(function (module) { if (binding && (!livePaneBinding(frame, msg) || frame.clayPane.identity().binding !== binding)) return; module.openSharedBrowserAt(msg.url); }).catch(function (error) { showToast(error.message || 'Could not open the browser.', 'warn'); });
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { store } from './store.js';
|
|
2
|
+
import { livePaneBinding, paneMessageBinding } from './pane-binding.js';
|
|
2
3
|
|
|
3
4
|
function paneFrame(host, source) {
|
|
4
5
|
if (!host || !source) return null;
|
|
@@ -19,6 +20,7 @@ function matchingPane(frame, split) {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
function hasLivePaneSource(frame, pane) {
|
|
23
|
+
if (frame && frame.clayPane) return livePaneBinding(frame);
|
|
22
24
|
if (!frame || !pane || typeof frame.src !== "string") return false;
|
|
23
25
|
var expected = "/p/" + encodeURIComponent(pane.slug) + "/?pane=1&session=" + encodeURIComponent(pane.sessionId);
|
|
24
26
|
try { return new URL(expected, window.location.href).href === frame.src; } catch (e) { return false; }
|
|
@@ -41,6 +43,7 @@ export function forwardPaneFileReference(path, opts) {
|
|
|
41
43
|
if (!store.get('paneMode') || window.parent === window || typeof path !== "string" || !path) return false;
|
|
42
44
|
window.parent.postMessage({
|
|
43
45
|
type: "clay-pane-open-file",
|
|
46
|
+
paneBinding: paneMessageBinding(),
|
|
44
47
|
path: path,
|
|
45
48
|
line: opts && opts.line != null ? opts.line : null,
|
|
46
49
|
column: opts && opts.column != null ? opts.column : null,
|
|
@@ -57,6 +60,7 @@ export function handlePaneFileMessage(event, host, openFile, openFiles) {
|
|
|
57
60
|
var frame = paneFrame(host, event.source);
|
|
58
61
|
var state = store.snap();
|
|
59
62
|
var pane = matchingPane(frame, state.splitPanes);
|
|
63
|
+
if (frame && frame.clayPane && !livePaneBinding(frame, msg)) return true;
|
|
60
64
|
if (!pane || !hasLivePaneSource(frame, pane) || String(pane.slug) !== String(state.currentSlug) || msg.projectSlug !== frame.dataset.projectSlug || String(msg.sessionId) !== String(frame.dataset.sessionId) || !validLocation(msg.line) || !validLocation(msg.column)) return true;
|
|
61
65
|
if (typeof msg.path !== "string" || !msg.path) return true;
|
|
62
66
|
if (!state.connected || typeof openFile !== "function") return true;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { store } from './store.js';
|
|
2
|
+
import { livePaneBinding } from './pane-binding.js';
|
|
2
3
|
import { openIssues } from './issues.js';
|
|
3
4
|
|
|
4
5
|
function isIssueReference(ref) {
|
|
@@ -8,7 +9,7 @@ function isIssueReference(ref) {
|
|
|
8
9
|
function isPaneSource(host, source) {
|
|
9
10
|
var frames = host.querySelectorAll(".split-pane-frame");
|
|
10
11
|
for (var i = 0; i < frames.length; i++) {
|
|
11
|
-
if (frames[i].contentWindow === source) return
|
|
12
|
+
if (frames[i].contentWindow === source) return !frames[i].clayPane || livePaneBinding(frames[i]);
|
|
12
13
|
}
|
|
13
14
|
return false;
|
|
14
15
|
}
|
|
@@ -18,6 +19,8 @@ export function handlePaneIssueMessage(event, host) {
|
|
|
18
19
|
var msg = event.data;
|
|
19
20
|
if (!msg || msg.type !== "clay-pane-open-issue") return false;
|
|
20
21
|
if (!isIssueReference(msg.ref) || !isPaneSource(host, event.source)) return true;
|
|
22
|
+
var frame = Array.from(host.querySelectorAll('.split-pane-frame')).find(function (item) { return item.contentWindow === event.source; });
|
|
23
|
+
if (frame && frame.clayPane && !livePaneBinding(frame, msg)) return true;
|
|
21
24
|
|
|
22
25
|
var issueTarget = store.get('issuesCache') && store.get('issuesCache')[msg.ref];
|
|
23
26
|
var projectSlug = (issueTarget && issueTarget.projectSlug) || msg.projectSlug || store.get('currentSlug');
|
|
@@ -330,6 +330,7 @@ function renderItem(item, index) {
|
|
|
330
330
|
var disabled = controlsDisabled ? ' disabled aria-disabled="true"' : '';
|
|
331
331
|
var text = (item.message && item.message.text || "").trim() || "Attachment-only message";
|
|
332
332
|
var html = '<div class="pending-message-chip' + (item.state === "claimed" ? ' is-claimed' : '') + (scheduled ? ' is-scheduled' : '') + (futureScheduled ? ' is-future' : '') + '" data-pending-id="' + escapeHtml(item.id) + '">';
|
|
333
|
+
if (item.schedule && item.schedule.logicalScheduleId) html = html.replace('data-pending-id=', 'data-control-schedule-id="' + escapeHtml(item.schedule.logicalScheduleId) + '" data-control-revision="' + escapeHtml(item.schedule.logicalRevision || '') + '" data-control-runtime="' + escapeHtml(store.get('controlRuntimeId') || '') + '" data-pending-id=');
|
|
333
334
|
html += '<span class="pending-message-number" aria-hidden="true">' + (index + 1) + '</span>';
|
|
334
335
|
if (own && item.state === "pending") html += '<button class="pending-message-drag" type="button" data-action="drag" aria-label="Reorder queued message ' + (index + 1) + '" title="Drag, or use arrow keys to reorder"' + disabled + '>' + '<i data-lucide="grip-vertical"></i></button>';
|
|
335
336
|
else html += '<span class="pending-message-drag is-static"><i data-lucide="' + (item.state === "claimed" ? "loader-circle" : "lock-keyhole") + '"></i></span>';
|
|
@@ -66,7 +66,7 @@ export function permissionStatusText(state, pending, autoSupported, autoVisible)
|
|
|
66
66
|
if (state.permissionMode === "plan") return "Plan workflow";
|
|
67
67
|
if (state.permissionMode === "acceptEdits") return "Auto-accept edits workflow";
|
|
68
68
|
if (state.permissionMode === "dontAsk") return "Don't ask workflow";
|
|
69
|
-
if (autoVisible && !autoSupported) return "Auto unavailable for this
|
|
69
|
+
if (autoVisible && !autoSupported) return "Auto unavailable for this session";
|
|
70
70
|
if (state.permissionMode === "auto" && !state.effectivePermissionMode) return "Auto selected · waiting for runtime";
|
|
71
71
|
if (state.permissionMode === "auto" && state.effectivePermissionMode !== "auto") {
|
|
72
72
|
return "Auto unavailable at runtime · using " + modeLabel(state.effectivePermissionMode);
|
|
@@ -91,7 +91,8 @@ export function renderPermissionControl(control, state) {
|
|
|
91
91
|
var projectSlug = state.projectSlug || "";
|
|
92
92
|
var sessionId = state.sessionId || null;
|
|
93
93
|
var pending = permissionPendingFor(projectSlug, sessionId);
|
|
94
|
-
var
|
|
94
|
+
var description = ((store.get("vendorInfo") || {})[state.vendor] || {}).configuration || {};
|
|
95
|
+
var autoVisible = description.auto === true || !!(state.permissionCapabilities && state.permissionCapabilities.auto === true);
|
|
95
96
|
var autoSupported = !!(state.permissionCapabilities && state.permissionCapabilities.auto === true);
|
|
96
97
|
var globallyForced = state.globalPermissionModeForced === true;
|
|
97
98
|
var connected = state.connected !== false && !!getWs() && getWs().readyState === 1;
|
|
@@ -114,7 +115,7 @@ export function renderPermissionControl(control, state) {
|
|
|
114
115
|
buttons[i].classList.toggle("pending", requested);
|
|
115
116
|
buttons[i].setAttribute("aria-pressed", selected ? "true" : "false");
|
|
116
117
|
buttons[i].setAttribute("aria-busy", requested ? "true" : "false");
|
|
117
|
-
buttons[i].title = unsupported ? "Auto permissions are unavailable for this
|
|
118
|
+
buttons[i].title = unsupported ? "Auto permissions are unavailable for this session." : buttonTitles[mode];
|
|
118
119
|
}
|
|
119
120
|
var status = control.querySelector(".session-permission-status");
|
|
120
121
|
if (status) {
|
|
@@ -138,7 +139,7 @@ export function bindPermissionControl(control, getState) {
|
|
|
138
139
|
var autoSupported = !!(state.permissionCapabilities && state.permissionCapabilities.auto === true);
|
|
139
140
|
if (state.visible === false || state.locked === true || state.globalPermissionModeForced === true || state.connected === false || store.get('connected') === false) return;
|
|
140
141
|
if (!state.projectSlug || state.projectSlug !== store.get('currentSlug') || !state.sessionId) return;
|
|
141
|
-
if (mode === "auto" &&
|
|
142
|
+
if (mode === "auto" && !autoSupported) return;
|
|
142
143
|
sendPermissionMode(state.projectSlug, state.sessionId, mode);
|
|
143
144
|
});
|
|
144
145
|
}
|
|
@@ -17,7 +17,13 @@ export function preparePersonalConnectionDialog(overlay, inline) {
|
|
|
17
17
|
if (label && input) label.htmlFor = input.id;
|
|
18
18
|
});
|
|
19
19
|
enhanceSettingsSelects(overlay);
|
|
20
|
-
|
|
20
|
+
var fields = Array.from(overlay.querySelectorAll('input,select,textarea'));
|
|
21
|
+
function value(field) {return field.type === 'checkbox' ? field.checked : field.value;}
|
|
22
|
+
var baseline = fields.map(value);
|
|
23
|
+
function markDirty() {
|
|
24
|
+
dirty = fields.some(function (field, index) {return value(field) !== baseline[index];});
|
|
25
|
+
if (inline) store.set({personalEmailDirty:dirty});
|
|
26
|
+
}
|
|
21
27
|
overlay.addEventListener('input', markDirty);
|
|
22
28
|
overlay.addEventListener('change', markDirty);
|
|
23
29
|
var unsubscribe = inline ? store.subscribe(function (state, previousState) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Display-only metadata from a bound product service. The exact question and
|
|
2
|
+
// authenticated response remain unchanged; this renderer grants no authority.
|
|
3
|
+
export function renderProductReview(element, question) {
|
|
4
|
+
var review = question.review;
|
|
5
|
+
if (!review || review.kind !== 'product-control' || typeof review.action !== 'string' || typeof review.target !== 'string' || typeof review.context !== 'string' || typeof review.reason !== 'string') return false;
|
|
6
|
+
element.classList.add('product-review');
|
|
7
|
+
element.textContent = '';
|
|
8
|
+
function text(tag, className, value) {
|
|
9
|
+
var node = document.createElement(tag);
|
|
10
|
+
node.className = className;
|
|
11
|
+
node.textContent = value;
|
|
12
|
+
element.appendChild(node);
|
|
13
|
+
}
|
|
14
|
+
text('strong', 'product-review-action', review.action + ': ' + review.target);
|
|
15
|
+
text('p', 'product-review-context', review.context);
|
|
16
|
+
text('p', 'product-review-reason', review.reason);
|
|
17
|
+
var details = document.createElement('details');
|
|
18
|
+
var summary = document.createElement('summary');
|
|
19
|
+
summary.textContent = 'Exact request details';
|
|
20
|
+
var payload = document.createElement('pre');
|
|
21
|
+
payload.textContent = question.question;
|
|
22
|
+
details.appendChild(summary);
|
|
23
|
+
details.appendChild(payload);
|
|
24
|
+
element.appendChild(details);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
@@ -4,7 +4,7 @@ import { setChatLayout } from './theme.js';
|
|
|
4
4
|
// Generated identities use deterministic local pixel identicons.
|
|
5
5
|
|
|
6
6
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
7
|
-
import { avatarUrl,
|
|
7
|
+
import { avatarUrl, userAvatarSeed } from './avatar.js';
|
|
8
8
|
import { store } from './store.js';
|
|
9
9
|
import { applyTerminalFont } from './terminal-prefs.js';
|
|
10
10
|
|
|
@@ -135,9 +135,12 @@ export function uploadAvatarBlob(blob) {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
// --- Avatar position picker ---
|
|
138
|
-
|
|
138
|
+
// With a host element the editor mounts inline as a settings subview instead
|
|
139
|
+
// of a page-level overlay.
|
|
140
|
+
export function showAvatarPositioner(img, objectUrl, onDone, host) {
|
|
139
141
|
var outputSize = 256;
|
|
140
142
|
var viewSize = 220;
|
|
143
|
+
var priorFocus = document.activeElement;
|
|
141
144
|
|
|
142
145
|
// State
|
|
143
146
|
var scale = 1;
|
|
@@ -169,7 +172,7 @@ export function showAvatarPositioner(img, objectUrl, onDone) {
|
|
|
169
172
|
|
|
170
173
|
// Build overlay
|
|
171
174
|
var overlay = document.createElement('div');
|
|
172
|
-
overlay.className = 'avatar-positioner-overlay';
|
|
175
|
+
overlay.className = host ? 'avatar-positioner-inline settings-subview' : 'avatar-positioner-overlay';
|
|
173
176
|
|
|
174
177
|
var container = document.createElement('div');
|
|
175
178
|
container.className = 'avatar-positioner-container';
|
|
@@ -225,8 +228,10 @@ export function showAvatarPositioner(img, objectUrl, onDone) {
|
|
|
225
228
|
container.appendChild(btnRow);
|
|
226
229
|
|
|
227
230
|
overlay.appendChild(container);
|
|
228
|
-
|
|
231
|
+
if (host) { host.classList.add('has-subview'); host.appendChild(overlay); overlay.setAttribute('role', 'region'); overlay.setAttribute('aria-label', 'Position your avatar'); }
|
|
232
|
+
else document.body.appendChild(overlay);
|
|
229
233
|
updatePreview();
|
|
234
|
+
if (host) doneFocus();
|
|
230
235
|
|
|
231
236
|
// Drag
|
|
232
237
|
var dragging = false;
|
|
@@ -288,9 +293,12 @@ export function showAvatarPositioner(img, objectUrl, onDone) {
|
|
|
288
293
|
updatePreview();
|
|
289
294
|
}, { passive: false });
|
|
290
295
|
|
|
296
|
+
function doneFocus() { closeBtn.focus(); }
|
|
297
|
+
|
|
291
298
|
function cleanup(revoke) {
|
|
292
299
|
document.removeEventListener('keydown', onOverlayKeydown);
|
|
293
300
|
overlay.remove();
|
|
301
|
+
if (host) { host.classList.remove('has-subview'); if (priorFocus && priorFocus.isConnected) priorFocus.focus(); }
|
|
294
302
|
if (revoke) URL.revokeObjectURL(objectUrl);
|
|
295
303
|
}
|
|
296
304
|
|
|
@@ -586,240 +594,3 @@ export function getProfile() {
|
|
|
586
594
|
export function getProfileLang() {
|
|
587
595
|
return profile.lang;
|
|
588
596
|
}
|
|
589
|
-
|
|
590
|
-
// --- Mate profile popover (reuses same UI minus language) ---
|
|
591
|
-
var matePopoverEl = null;
|
|
592
|
-
var mateSaveTimer = null;
|
|
593
|
-
|
|
594
|
-
export function showMateProfilePopover(anchorEl, mateData, onUpdate) {
|
|
595
|
-
if (matePopoverEl) {
|
|
596
|
-
hideMatePopover();
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
var mp = mateData.profile || {};
|
|
601
|
-
var mateName = mp.displayName || mateData.name || '';
|
|
602
|
-
var mateColor = mp.avatarColor || '#5857fc';
|
|
603
|
-
var mateStyle = mp.avatarStyle || 'imprint';
|
|
604
|
-
var mateSeed = mp.avatarSeed || mateData.id || 'mate';
|
|
605
|
-
var mateCustom = mp.avatarCustom || '';
|
|
606
|
-
|
|
607
|
-
matePopoverEl = document.createElement('div');
|
|
608
|
-
matePopoverEl.className = 'profile-popover mate-profile-popover';
|
|
609
|
-
|
|
610
|
-
var html = '';
|
|
611
|
-
|
|
612
|
-
// Banner + close
|
|
613
|
-
html += '<div class="profile-banner">';
|
|
614
|
-
html += '<button class="profile-close-btn">×</button>';
|
|
615
|
-
html += '</div>';
|
|
616
|
-
|
|
617
|
-
// Avatar row
|
|
618
|
-
var mateAvatarSrc = mateCustom ? mateCustom : mateMarkUrl(mateName || 'Mate', 80);
|
|
619
|
-
html += '<div class="profile-avatar-row">';
|
|
620
|
-
html += '<div class="profile-popover-avatar">';
|
|
621
|
-
html += '<img class="profile-popover-avatar-img" src="' + mateAvatarSrc + '" alt="' + escapeAttr(mateName || 'Clay Mate') + '">';
|
|
622
|
-
html += '</div>';
|
|
623
|
-
html += '<div class="profile-name-display">' + escapeAttr(mateName || 'New Mate') + '</div>';
|
|
624
|
-
html += '</div>';
|
|
625
|
-
|
|
626
|
-
// Body
|
|
627
|
-
html += '<div class="profile-popover-body">';
|
|
628
|
-
|
|
629
|
-
// Name
|
|
630
|
-
html += '<div class="profile-field">';
|
|
631
|
-
html += '<label class="profile-field-label">Display Name</label>';
|
|
632
|
-
html += '<input type="text" class="profile-field-input" id="mate-profile-name" value="' + escapeAttr(mateName) + '" placeholder="Name your mate..." maxlength="50" spellcheck="false" autocomplete="off">';
|
|
633
|
-
html += '</div>';
|
|
634
|
-
|
|
635
|
-
// Avatar picker (hidden if avatar is locked)
|
|
636
|
-
var mateAvatarLocked = mp.avatarLocked || false;
|
|
637
|
-
if (!mateAvatarLocked) {
|
|
638
|
-
html += '<div class="profile-field">';
|
|
639
|
-
html += '<label class="profile-field-label">Identity</label>';
|
|
640
|
-
html += '<div class="profile-imprint-panel">';
|
|
641
|
-
html += '<div class="profile-imprint-preview"><img src="' + mateMarkUrl(mateName || 'Mate', 72) + '" alt="Clay Mate initial"><span><strong>Mate initial</strong><small>Based on display name</small></span></div>';
|
|
642
|
-
html += '<div class="profile-imprint-actions profile-mate-mark-actions">';
|
|
643
|
-
html += '<button class="profile-use-imprint' + (!mateCustom ? ' is-active' : '') + '" type="button">Use initial</button>';
|
|
644
|
-
html += '<button class="profile-avatar-upload' + (mateCustom ? ' is-active' : '') + '" type="button">Upload image</button>';
|
|
645
|
-
html += '</div>';
|
|
646
|
-
html += '</div>';
|
|
647
|
-
html += '<input type="file" id="mate-profile-avatar-file" accept="image/*" style="display:none">';
|
|
648
|
-
html += '</div>';
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
html += '</div>'; // close body
|
|
652
|
-
|
|
653
|
-
matePopoverEl.innerHTML = html;
|
|
654
|
-
|
|
655
|
-
// State tracker
|
|
656
|
-
var mateProfile = {
|
|
657
|
-
displayName: mateName,
|
|
658
|
-
avatarStyle: mateStyle,
|
|
659
|
-
avatarSeed: mateSeed,
|
|
660
|
-
avatarColor: mateColor,
|
|
661
|
-
avatarCustom: mateCustom,
|
|
662
|
-
};
|
|
663
|
-
|
|
664
|
-
function refreshChatAvatars() {
|
|
665
|
-
var newUrl = mateAvatarUrl({ profile: mateProfile, id: mateData.id }, 64);
|
|
666
|
-
// Update all mate avatars in the chat area
|
|
667
|
-
var bubbles = document.querySelectorAll('.dm-bubble-avatar-mate');
|
|
668
|
-
for (var i = 0; i < bubbles.length; i++) {
|
|
669
|
-
bubbles[i].src = newUrl;
|
|
670
|
-
}
|
|
671
|
-
// Update body dataset so new messages use the updated URL
|
|
672
|
-
if (document.body.dataset.mateAvatarUrl) {
|
|
673
|
-
document.body.dataset.mateAvatarUrl = newUrl;
|
|
674
|
-
}
|
|
675
|
-
// Update mate sidebar avatar
|
|
676
|
-
var sidebarAvatar = document.querySelector('.mate-sidebar-avatar');
|
|
677
|
-
if (sidebarAvatar) sidebarAvatar.src = newUrl;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
function debouncedMateUpdate() {
|
|
681
|
-
if (mateSaveTimer) clearTimeout(mateSaveTimer);
|
|
682
|
-
mateSaveTimer = setTimeout(function() {
|
|
683
|
-
if (onUpdate) onUpdate({
|
|
684
|
-
name: mateProfile.displayName,
|
|
685
|
-
profile: {
|
|
686
|
-
displayName: mateProfile.displayName,
|
|
687
|
-
avatarStyle: mateProfile.avatarStyle,
|
|
688
|
-
avatarSeed: mateProfile.avatarSeed,
|
|
689
|
-
avatarColor: mateProfile.avatarColor,
|
|
690
|
-
avatarCustom: mateProfile.avatarCustom,
|
|
691
|
-
},
|
|
692
|
-
});
|
|
693
|
-
refreshChatAvatars();
|
|
694
|
-
mateSaveTimer = null;
|
|
695
|
-
}, 400);
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
function updateMatePopoverHeader() {
|
|
699
|
-
if (!matePopoverEl) return;
|
|
700
|
-
var img = matePopoverEl.querySelector('.profile-popover-avatar-img');
|
|
701
|
-
var nd = matePopoverEl.querySelector('.profile-name-display');
|
|
702
|
-
if (img) img.src = mateProfile.avatarCustom
|
|
703
|
-
? mateProfile.avatarCustom
|
|
704
|
-
: mateMarkUrl(mateProfile.displayName || 'Mate', 80);
|
|
705
|
-
var preview = matePopoverEl.querySelector('.profile-imprint-preview img');
|
|
706
|
-
if (preview) preview.src = mateMarkUrl(mateProfile.displayName || 'Mate', 72);
|
|
707
|
-
if (nd) nd.textContent = mateProfile.displayName || 'New Mate';
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
// Events
|
|
711
|
-
matePopoverEl.querySelector('.profile-close-btn').addEventListener('click', function(e) {
|
|
712
|
-
e.stopPropagation();
|
|
713
|
-
hideMatePopover();
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
var nameInput = matePopoverEl.querySelector('#mate-profile-name');
|
|
717
|
-
nameInput.addEventListener('input', function() {
|
|
718
|
-
mateProfile.displayName = nameInput.value.trim();
|
|
719
|
-
updateMatePopoverHeader();
|
|
720
|
-
debouncedMateUpdate();
|
|
721
|
-
});
|
|
722
|
-
nameInput.addEventListener('keydown', function(e) {
|
|
723
|
-
if (e.key === 'Enter') { e.preventDefault(); hideMatePopover(); }
|
|
724
|
-
e.stopPropagation();
|
|
725
|
-
});
|
|
726
|
-
nameInput.addEventListener('keyup', function(e) { e.stopPropagation(); });
|
|
727
|
-
nameInput.addEventListener('keypress', function(e) { e.stopPropagation(); });
|
|
728
|
-
|
|
729
|
-
// Avatar upload button
|
|
730
|
-
var mateUploadBtn = matePopoverEl.querySelector('.profile-avatar-upload');
|
|
731
|
-
var mateFileInput = matePopoverEl.querySelector('#mate-profile-avatar-file');
|
|
732
|
-
if (mateUploadBtn && mateFileInput) {
|
|
733
|
-
mateUploadBtn.addEventListener('click', function() {
|
|
734
|
-
mateFileInput.click();
|
|
735
|
-
});
|
|
736
|
-
mateFileInput.addEventListener('change', function() {
|
|
737
|
-
var file = mateFileInput.files[0];
|
|
738
|
-
if (!file) return;
|
|
739
|
-
|
|
740
|
-
function uploadMateBlob(blob) {
|
|
741
|
-
blob.arrayBuffer().then(function(ab) {
|
|
742
|
-
var buf = new Uint8Array(ab);
|
|
743
|
-
fetch('/api/mate-avatar/' + encodeURIComponent(mateData.id), {
|
|
744
|
-
method: 'POST',
|
|
745
|
-
headers: { 'Content-Type': 'application/octet-stream' },
|
|
746
|
-
body: buf,
|
|
747
|
-
}).then(function(r) { return r.json(); }).then(function(data) {
|
|
748
|
-
if (data.ok) {
|
|
749
|
-
mateProfile.avatarCustom = data.avatar;
|
|
750
|
-
updateMatePopoverHeader();
|
|
751
|
-
if (mateUploadBtn) {
|
|
752
|
-
mateUploadBtn.classList.add('is-active');
|
|
753
|
-
}
|
|
754
|
-
var imprintButton = matePopoverEl && matePopoverEl.querySelector('.profile-use-imprint');
|
|
755
|
-
if (imprintButton) imprintButton.classList.remove('is-active');
|
|
756
|
-
debouncedMateUpdate();
|
|
757
|
-
}
|
|
758
|
-
});
|
|
759
|
-
});
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// Load image and open position picker
|
|
763
|
-
var img = new Image();
|
|
764
|
-
var objectUrl = URL.createObjectURL(file);
|
|
765
|
-
img.onload = function() {
|
|
766
|
-
showAvatarPositioner(img, objectUrl, function(croppedBlob) {
|
|
767
|
-
URL.revokeObjectURL(objectUrl);
|
|
768
|
-
uploadMateBlob(croppedBlob);
|
|
769
|
-
});
|
|
770
|
-
};
|
|
771
|
-
img.src = objectUrl;
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
if (!mateAvatarLocked) {
|
|
776
|
-
matePopoverEl.querySelector('.profile-use-imprint').addEventListener('click', function() {
|
|
777
|
-
mateProfile.avatarCustom = '';
|
|
778
|
-
updateMatePopoverHeader();
|
|
779
|
-
matePopoverEl.querySelector('.profile-use-imprint').classList.add('is-active');
|
|
780
|
-
matePopoverEl.querySelector('.profile-avatar-upload').classList.remove('is-active');
|
|
781
|
-
debouncedMateUpdate();
|
|
782
|
-
});
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
matePopoverEl.addEventListener('click', function(e) { e.stopPropagation(); });
|
|
786
|
-
|
|
787
|
-
// Position near anchor
|
|
788
|
-
document.body.appendChild(matePopoverEl);
|
|
789
|
-
refreshIcons();
|
|
790
|
-
|
|
791
|
-
var rect = anchorEl.getBoundingClientRect();
|
|
792
|
-
matePopoverEl.style.position = 'fixed';
|
|
793
|
-
matePopoverEl.style.left = (rect.right + 8) + 'px';
|
|
794
|
-
matePopoverEl.style.zIndex = '9999';
|
|
795
|
-
// Align bottom of popover with bottom of anchor icon
|
|
796
|
-
var popHeight = matePopoverEl.offsetHeight;
|
|
797
|
-
var bottomAligned = rect.bottom - popHeight;
|
|
798
|
-
matePopoverEl.style.top = Math.max(8, bottomAligned) + 'px';
|
|
799
|
-
|
|
800
|
-
setTimeout(function() {
|
|
801
|
-
document.addEventListener('click', closeMateOnOutside);
|
|
802
|
-
document.addEventListener('keydown', closeMateOnEscape);
|
|
803
|
-
}, 0);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
function closeMateOnOutside(e) {
|
|
807
|
-
if (matePopoverEl && !matePopoverEl.contains(e.target)) {
|
|
808
|
-
hideMatePopover();
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
function closeMateOnEscape(e) {
|
|
813
|
-
if (e.key === 'Escape' && matePopoverEl) {
|
|
814
|
-
hideMatePopover();
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
function hideMatePopover() {
|
|
819
|
-
if (matePopoverEl) {
|
|
820
|
-
matePopoverEl.remove();
|
|
821
|
-
matePopoverEl = null;
|
|
822
|
-
}
|
|
823
|
-
document.removeEventListener('click', closeMateOnOutside);
|
|
824
|
-
document.removeEventListener('keydown', closeMateOnEscape);
|
|
825
|
-
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { store } from './store.js';
|
|
2
|
+
|
|
3
|
+
// Hard navigation destroys detached panels, cached transcripts and sockets.
|
|
4
|
+
// Clear the rendered document first so revoked content cannot linger while the
|
|
5
|
+
// replacement page is loading or when that request fails.
|
|
6
|
+
export function leaveRevokedProject(url) {
|
|
7
|
+
store.set({ activeSessionId: null, activeProjectSlug: null, sessionActivatedProjectSlug: null, sessions: [], splitPanes: null });
|
|
8
|
+
document.body.replaceChildren();
|
|
9
|
+
window.location.replace(url || "/");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function reconnectDestination(info, slug) {
|
|
13
|
+
if (!slug || !info || !Array.isArray(info.projects)) return null;
|
|
14
|
+
var project = info.projects.find(function (item) { return item.slug === slug; });
|
|
15
|
+
if (!project) return "/";
|
|
16
|
+
return project.contentAccess === false ? "/p/" + encodeURIComponent(slug) + "/" : null;
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// This page never opens a project socket or loads project content modules.
|
|
2
|
+
var tabs = Array.from(document.querySelectorAll('[role="tab"]'));
|
|
3
|
+
function select(tab) {
|
|
4
|
+
tabs.forEach(function (item) {
|
|
5
|
+
var active = item === tab;
|
|
6
|
+
item.setAttribute("aria-selected", String(active));
|
|
7
|
+
item.tabIndex = active ? 0 : -1;
|
|
8
|
+
document.getElementById(item.getAttribute("aria-controls")).hidden = !active;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
tabs.forEach(function (tab, index) {
|
|
12
|
+
tab.addEventListener("click", function () { select(tab); });
|
|
13
|
+
tab.addEventListener("keydown", function (event) {
|
|
14
|
+
if (["ArrowLeft", "ArrowRight", "Home", "End"].indexOf(event.key) === -1) return;
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
var target = event.key === "Home" ? tabs[0] : event.key === "End" ? tabs[tabs.length - 1] : tabs[(index + (event.key === "ArrowRight" ? 1 : tabs.length - 1)) % tabs.length];
|
|
17
|
+
select(target);
|
|
18
|
+
target.focus();
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
select(tabs[0]);
|