dsh-plugin-mind-tree 0.0.0-stage → 0.3.0
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/LICENSE +21 -0
- package/README.md +294 -2
- package/cordis.patch.yml +4 -0
- package/lib/client.js +23176 -0
- package/lib/format.js +364 -0
- package/lib/index.js +1006 -0
- package/lib/reduce.js +182 -0
- package/lib/remote.js +178 -0
- package/lib/typert.host.js +30 -0
- package/package.json +90 -4
package/lib/reduce.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// 过程信息削减层:把"事件日志式"的完整树压缩成"对话结构式"的思维树。
|
|
2
|
+
// Copyright (c) 2026 ShOpenMind · https://github.com/ShOpenMind/dsh-plugin-mind-tree · MIT
|
|
3
|
+
// 纯函数、无 DSH 依赖,客户端渲染与导出共用,可独立单测。
|
|
4
|
+
import { buildHierarchy, isInjectedLabel } from './format.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 三档信息量:
|
|
8
|
+
* - compact (默认):只留 轮次 + 用户真实发言 + 分支节点 + 每轮工具活动聚合 1 行 + 每轮最终助手回复;
|
|
9
|
+
* - standard:在 compact 基础上保留实质性助手过程文本(≥ MIN_ASSISTANT_STANDARD 字)与工具明细行,去掉工具结果;
|
|
10
|
+
* - full:不做任何削减(与事件日志一一对应)。
|
|
11
|
+
*/
|
|
12
|
+
export const DETAIL_LEVELS = ['compact', 'standard', 'full'];
|
|
13
|
+
|
|
14
|
+
/** standard 档保留的助手文本最小字数。 */
|
|
15
|
+
export const MIN_ASSISTANT_STANDARD = 60;
|
|
16
|
+
/** 工具聚合行里展示的工具名个数。 */
|
|
17
|
+
const GROUP_NAME_LIMIT = 4;
|
|
18
|
+
|
|
19
|
+
const charLength = (text) => [...String(text ?? '')].length;
|
|
20
|
+
|
|
21
|
+
/** 工具名:去掉"工具 "前缀与参数部分。 */
|
|
22
|
+
function toolName(label) {
|
|
23
|
+
return String(label ?? '工具')
|
|
24
|
+
.replace(/^工具\s*/, '')
|
|
25
|
+
.split(/[\s((::]/)[0] || '工具';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** 每轮最后一条助手消息(视为该轮答复)。 */
|
|
29
|
+
function lastAssistantIds(nodes) {
|
|
30
|
+
const byTurn = new Map();
|
|
31
|
+
for (const node of nodes) {
|
|
32
|
+
if (node.kind !== 'assistant') continue;
|
|
33
|
+
const key = node.turn ?? -1;
|
|
34
|
+
if (!byTurn.has(key)) byTurn.set(key, []);
|
|
35
|
+
byTurn.get(key).push(node);
|
|
36
|
+
}
|
|
37
|
+
const ids = new Set();
|
|
38
|
+
for (const list of byTurn.values()) ids.add(list[list.length - 1].id);
|
|
39
|
+
return ids;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 削减思维树。
|
|
44
|
+
* @param tree - { sessionId, title, nodes, edges, turnCount }
|
|
45
|
+
* @param level - compact | standard | full
|
|
46
|
+
* @returns 与原结构同形的新对象;full 档原样返回。附 `reduction` 统计与 `grouped` 折叠信息。
|
|
47
|
+
*/
|
|
48
|
+
export function reduceGraph(tree, level = 'compact') {
|
|
49
|
+
if (tree === null || tree === undefined) return tree;
|
|
50
|
+
if (level === 'full') return tree;
|
|
51
|
+
const nodes = tree.nodes ?? [];
|
|
52
|
+
const keepIds = new Set();
|
|
53
|
+
const isCompact = level === 'compact';
|
|
54
|
+
const minAssistant = isCompact ? Number.POSITIVE_INFINITY : MIN_ASSISTANT_STANDARD;
|
|
55
|
+
const lastOfTurn = lastAssistantIds(nodes);
|
|
56
|
+
/** 归入工具聚合行的节点(turn -> 节点数组)。 */
|
|
57
|
+
const groupBuckets = new Map();
|
|
58
|
+
|
|
59
|
+
for (const node of nodes) {
|
|
60
|
+
// 根节点与轮次节点始终保留(树骨架)。
|
|
61
|
+
if (node.id === 'root' || node.kind === 'turn') { keepIds.add(node.id); continue; }
|
|
62
|
+
// 分支节点(决策点)始终保留,哪怕它是工具调用或助手消息。
|
|
63
|
+
if (node.branch) { keepIds.add(node.id); continue; }
|
|
64
|
+
switch (node.kind) {
|
|
65
|
+
case 'result':
|
|
66
|
+
continue; // 工具输出:折叠掉(可在工具行详情中查看)
|
|
67
|
+
case 'info':
|
|
68
|
+
continue; // system / developer 注入内容
|
|
69
|
+
case 'user':
|
|
70
|
+
if (isInjectedLabel(node.label)) continue; // 模型切换、运行时上下文、后台任务通知
|
|
71
|
+
break;
|
|
72
|
+
case 'assistant':
|
|
73
|
+
if (!(lastOfTurn.has(node.id) || charLength(node.label) >= minAssistant)) continue;
|
|
74
|
+
break;
|
|
75
|
+
case 'tool': {
|
|
76
|
+
if (!isCompact) break; // standard 保留工具明细行
|
|
77
|
+
const key = node.turn ?? -1;
|
|
78
|
+
if (!groupBuckets.has(key)) groupBuckets.set(key, []);
|
|
79
|
+
groupBuckets.get(key).push(node);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
default:
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
keepIds.add(node.id);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 生成每轮的"工具活动"聚合行。
|
|
89
|
+
const synthetic = [];
|
|
90
|
+
for (const [turn, list] of groupBuckets) {
|
|
91
|
+
if (list.length === 0) continue;
|
|
92
|
+
const counts = new Map();
|
|
93
|
+
for (const item of list) {
|
|
94
|
+
const name = toolName(item.label);
|
|
95
|
+
counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
96
|
+
}
|
|
97
|
+
const top = [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, GROUP_NAME_LIMIT)
|
|
98
|
+
.map(([name, count]) => (count > 1 ? `${name}×${count}` : name));
|
|
99
|
+
const rest = counts.size - top.length;
|
|
100
|
+
synthetic.push({
|
|
101
|
+
id: `tg:${turn}`,
|
|
102
|
+
seq: list[0].seq,
|
|
103
|
+
type: 'tool/group',
|
|
104
|
+
kind: 'toolgroup',
|
|
105
|
+
...(turn >= 0 ? { turn } : {}),
|
|
106
|
+
label: `工具活动 ×${list.length} · ${top.join(' ')}${rest > 0 ? ` +${rest}` : ''}`,
|
|
107
|
+
surface: 'current',
|
|
108
|
+
// 自带折叠清单(含标签与序号),这样聚合行在"精简"档下也能独立展示与搜索。
|
|
109
|
+
grouped: list.map((item) => ({ id: item.id, label: item.label, seq: item.seq, kind: item.kind })),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const reducedNodes = [...nodes.filter((n) => keepIds.has(n.id)), ...synthetic];
|
|
114
|
+
const keptIds = new Set(reducedNodes.map((n) => n.id));
|
|
115
|
+
const { children, parentOf } = buildHierarchy(tree);
|
|
116
|
+
|
|
117
|
+
// 重新挂接:每个保留节点挂到"最近的保留祖先";找不到则挂到所属轮次,再退到根。
|
|
118
|
+
const nearestKeptAncestor = (node) => {
|
|
119
|
+
let cursor = parentOf.get(node.id);
|
|
120
|
+
const seen = new Set([node.id]);
|
|
121
|
+
while (cursor !== undefined && !seen.has(cursor)) {
|
|
122
|
+
if (keptIds.has(cursor)) return cursor;
|
|
123
|
+
seen.add(cursor);
|
|
124
|
+
cursor = parentOf.get(cursor);
|
|
125
|
+
}
|
|
126
|
+
return undefined;
|
|
127
|
+
};
|
|
128
|
+
const turnIdOf = (node) => (node.turn != null && keptIds.has(`t${node.turn}`) ? `t${node.turn}` : undefined);
|
|
129
|
+
const fallbackParent = (node) => turnIdOf(node)
|
|
130
|
+
?? (keptIds.has('root') ? 'root' : undefined);
|
|
131
|
+
|
|
132
|
+
const edges = [];
|
|
133
|
+
const roots = reducedNodes.filter((n) => n.kind === 'turn' || n.id === 'root');
|
|
134
|
+
const rootId = reducedNodes.find((n) => n.id === 'root')?.id;
|
|
135
|
+
const turns = reducedNodes.filter((n) => n.kind === 'turn').sort((a, b) => (a.turn ?? 0) - (b.turn ?? 0));
|
|
136
|
+
let previous = rootId;
|
|
137
|
+
for (const turn of turns) {
|
|
138
|
+
edges.push({ from: previous ?? turn.id, to: turn.id, kind: 'next' });
|
|
139
|
+
previous = turn.id;
|
|
140
|
+
}
|
|
141
|
+
for (const node of reducedNodes) {
|
|
142
|
+
if (node.id === 'root' || node.kind === 'turn') continue;
|
|
143
|
+
const parent = node.kind === 'toolgroup'
|
|
144
|
+
? (fallbackParent(node) ?? rootId)
|
|
145
|
+
: (nearestKeptAncestor(node) ?? fallbackParent(node) ?? rootId);
|
|
146
|
+
if (parent === undefined || parent === node.id) continue;
|
|
147
|
+
edges.push({ from: parent, to: node.id, kind: 'step' });
|
|
148
|
+
}
|
|
149
|
+
// 次级边(被替换 / 派生):两端都保留才保留。
|
|
150
|
+
for (const edge of tree.edges ?? []) {
|
|
151
|
+
if (edge.kind !== 'replaced-by' && edge.kind !== 'derived') continue;
|
|
152
|
+
if (!keptIds.has(edge.from) || !keptIds.has(edge.to)) continue;
|
|
153
|
+
if (edge.from === edge.to) continue;
|
|
154
|
+
edges.push({ from: edge.from, to: edge.to, kind: edge.kind });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
...tree,
|
|
159
|
+
nodes: reducedNodes,
|
|
160
|
+
edges,
|
|
161
|
+
reduction: {
|
|
162
|
+
level,
|
|
163
|
+
before: nodes.length,
|
|
164
|
+
after: reducedNodes.length,
|
|
165
|
+
grouped: synthetic.length,
|
|
166
|
+
foldedTools: [...groupBuckets.values()].reduce((sum, list) => sum + list.length, 0),
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** 便于 UI 显示:三档的中文/英文标签与说明。 */
|
|
172
|
+
export const DETAIL_LABELS = {
|
|
173
|
+
compact: { zh: '精简', en: 'Compact' },
|
|
174
|
+
standard: { zh: '标准', en: 'Standard' },
|
|
175
|
+
full: { zh: '完整', en: 'Full' },
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/** 统计:树里有多少"过程信息"节点(用于提示可以精简)。 */
|
|
179
|
+
export function processNodeCount(tree) {
|
|
180
|
+
return (tree?.nodes ?? []).filter((n) => n.kind === 'result' || n.kind === 'info'
|
|
181
|
+
|| (n.kind === 'tool' && !n.branch) || (n.kind === 'user' && isInjectedLabel(n.label))).length;
|
|
182
|
+
}
|
package/lib/remote.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// dsh-plugin-mind-tree 远程契约:主机(host)与网页客户端(client)之间唯一的数据面。
|
|
2
|
+
// Copyright (c) 2026 ShOpenMind · https://github.com/ShOpenMind/dsh-plugin-mind-tree · MIT
|
|
3
|
+
// 本文件同时被宿主加载器(经 ./typert)与客户端构建工具(打包进 lib/client.js)引用,
|
|
4
|
+
// 因此只依赖 zod,不依赖任何 DSH 实现代码。
|
|
5
|
+
import z from 'zod';
|
|
6
|
+
|
|
7
|
+
export const PACKAGE = 'dsh-plugin-mind-tree';
|
|
8
|
+
export const NAMESPACE = 'mindTree';
|
|
9
|
+
|
|
10
|
+
export const MindNodeSchema = z.object({
|
|
11
|
+
sessionId: z.string(),
|
|
12
|
+
title: z.string().optional(),
|
|
13
|
+
parentSessionId: z.string().nullable().optional(),
|
|
14
|
+
origin: z.string().nullable().optional(),
|
|
15
|
+
delegationDepth: z.number().optional(),
|
|
16
|
+
live: z.boolean(),
|
|
17
|
+
persisted: z.boolean(),
|
|
18
|
+
createdAt: z.number(),
|
|
19
|
+
cwd: z.string().optional(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const MindEdgeSchema = z.object({
|
|
23
|
+
from: z.string(),
|
|
24
|
+
to: z.string(),
|
|
25
|
+
kind: z.string(),
|
|
26
|
+
spawnSeq: z.number().optional(),
|
|
27
|
+
spawnLabel: z.string().optional(),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const ForestViewSchema = z.object({
|
|
31
|
+
nodes: z.array(MindNodeSchema),
|
|
32
|
+
edges: z.array(MindEdgeSchema),
|
|
33
|
+
roots: z.array(z.string()),
|
|
34
|
+
warnings: z.array(z.string()).optional(),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export const LineageViewSchema = z.object({
|
|
38
|
+
complete: z.boolean(),
|
|
39
|
+
unresolvedParentId: z.string().optional(),
|
|
40
|
+
target: z.string(),
|
|
41
|
+
root: z.string().optional(),
|
|
42
|
+
nodes: z.array(MindNodeSchema),
|
|
43
|
+
edges: z.array(MindEdgeSchema),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const BranchNodeSchema = z.object({
|
|
47
|
+
id: z.string(),
|
|
48
|
+
seq: z.number(),
|
|
49
|
+
type: z.string(),
|
|
50
|
+
kind: z.string(),
|
|
51
|
+
turn: z.number().optional(),
|
|
52
|
+
step: z.number().optional(),
|
|
53
|
+
label: z.string(),
|
|
54
|
+
summary: z.string().optional(), // 轮次摘要(约 6–15 字)
|
|
55
|
+
text: z.string().optional(),
|
|
56
|
+
usage: z
|
|
57
|
+
.object({
|
|
58
|
+
input: z.number(),
|
|
59
|
+
output: z.number(),
|
|
60
|
+
total: z.number(),
|
|
61
|
+
cacheRead: z.number().optional(),
|
|
62
|
+
cacheWrite: z.number().optional(),
|
|
63
|
+
reasoning: z.number().optional(),
|
|
64
|
+
messageCount: z.number().optional(),
|
|
65
|
+
durationMs: z.number().optional(),
|
|
66
|
+
})
|
|
67
|
+
.optional(), // 轮次 token 消耗聚合
|
|
68
|
+
surface: z.string(),
|
|
69
|
+
branch: z
|
|
70
|
+
.object({
|
|
71
|
+
kind: z.string(),
|
|
72
|
+
detail: z.unknown().optional(),
|
|
73
|
+
})
|
|
74
|
+
.optional(),
|
|
75
|
+
sessionId: z.string().optional(),
|
|
76
|
+
origin: z.string().optional(),
|
|
77
|
+
error: z.boolean().optional(),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
export const BranchEdgeSchema = z.object({
|
|
81
|
+
from: z.string(),
|
|
82
|
+
to: z.string(),
|
|
83
|
+
kind: z.string(),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
export const ThoughtTreeSchema = z.object({
|
|
87
|
+
sessionId: z.string(),
|
|
88
|
+
title: z.string().optional(),
|
|
89
|
+
nodes: z.array(BranchNodeSchema),
|
|
90
|
+
edges: z.array(BranchEdgeSchema),
|
|
91
|
+
turnCount: z.number(),
|
|
92
|
+
warnings: z.array(z.string()).optional(),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
export const EventWindowSchema = z.object({
|
|
96
|
+
sessionId: z.string(),
|
|
97
|
+
seq: z.number(),
|
|
98
|
+
startSeq: z.number(),
|
|
99
|
+
endSeq: z.number(),
|
|
100
|
+
inheritedEventCount: z.number(),
|
|
101
|
+
target: z.unknown(),
|
|
102
|
+
events: z.array(z.unknown()),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
export const FollowFrameSchema = z.object({
|
|
106
|
+
sessionId: z.string(),
|
|
107
|
+
seq: z.number(),
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
export const FOREST_DESCRIPTOR = {
|
|
111
|
+
id: `${PACKAGE}#mindTree/forest`,
|
|
112
|
+
service: NAMESPACE,
|
|
113
|
+
namespace: NAMESPACE,
|
|
114
|
+
method: 'forest',
|
|
115
|
+
invocation: { kind: 'direct' },
|
|
116
|
+
parameters: [],
|
|
117
|
+
cancellation: { parameter: 'signal' },
|
|
118
|
+
result: { mode: 'strict', typeSymbol: `${PACKAGE}#ForestView`, create: () => ForestViewSchema },
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const LINEAGE_DESCRIPTOR = {
|
|
122
|
+
id: `${PACKAGE}#mindTree/lineage`,
|
|
123
|
+
service: NAMESPACE,
|
|
124
|
+
namespace: NAMESPACE,
|
|
125
|
+
method: 'lineage',
|
|
126
|
+
invocation: { kind: 'direct' },
|
|
127
|
+
parameters: [
|
|
128
|
+
{ name: 'sessionId', wire: 'sessionId', source: 'json', codec: { mode: 'strict', typeSymbol: `${PACKAGE}#SessionId`, create: () => z.string() } },
|
|
129
|
+
],
|
|
130
|
+
cancellation: { parameter: 'signal' },
|
|
131
|
+
result: { mode: 'strict', typeSymbol: `${PACKAGE}#LineageView`, create: () => LineageViewSchema },
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const TREE_DESCRIPTOR = {
|
|
135
|
+
id: `${PACKAGE}#mindTree/tree`,
|
|
136
|
+
service: NAMESPACE,
|
|
137
|
+
namespace: NAMESPACE,
|
|
138
|
+
method: 'tree',
|
|
139
|
+
invocation: { kind: 'direct' },
|
|
140
|
+
parameters: [
|
|
141
|
+
{ name: 'sessionId', wire: 'sessionId', source: 'json', codec: { mode: 'strict', typeSymbol: `${PACKAGE}#SessionId`, create: () => z.string() } },
|
|
142
|
+
],
|
|
143
|
+
cancellation: { parameter: 'signal' },
|
|
144
|
+
result: { mode: 'strict', typeSymbol: `${PACKAGE}#ThoughtTree`, create: () => ThoughtTreeSchema },
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const DETAIL_DESCRIPTOR = {
|
|
148
|
+
id: `${PACKAGE}#mindTree/detail`,
|
|
149
|
+
service: NAMESPACE,
|
|
150
|
+
namespace: NAMESPACE,
|
|
151
|
+
method: 'detail',
|
|
152
|
+
invocation: { kind: 'direct' },
|
|
153
|
+
parameters: [
|
|
154
|
+
{ name: 'sessionId', wire: 'sessionId', source: 'json', codec: { mode: 'strict', typeSymbol: `${PACKAGE}#SessionId`, create: () => z.string() } },
|
|
155
|
+
{ name: 'seq', wire: 'seq', source: 'json', codec: { mode: 'strict', typeSymbol: `${PACKAGE}#Seq`, create: () => z.number() } },
|
|
156
|
+
{ name: 'before', wire: 'before', source: 'json', codec: { mode: 'strict', typeSymbol: `${PACKAGE}#Seq`, create: () => z.number() } },
|
|
157
|
+
{ name: 'after', wire: 'after', source: 'json', codec: { mode: 'strict', typeSymbol: `${PACKAGE}#Seq`, create: () => z.number() } },
|
|
158
|
+
],
|
|
159
|
+
cancellation: { parameter: 'signal' },
|
|
160
|
+
result: { mode: 'strict', typeSymbol: `${PACKAGE}#EventWindow`, create: () => EventWindowSchema },
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const FOLLOW_DESCRIPTOR = {
|
|
164
|
+
id: `${PACKAGE}#mindTree/follow`,
|
|
165
|
+
service: NAMESPACE,
|
|
166
|
+
namespace: NAMESPACE,
|
|
167
|
+
method: 'follow',
|
|
168
|
+
mode: 'stream',
|
|
169
|
+
invocation: { kind: 'direct' },
|
|
170
|
+
parameters: [],
|
|
171
|
+
cancellation: { parameter: 'signal' },
|
|
172
|
+
result: { mode: 'strict', typeSymbol: `${PACKAGE}#FollowFrame`, create: () => FollowFrameSchema },
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
export const TYPERT_REMOTE = {
|
|
176
|
+
package: PACKAGE,
|
|
177
|
+
descriptors: [FOREST_DESCRIPTOR, LINEAGE_DESCRIPTOR, TREE_DESCRIPTOR, DETAIL_DESCRIPTOR, FOLLOW_DESCRIPTOR],
|
|
178
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// 严格反射清单,由 DSH Typert 加载器校验。
|
|
2
|
+
// Copyright (c) 2026 ShOpenMind · https://github.com/ShOpenMind/dsh-plugin-mind-tree · MIT
|
|
3
|
+
import { PACKAGE, NAMESPACE, FOREST_DESCRIPTOR, LINEAGE_DESCRIPTOR, TREE_DESCRIPTOR, DETAIL_DESCRIPTOR, FOLLOW_DESCRIPTOR } from './remote.js';
|
|
4
|
+
|
|
5
|
+
export const TYPERT = {
|
|
6
|
+
package: PACKAGE,
|
|
7
|
+
face: 'host',
|
|
8
|
+
schemas: [],
|
|
9
|
+
invocations: [FOREST_DESCRIPTOR, LINEAGE_DESCRIPTOR, TREE_DESCRIPTOR, DETAIL_DESCRIPTOR, FOLLOW_DESCRIPTOR],
|
|
10
|
+
model: {
|
|
11
|
+
services: [{
|
|
12
|
+
key: NAMESPACE,
|
|
13
|
+
exportName: 'MindTreeService',
|
|
14
|
+
description: '只读的对话分支分析服务:遍历会话事件日志,识别分支节点(替换、重试、提问、批准、派生、目标、待办、计划、压缩),并提供会话血统(派生/子代理)追踪与思维树数据。不写入会话,不发起模型调用。',
|
|
15
|
+
summary: '对话上下文分支节点与思维树分析',
|
|
16
|
+
tags: ['mind-map', 'tree', 'session', 'branch'],
|
|
17
|
+
members: [
|
|
18
|
+
{ kind: 'method', name: 'forest', signature: 'forest(signal?: AbortSignal): Promise<ForestView>' },
|
|
19
|
+
{ kind: 'method', name: 'lineage', signature: 'lineage(sessionId: string, signal?: AbortSignal): Promise<LineageView>' },
|
|
20
|
+
{ kind: 'method', name: 'tree', signature: 'tree(sessionId: string, signal?: AbortSignal): Promise<ThoughtTree>' },
|
|
21
|
+
{ kind: 'method', name: 'detail', signature: 'detail(sessionId: string, seq: number, before: number, after: number, signal?: AbortSignal): Promise<EventWindow>' },
|
|
22
|
+
{ kind: 'method', name: 'follow', signature: 'follow(signal?: AbortSignal): AsyncIterable<FollowFrame>' },
|
|
23
|
+
],
|
|
24
|
+
types: [],
|
|
25
|
+
}],
|
|
26
|
+
events: [],
|
|
27
|
+
objects: [],
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
export default TYPERT;
|
package/package.json
CHANGED
|
@@ -1,6 +1,92 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-mind-tree",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "遍历对话上下文,识别分支节点并渲染思维树/会话树的 DeepSeek Harness 插件(右侧栏 GUI + mind_tree 工具 + Obsidian 导出)。",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "ShOpenMind",
|
|
9
|
+
"email": "ShOpenMind@users.noreply.github.com",
|
|
10
|
+
"url": "https://github.com/ShOpenMind/dsh-plugin-mind-tree"
|
|
11
|
+
},
|
|
12
|
+
"main": "lib/index.js",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": "./lib/index.js",
|
|
15
|
+
"./client": "./lib/client.js",
|
|
16
|
+
"./format": "./lib/format.js",
|
|
17
|
+
"./typert": "./lib/typert.host.js",
|
|
18
|
+
"./remote": "./lib/remote.js",
|
|
19
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
20
|
+
"./package.json": "./package.json"
|
|
21
|
+
},
|
|
22
|
+
"files": ["lib", "cordis.patch.yml", "README.md", "LICENSE"],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/ShOpenMind/dsh-plugin-mind-tree.git"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/ShOpenMind/dsh-plugin-mind-tree#readme",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/ShOpenMind/dsh-plugin-mind-tree/issues"
|
|
30
|
+
},
|
|
31
|
+
"keywords": ["dsh", "deepseek-harness", "plugin", "mindmap", "session-tree", "observability", "dsh-plugin", "dsh-bundle", "dsh-market"],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"zod": "^4.4.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"esbuild": "^0.25.0",
|
|
37
|
+
"happy-dom": "^20.14.6",
|
|
38
|
+
"mermaid": "^12.1.0",
|
|
39
|
+
"react": "^18.3.1",
|
|
40
|
+
"react-dom": "^18.3.1"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "node tools/build.mjs",
|
|
44
|
+
"test": "node tools/run-all.mjs",
|
|
45
|
+
"test:host": "node tools/host-test.mjs",
|
|
46
|
+
"test:reduce": "node tools/reduce-test.mjs",
|
|
47
|
+
"test:client": "node tools/client-test.mjs",
|
|
48
|
+
"test:mount": "node tools/mount-test.mjs",
|
|
49
|
+
"test:render": "node tools/render-test.mjs",
|
|
50
|
+
"test:mermaid": "node tools/mermaid-check.mjs",
|
|
51
|
+
"test:integration": "node tools/integration-test.mjs"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@deepseek-ai/dsh": ">=0.2.0-rc.2 <0.3.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependenciesMeta": {
|
|
57
|
+
"@deepseek-ai/dsh": {
|
|
58
|
+
"optional": true
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"engines": { "node": ">=22" },
|
|
62
|
+
"dsh": {
|
|
63
|
+
"bundle": { "patch": "./cordis.patch.yml" },
|
|
64
|
+
"client": {
|
|
65
|
+
"platform": "web",
|
|
66
|
+
"inject": [
|
|
67
|
+
"@deepseek-ai/dsh-client-locale",
|
|
68
|
+
"@deepseek-ai/dsh-api-gateway",
|
|
69
|
+
"@deepseek-ai/dsh-client-connection",
|
|
70
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
71
|
+
"@deepseek-ai/dsh-client-ui-session",
|
|
72
|
+
"@deepseek-ai/dsh-client-ui-renderer",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
74
|
+
"@deepseek-ai/dsh-client-ui-primitives",
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-workspace"
|
|
77
|
+
],
|
|
78
|
+
"external": [
|
|
79
|
+
"@deepseek-ai/dsh-client-locale",
|
|
80
|
+
"@deepseek-ai/dsh-api-gateway",
|
|
81
|
+
"@deepseek-ai/dsh-client-connection",
|
|
82
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
83
|
+
"@deepseek-ai/dsh-client-ui-session",
|
|
84
|
+
"@deepseek-ai/dsh-client-ui-renderer",
|
|
85
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
86
|
+
"@deepseek-ai/dsh-client-ui-primitives",
|
|
87
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right",
|
|
88
|
+
"@deepseek-ai/dsh-client-ui-workspace"
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|