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,269 @@
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.registerSkillChainCommands = registerSkillChainCommands;
16
+ const data_1 = require("../../data");
17
+ const skill_chain_1 = require("../../skill-chain");
18
+ const box_1 = require("../../ui/box");
19
+ const theme_1 = require("../../ui/theme");
20
+ const cli_utils_1 = require("../../utils/cli-utils");
21
+ const agent_dispatch_1 = require("../../agent-dispatch");
22
+ const crypto_1 = __importDefault(require("crypto"));
23
+ function registerSkillChainCommands(program) {
24
+ program
25
+ .command('chain <cmd> [args...]')
26
+ .alias('ch')
27
+ .description('Skill Chain management (list|info|auto|run|status|advance|skip|abort|history)')
28
+ .option('-p, --project <name>', 'Project name or ID')
29
+ .option('--agent <agent>', 'Agent name')
30
+ .action((cmd, args, opts) => __awaiter(this, void 0, void 0, function* () {
31
+ switch (cmd) {
32
+ case 'list':
33
+ case 'ls':
34
+ chainList();
35
+ break;
36
+ case 'info':
37
+ chainInfo(args[0]);
38
+ break;
39
+ case 'auto':
40
+ yield chainAuto(args.join(' '), opts);
41
+ break;
42
+ case 'run':
43
+ case 'start':
44
+ yield chainStart(args[0], args.slice(1).join(' '), opts);
45
+ break;
46
+ case 'status':
47
+ case 'st':
48
+ chainStatus(args[0]);
49
+ break;
50
+ case 'advance':
51
+ case 'next':
52
+ yield chainAdvance(args[0], args.slice(1).join(' '));
53
+ break;
54
+ case 'skip':
55
+ yield chainSkip(args[0], args.slice(1).join(' '));
56
+ break;
57
+ case 'abort':
58
+ case 'stop':
59
+ chainAbortCmd(args[0], args.slice(1).join(' '));
60
+ break;
61
+ case 'history':
62
+ chainHistory();
63
+ break;
64
+ default: console.log((0, box_1.renderResult)('error', `Unknown chain command: ${cmd}`, [(0, theme_1.dim)('Available: list, info, auto, run, status, advance, skip, abort, history')]));
65
+ }
66
+ }));
67
+ }
68
+ function chainList() {
69
+ const chains = (0, skill_chain_1.listChains)();
70
+ console.log((0, box_1.renderCommandHeader)('Available Skill Chains', '🔗'));
71
+ for (const c of chains) {
72
+ console.log(` ${(0, theme_1.brand)((0, cli_utils_1.padRight)(c.id, 20))} ${(0, theme_1.dim)(c.name)} ${(0, theme_1.dim)(`(${c.steps.length} steps)`)}`);
73
+ }
74
+ console.log();
75
+ }
76
+ function chainInfo(chainId) {
77
+ if (!chainId) {
78
+ console.log((0, box_1.renderResult)('error', 'Chain ID required.'));
79
+ return;
80
+ }
81
+ const c = (0, skill_chain_1.findChain)(chainId);
82
+ if (!c) {
83
+ console.log((0, box_1.renderResult)('error', `Chain not found: ${chainId}`));
84
+ return;
85
+ }
86
+ console.log((0, box_1.renderCommandHeader)(`Chain Info: ${c.name}`, '🔗'));
87
+ console.log((0, theme_1.dim)(` ID: ${c.id}`));
88
+ console.log((0, theme_1.dim)(` Description: ${c.description || '—'}`));
89
+ console.log(`\n ${(0, theme_1.brand)('Steps:')}`);
90
+ c.steps.forEach((s, idx) => {
91
+ console.log(` ${idx + 1}. ${(0, cli_utils_1.padRight)(s.skill, 20)} ${(0, theme_1.dim)(s.description || '—')}`);
92
+ });
93
+ console.log();
94
+ }
95
+ function dispatchCurrentChainStep(exec) {
96
+ return __awaiter(this, void 0, void 0, function* () {
97
+ const data = (0, data_1.loadData)();
98
+ const currentStep = exec.steps[exec.currentStepIndex];
99
+ if (!currentStep)
100
+ return;
101
+ const project = data.projects.find(p => p.id === exec.projectId) || data.projects[0];
102
+ if (project) {
103
+ const task = {
104
+ id: crypto_1.default.randomUUID(), // Mock task for dispatch
105
+ projectId: project.id,
106
+ title: `${exec.taskTitle} (Step ${currentStep.index + 1}: ${currentStep.skill})`,
107
+ description: currentStep.description,
108
+ column: 'backlog',
109
+ order: 0,
110
+ priority: 'medium',
111
+ agent: exec.agent,
112
+ skill: currentStep.skill,
113
+ createdAt: new Date().toISOString(),
114
+ updatedAt: new Date().toISOString()
115
+ };
116
+ yield (0, agent_dispatch_1.dispatchTaskToAgent)(task, project);
117
+ }
118
+ });
119
+ }
120
+ function chainAuto(taskTitle, opts) {
121
+ return __awaiter(this, void 0, void 0, function* () {
122
+ if (!taskTitle) {
123
+ console.log((0, box_1.renderResult)('error', 'Usage: cm chain auto "Task Title"'));
124
+ return;
125
+ }
126
+ const match = (0, skill_chain_1.matchChain)(taskTitle);
127
+ if (!match) {
128
+ console.log((0, box_1.renderResult)('warning', `No specific chain matched for "${taskTitle}". Defaulting to Feature Development.`));
129
+ yield chainStart('feature-development', taskTitle, opts);
130
+ }
131
+ else {
132
+ console.log((0, box_1.renderResult)('success', `Detected chain: ${(0, theme_1.brand)(match.name)}`));
133
+ yield chainStart(match.id, taskTitle, opts);
134
+ }
135
+ });
136
+ }
137
+ function chainStart(chainId, taskTitle, opts) {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ if (!chainId || !taskTitle) {
140
+ console.log((0, box_1.renderResult)('error', 'Usage: cm chain run <chainId> "Task Title"'));
141
+ return;
142
+ }
143
+ const c = (0, skill_chain_1.findChain)(chainId);
144
+ if (!c) {
145
+ console.log((0, box_1.renderResult)('error', `Chain not found: ${chainId}`));
146
+ return;
147
+ }
148
+ console.log((0, box_1.renderResult)('info', `Starting chain: ${c.name}...`));
149
+ const data = (0, data_1.loadData)();
150
+ const agent = opts.agent || 'Hamster';
151
+ const projectId = opts.project || 'default';
152
+ const exec = (0, skill_chain_1.createChainExecution)(c, projectId, taskTitle, agent, process.cwd());
153
+ data.chainExecutions.unshift(exec);
154
+ (0, data_1.saveData)(data);
155
+ // Dispatch first step
156
+ const firstStep = exec.steps[0];
157
+ console.log(` ${(0, theme_1.success)('▶')} Step 1: ${(0, theme_1.brand)(firstStep.skill)}`);
158
+ yield dispatchCurrentChainStep(exec);
159
+ });
160
+ }
161
+ function chainStatus(execIdPrefix) {
162
+ const data = (0, data_1.loadData)();
163
+ const execs = data.chainExecutions;
164
+ if (execs.length === 0) {
165
+ console.log(`\n ${(0, theme_1.dim)('No chain executions found.')}\n`);
166
+ return;
167
+ }
168
+ const exec = execIdPrefix ? execs.find(e => e.id.startsWith(execIdPrefix)) : execs[0];
169
+ if (!exec) {
170
+ console.log((0, box_1.renderResult)('error', `Execution not found: ${execIdPrefix}`));
171
+ return;
172
+ }
173
+ console.log((0, box_1.renderCommandHeader)(`Chain Execution: ${exec.chainName}`, '🔗'));
174
+ console.log((0, theme_1.dim)(` Task: ${exec.taskTitle}`));
175
+ console.log((0, theme_1.dim)(` Status: ${exec.status.toUpperCase()}`));
176
+ console.log(`\n ${(0, theme_1.brand)('Progress:')} ${(0, skill_chain_1.formatChainProgress)(exec)}`);
177
+ console.log(` ${(0, skill_chain_1.formatChainProgressBar)(exec)}`);
178
+ console.log();
179
+ }
180
+ function chainAdvance(execIdPrefix, output) {
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ const data = (0, data_1.loadData)();
183
+ let exec = execIdPrefix ? data.chainExecutions.find(e => e.id.startsWith(execIdPrefix)) : data.chainExecutions.find(e => e.status === 'running');
184
+ if (!exec && execIdPrefix) {
185
+ // Fallback: execIdPrefix might be the output message instead of an ID
186
+ exec = data.chainExecutions.find(e => e.status === 'running');
187
+ if (exec) {
188
+ output = output ? `${execIdPrefix} ${output}` : execIdPrefix;
189
+ }
190
+ }
191
+ if (!exec) {
192
+ console.log((0, box_1.renderResult)('error', 'No running chain execution found.'));
193
+ return;
194
+ }
195
+ const res = (0, skill_chain_1.advanceChain)(exec, output || 'Completed via CLI');
196
+ (0, data_1.saveData)(data);
197
+ if (res.completed) {
198
+ console.log((0, box_1.renderResult)('success', 'Chain exploration COMPLETED!'));
199
+ }
200
+ else if (res.nextSkill) {
201
+ console.log((0, box_1.renderResult)('success', `Step advanced! Next: ${(0, theme_1.brand)(res.nextSkill)}`));
202
+ yield dispatchCurrentChainStep(exec);
203
+ }
204
+ });
205
+ }
206
+ function chainSkip(execIdPrefix, reason) {
207
+ return __awaiter(this, void 0, void 0, function* () {
208
+ const data = (0, data_1.loadData)();
209
+ let exec = execIdPrefix ? data.chainExecutions.find(e => e.id.startsWith(execIdPrefix)) : data.chainExecutions.find(e => e.status === 'running');
210
+ if (!exec && execIdPrefix) {
211
+ exec = data.chainExecutions.find(e => e.status === 'running');
212
+ if (exec) {
213
+ reason = reason ? `${execIdPrefix} ${reason}` : execIdPrefix;
214
+ }
215
+ }
216
+ if (!exec) {
217
+ console.log((0, box_1.renderResult)('error', 'No running chain execution found.'));
218
+ return;
219
+ }
220
+ const res = (0, skill_chain_1.skipChainStep)(exec, reason || 'Skipped via CLI');
221
+ (0, data_1.saveData)(data);
222
+ if (res.completed) {
223
+ console.log((0, box_1.renderResult)('success', 'Chain completed (steps skipped).'));
224
+ }
225
+ else if (res.nextSkill) {
226
+ console.log((0, box_1.renderResult)('success', `Step skipped! Next: ${(0, theme_1.brand)(res.nextSkill)}`));
227
+ yield dispatchCurrentChainStep(exec);
228
+ }
229
+ });
230
+ }
231
+ function chainAbortCmd(execIdPrefix, reason) {
232
+ const data = (0, data_1.loadData)();
233
+ let exec = execIdPrefix ? data.chainExecutions.find(e => e.id.startsWith(execIdPrefix)) : data.chainExecutions.find(e => e.status === 'running');
234
+ if (!exec && execIdPrefix) {
235
+ exec = data.chainExecutions.find(e => e.status === 'running');
236
+ if (exec) {
237
+ reason = reason ? `${execIdPrefix} ${reason}` : execIdPrefix;
238
+ }
239
+ }
240
+ if (!exec) {
241
+ console.log((0, box_1.renderResult)('error', 'No running chain execution found.'));
242
+ return;
243
+ }
244
+ (0, skill_chain_1.abortChain)(exec, reason || 'Aborted via CLI');
245
+ (0, data_1.saveData)(data);
246
+ console.log((0, box_1.renderResult)('warning', 'Chain execution ABORTED.'));
247
+ }
248
+ function chainHistory() {
249
+ const data = (0, data_1.loadData)();
250
+ const execs = data.chainExecutions;
251
+ if (execs.length === 0) {
252
+ console.log(`\n ${(0, theme_1.dim)('No chain executions yet.')}\n`);
253
+ return;
254
+ }
255
+ const STATUS_ICONS = {
256
+ pending: '⚪', running: '🔵', paused: '⏸️', completed: '✅', failed: '❌', aborted: '🛑',
257
+ };
258
+ console.log((0, box_1.renderCommandHeader)(`Chain History (${execs.length})`, '🔗'));
259
+ console.log((0, theme_1.dim)(' ' + (0, cli_utils_1.padRight)('Status', 8) + (0, cli_utils_1.padRight)('Chain', 24) + (0, cli_utils_1.padRight)('Task', 30) + (0, cli_utils_1.padRight)('Progress', 14) + 'Time'));
260
+ console.log((0, theme_1.dim)(' ' + '─'.repeat(86)));
261
+ for (const exec of execs.slice(0, 20)) {
262
+ const icon = STATUS_ICONS[exec.status] || '❓';
263
+ const completed = exec.steps.filter(s => s.status === 'completed' || s.status === 'skipped').length;
264
+ const progress = `${completed}/${exec.steps.length} steps`;
265
+ const time = (0, cli_utils_1.formatTimeAgoCli)(exec.startedAt);
266
+ console.log(' ' + (0, cli_utils_1.padRight)(icon, 8) + (0, theme_1.brand)((0, cli_utils_1.padRight)(exec.chainName.substring(0, 22), 24)) + (0, cli_utils_1.padRight)(exec.taskTitle.substring(0, 28), 30) + (0, theme_1.dim)((0, cli_utils_1.padRight)(progress, 14)) + (0, theme_1.dim)(time));
267
+ }
268
+ console.log();
269
+ }
@@ -0,0 +1,89 @@
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.registerSystemCommands = registerSystemCommands;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const data_1 = require("../../data");
12
+ const theme_1 = require("../../ui/theme");
13
+ const box_1 = require("../../ui/box");
14
+ const hamster_1 = require("../../ui/hamster");
15
+ const skill_utils_1 = require("../../utils/skill-utils");
16
+ const cli_utils_1 = require("../../utils/cli-utils");
17
+ const pkg = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '..', '..', '..', 'package.json'), 'utf-8'));
18
+ const VERSION = pkg.version;
19
+ function registerSystemCommands(program) {
20
+ // ─── Status Command ────────────────────────────────────────────────────────
21
+ program
22
+ .command('status')
23
+ .alias('s')
24
+ .description('Show task & project summary')
25
+ .action(() => {
26
+ const data = (0, data_1.loadData)();
27
+ showBanner();
28
+ console.log((0, box_1.renderCommandHeader)('Status Overview', '📊'));
29
+ // Projects
30
+ console.log((0, theme_1.brand)(` Projects: ${data.projects.length}`));
31
+ for (const p of data.projects) {
32
+ const pt = data.tasks.filter(t => t.projectId === p.id);
33
+ const done = pt.filter(t => t.column === 'done').length;
34
+ const pct = pt.length > 0 ? Math.round((done / pt.length) * 100) : 0;
35
+ console.log((0, theme_1.dim)(` 📦 ${(0, cli_utils_1.padRight)(p.name, 20)} ${(0, cli_utils_1.progressBar)(pct)} ${done}/${pt.length} (${pct}%)`));
36
+ }
37
+ // Tasks
38
+ const total = data.tasks.length;
39
+ const byCol = { backlog: 0, 'in-progress': 0, review: 0, done: 0 };
40
+ data.tasks.forEach(t => { byCol[t.column] = (byCol[t.column] || 0) + 1; });
41
+ console.log();
42
+ console.log((0, theme_1.brand)(` Tasks: ${total}`));
43
+ console.log((0, theme_1.dim)(` ⚪ Backlog: ${byCol.backlog}`));
44
+ console.log((0, theme_1.info)(` 🟢 In Progress: ${byCol['in-progress']}`));
45
+ console.log((0, theme_1.warning)(` 🟡 Review: ${byCol.review}`));
46
+ console.log((0, theme_1.success)(` 🟢 Done: ${byCol.done}`));
47
+ // Deploys
48
+ if (data.deployments.length > 0) {
49
+ console.log();
50
+ console.log((0, theme_1.brand)(` Deployments: ${data.deployments.length}`));
51
+ const latest = data.deployments[0];
52
+ const sc = theme_1.STATUS[latest.status] || chalk_1.default.white;
53
+ console.log((0, theme_1.dim)(` Latest: ${latest.env} — ${sc(latest.status)} — ${latest.message} (${(0, cli_utils_1.formatTimeAgoCli)(latest.startedAt)})`));
54
+ }
55
+ console.log();
56
+ });
57
+ // ─── Config Command ────────────────────────────────────────────────────────
58
+ program
59
+ .command('config [key] [value]')
60
+ .description('Get or set configuration')
61
+ .action((key, value) => {
62
+ if (!key) {
63
+ console.log((0, box_1.renderCommandHeader)('Configuration', '⚙️'));
64
+ console.log((0, theme_1.dim)(' Run cm config <key> <value> to set a value.\n'));
65
+ return;
66
+ }
67
+ if (value) {
68
+ console.log((0, box_1.renderResult)('success', `Config set: ${key} = ${value}`));
69
+ }
70
+ else {
71
+ console.log((0, box_1.renderResult)('info', `Config: ${key} = (not set)`));
72
+ }
73
+ });
74
+ // ─── Open Command ───────────────────────────────────────────────────────────
75
+ program
76
+ .command('open')
77
+ .description('Open dashboard in browser')
78
+ .action(() => {
79
+ const url = `http://localhost:${data_1.DEFAULT_PORT}`;
80
+ console.log((0, box_1.renderResult)('info', `Opening ${url}...`));
81
+ (0, cli_utils_1.openUrl)(url);
82
+ });
83
+ }
84
+ function showBanner() {
85
+ const cPath = process.cwd().replace(os_1.default.homedir(), '~');
86
+ const skillCount = (0, skill_utils_1.getSkillCount)();
87
+ // Using a default/mocked profile for now (profile logic is being refactored)
88
+ console.log((0, hamster_1.renderHamsterBanner)(undefined, VERSION, cPath, skillCount));
89
+ }
@@ -0,0 +1,254 @@
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.registerTaskCommands = registerTaskCommands;
16
+ const crypto_1 = __importDefault(require("crypto"));
17
+ const chalk_1 = __importDefault(require("chalk"));
18
+ const data_1 = require("../../data");
19
+ const agent_dispatch_1 = require("../../agent-dispatch");
20
+ const theme_1 = require("../../ui/theme");
21
+ const box_1 = require("../../ui/box");
22
+ const cli_utils_1 = require("../../utils/cli-utils");
23
+ const COL_COLORS = theme_1.COL;
24
+ const PRIORITY_COLORS = theme_1.PRI;
25
+ function registerTaskCommands(program) {
26
+ program
27
+ .command('task <cmd> [args...]')
28
+ .alias('t')
29
+ .description('Task management (add|list|move|done|rm|dispatch|stuck)')
30
+ .option('-p, --project <name>', 'Project name or ID')
31
+ .option('-c, --column <column>', 'Column (backlog|in-progress|review|done)', 'backlog')
32
+ .option('--priority <level>', 'Priority (low|medium|high|urgent)', 'medium')
33
+ .option('--agent <agent>', 'Agent name')
34
+ .option('--skill <skill>', 'Skill name')
35
+ .option('--all', 'Show all projects')
36
+ .option('--force', 'Force re-dispatch')
37
+ .action((cmd, args, opts) => {
38
+ switch (cmd) {
39
+ case 'add':
40
+ taskAdd(args.join(' '), opts);
41
+ break;
42
+ case 'list':
43
+ case 'ls':
44
+ taskList(opts);
45
+ break;
46
+ case 'move':
47
+ taskMove(args[0], args[1]);
48
+ break;
49
+ case 'done':
50
+ taskDone(args[0]);
51
+ break;
52
+ case 'rm':
53
+ case 'delete':
54
+ taskRemove(args[0]);
55
+ break;
56
+ case 'dispatch':
57
+ taskDispatch(args[0], opts);
58
+ break;
59
+ case 'stuck':
60
+ taskStuck(opts);
61
+ break;
62
+ default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: add, list, move, done, rm, dispatch, stuck')]));
63
+ }
64
+ });
65
+ }
66
+ function taskAdd(title, opts) {
67
+ if (!title) {
68
+ console.log((0, box_1.renderResult)('error', 'Title required. Usage: cm task add "My task"'));
69
+ return;
70
+ }
71
+ const data = (0, data_1.loadData)();
72
+ let projectId;
73
+ if (opts.project) {
74
+ const project = (0, data_1.findProjectByNameOrId)(data, opts.project);
75
+ if (!project) {
76
+ console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
77
+ return;
78
+ }
79
+ projectId = project.id;
80
+ }
81
+ else if (data.projects.length > 0) {
82
+ projectId = data.projects[0].id;
83
+ }
84
+ else {
85
+ const dp = {
86
+ id: crypto_1.default.randomUUID(),
87
+ name: 'Default Project',
88
+ path: process.cwd(),
89
+ agents: [],
90
+ createdAt: new Date().toISOString()
91
+ };
92
+ data.projects.push(dp);
93
+ projectId = dp.id;
94
+ }
95
+ const now = new Date().toISOString();
96
+ const column = (opts.column || 'backlog');
97
+ const ct = data.tasks.filter((t) => t.column === column && t.projectId === projectId);
98
+ const mo = ct.length > 0 ? Math.max(...ct.map((t) => t.order)) : -1;
99
+ const task = {
100
+ id: crypto_1.default.randomUUID(),
101
+ projectId: projectId,
102
+ title: title.trim(),
103
+ description: '',
104
+ column,
105
+ order: mo + 1,
106
+ priority: (opts.priority || 'medium'),
107
+ agent: opts.agent || '',
108
+ skill: opts.skill || '',
109
+ createdAt: now,
110
+ updatedAt: now
111
+ };
112
+ data.tasks.push(task);
113
+ (0, data_1.logActivity)(data, 'task_created', `Task "${task.title}" created via CLI`, projectId, opts.agent || '');
114
+ (0, data_1.saveData)(data);
115
+ const project = data.projects.find((p) => p.id === projectId);
116
+ console.log((0, box_1.renderResult)('success', `Task created: ${title}`, [
117
+ `${(0, theme_1.dim)('ID:')} ${(0, theme_1.brand)((0, data_1.shortId)(task.id))} ${(0, theme_1.dim)('|')} ${(0, theme_1.dim)('Project:')} ${(0, theme_1.brand)((project === null || project === void 0 ? void 0 : project.name) || 'Default')} ${(0, theme_1.dim)('|')} ${(0, theme_1.dim)(column)} ${(0, theme_1.dim)('|')} ${(0, theme_1.dim)(opts.priority || 'medium')}`,
118
+ ]));
119
+ }
120
+ function taskList(opts) {
121
+ const data = (0, data_1.loadData)();
122
+ let tasks = data.tasks;
123
+ if (opts.project && !opts.all) {
124
+ const project = (0, data_1.findProjectByNameOrId)(data, opts.project);
125
+ if (!project) {
126
+ console.log((0, box_1.renderResult)('error', `Project not found: ${opts.project}`));
127
+ return;
128
+ }
129
+ tasks = tasks.filter((t) => t.projectId === project.id);
130
+ console.log((0, box_1.renderCommandHeader)(`Tasks — ${project.name}`, '📋'));
131
+ }
132
+ else {
133
+ console.log((0, box_1.renderCommandHeader)('All Tasks', '📋'));
134
+ }
135
+ if (tasks.length === 0) {
136
+ console.log(` ${(0, theme_1.dim)('No tasks found.')}\n`);
137
+ return;
138
+ }
139
+ console.log((0, theme_1.dim)(' ' + (0, cli_utils_1.padRight)('ID', 10) + (0, cli_utils_1.padRight)('Title', 36) + (0, cli_utils_1.padRight)('Column', 14) + (0, cli_utils_1.padRight)('Priority', 10) + (0, cli_utils_1.padRight)('Agent', 14) + 'Project'));
140
+ console.log((0, theme_1.dim)(' ' + '─'.repeat(100)));
141
+ const co = ['backlog', 'in-progress', 'review', 'done'];
142
+ tasks.sort((a, b) => co.indexOf(a.column) - co.indexOf(b.column) || a.order - b.order);
143
+ for (const task of tasks) {
144
+ const cc = COL_COLORS[task.column] || chalk_1.default.white;
145
+ const pc = PRIORITY_COLORS[task.priority] || chalk_1.default.white;
146
+ const project = data.projects.find((p) => p.id === task.projectId);
147
+ console.log(' ' + (0, theme_1.dim)((0, cli_utils_1.padRight)((0, data_1.shortId)(task.id), 10)) + (0, cli_utils_1.padRight)(task.title.substring(0, 34), 36) + cc((0, cli_utils_1.padRight)(task.column, 14)) + pc((0, cli_utils_1.padRight)(task.priority, 10)) + (0, theme_1.dim)((0, cli_utils_1.padRight)(task.agent || '—', 14)) + (0, theme_1.dim)((project === null || project === void 0 ? void 0 : project.name) || '—'));
148
+ }
149
+ console.log((0, theme_1.dim)(`\n Total: ${tasks.length} tasks\n`));
150
+ }
151
+ function taskMove(idPrefix, targetColumn) {
152
+ if (!idPrefix || !targetColumn) {
153
+ console.log((0, box_1.renderResult)('error', 'Usage: cm task move <id> <column>'));
154
+ return;
155
+ }
156
+ const vc = ['backlog', 'in-progress', 'review', 'done'];
157
+ if (!vc.includes(targetColumn)) {
158
+ console.log((0, box_1.renderResult)('error', `Invalid column: ${targetColumn}`, [(0, theme_1.dim)(`Valid: ${vc.join(', ')}`)]));
159
+ return;
160
+ }
161
+ const data = (0, data_1.loadData)();
162
+ const task = (0, data_1.findTaskByIdPrefix)(data, idPrefix);
163
+ if (!task) {
164
+ console.log((0, box_1.renderResult)('error', `Task not found: ${idPrefix}`));
165
+ return;
166
+ }
167
+ const oldCol = task.column;
168
+ // Validate transition
169
+ const VALID_TRANSITIONS = {
170
+ 'backlog': ['in-progress'],
171
+ 'in-progress': ['review', 'done', 'backlog'],
172
+ 'review': ['done', 'in-progress'],
173
+ 'done': ['backlog'],
174
+ };
175
+ const allowed = VALID_TRANSITIONS[oldCol] || [];
176
+ if (oldCol !== targetColumn && !allowed.includes(targetColumn)) {
177
+ console.log((0, box_1.renderResult)('error', `Invalid transition: ${oldCol} → ${targetColumn}`, [(0, theme_1.dim)(`Allowed: ${allowed.join(', ')}`)]));
178
+ return;
179
+ }
180
+ if (oldCol === targetColumn) {
181
+ console.log(` ${(0, theme_1.dim)(`Task already in ${targetColumn}.`)}`);
182
+ return;
183
+ }
184
+ task.column = targetColumn;
185
+ task.updatedAt = new Date().toISOString();
186
+ (0, data_1.saveData)(data);
187
+ (0, data_1.logActivity)(data, 'task_moved', `Task "${task.title}" moved ${oldCol} → ${targetColumn}`, task.projectId);
188
+ console.log((0, box_1.renderResult)('success', `Task moved: ${(0, data_1.shortId)(task.id)}`, [`${(0, theme_1.dim)('New column:')} ${(0, theme_1.brand)(targetColumn)}`]));
189
+ }
190
+ function taskDone(idPrefix) {
191
+ taskMove(idPrefix, 'done');
192
+ }
193
+ function taskRemove(idPrefix) {
194
+ if (!idPrefix) {
195
+ console.log((0, box_1.renderResult)('error', 'Usage: cm task rm <id>'));
196
+ return;
197
+ }
198
+ const data = (0, data_1.loadData)();
199
+ const task = (0, data_1.findTaskByIdPrefix)(data, idPrefix);
200
+ if (!task) {
201
+ console.log((0, box_1.renderResult)('error', `Task not found: ${idPrefix}`));
202
+ return;
203
+ }
204
+ data.tasks = data.tasks.filter((t) => t.id !== task.id);
205
+ (0, data_1.logActivity)(data, 'task_deleted', `Task "${task.title}" deleted`, task.projectId);
206
+ (0, data_1.saveData)(data);
207
+ console.log((0, box_1.renderResult)('success', `Task deleted: ${task.title}`));
208
+ }
209
+ function taskDispatch(idPrefix, opts) {
210
+ return __awaiter(this, void 0, void 0, function* () {
211
+ if (!idPrefix) {
212
+ console.log((0, box_1.renderResult)('error', 'Usage: cm task dispatch <id>'));
213
+ return;
214
+ }
215
+ const data = (0, data_1.loadData)();
216
+ const task = (0, data_1.findTaskByIdPrefix)(data, idPrefix);
217
+ if (!task) {
218
+ console.log((0, box_1.renderResult)('error', `Task not found: ${idPrefix}`));
219
+ return;
220
+ }
221
+ const project = data.projects.find((p) => p.id === task.projectId);
222
+ if (!project) {
223
+ console.log((0, box_1.renderResult)('error', `Project not found for task: ${task.id}`));
224
+ return;
225
+ }
226
+ console.log((0, box_1.renderResult)('info', `Dispatching task: ${task.title}...`));
227
+ const success = yield (0, agent_dispatch_1.dispatchTaskToAgent)(task, project, opts.force);
228
+ if (success) {
229
+ task.column = 'in-progress';
230
+ task.updatedAt = new Date().toISOString();
231
+ (0, data_1.saveData)(data);
232
+ }
233
+ });
234
+ }
235
+ function taskStuck(opts) {
236
+ const data = (0, data_1.loadData)();
237
+ const now = new Date().getTime();
238
+ const STUCK_THRESHOLD = 30 * 60 * 1000; // 30 mins
239
+ const stuckTasks = data.tasks.filter((t) => {
240
+ if (t.column !== 'in-progress')
241
+ return false;
242
+ const lastUpdate = new Date(t.updatedAt).getTime();
243
+ return (now - lastUpdate) > STUCK_THRESHOLD;
244
+ });
245
+ if (stuckTasks.length === 0) {
246
+ console.log((0, box_1.renderResult)('success', 'No stuck tasks detected.'));
247
+ return;
248
+ }
249
+ console.log((0, box_1.renderCommandHeader)('Stuck Tasks Detected', '⚠️'));
250
+ for (const t of stuckTasks) {
251
+ const project = data.projects.find((p) => p.id === t.projectId);
252
+ console.log(` ${(0, theme_1.dim)((0, data_1.shortId)(t.id))} ${(0, cli_utils_1.padRight)(t.title, 40)} ${(0, theme_1.brand)((project === null || project === void 0 ? void 0 : project.name) || '—')} ${(0, theme_1.dim)('Stuck for ' + Math.round((now - new Date(t.updatedAt).getTime()) / 60000) + 'm')}`);
253
+ }
254
+ }