clay-server 5.1.1-beta.1 → 5.2.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/account-auth-policy.js +21 -0
- package/lib/account-auth-socket.js +30 -0
- package/lib/account-auth-throttle.js +44 -0
- package/lib/account-auth-transport.js +48 -0
- package/lib/account-login-page.js +28 -0
- package/lib/account-passkey-challenges.js +31 -0
- package/lib/account-passkey-page.js +89 -0
- package/lib/account-passkey-policy.js +39 -0
- package/lib/account-password-page.js +69 -0
- package/lib/account-passwords.js +36 -0
- package/lib/account-remembered.js +77 -0
- package/lib/account-session-page.js +51 -0
- package/lib/account-session-store.js +82 -0
- package/lib/builtin-mates.js +19 -16
- package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
- package/lib/canonical-clay-record-authority.js +15 -0
- package/lib/canonical-clay-scheduling-authority.js +19 -0
- package/lib/claude-hook-installer.js +1 -239
- package/lib/claude-jsonl-watcher.js +1 -204
- package/lib/clay-control-presentation-binding.js +96 -0
- package/lib/clay-control-presentation.js +128 -0
- package/lib/clay-control-target-projection.js +26 -0
- package/lib/clay-mate-chat-receipts.js +26 -0
- package/lib/clay-mate-chat.js +88 -0
- package/lib/clay-mate-knowledge-input.js +26 -0
- package/lib/clay-mate-knowledge.js +95 -0
- package/lib/clay-mate-lifecycle.js +95 -0
- package/lib/clay-product-control-input.js +33 -0
- package/lib/clay-product-control-tools.js +51 -0
- package/lib/clay-product-control.js +247 -0
- package/lib/clay-project-lifecycle.js +154 -0
- package/lib/clay-project-record-input.js +44 -0
- package/lib/clay-project-records.js +84 -0
- package/lib/clay-scheduling-input.js +21 -0
- package/lib/clay-scheduling-receipts.js +26 -0
- package/lib/clay-scheduling.js +119 -0
- package/lib/clay-screen-controls.js +104 -0
- package/lib/clay-skill-install.js +1 -33
- package/lib/clay-workspace-controls.js +84 -0
- package/lib/clay-workspace-input.js +17 -0
- package/lib/clay-workspace-receipts.js +26 -0
- package/lib/cli-sessions.js +1 -300
- package/lib/codex-defaults.js +1 -28
- package/lib/context-usage.js +3 -2
- package/lib/contextual-screen-snapshot.js +38 -0
- package/lib/daemon-project-access.js +11 -0
- package/lib/daemon-project-lifecycle-callbacks.js +15 -0
- package/lib/daemon-project-lifecycle.js +262 -0
- package/lib/daemon-projects.js +1 -1
- package/lib/daemon.js +80 -276
- package/lib/default-ai-runtime.js +4 -8
- package/lib/dm-digest-cursor.js +120 -0
- package/lib/email-mcp-server.js +1 -1
- package/lib/issues-service.js +29 -15
- package/lib/kiro-defaults.js +1 -22
- package/lib/knowledge-db-import-validation.js +46 -0
- package/lib/knowledge-db-import.js +99 -0
- package/lib/knowledge-db-service.js +24 -33
- package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
- package/lib/knowledge-db-storage-nedb.js +66 -0
- package/lib/knowledge-db-storage.js +72 -0
- package/lib/knowledge-db-validation.js +0 -0
- package/lib/knowledge-document-index.js +2 -1
- package/lib/knowledge-file-store.js +7 -1
- package/lib/knowledge-product-operations.js +46 -0
- package/lib/mate-avatar-catalog.js +12 -0
- package/lib/mate-avatar-migration.js +41 -0
- package/lib/mate-context-service.js +138 -0
- package/lib/mate-context-tools.js +21 -0
- package/lib/mate-creation-mcp-server.js +2 -0
- package/lib/mate-knowledge-canonical-access.js +10 -0
- package/lib/mate-knowledge-mate-bound.js +53 -0
- package/lib/mate-knowledge-mcp-server.js +55 -8
- package/lib/mate-knowledge-service.js +16 -34
- package/lib/mate-knowledge-text-tools.js +106 -0
- package/lib/mate-lifecycle-service.js +94 -0
- package/lib/mate-message-delivery.js +43 -0
- package/lib/mate-ready-creation.js +9 -1
- package/lib/mate-schedule-input.js +29 -0
- package/lib/mate-schedule-lifecycle.js +151 -0
- package/lib/mate-scheduling.js +103 -0
- package/lib/mates.js +18 -6
- package/lib/mcp-agent-tools.js +117 -0
- package/lib/mcp-connection-store.js +119 -15
- package/lib/mcp-import-credentials.js +31 -0
- package/lib/mcp-local-transport.js +13 -0
- package/lib/mcp-oauth.js +8 -6
- package/lib/mcp-proxy.js +2 -32
- package/lib/mcp-query-bridge.js +30 -0
- package/lib/mcp-remote-connections.js +74 -20
- package/lib/mcp-source-adapters.js +1 -0
- package/lib/mcp-source-context.js +1 -0
- package/lib/mcp-source-discovery.js +1 -0
- package/lib/mcp-source-plugins.js +1 -0
- package/lib/mcp-source-restrictions.js +1 -0
- package/lib/mcp-tool-policy.js +9 -0
- package/lib/migrate-single-user.js +3 -23
- package/lib/notes-checklist.js +50 -0
- package/lib/notes.js +49 -3
- package/lib/os-user-diagnostics.js +2 -4
- package/lib/os-users.js +24 -70
- package/lib/pane-pending-interactions.js +20 -0
- package/lib/pane-session-activation.js +114 -0
- package/lib/pane-session-transport.js +26 -0
- package/lib/project-admin-overview.js +51 -0
- package/lib/project-ask-user.js +8 -4
- package/lib/project-connection.js +14 -10
- package/lib/project-control-git-view.js +12 -0
- package/lib/project-debate.js +1 -0
- package/lib/project-delegated-follow-up.js +2 -1
- package/lib/project-directory-claim.js +65 -0
- package/lib/project-file-operations.js +61 -0
- package/lib/project-filesystem.js +15 -85
- package/lib/project-full-access.js +23 -2
- package/lib/project-http.js +7 -4
- package/lib/project-knowledge.js +32 -18
- package/lib/project-lifecycle-operations.js +98 -0
- package/lib/project-lifecycle-process-witness.js +32 -0
- package/lib/project-lifecycle-runtime.js +50 -0
- package/lib/project-linux-access.js +22 -0
- package/lib/project-logs-canonical-clay.js +27 -0
- package/lib/project-logs-clay-query.js +16 -0
- package/lib/project-logs-schema.js +4 -2
- package/lib/project-logs-service.js +8 -7
- package/lib/project-logs.js +1 -0
- package/lib/project-loop.js +1 -0
- package/lib/project-mate-chat-control.js +55 -0
- package/lib/project-mate-creation-proposal.js +18 -3
- package/lib/project-mate-interaction.js +40 -62
- package/lib/project-mcp.js +54 -16
- package/lib/project-models.js +14 -31
- package/lib/project-notifications.js +76 -17
- package/lib/project-ownership.js +77 -0
- package/lib/project-pair-result-delivery.js +14 -3
- package/lib/project-pair-usage.js +12 -13
- package/lib/project-pending-message-queue.js +4 -1
- package/lib/project-product-control.js +89 -0
- package/lib/project-product-session-queue.js +46 -0
- package/lib/project-push-access.js +28 -0
- package/lib/project-scheduled-message-queue.js +30 -0
- package/lib/project-scheduled-messages.js +67 -68
- package/lib/project-scheduled-task-control.js +83 -0
- package/lib/project-scheduled-tasks.js +13 -2
- package/lib/project-scheduling-access.js +10 -0
- package/lib/project-server-settings.js +1 -0
- package/lib/project-session-actions.js +65 -0
- package/lib/project-session-delete.js +8 -1
- package/lib/project-session-document.js +27 -7
- package/lib/project-session-github.js +63 -19
- package/lib/project-session-history-actions.js +167 -0
- package/lib/project-session-linear.js +14 -6
- package/lib/project-session-notes.js +7 -3
- package/lib/project-session-pair.js +1 -1
- package/lib/project-session-runtime-actions.js +64 -0
- package/lib/project-session-spawn.js +2 -3
- package/lib/project-session-vendor.js +55 -0
- package/lib/project-sessions.js +103 -272
- package/lib/project-shared-browser.js +78 -17
- package/lib/project-studio-presentation.js +58 -0
- package/lib/project-user-knowledge.js +2 -1
- package/lib/project-user-message.js +67 -1
- package/lib/project-vendor-login.js +6 -36
- package/lib/project-workspace-operations.js +126 -0
- package/lib/project-workspace-query.js +19 -2
- package/lib/project.js +178 -45
- package/lib/public/app.js +46 -0
- package/lib/public/appearance-bootstrap.js +16 -0
- package/lib/public/auth/account-login.css +98 -0
- package/lib/public/auth/account-login.js +104 -0
- package/lib/public/css/clay-tool-activity.css +51 -0
- package/lib/public/css/clay-workspace.css +29 -0
- package/lib/public/css/command-palette.css +12 -33
- package/lib/public/css/contextual-clay.css +240 -0
- package/lib/public/css/home-debate-planning.css +2 -0
- package/lib/public/css/home-mate-creation.css +5 -0
- package/lib/public/css/input.css +6 -0
- package/lib/public/css/mate-avatar-gallery.css +12 -0
- package/lib/public/css/mate-conversation.css +10 -5
- package/lib/public/css/messages.css +6 -2
- package/lib/public/css/overlays.css +4 -2
- package/lib/public/css/project-admin-overview.css +13 -0
- package/lib/public/css/session-folders.css +11 -0
- package/lib/public/css/session-github.css +46 -1
- package/lib/public/css/shared-browser.css +35 -1
- package/lib/public/css/sticky-notes.css +87 -1
- package/lib/public/css/user-settings-sessions.css +42 -0
- package/lib/public/index.html +28 -10
- package/lib/public/mate-avatars/B01.png +0 -0
- package/lib/public/mate-avatars/B02.png +0 -0
- package/lib/public/mate-avatars/B03.png +0 -0
- package/lib/public/mate-avatars/B04.png +0 -0
- package/lib/public/mate-avatars/B05.png +0 -0
- package/lib/public/mate-avatars/B06.png +0 -0
- package/lib/public/mate-avatars/B07.png +0 -0
- package/lib/public/mate-avatars/B08.png +0 -0
- package/lib/public/mate-avatars/B09.png +0 -0
- package/lib/public/mate-avatars/B10.png +0 -0
- package/lib/public/mate-avatars/B11.png +0 -0
- package/lib/public/mate-avatars/B12.png +0 -0
- package/lib/public/mate-avatars/B13.png +0 -0
- package/lib/public/mate-avatars/B14.png +0 -0
- package/lib/public/mate-avatars/B15.png +0 -0
- package/lib/public/mate-avatars/B16.png +0 -0
- package/lib/public/mate-avatars/B17.png +0 -0
- package/lib/public/mate-avatars/B18.png +0 -0
- package/lib/public/mate-avatars/B19.png +0 -0
- package/lib/public/mate-avatars/B20.png +0 -0
- package/lib/public/mate-avatars/B21.png +0 -0
- package/lib/public/mate-avatars/B22.png +0 -0
- package/lib/public/mate-avatars/B23.png +0 -0
- package/lib/public/mate-avatars/B24.png +0 -0
- package/lib/public/mate-avatars/B25.png +0 -0
- package/lib/public/mate-avatars/B26.png +0 -0
- package/lib/public/mate-avatars/B27.png +0 -0
- package/lib/public/mate-avatars/B28.png +0 -0
- package/lib/public/mate-avatars/B29.png +0 -0
- package/lib/public/mate-avatars/B30.png +0 -0
- package/lib/public/mate-avatars/B31.png +0 -0
- package/lib/public/mate-avatars/B32.png +0 -0
- package/lib/public/mate-avatars/B33.png +0 -0
- package/lib/public/mate-avatars/B34.png +0 -0
- package/lib/public/mate-avatars/B35.png +0 -0
- package/lib/public/mate-avatars/B36.png +0 -0
- package/lib/public/mate-avatars/B37.png +0 -0
- package/lib/public/mate-avatars/B38.png +0 -0
- package/lib/public/mate-avatars/B39.png +0 -0
- package/lib/public/mate-avatars/B40.png +0 -0
- package/lib/public/mate-avatars/B41.png +0 -0
- package/lib/public/mate-avatars/B42.png +0 -0
- package/lib/public/mate-avatars/B43.png +0 -0
- package/lib/public/mate-avatars/B44.png +0 -0
- package/lib/public/mate-avatars/B45.png +0 -0
- package/lib/public/mate-avatars/B46.png +0 -0
- package/lib/public/mate-avatars/B47.png +0 -0
- package/lib/public/mate-avatars/B48.png +0 -0
- package/lib/public/mate-avatars/C01.png +0 -0
- package/lib/public/mate-avatars/C02.png +0 -0
- package/lib/public/mate-avatars/C03.png +0 -0
- package/lib/public/mate-avatars/C04.png +0 -0
- package/lib/public/mate-avatars/C05.png +0 -0
- package/lib/public/mate-avatars/C06.png +0 -0
- package/lib/public/mate-avatars/C07.png +0 -0
- package/lib/public/mate-avatars/C08.png +0 -0
- package/lib/public/mate-avatars/C09.png +0 -0
- package/lib/public/mate-avatars/C10.png +0 -0
- package/lib/public/mate-avatars/C11.png +0 -0
- package/lib/public/mate-avatars/C12.png +0 -0
- package/lib/public/mate-avatars/C13.png +0 -0
- package/lib/public/mate-avatars/C14.png +0 -0
- package/lib/public/mate-avatars/C15.png +0 -0
- package/lib/public/mate-avatars/C16.png +0 -0
- package/lib/public/mate-avatars/C17.png +0 -0
- package/lib/public/mate-avatars/C18.png +0 -0
- package/lib/public/mate-avatars/C19.png +0 -0
- package/lib/public/mate-avatars/C20.png +0 -0
- package/lib/public/mate-avatars/C21.png +0 -0
- package/lib/public/mate-avatars/C22.png +0 -0
- package/lib/public/mate-avatars/C23.png +0 -0
- package/lib/public/mate-avatars/C24.png +0 -0
- package/lib/public/mate-avatars/C25.png +0 -0
- package/lib/public/mate-avatars/C26.png +0 -0
- package/lib/public/mate-avatars/C27.png +0 -0
- package/lib/public/mate-avatars/C28.png +0 -0
- package/lib/public/mate-avatars/C29.png +0 -0
- package/lib/public/mate-avatars/C30.png +0 -0
- package/lib/public/mate-avatars/C31.png +0 -0
- package/lib/public/mate-avatars/C32.png +0 -0
- package/lib/public/mate-avatars/C33.png +0 -0
- package/lib/public/mate-avatars/C34.png +0 -0
- package/lib/public/mate-avatars/C35.png +0 -0
- package/lib/public/mate-avatars/C36.png +0 -0
- package/lib/public/mate-avatars/C37.png +0 -0
- package/lib/public/mate-avatars/C38.png +0 -0
- package/lib/public/mate-avatars/C39.png +0 -0
- package/lib/public/mate-avatars/C40.png +0 -0
- package/lib/public/mate-avatars/C41.png +0 -0
- package/lib/public/mate-avatars/C42.png +0 -0
- package/lib/public/mate-avatars/C43.png +0 -0
- package/lib/public/mate-avatars/C44.png +0 -0
- package/lib/public/mate-avatars/C45.png +0 -0
- package/lib/public/mate-avatars/C46.png +0 -0
- package/lib/public/mate-avatars/C47.png +0 -0
- package/lib/public/mate-avatars/C48.png +0 -0
- package/lib/public/mate-avatars/catalog.json +482 -0
- package/lib/public/mate-avatars/lead-clay.png +0 -0
- package/lib/public/modules/account-auth-settings.js +71 -0
- package/lib/public/modules/account-transport-settings.js +51 -0
- package/lib/public/modules/admin-settings-projects.js +6 -2
- package/lib/public/modules/app-connection.js +11 -1
- package/lib/public/modules/app-favicon.js +18 -9
- package/lib/public/modules/app-header.js +7 -4
- package/lib/public/modules/app-loop-ui.js +2 -0
- package/lib/public/modules/app-message-router.js +22 -1
- package/lib/public/modules/app-messages.js +119 -17
- package/lib/public/modules/app-misc.js +3 -1
- package/lib/public/modules/app-notifications.js +11 -5
- package/lib/public/modules/app-panels.js +61 -123
- package/lib/public/modules/app-projects.js +13 -0
- package/lib/public/modules/app-rate-limit.js +7 -27
- package/lib/public/modules/app-rendering.js +4 -3
- package/lib/public/modules/avatar.js +15 -41
- package/lib/public/modules/chat-render-runtime.js +20 -0
- package/lib/public/modules/clay-browser-links.js +47 -0
- package/lib/public/modules/clay-control-activity.js +214 -0
- package/lib/public/modules/clay-control-copy.js +36 -0
- package/lib/public/modules/clay-control-detail-targets.js +44 -0
- package/lib/public/modules/clay-control-object-targets.js +52 -0
- package/lib/public/modules/clay-control-target-visibility.js +12 -0
- package/lib/public/modules/clay-control-targets.js +44 -0
- package/lib/public/modules/clay-log-links.js +23 -0
- package/lib/public/modules/clay-navigation-render.js +52 -0
- package/lib/public/modules/clay-owner-navigation.js +33 -0
- package/lib/public/modules/clay-session-links.js +31 -0
- package/lib/public/modules/clay-studio-bridge.js +20 -0
- package/lib/public/modules/clay-studio-document.js +67 -0
- package/lib/public/modules/clay-studio-render.js +146 -0
- package/lib/public/modules/clay-tool-activity.js +140 -0
- package/lib/public/modules/clay-tool-presentation.js +342 -0
- package/lib/public/modules/command-palette.js +162 -40
- package/lib/public/modules/contextual-ask-session.js +26 -0
- package/lib/public/modules/contextual-clay-geometry.js +155 -0
- package/lib/public/modules/contextual-clay-session.js +130 -0
- package/lib/public/modules/contextual-clay-workspace.js +169 -0
- package/lib/public/modules/contextual-clay.js +250 -0
- package/lib/public/modules/contextual-composer.js +91 -0
- package/lib/public/modules/contextual-mate-context.js +117 -0
- package/lib/public/modules/contextual-mate-hint.js +40 -0
- package/lib/public/modules/contextual-mate-identity.js +23 -0
- package/lib/public/modules/contextual-mate-sessions.js +134 -0
- package/lib/public/modules/contextual-search.js +137 -0
- package/lib/public/modules/contextual-session-citations.js +58 -0
- package/lib/public/modules/debate.js +1 -0
- package/lib/public/modules/default-ai.js +11 -3
- package/lib/public/modules/elicitation-form.js +5 -0
- package/lib/public/modules/filebrowser.js +20 -1
- package/lib/public/modules/generation-stop.js +8 -5
- package/lib/public/modules/git-panel.js +3 -1
- package/lib/public/modules/history-replay-batch.js +13 -1
- package/lib/public/modules/home-debate-live.js +2 -0
- package/lib/public/modules/home-debate-planning.js +7 -7
- package/lib/public/modules/home-mate-avatar-editor.js +127 -208
- package/lib/public/modules/home-mate-chat.js +8 -6
- package/lib/public/modules/home-mate-creation.js +73 -1
- package/lib/public/modules/home-mate-settings.js +19 -12
- package/lib/public/modules/icon-strip-tooltip.js +2 -1
- package/lib/public/modules/input.js +88 -10
- package/lib/public/modules/issues-render.js +3 -2
- package/lib/public/modules/knowledge-db-workbench.js +4 -4
- package/lib/public/modules/markdown.js +6 -34
- package/lib/public/modules/mate-avatar-catalog.js +97 -0
- package/lib/public/modules/mate-knowledge-workbench.js +1 -1
- package/lib/public/modules/mate-management.js +40 -7
- package/lib/public/modules/mcp-connection-view.js +31 -13
- package/lib/public/modules/mcp-discovery-view.js +31 -0
- package/lib/public/modules/mcp-ui.js +23 -4
- package/lib/public/modules/mention.js +3 -0
- package/lib/public/modules/message-delivery.js +20 -2
- package/lib/public/modules/model-picker.js +2 -0
- package/lib/public/modules/pane-activation.js +214 -0
- package/lib/public/modules/pane-binding.js +82 -0
- package/lib/public/modules/pane-bridge.js +7 -4
- package/lib/public/modules/pane-browser-bridge.js +22 -0
- package/lib/public/modules/pane-file-bridge.js +4 -0
- package/lib/public/modules/pane-issue-bridge.js +4 -1
- package/lib/public/modules/passkey-browser.js +69 -0
- package/lib/public/modules/passkey-server-settings.js +57 -0
- package/lib/public/modules/pending-message-queue.js +1 -0
- package/lib/public/modules/permission-control.js +5 -4
- package/lib/public/modules/personal-settings-dialog.js +7 -1
- package/lib/public/modules/product-review.js +26 -0
- package/lib/public/modules/profile.js +1 -238
- package/lib/public/modules/project-access-recovery.js +17 -0
- package/lib/public/modules/project-admin-overview.js +21 -0
- package/lib/public/modules/project-chat-identity.js +13 -4
- package/lib/public/modules/project-logs-render.js +6 -2
- package/lib/public/modules/project-mate-navigation.js +144 -22
- package/lib/public/modules/rewind.js +5 -0
- package/lib/public/modules/scheduled-tasks.js +2 -0
- package/lib/public/modules/scheduler.js +2 -0
- package/lib/public/modules/search-clay-chat.js +5 -440
- package/lib/public/modules/server-settings-controls.js +10 -0
- package/lib/public/modules/server-settings.js +7 -2
- package/lib/public/modules/session-actions.js +5 -2
- package/lib/public/modules/session-context-menu.js +5 -0
- package/lib/public/modules/session-create-form.js +10 -10
- package/lib/public/modules/session-folder-layout.js +1 -1
- package/lib/public/modules/session-folder-view-menu.js +9 -0
- package/lib/public/modules/session-github.js +85 -14
- package/lib/public/modules/session-rich-drafts.js +21 -0
- package/lib/public/modules/session-switch-defer.js +67 -0
- package/lib/public/modules/session-work-primary.js +51 -0
- package/lib/public/modules/settings-defaults.js +27 -28
- package/lib/public/modules/shared-browser-settings.js +112 -0
- package/lib/public/modules/shared-browser-tabs.js +13 -3
- package/lib/public/modules/shared-browser.js +29 -6
- package/lib/public/modules/sidebar-mobile.js +4 -3
- package/lib/public/modules/sidebar-projects.js +1 -0
- package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
- package/lib/public/modules/sidebar-sessions.js +1 -0
- package/lib/public/modules/split-group-restore.js +68 -0
- package/lib/public/modules/split-pair-ui.js +1 -0
- package/lib/public/modules/split-pane-reconciler.js +15 -0
- package/lib/public/modules/split-pane-renderer.js +87 -6
- package/lib/public/modules/split-session-boundary.js +1 -1
- package/lib/public/modules/split-view.js +60 -68
- package/lib/public/modules/sticky-note-markdown.js +72 -6
- package/lib/public/modules/sticky-notes-actions.js +30 -0
- package/lib/public/modules/sticky-notes-browser.js +9 -2
- package/lib/public/modules/sticky-notes-card.js +23 -7
- package/lib/public/modules/sticky-notes-checklist.js +116 -0
- package/lib/public/modules/sticky-notes-editor.js +108 -44
- package/lib/public/modules/sticky-notes-shared.js +50 -2
- package/lib/public/modules/sticky-notes-state.js +66 -0
- package/lib/public/modules/sticky-notes.js +34 -51
- package/lib/public/modules/stt-controller.js +4 -1
- package/lib/public/modules/stt-recording.js +1 -1
- package/lib/public/modules/stt.js +7 -2
- package/lib/public/modules/terminal.js +9 -0
- package/lib/public/modules/theme.js +8 -1
- package/lib/public/modules/thinking-lifecycle.js +33 -3
- package/lib/public/modules/thinking-view.js +23 -1
- package/lib/public/modules/tools.js +60 -11
- package/lib/public/modules/tui-grab.js +1 -2
- package/lib/public/modules/user-settings-account.js +14 -1
- package/lib/public/modules/user-settings-appearance.js +10 -3
- package/lib/public/modules/user-settings-editors.js +1 -1
- package/lib/public/modules/user-settings-layout.js +11 -2
- package/lib/public/modules/user-settings-preferences.js +6 -2
- package/lib/public/modules/user-settings-profile.js +12 -2
- package/lib/public/modules/user-settings-sessions.js +120 -0
- package/lib/public/modules/user-settings.js +6 -2
- package/lib/public/modules/vendor-login-browser.js +5 -3
- package/lib/public/modules/vendor-login.js +2 -2
- package/lib/public/modules/vendor-priority.js +15 -1
- package/lib/public/modules/wireframe-workbench.js +5 -2
- package/lib/public/modules/you-activity.js +3 -1
- package/lib/public/modules/you.js +91 -6
- package/lib/public/muse-avatar.svg +4 -0
- package/lib/public/style.css +6 -0
- package/lib/public/sw.js +3 -1
- package/lib/safe-bash-commands.js +3 -45
- package/lib/scheduled-task-records.js +3 -1
- package/lib/scheduler.js +2 -0
- package/lib/sdk-bridge.js +342 -401
- package/lib/sdk-foreground-admission.js +16 -0
- package/lib/sdk-mcp-descriptors.js +2 -37
- package/lib/sdk-message-processor.js +52 -17
- package/lib/sdk-quota-snapshot.js +1 -1
- package/lib/sdk-response-recovery.js +1 -0
- package/lib/sdk-worker.js +2 -677
- package/lib/server-account-passkeys.js +186 -0
- package/lib/server-account-passwords.js +127 -0
- package/lib/server-account-security.js +53 -0
- package/lib/server-admin.js +63 -16
- package/lib/server-appearance-settings.js +13 -1
- package/lib/server-auth.js +107 -79
- package/lib/server-contextual-clay-settings.js +40 -0
- package/lib/server-contextual-mate-sessions.js +70 -0
- package/lib/server-dm.js +2 -1
- package/lib/server-global-ws.js +10 -20
- package/lib/server-home-chat-events.js +18 -4
- package/lib/server-home-chat.js +22 -20
- package/lib/server-home-clay-entry.js +23 -4
- package/lib/server-home-clay-session-links.js +29 -9
- package/lib/server-home-mate-creation.js +1 -0
- package/lib/server-home-mcp-consent.js +14 -0
- package/lib/server-mates.js +25 -62
- package/lib/server-owner-ui.js +118 -0
- package/lib/server-path-access.js +38 -0
- package/lib/server-project-removal.js +22 -0
- package/lib/server-settings.js +8 -2
- package/lib/server.js +165 -43
- package/lib/session-config-transition.js +45 -0
- package/lib/session-folders.js +7 -2
- package/lib/session-fork-history.js +21 -0
- package/lib/session-github.js +9 -2
- package/lib/session-hygiene.js +3 -35
- package/lib/session-permission-mode.js +4 -3
- package/lib/session-skill-scope.js +11 -0
- package/lib/session-visibility.js +5 -2
- package/lib/session-work-primary.js +50 -0
- package/lib/sessions.js +64 -99
- package/lib/shared-browser-cookie-sync.js +32 -0
- package/lib/shared-browser-cookies.js +79 -0
- package/lib/shared-browser-runtime.js +25 -9
- package/lib/shared-browser-storage-sync.js +43 -0
- package/lib/shared-browser-storage.js +101 -0
- package/lib/shared-browser-tools.js +2 -1
- package/lib/shared-browser-worker.js +46 -10
- package/lib/terminal-manager.js +65 -6
- package/lib/tool-llm.js +1 -1
- package/lib/tui-transcript-index.js +1 -132
- package/lib/user-knowledge-service.js +23 -1
- package/lib/users-auth.js +38 -3
- package/lib/users-contextual-clay-preferences.js +31 -0
- package/lib/users-create.js +97 -0
- package/lib/users-permissions.js +2 -8
- package/lib/users-server-pin.js +37 -0
- package/lib/users.js +18 -84
- package/lib/vendor-login-browser.js +1 -11
- package/lib/workspace-assignment-service.js +25 -0
- package/lib/workspace-query-access.js +4 -1
- package/lib/workspace-query-mcp-server.js +1 -1
- package/lib/workspace-query-service.js +13 -2
- package/lib/ws-request.js +1 -0
- package/lib/ws-schema.js +18 -2
- package/lib/yoke/acp-agent-profiles.js +7 -5
- package/lib/yoke/adapters/antigravity.js +3 -14
- package/lib/yoke/adapters/claude-query-contract.js +9 -0
- package/lib/yoke/adapters/claude.js +54 -50
- package/lib/yoke/adapters/codex-query-contract.js +24 -0
- package/lib/yoke/adapters/codex.js +53 -111
- package/lib/yoke/adapters/kiro.js +3 -1
- package/lib/yoke/adapters/muse-query-contract.js +7 -0
- package/lib/yoke/adapters/muse.js +122 -0
- package/lib/yoke/auth-events.js +17 -0
- package/lib/yoke/claude-hook-installer.js +271 -0
- package/lib/yoke/claude-jsonl-watcher.js +204 -0
- package/lib/yoke/claude-maintenance.js +55 -0
- package/lib/yoke/claude-permission-patterns.js +53 -0
- package/lib/yoke/claude-response-recovery.js +155 -0
- package/lib/yoke/claude-transcript-hygiene.js +34 -0
- package/lib/yoke/claude-worker-startup.js +28 -0
- package/lib/yoke/clay-skill-install.js +33 -0
- package/lib/yoke/cli-sessions.js +300 -0
- package/lib/yoke/codex-app-server.js +7 -12
- package/lib/yoke/codex-idle-recovery.js +81 -1
- package/lib/yoke/codex-recovery-admission.js +164 -0
- package/lib/yoke/configuration.js +13 -0
- package/lib/yoke/discovery.js +70 -0
- package/lib/yoke/errors.js +8 -0
- package/lib/yoke/host-environment.js +7 -0
- package/lib/yoke/index.js +9 -51
- package/lib/yoke/interface.js +116 -0
- package/lib/yoke/kiro-acp-server.js +5 -5
- package/lib/yoke/legacy-sessions.js +89 -0
- package/lib/yoke/login-protocol.js +25 -0
- package/lib/yoke/maintenance.js +12 -0
- package/lib/yoke/mcp-proxy.js +32 -0
- package/lib/yoke/mcp-source-adapters.js +91 -0
- package/lib/yoke/mcp-source-context.js +42 -0
- package/lib/yoke/mcp-source-discovery.js +169 -0
- package/lib/yoke/mcp-source-plugins.js +68 -0
- package/lib/yoke/mcp-source-restrictions.js +47 -0
- package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
- package/lib/yoke/model-preferences.js +6 -0
- package/lib/yoke/muse-artifacts.js +36 -0
- package/lib/yoke/muse-controls.js +50 -0
- package/lib/yoke/muse-input.js +64 -0
- package/lib/yoke/muse-items.js +157 -0
- package/lib/yoke/muse-policy.js +52 -0
- package/lib/yoke/muse-query.js +428 -0
- package/lib/yoke/muse-runtime.js +211 -0
- package/lib/yoke/muse-services.js +79 -0
- package/lib/yoke/muse-skills.js +79 -0
- package/lib/yoke/muse-turns.js +71 -0
- package/lib/yoke/options/acp.js +2 -0
- package/lib/yoke/options/antigravity.js +2 -0
- package/lib/yoke/options/claude.js +21 -0
- package/lib/yoke/options/codex-defaults.js +29 -0
- package/lib/yoke/options/codex-settings.js +21 -0
- package/lib/yoke/options/codex.js +6 -0
- package/lib/yoke/options/kiro-defaults.js +22 -0
- package/lib/yoke/options/kiro.js +5 -0
- package/lib/yoke/options/muse.js +5 -0
- package/lib/yoke/provider-contract.js +5 -0
- package/lib/yoke/providers/antigravity-executable.js +8 -0
- package/lib/yoke/providers/claude-executable.js +40 -0
- package/lib/yoke/providers/claude-model-descriptions.js +14 -0
- package/lib/yoke/providers/claude-process.js +97 -0
- package/lib/yoke/providers/claude-provision.js +75 -0
- package/lib/yoke/providers/codex-errors.js +8 -0
- package/lib/yoke/providers/muse-executable.js +17 -0
- package/lib/yoke/provisioning.js +6 -0
- package/lib/yoke/query-options.js +10 -0
- package/lib/yoke/response-recovery.js +41 -0
- package/lib/yoke/sdk-mcp-descriptors.js +37 -0
- package/lib/yoke/sdk-server-factory.js +7 -0
- package/lib/yoke/session-history.js +8 -0
- package/lib/yoke/session-tool-transport.js +34 -13
- package/lib/yoke/settings.js +23 -0
- package/lib/yoke/source-locations.js +4 -0
- package/lib/yoke/title-query.js +18 -7
- package/lib/yoke/tui-transcript-index.js +132 -0
- package/lib/yoke/usage.js +48 -0
- package/lib/yoke/user-input.js +13 -0
- package/lib/yoke/vendor-registry.js +81 -1
- package/package.json +11 -4
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// Owner-authenticated presentation only; this module never invokes a product action.
|
|
2
|
+
import { contextualMateStamp } from './contextual-mate-identity.js';
|
|
3
|
+
import { store } from './store.js';
|
|
4
|
+
import { mateAvatarUrl } from './avatar.js';
|
|
5
|
+
import { activityCopy, validActivity } from './clay-control-copy.js';
|
|
6
|
+
import { controlTarget, activityPlacement, visibleTarget } from './clay-control-targets.js';
|
|
7
|
+
|
|
8
|
+
function forward(message) {
|
|
9
|
+
if (!store.get('paneMode') || window.parent === window) return false;
|
|
10
|
+
store.set({ clayControlForwarded: message });
|
|
11
|
+
window.parent.postMessage({ type: 'clay-control-presentation', message: message }, location.origin);
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
export function clearClayControlActivity() {
|
|
15
|
+
var activity = store.get('clayControlActivity');
|
|
16
|
+
if (activity) {
|
|
17
|
+
clearTimeout(activity.timer);
|
|
18
|
+
cancelAnimationFrame(activity.frame);
|
|
19
|
+
if (activity.animation) activity.animation.cancel();
|
|
20
|
+
if (activity.observer) activity.observer.disconnect();
|
|
21
|
+
if (activity.resize) activity.resize.disconnect();
|
|
22
|
+
}
|
|
23
|
+
store.set({ clayControlActivity: null });
|
|
24
|
+
var element = document.getElementById('clay-control-activity');
|
|
25
|
+
if (element) element.remove();
|
|
26
|
+
}
|
|
27
|
+
function layout() {
|
|
28
|
+
var activity = store.get('clayControlActivity'), element = document.getElementById('clay-control-activity');
|
|
29
|
+
if (!activity || !element) return;
|
|
30
|
+
var surface = document.getElementById('contextual-clay');
|
|
31
|
+
var narrow = window.matchMedia('(max-width: 768px)').matches;
|
|
32
|
+
var workbench = narrow && Array.from(document.querySelectorAll('#file-viewer, #mate-knowledge-workbench, #project-logs-panel, #issues-panel, #scheduled-tasks-panel')).find(function (item) { return visibleTarget(item); });
|
|
33
|
+
var host = workbench || surface;
|
|
34
|
+
var inline = narrow && host && !host.hidden && host.getClientRects().length;
|
|
35
|
+
element.classList.toggle('is-inline', !!inline);
|
|
36
|
+
if (inline) {
|
|
37
|
+
if (element.parentNode !== host) {
|
|
38
|
+
if (host === surface) host.insertBefore(element, surface.querySelector('.contextual-clay-body'));
|
|
39
|
+
else host.insertBefore(element, host.children[1] || null);
|
|
40
|
+
}
|
|
41
|
+
element.classList.remove('has-target', 'is-flipped', 'is-reversed');
|
|
42
|
+
element.dataset.targeted = 'false'; element.style.visibility = 'visible';
|
|
43
|
+
element.style.marginTop = '6px';
|
|
44
|
+
var inlineBox = element.getBoundingClientRect(), offset = 0;
|
|
45
|
+
Array.from(document.querySelectorAll('.notif-banner.show')).forEach(function (banner) { var rect = banner.getBoundingClientRect(); if (rect.left < inlineBox.right && rect.right > inlineBox.left && rect.bottom > inlineBox.top && rect.top < inlineBox.bottom) offset = Math.max(offset, rect.bottom - inlineBox.top + 8); });
|
|
46
|
+
if (offset) element.style.marginTop = (6 + offset) + 'px';
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (element.parentNode !== document.body) document.body.appendChild(element);
|
|
50
|
+
element.style.removeProperty("margin-top");
|
|
51
|
+
var contextual = store.get('contextualClay') || {};
|
|
52
|
+
var background = activity.fromPane && (contextual.mode !== 'popover' || contextual.mateId !== activity.message.mateId);
|
|
53
|
+
var row = !background && !window.matchMedia('(pointer: coarse), (max-width: 768px)').matches && controlTarget(activity.message.target);
|
|
54
|
+
if (activity.targetNode !== row) {
|
|
55
|
+
if (activity.targetNode) activity.resize.unobserve(activity.targetNode);
|
|
56
|
+
activity.targetNode = row;
|
|
57
|
+
if (row) activity.resize.observe(row, { box: 'border-box' });
|
|
58
|
+
}
|
|
59
|
+
var obstacles = Array.from(document.querySelectorAll('#input-area, #contextual-clay, .ask-user-container:not(.answered), [role="dialog"], .notif-banner.show, #file-viewer-body, .wireframe-workbench-canvas')).filter(function (item) {
|
|
60
|
+
return (!row || !item.contains(row) || item.id === 'input-area') && !item.closest('details:not([open]), [hidden], [inert], [aria-hidden="true"]') && item.getClientRects().length && !item.hidden && getComputedStyle(item).visibility !== 'hidden' && Number(getComputedStyle(item).opacity) > 0;
|
|
61
|
+
}).map(function (item) { return item.getBoundingClientRect(); });
|
|
62
|
+
var box = element.getBoundingClientRect();
|
|
63
|
+
var place = activityPlacement(row, box.width, box.height, obstacles);
|
|
64
|
+
element.style.visibility = place ? 'visible' : 'hidden';
|
|
65
|
+
if (!place) { if (activity.animation) activity.animation.cancel(); element.dataset.targeted = 'false'; element.classList.remove('has-target', 'is-flipped', 'is-reversed'); element.style.removeProperty('--tip-x'); element.style.removeProperty('--tip-y'); return; }
|
|
66
|
+
var targeted = place.tipX !== undefined;
|
|
67
|
+
if (!targeted && activity.animation) { activity.animation.cancel(); activity.animation = null; }
|
|
68
|
+
element.classList.toggle('has-target', targeted);
|
|
69
|
+
element.classList.toggle('is-flipped', !!place.flip);
|
|
70
|
+
element.classList.toggle('is-reversed', !!place.reverse);
|
|
71
|
+
element.style.left = place.left + 'px'; element.style.top = place.top + 'px';
|
|
72
|
+
if (targeted) {
|
|
73
|
+
element.style.setProperty('--tip-x', (place.tipX - place.left) + 'px');
|
|
74
|
+
element.style.setProperty('--tip-y', (place.tipY - place.top) + 'px');
|
|
75
|
+
}
|
|
76
|
+
element.dataset.targeted = String(targeted);
|
|
77
|
+
if (document.getAnimations().some(function (animation) {
|
|
78
|
+
var node = animation.effect && animation.effect.target;
|
|
79
|
+
if (animation.playState !== 'running' || !(node instanceof Element) || element.contains(node) ||
|
|
80
|
+
!(row && (node === row || node.contains(row)) || node.matches('.notif-banner.show'))) return false;
|
|
81
|
+
if (!activity.motionSeen) activity.motionSeen = new WeakSet();
|
|
82
|
+
if (!activity.motionSeen.has(animation)) { activity.motionSeen.add(animation); activity.motionUntil = Date.now() + 5000; }
|
|
83
|
+
return Date.now() < activity.motionUntil;
|
|
84
|
+
})) scheduleLayout();
|
|
85
|
+
}
|
|
86
|
+
function scheduleLayout() {
|
|
87
|
+
var activity = store.get('clayControlActivity');
|
|
88
|
+
if (!activity || activity.frame) return;
|
|
89
|
+
activity.frame = requestAnimationFrame(function () { activity.frame = null; layout(); });
|
|
90
|
+
}
|
|
91
|
+
function render(message, mate, copy, fromPane) {
|
|
92
|
+
var existing = store.get('clayControlActivity');
|
|
93
|
+
if (existing && existing.message.id === message.id) {
|
|
94
|
+
existing.message = message;
|
|
95
|
+
existing.fromPane = !!fromPane;
|
|
96
|
+
clearTimeout(existing.timer);
|
|
97
|
+
existing.timer = setTimeout(clearClayControlActivity, message.terminal === false || ['review', 'running'].indexOf(message.phase) >= 0 ? 300000 : 6000);
|
|
98
|
+
document.querySelector('#clay-control-activity .clay-control-bubble').textContent = copy;
|
|
99
|
+
scheduleLayout(); return;
|
|
100
|
+
}
|
|
101
|
+
var previous = document.getElementById('clay-control-activity');
|
|
102
|
+
var previousRect = previous && previous.classList.contains('has-target') && previous.getBoundingClientRect();
|
|
103
|
+
clearClayControlActivity();
|
|
104
|
+
var element = document.createElement('div'); element.id = 'clay-control-activity';
|
|
105
|
+
element.setAttribute('role', 'status'); element.setAttribute('aria-live', 'polite'); element.setAttribute('aria-atomic', 'true');
|
|
106
|
+
var identity = document.createElement('span'); identity.className = 'clay-control-identity';
|
|
107
|
+
var avatar = document.createElement('img'); avatar.alt = ''; avatar.width = 20; avatar.height = 20;
|
|
108
|
+
avatar.addEventListener('error', function () { avatar.hidden = true; }, { once: true });
|
|
109
|
+
avatar.src = mateAvatarUrl(mate, 20);
|
|
110
|
+
var name = document.createElement('span'); name.className = 'clay-control-name';
|
|
111
|
+
name.textContent = (mate.profile || {}).displayName || mate.displayName || mate.name || (mate.builtinKey === 'clay' ? 'Clay' : 'Mate');
|
|
112
|
+
identity.append(avatar, name);
|
|
113
|
+
var bubble = document.createElement('span'); bubble.className = 'clay-control-bubble'; bubble.textContent = copy;
|
|
114
|
+
var pointer = document.createElement('span'); pointer.className = 'clay-control-pointer'; pointer.setAttribute('aria-hidden', 'true');
|
|
115
|
+
element.append(pointer, identity, bubble); document.body.appendChild(element);
|
|
116
|
+
var observer = new MutationObserver(function (changes) {
|
|
117
|
+
if (changes.some(function (change) { return !element.contains(change.target); })) scheduleLayout();
|
|
118
|
+
});
|
|
119
|
+
observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['class', 'hidden', 'inert', 'data-session-id', 'data-control-session-origin', 'data-control-revision', 'data-ref', 'data-task-id', 'data-open-issue', 'data-control-runtime', 'data-control-mate-stamp'] });
|
|
120
|
+
var resize = new ResizeObserver(scheduleLayout); resize.observe(document.body); resize.observe(element);
|
|
121
|
+
var activity = { message: message, fromPane: !!fromPane, observer: observer, resize: resize, frame: null,
|
|
122
|
+
timer: setTimeout(clearClayControlActivity, message.terminal === false || ['review', 'running'].indexOf(message.phase) >= 0 ? 300000 : 6000) };
|
|
123
|
+
store.set({ clayControlActivity: activity }); layout();
|
|
124
|
+
if (previousRect && element.classList.contains('has-target') && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
125
|
+
var next = element.getBoundingClientRect(), dx = previousRect.left - next.left, dy = previousRect.top - next.top;
|
|
126
|
+
if (Math.hypot(dx, dy) <= 600 && (dx || dy)) activity.animation = element.animate([
|
|
127
|
+
{ transform: 'translate(' + dx + 'px, ' + dy + 'px)' }, { transform: 'translate(0, 0)' }
|
|
128
|
+
], { duration: 140, easing: 'ease-out' });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export function handleClayControlActivity(message) {
|
|
132
|
+
if (message && message.type === 'clay_control_viewer') { store.set({ clayControlViewerRef: message.viewerRef }); return true; }
|
|
133
|
+
if (!message || message.type !== 'clay_control_activity') return false;
|
|
134
|
+
if (!validActivity(message) || message.recipientViewerRef !== store.get('clayControlViewerRef')) return true;
|
|
135
|
+
if (store.get('paneMode') && (message.sourceSessionOriginId !== store.get('sessionOriginId') || message.sourceSessionId !== store.get('activeSessionId') || message.mateId !== store.get('activeProjectMateId'))) return true;
|
|
136
|
+
if (!sourceMate(message)) return true;
|
|
137
|
+
if (forward(message)) return true;
|
|
138
|
+
acceptActivity(message);
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
function sourceMate(message) {
|
|
142
|
+
return (store.get('cachedMatesList') || []).find(function (mate) {
|
|
143
|
+
return !mate.archived && !mate.lifecycleDeletion && mate.id === message.mateId && mate.builtinKey === 'clay' && contextualMateStamp(mate) === message.sourceMateStamp;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function acceptActivity(message, fromPane) {
|
|
147
|
+
if ((message.ownerId || null) !== (store.get('myUserId') || null) || !store.get('connected')) return;
|
|
148
|
+
if (!sourceMate(message)) return;
|
|
149
|
+
var active = store.get('clayControlActivity');
|
|
150
|
+
var receipts = store.get('clayControlReceipts') || [];
|
|
151
|
+
var old = receipts.find(function (entry) { return entry.id === message.id; });
|
|
152
|
+
var order = store.get('clayControlOrder') || 0;
|
|
153
|
+
if (message.order < order || old && message.sequence <= old.sequence) return;
|
|
154
|
+
if (old && old.stopped) return;
|
|
155
|
+
receipts = receipts.filter(function (entry) { return entry.id !== message.id && Date.now() - entry.time < 300000; }).slice(-99);
|
|
156
|
+
receipts.push({ id: message.id, sequence: message.sequence, time: Date.now(), stopped: message.phase === 'clear' });
|
|
157
|
+
store.set({ clayControlOrder: message.order, clayControlReceipts: receipts });
|
|
158
|
+
if (message.phase === 'clear') { if (active && active.message.id === message.id) clearClayControlActivity(); return; }
|
|
159
|
+
var mate = (store.get('cachedMatesList') || []).find(function (item) { return !item.archived && !item.lifecycleDeletion && item.id === message.mateId && item.builtinKey === 'clay'; });
|
|
160
|
+
if (!mate) return;
|
|
161
|
+
render(message, mate, activityCopy(message), fromPane);
|
|
162
|
+
}
|
|
163
|
+
// Ordinary Mates retain their existing restricted navigation invocation feedback.
|
|
164
|
+
export function showClayNavigationActivity(target, failed) {
|
|
165
|
+
if (!target || !target.contextualSourceMateId) return;
|
|
166
|
+
var mate = (store.get('cachedMatesList') || []).find(function (item) { return !item.archived && item.id === target.contextualSourceMateId; });
|
|
167
|
+
if (!mate) return;
|
|
168
|
+
render({ id: 'ordinary-navigation', target: Object.assign({ kind: 'session' }, target) }, mate,
|
|
169
|
+
failed ? 'I could not start that navigation.' : 'I’m opening the reviewed conversation.');
|
|
170
|
+
}
|
|
171
|
+
function stopPresentation() {
|
|
172
|
+
var active = store.get('clayControlActivity');
|
|
173
|
+
if (active) {
|
|
174
|
+
var receipts = (store.get('clayControlReceipts') || []).slice();
|
|
175
|
+
receipts.push({ id: active.message.id, sequence: Number.MAX_SAFE_INTEGER, stopped: true, time: Date.now() });
|
|
176
|
+
store.set({ clayControlReceipts: receipts.slice(-100) });
|
|
177
|
+
}
|
|
178
|
+
clearClayControlActivity();
|
|
179
|
+
}
|
|
180
|
+
export function initClayControlActivity() {
|
|
181
|
+
store.subscribe(function (value, previous) {
|
|
182
|
+
if (!value.connected && previous.connected) store.set({ clayControlOrder: 0, clayControlViewerRef: null });
|
|
183
|
+
if (!value.clayControlActivity) return;
|
|
184
|
+
if (!value.connected || value.myUserId !== previous.myUserId || value.currentSlug !== previous.currentSlug || value.activeSessionId !== previous.activeSessionId) { stopPresentation(); return; }
|
|
185
|
+
if (value.cachedMatesList !== previous.cachedMatesList) {
|
|
186
|
+
var actor = value.clayControlActivity.message.mateId;
|
|
187
|
+
if (actor && !sourceMate(value.clayControlActivity.message)) stopPresentation();
|
|
188
|
+
}
|
|
189
|
+
scheduleLayout();
|
|
190
|
+
});
|
|
191
|
+
['resize', 'scroll'].forEach(function (name) { window.addEventListener(name, scheduleLayout, true); });
|
|
192
|
+
['transitionrun', 'transitionend', 'transitioncancel', 'animationstart', 'animationend', 'animationcancel'].forEach(function (name) { document.addEventListener(name, scheduleLayout, true); });
|
|
193
|
+
document.addEventListener('visibilitychange', function () { if (document.hidden) stopPresentation(); });
|
|
194
|
+
document.addEventListener('click', function (event) {
|
|
195
|
+
if (event.target.closest('#generation-stop, #autonomous-run-stop, #send-btn.stop')) stopPresentation();
|
|
196
|
+
}, true);
|
|
197
|
+
window.addEventListener('message', function (event) {
|
|
198
|
+
if (event.origin !== location.origin || !event.data || event.data.type !== 'clay-control-presentation') return;
|
|
199
|
+
var host = document.getElementById('contextual-clay'), message = event.data.message;
|
|
200
|
+
if (!validActivity(message)) return;
|
|
201
|
+
var frame = host && Array.from(host.querySelectorAll('iframe[data-canonical="true"]')).find(function (item) { return item.contentWindow === event.source; });
|
|
202
|
+
var bridge = frame && frame.conversation;
|
|
203
|
+
var identity = bridge && bridge.document === frame.contentDocument && bridge.source === frame.contentWindow && bridge.identity();
|
|
204
|
+
if (!identity || message.phase !== 'clear' && (!identity.connected || !identity.available) || identity.ownerId !== store.get('myUserId') || identity.mateId !== message.mateId || identity.sessionId !== message.sourceSessionId || identity.sessionOriginId !== message.sourceSessionOriginId || identity.viewerRef !== message.recipientViewerRef || !sourceMate(message)) return;
|
|
205
|
+
if (new URL(frame.src, location.href).pathname !== '/p/' + encodeURIComponent(message.sourceSlug) + '/') return;
|
|
206
|
+
acceptActivity(message, true);
|
|
207
|
+
});
|
|
208
|
+
document.addEventListener('contextual-ask-stopped', stopPresentation, true);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export function withdrawPaneControlActivity() {
|
|
212
|
+
var message = store.get('clayControlForwarded');
|
|
213
|
+
if (message) forward(Object.assign({}, message, { phase: 'clear', sequence: message.sequence + 1 }));
|
|
214
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
var domains = { session: 'conversation', project: 'project', mate: 'Mate profile', knowledge: 'Mate Knowledge', records: 'project record', schedule: 'schedule', conversation: 'Mate conversation', workspace: 'workspace', screen: 'screen', assignment: 'Driver work', studio: 'Studio workbench' };
|
|
2
|
+
var actions = {
|
|
3
|
+
rename: 'rename this conversation so it is easier to find', stop: 'request Stop so this work can settle',
|
|
4
|
+
model: 'change the model for this conversation', effort: 'adjust reasoning effort for this conversation',
|
|
5
|
+
permission: 'change the reviewed permission mode', delete: 'remove the reviewed item',
|
|
6
|
+
fork: 'fork the conversation at the reviewed checkpoint', rewind: 'restore the reviewed conversation checkpoint',
|
|
7
|
+
vendor: 'select the provider for this conversation', vendor_new_session: 'prepare a new conversation with the reviewed provider',
|
|
8
|
+
runtime: 'return this conversation to GUI chat', queue_add: 'queue the reviewed message for the Driver',
|
|
9
|
+
queue_edit: 'update the reviewed queued message', queue_cancel: 'cancel the reviewed queued message',
|
|
10
|
+
queue_reorder: 'reorder the reviewed message queue', navigate: 'open the reviewed conversation so we can continue there',
|
|
11
|
+
dismiss_notifications: 'dismiss the reviewed notifications', profile: 'update the reviewed Mate profile',
|
|
12
|
+
send: 'deliver the reviewed message to this Mate', assign: 'prepare the requested Driver work for your review', follow_up: 'prepare a follow-up for the existing Driver', document: 'open the requested document for editing', sketch: 'present the requested sketch', browser: 'operate the requested shared browser tab'
|
|
13
|
+
};
|
|
14
|
+
export function activityCopy(msg) {
|
|
15
|
+
var purpose = (['session', 'conversation', 'screen', 'mate', 'assignment', 'studio'].indexOf(msg.domain) >= 0 && Object.hasOwn(actions, msg.action) && actions[msg.action]) || 'apply the reviewed change to this ' + (domains[msg.domain] || 'item');
|
|
16
|
+
var endings = { review: 'I’m waiting for your review before I ' + purpose + '.', running: 'I’m working to ' + purpose + '.',
|
|
17
|
+
proposed: 'I saved the task proposal. Use Create task in Scheduled Tasks to create it; execution has not started.',
|
|
18
|
+
persisted: 'I saved the reviewed change.', completed: 'The service finished the reviewed change.', queued: 'I queued the request. The work has not finished yet.',
|
|
19
|
+
delivered: 'I sent the navigation request. I cannot yet confirm what is visible.', acknowledged: 'I started opening the conversation. Its visible result is still unconfirmed.',
|
|
20
|
+
rendered: 'The reviewed conversation is visibly open in the selected window.',
|
|
21
|
+
cancelled: 'I left the change unapplied.', failed: 'I could not finish this change. Please check the result before trying again.',
|
|
22
|
+
partial: 'Part of this change took effect, but the operation failed. Please check the result.', unknown: 'I cannot confirm the outcome. Please check before trying again.' };
|
|
23
|
+
if (msg.domain === 'assignment') { var work = { review: 'I prepared the Driver work. Please review its proposal before it starts.', queued: 'I submitted the approved Driver work for dispatch.', running: 'The Driver is working on the approved request.', completed: 'The Driver finished this request.', cancelled: 'I left this Driver request unapplied.', unknown: 'I cannot confirm the Driver outcome. Please inspect the work before retrying.' }; return work[msg.phase] || endings[msg.phase] || null; }
|
|
24
|
+
if (msg.domain === 'studio' && msg.phase === 'rendered') return 'The requested workbench content is visibly rendered in this window.';
|
|
25
|
+
if (msg.domain === 'studio' && msg.phase === 'render_unknown') return 'The service returned, but I could not confirm that the workbench content is visible.';
|
|
26
|
+
if (msg.domain === 'studio' && msg.phase === 'delivered') return 'I sent the requested content to the workbench. Its visible result is unconfirmed.';
|
|
27
|
+
if (msg.domain === 'studio' && msg.phase === 'completed') return 'I finished the requested workbench operation.';
|
|
28
|
+
return endings[msg.phase] || null;
|
|
29
|
+
}
|
|
30
|
+
export function validActivity(msg) {
|
|
31
|
+
return msg && msg.version === 1 && typeof msg.id === 'string' && /^activity:[\w-]{36}$/.test(msg.id) &&
|
|
32
|
+
typeof msg.sourceSessionOriginId === 'string' && !!msg.sourceSessionOriginId && typeof msg.sourceMateStamp === 'string' &&
|
|
33
|
+
typeof msg.recipientViewerRef === 'string' && /^viewer:[\w-]{36}$/.test(msg.recipientViewerRef) && Number.isSafeInteger(msg.sourceQueryGeneration) &&
|
|
34
|
+
Number.isSafeInteger(msg.order) && msg.order > 0 && Number.isSafeInteger(msg.sequence) && msg.sequence > 0 &&
|
|
35
|
+
(msg.phase === 'clear' || Object.hasOwn(domains, msg.domain) && !!activityCopy(msg));
|
|
36
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { visibleTarget } from './clay-control-target-visibility.js';
|
|
2
|
+
import { store } from './store.js';
|
|
3
|
+
|
|
4
|
+
function node(selector, id, revision, field) {
|
|
5
|
+
return Array.from(document.querySelectorAll(selector)).find(function (item) {
|
|
6
|
+
return item.dataset[field] === id && item.dataset.controlRevision === String(revision) && item.dataset.controlRuntime === store.get('controlRuntimeId');
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
// Fixed object adapters verify authoritative client state before locating rendered identities.
|
|
10
|
+
export function detailedControlTarget(target) {
|
|
11
|
+
if (target.kind === 'notifications') {
|
|
12
|
+
var notifications = store.get('clayControlNotifications') || [];
|
|
13
|
+
var nodes = target.items.map(function (item) {
|
|
14
|
+
if (!notifications.some(function (saved) { return saved.id === item.id && saved.controlRevision === item.revision; })) return null;
|
|
15
|
+
return Array.from(document.querySelectorAll('.notif-banner[data-notif-id]')).find(function (el) { return el.dataset.notifId === item.id && el.dataset.controlRevision === item.revision; });
|
|
16
|
+
});
|
|
17
|
+
return nodes.every(function (item) { return visibleTarget(item); }) ? nodes.length === 1 ? nodes[0] : nodes[0].parentElement : null;
|
|
18
|
+
}
|
|
19
|
+
if (target.projectSlug !== store.get('currentSlug') || target.runtimeId !== store.get('controlRuntimeId')) return null;
|
|
20
|
+
if (target.kind === 'git-set') {
|
|
21
|
+
var git = store.get('clayControlGitView');
|
|
22
|
+
if (!git || git.repository !== target.repository || git.runtimeId !== target.runtimeId || git.projectSlug !== target.projectSlug) return null;
|
|
23
|
+
var rows = target.files.map(function (file) { return git.files.some(function (saved) { return saved.path === file.path && saved.revision === file.revision; }) && node('.git-file-row', file.path, file.revision, 'controlGitPath'); });
|
|
24
|
+
if (!rows.every(function (item) { return visibleTarget(item); })) return null;
|
|
25
|
+
return document.querySelector('#git-panel-body');
|
|
26
|
+
}
|
|
27
|
+
if (target.kind !== 'knowledge' || !target.objectId) return null;
|
|
28
|
+
var main = (store.get('mateKnowledgeWorkspaces') || {})[target.projectSlug];
|
|
29
|
+
if (!main) return null;
|
|
30
|
+
if (target.object === 'document') {
|
|
31
|
+
var file = main.files.concat(main.deletedFiles || []).find(function (item) { return !item.common && item.id === target.objectId && item.name === target.name && String(item.revision) === target.revision; });
|
|
32
|
+
return file && node('.knowledge-file-row', 'local:' + file.id, target.revision, 'openDocument');
|
|
33
|
+
}
|
|
34
|
+
if (target.object === 'database') {
|
|
35
|
+
var database = main.files.find(function (item) { return !item.common && item.id === target.databaseId && String(item.revision) === target.revision; });
|
|
36
|
+
return database && node('.knowledge-file-row', 'local:' + target.databaseId, target.revision, 'openDocument');
|
|
37
|
+
}
|
|
38
|
+
var db = ((store.get('mateKnowledgeDatabaseWorkspaces') || {})[target.projectSlug] || {}).databases;
|
|
39
|
+
var view = db && db[target.databaseId];
|
|
40
|
+
if (!view || !view.database || String(view.database.revision) !== target.databaseRevision) return null;
|
|
41
|
+
if (target.object === 'database') return node('.knowledge-file-row', 'local:' + target.databaseId, target.revision, 'openDocument');
|
|
42
|
+
var record = (view.records || []).concat(view.recordDetail && view.recordDetail.record || []).find(function (item) { return item.id === target.objectId && String(item.revision) === target.revision; });
|
|
43
|
+
return record && Array.from(document.querySelectorAll('[data-db-record][data-db-database]')).find(function (item) { return item.dataset.dbRecord === record.id && item.dataset.dbDatabase === target.databaseId && item.dataset.controlRevision === target.revision && item.dataset.controlRuntime === target.runtimeId; });
|
|
44
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { studioControlTarget } from './clay-studio-render.js';
|
|
2
|
+
import { store } from './store.js';
|
|
3
|
+
import { detailedControlTarget } from './clay-control-detail-targets.js';
|
|
4
|
+
import { contextualMateStamp } from './contextual-mate-identity.js';
|
|
5
|
+
|
|
6
|
+
// Server projections identify the object; fixed adapters only locate its rendered view.
|
|
7
|
+
export function objectControlTarget(target) {
|
|
8
|
+
if (target.kind === 'surface') return studioControlTarget(target);
|
|
9
|
+
var detailed = detailedControlTarget(target);
|
|
10
|
+
if (['knowledge', 'notifications', 'git-set'].indexOf(target.kind) >= 0) return detailed;
|
|
11
|
+
if (target.kind === 'mate') {
|
|
12
|
+
var mate = (store.get('cachedMatesList') || []).find(function (item) { return item.id === target.mateId && !item.archived && !item.lifecycleDeletion && contextualMateStamp(item) === target.mateStamp; });
|
|
13
|
+
if (!mate) return null;
|
|
14
|
+
return Array.from(document.querySelectorAll('.icon-strip-project-mate[data-mate-id], .icon-strip-brand')).find(function (item) {
|
|
15
|
+
return item.dataset.mateId === mate.id && item.dataset.controlMateStamp === target.mateStamp || mate.builtinKey === 'clay' && item.classList.contains('icon-strip-brand');
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
var project = (store.get('projectsHubList') || []).find(function (item) { return item.slug === target.projectSlug && item.controlRuntimeId === target.runtimeId && item.contentAccess !== false; });
|
|
19
|
+
if (target.kind === 'project') {
|
|
20
|
+
if (!project) return null;
|
|
21
|
+
return Array.from(document.querySelectorAll('#icon-strip-projects .icon-strip-item[href]')).find(function (item) { return item.dataset.controlRuntime === target.runtimeId && new URL(item.href, location.href).pathname === '/p/' + encodeURIComponent(target.projectSlug) + '/'; });
|
|
22
|
+
}
|
|
23
|
+
if (target.projectSlug !== store.get('currentSlug') || target.runtimeId !== store.get('controlRuntimeId')) return null;
|
|
24
|
+
if (target.kind === 'record') {
|
|
25
|
+
var selector = target.area === 'issues' ? '.issue-row[data-open-issue], .issue-detail[data-control-ref]' : '.project-log-row[data-ref]';
|
|
26
|
+
return Array.from(document.querySelectorAll(selector)).find(function (item) {
|
|
27
|
+
return (item.dataset.openIssue || item.dataset.controlRef || item.dataset.ref) === target.ref && item.dataset.controlRevision === target.revision && item.dataset.controlRuntime === target.runtimeId;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (target.kind === 'file') {
|
|
31
|
+
var file = store.get('clayControlFileView');
|
|
32
|
+
if (!file || file.path !== target.path || file.revision !== target.revision || file.projectSlug !== target.projectSlug || file.runtimeId !== target.runtimeId) return null;
|
|
33
|
+
return document.querySelector('#file-viewer .file-viewer-header');
|
|
34
|
+
}
|
|
35
|
+
if (target.kind === 'git') {
|
|
36
|
+
var git = store.get('clayControlGitView');
|
|
37
|
+
if (!git || git.projectSlug !== target.projectSlug || git.runtimeId !== target.runtimeId || git.repository !== target.repository || !git.files.some(function (item) { return item.path === target.path && item.revision === target.revision; })) return null;
|
|
38
|
+
return Array.from(document.querySelectorAll('.git-file-row[data-control-git-path]')).find(function (item) { return item.dataset.controlGitPath === target.path && item.dataset.controlRevision === target.revision && item.dataset.controlRuntime === target.runtimeId; });
|
|
39
|
+
}
|
|
40
|
+
if (target.kind === 'terminal') {
|
|
41
|
+
var terminal = (store.get('clayControlTerminalViews') || []).find(function (item) { return item.id === target.id && item.identity === target.identity && item.revision === target.revision && item.runtimeId === target.runtimeId; });
|
|
42
|
+
if (!terminal) return null;
|
|
43
|
+
return Array.from(document.querySelectorAll('.terminal-tab[data-control-terminal-id]')).find(function (item) { return item.dataset.controlTerminalId === String(target.id) && item.dataset.controlRuntime === target.runtimeId; });
|
|
44
|
+
}
|
|
45
|
+
if (target.kind === 'schedule') {
|
|
46
|
+
if (target.sessionId !== store.get('activeSessionId') || target.sessionOriginId !== store.get('sessionOriginId')) return null;
|
|
47
|
+
var queue = store.get('pendingMessageQueue');
|
|
48
|
+
var logical = queue && (queue.items || []).some(function (item) { return item.schedule && item.schedule.logicalScheduleId === target.id && item.schedule.logicalRevision === target.revision; });
|
|
49
|
+
return Array.from(document.querySelectorAll('.scheduled-task-row[data-task-id], .pending-message-chip[data-control-schedule-id]')).find(function (item) { return (item.dataset.taskId === target.id || logical && item.dataset.controlScheduleId === target.id) && item.dataset.controlRevision === target.revision && item.dataset.controlRuntime === target.runtimeId; });
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function visibleTarget(element) {
|
|
2
|
+
if (!element || !element.isConnected || element.closest('[hidden], [inert], [aria-hidden="true"]')) return false;
|
|
3
|
+
var rect = element.getBoundingClientRect(), style = getComputedStyle(element);
|
|
4
|
+
if (style.visibility !== 'visible' || Number(style.opacity) === 0 || !rect.width || !rect.height || rect.left < 0 || rect.top < 0 || rect.right > innerWidth || rect.bottom > innerHeight) return false;
|
|
5
|
+
for (var parent = element.parentElement; parent; parent = parent.parentElement) {
|
|
6
|
+
if (Number(getComputedStyle(parent).opacity) === 0) return false;
|
|
7
|
+
}
|
|
8
|
+
return [rect.left + 2, rect.left + rect.width / 2, rect.right - 2].every(function (x) {
|
|
9
|
+
var hit = document.elementFromPoint(x, rect.top + rect.height / 2);
|
|
10
|
+
return hit && element.contains(hit);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { visibleTarget } from './clay-control-target-visibility.js';
|
|
2
|
+
export { visibleTarget };
|
|
3
|
+
import { objectControlTarget } from './clay-control-object-targets.js';
|
|
4
|
+
import { store } from './store.js';
|
|
5
|
+
|
|
6
|
+
// Stable product adapters only. Activity data never supplies a CSS selector.
|
|
7
|
+
export function controlTarget(target) {
|
|
8
|
+
if (!target) return null;
|
|
9
|
+
if (target.kind !== 'session') { var object = objectControlTarget(target); return visibleTarget(object) ? object : null; }
|
|
10
|
+
if (target.projectSlug !== store.get('currentSlug')) return null;
|
|
11
|
+
if (target.kind === 'session' && Number.isSafeInteger(target.sessionId) && typeof target.sessionOriginId === 'string' && target.sessionOriginId) {
|
|
12
|
+
return Array.from(document.querySelectorAll('.session-item[data-session-id]')).find(function (row) {
|
|
13
|
+
return Number(row.dataset.sessionId) === target.sessionId && row.dataset.controlSessionOrigin === target.sessionOriginId && visibleTarget(row);
|
|
14
|
+
}) || null;
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function overlaps(a, b) { return a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top; }
|
|
20
|
+
export function activityPlacement(row, width, height, obstacles) {
|
|
21
|
+
var margin = 12, rect = row && row.getBoundingClientRect();
|
|
22
|
+
var candidates = [];
|
|
23
|
+
if (rect) {
|
|
24
|
+
// Keep the cursor shaft seated in the identity pill in either vertical direction.
|
|
25
|
+
candidates.push({ left: rect.right + 8, top: rect.top + rect.height / 2 + 20, tipX: rect.right - 2, tipY: rect.top + rect.height / 2 });
|
|
26
|
+
candidates.push({ left: rect.right + 8, top: rect.top + rect.height / 2 - 34, tipX: rect.right - 2, tipY: rect.top + rect.height / 2, flip: true });
|
|
27
|
+
candidates.push({ left: rect.left - width - 8, top: rect.top + rect.height / 2 + 20, tipX: rect.left + 2, tipY: rect.top + rect.height / 2, reverse: true });
|
|
28
|
+
}
|
|
29
|
+
candidates.push({ left: innerWidth - width - margin, top: 64 });
|
|
30
|
+
candidates.push({ left: margin, top: 64 });
|
|
31
|
+
candidates.push({ left: innerWidth - width - margin, top: innerHeight - height - 80 });
|
|
32
|
+
candidates.push({ left: (innerWidth - width) / 2, top: 64 });
|
|
33
|
+
obstacles.slice(0, 12).forEach(function (obstacle) {
|
|
34
|
+
candidates.push({ left: innerWidth - width - margin, top: obstacle.bottom + 8 });
|
|
35
|
+
candidates.push({ left: margin, top: obstacle.bottom + 8 });
|
|
36
|
+
candidates.push({ left: (innerWidth - width) / 2, top: obstacle.bottom + 8 });
|
|
37
|
+
});
|
|
38
|
+
return candidates.find(function (candidate) {
|
|
39
|
+
var box = { left: candidate.left, right: candidate.left + width, top: candidate.top, bottom: candidate.top + height };
|
|
40
|
+
if (box.left < margin || box.right > innerWidth - margin || box.top < margin || box.bottom > innerHeight - margin) return false;
|
|
41
|
+
if (rect && overlaps(box, rect)) return false;
|
|
42
|
+
return !obstacles.some(function (obstacle) { return overlaps(box, obstacle); });
|
|
43
|
+
}) || null;
|
|
44
|
+
}
|
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { enhanceClayIssueLinks, isExactClayIssueReference } from './clay-issue-links.js';
|
|
2
2
|
import { enhanceGithubLinks } from './github-links.js';
|
|
3
|
+
import { escapeHtml } from './utils.js';
|
|
3
4
|
|
|
4
5
|
export function renderClayRecordLink(href, text) {
|
|
6
|
+
if (isExactClaySessionReference(href)) return renderClaySessionLink(href.trim(), text);
|
|
5
7
|
if (!isExactClayLogReference(href) && !isExactClayIssueReference(href)) return null;
|
|
6
8
|
return '<a href="#" data-clay-record-ref="' + href.trim() + '">' + text + '</a>';
|
|
7
9
|
}
|
|
10
|
+
|
|
11
|
+
export function isExactClaySessionReference(text) {
|
|
12
|
+
return parseClaySessionReference(text) !== null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function renderClaySessionLink(ref, text) {
|
|
16
|
+
var parsed = parseClaySessionReference(ref);
|
|
17
|
+
if (!parsed) return null;
|
|
18
|
+
var label = text ? String(text).trim() : "";
|
|
19
|
+
var safeLabel = escapeHtml(label).replace(/"/g, """);
|
|
20
|
+
var entryAttr = parsed.entryIndex === null ? "" : ' data-session-entry-index="' + parsed.entryIndex + '"';
|
|
21
|
+
return '<button type="button" class="clayos-session-link clayos-record-link" data-session-ref="' + parsed.ref + '"' + entryAttr + ' aria-label="Open session' + (safeLabel ? " from " + safeLabel : "") + '"><span>Session</span>' + (safeLabel ? '<small>' + safeLabel + '</small>' : '') + '</button>';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function parseClaySessionReference(text) {
|
|
25
|
+
var match = /^((?:session:[A-Za-z0-9_-]{24}))(?:#entry-([0-9]+))?$/.exec((text || "").trim());
|
|
26
|
+
if (!match) return null;
|
|
27
|
+
var entryIndex = match[2] === undefined ? null : Number(match[2]);
|
|
28
|
+
if (entryIndex !== null && (!Number.isSafeInteger(entryIndex) || entryIndex < 0)) return null;
|
|
29
|
+
return { ref: match[1], entryIndex: entryIndex };
|
|
30
|
+
}
|
|
8
31
|
export function parseClayLogReferences(text) {
|
|
9
32
|
var pattern = /\[clayos\/(log:[A-Za-z0-9_-]{24})(?:\s+[\u2014-]\s+([^\]\n]{1,80}))?\]|(^|[^A-Za-z0-9_/:])(log:[A-Za-z0-9_-]{24})(?![A-Za-z0-9_-])/g;
|
|
10
33
|
var results = [];
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { store } from './store.js';
|
|
2
|
+
import { getWs } from './ws-ref.js';
|
|
3
|
+
|
|
4
|
+
function visible(element) {
|
|
5
|
+
if (!element || !element.isConnected || element.closest('[hidden], [inert], [aria-hidden="true"]')) return false;
|
|
6
|
+
var box = element.getBoundingClientRect(), style = getComputedStyle(element);
|
|
7
|
+
if (style.visibility !== 'visible' || Number(style.opacity) === 0 || box.width <= 0 || box.height <= 0) return false;
|
|
8
|
+
for (var parent = element.parentElement; parent; parent = parent.parentElement) if (getComputedStyle(parent).visibility !== 'visible' || Number(getComputedStyle(parent).opacity) === 0) return false;
|
|
9
|
+
var left = Math.max(0, box.left), right = Math.min(innerWidth, box.right), top = Math.max(0, box.top), bottom = Math.min(innerHeight, box.bottom);
|
|
10
|
+
return right > left && bottom > top && [0.2, 0.5, 0.8].some(function (x) {
|
|
11
|
+
return [0.2, 0.5, 0.8].some(function (y) { var hit = document.elementFromPoint(left + (right - left) * x, top + (bottom - top) * y); return hit && element.contains(hit); });
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
// Bounded evidence from the exact authenticated document, never navigation receipt.
|
|
15
|
+
export function observeNavigationRendering(message, socket) {
|
|
16
|
+
var previous = store.get('clayNavigationRendering');
|
|
17
|
+
if (previous) previous.finish(false);
|
|
18
|
+
var target = message.target, owner = store.get('myUserId'), settled = false, stable = 0, frame, timer;
|
|
19
|
+
function finish(rendered) {
|
|
20
|
+
if (settled) return;
|
|
21
|
+
settled = true; cancelAnimationFrame(frame); clearTimeout(timer); unsubscribe();
|
|
22
|
+
document.removeEventListener('visibilitychange', hidden); document.removeEventListener('click', stop, true);
|
|
23
|
+
if (store.get('clayNavigationRendering') === attempt) store.set({ clayNavigationRendering: null });
|
|
24
|
+
if (getWs() === socket && socket.readyState === 1) socket.send(JSON.stringify({ type: 'clay_navigation_rendered', deliveryId: message.deliveryId,
|
|
25
|
+
renderToken: message.renderToken, visible: rendered, projectSlug: target.projectSlug, sessionId: target.sessionId,
|
|
26
|
+
sessionOriginId: target.sessionOriginId, surface: 'conversation', entryIndex: target.entryIndex }));
|
|
27
|
+
}
|
|
28
|
+
var attempt = { finish: finish };
|
|
29
|
+
store.set({ clayNavigationRendering: attempt });
|
|
30
|
+
function hidden() { if (document.hidden) finish(false); }
|
|
31
|
+
var unsubscribe = store.subscribe(function (value, old) {
|
|
32
|
+
if (!value.connected || value.myUserId !== owner || getWs() !== socket || value.currentSlug !== old.currentSlug && value.currentSlug !== target.projectSlug || value.activeSessionId !== old.activeSessionId && value.currentSlug === target.projectSlug && value.activeSessionId !== target.sessionId) finish(false);
|
|
33
|
+
});
|
|
34
|
+
function stop(event) { if (event.target.closest('#generation-stop, #autonomous-run-stop, #send-btn.stop')) finish(false); }
|
|
35
|
+
document.addEventListener('click', stop, true);
|
|
36
|
+
document.addEventListener('visibilitychange', hidden);
|
|
37
|
+
timer = setTimeout(function () { finish(false); }, Math.max(0, Math.min(5000, message.renderDeadline - Date.now())));
|
|
38
|
+
function inspect() {
|
|
39
|
+
if (settled) return;
|
|
40
|
+
if (document.hidden || getWs() !== socket || !store.get('connected') || store.get('myUserId') !== owner) { finish(false); return; }
|
|
41
|
+
var transcript = document.getElementById('messages');
|
|
42
|
+
var exact = store.get('currentSlug') === target.projectSlug && store.get('activeSessionId') === target.sessionId && store.get('sessionOriginId') === target.sessionOriginId &&
|
|
43
|
+
!store.get('paneMode') && !store.get('dmMode') && !store.get('homeShellVisible') && !store.get('replayingHistory') && transcript &&
|
|
44
|
+
transcript.dataset.controlSessionId === String(target.sessionId) && transcript.dataset.controlSessionOrigin === target.sessionOriginId && visible(transcript);
|
|
45
|
+
if (exact && target.entryIndex !== undefined) exact = transcript.dataset.controlHistoryRevision === target.historyRevision && Array.from(transcript.querySelectorAll('[data-history-index], [data-history-indexes]')).some(function (item) {
|
|
46
|
+
return (item.dataset.historyIndex === String(target.entryIndex) || (item.dataset.historyIndexes || '').split(',').indexOf(String(target.entryIndex)) >= 0) && visible(item);
|
|
47
|
+
});
|
|
48
|
+
stable = exact ? stable + 1 : 0;
|
|
49
|
+
if (stable >= 2) finish(true); else frame = requestAnimationFrame(inspect);
|
|
50
|
+
}
|
|
51
|
+
frame = requestAnimationFrame(inspect);
|
|
52
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { observeNavigationRendering } from './clay-navigation-render.js';
|
|
2
|
+
import { showClayNavigationActivity, clearClayControlActivity } from './clay-control-activity.js';
|
|
3
|
+
import { store } from './store.js';
|
|
4
|
+
import { getWs } from './ws-ref.js';
|
|
5
|
+
import { navigateToSession } from './command-palette.js';
|
|
6
|
+
function context() {
|
|
7
|
+
return JSON.stringify([store.get('currentSlug'), store.get('activeSessionId'), store.get('dmMode'), store.get('homeShellVisible'), store.get('homeChatMateId'), store.get('homeChatSessionId'), store.get('homeSubSurface'), (store.get('contextualClay') || {}).mode]);
|
|
8
|
+
}
|
|
9
|
+
export function handleOwnerNavigation(msg) {
|
|
10
|
+
if (msg.type !== 'clay_navigation_offer' && msg.type !== 'clay_navigation_apply') return false;
|
|
11
|
+
var ws = getWs();
|
|
12
|
+
if (!ws || ws.readyState !== 1) return true;
|
|
13
|
+
if (msg.type === 'clay_navigation_offer') {
|
|
14
|
+
if (document.hidden || store.get('paneMode')) return true;
|
|
15
|
+
store.set({ clayNavigationOffer: { id: msg.deliveryId, context: context(), socket: ws } });
|
|
16
|
+
ws.send(JSON.stringify({ type: 'clay_navigation_claim', deliveryId: msg.deliveryId }));
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
var offer = store.get('clayNavigationOffer');
|
|
20
|
+
store.set({ clayNavigationOffer: null });
|
|
21
|
+
var accepted = offer && offer.id === msg.deliveryId && offer.socket === ws && offer.context === context() && !document.hidden && !store.get('paneMode');
|
|
22
|
+
var status = 'refused';
|
|
23
|
+
if (accepted && msg.target && typeof msg.target.projectSlug === 'string' && Number.isSafeInteger(msg.target.sessionId)) {
|
|
24
|
+
try {
|
|
25
|
+
showClayNavigationActivity(msg.target, false); navigateToSession(msg.target, null, msg.target.entryIndex); status = 'accepted';
|
|
26
|
+
} catch (error) { showClayNavigationActivity(msg.target, true); status = 'failed'; }
|
|
27
|
+
}
|
|
28
|
+
if (status === 'refused') clearClayControlActivity();
|
|
29
|
+
// This acknowledges navigator invocation only. Rendering may finish after reconnect.
|
|
30
|
+
if (ws.readyState === 1) ws.send(JSON.stringify({ type: 'clay_navigation_ack', deliveryId: msg.deliveryId, status: status }));
|
|
31
|
+
if (status === 'accepted') observeNavigationRendering(msg, ws);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { parseClaySessionReference, renderClaySessionLink } from './clay-log-links.js';
|
|
2
|
+
|
|
3
|
+
// The prefix is a display compatibility label, never a navigation target.
|
|
4
|
+
var citationPattern = /\[([A-Za-z0-9][A-Za-z0-9_-]{0,79})\/(session:[A-Za-z0-9_-]{24}(?:#entry-[0-9]+)?)(?:\s+[\u2014-]\s+([^\]\n]{1,80}))?\]/g;
|
|
5
|
+
function matches(text) {
|
|
6
|
+
var pattern = new RegExp(citationPattern.source, 'g'), results = [], match;
|
|
7
|
+
while ((match = pattern.exec(text))) if (parseClaySessionReference(match[2])) results.push({ start: match.index, end: pattern.lastIndex, prefix: match[1], ref: match[2], label: match[3] || '' });
|
|
8
|
+
return results;
|
|
9
|
+
}
|
|
10
|
+
function button(match) {
|
|
11
|
+
var template = document.createElement('template');
|
|
12
|
+
template.innerHTML = renderClaySessionLink(match.ref, match.label);
|
|
13
|
+
return template.content.firstElementChild;
|
|
14
|
+
}
|
|
15
|
+
export function enhanceSessionCitations(root) {
|
|
16
|
+
// Historical assistants sometimes wrapped a whole project-labelled citation
|
|
17
|
+
// in inline code. Only that complete legacy token is a compatibility citation.
|
|
18
|
+
// Canonical code samples, mixed inline code and all fenced code stay literal.
|
|
19
|
+
if (root.closest('.msg-assistant')) root.querySelectorAll('code').forEach(function (code) {
|
|
20
|
+
if (code.closest('pre, a, button')) return;
|
|
21
|
+
var text = code.textContent || '', found = matches(text);
|
|
22
|
+
if (found.length === 1 && found[0].prefix !== 'clayos' && found[0].start === 0 && found[0].end === text.length) code.replaceWith(button(found[0]));
|
|
23
|
+
});
|
|
24
|
+
var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT), nodes = [], node;
|
|
25
|
+
while ((node = walker.nextNode())) if (node.parentElement && !node.parentElement.closest('code, pre, a, button') && matches(node.nodeValue || '').length) nodes.push(node);
|
|
26
|
+
nodes.forEach(function (node) {
|
|
27
|
+
var text = node.nodeValue || '', fragment = document.createDocumentFragment(), offset = 0;
|
|
28
|
+
matches(text).forEach(function (match) { fragment.appendChild(document.createTextNode(text.slice(offset, match.start))); fragment.appendChild(button(match)); offset = match.end; });
|
|
29
|
+
fragment.appendChild(document.createTextNode(text.slice(offset))); node.replaceWith(fragment);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { adoptDocumentSource, presentedDocument, initDocumentSource } from './clay-studio-document.js';
|
|
2
|
+
import { acceptStudioForward, trustedStudioFrame, initStudioReceipts } from './clay-studio-render.js';
|
|
3
|
+
import { presentMarkdownEdit, handleFileChanged } from './filebrowser.js';
|
|
4
|
+
import { openWireframe } from './wireframe-workbench.js';
|
|
5
|
+
|
|
6
|
+
export function initStudioBridge() {
|
|
7
|
+
initStudioReceipts(); initDocumentSource();
|
|
8
|
+
window.addEventListener('message', function (event) {
|
|
9
|
+
var data = event.data;
|
|
10
|
+
if (event.origin === location.origin && data && data.type === 'clay-studio-document-update' && data.message) {
|
|
11
|
+
var view = presentedDocument(data.message.path);
|
|
12
|
+
if (view && view.source === event.source && view.descriptor.token === data.token) handleFileChanged(data.message, view);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!data || ['clay-pane-present-markdown', 'clay-pane-present-wireframe'].indexOf(data.type) < 0 || !data.message || !data.message.controlPresentation) return;
|
|
16
|
+
if (!trustedStudioFrame(event, data) || !acceptStudioForward(event, data)) return;
|
|
17
|
+
if (data.type === 'clay-pane-present-markdown') { adoptDocumentSource(event, data, trustedStudioFrame(event, data)); presentMarkdownEdit(data.message); }
|
|
18
|
+
else openWireframe(data.message);
|
|
19
|
+
});
|
|
20
|
+
}
|