@customize-agent/knowledge 3.0.10 → 3.0.12
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/dist/core/index-state-store.js +7 -1
- package/dist/core/knowledge-base-manager.js +11 -2
- package/dist/core/multi-project-manager.js +2 -1
- package/dist/core/project-config.d.ts +3 -1
- package/dist/core/project-config.js +10 -8
- package/dist/extraction/content-extractor.d.ts +1 -0
- package/dist/extraction/content-extractor.js +22 -1
- package/package.json +2 -1
|
@@ -494,7 +494,13 @@ export class IndexStateStore {
|
|
|
494
494
|
);
|
|
495
495
|
`);
|
|
496
496
|
this.initFts();
|
|
497
|
-
|
|
497
|
+
try {
|
|
498
|
+
if (this.getMetadata('schema_version') !== '2')
|
|
499
|
+
this.setMetadata('schema_version', '2');
|
|
500
|
+
}
|
|
501
|
+
catch {
|
|
502
|
+
// 受限环境中已有索引库可能以只读方式挂载;运行时元数据不是必需项。
|
|
503
|
+
}
|
|
498
504
|
}
|
|
499
505
|
initFts() {
|
|
500
506
|
try {
|
|
@@ -32,7 +32,7 @@ export class KnowledgeBaseManager {
|
|
|
32
32
|
relationshipDetector = new RelationshipDetector();
|
|
33
33
|
embeddingProvider;
|
|
34
34
|
vectorStores;
|
|
35
|
-
configManager
|
|
35
|
+
configManager;
|
|
36
36
|
projectConfig;
|
|
37
37
|
lastSkippedFiles = [];
|
|
38
38
|
llmProvider;
|
|
@@ -47,6 +47,7 @@ export class KnowledgeBaseManager {
|
|
|
47
47
|
this.llmProvider = options.llmProvider;
|
|
48
48
|
this.onProgress = options.onProgress;
|
|
49
49
|
const storageRoot = options.storageRoot ?? path.join(os.homedir(), USER_DATA_DIR);
|
|
50
|
+
this.configManager = new ProjectConfigManager(storageRoot);
|
|
50
51
|
let dbPath;
|
|
51
52
|
if (this.scope === 'global') {
|
|
52
53
|
this.kbPath = options.kbPath ?? path.join(storageRoot, GLOBAL_KNOWLEDGE_DIR);
|
|
@@ -366,18 +367,26 @@ export class KnowledgeBaseManager {
|
|
|
366
367
|
return this.incrementalIndex();
|
|
367
368
|
}
|
|
368
369
|
getUploadRelativePath(fileName, targetRelativePath) {
|
|
369
|
-
return targetRelativePath
|
|
370
|
+
return targetRelativePath ? this.normalizeRelativePath(targetRelativePath) : this.defaultUploadRelativePath(fileName);
|
|
370
371
|
}
|
|
371
372
|
async uploadFile(fileName, content, targetRelativePath, onProgress, options = {}) {
|
|
372
373
|
return this.uploadFiles([{ fileName, content, targetRelativePath }], onProgress, options);
|
|
373
374
|
}
|
|
374
375
|
async uploadFiles(files, onProgress, options = {}) {
|
|
375
376
|
this.initialize();
|
|
377
|
+
const uploadedPaths = [];
|
|
376
378
|
for (const file of files) {
|
|
377
379
|
const relativePath = this.getUploadRelativePath(file.fileName, file.targetRelativePath);
|
|
378
380
|
const targetPath = this.resolveKbRelativePath(relativePath);
|
|
379
381
|
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
380
382
|
fs.writeFileSync(targetPath, file.content);
|
|
383
|
+
uploadedPaths.push(relativePath);
|
|
384
|
+
}
|
|
385
|
+
for (const relativePath of uploadedPaths) {
|
|
386
|
+
const record = this.store.listRecords().find(item => item.relativePath === relativePath);
|
|
387
|
+
if (record)
|
|
388
|
+
await this.deleteVectorFile(record.collectionName, relativePath);
|
|
389
|
+
this.store.deleteRecord(relativePath);
|
|
381
390
|
}
|
|
382
391
|
return this.incrementalIndex({ onProgress, vectorMode: options.vectorMode });
|
|
383
392
|
}
|
|
@@ -10,13 +10,14 @@ export class MultiProjectManager {
|
|
|
10
10
|
storageRoot;
|
|
11
11
|
llmProvider;
|
|
12
12
|
registry;
|
|
13
|
-
configManager
|
|
13
|
+
configManager;
|
|
14
14
|
projects = new Map();
|
|
15
15
|
globalKB;
|
|
16
16
|
constructor(storageRoot = path.join(os.homedir(), USER_DATA_DIR), llmProvider) {
|
|
17
17
|
this.storageRoot = storageRoot;
|
|
18
18
|
this.llmProvider = llmProvider;
|
|
19
19
|
this.registry = new ProjectRegistry(path.join(storageRoot, 'projects', 'registry.db'));
|
|
20
|
+
this.configManager = new ProjectConfigManager(storageRoot);
|
|
20
21
|
}
|
|
21
22
|
async getProject(projectRoot) {
|
|
22
23
|
const resolvedRoot = path.resolve(projectRoot);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ProjectConfig } from '../types.js';
|
|
2
|
-
export declare function getProjectConfigPath(projectRoot: string): string;
|
|
2
|
+
export declare function getProjectConfigPath(projectRoot: string, storageRoot?: string): string;
|
|
3
3
|
export declare function getProjectKbPath(projectRoot: string): string;
|
|
4
4
|
export declare function ensureProjectCustomizeFile(projectRoot: string): void;
|
|
5
5
|
export declare class ProjectConfigManager {
|
|
6
|
+
private readonly storageRoot;
|
|
7
|
+
constructor(storageRoot?: string);
|
|
6
8
|
loadOrCreate(projectRoot: string): ProjectConfig;
|
|
7
9
|
save(projectRoot: string, config: ProjectConfig): void;
|
|
8
10
|
private withDefaults;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import * as os from 'node:os';
|
|
4
|
-
import { DEFAULT_CATEGORY_DIRS, KNOWLEDGE_BASE_DIR,
|
|
4
|
+
import { DEFAULT_CATEGORY_DIRS, KNOWLEDGE_BASE_DIR, USER_DATA_DIR } from '../constants.js';
|
|
5
5
|
import { computeProjectId } from './project-id.js';
|
|
6
|
-
export function getProjectConfigPath(projectRoot) {
|
|
6
|
+
export function getProjectConfigPath(projectRoot, storageRoot = path.join(os.homedir(), USER_DATA_DIR)) {
|
|
7
7
|
const projectId = computeProjectId(projectRoot);
|
|
8
|
-
return path.join(
|
|
8
|
+
return path.join(storageRoot, 'projects', projectId, 'project.json');
|
|
9
9
|
}
|
|
10
10
|
export function getProjectKbPath(projectRoot) {
|
|
11
11
|
return path.join(projectRoot, KNOWLEDGE_BASE_DIR);
|
|
@@ -35,22 +35,24 @@ export function ensureProjectCustomizeFile(projectRoot) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
export class ProjectConfigManager {
|
|
38
|
+
storageRoot;
|
|
39
|
+
constructor(storageRoot = path.join(os.homedir(), USER_DATA_DIR)) {
|
|
40
|
+
this.storageRoot = storageRoot;
|
|
41
|
+
}
|
|
38
42
|
loadOrCreate(projectRoot) {
|
|
39
43
|
ensureProjectCustomizeFile(projectRoot);
|
|
40
|
-
const configPath = getProjectConfigPath(projectRoot);
|
|
44
|
+
const configPath = getProjectConfigPath(projectRoot, this.storageRoot);
|
|
41
45
|
const now = Date.now();
|
|
42
46
|
if (fs.existsSync(configPath)) {
|
|
43
47
|
const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
44
|
-
|
|
45
|
-
this.save(projectRoot, { ...config, lastOpenedAt: now });
|
|
46
|
-
return { ...config, lastOpenedAt: now };
|
|
48
|
+
return this.withDefaults(projectRoot, raw, now);
|
|
47
49
|
}
|
|
48
50
|
const config = this.withDefaults(projectRoot, {}, now);
|
|
49
51
|
this.save(projectRoot, config);
|
|
50
52
|
return config;
|
|
51
53
|
}
|
|
52
54
|
save(projectRoot, config) {
|
|
53
|
-
const configPath = getProjectConfigPath(projectRoot);
|
|
55
|
+
const configPath = getProjectConfigPath(projectRoot, this.storageRoot);
|
|
54
56
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
55
57
|
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
56
58
|
}
|
|
@@ -2,6 +2,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
|
+
import { pathToFileURL } from 'node:url';
|
|
5
6
|
import { ExternalExtractorRegistry } from './external-extractor.js';
|
|
6
7
|
import { resolveAndImport, resolvePackage, getNodeModulesRoot } from './module-resolver.js';
|
|
7
8
|
export class ContentExtractor {
|
|
@@ -333,10 +334,31 @@ export class ContentExtractor {
|
|
|
333
334
|
warnings,
|
|
334
335
|
};
|
|
335
336
|
}
|
|
337
|
+
async tryConvertDwgWithBundledWasm(filePath) {
|
|
338
|
+
try {
|
|
339
|
+
const mod = await resolveAndImport('dwgdxf');
|
|
340
|
+
if (!mod.convertDwgToDxf)
|
|
341
|
+
return { tool: 'dwgdxf_wasm', warnings: ['内置 dwgdxf WASM 转换器未导出 convertDwgToDxf'] };
|
|
342
|
+
const wasmBase = pathToFileURL(path.join(path.dirname(resolvePackage('dwgdxf')), 'wasm')).href;
|
|
343
|
+
const dxfBytes = await mod.convertDwgToDxf(fs.readFileSync(filePath), { wasmBase });
|
|
344
|
+
const dxfText = Buffer.from(dxfBytes).toString('utf8');
|
|
345
|
+
return dxfText.trim()
|
|
346
|
+
? { dxfText, tool: 'dwgdxf_wasm', warnings: [] }
|
|
347
|
+
: { tool: 'dwgdxf_wasm', warnings: ['内置 dwgdxf WASM 转换器未输出 DXF 文本'] };
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
return { tool: 'dwgdxf_wasm', warnings: [`内置 dwgdxf WASM 转换失败: ${error instanceof Error ? error.message : String(error)}`] };
|
|
351
|
+
}
|
|
352
|
+
}
|
|
336
353
|
async tryConvertDwgToDxf(filePath) {
|
|
337
354
|
const tmpDir = fs.mkdtempSync(path.join(this.getTempRoot(), 'customize-dwg-'));
|
|
338
355
|
const outputPath = path.join(tmpDir, `${path.basename(filePath, path.extname(filePath))}.dxf`);
|
|
339
356
|
try {
|
|
357
|
+
const failures = [];
|
|
358
|
+
const bundled = await this.tryConvertDwgWithBundledWasm(filePath);
|
|
359
|
+
if (bundled.dxfText)
|
|
360
|
+
return bundled;
|
|
361
|
+
failures.push(...bundled.warnings);
|
|
340
362
|
const customCmd = process.env.CUSTOMIZE_DWG_TO_DXF_CMD;
|
|
341
363
|
if (customCmd) {
|
|
342
364
|
if (/\s/u.test(customCmd))
|
|
@@ -357,7 +379,6 @@ export class ContentExtractor {
|
|
|
357
379
|
return { dxfText: fs.readFileSync(outputPath, 'utf8'), tool: 'external_dwg_to_dxf', warnings: [] };
|
|
358
380
|
return { tool: 'external_dwg_to_dxf', warnings: [`CUSTOMIZE_DWG_TO_DXF_CMD 转换失败: ${result.stderr || result.stdout || result.error?.message || 'unknown error'}`] };
|
|
359
381
|
}
|
|
360
|
-
const failures = [];
|
|
361
382
|
for (const bin of ['dwgread', 'dwg2dxf']) {
|
|
362
383
|
const result = spawnSync(bin, bin === 'dwgread' ? ['-O', 'DXF', '-o', outputPath, filePath] : [filePath, outputPath], { encoding: 'utf8', timeout: 120_000 });
|
|
363
384
|
if (result.status === 0 && fs.existsSync(outputPath))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@customize-agent/knowledge",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.12",
|
|
4
4
|
"description": "Local knowledge base infrastructure for customize-agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@napi-rs/canvas": "^0.1.82",
|
|
39
39
|
"better-sqlite3": "^12.10.0",
|
|
40
|
+
"dwgdxf": "^2.0.1",
|
|
40
41
|
"dxf-parser": "^1.1.2",
|
|
41
42
|
"fast-glob": "^3.3.3",
|
|
42
43
|
"jszip": "^3.10.1",
|