@theihtisham/agent-shadow-brain 7.1.3 → 7.1.4
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 +20 -0
- package/README.md +125 -90
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/brain/activity-journal.d.ts.map +1 -1
- package/dist/brain/activity-journal.js +2 -1
- package/dist/brain/activity-journal.js.map +1 -1
- package/dist/brain/auto-update.js +1 -1
- package/dist/brain/brain-portability.js +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 +2 -0
- package/dist/brain/client-integrations.d.ts.map +1 -1
- package/dist/brain/client-integrations.js +8 -27
- package/dist/brain/client-integrations.js.map +1 -1
- package/dist/brain/context-assembly.d.ts +10 -2
- package/dist/brain/context-assembly.d.ts.map +1 -1
- package/dist/brain/context-assembly.js +238 -14
- package/dist/brain/context-assembly.js.map +1 -1
- 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 +22 -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 +300 -0
- package/dist/brain/context-retrieval.js.map +1 -0
- package/dist/brain/feature-settings.d.ts.map +1 -1
- package/dist/brain/feature-settings.js +2 -1
- 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 +11 -1
- package/dist/brain/global-brain.d.ts.map +1 -1
- package/dist/brain/global-brain.js +58 -6
- package/dist/brain/global-brain.js.map +1 -1
- package/dist/brain/mcp-server.d.ts +9 -0
- package/dist/brain/mcp-server.d.ts.map +1 -1
- package/dist/brain/mcp-server.js +237 -53
- package/dist/brain/mcp-server.js.map +1 -1
- package/dist/brain/mcp-stdio.d.ts.map +1 -1
- package/dist/brain/mcp-stdio.js +10 -4
- package/dist/brain/mcp-stdio.js.map +1 -1
- package/dist/brain/memory-annotations.d.ts.map +1 -1
- package/dist/brain/memory-annotations.js +2 -1
- package/dist/brain/memory-annotations.js.map +1 -1
- package/dist/brain/memory-inspection.d.ts +72 -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 +44 -0
- package/dist/brain/memory-mcp-content.d.ts.map +1 -0
- package/dist/brain/memory-mcp-content.js +91 -0
- package/dist/brain/memory-mcp-content.js.map +1 -0
- package/dist/brain/orchestrator.js +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 +289 -0
- package/dist/brain/project-feedback.js.map +1 -0
- package/dist/brain/project-hub-contract.d.ts +326 -0
- package/dist/brain/project-hub-contract.d.ts.map +1 -0
- package/dist/brain/project-hub-contract.js +56 -0
- package/dist/brain/project-hub-contract.js.map +1 -0
- package/dist/brain/project-hub-mcp.d.ts +168 -0
- package/dist/brain/project-hub-mcp.d.ts.map +1 -0
- package/dist/brain/project-hub-mcp.js +41 -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 +38 -0
- package/dist/brain/project-hub-store.d.ts.map +1 -0
- package/dist/brain/project-hub-store.js +189 -0
- package/dist/brain/project-hub-store.js.map +1 -0
- package/dist/brain/project-hub.d.ts +127 -0
- package/dist/brain/project-hub.d.ts.map +1 -0
- package/dist/brain/project-hub.js +381 -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 +41 -0
- package/dist/brain/project-kit.d.ts.map +1 -0
- package/dist/brain/project-kit.js +255 -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/subconscious.js +2 -2
- package/dist/brain/subconscious.js.map +1 -1
- 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 +22 -3
- package/dist/cli.js.map +1 -1
- package/dist/context-cli.d.ts.map +1 -1
- package/dist/context-cli.js +39 -5
- package/dist/context-cli.js.map +1 -1
- 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 +137 -0
- package/dist/dashboard/brain-hub-actions.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 +335 -0
- package/dist/dashboard/brain-hub-client.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 +176 -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 +30 -0
- package/dist/dashboard/brain-hub-html.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 +79 -0
- package/dist/dashboard/brain-hub-project-views.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 +150 -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.map +1 -1
- package/dist/dashboard/live-workspace-html.js +177 -28
- package/dist/dashboard/live-workspace-html.js.map +1 -1
- 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-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-workspace.d.ts +16 -0
- package/dist/dashboard/project-workspace.d.ts.map +1 -0
- package/dist/dashboard/project-workspace.js +106 -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 +15 -4
- 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 +27 -27
- package/dist/dashboard/workspace-api.d.ts +6 -0
- package/dist/dashboard/workspace-api.d.ts.map +1 -1
- package/dist/dashboard/workspace-api.js +154 -34
- 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 +487 -81
- package/dist/dashboard/workspace-html.js.map +1 -1
- package/dist/dashboard/workspace-status.d.ts +50 -0
- package/dist/dashboard/workspace-status.d.ts.map +1 -0
- package/dist/dashboard/workspace-status.js +22 -0
- package/dist/dashboard/workspace-status.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/integration-cli.d.ts.map +1 -1
- package/dist/integration-cli.js +6 -4
- package/dist/integration-cli.js.map +1 -1
- 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 +1 -1
- package/dist/types.d.ts.map +1 -1
- 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 +24 -0
- package/docs/INTEGRATIONS.md +68 -0
- package/docs/LEARNING.md +46 -0
- package/docs/PROJECT_KIT.md +93 -0
- package/docs/QUICKSTART.md +44 -0
- package/docs/README.md +33 -0
- package/docs/ROADMAP-v7.md +147 -0
- package/docs/SHARING.md +13 -0
- package/docs/SHOWCASE.md +87 -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/WORKFLOW_INTEGRATION.md +19 -1
- package/docs/WORKSPACE.md +17 -91
- 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/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.4.gif +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_NOTES_v7.1.4.md +30 -0
- package/docs/launch/RESEARCH_AND_PLAN_v7.1.4.md +255 -0
- package/package.json +25 -7
- package/skills/shadow-research/SKILL.md +2 -0
- package/skills/shadow-workflow/SKILL.md +6 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v6-dashboard-html.d.ts","sourceRoot":"","sources":["../../src/dashboard/v6-dashboard-html.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"v6-dashboard-html.d.ts","sourceRoot":"","sources":["../../src/dashboard/v6-dashboard-html.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,6trTAqtItB,CAAC"}
|
|
@@ -1129,9 +1129,9 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
1129
1129
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
|
|
1130
1130
|
Activity
|
|
1131
1131
|
</button>
|
|
1132
|
-
<button class="nav-item" data-tab="agents" data-title="
|
|
1132
|
+
<button class="nav-item" data-tab="agents" data-title="Client setup" title="Inspect coding-client configuration and recorded tool identities.">
|
|
1133
1133
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
|
1134
|
-
|
|
1134
|
+
Client setup<span class="badge-count" id="badge-agents">0</span>
|
|
1135
1135
|
</button>
|
|
1136
1136
|
<button class="nav-item" data-tab="livebrain" data-title="Brain Health" title="A health check of your brain's memory quality, with tips to improve it.">
|
|
1137
1137
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>
|
|
@@ -1149,9 +1149,9 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
1149
1149
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19V5"/><path d="M4 6h9l1 2h6v8h-9l-1-2H4"/></svg>
|
|
1150
1150
|
Project Memory<span class="badge-count" id="badge-ww2br">0</span>
|
|
1151
1151
|
</button>
|
|
1152
|
-
<button class="nav-item" data-tab="graph" data-title="
|
|
1152
|
+
<button class="nav-item" data-tab="graph" data-title="Recorded network" title="Configured clients and newly observed recorded events.">
|
|
1153
1153
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><circle cx="12" cy="12" r="8"/></svg>
|
|
1154
|
-
|
|
1154
|
+
Recorded network
|
|
1155
1155
|
</button>
|
|
1156
1156
|
<button class="nav-item" data-tab="seeder" data-title="Add Knowledge" title="Research a topic and save it as verified, source-backed knowledge.">
|
|
1157
1157
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="M5 9c0-3 2-5 7-7 5 2 7 4 7 7 0 5-4 8-7 8s-7-3-7-8z"/><path d="M8 12h8"/></svg>
|
|
@@ -1279,7 +1279,7 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
1279
1279
|
|
|
1280
1280
|
<div class="grid cols-4">
|
|
1281
1281
|
<div class="card stat-card accent">
|
|
1282
|
-
<div class="label">
|
|
1282
|
+
<div class="label">Recorded tools</div>
|
|
1283
1283
|
<div class="value accent" id="ov-agents">—</div>
|
|
1284
1284
|
<div class="trend">AI tools linked to your brain</div>
|
|
1285
1285
|
</div>
|
|
@@ -1941,7 +1941,7 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
1941
1941
|
</div>
|
|
1942
1942
|
<div class="grid cols-2 mt">
|
|
1943
1943
|
<div class="card stat-card"><div class="label">Monthly Projection</div><div class="value" id="tok-proj">$—</div><div class="trend">from last 7 days</div></div>
|
|
1944
|
-
<div class="card stat-card"><div class="label">
|
|
1944
|
+
<div class="card stat-card"><div class="label">Estimated opportunity</div><div class="value" style="color:var(--success)" id="tok-save">$—</div><div class="trend up">manual ledger · pricing estimates</div></div>
|
|
1945
1945
|
</div>
|
|
1946
1946
|
<div class="warning-banner mt" id="tok-runtime-note"><strong>Accuracy</strong><span>Token records are historical. Current agent and model spend are shown separately.</span></div>
|
|
1947
1947
|
<div class="grid cols-2 mt-lg">
|
|
@@ -2213,10 +2213,10 @@ const FEATURES = [
|
|
|
2213
2213
|
['memory','Memories','Browse and search saved knowledge'],
|
|
2214
2214
|
['chat','Ask the Brain','Ask questions in plain language'],
|
|
2215
2215
|
['activity','Activity','Live feed of what the brain is doing'],
|
|
2216
|
-
['agents','
|
|
2216
|
+
['agents','Client setup','Client configuration and recorded tools'],
|
|
2217
2217
|
['livebrain','Brain Health','Memory quality with tips to improve'],
|
|
2218
2218
|
['ww2br','Project Memory','Memory and status for one project'],
|
|
2219
|
-
['graph','
|
|
2219
|
+
['graph','Recorded network','Configured clients and newly observed recorded events'],
|
|
2220
2220
|
['seeder','Add Knowledge','Research a topic and save it as verified knowledge'],
|
|
2221
2221
|
['garden','Memory Garden','Watch your memories grow over time'],
|
|
2222
2222
|
['sabb','Sub-Agents','Share the right context with helper agents'],
|
|
@@ -2412,10 +2412,10 @@ async function refresh() {
|
|
|
2412
2412
|
state.hive = hive;
|
|
2413
2413
|
state.lastRefreshAt = Date.now();
|
|
2414
2414
|
|
|
2415
|
-
animateNum('stat-agents', hive.totalAgentsConnected ?? 0);
|
|
2415
|
+
animateNum('stat-agents', hive.totalRecordedAgents ?? hive.totalAgentsConnected ?? 0);
|
|
2416
2416
|
animateNum('stat-memories', hive.totalMemoriesStored ?? 0);
|
|
2417
2417
|
animateNum('stat-dreams', hive.modules.dream?.totalDreams ?? 0);
|
|
2418
|
-
animateNum('stat-tools', hive.totalAgentsConnected ?? 0);
|
|
2418
|
+
animateNum('stat-tools', hive.totalRecordedAgents ?? hive.totalAgentsConnected ?? 0);
|
|
2419
2419
|
document.getElementById('badge-sabb').textContent = hive.modules.sabb?.totalSpawns ?? 0;
|
|
2420
2420
|
document.getElementById('badge-causal').textContent = hive.modules.causal?.totalLinks ?? 0;
|
|
2421
2421
|
document.getElementById('badge-collision').textContent = hive.modules.collision?.collisionsDetected ?? 0;
|
|
@@ -2428,7 +2428,7 @@ async function refresh() {
|
|
|
2428
2428
|
async function refreshOverview() {
|
|
2429
2429
|
const hive = state.hive || await api('/api/v6/hive-status');
|
|
2430
2430
|
if (!hive) return;
|
|
2431
|
-
animateNum('ov-agents', hive.totalAgentsConnected ?? 0);
|
|
2431
|
+
animateNum('ov-agents', hive.totalRecordedAgents ?? hive.totalAgentsConnected ?? 0);
|
|
2432
2432
|
animateNum('ov-memories', hive.totalMemoriesStored ?? 0);
|
|
2433
2433
|
animateNum('ov-subagents', hive.modules.sabb?.totalSpawns ?? 0);
|
|
2434
2434
|
document.getElementById('ov-subagents-sub').textContent = \`grad: \${hive.modules.sabb?.graduated ?? 0} · quar: \${hive.modules.sabb?.quarantined ?? 0}\`;
|
|
@@ -2455,7 +2455,7 @@ async function refreshOverview() {
|
|
|
2455
2455
|
['Air-gap', hive.modules.airGap?.enabled ? 'ENABLED' : 'disabled', hive.modules.airGap?.enabled ? 'good' : ''],
|
|
2456
2456
|
['Version', hive.version, ''],
|
|
2457
2457
|
['Monthly cost', '$' + (hive.modules.tokenEconomy?.monthlyProjectionUsd?.toFixed?.(2) ?? '0.00'), 'warn'],
|
|
2458
|
-
['
|
|
2458
|
+
['Estimated savings opportunity', '$' + (hive.modules.tokenEconomy?.savingsOpportunitiesUsd?.toFixed?.(2) ?? '0.00'), 'good'],
|
|
2459
2459
|
];
|
|
2460
2460
|
document.getElementById('ov-health').innerHTML = health.map(([k, v, cls]) => \`<div class="row"><span class="k">\${k}</span><span class="v \${cls}">\${v}</span></div>\`).join('');
|
|
2461
2461
|
|
|
@@ -3298,7 +3298,7 @@ async function refreshConfig() {
|
|
|
3298
3298
|
document.getElementById('config-state').innerHTML = \`
|
|
3299
3299
|
<div class="row"><span class="k">Version</span><span class="v">\${hive.version}</span></div>
|
|
3300
3300
|
<div class="row"><span class="k">Local-first</span><span class="v \${hive.localFirst ? 'good' : 'warn'}">\${hive.localFirst ? 'YES' : 'no'}</span></div>
|
|
3301
|
-
<div class="row"><span class="k">
|
|
3301
|
+
<div class="row"><span class="k">Recorded tools</span><span class="v">\${hive.totalAgentsConnected}</span></div>
|
|
3302
3302
|
<div class="row"><span class="k">Memories stored</span><span class="v">\${hive.totalMemoriesStored}</span></div>
|
|
3303
3303
|
<div class="row"><span class="k">Modules active</span><span class="v good">\${Object.keys(hive.modules || {}).length}</span></div>\`;
|
|
3304
3304
|
}
|
|
@@ -3614,14 +3614,7 @@ function ingestActivity(raw, fresh) {
|
|
|
3614
3614
|
if (!activityPaused) {
|
|
3615
3615
|
appendLog(e.source, e.type, e.detail);
|
|
3616
3616
|
if (fresh) {
|
|
3617
|
-
|
|
3618
|
-
if (typeof graphTimer !== 'undefined' && graphTimer) {
|
|
3619
|
-
const col = signalColors[e.type] || '#18ffff';
|
|
3620
|
-
const srcExists = graphNodes.find(n => n.id === e.source);
|
|
3621
|
-
graphSignals.push({ fromId: srcExists ? e.source : 'brain', toId: 'brain', type: e.type, color: col, progress: 0, spawnedAt: Date.now() });
|
|
3622
|
-
if (graphSignals.length > 100) graphSignals = graphSignals.slice(-100);
|
|
3623
|
-
}
|
|
3624
|
-
} catch (err) {}
|
|
3617
|
+
// Graph animation consumes the deduplicated stored-event stream in pullTopology.
|
|
3625
3618
|
lastIngestFresh = true;
|
|
3626
3619
|
}
|
|
3627
3620
|
}
|
|
@@ -3707,6 +3700,7 @@ async function refreshActivity() {
|
|
|
3707
3700
|
}
|
|
3708
3701
|
|
|
3709
3702
|
// ──── Live Graph ───────────────────────────────────────────────────────
|
|
3703
|
+
let graphObservedEvents = new Set(), graphObserved = false;
|
|
3710
3704
|
let graphFrame = 0, graphNodes = [], graphEdges = [], graphSignals = [], graphTimer = null, graphPullTimer = null;
|
|
3711
3705
|
const signalColors = { 'memory-write':'#10e68c','subagent-spawn':'#18ffff','dream':'#a855f7','revisit':'#a855f7','counterfactual':'#a855f7','consolidation':'#a855f7','contradiction':'#ff5864','pattern-discovery':'#10e68c','collision':'#ff5864','quarantine':'#ec4899','firewall-block':'#ffb53f' };
|
|
3712
3706
|
async function startGraph() { await pullTopology(); if (graphTimer) cancelAnimationFrame(graphTimer); graphLoop(); if (graphPullTimer) clearInterval(graphPullTimer); graphPullTimer = setInterval(pullTopology, 3000); }
|
|
@@ -3718,10 +3712,10 @@ async function pullTopology() {
|
|
|
3718
3712
|
const W = canvas.width, H = canvas.height, cx = W/2, cy = H/2;
|
|
3719
3713
|
const prev = new Map(graphNodes.map(n => [n.id, { x: n.x, y: n.y }]));
|
|
3720
3714
|
graphNodes = [{ id:'brain', label:'HIVE MIND', x: cx, y: cy, r: 50, type:'brain', color:'#a855f7' }];
|
|
3721
|
-
(topo.agents || []).forEach((a, i, arr) => {
|
|
3715
|
+
(topo.agents || []).filter(a => a.configurationDetected).forEach((a, i, arr) => {
|
|
3722
3716
|
const ang = (i / arr.length) * Math.PI * 2 - Math.PI / 2, r = 240;
|
|
3723
3717
|
const p = prev.get(a.id);
|
|
3724
|
-
graphNodes.push({ id: a.id, label: a.displayName, x: p?.x ?? cx + Math.cos(ang) * r, y: p?.y ?? cy + Math.sin(ang) * r, targetX: cx + Math.cos(ang) * r, targetY: cy + Math.sin(ang) * r, r:
|
|
3718
|
+
graphNodes.push({ id: a.id, label: a.displayName, x: p?.x ?? cx + Math.cos(ang) * r, y: p?.y ?? cy + Math.sin(ang) * r, targetX: cx + Math.cos(ang) * r, targetY: cy + Math.sin(ang) * r, r: 20, type:'agent', connected: false, color: '#8695aa' });
|
|
3725
3719
|
});
|
|
3726
3720
|
(topo.subAgents || []).forEach((s, i, arr) => {
|
|
3727
3721
|
const parent = graphNodes.find(n => n.id === s.parent), ang = (i / Math.max(arr.length,1)) * Math.PI * 2, r = 130;
|
|
@@ -3730,19 +3724,25 @@ async function pullTopology() {
|
|
|
3730
3724
|
});
|
|
3731
3725
|
graphEdges = [];
|
|
3732
3726
|
for (const n of graphNodes) {
|
|
3733
|
-
if (n.type === 'agent') graphEdges.push({ from:'brain', to: n.id, active:
|
|
3734
|
-
if (n.type === 'subagent') graphEdges.push({ from: n.parent ?? 'brain', to: n.id, active:
|
|
3727
|
+
if (n.type === 'agent') graphEdges.push({ from:'brain', to: n.id, active: false });
|
|
3728
|
+
if (n.type === 'subagent') graphEdges.push({ from: n.parent ?? 'brain', to: n.id, active: false });
|
|
3735
3729
|
}
|
|
3736
3730
|
const now = Date.now();
|
|
3737
3731
|
for (const e of (topo.events || [])) {
|
|
3732
|
+
const eventKey = e.id || JSON.stringify([e.type,e.source,e.target,e.timestamp]);
|
|
3733
|
+
if (graphObservedEvents.has(eventKey)) continue;
|
|
3734
|
+
graphObservedEvents.add(eventKey);
|
|
3735
|
+
if (!graphObserved) continue;
|
|
3738
3736
|
const src = e.source ?? 'brain';
|
|
3739
|
-
const srcN = graphNodes.find(n => n.id === src)
|
|
3737
|
+
const srcN = graphNodes.find(n => n.id === src);
|
|
3740
3738
|
const dstN = e.type === 'subagent-spawn' ? graphNodes.find(n => n.id === e.target) : graphNodes.find(n => n.id === 'brain');
|
|
3741
3739
|
if (!srcN || !dstN) continue;
|
|
3742
3740
|
graphSignals.push({ fromId: srcN.id, toId: dstN.id, type: e.type, color: signalColors[e.type] || '#18ffff', progress: 0, spawnedAt: now });
|
|
3743
3741
|
}
|
|
3742
|
+
graphObserved = true;
|
|
3743
|
+
if (graphObservedEvents.size > 500) graphObservedEvents = new Set([...graphObservedEvents].slice(-500));
|
|
3744
3744
|
if (graphSignals.length > 100) graphSignals = graphSignals.slice(-100);
|
|
3745
|
-
document.getElementById('graph-meta').textContent = \`\${(topo.agents || []).length}
|
|
3745
|
+
document.getElementById('graph-meta').textContent = \`\${(topo.agents || []).filter(a => a.configurationDetected).length} configured/detected clients · \${(topo.subAgents || []).length} recorded sub-agents · \${graphSignals.length} new event signals\`;
|
|
3746
3746
|
}
|
|
3747
3747
|
function graphLoop() {
|
|
3748
3748
|
const c = document.getElementById('graph-canvas');
|
|
@@ -3,6 +3,8 @@ import { type GlobalBrain } from '../brain/global-brain.js';
|
|
|
3
3
|
import { type FeatureSettingsStore } from '../brain/feature-settings.js';
|
|
4
4
|
import { type MemoryAnnotationsStore } from '../brain/memory-annotations.js';
|
|
5
5
|
import { type ActivityJournal } from '../brain/activity-journal.js';
|
|
6
|
+
import { WorkspaceRuntime } from './workspace-status.js';
|
|
7
|
+
import type { ProjectHubService } from '../brain/project-hub.js';
|
|
6
8
|
export interface WorkspaceDependencies {
|
|
7
9
|
brain?: GlobalBrain;
|
|
8
10
|
settings?: FeatureSettingsStore;
|
|
@@ -10,6 +12,10 @@ export interface WorkspaceDependencies {
|
|
|
10
12
|
projectDir?: string;
|
|
11
13
|
journal?: ActivityJournal;
|
|
12
14
|
demo?: boolean;
|
|
15
|
+
localProject?: boolean;
|
|
16
|
+
runtime?: WorkspaceRuntime;
|
|
17
|
+
hub?: ProjectHubService;
|
|
18
|
+
prepareStorage?: () => Promise<string | null>;
|
|
13
19
|
}
|
|
14
20
|
/** The workspace API reads only the memory store and dedicated feature settings. */
|
|
15
21
|
export declare function handleWorkspaceRequest(req: IncomingMessage, res: ServerResponse, dependencies?: WorkspaceDependencies): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-api.d.ts","sourceRoot":"","sources":["../../src/dashboard/workspace-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace-api.d.ts","sourceRoot":"","sources":["../../src/dashboard/workspace-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAK5E,OAAO,EAA2C,KAAK,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAClH,OAAO,EAAqC,KAAK,sBAAsB,EAAiC,MAAM,gCAAgC,CAAC;AAG/I,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAMxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAKjE,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,GAAG,CAAC,EAAE,iBAAiB,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAwED,oFAAoF;AACpF,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,YAAY,GAAE,qBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CA4R/I"}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { getGlobalBrain } from '../brain/global-brain.js';
|
|
2
3
|
import { getBrainBus } from '../brain/brain-bus.js';
|
|
3
4
|
import { assembleContext } from '../brain/context-assembly.js';
|
|
5
|
+
import { parseContextRequest } from '../brain/context-request.js';
|
|
6
|
+
import { inspectMemoryHealth } from '../brain/memory-inspection.js';
|
|
4
7
|
import { FEATURE_DEFINITIONS, getFeatureSettings } from '../brain/feature-settings.js';
|
|
5
8
|
import { memoryAnnotationsFor, memoryState } from '../brain/memory-annotations.js';
|
|
6
9
|
import { normalizeMemorySources } from '../brain/memory-sources.js';
|
|
7
10
|
import { inspectClientIntegrations } from '../brain/client-integrations.js';
|
|
8
11
|
import { activityJournalFor } from '../brain/activity-journal.js';
|
|
9
12
|
import { reportAgentActivity } from '../brain/activity-reporting.js';
|
|
13
|
+
import { inspectProject, planProjectSkill, applyProjectSkill } from '../brain/project-kit.js';
|
|
14
|
+
import { requireProjectStore, addProjectKnowledge } from '../brain/project-memory.js';
|
|
15
|
+
import { ProjectFeedbackStore } from '../brain/project-feedback.js';
|
|
16
|
+
import { WorkspaceRuntime } from './workspace-status.js';
|
|
17
|
+
import { isProjectHubRoute, handleProjectHubRequest } from './project-hub-api.js';
|
|
10
18
|
const INVENTORY_LIMIT = 2500;
|
|
19
|
+
const sharedRuntime = new WorkspaceRuntime('shared');
|
|
11
20
|
function sources(entry) {
|
|
12
21
|
return normalizeMemorySources(entry.metadata, { limit: 8, maxChars: 500 });
|
|
13
22
|
}
|
|
@@ -89,10 +98,105 @@ export async function handleWorkspaceRequest(req, res, dependencies = {}) {
|
|
|
89
98
|
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
90
99
|
const route = url.pathname.slice('/api/workspace/'.length);
|
|
91
100
|
const method = req.method ?? 'GET';
|
|
101
|
+
const expectedProject = req.headers['x-shadow-brain-project'];
|
|
102
|
+
if (method === 'POST' && expectedProject !== undefined && expectedProject !== dependencies.runtime?.project?.id) {
|
|
103
|
+
return send({ error: 'This port now serves a different project. Reload the portal before making changes.', code: 'WORKSPACE_PROJECT_CHANGED' }, 409);
|
|
104
|
+
}
|
|
105
|
+
const storageError = await dependencies.prepareStorage?.();
|
|
106
|
+
if (route === 'status' && method === 'GET')
|
|
107
|
+
return send((dependencies.runtime ?? sharedRuntime).status(dependencies.brain, !!dependencies.hub && !storageError, storageError));
|
|
108
|
+
if (storageError)
|
|
109
|
+
return send({ error: storageError, code: 'WORKSPACE_STORAGE_UNAVAILABLE' }, 503);
|
|
110
|
+
if (isProjectHubRoute(url.pathname)) {
|
|
111
|
+
const settings = dependencies.settings ?? getFeatureSettings();
|
|
112
|
+
const journal = dependencies.journal;
|
|
113
|
+
const correlationId = randomUUID();
|
|
114
|
+
const projectId = dependencies.runtime?.project?.id;
|
|
115
|
+
const tool = 'hub-' + (url.pathname.split('/')[4] || 'overview');
|
|
116
|
+
const record = async (kind) => {
|
|
117
|
+
if (method !== 'POST' || !journal || !settings.get().features.activityRecording)
|
|
118
|
+
return;
|
|
119
|
+
await journal.append({ kind, source: 'reported', transport: 'host', projectId, agent: 'portal', tool, correlationId,
|
|
120
|
+
...(kind === 'tool-end' ? { outcome: res.statusCode < 400 ? 'success' : 'error' } : {}) }).catch(() => { });
|
|
121
|
+
};
|
|
122
|
+
await record('tool-start');
|
|
123
|
+
try {
|
|
124
|
+
await handleProjectHubRequest(req, res, dependencies.hub, url);
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
await record('tool-end');
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const local = dependencies.localProject && dependencies.projectDir && dependencies.brain
|
|
132
|
+
? requireProjectStore(dependencies.projectDir, dependencies.brain) : undefined;
|
|
133
|
+
const projectRoutes = ['project-profile', 'project-knowledge', 'project-skill-preview', 'project-skill-apply', 'project-feedback'];
|
|
92
134
|
const writes = ['memory-review', 'memory-link', 'memory-unlink'];
|
|
93
|
-
if (!['GET', 'POST'].includes(method) || (method === 'POST' && !['context', 'features', 'activity-report', ...writes].includes(route)))
|
|
135
|
+
if (!['GET', 'POST'].includes(method) || (method === 'POST' && !['context', 'context-compare', 'features', 'activity-report', ...writes, ...projectRoutes.slice(1)].includes(route)))
|
|
94
136
|
return send({ error: 'Method not allowed.' }, 405);
|
|
95
137
|
const settings = dependencies.settings ?? getFeatureSettings();
|
|
138
|
+
const localActivity = () => {
|
|
139
|
+
const enabled = settings.get().features.liveActivity;
|
|
140
|
+
if (!local)
|
|
141
|
+
return activity(enabled);
|
|
142
|
+
const journal = dependencies.journal ?? activityJournalFor(dependencies.brain);
|
|
143
|
+
return { enabled, activity: enabled ? journal.read({ projectId: local.projectId, limit: 200 }).events.slice(-30).reverse().map(event => ({
|
|
144
|
+
id: event.id, type: event.kind, label: [event.tool, event.phase, event.outcome].filter(Boolean).join(' · ') || event.kind,
|
|
145
|
+
agent: event.agent ?? '', project: local.projectName, timestamp: event.timestamp,
|
|
146
|
+
})) : [] };
|
|
147
|
+
};
|
|
148
|
+
if (projectRoutes.includes(route)) {
|
|
149
|
+
if (!local)
|
|
150
|
+
return send({ error: 'Open shadow-brain project workspace for project-local knowledge and skills.' }, 409);
|
|
151
|
+
if (route === 'project-profile')
|
|
152
|
+
return send(inspectProject(local.root));
|
|
153
|
+
if (route === 'project-feedback') {
|
|
154
|
+
const feedback = new ProjectFeedbackStore(local.root, dependencies.brain);
|
|
155
|
+
if (method === 'GET')
|
|
156
|
+
return send(feedback.get());
|
|
157
|
+
const input = await body(req);
|
|
158
|
+
const { expectedRevision, kind, ...params } = input;
|
|
159
|
+
await dependencies.brain.init();
|
|
160
|
+
dependencies.brain.refresh();
|
|
161
|
+
if (dependencies.brain.getStorageHealth().lastError)
|
|
162
|
+
throw new Error('Project memory could not be read; feedback was not changed.');
|
|
163
|
+
const command = { kind: kind === 'record' ? 'upsert' : kind === 'enable' ? 'toggle' : kind, ...params };
|
|
164
|
+
return send(await feedback.update(command, expectedRevision, 'user'));
|
|
165
|
+
}
|
|
166
|
+
if (method !== 'POST')
|
|
167
|
+
return send({ error: 'Use POST for project knowledge and skill requests.' }, 405);
|
|
168
|
+
const input = await body(req);
|
|
169
|
+
if (route === 'project-skill-preview')
|
|
170
|
+
return send(planProjectSkill(local.root, input));
|
|
171
|
+
const started = Date.now();
|
|
172
|
+
const correlationId = randomUUID();
|
|
173
|
+
const recordOperation = async (outcome) => {
|
|
174
|
+
if (!settings.get().features.activityRecording)
|
|
175
|
+
return;
|
|
176
|
+
try {
|
|
177
|
+
await (dependencies.journal ?? activityJournalFor(dependencies.brain)).append({ projectId: local.projectId,
|
|
178
|
+
kind: outcome ? 'tool-end' : 'tool-start', source: 'reported', transport: 'host', agent: 'user', sessionId: 'project-portal',
|
|
179
|
+
tool: route, correlationId, ...(outcome ? { outcome, durationMs: Math.max(0, Date.now() - started) } : {}) });
|
|
180
|
+
}
|
|
181
|
+
catch { /* The committed result remains valid when optional activity recording is unavailable. */ }
|
|
182
|
+
};
|
|
183
|
+
await recordOperation();
|
|
184
|
+
let result;
|
|
185
|
+
try {
|
|
186
|
+
if (route === 'project-knowledge')
|
|
187
|
+
result = await addProjectKnowledge(local.root, dependencies.brain, input);
|
|
188
|
+
else {
|
|
189
|
+
const { expectedPlanHash, ...params } = input;
|
|
190
|
+
result = await applyProjectSkill(local.root, params, expectedPlanHash);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
await recordOperation('error');
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
await recordOperation('success');
|
|
198
|
+
return send(result);
|
|
199
|
+
}
|
|
96
200
|
if (route === 'features') {
|
|
97
201
|
if (method === 'POST') {
|
|
98
202
|
const input = await body(req);
|
|
@@ -105,7 +209,7 @@ export async function handleWorkspaceRequest(req, res, dependencies = {}) {
|
|
|
105
209
|
return send(settingsResponse(settings));
|
|
106
210
|
}
|
|
107
211
|
if (route === 'activity')
|
|
108
|
-
return send(
|
|
212
|
+
return send(localActivity());
|
|
109
213
|
if (route === 'telemetry') {
|
|
110
214
|
const flags = settings.get().features;
|
|
111
215
|
const common = { checkedAt: new Date().toISOString(), liveEnabled: flags.liveActivity, recordingEnabled: flags.activityRecording, demo: dependencies.demo === true };
|
|
@@ -116,23 +220,29 @@ export async function handleWorkspaceRequest(req, res, dependencies = {}) {
|
|
|
116
220
|
const cursor = qs.get('cursor');
|
|
117
221
|
const journal = dependencies.journal ?? activityJournalFor(dependencies.brain ?? getGlobalBrain());
|
|
118
222
|
const page = journal.read({ afterSequence: cursor === null ? undefined : bounded(cursor, 0, Number.MAX_SAFE_INTEGER, 0),
|
|
119
|
-
journalId: query(qs, 'journalId'), projectId: query(qs, 'project'), limit: bounded(qs.get('limit'), 200, 200) });
|
|
223
|
+
journalId: query(qs, 'journalId'), projectId: local?.projectId ?? query(qs, 'project'), limit: bounded(qs.get('limit'), 200, 200) });
|
|
120
224
|
return send({ ...common, ...page, cursor: page.nextAfterSequence });
|
|
121
225
|
}
|
|
122
226
|
if (route === 'activity-report') {
|
|
123
227
|
if (method !== 'POST')
|
|
124
228
|
return send({ error: 'Use POST to report activity.' }, 405);
|
|
125
229
|
const input = await body(req);
|
|
230
|
+
if (local && input.projectId !== undefined && input.projectId !== local.projectId)
|
|
231
|
+
throw new TypeError('This portal is pinned to its local project.');
|
|
232
|
+
if (local)
|
|
233
|
+
input.projectId = local.projectId;
|
|
126
234
|
return send(await reportAgentActivity(dependencies.brain ?? getGlobalBrain(), settings, input, dependencies.journal));
|
|
127
235
|
}
|
|
128
|
-
if (!['overview', 'memories', 'graph', 'context', 'memory', 'integrations', ...writes].includes(route))
|
|
236
|
+
if (!['overview', 'memories', 'graph', 'context', 'context-compare', 'memory', 'memory-health', 'integrations', ...writes].includes(route))
|
|
129
237
|
return send({ error: 'Not found.' }, 404);
|
|
130
|
-
if (
|
|
238
|
+
if (['context', 'context-compare'].includes(route) && method !== 'POST')
|
|
131
239
|
return send({ error: 'Use POST for context assembly.' }, 405);
|
|
132
240
|
if (writes.includes(route) && method !== 'POST')
|
|
133
241
|
return send({ error: 'Use POST for memory changes.' }, 405);
|
|
134
242
|
const mutationInput = writes.includes(route) ? await body(req) : undefined;
|
|
135
243
|
if (mutationInput) {
|
|
244
|
+
if (local && mutationInput.projectId !== local.projectId)
|
|
245
|
+
throw new TypeError('This portal is pinned to its local project.');
|
|
136
246
|
if (!Number.isSafeInteger(mutationInput.expectedRevision) || Number(mutationInput.expectedRevision) < 0)
|
|
137
247
|
throw new TypeError('A current expectedRevision is required.');
|
|
138
248
|
const allowed = route === 'memory-review' ? ['projectId', 'memoryId', 'state', 'note', 'expectedRevision'] :
|
|
@@ -142,41 +252,42 @@ export async function handleWorkspaceRequest(req, res, dependencies = {}) {
|
|
|
142
252
|
}
|
|
143
253
|
const brain = dependencies.brain ?? getGlobalBrain();
|
|
144
254
|
if (route === 'integrations')
|
|
145
|
-
return send(inspectClientIntegrations({ projectDir: dependencies.projectDir, brain }));
|
|
255
|
+
return send(inspectClientIntegrations({ projectDir: dependencies.projectDir, brain, localProjectId: local?.projectId }));
|
|
146
256
|
const annotationStore = dependencies.annotations ?? memoryAnnotationsFor(brain);
|
|
147
257
|
const refresh = async () => {
|
|
148
258
|
await brain.init();
|
|
149
|
-
|
|
150
|
-
brain.refresh();
|
|
151
|
-
else
|
|
152
|
-
await brain.sync();
|
|
259
|
+
brain.refresh();
|
|
153
260
|
if (brain.getStorageHealth().lastError)
|
|
154
261
|
throw new Error('The memory store could not be read. Check storage health.');
|
|
155
262
|
};
|
|
156
|
-
if (route === 'context') {
|
|
263
|
+
if (route === 'context' || route === 'context-compare') {
|
|
157
264
|
const input = await body(req);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
throw new TypeError('Choose a project.');
|
|
162
|
-
if (input.query !== undefined && typeof input.query !== 'string')
|
|
163
|
-
throw new TypeError('Task must be text.');
|
|
164
|
-
if (input.includeCrossProject !== undefined && typeof input.includeCrossProject !== 'boolean')
|
|
165
|
-
throw new TypeError('Cross-project choice must be boolean.');
|
|
166
|
-
if (input.tokenBudget !== undefined && (!Number.isSafeInteger(input.tokenBudget) || Number(input.tokenBudget) < 0 || Number(input.tokenBudget) > 12000))
|
|
167
|
-
throw new TypeError('Token budget must be an integer from 0 to 12000.');
|
|
265
|
+
const options = parseContextRequest(input);
|
|
266
|
+
if (local && (options.projectId !== local.projectId || options.includeCrossProject === true))
|
|
267
|
+
throw new TypeError('This portal is pinned to its local project.');
|
|
168
268
|
const flags = settings.get().features;
|
|
169
269
|
if (flags.contextAssembly)
|
|
170
270
|
await refresh();
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
271
|
+
const common = { ...options, features: flags, annotations: flags.contextAssembly ? annotationStore.get() : undefined,
|
|
272
|
+
feedback: flags.contextAssembly && local ? new ProjectFeedbackStore(local.root, brain).get() : undefined };
|
|
273
|
+
if (route === 'context')
|
|
274
|
+
return send(assembleContext(brain, common));
|
|
275
|
+
const legacy = assembleContext(brain, { ...common, profile: 'legacy' });
|
|
276
|
+
const adaptive = assembleContext(brain, { ...common, profile: 'adaptive' });
|
|
277
|
+
const oldIds = new Set(legacy.entries.map(entry => entry.id));
|
|
278
|
+
const newIds = new Set(adaptive.entries.map(entry => entry.id));
|
|
279
|
+
return send({ legacy, adaptive, delta: { addedIds: [...newIds].filter(id => !oldIds.has(id)),
|
|
280
|
+
removedIds: [...oldIds].filter(id => !newIds.has(id)), sharedIds: [...newIds].filter(id => oldIds.has(id)) },
|
|
281
|
+
warnings: ['Both profiles use the same memory view. Their token estimators differ; selection changes are not proof of higher accuracy.'] });
|
|
175
282
|
}
|
|
176
283
|
await refresh();
|
|
177
284
|
const annotations = annotationStore.get();
|
|
178
285
|
const qs = url.searchParams;
|
|
179
|
-
const requestedProject = query(qs, 'project');
|
|
286
|
+
const requestedProject = local?.projectId ?? query(qs, 'project');
|
|
287
|
+
if (local && query(qs, 'project') && query(qs, 'project') !== local.projectId)
|
|
288
|
+
throw new TypeError('This portal is pinned to its local project.');
|
|
289
|
+
if (route === 'memory-health')
|
|
290
|
+
return send(inspectMemoryHealth(brain, annotations, { projectId: requestedProject, limit: bounded(qs.get('limit'), 30, 100) }));
|
|
180
291
|
if (route === 'memory') {
|
|
181
292
|
const id = query(qs, 'id');
|
|
182
293
|
if (!id || !requestedProject)
|
|
@@ -218,16 +329,23 @@ export async function handleWorkspaceRequest(req, res, dependencies = {}) {
|
|
|
218
329
|
const committed = await annotationStore.update(command, input.expectedRevision);
|
|
219
330
|
return send({ revision: committed.revision, updatedAt: committed.updatedAt });
|
|
220
331
|
}
|
|
221
|
-
const
|
|
332
|
+
const recentInventory = brain.timeline({ limit: INVENTORY_LIMIT, ...(local ? { projectId: local.projectId } : {}) });
|
|
333
|
+
const inventory = requestedProject ? brain.timeline({ projectId: requestedProject, limit: INVENTORY_LIMIT }) : recentInventory;
|
|
222
334
|
const projectMap = new Map();
|
|
223
|
-
|
|
335
|
+
if (local)
|
|
336
|
+
projectMap.set(local.projectId, { id: local.projectId, name: local.projectName, memories: 0, updatedAt: null });
|
|
337
|
+
for (const entry of recentInventory) {
|
|
224
338
|
const project = projectMap.get(entry.projectId) ?? { id: entry.projectId, name: entry.projectName || entry.projectId, memories: 0, updatedAt: date(entry.createdAt) };
|
|
225
339
|
project.memories++;
|
|
226
340
|
projectMap.set(entry.projectId, project);
|
|
227
341
|
}
|
|
342
|
+
if (requestedProject && inventory.length)
|
|
343
|
+
projectMap.set(requestedProject, {
|
|
344
|
+
id: requestedProject, name: inventory[0].projectName || requestedProject, memories: inventory.length, updatedAt: date(inventory[0].createdAt),
|
|
345
|
+
});
|
|
228
346
|
const projects = [...projectMap.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
229
347
|
const facets = { projects, categories: [...new Set(inventory.map(entry => entry.category))].sort(), agents: [...new Set(inventory.map(entry => entry.agentTool))].sort() };
|
|
230
|
-
const inventoryTruncated = brain.getStats().totalEntries > inventory.length;
|
|
348
|
+
const inventoryTruncated = requestedProject ? brain.timeline({ projectId: requestedProject, limit: INVENTORY_LIMIT + 1 }).length > INVENTORY_LIMIT : brain.getStats().totalEntries > inventory.length;
|
|
231
349
|
if (route === 'overview') {
|
|
232
350
|
const scoped = inventory.filter(entry => !requestedProject || entry.projectId === requestedProject);
|
|
233
351
|
const quality = { total: scoped.length, sourceBacked: 0, active: 0, contested: 0, archived: 0, superseded: 0, reviewed: 0 };
|
|
@@ -238,13 +356,15 @@ export async function handleWorkspaceRequest(req, res, dependencies = {}) {
|
|
|
238
356
|
if (annotations.reviews[entry.id]?.projectId === entry.projectId)
|
|
239
357
|
quality.reviewed++;
|
|
240
358
|
}
|
|
241
|
-
return send({ version: '7.1.
|
|
242
|
-
|
|
359
|
+
return send({ version: '7.1.4', demo: dependencies.demo === true,
|
|
360
|
+
projectKit: local ? { available: true, projectId: local.projectId, projectName: local.projectName, root: local.root, storagePath: local.storagePath } : { available: false },
|
|
361
|
+
totals: { projects: projects.length, memories: local ? inventory.length : brain.getStats().totalEntries, agents: facets.agents.length },
|
|
362
|
+
projects, ...localActivity(), storageHealth: brain.getStorageHealth(),
|
|
243
363
|
features: settings.get().features, recentMemories: scoped.slice(0, 5).map(entry => summary(entry, annotations)), truncated: inventoryTruncated,
|
|
244
364
|
quality, scope: { projectId: requestedProject ?? null, basis: 'recent-inventory' },
|
|
245
365
|
inventoryLimit: INVENTORY_LIMIT });
|
|
246
366
|
}
|
|
247
|
-
const projectId =
|
|
367
|
+
const projectId = requestedProject;
|
|
248
368
|
const category = query(qs, 'category');
|
|
249
369
|
const agentTool = query(qs, 'agent');
|
|
250
370
|
const search = query(qs, 'q');
|
|
@@ -288,7 +408,7 @@ export async function handleWorkspaceRequest(req, res, dependencies = {}) {
|
|
|
288
408
|
}
|
|
289
409
|
const detail = summary(entry, annotations);
|
|
290
410
|
nodes.push({ id: memoryNode, kind: 'memory', label: detail.title, project: entry.projectId, category: entry.category,
|
|
291
|
-
memoryId: entry.id, effectiveState: detail.effectiveState, snippet: detail.snippet, source: detail.source, agent: entry.agentTool, updatedAt: detail.updatedAt });
|
|
411
|
+
memoryId: entry.id, effectiveState: detail.effectiveState, snippet: detail.snippet, source: detail.source, sources: detail.sources, agent: entry.agentTool, updatedAt: detail.updatedAt });
|
|
292
412
|
edges.push({ source: projectNode, target: memoryNode, kind: 'belongs-to' }, { source: agentNode, target: memoryNode, kind: 'recorded-by' });
|
|
293
413
|
}
|
|
294
414
|
const shownById = new Map(shown.map(entry => [entry.id, entry.projectId]));
|
|
@@ -301,7 +421,7 @@ export async function handleWorkspaceRequest(req, res, dependencies = {}) {
|
|
|
301
421
|
}
|
|
302
422
|
catch (error) {
|
|
303
423
|
const code = error.code;
|
|
304
|
-
send({ error: error instanceof Error ? error.message : String(error), ...(code ? { code } : {}) }, code === 'FEATURE_SETTINGS_CONFLICT' || code === 'ANNOTATIONS_CONFLICT' ? 409 : code === 'ANNOTATIONS_NOT_FOUND' ? 404 :
|
|
424
|
+
send({ error: error instanceof Error ? error.message : String(error), ...(code ? { code } : {}) }, code === 'FEATURE_SETTINGS_CONFLICT' || code === 'ANNOTATIONS_CONFLICT' || code?.includes('CONFLICT') || code?.includes('STALE') ? 409 : code === 'ANNOTATIONS_NOT_FOUND' ? 404 :
|
|
305
425
|
code === 'FEATURE_SETTINGS_INVALID_PATCH' || code === 'ANNOTATIONS_INVALID_COMMAND' || code === 'ACTIVITY_JOURNAL_INVALID_EVENT' ||
|
|
306
426
|
code === 'ACTIVITY_JOURNAL_INVALID_CURSOR' || error instanceof TypeError || error instanceof RangeError ? 400 : 500);
|
|
307
427
|
}
|