@monoes/monomindcli 2.0.2 → 2.1.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.
Files changed (180) hide show
  1. package/.claude/commands/mastermind/runorg.md +4 -0
  2. package/.claude/helpers/control-start.cjs +50 -5
  3. package/.claude/helpers/event-logger.cjs +109 -6
  4. package/.claude/helpers/graphify-freshen.cjs +19 -17
  5. package/.claude/helpers/handlers/agent-start-handler.cjs +60 -28
  6. package/.claude/helpers/handlers/capture-handler.cjs +75 -18
  7. package/.claude/helpers/handlers/edit-handler.cjs +27 -9
  8. package/.claude/helpers/handlers/gates-handler.cjs +16 -7
  9. package/.claude/helpers/handlers/loops-status-handler.cjs +1 -1
  10. package/.claude/helpers/handlers/route-handler.cjs +4 -4
  11. package/.claude/helpers/handlers/session-handler.cjs +40 -22
  12. package/.claude/helpers/handlers/session-restore-handler.cjs +0 -12
  13. package/.claude/helpers/handlers/task-handler.cjs +53 -22
  14. package/.claude/helpers/hook-handler.cjs +54 -4
  15. package/.claude/helpers/intelligence.cjs +94 -15
  16. package/.claude/helpers/session.cjs +6 -1
  17. package/.claude/helpers/statusline.cjs +10 -10
  18. package/.claude/helpers/token-tracker.cjs +3 -3
  19. package/.claude/helpers/utils/agent-registrations.cjs +41 -0
  20. package/.claude/helpers/utils/fs-helpers.cjs +183 -0
  21. package/.claude/helpers/utils/micro-agents.cjs +10 -6
  22. package/.claude/helpers/utils/telemetry.cjs +35 -19
  23. package/bin/cli.js +10 -1
  24. package/dist/src/commands/agent-ops.d.ts.map +1 -1
  25. package/dist/src/commands/agent-ops.js +9 -15
  26. package/dist/src/commands/agent-ops.js.map +1 -1
  27. package/dist/src/commands/cleanup.d.ts.map +1 -1
  28. package/dist/src/commands/cleanup.js +20 -4
  29. package/dist/src/commands/cleanup.js.map +1 -1
  30. package/dist/src/commands/completions.d.ts.map +1 -1
  31. package/dist/src/commands/completions.js +66 -261
  32. package/dist/src/commands/completions.js.map +1 -1
  33. package/dist/src/commands/doctor.d.ts.map +1 -1
  34. package/dist/src/commands/doctor.js +7 -2
  35. package/dist/src/commands/doctor.js.map +1 -1
  36. package/dist/src/commands/hooks-workers.d.ts.map +1 -1
  37. package/dist/src/commands/hooks-workers.js +7 -0
  38. package/dist/src/commands/hooks-workers.js.map +1 -1
  39. package/dist/src/commands/index.d.ts.map +1 -1
  40. package/dist/src/commands/index.js +3 -0
  41. package/dist/src/commands/index.js.map +1 -1
  42. package/dist/src/commands/mcp.d.ts.map +1 -1
  43. package/dist/src/commands/mcp.js +11 -6
  44. package/dist/src/commands/mcp.js.map +1 -1
  45. package/dist/src/commands/memory-admin.d.ts.map +1 -1
  46. package/dist/src/commands/memory-admin.js +12 -6
  47. package/dist/src/commands/memory-admin.js.map +1 -1
  48. package/dist/src/commands/memory-transfer.d.ts.map +1 -1
  49. package/dist/src/commands/memory-transfer.js +6 -13
  50. package/dist/src/commands/memory-transfer.js.map +1 -1
  51. package/dist/src/commands/monograph.js +3 -3
  52. package/dist/src/commands/monograph.js.map +1 -1
  53. package/dist/src/commands/org.d.ts +3 -1
  54. package/dist/src/commands/org.d.ts.map +1 -1
  55. package/dist/src/commands/org.js +306 -129
  56. package/dist/src/commands/org.js.map +1 -1
  57. package/dist/src/commands/start.d.ts.map +1 -1
  58. package/dist/src/commands/start.js +142 -37
  59. package/dist/src/commands/start.js.map +1 -1
  60. package/dist/src/commands/tokens.d.ts.map +1 -1
  61. package/dist/src/commands/tokens.js +21 -3
  62. package/dist/src/commands/tokens.js.map +1 -1
  63. package/dist/src/config-adapter.d.ts.map +1 -1
  64. package/dist/src/config-adapter.js +37 -17
  65. package/dist/src/config-adapter.js.map +1 -1
  66. package/dist/src/index.d.ts.map +1 -1
  67. package/dist/src/index.js +64 -28
  68. package/dist/src/index.js.map +1 -1
  69. package/dist/src/init/claudemd-generator.d.ts.map +1 -1
  70. package/dist/src/init/claudemd-generator.js +44 -11
  71. package/dist/src/init/claudemd-generator.js.map +1 -1
  72. package/dist/src/init/executor.d.ts.map +1 -1
  73. package/dist/src/init/executor.js +63 -49
  74. package/dist/src/init/executor.js.map +1 -1
  75. package/dist/src/mcp-client.d.ts +8 -3
  76. package/dist/src/mcp-client.d.ts.map +1 -1
  77. package/dist/src/mcp-client.js +37 -3
  78. package/dist/src/mcp-client.js.map +1 -1
  79. package/dist/src/mcp-server.d.ts.map +1 -1
  80. package/dist/src/mcp-server.js +8 -2
  81. package/dist/src/mcp-server.js.map +1 -1
  82. package/dist/src/mcp-tools/agent-tools.d.ts +20 -0
  83. package/dist/src/mcp-tools/agent-tools.d.ts.map +1 -1
  84. package/dist/src/mcp-tools/agent-tools.js +10 -5
  85. package/dist/src/mcp-tools/agent-tools.js.map +1 -1
  86. package/dist/src/mcp-tools/github-tools.d.ts.map +1 -1
  87. package/dist/src/mcp-tools/github-tools.js +30 -8
  88. package/dist/src/mcp-tools/github-tools.js.map +1 -1
  89. package/dist/src/mcp-tools/graphify-tools.d.ts.map +1 -1
  90. package/dist/src/mcp-tools/graphify-tools.js +11 -2
  91. package/dist/src/mcp-tools/graphify-tools.js.map +1 -1
  92. package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -1
  93. package/dist/src/mcp-tools/hive-mind-tools.js +51 -34
  94. package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -1
  95. package/dist/src/mcp-tools/knowledge-tools.d.ts.map +1 -1
  96. package/dist/src/mcp-tools/knowledge-tools.js +9 -1
  97. package/dist/src/mcp-tools/knowledge-tools.js.map +1 -1
  98. package/dist/src/mcp-tools/monograph-compat.d.ts.map +1 -1
  99. package/dist/src/mcp-tools/monograph-compat.js +56 -14
  100. package/dist/src/mcp-tools/monograph-compat.js.map +1 -1
  101. package/dist/src/mcp-tools/monograph-tools.d.ts.map +1 -1
  102. package/dist/src/mcp-tools/monograph-tools.js +65 -43
  103. package/dist/src/mcp-tools/monograph-tools.js.map +1 -1
  104. package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -1
  105. package/dist/src/mcp-tools/swarm-tools.js +6 -4
  106. package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
  107. package/dist/src/mcp-tools/system-tools.d.ts.map +1 -1
  108. package/dist/src/mcp-tools/system-tools.js +4 -4
  109. package/dist/src/mcp-tools/system-tools.js.map +1 -1
  110. package/dist/src/mcp-tools/types.d.ts +20 -0
  111. package/dist/src/mcp-tools/types.d.ts.map +1 -1
  112. package/dist/src/mcp-tools/types.js +36 -1
  113. package/dist/src/mcp-tools/types.js.map +1 -1
  114. package/dist/src/memory/hnsw-operations.d.ts +13 -1
  115. package/dist/src/memory/hnsw-operations.d.ts.map +1 -1
  116. package/dist/src/memory/hnsw-operations.js +66 -14
  117. package/dist/src/memory/hnsw-operations.js.map +1 -1
  118. package/dist/src/memory/intelligence.d.ts.map +1 -1
  119. package/dist/src/memory/intelligence.js +99 -3
  120. package/dist/src/memory/intelligence.js.map +1 -1
  121. package/dist/src/memory/memory-bridge.d.ts +7 -0
  122. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  123. package/dist/src/memory/memory-bridge.js +20 -0
  124. package/dist/src/memory/memory-bridge.js.map +1 -1
  125. package/dist/src/orgrt/broker.d.ts +24 -0
  126. package/dist/src/orgrt/broker.d.ts.map +1 -0
  127. package/dist/src/orgrt/broker.js +68 -0
  128. package/dist/src/orgrt/broker.js.map +1 -0
  129. package/dist/src/orgrt/daemon.d.ts +30 -0
  130. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  131. package/dist/src/orgrt/daemon.js +96 -7
  132. package/dist/src/orgrt/daemon.js.map +1 -1
  133. package/dist/src/orgrt/forwarder.d.ts +10 -5
  134. package/dist/src/orgrt/forwarder.d.ts.map +1 -1
  135. package/dist/src/orgrt/forwarder.js +105 -8
  136. package/dist/src/orgrt/forwarder.js.map +1 -1
  137. package/dist/src/orgrt/live.html +56 -0
  138. package/dist/src/orgrt/provider.d.ts.map +1 -1
  139. package/dist/src/orgrt/provider.js +1 -0
  140. package/dist/src/orgrt/provider.js.map +1 -1
  141. package/dist/src/orgrt/scheduler.d.ts +13 -0
  142. package/dist/src/orgrt/scheduler.d.ts.map +1 -0
  143. package/dist/src/orgrt/scheduler.js +48 -0
  144. package/dist/src/orgrt/scheduler.js.map +1 -0
  145. package/dist/src/orgrt/server.d.ts +8 -0
  146. package/dist/src/orgrt/server.d.ts.map +1 -0
  147. package/dist/src/orgrt/server.js +72 -0
  148. package/dist/src/orgrt/server.js.map +1 -0
  149. package/dist/src/orgrt/test-loop.d.ts +12 -0
  150. package/dist/src/orgrt/test-loop.d.ts.map +1 -0
  151. package/dist/src/orgrt/test-loop.js +108 -0
  152. package/dist/src/orgrt/test-loop.js.map +1 -0
  153. package/dist/src/output.d.ts.map +1 -1
  154. package/dist/src/output.js +12 -5
  155. package/dist/src/output.js.map +1 -1
  156. package/dist/src/parser.d.ts +32 -0
  157. package/dist/src/parser.d.ts.map +1 -1
  158. package/dist/src/parser.js +130 -5
  159. package/dist/src/parser.js.map +1 -1
  160. package/dist/src/routing/embed-worker.js +13 -1
  161. package/dist/src/routing/embed-worker.js.map +1 -1
  162. package/dist/src/routing/route-layer-factory.d.ts.map +1 -1
  163. package/dist/src/routing/route-layer-factory.js +31 -0
  164. package/dist/src/routing/route-layer-factory.js.map +1 -1
  165. package/dist/src/services/config-file-manager.d.ts +21 -0
  166. package/dist/src/services/config-file-manager.d.ts.map +1 -1
  167. package/dist/src/services/config-file-manager.js +60 -7
  168. package/dist/src/services/config-file-manager.js.map +1 -1
  169. package/dist/src/services/crash-reporter.d.ts.map +1 -1
  170. package/dist/src/services/crash-reporter.js +2 -1
  171. package/dist/src/services/crash-reporter.js.map +1 -1
  172. package/dist/src/ui/dashboard.html +40 -40
  173. package/dist/src/ui/orgs.html +110 -11
  174. package/dist/src/ui/server.mjs +304 -133
  175. package/dist/src/utils/input-guards.d.ts +9 -0
  176. package/dist/src/utils/input-guards.d.ts.map +1 -1
  177. package/dist/src/utils/input-guards.js +39 -5
  178. package/dist/src/utils/input-guards.js.map +1 -1
  179. package/dist/tsconfig.tsbuildinfo +1 -1
  180. package/package.json +6 -2
@@ -4448,9 +4448,9 @@ function appendChatViewEvent(ev, animate) {
4448
4448
  const atBottom = !animate || (feed.scrollHeight - feed.scrollTop - feed.clientHeight < 80);
4449
4449
  const ts = ev.ts ? new Date(ev.ts).toLocaleTimeString([],{hour:'2-digit',minute:'2-digit',second:'2-digit'}) : '';
4450
4450
  if (ev.type === 'run:start') {
4451
- el = mkCVSys('▶ Run started' + (ev.goal ? ': ' + esc(ev.goal.slice(0,80)) : '') + (ev.bossRole ? ' · boss: ' + esc(ev.bossRole) : ''), ts);
4451
+ el = mkCVSys('▶ Run started' + (ev.goal ? ': ' + (ev.goal.slice(0,80)) : '') + (ev.bossRole ? ' · boss: ' + (ev.bossRole) : ''), ts);
4452
4452
  } else if (ev.type === 'run:cycle:complete') {
4453
- el = mkCVSys('◎ Cycle complete' + (ev.pending != null ? ' · ' + esc(String(ev.pending)) + ' tasks pending' : ''), ts);
4453
+ el = mkCVSys('◎ Cycle complete' + (ev.pending != null ? ' · ' + (String(ev.pending)) + ' tasks pending' : ''), ts);
4454
4454
  } else if (ev.type === 'intercom') {
4455
4455
  el = mkCVIntercom(ev.from, ev.to, ev.msg || '', ts);
4456
4456
  } else if (ev.type === 'org:comms') {
@@ -4459,15 +4459,15 @@ function appendChatViewEvent(ev, animate) {
4459
4459
  if (ev.to && ev.to !== 'all') el = mkCVIntercom(_cvCommsFrom, ev.to, ev.msg || '', ts);
4460
4460
  else el = mkCVAgent(_cvCommsFrom, ev.msg || '', ts, 'org:comms');
4461
4461
  } else if (ev.type === 'org:agent:online') {
4462
- el = mkCVSys('[' + esc(ev.org || '') + '] ' + esc(ev.role || ev.title || '?') + ' online' + (ev.title && ev.role && ev.title !== ev.role ? ' (' + esc(ev.title) + ')' : ''), ts);
4462
+ el = mkCVSys('[' + (ev.org || '') + '] ' + (ev.role || ev.title || '?') + ' online' + (ev.title && ev.role && ev.title !== ev.role ? ' (' + (ev.title) + ')' : ''), ts);
4463
4463
  } else if (ev.type === 'org:checkpoint') {
4464
- el = mkCVSys('[checkpoint] ' + esc(ev.summary || ev.progress || ev.msg || ''), ts);
4464
+ el = mkCVSys('[checkpoint] ' + (ev.summary || ev.progress || ev.msg || ''), ts);
4465
4465
  } else if (ev.type === 'org:start') {
4466
- el = mkCVSys('[org:start] ' + esc(ev.org || ''), ts);
4466
+ el = mkCVSys('[org:start] ' + (ev.org || ''), ts);
4467
4467
  } else if (ev.type === 'run:complete') {
4468
- el = mkCVSys('■ Run complete' + (ev.status ? ' [' + esc(ev.status) + ']' : ''), ts);
4468
+ el = mkCVSys('■ Run complete' + (ev.status ? ' [' + (ev.status) + ']' : ''), ts);
4469
4469
  } else if (ev.type === 'org:complete') {
4470
- el = mkCVSys('■ Org complete' + (ev.org ? ' — ' + esc(ev.org) : ''), ts);
4470
+ el = mkCVSys('■ Org complete' + (ev.org ? ' — ' + (ev.org) : ''), ts);
4471
4471
  } else if (ev.type === 'agent:result') {
4472
4472
  el = mkCVResult(ev.agent || ev.from || '?', ev.result || ev.msg || ev.message || ev.summary || '', ts);
4473
4473
  } else if (ev.type === 'agent:spawn') {
@@ -4487,36 +4487,36 @@ function appendChatViewEvent(ev, animate) {
4487
4487
  const _auAgent = ev.role || ev.agentType || '?';
4488
4488
  const _auCost = ev.cost_usd != null ? '$' + Number(ev.cost_usd).toFixed(4) : '';
4489
4489
  const _auTok = (ev.tokens_in || ev.tokens_out) ? ((ev.tokens_in||0)).toLocaleString() + '↑ ' + ((ev.tokens_out||0)).toLocaleString() + '↓' : '';
4490
- el = mkCVSys('◈ ' + esc(_auAgent) + (_auTok ? ' · ' + _auTok : '') + (_auCost ? ' · ' + _auCost : ''), ts);
4490
+ el = mkCVSys('◈ ' + (_auAgent) + (_auTok ? ' · ' + _auTok : '') + (_auCost ? ' · ' + _auCost : ''), ts);
4491
4491
  } else if (ev.type === 'agent:message') {
4492
4492
  el = mkCVAgent(ev.agent || ev.name || ev.role || '?', ev.msg || ev.message || ev.content || '', ts, ev.type);
4493
4493
  } else if (ev.type === 'session:start') {
4494
- el = mkCVSys('Session started' + (ev.prompt ? ': ' + esc(ev.prompt.slice(0,80)) : ''), ts);
4494
+ el = mkCVSys('Session started' + (ev.prompt ? ': ' + (ev.prompt.slice(0,80)) : ''), ts);
4495
4495
  } else if (ev.type === 'session:complete') {
4496
- el = mkCVSys('Session complete' + (ev.status ? ' — ' + esc(ev.status) : ''), ts);
4496
+ el = mkCVSys('Session complete' + (ev.status ? ' — ' + (ev.status) : ''), ts);
4497
4497
  } else if (ev.type === 'domain:dispatch') {
4498
- el = mkCVSys('→ ' + esc(ev.domain || '') + (ev.cmd ? ': ' + esc(ev.cmd.slice(0,80)) : ''), ts);
4498
+ el = mkCVSys('→ ' + (ev.domain || '') + (ev.cmd ? ': ' + (ev.cmd.slice(0,80)) : ''), ts);
4499
4499
  } else if (ev.type === 'domain:complete') {
4500
- el = mkCVSys('✓ ' + esc(ev.domain || '') + (ev.status ? ' [' + esc(ev.status) + ']' : ''), ts);
4500
+ el = mkCVSys('✓ ' + (ev.domain || '') + (ev.status ? ' [' + (ev.status) + ']' : ''), ts);
4501
4501
  } else if (ev.type === 'loop:start') {
4502
- el = mkCVSys('◎ Loop: ' + esc(ev.command || '') + (ev.repeat ? ' ×' + esc(String(ev.repeat)) : ''), ts);
4502
+ el = mkCVSys('◎ Loop: ' + (ev.command || '') + (ev.repeat ? ' ×' + (String(ev.repeat)) : ''), ts);
4503
4503
  if (currentView === 'loops') renderLoops();
4504
4504
  } else if (ev.type === 'loop:complete') {
4505
- el = mkCVSys('■ Loop done: ' + esc(ev.command || '') + (ev.ranReps ? ' (' + esc(String(ev.ranReps)) + ' runs)' : ''), ts);
4505
+ el = mkCVSys('■ Loop done: ' + (ev.command || '') + (ev.ranReps ? ' (' + (String(ev.ranReps)) + ' runs)' : ''), ts);
4506
4506
  if (currentView === 'loops') renderLoops();
4507
4507
  } else if (ev.type === 'loop:tick') {
4508
4508
  const _tickLbl = ev.rep != null
4509
- ? 'rep ' + esc(String(ev.rep)) + ' done' + (ev.wait != null ? ' → next in ' + esc(String(ev.wait)) + 's' : '')
4510
- : esc(ev.command || ev.loopId || ev.id || '');
4509
+ ? 'rep ' + (String(ev.rep)) + ' done' + (ev.wait != null ? ' → next in ' + (String(ev.wait)) + 's' : '')
4510
+ : (ev.command || ev.loopId || ev.id || '');
4511
4511
  el = mkCVSys('◷ ' + _tickLbl, ts);
4512
4512
  el.dataset.evType = 'loop:tick';
4513
4513
  if (feed.lastElementChild?.dataset?.evType === 'loop:tick') feed.lastElementChild.remove();
4514
4514
  if (currentView === 'loops') renderLoops();
4515
4515
  } else if (ev.type === 'loop:hil' || ev.type === 'loop:hil:waiting') {
4516
- el = mkCVSys('⚠ Loop HIL: ' + esc(ev.command || ev.loopId || ev.id || ''), ts);
4516
+ el = mkCVSys('⚠ Loop HIL: ' + (ev.command || ev.loopId || ev.id || ''), ts);
4517
4517
  if (currentView === 'loops') renderLoops();
4518
4518
  } else if (ev.type === 'loop:hil:resolved') {
4519
- el = mkCVSys('✓ Loop HIL resolved: ' + esc(ev.loopId || ev.command || ''), ts);
4519
+ el = mkCVSys('✓ Loop HIL resolved: ' + (ev.loopId || ev.command || ''), ts);
4520
4520
  if (currentView === 'loops') renderLoops();
4521
4521
  } else if (ev.type === 'file:write') {
4522
4522
  el = mkCVFileCard(ev.name || ev.path || '?', ev.path || '', ev.size || 0, ts);
@@ -4527,12 +4527,12 @@ function appendChatViewEvent(ev, animate) {
4527
4527
  } else if (ev.type === 'agent:browse') {
4528
4528
  el = mkCVTool('BROWSE', ev.payload || ev.url || '', '', 'oklch(65% 0.15 190)', ts);
4529
4529
  } else if (ev.type === 'org:agent:offline') {
4530
- el = mkCVSys('◌ ' + esc(ev.title || ev.role || '?') + ' offline' + (ev.org ? ' [' + esc(ev.org) + ']' : ''), ts);
4530
+ el = mkCVSys('◌ ' + (ev.title || ev.role || '?') + ' offline' + (ev.org ? ' [' + (ev.org) + ']' : ''), ts);
4531
4531
  } else if (ev.type === 'org:error') {
4532
- el = mkCVSys('⚠ Error: ' + esc(ev.msg || ev.error || ev.message || ''), ts);
4532
+ el = mkCVSys('⚠ Error: ' + (ev.msg || ev.error || ev.message || ''), ts);
4533
4533
  el.classList.add('cv-err');
4534
4534
  } else {
4535
- el = mkCVSys(esc(ev.type || 'event'), ts);
4535
+ el = mkCVSys((ev.type || 'event'), ts);
4536
4536
  }
4537
4537
  if (animate) el.classList.add('cv-new');
4538
4538
  feed.appendChild(el);
@@ -4671,10 +4671,10 @@ function mkCVTool(tag, cmd, output, color, ts) {
4671
4671
  return d;
4672
4672
  }
4673
4673
 
4674
- function mkCVSys(html, ts) {
4674
+ function mkCVSys(text, ts) {
4675
4675
  const d = document.createElement('div');
4676
4676
  d.className = 'cv-msg cv-sys';
4677
- d.innerHTML = `<div class="cv-bub"><span class="cv-etype">SYS</span><span class="cv-text">${html}</span><span class="cv-ts">${ts}</span></div>`;
4677
+ 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
4678
  return d;
4679
4679
  }
4680
4680
 
@@ -8014,18 +8014,18 @@ function _odtAppendEvent(ev, animate) {
8014
8014
  const ts = ev.ts ? new Date(ev.ts).toLocaleTimeString([],{hour:'2-digit',minute:'2-digit',second:'2-digit'}) : '';
8015
8015
  let el;
8016
8016
  if (ev.type === 'run:start') {
8017
- el = mkCVSys('▶ Run started' + (ev.goal ? ': ' + esc(ev.goal.slice(0,80)) : '') + (ev.bossRole ? ' · boss: ' + esc(ev.bossRole) : ''), ts);
8017
+ el = mkCVSys('▶ Run started' + (ev.goal ? ': ' + (ev.goal.slice(0,80)) : '') + (ev.bossRole ? ' · boss: ' + (ev.bossRole) : ''), ts);
8018
8018
  } else if (ev.type === 'run:cycle:complete') {
8019
- el = mkCVSys('◎ Cycle complete' + (ev.pending != null ? ' · ' + esc(String(ev.pending)) + ' tasks pending' : ''), ts);
8019
+ el = mkCVSys('◎ Cycle complete' + (ev.pending != null ? ' · ' + (String(ev.pending)) + ' tasks pending' : ''), ts);
8020
8020
  } else if (ev.type === 'run:complete') {
8021
- el = mkCVSys('■ Run complete' + (ev.status ? ' [' + esc(ev.status) + ']' : ''), ts);
8021
+ el = mkCVSys('■ Run complete' + (ev.status ? ' [' + (ev.status) + ']' : ''), ts);
8022
8022
  } else if (ev.type === 'org:comms') {
8023
8023
  // Some older runs use ev.role instead of ev.from — normalise before rendering
8024
8024
  const _commsFrom = ev.from || ev.role || 'boss';
8025
8025
  if (ev.to && ev.to !== 'all') el = mkCVIntercom(_commsFrom, ev.to, ev.msg || '', ts);
8026
8026
  else el = mkCVAgent(_commsFrom, ev.msg || '', ts, 'org:comms');
8027
8027
  } else if (ev.type === 'org:agent:online') {
8028
- el = mkCVSys('◉ ' + esc(ev.title || ev.role || '?') + ' online', ts);
8028
+ el = mkCVSys('◉ ' + (ev.title || ev.role || '?') + ' online', ts);
8029
8029
  } else if (ev.type === 'org:checkpoint') {
8030
8030
  el = mkCVAgent('boss', ev.summary || ev.progress || ev.msg || '', ts, 'org:checkpoint');
8031
8031
  } else if (ev.type === 'org:start' || ev.type === 'org:complete') {
@@ -8041,32 +8041,32 @@ function _odtAppendEvent(ev, animate) {
8041
8041
  } else if (ev.type === 'agent:message') {
8042
8042
  el = mkCVAgent(ev.agent || ev.name || ev.role || '?', ev.msg || ev.message || ev.content || '', ts, ev.type);
8043
8043
  } else if (ev.type === 'session:start') {
8044
- el = mkCVSys('▶ ' + esc((ev.prompt || '').replace(/^running org:\s*/i,'').slice(0,80) || 'Session started'), ts);
8044
+ el = mkCVSys('▶ ' + ((ev.prompt || '').replace(/^running org:\s*/i,'').slice(0,80) || 'Session started'), ts);
8045
8045
  } else if (ev.type === 'session:complete') {
8046
- el = mkCVSys('■ Complete' + (ev.status ? ' — ' + esc(ev.status) : ''), ts);
8046
+ el = mkCVSys('■ Complete' + (ev.status ? ' — ' + (ev.status) : ''), ts);
8047
8047
  } else if (ev.type === 'domain:dispatch') {
8048
- el = mkCVSys('→ ' + esc(ev.domain || '') + (ev.cmd ? ': ' + esc(ev.cmd.slice(0,80)) : ''), ts);
8048
+ el = mkCVSys('→ ' + (ev.domain || '') + (ev.cmd ? ': ' + (ev.cmd.slice(0,80)) : ''), ts);
8049
8049
  } else if (ev.type === 'domain:complete') {
8050
- el = mkCVSys('✓ ' + esc(ev.domain || '') + (ev.status ? ' [' + esc(ev.status) + ']' : ''), ts);
8050
+ el = mkCVSys('✓ ' + (ev.domain || '') + (ev.status ? ' [' + (ev.status) + ']' : ''), ts);
8051
8051
  } else if (ev.type === 'loop:start') {
8052
- el = mkCVSys('Loop: ' + esc(ev.command || ''), ts);
8052
+ el = mkCVSys('Loop: ' + (ev.command || ''), ts);
8053
8053
  } else if (ev.type === 'loop:complete') {
8054
- el = mkCVSys('Loop done: ' + esc(ev.command || '') + (ev.ranReps ? ' (' + ev.ranReps + ' runs)' : ''), ts);
8054
+ el = mkCVSys('Loop done: ' + (ev.command || '') + (ev.ranReps ? ' (' + ev.ranReps + ' runs)' : ''), ts);
8055
8055
  } else if (ev.type === 'loop:tick') {
8056
8056
  const _trep = ev.rep ?? ev.fromRep;
8057
8057
  const _tnext = ev.nextRep ?? ev.toRep;
8058
8058
  const tickLabel = _trep != null
8059
- ? 'rep ' + esc(String(_trep)) + ' done' + (_tnext != null ? ' → rep ' + esc(String(_tnext)) + (ev.wait != null ? ' in ' + esc(String(ev.wait)) + 's' : '') : '')
8060
- : esc(ev.command || ev.loopId || '');
8059
+ ? 'rep ' + (String(_trep)) + ' done' + (_tnext != null ? ' → rep ' + (String(_tnext)) + (ev.wait != null ? ' in ' + (String(ev.wait)) + 's' : '') : '')
8060
+ : (ev.command || ev.loopId || '');
8061
8061
  el = mkCVSys('◷ ' + tickLabel, ts);
8062
8062
  el.dataset.evType = 'loop:tick';
8063
8063
  // Collapse: replace the previous loop:tick if it's the last element — prevents the
8064
8064
  // feed from flooding with one entry per rep in long-running loops (e.g. --repeat 9999).
8065
8065
  if (feed.lastElementChild?.dataset?.evType === 'loop:tick') feed.lastElementChild.remove();
8066
8066
  } else if (ev.type === 'loop:hil' || ev.type === 'loop:hil:waiting') {
8067
- el = mkCVSys('⚠ Loop HIL: ' + esc(ev.command || ev.loopId || ''), ts);
8067
+ el = mkCVSys('⚠ Loop HIL: ' + (ev.command || ev.loopId || ''), ts);
8068
8068
  } else if (ev.type === 'loop:hil:resolved') {
8069
- el = mkCVSys('✓ Loop HIL resolved: ' + esc(ev.loopId || ''), ts);
8069
+ el = mkCVSys('✓ Loop HIL resolved: ' + (ev.loopId || ''), ts);
8070
8070
  } else if (ev.type === 'agent:edit' || ev.type === 'agent:write') {
8071
8071
  el = mkCVTool('EDIT', ev.payload || ev.file || ev.path || '', '', 'oklch(65% 0.20 270)', ts);
8072
8072
  } else if (ev.type === 'agent:bash') {
@@ -8074,15 +8074,15 @@ function _odtAppendEvent(ev, animate) {
8074
8074
  } else if (ev.type === 'agent:browse') {
8075
8075
  el = mkCVTool('BROWSE', ev.payload || ev.url || '', '', 'oklch(65% 0.15 190)', ts);
8076
8076
  } else if (ev.type === 'org:error') {
8077
- el = mkCVSys('⚠ Error: ' + esc(ev.msg || ev.error || ev.message || ''), ts);
8077
+ el = mkCVSys('⚠ Error: ' + (ev.msg || ev.error || ev.message || ''), ts);
8078
8078
  el.classList.add('cv-err');
8079
8079
  } else if (ev.type === 'org:agent:offline') {
8080
- el = mkCVSys('◌ ' + esc(ev.title || ev.role || '?') + ' offline', ts);
8080
+ el = mkCVSys('◌ ' + (ev.title || ev.role || '?') + ' offline', ts);
8081
8081
  } else if (ev.type === 'user:message') {
8082
8082
  el = mkCVAgent('you', ev.text || ev.msg || ev.message || '', ts, 'user:message');
8083
8083
  el.classList.add('cv-user-msg');
8084
8084
  } else {
8085
- el = mkCVSys(esc(ev.type || 'event'), ts);
8085
+ el = mkCVSys((ev.type || 'event'), ts);
8086
8086
  }
8087
8087
  if (animate) el.classList.add('cv-new');
8088
8088
  feed.appendChild(el);
@@ -383,6 +383,37 @@ html, body {
383
383
  content: '—'; color: oklch(36% 0.008 186 / 0.5); flex-shrink: 0; margin-top: 1px;
384
384
  }
385
385
 
386
+ /* ── Files tab ──────────────────────────────────────────────────── */
387
+ #files-pane { padding: 20px; }
388
+ .files-grid {
389
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
390
+ gap: 10px;
391
+ }
392
+ .file-card {
393
+ background: var(--bg-panel);
394
+ border: 1px solid var(--border); border-radius: 3px;
395
+ padding: 10px 12px;
396
+ display: flex; align-items: center; gap: 10px;
397
+ transition: border-color 0.12s;
398
+ }
399
+ .file-card:hover { border-color: var(--teal-dim); }
400
+ .fc-icon { font-size: 18px; flex-shrink: 0; }
401
+ .fc-body { flex: 1; min-width: 0; }
402
+ .fc-name {
403
+ font-size: 12px; color: var(--text); font-weight: 500;
404
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
405
+ }
406
+ .fc-meta {
407
+ font-size: 9px; color: var(--dim); margin-top: 2px;
408
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
409
+ }
410
+ .fc-view {
411
+ flex-shrink: 0; background: #1a3a5a; color: #5d9fd9; border: 1px solid #2980b944;
412
+ border-radius: 4px; padding: 4px 10px; font-size: 10px; font-weight: 700; cursor: pointer;
413
+ }
414
+ .fc-view:hover { background: #204a70; }
415
+ .fc-binary { flex-shrink: 0; font-size: 9px; color: var(--dim); }
416
+
386
417
  /* ── Activity / event log ───────────────────────────────────────── */
387
418
  #activity-pane { padding: 20px; }
388
419
  #activity-log { display: flex; flex-direction: column; gap: 0; }
@@ -819,6 +850,7 @@ html, body {
819
850
  <button class="tab-btn" onclick="switchTab('roles')">ROLES</button>
820
851
  <button class="tab-btn" onclick="switchTab('activity')">ACTIVITY</button>
821
852
  <button class="tab-btn" onclick="switchTab('health')">HEALTH</button>
853
+ <button class="tab-btn" onclick="switchTab('files')">FILES</button>
822
854
  <button class="tab-btn" onclick="switchTab('chat')">CHAT</button>
823
855
  </div>
824
856
 
@@ -937,6 +969,14 @@ html, body {
937
969
  </div>
938
970
  </div>
939
971
 
972
+ <!-- Files tab: every asset any agent in this org has produced, across all runs -->
973
+ <div class="tab-pane" id="tab-files">
974
+ <div id="files-pane">
975
+ <div id="files-empty" class="act-empty" style="display:none">No files produced yet.</div>
976
+ <div id="files-grid" class="files-grid"></div>
977
+ </div>
978
+ </div>
979
+
940
980
  <!-- Chat tab -->
941
981
  <div class="tab-pane" id="tab-chat">
942
982
  <div id="chat-pane">
@@ -1081,9 +1121,61 @@ window.switchTab = function(tab) {
1081
1121
  const mainBody = document.getElementById('main-body');
1082
1122
  if (mainBody) mainBody.classList.toggle('chat-active', tab === 'chat');
1083
1123
  if (tab === 'chat') renderChatTab();
1124
+ else if (tab === 'files') renderFilesTab();
1084
1125
  else if (orgDetailData) renderTab(tab);
1085
1126
  };
1086
1127
 
1128
+ // ── Files tab: every asset produced by this org, deduped by path, latest first ──
1129
+ function collectOrgArtifacts() {
1130
+ const bySessions = chatSessions.filter(orgSessionMatch);
1131
+ const seen = new Map(); // path -> { art, ts, from }
1132
+ bySessions.forEach(s => (s.events || []).forEach(ev => {
1133
+ if (ev.type !== 'org:artifact') return;
1134
+ const art = ev.artifact || (ev.path ? { path: ev.path, label: ev.label, mimeType: ev.mimeType } : null);
1135
+ if (!art || !art.path) return;
1136
+ const prev = seen.get(art.path);
1137
+ if (!prev || (ev.ts || 0) >= prev.ts) seen.set(art.path, { art, ts: ev.ts || 0, from: ev.from || '' });
1138
+ }));
1139
+ return Array.from(seen.values()).sort((a, b) => b.ts - a.ts);
1140
+ }
1141
+
1142
+ function mkFileCard(entry) {
1143
+ const { art, ts, from } = entry;
1144
+ const el = document.createElement('div');
1145
+ el.className = 'file-card';
1146
+ const isText = (art.mimeType || '').startsWith('text/') || (art.mimeType || '') === 'application/json';
1147
+ const labelRaw = art.label || (art.path || 'file').split('/').pop();
1148
+ const timeStr = ts ? new Date(ts).toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }) : '';
1149
+ const meta = [from, art.path ? art.path.split('/').slice(-3).join('/') : null, timeStr].filter(Boolean).join(' · ');
1150
+ el.innerHTML = `
1151
+ <div class="fc-icon">📄</div>
1152
+ <div class="fc-body">
1153
+ <div class="fc-name">${esc(labelRaw)}</div>
1154
+ <div class="fc-meta">${esc(meta)}</div>
1155
+ </div>
1156
+ ${isText && art.path
1157
+ ? `<button class="fc-view" onclick="viewArtifact(${JSON.stringify(art.path)},${JSON.stringify(labelRaw)})">View</button>`
1158
+ : `<span class="fc-binary">Binary</span>`}
1159
+ `;
1160
+ return el;
1161
+ }
1162
+
1163
+ function paintFilesGrid() {
1164
+ const grid = document.getElementById('files-grid');
1165
+ const empty = document.getElementById('files-empty');
1166
+ if (!grid) return;
1167
+ const files = collectOrgArtifacts();
1168
+ grid.innerHTML = '';
1169
+ if (!files.length) { if (empty) empty.style.display = 'block'; return; }
1170
+ if (empty) empty.style.display = 'none';
1171
+ files.forEach(entry => grid.appendChild(mkFileCard(entry)));
1172
+ }
1173
+
1174
+ function renderFilesTab() {
1175
+ paintFilesGrid(); // paint immediately with whatever's cached
1176
+ loadChatSessions().then(() => { if (currentTab === 'files') paintFilesGrid(); });
1177
+ }
1178
+
1087
1179
  // ── Render all orgs in sidebar ────────────────────────────────────
1088
1180
  function renderSidebar() {
1089
1181
  const list = document.getElementById('sb-list');
@@ -1689,8 +1781,13 @@ function orgSessionMatch(s) {
1689
1781
  const orgLc = selectedOrg.toLowerCase();
1690
1782
  const prompt = (s.prompt || '').toLowerCase();
1691
1783
  if (prompt.includes('running org: ' + orgLc) || prompt.includes('org: ' + orgLc)) return true;
1692
- // Also check events for an org field
1693
- return (s.events || []).some(ev => (ev.org || '').toLowerCase() === orgLc);
1784
+ // Only genuine org-run events (org:comms, org:artifact, org:start, ...) count.
1785
+ // agent:bash / agent:edit / etc. also carry an `org` field (ambient "which
1786
+ // org was active while this Claude Code session ran" tagging) — matching on
1787
+ // those too would pull an unrelated dev session's entire tool-call history
1788
+ // into this org's Chat/Files tabs whenever that org happened to be running
1789
+ // at the same time.
1790
+ return (s.events || []).some(ev => (ev.type || '').startsWith('org:') && (ev.org || '').toLowerCase() === orgLc);
1694
1791
  }
1695
1792
 
1696
1793
  function populateChatSelect() {
@@ -1834,21 +1931,21 @@ function appendChatEvent(ev, animate) {
1834
1931
  } else if (ev.type === 'agent:spawn') {
1835
1932
  const col = dc(ev.domain);
1836
1933
  const name = ev.agentType || ev.from || ev.agent || 'agent';
1837
- el = mkAgent(name, `spawned: ${esc(ev.task||'task')}`, ts, col, 'spawn');
1934
+ el = mkAgent(name, `spawned: ${ev.task||'task'}`, ts, col, 'spawn');
1838
1935
  } else if (ev.type === 'agent:complete') {
1839
1936
  const name = ev.agentType || ev.role || ev.from || 'agent';
1840
1937
  const result = (ev.result || '').slice(0, 300);
1841
1938
  const cost = ev.cost_usd ? ` · $${parseFloat(ev.cost_usd).toFixed(4)}` : '';
1842
1939
  const tools = ev.toolCalls?.length ? ` · ${ev.toolCalls.slice(0,4).join(', ')}` : '';
1843
- el = mkAgent(name, `${esc(result) || 'done'}${esc(tools)}${esc(cost)}`, ts, dc(ev.domain), 'complete');
1940
+ el = mkAgent(name, `${result || 'done'}${tools}${cost}`, ts, dc(ev.domain), 'complete');
1844
1941
  } else if (ev.type === 'org:comms') {
1845
- el = mkIntercom(ev.from || 'boss', ev.to || 'agent', esc(ev.msg || ev.message || ''), ts);
1942
+ el = mkIntercom(ev.from || 'boss', ev.to || 'agent', ev.msg || ev.message || '', ts);
1846
1943
  } else if (ev.type === 'agent:message') {
1847
- el = mkAgent(ev.agent||'agent', esc(ev.text||''), ts, dc(ev.domain), null);
1944
+ el = mkAgent(ev.agent||'agent', ev.text||'', ts, dc(ev.domain), null);
1848
1945
  } else if (ev.type === 'intercom') {
1849
- el = mkIntercom(ev.from, ev.to, esc(ev.msg||''), ts);
1946
+ el = mkIntercom(ev.from, ev.to, ev.msg||'', ts);
1850
1947
  } else if (ev.type === 'user:message') {
1851
- el = mkUser(esc(ev.text||ev.msg||''), ts);
1948
+ el = mkUser(ev.text||ev.msg||'', ts);
1852
1949
  } else if (ev.type === 'loop:start') {
1853
1950
  el = mkSys(`🔁 Loop: ${esc(ev.command||'')} (${ev.repeat||'?'} runs)`, ts);
1854
1951
  } else if (ev.type === 'loop:complete') {
@@ -1876,13 +1973,13 @@ function mkAgent(name, text, ts, color, typeTag) {
1876
1973
  el.className = 'cmsg cagent';
1877
1974
  const tagStyle = color ? `style="border-color:${color}44;color:${color}"` : '';
1878
1975
  const ttag = typeTag ? `<span class="cevtype">${esc(typeTag)}</span>` : '';
1879
- el.innerHTML = `<div class="cmsg-meta"><span class="ctag" ${tagStyle}>${esc(name)}</span>${ttag}<span class="cts">${ts}</span></div><div class="cbubble">${text}</div>`;
1976
+ el.innerHTML = `<div class="cmsg-meta"><span class="ctag" ${tagStyle}>${esc(name)}</span>${ttag}<span class="cts">${ts}</span></div><div class="cbubble">${esc(text)}</div>`;
1880
1977
  return el;
1881
1978
  }
1882
1979
  function mkIntercom(from, to, text, ts) {
1883
1980
  const el = document.createElement('div');
1884
1981
  el.className = 'cmsg cic';
1885
- el.innerHTML = `<div class="cmsg-meta"><span class="ctag sender">${esc(from||'?')}</span><span class="cic-arrow">→</span><span class="ctag receiver">${esc(to||'?')}</span><span class="cevtype">intercom</span><span class="cts">${ts}</span></div><div class="cbubble">${text}</div>`;
1982
+ el.innerHTML = `<div class="cmsg-meta"><span class="ctag sender">${esc(from||'?')}</span><span class="cic-arrow">→</span><span class="ctag receiver">${esc(to||'?')}</span><span class="cevtype">intercom</span><span class="cts">${ts}</span></div><div class="cbubble">${esc(text)}</div>`;
1886
1983
  return el;
1887
1984
  }
1888
1985
  function mkArtifact(art, ts) {
@@ -1901,7 +1998,7 @@ function mkArtifact(art, ts) {
1901
1998
  function mkUser(text, ts) {
1902
1999
  const el = document.createElement('div');
1903
2000
  el.className = 'cmsg cuser';
1904
- el.innerHTML = `<div class="cmsg-meta" style="justify-content:flex-end"><span class="cts">${ts}</span><span class="ctag" style="border-color:oklch(68% 0.18 250 / 0.35);color:oklch(68% 0.14 250)">you</span></div><div class="cbubble">${text}</div>`;
2001
+ el.innerHTML = `<div class="cmsg-meta" style="justify-content:flex-end"><span class="cts">${ts}</span><span class="ctag" style="border-color:oklch(68% 0.18 250 / 0.35);color:oklch(68% 0.14 250)">you</span></div><div class="cbubble">${esc(text)}</div>`;
1905
2002
  return el;
1906
2003
  }
1907
2004
 
@@ -2042,6 +2139,8 @@ function handleMmEvent(ev) {
2042
2139
  appendChatEvent(ev, true);
2043
2140
  chatScrollFeed();
2044
2141
  }
2142
+ // Live-update the Files tab when a new asset lands while it's open
2143
+ if (ev.type === 'org:artifact' && currentTab === 'files') paintFilesGrid();
2045
2144
  }
2046
2145
  }
2047
2146