openmatrix 0.1.11 → 0.1.13

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 CHANGED
@@ -251,6 +251,7 @@ Accept 阶段由 Reviewer Agent 执行:
251
251
  | `/om` | **默认入口** - 直接输入任务描述即可启动 |
252
252
  | `/om:start` | 启动新任务 (第一个问题选质量级别) |
253
253
  | `/om:auto` | 🚀 **全自动执行** - 无阻塞、无确认、直接完成 |
254
+ | `/om:check` | 🔍 **项目检查** - 自动检测可改进点并提供升级建议 |
254
255
  | `/om:status` | 查看状态 |
255
256
  | `/om:approve` | 审批决策 |
256
257
  | `/om:meeting` | 处理阻塞问题 |
@@ -260,6 +261,31 @@ Accept 阶段由 Reviewer Agent 执行:
260
261
 
261
262
  > `/om` 是 `/om:start` 的快捷方式,功能完全相同
262
263
 
264
+ ### `/om:check` 项目检查
265
+
266
+ **适用场景**: 代码质量检查、安全审计、AI 项目配置检查
267
+
268
+ ```bash
269
+ /om:check # 自动扫描当前项目
270
+ /om:check 安全 # 聚焦安全问题
271
+ /om:check --categories skill,prompt,agent # 检查 AI 项目配置
272
+ /om:check --auto # 自动执行所有改进
273
+ ```
274
+
275
+ **检测维度**:
276
+
277
+ | 类别 | 说明 | 示例 |
278
+ |------|------|------|
279
+ | 🐛 bug | 代码缺陷 | TODO, FIXME, 潜在bug |
280
+ | 🔧 quality | 代码质量 | 过长函数, 复杂度, 重复代码 |
281
+ | 📦 capability | 缺失能力 | 缺少测试, 文档, 类型定义 |
282
+ | 🔒 security | 安全问题 | 硬编码密钥, SQL注入 |
283
+ | 🤖 prompt | Prompt 问题 | 注入风险, 缺少格式说明 |
284
+ | ⚡ skill | Skill 问题 | 缺少 frontmatter, objective |
285
+ | 🧠 agent | Agent 配置 | CLAUDE.md 缺少构建命令 |
286
+
287
+ **支持项目类型**: OpenMatrix, AI项目, Node.js, TypeScript, Python, Go, Rust, Java, C#, C/C++, PHP, Dart
288
+
263
289
  ### `/om:start` 执行流程 (含 Meeting 机制)
264
290
 
265
291
  ```
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const checkCommand: Command;
@@ -0,0 +1,330 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.checkCommand = void 0;
40
+ // src/cli/commands/check.ts
41
+ const commander_1 = require("commander");
42
+ const upgrade_detector_js_1 = require("../../orchestrator/upgrade-detector.js");
43
+ const readline = __importStar(require("readline"));
44
+ const chalk_1 = __importDefault(require("chalk"));
45
+ exports.checkCommand = new commander_1.Command('check')
46
+ .description('自动检测项目可改进点并提供升级建议')
47
+ .argument('[hint]', '用户提示 (可选,用于聚焦检测方向)')
48
+ .option('--json', '输出 JSON 格式 (供 Skill 解析)')
49
+ .option('--auto', '自动执行所有改进建议 (无需确认)')
50
+ .option('--categories <items>', '指定检测类别 (逗号分隔)', 'bug,quality,capability,ux,style,security,common')
51
+ .option('--min-priority <level>', '最小优先级 (critical|high|medium|low)', 'low')
52
+ .option('--max <number>', '最大建议数量', '50')
53
+ .option('--scan <dirs>', '扫描目录 (逗号分隔)', 'src,skills,tests,docs')
54
+ .option('--interactive', '交互式选择要执行的改进', false)
55
+ .action(async (hint, options) => {
56
+ const projectRoot = process.cwd();
57
+ // 解析配置
58
+ const config = {
59
+ userHint: hint,
60
+ categories: options.categories.split(',').map((c) => c.trim()),
61
+ minPriority: options.minPriority,
62
+ maxSuggestions: parseInt(options.max),
63
+ scanDirs: options.scan.split(',').map((d) => d.trim())
64
+ };
65
+ // 创建检测器
66
+ const detector = new upgrade_detector_js_1.UpgradeDetector(projectRoot, config);
67
+ if (!options.json) {
68
+ console.log(chalk_1.default.bold.cyan('\n🔍 OpenMatrix 升级检测器'));
69
+ console.log('━'.repeat(42));
70
+ console.log(`📁 项目路径: ${projectRoot}`);
71
+ if (hint) {
72
+ console.log(`💡 用户提示: ${hint}`);
73
+ }
74
+ console.log('\n⏳ 正在扫描项目...\n');
75
+ }
76
+ try {
77
+ // 执行检测
78
+ const result = await detector.detect();
79
+ // JSON 输出
80
+ if (options.json) {
81
+ console.log(JSON.stringify(result, null, 2));
82
+ return;
83
+ }
84
+ // 显示结果
85
+ displayResult(result);
86
+ // 交互式选择
87
+ if (options.interactive && result.suggestions.length > 0) {
88
+ const selected = await interactiveSelect(result.suggestions);
89
+ if (selected.length > 0) {
90
+ await executeSelected(selected, result.projectType);
91
+ }
92
+ }
93
+ else if (options.auto && result.suggestions.length > 0) {
94
+ // 自动执行所有
95
+ await executeAll(result.suggestions, result.projectType);
96
+ }
97
+ else if (result.suggestions.length > 0) {
98
+ // 询问用户
99
+ const shouldExecute = await askForExecution();
100
+ if (shouldExecute) {
101
+ await executeAll(result.suggestions, result.projectType);
102
+ }
103
+ }
104
+ }
105
+ catch (error) {
106
+ if (options.json) {
107
+ console.log(JSON.stringify({ error: String(error) }));
108
+ }
109
+ else {
110
+ console.error(chalk_1.default.red('\n❌ 检测失败:'), error);
111
+ }
112
+ process.exit(1);
113
+ }
114
+ });
115
+ /**
116
+ * 显示检测结果
117
+ */
118
+ function displayResult(result) {
119
+ const { projectType, projectName, suggestions, summary } = result;
120
+ console.log(chalk_1.default.bold(`📦 项目: ${projectName}`));
121
+ console.log(` 类型: ${formatProjectType(projectType)}`);
122
+ console.log(` 扫描时间: ${new Date(result.timestamp).toLocaleString()}\n`);
123
+ // 摘要
124
+ console.log(chalk_1.default.bold('📊 检测摘要'));
125
+ console.log('━'.repeat(42));
126
+ const categoryLabels = {
127
+ bug: '🐛 代码缺陷',
128
+ quality: '🔧 代码质量',
129
+ capability: '📦 缺失能力',
130
+ ux: '👤 用户体验',
131
+ style: '🎨 代码风格',
132
+ security: '🔒 安全问题',
133
+ common: '⚠️ 常见问题',
134
+ prompt: '🤖 Prompt 问题',
135
+ skill: '⚡ Skill 问题',
136
+ agent: '🧠 Agent 配置'
137
+ };
138
+ for (const [cat, count] of Object.entries(summary.byCategory)) {
139
+ if (count > 0) {
140
+ console.log(` ${categoryLabels[cat]}: ${chalk_1.default.yellow(count)}`);
141
+ }
142
+ }
143
+ console.log(`\n 总计: ${chalk_1.default.bold(summary.total)} 个建议`);
144
+ console.log(` 可自动修复: ${chalk_1.default.green(summary.autoFixable)} 个\n`);
145
+ if (suggestions.length === 0) {
146
+ console.log(chalk_1.default.green('✅ 未发现问题,项目状态良好!\n'));
147
+ return;
148
+ }
149
+ // 详细建议
150
+ console.log(chalk_1.default.bold('📋 改进建议'));
151
+ console.log('━'.repeat(42) + '\n');
152
+ // 按优先级分组
153
+ const critical = suggestions.filter(s => s.priority === 'critical');
154
+ const high = suggestions.filter(s => s.priority === 'high');
155
+ const medium = suggestions.filter(s => s.priority === 'medium');
156
+ const low = suggestions.filter(s => s.priority === 'low');
157
+ if (critical.length > 0) {
158
+ console.log(chalk_1.default.red.bold('🚨 关键问题:\n'));
159
+ for (const s of critical) {
160
+ displaySuggestion(s);
161
+ }
162
+ }
163
+ if (high.length > 0) {
164
+ console.log(chalk_1.default.yellow.bold('⚠️ 高优先级:\n'));
165
+ for (const s of high) {
166
+ displaySuggestion(s);
167
+ }
168
+ }
169
+ if (medium.length > 0) {
170
+ console.log(chalk_1.default.blue.bold('📋 中优先级:\n'));
171
+ for (const s of medium) {
172
+ displaySuggestion(s);
173
+ }
174
+ }
175
+ if (low.length > 0) {
176
+ console.log(chalk_1.default.gray.bold('💡 低优先级:\n'));
177
+ for (const s of low.slice(0, 10)) { // 限制显示
178
+ displaySuggestion(s);
179
+ }
180
+ if (low.length > 10) {
181
+ console.log(chalk_1.default.gray(` ... 还有 ${low.length - 10} 个低优先级建议\n`));
182
+ }
183
+ }
184
+ // 提示
185
+ console.log(chalk_1.default.gray('━'.repeat(42)));
186
+ console.log(chalk_1.default.gray('💡 提示:'));
187
+ console.log(chalk_1.default.gray(' --interactive 交互式选择改进项'));
188
+ console.log(chalk_1.default.gray(' --auto 自动执行所有改进'));
189
+ console.log();
190
+ }
191
+ /**
192
+ * 显示单个建议
193
+ */
194
+ function displaySuggestion(s) {
195
+ const priorityColors = {
196
+ critical: chalk_1.default.red,
197
+ high: chalk_1.default.yellow,
198
+ medium: chalk_1.default.blue,
199
+ low: chalk_1.default.gray
200
+ };
201
+ const categoryIcons = {
202
+ bug: '🐛',
203
+ quality: '🔧',
204
+ capability: '📦',
205
+ ux: '👤',
206
+ style: '🎨',
207
+ security: '🔒',
208
+ common: '⚠️',
209
+ prompt: '🤖',
210
+ skill: '⚡',
211
+ agent: '🧠'
212
+ };
213
+ const color = priorityColors[s.priority];
214
+ console.log(` ${color(`[${s.id}]`)} ${categoryIcons[s.category]} ${s.title}`);
215
+ console.log(` 位置: ${s.location.file}${s.location.line ? `:${s.location.line}` : ''}`);
216
+ console.log(` 建议: ${chalk_1.default.gray(s.suggestion)}`);
217
+ if (s.autoFixable) {
218
+ console.log(` ${chalk_1.default.green('✓ 可自动修复')}`);
219
+ }
220
+ console.log();
221
+ }
222
+ /**
223
+ * 格式化项目类型
224
+ */
225
+ function formatProjectType(type) {
226
+ const labels = {
227
+ openmatrix: '🤖 OpenMatrix',
228
+ 'ai-project': '🧠 AI 项目',
229
+ nodejs: '📦 Node.js',
230
+ typescript: '📘 TypeScript',
231
+ python: '🐍 Python',
232
+ go: '🔷 Go',
233
+ rust: '🦀 Rust',
234
+ java: '☕ Java',
235
+ csharp: '💜 C#',
236
+ cpp: '⚙️ C/C++',
237
+ php: '🐘 PHP',
238
+ dart: '🎯 Dart',
239
+ unknown: '❓ 未知'
240
+ };
241
+ return labels[type];
242
+ }
243
+ /**
244
+ * 交互式选择
245
+ */
246
+ async function interactiveSelect(suggestions) {
247
+ console.log(chalk_1.default.bold.cyan('\n🎯 交互式选择'));
248
+ console.log('━'.repeat(42));
249
+ console.log('选择要执行的改进项 (空格选择,回车确认):\n');
250
+ const rl = readline.createInterface({
251
+ input: process.stdin,
252
+ output: process.stdout
253
+ });
254
+ // 显示选项
255
+ suggestions.forEach((s, i) => {
256
+ console.log(` [ ] ${i + 1}. ${s.title} (${s.priority})`);
257
+ });
258
+ console.log('\n输入序号 (用逗号分隔),或输入 "all" 选择全部:');
259
+ return new Promise((resolve) => {
260
+ rl.question('> ', (answer) => {
261
+ rl.close();
262
+ if (answer.trim().toLowerCase() === 'all') {
263
+ resolve(suggestions);
264
+ return;
265
+ }
266
+ const indices = answer.split(',')
267
+ .map(s => parseInt(s.trim()) - 1)
268
+ .filter(i => i >= 0 && i < suggestions.length);
269
+ resolve(indices.map(i => suggestions[i]));
270
+ });
271
+ });
272
+ }
273
+ /**
274
+ * 询问是否执行
275
+ */
276
+ async function askForExecution() {
277
+ const rl = readline.createInterface({
278
+ input: process.stdin,
279
+ output: process.stdout
280
+ });
281
+ return new Promise((resolve) => {
282
+ rl.question('\n是否执行这些改进? (y/N) ', (answer) => {
283
+ rl.close();
284
+ resolve(answer.trim().toLowerCase() === 'y');
285
+ });
286
+ });
287
+ }
288
+ /**
289
+ * 执行选中的改进
290
+ */
291
+ async function executeSelected(suggestions, projectType) {
292
+ console.log(chalk_1.default.bold.cyan('\n🚀 执行改进'));
293
+ console.log('━'.repeat(42));
294
+ console.log(`选择了 ${suggestions.length} 个改进项\n`);
295
+ // 这里需要调用 /om:start 来执行实际的改进
296
+ // 输出 JSON 格式供 Skill 解析
297
+ console.log(JSON.stringify({
298
+ action: 'execute_upgrades',
299
+ projectType,
300
+ suggestions: suggestions.map(s => ({
301
+ id: s.id,
302
+ title: s.title,
303
+ category: s.category,
304
+ priority: s.priority,
305
+ location: s.location,
306
+ suggestion: s.suggestion
307
+ }))
308
+ }, null, 2));
309
+ }
310
+ /**
311
+ * 执行所有改进
312
+ */
313
+ async function executeAll(suggestions, projectType) {
314
+ console.log(chalk_1.default.bold.cyan('\n🚀 自动执行所有改进'));
315
+ console.log('━'.repeat(42));
316
+ // 输出 JSON 供 Skill 处理
317
+ console.log(JSON.stringify({
318
+ action: 'execute_all_upgrades',
319
+ projectType,
320
+ count: suggestions.length,
321
+ suggestions: suggestions.map(s => ({
322
+ id: s.id,
323
+ title: s.title,
324
+ category: s.category,
325
+ priority: s.priority,
326
+ location: s.location,
327
+ suggestion: s.suggestion
328
+ }))
329
+ }, null, 2));
330
+ }
@@ -65,8 +65,8 @@ exports.installSkillsCommand = new commander_1.Command('install-skills')
65
65
  console.error(' Error:', err.message);
66
66
  process.exit(1);
67
67
  }
68
- // Get skill files (excluding om.md and openmatrix-auto.md which are handled separately)
69
- const files = fs.readdirSync(skillsDir).filter(f => f.endsWith('.md') && f !== 'om.md' && f !== 'openmatrix-auto.md');
68
+ // Get skill files (excluding om.md and openmatrix.md which are handled separately)
69
+ const files = fs.readdirSync(skillsDir).filter(f => f.endsWith('.md') && f !== 'om.md' && f !== 'openmatrix.md');
70
70
  if (files.length === 0) {
71
71
  console.error('❌ No skill files found in:', skillsDir);
72
72
  process.exit(1);
@@ -117,22 +117,22 @@ exports.installSkillsCommand = new commander_1.Command('install-skills')
117
117
  }
118
118
  }
119
119
  // Install auto-detection instructions
120
- const autoSrc = path.join(skillsDir, 'openmatrix-auto.md');
121
- const autoDest = path.join(claudeDir, 'commands', 'openmatrix-auto.md');
120
+ const autoSrc = path.join(skillsDir, 'openmatrix.md');
121
+ const autoDest = path.join(claudeDir, 'commands', 'openmatrix.md');
122
122
  if (fs.existsSync(autoSrc)) {
123
123
  try {
124
124
  if (fs.existsSync(autoDest) && !options.force) {
125
- console.log(` ⏭️ Skipped: openmatrix-auto.md (already exists)`);
125
+ console.log(` ⏭️ Skipped: openmatrix.md (already exists)`);
126
126
  skipped++;
127
127
  }
128
128
  else {
129
129
  fs.copyFileSync(autoSrc, autoDest);
130
- console.log(` ✅ Installed: auto-detection rules`);
130
+ console.log(` ✅ Installed: /om:openmatrix (auto-detection)`);
131
131
  installed++;
132
132
  }
133
133
  }
134
134
  catch (err) {
135
- console.log(` ❌ Failed: openmatrix-auto.md (${err.message})`);
135
+ console.log(` ❌ Failed: openmatrix.md (${err.message})`);
136
136
  failed++;
137
137
  }
138
138
  }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const upgradeCommand: Command;