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
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) {
|
|
@@ -456,6 +507,8 @@ function createServer(opts) {
|
|
|
456
507
|
var linear = require('./server-linear').attachLinear({ users: users, getMultiUserFromReq: getMultiUserFromReq,
|
|
457
508
|
isRequestAuthed: isRequestAuthed, CONFIG_DIR: CONFIG_DIR });
|
|
458
509
|
|
|
510
|
+
var githubStars = require('./server-github-stars').attachGithubStars({ isRequestAuthed: isRequestAuthed });
|
|
511
|
+
|
|
459
512
|
var speech = serverSpeech.attachSpeech({ users: users, getMultiUserFromReq: getMultiUserFromReq,
|
|
460
513
|
isRequestAuthed: isRequestAuthed, CONFIG_DIR: CONFIG_DIR, getAllowedOrigins: getAllowedOrigins });
|
|
461
514
|
|
|
@@ -491,6 +544,41 @@ function createServer(opts) {
|
|
|
491
544
|
},
|
|
492
545
|
});
|
|
493
546
|
|
|
547
|
+
function injectAppearanceSeed(html, appearance) {
|
|
548
|
+
var validId = function (value) {
|
|
549
|
+
return typeof value === "string" && /^[a-zA-Z0-9_-]{1,120}$/.test(value) ? value : null;
|
|
550
|
+
};
|
|
551
|
+
var mode = appearance && ["light", "dark"].indexOf(appearance.mode) >= 0 ? appearance.mode : null;
|
|
552
|
+
var seed = appearance && appearance.configured === true ? {
|
|
553
|
+
configured: true,
|
|
554
|
+
theme: validId(appearance.theme),
|
|
555
|
+
mode: mode,
|
|
556
|
+
lightTheme: validId(appearance.lightTheme),
|
|
557
|
+
darkTheme: validId(appearance.darkTheme),
|
|
558
|
+
} : null;
|
|
559
|
+
var payload = JSON.stringify(seed).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
560
|
+
var script = '<script>window.__clayAppearanceSeed=' + payload + ';</script>';
|
|
561
|
+
return html.replace('<script src="appearance-bootstrap.js"></script>', script + '<script src="appearance-bootstrap.js"></script>');
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
function sendAppShell(req, res, slug) {
|
|
565
|
+
try {
|
|
566
|
+
var shell = fs.readFileSync(path.join(publicDir, "index.html"), "utf8");
|
|
567
|
+
if (slug) shell = injectRootProjectSlug(shell, slug);
|
|
568
|
+
var appearance = null;
|
|
569
|
+
try { appearance = settings.getInitialAppearance(req); } catch (e) {}
|
|
570
|
+
shell = injectAppearanceSeed(shell, appearance);
|
|
571
|
+
res.writeHead(200, {
|
|
572
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
573
|
+
"Cache-Control": "private, no-store",
|
|
574
|
+
});
|
|
575
|
+
res.end(shell);
|
|
576
|
+
} catch (e) {
|
|
577
|
+
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
578
|
+
res.end("App shell missing.");
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
494
582
|
var palette = serverPalette.attachPalette({
|
|
495
583
|
users: users,
|
|
496
584
|
projects: projects,
|
|
@@ -512,7 +600,28 @@ function createServer(opts) {
|
|
|
512
600
|
broadcastAll: function (msg) { broadcastAll(msg); },
|
|
513
601
|
sendToUser: function (userId, msg) { sendToUser(userId, msg); },
|
|
514
602
|
pushModule: pushModule,
|
|
603
|
+
forEachClient: forEachAppClient,
|
|
604
|
+
getUsers: function () { return users.getAllUsers(); },
|
|
605
|
+
canView: function (ws, notification) { return canViewNotification(ws && ws._clayUser && ws._clayUser.id, notification); },
|
|
606
|
+
canViewPrincipal: function (principal, notification) { return canViewNotification(principal.userId, notification); },
|
|
515
607
|
});
|
|
608
|
+
function canViewNotification(userId, notification) {
|
|
609
|
+
if (!users.isMultiUser()) return true;
|
|
610
|
+
if (!userId || !users.findUserById(userId)) return false;
|
|
611
|
+
if (notification.targetUserId && notification.targetUserId !== userId) return false;
|
|
612
|
+
if (notification.slug) {
|
|
613
|
+
if (!canUserAccessSlug(userId, notification.slug)) return false;
|
|
614
|
+
if (notification.sessionId) {
|
|
615
|
+
var project = projects.get(notification.slug);
|
|
616
|
+
var session = project && project.getSessionManager().sessions.get(notification.sessionId);
|
|
617
|
+
var status = project && project.getStatus();
|
|
618
|
+
var access = status && status.isMate ? { isMate: true, visibility: "private", ownerId: status.projectOwnerId } : onGetProjectAccess(notification.slug);
|
|
619
|
+
if (!session || !users.canAccessSession(userId, session, access)) return false;
|
|
620
|
+
}
|
|
621
|
+
return !notification.ownerId || notification.ownerId === userId || !!notification.sessionId;
|
|
622
|
+
}
|
|
623
|
+
return notification.targetUserId === userId || notification.ownerId === userId;
|
|
624
|
+
}
|
|
516
625
|
|
|
517
626
|
// --- Security headers ---
|
|
518
627
|
var securityHeaders = {
|
|
@@ -818,6 +927,7 @@ function createServer(opts) {
|
|
|
818
927
|
|
|
819
928
|
if (linear.handleRequest(req, res, fullUrl)) return;
|
|
820
929
|
if (speech.handleRequest(req, res, fullUrl)) return;
|
|
930
|
+
if (githubStars.handleRequest(req, res, fullUrl)) return;
|
|
821
931
|
if (networkSettings.handleRequest(req, res, fullUrl)) return;
|
|
822
932
|
if (storageSettings.handleRequest(req, res, fullUrl)) return;
|
|
823
933
|
if (settings.handleRequest(req, res, fullUrl)) return;
|
|
@@ -910,15 +1020,7 @@ function createServer(opts) {
|
|
|
910
1020
|
});
|
|
911
1021
|
}
|
|
912
1022
|
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
|
-
}
|
|
1023
|
+
sendAppShell(req, res, targetSlug);
|
|
922
1024
|
return;
|
|
923
1025
|
}
|
|
924
1026
|
}
|
|
@@ -936,9 +1038,7 @@ function createServer(opts) {
|
|
|
936
1038
|
return;
|
|
937
1039
|
}
|
|
938
1040
|
}
|
|
939
|
-
|
|
940
|
-
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
941
|
-
res.end("App shell missing.");
|
|
1041
|
+
sendAppShell(req, res, null);
|
|
942
1042
|
return;
|
|
943
1043
|
}
|
|
944
1044
|
|
|
@@ -955,8 +1055,8 @@ function createServer(opts) {
|
|
|
955
1055
|
var projectList = [];
|
|
956
1056
|
var infoUser = users.isMultiUser() ? getMultiUserFromReq(req) : null;
|
|
957
1057
|
projects.forEach(function (ctx, slug) {
|
|
958
|
-
if (users.isMultiUser() && (!infoUser || !canUserAccessSlug(infoUser.id, slug))) return;
|
|
959
|
-
projectList.push({ slug: slug, project: ctx.project });
|
|
1058
|
+
if (users.isMultiUser() && (!infoUser || (!canUserAccessSlug(infoUser.id, slug) && !administrativeMetadata(infoUser.id, slug)))) return;
|
|
1059
|
+
projectList.push({ slug: slug, project: ctx.project, contentAccess: !users.isMultiUser() || canUserAccessSlug(infoUser.id, slug) });
|
|
960
1060
|
});
|
|
961
1061
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
962
1062
|
res.end(JSON.stringify({ projects: projectList, version: currentVersion, authenticated: true }));
|
|
@@ -965,6 +1065,10 @@ function createServer(opts) {
|
|
|
965
1065
|
|
|
966
1066
|
// Static files (favicon, manifest, icons, sw.js, mate avatars, etc.)
|
|
967
1067
|
if (!fullUrl.includes("..") && !fullUrl.startsWith("/p/") && !fullUrl.startsWith("/api/")) {
|
|
1068
|
+
if (fullUrl === "/index.html") {
|
|
1069
|
+
sendAppShell(req, res, null);
|
|
1070
|
+
return;
|
|
1071
|
+
}
|
|
968
1072
|
if (serveStatic(fullUrl, res)) return;
|
|
969
1073
|
}
|
|
970
1074
|
|
|
@@ -1028,8 +1132,14 @@ function createServer(opts) {
|
|
|
1028
1132
|
if (users.isMultiUser() && !isMcpBridgeAuthenticated) {
|
|
1029
1133
|
var httpUser = getMultiUserFromReq(req);
|
|
1030
1134
|
if (!httpUser || !canUserAccessSlug(httpUser.id, slug)) {
|
|
1031
|
-
|
|
1032
|
-
|
|
1135
|
+
var overview = httpUser && administrativeMetadata(httpUser.id, slug);
|
|
1136
|
+
if (overview && req.method === "GET" && (projectUrlForAuth === "/" || projectUrlForAuth === "/index.html")) {
|
|
1137
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" });
|
|
1138
|
+
res.end(projectAdminOverview.page(overview, getVisibleProjects(httpUser.id)));
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
res.writeHead(403, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
1142
|
+
res.end(JSON.stringify({ error: "Project content access is not permitted" }));
|
|
1033
1143
|
return;
|
|
1034
1144
|
}
|
|
1035
1145
|
}
|
|
@@ -1054,6 +1164,10 @@ function createServer(opts) {
|
|
|
1054
1164
|
|
|
1055
1165
|
// Static files (same assets for all projects)
|
|
1056
1166
|
if (req.method === "GET") {
|
|
1167
|
+
if (projectUrl === "/" || projectUrl === "/index.html") {
|
|
1168
|
+
sendAppShell(req, res, slug);
|
|
1169
|
+
return;
|
|
1170
|
+
}
|
|
1057
1171
|
if (serveStatic(projectUrl, res)) return;
|
|
1058
1172
|
}
|
|
1059
1173
|
|
|
@@ -1134,6 +1248,7 @@ function createServer(opts) {
|
|
|
1134
1248
|
var globalWs = serverGlobalWs.attachGlobalWs({
|
|
1135
1249
|
osUsers: osUsers,
|
|
1136
1250
|
usersModule: users,
|
|
1251
|
+
canUsePath: canUsePath,
|
|
1137
1252
|
onAddProject: onAddProject,
|
|
1138
1253
|
onCreateProject: onCreateProject,
|
|
1139
1254
|
onCloneProject: onCloneProject,
|
|
@@ -1185,6 +1300,7 @@ function createServer(opts) {
|
|
|
1185
1300
|
if (!require('./account-auth-socket').guardSocket(ws, req, isRequestAuthed, auth.touchSession)) return;
|
|
1186
1301
|
ws._clayPane = wsRequest.pane;
|
|
1187
1302
|
ws._clayPaneSession = wsRequest.paneSession;
|
|
1303
|
+
ws._clayContextual = wsRequest.contextual;
|
|
1188
1304
|
globalWs.handleConnection(ws, globalUser);
|
|
1189
1305
|
});
|
|
1190
1306
|
return;
|
|
@@ -1230,6 +1346,7 @@ function createServer(opts) {
|
|
|
1230
1346
|
ws._clayUser = wsUser; // attach user context
|
|
1231
1347
|
ws._clayPane = wsRequest.pane;
|
|
1232
1348
|
ws._clayPaneSession = wsRequest.paneSession;
|
|
1349
|
+
ws._clayContextual = wsRequest.contextual;
|
|
1233
1350
|
var remoteAddr = req.socket.remoteAddress || "";
|
|
1234
1351
|
ws._clayLocal = (remoteAddr === "127.0.0.1" || remoteAddr === "::1" || remoteAddr === "::ffff:127.0.0.1");
|
|
1235
1352
|
// Clear cross-project unread for this project when client connects
|
|
@@ -1274,17 +1391,10 @@ function createServer(opts) {
|
|
|
1274
1391
|
if (processingUpdateTimer) clearTimeout(processingUpdateTimer);
|
|
1275
1392
|
processingUpdateTimer = setTimeout(function () {
|
|
1276
1393
|
processingUpdateTimer = null;
|
|
1277
|
-
var allProjectsList = getProjects();
|
|
1278
1394
|
// Always send per-client to include cross-project unread counts
|
|
1279
1395
|
projects.forEach(function (ctx, projSlug) {
|
|
1280
1396
|
ctx.forEachClient(function (ws) {
|
|
1281
|
-
var filtered =
|
|
1282
|
-
if (users.isMultiUser() && onGetProjectAccess) {
|
|
1283
|
-
var wsUser = ws._clayUser;
|
|
1284
|
-
filtered = wsUser ? allProjectsList.filter(function (p) {
|
|
1285
|
-
return canUserAccessSlug(wsUser.id, p.slug);
|
|
1286
|
-
}) : [];
|
|
1287
|
-
}
|
|
1397
|
+
var filtered = getVisibleProjects(ws._clayUser ? ws._clayUser.id : null);
|
|
1288
1398
|
// Attach per-project unread counts for this client
|
|
1289
1399
|
var unreadMap = getCrossProjectUnread(ws);
|
|
1290
1400
|
var projectsWithUnread = filtered.map(function (p) {
|
|
@@ -1334,6 +1444,10 @@ function createServer(opts) {
|
|
|
1334
1444
|
function addProject(cwd, slug, title, icon, projectOwnerId, worktreeMeta, extraOpts) {
|
|
1335
1445
|
if (projects.has(slug)) return false;
|
|
1336
1446
|
var extra = extraOpts || {};
|
|
1447
|
+
if (extra.isMate) {
|
|
1448
|
+
var registeredMate = mates.getMate(mates.buildMateCtx(users.isMultiUser() ? projectOwnerId : null), extra.mateId || path.basename(cwd));
|
|
1449
|
+
if (registeredMate && registeredMate.lifecycleDeletion) return false;
|
|
1450
|
+
}
|
|
1337
1451
|
var ctx = createProjectContext({
|
|
1338
1452
|
cwd: cwd,
|
|
1339
1453
|
slug: slug,
|
|
@@ -1353,6 +1467,9 @@ function createServer(opts) {
|
|
|
1353
1467
|
return mateHandler.createReadyMateFromInterview(ws, userId, definition);
|
|
1354
1468
|
},
|
|
1355
1469
|
workspaceQueryService: workspaceQueryService,
|
|
1470
|
+
clayProductControl: clayProductControl,
|
|
1471
|
+
mateContextService: mateContextService,
|
|
1472
|
+
resumeLifecycleProject: function (userId) { return opts.projectLifecycle ? opts.projectLifecycle.resumeRecovered(slug, userId) : true; },
|
|
1356
1473
|
projectLogsService: projectLogsService,
|
|
1357
1474
|
issuesService: issuesService,
|
|
1358
1475
|
linearStorage: linear.storage,
|
|
@@ -1374,13 +1491,19 @@ function createServer(opts) {
|
|
|
1374
1491
|
return !!(access && !access.error && users.canAccessProject(userId, access));
|
|
1375
1492
|
},
|
|
1376
1493
|
getProjectAccess: function () {
|
|
1377
|
-
if (extra.isMate)
|
|
1494
|
+
if (extra.isMate) {
|
|
1495
|
+
var mate = mates.getMate(mates.buildMateCtx(users.isMultiUser() ? projectOwnerId : null), extra.mateId || path.basename(cwd));
|
|
1496
|
+
return { isMate: true, visibility: "private", ownerId: projectOwnerId || null, allowedUsers: [], lifecycleExecutionPaused: !mate || !!mate.lifecycleDeletion };
|
|
1497
|
+
}
|
|
1378
1498
|
return onGetProjectAccess ? onGetProjectAccess(slug) : { visibility: "public", ownerId: projectOwnerId || null };
|
|
1379
1499
|
},
|
|
1380
1500
|
shouldSuppressResponseNotification: function (session) {
|
|
1381
1501
|
return shouldSuppressHomeResponse(projects, slug, session);
|
|
1382
1502
|
},
|
|
1383
|
-
pushModule: pushModule,
|
|
1503
|
+
pushModule: require("./project-push-access").scopedPush(pushModule, {
|
|
1504
|
+
slug: slug, users: users, getProject: function (target) { return projects.get(target); },
|
|
1505
|
+
canAccessProject: canUserAccessSlug, getAccess: onGetProjectAccess,
|
|
1506
|
+
}),
|
|
1384
1507
|
debug: debug,
|
|
1385
1508
|
dangerouslySkipPermissions: dangerouslySkipPermissions,
|
|
1386
1509
|
osUsers: osUsers,
|
|
@@ -1412,6 +1535,7 @@ function createServer(opts) {
|
|
|
1412
1535
|
var status = ctx.getStatus();
|
|
1413
1536
|
var recs = ctx.getSchedules();
|
|
1414
1537
|
for (var i = 0; i < recs.length; i++) {
|
|
1538
|
+
if (users.isMultiUser() && recs[i].ownerId !== userId) continue;
|
|
1415
1539
|
// Shallow-copy full record and augment with project metadata
|
|
1416
1540
|
var copy = {};
|
|
1417
1541
|
var keys = Object.keys(recs[i]);
|
|
@@ -1469,6 +1593,8 @@ function createServer(opts) {
|
|
|
1469
1593
|
return ctx.getSchedules().length;
|
|
1470
1594
|
},
|
|
1471
1595
|
canAccessProjectSlug: canUserAccessSlug,
|
|
1596
|
+
onGetProjectAccess: onGetProjectAccess,
|
|
1597
|
+
canUsePath: canUsePath,
|
|
1472
1598
|
onPresenceChange: broadcastPresenceChange,
|
|
1473
1599
|
onProcessingChanged: broadcastProcessingChange,
|
|
1474
1600
|
onSessionDone: function () { onSessionDone(slug); },
|
|
@@ -1622,6 +1748,8 @@ function createServer(opts) {
|
|
|
1622
1748
|
}
|
|
1623
1749
|
|
|
1624
1750
|
function handleDmMessage(ws, msg, routedProjectSlug) {
|
|
1751
|
+
if (ownerUiService.handleMessage(ws, msg)) return true;
|
|
1752
|
+
if (mateContextService.handleMessage(ws, msg)) return true;
|
|
1625
1753
|
if (cursorSharingService && cursorSharingService.handleMessage(ws, msg)) return true;
|
|
1626
1754
|
if (defaultVendorService && defaultVendorService.handleMessage(ws, msg, routedProjectSlug)) return true;
|
|
1627
1755
|
if (contextViewService && contextViewService.handleMessage(ws, msg)) return true;
|
|
@@ -1630,25 +1758,14 @@ function createServer(opts) {
|
|
|
1630
1758
|
if (dmHandler.handleMessage(ws, msg)) return true;
|
|
1631
1759
|
if (mateHandler && mateHandler.handleMessage(ws, msg)) return true;
|
|
1632
1760
|
if (emailHandler.handleMessage(ws, msg)) return true;
|
|
1633
|
-
if (homeChatHandler.handleMessage(ws, msg)) return true;
|
|
1761
|
+
if (homeChatHandler.handleMessage(ws, msg, routedProjectSlug)) return true;
|
|
1634
1762
|
if (homePreferencesHandler.handleMessage(ws, msg)) return true;
|
|
1635
1763
|
if (toolsHandler.handleMessage(ws, msg)) return true;
|
|
1636
1764
|
return false;
|
|
1637
1765
|
}
|
|
1638
1766
|
|
|
1639
|
-
function removeProject(slug) {
|
|
1640
|
-
|
|
1641
|
-
if (!ctx) return false;
|
|
1642
|
-
var wasMate = ctx.getStatus().isMate;
|
|
1643
|
-
var shutdownResult = ctx.destroy();
|
|
1644
|
-
projects.delete(slug);
|
|
1645
|
-
if (shutdownResult && typeof shutdownResult.catch === "function") {
|
|
1646
|
-
shutdownResult.catch(function(err) {
|
|
1647
|
-
console.error("[server] Project destroy failed for " + slug + ":", err && err.message ? err.message : err);
|
|
1648
|
-
});
|
|
1649
|
-
}
|
|
1650
|
-
if (!wasMate) scheduleRegistryRefresh();
|
|
1651
|
-
return true;
|
|
1767
|
+
function removeProject(slug, awaitCompletion) {
|
|
1768
|
+
return require('./server-project-removal').removeProjectRuntime(projects, slug, awaitCompletion, scheduleRegistryRefresh);
|
|
1652
1769
|
}
|
|
1653
1770
|
|
|
1654
1771
|
// Now that addProject and removeProject are defined, initialize mateHandler
|
|
@@ -1734,7 +1851,11 @@ function createServer(opts) {
|
|
|
1734
1851
|
function getVisibleProjects(userId) {
|
|
1735
1852
|
var visible = [];
|
|
1736
1853
|
projects.forEach(function (ctx, slug) {
|
|
1737
|
-
if (users.isMultiUser() && (!userId || !canUserAccessSlug(userId, slug)))
|
|
1854
|
+
if (users.isMultiUser() && (!userId || !canUserAccessSlug(userId, slug))) {
|
|
1855
|
+
var metadata = administrativeMetadata(userId, slug);
|
|
1856
|
+
if (metadata) visible.push(metadata);
|
|
1857
|
+
return;
|
|
1858
|
+
}
|
|
1738
1859
|
var status = ctx.getStatus();
|
|
1739
1860
|
if (!status.isMate && onGetProjectAccess) {
|
|
1740
1861
|
var access = onGetProjectAccess(slug);
|
|
@@ -1933,6 +2054,7 @@ function createServer(opts) {
|
|
|
1933
2054
|
speech.destroy();
|
|
1934
2055
|
var shutdowns = [];
|
|
1935
2056
|
shutdowns.push(durableSchedulerLifecycle.shutdown());
|
|
2057
|
+
shutdowns.push(lifecycleRuntime.shutdown());
|
|
1936
2058
|
projects.forEach(function (ctx, slug) {
|
|
1937
2059
|
console.log("[server] Destroying project:", slug);
|
|
1938
2060
|
var result = ctx.destroy();
|
|
@@ -2000,6 +2122,8 @@ function createServer(opts) {
|
|
|
2000
2122
|
isTLS: !!tlsOptions,
|
|
2001
2123
|
addProject: addProject,
|
|
2002
2124
|
removeProject: removeProject,
|
|
2125
|
+
getProjectLifecycleTargets: lifecycleRuntime.targets,
|
|
2126
|
+
closeProjectLifecycle: lifecycleRuntime.close,
|
|
2003
2127
|
getProjects: getProjects,
|
|
2004
2128
|
reorderProjects: reorderProjects,
|
|
2005
2129
|
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
|
};
|