@sanqianx/project-knowledge 5.0.9-rc.9 → 5.0.10-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +140 -0
- package/README.md +11 -4
- package/_modules/knowledge-engine/README.md +9 -1
- package/_modules/knowledge-engine/package.json +1 -1
- package/_modules/knowledge-engine/src/coordinator.js +11 -2
- package/_modules/knowledge-engine/src/headless-analyzer.js +2 -1
- package/_modules/knowledge-engine/src/memories.js +133 -24
- package/_modules/knowledge-engine/src/retrieval.js +19 -4
- package/_modules/knowledge-engine/src/runtime/contracts.js +1 -0
- package/_modules/knowledge-engine/src/runtime/knowledge-promotion.js +6 -2
- package/_modules/knowledge-engine/src/runtime/markdown-knowledge-indexer.js +7 -2
- package/_modules/knowledge-engine/src/server.js +1 -1
- package/_modules/knowledge-engine/src/store.js +9 -6
- package/_site/_test/bin-cli-test.js +15 -2
- package/_site/_test/mcp-server-test.js +1 -1
- package/_site/_test/module-agent-start-proxy-test.js +65 -0
- package/_site/_test/module-bridge-eventbridge-test.js +1 -1
- package/_site/_test/module-wiring-unbind-race-test.js +59 -0
- package/_site/_test/path-consistency-test.js +1 -1
- package/_site/_test/product-diagnostics-ui-test.js +5 -1
- package/_site/_test/product-progress-status-test.js +70 -0
- package/_site/_test/shared-scope-root-binding-test.js +67 -0
- package/_site/_test/test-server-cleanup-test.js +5 -1
- package/_site/_test/vector-storage-root-test.js +16 -0
- package/_site/lib/engine-connection.js +4 -1
- package/_site/lib/knowledge-tool-runtime.js +1 -1
- package/_site/lib/module-bridge.js +65 -8
- package/_site/lib/server-app.js +4 -2
- package/_site/lib/settings-store.js +20 -0
- package/module-runtime-manifest.json +41 -41
- 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 +2 -2
- package/ui/product.css +1 -0
- package/ui/product.js +62 -10
- package/vendor-manifest.json +12 -12
|
@@ -31,6 +31,9 @@ const { once } = require('events');
|
|
|
31
31
|
const { DomainError } = require('./contracts');
|
|
32
32
|
|
|
33
33
|
const PROXY_TIMEOUT_MS = 10000;
|
|
34
|
+
// Native client startup includes knowledge retrieval and a local server/CLI
|
|
35
|
+
// handshake. It has a bounded setup budget, separate from ordinary reads/SSE.
|
|
36
|
+
const AGENT_START_TIMEOUT_MS = 90000;
|
|
34
37
|
// Registration drives a full embedding pass in vector-hub (remote API); a
|
|
35
38
|
// fresh knowledge folder can easily exceed the interactive proxy budget.
|
|
36
39
|
const REGISTER_TIMEOUT_MS = 60000;
|
|
@@ -90,6 +93,7 @@ class ModuleBridge {
|
|
|
90
93
|
this.runtimeToken = options.runtimeToken || crypto.randomBytes(32).toString('hex');
|
|
91
94
|
this.registryStore = options.registryStore || null;
|
|
92
95
|
this.projectStore = options.projectStore || null;
|
|
96
|
+
this.projectWiringQueue = new Map();
|
|
93
97
|
this.settingsStore = options.settingsStore || null;
|
|
94
98
|
this.dataDir = options.dataDir || null;
|
|
95
99
|
this.supervised = [];
|
|
@@ -131,7 +135,11 @@ class ModuleBridge {
|
|
|
131
135
|
// The native folder pickers hold the request open until the user closes
|
|
132
136
|
// the dialog — they need a human-scale budget, not the API budget.
|
|
133
137
|
const isPicker = /\/(system\/)?pick-folder/.test(target);
|
|
134
|
-
const
|
|
138
|
+
const targetUrl = new URL(target);
|
|
139
|
+
const pathname = targetUrl.pathname;
|
|
140
|
+
const isAgentStart = req.method === 'POST' && /^\/api\/claude-workbench\/v1\/sessions(?:\/[^/]+\/input)?\/?$/.test(pathname);
|
|
141
|
+
const timeoutMs = isPicker ? PICKER_TIMEOUT_MS : isAgentStart ? AGENT_START_TIMEOUT_MS : PROXY_TIMEOUT_MS;
|
|
142
|
+
const startedAt = Date.now();
|
|
135
143
|
let upstream;
|
|
136
144
|
const controller = new AbortController();
|
|
137
145
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -148,8 +156,13 @@ class ModuleBridge {
|
|
|
148
156
|
clearTimeout(timer);
|
|
149
157
|
res.off?.('close', disconnected);
|
|
150
158
|
if (res.destroyed) return;
|
|
159
|
+
const details = { failureKind: controller.signal.aborted ? 'UPSTREAM_TIMEOUT' : 'NETWORK_ERROR', timeoutMs };
|
|
160
|
+
this.logger.warn('module.proxy.failed', '模块请求未完成,请检查连接或客户端启动。', {
|
|
161
|
+
component: 'module-bridge', phase: 'proxy', durationMs: Date.now() - startedAt,
|
|
162
|
+
context: { ...details, method: req.method, path: pathname },
|
|
163
|
+
});
|
|
151
164
|
res.writeHead(502, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
152
|
-
res.end(JSON.stringify({ ok: false, error: 'MODULE_UNREACHABLE', target }));
|
|
165
|
+
res.end(JSON.stringify({ ok: false, error: 'MODULE_UNREACHABLE', target: targetUrl.origin + pathname, details }));
|
|
153
166
|
return;
|
|
154
167
|
}
|
|
155
168
|
const contentType = upstream.headers.get('content-type') || 'application/json; charset=utf-8';
|
|
@@ -323,7 +336,7 @@ class ModuleBridge {
|
|
|
323
336
|
let indexPath = null;
|
|
324
337
|
try { indexPath = new StorageLayout({ dataDir }).getVectorRootPath(this.settingsStore?.read()); }
|
|
325
338
|
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' } };
|
|
339
|
+
const status = { scopes: false, scopeStatus: { status: 'pending' }, model: false, embedding: false, indexStorage: { expectedPath: indexPath, actualPath: null, status: 'pending' } };
|
|
327
340
|
const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.runtimeToken}` };
|
|
328
341
|
try {
|
|
329
342
|
if (this.settingsStore) {
|
|
@@ -331,11 +344,28 @@ class ModuleBridge {
|
|
|
331
344
|
if (settings.knowledge.rootPath) {
|
|
332
345
|
const brain = settings.brain;
|
|
333
346
|
const root = path.join(settings.knowledge.rootPath, '_shared');
|
|
334
|
-
const
|
|
335
|
-
|
|
347
|
+
const response = await this._fetch(`${this.engineUrl}/api/snapshot`);
|
|
348
|
+
if (!response.ok) throw new DomainError('ENGINE_UNAVAILABLE', '共享知识接线暂时不可用。');
|
|
349
|
+
const prior = (await response.json()).sharedScopes || [];
|
|
350
|
+
// Root settings govern new directories and derived indexes, never move
|
|
351
|
+
// existing knowledge. Retain engine-acknowledged bindings in the spine.
|
|
352
|
+
const binding = (item, kind) => {
|
|
353
|
+
const existing = prior.find(scope => scope.id === item.id && scope.kind === kind && scope.brainId === brain.id);
|
|
354
|
+
if (existing && !path.isAbsolute(existing.knowledgePath || '')) throw new DomainError('DATA_CORRUPT', '共享目录绑定损坏。');
|
|
355
|
+
return item.knowledgePath || existing?.knowledgePath || path.join(root, item.id);
|
|
356
|
+
};
|
|
357
|
+
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') }))];
|
|
358
|
+
const applied = await this._fetch(`${this.engineUrl}/api/scopes`, { method: 'POST', headers, body: JSON.stringify({ scopes }) });
|
|
359
|
+
if (!applied.ok) throw new DomainError('SHARED_SCOPE_APPLY_FAILED', '共享目录接线未完成。');
|
|
360
|
+
await this.settingsStore.bindSharedKnowledgePaths?.(scopes);
|
|
361
|
+
status.scopes = true; status.scopeStatus = { status: 'ready' };
|
|
336
362
|
}
|
|
337
363
|
}
|
|
338
|
-
} catch {
|
|
364
|
+
} catch (error) {
|
|
365
|
+
status.scopeStatus = { status: 'pending', code: ['DATA_CORRUPT', 'IMMUTABLE_FIELD', 'ENGINE_UNAVAILABLE', 'SHARED_SCOPE_APPLY_FAILED'].includes(error.code) ? error.code : 'ENGINE_UNAVAILABLE' };
|
|
366
|
+
this.logger.warn('modules.scopes.pending', 'Shared knowledge wiring is pending; existing data is retained.', { context: { code: status.scopeStatus.code } });
|
|
367
|
+
// A scope failure must not prevent revoking a stale model key.
|
|
368
|
+
}
|
|
339
369
|
try {
|
|
340
370
|
let profile = null;
|
|
341
371
|
try {
|
|
@@ -369,7 +399,24 @@ class ModuleBridge {
|
|
|
369
399
|
* (retry on the next register call or health-check pass), never a hard error.
|
|
370
400
|
* KB_MODULES_REGISTER=0 disables fan-out entirely (test isolation).
|
|
371
401
|
*/
|
|
372
|
-
|
|
402
|
+
_withProjectWiring(projectId, action) {
|
|
403
|
+
const prior = this.projectWiringQueue.get(projectId) || Promise.resolve();
|
|
404
|
+
const operation = prior.catch(() => {}).then(action);
|
|
405
|
+
const settled = operation.finally(() => { if (this.projectWiringQueue.get(projectId) === settled) this.projectWiringQueue.delete(projectId); });
|
|
406
|
+
this.projectWiringQueue.set(projectId, settled);
|
|
407
|
+
return settled;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
registerProjectLinks(input) {
|
|
411
|
+
return this._withProjectWiring(input.projectId, () => {
|
|
412
|
+
// A supervisor may have captured this project before a concurrent unbind.
|
|
413
|
+
// Recheck the spine after acquiring the same lease as the removal path.
|
|
414
|
+
if (this.registryStore && !this.registryStore.readDisplaySnapshot(input.projectId)) return Object.fromEntries(['terminal', 'vectorHub', 'eventBridge', 'engine'].map(key => [key, { ok: true, status: 'removed', skipped: 'project-not-registered' }]));
|
|
415
|
+
return this._registerProjectLinks(input);
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
async _registerProjectLinks({ projectId, name, workspacePath, knowledgePath }) {
|
|
373
420
|
const result = { terminal: { ok: false }, vectorHub: { ok: false }, eventBridge: { ok: false }, engine: { ok: false } };
|
|
374
421
|
if (String(process.env.KB_MODULES_REGISTER || '') === '0') {
|
|
375
422
|
result.terminal = { ok: false, status: 'disabled' };
|
|
@@ -461,7 +508,17 @@ class ModuleBridge {
|
|
|
461
508
|
* only drops its derived index (source untouched); terminal removes the project
|
|
462
509
|
* with keepSessions=1 so session records survive; the event-bridge console only
|
|
463
510
|
* unregisters the project — journals and sealed commit documents stay on disk. */
|
|
464
|
-
|
|
511
|
+
removeProjectLinks(input) {
|
|
512
|
+
return this._withProjectWiring(input.projectId, async () => {
|
|
513
|
+
const result = await this._removeProjectLinks(input);
|
|
514
|
+
// The caller owns registry/lifecycle changes. Hold the wiring lease until
|
|
515
|
+
// its transaction settles, so delayed reconfiguration cannot resurrect it.
|
|
516
|
+
await input.onRemoved?.(result);
|
|
517
|
+
return result;
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
async _removeProjectLinks({ projectId, requireEngine = true }) {
|
|
465
522
|
const wiring = (this.projectStore ? this.projectStore.readState(projectId).modules : null) || {};
|
|
466
523
|
const result = { terminal: { ok: false }, vectorHub: { ok: false }, eventBridge: { ok: false }, engine: { ok: false } };
|
|
467
524
|
// Stop the writer first, before removing hooks/index registrations.
|
package/_site/lib/server-app.js
CHANGED
|
@@ -1057,11 +1057,13 @@ function createRequestHandler(runtime, options = {}) {
|
|
|
1057
1057
|
throw new DomainError('PROJECT_NOT_FOUND', 'Project was not found.', { status: 404 });
|
|
1058
1058
|
}
|
|
1059
1059
|
const body = await readJsonBody(req);
|
|
1060
|
-
|
|
1061
|
-
const result = await runtime.lifecycleService.deleteProject(projectId, {
|
|
1060
|
+
const remove = () => runtime.lifecycleService.deleteProject(projectId, {
|
|
1062
1061
|
deleteKnowledge: body.deleteKnowledge === true,
|
|
1063
1062
|
confirmationToken: body.confirmationToken || '',
|
|
1064
1063
|
});
|
|
1064
|
+
let result;
|
|
1065
|
+
if (runtime.registryStore.readDisplaySnapshot(projectId)) await runtime.moduleBridge.removeProjectLinks({ projectId, requireEngine: runtime.analysisOwner !== 'legacy', onRemoved: async () => { result = await remove(); } });
|
|
1066
|
+
else result = await remove();
|
|
1065
1067
|
return send(res, 200, result);
|
|
1066
1068
|
}
|
|
1067
1069
|
const gitStatusMatch = pathname.match(/^\/api\/projects\/([^/]+)\/git-status$/);
|
|
@@ -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 {
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "project-knowledge/module-content/v1",
|
|
3
3
|
"productFiles": {
|
|
4
|
-
"ui/index.html": "
|
|
5
|
-
"ui/product.js": "
|
|
6
|
-
"ui/product.css": "
|
|
4
|
+
"ui/index.html": "e4320976133d054afb3c1429337d6c0ef4792c413ce73d5b2d6ea2f06c29a573",
|
|
5
|
+
"ui/product.js": "9c8cb126d404d75c03b0d5e2c7ad93dc06b2a4693f2eab520faeb70a009f5cf3",
|
|
6
|
+
"ui/product.css": "0c31d4937780b3a277689b4619208ad0e5dc59a84d7e27fc16b5f1815d59b47c",
|
|
7
7
|
"ui/favicon.svg": "c48be946b224112ebb0238b44263f7a61bda31e531afa895c2e9801c0ff24f32"
|
|
8
8
|
},
|
|
9
9
|
"modules": {
|
|
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.7",
|
|
14
14
|
"files": {
|
|
15
15
|
"LICENSE": "c1b9df1275e769f3dbab000d1e457a2d4b0f28eb5da6c77e48dc37eeba202ed7",
|
|
16
|
-
"README.md": "
|
|
17
|
-
"apps/agent-terminal/app.css": "
|
|
18
|
-
"apps/agent-terminal/app.js": "
|
|
19
|
-
"apps/agent-terminal/index.html": "
|
|
16
|
+
"README.md": "5a382c531372deaa63b3e014f4dbd077d41ce02efee40347973463081848cb86",
|
|
17
|
+
"apps/agent-terminal/app.css": "ede36d9fdb1f7036e3453134c0d5a86197bfc30e3ac547a24b4fc1d17847277e",
|
|
18
|
+
"apps/agent-terminal/app.js": "e23fde6529f72031b745b47d5658e62f9079678248aab95599487d1d0660b6e7",
|
|
19
|
+
"apps/agent-terminal/index.html": "cdffd5c535c81f56aba70ec5dd3bc060f59ec2abcdc8676b79c8f327126be605",
|
|
20
20
|
"apps/ai-profile-settings-host/index.html": "bc158f68954506d2b8e43c690f28dbe931eff9a02b1524855ac17e74ea4df736",
|
|
21
21
|
"apps/ai-profile-settings-host/page.css": "8b75cbf7f1ea5aaa92f2889390720ece310a8fd4b9ca38c890fa447d4323a557",
|
|
22
22
|
"apps/ai-profile-settings-host/page.js": "f42755a3ed17bd7e00919cee56875b04035aa3c5526fce889f8ba52f4278a8b8",
|
|
@@ -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": "18581c89859580ba153ca6582691fe87daf9bc37fb9971040bd8c564a0440281",
|
|
31
31
|
"docs/sdk/README.md": "7ab591d39c36a3b84cfdf487ff567040ec453975f3ef0fba86dc822094667b61",
|
|
32
|
-
"package.json": "
|
|
32
|
+
"package.json": "f2f45324f4bff372fe99e8bcb0af04624162a2f65712f8b8f6479e5630d64de7",
|
|
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": "2cc2ee4f2305ddb5fe32f0c9bc928f47257e4522f7b2063e84de92d981f7660a",
|
|
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": "502ec29cf54dcbc604dc9bc6ccd7c74a553ae9b301616b37e2624c6a038601fc",
|
|
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": "56adcbfba15bf283e885032f3d6bab4ff3a8d3ba1ab03e84e44fde04ed2ff445",
|
|
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",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"packages/server/lib/agent-registry.js": "fbf4f3e96542502a41e7fdf77037d63c3b0444d26708ad9766bec90fbb6b38bb",
|
|
52
52
|
"packages/server/lib/attachment-store.js": "5c92c45c7ec5a8b0ee9c14edb42eeda5fce93d8e654718dcd75c12e3f0bfa6e7",
|
|
53
53
|
"packages/server/lib/bridges/app-server-bridge.js": "85bb644ab570a7a7e6aa26123c8e3cd2e8c11c3ff4e1270954b8e26517968f69",
|
|
54
|
-
"packages/server/lib/bridges/opencode-server-bridge.js": "
|
|
54
|
+
"packages/server/lib/bridges/opencode-server-bridge.js": "910e4216b184d35b98fb525c629670007f4eaf52f27cfe58a631764983271ff6",
|
|
55
55
|
"packages/server/lib/capture-settings-store.js": "eb18885d7bedd3e353287dd7d1cf81e815e5d65d5d82170aa8fe5506a03de8bd",
|
|
56
56
|
"packages/server/lib/cli-session-recovery.js": "e66dc0ad83af18841bf3a598bb27932af42a20cf9395c16dcbaf9b022a5201b5",
|
|
57
57
|
"packages/server/lib/context-resolver.js": "d3060bfe35fb184e521847fc0900cf6114f8ebf3120ce13ed39dfc224af54660",
|
|
@@ -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": "08195a1f8a78f8a9405f3c5c7e037f4c451c77128fd0f81e7406cada89ca8075",
|
|
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": "a07586cb53b6eb77c4c5af51bcc81509c753e4bbf715a7359e466cec2ba80012",
|
|
86
86
|
"packages/ui/README.md": "793c4a9c286fee23f39062a1976ca3afe9d2816dcdb55e156ba940e1ef514f89",
|
|
87
87
|
"packages/ui/theme.css": "8f03a081272a7db11b196f7a70d0fafb1f8d954778f329f1ba53d110d9d5fd98",
|
|
88
88
|
"src/assets/claude-prompts.json": "cb111f2e0a45afe8a31c251a504d1ab5375966ed61291660e61fd2efd77f6d9f",
|
|
@@ -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.3",
|
|
116
116
|
"files": {
|
|
117
|
-
"README.md": "
|
|
117
|
+
"README.md": "da267117f2f3cf61bc865a6fa3a2097dcb999f7f7e50eb7add0b74494a9f982e",
|
|
118
118
|
"dist/cjs/bin.d.ts": "43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012",
|
|
119
119
|
"dist/cjs/bin.js": "8d0317ce087d22074b4ad350d63bf39cd6d218da565496621cd0daf4245cbdc4",
|
|
120
120
|
"dist/cjs/bin.js.map": "818e872380d9c7ba045238ba65ce77111ba822b356be26327ed05936e5667e5e",
|
|
@@ -122,12 +122,12 @@
|
|
|
122
122
|
"dist/cjs/core/embeddings.js": "5e199fd6e0de174aad1ba5440dd6358d9b180d4f82d62c7d8cd1fb8a17efb2d7",
|
|
123
123
|
"dist/cjs/core/embeddings.js.map": "f1b9ec78274cdd7359a59e8a47af7c376de61587bc4b9fc78df970734169ee38",
|
|
124
124
|
"dist/cjs/core/hub.d.ts": "5173ac7396ffdce780fa0b93428a330142a1a2edf378527b6291036edc9a0d7d",
|
|
125
|
-
"dist/cjs/core/hub.js": "
|
|
126
|
-
"dist/cjs/core/hub.js.map": "
|
|
127
|
-
"dist/cjs/core/kb-sync.d.ts": "
|
|
128
|
-
"dist/cjs/core/kb-sync.js": "
|
|
129
|
-
"dist/cjs/core/kb-sync.js.map": "
|
|
130
|
-
"dist/cjs/core/types.d.ts": "
|
|
125
|
+
"dist/cjs/core/hub.js": "f90ee514c0cf9ac67d7aae728d7af2606d7404ab84436fbdc066663006cb67e2",
|
|
126
|
+
"dist/cjs/core/hub.js.map": "10d5d99d4ca8edb6af289b9da28eb63037ffa6762f382434040292d517d887fa",
|
|
127
|
+
"dist/cjs/core/kb-sync.d.ts": "8290ae4c5840dcf98769cfec1734d5ebeb102020b348da2a8382b1cad057da1b",
|
|
128
|
+
"dist/cjs/core/kb-sync.js": "b6bc7f11d3e63894fe8633151ac38c853f30d8675a15e57605bd8ff68bffd4b5",
|
|
129
|
+
"dist/cjs/core/kb-sync.js.map": "687ce74cdf668c1b99809a23c078861e66dacd0050056ff0231d69c3d6e6b85a",
|
|
130
|
+
"dist/cjs/core/types.d.ts": "b54fd90a3aaef7b90fe106857de350b2300b7eaa46a5bfb6b4959bfe09faa554",
|
|
131
131
|
"dist/cjs/core/types.js": "b0d2bc4142d0c62d43f996aaeb64f22c4889ac853f8a3765758b505d972d0149",
|
|
132
132
|
"dist/cjs/core/types.js.map": "9c8da204af4d662188e539b27e61f9ee44ecbe68da4211676ebdda14303e6f3b",
|
|
133
133
|
"dist/cjs/index.d.ts": "96aa5a8b9c843a85c7cdc00901e0e95ecae6f01655e7de2d965f96b1d19181a0",
|
|
@@ -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": "06c0e5c05ad47b3ab0a826303703d1b38d68e45f3686e687d832470dac56a05b",
|
|
140
|
+
"dist/cjs/server/manager.js": "947aba093ae79b294a67d8ebd10ceedcc5ff92a3298dfffbc09681f66eed4448",
|
|
141
|
+
"dist/cjs/server/manager.js.map": "d5236999f576019189c8464c4a9aaf1776902da2c5c09d962b557210cc3d8427",
|
|
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": "18cb8c4ada3a7b4c8fa20a2bdfcee2d7bff440ab1d0caabf7c6eaed2b5178bed",
|
|
144
|
+
"dist/cjs/server/server.js.map": "e7a4689fdaedcea9644c0c1a3065cce71017af9aa13be6cb4a90889eae0e7885",
|
|
145
145
|
"dist/esm/bin.d.ts": "43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012",
|
|
146
146
|
"dist/esm/bin.js": "69f6059ce2336eb7f0d9503f86c83da787aaf74a8bfd804c694ba5b2e1728be0",
|
|
147
147
|
"dist/esm/bin.js.map": "fc174c2b5c66c20ff88184ddeb00577406185945ccadb0bddbb2014909339e9e",
|
|
@@ -149,12 +149,12 @@
|
|
|
149
149
|
"dist/esm/core/embeddings.js": "b19e0cf42ca03e50644e39e39da4c003b9e273213c4532bd443c77085d2db521",
|
|
150
150
|
"dist/esm/core/embeddings.js.map": "043aa6822e6b4a692be025d89efb5d7d44f4b6b39ce36bcfad2e64dde45589bb",
|
|
151
151
|
"dist/esm/core/hub.d.ts": "5173ac7396ffdce780fa0b93428a330142a1a2edf378527b6291036edc9a0d7d",
|
|
152
|
-
"dist/esm/core/hub.js": "
|
|
153
|
-
"dist/esm/core/hub.js.map": "
|
|
154
|
-
"dist/esm/core/kb-sync.d.ts": "
|
|
155
|
-
"dist/esm/core/kb-sync.js": "
|
|
156
|
-
"dist/esm/core/kb-sync.js.map": "
|
|
157
|
-
"dist/esm/core/types.d.ts": "
|
|
152
|
+
"dist/esm/core/hub.js": "ea14e891ce2b1861b2a2a1cc9acf0d4249fab2b3354694cfbe519a26f4199453",
|
|
153
|
+
"dist/esm/core/hub.js.map": "a02798e02a9b4a4c41e7496c23d12c12bee25b3ed6adccb0fde91a5b757f70a6",
|
|
154
|
+
"dist/esm/core/kb-sync.d.ts": "8290ae4c5840dcf98769cfec1734d5ebeb102020b348da2a8382b1cad057da1b",
|
|
155
|
+
"dist/esm/core/kb-sync.js": "cbdfab9fecbdd2d6996744ad0bf88f446012d5616f57fdc60f5a8e8d8c462c5f",
|
|
156
|
+
"dist/esm/core/kb-sync.js.map": "e14d56e04a08642f6fb917310cf296ab2cf05c6a2fc6a2cab8ab929f50300843",
|
|
157
|
+
"dist/esm/core/types.d.ts": "b54fd90a3aaef7b90fe106857de350b2300b7eaa46a5bfb6b4959bfe09faa554",
|
|
158
158
|
"dist/esm/core/types.js": "01ae2a5b120382f9a648ced7ee8507493a134f216d100fc61600c6c9738235d2",
|
|
159
159
|
"dist/esm/core/types.js.map": "9c8da204af4d662188e539b27e61f9ee44ecbe68da4211676ebdda14303e6f3b",
|
|
160
160
|
"dist/esm/index.d.ts": "96aa5a8b9c843a85c7cdc00901e0e95ecae6f01655e7de2d965f96b1d19181a0",
|
|
@@ -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": "06c0e5c05ad47b3ab0a826303703d1b38d68e45f3686e687d832470dac56a05b",
|
|
168
|
+
"dist/esm/server/manager.js": "96e1262505a02299e3d6ae5dc1c7ba3a3f69c694f57d89d97e3e4c163b40523e",
|
|
169
|
+
"dist/esm/server/manager.js.map": "10bb43dec7cdf07d1e6260552f40ca347a6eb491ba8bbe81b6ce2a41157a9a87",
|
|
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": "fcf74d2d6ddc19be2ceab561efc904a2b703507901a6a35c3646c4032cac56d6",
|
|
172
|
+
"dist/esm/server/server.js.map": "6c19f311146c60a1ccea89ac223a16ca44e690ac5ac4d8408cd19edc7066f83e",
|
|
173
|
+
"package.json": "5010182529b9f1d4624ff4abd02b8eb48dbbeb4ddf92ef4bc45dd6b332aed100",
|
|
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.
|
|
3
|
+
"version": "5.0.10-rc.1",
|
|
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.3",
|
|
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.7",
|
|
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.
|
|
4
|
+
"version": "5.0.10-rc.1",
|
|
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
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<section class="view" id="view-home"><div class="welcome"><div><small>工作概览</small><h2 id="homeTitle">我的智脑</h2><p>保存项目事实,连接相关经验。你的长期偏好,只在确认后使用。</p></div><div class="actions"><button class="primary" data-go="work">开始工作</button><button data-action="import">导入项目</button></div></div><div id="homeContent"></div></section>
|
|
26
26
|
<section class="view module-view" id="view-work"><div id="workEmpty" class="empty" hidden>导入项目后,就可以在这里开始工作。<button data-action="import">导入项目</button></div><div class="work-layout" id="workLayout"><div class="frame-container"><iframe id="workFrame" title="Agent 工作台" referrerpolicy="same-origin"></iframe></div><aside class="knowledge-context"><header><h2>本次知识引用</h2><small id="contextScope">任务发送前自动检索</small></header><div id="contextContent" class="empty small-empty">发送任务后显示实际检索到的项目事实、领域经验和已确认记忆。</div></aside></div></section>
|
|
27
27
|
<section class="view module-view" id="view-search"><div class="module-toolbar"><span>查找知识</span><div class="segmented" id="searchScope"><button data-scope="project">当前项目</button><button data-scope="domain">所属领域</button><button data-scope="brain">整个智脑</button></div></div><div id="searchEmpty" class="empty" hidden>尚未导入项目。<button data-action="import">导入项目</button></div><div class="frame-container"><iframe id="vectorFrame" title="知识检索" referrerpolicy="same-origin"></iframe></div></section>
|
|
28
|
-
<section class="view" id="view-memory"><div class="section-heading"><div><h2>长期记忆</h2><p
|
|
28
|
+
<section class="view" id="view-memory"><div class="section-heading"><div><h2>长期记忆</h2><p>审核内容与适用范围后确认。来源项目不等于适用项目。</p></div></div><div class="memory-toolbar"><div class="segmented" id="memoryTabs"><button data-memory-tab="confirmed">已确认</button><button data-memory-tab="candidate">候选箱 <span id="candidateCount"></span></button></div><div class="actions"><select id="memoryScopeFilter" aria-label="筛选记忆范围"><option value="">全部范围</option><option value="global">全局记忆</option><option value="domain">领域记忆</option><option value="project">项目记忆</option></select><select id="memoryTargetFilter" aria-label="筛选记忆目标" hidden></select></div></div><div id="memoryContent"></div></section>
|
|
29
29
|
<section class="view" id="view-projects"><div class="section-heading"><div><h2>领域与项目</h2><p>统一管理归属,项目知识仍保存在原来的目录。</p></div><div class="actions"><button id="createDomain">创建领域</button><button class="primary" data-action="import">导入项目</button></div></div><div class="hierarchy"><div class="panel tree" id="projectTree"></div><div class="panel" id="projectDetail"></div></div></section>
|
|
30
30
|
<section class="view module-view" id="view-activity"><div class="module-toolbar"><div class="segmented" id="activityTabs"><button data-activity-tab="updates">知识更新</button><button data-activity-tab="sessions">开发会话与提交</button></div><span id="activityConnection" class="muted">正在连接更新</span></div><div class="activity-updates" id="activityUpdates"></div><div class="frame-container" id="activitySessions" hidden><iframe id="bridgeFrame" title="开发会话与提交" referrerpolicy="same-origin"></iframe></div></section>
|
|
31
31
|
</div>
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
</form></dialog>
|
|
58
58
|
<dialog id="importDialog"><form id="importForm"><div class="dialog-heading"><h2>导入项目</h2><button type="button" data-close="importDialog" aria-label="关闭">×</button></div><p class="muted">绑定代码与新的空知识目录。只建立跟踪基线,不读取旧知识、不分析全部历史。</p><label>代码目录<div class="input-with-action"><input name="localPath" id="importCode" required placeholder="D:\SanQian.Xu\my-project"><button type="button" id="pickCode">选择</button></div></label><label>项目名称<input name="displayName" id="importName" required maxlength="200"></label><label>知识目录<div class="input-with-action"><input name="knowledgePath" id="importKnowledge" required placeholder="D:\SanQian.Xu\knowledge\my-project"><button type="button" id="pickKnowledge">选择</button></div></label><label>所属领域<select name="domainId" id="importDomain"></select></label><label id="gitInitChoice" class="checkbox" hidden><input type="checkbox" name="confirmGitInit">这个目录不是 Git 仓库,我确认初始化 Git。</label><label id="replaceHookChoice" class="checkbox" hidden><input type="checkbox" name="confirmReplaceHook">目录留有旧知识库的托管 Hook,我确认替换为新项目接线。不会覆盖第三方 Hook。</label><div id="preflightStatus" class="feedback" role="status">填写目录后检查导入条件。</div><button type="button" id="setupImportRoot" hidden>设置知识根目录</button><div class="dialog-actions"><button type="button" data-close="importDialog">取消</button><button type="submit" class="primary" id="confirmImport" disabled>导入项目</button></div></form></dialog>
|
|
59
59
|
<dialog id="domainDialog"><form id="domainForm"><div class="dialog-heading"><h2>创建领域</h2><button type="button" data-close="domainDialog" aria-label="关闭">×</button></div><label>领域名称<input name="name" required maxlength="100" placeholder="例如:开发工具"></label><p class="muted">领域用于共享相关项目的知识,不是新的代码项目。</p><div class="dialog-actions"><button type="button" data-close="domainDialog">取消</button><button class="primary" type="submit">创建领域</button></div></form></dialog>
|
|
60
|
-
<dialog id="memoryDialog"><form id="memoryForm"><div class="dialog-heading"><h2
|
|
60
|
+
<dialog id="memoryDialog"><form id="memoryForm"><div class="dialog-heading"><h2 id="memoryDialogTitle">审核记忆</h2><button type="button" data-close="memoryDialog" aria-label="关闭">×</button></div><label>记忆内容<textarea id="memoryText" maxlength="2000" required rows="5"></textarea></label><label>适用范围<select id="memoryScope"><option value="global">全局:所有领域与项目</option><option value="domain">领域:指定领域内的项目</option><option value="project">项目:仅指定项目</option></select></label><label id="memoryTargetLabel">适用目标<select id="memoryTarget" required></select></label><p id="memoryScopeHint" class="muted"></p><details class="memory-evidence"><summary>原始总结与来源依据(只读)</summary><p id="memoryOriginal"></p><p id="memoryEvidence" class="muted"></p><blockquote id="memoryQuote"></blockquote></details><p id="memoryFeedback" class="feedback" hidden role="status"></p><div class="dialog-actions"><button type="button" data-close="memoryDialog">取消</button><button type="submit" id="saveMemoryCandidate" data-mode="candidate">保存候选</button><button type="submit" id="confirmMemory" class="primary" data-mode="confirmed">确认并保存</button></div></form></dialog>
|
|
61
61
|
<dialog id="unbindDialog"><form id="unbindForm"><div class="dialog-heading"><h2>解绑项目</h2><button type="button" data-close="unbindDialog" aria-label="关闭">×</button></div><p id="unbindProjectName"></p><p class="muted">项目将从列表移除,取消尚未开始的维护任务。代码、知识文件、提交证据和会话历史仍保留。正在执行的知识写入结束前不会解绑。</p><p id="unbindFeedback" class="feedback" role="status"></p><div class="dialog-actions"><button type="button" data-close="unbindDialog">取消</button><button class="primary" type="submit" id="confirmUnbind">解绑并保留数据</button></div></form></dialog>
|
|
62
62
|
<dialog id="referenceDialog" class="reference-dialog"><div class="dialog-heading"><h2 id="referenceTitle">知识引用</h2><div class="actions"><button id="copyReference">复制引用</button><button data-close="referenceDialog" aria-label="关闭">×</button></div></div><p id="referenceMeta" class="muted"></p><pre id="referenceContent"></pre></dialog>
|
|
63
63
|
<dialog id="engineDialog" class="engine-dialog"><div class="dialog-heading"><h2>知识引擎诊断</h2><button data-close="engineDialog" aria-label="关闭">×</button></div><iframe id="engineFrame" title="知识引擎诊断" referrerpolicy="same-origin"></iframe></dialog>
|
package/ui/product.css
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
:root{--page:#f3f5f7;--surface:#fff;--surface2:#f8f9fb;--surface3:#edf1f4;--line:#dce2e8;--text:#202733;--muted:#687587;--faint:#8e99a7;--nav:#eef1f4;--accent:#516f89;--accent-soft:#e6edf3;--good:#397761;--bad:#a05252;--bad-soft:#fbeeee;color-scheme:light}
|
|
2
2
|
label>.detail-path{display:block;width:100%;margin:8px 0 0;color:var(--text)}
|
|
3
|
+
.memory-toolbar{display:flex;justify-content:space-between;align-items:center;gap:24px}.memory-meta{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px}.memory-evidence{margin-top:24px;border-top:1px solid var(--line);padding-top:16px}.memory-evidence summary{cursor:pointer;color:var(--muted)}.memory-evidence p,.memory-evidence blockquote{white-space:pre-wrap;overflow-wrap:anywhere}.memory-evidence blockquote{margin:16px 0;border-left:2px solid var(--line);padding-left:16px;color:var(--muted)}
|
|
3
4
|
.agent-capture-row{display:flex;align-items:center;gap:16px;padding:16px 0;border-bottom:1px solid var(--line)}.agent-capture-row>div:first-child{flex:1;min-width:0}.agent-capture-row small{display:block;color:var(--muted);margin-top:8px;overflow-wrap:anywhere}.agent-capture-row .actions{flex-shrink:0}#agentCaptureFeedback{white-space:pre-wrap}
|
|
4
5
|
#logsDialog{display:flex;flex-direction:column;overflow:hidden}#logsDialog:not([open]){display:none}#logsContent{overflow:auto;min-height:0;flex:1;margin-top:16px}#logsContent .row{align-items:flex-start;cursor:pointer}#logsContent pre{flex:1;min-width:0;margin:0}#logsContent .log-entry{border-bottom:1px solid var(--line)}#logsContent .log-detail{padding:16px;background:var(--surface2);max-height:320px;overflow:auto}#logsContent [data-level=warn],#logsContent [data-level=error],#logsContent [data-level=fatal]{color:var(--bad)}#logsContent .row time,#logsContent .row pre{color:inherit}
|
|
5
6
|
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;animation:none!important;transition:none!important}}
|