codymaster 4.5.1 → 4.5.2

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.
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * cm-dashboard MCP Bridge — Phase 2 (Claude Desktop)
4
+ *
5
+ * Standalone MCP server over stdio (no extra dependencies).
6
+ * Exposes 3 tools that sync tasks to the cm-dashboard.
7
+ *
8
+ * Install:
9
+ * cp scripts/mcp-bridge.js ~/.claude/scripts/mcp-bridge.js
10
+ *
11
+ * Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
12
+ * {
13
+ * "mcpServers": {
14
+ * "cm-dashboard": {
15
+ * "command": "node",
16
+ * "args": ["/Users/<you>/.claude/scripts/mcp-bridge.js"]
17
+ * }
18
+ * }
19
+ * }
20
+ *
21
+ * Tools provided:
22
+ * cm_sync_todos — sync TodoWrite list to dashboard
23
+ * cm_get_tasks — read current board state
24
+ * cm_update_task — move a single task between columns
25
+ */
26
+
27
+ 'use strict';
28
+
29
+ const http = require('http');
30
+
31
+ const DASHBOARD_PORT = process.env.CM_DASHBOARD_PORT || 6969;
32
+ const SERVER_NAME = 'cm-dashboard';
33
+ const SERVER_VERSION = '1.0.0';
34
+
35
+ // ── Status mapping ────────────────────────────────────────────────────────────
36
+
37
+ const STATUS_TO_COLUMN = {
38
+ pending: 'backlog',
39
+ in_progress: 'in-progress',
40
+ completed: 'done',
41
+ backlog: 'backlog',
42
+ 'in-progress': 'in-progress',
43
+ done: 'done',
44
+ };
45
+
46
+ // ── Dashboard HTTP helpers ────────────────────────────────────────────────────
47
+
48
+ function dashboardRequest(method, path, body) {
49
+ return new Promise((resolve, reject) => {
50
+ const bodyStr = body ? JSON.stringify(body) : null;
51
+ const options = {
52
+ hostname: 'localhost',
53
+ port: DASHBOARD_PORT,
54
+ path,
55
+ method,
56
+ headers: { 'Content-Type': 'application/json' },
57
+ };
58
+ if (bodyStr) options.headers['Content-Length'] = Buffer.byteLength(bodyStr);
59
+
60
+ const req = http.request(options, (res) => {
61
+ const chunks = [];
62
+ res.on('data', (c) => chunks.push(c));
63
+ res.on('end', () => {
64
+ try {
65
+ resolve(JSON.parse(Buffer.concat(chunks).toString()));
66
+ } catch {
67
+ resolve(null);
68
+ }
69
+ });
70
+ });
71
+ req.on('error', reject);
72
+ if (bodyStr) req.write(bodyStr);
73
+ req.end();
74
+ });
75
+ }
76
+
77
+ // ── Tool implementations ──────────────────────────────────────────────────────
78
+
79
+ async function cmSyncTodos({ todos, projectName, sessionId }) {
80
+ if (!Array.isArray(todos) || todos.length === 0) {
81
+ return { synced: 0, message: 'No todos to sync.' };
82
+ }
83
+
84
+ const sid = sessionId || `mcp-${Date.now()}`;
85
+ const project = projectName || 'Claude Desktop';
86
+
87
+ const results = await Promise.allSettled(
88
+ todos.map((todo) =>
89
+ dashboardRequest('POST', '/api/tasks/auto-sync', {
90
+ conversationId: `${sid}:${todo.id}`,
91
+ title: todo.content,
92
+ status: STATUS_TO_COLUMN[todo.status] || 'backlog',
93
+ agent: 'claude-code',
94
+ priority: todo.priority || 'medium',
95
+ projectName: project,
96
+ })
97
+ )
98
+ );
99
+
100
+ const synced = results.filter((r) => r.status === 'fulfilled').length;
101
+ return { synced, total: todos.length, projectName: project };
102
+ }
103
+
104
+ async function cmGetTasks({ projectName }) {
105
+ const projects = await dashboardRequest('GET', '/api/projects', null);
106
+ if (!Array.isArray(projects)) throw new Error('Dashboard not running on port ' + DASHBOARD_PORT);
107
+
108
+ let project = projectName
109
+ ? projects.find((p) => p.name.toLowerCase().includes(projectName.toLowerCase()))
110
+ : projects[0];
111
+
112
+ if (!project) return { columns: { backlog: [], 'in-progress': [], review: [], done: [] }, projectName: null };
113
+
114
+ const tasks = await dashboardRequest('GET', `/api/tasks?projectId=${project.id}`, null);
115
+ const columns = { backlog: [], 'in-progress': [], review: [], done: [] };
116
+ for (const t of tasks || []) {
117
+ if (columns[t.column]) columns[t.column].push({ id: t.id, title: t.title, priority: t.priority, agent: t.agent });
118
+ }
119
+ return { projectName: project.name, columns };
120
+ }
121
+
122
+ async function cmUpdateTask({ conversationId, status, title, projectName }) {
123
+ if (!conversationId && !title) throw new Error('conversationId or title is required');
124
+ const result = await dashboardRequest('POST', '/api/tasks/auto-sync', {
125
+ conversationId: conversationId || `mcp-${Date.now()}:manual`,
126
+ title: title || conversationId,
127
+ status: STATUS_TO_COLUMN[status] || 'in-progress',
128
+ agent: 'claude-code',
129
+ projectName: projectName || 'Claude Desktop',
130
+ });
131
+ return result;
132
+ }
133
+
134
+ // ── Tool registry ─────────────────────────────────────────────────────────────
135
+
136
+ const TOOLS = [
137
+ {
138
+ name: 'cm_sync_todos',
139
+ description: 'Sync the current todo list to the cm-dashboard Kanban board. Call this after every TodoWrite to keep the dashboard up to date.',
140
+ inputSchema: {
141
+ type: 'object',
142
+ properties: {
143
+ todos: {
144
+ type: 'array',
145
+ description: 'The todos array from TodoWrite',
146
+ items: {
147
+ type: 'object',
148
+ properties: {
149
+ id: { type: 'string' },
150
+ content: { type: 'string' },
151
+ status: { type: 'string', enum: ['pending', 'in_progress', 'completed'] },
152
+ priority: { type: 'string', enum: ['high', 'medium', 'low'] },
153
+ },
154
+ required: ['id', 'content', 'status'],
155
+ },
156
+ },
157
+ projectName: { type: 'string', description: 'Project name on the dashboard (defaults to "Claude Desktop")' },
158
+ sessionId: { type: 'string', description: 'Unique session identifier for task deduplication' },
159
+ },
160
+ required: ['todos'],
161
+ },
162
+ },
163
+ {
164
+ name: 'cm_get_tasks',
165
+ description: 'Read the current Kanban board state from cm-dashboard. Returns tasks grouped by column.',
166
+ inputSchema: {
167
+ type: 'object',
168
+ properties: {
169
+ projectName: { type: 'string', description: 'Filter by project name (partial match). Omit for first project.' },
170
+ },
171
+ },
172
+ },
173
+ {
174
+ name: 'cm_update_task',
175
+ description: 'Move a single task to a new status on the cm-dashboard.',
176
+ inputSchema: {
177
+ type: 'object',
178
+ properties: {
179
+ conversationId: { type: 'string', description: 'The conversationId used when the task was created (e.g. "<sessionId>:<todoId>")' },
180
+ title: { type: 'string', description: 'Task title (used if conversationId unknown)' },
181
+ status: { type: 'string', enum: ['pending', 'in_progress', 'completed'], description: 'New status' },
182
+ projectName: { type: 'string' },
183
+ },
184
+ required: ['status'],
185
+ },
186
+ },
187
+ ];
188
+
189
+ // ── MCP stdio protocol (JSON-RPC 2.0, Content-Length framing) ─────────────────
190
+
191
+ function sendMessage(msg) {
192
+ const json = JSON.stringify(msg);
193
+ const header = `Content-Length: ${Buffer.byteLength(json)}\r\n\r\n`;
194
+ process.stdout.write(header + json);
195
+ }
196
+
197
+ function respond(id, result) {
198
+ sendMessage({ jsonrpc: '2.0', id, result });
199
+ }
200
+
201
+ function respondError(id, code, message) {
202
+ sendMessage({ jsonrpc: '2.0', id, error: { code, message } });
203
+ }
204
+
205
+ async function handleRequest(msg) {
206
+ const { id, method, params } = msg;
207
+
208
+ if (method === 'initialize') {
209
+ respond(id, {
210
+ protocolVersion: '2024-11-05',
211
+ capabilities: { tools: {} },
212
+ serverInfo: { name: SERVER_NAME, version: SERVER_VERSION },
213
+ });
214
+ return;
215
+ }
216
+
217
+ if (method === 'notifications/initialized') return; // no response needed
218
+
219
+ if (method === 'tools/list') {
220
+ respond(id, { tools: TOOLS });
221
+ return;
222
+ }
223
+
224
+ if (method === 'tools/call') {
225
+ const { name, arguments: args } = params || {};
226
+ try {
227
+ let result;
228
+ if (name === 'cm_sync_todos') result = await cmSyncTodos(args || {});
229
+ else if (name === 'cm_get_tasks') result = await cmGetTasks(args || {});
230
+ else if (name === 'cm_update_task') result = await cmUpdateTask(args || {});
231
+ else throw new Error(`Unknown tool: ${name}`);
232
+
233
+ respond(id, {
234
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
235
+ });
236
+ } catch (err) {
237
+ respond(id, {
238
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
239
+ isError: true,
240
+ });
241
+ }
242
+ return;
243
+ }
244
+
245
+ if (id !== undefined) {
246
+ respondError(id, -32601, `Method not found: ${method}`);
247
+ }
248
+ }
249
+
250
+ // ── Stdin reader (Content-Length framed) ─────────────────────────────────────
251
+
252
+ let buffer = Buffer.alloc(0);
253
+
254
+ process.stdin.on('data', async (chunk) => {
255
+ buffer = Buffer.concat([buffer, chunk]);
256
+
257
+ while (true) {
258
+ // Look for header separator
259
+ const sep = buffer.indexOf('\r\n\r\n');
260
+ if (sep === -1) break;
261
+
262
+ const header = buffer.slice(0, sep).toString();
263
+ const match = header.match(/Content-Length:\s*(\d+)/i);
264
+ if (!match) { buffer = buffer.slice(sep + 4); break; }
265
+
266
+ const contentLength = parseInt(match[1], 10);
267
+ const bodyStart = sep + 4;
268
+ if (buffer.length < bodyStart + contentLength) break; // wait for more data
269
+
270
+ const body = buffer.slice(bodyStart, bodyStart + contentLength).toString('utf8');
271
+ buffer = buffer.slice(bodyStart + contentLength);
272
+
273
+ try {
274
+ const msg = JSON.parse(body);
275
+ await handleRequest(msg);
276
+ } catch {
277
+ // ignore malformed messages
278
+ }
279
+ }
280
+ });
281
+
282
+ process.stdin.on('end', () => process.exit(0));
283
+ process.on('SIGTERM', () => process.exit(0));
284
+ process.on('SIGINT', () => process.exit(0));
@@ -0,0 +1,301 @@
1
+ #!/usr/bin/env node
2
+
3
+ const G = '\x1b[32m';
4
+ const C = '\x1b[36m';
5
+ const W = '\x1b[37m';
6
+ const O = '\x1b[33m';
7
+ const Y = '\x1b[1;33m';
8
+ const BOLD = '\x1b[1m';
9
+ const DIM = '\x1b[2m';
10
+ const NC = '\x1b[0m';
11
+
12
+ // Simple check for Vietnamese environment for the CORE UI
13
+ const isVi = Intl.DateTimeFormat().resolvedOptions().locale.startsWith('vi');
14
+
15
+ const sentiments = {
16
+ start: [
17
+ "🐹: Whiskers twitching... CodyMaster incoming!",
18
+ "🐹: Let's fill these cheeks with 65 skills! ✨",
19
+ "🐹: Waking up from a power nap! Let's build! 🐭"
20
+ ],
21
+ progress: [
22
+ "🐹: Sniffing out your AI agents...",
23
+ "🐹: Running on the wheel to speed this up! 🏃💨",
24
+ "🐹: Found a skill! Stashing it in my pocket... 💎"
25
+ ],
26
+ finish: [
27
+ "🐹: Mission accomplished! Can I have a walnut now? 🥜",
28
+ "🐹: My cheeks are stuffed with 65 skills for you! ✨",
29
+ "🐹: Terminal is Hamster-approved! Better than a wheel! 🎡",
30
+ "🐹: 65 skills stored. I'm ready for vibe coding! ⚡"
31
+ ]
32
+ };
33
+
34
+ const getSentiment = (state) => {
35
+ const list = sentiments[state];
36
+ return ` ${C}${list[Math.floor(Math.random() * list.length)]}${NC}`;
37
+ };
38
+
39
+ const showSkillGuide = (choice) => {
40
+ console.clear();
41
+ console.log(` ${G}\\${NC} ${O}( \\_/ )${NC} ${G}/${NC}`);
42
+ console.log(` ${G}\\${NC} ${O}(${NC} ${G}^ u ^${NC} ${O})${NC} ${G}/${NC}`);
43
+ console.log(` ${G}--${NC} ${O}( ___ )${NC} ${G}--${NC}`);
44
+ console.log('');
45
+
46
+ if (isVi) {
47
+ switch(choice) {
48
+ case '1':
49
+ console.log(`${Y}${BOLD}1. Hướng dẫn toàn tập${NC} (${C}cm-how-it-work${NC})`);
50
+ console.log(`${BOLD}🎯 Tình huống:${NC} Bạn mới cài CodyMaster và chưa biết bắt đầu từ đâu.`);
51
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm @/cm-how-it-work\``);
52
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Giải thích quy trình từ ý tưởng đến lúc deploy một ứng dụng web bằng bộ skill này."`);
53
+ break;
54
+ case '2':
55
+ console.log(`${Y}${BOLD}2. Vibe Coding (Zero Code)${NC} (${C}cm-start${NC})`);
56
+ console.log(`${BOLD}🎯 Tình huống:${NC} Bạn có ý tưởng nhưng lười gõ từng dòng code.`);
57
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm @/cm-start\``);
58
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Tôi muốn làm một trang web bán cà phê có giỏ hàng, dùng Tailwind CSS."`);
59
+ break;
60
+ case '3':
61
+ console.log(`${Y}${BOLD}3. Tham gia dự án có sẵn${NC} (${C}cm-brainstorm-idea${NC})`);
62
+ console.log(`${BOLD}🎯 Tình huống:${NC} Bạn nhảy vào một dự án có sẵn và thấy code quá rắc rối.`);
63
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm @/cm-brainstorm-idea\``);
64
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Đọc toàn bộ project này và chỉ cho tôi 3 điểm yếu lớn nhất cần cải thiện ngay."`);
65
+ break;
66
+ case '4':
67
+ console.log(`${Y}${BOLD}4. Thiết kế giao diện (UX/UI)${NC} (${C}cm-ux-master / cm-ui-preview${NC})`);
68
+ console.log(`${BOLD}🎯 Tình huống:${NC} Bạn muốn web của mình đẹp như Apple hay Linear.`);
69
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm @/cm-ux-master\``);
70
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Lấy style từ trang stripe.com và thiết kế cho tôi một trang thanh toán cực sang."`);
71
+ break;
72
+ case '5':
73
+ console.log(`${Y}${BOLD}5. Lập trình TDD & Pair code${NC} (${C}cm-tdd${NC})`);
74
+ console.log(`${BOLD}🎯 Tình huống:${NC} Bạn muốn code chắc chắn, không có lỗi khi chạy production.`);
75
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm @/cm-tdd\``);
76
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Viết test case trước, sau đó code chức năng đăng ký người dùng cho tôi."`);
77
+ break;
78
+ case '6':
79
+ console.log(`${Y}${BOLD}6. Dọn dẹp & Tái cấu trúc${NC} (${C}cm-clean-code${NC})`);
80
+ console.log(`${BOLD}🎯 Tình huống:${NC} Code chạy được nhưng nhìn như "bãi rác".`);
81
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm @/cm-clean-code\``);
82
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Tối ưu lại file này: xóa code thừa, đặt lại tên biến cho chuẩn và dễ hiểu hơn."`);
83
+ break;
84
+ case '7':
85
+ console.log(`${Y}${BOLD}7. Quét & Sửa lỗi bảo mật${NC} (${C}cm-security-gate${NC})`);
86
+ console.log(`${BOLD}🎯 Tình huống:${NC} Sợ lộ API key hoặc web bị hack XSS.`);
87
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm @/cm-security-gate\``);
88
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Kiểm tra xem project có lỗ hổng bảo mật nào không trước khi tôi push lên GitHub."`);
89
+ break;
90
+ case '8':
91
+ console.log(`${Y}${BOLD}8. Viết tài liệu Docs & API${NC} (${C}cm-dockit${NC})`);
92
+ console.log(`${BOLD}🎯 Tình huống:${NC} Lười viết tài liệu hướng dẫn cho đồng nghiệp hoặc khách hàng.`);
93
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm @/cm-dockit\``);
94
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Tự động tạo file hướng dẫn sử dụng (README) cho toàn bộ project này."`);
95
+ break;
96
+ case '9':
97
+ console.log(`${Y}${BOLD}9. Tạo WOW Landing Page${NC} (${C}cm-cro-methodology${NC})`);
98
+ console.log(`${BOLD}🎯 Tình huống:${NC} Web có người vào nhưng không ai mua hàng/đăng ký.`);
99
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm @/cm-cro-methodology\``);
100
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Phân tích trang web này và chỉ cách tăng gấp đôi tỷ lệ khách hàng đăng ký."`);
101
+ break;
102
+ case '10':
103
+ console.log(`${Y}${BOLD}10. Bảng theo dõi tiến độ${NC} (${C}cm dashboard${NC})`);
104
+ console.log(`${BOLD}🎯 Tình huống:${NC} Muốn biết mình đã làm được bao nhiêu % công việc rồi.`);
105
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm dashboard\``);
106
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Hiện bảng dashboard để tôi xem tiến độ các task hiện tại."`);
107
+ break;
108
+ case '11':
109
+ console.log(`${Y}${BOLD}11. Xem Demo (Claude Code)${NC} (${C}/cm:demo${NC})`);
110
+ console.log(`${BOLD}🎯 Tình huống:${NC} Muốn xem CodyMaster tự "múa" code như thế nào.`);
111
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`/cm:demo\``);
112
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Bắt đầu demo: tự tạo một ứng dụng TodoList từ A-Z trong 1 phút."`);
113
+ break;
114
+ case '12':
115
+ console.log(`${Y}${BOLD}12. Trợ giúp & Cú pháp lệnh${NC} (${C}cm help${NC})`);
116
+ console.log(`${BOLD}🎯 Tình huống:${NC} Quên lệnh hoặc muốn tìm thêm skill xịn khác.`);
117
+ console.log(`${BOLD}🚀 Câu lệnh:${NC} \`cm help\``);
118
+ console.log(`${BOLD}💡 Thử copy prompt này:${NC} "Liệt kê các skill liên quan đến Growth Hacking và Marketing."`);
119
+ break;
120
+ }
121
+ } else {
122
+ switch(choice) {
123
+ case '1':
124
+ console.log(`${Y}${BOLD}1. The Ultimate Guide${NC} (${C}cm-how-it-work${NC})`);
125
+ console.log(`${BOLD}🎯 Situation:${NC} You just installed CodyMaster and don't know where to start.`);
126
+ console.log(`${BOLD}🚀 Command:${NC} \`cm @/cm-how-it-work\``);
127
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Explain the process from idea to deployment using this skill kit."`);
128
+ break;
129
+ case '2':
130
+ console.log(`${Y}${BOLD}2. Vibe Coding (Zero Code)${NC} (${C}cm-start${NC})`);
131
+ console.log(`${BOLD}🎯 Situation:${NC} You have an idea but are too lazy to write code manually.`);
132
+ console.log(`${BOLD}🚀 Command:${NC} \`cm @/cm-start\``);
133
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Build a coffee shop website with a cart using Tailwind CSS."`);
134
+ break;
135
+ case '3':
136
+ console.log(`${Y}${BOLD}3. Code an Existing Project${NC} (${C}cm-brainstorm-idea${NC})`);
137
+ console.log(`${BOLD}🎯 Situation:${NC} You're joining an existing project and the code is a mess.`);
138
+ console.log(`${BOLD}🚀 Command:${NC} \`cm @/cm-brainstorm-idea\``);
139
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Read this entire project and tell me the 3 biggest weaknesses."`);
140
+ break;
141
+ case '4':
142
+ console.log(`${Y}${BOLD}4. Generate UX/UI Designs${NC} (${C}cm-ux-master / cm-ui-preview${NC})`);
143
+ console.log(`${BOLD}🎯 Situation:${NC} You want your web app to look as premium as Apple or Linear.`);
144
+ console.log(`${BOLD}🚀 Command:${NC} \`cm @/cm-ux-master\``);
145
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Copy the style from stripe.com and design a high-end checkout page."`);
146
+ break;
147
+ case '5':
148
+ console.log(`${Y}${BOLD}5. Code TDD & Pair Coding${NC} (${C}cm-tdd${NC})`);
149
+ console.log(`${BOLD}🎯 Situation:${NC} You want reliable code that doesn't break in production.`);
150
+ console.log(`${BOLD}🚀 Command:${NC} \`cm @/cm-tdd\``);
151
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Write test cases first, then implement user registration for me."`);
152
+ break;
153
+ case '6':
154
+ console.log(`${Y}${BOLD}6. Clean & Refactor Codebase${NC} (${C}cm-clean-code${NC})`);
155
+ console.log(`${BOLD}🎯 Situation:${NC} The code works but it looks like a "garbage dump".`);
156
+ console.log(`${BOLD}🚀 Command:${NC} \`cm @/cm-clean-code\``);
157
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Optimize this file: remove dead code and rename variables for clarity."`);
158
+ break;
159
+ case '7':
160
+ console.log(`${Y}${BOLD}7. Scan for Vulnerabilities${NC} (${C}cm-security-gate${NC})`);
161
+ console.log(`${BOLD}🎯 Situation:${NC} Worried about leaking API keys or XSS hacks.`);
162
+ console.log(`${BOLD}🚀 Command:${NC} \`cm @/cm-security-gate\``);
163
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Check if there are any security vulnerabilities before I push to GitHub."`);
164
+ break;
165
+ case '8':
166
+ console.log(`${Y}${BOLD}8. Write Docs & Generate APIs${NC} (${C}cm-dockit${NC})`);
167
+ console.log(`${BOLD}🎯 Situation:${NC} Lazy to write documentation for teammates or clients.`);
168
+ console.log(`${BOLD}🚀 Command:${NC} \`cm @/cm-dockit\``);
169
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Automatically generate a README guide for this entire project."`);
170
+ break;
171
+ case '9':
172
+ console.log(`${Y}${BOLD}9. Release WOW Landing Page${NC} (${C}cm-cro-methodology${NC})`);
173
+ console.log(`${BOLD}🎯 Situation:${NC} Visitors come to your site but don't buy or sign up.`);
174
+ console.log(`${BOLD}🚀 Command:${NC} \`cm @/cm-cro-methodology\``);
175
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Analyze this website and show me how to double my sign-up rate."`);
176
+ break;
177
+ case '10':
178
+ console.log(`${Y}${BOLD}10. Open Progress Dashboard${NC} (${C}cm dashboard${NC})`);
179
+ console.log(`${BOLD}🎯 Situation:${NC} Want to know how much work is actually completed.`);
180
+ console.log(`${BOLD}🚀 Command:${NC} \`cm dashboard\``);
181
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Show the dashboard so I can see the progress of current tasks."`);
182
+ break;
183
+ case '11':
184
+ console.log(`${Y}${BOLD}11. See an Interactive Demo${NC} (${C}/cm:demo${NC})`);
185
+ console.log(`${BOLD}🎯 Situation:${NC} Want to see CodyMaster perform its magic automatically.`);
186
+ console.log(`${BOLD}🚀 Command:${NC} \`/cm:demo\``);
187
+ console.log(`${BOLD}💡 Try this prompt:${NC} "Start demo: build a TodoList app from scratch in 1 minute."`);
188
+ break;
189
+ case '12':
190
+ console.log(`${Y}${BOLD}12. Help & Command List${NC} (${C}cm help${NC})`);
191
+ console.log(`${BOLD}🎯 Situation:${NC} Forgot a command or looking for more cool skills.`);
192
+ console.log(`${BOLD}🚀 Command:${NC} \`cm help\``);
193
+ console.log(`${BOLD}💡 Try this prompt:${NC} "List all skills related to Growth Hacking and Marketing."`);
194
+ break;
195
+ }
196
+ }
197
+
198
+ console.log('');
199
+ console.log(`${W}${BOLD}${isVi ? 'Nhấn ENTER để quay lại...' : 'Press ENTER to go back...'}${NC}`);
200
+ };
201
+
202
+ const printMenu = () => {
203
+ console.clear();
204
+ console.log(` ${G}\\${NC} ${O}( \\_/ )${NC} ${G}/${NC}`);
205
+ console.log(` ${G}\\${NC} ${O}(${NC} ${G}^ u ^${NC} ${O})${NC} ${G}/${NC}`);
206
+ console.log(` ${G}--${NC} ${O}( ___ )${NC} ${G}--${NC} ${G}${BOLD}${isVi ? '✅ Hoàn tất!' : '✅ Done!'}${NC}`);
207
+ console.log(` ${O}| [ ] |${NC}`);
208
+ console.log(` ${O}'--w-w--'${NC}`);
209
+ console.log('');
210
+
211
+ if (isVi) {
212
+ console.log(` ${W}${BOLD}🎉 Thành công! Bạn đã mở khóa 65 kỹ năng AI toàn năng:${NC}`);
213
+ } else {
214
+ console.log(` ${W}${BOLD}🎉 Success! You just unlocked 65 omnipotent AI skills:${NC}`);
215
+ }
216
+
217
+ console.log('');
218
+ console.log(getSentiment('finish'));
219
+ console.log('');
220
+
221
+ if (isVi) {
222
+ console.log(` ${C}🎯 Orchestration${NC} : Lên kế hoạch & Điều phối Agent`);
223
+ console.log(` ${C}🎨 Product${NC} : Thiết kế UX/UI & Tâm lý hành vi`);
224
+ console.log(` ${C}🔧 Engineering${NC} : Code Full-stack & Tái cấu trúc`);
225
+ console.log(` ${C}🔒 Security${NC} : Bảo mật tự động & Chống rò rỉ`);
226
+ console.log(` ${C}⚙️ Operations${NC} : Triển khai an toàn & Quản lý CI/CD`);
227
+ console.log(` ${C}📈 Growth${NC} : Tối ưu chuyển đổi (CRO) & Tracking`);
228
+ console.log('');
229
+ console.log(` ${W}${BOLD}💡 Nhập số (1-12) để xem hướng dẫn & ví dụ:${NC}`);
230
+ console.log('');
231
+ console.log(` 1. ${Y}Cách CodyMaster vận hành ${NC} → cm-how-it-work`);
232
+ console.log(` 2. ${Y}Vibe coding (Zero code) ${NC} → cm-start`);
233
+ console.log(` 3. ${Y}Tham gia dự án có sẵn ${NC} → cm-brainstorm-idea`);
234
+ console.log(` 4. ${Y}Code giao diện từ URL/Ảnh ${NC} → cm-ux-master`);
235
+ console.log(` 5. ${Y}Lập trình TDD & Pair code ${NC} → cm-tdd`);
236
+ console.log(` 6. ${Y}Dọn dẹp & Tái cấu trúc ${NC} → cm-clean-code`);
237
+ console.log(` 7. ${Y}Quét & Sửa lỗi bảo mật ${NC} → cm-security-gate`);
238
+ console.log(` 8. ${Y}Viết tài liệu Docs & API ${NC} → cm-dockit`);
239
+ console.log(` 9. ${Y}Tạo Landing Page "WOW" ${NC} → cm-cro-methodology`);
240
+ console.log(` 10. ${Y}Bảng theo dõi tiến độ ${NC} → cm dashboard`);
241
+ console.log(` 11. ${Y}Xem Demo tự động ${NC} → /cm:demo`);
242
+ console.log(` 12. ${Y}Trợ giúp & Cú pháp lệnh ${NC} → cm help`);
243
+ } else {
244
+ console.log(` ${C}🎯 Orchestration${NC} : Task Planning & Agent Synergy`);
245
+ console.log(` ${C}🎨 Product${NC} : UX/UI Mastery & User Psychology`);
246
+ console.log(` ${C}🔧 Engineering${NC} : Full-stack TDD & Refactoring`);
247
+ console.log(` ${C}🔒 Security${NC} : Automated Gates & Secret Shields`);
248
+ console.log(` ${C}⚙️ Operations${NC} : Safe Deployments & CI/CD Excellence`);
249
+ console.log(` ${C}📈 Growth${NC} : Conversion Tracking & Hacks`);
250
+ console.log('');
251
+ console.log(` ${W}${BOLD}💡 Type a number (1-12) for guide & examples:${NC}`);
252
+ console.log('');
253
+ console.log(` 1. ${Y}The ultimate guide ${NC} → cm-how-it-work`);
254
+ console.log(` 2. ${Y}Vibe coding (Zero code) ${NC} → cm-start`);
255
+ console.log(` 3. ${Y}Code an existing project ${NC} → cm-brainstorm-idea`);
256
+ console.log(` 4. ${Y}Generate UX/UI designs ${NC} → cm-ux-master`);
257
+ console.log(` 5. ${Y}Code TDD & Pair coding ${NC} → cm-tdd`);
258
+ console.log(` 6. ${Y}Clean & Refactor codebase ${NC} → cm-clean-code`);
259
+ console.log(` 7. ${Y}Scan for vulnerabilities ${NC} → cm-security-gate`);
260
+ console.log(` 8. ${Y}Write docs & generate APIs ${NC} → cm-dockit`);
261
+ console.log(` 9. ${Y}Release WOW landing page ${NC} → cm-cro-methodology`);
262
+ console.log(` 10. ${Y}Open progress dashboard ${NC} → cm dashboard`);
263
+ console.log(` 11. ${Y}See an interactive demo ${NC} → /cm:demo`);
264
+ console.log(` 12. ${Y}Help & Command list ${NC} → cm help`);
265
+ }
266
+
267
+ console.log('');
268
+ console.log(` ${W}${BOLD}${isVi ? '📚 Tài liệu:' : '📚 Documentation:'}${NC} ${C}https://cody.todyle.com/docs${NC}`);
269
+ console.log('');
270
+ console.log(` ${DIM}Press 'q' to exit.${NC}`);
271
+ };
272
+
273
+ const main = async () => {
274
+ if (!process.stdout.isTTY) {
275
+ printMenu();
276
+ return;
277
+ }
278
+
279
+ const readline = require('readline');
280
+ const rl = readline.createInterface({
281
+ input: process.stdin,
282
+ output: process.stdout
283
+ });
284
+
285
+ const question = (query) => new Promise(resolve => rl.question(query, resolve));
286
+
287
+ while (true) {
288
+ printMenu();
289
+ const answer = await question(' > ');
290
+ if (answer.toLowerCase() === 'q') break;
291
+ if (parseInt(answer) >= 1 && parseInt(answer) <= 12) {
292
+ showSkillGuide(answer);
293
+ await question('');
294
+ } else if (answer === '') {
295
+ break;
296
+ }
297
+ }
298
+ rl.close();
299
+ };
300
+
301
+ main();