mycontext-cli 2.0.8 → 2.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/communication/AgentCommunicationManager.d.ts +3 -3
- package/dist/agents/communication/AgentCommunicationManager.d.ts.map +1 -1
- package/dist/agents/communication/AgentCommunicationManager.js +7 -6
- package/dist/agents/communication/AgentCommunicationManager.js.map +1 -1
- package/dist/agents/evolution/CodeEvolutionEngine.d.ts.map +1 -1
- package/dist/agents/evolution/CodeEvolutionEngine.js +10 -7
- package/dist/agents/evolution/CodeEvolutionEngine.js.map +1 -1
- package/dist/agents/implementations/ArchitectAgent.js +2 -2
- package/dist/agents/implementations/ArchitectAgent.js.map +1 -1
- package/dist/agents/implementations/BackendDevAgent.d.ts.map +1 -1
- package/dist/agents/implementations/BackendDevAgent.js +4 -1
- package/dist/agents/implementations/BackendDevAgent.js.map +1 -1
- package/dist/agents/implementations/BuildStrategyAgent.d.ts.map +1 -1
- package/dist/agents/implementations/BuildStrategyAgent.js +4 -3
- package/dist/agents/implementations/BuildStrategyAgent.js.map +1 -1
- package/dist/agents/implementations/CodeGenSubAgent.d.ts.map +1 -1
- package/dist/agents/implementations/CodeGenSubAgent.js +6 -5
- package/dist/agents/implementations/CodeGenSubAgent.js.map +1 -1
- package/dist/agents/implementations/DocsSubAgent.js +2 -2
- package/dist/agents/implementations/DocsSubAgent.js.map +1 -1
- package/dist/agents/implementations/EnhancementAgent.d.ts.map +1 -1
- package/dist/agents/implementations/EnhancementAgent.js +6 -4
- package/dist/agents/implementations/EnhancementAgent.js.map +1 -1
- package/dist/agents/implementations/InteractiveAgent.d.ts.map +1 -1
- package/dist/agents/implementations/InteractiveAgent.js +8 -1
- package/dist/agents/implementations/InteractiveAgent.js.map +1 -1
- package/dist/agents/implementations/PromptConstructorAgent.d.ts.map +1 -1
- package/dist/agents/implementations/PromptConstructorAgent.js +79 -31
- package/dist/agents/implementations/PromptConstructorAgent.js.map +1 -1
- package/dist/agents/implementations/QASubAgent.js +2 -2
- package/dist/agents/implementations/QASubAgent.js.map +1 -1
- package/dist/agents/implementations/SecurityAgent.js +2 -2
- package/dist/agents/implementations/SecurityAgent.js.map +1 -1
- package/dist/agents/implementations/WorkflowAgent.d.ts +0 -1
- package/dist/agents/implementations/WorkflowAgent.d.ts.map +1 -1
- package/dist/agents/implementations/WorkflowAgent.js +6 -10
- package/dist/agents/implementations/WorkflowAgent.js.map +1 -1
- package/dist/agents/intelligence/ProjectIntelligence.js +5 -5
- package/dist/agents/intelligence/ProjectIntelligence.js.map +1 -1
- package/dist/agents/orchestrator/SubAgentOrchestrator.d.ts.map +1 -1
- package/dist/agents/orchestrator/SubAgentOrchestrator.js +4 -4
- package/dist/agents/orchestrator/SubAgentOrchestrator.js.map +1 -1
- package/dist/cli.js +8 -40
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +9 -9
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/enhance.d.ts.map +1 -1
- package/dist/commands/enhance.js +23 -78
- package/dist/commands/enhance.js.map +1 -1
- package/dist/commands/generate-components.d.ts.map +1 -1
- package/dist/commands/generate-components.js +12 -7
- package/dist/commands/generate-components.js.map +1 -1
- package/dist/commands/generate-todos.js +1 -1
- package/dist/commands/generate-todos.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +57 -41
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/playbooks.d.ts.map +1 -1
- package/dist/commands/playbooks.js +14 -8
- package/dist/commands/playbooks.js.map +1 -1
- package/dist/commands/preview.js +1 -1
- package/dist/commands/preview.js.map +1 -1
- package/dist/commands/refine.d.ts.map +1 -1
- package/dist/commands/refine.js +5 -3
- package/dist/commands/refine.js.map +1 -1
- package/dist/commands/sanitize.d.ts.map +1 -1
- package/dist/commands/sanitize.js +11 -4
- package/dist/commands/sanitize.js.map +1 -1
- package/dist/commands/setup-database.d.ts.map +1 -1
- package/dist/commands/setup-database.js +9 -7
- package/dist/commands/setup-database.js.map +1 -1
- package/dist/commands/setup-instantdb.d.ts.map +1 -1
- package/dist/commands/setup-instantdb.js +9 -7
- package/dist/commands/setup-instantdb.js.map +1 -1
- package/dist/config/build-strategies.json +2 -2
- package/dist/{agents/personalities/definitions.d.ts → constants/subAgentPersonalities.d.ts} +2 -2
- package/dist/constants/subAgentPersonalities.d.ts.map +1 -0
- package/dist/{agents/personalities/definitions.js → constants/subAgentPersonalities.js} +2 -2
- package/dist/constants/subAgentPersonalities.js.map +1 -0
- package/dist/package.json +1 -1
- package/dist/types/analysis.d.ts +67 -0
- package/dist/types/analysis.d.ts.map +1 -0
- package/dist/types/analysis.js +7 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/types/components.d.ts +90 -0
- package/dist/types/components.d.ts.map +1 -0
- package/dist/types/components.js +7 -0
- package/dist/types/components.js.map +1 -0
- package/dist/types/enhancement.d.ts +127 -0
- package/dist/types/enhancement.d.ts.map +1 -0
- package/dist/types/enhancement.js +7 -0
- package/dist/types/enhancement.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +25 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/progress.d.ts +88 -0
- package/dist/types/progress.d.ts.map +1 -0
- package/dist/types/progress.js +7 -0
- package/dist/types/progress.js.map +1 -0
- package/dist/utils/ProjectHealthMonitor.d.ts.map +1 -1
- package/dist/utils/ProjectHealthMonitor.js +47 -36
- package/dist/utils/ProjectHealthMonitor.js.map +1 -1
- package/dist/utils/agentDefinitions.d.ts +2 -2
- package/dist/utils/agentDefinitions.d.ts.map +1 -1
- package/dist/utils/agentDefinitions.js +40 -33
- package/dist/utils/agentDefinitions.js.map +1 -1
- package/dist/utils/buildStrategyManager.d.ts.map +1 -1
- package/dist/utils/buildStrategyManager.js +1 -1
- package/dist/utils/buildStrategyManager.js.map +1 -1
- package/dist/utils/claudeAgentClient.d.ts +0 -1
- package/dist/utils/claudeAgentClient.d.ts.map +1 -1
- package/dist/utils/claudeAgentClient.js +46 -39
- package/dist/utils/claudeAgentClient.js.map +1 -1
- package/dist/utils/hybridAIClient.d.ts +1 -9
- package/dist/utils/hybridAIClient.d.ts.map +1 -1
- package/dist/utils/hybridAIClient.js +81 -78
- package/dist/utils/hybridAIClient.js.map +1 -1
- package/dist/utils/mcpAgentIntegration.d.ts.map +1 -1
- package/dist/utils/mcpAgentIntegration.js +1 -1
- package/dist/utils/mcpAgentIntegration.js.map +1 -1
- package/dist/utils/mcpTools.d.ts +5 -5
- package/dist/utils/mcpTools.d.ts.map +1 -1
- package/dist/utils/mcpTools.js +319 -241
- package/dist/utils/mcpTools.js.map +1 -1
- package/dist/utils/progressTracker.d.ts +3 -79
- package/dist/utils/progressTracker.d.ts.map +1 -1
- package/dist/utils/progressTracker.js +92 -68
- package/dist/utils/progressTracker.js.map +1 -1
- package/dist/utils/typeTemplateGenerator.d.ts.map +1 -1
- package/dist/utils/typeTemplateGenerator.js +125 -79
- package/dist/utils/typeTemplateGenerator.js.map +1 -1
- package/package.json +1 -1
- package/dist/agents/implementations/ClaudeAgentWorkflow.d.ts +0 -110
- package/dist/agents/implementations/ClaudeAgentWorkflow.d.ts.map +0 -1
- package/dist/agents/implementations/ClaudeAgentWorkflow.js +0 -661
- package/dist/agents/implementations/ClaudeAgentWorkflow.js.map +0 -1
- package/dist/agents/personalities/definitions.d.ts.map +0 -1
- package/dist/agents/personalities/definitions.js.map +0 -1
- package/dist/commands/model.d.ts +0 -22
- package/dist/commands/model.d.ts.map +0 -1
- package/dist/commands/model.js +0 -130
- package/dist/commands/model.js.map +0 -1
- package/dist/commands/normalize.d.ts +0 -5
- package/dist/commands/normalize.d.ts.map +0 -1
- package/dist/commands/normalize.js +0 -128
- package/dist/commands/normalize.js.map +0 -1
- package/dist/commands/pricing.d.ts +0 -15
- package/dist/commands/pricing.d.ts.map +0 -1
- package/dist/commands/pricing.js +0 -94
- package/dist/commands/pricing.js.map +0 -1
- package/dist/config/ai-providers.json +0 -102
- package/dist/config/pricing.json +0 -55
- package/dist/utils/aiClientFactory.d.ts +0 -93
- package/dist/utils/aiClientFactory.d.ts.map +0 -1
- package/dist/utils/aiClientFactory.js +0 -290
- package/dist/utils/aiClientFactory.js.map +0 -1
- package/dist/utils/aiClientRouter.d.ts +0 -121
- package/dist/utils/aiClientRouter.d.ts.map +0 -1
- package/dist/utils/aiClientRouter.js +0 -401
- package/dist/utils/aiClientRouter.js.map +0 -1
- package/dist/utils/apiKeyManager.d.ts +0 -137
- package/dist/utils/apiKeyManager.d.ts.map +0 -1
- package/dist/utils/apiKeyManager.js +0 -479
- package/dist/utils/apiKeyManager.js.map +0 -1
- package/dist/utils/claudeClient.d.ts +0 -28
- package/dist/utils/claudeClient.d.ts.map +0 -1
- package/dist/utils/claudeClient.js +0 -233
- package/dist/utils/claudeClient.js.map +0 -1
- package/dist/utils/geminiClient.d.ts +0 -61
- package/dist/utils/geminiClient.d.ts.map +0 -1
- package/dist/utils/geminiClient.js +0 -173
- package/dist/utils/geminiClient.js.map +0 -1
- package/dist/utils/githubModelsClient.d.ts +0 -27
- package/dist/utils/githubModelsClient.d.ts.map +0 -1
- package/dist/utils/githubModelsClient.js +0 -332
- package/dist/utils/githubModelsClient.js.map +0 -1
- package/dist/utils/huggingFaceClient.d.ts +0 -44
- package/dist/utils/huggingFaceClient.d.ts.map +0 -1
- package/dist/utils/huggingFaceClient.js +0 -169
- package/dist/utils/huggingFaceClient.js.map +0 -1
- package/dist/utils/openaiClient.d.ts +0 -24
- package/dist/utils/openaiClient.d.ts.map +0 -1
- package/dist/utils/openaiClient.js +0 -204
- package/dist/utils/openaiClient.js.map +0 -1
- package/dist/utils/qwenClient.d.ts +0 -22
- package/dist/utils/qwenClient.d.ts.map +0 -1
- package/dist/utils/qwenClient.js +0 -185
- package/dist/utils/qwenClient.js.map +0 -1
- package/dist/utils/streamingHandler.d.ts +0 -98
- package/dist/utils/streamingHandler.d.ts.map +0 -1
- package/dist/utils/streamingHandler.js +0 -259
- package/dist/utils/streamingHandler.js.map +0 -1
- package/dist/utils/xaiClient.d.ts +0 -19
- package/dist/utils/xaiClient.d.ts.map +0 -1
- package/dist/utils/xaiClient.js +0 -135
- package/dist/utils/xaiClient.js.map +0 -1
package/dist/utils/mcpTools.js
CHANGED
|
@@ -49,35 +49,40 @@ const path = __importStar(require("path"));
|
|
|
49
49
|
/**
|
|
50
50
|
* Analyze React component structure and dependencies
|
|
51
51
|
*/
|
|
52
|
-
exports.analyzeComponentTool = (0, claude_agent_sdk_1.tool)(
|
|
53
|
-
filePath: zod_1.z.string().describe(
|
|
54
|
-
checkTypes: zod_1.z
|
|
55
|
-
|
|
52
|
+
exports.analyzeComponentTool = (0, claude_agent_sdk_1.tool)("AnalyzeComponent", "Analyzes a React component file structure, dependencies, props, and provides insights", {
|
|
53
|
+
filePath: zod_1.z.string().describe("Path to the component file"),
|
|
54
|
+
checkTypes: zod_1.z
|
|
55
|
+
.boolean()
|
|
56
|
+
.optional()
|
|
57
|
+
.describe("Whether to analyze TypeScript types"),
|
|
58
|
+
checkImports: zod_1.z.boolean().optional().describe("Whether to analyze imports"),
|
|
56
59
|
}, async (args) => {
|
|
57
60
|
try {
|
|
58
61
|
const { filePath, checkTypes = true, checkImports = true } = args;
|
|
59
|
-
if (!await fs.pathExists(filePath)) {
|
|
62
|
+
if (!(await fs.pathExists(filePath))) {
|
|
60
63
|
return {
|
|
61
|
-
content: [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: `Error: File not found at ${filePath}`,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
65
70
|
isError: true,
|
|
66
71
|
};
|
|
67
72
|
}
|
|
68
|
-
const content = await fs.readFile(filePath,
|
|
73
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
69
74
|
const analysis = [];
|
|
70
75
|
analysis.push(`# Component Analysis: ${path.basename(filePath)}\n`);
|
|
71
76
|
analysis.push(`**File:** ${filePath}`);
|
|
72
|
-
analysis.push(`**Lines:** ${content.split(
|
|
77
|
+
analysis.push(`**Lines:** ${content.split("\n").length}\n`);
|
|
73
78
|
// Check for React component
|
|
74
79
|
const hasReactImport = /import.*React.*from\s+['"]react['"]/.test(content);
|
|
75
80
|
const isComponent = /export\s+(default\s+)?(?:function|const|class)\s+\w+/.test(content);
|
|
76
|
-
analysis.push(`**Is React Component:** ${isComponent ?
|
|
81
|
+
analysis.push(`**Is React Component:** ${isComponent ? "Yes" : "No"}`);
|
|
77
82
|
if (checkImports) {
|
|
78
83
|
const imports = content.match(/import\s+.+\s+from\s+['"].+['"]/g) || [];
|
|
79
84
|
analysis.push(`\n## Imports (${imports.length})`);
|
|
80
|
-
imports.slice(0, 10).forEach(imp => analysis.push(`- ${imp}`));
|
|
85
|
+
imports.slice(0, 10).forEach((imp) => analysis.push(`- ${imp}`));
|
|
81
86
|
if (imports.length > 10) {
|
|
82
87
|
analysis.push(`... and ${imports.length - 10} more`);
|
|
83
88
|
}
|
|
@@ -85,7 +90,7 @@ exports.analyzeComponentTool = (0, claude_agent_sdk_1.tool)('AnalyzeComponent',
|
|
|
85
90
|
if (checkTypes) {
|
|
86
91
|
const interfaces = content.match(/(?:interface|type)\s+\w+/g) || [];
|
|
87
92
|
analysis.push(`\n## Type Definitions (${interfaces.length})`);
|
|
88
|
-
interfaces.forEach(type => analysis.push(`- ${type}`));
|
|
93
|
+
interfaces.forEach((type) => analysis.push(`- ${type}`));
|
|
89
94
|
}
|
|
90
95
|
// Check for props
|
|
91
96
|
const propsMatch = content.match(/(?:interface|type)\s+(\w+Props)/);
|
|
@@ -97,21 +102,25 @@ exports.analyzeComponentTool = (0, claude_agent_sdk_1.tool)('AnalyzeComponent',
|
|
|
97
102
|
const uniqueHooks = [...new Set(hooks)];
|
|
98
103
|
if (uniqueHooks.length > 0) {
|
|
99
104
|
analysis.push(`\n## Hooks Used (${uniqueHooks.length})`);
|
|
100
|
-
uniqueHooks.forEach(hook => analysis.push(`- ${hook}`));
|
|
105
|
+
uniqueHooks.forEach((hook) => analysis.push(`- ${hook}`));
|
|
101
106
|
}
|
|
102
107
|
return {
|
|
103
|
-
content: [
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
content: [
|
|
109
|
+
{
|
|
110
|
+
type: "text",
|
|
111
|
+
text: analysis.join("\n"),
|
|
112
|
+
},
|
|
113
|
+
],
|
|
107
114
|
};
|
|
108
115
|
}
|
|
109
116
|
catch (error) {
|
|
110
117
|
return {
|
|
111
|
-
content: [
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
118
|
+
content: [
|
|
119
|
+
{
|
|
120
|
+
type: "text",
|
|
121
|
+
text: `Error analyzing component: ${error.message}`,
|
|
122
|
+
},
|
|
123
|
+
],
|
|
115
124
|
isError: true,
|
|
116
125
|
};
|
|
117
126
|
}
|
|
@@ -119,31 +128,38 @@ exports.analyzeComponentTool = (0, claude_agent_sdk_1.tool)('AnalyzeComponent',
|
|
|
119
128
|
/**
|
|
120
129
|
* Validate PRD structure and completeness
|
|
121
130
|
*/
|
|
122
|
-
exports.validatePRDTool = (0, claude_agent_sdk_1.tool)(
|
|
123
|
-
prdPath: zod_1.z
|
|
131
|
+
exports.validatePRDTool = (0, claude_agent_sdk_1.tool)("ValidatePRD", "Validates a Product Requirements Document (PRD) for completeness and structure", {
|
|
132
|
+
prdPath: zod_1.z
|
|
133
|
+
.string()
|
|
134
|
+
.describe("Path to the PRD file (usually .mycontext/01-prd.md)"),
|
|
124
135
|
}, async (args) => {
|
|
125
136
|
try {
|
|
126
137
|
const { prdPath } = args;
|
|
127
|
-
if (!await fs.pathExists(prdPath)) {
|
|
138
|
+
if (!(await fs.pathExists(prdPath))) {
|
|
128
139
|
return {
|
|
129
|
-
content: [
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
content: [
|
|
141
|
+
{
|
|
142
|
+
type: "text",
|
|
143
|
+
text: `Error: PRD file not found at ${prdPath}`,
|
|
144
|
+
},
|
|
145
|
+
],
|
|
133
146
|
isError: true,
|
|
134
147
|
};
|
|
135
148
|
}
|
|
136
|
-
const content = await fs.readFile(prdPath,
|
|
149
|
+
const content = await fs.readFile(prdPath, "utf-8");
|
|
137
150
|
const issues = [];
|
|
138
151
|
const score = { total: 0, passed: 0 };
|
|
139
152
|
// Check for required sections
|
|
140
153
|
const requiredSections = [
|
|
141
|
-
{ name:
|
|
142
|
-
{ name:
|
|
143
|
-
{ name:
|
|
144
|
-
{
|
|
154
|
+
{ name: "Project Overview", pattern: /#+\s*(?:Project\s+)?Overview/i },
|
|
155
|
+
{ name: "Features", pattern: /#+\s*(?:Key\s+)?Features/i },
|
|
156
|
+
{ name: "User Stories", pattern: /#+\s*User\s+(?:Stories|Flows)/i },
|
|
157
|
+
{
|
|
158
|
+
name: "Technical Stack",
|
|
159
|
+
pattern: /#+\s*(?:Tech|Technical)\s+Stack/i,
|
|
160
|
+
},
|
|
145
161
|
];
|
|
146
|
-
requiredSections.forEach(section => {
|
|
162
|
+
requiredSections.forEach((section) => {
|
|
147
163
|
score.total++;
|
|
148
164
|
if (section.pattern.test(content)) {
|
|
149
165
|
score.passed++;
|
|
@@ -155,7 +171,7 @@ exports.validatePRDTool = (0, claude_agent_sdk_1.tool)('ValidatePRD', 'Validates
|
|
|
155
171
|
// Check content length
|
|
156
172
|
score.total++;
|
|
157
173
|
if (content.length < 500) {
|
|
158
|
-
issues.push(
|
|
174
|
+
issues.push("❌ PRD is too short (< 500 characters)");
|
|
159
175
|
}
|
|
160
176
|
else {
|
|
161
177
|
score.passed++;
|
|
@@ -166,7 +182,7 @@ exports.validatePRDTool = (0, claude_agent_sdk_1.tool)('ValidatePRD', 'Validates
|
|
|
166
182
|
score.passed++;
|
|
167
183
|
}
|
|
168
184
|
else {
|
|
169
|
-
issues.push(
|
|
185
|
+
issues.push("⚠️ No code examples or technical specifications found");
|
|
170
186
|
}
|
|
171
187
|
const percentage = Math.round((score.passed / score.total) * 100);
|
|
172
188
|
const result = [];
|
|
@@ -175,36 +191,40 @@ exports.validatePRDTool = (0, claude_agent_sdk_1.tool)('ValidatePRD', 'Validates
|
|
|
175
191
|
result.push(`**Score:** ${score.passed}/${score.total} (${percentage}%)\n`);
|
|
176
192
|
if (issues.length > 0) {
|
|
177
193
|
result.push(`## Issues Found (${issues.length})\n`);
|
|
178
|
-
issues.forEach(issue => result.push(issue));
|
|
194
|
+
issues.forEach((issue) => result.push(issue));
|
|
179
195
|
}
|
|
180
196
|
else {
|
|
181
197
|
result.push(`✅ PRD is complete and well-structured!`);
|
|
182
198
|
}
|
|
183
199
|
result.push(`\n## Recommendations`);
|
|
184
200
|
if (percentage < 60) {
|
|
185
|
-
result.push(
|
|
186
|
-
result.push(
|
|
201
|
+
result.push("- PRD needs significant improvement");
|
|
202
|
+
result.push("- Add missing sections and more detail");
|
|
187
203
|
}
|
|
188
204
|
else if (percentage < 80) {
|
|
189
|
-
result.push(
|
|
190
|
-
result.push(
|
|
205
|
+
result.push("- PRD is good but could be enhanced");
|
|
206
|
+
result.push("- Consider adding more technical specifications");
|
|
191
207
|
}
|
|
192
208
|
else {
|
|
193
|
-
result.push(
|
|
209
|
+
result.push("- PRD is excellent! Ready for implementation");
|
|
194
210
|
}
|
|
195
211
|
return {
|
|
196
|
-
content: [
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
212
|
+
content: [
|
|
213
|
+
{
|
|
214
|
+
type: "text",
|
|
215
|
+
text: result.join("\n"),
|
|
216
|
+
},
|
|
217
|
+
],
|
|
200
218
|
};
|
|
201
219
|
}
|
|
202
220
|
catch (error) {
|
|
203
221
|
return {
|
|
204
|
-
content: [
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
222
|
+
content: [
|
|
223
|
+
{
|
|
224
|
+
type: "text",
|
|
225
|
+
text: `Error validating PRD: ${error.message}`,
|
|
226
|
+
},
|
|
227
|
+
],
|
|
208
228
|
isError: true,
|
|
209
229
|
};
|
|
210
230
|
}
|
|
@@ -212,35 +232,42 @@ exports.validatePRDTool = (0, claude_agent_sdk_1.tool)('ValidatePRD', 'Validates
|
|
|
212
232
|
/**
|
|
213
233
|
* Check TypeScript types in generated code
|
|
214
234
|
*/
|
|
215
|
-
exports.checkTypesTool = (0, claude_agent_sdk_1.tool)(
|
|
216
|
-
targetPath: zod_1.z.string().describe(
|
|
217
|
-
strict: zod_1.z
|
|
235
|
+
exports.checkTypesTool = (0, claude_agent_sdk_1.tool)("CheckTypes", "Validates TypeScript types in a file or directory", {
|
|
236
|
+
targetPath: zod_1.z.string().describe("Path to file or directory to check"),
|
|
237
|
+
strict: zod_1.z
|
|
238
|
+
.boolean()
|
|
239
|
+
.optional()
|
|
240
|
+
.describe("Whether to use strict type checking"),
|
|
218
241
|
}, async (args) => {
|
|
219
242
|
try {
|
|
220
243
|
const { targetPath, strict = false } = args;
|
|
221
|
-
if (!await fs.pathExists(targetPath)) {
|
|
244
|
+
if (!(await fs.pathExists(targetPath))) {
|
|
222
245
|
return {
|
|
223
|
-
content: [
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
246
|
+
content: [
|
|
247
|
+
{
|
|
248
|
+
type: "text",
|
|
249
|
+
text: `Error: Path not found at ${targetPath}`,
|
|
250
|
+
},
|
|
251
|
+
],
|
|
227
252
|
isError: true,
|
|
228
253
|
};
|
|
229
254
|
}
|
|
230
255
|
const result = [];
|
|
231
256
|
result.push(`# Type Check: ${path.basename(targetPath)}\n`);
|
|
232
257
|
// Check if it's a TypeScript file
|
|
233
|
-
const isTypeScript = targetPath.endsWith(
|
|
258
|
+
const isTypeScript = targetPath.endsWith(".ts") || targetPath.endsWith(".tsx");
|
|
234
259
|
if (!isTypeScript) {
|
|
235
|
-
result.push(
|
|
260
|
+
result.push("⚠️ Not a TypeScript file");
|
|
236
261
|
return {
|
|
237
|
-
content: [
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
262
|
+
content: [
|
|
263
|
+
{
|
|
264
|
+
type: "text",
|
|
265
|
+
text: result.join("\n"),
|
|
266
|
+
},
|
|
267
|
+
],
|
|
241
268
|
};
|
|
242
269
|
}
|
|
243
|
-
const content = await fs.readFile(targetPath,
|
|
270
|
+
const content = await fs.readFile(targetPath, "utf-8");
|
|
244
271
|
// Check for common issues
|
|
245
272
|
const issues = [];
|
|
246
273
|
// Check for 'any' types (if strict)
|
|
@@ -253,33 +280,37 @@ exports.checkTypesTool = (0, claude_agent_sdk_1.tool)('CheckTypes', 'Validates T
|
|
|
253
280
|
// Check for proper type exports
|
|
254
281
|
const hasTypeExport = /export\s+(?:type|interface)/.test(content);
|
|
255
282
|
if (hasTypeExport) {
|
|
256
|
-
result.push(
|
|
283
|
+
result.push("✅ Contains exported types/interfaces");
|
|
257
284
|
}
|
|
258
285
|
// Check for proper prop types
|
|
259
286
|
const hasPropTypes = /\w+Props\s*[={]/.test(content);
|
|
260
287
|
if (hasPropTypes) {
|
|
261
|
-
result.push(
|
|
288
|
+
result.push("✅ Defines prop types");
|
|
262
289
|
}
|
|
263
290
|
if (issues.length > 0) {
|
|
264
|
-
result.push(
|
|
265
|
-
issues.forEach(issue => result.push(issue));
|
|
291
|
+
result.push("\n## Issues Found:");
|
|
292
|
+
issues.forEach((issue) => result.push(issue));
|
|
266
293
|
}
|
|
267
294
|
else {
|
|
268
|
-
result.push(
|
|
295
|
+
result.push("\n✅ No type issues found");
|
|
269
296
|
}
|
|
270
297
|
return {
|
|
271
|
-
content: [
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
298
|
+
content: [
|
|
299
|
+
{
|
|
300
|
+
type: "text",
|
|
301
|
+
text: result.join("\n"),
|
|
302
|
+
},
|
|
303
|
+
],
|
|
275
304
|
};
|
|
276
305
|
}
|
|
277
306
|
catch (error) {
|
|
278
307
|
return {
|
|
279
|
-
content: [
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
308
|
+
content: [
|
|
309
|
+
{
|
|
310
|
+
type: "text",
|
|
311
|
+
text: `Error checking types: ${error.message}`,
|
|
312
|
+
},
|
|
313
|
+
],
|
|
283
314
|
isError: true,
|
|
284
315
|
};
|
|
285
316
|
}
|
|
@@ -287,22 +318,27 @@ exports.checkTypesTool = (0, claude_agent_sdk_1.tool)('CheckTypes', 'Validates T
|
|
|
287
318
|
/**
|
|
288
319
|
* Generate component documentation
|
|
289
320
|
*/
|
|
290
|
-
exports.generateDocsTool = (0, claude_agent_sdk_1.tool)(
|
|
291
|
-
componentPath: zod_1.z.string().describe(
|
|
292
|
-
outputPath: zod_1.z
|
|
321
|
+
exports.generateDocsTool = (0, claude_agent_sdk_1.tool)("GenerateDocs", "Generates documentation for a React component", {
|
|
322
|
+
componentPath: zod_1.z.string().describe("Path to the component file"),
|
|
323
|
+
outputPath: zod_1.z
|
|
324
|
+
.string()
|
|
325
|
+
.optional()
|
|
326
|
+
.describe("Where to save the documentation"),
|
|
293
327
|
}, async (args) => {
|
|
294
328
|
try {
|
|
295
329
|
const { componentPath, outputPath } = args;
|
|
296
|
-
if (!await fs.pathExists(componentPath)) {
|
|
330
|
+
if (!(await fs.pathExists(componentPath))) {
|
|
297
331
|
return {
|
|
298
|
-
content: [
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
332
|
+
content: [
|
|
333
|
+
{
|
|
334
|
+
type: "text",
|
|
335
|
+
text: `Error: Component not found at ${componentPath}`,
|
|
336
|
+
},
|
|
337
|
+
],
|
|
302
338
|
isError: true,
|
|
303
339
|
};
|
|
304
340
|
}
|
|
305
|
-
const content = await fs.readFile(componentPath,
|
|
341
|
+
const content = await fs.readFile(componentPath, "utf-8");
|
|
306
342
|
const componentName = path.basename(componentPath, path.extname(componentPath));
|
|
307
343
|
const docs = [];
|
|
308
344
|
docs.push(`# ${componentName}\n`);
|
|
@@ -311,55 +347,59 @@ exports.generateDocsTool = (0, claude_agent_sdk_1.tool)('GenerateDocs', 'Generat
|
|
|
311
347
|
const descMatch = content.match(/\/\*\*\s*\n\s*\*\s*(.+)\n/);
|
|
312
348
|
if (descMatch) {
|
|
313
349
|
docs.push(`## Description\n`);
|
|
314
|
-
docs.push(descMatch[1]);
|
|
315
|
-
docs.push(
|
|
350
|
+
docs.push(descMatch[1] || "");
|
|
351
|
+
docs.push("");
|
|
316
352
|
}
|
|
317
353
|
// Extract props interface
|
|
318
354
|
const propsMatch = content.match(/(?:interface|type)\s+(\w+Props)\s*=?\s*{([^}]+)}/);
|
|
319
355
|
if (propsMatch) {
|
|
320
356
|
docs.push(`## Props\n`);
|
|
321
|
-
docs.push(
|
|
357
|
+
docs.push("```typescript");
|
|
322
358
|
docs.push(propsMatch[0]);
|
|
323
|
-
docs.push(
|
|
359
|
+
docs.push("```\n");
|
|
324
360
|
}
|
|
325
361
|
// Extract imports
|
|
326
362
|
const imports = content.match(/import\s+.+\s+from\s+['"].+['"]/g) || [];
|
|
327
363
|
if (imports.length > 0) {
|
|
328
364
|
docs.push(`## Dependencies\n`);
|
|
329
|
-
imports.slice(0, 5).forEach(imp => {
|
|
365
|
+
imports.slice(0, 5).forEach((imp) => {
|
|
330
366
|
const match = imp.match(/from\s+['"](.+)['"]/);
|
|
331
367
|
if (match) {
|
|
332
368
|
docs.push(`- \`${match[1]}\``);
|
|
333
369
|
}
|
|
334
370
|
});
|
|
335
|
-
docs.push(
|
|
371
|
+
docs.push("");
|
|
336
372
|
}
|
|
337
373
|
// Usage example
|
|
338
374
|
docs.push(`## Usage\n`);
|
|
339
|
-
docs.push(
|
|
375
|
+
docs.push("```tsx");
|
|
340
376
|
docs.push(`import ${componentName} from './${componentName}';`);
|
|
341
|
-
docs.push(
|
|
377
|
+
docs.push("");
|
|
342
378
|
docs.push(`<${componentName} />`);
|
|
343
|
-
docs.push(
|
|
344
|
-
const docsContent = docs.join(
|
|
379
|
+
docs.push("```");
|
|
380
|
+
const docsContent = docs.join("\n");
|
|
345
381
|
// Save if output path provided
|
|
346
382
|
if (outputPath) {
|
|
347
383
|
await fs.ensureDir(path.dirname(outputPath));
|
|
348
|
-
await fs.writeFile(outputPath, docsContent,
|
|
384
|
+
await fs.writeFile(outputPath, docsContent, "utf-8");
|
|
349
385
|
}
|
|
350
386
|
return {
|
|
351
|
-
content: [
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
387
|
+
content: [
|
|
388
|
+
{
|
|
389
|
+
type: "text",
|
|
390
|
+
text: `Documentation generated successfully!\n\n${docsContent}`,
|
|
391
|
+
},
|
|
392
|
+
],
|
|
355
393
|
};
|
|
356
394
|
}
|
|
357
395
|
catch (error) {
|
|
358
396
|
return {
|
|
359
|
-
content: [
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
397
|
+
content: [
|
|
398
|
+
{
|
|
399
|
+
type: "text",
|
|
400
|
+
text: `Error generating docs: ${error.message}`,
|
|
401
|
+
},
|
|
402
|
+
],
|
|
363
403
|
isError: true,
|
|
364
404
|
};
|
|
365
405
|
}
|
|
@@ -367,9 +407,12 @@ exports.generateDocsTool = (0, claude_agent_sdk_1.tool)('GenerateDocs', 'Generat
|
|
|
367
407
|
/**
|
|
368
408
|
* Detect existing validated components in the project
|
|
369
409
|
*/
|
|
370
|
-
exports.detectExistingComponentsTool = (0, claude_agent_sdk_1.tool)(
|
|
371
|
-
projectPath: zod_1.z.string().describe(
|
|
372
|
-
includeValidation: zod_1.z
|
|
410
|
+
exports.detectExistingComponentsTool = (0, claude_agent_sdk_1.tool)("DetectExistingComponents", "Detects and analyzes existing validated components in the project for component-first workflow", {
|
|
411
|
+
projectPath: zod_1.z.string().describe("Path to the project directory"),
|
|
412
|
+
includeValidation: zod_1.z
|
|
413
|
+
.boolean()
|
|
414
|
+
.optional()
|
|
415
|
+
.describe("Check validation status from progress files"),
|
|
373
416
|
}, async (args) => {
|
|
374
417
|
try {
|
|
375
418
|
const { projectPath, includeValidation = true } = args;
|
|
@@ -379,13 +422,13 @@ exports.detectExistingComponentsTool = (0, claude_agent_sdk_1.tool)('DetectExist
|
|
|
379
422
|
componentGroups: [],
|
|
380
423
|
validatedComponents: [],
|
|
381
424
|
componentList: null,
|
|
382
|
-
recommendation:
|
|
383
|
-
summary:
|
|
425
|
+
recommendation: "",
|
|
426
|
+
summary: "",
|
|
384
427
|
};
|
|
385
428
|
// Check for component list
|
|
386
429
|
const componentListPaths = [
|
|
387
|
-
path.join(projectPath,
|
|
388
|
-
path.join(projectPath,
|
|
430
|
+
path.join(projectPath, ".mycontext/04-component-list.json"),
|
|
431
|
+
path.join(projectPath, ".mycontext/component-list.json"),
|
|
389
432
|
];
|
|
390
433
|
for (const listPath of componentListPaths) {
|
|
391
434
|
if (await fs.pathExists(listPath)) {
|
|
@@ -395,7 +438,7 @@ exports.detectExistingComponentsTool = (0, claude_agent_sdk_1.tool)('DetectExist
|
|
|
395
438
|
}
|
|
396
439
|
}
|
|
397
440
|
// Check for components directory
|
|
398
|
-
const componentsDir = path.join(projectPath,
|
|
441
|
+
const componentsDir = path.join(projectPath, "components");
|
|
399
442
|
if (await fs.pathExists(componentsDir)) {
|
|
400
443
|
result.hasComponents = true;
|
|
401
444
|
// Find all component groups
|
|
@@ -409,25 +452,25 @@ exports.detectExistingComponentsTool = (0, claude_agent_sdk_1.tool)('DetectExist
|
|
|
409
452
|
}
|
|
410
453
|
// If validation requested, check progress files
|
|
411
454
|
if (includeValidation) {
|
|
412
|
-
const progressDir = path.join(projectPath,
|
|
455
|
+
const progressDir = path.join(projectPath, ".mycontext/progress/07-components");
|
|
413
456
|
if (await fs.pathExists(progressDir)) {
|
|
414
457
|
const progressFiles = await fs.readdir(progressDir);
|
|
415
458
|
for (const file of progressFiles) {
|
|
416
|
-
if (file.endsWith(
|
|
459
|
+
if (file.endsWith(".json")) {
|
|
417
460
|
try {
|
|
418
461
|
const progress = await fs.readJson(path.join(progressDir, file));
|
|
419
|
-
if (progress.status ===
|
|
462
|
+
if (progress.status === "completed") {
|
|
420
463
|
result.validatedComponents.push({
|
|
421
|
-
name: progress.componentName || path.basename(file,
|
|
422
|
-
group: progress.group ||
|
|
423
|
-
path: progress.filePath ||
|
|
464
|
+
name: progress.componentName || path.basename(file, ".json"),
|
|
465
|
+
group: progress.group || "unknown",
|
|
466
|
+
path: progress.filePath || "",
|
|
424
467
|
validated: true,
|
|
425
468
|
validationResults: {
|
|
426
469
|
typescript: progress.validations?.typescript || false,
|
|
427
470
|
eslint: progress.validations?.eslint || false,
|
|
428
471
|
build: progress.validations?.build || false,
|
|
429
472
|
tests: progress.validations?.tests || false,
|
|
430
|
-
}
|
|
473
|
+
},
|
|
431
474
|
});
|
|
432
475
|
}
|
|
433
476
|
}
|
|
@@ -442,19 +485,19 @@ exports.detectExistingComponentsTool = (0, claude_agent_sdk_1.tool)('DetectExist
|
|
|
442
485
|
// AI recommendation based on findings
|
|
443
486
|
const validatedCount = result.validatedComponents.length;
|
|
444
487
|
if (validatedCount >= 3) {
|
|
445
|
-
result.recommendation =
|
|
488
|
+
result.recommendation = "REUSE_COMPONENTS";
|
|
446
489
|
result.summary = `Found ${validatedCount} validated components across ${result.componentGroups.length} groups. Recommend REUSING existing components and generating scaffolding only.`;
|
|
447
490
|
}
|
|
448
491
|
else if (result.hasContextFiles && result.hasComponents) {
|
|
449
|
-
result.recommendation =
|
|
492
|
+
result.recommendation = "PARTIAL_REUSE";
|
|
450
493
|
result.summary = `Found ${validatedCount} validated components. Consider mixing existing components with new generation.`;
|
|
451
494
|
}
|
|
452
495
|
else if (result.hasContextFiles) {
|
|
453
|
-
result.recommendation =
|
|
496
|
+
result.recommendation = "GENERATE_COMPONENTS";
|
|
454
497
|
result.summary = `Found context files but no validated components. Generate components from component list.`;
|
|
455
498
|
}
|
|
456
499
|
else {
|
|
457
|
-
result.recommendation =
|
|
500
|
+
result.recommendation = "GENERATE_ALL";
|
|
458
501
|
result.summary = `No components or context files found. Start fresh with full generation workflow.`;
|
|
459
502
|
}
|
|
460
503
|
const output = [];
|
|
@@ -463,54 +506,58 @@ exports.detectExistingComponentsTool = (0, claude_agent_sdk_1.tool)('DetectExist
|
|
|
463
506
|
output.push(`**Recommendation:** ${result.recommendation}\n`);
|
|
464
507
|
output.push(`## Summary`);
|
|
465
508
|
output.push(result.summary);
|
|
466
|
-
output.push(
|
|
509
|
+
output.push("");
|
|
467
510
|
output.push(`## Findings`);
|
|
468
|
-
output.push(`- Has Components: ${result.hasComponents ?
|
|
469
|
-
output.push(`- Has Context Files: ${result.hasContextFiles ?
|
|
511
|
+
output.push(`- Has Components: ${result.hasComponents ? "✅" : "❌"}`);
|
|
512
|
+
output.push(`- Has Context Files: ${result.hasContextFiles ? "✅" : "❌"}`);
|
|
470
513
|
output.push(`- Component Groups: ${result.componentGroups.length}`);
|
|
471
514
|
output.push(`- Validated Components: ${result.validatedComponents.length}\n`);
|
|
472
515
|
if (result.validatedComponents.length > 0) {
|
|
473
516
|
output.push(`## Validated Components (${result.validatedComponents.length})\n`);
|
|
474
|
-
result.validatedComponents.forEach(comp => {
|
|
517
|
+
result.validatedComponents.forEach((comp) => {
|
|
475
518
|
output.push(`### ${comp.name} (${comp.group})`);
|
|
476
|
-
output.push(`- TypeScript: ${comp.validationResults.typescript ?
|
|
477
|
-
output.push(`- ESLint: ${comp.validationResults.eslint ?
|
|
478
|
-
output.push(`- Build: ${comp.validationResults.build ?
|
|
479
|
-
output.push(`- Tests: ${comp.validationResults.tests ?
|
|
480
|
-
output.push(
|
|
519
|
+
output.push(`- TypeScript: ${comp.validationResults.typescript ? "✅" : "❌"}`);
|
|
520
|
+
output.push(`- ESLint: ${comp.validationResults.eslint ? "✅" : "❌"}`);
|
|
521
|
+
output.push(`- Build: ${comp.validationResults.build ? "✅" : "❌"}`);
|
|
522
|
+
output.push(`- Tests: ${comp.validationResults.tests ? "✅" : "❌"}`);
|
|
523
|
+
output.push("");
|
|
481
524
|
});
|
|
482
525
|
}
|
|
483
526
|
if (result.componentGroups.length > 0) {
|
|
484
527
|
output.push(`## Component Groups (${result.componentGroups.length})\n`);
|
|
485
|
-
result.componentGroups.forEach(group => output.push(`- ${group}`));
|
|
486
|
-
output.push(
|
|
528
|
+
result.componentGroups.forEach((group) => output.push(`- ${group}`));
|
|
529
|
+
output.push("");
|
|
487
530
|
}
|
|
488
531
|
output.push(`## Next Steps`);
|
|
489
|
-
if (result.recommendation ===
|
|
490
|
-
output.push(
|
|
491
|
-
output.push(
|
|
492
|
-
output.push(
|
|
532
|
+
if (result.recommendation === "REUSE_COMPONENTS") {
|
|
533
|
+
output.push("1. Use MapComponentsToRoutes to create route mappings");
|
|
534
|
+
output.push("2. Use GenerateScaffolding to create routes, actions, and hooks");
|
|
535
|
+
output.push("3. Skip component generation - reuse existing validated components");
|
|
493
536
|
}
|
|
494
|
-
else if (result.recommendation ===
|
|
495
|
-
output.push(
|
|
496
|
-
output.push(
|
|
497
|
-
output.push(
|
|
498
|
-
output.push(
|
|
537
|
+
else if (result.recommendation === "GENERATE_ALL") {
|
|
538
|
+
output.push("1. Generate context files (PRD, types, branding)");
|
|
539
|
+
output.push("2. Generate component list");
|
|
540
|
+
output.push("3. Generate and validate all components");
|
|
541
|
+
output.push("4. Generate scaffolding (routes, actions, hooks)");
|
|
499
542
|
}
|
|
500
543
|
return {
|
|
501
|
-
content: [
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
544
|
+
content: [
|
|
545
|
+
{
|
|
546
|
+
type: "text",
|
|
547
|
+
text: output.join("\n"),
|
|
548
|
+
},
|
|
549
|
+
],
|
|
505
550
|
metadata: result,
|
|
506
551
|
};
|
|
507
552
|
}
|
|
508
553
|
catch (error) {
|
|
509
554
|
return {
|
|
510
|
-
content: [
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
555
|
+
content: [
|
|
556
|
+
{
|
|
557
|
+
type: "text",
|
|
558
|
+
text: `Error detecting components: ${error.message}`,
|
|
559
|
+
},
|
|
560
|
+
],
|
|
514
561
|
isError: true,
|
|
515
562
|
};
|
|
516
563
|
}
|
|
@@ -518,87 +565,94 @@ exports.detectExistingComponentsTool = (0, claude_agent_sdk_1.tool)('DetectExist
|
|
|
518
565
|
/**
|
|
519
566
|
* Map components to routes intelligently
|
|
520
567
|
*/
|
|
521
|
-
exports.mapComponentsToRoutesTool = (0, claude_agent_sdk_1.tool)(
|
|
522
|
-
components: zod_1.z
|
|
568
|
+
exports.mapComponentsToRoutesTool = (0, claude_agent_sdk_1.tool)("MapComponentsToRoutes", "Creates intelligent mapping between existing components and Next.js routes based on component names and PRD context", {
|
|
569
|
+
components: zod_1.z
|
|
570
|
+
.array(zod_1.z.object({
|
|
523
571
|
name: zod_1.z.string(),
|
|
524
572
|
group: zod_1.z.string(),
|
|
525
573
|
path: zod_1.z.string(),
|
|
526
|
-
}))
|
|
527
|
-
|
|
528
|
-
|
|
574
|
+
}))
|
|
575
|
+
.describe("List of components to map"),
|
|
576
|
+
prdContext: zod_1.z
|
|
577
|
+
.string()
|
|
578
|
+
.optional()
|
|
579
|
+
.describe("PRD context for understanding app structure"),
|
|
580
|
+
architectureType: zod_1.z
|
|
581
|
+
.enum(["nextjs-app-router", "nextjs-pages", "react-spa"])
|
|
582
|
+
.describe("Target architecture"),
|
|
529
583
|
}, async (args) => {
|
|
530
584
|
try {
|
|
531
585
|
const { components, prdContext, architectureType } = args;
|
|
532
|
-
const componentRouteMap = components.map(comp => {
|
|
586
|
+
const componentRouteMap = components.map((comp) => {
|
|
533
587
|
// Intelligent routing logic based on component name/group
|
|
534
588
|
const name = comp.name;
|
|
535
589
|
const group = comp.group.toLowerCase();
|
|
536
590
|
// Determine if this should be a page component
|
|
537
|
-
const isPageComponent = name.toLowerCase().includes(
|
|
538
|
-
name.toLowerCase().includes(
|
|
539
|
-
name.toLowerCase().includes(
|
|
540
|
-
name.toLowerCase().includes(
|
|
541
|
-
name.toLowerCase().includes(
|
|
542
|
-
name.toLowerCase().includes(
|
|
543
|
-
name.toLowerCase().includes(
|
|
591
|
+
const isPageComponent = name.toLowerCase().includes("page") ||
|
|
592
|
+
name.toLowerCase().includes("view") ||
|
|
593
|
+
name.toLowerCase().includes("screen") ||
|
|
594
|
+
name.toLowerCase().includes("dashboard") ||
|
|
595
|
+
name.toLowerCase().includes("home") ||
|
|
596
|
+
name.toLowerCase().includes("login") ||
|
|
597
|
+
name.toLowerCase().includes("signup");
|
|
544
598
|
// Determine route based on component name and group
|
|
545
599
|
let routes = [];
|
|
546
|
-
let layout =
|
|
600
|
+
let layout = "DefaultLayout";
|
|
547
601
|
if (isPageComponent) {
|
|
548
602
|
// Extract route from component name
|
|
549
603
|
let routeName = name
|
|
550
|
-
.replace(/Page$/i,
|
|
551
|
-
.replace(/View$/i,
|
|
552
|
-
.replace(/Screen$/i,
|
|
604
|
+
.replace(/Page$/i, "")
|
|
605
|
+
.replace(/View$/i, "")
|
|
606
|
+
.replace(/Screen$/i, "");
|
|
553
607
|
// Convert to kebab-case
|
|
554
608
|
routeName = routeName
|
|
555
|
-
.replace(/([a-z])([A-Z])/g,
|
|
609
|
+
.replace(/([a-z])([A-Z])/g, "$1-$2")
|
|
556
610
|
.toLowerCase();
|
|
557
|
-
routes = [`/${routeName ===
|
|
611
|
+
routes = [`/${routeName === "home" ? "" : routeName}`];
|
|
558
612
|
}
|
|
559
613
|
// Determine layout based on group
|
|
560
|
-
if (group ===
|
|
561
|
-
layout =
|
|
614
|
+
if (group === "authentication" || group === "auth") {
|
|
615
|
+
layout = "AuthLayout";
|
|
562
616
|
}
|
|
563
|
-
else if (group ===
|
|
564
|
-
layout =
|
|
617
|
+
else if (group === "forms" || group === "form") {
|
|
618
|
+
layout = "FormLayout";
|
|
565
619
|
}
|
|
566
|
-
else if (group ===
|
|
567
|
-
layout =
|
|
620
|
+
else if (group === "admin" || group === "dashboard") {
|
|
621
|
+
layout = "DashboardLayout";
|
|
568
622
|
}
|
|
569
623
|
// Determine actions based on component type
|
|
570
624
|
const actions = [];
|
|
571
|
-
if (name.toLowerCase().includes(
|
|
625
|
+
if (name.toLowerCase().includes("form")) {
|
|
572
626
|
actions.push(`handle${name}Submit`);
|
|
573
627
|
actions.push(`validate${name}Data`);
|
|
574
628
|
}
|
|
575
|
-
if (name.toLowerCase().includes(
|
|
576
|
-
actions.push(
|
|
629
|
+
if (name.toLowerCase().includes("login")) {
|
|
630
|
+
actions.push("authenticateUser", "validateCredentials");
|
|
577
631
|
}
|
|
578
|
-
if (name.toLowerCase().includes(
|
|
579
|
-
actions.push(
|
|
632
|
+
if (name.toLowerCase().includes("signup")) {
|
|
633
|
+
actions.push("createUser", "sendVerificationEmail");
|
|
580
634
|
}
|
|
581
635
|
// Determine hooks
|
|
582
636
|
const hooks = [];
|
|
583
|
-
if (name.toLowerCase().includes(
|
|
584
|
-
hooks.push(
|
|
637
|
+
if (name.toLowerCase().includes("form")) {
|
|
638
|
+
hooks.push("useForm");
|
|
585
639
|
}
|
|
586
|
-
if (group ===
|
|
587
|
-
hooks.push(
|
|
640
|
+
if (group === "authentication" || group === "auth") {
|
|
641
|
+
hooks.push("useAuth");
|
|
588
642
|
}
|
|
589
643
|
return {
|
|
590
644
|
component: comp.name,
|
|
591
645
|
group: comp.group,
|
|
592
646
|
componentPath: comp.path,
|
|
593
|
-
type: isPageComponent ?
|
|
647
|
+
type: isPageComponent ? "page" : "component",
|
|
594
648
|
routes: routes,
|
|
595
649
|
layout: layout,
|
|
596
650
|
actions: actions,
|
|
597
651
|
hooks: hooks,
|
|
598
652
|
};
|
|
599
653
|
});
|
|
600
|
-
const pageCount = componentRouteMap.filter(m => m.type ===
|
|
601
|
-
const componentCount = componentRouteMap.filter(m => m.type ===
|
|
654
|
+
const pageCount = componentRouteMap.filter((m) => m.type === "page").length;
|
|
655
|
+
const componentCount = componentRouteMap.filter((m) => m.type === "component").length;
|
|
602
656
|
const output = [];
|
|
603
657
|
output.push(`# Component-to-Route Mapping\n`);
|
|
604
658
|
output.push(`**Architecture:** ${architectureType}`);
|
|
@@ -606,46 +660,51 @@ exports.mapComponentsToRoutesTool = (0, claude_agent_sdk_1.tool)('MapComponentsT
|
|
|
606
660
|
output.push(`**Page Components:** ${pageCount}`);
|
|
607
661
|
output.push(`**Reusable Components:** ${componentCount}\n`);
|
|
608
662
|
output.push(`## Route Mappings\n`);
|
|
609
|
-
componentRouteMap.forEach(mapping => {
|
|
663
|
+
componentRouteMap.forEach((mapping) => {
|
|
610
664
|
output.push(`### ${mapping.component} (${mapping.type})`);
|
|
611
665
|
output.push(`- **Group:** ${mapping.group}`);
|
|
612
666
|
output.push(`- **Layout:** ${mapping.layout}`);
|
|
613
667
|
if (mapping.routes.length > 0) {
|
|
614
668
|
output.push(`- **Routes:**`);
|
|
615
|
-
mapping.routes.forEach(route => output.push(` - ${route}`));
|
|
669
|
+
mapping.routes.forEach((route) => output.push(` - ${route}`));
|
|
616
670
|
}
|
|
617
671
|
if (mapping.actions.length > 0) {
|
|
618
|
-
output.push(`- **Actions:** ${mapping.actions.join(
|
|
672
|
+
output.push(`- **Actions:** ${mapping.actions.join(", ")}`);
|
|
619
673
|
}
|
|
620
674
|
if (mapping.hooks.length > 0) {
|
|
621
|
-
output.push(`- **Hooks:** ${mapping.hooks.join(
|
|
675
|
+
output.push(`- **Hooks:** ${mapping.hooks.join(", ")}`);
|
|
622
676
|
}
|
|
623
|
-
output.push(
|
|
677
|
+
output.push("");
|
|
624
678
|
});
|
|
625
679
|
output.push(`## Summary`);
|
|
626
680
|
output.push(`- ${pageCount} components will be mapped to routes`);
|
|
627
681
|
output.push(`- ${componentCount} components will be reusable across pages`);
|
|
628
682
|
output.push(`- Total routes to generate: ${componentRouteMap.reduce((acc, m) => acc + m.routes.length, 0)}`);
|
|
629
683
|
return {
|
|
630
|
-
content: [
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
684
|
+
content: [
|
|
685
|
+
{
|
|
686
|
+
type: "text",
|
|
687
|
+
text: output.join("\n"),
|
|
688
|
+
},
|
|
689
|
+
],
|
|
634
690
|
metadata: {
|
|
635
691
|
mappings: componentRouteMap,
|
|
636
692
|
architectureType,
|
|
637
693
|
totalRoutes: componentRouteMap.reduce((acc, m) => acc + m.routes.length, 0),
|
|
638
694
|
totalActions: componentRouteMap.reduce((acc, m) => acc + m.actions.length, 0),
|
|
639
|
-
totalHooks: [...new Set(componentRouteMap.flatMap(m => m.hooks))]
|
|
695
|
+
totalHooks: [...new Set(componentRouteMap.flatMap((m) => m.hooks))]
|
|
696
|
+
.length,
|
|
640
697
|
},
|
|
641
698
|
};
|
|
642
699
|
}
|
|
643
700
|
catch (error) {
|
|
644
701
|
return {
|
|
645
|
-
content: [
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
702
|
+
content: [
|
|
703
|
+
{
|
|
704
|
+
type: "text",
|
|
705
|
+
text: `Error mapping components to routes: ${error.message}`,
|
|
706
|
+
},
|
|
707
|
+
],
|
|
649
708
|
isError: true,
|
|
650
709
|
};
|
|
651
710
|
}
|
|
@@ -653,13 +712,24 @@ exports.mapComponentsToRoutesTool = (0, claude_agent_sdk_1.tool)('MapComponentsT
|
|
|
653
712
|
/**
|
|
654
713
|
* Generate scaffolding for existing components
|
|
655
714
|
*/
|
|
656
|
-
exports.generateScaffoldingTool = (0, claude_agent_sdk_1.tool)(
|
|
657
|
-
componentMappings: zod_1.z
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
715
|
+
exports.generateScaffoldingTool = (0, claude_agent_sdk_1.tool)("GenerateScaffolding", "Generates app scaffolding (routes, actions, hooks, layouts) for existing validated components", {
|
|
716
|
+
componentMappings: zod_1.z
|
|
717
|
+
.any()
|
|
718
|
+
.describe("Component-to-route mappings from MapComponentsToRoutes"),
|
|
719
|
+
projectPath: zod_1.z.string().describe("Project directory path"),
|
|
720
|
+
generateRoutes: zod_1.z
|
|
721
|
+
.boolean()
|
|
722
|
+
.default(true)
|
|
723
|
+
.describe("Generate Next.js routes"),
|
|
724
|
+
generateActions: zod_1.z
|
|
725
|
+
.boolean()
|
|
726
|
+
.default(true)
|
|
727
|
+
.describe("Generate server actions"),
|
|
728
|
+
generateHooks: zod_1.z.boolean().default(true).describe("Generate custom hooks"),
|
|
729
|
+
generateLayouts: zod_1.z
|
|
730
|
+
.boolean()
|
|
731
|
+
.default(true)
|
|
732
|
+
.describe("Generate layout components"),
|
|
663
733
|
}, async (args) => {
|
|
664
734
|
try {
|
|
665
735
|
const { componentMappings, projectPath, generateRoutes = true, generateActions = true, generateHooks = true, generateLayouts = true, } = args;
|
|
@@ -673,9 +743,11 @@ exports.generateScaffoldingTool = (0, claude_agent_sdk_1.tool)('GenerateScaffold
|
|
|
673
743
|
// Generate routes for page components
|
|
674
744
|
if (generateRoutes) {
|
|
675
745
|
for (const mapping of mappings) {
|
|
676
|
-
if (mapping.type ===
|
|
746
|
+
if (mapping.type === "page" &&
|
|
747
|
+
mapping.routes &&
|
|
748
|
+
mapping.routes.length > 0) {
|
|
677
749
|
for (const route of mapping.routes) {
|
|
678
|
-
const routePath = path.join(projectPath,
|
|
750
|
+
const routePath = path.join(projectPath, "app", route, "page.tsx");
|
|
679
751
|
// Generate page that imports and uses the component
|
|
680
752
|
const pageContent = `import { ${mapping.component} } from '@/components/${mapping.group}/${mapping.component}';
|
|
681
753
|
|
|
@@ -702,31 +774,33 @@ export default function Page() {
|
|
|
702
774
|
}
|
|
703
775
|
}
|
|
704
776
|
for (const [group, groupMappings] of actionsByGroup) {
|
|
705
|
-
const actionsPath = path.join(projectPath,
|
|
777
|
+
const actionsPath = path.join(projectPath, "actions", `${group}.ts`);
|
|
706
778
|
const actionContent = [];
|
|
707
779
|
actionContent.push(`'use server';`);
|
|
708
|
-
actionContent.push(
|
|
780
|
+
actionContent.push("");
|
|
709
781
|
actionContent.push(`// Server actions for ${group} components`);
|
|
710
|
-
actionContent.push(
|
|
782
|
+
actionContent.push("");
|
|
711
783
|
for (const mapping of groupMappings) {
|
|
712
784
|
for (const action of mapping.actions) {
|
|
713
785
|
actionContent.push(`export async function ${action}(data: any) {`);
|
|
714
786
|
actionContent.push(` // TODO: Implement ${action}`);
|
|
715
787
|
actionContent.push(` return { success: true };`);
|
|
716
788
|
actionContent.push(`}`);
|
|
717
|
-
actionContent.push(
|
|
789
|
+
actionContent.push("");
|
|
718
790
|
}
|
|
719
791
|
}
|
|
720
792
|
await fs.ensureDir(path.dirname(actionsPath));
|
|
721
|
-
await fs.writeFile(actionsPath, actionContent.join(
|
|
793
|
+
await fs.writeFile(actionsPath, actionContent.join("\n"));
|
|
722
794
|
generated.actions.push(actionsPath);
|
|
723
795
|
}
|
|
724
796
|
}
|
|
725
797
|
// Generate custom hooks
|
|
726
798
|
if (generateHooks) {
|
|
727
|
-
const uniqueHooks = [
|
|
799
|
+
const uniqueHooks = [
|
|
800
|
+
...new Set(mappings.flatMap((m) => m.hooks || [])),
|
|
801
|
+
];
|
|
728
802
|
for (const hook of uniqueHooks) {
|
|
729
|
-
const hookPath = path.join(projectPath,
|
|
803
|
+
const hookPath = path.join(projectPath, "hooks", `${hook}.ts`);
|
|
730
804
|
const hookContent = `import { useState, useEffect } from 'react';
|
|
731
805
|
|
|
732
806
|
export function ${hook}() {
|
|
@@ -749,8 +823,8 @@ export function ${hook}() {
|
|
|
749
823
|
if (generateLayouts) {
|
|
750
824
|
const uniqueLayouts = [...new Set(mappings.map((m) => m.layout))];
|
|
751
825
|
for (const layout of uniqueLayouts) {
|
|
752
|
-
if (layout && layout !==
|
|
753
|
-
const layoutPath = path.join(projectPath,
|
|
826
|
+
if (layout && layout !== "DefaultLayout") {
|
|
827
|
+
const layoutPath = path.join(projectPath, "components", "layouts", `${layout}.tsx`);
|
|
754
828
|
const layoutContent = `import { ReactNode } from 'react';
|
|
755
829
|
|
|
756
830
|
interface ${layout}Props {
|
|
@@ -777,23 +851,23 @@ export function ${layout}({ children }: ${layout}Props) {
|
|
|
777
851
|
output.push(`## Generated Files\n`);
|
|
778
852
|
if (generated.routes.length > 0) {
|
|
779
853
|
output.push(`### Routes (${generated.routes.length})`);
|
|
780
|
-
generated.routes.forEach(r => output.push(`- ${r}`));
|
|
781
|
-
output.push(
|
|
854
|
+
generated.routes.forEach((r) => output.push(`- ${r}`));
|
|
855
|
+
output.push("");
|
|
782
856
|
}
|
|
783
857
|
if (generated.actions.length > 0) {
|
|
784
858
|
output.push(`### Actions (${generated.actions.length})`);
|
|
785
|
-
generated.actions.forEach(a => output.push(`- ${a}`));
|
|
786
|
-
output.push(
|
|
859
|
+
generated.actions.forEach((a) => output.push(`- ${a}`));
|
|
860
|
+
output.push("");
|
|
787
861
|
}
|
|
788
862
|
if (generated.hooks.length > 0) {
|
|
789
863
|
output.push(`### Hooks (${generated.hooks.length})`);
|
|
790
|
-
generated.hooks.forEach(h => output.push(`- ${h}`));
|
|
791
|
-
output.push(
|
|
864
|
+
generated.hooks.forEach((h) => output.push(`- ${h}`));
|
|
865
|
+
output.push("");
|
|
792
866
|
}
|
|
793
867
|
if (generated.layouts.length > 0) {
|
|
794
868
|
output.push(`### Layouts (${generated.layouts.length})`);
|
|
795
|
-
generated.layouts.forEach(l => output.push(`- ${l}`));
|
|
796
|
-
output.push(
|
|
869
|
+
generated.layouts.forEach((l) => output.push(`- ${l}`));
|
|
870
|
+
output.push("");
|
|
797
871
|
}
|
|
798
872
|
output.push(`## Summary`);
|
|
799
873
|
output.push(`✅ Successfully generated scaffolding for existing components`);
|
|
@@ -802,10 +876,12 @@ export function ${layout}({ children }: ${layout}Props) {
|
|
|
802
876
|
output.push(`- Hooks: ${generated.hooks.length}`);
|
|
803
877
|
output.push(`- Layouts: ${generated.layouts.length}`);
|
|
804
878
|
return {
|
|
805
|
-
content: [
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
879
|
+
content: [
|
|
880
|
+
{
|
|
881
|
+
type: "text",
|
|
882
|
+
text: output.join("\n"),
|
|
883
|
+
},
|
|
884
|
+
],
|
|
809
885
|
metadata: {
|
|
810
886
|
success: true,
|
|
811
887
|
generated,
|
|
@@ -814,10 +890,12 @@ export function ${layout}({ children }: ${layout}Props) {
|
|
|
814
890
|
}
|
|
815
891
|
catch (error) {
|
|
816
892
|
return {
|
|
817
|
-
content: [
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
893
|
+
content: [
|
|
894
|
+
{
|
|
895
|
+
type: "text",
|
|
896
|
+
text: `Error generating scaffolding: ${error.message}`,
|
|
897
|
+
},
|
|
898
|
+
],
|
|
821
899
|
isError: true,
|
|
822
900
|
};
|
|
823
901
|
}
|
|
@@ -841,6 +919,6 @@ function getAllMCPTools() {
|
|
|
841
919
|
*/
|
|
842
920
|
function getMCPToolByName(name) {
|
|
843
921
|
const tools = getAllMCPTools();
|
|
844
|
-
return tools.find(tool => tool.name === name);
|
|
922
|
+
return tools.find((tool) => tool.name === name);
|
|
845
923
|
}
|
|
846
924
|
//# sourceMappingURL=mcpTools.js.map
|