memorix 1.7.2 → 1.8.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 (90) hide show
  1. package/CHANGELOG.md +59 -1
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/assets/star-history-dark.svg +4 -4
  5. package/assets/star-history-light.svg +4 -4
  6. package/assets/star-history.json +47 -3
  7. package/dist/cli/index.js +1801 -254
  8. package/dist/dashboard/static/app.js +88 -4
  9. package/dist/dashboard/static/index.html +10 -0
  10. package/dist/dashboard/static/style.css +86 -0
  11. package/dist/index.js +1241 -224
  12. package/dist/maintenance-runner.js +972 -126
  13. package/dist/media-audio-runner.js +967 -121
  14. package/dist/media-video-runner.js +972 -126
  15. package/dist/memcode-runtime/CHANGELOG.md +59 -1
  16. package/dist/sdk.js +1240 -223
  17. package/dist/types.d.ts +8 -0
  18. package/dist/vector-backfill-runner.js +972 -126
  19. package/docs/1.2.4-PERSISTENT-MEMORY-DELIVERY.md +1 -1
  20. package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +75 -0
  21. package/docs/API_REFERENCE.md +37 -1
  22. package/docs/ARCHITECTURE.md +1 -1
  23. package/docs/CONFIGURATION.md +57 -1
  24. package/docs/DASHBOARD.md +10 -0
  25. package/docs/DEVELOPMENT.md +3 -2
  26. package/docs/INTEGRATIONS.md +1 -1
  27. package/docs/PERFORMANCE.md +3 -1
  28. package/docs/README.md +11 -1
  29. package/docs/SETUP.md +2 -1
  30. package/package.json +1 -1
  31. package/plugins/antigravity/memorix/rules/memorix.md +1 -1
  32. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  33. package/plugins/claude/memorix/SKILL.md +1 -1
  34. package/plugins/claude/memorix/skills/memorix-memory/SKILL.md +2 -2
  35. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  36. package/plugins/codebuddy/memorix/skills/memorix-memory/SKILL.md +2 -2
  37. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  38. package/plugins/codex/memorix/skills/memorix-memory/SKILL.md +2 -2
  39. package/plugins/copilot/memorix/plugin.json +1 -1
  40. package/plugins/copilot/memorix/skills/memorix-memory/SKILL.md +2 -2
  41. package/plugins/cursor/memorix/skills/memorix-memory/SKILL.md +2 -2
  42. package/plugins/gemini/memorix/GEMINI.md +1 -1
  43. package/plugins/gemini/memorix/gemini-extension.json +1 -1
  44. package/plugins/omp/memorix/package.json +1 -1
  45. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  46. package/plugins/pi/memorix/package.json +1 -1
  47. package/plugins/pi/memorix/skills/memorix-memory/SKILL.md +2 -2
  48. package/server.json +2 -2
  49. package/src/cli/capability-map.ts +2 -0
  50. package/src/cli/commands/config-migrate.ts +7 -0
  51. package/src/cli/commands/context.ts +11 -0
  52. package/src/cli/commands/doctor.ts +5 -1
  53. package/src/cli/commands/evidence.ts +56 -0
  54. package/src/cli/commands/feedback.ts +58 -0
  55. package/src/cli/commands/init.ts +17 -0
  56. package/src/cli/commands/resume.ts +2 -0
  57. package/src/cli/commands/serve-http.ts +201 -12
  58. package/src/cli/commands/status.ts +2 -0
  59. package/src/cli/fallback-budget.ts +59 -0
  60. package/src/cli/index.ts +5 -1
  61. package/src/compact/engine.ts +26 -1
  62. package/src/config/dotenv-loader.ts +17 -0
  63. package/src/config/resolved-config.ts +110 -12
  64. package/src/config/toml-loader.ts +8 -0
  65. package/src/config/yaml-loader.ts +9 -0
  66. package/src/dashboard/config-provenance.ts +17 -0
  67. package/src/dashboard/evidence.ts +63 -0
  68. package/src/dashboard/server.ts +93 -68
  69. package/src/dashboard/static/index.html +10 -0
  70. package/src/dashboard/static/style.css +86 -0
  71. package/src/hooks/installers/index.ts +1 -1
  72. package/src/hooks/official-skills.ts +3 -3
  73. package/src/hooks/rules/memorix-agent-rules.md +1 -1
  74. package/src/llm/provider.ts +33 -7
  75. package/src/memory/feedback-model.ts +4 -0
  76. package/src/memory/feedback.ts +220 -0
  77. package/src/memory/observations.ts +19 -0
  78. package/src/memory/retention.ts +38 -5
  79. package/src/multimodal/image-loader.ts +6 -3
  80. package/src/rerank/http-provider.ts +125 -0
  81. package/src/rerank/index.ts +81 -0
  82. package/src/rerank/policy.ts +88 -0
  83. package/src/server/mcp-binding-store.ts +79 -0
  84. package/src/server/mcp-diagnostics.ts +40 -0
  85. package/src/server/tool-profile.ts +4 -0
  86. package/src/server.ts +121 -1
  87. package/src/store/evidence-store.ts +261 -0
  88. package/src/store/orama-store.ts +79 -53
  89. package/src/store/sqlite-db.ts +104 -0
  90. 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',
@@ -428,6 +441,7 @@ const i18n = {
428
441
  navKnowledge: 'Memory Overview',
429
442
  navGraph: 'Memory Map',
430
443
  navObservations: 'Observations',
444
+ navEvidence: 'Evidence',
431
445
  navRetention: 'Retention',
432
446
  navConfig: 'Config',
433
447
  navIdentity: 'Identity',
@@ -438,6 +452,7 @@ const i18n = {
438
452
  navLabelKnowledge: 'Knowledge',
439
453
  navLabelGraph: 'Graph',
440
454
  navLabelObservations: 'Observations',
455
+ navLabelEvidence: 'Evidence',
441
456
  navLabelRetention: 'Retention',
442
457
  navLabelConfig: 'Config',
443
458
  navLabelIdentity: 'Identity',
@@ -479,6 +494,7 @@ const i18n = {
479
494
  entities: '实体',
480
495
  relations: '关系',
481
496
  observations: '观察记录',
497
+ evidence: '证据',
482
498
  nextId: '下一个 ID',
483
499
  observationTypes: '观察类型分布',
484
500
  recentActivity: '最近活动',
@@ -506,6 +522,18 @@ const i18n = {
506
522
  noMatchingObs: '没有匹配的观察记录',
507
523
  noObsTitle: '暂无观察记录',
508
524
  noObsDesc: '使用 memorix_store 创建观察记录',
525
+ evidenceSubtitle: '查看记忆为何可信、来自哪里,以及是否仍然有效',
526
+ evidenceSource: '来源',
527
+ evidenceLocator: '定位',
528
+ evidenceFreshness: '新鲜度',
529
+ evidenceCurrent: '当前',
530
+ evidenceStale: '已过期',
531
+ evidenceVerified: '已验证',
532
+ evidenceUnverified: '未验证',
533
+ evidenceConflicted: '有冲突',
534
+ evidenceNoCards: '暂无证据卡',
535
+ evidenceNoCardsDesc: '写入或同步项目记忆后,这里会显示来源和审计信息。',
536
+ evidenceEvents: '审计事件',
509
537
  untitled: '无标题',
510
538
  unknown: '未知',
511
539
  lowQuality: '清理候选',
@@ -897,6 +925,7 @@ const i18n = {
897
925
  navKnowledge: '记忆概览',
898
926
  navGraph: '记忆关系图',
899
927
  navObservations: '观察记录',
928
+ navEvidence: '证据',
900
929
  navRetention: '记忆衰减',
901
930
  navConfig: '配置溯源',
902
931
  navIdentity: '身份健康',
@@ -907,6 +936,7 @@ const i18n = {
907
936
  navLabelKnowledge: '知识库',
908
937
  navLabelGraph: '图谱',
909
938
  navLabelObservations: '观察',
939
+ navLabelEvidence: '证据',
910
940
  navLabelRetention: '衰减',
911
941
  navLabelConfig: '配置',
912
942
  navLabelIdentity: '身份',
@@ -970,8 +1000,8 @@ function setLang(lang) {
970
1000
  if (label) label.textContent = lang === 'en' ? '中文' : 'EN';
971
1001
 
972
1002
  // 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' };
1003
+ 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' };
1004
+ 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
1005
  document.querySelectorAll('.nav-btn').forEach(b => {
976
1006
  const page = b.dataset.page;
977
1007
  if (page && tooltipMap[page]) b.title = t(tooltipMap[page]);
@@ -1062,7 +1092,7 @@ onDomReady(() => {
1062
1092
  // Router & Navigation
1063
1093
  // ============================================================
1064
1094
 
1065
- const pages = ['dashboard', 'git-memory', 'knowledge', 'graph', 'observations', 'retention', 'config', 'identity', 'sessions', 'team'];
1095
+ const pages = ['dashboard', 'git-memory', 'knowledge', 'graph', 'observations', 'evidence', 'retention', 'config', 'identity', 'sessions', 'team'];
1066
1096
  let currentPage = 'dashboard';
1067
1097
 
1068
1098
  function navigate(page) {
@@ -1569,6 +1599,7 @@ async function loadPage(page) {
1569
1599
  case 'knowledge': await loadKnowledge(); break;
1570
1600
  case 'graph': await loadGraph(); break;
1571
1601
  case 'observations': await loadObservations(); break;
1602
+ case 'evidence': await loadEvidence(); break;
1572
1603
  case 'retention': await loadRetention(); break;
1573
1604
  case 'config': await loadConfig(); break;
1574
1605
  case 'identity': await loadIdentity(); break;
@@ -3632,6 +3663,51 @@ async function loadObservations() {
3632
3663
  renderObsList();
3633
3664
  }
3634
3665
 
3666
+ async function loadEvidence() {
3667
+ const container = document.getElementById('page-evidence');
3668
+ container.innerHTML = '<div class="loading"><div class="spinner"></div></div>';
3669
+ const data = await api('evidence') || { cards: [] };
3670
+ const cards = data.cards || [];
3671
+ if (cards.length === 0) {
3672
+ container.innerHTML = emptyState('<span class="iconify" data-icon="lucide:file-check-2" style="font-size:36px;"></span>', t('evidenceNoCards'), t('evidenceNoCardsDesc'));
3673
+ return;
3674
+ }
3675
+ container.innerHTML = `
3676
+ <div class="page-header">
3677
+ <h1 class="page-title">${t('evidence')}</h1>
3678
+ <p class="page-subtitle">${t('evidenceSubtitle')}</p>
3679
+ </div>
3680
+ <div class="evidence-console" role="list">
3681
+ ${cards.map((card) => {
3682
+ const freshness = card.freshness === 'stale' ? t('evidenceStale') : t('evidenceCurrent');
3683
+ const verification = card.verification === 'verified' ? t('evidenceVerified') : card.verification === 'conflicted' ? t('evidenceConflicted') : t('evidenceUnverified');
3684
+ const eventCount = (card.events || []).length;
3685
+ return `
3686
+ <article class="evidence-card" role="listitem">
3687
+ <div class="evidence-card-header">
3688
+ <div class="evidence-card-heading">
3689
+ <span class="evidence-card-kind">${escapeHtml(card.sourceKind || 'memory')}</span>
3690
+ <h2>${escapeHtml(card.title || t('untitled'))}</h2>
3691
+ </div>
3692
+ <div class="evidence-card-state">
3693
+ <span class="evidence-state evidence-${card.freshness === 'stale' ? 'stale' : 'current'}">${escapeHtml(freshness)}</span>
3694
+ <span class="evidence-state evidence-${card.verification === 'verified' ? 'verified' : card.verification === 'conflicted' ? 'conflicted' : 'unverified'}">${escapeHtml(verification)}</span>
3695
+ </div>
3696
+ </div>
3697
+ <p class="evidence-card-summary">${escapeHtml(card.summary || '')}</p>
3698
+ <dl class="evidence-card-meta">
3699
+ <div><dt>${t('evidenceSource')}</dt><dd>${escapeHtml(card.sourceRef || 'unknown')}</dd></div>
3700
+ <div><dt>${t('evidenceLocator')}</dt><dd>${escapeHtml(card.locator || 'not recorded')}</dd></div>
3701
+ <div><dt>${t('evidenceEvents')}</dt><dd>${eventCount}</dd></div>
3702
+ </dl>
3703
+ ${card.staleReason ? `<div class="evidence-card-warning">${escapeHtml(card.staleReason)}</div>` : ''}
3704
+ </article>
3705
+ `;
3706
+ }).join('')}
3707
+ </div>
3708
+ `;
3709
+ }
3710
+
3635
3711
  function renderObsList() {
3636
3712
  const list = document.getElementById('obs-list');
3637
3713
  if (!list) return;
@@ -3686,7 +3762,15 @@ function renderObsList() {
3686
3762
  ${obs.narrative ? `<div class="obs-detail-section"><label>${t('narrative')}</label><div class="obs-card-narrative">${hl(obs.narrative)}</div></div>` : ''}
3687
3763
  ${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
3764
  ${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>` : ''}
3765
+ ${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>` : ''}
3766
+ <div class="obs-detail-section evidence-provenance" aria-label="Evidence provenance">
3767
+ <label>Evidence</label>
3768
+ <div class="obs-card-meta">
3769
+ <span>Source: ${escapeHtml(obs.sourceDetail || obs.source || 'unknown')}</span>
3770
+ ${obs.sessionId ? `<span>Session: ${escapeHtml(obs.sessionId)}</span>` : ''}
3771
+ ${obs.status ? `<span>Verification: ${obs.status === 'resolved' ? 'verified' : obs.status === 'archived' ? 'conflicted' : 'unverified'}</span>` : ''}
3772
+ </div>
3773
+ </div>
3690
3774
  <div class="obs-detail-actions">
3691
3775
  <button class="delete-btn" onclick="deleteObs(${obs.id}, event)">
3692
3776
  <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>
@@ -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">
@@ -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;