@sanqianx/project-knowledge 5.0.9-rc.7 → 5.0.9-rc.8
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +13 -0
- package/README.md +7 -0
- package/_site/_test/vector-storage-root-test.js +52 -0
- package/_site/lib/module-bridge.js +24 -8
- package/_site/lib/server-app.js +3 -3
- package/_site/lib/storage-layout.js +4 -0
- package/module-runtime-manifest.json +30 -30
- package/package.json +3 -3
- package/plugins/project-knowledge/.claude-plugin/plugin.json +1 -1
- package/plugins/project-knowledge/.codex-plugin/plugin.json +1 -1
- package/plugins/project-knowledge/.mcp.json +1 -1
- package/ui/index.html +1 -1
- package/ui/product.js +10 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [5.0.9-rc.8] - 2026-10-11
|
|
4
|
+
|
|
5
|
+
- Pin Workbench 0.13.2-rc.4: atomically replace all native Agent histories,
|
|
6
|
+
retaining the previous complete record on disk-full or locked-file errors.
|
|
7
|
+
CLI fallback no longer deletes durable history before a failed rename.
|
|
8
|
+
- Keep the original disk-full loss and separate successful background recovery
|
|
9
|
+
records. Candidate acceptance includes faults against downloaded module bytes.
|
|
10
|
+
- Pin vector-hub 1.0.8-rc.2. Managed indexes now follow the knowledge root
|
|
11
|
+
under `.indexes`; show the acknowledged actual directory in System Status.
|
|
12
|
+
Rebuild on a root/model change while retaining the old index directory;
|
|
13
|
+
serialize queued writes and avoid a full paid rebuild on normal restart.
|
|
14
|
+
- Do not promote latest until installed and existing-v5 acceptance pass.
|
|
15
|
+
|
|
3
16
|
## [5.0.9-rc.7] - 2026-10-11
|
|
4
17
|
|
|
5
18
|
- Vendor engine 0.2.3-rc.3: recognize promoted commit identifiers inside
|
package/README.md
CHANGED
|
@@ -127,6 +127,13 @@ visible as dirty state and is retried.
|
|
|
127
127
|
vector-hub owns the derived index; the shell no longer runs a second index
|
|
128
128
|
writer. Failed indexing leaves promoted Markdown intact and repairable.
|
|
129
129
|
|
|
130
|
+
Managed vectors follow the configured knowledge root at `<knowledge>/.indexes`.
|
|
131
|
+
The system drawer displays the actual directory and pending wiring separately.
|
|
132
|
+
Root changes leave project Markdown and old indexes untouched, drain existing
|
|
133
|
+
index writes, switch subsequent writes, and rebuild registered knowledge with
|
|
134
|
+
the configured embedding model. Credentials and small runtime metadata remain
|
|
135
|
+
in the product data directory; no expensive historical Agent analysis is started.
|
|
136
|
+
|
|
130
137
|
The application does not create, edit, refresh, or delete `CLAUDE.md`.
|
|
131
138
|
|
|
132
139
|
## Requirement capture
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const assert = require('node:assert/strict');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { StorageLayout } = require('../lib/storage-layout');
|
|
5
|
+
const { ModuleBridge } = require('../lib/module-bridge');
|
|
6
|
+
const root = path.resolve('D:/knowledge storage 中文');
|
|
7
|
+
const layout = new StorageLayout({ dataDir: path.resolve('D:/metadata') });
|
|
8
|
+
assert.equal(layout.getVectorRootPath({ knowledge: { rootPath: root } }), path.join(root, '.indexes'));
|
|
9
|
+
assert.equal(layout.getVectorRootPath({ knowledge: { rootPath: '' } }), path.join(layout.getDataDir(), 'vectorhub'));
|
|
10
|
+
const settingsStore = { read: () => ({ knowledge: { rootPath: root }, brain: { id: 'brain-default', domains: [] } }) };
|
|
11
|
+
const bridge = new ModuleBridge({ settingsStore, dataDir: layout.getDataDir() });
|
|
12
|
+
const spec = bridge._supervisedSpecs().find(spec => spec.name === 'vector-hub');
|
|
13
|
+
assert.equal(spec.env.VECTOR_HUB_ROOT, path.join(root, '.indexes'));
|
|
14
|
+
assert.equal(spec.env.VECTOR_HUB_CONFIG, path.join(layout.getDataDir(), 'vectorhub', 'config.json'));
|
|
15
|
+
const calls = [];
|
|
16
|
+
bridge._fetch = async (url, init) => { const body = JSON.parse(init.body); calls.push({ url, body }); return { ok: true, json: async () => url.includes('/api/internal/runtime-config') ? { ok: true, rootPath: path.join(root, '.indexes') } : {} }; };
|
|
17
|
+
bridge.syncEngineConfiguration().then(async status => {
|
|
18
|
+
assert.equal(calls.find(call => call.url.includes('/api/internal/runtime-config')).body.storageRoot, path.join(root, '.indexes'));
|
|
19
|
+
assert.equal(status.indexStorage.status, 'ready');
|
|
20
|
+
let currentRoot = root, release, started;
|
|
21
|
+
const entered = new Promise(resolve => { started = resolve; });
|
|
22
|
+
const held = new Promise(resolve => { release = resolve; });
|
|
23
|
+
const queued = new ModuleBridge({ dataDir: layout.getDataDir(), settingsStore: { read: () => ({ knowledge: { rootPath: currentRoot }, brain: { id: 'brain-default', domains: [] } }) } });
|
|
24
|
+
const applied = [];
|
|
25
|
+
queued._fetch = async (url, init) => {
|
|
26
|
+
const body = JSON.parse(init.body);
|
|
27
|
+
if (url.endsWith('/api/internal/runtime-config')) {
|
|
28
|
+
applied.push(body.storageRoot);
|
|
29
|
+
if (applied.length === 1) { started(); await held; }
|
|
30
|
+
return { ok: true, json: async () => ({ rootPath: body.storageRoot }) };
|
|
31
|
+
}
|
|
32
|
+
return { ok: true, json: async () => null };
|
|
33
|
+
};
|
|
34
|
+
const first = queued.syncEngineConfiguration(); await entered;
|
|
35
|
+
currentRoot = path.join(root, 'new root');
|
|
36
|
+
const second = queued.syncEngineConfiguration(); release();
|
|
37
|
+
await first;
|
|
38
|
+
const latest = await second;
|
|
39
|
+
assert.deepEqual(applied, [path.join(root, '.indexes'), path.join(currentRoot, '.indexes')]);
|
|
40
|
+
assert.equal(latest.indexStorage.actualPath, path.join(currentRoot, '.indexes'));
|
|
41
|
+
assert.equal(latest.indexStorage.status, 'ready');
|
|
42
|
+
const broken = new ModuleBridge({ dataDir: layout.getDataDir(), settingsStore: { read: () => { throw new Error('corrupt settings'); } } });
|
|
43
|
+
let revoked;
|
|
44
|
+
broken._fetch = async (url, init) => {
|
|
45
|
+
if (url.endsWith('/api/internal/runtime-config')) revoked = JSON.parse(init.body);
|
|
46
|
+
return { ok: false };
|
|
47
|
+
};
|
|
48
|
+
const unavailable = await broken.syncEngineConfiguration();
|
|
49
|
+
assert.deepEqual(revoked, { settings: null });
|
|
50
|
+
assert.equal(unavailable.indexStorage.status, 'pending');
|
|
51
|
+
console.log('vector-storage-root-test PASS');
|
|
52
|
+
}).catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -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
|
-
|
|
314
|
-
if (this.
|
|
315
|
-
this.
|
|
316
|
-
|
|
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, 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) {
|
|
@@ -341,10 +351,15 @@ class ModuleBridge {
|
|
|
341
351
|
const resolved = await this._fetch(`${this.terminalUrl}/api/claude-workbench/v1/internal/embedding-config`, { method: 'POST', headers, body: '{}' });
|
|
342
352
|
if (resolved.ok) settings = await resolved.json();
|
|
343
353
|
} 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 }) });
|
|
354
|
+
const applied = await this._fetch(`${this.vectorHubUrl}/api/internal/runtime-config`, { method: 'POST', headers, body: JSON.stringify({ settings, ...(indexPath ? { storageRoot: indexPath } : {}) }) });
|
|
345
355
|
status.embedding = applied.ok && !!settings;
|
|
356
|
+
if (applied.ok) {
|
|
357
|
+
const result = await applied.json();
|
|
358
|
+
status.indexStorage.actualPath = result.rootPath || null;
|
|
359
|
+
status.indexStorage.status = result.rootPath && path.resolve(result.rootPath) === indexPath ? 'ready' : 'pending';
|
|
360
|
+
}
|
|
346
361
|
} catch { /* Public status contains no resolved configuration. */ }
|
|
347
|
-
this.
|
|
362
|
+
this.configStatus = status;
|
|
348
363
|
return status;
|
|
349
364
|
}
|
|
350
365
|
|
|
@@ -559,12 +574,13 @@ class ModuleBridge {
|
|
|
559
574
|
this.logger.warn('modules.supervisor', '@sanqianx/vector-hub runtime not installed; expecting an external service.', {});
|
|
560
575
|
} else {
|
|
561
576
|
const dataDir = this.dataDir || require('./data-dir').getDataDir();
|
|
562
|
-
const
|
|
577
|
+
const configRoot = path.join(dataDir, 'vectorhub');
|
|
578
|
+
const root = new StorageLayout({ dataDir }).getVectorRootPath(this.settingsStore?.read());
|
|
563
579
|
specs.push({
|
|
564
580
|
name: 'vector-hub',
|
|
565
581
|
command: `node ${JSON.stringify(vectorHubEntry)} serve --host ${urlHost(this.vectorHubUrl)} --port ${urlPort(this.vectorHubUrl, 8787)} --root ${JSON.stringify(root)}`,
|
|
566
582
|
url: this.vectorHubUrl,
|
|
567
|
-
env: { VECTOR_HUB_ROOT: root, VECTOR_HUB_CONFIG: path.join(
|
|
583
|
+
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
584
|
});
|
|
569
585
|
}
|
|
570
586
|
}
|
package/_site/lib/server-app.js
CHANGED
|
@@ -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) });
|
|
@@ -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); }
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "project-knowledge/module-content/v1",
|
|
3
3
|
"productFiles": {
|
|
4
|
-
"ui/index.html": "
|
|
5
|
-
"ui/product.js": "
|
|
4
|
+
"ui/index.html": "5cc3f9519a0671e7d5b24a94987a96b7ee81d3ed3367e3c02cd70934f08e64c8",
|
|
5
|
+
"ui/product.js": "1081a5b01f2f46c4828b63873670360de85d78e7830eebbec1721ddb1618e8e1",
|
|
6
6
|
"ui/product.css": "3f89daeb52c5f1ed8a79150c9a84200187474a013fd97c6d7c8799d850e5b0b7",
|
|
7
7
|
"ui/favicon.svg": "c48be946b224112ebb0238b44263f7a61bda31e531afa895c2e9801c0ff24f32"
|
|
8
8
|
},
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
"terminal": {
|
|
11
11
|
"name": "@sanqianx/claude-ai-workbench",
|
|
12
12
|
"installName": "claude-ai-workbench",
|
|
13
|
-
"version": "0.13.2-rc.
|
|
13
|
+
"version": "0.13.2-rc.4",
|
|
14
14
|
"files": {
|
|
15
15
|
"LICENSE": "c1b9df1275e769f3dbab000d1e457a2d4b0f28eb5da6c77e48dc37eeba202ed7",
|
|
16
|
-
"README.md": "
|
|
16
|
+
"README.md": "6f4176416a3cfa702d17da8987327e014fec93e34ff5bd350175c771a55c1521",
|
|
17
17
|
"apps/agent-terminal/app.css": "39cc65ac65bcb390f4aa21d9b783182ca229557f6bec15090f69598120161917",
|
|
18
18
|
"apps/agent-terminal/app.js": "2fedcc79f9515ebae89d1c7dc996d732aa1d0946038eaaa045438121bf27f551",
|
|
19
19
|
"apps/agent-terminal/index.html": "6a52ba210696c8aed99e2786e21d2771340070d51583199dd74c8da41edf0257",
|
|
@@ -27,20 +27,20 @@
|
|
|
27
27
|
"apps/minimal-test-host/README.md": "fa73136f4ee3865c2d91eb97b2e8c03679aa4688e44c1e1c8ec6e27d604b0de5",
|
|
28
28
|
"docs/sdk/FILE_LAYOUT.md": "17882f96505c8161bfb66876684b9d2d3f50021a111b8b844502d3cb4e97870a",
|
|
29
29
|
"docs/sdk/INTEGRATION.md": "d4c0c80d2d2fc610205102d703a429bfaa20f9f3a48f1718f5bab02ee90138df",
|
|
30
|
-
"docs/sdk/openapi.yaml": "
|
|
30
|
+
"docs/sdk/openapi.yaml": "702a9cab4ccc38c186977c4bdcba653443311c676d6c7a70b7661647fa303470",
|
|
31
31
|
"docs/sdk/README.md": "7ab591d39c36a3b84cfdf487ff567040ec453975f3ef0fba86dc822094667b61",
|
|
32
|
-
"package.json": "
|
|
32
|
+
"package.json": "87a7e1e85554e0d047eac03787c405d7017b5d83648a4968638553c136d0b7d1",
|
|
33
33
|
"packages/client/index.d.ts": "fb66b7b21ac936cddcb7f74543cf4f3bb7e80c169534ec249ab8ef2356224162",
|
|
34
34
|
"packages/client/index.js": "92fe5ddd32289d729f336f669e47bd9601e562f5a4309ee4fa7f7f15b567edc2",
|
|
35
|
-
"packages/client/package.json": "
|
|
35
|
+
"packages/client/package.json": "796d1fb39003b780248a962967ae4f0f84a5d834b2beedeedc10b958291c3645",
|
|
36
36
|
"packages/client/README.md": "342dff9b1dcbc85fccc9b980ed3e4e455aa71133af1d0805b8431ea2ac564ef8",
|
|
37
37
|
"packages/contracts/index.d.ts": "edc717067bfb864c6c95df0c408a799fbf90b7552519131e6dc35af3f9eb9006",
|
|
38
38
|
"packages/contracts/index.js": "565b4a88190dbb8994cd0a9309b30b00f64305d65505fff9fa360d7ce69dfb58",
|
|
39
|
-
"packages/contracts/package.json": "
|
|
39
|
+
"packages/contracts/package.json": "deaa5929f849f6f994df7fbb0243c77f896b8fc73edcc3c785206b898cfafa71",
|
|
40
40
|
"packages/contracts/README.md": "44d83a3cc508cec6c5c20dfa1f2c08d5ea03e3afb2853639fdc0a9cc8eb5b9c8",
|
|
41
41
|
"packages/core/index.d.ts": "c95b24a13f8aeeb128497833cf298790563baca6036ea5d29a9d8daff53199d7",
|
|
42
42
|
"packages/core/index.js": "5579ceb1a63d3f962f5656c75f82cf60cd834fd270b4aa95e581bf38e4432448",
|
|
43
|
-
"packages/core/package.json": "
|
|
43
|
+
"packages/core/package.json": "6e579a889060bf6fad7709ea89a104fe4ac90854ea39107b649c44b3b83666bf",
|
|
44
44
|
"packages/core/README.md": "e222c546104a168f1038d95c6c4efb8e5603edd6145ab2cab79cab977fb710e5",
|
|
45
45
|
"packages/server/bin/agent-terminal-server.js": "043dff4d76e3fd213b666a55e581ed1e72f9e5b8de6cb798fbf42bd39ed26861",
|
|
46
46
|
"packages/server/bin/claude-workbench-server.js": "b03c730b6d86faf6974afea26c74109d59b1bbc1ecc656c1d6270258708694ac",
|
|
@@ -57,15 +57,15 @@
|
|
|
57
57
|
"packages/server/lib/context-resolver.js": "d3060bfe35fb184e521847fc0900cf6114f8ebf3120ce13ed39dfc224af54660",
|
|
58
58
|
"packages/server/lib/conversation-capture.js": "9f3ee29003eaea4778dc1e4b7e23e868f2ba0268bd43db07317acba62f48a094",
|
|
59
59
|
"packages/server/lib/diagnostics.js": "b45687fcc07f8baeb33ffd08efdc875494d4e3205887514fdfd7e1ce6370753b",
|
|
60
|
-
"packages/server/lib/drivers/cli-json-runner.js": "
|
|
61
|
-
"packages/server/lib/drivers/codex-driver.js": "
|
|
62
|
-
"packages/server/lib/drivers/opencode-driver.js": "
|
|
63
|
-
"packages/server/lib/drivers/zcode-driver.js": "
|
|
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
64
|
"packages/server/lib/drivers/zcode-profile-runtime.js": "77c5ac83551cc424375918863d4a31039984492c3a1c987a615a072ac7cb1f14",
|
|
65
65
|
"packages/server/lib/event-stream.js": "b0f20bac19933a1a428c22938ae2666a1231b74a4330619b885171662133f48b",
|
|
66
66
|
"packages/server/lib/folder-picker.js": "70f55df999262b90433f2b4251aa69dd70a23b55a84756b5f1d24dbeacfbda31",
|
|
67
67
|
"packages/server/lib/http-handler.js": "c0b1cc19c66beef0f0d9b8db48ede6b110bff59d410b81673bab2e81c05b01d7",
|
|
68
|
-
"packages/server/lib/json-file.js": "
|
|
68
|
+
"packages/server/lib/json-file.js": "4252b57abcd0aafa45c584bac98fcbaf09174774addbb5a4798b381a7aeb35cc",
|
|
69
69
|
"packages/server/lib/knowledge-context.js": "82023a94472fcb6fd6a74a53be43091473dbef11e6ac94ff9482c8a7fbc5c286",
|
|
70
70
|
"packages/server/lib/model-detection.js": "fa52213200c1f1a1f00e463ada57c415bf1bd4e2aedfebd04de50750509d06cf",
|
|
71
71
|
"packages/server/lib/profile-store.js": "70a9ff6aa31fe438ba8431f3e461f72e5d977f3510f2c42d39e9133e2f3491a8",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"packages/server/lib/system-doctor.js": "2b0e858d69d8fb268eaed950c9883473ee9850684b532bc2db8e14674a974919",
|
|
75
75
|
"packages/server/lib/ui-preferences-store.js": "e108cb22e7cc1f3438704913d5401e01de2c0e717eb2abd3bdc4727209393819",
|
|
76
76
|
"packages/server/lib/workbench-service.js": "92b9323db8742bbdd69abd111c81cab86b225103596f6818b007fbfe2376fc6f",
|
|
77
|
-
"packages/server/package.json": "
|
|
77
|
+
"packages/server/package.json": "618af8f48eb5da8f163d061c1832973a0b1e8a733fb795ff9c00f56379a4d1b1",
|
|
78
78
|
"packages/server/README.md": "a34cfaa4f4e859008b44e2be8e1aafb56e97fe83e6129c968a8562945fa843f3",
|
|
79
79
|
"packages/ui/ai-profile-settings.d.ts": "0551b6c6eda6d18ea89a976daddf01b2161195f4874fe2d67a57cd9ecc6ce643",
|
|
80
80
|
"packages/ui/ai-profile-settings.js": "e92bbac67a1199d473e4e44b32d1cc76c5b6c79306d4fef9d9067a1bb6ec42ca",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"packages/ui/claude-terminal.js": "96bd217a4a7e4792ae3fbaaf46249ecee13b0f4e01fc6d25a1b8b22d8f8fe00c",
|
|
83
83
|
"packages/ui/index.d.ts": "e547ab39640fe7519fb367b78442dc8a2c51b2efd17b66f8b0a003b154b36ead",
|
|
84
84
|
"packages/ui/index.js": "f4394aabd395938f5c3fe587e430471d4033e83945a9b9c7e0149ad4040982c9",
|
|
85
|
-
"packages/ui/package.json": "
|
|
85
|
+
"packages/ui/package.json": "f5da277437bfb5308bb0cc8c998cc7b02cc92db7dd767a2242eedcad30200b81",
|
|
86
86
|
"packages/ui/README.md": "793c4a9c286fee23f39062a1976ca3afe9d2816dcdb55e156ba940e1ef514f89",
|
|
87
87
|
"packages/ui/theme.css": "8f03a081272a7db11b196f7a70d0fafb1f8d954778f329f1ba53d110d9d5fd98",
|
|
88
88
|
"src/assets/claude-prompts.json": "cb111f2e0a45afe8a31c251a504d1ab5375966ed61291660e61fd2efd77f6d9f",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"src/backend/lib/ai-vendor-presets.js": "02c6de9c2e89ad0286426e8eb4900c3c6a4960ef0e8f9d27ffb5836062abfbb2",
|
|
96
96
|
"src/backend/lib/ai-workspace.js": "969917f26cd0b0a272932714819d838a2bab2a5aac5c4e946647dfa3afa479bf",
|
|
97
97
|
"src/backend/lib/automation-config.js": "c23b868bbcfbcece4465c9c939faccaef582667e858f3f36fc7b6d19bcd545e6",
|
|
98
|
-
"src/backend/lib/claude-cli-runner.js": "
|
|
98
|
+
"src/backend/lib/claude-cli-runner.js": "d72ab781fc9b7194fcb4ea44dd8b7d6ef3a8812924af261d37859e8e5602d379",
|
|
99
99
|
"src/backend/lib/data-dir.js": "a62d96d1ab538e37690ad31fe4f51e84120b55b6bc767661ed98ad9242f879db",
|
|
100
100
|
"src/backend/lib/llm-client.js": "76d1a73fbea445b5ac34c23d1a3b084e0884c5efed6f7d3b9ed76d406d2cd038",
|
|
101
101
|
"src/backend/lib/model-context-windows.js": "f64f7c995143407b7390105087e3ebcd56a5a3ba2fd3019478a86f9e3c6b7896",
|
|
@@ -112,9 +112,9 @@
|
|
|
112
112
|
"vectorHub": {
|
|
113
113
|
"name": "@sanqianx/vector-hub",
|
|
114
114
|
"installName": "@sanqianx/vector-hub",
|
|
115
|
-
"version": "1.0.8-rc.
|
|
115
|
+
"version": "1.0.8-rc.2",
|
|
116
116
|
"files": {
|
|
117
|
-
"README.md": "
|
|
117
|
+
"README.md": "b0d0fd647aef14c803ac4573f58bd2d425c2dc9bc736187a4684d7caba473184",
|
|
118
118
|
"dist/cjs/bin.d.ts": "43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012",
|
|
119
119
|
"dist/cjs/bin.js": "8d0317ce087d22074b4ad350d63bf39cd6d218da565496621cd0daf4245cbdc4",
|
|
120
120
|
"dist/cjs/bin.js.map": "818e872380d9c7ba045238ba65ce77111ba822b356be26327ed05936e5667e5e",
|
|
@@ -136,12 +136,12 @@
|
|
|
136
136
|
"dist/cjs/server/folder-picker.d.ts": "b9c59dbc834fff668b1894f516450c2edc985c7bfac31edf9b7b4e766474b32b",
|
|
137
137
|
"dist/cjs/server/folder-picker.js": "053121152a210c899e8593d60670a2a510b435c3b479300c572aa4bc8443e58e",
|
|
138
138
|
"dist/cjs/server/folder-picker.js.map": "dce1ad1b03c8a6a4fba7b3cacec5b65e55c1dfd1886c5e70df384efd1a5c68a6",
|
|
139
|
-
"dist/cjs/server/manager.d.ts": "
|
|
140
|
-
"dist/cjs/server/manager.js": "
|
|
141
|
-
"dist/cjs/server/manager.js.map": "
|
|
139
|
+
"dist/cjs/server/manager.d.ts": "d23ee9c3f9b72ff89c511f81f5cfb6e2b62d4ba4963099c3c9f5a65531216097",
|
|
140
|
+
"dist/cjs/server/manager.js": "aea5c81a048cf2bd7736c289dbee9cf2d0bea4caf7093a1d8f8179d6fcea48a3",
|
|
141
|
+
"dist/cjs/server/manager.js.map": "594ac93b2986160e47f927683f2f5feee84054dbf7255d965ada9dea561845b8",
|
|
142
142
|
"dist/cjs/server/server.d.ts": "13288ace9aa6ec016a2b06dc036868324ac6c23c7e73771e95d120be778f238a",
|
|
143
|
-
"dist/cjs/server/server.js": "
|
|
144
|
-
"dist/cjs/server/server.js.map": "
|
|
143
|
+
"dist/cjs/server/server.js": "43d6e18a1a36fd1af6179ff98d356efaee1da9464c85d76e9bf057b71741534e",
|
|
144
|
+
"dist/cjs/server/server.js.map": "d599dbfbe0f98abaf103849eafee70b407d332ff0d767c1d95f54c80e85bf2bb",
|
|
145
145
|
"dist/esm/bin.d.ts": "43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012",
|
|
146
146
|
"dist/esm/bin.js": "69f6059ce2336eb7f0d9503f86c83da787aaf74a8bfd804c694ba5b2e1728be0",
|
|
147
147
|
"dist/esm/bin.js.map": "fc174c2b5c66c20ff88184ddeb00577406185945ccadb0bddbb2014909339e9e",
|
|
@@ -164,13 +164,13 @@
|
|
|
164
164
|
"dist/esm/server/folder-picker.d.ts": "b9c59dbc834fff668b1894f516450c2edc985c7bfac31edf9b7b4e766474b32b",
|
|
165
165
|
"dist/esm/server/folder-picker.js": "6c8247e431b7181c45fb169b29e5825a0b3589f44e1625b3a5a291d7b8358042",
|
|
166
166
|
"dist/esm/server/folder-picker.js.map": "f70723213f032a0f10f538289a176a50fc8f02c200b0194479ffc139b5fbb13b",
|
|
167
|
-
"dist/esm/server/manager.d.ts": "
|
|
168
|
-
"dist/esm/server/manager.js": "
|
|
169
|
-
"dist/esm/server/manager.js.map": "
|
|
167
|
+
"dist/esm/server/manager.d.ts": "d23ee9c3f9b72ff89c511f81f5cfb6e2b62d4ba4963099c3c9f5a65531216097",
|
|
168
|
+
"dist/esm/server/manager.js": "2f1772ce5885128694e8cd9c89ca7ae74694a1f85758fc8e17b577b7ab54c2e4",
|
|
169
|
+
"dist/esm/server/manager.js.map": "f68a87c9763e8c4e3ddfc98e981ada4ea83922793035f19051b88dc3e7f47bc0",
|
|
170
170
|
"dist/esm/server/server.d.ts": "13288ace9aa6ec016a2b06dc036868324ac6c23c7e73771e95d120be778f238a",
|
|
171
|
-
"dist/esm/server/server.js": "
|
|
172
|
-
"dist/esm/server/server.js.map": "
|
|
173
|
-
"package.json": "
|
|
171
|
+
"dist/esm/server/server.js": "df4caa8a596a9724c526dab5395e5018f63164ef0d10522d75ca4c44d62c1ee3",
|
|
172
|
+
"dist/esm/server/server.js.map": "3743325b664476176931989f2d762d53b48c5eb4bcbf3d81ab222c4231d026be",
|
|
173
|
+
"package.json": "812251c1b6f091da2f7ab06c93446e5f7c19bf4715074919e38e956e0eca373b",
|
|
174
174
|
"ui/index.html": "7301a595d625dadcd424069e7bb978004bfb6118eddef7a223bd25449ca6e0eb",
|
|
175
175
|
"ui/vendor/marked.min.js": "c68075672d976e4777390560baa112194855bd4404b13647da4855aae1f9360c"
|
|
176
176
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanqianx/project-knowledge",
|
|
3
|
-
"version": "5.0.9-rc.
|
|
3
|
+
"version": "5.0.9-rc.8",
|
|
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": {
|
|
@@ -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.8-rc.
|
|
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.2-rc.
|
|
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.9-rc.
|
|
4
|
+
"version": "5.0.9-rc.8",
|
|
5
5
|
"description": "Read durable project decisions and implementation history from Project Knowledge.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "SanQianX",
|
package/ui/index.html
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
<section id="agentCaptureSection"><div class="actions"><h3>外部 Agent 采集</h3><button id="refreshAgentCapture">检查状态</button></div><p class="muted">只接入你使用的工具。采集外部开发会话,不会重新安装 Agent,也不影响已有记录。</p><div id="agentCaptureList"></div><p id="agentCaptureFeedback" class="feedback" role="status"></p></section>
|
|
41
41
|
<section><h3>后台维护模型</h3><p class="muted">使用持久化默认模型,不跟随聊天中的临时切换。</p><select id="maintenanceModel" aria-label="后台维护默认模型"></select><div class="actions"><button id="saveMaintenance">保存默认模型</button><button id="configureProviders">管理模型供应商</button></div><p id="configurationStatus" class="muted"></p></section>
|
|
42
42
|
<section><h3>向量检索模型</h3><p id="embeddingStatus" class="muted">正在读取配置。</p><button id="openEmbedding">配置向量模型</button><p class="muted">凭据由工作台统一保存。未配置时仍可使用文本检索。</p></section>
|
|
43
|
-
<section><h3>智脑设置</h3><label>名称<input id="brainName" maxlength="100"></label><label>知识根目录<div class="input-with-action"><input id="knowledgeRoot"><button id="pickRoot">选择</button></div></label><p class="muted"
|
|
43
|
+
<section><h3>智脑设置</h3><label>名称<input id="brainName" maxlength="100"></label><label>知识根目录<div class="input-with-action"><input id="knowledgeRoot"><button id="pickRoot">选择</button></div></label><label>向量索引目录<output id="indexStoragePath" class="detail-path"></output></label><p id="indexStorageStatus" class="muted"></p><p class="muted">索引跟随知识根目录,可重新构建;切换时原索引保留,已有项目知识与共享知识不移动。</p><button id="saveBrainSettings">保存设置</button></section>
|
|
44
44
|
<section><div class="actions"><button id="openEngine">知识引擎诊断</button><button id="openLogs">系统诊断记录</button></div><p class="muted">诊断不影响正在进行的会话与维护。</p></section>
|
|
45
45
|
</div>
|
|
46
46
|
</aside>
|
package/ui/product.js
CHANGED
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
const [brain, projects, health] = await Promise.all([api('/api/brain'), api('/api/projects/aggregated'), api('/api/modules/health')]);
|
|
160
160
|
if (epoch !== registryEpoch) return;
|
|
161
161
|
state.brain = brain.brain; state.root = brain.knowledgeRoot; state.projects = projects.projects; state.health = health.modules; state.ownership = health.ownership;
|
|
162
|
+
state.indexStorage = { path: brain.indexStoragePath, ...brain.configuration?.indexStorage };
|
|
162
163
|
if (!activeProject()) { state.projectId = state.projects[0]?.projectId || ''; state.epoch++; Object.keys(frames).forEach(frameContext); }
|
|
163
164
|
renderProjectOptions(); renderSystem(); connectProgress(); await refreshSnapshot(); setView(state.view);
|
|
164
165
|
} catch (error) { toast(error.message); }
|
|
@@ -170,9 +171,12 @@
|
|
|
170
171
|
function renderSystem() {
|
|
171
172
|
const down = Object.keys(modules).filter(key => !state.health[key]?.up);
|
|
172
173
|
const pending = state.ownership?.owner === 'engine' && !state.ownership.ready;
|
|
174
|
+
const storagePending = !!state.indexStorage?.expectedPath && state.indexStorage.status !== 'ready';
|
|
175
|
+
renderStorageInfo();
|
|
173
176
|
$('systemDot').className = `dot ${down.length || pending ? 'issue' : 'up'}`;
|
|
174
177
|
$('systemTitle').textContent = pending ? '知识引擎连接待恢复' : down.length ? '部分服务需要处理' : '系统连接正常';
|
|
175
178
|
$('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
|
+
if (storagePending && !pending && !down.length) { $('systemDot').className = 'dot issue'; $('systemTitle').textContent = '索引目录接线待恢复'; $('systemDetail').textContent = `目标目录:${state.indexStorage.expectedPath}。请在系统状态中修复接线。`; }
|
|
176
180
|
$('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('');
|
|
177
181
|
if (!navigator.onLine) {
|
|
178
182
|
$('systemDot').className = 'dot issue'; $('systemTitle').textContent = '网页连接中断';
|
|
@@ -183,8 +187,13 @@
|
|
|
183
187
|
async function openSystem() {
|
|
184
188
|
$('systemDrawer').hidden = false; $('drawerBackdrop').hidden = false;
|
|
185
189
|
$('brainName').value = state.brain.name; $('knowledgeRoot').value = state.root;
|
|
190
|
+
renderStorageInfo();
|
|
186
191
|
await Promise.all([loadMaintenance(), loadAgentCapture()]);
|
|
187
192
|
}
|
|
193
|
+
function renderStorageInfo() {
|
|
194
|
+
$('indexStoragePath').textContent = state.indexStorage?.actualPath || state.indexStorage?.path || '设置知识根目录后自动确定';
|
|
195
|
+
$('indexStorageStatus').textContent = state.indexStorage?.status === 'ready' ? '索引目录已生效。' : `索引接线待恢复;目标目录:${state.indexStorage?.expectedPath || state.indexStorage?.path || '尚未设置'}`;
|
|
196
|
+
}
|
|
188
197
|
async function loadAgentCapture() {
|
|
189
198
|
const epoch = ++captureEpoch;
|
|
190
199
|
try {
|
|
@@ -376,7 +385,7 @@
|
|
|
376
385
|
on('embeddingForm', 'submit', async event => { event.preventDefault(); await saveEmbedding(); });
|
|
377
386
|
on('disableEmbedding', 'click', () => saveEmbedding(false));
|
|
378
387
|
on('embeddingDialog', 'close', () => { $('embeddingSecret').value = ''; });
|
|
379
|
-
on('saveBrainSettings', 'click', async () => { await api('/api/brain', { method: 'PATCH', body: { name: $('brainName').value } }); await api('/api/settings', { method: 'PATCH', body: { knowledge: { rootPath: $('knowledgeRoot').value } } }); toast('
|
|
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(); });
|
|
380
389
|
on('setupImportRoot', 'click', async () => { $('importDialog').close(); resumeImport = true; await openSystem(); $('knowledgeRoot').focus(); });
|
|
381
390
|
on('pickRoot', 'click', () => pick('knowledgeRoot')); on('pickCode', 'click', () => pick('importCode')); on('pickKnowledge', 'click', () => pick('importKnowledge'));
|
|
382
391
|
on('openEngine', 'click', () => { closeSystem(); initializeFrame('engine'); $('engineDialog').showModal(); post('engine', { type: 'kb:visibility', visible: true }); });
|