clay-server 5.2.0-beta.1 → 5.2.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/lib/account-auth-socket.js +1 -0
- package/lib/builtin-mates.js +19 -16
- package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
- package/lib/canonical-clay-record-authority.js +15 -0
- package/lib/canonical-clay-scheduling-authority.js +19 -0
- package/lib/claude-hook-installer.js +1 -239
- package/lib/claude-jsonl-watcher.js +1 -204
- package/lib/clay-control-presentation-binding.js +96 -0
- package/lib/clay-control-presentation.js +128 -0
- package/lib/clay-control-target-projection.js +26 -0
- package/lib/clay-mate-chat-receipts.js +26 -0
- package/lib/clay-mate-chat.js +88 -0
- package/lib/clay-mate-knowledge-input.js +26 -0
- package/lib/clay-mate-knowledge.js +95 -0
- package/lib/clay-mate-lifecycle.js +95 -0
- package/lib/clay-product-control-input.js +33 -0
- package/lib/clay-product-control-tools.js +52 -0
- package/lib/clay-product-control.js +250 -0
- package/lib/clay-project-lifecycle.js +154 -0
- package/lib/clay-project-record-input.js +44 -0
- package/lib/clay-project-records.js +84 -0
- package/lib/clay-scheduling-input.js +21 -0
- package/lib/clay-scheduling-receipts.js +26 -0
- package/lib/clay-scheduling.js +119 -0
- package/lib/clay-screen-controls.js +104 -0
- package/lib/clay-skill-install.js +1 -33
- package/lib/clay-vendor-usage.js +44 -0
- package/lib/clay-workspace-controls.js +84 -0
- package/lib/clay-workspace-input.js +17 -0
- package/lib/clay-workspace-receipts.js +26 -0
- package/lib/cli-sessions.js +1 -300
- package/lib/codex-defaults.js +1 -28
- package/lib/context-usage.js +3 -2
- package/lib/contextual-screen-snapshot.js +38 -0
- package/lib/daemon-project-access.js +11 -0
- package/lib/daemon-project-lifecycle-callbacks.js +15 -0
- package/lib/daemon-project-lifecycle.js +262 -0
- package/lib/daemon-projects.js +1 -1
- package/lib/daemon.js +78 -276
- package/lib/default-ai-runtime.js +4 -8
- package/lib/dm-digest-cursor.js +120 -0
- package/lib/email-mcp-server.js +1 -1
- package/lib/github-star-count.js +147 -0
- package/lib/issues-service.js +29 -15
- package/lib/kiro-defaults.js +1 -22
- package/lib/knowledge-db-import-validation.js +46 -0
- package/lib/knowledge-db-import.js +99 -0
- package/lib/knowledge-db-service.js +24 -33
- package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
- package/lib/knowledge-db-storage-nedb.js +66 -0
- package/lib/knowledge-db-storage.js +72 -0
- package/lib/knowledge-db-validation.js +0 -0
- package/lib/knowledge-document-index.js +2 -1
- package/lib/knowledge-file-store.js +7 -1
- package/lib/knowledge-product-operations.js +46 -0
- package/lib/mate-avatar-catalog.js +12 -0
- package/lib/mate-avatar-migration.js +41 -0
- package/lib/mate-context-service.js +138 -0
- package/lib/mate-context-tools.js +21 -0
- package/lib/mate-creation-mcp-server.js +2 -0
- package/lib/mate-knowledge-canonical-access.js +10 -0
- package/lib/mate-knowledge-mate-bound.js +53 -0
- package/lib/mate-knowledge-mcp-server.js +55 -8
- package/lib/mate-knowledge-service.js +16 -34
- package/lib/mate-knowledge-text-tools.js +106 -0
- package/lib/mate-lifecycle-service.js +94 -0
- package/lib/mate-message-delivery.js +43 -0
- package/lib/mate-ready-creation.js +9 -1
- package/lib/mate-schedule-input.js +29 -0
- package/lib/mate-schedule-lifecycle.js +151 -0
- package/lib/mate-scheduling.js +103 -0
- package/lib/mates.js +18 -6
- package/lib/mcp-agent-tools.js +117 -0
- package/lib/mcp-connection-store.js +119 -15
- package/lib/mcp-import-credentials.js +31 -0
- package/lib/mcp-local-transport.js +13 -0
- package/lib/mcp-oauth.js +8 -6
- package/lib/mcp-proxy.js +2 -32
- package/lib/mcp-query-bridge.js +30 -0
- package/lib/mcp-remote-connections.js +74 -20
- package/lib/mcp-source-adapters.js +1 -0
- package/lib/mcp-source-context.js +1 -0
- package/lib/mcp-source-discovery.js +1 -0
- package/lib/mcp-source-plugins.js +1 -0
- package/lib/mcp-source-restrictions.js +1 -0
- package/lib/mcp-tool-policy.js +9 -0
- package/lib/notes-checklist.js +92 -0
- package/lib/notes.js +51 -4
- package/lib/os-user-diagnostics.js +2 -4
- package/lib/os-users.js +24 -70
- package/lib/pane-pending-interactions.js +20 -0
- package/lib/pane-session-activation.js +114 -0
- package/lib/pane-session-transport.js +26 -0
- package/lib/project-admin-overview.js +51 -0
- package/lib/project-ask-user.js +8 -4
- package/lib/project-connection.js +14 -10
- package/lib/project-control-git-view.js +12 -0
- package/lib/project-debate.js +1 -0
- package/lib/project-delegated-follow-up.js +2 -1
- package/lib/project-directory-claim.js +65 -0
- package/lib/project-file-operations.js +61 -0
- package/lib/project-filesystem.js +15 -85
- package/lib/project-full-access.js +23 -2
- package/lib/project-http.js +7 -4
- package/lib/project-knowledge.js +32 -18
- package/lib/project-lifecycle-operations.js +98 -0
- package/lib/project-lifecycle-process-witness.js +32 -0
- package/lib/project-lifecycle-runtime.js +50 -0
- package/lib/project-linux-access.js +22 -0
- package/lib/project-logs-canonical-clay.js +27 -0
- package/lib/project-logs-clay-query.js +16 -0
- package/lib/project-logs-schema.js +4 -2
- package/lib/project-logs-service.js +8 -7
- package/lib/project-logs.js +1 -0
- package/lib/project-loop.js +1 -0
- package/lib/project-mate-chat-control.js +55 -0
- package/lib/project-mate-creation-proposal.js +18 -3
- package/lib/project-mate-interaction.js +40 -62
- package/lib/project-mcp.js +54 -16
- package/lib/project-models.js +14 -31
- package/lib/project-notifications.js +76 -17
- package/lib/project-ownership.js +77 -0
- package/lib/project-pair-result-delivery.js +14 -3
- package/lib/project-pair-usage.js +12 -13
- package/lib/project-pending-message-queue.js +4 -1
- package/lib/project-product-control.js +89 -0
- package/lib/project-product-session-queue.js +46 -0
- package/lib/project-push-access.js +28 -0
- package/lib/project-scheduled-message-queue.js +30 -0
- package/lib/project-scheduled-messages.js +67 -68
- package/lib/project-scheduled-task-control.js +83 -0
- package/lib/project-scheduled-tasks.js +13 -2
- package/lib/project-scheduling-access.js +10 -0
- package/lib/project-session-actions.js +65 -0
- package/lib/project-session-delete.js +8 -1
- package/lib/project-session-document.js +27 -7
- package/lib/project-session-github.js +63 -19
- package/lib/project-session-history-actions.js +167 -0
- package/lib/project-session-linear.js +14 -6
- package/lib/project-session-notes.js +40 -11
- package/lib/project-session-pair.js +1 -1
- package/lib/project-session-runtime-actions.js +64 -0
- package/lib/project-session-spawn.js +2 -3
- package/lib/project-session-vendor.js +55 -0
- package/lib/project-sessions.js +160 -290
- package/lib/project-shared-browser.js +78 -17
- package/lib/project-start-protocol.js +29 -0
- package/lib/project-studio-presentation.js +58 -0
- package/lib/project-user-message.js +67 -1
- package/lib/project-vendor-login.js +8 -36
- package/lib/project-workspace-operations.js +126 -0
- package/lib/project-workspace-query.js +19 -2
- package/lib/project.js +181 -45
- package/lib/public/app.js +71 -17
- package/lib/public/appearance-bootstrap.js +16 -0
- package/lib/public/css/clay-tool-activity.css +51 -0
- package/lib/public/css/clay-workspace.css +29 -0
- package/lib/public/css/command-palette.css +12 -33
- package/lib/public/css/contextual-clay.css +240 -0
- package/lib/public/css/filebrowser.css +1 -1
- package/lib/public/css/home-debate-planning.css +2 -0
- package/lib/public/css/home-mate-creation.css +5 -0
- package/lib/public/css/input.css +6 -0
- package/lib/public/css/mate-avatar-gallery.css +12 -0
- package/lib/public/css/mate-conversation.css +10 -5
- package/lib/public/css/mate-loading-scene.css +21 -0
- package/lib/public/css/messages.css +6 -2
- package/lib/public/css/overlays.css +68 -258
- package/lib/public/css/project-admin-overview.css +13 -0
- package/lib/public/css/project-mate-creation.css +5 -6
- package/lib/public/css/project-start.css +108 -0
- package/lib/public/css/projects-hub.css +53 -14
- package/lib/public/css/session-folders.css +11 -0
- package/lib/public/css/session-github.css +46 -1
- package/lib/public/css/settings-shell.css +103 -0
- package/lib/public/css/shared-browser.css +35 -1
- package/lib/public/css/sidebar.css +7 -0
- package/lib/public/css/sticky-notes.css +87 -1
- package/lib/public/css/title-bar.css +79 -0
- package/lib/public/index.html +61 -68
- package/lib/public/mate-avatars/B01.png +0 -0
- package/lib/public/mate-avatars/B02.png +0 -0
- package/lib/public/mate-avatars/B03.png +0 -0
- package/lib/public/mate-avatars/B04.png +0 -0
- package/lib/public/mate-avatars/B05.png +0 -0
- package/lib/public/mate-avatars/B06.png +0 -0
- package/lib/public/mate-avatars/B07.png +0 -0
- package/lib/public/mate-avatars/B08.png +0 -0
- package/lib/public/mate-avatars/B09.png +0 -0
- package/lib/public/mate-avatars/B10.png +0 -0
- package/lib/public/mate-avatars/B11.png +0 -0
- package/lib/public/mate-avatars/B12.png +0 -0
- package/lib/public/mate-avatars/B13.png +0 -0
- package/lib/public/mate-avatars/B14.png +0 -0
- package/lib/public/mate-avatars/B15.png +0 -0
- package/lib/public/mate-avatars/B16.png +0 -0
- package/lib/public/mate-avatars/B17.png +0 -0
- package/lib/public/mate-avatars/B18.png +0 -0
- package/lib/public/mate-avatars/B19.png +0 -0
- package/lib/public/mate-avatars/B20.png +0 -0
- package/lib/public/mate-avatars/B21.png +0 -0
- package/lib/public/mate-avatars/B22.png +0 -0
- package/lib/public/mate-avatars/B23.png +0 -0
- package/lib/public/mate-avatars/B24.png +0 -0
- package/lib/public/mate-avatars/B25.png +0 -0
- package/lib/public/mate-avatars/B26.png +0 -0
- package/lib/public/mate-avatars/B27.png +0 -0
- package/lib/public/mate-avatars/B28.png +0 -0
- package/lib/public/mate-avatars/B29.png +0 -0
- package/lib/public/mate-avatars/B30.png +0 -0
- package/lib/public/mate-avatars/B31.png +0 -0
- package/lib/public/mate-avatars/B32.png +0 -0
- package/lib/public/mate-avatars/B33.png +0 -0
- package/lib/public/mate-avatars/B34.png +0 -0
- package/lib/public/mate-avatars/B35.png +0 -0
- package/lib/public/mate-avatars/B36.png +0 -0
- package/lib/public/mate-avatars/B37.png +0 -0
- package/lib/public/mate-avatars/B38.png +0 -0
- package/lib/public/mate-avatars/B39.png +0 -0
- package/lib/public/mate-avatars/B40.png +0 -0
- package/lib/public/mate-avatars/B41.png +0 -0
- package/lib/public/mate-avatars/B42.png +0 -0
- package/lib/public/mate-avatars/B43.png +0 -0
- package/lib/public/mate-avatars/B44.png +0 -0
- package/lib/public/mate-avatars/B45.png +0 -0
- package/lib/public/mate-avatars/B46.png +0 -0
- package/lib/public/mate-avatars/B47.png +0 -0
- package/lib/public/mate-avatars/B48.png +0 -0
- package/lib/public/mate-avatars/C01.png +0 -0
- package/lib/public/mate-avatars/C02.png +0 -0
- package/lib/public/mate-avatars/C03.png +0 -0
- package/lib/public/mate-avatars/C04.png +0 -0
- package/lib/public/mate-avatars/C05.png +0 -0
- package/lib/public/mate-avatars/C06.png +0 -0
- package/lib/public/mate-avatars/C07.png +0 -0
- package/lib/public/mate-avatars/C08.png +0 -0
- package/lib/public/mate-avatars/C09.png +0 -0
- package/lib/public/mate-avatars/C10.png +0 -0
- package/lib/public/mate-avatars/C11.png +0 -0
- package/lib/public/mate-avatars/C12.png +0 -0
- package/lib/public/mate-avatars/C13.png +0 -0
- package/lib/public/mate-avatars/C14.png +0 -0
- package/lib/public/mate-avatars/C15.png +0 -0
- package/lib/public/mate-avatars/C16.png +0 -0
- package/lib/public/mate-avatars/C17.png +0 -0
- package/lib/public/mate-avatars/C18.png +0 -0
- package/lib/public/mate-avatars/C19.png +0 -0
- package/lib/public/mate-avatars/C20.png +0 -0
- package/lib/public/mate-avatars/C21.png +0 -0
- package/lib/public/mate-avatars/C22.png +0 -0
- package/lib/public/mate-avatars/C23.png +0 -0
- package/lib/public/mate-avatars/C24.png +0 -0
- package/lib/public/mate-avatars/C25.png +0 -0
- package/lib/public/mate-avatars/C26.png +0 -0
- package/lib/public/mate-avatars/C27.png +0 -0
- package/lib/public/mate-avatars/C28.png +0 -0
- package/lib/public/mate-avatars/C29.png +0 -0
- package/lib/public/mate-avatars/C30.png +0 -0
- package/lib/public/mate-avatars/C31.png +0 -0
- package/lib/public/mate-avatars/C32.png +0 -0
- package/lib/public/mate-avatars/C33.png +0 -0
- package/lib/public/mate-avatars/C34.png +0 -0
- package/lib/public/mate-avatars/C35.png +0 -0
- package/lib/public/mate-avatars/C36.png +0 -0
- package/lib/public/mate-avatars/C37.png +0 -0
- package/lib/public/mate-avatars/C38.png +0 -0
- package/lib/public/mate-avatars/C39.png +0 -0
- package/lib/public/mate-avatars/C40.png +0 -0
- package/lib/public/mate-avatars/C41.png +0 -0
- package/lib/public/mate-avatars/C42.png +0 -0
- package/lib/public/mate-avatars/C43.png +0 -0
- package/lib/public/mate-avatars/C44.png +0 -0
- package/lib/public/mate-avatars/C45.png +0 -0
- package/lib/public/mate-avatars/C46.png +0 -0
- package/lib/public/mate-avatars/C47.png +0 -0
- package/lib/public/mate-avatars/C48.png +0 -0
- package/lib/public/mate-avatars/catalog.json +482 -0
- package/lib/public/mate-avatars/lead-clay.png +0 -0
- package/lib/public/modules/admin-settings-invitations.js +2 -2
- package/lib/public/modules/admin-settings-projects.js +8 -4
- package/lib/public/modules/admin-settings-ui.js +20 -4
- package/lib/public/modules/admin-settings-users.js +4 -4
- package/lib/public/modules/app-connection.js +11 -1
- package/lib/public/modules/app-favicon.js +18 -9
- package/lib/public/modules/app-header.js +7 -4
- package/lib/public/modules/app-home-hub.js +2 -1
- package/lib/public/modules/app-loop-ui.js +2 -0
- package/lib/public/modules/app-message-router.js +22 -1
- package/lib/public/modules/app-messages.js +125 -19
- package/lib/public/modules/app-misc.js +3 -1
- package/lib/public/modules/app-notifications.js +11 -5
- package/lib/public/modules/app-panels.js +61 -123
- package/lib/public/modules/app-projects.js +14 -407
- package/lib/public/modules/app-rate-limit.js +19 -28
- package/lib/public/modules/app-rendering.js +4 -3
- package/lib/public/modules/avatar.js +15 -41
- package/lib/public/modules/chat-render-runtime.js +20 -0
- package/lib/public/modules/clay-browser-links.js +47 -0
- package/lib/public/modules/clay-control-activity.js +214 -0
- package/lib/public/modules/clay-control-copy.js +36 -0
- package/lib/public/modules/clay-control-detail-targets.js +44 -0
- package/lib/public/modules/clay-control-object-targets.js +52 -0
- package/lib/public/modules/clay-control-target-visibility.js +12 -0
- package/lib/public/modules/clay-control-targets.js +44 -0
- package/lib/public/modules/clay-log-links.js +23 -0
- package/lib/public/modules/clay-navigation-render.js +52 -0
- package/lib/public/modules/clay-owner-navigation.js +33 -0
- package/lib/public/modules/clay-session-links.js +31 -0
- package/lib/public/modules/clay-studio-bridge.js +20 -0
- package/lib/public/modules/clay-studio-document.js +67 -0
- package/lib/public/modules/clay-studio-render.js +146 -0
- package/lib/public/modules/clay-tool-activity.js +140 -0
- package/lib/public/modules/clay-tool-presentation.js +343 -0
- package/lib/public/modules/command-palette.js +162 -40
- package/lib/public/modules/contextual-ask-session.js +26 -0
- package/lib/public/modules/contextual-clay-geometry.js +155 -0
- package/lib/public/modules/contextual-clay-session.js +130 -0
- package/lib/public/modules/contextual-clay-workspace.js +169 -0
- package/lib/public/modules/contextual-clay.js +252 -0
- package/lib/public/modules/contextual-composer.js +91 -0
- package/lib/public/modules/contextual-mate-context.js +117 -0
- package/lib/public/modules/contextual-mate-hint.js +40 -0
- package/lib/public/modules/contextual-mate-identity.js +23 -0
- package/lib/public/modules/contextual-mate-sessions.js +134 -0
- package/lib/public/modules/contextual-search.js +137 -0
- package/lib/public/modules/contextual-session-citations.js +58 -0
- package/lib/public/modules/debate.js +1 -0
- package/lib/public/modules/default-ai.js +11 -3
- package/lib/public/modules/elicitation-form.js +5 -0
- package/lib/public/modules/filebrowser.js +20 -1
- package/lib/public/modules/generation-stop.js +8 -5
- package/lib/public/modules/git-panel.js +3 -1
- package/lib/public/modules/github-star.js +66 -0
- package/lib/public/modules/history-replay-batch.js +13 -1
- package/lib/public/modules/home-debate-live.js +2 -0
- package/lib/public/modules/home-debate-planning.js +7 -7
- package/lib/public/modules/home-mate-avatar-editor.js +127 -208
- package/lib/public/modules/home-mate-chat.js +8 -6
- package/lib/public/modules/home-mate-creation.js +73 -1
- package/lib/public/modules/home-mate-settings.js +19 -12
- package/lib/public/modules/icon-strip-tooltip.js +2 -1
- package/lib/public/modules/input.js +88 -10
- package/lib/public/modules/issues-render.js +3 -2
- package/lib/public/modules/knowledge-db-workbench.js +4 -4
- package/lib/public/modules/markdown.js +6 -34
- package/lib/public/modules/mate-avatar-catalog.js +97 -0
- package/lib/public/modules/mate-knowledge-workbench.js +1 -1
- package/lib/public/modules/mate-loading-scene.js +17 -0
- package/lib/public/modules/mate-management.js +40 -7
- package/lib/public/modules/mcp-connection-view.js +31 -13
- package/lib/public/modules/mcp-discovery-view.js +31 -0
- package/lib/public/modules/mcp-ui.js +23 -4
- package/lib/public/modules/mention.js +3 -0
- package/lib/public/modules/message-delivery.js +20 -2
- package/lib/public/modules/model-picker.js +2 -0
- package/lib/public/modules/pane-activation.js +214 -0
- package/lib/public/modules/pane-binding.js +82 -0
- package/lib/public/modules/pane-bridge.js +7 -4
- package/lib/public/modules/pane-browser-bridge.js +22 -0
- package/lib/public/modules/pane-file-bridge.js +4 -0
- package/lib/public/modules/pane-issue-bridge.js +4 -1
- package/lib/public/modules/pending-message-queue.js +1 -0
- package/lib/public/modules/permission-control.js +5 -4
- package/lib/public/modules/personal-settings-dialog.js +7 -1
- package/lib/public/modules/product-review.js +26 -0
- package/lib/public/modules/profile.js +12 -241
- package/lib/public/modules/project-access-recovery.js +17 -0
- package/lib/public/modules/project-admin-overview.js +21 -0
- package/lib/public/modules/project-chat-identity.js +13 -4
- package/lib/public/modules/project-logs-render.js +3 -0
- package/lib/public/modules/project-mate-creation-workspace.js +13 -4
- package/lib/public/modules/project-mate-navigation.js +144 -22
- package/lib/public/modules/project-session-visibility-settings.js +19 -16
- package/lib/public/modules/project-settings.js +119 -129
- package/lib/public/modules/project-start-dialog.js +130 -0
- package/lib/public/modules/project-start-folder-state.js +78 -0
- package/lib/public/modules/project-start-folder-view.js +190 -0
- package/lib/public/modules/project-start-forms.js +66 -0
- package/lib/public/modules/project-start-path.js +60 -0
- package/lib/public/modules/project-start-state.js +54 -0
- package/lib/public/modules/project-start-submit.js +67 -0
- package/lib/public/modules/projects-hub-view.js +33 -14
- package/lib/public/modules/projects-hub.js +10 -6
- package/lib/public/modules/rewind.js +5 -0
- package/lib/public/modules/scheduled-tasks.js +2 -0
- package/lib/public/modules/scheduler.js +2 -0
- package/lib/public/modules/search-clay-chat.js +5 -440
- package/lib/public/modules/server-settings.js +36 -91
- package/lib/public/modules/session-actions.js +5 -2
- package/lib/public/modules/session-context-menu.js +5 -0
- package/lib/public/modules/session-create-form.js +10 -10
- package/lib/public/modules/session-folder-layout.js +1 -1
- package/lib/public/modules/session-folder-view-menu.js +9 -0
- package/lib/public/modules/session-github.js +85 -14
- package/lib/public/modules/session-rich-drafts.js +21 -0
- package/lib/public/modules/session-switch-defer.js +67 -0
- package/lib/public/modules/session-work-primary.js +51 -0
- package/lib/public/modules/settings-defaults.js +27 -28
- package/lib/public/modules/settings-project-target.js +56 -0
- package/lib/public/modules/settings-select.js +1 -1
- package/lib/public/modules/settings-shell-registry.js +88 -0
- package/lib/public/modules/settings-shell-view.js +104 -0
- package/lib/public/modules/settings-shell.js +342 -0
- package/lib/public/modules/shared-browser-settings.js +112 -0
- package/lib/public/modules/shared-browser-tabs.js +13 -3
- package/lib/public/modules/shared-browser.js +29 -6
- package/lib/public/modules/sidebar-mobile.js +12 -33
- package/lib/public/modules/sidebar-projects.js +3 -1
- package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
- package/lib/public/modules/sidebar-sessions.js +1 -0
- package/lib/public/modules/split-group-restore.js +68 -0
- package/lib/public/modules/split-pair-ui.js +1 -0
- package/lib/public/modules/split-pane-reconciler.js +15 -0
- package/lib/public/modules/split-pane-renderer.js +87 -6
- package/lib/public/modules/split-session-boundary.js +1 -1
- package/lib/public/modules/split-view.js +60 -68
- package/lib/public/modules/sticky-note-markdown.js +72 -6
- package/lib/public/modules/sticky-notes-actions.js +30 -0
- package/lib/public/modules/sticky-notes-browser.js +9 -2
- package/lib/public/modules/sticky-notes-card.js +23 -7
- package/lib/public/modules/sticky-notes-checklist.js +116 -0
- package/lib/public/modules/sticky-notes-editor.js +108 -44
- package/lib/public/modules/sticky-notes-shared.js +50 -2
- package/lib/public/modules/sticky-notes-state.js +66 -0
- package/lib/public/modules/sticky-notes.js +34 -51
- package/lib/public/modules/stt-controller.js +4 -1
- package/lib/public/modules/stt-recording.js +1 -1
- package/lib/public/modules/stt.js +7 -2
- package/lib/public/modules/terminal.js +9 -0
- package/lib/public/modules/theme.js +18 -3
- package/lib/public/modules/thinking-lifecycle.js +33 -3
- package/lib/public/modules/thinking-view.js +23 -1
- package/lib/public/modules/tools.js +60 -11
- package/lib/public/modules/tui-grab.js +1 -2
- package/lib/public/modules/user-settings-appearance.js +10 -3
- package/lib/public/modules/user-settings-editors.js +1 -1
- package/lib/public/modules/user-settings-layout.js +14 -30
- package/lib/public/modules/user-settings-preferences.js +6 -2
- package/lib/public/modules/user-settings-profile.js +13 -3
- package/lib/public/modules/user-settings.js +18 -84
- package/lib/public/modules/vendor-login-browser.js +5 -3
- package/lib/public/modules/vendor-login.js +2 -2
- package/lib/public/modules/vendor-priority.js +15 -1
- package/lib/public/modules/vendor-usage-format.js +93 -0
- package/lib/public/modules/vendor-usage-list.js +45 -0
- package/lib/public/modules/vendor-usage-model.js +215 -0
- package/lib/public/modules/vendor-usage-overview.js +312 -0
- package/lib/public/modules/wireframe-workbench.js +5 -2
- package/lib/public/muse-avatar.svg +4 -0
- package/lib/public/style.css +14 -6
- package/lib/public/sw.js +3 -1
- package/lib/public/welcome-art/conversation-desk.png +0 -0
- package/lib/public/welcome-art/mate-clay.png +0 -0
- package/lib/public/welcome-art/project-clay.png +0 -0
- package/lib/safe-bash-commands.js +3 -45
- package/lib/scheduled-task-records.js +3 -1
- package/lib/scheduler.js +2 -0
- package/lib/sdk-bridge.js +348 -402
- package/lib/sdk-foreground-admission.js +16 -0
- package/lib/sdk-mcp-descriptors.js +2 -37
- package/lib/sdk-message-processor.js +61 -18
- package/lib/sdk-quota-snapshot.js +21 -3
- package/lib/sdk-response-recovery.js +1 -0
- package/lib/sdk-worker.js +2 -677
- package/lib/server-admin.js +63 -16
- package/lib/server-appearance-settings.js +13 -1
- package/lib/server-contextual-clay-settings.js +40 -0
- package/lib/server-contextual-mate-sessions.js +70 -0
- package/lib/server-dm.js +2 -1
- package/lib/server-github-stars.js +39 -0
- package/lib/server-global-ws.js +26 -32
- package/lib/server-home-chat-events.js +18 -4
- package/lib/server-home-chat.js +22 -20
- package/lib/server-home-clay-entry.js +23 -4
- package/lib/server-home-clay-session-links.js +29 -9
- package/lib/server-home-mate-creation.js +1 -0
- package/lib/server-home-mcp-consent.js +14 -0
- package/lib/server-mates.js +25 -62
- package/lib/server-owner-ui.js +118 -0
- package/lib/server-path-access.js +38 -0
- package/lib/server-project-removal.js +22 -0
- package/lib/server-settings.js +6 -1
- package/lib/server.js +167 -43
- package/lib/session-config-transition.js +45 -0
- package/lib/session-folders.js +7 -2
- package/lib/session-fork-history.js +21 -0
- package/lib/session-github.js +9 -2
- package/lib/session-hygiene.js +3 -35
- package/lib/session-notes-mcp-server.js +26 -4
- package/lib/session-notes-writes.js +88 -0
- package/lib/session-permission-mode.js +4 -3
- package/lib/session-skill-scope.js +11 -0
- package/lib/session-visibility.js +25 -10
- package/lib/session-work-primary.js +50 -0
- package/lib/sessions.js +66 -99
- package/lib/shared-browser-cookie-sync.js +32 -0
- package/lib/shared-browser-cookies.js +79 -0
- package/lib/shared-browser-runtime.js +25 -9
- package/lib/shared-browser-storage-sync.js +43 -0
- package/lib/shared-browser-storage.js +101 -0
- package/lib/shared-browser-tools.js +2 -1
- package/lib/shared-browser-worker.js +46 -10
- package/lib/terminal-manager.js +65 -6
- package/lib/tool-llm.js +1 -1
- package/lib/tui-transcript-index.js +1 -132
- package/lib/users-contextual-clay-preferences.js +31 -0
- package/lib/users-permissions.js +2 -8
- package/lib/users.js +7 -0
- package/lib/vendor-login-browser.js +1 -11
- package/lib/vendor-usage-acp-readers.js +97 -0
- package/lib/vendor-usage-capabilities.js +88 -0
- package/lib/vendor-usage-http-readers.js +214 -0
- package/lib/vendor-usage-metrics.js +47 -0
- package/lib/vendor-usage-native-readers.js +106 -0
- package/lib/vendor-usage-overview.js +406 -0
- package/lib/vendor-usage-service.js +281 -0
- package/lib/workspace-assignment-service.js +25 -0
- package/lib/workspace-query-access.js +4 -1
- package/lib/workspace-query-mcp-server.js +1 -1
- package/lib/workspace-query-service.js +13 -2
- package/lib/ws-request.js +1 -0
- package/lib/ws-schema.js +22 -4
- package/lib/yoke/acp-agent-profiles.js +7 -5
- package/lib/yoke/adapters/antigravity.js +3 -14
- package/lib/yoke/adapters/claude-query-contract.js +9 -0
- package/lib/yoke/adapters/claude.js +66 -50
- package/lib/yoke/adapters/codex-query-contract.js +25 -0
- package/lib/yoke/adapters/codex.js +98 -123
- package/lib/yoke/adapters/kiro.js +3 -1
- package/lib/yoke/adapters/muse-query-contract.js +7 -0
- package/lib/yoke/adapters/muse.js +122 -0
- package/lib/yoke/auth-events.js +17 -0
- package/lib/yoke/claude-hook-installer.js +272 -0
- package/lib/yoke/claude-jsonl-watcher.js +204 -0
- package/lib/yoke/claude-maintenance.js +55 -0
- package/lib/yoke/claude-permission-patterns.js +53 -0
- package/lib/yoke/claude-response-recovery.js +155 -0
- package/lib/yoke/claude-transcript-hygiene.js +34 -0
- package/lib/yoke/claude-worker-startup.js +28 -0
- package/lib/yoke/clay-skill-install.js +33 -0
- package/lib/yoke/cli-sessions.js +300 -0
- package/lib/yoke/codex-app-server.js +7 -12
- package/lib/yoke/codex-dynamic-tool-names.js +80 -0
- package/lib/yoke/codex-idle-recovery.js +81 -1
- package/lib/yoke/codex-model-catalog.js +37 -3
- package/lib/yoke/codex-recovery-admission.js +164 -0
- package/lib/yoke/configuration.js +13 -0
- package/lib/yoke/discovery.js +70 -0
- package/lib/yoke/errors.js +8 -0
- package/lib/yoke/host-environment.js +7 -0
- package/lib/yoke/index.js +9 -51
- package/lib/yoke/interface.js +116 -0
- package/lib/yoke/kiro-acp-server.js +5 -5
- package/lib/yoke/legacy-sessions.js +89 -0
- package/lib/yoke/login-protocol.js +25 -0
- package/lib/yoke/maintenance.js +12 -0
- package/lib/yoke/mcp-proxy.js +32 -0
- package/lib/yoke/mcp-source-adapters.js +91 -0
- package/lib/yoke/mcp-source-context.js +42 -0
- package/lib/yoke/mcp-source-discovery.js +169 -0
- package/lib/yoke/mcp-source-plugins.js +68 -0
- package/lib/yoke/mcp-source-restrictions.js +47 -0
- package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
- package/lib/yoke/model-preferences.js +6 -0
- package/lib/yoke/muse-artifacts.js +36 -0
- package/lib/yoke/muse-controls.js +50 -0
- package/lib/yoke/muse-input.js +64 -0
- package/lib/yoke/muse-items.js +157 -0
- package/lib/yoke/muse-policy.js +52 -0
- package/lib/yoke/muse-query.js +428 -0
- package/lib/yoke/muse-runtime.js +211 -0
- package/lib/yoke/muse-services.js +92 -0
- package/lib/yoke/muse-skills.js +79 -0
- package/lib/yoke/muse-turns.js +71 -0
- package/lib/yoke/options/acp.js +2 -0
- package/lib/yoke/options/antigravity.js +2 -0
- package/lib/yoke/options/claude.js +21 -0
- package/lib/yoke/options/codex-defaults.js +29 -0
- package/lib/yoke/options/codex-settings.js +21 -0
- package/lib/yoke/options/codex.js +6 -0
- package/lib/yoke/options/kiro-defaults.js +22 -0
- package/lib/yoke/options/kiro.js +5 -0
- package/lib/yoke/options/muse.js +5 -0
- package/lib/yoke/provider-contract.js +5 -0
- package/lib/yoke/providers/antigravity-executable.js +8 -0
- package/lib/yoke/providers/claude-executable.js +40 -0
- package/lib/yoke/providers/claude-model-descriptions.js +34 -0
- package/lib/yoke/providers/claude-process.js +97 -0
- package/lib/yoke/providers/claude-provision.js +75 -0
- package/lib/yoke/providers/codex-errors.js +8 -0
- package/lib/yoke/providers/muse-executable.js +17 -0
- package/lib/yoke/provisioning.js +6 -0
- package/lib/yoke/query-options.js +10 -0
- package/lib/yoke/response-recovery.js +41 -0
- package/lib/yoke/sdk-mcp-descriptors.js +37 -0
- package/lib/yoke/sdk-server-factory.js +7 -0
- package/lib/yoke/session-history.js +8 -0
- package/lib/yoke/session-tool-transport.js +34 -13
- package/lib/yoke/settings.js +23 -0
- package/lib/yoke/source-locations.js +4 -0
- package/lib/yoke/title-query.js +18 -7
- package/lib/yoke/tui-transcript-index.js +132 -0
- package/lib/yoke/usage.js +48 -0
- package/lib/yoke/user-input.js +13 -0
- package/lib/yoke/vendor-registry.js +87 -3
- package/package.json +11 -4
- package/lib/public/modules/server-settings-navigation.js +0 -39
|
@@ -1,76 +1,64 @@
|
|
|
1
1
|
import { store } from './store.js';
|
|
2
2
|
import { getWs } from './ws-ref.js';
|
|
3
|
-
import { trapSettingsFocus, isolateSettingsDialog, confirmSettingsAction } from './server-settings-state.js';
|
|
4
3
|
import { initProjectEnvironment, openProjectEnvironment, projectEnvironmentDirty, discardProjectEnvironment } from './project-settings-environment.js';
|
|
5
4
|
import { enhanceSettingsSelects } from './settings-select.js';
|
|
6
|
-
// Project identity and
|
|
5
|
+
// Project identity, access and environment: the Project pane of the unified
|
|
6
|
+
// settings shell. The shell owns the selected target; this pane only renders
|
|
7
|
+
// and edits the project it was last bound to.
|
|
7
8
|
import { refreshIcons } from './icons.js';
|
|
8
9
|
import { showToast } from './utils.js';
|
|
9
10
|
import { parseEmojis } from './markdown.js';
|
|
10
|
-
import {
|
|
11
|
-
import { openNotesBrowser, closeNotesBrowser, isNotesBrowserOpen } from './sticky-notes-browser.js';
|
|
11
|
+
import { registerSettingsScope, openSettings, closeSettings, isSettingsShellOpen, activeSettingsScope } from './settings-shell.js';
|
|
12
12
|
import { initProjectSessionVisibilitySettings, populateProjectSessionVisibilitySettings } from './project-session-visibility-settings.js';
|
|
13
13
|
|
|
14
14
|
var panelEl = null;
|
|
15
|
-
var navItems = null;
|
|
16
15
|
var sections = null;
|
|
17
|
-
var notesBrowserReopen = false;
|
|
18
|
-
var restoreBackground = null;
|
|
19
|
-
var returnFocus = null;
|
|
20
16
|
function settingsSlug() { return store.get("projectSettingsSlug"); }
|
|
21
17
|
function settingsProject() { return store.get("projectSettingsProject"); }
|
|
22
18
|
|
|
23
19
|
// Emoji categories (reuse from sidebar)
|
|
24
20
|
var EMOJI_CATEGORIES = null;
|
|
25
21
|
|
|
22
|
+
function renameDirty() {
|
|
23
|
+
var rename = document.getElementById("ps-rename-form");
|
|
24
|
+
var project = settingsProject();
|
|
25
|
+
return !!(rename && project && !rename.classList.contains("hidden") && document.getElementById("ps-rename-input").value.trim() !== (project.name || ""));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function discardDrafts() {
|
|
29
|
+
discardProjectEnvironment();
|
|
30
|
+
cancelRename();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
var controller = {
|
|
34
|
+
enter: function () {},
|
|
35
|
+
activate: function (page) { switchSection(page); },
|
|
36
|
+
leave: function () { closePsEmojiPicker(); },
|
|
37
|
+
busy: function (kind) { return kind !== "page" && (store.get("projectEnvironmentEditor") || {}).saving ? "Wait for the environment save to finish." : ""; },
|
|
38
|
+
leavePrompt: function (kind) {
|
|
39
|
+
var env = projectEnvironmentDirty();
|
|
40
|
+
var rename = renameDirty();
|
|
41
|
+
if (!env && !rename) return null;
|
|
42
|
+
if (kind === "close") return { message: "Your changes have not been saved. Discard them and close?", action: "Discard changes", apply: discardDrafts };
|
|
43
|
+
if (kind === "page") return null;
|
|
44
|
+
if (kind === "project" && rename) return { message: "Your unsaved project name change will be discarded when you switch projects. An unsaved environment draft stays in this tab.", action: "Discard name and switch", apply: cancelRename };
|
|
45
|
+
return { message: "Your unsaved project changes will remain in this tab. Leave this editor and keep the draft?", action: "Keep draft and leave" };
|
|
46
|
+
},
|
|
47
|
+
retarget: bindProjectSettings,
|
|
48
|
+
refreshTarget: refreshProjectSettings,
|
|
49
|
+
clearTarget: clearProjectSettings,
|
|
50
|
+
setEmpty: setPaneEmpty
|
|
51
|
+
};
|
|
26
52
|
|
|
27
53
|
export function initProjectSettings(emojiCategories) {
|
|
28
54
|
EMOJI_CATEGORIES = emojiCategories;
|
|
29
55
|
panelEl = document.getElementById("project-settings");
|
|
30
56
|
if (!panelEl) return;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
var destinations = [{id: 'profile', label: 'General'}, {id: 'access', label: 'Access'}, {id: 'environment', label: 'Environment'}];
|
|
34
|
-
var nav = panelEl.querySelector('.server-settings-nav-items');
|
|
35
|
-
var dropdown = document.getElementById('ps-nav-dropdown');
|
|
36
|
-
destinations.forEach(function (page) {
|
|
37
|
-
var button = document.createElement('button');
|
|
38
|
-
button.className = 'settings-nav-item'; button.dataset.section = page.id; button.textContent = page.label;
|
|
39
|
-
nav.appendChild(button);
|
|
40
|
-
var option = document.createElement('option'); option.value = page.id; option.textContent = page.label; dropdown.appendChild(option);
|
|
41
|
-
});
|
|
57
|
+
controller.pane = panelEl;
|
|
58
|
+
registerSettingsScope("project", controller);
|
|
42
59
|
initProjectEnvironment();
|
|
43
|
-
panelEl.addEventListener('click', function (event) { if (event.target === panelEl) closeProjectSettings(); });
|
|
44
|
-
panelEl.addEventListener('keydown', function (event) {
|
|
45
|
-
if (event.key === 'Escape' && !event.defaultPrevented) { event.preventDefault(); event.stopPropagation(); closeProjectSettings(); }
|
|
46
|
-
trapSettingsFocus(event, panelEl);
|
|
47
|
-
});
|
|
48
|
-
navItems = panelEl.querySelectorAll(".settings-nav-item");
|
|
49
60
|
sections = panelEl.querySelectorAll(".ps-section");
|
|
50
61
|
|
|
51
|
-
// Nav clicks
|
|
52
|
-
for (var i = 0; i < navItems.length; i++) {
|
|
53
|
-
navItems[i].addEventListener("click", function () {
|
|
54
|
-
switchSection(this.dataset.section);
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Mobile dropdown nav
|
|
59
|
-
var psNavDropdown = document.getElementById("ps-nav-dropdown");
|
|
60
|
-
if (psNavDropdown) {
|
|
61
|
-
psNavDropdown.addEventListener("change", function () {
|
|
62
|
-
switchSection(psNavDropdown.value);
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Close button
|
|
67
|
-
var closeBtn = document.getElementById("project-settings-close");
|
|
68
|
-
if (closeBtn) {
|
|
69
|
-
closeBtn.addEventListener("click", function () {
|
|
70
|
-
closeProjectSettings();
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
62
|
// Profile: rename
|
|
75
63
|
var renameBtn = document.getElementById("ps-rename-btn");
|
|
76
64
|
var renameForm = document.getElementById("ps-rename-form");
|
|
@@ -111,98 +99,105 @@ export function initProjectSettings(emojiCategories) {
|
|
|
111
99
|
}
|
|
112
100
|
if (iconRemoveBtn) {
|
|
113
101
|
iconRemoveBtn.addEventListener("click", function () {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
updateIconPreview(null);
|
|
102
|
+
var slug = settingsSlug();
|
|
103
|
+
var previous = { icon: settingsProject() ? settingsProject().icon || null : null };
|
|
104
|
+
if (slug && sendEdit("set_project_icon", { slug: slug, icon: null }, previous)) updateIconPreview(null);
|
|
118
105
|
});
|
|
119
106
|
}
|
|
120
107
|
|
|
121
108
|
initProjectSessionVisibilitySettings();
|
|
122
|
-
store.subscribe(function (next, previous) { if (next.myUserId !== previous.myUserId) closeProjectSettings({ cleanup: true }); });
|
|
123
109
|
}
|
|
124
110
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
111
|
+
// Entry for the project context menu and mobile sheet: show this exact
|
|
112
|
+
// project's settings without changing the open workspace.
|
|
113
|
+
export function openProjectSettings(slug) {
|
|
114
|
+
return openSettings({ scope: "project", page: "profile", slug: slug });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Bind the pane to one project. Called by the shell for every target change.
|
|
118
|
+
function bindProjectSettings(slug, project) {
|
|
119
|
+
var same = settingsSlug() === slug;
|
|
120
|
+
store.set({ projectSettingsSlug: slug, projectSettingsProject: Object.assign({}, project, { name: project.title || project.project || project.name || slug }) });
|
|
130
121
|
var env = store.get("projectEnvironmentEditor");
|
|
131
122
|
if (env && !env.dirty && !env.saving) store.set({ projectEnvironmentEditor: Object.assign({}, env, { loaded: false, loading: false }) });
|
|
123
|
+
if (same) refreshProjectSettings(slug, project);
|
|
124
|
+
else { closePsEmojiPicker(); populateProfile(); }
|
|
125
|
+
var active = panelEl.querySelector(".ps-section.active");
|
|
126
|
+
if (active && active.dataset.section === "environment") openProjectEnvironment(slug);
|
|
127
|
+
}
|
|
132
128
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
129
|
+
function refreshProjectSettings(slug, project) {
|
|
130
|
+
if (settingsSlug() !== slug) return;
|
|
131
|
+
var name = project.title || project.project || project.name || slug;
|
|
132
|
+
store.set({ projectSettingsProject: Object.assign({}, project, { name: name }) });
|
|
133
|
+
var nameEl = document.getElementById("ps-project-name");
|
|
134
|
+
if (nameEl) nameEl.textContent = name || "-";
|
|
135
|
+
updateIconPreview(project.icon || null);
|
|
136
|
+
populateProjectSessionVisibilitySettings(slug, settingsProject());
|
|
137
|
+
document.getElementById('ps-project-path').textContent = project.path || (slug === store.get('currentSlug') ? store.get('cwd') : '') || 'Folder information unavailable';
|
|
138
|
+
}
|
|
142
139
|
|
|
140
|
+
// The selected project is gone or no longer authorised.
|
|
141
|
+
function clearProjectSettings(slug) {
|
|
142
|
+
var env = store.get("projectEnvironmentEditor") || {};
|
|
143
|
+
var drafts = Object.assign({}, store.get("projectEnvironmentDrafts") || {});
|
|
144
|
+
delete drafts[slug];
|
|
145
|
+
store.set({ projectSettingsSlug: null, projectSettingsProject: null, projectEnvironmentDrafts: drafts });
|
|
146
|
+
if (env.slug === slug) { store.set({ projectEnvironmentEditor: {} }); }
|
|
147
|
+
closePsEmojiPicker();
|
|
148
|
+
cancelRename();
|
|
149
|
+
}
|
|
143
150
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
var EMPTY_HEADINGS = { loading: "Loading projects", empty: "No project selected", error: "Projects unavailable", lost: "Project unavailable" };
|
|
152
|
+
function setPaneEmpty(text, kind) {
|
|
153
|
+
var empty = document.getElementById("ps-empty");
|
|
154
|
+
if (empty) {
|
|
155
|
+
empty.hidden = !text;
|
|
156
|
+
document.getElementById("ps-empty-text").textContent = text || "";
|
|
157
|
+
empty.querySelector("h2").textContent = EMPTY_HEADINGS[kind] || EMPTY_HEADINGS.empty;
|
|
149
158
|
}
|
|
159
|
+
panelEl.classList.toggle("ps-no-target", !!text);
|
|
160
|
+
}
|
|
150
161
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
162
|
+
// Rename and icon edits are bound to the exact project, request and (for the
|
|
163
|
+
// reply) the slug the server echoes; a reply for another project never
|
|
164
|
+
// changes the view.
|
|
165
|
+
var pendingEdits = {};
|
|
166
|
+
var editSequence = 0;
|
|
167
|
+
function sendEdit(type, fields, previous) {
|
|
168
|
+
var ws = getWs();
|
|
169
|
+
if (!ws || !store.get("connected")) return false;
|
|
170
|
+
editSequence += 1;
|
|
171
|
+
var requestId = "project-settings-" + Date.now() + "-" + editSequence;
|
|
172
|
+
pendingEdits[requestId] = { slug: fields.slug, type: type, previous: previous };
|
|
173
|
+
ws.send(JSON.stringify(Object.assign({ type: type, requestId: requestId }, fields)));
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function handleProjectSettingsEditResult(msg) {
|
|
178
|
+
var pending = msg && msg.requestId && pendingEdits[msg.requestId];
|
|
179
|
+
if (!pending) return;
|
|
180
|
+
delete pendingEdits[msg.requestId];
|
|
181
|
+
if (msg.slug !== pending.slug || msg.ok || settingsSlug() !== pending.slug) return;
|
|
182
|
+
if (pending.type === "set_project_title") updateProjectSettingsName(pending.previous.name);
|
|
183
|
+
else updateProjectSettingsIcon(pending.previous.icon);
|
|
157
184
|
}
|
|
158
185
|
|
|
159
|
-
// `cleanup` is for teardown while leaving the project: the notes workbench is
|
|
160
|
-
// not reopened over whatever screen comes next.
|
|
161
186
|
export function closeProjectSettings(opts) {
|
|
162
|
-
|
|
163
|
-
if (!(opts && opts.cleanup) && (store.get("projectEnvironmentEditor") || {}).saving) { showToast("Wait for the environment save to finish."); return; }
|
|
164
|
-
var rename = document.getElementById("ps-rename-form");
|
|
165
|
-
var renameDirty = rename && !rename.classList.contains("hidden") && document.getElementById("ps-rename-input").value.trim() !== (settingsProject().name || "");
|
|
166
|
-
if (!(opts && (opts.cleanup || opts.confirmed)) && (projectEnvironmentDirty() || renameDirty)) {
|
|
167
|
-
confirmSettingsAction('Your changes have not been saved. Discard them and close?', 'Discard changes', function () {
|
|
168
|
-
discardProjectEnvironment(); closeProjectSettings({ confirmed: true });
|
|
169
|
-
});
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
var wasOpen = !panelEl.classList.contains("hidden");
|
|
173
|
-
panelEl.classList.add("hidden");
|
|
174
|
-
closePsEmojiPicker();
|
|
175
|
-
if (restoreBackground) { restoreBackground(); restoreBackground = null; }
|
|
176
|
-
if (returnFocus && returnFocus.isConnected && !(opts && opts.cleanup)) returnFocus.focus();
|
|
177
|
-
if (wasOpen) {
|
|
178
|
-
releaseNotesForSettings();
|
|
179
|
-
if (notesBrowserReopen && !(opts && opts.cleanup)) openNotesBrowser();
|
|
180
|
-
notesBrowserReopen = false;
|
|
181
|
-
}
|
|
187
|
+
closeSettings({ cleanup: !!(opts && opts.cleanup), onlyScope: "project" });
|
|
182
188
|
}
|
|
183
189
|
|
|
184
190
|
export function isProjectSettingsOpen() {
|
|
185
|
-
return
|
|
191
|
+
return isSettingsShellOpen() && activeSettingsScope() === "project";
|
|
186
192
|
}
|
|
187
193
|
|
|
188
194
|
function switchSection(name) {
|
|
189
|
-
for (var i = 0; i < navItems.length; i++) {
|
|
190
|
-
var active = navItems[i].dataset.section === name;
|
|
191
|
-
navItems[i].classList.toggle("active", active);
|
|
192
|
-
navItems[i].setAttribute("aria-current", active ? "page" : "false");
|
|
193
|
-
}
|
|
194
195
|
for (var j = 0; j < sections.length; j++) {
|
|
195
|
-
|
|
196
|
-
sections[j].classList.toggle("active", active2);
|
|
196
|
+
sections[j].classList.toggle("active", sections[j].dataset.section === name);
|
|
197
197
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if (psNavDropdown && psNavDropdown.value !== name) {
|
|
202
|
-
psNavDropdown.value = name;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (name === "environment") openProjectEnvironment(settingsSlug());
|
|
198
|
+
if (name === "environment" && settingsSlug()) openProjectEnvironment(settingsSlug());
|
|
199
|
+
enhanceSettingsSelects(panelEl);
|
|
200
|
+
refreshIcons();
|
|
206
201
|
}
|
|
207
202
|
|
|
208
203
|
function populateProfile() {
|
|
@@ -229,15 +224,13 @@ function commitRename() {
|
|
|
229
224
|
var renameInput = document.getElementById("ps-rename-input");
|
|
230
225
|
var nameEl = document.getElementById("ps-project-name");
|
|
231
226
|
var newName = renameInput ? renameInput.value.trim() : "";
|
|
232
|
-
|
|
233
|
-
|
|
227
|
+
var slug = settingsSlug();
|
|
228
|
+
var previous = { name: settingsProject() ? settingsProject().name : "" };
|
|
229
|
+
if (newName && slug && sendEdit("set_project_title", { slug: slug, title: newName }, previous)) {
|
|
234
230
|
if (nameEl) nameEl.textContent = newName;
|
|
235
231
|
if (settingsProject()) settingsProject().name = newName;
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
if (newName && getWs() && store.get("connected")) cancelRename();
|
|
240
|
-
else showToast("Enter a name and connect to the server before saving.");
|
|
232
|
+
cancelRename();
|
|
233
|
+
} else showToast("Enter a name and connect to the server before saving.");
|
|
241
234
|
}
|
|
242
235
|
|
|
243
236
|
function cancelRename() {
|
|
@@ -330,10 +323,9 @@ function showPsEmojiPicker() {
|
|
|
330
323
|
btn.addEventListener("click", function (e) {
|
|
331
324
|
e.stopPropagation();
|
|
332
325
|
closePsEmojiPicker();
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
updateIconPreview(emoji);
|
|
326
|
+
var slug = settingsSlug();
|
|
327
|
+
var previous = { icon: settingsProject() ? settingsProject().icon || null : null };
|
|
328
|
+
if (slug && sendEdit("set_project_icon", { slug: slug, icon: emoji }, previous)) updateIconPreview(emoji);
|
|
337
329
|
});
|
|
338
330
|
grid.appendChild(btn);
|
|
339
331
|
})(emojis[i]);
|
|
@@ -365,8 +357,6 @@ export function updateProjectSettingsName(name) {
|
|
|
365
357
|
if (settingsProject()) settingsProject().name = name;
|
|
366
358
|
var nameEl = document.getElementById("ps-project-name");
|
|
367
359
|
if (nameEl) nameEl.textContent = name || "-";
|
|
368
|
-
var navTitle = document.getElementById("ps-nav-title");
|
|
369
|
-
if (navTitle) navTitle.textContent = name || "-";
|
|
370
360
|
}
|
|
371
361
|
|
|
372
362
|
export function handleProjectOwnerChanged(msg) {
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// project-start-dialog.js - One fixed-size dialog for choosing how to start a project
|
|
2
|
+
|
|
3
|
+
import { store } from './store.js';
|
|
4
|
+
import { iconHtml, refreshIcons } from './icons.js';
|
|
5
|
+
import { openState, closeState, selectView } from './project-start-state.js';
|
|
6
|
+
import { folderViewHtml, bindFolderView, renderFolderView, startFolderBrowse, resetFolderState, handleBrowseDirResult } from './project-start-folder-view.js';
|
|
7
|
+
import { formViewHtml, bindFormView, renderFormView } from './project-start-forms.js';
|
|
8
|
+
import { submitFolder, handleAddProjectResult, handleCloneProgress } from './project-start-submit.js';
|
|
9
|
+
|
|
10
|
+
export { handleBrowseDirResult, handleAddProjectResult, handleCloneProgress };
|
|
11
|
+
|
|
12
|
+
var TITLES = { choices: 'Start a project', open: 'Open a folder', create: 'Create a project', clone: 'Clone a repository' };
|
|
13
|
+
var CHOICES = [
|
|
14
|
+
{ view: 'open', icon: 'folder-open', title: 'Open an existing folder', text: 'Use a directory on the machine running Clay.' },
|
|
15
|
+
{ view: 'create', icon: 'plus', title: 'Create a new project', text: 'Start in a new, empty project directory.' },
|
|
16
|
+
{ view: 'clone', icon: 'git-branch', title: 'Clone a repository', text: 'Bring an existing Git repository into Clay.' },
|
|
17
|
+
];
|
|
18
|
+
var shownGen = -1;
|
|
19
|
+
var opener = null;
|
|
20
|
+
|
|
21
|
+
function modal() { return document.getElementById('project-start-modal'); }
|
|
22
|
+
function body() { return document.getElementById('project-start-body'); }
|
|
23
|
+
function current() { return store.get('projectStart'); }
|
|
24
|
+
|
|
25
|
+
function choicesHtml() {
|
|
26
|
+
var html = '<div class="project-start-view" data-view="choices"><div class="project-start-scroll"><ul class="project-start-rows project-start-choices" role="list">';
|
|
27
|
+
for (var i = 0; i < CHOICES.length; i++) {
|
|
28
|
+
var c = CHOICES[i];
|
|
29
|
+
html += '<li><button type="button" class="project-start-row project-start-choice" data-choice="' + c.view + '">' +
|
|
30
|
+
iconHtml(c.icon, 'project-start-choice-icon') + '<span class="project-start-choice-text"><strong>' + c.title + '</strong><span>' + c.text + '</span></span>' +
|
|
31
|
+
iconHtml('chevron-right') + '</button></li>';
|
|
32
|
+
}
|
|
33
|
+
return html + '</ul></div></div>';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function focusFirst(view) {
|
|
37
|
+
var target = null;
|
|
38
|
+
if (view === 'choices') target = body().querySelector('[data-choice]');
|
|
39
|
+
else if (view === 'open') target = body().querySelector('[data-ps="list"]');
|
|
40
|
+
else target = body().querySelector('[data-ps="field"]');
|
|
41
|
+
if (!target) target = modal().querySelector('.project-start-dialog');
|
|
42
|
+
target.focus({ preventScroll: true });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function renderShell(view) {
|
|
46
|
+
var container = body();
|
|
47
|
+
document.getElementById('project-start-title').textContent = TITLES[view];
|
|
48
|
+
document.getElementById('project-start-back').hidden = view === 'choices';
|
|
49
|
+
document.getElementById('project-start-subtitle').hidden = view !== 'choices';
|
|
50
|
+
if (view === 'choices') container.innerHTML = choicesHtml();
|
|
51
|
+
else if (view === 'open') { container.innerHTML = folderViewHtml(); bindFolderView(submitFolder); }
|
|
52
|
+
else { container.innerHTML = formViewHtml(view); bindFormView(view); }
|
|
53
|
+
refreshIcons();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function render(state, previous) {
|
|
57
|
+
var overlay = modal();
|
|
58
|
+
if (!overlay) return;
|
|
59
|
+
if (state.view === null) {
|
|
60
|
+
if (!overlay.classList.contains('hidden')) hide();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (state.gen !== shownGen || previous.view === null) {
|
|
64
|
+
shownGen = state.gen;
|
|
65
|
+
overlay.classList.remove('hidden');
|
|
66
|
+
renderShell(state.view);
|
|
67
|
+
if (state.view === 'open') { resetFolderState(); startFolderBrowse(); }
|
|
68
|
+
if (state.view === 'create' || state.view === 'clone') renderFormView(state.view);
|
|
69
|
+
focusFirst(state.view);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (state.view === 'open') renderFolderView();
|
|
73
|
+
else if (state.view === 'create' || state.view === 'clone') renderFormView(state.view);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function hide() {
|
|
77
|
+
modal().classList.add('hidden');
|
|
78
|
+
body().innerHTML = '';
|
|
79
|
+
shownGen = -1;
|
|
80
|
+
resetFolderState();
|
|
81
|
+
var target = opener;
|
|
82
|
+
opener = null;
|
|
83
|
+
if (target && document.contains(target) && typeof target.focus === 'function') target.focus({ preventScroll: true });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function openAddProjectModal(mode) {
|
|
87
|
+
if (current().view === null) opener = document.activeElement;
|
|
88
|
+
store.set({ projectStart: openState(current(), mode) });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function closeAddProjectModal() {
|
|
92
|
+
if (current().view === null) return;
|
|
93
|
+
store.set({ projectStart: closeState(current()) });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function trapTab(event, dialog) {
|
|
97
|
+
var items = dialog.querySelectorAll('button:not([disabled]):not([hidden]), input:not([disabled]):not([hidden]), [tabindex="-1"][data-ps="list"]');
|
|
98
|
+
var focusable = [];
|
|
99
|
+
for (var i = 0; i < items.length; i++) if (items[i].offsetParent !== null && items[i].tabIndex >= 0) focusable.push(items[i]);
|
|
100
|
+
if (!focusable.length) { event.preventDefault(); dialog.focus(); return; }
|
|
101
|
+
var first = focusable[0];
|
|
102
|
+
var last = focusable[focusable.length - 1];
|
|
103
|
+
var active = document.activeElement;
|
|
104
|
+
if (event.shiftKey && (active === first || active === dialog)) { event.preventDefault(); last.focus(); }
|
|
105
|
+
else if (!event.shiftKey && active === last) { event.preventDefault(); first.focus(); }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function initProjectStart() {
|
|
109
|
+
var overlay = modal();
|
|
110
|
+
var dialog = overlay.querySelector('.project-start-dialog');
|
|
111
|
+
store.subscribe(function (state, previous) {
|
|
112
|
+
if (state.projectStart !== previous.projectStart) render(state.projectStart, previous.projectStart);
|
|
113
|
+
else if (state.projectStartFolder !== previous.projectStartFolder && state.projectStart.view === 'open') renderFolderView();
|
|
114
|
+
});
|
|
115
|
+
overlay.querySelector('.project-start-backdrop').addEventListener('click', closeAddProjectModal);
|
|
116
|
+
document.getElementById('project-start-close').addEventListener('click', closeAddProjectModal);
|
|
117
|
+
document.getElementById('project-start-back').addEventListener('click', function () {
|
|
118
|
+
store.set({ projectStart: selectView(current(), 'choices') });
|
|
119
|
+
});
|
|
120
|
+
body().addEventListener('click', function (event) {
|
|
121
|
+
var choice = event.target.closest('[data-choice]');
|
|
122
|
+
if (choice) store.set({ projectStart: selectView(current(), choice.dataset.choice) });
|
|
123
|
+
});
|
|
124
|
+
dialog.addEventListener('keydown', function (event) {
|
|
125
|
+
if (event.key === 'Escape') { event.preventDefault(); closeAddProjectModal(); }
|
|
126
|
+
else if (event.key === 'Tab') trapTab(event, dialog);
|
|
127
|
+
});
|
|
128
|
+
var addButton = document.getElementById('project-list-add');
|
|
129
|
+
if (addButton) addButton.addEventListener('click', function () { openAddProjectModal(); });
|
|
130
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// project-start-folder-state.js - Pure state transitions for the open-folder browser.
|
|
2
|
+
// A reply is applied only when its requestId matches the single in-flight request.
|
|
3
|
+
|
|
4
|
+
export function emptyFolderState() {
|
|
5
|
+
return {
|
|
6
|
+
status: "idle", dir: null, parent: null, entries: [], error: null, errorKind: null,
|
|
7
|
+
requestId: null, requestedPath: null, candidates: [], candidateIdx: 0, initial: false, pathOpen: false,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function beginInitial(candidates, requestId) {
|
|
12
|
+
var next = emptyFolderState();
|
|
13
|
+
next.status = "loading";
|
|
14
|
+
next.candidates = candidates.slice();
|
|
15
|
+
next.initial = true;
|
|
16
|
+
next.requestId = requestId;
|
|
17
|
+
next.requestedPath = candidates[0] || "~";
|
|
18
|
+
return next;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function beginNavigate(prev, path, requestId) {
|
|
22
|
+
return Object.assign({}, prev, {
|
|
23
|
+
status: "loading", requestId: requestId, requestedPath: path, error: null, errorKind: null, initial: false,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function errorKindOf(message) {
|
|
28
|
+
return /not permitted|permission|EACCES|EPERM/i.test(message || "") ? "denied" : "failed";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function cleanEntries(entries) {
|
|
32
|
+
var out = [];
|
|
33
|
+
for (var i = 0; i < (entries || []).length; i++) {
|
|
34
|
+
var e = entries[i];
|
|
35
|
+
if (e && typeof e.name === "string" && typeof e.path === "string") out.push({ name: e.name, path: e.path });
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Returns { state, retryPath }. retryPath is set when the initial candidate failed and another remains.
|
|
41
|
+
export function applyBrowseResult(prev, msg, nextRequestId) {
|
|
42
|
+
if (!msg || prev.status !== "loading" || !prev.requestId || msg.requestId !== prev.requestId) {
|
|
43
|
+
return { state: prev, retryPath: null };
|
|
44
|
+
}
|
|
45
|
+
var failed = !!msg.error;
|
|
46
|
+
var wrongTarget = !failed && (typeof msg.dir !== "string" || (msg.prefix || "") !== "");
|
|
47
|
+
if (failed || wrongTarget) {
|
|
48
|
+
var idx = prev.candidateIdx + 1;
|
|
49
|
+
if (prev.initial && idx < prev.candidates.length) {
|
|
50
|
+
var retry = Object.assign({}, prev, { candidateIdx: idx, requestId: nextRequestId, requestedPath: prev.candidates[idx] });
|
|
51
|
+
return { state: retry, retryPath: prev.candidates[idx] };
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
state: Object.assign({}, prev, {
|
|
55
|
+
status: "error",
|
|
56
|
+
error: failed ? msg.error : "That folder was not found.",
|
|
57
|
+
errorKind: failed ? errorKindOf(msg.error) : "missing",
|
|
58
|
+
}),
|
|
59
|
+
retryPath: null,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
state: Object.assign({}, prev, {
|
|
64
|
+
status: "ready", dir: msg.dir, parent: typeof msg.parent === "string" ? msg.parent : null,
|
|
65
|
+
entries: cleanEntries(msg.entries), error: null, errorKind: null, initial: false,
|
|
66
|
+
}),
|
|
67
|
+
retryPath: null,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function failLocally(prev, message) {
|
|
72
|
+
if (prev.status !== "loading") return prev;
|
|
73
|
+
return Object.assign({}, prev, { status: "error", error: message, errorKind: "failed" });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function canOpenFolder(state) {
|
|
77
|
+
return state.status === "ready" && typeof state.dir === "string" && state.dir.length > 0;
|
|
78
|
+
}
|