sumulige-claude 1.5.1 → 1.6.0

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 (223) 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/README.md +280 -529
  48. package/cli.js +19 -3
  49. package/package.json +29 -3
  50. package/template/.codex/README.md +69 -0
  51. package/template/.codex/config.toml +56 -0
  52. package/template/AGENTS.md +94 -0
  53. package/.claude/.kickoff-hint.txt +0 -52
  54. package/.claude/.sumulige-claude-version +0 -1
  55. package/.claude/.version +0 -1
  56. package/.claude/AGENTS.md +0 -42
  57. package/.claude/ANCHORS.md +0 -40
  58. package/.claude/CLAUDE.md +0 -138
  59. package/.claude/MEMORY.md +0 -69
  60. package/.claude/PROJECT_LOG.md +0 -101
  61. package/.claude/THINKING_CHAIN_GUIDE.md +0 -287
  62. package/.claude/USAGE.md +0 -175
  63. package/.claude/boris-optimizations.md +0 -167
  64. package/.claude/handoffs/INDEX.md +0 -21
  65. package/.claude/handoffs/LATEST.md +0 -76
  66. package/.claude/handoffs/handoff_2026-01-22T13-07-04-757Z.md +0 -76
  67. package/.claude/quality-gate.json +0 -82
  68. package/.claude/rag/skill-index.json +0 -135
  69. package/.claude/settings.json +0 -99
  70. package/.claude/settings.local.json +0 -175
  71. package/.claude/templates/PROJECT_KICKOFF.md +0 -89
  72. package/.claude/templates/PROJECT_PROPOSAL.md +0 -227
  73. package/.claude/templates/TASK_PLAN.md +0 -121
  74. package/.claude/templates/hooks/README.md +0 -302
  75. package/.claude/templates/hooks/hook.sh.template +0 -94
  76. package/.claude/templates/hooks/user-prompt-submit.cjs.template +0 -116
  77. package/.claude/templates/hooks/user-response-submit.cjs.template +0 -94
  78. package/.claude/templates/hooks/validate.js +0 -173
  79. package/.claude/templates/tasks/develop.md +0 -69
  80. package/.claude/templates/tasks/research.md +0 -64
  81. package/.claude/templates/tasks/test.md +0 -96
  82. package/.claude/thinking-routes/.last-sync +0 -1
  83. package/.claude/thinking-routes/QUICKREF.md +0 -98
  84. package/.claude/workflow/document-scanner.js +0 -426
  85. package/.claude/workflow/knowledge-engine.js +0 -941
  86. package/.claude/workflow/notebooklm/browser.js +0 -1028
  87. package/.claude/workflow/phases/phase1-research.js +0 -578
  88. package/.claude/workflow/phases/phase1-research.ts +0 -465
  89. package/.claude/workflow/phases/phase2-approve.js +0 -722
  90. package/.claude/workflow/phases/phase3-plan.js +0 -1200
  91. package/.claude/workflow/phases/phase4-develop.js +0 -894
  92. package/.claude/workflow/search-cache.js +0 -230
  93. package/.claude/workflow/templates/approval.md +0 -315
  94. package/.claude/workflow/templates/development.md +0 -377
  95. package/.claude/workflow/templates/planning.md +0 -328
  96. package/.claude/workflow/templates/research.md +0 -250
  97. package/.claude/workflow/types.js +0 -37
  98. package/.claude/workflow/web-search.js +0 -278
  99. package/.claude-plugin/marketplace.json +0 -71
  100. package/.github/workflows/sync-skills.yml +0 -74
  101. package/.versionrc +0 -25
  102. package/AGENTS.md +0 -580
  103. package/CHANGELOG.md +0 -481
  104. package/CLAUDE-template.md +0 -114
  105. package/DEV_TOOLS_GUIDE.md +0 -190
  106. package/PROJECT_STRUCTURE.md +0 -266
  107. package/Q&A.md +0 -325
  108. package/config/defaults.json +0 -34
  109. package/config/official-skills.json +0 -183
  110. package/config/quality-gate.json +0 -67
  111. package/config/skill-categories.json +0 -40
  112. package/config/version-manifest.json +0 -85
  113. package/demos/power-3d-scatter.html +0 -683
  114. package/development/cache/web-search/search_1193d605f8eb364651fc2f2041b58a31.json +0 -36
  115. package/development/cache/web-search/search_3798bf06960edc125f744a1abb5b72c5.json +0 -36
  116. package/development/cache/web-search/search_37c7d4843a53f0d83f1122a6f908a2a3.json +0 -36
  117. package/development/cache/web-search/search_44166fa0153709ee168485a22aa0ab40.json +0 -36
  118. package/development/cache/web-search/search_4deaebb1f77e86a8ca066dc5a49c59fd.json +0 -36
  119. package/development/cache/web-search/search_94da91789466070a7f545612e73c7372.json +0 -36
  120. package/development/cache/web-search/search_dd5de8491b8b803a3cb01339cd210fb0.json +0 -36
  121. package/development/knowledge-base/.index.clean.json +0 -1
  122. package/development/knowledge-base/.index.json +0 -486
  123. package/development/knowledge-base/test-best-practices.md +0 -29
  124. package/development/projects/proj_mkh1pazz_ixmt1/phase1/feasibility-report.md +0 -160
  125. package/development/projects/proj_mkh4jvnb_z7rwf/phase1/feasibility-report.md +0 -160
  126. package/development/projects/proj_mkh4jxkd_ewz5a/phase1/feasibility-report.md +0 -160
  127. package/development/projects/proj_mkh4k84n_ni73k/phase1/feasibility-report.md +0 -160
  128. package/development/projects/proj_mkh4wfyd_u9w88/phase1/feasibility-report.md +0 -160
  129. package/development/projects/proj_mkh4wsbo_iahvf/development/projects/proj_mkh4xbpg_4na5w/phase1/feasibility-report.md +0 -160
  130. package/development/projects/proj_mkh4wsbo_iahvf/phase1/feasibility-report.md +0 -160
  131. package/development/projects/proj_mkh4xulg_1ka8x/phase1/feasibility-report.md +0 -160
  132. package/development/projects/proj_mkh4xwhj_gch8j/phase1/feasibility-report.md +0 -160
  133. package/development/projects/proj_mkh4y2qk_9lm8z/phase1/feasibility-report.md +0 -160
  134. package/development/projects/proj_mkh4y2qk_9lm8z/phase2/requirements.md +0 -226
  135. package/development/projects/proj_mkh4y2qk_9lm8z/phase3/PRD.md +0 -345
  136. package/development/projects/proj_mkh4y2qk_9lm8z/phase3/TASK_PLAN.md +0 -284
  137. package/development/projects/proj_mkh4y2qk_9lm8z/phase3/prototype/README.md +0 -14
  138. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/DEVELOPMENT_LOG.md +0 -35
  139. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/TASKS.md +0 -34
  140. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/.env.example +0 -5
  141. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/README.md +0 -60
  142. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/package.json +0 -25
  143. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/index.js +0 -70
  144. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/routes/index.js +0 -48
  145. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/health.test.js +0 -20
  146. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/jest.config.js +0 -21
  147. package/development/projects/proj_mkh7veqg_3lypc/phase1/feasibility-report.md +0 -160
  148. package/development/projects/proj_mkh7veqg_3lypc/phase2/requirements.md +0 -226
  149. package/development/projects/proj_mkh7veqg_3lypc/phase3/PRD.md +0 -345
  150. package/development/projects/proj_mkh7veqg_3lypc/phase3/TASK_PLAN.md +0 -284
  151. package/development/projects/proj_mkh7veqg_3lypc/phase3/prototype/README.md +0 -14
  152. package/development/projects/proj_mkh8k8fo_rmqn5/phase1/feasibility-report.md +0 -160
  153. package/development/projects/proj_mkh8xyhy_1vshq/phase1/feasibility-report.md +0 -178
  154. package/development/projects/proj_mkh8zddd_dhamf/phase1/feasibility-report.md +0 -377
  155. package/development/projects/proj_mkh8zddd_dhamf/phase2/requirements.md +0 -442
  156. package/development/projects/proj_mkh8zddd_dhamf/phase3/api-design.md +0 -800
  157. package/development/projects/proj_mkh8zddd_dhamf/phase3/architecture.md +0 -625
  158. package/development/projects/proj_mkh8zddd_dhamf/phase3/data-model.md +0 -830
  159. package/development/projects/proj_mkh8zddd_dhamf/phase3/risks.md +0 -957
  160. package/development/projects/proj_mkh8zddd_dhamf/phase3/wbs.md +0 -381
  161. package/development/todos/.state.json +0 -19
  162. package/development/todos/INDEX.md +0 -63
  163. package/development/todos/active/_README.md +0 -49
  164. package/development/todos/archived/_README.md +0 -11
  165. package/development/todos/backlog/_README.md +0 -11
  166. package/development/todos/backlog/mcp-integration.md +0 -35
  167. package/development/todos/completed/_README.md +0 -11
  168. package/development/todos/completed/boris-optimizations.md +0 -39
  169. package/development/todos/completed/develop/local-knowledge-index.md +0 -85
  170. package/development/todos/completed/develop/todo-system.md +0 -47
  171. package/development/todos/completed/develop/web-search-integration.md +0 -83
  172. package/development/todos/completed/test/phase1-e2e-test.md +0 -103
  173. package/docs/DEVELOPMENT.md +0 -461
  174. package/docs/MARKETPLACE.md +0 -352
  175. package/docs/RELEASE.md +0 -93
  176. package/jest.config.js +0 -63
  177. package/lib/commands.js +0 -3588
  178. package/lib/config-manager.js +0 -441
  179. package/lib/config-schema.js +0 -408
  180. package/lib/config-validator.js +0 -330
  181. package/lib/config.js +0 -122
  182. package/lib/errors.js +0 -305
  183. package/lib/incremental-sync.js +0 -274
  184. package/lib/marketplace.js +0 -487
  185. package/lib/migrations.js +0 -154
  186. package/lib/permission-audit.js +0 -255
  187. package/lib/quality-gate.js +0 -431
  188. package/lib/quality-rules.js +0 -373
  189. package/lib/utils.js +0 -150
  190. package/lib/version-check.js +0 -169
  191. package/lib/version-manifest.js +0 -171
  192. package/project-paradigm.md +0 -313
  193. package/prompts/how-to-find.md +0 -163
  194. package/prompts/linus-architect.md +0 -71
  195. package/prompts/software-architect.md +0 -173
  196. package/prompts/web-designer.md +0 -249
  197. package/scripts/fix-hooks.mjs +0 -97
  198. package/scripts/sync-external.mjs +0 -298
  199. package/scripts/sync-to-home.sh +0 -108
  200. package/scripts/update-registry.mjs +0 -325
  201. package/sources.yaml +0 -83
  202. package/tests/README.md +0 -263
  203. package/tests/commands.test.js +0 -1086
  204. package/tests/config-manager.test.js +0 -677
  205. package/tests/config-schema.test.js +0 -425
  206. package/tests/config-validator.test.js +0 -436
  207. package/tests/config.test.js +0 -100
  208. package/tests/errors.test.js +0 -477
  209. package/tests/manual/phase1-e2e.sh +0 -389
  210. package/tests/manual/phase2-test-cases.md +0 -311
  211. package/tests/manual/phase3-test-cases.md +0 -309
  212. package/tests/manual/phase4-test-cases.md +0 -414
  213. package/tests/manual/test-cases.md +0 -417
  214. package/tests/marketplace.test.js +0 -420
  215. package/tests/migrations.test.js +0 -187
  216. package/tests/quality-gate.test.js +0 -679
  217. package/tests/quality-rules.test.js +0 -619
  218. package/tests/sync-external.test.js +0 -214
  219. package/tests/update-registry.test.js +0 -251
  220. package/tests/utils.test.js +0 -171
  221. package/tests/version-check.test.js +0 -75
  222. package/tests/web-search.test.js +0 -392
  223. 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
- });