openmatrix 0.2.25 → 0.2.27
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/README.md +155 -595
- package/dist/agents/agent-runner.d.ts +5 -1
- package/dist/agents/agent-runner.js +53 -3
- package/dist/cli/commands/complete.js +13 -1
- package/dist/cli/commands/start.js +28 -14
- package/dist/cli/commands/status.js +13 -1
- package/dist/storage/file-store.d.ts +8 -0
- package/dist/storage/file-store.js +30 -0
- package/dist/storage/state-manager.d.ts +115 -0
- package/dist/storage/state-manager.js +269 -46
- package/package.json +1 -1
- package/skills/approve.md +1 -1
- package/skills/auto.md +39 -14
- package/skills/brainstorm.md +1 -5
- package/skills/check.md +1 -1
- package/skills/debug.md +692 -765
- package/skills/deploy.md +1 -1
- package/skills/feature.md +17 -14
- package/skills/meeting.md +1 -1
- package/skills/om.md +74 -8
- package/skills/openmatrix.md +5 -14
- package/skills/plan.md +54 -19
- package/skills/report.md +1 -1
- package/skills/research.md +16 -1
- package/skills/resume.md +3 -5
- package/skills/retry.md +1 -1
- package/skills/start.md +193 -54
- package/skills/status.md +1 -1
- package/skills/test.md +105 -8
|
@@ -72,9 +72,13 @@ export declare class AgentRunner {
|
|
|
72
72
|
*/
|
|
73
73
|
private buildAmbiguityDetectionInstruction;
|
|
74
74
|
/**
|
|
75
|
-
* 构建累积上下文 -
|
|
75
|
+
* 构建累积上下文 - 从当前运行的 context.md 读取前序 Agent 的决策和知识
|
|
76
76
|
*/
|
|
77
77
|
private buildAccumulatedContext;
|
|
78
|
+
/**
|
|
79
|
+
* 构建测试项目上下文 — 注入原始扫描数据供 AI 自行分析
|
|
80
|
+
*/
|
|
81
|
+
private buildTestContext;
|
|
78
82
|
/**
|
|
79
83
|
* 构建阶段上下文
|
|
80
84
|
*/
|
|
@@ -137,6 +137,9 @@ class AgentRunner {
|
|
|
137
137
|
const phaseContext = this.buildPhaseContext(task);
|
|
138
138
|
const accumulatedContext = await this.buildAccumulatedContext(task);
|
|
139
139
|
const ambiguityInstruction = this.buildAmbiguityDetectionInstruction(task);
|
|
140
|
+
const testContext = task.assignedAgent === 'tester' ? await this.buildTestContext() : '';
|
|
141
|
+
const state = await this.stateManager.getState();
|
|
142
|
+
const runId = state.runId;
|
|
140
143
|
return `# 任务执行
|
|
141
144
|
|
|
142
145
|
${ambiguityInstruction}
|
|
@@ -148,6 +151,15 @@ ${ambiguityInstruction}
|
|
|
148
151
|
- 优先级: ${task.priority}
|
|
149
152
|
- 超时: ${task.timeout / 1000} 秒
|
|
150
153
|
|
|
154
|
+
## 工作目录隔离
|
|
155
|
+
|
|
156
|
+
本次运行 ID: ${runId}
|
|
157
|
+
所有中间产物必须写入运行专属目录: \`.openmatrix/${runId}/tasks/${task.id}/artifacts/\`
|
|
158
|
+
- 中间产物: \`.openmatrix/${runId}/tasks/${task.id}/artifacts/\`
|
|
159
|
+
- 结果报告: \`.openmatrix/${runId}/tasks/${task.id}/artifacts/result.md\`
|
|
160
|
+
|
|
161
|
+
**注意**: 业务代码(src/、tests/ 等)写入项目正常目录,仅中间产物和报告写入运行目录。
|
|
162
|
+
|
|
151
163
|
## 当前阶段
|
|
152
164
|
${phaseContext}
|
|
153
165
|
|
|
@@ -157,6 +169,7 @@ ${task.dependencies.length > 0
|
|
|
157
169
|
: '无依赖'}
|
|
158
170
|
|
|
159
171
|
${accumulatedContext}
|
|
172
|
+
${testContext}
|
|
160
173
|
|
|
161
174
|
---
|
|
162
175
|
|
|
@@ -168,7 +181,7 @@ ${agentPrompt.instructions}
|
|
|
168
181
|
|
|
169
182
|
## 完成要求
|
|
170
183
|
|
|
171
|
-
1. 将执行结果写入: \`.openmatrix/tasks/${task.id}/artifacts/result.md\`
|
|
184
|
+
1. 将执行结果写入: \`.openmatrix/${runId}/tasks/${task.id}/artifacts/result.md\`
|
|
172
185
|
(任务状态由 openmatrix complete 命令管理,请勿直接修改 task.json)
|
|
173
186
|
2. 如需审批,创建审批请求: \`.openmatrix/approvals/\` 目录
|
|
174
187
|
|
|
@@ -260,11 +273,21 @@ ${agentPrompt.instructions}
|
|
|
260
273
|
**重要**: 如果无法解析歧义检测结果,视为无歧义继续执行。`;
|
|
261
274
|
}
|
|
262
275
|
/**
|
|
263
|
-
* 构建累积上下文 -
|
|
276
|
+
* 构建累积上下文 - 从当前运行的 context.md 读取前序 Agent 的决策和知识
|
|
264
277
|
*/
|
|
265
278
|
async buildAccumulatedContext(currentTask) {
|
|
266
279
|
const omPath = path.join(process.cwd(), '.openmatrix');
|
|
267
|
-
|
|
280
|
+
// 读取 current.json 获取当前 runId
|
|
281
|
+
let contextFile = path.join(omPath, 'context.md');
|
|
282
|
+
try {
|
|
283
|
+
const currentJson = await fs.readFile(path.join(omPath, 'current.json'), 'utf-8');
|
|
284
|
+
const { runId } = JSON.parse(currentJson);
|
|
285
|
+
if (runId)
|
|
286
|
+
contextFile = path.join(omPath, runId, 'context.md');
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
// fallback to root context.md
|
|
290
|
+
}
|
|
268
291
|
try {
|
|
269
292
|
const content = await fs.readFile(contextFile, 'utf-8');
|
|
270
293
|
const trimmed = content.trim();
|
|
@@ -277,6 +300,33 @@ ${agentPrompt.instructions}
|
|
|
277
300
|
你应该基于这些信息来工作,避免重复犯错或与已有决策冲突。
|
|
278
301
|
|
|
279
302
|
${trimmed}
|
|
303
|
+
`;
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
return '';
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* 构建测试项目上下文 — 注入原始扫描数据供 AI 自行分析
|
|
311
|
+
*/
|
|
312
|
+
async buildTestContext() {
|
|
313
|
+
try {
|
|
314
|
+
const { performFullScan } = await import('../test/context-analyzer.js');
|
|
315
|
+
const scanResult = performFullScan(process.cwd());
|
|
316
|
+
return `
|
|
317
|
+
## 项目测试扫描数据(原始数据,由 AI 自行分析决策)
|
|
318
|
+
|
|
319
|
+
\`\`\`json
|
|
320
|
+
${JSON.stringify({
|
|
321
|
+
frameworks: scanResult.frameworks,
|
|
322
|
+
testStyle: scanResult.testStyle,
|
|
323
|
+
existingTests: scanResult.existingTests.slice(0, 10),
|
|
324
|
+
projectType: scanResult.projectType,
|
|
325
|
+
isFrontend: scanResult.isFrontend,
|
|
326
|
+
hasUIComponents: scanResult.hasUIComponents,
|
|
327
|
+
summary: scanResult.summary
|
|
328
|
+
}, null, 2)}
|
|
329
|
+
\`\`\`
|
|
280
330
|
`;
|
|
281
331
|
}
|
|
282
332
|
catch {
|
|
@@ -106,7 +106,18 @@ exports.completeCommand = new commander_1.Command('complete')
|
|
|
106
106
|
});
|
|
107
107
|
// 5. 追加写入全局 context.md (Agent Memory)
|
|
108
108
|
if (isSuccess) {
|
|
109
|
-
|
|
109
|
+
// 读取 current.json 获取当前 runId,context.md 写入运行目录
|
|
110
|
+
let contextDir = omPath;
|
|
111
|
+
try {
|
|
112
|
+
const currentJson = await fs.readFile(path.join(omPath, 'current.json'), 'utf-8');
|
|
113
|
+
const { runId } = JSON.parse(currentJson);
|
|
114
|
+
if (runId)
|
|
115
|
+
contextDir = path.join(omPath, runId);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// fallback to omPath
|
|
119
|
+
}
|
|
120
|
+
const contextFile = path.join(contextDir, 'context.md');
|
|
110
121
|
const timestamp = new Date().toISOString();
|
|
111
122
|
// 构建上下文内容
|
|
112
123
|
const summary = options.summary || '任务已完成';
|
|
@@ -116,6 +127,7 @@ exports.completeCommand = new commander_1.Command('complete')
|
|
|
116
127
|
|
|
117
128
|
`;
|
|
118
129
|
try {
|
|
130
|
+
await fs.mkdir(contextDir, { recursive: true });
|
|
119
131
|
// 原子追加写入全局 context.md(O_APPEND flag 保证并发安全)
|
|
120
132
|
await fs.appendFile(contextFile, contextEntry, 'utf-8');
|
|
121
133
|
}
|
|
@@ -66,7 +66,6 @@ exports.startCommand = new commander_1.Command('start')
|
|
|
66
66
|
const omPath = path.join(basePath, '.openmatrix');
|
|
67
67
|
// 确保目录存在
|
|
68
68
|
await fs.mkdir(omPath, { recursive: true });
|
|
69
|
-
await fs.mkdir(path.join(omPath, 'tasks'), { recursive: true });
|
|
70
69
|
await fs.mkdir(path.join(omPath, 'approvals'), { recursive: true });
|
|
71
70
|
// 确保 .openmatrix 被 git 忽略
|
|
72
71
|
await (0, gitignore_js_1.ensureOpenmatrixGitignore)(basePath);
|
|
@@ -88,6 +87,10 @@ exports.startCommand = new commander_1.Command('start')
|
|
|
88
87
|
const stateManager = new state_manager_js_1.StateManager(omPath);
|
|
89
88
|
await stateManager.initialize();
|
|
90
89
|
const state = await stateManager.getState();
|
|
90
|
+
// 如果上次运行已结束(completed/failed),自动清理旧数据开始新运行
|
|
91
|
+
if (state.status === 'completed' || state.status === 'failed') {
|
|
92
|
+
await stateManager.reset();
|
|
93
|
+
}
|
|
91
94
|
// 检查是否已有运行中的任务
|
|
92
95
|
if (state.status === 'running') {
|
|
93
96
|
if (options.json) {
|
|
@@ -203,8 +206,23 @@ async function handleTasksJson(options, stateManager, state, omPath, basePath) {
|
|
|
203
206
|
if (jsonStr.startsWith('@')) {
|
|
204
207
|
const filePath = jsonStr.slice(1);
|
|
205
208
|
// 如果是相对路径,转换为绝对路径
|
|
206
|
-
|
|
207
|
-
|
|
209
|
+
let resolvedPath = path.isAbsolute(filePath) ? filePath : path.join(basePath, filePath);
|
|
210
|
+
// 特殊处理:如果文件名是 tasks-input.json 且不带路径,尝试从 runId 目录读取
|
|
211
|
+
if (filePath === 'tasks-input.json' || filePath.endsWith('/tasks-input.json')) {
|
|
212
|
+
// 先尝试从 runId 目录读取
|
|
213
|
+
const state = await stateManager.getState();
|
|
214
|
+
const runIdPath = path.join(omPath, state.runId, 'tasks-input.json');
|
|
215
|
+
try {
|
|
216
|
+
jsonStr = await fs.readFile(runIdPath, 'utf-8');
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
// 如果 runId 目录不存在,尝试原有路径
|
|
220
|
+
jsonStr = await fs.readFile(resolvedPath, 'utf-8');
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
jsonStr = await fs.readFile(resolvedPath, 'utf-8');
|
|
225
|
+
}
|
|
208
226
|
}
|
|
209
227
|
tasksInput = JSON.parse(jsonStr);
|
|
210
228
|
}
|
|
@@ -238,18 +256,14 @@ async function handleTasksJson(options, stateManager, state, omPath, basePath) {
|
|
|
238
256
|
console.log(`🔬 已加载研究领域: ${researchContext.domain}`);
|
|
239
257
|
}
|
|
240
258
|
}
|
|
241
|
-
//
|
|
259
|
+
// 读取独立的技术方案文档(从当前 runId 目录)
|
|
242
260
|
let planContent;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (!options.json) {
|
|
247
|
-
console.log(`📄 已加载技术方案: plan.md`);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
catch {
|
|
251
|
-
// plan.md 不存在时继续(可能由 AI 后续生成或无 plan)
|
|
261
|
+
planContent = await stateManager.getPlan();
|
|
262
|
+
if (planContent && !options.json) {
|
|
263
|
+
console.log(`📄 已加载技术方案: plan.md`);
|
|
252
264
|
}
|
|
265
|
+
// 转换为 string | undefined(供 TaskPlanner 使用)
|
|
266
|
+
const planContentForPlanner = planContent || undefined;
|
|
253
267
|
// 构建 ParsedTask
|
|
254
268
|
const parsedTask = {
|
|
255
269
|
title: resolvedInput.title || tasksInput.title,
|
|
@@ -282,7 +296,7 @@ async function handleTasksJson(options, stateManager, state, omPath, basePath) {
|
|
|
282
296
|
}
|
|
283
297
|
// 使用 TaskPlanner 拆分(保持原有拆分逻辑)
|
|
284
298
|
const planner = new task_planner_js_1.TaskPlanner();
|
|
285
|
-
const subTasks = planner.breakdown(parsedTask, extraAnswers, qualityConfig,
|
|
299
|
+
const subTasks = planner.breakdown(parsedTask, extraAnswers, qualityConfig, planContentForPlanner);
|
|
286
300
|
// 创建任务到状态管理器,并建立 ID 映射
|
|
287
301
|
// TaskPlanner 生成的 taskId 和 StateManager 创建的 id 不同,
|
|
288
302
|
// 需要映射后才能正确设置 dependencies
|
|
@@ -70,7 +70,19 @@ async function showStatus(manager, reporter, options) {
|
|
|
70
70
|
const state = await manager.getState();
|
|
71
71
|
const tasks = await manager.listTasks();
|
|
72
72
|
if (options.json) {
|
|
73
|
-
|
|
73
|
+
// 添加文件状态字段
|
|
74
|
+
const hasPlan = await manager.hasPlan();
|
|
75
|
+
const hasTasksInput = await manager.hasTasksInput();
|
|
76
|
+
const hasResearchContext = await manager.hasResearchContext();
|
|
77
|
+
console.log(JSON.stringify({
|
|
78
|
+
state,
|
|
79
|
+
tasks,
|
|
80
|
+
files: {
|
|
81
|
+
hasPlan,
|
|
82
|
+
hasTasksInput,
|
|
83
|
+
hasResearchContext
|
|
84
|
+
}
|
|
85
|
+
}, null, 2));
|
|
74
86
|
return;
|
|
75
87
|
}
|
|
76
88
|
// Header
|
|
@@ -22,6 +22,14 @@ export declare class FileStore {
|
|
|
22
22
|
exists(path: string): Promise<boolean>;
|
|
23
23
|
listFiles(dir: string): Promise<string[]>;
|
|
24
24
|
listDirs(dir: string): Promise<string[]>;
|
|
25
|
+
/**
|
|
26
|
+
* 递归删除目录
|
|
27
|
+
*/
|
|
28
|
+
removeDir(dir: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* 删除文件
|
|
31
|
+
*/
|
|
32
|
+
removeFile(filePath: string): Promise<void>;
|
|
25
33
|
/**
|
|
26
34
|
* 同步写入 JSON 文件
|
|
27
35
|
*/
|
|
@@ -108,6 +108,36 @@ class FileStore {
|
|
|
108
108
|
return [];
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* 递归删除目录
|
|
113
|
+
*/
|
|
114
|
+
async removeDir(dir) {
|
|
115
|
+
const fullPath = (0, path_1.join)(this.basePath, dir);
|
|
116
|
+
try {
|
|
117
|
+
await (0, promises_1.rm)(fullPath, { recursive: true, force: true });
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
const nodeError = error;
|
|
121
|
+
if (nodeError.code !== 'ENOENT') {
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* 删除文件
|
|
128
|
+
*/
|
|
129
|
+
async removeFile(filePath) {
|
|
130
|
+
const fullPath = (0, path_1.join)(this.basePath, filePath);
|
|
131
|
+
try {
|
|
132
|
+
await (0, promises_1.unlink)(fullPath);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
const nodeError = error;
|
|
136
|
+
if (nodeError.code !== 'ENOENT') {
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
111
141
|
// ============ 同步方法(用于构造器等场景)============
|
|
112
142
|
/**
|
|
113
143
|
* 同步写入 JSON 文件
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { GlobalState, Task, Approval, ApprovalStatus, Meeting, MeetingStatus } from '../types/index.js';
|
|
2
2
|
export declare class StateManager {
|
|
3
|
+
private rootStore;
|
|
3
4
|
private store;
|
|
5
|
+
private basePath;
|
|
4
6
|
private stateCache;
|
|
5
7
|
private lockDepth;
|
|
6
8
|
constructor(basePath: string);
|
|
@@ -18,6 +20,11 @@ export declare class StateManager {
|
|
|
18
20
|
*/
|
|
19
21
|
private tryCleanStaleLock;
|
|
20
22
|
initialize(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* 重置状态 — 清理旧运行数据,为新运行做准备
|
|
25
|
+
* 删除旧 runId 目录,生成新 runId,更新 current.json
|
|
26
|
+
*/
|
|
27
|
+
reset(): Promise<void>;
|
|
21
28
|
getState(): Promise<GlobalState>;
|
|
22
29
|
updateState(updates: Partial<GlobalState>): Promise<void>;
|
|
23
30
|
createTask(input: {
|
|
@@ -55,6 +62,114 @@ export declare class StateManager {
|
|
|
55
62
|
updateApproval(approval: Approval): Promise<void>;
|
|
56
63
|
getApprovalsByStatus(status: ApprovalStatus): Promise<Approval[]>;
|
|
57
64
|
getAllApprovals(): Promise<Approval[]>;
|
|
65
|
+
/**
|
|
66
|
+
* 保存技术方案文档 (plan.md)
|
|
67
|
+
* 路径: .openmatrix/{runId}/plan.md
|
|
68
|
+
*/
|
|
69
|
+
savePlan(content: string): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* 读取技术方案文档
|
|
72
|
+
* @returns plan.md 内容,不存在返回 null
|
|
73
|
+
*/
|
|
74
|
+
getPlan(): Promise<string | null>;
|
|
75
|
+
/**
|
|
76
|
+
* 检查 plan.md 是否存在
|
|
77
|
+
*/
|
|
78
|
+
hasPlan(): Promise<boolean>;
|
|
79
|
+
/**
|
|
80
|
+
* 保存任务输入元数据
|
|
81
|
+
* 路径: .openmatrix/{runId}/tasks-input.json
|
|
82
|
+
*/
|
|
83
|
+
saveTasksInput(data: {
|
|
84
|
+
title: string;
|
|
85
|
+
description?: string;
|
|
86
|
+
goals: string[];
|
|
87
|
+
goalTypes?: string[];
|
|
88
|
+
goalComplexity?: ('low' | 'medium' | 'high')[];
|
|
89
|
+
constraints?: string[];
|
|
90
|
+
deliverables?: string[];
|
|
91
|
+
answers?: Record<string, string>;
|
|
92
|
+
}): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* 读取任务输入元数据
|
|
95
|
+
* @returns tasks-input.json 数据,不存在返回 null
|
|
96
|
+
*/
|
|
97
|
+
getTasksInput(): Promise<{
|
|
98
|
+
title: string;
|
|
99
|
+
description?: string;
|
|
100
|
+
goals: string[];
|
|
101
|
+
goalTypes?: string[];
|
|
102
|
+
goalComplexity?: ('low' | 'medium' | 'high')[];
|
|
103
|
+
constraints?: string[];
|
|
104
|
+
deliverables?: string[];
|
|
105
|
+
answers?: Record<string, string>;
|
|
106
|
+
} | null>;
|
|
107
|
+
/**
|
|
108
|
+
* 检查 tasks-input.json 是否存在
|
|
109
|
+
*/
|
|
110
|
+
hasTasksInput(): Promise<boolean>;
|
|
111
|
+
/**
|
|
112
|
+
* 保存研究会话
|
|
113
|
+
* 路径: .openmatrix/{runId}/research/session.json
|
|
114
|
+
*/
|
|
115
|
+
saveResearchSession(session: Record<string, unknown>): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* 读取研究会话
|
|
118
|
+
*/
|
|
119
|
+
getResearchSession(): Promise<Record<string, unknown> | null>;
|
|
120
|
+
/**
|
|
121
|
+
* 保存研究报告
|
|
122
|
+
*/
|
|
123
|
+
saveResearchReport(content: string): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* 读取研究报告
|
|
126
|
+
*/
|
|
127
|
+
getResearchReport(): Promise<string | null>;
|
|
128
|
+
/**
|
|
129
|
+
* 保存研究上下文 (供 start 使用)
|
|
130
|
+
*/
|
|
131
|
+
saveResearchContext(context: {
|
|
132
|
+
topic: string;
|
|
133
|
+
domain: string;
|
|
134
|
+
goals?: string[];
|
|
135
|
+
constraints?: string[];
|
|
136
|
+
deliverables?: string[];
|
|
137
|
+
reportPath?: string;
|
|
138
|
+
knowledgePath?: string;
|
|
139
|
+
}): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* 读取研究上下文
|
|
142
|
+
*/
|
|
143
|
+
getResearchContext(): Promise<{
|
|
144
|
+
topic: string;
|
|
145
|
+
domain: string;
|
|
146
|
+
goals?: string[];
|
|
147
|
+
constraints?: string[];
|
|
148
|
+
deliverables?: string[];
|
|
149
|
+
reportPath?: string;
|
|
150
|
+
knowledgePath?: string;
|
|
151
|
+
} | null>;
|
|
152
|
+
/**
|
|
153
|
+
* 检查研究上下文是否存在
|
|
154
|
+
*/
|
|
155
|
+
hasResearchContext(): Promise<boolean>;
|
|
156
|
+
/**
|
|
157
|
+
* 保存知识条目
|
|
158
|
+
*/
|
|
159
|
+
saveKnowledgeFinding(index: number, content: string): Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* 保存头脑风暴会话
|
|
162
|
+
*/
|
|
163
|
+
saveBrainstormSession(session: Record<string, unknown>): Promise<void>;
|
|
164
|
+
/**
|
|
165
|
+
* 读取头脑风暴会话
|
|
166
|
+
*/
|
|
167
|
+
getBrainstormSession(): Promise<Record<string, unknown> | null>;
|
|
168
|
+
/**
|
|
169
|
+
* 迁移旧版本文件到 runId 目录
|
|
170
|
+
* 只在首次检测到旧文件时执行
|
|
171
|
+
*/
|
|
172
|
+
migrateFromLegacy(): Promise<void>;
|
|
58
173
|
saveMeeting(meeting: Meeting): Promise<void>;
|
|
59
174
|
getMeeting(meetingId: string): Promise<Meeting | null>;
|
|
60
175
|
getMeetingsByStatus(status: MeetingStatus): Promise<Meeting[]>;
|