reflectt-node 0.1.4 β†’ 0.1.6

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 (160) hide show
  1. package/README.md +63 -146
  2. package/defaults/TEAM-ROLES.yaml +221 -31
  3. package/dist/activationEvents.d.ts +13 -2
  4. package/dist/activationEvents.d.ts.map +1 -1
  5. package/dist/activationEvents.js +172 -38
  6. package/dist/activationEvents.js.map +1 -1
  7. package/dist/activity.d.ts +72 -0
  8. package/dist/activity.d.ts.map +1 -0
  9. package/dist/activity.js +510 -0
  10. package/dist/activity.js.map +1 -0
  11. package/dist/alert-preflight.d.ts +33 -0
  12. package/dist/alert-preflight.d.ts.map +1 -1
  13. package/dist/alert-preflight.js +218 -2
  14. package/dist/alert-preflight.js.map +1 -1
  15. package/dist/assignment.d.ts.map +1 -1
  16. package/dist/assignment.js +11 -6
  17. package/dist/assignment.js.map +1 -1
  18. package/dist/boardHealthWorker.d.ts.map +1 -1
  19. package/dist/boardHealthWorker.js +25 -12
  20. package/dist/boardHealthWorker.js.map +1 -1
  21. package/dist/canvas-slots.d.ts +1 -1
  22. package/dist/channels.d.ts +1 -1
  23. package/dist/chat-approval-detector.d.ts.map +1 -1
  24. package/dist/chat-approval-detector.js +29 -11
  25. package/dist/chat-approval-detector.js.map +1 -1
  26. package/dist/chat.d.ts +14 -0
  27. package/dist/chat.d.ts.map +1 -1
  28. package/dist/chat.js +68 -4
  29. package/dist/chat.js.map +1 -1
  30. package/dist/cli.js +349 -28
  31. package/dist/cli.js.map +1 -1
  32. package/dist/cloud.d.ts +28 -1
  33. package/dist/cloud.d.ts.map +1 -1
  34. package/dist/cloud.js +62 -25
  35. package/dist/cloud.js.map +1 -1
  36. package/dist/compliance-detector.d.ts +42 -0
  37. package/dist/compliance-detector.d.ts.map +1 -0
  38. package/dist/compliance-detector.js +286 -0
  39. package/dist/compliance-detector.js.map +1 -0
  40. package/dist/continuity-loop.d.ts.map +1 -1
  41. package/dist/continuity-loop.js +7 -3
  42. package/dist/continuity-loop.js.map +1 -1
  43. package/dist/dashboard.d.ts +6 -2
  44. package/dist/dashboard.d.ts.map +1 -1
  45. package/dist/dashboard.js +84 -28
  46. package/dist/dashboard.js.map +1 -1
  47. package/dist/db.d.ts.map +1 -1
  48. package/dist/db.js +24 -1
  49. package/dist/db.js.map +1 -1
  50. package/dist/doctor.d.ts.map +1 -1
  51. package/dist/doctor.js +17 -6
  52. package/dist/doctor.js.map +1 -1
  53. package/dist/executionSweeper.d.ts +2 -0
  54. package/dist/executionSweeper.d.ts.map +1 -1
  55. package/dist/executionSweeper.js +60 -4
  56. package/dist/executionSweeper.js.map +1 -1
  57. package/dist/focus.d.ts +20 -0
  58. package/dist/focus.d.ts.map +1 -0
  59. package/dist/focus.js +57 -0
  60. package/dist/focus.js.map +1 -0
  61. package/dist/health.d.ts +1 -0
  62. package/dist/health.d.ts.map +1 -1
  63. package/dist/health.js +47 -15
  64. package/dist/health.js.map +1 -1
  65. package/dist/hostConnectGuard.d.ts +25 -0
  66. package/dist/hostConnectGuard.d.ts.map +1 -0
  67. package/dist/hostConnectGuard.js +27 -0
  68. package/dist/hostConnectGuard.js.map +1 -0
  69. package/dist/index.js +257 -39
  70. package/dist/index.js.map +1 -1
  71. package/dist/insight-mutation.d.ts +26 -0
  72. package/dist/insight-mutation.d.ts.map +1 -1
  73. package/dist/insight-mutation.js +103 -12
  74. package/dist/insight-mutation.js.map +1 -1
  75. package/dist/insight-task-bridge.d.ts +1 -1
  76. package/dist/insight-task-bridge.d.ts.map +1 -1
  77. package/dist/insight-task-bridge.js +6 -3
  78. package/dist/insight-task-bridge.js.map +1 -1
  79. package/dist/insights.d.ts +20 -0
  80. package/dist/insights.d.ts.map +1 -1
  81. package/dist/insights.js +129 -4
  82. package/dist/insights.js.map +1 -1
  83. package/dist/mcp.d.ts.map +1 -1
  84. package/dist/mcp.js +9 -8
  85. package/dist/mcp.js.map +1 -1
  86. package/dist/notificationDedupeGuard.d.ts +33 -0
  87. package/dist/notificationDedupeGuard.d.ts.map +1 -0
  88. package/dist/notificationDedupeGuard.js +88 -0
  89. package/dist/notificationDedupeGuard.js.map +1 -0
  90. package/dist/openclaw.d.ts.map +1 -1
  91. package/dist/openclaw.js +3 -2
  92. package/dist/openclaw.js.map +1 -1
  93. package/dist/policy.d.ts +1 -1
  94. package/dist/policy.d.ts.map +1 -1
  95. package/dist/policy.js +3 -1
  96. package/dist/policy.js.map +1 -1
  97. package/dist/prAutoMerge.d.ts.map +1 -1
  98. package/dist/prAutoMerge.js +23 -0
  99. package/dist/prAutoMerge.js.map +1 -1
  100. package/dist/presence.d.ts +16 -1
  101. package/dist/presence.d.ts.map +1 -1
  102. package/dist/presence.js +97 -9
  103. package/dist/presence.js.map +1 -1
  104. package/dist/pulse.d.ts +60 -0
  105. package/dist/pulse.d.ts.map +1 -0
  106. package/dist/pulse.js +139 -0
  107. package/dist/pulse.js.map +1 -0
  108. package/dist/reflection-automation.d.ts.map +1 -1
  109. package/dist/reflection-automation.js +38 -0
  110. package/dist/reflection-automation.js.map +1 -1
  111. package/dist/release.d.ts +2 -0
  112. package/dist/release.d.ts.map +1 -1
  113. package/dist/release.js +14 -1
  114. package/dist/release.js.map +1 -1
  115. package/dist/request-tracker.d.ts +6 -0
  116. package/dist/request-tracker.d.ts.map +1 -1
  117. package/dist/request-tracker.js +31 -12
  118. package/dist/request-tracker.js.map +1 -1
  119. package/dist/scopeOverlap.d.ts +32 -0
  120. package/dist/scopeOverlap.d.ts.map +1 -0
  121. package/dist/scopeOverlap.js +219 -0
  122. package/dist/scopeOverlap.js.map +1 -0
  123. package/dist/server.d.ts.map +1 -1
  124. package/dist/server.js +736 -117
  125. package/dist/server.js.map +1 -1
  126. package/dist/service-probe.d.ts.map +1 -1
  127. package/dist/service-probe.js +39 -2
  128. package/dist/service-probe.js.map +1 -1
  129. package/dist/shipped-heartbeat.d.ts +1 -1
  130. package/dist/shipped-heartbeat.js +1 -1
  131. package/dist/taskPrecheck.js +6 -6
  132. package/dist/taskPrecheck.js.map +1 -1
  133. package/dist/tasks-next-diagnostics.d.ts +15 -0
  134. package/dist/tasks-next-diagnostics.d.ts.map +1 -0
  135. package/dist/tasks-next-diagnostics.js +33 -0
  136. package/dist/tasks-next-diagnostics.js.map +1 -0
  137. package/dist/tasks.d.ts +3 -2
  138. package/dist/tasks.d.ts.map +1 -1
  139. package/dist/tasks.js +41 -16
  140. package/dist/tasks.js.map +1 -1
  141. package/dist/team-config.d.ts.map +1 -1
  142. package/dist/team-config.js +20 -0
  143. package/dist/team-config.js.map +1 -1
  144. package/dist/todoHoardingGuard.d.ts +35 -0
  145. package/dist/todoHoardingGuard.d.ts.map +1 -0
  146. package/dist/todoHoardingGuard.js +150 -0
  147. package/dist/todoHoardingGuard.js.map +1 -0
  148. package/dist/types.d.ts +4 -2
  149. package/dist/types.d.ts.map +1 -1
  150. package/dist/version.d.ts +2 -0
  151. package/dist/version.d.ts.map +1 -0
  152. package/dist/version.js +16 -0
  153. package/dist/version.js.map +1 -0
  154. package/dist/working-contract.d.ts.map +1 -1
  155. package/dist/working-contract.js +59 -3
  156. package/dist/working-contract.js.map +1 -1
  157. package/package.json +5 -1
  158. package/public/dashboard.js +161 -20
  159. package/public/docs.md +68 -8
  160. package/public/polls-mock.html +1 -1
@@ -14,7 +14,60 @@ import { routeMessage } from './messageRouter.js';
14
14
  import { listReflections } from './reflections.js';
15
15
  import { getEffectiveActivity, formatActivityWarning } from './activity-signal.js';
16
16
  // ── State: track warnings ──
17
- const warningTimestamps = new Map(); // key: `${agent}:${taskId}`
17
+ /**
18
+ * warningTimestamps: key β†’ epoch ms when Phase 1 warning was issued.
19
+ *
20
+ * Backed by SQLite so restarts don't re-fire warnings. In-memory cache
21
+ * is seeded from DB on first use.
22
+ *
23
+ * Root cause of compliance snapshot 3x bug: this was previously a plain
24
+ * in-memory Map that reset on every server restart. Each restart would
25
+ * re-fire the Phase 1 warning for every stale doing task. The stale
26
+ * duration increments between restarts (e.g. "stale for 45m" vs "46m"),
27
+ * which bypassed chat.ts content dedup, resulting in 2–3x identical-
28
+ * looking warning messages per agent per deploy cycle.
29
+ */
30
+ const warningTimestamps = new Map();
31
+ let _warningDbSeeded = false;
32
+ function ensureWarningTable() {
33
+ const db = getDb();
34
+ db.prepare(`
35
+ CREATE TABLE IF NOT EXISTS wc_warning_timestamps (
36
+ key TEXT PRIMARY KEY,
37
+ warned_at INTEGER NOT NULL
38
+ )
39
+ `).run();
40
+ }
41
+ function seedWarningTimestamps() {
42
+ if (_warningDbSeeded)
43
+ return;
44
+ _warningDbSeeded = true;
45
+ try {
46
+ ensureWarningTable();
47
+ const db = getDb();
48
+ const rows = db.prepare('SELECT key, warned_at FROM wc_warning_timestamps').all();
49
+ for (const row of rows) {
50
+ warningTimestamps.set(row.key, row.warned_at);
51
+ }
52
+ }
53
+ catch { /* db may not be ready */ }
54
+ }
55
+ function persistWarning(key, timestamp) {
56
+ try {
57
+ ensureWarningTable();
58
+ const db = getDb();
59
+ db.prepare('INSERT OR REPLACE INTO wc_warning_timestamps (key, warned_at) VALUES (?, ?)').run(key, timestamp);
60
+ }
61
+ catch { /* best-effort */ }
62
+ }
63
+ function clearWarning(key) {
64
+ warningTimestamps.delete(key);
65
+ try {
66
+ const db = getDb();
67
+ db.prepare('DELETE FROM wc_warning_timestamps WHERE key = ?').run(key);
68
+ }
69
+ catch { /* best-effort */ }
70
+ }
18
71
  // ── Enforcement tick ──
19
72
  /**
20
73
  * Called periodically. Checks all 'doing' tasks for stale status.
@@ -24,6 +77,8 @@ export async function tickWorkingContract() {
24
77
  const config = getConfig();
25
78
  if (!config.enabled)
26
79
  return { warnings: 0, requeued: 0, actions: [] };
80
+ // Seed warningTimestamps from DB on first tick (survives process restarts)
81
+ seedWarningTimestamps();
27
82
  const now = Date.now();
28
83
  const staleThresholdMs = config.staleAutoRequeueMin * 60_000;
29
84
  const graceMs = config.graceAfterWarningMin * 60_000;
@@ -51,6 +106,7 @@ export async function tickWorkingContract() {
51
106
  if (!warnedAt) {
52
107
  // Phase 1: Issue warning
53
108
  warningTimestamps.set(warningKey, now);
109
+ persistWarning(warningKey, now);
54
110
  const signalInfo = formatActivityWarning(activitySignal, config.staleAutoRequeueMin, now);
55
111
  const action = {
56
112
  type: 'warning',
@@ -80,7 +136,7 @@ export async function tickWorkingContract() {
80
136
  const activitySinceWarning = getLastActivityForAgent(task.id, agent);
81
137
  if (activitySinceWarning && activitySinceWarning > warnedAt) {
82
138
  // Agent responded β€” clear warning
83
- warningTimestamps.delete(warningKey);
139
+ clearWarning(warningKey);
84
140
  continue;
85
141
  }
86
142
  // Auto-requeue
@@ -95,7 +151,7 @@ export async function tickWorkingContract() {
95
151
  };
96
152
  actions.push(action);
97
153
  requeued++;
98
- warningTimestamps.delete(warningKey);
154
+ clearWarning(warningKey);
99
155
  if (!config.dryRun) {
100
156
  try {
101
157
  // Move task back to todo, clear assignee
@@ -1 +1 @@
1
- {"version":3,"file":"working-contract.js","sourceRoot":"","sources":["../src/working-contract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"working-contract.js","sourceRoot":"","sources":["../src/working-contract.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reflectt-node",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Coordinate your AI agent team. Shared tasks, memory, reflections, and presence. Self-host for free.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -29,6 +29,7 @@
29
29
  "test:watch": "vitest",
30
30
  "deploy": "bash scripts/post-merge-rebuild.sh",
31
31
  "hooks:install": "bash scripts/install-hooks.sh",
32
+ "prepublishOnly": "npm run build",
32
33
  "prepack": "chmod +x dist/cli.js"
33
34
  },
34
35
  "keywords": [
@@ -87,5 +88,8 @@
87
88
  ],
88
89
  "optionalDependencies": {
89
90
  "@xenova/transformers": "^2.17.2"
91
+ },
92
+ "overrides": {
93
+ "sharp": "^0.34.0"
90
94
  }
91
95
  }
@@ -11,7 +11,7 @@ document.addEventListener('keydown', function(e) {
11
11
  /* ============================================================
12
12
  SIDEBAR NAV β€” hash-based client-side routing
13
13
  ============================================================ */
14
- const VALID_PAGES = ['overview', 'tasks', 'chat', 'reviews', 'health', 'outcomes', 'research', 'artifacts'];
14
+ const VALID_PAGES = ['overview', 'tasks', 'chat', 'reviews', 'health', 'outcomes', 'research', 'artifacts', 'doctor'];
15
15
 
16
16
  function navigateTo(page) {
17
17
  if (!VALID_PAGES.includes(page)) page = 'overview';
@@ -71,8 +71,14 @@ function updateFirstBootBanner() {
71
71
  const el = document.getElementById('first-boot-banner');
72
72
  if (!el) return;
73
73
  const dismissed = localStorage.getItem('reflectt-first-boot-dismissed');
74
- const hasTasks = allTasks.length > 0;
75
- el.hidden = dismissed === '1' || hasTasks;
74
+ // We seed a welcome task on first boot, so `allTasks.length > 0` is not a good proxy for
75
+ // "user has started using the system". Only hide the banner once a *non-seeded* task exists.
76
+ const seededSources = new Set(['first-boot', 'first-boot-intent']);
77
+ const hasRealTasks = allTasks.some(t => {
78
+ const src = t && t.metadata && t.metadata.source;
79
+ return !src || !seededSources.has(src);
80
+ });
81
+ el.hidden = dismissed === '1' || hasRealTasks;
76
82
  }
77
83
  function dismissFirstBootBanner() {
78
84
  localStorage.setItem('reflectt-first-boot-dismissed', '1');
@@ -80,6 +86,53 @@ function dismissFirstBootBanner() {
80
86
  if (el) el.hidden = true;
81
87
  }
82
88
 
89
+ function updateOverviewEmptyState() {
90
+ const el = document.getElementById('overview-empty-state');
91
+ if (!el) return;
92
+ const hasTasks = allTasks.length > 0;
93
+ const hasMessages = allMessages.length > 0;
94
+ el.style.display = (hasTasks || hasMessages) ? 'none' : '';
95
+ }
96
+
97
+ function updateOverviewSummary() {
98
+ const panel = document.getElementById('overview-summary');
99
+ if (!panel) return;
100
+ const hasTasks = allTasks.length > 0;
101
+ const hasMessages = allMessages.length > 0;
102
+ panel.style.display = (hasTasks || hasMessages) ? '' : 'none';
103
+
104
+ // Stats
105
+ const statsEl = document.getElementById('overview-stats');
106
+ if (statsEl) {
107
+ const counts = { doing: 0, todo: 0, validating: 0, done: 0, blocked: 0 };
108
+ allTasks.forEach(t => { if (counts[t.status] !== undefined) counts[t.status]++; });
109
+ const statStyle = 'text-align:center;padding:10px;background:var(--bg-secondary, rgba(255,255,255,0.03));border-radius:8px;border:1px solid var(--border)';
110
+ const numStyle = 'font-size:20px;font-weight:600;color:var(--text-bright)';
111
+ const labelStyle = 'font-size:11px;color:var(--text-muted);margin-top:2px';
112
+ statsEl.innerHTML = [
113
+ { label: 'In Progress', count: counts.doing, color: 'var(--accent, #3B57E8)' },
114
+ { label: 'To Do', count: counts.todo, color: 'var(--text-muted)' },
115
+ { label: 'Validating', count: counts.validating, color: '#E8A83B' },
116
+ { label: 'Done', count: counts.done, color: '#4CAF50' },
117
+ { label: 'Blocked', count: counts.blocked, color: '#E84C3B' },
118
+ ].map(s => `<div style="${statStyle}"><div style="${numStyle};color:${s.color}">${s.count}</div><div style="${labelStyle}">${s.label}</div></div>`).join('');
119
+ }
120
+
121
+ // Recent activity β€” last 8 messages
122
+ const actEl = document.getElementById('overview-activity-list');
123
+ if (actEl && allMessages.length > 0) {
124
+ const recent = allMessages.slice(-8).reverse();
125
+ actEl.innerHTML = recent.map(m => {
126
+ const time = new Date(m.timestamp || m.ts || Date.now()).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
127
+ const from = m.from || m.author || 'system';
128
+ const text = (m.content || m.text || '').slice(0, 120);
129
+ return `<div style="padding:4px 0;border-bottom:1px solid var(--border)"><span style="color:var(--accent);font-weight:500">${from}</span> <span style="opacity:0.5">${time}</span><br>${text}${text.length >= 120 ? '…' : ''}</div>`;
130
+ }).join('');
131
+ } else if (actEl) {
132
+ actEl.innerHTML = '<div style="opacity:0.5">No recent messages</div>';
133
+ }
134
+ }
135
+
83
136
  // Delta cursors for lower payload refreshes
84
137
  let lastTaskSync = 0;
85
138
  let lastChatSync = 0;
@@ -258,7 +311,7 @@ function renderLaneTransitionMeta(task) {
258
311
  return `<div style="margin-top:6px;font-size:11px;color:var(--text-muted)">🧭 ${esc(parts.join(' Β· '))}</div>`;
259
312
  }
260
313
 
261
- function mentionsRyan(message) { return /@ryan\b/i.test(message || ''); }
314
+ function hasMention(message) { return /@([a-zA-Z][a-zA-Z0-9_-]*)/i.test(message || ''); }
262
315
 
263
316
  function resolveSSOTState(lastVerifiedUtc) {
264
317
  if (!lastVerifiedUtc) return { state: 'unknown', label: 'unknown', text: 'verification timestamp unavailable' };
@@ -450,12 +503,12 @@ function formatDurationMin(min) {
450
503
 
451
504
  function statusTemplateFor(agent, taskId) {
452
505
  const mentions = agent === 'pixel'
453
- ? '@kai @link'
506
+ ? '@owner @link'
454
507
  : agent === 'link'
455
- ? '@kai @pixel'
508
+ ? '@owner @pixel'
456
509
  : agent === 'kai'
457
510
  ? '@link @pixel'
458
- : '@kai @pixel';
511
+ : '@owner @pixel';
459
512
  return [
460
513
  mentions,
461
514
  'Task: ' + (taskId || '<task-id>'),
@@ -717,6 +770,8 @@ async function loadTasks(forceFull = false) {
717
770
  const navTaskBadge = document.getElementById('nav-task-count');
718
771
  if (navTaskBadge) navTaskBadge.textContent = allTasks.length;
719
772
  updateFirstBootBanner();
773
+ updateOverviewEmptyState();
774
+ updateOverviewSummary();
720
775
  }
721
776
 
722
777
  function renderProjectTabs() {
@@ -741,7 +796,7 @@ function toggleTestTasks() {
741
796
  renderStatusFilterTabs();
742
797
  renderKanban();
743
798
  // Update task count
744
- const openCount = getVisibleTasks().filter(t => t.status !== 'done').length;
799
+ const openCount = getVisibleTasks().filter(t => !['done', 'resolved_externally', 'cancelled'].includes(t.status)).length;
745
800
  document.getElementById('task-count').textContent = currentStatusFilter === 'open'
746
801
  ? openCount + ' open tasks'
747
802
  : getVisibleTasks().length + ' tasks';
@@ -779,20 +834,45 @@ function renderKanban() {
779
834
  const filtered = currentProject === 'all' ? visible : visible.filter(t => classifyProject(t) === currentProject);
780
835
  const cols = currentStatusFilter === 'open'
781
836
  ? ['todo', 'doing', 'blocked', 'validating']
782
- : ['todo', 'doing', 'blocked', 'validating', 'done'];
837
+ : ['todo', 'doing', 'blocked', 'validating', 'done', 'resolved_externally', 'cancelled'];
783
838
  const grouped = {}; cols.forEach(c => grouped[c] = []);
784
- filtered.forEach(t => { const s = t.status || 'todo'; if (grouped[s]) grouped[s].push(t); else grouped['todo'].push(t); });
839
+ const tasksForBoard = currentStatusFilter === 'open'
840
+ ? filtered.filter(t => cols.includes(t.status || 'todo'))
841
+ : filtered;
842
+ tasksForBoard.forEach(t => { const s = t.status || 'todo'; if (grouped[s]) grouped[s].push(t); else grouped['todo'].push(t); });
785
843
  const pOrder = { P0: 0, P1: 1, P2: 2, P3: 3 };
786
844
  cols.forEach(c => grouped[c].sort((a, b) => (pOrder[a.priority] ?? 9) - (pOrder[b.priority] ?? 9)));
787
845
 
788
846
  const kanban = document.getElementById('kanban');
847
+
848
+ // Full-board empty state: no tasks at all
849
+ const totalOnBoard = tasksForBoard.length;
850
+ if (totalOnBoard === 0) {
851
+ kanban.innerHTML = '<div class="board-empty-state" style="grid-column:1/-1;text-align:center;padding:40px 20px;color:var(--text-muted)">'
852
+ + '<div style="font-size:28px;margin-bottom:12px">πŸ“‹</div>'
853
+ + '<div style="font-size:15px;font-weight:500;color:var(--text-bright);margin-bottom:6px">No tasks yet</div>'
854
+ + '<div style="font-size:13px;max-width:340px;margin:0 auto;line-height:1.5">Create your first task via the API, or connect an AI agent to start generating work automatically.</div>'
855
+ + '<div style="margin-top:14px;display:flex;gap:10px;justify-content:center;flex-wrap:wrap">'
856
+ + '<a href="/docs" target="_blank" style="color:var(--accent);font-size:12px;text-decoration:none">API reference β†’</a>'
857
+ + '<a href="/capabilities" target="_blank" style="color:var(--accent);font-size:12px;text-decoration:none">Capabilities β†’</a>'
858
+ + '</div></div>';
859
+ return;
860
+ }
861
+
789
862
  kanban.innerHTML = cols.map(col => {
790
863
  const items = grouped[col];
791
864
  const isDone = col === 'done';
792
865
  const isTodo = col === 'todo';
793
866
  const colLimit = isDone ? 3 : isTodo ? 10 : items.length;
867
+ const emptyMessages = {
868
+ todo: 'No tasks queued',
869
+ doing: 'Nothing in progress',
870
+ blocked: 'Nothing blocked',
871
+ validating: 'Nothing awaiting review',
872
+ done: 'No completed tasks yet',
873
+ };
794
874
  const cards = items.length === 0
795
- ? '<div class="empty">β€”</div>'
875
+ ? '<div class="empty" style="font-size:12px;padding:12px 8px">' + (emptyMessages[col] || 'β€”') + '</div>'
796
876
  : items.map((t, idx) => {
797
877
  const isHidden = idx >= colLimit;
798
878
  const assigneeAgent = t.assignee ? AGENTS.find(a => a.name === t.assignee) : null;
@@ -1032,13 +1112,13 @@ async function loadChat(forceFull = false) {
1032
1112
  if (!channelStats.has(ch)) channelStats.set(ch, { total: 0, mentions: 0 });
1033
1113
  const stats = channelStats.get(ch);
1034
1114
  stats.total += 1;
1035
- if (mentionsRyan(m.content)) stats.mentions += 1;
1115
+ if (hasMention(m.content)) stats.mentions += 1;
1036
1116
  });
1037
1117
 
1038
1118
  const tabs = document.getElementById('channel-tabs');
1039
1119
  tabs.innerHTML = Array.from(channels).map(ch => {
1040
1120
  const stats = ch === 'all'
1041
- ? { total: allMessages.length, mentions: allMessages.filter(m => mentionsRyan(m.content)).length }
1121
+ ? { total: allMessages.length, mentions: allMessages.filter(m => hasMention(m.content)).length }
1042
1122
  : (channelStats.get(ch) || { total: 0, mentions: 0 });
1043
1123
  const label = ch === 'all' ? '🌐 all' : '#' + esc(ch);
1044
1124
  const countMeta = `<span class="meta">${stats.total}</span>`;
@@ -1069,7 +1149,7 @@ function renderChat() {
1069
1149
  body.innerHTML = shown.map(m => {
1070
1150
  const agent = AGENT_INDEX.get(m.from);
1071
1151
  const roleTag = agent ? `<span class="msg-role">${esc(agent.role)}</span>` : '';
1072
- const mentioned = mentionsRyan(m.content);
1152
+ const mentioned = hasMention(m.content);
1073
1153
  const channelTag = m.channel ? '<span class="msg-channel">#' + esc(m.channel) + '</span>' : '';
1074
1154
  const editedTag = m.metadata && m.metadata.editedAt ? '<span class="msg-edited">(edited)</span>' : '';
1075
1155
  return `
@@ -1294,9 +1374,9 @@ async function loadSharedArtifacts() {
1294
1374
  const files = entries.filter(e => e && e.type === 'file');
1295
1375
  count.textContent = files.length + ' files';
1296
1376
 
1297
- // Pinned: Ryan's thoughts (if symlinked into shared workspace process/)
1377
+ // Pinned: operator notes (optional)
1298
1378
  const pinned = [
1299
- { name: "RYANS-THOUGHTS.md", label: "Ryan's thoughts" },
1379
+ { name: "OPERATOR-NOTES.md", label: "Operator notes" },
1300
1380
  ];
1301
1381
 
1302
1382
  const pinnedRows = pinned.map(p => {
@@ -1540,6 +1620,51 @@ async function loadHealth() {
1540
1620
  }
1541
1621
  }
1542
1622
 
1623
+ async function loadDoctorPage() {
1624
+ const body = document.getElementById('doctor-body');
1625
+ const raw = document.getElementById('doctor-raw');
1626
+ if (!body) return;
1627
+ body.innerHTML = '<div class="loading">Loading diagnostics…</div>';
1628
+
1629
+ try {
1630
+ const res = await fetch(BASE + '/health');
1631
+ const data = await res.json();
1632
+
1633
+ // Render pretty summary
1634
+ const rows = [
1635
+ ['Status', data.status ?? 'β€”'],
1636
+ ['Version', data.version ?? 'β€”'],
1637
+ ['Uptime', data.uptime != null ? `${Math.floor(data.uptime / 60)}m ${data.uptime % 60}s` : 'β€”'],
1638
+ ['PID', data.pid ?? data.runtime?.pid ?? 'β€”'],
1639
+ ['Node', data.nodeVersion ?? data.runtime?.nodeVersion ?? 'β€”'],
1640
+ ['Port', data.port ?? data.runtime?.port ?? 'β€”'],
1641
+ ['Deploy stale', data.deploy?.stale != null ? (data.deploy.stale ? '⚠️ Yes' : 'βœ… No') : 'β€”'],
1642
+ ['Deploy grace', data.deploy?.withinGrace ? `⏳ ${Math.round((data.deploy.graceRemainingMs || 0) / 60000)}m left` : 'β€”'],
1643
+ ['Tasks (todo)', data.tasks?.todo ?? 'β€”'],
1644
+ ['Tasks (doing)', data.tasks?.doing ?? 'β€”'],
1645
+ ];
1646
+
1647
+ body.innerHTML = `<table style="width:100%;border-collapse:collapse;font-size:13px">
1648
+ ${rows.map(([k, v]) => `<tr>
1649
+ <td style="padding:6px 12px 6px 0;color:var(--muted);width:40%;white-space:nowrap">${k}</td>
1650
+ <td style="padding:6px 0;font-family:var(--font-mono,monospace)">${String(v)}</td>
1651
+ </tr>`).join('')}
1652
+ </table>
1653
+ <div style="margin-top:8px;font-size:11px;color:var(--muted)">Last refreshed: ${new Date().toLocaleTimeString()}</div>`;
1654
+
1655
+ if (raw) raw.textContent = JSON.stringify(data, null, 2);
1656
+ } catch (e) {
1657
+ body.innerHTML = `<div class="empty-state">Failed to load diagnostics: ${e.message}</div>`;
1658
+ }
1659
+ }
1660
+
1661
+ // Hook into page activation: load doctor data when the page is shown
1662
+ const _origActivatePage = activatePage;
1663
+ function activatePage(page) {
1664
+ _origActivatePage(page);
1665
+ if (page === 'doctor') loadDoctorPage();
1666
+ }
1667
+
1543
1668
  async function loadReleaseStatus(force = false) {
1544
1669
  const badge = document.getElementById('release-badge');
1545
1670
  if (!badge) return;
@@ -1555,6 +1680,7 @@ async function loadReleaseStatus(force = false) {
1555
1680
  badge.classList.toggle('stale', stale);
1556
1681
  badge.classList.toggle('fresh', !stale);
1557
1682
  badge.textContent = stale ? 'deploy: stale' : 'deploy: in sync';
1683
+ badge.style.display = '';
1558
1684
 
1559
1685
  const reasons = Array.isArray(status.reasons) ? status.reasons : [];
1560
1686
  const startupCommit = status.startup && status.startup.commit ? status.startup.commit.slice(0, 8) : 'unknown';
@@ -1590,6 +1716,7 @@ async function loadBuildInfo() {
1590
1716
  badge.classList.toggle('stale', branch !== 'main');
1591
1717
  badge.textContent = `${sha} β€’ ${uptimeStr}`;
1592
1718
  badge.title = `SHA: ${info.gitSha}\nBranch: ${branch}\nCommit: ${info.gitMessage}\nAuthor: ${info.gitAuthor}\nPID: ${info.pid}\nNode: ${info.nodeVersion}\nStarted: ${info.startedAt}`;
1719
+ badge.style.display = '';
1593
1720
  } catch (err) {
1594
1721
  badge.textContent = 'build: error';
1595
1722
  badge.title = 'Failed to load build info';
@@ -1708,7 +1835,16 @@ function renderReviewQueue() {
1708
1835
  });
1709
1836
 
1710
1837
  if (validating.length === 0) {
1711
- panel.style.display = 'none';
1838
+ panel.style.display = '';
1839
+ count.textContent = '';
1840
+ body.innerHTML = '<div style="text-align:center;padding:24px 16px;color:var(--text-muted)">'
1841
+ + '<div style="font-size:22px;margin-bottom:8px">βœ“</div>'
1842
+ + '<div style="font-size:13px;font-weight:500;color:var(--text-bright);margin-bottom:4px">Review queue is clear</div>'
1843
+ + '<div style="font-size:12px;line-height:1.5">Tasks move here when they enter <em>validating</em>. Reviewers will see SLA timers and can approve or request changes.</div>'
1844
+ + '</div>';
1845
+ // Clear sidebar badge
1846
+ const navReviewBadge = document.getElementById('nav-review-count');
1847
+ if (navReviewBadge) navReviewBadge.textContent = '0';
1712
1848
  return;
1713
1849
  }
1714
1850
 
@@ -1770,7 +1906,7 @@ async function escalateReviewBreaches(breachedTasks) {
1770
1906
  return '- ' + t.id + ' (' + (t.title || '').slice(0, 50) + ') β€” reviewer: @' + reviewer + ', waiting ' + formatDuration(t.timeInReview);
1771
1907
  });
1772
1908
 
1773
- const content = '@kai Review SLA breach detected:\n' + lines.join('\n');
1909
+ const content = '@owner Review SLA breach detected:\n' + lines.join('\n');
1774
1910
 
1775
1911
  try {
1776
1912
  await fetch(BASE + '/chat/messages', {
@@ -2749,6 +2885,11 @@ function toggleFocusMode() {
2749
2885
  // Persist preference
2750
2886
  try { localStorage.setItem('reflectt-focus-mode', focusModeActive ? '1' : '0'); } catch {}
2751
2887
 
2888
+ // Show/hide dev-only panels
2889
+ document.querySelectorAll('.panel.focus-only').forEach(panel => {
2890
+ panel.style.display = focusModeActive ? '' : 'none';
2891
+ });
2892
+
2752
2893
  // Re-render kanban to add/remove QA contract details
2753
2894
  renderKanban();
2754
2895
 
@@ -2840,9 +2981,9 @@ async function checkGettingStarted() {
2840
2981
  const hasTasks = (health.tasks?.total || 0) > 0;
2841
2982
  const hasMessages = (health.chat?.total || 0) > 0;
2842
2983
 
2843
- // Step 1: preflight β€” done if server is healthy
2984
+ // Step 1: server running β€” always done if dashboard loads
2844
2985
  const step1 = document.getElementById('gs-preflight');
2845
- if (step1 && hasHeartbeat) {
2986
+ if (step1) {
2846
2987
  step1.classList.add('done');
2847
2988
  step1.querySelector('.gs-icon').textContent = 'βœ“';
2848
2989
  }