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.
- package/CHANGELOG.md +55 -7
- package/README.md +142 -95
- package/dist/advisory-handoff.js +89 -0
- package/dist/advisory-report.js +105 -0
- package/dist/cli/command-registry.js +8 -0
- package/dist/cli/commands/bench.js +69 -0
- package/dist/cli/commands/brain.js +108 -0
- package/dist/cli/commands/engineering.js +108 -0
- package/dist/cli/commands/evolve.js +123 -0
- package/dist/cli/commands/mcp-serve.js +104 -0
- package/dist/cm-config.js +0 -18
- package/dist/codybench/judges/automated.js +31 -0
- package/dist/codybench/runners/claude-code.js +32 -0
- package/dist/codybench/suites/memory-retention.js +85 -0
- package/dist/codybench/suites/tdd-regression.js +35 -0
- package/dist/codybench/suites/token-efficiency.js +55 -0
- package/dist/codybench/types.js +2 -0
- package/dist/context-db.js +157 -0
- package/dist/continuity.js +2 -6
- package/dist/execution-analyzer.js +138 -0
- package/dist/indexer/skills-lib.js +533 -0
- package/dist/indexer/skills-map.js +1374 -0
- package/dist/indexer/skills.js +16 -0
- package/dist/learning-promoter.js +246 -0
- package/dist/mcp-context-server.js +230 -1
- package/dist/skill-chain.js +63 -1
- package/dist/skill-evolver.js +456 -0
- package/dist/skill-execution-cache.js +254 -0
- package/dist/smart-brain-router.js +184 -0
- package/dist/storage-backend.js +10 -8
- package/dist/token-budget.js +88 -0
- package/package.json +2 -3
- package/scripts/postinstall.js +10 -59
- package/skills/CLAUDE.md +0 -5
- package/skills/_shared/helpers.md +2 -8
- package/skills/cm-browse/SKILL.md +6 -0
- package/skills/cm-conductor-worktrees/SKILL.md +4 -0
- package/skills/cm-content-factory/landing/docs/content/changelog.md +4 -4
- package/skills/cm-content-factory/landing/docs/content/deployment.md +3 -3
- package/skills/cm-content-factory/landing/docs/content/execution-flow.md +8 -8
- package/skills/cm-content-factory/landing/docs/content/memory-system.md +38 -0
- package/skills/cm-content-factory/landing/docs/content/openspace.md +1 -1
- package/skills/cm-content-factory/landing/docs/content/use-cases.md +2 -2
- package/skills/cm-content-factory/landing/docs/content/v5-intro.md +3 -3
- package/skills/cm-content-factory/landing/docs/index.html +1 -1
- package/skills/cm-content-factory/landing/index.html +3 -3
- package/skills/cm-content-factory/landing/translations.js +37 -37
- package/skills/cm-continuity/SKILL.md +32 -33
- package/skills/cm-design-studio/SKILL.md +4 -0
- package/skills/cm-ecosystem-roadmap/SKILL.md +4 -0
- package/skills/cm-engineering-meta/SKILL.md +4 -0
- package/skills/cm-guardian-runtime/SKILL.md +5 -1
- package/skills/cm-mcp-engineering/SKILL.md +4 -0
- package/skills/cm-post-deploy-canary/SKILL.md +4 -0
- package/skills/cm-project-bootstrap/SKILL.md +11 -0
- package/skills/cm-qa-visual-cli/SKILL.md +4 -0
- package/skills/cm-retro-cli/SKILL.md +4 -0
- package/skills/cm-second-opinion-cli/SKILL.md +4 -0
- package/skills/cm-security-gate/SKILL.md +1 -0
- package/skills/cm-skill-chain/SKILL.md +25 -4
- package/skills/cm-skill-evolution/SKILL.md +83 -0
- package/skills/cm-skill-health/SKILL.md +83 -0
- package/skills/cm-skill-index/SKILL.md +11 -3
- package/skills/cm-skill-search/SKILL.md +49 -0
- package/skills/cm-skill-share/SKILL.md +58 -0
- package/skills/cm-sprint-bus/SKILL.md +4 -0
- package/skills/cm-start/SKILL.md +0 -10
- package/skills/cm-tdd/SKILL.md +2 -2
- package/skills/profiles/full.txt +4 -0
- package/install.sh +0 -1125
- package/scripts/viking-demo.ts +0 -105
- 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
|
+
}
|