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
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import { forwardContextualSessionCitation, validContextualCitation, contextualCitationLink } from './contextual-session-citations.js';
|
|
1
2
|
import { mateAvatarUrl } from './avatar.js';
|
|
2
3
|
import { escapeHtml } from './utils.js';
|
|
3
4
|
import { refreshIcons } from './icons.js';
|
|
4
5
|
import { openSearch as openSessionSearch } from './session-search.js';
|
|
5
|
-
import { startSearchClayChat,
|
|
6
|
+
import { startSearchClayChat, retrySearchClayAsk } from './search-clay-chat.js';
|
|
6
7
|
import { getWs } from './ws-ref.js';
|
|
7
8
|
import { openProjectLog } from './project-logs.js';
|
|
9
|
+
import { store } from './store.js';
|
|
10
|
+
import { disarmStickyBottom } from './chat-render-runtime.js';
|
|
8
11
|
|
|
9
12
|
function formatRelativeDate(ts) {
|
|
10
13
|
if (!ts) return "";
|
|
@@ -27,7 +30,7 @@ var paletteEl = null, inputEl = null, resultsEl = null, footerEl = null;
|
|
|
27
30
|
var activeIndex = -1, items = [], debounceTimer = null, abortCtrl = null;
|
|
28
31
|
var pendingNav = null, cachedHomeData = [], cachedVersion = null;
|
|
29
32
|
var pendingLogNav = null;
|
|
30
|
-
var searchResults = [], searchQuery = "", searchPending = false
|
|
33
|
+
var searchResults = [], searchQuery = "", searchPending = false;
|
|
31
34
|
|
|
32
35
|
export function initCommandPalette(value) {
|
|
33
36
|
ctx = value;
|
|
@@ -60,6 +63,10 @@ function handleClaySessionLinkClick(event) {
|
|
|
60
63
|
openProjectLog(link.dataset.logRef);
|
|
61
64
|
return;
|
|
62
65
|
}
|
|
66
|
+
if (link.classList.contains('clayos-session-link') && forwardContextualSessionCitation(link)) return;
|
|
67
|
+
requestClayRecordLink(link);
|
|
68
|
+
}
|
|
69
|
+
export function requestClayRecordLink(link, citation) {
|
|
63
70
|
var ws = getWs();
|
|
64
71
|
if (!ws || ws.readyState !== 1) {
|
|
65
72
|
link.classList.add("is-error");
|
|
@@ -70,6 +77,10 @@ function handleClaySessionLinkClick(event) {
|
|
|
70
77
|
var requestId = "clayos-" + (isLog ? "log-" : "session-") + Date.now() + "-" + Math.random().toString(36).slice(2, 9);
|
|
71
78
|
if (isLog) link.dataset.logRequest = requestId;
|
|
72
79
|
else link.dataset.sessionRequest = requestId;
|
|
80
|
+
if (!isLog) store.set({ sessionNavigationRequestId: requestId, sessionNavigationRequestContext: {
|
|
81
|
+
projectSlug: store.get('currentSlug'),
|
|
82
|
+
sessionId: store.get('activeSessionId'), citation: citation || null
|
|
83
|
+
} });
|
|
73
84
|
link.classList.remove("is-error");
|
|
74
85
|
link.classList.add("is-loading");
|
|
75
86
|
var request = { requestId: requestId, surface: link.closest(".search-clay-chat") ? "search" : "home" };
|
|
@@ -79,24 +90,50 @@ function handleClaySessionLinkClick(event) {
|
|
|
79
90
|
} else {
|
|
80
91
|
request.type = "home_clay_session_resolve";
|
|
81
92
|
request.sessionRef = link.dataset.sessionRef;
|
|
93
|
+
if (citation) request.contextualSource = { mateId: citation.mateId, sessionId: citation.sessionId, sessionOriginId: citation.originId, mateStamp: citation.stamp };
|
|
94
|
+
if (link.dataset.sessionEntryIndex !== undefined) request.entryIndex = Number(link.dataset.sessionEntryIndex);
|
|
82
95
|
}
|
|
83
96
|
ws.send(JSON.stringify(request));
|
|
97
|
+
return true;
|
|
84
98
|
}
|
|
85
99
|
|
|
86
100
|
export function handleClaySessionTarget(msg) {
|
|
87
101
|
if (!msg || (msg.type !== "home_clay_session_target" && msg.type !== "home_clay_log_target")) return false;
|
|
88
102
|
var isLog = msg.type === "home_clay_log_target";
|
|
89
103
|
var links = document.querySelectorAll(isLog ? ".clayos-log-link[data-log-request]" : ".clayos-session-link[data-session-request]");
|
|
90
|
-
var
|
|
104
|
+
var sourceContext = store.get('sessionNavigationRequestContext');
|
|
105
|
+
var citation = !isLog && sourceContext && sourceContext.citation;
|
|
106
|
+
var link = !isLog ? contextualCitationLink(citation, msg.requestId) : null;
|
|
91
107
|
for (var i = 0; i < links.length; i++) {
|
|
92
108
|
if ((isLog ? links[i].dataset.logRequest : links[i].dataset.sessionRequest) === msg.requestId) link = links[i];
|
|
93
109
|
}
|
|
110
|
+
if (!isLog && link && link.ownerDocument !== document && !citation) { link.classList.remove('is-loading'); link.classList.add('is-error'); link.title = 'The view changed. Click again from the current conversation.'; delete link.dataset.sessionRequest; return true; }
|
|
111
|
+
if (!isLog && store.get('sessionNavigationRequestId') !== msg.requestId) {
|
|
112
|
+
if (link) {
|
|
113
|
+
link.classList.remove("is-loading");
|
|
114
|
+
delete link.dataset.sessionRequest;
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
if (!isLog) {
|
|
119
|
+
var requestContext = store.get('sessionNavigationRequestContext');
|
|
120
|
+
if (citation && (!validContextualCitation(citation) || msg.sessionRef !== citation.ref)) { if (link) { link.classList.remove('is-loading'); link.classList.add('is-error'); link.title = 'The view changed. Click again from the current conversation.'; delete link.dataset.sessionRequest; } store.set({ pendingSessionEntryNavigation: null, sessionNavigationRequestContext: null }); return true; }
|
|
121
|
+
if (requestContext && (String(store.get('currentSlug')) !== String(requestContext.projectSlug) || String(store.get('activeSessionId')) !== String(requestContext.sessionId))) {
|
|
122
|
+
if (link) {
|
|
123
|
+
link.classList.remove("is-loading");
|
|
124
|
+
delete link.dataset.sessionRequest;
|
|
125
|
+
}
|
|
126
|
+
store.set({ pendingSessionEntryNavigation: null, sessionNavigationRequestContext: null });
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
94
130
|
if (link) {
|
|
95
131
|
link.classList.remove("is-loading");
|
|
96
132
|
if (isLog) delete link.dataset.logRequest;
|
|
97
133
|
else delete link.dataset.sessionRequest;
|
|
98
134
|
}
|
|
99
135
|
if (msg.status !== "ready" || !msg.target) {
|
|
136
|
+
if (!isLog) store.set({ pendingSessionEntryNavigation: null });
|
|
100
137
|
if (link) {
|
|
101
138
|
link.classList.add("is-error");
|
|
102
139
|
link.title = msg.error || "Item not available";
|
|
@@ -108,7 +145,7 @@ export function handleClaySessionTarget(msg) {
|
|
|
108
145
|
navigateToLog(msg.target);
|
|
109
146
|
return true;
|
|
110
147
|
}
|
|
111
|
-
navigateToSession({ projectSlug: msg.target.projectSlug, sessionId: msg.target.sessionId }, null);
|
|
148
|
+
navigateToSession({ projectSlug: msg.target.projectSlug, sessionId: msg.target.sessionId }, null, msg.target.entryIndex);
|
|
112
149
|
return true;
|
|
113
150
|
}
|
|
114
151
|
|
|
@@ -120,11 +157,6 @@ export function openCommandPalette() {
|
|
|
120
157
|
var trigger = document.getElementById("cmd-palette-btn");
|
|
121
158
|
if (trigger) trigger.style.visibility = "hidden";
|
|
122
159
|
updateFooter();
|
|
123
|
-
if (attachSearchClayChat(resultsEl, showSearch, closeCommandPalette)) {
|
|
124
|
-
chatMode = true;
|
|
125
|
-
paletteEl.classList.add("is-chatting");
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
160
|
showSearch();
|
|
129
161
|
fetchHomeData();
|
|
130
162
|
}
|
|
@@ -136,24 +168,114 @@ export function closeCommandPalette() {
|
|
|
136
168
|
if (trigger) trigger.style.visibility = "";
|
|
137
169
|
if (debounceTimer) { clearTimeout(debounceTimer); debounceTimer = null; }
|
|
138
170
|
if (abortCtrl) { abortCtrl.abort(); abortCtrl = null; }
|
|
139
|
-
detachSearchClayChat();
|
|
140
171
|
}
|
|
141
172
|
|
|
142
173
|
export function setPaletteVersion(version) { cachedVersion = version; }
|
|
143
174
|
|
|
144
|
-
export function handlePaletteSessionSwitch() {
|
|
175
|
+
export function handlePaletteSessionSwitch(authoritative) {
|
|
145
176
|
if (pendingLogNav && ctx.currentSlug && ctx.currentSlug() === pendingLogNav.projectSlug) {
|
|
146
177
|
var logNav = pendingLogNav;
|
|
147
178
|
pendingLogNav = null;
|
|
148
179
|
openProjectLog(logNav.ref);
|
|
149
180
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
pendingNav
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (
|
|
181
|
+
// session_list precedes the connection's authoritative session_switched.
|
|
182
|
+
// Wait for that identity instead of requesting a duplicate initial replay.
|
|
183
|
+
if (authoritative === true && pendingNav && store.get('activeSessionId')) {
|
|
184
|
+
var nav = pendingNav;
|
|
185
|
+
pendingNav = null;
|
|
186
|
+
if (ctx.currentSlug && ctx.currentSlug() === nav.slug) {
|
|
187
|
+
navigateToSession({ projectSlug: nav.slug, sessionId: nav.sessionId }, nav.query, nav.entryIndex);
|
|
188
|
+
}
|
|
156
189
|
}
|
|
190
|
+
var pending = store.get('pendingSessionEntryNavigation');
|
|
191
|
+
if (pending && isActiveEntryNavigation(pending)) pending.awaitingTarget = false;
|
|
192
|
+
var highlight = store.get('sessionEntryHighlight');
|
|
193
|
+
if (highlight && !isCurrentEntryHighlight(highlight)) store.set({ sessionEntryHighlight: null });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function handlePaletteHistoryDone() {
|
|
197
|
+
var pending = store.get('pendingSessionEntryNavigation');
|
|
198
|
+
if (!pending) {
|
|
199
|
+
var highlight = store.get('sessionEntryHighlight');
|
|
200
|
+
if (highlight && isCurrentEntryHighlight(highlight)) jumpToSessionEntry(highlight.entryIndex, highlight);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (!isActiveEntryNavigation(pending)) {
|
|
204
|
+
if (pending.awaitingTarget) return;
|
|
205
|
+
store.set({ pendingSessionEntryNavigation: null });
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
var historyFrom = store.get('historyFrom') || 0;
|
|
209
|
+
if (pending.entryIndex < historyFrom) {
|
|
210
|
+
var ws = getWs();
|
|
211
|
+
if (ws && ws.readyState === 1) ws.send(JSON.stringify({ type: "load_more_history", before: historyFrom, target: pending.entryIndex }));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
jumpToSessionEntry(pending.entryIndex, pending);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function handlePaletteHistoryPrepended() {
|
|
218
|
+
var pending = store.get('pendingSessionEntryNavigation');
|
|
219
|
+
if (!pending) return;
|
|
220
|
+
if (!isActiveEntryNavigation(pending)) {
|
|
221
|
+
if (pending.awaitingTarget) return;
|
|
222
|
+
store.set({ pendingSessionEntryNavigation: null });
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
requestAnimationFrame(function () {
|
|
226
|
+
if (store.get('pendingSessionEntryNavigation') !== pending) return;
|
|
227
|
+
// This frame was scheduled for an already active target. A later
|
|
228
|
+
// navigation cancels it even if its initial awaiting flag was retained.
|
|
229
|
+
if (!isActiveEntryNavigation(pending)) {
|
|
230
|
+
store.set({ pendingSessionEntryNavigation: null });
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
handlePaletteHistoryDone();
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function isActiveEntryNavigation(pending) {
|
|
238
|
+
return String(store.get('currentSlug') || (ctx && ctx.currentSlug ? ctx.currentSlug() : "")) === String(pending.projectSlug) && String(store.get('activeSessionId')) === String(pending.sessionId);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function isCurrentEntryHighlight(highlight) {
|
|
242
|
+
return highlight.expiresAt > Date.now() && isActiveEntryNavigation(highlight)
|
|
243
|
+
&& highlight.sessionOriginId === (store.get('sessionOriginId') || null);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function jumpToSessionEntry(entryIndex, pending) {
|
|
247
|
+
if (pending && !isActiveEntryNavigation(pending)) return;
|
|
248
|
+
var messages = document.querySelectorAll("#messages [data-history-index], #messages [data-history-indexes]");
|
|
249
|
+
var target = null;
|
|
250
|
+
for (var i = 0; i < messages.length; i++) {
|
|
251
|
+
var indexes = (messages[i].dataset.historyIndexes || messages[i].dataset.historyIndex || "").split(",");
|
|
252
|
+
if (indexes.indexOf(String(entryIndex)) !== -1) { target = messages[i]; break; }
|
|
253
|
+
}
|
|
254
|
+
if (!target) return;
|
|
255
|
+
store.set({ pendingSessionEntryNavigation: null });
|
|
256
|
+
disarmStickyBottom();
|
|
257
|
+
var oldTargets = document.querySelectorAll("#messages .session-entry-target");
|
|
258
|
+
for (var oldIndex = 0; oldIndex < oldTargets.length; oldIndex++) oldTargets[oldIndex].classList.remove("session-entry-target");
|
|
259
|
+
var reducedMotion = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
260
|
+
// A repeated authoritative replay replaces the DOM after the initial jump.
|
|
261
|
+
// Retain only this exact origin for the original feedback lifetime.
|
|
262
|
+
var highlight = pending && pending.expiresAt ? pending : {
|
|
263
|
+
projectSlug: store.get('currentSlug'), sessionId: store.get('activeSessionId'),
|
|
264
|
+
sessionOriginId: store.get('sessionOriginId') || null, entryIndex: entryIndex,
|
|
265
|
+
expiresAt: Date.now() + (reducedMotion ? 700 : 1800),
|
|
266
|
+
};
|
|
267
|
+
store.set({ sessionEntryHighlight: highlight });
|
|
268
|
+
target.scrollIntoView({ behavior: reducedMotion ? "auto" : "smooth", block: "center" });
|
|
269
|
+
target.classList.remove("session-entry-target");
|
|
270
|
+
void target.offsetWidth;
|
|
271
|
+
target.classList.add("session-entry-target");
|
|
272
|
+
target.sessionEntryHighlight = highlight;
|
|
273
|
+
setTimeout(function () {
|
|
274
|
+
if (target.sessionEntryHighlight !== highlight) return;
|
|
275
|
+
target.classList.remove("session-entry-target");
|
|
276
|
+
delete target.sessionEntryHighlight;
|
|
277
|
+
if (store.get('sessionEntryHighlight') === highlight) store.set({ sessionEntryHighlight: null });
|
|
278
|
+
}, Math.max(0, highlight.expiresAt - Date.now()));
|
|
157
279
|
}
|
|
158
280
|
|
|
159
281
|
function navigateToLog(target) {
|
|
@@ -211,8 +333,6 @@ function buildDOM() {
|
|
|
211
333
|
}
|
|
212
334
|
|
|
213
335
|
function showSearch() {
|
|
214
|
-
chatMode = false;
|
|
215
|
-
paletteEl.classList.remove("is-chatting");
|
|
216
336
|
inputEl.value = searchQuery;
|
|
217
337
|
inputEl.disabled = false;
|
|
218
338
|
inputEl.focus({ preventScroll: true });
|
|
@@ -276,7 +396,6 @@ function sessionIcon(session) {
|
|
|
276
396
|
}
|
|
277
397
|
|
|
278
398
|
function renderSearch() {
|
|
279
|
-
if (chatMode) return;
|
|
280
399
|
var query = searchQuery.toLowerCase();
|
|
281
400
|
var sessions = query ? cachedHomeData.filter(function (item) {
|
|
282
401
|
return (item.sessionTitle || "").toLowerCase().indexOf(query) !== -1 || (item.projectTitle || "").toLowerCase().indexOf(query) !== -1;
|
|
@@ -286,11 +405,10 @@ function renderSearch() {
|
|
|
286
405
|
for (var r = 0; r < searchResults.length; r++) if (!seen[sessionKey(searchResults[r])]) { sessions.push(searchResults[r]); seen[sessionKey(searchResults[r])] = true; }
|
|
287
406
|
items = [];
|
|
288
407
|
var html = "", index = 0;
|
|
289
|
-
var
|
|
290
|
-
if (
|
|
291
|
-
items.push({ type:
|
|
292
|
-
html += '<
|
|
293
|
-
html += renderItem(index++, '<img src="/clay-studio-symbol.png" width="22" height="22" alt="">', "Return to Clay", escapeHtml(clayChat.processing ? "Clay is responding" : "Continue your current conversation"), clayChat.preview ? escapeHtml(clayChat.preview) : null, clayChat.updatedAt, " is-resume-clay");
|
|
408
|
+
var pendingAsk = store.get('contextualSearchAsk');
|
|
409
|
+
if (!query && pendingAsk && pendingAsk.ownerId === store.get('myUserId') && !pendingAsk.clientMessageId && /^(error|stopped)$/.test(pendingAsk.status)) {
|
|
410
|
+
items.push({ type: 'retry-clay-ask' });
|
|
411
|
+
html += renderItem(index++, '<img src="/clay-studio-symbol.png" width="22" height="22" alt="">', 'Retry previous question', escapeHtml(pendingAsk.text), null, null, ' is-retry-clay-ask');
|
|
294
412
|
}
|
|
295
413
|
if (sessions.length) {
|
|
296
414
|
html += '<div class="cmd-palette-group-label">' + (query ? "Conversations" : "Recent conversations") + '</div>';
|
|
@@ -305,8 +423,8 @@ function renderSearch() {
|
|
|
305
423
|
if (query) {
|
|
306
424
|
items.push({ type: "ask-clay", query: searchQuery });
|
|
307
425
|
if (!sessions.length && !searchPending) html += '<div class="cmd-palette-exact-empty">No exact matches. Clay can search by meaning.</div>';
|
|
308
|
-
html += '<div class="cmd-palette-group-label">
|
|
309
|
-
html += renderItem(index, '<img src="/clay-studio-symbol.png" width="22" height="22" alt="">',
|
|
426
|
+
html += '<div class="cmd-palette-group-label">Ask Clay</div>';
|
|
427
|
+
html += renderItem(index, '<img src="/clay-studio-symbol.png" width="22" height="22" alt="">', 'Ask Clay about “' + escapeHtml(searchQuery) + '”', "Start a new Clay conversation", null, null, " is-ask-clay");
|
|
310
428
|
}
|
|
311
429
|
if (!html) html = '<div class="cmd-palette-empty">No conversations yet.</div>';
|
|
312
430
|
resultsEl.innerHTML = html;
|
|
@@ -339,31 +457,35 @@ function setActive(index, skipScroll) {
|
|
|
339
457
|
}
|
|
340
458
|
|
|
341
459
|
function beginClayChat(query) {
|
|
342
|
-
if (
|
|
343
|
-
|
|
344
|
-
paletteEl.classList.add("is-chatting");
|
|
345
|
-
startSearchClayChat(query, resultsEl, showSearch, closeCommandPalette);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
function resumeClayChat() {
|
|
349
|
-
if (!attachSearchClayChat(resultsEl, showSearch, closeCommandPalette)) return;
|
|
350
|
-
chatMode = true;
|
|
351
|
-
paletteEl.classList.add("is-chatting");
|
|
460
|
+
if (!isCommandPaletteOpen()) return;
|
|
461
|
+
if (startSearchClayChat(query)) closeCommandPalette();
|
|
352
462
|
}
|
|
353
463
|
|
|
354
464
|
function activateItem(entry) {
|
|
355
|
-
if (entry.type ===
|
|
465
|
+
if (entry.type === 'retry-clay-ask') { if (retrySearchClayAsk()) closeCommandPalette(); return; }
|
|
356
466
|
if (entry.type === "ask-clay") { beginClayChat(entry.query); return; }
|
|
357
467
|
if (entry.type === "mate-session" || entry.type === "session") navigateToSession(entry.data, entry.query);
|
|
358
468
|
}
|
|
359
469
|
|
|
360
|
-
function navigateToSession(item, query) {
|
|
470
|
+
export function navigateToSession(item, query, entryIndex) {
|
|
361
471
|
closeCommandPalette();
|
|
472
|
+
pendingNav = null;
|
|
473
|
+
store.set({ sessionEntryHighlight: null });
|
|
474
|
+
var hasEntry = entryIndex !== null && entryIndex !== undefined && Number.isSafeInteger(Number(entryIndex)) && Number(entryIndex) >= 0;
|
|
475
|
+
store.set({ pendingSessionEntryNavigation: hasEntry ? { projectSlug: item.projectSlug, sessionId: item.sessionId, entryIndex: Number(entryIndex), awaitingTarget: true } : null });
|
|
362
476
|
if (ctx.currentSlug && ctx.currentSlug() === item.projectSlug) {
|
|
477
|
+
var alreadyActive = String(store.get('activeSessionId')) === String(item.sessionId);
|
|
478
|
+
if (alreadyActive) {
|
|
479
|
+
if (query) setTimeout(function () { openSessionSearch(query); }, 400);
|
|
480
|
+
if (hasEntry) requestAnimationFrame(function () {
|
|
481
|
+
if (!store.get('replayingHistory')) handlePaletteHistoryDone();
|
|
482
|
+
});
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
363
485
|
ctx.selectSession(item.sessionId);
|
|
364
486
|
if (query) setTimeout(function () { openSessionSearch(query); }, 400);
|
|
365
487
|
} else {
|
|
366
|
-
pendingNav = { slug: item.projectSlug, sessionId: item.sessionId, query: query };
|
|
488
|
+
pendingNav = { slug: item.projectSlug, sessionId: item.sessionId, query: query, entryIndex: hasEntry ? Number(entryIndex) : null };
|
|
367
489
|
ctx.switchProject(item.projectSlug);
|
|
368
490
|
}
|
|
369
491
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { store } from './store.js';
|
|
2
|
+
import { sendTextMessage } from './input.js';
|
|
3
|
+
import { pausePendingMessage } from './message-delivery.js';
|
|
4
|
+
import { stopGeneration } from './generation-stop.js';
|
|
5
|
+
|
|
6
|
+
export function submitContextualAsk(request) {
|
|
7
|
+
if (!request || typeof request.requestId !== 'string' || typeof request.text !== 'string') return null;
|
|
8
|
+
var current = store.get('contextualAskSubmission');
|
|
9
|
+
if (current && current.requestId === request.requestId) return current;
|
|
10
|
+
if (!request || request.ownerId !== store.get('myUserId') || request.sessionId !== store.get('paneSessionId') || request.sessionOriginId !== store.get('sessionOriginId') || !store.get('contextualSessionReady') || !store.get('connected') || store.get('contextualWriterSuspended') || !window.frameElement || window.frameElement.dataset.canonical !== 'true') return null;
|
|
11
|
+
// A fresh session has no user draft to replace. Refuse any ambiguous target.
|
|
12
|
+
if (document.getElementById('input').value || (store.get('pendingOutboundMessages') || []).length) return null;
|
|
13
|
+
store.set({ contextualAskSubmission: { requestId: request.requestId, status: 'sending' } });
|
|
14
|
+
sendTextMessage(request.text);
|
|
15
|
+
var outbound = (store.get('pendingOutboundMessages') || []).find(function (item) { return item.payload.text === request.text && item.sessionId === request.sessionId; });
|
|
16
|
+
var submission = { requestId: request.requestId, status: outbound ? 'sent' : 'unconfirmed', clientMessageId: outbound && outbound.payload.clientMessageId };
|
|
17
|
+
store.set({ contextualAskSubmission: submission });
|
|
18
|
+
return submission;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function pauseContextualAsk() {
|
|
22
|
+
var current = store.get('contextualAskSubmission');
|
|
23
|
+
if (current && current.clientMessageId) pausePendingMessage(current.clientMessageId);
|
|
24
|
+
if (current) store.set({ contextualAskSubmission: Object.assign({}, current, { status: 'stopped' }) });
|
|
25
|
+
}
|
|
26
|
+
export function stopContextualAsk() { pauseContextualAsk(); return stopGeneration(); }
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { contextualTrigger } from './contextual-mate-identity.js';
|
|
2
|
+
import { renderContextualMateHint } from './contextual-mate-hint.js';
|
|
3
|
+
import { store } from './store.js';
|
|
4
|
+
import { showToast } from './utils.js';
|
|
5
|
+
|
|
6
|
+
var endpoint = '/api/user/contextual-clay-geometry';
|
|
7
|
+
function state() { return store.get('contextualClayGeometry') || {}; }
|
|
8
|
+
function surface() { return document.getElementById('contextual-clay'); }
|
|
9
|
+
function narrow() { return window.matchMedia('(max-width: 768px)').matches; }
|
|
10
|
+
function rectValue(rect) { return { left: rect.left, top: rect.top, width: rect.width, height: rect.height }; }
|
|
11
|
+
function bounded(value) {
|
|
12
|
+
return { left: Math.round(Math.max(0, Math.min(16384, value.left))), top: Math.round(Math.max(0, Math.min(16384, value.top))), width: Math.round(Math.max(340, Math.min(2560, value.width))), height: Math.round(Math.max(360, Math.min(2160, value.height))) };
|
|
13
|
+
}
|
|
14
|
+
function setState(patch) { store.set({ contextualClayGeometry: Object.assign({}, state(), patch) }); }
|
|
15
|
+
function defaultGeometry() {
|
|
16
|
+
var trigger = contextualTrigger();
|
|
17
|
+
var anchor = trigger && trigger.getBoundingClientRect();
|
|
18
|
+
return { left: anchor ? anchor.right + 8 : 64, top: anchor ? anchor.top : 38, width: 480, height: 640 };
|
|
19
|
+
}
|
|
20
|
+
export function positionContextualClay() {
|
|
21
|
+
var element = surface();
|
|
22
|
+
var hint = renderContextualMateHint();
|
|
23
|
+
if (!element || narrow() || (store.get('contextualClay') || {}).mode === 'opening') return;
|
|
24
|
+
var desired = state().preview || state().desired || defaultGeometry();
|
|
25
|
+
var width = Math.min(desired.width, window.innerWidth - 16);
|
|
26
|
+
var height = Math.min(desired.height, window.innerHeight - 16);
|
|
27
|
+
var left = Math.max(8, Math.min(desired.left, window.innerWidth - width - 8));
|
|
28
|
+
var top = Math.max(8, Math.min(desired.top, window.innerHeight - height - 8));
|
|
29
|
+
if (hint && left < hint.right + 8 && left + width > hint.left && top < hint.bottom + 8 && top + height > hint.top) {
|
|
30
|
+
left = hint.right + 8; width = Math.min(width, window.innerWidth - left - 8);
|
|
31
|
+
}
|
|
32
|
+
element.style.setProperty('--contextual-left', left + 'px');
|
|
33
|
+
element.style.setProperty('--contextual-top', top + 'px');
|
|
34
|
+
element.style.setProperty('--contextual-width', width + 'px');
|
|
35
|
+
element.style.setProperty('--contextual-height', height + 'px');
|
|
36
|
+
}
|
|
37
|
+
async function flushSave() {
|
|
38
|
+
var current = state();
|
|
39
|
+
if (current.saving || !current.pending) return;
|
|
40
|
+
var owner = store.get('myUserId'); var value = current.pending;
|
|
41
|
+
setState({ saving: true, pending: null });
|
|
42
|
+
try {
|
|
43
|
+
var response = await fetch(endpoint, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'X-Clay-Settings': '1' }, body: JSON.stringify(value) });
|
|
44
|
+
if (!response.ok) throw new Error('Could not save popover position and size.');
|
|
45
|
+
if (store.get('myUserId') === owner) setState({ saved: value });
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (store.get('myUserId') === owner) showToast('Popover position and size could not be saved. Adjust again to retry.', 'error');
|
|
48
|
+
} finally {
|
|
49
|
+
if (store.get('myUserId') === owner) { setState({ saving: false }); flushSave(); }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function commit(value) {
|
|
53
|
+
var next = bounded(value);
|
|
54
|
+
setState({ desired: next, pending: next, revision: (state().revision || 0) + 1 });
|
|
55
|
+
positionContextualClay(); flushSave();
|
|
56
|
+
}
|
|
57
|
+
function finish(cancel) {
|
|
58
|
+
var drag = state().interaction;
|
|
59
|
+
if (!drag) return;
|
|
60
|
+
var value = state().preview;
|
|
61
|
+
setState({ interaction: null, preview: null });
|
|
62
|
+
var element = surface();
|
|
63
|
+
if (element) {
|
|
64
|
+
element.classList.remove('contextual-clay-manipulating');
|
|
65
|
+
var handle = drag.edge ? element.querySelector('[data-clay-resize="' + drag.edge + '"]') : element.querySelector('header');
|
|
66
|
+
if (handle && handle.hasPointerCapture(drag.pointerId)) handle.releasePointerCapture(drag.pointerId);
|
|
67
|
+
}
|
|
68
|
+
if (!cancel && value) {
|
|
69
|
+
if (!drag.edge && drag.desired) { value.width = drag.desired.width; value.height = drag.desired.height; }
|
|
70
|
+
commit(value);
|
|
71
|
+
}
|
|
72
|
+
else positionContextualClay();
|
|
73
|
+
}
|
|
74
|
+
function move(event) {
|
|
75
|
+
var drag = state().interaction;
|
|
76
|
+
if (!drag || event.pointerId !== drag.pointerId) return;
|
|
77
|
+
var dx = event.clientX - drag.x; var dy = event.clientY - drag.y;
|
|
78
|
+
if (!state().preview && Math.hypot(dx, dy) < 3) return;
|
|
79
|
+
var value = Object.assign({}, drag.start);
|
|
80
|
+
if (drag.edge) {
|
|
81
|
+
if (drag.edge.indexOf('e') >= 0) value.width = Math.max(340, Math.min(2560, window.innerWidth - value.left - 8, value.width + dx));
|
|
82
|
+
if (drag.edge.indexOf('s') >= 0) value.height = Math.max(360, Math.min(2160, window.innerHeight - value.top - 8, value.height + dy));
|
|
83
|
+
} else {
|
|
84
|
+
value.left = Math.max(8, Math.min(window.innerWidth - value.width - 8, value.left + dx));
|
|
85
|
+
value.top = Math.max(8, Math.min(window.innerHeight - value.height - 8, value.top + dy));
|
|
86
|
+
}
|
|
87
|
+
setState({ preview: value }); positionContextualClay();
|
|
88
|
+
}
|
|
89
|
+
async function loadPreference(owner) {
|
|
90
|
+
setState({ owner: owner, desired: null, revision: 0, pending: null, saving: false });
|
|
91
|
+
try {
|
|
92
|
+
var response = await fetch(endpoint);
|
|
93
|
+
if (!response.ok) throw new Error('Preference unavailable');
|
|
94
|
+
var data = await response.json();
|
|
95
|
+
if (store.get('myUserId') === owner && !state().revision && !state().interaction) {
|
|
96
|
+
setState({ desired: data.geometry, saved: data.geometry }); positionContextualClay();
|
|
97
|
+
}
|
|
98
|
+
} catch (error) { /* Keep the usable anchored default when preferences are unavailable. */ }
|
|
99
|
+
}
|
|
100
|
+
export function attachContextualGeometry(element) {
|
|
101
|
+
var header = element.querySelector('header');
|
|
102
|
+
header.tabIndex = 0;
|
|
103
|
+
header.setAttribute('aria-label', 'Move Clay conversation. Use arrow keys to move; hold Shift for larger steps.');
|
|
104
|
+
header.title = 'Drag to move · Arrow keys when focused';
|
|
105
|
+
['e', 's', 'se'].forEach(function (edge) {
|
|
106
|
+
var handle = document.createElement('button');
|
|
107
|
+
handle.type = 'button'; handle.dataset.clayResize = edge;
|
|
108
|
+
handle.setAttribute('aria-label', 'Resize Clay conversation' + (edge === 'e' ? ' width' : edge === 's' ? ' height' : '') + '. Use arrow keys; hold Shift for larger steps.');
|
|
109
|
+
handle.title = 'Drag to resize · Arrow keys when focused';
|
|
110
|
+
element.appendChild(handle);
|
|
111
|
+
});
|
|
112
|
+
element.addEventListener('pointerdown', function (event) {
|
|
113
|
+
var handle = event.target.closest('[data-clay-resize]');
|
|
114
|
+
var heading = event.target.closest('header');
|
|
115
|
+
if (narrow() || event.button !== 0 || (!handle && (!heading || event.target.closest('button, details, a, input')))) return;
|
|
116
|
+
if ((store.get('contextualClay') || {}).mode !== 'popover') return;
|
|
117
|
+
event.preventDefault();
|
|
118
|
+
var target = handle || header;
|
|
119
|
+
setState({ interaction: { pointerId: event.pointerId, x: event.clientX, y: event.clientY, start: rectValue(element.getBoundingClientRect()), desired: state().desired, edge: handle ? handle.dataset.clayResize : null } });
|
|
120
|
+
element.classList.add('contextual-clay-manipulating');
|
|
121
|
+
target.setPointerCapture(event.pointerId);
|
|
122
|
+
});
|
|
123
|
+
element.addEventListener('pointermove', move);
|
|
124
|
+
element.addEventListener('pointerup', function (event) { if (state().interaction && event.pointerId === state().interaction.pointerId) { move(event); finish(false); } });
|
|
125
|
+
element.addEventListener('pointercancel', function () { finish(true); });
|
|
126
|
+
element.addEventListener('lostpointercapture', function () { finish(true); });
|
|
127
|
+
element.addEventListener('keydown', function (event) {
|
|
128
|
+
if (narrow() || ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].indexOf(event.key) < 0) return;
|
|
129
|
+
var edge = event.target.dataset.clayResize;
|
|
130
|
+
if (event.target !== header && !edge) return;
|
|
131
|
+
event.preventDefault();
|
|
132
|
+
var value = rectValue(element.getBoundingClientRect()); var step = event.shiftKey ? 32 : 8;
|
|
133
|
+
var horizontal = event.key === 'ArrowLeft' || event.key === 'ArrowRight';
|
|
134
|
+
var delta = event.key === 'ArrowLeft' || event.key === 'ArrowUp' ? -step : step;
|
|
135
|
+
if (edge) {
|
|
136
|
+
if (horizontal && edge.indexOf('e') >= 0) value.width = Math.min(window.innerWidth - value.left - 8, value.width + delta);
|
|
137
|
+
if (!horizontal && edge.indexOf('s') >= 0) value.height = Math.min(window.innerHeight - value.top - 8, value.height + delta);
|
|
138
|
+
} else if (horizontal) value.left = Math.max(8, Math.min(window.innerWidth - value.width - 8, value.left + delta));
|
|
139
|
+
else value.top = Math.max(8, Math.min(window.innerHeight - value.height - 8, value.top + delta));
|
|
140
|
+
if (!edge && state().desired) { value.width = state().desired.width; value.height = state().desired.height; }
|
|
141
|
+
commit(value);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
export function initContextualGeometry() {
|
|
145
|
+
store.subscribe(function (value, previous) {
|
|
146
|
+
if (value.myUserId && value.myUserId !== previous.myUserId) { finish(true); loadPreference(value.myUserId); }
|
|
147
|
+
if ((value.contextualClay || {}).mode !== (previous.contextualClay || {}).mode) finish(true);
|
|
148
|
+
});
|
|
149
|
+
document.addEventListener('keydown', function (event) {
|
|
150
|
+
if (event.key === 'Escape' && state().interaction) { event.preventDefault(); event.stopImmediatePropagation(); finish(true); }
|
|
151
|
+
}, true);
|
|
152
|
+
window.addEventListener('blur', function () { finish(true); });
|
|
153
|
+
window.addEventListener('resize', function () { finish(true); positionContextualClay(); });
|
|
154
|
+
if (store.get('myUserId')) loadPreference(store.get('myUserId'));
|
|
155
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Session identity remains pinned across transport recovery and presentation.
|
|
2
|
+
import { autoResize, takeComposerDraft, restoreComposerDraft } from './input.js';
|
|
3
|
+
import { store } from './store.js';
|
|
4
|
+
import { withdrawPaneControlActivity } from './clay-control-activity.js';
|
|
5
|
+
import { initContextualComposer } from './contextual-composer.js';
|
|
6
|
+
import { submitContextualAsk, pauseContextualAsk, stopContextualAsk } from './contextual-ask-session.js';
|
|
7
|
+
|
|
8
|
+
// Session replay and authenticated account bootstrap complete independently.
|
|
9
|
+
function submissionReady() { var expected = window.frameElement && window.frameElement.dataset.expectedSessionOrigin; return (!expected || expected === store.get('sessionOriginId')) && !!(store.get('contextualSessionReady') && store.get('connected') && store.get('myUserId') && store.get('sessionOriginId') && store.get('activeSessionId') === store.get('paneSessionId')); }
|
|
10
|
+
function enabled() { return store.get('paneMode') && new URLSearchParams(location.search).get('contextual') === '1'; }
|
|
11
|
+
function renderSessionAvailability() {
|
|
12
|
+
var input = document.getElementById('input');
|
|
13
|
+
var frame = window.frameElement;
|
|
14
|
+
var mate = frame && (store.get('cachedMatesList') || []).find(function (item) { return item.id === frame.dataset.mateId; });
|
|
15
|
+
var name = mate && ((mate.profile || {}).displayName || mate.displayName || mate.name);
|
|
16
|
+
if (input && name) { input.setAttribute('aria-label', 'Message ' + name); if (name.length > 32) input.placeholder = 'Message this Mate…'; }
|
|
17
|
+
var wrapper = document.getElementById('input-wrapper');
|
|
18
|
+
if (wrapper) wrapper.inert = !submissionReady();
|
|
19
|
+
try {
|
|
20
|
+
var surface = window.parent.document.getElementById('contextual-clay');
|
|
21
|
+
var anchor = window.parent.document.querySelector('[aria-describedby="contextual-mate-hint"]') || window.parent.document.querySelector('.icon-strip-brand');
|
|
22
|
+
if (submissionReady() && surface && surface.dataset.focusEntry === 'true' && !window.frameElement.hidden && !window.frameElement.inert) {
|
|
23
|
+
delete surface.dataset.focusEntry;
|
|
24
|
+
if (surface.dataset.mode === 'popover' && window.parent.document.activeElement === anchor) document.getElementById('input').focus({ preventScroll: true });
|
|
25
|
+
}
|
|
26
|
+
} catch (error) { /* Cross-origin authentication owns focus. */ }
|
|
27
|
+
if (store.get('contextualSessionReady') && window.frameElement && !window.frameElement.hidden) {
|
|
28
|
+
window.frameElement.dataset.sessionId = String(store.get('paneSessionId'));
|
|
29
|
+
var parentSurface = window.parent.document.getElementById('contextual-clay');
|
|
30
|
+
if (parentSurface) parentSurface.dispatchEvent(new window.parent.CustomEvent('contextual-clay-ready'));
|
|
31
|
+
}
|
|
32
|
+
var warning = document.getElementById('contextual-session-warning');
|
|
33
|
+
if (!warning && store.get('contextualSessionUnavailable')) {
|
|
34
|
+
warning = document.createElement('p');
|
|
35
|
+
warning.id = 'contextual-session-warning'; warning.setAttribute('role', 'status');
|
|
36
|
+
warning.textContent = 'This Mate conversation is no longer available. Your draft is still here.';
|
|
37
|
+
document.getElementById('input-area').prepend(warning);
|
|
38
|
+
}
|
|
39
|
+
if (warning) warning.hidden = !store.get('contextualSessionUnavailable');
|
|
40
|
+
}
|
|
41
|
+
export function handleContextualSessionMessage(msg) {
|
|
42
|
+
if (!enabled()) return;
|
|
43
|
+
if (msg.type === 'session_list' && store.get('paneSessionId') && !(msg.sessions || []).some(function (session) { return session.id === store.get('paneSessionId'); })) {
|
|
44
|
+
store.set({ contextualSessionReady: false, contextualSessionUnavailable: true });
|
|
45
|
+
}
|
|
46
|
+
if (msg.type === 'session_switched') {
|
|
47
|
+
var pin = store.get('paneSessionId');
|
|
48
|
+
if (pin && msg.id !== pin) return true;
|
|
49
|
+
var path = store.get('wsPath').replace(/&session=\d+/g, '');
|
|
50
|
+
store.set({ contextualSessionReady: false, contextualSessionReceived: true, contextualSessionUnavailable: false, paneSessionId: msg.id, wsPath: path + '&session=' + msg.id });
|
|
51
|
+
}
|
|
52
|
+
if (msg.type === 'history_done' && store.get('contextualSessionReceived')) store.set({ contextualSessionReady: true });
|
|
53
|
+
renderSessionAvailability();
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
export function initContextualSession() {
|
|
57
|
+
if (!enabled()) return;
|
|
58
|
+
document.body.classList.add('contextual-chat-pane');
|
|
59
|
+
initContextualComposer();
|
|
60
|
+
// Bind at app readiness rather than iframe load: slow assets must not leave
|
|
61
|
+
// an already usable composer without its presentation keyboard handling.
|
|
62
|
+
document.addEventListener('keydown', function (event) {
|
|
63
|
+
if (event.key !== 'Escape') return;
|
|
64
|
+
try {
|
|
65
|
+
var surface = window.parent.document.getElementById('contextual-clay');
|
|
66
|
+
if (surface && window.frameElement && surface.contains(window.frameElement)) surface.dispatchEvent(new window.parent.CustomEvent('contextual-clay-keydown', { detail: { source: window, keyboardEvent: event } }));
|
|
67
|
+
} catch (error) { /* Authentication navigation owns its document. */ }
|
|
68
|
+
});
|
|
69
|
+
var surfaceBridge = window.parent.document.getElementById('contextual-clay');
|
|
70
|
+
if (surfaceBridge && window.frameElement && surfaceBridge.contains(window.frameElement)) window.frameElement.conversation = {
|
|
71
|
+
source: window, document: document,
|
|
72
|
+
submitAsk: submitContextualAsk,
|
|
73
|
+
pauseAsk: pauseContextualAsk,
|
|
74
|
+
stopAsk: stopContextualAsk,
|
|
75
|
+
identity: function () { return { mateId: store.get('activeProjectMateId'), viewerRef: store.get('clayControlViewerRef'), sessionId: store.get('paneSessionId'), sessionOriginId: store.get('sessionOriginId'), ownerId: store.get('myUserId'), connected: store.get('connected'), available: !store.get('contextualSessionUnavailable'), ready: submissionReady() }; },
|
|
76
|
+
suspend: function (value) { store.set({ contextualWriterSuspended: value }); document.getElementById('input').readOnly = value; },
|
|
77
|
+
checkDraft: function () { var draft = takeComposerDraft(); restoreComposerDraft(draft); },
|
|
78
|
+
take: function () { var draft = takeComposerDraft(); var drafts = Object.assign({}, store.get('sessionDrafts')); delete drafts[store.get('paneSessionId')]; store.set({ sessionDrafts: drafts }); return draft; },
|
|
79
|
+
restore: restoreComposerDraft
|
|
80
|
+
};
|
|
81
|
+
document.addEventListener('click', function (event) {
|
|
82
|
+
if (event.target.closest('#generation-stop, #autonomous-run-stop, #send-btn.stop')) {
|
|
83
|
+
pauseContextualAsk();
|
|
84
|
+
var askHost = window.parent.document.getElementById('contextual-clay');
|
|
85
|
+
if (askHost) askHost.dispatchEvent(new window.parent.CustomEvent('contextual-ask-stopped', { detail: { source: window } }));
|
|
86
|
+
}
|
|
87
|
+
if (store.get('contextualWriterSuspended') && event.target.closest('#send-btn, #attach-wrap, #contextual-attach-btn, #config-chip-wrap, .ask-user-container')) { event.preventDefault(); event.stopImmediatePropagation(); }
|
|
88
|
+
}, true);
|
|
89
|
+
store.set({ contextualSessionReady: false, contextualSessionUnavailable: false });
|
|
90
|
+
var width = 0;
|
|
91
|
+
new ResizeObserver(function (entries) {
|
|
92
|
+
var next = entries[0].contentRect.width;
|
|
93
|
+
if (next === width || next === 0) return;
|
|
94
|
+
width = next;
|
|
95
|
+
autoResize();
|
|
96
|
+
}).observe(document.getElementById('input-textarea-wrap'));
|
|
97
|
+
function guardPendingReview(event) {
|
|
98
|
+
if ((!store.get('contextualSessionReady') || store.get('contextualWriterSuspended')) && event.target.closest('.ask-user-submit, .ask-user-other input') && (event.type === 'click' || event.key === 'Enter')) { event.preventDefault(); event.stopImmediatePropagation(); }
|
|
99
|
+
}
|
|
100
|
+
document.addEventListener('click', guardPendingReview, true);
|
|
101
|
+
document.addEventListener('keydown', guardPendingReview, true);
|
|
102
|
+
store.subscribe(function (value, previous) {
|
|
103
|
+
if (value.connected !== previous.connected || value.contextualSessionReady !== previous.contextualSessionReady || value.contextualSessionUnavailable !== previous.contextualSessionUnavailable) {
|
|
104
|
+
var parentSurface = window.parent.document.getElementById('contextual-clay');
|
|
105
|
+
if (parentSurface && window.frameElement && !window.frameElement.hidden && parentSurface.contains(window.frameElement)) parentSurface.dispatchEvent(new window.parent.CustomEvent('contextual-clay-availability'));
|
|
106
|
+
}
|
|
107
|
+
if (!value.connected && previous.connected) {
|
|
108
|
+
withdrawPaneControlActivity();
|
|
109
|
+
var input = document.getElementById('input');
|
|
110
|
+
var drafts = Object.assign({}, value.sessionDrafts);
|
|
111
|
+
if (value.paneSessionId && input) drafts[value.paneSessionId] = input.value;
|
|
112
|
+
store.set({ contextualSessionReady: false, contextualSessionReceived: false, sessionDrafts: drafts });
|
|
113
|
+
}
|
|
114
|
+
renderSessionAvailability();
|
|
115
|
+
});
|
|
116
|
+
renderSessionAvailability();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Capture bounded metadata separately from user attachments. This is
|
|
120
|
+
// untrusted reference data, never approval or a target for an existing action.
|
|
121
|
+
export function contextualScreenReference() {
|
|
122
|
+
if (!enabled() || window.parent === window) return null;
|
|
123
|
+
try {
|
|
124
|
+
var surface = window.parent.document.getElementById('contextual-clay');
|
|
125
|
+
if (!surface || !window.frameElement || window.frameElement.hidden || window.frameElement.dataset.canonical !== 'true' || !surface.contains(window.frameElement)) return null;
|
|
126
|
+
var reference = JSON.parse(surface.dataset.screenReference || 'null');
|
|
127
|
+
if (!reference || reference.ownerId !== (store.get('myUserId') || null)) return null;
|
|
128
|
+
return { version: 1, viewId: typeof reference.viewId === 'string' ? reference.viewId.slice(0, 100) : null, projectTitle: typeof reference.projectTitle === 'string' ? reference.projectTitle.slice(0, 160) : null, conversationTitle: typeof reference.conversationTitle === 'string' ? reference.conversationTitle.slice(0, 160) : null, projectSlug: typeof reference.projectSlug === 'string' ? reference.projectSlug.slice(0, 160) : null, sessionId: Number.isSafeInteger(reference.sessionId) ? reference.sessionId : null, screen: String(reference.screen || '').slice(0, 40) };
|
|
129
|
+
} catch (error) { return null; }
|
|
130
|
+
}
|