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.
- package/CHANGELOG.md +74 -8
- package/README.md +192 -95
- package/dist/advisory-handoff.js +89 -0
- package/dist/advisory-report.js +105 -0
- package/dist/browse-server.js +251 -0
- package/dist/cli/command-registry.js +34 -0
- package/dist/cli/commands/agent.js +120 -0
- package/dist/cli/commands/bench.js +69 -0
- package/dist/cli/commands/brain.js +108 -0
- package/dist/cli/commands/dashboard.js +93 -0
- package/dist/cli/commands/design-studio.js +111 -0
- package/dist/cli/commands/distro.js +25 -0
- package/dist/cli/commands/engineering.js +596 -0
- package/dist/cli/commands/evolve.js +123 -0
- package/dist/cli/commands/mcp-serve.js +104 -0
- package/dist/cli/commands/project.js +324 -0
- package/dist/cli/commands/skill-chain.js +269 -0
- package/dist/cli/commands/system.js +89 -0
- package/dist/cli/commands/task.js +254 -0
- package/dist/cli/update-check.js +83 -0
- package/dist/cm-config.js +92 -0
- package/dist/cm-suggest.js +77 -0
- 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/distro-validate.js +54 -0
- package/dist/execution-analyzer.js +138 -0
- package/dist/guardian-core.js +74 -0
- package/dist/index.js +36 -2759
- 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 +289 -1
- package/dist/mcp-skills-tools.js +81 -0
- package/dist/retro-summary.js +70 -0
- package/dist/second-opinion-providers.js +79 -0
- 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/sprint-pipeline.js +228 -0
- package/dist/storage-backend.js +14 -67
- package/dist/token-budget.js +88 -0
- package/dist/utils/cli-utils.js +76 -0
- package/dist/utils/skill-utils.js +32 -0
- package/package.json +17 -7
- package/scripts/build-skills.mjs +51 -0
- package/scripts/gate-0-repo-hygiene.js +75 -0
- package/scripts/postinstall.js +34 -28
- package/scripts/security-scan.js +1 -1
- package/scripts/validate-skills.mjs +42 -0
- package/skills/CLAUDE.md +2 -7
- package/skills/_shared/helpers.md +2 -8
- package/skills/cm-ads-tracker/SKILL.md +3 -6
- package/skills/cm-browse/SKILL.md +34 -0
- package/skills/cm-conductor-worktrees/SKILL.md +28 -0
- package/skills/cm-content-factory/SKILL.md +1 -1
- package/skills/cm-content-factory/landing/docs/content/changelog.md +36 -0
- package/skills/cm-content-factory/landing/docs/content/deployment.md +46 -0
- package/skills/cm-content-factory/landing/docs/content/execution-flow.md +67 -0
- package/skills/cm-content-factory/landing/docs/content/memory-system.md +38 -0
- package/skills/cm-content-factory/landing/docs/content/openspace.md +27 -0
- package/skills/cm-content-factory/landing/docs/content/use-cases.md +26 -0
- package/skills/cm-content-factory/landing/docs/content/v5-intro.md +28 -0
- package/skills/cm-content-factory/landing/docs/index.html +240 -0
- package/skills/cm-content-factory/landing/index.html +100 -100
- package/skills/cm-content-factory/landing/script.js +42 -0
- package/skills/cm-content-factory/landing/translations.js +400 -400
- package/skills/cm-continuity/SKILL.md +32 -33
- package/skills/cm-design-studio/SKILL.md +34 -0
- package/skills/cm-ecosystem-roadmap/SKILL.md +15 -0
- package/skills/cm-engineering-meta/SKILL.md +73 -0
- package/skills/cm-growth-hacking/SKILL.md +1 -12
- package/skills/cm-guardian-runtime/SKILL.md +26 -0
- package/skills/cm-mcp-engineering/SKILL.md +22 -0
- package/skills/cm-notebooklm/SKILL.md +1 -17
- package/skills/cm-post-deploy-canary/SKILL.md +22 -0
- package/skills/cm-project-bootstrap/SKILL.md +11 -0
- package/skills/cm-qa-visual-cli/SKILL.md +22 -0
- package/skills/cm-retro-cli/SKILL.md +23 -0
- package/skills/cm-second-opinion-cli/SKILL.md +23 -0
- package/skills/cm-secret-shield/SKILL.md +2 -2
- 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 +33 -0
- package/skills/cm-start/SKILL.md +0 -10
- package/skills/cm-tdd/SKILL.md +59 -72
- package/skills/profiles/README.md +21 -0
- package/skills/profiles/core.txt +23 -0
- package/skills/profiles/design.txt +6 -0
- package/skills/profiles/full.txt +62 -0
- package/skills/profiles/growth.txt +10 -0
- package/skills/profiles/knowledge.txt +7 -0
- package/install.sh +0 -901
- package/scripts/test-gemini.js +0 -13
- package/skills/cm-frappe-agent/SKILL.md +0 -134
- package/skills/cm-frappe-agent/agents/doctype-architect.md +0 -596
- package/skills/cm-frappe-agent/agents/erpnext-customizer.md +0 -643
- package/skills/cm-frappe-agent/agents/frappe-backend.md +0 -814
- package/skills/cm-frappe-agent/agents/frappe-custom-frontend.md +0 -557
- package/skills/cm-frappe-agent/agents/frappe-debugger.md +0 -625
- package/skills/cm-frappe-agent/agents/frappe-fixer.md +0 -275
- package/skills/cm-frappe-agent/agents/frappe-frontend.md +0 -660
- package/skills/cm-frappe-agent/agents/frappe-installer.md +0 -158
- package/skills/cm-frappe-agent/agents/frappe-performance.md +0 -307
- package/skills/cm-frappe-agent/agents/frappe-planner.md +0 -419
- package/skills/cm-frappe-agent/agents/frappe-remote-ops.md +0 -153
- package/skills/cm-frappe-agent/agents/github-workflow.md +0 -286
- package/skills/cm-frappe-agent/commands/frappe-app.md +0 -351
- package/skills/cm-frappe-agent/commands/frappe-backend.md +0 -162
- package/skills/cm-frappe-agent/commands/frappe-bench.md +0 -254
- package/skills/cm-frappe-agent/commands/frappe-debug.md +0 -263
- package/skills/cm-frappe-agent/commands/frappe-doctype-create.md +0 -272
- package/skills/cm-frappe-agent/commands/frappe-doctype-field.md +0 -310
- package/skills/cm-frappe-agent/commands/frappe-erpnext.md +0 -210
- package/skills/cm-frappe-agent/commands/frappe-fix.md +0 -59
- package/skills/cm-frappe-agent/commands/frappe-frontend.md +0 -210
- package/skills/cm-frappe-agent/commands/frappe-fullstack.md +0 -243
- package/skills/cm-frappe-agent/commands/frappe-github.md +0 -57
- package/skills/cm-frappe-agent/commands/frappe-install.md +0 -52
- package/skills/cm-frappe-agent/commands/frappe-plan.md +0 -442
- package/skills/cm-frappe-agent/commands/frappe-remote.md +0 -58
- package/skills/cm-frappe-agent/commands/frappe-test.md +0 -356
- package/skills/cm-frappe-agent/docs/README.md +0 -51
- package/skills/cm-frappe-agent/docs/agents-catalog.md +0 -113
- package/skills/cm-frappe-agent/docs/architecture.md +0 -149
- package/skills/cm-frappe-agent/docs/commands-catalog.md +0 -82
- package/skills/cm-frappe-agent/docs/resources-catalog.md +0 -66
- package/skills/cm-frappe-agent/docs/sitemap-urls.txt +0 -52
- package/skills/cm-frappe-agent/docs/sitemap.md +0 -81
- package/skills/cm-frappe-agent/docs/sop/user-guide.md +0 -178
- package/skills/cm-frappe-agent/docs/sop/vibe-coding-guide.md +0 -122
- package/skills/cm-frappe-agent/resources/7-layer-architecture.md +0 -985
- package/skills/cm-frappe-agent/resources/bench_commands.md +0 -73
- package/skills/cm-frappe-agent/resources/code-patterns-guide.md +0 -948
- package/skills/cm-frappe-agent/resources/common_pitfalls.md +0 -266
- package/skills/cm-frappe-agent/resources/doctype-registry.md +0 -158
- package/skills/cm-frappe-agent/resources/installation-guide.md +0 -289
- package/skills/cm-frappe-agent/resources/rest-api-patterns.md +0 -182
- package/skills/cm-frappe-agent/resources/scaffold_checklist.md +0 -82
- package/skills/cm-frappe-agent/resources/upgrade_patterns.md +0 -113
- package/skills/cm-frappe-agent/resources/web-form-patterns.md +0 -252
- package/skills/cm-frappe-agent/skills/bench-commands/SKILL.md +0 -621
- package/skills/cm-frappe-agent/skills/client-scripts/SKILL.md +0 -642
- package/skills/cm-frappe-agent/skills/doctype-patterns/SKILL.md +0 -576
- package/skills/cm-frappe-agent/skills/frappe-api/SKILL.md +0 -740
- package/skills/cm-frappe-agent/skills/remote-operations/SKILL.md +0 -47
- package/skills/cm-frappe-agent/skills/server-scripts/SKILL.md +0 -608
- package/skills/cm-frappe-agent/skills/web-forms/SKILL.md +0 -46
- package/skills/frappe-app-builder.zip +0 -0
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
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.registerProjectCommands = registerProjectCommands;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
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 registerProjectCommands(program) {
|
|
14
|
+
// ─── Project Command ───────────────────────────────────────────────────────
|
|
15
|
+
program
|
|
16
|
+
.command('project <cmd> [args...]')
|
|
17
|
+
.alias('p')
|
|
18
|
+
.description('Project management (add|list|rm)')
|
|
19
|
+
.action((cmd, args, opts) => {
|
|
20
|
+
switch (cmd) {
|
|
21
|
+
case 'add':
|
|
22
|
+
projectAdd(args[0], opts);
|
|
23
|
+
break;
|
|
24
|
+
case 'list':
|
|
25
|
+
case 'ls':
|
|
26
|
+
projectList();
|
|
27
|
+
break;
|
|
28
|
+
case 'rm':
|
|
29
|
+
case 'delete':
|
|
30
|
+
projectRemove(args[0]);
|
|
31
|
+
break;
|
|
32
|
+
default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: add, list, rm')]));
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
// ─── Deploy Command ────────────────────────────────────────────────────────
|
|
36
|
+
program
|
|
37
|
+
.command('deploy <cmd> [args...]')
|
|
38
|
+
.alias('d')
|
|
39
|
+
.description('Deployment management (staging|production|list)')
|
|
40
|
+
.option('-p, --project <name>', 'Project name or ID')
|
|
41
|
+
.option('-m, --message <msg>', 'Deployment message')
|
|
42
|
+
.option('-c, --commit <sha>', 'Commit SHA')
|
|
43
|
+
.option('-b, --branch <name>', 'Branch name', 'main')
|
|
44
|
+
.option('--agent <agent>', 'Agent name')
|
|
45
|
+
.action((cmd, args, opts) => {
|
|
46
|
+
switch (cmd) {
|
|
47
|
+
case 'staging':
|
|
48
|
+
case 'stg':
|
|
49
|
+
deployRecord('staging', opts);
|
|
50
|
+
break;
|
|
51
|
+
case 'production':
|
|
52
|
+
case 'prod':
|
|
53
|
+
deployRecord('production', opts);
|
|
54
|
+
break;
|
|
55
|
+
case 'list':
|
|
56
|
+
case 'ls':
|
|
57
|
+
deployList(opts);
|
|
58
|
+
break;
|
|
59
|
+
default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: staging, production, list')]));
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
// ─── Rollback Command ───────────────────────────────────────────────────────
|
|
63
|
+
program
|
|
64
|
+
.command('rollback <deployId>')
|
|
65
|
+
.alias('rb')
|
|
66
|
+
.description('Rollback a deployment')
|
|
67
|
+
.option('--agent <agent>', 'Agent name')
|
|
68
|
+
.action((deployId, opts) => {
|
|
69
|
+
const data = (0, data_1.loadData)();
|
|
70
|
+
const dep = data.deployments.find((d) => d.id === deployId || d.id.startsWith(deployId));
|
|
71
|
+
if (!dep) {
|
|
72
|
+
console.log((0, box_1.renderResult)('error', `Deployment not found: ${deployId}`));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (dep.status === 'rolled_back') {
|
|
76
|
+
console.log((0, box_1.renderResult)('warning', 'Already rolled back.'));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
dep.status = 'rolled_back';
|
|
80
|
+
const now = new Date().toISOString();
|
|
81
|
+
const rollback = {
|
|
82
|
+
id: crypto_1.default.randomUUID(), projectId: dep.projectId, env: dep.env, status: 'success',
|
|
83
|
+
commit: '', branch: dep.branch, agent: opts.agent || '', message: `Rollback of ${(0, data_1.shortId)(dep.id)}`,
|
|
84
|
+
startedAt: now, finishedAt: now, rollbackOf: dep.id,
|
|
85
|
+
};
|
|
86
|
+
data.deployments.unshift(rollback);
|
|
87
|
+
(0, data_1.logActivity)(data, 'rollback', `Rolled back ${dep.env} deploy: ${dep.message}`, dep.projectId, opts.agent || '', { originalDeployId: dep.id, rollbackId: rollback.id });
|
|
88
|
+
(0, data_1.saveData)(data);
|
|
89
|
+
console.log((0, box_1.renderResult)('success', 'Rollback complete!', [
|
|
90
|
+
`${(0, theme_1.dim)('Original:')} ${(0, theme_1.brand)((0, data_1.shortId)(dep.id))} ${(0, theme_1.dim)(`(${dep.env})`)}`,
|
|
91
|
+
`${(0, theme_1.dim)('Rollback ID:')} ${(0, theme_1.brand)((0, data_1.shortId)(rollback.id))}`,
|
|
92
|
+
`${(0, theme_1.dim)('Status:')} ${dep.message} → rolled back`,
|
|
93
|
+
]));
|
|
94
|
+
});
|
|
95
|
+
// ─── History Command ────────────────────────────────────────────────────────
|
|
96
|
+
program
|
|
97
|
+
.command('history')
|
|
98
|
+
.alias('h')
|
|
99
|
+
.description('Show activity history')
|
|
100
|
+
.option('-n, --limit <n>', 'Number of entries', '20')
|
|
101
|
+
.option('-p, --project <name>', 'Filter by project')
|
|
102
|
+
.action((opts) => {
|
|
103
|
+
const data = (0, data_1.loadData)();
|
|
104
|
+
let acts = data.activities;
|
|
105
|
+
if (opts.project) {
|
|
106
|
+
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
107
|
+
if (!p) {
|
|
108
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
acts = acts.filter((a) => a.projectId === p.id);
|
|
112
|
+
}
|
|
113
|
+
const limit = parseInt(opts.limit) || 20;
|
|
114
|
+
acts = acts.slice(0, limit);
|
|
115
|
+
if (acts.length === 0) {
|
|
116
|
+
console.log(`\n ${(0, theme_1.dim)('No activity yet.')}\n`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const ACT_ICONS = {
|
|
120
|
+
'task_created': '✨', 'task_moved': '↔️', 'task_done': '✅', 'task_deleted': '🗑️', 'task_updated': '✏️',
|
|
121
|
+
'project_created': '📦', 'project_deleted': '🗑️',
|
|
122
|
+
'deploy_staging': '🟡', 'deploy_production': '🚀', 'deploy_failed': '❌', 'rollback': '⏪',
|
|
123
|
+
'git_push': '📤', 'changelog_added': '📝',
|
|
124
|
+
};
|
|
125
|
+
console.log((0, box_1.renderCommandHeader)(`Activity History (latest ${acts.length})`, '📜'));
|
|
126
|
+
for (const a of acts) {
|
|
127
|
+
const icon = ACT_ICONS[a.type] || '📌';
|
|
128
|
+
const proj = data.projects.find((p) => p.id === a.projectId);
|
|
129
|
+
const projTag = proj ? (0, theme_1.dim)(` [${proj.name}]`) : '';
|
|
130
|
+
const agentTag = a.agent ? (0, theme_1.dim)(` @${a.agent}`) : '';
|
|
131
|
+
const time = (0, cli_utils_1.formatTimeAgoCli)(a.createdAt);
|
|
132
|
+
console.log(` ${icon} ${a.message}${projTag}${agentTag} ${(0, theme_1.dim)(`← ${time}`)}`);
|
|
133
|
+
}
|
|
134
|
+
console.log();
|
|
135
|
+
});
|
|
136
|
+
// ─── Changelog Command ─────────────────────────────────────────────────────
|
|
137
|
+
program
|
|
138
|
+
.command('changelog <cmd> [args...]')
|
|
139
|
+
.alias('cl')
|
|
140
|
+
.description('Changelog management (add|list)')
|
|
141
|
+
.option('-p, --project <name>', 'Project name or ID')
|
|
142
|
+
.option('--agent <agent>', 'Agent name')
|
|
143
|
+
.action((cmd, args, opts) => {
|
|
144
|
+
switch (cmd) {
|
|
145
|
+
case 'add':
|
|
146
|
+
changelogAdd(args, opts);
|
|
147
|
+
break;
|
|
148
|
+
case 'list':
|
|
149
|
+
case 'ls':
|
|
150
|
+
changelogList(opts);
|
|
151
|
+
break;
|
|
152
|
+
default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: add, list')]));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
function projectAdd(name, opts) {
|
|
157
|
+
if (!name) {
|
|
158
|
+
console.log((0, box_1.renderResult)('error', 'Name required. Usage: cm project add "My Project"'));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const data = (0, data_1.loadData)();
|
|
162
|
+
const project = {
|
|
163
|
+
id: crypto_1.default.randomUUID(), name, path: process.cwd(), agents: [],
|
|
164
|
+
createdAt: new Date().toISOString(),
|
|
165
|
+
};
|
|
166
|
+
data.projects.push(project);
|
|
167
|
+
(0, data_1.logActivity)(data, 'project_created', `Project "${name}" created via CLI`, project.id);
|
|
168
|
+
(0, data_1.saveData)(data);
|
|
169
|
+
console.log((0, box_1.renderResult)('success', `Project created: ${name}`, [`${(0, theme_1.dim)('ID:')} ${(0, theme_1.brand)((0, data_1.shortId)(project.id))}`]));
|
|
170
|
+
}
|
|
171
|
+
function projectList() {
|
|
172
|
+
const data = (0, data_1.loadData)();
|
|
173
|
+
if (data.projects.length === 0) {
|
|
174
|
+
console.log(`\n ${(0, theme_1.dim)('No projects found.')}\n`);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
console.log((0, box_1.renderCommandHeader)('Projects', '📦'));
|
|
178
|
+
for (const p of data.projects) {
|
|
179
|
+
const tasks = data.tasks.filter((t) => t.projectId === p.id);
|
|
180
|
+
const done = tasks.filter((t) => t.column === 'done').length;
|
|
181
|
+
console.log(` ${(0, theme_1.brand)((0, data_1.shortId)(p.id))} ${(0, cli_utils_1.padRight)(p.name, 30)} ${(0, theme_1.dim)(`${done}/${tasks.length} tasks`)}`);
|
|
182
|
+
}
|
|
183
|
+
console.log();
|
|
184
|
+
}
|
|
185
|
+
function projectRemove(query) {
|
|
186
|
+
if (!query) {
|
|
187
|
+
console.log((0, box_1.renderResult)('error', 'Query required. Usage: cm project rm <name|id>'));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const data = (0, data_1.loadData)();
|
|
191
|
+
const p = (0, data_1.findProjectByNameOrId)(data, query);
|
|
192
|
+
if (!p) {
|
|
193
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${query}`));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
data.projects = data.projects.filter((proj) => proj.id !== p.id);
|
|
197
|
+
data.tasks = data.tasks.filter((t) => t.projectId !== p.id);
|
|
198
|
+
(0, data_1.logActivity)(data, 'project_deleted', `Project "${p.name}" deleted`, p.id);
|
|
199
|
+
(0, data_1.saveData)(data);
|
|
200
|
+
console.log((0, box_1.renderResult)('success', `Project deleted: ${p.name}`));
|
|
201
|
+
}
|
|
202
|
+
function deployRecord(env, opts) {
|
|
203
|
+
const data = (0, data_1.loadData)();
|
|
204
|
+
let projectId;
|
|
205
|
+
if (opts.project) {
|
|
206
|
+
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
207
|
+
if (!p) {
|
|
208
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
projectId = p.id;
|
|
212
|
+
}
|
|
213
|
+
else if (data.projects.length > 0) {
|
|
214
|
+
projectId = data.projects[0].id;
|
|
215
|
+
}
|
|
216
|
+
const now = new Date().toISOString();
|
|
217
|
+
const dep = {
|
|
218
|
+
id: crypto_1.default.randomUUID(), projectId: projectId || '', env, status: 'success',
|
|
219
|
+
commit: opts.commit || '', branch: opts.branch || 'main',
|
|
220
|
+
message: opts.message || 'Manual deployment',
|
|
221
|
+
agent: opts.agent || '', startedAt: now, finishedAt: now,
|
|
222
|
+
};
|
|
223
|
+
data.deployments.unshift(dep);
|
|
224
|
+
(0, data_1.logActivity)(data, env === 'staging' ? 'deploy_staging' : 'deploy_production', `Deployed to ${env}: ${dep.message}`, projectId, opts.agent || '', { deploymentId: dep.id });
|
|
225
|
+
(0, data_1.saveData)(data);
|
|
226
|
+
const envColor = env === 'production' ? theme_1.success : theme_1.warning;
|
|
227
|
+
const project = data.projects.find((p) => p.id === projectId);
|
|
228
|
+
const details = [
|
|
229
|
+
`${(0, theme_1.dim)('ID:')} ${(0, theme_1.brand)((0, data_1.shortId)(dep.id))}`,
|
|
230
|
+
`${(0, theme_1.dim)('Env:')} ${envColor(env)}`,
|
|
231
|
+
`${(0, theme_1.dim)('Project:')} ${(0, theme_1.brand)((project === null || project === void 0 ? void 0 : project.name) || '—')}`,
|
|
232
|
+
`${(0, theme_1.dim)('Message:')} ${dep.message}`,
|
|
233
|
+
];
|
|
234
|
+
if (dep.commit)
|
|
235
|
+
details.push(`${(0, theme_1.dim)('Commit:')} ${(0, theme_1.brand)(dep.commit)}`);
|
|
236
|
+
details.push(`${(0, theme_1.dim)('Branch:')} ${(0, theme_1.brand)(dep.branch)}`);
|
|
237
|
+
console.log((0, box_1.renderResult)('success', 'Deployment recorded!', details));
|
|
238
|
+
}
|
|
239
|
+
function deployList(opts) {
|
|
240
|
+
const data = (0, data_1.loadData)();
|
|
241
|
+
let deps = data.deployments;
|
|
242
|
+
if (opts.project) {
|
|
243
|
+
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
244
|
+
if (!p) {
|
|
245
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
deps = deps.filter((d) => d.projectId === p.id);
|
|
249
|
+
}
|
|
250
|
+
if (deps.length === 0) {
|
|
251
|
+
console.log(`\n ${(0, theme_1.dim)('No deployments yet.')}\n`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
console.log((0, box_1.renderCommandHeader)('Deployment History', '🚀'));
|
|
255
|
+
console.log((0, theme_1.dim)(' ' + (0, cli_utils_1.padRight)('ID', 10) + (0, cli_utils_1.padRight)('Env', 12) + (0, cli_utils_1.padRight)('Status', 14) + (0, cli_utils_1.padRight)('Message', 32) + (0, cli_utils_1.padRight)('Branch', 12) + 'Time'));
|
|
256
|
+
console.log((0, theme_1.dim)(' ' + '─'.repeat(100)));
|
|
257
|
+
for (const dep of deps.slice(0, 20)) {
|
|
258
|
+
const sc = theme_1.STATUS[dep.status] || chalk_1.default.white;
|
|
259
|
+
const ec = dep.env === 'production' ? theme_1.success : theme_1.warning;
|
|
260
|
+
const timeAgo = (0, cli_utils_1.formatTimeAgoCli)(dep.startedAt);
|
|
261
|
+
const rollbackFlag = dep.rollbackOf ? ' ⏪' : '';
|
|
262
|
+
console.log(' ' + (0, theme_1.dim)((0, cli_utils_1.padRight)((0, data_1.shortId)(dep.id), 10)) + ec((0, cli_utils_1.padRight)(dep.env, 12)) + sc((0, cli_utils_1.padRight)(dep.status.replace('_', ' ') + rollbackFlag, 14)) + (0, cli_utils_1.padRight)(dep.message.substring(0, 30), 32) + (0, theme_1.dim)((0, cli_utils_1.padRight)(dep.branch || '—', 12)) + (0, theme_1.dim)(timeAgo));
|
|
263
|
+
}
|
|
264
|
+
console.log((0, theme_1.dim)(`\n Total: ${deps.length} deployments\n`));
|
|
265
|
+
}
|
|
266
|
+
function changelogAdd(args, opts) {
|
|
267
|
+
if (args.length < 2) {
|
|
268
|
+
console.log((0, box_1.renderResult)('error', 'Usage: cm changelog add <version> "<title>" [changes...]'));
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const data = (0, data_1.loadData)();
|
|
272
|
+
let projectId = '';
|
|
273
|
+
if (opts.project) {
|
|
274
|
+
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
275
|
+
if (!p) {
|
|
276
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
projectId = p.id;
|
|
280
|
+
}
|
|
281
|
+
else if (data.projects.length > 0) {
|
|
282
|
+
projectId = data.projects[0].id;
|
|
283
|
+
}
|
|
284
|
+
const version = args[0];
|
|
285
|
+
const title = args[1];
|
|
286
|
+
const changes = args.slice(2);
|
|
287
|
+
const entry = {
|
|
288
|
+
id: crypto_1.default.randomUUID(), projectId, version, title, changes,
|
|
289
|
+
agent: opts.agent || '', createdAt: new Date().toISOString(),
|
|
290
|
+
};
|
|
291
|
+
data.changelog.unshift(entry);
|
|
292
|
+
(0, data_1.logActivity)(data, 'changelog_added', `Changelog ${version}: ${title}`, projectId, opts.agent || '');
|
|
293
|
+
(0, data_1.saveData)(data);
|
|
294
|
+
const details = [`${(0, theme_1.dim)('Version:')} ${(0, theme_1.brand)(version)}`, `${(0, theme_1.dim)('Title:')} ${title}`];
|
|
295
|
+
if (changes.length > 0) {
|
|
296
|
+
changes.forEach(c => details.push(`${(0, theme_1.dim)('•')} ${c}`));
|
|
297
|
+
}
|
|
298
|
+
console.log((0, box_1.renderResult)('success', 'Changelog entry added!', details));
|
|
299
|
+
}
|
|
300
|
+
function changelogList(opts) {
|
|
301
|
+
const data = (0, data_1.loadData)();
|
|
302
|
+
let entries = data.changelog;
|
|
303
|
+
if (opts.project) {
|
|
304
|
+
const p = (0, data_1.findProjectByNameOrId)(data, opts.project);
|
|
305
|
+
if (!p) {
|
|
306
|
+
console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
entries = entries.filter((c) => c.projectId === p.id);
|
|
310
|
+
}
|
|
311
|
+
if (entries.length === 0) {
|
|
312
|
+
console.log(`\n ${(0, theme_1.dim)('No changelog entries.')}\n`);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
console.log((0, box_1.renderCommandHeader)('Changelog', '📝'));
|
|
316
|
+
for (const entry of entries) {
|
|
317
|
+
const proj = data.projects.find((p) => p.id === entry.projectId);
|
|
318
|
+
console.log((0, theme_1.brand)(` ${entry.version}`) + ` — ${entry.title}` + (0, theme_1.dim)(` (${(0, cli_utils_1.formatTimeAgoCli)(entry.createdAt)})${proj ? ' [' + proj.name + ']' : ''}`));
|
|
319
|
+
if (entry.changes.length > 0) {
|
|
320
|
+
entry.changes.forEach((c) => console.log((0, theme_1.dim)(` • ${c}`)));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
console.log();
|
|
324
|
+
}
|