openmatrix 0.2.24 → 0.2.26
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 +20 -16
- package/dist/orchestrator/task-planner.d.ts +5 -104
- package/dist/orchestrator/task-planner.js +99 -799
- package/dist/storage/file-store.d.ts +8 -0
- package/dist/storage/file-store.js +30 -0
- package/dist/storage/state-manager.d.ts +7 -0
- package/dist/storage/state-manager.js +101 -46
- package/dist/test/generator.js +39 -11
- package/dist/types/index.d.ts +3 -1
- package/package.json +61 -61
- package/skills/auto.md +383 -415
- package/skills/brainstorm.md +27 -29
- package/skills/om.md +3 -3
- package/skills/plan.md +261 -0
- package/skills/start.md +621 -707
|
@@ -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: {
|
|
@@ -13,11 +13,16 @@ const DEFAULT_CONFIG = {
|
|
|
13
13
|
model: 'claude-sonnet-4-6'
|
|
14
14
|
};
|
|
15
15
|
class StateManager {
|
|
16
|
+
rootStore;
|
|
16
17
|
store;
|
|
18
|
+
basePath;
|
|
17
19
|
stateCache = null;
|
|
18
|
-
lockDepth = 0;
|
|
20
|
+
lockDepth = 0;
|
|
19
21
|
constructor(basePath) {
|
|
20
|
-
this.
|
|
22
|
+
this.basePath = basePath;
|
|
23
|
+
this.rootStore = new file_store_js_1.FileStore(basePath);
|
|
24
|
+
// store will be set in initialize() or reset() to point to {basePath}/{runId}/
|
|
25
|
+
this.store = this.rootStore;
|
|
21
26
|
}
|
|
22
27
|
/**
|
|
23
28
|
* 跨进程文件锁 — 防止多个 openmatrix CLI 进程同时读写 state.json
|
|
@@ -84,49 +89,101 @@ class StateManager {
|
|
|
84
89
|
}
|
|
85
90
|
}
|
|
86
91
|
async initialize() {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
await this.store.writeJson('state.json', initialState);
|
|
111
|
-
this.stateCache = initialState;
|
|
92
|
+
// 读取根索引,确定当前 runId
|
|
93
|
+
const current = await this.rootStore.readJson('current.json');
|
|
94
|
+
if (current?.runId) {
|
|
95
|
+
// 切换 store 到当前运行目录
|
|
96
|
+
this.store = new file_store_js_1.FileStore((0, path_1.join)(this.basePath, current.runId));
|
|
97
|
+
const existing = await this.store.readJson('state.json');
|
|
98
|
+
if (existing) {
|
|
99
|
+
existing.statistics = {
|
|
100
|
+
totalTasks: existing.statistics?.totalTasks ?? 0,
|
|
101
|
+
completed: existing.statistics?.completed ?? 0,
|
|
102
|
+
inProgress: existing.statistics?.inProgress ?? 0,
|
|
103
|
+
failed: existing.statistics?.failed ?? 0,
|
|
104
|
+
pending: existing.statistics?.pending ?? 0,
|
|
105
|
+
scheduled: existing.statistics?.scheduled ?? 0,
|
|
106
|
+
blocked: existing.statistics?.blocked ?? 0,
|
|
107
|
+
waiting: existing.statistics?.waiting ?? 0,
|
|
108
|
+
verify: existing.statistics?.verify ?? 0,
|
|
109
|
+
accept: existing.statistics?.accept ?? 0,
|
|
110
|
+
retry_queue: existing.statistics?.retry_queue ?? 0
|
|
111
|
+
};
|
|
112
|
+
this.stateCache = existing;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
112
115
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
116
|
+
// 没有 current.json 或 state.json 不存在 — 创建新运行
|
|
117
|
+
const runId = this.generateRunId();
|
|
118
|
+
this.store = new file_store_js_1.FileStore((0, path_1.join)(this.basePath, runId));
|
|
119
|
+
await this.rootStore.writeJson('current.json', { runId });
|
|
120
|
+
const initialState = {
|
|
121
|
+
version: '1.0',
|
|
122
|
+
runId,
|
|
123
|
+
status: 'initialized',
|
|
124
|
+
currentPhase: 'planning',
|
|
125
|
+
startedAt: new Date().toISOString(),
|
|
126
|
+
config: DEFAULT_CONFIG,
|
|
127
|
+
statistics: {
|
|
128
|
+
totalTasks: 0,
|
|
129
|
+
completed: 0,
|
|
130
|
+
inProgress: 0,
|
|
131
|
+
failed: 0,
|
|
132
|
+
pending: 0,
|
|
133
|
+
scheduled: 0,
|
|
134
|
+
blocked: 0,
|
|
135
|
+
waiting: 0,
|
|
136
|
+
verify: 0,
|
|
137
|
+
accept: 0,
|
|
138
|
+
retry_queue: 0
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
await this.store.writeJson('state.json', initialState);
|
|
142
|
+
this.stateCache = initialState;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* 重置状态 — 清理旧运行数据,为新运行做准备
|
|
146
|
+
* 删除旧 runId 目录,生成新 runId,更新 current.json
|
|
147
|
+
*/
|
|
148
|
+
async reset() {
|
|
149
|
+
// 清理旧 runId 目录
|
|
150
|
+
const oldRunId = this.stateCache?.runId;
|
|
151
|
+
if (oldRunId) {
|
|
152
|
+
await this.rootStore.removeDir(oldRunId);
|
|
129
153
|
}
|
|
154
|
+
// 兼容旧版本的目录
|
|
155
|
+
await this.rootStore.removeDir('tasks');
|
|
156
|
+
await this.rootStore.removeDir('approvals');
|
|
157
|
+
await this.rootStore.removeDir('meetings');
|
|
158
|
+
await this.rootStore.removeDir('runs');
|
|
159
|
+
await this.rootStore.removeFile('context.md');
|
|
160
|
+
// 创建新运行
|
|
161
|
+
const runId = this.generateRunId();
|
|
162
|
+
this.store = new file_store_js_1.FileStore((0, path_1.join)(this.basePath, runId));
|
|
163
|
+
await this.rootStore.writeJson('current.json', { runId });
|
|
164
|
+
const freshState = {
|
|
165
|
+
version: '1.0',
|
|
166
|
+
runId,
|
|
167
|
+
status: 'initialized',
|
|
168
|
+
currentPhase: 'planning',
|
|
169
|
+
startedAt: new Date().toISOString(),
|
|
170
|
+
config: DEFAULT_CONFIG,
|
|
171
|
+
statistics: {
|
|
172
|
+
totalTasks: 0,
|
|
173
|
+
completed: 0,
|
|
174
|
+
inProgress: 0,
|
|
175
|
+
failed: 0,
|
|
176
|
+
pending: 0,
|
|
177
|
+
scheduled: 0,
|
|
178
|
+
blocked: 0,
|
|
179
|
+
waiting: 0,
|
|
180
|
+
verify: 0,
|
|
181
|
+
accept: 0,
|
|
182
|
+
retry_queue: 0
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
await this.store.writeJson('state.json', freshState);
|
|
186
|
+
this.stateCache = freshState;
|
|
130
187
|
}
|
|
131
188
|
async getState() {
|
|
132
189
|
if (!this.stateCache) {
|
|
@@ -207,7 +264,6 @@ class StateManager {
|
|
|
207
264
|
});
|
|
208
265
|
}
|
|
209
266
|
async getTask(taskId) {
|
|
210
|
-
// Try subdirectory structure first, fall back to flat file
|
|
211
267
|
let task = await this.store.readJson(`tasks/${taskId}/task.json`);
|
|
212
268
|
if (!task) {
|
|
213
269
|
task = await this.store.readJson(`tasks/${taskId}.json`);
|
|
@@ -225,7 +281,7 @@ class StateManager {
|
|
|
225
281
|
...updates,
|
|
226
282
|
updatedAt: new Date().toISOString()
|
|
227
283
|
};
|
|
228
|
-
// Always write to
|
|
284
|
+
// Always write to current run directory
|
|
229
285
|
await this.store.writeJson(`tasks/${taskId}/task.json`, updatedTask);
|
|
230
286
|
// Update statistics if status changed
|
|
231
287
|
if (updates.status && updates.status !== oldStatus) {
|
|
@@ -249,7 +305,6 @@ class StateManager {
|
|
|
249
305
|
continue;
|
|
250
306
|
const task = await this.store.readJson(`tasks/${file}`);
|
|
251
307
|
if (task) {
|
|
252
|
-
// Avoid duplicate if already found in subdirectory
|
|
253
308
|
if (!tasks.some(t => t.id === task.id)) {
|
|
254
309
|
tasks.push(task);
|
|
255
310
|
}
|
package/dist/test/generator.js
CHANGED
|
@@ -143,10 +143,25 @@ function generateTestContent(source, config) {
|
|
|
143
143
|
// 导入语句
|
|
144
144
|
const importPath = source.path.replace(/\.(ts|tsx)$/, '').replace(/\.(js|jsx)$/, '');
|
|
145
145
|
const imports = generateImports(source.exports, importPath, usesTypeScript);
|
|
146
|
+
// 需要生命周期钩子的文件类型
|
|
147
|
+
const needsLifecycle = ['service', 'util', 'api', 'module'].includes(source.fileType);
|
|
148
|
+
// 需要 vi 导入的测试类型(使用 Mock 验证副作用)
|
|
149
|
+
const needsViImport = ['service', 'util', 'api', 'component', 'module'].includes(source.fileType);
|
|
146
150
|
// 测试块
|
|
147
151
|
const testBlocks = source.exports.map(exp => generateTestBlock(exp, framework, usesDescribeIt, source.fileType));
|
|
148
152
|
// 组装内容
|
|
149
|
-
const content = `${
|
|
153
|
+
const content = `${needsViImport ? `import { vi } from 'vitest';\n` : ''}${imports}
|
|
154
|
+
${needsLifecycle ? `
|
|
155
|
+
beforeEach(() => {
|
|
156
|
+
vi.clearAllMocks();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
afterEach(() => {
|
|
160
|
+
vi.restoreAllMocks();
|
|
161
|
+
});
|
|
162
|
+
` : ''}
|
|
163
|
+
${testBlocks.join('\n\n')}
|
|
164
|
+
`;
|
|
150
165
|
return content;
|
|
151
166
|
}
|
|
152
167
|
/**
|
|
@@ -193,13 +208,15 @@ function generateBusinessTestCases(exportName, fileType) {
|
|
|
193
208
|
name: 'should return valid result on successful execution',
|
|
194
209
|
arrange: `// Arrange - 准备有效的输入参数
|
|
195
210
|
const params = { id: 'test-id', data: {} };
|
|
196
|
-
const
|
|
211
|
+
const spy = vi.spyOn({ ${exportName} }, '${exportName}');`,
|
|
197
212
|
act: `// Act - 执行服务方法
|
|
198
213
|
const result = await ${exportName}(params);`,
|
|
199
214
|
assert: [
|
|
200
215
|
'expect(result).toBeDefined();',
|
|
201
216
|
'expect(result).toHaveProperty(\'data\');',
|
|
202
|
-
'expect(result.error).toBeUndefined();'
|
|
217
|
+
'expect(result.error).toBeUndefined();',
|
|
218
|
+
`expect(spy).toHaveBeenCalledWith(params);`,
|
|
219
|
+
'expect(spy).toHaveBeenCalledTimes(1);'
|
|
203
220
|
]
|
|
204
221
|
},
|
|
205
222
|
{
|
|
@@ -239,12 +256,15 @@ function generateBusinessTestCases(exportName, fileType) {
|
|
|
239
256
|
name: 'should process valid input correctly',
|
|
240
257
|
arrange: `// Arrange - 准备有效输入
|
|
241
258
|
const input = 'test-value';
|
|
242
|
-
const expected = 'expected-result'
|
|
259
|
+
const expected = 'expected-result';
|
|
260
|
+
const spy = vi.spyOn({ ${exportName} }, '${exportName}');`,
|
|
243
261
|
act: `// Act
|
|
244
262
|
const result = ${exportName}(input);`,
|
|
245
263
|
assert: [
|
|
246
264
|
'expect(result).toBeDefined();',
|
|
247
|
-
'expect(typeof result).toBe(\'string\');'
|
|
265
|
+
'expect(typeof result).toBe(\'string\');',
|
|
266
|
+
`expect(spy).toHaveBeenCalledWith(input);`,
|
|
267
|
+
'expect(spy).toHaveBeenCalledTimes(1);'
|
|
248
268
|
]
|
|
249
269
|
},
|
|
250
270
|
{
|
|
@@ -333,19 +353,25 @@ function generateBusinessTestCases(exportName, fileType) {
|
|
|
333
353
|
{
|
|
334
354
|
name: 'should return success response for valid request',
|
|
335
355
|
arrange: `// Arrange - 准备有效的 API 请求参数
|
|
336
|
-
const request = { method: \'GET\', path: \'/api/test\' }
|
|
356
|
+
const request = { method: \'GET\', path: \'/api/test\' };
|
|
357
|
+
const mockResponse = { status: 200, data: { id: 1 } };
|
|
358
|
+
const spy = vi.spyOn({ ${exportName} }, '${exportName}').mockResolvedValue(mockResponse);`,
|
|
337
359
|
act: `// Act - 执行 API 调用
|
|
338
360
|
const response = await ${exportName}(request);`,
|
|
339
361
|
assert: [
|
|
340
362
|
'expect(response).toBeDefined();',
|
|
341
363
|
'expect(response.status).toBe(200);',
|
|
342
|
-
'expect(response.data).toBeDefined();'
|
|
364
|
+
'expect(response.data).toBeDefined();',
|
|
365
|
+
`expect(spy).toHaveBeenCalledWith(request);`,
|
|
366
|
+
'expect(spy).toHaveBeenCalledTimes(1);'
|
|
343
367
|
]
|
|
344
368
|
},
|
|
345
369
|
{
|
|
346
370
|
name: 'should handle 404 not found',
|
|
347
371
|
arrange: `// Arrange - 准备不存在的资源请求
|
|
348
|
-
const request = { method: \'GET\', path: \'/api/nonexistent\' }
|
|
372
|
+
const request = { method: \'GET\', path: \'/api/nonexistent\' };
|
|
373
|
+
const mockResponse = { status: 404, error: \'Not Found\' };
|
|
374
|
+
vi.spyOn({ ${exportName} }, '${exportName}').mockResolvedValue(mockResponse);`,
|
|
349
375
|
act: `// Act - 请求不存在的资源
|
|
350
376
|
const response = await ${exportName}(request);`,
|
|
351
377
|
assert: [
|
|
@@ -356,7 +382,9 @@ function generateBusinessTestCases(exportName, fileType) {
|
|
|
356
382
|
{
|
|
357
383
|
name: 'should handle invalid request body',
|
|
358
384
|
arrange: `// Arrange - 准备无效的请求体
|
|
359
|
-
const request = { method: \'POST\', path: \'/api/test\', body: null }
|
|
385
|
+
const request = { method: \'POST\', path: \'/api/test\', body: null };
|
|
386
|
+
const mockResponse = { status: 400, error: \'invalid request\' };
|
|
387
|
+
vi.spyOn({ ${exportName} }, '${exportName}').mockResolvedValue(mockResponse);`,
|
|
360
388
|
act: `// Act - 发送无效请求
|
|
361
389
|
const response = await ${exportName}(request);`,
|
|
362
390
|
assert: [
|
|
@@ -368,10 +396,10 @@ function generateBusinessTestCases(exportName, fileType) {
|
|
|
368
396
|
name: 'should handle network errors gracefully',
|
|
369
397
|
arrange: `// Arrange - 模拟网络错误
|
|
370
398
|
const request = { method: \'GET\', path: \'/api/error\' };
|
|
371
|
-
|
|
399
|
+
vi.spyOn({ ${exportName} }, '${exportName}').mockRejectedValue(new Error('Network Error'));`,
|
|
372
400
|
act: `// Act - 处理错误响应`,
|
|
373
401
|
assert: [
|
|
374
|
-
`await expect(${exportName}(request)).
|
|
402
|
+
`await expect(${exportName}(request)).rejects.toThrow('Network Error');`,
|
|
375
403
|
'// 应该返回错误对象而非抛出异常'
|
|
376
404
|
]
|
|
377
405
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -228,8 +228,10 @@ export interface ParsedTask {
|
|
|
228
228
|
title: string;
|
|
229
229
|
description: string;
|
|
230
230
|
goals: string[];
|
|
231
|
-
/** 每个 goal 的类型标注 (
|
|
231
|
+
/** 每个 goal 的类型标注 (AI 必填),与 goals 数组一一对应 */
|
|
232
232
|
goalTypes?: GoalType[];
|
|
233
|
+
/** 每个 goal 的复杂度标注 (AI 必填),与 goals 数组一一对应 */
|
|
234
|
+
goalComplexity?: ('low' | 'medium' | 'high')[];
|
|
233
235
|
constraints: string[];
|
|
234
236
|
deliverables: string[];
|
|
235
237
|
rawContent: string;
|
package/package.json
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "openmatrix",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "AI Agent task orchestration system with Claude Code Skills integration",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"bin": {
|
|
8
|
-
"openmatrix": "dist/cli/index.js"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"dist",
|
|
12
|
-
"skills",
|
|
13
|
-
"scripts",
|
|
14
|
-
"README.md"
|
|
15
|
-
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"build": "tsc",
|
|
18
|
-
"dev": "tsx src/cli/index.ts",
|
|
19
|
-
"test": "vitest",
|
|
20
|
-
"lint": "eslint src --ext .ts",
|
|
21
|
-
"typecheck": "tsc --noEmit",
|
|
22
|
-
"postinstall": "node scripts/install-skills.js"
|
|
23
|
-
},
|
|
24
|
-
"keywords": [
|
|
25
|
-
"claude",
|
|
26
|
-
"claude-code",
|
|
27
|
-
"ai-agent",
|
|
28
|
-
"task-orchestration",
|
|
29
|
-
"automation",
|
|
30
|
-
"multi-agent"
|
|
31
|
-
],
|
|
32
|
-
"author": "",
|
|
33
|
-
"license": "MIT",
|
|
34
|
-
"type": "commonjs",
|
|
35
|
-
"repository": {
|
|
36
|
-
"type": "git",
|
|
37
|
-
"url": "git+https://github.com/bigfish1913/openmatrix.git"
|
|
38
|
-
},
|
|
39
|
-
"homepage": "https://github.com/bigfish1913/openmatrix#readme",
|
|
40
|
-
"bugs": {
|
|
41
|
-
"url": "https://github.com/bigfish1913/openmatrix/issues"
|
|
42
|
-
},
|
|
43
|
-
"dependencies": {
|
|
44
|
-
"chalk": "^5.6.2",
|
|
45
|
-
"chokidar": "^5.0.0",
|
|
46
|
-
"commander": "^14.0.3",
|
|
47
|
-
"winston": "^3.19.0"
|
|
48
|
-
},
|
|
49
|
-
"devDependencies": {
|
|
50
|
-
"@types/node": "^22.0.0",
|
|
51
|
-
"@typescript-eslint/eslint-plugin": "^8.58.1",
|
|
52
|
-
"@typescript-eslint/parser": "^8.58.1",
|
|
53
|
-
"@vitest/coverage-v8": "^1.6.1",
|
|
54
|
-
"eslint": "^10.2.0",
|
|
55
|
-
"typescript": "^5.3.3",
|
|
56
|
-
"vitest": "^1.6.0"
|
|
57
|
-
},
|
|
58
|
-
"engines": {
|
|
59
|
-
"node": ">=18.0.0"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "openmatrix",
|
|
3
|
+
"version": "0.2.26",
|
|
4
|
+
"description": "AI Agent task orchestration system with Claude Code Skills integration",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"openmatrix": "dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"skills",
|
|
13
|
+
"scripts",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"dev": "tsx src/cli/index.ts",
|
|
19
|
+
"test": "vitest",
|
|
20
|
+
"lint": "eslint src --ext .ts",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"postinstall": "node scripts/install-skills.js"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"claude",
|
|
26
|
+
"claude-code",
|
|
27
|
+
"ai-agent",
|
|
28
|
+
"task-orchestration",
|
|
29
|
+
"automation",
|
|
30
|
+
"multi-agent"
|
|
31
|
+
],
|
|
32
|
+
"author": "",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"type": "commonjs",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/bigfish1913/openmatrix.git"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/bigfish1913/openmatrix#readme",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/bigfish1913/openmatrix/issues"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"chalk": "^5.6.2",
|
|
45
|
+
"chokidar": "^5.0.0",
|
|
46
|
+
"commander": "^14.0.3",
|
|
47
|
+
"winston": "^3.19.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^22.0.0",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^8.58.1",
|
|
52
|
+
"@typescript-eslint/parser": "^8.58.1",
|
|
53
|
+
"@vitest/coverage-v8": "^1.6.1",
|
|
54
|
+
"eslint": "^10.2.0",
|
|
55
|
+
"typescript": "^5.3.3",
|
|
56
|
+
"vitest": "^1.6.0"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18.0.0"
|
|
60
|
+
}
|
|
61
|
+
}
|