@sanqianx/project-knowledge 5.0.3 → 5.0.5

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.
@@ -9,7 +9,7 @@
9
9
  "plugins": [
10
10
  {
11
11
  "name": "project-knowledge",
12
- "version": "5.0.3",
12
+ "version": "5.0.5",
13
13
  "source": "./plugins/project-knowledge",
14
14
  "description": "Search durable project decisions and implementation history through MCP."
15
15
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [5.0.5] - 2026-10-10
4
+
5
+ - Invalidate in-flight registry snapshots after domain creation, project import,
6
+ ownership changes and wiring repair. A read begun before the write cannot
7
+ hide the newly registered data until the next polling cycle.
8
+ - Includes all knowledge-maintenance, Claude discovery and local diagnostic
9
+ fixes from 5.0.3, plus exact commit retrieval from 5.0.4. No schema migration
10
+ or automatic replay of failed model tasks.
11
+
12
+ ## [5.0.4] - 2026-10-10
13
+
14
+ - Vendor engine 0.2.2: treat a known full/prefix commit SHA as a provenance
15
+ identifier. Unrelated high-scoring vector chunks cannot crowd out the matching
16
+ current knowledge. Preserve ordinary semantic ranking and current-file truth;
17
+ overwritten documents are not attributed to their earlier commit.
18
+ - Includes the empty-knowledge and Claude discovery/diagnostic fixes from 5.0.3.
19
+
3
20
  ## [5.0.3] - 2026-10-10
4
21
 
5
22
  - Pin Workbench 0.13.1: reject stale Claude executable overrides without hiding
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanqianx/ai-coding-knowledge-engine",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Knowledge engine module for project-knowledge: commit-boundary triggered knowledge analysis/generation (trigger plane) and retrieval for development assistants (retrieval plane).",
5
5
  "license": "Apache-2.0",
6
6
  "main": "src/server.js",
@@ -7,6 +7,23 @@ const { DomainError } = require('./runtime/contracts');
7
7
 
8
8
  class EngineRetrieval extends KnowledgeRetrievalService {
9
9
  constructor(options) { super(options); this.store = options.store; this.memories = options.memories; this.vectorUrl = options.vectorUrl || 'http://127.0.0.1:8787'; }
10
+ signalSet(input = {}) {
11
+ const signals = super.signalSet(input);
12
+ const query = signals.indexQuery.trim().toLowerCase();
13
+ if (/^[a-f0-9]{7,64}$/.test(query) && this.store.listRuns().some(run => run.promotedAt && run.commitSha?.startsWith(query))) signals.commitPrefix = query;
14
+ return signals;
15
+ }
16
+ score(candidate, signals) {
17
+ if (signals.commitPrefix) {
18
+ // A known commit is an identifier, not a semantic topic. Unrelated
19
+ // vector hits must not crowd its current, provenance-checked files out.
20
+ const source = this.store.listRuns(candidate.projectId).find(run => run.promotedAt && run.staging?.operations?.some(operation => operation.path === candidate.entryId));
21
+ if (!source?.commitSha?.startsWith(signals.commitPrefix)) return { score: 0, selectionSignals: [] };
22
+ const result = super.score(candidate, signals);
23
+ return { score: Math.max(1, result.score), selectionSignals: [...result.selectionSignals, 'exact-commit'] };
24
+ }
25
+ return super.score(candidate, signals);
26
+ }
10
27
  resolve(input = {}) {
11
28
  let project = this.store.getProject(input.projectId || input.projectSlug || input.project);
12
29
  if (!project && (input.repoPath || input.path)) project = this.store.listProjects().find(p => this.layout.pathsEqual(p.repoPath, input.repoPath || input.path));
@@ -18,6 +18,8 @@ assert.equal((script.match(/\.src = /g) || []).length, 1, 'frames initialize onc
18
18
  for (const contract of ['kb:theme', 'kb:select-project', 'kb:scope', 'kb:knowledge', 'kb:ready']) assert.ok(script.includes(contract));
19
19
  assert.ok(script.includes('event.origin !== location.origin') && script.includes('contentWindow === event.source'), 'module messages must be from the expected frame and origin');
20
20
  assert.ok(script.includes('state.epoch++') && script.includes('referenceEpoch') && script.includes('logEpoch'), 'late project/reference/log feedback must be isolated');
21
+ assert.match(script, /on\('domainForm'[\s\S]*?await refreshRegistry\(true\)/, 'domain writes must invalidate pre-mutation reads');
22
+ assert.match(script, /registered = true;[\s\S]*?await refreshRegistry\(true\)/, 'import must not reuse a pre-import snapshot');
21
23
  assert.ok(script.includes('esc(r.title)') && script.includes('esc(m.text)') && script.includes('esc(project.name)'));
22
24
  assert.ok(script.includes('text.textContent = record.message') && script.includes("'logs/appended'"), 'diagnostics stay inert and stream live');
23
25
  assert.ok(script.includes('URL.revokeObjectURL(url)') && script.includes('logStream?.close()'));
@@ -2,7 +2,7 @@
2
2
  "schema": "project-knowledge/module-content/v1",
3
3
  "productFiles": {
4
4
  "ui/index.html": "e7291caab778eba3c5499d8286804ad1f4ef31c87a957f69c8fb77befc01321b",
5
- "ui/product.js": "1a6ddedd97b00c3f798c13a0a55b0f63790e701483492bc97d28cae4034efaf8",
5
+ "ui/product.js": "e35c1650df239cec0a9d73197fed7ac069bb09f0c51f4752e03115784a526518",
6
6
  "ui/product.css": "73554abf3f951ea01a2bfe2df81748b702a6ca4488eea16bfe5afe04ef1dea70"
7
7
  },
8
8
  "modules": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanqianx/project-knowledge",
3
- "version": "5.0.3",
3
+ "version": "5.0.5",
4
4
  "description": "Knowledge base manager with Git integration, AI-driven analysis, and bilingual (zh-CN/en-US) knowledge output",
5
5
  "main": "_site/server.js",
6
6
  "scripts": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "project-knowledge",
4
- "version": "5.0.3",
4
+ "version": "5.0.5",
5
5
  "description": "Read durable project decisions and implementation history from Project Knowledge.",
6
6
  "author": {
7
7
  "name": "SanQianX",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-knowledge",
3
- "version": "5.0.3",
3
+ "version": "5.0.5",
4
4
  "description": "Read durable project decisions and implementation history from Project Knowledge.",
5
5
  "author": {
6
6
  "name": "SanQianX",
@@ -6,7 +6,7 @@
6
6
  "args": [
7
7
  "-y",
8
8
  "--package",
9
- "@sanqianx/project-knowledge@5.0.3",
9
+ "@sanqianx/project-knowledge@5.0.5",
10
10
  "project-knowledge-mcp"
11
11
  ]
12
12
  }
package/ui/product.js CHANGED
@@ -291,7 +291,7 @@
291
291
  const result = await api(`/api/projects/${encodeURIComponent(project.projectId)}/module-register`, { method: 'POST', body: {} });
292
292
  const pending = Object.entries(result.modules).filter(([, v]) => !v.ok).map(([key]) => modules[key]);
293
293
  $('wiringFeedback').textContent = pending.length ? `项目已登记,待恢复:${pending.join('、')}` : '四个模块已连接。';
294
- toast($('wiringFeedback').textContent); await refreshRegistry(); Object.keys(frames).forEach(frameContext);
294
+ toast($('wiringFeedback').textContent); await refreshRegistry(true); Object.keys(frames).forEach(frameContext);
295
295
  }
296
296
  async function pick(target) {
297
297
  const result = await api('/api/terminal/system/pick-folder');
@@ -350,7 +350,7 @@
350
350
  };
351
351
  execute().catch(error => toast(error.message));
352
352
  });
353
- document.addEventListener('change', e => { if (e.target.id === 'projectDomain') api(`/api/projects/${encodeURIComponent(state.projectId)}`, { method: 'PATCH', body: { domainId: e.target.value || null } }).then(refreshRegistry).catch(error => toast(error.message)); });
353
+ document.addEventListener('change', e => { if (e.target.id === 'projectDomain') api(`/api/projects/${encodeURIComponent(state.projectId)}`, { method: 'PATCH', body: { domainId: e.target.value || null } }).then(() => refreshRegistry(true)).catch(error => toast(error.message)); });
354
354
  window.addEventListener('message', event => {
355
355
  if (event.origin !== location.origin || !event.data || typeof event.data !== 'object') return;
356
356
  const key = Object.keys(frames).find(k => $(frames[k].id).contentWindow === event.source); if (!key) return;
@@ -393,7 +393,7 @@
393
393
  on('loadLogs', 'click', loadLogs);
394
394
  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); });
395
395
  on('createDomain', 'click', () => { $('domainForm').reset(); $('domainDialog').showModal(); });
396
- on('domainForm', 'submit', async e => { e.preventDefault(); await api('/api/domains', { method: 'POST', body: Object.fromEntries(new FormData(e.target)) }); $('domainDialog').close(); await refreshRegistry(); });
396
+ 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); });
397
397
  on('memoryForm', 'submit', async e => { e.preventDefault(); await api(`/api/engine/memories/${encodeURIComponent(editingMemoryId)}`, { method: 'PATCH', body: { text: $('memoryText').value } }); $('memoryDialog').close(); await refreshSnapshot(); });
398
398
  on('unbindForm', 'submit', async e => {
399
399
  e.preventDefault(); if (!unbindProjectId || unbinding) return;
@@ -423,7 +423,7 @@
423
423
  e.preventDefault(); if (!state.preflight?.ready || state.preflight.plannedGitInit && !$('importForm').elements.confirmGitInit.checked || state.preflight.checks.hook?.replacementProjectId && !$('importForm').elements.confirmReplaceHook.checked) return;
424
424
  $('confirmImport').disabled = true; $('confirmImport').textContent = '正在登记…';
425
425
  let failed = false, registered = false;
426
- try { const result = await api('/api/projects/import', { method: 'POST', body: importInput() }); registered = true; state.projectId = result.projectId; state.epoch++; $('importDialog').close(); await refreshRegistry(); Object.keys(frames).forEach(frameContext); setView('projects'); toast(Object.values(result.modules).every(m => m.ok) ? '项目已导入,四个模块已连接。' : '项目已导入,部分接线待恢复。'); }
426
+ try { const result = await api('/api/projects/import', { method: 'POST', body: importInput() }); registered = true; state.projectId = result.projectId; state.epoch++; $('importDialog').close(); await refreshRegistry(true); Object.keys(frames).forEach(frameContext); setView('projects'); toast(Object.values(result.modules).every(m => m.ok) ? '项目已导入,四个模块已连接。' : '项目已导入,部分接线待恢复。'); }
427
427
  catch (error) {
428
428
  failed = true;
429
429
  if (registered) { toast(`项目已登记,但页面状态刷新失败:${error.message}`); return; }
@@ -3,11 +3,11 @@
3
3
  "modules": {
4
4
  "knowledge-engine": {
5
5
  "name": "@sanqianx/ai-coding-knowledge-engine",
6
- "version": "0.2.1",
6
+ "version": "0.2.2",
7
7
  "root": "_modules/knowledge-engine",
8
8
  "files": {
9
9
  "README.md": "236dafd8092e13ab731d4a14548e04c4ad3126bdfa63c706a6afe6f9b1dc535d",
10
- "package.json": "f7a91e96c77d62aeee4d0dc9b4da327bf615f07d18b1882c305de556cd9ffb65",
10
+ "package.json": "4fe13c333017a073431c4b730c000a30d2be81012dbb8881dcae3167e3c38643",
11
11
  "src/analysis-contract.js": "fee063967d32eefc955cf0729f7dc8cb31bd690b85e22471c9059494a599c77a",
12
12
  "src/analysis-output.js": "95a3c19dcc9ab85d1dba7fee5b9aec80f9c000dfba89da3fd0be25a81e2fb680",
13
13
  "src/analysis-worker.js": "a105cabe6e1573b2d986b1e7a5aaf615e2fb53524156fc8e4e2c0a71f2c97e55",
@@ -17,7 +17,7 @@
17
17
  "src/diagnostics.js": "1ad8b21e0f26d7c18861d51c711a6d36e5070658205cab19727494279f0801e4",
18
18
  "src/headless-analyzer.js": "cfe54b392b2aff6e2c5157481dfeb5ccebc4ce83d1d74aa44f28cf2eb923b013",
19
19
  "src/memories.js": "0a8667e6daba99fa5022393951a28e96cdadf98af85b6af9a6be96c7f4e896fc",
20
- "src/retrieval.js": "acbf76bb93fd13dac391c2e918891a56ace869db5583d2a5994641b6782496d6",
20
+ "src/retrieval.js": "b3ae3f701a007e3d3ff98811bb80db3505e2fcc87f94aaa9e36057edc7eb71c2",
21
21
  "src/runtime/README.md": "9be676eca76a7857b34d7357194e6f0ee733c22e61d962d53984715dbec7f673",
22
22
  "src/runtime/atomic-file.js": "9846b4b69db5ded811acf19a1181ef93615d93efaa542b858e552a7f3124ad23",
23
23
  "src/runtime/automation-config.js": "6498c5397be12b155829740595a1553d4dcd6eaa7db6ced3ef88fdc60218f00e",