codymaster 4.8.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 (72) hide show
  1. package/CHANGELOG.md +55 -7
  2. package/README.md +142 -95
  3. package/dist/advisory-handoff.js +89 -0
  4. package/dist/advisory-report.js +105 -0
  5. package/dist/cli/command-registry.js +8 -0
  6. package/dist/cli/commands/bench.js +69 -0
  7. package/dist/cli/commands/brain.js +108 -0
  8. package/dist/cli/commands/engineering.js +108 -0
  9. package/dist/cli/commands/evolve.js +123 -0
  10. package/dist/cli/commands/mcp-serve.js +104 -0
  11. package/dist/cm-config.js +0 -18
  12. package/dist/codybench/judges/automated.js +31 -0
  13. package/dist/codybench/runners/claude-code.js +32 -0
  14. package/dist/codybench/suites/memory-retention.js +85 -0
  15. package/dist/codybench/suites/tdd-regression.js +35 -0
  16. package/dist/codybench/suites/token-efficiency.js +55 -0
  17. package/dist/codybench/types.js +2 -0
  18. package/dist/context-db.js +157 -0
  19. package/dist/continuity.js +2 -6
  20. package/dist/execution-analyzer.js +138 -0
  21. package/dist/indexer/skills-lib.js +533 -0
  22. package/dist/indexer/skills-map.js +1374 -0
  23. package/dist/indexer/skills.js +16 -0
  24. package/dist/learning-promoter.js +246 -0
  25. package/dist/mcp-context-server.js +230 -1
  26. package/dist/skill-chain.js +63 -1
  27. package/dist/skill-evolver.js +456 -0
  28. package/dist/skill-execution-cache.js +254 -0
  29. package/dist/smart-brain-router.js +184 -0
  30. package/dist/storage-backend.js +10 -8
  31. package/dist/token-budget.js +88 -0
  32. package/package.json +2 -3
  33. package/scripts/postinstall.js +10 -59
  34. package/skills/CLAUDE.md +0 -5
  35. package/skills/_shared/helpers.md +2 -8
  36. package/skills/cm-browse/SKILL.md +6 -0
  37. package/skills/cm-conductor-worktrees/SKILL.md +4 -0
  38. package/skills/cm-content-factory/landing/docs/content/changelog.md +4 -4
  39. package/skills/cm-content-factory/landing/docs/content/deployment.md +3 -3
  40. package/skills/cm-content-factory/landing/docs/content/execution-flow.md +8 -8
  41. package/skills/cm-content-factory/landing/docs/content/memory-system.md +38 -0
  42. package/skills/cm-content-factory/landing/docs/content/openspace.md +1 -1
  43. package/skills/cm-content-factory/landing/docs/content/use-cases.md +2 -2
  44. package/skills/cm-content-factory/landing/docs/content/v5-intro.md +3 -3
  45. package/skills/cm-content-factory/landing/docs/index.html +1 -1
  46. package/skills/cm-content-factory/landing/index.html +3 -3
  47. package/skills/cm-content-factory/landing/translations.js +37 -37
  48. package/skills/cm-continuity/SKILL.md +32 -33
  49. package/skills/cm-design-studio/SKILL.md +4 -0
  50. package/skills/cm-ecosystem-roadmap/SKILL.md +4 -0
  51. package/skills/cm-engineering-meta/SKILL.md +4 -0
  52. package/skills/cm-guardian-runtime/SKILL.md +5 -1
  53. package/skills/cm-mcp-engineering/SKILL.md +4 -0
  54. package/skills/cm-post-deploy-canary/SKILL.md +4 -0
  55. package/skills/cm-project-bootstrap/SKILL.md +11 -0
  56. package/skills/cm-qa-visual-cli/SKILL.md +4 -0
  57. package/skills/cm-retro-cli/SKILL.md +4 -0
  58. package/skills/cm-second-opinion-cli/SKILL.md +4 -0
  59. package/skills/cm-security-gate/SKILL.md +1 -0
  60. package/skills/cm-skill-chain/SKILL.md +25 -4
  61. package/skills/cm-skill-evolution/SKILL.md +83 -0
  62. package/skills/cm-skill-health/SKILL.md +83 -0
  63. package/skills/cm-skill-index/SKILL.md +11 -3
  64. package/skills/cm-skill-search/SKILL.md +49 -0
  65. package/skills/cm-skill-share/SKILL.md +58 -0
  66. package/skills/cm-sprint-bus/SKILL.md +4 -0
  67. package/skills/cm-start/SKILL.md +0 -10
  68. package/skills/cm-tdd/SKILL.md +2 -2
  69. package/skills/profiles/full.txt +4 -0
  70. package/install.sh +0 -1125
  71. package/scripts/viking-demo.ts +0 -105
  72. package/skills/cm-content-factory/landing/docs/content/openviking.md +0 -33
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildAdvisoryReportData = buildAdvisoryReportData;
4
+ exports.buildAdvisoryMetricsData = buildAdvisoryMetricsData;
5
+ exports.formatAdvisoryReport = formatAdvisoryReport;
6
+ exports.formatAdvisoryMetrics = formatAdvisoryMetrics;
7
+ const execution_analyzer_1 = require("./execution-analyzer");
8
+ function fmtConfidence(value) {
9
+ if (typeof value !== 'number')
10
+ return '-';
11
+ return value.toFixed(2);
12
+ }
13
+ function summarizeTargetSkills(analysis) {
14
+ const targets = analysis.skill_judgments
15
+ .filter((judgment) => judgment.selected || judgment.applied)
16
+ .map((judgment) => judgment.skill);
17
+ return targets.length > 0 ? targets.join(', ') : '-';
18
+ }
19
+ function formatAnalysisLine(analysis) {
20
+ var _a;
21
+ const action = (_a = analysis.recommended_action) !== null && _a !== void 0 ? _a : 'NONE';
22
+ return [
23
+ `- ${analysis.task_title}`,
24
+ `status=${analysis.status}`,
25
+ `action=${action}`,
26
+ `confidence=${fmtConfidence(analysis.confidence)}`,
27
+ `skills=${summarizeTargetSkills(analysis)}`,
28
+ ].join(' | ');
29
+ }
30
+ function formatMetricLine(metric) {
31
+ var _a;
32
+ return [
33
+ `- ${metric.skill}`,
34
+ `quality=${metric.quality_weight.toFixed(2)}`,
35
+ `selected=${metric.selections}`,
36
+ `applied=${metric.applications}`,
37
+ `completed=${metric.task_completions}`,
38
+ `fallbacks=${metric.fallbacks}`,
39
+ `action=${(_a = metric.last_recommended_action) !== null && _a !== void 0 ? _a : '-'}`,
40
+ ].join(' | ');
41
+ }
42
+ function buildAdvisoryReportData(backend, options = {}) {
43
+ var _a;
44
+ const limit = (_a = options.limit) !== null && _a !== void 0 ? _a : 10;
45
+ return backend.getExecutionAnalyses(limit).map((analysis) => ({
46
+ id: analysis.id,
47
+ task_title: analysis.task_title,
48
+ status: analysis.status,
49
+ summary: analysis.summary,
50
+ source_task_type: analysis.source_task_type,
51
+ recommended_action: analysis.recommended_action,
52
+ confidence: analysis.confidence,
53
+ created_at: analysis.created_at,
54
+ active_skills: analysis.skill_judgments
55
+ .filter((judgment) => judgment.selected || judgment.applied)
56
+ .map((judgment) => judgment.skill),
57
+ }));
58
+ }
59
+ function buildAdvisoryMetricsData(backend, options = {}) {
60
+ var _a;
61
+ const limit = (_a = options.limit) !== null && _a !== void 0 ? _a : 10;
62
+ return backend.listSkillMetrics(limit).map((metric) => ({
63
+ skill: metric.skill,
64
+ quality_weight: (0, execution_analyzer_1.qualityWeight)(metric),
65
+ selections: metric.selections,
66
+ applications: metric.applications,
67
+ task_completions: metric.task_completions,
68
+ fallbacks: metric.fallbacks,
69
+ total_token_estimate: metric.total_token_estimate,
70
+ last_task_type: metric.last_task_type,
71
+ last_recommended_action: metric.last_recommended_action,
72
+ last_used_at: metric.last_used_at,
73
+ updated_at: metric.updated_at,
74
+ }));
75
+ }
76
+ function formatAdvisoryReport(backend, options = {}) {
77
+ const analyses = buildAdvisoryReportData(backend, options);
78
+ if (analyses.length === 0) {
79
+ return [
80
+ 'Advisory Report',
81
+ '',
82
+ 'No execution analyses recorded yet.',
83
+ ].join('\n');
84
+ }
85
+ return [
86
+ 'Advisory Report',
87
+ '',
88
+ ...analyses.map((analysis) => formatAnalysisLine(Object.assign(Object.assign({}, analysis), { skill_judgments: analysis.active_skills.map((skill) => ({ skill, selected: true })) }))),
89
+ ].join('\n');
90
+ }
91
+ function formatAdvisoryMetrics(backend, options = {}) {
92
+ const metrics = buildAdvisoryMetricsData(backend, options);
93
+ if (metrics.length === 0) {
94
+ return [
95
+ 'Skill Metrics',
96
+ '',
97
+ 'No skill metrics recorded yet.',
98
+ ].join('\n');
99
+ }
100
+ return [
101
+ 'Skill Metrics',
102
+ '',
103
+ ...metrics.map(formatMetricLine),
104
+ ].join('\n');
105
+ }
@@ -10,6 +10,10 @@ const task_1 = require("./commands/task");
10
10
  const engineering_1 = require("./commands/engineering");
11
11
  const design_studio_1 = require("./commands/design-studio");
12
12
  const distro_1 = require("./commands/distro");
13
+ const mcp_serve_1 = require("./commands/mcp-serve");
14
+ const bench_1 = require("./commands/bench");
15
+ const brain_1 = require("./commands/brain");
16
+ const evolve_1 = require("./commands/evolve");
13
17
  /**
14
18
  * Registers all CLI commands with the provided program instance.
15
19
  */
@@ -23,4 +27,8 @@ function registerAllCommands(program) {
23
27
  (0, engineering_1.registerEngineeringCommands)(program);
24
28
  (0, design_studio_1.registerDesignStudioCommands)(program);
25
29
  (0, distro_1.registerDistroCommands)(program);
30
+ (0, mcp_serve_1.registerMcpServeCommands)(program);
31
+ (0, bench_1.registerBenchCommands)(program);
32
+ (0, brain_1.registerBrainCommands)(program);
33
+ (0, evolve_1.registerEvolveCommands)(program);
26
34
  }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.registerBenchCommands = registerBenchCommands;
16
+ const fs_1 = __importDefault(require("fs"));
17
+ const path_1 = __importDefault(require("path"));
18
+ const chalk_1 = __importDefault(require("chalk"));
19
+ const tdd_regression_1 = require("../../codybench/suites/tdd-regression");
20
+ const token_efficiency_1 = require("../../codybench/suites/token-efficiency");
21
+ const memory_retention_1 = require("../../codybench/suites/memory-retention");
22
+ const claude_code_1 = require("../../codybench/runners/claude-code");
23
+ const automated_1 = require("../../codybench/judges/automated");
24
+ const SUITES = [tdd_regression_1.tddRegressionSuite, token_efficiency_1.tokenEfficiencySuite, memory_retention_1.memoryRetentionSuite];
25
+ function registerBenchCommands(program) {
26
+ program
27
+ .command('bench')
28
+ .description('Run CodyBench evaluation suites (v0.1)')
29
+ .option('--suite <id>', 'Run specific suite (default: all enabled)')
30
+ .option('--runs <n>', 'Override repeat count per suite', parseInt)
31
+ .option('--output <path>', 'Output JSON file path')
32
+ .action((opts) => __awaiter(this, void 0, void 0, function* () {
33
+ var _a;
34
+ const projectPath = process.cwd();
35
+ const configPath = path_1.default.join(projectPath, 'codybench', 'config.json');
36
+ let config;
37
+ try {
38
+ config = JSON.parse(fs_1.default.readFileSync(configPath, 'utf-8'));
39
+ }
40
+ catch (_b) {
41
+ console.error(chalk_1.default.red('Error: codybench/config.json not found. Run from project root.'));
42
+ process.exit(1);
43
+ }
44
+ // Override repeat if --runs provided
45
+ if (opts.runs)
46
+ config.evals = config.evals.map(e => (Object.assign(Object.assign({}, e), { repeat: opts.runs })));
47
+ const suitesToRun = opts.suite
48
+ ? SUITES.filter(s => s.id === opts.suite)
49
+ : SUITES.filter(s => config.evals.find(e => e.id === s.id && e.enabled));
50
+ if (suitesToRun.length === 0) {
51
+ console.error(chalk_1.default.red(`No suites found${opts.suite ? ` matching "${opts.suite}"` : ''}.`));
52
+ process.exit(1);
53
+ }
54
+ console.log(chalk_1.default.bold(`\nCodyBench v${config.version} — running ${suitesToRun.length} suite(s)\n`));
55
+ const allResults = [];
56
+ for (const suite of suitesToRun) {
57
+ process.stdout.write(chalk_1.default.dim(` Running ${suite.name}...`));
58
+ const results = yield (0, claude_code_1.runSuite)(suite, config, projectPath);
59
+ allResults.push(...results);
60
+ console.log(chalk_1.default.green(' done'));
61
+ }
62
+ const aggregates = (0, automated_1.aggregateResults)(allResults);
63
+ console.log('\n' + (0, automated_1.formatLeaderboard)(aggregates) + '\n');
64
+ const outputPath = (_a = opts.output) !== null && _a !== void 0 ? _a : path_1.default.join(projectPath, config.output_dir, `results-${Date.now()}.json`);
65
+ fs_1.default.mkdirSync(path_1.default.dirname(outputPath), { recursive: true });
66
+ fs_1.default.writeFileSync(outputPath, JSON.stringify({ config, results: allResults, aggregates }, null, 2));
67
+ console.log(chalk_1.default.dim(`Results saved to: ${outputPath}`));
68
+ }));
69
+ }
@@ -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
+ }
@@ -25,6 +25,9 @@ const second_opinion_providers_1 = require("../../second-opinion-providers");
25
25
  const sprint_pipeline_1 = require("../../sprint-pipeline");
26
26
  const retro_summary_1 = require("../../retro-summary");
27
27
  const cm_suggest_1 = require("../../cm-suggest");
28
+ const storage_backend_1 = require("../../storage-backend");
29
+ const advisory_report_1 = require("../../advisory-report");
30
+ const advisory_handoff_1 = require("../../advisory-handoff");
28
31
  function projectPath(opt) {
29
32
  return path_1.default.resolve(opt || process.cwd());
30
33
  }
@@ -100,6 +103,83 @@ function registerEngineeringCommands(program) {
100
103
  }
101
104
  console.log(chalk_1.default.green('OK'), opts.file);
102
105
  });
106
+ const advisory = program
107
+ .command('advisory')
108
+ .description('Operator-facing execution analysis and skill quality reports');
109
+ advisory
110
+ .command('report')
111
+ .description('Show recent execution analyses with recommended actions')
112
+ .option('--project <dir>')
113
+ .option('--limit <n>', 'number of analyses to show', '10')
114
+ .action((opts) => {
115
+ var _a;
116
+ const root = projectPath(opts.project);
117
+ const backend = (0, storage_backend_1.getBackend)(root);
118
+ backend.initialize();
119
+ try {
120
+ const limit = Math.max(1, parseInt(String((_a = opts.limit) !== null && _a !== void 0 ? _a : '10'), 10) || 10);
121
+ console.log((0, advisory_report_1.formatAdvisoryReport)(backend, { limit }));
122
+ }
123
+ finally {
124
+ backend.close();
125
+ }
126
+ });
127
+ advisory
128
+ .command('metrics')
129
+ .description('Show aggregated skill metrics with quality weights')
130
+ .option('--project <dir>')
131
+ .option('--limit <n>', 'number of skills to show', '10')
132
+ .action((opts) => {
133
+ var _a;
134
+ const root = projectPath(opts.project);
135
+ const backend = (0, storage_backend_1.getBackend)(root);
136
+ backend.initialize();
137
+ try {
138
+ const limit = Math.max(1, parseInt(String((_a = opts.limit) !== null && _a !== void 0 ? _a : '10'), 10) || 10);
139
+ console.log((0, advisory_report_1.formatAdvisoryMetrics)(backend, { limit }));
140
+ }
141
+ finally {
142
+ backend.close();
143
+ }
144
+ });
145
+ advisory
146
+ .command('handoff')
147
+ .description('Build a structured advisory handoff for cm-skill-health or cm-skill-evolution')
148
+ .requiredOption('--for <consumer>', 'cm-skill-health | cm-skill-evolution')
149
+ .option('--analysis <id>', 'analysis id prefix (default: latest)')
150
+ .option('--skill <name>', 'override target skill')
151
+ .option('--format <f>', 'md | json', 'md')
152
+ .option('--project <dir>')
153
+ .action((opts) => {
154
+ var _a;
155
+ const consumer = String(opts.for);
156
+ if (consumer !== 'cm-skill-health' && consumer !== 'cm-skill-evolution') {
157
+ console.error(chalk_1.default.red('Invalid --for value. Use cm-skill-health or cm-skill-evolution.'));
158
+ process.exit(1);
159
+ }
160
+ const root = projectPath(opts.project);
161
+ const backend = (0, storage_backend_1.getBackend)(root);
162
+ backend.initialize();
163
+ try {
164
+ const handoff = (0, advisory_handoff_1.buildAdvisoryHandoff)(backend, {
165
+ consumer,
166
+ analysisId: opts.analysis,
167
+ skill: opts.skill,
168
+ });
169
+ const format = String((_a = opts.format) !== null && _a !== void 0 ? _a : 'md').toLowerCase();
170
+ if (format === 'json')
171
+ console.log(JSON.stringify(handoff, null, 2));
172
+ else
173
+ console.log((0, advisory_handoff_1.formatAdvisoryHandoffMarkdown)(handoff));
174
+ }
175
+ catch (error) {
176
+ console.error(chalk_1.default.red(error.message));
177
+ process.exit(1);
178
+ }
179
+ finally {
180
+ backend.close();
181
+ }
182
+ });
103
183
  const sprint = program.command('sprint').description('Opinionated pipeline + .cm/sprint Context Bus');
104
184
  sprint
105
185
  .command('init')
@@ -413,6 +493,34 @@ function registerEngineeringCommands(program) {
413
493
  console.log(chalk_1.default.dim(` ${s.reason}`));
414
494
  }
415
495
  });
496
+ const indexer = program.command('index').description('Project intelligence indexing');
497
+ indexer
498
+ .command('skills')
499
+ .description('Detect tech stack and build .cm/project-skills.md')
500
+ .option('--project <dir>')
501
+ .action((opts) => {
502
+ const root = projectPath(opts.project);
503
+ // Lazy load to avoid module compilation issues at boot if not used
504
+ const { generateProjectSkillsIndex } = require('../../indexer/skills');
505
+ const idx = generateProjectSkillsIndex(root);
506
+ const dotCm = path_1.default.join(root, '.cm');
507
+ if (!fs_1.default.existsSync(dotCm)) {
508
+ fs_1.default.mkdirSync(dotCm, { recursive: true });
509
+ }
510
+ const out = path_1.default.join(dotCm, 'project-skills.md');
511
+ const md = [
512
+ '# Local Project Skills Index',
513
+ '',
514
+ `Detected Technologies: **${idx.detectedTechnologies.join(', ') || 'None'}**`,
515
+ '',
516
+ '## Recommended Community Skills',
517
+ ...idx.recommendedSkills.map((s) => `- \`${s}\``),
518
+ '',
519
+ '> Autogenerated by `cm index skills`. Agents should run `npx skills add <skill>` if needed.'
520
+ ].join('\n');
521
+ fs_1.default.writeFileSync(out, md, 'utf-8');
522
+ console.log(chalk_1.default.green(`Indexed ${idx.detectedTechnologies.length} technologies and ${idx.recommendedSkills.length} skills to ${out}`));
523
+ });
416
524
  }
417
525
  function browseRequest(port, pathname, method, auth, body) {
418
526
  return new Promise((resolve, reject) => {
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerEvolveCommands = registerEvolveCommands;
4
+ const skill_evolver_1 = require("../../skill-evolver");
5
+ const learning_promoter_1 = require("../../learning-promoter");
6
+ const advisory_handoff_1 = require("../../advisory-handoff");
7
+ const storage_backend_1 = require("../../storage-backend");
8
+ // ─── Evolution CLI Commands ─────────────────────────────────────────────────
9
+ function registerEvolveCommands(program) {
10
+ const evolve = program
11
+ .command('evolve')
12
+ .description('Skill Evolution Engine — self-improving skills via FIX/DERIVED/CAPTURED modes');
13
+ evolve
14
+ .command('status')
15
+ .description('Show skill evolution status and records')
16
+ .option('-p, --project <path>', 'Project path', process.cwd())
17
+ .action((opts) => {
18
+ var _a;
19
+ const evolver = new skill_evolver_1.SkillEvolver(opts.project);
20
+ const records = evolver.listSkillRecords();
21
+ if (records.length === 0) {
22
+ console.log('🧬 No skill evolution records yet. Skills will begin evolving after task executions.');
23
+ return;
24
+ }
25
+ console.log('🧬 Skill Evolution Records');
26
+ console.log('─'.repeat(70));
27
+ console.log(`${'Skill'.padEnd(30)} ${'Origin'.padEnd(10)} ${'Gen'.padEnd(5)} ${'Evolutions'.padEnd(12)} Last Mode`);
28
+ console.log('─'.repeat(70));
29
+ for (const record of records) {
30
+ console.log(`${record.skill_name.padEnd(30)} ${record.origin.padEnd(10)} ${String(record.generation).padEnd(5)} ${String(record.evolution_count).padEnd(12)} ${(_a = record.last_evolution_mode) !== null && _a !== void 0 ? _a : '-'}`);
31
+ }
32
+ });
33
+ evolve
34
+ .command('run <mode> <skill>')
35
+ .description('Execute evolution on a skill (modes: FIX, DERIVED, CAPTURED)')
36
+ .option('-p, --project <path>', 'Project path', process.cwd())
37
+ .option('-c, --confidence <n>', 'Override confidence threshold', '0.85')
38
+ .action((mode, skill, opts) => {
39
+ const upperMode = mode.toUpperCase();
40
+ if (!['FIX', 'DERIVED', 'CAPTURED'].includes(upperMode)) {
41
+ console.error(`❌ Invalid mode: ${mode}. Must be FIX, DERIVED, or CAPTURED.`);
42
+ process.exit(1);
43
+ }
44
+ const evolver = new skill_evolver_1.SkillEvolver(opts.project);
45
+ const result = evolver.evolve(upperMode, skill, parseFloat(opts.confidence));
46
+ console.log((0, skill_evolver_1.formatEvolutionResult)(result));
47
+ });
48
+ evolve
49
+ .command('auto')
50
+ .description('Auto-evolve based on latest advisory handoff')
51
+ .option('-p, --project <path>', 'Project path', process.cwd())
52
+ .action((opts) => {
53
+ try {
54
+ const backend = (0, storage_backend_1.getBackend)(opts.project);
55
+ backend.initialize();
56
+ const handoff = (0, advisory_handoff_1.buildAdvisoryHandoff)(backend, { consumer: 'cm-skill-evolution' });
57
+ const evolver = new skill_evolver_1.SkillEvolver(opts.project, backend);
58
+ const result = evolver.evolveFromAdvisory(handoff);
59
+ console.log((0, skill_evolver_1.formatEvolutionResult)(result));
60
+ }
61
+ catch (err) {
62
+ console.error(`❌ Auto-evolve failed: ${err instanceof Error ? err.message : err}`);
63
+ }
64
+ });
65
+ evolve
66
+ .command('history')
67
+ .description('Show evolution history')
68
+ .option('-p, --project <path>', 'Project path', process.cwd())
69
+ .option('-s, --skill <name>', 'Filter by skill name')
70
+ .option('-n, --limit <n>', 'Max entries', '20')
71
+ .action((opts) => {
72
+ const evolver = new skill_evolver_1.SkillEvolver(opts.project);
73
+ const history = evolver.getHistory(opts.skill, parseInt(opts.limit));
74
+ console.log((0, skill_evolver_1.formatEvolutionHistory)(history));
75
+ });
76
+ evolve
77
+ .command('rollback <skill>')
78
+ .description('Rollback a skill to its pre-evolution backup')
79
+ .option('-p, --project <path>', 'Project path', process.cwd())
80
+ .action((skill, opts) => {
81
+ const evolver = new skill_evolver_1.SkillEvolver(opts.project);
82
+ const result = evolver.rollback(skill);
83
+ console.log((0, skill_evolver_1.formatEvolutionResult)(result));
84
+ });
85
+ // ─── Learning Promotion ─────────────────────────────────────────────────
86
+ evolve
87
+ .command('candidates')
88
+ .description('Show learnings that qualify for promotion to skills')
89
+ .option('-p, --project <path>', 'Project path', process.cwd())
90
+ .action((opts) => {
91
+ const promoter = new learning_promoter_1.LearningPromoter(opts.project);
92
+ const candidates = promoter.findCandidates();
93
+ console.log((0, learning_promoter_1.formatPromotionCandidates)(candidates));
94
+ });
95
+ evolve
96
+ .command('promote <learningId>')
97
+ .description('Promote a specific learning to a reusable skill')
98
+ .option('-p, --project <path>', 'Project path', process.cwd())
99
+ .action((learningId, opts) => {
100
+ const promoter = new learning_promoter_1.LearningPromoter(opts.project);
101
+ const result = promoter.promote(learningId);
102
+ const icon = result.promoted ? '✅' : '❌';
103
+ console.log(`${icon} ${result.reason}`);
104
+ if (result.promoted) {
105
+ console.log(` Skill: ${result.skillName}`);
106
+ console.log(` Path: ${result.skillPath}`);
107
+ }
108
+ });
109
+ evolve
110
+ .command('auto-promote')
111
+ .description('Auto-promote the top learning candidate to a skill')
112
+ .option('-p, --project <path>', 'Project path', process.cwd())
113
+ .action((opts) => {
114
+ const promoter = new learning_promoter_1.LearningPromoter(opts.project);
115
+ const result = promoter.autoPromote();
116
+ if (!result) {
117
+ console.log('📚 No learnings qualify for auto-promotion yet.');
118
+ return;
119
+ }
120
+ const icon = result.promoted ? '✅' : '❌';
121
+ console.log(`${icon} ${result.reason}`);
122
+ });
123
+ }
@@ -0,0 +1,104 @@
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.registerMcpServeCommands = registerMcpServeCommands;
7
+ const child_process_1 = require("child_process");
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const os_1 = __importDefault(require("os"));
11
+ const chalk_1 = __importDefault(require("chalk"));
12
+ function registerMcpServeCommands(program) {
13
+ program
14
+ .command('mcp-serve')
15
+ .description('Start CodyMaster MCP context server (stdio transport for Goose, Claude Desktop, etc.)')
16
+ .option('--project <path>', 'Project root directory (default: current working directory)')
17
+ .option('--print-config', 'Print Goose/Claude Desktop JSON config snippet and exit')
18
+ .option('--install-claude', 'Auto-install MCP servers into Claude Desktop / Cowork config')
19
+ .action((opts) => {
20
+ var _a;
21
+ const projectPath = path_1.default.resolve((_a = opts.project) !== null && _a !== void 0 ? _a : process.cwd());
22
+ if (opts.installClaude) {
23
+ let configPath = '';
24
+ if (process.platform === 'win32') {
25
+ configPath = path_1.default.join(process.env.APPDATA || '', 'Claude', 'claude_desktop_config.json');
26
+ }
27
+ else if (process.platform === 'darwin') {
28
+ configPath = path_1.default.join(os_1.default.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
29
+ }
30
+ else {
31
+ console.error(chalk_1.default.red('Auto-install is currently only supported on Windows and macOS.'));
32
+ process.exit(1);
33
+ }
34
+ let config = {};
35
+ if (fs_1.default.existsSync(configPath)) {
36
+ try {
37
+ config = JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
38
+ }
39
+ catch (e) {
40
+ console.error(chalk_1.default.red(`Failed to parse ${configPath}: ${e.message}`));
41
+ process.exit(1);
42
+ }
43
+ }
44
+ if (!config.mcpServers)
45
+ config.mcpServers = {};
46
+ const serverPath = path_1.default.join(__dirname, '..', '..', '..', 'dist', 'mcp-context-server.js');
47
+ const dashboardPath = path_1.default.join(__dirname, '..', '..', '..', 'scripts', 'mcp-bridge.js');
48
+ config.mcpServers['cm-context'] = {
49
+ command: process.execPath,
50
+ args: [serverPath, '--project', projectPath],
51
+ env: { 'CM_PROJECT_PATH': projectPath }
52
+ };
53
+ config.mcpServers['cm-dashboard'] = {
54
+ command: process.execPath,
55
+ args: [dashboardPath]
56
+ };
57
+ const configDir = path_1.default.dirname(configPath);
58
+ if (!fs_1.default.existsSync(configDir))
59
+ fs_1.default.mkdirSync(configDir, { recursive: true });
60
+ fs_1.default.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
61
+ console.log(chalk_1.default.green(`🎉 Installed successfully into Claude Desktop: ${configPath}`));
62
+ process.exit(0);
63
+ }
64
+ if (opts.printConfig) {
65
+ const gooseConfig = {
66
+ id: 'codymaster',
67
+ name: 'CodyMaster Intelligence Layer',
68
+ type: 'stdio',
69
+ cmd: 'npx',
70
+ args: ['codymaster', 'mcp-serve', '--project', projectPath],
71
+ };
72
+ const claudeConfig = {
73
+ mcpServers: {
74
+ 'cm-context': {
75
+ command: process.execPath,
76
+ args: [
77
+ path_1.default.join(__dirname, '..', '..', '..', 'dist', 'mcp-context-server.js'),
78
+ '--project',
79
+ projectPath,
80
+ ],
81
+ },
82
+ },
83
+ };
84
+ console.log(chalk_1.default.bold('\nGoose config (add to ~/.config/goose/config.yaml extensions):'));
85
+ console.log(JSON.stringify(gooseConfig, null, 2));
86
+ console.log(chalk_1.default.bold('\nClaude Desktop config (add to mcpServers in claude_desktop_config.json):'));
87
+ console.log(JSON.stringify(claudeConfig.mcpServers, null, 2));
88
+ process.exit(0);
89
+ }
90
+ const serverPath = path_1.default.join(__dirname, '..', '..', '..', 'dist', 'mcp-context-server.js');
91
+ if (!fs_1.default.existsSync(serverPath)) {
92
+ console.error(chalk_1.default.red(`Error: MCP server not found at ${serverPath}`));
93
+ console.error(chalk_1.default.yellow('Run `npm run build` first to compile the server.'));
94
+ process.exit(1);
95
+ }
96
+ console.error(chalk_1.default.dim(`[CodyMaster] Starting MCP server for project: ${projectPath}`));
97
+ const child = (0, child_process_1.spawn)(process.execPath, [serverPath, '--project', projectPath], {
98
+ stdio: 'inherit',
99
+ });
100
+ child.on('exit', (code) => process.exit(code !== null && code !== void 0 ? code : 0));
101
+ process.on('SIGINT', () => child.kill('SIGINT'));
102
+ process.on('SIGTERM', () => child.kill('SIGTERM'));
103
+ });
104
+ }