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.
- package/CHANGELOG.md +41 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/cli/index.js +1488 -270
- package/dist/dashboard/static/app.js +125 -27
- package/dist/dashboard/static/index.html +11 -1
- package/dist/dashboard/static/style.css +86 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +927 -240
- package/dist/maintenance-runner.js +607 -68
- package/dist/media-audio-runner.js +602 -63
- package/dist/media-video-runner.js +607 -68
- package/dist/memcode-runtime/CHANGELOG.md +41 -0
- package/dist/sdk.js +926 -239
- package/dist/types.d.ts +8 -0
- package/dist/vector-backfill-runner.js +607 -68
- package/docs/1.2.4-PERSISTENT-MEMORY-DELIVERY.md +1 -1
- package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +75 -0
- package/docs/API_REFERENCE.md +39 -1
- package/docs/ARCHITECTURE.md +3 -1
- package/docs/DASHBOARD.md +16 -0
- package/docs/DEVELOPMENT.md +3 -2
- package/docs/INTEGRATIONS.md +1 -1
- package/docs/README.md +15 -2
- package/package.json +1 -1
- package/plugins/antigravity/memorix/rules/memorix.md +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/memorix/SKILL.md +1 -1
- package/plugins/claude/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/copilot/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/cursor/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/gemini/memorix/GEMINI.md +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/plugins/pi/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/server.json +2 -2
- package/src/cli/capability-map.ts +2 -0
- package/src/cli/commands/context.ts +11 -0
- package/src/cli/commands/dashboard.ts +1 -1
- package/src/cli/commands/evidence.ts +56 -0
- package/src/cli/commands/feedback.ts +58 -0
- package/src/cli/commands/resume.ts +2 -0
- package/src/cli/commands/serve-http.ts +229 -13
- package/src/cli/fallback-budget.ts +59 -0
- package/src/cli/index.ts +5 -1
- package/src/compact/engine.ts +26 -1
- package/src/config/dotenv-loader.ts +17 -0
- package/src/dashboard/config-provenance.ts +17 -0
- package/src/dashboard/evidence.ts +63 -0
- package/src/dashboard/server.ts +178 -154
- package/src/dashboard/static/index.html +11 -1
- package/src/dashboard/static/style.css +86 -0
- package/src/hooks/installers/index.ts +1 -1
- package/src/hooks/official-skills.ts +3 -3
- package/src/hooks/rules/memorix-agent-rules.md +1 -1
- package/src/memory/feedback-model.ts +4 -0
- package/src/memory/feedback.ts +220 -0
- package/src/memory/observations.ts +19 -0
- package/src/memory/retention.ts +38 -5
- package/src/server/mcp-binding-store.ts +79 -0
- package/src/server/mcp-diagnostics.ts +40 -0
- package/src/server/tool-profile.ts +4 -0
- package/src/server.ts +125 -5
- package/src/store/evidence-store.ts +261 -0
- package/src/store/sqlite-db.ts +104 -0
- 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: '
|
|
134
|
-
teamNoData: 'No coordination
|
|
135
|
-
teamNoDataHint: '
|
|
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
|
-
|
|
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
|
|
458
|
-
modeControlPlaneHint: 'HTTP control plane - shared MCP access and
|
|
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: '
|
|
598
|
-
teamNoData: '
|
|
599
|
-
teamNoDataHint: '
|
|
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
|
-
|
|
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
|
-
|
|
1131
|
-
|
|
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
|
-
|
|
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;">${
|
|
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
|
-
${
|
|
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('
|
|
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
|
|
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?:
|
|
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;
|