ceobe-mastery-cli 1.0.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 (76) hide show
  1. package/dist/ai/executor.js +88 -0
  2. package/dist/ai/gateway.js +16 -0
  3. package/dist/ai/planner.js +221 -0
  4. package/dist/ai/tools/systemTools.js +136 -0
  5. package/dist/config/env.js +41 -0
  6. package/dist/index.js +168 -0
  7. package/dist/utils/contextLoader.js +133 -0
  8. package/docs/agent-persona.md +48 -0
  9. package/package.json +36 -0
  10. package/rules/coding-standards.md +38 -0
  11. package/rules/engineering-rules.md +214 -0
  12. package/skills/bun-developer/SKILL.md +6 -0
  13. package/skills/bun-developer/package-management.md +4 -0
  14. package/skills/bun-developer/runtime-features.md +4 -0
  15. package/skills/bun-developer/testing.md +3 -0
  16. package/skills/cost-reducer/SKILL.md +6 -0
  17. package/skills/cost-reducer/cloud-and-infra.md +4 -0
  18. package/skills/cost-reducer/code-level-savings.md +4 -0
  19. package/skills/cost-reducer/serverless-optimization.md +3 -0
  20. package/skills/cost-reducer/services-and-finops.md +3 -0
  21. package/skills/create-skill/SKILL.md +6 -0
  22. package/skills/create-skill/examples.md +2 -0
  23. package/skills/create-skill/reference.md +2 -0
  24. package/skills/customer-support/SKILL.md +6 -0
  25. package/skills/customer-support/escalation-guide.md +2 -0
  26. package/skills/customer-support/response-templates.md +4 -0
  27. package/skills/database-architect/SKILL.md +6 -0
  28. package/skills/database-architect/index-optimization.md +3 -0
  29. package/skills/database-architect/migration-best-practices.md +3 -0
  30. package/skills/database-architect/normalization-rules.md +3 -0
  31. package/skills/deployment-ops/SKILL.md +6 -0
  32. package/skills/deployment-ops/dockerfile-standards.md +3 -0
  33. package/skills/deployment-ops/github-actions-templates.md +3 -0
  34. package/skills/deployment-ops/monorepo-deployment.md +2 -0
  35. package/skills/frontend-design/SKILL.md +6 -0
  36. package/skills/frontend-design/component-patterns.md +3 -0
  37. package/skills/frontend-design/modern-aesthetics.md +5 -0
  38. package/skills/frontend-design/state-and-routing.md +3 -0
  39. package/skills/know-me/SKILL.md +6 -0
  40. package/skills/know-me/memory-operations.md +2 -0
  41. package/skills/know-me/what-to-track.md +6 -0
  42. package/skills/n8n/SKILL.md +6 -0
  43. package/skills/n8n/api-reference.md +2 -0
  44. package/skills/n8n/auth-nodes-reference.md +3 -0
  45. package/skills/n8n/custom-nodes-reference.md +3 -0
  46. package/skills/n8n/workflow-reference.md +3 -0
  47. package/skills/researcher/SKILL.md +6 -0
  48. package/skills/researcher/search-techniques.md +3 -0
  49. package/skills/researcher/synthesis-format.md +6 -0
  50. package/skills/scalability/SKILL.md +6 -0
  51. package/skills/scalability/api-and-services.md +3 -0
  52. package/skills/scalability/caching-and-queues.md +3 -0
  53. package/skills/scalability/database-scaling.md +4 -0
  54. package/skills/scalability/infrastructure.md +3 -0
  55. package/skills/scalability/state-management.md +2 -0
  56. package/skills/security/SKILL.md +6 -0
  57. package/skills/security/api-security.md +3 -0
  58. package/skills/security/auth-and-secrets.md +4 -0
  59. package/skills/security/database-and-deps.md +3 -0
  60. package/skills/security/web-security.md +3 -0
  61. package/skills/self-healing/SKILL.md +6 -0
  62. package/skills/self-healing/diagnostic-techniques.md +4 -0
  63. package/skills/self-healing/memory-management.md +2 -0
  64. package/skills/self-healing/pattern-recognition.md +5 -0
  65. package/skills/testing-engineer/SKILL.md +6 -0
  66. package/skills/testing-engineer/e2e-playwright.md +3 -0
  67. package/skills/testing-engineer/mocking-strategies.md +3 -0
  68. package/skills/testing-engineer/unit-testing-vitest.md +3 -0
  69. package/skills/trigger-dev/SKILL.md +6 -0
  70. package/skills/trigger-dev/advanced-reference.md +3 -0
  71. package/skills/trigger-dev/config-reference.md +2 -0
  72. package/skills/trigger-dev/core-reference.md +2 -0
  73. package/templates/api-template.md +82 -0
  74. package/templates/architecture-template.md +63 -0
  75. package/templates/brd-template.md +78 -0
  76. package/templates/tasks-template.md +47 -0
@@ -0,0 +1,88 @@
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.executePlan = executePlan;
7
+ const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
8
+ const env_1 = require("../config/env");
9
+ const gateway_1 = require("./gateway");
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const ora_1 = __importDefault(require("ora"));
12
+ const systemTools_1 = require("./tools/systemTools");
13
+ async function executePlan(planMarkdown) {
14
+ const spinner = (0, ora_1.default)('Claude 4.6 Sonnet is executing the plan...').start();
15
+ try {
16
+ const gatewayUrl = (0, gateway_1.getGatewayUrl)('anthropic');
17
+ const anthropic = new sdk_1.default({
18
+ apiKey: env_1.env.ANTHROPIC_API_KEY,
19
+ baseURL: gatewayUrl
20
+ });
21
+ const systemInstruction = `
22
+ You are the Execution Engine of the Ceobe AI System.
23
+ Your task is to take the provided execution plan and strictly implement it.
24
+ You have access to tool commands if run within an agent wrapper, otherwise output the exact code and terminal commands required to fulfill the user's request.
25
+ DO NOT provide planning commentary. DO NOT hallucinate dependencies. Write code.
26
+ `;
27
+ let messages = [
28
+ {
29
+ role: "user",
30
+ content: `Execute the following plan:\n\n${planMarkdown}`
31
+ }
32
+ ];
33
+ let isThinking = true;
34
+ while (isThinking) {
35
+ const msg = await anthropic.messages.create({
36
+ model: "claude-4.6-sonnet",
37
+ max_tokens: 4096,
38
+ temperature: 0,
39
+ system: systemInstruction,
40
+ messages: messages,
41
+ tools: systemTools_1.tools // Type bypass for SDK version compatibility,
42
+ });
43
+ // Log the assistant's text reasoning before the tool call
44
+ const textBlock = msg.content.find(c => c.type === 'text');
45
+ if (textBlock && textBlock.type === 'text' && textBlock.text) {
46
+ spinner.text = chalk_1.default.cyan(`Claude is thinking: ${textBlock.text.substring(0, 50)}...`);
47
+ }
48
+ const toolCalls = msg.content.filter(c => c.type === 'tool_use');
49
+ messages.push({
50
+ role: "assistant",
51
+ content: msg.content
52
+ });
53
+ if (toolCalls.length === 0) {
54
+ // No more tools, stop loop
55
+ isThinking = false;
56
+ spinner.succeed(chalk_1.default.green('Claude 4.6 Sonnet execution completed.'));
57
+ console.log(chalk_1.default.cyan('\n--- Final Response ---\n'));
58
+ if (textBlock && textBlock.type === 'text')
59
+ console.log(textBlock.text);
60
+ console.log(chalk_1.default.cyan('\n----------------------\n'));
61
+ }
62
+ else {
63
+ // Execute tool calls and feed results back to Claude
64
+ let toolResults = [];
65
+ for (const block of toolCalls) {
66
+ if (block.type !== 'tool_use')
67
+ continue;
68
+ spinner.text = chalk_1.default.yellow(`Claude is executing tool: ${block.name}...`);
69
+ const resultText = await (0, systemTools_1.handleToolCall)(block.name, block.input);
70
+ toolResults.push({
71
+ type: 'tool_result',
72
+ tool_use_id: block.id,
73
+ content: resultText
74
+ });
75
+ }
76
+ messages.push({
77
+ role: "user",
78
+ content: toolResults
79
+ });
80
+ }
81
+ }
82
+ }
83
+ catch (error) {
84
+ spinner.fail(chalk_1.default.red('Claude 4.6 Sonnet execution failed.'));
85
+ console.error(chalk_1.default.red(error.message));
86
+ throw error;
87
+ }
88
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGatewayUrl = getGatewayUrl;
4
+ const env_1 = require("../config/env");
5
+ /**
6
+ * Constructs the Cloudflare AI Gateway URL for a given provider.
7
+ *
8
+ * @param provider - 'google-genai' for Gemini, 'anthropic' for Claude
9
+ * @returns The gateway URL
10
+ */
11
+ function getGatewayUrl(provider) {
12
+ if (!env_1.env.CLOUDFLARE_ACCOUNT_ID || !env_1.env.CLOUDFLARE_GATEWAY_ID) {
13
+ throw new Error('Cloudflare Gateway credentials are not properly configured.');
14
+ }
15
+ return `https://gateway.ai.cloudflare.com/v1/${env_1.env.CLOUDFLARE_ACCOUNT_ID}/${env_1.env.CLOUDFLARE_GATEWAY_ID}/${provider}`;
16
+ }
@@ -0,0 +1,221 @@
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.selectRelevantSkills = selectRelevantSkills;
7
+ exports.generateBRD = generateBRD;
8
+ exports.generateArchitecture = generateArchitecture;
9
+ exports.generateImplementationPlan = generateImplementationPlan;
10
+ exports.auditPlan = auditPlan;
11
+ const genai_1 = require("@google/genai");
12
+ const env_1 = require("../config/env");
13
+ const chalk_1 = __importDefault(require("chalk"));
14
+ const ora_1 = __importDefault(require("ora"));
15
+ const contextLoader_1 = require("../utils/contextLoader");
16
+ const ai = new genai_1.GoogleGenAI({
17
+ apiKey: env_1.env.GEMINI_API_KEY,
18
+ // Note: Depending on the exact SDK version/options,
19
+ // baseUrl mapping might require custom fetch or specific instantiation config.
20
+ // Using native fetch or overriding baseUrl here ensures routing via Cloudflare.
21
+ });
22
+ /**
23
+ * PHASE 0: SKILL CLASSIFICATION
24
+ * Determines which specific skill sets are needed for the user's task.
25
+ */
26
+ async function selectRelevantSkills(taskDescription) {
27
+ const spinner = (0, ora_1.default)('Gemini 3.1 Pro is analyzing the required skills for this task...').start();
28
+ try {
29
+ const availableSkills = (0, contextLoader_1.getAvailableSkills)();
30
+ if (availableSkills.length === 0) {
31
+ spinner.succeed('No skills found in workspace. Proceeding without skills.');
32
+ return [];
33
+ }
34
+ const systemInstruction = `
35
+ You are the Ceobe AI Skill Router.
36
+ Your ONLY job is to analyze the user request and determine which internal skills are required.
37
+
38
+ Available Skills:
39
+ ${availableSkills.join(', ')}
40
+
41
+ User Request:
42
+ ${taskDescription}
43
+
44
+ Analyze the request. Output ONLY a raw, comma-separated list of the exact skill names required. If none apply, output "none".
45
+ Example: "cost-reducer, scalability, frontend-design"
46
+ NO markdown, NO greetings, NO extra text.
47
+ `;
48
+ const response = await ai.models.generateContent({
49
+ model: 'gemini-3.1-pro-preview',
50
+ contents: [{ role: 'user', parts: [{ text: systemInstruction }] }],
51
+ config: { temperature: 0.0 } // 0.0 for strict deterministic classification
52
+ });
53
+ const output = (response.text || '').trim();
54
+ if (output.toLowerCase() === 'none') {
55
+ spinner.succeed(chalk_1.default.green('Gemini selected NO specific skills.'));
56
+ return [];
57
+ }
58
+ const selected = output.split(',').map(s => s.trim()).filter(s => availableSkills.includes(s));
59
+ spinner.succeed(chalk_1.default.green(`Gemini selected skills: ${selected.join(', ')}`));
60
+ return selected;
61
+ }
62
+ catch (error) {
63
+ spinner.fail(chalk_1.default.red('Failed to route skills. Proceeding with base rules only.'));
64
+ return [];
65
+ }
66
+ }
67
+ async function generateBRD(taskDescription, selectedSkills = []) {
68
+ const spinner = (0, ora_1.default)('Gemini 3.1 Pro is analyzing the request and generating a Business Requirements Document...').start();
69
+ try {
70
+ const rules = (0, contextLoader_1.readCeobeRules)();
71
+ const skillsContext = selectedSkills.length > 0 ? (0, contextLoader_1.readSpecificSkills)(selectedSkills) : '';
72
+ const systemInstruction = `
73
+ You are the Brain of the Ceobe AI Engineering System. You are a Senior Architect.
74
+ STAGE 1: DISCOVERY & BRD.
75
+
76
+ Adhere to these rules:
77
+ ${rules}
78
+
79
+ ${skillsContext}
80
+
81
+ User Request:
82
+ ${taskDescription}
83
+
84
+ Output ONLY the markdown Business Requirements Document (BRD). Do not output greetings or implementation steps yet. Focus on goals, target audience, and feature definitions.
85
+
86
+ YOU MUST FORMAT YOUR OUTPUT EXACTLY ACCORDING TO THIS TEMPLATE:
87
+ ${(0, contextLoader_1.readTemplate)('brd-template.md')}
88
+ `;
89
+ const response = await ai.models.generateContent({
90
+ model: 'gemini-3.1-pro-preview',
91
+ contents: [{ role: 'user', parts: [{ text: systemInstruction }] }],
92
+ config: { temperature: 0.2 }
93
+ });
94
+ spinner.succeed(chalk_1.default.green('Gemini 3.1 Pro successfully generated the BRD.'));
95
+ return response.text || '';
96
+ }
97
+ catch (error) {
98
+ spinner.fail(chalk_1.default.red('Gemini 3.1 Pro failed to generate BRD.'));
99
+ throw error;
100
+ }
101
+ }
102
+ async function generateArchitecture(brdContent, selectedSkills = []) {
103
+ const spinner = (0, ora_1.default)('Gemini 3.1 Pro is designing the System Architecture...').start();
104
+ try {
105
+ const rules = (0, contextLoader_1.readCeobeRules)();
106
+ const skillsContext = selectedSkills.length > 0 ? (0, contextLoader_1.readSpecificSkills)(selectedSkills) : '';
107
+ const systemInstruction = `
108
+ You are the Brain of the Ceobe AI Engineering System. You are a Senior Architect.
109
+ STAGE 2: ARCHITECTURE DESIGN.
110
+
111
+ Rules:
112
+ ${rules}
113
+
114
+ ${skillsContext}
115
+
116
+ Current BRD Context:
117
+ ${brdContent}
118
+
119
+ Output ONLY the markdown Architecture Document based on the constraints. Outline the tech stack, data schemas, and folder structures. Do not write full code.
120
+
121
+ YOU MUST FORMAT YOUR OUTPUT EXACTLY ACCORDING TO THIS TEMPLATE:
122
+ ${(0, contextLoader_1.readTemplate)('architecture-template.md')}
123
+ `;
124
+ const response = await ai.models.generateContent({
125
+ model: 'gemini-3.1-pro-preview',
126
+ contents: [{ role: 'user', parts: [{ text: systemInstruction }] }],
127
+ config: { temperature: 0.2 }
128
+ });
129
+ spinner.succeed(chalk_1.default.green('Gemini 3.1 Pro successfully generated the Architecture Plan.'));
130
+ return response.text || '';
131
+ }
132
+ catch (error) {
133
+ spinner.fail(chalk_1.default.red('Gemini 3.1 Pro failed to generate Architecture Plan.'));
134
+ throw error;
135
+ }
136
+ }
137
+ async function generateImplementationPlan(architectureContent, selectedSkills = []) {
138
+ const spinner = (0, ora_1.default)('Gemini 3.1 Pro is generating the Execution Checklist...').start();
139
+ try {
140
+ const rules = (0, contextLoader_1.readCeobeRules)();
141
+ const skillsContext = selectedSkills.length > 0 ? (0, contextLoader_1.readSpecificSkills)(selectedSkills) : '';
142
+ const systemInstruction = `
143
+ You are the Brain of the Ceobe AI Engineering System. You are a Senior Architect.
144
+ STAGE 3: IMPLEMENTATION / SPRINT PLANNING.
145
+
146
+ Rules:
147
+ ${rules}
148
+
149
+ ${skillsContext}
150
+
151
+ Current Architecture Plan Context:
152
+ ${architectureContent}
153
+
154
+ Output ONLY the markdown execution checklist (a Jira-like task list). Detail what file paths to create/edit and exactly what code Claude should write in each file.
155
+
156
+ YOU MUST FORMAT YOUR OUTPUT EXACTLY ACCORDING TO THIS TEMPLATE:
157
+ ${(0, contextLoader_1.readTemplate)('tasks-template.md')}
158
+ `;
159
+ const response = await ai.models.generateContent({
160
+ model: 'gemini-3.1-pro-preview',
161
+ contents: [{ role: 'user', parts: [{ text: systemInstruction }] }],
162
+ config: { temperature: 0.2 }
163
+ });
164
+ spinner.succeed(chalk_1.default.green('Gemini 3.1 Pro successfully generated the Execution Checklist.'));
165
+ return response.text || '';
166
+ }
167
+ catch (error) {
168
+ spinner.fail(chalk_1.default.red('Gemini 3.1 Pro failed to generate Checklist.'));
169
+ throw error;
170
+ }
171
+ }
172
+ async function auditPlan(combinedContent, selectedSkills = []) {
173
+ const spinner = (0, ora_1.default)('Gemini 3.1 Pro is auditing the project plans for conflicts and rule violations...').start();
174
+ try {
175
+ const rules = (0, contextLoader_1.readCeobeRules)();
176
+ const skillsContext = selectedSkills.length > 0 ? (0, contextLoader_1.readSpecificSkills)(selectedSkills) : '';
177
+ const systemInstruction = `
178
+ You are the Lead Quality Assurance Auditor for the Ceobe AI Engineering System.
179
+ STAGE 4: PLAN AUDIT & VALIDATION.
180
+
181
+ Rules:
182
+ ${rules}
183
+
184
+ ${skillsContext}
185
+
186
+ Below is the combined content of the BRD, Architecture, and Task execution plan that the user has manually reviewed and potentially edited.
187
+
188
+ Combined Content:
189
+ ${combinedContent}
190
+
191
+ Your Job:
192
+ 1. Verify if the Architecture contradicts the BRD.
193
+ 2. Verify if the Task List executes everything required by the Architecture.
194
+ 3. Verify if anything in the plans violates the core Ceobe Engineering Rules or the provided Skills constraints (e.g. using npm when bun-developer is active).
195
+
196
+ If the plans are 100% solid and ready for execution, reply ABSOLUTELY ONLY with the word: "APPROVED".
197
+ If there are critical conflicts, bugs, or missing steps, reply with a markdown list of the mandatory changes needed. Do NOT say "APPROVED" if there are warnings.
198
+ `;
199
+ const response = await ai.models.generateContent({
200
+ model: 'gemini-3.1-pro-preview',
201
+ contents: [{ role: 'user', parts: [{ text: systemInstruction }] }],
202
+ config: { temperature: 0.1 }
203
+ });
204
+ const output = (response.text || '').trim();
205
+ if (output === 'APPROVED') {
206
+ spinner.succeed(chalk_1.default.green('Audit PASSED. Project blueprint is solid and ready for execution.'));
207
+ return true;
208
+ }
209
+ else {
210
+ spinner.warn(chalk_1.default.yellow('Audit FAILED. Conflicts or missing steps detected.'));
211
+ console.log(chalk_1.default.cyan(`\\n--- Auditor Feedback ---\\n`));
212
+ console.log(output);
213
+ console.log(chalk_1.default.cyan(`\\n-------------------------\\n`));
214
+ return false;
215
+ }
216
+ }
217
+ catch (error) {
218
+ spinner.fail(chalk_1.default.red('Gemini 3.1 Pro failed to audit the plans.'));
219
+ throw error;
220
+ }
221
+ }
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.tools = void 0;
37
+ exports.handleToolCall = handleToolCall;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const child_process_1 = require("child_process");
41
+ const util_1 = require("util");
42
+ const env_1 = require("../../config/env");
43
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
44
+ exports.tools = [
45
+ {
46
+ name: 'read_file',
47
+ description: 'Reads the content of a file. Returns the file content as a string.',
48
+ input_schema: {
49
+ type: 'object',
50
+ properties: {
51
+ file_path: {
52
+ type: 'string',
53
+ description: 'The absolute or relative path to the file to read. (e.g. src/index.ts or D:/path/to/file)'
54
+ }
55
+ },
56
+ required: ['file_path']
57
+ }
58
+ },
59
+ {
60
+ name: 'write_file',
61
+ description: 'Writes content to a file. Overwrites the file if it exists, creates it if it does not. Also creates necessary parent directories.',
62
+ input_schema: {
63
+ type: 'object',
64
+ properties: {
65
+ file_path: {
66
+ type: 'string',
67
+ description: 'The absolute or relative path to the file to write.'
68
+ },
69
+ content: {
70
+ type: 'string',
71
+ description: 'The full content to write to the file.'
72
+ }
73
+ },
74
+ required: ['file_path', 'content']
75
+ }
76
+ },
77
+ {
78
+ name: 'execute_command',
79
+ description: 'Executes a bash/PowerShell command on the host system. Returns stdout and stderr.',
80
+ input_schema: {
81
+ type: 'object',
82
+ properties: {
83
+ command: {
84
+ type: 'string',
85
+ description: 'The terminal command to run (e.g., npm install express, tsc, dir)'
86
+ }
87
+ },
88
+ required: ['command']
89
+ }
90
+ }
91
+ ];
92
+ // Helper to resolve paths against the workspace root if they are relative
93
+ function resolvePath(filePath) {
94
+ if (path.isAbsolute(filePath)) {
95
+ return filePath;
96
+ }
97
+ return path.join(env_1.env.TARGET_PROJECT_DIR, filePath);
98
+ }
99
+ async function handleToolCall(toolName, input) {
100
+ try {
101
+ switch (toolName) {
102
+ case 'read_file': {
103
+ const fullPath = resolvePath(input.file_path);
104
+ if (!fs.existsSync(fullPath)) {
105
+ return `Error: File not found at ${fullPath}`;
106
+ }
107
+ return fs.readFileSync(fullPath, 'utf8');
108
+ }
109
+ case 'write_file': {
110
+ const fullPath = resolvePath(input.file_path);
111
+ const dir = path.dirname(fullPath);
112
+ if (!fs.existsSync(dir)) {
113
+ fs.mkdirSync(dir, { recursive: true });
114
+ }
115
+ fs.writeFileSync(fullPath, input.content, 'utf8');
116
+ return `Successfully wrote to ${fullPath}`;
117
+ }
118
+ case 'execute_command': {
119
+ // Caution: In a real secure environment, commands must be sandboxed or require user approval.
120
+ // For this AI engineering system, we allow execution within the workspace context.
121
+ const { stdout, stderr } = await execAsync(input.command, { cwd: env_1.env.TARGET_PROJECT_DIR });
122
+ let result = '';
123
+ if (stdout)
124
+ result += `STDOUT:\n${stdout}\n`;
125
+ if (stderr)
126
+ result += `STDERR:\n${stderr}\n`;
127
+ return result || 'Command executed successfully with no output.';
128
+ }
129
+ default:
130
+ return `Error: Tool ${toolName} not recognized.`;
131
+ }
132
+ }
133
+ catch (error) {
134
+ return `Error executing ${toolName}: ${error.message}`;
135
+ }
136
+ }
@@ -0,0 +1,41 @@
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.env = void 0;
7
+ exports.loadEnv = loadEnv;
8
+ const dotenv_1 = __importDefault(require("dotenv"));
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ // Load environment variables from .env file
11
+ dotenv_1.default.config();
12
+ const path_1 = __importDefault(require("path"));
13
+ function loadEnv() {
14
+ const missingKeys = [];
15
+ const getEnv = (key) => {
16
+ const value = process.env[key];
17
+ if (!value) {
18
+ missingKeys.push(key);
19
+ return '';
20
+ }
21
+ return value;
22
+ };
23
+ const config = {
24
+ CLOUDFLARE_ACCOUNT_ID: getEnv('CLOUDFLARE_ACCOUNT_ID'),
25
+ CLOUDFLARE_GATEWAY_ID: getEnv('CLOUDFLARE_GATEWAY_ID'),
26
+ GEMINI_API_KEY: getEnv('GEMINI_API_KEY'),
27
+ ANTHROPIC_API_KEY: getEnv('ANTHROPIC_API_KEY'),
28
+ // The location of Ceobe's brain (skills, templates, rules)
29
+ CEOEBE_INSTALL_DIR: process.env.CEOEBE_INSTALL_DIR || path_1.default.resolve(__dirname, '../../'),
30
+ // The user's current terminal directory where code is written
31
+ TARGET_PROJECT_DIR: process.cwd(),
32
+ };
33
+ if (missingKeys.length > 0) {
34
+ console.error(chalk_1.default.red(`[Error] Missing required environment variables:`));
35
+ missingKeys.forEach(key => console.error(chalk_1.default.red(` - ${key}`)));
36
+ console.error(chalk_1.default.yellow(`\nPlease set them in your .env file or system environment variables.`));
37
+ process.exit(1);
38
+ }
39
+ return config;
40
+ }
41
+ exports.env = loadEnv();
package/dist/index.js ADDED
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const commander_1 = require("commander");
41
+ const chalk_1 = __importDefault(require("chalk"));
42
+ const env_1 = require("./config/env");
43
+ const planner_1 = require("./ai/planner");
44
+ const executor_1 = require("./ai/executor");
45
+ const fs = __importStar(require("fs"));
46
+ const path = __importStar(require("path"));
47
+ const program = new commander_1.Command();
48
+ program
49
+ .name('ceobe')
50
+ .description('Ceobe CLI: An AI Engineering orchestrator using Gemini 3.1 Pro and Sonnet 4.6 via Cloudflare AI Gateway.')
51
+ .version('1.0.0');
52
+ program
53
+ .command('plan <description>')
54
+ .description('Phase 1: Generate BRD, Architecture, and Task Plan for review.')
55
+ .action(async (description) => {
56
+ console.log(chalk_1.default.blue(`Planning project with description: ${description}`));
57
+ console.log(chalk_1.default.gray(`Workspace: ${env_1.env.TARGET_PROJECT_DIR}\n`));
58
+ try {
59
+ const ceobeDir = path.join(env_1.env.TARGET_PROJECT_DIR, '.ceobe');
60
+ if (!fs.existsSync(ceobeDir))
61
+ fs.mkdirSync(ceobeDir, { recursive: true });
62
+ const selectedSkills = await (0, planner_1.selectRelevantSkills)(description);
63
+ const brd = await (0, planner_1.generateBRD)(description, selectedSkills);
64
+ fs.writeFileSync(path.join(ceobeDir, 'brd.md'), brd);
65
+ const arch = await (0, planner_1.generateArchitecture)(brd, selectedSkills);
66
+ fs.writeFileSync(path.join(ceobeDir, 'architecture.md'), arch);
67
+ const plan = await (0, planner_1.generateImplementationPlan)(arch, selectedSkills);
68
+ fs.writeFileSync(path.join(ceobeDir, 'task.md'), plan);
69
+ console.log(chalk_1.default.magenta(`\n[Planning Phase Complete] Documents saved to .ceobe/ folder.`));
70
+ console.log(chalk_1.default.yellow(`Please review brd.md, architecture.md, and task.md.`));
71
+ console.log(chalk_1.default.green(`Once approved, run: npx ceobe execute\n`));
72
+ }
73
+ catch (err) {
74
+ console.error(chalk_1.default.red('\n[Error] Project planning failed.'));
75
+ console.error(err);
76
+ }
77
+ });
78
+ program
79
+ .command('execute [taskFile]')
80
+ .description('Phase 2: Execute a generated task plan (default: task.md).')
81
+ .action(async (taskFile = 'task.md') => {
82
+ console.log(chalk_1.default.blue(`Executing plan from: .ceobe/${taskFile}`));
83
+ try {
84
+ const taskPath = path.join(env_1.env.TARGET_PROJECT_DIR, '.ceobe', taskFile);
85
+ if (!fs.existsSync(taskPath)) {
86
+ console.error(chalk_1.default.red(`\n[Error] Task file not found at ${taskPath}`));
87
+ console.error(chalk_1.default.yellow(`Did you forget to run 'ceobe plan' first?\n`));
88
+ return;
89
+ }
90
+ const planContent = fs.readFileSync(taskPath, 'utf8');
91
+ console.log(chalk_1.default.magenta(`\n[Execution Phase Started. Firing up Sonnet 4.6]\n`));
92
+ await (0, executor_1.executePlan)(planContent);
93
+ }
94
+ catch (err) {
95
+ console.error(chalk_1.default.red('\n[Error] Execution failed.'));
96
+ console.error(err);
97
+ }
98
+ });
99
+ program
100
+ .command('audit [prefix]')
101
+ .description('Phase 1.5: Audit your edited plans for conflicts before execution. Prefix is empty for new projects, or "feature-" for features.')
102
+ .action(async (prefix = '') => {
103
+ console.log(chalk_1.default.blue(`Auditing plans in .ceobe/ folder with prefix '${prefix}'...`));
104
+ try {
105
+ const ceobeDir = path.join(env_1.env.TARGET_PROJECT_DIR, '.ceobe');
106
+ const brdPath = path.join(ceobeDir, prefix ? `${prefix}brd.md` : 'brd.md');
107
+ const archPath = path.join(ceobeDir, prefix ? `${prefix}architecture.md` : 'architecture.md');
108
+ const taskPath = path.join(ceobeDir, prefix ? `${prefix}task.md` : 'task.md');
109
+ if (!fs.existsSync(brdPath) || !fs.existsSync(archPath) || !fs.existsSync(taskPath)) {
110
+ console.error(chalk_1.default.red(`\n[Error] Missing plan files in ${ceobeDir}. Expected brd, architecture, and task files.`));
111
+ return;
112
+ }
113
+ const combinedContent = `
114
+ --- BRD ---
115
+ ${fs.readFileSync(brdPath, 'utf8')}
116
+ --- ARCHITECTURE ---
117
+ ${fs.readFileSync(archPath, 'utf8')}
118
+ --- TASK PLAN ---
119
+ ${fs.readFileSync(taskPath, 'utf8')}
120
+ `;
121
+ // Simple heuristic: read the BRD description to guess the skills again
122
+ const briefDescription = fs.readFileSync(brdPath, 'utf8').substring(0, 500);
123
+ const selectedSkills = await (0, planner_1.selectRelevantSkills)(briefDescription);
124
+ const passed = await (0, planner_1.auditPlan)(combinedContent, selectedSkills);
125
+ if (passed) {
126
+ console.log(chalk_1.default.green(`\nYou are cleared to run: npx ceobe execute ${prefix ? prefix + 'task.md' : ''}\n`));
127
+ }
128
+ else {
129
+ console.log(chalk_1.default.yellow(`\nPlease fix the above issues in your markdown files, then run 'ceobe audit' again.\n`));
130
+ }
131
+ }
132
+ catch (err) {
133
+ console.error(chalk_1.default.red('\n[Error] Audit failed.'));
134
+ console.error(err);
135
+ }
136
+ });
137
+ program
138
+ .command('build-feature <description>')
139
+ .description('Build a new feature following Ceobe engineering rules.')
140
+ .action(async (description) => {
141
+ console.log(chalk_1.default.blue(`Building feature with description: ${description}`));
142
+ console.log(chalk_1.default.gray(`Workspace: ${env_1.env.TARGET_PROJECT_DIR}\n`));
143
+ try {
144
+ const ceobeDir = path.join(env_1.env.TARGET_PROJECT_DIR, '.ceobe');
145
+ if (!fs.existsSync(ceobeDir))
146
+ fs.mkdirSync(ceobeDir, { recursive: true });
147
+ const selectedSkills = await (0, planner_1.selectRelevantSkills)(description);
148
+ const brd = await (0, planner_1.generateBRD)(description, selectedSkills);
149
+ fs.writeFileSync(path.join(ceobeDir, 'feature-brd.md'), brd);
150
+ const arch = await (0, planner_1.generateArchitecture)(brd, selectedSkills);
151
+ fs.writeFileSync(path.join(ceobeDir, 'feature-architecture.md'), arch);
152
+ const plan = await (0, planner_1.generateImplementationPlan)(arch, selectedSkills);
153
+ fs.writeFileSync(path.join(ceobeDir, 'feature-task.md'), plan);
154
+ console.log(chalk_1.default.magenta(`\n[Feature Blueprint Complete] Documents saved to .ceobe/ folder.`));
155
+ console.log(chalk_1.default.yellow(`Please review feature-brd.md, feature-architecture.md, and feature-task.md.`));
156
+ console.log(chalk_1.default.green(`Once approved, run: npx ceobe execute feature-task.md\n`));
157
+ }
158
+ catch (err) {
159
+ console.error(chalk_1.default.red('\n[Error] Feature build failed.'));
160
+ console.error(err);
161
+ }
162
+ });
163
+ // Parse the arguments
164
+ program.parse(process.argv);
165
+ // If no arguments passed, show help
166
+ if (!process.argv.slice(2).length) {
167
+ program.outputHelp();
168
+ }