@theihtisham/agent-shadow-brain 7.2.0 → 7.22.0
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/CHANGELOG.md +478 -429
- package/README.md +198 -68
- package/dist/activity-cli.d.ts +3 -0
- package/dist/activity-cli.d.ts.map +1 -0
- package/dist/activity-cli.js +78 -0
- package/dist/activity-cli.js.map +1 -0
- package/dist/adapters/index.d.ts +2 -1
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +3 -2
- package/dist/adapters/index.js.map +1 -1
- package/dist/brain/activity-journal.d.ts +82 -0
- package/dist/brain/activity-journal.d.ts.map +1 -0
- package/dist/brain/activity-journal.js +315 -0
- package/dist/brain/activity-journal.js.map +1 -0
- package/dist/brain/activity-reporting.d.ts +14 -0
- package/dist/brain/activity-reporting.d.ts.map +1 -0
- package/dist/brain/activity-reporting.js +17 -0
- package/dist/brain/activity-reporting.js.map +1 -0
- package/dist/brain/auto-update.js +1 -1
- package/dist/brain/auto-update.js.map +1 -1
- package/dist/brain/brain-portability.js +1 -1
- package/dist/brain/brain-portability.js.map +1 -1
- package/dist/brain/client-config.d.ts +19 -0
- package/dist/brain/client-config.d.ts.map +1 -0
- package/dist/brain/client-config.js +40 -0
- package/dist/brain/client-config.js.map +1 -0
- package/dist/brain/client-integrations.d.ts +63 -0
- package/dist/brain/client-integrations.d.ts.map +1 -0
- package/dist/brain/client-integrations.js +79 -0
- package/dist/brain/client-integrations.js.map +1 -0
- package/dist/brain/context-assembly.d.ts +41 -5
- package/dist/brain/context-assembly.d.ts.map +1 -1
- package/dist/brain/context-assembly.js +366 -35
- package/dist/brain/context-assembly.js.map +1 -1
- package/dist/brain/context-efficiency.d.ts +48 -0
- package/dist/brain/context-efficiency.d.ts.map +1 -0
- package/dist/brain/context-efficiency.js +34 -0
- package/dist/brain/context-efficiency.js.map +1 -0
- package/dist/brain/context-request.d.ts +4 -0
- package/dist/brain/context-request.d.ts.map +1 -0
- package/dist/brain/context-request.js +24 -0
- package/dist/brain/context-request.js.map +1 -0
- package/dist/brain/context-retrieval.d.ts +88 -0
- package/dist/brain/context-retrieval.d.ts.map +1 -0
- package/dist/brain/context-retrieval.js +301 -0
- package/dist/brain/context-retrieval.js.map +1 -0
- package/dist/brain/feature-settings.d.ts +10 -0
- package/dist/brain/feature-settings.d.ts.map +1 -1
- package/dist/brain/feature-settings.js +18 -2
- package/dist/brain/feature-settings.js.map +1 -1
- package/dist/brain/file-identity.d.ts +4 -0
- package/dist/brain/file-identity.d.ts.map +1 -0
- package/dist/brain/file-identity.js +27 -0
- package/dist/brain/file-identity.js.map +1 -0
- package/dist/brain/global-brain.d.ts +18 -2
- package/dist/brain/global-brain.d.ts.map +1 -1
- package/dist/brain/global-brain.js +75 -7
- package/dist/brain/global-brain.js.map +1 -1
- package/dist/brain/managed-project-skills.d.ts +48 -0
- package/dist/brain/managed-project-skills.d.ts.map +1 -0
- package/dist/brain/managed-project-skills.js +230 -0
- package/dist/brain/managed-project-skills.js.map +1 -0
- package/dist/brain/mcp-presence.d.ts +50 -0
- package/dist/brain/mcp-presence.d.ts.map +1 -0
- package/dist/brain/mcp-presence.js +214 -0
- package/dist/brain/mcp-presence.js.map +1 -0
- package/dist/brain/mcp-server.d.ts +40 -1
- package/dist/brain/mcp-server.d.ts.map +1 -1
- package/dist/brain/mcp-server.js +506 -52
- package/dist/brain/mcp-server.js.map +1 -1
- package/dist/brain/mcp-stdio.d.ts +12 -0
- package/dist/brain/mcp-stdio.d.ts.map +1 -0
- package/dist/brain/mcp-stdio.js +158 -0
- package/dist/brain/mcp-stdio.js.map +1 -0
- package/dist/brain/memory-annotations.d.ts +99 -0
- package/dist/brain/memory-annotations.d.ts.map +1 -0
- package/dist/brain/memory-annotations.js +402 -0
- package/dist/brain/memory-annotations.js.map +1 -0
- package/dist/brain/memory-graph.d.ts.map +1 -1
- package/dist/brain/memory-graph.js +12 -23
- package/dist/brain/memory-graph.js.map +1 -1
- package/dist/brain/memory-inspection.d.ts +73 -0
- package/dist/brain/memory-inspection.d.ts.map +1 -0
- package/dist/brain/memory-inspection.js +131 -0
- package/dist/brain/memory-inspection.js.map +1 -0
- package/dist/brain/memory-mcp-content.d.ts +46 -0
- package/dist/brain/memory-mcp-content.d.ts.map +1 -0
- package/dist/brain/memory-mcp-content.js +95 -0
- package/dist/brain/memory-mcp-content.js.map +1 -0
- package/dist/brain/memory-sources.d.ts +8 -0
- package/dist/brain/memory-sources.d.ts.map +1 -0
- package/dist/brain/memory-sources.js +27 -0
- package/dist/brain/memory-sources.js.map +1 -0
- package/dist/brain/model-registry.d.ts +4 -5
- package/dist/brain/model-registry.d.ts.map +1 -1
- package/dist/brain/model-registry.js +22 -207
- package/dist/brain/model-registry.js.map +1 -1
- package/dist/brain/model-usage.d.ts +66 -0
- package/dist/brain/model-usage.d.ts.map +1 -0
- package/dist/brain/model-usage.js +246 -0
- package/dist/brain/model-usage.js.map +1 -0
- package/dist/brain/native-codex.d.ts +105 -0
- package/dist/brain/native-codex.d.ts.map +1 -0
- package/dist/brain/native-codex.js +292 -0
- package/dist/brain/native-codex.js.map +1 -0
- package/dist/brain/native-session-import.d.ts +56 -0
- package/dist/brain/native-session-import.d.ts.map +1 -0
- package/dist/brain/native-session-import.js +307 -0
- package/dist/brain/native-session-import.js.map +1 -0
- package/dist/brain/orchestrator.js +1 -1
- package/dist/brain/orchestrator.js.map +1 -1
- package/dist/brain/project-feedback.d.ts +63 -0
- package/dist/brain/project-feedback.d.ts.map +1 -0
- package/dist/brain/project-feedback.js +300 -0
- package/dist/brain/project-feedback.js.map +1 -0
- package/dist/brain/project-hub-contract.d.ts +332 -0
- package/dist/brain/project-hub-contract.d.ts.map +1 -0
- package/dist/brain/project-hub-contract.js +57 -0
- package/dist/brain/project-hub-contract.js.map +1 -0
- package/dist/brain/project-hub-mcp.d.ts +182 -0
- package/dist/brain/project-hub-mcp.d.ts.map +1 -0
- package/dist/brain/project-hub-mcp.js +46 -0
- package/dist/brain/project-hub-mcp.js.map +1 -0
- package/dist/brain/project-hub-pdf-worker.d.ts +13 -0
- package/dist/brain/project-hub-pdf-worker.d.ts.map +1 -0
- package/dist/brain/project-hub-pdf-worker.js +84 -0
- package/dist/brain/project-hub-pdf-worker.js.map +1 -0
- package/dist/brain/project-hub-store.d.ts +50 -0
- package/dist/brain/project-hub-store.d.ts.map +1 -0
- package/dist/brain/project-hub-store.js +257 -0
- package/dist/brain/project-hub-store.js.map +1 -0
- package/dist/brain/project-hub.d.ts +132 -0
- package/dist/brain/project-hub.d.ts.map +1 -0
- package/dist/brain/project-hub.js +403 -0
- package/dist/brain/project-hub.js.map +1 -0
- package/dist/brain/project-kit-inspection.d.ts +28 -0
- package/dist/brain/project-kit-inspection.d.ts.map +1 -0
- package/dist/brain/project-kit-inspection.js +200 -0
- package/dist/brain/project-kit-inspection.js.map +1 -0
- package/dist/brain/project-kit-paths.d.ts +13 -0
- package/dist/brain/project-kit-paths.d.ts.map +1 -0
- package/dist/brain/project-kit-paths.js +141 -0
- package/dist/brain/project-kit-paths.js.map +1 -0
- package/dist/brain/project-kit.d.ts +51 -0
- package/dist/brain/project-kit.d.ts.map +1 -0
- package/dist/brain/project-kit.js +319 -0
- package/dist/brain/project-kit.js.map +1 -0
- package/dist/brain/project-memory.d.ts +38 -0
- package/dist/brain/project-memory.d.ts.map +1 -0
- package/dist/brain/project-memory.js +76 -0
- package/dist/brain/project-memory.js.map +1 -0
- package/dist/brain/project-policy-delivery.d.ts +8 -0
- package/dist/brain/project-policy-delivery.d.ts.map +1 -0
- package/dist/brain/project-policy-delivery.js +38 -0
- package/dist/brain/project-policy-delivery.js.map +1 -0
- package/dist/brain/project-policy.d.ts +88 -0
- package/dist/brain/project-policy.d.ts.map +1 -0
- package/dist/brain/project-policy.js +267 -0
- package/dist/brain/project-policy.js.map +1 -0
- package/dist/brain/project-session-contract.d.ts +180 -0
- package/dist/brain/project-session-contract.d.ts.map +1 -0
- package/dist/brain/project-session-contract.js +50 -0
- package/dist/brain/project-session-contract.js.map +1 -0
- package/dist/brain/project-session-mcp.d.ts +145 -0
- package/dist/brain/project-session-mcp.d.ts.map +1 -0
- package/dist/brain/project-session-mcp.js +58 -0
- package/dist/brain/project-session-mcp.js.map +1 -0
- package/dist/brain/project-sessions.d.ts +97 -0
- package/dist/brain/project-sessions.d.ts.map +1 -0
- package/dist/brain/project-sessions.js +223 -0
- package/dist/brain/project-sessions.js.map +1 -0
- package/dist/brain/project-source-contract.d.ts +109 -0
- package/dist/brain/project-source-contract.d.ts.map +1 -0
- package/dist/brain/project-source-contract.js +2 -0
- package/dist/brain/project-source-contract.js.map +1 -0
- package/dist/brain/project-source-intake.d.ts +26 -0
- package/dist/brain/project-source-intake.d.ts.map +1 -0
- package/dist/brain/project-source-intake.js +457 -0
- package/dist/brain/project-source-intake.js.map +1 -0
- package/dist/brain/subconscious.d.ts +3 -1
- package/dist/brain/subconscious.d.ts.map +1 -1
- package/dist/brain/subconscious.js +8 -3
- package/dist/brain/subconscious.js.map +1 -1
- package/dist/brain/workflow-skills.d.ts +5 -5
- package/dist/brain/workflow-skills.d.ts.map +1 -1
- package/dist/brain/workflow-skills.js +3 -2
- package/dist/brain/workflow-skills.js.map +1 -1
- package/dist/cli.js +37 -3
- package/dist/cli.js.map +1 -1
- package/dist/context-cli.d.ts.map +1 -1
- package/dist/context-cli.js +49 -7
- package/dist/context-cli.js.map +1 -1
- package/dist/curation-cli.d.ts +4 -0
- package/dist/curation-cli.d.ts.map +1 -0
- package/dist/curation-cli.js +118 -0
- package/dist/curation-cli.js.map +1 -0
- package/dist/dashboard/brain-hub-actions.d.ts +2 -0
- package/dist/dashboard/brain-hub-actions.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-actions.js +234 -0
- package/dist/dashboard/brain-hub-actions.js.map +1 -0
- package/dist/dashboard/brain-hub-agent-dock.d.ts +2 -0
- package/dist/dashboard/brain-hub-agent-dock.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-agent-dock.js +255 -0
- package/dist/dashboard/brain-hub-agent-dock.js.map +1 -0
- package/dist/dashboard/brain-hub-brand-icons.d.ts +2 -0
- package/dist/dashboard/brain-hub-brand-icons.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-brand-icons.js +9 -0
- package/dist/dashboard/brain-hub-brand-icons.js.map +1 -0
- package/dist/dashboard/brain-hub-client.d.ts +2 -0
- package/dist/dashboard/brain-hub-client.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-client.js +435 -0
- package/dist/dashboard/brain-hub-client.js.map +1 -0
- package/dist/dashboard/brain-hub-context.d.ts +2 -0
- package/dist/dashboard/brain-hub-context.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-context.js +37 -0
- package/dist/dashboard/brain-hub-context.js.map +1 -0
- package/dist/dashboard/brain-hub-controls.d.ts +2 -0
- package/dist/dashboard/brain-hub-controls.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-controls.js +63 -0
- package/dist/dashboard/brain-hub-controls.js.map +1 -0
- package/dist/dashboard/brain-hub-exchanges.d.ts +2 -0
- package/dist/dashboard/brain-hub-exchanges.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-exchanges.js +82 -0
- package/dist/dashboard/brain-hub-exchanges.js.map +1 -0
- package/dist/dashboard/brain-hub-graph.d.ts +2 -0
- package/dist/dashboard/brain-hub-graph.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-graph.js +338 -0
- package/dist/dashboard/brain-hub-graph.js.map +1 -0
- package/dist/dashboard/brain-hub-html.d.ts +2 -0
- package/dist/dashboard/brain-hub-html.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-html.js +85 -0
- package/dist/dashboard/brain-hub-html.js.map +1 -0
- package/dist/dashboard/brain-hub-knowledge.d.ts +2 -0
- package/dist/dashboard/brain-hub-knowledge.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-knowledge.js +33 -0
- package/dist/dashboard/brain-hub-knowledge.js.map +1 -0
- package/dist/dashboard/brain-hub-live.d.ts +2 -0
- package/dist/dashboard/brain-hub-live.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-live.js +151 -0
- package/dist/dashboard/brain-hub-live.js.map +1 -0
- package/dist/dashboard/brain-hub-managed-skills.d.ts +2 -0
- package/dist/dashboard/brain-hub-managed-skills.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-managed-skills.js +20 -0
- package/dist/dashboard/brain-hub-managed-skills.js.map +1 -0
- package/dist/dashboard/brain-hub-native.d.ts +2 -0
- package/dist/dashboard/brain-hub-native.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-native.js +44 -0
- package/dist/dashboard/brain-hub-native.js.map +1 -0
- package/dist/dashboard/brain-hub-project-views.d.ts +2 -0
- package/dist/dashboard/brain-hub-project-views.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-project-views.js +80 -0
- package/dist/dashboard/brain-hub-project-views.js.map +1 -0
- package/dist/dashboard/brain-hub-sessions.d.ts +2 -0
- package/dist/dashboard/brain-hub-sessions.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-sessions.js +40 -0
- package/dist/dashboard/brain-hub-sessions.js.map +1 -0
- package/dist/dashboard/brain-hub-usage.d.ts +2 -0
- package/dist/dashboard/brain-hub-usage.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-usage.js +28 -0
- package/dist/dashboard/brain-hub-usage.js.map +1 -0
- package/dist/dashboard/brain-hub-views.d.ts +2 -0
- package/dist/dashboard/brain-hub-views.d.ts.map +1 -0
- package/dist/dashboard/brain-hub-views.js +155 -0
- package/dist/dashboard/brain-hub-views.js.map +1 -0
- package/dist/dashboard/demo-workspace.d.ts +11 -0
- package/dist/dashboard/demo-workspace.d.ts.map +1 -0
- package/dist/dashboard/demo-workspace.js +178 -0
- package/dist/dashboard/demo-workspace.js.map +1 -0
- package/dist/dashboard/live-workspace-html.d.ts +2 -0
- package/dist/dashboard/live-workspace-html.d.ts.map +1 -0
- package/dist/dashboard/live-workspace-html.js +1042 -0
- package/dist/dashboard/live-workspace-html.js.map +1 -0
- package/dist/dashboard/managed-project-skills-api.d.ts +29 -0
- package/dist/dashboard/managed-project-skills-api.d.ts.map +1 -0
- package/dist/dashboard/managed-project-skills-api.js +28 -0
- package/dist/dashboard/managed-project-skills-api.js.map +1 -0
- package/dist/dashboard/native-codex-api.d.ts +83 -0
- package/dist/dashboard/native-codex-api.d.ts.map +1 -0
- package/dist/dashboard/native-codex-api.js +91 -0
- package/dist/dashboard/native-codex-api.js.map +1 -0
- package/dist/dashboard/project-feedback-html.d.ts +5 -0
- package/dist/dashboard/project-feedback-html.d.ts.map +1 -0
- package/dist/dashboard/project-feedback-html.js +216 -0
- package/dist/dashboard/project-feedback-html.js.map +1 -0
- package/dist/dashboard/project-file-watch.d.ts +46 -0
- package/dist/dashboard/project-file-watch.d.ts.map +1 -0
- package/dist/dashboard/project-file-watch.js +221 -0
- package/dist/dashboard/project-file-watch.js.map +1 -0
- package/dist/dashboard/project-hub-api.d.ts +5 -0
- package/dist/dashboard/project-hub-api.d.ts.map +1 -0
- package/dist/dashboard/project-hub-api.js +121 -0
- package/dist/dashboard/project-hub-api.js.map +1 -0
- package/dist/dashboard/project-kit-html.d.ts +4 -0
- package/dist/dashboard/project-kit-html.d.ts.map +1 -0
- package/dist/dashboard/project-kit-html.js +359 -0
- package/dist/dashboard/project-kit-html.js.map +1 -0
- package/dist/dashboard/project-live-stream.d.ts +33 -0
- package/dist/dashboard/project-live-stream.d.ts.map +1 -0
- package/dist/dashboard/project-live-stream.js +233 -0
- package/dist/dashboard/project-live-stream.js.map +1 -0
- package/dist/dashboard/project-policy-api.d.ts +37 -0
- package/dist/dashboard/project-policy-api.d.ts.map +1 -0
- package/dist/dashboard/project-policy-api.js +31 -0
- package/dist/dashboard/project-policy-api.js.map +1 -0
- package/dist/dashboard/project-session-api.d.ts +28 -0
- package/dist/dashboard/project-session-api.d.ts.map +1 -0
- package/dist/dashboard/project-session-api.js +84 -0
- package/dist/dashboard/project-session-api.js.map +1 -0
- package/dist/dashboard/project-source-api.d.ts +11 -0
- package/dist/dashboard/project-source-api.d.ts.map +1 -0
- package/dist/dashboard/project-source-api.js +67 -0
- package/dist/dashboard/project-source-api.js.map +1 -0
- package/dist/dashboard/project-workspace.d.ts +16 -0
- package/dist/dashboard/project-workspace.d.ts.map +1 -0
- package/dist/dashboard/project-workspace.js +124 -0
- package/dist/dashboard/project-workspace.js.map +1 -0
- package/dist/dashboard/server.d.ts +1 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +99 -42
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts.map +1 -1
- package/dist/dashboard/v6-dashboard-html.js +4261 -4309
- package/dist/dashboard/v6-dashboard-html.js.map +1 -1
- package/dist/dashboard/workspace-api.d.ts +12 -0
- package/dist/dashboard/workspace-api.d.ts.map +1 -1
- package/dist/dashboard/workspace-api.js +359 -41
- package/dist/dashboard/workspace-api.js.map +1 -1
- package/dist/dashboard/workspace-html.d.ts.map +1 -1
- package/dist/dashboard/workspace-html.js +1118 -135
- package/dist/dashboard/workspace-html.js.map +1 -1
- package/dist/dashboard/workspace-status.d.ts +53 -0
- package/dist/dashboard/workspace-status.d.ts.map +1 -0
- package/dist/dashboard/workspace-status.js +23 -0
- package/dist/dashboard/workspace-status.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/integration-cli.d.ts +3 -0
- package/dist/integration-cli.d.ts.map +1 -0
- package/dist/integration-cli.js +16 -0
- package/dist/integration-cli.js.map +1 -0
- package/dist/project-cli.d.ts +3 -0
- package/dist/project-cli.d.ts.map +1 -0
- package/dist/project-cli.js +100 -0
- package/dist/project-cli.js.map +1 -0
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/docs/BRAND_ASSETS.md +36 -0
- package/docs/COMPARISON.md +22 -0
- package/docs/COMPONENTS.md +66 -0
- package/docs/CONTEXT_LAB.md +79 -0
- package/docs/FEATURES_AND_LIMITS.md +29 -0
- package/docs/INTEGRATIONS.md +70 -0
- package/docs/LEARNING.md +46 -0
- package/docs/PROJECT_KIT.md +98 -0
- package/docs/QUICKSTART.md +62 -0
- package/docs/README.md +36 -0
- package/docs/ROADMAP-v7.md +147 -0
- package/docs/SESSIONS.md +77 -0
- package/docs/SHARING.md +13 -0
- package/docs/SHOWCASE.md +87 -0
- package/docs/SOURCE_INTAKE.md +33 -0
- package/docs/STATS.md +21 -0
- package/docs/TROUBLESHOOTING.md +42 -0
- package/docs/UPGRADE_PLAN_v7.0.0.md +203 -0
- package/docs/VIRAL-PLAYBOOK.md +259 -0
- package/docs/VISUAL_GUIDE_v7.1.4.md +70 -0
- package/docs/VISUAL_GUIDE_v7.22.0.md +73 -0
- package/docs/WORKFLOW_INTEGRATION.md +21 -1
- package/docs/WORKSPACE.md +63 -70
- package/docs/assets/7.1.4-collaboration-design-preview.png +0 -0
- package/docs/assets/7.1.4-comparison.png +0 -0
- package/docs/assets/7.1.4-context-lab.png +0 -0
- package/docs/assets/7.1.4-control-room-dense-preview.png +0 -0
- package/docs/assets/7.1.4-control-room-focus-preview.png +0 -0
- package/docs/assets/7.1.4-features.png +0 -0
- package/docs/assets/7.1.4-graph.png +0 -0
- package/docs/assets/7.1.4-hub-control-room.png +0 -0
- package/docs/assets/7.1.4-hub-empty.png +0 -0
- package/docs/assets/7.1.4-hub-knowledge.png +0 -0
- package/docs/assets/7.1.4-hub-learning.png +0 -0
- package/docs/assets/7.1.4-hub-mobile.png +0 -0
- package/docs/assets/7.1.4-hub-public-docs-source.png +0 -0
- package/docs/assets/7.1.4-hub-public-docs.gif +0 -0
- package/docs/assets/7.1.4-hub-public-docs.png +0 -0
- package/docs/assets/7.1.4-hub-setup.png +0 -0
- package/docs/assets/7.1.4-hub-walkthrough.gif +0 -0
- package/docs/assets/7.1.4-integrations.png +0 -0
- package/docs/assets/7.1.4-knowledge-design-preview.png +0 -0
- package/docs/assets/7.1.4-learning-design-preview.png +0 -0
- package/docs/assets/7.1.4-learning.png +0 -0
- package/docs/assets/7.1.4-live.png +0 -0
- package/docs/assets/7.1.4-memory-review.png +0 -0
- package/docs/assets/7.1.4-mobile.png +0 -0
- package/docs/assets/7.1.4-models-design-preview.png +0 -0
- package/docs/assets/7.1.4-outcome-ranking.png +0 -0
- package/docs/assets/7.1.4-overview.png +0 -0
- package/docs/assets/7.1.4-project-kit.png +0 -0
- package/docs/assets/7.1.4-project-skill-preview.png +0 -0
- package/docs/assets/7.1.4-replay.png +0 -0
- package/docs/assets/7.1.4-setup-design-preview.png +0 -0
- package/docs/assets/7.1.4-usage-design-preview.png +0 -0
- package/docs/assets/7.22.0-agent-dock-mobile.png +0 -0
- package/docs/assets/7.22.0-agent-dock.gif +0 -0
- package/docs/assets/7.22.0-agent-dock.png +0 -0
- package/docs/assets/7.22.0-hub-exchange.png +0 -0
- package/docs/assets/7.22.0-hub-exchanges.gif +0 -0
- package/docs/assets/7.22.0-hub-graph.png +0 -0
- package/docs/assets/7.22.0-hub-mobile-empty.png +0 -0
- package/docs/assets/7.22.0-managed-skills.png +0 -0
- package/docs/assets/7.22.0-plain-evidence.png +0 -0
- package/docs/assets/7.22.0-project-controls.png +0 -0
- package/docs/assets/7.22.0-sessions.png +0 -0
- package/docs/assets/7.22.0-teach-brain.png +0 -0
- package/docs/assets/context-v7.1.3.png +0 -0
- package/docs/assets/features-v7.1.3.png +0 -0
- package/docs/assets/graph-v7.1.3.png +0 -0
- package/docs/assets/integrations-v7.1.3.png +0 -0
- package/docs/assets/live-v7.1.3.png +0 -0
- package/docs/assets/live-v7.1.4.gif +0 -0
- package/docs/assets/memory-detail-v7.1.3.png +0 -0
- package/docs/assets/overview-v7.1.3.png +0 -0
- package/docs/evaluation/CONTEXT_EVALUATION_v7.1.4.json +1818 -0
- package/docs/evaluation/CONTEXT_EVALUATION_v7.1.4.md +36 -0
- package/docs/launch/COMPONENT_MAP_v7.1.4.md +307 -0
- package/docs/launch/PROJECT_KIT_PLAN_v7.1.4.md +110 -0
- package/docs/launch/PROJECT_LEARNING_PLAN_v7.1.4.md +63 -0
- package/docs/launch/RELEASE_ACCEPTANCE_v7.22.0.md +48 -0
- package/docs/launch/RELEASE_NOTES_v7.1.3.md +40 -0
- package/docs/launch/RELEASE_NOTES_v7.1.4.md +30 -0
- package/docs/launch/RELEASE_NOTES_v7.22.0.md +53 -0
- package/docs/launch/RESEARCH_AND_PLAN_v7.1.4.md +255 -0
- package/docs/launch/RESEARCH_AND_PLAN_v7.22.0.md +672 -0
- package/package.json +135 -111
- package/skills/shadow-research/SKILL.md +2 -0
- package/skills/shadow-workflow/SKILL.md +8 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/** Project Kit uses the same local workspace shell and HTTP helpers. */
|
|
2
|
+
import { PROJECT_FEEDBACK_MARKUP, PROJECT_FEEDBACK_SCRIPT, PROJECT_FEEDBACK_STYLE } from './project-feedback-html.js';
|
|
3
|
+
export const PROJECT_KIT_STYLE = String.raw `
|
|
4
|
+
html[data-project-local="true"] .advanced-link { display: none; }
|
|
5
|
+
.project-local-notice { display: none; }
|
|
6
|
+
html[data-project-local="true"] .project-local-notice { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; padding: 8px 12px; margin-bottom: 16px; border-radius: 7px; background: var(--tint); color: var(--project); font-size: .83rem; }
|
|
7
|
+
.project-local-notice a { font-weight: 680; text-decoration: underline; text-underline-offset: 3px; }
|
|
8
|
+
.kit-identity { display: grid; grid-template-columns: minmax(150px,.8fr) minmax(0,1.2fr); align-items: center; gap: 16px; padding: 18px 20px; border-radius: 10px; color: var(--instrument-ink); background: var(--instrument); }
|
|
9
|
+
.kit-identity p { color: var(--instrument-muted); margin-top: 5px; }
|
|
10
|
+
.kit-identity .mono { color: var(--instrument-ink); }
|
|
11
|
+
.kit-identity dl { display: grid; gap: 6px; min-width: 0; }
|
|
12
|
+
.kit-identity dt { color: var(--instrument-muted); font-size: .78rem; }
|
|
13
|
+
.kit-identity dd { margin-top: 1px; }
|
|
14
|
+
.kit-identity summary { cursor: pointer; color: var(--signal); margin-top: 5px; }
|
|
15
|
+
.kit-identity details[open] > summary { margin-bottom: 6px; }
|
|
16
|
+
.kit-layout { grid-template-columns: minmax(280px,.88fr) minmax(0,1.25fr); }
|
|
17
|
+
.kit-form { display: grid; gap: 12px; }
|
|
18
|
+
.kit-form .button { justify-self: start; }
|
|
19
|
+
.kit-fields { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 8px; }
|
|
20
|
+
.kit-form-status { min-width: 0; }
|
|
21
|
+
.kit-form-status:empty { display: none; }
|
|
22
|
+
.kit-profile { display: grid; gap: 11px; }
|
|
23
|
+
.kit-profile summary { cursor: pointer; color: var(--teal); font-weight: 650; }
|
|
24
|
+
.kit-profile details[open] > summary { margin-bottom: 6px; }
|
|
25
|
+
.kit-evidence, .kit-checks { max-height: 300px; overflow: auto; }
|
|
26
|
+
.kit-evidence li, .kit-checks li { padding: 7px 0; }
|
|
27
|
+
.kit-evidence .tags { margin-top: 4px; }
|
|
28
|
+
.kit-checks .form-actions { margin-top: 3px; }
|
|
29
|
+
.kit-preview { border-top: 1px solid var(--line); min-width: 0; }
|
|
30
|
+
.kit-preview > .panel-head { background: var(--inset); }
|
|
31
|
+
.kit-preview-file { display: grid; gap: 8px; min-width: 0; }
|
|
32
|
+
.kit-file-header { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 6px; }
|
|
33
|
+
.kit-preview-file .context-preview { max-height: 440px; }
|
|
34
|
+
.kit-apply-controls { border-top: 1px solid var(--line); }
|
|
35
|
+
.kit-apply-controls .form-actions { margin-bottom: 6px; }
|
|
36
|
+
.kit-applied-list { padding-left: 18px; margin-top: 5px; }
|
|
37
|
+
@media (max-width: 985px) { .kit-layout { grid-template-columns: minmax(0,1fr); } }
|
|
38
|
+
@media (max-width: 690px) {
|
|
39
|
+
.kit-identity { grid-template-columns: minmax(0,1fr); gap: 10px; padding: 13px 14px; }
|
|
40
|
+
.kit-preview { scroll-margin-top: 55px; }
|
|
41
|
+
}
|
|
42
|
+
${PROJECT_FEEDBACK_STYLE}
|
|
43
|
+
`;
|
|
44
|
+
export const PROJECT_KIT_MARKUP = String.raw `
|
|
45
|
+
<section id="page-project-kit" aria-labelledby="title-project-kit" hidden>
|
|
46
|
+
<div class="page-head">
|
|
47
|
+
<div><h1 id="title-project-kit" tabindex="-1">Project Kit</h1><p class="muted">Inspect this project, save knowledge, and prepare a skill for a coding agent.</p></div>
|
|
48
|
+
<button class="button" type="button" id="kit-refresh" hidden><span data-icon="refresh"></span>Refresh profile</button>
|
|
49
|
+
</div>
|
|
50
|
+
<div id="kit-gate" class="panel" role="status"></div>
|
|
51
|
+
<div id="kit-workbench" class="stack" hidden>
|
|
52
|
+
<section id="kit-identity" class="kit-identity" aria-label="Pinned project and storage"></section>
|
|
53
|
+
<div class="split kit-layout">
|
|
54
|
+
<div class="stack">
|
|
55
|
+
<section class="panel" aria-labelledby="kit-profile-heading">
|
|
56
|
+
<div class="panel-head"><h2 id="kit-profile-heading">Observed project profile</h2></div>
|
|
57
|
+
<div id="kit-profile" aria-busy="true"></div>
|
|
58
|
+
</section>
|
|
59
|
+
<section class="panel" aria-labelledby="kit-knowledge-heading">
|
|
60
|
+
<div class="panel-head"><div><h2 id="kit-knowledge-heading">Project knowledge</h2><p class="small muted">Record a decision, constraint, or lesson you want agents to recall.</p></div></div>
|
|
61
|
+
<form class="panel-body kit-form" id="kit-knowledge-form">
|
|
62
|
+
<label class="label" for="kit-knowledge-title">Title<input id="kit-knowledge-title" maxlength="160" required placeholder="Retry rules for checkout"></label>
|
|
63
|
+
<label class="label" for="kit-knowledge-content">Knowledge<textarea id="kit-knowledge-content" maxlength="8000" rows="4" required placeholder="Describe the rule and when it applies."></textarea></label>
|
|
64
|
+
<div class="kit-fields">
|
|
65
|
+
<label class="label" for="kit-knowledge-category">Category <span class="small muted">Optional</span><input id="kit-knowledge-category" maxlength="64" pattern="[A-Za-z0-9][A-Za-z0-9 _.\-]*" placeholder="knowledge"></label>
|
|
66
|
+
<label class="label" for="kit-knowledge-source">Source reference <span class="small muted">Optional</span><input id="kit-knowledge-source" maxlength="500" placeholder="docs/checkout.md"></label>
|
|
67
|
+
</div>
|
|
68
|
+
<button class="button primary" type="submit" id="kit-knowledge-save"><span data-icon="memory"></span>Save knowledge</button>
|
|
69
|
+
<div class="kit-form-status" id="kit-knowledge-status" role="status"></div>
|
|
70
|
+
</form>
|
|
71
|
+
</section>
|
|
72
|
+
</div>
|
|
73
|
+
<section class="panel" aria-labelledby="kit-skill-heading">
|
|
74
|
+
<div class="panel-head"><div><h2 id="kit-skill-heading">Skill builder</h2><p class="small muted">Describe the workflow, then review the generated file before applying it.</p></div></div>
|
|
75
|
+
<form class="panel-body kit-form" id="kit-skill-form">
|
|
76
|
+
<label class="label" for="kit-requirement">Requirement<textarea id="kit-requirement" rows="4" maxlength="8000" required placeholder="When a checkout retry changes, verify idempotency and add a regression case."></textarea></label>
|
|
77
|
+
<div class="kit-fields">
|
|
78
|
+
<label class="label" for="kit-target">Agent target<select id="kit-target"><option value="codex">Codex</option><option value="claude-code">Claude Code</option><option value="opencode">OpenCode</option><option value="deepseek-harness">DeepSeek Harness</option><option value="portable">Portable</option></select></label>
|
|
79
|
+
<label class="label" for="kit-skill-name">Skill name<input id="kit-skill-name" maxlength="63" pattern="[a-z0-9]+(?:-[a-z0-9]+)*" placeholder="Generated from requirement"></label>
|
|
80
|
+
</div>
|
|
81
|
+
<label class="label" for="kit-skill-knowledge">Supporting knowledge <span class="small muted">Optional reference material</span><textarea id="kit-skill-knowledge" maxlength="8000" rows="3" placeholder="Add the project rule or evidence the skill should carry."></textarea></label>
|
|
82
|
+
<button class="button primary" type="submit" id="kit-preview-submit"><span data-icon="context"></span>Preview skill</button>
|
|
83
|
+
</form>
|
|
84
|
+
<section class="kit-preview" id="kit-preview" aria-labelledby="kit-preview-heading">
|
|
85
|
+
<div class="panel-head"><h3 id="kit-preview-heading" tabindex="-1">Skill preview</h3><span id="kit-preview-state" class="small muted" role="status"></span></div>
|
|
86
|
+
<div id="kit-preview-body"></div>
|
|
87
|
+
<div class="panel-body kit-apply-controls" id="kit-apply-controls" hidden>
|
|
88
|
+
<div class="form-actions"><button class="button primary" type="button" id="kit-apply"><span data-icon="plus"></span>Apply local skill</button></div>
|
|
89
|
+
<p class="small muted">Writes the displayed project-relative file. Confirm the path and content above.</p>
|
|
90
|
+
<div class="kit-form-status" id="kit-apply-status" role="status"></div>
|
|
91
|
+
</div>
|
|
92
|
+
</section>
|
|
93
|
+
</section>
|
|
94
|
+
</div>
|
|
95
|
+
${PROJECT_FEEDBACK_MARKUP}
|
|
96
|
+
</div>
|
|
97
|
+
</section>
|
|
98
|
+
`;
|
|
99
|
+
export const PROJECT_KIT_SCRIPT = String.raw `
|
|
100
|
+
const kit = { profile: null, profileLoading: false, saving: false, savedKnowledge: '', preview: null, previewInput: null,
|
|
101
|
+
previewing: false, applying: false, dirty: false, previewError: '', applied: null };
|
|
102
|
+
|
|
103
|
+
function renderKitIdentity(info) {
|
|
104
|
+
const root = String(info.root || '').replace(/\\/g, '/').replace(/\/$/, '') + '/';
|
|
105
|
+
const storage = String(info.storagePath || '').replace(/\\/g, '/');
|
|
106
|
+
const relativeStorage = storage.startsWith(root) ? storage.slice(root.length) : 'Project-local store';
|
|
107
|
+
$('kit-identity').innerHTML = '<div><h2>' + esc(info.projectName || info.projectId) + '</h2><p class="small">Project-local memory and skills</p>' +
|
|
108
|
+
'<button class="button quiet kit-outcomes-jump" type="button" id="kit-outcomes-jump">Record a memory outcome ' + icon('chevron', true) + '</button></div>' +
|
|
109
|
+
'<div><p class="small">Memory store</p><code class="mono">' + esc(relativeStorage) + '</code><details><summary class="small">Show full paths</summary>' +
|
|
110
|
+
'<dl><div><dt>Project root</dt><dd class="mono">' + esc(info.root) + '</dd></div><div><dt>Memory store</dt><dd class="mono">' +
|
|
111
|
+
esc(info.storagePath) + '</dd></div></dl></details></div>';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function renderKitProfile(profile) {
|
|
115
|
+
const coverage = profile.coverage || {};
|
|
116
|
+
const entries = list(profile.evidence);
|
|
117
|
+
const checks = list(profile.checks);
|
|
118
|
+
const findings = entries.map((entry) => '<li><strong class="mono">' + esc(entry.path) + '</strong>' +
|
|
119
|
+
tags([['project', nice(entry.kind)], ...list(entry.signals).map((signal) => ['memory', signal])]) + '</li>').join('');
|
|
120
|
+
const commands = checks.map((check) => '<li><strong>' + esc(check.label) + '</strong><p class="small muted">' +
|
|
121
|
+
esc(check.source) + '</p>' + commandMarkup(check.command) + '</li>').join('');
|
|
122
|
+
$('kit-profile').innerHTML = '<div class="panel-body kit-profile"><p class="small muted">Observed ' + dateMarkup(profile.observedAt, true) +
|
|
123
|
+
' · ' + number(coverage.entries) + ' entries inspected' + (coverage.truncated ? ' (inspection limit reached)' : '') + '.</p>' +
|
|
124
|
+
'<div><h3>Detected stack</h3>' + (list(profile.stack).length ? tags(profile.stack.map((value) => ['project', value])) :
|
|
125
|
+
'<p class="small muted">No supported stack markers found.</p>') + '</div>' +
|
|
126
|
+
(list(profile.packageManagers).length ? '<div><h3>Package managers</h3>' + tags(profile.packageManagers.map((value) => ['memory', value])) + '</div>' : '') +
|
|
127
|
+
(findings ? '<details open><summary>File evidence · ' + number(entries.length) + '</summary><ul class="list kit-evidence">' + findings + '</ul></details>' : '') +
|
|
128
|
+
(commands ? '<details><summary>Suggested project checks · ' + number(checks.length) + '</summary><ul class="list kit-checks">' + commands + '</ul></details>' : '') +
|
|
129
|
+
list(profile.warnings).map((warning) => '<p class="small muted">' + esc(warning) + '</p>').join('') + '</div>';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async function loadProjectKit(force = false) {
|
|
133
|
+
const gate = $('kit-gate');
|
|
134
|
+
const workbench = $('kit-workbench');
|
|
135
|
+
if (!state.overviewLoaded) {
|
|
136
|
+
gate.hidden = false;
|
|
137
|
+
gate.innerHTML = skeleton('Checking project workspace…');
|
|
138
|
+
await loadOverview();
|
|
139
|
+
}
|
|
140
|
+
if (!state.overviewLoaded) {
|
|
141
|
+
gate.innerHTML = errorMarkup('Could not check the project workspace.', 'kit-profile');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const info = state.projectKit;
|
|
145
|
+
const enabled = info?.available === true;
|
|
146
|
+
workbench.hidden = !enabled;
|
|
147
|
+
$('kit-refresh').hidden = !enabled;
|
|
148
|
+
gate.hidden = enabled;
|
|
149
|
+
if (!enabled) {
|
|
150
|
+
gate.innerHTML = blank('project', 'Start a project workspace', 'Run this command from the project folder to use Project Kit with a project-local store.',
|
|
151
|
+
commandMarkup('shadow-brain project workspace .'));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
renderKitIdentity(info);
|
|
155
|
+
void loadProjectFeedback();
|
|
156
|
+
const focusMemory = state.view === 'project-kit' ? routeParams().get('memory') || '' : '';
|
|
157
|
+
if (focusMemory || outcomes.project !== info.projectId) void loadFeedbackMemories(focusMemory);
|
|
158
|
+
if (focusMemory && (document.activeElement === $('title-project-kit') || document.activeElement === document.body)) openOutcomeEditor();
|
|
159
|
+
if (kit.profileLoading || kit.profile && !force) return;
|
|
160
|
+
kit.profileLoading = true;
|
|
161
|
+
const target = $('kit-profile');
|
|
162
|
+
$('kit-refresh').disabled = true;
|
|
163
|
+
target.innerHTML = skeleton('Inspecting the pinned project…');
|
|
164
|
+
setBusy(target, true);
|
|
165
|
+
try {
|
|
166
|
+
const profile = await api('project-profile');
|
|
167
|
+
if (profile.projectId !== info.projectId) throw new Error('The server returned a different project profile.');
|
|
168
|
+
kit.profile = profile;
|
|
169
|
+
renderKitProfile(profile);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
kit.profile = null;
|
|
172
|
+
target.innerHTML = errorMarkup(error.message, 'kit-profile');
|
|
173
|
+
} finally {
|
|
174
|
+
kit.profileLoading = false;
|
|
175
|
+
$('kit-refresh').disabled = false;
|
|
176
|
+
setBusy(target, false);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function saveKitKnowledge() {
|
|
181
|
+
if (kit.saving || state.projectKit?.available !== true) return;
|
|
182
|
+
const title = $('kit-knowledge-title').value.trim();
|
|
183
|
+
const content = $('kit-knowledge-content').value;
|
|
184
|
+
const category = $('kit-knowledge-category').value.trim();
|
|
185
|
+
const source = $('kit-knowledge-source').value.trim();
|
|
186
|
+
if (!title || !content.trim()) {
|
|
187
|
+
$('kit-knowledge-status').innerHTML = errorMarkup('Enter a title and knowledge text.');
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const form = $('kit-knowledge-form');
|
|
191
|
+
const status = $('kit-knowledge-status');
|
|
192
|
+
const button = $('kit-knowledge-save');
|
|
193
|
+
kit.saving = true;
|
|
194
|
+
button.disabled = true;
|
|
195
|
+
status.textContent = 'Saving to the project store…';
|
|
196
|
+
try {
|
|
197
|
+
const result = await api('project-knowledge', { body: { title, content, ...(category ? { category } : {}), ...(source ? { source } : {}) } });
|
|
198
|
+
if (!result.ok || !result.memoryId || result.projectId !== state.projectKit.projectId) throw new Error('The server returned an unreadable saved memory.');
|
|
199
|
+
kit.savedKnowledge = [title, content, source ? 'Recorded reference: ' + source : ''].filter(Boolean).join('\n\n');
|
|
200
|
+
if ($('kit-knowledge-title').value.trim() === title && $('kit-knowledge-content').value === content &&
|
|
201
|
+
$('kit-knowledge-category').value.trim() === category && $('kit-knowledge-source').value.trim() === source) form.reset();
|
|
202
|
+
state.overviewLoaded = false;
|
|
203
|
+
state.graph.snapshot = null;
|
|
204
|
+
void loadFeedbackMemories();
|
|
205
|
+
if (state.context.pack || state.context.pending) {
|
|
206
|
+
state.context.dirty = true;
|
|
207
|
+
if (!state.context.pending) renderContext();
|
|
208
|
+
}
|
|
209
|
+
status.innerHTML = '<div class="stack"><p class="small">Saved as user-provided project knowledge.</p><div class="form-actions">' +
|
|
210
|
+
memoryLink(result.memoryId, result.projectId, 'View saved memory') + '<button class="button quiet" type="button" id="kit-use-knowledge">Use in skill</button>' +
|
|
211
|
+
'<a class="button quiet" href="' + esc(routeLink('context', { project: result.projectId })) + '">Open Context Lab ' + icon('chevron', true) +
|
|
212
|
+
'</a></div><p class="small muted" id="kit-use-status" role="status"></p></div>';
|
|
213
|
+
} catch (error) {
|
|
214
|
+
status.innerHTML = errorMarkup(error.message);
|
|
215
|
+
} finally {
|
|
216
|
+
kit.saving = false;
|
|
217
|
+
button.disabled = false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function useKitKnowledge() {
|
|
222
|
+
const status = $('kit-use-status');
|
|
223
|
+
const field = $('kit-skill-knowledge');
|
|
224
|
+
if (!status || !kit.savedKnowledge) return;
|
|
225
|
+
if (field.value.includes(kit.savedKnowledge)) {
|
|
226
|
+
status.textContent = 'This knowledge is already in the skill draft.';
|
|
227
|
+
field.focus();
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const next = [field.value, kit.savedKnowledge].filter((value) => value.trim()).join('\n\n');
|
|
231
|
+
if (next.length > field.maxLength) {
|
|
232
|
+
status.textContent = 'The skill draft exceeds 8,000 characters. Use a shorter excerpt from the saved memory.';
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
field.value = next;
|
|
236
|
+
field.dispatchEvent(new Event('input', { bubbles: true }));
|
|
237
|
+
status.textContent = 'Added to the skill draft as reference material.';
|
|
238
|
+
field.focus();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const kitFileStates = { create: ['ok', 'Ready to create'], update: ['ok', 'Ready to update'], unchanged: ['', 'Already current'], conflict: ['warn', 'Protected file'] };
|
|
242
|
+
const kitApplyStates = { created: 'Created', updated: 'Updated', unchanged: 'Already current' };
|
|
243
|
+
|
|
244
|
+
function renderKitPreview() {
|
|
245
|
+
const target = $('kit-preview-body');
|
|
246
|
+
const status = $('kit-preview-state');
|
|
247
|
+
const files = list(kit.preview?.files);
|
|
248
|
+
const conflict = files.some((file) => file.status === 'conflict');
|
|
249
|
+
const ready = !!kit.preview && files.length > 0;
|
|
250
|
+
const controls = $('kit-apply-controls');
|
|
251
|
+
controls.hidden = !ready;
|
|
252
|
+
$('kit-apply').disabled = !ready || conflict || kit.dirty || kit.applying || !!kit.applied;
|
|
253
|
+
$('kit-preview-submit').disabled = kit.previewing || kit.applying;
|
|
254
|
+
$('kit-preview').setAttribute('aria-busy', String(kit.previewing || kit.applying));
|
|
255
|
+
if (kit.previewing) {
|
|
256
|
+
status.textContent = 'Generating preview';
|
|
257
|
+
target.innerHTML = skeleton('Building the exact file preview…');
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (kit.previewError) {
|
|
261
|
+
status.textContent = 'Preview failed';
|
|
262
|
+
target.innerHTML = errorMarkup(kit.previewError);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (!ready) {
|
|
266
|
+
status.textContent = '';
|
|
267
|
+
target.innerHTML = blank('context', 'Ready to preview', 'Enter a requirement and choose an agent target.');
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
status.textContent = kit.dirty ? 'Preview out of date' : conflict ? 'Protected file' : kit.applied ? 'Applied locally' : kit.applying ? 'Applying' : 'Ready to review';
|
|
271
|
+
const preview = kit.preview;
|
|
272
|
+
const warnings = list(preview.warnings).map((warning) => '<p class="small muted">' + esc(warning) + '</p>').join('');
|
|
273
|
+
const stale = kit.dirty ? '<p class="status small" role="status">Preview again to review the current file plan.</p>' : '';
|
|
274
|
+
target.innerHTML = '<div class="panel-body stack">' + stale + warnings + files.map((file) => {
|
|
275
|
+
const [tone, label] = kitFileStates[file.status] || ['', 'Review'];
|
|
276
|
+
return '<div class="kit-preview-file"><div class="kit-file-header"><strong class="mono">' + esc(file.relativePath) +
|
|
277
|
+
'</strong><span class="tag check-' + tone + '">' + label + '</span></div>' +
|
|
278
|
+
(file.reason ? '<p class="small muted">' + esc(file.reason) + '</p>' : '') +
|
|
279
|
+
'<pre class="context-preview mono" tabindex="0" aria-label="Generated skill file">' + esc(file.content) + '</pre></div>';
|
|
280
|
+
}).join('') + '</div>';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async function previewKitSkill() {
|
|
284
|
+
if (kit.previewing || kit.applying || state.projectKit?.available !== true) return;
|
|
285
|
+
const requirement = $('kit-requirement').value;
|
|
286
|
+
const target = $('kit-target').value;
|
|
287
|
+
const name = $('kit-skill-name').value.trim();
|
|
288
|
+
const knowledge = $('kit-skill-knowledge').value;
|
|
289
|
+
if (!requirement.trim()) {
|
|
290
|
+
kit.previewError = 'Enter a requirement for the skill.';
|
|
291
|
+
renderKitPreview();
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const body = { requirement, target, ...(name ? { name } : {}), ...(knowledge.trim() ? { knowledge } : {}) };
|
|
295
|
+
kit.previewing = true;
|
|
296
|
+
kit.preview = null;
|
|
297
|
+
kit.previewInput = body;
|
|
298
|
+
kit.previewError = '';
|
|
299
|
+
kit.applied = null;
|
|
300
|
+
kit.dirty = false;
|
|
301
|
+
$('kit-apply-status').replaceChildren();
|
|
302
|
+
renderKitPreview();
|
|
303
|
+
try {
|
|
304
|
+
const preview = await api('project-skill-preview', { body });
|
|
305
|
+
if (preview.projectId !== state.projectKit.projectId || !preview.planHash || !list(preview.files).length) {
|
|
306
|
+
throw new Error('The server returned an unreadable skill preview.');
|
|
307
|
+
}
|
|
308
|
+
kit.preview = preview;
|
|
309
|
+
} catch (error) {
|
|
310
|
+
kit.previewError = error.message;
|
|
311
|
+
} finally {
|
|
312
|
+
kit.previewing = false;
|
|
313
|
+
renderKitPreview();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async function applyKitSkill() {
|
|
318
|
+
if (!kit.preview || !kit.previewInput || kit.dirty || kit.applying || kit.applied ||
|
|
319
|
+
list(kit.preview.files).some((file) => file.status === 'conflict') || state.projectKit?.available !== true) return;
|
|
320
|
+
const status = $('kit-apply-status');
|
|
321
|
+
kit.applying = true;
|
|
322
|
+
status.textContent = 'Applying the reviewed plan…';
|
|
323
|
+
renderKitPreview();
|
|
324
|
+
try {
|
|
325
|
+
const result = await api('project-skill-apply', { body: { ...kit.previewInput, expectedPlanHash: kit.preview.planHash } });
|
|
326
|
+
if (result.projectId !== state.projectKit.projectId || !list(result.files).length) throw new Error('The server returned an unreadable apply result.');
|
|
327
|
+
kit.applied = result;
|
|
328
|
+
status.innerHTML = '<p class="small">Skill saved in this project.</p><ul class="kit-applied-list small">' + result.files.map((file) =>
|
|
329
|
+
'<li>' + esc(kitApplyStates[file.status] || nice(file.status)) + ' <code class="mono">' + esc(file.relativePath) + '</code></li>').join('') + '</ul>' +
|
|
330
|
+
list(result.warnings).map((warning) => '<p class="small muted">' + esc(warning) + '</p>').join('');
|
|
331
|
+
} catch (error) {
|
|
332
|
+
if (error.status === 409) kit.dirty = true;
|
|
333
|
+
status.innerHTML = errorMarkup(error.message);
|
|
334
|
+
} finally {
|
|
335
|
+
kit.applying = false;
|
|
336
|
+
renderKitPreview();
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
$('kit-refresh').addEventListener('click', () => { void loadProjectKit(true); });
|
|
341
|
+
$('kit-identity').addEventListener('click', (event) => {
|
|
342
|
+
if (event.target.closest('#kit-outcomes-jump')) openOutcomeEditor();
|
|
343
|
+
});
|
|
344
|
+
$('kit-knowledge-form').addEventListener('submit', (event) => { event.preventDefault(); void saveKitKnowledge(); });
|
|
345
|
+
$('kit-knowledge-status').addEventListener('click', (event) => {
|
|
346
|
+
if (event.target.closest('#kit-use-knowledge')) useKitKnowledge();
|
|
347
|
+
});
|
|
348
|
+
$('kit-skill-form').addEventListener('submit', (event) => { event.preventDefault(); void previewKitSkill(); });
|
|
349
|
+
$('kit-skill-form').addEventListener('input', () => {
|
|
350
|
+
if (kit.previewInput && !kit.dirty) {
|
|
351
|
+
kit.dirty = true;
|
|
352
|
+
renderKitPreview();
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
$('kit-apply').addEventListener('click', () => { void applyKitSkill(); });
|
|
356
|
+
${PROJECT_FEEDBACK_SCRIPT}
|
|
357
|
+
renderKitPreview();
|
|
358
|
+
`;
|
|
359
|
+
//# sourceMappingURL=project-kit-html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-kit-html.js","sourceRoot":"","sources":["../../src/dashboard/project-kit-html.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEtH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCzC,sBAAsB;CACvB,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmD1C,uBAAuB;;;CAGxB,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiQ1C,uBAAuB;;CAExB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { FeatureSettingsStore } from '../brain/feature-settings.js';
|
|
3
|
+
export declare class ProjectLiveStream {
|
|
4
|
+
private readonly root;
|
|
5
|
+
private readonly serverInstanceId;
|
|
6
|
+
private readonly settings;
|
|
7
|
+
private readonly clients;
|
|
8
|
+
private readonly ring;
|
|
9
|
+
private readonly files;
|
|
10
|
+
private readonly watcher;
|
|
11
|
+
private readonly changes;
|
|
12
|
+
private flags?;
|
|
13
|
+
private baseline;
|
|
14
|
+
private sequence;
|
|
15
|
+
private timer?;
|
|
16
|
+
private heartbeat?;
|
|
17
|
+
private closed;
|
|
18
|
+
constructor(root: string, serverInstanceId: string, settings: FeatureSettingsStore);
|
|
19
|
+
static route(path: string): boolean;
|
|
20
|
+
handle(request: IncomingMessage, response: ServerResponse, url: URL): void;
|
|
21
|
+
close(): void;
|
|
22
|
+
private startTimers;
|
|
23
|
+
private stopTimers;
|
|
24
|
+
private check;
|
|
25
|
+
private disconnect;
|
|
26
|
+
private parseCursor;
|
|
27
|
+
private emit;
|
|
28
|
+
private control;
|
|
29
|
+
private serialize;
|
|
30
|
+
private send;
|
|
31
|
+
private flush;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=project-live-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-live-stream.d.ts","sourceRoot":"","sources":["../../src/dashboard/project-live-stream.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,KAAK,EAAgB,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AA0CvF,qBAAa,iBAAiB;IAahB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAU,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAAU,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAZ/G,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6C;IACnE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,KAAK,CAAC,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,KAAK,CAAC,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAiB;IACnC,OAAO,CAAC,MAAM,CAAS;gBAEM,IAAI,EAAE,MAAM,EAAmB,gBAAgB,EAAE,MAAM,EAAmB,QAAQ,EAAE,oBAAoB;IASrI,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC,MAAM,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI;IAwC1E,KAAK,IAAI,IAAI;IAUb,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,KAAK;IA2Cb,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,IAAI;IAWZ,OAAO,CAAC,KAAK;CAOd"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { lstatSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { MCP_PRESENCE_FILE } from '../brain/mcp-presence.js';
|
|
4
|
+
import { ProjectFileWatch } from './project-file-watch.js';
|
|
5
|
+
const LIMITS = { connections: 8, ring: 128, files: 50, queuedBytes: 96 * 1024, checkMs: 250, heartbeatMs: 14000 };
|
|
6
|
+
const STORES = [
|
|
7
|
+
['project-memory.json', ['graph']],
|
|
8
|
+
['memory-annotations.json', ['graph']],
|
|
9
|
+
['activity-journal.json', ['telemetry']],
|
|
10
|
+
['feature-settings.json', ['features', 'presence']],
|
|
11
|
+
['memory-feedback.json', ['feedback']],
|
|
12
|
+
['project-hub.sqlite', ['hub', 'sessions']],
|
|
13
|
+
['project-hub.sqlite-wal', ['hub', 'sessions']],
|
|
14
|
+
['project-sources.sqlite', ['sources']],
|
|
15
|
+
['project-sources.sqlite-wal', ['sources']],
|
|
16
|
+
['project-policy.json', ['policy', 'presence']],
|
|
17
|
+
[MCP_PRESENCE_FILE, ['presence']],
|
|
18
|
+
['model-usage.sqlite', ['usage']],
|
|
19
|
+
['model-usage.sqlite-wal', ['usage']],
|
|
20
|
+
];
|
|
21
|
+
function metadata(file) {
|
|
22
|
+
try {
|
|
23
|
+
const entry = lstatSync(file, { bigint: true, throwIfNoEntry: false });
|
|
24
|
+
if (!entry?.isFile() || entry.nlink !== 1n)
|
|
25
|
+
return '';
|
|
26
|
+
return [entry.dev, entry.ino, entry.size, entry.mtimeNs, entry.ctimeNs].join(':');
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return '?';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function json(response, status, data) {
|
|
33
|
+
response.writeHead(status, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-store', 'X-Content-Type-Options': 'nosniff' });
|
|
34
|
+
response.end(JSON.stringify(data));
|
|
35
|
+
}
|
|
36
|
+
export class ProjectLiveStream {
|
|
37
|
+
constructor(root, serverInstanceId, settings) {
|
|
38
|
+
this.root = root;
|
|
39
|
+
this.serverInstanceId = serverInstanceId;
|
|
40
|
+
this.settings = settings;
|
|
41
|
+
this.clients = new Set();
|
|
42
|
+
this.ring = [];
|
|
43
|
+
this.files = [];
|
|
44
|
+
this.changes = new Map();
|
|
45
|
+
this.baseline = false;
|
|
46
|
+
this.sequence = 0;
|
|
47
|
+
this.closed = false;
|
|
48
|
+
this.watcher = new ProjectFileWatch(root, file => {
|
|
49
|
+
if (!this.flags?.liveActivity || !this.flags.activityRecording || !this.flags.projectFileActivity)
|
|
50
|
+
return;
|
|
51
|
+
const event = this.emit({ kind: 'file', ...file });
|
|
52
|
+
this.files.push(event);
|
|
53
|
+
if (this.files.length > LIMITS.files)
|
|
54
|
+
this.files.shift();
|
|
55
|
+
}, () => { if (this.flags?.liveActivity)
|
|
56
|
+
this.emit({ kind: 'watch', watch: this.watcher.summary() }); });
|
|
57
|
+
}
|
|
58
|
+
static route(path) {
|
|
59
|
+
return path === '/api/workspace/stream' || path === '/api/workspace/project-files';
|
|
60
|
+
}
|
|
61
|
+
handle(request, response, url) {
|
|
62
|
+
if (request.method !== 'GET')
|
|
63
|
+
return json(response, 405, { error: 'Use GET for the local project stream.' });
|
|
64
|
+
if (request.headers.origin && request.headers.origin !== 'http://' + request.headers.host ||
|
|
65
|
+
['cross-site', 'same-site'].includes(String(request.headers['sec-fetch-site']))) {
|
|
66
|
+
return json(response, 403, { error: 'The project stream accepts same-origin requests.' });
|
|
67
|
+
}
|
|
68
|
+
if (this.closed)
|
|
69
|
+
return json(response, 503, { error: 'The project stream is closing.' });
|
|
70
|
+
this.check();
|
|
71
|
+
const watch = this.watcher.summary();
|
|
72
|
+
if (url.pathname.endsWith('/project-files'))
|
|
73
|
+
return json(response, 200, {
|
|
74
|
+
watch, serverInstanceId: this.serverInstanceId, enabled: !!this.flags?.projectFileActivity,
|
|
75
|
+
items: this.flags?.liveActivity ? this.watcher.inventory() : [], events: this.flags?.liveActivity ? this.files : [],
|
|
76
|
+
});
|
|
77
|
+
if (this.clients.size >= LIMITS.connections)
|
|
78
|
+
return json(response, 429, { error: 'The project stream reached its connection limit.' });
|
|
79
|
+
response.writeHead(200, {
|
|
80
|
+
'Content-Type': 'text/event-stream; charset=utf-8', 'Cache-Control': 'no-store, no-transform',
|
|
81
|
+
'X-Content-Type-Options': 'nosniff', 'X-Accel-Buffering': 'no',
|
|
82
|
+
});
|
|
83
|
+
response.flushHeaders();
|
|
84
|
+
const client = { response, pending: [], queued: 0, blocked: false };
|
|
85
|
+
this.clients.add(client);
|
|
86
|
+
response.once('close', () => this.disconnect(client));
|
|
87
|
+
response.on('drain', () => { client.blocked = false; this.flush(client); });
|
|
88
|
+
this.send(client, 'retry: 1800\n\n');
|
|
89
|
+
if (!this.flags?.liveActivity) {
|
|
90
|
+
this.control(client, 'disabled');
|
|
91
|
+
response.end();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const header = request.headers['last-event-id'];
|
|
95
|
+
const cursor = typeof header === 'string' ? header : url.searchParams.get('cursor');
|
|
96
|
+
const after = this.parseCursor(cursor);
|
|
97
|
+
if (cursor && after === null)
|
|
98
|
+
this.control(client, 'reset');
|
|
99
|
+
else if (after !== null) {
|
|
100
|
+
for (const event of this.ring)
|
|
101
|
+
if (event.sequence > after)
|
|
102
|
+
this.send(client, this.serialize(event));
|
|
103
|
+
}
|
|
104
|
+
this.control(client, 'ready');
|
|
105
|
+
this.startTimers();
|
|
106
|
+
}
|
|
107
|
+
close() {
|
|
108
|
+
this.closed = true;
|
|
109
|
+
for (const client of this.clients)
|
|
110
|
+
client.response.destroy();
|
|
111
|
+
this.clients.clear();
|
|
112
|
+
this.stopTimers();
|
|
113
|
+
this.watcher.stop();
|
|
114
|
+
this.ring.length = 0;
|
|
115
|
+
this.files.length = 0;
|
|
116
|
+
}
|
|
117
|
+
startTimers() {
|
|
118
|
+
this.timer ?? (this.timer = setInterval(() => this.check(), LIMITS.checkMs).unref());
|
|
119
|
+
this.heartbeat ?? (this.heartbeat = setInterval(() => {
|
|
120
|
+
for (const client of this.clients)
|
|
121
|
+
this.send(client, ': heartbeat\n\n');
|
|
122
|
+
}, LIMITS.heartbeatMs).unref());
|
|
123
|
+
}
|
|
124
|
+
stopTimers() {
|
|
125
|
+
clearInterval(this.timer);
|
|
126
|
+
clearInterval(this.heartbeat);
|
|
127
|
+
this.timer = this.heartbeat = undefined;
|
|
128
|
+
}
|
|
129
|
+
check() {
|
|
130
|
+
const directory = join(this.root, '.shadow-brain');
|
|
131
|
+
let validDirectory = false, missingDirectory = false;
|
|
132
|
+
try {
|
|
133
|
+
if (lstatSync(this.root, { throwIfNoEntry: false })?.isDirectory()) {
|
|
134
|
+
const entry = lstatSync(directory, { throwIfNoEntry: false });
|
|
135
|
+
missingDirectory = !entry;
|
|
136
|
+
validDirectory = !!entry?.isDirectory();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch { /* An unavailable directory cannot be read safely. */ }
|
|
140
|
+
const changes = new Set();
|
|
141
|
+
for (const [basename, areas] of STORES) {
|
|
142
|
+
const value = validDirectory ? metadata(join(directory, basename)) : '';
|
|
143
|
+
if (this.baseline && this.changes.get(basename) !== value)
|
|
144
|
+
for (const area of areas)
|
|
145
|
+
changes.add(area);
|
|
146
|
+
this.changes.set(basename, value);
|
|
147
|
+
}
|
|
148
|
+
if (!this.baseline || changes.has('features')) {
|
|
149
|
+
try {
|
|
150
|
+
this.flags = validDirectory || missingDirectory ? this.settings.get().features : undefined;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
this.flags = undefined;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
this.baseline = true;
|
|
157
|
+
if (!this.flags?.liveActivity) {
|
|
158
|
+
this.watcher.stop();
|
|
159
|
+
this.ring.length = 0;
|
|
160
|
+
this.files.length = 0;
|
|
161
|
+
for (const client of this.clients) {
|
|
162
|
+
this.control(client, 'disabled');
|
|
163
|
+
client.response.end();
|
|
164
|
+
}
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const observe = this.flags.projectFileActivity && this.flags.activityRecording;
|
|
168
|
+
if (observe && this.clients.size)
|
|
169
|
+
this.watcher.start();
|
|
170
|
+
else if (!observe && (this.watcher.summary().status !== 'off' || this.files.length)) {
|
|
171
|
+
this.watcher.stop();
|
|
172
|
+
this.files.length = 0;
|
|
173
|
+
this.ring.length = 0;
|
|
174
|
+
this.emit({ kind: 'watch', watch: this.watcher.summary() });
|
|
175
|
+
}
|
|
176
|
+
if (changes.size)
|
|
177
|
+
this.emit({ kind: 'change', areas: [...changes] });
|
|
178
|
+
}
|
|
179
|
+
disconnect(client) {
|
|
180
|
+
this.clients.delete(client);
|
|
181
|
+
if (this.clients.size)
|
|
182
|
+
return;
|
|
183
|
+
this.stopTimers();
|
|
184
|
+
this.watcher.stop();
|
|
185
|
+
// Reconcile on the next subscriber before replaying recent notifications.
|
|
186
|
+
}
|
|
187
|
+
parseCursor(raw) {
|
|
188
|
+
if (!raw)
|
|
189
|
+
return null;
|
|
190
|
+
const [instance, cursor, extra] = raw.split(':');
|
|
191
|
+
const sequence = Number(cursor);
|
|
192
|
+
if (extra !== undefined || instance !== this.serverInstanceId || !/^\d+$/.test(cursor ?? '') ||
|
|
193
|
+
!Number.isSafeInteger(sequence) || sequence < (this.ring[0]?.sequence ?? this.sequence + 1) - 1 || sequence > this.sequence)
|
|
194
|
+
return null;
|
|
195
|
+
return sequence;
|
|
196
|
+
}
|
|
197
|
+
emit(notice) {
|
|
198
|
+
const event = { ...notice, serverInstanceId: this.serverInstanceId, sequence: ++this.sequence, timestamp: new Date().toISOString() };
|
|
199
|
+
this.ring.push(event);
|
|
200
|
+
if (this.ring.length > LIMITS.ring)
|
|
201
|
+
this.ring.shift();
|
|
202
|
+
const message = this.serialize(event);
|
|
203
|
+
for (const client of this.clients)
|
|
204
|
+
this.send(client, message);
|
|
205
|
+
return event;
|
|
206
|
+
}
|
|
207
|
+
control(client, kind) {
|
|
208
|
+
this.send(client, this.serialize({ kind, watch: this.watcher.summary(), serverInstanceId: this.serverInstanceId,
|
|
209
|
+
sequence: this.sequence, timestamp: new Date().toISOString() }));
|
|
210
|
+
}
|
|
211
|
+
serialize(event) {
|
|
212
|
+
return 'id: ' + event.serverInstanceId + ':' + event.sequence + '\nevent: ' + event.kind + '\ndata: ' + JSON.stringify(event) + '\n\n';
|
|
213
|
+
}
|
|
214
|
+
send(client, message) {
|
|
215
|
+
if (client.response.destroyed || client.response.writableEnded)
|
|
216
|
+
return;
|
|
217
|
+
if (client.queued + client.response.writableLength + Buffer.byteLength(message) > LIMITS.queuedBytes) {
|
|
218
|
+
client.response.destroy();
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
client.pending.push(message);
|
|
222
|
+
client.queued += Buffer.byteLength(message);
|
|
223
|
+
this.flush(client);
|
|
224
|
+
}
|
|
225
|
+
flush(client) {
|
|
226
|
+
while (!client.blocked && client.pending.length && !client.response.destroyed && !client.response.writableEnded) {
|
|
227
|
+
const message = client.pending.shift();
|
|
228
|
+
client.queued -= Buffer.byteLength(message);
|
|
229
|
+
client.blocked = !client.response.write(message);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=project-live-stream.js.map
|