stigmergy 1.3.2-beta.0 → 1.3.2-beta.10

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.
@@ -0,0 +1,252 @@
1
+ # 错误教训记录 (LESSONS LEARNED)
2
+
3
+ 本文档记录 Stigmergy 项目开发过程中遇到的重大错误和经验教训,**必须仔细阅读并避免重复犯错**。
4
+
5
+ ---
6
+
7
+ ## 🔴 致命错误 #1: 模板字符串中的正则表达式转义
8
+
9
+ **日期**: 2025-12-25
10
+ **影响**: 生产环境语法错误,所有 CLI 工具的 ResumeSession 集成失效
11
+ **修复版本**: v1.3.2-beta.3
12
+ **调试时间**: 约 2 小时
13
+ **失败尝试**: 3 次
14
+
15
+ ### 问题描述
16
+
17
+ 生成的 `resumesession-history.js` 文件包含语法错误:
18
+
19
+ ```javascript
20
+ SyntaxError: Invalid or unexpected token
21
+ at resumesession-history.js:515
22
+ const cleanInput = input.replace(/^\\/?stigmergy-resume\s*/i, '').trim();
23
+ ^^^^^^^
24
+ ```
25
+
26
+ ### 错误代码
27
+
28
+ **文件**: `src/core/coordination/nodejs/generators/ResumeSessionGenerator.js`
29
+ **位置**: Line 537, 627
30
+
31
+ ```javascript
32
+ // ❌ 错误写法
33
+ const cleanInput = input.replace(/^\\\\/?\${commandName}\\s*/i, '').trim();
34
+ const parts = cleanInput.split(/\\\\s+/).filter(p => p.length > 0);
35
+ ```
36
+
37
+ ### 根本原因分析
38
+
39
+ #### 错误 #1: 阻止了模板插值
40
+
41
+ ```javascript
42
+ \${commandName} // ❌ 这会生成字面量 "${commandName}",而不是插值后的值!
43
+ ${commandName} // ✅ 这才会插值生成 "/stigmergy-resume"
44
+ ```
45
+
46
+ **错误后果**:生成的代码中包含 `${commandName}` 字面量,导致语法错误。
47
+
48
+ #### 错误 #2: 正则字面量中的 `/` 冲突
49
+
50
+ ```javascript
51
+ // 当 commandName = "/stigmergy-resume" 时
52
+ // 生成的代码:
53
+ const cleanInput = input.replace(/^\\/?\/stigmergy-resume\s*/i, '').trim();
54
+ // ↑ 第一个 / 关闭了正则字面量
55
+ // stigmergy-resume\s*/i ← 这部分变成了无关代码
56
+ ```
57
+
58
+ **错误后果**:正则表达式被提前关闭,后续代码变成语法错误。
59
+
60
+ #### 错误 #3: 反斜杠转义计算错误
61
+
62
+ ```
63
+ 模板字符串转义层级:
64
+ 源文件 → 模板字符串 → 生成代码 → 正则表达式
65
+
66
+ 错误的计算:
67
+ 源文件写:/^\\\\/?\${commandName}\\s*/i
68
+ 期望生成:/^\\/?stigmergy-resume\s*/i
69
+ 实际生成:/^\\/?${commandName}\s*/i ← 未插值 + 正则破坏
70
+ ```
71
+
72
+ ### 正确的解决方案
73
+
74
+ ```javascript
75
+ // ✅ 正确写法
76
+ const cleanInput = input.replace(
77
+ new RegExp('^\\\\\\\\/?' + '${commandName}' + '\\\\\s*', 'i'),
78
+ ''
79
+ ).trim();
80
+ const parts = cleanInput.split(/\\\s+/).filter(p => p.length > 0);
81
+ ```
82
+
83
+ ### 转义计算公式
84
+
85
+ ```
86
+ 源文件中的反斜杠数 = 目标反斜杠数 × 2^(嵌套层数)
87
+ ```
88
+
89
+ **实际应用**:
90
+
91
+ | 目标 | 在模板字符串中写 | 生成后 | 解释 |
92
+ |------|------------------|--------|------|
93
+ | `\s` | `\\s` | `\s` | 模板转义 1 次 |
94
+ | `\\s` | `\\\\s` | `\\s` | 模板转义 1 次 |
95
+ | `\\\s` | `\\\\\\s` | `\\s` | 字符串内容为 `\\s` |
96
+
97
+ ### 为什么使用 RegExp 构造函数?
98
+
99
+ ```javascript
100
+ // ❌ 危险:正则字面量
101
+ /^\\\\/?\/stigmergy-resume\s*/i
102
+ // ↑ 与命令名中的 / 冲突
103
+
104
+ // ✅ 安全:RegExp 构造函数
105
+ new RegExp('^\\\\\\\\/?' + '/stigmergy-resume' + '\\\\\s*', 'i')
106
+ // ↑ 通过字符串拼接避免 / 冲突
107
+ ```
108
+
109
+ ### 经验教训
110
+
111
+ #### 1. 永远记住的规则
112
+
113
+ > **在模板字符串中生成包含正则的代码时,使用 RegExp 构造函数 + 字符串拼接,永远比尝试计算正确的正则字面量转义更安全!**
114
+
115
+ ```javascript
116
+ // ✅ 安全、清晰、可维护
117
+ new RegExp('pattern' + variable + 'pattern', 'flags')
118
+
119
+ // ❌ 危险、复杂、易出错
120
+ /pattern${variable}pattern/flags
121
+ ```
122
+
123
+ #### 2. 必须遵守的规则
124
+
125
+ - [ ] **永远不要阻止插值**:使用 `${variable}`,而不是 `\${variable}`
126
+ - [ ] **动态模式 → RegExp 构造函数**:避免正则字面量中的 `/` 冲突
127
+ - [ ] **反斜杠数量必须计算**:使用公式,不能猜测
128
+ - [ ] **必须添加语法验证**:生成代码后立即测试语法
129
+ - [ ] **必须注释说明转义**:让其他人理解你的计算
130
+
131
+ #### 3. 代码审查检查清单
132
+
133
+ 涉及 **模板字符串 + 正则表达式** 的代码必须检查:
134
+
135
+ ```javascript
136
+ // ✅ 检查项
137
+ - [ ] 所有 ${variable} 是否真的需要插值(不是 \${variable})
138
+ - [ ] 如果模式包含动态的 /,是否使用了 RegExp 构造函数
139
+ - [ ] 反斜杠数量是否经过计算(而非猜测)
140
+ - [ ] 是否有语法验证测试
141
+ - [ ] 是否注释说明了转义的计算过程
142
+ ```
143
+
144
+ ### 验证工具
145
+
146
+ ```javascript
147
+ /**
148
+ * 验证生成的代码是否有语法错误
149
+ */
150
+ function validateGeneratedCode(code) {
151
+ try {
152
+ new Function(code);
153
+ return true;
154
+ } catch (e) {
155
+ console.error('❌ 语法错误:', e.message);
156
+ console.error('代码:', code);
157
+ return false;
158
+ }
159
+ }
160
+
161
+ /**
162
+ * 计算需要的反斜杠数量
163
+ */
164
+ function calculateBackslashes(targetCount, nestingDepth = 1) {
165
+ return '\\'.repeat(targetCount * Math.pow(2, nestingDepth));
166
+ }
167
+
168
+ // 使用示例
169
+ const generatedCode = generator.generateForCLI('claude');
170
+ if (!validateGeneratedCode(generatedCode)) {
171
+ throw new Error('生成的代码有语法错误!');
172
+ }
173
+ ```
174
+
175
+ ### 相关文档
176
+
177
+ - [开发规范 - 代码生成规范](./development_guidelines.md#10-代码生成规范)
178
+ - [ResumeSessionGenerator 源代码](../src/core/coordination/nodejs/generators/ResumeSessionGenerator.js)
179
+ - [修复提交](https://github.com/your-repo/commit/6a2ee2c6)
180
+
181
+ ---
182
+
183
+ ## 📋 错误教训快速参考
184
+
185
+ ### 正则表达式生成
186
+
187
+ | 场景 | ✅ 正确 | ❌ 错误 |
188
+ |------|--------|--------|
189
+ | 动态模式 | `new RegExp(pattern + var)` | `/pattern${var}/` |
190
+ | 模板插值 | `${variable}` | `\${variable}` |
191
+ | 反斜杠转义 | 通过公式计算 | 猜测数量 |
192
+ | 语法验证 | 必须添加 | 跳过测试 |
193
+
194
+ ### 转义速查表
195
+
196
+ | 生成目标 | 模板字符串中写 | 说明 |
197
+ |----------|----------------|------|
198
+ | `\s` | `\\s` | 匹配空白字符 |
199
+ | `\\s` | `\\\\s` | 字符串 `"\s"` |
200
+ | `\\\s` | `\\\\\\s` | 字符串 `"\\s"` |
201
+ | `/stigmergy-resume` | `${commandName}` | 插值命令名 |
202
+ | `RegExp('/stigmergy-resume')` | `new RegExp('${commandName}')` | 动态正则 |
203
+
204
+ ---
205
+
206
+ ## 🔄 如何添加新的错误教训
207
+
208
+ 当遇到重大错误时,请按照以下格式记录:
209
+
210
+ ```markdown
211
+ ## 🔴 致命错误 #N: [错误标题]
212
+
213
+ **日期**: YYYY-MM-DD
214
+ **影响**: [影响范围]
215
+ **修复版本**: vX.X.X
216
+ **调试时间**: 约 X 小时
217
+ **失败尝试**: X 次
218
+
219
+ ### 问题描述
220
+ [描述问题的现象和错误信息]
221
+
222
+ ### 错误代码
223
+ **文件**: [文件路径]
224
+ **位置**: Line XXX
225
+
226
+ ```javascript
227
+ // ❌ 错误写法
228
+ [错误代码]
229
+ ```
230
+
231
+ ### 根本原因分析
232
+ [分析为什么会出现这个错误]
233
+
234
+ ### 正确的解决方案
235
+ ```javascript
236
+ // ✅ 正确写法
237
+ [正确代码]
238
+ ```
239
+
240
+ ### 经验教训
241
+ [总结规则和检查清单]
242
+
243
+ ### 验证工具
244
+ [提供验证和测试方法]
245
+ ```
246
+
247
+ ---
248
+
249
+ **最后更新**: 2025-12-25
250
+ **维护者**: Stigmergy 开发团队
251
+
252
+ **记住这些教训,避免重复犯错!**
@@ -389,4 +389,280 @@ class CacheManager {
389
389
  }
390
390
  ```
391
391
 
392
+ ## 10. 代码生成规范
393
+
394
+ ### 10.1 模板字符串中的正则表达式 ⚠️ 极其重要!
395
+
396
+ #### 🔴 致命陷阱:正则表达式字面量 vs RegExp 构造函数
397
+
398
+ **问题场景**:在模板字符串中生成包含正则表达式的代码
399
+
400
+ ```javascript
401
+ // ❌ 错误示例
402
+ const code = `
403
+ const cleanInput = input.replace(/^\\\\/?${commandName}\\s*/i, '').trim();
404
+ `;
405
+
406
+ // 当 commandName = "/stigmergy-resume" 时
407
+ // 生成:/^\\/?\/stigmergy-resume\s*/i
408
+ // ↑ 正则被 "/stigmergy-resume" 中的 / 提前关闭!
409
+ ```
410
+
411
+ **错误原因分析**:
412
+
413
+ 1. **正则字面量语法冲突**:`/pattern/` 首尾的 `/` 是定界符
414
+ 2. **命令名中的 `/` 破坏语法**:`/^\\/?\/stigmergy-resume` 中第一个 `/` 关闭了正则
415
+ 3. **模板字符串插值错误**:使用 `\${variable}` 会阻止插值!
416
+
417
+ #### ✅ 正确做法:使用 RegExp 构造函数
418
+
419
+ ```javascript
420
+ // ✅ 正确示例
421
+ const code = `
422
+ const cleanInput = input.replace(
423
+ new RegExp('^\\\\\\\\/?' + '${commandName}' + '\\\\\s*', 'i'),
424
+ ''
425
+ ).trim();
426
+ `;
427
+ ```
428
+
429
+ **转义计算公式**:
430
+
431
+ ```
432
+ 源文件中的反斜杠数 = 目标反斜杠数 × 2^(嵌套层数)
433
+ ```
434
+
435
+ | 目标 | 在模板字符串中写 | 生成后 | 说明 |
436
+ |------|------------------|--------|------|
437
+ | `\s` | `\\s` | `\s` | 模板转义一次 |
438
+ | `\\s` | `\\\\s` | `\\s` | 模板转义一次 |
439
+ | `\\\s` | `\\\\\\s` | `\\s` | 字符串中为 `\\s` |
440
+
441
+ #### 📋 必须遵守的规则
442
+
443
+ 1. **动态模式 → 用 RegExp 构造函数**
444
+ ```javascript
445
+ new RegExp(pattern + variable + pattern, flags)
446
+ ```
447
+
448
+ 2. **静态模式 → 可以用正则字面量**
449
+ ```javascript
450
+ const staticRegex = /\s+/; // 简单清晰
451
+ ```
452
+
453
+ 3. **永远不要阻止插值**
454
+ ```javascript
455
+ // ❌ 错误:阻止插值
456
+ \${commandName} // 生成字面量 "${commandName}"
457
+
458
+ // ✅ 正确:允许插值
459
+ ${commandName} // 生成实际值 "/stigmergy-resume"
460
+ ```
461
+
462
+ 4. **不要在字符串中转义 `/`**
463
+ ```javascript
464
+ // ❌ 不必要
465
+ '\/path' // 在字符串中不需要转义 /
466
+
467
+ // ✅ 正确
468
+ '/path' // 字符串中的 / 不需要转义
469
+ ```
470
+
471
+ #### 🛠️ 调试工具
472
+
473
+ ```javascript
474
+ /**
475
+ * 验证生成的代码是否有语法错误
476
+ */
477
+ function validateGeneratedCode(code) {
478
+ try {
479
+ new Function(code);
480
+ return true;
481
+ } catch (e) {
482
+ console.error('语法错误:', e.message);
483
+ return false;
484
+ }
485
+ }
486
+
487
+ /**
488
+ * 计算需要的反斜杠数量
489
+ */
490
+ function calculateBackslashes(targetCount, nestingDepth = 1) {
491
+ return '\\'.repeat(targetCount * Math.pow(2, nestingDepth));
492
+ }
493
+ ```
494
+
495
+ #### 📝 代码审查检查清单
496
+
497
+ 涉及 **模板字符串 + 正则表达式** 的代码必须检查:
498
+
499
+ - [ ] 所有 `${variable}` 是否真的需要插值(不是 `\${variable}`)
500
+ - [ ] 如果模式包含动态的 `/`,是否使用了 RegExp 构造函数
501
+ - [ ] 反斜杠数量是否经过计算(而非猜测)
502
+ - [ ] 是否有语法验证测试
503
+ - [ ] 是否注释说明了转义的计算过程
504
+
505
+ #### 💡 永远记住
506
+
507
+ > **在模板字符串中生成包含正则的代码时,使用 RegExp 构造函数 + 字符串拼接,永远比尝试计算正确的正则字面量转义更安全!**
508
+
509
+ ```javascript
510
+ // ✅ 安全、清晰、可维护
511
+ new RegExp('pattern' + variable + 'pattern', 'flags')
512
+
513
+ // ❌ 危险、复杂、易出错
514
+ /pattern${variable}pattern/flags
515
+ ```
516
+
517
+ ### 10.2 代码生成最佳实践
518
+
519
+ #### 10.2.1 生成器模式
520
+
521
+ ```javascript
522
+ class CodeGenerator {
523
+ /**
524
+ * 生成CLI集成代码
525
+ * @param {string} cliName - CLI工具名称
526
+ * @returns {string} 生成的代码
527
+ */
528
+ generateForCLI(cliName) {
529
+ const commandName = this.getCommandName(cliName);
530
+
531
+ return `
532
+ // Auto-generated by Stigmergy - DO NOT EDIT
533
+ const handler = {
534
+ commandName: '${commandName}',
535
+
536
+ async handle(input) {
537
+ const cleanInput = input.replace(
538
+ new RegExp('^\\\\\\\\/?' + '${commandName}' + '\\\\\s*', 'i'),
539
+ ''
540
+ ).trim();
541
+
542
+ // 处理逻辑...
543
+ return { response: 'OK' };
544
+ }
545
+ };
546
+
547
+ module.exports = handler;
548
+ `;
549
+ }
550
+
551
+ /**
552
+ * 获取命令名称
553
+ */
554
+ getCommandName(cliName) {
555
+ const needsSlash = ['claude', 'codebuddy'].includes(cliName.toLowerCase());
556
+ return needsSlash ? `/stigmergy-resume` : 'stigmergy-resume';
557
+ }
558
+ }
559
+ ```
560
+
561
+ #### 10.2.2 测试生成代码
562
+
563
+ ```javascript
564
+ const { CodeGenerator } = require('./generators');
565
+
566
+ describe('CodeGenerator', () => {
567
+ test('should generate valid JavaScript syntax', () => {
568
+ const generator = new CodeGenerator();
569
+ const code = generator.generateForCLI('claude');
570
+
571
+ // 验证语法
572
+ expect(() => new Function(code)).not.toThrow();
573
+
574
+ // 验证包含关键部分
575
+ expect(code).toContain('new RegExp');
576
+ expect(code).toContain('/stigmergy-resume');
577
+ });
578
+
579
+ test('should escape regex correctly', () => {
580
+ const generator = new CodeGenerator();
581
+ const code = generator.generateForCLI('claude');
582
+
583
+ // 提取并验证正则表达式
584
+ const regexMatch = code.match(/new RegExp\('([^']+)',\s*'i'\)/);
585
+ expect(regexMatch).toBeTruthy();
586
+
587
+ // 测试生成的正则是否工作
588
+ const pattern = regexMatch[1];
589
+ const regex = new RegExp(pattern, 'i');
590
+ expect(regex.test('/stigmergy-resume')).toBe(true);
591
+ expect(regex.test('\\/stigmergy-resume')).toBe(true);
592
+ });
593
+ });
594
+ ```
595
+
596
+ ### 10.3 常见错误案例
597
+
598
+ #### 案例1:阻止插值
599
+
600
+ ```javascript
601
+ // ❌ 错误
602
+ const commandName = '/stigmergy-resume';
603
+ const code = `input.replace(/^\\\\/?\${commandName}\\s*/i, '')`;
604
+ // 生成:input.replace(/^\\\\/?${commandName}\s*/i, '')
605
+ // ↑ 未插值!
606
+ ```
607
+
608
+ ```javascript
609
+ // ✅ 正确
610
+ const commandName = '/stigmergy-resume';
611
+ const code = `input.replace(new RegExp('^\\\\\\\\/?' + '${commandName}' + '\\\\\s*', 'i'), '')`;
612
+ // 生成:input.replace(new RegExp('^\\\\/?' + '/stigmergy-resume' + '\s*', 'i'), '')
613
+ ```
614
+
615
+ #### 案例2:正则字面量中的 `/` 冲突
616
+
617
+ ```javascript
618
+ // ❌ 错误
619
+ const commandName = '/stigmergy-resume';
620
+ const code = `input.replace(/\\/?${commandName}\\s*/i, '')`;
621
+ // 生成:input.replace(/\/?\/stigmergy-resume\s*/i, '')
622
+ // ↑ 第一个 / 关闭了正则
623
+ ```
624
+
625
+ ```javascript
626
+ // ✅ 正确
627
+ const commandName = '/stigmergy-resume';
628
+ const code = `input.replace(new RegExp('^\\\\\\\\/?' + '${commandName}' + '\\\\\s*', 'i'), '')`;
629
+ ```
630
+
631
+ ### 10.4 历史教训记录
632
+
633
+ #### 2025-12-25: ResumeSessionGenerator 正则转义错误
634
+
635
+ **问题描述**:
636
+ 生成的 `resumesession-history.js` 文件包含语法错误,导致无法加载。
637
+
638
+ **错误代码**(Line 537, 627):
639
+ ```javascript
640
+ const cleanInput = input.replace(/^\\\\/?\${commandName}\\s*/i, '').trim();
641
+ ```
642
+
643
+ **错误原因**:
644
+ 1. `\${commandName}` 阻止了模板插值
645
+ 2. 正则字面量中的 `/` 与命令名中的 `/` 冲突
646
+ 3. 反斜杠转义计算错误
647
+
648
+ **修复方案**:
649
+ ```javascript
650
+ const cleanInput = input.replace(
651
+ new RegExp('^\\\\\\\\/?' + '${commandName}' + '\\\\\s*', 'i'),
652
+ ''
653
+ ).trim();
654
+ ```
655
+
656
+ **影响范围**:
657
+ - 影响:所有CLI工具的ResumeSession集成
658
+ - 修复版本:v1.3.2-beta.3
659
+ - 调试时间:约2小时
660
+ - 失败尝试:3次
661
+
662
+ **经验总结**:
663
+ - 永远使用 RegExp 构造函数处理动态正则
664
+ - 永远不要在模板字符串中用 `\${` 阻止插值(除非真的需要字面量)
665
+ - 反斜杠数量必须通过公式计算,不能猜测
666
+ - 必须添加语法验证测试
667
+
392
668
  遵循这些开发规范可以确保代码质量、可维护性和团队协作效率。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stigmergy",
3
- "version": "1.3.2-beta.0",
3
+ "version": "1.3.2-beta.10",
4
4
  "description": "Stigmergy CLI - Multi-Agents Cross-AI CLI Tools Collaboration System",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -48,6 +48,8 @@
48
48
  "path-fixer": "node path-fixer.js",
49
49
  "emergency-clean": "node emergency-cleanup.js",
50
50
  "test:conflict-prevention": "node test/conflict-prevention-test.js",
51
+ "test:comprehensive": "node scripts/run-comprehensive-tests.js",
52
+ "test:quick": "node scripts/run-quick-tests.js",
51
53
  "post-deployment-config": "node scripts/post-deployment-config.js",
52
54
  "preinstall": "node scripts/preinstall-check.js",
53
55
  "postinstall": "node src/index.js auto-install",