openmatrix 0.2.3 → 0.2.4

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.
@@ -37,9 +37,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.logger = void 0;
40
+ exports.persistLog = persistLog;
40
41
  exports.createLogger = createLogger;
41
42
  exports.getLogger = getLogger;
42
43
  exports.setLogger = setLogger;
44
+ exports.initLoggerWithRunId = initLoggerWithRunId;
43
45
  // src/utils/logger.ts
44
46
  const winston_1 = __importDefault(require("winston"));
45
47
  const path = __importStar(require("path"));
@@ -54,11 +56,28 @@ const fs = __importStar(require("fs"));
54
56
  * 4. 结构化 JSON 日志
55
57
  */
56
58
  let defaultLogger = null;
59
+ /**
60
+ * 持久化日志到文件(追加模式)
61
+ * 用于关键操作的审计追踪
62
+ */
63
+ function persistLog(log, omPath) {
64
+ try {
65
+ const logsDir = path.join(omPath, 'logs');
66
+ if (!fs.existsSync(logsDir)) {
67
+ fs.mkdirSync(logsDir, { recursive: true });
68
+ }
69
+ const logFile = path.join(logsDir, `${log.runId || 'default'}.log`);
70
+ fs.appendFileSync(logFile, JSON.stringify(log) + '\n', 'utf-8');
71
+ }
72
+ catch {
73
+ // 持久化失败不应影响主流程
74
+ }
75
+ }
57
76
  /**
58
77
  * 创建或获取默认 Logger
59
78
  */
60
79
  function createLogger(options = {}) {
61
- const { level = process.env.OPENMATRIX_LOG_LEVEL || 'info', logDir = '.openmatrix/logs', console: enableConsole = true } = options;
80
+ const { level = process.env.OPENMATRIX_LOG_LEVEL || 'info', logDir = '.openmatrix/logs', console: enableConsole = true, runId } = options;
62
81
  // 确保日志目录存在
63
82
  const absoluteLogDir = path.resolve(process.cwd(), logDir);
64
83
  if (!fs.existsSync(absoluteLogDir)) {
@@ -102,7 +121,7 @@ function createLogger(options = {}) {
102
121
  // 创建 logger
103
122
  const logger = winston_1.default.createLogger({
104
123
  level,
105
- defaultMeta: { service: 'openmatrix' },
124
+ defaultMeta: { service: 'openmatrix', runId },
106
125
  transports
107
126
  });
108
127
  return logger;
@@ -122,6 +141,22 @@ function getLogger() {
122
141
  function setLogger(logger) {
123
142
  defaultLogger = logger;
124
143
  }
144
+ /**
145
+ * 使用 runId 初始化 logger
146
+ */
147
+ function initLoggerWithRunId(runId, omPath) {
148
+ defaultLogger = createLogger({ runId });
149
+ if (omPath) {
150
+ // 记录初始化日志
151
+ persistLog({
152
+ level: 'info',
153
+ runId,
154
+ operation: 'init',
155
+ message: 'Logger initialized',
156
+ timestamp: new Date().toISOString()
157
+ }, omPath);
158
+ }
159
+ }
125
160
  /**
126
161
  * 便捷方法: 直接记录日志
127
162
  */
@@ -130,6 +165,45 @@ exports.logger = {
130
165
  error: (message, meta) => getLogger().error(message, meta),
131
166
  warn: (message, meta) => getLogger().warn(message, meta),
132
167
  debug: (message, meta) => getLogger().debug(message, meta),
168
+ // 结构化日志(带持久化)
169
+ structured: {
170
+ info: (operation, message, meta, omPath) => {
171
+ const log = {
172
+ level: 'info',
173
+ operation,
174
+ message,
175
+ metadata: meta,
176
+ timestamp: new Date().toISOString()
177
+ };
178
+ getLogger().info(message, { operation, ...meta });
179
+ if (omPath)
180
+ persistLog(log, omPath);
181
+ },
182
+ error: (operation, message, meta, omPath) => {
183
+ const log = {
184
+ level: 'error',
185
+ operation,
186
+ message,
187
+ metadata: meta,
188
+ timestamp: new Date().toISOString()
189
+ };
190
+ getLogger().error(message, { operation, ...meta });
191
+ if (omPath)
192
+ persistLog(log, omPath);
193
+ },
194
+ warn: (operation, message, meta, omPath) => {
195
+ const log = {
196
+ level: 'warn',
197
+ operation,
198
+ message,
199
+ metadata: meta,
200
+ timestamp: new Date().toISOString()
201
+ };
202
+ getLogger().warn(message, { operation, ...meta });
203
+ if (omPath)
204
+ persistLog(log, omPath);
205
+ }
206
+ },
133
207
  // 任务相关日志
134
208
  task: {
135
209
  start: (taskId, title) => {
@@ -143,6 +217,19 @@ exports.logger = {
143
217
  },
144
218
  retry: (taskId, attempt) => {
145
219
  getLogger().warn(`Task retry: ${taskId}`, { taskId, attempt });
220
+ },
221
+ timeout: (taskId, timeout, phase, omPath) => {
222
+ const log = {
223
+ level: 'error',
224
+ taskId,
225
+ operation: 'taskTimeout',
226
+ message: `Task timed out after ${timeout}s`,
227
+ metadata: { timeout, phase },
228
+ timestamp: new Date().toISOString()
229
+ };
230
+ getLogger().error(`Task timed out: ${taskId}`, { taskId, timeout, phase });
231
+ if (omPath)
232
+ persistLog(log, omPath);
146
233
  }
147
234
  },
148
235
  // Agent 相关日志
@@ -162,5 +249,26 @@ exports.logger = {
162
249
  decision: (approvalId, decision) => {
163
250
  getLogger().info(`Approval decision: ${approvalId}`, { approvalId, decision });
164
251
  }
252
+ },
253
+ // 任务编排日志
254
+ orchestration: {
255
+ breakdown: (moduleCount, moduleNames, omPath) => {
256
+ const log = {
257
+ level: 'info',
258
+ operation: 'breakdown',
259
+ message: `Parsed ${moduleCount} modules from plan`,
260
+ metadata: { moduleNames },
261
+ timestamp: new Date().toISOString()
262
+ };
263
+ getLogger().info(`Breakdown: ${moduleCount} modules`, { moduleNames });
264
+ if (omPath)
265
+ persistLog(log, omPath);
266
+ },
267
+ schedule: (taskId, dependencies) => {
268
+ getLogger().info(`Task scheduled: ${taskId}`, { taskId, dependencies });
269
+ },
270
+ dependencyResolved: (taskId) => {
271
+ getLogger().debug(`Dependencies resolved: ${taskId}`, { taskId });
272
+ }
165
273
  }
166
274
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmatrix",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "AI Agent task orchestration system with Claude Code Skills integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,6 +17,8 @@
17
17
  "build": "tsc",
18
18
  "dev": "tsx src/cli/index.ts",
19
19
  "test": "vitest",
20
+ "lint": "eslint src --ext .ts",
21
+ "typecheck": "tsc --noEmit",
20
22
  "postinstall": "node scripts/install-skills.js"
21
23
  },
22
24
  "keywords": [
@@ -47,6 +49,9 @@
47
49
  "winston": "^3.19.0"
48
50
  },
49
51
  "devDependencies": {
52
+ "@typescript-eslint/eslint-plugin": "^8.58.1",
53
+ "@typescript-eslint/parser": "^8.58.1",
54
+ "eslint": "^10.2.0",
50
55
  "vitest": "^1.6.0"
51
56
  },
52
57
  "engines": {
package/skills/start.md CHANGED
@@ -224,6 +224,38 @@ AskUserQuestion: `header: "执行模式"`, `multiSelect: false`
224
224
 
225
225
  **研究上下文集成**: 如果已加载研究领域,AI 应基于 `RESEARCH.md` 中的领域知识确认/补充 goals,而非从零提取。`plan` 字段应包含领域技术栈、架构模式等知识。
226
226
 
227
+ **plan 字段格式要求(供系统解析模块):**
228
+
229
+ plan 中必须包含以下结构之一,系统将据此拆分为模块级任务:
230
+
231
+ **中文格式(推荐):**
232
+ ```
233
+ ## 架构设计
234
+ 1. 用户域:用户注册登录模块
235
+ 2. 订单域:订单处理模块
236
+ 3. 商品域:商品管理模块
237
+ ```
238
+
239
+ 或简洁格式:
240
+ ```
241
+ 3领域模块: 用户、订单、商品
242
+ ```
243
+
244
+ **英文格式:**
245
+ ```
246
+ ## Modules
247
+ - User module: authentication and profile
248
+ - Order module: order processing
249
+ - Product module: catalog management
250
+ ```
251
+
252
+ 或:
253
+ ```
254
+ 3 modules: User, Order, Product
255
+ ```
256
+
257
+ > **重要**: 如果 plan 不包含可解析的模块结构,系统将从 goals 中推断模块(仅 `development` 类型 goal),或 fallback 到按 goal 拆分。包含模块结构可获得更精细的依赖分析和并行执行优化。
258
+
227
259
  **goalTypes 标注示例:**
228
260
 
229
261
  | Goal | Type | 理由 |