memorix 1.7.3 → 1.8.1

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 (73) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/dist/cli/index.js +1488 -270
  5. package/dist/dashboard/static/app.js +125 -27
  6. package/dist/dashboard/static/index.html +11 -1
  7. package/dist/dashboard/static/style.css +86 -0
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.js +927 -240
  10. package/dist/maintenance-runner.js +607 -68
  11. package/dist/media-audio-runner.js +602 -63
  12. package/dist/media-video-runner.js +607 -68
  13. package/dist/memcode-runtime/CHANGELOG.md +41 -0
  14. package/dist/sdk.js +926 -239
  15. package/dist/types.d.ts +8 -0
  16. package/dist/vector-backfill-runner.js +607 -68
  17. package/docs/1.2.4-PERSISTENT-MEMORY-DELIVERY.md +1 -1
  18. package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +75 -0
  19. package/docs/API_REFERENCE.md +39 -1
  20. package/docs/ARCHITECTURE.md +3 -1
  21. package/docs/DASHBOARD.md +16 -0
  22. package/docs/DEVELOPMENT.md +3 -2
  23. package/docs/INTEGRATIONS.md +1 -1
  24. package/docs/README.md +15 -2
  25. package/package.json +1 -1
  26. package/plugins/antigravity/memorix/rules/memorix.md +1 -1
  27. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  28. package/plugins/claude/memorix/SKILL.md +1 -1
  29. package/plugins/claude/memorix/skills/memorix-memory/SKILL.md +2 -2
  30. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  31. package/plugins/codebuddy/memorix/skills/memorix-memory/SKILL.md +2 -2
  32. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  33. package/plugins/codex/memorix/skills/memorix-memory/SKILL.md +2 -2
  34. package/plugins/copilot/memorix/plugin.json +1 -1
  35. package/plugins/copilot/memorix/skills/memorix-memory/SKILL.md +2 -2
  36. package/plugins/cursor/memorix/skills/memorix-memory/SKILL.md +2 -2
  37. package/plugins/gemini/memorix/GEMINI.md +1 -1
  38. package/plugins/gemini/memorix/gemini-extension.json +1 -1
  39. package/plugins/omp/memorix/package.json +1 -1
  40. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  41. package/plugins/pi/memorix/package.json +1 -1
  42. package/plugins/pi/memorix/skills/memorix-memory/SKILL.md +2 -2
  43. package/server.json +2 -2
  44. package/src/cli/capability-map.ts +2 -0
  45. package/src/cli/commands/context.ts +11 -0
  46. package/src/cli/commands/dashboard.ts +1 -1
  47. package/src/cli/commands/evidence.ts +56 -0
  48. package/src/cli/commands/feedback.ts +58 -0
  49. package/src/cli/commands/resume.ts +2 -0
  50. package/src/cli/commands/serve-http.ts +229 -13
  51. package/src/cli/fallback-budget.ts +59 -0
  52. package/src/cli/index.ts +5 -1
  53. package/src/compact/engine.ts +26 -1
  54. package/src/config/dotenv-loader.ts +17 -0
  55. package/src/dashboard/config-provenance.ts +17 -0
  56. package/src/dashboard/evidence.ts +63 -0
  57. package/src/dashboard/server.ts +178 -154
  58. package/src/dashboard/static/index.html +11 -1
  59. package/src/dashboard/static/style.css +86 -0
  60. package/src/hooks/installers/index.ts +1 -1
  61. package/src/hooks/official-skills.ts +3 -3
  62. package/src/hooks/rules/memorix-agent-rules.md +1 -1
  63. package/src/memory/feedback-model.ts +4 -0
  64. package/src/memory/feedback.ts +220 -0
  65. package/src/memory/observations.ts +19 -0
  66. package/src/memory/retention.ts +38 -5
  67. package/src/server/mcp-binding-store.ts +79 -0
  68. package/src/server/mcp-diagnostics.ts +40 -0
  69. package/src/server/tool-profile.ts +4 -0
  70. package/src/server.ts +125 -5
  71. package/src/store/evidence-store.ts +261 -0
  72. package/src/store/sqlite-db.ts +104 -0
  73. package/src/types.ts +8 -0
@@ -15,6 +15,7 @@ const i18n = {
15
15
  entities: 'Entities',
16
16
  relations: 'Relations',
17
17
  observations: 'Observations',
18
+ evidence: 'Evidence',
18
19
  nextId: 'Next ID',
19
20
  observationTypes: 'Observation Types',
20
21
  recentActivity: 'Recent Activity',
@@ -42,6 +43,18 @@ const i18n = {
42
43
  noMatchingObs: 'No matching observations',
43
44
  noObsTitle: 'No Observations',
44
45
  noObsDesc: 'Use memorix_store to create observations',
46
+ evidenceSubtitle: 'Why this memory is trusted, where it came from, and whether it is still current',
47
+ evidenceSource: 'Source',
48
+ evidenceLocator: 'Locator',
49
+ evidenceFreshness: 'Freshness',
50
+ evidenceCurrent: 'Current',
51
+ evidenceStale: 'Stale',
52
+ evidenceVerified: 'Verified',
53
+ evidenceUnverified: 'Unverified',
54
+ evidenceConflicted: 'Conflicted',
55
+ evidenceNoCards: 'No evidence cards',
56
+ evidenceNoCardsDesc: 'Store or sync project memories to build a provenance view.',
57
+ evidenceEvents: 'Audit events',
45
58
  untitled: 'Untitled',
46
59
  unknown: 'unknown',
47
60
  lowQuality: 'cleanup candidate',
@@ -129,17 +142,21 @@ const i18n = {
129
142
  noRetentionDesc: 'Store observations to see memory retention scores',
130
143
 
131
144
  // Team -> Coordination
132
- teamTitle: 'Coordination',
133
- teamSubtitle: 'Coordinated agents, tasks, locks, and handoffs',
134
- teamNoData: 'No coordination workflow activity yet',
135
- teamNoDataHint: 'Use the CLI orchestrator or inspect coordination state.',
145
+ teamTitle: 'Coordination Status',
146
+ teamSubtitle: 'Read-only project coordination status',
147
+ teamNoData: 'No coordination status is available',
148
+ teamNoDataHint: 'Coordination state is read-only and comes from the project SQLite store.',
149
+ teamStatusError: 'Coordination status unavailable',
150
+ teamStatusDegraded: 'Coordination status degraded',
151
+ teamStatusErrorDesc: 'The persistent coordination state could not be read. This view has no write actions.',
152
+ teamStatusDegradedDesc: 'Some persistent coordination state could not be read. Values may be incomplete.',
136
153
  teamActiveAgents: 'Active Agents',
137
154
  teamLockedFiles: 'Locked Files',
138
155
  teamTasks: 'Tasks',
139
156
  teamAvailable: 'Available',
140
157
  teamAgents: 'Agents',
141
158
  teamLocks: 'File Locks',
142
- teamTaskBoard: 'Task Board',
159
+ teamTaskStatus: 'Task Status',
143
160
  // Resume area
144
161
  resumeTitle: 'Continue This Project',
145
162
  resumeDesc: 'What needs attention right now',
@@ -269,7 +286,7 @@ const i18n = {
269
286
  projectUnresolved: 'Unresolved',
270
287
  projectUnresolvedDesc: 'No project bound — select a project from the switcher',
271
288
  projectResolved: 'Resolved',
272
- projectScopeProject: 'Project Coordination',
289
+ projectScopeProject: 'Project Coordination Status',
273
290
  projectScopeGlobal: 'All Projects',
274
291
  projectScopeProjectDesc: 'Agents and tasks coordinated for this project',
275
292
  projectScopeGlobalDesc: 'Agents and tasks coordinated across projects',
@@ -428,6 +445,7 @@ const i18n = {
428
445
  navKnowledge: 'Memory Overview',
429
446
  navGraph: 'Memory Map',
430
447
  navObservations: 'Observations',
448
+ navEvidence: 'Evidence',
431
449
  navRetention: 'Retention',
432
450
  navConfig: 'Config',
433
451
  navIdentity: 'Identity',
@@ -438,6 +456,7 @@ const i18n = {
438
456
  navLabelKnowledge: 'Knowledge',
439
457
  navLabelGraph: 'Graph',
440
458
  navLabelObservations: 'Observations',
459
+ navLabelEvidence: 'Evidence',
441
460
  navLabelRetention: 'Retention',
442
461
  navLabelConfig: 'Config',
443
462
  navLabelIdentity: 'Identity',
@@ -454,8 +473,8 @@ const i18n = {
454
473
  // Mode banner
455
474
  modeStandalone: 'Standalone',
456
475
  modeControlPlane: 'Control Plane',
457
- modeStandaloneHint: 'Standalone dashboard - memory and read-only coordination state',
458
- modeControlPlaneHint: 'HTTP control plane - shared MCP access and live dashboard',
476
+ modeStandaloneHint: 'Standalone dashboard - memory and read-only coordination status',
477
+ modeControlPlaneHint: 'HTTP control plane - shared MCP access and read-only coordination status',
459
478
  modeBannerProject: 'Project',
460
479
  modeBannerMcp: 'MCP',
461
480
 
@@ -479,6 +498,7 @@ const i18n = {
479
498
  entities: '实体',
480
499
  relations: '关系',
481
500
  observations: '观察记录',
501
+ evidence: '证据',
482
502
  nextId: '下一个 ID',
483
503
  observationTypes: '观察类型分布',
484
504
  recentActivity: '最近活动',
@@ -506,6 +526,18 @@ const i18n = {
506
526
  noMatchingObs: '没有匹配的观察记录',
507
527
  noObsTitle: '暂无观察记录',
508
528
  noObsDesc: '使用 memorix_store 创建观察记录',
529
+ evidenceSubtitle: '查看记忆为何可信、来自哪里,以及是否仍然有效',
530
+ evidenceSource: '来源',
531
+ evidenceLocator: '定位',
532
+ evidenceFreshness: '新鲜度',
533
+ evidenceCurrent: '当前',
534
+ evidenceStale: '已过期',
535
+ evidenceVerified: '已验证',
536
+ evidenceUnverified: '未验证',
537
+ evidenceConflicted: '有冲突',
538
+ evidenceNoCards: '暂无证据卡',
539
+ evidenceNoCardsDesc: '写入或同步项目记忆后,这里会显示来源和审计信息。',
540
+ evidenceEvents: '审计事件',
509
541
  untitled: '无标题',
510
542
  unknown: '未知',
511
543
  lowQuality: '清理候选',
@@ -593,17 +625,21 @@ const i18n = {
593
625
  noRetentionDesc: '存储观察记录以查看记忆衰减分数',
594
626
 
595
627
  // Team -> 编排协作
596
- teamTitle: '编排协作',
597
- teamSubtitle: 'agents、任务、文件锁和交接状态',
598
- teamNoData: '暂无编排协作活动',
599
- teamNoDataHint: '使用 CLI 编排任务,或查看协调状态。',
628
+ teamTitle: '协作状态',
629
+ teamSubtitle: '只读项目协作状态',
630
+ teamNoData: '暂无可用的协作状态',
631
+ teamNoDataHint: '协作状态为只读,并来自项目 SQLite 存储。',
632
+ teamStatusError: '协作状态不可用',
633
+ teamStatusDegraded: '协作状态已降级',
634
+ teamStatusErrorDesc: '无法读取持久协作状态。此视图不提供写入操作。',
635
+ teamStatusDegradedDesc: '部分持久协作状态无法读取,当前数据可能不完整。',
600
636
  teamActiveAgents: '活跃 Agent',
601
637
  teamLockedFiles: '锁定文件',
602
638
  teamTasks: '任务',
603
639
  teamAvailable: '可领取',
604
640
  teamAgents: 'Agent',
605
641
  teamLocks: '文件锁',
606
- teamTaskBoard: '任务看板',
642
+ teamTaskStatus: '任务状态',
607
643
  // Resume area
608
644
  resumeTitle: '继续这个项目',
609
645
  resumeDesc: '当前需要关注的事项',
@@ -733,7 +769,7 @@ const i18n = {
733
769
  projectUnresolved: '未绑定',
734
770
  projectUnresolvedDesc: '无项目绑定 — 请从切换器选择项目',
735
771
  projectResolved: '已绑定',
736
- projectScopeProject: '项目编排协作',
772
+ projectScopeProject: '项目协作状态',
737
773
  projectScopeGlobal: '所有项目',
738
774
  projectScopeProjectDesc: '当前项目中的 agents 和任务',
739
775
  projectScopeGlobalDesc: '所有项目中的 agents 和任务',
@@ -897,6 +933,7 @@ const i18n = {
897
933
  navKnowledge: '记忆概览',
898
934
  navGraph: '记忆关系图',
899
935
  navObservations: '观察记录',
936
+ navEvidence: '证据',
900
937
  navRetention: '记忆衰减',
901
938
  navConfig: '配置溯源',
902
939
  navIdentity: '身份健康',
@@ -907,6 +944,7 @@ const i18n = {
907
944
  navLabelKnowledge: '知识库',
908
945
  navLabelGraph: '图谱',
909
946
  navLabelObservations: '观察',
947
+ navLabelEvidence: '证据',
910
948
  navLabelRetention: '衰减',
911
949
  navLabelConfig: '配置',
912
950
  navLabelIdentity: '身份',
@@ -923,8 +961,8 @@ const i18n = {
923
961
  // Mode banner
924
962
  modeStandalone: '独立模式',
925
963
  modeControlPlane: '控制平面',
926
- modeStandaloneHint: '独立看板 - 记忆与只读协调状态',
927
- modeControlPlaneHint: 'HTTP 控制平面 - 共享 MCP 接入与实时看板',
964
+ modeStandaloneHint: '独立视图 - 记忆与只读协作状态',
965
+ modeControlPlaneHint: 'HTTP 控制平面 - 共享 MCP 接入与只读协作状态',
928
966
  modeBannerProject: '项目',
929
967
  modeBannerMcp: 'MCP',
930
968
 
@@ -970,8 +1008,8 @@ function setLang(lang) {
970
1008
  if (label) label.textContent = lang === 'en' ? '中文' : 'EN';
971
1009
 
972
1010
  // Update nav tooltips + labels
973
- const tooltipMap = { dashboard: 'navDashboard', 'git-memory': 'navGitMemory', knowledge: 'navKnowledge', graph: 'navGraph', observations: 'navObservations', retention: 'navRetention', config: 'navConfig', identity: 'navIdentity', sessions: 'navSessions', team: 'navTeam' };
974
- const labelMap = { dashboard: 'navLabelDashboard', 'git-memory': 'navLabelGitMemory', knowledge: 'navLabelKnowledge', graph: 'navLabelGraph', observations: 'navLabelObservations', retention: 'navLabelRetention', config: 'navLabelConfig', identity: 'navLabelIdentity', sessions: 'navLabelSessions', team: 'navLabelTeam' };
1011
+ const tooltipMap = { dashboard: 'navDashboard', 'git-memory': 'navGitMemory', knowledge: 'navKnowledge', graph: 'navGraph', observations: 'navObservations', evidence: 'navEvidence', retention: 'navRetention', config: 'navConfig', identity: 'navIdentity', sessions: 'navSessions', team: 'navTeam' };
1012
+ const labelMap = { dashboard: 'navLabelDashboard', 'git-memory': 'navLabelGitMemory', knowledge: 'navLabelKnowledge', graph: 'navLabelGraph', observations: 'navLabelObservations', evidence: 'navLabelEvidence', retention: 'navLabelRetention', config: 'navLabelConfig', identity: 'navLabelIdentity', sessions: 'navLabelSessions', team: 'navLabelTeam' };
975
1013
  document.querySelectorAll('.nav-btn').forEach(b => {
976
1014
  const page = b.dataset.page;
977
1015
  if (page && tooltipMap[page]) b.title = t(tooltipMap[page]);
@@ -1062,7 +1100,7 @@ onDomReady(() => {
1062
1100
  // Router & Navigation
1063
1101
  // ============================================================
1064
1102
 
1065
- const pages = ['dashboard', 'git-memory', 'knowledge', 'graph', 'observations', 'retention', 'config', 'identity', 'sessions', 'team'];
1103
+ const pages = ['dashboard', 'git-memory', 'knowledge', 'graph', 'observations', 'evidence', 'retention', 'config', 'identity', 'sessions', 'team'];
1066
1104
  let currentPage = 'dashboard';
1067
1105
 
1068
1106
  function navigate(page) {
@@ -1127,8 +1165,12 @@ async function api(endpoint) {
1127
1165
  ? `/api/${endpoint}${sep}project=${encodeURIComponent(selectedProject)}`
1128
1166
  : `/api/${endpoint}`;
1129
1167
  const res = await fetch(url);
1130
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
1131
- return await res.json();
1168
+ const payload = await res.json().catch(() => null);
1169
+ if (!res.ok) {
1170
+ if (endpoint.startsWith('team') && payload?.status) return payload;
1171
+ throw new Error(`HTTP ${res.status}`);
1172
+ }
1173
+ return payload;
1132
1174
  } catch (err) {
1133
1175
  console.error(`API error (${endpoint}):`, err);
1134
1176
  return null;
@@ -1569,6 +1611,7 @@ async function loadPage(page) {
1569
1611
  case 'knowledge': await loadKnowledge(); break;
1570
1612
  case 'graph': await loadGraph(); break;
1571
1613
  case 'observations': await loadObservations(); break;
1614
+ case 'evidence': await loadEvidence(); break;
1572
1615
  case 'retention': await loadRetention(); break;
1573
1616
  case 'config': await loadConfig(); break;
1574
1617
  case 'identity': await loadIdentity(); break;
@@ -3632,6 +3675,51 @@ async function loadObservations() {
3632
3675
  renderObsList();
3633
3676
  }
3634
3677
 
3678
+ async function loadEvidence() {
3679
+ const container = document.getElementById('page-evidence');
3680
+ container.innerHTML = '<div class="loading"><div class="spinner"></div></div>';
3681
+ const data = await api('evidence') || { cards: [] };
3682
+ const cards = data.cards || [];
3683
+ if (cards.length === 0) {
3684
+ container.innerHTML = emptyState('<span class="iconify" data-icon="lucide:file-check-2" style="font-size:36px;"></span>', t('evidenceNoCards'), t('evidenceNoCardsDesc'));
3685
+ return;
3686
+ }
3687
+ container.innerHTML = `
3688
+ <div class="page-header">
3689
+ <h1 class="page-title">${t('evidence')}</h1>
3690
+ <p class="page-subtitle">${t('evidenceSubtitle')}</p>
3691
+ </div>
3692
+ <div class="evidence-console" role="list">
3693
+ ${cards.map((card) => {
3694
+ const freshness = card.freshness === 'stale' ? t('evidenceStale') : t('evidenceCurrent');
3695
+ const verification = card.verification === 'verified' ? t('evidenceVerified') : card.verification === 'conflicted' ? t('evidenceConflicted') : t('evidenceUnverified');
3696
+ const eventCount = (card.events || []).length;
3697
+ return `
3698
+ <article class="evidence-card" role="listitem">
3699
+ <div class="evidence-card-header">
3700
+ <div class="evidence-card-heading">
3701
+ <span class="evidence-card-kind">${escapeHtml(card.sourceKind || 'memory')}</span>
3702
+ <h2>${escapeHtml(card.title || t('untitled'))}</h2>
3703
+ </div>
3704
+ <div class="evidence-card-state">
3705
+ <span class="evidence-state evidence-${card.freshness === 'stale' ? 'stale' : 'current'}">${escapeHtml(freshness)}</span>
3706
+ <span class="evidence-state evidence-${card.verification === 'verified' ? 'verified' : card.verification === 'conflicted' ? 'conflicted' : 'unverified'}">${escapeHtml(verification)}</span>
3707
+ </div>
3708
+ </div>
3709
+ <p class="evidence-card-summary">${escapeHtml(card.summary || '')}</p>
3710
+ <dl class="evidence-card-meta">
3711
+ <div><dt>${t('evidenceSource')}</dt><dd>${escapeHtml(card.sourceRef || 'unknown')}</dd></div>
3712
+ <div><dt>${t('evidenceLocator')}</dt><dd>${escapeHtml(card.locator || 'not recorded')}</dd></div>
3713
+ <div><dt>${t('evidenceEvents')}</dt><dd>${eventCount}</dd></div>
3714
+ </dl>
3715
+ ${card.staleReason ? `<div class="evidence-card-warning">${escapeHtml(card.staleReason)}</div>` : ''}
3716
+ </article>
3717
+ `;
3718
+ }).join('')}
3719
+ </div>
3720
+ `;
3721
+ }
3722
+
3635
3723
  function renderObsList() {
3636
3724
  const list = document.getElementById('obs-list');
3637
3725
  if (!list) return;
@@ -3686,7 +3774,15 @@ function renderObsList() {
3686
3774
  ${obs.narrative ? `<div class="obs-detail-section"><label>${t('narrative')}</label><div class="obs-card-narrative">${hl(obs.narrative)}</div></div>` : ''}
3687
3775
  ${obs.facts && obs.facts.length > 0 ? `<div class="obs-detail-section"><label>${t('facts')}</label><div class="obs-card-facts">${obs.facts.map(f => `<span class="fact-tag">${hl(f)}</span>`).join('')}</div></div>` : ''}
3688
3776
  ${obs.concepts && obs.concepts.length > 0 ? `<div class="obs-detail-section"><label>${t('concepts')}</label><div class="obs-card-facts">${obs.concepts.map(c => `<span class="fact-tag concept-tag">${hl(c)}</span>`).join('')}</div></div>` : ''}
3689
- ${obs.filesModified && obs.filesModified.length > 0 ? `<div class="obs-detail-section"><label>${t('files')}</label><div class="obs-card-facts">${obs.filesModified.map(f => `<span class="fact-tag file-tag">${hl(f)}</span>`).join('')}</div></div>` : ''}
3777
+ ${obs.filesModified && obs.filesModified.length > 0 ? `<div class="obs-detail-section"><label>${t('files')}</label><div class="obs-card-facts">${obs.filesModified.map(f => `<span class="fact-tag file-tag">${hl(f)}</span>`).join('')}</div></div>` : ''}
3778
+ <div class="obs-detail-section evidence-provenance" aria-label="Evidence provenance">
3779
+ <label>Evidence</label>
3780
+ <div class="obs-card-meta">
3781
+ <span>Source: ${escapeHtml(obs.sourceDetail || obs.source || 'unknown')}</span>
3782
+ ${obs.sessionId ? `<span>Session: ${escapeHtml(obs.sessionId)}</span>` : ''}
3783
+ ${obs.status ? `<span>Verification: ${obs.status === 'resolved' ? 'verified' : obs.status === 'archived' ? 'conflicted' : 'unverified'}</span>` : ''}
3784
+ </div>
3785
+ </div>
3690
3786
  <div class="obs-detail-actions">
3691
3787
  <button class="delete-btn" onclick="deleteObs(${obs.id}, event)">
3692
3788
  <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M2 4h12M5 4V3a1 1 0 011-1h4a1 1 0 011 1v1M6 7v5M10 7v5M3 4l1 9a1 1 0 001 1h6a1 1 0 001-1l1-9"/></svg>
@@ -4408,7 +4504,10 @@ async function loadTeam() {
4408
4504
  }
4409
4505
 
4410
4506
  const data = await api('team?scope=' + teamScope);
4411
- if (!data || data.unavailable) {
4507
+ if (!data || data.unavailable || data.status === 'error' || data.status === 'degraded') {
4508
+ const isDegraded = data?.status === 'degraded';
4509
+ const statusTitle = isDegraded ? t('teamStatusDegraded') : (data?.status === 'error' ? t('teamStatusError') : t('teamNoData'));
4510
+ const statusDescription = isDegraded ? t('teamStatusDegradedDesc') : (data?.status === 'error' ? t('teamStatusErrorDesc') : t('teamNoDataHint'));
4412
4511
  container.innerHTML = `
4413
4512
  <div class="page-header">
4414
4513
  <h1 class="page-title">${t('teamTitle')}</h1>
@@ -4417,10 +4516,9 @@ async function loadTeam() {
4417
4516
  <div class="panel">
4418
4517
  <div class="panel-body" style="text-align:center;padding:48px;">
4419
4518
  <div style="font-size:36px;margin-bottom:12px;"><span class="iconify" data-icon="lucide:users" style="font-size:36px;"></span></div>
4420
- <div style="font-size:16px;font-weight:600;color:var(--text-primary);margin-bottom:8px;">${t('teamNoData')}</div>
4519
+ <div style="font-size:16px;font-weight:600;color:var(--text-primary);margin-bottom:8px;">${statusTitle}</div>
4421
4520
  <div style="font-size:13px;color:var(--text-muted);max-width:480px;margin:0 auto;line-height:1.6;">
4422
- ${t('teamNoDataHint')}<br>
4423
- <code style="background:var(--bg-surface);padding:4px 10px;border-radius:6px;margin-top:8px;display:inline-block;font-size:12px;">memorix orchestrate · memorix team status · memorix task list</code>
4521
+ ${statusDescription}<br>
4424
4522
  </div>
4425
4523
  </div>
4426
4524
  </div>
@@ -4679,7 +4777,7 @@ async function loadTeam() {
4679
4777
 
4680
4778
  <div class="panel">
4681
4779
  <div class="panel-header">
4682
- <span class="panel-title">${t('teamTaskBoard')}</span>
4780
+ <span class="panel-title">${t('teamTaskStatus')}</span>
4683
4781
  <span class="team-panel-count">${data.availableTasks || 0} ${t('teamAvailableToClaim')}</span>
4684
4782
  </div>
4685
4783
  <div class="panel-body">
@@ -92,6 +92,15 @@
92
92
  </svg>
93
93
  <span class="nav-label">Observations</span>
94
94
  </button>
95
+ <button class="nav-btn" data-page="evidence" title="Evidence" aria-label="Evidence">
96
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
97
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
98
+ <polyline points="14 2 14 8 20 8"/>
99
+ <line x1="8" y1="13" x2="16" y2="13"/>
100
+ <line x1="8" y1="17" x2="14" y2="17"/>
101
+ </svg>
102
+ <span class="nav-label">Evidence</span>
103
+ </button>
95
104
  </div>
96
105
  <div class="sidebar-section-label" data-section="health">HEALTH</div>
97
106
  <div class="sidebar-nav">
@@ -126,7 +135,7 @@
126
135
  </svg>
127
136
  <span class="nav-label">Sessions</span>
128
137
  </button>
129
- <button class="nav-btn" data-page="team" title="Coordination" aria-label="Coordination">
138
+ <button class="nav-btn" data-page="team" title="Coordination Status" aria-label="Coordination Status">
130
139
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
131
140
  <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
132
141
  <circle cx="9" cy="7" r="4"/>
@@ -175,6 +184,7 @@
175
184
  <div id="page-knowledge" class="page"></div>
176
185
  <div id="page-graph" class="page"></div>
177
186
  <div id="page-observations" class="page"></div>
187
+ <div id="page-evidence" class="page"></div>
178
188
  <div id="page-retention" class="page"></div>
179
189
  <div id="page-config" class="page"></div>
180
190
  <div id="page-identity" class="page"></div>
@@ -64,6 +64,92 @@
64
64
  --transition-emphasized: 500ms cubic-bezier(0.2, 0, 0, 1);
65
65
  }
66
66
 
67
+ /* Evidence Console: provenance is readable at a glance and stays bounded on
68
+ narrow screens; long paths and generated titles never widen the viewport. */
69
+ .evidence-console {
70
+ display: grid;
71
+ gap: 12px;
72
+ min-width: 0;
73
+ }
74
+
75
+ .evidence-card {
76
+ border: 1px solid var(--border-color, rgba(148, 163, 184, .18));
77
+ border-radius: 8px;
78
+ background: var(--surface, rgba(15, 23, 42, .45));
79
+ padding: 16px;
80
+ min-width: 0;
81
+ }
82
+
83
+ .evidence-card-header {
84
+ display: flex;
85
+ gap: 12px;
86
+ align-items: flex-start;
87
+ justify-content: space-between;
88
+ min-width: 0;
89
+ }
90
+
91
+ .evidence-card-heading {
92
+ min-width: 0;
93
+ }
94
+
95
+ .evidence-card-heading h2 {
96
+ margin: 4px 0 0;
97
+ font-size: 16px;
98
+ line-height: 1.35;
99
+ overflow-wrap: anywhere;
100
+ }
101
+
102
+ .evidence-card-kind {
103
+ color: var(--text-muted);
104
+ font-size: 11px;
105
+ text-transform: uppercase;
106
+ }
107
+
108
+ .evidence-card-state {
109
+ display: flex;
110
+ gap: 6px;
111
+ flex: 0 0 auto;
112
+ flex-wrap: wrap;
113
+ justify-content: flex-end;
114
+ }
115
+
116
+ .evidence-state {
117
+ border: 1px solid currentColor;
118
+ border-radius: 999px;
119
+ padding: 3px 7px;
120
+ font-size: 11px;
121
+ white-space: nowrap;
122
+ }
123
+
124
+ .evidence-current, .evidence-verified { color: #4ade80; }
125
+ .evidence-stale, .evidence-conflicted { color: #fb923c; }
126
+ .evidence-unverified { color: var(--text-muted); }
127
+
128
+ .evidence-card-summary {
129
+ margin: 12px 0;
130
+ color: var(--text-secondary, var(--text-muted));
131
+ line-height: 1.55;
132
+ overflow-wrap: anywhere;
133
+ }
134
+
135
+ .evidence-card-meta {
136
+ display: grid;
137
+ grid-template-columns: repeat(3, minmax(0, 1fr));
138
+ gap: 10px;
139
+ margin: 0;
140
+ }
141
+
142
+ .evidence-card-meta div { min-width: 0; }
143
+ .evidence-card-meta dt { color: var(--text-muted); font-size: 11px; margin-bottom: 3px; }
144
+ .evidence-card-meta dd { margin: 0; font-size: 12px; overflow-wrap: anywhere; }
145
+ .evidence-card-warning { margin-top: 10px; color: #fb923c; font-size: 12px; overflow-wrap: anywhere; }
146
+
147
+ @media (max-width: 600px) {
148
+ .evidence-card-header { display: block; }
149
+ .evidence-card-state { justify-content: flex-start; margin-top: 10px; }
150
+ .evidence-card-meta { grid-template-columns: 1fr; }
151
+ }
152
+
67
153
  /* Light Theme - MD3 */
68
154
  [data-theme="light"] {
69
155
  --bg-base: #FFFBFE;
package/dist/index.d.ts CHANGED
@@ -479,7 +479,7 @@ type ToolProfile = 'micro' | 'lite' | 'team' | 'full';
479
479
  * Create and configure the Memorix MCP Server.
480
480
  */
481
481
  /** Optional shared TeamStore — passed by serve-http so all sessions share state */
482
- interface SharedTeamInstances {
482
+ interface SharedTeamStore {
483
483
  teamStore: TeamStore;
484
484
  }
485
485
  interface CreateMemorixServerOptions {
@@ -500,7 +500,7 @@ interface CreateMemorixServerOptions {
500
500
  */
501
501
  projectBinding?: ProjectBindingController;
502
502
  }
503
- declare function createMemorixServer(cwd?: string, existingServer?: McpServer, sharedTeam?: SharedTeamInstances, options?: CreateMemorixServerOptions): Promise<{
503
+ declare function createMemorixServer(cwd?: string, existingServer?: McpServer, sharedTeam?: SharedTeamStore, options?: CreateMemorixServerOptions): Promise<{
504
504
  server: McpServer;
505
505
  graphManager: KnowledgeGraphManager;
506
506
  projectId: string;