@sanqianx/project-knowledge 5.0.8 → 5.0.9-rc.10

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 (52) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +109 -0
  3. package/README.md +27 -4
  4. package/_modules/knowledge-engine/README.md +6 -1
  5. package/_modules/knowledge-engine/package.json +1 -1
  6. package/_modules/knowledge-engine/src/coordinator.js +68 -36
  7. package/_modules/knowledge-engine/src/diagnostics.js +1 -1
  8. package/_modules/knowledge-engine/src/headless-analyzer.js +3 -1
  9. package/_modules/knowledge-engine/src/index-request.js +49 -0
  10. package/_modules/knowledge-engine/src/knowledge-targets.js +46 -0
  11. package/_modules/knowledge-engine/src/retrieval.js +7 -5
  12. package/_modules/knowledge-engine/src/runtime/conversation-store.js +1 -1
  13. package/_modules/knowledge-engine/src/server.js +1 -1
  14. package/_modules/knowledge-engine/ui/app.js +1 -1
  15. package/_site/_test/candidate-release-contract-test.js +14 -0
  16. package/_site/_test/conversation-store-test.js +2 -0
  17. package/_site/_test/fixtures/make-git-repos.js +1 -9
  18. package/_site/_test/index-error-display-contract-test.js +10 -0
  19. package/_site/_test/knowledge-engine-client-test.js +105 -0
  20. package/_site/_test/product-brand-contract-test.js +25 -0
  21. package/_site/_test/release-version-sync-test.js +7 -1
  22. package/_site/_test/sessions-stream-test.js +3 -2
  23. package/_site/_test/shared-scope-root-binding-test.js +67 -0
  24. package/_site/_test/simple-import-test.js +3 -2
  25. package/_site/_test/team-knowledge-store-test.js +3 -2
  26. package/_site/_test/test-server-cleanup-test.js +31 -0
  27. package/_site/_test/vector-storage-root-test.js +52 -0
  28. package/_site/_test/workspace-ui-contract-test.js +1 -0
  29. package/_site/lib/contracts.js +5 -0
  30. package/_site/lib/conversation-store.js +1 -1
  31. package/_site/lib/engine-knowledge-client.js +72 -0
  32. package/_site/lib/knowledge-tool-runtime.js +7 -0
  33. package/_site/lib/module-bridge.js +44 -11
  34. package/_site/lib/server-app.js +3 -3
  35. package/_site/lib/settings-store.js +20 -0
  36. package/_site/lib/storage-layout.js +4 -0
  37. package/_site/scripts/pack-module-candidates.js +1 -1
  38. package/_site/scripts/sync-release-version.js +12 -10
  39. package/_site/scripts/verify-module-runtime.js +7 -2
  40. package/_site/scripts/verify-product-runtime.js +1 -0
  41. package/bin/project-knowledge-kb.js +4 -2
  42. package/bin/project-knowledge-mcp.js +7 -1
  43. package/module-runtime-manifest.json +41 -38
  44. package/package.json +6 -6
  45. package/plugins/project-knowledge/.claude-plugin/plugin.json +1 -1
  46. package/plugins/project-knowledge/.codex-plugin/plugin.json +1 -1
  47. package/plugins/project-knowledge/.mcp.json +1 -1
  48. package/ui/favicon.svg +5 -38
  49. package/ui/index.html +4 -4
  50. package/ui/product.css +2 -1
  51. package/ui/product.js +13 -2
  52. package/vendor-manifest.json +12 -10
@@ -24,6 +24,7 @@
24
24
 
25
25
  const { spawn, spawnSync } = require('child_process');
26
26
  const path = require('path');
27
+ const { StorageLayout } = require('./storage-layout');
27
28
  const fs = require('fs');
28
29
  const crypto = require('crypto');
29
30
  const { once } = require('events');
@@ -310,10 +311,19 @@ class ModuleBridge {
310
311
  } };
311
312
  }
312
313
 
313
- async syncEngineConfiguration() {
314
- if (this.syncingConfig) return this.configStatus || { scopes: false, model: false };
315
- this.syncingConfig = true;
316
- const status = { scopes: false, model: false, embedding: false };
314
+ syncEngineConfiguration() {
315
+ if (this.configSyncPromise) return this.configSyncPromise.catch(() => undefined).then(() => this.syncEngineConfiguration());
316
+ const pending = this._syncEngineConfiguration().finally(() => { if (this.configSyncPromise === pending) this.configSyncPromise = null; });
317
+ this.configSyncPromise = pending;
318
+ return pending;
319
+ }
320
+
321
+ async _syncEngineConfiguration() {
322
+ const dataDir = this.dataDir || require('./data-dir').getDataDir();
323
+ let indexPath = null;
324
+ try { indexPath = new StorageLayout({ dataDir }).getVectorRootPath(this.settingsStore?.read()); }
325
+ catch { /* Corrupt settings must not switch storage or prevent credential revocation. */ }
326
+ const status = { scopes: false, scopeStatus: { status: 'pending' }, model: false, embedding: false, indexStorage: { expectedPath: indexPath, actualPath: null, status: 'pending' } };
317
327
  const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.runtimeToken}` };
318
328
  try {
319
329
  if (this.settingsStore) {
@@ -321,11 +331,28 @@ class ModuleBridge {
321
331
  if (settings.knowledge.rootPath) {
322
332
  const brain = settings.brain;
323
333
  const root = path.join(settings.knowledge.rootPath, '_shared');
324
- const scopes = [{ id: brain.id, kind: 'brain', brainId: brain.id, name: brain.name, knowledgePath: path.join(root, brain.id) }, ...brain.domains.map(d => ({ id: d.id, kind: 'domain', brainId: brain.id, domainId: d.id, name: d.name, knowledgePath: path.join(root, d.id) }))];
325
- status.scopes = (await this._fetch(`${this.engineUrl}/api/scopes`, { method: 'POST', headers, body: JSON.stringify({ scopes }) })).ok;
334
+ const response = await this._fetch(`${this.engineUrl}/api/snapshot`);
335
+ if (!response.ok) throw new DomainError('ENGINE_UNAVAILABLE', '共享知识接线暂时不可用。');
336
+ const prior = (await response.json()).sharedScopes || [];
337
+ // Root settings govern new directories and derived indexes, never move
338
+ // existing knowledge. Retain engine-acknowledged bindings in the spine.
339
+ const binding = (item, kind) => {
340
+ const existing = prior.find(scope => scope.id === item.id && scope.kind === kind && scope.brainId === brain.id);
341
+ if (existing && !path.isAbsolute(existing.knowledgePath || '')) throw new DomainError('DATA_CORRUPT', '共享目录绑定损坏。');
342
+ return item.knowledgePath || existing?.knowledgePath || path.join(root, item.id);
343
+ };
344
+ const scopes = [{ id: brain.id, kind: 'brain', brainId: brain.id, name: brain.name, knowledgePath: binding(brain, 'brain') }, ...brain.domains.map(d => ({ id: d.id, kind: 'domain', brainId: brain.id, domainId: d.id, name: d.name, knowledgePath: binding(d, 'domain') }))];
345
+ const applied = await this._fetch(`${this.engineUrl}/api/scopes`, { method: 'POST', headers, body: JSON.stringify({ scopes }) });
346
+ if (!applied.ok) throw new DomainError('SHARED_SCOPE_APPLY_FAILED', '共享目录接线未完成。');
347
+ await this.settingsStore.bindSharedKnowledgePaths?.(scopes);
348
+ status.scopes = true; status.scopeStatus = { status: 'ready' };
326
349
  }
327
350
  }
328
- } catch { /* A scope failure must not prevent revoking a stale model key. */ }
351
+ } catch (error) {
352
+ status.scopeStatus = { status: 'pending', code: ['DATA_CORRUPT', 'IMMUTABLE_FIELD', 'ENGINE_UNAVAILABLE', 'SHARED_SCOPE_APPLY_FAILED'].includes(error.code) ? error.code : 'ENGINE_UNAVAILABLE' };
353
+ this.logger.warn('modules.scopes.pending', 'Shared knowledge wiring is pending; existing data is retained.', { context: { code: status.scopeStatus.code } });
354
+ // A scope failure must not prevent revoking a stale model key.
355
+ }
329
356
  try {
330
357
  let profile = null;
331
358
  try {
@@ -341,10 +368,15 @@ class ModuleBridge {
341
368
  const resolved = await this._fetch(`${this.terminalUrl}/api/claude-workbench/v1/internal/embedding-config`, { method: 'POST', headers, body: '{}' });
342
369
  if (resolved.ok) settings = await resolved.json();
343
370
  } catch { /* Revocation wins over a previously cached runtime key. */ }
344
- const applied = await this._fetch(`${this.vectorHubUrl}/api/internal/runtime-config`, { method: 'POST', headers, body: JSON.stringify({ settings }) });
371
+ const applied = await this._fetch(`${this.vectorHubUrl}/api/internal/runtime-config`, { method: 'POST', headers, body: JSON.stringify({ settings, ...(indexPath ? { storageRoot: indexPath } : {}) }) });
345
372
  status.embedding = applied.ok && !!settings;
373
+ if (applied.ok) {
374
+ const result = await applied.json();
375
+ status.indexStorage.actualPath = result.rootPath || null;
376
+ status.indexStorage.status = result.rootPath && path.resolve(result.rootPath) === indexPath ? 'ready' : 'pending';
377
+ }
346
378
  } catch { /* Public status contains no resolved configuration. */ }
347
- this.syncingConfig = false; this.configStatus = status;
379
+ this.configStatus = status;
348
380
  return status;
349
381
  }
350
382
 
@@ -559,12 +591,13 @@ class ModuleBridge {
559
591
  this.logger.warn('modules.supervisor', '@sanqianx/vector-hub runtime not installed; expecting an external service.', {});
560
592
  } else {
561
593
  const dataDir = this.dataDir || require('./data-dir').getDataDir();
562
- const root = path.join(dataDir, 'vectorhub');
594
+ const configRoot = path.join(dataDir, 'vectorhub');
595
+ const root = new StorageLayout({ dataDir }).getVectorRootPath(this.settingsStore?.read());
563
596
  specs.push({
564
597
  name: 'vector-hub',
565
598
  command: `node ${JSON.stringify(vectorHubEntry)} serve --host ${urlHost(this.vectorHubUrl)} --port ${urlPort(this.vectorHubUrl, 8787)} --root ${JSON.stringify(root)}`,
566
599
  url: this.vectorHubUrl,
567
- env: { VECTOR_HUB_ROOT: root, VECTOR_HUB_CONFIG: path.join(root, 'config.json'), VECTOR_HUB_LEGACY_CONFIG: path.join(root, 'no-legacy-config.json'), KB_VECTOR_MANAGED: '1', KB_VECTOR_RUNTIME_TOKEN: this.runtimeToken },
600
+ env: { VECTOR_HUB_ROOT: root, VECTOR_HUB_CONFIG: path.join(configRoot, 'config.json'), VECTOR_HUB_LEGACY_CONFIG: path.join(configRoot, 'no-legacy-config.json'), KB_VECTOR_MANAGED: '1', KB_VECTOR_RUNTIME_TOKEN: this.runtimeToken },
568
601
  });
569
602
  }
570
603
  }
@@ -921,7 +921,7 @@ function createRequestHandler(runtime, options = {}) {
921
921
  }
922
922
  if (method === 'GET' && pathname === '/api/brain') {
923
923
  const settings = runtime.settingsStore.read();
924
- return send(res, 200, { ok: true, brain: settings.brain, knowledgeRoot: settings.knowledge.rootPath, configuration: runtime.moduleBridge.configStatus || null });
924
+ return send(res, 200, { ok: true, brain: settings.brain, knowledgeRoot: settings.knowledge.rootPath, indexStoragePath: runtime.layout.getVectorRootPath(settings), configuration: runtime.moduleBridge.configStatus || null });
925
925
  }
926
926
  if (method === 'PATCH' && pathname === '/api/brain') {
927
927
  const body = await readJsonBody(req);
@@ -982,8 +982,8 @@ function createRequestHandler(runtime, options = {}) {
982
982
  if (body.logging) throw new DomainError('IMMUTABLE_FIELD', 'Logging storage and capture policy are not user settings.', { status: 409 });
983
983
  if (!Object.keys(patch).length) throw new DomainError('INVALID_ARGUMENT', 'Only the knowledge root is mutable on this route.');
984
984
  const settings = await runtime.settingsStore.updatePatch(patch);
985
- await runtime.moduleBridge.syncEngineConfiguration();
986
- return send(res, 200, { ok: true, settings: { ...settings, ai: publicAiProfilesConfig(settings.ai) } });
985
+ const configuration = await runtime.moduleBridge.syncEngineConfiguration();
986
+ return send(res, 200, { ok: true, settings: { ...settings, ai: publicAiProfilesConfig(settings.ai) }, configuration });
987
987
  }
988
988
 
989
989
  if (method === 'GET' && pathname === '/api/projects') return send(res, 200, { ok: true, projects: listProjectViews(runtime.registryStore, runtime.projectStore) });
@@ -1,6 +1,7 @@
1
1
  const { SCHEMAS, DomainError, publicAiProfilesConfig } = require('./contracts');
2
2
  const AtomicFile = require('./atomic-file');
3
3
  const { StorageLayout } = require('./storage-layout');
4
+ const path = require('node:path');
4
5
 
5
6
  function defaultSettings() {
6
7
  return {
@@ -43,9 +44,12 @@ function validateSettings(settings) {
43
44
  }
44
45
  settings.brain = settings.brain || { id: 'brain-default', name: '我的智脑', domains: [] };
45
46
  if (settings.brain.id !== 'brain-default' || typeof settings.brain.name !== 'string' || !settings.brain.name.trim() || settings.brain.name.length > 100 || !Array.isArray(settings.brain.domains)) throw new DomainError('DATA_CORRUPT', 'Brain metadata is invalid.', { status: 500 });
47
+ const validBinding = value => value === undefined || typeof value === 'string' && path.isAbsolute(value);
48
+ if (!validBinding(settings.brain.knowledgePath)) throw new DomainError('DATA_CORRUPT', 'Brain knowledge binding is invalid.', { status: 500 });
46
49
  const ids = new Set();
47
50
  for (const domain of settings.brain.domains) {
48
51
  if (!domain || !/^domain-[a-z0-9-]+$/.test(domain.id) || ids.has(domain.id) || typeof domain.name !== 'string' || !domain.name.trim() || domain.name.length > 100) throw new DomainError('DATA_CORRUPT', 'Domain metadata is invalid.', { status: 500 });
52
+ if (!validBinding(domain.knowledgePath)) throw new DomainError('DATA_CORRUPT', 'Domain knowledge binding is invalid.', { status: 500 });
49
53
  ids.add(domain.id);
50
54
  }
51
55
  const logging = settings.logging || {};
@@ -92,6 +96,7 @@ class SettingsStore {
92
96
 
93
97
  async updatePatch(patch) {
94
98
  return this.atomic.withFileLock(this.lockPath, async () => {
99
+ if (patch?.brain && (Object.prototype.hasOwnProperty.call(patch.brain, 'knowledgePath') || patch.brain.domains?.some?.(domain => Object.prototype.hasOwnProperty.call(domain, 'knowledgePath')))) throw new DomainError('INVALID_ARGUMENT', '共享知识目录绑定只允许受控接线写入。');
95
100
  if (patch && patch.logging && typeof patch.logging === 'object') {
96
101
  const unknown = Object.keys(patch.logging).find(key => key !== 'levels');
97
102
  if (unknown) throw new DomainError('INVALID_ARGUMENT', `Logging setting is read-only or unsupported: ${unknown}.`, { details: { field: unknown } });
@@ -120,6 +125,21 @@ class SettingsStore {
120
125
  });
121
126
  }
122
127
 
128
+ async bindSharedKnowledgePaths(scopes) {
129
+ return this.atomic.withFileLock(this.lockPath, async () => {
130
+ const settings = this.read();
131
+ let changed = false;
132
+ for (const scope of scopes) {
133
+ const target = scope.kind === 'brain' && scope.id === settings.brain.id ? settings.brain : settings.brain.domains.find(domain => domain.id === scope.id);
134
+ if (!target || !path.isAbsolute(scope.knowledgePath || '')) throw new DomainError('INVALID_ARGUMENT', '共享知识绑定无效。');
135
+ if (target.knowledgePath && !this.layout.pathsEqual(target.knowledgePath, scope.knowledgePath)) throw new DomainError('IMMUTABLE_FIELD', '共享知识目录不能隐式移动。', { status: 409 });
136
+ if (!target.knowledgePath) { target.knowledgePath = path.resolve(scope.knowledgePath); changed = true; }
137
+ }
138
+ if (changed) { settings.updatedAt = new Date().toISOString(); validateSettings(settings); this.atomic.writeJsonAtomic(this.filePath, settings); }
139
+ return settings;
140
+ });
141
+ }
142
+
123
143
  readPublicView(options = {}) {
124
144
  const settings = this.read(options);
125
145
  return {
@@ -49,6 +49,10 @@ class StorageLayout {
49
49
  getRegistryLockPath() { return path.join(this.dataDir, 'runtime', 'locks', 'projects.lock'); }
50
50
 
51
51
  getIndexPath() { return path.join(this.dataDir, 'index', 'knowledge.lancedb'); }
52
+ getVectorRootPath(settings) {
53
+ const root = settings?.knowledge?.rootPath;
54
+ return root ? path.join(path.resolve(root), '.indexes') : path.join(this.dataDir, 'vectorhub');
55
+ }
52
56
  getCachePath(...segments) { return path.join(this.dataDir, 'cache', ...segments); }
53
57
  getRuntimePath(...segments) { return path.join(this.dataDir, 'runtime', ...segments); }
54
58
  getRecoveryPath(...segments) { return path.join(this.dataDir, 'recovery', ...segments); }
@@ -53,7 +53,7 @@ function pack(sources) {
53
53
  process.stdout.write(`Packed ${key} ${pkg.version}: ${result.files.length} files\n`);
54
54
  }
55
55
  const manifestPath = path.join(output, 'module-candidates.json'); AtomicFile.writeJsonAtomic(manifestPath, manifest);
56
- const productFiles = Object.fromEntries(['ui/index.html', 'ui/product.js', 'ui/product.css'].map(file => [file, hash(fs.readFileSync(path.join(root, file)))]));
56
+ const productFiles = Object.fromEntries(['ui/index.html', 'ui/product.js', 'ui/product.css', 'ui/favicon.svg'].map(file => [file, hash(fs.readFileSync(path.join(root, file)))]));
57
57
  AtomicFile.writeJsonAtomic(path.join(root, 'module-runtime-manifest.json'), { schema: 'project-knowledge/module-content/v1', productFiles, modules: Object.fromEntries(Object.entries(manifest.modules).map(([key, module]) => [key, { name: module.name, installName: module.installName, version: module.version, files: module.files }])) });
58
58
  process.stdout.write(`MODULE_CANDIDATES ${manifestPath}\n`);
59
59
  return manifestPath;
@@ -20,7 +20,7 @@ function packageVersion(rootDir) {
20
20
  return version;
21
21
  }
22
22
 
23
- function releaseVersionTargets(rootDir, version) {
23
+ function releaseVersionTargets(rootDir, version, { webOnly = false } = {}) {
24
24
  return [
25
25
  {
26
26
  file: 'package-lock.json',
@@ -67,13 +67,13 @@ function releaseVersionTargets(rootDir, version) {
67
67
  args[index] = `@sanqianx/project-knowledge@${version}`;
68
68
  },
69
69
  },
70
- ].map(target => ({ ...target, path: path.join(rootDir, target.file) }));
70
+ ].filter(target => !webOnly || !target.file.startsWith('desktop/')).map(target => ({ ...target, path: path.join(rootDir, target.file) }));
71
71
  }
72
72
 
73
- function inspectReleaseVersion(rootDir) {
73
+ function inspectReleaseVersion(rootDir, options) {
74
74
  const version = packageVersion(rootDir);
75
75
  const drift = [];
76
- for (const target of releaseVersionTargets(rootDir, version)) {
76
+ for (const target of releaseVersionTargets(rootDir, version, options)) {
77
77
  const before = fs.readFileSync(target.path, 'utf8');
78
78
  const value = JSON.parse(before);
79
79
  target.update(value);
@@ -83,10 +83,10 @@ function inspectReleaseVersion(rootDir) {
83
83
  return { version, drift };
84
84
  }
85
85
 
86
- function syncReleaseVersion(rootDir) {
86
+ function syncReleaseVersion(rootDir, options) {
87
87
  const version = packageVersion(rootDir);
88
88
  const changed = [];
89
- for (const target of releaseVersionTargets(rootDir, version)) {
89
+ for (const target of releaseVersionTargets(rootDir, version, options)) {
90
90
  const before = fs.readFileSync(target.path, 'utf8');
91
91
  const value = JSON.parse(before);
92
92
  target.update(value);
@@ -114,21 +114,23 @@ function parseArgs(argv) {
114
114
  let check = false;
115
115
  let tag = null;
116
116
  let stage = false;
117
+ let webOnly = false;
117
118
  for (let index = 0; index < argv.length; index += 1) {
118
119
  const arg = argv[index];
119
120
  if (arg === '--check') check = true;
120
121
  else if (arg === '--stage') stage = true;
122
+ else if (arg === '--web-only') webOnly = true;
121
123
  else if (arg === '--root') rootDir = path.resolve(argv[++index] || '');
122
124
  else if (arg === '--tag') tag = String(argv[++index] || '').trim();
123
125
  else throw new Error(`Unknown argument: ${arg}`);
124
126
  }
125
- return { rootDir, check, tag, stage };
127
+ return { rootDir, check, tag, stage, webOnly };
126
128
  }
127
129
 
128
130
  function main(argv = process.argv.slice(2)) {
129
- const { rootDir, check, tag, stage } = parseArgs(argv);
131
+ const { rootDir, check, tag, stage, webOnly } = parseArgs(argv);
130
132
  if (check) {
131
- const result = inspectReleaseVersion(rootDir);
133
+ const result = inspectReleaseVersion(rootDir, { webOnly });
132
134
  if (result.drift.length) {
133
135
  throw new Error(`Release version ${result.version} is out of sync: ${result.drift.join(', ')}`);
134
136
  }
@@ -138,7 +140,7 @@ function main(argv = process.argv.slice(2)) {
138
140
  console.log(`release version ${result.version} is synchronized`);
139
141
  return result;
140
142
  }
141
- const result = syncReleaseVersion(rootDir);
143
+ const result = syncReleaseVersion(rootDir, { webOnly });
142
144
  if (stage) stageReleaseVersionFiles(rootDir, result.changed);
143
145
  console.log(result.changed.length
144
146
  ? `${stage ? 'synchronized and staged' : 'synchronized'} release version ${result.version}: ${result.changed.join(', ')}`
@@ -5,6 +5,10 @@ const crypto = require('crypto');
5
5
  const { spawnSync } = require('child_process');
6
6
  const root = path.resolve(__dirname, '../..');
7
7
  const workingTree = process.argv.includes('--working-tree');
8
+ function isPinnedModuleVersion(name, value) {
9
+ const version = name === 'claude-ai-workbench' ? String(value || '').replace(/^npm:@sanqianx\/claude-ai-workbench@/, '') : value;
10
+ return /^\d+\.\d+\.\d+(?:-rc\.\d+)?$/.test(version || '');
11
+ }
8
12
  function verify() {
9
13
  const manifest = JSON.parse(fs.readFileSync(path.join(root, 'vendor-manifest.json'), 'utf8'));
10
14
  if (manifest.schema !== 'project-knowledge/vendor-runtime/v1') throw new Error('Invalid runtime manifest');
@@ -12,7 +16,7 @@ function verify() {
12
16
  if (!engine || engine.root !== '_modules/knowledge-engine') throw new Error('Missing engine runtime');
13
17
  const packageInfo = JSON.parse(fs.readFileSync(path.join(root, 'package.json')));
14
18
  for (const dependency of ['claude-ai-workbench', '@sanqianx/vector-hub', '@sanqianx/ai-coding-event-bridge-console']) {
15
- if (!/^\d+\.\d+\.\d+$/.test(packageInfo.dependencies[dependency] || '') && !/^npm:@sanqianx\/claude-ai-workbench@\d+\.\d+\.\d+$/.test(packageInfo.dependencies[dependency] || '')) throw new Error(`Module dependency must be pinned: ${dependency}`);
19
+ if (!isPinnedModuleVersion(dependency, packageInfo.dependencies[dependency])) throw new Error(`Module dependency must be pinned: ${dependency}`);
16
20
  }
17
21
  const required = ['package.json', 'src/bin.js', 'src/server.js', 'src/coordinator.js', 'src/analysis-worker.js', 'ui/index.html', 'ui/app.js', 'ui/app.css'];
18
22
  if (required.some(file => !engine.files[file])) throw new Error('Incomplete runtime manifest');
@@ -42,4 +46,5 @@ function verify() {
42
46
  if (enginePackage.version !== engine.version || Object.keys(enginePackage.dependencies || {}).length || Object.keys(enginePackage.devDependencies || {}).length) throw new Error('Engine version/dependency contract failed');
43
47
  process.stdout.write(workingTree ? 'Runtime content verified; uncommitted working tree is not release approval.\n' : 'Vendored runtime release gate passed.\n');
44
48
  }
45
- try { verify(); } catch (error) { process.stderr.write(`${error.message}\n`); process.exitCode = 1; }
49
+ if (require.main === module) { try { verify(); } catch (error) { process.stderr.write(`${error.message}\n`); process.exitCode = 1; } }
50
+ module.exports = { isPinnedModuleVersion };
@@ -7,6 +7,7 @@ const { safeRelative } = require('./pack-module-candidates');
7
7
  function verifyProductRuntime(coreRoot, resolveFrom = path.join(coreRoot, 'package.json')) {
8
8
  const manifest = JSON.parse(fs.readFileSync(path.join(coreRoot, 'module-runtime-manifest.json')));
9
9
  if (manifest.schema !== 'project-knowledge/module-content/v1' || Object.keys(manifest.modules).length !== 3) throw new Error('Incomplete module content manifest');
10
+ for (const file of ['ui/index.html', 'ui/product.js', 'ui/product.css', 'ui/favicon.svg']) if (!manifest.productFiles?.[file]) throw new Error(`Product asset missing from content manifest: ${file}`);
10
11
  const resolve = createRequire(resolveFrom);
11
12
  for (const [relative, expected] of Object.entries(manifest.productFiles || {})) {
12
13
  if (!safeRelative(relative) || crypto.createHash('sha256').update(fs.readFileSync(path.join(coreRoot, relative))).digest('hex') !== expected) throw new Error(`Product UI content mismatch: ${relative}`);
@@ -25,7 +25,9 @@ Read-only local knowledge tools:
25
25
  project-knowledge-kb get --project <projectId-or-legacy-slug> --entry <path>
26
26
  project-knowledge-kb history --project <projectId-or-legacy-slug> [--limit 20]
27
27
 
28
- Add --json for machine-readable output. These commands never modify knowledge or project configuration.\n`);
28
+ Add --scope project|domain|brain for a search range, --space <id> for a cited
29
+ shared entry, and --json for machine-readable output. These commands never
30
+ modify knowledge or project configuration.\n`);
29
31
  }
30
32
 
31
33
  async function main(argv = process.argv.slice(2), options = {}) {
@@ -38,7 +40,7 @@ async function main(argv = process.argv.slice(2), options = {}) {
38
40
  if (!args.project) throw new Error('--project is required');
39
41
  const runtime = options.runtime || new KnowledgeToolRuntime(options);
40
42
  try {
41
- const input = { project: args.project, query: args.query, limit: args.limit, entry: args.entry };
43
+ const input = { project: args.project, query: args.query, limit: args.limit, entry: args.entry, scope: args.scope, spaceId: args.spaceId || args.space };
42
44
  let result;
43
45
  if (args.command === 'search') result = await runtime.search(input);
44
46
  else if (args.command === 'ask') result = await runtime.ask(input);
@@ -11,6 +11,7 @@ const { KnowledgeToolRuntime } = require('../_site/lib/knowledge-tool-runtime');
11
11
  const { serializeErrorEnvelope, createId } = require('../_site/lib/contracts');
12
12
 
13
13
  const SERVER_NAME = 'project-knowledge';
14
+ const SCOPE = { type: 'string', enum: ['project', 'domain', 'brain'], description: 'Knowledge range: current project (default), its domain, or its brain.' };
14
15
  const SERVER_INSTRUCTIONS = `Project Knowledge is the durable source of prior project decisions and implementation history. Knowledge content is read-only; the only write operation appends an explicit supplemental Prompt event to the shared conversation truth.
15
16
 
16
17
  At the start of work in a registered Git repository, and before answering questions about prior work or implementing a non-trivial change:
@@ -56,7 +57,7 @@ const TOOLS = [
56
57
  },
57
58
  {
58
59
  name: 'project_knowledge_search',
59
- description: 'Search durable project knowledge using the current project and its explicitly related-project scope. This tool is read-only.',
60
+ description: 'Search the same durable knowledge and commit citations as the product UI, within the selected project, domain or brain. This tool is read-only.',
60
61
  inputSchema: {
61
62
  type: 'object',
62
63
  required: ['query'],
@@ -66,6 +67,7 @@ const TOOLS = [
66
67
  projectId: { type: 'string', description: 'Stable projectId returned by project_knowledge_resolve.' },
67
68
  project: { type: 'string', description: 'Optional registered project slug.' },
68
69
  limit: { type: 'integer', minimum: 1, maximum: 30, default: 8 },
70
+ scope: SCOPE,
69
71
  },
70
72
  additionalProperties: false,
71
73
  },
@@ -82,6 +84,7 @@ const TOOLS = [
82
84
  projectId: { type: 'string' },
83
85
  project: { type: 'string' },
84
86
  limit: { type: 'integer', minimum: 1, maximum: 30, default: 8 },
87
+ scope: SCOPE,
85
88
  },
86
89
  additionalProperties: false,
87
90
  },
@@ -95,6 +98,8 @@ const TOOLS = [
95
98
  properties: {
96
99
  entry: { type: 'string', minLength: 1, description: 'Entry identifier returned by search.' },
97
100
  space: { type: 'string', description: 'Optional scoped knowledge space identifier.' },
101
+ spaceId: { type: 'string', description: 'Knowledge space identifier returned by a citation; alias of space.' },
102
+ scope: SCOPE,
98
103
  repoPath: { type: 'string' },
99
104
  projectId: { type: 'string' },
100
105
  project: { type: 'string' },
@@ -112,6 +117,7 @@ const TOOLS = [
112
117
  projectId: { type: 'string' },
113
118
  project: { type: 'string' },
114
119
  limit: { type: 'integer', minimum: 1, maximum: 100, default: 20 },
120
+ scope: SCOPE,
115
121
  },
116
122
  additionalProperties: false,
117
123
  },
@@ -1,18 +1,19 @@
1
1
  {
2
2
  "schema": "project-knowledge/module-content/v1",
3
3
  "productFiles": {
4
- "ui/index.html": "e7291caab778eba3c5499d8286804ad1f4ef31c87a957f69c8fb77befc01321b",
5
- "ui/product.js": "e35c1650df239cec0a9d73197fed7ac069bb09f0c51f4752e03115784a526518",
6
- "ui/product.css": "73554abf3f951ea01a2bfe2df81748b702a6ca4488eea16bfe5afe04ef1dea70"
4
+ "ui/index.html": "5cc3f9519a0671e7d5b24a94987a96b7ee81d3ed3367e3c02cd70934f08e64c8",
5
+ "ui/product.js": "714295970c175e4ada8155422dd3b1a013e9f452efc713f528373b36030ca26d",
6
+ "ui/product.css": "70547d3f2c53b6cc5c73cb95eb8cb3faf0dc8ccee7cd6b11a89a88885de7c3f8",
7
+ "ui/favicon.svg": "c48be946b224112ebb0238b44263f7a61bda31e531afa895c2e9801c0ff24f32"
7
8
  },
8
9
  "modules": {
9
10
  "terminal": {
10
11
  "name": "@sanqianx/claude-ai-workbench",
11
12
  "installName": "claude-ai-workbench",
12
- "version": "0.13.1",
13
+ "version": "0.13.2-rc.4",
13
14
  "files": {
14
15
  "LICENSE": "c1b9df1275e769f3dbab000d1e457a2d4b0f28eb5da6c77e48dc37eeba202ed7",
15
- "README.md": "07a12d2397f625bd9d3a5e2944012d031a03c0bf1c8237e7c2b6f47cb6636685",
16
+ "README.md": "6f4176416a3cfa702d17da8987327e014fec93e34ff5bd350175c771a55c1521",
16
17
  "apps/agent-terminal/app.css": "39cc65ac65bcb390f4aa21d9b783182ca229557f6bec15090f69598120161917",
17
18
  "apps/agent-terminal/app.js": "2fedcc79f9515ebae89d1c7dc996d732aa1d0946038eaaa045438121bf27f551",
18
19
  "apps/agent-terminal/index.html": "6a52ba210696c8aed99e2786e21d2771340070d51583199dd74c8da41edf0257",
@@ -26,52 +27,54 @@
26
27
  "apps/minimal-test-host/README.md": "fa73136f4ee3865c2d91eb97b2e8c03679aa4688e44c1e1c8ec6e27d604b0de5",
27
28
  "docs/sdk/FILE_LAYOUT.md": "17882f96505c8161bfb66876684b9d2d3f50021a111b8b844502d3cb4e97870a",
28
29
  "docs/sdk/INTEGRATION.md": "d4c0c80d2d2fc610205102d703a429bfaa20f9f3a48f1718f5bab02ee90138df",
29
- "docs/sdk/openapi.yaml": "3e6cc332979a58d98073e5e04ceccef1c62aff681e78dc9f705450e6ad95006e",
30
+ "docs/sdk/openapi.yaml": "702a9cab4ccc38c186977c4bdcba653443311c676d6c7a70b7661647fa303470",
30
31
  "docs/sdk/README.md": "7ab591d39c36a3b84cfdf487ff567040ec453975f3ef0fba86dc822094667b61",
31
- "package.json": "88df20662b9034a4cfca3b5c49cf58f2ad41398d34abfd37078a13fe87642cd7",
32
+ "package.json": "87a7e1e85554e0d047eac03787c405d7017b5d83648a4968638553c136d0b7d1",
32
33
  "packages/client/index.d.ts": "fb66b7b21ac936cddcb7f74543cf4f3bb7e80c169534ec249ab8ef2356224162",
33
34
  "packages/client/index.js": "92fe5ddd32289d729f336f669e47bd9601e562f5a4309ee4fa7f7f15b567edc2",
34
- "packages/client/package.json": "4998341161acc712ef4b775004d2e791c232662269c18924029d7fa9e63e7452",
35
+ "packages/client/package.json": "796d1fb39003b780248a962967ae4f0f84a5d834b2beedeedc10b958291c3645",
35
36
  "packages/client/README.md": "342dff9b1dcbc85fccc9b980ed3e4e455aa71133af1d0805b8431ea2ac564ef8",
36
37
  "packages/contracts/index.d.ts": "edc717067bfb864c6c95df0c408a799fbf90b7552519131e6dc35af3f9eb9006",
37
38
  "packages/contracts/index.js": "565b4a88190dbb8994cd0a9309b30b00f64305d65505fff9fa360d7ce69dfb58",
38
- "packages/contracts/package.json": "26d81905c0757c918ec9d0272645e4e6c3a5e64cfc7c31eb2e40c4f31f12dde1",
39
+ "packages/contracts/package.json": "deaa5929f849f6f994df7fbb0243c77f896b8fc73edcc3c785206b898cfafa71",
39
40
  "packages/contracts/README.md": "44d83a3cc508cec6c5c20dfa1f2c08d5ea03e3afb2853639fdc0a9cc8eb5b9c8",
40
41
  "packages/core/index.d.ts": "c95b24a13f8aeeb128497833cf298790563baca6036ea5d29a9d8daff53199d7",
41
42
  "packages/core/index.js": "5579ceb1a63d3f962f5656c75f82cf60cd834fd270b4aa95e581bf38e4432448",
42
- "packages/core/package.json": "a8dacd7a973ea57bcead83668aa837c3092537397d043b6f4a381a71c7fe7c8e",
43
+ "packages/core/package.json": "6e579a889060bf6fad7709ea89a104fe4ac90854ea39107b649c44b3b83666bf",
43
44
  "packages/core/README.md": "e222c546104a168f1038d95c6c4efb8e5603edd6145ab2cab79cab977fb710e5",
44
- "packages/server/bin/agent-terminal-server.js": "b01297ab245a2b994bf42043b7469bd6e71d8f76a4bb99d4ed651e71844c152f",
45
- "packages/server/bin/claude-workbench-server.js": "a8c46ed7e71afcc10e00a104ed6f2d0ac05346a743b33c3a5bd11b1314d80f40",
45
+ "packages/server/bin/agent-terminal-server.js": "043dff4d76e3fd213b666a55e581ed1e72f9e5b8de6cb798fbf42bd39ed26861",
46
+ "packages/server/bin/claude-workbench-server.js": "b03c730b6d86faf6974afea26c74109d59b1bbc1ecc656c1d6270258708694ac",
46
47
  "packages/server/bin/claude-workbench.js": "98dbd550d4d657056a75a190e7ee0dffd9f760fba58783f3ffb8d389ad7a32de",
47
48
  "packages/server/index.d.ts": "ad39d5091056df5ec94e031a0de47c2c4ff75128ec3edadc3d3a364fca1b912b",
48
- "packages/server/index.js": "96750689d90661c49bcdd170ed3f2d4e19dafd180ae62640e2207c3b261a8918",
49
+ "packages/server/index.js": "06f2f28a838246e5f40449e449d54961f4d6fda74bb2a5b739a4bfc8fcd7e171",
49
50
  "packages/server/lib/agent-discovery.js": "7fa15684329fd287cd0869183808311bf975263255425562f2896bc2c1a69e7c",
50
- "packages/server/lib/agent-registry.js": "1c1ce6771ee3fc217293b5c5166ade8f098b6d5d68d47511bd772ba86ee438e9",
51
+ "packages/server/lib/agent-registry.js": "fbf4f3e96542502a41e7fdf77037d63c3b0444d26708ad9766bec90fbb6b38bb",
51
52
  "packages/server/lib/attachment-store.js": "5c92c45c7ec5a8b0ee9c14edb42eeda5fce93d8e654718dcd75c12e3f0bfa6e7",
52
53
  "packages/server/lib/bridges/app-server-bridge.js": "85bb644ab570a7a7e6aa26123c8e3cd2e8c11c3ff4e1270954b8e26517968f69",
53
54
  "packages/server/lib/bridges/opencode-server-bridge.js": "ab3a9330db5a497760b998dbe6af47fbe351683ad92941d7e1a820e72e382bb1",
54
55
  "packages/server/lib/capture-settings-store.js": "eb18885d7bedd3e353287dd7d1cf81e815e5d65d5d82170aa8fe5506a03de8bd",
56
+ "packages/server/lib/cli-session-recovery.js": "e66dc0ad83af18841bf3a598bb27932af42a20cf9395c16dcbaf9b022a5201b5",
55
57
  "packages/server/lib/context-resolver.js": "d3060bfe35fb184e521847fc0900cf6114f8ebf3120ce13ed39dfc224af54660",
56
58
  "packages/server/lib/conversation-capture.js": "9f3ee29003eaea4778dc1e4b7e23e868f2ba0268bd43db07317acba62f48a094",
57
59
  "packages/server/lib/diagnostics.js": "b45687fcc07f8baeb33ffd08efdc875494d4e3205887514fdfd7e1ce6370753b",
58
- "packages/server/lib/drivers/cli-json-runner.js": "c3febcea2df92b72125d053a4ffe6349e61caa98491acb6123ae964b6b90de8a",
59
- "packages/server/lib/drivers/codex-driver.js": "cb6f60048af534d836c7e95c494fbd16aa28ba24c5e94d76edb2eb9720f4cb54",
60
- "packages/server/lib/drivers/opencode-driver.js": "119b11663d926a3f5f7c63c960264784879459b3f84e6fdf482b4346697a6376",
61
- "packages/server/lib/drivers/zcode-driver.js": "507dcd56e17066703f2467a96bb3c9efca6b7b1810a78d607ac576508e8d4615",
60
+ "packages/server/lib/drivers/cli-json-runner.js": "d3ad5dc67481d69abb3593ca58e7ca703bf1c438042d634d83642803849d797f",
61
+ "packages/server/lib/drivers/codex-driver.js": "d472a6229aab8e3e5a568fa5f6c63de77afcf2b84c7a930101dd94e8b11a640e",
62
+ "packages/server/lib/drivers/opencode-driver.js": "322043d2d1912204c17b8c46f14d19bf132c096365cdacfdb98cfc0855e88c73",
63
+ "packages/server/lib/drivers/zcode-driver.js": "89c99e3f40c8064260d83153116c2c12acfec9485df2e495207ba3a64bb95764",
64
+ "packages/server/lib/drivers/zcode-profile-runtime.js": "77c5ac83551cc424375918863d4a31039984492c3a1c987a615a072ac7cb1f14",
62
65
  "packages/server/lib/event-stream.js": "b0f20bac19933a1a428c22938ae2666a1231b74a4330619b885171662133f48b",
63
66
  "packages/server/lib/folder-picker.js": "70f55df999262b90433f2b4251aa69dd70a23b55a84756b5f1d24dbeacfbda31",
64
67
  "packages/server/lib/http-handler.js": "c0b1cc19c66beef0f0d9b8db48ede6b110bff59d410b81673bab2e81c05b01d7",
65
- "packages/server/lib/json-file.js": "c922e10116655cd519a5365aaac5468266f6d8a76e41db33eaa51f94b79dae13",
68
+ "packages/server/lib/json-file.js": "4252b57abcd0aafa45c584bac98fcbaf09174774addbb5a4798b381a7aeb35cc",
66
69
  "packages/server/lib/knowledge-context.js": "82023a94472fcb6fd6a74a53be43091473dbef11e6ac94ff9482c8a7fbc5c286",
67
70
  "packages/server/lib/model-detection.js": "fa52213200c1f1a1f00e463ada57c415bf1bd4e2aedfebd04de50750509d06cf",
68
- "packages/server/lib/profile-store.js": "2a4496970c4b54a814f043cdeda87b897ad80d298dd96385964cf17e8164e6c6",
71
+ "packages/server/lib/profile-store.js": "70a9ff6aa31fe438ba8431f3e461f72e5d977f3510f2c42d39e9133e2f3491a8",
69
72
  "packages/server/lib/project-store.js": "5225c78f3216340f01b99356496c8e2c2d9cfc6247954a3f00b273dd2cc5b692",
70
73
  "packages/server/lib/session-archive-store.js": "d3335b832a6e9fb9792991056f6596a997a4959efa6e62b60fb60133fb724196",
71
74
  "packages/server/lib/system-doctor.js": "2b0e858d69d8fb268eaed950c9883473ee9850684b532bc2db8e14674a974919",
72
75
  "packages/server/lib/ui-preferences-store.js": "e108cb22e7cc1f3438704913d5401e01de2c0e717eb2abd3bdc4727209393819",
73
- "packages/server/lib/workbench-service.js": "b5caac09665b21a118a0cd826adfa3f3006e68989182e4d80bf3a4554b951250",
74
- "packages/server/package.json": "6e80c900440c99144a629458c287bc1215a2aa0841c7493612f8db00e9f5dc66",
76
+ "packages/server/lib/workbench-service.js": "92b9323db8742bbdd69abd111c81cab86b225103596f6818b007fbfe2376fc6f",
77
+ "packages/server/package.json": "618af8f48eb5da8f163d061c1832973a0b1e8a733fb795ff9c00f56379a4d1b1",
75
78
  "packages/server/README.md": "a34cfaa4f4e859008b44e2be8e1aafb56e97fe83e6129c968a8562945fa843f3",
76
79
  "packages/ui/ai-profile-settings.d.ts": "0551b6c6eda6d18ea89a976daddf01b2161195f4874fe2d67a57cd9ecc6ce643",
77
80
  "packages/ui/ai-profile-settings.js": "e92bbac67a1199d473e4e44b32d1cc76c5b6c79306d4fef9d9067a1bb6ec42ca",
@@ -79,7 +82,7 @@
79
82
  "packages/ui/claude-terminal.js": "96bd217a4a7e4792ae3fbaaf46249ecee13b0f4e01fc6d25a1b8b22d8f8fe00c",
80
83
  "packages/ui/index.d.ts": "e547ab39640fe7519fb367b78442dc8a2c51b2efd17b66f8b0a003b154b36ead",
81
84
  "packages/ui/index.js": "f4394aabd395938f5c3fe587e430471d4033e83945a9b9c7e0149ad4040982c9",
82
- "packages/ui/package.json": "fd52ffefcb0dca34c5058d84559fe25a8d635469b039c9fd05b499889636731b",
85
+ "packages/ui/package.json": "f5da277437bfb5308bb0cc8c998cc7b02cc92db7dd767a2242eedcad30200b81",
83
86
  "packages/ui/README.md": "793c4a9c286fee23f39062a1976ca3afe9d2816dcdb55e156ba940e1ef514f89",
84
87
  "packages/ui/theme.css": "8f03a081272a7db11b196f7a70d0fafb1f8d954778f329f1ba53d110d9d5fd98",
85
88
  "src/assets/claude-prompts.json": "cb111f2e0a45afe8a31c251a504d1ab5375966ed61291660e61fd2efd77f6d9f",
@@ -92,7 +95,7 @@
92
95
  "src/backend/lib/ai-vendor-presets.js": "02c6de9c2e89ad0286426e8eb4900c3c6a4960ef0e8f9d27ffb5836062abfbb2",
93
96
  "src/backend/lib/ai-workspace.js": "969917f26cd0b0a272932714819d838a2bab2a5aac5c4e946647dfa3afa479bf",
94
97
  "src/backend/lib/automation-config.js": "c23b868bbcfbcece4465c9c939faccaef582667e858f3f36fc7b6d19bcd545e6",
95
- "src/backend/lib/claude-cli-runner.js": "05cc4e57e7e52721de8d9e14eff1f37424bd094796bbbc70fcbca0a6c203d868",
98
+ "src/backend/lib/claude-cli-runner.js": "d72ab781fc9b7194fcb4ea44dd8b7d6ef3a8812924af261d37859e8e5602d379",
96
99
  "src/backend/lib/data-dir.js": "a62d96d1ab538e37690ad31fe4f51e84120b55b6bc767661ed98ad9242f879db",
97
100
  "src/backend/lib/llm-client.js": "76d1a73fbea445b5ac34c23d1a3b084e0884c5efed6f7d3b9ed76d406d2cd038",
98
101
  "src/backend/lib/model-context-windows.js": "f64f7c995143407b7390105087e3ebcd56a5a3ba2fd3019478a86f9e3c6b7896",
@@ -109,9 +112,9 @@
109
112
  "vectorHub": {
110
113
  "name": "@sanqianx/vector-hub",
111
114
  "installName": "@sanqianx/vector-hub",
112
- "version": "1.0.7",
115
+ "version": "1.0.8-rc.2",
113
116
  "files": {
114
- "README.md": "1998a65a3a50419fee13016b201621aaba6a5868038cb5f18a7f0a15fef74900",
117
+ "README.md": "b0d0fd647aef14c803ac4573f58bd2d425c2dc9bc736187a4684d7caba473184",
115
118
  "dist/cjs/bin.d.ts": "43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012",
116
119
  "dist/cjs/bin.js": "8d0317ce087d22074b4ad350d63bf39cd6d218da565496621cd0daf4245cbdc4",
117
120
  "dist/cjs/bin.js.map": "818e872380d9c7ba045238ba65ce77111ba822b356be26327ed05936e5667e5e",
@@ -133,12 +136,12 @@
133
136
  "dist/cjs/server/folder-picker.d.ts": "b9c59dbc834fff668b1894f516450c2edc985c7bfac31edf9b7b4e766474b32b",
134
137
  "dist/cjs/server/folder-picker.js": "053121152a210c899e8593d60670a2a510b435c3b479300c572aa4bc8443e58e",
135
138
  "dist/cjs/server/folder-picker.js.map": "dce1ad1b03c8a6a4fba7b3cacec5b65e55c1dfd1886c5e70df384efd1a5c68a6",
136
- "dist/cjs/server/manager.d.ts": "f2fc59843006b2a96d9f1d6a39ac02e359e6016068c6f9cc1b16705979b2f03a",
137
- "dist/cjs/server/manager.js": "eb10297ef7f37a0a736c7662e4a3f524b25110681c166969df099fce8198468a",
138
- "dist/cjs/server/manager.js.map": "6b1e0d041a9d292fc7fdd351e09331477d965c6e7b48bafa7d50ec66902399f5",
139
+ "dist/cjs/server/manager.d.ts": "d23ee9c3f9b72ff89c511f81f5cfb6e2b62d4ba4963099c3c9f5a65531216097",
140
+ "dist/cjs/server/manager.js": "aea5c81a048cf2bd7736c289dbee9cf2d0bea4caf7093a1d8f8179d6fcea48a3",
141
+ "dist/cjs/server/manager.js.map": "594ac93b2986160e47f927683f2f5feee84054dbf7255d965ada9dea561845b8",
139
142
  "dist/cjs/server/server.d.ts": "13288ace9aa6ec016a2b06dc036868324ac6c23c7e73771e95d120be778f238a",
140
- "dist/cjs/server/server.js": "844b981bbbb905552973e74d61cdf773c54e6bf2eb928280de1d286c8f17ad0a",
141
- "dist/cjs/server/server.js.map": "b0ca6318fa5aa7bebce6f84c725d2f7329231ad6c195066de96bb1de2e90c588",
143
+ "dist/cjs/server/server.js": "43d6e18a1a36fd1af6179ff98d356efaee1da9464c85d76e9bf057b71741534e",
144
+ "dist/cjs/server/server.js.map": "d599dbfbe0f98abaf103849eafee70b407d332ff0d767c1d95f54c80e85bf2bb",
142
145
  "dist/esm/bin.d.ts": "43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012",
143
146
  "dist/esm/bin.js": "69f6059ce2336eb7f0d9503f86c83da787aaf74a8bfd804c694ba5b2e1728be0",
144
147
  "dist/esm/bin.js.map": "fc174c2b5c66c20ff88184ddeb00577406185945ccadb0bddbb2014909339e9e",
@@ -161,14 +164,14 @@
161
164
  "dist/esm/server/folder-picker.d.ts": "b9c59dbc834fff668b1894f516450c2edc985c7bfac31edf9b7b4e766474b32b",
162
165
  "dist/esm/server/folder-picker.js": "6c8247e431b7181c45fb169b29e5825a0b3589f44e1625b3a5a291d7b8358042",
163
166
  "dist/esm/server/folder-picker.js.map": "f70723213f032a0f10f538289a176a50fc8f02c200b0194479ffc139b5fbb13b",
164
- "dist/esm/server/manager.d.ts": "f2fc59843006b2a96d9f1d6a39ac02e359e6016068c6f9cc1b16705979b2f03a",
165
- "dist/esm/server/manager.js": "9c89e36fa7d8eef98f29c9180c455d27c1b3dca991df4249d5dcda759b43d9a3",
166
- "dist/esm/server/manager.js.map": "c754044a92afa6f95155871054fccb79eb7b9753803dff0a36a3336d99892d76",
167
+ "dist/esm/server/manager.d.ts": "d23ee9c3f9b72ff89c511f81f5cfb6e2b62d4ba4963099c3c9f5a65531216097",
168
+ "dist/esm/server/manager.js": "2f1772ce5885128694e8cd9c89ca7ae74694a1f85758fc8e17b577b7ab54c2e4",
169
+ "dist/esm/server/manager.js.map": "f68a87c9763e8c4e3ddfc98e981ada4ea83922793035f19051b88dc3e7f47bc0",
167
170
  "dist/esm/server/server.d.ts": "13288ace9aa6ec016a2b06dc036868324ac6c23c7e73771e95d120be778f238a",
168
- "dist/esm/server/server.js": "6781d298e17451013e2fe475e282a1e9e853be0788819583cdfab50662d7940f",
169
- "dist/esm/server/server.js.map": "3abb22e239bd841307a323e1b02b51ebba43ec0a708d32c9d1ec35aa44967090",
170
- "package.json": "3812a503cc8ac2197d980f920a28e54c141193db7ab8e82c8718655b40df4f08",
171
- "ui/index.html": "20c11d7e77e4fd57083ea9ecc434231a64d4b49b6f64e49b7c31b3dbaf044f19",
171
+ "dist/esm/server/server.js": "df4caa8a596a9724c526dab5395e5018f63164ef0d10522d75ca4c44d62c1ee3",
172
+ "dist/esm/server/server.js.map": "3743325b664476176931989f2d762d53b48c5eb4bcbf3d81ab222c4231d026be",
173
+ "package.json": "812251c1b6f091da2f7ab06c93446e5f7c19bf4715074919e38e956e0eca373b",
174
+ "ui/index.html": "7301a595d625dadcd424069e7bb978004bfb6118eddef7a223bd25449ca6e0eb",
172
175
  "ui/vendor/marked.min.js": "c68075672d976e4777390560baa112194855bd4404b13647da4855aae1f9360c"
173
176
  }
174
177
  },
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@sanqianx/project-knowledge",
3
- "version": "5.0.8",
3
+ "version": "5.0.9-rc.10",
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": {
7
7
  "start": "node _site/server.js",
8
8
  "test": "node _site/_test/run-all-tests.js",
9
- "release:sync": "node _site/scripts/sync-release-version.js",
9
+ "release:sync": "node _site/scripts/sync-release-version.js --web-only",
10
10
  "vendor:modules": "node _site/scripts/vendor-modules.js",
11
11
  "runtime:verify": "node _site/scripts/verify-module-runtime.js --working-tree",
12
- "release:verify": "node _site/scripts/sync-release-version.js --check && node _site/scripts/verify-module-runtime.js && node _site/scripts/verify-product-runtime.js && node _site/_test/integration-adapters-test.js",
12
+ "release:verify": "node _site/scripts/sync-release-version.js --check --web-only && node _site/scripts/verify-module-runtime.js && node _site/scripts/verify-product-runtime.js && node _site/_test/integration-adapters-test.js",
13
13
  "preversion": "npm run release:verify",
14
- "version": "node _site/scripts/sync-release-version.js --stage",
14
+ "version": "node _site/scripts/sync-release-version.js --stage --web-only",
15
15
  "postversion": "npm run release:verify"
16
16
  },
17
17
  "bin": {
@@ -81,10 +81,10 @@
81
81
  "@lancedb/lancedb": "0.31.0",
82
82
  "@modelcontextprotocol/sdk": "1.29.0",
83
83
  "@sanqianx/ai-coding-event-bridge-console": "0.7.2",
84
- "@sanqianx/vector-hub": "1.0.7",
84
+ "@sanqianx/vector-hub": "1.0.8-rc.2",
85
85
  "buffer": "^6.0.3",
86
86
  "cheerio": "^1.2.0",
87
- "claude-ai-workbench": "npm:@sanqianx/claude-ai-workbench@0.13.1",
87
+ "claude-ai-workbench": "npm:@sanqianx/claude-ai-workbench@0.13.2-rc.4",
88
88
  "cross-spawn": "7.0.6",
89
89
  "dotenv": "^17.4.2",
90
90
  "gpt-tokenizer": "^3.4.0",
@@ -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.8",
4
+ "version": "5.0.9-rc.10",
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.8",
3
+ "version": "5.0.9-rc.10",
4
4
  "description": "Read durable project decisions and implementation history from Project Knowledge.",
5
5
  "author": {
6
6
  "name": "SanQianX",