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
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
import { refreshIcons, iconHtml } from './icons.js';
|
|
9
9
|
import { extractMarkdown, renderMiniMarkdown } from './sticky-note-markdown.js';
|
|
10
10
|
import { enhanceClayLogLinks } from './clay-log-links.js';
|
|
11
|
-
import { debouncedTextUpdate, syncTitle } from './sticky-notes-shared.js';
|
|
11
|
+
import { debouncedTextUpdate, syncTitle, getNoteUiState, setNoteUiState, subscribeNoteUiState } from './sticky-notes-shared.js';
|
|
12
|
+
|
|
13
|
+
import { renderTaskControls } from './sticky-notes-checklist.js';
|
|
14
|
+
import { requestChecklistMode } from './sticky-notes-actions.js';
|
|
15
|
+
import { mutateChecklist } from './sticky-notes-state.js';
|
|
12
16
|
|
|
13
17
|
var formatToolbarEl = null;
|
|
14
18
|
|
|
@@ -145,51 +149,112 @@ function positionToolbarAtRange(toolbar, range) {
|
|
|
145
149
|
});
|
|
146
150
|
}
|
|
147
151
|
|
|
148
|
-
export function setupTextEdit(textarea, rendered, noteId, mdBtn) {
|
|
152
|
+
export function setupTextEdit(textarea, rendered, noteId, mdBtn, checklistBtn, noteData) {
|
|
149
153
|
var noteEl = textarea.closest(".sticky-note");
|
|
150
154
|
var mdMode = false;
|
|
155
|
+
var disposed = false;
|
|
156
|
+
var ui = getNoteUiState(noteId, noteData);
|
|
157
|
+
var checklistMode = ui.checklistMode === true;
|
|
158
|
+
var checklistState = ui.checklistState || {};
|
|
159
|
+
var renderedDirty = false;
|
|
160
|
+
var sourceText = ui.text !== undefined ? ui.text : textarea.value;
|
|
161
|
+
textarea.value = sourceText;
|
|
162
|
+
|
|
163
|
+
function renderChecklist() {
|
|
164
|
+
var active = document.activeElement;
|
|
165
|
+
var focusKey = active && rendered.contains(active) && active.dataset ? active.dataset.checklistKey : undefined;
|
|
166
|
+
if (checklistMode) renderTaskControls(rendered, noteId);
|
|
167
|
+
else rendered.innerHTML = renderMiniMarkdown(sourceText, { checklistMode: checklistMode, checklistState: checklistState });
|
|
168
|
+
if (sourceText.trim()) enhanceClayLogLinks(rendered);
|
|
169
|
+
rendered.classList.toggle("is-empty", !checklistMode && !sourceText.trim());
|
|
170
|
+
rendered.contentEditable = checklistMode || getNoteUiState(noteId).pending.length ? "false" : "true";
|
|
171
|
+
if (focusKey !== undefined) {
|
|
172
|
+
var checks = rendered.querySelectorAll("[data-checklist-key]");
|
|
173
|
+
for (var i = 0; i < checks.length; i++) {
|
|
174
|
+
if (checks[i].dataset.checklistKey === focusKey) { checks[i].focus({ preventScroll: true }); break; }
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
151
178
|
|
|
152
179
|
function saveRenderedMarkdown() {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
180
|
+
if (checklistMode) return;
|
|
181
|
+
renderedDirty = true;
|
|
182
|
+
sourceText = extractMarkdown(rendered);
|
|
183
|
+
textarea.value = sourceText;
|
|
184
|
+
setNoteUiState(noteId, { text: sourceText, draft: true });
|
|
185
|
+
debouncedTextUpdate(noteId, sourceText);
|
|
186
|
+
syncTitle(noteEl, sourceText);
|
|
187
|
+
rendered.classList.toggle("is-empty", !checklistMode && !sourceText.trim());
|
|
158
188
|
}
|
|
159
189
|
|
|
160
190
|
function toggleChecklistItem(check) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
191
|
+
if (checklistMode && check.dataset.checklistIndex !== undefined) {
|
|
192
|
+
var index = parseInt(check.dataset.checklistIndex, 10);
|
|
193
|
+
var checked = !check.classList.contains("checked");
|
|
194
|
+
mutateChecklist(noteId, { checklistIndex: index, checklistKey: check.dataset.checklistKey || "", checklistSource: sourceText, checklistChecked: checked });
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
var normalChecked = !check.classList.contains("checked");
|
|
198
|
+
check.classList.toggle("checked", normalChecked);
|
|
199
|
+
check.textContent = normalChecked ? "✓" : "☐";
|
|
200
|
+
check.setAttribute("aria-checked", normalChecked ? "true" : "false");
|
|
165
201
|
saveRenderedMarkdown();
|
|
166
202
|
}
|
|
167
203
|
|
|
168
|
-
|
|
204
|
+
var unsubscribeUiState = subscribeNoteUiState(function (all) {
|
|
205
|
+
var next = all[noteId];
|
|
206
|
+
if (!next) return;
|
|
207
|
+
var changed = next.checklistMode !== checklistMode ||
|
|
208
|
+
(next.text !== undefined && next.text !== sourceText) ||
|
|
209
|
+
next.pending.length !== ui.pending.length ||
|
|
210
|
+
next.checklistInputs !== ui.checklistInputs && !next.checklistInputs ||
|
|
211
|
+
JSON.stringify(next.checklistState || {}) !== JSON.stringify(checklistState || {});
|
|
212
|
+
ui = next;
|
|
213
|
+
checklistMode = next.checklistMode === true;
|
|
214
|
+
checklistState = next.checklistState || {};
|
|
215
|
+
if (next.text !== undefined && next.text !== sourceText) {
|
|
216
|
+
sourceText = next.text;
|
|
217
|
+
textarea.value = sourceText;
|
|
218
|
+
}
|
|
219
|
+
mdBtn.hidden = checklistMode;
|
|
220
|
+
mdBtn.disabled = checklistMode;
|
|
221
|
+
if (checklistMode && mdMode) {
|
|
222
|
+
mdMode = false; textarea.style.display = 'none'; rendered.style.display = ''; mdBtn.classList.remove('active');
|
|
223
|
+
}
|
|
224
|
+
checklistBtn.classList.toggle("active", checklistMode);
|
|
225
|
+
checklistBtn.title = checklistMode ? "Show note" : "Show checklist";
|
|
226
|
+
checklistBtn.setAttribute("aria-label", checklistBtn.title);
|
|
227
|
+
checklistBtn.setAttribute("aria-pressed", checklistMode ? "true" : "false");
|
|
228
|
+
var status = noteEl.querySelector(".sticky-note-save-status");
|
|
229
|
+
if (status) status.textContent = next.error || (next.pending && next.pending.length ? "Saving…" : "");
|
|
230
|
+
if (changed && !mdMode) { renderChecklist(); syncTitle(noteEl, sourceText); }
|
|
231
|
+
});
|
|
232
|
+
noteEl._stickyNoteDispose = function () {
|
|
233
|
+
disposed = true;
|
|
234
|
+
closeFormatToolbar();
|
|
235
|
+
unsubscribeUiState();
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
checklistBtn.addEventListener("click", function (e) {
|
|
239
|
+
e.stopPropagation();
|
|
240
|
+
requestChecklistMode(noteId);
|
|
241
|
+
});
|
|
242
|
+
|
|
169
243
|
mdBtn.addEventListener("click", function (e) {
|
|
170
244
|
e.stopPropagation();
|
|
245
|
+
if (checklistMode) return;
|
|
171
246
|
mdMode = !mdMode;
|
|
172
247
|
if (mdMode) {
|
|
173
|
-
|
|
174
|
-
var md = extractMarkdown(rendered);
|
|
175
|
-
textarea.value = md;
|
|
248
|
+
textarea.value = sourceText;
|
|
176
249
|
textarea.style.display = "";
|
|
177
250
|
rendered.style.display = "none";
|
|
178
251
|
mdBtn.classList.add("active");
|
|
179
252
|
textarea.focus();
|
|
180
253
|
} else {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (md.trim()) {
|
|
186
|
-
rendered.innerHTML = renderMiniMarkdown(md);
|
|
187
|
-
enhanceClayLogLinks(rendered);
|
|
188
|
-
rendered.classList.remove("is-empty");
|
|
189
|
-
} else {
|
|
190
|
-
rendered.innerHTML = "";
|
|
191
|
-
rendered.classList.add("is-empty");
|
|
192
|
-
}
|
|
254
|
+
sourceText = textarea.value;
|
|
255
|
+
if (getNoteUiState(noteId).draft) debouncedTextUpdate(noteId, sourceText);
|
|
256
|
+
syncTitle(noteEl, sourceText);
|
|
257
|
+
renderChecklist();
|
|
193
258
|
textarea.style.display = "none";
|
|
194
259
|
rendered.style.display = "";
|
|
195
260
|
mdBtn.classList.remove("active");
|
|
@@ -197,11 +262,7 @@ export function setupTextEdit(textarea, rendered, noteId, mdBtn) {
|
|
|
197
262
|
}
|
|
198
263
|
});
|
|
199
264
|
|
|
200
|
-
|
|
201
|
-
rendered.addEventListener("input", function () {
|
|
202
|
-
saveRenderedMarkdown();
|
|
203
|
-
});
|
|
204
|
-
|
|
265
|
+
rendered.addEventListener("input", saveRenderedMarkdown);
|
|
205
266
|
rendered.addEventListener("click", function (e) {
|
|
206
267
|
var check = e.target.closest && e.target.closest(".sn-check");
|
|
207
268
|
if (!check || !rendered.contains(check)) return;
|
|
@@ -210,27 +271,23 @@ export function setupTextEdit(textarea, rendered, noteId, mdBtn) {
|
|
|
210
271
|
toggleChecklistItem(check);
|
|
211
272
|
});
|
|
212
273
|
|
|
213
|
-
// On blur, re-render to normalize HTML structure
|
|
214
274
|
rendered.addEventListener("blur", function (e) {
|
|
215
|
-
|
|
275
|
+
if (checklistMode || !renderedDirty) return;
|
|
276
|
+
renderedDirty = false;
|
|
216
277
|
if (e.relatedTarget && e.relatedTarget.closest && e.relatedTarget.closest(".sn-format-toolbar")) return;
|
|
217
278
|
closeFormatToolbar();
|
|
218
279
|
var md = extractMarkdown(rendered);
|
|
280
|
+
sourceText = md;
|
|
219
281
|
textarea.value = md;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
enhanceClayLogLinks(rendered);
|
|
223
|
-
rendered.classList.remove("is-empty");
|
|
224
|
-
} else {
|
|
225
|
-
rendered.innerHTML = "";
|
|
226
|
-
rendered.classList.add("is-empty");
|
|
227
|
-
}
|
|
282
|
+
setNoteUiState(noteId, { text: sourceText, draft: true });
|
|
283
|
+
renderChecklist();
|
|
228
284
|
});
|
|
229
285
|
|
|
230
286
|
// Show format toolbar when selecting text
|
|
231
287
|
rendered.addEventListener("mouseup", function (e) {
|
|
232
288
|
if (e.target.tagName === "A") return;
|
|
233
289
|
setTimeout(function () {
|
|
290
|
+
if (disposed) return;
|
|
234
291
|
var sel = window.getSelection();
|
|
235
292
|
if (sel && !sel.isCollapsed && sel.toString().trim()) {
|
|
236
293
|
showFormatToolbar(rendered);
|
|
@@ -260,6 +317,7 @@ export function setupTextEdit(textarea, rendered, noteId, mdBtn) {
|
|
|
260
317
|
toggleChecklistItem(e.target);
|
|
261
318
|
return;
|
|
262
319
|
}
|
|
320
|
+
if (checklistMode) return;
|
|
263
321
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
264
322
|
e.preventDefault();
|
|
265
323
|
document.execCommand("insertLineBreak");
|
|
@@ -268,6 +326,7 @@ export function setupTextEdit(textarea, rendered, noteId, mdBtn) {
|
|
|
268
326
|
|
|
269
327
|
// Paste as plain text to avoid importing HTML formatting
|
|
270
328
|
rendered.addEventListener("paste", function (e) {
|
|
329
|
+
if (checklistMode) return;
|
|
271
330
|
e.preventDefault();
|
|
272
331
|
var text = (e.clipboardData || window.clipboardData).getData("text/plain");
|
|
273
332
|
document.execCommand("insertText", false, text);
|
|
@@ -281,10 +340,15 @@ export function setupTextEdit(textarea, rendered, noteId, mdBtn) {
|
|
|
281
340
|
// Sync textarea edits when in MD mode
|
|
282
341
|
textarea.addEventListener("input", function () {
|
|
283
342
|
if (!mdMode) return;
|
|
284
|
-
|
|
285
|
-
|
|
343
|
+
sourceText = textarea.value;
|
|
344
|
+
setNoteUiState(noteId, { text: sourceText, draft: true });
|
|
345
|
+
debouncedTextUpdate(noteId, sourceText);
|
|
346
|
+
syncTitle(noteEl, sourceText);
|
|
286
347
|
});
|
|
287
348
|
|
|
349
|
+
mdBtn.hidden = checklistMode; mdBtn.disabled = checklistMode;
|
|
350
|
+
renderChecklist();
|
|
351
|
+
|
|
288
352
|
textarea.addEventListener("mousedown", function (e) {
|
|
289
353
|
e.stopPropagation();
|
|
290
354
|
});
|
|
@@ -55,8 +55,51 @@ export function clampSize(x, y, w, h) {
|
|
|
55
55
|
|
|
56
56
|
export function send(obj) {
|
|
57
57
|
var ws = getWs();
|
|
58
|
-
if (!ws || !store.get('connected')) return;
|
|
59
|
-
ws.send(JSON.stringify(obj));
|
|
58
|
+
if (!ws || !store.get('connected')) return false;
|
|
59
|
+
try { ws.send(JSON.stringify(obj)); return true; } catch (error) { return false; }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getNoteUiState(id, fallback) {
|
|
63
|
+
var all = store.get("stickyNoteUiState") || {};
|
|
64
|
+
if (!all[id]) {
|
|
65
|
+
var initial = {
|
|
66
|
+
canonical: Object.assign({}, fallback),
|
|
67
|
+
canonicalRevision: 0,
|
|
68
|
+
draft: false,
|
|
69
|
+
text: fallback && fallback.text ? fallback.text : "",
|
|
70
|
+
checklistMode: fallback && fallback.checklistMode === true,
|
|
71
|
+
checklistState: fallback && fallback.checklistState ? fallback.checklistState : {},
|
|
72
|
+
pending: [],
|
|
73
|
+
};
|
|
74
|
+
var next = Object.assign({}, all);
|
|
75
|
+
next[id] = initial;
|
|
76
|
+
store.set({ stickyNoteUiState: next });
|
|
77
|
+
return initial;
|
|
78
|
+
}
|
|
79
|
+
return all[id];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function setNoteUiState(id, changes) {
|
|
83
|
+
var all = store.get("stickyNoteUiState") || {};
|
|
84
|
+
var current = all[id] || {};
|
|
85
|
+
var next = Object.assign({}, all);
|
|
86
|
+
next[id] = Object.assign({}, current, changes || {});
|
|
87
|
+
store.set({ stickyNoteUiState: next });
|
|
88
|
+
return next[id];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function deleteNoteUiState(id) {
|
|
92
|
+
var all = store.get("stickyNoteUiState") || {};
|
|
93
|
+
if (!all[id]) return;
|
|
94
|
+
var next = Object.assign({}, all);
|
|
95
|
+
delete next[id];
|
|
96
|
+
store.set({ stickyNoteUiState: next });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function subscribeNoteUiState(listener) {
|
|
100
|
+
return store.subscribe(function (next, previous) {
|
|
101
|
+
if (next.stickyNoteUiState !== previous.stickyNoteUiState) listener(next.stickyNoteUiState || {});
|
|
102
|
+
});
|
|
60
103
|
}
|
|
61
104
|
|
|
62
105
|
export function debouncedUpdate(id, changes, delay) {
|
|
@@ -82,6 +125,11 @@ export function syncTitle(noteEl, text) {
|
|
|
82
125
|
|
|
83
126
|
|
|
84
127
|
// Drop any pending writes for a note this client no longer has.
|
|
128
|
+
export function clearNoteTextTimer(id) {
|
|
129
|
+
clearTimeout(textTimers[id]);
|
|
130
|
+
delete textTimers[id];
|
|
131
|
+
}
|
|
132
|
+
|
|
85
133
|
export function clearNoteTimers(id) {
|
|
86
134
|
clearTimeout(updateTimers[id]);
|
|
87
135
|
clearTimeout(textTimers[id]);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Reconcile canonical broadcasts with optimistic checklist actions and text drafts.
|
|
2
|
+
import { store } from './store.js';
|
|
3
|
+
import { getNoteUiState, setNoteUiState, send } from './sticky-notes-shared.js';
|
|
4
|
+
|
|
5
|
+
function project(ui, pending, error) {
|
|
6
|
+
var canonical = ui.canonical || {};
|
|
7
|
+
var text = ui.draft ? ui.text : canonical.text || "";
|
|
8
|
+
var mode = canonical.checklistMode === true;
|
|
9
|
+
var state = Object.assign({}, canonical.checklistState || {});
|
|
10
|
+
pending.forEach(function (request) {
|
|
11
|
+
var changes = request.changes;
|
|
12
|
+
if (changes.text !== undefined) text = changes.text;
|
|
13
|
+
if (changes.checklistMode !== undefined) mode = changes.checklistMode;
|
|
14
|
+
if (changes.checklistKey) state[decodeURIComponent(changes.checklistKey)] = changes.checklistChecked;
|
|
15
|
+
});
|
|
16
|
+
return setNoteUiState(canonical.id, {
|
|
17
|
+
text: text,
|
|
18
|
+
checklistMode: mode, checklistState: state, pending: pending, error: error || '',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function reconcileNote(data) {
|
|
23
|
+
var ui = getNoteUiState(data.id, data);
|
|
24
|
+
var draft = ui.draft && ui.text !== (data.text || '');
|
|
25
|
+
ui = setNoteUiState(data.id, { canonical: data, canonicalRevision: (ui.canonicalRevision || 0) + 1, draft: draft });
|
|
26
|
+
project(ui, ui.pending || [], ui.error);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function mutateChecklist(id, changes) {
|
|
30
|
+
var ui = getNoteUiState(id);
|
|
31
|
+
var requestId = 'note-update-' + Date.now() + '-' + Math.random().toString(36).slice(2);
|
|
32
|
+
var pending = (ui.pending || []).concat([{ requestId: requestId, changes: changes, revision: ui.canonicalRevision, draftText: ui.text }]);
|
|
33
|
+
project(ui, pending, '');
|
|
34
|
+
if (!send(Object.assign({}, changes, { type: changes.humanClose ? 'note_close' : 'note_update', id: id, requestId: requestId }))) {
|
|
35
|
+
project(getNoteUiState(id), pending.slice(0, -1), 'Connection unavailable');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function reconcileNoteResult(msg) {
|
|
40
|
+
var ui = getNoteUiState(msg.noteId);
|
|
41
|
+
var request = (ui.pending || []).find(function (item) { return item.requestId === msg.requestId; });
|
|
42
|
+
if (!request) return;
|
|
43
|
+
// The server broadcasts before acknowledgement. Use the returned note when
|
|
44
|
+
// that broadcast was absent, but never replace a newer remote canonical note.
|
|
45
|
+
if (msg.ok && msg.note && ui.canonicalRevision === request.revision) {
|
|
46
|
+
reconcileNote(msg.note);
|
|
47
|
+
ui = getNoteUiState(msg.noteId);
|
|
48
|
+
}
|
|
49
|
+
if (msg.ok && request.changes.checklistConvert && ui.text === request.draftText) {
|
|
50
|
+
ui = setNoteUiState(msg.noteId, { draft: false, text: ui.canonical.text || '' });
|
|
51
|
+
}
|
|
52
|
+
if (msg.ok && (request.changes.checklistEdit || request.changes.checklistConvert || request.changes.humanClose)) {
|
|
53
|
+
ui = setNoteUiState(msg.noteId, { checklistInputs: null });
|
|
54
|
+
}
|
|
55
|
+
var remaining = ui.pending.filter(function (item) { return item.requestId !== msg.requestId; });
|
|
56
|
+
project(ui, remaining, msg.ok ? '' : msg.error || 'Could not save checklist change');
|
|
57
|
+
return ui.canonical;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
store.subscribe(function (next, previous) {
|
|
61
|
+
if (next.connected || next.connected === previous.connected) return;
|
|
62
|
+
var all = next.stickyNoteUiState || {};
|
|
63
|
+
Object.keys(all).forEach(function (id) {
|
|
64
|
+
if (all[id].pending && all[id].pending.length) project(all[id], [], 'Connection unavailable');
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
// The sticky-note canvas: the board of floating cards over the conversation.
|
|
2
|
-
//
|
|
3
2
|
// This module owns the notes map, visibility, the badges, and the WebSocket
|
|
4
3
|
// handlers. Card markup and interactions live in sticky-notes-card.js, text
|
|
5
|
-
// editing in sticky-notes-editor.js, and
|
|
4
|
+
// editing in sticky-notes-editor.js, and leaf helpers in
|
|
6
5
|
// sticky-notes-shared.js. The browse/index pane is sticky-notes-browser.js.
|
|
7
6
|
|
|
8
7
|
import { refreshIcons, iconHtml } from './icons.js';
|
|
9
|
-
import {
|
|
10
|
-
import { enhanceClayLogLinks } from './clay-log-links.js';
|
|
11
|
-
import { isClosedNote, send, clampPos, clearNoteTimers, syncTitle } from './sticky-notes-shared.js';
|
|
8
|
+
import { isClosedNote, send, clampPos, clearNoteTimers, deleteNoteUiState } from './sticky-notes-shared.js';
|
|
12
9
|
import { renderNote, closeColorPicker } from './sticky-notes-card.js';
|
|
13
10
|
import { closeFormatToolbar, isFormatToolbarOpen } from './sticky-notes-editor.js';
|
|
14
11
|
import { store } from './store.js';
|
|
12
|
+
import { reconcileNote, reconcileNoteResult } from './sticky-notes-state.js';
|
|
15
13
|
|
|
16
14
|
var notes = new Map(); // id -> { data, el }
|
|
17
15
|
var notesVisible = false;
|
|
18
16
|
var notesResizeObserver = null;
|
|
19
17
|
|
|
20
|
-
// The canvas shows open notes only. Closed notes
|
|
21
|
-
// the browser's Closed tab until they are reopened.
|
|
18
|
+
// The canvas shows open notes only. Closed notes live in the browser's Closed tab.
|
|
22
19
|
function openCount() {
|
|
23
20
|
var count = 0;
|
|
24
21
|
notes.forEach(function (entry) {
|
|
@@ -259,9 +256,7 @@ export function handleNotesList(msg) {
|
|
|
259
256
|
var container = document.getElementById("sticky-notes-container");
|
|
260
257
|
if (!container) return;
|
|
261
258
|
|
|
262
|
-
//
|
|
263
|
-
// list unchanged; tearing every note down and recreating it made all the
|
|
264
|
-
// floating cards vanish and reappear, and destroyed any open editor.
|
|
259
|
+
// Reconcile keyed cards in place so reconnects retain the active editor.
|
|
265
260
|
var list = msg.notes || [];
|
|
266
261
|
var seen = {};
|
|
267
262
|
var created = false;
|
|
@@ -283,28 +278,27 @@ export function handleNotesList(msg) {
|
|
|
283
278
|
created = true;
|
|
284
279
|
}
|
|
285
280
|
|
|
286
|
-
// Remove
|
|
281
|
+
// Remove subscriptions and delayed writes along with stale cards.
|
|
287
282
|
var staleIds = [];
|
|
288
283
|
notes.forEach(function (value, id) {
|
|
289
284
|
if (!seen[id]) staleIds.push(id);
|
|
290
285
|
});
|
|
291
286
|
for (i = 0; i < staleIds.length; i++) {
|
|
292
287
|
var stale = notes.get(staleIds[i]);
|
|
288
|
+
if (stale && stale.el && stale.el._stickyNoteDispose) stale.el._stickyNoteDispose();
|
|
293
289
|
if (stale && stale.el && stale.el.parentNode) stale.el.parentNode.removeChild(stale.el);
|
|
290
|
+
clearNoteTimers(staleIds[i]);
|
|
291
|
+
deleteNoteUiState(staleIds[i]);
|
|
294
292
|
notes.delete(staleIds[i]);
|
|
295
293
|
}
|
|
296
294
|
|
|
297
|
-
//
|
|
298
|
-
// pass introduces no new Lucide markup and must not trigger a document scan.
|
|
295
|
+
// An all-patch list adds no icon markup and needs no document-wide scan.
|
|
299
296
|
if (created) refreshIcons();
|
|
300
297
|
|
|
301
298
|
updateBadge();
|
|
302
299
|
updateSidebarBadge();
|
|
303
300
|
refreshBrowser();
|
|
304
301
|
|
|
305
|
-
// Auto-show only when something is actually asking for attention. A board of
|
|
306
|
-
// nothing but closed notes must not pop the canvas open. Temporary hiding is
|
|
307
|
-
// explicit view state and must survive reconnects and list updates.
|
|
308
302
|
if (openCount() > 0 && !notesVisible) {
|
|
309
303
|
notesVisible = true;
|
|
310
304
|
applyCanvasVisibility();
|
|
@@ -337,18 +331,13 @@ export function handleNoteCreated(msg) {
|
|
|
337
331
|
syncFlightControls();
|
|
338
332
|
}
|
|
339
333
|
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
// applied. The rendered markdown is only replaced when the text actually
|
|
344
|
-
// changed and the note is not being edited, so a geometry-only or z-only
|
|
345
|
-
// update never destroys the user's caret, selection, or in-progress draft.
|
|
346
|
-
// Returns true when icon markup was replaced, so the caller can decide whether
|
|
347
|
-
// a Lucide pass is needed at all.
|
|
334
|
+
// Canonical content reconciles through the store; geometry patches independently
|
|
335
|
+
// so movement and stacking updates preserve the editor and its draft.
|
|
336
|
+
// Return whether the minimize control introduced fresh icon markup.
|
|
348
337
|
function patchNote(entry, next) {
|
|
349
338
|
if (!entry || !next) return false;
|
|
350
|
-
var previous = entry.data || {};
|
|
351
339
|
entry.data = next;
|
|
340
|
+
reconcileNote(next);
|
|
352
341
|
var el = entry.el;
|
|
353
342
|
|
|
354
343
|
el.style.left = next.x + "px";
|
|
@@ -358,26 +347,6 @@ function patchNote(entry, next) {
|
|
|
358
347
|
el.style.zIndex = 100 + (next.zIndex || 0);
|
|
359
348
|
el.dataset.color = next.color || "purple";
|
|
360
349
|
|
|
361
|
-
var textarea = el.querySelector(".sticky-note-text");
|
|
362
|
-
var rendered = el.querySelector(".sticky-note-rendered");
|
|
363
|
-
var nextText = next.text || "";
|
|
364
|
-
var editing = rendered === document.activeElement || textarea === document.activeElement;
|
|
365
|
-
// A draft the user typed but has not committed must survive a redraw.
|
|
366
|
-
var hasDraft = !!(textarea && textarea.value !== (previous.text || ""));
|
|
367
|
-
var textChanged = nextText !== (previous.text || "");
|
|
368
|
-
if (rendered && !editing && !hasDraft && textChanged) {
|
|
369
|
-
if (textarea) textarea.value = nextText;
|
|
370
|
-
if (nextText.trim()) {
|
|
371
|
-
rendered.innerHTML = renderMiniMarkdown(nextText);
|
|
372
|
-
enhanceClayLogLinks(rendered);
|
|
373
|
-
rendered.classList.remove("is-empty");
|
|
374
|
-
} else {
|
|
375
|
-
rendered.innerHTML = "";
|
|
376
|
-
rendered.classList.add("is-empty");
|
|
377
|
-
}
|
|
378
|
-
syncTitle(el, nextText);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
350
|
if (typeof next.opacity === "number") {
|
|
382
351
|
el.style.setProperty("--note-opacity", next.opacity);
|
|
383
352
|
var slider = el.querySelector(".sticky-note-opacity-slider");
|
|
@@ -388,8 +357,6 @@ function patchNote(entry, next) {
|
|
|
388
357
|
else el.classList.remove("hidden");
|
|
389
358
|
syncFlightState(el, true);
|
|
390
359
|
|
|
391
|
-
// The minimize button swaps its icon, which is the only path here that can
|
|
392
|
-
// introduce fresh Lucide markup.
|
|
393
360
|
var iconsReplaced = false;
|
|
394
361
|
var wasMinimized = el.classList.contains("minimized");
|
|
395
362
|
var minBtn = el.querySelector(".sticky-note-min-btn");
|
|
@@ -419,13 +386,18 @@ export function handleNoteUpdated(msg) {
|
|
|
419
386
|
if (patchNote(entry, msg.note)) refreshIcons();
|
|
420
387
|
reclampAllNotes();
|
|
421
388
|
|
|
422
|
-
// A close or reopen arrives as an ordinary update, so the canvas count and
|
|
423
|
-
// the browser both follow from the same message.
|
|
424
389
|
updateBadge();
|
|
425
390
|
updateSidebarBadge();
|
|
426
391
|
refreshBrowser();
|
|
427
392
|
}
|
|
428
393
|
|
|
394
|
+
export function handleNoteUpdateResult(msg) {
|
|
395
|
+
var entry = notes.get(msg.noteId);
|
|
396
|
+
if (!entry || !msg.requestId) return;
|
|
397
|
+
var canonical = reconcileNoteResult(msg);
|
|
398
|
+
if (canonical) { entry.data = canonical; refreshBrowser(); }
|
|
399
|
+
}
|
|
400
|
+
|
|
429
401
|
export function handleNoteWritten(msg) {
|
|
430
402
|
var entry = notes.get(msg.id);
|
|
431
403
|
if (!entry) return;
|
|
@@ -437,11 +409,11 @@ export function handleNoteWritten(msg) {
|
|
|
437
409
|
}, 2100);
|
|
438
410
|
}
|
|
439
411
|
|
|
440
|
-
// Defensive only. The server no longer deletes notes and never sends this, but
|
|
441
|
-
// an older daemon on the other end of the socket still must not corrupt state.
|
|
442
412
|
export function handleNoteDeleted(msg) {
|
|
443
413
|
var entry = notes.get(msg.id);
|
|
414
|
+
if (entry && entry.el._stickyNoteDispose) entry.el._stickyNoteDispose();
|
|
444
415
|
if (entry) entry.el.remove();
|
|
416
|
+
deleteNoteUiState(msg.id);
|
|
445
417
|
clearNoteTimers(msg.id);
|
|
446
418
|
notes.delete(msg.id);
|
|
447
419
|
updateBadge();
|
|
@@ -467,3 +439,14 @@ function updateSidebarBadge() {
|
|
|
467
439
|
export function isNotesVisible() {
|
|
468
440
|
return notesVisible;
|
|
469
441
|
}
|
|
442
|
+
|
|
443
|
+
// Project navigation must cancel writes and detach subscriptions before reuse.
|
|
444
|
+
export function resetStickyNotes() {
|
|
445
|
+
handleNotesList({ notes: [] });
|
|
446
|
+
closeFormatToolbar();
|
|
447
|
+
closeColorPicker();
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
store.subscribe(function (next, previous) {
|
|
451
|
+
if (next.currentSlug !== previous.currentSlug) resetStickyNotes();
|
|
452
|
+
});
|
|
@@ -12,7 +12,8 @@ export function speechContext() {
|
|
|
12
12
|
var s = store.snap();
|
|
13
13
|
return JSON.stringify([s.currentSlug, s.activeSessionId, s.dmMode, s.dmKey,
|
|
14
14
|
s.dmTargetUser && s.dmTargetUser.id, s.homePrimarySurface, s.homeSubSurface,
|
|
15
|
-
s.homeChatMateId, s.homeChatSessionId
|
|
15
|
+
s.homeChatMateId, s.homeChatSessionId, s.sessionOriginId, s.myUserId, s.sessionActionEpoch || 0,
|
|
16
|
+
s.paneCommittedBinding && s.paneCommittedBinding.generation]);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export function setSpeechStatus(id, message, isError) {
|
|
@@ -76,6 +77,7 @@ export function claimSpeech(id, input, recognition) {
|
|
|
76
77
|
var active = { id: id, input: input, recognition: recognition, context: speechContext(),
|
|
77
78
|
before: input.value, lastValue: input.value, writing: false, started: false, timeout: null };
|
|
78
79
|
active.traceId = Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 7);
|
|
80
|
+
active.paneBinding = store.get('paneCommittedBinding') || null;
|
|
79
81
|
active.traceStarted = Date.now();
|
|
80
82
|
store.set({ speechActive: active, speechRetry: null });
|
|
81
83
|
return active;
|
|
@@ -113,6 +115,7 @@ export function startSTT(id, input) {
|
|
|
113
115
|
var active = { id: id, input: input, recognition: recognition, context: speechContext(),
|
|
114
116
|
before: input.value, lastValue: input.value, writing: false, started: false, timeout: null };
|
|
115
117
|
recognition.lang = store.get('speechLang') || 'en-US';
|
|
118
|
+
active.paneBinding = store.get('paneCommittedBinding') || null;
|
|
116
119
|
recognition.continuous = true;
|
|
117
120
|
recognition.interimResults = true;
|
|
118
121
|
recognition.onstart = function () {
|
|
@@ -26,7 +26,7 @@ async function upload(active, blob) {
|
|
|
26
26
|
model: active.model, language: active.language, blob: blob };
|
|
27
27
|
failSTT(error.name === 'AbortError' ? 'Transcription timed out. Please try again.' : error.message);
|
|
28
28
|
store.set({ speechRetry: retry });
|
|
29
|
-
setTimeout(function () { if (store.get('speechRetry') === retry) store.set({ speechRetry: null }); }, 300000);
|
|
29
|
+
setTimeout(function () { if (store.get('speechRetry') === retry && !store.get('deferredSessionSwitch')) store.set({ speechRetry: null }); }, 300000);
|
|
30
30
|
return false;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -25,6 +25,7 @@ function bindComposer(id, inputId, wrapperId) {
|
|
|
25
25
|
if (!button || !input || !wrapper || button.dataset.speechBound) return;
|
|
26
26
|
var composer = document.getElementById(id === 'stt-btn' ? 'input-row' : 'home-mate-chat-composer') || wrapper;
|
|
27
27
|
var toolbar = document.getElementById(id === 'stt-btn' ? 'input-bottom' : 'home-mate-chat-composer') || composer;
|
|
28
|
+
button.addEventListener('click', refreshSpeechBrowser);
|
|
28
29
|
button.dataset.speechBound = 'true'; button.classList.add('stt-button');
|
|
29
30
|
var group = document.createElement('span'); group.className = 'stt-controls';
|
|
30
31
|
button.before(group); group.appendChild(button);
|
|
@@ -32,7 +33,7 @@ function bindComposer(id, inputId, wrapperId) {
|
|
|
32
33
|
picker.className = 'stt-picker-toggle'; picker.innerHTML = iconHtml('chevron-down');
|
|
33
34
|
picker.setAttribute('aria-label', 'Choose voice model'); picker.setAttribute('aria-haspopup', 'dialog'); picker.setAttribute('aria-expanded', 'false');
|
|
34
35
|
picker.title = 'Choose voice model'; group.appendChild(picker);
|
|
35
|
-
picker.addEventListener('click', function () { openSpeechPicker(picker); });
|
|
36
|
+
picker.addEventListener('click', function () { refreshSpeechBrowser(); openSpeechPicker(picker); });
|
|
36
37
|
var row = document.createElement('div'); row.className = 'stt-progress'; row.hidden = true;
|
|
37
38
|
var status = document.createElement('span'); status.id = id + '-status'; status.className = 'stt-status'; status.setAttribute('role', 'status');
|
|
38
39
|
var timer = document.createElement('span'); timer.className = 'stt-timer'; timer.setAttribute('aria-hidden', 'true');
|
|
@@ -70,7 +71,7 @@ function bindComposer(id, inputId, wrapperId) {
|
|
|
70
71
|
function render() {
|
|
71
72
|
var active = store.get('speechActive'); var own = !!active && active.id === id;
|
|
72
73
|
var model = voiceModel(); var provider = voiceProvider(model.provider);
|
|
73
|
-
var browser = model.provider === 'browser' ?
|
|
74
|
+
var browser = model.provider === 'browser' ? store.get('speechBrowserIdentity') : null;
|
|
74
75
|
var pending = own && active.model && active.phase !== 'recording';
|
|
75
76
|
var autoSend = own && !!active.autoSend;
|
|
76
77
|
composer.classList.toggle('stt-recording', own);
|
|
@@ -117,7 +118,11 @@ function bindComposer(id, inputId, wrapperId) {
|
|
|
117
118
|
observer.observe(input, { attributes: true, attributeFilter: ['disabled', 'readonly'] });
|
|
118
119
|
render();
|
|
119
120
|
}
|
|
121
|
+
// Browser identity may read layout; refresh on entry and interaction, not transcript updates.
|
|
122
|
+
function refreshSpeechBrowser() { store.set({ speechBrowserIdentity: browserSpeechInfo() }); }
|
|
120
123
|
export function initSTT() {
|
|
124
|
+
refreshSpeechBrowser();
|
|
125
|
+
window.addEventListener('focus', refreshSpeechBrowser);
|
|
121
126
|
initSpeechLifecycle(); initSpeechPicker();
|
|
122
127
|
bindComposer('stt-btn', 'input', 'input-wrapper');
|
|
123
128
|
bindComposer('home-stt-btn', 'home-mate-chat-input', 'home-mate-chat-composer-frame');
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { store } from './store.js';
|
|
1
2
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
2
3
|
import { closeSidebar } from './sidebar.js';
|
|
3
4
|
import { claimRightWorkbench, registerRightWorkbench, releaseRightWorkbench } from './right-workbench.js';
|
|
@@ -538,6 +539,8 @@ function renderTabBar() {
|
|
|
538
539
|
(function (t) {
|
|
539
540
|
var el = document.createElement("div");
|
|
540
541
|
el.className = "terminal-tab";
|
|
542
|
+
el.dataset.controlTerminalId = String(t.id);
|
|
543
|
+
el.dataset.controlRuntime = store.get("controlRuntimeId") || "";
|
|
541
544
|
if (t.id === activeTabId) el.classList.add("active");
|
|
542
545
|
if (t.exited) el.classList.add("exited");
|
|
543
546
|
|
|
@@ -696,6 +699,7 @@ function updateTerminalBadge() {
|
|
|
696
699
|
// --- Handle server messages ---
|
|
697
700
|
|
|
698
701
|
export function handleTermList(msg) {
|
|
702
|
+
store.set({ clayControlTerminalViews: (msg.terminals || []).map(function (item) { return { id: item.id, identity: item.controlIdentity, revision: item.controlRevision, runtimeId: store.get('controlRuntimeId') }; }) });
|
|
699
703
|
// TUI session terminals are owned by session-tui-view.js and must not
|
|
700
704
|
// appear in the bottom terminal panel. Filter them out before any tab
|
|
701
705
|
// bookkeeping so the panel never tries to render or auto-attach them.
|
|
@@ -762,7 +766,11 @@ export function handleTermCreated(msg) {
|
|
|
762
766
|
}
|
|
763
767
|
}
|
|
764
768
|
|
|
769
|
+
export function handleTerminalProjection(msg) {
|
|
770
|
+
if (msg.controlIdentity && msg.controlRevision) store.set({ clayControlTerminalViews: (store.get('clayControlTerminalViews') || []).map(function (item) { return item.id === msg.id && item.identity === msg.controlIdentity ? Object.assign({}, item, { revision: msg.controlRevision }) : item; }) });
|
|
771
|
+
}
|
|
765
772
|
export function handleTermOutput(msg) {
|
|
773
|
+
handleTerminalProjection(msg);
|
|
766
774
|
if (!msg.id) return;
|
|
767
775
|
var tab = tabs.get(msg.id);
|
|
768
776
|
if (tab && tab.xterm && msg.data) {
|
|
@@ -771,6 +779,7 @@ export function handleTermOutput(msg) {
|
|
|
771
779
|
}
|
|
772
780
|
|
|
773
781
|
export function handleTermResized(msg) {
|
|
782
|
+
handleTerminalProjection(msg);
|
|
774
783
|
if (!msg.id) return;
|
|
775
784
|
var tab = tabs.get(msg.id);
|
|
776
785
|
if (tab && tab.xterm && msg.cols > 0 && msg.rows > 0) {
|