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.
- package/.claude/hooks/hook-registry.json +0 -15
- package/.claude/rules/coding-style.md +18 -7
- package/.claude/rules/hooks.md +15 -4
- package/.claude/rules/performance.md +15 -5
- package/.claude/rules/security.md +140 -4
- package/.claude/rules/testing.md +138 -9
- package/.claude/rules/web-design-standard.md +16 -5
- package/.claude/skills/algorithmic-art/metadata.yaml +28 -0
- package/.claude/skills/api-tester/SKILL.md +61 -0
- package/.claude/skills/api-tester/examples/basic.md +3 -0
- package/.claude/skills/api-tester/metadata.yaml +30 -0
- package/.claude/skills/api-tester/templates/default.md +3 -0
- package/.claude/skills/brand-guidelines/metadata.yaml +26 -0
- package/.claude/skills/canvas-design/metadata.yaml +27 -0
- package/.claude/skills/code-reviewer-123/SKILL.md +61 -0
- package/.claude/skills/code-reviewer-123/examples/basic.md +3 -0
- package/.claude/skills/code-reviewer-123/metadata.yaml +30 -0
- package/.claude/skills/code-reviewer-123/templates/default.md +3 -0
- package/.claude/skills/doc-coauthoring/metadata.yaml +27 -0
- package/.claude/skills/docx/metadata.yaml +30 -0
- package/.claude/skills/frontend-design/metadata.yaml +28 -0
- package/.claude/skills/internal-comms/metadata.yaml +28 -0
- package/.claude/skills/mcp-builder/metadata.yaml +26 -0
- package/.claude/skills/my-skill/SKILL.md +61 -0
- package/.claude/skills/my-skill/examples/basic.md +3 -0
- package/.claude/skills/my-skill/metadata.yaml +30 -0
- package/.claude/skills/my-skill/templates/default.md +3 -0
- package/.claude/skills/pdf/metadata.yaml +29 -0
- package/.claude/skills/pptx/metadata.yaml +29 -0
- package/.claude/skills/react-best-practices/metadata.yaml +26 -0
- package/.claude/skills/react-node-practices/SKILL.md +409 -0
- package/.claude/skills/react-node-practices/metadata.yaml +56 -0
- package/.claude/skills/skill-creator/metadata.yaml +25 -0
- package/.claude/skills/slack-gif-creator/metadata.yaml +28 -0
- package/.claude/skills/test-skill-name/SKILL.md +61 -0
- package/.claude/skills/test-skill-name/examples/basic.md +3 -0
- package/.claude/skills/test-skill-name/metadata.yaml +30 -0
- package/.claude/skills/test-skill-name/templates/default.md +3 -0
- package/.claude/skills/test-workflow/metadata.yaml +32 -0
- package/.claude/skills/theme-factory/metadata.yaml +26 -0
- package/.claude/skills/threejs-fundamentals/metadata.yaml +27 -0
- package/.claude/skills/web-artifacts-builder/metadata.yaml +30 -0
- package/.claude/skills/web-design-guidelines/metadata.yaml +26 -0
- package/.claude/skills/webapp-testing/metadata.yaml +26 -0
- package/.claude/skills/xlsx/metadata.yaml +29 -0
- package/LICENSE +21 -0
- package/cli.js +1 -1
- package/package.json +25 -3
- package/.claude/.kickoff-hint.txt +0 -52
- package/.claude/.sumulige-claude-version +0 -1
- package/.claude/.version +0 -1
- package/.claude/AGENTS.md +0 -42
- package/.claude/ANCHORS.md +0 -40
- package/.claude/CLAUDE.md +0 -138
- package/.claude/MEMORY.md +0 -69
- package/.claude/PROJECT_LOG.md +0 -101
- package/.claude/THINKING_CHAIN_GUIDE.md +0 -287
- package/.claude/USAGE.md +0 -175
- package/.claude/boris-optimizations.md +0 -167
- package/.claude/handoffs/INDEX.md +0 -21
- package/.claude/handoffs/LATEST.md +0 -76
- package/.claude/handoffs/handoff_2026-01-22T13-07-04-757Z.md +0 -76
- package/.claude/quality-gate.json +0 -82
- package/.claude/rag/skill-index.json +0 -135
- package/.claude/settings.json +0 -99
- package/.claude/settings.local.json +0 -175
- package/.claude/templates/PROJECT_KICKOFF.md +0 -89
- package/.claude/templates/PROJECT_PROPOSAL.md +0 -227
- package/.claude/templates/TASK_PLAN.md +0 -121
- package/.claude/templates/hooks/README.md +0 -302
- package/.claude/templates/hooks/hook.sh.template +0 -94
- package/.claude/templates/hooks/user-prompt-submit.cjs.template +0 -116
- package/.claude/templates/hooks/user-response-submit.cjs.template +0 -94
- package/.claude/templates/hooks/validate.js +0 -173
- package/.claude/templates/tasks/develop.md +0 -69
- package/.claude/templates/tasks/research.md +0 -64
- package/.claude/templates/tasks/test.md +0 -96
- package/.claude/thinking-routes/.last-sync +0 -1
- package/.claude/thinking-routes/QUICKREF.md +0 -98
- package/.claude/workflow/document-scanner.js +0 -426
- package/.claude/workflow/knowledge-engine.js +0 -941
- package/.claude/workflow/notebooklm/browser.js +0 -1028
- package/.claude/workflow/phases/phase1-research.js +0 -578
- package/.claude/workflow/phases/phase1-research.ts +0 -465
- package/.claude/workflow/phases/phase2-approve.js +0 -722
- package/.claude/workflow/phases/phase3-plan.js +0 -1200
- package/.claude/workflow/phases/phase4-develop.js +0 -894
- package/.claude/workflow/search-cache.js +0 -230
- package/.claude/workflow/templates/approval.md +0 -315
- package/.claude/workflow/templates/development.md +0 -377
- package/.claude/workflow/templates/planning.md +0 -328
- package/.claude/workflow/templates/research.md +0 -250
- package/.claude/workflow/types.js +0 -37
- package/.claude/workflow/web-search.js +0 -278
- package/.claude-plugin/marketplace.json +0 -71
- package/.github/workflows/sync-skills.yml +0 -74
- package/.versionrc +0 -25
- package/AGENTS.md +0 -580
- package/CHANGELOG.md +0 -481
- package/CLAUDE-template.md +0 -114
- package/DEV_TOOLS_GUIDE.md +0 -190
- package/PROJECT_STRUCTURE.md +0 -266
- package/Q&A.md +0 -325
- package/config/defaults.json +0 -34
- package/config/official-skills.json +0 -183
- package/config/quality-gate.json +0 -67
- package/config/skill-categories.json +0 -40
- package/config/version-manifest.json +0 -85
- package/demos/power-3d-scatter.html +0 -683
- package/development/cache/web-search/search_1193d605f8eb364651fc2f2041b58a31.json +0 -36
- package/development/cache/web-search/search_3798bf06960edc125f744a1abb5b72c5.json +0 -36
- package/development/cache/web-search/search_37c7d4843a53f0d83f1122a6f908a2a3.json +0 -36
- package/development/cache/web-search/search_44166fa0153709ee168485a22aa0ab40.json +0 -36
- package/development/cache/web-search/search_4deaebb1f77e86a8ca066dc5a49c59fd.json +0 -36
- package/development/cache/web-search/search_94da91789466070a7f545612e73c7372.json +0 -36
- package/development/cache/web-search/search_dd5de8491b8b803a3cb01339cd210fb0.json +0 -36
- package/development/knowledge-base/.index.clean.json +0 -1
- package/development/knowledge-base/.index.json +0 -486
- package/development/knowledge-base/test-best-practices.md +0 -29
- package/development/projects/proj_mkh1pazz_ixmt1/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4jvnb_z7rwf/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4jxkd_ewz5a/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4k84n_ni73k/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4wfyd_u9w88/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4wsbo_iahvf/development/projects/proj_mkh4xbpg_4na5w/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4wsbo_iahvf/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4xulg_1ka8x/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4xwhj_gch8j/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4y2qk_9lm8z/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh4y2qk_9lm8z/phase2/requirements.md +0 -226
- package/development/projects/proj_mkh4y2qk_9lm8z/phase3/PRD.md +0 -345
- package/development/projects/proj_mkh4y2qk_9lm8z/phase3/TASK_PLAN.md +0 -284
- package/development/projects/proj_mkh4y2qk_9lm8z/phase3/prototype/README.md +0 -14
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/DEVELOPMENT_LOG.md +0 -35
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/TASKS.md +0 -34
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/.env.example +0 -5
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/README.md +0 -60
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/package.json +0 -25
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/index.js +0 -70
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/routes/index.js +0 -48
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/health.test.js +0 -20
- package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/jest.config.js +0 -21
- package/development/projects/proj_mkh7veqg_3lypc/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh7veqg_3lypc/phase2/requirements.md +0 -226
- package/development/projects/proj_mkh7veqg_3lypc/phase3/PRD.md +0 -345
- package/development/projects/proj_mkh7veqg_3lypc/phase3/TASK_PLAN.md +0 -284
- package/development/projects/proj_mkh7veqg_3lypc/phase3/prototype/README.md +0 -14
- package/development/projects/proj_mkh8k8fo_rmqn5/phase1/feasibility-report.md +0 -160
- package/development/projects/proj_mkh8xyhy_1vshq/phase1/feasibility-report.md +0 -178
- package/development/projects/proj_mkh8zddd_dhamf/phase1/feasibility-report.md +0 -377
- package/development/projects/proj_mkh8zddd_dhamf/phase2/requirements.md +0 -442
- package/development/projects/proj_mkh8zddd_dhamf/phase3/api-design.md +0 -800
- package/development/projects/proj_mkh8zddd_dhamf/phase3/architecture.md +0 -625
- package/development/projects/proj_mkh8zddd_dhamf/phase3/data-model.md +0 -830
- package/development/projects/proj_mkh8zddd_dhamf/phase3/risks.md +0 -957
- package/development/projects/proj_mkh8zddd_dhamf/phase3/wbs.md +0 -381
- package/development/todos/.state.json +0 -19
- package/development/todos/INDEX.md +0 -63
- package/development/todos/active/_README.md +0 -49
- package/development/todos/archived/_README.md +0 -11
- package/development/todos/backlog/_README.md +0 -11
- package/development/todos/backlog/mcp-integration.md +0 -35
- package/development/todos/completed/_README.md +0 -11
- package/development/todos/completed/boris-optimizations.md +0 -39
- package/development/todos/completed/develop/local-knowledge-index.md +0 -85
- package/development/todos/completed/develop/todo-system.md +0 -47
- package/development/todos/completed/develop/web-search-integration.md +0 -83
- package/development/todos/completed/test/phase1-e2e-test.md +0 -103
- package/docs/DEVELOPMENT.md +0 -461
- package/docs/MARKETPLACE.md +0 -352
- package/docs/RELEASE.md +0 -93
- package/jest.config.js +0 -63
- package/lib/commands.js +0 -3588
- package/lib/config-manager.js +0 -441
- package/lib/config-schema.js +0 -408
- package/lib/config-validator.js +0 -330
- package/lib/config.js +0 -122
- package/lib/errors.js +0 -305
- package/lib/incremental-sync.js +0 -274
- package/lib/marketplace.js +0 -487
- package/lib/migrations.js +0 -154
- package/lib/permission-audit.js +0 -255
- package/lib/quality-gate.js +0 -431
- package/lib/quality-rules.js +0 -373
- package/lib/utils.js +0 -150
- package/lib/version-check.js +0 -169
- package/lib/version-manifest.js +0 -171
- package/project-paradigm.md +0 -313
- package/prompts/how-to-find.md +0 -163
- package/prompts/linus-architect.md +0 -71
- package/prompts/software-architect.md +0 -173
- package/prompts/web-designer.md +0 -249
- package/scripts/fix-hooks.mjs +0 -97
- package/scripts/sync-external.mjs +0 -298
- package/scripts/sync-to-home.sh +0 -108
- package/scripts/update-registry.mjs +0 -325
- package/sources.yaml +0 -83
- package/tests/README.md +0 -263
- package/tests/commands.test.js +0 -1086
- package/tests/config-manager.test.js +0 -677
- package/tests/config-schema.test.js +0 -425
- package/tests/config-validator.test.js +0 -436
- package/tests/config.test.js +0 -100
- package/tests/errors.test.js +0 -477
- package/tests/manual/phase1-e2e.sh +0 -389
- package/tests/manual/phase2-test-cases.md +0 -311
- package/tests/manual/phase3-test-cases.md +0 -309
- package/tests/manual/phase4-test-cases.md +0 -414
- package/tests/manual/test-cases.md +0 -417
- package/tests/marketplace.test.js +0 -420
- package/tests/migrations.test.js +0 -187
- package/tests/quality-gate.test.js +0 -679
- package/tests/quality-rules.test.js +0 -619
- package/tests/sync-external.test.js +0 -214
- package/tests/update-registry.test.js +0 -251
- package/tests/utils.test.js +0 -171
- package/tests/version-check.test.js +0 -75
- package/tests/web-search.test.js +0 -392
- package/thinkinglens-silent.md +0 -138
package/lib/errors.js
DELETED
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Structured Error Types
|
|
3
|
-
*
|
|
4
|
-
* Provides structured error information with recovery hints.
|
|
5
|
-
* All errors include:
|
|
6
|
-
* - Error code for programmatic handling
|
|
7
|
-
* - Severity level (info/warn/error/critical)
|
|
8
|
-
* - Details object with context
|
|
9
|
-
* - Hints array with recovery suggestions
|
|
10
|
-
* - Optional documentation URL
|
|
11
|
-
*
|
|
12
|
-
* @module lib/errors
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Base SMC Error class
|
|
17
|
-
*/
|
|
18
|
-
class SMCError extends Error {
|
|
19
|
-
/**
|
|
20
|
-
* @param {string} message - Error message
|
|
21
|
-
* @param {Object} options - Error options
|
|
22
|
-
* @param {string} options.code - Error code (e.g., 'ERR_CONFIG')
|
|
23
|
-
* @param {string} options.severity - Severity level: 'info' | 'warn' | 'error' | 'critical'
|
|
24
|
-
* @param {Object} options.details - Additional error details
|
|
25
|
-
* @param {string[]} options.hints - Recovery hints
|
|
26
|
-
* @param {string} options.docUrl - Documentation URL
|
|
27
|
-
*/
|
|
28
|
-
constructor(message, options = {}) {
|
|
29
|
-
super(message);
|
|
30
|
-
this.name = this.constructor.name;
|
|
31
|
-
this.code = options.code || 'ERR_UNKNOWN';
|
|
32
|
-
this.severity = options.severity || 'error';
|
|
33
|
-
this.details = options.details || {};
|
|
34
|
-
this.hints = options.hints || [];
|
|
35
|
-
this.docUrl = options.docUrl;
|
|
36
|
-
|
|
37
|
-
// Maintain proper stack trace
|
|
38
|
-
Error.captureStackTrace?.(this, this.constructor);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Convert error to JSON-serializable object
|
|
43
|
-
*/
|
|
44
|
-
toJSON() {
|
|
45
|
-
return {
|
|
46
|
-
name: this.name,
|
|
47
|
-
code: this.code,
|
|
48
|
-
message: this.message,
|
|
49
|
-
severity: this.severity,
|
|
50
|
-
details: this.details,
|
|
51
|
-
hints: this.hints,
|
|
52
|
-
docUrl: this.docUrl
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Format error for console output
|
|
58
|
-
*/
|
|
59
|
-
toString() {
|
|
60
|
-
let output = `[${this.code}] ${this.message}`;
|
|
61
|
-
if (this.hints.length > 0) {
|
|
62
|
-
output += '\n\nSuggestions:\n';
|
|
63
|
-
this.hints.forEach((h, i) => {
|
|
64
|
-
output += ` ${i + 1}. ${h}\n`;
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
if (this.docUrl) {
|
|
68
|
-
output += `\nDocs: ${this.docUrl}\n`;
|
|
69
|
-
}
|
|
70
|
-
return output;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Check if this error has a specific severity level or higher
|
|
75
|
-
* @param {string} minSeverity - Minimum severity to check against
|
|
76
|
-
* @returns {boolean}
|
|
77
|
-
*/
|
|
78
|
-
hasSeverity(minSeverity) {
|
|
79
|
-
const levels = { info: 0, warn: 1, error: 2, critical: 3 };
|
|
80
|
-
return levels[this.severity] >= levels[minSeverity];
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Configuration-related errors
|
|
86
|
-
* Used for config file parsing, validation, and loading issues
|
|
87
|
-
*/
|
|
88
|
-
class ConfigError extends SMCError {
|
|
89
|
-
/**
|
|
90
|
-
* @param {string} message - Error message
|
|
91
|
-
* @param {Object[]} errors - Array of validation errors
|
|
92
|
-
* @param {string[]} fixes - Array of auto-fix suggestions
|
|
93
|
-
* @param {Object} options - Additional options passed to SMCError
|
|
94
|
-
*/
|
|
95
|
-
constructor(message, errors = [], fixes = [], options = {}) {
|
|
96
|
-
super(message, {
|
|
97
|
-
code: 'ERR_CONFIG',
|
|
98
|
-
severity: 'critical',
|
|
99
|
-
...options
|
|
100
|
-
});
|
|
101
|
-
this.errors = errors;
|
|
102
|
-
this.fixes = fixes;
|
|
103
|
-
this.details = {
|
|
104
|
-
errorCount: errors.length,
|
|
105
|
-
fixCount: fixes.length,
|
|
106
|
-
criticalCount: errors.filter(e => e.severity === 'critical').length,
|
|
107
|
-
errorCount: errors.length,
|
|
108
|
-
fixCount: fixes.length,
|
|
109
|
-
criticalCount: errors.filter(e => e.severity === 'critical').length
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Format config error for console output
|
|
115
|
-
*/
|
|
116
|
-
toString() {
|
|
117
|
-
let output = `ConfigError: ${this.message}\n`;
|
|
118
|
-
|
|
119
|
-
if (this.details.errorCount > 0) {
|
|
120
|
-
output += `\nErrors (${this.details.errorCount}):\n`;
|
|
121
|
-
this.errors.forEach(e => {
|
|
122
|
-
const icon = e.severity === 'critical' ? 'X' : e.severity === 'error' ? 'E' : 'W';
|
|
123
|
-
output += ` [${icon}] ${e.path}: ${e.message}\n`;
|
|
124
|
-
if (e.fix) {
|
|
125
|
-
output += ` Fix: ${e.fix}\n`;
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (this.details.fixCount > 0) {
|
|
131
|
-
output += `\nSuggested fixes:\n`;
|
|
132
|
-
this.fixes.forEach((f, i) => {
|
|
133
|
-
output += ` ${i + 1}. ${f}\n`;
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return output;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Validation errors
|
|
143
|
-
* Used when data validation fails
|
|
144
|
-
*/
|
|
145
|
-
class ValidationError extends SMCError {
|
|
146
|
-
constructor(message, options = {}) {
|
|
147
|
-
super(message, {
|
|
148
|
-
code: 'ERR_VALIDATION',
|
|
149
|
-
severity: 'error',
|
|
150
|
-
...options
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Quality gate errors
|
|
157
|
-
* Used when quality checks fail
|
|
158
|
-
*/
|
|
159
|
-
class QualityGateError extends SMCError {
|
|
160
|
-
/**
|
|
161
|
-
* @param {string} message - Error message
|
|
162
|
-
* @param {Object} results - Quality check results
|
|
163
|
-
* @param {Object} options - Additional options
|
|
164
|
-
*/
|
|
165
|
-
constructor(message, results = {}, options = {}) {
|
|
166
|
-
super(message, {
|
|
167
|
-
code: 'ERR_QUALITY_GATE',
|
|
168
|
-
severity: 'error',
|
|
169
|
-
...options
|
|
170
|
-
});
|
|
171
|
-
this.results = results;
|
|
172
|
-
this.details = {
|
|
173
|
-
passed: results.passed || false,
|
|
174
|
-
total: results.summary?.total || 0,
|
|
175
|
-
critical: results.summary?.critical || 0,
|
|
176
|
-
error: results.summary?.error || 0,
|
|
177
|
-
warn: results.summary?.warn || 0
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Migration errors
|
|
184
|
-
* Used during config migration
|
|
185
|
-
*/
|
|
186
|
-
class MigrationError extends SMCError {
|
|
187
|
-
constructor(message, options = {}) {
|
|
188
|
-
super(message, {
|
|
189
|
-
code: 'ERR_MIGRATION',
|
|
190
|
-
severity: 'critical',
|
|
191
|
-
...options
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* File operation errors
|
|
198
|
-
* Used for file read/write issues
|
|
199
|
-
*/
|
|
200
|
-
class FileError extends SMCError {
|
|
201
|
-
constructor(message, filePath, options = {}) {
|
|
202
|
-
super(message, {
|
|
203
|
-
code: 'ERR_FILE',
|
|
204
|
-
severity: 'error',
|
|
205
|
-
...options
|
|
206
|
-
});
|
|
207
|
-
this.filePath = filePath;
|
|
208
|
-
this.details.file = filePath;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Rule execution errors
|
|
214
|
-
* Used when a quality rule fails to execute
|
|
215
|
-
*/
|
|
216
|
-
class RuleError extends SMCError {
|
|
217
|
-
constructor(message, ruleId, options = {}) {
|
|
218
|
-
super(message, {
|
|
219
|
-
code: 'ERR_RULE',
|
|
220
|
-
severity: 'warn',
|
|
221
|
-
...options
|
|
222
|
-
});
|
|
223
|
-
this.ruleId = ruleId;
|
|
224
|
-
this.details.rule = ruleId;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Parse error details from AJV validation output
|
|
230
|
-
* @param {Object[]} ajvErrors - AJV validation errors
|
|
231
|
-
* @returns {Object[]} Parsed error objects
|
|
232
|
-
*/
|
|
233
|
-
function parseAJVErrors(ajvErrors) {
|
|
234
|
-
return ajvErrors.map(error => {
|
|
235
|
-
const path = error.instancePath || 'root';
|
|
236
|
-
const message = error.message || 'Validation failed';
|
|
237
|
-
|
|
238
|
-
return {
|
|
239
|
-
path,
|
|
240
|
-
message,
|
|
241
|
-
severity: getSeverityFromKeyword(error.keyword),
|
|
242
|
-
expected: error.schema?.type || error.schema?.enum?.join('|'),
|
|
243
|
-
actual: error.data,
|
|
244
|
-
keyword: error.keyword,
|
|
245
|
-
fix: generateFixFromError(error)
|
|
246
|
-
};
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Map AJV keyword to severity level
|
|
252
|
-
* @param {string} keyword - AJV error keyword
|
|
253
|
-
* @returns {string} Severity level
|
|
254
|
-
*/
|
|
255
|
-
function getSeverityFromKeyword(keyword) {
|
|
256
|
-
const severityMap = {
|
|
257
|
-
required: 'critical',
|
|
258
|
-
type: 'error',
|
|
259
|
-
enum: 'error',
|
|
260
|
-
pattern: 'warn',
|
|
261
|
-
format: 'warn',
|
|
262
|
-
minimum: 'warn',
|
|
263
|
-
maximum: 'warn',
|
|
264
|
-
minLength: 'warn',
|
|
265
|
-
maxLength: 'warn'
|
|
266
|
-
};
|
|
267
|
-
return severityMap[keyword] || 'warn';
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Generate auto-fix suggestion from AJV error
|
|
272
|
-
* @param {Object} error - AJV error object
|
|
273
|
-
* @returns {string|null} Fix suggestion
|
|
274
|
-
*/
|
|
275
|
-
function generateFixFromError(error) {
|
|
276
|
-
const fixes = {
|
|
277
|
-
required: `Add missing field: ${error.params?.missingProperty}`,
|
|
278
|
-
pattern: `Value must match pattern: ${error.schema?.pattern}`,
|
|
279
|
-
enum: `Value must be one of: ${error.schema?.enum?.join(', ')}`,
|
|
280
|
-
type: `Change type to: ${error.schema?.type}`,
|
|
281
|
-
minimum: `Value must be >= ${error.schema?.minimum}`,
|
|
282
|
-
maximum: `Value must be <= ${error.schema?.maximum}`,
|
|
283
|
-
minLength: `Length must be >= ${error.schema?.minLength}`,
|
|
284
|
-
maxLength: `Length must be <= ${error.schema?.maxLength}`
|
|
285
|
-
};
|
|
286
|
-
return fixes[error.keyword] || null;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
module.exports = {
|
|
290
|
-
// Base class
|
|
291
|
-
SMCError,
|
|
292
|
-
|
|
293
|
-
// Specific error types
|
|
294
|
-
ConfigError,
|
|
295
|
-
ValidationError,
|
|
296
|
-
QualityGateError,
|
|
297
|
-
MigrationError,
|
|
298
|
-
FileError,
|
|
299
|
-
RuleError,
|
|
300
|
-
|
|
301
|
-
// Utility functions
|
|
302
|
-
parseAJVErrors,
|
|
303
|
-
getSeverityFromKeyword,
|
|
304
|
-
generateFixFromError
|
|
305
|
-
};
|
package/lib/incremental-sync.js
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Incremental Sync Manager
|
|
3
|
-
*
|
|
4
|
-
* 增量同步功能,只同步变更的文件
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const versionManifest = require('./version-manifest');
|
|
10
|
-
|
|
11
|
-
const TEMPLATE_DIR = path.join(__dirname, '../template');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 复制文件
|
|
15
|
-
*/
|
|
16
|
-
function copyFile(src, dest) {
|
|
17
|
-
const dir = path.dirname(dest);
|
|
18
|
-
if (!fs.existsSync(dir)) {
|
|
19
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
20
|
-
}
|
|
21
|
-
fs.copyFileSync(src, dest);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 合并 JSON 配置
|
|
26
|
-
*/
|
|
27
|
-
function mergeJsonConfig(src, dest) {
|
|
28
|
-
let existing = {};
|
|
29
|
-
if (fs.existsSync(dest)) {
|
|
30
|
-
try {
|
|
31
|
-
existing = JSON.parse(fs.readFileSync(dest, 'utf-8'));
|
|
32
|
-
} catch (e) {
|
|
33
|
-
existing = {};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const newConfig = JSON.parse(fs.readFileSync(src, 'utf-8'));
|
|
38
|
-
|
|
39
|
-
// 深度合并
|
|
40
|
-
const merged = deepMerge(existing, newConfig);
|
|
41
|
-
|
|
42
|
-
const dir = path.dirname(dest);
|
|
43
|
-
if (!fs.existsSync(dir)) {
|
|
44
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
45
|
-
}
|
|
46
|
-
fs.writeFileSync(dest, JSON.stringify(merged, null, 2));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 深度合并对象
|
|
51
|
-
*/
|
|
52
|
-
function deepMerge(target, source) {
|
|
53
|
-
const result = { ...target };
|
|
54
|
-
|
|
55
|
-
for (const key of Object.keys(source)) {
|
|
56
|
-
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
57
|
-
result[key] = deepMerge(result[key] || {}, source[key]);
|
|
58
|
-
} else {
|
|
59
|
-
result[key] = source[key];
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return result;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 应用单个变更
|
|
68
|
-
*/
|
|
69
|
-
function applyChange(change, projectDir, rules) {
|
|
70
|
-
const rule = rules[change.type];
|
|
71
|
-
if (!rule) return { success: false, reason: 'Unknown change type' };
|
|
72
|
-
|
|
73
|
-
const action = rule[change.action];
|
|
74
|
-
if (!action) return { success: false, reason: 'Unknown action' };
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
switch (change.type) {
|
|
78
|
-
case 'hook':
|
|
79
|
-
return applyHookChange(change, projectDir, action);
|
|
80
|
-
case 'config':
|
|
81
|
-
return applyConfigChange(change, projectDir, action);
|
|
82
|
-
case 'command':
|
|
83
|
-
return applyCommandChange(change, projectDir, action);
|
|
84
|
-
case 'lib':
|
|
85
|
-
return applyLibChange(change, projectDir, action);
|
|
86
|
-
case 'skill':
|
|
87
|
-
return applySkillChange(change, projectDir, action);
|
|
88
|
-
default:
|
|
89
|
-
return { success: true, skipped: true };
|
|
90
|
-
}
|
|
91
|
-
} catch (e) {
|
|
92
|
-
return { success: false, reason: e.message };
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* 应用 hook 变更
|
|
98
|
-
*/
|
|
99
|
-
function applyHookChange(change, projectDir, action) {
|
|
100
|
-
const hookName = change.name;
|
|
101
|
-
const src = path.join(TEMPLATE_DIR, '.claude/hooks', `${hookName}.cjs`);
|
|
102
|
-
const dest = path.join(projectDir, '.claude/hooks', `${hookName}.cjs`);
|
|
103
|
-
|
|
104
|
-
if (action === 'copy') {
|
|
105
|
-
if (fs.existsSync(src)) {
|
|
106
|
-
copyFile(src, dest);
|
|
107
|
-
return { success: true, action: 'copied', file: dest };
|
|
108
|
-
}
|
|
109
|
-
return { success: false, reason: 'Source file not found' };
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (action === 'delete') {
|
|
113
|
-
if (fs.existsSync(dest)) {
|
|
114
|
-
fs.unlinkSync(dest);
|
|
115
|
-
return { success: true, action: 'deleted', file: dest };
|
|
116
|
-
}
|
|
117
|
-
return { success: true, skipped: true };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return { success: true, skipped: true };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* 应用配置变更
|
|
125
|
-
*/
|
|
126
|
-
function applyConfigChange(change, projectDir, action) {
|
|
127
|
-
const configName = change.name;
|
|
128
|
-
let src, dest;
|
|
129
|
-
|
|
130
|
-
if (configName === 'settings.json') {
|
|
131
|
-
src = path.join(TEMPLATE_DIR, '.claude/settings.json');
|
|
132
|
-
dest = path.join(projectDir, '.claude/settings.json');
|
|
133
|
-
} else if (configName === 'hook-registry.json') {
|
|
134
|
-
src = path.join(TEMPLATE_DIR, '.claude/hooks/hook-registry.json');
|
|
135
|
-
dest = path.join(projectDir, '.claude/hooks/hook-registry.json');
|
|
136
|
-
} else {
|
|
137
|
-
src = path.join(TEMPLATE_DIR, '.claude', configName);
|
|
138
|
-
dest = path.join(projectDir, '.claude', configName);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (action === 'copy') {
|
|
142
|
-
if (fs.existsSync(src)) {
|
|
143
|
-
copyFile(src, dest);
|
|
144
|
-
return { success: true, action: 'copied', file: dest };
|
|
145
|
-
}
|
|
146
|
-
return { success: false, reason: 'Source file not found' };
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (action === 'merge') {
|
|
150
|
-
if (fs.existsSync(src)) {
|
|
151
|
-
mergeJsonConfig(src, dest);
|
|
152
|
-
return { success: true, action: 'merged', file: dest };
|
|
153
|
-
}
|
|
154
|
-
return { success: false, reason: 'Source file not found' };
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return { success: true, skipped: true };
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* 应用命令变更
|
|
162
|
-
*/
|
|
163
|
-
function applyCommandChange(change, projectDir, action) {
|
|
164
|
-
const commandName = change.name;
|
|
165
|
-
const src = path.join(TEMPLATE_DIR, '.claude/commands', `${commandName}.md`);
|
|
166
|
-
const dest = path.join(projectDir, '.claude/commands', `${commandName}.md`);
|
|
167
|
-
|
|
168
|
-
if (action === 'copy') {
|
|
169
|
-
if (fs.existsSync(src)) {
|
|
170
|
-
copyFile(src, dest);
|
|
171
|
-
return { success: true, action: 'copied', file: dest };
|
|
172
|
-
}
|
|
173
|
-
return { success: false, reason: 'Source file not found' };
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return { success: true, skipped: true };
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* 应用库文件变更
|
|
181
|
-
*/
|
|
182
|
-
function applyLibChange(change, projectDir, action) {
|
|
183
|
-
const libPath = change.name;
|
|
184
|
-
const src = path.join(TEMPLATE_DIR, '.claude', libPath);
|
|
185
|
-
const dest = path.join(projectDir, '.claude', libPath);
|
|
186
|
-
|
|
187
|
-
if (action === 'copy') {
|
|
188
|
-
if (fs.existsSync(src)) {
|
|
189
|
-
copyFile(src, dest);
|
|
190
|
-
return { success: true, action: 'copied', file: dest };
|
|
191
|
-
}
|
|
192
|
-
return { success: false, reason: 'Source file not found' };
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return { success: true, skipped: true };
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* 应用技能变更
|
|
200
|
-
*/
|
|
201
|
-
function applySkillChange(change, projectDir, action) {
|
|
202
|
-
// 技能同步由现有的 sync 命令处理
|
|
203
|
-
return { success: true, skipped: true, reason: 'Skills handled by full sync' };
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* 执行增量同步
|
|
208
|
-
*/
|
|
209
|
-
function incrementalSync(projectDir, options = {}) {
|
|
210
|
-
const summary = versionManifest.getUpdateSummary(projectDir);
|
|
211
|
-
|
|
212
|
-
if (!summary.needsUpdate) {
|
|
213
|
-
return {
|
|
214
|
-
success: true,
|
|
215
|
-
message: 'Already up to date',
|
|
216
|
-
changes: []
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (summary.isNewInstall) {
|
|
221
|
-
return {
|
|
222
|
-
success: false,
|
|
223
|
-
message: 'New installation detected. Please run full sync first.',
|
|
224
|
-
needsFullSync: true
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if (summary.hasBreakingChanges && !options.force) {
|
|
229
|
-
return {
|
|
230
|
-
success: false,
|
|
231
|
-
message: 'Breaking changes detected. Use --force to continue.',
|
|
232
|
-
hasBreakingChanges: true,
|
|
233
|
-
changes: summary.changes
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const rules = versionManifest.getSyncRules();
|
|
238
|
-
const results = [];
|
|
239
|
-
|
|
240
|
-
for (const versionChange of summary.changes) {
|
|
241
|
-
for (const change of versionChange.changes) {
|
|
242
|
-
const result = applyChange(change, projectDir, rules);
|
|
243
|
-
results.push({
|
|
244
|
-
version: versionChange.version,
|
|
245
|
-
change,
|
|
246
|
-
result
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// 更新项目版本
|
|
252
|
-
versionManifest.setProjectVersion(projectDir, summary.toVersion);
|
|
253
|
-
|
|
254
|
-
return {
|
|
255
|
-
success: true,
|
|
256
|
-
message: `Updated from ${summary.fromVersion} to ${summary.toVersion}`,
|
|
257
|
-
fromVersion: summary.fromVersion,
|
|
258
|
-
toVersion: summary.toVersion,
|
|
259
|
-
results: results
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* 检查更新
|
|
265
|
-
*/
|
|
266
|
-
function checkForUpdates(projectDir) {
|
|
267
|
-
return versionManifest.getUpdateSummary(projectDir);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
module.exports = {
|
|
271
|
-
incrementalSync,
|
|
272
|
-
checkForUpdates,
|
|
273
|
-
applyChange
|
|
274
|
-
};
|