@theihtisham/agent-shadow-brain 7.2.0 → 7.22.1
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 +482 -427
- package/README.md +202 -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 +39 -87
- 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 +2535 -1552
- 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 +125 -105
- 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_CHECKLIST_v7.0.0.md +24 -24
- package/docs/launch/RELEASE_NOTES_v7.0.0.md +44 -44
- package/docs/launch/RELEASE_NOTES_v7.1.0.md +32 -32
- 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.2.0.md +24 -24
- package/docs/launch/RELEASE_NOTES_v7.22.0.md +53 -0
- package/docs/launch/RELEASE_NOTES_v7.22.1.md +11 -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 +139 -111
- package/skills/shadow-debug/SKILL.md +16 -16
- package/skills/shadow-implement/SKILL.md +16 -16
- package/skills/shadow-release/SKILL.md +16 -16
- package/skills/shadow-research/SKILL.md +14 -12
- package/skills/shadow-review/SKILL.md +14 -14
- package/skills/shadow-workflow/SKILL.md +39 -31
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export declare const SOURCE_LIMITS: Readonly<{
|
|
2
|
+
bytes: number;
|
|
3
|
+
items: 500;
|
|
4
|
+
itemChars: 6000;
|
|
5
|
+
extractedChars: 180000;
|
|
6
|
+
sources: 200;
|
|
7
|
+
operations: 20000;
|
|
8
|
+
}>;
|
|
9
|
+
export type SourceKind = 'knowledge-json' | 'transcript-json' | 'text' | 'markdown';
|
|
10
|
+
export type SourceRole = 'user' | 'assistant' | 'system' | 'developer' | 'tool';
|
|
11
|
+
export interface SourceItem {
|
|
12
|
+
id: string;
|
|
13
|
+
title: string;
|
|
14
|
+
text: string;
|
|
15
|
+
category: string;
|
|
16
|
+
role?: SourceRole;
|
|
17
|
+
source?: string;
|
|
18
|
+
status: 'pending' | 'approved' | 'rejected';
|
|
19
|
+
memoryId: string | null;
|
|
20
|
+
approved?: {
|
|
21
|
+
title: string;
|
|
22
|
+
text: string;
|
|
23
|
+
category: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface SourceImport {
|
|
27
|
+
id: string;
|
|
28
|
+
projectId: string;
|
|
29
|
+
kind: SourceKind;
|
|
30
|
+
name: string;
|
|
31
|
+
sha256: string;
|
|
32
|
+
bytes: number;
|
|
33
|
+
parser: string;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
title: string;
|
|
36
|
+
items: SourceItem[];
|
|
37
|
+
}
|
|
38
|
+
export type SourceImportPreview = SourceImport;
|
|
39
|
+
export interface MemoryEvidenceResult {
|
|
40
|
+
memoryId: string;
|
|
41
|
+
projectId: string;
|
|
42
|
+
state: 'resolved' | 'reference-only' | 'missing' | 'mismatch';
|
|
43
|
+
evidence?: {
|
|
44
|
+
kind: 'pdf-page' | 'json-item' | 'transcript-message' | 'text-section' | 'lesson-outcome';
|
|
45
|
+
title: string;
|
|
46
|
+
text: string;
|
|
47
|
+
truncated: boolean;
|
|
48
|
+
sourceId: string;
|
|
49
|
+
sha256?: string;
|
|
50
|
+
page?: number;
|
|
51
|
+
locator?: string;
|
|
52
|
+
role?: string;
|
|
53
|
+
roomId?: string;
|
|
54
|
+
outcomeId?: string;
|
|
55
|
+
artifactId?: string;
|
|
56
|
+
artifactSha256?: string;
|
|
57
|
+
reported?: boolean;
|
|
58
|
+
approvedText?: string;
|
|
59
|
+
approvedTitle?: string;
|
|
60
|
+
category?: string;
|
|
61
|
+
outcome?: {
|
|
62
|
+
result: 'pass' | 'fail' | 'partial';
|
|
63
|
+
check: string;
|
|
64
|
+
evidence: string;
|
|
65
|
+
provenance: 'agent-report' | 'user-report';
|
|
66
|
+
};
|
|
67
|
+
evaluation?: {
|
|
68
|
+
baseline: boolean;
|
|
69
|
+
candidate: boolean;
|
|
70
|
+
control: boolean;
|
|
71
|
+
evidence: string;
|
|
72
|
+
provenance: 'user-report';
|
|
73
|
+
method: 'operator-reported-comparison';
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
references: string[];
|
|
77
|
+
}
|
|
78
|
+
export interface SourceReviewInput {
|
|
79
|
+
decision: 'approve' | 'reject';
|
|
80
|
+
key: string;
|
|
81
|
+
title?: string;
|
|
82
|
+
text?: string;
|
|
83
|
+
category?: string;
|
|
84
|
+
}
|
|
85
|
+
export interface ReviewedSessionTranscript {
|
|
86
|
+
id: string;
|
|
87
|
+
name: string;
|
|
88
|
+
items: Array<{
|
|
89
|
+
id: string;
|
|
90
|
+
locator: string;
|
|
91
|
+
role: 'user' | 'assistant' | 'note';
|
|
92
|
+
originalRole: SourceRole;
|
|
93
|
+
text: string;
|
|
94
|
+
}>;
|
|
95
|
+
}
|
|
96
|
+
export interface SourceImportSummary {
|
|
97
|
+
id: string;
|
|
98
|
+
name: string;
|
|
99
|
+
title: string;
|
|
100
|
+
kind: SourceKind;
|
|
101
|
+
sha256: string;
|
|
102
|
+
bytes: number;
|
|
103
|
+
createdAt: string;
|
|
104
|
+
itemCount: number;
|
|
105
|
+
approvedCount: number;
|
|
106
|
+
pendingCount: number;
|
|
107
|
+
rejectedCount: number;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=project-source-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-source-contract.d.ts","sourceRoot":"","sources":["../../src/brain/project-source-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-source-contract.js","sourceRoot":"","sources":["../../src/brain/project-source-contract.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { GlobalBrain } from './global-brain.js';
|
|
2
|
+
import { type SourceImport, type SourceReviewInput, type MemoryEvidenceResult, type ReviewedSessionTranscript, type SourceImportSummary } from './project-source-contract.js';
|
|
3
|
+
export declare class ProjectSourceIntake {
|
|
4
|
+
private readonly brain;
|
|
5
|
+
private readonly now;
|
|
6
|
+
private readonly project;
|
|
7
|
+
private database?;
|
|
8
|
+
constructor(directory: string, brain: GlobalBrain, now?: () => number);
|
|
9
|
+
close(): void;
|
|
10
|
+
private db;
|
|
11
|
+
/** Read existing storage without creating a project directory or modifying a damaged database. */
|
|
12
|
+
private read;
|
|
13
|
+
private transaction;
|
|
14
|
+
private row;
|
|
15
|
+
previewImport(name: string, bytes: Uint8Array): SourceImport;
|
|
16
|
+
/** The operator explicitly saves a short note. Originals and retry identities stay intact. */
|
|
17
|
+
rememberText(text: unknown): Promise<SourceImport>;
|
|
18
|
+
getImport(sourceId: string): SourceImport;
|
|
19
|
+
listImports(): SourceImport[];
|
|
20
|
+
listImportSummaries(): SourceImportSummary[];
|
|
21
|
+
/** Export only reviewed transcript material for an explicit session-history import. */
|
|
22
|
+
sessionTranscript(sourceId: string): ReviewedSessionTranscript;
|
|
23
|
+
reviewImportItem(sourceId: string, itemId: string, input: SourceReviewInput): Promise<SourceImport>;
|
|
24
|
+
resolveMemoryEvidence(memoryId: string): MemoryEvidenceResult;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=project-source-intake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-source-intake.d.ts","sourceRoot":"","sources":["../../src/brain/project-source-intake.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKrD,OAAO,EAAiB,KAAK,YAAY,EAAqD,KAAK,iBAAiB,EAAE,KAAK,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,KAAK,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAoFhP,qBAAa,mBAAmB;IAGC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAe,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFxF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IACjE,OAAO,CAAC,QAAQ,CAAC,CAAe;gBACpB,SAAS,EAAE,MAAM,EAAmB,KAAK,EAAE,WAAW,EAAmB,GAAG,eAAW;IACnG,KAAK,IAAI,IAAI;IACb,OAAO,CAAC,EAAE;IAoBV,kGAAkG;IAClG,OAAO,CAAC,IAAI;IAqBZ,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,GAAG;IAKX,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,YAAY;IAU5D,8FAA8F;IACxF,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;IAgBxD,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IACzC,WAAW,IAAI,YAAY,EAAE;IAC7B,mBAAmB,IAAI,mBAAmB,EAAE;IAW5C,uFAAuF;IACvF,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,yBAAyB;IA4BxD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAqCzG,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB;CA2D9D"}
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { lstatSync } from 'node:fs';
|
|
3
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
4
|
+
import { requireProjectStore } from './project-memory.js';
|
|
5
|
+
import { ensureProjectDirectory, projectLocalPath } from './project-kit-paths.js';
|
|
6
|
+
import { digest, HubStore } from './project-hub-store.js';
|
|
7
|
+
import { ProjectHubError } from './project-hub-contract.js';
|
|
8
|
+
import { SOURCE_LIMITS } from './project-source-contract.js';
|
|
9
|
+
const bad = (message, status = 400) => { throw new ProjectHubError('SOURCE_INVALID', message, status); };
|
|
10
|
+
const controls = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/u;
|
|
11
|
+
const forbidden = /^(?:__proto__|prototype|constructor|password|passwd|passkey|api[_-]?key|secret|secrets|credentials?|client[_-]?secret|private[_-]?key|token|id[_-]?token|auth[_-]?token|access[_-]?token|refresh[_-]?token|authorization|cookies?|session[_-]?token)$/iu;
|
|
12
|
+
const roles = new Set(['user', 'assistant', 'system', 'developer', 'tool']);
|
|
13
|
+
const field = (value, label, max, multiline = true) => {
|
|
14
|
+
if (typeof value !== 'string' || !value.trim() || value.length > max || controls.test(value) || (!multiline && /[\r\n\t]/u.test(value)))
|
|
15
|
+
bad(`${label} must be nonempty, at most ${max} characters, and contain no control characters.`);
|
|
16
|
+
return value;
|
|
17
|
+
};
|
|
18
|
+
function inspect(value, depth = 0) {
|
|
19
|
+
if (depth > 12)
|
|
20
|
+
bad('JSON nesting exceeds 12 levels.');
|
|
21
|
+
if (Array.isArray(value)) {
|
|
22
|
+
value.forEach(x => inspect(x, depth + 1));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (value && typeof value === 'object')
|
|
26
|
+
for (const [key, item] of Object.entries(value)) {
|
|
27
|
+
if (forbidden.test(key))
|
|
28
|
+
bad('JSON contains a prohibited credential-shaped or prototype field.');
|
|
29
|
+
inspect(item, depth + 1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function object(value, allowed, label) {
|
|
33
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
34
|
+
bad(`${label} must be an object.`);
|
|
35
|
+
const obj = value;
|
|
36
|
+
if (Object.keys(obj).some(k => !allowed.includes(k)))
|
|
37
|
+
bad(`${label} contains unsupported fields.`);
|
|
38
|
+
return obj;
|
|
39
|
+
}
|
|
40
|
+
function suggest(text) {
|
|
41
|
+
const first = text.split(/\r\n|\n|\r/u).find(line => line.trim())?.trim().replace(/^#{1,6}\s+/u, '') ?? 'Source section';
|
|
42
|
+
const category = /\b(?:must|should|requirement|constraint)\b/iu.test(text) ? 'requirement' : /\b(?:plan|step|todo|next)\b/iu.test(text) ? 'plan' : 'knowledge';
|
|
43
|
+
return { title: first.length > 150 ? first.slice(0, 147) + '...' : first, category };
|
|
44
|
+
}
|
|
45
|
+
function parse(name, bytes) {
|
|
46
|
+
if (!/^[^\\/:*?"<>|\u0000-\u001f\u007f]{1,110}\.(?:json|txt|md|markdown)$/iu.test(name) || name.startsWith('.') || name !== name.trim())
|
|
47
|
+
bad('Use an ordinary .json, .txt, .md or .markdown filename without path components.');
|
|
48
|
+
if (!bytes.length || bytes.length > SOURCE_LIMITS.bytes)
|
|
49
|
+
bad('Source must be between 1 byte and 1 MiB.', 413);
|
|
50
|
+
let content;
|
|
51
|
+
try {
|
|
52
|
+
content = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return bad('Source must be valid UTF-8.');
|
|
56
|
+
}
|
|
57
|
+
if (controls.test(content))
|
|
58
|
+
bad('Source contains unsupported control characters.');
|
|
59
|
+
let kind, title = name, items = [];
|
|
60
|
+
if (/\.json$/iu.test(name)) {
|
|
61
|
+
let value;
|
|
62
|
+
try {
|
|
63
|
+
value = JSON.parse(content);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return bad('Malformed JSON.');
|
|
67
|
+
}
|
|
68
|
+
inspect(value);
|
|
69
|
+
let records, transcript = false, topLevelArray = false;
|
|
70
|
+
if (Array.isArray(value)) {
|
|
71
|
+
records = value;
|
|
72
|
+
transcript = true;
|
|
73
|
+
topLevelArray = true;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const root = object(value, ['schemaVersion', 'kind', 'title', 'records', 'messages'], 'JSON root');
|
|
77
|
+
if (root.kind === 'knowledge' && root.schemaVersion === 1 && Array.isArray(root.records) && root.messages === undefined)
|
|
78
|
+
records = root.records;
|
|
79
|
+
else if (root.kind === 'transcript' && root.schemaVersion === 1 && Array.isArray(root.messages) && root.records === undefined) {
|
|
80
|
+
records = root.messages;
|
|
81
|
+
transcript = true;
|
|
82
|
+
}
|
|
83
|
+
else if (Object.keys(root).length === 1 && Array.isArray(root.messages)) {
|
|
84
|
+
records = root.messages;
|
|
85
|
+
transcript = true;
|
|
86
|
+
}
|
|
87
|
+
else
|
|
88
|
+
return bad('Unsupported JSON shape. Use knowledge JSON or a simple transcript.');
|
|
89
|
+
if (root.title !== undefined)
|
|
90
|
+
title = field(root.title, 'Title', 150, false);
|
|
91
|
+
else if (root.kind !== undefined)
|
|
92
|
+
bad('Versioned JSON requires a title.');
|
|
93
|
+
}
|
|
94
|
+
if (!records.length || records.length > SOURCE_LIMITS.items)
|
|
95
|
+
bad('Source must contain 1 to 500 records.');
|
|
96
|
+
kind = transcript ? 'transcript-json' : 'knowledge-json';
|
|
97
|
+
items = records.map((raw, index) => {
|
|
98
|
+
const row = object(raw, transcript ? ['role', 'content'] : ['title', 'content', 'source'], `Record ${index + 1}`);
|
|
99
|
+
const text = field(row.content, `Record ${index + 1} content`, SOURCE_LIMITS.itemChars);
|
|
100
|
+
const locator = topLevelArray ? `/${index}` : `/${transcript ? 'messages' : 'records'}/${index}`;
|
|
101
|
+
if (transcript) {
|
|
102
|
+
if (typeof row.role !== 'string' || !roles.has(row.role))
|
|
103
|
+
bad(`Message ${index + 1} has an unsupported role.`);
|
|
104
|
+
return { id: locator, title: `${row.role} message ${index + 1}`, text, category: 'transcript-evidence', role: row.role, status: 'pending', memoryId: null };
|
|
105
|
+
}
|
|
106
|
+
return { id: locator, title: field(row.title, `Record ${index + 1} title`, 150, false), text, category: 'knowledge',
|
|
107
|
+
...(row.source === undefined ? {} : { source: field(row.source, 'Source label', 500, false) }), status: 'pending', memoryId: null };
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
kind = /\.txt$/iu.test(name) ? 'text' : 'markdown';
|
|
112
|
+
// Paragraphs retain their exact nonblank lines and their original line numbers.
|
|
113
|
+
const lines = content.match(/[^\r\n]*(?:\r\n|\r|\n|$)/gu)?.filter(Boolean) ?? [];
|
|
114
|
+
let start = -1, buffer = '';
|
|
115
|
+
const flush = (end) => {
|
|
116
|
+
if (start < 0)
|
|
117
|
+
return;
|
|
118
|
+
const text = buffer.replace(/(?:\r\n|\r|\n)$/u, '');
|
|
119
|
+
field(text, `Lines ${start + 1}-${end}`, SOURCE_LIMITS.itemChars);
|
|
120
|
+
const suggestion = suggest(text);
|
|
121
|
+
items.push({ id: `lines:${start + 1}-${end}`, ...suggestion, text, status: 'pending', memoryId: null });
|
|
122
|
+
start = -1;
|
|
123
|
+
buffer = '';
|
|
124
|
+
};
|
|
125
|
+
lines.forEach((line, i) => { if (!line.trim())
|
|
126
|
+
flush(i);
|
|
127
|
+
else {
|
|
128
|
+
if (start < 0)
|
|
129
|
+
start = i;
|
|
130
|
+
buffer += line;
|
|
131
|
+
} });
|
|
132
|
+
flush(lines.length);
|
|
133
|
+
if (!items.length || items.length > SOURCE_LIMITS.items)
|
|
134
|
+
bad('Text must contain 1 to 500 paragraphs or sections.');
|
|
135
|
+
}
|
|
136
|
+
if (items.reduce((n, item) => n + item.text.length, 0) > SOURCE_LIMITS.extractedChars)
|
|
137
|
+
bad('Extracted text exceeds 180,000 characters.');
|
|
138
|
+
return { kind, title, items };
|
|
139
|
+
}
|
|
140
|
+
export class ProjectSourceIntake {
|
|
141
|
+
constructor(directory, brain, now = Date.now) {
|
|
142
|
+
this.brain = brain;
|
|
143
|
+
this.now = now;
|
|
144
|
+
this.project = requireProjectStore(directory, brain);
|
|
145
|
+
}
|
|
146
|
+
close() { this.database?.close(); this.database = undefined; }
|
|
147
|
+
db() {
|
|
148
|
+
ensureProjectDirectory(this.project.root, '.shadow-brain');
|
|
149
|
+
const relative = '.shadow-brain/project-sources.sqlite';
|
|
150
|
+
for (const suffix of ['', '-journal', '-wal', '-shm']) {
|
|
151
|
+
const filename = projectLocalPath(this.project.root, relative + suffix), info = lstatSync(filename, { throwIfNoEntry: false });
|
|
152
|
+
if (info && (!info.isFile() || info.nlink !== 1))
|
|
153
|
+
throw new ProjectHubError('SOURCE_UNSAFE_STORE', 'Source storage requires ordinary unlinked files.', 409);
|
|
154
|
+
}
|
|
155
|
+
if (this.database)
|
|
156
|
+
return this.database;
|
|
157
|
+
// Validate any existing store read-only before issuing schema or write statements.
|
|
158
|
+
const filename = projectLocalPath(this.project.root, relative);
|
|
159
|
+
if (lstatSync(filename, { throwIfNoEntry: false }))
|
|
160
|
+
this.read(() => undefined, () => undefined);
|
|
161
|
+
const db = new DatabaseSync(filename, { allowExtension: false });
|
|
162
|
+
try {
|
|
163
|
+
db.exec('PRAGMA busy_timeout=3000; PRAGMA trusted_schema=OFF; PRAGMA synchronous=FULL; CREATE TABLE IF NOT EXISTS metadata (project_id TEXT PRIMARY KEY, version INTEGER NOT NULL) STRICT; CREATE TABLE IF NOT EXISTS sources (id TEXT PRIMARY KEY, sha256 TEXT NOT NULL UNIQUE, data TEXT NOT NULL, bytes BLOB NOT NULL) STRICT; CREATE TABLE IF NOT EXISTS operations (key TEXT PRIMARY KEY, hash TEXT NOT NULL) STRICT;');
|
|
164
|
+
db.prepare('INSERT INTO metadata SELECT ?,1 WHERE NOT EXISTS(SELECT 1 FROM metadata)').run(this.project.projectId);
|
|
165
|
+
const rows = db.prepare('SELECT project_id,version FROM metadata LIMIT 2').all();
|
|
166
|
+
if (rows.length !== 1 || rows[0].project_id !== this.project.projectId || rows[0].version !== 1)
|
|
167
|
+
throw new Error('Source store belongs to another project or version.');
|
|
168
|
+
this.database = db;
|
|
169
|
+
return db;
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
db.close();
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/** Read existing storage without creating a project directory or modifying a damaged database. */
|
|
177
|
+
read(fn, absent) {
|
|
178
|
+
if (this.database)
|
|
179
|
+
return fn(this.database);
|
|
180
|
+
const relative = '.shadow-brain/project-sources.sqlite';
|
|
181
|
+
for (const suffix of ['', '-journal', '-wal', '-shm']) {
|
|
182
|
+
const path = projectLocalPath(this.project.root, relative + suffix);
|
|
183
|
+
const info = lstatSync(path, { throwIfNoEntry: false });
|
|
184
|
+
if (info && (!info.isFile() || info.nlink !== 1))
|
|
185
|
+
throw new ProjectHubError('SOURCE_UNSAFE_STORE', 'Source storage requires ordinary unlinked files.', 409);
|
|
186
|
+
}
|
|
187
|
+
const filename = projectLocalPath(this.project.root, relative);
|
|
188
|
+
if (!lstatSync(filename, { throwIfNoEntry: false }))
|
|
189
|
+
return absent();
|
|
190
|
+
let db;
|
|
191
|
+
try {
|
|
192
|
+
db = new DatabaseSync(filename, { readOnly: true, allowExtension: false });
|
|
193
|
+
db.exec('PRAGMA busy_timeout=3000; PRAGMA trusted_schema=OFF;');
|
|
194
|
+
const rows = db.prepare('SELECT project_id,version FROM metadata LIMIT 2').all();
|
|
195
|
+
if (rows.length !== 1 || rows[0].project_id !== this.project.projectId || rows[0].version !== 1)
|
|
196
|
+
throw new Error('Invalid source store scope.');
|
|
197
|
+
db.prepare('SELECT id,sha256,data,bytes FROM sources LIMIT 0').all();
|
|
198
|
+
db.prepare('SELECT key,hash FROM operations LIMIT 0').all();
|
|
199
|
+
return fn(db);
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
db?.close();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
transaction(fn) {
|
|
206
|
+
const db = this.db();
|
|
207
|
+
db.exec('BEGIN IMMEDIATE');
|
|
208
|
+
try {
|
|
209
|
+
const result = fn(db);
|
|
210
|
+
db.exec('COMMIT');
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
db.exec('ROLLBACK');
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
row(db, id) {
|
|
219
|
+
const value = db.prepare('SELECT data FROM sources WHERE id=?').get(id)?.data;
|
|
220
|
+
if (typeof value !== 'string')
|
|
221
|
+
throw new ProjectHubError('SOURCE_NOT_FOUND', 'Source was not found in this project.', 404);
|
|
222
|
+
return JSON.parse(value);
|
|
223
|
+
}
|
|
224
|
+
previewImport(name, bytes) {
|
|
225
|
+
const extracted = parse(name, bytes), sha256 = digest(bytes);
|
|
226
|
+
return this.transaction(db => {
|
|
227
|
+
const existing = db.prepare('SELECT data FROM sources WHERE sha256=?').get(sha256)?.data;
|
|
228
|
+
if (typeof existing === 'string')
|
|
229
|
+
return JSON.parse(existing);
|
|
230
|
+
if (Number(db.prepare('SELECT count(*) AS n FROM sources').get()?.n) >= SOURCE_LIMITS.sources)
|
|
231
|
+
bad('Project source limit reached.', 422);
|
|
232
|
+
const record = { id: randomUUID(), projectId: this.project.projectId, name, sha256, bytes: bytes.length, parser: 'deterministic-source-v1', createdAt: new Date(this.now()).toISOString(), ...extracted };
|
|
233
|
+
db.prepare('INSERT INTO sources VALUES(?,?,?,?)').run(record.id, sha256, JSON.stringify(record), bytes);
|
|
234
|
+
return record;
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/** The operator explicitly saves a short note. Originals and retry identities stay intact. */
|
|
238
|
+
async rememberText(text) {
|
|
239
|
+
const note = field(text, 'Note (use Review first for longer notes)', SOURCE_LIMITS.itemChars);
|
|
240
|
+
const bytes = Buffer.from(note, 'utf8');
|
|
241
|
+
if (parse('My-note.txt', bytes).items.length > 20)
|
|
242
|
+
bad('Use Review first for notes with more than 20 paragraphs.');
|
|
243
|
+
let source = this.previewImport('My-note.txt', bytes);
|
|
244
|
+
if (!['text', 'markdown'].includes(source.kind))
|
|
245
|
+
throw new ProjectHubError('SOURCE_CONFLICT', 'This text was already imported in another format. Open its existing source review.', 409);
|
|
246
|
+
if (source.items.some(item => item.status === 'rejected'))
|
|
247
|
+
throw new ProjectHubError('SOURCE_CONFLICT', 'These notes contain previously skipped parts. Open the source review to inspect the saved decisions.', 409);
|
|
248
|
+
for (const item of source.items) {
|
|
249
|
+
if (item.status === 'approved')
|
|
250
|
+
continue;
|
|
251
|
+
source = await this.reviewImportItem(source.id, item.id, {
|
|
252
|
+
decision: 'approve', key: 'remember_' + digest(JSON.stringify([source.sha256, item.id])),
|
|
253
|
+
...(item.approved ?? {}),
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
return source;
|
|
257
|
+
}
|
|
258
|
+
getImport(sourceId) { return this.read(db => this.row(db, sourceId), () => { throw new ProjectHubError('SOURCE_NOT_FOUND', 'Source was not found in this project.', 404); }); }
|
|
259
|
+
listImports() { return this.read(db => db.prepare('SELECT data FROM sources ORDER BY rowid DESC').all().map(row => JSON.parse(row.data)), () => []); }
|
|
260
|
+
listImportSummaries() {
|
|
261
|
+
return this.read(db => db.prepare(`SELECT id, sha256, json_extract(data, '$.name') AS name,
|
|
262
|
+
json_extract(data, '$.title') AS title, json_extract(data, '$.kind') AS kind,
|
|
263
|
+
json_extract(data, '$.bytes') AS bytes, json_extract(data, '$.createdAt') AS createdAt,
|
|
264
|
+
json_array_length(data, '$.items') AS itemCount,
|
|
265
|
+
(SELECT count(*) FROM json_each(sources.data, '$.items') WHERE json_extract(value, '$.status')='approved') AS approvedCount,
|
|
266
|
+
(SELECT count(*) FROM json_each(sources.data, '$.items') WHERE json_extract(value, '$.status')='pending') AS pendingCount,
|
|
267
|
+
(SELECT count(*) FROM json_each(sources.data, '$.items') WHERE json_extract(value, '$.status')='rejected') AS rejectedCount
|
|
268
|
+
FROM sources ORDER BY rowid DESC LIMIT 200`).all(), () => []);
|
|
269
|
+
}
|
|
270
|
+
/** Export only reviewed transcript material for an explicit session-history import. */
|
|
271
|
+
sessionTranscript(sourceId) {
|
|
272
|
+
const row = this.read(db => db.prepare('SELECT data,bytes FROM sources WHERE id=?').get(sourceId), () => undefined);
|
|
273
|
+
if (!row)
|
|
274
|
+
throw new ProjectHubError('SOURCE_NOT_FOUND', 'Source was not found in this project.', 404);
|
|
275
|
+
const record = JSON.parse(row.data), bytes = row.bytes;
|
|
276
|
+
if (record.projectId !== this.project.projectId || record.id !== sourceId || record.kind !== 'transcript-json')
|
|
277
|
+
bad('Choose a reviewed transcript source.');
|
|
278
|
+
if (digest(bytes) !== record.sha256)
|
|
279
|
+
throw new ProjectHubError('SOURCE_MISMATCH', 'Stored source bytes do not match their digest.', 409);
|
|
280
|
+
const original = parse(record.name, bytes);
|
|
281
|
+
if (original.kind !== record.kind)
|
|
282
|
+
throw new ProjectHubError('SOURCE_MISMATCH', 'Stored transcript does not match its source.', 409);
|
|
283
|
+
const selected = record.items.filter(item => item.status === 'approved');
|
|
284
|
+
if (!selected.length)
|
|
285
|
+
bad('Approve at least one transcript message before importing.');
|
|
286
|
+
if (!lstatSync(this.project.storagePath, { throwIfNoEntry: false }))
|
|
287
|
+
throw new ProjectHubError('SOURCE_MEMORY_UNAVAILABLE', 'Project memory is unavailable; reviewed messages cannot be verified.', 503);
|
|
288
|
+
this.brain.refresh();
|
|
289
|
+
if (this.brain.getStorageHealth().lastError)
|
|
290
|
+
throw new ProjectHubError('SOURCE_MEMORY_UNAVAILABLE', 'Project memory is unavailable; reviewed messages cannot be verified.', 503);
|
|
291
|
+
const originals = new Map(original.items.map(item => [item.id, item]));
|
|
292
|
+
const items = selected.map(item => {
|
|
293
|
+
const source = originals.get(item.id);
|
|
294
|
+
if (!source || !item.approved || !item.memoryId || !item.role || source.role !== item.role || source.text !== item.text || source.title !== item.title) {
|
|
295
|
+
throw new ProjectHubError('SOURCE_MISMATCH', 'Reviewed transcript no longer matches its original source.', 409);
|
|
296
|
+
}
|
|
297
|
+
const memory = this.brain.getEntry(item.memoryId), metadata = memory?.metadata;
|
|
298
|
+
if (!memory || memory.projectId !== this.project.projectId || memory.content !== item.approved.title + '\n' + item.approved.text || metadata?.origin !== 'project-source-import' || metadata.sourceId !== record.id || metadata.sourceSha256 !== record.sha256 || metadata.sourceKind !== record.kind || metadata.sourceLocator !== item.id || metadata.sourceRole !== item.role) {
|
|
299
|
+
throw new ProjectHubError('SOURCE_MISMATCH', 'A reviewed transcript memory could not be verified.', 409);
|
|
300
|
+
}
|
|
301
|
+
return { id: item.id, locator: item.id, role: item.role === 'user' || item.role === 'assistant' ? item.role : 'note',
|
|
302
|
+
originalRole: item.role, text: item.approved.text };
|
|
303
|
+
});
|
|
304
|
+
return { id: record.id, name: record.title, items };
|
|
305
|
+
}
|
|
306
|
+
async reviewImportItem(sourceId, itemId, input) {
|
|
307
|
+
if (!input || !['approve', 'reject'].includes(input.decision) || !/^[A-Za-z0-9_-]{12,100}$/u.test(input.key) || Object.keys(input).some(k => !['decision', 'key', 'title', 'text', 'category'].includes(k)))
|
|
308
|
+
bad('Invalid review decision or operation key.');
|
|
309
|
+
if (input.decision === 'reject' && (input.title !== undefined || input.text !== undefined || input.category !== undefined))
|
|
310
|
+
bad('Edits apply only to approval.');
|
|
311
|
+
const pending = this.transaction(db => {
|
|
312
|
+
const hash = digest(JSON.stringify({ sourceId, itemId, input }));
|
|
313
|
+
const previous = db.prepare('SELECT hash FROM operations WHERE key=?').get(input.key);
|
|
314
|
+
if (previous && previous.hash !== hash)
|
|
315
|
+
throw new ProjectHubError('SOURCE_CONFLICT', 'Operation key already used with another request.', 409);
|
|
316
|
+
const record = this.row(db, sourceId), item = record.items.find(x => x.id === itemId);
|
|
317
|
+
if (!item)
|
|
318
|
+
throw new ProjectHubError('SOURCE_NOT_FOUND', 'Source item was not found.', 404);
|
|
319
|
+
if (input.decision === 'reject') {
|
|
320
|
+
if (item.memoryId)
|
|
321
|
+
throw new ProjectHubError('SOURCE_CONFLICT', 'This item already has an approval.', 409);
|
|
322
|
+
item.status = 'rejected';
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
if (item.status === 'rejected')
|
|
326
|
+
throw new ProjectHubError('SOURCE_CONFLICT', 'This item was rejected.', 409);
|
|
327
|
+
const approved = { title: field(input.title ?? item.title, 'Approved title', 150, false), text: field(input.text ?? item.text, 'Approved text', SOURCE_LIMITS.itemChars), category: field(input.category ?? item.category, 'Category', 64, false) };
|
|
328
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9 _.-]{0,63}$/u.test(approved.category))
|
|
329
|
+
bad('Category must use plain letters, numbers, spaces, dots, hyphens or underscores.');
|
|
330
|
+
if (item.approved && JSON.stringify(item.approved) !== JSON.stringify(approved))
|
|
331
|
+
throw new ProjectHubError('SOURCE_CONFLICT', 'This item has already been approved with different text.', 409);
|
|
332
|
+
item.memoryId ?? (item.memoryId = randomUUID());
|
|
333
|
+
item.approved = approved;
|
|
334
|
+
}
|
|
335
|
+
if (!previous) {
|
|
336
|
+
if (Number(db.prepare('SELECT count(*) AS n FROM operations').get()?.n) >= SOURCE_LIMITS.operations)
|
|
337
|
+
bad('Source review operation limit reached.', 422);
|
|
338
|
+
db.prepare('INSERT INTO operations VALUES(?,?)').run(input.key, hash);
|
|
339
|
+
}
|
|
340
|
+
db.prepare('UPDATE sources SET data=? WHERE id=?').run(JSON.stringify(record), sourceId);
|
|
341
|
+
return { record, item };
|
|
342
|
+
});
|
|
343
|
+
if (input.decision === 'approve') {
|
|
344
|
+
const { record, item } = pending, approved = item.approved;
|
|
345
|
+
await this.brain.init();
|
|
346
|
+
this.brain.refresh();
|
|
347
|
+
if (this.brain.getStorageHealth().lastError)
|
|
348
|
+
throw new ProjectHubError('SOURCE_MEMORY_UNAVAILABLE', 'Project memory unavailable; retry with the same key.', 503);
|
|
349
|
+
this.brain.writeSync({ projectId: this.project.projectId, projectName: this.project.projectName, category: approved.category, agentTool: 'user', content: approved.title + '\n' + approved.text, importance: 0.7,
|
|
350
|
+
metadata: { origin: 'project-source-import', sourceId, sourceSha256: record.sha256, sourceKind: record.kind, sourceLocator: item.id, untrustedEvidence: true, title: approved.title, ...(item.role ? { sourceRole: item.role } : {}), sources: [`${record.name} · sha256:${record.sha256} · ${item.id}`, ...(item.source ? [item.source] : [])] } }, item.memoryId);
|
|
351
|
+
await this.brain.sync();
|
|
352
|
+
this.transaction(db => { const latest = this.row(db, sourceId), current = latest.items.find(x => x.id === itemId); current.status = 'approved'; db.prepare('UPDATE sources SET data=? WHERE id=?').run(JSON.stringify(latest), sourceId); });
|
|
353
|
+
}
|
|
354
|
+
return this.getImport(sourceId);
|
|
355
|
+
}
|
|
356
|
+
resolveMemoryEvidence(memoryId) {
|
|
357
|
+
const base = { memoryId, projectId: this.project.projectId, state: 'missing', references: [] };
|
|
358
|
+
// A read on a new or removed store must not create it or expose stale in-process entries.
|
|
359
|
+
if (!lstatSync(this.project.storagePath, { throwIfNoEntry: false }))
|
|
360
|
+
return base;
|
|
361
|
+
this.brain.refresh();
|
|
362
|
+
if (this.brain.getStorageHealth().lastError)
|
|
363
|
+
throw new ProjectHubError('SOURCE_MEMORY_UNAVAILABLE', 'Project memory is unavailable; source evidence cannot be verified.', 503);
|
|
364
|
+
const memory = this.brain.getEntry(memoryId);
|
|
365
|
+
if (!memory || memory.projectId !== this.project.projectId)
|
|
366
|
+
return base;
|
|
367
|
+
const meta = memory.metadata ?? {}, references = Array.isArray(meta.sources) ? meta.sources.filter((x) => typeof x === 'string').slice(0, 10).map(x => x.slice(0, 500)) : [];
|
|
368
|
+
base.references = references;
|
|
369
|
+
base.state = references.length ? 'reference-only' : 'missing';
|
|
370
|
+
const bounded = (text) => ({ text: text.slice(0, 8000), truncated: text.length > 8000 });
|
|
371
|
+
if (meta.origin === 'project-source-import') {
|
|
372
|
+
base.state = 'mismatch';
|
|
373
|
+
if (typeof meta.sourceId !== 'string' || typeof meta.sourceLocator !== 'string')
|
|
374
|
+
return base;
|
|
375
|
+
const row = this.read(db => db.prepare('SELECT data,bytes FROM sources WHERE id=?').get(meta.sourceId), () => undefined);
|
|
376
|
+
if (!row) {
|
|
377
|
+
base.state = 'missing';
|
|
378
|
+
return base;
|
|
379
|
+
}
|
|
380
|
+
const record = JSON.parse(row.data), bytes = row.bytes;
|
|
381
|
+
if (record.projectId !== this.project.projectId || digest(bytes) !== record.sha256 || meta.sourceSha256 !== record.sha256 || meta.sourceKind !== record.kind)
|
|
382
|
+
return base;
|
|
383
|
+
const item = record.items.find(x => x.id === meta.sourceLocator);
|
|
384
|
+
if (!item || item.memoryId !== memoryId || item.status !== 'approved' || !item.approved || memory.content !== item.approved.title + '\n' + item.approved.text)
|
|
385
|
+
return base;
|
|
386
|
+
let original;
|
|
387
|
+
try {
|
|
388
|
+
original = parse(record.name, bytes).items.find(x => x.id === item.id);
|
|
389
|
+
}
|
|
390
|
+
catch {
|
|
391
|
+
return base;
|
|
392
|
+
}
|
|
393
|
+
if (!original || original.text !== item.text || original.title !== item.title || original.role !== item.role)
|
|
394
|
+
return base;
|
|
395
|
+
base.state = 'resolved';
|
|
396
|
+
base.evidence = { kind: record.kind === 'transcript-json' ? 'transcript-message' : record.kind === 'knowledge-json' ? 'json-item' : 'text-section', title: item.title, ...bounded(item.text), sourceId: record.id, sha256: record.sha256, locator: item.id, ...(item.role ? { role: item.role } : {}), approvedText: item.approved.text, approvedTitle: item.approved.title, category: item.approved.category };
|
|
397
|
+
return base;
|
|
398
|
+
}
|
|
399
|
+
if (meta.origin === 'project-hub-document' || meta.origin === 'project-hub-lesson') {
|
|
400
|
+
base.state = 'mismatch';
|
|
401
|
+
const hubPath = projectLocalPath(this.project.root, '.shadow-brain/project-hub.sqlite');
|
|
402
|
+
if (!lstatSync(hubPath, { throwIfNoEntry: false })) {
|
|
403
|
+
base.state = 'missing';
|
|
404
|
+
return base;
|
|
405
|
+
}
|
|
406
|
+
const hub = new HubStore(this.project.root, this.project.projectId);
|
|
407
|
+
try {
|
|
408
|
+
hub.checkStorage();
|
|
409
|
+
if (meta.origin === 'project-hub-document') {
|
|
410
|
+
if (typeof meta.documentId !== 'string' || typeof meta.page !== 'number')
|
|
411
|
+
return base;
|
|
412
|
+
const doc = hub.get('documents', meta.documentId);
|
|
413
|
+
if (!doc) {
|
|
414
|
+
base.state = 'missing';
|
|
415
|
+
return base;
|
|
416
|
+
}
|
|
417
|
+
const page = doc.pages.find(x => x.page === meta.page), bytes = hub.blob('pdf:' + doc.sha256);
|
|
418
|
+
if (!page || !bytes || digest(bytes) !== doc.sha256 || doc.sha256 !== meta.documentSha256 || page.memoryId !== memoryId || page.status !== 'approved' || memory.content !== `${doc.name} · p. ${page.page}\n${page.text}`)
|
|
419
|
+
return base;
|
|
420
|
+
base.state = 'resolved';
|
|
421
|
+
base.evidence = { kind: 'pdf-page', title: doc.name, ...bounded(page.text), truncated: page.truncated || page.text.length > 8000, sourceId: doc.id, sha256: doc.sha256, page: page.page };
|
|
422
|
+
return base;
|
|
423
|
+
}
|
|
424
|
+
if (typeof meta.lessonId !== 'string' || typeof meta.outcomeId !== 'string')
|
|
425
|
+
return base;
|
|
426
|
+
const lesson = hub.get('lessons', meta.lessonId), outcome = hub.get('outcomes', meta.outcomeId);
|
|
427
|
+
if (!lesson || !outcome) {
|
|
428
|
+
base.state = 'missing';
|
|
429
|
+
return base;
|
|
430
|
+
}
|
|
431
|
+
if (lesson.memoryId !== memoryId || lesson.outcomeId !== outcome.id || memory.content !== lesson.title + '\n' + lesson.text || !['promoted', 'rolled-back'].includes(lesson.status))
|
|
432
|
+
return base;
|
|
433
|
+
let artifact;
|
|
434
|
+
if (outcome.artifactId) {
|
|
435
|
+
artifact = hub.get('artifacts', outcome.artifactId, outcome.roomId);
|
|
436
|
+
if (!artifact) {
|
|
437
|
+
base.state = 'missing';
|
|
438
|
+
return base;
|
|
439
|
+
}
|
|
440
|
+
const bytes = hub.blob('artifact:' + artifact.sha256);
|
|
441
|
+
if (!bytes || digest(bytes) !== artifact.sha256 || artifact.taskId !== outcome.taskId)
|
|
442
|
+
return base;
|
|
443
|
+
}
|
|
444
|
+
base.state = 'resolved';
|
|
445
|
+
base.evidence = { kind: 'lesson-outcome', title: lesson.title, ...bounded(lesson.text), sourceId: lesson.id, outcomeId: outcome.id, roomId: outcome.roomId, ...(artifact ? { artifactId: artifact.id, artifactSha256: artifact.sha256 } : {}), reported: true,
|
|
446
|
+
outcome: { result: outcome.result, check: outcome.check.slice(0, 240), evidence: outcome.evidence.slice(0, 3000), provenance: outcome.provenance },
|
|
447
|
+
...(lesson.evaluation ? { evaluation: { baseline: lesson.evaluation.baseline, candidate: lesson.evaluation.candidate, control: lesson.evaluation.control, evidence: lesson.evaluation.evidence.slice(0, 4000), provenance: lesson.evaluation.provenance, method: lesson.evaluation.method } } : {}) };
|
|
448
|
+
return base;
|
|
449
|
+
}
|
|
450
|
+
finally {
|
|
451
|
+
hub.close();
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return base;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
//# sourceMappingURL=project-source-intake.js.map
|