codymaster 4.6.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/CHANGELOG.md +74 -8
  2. package/README.md +192 -95
  3. package/dist/advisory-handoff.js +89 -0
  4. package/dist/advisory-report.js +105 -0
  5. package/dist/browse-server.js +251 -0
  6. package/dist/cli/command-registry.js +34 -0
  7. package/dist/cli/commands/agent.js +120 -0
  8. package/dist/cli/commands/bench.js +69 -0
  9. package/dist/cli/commands/brain.js +108 -0
  10. package/dist/cli/commands/dashboard.js +93 -0
  11. package/dist/cli/commands/design-studio.js +111 -0
  12. package/dist/cli/commands/distro.js +25 -0
  13. package/dist/cli/commands/engineering.js +596 -0
  14. package/dist/cli/commands/evolve.js +123 -0
  15. package/dist/cli/commands/mcp-serve.js +104 -0
  16. package/dist/cli/commands/project.js +324 -0
  17. package/dist/cli/commands/skill-chain.js +269 -0
  18. package/dist/cli/commands/system.js +89 -0
  19. package/dist/cli/commands/task.js +254 -0
  20. package/dist/cli/update-check.js +83 -0
  21. package/dist/cm-config.js +92 -0
  22. package/dist/cm-suggest.js +77 -0
  23. package/dist/codybench/judges/automated.js +31 -0
  24. package/dist/codybench/runners/claude-code.js +32 -0
  25. package/dist/codybench/suites/memory-retention.js +85 -0
  26. package/dist/codybench/suites/tdd-regression.js +35 -0
  27. package/dist/codybench/suites/token-efficiency.js +55 -0
  28. package/dist/codybench/types.js +2 -0
  29. package/dist/context-db.js +157 -0
  30. package/dist/continuity.js +2 -6
  31. package/dist/distro-validate.js +54 -0
  32. package/dist/execution-analyzer.js +138 -0
  33. package/dist/guardian-core.js +74 -0
  34. package/dist/index.js +36 -2759
  35. package/dist/indexer/skills-lib.js +533 -0
  36. package/dist/indexer/skills-map.js +1374 -0
  37. package/dist/indexer/skills.js +16 -0
  38. package/dist/learning-promoter.js +246 -0
  39. package/dist/mcp-context-server.js +289 -1
  40. package/dist/mcp-skills-tools.js +81 -0
  41. package/dist/retro-summary.js +70 -0
  42. package/dist/second-opinion-providers.js +79 -0
  43. package/dist/skill-chain.js +63 -1
  44. package/dist/skill-evolver.js +456 -0
  45. package/dist/skill-execution-cache.js +254 -0
  46. package/dist/smart-brain-router.js +184 -0
  47. package/dist/sprint-pipeline.js +228 -0
  48. package/dist/storage-backend.js +14 -67
  49. package/dist/token-budget.js +88 -0
  50. package/dist/utils/cli-utils.js +76 -0
  51. package/dist/utils/skill-utils.js +32 -0
  52. package/package.json +17 -7
  53. package/scripts/build-skills.mjs +51 -0
  54. package/scripts/gate-0-repo-hygiene.js +75 -0
  55. package/scripts/postinstall.js +34 -28
  56. package/scripts/security-scan.js +1 -1
  57. package/scripts/validate-skills.mjs +42 -0
  58. package/skills/CLAUDE.md +2 -7
  59. package/skills/_shared/helpers.md +2 -8
  60. package/skills/cm-ads-tracker/SKILL.md +3 -6
  61. package/skills/cm-browse/SKILL.md +34 -0
  62. package/skills/cm-conductor-worktrees/SKILL.md +28 -0
  63. package/skills/cm-content-factory/SKILL.md +1 -1
  64. package/skills/cm-content-factory/landing/docs/content/changelog.md +36 -0
  65. package/skills/cm-content-factory/landing/docs/content/deployment.md +46 -0
  66. package/skills/cm-content-factory/landing/docs/content/execution-flow.md +67 -0
  67. package/skills/cm-content-factory/landing/docs/content/memory-system.md +38 -0
  68. package/skills/cm-content-factory/landing/docs/content/openspace.md +27 -0
  69. package/skills/cm-content-factory/landing/docs/content/use-cases.md +26 -0
  70. package/skills/cm-content-factory/landing/docs/content/v5-intro.md +28 -0
  71. package/skills/cm-content-factory/landing/docs/index.html +240 -0
  72. package/skills/cm-content-factory/landing/index.html +100 -100
  73. package/skills/cm-content-factory/landing/script.js +42 -0
  74. package/skills/cm-content-factory/landing/translations.js +400 -400
  75. package/skills/cm-continuity/SKILL.md +32 -33
  76. package/skills/cm-design-studio/SKILL.md +34 -0
  77. package/skills/cm-ecosystem-roadmap/SKILL.md +15 -0
  78. package/skills/cm-engineering-meta/SKILL.md +73 -0
  79. package/skills/cm-growth-hacking/SKILL.md +1 -12
  80. package/skills/cm-guardian-runtime/SKILL.md +26 -0
  81. package/skills/cm-mcp-engineering/SKILL.md +22 -0
  82. package/skills/cm-notebooklm/SKILL.md +1 -17
  83. package/skills/cm-post-deploy-canary/SKILL.md +22 -0
  84. package/skills/cm-project-bootstrap/SKILL.md +11 -0
  85. package/skills/cm-qa-visual-cli/SKILL.md +22 -0
  86. package/skills/cm-retro-cli/SKILL.md +23 -0
  87. package/skills/cm-second-opinion-cli/SKILL.md +23 -0
  88. package/skills/cm-secret-shield/SKILL.md +2 -2
  89. package/skills/cm-security-gate/SKILL.md +1 -0
  90. package/skills/cm-skill-chain/SKILL.md +25 -4
  91. package/skills/cm-skill-evolution/SKILL.md +83 -0
  92. package/skills/cm-skill-health/SKILL.md +83 -0
  93. package/skills/cm-skill-index/SKILL.md +11 -3
  94. package/skills/cm-skill-search/SKILL.md +49 -0
  95. package/skills/cm-skill-share/SKILL.md +58 -0
  96. package/skills/cm-sprint-bus/SKILL.md +33 -0
  97. package/skills/cm-start/SKILL.md +0 -10
  98. package/skills/cm-tdd/SKILL.md +59 -72
  99. package/skills/profiles/README.md +21 -0
  100. package/skills/profiles/core.txt +23 -0
  101. package/skills/profiles/design.txt +6 -0
  102. package/skills/profiles/full.txt +62 -0
  103. package/skills/profiles/growth.txt +10 -0
  104. package/skills/profiles/knowledge.txt +7 -0
  105. package/install.sh +0 -901
  106. package/scripts/test-gemini.js +0 -13
  107. package/skills/cm-frappe-agent/SKILL.md +0 -134
  108. package/skills/cm-frappe-agent/agents/doctype-architect.md +0 -596
  109. package/skills/cm-frappe-agent/agents/erpnext-customizer.md +0 -643
  110. package/skills/cm-frappe-agent/agents/frappe-backend.md +0 -814
  111. package/skills/cm-frappe-agent/agents/frappe-custom-frontend.md +0 -557
  112. package/skills/cm-frappe-agent/agents/frappe-debugger.md +0 -625
  113. package/skills/cm-frappe-agent/agents/frappe-fixer.md +0 -275
  114. package/skills/cm-frappe-agent/agents/frappe-frontend.md +0 -660
  115. package/skills/cm-frappe-agent/agents/frappe-installer.md +0 -158
  116. package/skills/cm-frappe-agent/agents/frappe-performance.md +0 -307
  117. package/skills/cm-frappe-agent/agents/frappe-planner.md +0 -419
  118. package/skills/cm-frappe-agent/agents/frappe-remote-ops.md +0 -153
  119. package/skills/cm-frappe-agent/agents/github-workflow.md +0 -286
  120. package/skills/cm-frappe-agent/commands/frappe-app.md +0 -351
  121. package/skills/cm-frappe-agent/commands/frappe-backend.md +0 -162
  122. package/skills/cm-frappe-agent/commands/frappe-bench.md +0 -254
  123. package/skills/cm-frappe-agent/commands/frappe-debug.md +0 -263
  124. package/skills/cm-frappe-agent/commands/frappe-doctype-create.md +0 -272
  125. package/skills/cm-frappe-agent/commands/frappe-doctype-field.md +0 -310
  126. package/skills/cm-frappe-agent/commands/frappe-erpnext.md +0 -210
  127. package/skills/cm-frappe-agent/commands/frappe-fix.md +0 -59
  128. package/skills/cm-frappe-agent/commands/frappe-frontend.md +0 -210
  129. package/skills/cm-frappe-agent/commands/frappe-fullstack.md +0 -243
  130. package/skills/cm-frappe-agent/commands/frappe-github.md +0 -57
  131. package/skills/cm-frappe-agent/commands/frappe-install.md +0 -52
  132. package/skills/cm-frappe-agent/commands/frappe-plan.md +0 -442
  133. package/skills/cm-frappe-agent/commands/frappe-remote.md +0 -58
  134. package/skills/cm-frappe-agent/commands/frappe-test.md +0 -356
  135. package/skills/cm-frappe-agent/docs/README.md +0 -51
  136. package/skills/cm-frappe-agent/docs/agents-catalog.md +0 -113
  137. package/skills/cm-frappe-agent/docs/architecture.md +0 -149
  138. package/skills/cm-frappe-agent/docs/commands-catalog.md +0 -82
  139. package/skills/cm-frappe-agent/docs/resources-catalog.md +0 -66
  140. package/skills/cm-frappe-agent/docs/sitemap-urls.txt +0 -52
  141. package/skills/cm-frappe-agent/docs/sitemap.md +0 -81
  142. package/skills/cm-frappe-agent/docs/sop/user-guide.md +0 -178
  143. package/skills/cm-frappe-agent/docs/sop/vibe-coding-guide.md +0 -122
  144. package/skills/cm-frappe-agent/resources/7-layer-architecture.md +0 -985
  145. package/skills/cm-frappe-agent/resources/bench_commands.md +0 -73
  146. package/skills/cm-frappe-agent/resources/code-patterns-guide.md +0 -948
  147. package/skills/cm-frappe-agent/resources/common_pitfalls.md +0 -266
  148. package/skills/cm-frappe-agent/resources/doctype-registry.md +0 -158
  149. package/skills/cm-frappe-agent/resources/installation-guide.md +0 -289
  150. package/skills/cm-frappe-agent/resources/rest-api-patterns.md +0 -182
  151. package/skills/cm-frappe-agent/resources/scaffold_checklist.md +0 -82
  152. package/skills/cm-frappe-agent/resources/upgrade_patterns.md +0 -113
  153. package/skills/cm-frappe-agent/resources/web-form-patterns.md +0 -252
  154. package/skills/cm-frappe-agent/skills/bench-commands/SKILL.md +0 -621
  155. package/skills/cm-frappe-agent/skills/client-scripts/SKILL.md +0 -642
  156. package/skills/cm-frappe-agent/skills/doctype-patterns/SKILL.md +0 -576
  157. package/skills/cm-frappe-agent/skills/frappe-api/SKILL.md +0 -740
  158. package/skills/cm-frappe-agent/skills/remote-operations/SKILL.md +0 -47
  159. package/skills/cm-frappe-agent/skills/server-scripts/SKILL.md +0 -608
  160. package/skills/cm-frappe-agent/skills/web-forms/SKILL.md +0 -46
  161. package/skills/frappe-app-builder.zip +0 -0
@@ -0,0 +1,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
+ }