@sanqianx/project-knowledge 5.0.9-rc.9 → 5.0.10-rc.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 (39) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +140 -0
  3. package/README.md +11 -4
  4. package/_modules/knowledge-engine/README.md +9 -1
  5. package/_modules/knowledge-engine/package.json +1 -1
  6. package/_modules/knowledge-engine/src/coordinator.js +11 -2
  7. package/_modules/knowledge-engine/src/headless-analyzer.js +2 -1
  8. package/_modules/knowledge-engine/src/memories.js +133 -24
  9. package/_modules/knowledge-engine/src/retrieval.js +19 -4
  10. package/_modules/knowledge-engine/src/runtime/contracts.js +1 -0
  11. package/_modules/knowledge-engine/src/runtime/knowledge-promotion.js +6 -2
  12. package/_modules/knowledge-engine/src/runtime/markdown-knowledge-indexer.js +7 -2
  13. package/_modules/knowledge-engine/src/server.js +1 -1
  14. package/_modules/knowledge-engine/src/store.js +9 -6
  15. package/_site/_test/bin-cli-test.js +15 -2
  16. package/_site/_test/mcp-server-test.js +1 -1
  17. package/_site/_test/module-agent-start-proxy-test.js +65 -0
  18. package/_site/_test/module-bridge-eventbridge-test.js +1 -1
  19. package/_site/_test/module-wiring-unbind-race-test.js +59 -0
  20. package/_site/_test/path-consistency-test.js +1 -1
  21. package/_site/_test/product-diagnostics-ui-test.js +5 -1
  22. package/_site/_test/product-progress-status-test.js +70 -0
  23. package/_site/_test/shared-scope-root-binding-test.js +67 -0
  24. package/_site/_test/test-server-cleanup-test.js +5 -1
  25. package/_site/_test/vector-storage-root-test.js +16 -0
  26. package/_site/lib/engine-connection.js +4 -1
  27. package/_site/lib/knowledge-tool-runtime.js +1 -1
  28. package/_site/lib/module-bridge.js +65 -8
  29. package/_site/lib/server-app.js +4 -2
  30. package/_site/lib/settings-store.js +20 -0
  31. package/module-runtime-manifest.json +41 -41
  32. package/package.json +3 -3
  33. package/plugins/project-knowledge/.claude-plugin/plugin.json +1 -1
  34. package/plugins/project-knowledge/.codex-plugin/plugin.json +1 -1
  35. package/plugins/project-knowledge/.mcp.json +1 -1
  36. package/ui/index.html +2 -2
  37. package/ui/product.css +1 -0
  38. package/ui/product.js +62 -10
  39. package/vendor-manifest.json +12 -12
package/ui/product.js CHANGED
@@ -105,8 +105,40 @@
105
105
  }
106
106
  function renderMemories() {
107
107
  all('[data-memory-tab]').forEach(button => button.classList.toggle('active', button.dataset.memoryTab === state.memoryTab));
108
- const memories = state.snapshot.memories.filter(m => m.status === state.memoryTab);
109
- $('memoryContent').innerHTML = !state.engineAvailable ? '<div class="empty">知识引擎暂时不可用。未读取到的记忆不会显示为已确认。</div>' : memories.length ? `<div class="memory-grid">${memories.map(m => `<article class="memory-card"><p>${esc(m.text)}</p><small>${esc(projectName(m.evidence.projectId))} · commit ${esc(m.evidence.commitSha.slice(0, 8))}<br>${esc(m.evidence.entryId)}</small><div class="actions"><button data-memory-action="evidence" data-memory-id="${esc(m.id)}">查看依据</button><button data-memory-action="edit" data-memory-id="${esc(m.id)}">编辑</button>${m.status === 'candidate' ? `<button class="primary" data-memory-action="confirm" data-memory-id="${esc(m.id)}">确认</button><button data-memory-action="ignore" data-memory-id="${esc(m.id)}">忽略</button>` : badge('已确认', 'up')}</div></article>`).join('')}</div>` : `<div class="empty">${state.memoryTab === 'confirmed' ? '还没有已确认的长期记忆。' : '候选箱为空。维护产物中的有据偏好会进入这里,等待你的确认。'}</div>`;
108
+ const type = $('memoryScopeFilter').value, target = $('memoryTargetFilter').value;
109
+ const memories = state.snapshot.memories.filter(m => m.status === state.memoryTab && (!type || (m.scopeType || 'global') === type) && (!type || type === 'global' || !target || m.scopeId === target));
110
+ $('memoryContent').innerHTML = !state.engineAvailable ? '<div class="empty">知识引擎暂时不可用。未读取到的记忆不会显示为已确认。</div>' : memories.length ? `<div class="memory-grid">${memories.map(m => `<article class="memory-card" data-memory-card="${esc(m.id)}"><div class="memory-meta">${badge(memoryScopeName(m))}${m.targetAvailable === false ? badge('目标已失效,不会注入', 'issue') : m.status === 'confirmed' && m.syncStatus === 'pending' ? badge('写入待恢复', 'issue') : m.status === 'confirmed' && m.indexStatus === 'failed' ? badge('索引待恢复', 'issue') : m.status === 'confirmed' && m.indexStatus === 'pending' ? badge('索引更新中') : ''}</div><p>${esc(m.text)}</p><small>来源:${esc(projectName(m.evidence.projectId))} · commit ${esc(m.evidence.commitSha.slice(0, 8))}<br>${esc(m.evidence.entryId)}</small><div class="actions"><button data-memory-action="evidence" data-memory-id="${esc(m.id)}">查看依据</button>${m.status === 'candidate' ? `<button class="primary" data-memory-action="confirm" data-memory-id="${esc(m.id)}">审核确认</button><button data-memory-action="ignore" data-memory-id="${esc(m.id)}">忽略</button>` : `<button data-memory-action="edit" data-memory-id="${esc(m.id)}">编辑</button>${badge(m.syncStatus === 'pending' ? '待同步' : '已确认', m.syncStatus === 'pending' ? 'issue' : 'up')}`}</div></article>`).join('')}</div>` : `<div class="empty">${type ? '此范围内没有匹配的记忆。' : state.memoryTab === 'confirmed' ? '还没有已确认的长期记忆。' : '候选箱为空。维护产物中的有据偏好会进入这里,等待你的确认。'}</div>`;
111
+ }
112
+ function memoryScopeName(memory) {
113
+ const type = memory.scopeType || 'global';
114
+ return type === 'global' ? '全局 · 所有领域与项目' : `${type === 'domain' ? '领域' : '项目'} · ${type === 'domain' ? domainName(memory.scopeId) : projectName(memory.scopeId)}`;
115
+ }
116
+ function memoryTargets(type) { return type === 'domain' ? state.brain.domains : type === 'project' ? state.projects.map(p => ({ id: p.projectId, name: p.name })) : []; }
117
+ function updateMemoryTarget(type, selected = '') {
118
+ const options = memoryTargets(type);
119
+ $('memoryTargetLabel').hidden = type === 'global'; $('memoryTarget').required = type !== 'global'; $('memoryTarget').disabled = type === 'global';
120
+ $('memoryTarget').innerHTML = '<option value="">请选择适用目标</option>' + options.map(p => `<option value="${esc(p.id)}">${esc(p.name)}</option>`).join('');
121
+ $('memoryTarget').value = selected;
122
+ $('memoryScopeHint').textContent = type === 'global' ? '确认后可用于所有领域和项目。' : type === 'domain' ? '只用于所选领域当前所属的项目。可改选其他已有领域。' : '只用于所选项目。可改选其他已有项目。';
123
+ }
124
+ function updateMemoryFilter() {
125
+ const type = $('memoryScopeFilter').value, previous = $('memoryTargetFilter').value;
126
+ $('memoryTargetFilter').hidden = !['domain', 'project'].includes(type);
127
+ $('memoryTargetFilter').innerHTML = '<option value="">全部目标</option>' + memoryTargets(type).map(p => `<option value="${esc(p.id)}">${esc(p.name)}</option>`).join('');
128
+ $('memoryTargetFilter').value = memoryTargets(type).some(p => p.id === previous) ? previous : '';
129
+ renderMemories();
130
+ }
131
+ function openMemory(memory) {
132
+ editingMemoryId = memory.id;
133
+ $('memoryDialogTitle').textContent = memory.status === 'candidate' ? '审核并确认记忆' : '编辑已确认记忆';
134
+ $('memoryText').value = memory.text; $('memoryScope').value = memory.scopeType || 'global';
135
+ updateMemoryTarget($('memoryScope').value, memory.scopeId || memory.brainId);
136
+ $('memoryOriginal').textContent = `原始总结:${memory.originalText || memory.text}`;
137
+ $('memoryEvidence').textContent = `${projectName(memory.evidence.projectId)} · ${memory.evidence.commitSha} / ${memory.evidence.entryId}`;
138
+ $('memoryQuote').textContent = memory.evidence.quote;
139
+ $('memoryFeedback').hidden = true; $('saveMemoryCandidate').hidden = memory.status !== 'candidate';
140
+ $('confirmMemory').textContent = memory.status === 'candidate' ? '确认并保存' : '保存修改';
141
+ $('memoryDialog').showModal();
110
142
  }
111
143
  function renderActivity() {
112
144
  all('[data-activity-tab]').forEach(button => button.classList.toggle('active', button.dataset.activityTab === state.activityTab));
@@ -131,7 +163,7 @@
131
163
  $('referenceTitle').textContent = reference.title || reference.entryId;
132
164
  $('referenceMeta').textContent = `${projectName(reference.projectId)} / ${reference.entryId}${reference.commitSha ? ` · commit ${reference.commitSha}` : ''}`;
133
165
  $('referenceContent').textContent = reference.text || '读取知识文件…'; $('referenceDialog').showModal();
134
- if (reference.entryId) {
166
+ if (reference.entryId && reference.readFile !== false) {
135
167
  const result = await api('/api/engine/get', { method: 'POST', body: { projectId: state.projects.some(p => p.projectId === reference.projectId) ? reference.projectId : id, spaceId: reference.spaceId, entryId: reference.entryId } });
136
168
  if (epoch === referenceEpoch && id === state.projectId && $('referenceDialog').open) $('referenceContent').textContent = result.chunks.map(c => c.chunk_text).join('\n');
137
169
  }
@@ -160,8 +192,9 @@
160
192
  if (epoch !== registryEpoch) return;
161
193
  state.brain = brain.brain; state.root = brain.knowledgeRoot; state.projects = projects.projects; state.health = health.modules; state.ownership = health.ownership;
162
194
  state.indexStorage = { path: brain.indexStoragePath, ...brain.configuration?.indexStorage };
195
+ state.scopeStatus = brain.configuration?.scopeStatus;
163
196
  if (!activeProject()) { state.projectId = state.projects[0]?.projectId || ''; state.epoch++; Object.keys(frames).forEach(frameContext); }
164
- renderProjectOptions(); renderSystem(); connectProgress(); await refreshSnapshot(); setView(state.view);
197
+ renderProjectOptions(); renderSystem(); connectProgress(); await refreshSnapshot(); updateMemoryFilter(); setView(state.view);
165
198
  } catch (error) { toast(error.message); }
166
199
  finally { if (epoch === registryEpoch) { registryPromise = null; connectProgress(); } }
167
200
  })();
@@ -177,6 +210,7 @@
177
210
  $('systemTitle').textContent = pending ? '知识引擎连接待恢复' : down.length ? '部分服务需要处理' : '系统连接正常';
178
211
  $('systemDetail').textContent = pending ? `${state.ownership.message || '服务恢复后自动重试。'}${state.ownership.error ? ` · ${state.ownership.error.step} (${state.ownership.error.code})` : ''}` : down.length ? down.map(k => modules[k]).join('、') : '本机知识服务已连接';
179
212
  if (storagePending && !pending && !down.length) { $('systemDot').className = 'dot issue'; $('systemTitle').textContent = '索引目录接线待恢复'; $('systemDetail').textContent = `目标目录:${state.indexStorage.expectedPath}。请在系统状态中修复接线。`; }
213
+ if (state.root && state.scopeStatus?.status === 'pending' && !pending && !down.length) { $('systemDot').className = 'dot issue'; $('systemTitle').textContent = '共享知识接线待恢复'; $('systemDetail').textContent = '已有知识与长期记忆保留,请在系统状态中修复接线。'; }
180
214
  $('moduleHealth').innerHTML = Object.entries(modules).map(([key, name]) => `<div class="row"><div><b>${esc(name)}</b><small>${esc(state.health[key]?.url || '')}</small></div>${badge(state.health[key]?.up ? '在线' : '离线', state.health[key]?.up ? 'up' : 'issue')}</div>`).join('');
181
215
  if (!navigator.onLine) {
182
216
  $('systemDot').className = 'dot issue'; $('systemTitle').textContent = '网页连接中断';
@@ -352,9 +386,9 @@
352
386
  if (button.dataset.memoryAction) {
353
387
  const memory = state.snapshot.memories.find(m => m.id === button.dataset.memoryId); if (!memory) return;
354
388
  const action = button.dataset.memoryAction;
355
- if (action === 'evidence') await openReference({ ...memory.evidence, text: memory.evidence.quote, title: '记忆来源依据' });
356
- else if (action === 'edit') { editingMemoryId = memory.id; $('memoryText').value = memory.text; $('memoryEvidence').textContent = `${projectName(memory.evidence.projectId)} · ${memory.evidence.commitSha.slice(0, 8)} / ${memory.evidence.entryId}`; $('memoryDialog').showModal(); }
357
- else { await api(`/api/engine/memories/${encodeURIComponent(memory.id)}`, { method: 'PATCH', body: { status: action === 'confirm' ? 'confirmed' : 'ignored' } }); await refreshSnapshot(); }
389
+ if (action === 'evidence') await openReference({ ...memory.evidence, readFile: false, text: memory.evidence.quote, title: '记忆来源依据(冻结原文)' });
390
+ else if (action === 'edit' || action === 'confirm') openMemory(memory);
391
+ else { await api(`/api/engine/memories/${encodeURIComponent(memory.id)}`, { method: 'PATCH', body: { status: 'ignored' } }); await refreshSnapshot(); }
358
392
  }
359
393
  };
360
394
  execute().catch(error => toast(error.message));
@@ -385,7 +419,7 @@
385
419
  on('embeddingForm', 'submit', async event => { event.preventDefault(); await saveEmbedding(); });
386
420
  on('disableEmbedding', 'click', () => saveEmbedding(false));
387
421
  on('embeddingDialog', 'close', () => { $('embeddingSecret').value = ''; });
388
- on('saveBrainSettings', 'click', async () => { await api('/api/brain', { method: 'PATCH', body: { name: $('brainName').value } }); const saved = await api('/api/settings', { method: 'PATCH', body: { knowledge: { rootPath: $('knowledgeRoot').value } } }); toast(saved.configuration?.indexStorage?.status === 'ready' ? '设置已保存,索引目录已生效;已有知识未移动。' : '设置已保存,索引目录接线待恢复;已有知识保留。'); await refreshRegistry(true); if (resumeImport) closeSystem(); });
422
+ on('saveBrainSettings', 'click', async () => { await api('/api/brain', { method: 'PATCH', body: { name: $('brainName').value } }); const saved = await api('/api/settings', { method: 'PATCH', body: { knowledge: { rootPath: $('knowledgeRoot').value } } }); toast(saved.configuration?.scopeStatus?.status === 'pending' ? '设置已保存,共享知识接线待恢复;已有知识保留。' : saved.configuration?.indexStorage?.status === 'ready' ? '设置已保存,索引目录已生效;已有知识未移动。' : '设置已保存,索引目录接线待恢复;已有知识保留。'); await refreshRegistry(true); if (resumeImport) closeSystem(); });
389
423
  on('setupImportRoot', 'click', async () => { $('importDialog').close(); resumeImport = true; await openSystem(); $('knowledgeRoot').focus(); });
390
424
  on('pickRoot', 'click', () => pick('knowledgeRoot')); on('pickCode', 'click', () => pick('importCode')); on('pickKnowledge', 'click', () => pick('importKnowledge'));
391
425
  on('openEngine', 'click', () => { closeSystem(); initializeFrame('engine'); $('engineDialog').showModal(); post('engine', { type: 'kb:visibility', visible: true }); });
@@ -403,7 +437,25 @@
403
437
  on('exportLogs', 'click', async () => { const params = new URLSearchParams({ q: $('logsSearch').value.trim() }); if ($('logsScope').value === 'project' && state.projectId) params.set('projectId', state.projectId); const response = await fetch(`/api/logs/export?${params}`); if (!response.ok) throw new Error('诊断导出失败。'); const blob = await response.blob(); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = 'knowledge-diagnostics.jsonl'; link.click(); setTimeout(() => URL.revokeObjectURL(url), 1000); });
404
438
  on('createDomain', 'click', () => { $('domainForm').reset(); $('domainDialog').showModal(); });
405
439
  on('domainForm', 'submit', async e => { e.preventDefault(); await api('/api/domains', { method: 'POST', body: Object.fromEntries(new FormData(e.target)) }); $('domainDialog').close(); await refreshRegistry(true); });
406
- on('memoryForm', 'submit', async e => { e.preventDefault(); await api(`/api/engine/memories/${encodeURIComponent(editingMemoryId)}`, { method: 'PATCH', body: { text: $('memoryText').value } }); $('memoryDialog').close(); await refreshSnapshot(); });
440
+ on('memoryScopeFilter', 'change', updateMemoryFilter); on('memoryTargetFilter', 'change', renderMemories);
441
+ on('memoryScope', 'change', () => {
442
+ const memory = state.snapshot.memories.find(m => m.id === editingMemoryId), type = $('memoryScope').value;
443
+ const source = state.projects.find(p => p.projectId === memory?.evidence.projectId);
444
+ updateMemoryTarget(type, type === 'project' ? source?.projectId : type === 'domain' ? source?.domainId : '');
445
+ });
446
+ on('memoryForm', 'submit', async e => {
447
+ e.preventDefault();
448
+ if ($('confirmMemory').disabled) return;
449
+ const type = $('memoryScope').value, body = { text: $('memoryText').value, scopeType: type, scopeId: type === 'global' ? state.brain.id : $('memoryTarget').value };
450
+ if (e.submitter?.dataset.mode === 'confirmed') body.status = 'confirmed';
451
+ $('confirmMemory').disabled = true; $('saveMemoryCandidate').disabled = true;
452
+ try {
453
+ const result = await api(`/api/engine/memories/${encodeURIComponent(editingMemoryId)}`, { method: 'PATCH', body });
454
+ $('memoryDialog').close(); await refreshSnapshot();
455
+ toast(result.memory.syncStatus === 'pending' ? '确认已保存,记忆文件待恢复;未同步内容不会注入任务。' : body.status === 'confirmed' ? '记忆内容与适用范围已确认。' : '候选已保存,尚未生效。');
456
+ } catch (error) { $('memoryFeedback').textContent = error.message; $('memoryFeedback').hidden = false; }
457
+ finally { $('confirmMemory').disabled = false; $('saveMemoryCandidate').disabled = false; }
458
+ });
407
459
  on('unbindForm', 'submit', async e => {
408
460
  e.preventDefault(); if (!unbindProjectId || unbinding) return;
409
461
  const projectId = unbindProjectId;
@@ -449,7 +501,7 @@
449
501
  renderSystem(); render();
450
502
  });
451
503
  window.addEventListener('online', () => {
452
- $('activityConnection').textContent = '正在恢复快照'; refreshRegistry();
504
+ $('activityConnection').textContent = state.engineAvailable && state.stream?.readyState === EventSource.OPEN ? '已连接实时更新' : '正在恢复快照'; refreshRegistry();
453
505
  if ($('logsDialog').open) loadLogs().catch(error => toast(error.message));
454
506
  });
455
507
  window.addEventListener('beforeunload', () => { state.stream?.close(); logStream?.close(); });
@@ -3,23 +3,23 @@
3
3
  "modules": {
4
4
  "knowledge-engine": {
5
5
  "name": "@sanqianx/ai-coding-knowledge-engine",
6
- "version": "0.2.3-rc.4",
6
+ "version": "0.2.4-rc.1",
7
7
  "root": "_modules/knowledge-engine",
8
8
  "files": {
9
- "README.md": "df15aafdfe833186c1f655a1847171435214b96ad168c5eb44774fec82d28cf6",
10
- "package.json": "61e95ac2871a4e4e8964851161aac3c7fe4ef5015c8d03ec6ff1e9e53bbaa43f",
9
+ "README.md": "d1c821dca4fba483d1ae1d9ade3672acdf4e71aae81cb359e6be8a8b959f8c77",
10
+ "package.json": "5fd307694b04ed67dcb67fc9c1477a9a79d450647c558a38cfbfad8933364f34",
11
11
  "src/analysis-contract.js": "fee063967d32eefc955cf0729f7dc8cb31bd690b85e22471c9059494a599c77a",
12
12
  "src/analysis-output.js": "95a3c19dcc9ab85d1dba7fee5b9aec80f9c000dfba89da3fd0be25a81e2fb680",
13
13
  "src/analysis-worker.js": "a105cabe6e1573b2d986b1e7a5aaf615e2fb53524156fc8e4e2c0a71f2c97e55",
14
14
  "src/bin.js": "22208907431d0f3a971a669c7e5eb44b3b7af9bbb36fd7ba17c3b90c4288bd70",
15
15
  "src/bridge-client.js": "ae0dba21e4286694bcd9e064ca36564ec997969ae1eb1ce4f8a6665e447cbffe",
16
- "src/coordinator.js": "1df096060faa83245c49b65a861f32cdaeeb7a190b94abf2ad6477151d7ca2ff",
16
+ "src/coordinator.js": "9cd891802ca1837ef2147b8c38012bbbec74dca555c2b93754550cdcdaf769f5",
17
17
  "src/diagnostics.js": "f7b516ace61a1e9faaa6876930b9e2e258499a25857d1203f4e53d28bfd0fa1a",
18
- "src/headless-analyzer.js": "2f345adee332c003ecb9a1e01eac4fa69d8802b4e6dd9effb03ac3cb19aa3e48",
18
+ "src/headless-analyzer.js": "5932f04c88334fba8851ab0e73508138c8f22e3b57325520d9767dc38db29ac9",
19
19
  "src/index-request.js": "78f26b872299005499fff4f2d1f9e8f986784f2ff36a5cf2be2b1e7b7c7d9378",
20
20
  "src/knowledge-targets.js": "aa44ec285d16d7b1c0b63bf084058a1d6f867fa9929c753b6b0cbb24f7b20ee2",
21
- "src/memories.js": "0a8667e6daba99fa5022393951a28e96cdadf98af85b6af9a6be96c7f4e896fc",
22
- "src/retrieval.js": "bbb09cefc3c6ed692a51edfeecf6ac50619b8a2afbdf2034e0fdb5e00f4cfa68",
21
+ "src/memories.js": "4c808122f5aa070f3e5c8ad90daa1057957f25a50c195b836b5c6c22894f3551",
22
+ "src/retrieval.js": "629c454f9ba63c56db0484c0b35486d17238e57ebf18463f6cc679e1a99e3471",
23
23
  "src/runtime/README.md": "9be676eca76a7857b34d7357194e6f0ee733c22e61d962d53984715dbec7f673",
24
24
  "src/runtime/atomic-file.js": "9846b4b69db5ded811acf19a1181ef93615d93efaa542b858e552a7f3124ad23",
25
25
  "src/runtime/automation-config.js": "6498c5397be12b155829740595a1553d4dcd6eaa7db6ced3ef88fdc60218f00e",
@@ -28,18 +28,18 @@
28
28
  "src/runtime/commit-prompt.js": "11856175a405c00514add6a540324a0efe3d7e5dd872c9e8a0b77f9f40abc551",
29
29
  "src/runtime/commit-reconciler.js": "41d0bafe43692cf37ac4e9c4b81a8bcfd828ca849cbe20d9fede237b6d001c69",
30
30
  "src/runtime/content-hash.js": "201ee7dcc054310f14097a00058cf9b28fa913367eef616e0fdd8facbf3c6c41",
31
- "src/runtime/contracts.js": "567fbace85ad0534fb0119f5c0e57d73acc0b76cc799af93d778c5ecbade53df",
31
+ "src/runtime/contracts.js": "b6bbae90348bf1291936d826e99f5703c629b872e35e2103dc7b933349ce7155",
32
32
  "src/runtime/conversation-exclusions.js": "ef8545034b862d384fb460140490bb531b58d94992f5e2222ebaaa079b44fa63",
33
33
  "src/runtime/conversation-store.js": "644318f9c04376a3317ced240dd94afa99a79631f0ecc394c5aa298ae2bc0474",
34
34
  "src/runtime/evidence-bundle.js": "33d4614849d5e1d69aba8b75c3a43c18b7b6f94e5c78654c82ef631331cc94cc",
35
35
  "src/runtime/git-runner.js": "b74fe197bd4dcf3e70635ef7b1f2615edf965c1d9a3ffe5406aabd41b76d74a9",
36
- "src/runtime/knowledge-promotion.js": "c24aba505caf11cdc8faba763beffc65956c1330ef28ed5fbd6ae16eac640fa6",
36
+ "src/runtime/knowledge-promotion.js": "892a227921ca399e80ea7b3991bfd13de0ffc221c7a0562393f1e5d33c2d00fa",
37
37
  "src/runtime/knowledge-retrieval-service.js": "75444f495a9ad0720af0e57b8d27d7ac1325c78a768f4f68ebd86ebc2524945e",
38
38
  "src/runtime/layout.js": "c48fa1db62e5df1edefe13218e470c5ceea4ef2781293512c2c18e5c2ba0c7e9",
39
- "src/runtime/markdown-knowledge-indexer.js": "44a76a9adefad07e78f77b1106b10d6c1cc7873d76362df4c546892b21f3939c",
39
+ "src/runtime/markdown-knowledge-indexer.js": "4d6b5b955849d274ca0614ef030c94526da7c39ab0874f02c168d0681f5b1406",
40
40
  "src/runtime/scanner.js": "d99fa8d74a6fbbaae75ca49f62127e14cf9e48b1404e4b4d597ef39df5441410",
41
- "src/server.js": "7deff466d28b94ec8975cd87ebd55c59d0aa6b49a8dfa447b552b1d32aa9c4b7",
42
- "src/store.js": "71f0417c2c1e42b89429e3dee1adff7b2c09e86682cb3f4843ce6d9e5aafd7ec",
41
+ "src/server.js": "51fa98f37952d5a3fff3cb9bb4c95eb76a5222d6f14096b1068518144b721605",
42
+ "src/store.js": "b97e2d8045b67e67043b69622230bc01b0e8fcc45476a51c7c9a3ecf479a6447",
43
43
  "ui/app.css": "7ad370c269e60a7b5ec907d81a607b2d16bd07b2d7c22a81f102dab51eeb2889",
44
44
  "ui/app.js": "33a2ba38f0dafbbb2e30a1eb3fc93476bfcaf528e124e1a9b2edd2fb69221e9e",
45
45
  "ui/index.html": "ce3565cfefd4838b11d37a91a906ef26ca5a1834844fe3f7c897b56851a3c418"