clay-server 5.1.1-beta.1 → 5.2.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/account-auth-policy.js +21 -0
- package/lib/account-auth-socket.js +30 -0
- package/lib/account-auth-throttle.js +44 -0
- package/lib/account-auth-transport.js +48 -0
- package/lib/account-login-page.js +28 -0
- package/lib/account-passkey-challenges.js +31 -0
- package/lib/account-passkey-page.js +89 -0
- package/lib/account-passkey-policy.js +39 -0
- package/lib/account-password-page.js +69 -0
- package/lib/account-passwords.js +36 -0
- package/lib/account-remembered.js +77 -0
- package/lib/account-session-page.js +51 -0
- package/lib/account-session-store.js +82 -0
- package/lib/builtin-mates.js +19 -16
- package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
- package/lib/canonical-clay-record-authority.js +15 -0
- package/lib/canonical-clay-scheduling-authority.js +19 -0
- package/lib/claude-hook-installer.js +1 -239
- package/lib/claude-jsonl-watcher.js +1 -204
- package/lib/clay-control-presentation-binding.js +96 -0
- package/lib/clay-control-presentation.js +128 -0
- package/lib/clay-control-target-projection.js +26 -0
- package/lib/clay-mate-chat-receipts.js +26 -0
- package/lib/clay-mate-chat.js +88 -0
- package/lib/clay-mate-knowledge-input.js +26 -0
- package/lib/clay-mate-knowledge.js +95 -0
- package/lib/clay-mate-lifecycle.js +95 -0
- package/lib/clay-product-control-input.js +33 -0
- package/lib/clay-product-control-tools.js +51 -0
- package/lib/clay-product-control.js +247 -0
- package/lib/clay-project-lifecycle.js +154 -0
- package/lib/clay-project-record-input.js +44 -0
- package/lib/clay-project-records.js +84 -0
- package/lib/clay-scheduling-input.js +21 -0
- package/lib/clay-scheduling-receipts.js +26 -0
- package/lib/clay-scheduling.js +119 -0
- package/lib/clay-screen-controls.js +104 -0
- package/lib/clay-skill-install.js +1 -33
- package/lib/clay-workspace-controls.js +84 -0
- package/lib/clay-workspace-input.js +17 -0
- package/lib/clay-workspace-receipts.js +26 -0
- package/lib/cli-sessions.js +1 -300
- package/lib/codex-defaults.js +1 -28
- package/lib/context-usage.js +3 -2
- package/lib/contextual-screen-snapshot.js +38 -0
- package/lib/daemon-project-access.js +11 -0
- package/lib/daemon-project-lifecycle-callbacks.js +15 -0
- package/lib/daemon-project-lifecycle.js +262 -0
- package/lib/daemon-projects.js +1 -1
- package/lib/daemon.js +80 -276
- package/lib/default-ai-runtime.js +4 -8
- package/lib/dm-digest-cursor.js +120 -0
- package/lib/email-mcp-server.js +1 -1
- package/lib/issues-service.js +29 -15
- package/lib/kiro-defaults.js +1 -22
- package/lib/knowledge-db-import-validation.js +46 -0
- package/lib/knowledge-db-import.js +99 -0
- package/lib/knowledge-db-service.js +24 -33
- package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
- package/lib/knowledge-db-storage-nedb.js +66 -0
- package/lib/knowledge-db-storage.js +72 -0
- package/lib/knowledge-db-validation.js +0 -0
- package/lib/knowledge-document-index.js +2 -1
- package/lib/knowledge-file-store.js +7 -1
- package/lib/knowledge-product-operations.js +46 -0
- package/lib/mate-avatar-catalog.js +12 -0
- package/lib/mate-avatar-migration.js +41 -0
- package/lib/mate-context-service.js +138 -0
- package/lib/mate-context-tools.js +21 -0
- package/lib/mate-creation-mcp-server.js +2 -0
- package/lib/mate-knowledge-canonical-access.js +10 -0
- package/lib/mate-knowledge-mate-bound.js +53 -0
- package/lib/mate-knowledge-mcp-server.js +55 -8
- package/lib/mate-knowledge-service.js +16 -34
- package/lib/mate-knowledge-text-tools.js +106 -0
- package/lib/mate-lifecycle-service.js +94 -0
- package/lib/mate-message-delivery.js +43 -0
- package/lib/mate-ready-creation.js +9 -1
- package/lib/mate-schedule-input.js +29 -0
- package/lib/mate-schedule-lifecycle.js +151 -0
- package/lib/mate-scheduling.js +103 -0
- package/lib/mates.js +18 -6
- package/lib/mcp-agent-tools.js +117 -0
- package/lib/mcp-connection-store.js +119 -15
- package/lib/mcp-import-credentials.js +31 -0
- package/lib/mcp-local-transport.js +13 -0
- package/lib/mcp-oauth.js +8 -6
- package/lib/mcp-proxy.js +2 -32
- package/lib/mcp-query-bridge.js +30 -0
- package/lib/mcp-remote-connections.js +74 -20
- package/lib/mcp-source-adapters.js +1 -0
- package/lib/mcp-source-context.js +1 -0
- package/lib/mcp-source-discovery.js +1 -0
- package/lib/mcp-source-plugins.js +1 -0
- package/lib/mcp-source-restrictions.js +1 -0
- package/lib/mcp-tool-policy.js +9 -0
- package/lib/migrate-single-user.js +3 -23
- package/lib/notes-checklist.js +50 -0
- package/lib/notes.js +49 -3
- package/lib/os-user-diagnostics.js +2 -4
- package/lib/os-users.js +24 -70
- package/lib/pane-pending-interactions.js +20 -0
- package/lib/pane-session-activation.js +114 -0
- package/lib/pane-session-transport.js +26 -0
- package/lib/project-admin-overview.js +51 -0
- package/lib/project-ask-user.js +8 -4
- package/lib/project-connection.js +14 -10
- package/lib/project-control-git-view.js +12 -0
- package/lib/project-debate.js +1 -0
- package/lib/project-delegated-follow-up.js +2 -1
- package/lib/project-directory-claim.js +65 -0
- package/lib/project-file-operations.js +61 -0
- package/lib/project-filesystem.js +15 -85
- package/lib/project-full-access.js +23 -2
- package/lib/project-http.js +7 -4
- package/lib/project-knowledge.js +32 -18
- package/lib/project-lifecycle-operations.js +98 -0
- package/lib/project-lifecycle-process-witness.js +32 -0
- package/lib/project-lifecycle-runtime.js +50 -0
- package/lib/project-linux-access.js +22 -0
- package/lib/project-logs-canonical-clay.js +27 -0
- package/lib/project-logs-clay-query.js +16 -0
- package/lib/project-logs-schema.js +4 -2
- package/lib/project-logs-service.js +8 -7
- package/lib/project-logs.js +1 -0
- package/lib/project-loop.js +1 -0
- package/lib/project-mate-chat-control.js +55 -0
- package/lib/project-mate-creation-proposal.js +18 -3
- package/lib/project-mate-interaction.js +40 -62
- package/lib/project-mcp.js +54 -16
- package/lib/project-models.js +14 -31
- package/lib/project-notifications.js +76 -17
- package/lib/project-ownership.js +77 -0
- package/lib/project-pair-result-delivery.js +14 -3
- package/lib/project-pair-usage.js +12 -13
- package/lib/project-pending-message-queue.js +4 -1
- package/lib/project-product-control.js +89 -0
- package/lib/project-product-session-queue.js +46 -0
- package/lib/project-push-access.js +28 -0
- package/lib/project-scheduled-message-queue.js +30 -0
- package/lib/project-scheduled-messages.js +67 -68
- package/lib/project-scheduled-task-control.js +83 -0
- package/lib/project-scheduled-tasks.js +13 -2
- package/lib/project-scheduling-access.js +10 -0
- package/lib/project-server-settings.js +1 -0
- package/lib/project-session-actions.js +65 -0
- package/lib/project-session-delete.js +8 -1
- package/lib/project-session-document.js +27 -7
- package/lib/project-session-github.js +63 -19
- package/lib/project-session-history-actions.js +167 -0
- package/lib/project-session-linear.js +14 -6
- package/lib/project-session-notes.js +7 -3
- package/lib/project-session-pair.js +1 -1
- package/lib/project-session-runtime-actions.js +64 -0
- package/lib/project-session-spawn.js +2 -3
- package/lib/project-session-vendor.js +55 -0
- package/lib/project-sessions.js +103 -272
- package/lib/project-shared-browser.js +78 -17
- package/lib/project-studio-presentation.js +58 -0
- package/lib/project-user-knowledge.js +2 -1
- package/lib/project-user-message.js +67 -1
- package/lib/project-vendor-login.js +6 -36
- package/lib/project-workspace-operations.js +126 -0
- package/lib/project-workspace-query.js +19 -2
- package/lib/project.js +178 -45
- package/lib/public/app.js +46 -0
- package/lib/public/appearance-bootstrap.js +16 -0
- package/lib/public/auth/account-login.css +98 -0
- package/lib/public/auth/account-login.js +104 -0
- package/lib/public/css/clay-tool-activity.css +51 -0
- package/lib/public/css/clay-workspace.css +29 -0
- package/lib/public/css/command-palette.css +12 -33
- package/lib/public/css/contextual-clay.css +240 -0
- package/lib/public/css/home-debate-planning.css +2 -0
- package/lib/public/css/home-mate-creation.css +5 -0
- package/lib/public/css/input.css +6 -0
- package/lib/public/css/mate-avatar-gallery.css +12 -0
- package/lib/public/css/mate-conversation.css +10 -5
- package/lib/public/css/messages.css +6 -2
- package/lib/public/css/overlays.css +4 -2
- package/lib/public/css/project-admin-overview.css +13 -0
- package/lib/public/css/session-folders.css +11 -0
- package/lib/public/css/session-github.css +46 -1
- package/lib/public/css/shared-browser.css +35 -1
- package/lib/public/css/sticky-notes.css +87 -1
- package/lib/public/css/user-settings-sessions.css +42 -0
- package/lib/public/index.html +28 -10
- package/lib/public/mate-avatars/B01.png +0 -0
- package/lib/public/mate-avatars/B02.png +0 -0
- package/lib/public/mate-avatars/B03.png +0 -0
- package/lib/public/mate-avatars/B04.png +0 -0
- package/lib/public/mate-avatars/B05.png +0 -0
- package/lib/public/mate-avatars/B06.png +0 -0
- package/lib/public/mate-avatars/B07.png +0 -0
- package/lib/public/mate-avatars/B08.png +0 -0
- package/lib/public/mate-avatars/B09.png +0 -0
- package/lib/public/mate-avatars/B10.png +0 -0
- package/lib/public/mate-avatars/B11.png +0 -0
- package/lib/public/mate-avatars/B12.png +0 -0
- package/lib/public/mate-avatars/B13.png +0 -0
- package/lib/public/mate-avatars/B14.png +0 -0
- package/lib/public/mate-avatars/B15.png +0 -0
- package/lib/public/mate-avatars/B16.png +0 -0
- package/lib/public/mate-avatars/B17.png +0 -0
- package/lib/public/mate-avatars/B18.png +0 -0
- package/lib/public/mate-avatars/B19.png +0 -0
- package/lib/public/mate-avatars/B20.png +0 -0
- package/lib/public/mate-avatars/B21.png +0 -0
- package/lib/public/mate-avatars/B22.png +0 -0
- package/lib/public/mate-avatars/B23.png +0 -0
- package/lib/public/mate-avatars/B24.png +0 -0
- package/lib/public/mate-avatars/B25.png +0 -0
- package/lib/public/mate-avatars/B26.png +0 -0
- package/lib/public/mate-avatars/B27.png +0 -0
- package/lib/public/mate-avatars/B28.png +0 -0
- package/lib/public/mate-avatars/B29.png +0 -0
- package/lib/public/mate-avatars/B30.png +0 -0
- package/lib/public/mate-avatars/B31.png +0 -0
- package/lib/public/mate-avatars/B32.png +0 -0
- package/lib/public/mate-avatars/B33.png +0 -0
- package/lib/public/mate-avatars/B34.png +0 -0
- package/lib/public/mate-avatars/B35.png +0 -0
- package/lib/public/mate-avatars/B36.png +0 -0
- package/lib/public/mate-avatars/B37.png +0 -0
- package/lib/public/mate-avatars/B38.png +0 -0
- package/lib/public/mate-avatars/B39.png +0 -0
- package/lib/public/mate-avatars/B40.png +0 -0
- package/lib/public/mate-avatars/B41.png +0 -0
- package/lib/public/mate-avatars/B42.png +0 -0
- package/lib/public/mate-avatars/B43.png +0 -0
- package/lib/public/mate-avatars/B44.png +0 -0
- package/lib/public/mate-avatars/B45.png +0 -0
- package/lib/public/mate-avatars/B46.png +0 -0
- package/lib/public/mate-avatars/B47.png +0 -0
- package/lib/public/mate-avatars/B48.png +0 -0
- package/lib/public/mate-avatars/C01.png +0 -0
- package/lib/public/mate-avatars/C02.png +0 -0
- package/lib/public/mate-avatars/C03.png +0 -0
- package/lib/public/mate-avatars/C04.png +0 -0
- package/lib/public/mate-avatars/C05.png +0 -0
- package/lib/public/mate-avatars/C06.png +0 -0
- package/lib/public/mate-avatars/C07.png +0 -0
- package/lib/public/mate-avatars/C08.png +0 -0
- package/lib/public/mate-avatars/C09.png +0 -0
- package/lib/public/mate-avatars/C10.png +0 -0
- package/lib/public/mate-avatars/C11.png +0 -0
- package/lib/public/mate-avatars/C12.png +0 -0
- package/lib/public/mate-avatars/C13.png +0 -0
- package/lib/public/mate-avatars/C14.png +0 -0
- package/lib/public/mate-avatars/C15.png +0 -0
- package/lib/public/mate-avatars/C16.png +0 -0
- package/lib/public/mate-avatars/C17.png +0 -0
- package/lib/public/mate-avatars/C18.png +0 -0
- package/lib/public/mate-avatars/C19.png +0 -0
- package/lib/public/mate-avatars/C20.png +0 -0
- package/lib/public/mate-avatars/C21.png +0 -0
- package/lib/public/mate-avatars/C22.png +0 -0
- package/lib/public/mate-avatars/C23.png +0 -0
- package/lib/public/mate-avatars/C24.png +0 -0
- package/lib/public/mate-avatars/C25.png +0 -0
- package/lib/public/mate-avatars/C26.png +0 -0
- package/lib/public/mate-avatars/C27.png +0 -0
- package/lib/public/mate-avatars/C28.png +0 -0
- package/lib/public/mate-avatars/C29.png +0 -0
- package/lib/public/mate-avatars/C30.png +0 -0
- package/lib/public/mate-avatars/C31.png +0 -0
- package/lib/public/mate-avatars/C32.png +0 -0
- package/lib/public/mate-avatars/C33.png +0 -0
- package/lib/public/mate-avatars/C34.png +0 -0
- package/lib/public/mate-avatars/C35.png +0 -0
- package/lib/public/mate-avatars/C36.png +0 -0
- package/lib/public/mate-avatars/C37.png +0 -0
- package/lib/public/mate-avatars/C38.png +0 -0
- package/lib/public/mate-avatars/C39.png +0 -0
- package/lib/public/mate-avatars/C40.png +0 -0
- package/lib/public/mate-avatars/C41.png +0 -0
- package/lib/public/mate-avatars/C42.png +0 -0
- package/lib/public/mate-avatars/C43.png +0 -0
- package/lib/public/mate-avatars/C44.png +0 -0
- package/lib/public/mate-avatars/C45.png +0 -0
- package/lib/public/mate-avatars/C46.png +0 -0
- package/lib/public/mate-avatars/C47.png +0 -0
- package/lib/public/mate-avatars/C48.png +0 -0
- package/lib/public/mate-avatars/catalog.json +482 -0
- package/lib/public/mate-avatars/lead-clay.png +0 -0
- package/lib/public/modules/account-auth-settings.js +71 -0
- package/lib/public/modules/account-transport-settings.js +51 -0
- package/lib/public/modules/admin-settings-projects.js +6 -2
- package/lib/public/modules/app-connection.js +11 -1
- package/lib/public/modules/app-favicon.js +18 -9
- package/lib/public/modules/app-header.js +7 -4
- package/lib/public/modules/app-loop-ui.js +2 -0
- package/lib/public/modules/app-message-router.js +22 -1
- package/lib/public/modules/app-messages.js +119 -17
- package/lib/public/modules/app-misc.js +3 -1
- package/lib/public/modules/app-notifications.js +11 -5
- package/lib/public/modules/app-panels.js +61 -123
- package/lib/public/modules/app-projects.js +13 -0
- package/lib/public/modules/app-rate-limit.js +7 -27
- package/lib/public/modules/app-rendering.js +4 -3
- package/lib/public/modules/avatar.js +15 -41
- package/lib/public/modules/chat-render-runtime.js +20 -0
- package/lib/public/modules/clay-browser-links.js +47 -0
- package/lib/public/modules/clay-control-activity.js +214 -0
- package/lib/public/modules/clay-control-copy.js +36 -0
- package/lib/public/modules/clay-control-detail-targets.js +44 -0
- package/lib/public/modules/clay-control-object-targets.js +52 -0
- package/lib/public/modules/clay-control-target-visibility.js +12 -0
- package/lib/public/modules/clay-control-targets.js +44 -0
- package/lib/public/modules/clay-log-links.js +23 -0
- package/lib/public/modules/clay-navigation-render.js +52 -0
- package/lib/public/modules/clay-owner-navigation.js +33 -0
- package/lib/public/modules/clay-session-links.js +31 -0
- package/lib/public/modules/clay-studio-bridge.js +20 -0
- package/lib/public/modules/clay-studio-document.js +67 -0
- package/lib/public/modules/clay-studio-render.js +146 -0
- package/lib/public/modules/clay-tool-activity.js +140 -0
- package/lib/public/modules/clay-tool-presentation.js +342 -0
- package/lib/public/modules/command-palette.js +162 -40
- package/lib/public/modules/contextual-ask-session.js +26 -0
- package/lib/public/modules/contextual-clay-geometry.js +155 -0
- package/lib/public/modules/contextual-clay-session.js +130 -0
- package/lib/public/modules/contextual-clay-workspace.js +169 -0
- package/lib/public/modules/contextual-clay.js +250 -0
- package/lib/public/modules/contextual-composer.js +91 -0
- package/lib/public/modules/contextual-mate-context.js +117 -0
- package/lib/public/modules/contextual-mate-hint.js +40 -0
- package/lib/public/modules/contextual-mate-identity.js +23 -0
- package/lib/public/modules/contextual-mate-sessions.js +134 -0
- package/lib/public/modules/contextual-search.js +137 -0
- package/lib/public/modules/contextual-session-citations.js +58 -0
- package/lib/public/modules/debate.js +1 -0
- package/lib/public/modules/default-ai.js +11 -3
- package/lib/public/modules/elicitation-form.js +5 -0
- package/lib/public/modules/filebrowser.js +20 -1
- package/lib/public/modules/generation-stop.js +8 -5
- package/lib/public/modules/git-panel.js +3 -1
- package/lib/public/modules/history-replay-batch.js +13 -1
- package/lib/public/modules/home-debate-live.js +2 -0
- package/lib/public/modules/home-debate-planning.js +7 -7
- package/lib/public/modules/home-mate-avatar-editor.js +127 -208
- package/lib/public/modules/home-mate-chat.js +8 -6
- package/lib/public/modules/home-mate-creation.js +73 -1
- package/lib/public/modules/home-mate-settings.js +19 -12
- package/lib/public/modules/icon-strip-tooltip.js +2 -1
- package/lib/public/modules/input.js +88 -10
- package/lib/public/modules/issues-render.js +3 -2
- package/lib/public/modules/knowledge-db-workbench.js +4 -4
- package/lib/public/modules/markdown.js +6 -34
- package/lib/public/modules/mate-avatar-catalog.js +97 -0
- package/lib/public/modules/mate-knowledge-workbench.js +1 -1
- package/lib/public/modules/mate-management.js +40 -7
- package/lib/public/modules/mcp-connection-view.js +31 -13
- package/lib/public/modules/mcp-discovery-view.js +31 -0
- package/lib/public/modules/mcp-ui.js +23 -4
- package/lib/public/modules/mention.js +3 -0
- package/lib/public/modules/message-delivery.js +20 -2
- package/lib/public/modules/model-picker.js +2 -0
- package/lib/public/modules/pane-activation.js +214 -0
- package/lib/public/modules/pane-binding.js +82 -0
- package/lib/public/modules/pane-bridge.js +7 -4
- package/lib/public/modules/pane-browser-bridge.js +22 -0
- package/lib/public/modules/pane-file-bridge.js +4 -0
- package/lib/public/modules/pane-issue-bridge.js +4 -1
- package/lib/public/modules/passkey-browser.js +69 -0
- package/lib/public/modules/passkey-server-settings.js +57 -0
- package/lib/public/modules/pending-message-queue.js +1 -0
- package/lib/public/modules/permission-control.js +5 -4
- package/lib/public/modules/personal-settings-dialog.js +7 -1
- package/lib/public/modules/product-review.js +26 -0
- package/lib/public/modules/profile.js +1 -238
- package/lib/public/modules/project-access-recovery.js +17 -0
- package/lib/public/modules/project-admin-overview.js +21 -0
- package/lib/public/modules/project-chat-identity.js +13 -4
- package/lib/public/modules/project-logs-render.js +6 -2
- package/lib/public/modules/project-mate-navigation.js +144 -22
- package/lib/public/modules/rewind.js +5 -0
- package/lib/public/modules/scheduled-tasks.js +2 -0
- package/lib/public/modules/scheduler.js +2 -0
- package/lib/public/modules/search-clay-chat.js +5 -440
- package/lib/public/modules/server-settings-controls.js +10 -0
- package/lib/public/modules/server-settings.js +7 -2
- package/lib/public/modules/session-actions.js +5 -2
- package/lib/public/modules/session-context-menu.js +5 -0
- package/lib/public/modules/session-create-form.js +10 -10
- package/lib/public/modules/session-folder-layout.js +1 -1
- package/lib/public/modules/session-folder-view-menu.js +9 -0
- package/lib/public/modules/session-github.js +85 -14
- package/lib/public/modules/session-rich-drafts.js +21 -0
- package/lib/public/modules/session-switch-defer.js +67 -0
- package/lib/public/modules/session-work-primary.js +51 -0
- package/lib/public/modules/settings-defaults.js +27 -28
- package/lib/public/modules/shared-browser-settings.js +112 -0
- package/lib/public/modules/shared-browser-tabs.js +13 -3
- package/lib/public/modules/shared-browser.js +29 -6
- package/lib/public/modules/sidebar-mobile.js +4 -3
- package/lib/public/modules/sidebar-projects.js +1 -0
- package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
- package/lib/public/modules/sidebar-sessions.js +1 -0
- package/lib/public/modules/split-group-restore.js +68 -0
- package/lib/public/modules/split-pair-ui.js +1 -0
- package/lib/public/modules/split-pane-reconciler.js +15 -0
- package/lib/public/modules/split-pane-renderer.js +87 -6
- package/lib/public/modules/split-session-boundary.js +1 -1
- package/lib/public/modules/split-view.js +60 -68
- package/lib/public/modules/sticky-note-markdown.js +72 -6
- package/lib/public/modules/sticky-notes-actions.js +30 -0
- package/lib/public/modules/sticky-notes-browser.js +9 -2
- package/lib/public/modules/sticky-notes-card.js +23 -7
- package/lib/public/modules/sticky-notes-checklist.js +116 -0
- package/lib/public/modules/sticky-notes-editor.js +108 -44
- package/lib/public/modules/sticky-notes-shared.js +50 -2
- package/lib/public/modules/sticky-notes-state.js +66 -0
- package/lib/public/modules/sticky-notes.js +34 -51
- package/lib/public/modules/stt-controller.js +4 -1
- package/lib/public/modules/stt-recording.js +1 -1
- package/lib/public/modules/stt.js +7 -2
- package/lib/public/modules/terminal.js +9 -0
- package/lib/public/modules/theme.js +8 -1
- package/lib/public/modules/thinking-lifecycle.js +33 -3
- package/lib/public/modules/thinking-view.js +23 -1
- package/lib/public/modules/tools.js +60 -11
- package/lib/public/modules/tui-grab.js +1 -2
- package/lib/public/modules/user-settings-account.js +14 -1
- package/lib/public/modules/user-settings-appearance.js +10 -3
- package/lib/public/modules/user-settings-editors.js +1 -1
- package/lib/public/modules/user-settings-layout.js +11 -2
- package/lib/public/modules/user-settings-preferences.js +6 -2
- package/lib/public/modules/user-settings-profile.js +12 -2
- package/lib/public/modules/user-settings-sessions.js +120 -0
- package/lib/public/modules/user-settings.js +6 -2
- package/lib/public/modules/vendor-login-browser.js +5 -3
- package/lib/public/modules/vendor-login.js +2 -2
- package/lib/public/modules/vendor-priority.js +15 -1
- package/lib/public/modules/wireframe-workbench.js +5 -2
- package/lib/public/modules/you-activity.js +3 -1
- package/lib/public/modules/you.js +91 -6
- package/lib/public/muse-avatar.svg +4 -0
- package/lib/public/style.css +6 -0
- package/lib/public/sw.js +3 -1
- package/lib/safe-bash-commands.js +3 -45
- package/lib/scheduled-task-records.js +3 -1
- package/lib/scheduler.js +2 -0
- package/lib/sdk-bridge.js +342 -401
- package/lib/sdk-foreground-admission.js +16 -0
- package/lib/sdk-mcp-descriptors.js +2 -37
- package/lib/sdk-message-processor.js +52 -17
- package/lib/sdk-quota-snapshot.js +1 -1
- package/lib/sdk-response-recovery.js +1 -0
- package/lib/sdk-worker.js +2 -677
- package/lib/server-account-passkeys.js +186 -0
- package/lib/server-account-passwords.js +127 -0
- package/lib/server-account-security.js +53 -0
- package/lib/server-admin.js +63 -16
- package/lib/server-appearance-settings.js +13 -1
- package/lib/server-auth.js +107 -79
- package/lib/server-contextual-clay-settings.js +40 -0
- package/lib/server-contextual-mate-sessions.js +70 -0
- package/lib/server-dm.js +2 -1
- package/lib/server-global-ws.js +10 -20
- package/lib/server-home-chat-events.js +18 -4
- package/lib/server-home-chat.js +22 -20
- package/lib/server-home-clay-entry.js +23 -4
- package/lib/server-home-clay-session-links.js +29 -9
- package/lib/server-home-mate-creation.js +1 -0
- package/lib/server-home-mcp-consent.js +14 -0
- package/lib/server-mates.js +25 -62
- package/lib/server-owner-ui.js +118 -0
- package/lib/server-path-access.js +38 -0
- package/lib/server-project-removal.js +22 -0
- package/lib/server-settings.js +8 -2
- package/lib/server.js +165 -43
- package/lib/session-config-transition.js +45 -0
- package/lib/session-folders.js +7 -2
- package/lib/session-fork-history.js +21 -0
- package/lib/session-github.js +9 -2
- package/lib/session-hygiene.js +3 -35
- package/lib/session-permission-mode.js +4 -3
- package/lib/session-skill-scope.js +11 -0
- package/lib/session-visibility.js +5 -2
- package/lib/session-work-primary.js +50 -0
- package/lib/sessions.js +64 -99
- package/lib/shared-browser-cookie-sync.js +32 -0
- package/lib/shared-browser-cookies.js +79 -0
- package/lib/shared-browser-runtime.js +25 -9
- package/lib/shared-browser-storage-sync.js +43 -0
- package/lib/shared-browser-storage.js +101 -0
- package/lib/shared-browser-tools.js +2 -1
- package/lib/shared-browser-worker.js +46 -10
- package/lib/terminal-manager.js +65 -6
- package/lib/tool-llm.js +1 -1
- package/lib/tui-transcript-index.js +1 -132
- package/lib/user-knowledge-service.js +23 -1
- package/lib/users-auth.js +38 -3
- package/lib/users-contextual-clay-preferences.js +31 -0
- package/lib/users-create.js +97 -0
- package/lib/users-permissions.js +2 -8
- package/lib/users-server-pin.js +37 -0
- package/lib/users.js +18 -84
- package/lib/vendor-login-browser.js +1 -11
- package/lib/workspace-assignment-service.js +25 -0
- package/lib/workspace-query-access.js +4 -1
- package/lib/workspace-query-mcp-server.js +1 -1
- package/lib/workspace-query-service.js +13 -2
- package/lib/ws-request.js +1 -0
- package/lib/ws-schema.js +18 -2
- package/lib/yoke/acp-agent-profiles.js +7 -5
- package/lib/yoke/adapters/antigravity.js +3 -14
- package/lib/yoke/adapters/claude-query-contract.js +9 -0
- package/lib/yoke/adapters/claude.js +54 -50
- package/lib/yoke/adapters/codex-query-contract.js +24 -0
- package/lib/yoke/adapters/codex.js +53 -111
- package/lib/yoke/adapters/kiro.js +3 -1
- package/lib/yoke/adapters/muse-query-contract.js +7 -0
- package/lib/yoke/adapters/muse.js +122 -0
- package/lib/yoke/auth-events.js +17 -0
- package/lib/yoke/claude-hook-installer.js +271 -0
- package/lib/yoke/claude-jsonl-watcher.js +204 -0
- package/lib/yoke/claude-maintenance.js +55 -0
- package/lib/yoke/claude-permission-patterns.js +53 -0
- package/lib/yoke/claude-response-recovery.js +155 -0
- package/lib/yoke/claude-transcript-hygiene.js +34 -0
- package/lib/yoke/claude-worker-startup.js +28 -0
- package/lib/yoke/clay-skill-install.js +33 -0
- package/lib/yoke/cli-sessions.js +300 -0
- package/lib/yoke/codex-app-server.js +7 -12
- package/lib/yoke/codex-idle-recovery.js +81 -1
- package/lib/yoke/codex-recovery-admission.js +164 -0
- package/lib/yoke/configuration.js +13 -0
- package/lib/yoke/discovery.js +70 -0
- package/lib/yoke/errors.js +8 -0
- package/lib/yoke/host-environment.js +7 -0
- package/lib/yoke/index.js +9 -51
- package/lib/yoke/interface.js +116 -0
- package/lib/yoke/kiro-acp-server.js +5 -5
- package/lib/yoke/legacy-sessions.js +89 -0
- package/lib/yoke/login-protocol.js +25 -0
- package/lib/yoke/maintenance.js +12 -0
- package/lib/yoke/mcp-proxy.js +32 -0
- package/lib/yoke/mcp-source-adapters.js +91 -0
- package/lib/yoke/mcp-source-context.js +42 -0
- package/lib/yoke/mcp-source-discovery.js +169 -0
- package/lib/yoke/mcp-source-plugins.js +68 -0
- package/lib/yoke/mcp-source-restrictions.js +47 -0
- package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
- package/lib/yoke/model-preferences.js +6 -0
- package/lib/yoke/muse-artifacts.js +36 -0
- package/lib/yoke/muse-controls.js +50 -0
- package/lib/yoke/muse-input.js +64 -0
- package/lib/yoke/muse-items.js +157 -0
- package/lib/yoke/muse-policy.js +52 -0
- package/lib/yoke/muse-query.js +428 -0
- package/lib/yoke/muse-runtime.js +211 -0
- package/lib/yoke/muse-services.js +79 -0
- package/lib/yoke/muse-skills.js +79 -0
- package/lib/yoke/muse-turns.js +71 -0
- package/lib/yoke/options/acp.js +2 -0
- package/lib/yoke/options/antigravity.js +2 -0
- package/lib/yoke/options/claude.js +21 -0
- package/lib/yoke/options/codex-defaults.js +29 -0
- package/lib/yoke/options/codex-settings.js +21 -0
- package/lib/yoke/options/codex.js +6 -0
- package/lib/yoke/options/kiro-defaults.js +22 -0
- package/lib/yoke/options/kiro.js +5 -0
- package/lib/yoke/options/muse.js +5 -0
- package/lib/yoke/provider-contract.js +5 -0
- package/lib/yoke/providers/antigravity-executable.js +8 -0
- package/lib/yoke/providers/claude-executable.js +40 -0
- package/lib/yoke/providers/claude-model-descriptions.js +14 -0
- package/lib/yoke/providers/claude-process.js +97 -0
- package/lib/yoke/providers/claude-provision.js +75 -0
- package/lib/yoke/providers/codex-errors.js +8 -0
- package/lib/yoke/providers/muse-executable.js +17 -0
- package/lib/yoke/provisioning.js +6 -0
- package/lib/yoke/query-options.js +10 -0
- package/lib/yoke/response-recovery.js +41 -0
- package/lib/yoke/sdk-mcp-descriptors.js +37 -0
- package/lib/yoke/sdk-server-factory.js +7 -0
- package/lib/yoke/session-history.js +8 -0
- package/lib/yoke/session-tool-transport.js +34 -13
- package/lib/yoke/settings.js +23 -0
- package/lib/yoke/source-locations.js +4 -0
- package/lib/yoke/title-query.js +18 -7
- package/lib/yoke/tui-transcript-index.js +132 -0
- package/lib/yoke/usage.js +48 -0
- package/lib/yoke/user-input.js +13 -0
- package/lib/yoke/vendor-registry.js +81 -1
- package/package.json +11 -4
package/lib/server.js
CHANGED
|
@@ -10,7 +10,7 @@ var dm = require("./dm");
|
|
|
10
10
|
var mates = require("./mates");
|
|
11
11
|
var serverAuth = require("./server-auth");
|
|
12
12
|
var serverSkills = require("./server-skills");
|
|
13
|
-
var claudeHookInstaller = require("./claude-hook-installer");
|
|
13
|
+
var claudeHookInstaller = require("./yoke/claude-hook-installer");
|
|
14
14
|
var serverDm = require("./server-dm");
|
|
15
15
|
var serverMates = require("./server-mates");
|
|
16
16
|
var serverHomeChat = require("./server-home-chat");
|
|
@@ -219,6 +219,14 @@ function createServer(opts) {
|
|
|
219
219
|
var isRequestAuthed = auth.isRequestAuthed;
|
|
220
220
|
var parseCookies = auth.parseCookies;
|
|
221
221
|
|
|
222
|
+
var projectAdminOverview = require("./project-admin-overview");
|
|
223
|
+
|
|
224
|
+
function administrativeMetadata(userId, slug) {
|
|
225
|
+
var user = userId && users.findUserById(userId);
|
|
226
|
+
var context = projects.get(slug);
|
|
227
|
+
return projectAdminOverview.metadataFor(user, context && context.getStatus(), onGetProjectAccess && onGetProjectAccess(slug), users);
|
|
228
|
+
}
|
|
229
|
+
|
|
222
230
|
function canUserAccessSlug(userId, slug) {
|
|
223
231
|
if (!userId || !slug) return false;
|
|
224
232
|
var project = projects && projects.get(slug);
|
|
@@ -237,6 +245,13 @@ function createServer(opts) {
|
|
|
237
245
|
return users.canAccessProject(userId, access) === true;
|
|
238
246
|
}
|
|
239
247
|
|
|
248
|
+
var projects = new Map(); // slug → projectContext
|
|
249
|
+
var lifecycleRuntime = require("./project-lifecycle-runtime").attachLifecycleRuntime({ projects: projects });
|
|
250
|
+
var canUsePath = require("./server-path-access").attachPathAccess({
|
|
251
|
+
users: users, projects: projects, canAccess: canUserAccessSlug, osUsers: osUsers,
|
|
252
|
+
resolveIdentity: require("./os-users").resolveOsUserInfo,
|
|
253
|
+
});
|
|
254
|
+
|
|
240
255
|
var realVersion = require("../package.json").version;
|
|
241
256
|
var currentVersion = debug ? "0.0.9" : realVersion;
|
|
242
257
|
|
|
@@ -341,8 +356,13 @@ function createServer(opts) {
|
|
|
341
356
|
var caContent = caPath ? (function () { try { return fs.readFileSync(caPath); } catch (e) { return null; } })() : null;
|
|
342
357
|
|
|
343
358
|
// --- Project registry ---
|
|
344
|
-
var projects = new Map(); // slug → projectContext
|
|
345
359
|
var assignmentService = attachWorkspaceAssignmentService({
|
|
360
|
+
getPresentation: function (principal) {
|
|
361
|
+
var project = projects.get(principal.sourceProjectSlug), manager = project && project.getSessionManager(), status = project && project.getStatus();
|
|
362
|
+
var session = manager && manager.sessions.get(principal.sourceSessionId);
|
|
363
|
+
var bound = clayProductControl && session && clayProductControl.bind({ projectSlug: principal.sourceProjectSlug, projectOwnerId: status.projectOwnerId, isMate: status.isMate, mateId: status.mateId, session: session });
|
|
364
|
+
return bound && bound._presentation;
|
|
365
|
+
},
|
|
346
366
|
storageDir: path.join(CONFIG_DIR, "workspace-assignments"),
|
|
347
367
|
getProjects: function () { return projects; },
|
|
348
368
|
isMultiUser: function () { return users.isMultiUser(); },
|
|
@@ -363,6 +383,36 @@ function createServer(opts) {
|
|
|
363
383
|
},
|
|
364
384
|
assignmentService: assignmentService,
|
|
365
385
|
});
|
|
386
|
+
var ownerUiService = require('./server-owner-ui').attachOwnerUi({
|
|
387
|
+
isMultiUser: users.isMultiUser, findUser: users.findUserById,
|
|
388
|
+
forEachClient: function (visit) {
|
|
389
|
+
if (globalWs) globalWs.forEachClient(function (ws) { visit(ws, null); });
|
|
390
|
+
projects.forEach(function (project, slug) { project.forEachClient(function (ws) { visit(ws, slug); }); });
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
var mateContextService = require('./mate-context-service').attachMateContextService({
|
|
394
|
+
getOwnerUi: function () { return ownerUiService; }, workspace: workspaceQueryService,
|
|
395
|
+
getProjects: function () { return projects; }, isMultiUser: users.isMultiUser,
|
|
396
|
+
findUser: users.findUserById, onGetProjectAccess: onGetProjectAccess,
|
|
397
|
+
canAccessProject: users.canAccessProject,
|
|
398
|
+
resolveMate: function (owner, id) { return mates.getMate(mates.buildMateCtx(users.isMultiUser() ? owner : null), id); }
|
|
399
|
+
});
|
|
400
|
+
var clayProductControl = require("./clay-product-control").attachClayProductControl({
|
|
401
|
+
getOwnerUi: function () { return ownerUiService; },
|
|
402
|
+
getNotifications: function () { return _globalNotifications; },
|
|
403
|
+
getRecordServices: function () { return { issues: issuesService, logs: projectLogsService }; },
|
|
404
|
+
projectLifecycle: opts.projectLifecycle || null,
|
|
405
|
+
getMateLifecycle: function () { return mateHandler && mateHandler.lifecycle; },
|
|
406
|
+
getMateDir: function (ownerId, mateId) { return mates.getMateDir(mates.buildMateCtx(users.isMultiUser() ? ownerId : null), mateId); },
|
|
407
|
+
lifecyclePermissions: function (user) { return users.getEffectivePermissions(user, osUsers); },
|
|
408
|
+
canUsePath: canUsePath,
|
|
409
|
+
getProjects: function () { return projects; },
|
|
410
|
+
isMultiUser: function () { return users.isMultiUser(); },
|
|
411
|
+
onGetProjectAccess: onGetProjectAccess,
|
|
412
|
+
canAccessProject: function (userId, access) { return users.canAccessProject(userId, access) === true; },
|
|
413
|
+
findUser: function (userId) { return users.findUserById(userId); },
|
|
414
|
+
resolveMate: function (userId, mateId) { return mates.getMate(mates.buildMateCtx(users.isMultiUser() ? userId : null), mateId); },
|
|
415
|
+
});
|
|
366
416
|
// Project access is resolved from the authoritative project record, not from
|
|
367
417
|
// getStatus(), which carries no visibility or allowedUsers fields.
|
|
368
418
|
var projectLogsService = attachProjectLogsService({
|
|
@@ -409,6 +459,7 @@ function createServer(opts) {
|
|
|
409
459
|
// Mate Knowledge reads the synchronized Knowledge records. The Mate list is
|
|
410
460
|
// derived from the owning user alone, so a binding can never span users.
|
|
411
461
|
var mateKnowledgeService = attachMateKnowledgeService({
|
|
462
|
+
findUser: function (userId) { return users.findUserById(userId); },
|
|
412
463
|
getProjects: function () { return projects; },
|
|
413
464
|
isMultiUser: function () { return users.isMultiUser(); },
|
|
414
465
|
resolveMate: function (userId, mateId) {
|
|
@@ -491,6 +542,41 @@ function createServer(opts) {
|
|
|
491
542
|
},
|
|
492
543
|
});
|
|
493
544
|
|
|
545
|
+
function injectAppearanceSeed(html, appearance) {
|
|
546
|
+
var validId = function (value) {
|
|
547
|
+
return typeof value === "string" && /^[a-zA-Z0-9_-]{1,120}$/.test(value) ? value : null;
|
|
548
|
+
};
|
|
549
|
+
var mode = appearance && ["light", "dark"].indexOf(appearance.mode) >= 0 ? appearance.mode : null;
|
|
550
|
+
var seed = appearance && appearance.configured === true ? {
|
|
551
|
+
configured: true,
|
|
552
|
+
theme: validId(appearance.theme),
|
|
553
|
+
mode: mode,
|
|
554
|
+
lightTheme: validId(appearance.lightTheme),
|
|
555
|
+
darkTheme: validId(appearance.darkTheme),
|
|
556
|
+
} : null;
|
|
557
|
+
var payload = JSON.stringify(seed).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
558
|
+
var script = '<script>window.__clayAppearanceSeed=' + payload + ';</script>';
|
|
559
|
+
return html.replace('<script src="appearance-bootstrap.js"></script>', script + '<script src="appearance-bootstrap.js"></script>');
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function sendAppShell(req, res, slug) {
|
|
563
|
+
try {
|
|
564
|
+
var shell = fs.readFileSync(path.join(publicDir, "index.html"), "utf8");
|
|
565
|
+
if (slug) shell = injectRootProjectSlug(shell, slug);
|
|
566
|
+
var appearance = null;
|
|
567
|
+
try { appearance = settings.getInitialAppearance(req); } catch (e) {}
|
|
568
|
+
shell = injectAppearanceSeed(shell, appearance);
|
|
569
|
+
res.writeHead(200, {
|
|
570
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
571
|
+
"Cache-Control": "private, no-store",
|
|
572
|
+
});
|
|
573
|
+
res.end(shell);
|
|
574
|
+
} catch (e) {
|
|
575
|
+
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
576
|
+
res.end("App shell missing.");
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
494
580
|
var palette = serverPalette.attachPalette({
|
|
495
581
|
users: users,
|
|
496
582
|
projects: projects,
|
|
@@ -512,7 +598,28 @@ function createServer(opts) {
|
|
|
512
598
|
broadcastAll: function (msg) { broadcastAll(msg); },
|
|
513
599
|
sendToUser: function (userId, msg) { sendToUser(userId, msg); },
|
|
514
600
|
pushModule: pushModule,
|
|
601
|
+
forEachClient: forEachAppClient,
|
|
602
|
+
getUsers: function () { return users.getAllUsers(); },
|
|
603
|
+
canView: function (ws, notification) { return canViewNotification(ws && ws._clayUser && ws._clayUser.id, notification); },
|
|
604
|
+
canViewPrincipal: function (principal, notification) { return canViewNotification(principal.userId, notification); },
|
|
515
605
|
});
|
|
606
|
+
function canViewNotification(userId, notification) {
|
|
607
|
+
if (!users.isMultiUser()) return true;
|
|
608
|
+
if (!userId || !users.findUserById(userId)) return false;
|
|
609
|
+
if (notification.targetUserId && notification.targetUserId !== userId) return false;
|
|
610
|
+
if (notification.slug) {
|
|
611
|
+
if (!canUserAccessSlug(userId, notification.slug)) return false;
|
|
612
|
+
if (notification.sessionId) {
|
|
613
|
+
var project = projects.get(notification.slug);
|
|
614
|
+
var session = project && project.getSessionManager().sessions.get(notification.sessionId);
|
|
615
|
+
var status = project && project.getStatus();
|
|
616
|
+
var access = status && status.isMate ? { isMate: true, visibility: "private", ownerId: status.projectOwnerId } : onGetProjectAccess(notification.slug);
|
|
617
|
+
if (!session || !users.canAccessSession(userId, session, access)) return false;
|
|
618
|
+
}
|
|
619
|
+
return !notification.ownerId || notification.ownerId === userId || !!notification.sessionId;
|
|
620
|
+
}
|
|
621
|
+
return notification.targetUserId === userId || notification.ownerId === userId;
|
|
622
|
+
}
|
|
516
623
|
|
|
517
624
|
// --- Security headers ---
|
|
518
625
|
var securityHeaders = {
|
|
@@ -910,15 +1017,7 @@ function createServer(opts) {
|
|
|
910
1017
|
});
|
|
911
1018
|
}
|
|
912
1019
|
if (targetSlug) {
|
|
913
|
-
|
|
914
|
-
var homeHtml = fs.readFileSync(path.join(publicDir, "index.html"), "utf8");
|
|
915
|
-
homeHtml = injectRootProjectSlug(homeHtml, targetSlug);
|
|
916
|
-
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-cache" });
|
|
917
|
-
res.end(homeHtml);
|
|
918
|
-
} catch (e) {
|
|
919
|
-
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
920
|
-
res.end("App shell missing.");
|
|
921
|
-
}
|
|
1020
|
+
sendAppShell(req, res, targetSlug);
|
|
922
1021
|
return;
|
|
923
1022
|
}
|
|
924
1023
|
}
|
|
@@ -936,9 +1035,7 @@ function createServer(opts) {
|
|
|
936
1035
|
return;
|
|
937
1036
|
}
|
|
938
1037
|
}
|
|
939
|
-
|
|
940
|
-
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
941
|
-
res.end("App shell missing.");
|
|
1038
|
+
sendAppShell(req, res, null);
|
|
942
1039
|
return;
|
|
943
1040
|
}
|
|
944
1041
|
|
|
@@ -955,8 +1052,8 @@ function createServer(opts) {
|
|
|
955
1052
|
var projectList = [];
|
|
956
1053
|
var infoUser = users.isMultiUser() ? getMultiUserFromReq(req) : null;
|
|
957
1054
|
projects.forEach(function (ctx, slug) {
|
|
958
|
-
if (users.isMultiUser() && (!infoUser || !canUserAccessSlug(infoUser.id, slug))) return;
|
|
959
|
-
projectList.push({ slug: slug, project: ctx.project });
|
|
1055
|
+
if (users.isMultiUser() && (!infoUser || (!canUserAccessSlug(infoUser.id, slug) && !administrativeMetadata(infoUser.id, slug)))) return;
|
|
1056
|
+
projectList.push({ slug: slug, project: ctx.project, contentAccess: !users.isMultiUser() || canUserAccessSlug(infoUser.id, slug) });
|
|
960
1057
|
});
|
|
961
1058
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
962
1059
|
res.end(JSON.stringify({ projects: projectList, version: currentVersion, authenticated: true }));
|
|
@@ -965,6 +1062,10 @@ function createServer(opts) {
|
|
|
965
1062
|
|
|
966
1063
|
// Static files (favicon, manifest, icons, sw.js, mate avatars, etc.)
|
|
967
1064
|
if (!fullUrl.includes("..") && !fullUrl.startsWith("/p/") && !fullUrl.startsWith("/api/")) {
|
|
1065
|
+
if (fullUrl === "/index.html") {
|
|
1066
|
+
sendAppShell(req, res, null);
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
968
1069
|
if (serveStatic(fullUrl, res)) return;
|
|
969
1070
|
}
|
|
970
1071
|
|
|
@@ -1028,8 +1129,14 @@ function createServer(opts) {
|
|
|
1028
1129
|
if (users.isMultiUser() && !isMcpBridgeAuthenticated) {
|
|
1029
1130
|
var httpUser = getMultiUserFromReq(req);
|
|
1030
1131
|
if (!httpUser || !canUserAccessSlug(httpUser.id, slug)) {
|
|
1031
|
-
|
|
1032
|
-
|
|
1132
|
+
var overview = httpUser && administrativeMetadata(httpUser.id, slug);
|
|
1133
|
+
if (overview && req.method === "GET" && (projectUrlForAuth === "/" || projectUrlForAuth === "/index.html")) {
|
|
1134
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" });
|
|
1135
|
+
res.end(projectAdminOverview.page(overview, getVisibleProjects(httpUser.id)));
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
res.writeHead(403, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
1139
|
+
res.end(JSON.stringify({ error: "Project content access is not permitted" }));
|
|
1033
1140
|
return;
|
|
1034
1141
|
}
|
|
1035
1142
|
}
|
|
@@ -1054,6 +1161,10 @@ function createServer(opts) {
|
|
|
1054
1161
|
|
|
1055
1162
|
// Static files (same assets for all projects)
|
|
1056
1163
|
if (req.method === "GET") {
|
|
1164
|
+
if (projectUrl === "/" || projectUrl === "/index.html") {
|
|
1165
|
+
sendAppShell(req, res, slug);
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1057
1168
|
if (serveStatic(projectUrl, res)) return;
|
|
1058
1169
|
}
|
|
1059
1170
|
|
|
@@ -1134,6 +1245,7 @@ function createServer(opts) {
|
|
|
1134
1245
|
var globalWs = serverGlobalWs.attachGlobalWs({
|
|
1135
1246
|
osUsers: osUsers,
|
|
1136
1247
|
usersModule: users,
|
|
1248
|
+
canUsePath: canUsePath,
|
|
1137
1249
|
onAddProject: onAddProject,
|
|
1138
1250
|
onCreateProject: onCreateProject,
|
|
1139
1251
|
onCloneProject: onCloneProject,
|
|
@@ -1182,8 +1294,10 @@ function createServer(opts) {
|
|
|
1182
1294
|
}
|
|
1183
1295
|
var globalUser = users.isMultiUser() ? getMultiUserFromReq(req) : null;
|
|
1184
1296
|
wss.handleUpgrade(req, socket, head, function (ws) {
|
|
1297
|
+
if (!require('./account-auth-socket').guardSocket(ws, req, isRequestAuthed, auth.touchSession)) return;
|
|
1185
1298
|
ws._clayPane = wsRequest.pane;
|
|
1186
1299
|
ws._clayPaneSession = wsRequest.paneSession;
|
|
1300
|
+
ws._clayContextual = wsRequest.contextual;
|
|
1187
1301
|
globalWs.handleConnection(ws, globalUser);
|
|
1188
1302
|
});
|
|
1189
1303
|
return;
|
|
@@ -1223,11 +1337,13 @@ function createServer(opts) {
|
|
|
1223
1337
|
}
|
|
1224
1338
|
|
|
1225
1339
|
wss.handleUpgrade(req, socket, head, function (ws) {
|
|
1340
|
+
if (!require('./account-auth-socket').guardSocket(ws, req, isRequestAuthed, auth.touchSession)) return;
|
|
1226
1341
|
// Apply rate limiting to WS messages
|
|
1227
1342
|
applyWsRateLimit(ws, WS_RATE_LIMIT);
|
|
1228
1343
|
ws._clayUser = wsUser; // attach user context
|
|
1229
1344
|
ws._clayPane = wsRequest.pane;
|
|
1230
1345
|
ws._clayPaneSession = wsRequest.paneSession;
|
|
1346
|
+
ws._clayContextual = wsRequest.contextual;
|
|
1231
1347
|
var remoteAddr = req.socket.remoteAddress || "";
|
|
1232
1348
|
ws._clayLocal = (remoteAddr === "127.0.0.1" || remoteAddr === "::1" || remoteAddr === "::ffff:127.0.0.1");
|
|
1233
1349
|
// Clear cross-project unread for this project when client connects
|
|
@@ -1272,17 +1388,10 @@ function createServer(opts) {
|
|
|
1272
1388
|
if (processingUpdateTimer) clearTimeout(processingUpdateTimer);
|
|
1273
1389
|
processingUpdateTimer = setTimeout(function () {
|
|
1274
1390
|
processingUpdateTimer = null;
|
|
1275
|
-
var allProjectsList = getProjects();
|
|
1276
1391
|
// Always send per-client to include cross-project unread counts
|
|
1277
1392
|
projects.forEach(function (ctx, projSlug) {
|
|
1278
1393
|
ctx.forEachClient(function (ws) {
|
|
1279
|
-
var filtered =
|
|
1280
|
-
if (users.isMultiUser() && onGetProjectAccess) {
|
|
1281
|
-
var wsUser = ws._clayUser;
|
|
1282
|
-
filtered = wsUser ? allProjectsList.filter(function (p) {
|
|
1283
|
-
return canUserAccessSlug(wsUser.id, p.slug);
|
|
1284
|
-
}) : [];
|
|
1285
|
-
}
|
|
1394
|
+
var filtered = getVisibleProjects(ws._clayUser ? ws._clayUser.id : null);
|
|
1286
1395
|
// Attach per-project unread counts for this client
|
|
1287
1396
|
var unreadMap = getCrossProjectUnread(ws);
|
|
1288
1397
|
var projectsWithUnread = filtered.map(function (p) {
|
|
@@ -1332,6 +1441,10 @@ function createServer(opts) {
|
|
|
1332
1441
|
function addProject(cwd, slug, title, icon, projectOwnerId, worktreeMeta, extraOpts) {
|
|
1333
1442
|
if (projects.has(slug)) return false;
|
|
1334
1443
|
var extra = extraOpts || {};
|
|
1444
|
+
if (extra.isMate) {
|
|
1445
|
+
var registeredMate = mates.getMate(mates.buildMateCtx(users.isMultiUser() ? projectOwnerId : null), extra.mateId || path.basename(cwd));
|
|
1446
|
+
if (registeredMate && registeredMate.lifecycleDeletion) return false;
|
|
1447
|
+
}
|
|
1335
1448
|
var ctx = createProjectContext({
|
|
1336
1449
|
cwd: cwd,
|
|
1337
1450
|
slug: slug,
|
|
@@ -1351,6 +1464,9 @@ function createServer(opts) {
|
|
|
1351
1464
|
return mateHandler.createReadyMateFromInterview(ws, userId, definition);
|
|
1352
1465
|
},
|
|
1353
1466
|
workspaceQueryService: workspaceQueryService,
|
|
1467
|
+
clayProductControl: clayProductControl,
|
|
1468
|
+
mateContextService: mateContextService,
|
|
1469
|
+
resumeLifecycleProject: function (userId) { return opts.projectLifecycle ? opts.projectLifecycle.resumeRecovered(slug, userId) : true; },
|
|
1354
1470
|
projectLogsService: projectLogsService,
|
|
1355
1471
|
issuesService: issuesService,
|
|
1356
1472
|
linearStorage: linear.storage,
|
|
@@ -1372,13 +1488,19 @@ function createServer(opts) {
|
|
|
1372
1488
|
return !!(access && !access.error && users.canAccessProject(userId, access));
|
|
1373
1489
|
},
|
|
1374
1490
|
getProjectAccess: function () {
|
|
1375
|
-
if (extra.isMate)
|
|
1491
|
+
if (extra.isMate) {
|
|
1492
|
+
var mate = mates.getMate(mates.buildMateCtx(users.isMultiUser() ? projectOwnerId : null), extra.mateId || path.basename(cwd));
|
|
1493
|
+
return { isMate: true, visibility: "private", ownerId: projectOwnerId || null, allowedUsers: [], lifecycleExecutionPaused: !mate || !!mate.lifecycleDeletion };
|
|
1494
|
+
}
|
|
1376
1495
|
return onGetProjectAccess ? onGetProjectAccess(slug) : { visibility: "public", ownerId: projectOwnerId || null };
|
|
1377
1496
|
},
|
|
1378
1497
|
shouldSuppressResponseNotification: function (session) {
|
|
1379
1498
|
return shouldSuppressHomeResponse(projects, slug, session);
|
|
1380
1499
|
},
|
|
1381
|
-
pushModule: pushModule,
|
|
1500
|
+
pushModule: require("./project-push-access").scopedPush(pushModule, {
|
|
1501
|
+
slug: slug, users: users, getProject: function (target) { return projects.get(target); },
|
|
1502
|
+
canAccessProject: canUserAccessSlug, getAccess: onGetProjectAccess,
|
|
1503
|
+
}),
|
|
1382
1504
|
debug: debug,
|
|
1383
1505
|
dangerouslySkipPermissions: dangerouslySkipPermissions,
|
|
1384
1506
|
osUsers: osUsers,
|
|
@@ -1410,6 +1532,7 @@ function createServer(opts) {
|
|
|
1410
1532
|
var status = ctx.getStatus();
|
|
1411
1533
|
var recs = ctx.getSchedules();
|
|
1412
1534
|
for (var i = 0; i < recs.length; i++) {
|
|
1535
|
+
if (users.isMultiUser() && recs[i].ownerId !== userId) continue;
|
|
1413
1536
|
// Shallow-copy full record and augment with project metadata
|
|
1414
1537
|
var copy = {};
|
|
1415
1538
|
var keys = Object.keys(recs[i]);
|
|
@@ -1467,6 +1590,7 @@ function createServer(opts) {
|
|
|
1467
1590
|
return ctx.getSchedules().length;
|
|
1468
1591
|
},
|
|
1469
1592
|
canAccessProjectSlug: canUserAccessSlug,
|
|
1593
|
+
canUsePath: canUsePath,
|
|
1470
1594
|
onPresenceChange: broadcastPresenceChange,
|
|
1471
1595
|
onProcessingChanged: broadcastProcessingChange,
|
|
1472
1596
|
onSessionDone: function () { onSessionDone(slug); },
|
|
@@ -1620,6 +1744,8 @@ function createServer(opts) {
|
|
|
1620
1744
|
}
|
|
1621
1745
|
|
|
1622
1746
|
function handleDmMessage(ws, msg, routedProjectSlug) {
|
|
1747
|
+
if (ownerUiService.handleMessage(ws, msg)) return true;
|
|
1748
|
+
if (mateContextService.handleMessage(ws, msg)) return true;
|
|
1623
1749
|
if (cursorSharingService && cursorSharingService.handleMessage(ws, msg)) return true;
|
|
1624
1750
|
if (defaultVendorService && defaultVendorService.handleMessage(ws, msg, routedProjectSlug)) return true;
|
|
1625
1751
|
if (contextViewService && contextViewService.handleMessage(ws, msg)) return true;
|
|
@@ -1628,25 +1754,14 @@ function createServer(opts) {
|
|
|
1628
1754
|
if (dmHandler.handleMessage(ws, msg)) return true;
|
|
1629
1755
|
if (mateHandler && mateHandler.handleMessage(ws, msg)) return true;
|
|
1630
1756
|
if (emailHandler.handleMessage(ws, msg)) return true;
|
|
1631
|
-
if (homeChatHandler.handleMessage(ws, msg)) return true;
|
|
1757
|
+
if (homeChatHandler.handleMessage(ws, msg, routedProjectSlug)) return true;
|
|
1632
1758
|
if (homePreferencesHandler.handleMessage(ws, msg)) return true;
|
|
1633
1759
|
if (toolsHandler.handleMessage(ws, msg)) return true;
|
|
1634
1760
|
return false;
|
|
1635
1761
|
}
|
|
1636
1762
|
|
|
1637
|
-
function removeProject(slug) {
|
|
1638
|
-
|
|
1639
|
-
if (!ctx) return false;
|
|
1640
|
-
var wasMate = ctx.getStatus().isMate;
|
|
1641
|
-
var shutdownResult = ctx.destroy();
|
|
1642
|
-
projects.delete(slug);
|
|
1643
|
-
if (shutdownResult && typeof shutdownResult.catch === "function") {
|
|
1644
|
-
shutdownResult.catch(function(err) {
|
|
1645
|
-
console.error("[server] Project destroy failed for " + slug + ":", err && err.message ? err.message : err);
|
|
1646
|
-
});
|
|
1647
|
-
}
|
|
1648
|
-
if (!wasMate) scheduleRegistryRefresh();
|
|
1649
|
-
return true;
|
|
1763
|
+
function removeProject(slug, awaitCompletion) {
|
|
1764
|
+
return require('./server-project-removal').removeProjectRuntime(projects, slug, awaitCompletion, scheduleRegistryRefresh);
|
|
1650
1765
|
}
|
|
1651
1766
|
|
|
1652
1767
|
// Now that addProject and removeProject are defined, initialize mateHandler
|
|
@@ -1732,7 +1847,11 @@ function createServer(opts) {
|
|
|
1732
1847
|
function getVisibleProjects(userId) {
|
|
1733
1848
|
var visible = [];
|
|
1734
1849
|
projects.forEach(function (ctx, slug) {
|
|
1735
|
-
if (users.isMultiUser() && (!userId || !canUserAccessSlug(userId, slug)))
|
|
1850
|
+
if (users.isMultiUser() && (!userId || !canUserAccessSlug(userId, slug))) {
|
|
1851
|
+
var metadata = administrativeMetadata(userId, slug);
|
|
1852
|
+
if (metadata) visible.push(metadata);
|
|
1853
|
+
return;
|
|
1854
|
+
}
|
|
1736
1855
|
var status = ctx.getStatus();
|
|
1737
1856
|
if (!status.isMate && onGetProjectAccess) {
|
|
1738
1857
|
var access = onGetProjectAccess(slug);
|
|
@@ -1931,6 +2050,7 @@ function createServer(opts) {
|
|
|
1931
2050
|
speech.destroy();
|
|
1932
2051
|
var shutdowns = [];
|
|
1933
2052
|
shutdowns.push(durableSchedulerLifecycle.shutdown());
|
|
2053
|
+
shutdowns.push(lifecycleRuntime.shutdown());
|
|
1934
2054
|
projects.forEach(function (ctx, slug) {
|
|
1935
2055
|
console.log("[server] Destroying project:", slug);
|
|
1936
2056
|
var result = ctx.destroy();
|
|
@@ -1998,6 +2118,8 @@ function createServer(opts) {
|
|
|
1998
2118
|
isTLS: !!tlsOptions,
|
|
1999
2119
|
addProject: addProject,
|
|
2000
2120
|
removeProject: removeProject,
|
|
2121
|
+
getProjectLifecycleTargets: lifecycleRuntime.targets,
|
|
2122
|
+
closeProjectLifecycle: lifecycleRuntime.close,
|
|
2001
2123
|
getProjects: getProjects,
|
|
2002
2124
|
reorderProjects: reorderProjects,
|
|
2003
2125
|
setProjectTitle: setProjectTitle,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Guarded configuration commit shared by SDK setters and permission transitions.
|
|
2
|
+
// Provider acknowledgement is distinct from local persistence. Once a request
|
|
3
|
+
// has crossed that boundary, failures never imply the provider was rolled back.
|
|
4
|
+
async function applySessionConfig(ctx) {
|
|
5
|
+
var session = ctx.session, sm = ctx.sm, handle = session.queryInstance;
|
|
6
|
+
var generation = Number(session._sdkQueryGeneration || 0), owner = session.ownerId;
|
|
7
|
+
var paused = !!session._pendingMessageDrainPaused, signal = session.abortController && session.abortController.signal;
|
|
8
|
+
var attempted = false, acknowledged = false, persisted = false, previous = {};
|
|
9
|
+
function current() {
|
|
10
|
+
ctx.revalidate();
|
|
11
|
+
if (sm.sessions.get(session.localId) !== session || session.ownerId !== owner || session.queryInstance !== handle ||
|
|
12
|
+
Number(session._sdkQueryGeneration || 0) !== generation || session.taskStopRequested ||
|
|
13
|
+
!!session._pendingMessageDrainPaused !== paused || signal && signal.aborted) throw new Error("Target ownership, runtime, or Stop state changed during the configuration request.");
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
current();
|
|
17
|
+
if (handle) {
|
|
18
|
+
if (typeof handle[ctx.method] !== "function") throw new Error("This provider cannot apply this configuration to the active runtime.");
|
|
19
|
+
attempted = true;
|
|
20
|
+
var reply = await handle[ctx.method](ctx.nativeValue);
|
|
21
|
+
if (reply === false || reply && reply.ok === false) throw new Error(reply && reply.error || "The provider refused the configuration change.");
|
|
22
|
+
acknowledged = true;
|
|
23
|
+
current();
|
|
24
|
+
}
|
|
25
|
+
var changes = typeof ctx.changes === "function" ? ctx.changes() : ctx.changes;
|
|
26
|
+
Object.keys(changes).forEach(function (key) { previous[key] = { present: Object.prototype.hasOwnProperty.call(session, key), value: session[key] }; });
|
|
27
|
+
Object.assign(session, changes);
|
|
28
|
+
try {
|
|
29
|
+
if (sm.saveSessionFile(session) !== true) throw new Error("Could not persist the configuration change.");
|
|
30
|
+
persisted = true;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
Object.keys(previous).forEach(function (key) { if (previous[key].present) session[key] = previous[key].value; else delete session[key]; });
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
// There is no await between the last authorization check, disk commit and
|
|
36
|
+
// publication. Never broadcast a desired value before its save succeeds.
|
|
37
|
+
ctx.publish();
|
|
38
|
+
return Object.assign({ ok: true, status: "completed", persisted: true, runtimeEffect: acknowledged ? "applied" : "none" }, changes);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
return { ok: false, status: "failed", outcome: persisted ? "partial" : attempted ? "uncertain" : "failed", persisted: persisted,
|
|
41
|
+
runtimeEffect: acknowledged ? "applied" : attempted ? "unknown" : "none", retrySafe: !attempted && !persisted,
|
|
42
|
+
error: (persisted ? "The configuration was saved, but publication did not complete. " : "") + (attempted ? "The provider may retain the requested change; no external rollback was attempted. " : "") + (error.message || String(error)) };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
module.exports = { applySessionConfig: applySessionConfig };
|
package/lib/session-folders.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// also keeps its folder (or Unfiled) assignment
|
|
10
10
|
// orders: { containerKey: [keys] } manual order per container ("unfiled", custom id, "all")
|
|
11
11
|
// collapsed: { containerKey: true }
|
|
12
|
-
// view: { group, sort, direction }
|
|
12
|
+
// view: { group, sort, direction, showDateHeadings }
|
|
13
13
|
// sessionKey is the session's opaque, durable sessionOriginId.
|
|
14
14
|
|
|
15
15
|
var crypto = require("crypto");
|
|
@@ -35,7 +35,7 @@ function defaultState() {
|
|
|
35
35
|
favorites: [],
|
|
36
36
|
orders: {},
|
|
37
37
|
collapsed: {},
|
|
38
|
-
view: { group: "folders", sort: "activity", direction: "desc" },
|
|
38
|
+
view: { group: "folders", sort: "activity", direction: "desc", showDateHeadings: true },
|
|
39
39
|
legacyFavoritesMigrated: false,
|
|
40
40
|
};
|
|
41
41
|
}
|
|
@@ -147,6 +147,7 @@ function normalizeState(raw) {
|
|
|
147
147
|
var view = isPlainObject(source.view) ? source.view : {};
|
|
148
148
|
if (SORTS.indexOf(view.sort) !== -1) state.view.sort = view.sort;
|
|
149
149
|
if (DIRECTIONS.indexOf(view.direction) !== -1) state.view.direction = view.direction;
|
|
150
|
+
if (typeof view.showDateHeadings === "boolean") state.view.showDateHeadings = view.showDateHeadings;
|
|
150
151
|
state.legacyFavoritesMigrated = source.legacyFavoritesMigrated === true;
|
|
151
152
|
return state;
|
|
152
153
|
}
|
|
@@ -334,6 +335,10 @@ function applyRaw(input, op, env) {
|
|
|
334
335
|
if (DIRECTIONS.indexOf(op.direction) === -1) return { error: "Invalid direction" };
|
|
335
336
|
state.view.direction = op.direction;
|
|
336
337
|
}
|
|
338
|
+
if (op.showDateHeadings !== undefined) {
|
|
339
|
+
if (typeof op.showDateHeadings !== "boolean") return { error: "Invalid date heading setting" };
|
|
340
|
+
state.view.showDateHeadings = op.showDateHeadings;
|
|
341
|
+
}
|
|
337
342
|
return { state: state };
|
|
338
343
|
}
|
|
339
344
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Product transcript slicing for providers that include a completed turn.
|
|
2
|
+
function endIndex(session, uuid, boundary) {
|
|
3
|
+
if (boundary === undefined) return undefined;
|
|
4
|
+
if (boundary !== "completed-turn-inclusive") throw new Error("Unsupported local fork history boundary");
|
|
5
|
+
var history = session.history || [];
|
|
6
|
+
var markers = (session.messageUUIDs || []).filter(function(marker) { return marker.uuid === uuid && marker.type === "user"; });
|
|
7
|
+
var marker = markers.length === 1 && markers[0];
|
|
8
|
+
var index = marker && marker.historyIndex;
|
|
9
|
+
var entry = Number.isInteger(index) && history[index];
|
|
10
|
+
if (!entry || entry.type !== "message_uuid" || entry.uuid !== uuid) throw new Error("Cannot safely represent this completed-turn fork boundary in local history");
|
|
11
|
+
for (var i = index + 1; i < history.length; i++) {
|
|
12
|
+
entry = history[i];
|
|
13
|
+
if (entry.type === "user_message" || entry.type === "message_uuid" && entry.messageType === "user") break;
|
|
14
|
+
if (entry.type === "done") {
|
|
15
|
+
if (entry.code === 0) return i + 1;
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
throw new Error("Cannot safely represent this completed-turn fork boundary in local history");
|
|
20
|
+
}
|
|
21
|
+
module.exports = { endIndex: endIndex };
|
package/lib/session-github.js
CHANGED
|
@@ -33,22 +33,29 @@ function runGh(cwd, args, identity, input) {
|
|
|
33
33
|
}
|
|
34
34
|
async function readReference(cwd, url, identity, run, statusOnly) {
|
|
35
35
|
var ref = parseReference(url);
|
|
36
|
-
var fields = "title,state,url" + (ref.kind === "pr" ? (statusOnly ? ",isDraft" : ",isDraft,headRefName,reviewDecision,statusCheckRollup") : "");
|
|
36
|
+
var fields = "title,state,url" + (ref.kind === "pr" ? (statusOnly ? ",isDraft,reviewDecision,reviewRequests" : ",isDraft,headRefName,reviewDecision,statusCheckRollup") : "");
|
|
37
37
|
var data = await (run || runGh)(cwd, [ref.kind === "pr" ? "pr" : "issue", "view", String(ref.number), "--repo", ref.repository, "--json", fields], identity);
|
|
38
38
|
var verified = parseReference(data.url);
|
|
39
39
|
if (verified.url.toLowerCase() !== ref.url.toLowerCase()) throw new Error("GitHub returned a different reference.");
|
|
40
40
|
ref.title = String(data.title || "").slice(0, 200);
|
|
41
41
|
ref.state = data.state === "MERGED" ? "merged" : data.state === "CLOSED" ? "closed" : data.state === "OPEN" ? (data.isDraft ? "draft" : "open") : "unknown";
|
|
42
42
|
ref.checkedAt = Date.now();
|
|
43
|
+
if (ref.kind === "pr") {
|
|
44
|
+
ref.review = ["APPROVED", "CHANGES_REQUESTED", "REVIEW_REQUIRED"].indexOf(data.reviewDecision) >= 0 ? data.reviewDecision : "";
|
|
45
|
+
}
|
|
43
46
|
if (ref.kind === "pr" && !statusOnly) {
|
|
44
47
|
ref.branch = String(data.headRefName || "").slice(0, 200);
|
|
45
|
-
ref.review = ["APPROVED", "CHANGES_REQUESTED", "REVIEW_REQUIRED"].indexOf(data.reviewDecision) >= 0 ? data.reviewDecision : "";
|
|
46
48
|
ref.checks = (data.statusCheckRollup || []).slice(0, 30).map(function (check) {
|
|
47
49
|
var target = check.detailsUrl || check.targetUrl || "";
|
|
48
50
|
if (!/^https:\/\//i.test(target)) target = "";
|
|
49
51
|
return { name: String(check.name || check.context || "Check").slice(0, 100), state: String(check.conclusion || check.state || check.status || "PENDING").slice(0, 40), url: target };
|
|
50
52
|
});
|
|
51
53
|
}
|
|
54
|
+
if (ref.kind === "pr" && statusOnly) {
|
|
55
|
+
ref.reviewRequests = Array.isArray(data.reviewRequests) ? data.reviewRequests.slice(0, 30).map(function (request) {
|
|
56
|
+
return String(request.login || "").trim().toLowerCase().slice(0, 100);
|
|
57
|
+
}).filter(Boolean) : [];
|
|
58
|
+
}
|
|
52
59
|
return ref;
|
|
53
60
|
}
|
|
54
61
|
module.exports = { parseReference: parseReference, readReference: readReference, runGh: runGh };
|
package/lib/session-hygiene.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
var sessionProvenance = require("./session-provenance");
|
|
6
6
|
|
|
7
7
|
var BLANK_SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
8
|
-
var
|
|
8
|
+
var transcriptHygiene = require("./yoke/claude-transcript-hygiene");
|
|
9
9
|
|
|
10
10
|
// A session is "blank" when nothing has ever happened in it and nothing is
|
|
11
11
|
// attached to it. Adopted external sessions are never blank (their transcript
|
|
@@ -61,43 +61,11 @@ function collectStaleBlankSessions(sessions, activeSessionId, now) {
|
|
|
61
61
|
return stale;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
function extractClaudeUserText(event) {
|
|
65
|
-
var content = event && event.message && event.message.content;
|
|
66
|
-
if (typeof content === "string") return content;
|
|
67
|
-
if (!Array.isArray(content)) return "";
|
|
68
|
-
var parts = [];
|
|
69
|
-
for (var i = 0; i < content.length; i++) {
|
|
70
|
-
if (content[i] && content[i].type === "text" && typeof content[i].text === "string") {
|
|
71
|
-
parts.push(content[i].text);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return parts.join("");
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// SDK capability probes create a real Claude transcript with a single "hi"
|
|
78
|
-
// prompt. Newer Claude Code versions append an interruption record when Clay
|
|
79
|
-
// aborts the probe, so that bookkeeping record must not make the transcript
|
|
80
|
-
// look like a real two-turn conversation.
|
|
81
|
-
function isClaudeWarmupTranscript(events) {
|
|
82
|
-
var promptCount = 0;
|
|
83
|
-
for (var i = 0; i < events.length; i++) {
|
|
84
|
-
var event = events[i];
|
|
85
|
-
if (!event || typeof event !== "object") continue;
|
|
86
|
-
if (event.type === "assistant") return false;
|
|
87
|
-
if (event.type !== "user" || !event.message || event.message.role !== "user") continue;
|
|
88
|
-
var text = extractClaudeUserText(event);
|
|
89
|
-
if (text === CLAUDE_INTERRUPTED_TEXT) continue;
|
|
90
|
-
if (text !== "hi") return false;
|
|
91
|
-
promptCount++;
|
|
92
|
-
}
|
|
93
|
-
return promptCount === 1;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
64
|
module.exports = {
|
|
97
65
|
isBlankSession: isBlankSession,
|
|
98
66
|
findReusableBlankSession: findReusableBlankSession,
|
|
99
67
|
collectStaleBlankSessions: collectStaleBlankSessions,
|
|
100
|
-
extractClaudeUserText: extractClaudeUserText,
|
|
101
|
-
isClaudeWarmupTranscript: isClaudeWarmupTranscript,
|
|
68
|
+
extractClaudeUserText: transcriptHygiene.extractClaudeUserText,
|
|
69
|
+
isClaudeWarmupTranscript: transcriptHygiene.isClaudeWarmupTranscript,
|
|
102
70
|
BLANK_SESSION_MAX_AGE_MS: BLANK_SESSION_MAX_AGE_MS,
|
|
103
71
|
};
|
|
@@ -7,11 +7,12 @@ function normalize(mode) {
|
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
function capabilities(session, defaultVendor) {
|
|
10
|
+
function capabilities(session, defaultVendor, provider) {
|
|
11
11
|
var vendor = session && session.vendor || defaultVendor || "claude";
|
|
12
|
+
var contract = require("./yoke/session-tool-transport").contract(provider || vendor);
|
|
12
13
|
return {
|
|
13
|
-
auto:
|
|
14
|
-
mcpOverride:
|
|
14
|
+
auto: Array.isArray(contract.permissionModes) && contract.permissionModes.indexOf("auto") !== -1,
|
|
15
|
+
mcpOverride: contract.mcpPermissionOverrides === true && !!(session && session.queryInstance &&
|
|
15
16
|
typeof session.queryInstance.setMcpPermissionModeOverride === "function"),
|
|
16
17
|
};
|
|
17
18
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Bind personal instruction reads to the existing live session/query authority.
|
|
2
|
+
function bind(session, sessions, options, valid, multiUser) {
|
|
3
|
+
var owner = session.ownerId || null;
|
|
4
|
+
return Object.assign({}, options, { isAvailable: function() {
|
|
5
|
+
if (!sessions || typeof sessions.get !== "function" || sessions.get(session.localId) !== session || !valid() || (session.ownerId || null) !== owner || session.youCurator || session.sessionVisibility === "shared" || session._mcpForeignInput) return false;
|
|
6
|
+
if (owner) return require("./mcp-session-access").canUsePersonalConnections(session, sessions);
|
|
7
|
+
return !multiUser && !session.delegated && !session._delegatedBy && !session._pairDelegation
|
|
8
|
+
&& !(session.history || []).some(function(entry) { return entry.type === "user_message" && entry.from && entry.from !== "default"; });
|
|
9
|
+
} });
|
|
10
|
+
}
|
|
11
|
+
module.exports = { bind: bind };
|
|
@@ -54,7 +54,7 @@ function handleDefaultChange(ctx, ws, msg) {
|
|
|
54
54
|
? ctx.usersModule.getEffectivePermissions(user, ctx.osUsers) : {};
|
|
55
55
|
var isOwner = !!(user && access && access.ownerId && access.ownerId === user.id);
|
|
56
56
|
var isAdmin = !!(user && user.role === "admin");
|
|
57
|
-
if (!user || !permissions.projectSettings ||
|
|
57
|
+
if (!user || !permissions.projectSettings || !isOwner) {
|
|
58
58
|
defaultChangeResult(ctx, ws, msg, { ok: false, error: "Project settings access is not permitted" });
|
|
59
59
|
return true;
|
|
60
60
|
}
|
|
@@ -98,7 +98,10 @@ function revokeViewers(ctx, session) {
|
|
|
98
98
|
// Clear the server-side selection before reconnecting so no further
|
|
99
99
|
// session events or input can cross the revoked access boundary.
|
|
100
100
|
client._clayActiveSession = null;
|
|
101
|
-
if (client.readyState === 1)
|
|
101
|
+
if (client.readyState === 1) {
|
|
102
|
+
if (ctx.sendTo) ctx.sendTo(client, { type: "access_revoked", slug: ctx.slug });
|
|
103
|
+
client.close(1008, "Session access changed");
|
|
104
|
+
}
|
|
102
105
|
});
|
|
103
106
|
}
|
|
104
107
|
}
|