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
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Update Marketplace Registry
|
|
4
|
-
*
|
|
5
|
-
* This script scans the skills directory and generates the marketplace.json
|
|
6
|
-
* registry file for Claude Code's native plugin system.
|
|
7
|
-
*
|
|
8
|
-
* Usage: node scripts/update-registry.mjs
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import fs from 'fs';
|
|
12
|
-
import path from 'path';
|
|
13
|
-
import { fileURLToPath } from 'url';
|
|
14
|
-
import { execSync } from 'child_process';
|
|
15
|
-
|
|
16
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
-
const __dirname = path.dirname(__filename);
|
|
18
|
-
const ROOT_DIR = path.join(__dirname, '..');
|
|
19
|
-
const MARKETPLACE_FILE = path.join(ROOT_DIR, '.claude-plugin', 'marketplace.json');
|
|
20
|
-
const SKILLS_DIR = path.join(ROOT_DIR, 'template', '.claude', 'skills');
|
|
21
|
-
const CATEGORIES_FILE = path.join(ROOT_DIR, 'config', 'skill-categories.json');
|
|
22
|
-
|
|
23
|
-
// ============================================================================
|
|
24
|
-
// Logging Utilities
|
|
25
|
-
// ============================================================================
|
|
26
|
-
|
|
27
|
-
const COLORS = {
|
|
28
|
-
reset: '\x1b[0m',
|
|
29
|
-
green: '\x1b[32m',
|
|
30
|
-
blue: '\x1b[34m',
|
|
31
|
-
yellow: '\x1b[33m',
|
|
32
|
-
gray: '\x1b[90m'
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
function log(message, color = 'reset') {
|
|
36
|
-
console.log(`${COLORS[color]}${message}${COLORS.reset}`);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// ============================================================================
|
|
40
|
-
// File System Utilities
|
|
41
|
-
// ============================================================================
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Recursively find all skill directories
|
|
45
|
-
*/
|
|
46
|
-
function findSkillDirs(dir, basePath = dir) {
|
|
47
|
-
if (!fs.existsSync(dir)) {
|
|
48
|
-
return [];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const skills = [];
|
|
52
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
53
|
-
|
|
54
|
-
for (const entry of entries) {
|
|
55
|
-
if (entry.isDirectory()) {
|
|
56
|
-
const fullPath = path.join(dir, entry.name);
|
|
57
|
-
|
|
58
|
-
// Skip template and examples directories
|
|
59
|
-
if (['template', 'examples', '__tests__'].includes(entry.name)) {
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Check if this is a skill directory (contains SKILL.md or metadata.yaml)
|
|
64
|
-
const hasSkillFile = fs.existsSync(path.join(fullPath, 'SKILL.md'));
|
|
65
|
-
const hasMetadata = fs.existsSync(path.join(fullPath, 'metadata.yaml'));
|
|
66
|
-
const hasSourceJson = fs.existsSync(path.join(fullPath, '.source.json'));
|
|
67
|
-
|
|
68
|
-
if (hasSkillFile || hasMetadata || hasSourceJson) {
|
|
69
|
-
const relativePath = path.relative(basePath, fullPath);
|
|
70
|
-
skills.push({
|
|
71
|
-
name: entry.name,
|
|
72
|
-
path: fullPath,
|
|
73
|
-
relativePath: relativePath,
|
|
74
|
-
hasSourceJson
|
|
75
|
-
});
|
|
76
|
-
} else {
|
|
77
|
-
// Recurse into subdirectories
|
|
78
|
-
skills.push(...findSkillDirs(fullPath, basePath));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return skills;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Parse YAML metadata file
|
|
88
|
-
*/
|
|
89
|
-
function parseMetadata(skillDir) {
|
|
90
|
-
const metadataPath = path.join(skillDir, 'metadata.yaml');
|
|
91
|
-
|
|
92
|
-
if (!fs.existsSync(metadataPath)) {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
const content = fs.readFileSync(metadataPath, 'utf8');
|
|
98
|
-
// Simple YAML parser for basic key: value format
|
|
99
|
-
const result = {};
|
|
100
|
-
let currentKey = null;
|
|
101
|
-
|
|
102
|
-
content.split('\n').forEach(line => {
|
|
103
|
-
const trimmed = line.trim();
|
|
104
|
-
|
|
105
|
-
// Skip comments and empty lines
|
|
106
|
-
if (!trimmed || trimmed.startsWith('#')) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Key: Value pair
|
|
111
|
-
const match = trimmed.match(/^([^:]+):\s*(.*)$/);
|
|
112
|
-
if (match) {
|
|
113
|
-
currentKey = match[1];
|
|
114
|
-
let value = match[2];
|
|
115
|
-
|
|
116
|
-
// Handle array values
|
|
117
|
-
if (value.startsWith('[')) {
|
|
118
|
-
try {
|
|
119
|
-
value = JSON.parse(value.replace(/'/g, '"'));
|
|
120
|
-
} catch (e) {
|
|
121
|
-
value = [];
|
|
122
|
-
}
|
|
123
|
-
} else if (value === '[]') {
|
|
124
|
-
value = [];
|
|
125
|
-
} else if (value === 'true') {
|
|
126
|
-
value = true;
|
|
127
|
-
} else if (value === 'false') {
|
|
128
|
-
value = false;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
result[currentKey] = value;
|
|
132
|
-
} else if (currentKey && trimmed.startsWith('-')) {
|
|
133
|
-
// Array item continuation
|
|
134
|
-
if (!Array.isArray(result[currentKey])) {
|
|
135
|
-
result[currentKey] = [];
|
|
136
|
-
}
|
|
137
|
-
result[currentKey].push(trimmed.slice(1).trim());
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
return result;
|
|
142
|
-
} catch (error) {
|
|
143
|
-
log(`Warning: Failed to parse ${metadataPath}`, 'yellow');
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Parse .source.json file
|
|
150
|
-
*/
|
|
151
|
-
function parseSourceJson(skillDir) {
|
|
152
|
-
const sourcePath = path.join(skillDir, '.source.json');
|
|
153
|
-
|
|
154
|
-
if (!fs.existsSync(sourcePath)) {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
try {
|
|
159
|
-
const content = fs.readFileSync(sourcePath, 'utf-8');
|
|
160
|
-
return JSON.parse(content);
|
|
161
|
-
} catch (error) {
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Get skill description from SKILL.md
|
|
168
|
-
*/
|
|
169
|
-
function getSkillDescription(skillDir) {
|
|
170
|
-
const skillPath = path.join(skillDir, 'SKILL.md');
|
|
171
|
-
|
|
172
|
-
if (!fs.existsSync(skillPath)) {
|
|
173
|
-
return null;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
try {
|
|
177
|
-
const content = fs.readFileSync(skillPath, 'utf-8');
|
|
178
|
-
// Extract first heading or first paragraph
|
|
179
|
-
const lines = content.split('\n');
|
|
180
|
-
|
|
181
|
-
for (const line of lines) {
|
|
182
|
-
const trimmed = line.trim();
|
|
183
|
-
// Skip title
|
|
184
|
-
if (trimmed.startsWith('#')) {
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
// Return first non-empty, non-comment line
|
|
188
|
-
if (trimmed && !trimmed.startsWith('>') && !trimmed.startsWith('<!--')) {
|
|
189
|
-
return trimmed.replace(/^>/, '').trim();
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return null;
|
|
194
|
-
} catch (error) {
|
|
195
|
-
return null;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Determine skill category
|
|
201
|
-
*/
|
|
202
|
-
function getSkillCategory(skillPath, categories) {
|
|
203
|
-
// Check if path contains a category
|
|
204
|
-
const pathParts = skillPath.split(path.sep);
|
|
205
|
-
|
|
206
|
-
for (const part of pathParts) {
|
|
207
|
-
if (categories[part]) {
|
|
208
|
-
return part;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return 'tools'; // Default category
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// ============================================================================
|
|
216
|
-
// Registry Generation
|
|
217
|
-
// ============================================================================
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Generate the marketplace.json registry
|
|
221
|
-
*/
|
|
222
|
-
function generateRegistry() {
|
|
223
|
-
log('📋 Generating Marketplace Registry', 'blue');
|
|
224
|
-
log('=====================================', 'gray');
|
|
225
|
-
log('');
|
|
226
|
-
|
|
227
|
-
// Load categories
|
|
228
|
-
let categories = {};
|
|
229
|
-
if (fs.existsSync(CATEGORIES_FILE)) {
|
|
230
|
-
categories = JSON.parse(fs.readFileSync(CATEGORIES_FILE, 'utf-8')).categories || {};
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// Find all skill directories
|
|
234
|
-
log('Scanning skills directory...', 'gray');
|
|
235
|
-
const skills = findSkillDirs(SKILLS_DIR);
|
|
236
|
-
log(`Found ${skills.length} skill(s)`, 'gray');
|
|
237
|
-
log('');
|
|
238
|
-
|
|
239
|
-
if (skills.length === 0) {
|
|
240
|
-
log('No skills found. Registry will be empty.', 'yellow');
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Build plugin entries
|
|
245
|
-
const pluginSkills = [];
|
|
246
|
-
|
|
247
|
-
for (const skill of skills) {
|
|
248
|
-
log(`Processing: ${skill.name}`, 'gray');
|
|
249
|
-
|
|
250
|
-
// Get metadata
|
|
251
|
-
const metadata = parseMetadata(skill.path);
|
|
252
|
-
const sourceJson = parseSourceJson(skill.path);
|
|
253
|
-
const description = metadata?.description || getSkillDescription(skill.path) || 'No description';
|
|
254
|
-
|
|
255
|
-
// Determine category
|
|
256
|
-
const category = metadata?.category || getSkillCategory(skill.relativePath, categories);
|
|
257
|
-
|
|
258
|
-
// Build relative path from .claude-plugin
|
|
259
|
-
const relativeFromPlugin = path.join('..', 'template', '.claude', 'skills', skill.relativePath);
|
|
260
|
-
|
|
261
|
-
pluginSkills.push({
|
|
262
|
-
name: skill.name,
|
|
263
|
-
description: description,
|
|
264
|
-
path: `./${relativeFromPlugin}`,
|
|
265
|
-
category: category,
|
|
266
|
-
external: !!sourceJson
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Build the full registry
|
|
271
|
-
const registry = {
|
|
272
|
-
name: 'smc-skills',
|
|
273
|
-
description: 'Sumulige Claude Agent Harness - Curated skill collection for AI coding agents',
|
|
274
|
-
homepage: 'https://github.com/sumulige/sumulige-claude',
|
|
275
|
-
owner: {
|
|
276
|
-
name: 'sumulige',
|
|
277
|
-
email: 'sumulige@example.com'
|
|
278
|
-
},
|
|
279
|
-
plugins: [
|
|
280
|
-
{
|
|
281
|
-
name: 'smc-skills',
|
|
282
|
-
description: 'Multi-agent orchestration harness with curated skills. Includes Conductor, Architect, Builder, Reviewer, Librarian agents plus RAG-based skill discovery system.',
|
|
283
|
-
source: './',
|
|
284
|
-
skills: pluginSkills.map(s => s.path),
|
|
285
|
-
strict: false,
|
|
286
|
-
skill_list: pluginSkills
|
|
287
|
-
}
|
|
288
|
-
],
|
|
289
|
-
metadata: {
|
|
290
|
-
version: getPackageVersion(),
|
|
291
|
-
generated_at: new Date().toISOString(),
|
|
292
|
-
skill_count: skills.length,
|
|
293
|
-
categories: categories
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
// Write registry file
|
|
298
|
-
log('', 'gray');
|
|
299
|
-
log(`Writing registry to: ${MARKETPLACE_FILE}`, 'gray');
|
|
300
|
-
fs.writeFileSync(MARKETPLACE_FILE, JSON.stringify(registry, null, 2));
|
|
301
|
-
|
|
302
|
-
log('', 'gray');
|
|
303
|
-
log('=====================================', 'gray');
|
|
304
|
-
log(`✅ Registry generated with ${skills.length} skills`, 'green');
|
|
305
|
-
log('=====================================', 'gray');
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Get package version
|
|
310
|
-
*/
|
|
311
|
-
function getPackageVersion() {
|
|
312
|
-
try {
|
|
313
|
-
const pkgPath = path.join(ROOT_DIR, 'package.json');
|
|
314
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
315
|
-
return pkg.version || '1.0.0';
|
|
316
|
-
} catch (error) {
|
|
317
|
-
return '1.0.0';
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// ============================================================================
|
|
322
|
-
// Run
|
|
323
|
-
// ============================================================================
|
|
324
|
-
|
|
325
|
-
generateRegistry();
|
package/sources.yaml
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# SMC External Skills Sources
|
|
2
|
-
# ===========================
|
|
3
|
-
# 此清单定义了从外部仓库同步到本项目的技能。
|
|
4
|
-
# GitHub Actions 工作流会读取此文件并每日自动同步上游技能。
|
|
5
|
-
#
|
|
6
|
-
# 添加技能:提交 PR 添加条目到此处。参考 CONTRIBUTING.md。
|
|
7
|
-
|
|
8
|
-
version: 1
|
|
9
|
-
skills:
|
|
10
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
-
# manus-kickoff - Native skill (maintained directly in this repo)
|
|
12
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
-
- name: manus-kickoff
|
|
14
|
-
description: Manus-style project kickoff workflow for AI autonomous development
|
|
15
|
-
native: true # Maintained directly in this repo
|
|
16
|
-
target:
|
|
17
|
-
category: workflow
|
|
18
|
-
path: template/.claude/skills/manus-kickoff
|
|
19
|
-
author:
|
|
20
|
-
name: sumulige
|
|
21
|
-
github: sumulige
|
|
22
|
-
license: MIT
|
|
23
|
-
homepage: https://github.com/sumulige/sumulige-claude
|
|
24
|
-
|
|
25
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
26
|
-
# Example: Adding an external skill (commented out)
|
|
27
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
28
|
-
# - name: dev-browser
|
|
29
|
-
# description: Browser automation with persistent page state
|
|
30
|
-
# source:
|
|
31
|
-
# repo: SawyerHood/dev-browser
|
|
32
|
-
# path: skills/dev-browser
|
|
33
|
-
# ref: main
|
|
34
|
-
# target:
|
|
35
|
-
# category: automation
|
|
36
|
-
# path: template/.claude/skills/automation/dev-browser
|
|
37
|
-
# author:
|
|
38
|
-
# name: Sawyer Hood
|
|
39
|
-
# github: SawyerHood
|
|
40
|
-
# license: MIT
|
|
41
|
-
# homepage: https://github.com/SawyerHood/dev-browser
|
|
42
|
-
# verified: false
|
|
43
|
-
# sync:
|
|
44
|
-
# include:
|
|
45
|
-
# - SKILL.md
|
|
46
|
-
# - references/
|
|
47
|
-
# - scripts/
|
|
48
|
-
# - src/
|
|
49
|
-
# - package.json
|
|
50
|
-
# exclude:
|
|
51
|
-
# - node_modules/
|
|
52
|
-
# - "*.lock"
|
|
53
|
-
|
|
54
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
55
|
-
# Schema Reference
|
|
56
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
57
|
-
#
|
|
58
|
-
# skills[]:
|
|
59
|
-
# name: Required. Unique skill identifier (lowercase, hyphens ok)
|
|
60
|
-
# description: Required. One-line description for marketplace listings
|
|
61
|
-
#
|
|
62
|
-
# native: Optional. Set true if skill is maintained directly in this repo
|
|
63
|
-
#
|
|
64
|
-
# source: Required for external skills
|
|
65
|
-
# repo: GitHub owner/repo (e.g., "SawyerHood/dev-browser")
|
|
66
|
-
# path: Path to skill folder within repo
|
|
67
|
-
# ref: Branch, tag, or commit SHA (default: main)
|
|
68
|
-
#
|
|
69
|
-
# target: Required
|
|
70
|
-
# category: One of: tools, development, productivity, automation, data, documentation, workflow
|
|
71
|
-
# path: Target path in smc-skills repo
|
|
72
|
-
#
|
|
73
|
-
# author: Required
|
|
74
|
-
# name: Display name
|
|
75
|
-
# github: GitHub username
|
|
76
|
-
#
|
|
77
|
-
# license: Required. SPDX identifier (MIT, Apache-2.0, etc.)
|
|
78
|
-
# homepage: Required. Link to project homepage or repo
|
|
79
|
-
# verified: Optional. Set true after manual review (default: false)
|
|
80
|
-
#
|
|
81
|
-
# sync: Optional. Fine-grained sync control
|
|
82
|
-
# include: List of files/folders to copy
|
|
83
|
-
# exclude: Glob patterns to skip
|
package/tests/README.md
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
# Sumulige Claude - 测试计划与报告
|
|
2
|
-
|
|
3
|
-
> 测试覆盖所有核心模块,确保代码质量
|
|
4
|
-
> 最后更新:2025-01-15
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 📊 测试覆盖率概览
|
|
9
|
-
|
|
10
|
-
```
|
|
11
|
-
Test Suites: 5 passed, 5 total
|
|
12
|
-
Tests: 78 passed, 78 total
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
| 模块 | 语句覆盖率 | 分支覆盖率 | 函数覆盖率 | 行覆盖率 | 状态 |
|
|
16
|
-
|------|-----------|-----------|-----------|---------|------|
|
|
17
|
-
| utils.js | 100% | 100% | 100% | 100% | ✅ |
|
|
18
|
-
| migrations.js | 86.66% | 75% | 87.5% | 88.67% | ✅ |
|
|
19
|
-
| config.js | 86.2% | 90.9% | 75% | 86.2% | ✅ |
|
|
20
|
-
| marketplace.js | 28.11% | 11.5% | 50% | 29.41% | ⚠️ |
|
|
21
|
-
| commands.js | 26.23% | 15.38% | 37.03% | 26.37% | ⚠️ |
|
|
22
|
-
| **总体** | **36.58%** | **26.95%** | **54.38%** | **36.72%** | 📊 |
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## 🧪 测试文件结构
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
tests/
|
|
30
|
-
├── README.md # 本文档
|
|
31
|
-
├── utils.test.js # 工具函数测试 (100%)
|
|
32
|
-
├── config.test.js # 配置管理测试 (86.2%)
|
|
33
|
-
├── migrations.test.js # 版本迁移测试 (86.66%)
|
|
34
|
-
├── marketplace.test.js # 市场功能测试 (28.11%)
|
|
35
|
-
└── commands.test.js # CLI 命令测试 (26.23%)
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## 📋 测试用例详情
|
|
41
|
-
|
|
42
|
-
### utils.test.js (23 tests)
|
|
43
|
-
|
|
44
|
-
```javascript
|
|
45
|
-
// copyRecursive - 递归复制目录
|
|
46
|
-
✓ should return 0 when source does not exist
|
|
47
|
-
✓ should copy files recursively
|
|
48
|
-
✓ should set execute permission for script files
|
|
49
|
-
✓ should not overwrite when overwrite=false
|
|
50
|
-
✓ should overwrite when overwrite=true
|
|
51
|
-
|
|
52
|
-
// ensureDir - 创建目录
|
|
53
|
-
✓ should create directory if not exists
|
|
54
|
-
✓ should not error if directory already exists
|
|
55
|
-
✓ should create nested directories
|
|
56
|
-
|
|
57
|
-
// toTitleCase - 标题大小写转换
|
|
58
|
-
✓ should convert string to title case
|
|
59
|
-
✓ should handle single word
|
|
60
|
-
✓ should handle empty string
|
|
61
|
-
✓ should handle already capitalized string
|
|
62
|
-
✓ should handle strings with multiple spaces
|
|
63
|
-
✓ should preserve special characters
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### config.test.js (7 tests)
|
|
67
|
-
|
|
68
|
-
```javascript
|
|
69
|
-
✓ should return default config when no user config exists
|
|
70
|
-
✓ should return DEFAULTS constant
|
|
71
|
-
✓ should create directory and save config
|
|
72
|
-
✓ should not error when directory exists
|
|
73
|
-
✓ should export required constants
|
|
74
|
-
✓ should have correct paths
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### migrations.test.js (18 tests)
|
|
78
|
-
|
|
79
|
-
```javascript
|
|
80
|
-
// getProjectVersion
|
|
81
|
-
✓ should return 1.0.0 when version file does not exist
|
|
82
|
-
✓ should read version from file
|
|
83
|
-
✓ should trim whitespace from version
|
|
84
|
-
✓ should return 1.0.0 on read error
|
|
85
|
-
|
|
86
|
-
// setProjectVersion
|
|
87
|
-
✓ should write version to file
|
|
88
|
-
✓ should add newline after version
|
|
89
|
-
✓ should create .claude directory if not exists
|
|
90
|
-
|
|
91
|
-
// compareVersions
|
|
92
|
-
✓ should return -1 when v1 < v2
|
|
93
|
-
✓ should return 1 when v1 > v2
|
|
94
|
-
✓ should return 0 when v1 === v2
|
|
95
|
-
✓ should handle version comparison correctly
|
|
96
|
-
✓ should handle version strings with different formats
|
|
97
|
-
|
|
98
|
-
// runMigrations
|
|
99
|
-
✓ should return success when already at latest version
|
|
100
|
-
✓ should return success when version is newer than template
|
|
101
|
-
✓ should return correct structure when pending migrations exist
|
|
102
|
-
✓ should handle missing settings.json gracefully
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### marketplace.test.js (18 tests)
|
|
106
|
-
|
|
107
|
-
```javascript
|
|
108
|
-
// parseSimpleYaml
|
|
109
|
-
✓ should parse version number
|
|
110
|
-
✓ should parse skill names
|
|
111
|
-
✓ should handle empty skills array
|
|
112
|
-
✓ should skip comments
|
|
113
|
-
✓ should handle empty lines
|
|
114
|
-
|
|
115
|
-
// marketplaceCommands
|
|
116
|
-
✓ marketplace:list - should be a function
|
|
117
|
-
✓ marketplace:list - should output to console
|
|
118
|
-
✓ marketplace:install - should show usage when no skill name provided
|
|
119
|
-
✓ marketplace:sync - should be a function
|
|
120
|
-
✓ marketplace:sync - should output sync message
|
|
121
|
-
✓ marketplace:add - should show usage when no repo provided
|
|
122
|
-
✓ marketplace:add - should validate repo format
|
|
123
|
-
✓ marketplace:remove - should show usage when no skill name provided
|
|
124
|
-
✓ marketplace:status - should be a function
|
|
125
|
-
✓ marketplace:status - should output status information
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### commands.test.js (12 tests)
|
|
129
|
-
|
|
130
|
-
```javascript
|
|
131
|
-
// exports
|
|
132
|
-
✓ should export runCommand function
|
|
133
|
-
✓ should export commands object
|
|
134
|
-
✓ should have all expected commands
|
|
135
|
-
|
|
136
|
-
// runCommand
|
|
137
|
-
✓ should call the correct command function
|
|
138
|
-
✓ should pass arguments to command function
|
|
139
|
-
✓ should handle unknown commands gracefully
|
|
140
|
-
|
|
141
|
-
// init
|
|
142
|
-
✓ should be a function
|
|
143
|
-
✓ should not throw
|
|
144
|
-
|
|
145
|
-
// sync
|
|
146
|
-
✓ should be a function
|
|
147
|
-
✓ should not throw
|
|
148
|
-
|
|
149
|
-
// agent
|
|
150
|
-
✓ should show usage when no task provided
|
|
151
|
-
✓ should display agent information when task provided
|
|
152
|
-
|
|
153
|
-
// skill:create
|
|
154
|
-
✓ should show usage when no skill name provided
|
|
155
|
-
✓ should validate skill name format
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## 🚀 运行测试
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
# 运行所有测试
|
|
164
|
-
npm test
|
|
165
|
-
|
|
166
|
-
# 运行测试并生成覆盖率报告
|
|
167
|
-
npm run test:coverage
|
|
168
|
-
|
|
169
|
-
# 监视模式
|
|
170
|
-
npm run test:watch
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
## 📦 依赖项
|
|
176
|
-
|
|
177
|
-
```json
|
|
178
|
-
{
|
|
179
|
-
"devDependencies": {
|
|
180
|
-
"jest": "^30.2.0",
|
|
181
|
-
"mock-fs": "^5.5.0",
|
|
182
|
-
"prettier": "^3.7.4",
|
|
183
|
-
"sinon": "^21.0.1",
|
|
184
|
-
"yaml": "^2.8.2"
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
## 🔧 测试策略
|
|
192
|
-
|
|
193
|
-
### 使用的工具
|
|
194
|
-
|
|
195
|
-
| 工具 | 用途 |
|
|
196
|
-
|------|------|
|
|
197
|
-
| Jest | 测试框架 + 断言 |
|
|
198
|
-
| mock-fs | 文件系统模拟 |
|
|
199
|
-
| sinon | 函数 stub 和 spy |
|
|
200
|
-
|
|
201
|
-
### Mock 策略
|
|
202
|
-
|
|
203
|
-
1. **文件系统操作**:使用 `mock-fs` 模拟文件系统
|
|
204
|
-
2. **外部命令**:使用 `sinon.stub` 模拟 `execSync`
|
|
205
|
-
3. **Console 输出**:使用 `jest.spyOn(console, 'log')` 捕获输出
|
|
206
|
-
|
|
207
|
-
### 已知限制
|
|
208
|
-
|
|
209
|
-
1. **commands.js** 覆盖率低 - 该模块依赖外部命令和实际文件操作
|
|
210
|
-
2. **marketplace.js** YAML 解析逻辑复杂,简化了测试场景
|
|
211
|
-
3. 集成测试未覆盖,建议后续添加端到端测试
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
## 🎯 改进建议
|
|
216
|
-
|
|
217
|
-
### 短期改进
|
|
218
|
-
|
|
219
|
-
1. 为 commands.js 添加更多单元测试(目标:40%+)
|
|
220
|
-
2. 补充 marketplace.js 的 YAML 解析边界测试
|
|
221
|
-
3. 添加错误处理的测试用例
|
|
222
|
-
|
|
223
|
-
### 长期改进
|
|
224
|
-
|
|
225
|
-
1. 添加集成测试覆盖完整的 CLI 工作流
|
|
226
|
-
2. 添加性能测试确保大型项目下的响应速度
|
|
227
|
-
3. 考虑添加快照测试用于模板文件验证
|
|
228
|
-
|
|
229
|
-
---
|
|
230
|
-
|
|
231
|
-
## 📝 测试最佳实践
|
|
232
|
-
|
|
233
|
-
### 遵循的原则
|
|
234
|
-
|
|
235
|
-
1. **AAA 模式**:Arrange-Act-Assert
|
|
236
|
-
2. **单一职责**:每个测试只验证一个行为
|
|
237
|
-
3. **独立性**:测试之间不共享状态
|
|
238
|
-
4. **可读性**:测试名称清晰描述测试内容
|
|
239
|
-
|
|
240
|
-
### 示例
|
|
241
|
-
|
|
242
|
-
```javascript
|
|
243
|
-
describe('toTitleCase', () => {
|
|
244
|
-
it('should convert string to title case', () => {
|
|
245
|
-
// Arrange
|
|
246
|
-
const input = 'hello world';
|
|
247
|
-
|
|
248
|
-
// Act
|
|
249
|
-
const result = utils.toTitleCase(input);
|
|
250
|
-
|
|
251
|
-
// Assert
|
|
252
|
-
expect(result).toBe('Hello World');
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
---
|
|
258
|
-
|
|
259
|
-
## 🔗 相关资源
|
|
260
|
-
|
|
261
|
-
- [Jest 文档](https://jestjs.io/)
|
|
262
|
-
- [mock-fs 文档](https://github.com/tschaub/mock-fs)
|
|
263
|
-
- [Sinon.JS 文档](https://sinonjs.org/)
|