monomind 2.0.3 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -92
- package/package.json +11 -7
- package/packages/@monomind/cli/.claude/helpers/control-start.cjs +13 -20
- package/packages/@monomind/cli/.claude/helpers/event-logger.cjs +109 -6
- package/packages/@monomind/cli/.claude/helpers/graphify-freshen.cjs +19 -17
- package/packages/@monomind/cli/.claude/helpers/handlers/agent-start-handler.cjs +60 -28
- package/packages/@monomind/cli/.claude/helpers/handlers/capture-handler.cjs +99 -28
- package/packages/@monomind/cli/.claude/helpers/handlers/edit-handler.cjs +27 -9
- package/packages/@monomind/cli/.claude/helpers/handlers/gates-handler.cjs +18 -9
- package/packages/@monomind/cli/.claude/helpers/handlers/loops-status-handler.cjs +1 -1
- package/packages/@monomind/cli/.claude/helpers/handlers/route-handler.cjs +33 -4
- package/packages/@monomind/cli/.claude/helpers/handlers/session-handler.cjs +75 -45
- package/packages/@monomind/cli/.claude/helpers/handlers/session-restore-handler.cjs +0 -12
- package/packages/@monomind/cli/.claude/helpers/handlers/task-handler.cjs +53 -22
- package/packages/@monomind/cli/.claude/helpers/hook-handler.cjs +75 -4
- package/packages/@monomind/cli/.claude/helpers/intelligence.cjs +94 -15
- package/packages/@monomind/cli/.claude/helpers/session.cjs +6 -1
- package/packages/@monomind/cli/.claude/helpers/statusline.cjs +10 -10
- package/packages/@monomind/cli/.claude/helpers/token-tracker.cjs +3 -3
- package/packages/@monomind/cli/.claude/helpers/utils/agent-registrations.cjs +41 -0
- package/packages/@monomind/cli/.claude/helpers/utils/fs-helpers.cjs +183 -0
- package/packages/@monomind/cli/.claude/helpers/utils/micro-agents.cjs +10 -6
- package/packages/@monomind/cli/.claude/helpers/utils/monograph.cjs +73 -2
- package/packages/@monomind/cli/.claude/helpers/utils/telemetry.cjs +35 -19
- package/packages/@monomind/cli/README.md +74 -92
- package/packages/@monomind/cli/bin/cli.js +10 -1
- package/packages/@monomind/cli/dist/src/browser/workflow/store.d.ts +2 -2
- package/packages/@monomind/cli/dist/src/commands/agent-ops.js +9 -15
- package/packages/@monomind/cli/dist/src/commands/browse.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/commands/cleanup.js +20 -4
- package/packages/@monomind/cli/dist/src/commands/completions.js +66 -261
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.js +5 -0
- package/packages/@monomind/cli/dist/src/commands/doctor.js +7 -2
- package/packages/@monomind/cli/dist/src/commands/hooks-workers.js +7 -0
- package/packages/@monomind/cli/dist/src/commands/index.js +3 -0
- package/packages/@monomind/cli/dist/src/commands/mcp.js +11 -6
- package/packages/@monomind/cli/dist/src/commands/memory-admin.js +12 -6
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +6 -13
- package/packages/@monomind/cli/dist/src/commands/monograph.js +3 -3
- package/packages/@monomind/cli/dist/src/commands/org.d.ts +3 -1
- package/packages/@monomind/cli/dist/src/commands/org.js +321 -127
- package/packages/@monomind/cli/dist/src/commands/platforms.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/commands/start.js +142 -37
- package/packages/@monomind/cli/dist/src/commands/tokens.js +21 -3
- package/packages/@monomind/cli/dist/src/config-adapter.js +37 -17
- package/packages/@monomind/cli/dist/src/index.js +64 -28
- package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +44 -11
- package/packages/@monomind/cli/dist/src/init/executor.js +93 -55
- package/packages/@monomind/cli/dist/src/mcp-client.d.ts +8 -3
- package/packages/@monomind/cli/dist/src/mcp-client.js +37 -3
- package/packages/@monomind/cli/dist/src/mcp-server.js +8 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.d.ts +20 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.js +10 -5
- package/packages/@monomind/cli/dist/src/mcp-tools/auto-install.d.ts +8 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/types.d.ts +31 -31
- package/packages/@monomind/cli/dist/src/mcp-tools/github-tools.js +30 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/graphify-tools.js +11 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +56 -35
- package/packages/@monomind/cli/dist/src/mcp-tools/knowledge-tools.js +9 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.js +56 -14
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +88 -41
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/prioritize-gaps.d.ts +36 -36
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/security-compliance/detect-secrets.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +6 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/system-tools.js +4 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/types.d.ts +20 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/types.js +36 -1
- package/packages/@monomind/cli/dist/src/memory/ewc-consolidation.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/memory/hnsw-operations.d.ts +13 -1
- package/packages/@monomind/cli/dist/src/memory/hnsw-operations.js +66 -14
- package/packages/@monomind/cli/dist/src/memory/intelligence.js +99 -3
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +20 -0
- package/packages/@monomind/cli/dist/src/memory/sona-optimizer.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/orgrt/broker.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/orgrt/broker.js +73 -0
- package/packages/@monomind/cli/dist/src/orgrt/bus.d.ts +5 -1
- package/packages/@monomind/cli/dist/src/orgrt/bus.js +5 -1
- package/packages/@monomind/cli/dist/src/orgrt/daemon.d.ts +46 -0
- package/packages/@monomind/cli/dist/src/orgrt/daemon.js +201 -18
- package/packages/@monomind/cli/dist/src/orgrt/forwarder.d.ts +10 -5
- package/packages/@monomind/cli/dist/src/orgrt/forwarder.js +138 -8
- package/packages/@monomind/cli/dist/src/orgrt/inbox.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/orgrt/inbox.js +56 -0
- package/packages/@monomind/cli/dist/src/orgrt/policy.d.ts +5 -1
- package/packages/@monomind/cli/dist/src/orgrt/policy.js +58 -5
- package/packages/@monomind/cli/dist/src/orgrt/provider.js +1 -0
- package/packages/@monomind/cli/dist/src/orgrt/scheduler.d.ts +13 -0
- package/packages/@monomind/cli/dist/src/orgrt/scheduler.js +48 -0
- package/packages/@monomind/cli/dist/src/orgrt/server.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/orgrt/server.js +39 -0
- package/packages/@monomind/cli/dist/src/orgrt/session.d.ts +10 -1
- package/packages/@monomind/cli/dist/src/orgrt/session.js +24 -1
- package/packages/@monomind/cli/dist/src/orgrt/test-loop.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/orgrt/test-loop.js +108 -0
- package/packages/@monomind/cli/dist/src/orgrt/types.d.ts +52 -52
- package/packages/@monomind/cli/dist/src/output.d.ts +29 -29
- package/packages/@monomind/cli/dist/src/output.js +22 -7
- package/packages/@monomind/cli/dist/src/parser.d.ts +32 -0
- package/packages/@monomind/cli/dist/src/parser.js +130 -5
- package/packages/@monomind/cli/dist/src/routing/embed-worker.js +13 -1
- package/packages/@monomind/cli/dist/src/routing/route-layer-factory.js +31 -0
- package/packages/@monomind/cli/dist/src/services/config-file-manager.d.ts +21 -0
- package/packages/@monomind/cli/dist/src/services/config-file-manager.js +60 -7
- package/packages/@monomind/cli/dist/src/services/crash-reporter.js +2 -1
- package/packages/@monomind/cli/dist/src/types.d.ts +2 -2
- package/packages/@monomind/cli/dist/src/ui/dashboard.html +243 -49
- package/packages/@monomind/cli/dist/src/ui/orgs-files.js +192 -0
- package/packages/@monomind/cli/dist/src/ui/orgs.html +79 -11
- package/packages/@monomind/cli/dist/src/ui/server.mjs +346 -139
- package/packages/@monomind/cli/dist/src/utils/input-guards.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/utils/input-guards.js +39 -5
- package/packages/@monomind/cli/package.json +15 -15
|
@@ -428,6 +428,18 @@ html, body { height: 100%; background: var(--bg); color: var(--text-hi); font-fa
|
|
|
428
428
|
/* SVG org chart */
|
|
429
429
|
.org-chart-wrap { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); overflow: hidden; margin-bottom: 12px; }
|
|
430
430
|
.org-chart-svg { width: 100%; display: block; }
|
|
431
|
+
.v2-bubble-inner {
|
|
432
|
+
background: oklch(18% 0.01 55 / 0.95);
|
|
433
|
+
border: 1px solid oklch(72% 0.18 75 / 0.4);
|
|
434
|
+
border-radius: 8px;
|
|
435
|
+
padding: 4px 8px;
|
|
436
|
+
font: 500 9.5px 'Inter', system-ui, sans-serif;
|
|
437
|
+
color: oklch(88% 0.01 75);
|
|
438
|
+
text-align: center;
|
|
439
|
+
white-space: nowrap;
|
|
440
|
+
overflow: hidden;
|
|
441
|
+
text-overflow: ellipsis;
|
|
442
|
+
}
|
|
431
443
|
.org-chart-legend { display: flex; gap: 14px; flex-wrap: wrap; padding: 0 2px; }
|
|
432
444
|
.ocl-item { display: flex; align-items: center; gap: 5px; font-size: 10px; color: var(--text-lo); }
|
|
433
445
|
|
|
@@ -2468,7 +2480,7 @@ function switchView(v, { updateHash = true } = {}) {
|
|
|
2468
2480
|
const titles = { now:'Now', projects:'Projects', sessions:'Sessions', loops:'Loops', tokens:'Tokens', memory:'Memory', orgs:'Orgs', monograph:'Monograph', monoagent:'MonoAgent', global:'Global Feed', 'global-loops':'Global Loops', 'global-tokens':'Global Tokens', chat:'Global Agent Chat' };
|
|
2469
2481
|
document.getElementById('view-title').textContent = titles[v] || v;
|
|
2470
2482
|
const PROJECT = DIR ? shortPath(DIR) : 'monomind';
|
|
2471
|
-
const VIEW_LABELS = { now: 'Now', sessions: 'Sessions', projects: 'Projects', loops: 'Loops', tokens: 'Tokens', memory: 'Memory', orgs: 'Orgs', monograph: 'Monograph', global: 'Global Feed', 'global-loops': 'Global Loops', 'global-tokens': 'Global Tokens' };
|
|
2483
|
+
const VIEW_LABELS = { now: 'Now', sessions: 'Sessions', projects: 'Projects', loops: 'Loops', tokens: 'Tokens', memory: 'Memory', orgs: 'Orgs', monograph: 'Monograph', monoagent: 'MonoAgent', global: 'Global Feed', 'global-loops': 'Global Loops', 'global-tokens': 'Global Tokens', chat: 'Global Agent Chat' };
|
|
2472
2484
|
document.title = `monomind · ${PROJECT} · ${VIEW_LABELS[v] || v}`;
|
|
2473
2485
|
if (updateHash) _pushHash();
|
|
2474
2486
|
// Projects always re-fetches so onclick paths in cards stay current
|
|
@@ -4448,9 +4460,9 @@ function appendChatViewEvent(ev, animate) {
|
|
|
4448
4460
|
const atBottom = !animate || (feed.scrollHeight - feed.scrollTop - feed.clientHeight < 80);
|
|
4449
4461
|
const ts = ev.ts ? new Date(ev.ts).toLocaleTimeString([],{hour:'2-digit',minute:'2-digit',second:'2-digit'}) : '';
|
|
4450
4462
|
if (ev.type === 'run:start') {
|
|
4451
|
-
el = mkCVSys('▶ Run started' + (ev.goal ? ': ' +
|
|
4463
|
+
el = mkCVSys('▶ Run started' + (ev.goal ? ': ' + (ev.goal.slice(0,80)) : '') + (ev.bossRole ? ' · boss: ' + (ev.bossRole) : ''), ts);
|
|
4452
4464
|
} else if (ev.type === 'run:cycle:complete') {
|
|
4453
|
-
el = mkCVSys('◎ Cycle complete' + (ev.pending != null ? ' · ' +
|
|
4465
|
+
el = mkCVSys('◎ Cycle complete' + (ev.pending != null ? ' · ' + (String(ev.pending)) + ' tasks pending' : ''), ts);
|
|
4454
4466
|
} else if (ev.type === 'intercom') {
|
|
4455
4467
|
el = mkCVIntercom(ev.from, ev.to, ev.msg || '', ts);
|
|
4456
4468
|
} else if (ev.type === 'org:comms') {
|
|
@@ -4459,15 +4471,15 @@ function appendChatViewEvent(ev, animate) {
|
|
|
4459
4471
|
if (ev.to && ev.to !== 'all') el = mkCVIntercom(_cvCommsFrom, ev.to, ev.msg || '', ts);
|
|
4460
4472
|
else el = mkCVAgent(_cvCommsFrom, ev.msg || '', ts, 'org:comms');
|
|
4461
4473
|
} else if (ev.type === 'org:agent:online') {
|
|
4462
|
-
el = mkCVSys('[' +
|
|
4474
|
+
el = mkCVSys('[' + (ev.org || '') + '] ' + (ev.role || ev.title || '?') + ' online' + (ev.title && ev.role && ev.title !== ev.role ? ' (' + (ev.title) + ')' : ''), ts);
|
|
4463
4475
|
} else if (ev.type === 'org:checkpoint') {
|
|
4464
|
-
el = mkCVSys('[checkpoint] ' +
|
|
4476
|
+
el = mkCVSys('[checkpoint] ' + (ev.summary || ev.progress || ev.msg || ''), ts);
|
|
4465
4477
|
} else if (ev.type === 'org:start') {
|
|
4466
|
-
el = mkCVSys('[org:start] ' +
|
|
4478
|
+
el = mkCVSys('[org:start] ' + (ev.org || ''), ts);
|
|
4467
4479
|
} else if (ev.type === 'run:complete') {
|
|
4468
|
-
el = mkCVSys('■ Run complete' + (ev.status ? ' [' +
|
|
4480
|
+
el = mkCVSys('■ Run complete' + (ev.status ? ' [' + (ev.status) + ']' : ''), ts);
|
|
4469
4481
|
} else if (ev.type === 'org:complete') {
|
|
4470
|
-
el = mkCVSys('■ Org complete' + (ev.org ? ' — ' +
|
|
4482
|
+
el = mkCVSys('■ Org complete' + (ev.org ? ' — ' + (ev.org) : ''), ts);
|
|
4471
4483
|
} else if (ev.type === 'agent:result') {
|
|
4472
4484
|
el = mkCVResult(ev.agent || ev.from || '?', ev.result || ev.msg || ev.message || ev.summary || '', ts);
|
|
4473
4485
|
} else if (ev.type === 'agent:spawn') {
|
|
@@ -4487,36 +4499,36 @@ function appendChatViewEvent(ev, animate) {
|
|
|
4487
4499
|
const _auAgent = ev.role || ev.agentType || '?';
|
|
4488
4500
|
const _auCost = ev.cost_usd != null ? '$' + Number(ev.cost_usd).toFixed(4) : '';
|
|
4489
4501
|
const _auTok = (ev.tokens_in || ev.tokens_out) ? ((ev.tokens_in||0)).toLocaleString() + '↑ ' + ((ev.tokens_out||0)).toLocaleString() + '↓' : '';
|
|
4490
|
-
el = mkCVSys('◈ ' +
|
|
4502
|
+
el = mkCVSys('◈ ' + (_auAgent) + (_auTok ? ' · ' + _auTok : '') + (_auCost ? ' · ' + _auCost : ''), ts);
|
|
4491
4503
|
} else if (ev.type === 'agent:message') {
|
|
4492
4504
|
el = mkCVAgent(ev.agent || ev.name || ev.role || '?', ev.msg || ev.message || ev.content || '', ts, ev.type);
|
|
4493
4505
|
} else if (ev.type === 'session:start') {
|
|
4494
|
-
el = mkCVSys('Session started' + (ev.prompt ? ': ' +
|
|
4506
|
+
el = mkCVSys('Session started' + (ev.prompt ? ': ' + (ev.prompt.slice(0,80)) : ''), ts);
|
|
4495
4507
|
} else if (ev.type === 'session:complete') {
|
|
4496
|
-
el = mkCVSys('Session complete' + (ev.status ? ' — ' +
|
|
4508
|
+
el = mkCVSys('Session complete' + (ev.status ? ' — ' + (ev.status) : ''), ts);
|
|
4497
4509
|
} else if (ev.type === 'domain:dispatch') {
|
|
4498
|
-
el = mkCVSys('→ ' +
|
|
4510
|
+
el = mkCVSys('→ ' + (ev.domain || '') + (ev.cmd ? ': ' + (ev.cmd.slice(0,80)) : ''), ts);
|
|
4499
4511
|
} else if (ev.type === 'domain:complete') {
|
|
4500
|
-
el = mkCVSys('✓ ' +
|
|
4512
|
+
el = mkCVSys('✓ ' + (ev.domain || '') + (ev.status ? ' [' + (ev.status) + ']' : ''), ts);
|
|
4501
4513
|
} else if (ev.type === 'loop:start') {
|
|
4502
|
-
el = mkCVSys('◎ Loop: ' +
|
|
4514
|
+
el = mkCVSys('◎ Loop: ' + (ev.command || '') + (ev.repeat ? ' ×' + (String(ev.repeat)) : ''), ts);
|
|
4503
4515
|
if (currentView === 'loops') renderLoops();
|
|
4504
4516
|
} else if (ev.type === 'loop:complete') {
|
|
4505
|
-
el = mkCVSys('■ Loop done: ' +
|
|
4517
|
+
el = mkCVSys('■ Loop done: ' + (ev.command || '') + (ev.ranReps ? ' (' + (String(ev.ranReps)) + ' runs)' : ''), ts);
|
|
4506
4518
|
if (currentView === 'loops') renderLoops();
|
|
4507
4519
|
} else if (ev.type === 'loop:tick') {
|
|
4508
4520
|
const _tickLbl = ev.rep != null
|
|
4509
|
-
? 'rep ' +
|
|
4510
|
-
:
|
|
4521
|
+
? 'rep ' + (String(ev.rep)) + ' done' + (ev.wait != null ? ' → next in ' + (String(ev.wait)) + 's' : '')
|
|
4522
|
+
: (ev.command || ev.loopId || ev.id || '');
|
|
4511
4523
|
el = mkCVSys('◷ ' + _tickLbl, ts);
|
|
4512
4524
|
el.dataset.evType = 'loop:tick';
|
|
4513
4525
|
if (feed.lastElementChild?.dataset?.evType === 'loop:tick') feed.lastElementChild.remove();
|
|
4514
4526
|
if (currentView === 'loops') renderLoops();
|
|
4515
4527
|
} else if (ev.type === 'loop:hil' || ev.type === 'loop:hil:waiting') {
|
|
4516
|
-
el = mkCVSys('⚠ Loop HIL: ' +
|
|
4528
|
+
el = mkCVSys('⚠ Loop HIL: ' + (ev.command || ev.loopId || ev.id || ''), ts);
|
|
4517
4529
|
if (currentView === 'loops') renderLoops();
|
|
4518
4530
|
} else if (ev.type === 'loop:hil:resolved') {
|
|
4519
|
-
el = mkCVSys('✓ Loop HIL resolved: ' +
|
|
4531
|
+
el = mkCVSys('✓ Loop HIL resolved: ' + (ev.loopId || ev.command || ''), ts);
|
|
4520
4532
|
if (currentView === 'loops') renderLoops();
|
|
4521
4533
|
} else if (ev.type === 'file:write') {
|
|
4522
4534
|
el = mkCVFileCard(ev.name || ev.path || '?', ev.path || '', ev.size || 0, ts);
|
|
@@ -4527,12 +4539,12 @@ function appendChatViewEvent(ev, animate) {
|
|
|
4527
4539
|
} else if (ev.type === 'agent:browse') {
|
|
4528
4540
|
el = mkCVTool('BROWSE', ev.payload || ev.url || '', '', 'oklch(65% 0.15 190)', ts);
|
|
4529
4541
|
} else if (ev.type === 'org:agent:offline') {
|
|
4530
|
-
el = mkCVSys('◌ ' +
|
|
4542
|
+
el = mkCVSys('◌ ' + (ev.title || ev.role || '?') + ' offline' + (ev.org ? ' [' + (ev.org) + ']' : ''), ts);
|
|
4531
4543
|
} else if (ev.type === 'org:error') {
|
|
4532
|
-
el = mkCVSys('⚠ Error: ' +
|
|
4544
|
+
el = mkCVSys('⚠ Error: ' + (ev.msg || ev.error || ev.message || ''), ts);
|
|
4533
4545
|
el.classList.add('cv-err');
|
|
4534
4546
|
} else {
|
|
4535
|
-
el = mkCVSys(
|
|
4547
|
+
el = mkCVSys((ev.type || 'event'), ts);
|
|
4536
4548
|
}
|
|
4537
4549
|
if (animate) el.classList.add('cv-new');
|
|
4538
4550
|
feed.appendChild(el);
|
|
@@ -4671,10 +4683,10 @@ function mkCVTool(tag, cmd, output, color, ts) {
|
|
|
4671
4683
|
return d;
|
|
4672
4684
|
}
|
|
4673
4685
|
|
|
4674
|
-
function mkCVSys(
|
|
4686
|
+
function mkCVSys(text, ts) {
|
|
4675
4687
|
const d = document.createElement('div');
|
|
4676
4688
|
d.className = 'cv-msg cv-sys';
|
|
4677
|
-
d.innerHTML = `<div class="cv-bub"><span class="cv-etype">SYS</span><span class="cv-text">${
|
|
4689
|
+
d.innerHTML = `<div class="cv-bub"><span class="cv-etype">SYS</span><span class="cv-text">${esc(text)}</span><span class="cv-ts">${ts}</span></div>`;
|
|
4678
4690
|
return d;
|
|
4679
4691
|
}
|
|
4680
4692
|
|
|
@@ -5786,6 +5798,7 @@ let _v2SelOrg = null;
|
|
|
5786
5798
|
let _v2OrgData = null;
|
|
5787
5799
|
let _v2OrgTab = 'chart';
|
|
5788
5800
|
const _v2OrgEventLog = {};
|
|
5801
|
+
let _v2ChartLayout = { pos: {}, edgeIdByPair: new Map() };
|
|
5789
5802
|
|
|
5790
5803
|
async function renderOrgs() {
|
|
5791
5804
|
try {
|
|
@@ -6204,6 +6217,9 @@ function v2RenderOrgChart() {
|
|
|
6204
6217
|
<image href="${avatarSrc}" x="${-avR}" y="${-R + 2}" width="${avR * 2}" height="${avR * 2}" clip-path="url(#${nodeClipIds[i]})" preserveAspectRatio="xMidYMid meet" onerror="this.setAttribute('href','data/avatars/coder.svg')"/>
|
|
6205
6218
|
<text text-anchor="middle" y="${nameY}" font-size="9" font-weight="${leader?'600':'500'}" font-family="'Inter',system-ui,sans-serif" fill="${color}">${esc(nameText)}</text>
|
|
6206
6219
|
${subTypeText ? `<text text-anchor="middle" y="${+nameY + 11}" font-size="7.5" font-family="'Inter',system-ui,sans-serif" fill="oklch(48% 0.005 75)">${esc(subTypeText)}</text>` : ''}
|
|
6220
|
+
<foreignObject class="v2-activity-bubble" data-bubble-for="${esc(role.id)}" x="-70" y="${-R - 46}" width="140" height="34" style="overflow:visible;pointer-events:none;visibility:hidden;opacity:0">
|
|
6221
|
+
<div class="v2-bubble-inner" xmlns="http://www.w3.org/1999/xhtml"></div>
|
|
6222
|
+
</foreignObject>
|
|
6207
6223
|
</g>`;
|
|
6208
6224
|
});
|
|
6209
6225
|
|
|
@@ -6230,6 +6246,7 @@ function v2RenderOrgChart() {
|
|
|
6230
6246
|
<g id="v2oc-edges">${edgesHTML}</g>
|
|
6231
6247
|
<g id="v2oc-nodes">${nodesHTML}</g>
|
|
6232
6248
|
<g id="v2oc-particles" opacity="${isRunning ? 1 : 0}">${particlesHTML}</g>
|
|
6249
|
+
<g id="v2oc-letters"></g>
|
|
6233
6250
|
</svg>
|
|
6234
6251
|
</div>
|
|
6235
6252
|
<div class="org-chart-legend" style="margin-top:10px">
|
|
@@ -6262,8 +6279,158 @@ function v2RenderOrgChart() {
|
|
|
6262
6279
|
el.style.opacity = '0';
|
|
6263
6280
|
});
|
|
6264
6281
|
}
|
|
6282
|
+
|
|
6283
|
+
const edgeIdByPair = new Map();
|
|
6284
|
+
comms.forEach((edge, ei) => {
|
|
6285
|
+
if (edge.from === edge.to) return;
|
|
6286
|
+
edgeIdByPair.set(edge.from + '->' + edge.to, 'v2ep' + ei);
|
|
6287
|
+
});
|
|
6288
|
+
_v2ChartLayout = { pos, edgeIdByPair };
|
|
6289
|
+
v2OrgActivityReset();
|
|
6290
|
+
}
|
|
6291
|
+
|
|
6292
|
+
function _v2RoleName(id, roles) {
|
|
6293
|
+
const r = (roles || []).find(x => x.id === id);
|
|
6294
|
+
return r ? (r.name || r.title || r.id) : id;
|
|
6295
|
+
}
|
|
6296
|
+
|
|
6297
|
+
function v2DeriveActivityText(ev, roles) {
|
|
6298
|
+
if (!ev || !ev.from) return null;
|
|
6299
|
+
const type = ev.type || '';
|
|
6300
|
+
if (type === 'org:tool') return ev.tool ? ('running ' + ev.tool) : 'active';
|
|
6301
|
+
if (type === 'org:checkpoint') {
|
|
6302
|
+
const p = ev.progress || '';
|
|
6303
|
+
return p ? (p.length > 40 ? p.slice(0, 39) + '...' : p) : 'active';
|
|
6304
|
+
}
|
|
6305
|
+
if (type === 'org:comms') {
|
|
6306
|
+
if (!ev.to || ev.to === 'all') return 'broadcasting';
|
|
6307
|
+
return 'messaging ' + _v2RoleName(ev.to, roles);
|
|
6308
|
+
}
|
|
6309
|
+
if (type === 'org:artifact') {
|
|
6310
|
+
const label = ev.artifact && ev.artifact.label;
|
|
6311
|
+
return label ? ('writing ' + label) : 'active';
|
|
6312
|
+
}
|
|
6313
|
+
return 'active';
|
|
6314
|
+
}
|
|
6315
|
+
|
|
6316
|
+
function v2DeriveLetterTarget(ev, roles) {
|
|
6317
|
+
if (!ev || !ev.from) return null;
|
|
6318
|
+
const type = ev.type || '';
|
|
6319
|
+
if (type === 'org:comms') {
|
|
6320
|
+
if (!ev.to || ev.to === 'all') return null;
|
|
6321
|
+
return { from: ev.from, to: ev.to };
|
|
6322
|
+
}
|
|
6323
|
+
if (type === 'org:checkpoint' || type === 'org:artifact') {
|
|
6324
|
+
const leader = (roles || []).find(_v2OrgIsLeader);
|
|
6325
|
+
if (!leader || leader.id === ev.from) return null;
|
|
6326
|
+
return { from: ev.from, to: leader.id };
|
|
6327
|
+
}
|
|
6328
|
+
return null;
|
|
6329
|
+
}
|
|
6330
|
+
|
|
6331
|
+
let _v2LetterBurst = { lastTs: 0, count: 0 };
|
|
6332
|
+
|
|
6333
|
+
function v2SpawnLetter(fromId, toId) {
|
|
6334
|
+
const layout = _v2ChartLayout;
|
|
6335
|
+
const fp = layout.pos[fromId], tp = layout.pos[toId];
|
|
6336
|
+
if (!fp || !tp) return;
|
|
6337
|
+
const group = document.getElementById('v2oc-letters');
|
|
6338
|
+
if (!group) return;
|
|
6339
|
+
|
|
6340
|
+
const now = Date.now();
|
|
6341
|
+
if (now - _v2LetterBurst.lastTs < 150) _v2LetterBurst.count++;
|
|
6342
|
+
else _v2LetterBurst.count = 0;
|
|
6343
|
+
_v2LetterBurst.lastTs = now;
|
|
6344
|
+
const delay = (_v2LetterBurst.count * 0.08).toFixed(2);
|
|
6345
|
+
|
|
6346
|
+
const svgNS = 'http://www.w3.org/2000/svg';
|
|
6347
|
+
let pathId = layout.edgeIdByPair.get(fromId + '->' + toId);
|
|
6348
|
+
let synthesizedPath = null;
|
|
6349
|
+
if (!pathId) {
|
|
6350
|
+
pathId = 'v2lp' + Math.random().toString(36).slice(2, 9);
|
|
6351
|
+
synthesizedPath = document.createElementNS(svgNS, 'path');
|
|
6352
|
+
synthesizedPath.setAttribute('id', pathId);
|
|
6353
|
+
synthesizedPath.setAttribute('d', 'M' + fp.x + ',' + fp.y + ' L' + tp.x + ',' + tp.y);
|
|
6354
|
+
synthesizedPath.setAttribute('fill', 'none');
|
|
6355
|
+
synthesizedPath.setAttribute('stroke', 'none');
|
|
6356
|
+
document.getElementById('v2oc-edges').appendChild(synthesizedPath);
|
|
6357
|
+
}
|
|
6358
|
+
|
|
6359
|
+
const letter = document.createElementNS(svgNS, 'g');
|
|
6360
|
+
const circ = document.createElementNS(svgNS, 'circle');
|
|
6361
|
+
circ.setAttribute('r', '6');
|
|
6362
|
+
circ.setAttribute('fill', 'oklch(85% 0.16 85)');
|
|
6363
|
+
circ.setAttribute('stroke', 'oklch(30% 0.02 55)');
|
|
6364
|
+
circ.setAttribute('stroke-width', '1');
|
|
6365
|
+
letter.appendChild(circ);
|
|
6366
|
+
const flap = document.createElementNS(svgNS, 'path');
|
|
6367
|
+
flap.setAttribute('d', 'M-3.5,-2 L0,1 L3.5,-2');
|
|
6368
|
+
flap.setAttribute('stroke', 'oklch(30% 0.02 55)');
|
|
6369
|
+
flap.setAttribute('stroke-width', '1');
|
|
6370
|
+
flap.setAttribute('fill', 'none');
|
|
6371
|
+
letter.appendChild(flap);
|
|
6372
|
+
|
|
6373
|
+
const anim = document.createElementNS(svgNS, 'animateMotion');
|
|
6374
|
+
anim.setAttribute('dur', '0.8s');
|
|
6375
|
+
anim.setAttribute('begin', delay + 's');
|
|
6376
|
+
anim.setAttribute('fill', 'freeze');
|
|
6377
|
+
const mpath = document.createElementNS(svgNS, 'mpath');
|
|
6378
|
+
mpath.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + pathId);
|
|
6379
|
+
anim.appendChild(mpath);
|
|
6380
|
+
letter.appendChild(anim);
|
|
6381
|
+
group.appendChild(letter);
|
|
6382
|
+
|
|
6383
|
+
if (typeof gsap !== 'undefined') {
|
|
6384
|
+
gsap.fromTo(letter, { scale: 0, autoAlpha: 0 }, { scale: 1, autoAlpha: 1, duration: 0.15, delay: Number(delay), ease: 'back.out(1.7)' });
|
|
6385
|
+
}
|
|
6386
|
+
|
|
6387
|
+
const totalMs = (Number(delay) + 0.8) * 1000;
|
|
6388
|
+
setTimeout(function() {
|
|
6389
|
+
function cleanup() {
|
|
6390
|
+
letter.remove();
|
|
6391
|
+
if (synthesizedPath) synthesizedPath.remove();
|
|
6392
|
+
}
|
|
6393
|
+
if (typeof gsap !== 'undefined') {
|
|
6394
|
+
gsap.to(letter, { autoAlpha: 0, duration: 0.15, onComplete: cleanup });
|
|
6395
|
+
} else cleanup();
|
|
6396
|
+
}, totalMs);
|
|
6397
|
+
}
|
|
6398
|
+
|
|
6399
|
+
let _v2BubbleTimers = new Map();
|
|
6400
|
+
|
|
6401
|
+
function v2OrgActivityReset() {
|
|
6402
|
+
_v2BubbleTimers.forEach(t => clearTimeout(t));
|
|
6403
|
+
_v2BubbleTimers = new Map();
|
|
6265
6404
|
}
|
|
6266
6405
|
|
|
6406
|
+
function v2ShowActivityBubble(roleId, text) {
|
|
6407
|
+
const fo = document.querySelector('.v2-activity-bubble[data-bubble-for="' + CSS.escape(roleId) + '"]');
|
|
6408
|
+
if (!fo) return;
|
|
6409
|
+
const inner = fo.querySelector('.v2-bubble-inner');
|
|
6410
|
+
inner.textContent = text;
|
|
6411
|
+
if (typeof gsap !== 'undefined') {
|
|
6412
|
+
gsap.killTweensOf(fo);
|
|
6413
|
+
fo.style.visibility = 'visible';
|
|
6414
|
+
gsap.fromTo(fo, { scale: 0.8, autoAlpha: 0 }, {
|
|
6415
|
+
scale: 1, autoAlpha: 1, duration: 0.3, ease: 'back.out(1.7)',
|
|
6416
|
+
transformOrigin: '50% 100%',
|
|
6417
|
+
});
|
|
6418
|
+
} else {
|
|
6419
|
+
fo.style.visibility = 'visible';
|
|
6420
|
+
fo.style.opacity = '1';
|
|
6421
|
+
}
|
|
6422
|
+
const existing = _v2BubbleTimers.get(roleId);
|
|
6423
|
+
if (existing) clearTimeout(existing);
|
|
6424
|
+
_v2BubbleTimers.set(roleId, setTimeout(function() {
|
|
6425
|
+
if (typeof gsap !== 'undefined') {
|
|
6426
|
+
gsap.to(fo, { autoAlpha: 0, duration: 0.4, ease: 'power2.in', onComplete: function() { fo.style.visibility = 'hidden'; } });
|
|
6427
|
+
} else {
|
|
6428
|
+
fo.style.opacity = '0';
|
|
6429
|
+
fo.style.visibility = 'hidden';
|
|
6430
|
+
}
|
|
6431
|
+
_v2BubbleTimers.delete(roleId);
|
|
6432
|
+
}, 5000));
|
|
6433
|
+
}
|
|
6267
6434
|
|
|
6268
6435
|
// ── in-place running dot updater (avoids full re-render + GSAP flicker on SSE events) ──
|
|
6269
6436
|
function v2UpdateChartRunningDots() {
|
|
@@ -7940,17 +8107,28 @@ window.odtChatSelectAgent = function(name) {
|
|
|
7940
8107
|
});
|
|
7941
8108
|
const feed = document.getElementById('odt-chat-feed');
|
|
7942
8109
|
const emptyEl = document.getElementById('odt-chat-empty');
|
|
7943
|
-
const sess = _odtChatSessions.find(s => s.id === _odtChatCurrentId);
|
|
7944
8110
|
feed.querySelectorAll('.cv-msg').forEach(e => e.remove());
|
|
7945
|
-
|
|
7946
|
-
|
|
8111
|
+
const id = _odtChatCurrentId;
|
|
8112
|
+
let events = null;
|
|
8113
|
+
let sess = null;
|
|
8114
|
+
if (id && id.startsWith('rgrp:') && _odtRunGroups[id]) {
|
|
8115
|
+
events = _odtGetMergedRunGroupEvents(_odtRunGroups[id]);
|
|
8116
|
+
} else if (id && id.startsWith('grp:') && _odtSessionGroups[id]) {
|
|
8117
|
+
events = _odtGetMergedGroupEvents(_odtSessionGroups[id]);
|
|
8118
|
+
} else {
|
|
8119
|
+
sess = _odtChatSessions.find(s => s.id === id);
|
|
8120
|
+
events = sess ? (sess.events || []) : null;
|
|
8121
|
+
}
|
|
8122
|
+
if (events === null) { if (emptyEl) { emptyEl.style.display = 'block'; emptyEl.textContent = 'Select a session to see agent communications.'; } return; }
|
|
8123
|
+
const visible = events.filter(ev => _odtChatAgentMatches(ev));
|
|
7947
8124
|
if (!visible.length) {
|
|
7948
8125
|
if (emptyEl) { emptyEl.style.display = 'block'; emptyEl.textContent = name === 'all' ? 'No events.' : `${name} was online in this run but sent no messages.`; }
|
|
7949
8126
|
} else {
|
|
7950
8127
|
if (emptyEl) emptyEl.style.display = 'none';
|
|
7951
8128
|
visible.forEach(ev => _odtAppendEvent(ev, false));
|
|
8129
|
+
if (!feed.querySelector('.cv-msg') && emptyEl) { emptyEl.style.display = 'block'; emptyEl.textContent = 'No displayable events.'; }
|
|
7952
8130
|
}
|
|
7953
|
-
if (!sess._isOrgRun) {
|
|
8131
|
+
if (sess && !sess._isOrgRun) {
|
|
7954
8132
|
const _linkedRunId = 'run-' + (sess.id || '').replace(/^mm-/, '');
|
|
7955
8133
|
const _linkedRun = _odtChatSessions.find(s => s._isOrgRun && s.id === _linkedRunId);
|
|
7956
8134
|
if (_linkedRun) {
|
|
@@ -7976,17 +8154,25 @@ window.odtChatSelectAgent = function(name) {
|
|
|
7976
8154
|
// Chat tab render mode (Summary/Detailed/Raw) — persists to localStorage
|
|
7977
8155
|
let _odtChatMode = localStorage.getItem('odt-chat-mode') || 'detailed';
|
|
7978
8156
|
|
|
7979
|
-
function
|
|
7980
|
-
_odtChatMode = mode;
|
|
7981
|
-
localStorage.setItem('odt-chat-mode', mode);
|
|
8157
|
+
function _odtApplyChatModeUI(mode) {
|
|
7982
8158
|
document.querySelectorAll('.odt-mode-btn').forEach(b => b.classList.remove('active'));
|
|
7983
8159
|
const btn = document.getElementById('odt-mode-' + mode);
|
|
7984
8160
|
if (btn) btn.classList.add('active');
|
|
7985
8161
|
}
|
|
7986
8162
|
|
|
8163
|
+
function setOdtChatMode(mode) {
|
|
8164
|
+
_odtChatMode = mode;
|
|
8165
|
+
localStorage.setItem('odt-chat-mode', mode);
|
|
8166
|
+
_odtApplyChatModeUI(mode);
|
|
8167
|
+
// Re-render the current selection so the mode change is reflected immediately —
|
|
8168
|
+
// previously this only affected events appended after the switch.
|
|
8169
|
+
if (_odtChatCurrentId) window.odtChatSelectAgent(_odtChatCurrentAgent);
|
|
8170
|
+
}
|
|
8171
|
+
|
|
7987
8172
|
function initOdtChatMode() {
|
|
7988
8173
|
const saved = localStorage.getItem('odt-chat-mode') || 'detailed';
|
|
7989
|
-
|
|
8174
|
+
_odtChatMode = saved;
|
|
8175
|
+
_odtApplyChatModeUI(saved);
|
|
7990
8176
|
}
|
|
7991
8177
|
|
|
7992
8178
|
function _odtAppendEvent(ev, animate) {
|
|
@@ -8014,18 +8200,18 @@ function _odtAppendEvent(ev, animate) {
|
|
|
8014
8200
|
const ts = ev.ts ? new Date(ev.ts).toLocaleTimeString([],{hour:'2-digit',minute:'2-digit',second:'2-digit'}) : '';
|
|
8015
8201
|
let el;
|
|
8016
8202
|
if (ev.type === 'run:start') {
|
|
8017
|
-
el = mkCVSys('▶ Run started' + (ev.goal ? ': ' +
|
|
8203
|
+
el = mkCVSys('▶ Run started' + (ev.goal ? ': ' + (ev.goal.slice(0,80)) : '') + (ev.bossRole ? ' · boss: ' + (ev.bossRole) : ''), ts);
|
|
8018
8204
|
} else if (ev.type === 'run:cycle:complete') {
|
|
8019
|
-
el = mkCVSys('◎ Cycle complete' + (ev.pending != null ? ' · ' +
|
|
8205
|
+
el = mkCVSys('◎ Cycle complete' + (ev.pending != null ? ' · ' + (String(ev.pending)) + ' tasks pending' : ''), ts);
|
|
8020
8206
|
} else if (ev.type === 'run:complete') {
|
|
8021
|
-
el = mkCVSys('■ Run complete' + (ev.status ? ' [' +
|
|
8207
|
+
el = mkCVSys('■ Run complete' + (ev.status ? ' [' + (ev.status) + ']' : ''), ts);
|
|
8022
8208
|
} else if (ev.type === 'org:comms') {
|
|
8023
8209
|
// Some older runs use ev.role instead of ev.from — normalise before rendering
|
|
8024
8210
|
const _commsFrom = ev.from || ev.role || 'boss';
|
|
8025
8211
|
if (ev.to && ev.to !== 'all') el = mkCVIntercom(_commsFrom, ev.to, ev.msg || '', ts);
|
|
8026
8212
|
else el = mkCVAgent(_commsFrom, ev.msg || '', ts, 'org:comms');
|
|
8027
8213
|
} else if (ev.type === 'org:agent:online') {
|
|
8028
|
-
el = mkCVSys('◉ ' +
|
|
8214
|
+
el = mkCVSys('◉ ' + (ev.title || ev.role || '?') + ' online', ts);
|
|
8029
8215
|
} else if (ev.type === 'org:checkpoint') {
|
|
8030
8216
|
el = mkCVAgent('boss', ev.summary || ev.progress || ev.msg || '', ts, 'org:checkpoint');
|
|
8031
8217
|
} else if (ev.type === 'org:start' || ev.type === 'org:complete') {
|
|
@@ -8041,32 +8227,32 @@ function _odtAppendEvent(ev, animate) {
|
|
|
8041
8227
|
} else if (ev.type === 'agent:message') {
|
|
8042
8228
|
el = mkCVAgent(ev.agent || ev.name || ev.role || '?', ev.msg || ev.message || ev.content || '', ts, ev.type);
|
|
8043
8229
|
} else if (ev.type === 'session:start') {
|
|
8044
|
-
el = mkCVSys('▶ ' +
|
|
8230
|
+
el = mkCVSys('▶ ' + ((ev.prompt || '').replace(/^running org:\s*/i,'').slice(0,80) || 'Session started'), ts);
|
|
8045
8231
|
} else if (ev.type === 'session:complete') {
|
|
8046
|
-
el = mkCVSys('■ Complete' + (ev.status ? ' — ' +
|
|
8232
|
+
el = mkCVSys('■ Complete' + (ev.status ? ' — ' + (ev.status) : ''), ts);
|
|
8047
8233
|
} else if (ev.type === 'domain:dispatch') {
|
|
8048
|
-
el = mkCVSys('→ ' +
|
|
8234
|
+
el = mkCVSys('→ ' + (ev.domain || '') + (ev.cmd ? ': ' + (ev.cmd.slice(0,80)) : ''), ts);
|
|
8049
8235
|
} else if (ev.type === 'domain:complete') {
|
|
8050
|
-
el = mkCVSys('✓ ' +
|
|
8236
|
+
el = mkCVSys('✓ ' + (ev.domain || '') + (ev.status ? ' [' + (ev.status) + ']' : ''), ts);
|
|
8051
8237
|
} else if (ev.type === 'loop:start') {
|
|
8052
|
-
el = mkCVSys('Loop: ' +
|
|
8238
|
+
el = mkCVSys('Loop: ' + (ev.command || ''), ts);
|
|
8053
8239
|
} else if (ev.type === 'loop:complete') {
|
|
8054
|
-
el = mkCVSys('Loop done: ' +
|
|
8240
|
+
el = mkCVSys('Loop done: ' + (ev.command || '') + (ev.ranReps ? ' (' + ev.ranReps + ' runs)' : ''), ts);
|
|
8055
8241
|
} else if (ev.type === 'loop:tick') {
|
|
8056
8242
|
const _trep = ev.rep ?? ev.fromRep;
|
|
8057
8243
|
const _tnext = ev.nextRep ?? ev.toRep;
|
|
8058
8244
|
const tickLabel = _trep != null
|
|
8059
|
-
? 'rep ' +
|
|
8060
|
-
:
|
|
8245
|
+
? 'rep ' + (String(_trep)) + ' done' + (_tnext != null ? ' → rep ' + (String(_tnext)) + (ev.wait != null ? ' in ' + (String(ev.wait)) + 's' : '') : '')
|
|
8246
|
+
: (ev.command || ev.loopId || '');
|
|
8061
8247
|
el = mkCVSys('◷ ' + tickLabel, ts);
|
|
8062
8248
|
el.dataset.evType = 'loop:tick';
|
|
8063
8249
|
// Collapse: replace the previous loop:tick if it's the last element — prevents the
|
|
8064
8250
|
// feed from flooding with one entry per rep in long-running loops (e.g. --repeat 9999).
|
|
8065
8251
|
if (feed.lastElementChild?.dataset?.evType === 'loop:tick') feed.lastElementChild.remove();
|
|
8066
8252
|
} else if (ev.type === 'loop:hil' || ev.type === 'loop:hil:waiting') {
|
|
8067
|
-
el = mkCVSys('⚠ Loop HIL: ' +
|
|
8253
|
+
el = mkCVSys('⚠ Loop HIL: ' + (ev.command || ev.loopId || ''), ts);
|
|
8068
8254
|
} else if (ev.type === 'loop:hil:resolved') {
|
|
8069
|
-
el = mkCVSys('✓ Loop HIL resolved: ' +
|
|
8255
|
+
el = mkCVSys('✓ Loop HIL resolved: ' + (ev.loopId || ''), ts);
|
|
8070
8256
|
} else if (ev.type === 'agent:edit' || ev.type === 'agent:write') {
|
|
8071
8257
|
el = mkCVTool('EDIT', ev.payload || ev.file || ev.path || '', '', 'oklch(65% 0.20 270)', ts);
|
|
8072
8258
|
} else if (ev.type === 'agent:bash') {
|
|
@@ -8074,15 +8260,15 @@ function _odtAppendEvent(ev, animate) {
|
|
|
8074
8260
|
} else if (ev.type === 'agent:browse') {
|
|
8075
8261
|
el = mkCVTool('BROWSE', ev.payload || ev.url || '', '', 'oklch(65% 0.15 190)', ts);
|
|
8076
8262
|
} else if (ev.type === 'org:error') {
|
|
8077
|
-
el = mkCVSys('⚠ Error: ' +
|
|
8263
|
+
el = mkCVSys('⚠ Error: ' + (ev.msg || ev.error || ev.message || ''), ts);
|
|
8078
8264
|
el.classList.add('cv-err');
|
|
8079
8265
|
} else if (ev.type === 'org:agent:offline') {
|
|
8080
|
-
el = mkCVSys('◌ ' +
|
|
8266
|
+
el = mkCVSys('◌ ' + (ev.title || ev.role || '?') + ' offline', ts);
|
|
8081
8267
|
} else if (ev.type === 'user:message') {
|
|
8082
8268
|
el = mkCVAgent('you', ev.text || ev.msg || ev.message || '', ts, 'user:message');
|
|
8083
8269
|
el.classList.add('cv-user-msg');
|
|
8084
8270
|
} else {
|
|
8085
|
-
el = mkCVSys(
|
|
8271
|
+
el = mkCVSys((ev.type || 'event'), ts);
|
|
8086
8272
|
}
|
|
8087
8273
|
if (animate) el.classList.add('cv-new');
|
|
8088
8274
|
feed.appendChild(el);
|
|
@@ -8146,6 +8332,14 @@ function _odtHandleLiveEvent(ev) {
|
|
|
8146
8332
|
const _arr = [..._odtChatSeenKeys];
|
|
8147
8333
|
_odtChatSeenKeys = new Set(_arr.slice(1000));
|
|
8148
8334
|
}
|
|
8335
|
+
// Wire activity bubble for org chart visualization
|
|
8336
|
+
if (ev && ev.org === _v2SelOrg) {
|
|
8337
|
+
const roles = Array.isArray(_v2OrgData && _v2OrgData.roles) ? _v2OrgData.roles : [];
|
|
8338
|
+
const text = v2DeriveActivityText(ev, roles);
|
|
8339
|
+
if (text && ev.from) v2ShowActivityBubble(ev.from, text);
|
|
8340
|
+
const letterTarget = v2DeriveLetterTarget(ev, roles);
|
|
8341
|
+
if (letterTarget) v2SpawnLetter(letterTarget.from, letterTarget.to);
|
|
8342
|
+
}
|
|
8149
8343
|
// Route org run events (have runId + org) to the active run session
|
|
8150
8344
|
if (ev?.org && ev?.runId && ev.org === _v2SelOrg) {
|
|
8151
8345
|
let runSess = _odtChatSessions.find(s => s.id === ev.runId);
|