@theihtisham/agent-shadow-brain 7.1.4 → 7.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +478 -462
- package/README.md +97 -24
- 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-integrations.js +1 -1
- package/dist/brain/client-integrations.js.map +1 -1
- package/dist/brain/context-assembly.d.ts +10 -0
- package/dist/brain/context-assembly.d.ts.map +1 -1
- package/dist/brain/context-assembly.js +15 -6
- 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 +1 -1
- package/dist/brain/context-request.d.ts.map +1 -1
- package/dist/brain/context-request.js +4 -2
- package/dist/brain/context-request.js.map +1 -1
- package/dist/brain/context-retrieval.d.ts +1 -1
- package/dist/brain/context-retrieval.d.ts.map +1 -1
- package/dist/brain/context-retrieval.js +2 -1
- package/dist/brain/context-retrieval.js.map +1 -1
- package/dist/brain/feature-settings.d.ts +5 -0
- package/dist/brain/feature-settings.d.ts.map +1 -1
- package/dist/brain/feature-settings.js +8 -2
- package/dist/brain/feature-settings.js.map +1 -1
- package/dist/brain/global-brain.d.ts +1 -1
- package/dist/brain/global-brain.d.ts.map +1 -1
- package/dist/brain/global-brain.js +1 -0
- 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 +12 -0
- package/dist/brain/mcp-server.d.ts.map +1 -1
- package/dist/brain/mcp-server.js +177 -31
- package/dist/brain/mcp-server.js.map +1 -1
- package/dist/brain/mcp-stdio.d.ts +1 -1
- package/dist/brain/mcp-stdio.d.ts.map +1 -1
- package/dist/brain/mcp-stdio.js +19 -1
- package/dist/brain/mcp-stdio.js.map +1 -1
- package/dist/brain/memory-annotations.d.ts +2 -0
- package/dist/brain/memory-annotations.d.ts.map +1 -1
- package/dist/brain/memory-annotations.js +13 -0
- package/dist/brain/memory-annotations.js.map +1 -1
- package/dist/brain/memory-inspection.d.ts +1 -0
- package/dist/brain/memory-inspection.d.ts.map +1 -1
- package/dist/brain/memory-inspection.js +1 -1
- package/dist/brain/memory-inspection.js.map +1 -1
- package/dist/brain/memory-mcp-content.d.ts +4 -2
- package/dist/brain/memory-mcp-content.d.ts.map +1 -1
- package/dist/brain/memory-mcp-content.js +20 -16
- package/dist/brain/memory-mcp-content.js.map +1 -1
- 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 +1 -1
- package/dist/brain/project-feedback.d.ts.map +1 -1
- package/dist/brain/project-feedback.js +19 -8
- package/dist/brain/project-feedback.js.map +1 -1
- package/dist/brain/project-hub-contract.d.ts +6 -0
- package/dist/brain/project-hub-contract.d.ts.map +1 -1
- package/dist/brain/project-hub-contract.js +2 -1
- package/dist/brain/project-hub-contract.js.map +1 -1
- package/dist/brain/project-hub-mcp.d.ts +14 -0
- package/dist/brain/project-hub-mcp.d.ts.map +1 -1
- package/dist/brain/project-hub-mcp.js +6 -1
- package/dist/brain/project-hub-mcp.js.map +1 -1
- package/dist/brain/project-hub-store.d.ts +14 -2
- package/dist/brain/project-hub-store.d.ts.map +1 -1
- package/dist/brain/project-hub-store.js +70 -2
- package/dist/brain/project-hub-store.js.map +1 -1
- package/dist/brain/project-hub.d.ts +5 -0
- package/dist/brain/project-hub.d.ts.map +1 -1
- package/dist/brain/project-hub.js +23 -1
- package/dist/brain/project-hub.js.map +1 -1
- package/dist/brain/project-kit.d.ts +10 -0
- package/dist/brain/project-kit.d.ts.map +1 -1
- package/dist/brain/project-kit.js +80 -16
- package/dist/brain/project-kit.js.map +1 -1
- 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/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/context-cli.d.ts.map +1 -1
- package/dist/context-cli.js +9 -3
- package/dist/context-cli.js.map +1 -1
- package/dist/dashboard/brain-hub-actions.d.ts.map +1 -1
- package/dist/dashboard/brain-hub-actions.js +232 -135
- package/dist/dashboard/brain-hub-actions.js.map +1 -1
- 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.map +1 -1
- package/dist/dashboard/brain-hub-client.js +433 -333
- package/dist/dashboard/brain-hub-client.js.map +1 -1
- 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.map +1 -1
- package/dist/dashboard/brain-hub-graph.js +236 -74
- package/dist/dashboard/brain-hub-graph.js.map +1 -1
- package/dist/dashboard/brain-hub-html.d.ts.map +1 -1
- package/dist/dashboard/brain-hub-html.js +56 -1
- package/dist/dashboard/brain-hub-html.js.map +1 -1
- 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.map +1 -1
- package/dist/dashboard/brain-hub-project-views.js +78 -77
- package/dist/dashboard/brain-hub-project-views.js.map +1 -1
- 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.map +1 -1
- package/dist/dashboard/brain-hub-views.js +151 -146
- package/dist/dashboard/brain-hub-views.js.map +1 -1
- package/dist/dashboard/live-workspace-html.js +1039 -1039
- 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-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-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.map +1 -1
- package/dist/dashboard/project-workspace.js +18 -0
- package/dist/dashboard/project-workspace.js.map +1 -1
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +64 -25
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts.map +1 -1
- package/dist/dashboard/v6-dashboard-html.js +4261 -4309
- package/dist/dashboard/v6-dashboard-html.js.map +1 -1
- package/dist/dashboard/workspace-api.d.ts.map +1 -1
- package/dist/dashboard/workspace-api.js +105 -23
- package/dist/dashboard/workspace-api.js.map +1 -1
- package/dist/dashboard/workspace-status.d.ts +3 -0
- package/dist/dashboard/workspace-status.d.ts.map +1 -1
- package/dist/dashboard/workspace-status.js +4 -3
- package/dist/dashboard/workspace-status.js.map +1 -1
- package/dist/project-cli.js +1 -1
- package/dist/project-cli.js.map +1 -1
- package/docs/BRAND_ASSETS.md +36 -0
- package/docs/FEATURES_AND_LIMITS.md +29 -24
- package/docs/INTEGRATIONS.md +4 -2
- package/docs/LEARNING.md +1 -1
- package/docs/PROJECT_KIT.md +6 -1
- package/docs/QUICKSTART.md +62 -44
- package/docs/README.md +36 -33
- package/docs/SESSIONS.md +77 -0
- package/docs/SOURCE_INTAKE.md +33 -0
- package/docs/STATS.md +21 -21
- package/docs/VISUAL_GUIDE_v7.22.0.md +73 -0
- package/docs/WORKFLOW_INTEGRATION.md +3 -1
- package/docs/WORKSPACE.md +63 -37
- 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/launch/RELEASE_ACCEPTANCE_v7.22.0.md +48 -0
- package/docs/launch/RELEASE_NOTES_v7.22.0.md +53 -0
- package/docs/launch/RESEARCH_AND_PLAN_v7.22.0.md +672 -0
- package/package.json +135 -130
- package/skills/shadow-workflow/SKILL.md +2 -0
|
@@ -1,335 +1,435 @@
|
|
|
1
|
-
export const BRAIN_HUB_CLIENT = String.raw `
|
|
2
|
-
const $ = id => document.getElementById(id);
|
|
3
|
-
const arr = value => Array.isArray(value) ? value : [];
|
|
4
|
-
const esc = value => String(value ?? '').replace(/[&<>"']/g, char => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[char]));
|
|
5
|
-
const fmt = value => Number.isFinite(value) ? value.toLocaleString() : 'Unavailable';
|
|
6
|
-
const clock = new Intl.DateTimeFormat(undefined,{hour:'2-digit',minute:'2-digit',second:'2-digit'});
|
|
7
|
-
const time = value => value && Number.isFinite(new Date(value).getTime()) ? clock.format(new Date(value)) : '—';
|
|
8
|
-
const isoTime = value => value && Number.isFinite(new Date(value).getTime()) ? new Date(value).toLocaleString() : 'Unavailable';
|
|
9
|
-
const reduced = matchMedia('(prefers-reduced-motion: reduce)');
|
|
10
|
-
const local = document.documentElement.dataset.projectLocal === 'true';
|
|
11
|
-
const projectFeatureLimits={crossProjectContext:'Project memory stays scoped to this project.',automaticBriefing:'Automatic briefing requires a legacy analysis session.'};
|
|
12
|
-
const featureLimit = id => local ? projectFeatureLimits[id] : undefined;
|
|
13
|
-
const nav = {overview:'Brain overview',knowledge:'Knowledge',room:'Collaboration',context:'Context',models:'Models',usage:'Usage',learning:'Learning',setup:'Setup'};
|
|
14
|
-
const labels = {codex:'Codex','claude-code':'Claude Code',opencode:'OpenCode','deepseek-harness':'DeepSeek Harness',user:'Operator'};
|
|
15
|
-
const hostName = value => labels[value] ?? value ?? 'Unknown host';
|
|
16
|
-
const state = {view:'overview',project:'',overview:null,server:null,connection:'connecting',errors:{},graph:null,features:null,integrations:null,
|
|
17
|
-
profile:null,feedback:null,hub:null,documents:null,docPage:1,room:null,context:null,contextInput:null,comparison:null,skill:null,skillInput:null,
|
|
18
|
-
picked:null,memory:null,focus:false,inspector:'record',graphMode:'graph',listing:false,events:[],cursor:undefined,journalId:undefined,
|
|
19
|
-
live:false,recording:false,journalGap:false,replayId:null,motionPaused:false,motionStarted:0,pulseIds:[],pending:false,message:'',messageError:false,
|
|
20
|
-
dataEpoch:0,viewEpoch:0,search:null,lessonFrom:null};
|
|
21
|
-
let timer, polling=false, pollAgain=false, failures=0, polls=0;
|
|
22
|
-
let controller;
|
|
23
|
-
const list = (content,attributes='',classes='') => '<ul class="list '+classes+'" '+attributes+'>'+content+'</ul>';
|
|
24
|
-
const chip = (text,tone='') => '<span class="chip '+tone+'">'+esc(text)+'</span>';
|
|
25
|
-
const btn = (text, attrs='', kind='') => '<button type="button" class="btn '+kind+'" '+attrs+'>'+esc(text)+'</button>';
|
|
26
|
-
const submit = (text, kind='primary') => '<button type="submit" class="btn '+kind+'" '+(state.pending?'disabled':'')+'>'+esc(text)+'</button>';
|
|
27
|
-
const panel = (title, content, meta='', cls='') => '<section class="panel '+cls+'"><div class="panel-head"><h2>'+esc(title)+'</h2>'+meta+'</div>'+content+'</section>';
|
|
28
|
-
const heading = (title, body, actions='') => '<div class="page-head"><div><h1 id="title" tabindex="-1">'+esc(title)+'</h1><p class="small muted">'+esc(body)+'</p></div><div class="actions">'+actions+'</div></div>';
|
|
29
|
-
const empty = (title, detail, action='') => '<div class="empty"><strong>'+esc(title)+'</strong><p class="small">'+esc(detail)+'</p>'+(action?'<div class="actions">'+action+'</div>':'')+'</div>';
|
|
30
|
-
const fact = (label,value) => '<div><dt>'+esc(label)+'</dt><dd>'+esc(value ?? 'Unavailable')+'</dd></div>';
|
|
31
|
-
const error = (key, fallback) => state.errors[key] ? empty('Could not load '+fallback,state.errors[key],btn('Retry','data-action="refresh"')) : '';
|
|
32
|
-
const action = (id,text,kind='',extra='') => btn(text,'data-action="'+id+'" '+extra,kind);
|
|
33
|
-
const view = (id,text=nav[id]) => btn(text,'data-view="'+id+'"','quiet');
|
|
34
|
-
const json = body => ({method:'POST',body:JSON.stringify(body),headers:{'Content-Type':'application/json'}});
|
|
35
|
-
const retryKeys=new Map();
|
|
36
|
-
async function hubWrite(route,input){
|
|
37
|
-
const id=route+'\n'+JSON.stringify(input);
|
|
38
|
-
if(!retryKeys.has(id)){
|
|
39
|
-
if(retryKeys.size>=40)retryKeys.delete(retryKeys.keys().next().value);
|
|
40
|
-
retryKeys.set(id,crypto.randomUUID());
|
|
41
|
-
}
|
|
42
|
-
try{
|
|
43
|
-
const result=await api(route,json({...input,key:retryKeys.get(id)}));
|
|
44
|
-
retryKeys.delete(id);return result;
|
|
45
|
-
}catch(failure){
|
|
46
|
-
if(failure.status&&failure.status<500)retryKeys.delete(id);
|
|
47
|
-
throw failure;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function status(message='',isError=false){
|
|
51
|
-
state.message=message;state.messageError=isError;
|
|
52
|
-
const target=$('view-status');
|
|
53
|
-
if(target){target.textContent=message;target.dataset.error=String(isError);}
|
|
54
|
-
}
|
|
55
|
-
function projectQuery(extra={}){
|
|
56
|
-
return '?'+new URLSearchParams({...extra,...(state.project?{project:state.project}:{})});
|
|
57
|
-
}
|
|
58
|
-
async function api(route,options={}){
|
|
59
|
-
const {timeoutMs=6500,...request}=options;
|
|
60
|
-
const timeout=AbortSignal.timeout(timeoutMs);
|
|
61
|
-
const signal=request.signal ? AbortSignal.any([request.signal,timeout]) : timeout;
|
|
62
|
-
const pinned=local&&(state.server?.project?.id??state.overview?.projectKit?.projectId);
|
|
63
|
-
const headers={Accept:'application/json',...request.headers,...(pinned&&request.method==='POST'?{'X-Shadow-Brain-Project':pinned}:{})};
|
|
64
|
-
const response=await fetch('/api/workspace/'+route,{...request,signal,cache:'no-store',headers});
|
|
65
|
-
const data=await response.json().catch(()=>null);
|
|
66
|
-
if(!response.ok||!data){
|
|
67
|
-
const failure=new Error(data?.error ?? 'Workspace request returned HTTP '+response.status+'.');
|
|
68
|
-
failure.status=response.status;failure.code=data?.code;throw failure;
|
|
69
|
-
}
|
|
70
|
-
return data;
|
|
71
|
-
}
|
|
72
|
-
function validStatus(data){
|
|
73
|
-
return data&&typeof data.version==='string'&&/^\d+\.\d+\.\d+(?:[-+][\w.-]+)?$/.test(data.version)&&
|
|
74
|
-
typeof data.serverInstanceId==='string'&&data.serverInstanceId.length>0&&['project','shared','demo'].includes(data.mode)&&
|
|
75
|
-
(data.mode!=='project'||typeof data.project?.id==='string'&&typeof data.project.name==='string')&&
|
|
76
|
-
['ready','error','initializing'].includes(data.storage?.status)&&data.capabilities?.memory===true;
|
|
77
|
-
}
|
|
78
|
-
function validOverview(data){return data&&typeof data.version==='string'&&Array.isArray(data.projects)&&data.totals&&data.projectKit;}
|
|
79
|
-
function scopeName(){return state.overview?.projectKit?.projectName ?? arr(state.overview?.projects).find(project=>project.id===state.project)?.name ?? (state.project||'All projects');}
|
|
80
|
-
function renderChrome(){
|
|
81
|
-
const selector=$('project');
|
|
82
|
-
const projects=arr(state.overview?.projects);
|
|
83
|
-
const fixed=state.overview?.projectKit?.projectId;
|
|
84
|
-
const options=(fixed?'':'<option value="">All projects</option>')+projects.map(project=>'<option value="'+esc(project.id)+'">'+esc(project.name)+'</option>').join('');
|
|
85
|
-
if(selector.dataset.options!==options){selector.innerHTML=options||'<option value="">Loading…</option>';selector.dataset.options=options;}
|
|
86
|
-
selector.disabled=!!fixed||!state.overview||state.pending;
|
|
87
|
-
selector.value=state.project;
|
|
88
|
-
const connection=$('connection');
|
|
89
|
-
const connected=state.connection==='reachable';
|
|
90
|
-
const isDemo=state.overview?.demo===true||state.server?.mode==='demo';
|
|
91
|
-
connection.className='chip '+(connected?'green':state.connection==='connecting'?'':'amber');
|
|
92
|
-
connection.innerHTML='<i class="dot" aria-hidden="true"></i> '+(connected?(isDemo?'Demo workspace · Example data':'Workspace reachable'):state.connection==='connecting'?'Connecting to workspace':'Workspace unavailable');
|
|
93
|
-
const notice=$('notice');
|
|
94
|
-
notice.textContent=state.connection==='offline'?'The local workspace did not respond. Keep this tab open while the launcher restarts the server, or refresh to retry. '+(state.overview?'Showing the last loaded snapshot.':''):
|
|
95
|
-
state.errors.overview||state.server?.storage?.status==='error'?'The server responded, but the memory store is unavailable. '+(state.errors.overview||state.server.storage.error||''):
|
|
96
|
-
state.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
state.
|
|
104
|
-
state.
|
|
105
|
-
state.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
state.
|
|
112
|
-
}
|
|
113
|
-
function
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
state.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if(
|
|
174
|
-
if(
|
|
175
|
-
|
|
176
|
-
if(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if(manual)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if(
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if(
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
$('main').
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
1
|
+
export const BRAIN_HUB_CLIENT = String.raw `
|
|
2
|
+
const $ = id => document.getElementById(id);
|
|
3
|
+
const arr = value => Array.isArray(value) ? value : [];
|
|
4
|
+
const esc = value => String(value ?? '').replace(/[&<>"']/g, char => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[char]));
|
|
5
|
+
const fmt = value => Number.isFinite(value) ? value.toLocaleString() : 'Unavailable';
|
|
6
|
+
const clock = new Intl.DateTimeFormat(undefined,{hour:'2-digit',minute:'2-digit',second:'2-digit'});
|
|
7
|
+
const time = value => value && Number.isFinite(new Date(value).getTime()) ? clock.format(new Date(value)) : '—';
|
|
8
|
+
const isoTime = value => value && Number.isFinite(new Date(value).getTime()) ? new Date(value).toLocaleString() : 'Unavailable';
|
|
9
|
+
const reduced = matchMedia('(prefers-reduced-motion: reduce)');
|
|
10
|
+
const local = document.documentElement.dataset.projectLocal === 'true';
|
|
11
|
+
const projectFeatureLimits={crossProjectContext:'Project memory stays scoped to this project.',automaticBriefing:'Automatic briefing requires a legacy analysis session.'};
|
|
12
|
+
const featureLimit = id => local ? projectFeatureLimits[id] : id==='projectFileActivity'?'Open a project workspace to observe project files.':undefined;
|
|
13
|
+
const nav = {overview:'Brain overview',sessions:'Sessions',knowledge:'Knowledge',room:'Collaboration',context:'Context',models:'Models',usage:'Usage',learning:'Learning',setup:'Setup'};
|
|
14
|
+
const labels = {codex:'Codex','claude-code':'Claude Code',opencode:'OpenCode','deepseek-harness':'DeepSeek Harness',user:'Operator'};
|
|
15
|
+
const hostName = value => labels[value] ?? value ?? 'Unknown host';
|
|
16
|
+
const state = {view:'overview',project:'',overview:null,server:null,connection:'connecting',errors:{},graph:null,features:null,integrations:null,
|
|
17
|
+
nativeConnection:null,nativeThreads:null,nativeThread:null,nativeArchived:false,nativeListCursor:null,nativeThreadCursor:null,sessions:null,session:null,sessionBefore:null,sessionCheckpoint:null,usage:null,sources:null,source:null,evidence:null,teachDraft:'',profile:null,feedback:null,hub:null,documents:null,docPage:1,room:null,context:null,contextInput:null,comparison:null,skill:null,skillInput:null,
|
|
18
|
+
picked:null,memory:null,focus:false,inspector:'record',graphMode:'graph',listing:false,events:[],cursor:undefined,journalId:undefined,
|
|
19
|
+
live:false,recording:false,journalGap:false,replayId:null,replayExpired:false,motionPaused:false,motionStarted:0,pulseIds:[],pending:false,message:'',messageError:false,
|
|
20
|
+
dataEpoch:0,viewEpoch:0,graphEpoch:0,graphFilter:'all',search:null,lessonFrom:null,policy:null,policySelection:null,managedSkills:null,managedSkillPlan:null,presence:null};
|
|
21
|
+
let timer, polling=false, pollAgain=false, failures=0, polls=0;
|
|
22
|
+
let controller;
|
|
23
|
+
const list = (content,attributes='',classes='') => '<ul class="list '+classes+'" '+attributes+'>'+content+'</ul>';
|
|
24
|
+
const chip = (text,tone='') => '<span class="chip '+tone+'">'+esc(text)+'</span>';
|
|
25
|
+
const btn = (text, attrs='', kind='') => '<button type="button" class="btn '+kind+'" '+attrs+'>'+esc(text)+'</button>';
|
|
26
|
+
const submit = (text, kind='primary') => '<button type="submit" class="btn '+kind+'" '+(state.pending?'disabled':'')+'>'+esc(text)+'</button>';
|
|
27
|
+
const panel = (title, content, meta='', cls='') => '<section class="panel '+cls+'"><div class="panel-head"><h2>'+esc(title)+'</h2>'+meta+'</div>'+content+'</section>';
|
|
28
|
+
const heading = (title, body, actions='') => '<div class="page-head"><div><h1 id="title" tabindex="-1">'+esc(title)+'</h1><p class="small muted">'+esc(body)+'</p></div><div class="actions">'+actions+'</div></div>';
|
|
29
|
+
const empty = (title, detail, action='') => '<div class="empty"><strong>'+esc(title)+'</strong><p class="small">'+esc(detail)+'</p>'+(action?'<div class="actions">'+action+'</div>':'')+'</div>';
|
|
30
|
+
const fact = (label,value) => '<div><dt>'+esc(label)+'</dt><dd>'+esc(value ?? 'Unavailable')+'</dd></div>';
|
|
31
|
+
const error = (key, fallback) => state.errors[key] ? empty('Could not load '+fallback,state.errors[key],btn('Retry','data-action="refresh"')) : '';
|
|
32
|
+
const action = (id,text,kind='',extra='') => btn(text,'data-action="'+id+'" '+extra,kind);
|
|
33
|
+
const view = (id,text=nav[id]) => btn(text,'data-view="'+id+'"','quiet');
|
|
34
|
+
const json = body => ({method:'POST',body:JSON.stringify(body),headers:{'Content-Type':'application/json'}});
|
|
35
|
+
const retryKeys=new Map();
|
|
36
|
+
async function hubWrite(route,input){
|
|
37
|
+
const id=route+'\n'+JSON.stringify(input);
|
|
38
|
+
if(!retryKeys.has(id)){
|
|
39
|
+
if(retryKeys.size>=40)retryKeys.delete(retryKeys.keys().next().value);
|
|
40
|
+
retryKeys.set(id,crypto.randomUUID());
|
|
41
|
+
}
|
|
42
|
+
try{
|
|
43
|
+
const result=await api(route,json({...input,key:retryKeys.get(id)}));
|
|
44
|
+
retryKeys.delete(id);return result;
|
|
45
|
+
}catch(failure){
|
|
46
|
+
if(failure.status&&failure.status<500)retryKeys.delete(id);
|
|
47
|
+
throw failure;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function status(message='',isError=false){
|
|
51
|
+
state.message=message;state.messageError=isError;
|
|
52
|
+
const target=$('view-status');
|
|
53
|
+
if(target){target.textContent=message;target.dataset.error=String(isError);}
|
|
54
|
+
}
|
|
55
|
+
function projectQuery(extra={}){
|
|
56
|
+
return '?'+new URLSearchParams({...extra,...(state.project?{project:state.project}:{})});
|
|
57
|
+
}
|
|
58
|
+
async function api(route,options={}){
|
|
59
|
+
const {timeoutMs=6500,...request}=options;
|
|
60
|
+
const timeout=AbortSignal.timeout(timeoutMs);
|
|
61
|
+
const signal=request.signal ? AbortSignal.any([request.signal,timeout]) : timeout;
|
|
62
|
+
const pinned=local&&(state.server?.project?.id??state.overview?.projectKit?.projectId);
|
|
63
|
+
const headers={Accept:'application/json',...request.headers,...(pinned&&request.method==='POST'?{'X-Shadow-Brain-Project':pinned}:{})};
|
|
64
|
+
const response=await fetch('/api/workspace/'+route,{...request,signal,cache:'no-store',headers});
|
|
65
|
+
const data=await response.json().catch(()=>null);
|
|
66
|
+
if(!response.ok||!data){
|
|
67
|
+
const failure=new Error(data?.error ?? 'Workspace request returned HTTP '+response.status+'.');
|
|
68
|
+
failure.status=response.status;failure.code=data?.code;throw failure;
|
|
69
|
+
}
|
|
70
|
+
return data;
|
|
71
|
+
}
|
|
72
|
+
function validStatus(data){
|
|
73
|
+
return data&&typeof data.version==='string'&&/^\d+\.\d+\.\d+(?:[-+][\w.-]+)?$/.test(data.version)&&
|
|
74
|
+
typeof data.serverInstanceId==='string'&&data.serverInstanceId.length>0&&['project','shared','demo'].includes(data.mode)&&
|
|
75
|
+
(data.mode!=='project'||typeof data.project?.id==='string'&&typeof data.project.name==='string')&&
|
|
76
|
+
['ready','error','initializing'].includes(data.storage?.status)&&data.capabilities?.memory===true;
|
|
77
|
+
}
|
|
78
|
+
function validOverview(data){return data&&typeof data.version==='string'&&Array.isArray(data.projects)&&data.totals&&data.projectKit;}
|
|
79
|
+
function scopeName(){return state.overview?.projectKit?.projectName ?? arr(state.overview?.projects).find(project=>project.id===state.project)?.name ?? (state.project||'All projects');}
|
|
80
|
+
function renderChrome(){
|
|
81
|
+
const selector=$('project');
|
|
82
|
+
const projects=arr(state.overview?.projects);
|
|
83
|
+
const fixed=state.overview?.projectKit?.projectId;
|
|
84
|
+
const options=(fixed?'':'<option value="">All projects</option>')+projects.map(project=>'<option value="'+esc(project.id)+'">'+esc(project.name)+'</option>').join('');
|
|
85
|
+
if(selector.dataset.options!==options){selector.innerHTML=options||'<option value="">Loading…</option>';selector.dataset.options=options;}
|
|
86
|
+
selector.disabled=!!fixed||!state.overview||state.pending;
|
|
87
|
+
selector.value=state.project;
|
|
88
|
+
const connection=$('connection');
|
|
89
|
+
const connected=state.connection==='reachable';
|
|
90
|
+
const isDemo=state.overview?.demo===true||state.server?.mode==='demo';
|
|
91
|
+
connection.className='chip '+(connected?'green':state.connection==='connecting'?'':'amber');
|
|
92
|
+
connection.innerHTML='<i class="dot" aria-hidden="true"></i> '+(connected?(isDemo?'Demo workspace · Example data':'Workspace reachable'):state.connection==='connecting'?'Connecting to workspace':'Workspace unavailable');
|
|
93
|
+
const notice=$('notice');
|
|
94
|
+
notice.textContent=state.connection==='offline'?'The local workspace did not respond. Keep this tab open while the launcher restarts the server, or refresh to retry. '+(state.overview?'Showing the last loaded snapshot.':''):
|
|
95
|
+
state.errors.overview||state.server?.storage?.status==='error'?'The server responded, but the memory store is unavailable. '+(state.errors.overview||state.server.storage.error||''):
|
|
96
|
+
state.replayExpired?'The selected replay record is outside the loaded history. Choose another record or return to latest.':
|
|
97
|
+
state.journalGap?'Some activity expired before this page could read it. The timeline shows retained records.':liveStream.notice??'';
|
|
98
|
+
$('scope-note').textContent=state.overview?(fixed?'Project-local workspace · ':'Global workspace · ')+scopeName()+(state.overview.version?' · v'+state.overview.version:''):'';
|
|
99
|
+
const buttons=Object.entries(nav).map(([id,label])=>'<button type="button" data-view="'+id+'" '+(id===state.view?'aria-current="page"':'')+'>'+label+'</button>').join('');
|
|
100
|
+
if($('nav').dataset.buttons!==buttons){$('nav').innerHTML=buttons;$('nav').dataset.buttons=buttons;}
|
|
101
|
+
}
|
|
102
|
+
function resetScope(){
|
|
103
|
+
state.dataEpoch++;state.viewEpoch++;state.graph=null;state.picked=null;state.memory=null;state.focus=false;state.context=null;
|
|
104
|
+
state.comparison=null;state.contextInput=null;state.hub=null;state.documents=null;state.room=null;state.profile=null;state.feedback=null;
|
|
105
|
+
state.skill=null;state.skillInput=null;state.search=null;state.events=[];state.cursor=undefined;state.journalId=undefined;state.lessonFrom=null;
|
|
106
|
+
state.replayId=null;state.replayExpired=false;state.journalGap=false;state.pulseIds=[];state.motionStarted=0;
|
|
107
|
+
state.policy=null;state.policySelection=null;state.managedSkills=null;state.managedSkillPlan=null;
|
|
108
|
+
if(typeof observedPulses!=='undefined'){observedPulses.clear();dockTool=null;dockSession=null;dockPinned=false;clearTimeout(dockPresenceTimer);}
|
|
109
|
+
state.presence=null;
|
|
110
|
+
clearTimeout(nativeTimer);state.nativeConnection=null;state.nativeThreads=null;state.nativeThread=null;state.nativeListCursor=null;state.nativeThreadCursor=null;state.nativeArchived=false;state.sessions=null;state.session=null;state.sessionBefore=null;state.sessionCheckpoint=null;state.usage=null;state.sources=null;state.source=null;state.evidence=null;state.teachDraft='';
|
|
111
|
+
state.graphEpoch++;state.graphFilter='all';state.listing=false;graphCamera=defaultCamera();
|
|
112
|
+
}
|
|
113
|
+
function updateOverview(value){
|
|
114
|
+
const fixed=value.projectKit?.projectId;
|
|
115
|
+
const next=fixed ?? (arr(value.projects).some(project=>project.id===state.project)?state.project:'');
|
|
116
|
+
if(next!==state.project){state.project=next;resetScope();}
|
|
117
|
+
state.overview=value;
|
|
118
|
+
}
|
|
119
|
+
function installTelemetry(page){
|
|
120
|
+
if(!page.liveEnabled){
|
|
121
|
+
state.events=[];state.cursor=undefined;state.journalId=undefined;state.live=false;state.recording=page.recordingEnabled;state.replayId=null;state.replayExpired=false;state.pulseIds=[];
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
state.live=true;state.recording=page.recordingEnabled;
|
|
125
|
+
if(page.gap||page.reset||(state.journalId&&state.journalId!==page.journalId)){
|
|
126
|
+
state.events=[];state.journalGap=!!page.gap;state.pulseIds=[];
|
|
127
|
+
}
|
|
128
|
+
const hasHistory=state.cursor!==undefined;
|
|
129
|
+
const unique=new Map(state.events.map(event=>[event.id,event]));
|
|
130
|
+
const added=arr(page.events).filter(event=>!unique.has(event.id));
|
|
131
|
+
for(const event of added)unique.set(event.id,event);
|
|
132
|
+
if(added.length||unique.size!==state.events.length)state.events=[...unique.values()].sort((a,b)=>a.sequence-b.sequence).slice(-200);
|
|
133
|
+
state.cursor=page.cursor;
|
|
134
|
+
state.journalId=page.journalId;
|
|
135
|
+
if(state.replayId&&!state.events.some(event=>event.id===state.replayId))state.replayExpired=true;
|
|
136
|
+
if(state.suppressLivePulse){state.suppressLivePulse=false;return;}
|
|
137
|
+
if(hasHistory&&!page.gap&&!page.reset&&!page.hasMore&&typeof noteAgentActivity==='function')noteAgentActivity(added);
|
|
138
|
+
if(hasHistory&&!page.gap&&!page.reset&&!page.hasMore&&state.view==='overview'&&state.graphMode==='graph'&&!state.replayId&&!state.motionPaused&&!reduced.matches){
|
|
139
|
+
const now=Date.now();
|
|
140
|
+
const fresh=added.filter(event=>{
|
|
141
|
+
const age=now-Date.parse(event.timestamp);
|
|
142
|
+
return exchangeKey(event)&&age>=0&&age<=6500;
|
|
143
|
+
});
|
|
144
|
+
if(fresh.length){state.pulseIds=fresh.slice(-4).map(event=>event.id);state.motionStarted=performance.now();}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async function refresh(manual=false,areas=null){
|
|
148
|
+
if(document.hidden&&!manual)return;
|
|
149
|
+
clearTimeout(timer);
|
|
150
|
+
if(polling){if(areas)queueLive(areas);else pollAgain ||= manual;return;}
|
|
151
|
+
polling=true;
|
|
152
|
+
controller=new AbortController();
|
|
153
|
+
const signal=controller.signal;
|
|
154
|
+
const options={signal};
|
|
155
|
+
try{
|
|
156
|
+
const scope=state.view;
|
|
157
|
+
const needsHealth=!areas||!state.server,needsSummary=!areas||areas.has('graph');
|
|
158
|
+
const [health,summary]=await Promise.allSettled([
|
|
159
|
+
needsHealth?api('status',options):state.server,
|
|
160
|
+
needsSummary?api('overview',options):state.overview,
|
|
161
|
+
]);
|
|
162
|
+
if(signal.aborted)return;
|
|
163
|
+
const old=state.server?.serverInstanceId;
|
|
164
|
+
const healthOk=health.status==='fulfilled'&&validStatus(health.value);
|
|
165
|
+
const summaryOk=summary.status==='fulfilled'&&validOverview(summary.value);
|
|
166
|
+
if(healthOk){
|
|
167
|
+
const next=health.value;
|
|
168
|
+
if(old&&next.serverInstanceId&&old!==next.serverInstanceId){resetScope();state.features=null;state.integrations=null;}
|
|
169
|
+
state.server=next;
|
|
170
|
+
}
|
|
171
|
+
const reachable=healthOk||summaryOk;
|
|
172
|
+
state.connection=reachable?'reachable':'offline';
|
|
173
|
+
if(summaryOk){updateOverview(summary.value);delete state.errors.overview;}
|
|
174
|
+
else if(reachable)state.errors.overview=summary.reason?.message??'The workspace returned an invalid overview.';
|
|
175
|
+
renderChrome();
|
|
176
|
+
if(!reachable){failures++;state.pulseIds=[];drawGraph();updateAgentDock();if(!$('title'))render();return;}
|
|
177
|
+
failures=0;
|
|
178
|
+
polls++;
|
|
179
|
+
const epoch=state.dataEpoch,graphEpoch=state.graphEpoch;
|
|
180
|
+
const params=new URLSearchParams(projectQuery({limit:'200'}).slice(1));
|
|
181
|
+
if(state.cursor!==undefined)params.set('cursor',state.cursor);
|
|
182
|
+
if(state.journalId)params.set('journalId',state.journalId);
|
|
183
|
+
const wanted=area=>!areas||areas.has(area);
|
|
184
|
+
const jobs=[];
|
|
185
|
+
if(local&&wanted('presence')&&dockVisible(scope))jobs.push(['presence',api('presence',options)]);
|
|
186
|
+
if(local&&(wanted('policy')||scope==='setup'&&wanted('sessions'))&&!state.pending&&
|
|
187
|
+
(['setup','sessions','context','overview'].includes(scope)||state.context))jobs.push(['policy',api('project-policy',options)]);
|
|
188
|
+
if(wanted('telemetry'))jobs.push(['telemetry',api('telemetry?'+params,options)]);
|
|
189
|
+
if(local&&wanted('usage')&&['models','usage','sessions','overview'].includes(scope))jobs.push(['usage',api('usage',options)]);
|
|
190
|
+
if(local&&wanted('sessions')&&dockVisible(scope)&&!state.pending){
|
|
191
|
+
jobs.push(['sessions',api('sessions',options)]);
|
|
192
|
+
if(scope==='sessions'&&state.session)jobs.push(['session',api('sessions/'+state.session.session.id+(state.sessionBefore?'?before='+encodeURIComponent(state.sessionBefore):''),options)]);
|
|
193
|
+
}
|
|
194
|
+
if(local&&wanted('feedback')&&scope==='learning'&&!state.pending)jobs.push(['feedback',api('project-feedback',options)]);
|
|
195
|
+
if(local&&wanted('sources')&&scope==='knowledge'&&!state.pending){
|
|
196
|
+
jobs.push(['sources',api('sources',options)]);
|
|
197
|
+
if(state.source)jobs.push(['source',api('sources/'+encodeURIComponent(state.source.id),options)]);
|
|
198
|
+
}
|
|
199
|
+
if(wanted('graph')&&(!state.graph||manual||(scope==='overview'&&(areas||polls%3===0||state.graph.totalMemories!==state.overview?.quality?.total))))jobs.push(['graph',api('graph'+projectQuery({limit:graphMemoryLimit,...(state.picked?.startsWith('memory:')?{memory:state.picked.slice(7)}:{})}),options)]);
|
|
200
|
+
if(wanted('features')&&(!state.features||manual||areas||scope==='setup'))jobs.push(['features',api('features',options)]);
|
|
201
|
+
if(local&&wanted('hub')&&state.server?.capabilities?.hub!==false&&!state.pending&&(!state.hub||manual||['room','knowledge','learning'].includes(scope)))jobs.push(['hub',api('hub',options)]);
|
|
202
|
+
if(local&&wanted('hub')&&!state.pending&&scope==='room'&&state.room)jobs.push(['room',api('hub/rooms/'+encodeURIComponent(state.room.room.id),options)]);
|
|
203
|
+
const results=await Promise.allSettled(jobs.map(([,job])=>job));
|
|
204
|
+
if(signal.aborted||epoch!==state.dataEpoch)return;
|
|
205
|
+
let needsRender=false;
|
|
206
|
+
results.forEach((result,index)=>{
|
|
207
|
+
const name=jobs[index][0];
|
|
208
|
+
if(result.status==='rejected'){needsRender ||= state.errors[name]!==result.reason.message;state.errors[name]=result.reason.message;return;}
|
|
209
|
+
needsRender ||= !!state.errors[name];
|
|
210
|
+
delete state.errors[name];
|
|
211
|
+
if(name==='policy'){const changed=installPolicy(result.value);needsRender ||= scope!=='overview'&&changed;return;}
|
|
212
|
+
if(name==='presence'){installDockPresence(result.value);scheduleDockExpiry();return;}
|
|
213
|
+
if(name==='session'&&state.session?.session.id!==result.value.session.id)return;
|
|
214
|
+
if(name==='source'){
|
|
215
|
+
if(state.source?.id!==result.value.source.id)return;
|
|
216
|
+
needsRender ||= state.view==='knowledge'&&JSON.stringify(state.source)!==JSON.stringify(result.value.source);
|
|
217
|
+
state.source=result.value.source;return;
|
|
218
|
+
}
|
|
219
|
+
if(name==='sessions'||name==='session'||name==='sources'){needsRender ||= scope!=='overview'&&state.view===scope&&JSON.stringify(state[name])!==JSON.stringify(result.value);state[name]=result.value;}
|
|
220
|
+
else if(name==='feedback'){needsRender ||= state.view==='learning'&&state.feedback?.revision!==result.value.revision;state.feedback=result.value;}
|
|
221
|
+
else if(name==='usage'){needsRender ||= ['models','usage','sessions'].includes(state.view)&&JSON.stringify(state.usage)!==JSON.stringify(result.value);state.usage=result.value;}
|
|
222
|
+
else if(name==='telemetry'){const before=JSON.stringify([state.live,state.recording,state.cursor,state.events.map(event=>event.id)]);installTelemetry(result.value);needsRender ||= ['models','usage'].includes(state.view)&&before!==JSON.stringify([state.live,state.recording,state.cursor,state.events.map(event=>event.id)]);if(result.value.hasMore)pollAgain=true;}
|
|
223
|
+
else if(name==='graph'&&graphEpoch===state.graphEpoch&&JSON.stringify(state.graph)!==JSON.stringify(result.value)){state.graph=result.value;needsRender ||= state.view==='overview';}
|
|
224
|
+
else if(name==='features'&&(!state.features||result.value.revision>=state.features.revision)){
|
|
225
|
+
needsRender ||= state.view==='setup'&&state.features?.revision!==result.value.revision;
|
|
226
|
+
state.features=result.value;
|
|
227
|
+
}else if(name==='hub'&&(!state.hub||result.value.revision>=state.hub.revision)){
|
|
228
|
+
needsRender ||= ['room','knowledge','learning'].includes(state.view)&&state.hub?.revision!==result.value.revision;
|
|
229
|
+
state.hub=result.value;
|
|
230
|
+
}else if(name==='room'&&state.room?.room?.id===result.value.room.id&&result.value.revision>=state.room.revision){
|
|
231
|
+
needsRender ||= state.view==='room'&&state.room.revision!==result.value.revision;
|
|
232
|
+
state.room=result.value;
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
syncProjectStream();streamBadge();renderChrome();
|
|
236
|
+
if(local&&(!areas||areas.has('features'))&&state.features?.features?.projectFileActivity)void readLiveFiles();
|
|
237
|
+
if(state.view==='overview'){
|
|
238
|
+
if(manual||!$('brain-stage')||needsRender)render(true);
|
|
239
|
+
else updateOverviewLive();
|
|
240
|
+
}else if(manual||!$('title')||needsRender)render(true);
|
|
241
|
+
updateAgentDock();
|
|
242
|
+
if(manual)await loadView();
|
|
243
|
+
} finally {
|
|
244
|
+
polling=false;controller=undefined;
|
|
245
|
+
if(!document.hidden){
|
|
246
|
+
const delay=pollAgain?20:failures?Math.min(15000,1800*2**Math.min(3,failures-1)):local&&liveStream.status==='off'?5000:2600;
|
|
247
|
+
const next=local&&liveStream.status==='live'?new Set(['telemetry']):null;
|
|
248
|
+
if(pollAgain||!next){pollAgain=false;timer=setTimeout(()=>void refresh(false,next),delay);}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
async function loadView(){
|
|
253
|
+
const epoch=++state.viewEpoch;
|
|
254
|
+
const current=state.view;
|
|
255
|
+
const jobs=[];
|
|
256
|
+
if(current==='setup')jobs.push(['integrations','integrations']);
|
|
257
|
+
if(local&¤t==='setup')jobs.push(['managedSkills','managed-skills']);
|
|
258
|
+
if(local&&['setup','sessions','context'].includes(current))jobs.push(['policy','project-policy']);
|
|
259
|
+
if(current==='knowledge'||current==='room'||current==='learning'){
|
|
260
|
+
if(local&&!state.hub)jobs.push(['hub','hub']);
|
|
261
|
+
if(local&¤t==='knowledge'&&!state.profile)jobs.push(['profile','project-profile']);
|
|
262
|
+
if(local&¤t==='learning')jobs.push(['feedback','project-feedback']);
|
|
263
|
+
}
|
|
264
|
+
if(local&¤t==='sessions')jobs.push(['sessions','sessions']);
|
|
265
|
+
if(local&¤t==='overview'&&!state.sessions)jobs.push(['sessions','sessions']);
|
|
266
|
+
if(local&¤t==='overview'&&!state.usage)jobs.push(['usage','usage']);
|
|
267
|
+
if(local&¤t==='overview'&&!state.policy)jobs.push(['policy','project-policy']);
|
|
268
|
+
if(local&&dockVisible(current))jobs.push(['presence','presence']);
|
|
269
|
+
if(local&&['models','usage','sessions'].includes(current))jobs.push(['usage','usage']);
|
|
270
|
+
if(local&¤t==='knowledge')jobs.push(['sources','sources']);
|
|
271
|
+
if(current==='models')jobs.push(['integrations','integrations']);
|
|
272
|
+
const results=await Promise.allSettled(jobs.map(([,url])=>api(url)));
|
|
273
|
+
if(epoch!==state.viewEpoch||current!==state.view)return;
|
|
274
|
+
results.forEach((result,index)=>{
|
|
275
|
+
const name=jobs[index][0];
|
|
276
|
+
if(result.status==='fulfilled'){
|
|
277
|
+
if(name==='policy')installPolicy(result.value);
|
|
278
|
+
else if(name==='presence')installDockPresence(result.value);
|
|
279
|
+
else state[name]=result.value;
|
|
280
|
+
delete state.errors[name];
|
|
281
|
+
}
|
|
282
|
+
else state.errors[name]=result.reason.message;
|
|
283
|
+
});
|
|
284
|
+
if(jobs.length)render(true);
|
|
285
|
+
scheduleDockExpiry();
|
|
286
|
+
if(local&¤t==='sessions')void refreshNativeChats();
|
|
287
|
+
if(local&¤t==='sessions')void readLiveFiles();
|
|
288
|
+
}
|
|
289
|
+
function openView(next){
|
|
290
|
+
if(!Object.hasOwn(nav,next))return;
|
|
291
|
+
state.view=next;state.message='';state.messageError=false;state.pulseIds=[];
|
|
292
|
+
scheduleDockExpiry();
|
|
293
|
+
render();window.scrollTo(0,0);$('title')?.focus({preventScroll:true});void loadView();
|
|
294
|
+
}
|
|
295
|
+
function render(restore=false){
|
|
296
|
+
const dockFocus=$('tool-dock')?.contains(document.activeElement)?document.activeElement:null;
|
|
297
|
+
const policyToolsOpen=$('policy-tools')?.open;
|
|
298
|
+
const finder=$('node-list');
|
|
299
|
+
const finderFocus=finder?.contains(document.activeElement)?document.activeElement:null;
|
|
300
|
+
const finderDraft=$('graph-search')?.value;
|
|
301
|
+
const formValues=restore?[...$('main').querySelectorAll('form[data-form]')].map(form=>{
|
|
302
|
+
const fields=[...form.elements].filter(node=>node.name&&node.type!=='submit'&&node.type!=='button');
|
|
303
|
+
return {kind:form.dataset.form,id:form.dataset.id,item:form.dataset.item,fields:fields.map(node=>({name:node.name,value:node.value,checked:node.checked,
|
|
304
|
+
file:node.type==='file'?node:null,active:node===document.activeElement,start:node.selectionStart,end:node.selectionEnd}))};
|
|
305
|
+
}):[];
|
|
306
|
+
unmountGraph();
|
|
307
|
+
renderChrome();
|
|
308
|
+
const viewBody=views[state.view]();
|
|
309
|
+
$('main').innerHTML=viewBody+'<p class="status small" id="view-status" role="status"></p>';
|
|
310
|
+
updateAgentDock();
|
|
311
|
+
if(dockFocus?.dataset.dockTool)focusDockTool(dockFocus.dataset.dockTool);
|
|
312
|
+
else if(dockFocus?.dataset.dockRecord)[...$('tool-dock')?.querySelectorAll('[data-dock-record]')??[]].find(button=>button.dataset.dockRecord===dockFocus.dataset.dockRecord)?.focus({preventScroll:true});
|
|
313
|
+
else if(dockFocus?.id)$(dockFocus.id)?.focus({preventScroll:true});
|
|
314
|
+
if(policyToolsOpen&&$('policy-tools'))$('policy-tools').open=true;
|
|
315
|
+
status(state.message,state.messageError);
|
|
316
|
+
if(state.view==='overview'){mountGraph();updateLiveFilePulse();}
|
|
317
|
+
if(state.listing&&typeof finderDraft==='string'&&$('graph-search'))$('graph-search').value=finderDraft;
|
|
318
|
+
if(finderFocus&&state.listing){
|
|
319
|
+
const next=finderFocus.id==='graph-search'?$('graph-search'):[...$('node-list')?.querySelectorAll('button')??[]].find(button=>
|
|
320
|
+
button.dataset.node===finderFocus.dataset.node&&button.dataset.graphMemory===finderFocus.dataset.graphMemory&&button.type===finderFocus.type);
|
|
321
|
+
next?.focus({preventScroll:true});
|
|
322
|
+
}
|
|
323
|
+
for(const form of $('main').querySelectorAll('form[data-form]')){
|
|
324
|
+
const saved=formValues.find(item=>item.kind===form.dataset.form&&item.id===form.dataset.id&&item.item===form.dataset.item);
|
|
325
|
+
if(!saved)continue;
|
|
326
|
+
for(const field of saved.fields){
|
|
327
|
+
let node=form.elements.namedItem(field.name);
|
|
328
|
+
if(!node)continue;
|
|
329
|
+
if(field.file?.files?.length){node.replaceWith(field.file);node=field.file;}
|
|
330
|
+
else if(node.type!=='file'&&(node.tagName!=='SELECT'||[...node.options].some(option=>option.value===field.value)))node.value=field.value;
|
|
331
|
+
if(node.type==='checkbox')node.checked=field.checked;
|
|
332
|
+
if(field.active){node.closest('details')?.setAttribute('open','');node.focus({preventScroll:true});if(field.start!==null)node.setSelectionRange?.(field.start,field.end);}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
$('main').querySelectorAll('[id^="policy-"][type="range"]').forEach(reflectPolicySlider);
|
|
336
|
+
}
|
|
337
|
+
async function chooseMemory(id){
|
|
338
|
+
const item=arr(state.graph?.nodes).find(node=>node.id===id);
|
|
339
|
+
if(!item)return;
|
|
340
|
+
state.picked=id;state.memory=null;state.focus=true;state.inspector='record';state.pulseIds=[];
|
|
341
|
+
if(graphCamera.scale>1&&graphSurface?.points.has(id)){
|
|
342
|
+
const point=graphSurface.points.get(id);
|
|
343
|
+
graphCamera.x=(graphSurface.width/2-point.x)*graphCamera.scale;
|
|
344
|
+
graphCamera.y=(graphSurface.height/2-point.y)*graphCamera.scale;
|
|
345
|
+
boundCamera(graphSurface);
|
|
346
|
+
}
|
|
347
|
+
renderInspector();drawGraph();
|
|
348
|
+
if(item.kind!=='memory')return;
|
|
349
|
+
const epoch=state.dataEpoch;
|
|
350
|
+
try{
|
|
351
|
+
const detail=await api('memory?'+new URLSearchParams({id:item.memoryId,project:item.project}));
|
|
352
|
+
if(epoch!==state.dataEpoch||state.picked!==id)return;
|
|
353
|
+
state.memory=detail;renderInspector();
|
|
354
|
+
}catch(failure){if(epoch===state.dataEpoch&&state.picked===id)status(failure.message,true);}
|
|
355
|
+
}
|
|
356
|
+
async function loadDocuments(id){state.documents=await api('hub/documents/'+encodeURIComponent(id));state.docPage=arr(state.documents.pages)[0]?.page??1;}
|
|
357
|
+
async function loadRoom(id){state.room=await api('hub/rooms/'+encodeURIComponent(id));}
|
|
358
|
+
async function refreshHub(){state.hub=await api('hub');delete state.errors.hub;}
|
|
359
|
+
async function refreshGraph(){state.graph=await api('graph'+projectQuery({limit:graphMemoryLimit}));delete state.errors.graph;}
|
|
360
|
+
function field(form,name){return String(form.get(name)??'').trim();}
|
|
361
|
+
async function clipboard(text){
|
|
362
|
+
if(!text)throw new Error('There is no text to copy.');
|
|
363
|
+
await navigator.clipboard.writeText(text);
|
|
364
|
+
status('Copied to clipboard.');
|
|
365
|
+
}
|
|
366
|
+
async function mutation(operation,source,success='Saved.'){
|
|
367
|
+
if(state.pending)return;
|
|
368
|
+
state.pending=true;
|
|
369
|
+
const submissionView=state.view;
|
|
370
|
+
if(source)source.disabled=true;
|
|
371
|
+
renderChrome();
|
|
372
|
+
status('Working…');
|
|
373
|
+
try{
|
|
374
|
+
const message=await operation();
|
|
375
|
+
state.pending=false;status(typeof message==='string'?message:success);render(state.view!==submissionView);
|
|
376
|
+
if(source?.dataset.feature)[...$('main').querySelectorAll('[data-feature]')].find(node=>node.dataset.feature===source.dataset.feature)?.focus({preventScroll:true});
|
|
377
|
+
if(source?.dataset.policyTool||source?.dataset.policyChat)[...$('main').querySelectorAll('[data-policy-tool],[data-policy-chat]')].find(node=>
|
|
378
|
+
source.dataset.policyTool?node.dataset.policyTool===source.dataset.policyTool:node.dataset.policyChat===source.dataset.policyChat)?.focus({preventScroll:true});
|
|
379
|
+
}
|
|
380
|
+
catch(failure){
|
|
381
|
+
if(failure.status===409){
|
|
382
|
+
if(source?.dataset.feature){try{state.features=await api('features');render(true);}catch{}}
|
|
383
|
+
else if(source?.dataset.action?.startsWith('managed-skill-')){state.managedSkillPlan=null;try{state.managedSkills=await api('managed-skills');render(true);}catch{}}
|
|
384
|
+
else if(source?.closest?.('[data-form=feedback]')||['toggle-feedback','remove-feedback'].includes(source?.dataset.action)){try{state.feedback=await api('project-feedback');render(true);}catch{}}
|
|
385
|
+
else if(source?.dataset.roomAction&&state.room){try{await loadRoom(state.room.room.id);render(true);}catch{}}
|
|
386
|
+
}
|
|
387
|
+
status(failure.message||'The workspace request failed.',true);
|
|
388
|
+
}finally{
|
|
389
|
+
state.pending=false;
|
|
390
|
+
if(source)source.disabled=false;
|
|
391
|
+
$('main').querySelectorAll('button[type=submit]').forEach(node=>node.disabled=false);
|
|
392
|
+
renderChrome();
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
async function afterSave(...refreshers){
|
|
396
|
+
const results=await Promise.allSettled(refreshers.map(refresh=>refresh()));
|
|
397
|
+
return results.some(result=>result.status==='rejected')?'Saved. Refresh the workspace to reload related records.':undefined;
|
|
398
|
+
}
|
|
399
|
+
function setReplay(index){
|
|
400
|
+
const event=state.events[index];
|
|
401
|
+
if(!event)return;
|
|
402
|
+
state.replayId=event.id;state.replayExpired=false;state.pulseIds=[];state.inspector='event';state.focus=false;
|
|
403
|
+
renderChrome();
|
|
404
|
+
updateOverviewLive();renderInspector();drawGraph();
|
|
405
|
+
}
|
|
406
|
+
function start(){
|
|
407
|
+
render();
|
|
408
|
+
$('reload').addEventListener('click',()=>void refresh(true));
|
|
409
|
+
$('project').addEventListener('change',event=>{
|
|
410
|
+
state.project=event.target.value;resetScope();render();void refresh(true);
|
|
411
|
+
});
|
|
412
|
+
$('main').addEventListener('input',event=>{if(event.target.id==='replay')setReplay(Number(event.target.value));else reflectPolicySlider(event.target);});
|
|
413
|
+
$('main').addEventListener('change',event=>{
|
|
414
|
+
if(event.target.id==='policy-chat'){state.policySelection=event.target.value;render();$('policy-chat')?.focus();}
|
|
415
|
+
});
|
|
416
|
+
$('main').addEventListener('focusin',event=>previewDockTool(event.target));
|
|
417
|
+
$('main').addEventListener('pointerover',event=>{if(event.pointerType==='mouse')previewDockTool(event.target);});
|
|
418
|
+
$('main').addEventListener('keydown',event=>{
|
|
419
|
+
if(event.key==='Escape'&&dockTool&&event.target.closest('#tool-dock')){
|
|
420
|
+
const close=$('tool-dock')?.querySelector('[data-dock-close]');
|
|
421
|
+
if(close){event.preventDefault();handleAgentDock(close);}
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
document.addEventListener('visibilitychange',()=>{
|
|
425
|
+
clearTimeout(timer);state.pulseIds=[];drawGraph();updateAgentDock();scheduleDockExpiry();
|
|
426
|
+
if(document.hidden){controller?.abort();stopProjectStream();}else {state.suppressLivePulse=!!liveStream.cursor;void refresh(true);}
|
|
427
|
+
});
|
|
428
|
+
reduced.addEventListener('change',()=>{state.pulseIds=[];updateOverviewLive();updateAgentDock();});
|
|
429
|
+
window.addEventListener('online',()=>void refresh(true));
|
|
430
|
+
document.addEventListener('click',handleClick);
|
|
431
|
+
document.addEventListener('submit',handleSubmit);
|
|
432
|
+
void refresh(true);
|
|
433
|
+
}
|
|
334
434
|
`;
|
|
335
435
|
//# sourceMappingURL=brain-hub-client.js.map
|