codymaster 4.6.0 → 5.2.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 (161) hide show
  1. package/CHANGELOG.md +74 -8
  2. package/README.md +192 -95
  3. package/dist/advisory-handoff.js +89 -0
  4. package/dist/advisory-report.js +105 -0
  5. package/dist/browse-server.js +251 -0
  6. package/dist/cli/command-registry.js +34 -0
  7. package/dist/cli/commands/agent.js +120 -0
  8. package/dist/cli/commands/bench.js +69 -0
  9. package/dist/cli/commands/brain.js +108 -0
  10. package/dist/cli/commands/dashboard.js +93 -0
  11. package/dist/cli/commands/design-studio.js +111 -0
  12. package/dist/cli/commands/distro.js +25 -0
  13. package/dist/cli/commands/engineering.js +596 -0
  14. package/dist/cli/commands/evolve.js +123 -0
  15. package/dist/cli/commands/mcp-serve.js +104 -0
  16. package/dist/cli/commands/project.js +324 -0
  17. package/dist/cli/commands/skill-chain.js +269 -0
  18. package/dist/cli/commands/system.js +89 -0
  19. package/dist/cli/commands/task.js +254 -0
  20. package/dist/cli/update-check.js +83 -0
  21. package/dist/cm-config.js +92 -0
  22. package/dist/cm-suggest.js +77 -0
  23. package/dist/codybench/judges/automated.js +31 -0
  24. package/dist/codybench/runners/claude-code.js +32 -0
  25. package/dist/codybench/suites/memory-retention.js +85 -0
  26. package/dist/codybench/suites/tdd-regression.js +35 -0
  27. package/dist/codybench/suites/token-efficiency.js +55 -0
  28. package/dist/codybench/types.js +2 -0
  29. package/dist/context-db.js +157 -0
  30. package/dist/continuity.js +2 -6
  31. package/dist/distro-validate.js +54 -0
  32. package/dist/execution-analyzer.js +138 -0
  33. package/dist/guardian-core.js +74 -0
  34. package/dist/index.js +36 -2759
  35. package/dist/indexer/skills-lib.js +533 -0
  36. package/dist/indexer/skills-map.js +1374 -0
  37. package/dist/indexer/skills.js +16 -0
  38. package/dist/learning-promoter.js +246 -0
  39. package/dist/mcp-context-server.js +289 -1
  40. package/dist/mcp-skills-tools.js +81 -0
  41. package/dist/retro-summary.js +70 -0
  42. package/dist/second-opinion-providers.js +79 -0
  43. package/dist/skill-chain.js +63 -1
  44. package/dist/skill-evolver.js +456 -0
  45. package/dist/skill-execution-cache.js +254 -0
  46. package/dist/smart-brain-router.js +184 -0
  47. package/dist/sprint-pipeline.js +228 -0
  48. package/dist/storage-backend.js +14 -67
  49. package/dist/token-budget.js +88 -0
  50. package/dist/utils/cli-utils.js +76 -0
  51. package/dist/utils/skill-utils.js +32 -0
  52. package/package.json +17 -7
  53. package/scripts/build-skills.mjs +51 -0
  54. package/scripts/gate-0-repo-hygiene.js +75 -0
  55. package/scripts/postinstall.js +34 -28
  56. package/scripts/security-scan.js +1 -1
  57. package/scripts/validate-skills.mjs +42 -0
  58. package/skills/CLAUDE.md +2 -7
  59. package/skills/_shared/helpers.md +2 -8
  60. package/skills/cm-ads-tracker/SKILL.md +3 -6
  61. package/skills/cm-browse/SKILL.md +34 -0
  62. package/skills/cm-conductor-worktrees/SKILL.md +28 -0
  63. package/skills/cm-content-factory/SKILL.md +1 -1
  64. package/skills/cm-content-factory/landing/docs/content/changelog.md +36 -0
  65. package/skills/cm-content-factory/landing/docs/content/deployment.md +46 -0
  66. package/skills/cm-content-factory/landing/docs/content/execution-flow.md +67 -0
  67. package/skills/cm-content-factory/landing/docs/content/memory-system.md +38 -0
  68. package/skills/cm-content-factory/landing/docs/content/openspace.md +27 -0
  69. package/skills/cm-content-factory/landing/docs/content/use-cases.md +26 -0
  70. package/skills/cm-content-factory/landing/docs/content/v5-intro.md +28 -0
  71. package/skills/cm-content-factory/landing/docs/index.html +240 -0
  72. package/skills/cm-content-factory/landing/index.html +100 -100
  73. package/skills/cm-content-factory/landing/script.js +42 -0
  74. package/skills/cm-content-factory/landing/translations.js +400 -400
  75. package/skills/cm-continuity/SKILL.md +32 -33
  76. package/skills/cm-design-studio/SKILL.md +34 -0
  77. package/skills/cm-ecosystem-roadmap/SKILL.md +15 -0
  78. package/skills/cm-engineering-meta/SKILL.md +73 -0
  79. package/skills/cm-growth-hacking/SKILL.md +1 -12
  80. package/skills/cm-guardian-runtime/SKILL.md +26 -0
  81. package/skills/cm-mcp-engineering/SKILL.md +22 -0
  82. package/skills/cm-notebooklm/SKILL.md +1 -17
  83. package/skills/cm-post-deploy-canary/SKILL.md +22 -0
  84. package/skills/cm-project-bootstrap/SKILL.md +11 -0
  85. package/skills/cm-qa-visual-cli/SKILL.md +22 -0
  86. package/skills/cm-retro-cli/SKILL.md +23 -0
  87. package/skills/cm-second-opinion-cli/SKILL.md +23 -0
  88. package/skills/cm-secret-shield/SKILL.md +2 -2
  89. package/skills/cm-security-gate/SKILL.md +1 -0
  90. package/skills/cm-skill-chain/SKILL.md +25 -4
  91. package/skills/cm-skill-evolution/SKILL.md +83 -0
  92. package/skills/cm-skill-health/SKILL.md +83 -0
  93. package/skills/cm-skill-index/SKILL.md +11 -3
  94. package/skills/cm-skill-search/SKILL.md +49 -0
  95. package/skills/cm-skill-share/SKILL.md +58 -0
  96. package/skills/cm-sprint-bus/SKILL.md +33 -0
  97. package/skills/cm-start/SKILL.md +0 -10
  98. package/skills/cm-tdd/SKILL.md +59 -72
  99. package/skills/profiles/README.md +21 -0
  100. package/skills/profiles/core.txt +23 -0
  101. package/skills/profiles/design.txt +6 -0
  102. package/skills/profiles/full.txt +62 -0
  103. package/skills/profiles/growth.txt +10 -0
  104. package/skills/profiles/knowledge.txt +7 -0
  105. package/install.sh +0 -901
  106. package/scripts/test-gemini.js +0 -13
  107. package/skills/cm-frappe-agent/SKILL.md +0 -134
  108. package/skills/cm-frappe-agent/agents/doctype-architect.md +0 -596
  109. package/skills/cm-frappe-agent/agents/erpnext-customizer.md +0 -643
  110. package/skills/cm-frappe-agent/agents/frappe-backend.md +0 -814
  111. package/skills/cm-frappe-agent/agents/frappe-custom-frontend.md +0 -557
  112. package/skills/cm-frappe-agent/agents/frappe-debugger.md +0 -625
  113. package/skills/cm-frappe-agent/agents/frappe-fixer.md +0 -275
  114. package/skills/cm-frappe-agent/agents/frappe-frontend.md +0 -660
  115. package/skills/cm-frappe-agent/agents/frappe-installer.md +0 -158
  116. package/skills/cm-frappe-agent/agents/frappe-performance.md +0 -307
  117. package/skills/cm-frappe-agent/agents/frappe-planner.md +0 -419
  118. package/skills/cm-frappe-agent/agents/frappe-remote-ops.md +0 -153
  119. package/skills/cm-frappe-agent/agents/github-workflow.md +0 -286
  120. package/skills/cm-frappe-agent/commands/frappe-app.md +0 -351
  121. package/skills/cm-frappe-agent/commands/frappe-backend.md +0 -162
  122. package/skills/cm-frappe-agent/commands/frappe-bench.md +0 -254
  123. package/skills/cm-frappe-agent/commands/frappe-debug.md +0 -263
  124. package/skills/cm-frappe-agent/commands/frappe-doctype-create.md +0 -272
  125. package/skills/cm-frappe-agent/commands/frappe-doctype-field.md +0 -310
  126. package/skills/cm-frappe-agent/commands/frappe-erpnext.md +0 -210
  127. package/skills/cm-frappe-agent/commands/frappe-fix.md +0 -59
  128. package/skills/cm-frappe-agent/commands/frappe-frontend.md +0 -210
  129. package/skills/cm-frappe-agent/commands/frappe-fullstack.md +0 -243
  130. package/skills/cm-frappe-agent/commands/frappe-github.md +0 -57
  131. package/skills/cm-frappe-agent/commands/frappe-install.md +0 -52
  132. package/skills/cm-frappe-agent/commands/frappe-plan.md +0 -442
  133. package/skills/cm-frappe-agent/commands/frappe-remote.md +0 -58
  134. package/skills/cm-frappe-agent/commands/frappe-test.md +0 -356
  135. package/skills/cm-frappe-agent/docs/README.md +0 -51
  136. package/skills/cm-frappe-agent/docs/agents-catalog.md +0 -113
  137. package/skills/cm-frappe-agent/docs/architecture.md +0 -149
  138. package/skills/cm-frappe-agent/docs/commands-catalog.md +0 -82
  139. package/skills/cm-frappe-agent/docs/resources-catalog.md +0 -66
  140. package/skills/cm-frappe-agent/docs/sitemap-urls.txt +0 -52
  141. package/skills/cm-frappe-agent/docs/sitemap.md +0 -81
  142. package/skills/cm-frappe-agent/docs/sop/user-guide.md +0 -178
  143. package/skills/cm-frappe-agent/docs/sop/vibe-coding-guide.md +0 -122
  144. package/skills/cm-frappe-agent/resources/7-layer-architecture.md +0 -985
  145. package/skills/cm-frappe-agent/resources/bench_commands.md +0 -73
  146. package/skills/cm-frappe-agent/resources/code-patterns-guide.md +0 -948
  147. package/skills/cm-frappe-agent/resources/common_pitfalls.md +0 -266
  148. package/skills/cm-frappe-agent/resources/doctype-registry.md +0 -158
  149. package/skills/cm-frappe-agent/resources/installation-guide.md +0 -289
  150. package/skills/cm-frappe-agent/resources/rest-api-patterns.md +0 -182
  151. package/skills/cm-frappe-agent/resources/scaffold_checklist.md +0 -82
  152. package/skills/cm-frappe-agent/resources/upgrade_patterns.md +0 -113
  153. package/skills/cm-frappe-agent/resources/web-form-patterns.md +0 -252
  154. package/skills/cm-frappe-agent/skills/bench-commands/SKILL.md +0 -621
  155. package/skills/cm-frappe-agent/skills/client-scripts/SKILL.md +0 -642
  156. package/skills/cm-frappe-agent/skills/doctype-patterns/SKILL.md +0 -576
  157. package/skills/cm-frappe-agent/skills/frappe-api/SKILL.md +0 -740
  158. package/skills/cm-frappe-agent/skills/remote-operations/SKILL.md +0 -47
  159. package/skills/cm-frappe-agent/skills/server-scripts/SKILL.md +0 -608
  160. package/skills/cm-frappe-agent/skills/web-forms/SKILL.md +0 -46
  161. package/skills/frappe-app-builder.zip +0 -0
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerBrainCommands = registerBrainCommands;
4
+ const smart_brain_router_1 = require("../../smart-brain-router");
5
+ const skill_execution_cache_1 = require("../../skill-execution-cache");
6
+ const token_budget_1 = require("../../token-budget");
7
+ // ─── Brain & Token CLI Commands ──────────────────────────────────────────────
8
+ function registerBrainCommands(program) {
9
+ const smart = program
10
+ .command('smart')
11
+ .description('Smart Brain Router — inspect brain layer selection for tasks');
12
+ smart
13
+ .command('plan <task>')
14
+ .description('Preview which brain layers would load for a task description')
15
+ .action((task) => {
16
+ const plan = (0, smart_brain_router_1.routeTask)(task);
17
+ const output = (0, smart_brain_router_1.formatBrainPlan)(plan);
18
+ console.log(output);
19
+ });
20
+ smart
21
+ .command('tiers')
22
+ .description('Show per-tier token budget allocations')
23
+ .action(() => {
24
+ const tierBudgets = (0, token_budget_1.getDefaultTierBudgets)();
25
+ console.log((0, token_budget_1.generateTierReport)(tierBudgets));
26
+ });
27
+ const token = program
28
+ .command('token')
29
+ .description('Token usage analysis and savings tracking');
30
+ token
31
+ .command('report')
32
+ .description('Show current token budget allocation')
33
+ .option('-p, --project <path>', 'Project path', process.cwd())
34
+ .action((opts) => {
35
+ const budget = (0, token_budget_1.loadBudget)(opts.project);
36
+ console.log((0, token_budget_1.generateBudgetReport)(budget));
37
+ console.log('');
38
+ const tierBudgets = (0, token_budget_1.getDefaultTierBudgets)();
39
+ console.log((0, token_budget_1.generateTierReport)(tierBudgets));
40
+ });
41
+ token
42
+ .command('savings')
43
+ .description('Show estimated token savings from smart routing and caching')
44
+ .option('-p, --project <path>', 'Project path', process.cwd())
45
+ .action((opts) => {
46
+ const cache = new skill_execution_cache_1.SkillExecutionCache(opts.project);
47
+ try {
48
+ cache.initialize();
49
+ const stats = cache.getStats();
50
+ console.log((0, skill_execution_cache_1.formatCacheStats)(stats));
51
+ console.log('');
52
+ // Compute savings summary
53
+ const savings = {
54
+ brainRoutingSaved: 0, // Tracked per-session (not persistent yet)
55
+ cacheHitsSaved: stats.estimatedTokensSaved,
56
+ progressiveLoadSaved: 0,
57
+ totalSaved: stats.estimatedTokensSaved,
58
+ sessionTasks: stats.totalHits,
59
+ };
60
+ console.log((0, token_budget_1.formatSavingsReport)(savings));
61
+ }
62
+ finally {
63
+ cache.close();
64
+ }
65
+ });
66
+ token
67
+ .command('cache')
68
+ .description('Show skill execution cache entries')
69
+ .option('-p, --project <path>', 'Project path', process.cwd())
70
+ .option('-n, --limit <n>', 'Max entries to show', '20')
71
+ .action((opts) => {
72
+ const cache = new skill_execution_cache_1.SkillExecutionCache(opts.project);
73
+ try {
74
+ cache.initialize();
75
+ const entries = cache.listCachedChains(parseInt(opts.limit));
76
+ if (entries.length === 0) {
77
+ console.log('📦 No cached skill chains yet. Complete some tasks to build the cache.');
78
+ return;
79
+ }
80
+ console.log(`📦 Skill Execution Cache (${entries.length} entries)`);
81
+ console.log('─'.repeat(70));
82
+ for (const entry of entries) {
83
+ const skills = entry.skillChain.join(' → ');
84
+ const eff = (entry.effectiveness * 100).toFixed(0);
85
+ console.log(` ${entry.taskPattern.slice(0, 45).padEnd(45)} │ ${skills}`);
86
+ console.log(` ${''.padEnd(45)} │ ${eff}% eff · ${entry.hitCount} hits · ${entry.tokenUsed} tok`);
87
+ }
88
+ }
89
+ finally {
90
+ cache.close();
91
+ }
92
+ });
93
+ token
94
+ .command('cache-clear')
95
+ .description('Clear the skill execution cache')
96
+ .option('-p, --project <path>', 'Project path', process.cwd())
97
+ .action((opts) => {
98
+ const cache = new skill_execution_cache_1.SkillExecutionCache(opts.project);
99
+ try {
100
+ cache.initialize();
101
+ const cleared = cache.clearCache();
102
+ console.log(`🗑️ Cleared ${cleared} cached entries.`);
103
+ }
104
+ finally {
105
+ cache.close();
106
+ }
107
+ });
108
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerDashboardCommands = registerDashboardCommands;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const dashboard_1 = require("../../dashboard");
9
+ const data_1 = require("../../data");
10
+ const theme_1 = require("../../ui/theme");
11
+ const box_1 = require("../../ui/box");
12
+ const cli_utils_1 = require("../../utils/cli-utils");
13
+ function registerDashboardCommands(program) {
14
+ program
15
+ .command('dashboard [cmd]')
16
+ .alias('dash')
17
+ .description('Dashboard server (start|stop|status|open)')
18
+ .option('-p, --port <port>', 'Port number', String(data_1.DEFAULT_PORT))
19
+ .action((cmd, opts) => {
20
+ const port = parseInt(opts.port) || data_1.DEFAULT_PORT;
21
+ switch (cmd) {
22
+ case 'start':
23
+ case undefined:
24
+ if (isDashboardRunning()) {
25
+ console.log((0, box_1.renderResult)('warning', 'Dashboard already running.', [`${(0, theme_1.dim)('URL:')} ${(0, theme_1.brand)(`http://localhost:${port}`)}`]));
26
+ return;
27
+ }
28
+ (0, dashboard_1.launchDashboard)(port);
29
+ break;
30
+ case 'stop':
31
+ stopDashboard();
32
+ break;
33
+ case 'status':
34
+ dashboardStatus(port);
35
+ break;
36
+ case 'open':
37
+ console.log((0, box_1.renderResult)('info', `Opening http://localhost:${port} ...`));
38
+ (0, cli_utils_1.openUrl)(`http://localhost:${port}`);
39
+ break;
40
+ case 'url':
41
+ console.log(`http://localhost:${port}`);
42
+ break;
43
+ default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: start, stop, status, open, url')]));
44
+ }
45
+ });
46
+ }
47
+ function isDashboardRunning() {
48
+ try {
49
+ if (!fs_1.default.existsSync(data_1.PID_FILE))
50
+ return false;
51
+ const pid = parseInt(fs_1.default.readFileSync(data_1.PID_FILE, 'utf-8').trim());
52
+ process.kill(pid, 0);
53
+ return true;
54
+ }
55
+ catch (_a) {
56
+ try {
57
+ fs_1.default.unlinkSync(data_1.PID_FILE);
58
+ }
59
+ catch (_b) { }
60
+ return false;
61
+ }
62
+ }
63
+ function stopDashboard() {
64
+ try {
65
+ if (!fs_1.default.existsSync(data_1.PID_FILE)) {
66
+ console.log((0, box_1.renderResult)('warning', 'No dashboard running.'));
67
+ return;
68
+ }
69
+ const pid = parseInt(fs_1.default.readFileSync(data_1.PID_FILE, 'utf-8').trim());
70
+ process.kill(pid, 'SIGTERM');
71
+ try {
72
+ fs_1.default.unlinkSync(data_1.PID_FILE);
73
+ }
74
+ catch (_a) { }
75
+ console.log((0, box_1.renderResult)('success', `Dashboard stopped (PID ${pid}).`));
76
+ }
77
+ catch (err) {
78
+ console.log((0, box_1.renderResult)('error', `Failed to stop: ${err.message}`));
79
+ try {
80
+ fs_1.default.unlinkSync(data_1.PID_FILE);
81
+ }
82
+ catch (_b) { }
83
+ }
84
+ }
85
+ function dashboardStatus(port) {
86
+ if (isDashboardRunning()) {
87
+ const pid = fs_1.default.readFileSync(data_1.PID_FILE, 'utf-8').trim();
88
+ console.log((0, box_1.renderResult)('success', 'Dashboard RUNNING', [`${(0, theme_1.dim)('PID:')} ${(0, theme_1.brand)(pid)}`, `${(0, theme_1.dim)('URL:')} ${(0, theme_1.brand)(`http://localhost:${port}`)}`]));
89
+ }
90
+ else {
91
+ console.log((0, box_1.renderResult)('warning', 'Dashboard NOT running', [(0, theme_1.dim)('Start with: cm dashboard start')]));
92
+ }
93
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initDesignStudioArtifacts = initDesignStudioArtifacts;
7
+ exports.registerDesignStudioCommands = registerDesignStudioCommands;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ function projectPath(opt) {
12
+ return path_1.default.resolve(opt || process.cwd());
13
+ }
14
+ const CHECKLIST = `# Design studio — checklist
15
+
16
+ - [ ] Problem / JTBD one-liner
17
+ - [ ] 2–3 UI variants named (A/B/C)
18
+ - [ ] Chosen variant + rationale
19
+ - [ ] Handoff block filled in HANDOFF.md
20
+ `;
21
+ const VARIANTS = `# Variants
22
+
23
+ | Id | Name | Notes |
24
+ |----|------|-------|
25
+ | A | | |
26
+ | B | | |
27
+ | C | | |
28
+ `;
29
+ const HANDOFF = `# Handoff to implementation
30
+
31
+ **Chosen variant:** (A/B/C)
32
+
33
+ **Screens / flows:**
34
+
35
+ **Tokens / components to reuse:**
36
+
37
+ **Out of scope:**
38
+
39
+ **Agent prompt stub:**
40
+
41
+ \`\`\`
42
+ Implement the chosen variant using existing design system tokens. …
43
+ \`\`\`
44
+ `;
45
+ const README = `# .cm/design-studio
46
+
47
+ Local artifact folder for **cm-design-studio**: variants, checklist, handoff.
48
+
49
+ Happy path:
50
+
51
+ 1. \`cm design-studio init\`
52
+ 2. Edit CHECKLIST.md + VARIANTS.md
53
+ 3. Fill HANDOFF.md, then run your build skill (e.g. cm-execution) with that stub.
54
+ `;
55
+ /** Writes default artifact files; skips paths that already exist. Returns created + skipped counts. */
56
+ function initDesignStudioArtifacts(root) {
57
+ const base = path_1.default.join(root, '.cm', 'design-studio');
58
+ fs_1.default.mkdirSync(base, { recursive: true });
59
+ const files = [
60
+ ['README.md', README],
61
+ ['CHECKLIST.md', CHECKLIST],
62
+ ['VARIANTS.md', VARIANTS],
63
+ ['HANDOFF.md', HANDOFF],
64
+ ];
65
+ let created = 0;
66
+ let skipped = 0;
67
+ for (const [name, body] of files) {
68
+ const p = path_1.default.join(base, name);
69
+ if (fs_1.default.existsSync(p)) {
70
+ skipped++;
71
+ }
72
+ else {
73
+ fs_1.default.writeFileSync(p, body, 'utf8');
74
+ created++;
75
+ }
76
+ }
77
+ return { created, skipped };
78
+ }
79
+ function registerDesignStudioCommands(program) {
80
+ const ds = program
81
+ .command('design-studio')
82
+ .description('Design variant workspace under .cm/design-studio');
83
+ ds.command('init')
84
+ .description('Create .cm/design-studio with checklist and handoff templates')
85
+ .option('--project <dir>', 'project root', process.cwd())
86
+ .action((opts) => {
87
+ const root = projectPath(opts.project);
88
+ const { created, skipped } = initDesignStudioArtifacts(root);
89
+ const base = path_1.default.join(root, '.cm', 'design-studio');
90
+ if (created)
91
+ console.log(chalk_1.default.green(`wrote ${created} file(s) under`), base);
92
+ if (skipped)
93
+ console.log(chalk_1.default.yellow(`skipped ${skipped} existing`));
94
+ });
95
+ ds.command('status')
96
+ .description('List design-studio artifact files if present')
97
+ .option('--project <dir>', 'project root', process.cwd())
98
+ .action((opts) => {
99
+ const root = projectPath(opts.project);
100
+ const base = path_1.default.join(root, '.cm', 'design-studio');
101
+ if (!fs_1.default.existsSync(base)) {
102
+ console.log(chalk_1.default.yellow('Not initialized. Run:'), chalk_1.default.cyan('cm design-studio init'));
103
+ return;
104
+ }
105
+ for (const f of fs_1.default.readdirSync(base)) {
106
+ const p = path_1.default.join(base, f);
107
+ const st = fs_1.default.statSync(p);
108
+ console.log(st.isDirectory() ? `${f}/` : f);
109
+ }
110
+ });
111
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerDistroCommands = registerDistroCommands;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const distro_validate_1 = require("../../distro-validate");
9
+ function registerDistroCommands(program) {
10
+ const distro = program.command('distro').description('Skill pack validation (ecosystem roadmap)');
11
+ distro
12
+ .command('validate')
13
+ .description('Validate a skill directory (SKILL.md / tmpl + optional meta.json)')
14
+ .argument('<dir>', 'path to skill folder')
15
+ .action((dir) => {
16
+ const r = (0, distro_validate_1.validateSkillPackDir)(dir);
17
+ for (const w of r.warnings)
18
+ console.log(chalk_1.default.yellow('warning:'), w);
19
+ for (const e of r.errors)
20
+ console.error(chalk_1.default.red('error:'), e);
21
+ if (!r.ok)
22
+ process.exit(1);
23
+ console.log(chalk_1.default.green('OK'), dir);
24
+ });
25
+ }