aifastdb-devplan 1.6.1 → 1.6.2
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/dev-plan-document-store.d.ts +13 -1
- package/dist/dev-plan-document-store.d.ts.map +1 -1
- package/dist/dev-plan-document-store.js +119 -0
- package/dist/dev-plan-document-store.js.map +1 -1
- package/dist/dev-plan-factory.d.ts.map +1 -1
- package/dist/dev-plan-factory.js +2 -1
- package/dist/dev-plan-factory.js.map +1 -1
- package/dist/dev-plan-graph-store.d.ts +64 -1
- package/dist/dev-plan-graph-store.d.ts.map +1 -1
- package/dist/dev-plan-graph-store.js +364 -2
- package/dist/dev-plan-graph-store.js.map +1 -1
- package/dist/dev-plan-interface.d.ts +24 -1
- package/dist/dev-plan-interface.d.ts.map +1 -1
- package/dist/dev-plan-migrate.d.ts +1 -0
- package/dist/dev-plan-migrate.d.ts.map +1 -1
- package/dist/dev-plan-migrate.js +28 -2
- package/dist/dev-plan-migrate.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/index.js +119 -0
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/types.d.ts +88 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/visualize/graph-canvas/api-compat.d.ts.map +1 -1
- package/dist/visualize/graph-canvas/api-compat.js +22 -12
- package/dist/visualize/graph-canvas/api-compat.js.map +1 -1
- package/dist/visualize/graph-canvas/core.d.ts.map +1 -1
- package/dist/visualize/graph-canvas/core.js +296 -4
- package/dist/visualize/graph-canvas/core.js.map +1 -1
- package/dist/visualize/graph-canvas/interaction.d.ts.map +1 -1
- package/dist/visualize/graph-canvas/interaction.js +11 -0
- package/dist/visualize/graph-canvas/interaction.js.map +1 -1
- package/dist/visualize/graph-canvas/layout-worker.d.ts.map +1 -1
- package/dist/visualize/graph-canvas/layout-worker.js +45 -9
- package/dist/visualize/graph-canvas/layout-worker.js.map +1 -1
- package/dist/visualize/graph-canvas/renderer.d.ts.map +1 -1
- package/dist/visualize/graph-canvas/renderer.js +164 -33
- package/dist/visualize/graph-canvas/renderer.js.map +1 -1
- package/dist/visualize/graph-canvas/styles.d.ts.map +1 -1
- package/dist/visualize/graph-canvas/styles.js +136 -121
- package/dist/visualize/graph-canvas/styles.js.map +1 -1
- package/dist/visualize/graph-canvas/viewport.d.ts.map +1 -1
- package/dist/visualize/graph-canvas/viewport.js +10 -0
- package/dist/visualize/graph-canvas/viewport.js.map +1 -1
- package/dist/visualize/server.js +149 -32
- package/dist/visualize/server.js.map +1 -1
- package/dist/visualize/template-core.d.ts +9 -0
- package/dist/visualize/template-core.d.ts.map +1 -0
- package/dist/visualize/template-core.js +714 -0
- package/dist/visualize/template-core.js.map +1 -0
- package/dist/visualize/template-data-loading.d.ts +7 -0
- package/dist/visualize/template-data-loading.d.ts.map +1 -0
- package/dist/visualize/template-data-loading.js +677 -0
- package/dist/visualize/template-data-loading.js.map +1 -0
- package/dist/visualize/template-detail-panel.d.ts +14 -0
- package/dist/visualize/template-detail-panel.d.ts.map +1 -0
- package/dist/visualize/template-detail-panel.js +553 -0
- package/dist/visualize/template-detail-panel.js.map +1 -0
- package/dist/visualize/template-graph-3d.d.ts +7 -0
- package/dist/visualize/template-graph-3d.d.ts.map +1 -0
- package/dist/visualize/template-graph-3d.js +1112 -0
- package/dist/visualize/template-graph-3d.js.map +1 -0
- package/dist/visualize/template-graph-vis.d.ts +8 -0
- package/dist/visualize/template-graph-vis.d.ts.map +1 -0
- package/dist/visualize/template-graph-vis.js +1204 -0
- package/dist/visualize/template-graph-vis.js.map +1 -0
- package/dist/visualize/template-html.d.ts +9 -0
- package/dist/visualize/template-html.d.ts.map +1 -0
- package/dist/visualize/template-html.js +484 -0
- package/dist/visualize/template-html.js.map +1 -0
- package/dist/visualize/template-pages.d.ts +7 -0
- package/dist/visualize/template-pages.d.ts.map +1 -0
- package/dist/visualize/template-pages.js +806 -0
- package/dist/visualize/template-pages.js.map +1 -0
- package/dist/visualize/template-stats-modal.d.ts +7 -0
- package/dist/visualize/template-stats-modal.d.ts.map +1 -0
- package/dist/visualize/template-stats-modal.js +406 -0
- package/dist/visualize/template-stats-modal.js.map +1 -0
- package/dist/visualize/template-styles.d.ts +9 -0
- package/dist/visualize/template-styles.d.ts.map +1 -0
- package/dist/visualize/template-styles.js +487 -0
- package/dist/visualize/template-styles.js.map +1 -0
- package/dist/visualize/template.d.ts +14 -3
- package/dist/visualize/template.d.ts.map +1 -1
- package/dist/visualize/template.js +38 -3475
- package/dist/visualize/template.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-plan-graph-store.d.ts","sourceRoot":"","sources":["../src/dev-plan-graph-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAaH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,UAAU,EACV,cAAc,EACd,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,qBAAqB,EACrB,eAAe,EAEf,WAAW,EACX,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,aAAa,EAEb,uBAAuB,EACvB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"dev-plan-graph-store.d.ts","sourceRoot":"","sources":["../src/dev-plan-graph-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -63,16 +63,20 @@ const ET = {
|
|
|
63
63
|
MAIN_TASK: 'devplan-main-task',
|
|
64
64
|
SUB_TASK: 'devplan-sub-task',
|
|
65
65
|
MODULE: 'devplan-module',
|
|
66
|
+
PROMPT: 'devplan-prompt',
|
|
66
67
|
};
|
|
67
68
|
/** Relation 类型常量 */
|
|
68
69
|
const RT = {
|
|
69
70
|
HAS_DOCUMENT: 'has_document',
|
|
70
71
|
HAS_MAIN_TASK: 'has_main_task',
|
|
71
72
|
HAS_SUB_TASK: 'has_sub_task',
|
|
73
|
+
HAS_MODULE: 'has_module',
|
|
72
74
|
MODULE_HAS_TASK: 'module_has_task',
|
|
73
75
|
MODULE_HAS_DOC: 'module_has_doc',
|
|
74
76
|
TASK_HAS_DOC: 'task_has_doc',
|
|
75
77
|
DOC_HAS_CHILD: 'doc_has_child',
|
|
78
|
+
TASK_HAS_PROMPT: 'task_has_prompt',
|
|
79
|
+
HAS_PROMPT: 'has_prompt',
|
|
76
80
|
};
|
|
77
81
|
// ============================================================================
|
|
78
82
|
// Helper
|
|
@@ -115,10 +119,10 @@ class DevPlanGraphStore {
|
|
|
115
119
|
// 构建 SocialGraphV2 配置
|
|
116
120
|
const graphConfig = {
|
|
117
121
|
path: config.graphPath,
|
|
118
|
-
shardCount: config.shardCount ||
|
|
122
|
+
shardCount: config.shardCount || 5,
|
|
119
123
|
walEnabled: true,
|
|
120
124
|
mode: 'balanced',
|
|
121
|
-
shardNames: ['tasks', 'relations', 'docs', 'modules'],
|
|
125
|
+
shardNames: ['tasks', 'relations', 'docs', 'modules', 'prompts'],
|
|
122
126
|
// 显式路由:DevPlan 实体类型 → 对应分片
|
|
123
127
|
typeShardMapping: {
|
|
124
128
|
'devplan-project': 0, // 项目根节点 → tasks shard
|
|
@@ -126,6 +130,7 @@ class DevPlanGraphStore {
|
|
|
126
130
|
'devplan-sub-task': 0, // 子任务 → tasks shard
|
|
127
131
|
'devplan-doc': 2, // 文档片段 → docs shard
|
|
128
132
|
'devplan-module': 3, // 功能模块 → modules shard
|
|
133
|
+
'devplan-prompt': 4, // Prompt 日志 → prompts shard
|
|
129
134
|
'_default': 0, // 未知类型 → tasks shard (fallback)
|
|
130
135
|
},
|
|
131
136
|
relationShardId: 1, // 所有关系 → relations shard
|
|
@@ -343,6 +348,7 @@ class DevPlanGraphStore {
|
|
|
343
348
|
estimatedHours: p.estimatedHours || undefined,
|
|
344
349
|
relatedSections: p.relatedSections || [],
|
|
345
350
|
moduleId: p.moduleId || undefined,
|
|
351
|
+
relatedPromptIds: p.relatedPromptIds || [],
|
|
346
352
|
totalSubtasks: p.totalSubtasks || 0,
|
|
347
353
|
completedSubtasks: p.completedSubtasks || 0,
|
|
348
354
|
status: p.status || 'pending',
|
|
@@ -685,6 +691,7 @@ class DevPlanGraphStore {
|
|
|
685
691
|
description: input.description || '',
|
|
686
692
|
estimatedHours: input.estimatedHours || 0,
|
|
687
693
|
relatedSections: input.relatedSections || [],
|
|
694
|
+
relatedPromptIds: input.relatedPromptIds || [],
|
|
688
695
|
moduleId: input.moduleId || null,
|
|
689
696
|
totalSubtasks: 0,
|
|
690
697
|
completedSubtasks: 0,
|
|
@@ -713,6 +720,15 @@ class DevPlanGraphStore {
|
|
|
713
720
|
}
|
|
714
721
|
}
|
|
715
722
|
}
|
|
723
|
+
// task -> prompt 关系(通过 relatedPromptIds 建立)
|
|
724
|
+
if (input.relatedPromptIds?.length) {
|
|
725
|
+
for (const promptId of input.relatedPromptIds) {
|
|
726
|
+
const promptEntity = this.graph.getEntity(promptId);
|
|
727
|
+
if (promptEntity && promptEntity.entity_type === ET.PROMPT) {
|
|
728
|
+
this.graph.putRelation(entity.id, promptEntity.id, RT.TASK_HAS_PROMPT);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
716
732
|
this.graph.flush();
|
|
717
733
|
return this.entityToMainTask(entity);
|
|
718
734
|
}
|
|
@@ -1274,6 +1290,121 @@ class DevPlanGraphStore {
|
|
|
1274
1290
|
};
|
|
1275
1291
|
}
|
|
1276
1292
|
// ==========================================================================
|
|
1293
|
+
// Prompt Operations (用户 Prompt 日志)
|
|
1294
|
+
// ==========================================================================
|
|
1295
|
+
/**
|
|
1296
|
+
* 保存一条 Prompt
|
|
1297
|
+
*
|
|
1298
|
+
* 自动分配 promptIndex (当天内自增序号)。
|
|
1299
|
+
* 如果指定了 relatedTaskId,自动建立 task_has_prompt 关系。
|
|
1300
|
+
*/
|
|
1301
|
+
savePrompt(input) {
|
|
1302
|
+
const now = Date.now();
|
|
1303
|
+
const today = new Date(now).toISOString().slice(0, 10); // YYYY-MM-DD
|
|
1304
|
+
// 获取当天已有 prompt 数量,分配自增序号
|
|
1305
|
+
const existingToday = this.listPrompts({ date: today });
|
|
1306
|
+
const promptIndex = existingToday.length + 1;
|
|
1307
|
+
// 生成简短标签作为 entity name
|
|
1308
|
+
const namePreview = input.content.slice(0, 50).replace(/\n/g, ' ');
|
|
1309
|
+
const entityName = `Prompt #${promptIndex} (${today})`;
|
|
1310
|
+
const entity = this.graph.addEntity(entityName, ET.PROMPT, {
|
|
1311
|
+
projectName: this.projectName,
|
|
1312
|
+
promptIndex,
|
|
1313
|
+
content: input.content,
|
|
1314
|
+
aiInterpretation: input.aiInterpretation || '',
|
|
1315
|
+
summary: input.summary || '',
|
|
1316
|
+
relatedTaskId: input.relatedTaskId || null,
|
|
1317
|
+
tags: input.tags || [],
|
|
1318
|
+
date: today,
|
|
1319
|
+
createdAt: now,
|
|
1320
|
+
});
|
|
1321
|
+
// project -> prompt 关系
|
|
1322
|
+
this.graph.putRelation(this.getProjectId(), entity.id, RT.HAS_PROMPT);
|
|
1323
|
+
// task -> prompt 关系
|
|
1324
|
+
if (input.relatedTaskId) {
|
|
1325
|
+
const taskEntity = this.findEntityByProp(ET.MAIN_TASK, 'taskId', input.relatedTaskId);
|
|
1326
|
+
if (taskEntity) {
|
|
1327
|
+
this.graph.putRelation(taskEntity.id, entity.id, RT.TASK_HAS_PROMPT);
|
|
1328
|
+
// 同时更新主任务的 relatedPromptIds 数组
|
|
1329
|
+
const taskProps = taskEntity.properties;
|
|
1330
|
+
const existingIds = taskProps.relatedPromptIds || [];
|
|
1331
|
+
if (!existingIds.includes(entity.id)) {
|
|
1332
|
+
this.graph.updateEntity(taskEntity.id, {
|
|
1333
|
+
properties: {
|
|
1334
|
+
...taskProps,
|
|
1335
|
+
relatedPromptIds: [...existingIds, entity.id],
|
|
1336
|
+
updatedAt: now,
|
|
1337
|
+
},
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
this.graph.flush();
|
|
1343
|
+
return this.entityToPrompt(entity);
|
|
1344
|
+
}
|
|
1345
|
+
/**
|
|
1346
|
+
* 列出 Prompt(支持按日期、关联任务过滤)
|
|
1347
|
+
*/
|
|
1348
|
+
listPrompts(filter) {
|
|
1349
|
+
// 如果按关联任务过滤,通过关系查询
|
|
1350
|
+
if (filter?.relatedTaskId) {
|
|
1351
|
+
return this.getTaskRelatedPrompts(filter.relatedTaskId);
|
|
1352
|
+
}
|
|
1353
|
+
const entities = this.findEntitiesByType(ET.PROMPT);
|
|
1354
|
+
let prompts = entities
|
|
1355
|
+
.filter((e) => {
|
|
1356
|
+
const p = e.properties;
|
|
1357
|
+
if (p.projectName !== this.projectName)
|
|
1358
|
+
return false;
|
|
1359
|
+
if (filter?.date && p.date !== filter.date)
|
|
1360
|
+
return false;
|
|
1361
|
+
return true;
|
|
1362
|
+
})
|
|
1363
|
+
.map((e) => this.entityToPrompt(e));
|
|
1364
|
+
// 按 createdAt 降序排列(最新的在前)
|
|
1365
|
+
prompts.sort((a, b) => b.createdAt - a.createdAt);
|
|
1366
|
+
if (filter?.limit && filter.limit > 0) {
|
|
1367
|
+
prompts = prompts.slice(0, filter.limit);
|
|
1368
|
+
}
|
|
1369
|
+
return prompts;
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* 获取主任务关联的所有 Prompt
|
|
1373
|
+
*/
|
|
1374
|
+
getTaskRelatedPrompts(taskId) {
|
|
1375
|
+
const taskEntity = this.findEntityByProp(ET.MAIN_TASK, 'taskId', taskId);
|
|
1376
|
+
if (!taskEntity)
|
|
1377
|
+
return [];
|
|
1378
|
+
const rels = this.getOutRelations(taskEntity.id, RT.TASK_HAS_PROMPT);
|
|
1379
|
+
const prompts = [];
|
|
1380
|
+
for (const rel of rels) {
|
|
1381
|
+
const promptEntity = this.graph.getEntity(rel.target);
|
|
1382
|
+
if (promptEntity && promptEntity.entity_type === ET.PROMPT) {
|
|
1383
|
+
prompts.push(this.entityToPrompt(promptEntity));
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
// 按 createdAt 升序排列
|
|
1387
|
+
prompts.sort((a, b) => a.createdAt - b.createdAt);
|
|
1388
|
+
return prompts;
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* Entity → Prompt 转换
|
|
1392
|
+
*/
|
|
1393
|
+
entityToPrompt(e) {
|
|
1394
|
+
const p = e.properties;
|
|
1395
|
+
return {
|
|
1396
|
+
id: e.id,
|
|
1397
|
+
projectName: this.projectName,
|
|
1398
|
+
promptIndex: p.promptIndex || 0,
|
|
1399
|
+
content: p.content || '',
|
|
1400
|
+
aiInterpretation: p.aiInterpretation || undefined,
|
|
1401
|
+
summary: p.summary || undefined,
|
|
1402
|
+
relatedTaskId: p.relatedTaskId || undefined,
|
|
1403
|
+
tags: p.tags || [],
|
|
1404
|
+
createdAt: p.createdAt || e.created_at,
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
// ==========================================================================
|
|
1277
1408
|
// Utility
|
|
1278
1409
|
// ==========================================================================
|
|
1279
1410
|
sync() {
|
|
@@ -1336,6 +1467,7 @@ class DevPlanGraphStore {
|
|
|
1336
1467
|
const includeModules = options?.includeModules !== false;
|
|
1337
1468
|
const includeNodeDegree = options?.includeNodeDegree !== false;
|
|
1338
1469
|
const enableBackendDegreeFallback = options?.enableBackendDegreeFallback !== false;
|
|
1470
|
+
const includePrompts = options?.includePrompts !== false;
|
|
1339
1471
|
const nodes = [];
|
|
1340
1472
|
const edges = [];
|
|
1341
1473
|
// 项目根节点
|
|
@@ -1395,6 +1527,39 @@ class DevPlanGraphStore {
|
|
|
1395
1527
|
label: RT.TASK_HAS_DOC,
|
|
1396
1528
|
});
|
|
1397
1529
|
}
|
|
1530
|
+
// task -> prompt 关系
|
|
1531
|
+
if (includePrompts) {
|
|
1532
|
+
const taskPromptRels = this.getOutRelations(mt.id, RT.TASK_HAS_PROMPT);
|
|
1533
|
+
for (const rel of taskPromptRels) {
|
|
1534
|
+
edges.push({
|
|
1535
|
+
from: mt.id,
|
|
1536
|
+
to: rel.target,
|
|
1537
|
+
label: RT.TASK_HAS_PROMPT,
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
// Prompt 节点(默认包含,可视化页面可传 includePrompts=false 排除)
|
|
1543
|
+
if (includePrompts) {
|
|
1544
|
+
const prompts = this.listPrompts();
|
|
1545
|
+
for (const prompt of prompts) {
|
|
1546
|
+
nodes.push({
|
|
1547
|
+
id: prompt.id,
|
|
1548
|
+
label: `Prompt #${prompt.promptIndex}`,
|
|
1549
|
+
type: 'prompt',
|
|
1550
|
+
properties: {
|
|
1551
|
+
promptIndex: prompt.promptIndex,
|
|
1552
|
+
summary: prompt.summary || '',
|
|
1553
|
+
relatedTaskId: prompt.relatedTaskId || null,
|
|
1554
|
+
createdAt: prompt.createdAt,
|
|
1555
|
+
},
|
|
1556
|
+
});
|
|
1557
|
+
edges.push({
|
|
1558
|
+
from: this.getProjectId(),
|
|
1559
|
+
to: prompt.id,
|
|
1560
|
+
label: RT.HAS_PROMPT,
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1398
1563
|
}
|
|
1399
1564
|
// 文档节点
|
|
1400
1565
|
if (includeDocuments) {
|
|
@@ -1450,6 +1615,12 @@ class DevPlanGraphStore {
|
|
|
1450
1615
|
mainTaskCount: mod.mainTaskCount,
|
|
1451
1616
|
},
|
|
1452
1617
|
});
|
|
1618
|
+
// 项目→模块 关系(确保每个模块都与项目节点相连,不会成为孤立节点)
|
|
1619
|
+
edges.push({
|
|
1620
|
+
from: this.getProjectId(),
|
|
1621
|
+
to: mod.id,
|
|
1622
|
+
label: RT.HAS_MODULE,
|
|
1623
|
+
});
|
|
1453
1624
|
// 模块→主任务 关系
|
|
1454
1625
|
const moduleTasks = this.listMainTasks({ moduleId: mod.moduleId });
|
|
1455
1626
|
for (const mt of moduleTasks) {
|
|
@@ -1506,6 +1677,197 @@ class DevPlanGraphStore {
|
|
|
1506
1677
|
}
|
|
1507
1678
|
return { nodes, edges };
|
|
1508
1679
|
}
|
|
1680
|
+
/**
|
|
1681
|
+
* 分页导出图谱数据 (Phase-9 T9.1)
|
|
1682
|
+
*
|
|
1683
|
+
* 利用 Rust 层 SocialGraphV2 的 exportGraphPaginated() 分页 API,
|
|
1684
|
+
* 避免全量加载 + 内存切片。真正的分页下推到数据库层。
|
|
1685
|
+
*
|
|
1686
|
+
* @param offset 分页偏移量
|
|
1687
|
+
* @param limit 每页节点数
|
|
1688
|
+
* @param options 可选参数
|
|
1689
|
+
* @returns 分页图谱数据
|
|
1690
|
+
*/
|
|
1691
|
+
exportGraphPaginated(offset, limit, options) {
|
|
1692
|
+
const includeDocuments = options?.includeDocuments !== false;
|
|
1693
|
+
const includeModules = options?.includeModules !== false;
|
|
1694
|
+
const includeNodeDegree = options?.includeNodeDegree !== false;
|
|
1695
|
+
// Build entity type filter for Rust layer
|
|
1696
|
+
const entityTypes = [];
|
|
1697
|
+
entityTypes.push(ET.PROJECT, ET.MAIN_TASK, ET.SUB_TASK);
|
|
1698
|
+
if (includeDocuments)
|
|
1699
|
+
entityTypes.push(ET.DOC);
|
|
1700
|
+
if (includeModules)
|
|
1701
|
+
entityTypes.push(ET.MODULE);
|
|
1702
|
+
if (options?.entityTypes?.length) {
|
|
1703
|
+
// Use user-specified filter if provided
|
|
1704
|
+
entityTypes.length = 0;
|
|
1705
|
+
entityTypes.push(...options.entityTypes);
|
|
1706
|
+
}
|
|
1707
|
+
try {
|
|
1708
|
+
// Call Rust SocialGraphV2.exportGraphPaginated via NAPI
|
|
1709
|
+
const result = this.graph.exportGraphPaginated({
|
|
1710
|
+
offset,
|
|
1711
|
+
limit,
|
|
1712
|
+
entityTypes,
|
|
1713
|
+
includeNodeDegree,
|
|
1714
|
+
includeEdgeMeta: false,
|
|
1715
|
+
});
|
|
1716
|
+
if (result && typeof result === 'object') {
|
|
1717
|
+
const rustNodes = result.nodes || [];
|
|
1718
|
+
const rustEdges = result.edges || [];
|
|
1719
|
+
// Transform Rust GraphNode -> DevPlanGraphNode
|
|
1720
|
+
// Rust GraphNode only carries `group: NodeGroup` (numeric 0/1/2) — all DevPlan
|
|
1721
|
+
// entities map to Tag(2), losing type information. We must resolve entity_type
|
|
1722
|
+
// via getEntity() for correct visualization (module=diamond, doc=box, etc.).
|
|
1723
|
+
const currentProjectId = this.getProjectId();
|
|
1724
|
+
const nodes = [];
|
|
1725
|
+
for (const n of rustNodes) {
|
|
1726
|
+
const data = n.data || {};
|
|
1727
|
+
// Try multiple sources for entity_type string
|
|
1728
|
+
let etStr = n.entity_type || n.entityType
|
|
1729
|
+
|| data.entity_type || data.entityType;
|
|
1730
|
+
// If still not found, look up the actual entity (fast hash lookup)
|
|
1731
|
+
if (!etStr || typeof etStr !== 'string') {
|
|
1732
|
+
try {
|
|
1733
|
+
const entity = this.graph.getEntity(n.id);
|
|
1734
|
+
if (entity) {
|
|
1735
|
+
etStr = entity.entity_type || entity.entityType;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
catch { /* ignore — fall through to group */ }
|
|
1739
|
+
}
|
|
1740
|
+
const devPlanType = this.mapGroupToDevPlanType(etStr || n.group);
|
|
1741
|
+
// Filter out project nodes that don't belong to the current project.
|
|
1742
|
+
// The Rust layer returns ALL entities matching the type filter, which may
|
|
1743
|
+
// include stale project nodes from other projects (e.g. "devplan-db").
|
|
1744
|
+
if (devPlanType === 'project' && n.id !== currentProjectId) {
|
|
1745
|
+
continue;
|
|
1746
|
+
}
|
|
1747
|
+
nodes.push({
|
|
1748
|
+
id: n.id,
|
|
1749
|
+
label: n.label || n.id,
|
|
1750
|
+
type: devPlanType,
|
|
1751
|
+
degree: includeNodeDegree ? (n.degree ?? 0) : undefined,
|
|
1752
|
+
properties: data,
|
|
1753
|
+
});
|
|
1754
|
+
}
|
|
1755
|
+
// Transform Rust GraphEdge -> DevPlanGraphEdge
|
|
1756
|
+
const edges = rustEdges.map((e) => ({
|
|
1757
|
+
from: e.from,
|
|
1758
|
+
to: e.to,
|
|
1759
|
+
label: e.label || e.relation_type || '',
|
|
1760
|
+
}));
|
|
1761
|
+
return {
|
|
1762
|
+
nodes,
|
|
1763
|
+
edges,
|
|
1764
|
+
totalNodes: result.total_nodes ?? result.totalNodes ?? nodes.length,
|
|
1765
|
+
totalEdges: result.total_edges ?? result.totalEdges ?? edges.length,
|
|
1766
|
+
offset: result.offset ?? offset,
|
|
1767
|
+
limit: result.limit ?? limit,
|
|
1768
|
+
hasMore: result.has_more ?? result.hasMore ?? false,
|
|
1769
|
+
};
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
catch {
|
|
1773
|
+
// If NAPI method not available, fall back to in-memory pagination
|
|
1774
|
+
}
|
|
1775
|
+
// Fallback: full load + in-memory pagination
|
|
1776
|
+
const fullGraph = this.exportGraph({
|
|
1777
|
+
includeDocuments,
|
|
1778
|
+
includeModules,
|
|
1779
|
+
includeNodeDegree,
|
|
1780
|
+
enableBackendDegreeFallback: true,
|
|
1781
|
+
});
|
|
1782
|
+
const allNodes = fullGraph.nodes;
|
|
1783
|
+
const pageNodes = allNodes.slice(offset, offset + limit);
|
|
1784
|
+
const pageNodeIds = new Set(pageNodes.map((n) => n.id));
|
|
1785
|
+
const pageEdges = fullGraph.edges.filter((e) => pageNodeIds.has(e.from) && pageNodeIds.has(e.to));
|
|
1786
|
+
return {
|
|
1787
|
+
nodes: pageNodes,
|
|
1788
|
+
edges: pageEdges,
|
|
1789
|
+
totalNodes: allNodes.length,
|
|
1790
|
+
totalEdges: fullGraph.edges.length,
|
|
1791
|
+
offset,
|
|
1792
|
+
limit,
|
|
1793
|
+
hasMore: offset + limit < allNodes.length,
|
|
1794
|
+
};
|
|
1795
|
+
}
|
|
1796
|
+
/**
|
|
1797
|
+
* 导出紧凑二进制格式 (Phase-9 T9.3)
|
|
1798
|
+
*
|
|
1799
|
+
* 利用 Rust 层 CompactGraphExport 格式,返回 Buffer。
|
|
1800
|
+
* 比 JSON 小 5x+,解析速度接近零。
|
|
1801
|
+
*
|
|
1802
|
+
* @returns Node.js Buffer 或 null (如果 NAPI 方法不可用)
|
|
1803
|
+
*/
|
|
1804
|
+
exportGraphCompact() {
|
|
1805
|
+
try {
|
|
1806
|
+
const buf = this.graph.exportGraphCompact({
|
|
1807
|
+
maxNodes: 1000000,
|
|
1808
|
+
includeTags: true,
|
|
1809
|
+
includeCompanies: true,
|
|
1810
|
+
includeNodeDegree: true,
|
|
1811
|
+
includeEdgeMeta: false,
|
|
1812
|
+
});
|
|
1813
|
+
if (buf && buf.length > 16) {
|
|
1814
|
+
return buf;
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
catch {
|
|
1818
|
+
// NAPI method not available
|
|
1819
|
+
}
|
|
1820
|
+
return null;
|
|
1821
|
+
}
|
|
1822
|
+
/**
|
|
1823
|
+
* 获取实体组聚合摘要 (Phase-9 T9.4)
|
|
1824
|
+
*
|
|
1825
|
+
* 利用 Rust 层 group_entities_summary() 返回按类型分组的统计信息。
|
|
1826
|
+
* 远比加载全部实体开销小,适合低缩放级别的集群视图。
|
|
1827
|
+
*
|
|
1828
|
+
* @returns 聚合结果或 null (如果 NAPI 方法不可用)
|
|
1829
|
+
*/
|
|
1830
|
+
getEntityGroupSummary() {
|
|
1831
|
+
try {
|
|
1832
|
+
const result = this.graph.getEntityGroupSummary();
|
|
1833
|
+
if (result && typeof result === 'object') {
|
|
1834
|
+
return {
|
|
1835
|
+
groups: (result.groups || []).map((g) => ({
|
|
1836
|
+
entityType: g.entity_type ?? g.entityType ?? '',
|
|
1837
|
+
count: g.count ?? 0,
|
|
1838
|
+
sampleIds: g.sample_ids ?? g.sampleIds ?? [],
|
|
1839
|
+
})),
|
|
1840
|
+
totalEntities: result.total_entities ?? result.totalEntities ?? 0,
|
|
1841
|
+
totalRelations: result.total_relations ?? result.totalRelations ?? 0,
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
catch {
|
|
1846
|
+
// NAPI method not available
|
|
1847
|
+
}
|
|
1848
|
+
return null;
|
|
1849
|
+
}
|
|
1850
|
+
/**
|
|
1851
|
+
* Map Rust NodeGroup name to DevPlan node type
|
|
1852
|
+
*/
|
|
1853
|
+
mapGroupToDevPlanType(group) {
|
|
1854
|
+
// Rust NodeGroup: 0=Person, 1=Company, 2=Tag
|
|
1855
|
+
// But in DevPlan context, entity_type matters more
|
|
1856
|
+
// We rely on the entity's entity_type property
|
|
1857
|
+
if (typeof group === 'string') {
|
|
1858
|
+
if (group.includes('project'))
|
|
1859
|
+
return 'project';
|
|
1860
|
+
if (group.includes('main-task') || group.includes('main_task'))
|
|
1861
|
+
return 'main-task';
|
|
1862
|
+
if (group.includes('sub-task') || group.includes('sub_task'))
|
|
1863
|
+
return 'sub-task';
|
|
1864
|
+
if (group.includes('doc'))
|
|
1865
|
+
return 'document';
|
|
1866
|
+
if (group.includes('module'))
|
|
1867
|
+
return 'module';
|
|
1868
|
+
}
|
|
1869
|
+
return 'sub-task'; // default fallback
|
|
1870
|
+
}
|
|
1509
1871
|
// ==========================================================================
|
|
1510
1872
|
// Private Helpers
|
|
1511
1873
|
// ==========================================================================
|