clay-server 5.2.0-beta.1 → 5.2.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/lib/account-auth-socket.js +1 -0
- package/lib/builtin-mates.js +19 -16
- package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
- package/lib/canonical-clay-record-authority.js +15 -0
- package/lib/canonical-clay-scheduling-authority.js +19 -0
- package/lib/claude-hook-installer.js +1 -239
- package/lib/claude-jsonl-watcher.js +1 -204
- package/lib/clay-control-presentation-binding.js +96 -0
- package/lib/clay-control-presentation.js +128 -0
- package/lib/clay-control-target-projection.js +26 -0
- package/lib/clay-mate-chat-receipts.js +26 -0
- package/lib/clay-mate-chat.js +88 -0
- package/lib/clay-mate-knowledge-input.js +26 -0
- package/lib/clay-mate-knowledge.js +95 -0
- package/lib/clay-mate-lifecycle.js +95 -0
- package/lib/clay-product-control-input.js +33 -0
- package/lib/clay-product-control-tools.js +52 -0
- package/lib/clay-product-control.js +250 -0
- package/lib/clay-project-lifecycle.js +154 -0
- package/lib/clay-project-record-input.js +44 -0
- package/lib/clay-project-records.js +84 -0
- package/lib/clay-scheduling-input.js +21 -0
- package/lib/clay-scheduling-receipts.js +26 -0
- package/lib/clay-scheduling.js +119 -0
- package/lib/clay-screen-controls.js +104 -0
- package/lib/clay-skill-install.js +1 -33
- package/lib/clay-vendor-usage.js +44 -0
- package/lib/clay-workspace-controls.js +84 -0
- package/lib/clay-workspace-input.js +17 -0
- package/lib/clay-workspace-receipts.js +26 -0
- package/lib/cli-sessions.js +1 -300
- package/lib/codex-defaults.js +1 -28
- package/lib/context-usage.js +3 -2
- package/lib/contextual-screen-snapshot.js +38 -0
- package/lib/daemon-project-access.js +11 -0
- package/lib/daemon-project-lifecycle-callbacks.js +15 -0
- package/lib/daemon-project-lifecycle.js +262 -0
- package/lib/daemon-projects.js +1 -1
- package/lib/daemon.js +78 -276
- package/lib/default-ai-runtime.js +4 -8
- package/lib/dm-digest-cursor.js +120 -0
- package/lib/email-mcp-server.js +1 -1
- package/lib/github-star-count.js +147 -0
- package/lib/issues-service.js +29 -15
- package/lib/kiro-defaults.js +1 -22
- package/lib/knowledge-db-import-validation.js +46 -0
- package/lib/knowledge-db-import.js +99 -0
- package/lib/knowledge-db-service.js +24 -33
- package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
- package/lib/knowledge-db-storage-nedb.js +66 -0
- package/lib/knowledge-db-storage.js +72 -0
- package/lib/knowledge-db-validation.js +0 -0
- package/lib/knowledge-document-index.js +2 -1
- package/lib/knowledge-file-store.js +7 -1
- package/lib/knowledge-product-operations.js +46 -0
- package/lib/mate-avatar-catalog.js +12 -0
- package/lib/mate-avatar-migration.js +41 -0
- package/lib/mate-context-service.js +138 -0
- package/lib/mate-context-tools.js +21 -0
- package/lib/mate-creation-mcp-server.js +2 -0
- package/lib/mate-knowledge-canonical-access.js +10 -0
- package/lib/mate-knowledge-mate-bound.js +53 -0
- package/lib/mate-knowledge-mcp-server.js +55 -8
- package/lib/mate-knowledge-service.js +16 -34
- package/lib/mate-knowledge-text-tools.js +106 -0
- package/lib/mate-lifecycle-service.js +94 -0
- package/lib/mate-message-delivery.js +43 -0
- package/lib/mate-ready-creation.js +9 -1
- package/lib/mate-schedule-input.js +29 -0
- package/lib/mate-schedule-lifecycle.js +151 -0
- package/lib/mate-scheduling.js +103 -0
- package/lib/mates.js +18 -6
- package/lib/mcp-agent-tools.js +117 -0
- package/lib/mcp-connection-store.js +119 -15
- package/lib/mcp-import-credentials.js +31 -0
- package/lib/mcp-local-transport.js +13 -0
- package/lib/mcp-oauth.js +8 -6
- package/lib/mcp-proxy.js +2 -32
- package/lib/mcp-query-bridge.js +30 -0
- package/lib/mcp-remote-connections.js +74 -20
- package/lib/mcp-source-adapters.js +1 -0
- package/lib/mcp-source-context.js +1 -0
- package/lib/mcp-source-discovery.js +1 -0
- package/lib/mcp-source-plugins.js +1 -0
- package/lib/mcp-source-restrictions.js +1 -0
- package/lib/mcp-tool-policy.js +9 -0
- package/lib/notes-checklist.js +92 -0
- package/lib/notes.js +51 -4
- package/lib/os-user-diagnostics.js +2 -4
- package/lib/os-users.js +24 -70
- package/lib/pane-pending-interactions.js +20 -0
- package/lib/pane-session-activation.js +114 -0
- package/lib/pane-session-transport.js +26 -0
- package/lib/project-admin-overview.js +51 -0
- package/lib/project-ask-user.js +8 -4
- package/lib/project-connection.js +14 -10
- package/lib/project-control-git-view.js +12 -0
- package/lib/project-debate.js +1 -0
- package/lib/project-delegated-follow-up.js +2 -1
- package/lib/project-directory-claim.js +65 -0
- package/lib/project-file-operations.js +61 -0
- package/lib/project-filesystem.js +15 -85
- package/lib/project-full-access.js +23 -2
- package/lib/project-http.js +7 -4
- package/lib/project-knowledge.js +32 -18
- package/lib/project-lifecycle-operations.js +98 -0
- package/lib/project-lifecycle-process-witness.js +32 -0
- package/lib/project-lifecycle-runtime.js +50 -0
- package/lib/project-linux-access.js +22 -0
- package/lib/project-logs-canonical-clay.js +27 -0
- package/lib/project-logs-clay-query.js +16 -0
- package/lib/project-logs-schema.js +4 -2
- package/lib/project-logs-service.js +8 -7
- package/lib/project-logs.js +1 -0
- package/lib/project-loop.js +1 -0
- package/lib/project-mate-chat-control.js +55 -0
- package/lib/project-mate-creation-proposal.js +18 -3
- package/lib/project-mate-interaction.js +40 -62
- package/lib/project-mcp.js +54 -16
- package/lib/project-models.js +14 -31
- package/lib/project-notifications.js +76 -17
- package/lib/project-ownership.js +77 -0
- package/lib/project-pair-result-delivery.js +14 -3
- package/lib/project-pair-usage.js +12 -13
- package/lib/project-pending-message-queue.js +4 -1
- package/lib/project-product-control.js +89 -0
- package/lib/project-product-session-queue.js +46 -0
- package/lib/project-push-access.js +28 -0
- package/lib/project-scheduled-message-queue.js +30 -0
- package/lib/project-scheduled-messages.js +67 -68
- package/lib/project-scheduled-task-control.js +83 -0
- package/lib/project-scheduled-tasks.js +13 -2
- package/lib/project-scheduling-access.js +10 -0
- package/lib/project-session-actions.js +65 -0
- package/lib/project-session-delete.js +8 -1
- package/lib/project-session-document.js +27 -7
- package/lib/project-session-github.js +63 -19
- package/lib/project-session-history-actions.js +167 -0
- package/lib/project-session-linear.js +14 -6
- package/lib/project-session-notes.js +40 -11
- package/lib/project-session-pair.js +1 -1
- package/lib/project-session-runtime-actions.js +64 -0
- package/lib/project-session-spawn.js +2 -3
- package/lib/project-session-vendor.js +55 -0
- package/lib/project-sessions.js +160 -290
- package/lib/project-shared-browser.js +78 -17
- package/lib/project-start-protocol.js +29 -0
- package/lib/project-studio-presentation.js +58 -0
- package/lib/project-user-message.js +67 -1
- package/lib/project-vendor-login.js +8 -36
- package/lib/project-workspace-operations.js +126 -0
- package/lib/project-workspace-query.js +19 -2
- package/lib/project.js +181 -45
- package/lib/public/app.js +71 -17
- package/lib/public/appearance-bootstrap.js +16 -0
- package/lib/public/css/clay-tool-activity.css +51 -0
- package/lib/public/css/clay-workspace.css +29 -0
- package/lib/public/css/command-palette.css +12 -33
- package/lib/public/css/contextual-clay.css +240 -0
- package/lib/public/css/filebrowser.css +1 -1
- package/lib/public/css/home-debate-planning.css +2 -0
- package/lib/public/css/home-mate-creation.css +5 -0
- package/lib/public/css/input.css +6 -0
- package/lib/public/css/mate-avatar-gallery.css +12 -0
- package/lib/public/css/mate-conversation.css +10 -5
- package/lib/public/css/mate-loading-scene.css +21 -0
- package/lib/public/css/messages.css +6 -2
- package/lib/public/css/overlays.css +68 -258
- package/lib/public/css/project-admin-overview.css +13 -0
- package/lib/public/css/project-mate-creation.css +5 -6
- package/lib/public/css/project-start.css +108 -0
- package/lib/public/css/projects-hub.css +53 -14
- package/lib/public/css/session-folders.css +11 -0
- package/lib/public/css/session-github.css +46 -1
- package/lib/public/css/settings-shell.css +103 -0
- package/lib/public/css/shared-browser.css +35 -1
- package/lib/public/css/sidebar.css +7 -0
- package/lib/public/css/sticky-notes.css +87 -1
- package/lib/public/css/title-bar.css +79 -0
- package/lib/public/index.html +61 -68
- package/lib/public/mate-avatars/B01.png +0 -0
- package/lib/public/mate-avatars/B02.png +0 -0
- package/lib/public/mate-avatars/B03.png +0 -0
- package/lib/public/mate-avatars/B04.png +0 -0
- package/lib/public/mate-avatars/B05.png +0 -0
- package/lib/public/mate-avatars/B06.png +0 -0
- package/lib/public/mate-avatars/B07.png +0 -0
- package/lib/public/mate-avatars/B08.png +0 -0
- package/lib/public/mate-avatars/B09.png +0 -0
- package/lib/public/mate-avatars/B10.png +0 -0
- package/lib/public/mate-avatars/B11.png +0 -0
- package/lib/public/mate-avatars/B12.png +0 -0
- package/lib/public/mate-avatars/B13.png +0 -0
- package/lib/public/mate-avatars/B14.png +0 -0
- package/lib/public/mate-avatars/B15.png +0 -0
- package/lib/public/mate-avatars/B16.png +0 -0
- package/lib/public/mate-avatars/B17.png +0 -0
- package/lib/public/mate-avatars/B18.png +0 -0
- package/lib/public/mate-avatars/B19.png +0 -0
- package/lib/public/mate-avatars/B20.png +0 -0
- package/lib/public/mate-avatars/B21.png +0 -0
- package/lib/public/mate-avatars/B22.png +0 -0
- package/lib/public/mate-avatars/B23.png +0 -0
- package/lib/public/mate-avatars/B24.png +0 -0
- package/lib/public/mate-avatars/B25.png +0 -0
- package/lib/public/mate-avatars/B26.png +0 -0
- package/lib/public/mate-avatars/B27.png +0 -0
- package/lib/public/mate-avatars/B28.png +0 -0
- package/lib/public/mate-avatars/B29.png +0 -0
- package/lib/public/mate-avatars/B30.png +0 -0
- package/lib/public/mate-avatars/B31.png +0 -0
- package/lib/public/mate-avatars/B32.png +0 -0
- package/lib/public/mate-avatars/B33.png +0 -0
- package/lib/public/mate-avatars/B34.png +0 -0
- package/lib/public/mate-avatars/B35.png +0 -0
- package/lib/public/mate-avatars/B36.png +0 -0
- package/lib/public/mate-avatars/B37.png +0 -0
- package/lib/public/mate-avatars/B38.png +0 -0
- package/lib/public/mate-avatars/B39.png +0 -0
- package/lib/public/mate-avatars/B40.png +0 -0
- package/lib/public/mate-avatars/B41.png +0 -0
- package/lib/public/mate-avatars/B42.png +0 -0
- package/lib/public/mate-avatars/B43.png +0 -0
- package/lib/public/mate-avatars/B44.png +0 -0
- package/lib/public/mate-avatars/B45.png +0 -0
- package/lib/public/mate-avatars/B46.png +0 -0
- package/lib/public/mate-avatars/B47.png +0 -0
- package/lib/public/mate-avatars/B48.png +0 -0
- package/lib/public/mate-avatars/C01.png +0 -0
- package/lib/public/mate-avatars/C02.png +0 -0
- package/lib/public/mate-avatars/C03.png +0 -0
- package/lib/public/mate-avatars/C04.png +0 -0
- package/lib/public/mate-avatars/C05.png +0 -0
- package/lib/public/mate-avatars/C06.png +0 -0
- package/lib/public/mate-avatars/C07.png +0 -0
- package/lib/public/mate-avatars/C08.png +0 -0
- package/lib/public/mate-avatars/C09.png +0 -0
- package/lib/public/mate-avatars/C10.png +0 -0
- package/lib/public/mate-avatars/C11.png +0 -0
- package/lib/public/mate-avatars/C12.png +0 -0
- package/lib/public/mate-avatars/C13.png +0 -0
- package/lib/public/mate-avatars/C14.png +0 -0
- package/lib/public/mate-avatars/C15.png +0 -0
- package/lib/public/mate-avatars/C16.png +0 -0
- package/lib/public/mate-avatars/C17.png +0 -0
- package/lib/public/mate-avatars/C18.png +0 -0
- package/lib/public/mate-avatars/C19.png +0 -0
- package/lib/public/mate-avatars/C20.png +0 -0
- package/lib/public/mate-avatars/C21.png +0 -0
- package/lib/public/mate-avatars/C22.png +0 -0
- package/lib/public/mate-avatars/C23.png +0 -0
- package/lib/public/mate-avatars/C24.png +0 -0
- package/lib/public/mate-avatars/C25.png +0 -0
- package/lib/public/mate-avatars/C26.png +0 -0
- package/lib/public/mate-avatars/C27.png +0 -0
- package/lib/public/mate-avatars/C28.png +0 -0
- package/lib/public/mate-avatars/C29.png +0 -0
- package/lib/public/mate-avatars/C30.png +0 -0
- package/lib/public/mate-avatars/C31.png +0 -0
- package/lib/public/mate-avatars/C32.png +0 -0
- package/lib/public/mate-avatars/C33.png +0 -0
- package/lib/public/mate-avatars/C34.png +0 -0
- package/lib/public/mate-avatars/C35.png +0 -0
- package/lib/public/mate-avatars/C36.png +0 -0
- package/lib/public/mate-avatars/C37.png +0 -0
- package/lib/public/mate-avatars/C38.png +0 -0
- package/lib/public/mate-avatars/C39.png +0 -0
- package/lib/public/mate-avatars/C40.png +0 -0
- package/lib/public/mate-avatars/C41.png +0 -0
- package/lib/public/mate-avatars/C42.png +0 -0
- package/lib/public/mate-avatars/C43.png +0 -0
- package/lib/public/mate-avatars/C44.png +0 -0
- package/lib/public/mate-avatars/C45.png +0 -0
- package/lib/public/mate-avatars/C46.png +0 -0
- package/lib/public/mate-avatars/C47.png +0 -0
- package/lib/public/mate-avatars/C48.png +0 -0
- package/lib/public/mate-avatars/catalog.json +482 -0
- package/lib/public/mate-avatars/lead-clay.png +0 -0
- package/lib/public/modules/admin-settings-invitations.js +2 -2
- package/lib/public/modules/admin-settings-projects.js +8 -4
- package/lib/public/modules/admin-settings-ui.js +20 -4
- package/lib/public/modules/admin-settings-users.js +4 -4
- package/lib/public/modules/app-connection.js +11 -1
- package/lib/public/modules/app-favicon.js +18 -9
- package/lib/public/modules/app-header.js +7 -4
- package/lib/public/modules/app-home-hub.js +2 -1
- package/lib/public/modules/app-loop-ui.js +2 -0
- package/lib/public/modules/app-message-router.js +22 -1
- package/lib/public/modules/app-messages.js +125 -19
- package/lib/public/modules/app-misc.js +3 -1
- package/lib/public/modules/app-notifications.js +11 -5
- package/lib/public/modules/app-panels.js +61 -123
- package/lib/public/modules/app-projects.js +14 -407
- package/lib/public/modules/app-rate-limit.js +19 -28
- package/lib/public/modules/app-rendering.js +4 -3
- package/lib/public/modules/avatar.js +15 -41
- package/lib/public/modules/chat-render-runtime.js +20 -0
- package/lib/public/modules/clay-browser-links.js +47 -0
- package/lib/public/modules/clay-control-activity.js +214 -0
- package/lib/public/modules/clay-control-copy.js +36 -0
- package/lib/public/modules/clay-control-detail-targets.js +44 -0
- package/lib/public/modules/clay-control-object-targets.js +52 -0
- package/lib/public/modules/clay-control-target-visibility.js +12 -0
- package/lib/public/modules/clay-control-targets.js +44 -0
- package/lib/public/modules/clay-log-links.js +23 -0
- package/lib/public/modules/clay-navigation-render.js +52 -0
- package/lib/public/modules/clay-owner-navigation.js +33 -0
- package/lib/public/modules/clay-session-links.js +31 -0
- package/lib/public/modules/clay-studio-bridge.js +20 -0
- package/lib/public/modules/clay-studio-document.js +67 -0
- package/lib/public/modules/clay-studio-render.js +146 -0
- package/lib/public/modules/clay-tool-activity.js +140 -0
- package/lib/public/modules/clay-tool-presentation.js +343 -0
- package/lib/public/modules/command-palette.js +162 -40
- package/lib/public/modules/contextual-ask-session.js +26 -0
- package/lib/public/modules/contextual-clay-geometry.js +155 -0
- package/lib/public/modules/contextual-clay-session.js +130 -0
- package/lib/public/modules/contextual-clay-workspace.js +169 -0
- package/lib/public/modules/contextual-clay.js +252 -0
- package/lib/public/modules/contextual-composer.js +91 -0
- package/lib/public/modules/contextual-mate-context.js +117 -0
- package/lib/public/modules/contextual-mate-hint.js +40 -0
- package/lib/public/modules/contextual-mate-identity.js +23 -0
- package/lib/public/modules/contextual-mate-sessions.js +134 -0
- package/lib/public/modules/contextual-search.js +137 -0
- package/lib/public/modules/contextual-session-citations.js +58 -0
- package/lib/public/modules/debate.js +1 -0
- package/lib/public/modules/default-ai.js +11 -3
- package/lib/public/modules/elicitation-form.js +5 -0
- package/lib/public/modules/filebrowser.js +20 -1
- package/lib/public/modules/generation-stop.js +8 -5
- package/lib/public/modules/git-panel.js +3 -1
- package/lib/public/modules/github-star.js +66 -0
- package/lib/public/modules/history-replay-batch.js +13 -1
- package/lib/public/modules/home-debate-live.js +2 -0
- package/lib/public/modules/home-debate-planning.js +7 -7
- package/lib/public/modules/home-mate-avatar-editor.js +127 -208
- package/lib/public/modules/home-mate-chat.js +8 -6
- package/lib/public/modules/home-mate-creation.js +73 -1
- package/lib/public/modules/home-mate-settings.js +19 -12
- package/lib/public/modules/icon-strip-tooltip.js +2 -1
- package/lib/public/modules/input.js +88 -10
- package/lib/public/modules/issues-render.js +3 -2
- package/lib/public/modules/knowledge-db-workbench.js +4 -4
- package/lib/public/modules/markdown.js +6 -34
- package/lib/public/modules/mate-avatar-catalog.js +97 -0
- package/lib/public/modules/mate-knowledge-workbench.js +1 -1
- package/lib/public/modules/mate-loading-scene.js +17 -0
- package/lib/public/modules/mate-management.js +40 -7
- package/lib/public/modules/mcp-connection-view.js +31 -13
- package/lib/public/modules/mcp-discovery-view.js +31 -0
- package/lib/public/modules/mcp-ui.js +23 -4
- package/lib/public/modules/mention.js +3 -0
- package/lib/public/modules/message-delivery.js +20 -2
- package/lib/public/modules/model-picker.js +2 -0
- package/lib/public/modules/pane-activation.js +214 -0
- package/lib/public/modules/pane-binding.js +82 -0
- package/lib/public/modules/pane-bridge.js +7 -4
- package/lib/public/modules/pane-browser-bridge.js +22 -0
- package/lib/public/modules/pane-file-bridge.js +4 -0
- package/lib/public/modules/pane-issue-bridge.js +4 -1
- package/lib/public/modules/pending-message-queue.js +1 -0
- package/lib/public/modules/permission-control.js +5 -4
- package/lib/public/modules/personal-settings-dialog.js +7 -1
- package/lib/public/modules/product-review.js +26 -0
- package/lib/public/modules/profile.js +12 -241
- package/lib/public/modules/project-access-recovery.js +17 -0
- package/lib/public/modules/project-admin-overview.js +21 -0
- package/lib/public/modules/project-chat-identity.js +13 -4
- package/lib/public/modules/project-logs-render.js +3 -0
- package/lib/public/modules/project-mate-creation-workspace.js +13 -4
- package/lib/public/modules/project-mate-navigation.js +144 -22
- package/lib/public/modules/project-session-visibility-settings.js +19 -16
- package/lib/public/modules/project-settings.js +119 -129
- package/lib/public/modules/project-start-dialog.js +130 -0
- package/lib/public/modules/project-start-folder-state.js +78 -0
- package/lib/public/modules/project-start-folder-view.js +190 -0
- package/lib/public/modules/project-start-forms.js +66 -0
- package/lib/public/modules/project-start-path.js +60 -0
- package/lib/public/modules/project-start-state.js +54 -0
- package/lib/public/modules/project-start-submit.js +67 -0
- package/lib/public/modules/projects-hub-view.js +33 -14
- package/lib/public/modules/projects-hub.js +10 -6
- package/lib/public/modules/rewind.js +5 -0
- package/lib/public/modules/scheduled-tasks.js +2 -0
- package/lib/public/modules/scheduler.js +2 -0
- package/lib/public/modules/search-clay-chat.js +5 -440
- package/lib/public/modules/server-settings.js +36 -91
- package/lib/public/modules/session-actions.js +5 -2
- package/lib/public/modules/session-context-menu.js +5 -0
- package/lib/public/modules/session-create-form.js +10 -10
- package/lib/public/modules/session-folder-layout.js +1 -1
- package/lib/public/modules/session-folder-view-menu.js +9 -0
- package/lib/public/modules/session-github.js +85 -14
- package/lib/public/modules/session-rich-drafts.js +21 -0
- package/lib/public/modules/session-switch-defer.js +67 -0
- package/lib/public/modules/session-work-primary.js +51 -0
- package/lib/public/modules/settings-defaults.js +27 -28
- package/lib/public/modules/settings-project-target.js +56 -0
- package/lib/public/modules/settings-select.js +1 -1
- package/lib/public/modules/settings-shell-registry.js +88 -0
- package/lib/public/modules/settings-shell-view.js +104 -0
- package/lib/public/modules/settings-shell.js +342 -0
- package/lib/public/modules/shared-browser-settings.js +112 -0
- package/lib/public/modules/shared-browser-tabs.js +13 -3
- package/lib/public/modules/shared-browser.js +29 -6
- package/lib/public/modules/sidebar-mobile.js +12 -33
- package/lib/public/modules/sidebar-projects.js +3 -1
- package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
- package/lib/public/modules/sidebar-sessions.js +1 -0
- package/lib/public/modules/split-group-restore.js +68 -0
- package/lib/public/modules/split-pair-ui.js +1 -0
- package/lib/public/modules/split-pane-reconciler.js +15 -0
- package/lib/public/modules/split-pane-renderer.js +87 -6
- package/lib/public/modules/split-session-boundary.js +1 -1
- package/lib/public/modules/split-view.js +60 -68
- package/lib/public/modules/sticky-note-markdown.js +72 -6
- package/lib/public/modules/sticky-notes-actions.js +30 -0
- package/lib/public/modules/sticky-notes-browser.js +9 -2
- package/lib/public/modules/sticky-notes-card.js +23 -7
- package/lib/public/modules/sticky-notes-checklist.js +116 -0
- package/lib/public/modules/sticky-notes-editor.js +108 -44
- package/lib/public/modules/sticky-notes-shared.js +50 -2
- package/lib/public/modules/sticky-notes-state.js +66 -0
- package/lib/public/modules/sticky-notes.js +34 -51
- package/lib/public/modules/stt-controller.js +4 -1
- package/lib/public/modules/stt-recording.js +1 -1
- package/lib/public/modules/stt.js +7 -2
- package/lib/public/modules/terminal.js +9 -0
- package/lib/public/modules/theme.js +18 -3
- package/lib/public/modules/thinking-lifecycle.js +33 -3
- package/lib/public/modules/thinking-view.js +23 -1
- package/lib/public/modules/tools.js +60 -11
- package/lib/public/modules/tui-grab.js +1 -2
- package/lib/public/modules/user-settings-appearance.js +10 -3
- package/lib/public/modules/user-settings-editors.js +1 -1
- package/lib/public/modules/user-settings-layout.js +14 -30
- package/lib/public/modules/user-settings-preferences.js +6 -2
- package/lib/public/modules/user-settings-profile.js +13 -3
- package/lib/public/modules/user-settings.js +18 -84
- package/lib/public/modules/vendor-login-browser.js +5 -3
- package/lib/public/modules/vendor-login.js +2 -2
- package/lib/public/modules/vendor-priority.js +15 -1
- package/lib/public/modules/vendor-usage-format.js +93 -0
- package/lib/public/modules/vendor-usage-list.js +45 -0
- package/lib/public/modules/vendor-usage-model.js +215 -0
- package/lib/public/modules/vendor-usage-overview.js +312 -0
- package/lib/public/modules/wireframe-workbench.js +5 -2
- package/lib/public/muse-avatar.svg +4 -0
- package/lib/public/style.css +14 -6
- package/lib/public/sw.js +3 -1
- package/lib/public/welcome-art/conversation-desk.png +0 -0
- package/lib/public/welcome-art/mate-clay.png +0 -0
- package/lib/public/welcome-art/project-clay.png +0 -0
- package/lib/safe-bash-commands.js +3 -45
- package/lib/scheduled-task-records.js +3 -1
- package/lib/scheduler.js +2 -0
- package/lib/sdk-bridge.js +348 -402
- package/lib/sdk-foreground-admission.js +16 -0
- package/lib/sdk-mcp-descriptors.js +2 -37
- package/lib/sdk-message-processor.js +61 -18
- package/lib/sdk-quota-snapshot.js +21 -3
- package/lib/sdk-response-recovery.js +1 -0
- package/lib/sdk-worker.js +2 -677
- package/lib/server-admin.js +63 -16
- package/lib/server-appearance-settings.js +13 -1
- package/lib/server-contextual-clay-settings.js +40 -0
- package/lib/server-contextual-mate-sessions.js +70 -0
- package/lib/server-dm.js +2 -1
- package/lib/server-github-stars.js +39 -0
- package/lib/server-global-ws.js +26 -32
- package/lib/server-home-chat-events.js +18 -4
- package/lib/server-home-chat.js +22 -20
- package/lib/server-home-clay-entry.js +23 -4
- package/lib/server-home-clay-session-links.js +29 -9
- package/lib/server-home-mate-creation.js +1 -0
- package/lib/server-home-mcp-consent.js +14 -0
- package/lib/server-mates.js +25 -62
- package/lib/server-owner-ui.js +118 -0
- package/lib/server-path-access.js +38 -0
- package/lib/server-project-removal.js +22 -0
- package/lib/server-settings.js +6 -1
- package/lib/server.js +167 -43
- package/lib/session-config-transition.js +45 -0
- package/lib/session-folders.js +7 -2
- package/lib/session-fork-history.js +21 -0
- package/lib/session-github.js +9 -2
- package/lib/session-hygiene.js +3 -35
- package/lib/session-notes-mcp-server.js +26 -4
- package/lib/session-notes-writes.js +88 -0
- package/lib/session-permission-mode.js +4 -3
- package/lib/session-skill-scope.js +11 -0
- package/lib/session-visibility.js +25 -10
- package/lib/session-work-primary.js +50 -0
- package/lib/sessions.js +66 -99
- package/lib/shared-browser-cookie-sync.js +32 -0
- package/lib/shared-browser-cookies.js +79 -0
- package/lib/shared-browser-runtime.js +25 -9
- package/lib/shared-browser-storage-sync.js +43 -0
- package/lib/shared-browser-storage.js +101 -0
- package/lib/shared-browser-tools.js +2 -1
- package/lib/shared-browser-worker.js +46 -10
- package/lib/terminal-manager.js +65 -6
- package/lib/tool-llm.js +1 -1
- package/lib/tui-transcript-index.js +1 -132
- package/lib/users-contextual-clay-preferences.js +31 -0
- package/lib/users-permissions.js +2 -8
- package/lib/users.js +7 -0
- package/lib/vendor-login-browser.js +1 -11
- package/lib/vendor-usage-acp-readers.js +97 -0
- package/lib/vendor-usage-capabilities.js +88 -0
- package/lib/vendor-usage-http-readers.js +214 -0
- package/lib/vendor-usage-metrics.js +47 -0
- package/lib/vendor-usage-native-readers.js +106 -0
- package/lib/vendor-usage-overview.js +406 -0
- package/lib/vendor-usage-service.js +281 -0
- package/lib/workspace-assignment-service.js +25 -0
- package/lib/workspace-query-access.js +4 -1
- package/lib/workspace-query-mcp-server.js +1 -1
- package/lib/workspace-query-service.js +13 -2
- package/lib/ws-request.js +1 -0
- package/lib/ws-schema.js +22 -4
- package/lib/yoke/acp-agent-profiles.js +7 -5
- package/lib/yoke/adapters/antigravity.js +3 -14
- package/lib/yoke/adapters/claude-query-contract.js +9 -0
- package/lib/yoke/adapters/claude.js +66 -50
- package/lib/yoke/adapters/codex-query-contract.js +25 -0
- package/lib/yoke/adapters/codex.js +98 -123
- package/lib/yoke/adapters/kiro.js +3 -1
- package/lib/yoke/adapters/muse-query-contract.js +7 -0
- package/lib/yoke/adapters/muse.js +122 -0
- package/lib/yoke/auth-events.js +17 -0
- package/lib/yoke/claude-hook-installer.js +272 -0
- package/lib/yoke/claude-jsonl-watcher.js +204 -0
- package/lib/yoke/claude-maintenance.js +55 -0
- package/lib/yoke/claude-permission-patterns.js +53 -0
- package/lib/yoke/claude-response-recovery.js +155 -0
- package/lib/yoke/claude-transcript-hygiene.js +34 -0
- package/lib/yoke/claude-worker-startup.js +28 -0
- package/lib/yoke/clay-skill-install.js +33 -0
- package/lib/yoke/cli-sessions.js +300 -0
- package/lib/yoke/codex-app-server.js +7 -12
- package/lib/yoke/codex-dynamic-tool-names.js +80 -0
- package/lib/yoke/codex-idle-recovery.js +81 -1
- package/lib/yoke/codex-model-catalog.js +37 -3
- package/lib/yoke/codex-recovery-admission.js +164 -0
- package/lib/yoke/configuration.js +13 -0
- package/lib/yoke/discovery.js +70 -0
- package/lib/yoke/errors.js +8 -0
- package/lib/yoke/host-environment.js +7 -0
- package/lib/yoke/index.js +9 -51
- package/lib/yoke/interface.js +116 -0
- package/lib/yoke/kiro-acp-server.js +5 -5
- package/lib/yoke/legacy-sessions.js +89 -0
- package/lib/yoke/login-protocol.js +25 -0
- package/lib/yoke/maintenance.js +12 -0
- package/lib/yoke/mcp-proxy.js +32 -0
- package/lib/yoke/mcp-source-adapters.js +91 -0
- package/lib/yoke/mcp-source-context.js +42 -0
- package/lib/yoke/mcp-source-discovery.js +169 -0
- package/lib/yoke/mcp-source-plugins.js +68 -0
- package/lib/yoke/mcp-source-restrictions.js +47 -0
- package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
- package/lib/yoke/model-preferences.js +6 -0
- package/lib/yoke/muse-artifacts.js +36 -0
- package/lib/yoke/muse-controls.js +50 -0
- package/lib/yoke/muse-input.js +64 -0
- package/lib/yoke/muse-items.js +157 -0
- package/lib/yoke/muse-policy.js +52 -0
- package/lib/yoke/muse-query.js +428 -0
- package/lib/yoke/muse-runtime.js +211 -0
- package/lib/yoke/muse-services.js +92 -0
- package/lib/yoke/muse-skills.js +79 -0
- package/lib/yoke/muse-turns.js +71 -0
- package/lib/yoke/options/acp.js +2 -0
- package/lib/yoke/options/antigravity.js +2 -0
- package/lib/yoke/options/claude.js +21 -0
- package/lib/yoke/options/codex-defaults.js +29 -0
- package/lib/yoke/options/codex-settings.js +21 -0
- package/lib/yoke/options/codex.js +6 -0
- package/lib/yoke/options/kiro-defaults.js +22 -0
- package/lib/yoke/options/kiro.js +5 -0
- package/lib/yoke/options/muse.js +5 -0
- package/lib/yoke/provider-contract.js +5 -0
- package/lib/yoke/providers/antigravity-executable.js +8 -0
- package/lib/yoke/providers/claude-executable.js +40 -0
- package/lib/yoke/providers/claude-model-descriptions.js +34 -0
- package/lib/yoke/providers/claude-process.js +97 -0
- package/lib/yoke/providers/claude-provision.js +75 -0
- package/lib/yoke/providers/codex-errors.js +8 -0
- package/lib/yoke/providers/muse-executable.js +17 -0
- package/lib/yoke/provisioning.js +6 -0
- package/lib/yoke/query-options.js +10 -0
- package/lib/yoke/response-recovery.js +41 -0
- package/lib/yoke/sdk-mcp-descriptors.js +37 -0
- package/lib/yoke/sdk-server-factory.js +7 -0
- package/lib/yoke/session-history.js +8 -0
- package/lib/yoke/session-tool-transport.js +34 -13
- package/lib/yoke/settings.js +23 -0
- package/lib/yoke/source-locations.js +4 -0
- package/lib/yoke/title-query.js +18 -7
- package/lib/yoke/tui-transcript-index.js +132 -0
- package/lib/yoke/usage.js +48 -0
- package/lib/yoke/user-input.js +13 -0
- package/lib/yoke/vendor-registry.js +87 -3
- package/package.json +11 -4
- package/lib/public/modules/server-settings-navigation.js +0 -39
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Plain task controls use Markdown only as the internal persistence format.
|
|
2
|
+
import { iconHtml, refreshIcons } from './icons.js';
|
|
3
|
+
import { getChecklistItems } from './sticky-note-markdown.js';
|
|
4
|
+
import { getNoteUiState, setNoteUiState } from './sticky-notes-shared.js';
|
|
5
|
+
import { mutateChecklist } from './sticky-notes-state.js';
|
|
6
|
+
|
|
7
|
+
export function checklistDraftText(ui) {
|
|
8
|
+
var fields = ui.checklistInputs || {};
|
|
9
|
+
var lines = (ui.text || '').split('\n');
|
|
10
|
+
if (fields.title !== undefined) lines[0] = fields.title;
|
|
11
|
+
getChecklistItems(ui.text).forEach(function (item) {
|
|
12
|
+
if (fields[item.key] !== undefined) {
|
|
13
|
+
var marker = item.text.match(/^\s*(?:[-*+]\s+)?\[([ xX])\]/);
|
|
14
|
+
var checked = ui.checklistState[item.key];
|
|
15
|
+
if (checked === undefined) checked = marker && marker[1].toLowerCase() === 'x';
|
|
16
|
+
lines[item.index + 1] = '- [' + (checked ? 'x' : ' ') + '] ' + fields[item.key];
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
if (fields.entry && fields.entry.trim()) {
|
|
20
|
+
if (!lines[0].trim()) lines[0] = 'Checklist';
|
|
21
|
+
lines.push('- [ ] ' + fields.entry.trim());
|
|
22
|
+
}
|
|
23
|
+
return lines.join('\n');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function renderTaskControls(root, id) {
|
|
27
|
+
var ui = getNoteUiState(id);
|
|
28
|
+
var fields = ui.checklistInputs || {};
|
|
29
|
+
var busy = ui.pending.length > 0;
|
|
30
|
+
var active = document.activeElement;
|
|
31
|
+
var focusField = active && root.contains(active) ? active.dataset.taskField : undefined;
|
|
32
|
+
var selection = focusField !== undefined ? [active.selectionStart, active.selectionEnd] : null;
|
|
33
|
+
root.replaceChildren();
|
|
34
|
+
var form = document.createElement('form'); form.className = 'sn-task-form';
|
|
35
|
+
form.setAttribute('aria-label', 'Checklist');
|
|
36
|
+
form.setAttribute('aria-busy', busy ? 'true' : 'false');
|
|
37
|
+
var feedback = document.createElement('span'); feedback.className = 'sn-task-feedback';
|
|
38
|
+
feedback.setAttribute('role', 'status');
|
|
39
|
+
var saveButton = document.createElement('button');
|
|
40
|
+
function updateFeedback() {
|
|
41
|
+
var current = getNoteUiState(id);
|
|
42
|
+
var dirty = checklistDraftText(current) !== current.text;
|
|
43
|
+
feedback.textContent = busy ? 'Saving…' : current.error ? (dirty ? 'Draft kept. ' : 'Not saved. ') + current.error : dirty ? 'Unsaved changes' : 'All changes saved';
|
|
44
|
+
saveButton.disabled = busy || !dirty;
|
|
45
|
+
}
|
|
46
|
+
function input(label, value, key) {
|
|
47
|
+
var control = document.createElement('textarea'); control.rows = 1; control.value = fields[key] !== undefined ? fields[key] : value;
|
|
48
|
+
control.setAttribute('aria-label', label); control.placeholder = label; control.maxLength = 400;
|
|
49
|
+
control.readOnly = busy;
|
|
50
|
+
control.dataset.taskField = key;
|
|
51
|
+
control.onkeydown = function (event) {
|
|
52
|
+
if (event.key === 'Enter' && !event.isComposing) { event.preventDefault(); form.requestSubmit(); }
|
|
53
|
+
};
|
|
54
|
+
control.oninput = function () {
|
|
55
|
+
var current = getNoteUiState(id);
|
|
56
|
+
// A task remains one persisted line; visual wrapping does not split tasks.
|
|
57
|
+
control.value = control.value.replace(/[\r\n]+/g, ' ');
|
|
58
|
+
var draft = Object.assign({}, current.checklistInputs || {}); draft[key] = control.value;
|
|
59
|
+
setNoteUiState(id, { checklistInputs: draft });
|
|
60
|
+
updateFeedback();
|
|
61
|
+
};
|
|
62
|
+
return control;
|
|
63
|
+
}
|
|
64
|
+
var title = input('Checklist title', (ui.text || '').split('\n')[0], 'title'); title.className = 'sn-task-title'; form.appendChild(title);
|
|
65
|
+
var items = getChecklistItems(ui.text);
|
|
66
|
+
var completed = 0;
|
|
67
|
+
var summary = document.createElement('div'); summary.className = 'sn-task-summary';
|
|
68
|
+
form.appendChild(summary);
|
|
69
|
+
items.forEach(function (item, position) {
|
|
70
|
+
var row = document.createElement('div'); row.className = 'sn-task-row';
|
|
71
|
+
var marker = item.text.match(/^\s*(?:[-*+]\s+)?\[([ xX])\]\s*(.*)$/);
|
|
72
|
+
var check = document.createElement('button'); check.type = 'button'; check.className = 'sn-check';
|
|
73
|
+
var checked = ui.checklistState[item.key];
|
|
74
|
+
if (checked === undefined) checked = marker && marker[1].toLowerCase() === 'x';
|
|
75
|
+
check.classList.toggle('checked', !!checked);
|
|
76
|
+
check.innerHTML = '<span class="sn-task-box" aria-hidden="true"><svg viewBox="0 0 16 16" fill="none"><path d="m3.5 8 3 3 6-6" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></span>';
|
|
77
|
+
row.classList.toggle('is-complete', !!checked);
|
|
78
|
+
if (checked) completed++;
|
|
79
|
+
check.setAttribute('role', 'checkbox'); check.setAttribute('aria-checked', checked ? 'true' : 'false'); check.setAttribute('aria-label', 'Complete task ' + (position + 1));
|
|
80
|
+
check.dataset.checklistIndex = item.index; check.dataset.checklistKey = encodeURIComponent(item.key);
|
|
81
|
+
check.disabled = busy;
|
|
82
|
+
var label = input('Task ' + (position + 1), marker ? marker[2] : item.text, item.key);
|
|
83
|
+
var remove = document.createElement('button'); remove.type = 'button'; remove.className = 'sn-task-remove'; remove.innerHTML = iconHtml('x'); remove.setAttribute('aria-label', 'Remove task ' + (position + 1)); remove.disabled = busy;
|
|
84
|
+
remove.onclick = function () {
|
|
85
|
+
var current = getNoteUiState(id); var lines = checklistDraftText(current).split('\n'); lines.splice(item.index + 1, 1);
|
|
86
|
+
save(lines.join('\n'));
|
|
87
|
+
};
|
|
88
|
+
row.append(check, label, remove); form.appendChild(row);
|
|
89
|
+
});
|
|
90
|
+
summary.textContent = items.length ? completed + ' of ' + items.length + ' complete' : 'A little space for what’s next';
|
|
91
|
+
var addRow = document.createElement('div'); addRow.className = 'sn-task-add';
|
|
92
|
+
var plus = document.createElement('span'); plus.className = 'sn-task-plus'; plus.innerHTML = iconHtml('plus'); plus.setAttribute('aria-hidden', 'true');
|
|
93
|
+
var entry = input('New task', '', 'entry'); entry.className = 'sn-task-entry'; entry.placeholder = 'Add a task…';
|
|
94
|
+
addRow.append(plus, entry); form.appendChild(addRow);
|
|
95
|
+
var footer = document.createElement('div'); footer.className = 'sn-task-footer';
|
|
96
|
+
saveButton.type = 'submit'; saveButton.className = 'sn-task-save'; saveButton.textContent = 'Save tasks';
|
|
97
|
+
footer.append(feedback, saveButton); form.appendChild(footer);
|
|
98
|
+
updateFeedback();
|
|
99
|
+
function save(text) {
|
|
100
|
+
var current = getNoteUiState(id);
|
|
101
|
+
if (current.pending.length) return;
|
|
102
|
+
mutateChecklist(id, { checklistEdit: true, checklistSource: current.canonical.text, checklistVersion: current.canonical.updatedAt, text: text });
|
|
103
|
+
}
|
|
104
|
+
form.onsubmit = function (event) { event.preventDefault(); save(checklistDraftText(getNoteUiState(id))); };
|
|
105
|
+
root.appendChild(form); refreshIcons(root);
|
|
106
|
+
if (focusField !== undefined) {
|
|
107
|
+
var controls = form.querySelectorAll('[data-task-field]');
|
|
108
|
+
for (var i = 0; i < controls.length; i++) {
|
|
109
|
+
if (controls[i].dataset.taskField === focusField) {
|
|
110
|
+
controls[i].focus({ preventScroll: true });
|
|
111
|
+
controls[i].setSelectionRange(selection[0], selection[1]);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -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
|
+
});
|