sumulige-claude 1.5.1 → 1.5.2

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.
Files changed (219) hide show
  1. package/.claude/hooks/hook-registry.json +0 -15
  2. package/.claude/rules/coding-style.md +18 -7
  3. package/.claude/rules/hooks.md +15 -4
  4. package/.claude/rules/performance.md +15 -5
  5. package/.claude/rules/security.md +140 -4
  6. package/.claude/rules/testing.md +138 -9
  7. package/.claude/rules/web-design-standard.md +16 -5
  8. package/.claude/skills/algorithmic-art/metadata.yaml +28 -0
  9. package/.claude/skills/api-tester/SKILL.md +61 -0
  10. package/.claude/skills/api-tester/examples/basic.md +3 -0
  11. package/.claude/skills/api-tester/metadata.yaml +30 -0
  12. package/.claude/skills/api-tester/templates/default.md +3 -0
  13. package/.claude/skills/brand-guidelines/metadata.yaml +26 -0
  14. package/.claude/skills/canvas-design/metadata.yaml +27 -0
  15. package/.claude/skills/code-reviewer-123/SKILL.md +61 -0
  16. package/.claude/skills/code-reviewer-123/examples/basic.md +3 -0
  17. package/.claude/skills/code-reviewer-123/metadata.yaml +30 -0
  18. package/.claude/skills/code-reviewer-123/templates/default.md +3 -0
  19. package/.claude/skills/doc-coauthoring/metadata.yaml +27 -0
  20. package/.claude/skills/docx/metadata.yaml +30 -0
  21. package/.claude/skills/frontend-design/metadata.yaml +28 -0
  22. package/.claude/skills/internal-comms/metadata.yaml +28 -0
  23. package/.claude/skills/mcp-builder/metadata.yaml +26 -0
  24. package/.claude/skills/my-skill/SKILL.md +61 -0
  25. package/.claude/skills/my-skill/examples/basic.md +3 -0
  26. package/.claude/skills/my-skill/metadata.yaml +30 -0
  27. package/.claude/skills/my-skill/templates/default.md +3 -0
  28. package/.claude/skills/pdf/metadata.yaml +29 -0
  29. package/.claude/skills/pptx/metadata.yaml +29 -0
  30. package/.claude/skills/react-best-practices/metadata.yaml +26 -0
  31. package/.claude/skills/react-node-practices/SKILL.md +409 -0
  32. package/.claude/skills/react-node-practices/metadata.yaml +56 -0
  33. package/.claude/skills/skill-creator/metadata.yaml +25 -0
  34. package/.claude/skills/slack-gif-creator/metadata.yaml +28 -0
  35. package/.claude/skills/test-skill-name/SKILL.md +61 -0
  36. package/.claude/skills/test-skill-name/examples/basic.md +3 -0
  37. package/.claude/skills/test-skill-name/metadata.yaml +30 -0
  38. package/.claude/skills/test-skill-name/templates/default.md +3 -0
  39. package/.claude/skills/test-workflow/metadata.yaml +32 -0
  40. package/.claude/skills/theme-factory/metadata.yaml +26 -0
  41. package/.claude/skills/threejs-fundamentals/metadata.yaml +27 -0
  42. package/.claude/skills/web-artifacts-builder/metadata.yaml +30 -0
  43. package/.claude/skills/web-design-guidelines/metadata.yaml +26 -0
  44. package/.claude/skills/webapp-testing/metadata.yaml +26 -0
  45. package/.claude/skills/xlsx/metadata.yaml +29 -0
  46. package/LICENSE +21 -0
  47. package/cli.js +1 -1
  48. package/package.json +25 -3
  49. package/.claude/.kickoff-hint.txt +0 -52
  50. package/.claude/.sumulige-claude-version +0 -1
  51. package/.claude/.version +0 -1
  52. package/.claude/AGENTS.md +0 -42
  53. package/.claude/ANCHORS.md +0 -40
  54. package/.claude/CLAUDE.md +0 -138
  55. package/.claude/MEMORY.md +0 -69
  56. package/.claude/PROJECT_LOG.md +0 -101
  57. package/.claude/THINKING_CHAIN_GUIDE.md +0 -287
  58. package/.claude/USAGE.md +0 -175
  59. package/.claude/boris-optimizations.md +0 -167
  60. package/.claude/handoffs/INDEX.md +0 -21
  61. package/.claude/handoffs/LATEST.md +0 -76
  62. package/.claude/handoffs/handoff_2026-01-22T13-07-04-757Z.md +0 -76
  63. package/.claude/quality-gate.json +0 -82
  64. package/.claude/rag/skill-index.json +0 -135
  65. package/.claude/settings.json +0 -99
  66. package/.claude/settings.local.json +0 -175
  67. package/.claude/templates/PROJECT_KICKOFF.md +0 -89
  68. package/.claude/templates/PROJECT_PROPOSAL.md +0 -227
  69. package/.claude/templates/TASK_PLAN.md +0 -121
  70. package/.claude/templates/hooks/README.md +0 -302
  71. package/.claude/templates/hooks/hook.sh.template +0 -94
  72. package/.claude/templates/hooks/user-prompt-submit.cjs.template +0 -116
  73. package/.claude/templates/hooks/user-response-submit.cjs.template +0 -94
  74. package/.claude/templates/hooks/validate.js +0 -173
  75. package/.claude/templates/tasks/develop.md +0 -69
  76. package/.claude/templates/tasks/research.md +0 -64
  77. package/.claude/templates/tasks/test.md +0 -96
  78. package/.claude/thinking-routes/.last-sync +0 -1
  79. package/.claude/thinking-routes/QUICKREF.md +0 -98
  80. package/.claude/workflow/document-scanner.js +0 -426
  81. package/.claude/workflow/knowledge-engine.js +0 -941
  82. package/.claude/workflow/notebooklm/browser.js +0 -1028
  83. package/.claude/workflow/phases/phase1-research.js +0 -578
  84. package/.claude/workflow/phases/phase1-research.ts +0 -465
  85. package/.claude/workflow/phases/phase2-approve.js +0 -722
  86. package/.claude/workflow/phases/phase3-plan.js +0 -1200
  87. package/.claude/workflow/phases/phase4-develop.js +0 -894
  88. package/.claude/workflow/search-cache.js +0 -230
  89. package/.claude/workflow/templates/approval.md +0 -315
  90. package/.claude/workflow/templates/development.md +0 -377
  91. package/.claude/workflow/templates/planning.md +0 -328
  92. package/.claude/workflow/templates/research.md +0 -250
  93. package/.claude/workflow/types.js +0 -37
  94. package/.claude/workflow/web-search.js +0 -278
  95. package/.claude-plugin/marketplace.json +0 -71
  96. package/.github/workflows/sync-skills.yml +0 -74
  97. package/.versionrc +0 -25
  98. package/AGENTS.md +0 -580
  99. package/CHANGELOG.md +0 -481
  100. package/CLAUDE-template.md +0 -114
  101. package/DEV_TOOLS_GUIDE.md +0 -190
  102. package/PROJECT_STRUCTURE.md +0 -266
  103. package/Q&A.md +0 -325
  104. package/config/defaults.json +0 -34
  105. package/config/official-skills.json +0 -183
  106. package/config/quality-gate.json +0 -67
  107. package/config/skill-categories.json +0 -40
  108. package/config/version-manifest.json +0 -85
  109. package/demos/power-3d-scatter.html +0 -683
  110. package/development/cache/web-search/search_1193d605f8eb364651fc2f2041b58a31.json +0 -36
  111. package/development/cache/web-search/search_3798bf06960edc125f744a1abb5b72c5.json +0 -36
  112. package/development/cache/web-search/search_37c7d4843a53f0d83f1122a6f908a2a3.json +0 -36
  113. package/development/cache/web-search/search_44166fa0153709ee168485a22aa0ab40.json +0 -36
  114. package/development/cache/web-search/search_4deaebb1f77e86a8ca066dc5a49c59fd.json +0 -36
  115. package/development/cache/web-search/search_94da91789466070a7f545612e73c7372.json +0 -36
  116. package/development/cache/web-search/search_dd5de8491b8b803a3cb01339cd210fb0.json +0 -36
  117. package/development/knowledge-base/.index.clean.json +0 -1
  118. package/development/knowledge-base/.index.json +0 -486
  119. package/development/knowledge-base/test-best-practices.md +0 -29
  120. package/development/projects/proj_mkh1pazz_ixmt1/phase1/feasibility-report.md +0 -160
  121. package/development/projects/proj_mkh4jvnb_z7rwf/phase1/feasibility-report.md +0 -160
  122. package/development/projects/proj_mkh4jxkd_ewz5a/phase1/feasibility-report.md +0 -160
  123. package/development/projects/proj_mkh4k84n_ni73k/phase1/feasibility-report.md +0 -160
  124. package/development/projects/proj_mkh4wfyd_u9w88/phase1/feasibility-report.md +0 -160
  125. package/development/projects/proj_mkh4wsbo_iahvf/development/projects/proj_mkh4xbpg_4na5w/phase1/feasibility-report.md +0 -160
  126. package/development/projects/proj_mkh4wsbo_iahvf/phase1/feasibility-report.md +0 -160
  127. package/development/projects/proj_mkh4xulg_1ka8x/phase1/feasibility-report.md +0 -160
  128. package/development/projects/proj_mkh4xwhj_gch8j/phase1/feasibility-report.md +0 -160
  129. package/development/projects/proj_mkh4y2qk_9lm8z/phase1/feasibility-report.md +0 -160
  130. package/development/projects/proj_mkh4y2qk_9lm8z/phase2/requirements.md +0 -226
  131. package/development/projects/proj_mkh4y2qk_9lm8z/phase3/PRD.md +0 -345
  132. package/development/projects/proj_mkh4y2qk_9lm8z/phase3/TASK_PLAN.md +0 -284
  133. package/development/projects/proj_mkh4y2qk_9lm8z/phase3/prototype/README.md +0 -14
  134. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/DEVELOPMENT_LOG.md +0 -35
  135. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/TASKS.md +0 -34
  136. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/.env.example +0 -5
  137. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/README.md +0 -60
  138. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/package.json +0 -25
  139. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/index.js +0 -70
  140. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/routes/index.js +0 -48
  141. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/health.test.js +0 -20
  142. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/jest.config.js +0 -21
  143. package/development/projects/proj_mkh7veqg_3lypc/phase1/feasibility-report.md +0 -160
  144. package/development/projects/proj_mkh7veqg_3lypc/phase2/requirements.md +0 -226
  145. package/development/projects/proj_mkh7veqg_3lypc/phase3/PRD.md +0 -345
  146. package/development/projects/proj_mkh7veqg_3lypc/phase3/TASK_PLAN.md +0 -284
  147. package/development/projects/proj_mkh7veqg_3lypc/phase3/prototype/README.md +0 -14
  148. package/development/projects/proj_mkh8k8fo_rmqn5/phase1/feasibility-report.md +0 -160
  149. package/development/projects/proj_mkh8xyhy_1vshq/phase1/feasibility-report.md +0 -178
  150. package/development/projects/proj_mkh8zddd_dhamf/phase1/feasibility-report.md +0 -377
  151. package/development/projects/proj_mkh8zddd_dhamf/phase2/requirements.md +0 -442
  152. package/development/projects/proj_mkh8zddd_dhamf/phase3/api-design.md +0 -800
  153. package/development/projects/proj_mkh8zddd_dhamf/phase3/architecture.md +0 -625
  154. package/development/projects/proj_mkh8zddd_dhamf/phase3/data-model.md +0 -830
  155. package/development/projects/proj_mkh8zddd_dhamf/phase3/risks.md +0 -957
  156. package/development/projects/proj_mkh8zddd_dhamf/phase3/wbs.md +0 -381
  157. package/development/todos/.state.json +0 -19
  158. package/development/todos/INDEX.md +0 -63
  159. package/development/todos/active/_README.md +0 -49
  160. package/development/todos/archived/_README.md +0 -11
  161. package/development/todos/backlog/_README.md +0 -11
  162. package/development/todos/backlog/mcp-integration.md +0 -35
  163. package/development/todos/completed/_README.md +0 -11
  164. package/development/todos/completed/boris-optimizations.md +0 -39
  165. package/development/todos/completed/develop/local-knowledge-index.md +0 -85
  166. package/development/todos/completed/develop/todo-system.md +0 -47
  167. package/development/todos/completed/develop/web-search-integration.md +0 -83
  168. package/development/todos/completed/test/phase1-e2e-test.md +0 -103
  169. package/docs/DEVELOPMENT.md +0 -461
  170. package/docs/MARKETPLACE.md +0 -352
  171. package/docs/RELEASE.md +0 -93
  172. package/jest.config.js +0 -63
  173. package/lib/commands.js +0 -3588
  174. package/lib/config-manager.js +0 -441
  175. package/lib/config-schema.js +0 -408
  176. package/lib/config-validator.js +0 -330
  177. package/lib/config.js +0 -122
  178. package/lib/errors.js +0 -305
  179. package/lib/incremental-sync.js +0 -274
  180. package/lib/marketplace.js +0 -487
  181. package/lib/migrations.js +0 -154
  182. package/lib/permission-audit.js +0 -255
  183. package/lib/quality-gate.js +0 -431
  184. package/lib/quality-rules.js +0 -373
  185. package/lib/utils.js +0 -150
  186. package/lib/version-check.js +0 -169
  187. package/lib/version-manifest.js +0 -171
  188. package/project-paradigm.md +0 -313
  189. package/prompts/how-to-find.md +0 -163
  190. package/prompts/linus-architect.md +0 -71
  191. package/prompts/software-architect.md +0 -173
  192. package/prompts/web-designer.md +0 -249
  193. package/scripts/fix-hooks.mjs +0 -97
  194. package/scripts/sync-external.mjs +0 -298
  195. package/scripts/sync-to-home.sh +0 -108
  196. package/scripts/update-registry.mjs +0 -325
  197. package/sources.yaml +0 -83
  198. package/tests/README.md +0 -263
  199. package/tests/commands.test.js +0 -1086
  200. package/tests/config-manager.test.js +0 -677
  201. package/tests/config-schema.test.js +0 -425
  202. package/tests/config-validator.test.js +0 -436
  203. package/tests/config.test.js +0 -100
  204. package/tests/errors.test.js +0 -477
  205. package/tests/manual/phase1-e2e.sh +0 -389
  206. package/tests/manual/phase2-test-cases.md +0 -311
  207. package/tests/manual/phase3-test-cases.md +0 -309
  208. package/tests/manual/phase4-test-cases.md +0 -414
  209. package/tests/manual/test-cases.md +0 -417
  210. package/tests/marketplace.test.js +0 -420
  211. package/tests/migrations.test.js +0 -187
  212. package/tests/quality-gate.test.js +0 -679
  213. package/tests/quality-rules.test.js +0 -619
  214. package/tests/sync-external.test.js +0 -214
  215. package/tests/update-registry.test.js +0 -251
  216. package/tests/utils.test.js +0 -171
  217. package/tests/version-check.test.js +0 -75
  218. package/tests/web-search.test.js +0 -392
  219. package/thinkinglens-silent.md +0 -138
@@ -1,477 +0,0 @@
1
- /**
2
- * Errors 模块单元测试
3
- */
4
-
5
- const fs = require('fs');
6
- const path = require('path');
7
- const os = require('os');
8
-
9
- describe('Error Types', () => {
10
- const {
11
- SMCError,
12
- ConfigError,
13
- ValidationError,
14
- QualityGateError,
15
- MigrationError,
16
- FileError,
17
- RuleError,
18
- parseAJVErrors,
19
- getSeverityFromKeyword,
20
- generateFixFromError
21
- } = require('../lib/errors');
22
-
23
- describe('SMCError (Base Class)', () => {
24
- it('should create error with all properties', () => {
25
- const error = new SMCError('Test error', {
26
- code: 'ERR_TEST',
27
- severity: 'error',
28
- details: { key: 'value' },
29
- hints: ['Fix this', 'Try that'],
30
- docUrl: 'https://example.com/docs'
31
- });
32
-
33
- expect(error.message).toBe('Test error');
34
- expect(error.name).toBe('SMCError');
35
- expect(error.code).toBe('ERR_TEST');
36
- expect(error.severity).toBe('error');
37
- expect(error.details).toEqual({ key: 'value' });
38
- expect(error.hints).toEqual(['Fix this', 'Try that']);
39
- expect(error.docUrl).toBe('https://example.com/docs');
40
- });
41
-
42
- it('should use defaults when options not provided', () => {
43
- const error = new SMCError('Simple error');
44
-
45
- expect(error.code).toBe('ERR_UNKNOWN');
46
- expect(error.severity).toBe('error');
47
- expect(error.details).toEqual({});
48
- expect(error.hints).toEqual([]);
49
- });
50
-
51
- it('should serialize to JSON correctly', () => {
52
- const error = new SMCError('Test', {
53
- code: 'ERR_TEST',
54
- severity: 'warn',
55
- hints: ['Hint 1']
56
- });
57
-
58
- const json = error.toJSON();
59
-
60
- expect(json).toEqual({
61
- name: 'SMCError',
62
- code: 'ERR_TEST',
63
- message: 'Test',
64
- severity: 'warn',
65
- details: {},
66
- hints: ['Hint 1'],
67
- docUrl: undefined
68
- });
69
- });
70
-
71
- it('should format toString with hints', () => {
72
- const error = new SMCError('Test error', {
73
- code: 'ERR_TEST',
74
- hints: ['First hint', 'Second hint']
75
- });
76
-
77
- const str = error.toString();
78
-
79
- expect(str).toContain('[ERR_TEST]');
80
- expect(str).toContain('Test error');
81
- expect(str).toContain('Suggestions:');
82
- expect(str).toContain('1. First hint');
83
- expect(str).toContain('2. Second hint');
84
- });
85
-
86
- it('should include docUrl in toString when present', () => {
87
- const error = new SMCError('Test', {
88
- code: 'ERR_TEST',
89
- docUrl: 'https://docs.example.com'
90
- });
91
-
92
- const str = error.toString();
93
-
94
- expect(str).toContain('https://docs.example.com');
95
- });
96
-
97
- it('should compare severity levels correctly', () => {
98
- const infoError = new SMCError('Test', { severity: 'info' });
99
- const warnError = new SMCError('Test', { severity: 'warn' });
100
- const errorError = new SMCError('Test', { severity: 'error' });
101
- const criticalError = new SMCError('Test', { severity: 'critical' });
102
-
103
- expect(infoError.hasSeverity('info')).toBe(true);
104
- expect(infoError.hasSeverity('warn')).toBe(false);
105
-
106
- expect(warnError.hasSeverity('info')).toBe(true);
107
- expect(warnError.hasSeverity('warn')).toBe(true);
108
- expect(warnError.hasSeverity('error')).toBe(false);
109
-
110
- expect(errorError.hasSeverity('info')).toBe(true);
111
- expect(errorError.hasSeverity('error')).toBe(true);
112
- expect(errorError.hasSeverity('critical')).toBe(false);
113
-
114
- expect(criticalError.hasSeverity('info')).toBe(true);
115
- expect(criticalError.hasSeverity('critical')).toBe(true);
116
- });
117
-
118
- it('should be instanceof Error', () => {
119
- const error = new SMCError('Test');
120
- expect(error instanceof Error).toBe(true);
121
- });
122
-
123
- it('should have correct stack trace', () => {
124
- const error = new SMCError('Test');
125
- expect(error.stack).toBeDefined();
126
- expect(error.stack).toContain('SMCError');
127
- });
128
- });
129
-
130
- describe('ConfigError', () => {
131
- it('should create config error with errors and fixes', () => {
132
- const errors = [
133
- { path: 'agents', message: 'Invalid agents config', severity: 'error' },
134
- { path: 'version', message: 'Missing version', severity: 'critical' }
135
- ];
136
- const fixes = ['Add version field', 'Fix agents structure'];
137
-
138
- const error = new ConfigError('Config validation failed', errors, fixes);
139
-
140
- expect(error.message).toBe('Config validation failed');
141
- expect(error.code).toBe('ERR_CONFIG');
142
- expect(error.severity).toBe('critical');
143
- expect(error.errors).toEqual(errors);
144
- expect(error.fixes).toEqual(fixes);
145
- expect(error.details.errorCount).toBe(2);
146
- expect(error.details.fixCount).toBe(2);
147
- expect(error.details.criticalCount).toBe(1);
148
- });
149
-
150
- it('should format toString with error details', () => {
151
- const errors = [
152
- { path: 'version', message: 'Missing version', severity: 'critical' },
153
- { path: 'agents', message: 'Invalid type', severity: 'error', fix: 'Use object type' }
154
- ];
155
- const fixes = ['Add version field'];
156
-
157
- const error = new ConfigError('Config error', errors, fixes);
158
- const str = error.toString();
159
-
160
- expect(str).toContain('ConfigError:');
161
- expect(str).toContain('Errors (2):');
162
- expect(str).toContain('[X] version: Missing version');
163
- expect(str).toContain('[E] agents: Invalid type');
164
- expect(str).toContain('Fix: Use object type');
165
- expect(str).toContain('Suggested fixes:');
166
- expect(str).toContain('1. Add version field');
167
- });
168
-
169
- it('should handle empty errors and fixes', () => {
170
- const error = new ConfigError('No errors', [], []);
171
-
172
- expect(error.details.errorCount).toBe(0);
173
- expect(error.details.fixCount).toBe(0);
174
- expect(error.details.criticalCount).toBe(0);
175
- });
176
-
177
- it('should accept additional options', () => {
178
- const error = new ConfigError('Test', [], [], {
179
- severity: 'error',
180
- code: 'CUSTOM_CODE'
181
- });
182
-
183
- expect(error.severity).toBe('error');
184
- expect(error.code).toBe('CUSTOM_CODE');
185
- });
186
- });
187
-
188
- describe('ValidationError', () => {
189
- it('should create validation error', () => {
190
- const error = new ValidationError('Validation failed');
191
-
192
- expect(error.message).toBe('Validation failed');
193
- expect(error.code).toBe('ERR_VALIDATION');
194
- expect(error.severity).toBe('error');
195
- });
196
-
197
- it('should accept custom options', () => {
198
- const error = new ValidationError('Custom message', {
199
- severity: 'critical',
200
- details: { field: 'email' }
201
- });
202
-
203
- expect(error.severity).toBe('critical');
204
- expect(error.details.field).toBe('email');
205
- });
206
- });
207
-
208
- describe('QualityGateError', () => {
209
- it('should create quality gate error with results', () => {
210
- const results = {
211
- passed: false,
212
- summary: {
213
- total: 10,
214
- critical: 1,
215
- error: 2,
216
- warn: 7
217
- }
218
- };
219
-
220
- const error = new QualityGateError('Quality gate failed', results);
221
-
222
- expect(error.message).toBe('Quality gate failed');
223
- expect(error.code).toBe('ERR_QUALITY_GATE');
224
- expect(error.severity).toBe('error');
225
- expect(error.results).toEqual(results);
226
- expect(error.details.passed).toBe(false);
227
- expect(error.details.total).toBe(10);
228
- expect(error.details.critical).toBe(1);
229
- expect(error.details.error).toBe(2);
230
- expect(error.details.warn).toBe(7);
231
- });
232
-
233
- it('should handle empty results', () => {
234
- const error = new QualityGateError('Failed', {});
235
-
236
- expect(error.details.passed).toBe(false);
237
- expect(error.details.total).toBe(0);
238
- expect(error.details.critical).toBe(0);
239
- });
240
- });
241
-
242
- describe('MigrationError', () => {
243
- it('should create migration error', () => {
244
- const error = new MigrationError('Migration from v1.0.0 failed');
245
-
246
- expect(error.message).toBe('Migration from v1.0.0 failed');
247
- expect(error.code).toBe('ERR_MIGRATION');
248
- expect(error.severity).toBe('critical');
249
- });
250
-
251
- it('should accept custom options', () => {
252
- const error = new MigrationError('Test', {
253
- details: { fromVersion: '1.0.0', toVersion: '1.1.0' }
254
- });
255
-
256
- expect(error.details.fromVersion).toBe('1.0.0');
257
- expect(error.details.toVersion).toBe('1.1.0');
258
- });
259
- });
260
-
261
- describe('FileError', () => {
262
- it('should create file error with filePath', () => {
263
- const filePath = '/path/to/file.json';
264
- const error = new FileError('File not found', filePath);
265
-
266
- expect(error.message).toBe('File not found');
267
- expect(error.code).toBe('ERR_FILE');
268
- expect(error.severity).toBe('error');
269
- expect(error.filePath).toBe(filePath);
270
- expect(error.details.file).toBe(filePath);
271
- });
272
-
273
- it('should accept custom options', () => {
274
- const error = new FileError('Test', '/path', {
275
- severity: 'critical'
276
- });
277
-
278
- expect(error.severity).toBe('critical');
279
- });
280
- });
281
-
282
- describe('RuleError', () => {
283
- it('should create rule error with ruleId', () => {
284
- const ruleId = 'line-count-limit';
285
- const error = new RuleError('Rule execution failed', ruleId);
286
-
287
- expect(error.message).toBe('Rule execution failed');
288
- expect(error.code).toBe('ERR_RULE');
289
- expect(error.severity).toBe('warn');
290
- expect(error.ruleId).toBe(ruleId);
291
- expect(error.details.rule).toBe(ruleId);
292
- });
293
-
294
- it('should accept custom options', () => {
295
- const error = new RuleError('Test', 'my-rule', {
296
- severity: 'error'
297
- });
298
-
299
- expect(error.severity).toBe('error');
300
- });
301
- });
302
-
303
- describe('Utility Functions', () => {
304
- describe('getSeverityFromKeyword', () => {
305
- it('should map AJV keywords to severity levels', () => {
306
- expect(getSeverityFromKeyword('required')).toBe('critical');
307
- expect(getSeverityFromKeyword('type')).toBe('error');
308
- expect(getSeverityFromKeyword('enum')).toBe('error');
309
- expect(getSeverityFromKeyword('pattern')).toBe('warn');
310
- expect(getSeverityFromKeyword('format')).toBe('warn');
311
- expect(getSeverityFromKeyword('minimum')).toBe('warn');
312
- expect(getSeverityFromKeyword('maximum')).toBe('warn');
313
- expect(getSeverityFromKeyword('minLength')).toBe('warn');
314
- expect(getSeverityFromKeyword('maxLength')).toBe('warn');
315
- });
316
-
317
- it('should return warn for unknown keywords', () => {
318
- expect(getSeverityFromKeyword('unknown')).toBe('warn');
319
- expect(getSeverityFromKeyword('custom')).toBe('warn');
320
- });
321
- });
322
-
323
- describe('generateFixFromError', () => {
324
- it('should generate fix suggestions for known keywords', () => {
325
- expect(generateFixFromError({ keyword: 'required', params: { missingProperty: 'name' } }))
326
- .toBe('Add missing field: name');
327
-
328
- expect(generateFixFromError({ keyword: 'pattern', schema: { pattern: '^[a-z]+$' } }))
329
- .toBe('Value must match pattern: ^[a-z]+$');
330
-
331
- expect(generateFixFromError({ keyword: 'enum', schema: { enum: ['a', 'b', 'c'] } }))
332
- .toBe('Value must be one of: a, b, c');
333
-
334
- expect(generateFixFromError({ keyword: 'type', schema: { type: 'string' } }))
335
- .toBe('Change type to: string');
336
-
337
- expect(generateFixFromError({ keyword: 'minimum', schema: { minimum: 0 } }))
338
- .toBe('Value must be >= 0');
339
-
340
- expect(generateFixFromError({ keyword: 'maximum', schema: { maximum: 100 } }))
341
- .toBe('Value must be <= 100');
342
-
343
- expect(generateFixFromError({ keyword: 'minLength', schema: { minLength: 5 } }))
344
- .toBe('Length must be >= 5');
345
-
346
- expect(generateFixFromError({ keyword: 'maxLength', schema: { maxLength: 50 } }))
347
- .toBe('Length must be <= 50');
348
- });
349
-
350
- it('should return null for unknown keywords', () => {
351
- expect(generateFixFromError({ keyword: 'unknown' })).toBeNull();
352
- });
353
- });
354
-
355
- describe('parseAJVErrors', () => {
356
- it('should parse AJV error objects', () => {
357
- const ajvErrors = [
358
- {
359
- instancePath: '/agents',
360
- message: 'must be object',
361
- keyword: 'type',
362
- schema: { type: 'object' },
363
- data: 'string'
364
- },
365
- {
366
- instancePath: '/version',
367
- message: 'must match pattern',
368
- keyword: 'pattern',
369
- schema: { pattern: '^\\d+\\.\\d+\\.\\d+$' }
370
- },
371
- {
372
- instancePath: '',
373
- message: "must have required property 'name'",
374
- keyword: 'required',
375
- params: { missingProperty: 'name' }
376
- }
377
- ];
378
-
379
- const parsed = parseAJVErrors(ajvErrors);
380
-
381
- expect(parsed).toHaveLength(3);
382
-
383
- expect(parsed[0]).toEqual({
384
- path: '/agents',
385
- message: 'must be object',
386
- severity: 'error',
387
- expected: 'object',
388
- actual: 'string',
389
- keyword: 'type',
390
- fix: 'Change type to: object'
391
- });
392
-
393
- expect(parsed[1]).toEqual({
394
- path: '/version',
395
- message: 'must match pattern',
396
- severity: 'warn',
397
- expected: undefined,
398
- actual: undefined,
399
- keyword: 'pattern',
400
- fix: 'Value must match pattern: ^\\d+\\.\\d+\\.\\d+$'
401
- });
402
-
403
- expect(parsed[2]).toEqual({
404
- path: 'root',
405
- message: "must have required property 'name'",
406
- severity: 'critical',
407
- expected: undefined,
408
- actual: undefined,
409
- keyword: 'required',
410
- fix: 'Add missing field: name'
411
- });
412
- });
413
-
414
- it('should handle empty array', () => {
415
- expect(parseAJVErrors([])).toEqual([]);
416
- });
417
-
418
- it('should handle missing instancePath', () => {
419
- const ajvErrors = [
420
- {
421
- message: 'validation failed',
422
- keyword: 'unknown'
423
- }
424
- ];
425
-
426
- const parsed = parseAJVErrors(ajvErrors);
427
-
428
- expect(parsed[0].path).toBe('root');
429
- });
430
-
431
- it('should handle errors with no schema property', () => {
432
- const ajvErrors = [
433
- {
434
- instancePath: '/test',
435
- message: 'failed',
436
- keyword: 'custom'
437
- }
438
- ];
439
-
440
- const parsed = parseAJVErrors(ajvErrors);
441
-
442
- expect(parsed[0].severity).toBe('warn');
443
- expect(parsed[0].fix).toBeNull();
444
- });
445
- });
446
- });
447
-
448
- describe('Error Inheritance Chain', () => {
449
- it('should maintain instanceof for all error types', () => {
450
- const smcError = new SMCError('test');
451
- const configError = new ConfigError('test', [], []);
452
- const validationError = new ValidationError('test');
453
- const qualityGateError = new QualityGateError('test', {});
454
- const migrationError = new MigrationError('test');
455
- const fileError = new FileError('test', '/path');
456
- const ruleError = new RuleError('test', 'rule-id');
457
-
458
- expect(configError instanceof SMCError).toBe(true);
459
- expect(configError instanceof Error).toBe(true);
460
-
461
- expect(validationError instanceof SMCError).toBe(true);
462
- expect(validationError instanceof Error).toBe(true);
463
-
464
- expect(qualityGateError instanceof SMCError).toBe(true);
465
- expect(qualityGateError instanceof Error).toBe(true);
466
-
467
- expect(migrationError instanceof SMCError).toBe(true);
468
- expect(migrationError instanceof Error).toBe(true);
469
-
470
- expect(fileError instanceof SMCError).toBe(true);
471
- expect(fileError instanceof Error).toBe(true);
472
-
473
- expect(ruleError instanceof SMCError).toBe(true);
474
- expect(ruleError instanceof Error).toBe(true);
475
- });
476
- });
477
- });