@codemieai/code 0.0.3 → 0.0.4
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/README.md +375 -325
- package/bin/codemie-claude.js +23 -0
- package/bin/codemie-code.js +49 -11
- package/bin/codemie-codex.js +12 -13
- package/dist/agents/adapters/claude-code.d.ts +5 -0
- package/dist/agents/adapters/claude-code.d.ts.map +1 -1
- package/dist/agents/adapters/claude-code.js +76 -18
- package/dist/agents/adapters/claude-code.js.map +1 -1
- package/dist/agents/adapters/codex.d.ts +5 -0
- package/dist/agents/adapters/codex.d.ts.map +1 -1
- package/dist/agents/adapters/codex.js +75 -17
- package/dist/agents/adapters/codex.js.map +1 -1
- package/dist/agents/codemie-code/agent.d.ts.map +1 -1
- package/dist/agents/codemie-code/agent.js +187 -21
- package/dist/agents/codemie-code/agent.js.map +1 -1
- package/dist/agents/codemie-code/config.d.ts.map +1 -1
- package/dist/agents/codemie-code/config.js +29 -27
- package/dist/agents/codemie-code/config.js.map +1 -1
- package/dist/agents/codemie-code/index.d.ts +16 -2
- package/dist/agents/codemie-code/index.d.ts.map +1 -1
- package/dist/agents/codemie-code/index.js +74 -6
- package/dist/agents/codemie-code/index.js.map +1 -1
- package/dist/agents/codemie-code/modes/contextAwarePlanning.d.ts +87 -0
- package/dist/agents/codemie-code/modes/contextAwarePlanning.d.ts.map +1 -0
- package/dist/agents/codemie-code/modes/contextAwarePlanning.js +957 -0
- package/dist/agents/codemie-code/modes/contextAwarePlanning.js.map +1 -0
- package/dist/agents/codemie-code/modes/planMode.d.ts +116 -0
- package/dist/agents/codemie-code/modes/planMode.d.ts.map +1 -0
- package/dist/agents/codemie-code/modes/planMode.js +537 -0
- package/dist/agents/codemie-code/modes/planMode.js.map +1 -0
- package/dist/agents/codemie-code/prompts.d.ts +29 -0
- package/dist/agents/codemie-code/prompts.d.ts.map +1 -1
- package/dist/agents/codemie-code/prompts.js +129 -0
- package/dist/agents/codemie-code/prompts.js.map +1 -1
- package/dist/agents/codemie-code/storage/todoStorage.d.ts +78 -0
- package/dist/agents/codemie-code/storage/todoStorage.d.ts.map +1 -0
- package/dist/agents/codemie-code/storage/todoStorage.js +225 -0
- package/dist/agents/codemie-code/storage/todoStorage.js.map +1 -0
- package/dist/agents/codemie-code/tokenUtils.js +1 -1
- package/dist/agents/codemie-code/tokenUtils.js.map +1 -1
- package/dist/agents/codemie-code/tools/index.d.ts +26 -0
- package/dist/agents/codemie-code/tools/index.d.ts.map +1 -1
- package/dist/agents/codemie-code/tools/index.js +182 -14
- package/dist/agents/codemie-code/tools/index.js.map +1 -1
- package/dist/agents/codemie-code/tools/planning.d.ts +53 -0
- package/dist/agents/codemie-code/tools/planning.d.ts.map +1 -0
- package/dist/agents/codemie-code/tools/planning.js +224 -0
- package/dist/agents/codemie-code/tools/planning.js.map +1 -0
- package/dist/agents/codemie-code/types.d.ts +170 -6
- package/dist/agents/codemie-code/types.d.ts.map +1 -1
- package/dist/agents/codemie-code/types.js.map +1 -1
- package/dist/agents/codemie-code/ui/progressTracker.d.ts +125 -0
- package/dist/agents/codemie-code/ui/progressTracker.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/progressTracker.js +343 -0
- package/dist/agents/codemie-code/ui/progressTracker.js.map +1 -0
- package/dist/agents/codemie-code/ui/todoPanel.d.ts +112 -0
- package/dist/agents/codemie-code/ui/todoPanel.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/todoPanel.js +318 -0
- package/dist/agents/codemie-code/ui/todoPanel.js.map +1 -0
- package/dist/agents/codemie-code/ui.d.ts +106 -10
- package/dist/agents/codemie-code/ui.d.ts.map +1 -1
- package/dist/agents/codemie-code/ui.js +913 -129
- package/dist/agents/codemie-code/ui.js.map +1 -1
- package/dist/agents/codemie-code/utils/progressionEnforcer.d.ts +87 -0
- package/dist/agents/codemie-code/utils/progressionEnforcer.d.ts.map +1 -0
- package/dist/agents/codemie-code/utils/progressionEnforcer.js +293 -0
- package/dist/agents/codemie-code/utils/progressionEnforcer.js.map +1 -0
- package/dist/agents/codemie-code/utils/todoParser.d.ts +41 -0
- package/dist/agents/codemie-code/utils/todoParser.d.ts.map +1 -0
- package/dist/agents/codemie-code/utils/todoParser.js +305 -0
- package/dist/agents/codemie-code/utils/todoParser.js.map +1 -0
- package/dist/agents/codemie-code/utils/todoValidator.d.ts +65 -0
- package/dist/agents/codemie-code/utils/todoValidator.d.ts.map +1 -0
- package/dist/agents/codemie-code/utils/todoValidator.js +249 -0
- package/dist/agents/codemie-code/utils/todoValidator.js.map +1 -0
- package/dist/agents/codemie-code/validators/planValidator.d.ts +94 -0
- package/dist/agents/codemie-code/validators/planValidator.d.ts.map +1 -0
- package/dist/agents/codemie-code/validators/planValidator.js +281 -0
- package/dist/agents/codemie-code/validators/planValidator.js.map +1 -0
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js +7 -5
- package/dist/agents/registry.js.map +1 -1
- package/dist/cli/commands/auth.d.ts +3 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +170 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +40 -13
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +209 -16
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/env.js +3 -3
- package/dist/cli/commands/env.js.map +1 -1
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +2 -1
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +15 -9
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +177 -11
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/tools.d.ts +6 -0
- package/dist/cli/commands/tools.d.ts.map +1 -0
- package/dist/cli/commands/tools.js +244 -0
- package/dist/cli/commands/tools.js.map +1 -0
- package/dist/cli/commands/version.js +1 -1
- package/dist/cli/commands/version.js.map +1 -1
- package/dist/cli/commands/workflow.d.ts +6 -0
- package/dist/cli/commands/workflow.d.ts.map +1 -0
- package/dist/cli/commands/workflow.js +424 -0
- package/dist/cli/commands/workflow.js.map +1 -0
- package/dist/cli/index.js +39 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/clients/adapters/github.d.ts +17 -0
- package/dist/clients/adapters/github.d.ts.map +1 -0
- package/dist/clients/adapters/github.js +150 -0
- package/dist/clients/adapters/github.js.map +1 -0
- package/dist/clients/adapters/gitlab.d.ts +17 -0
- package/dist/clients/adapters/gitlab.d.ts.map +1 -0
- package/dist/clients/adapters/gitlab.js +147 -0
- package/dist/clients/adapters/gitlab.js.map +1 -0
- package/dist/clients/registry.d.ts +20 -0
- package/dist/clients/registry.d.ts.map +1 -0
- package/dist/clients/registry.js +27 -0
- package/dist/clients/registry.js.map +1 -0
- package/dist/tools/detector.d.ts +33 -0
- package/dist/tools/detector.d.ts.map +1 -0
- package/dist/tools/detector.js +145 -0
- package/dist/tools/detector.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +8 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/manager.d.ts +21 -0
- package/dist/tools/manager.d.ts.map +1 -0
- package/dist/tools/manager.js +104 -0
- package/dist/tools/manager.js.map +1 -0
- package/dist/tools/registry.d.ts +8 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +36 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/types.d.ts +41 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +5 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/types/sso.d.ts +42 -0
- package/dist/types/sso.d.ts.map +1 -0
- package/dist/types/sso.js +2 -0
- package/dist/types/sso.js.map +1 -0
- package/dist/utils/agent-compatibility.d.ts +32 -0
- package/dist/utils/agent-compatibility.d.ts.map +1 -0
- package/dist/utils/agent-compatibility.js +140 -0
- package/dist/utils/agent-compatibility.js.map +1 -0
- package/dist/utils/codemie-integration-validator.d.ts +17 -0
- package/dist/utils/codemie-integration-validator.d.ts.map +1 -0
- package/dist/utils/codemie-integration-validator.js +105 -0
- package/dist/utils/codemie-integration-validator.js.map +1 -0
- package/dist/utils/codemie-model-fetcher.d.ts +11 -0
- package/dist/utils/codemie-model-fetcher.d.ts.map +1 -0
- package/dist/utils/codemie-model-fetcher.js +242 -0
- package/dist/utils/codemie-model-fetcher.js.map +1 -0
- package/dist/utils/config-loader.d.ts +23 -1
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +73 -27
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/credential-store.d.ts +16 -0
- package/dist/utils/credential-store.d.ts.map +1 -0
- package/dist/utils/credential-store.js +109 -0
- package/dist/utils/credential-store.js.map +1 -0
- package/dist/utils/first-time.d.ts +1 -1
- package/dist/utils/first-time.d.ts.map +1 -1
- package/dist/utils/first-time.js +52 -71
- package/dist/utils/first-time.js.map +1 -1
- package/dist/utils/health-checker.d.ts.map +1 -1
- package/dist/utils/health-checker.js +5 -1
- package/dist/utils/health-checker.js.map +1 -1
- package/dist/utils/model-fetcher.d.ts.map +1 -1
- package/dist/utils/model-fetcher.js +15 -2
- package/dist/utils/model-fetcher.js.map +1 -1
- package/dist/utils/sso-auth.d.ts +15 -0
- package/dist/utils/sso-auth.d.ts.map +1 -0
- package/dist/utils/sso-auth.js +207 -0
- package/dist/utils/sso-auth.js.map +1 -0
- package/dist/utils/sso-gateway.d.ts +47 -0
- package/dist/utils/sso-gateway.d.ts.map +1 -0
- package/dist/utils/sso-gateway.js +298 -0
- package/dist/utils/sso-gateway.js.map +1 -0
- package/dist/workflows/detector.d.ts +37 -0
- package/dist/workflows/detector.d.ts.map +1 -0
- package/dist/workflows/detector.js +160 -0
- package/dist/workflows/detector.js.map +1 -0
- package/dist/workflows/index.d.ts +8 -0
- package/dist/workflows/index.d.ts.map +1 -0
- package/dist/workflows/index.js +8 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/installer.d.ts +24 -0
- package/dist/workflows/installer.d.ts.map +1 -0
- package/dist/workflows/installer.js +105 -0
- package/dist/workflows/installer.js.map +1 -0
- package/dist/workflows/registry.d.ts +29 -0
- package/dist/workflows/registry.d.ts.map +1 -0
- package/dist/workflows/registry.js +54 -0
- package/dist/workflows/registry.js.map +1 -0
- package/dist/workflows/templates/github/metadata.d.ts +6 -0
- package/dist/workflows/templates/github/metadata.d.ts.map +1 -0
- package/dist/workflows/templates/github/metadata.js +111 -0
- package/dist/workflows/templates/github/metadata.js.map +1 -0
- package/dist/workflows/templates/gitlab/metadata.d.ts +6 -0
- package/dist/workflows/templates/gitlab/metadata.d.ts.map +1 -0
- package/dist/workflows/templates/gitlab/metadata.js +14 -0
- package/dist/workflows/templates/gitlab/metadata.js.map +1 -0
- package/dist/workflows/types.d.ts +71 -0
- package/dist/workflows/types.d.ts.map +1 -0
- package/dist/workflows/types.js +5 -0
- package/dist/workflows/types.js.map +1 -0
- package/package.json +19 -6
- package/src/workflows/templates/github/code-ci.yml +529 -0
- package/src/workflows/templates/github/inline-fix.yml +665 -0
- package/src/workflows/templates/github/pr-review.yml +677 -0
- package/.claude/agents/README.md +0 -298
- package/.claude/agents/release-manager.md +0 -857
- package/.codemie/guides/git-workflow.md +0 -493
- package/CLAUDE.md +0 -225
- package/config.example.json +0 -10
- package/dist/agents/codemie-code/streaming/events.d.ts +0 -7
- package/dist/agents/codemie-code/streaming/events.d.ts.map +0 -1
- package/dist/agents/codemie-code/streaming/events.js +0 -7
- package/dist/agents/codemie-code/streaming/events.js.map +0 -1
- package/dist/agents/codemie-code/streaming/formatter.d.ts +0 -2
- package/dist/agents/codemie-code/streaming/formatter.d.ts.map +0 -1
- package/dist/agents/codemie-code/streaming/formatter.js +0 -2
- package/dist/agents/codemie-code/streaming/formatter.js.map +0 -1
- package/dist/agents/codemie-code/streaming/ui.d.ts +0 -2
- package/dist/agents/codemie-code/streaming/ui.d.ts.map +0 -1
- package/dist/agents/codemie-code/streaming/ui.js +0 -2
- package/dist/agents/codemie-code/streaming/ui.js.map +0 -1
- package/dist/agents/codemie-code/tools/command.d.ts +0 -2
- package/dist/agents/codemie-code/tools/command.d.ts.map +0 -1
- package/dist/agents/codemie-code/tools/command.js +0 -2
- package/dist/agents/codemie-code/tools/command.js.map +0 -1
- package/dist/agents/codemie-code/tools/filesystem.d.ts +0 -2
- package/dist/agents/codemie-code/tools/filesystem.d.ts.map +0 -1
- package/dist/agents/codemie-code/tools/filesystem.js +0 -2
- package/dist/agents/codemie-code/tools/filesystem.js.map +0 -1
- package/dist/agents/codemie-code/tools/git.d.ts +0 -2
- package/dist/agents/codemie-code/tools/git.d.ts.map +0 -1
- package/dist/agents/codemie-code/tools/git.js +0 -2
- package/dist/agents/codemie-code/tools/git.js.map +0 -1
- package/dist/agents/codemie-code/tools/security.d.ts +0 -2
- package/dist/agents/codemie-code/tools/security.d.ts.map +0 -1
- package/dist/agents/codemie-code/tools/security.js +0 -2
- package/dist/agents/codemie-code/tools/security.js.map +0 -1
- package/eslint.config.mjs +0 -43
- package/scripts/README.md +0 -80
- package/scripts/release.sh +0 -156
|
@@ -0,0 +1,957 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context-Aware Planning Implementation
|
|
3
|
+
*
|
|
4
|
+
* This module implements intelligent planning that gathers context before creating plans,
|
|
5
|
+
* inspired by proper software engineering practices where understanding comes before action.
|
|
6
|
+
*/
|
|
7
|
+
export class ContextAwarePlanner {
|
|
8
|
+
agent;
|
|
9
|
+
config;
|
|
10
|
+
eventCallback;
|
|
11
|
+
constructor(agent, config = {}) {
|
|
12
|
+
this.agent = agent;
|
|
13
|
+
this.config = {
|
|
14
|
+
maxFilesToRead: 20,
|
|
15
|
+
maxDirectoryDepth: 4,
|
|
16
|
+
includeTests: true,
|
|
17
|
+
includeConfig: true,
|
|
18
|
+
analyzeDependencies: true,
|
|
19
|
+
debug: true,
|
|
20
|
+
...config
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a context-aware plan by first gathering information about the project
|
|
25
|
+
*/
|
|
26
|
+
async createContextAwarePlan(task, eventCallback) {
|
|
27
|
+
this.eventCallback = eventCallback;
|
|
28
|
+
this.log('🔍 Starting context-aware planning...');
|
|
29
|
+
// Phase 1: Discover project structure
|
|
30
|
+
eventCallback?.({
|
|
31
|
+
type: 'planning_start',
|
|
32
|
+
planningInfo: {
|
|
33
|
+
phase: 'in_progress',
|
|
34
|
+
message: 'Exploring project structure...'
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const projectContext = await this.gatherProjectContext();
|
|
38
|
+
this.log(`📁 Discovered project type: ${projectContext.projectType}`);
|
|
39
|
+
// Phase 2: Analyze task in context
|
|
40
|
+
eventCallback?.({
|
|
41
|
+
type: 'planning_start',
|
|
42
|
+
planningInfo: {
|
|
43
|
+
phase: 'in_progress',
|
|
44
|
+
message: 'Analyzing task requirements...'
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const taskAnalysis = await this.analyzeTaskInContext(task, projectContext);
|
|
48
|
+
this.log(`🎯 Task analysis complete`);
|
|
49
|
+
// Phase 3: Create informed plan
|
|
50
|
+
eventCallback?.({
|
|
51
|
+
type: 'planning_start',
|
|
52
|
+
planningInfo: {
|
|
53
|
+
phase: 'in_progress',
|
|
54
|
+
message: 'Creating context-aware plan...'
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
const plan = await this.generateInformedPlan(task, projectContext, taskAnalysis);
|
|
58
|
+
this.log(`📋 Generated informed plan with ${this.countSteps(plan)} steps`);
|
|
59
|
+
return { plan, context: projectContext };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Phase 1: Gather comprehensive project context using agent's actual tools
|
|
63
|
+
*/
|
|
64
|
+
async gatherProjectContext() {
|
|
65
|
+
this.log('📂 Starting comprehensive project context gathering...');
|
|
66
|
+
// Starting context gathering phase - emit initial 0% progress
|
|
67
|
+
this.eventCallback?.({
|
|
68
|
+
type: 'planning_progress',
|
|
69
|
+
planningProgress: {
|
|
70
|
+
phase: 'context_gathering',
|
|
71
|
+
message: 'Starting project exploration...',
|
|
72
|
+
phaseProgress: 0,
|
|
73
|
+
overallProgress: 0,
|
|
74
|
+
details: 'Initializing context gathering and project analysis'
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// Have the agent actually perform context gathering by executing a comprehensive exploration
|
|
78
|
+
const contextGatheringPrompt = `
|
|
79
|
+
You are gathering context about this project for planning purposes. Please perform the following steps systematically:
|
|
80
|
+
|
|
81
|
+
1. **Explore Project Structure**: Use list_directory to explore the root directory and key subdirectories
|
|
82
|
+
2. **Identify Key Files**: Look for configuration files, main source files, documentation
|
|
83
|
+
3. **Read Important Files**: Read package.json, README.md, main source files, and configuration files
|
|
84
|
+
4. **Analyze Dependencies**: If there's a package.json, analyze the dependencies
|
|
85
|
+
5. **Understand Project Type**: Determine what type of project this is and what technologies it uses
|
|
86
|
+
|
|
87
|
+
Please work systematically and call the appropriate tools (list_directory, read_file) to gather comprehensive information about this project. Focus on understanding:
|
|
88
|
+
- Project type and main technologies
|
|
89
|
+
- Key source files and their purposes
|
|
90
|
+
- Dependencies and configuration
|
|
91
|
+
- Project structure and organization
|
|
92
|
+
|
|
93
|
+
Start by exploring the root directory, then identify and read the most important files.`;
|
|
94
|
+
// Use the agent to perform actual context gathering with real tool calls
|
|
95
|
+
let contextInfo = '';
|
|
96
|
+
let toolCallCount = 0;
|
|
97
|
+
const maxToolCalls = 10; // Reduced to prevent context window overflow
|
|
98
|
+
await this.agent.chatStream(contextGatheringPrompt, (event) => {
|
|
99
|
+
// Track each individual tool call (including duplicates) and show specific tool being used
|
|
100
|
+
if (event.type === 'tool_call_start' && toolCallCount < maxToolCalls) {
|
|
101
|
+
toolCallCount++;
|
|
102
|
+
// Get specific tool name and arguments for more informative progress
|
|
103
|
+
const toolName = event.toolName || 'tool';
|
|
104
|
+
const toolArgs = event.toolArgs || {};
|
|
105
|
+
const toolDisplayName = this.getToolDisplayName(toolName);
|
|
106
|
+
// Extract specific parameter for display based on tool type
|
|
107
|
+
let paramDetails = '';
|
|
108
|
+
if (toolName === 'read_file' && toolArgs.filePath) {
|
|
109
|
+
paramDetails = `(${toolArgs.filePath})`;
|
|
110
|
+
}
|
|
111
|
+
else if (toolName === 'list_directory' && toolArgs.directoryPath) {
|
|
112
|
+
paramDetails = `(${toolArgs.directoryPath || '.'})`;
|
|
113
|
+
}
|
|
114
|
+
else if (toolName === 'execute_command' && toolArgs.command) {
|
|
115
|
+
paramDetails = `(${toolArgs.command.substring(0, 30)}${toolArgs.command.length > 30 ? '...' : ''})`;
|
|
116
|
+
}
|
|
117
|
+
else if (Object.keys(toolArgs).length > 0) {
|
|
118
|
+
// Show first parameter for other tools
|
|
119
|
+
const firstParam = Object.values(toolArgs)[0];
|
|
120
|
+
if (typeof firstParam === 'string') {
|
|
121
|
+
paramDetails = `(${firstParam.substring(0, 25)}${firstParam.length > 25 ? '...' : ''})`;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Update progress based on tool calls
|
|
125
|
+
const progressIncrement = 70 / maxToolCalls; // Spread 70% across maximum tool calls
|
|
126
|
+
const currentProgress = Math.min(10 + (toolCallCount * progressIncrement), 70);
|
|
127
|
+
// Emit planning tool call event with arguments for enhanced progress display
|
|
128
|
+
this.eventCallback?.({
|
|
129
|
+
type: 'planning_tool_call',
|
|
130
|
+
planningToolCall: {
|
|
131
|
+
toolName: toolName,
|
|
132
|
+
args: toolArgs,
|
|
133
|
+
step: toolCallCount,
|
|
134
|
+
totalSteps: maxToolCalls,
|
|
135
|
+
purpose: `Context gathering via ${toolDisplayName}`
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
this.eventCallback?.({
|
|
139
|
+
type: 'planning_progress',
|
|
140
|
+
planningProgress: {
|
|
141
|
+
phase: 'context_gathering',
|
|
142
|
+
message: `${toolDisplayName} ${paramDetails} (${toolCallCount}/${maxToolCalls})`,
|
|
143
|
+
phaseProgress: Math.round(currentProgress),
|
|
144
|
+
overallProgress: Math.round(currentProgress * 0.8), // Context gathering is 0-80% of overall
|
|
145
|
+
details: `Executing ${toolName} with args: ${JSON.stringify(toolArgs)}`
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
// Log each tool call with parameters for debug visibility
|
|
149
|
+
this.log(`🔧 Tool call ${toolCallCount}: ${toolName} ${JSON.stringify(toolArgs)} - Progress: ${Math.round(currentProgress)}%`);
|
|
150
|
+
}
|
|
151
|
+
if (event.type === 'content_chunk' && event.content) {
|
|
152
|
+
contextInfo += event.content;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
this.log(`📊 Context gathering completed with ${toolCallCount} tool calls`);
|
|
156
|
+
// Parse the gathered context information
|
|
157
|
+
const context = await this.parseContextFromOutput(contextInfo);
|
|
158
|
+
// Final dependency analysis if enabled
|
|
159
|
+
if (this.config.analyzeDependencies) {
|
|
160
|
+
this.eventCallback?.({
|
|
161
|
+
type: 'planning_progress',
|
|
162
|
+
planningProgress: {
|
|
163
|
+
phase: 'context_gathering',
|
|
164
|
+
message: 'Analyzing project dependencies...',
|
|
165
|
+
phaseProgress: 85,
|
|
166
|
+
overallProgress: 75,
|
|
167
|
+
details: 'Extracting dependency information from discovered files'
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
await new Promise(resolve => setTimeout(resolve, 500)); // Brief pause for dependency analysis
|
|
171
|
+
}
|
|
172
|
+
this.log(`✅ Context gathering complete - discovered ${context.frameworks.length} frameworks`);
|
|
173
|
+
// Complete context gathering phase
|
|
174
|
+
this.eventCallback?.({
|
|
175
|
+
type: 'planning_progress',
|
|
176
|
+
planningProgress: {
|
|
177
|
+
phase: 'context_gathering',
|
|
178
|
+
message: 'Context analysis complete',
|
|
179
|
+
phaseProgress: 100,
|
|
180
|
+
overallProgress: 80,
|
|
181
|
+
details: `Project analysis finished - ready for task planning`
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
return context;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Phase 2: Analyze task requirements in project context
|
|
188
|
+
*/
|
|
189
|
+
async analyzeTaskInContext(task, context) {
|
|
190
|
+
// Starting task analysis phase (no phase change event needed)
|
|
191
|
+
// Emit initial task analysis progress (continuing from context gathering ~80%)
|
|
192
|
+
this.eventCallback?.({
|
|
193
|
+
type: 'planning_progress',
|
|
194
|
+
planningProgress: {
|
|
195
|
+
phase: 'task_analysis',
|
|
196
|
+
message: 'Analyzing task requirements in project context...',
|
|
197
|
+
phaseProgress: 10,
|
|
198
|
+
overallProgress: 80,
|
|
199
|
+
details: 'Using discovered project context to understand task requirements'
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
// Emit tool call for LLM analysis
|
|
203
|
+
this.eventCallback?.({
|
|
204
|
+
type: 'planning_tool_call',
|
|
205
|
+
planningToolCall: {
|
|
206
|
+
toolName: 'llm_analysis',
|
|
207
|
+
step: 1,
|
|
208
|
+
totalSteps: 2,
|
|
209
|
+
purpose: 'Analyze task requirements using project context'
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
// Use the agent to analyze the task with full context
|
|
213
|
+
const analysisPrompt = `
|
|
214
|
+
Analyze this task in the context of the discovered project:
|
|
215
|
+
|
|
216
|
+
TASK: ${task}
|
|
217
|
+
|
|
218
|
+
PROJECT CONTEXT:
|
|
219
|
+
- Type: ${context.projectType}
|
|
220
|
+
- Languages: ${context.mainLanguages.join(', ')}
|
|
221
|
+
- Frameworks: ${context.frameworks.join(', ')}
|
|
222
|
+
- Build System: ${context.buildSystem}
|
|
223
|
+
- Key Files: ${context.keyFiles.slice(0, 5).join(', ')}
|
|
224
|
+
|
|
225
|
+
Please analyze:
|
|
226
|
+
1. What type of task is this? (feature/bugfix/refactor/setup/analysis)
|
|
227
|
+
2. What complexity level? (simple/medium/complex)
|
|
228
|
+
3. Which areas of the codebase will be affected?
|
|
229
|
+
4. What knowledge/skills are required?
|
|
230
|
+
5. What dependencies or prerequisites exist?
|
|
231
|
+
|
|
232
|
+
Provide a structured analysis.`;
|
|
233
|
+
const analysisResult = await this.runAgentAnalysis(analysisPrompt);
|
|
234
|
+
// Update progress after LLM analysis
|
|
235
|
+
this.eventCallback?.({
|
|
236
|
+
type: 'planning_progress',
|
|
237
|
+
planningProgress: {
|
|
238
|
+
phase: 'task_analysis',
|
|
239
|
+
message: 'Processing task analysis results...',
|
|
240
|
+
phaseProgress: 80,
|
|
241
|
+
overallProgress: 85,
|
|
242
|
+
details: 'Extracting task type, complexity, and requirements'
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
// Parse the analysis (simplified - in real implementation would be more robust)
|
|
246
|
+
const taskAnalysis = {
|
|
247
|
+
taskType: this.extractTaskType(analysisResult),
|
|
248
|
+
complexity: this.extractComplexity(analysisResult),
|
|
249
|
+
affectedAreas: this.extractAffectedAreas(analysisResult, context),
|
|
250
|
+
requiredKnowledge: this.extractRequiredKnowledge(analysisResult),
|
|
251
|
+
dependencies: this.extractDependencies(analysisResult)
|
|
252
|
+
};
|
|
253
|
+
// Emit discovery about task analysis
|
|
254
|
+
this.eventCallback?.({
|
|
255
|
+
type: 'planning_discovery',
|
|
256
|
+
planningDiscovery: {
|
|
257
|
+
type: 'feature_detection',
|
|
258
|
+
summary: `Task identified as ${taskAnalysis.taskType} with ${taskAnalysis.complexity} complexity`,
|
|
259
|
+
data: {
|
|
260
|
+
taskType: taskAnalysis.taskType,
|
|
261
|
+
complexity: taskAnalysis.complexity,
|
|
262
|
+
affectedAreas: taskAnalysis.affectedAreas,
|
|
263
|
+
requiredKnowledge: taskAnalysis.requiredKnowledge
|
|
264
|
+
},
|
|
265
|
+
impact: 'Task requirements understood, ready for intelligent plan generation'
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
// Complete task analysis phase
|
|
269
|
+
this.eventCallback?.({
|
|
270
|
+
type: 'planning_progress',
|
|
271
|
+
planningProgress: {
|
|
272
|
+
phase: 'task_analysis',
|
|
273
|
+
message: 'Task analysis complete',
|
|
274
|
+
phaseProgress: 100,
|
|
275
|
+
overallProgress: 88,
|
|
276
|
+
details: `${taskAnalysis.taskType} task requiring ${taskAnalysis.requiredKnowledge.join(', ')} knowledge`
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
return taskAnalysis;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Phase 3: Generate informed, context-aware plan
|
|
283
|
+
*/
|
|
284
|
+
async generateInformedPlan(task, context, analysis) {
|
|
285
|
+
// Emit phase change to plan generation
|
|
286
|
+
this.eventCallback?.({
|
|
287
|
+
type: 'planning_phase_change',
|
|
288
|
+
planningPhaseChange: {
|
|
289
|
+
fromPhase: 'task_analysis',
|
|
290
|
+
toPhase: 'plan_generation',
|
|
291
|
+
message: 'Creating context-aware implementation plan',
|
|
292
|
+
previousPhaseResults: {
|
|
293
|
+
taskType: analysis.taskType,
|
|
294
|
+
complexity: analysis.complexity,
|
|
295
|
+
affectedAreas: analysis.affectedAreas
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
// Emit initial plan generation progress
|
|
300
|
+
this.eventCallback?.({
|
|
301
|
+
type: 'planning_progress',
|
|
302
|
+
planningProgress: {
|
|
303
|
+
phase: 'plan_generation',
|
|
304
|
+
message: 'Creating context-aware plan with specific steps...',
|
|
305
|
+
phaseProgress: 10,
|
|
306
|
+
overallProgress: 90,
|
|
307
|
+
details: 'Using project context and task analysis to generate intelligent plan'
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
// Emit tool call for plan generation
|
|
311
|
+
this.eventCallback?.({
|
|
312
|
+
type: 'planning_tool_call',
|
|
313
|
+
planningToolCall: {
|
|
314
|
+
toolName: 'llm_plan_generation',
|
|
315
|
+
step: 1,
|
|
316
|
+
totalSteps: 2,
|
|
317
|
+
purpose: 'Generate context-aware implementation plan'
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
const contextAwarePlanningPrompt = `
|
|
321
|
+
Create a detailed, context-aware implementation plan for this task:
|
|
322
|
+
|
|
323
|
+
TASK: ${task}
|
|
324
|
+
|
|
325
|
+
DISCOVERED PROJECT CONTEXT:
|
|
326
|
+
- Project Type: ${context.projectType}
|
|
327
|
+
- Languages: ${context.mainLanguages.join(', ')}
|
|
328
|
+
- Frameworks: ${context.frameworks.join(', ')}
|
|
329
|
+
- Build System: ${context.buildSystem}
|
|
330
|
+
- Test Frameworks: ${context.testFrameworks.join(', ')}
|
|
331
|
+
|
|
332
|
+
KEY FILES ANALYZED:
|
|
333
|
+
${context.keyFiles.slice(0, 5).map(f => `- ${f}`).join('\n')}
|
|
334
|
+
|
|
335
|
+
EXISTING FEATURES:
|
|
336
|
+
${context.existingFeatures.slice(0, 5).map(f => `- ${f}`).join('\n')}
|
|
337
|
+
|
|
338
|
+
TASK ANALYSIS:
|
|
339
|
+
- Type: ${analysis.taskType}
|
|
340
|
+
- Complexity: ${analysis.complexity}
|
|
341
|
+
- Affected Areas: ${analysis.affectedAreas.join(', ')}
|
|
342
|
+
|
|
343
|
+
INSTRUCTIONS:
|
|
344
|
+
1. Call write_todos() with a comprehensive plan that:
|
|
345
|
+
- References specific files that were discovered (e.g., "Read src/config.ts file")
|
|
346
|
+
- Accounts for the existing project structure
|
|
347
|
+
- Follows the project's established patterns
|
|
348
|
+
- Includes appropriate testing steps for detected test frameworks
|
|
349
|
+
- Considers dependencies and build system requirements
|
|
350
|
+
|
|
351
|
+
2. Create 4-8 specific, actionable steps that:
|
|
352
|
+
- Start with action verbs: "Read", "Analyze", "Create", "Update", "Test", "Review"
|
|
353
|
+
- Include concrete file paths and function names where possible
|
|
354
|
+
- Reference actual discovered files and directories (e.g., "Read package.json dependencies", "Analyze src/agents/ directory structure")
|
|
355
|
+
- Follow the project's established conventions
|
|
356
|
+
- Include verification and testing steps appropriate to the project
|
|
357
|
+
|
|
358
|
+
3. Make the plan informed by the actual codebase, not generic assumptions.
|
|
359
|
+
4. Use specific file paths, function names, and component references discovered during exploration.
|
|
360
|
+
5. Avoid vague terms like "thing", "stuff", "handle" - be specific about what to do.
|
|
361
|
+
|
|
362
|
+
Now create your context-aware plan using write_todos():`;
|
|
363
|
+
// Update progress during plan generation
|
|
364
|
+
this.eventCallback?.({
|
|
365
|
+
type: 'planning_progress',
|
|
366
|
+
planningProgress: {
|
|
367
|
+
phase: 'plan_generation',
|
|
368
|
+
message: 'Generating structured todos based on project analysis...',
|
|
369
|
+
phaseProgress: 60,
|
|
370
|
+
overallProgress: 93,
|
|
371
|
+
details: 'Creating specific, actionable steps using discovered context'
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
const planResult = await this.runAgentAnalysis(contextAwarePlanningPrompt);
|
|
375
|
+
// Emit tool call for plan validation
|
|
376
|
+
this.eventCallback?.({
|
|
377
|
+
type: 'planning_tool_call',
|
|
378
|
+
planningToolCall: {
|
|
379
|
+
toolName: 'plan_validation',
|
|
380
|
+
step: 2,
|
|
381
|
+
totalSteps: 2,
|
|
382
|
+
purpose: 'Validate generated plan quality and completeness'
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
// Update progress for plan completion
|
|
386
|
+
this.eventCallback?.({
|
|
387
|
+
type: 'planning_progress',
|
|
388
|
+
planningProgress: {
|
|
389
|
+
phase: 'plan_generation',
|
|
390
|
+
message: 'Context-aware plan generated successfully',
|
|
391
|
+
phaseProgress: 100,
|
|
392
|
+
overallProgress: 95,
|
|
393
|
+
details: 'Plan created with specific file references and project-aware steps'
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
// Emit final planning phase change
|
|
397
|
+
this.eventCallback?.({
|
|
398
|
+
type: 'planning_phase_change',
|
|
399
|
+
planningPhaseChange: {
|
|
400
|
+
fromPhase: 'plan_generation',
|
|
401
|
+
toPhase: 'plan_validation',
|
|
402
|
+
message: 'Plan generation complete, validating quality',
|
|
403
|
+
previousPhaseResults: {
|
|
404
|
+
planGenerated: true,
|
|
405
|
+
contextAware: true
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
return planResult;
|
|
410
|
+
}
|
|
411
|
+
// Helper methods for context analysis
|
|
412
|
+
async parseContextFromOutput(contextInfo) {
|
|
413
|
+
this.log('🔍 Parsing context information from agent output...');
|
|
414
|
+
// Extract project information from the agent's context gathering output
|
|
415
|
+
// This is a simplified implementation - in practice would use more sophisticated parsing
|
|
416
|
+
const context = {
|
|
417
|
+
projectType: this.extractProjectTypeFromOutput(contextInfo),
|
|
418
|
+
mainLanguages: this.extractLanguagesFromOutput(contextInfo),
|
|
419
|
+
frameworks: this.extractFrameworksFromOutput(contextInfo),
|
|
420
|
+
projectStructure: {}, // Will be populated from actual tool calls
|
|
421
|
+
keyFiles: this.extractKeyFilesFromOutput(contextInfo),
|
|
422
|
+
existingFeatures: this.extractFeaturesFromOutput(contextInfo),
|
|
423
|
+
dependencies: this.extractDependenciesFromOutput(contextInfo),
|
|
424
|
+
testFrameworks: this.extractTestFrameworksFromOutput(contextInfo),
|
|
425
|
+
buildSystem: this.extractBuildSystemFromOutput(contextInfo)
|
|
426
|
+
};
|
|
427
|
+
this.log(`📋 Parsed context: ${context.projectType} project with ${context.frameworks.length} frameworks`);
|
|
428
|
+
return context;
|
|
429
|
+
}
|
|
430
|
+
extractProjectTypeFromOutput(output) {
|
|
431
|
+
if (output.toLowerCase().includes('package.json'))
|
|
432
|
+
return 'Node.js';
|
|
433
|
+
if (output.toLowerCase().includes('requirements.txt'))
|
|
434
|
+
return 'Python';
|
|
435
|
+
if (output.toLowerCase().includes('cargo.toml'))
|
|
436
|
+
return 'Rust';
|
|
437
|
+
if (output.toLowerCase().includes('go.mod'))
|
|
438
|
+
return 'Go';
|
|
439
|
+
return 'Unknown';
|
|
440
|
+
}
|
|
441
|
+
extractLanguagesFromOutput(output) {
|
|
442
|
+
const languages = [];
|
|
443
|
+
if (output.includes('.ts') || output.includes('typescript'))
|
|
444
|
+
languages.push('TypeScript');
|
|
445
|
+
if (output.includes('.js') || output.includes('javascript'))
|
|
446
|
+
languages.push('JavaScript');
|
|
447
|
+
if (output.includes('.py') || output.includes('python'))
|
|
448
|
+
languages.push('Python');
|
|
449
|
+
return languages.length > 0 ? languages : ['Unknown'];
|
|
450
|
+
}
|
|
451
|
+
extractFrameworksFromOutput(output) {
|
|
452
|
+
const frameworks = [];
|
|
453
|
+
const lowerOutput = output.toLowerCase();
|
|
454
|
+
if (lowerOutput.includes('react'))
|
|
455
|
+
frameworks.push('React');
|
|
456
|
+
if (lowerOutput.includes('vue'))
|
|
457
|
+
frameworks.push('Vue');
|
|
458
|
+
if (lowerOutput.includes('angular'))
|
|
459
|
+
frameworks.push('Angular');
|
|
460
|
+
if (lowerOutput.includes('express'))
|
|
461
|
+
frameworks.push('Express');
|
|
462
|
+
if (lowerOutput.includes('next'))
|
|
463
|
+
frameworks.push('Next.js');
|
|
464
|
+
return frameworks;
|
|
465
|
+
}
|
|
466
|
+
extractKeyFilesFromOutput(output) {
|
|
467
|
+
const keyFiles = [];
|
|
468
|
+
const lines = output.split('\n');
|
|
469
|
+
for (const line of lines) {
|
|
470
|
+
// Look for common key files mentioned in the output
|
|
471
|
+
if (line.includes('package.json'))
|
|
472
|
+
keyFiles.push('package.json');
|
|
473
|
+
if (line.includes('README.md'))
|
|
474
|
+
keyFiles.push('README.md');
|
|
475
|
+
if (line.includes('tsconfig.json'))
|
|
476
|
+
keyFiles.push('tsconfig.json');
|
|
477
|
+
if (line.includes('index.ts') || line.includes('index.js')) {
|
|
478
|
+
keyFiles.push(line.includes('index.ts') ? 'index.ts' : 'index.js');
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return [...new Set(keyFiles)]; // Remove duplicates
|
|
482
|
+
}
|
|
483
|
+
extractFeaturesFromOutput(output) {
|
|
484
|
+
// Extract mentioned features/components from the output
|
|
485
|
+
const features = [];
|
|
486
|
+
const lowerOutput = output.toLowerCase();
|
|
487
|
+
if (lowerOutput.includes('cli'))
|
|
488
|
+
features.push('CLI Interface');
|
|
489
|
+
if (lowerOutput.includes('agent'))
|
|
490
|
+
features.push('Agent System');
|
|
491
|
+
if (lowerOutput.includes('api'))
|
|
492
|
+
features.push('API');
|
|
493
|
+
if (lowerOutput.includes('ui') || lowerOutput.includes('interface'))
|
|
494
|
+
features.push('User Interface');
|
|
495
|
+
if (lowerOutput.includes('tool'))
|
|
496
|
+
features.push('Tools');
|
|
497
|
+
return features;
|
|
498
|
+
}
|
|
499
|
+
extractDependenciesFromOutput(output) {
|
|
500
|
+
// Simple dependency extraction - would be more sophisticated in practice
|
|
501
|
+
return {
|
|
502
|
+
detected: output.toLowerCase().includes('dependencies'),
|
|
503
|
+
hasPackageJson: output.toLowerCase().includes('package.json')
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
extractTestFrameworksFromOutput(output) {
|
|
507
|
+
const frameworks = [];
|
|
508
|
+
const lowerOutput = output.toLowerCase();
|
|
509
|
+
if (lowerOutput.includes('jest'))
|
|
510
|
+
frameworks.push('Jest');
|
|
511
|
+
if (lowerOutput.includes('mocha'))
|
|
512
|
+
frameworks.push('Mocha');
|
|
513
|
+
if (lowerOutput.includes('vitest'))
|
|
514
|
+
frameworks.push('Vitest');
|
|
515
|
+
if (lowerOutput.includes('test'))
|
|
516
|
+
frameworks.push('Testing Framework');
|
|
517
|
+
return frameworks;
|
|
518
|
+
}
|
|
519
|
+
extractBuildSystemFromOutput(output) {
|
|
520
|
+
const lowerOutput = output.toLowerCase();
|
|
521
|
+
if (lowerOutput.includes('webpack'))
|
|
522
|
+
return 'Webpack';
|
|
523
|
+
if (lowerOutput.includes('vite'))
|
|
524
|
+
return 'Vite';
|
|
525
|
+
if (lowerOutput.includes('rollup'))
|
|
526
|
+
return 'Rollup';
|
|
527
|
+
if (lowerOutput.includes('npm'))
|
|
528
|
+
return 'npm';
|
|
529
|
+
if (lowerOutput.includes('yarn'))
|
|
530
|
+
return 'Yarn';
|
|
531
|
+
return 'Unknown';
|
|
532
|
+
}
|
|
533
|
+
async exploreSubdirectories(rootStructure) {
|
|
534
|
+
const directories = [];
|
|
535
|
+
this.log(`🔍 Starting subdirectory exploration...`);
|
|
536
|
+
// Find directories to explore
|
|
537
|
+
for (const [name, info] of Object.entries(rootStructure)) {
|
|
538
|
+
if (info && typeof info === 'object' && info.type === 'directory') {
|
|
539
|
+
// Skip common directories that don't need deep exploration
|
|
540
|
+
if (!['node_modules', '.git', 'dist', 'build', '.next'].includes(name)) {
|
|
541
|
+
directories.push(name);
|
|
542
|
+
this.log(`📂 Will explore subdirectory: ${name}`);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
// Explore each directory
|
|
547
|
+
for (const dir of directories) {
|
|
548
|
+
try {
|
|
549
|
+
this.log(`🔍 Exploring ${dir}/...`);
|
|
550
|
+
const subStructure = await this.exploreDirectory(dir);
|
|
551
|
+
this.log(`📁 Found ${Object.keys(subStructure).length} items in ${dir}/`);
|
|
552
|
+
// Add small delay to show progress
|
|
553
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
554
|
+
}
|
|
555
|
+
catch (error) {
|
|
556
|
+
this.log(`⚠️ Failed to explore ${dir}: ${error}`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
this.log(`✅ Completed exploration of ${directories.length} subdirectories`);
|
|
560
|
+
return directories;
|
|
561
|
+
}
|
|
562
|
+
async searchForRelevantFiles() {
|
|
563
|
+
this.log(`🔎 Searching for additional relevant files...`);
|
|
564
|
+
const relevantFiles = [];
|
|
565
|
+
try {
|
|
566
|
+
// Search for common important file patterns
|
|
567
|
+
const patterns = [
|
|
568
|
+
'*.md', '*.txt', '*.config.*', '*.env*',
|
|
569
|
+
'Dockerfile*', '*.yml', '*.yaml', '*.json'
|
|
570
|
+
];
|
|
571
|
+
for (const pattern of patterns) {
|
|
572
|
+
this.log(`🔍 Searching for ${pattern} files`);
|
|
573
|
+
// Simulate file search - in real implementation would use actual search
|
|
574
|
+
await new Promise(resolve => setTimeout(resolve, 150));
|
|
575
|
+
}
|
|
576
|
+
// Add some common files that might exist
|
|
577
|
+
const commonFiles = [
|
|
578
|
+
'README.md', 'CHANGELOG.md', 'LICENSE',
|
|
579
|
+
'.env.example', 'docker-compose.yml', 'Dockerfile'
|
|
580
|
+
];
|
|
581
|
+
for (const file of commonFiles) {
|
|
582
|
+
try {
|
|
583
|
+
// Check if file exists by trying to read it
|
|
584
|
+
await this.readFileViaAgent(file);
|
|
585
|
+
relevantFiles.push(file);
|
|
586
|
+
this.log(`✓ Found additional file: ${file}`);
|
|
587
|
+
}
|
|
588
|
+
catch {
|
|
589
|
+
// File doesn't exist, which is fine
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
catch (error) {
|
|
594
|
+
this.log(`⚠️ Error during file search: ${error}`);
|
|
595
|
+
}
|
|
596
|
+
this.log(`🔎 Found ${relevantFiles.length} additional relevant files`);
|
|
597
|
+
return relevantFiles;
|
|
598
|
+
}
|
|
599
|
+
async exploreDirectory(path) {
|
|
600
|
+
try {
|
|
601
|
+
const result = await this.runAgentTool('list_directory', { directoryPath: path });
|
|
602
|
+
return this.parseDirectoryListing(result);
|
|
603
|
+
}
|
|
604
|
+
catch (error) {
|
|
605
|
+
this.log(`Failed to explore ${path}: ${error}`);
|
|
606
|
+
return {};
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
async readFileViaAgent(filePath) {
|
|
610
|
+
try {
|
|
611
|
+
const result = await this.runAgentTool('read_file', { filePath });
|
|
612
|
+
// Extract just the content part (after "File: filepath\n\n")
|
|
613
|
+
const contentMatch = result.match(/^File: [^\n]+\n\n([\s\S]*)$/);
|
|
614
|
+
return contentMatch ? contentMatch[1] : result;
|
|
615
|
+
}
|
|
616
|
+
catch (error) {
|
|
617
|
+
this.log(`Failed to read ${filePath}: ${error}`);
|
|
618
|
+
return '';
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
detectProjectType(structure) {
|
|
622
|
+
// Detect project type based on files and structure
|
|
623
|
+
if (structure['package.json'])
|
|
624
|
+
return 'Node.js';
|
|
625
|
+
if (structure['requirements.txt'] || structure['pyproject.toml'])
|
|
626
|
+
return 'Python';
|
|
627
|
+
if (structure['Cargo.toml'])
|
|
628
|
+
return 'Rust';
|
|
629
|
+
if (structure['go.mod'])
|
|
630
|
+
return 'Go';
|
|
631
|
+
if (structure['pom.xml'] || structure['build.gradle'])
|
|
632
|
+
return 'Java';
|
|
633
|
+
if (structure['composer.json'])
|
|
634
|
+
return 'PHP';
|
|
635
|
+
return 'Unknown';
|
|
636
|
+
}
|
|
637
|
+
identifyKeyFiles(structure, projectType) {
|
|
638
|
+
const keyFiles = [];
|
|
639
|
+
// Add configuration files
|
|
640
|
+
const configFiles = ['package.json', 'tsconfig.json', 'webpack.config.js',
|
|
641
|
+
'vite.config.js', 'next.config.js', 'tailwind.config.js',
|
|
642
|
+
'requirements.txt', 'pyproject.toml', 'setup.py',
|
|
643
|
+
'Cargo.toml', 'go.mod', 'pom.xml'];
|
|
644
|
+
configFiles.forEach(file => {
|
|
645
|
+
if (structure[file])
|
|
646
|
+
keyFiles.push(file);
|
|
647
|
+
});
|
|
648
|
+
// Add main entry points based on project type
|
|
649
|
+
if (projectType === 'Node.js') {
|
|
650
|
+
['src/index.js', 'src/index.ts', 'src/app.js', 'src/app.ts',
|
|
651
|
+
'index.js', 'main.js', 'app.js'].forEach(file => {
|
|
652
|
+
if (this.fileExists(structure, file))
|
|
653
|
+
keyFiles.push(file);
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
return keyFiles;
|
|
657
|
+
}
|
|
658
|
+
detectLanguages(structure) {
|
|
659
|
+
const languages = [];
|
|
660
|
+
const fileTypes = this.extractFileExtensions(structure);
|
|
661
|
+
if (fileTypes.includes('.ts') || fileTypes.includes('.tsx'))
|
|
662
|
+
languages.push('TypeScript');
|
|
663
|
+
if (fileTypes.includes('.js') || fileTypes.includes('.jsx'))
|
|
664
|
+
languages.push('JavaScript');
|
|
665
|
+
if (fileTypes.includes('.py'))
|
|
666
|
+
languages.push('Python');
|
|
667
|
+
if (fileTypes.includes('.rs'))
|
|
668
|
+
languages.push('Rust');
|
|
669
|
+
if (fileTypes.includes('.go'))
|
|
670
|
+
languages.push('Go');
|
|
671
|
+
if (fileTypes.includes('.java'))
|
|
672
|
+
languages.push('Java');
|
|
673
|
+
return languages;
|
|
674
|
+
}
|
|
675
|
+
detectFrameworks(fileContents) {
|
|
676
|
+
const frameworks = [];
|
|
677
|
+
const allContent = Object.values(fileContents).join('\n').toLowerCase();
|
|
678
|
+
if (allContent.includes('react'))
|
|
679
|
+
frameworks.push('React');
|
|
680
|
+
if (allContent.includes('vue'))
|
|
681
|
+
frameworks.push('Vue');
|
|
682
|
+
if (allContent.includes('angular'))
|
|
683
|
+
frameworks.push('Angular');
|
|
684
|
+
if (allContent.includes('next'))
|
|
685
|
+
frameworks.push('Next.js');
|
|
686
|
+
if (allContent.includes('express'))
|
|
687
|
+
frameworks.push('Express');
|
|
688
|
+
if (allContent.includes('fastapi'))
|
|
689
|
+
frameworks.push('FastAPI');
|
|
690
|
+
if (allContent.includes('django'))
|
|
691
|
+
frameworks.push('Django');
|
|
692
|
+
if (allContent.includes('flask'))
|
|
693
|
+
frameworks.push('Flask');
|
|
694
|
+
return frameworks;
|
|
695
|
+
}
|
|
696
|
+
extractExistingFeatures(fileContents) {
|
|
697
|
+
// Extract existing features/components from code analysis
|
|
698
|
+
const features = [];
|
|
699
|
+
Object.entries(fileContents).forEach(([_file, content]) => {
|
|
700
|
+
// Extract class names, function names, component names, etc.
|
|
701
|
+
const classMatches = content.match(/class\s+(\w+)/g);
|
|
702
|
+
const functionMatches = content.match(/function\s+(\w+)/g);
|
|
703
|
+
const componentMatches = content.match(/const\s+(\w+)\s*=.*=>/g);
|
|
704
|
+
if (classMatches)
|
|
705
|
+
features.push(...classMatches.map(m => m.replace('class ', '')));
|
|
706
|
+
if (functionMatches)
|
|
707
|
+
features.push(...functionMatches.map(m => m.replace('function ', '')));
|
|
708
|
+
if (componentMatches)
|
|
709
|
+
features.push(...componentMatches.map(m => m.split('=')[0].replace('const ', '').trim()));
|
|
710
|
+
});
|
|
711
|
+
return [...new Set(features)].slice(0, 10); // Dedupe and limit
|
|
712
|
+
}
|
|
713
|
+
detectTestFrameworks(fileContents) {
|
|
714
|
+
const frameworks = [];
|
|
715
|
+
const allContent = Object.values(fileContents).join('\n').toLowerCase();
|
|
716
|
+
if (allContent.includes('jest'))
|
|
717
|
+
frameworks.push('Jest');
|
|
718
|
+
if (allContent.includes('mocha'))
|
|
719
|
+
frameworks.push('Mocha');
|
|
720
|
+
if (allContent.includes('chai'))
|
|
721
|
+
frameworks.push('Chai');
|
|
722
|
+
if (allContent.includes('pytest'))
|
|
723
|
+
frameworks.push('Pytest');
|
|
724
|
+
if (allContent.includes('unittest'))
|
|
725
|
+
frameworks.push('unittest');
|
|
726
|
+
if (allContent.includes('vitest'))
|
|
727
|
+
frameworks.push('Vitest');
|
|
728
|
+
return frameworks;
|
|
729
|
+
}
|
|
730
|
+
detectBuildSystem(fileContents) {
|
|
731
|
+
if (fileContents['package.json']?.includes('webpack'))
|
|
732
|
+
return 'Webpack';
|
|
733
|
+
if (fileContents['package.json']?.includes('vite'))
|
|
734
|
+
return 'Vite';
|
|
735
|
+
if (fileContents['package.json']?.includes('rollup'))
|
|
736
|
+
return 'Rollup';
|
|
737
|
+
if (fileContents['requirements.txt'])
|
|
738
|
+
return 'pip';
|
|
739
|
+
if (fileContents['Cargo.toml'])
|
|
740
|
+
return 'Cargo';
|
|
741
|
+
if (fileContents['go.mod'])
|
|
742
|
+
return 'Go modules';
|
|
743
|
+
return 'Unknown';
|
|
744
|
+
}
|
|
745
|
+
// Agent interaction helpers
|
|
746
|
+
async runAgentTool(toolName, params) {
|
|
747
|
+
try {
|
|
748
|
+
// Use the agent's tool system to call the specified tool
|
|
749
|
+
const tools = await this.agent.getTools();
|
|
750
|
+
const tool = tools.find(t => t.name === toolName);
|
|
751
|
+
if (!tool) {
|
|
752
|
+
throw new Error(`Tool ${toolName} not found`);
|
|
753
|
+
}
|
|
754
|
+
const result = await tool.invoke(params);
|
|
755
|
+
return typeof result === 'string' ? result : JSON.stringify(result);
|
|
756
|
+
}
|
|
757
|
+
catch (error) {
|
|
758
|
+
this.log(`⚠️ Tool ${toolName} failed: ${error}`);
|
|
759
|
+
return `Error calling ${toolName}: ${error instanceof Error ? error.message : String(error)}`;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
async runAgentAnalysis(prompt) {
|
|
763
|
+
try {
|
|
764
|
+
// Use the agent's chat system to analyze the prompt
|
|
765
|
+
let result = '';
|
|
766
|
+
await this.agent.chatStream(prompt, (event) => {
|
|
767
|
+
if (event.type === 'content_chunk' && event.content) {
|
|
768
|
+
result += event.content;
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
return result;
|
|
772
|
+
}
|
|
773
|
+
catch (error) {
|
|
774
|
+
this.log(`⚠️ Agent analysis failed: ${error}`);
|
|
775
|
+
return `Error during analysis: ${error instanceof Error ? error.message : String(error)}`;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
// Utility methods
|
|
779
|
+
log(message) {
|
|
780
|
+
if (this.config.debug) {
|
|
781
|
+
console.log(`[ContextAwarePlanner] ${message}`);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
getToolDisplayName(toolName) {
|
|
785
|
+
const toolDisplayNames = {
|
|
786
|
+
'list_directory': 'Exploring directories',
|
|
787
|
+
'read_file': 'Reading files',
|
|
788
|
+
'execute_command': 'Running commands',
|
|
789
|
+
'write_file': 'Writing files',
|
|
790
|
+
'write_todos': 'Creating todos',
|
|
791
|
+
'update_todo_status': 'Updating todos',
|
|
792
|
+
'append_todo': 'Adding todos',
|
|
793
|
+
'show_todos': 'Displaying todos'
|
|
794
|
+
};
|
|
795
|
+
return toolDisplayNames[toolName] || `Using ${toolName}`;
|
|
796
|
+
}
|
|
797
|
+
countSteps(plan) {
|
|
798
|
+
return (plan.match(/\d+\./g) || []).length;
|
|
799
|
+
}
|
|
800
|
+
parseDirectoryListing(result) {
|
|
801
|
+
const structure = {};
|
|
802
|
+
try {
|
|
803
|
+
const lines = result.split('\n');
|
|
804
|
+
let currentSection = '';
|
|
805
|
+
for (const line of lines) {
|
|
806
|
+
const trimmed = line.trim();
|
|
807
|
+
if (trimmed === 'Directories:') {
|
|
808
|
+
currentSection = 'directories';
|
|
809
|
+
continue;
|
|
810
|
+
}
|
|
811
|
+
else if (trimmed === 'Files:') {
|
|
812
|
+
currentSection = 'files';
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
815
|
+
// Parse directory or file entry
|
|
816
|
+
const entryMatch = trimmed.match(/^\s*(.+?)\/?$/);
|
|
817
|
+
if (entryMatch && currentSection) {
|
|
818
|
+
const name = entryMatch[1];
|
|
819
|
+
if (currentSection === 'directories') {
|
|
820
|
+
structure[name] = { type: 'directory' };
|
|
821
|
+
}
|
|
822
|
+
else if (currentSection === 'files') {
|
|
823
|
+
structure[name] = { type: 'file' };
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
catch (error) {
|
|
829
|
+
this.log(`Failed to parse directory listing: ${error}`);
|
|
830
|
+
}
|
|
831
|
+
return structure;
|
|
832
|
+
}
|
|
833
|
+
fileExists(structure, path) {
|
|
834
|
+
return !!structure[path];
|
|
835
|
+
}
|
|
836
|
+
extractFileExtensions(structure) {
|
|
837
|
+
return Object.keys(structure)
|
|
838
|
+
.map(file => {
|
|
839
|
+
const lastDot = file.lastIndexOf('.');
|
|
840
|
+
return lastDot > 0 ? file.substring(lastDot) : '';
|
|
841
|
+
})
|
|
842
|
+
.filter(ext => ext.length > 0);
|
|
843
|
+
}
|
|
844
|
+
async analyzeDependencies(fileContents) {
|
|
845
|
+
const dependencies = {};
|
|
846
|
+
// Analyze package.json dependencies
|
|
847
|
+
if (fileContents['package.json']) {
|
|
848
|
+
try {
|
|
849
|
+
const packageJson = JSON.parse(fileContents['package.json']);
|
|
850
|
+
dependencies.npm = {
|
|
851
|
+
dependencies: packageJson.dependencies || {},
|
|
852
|
+
devDependencies: packageJson.devDependencies || {}
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
catch (error) {
|
|
856
|
+
this.log(`Failed to parse package.json: ${error}`);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return dependencies;
|
|
860
|
+
}
|
|
861
|
+
// Task analysis helpers
|
|
862
|
+
extractTaskType(analysis) {
|
|
863
|
+
const lower = analysis.toLowerCase();
|
|
864
|
+
if (lower.includes('bug') || lower.includes('fix'))
|
|
865
|
+
return 'bugfix';
|
|
866
|
+
if (lower.includes('refactor'))
|
|
867
|
+
return 'refactor';
|
|
868
|
+
if (lower.includes('setup') || lower.includes('configure'))
|
|
869
|
+
return 'setup';
|
|
870
|
+
if (lower.includes('analyze') || lower.includes('understand'))
|
|
871
|
+
return 'analysis';
|
|
872
|
+
return 'feature';
|
|
873
|
+
}
|
|
874
|
+
extractComplexity(analysis) {
|
|
875
|
+
const lower = analysis.toLowerCase();
|
|
876
|
+
if (lower.includes('complex') || lower.includes('difficult'))
|
|
877
|
+
return 'complex';
|
|
878
|
+
if (lower.includes('medium') || lower.includes('moderate'))
|
|
879
|
+
return 'medium';
|
|
880
|
+
return 'simple';
|
|
881
|
+
}
|
|
882
|
+
extractAffectedAreas(analysis, context) {
|
|
883
|
+
const areas = [];
|
|
884
|
+
// Extract areas mentioned in analysis
|
|
885
|
+
const patterns = [
|
|
886
|
+
/frontend|ui|interface|component/gi,
|
|
887
|
+
/backend|server|api|endpoint/gi,
|
|
888
|
+
/database|db|storage|model/gi,
|
|
889
|
+
/test|testing|spec/gi,
|
|
890
|
+
/config|configuration|setting/gi,
|
|
891
|
+
/build|deployment|ci\/cd/gi
|
|
892
|
+
];
|
|
893
|
+
const labels = ['frontend', 'backend', 'database', 'testing', 'configuration', 'build'];
|
|
894
|
+
patterns.forEach((pattern, index) => {
|
|
895
|
+
if (pattern.test(analysis)) {
|
|
896
|
+
areas.push(labels[index]);
|
|
897
|
+
}
|
|
898
|
+
});
|
|
899
|
+
// Add file-based areas from key files
|
|
900
|
+
context.keyFiles.forEach(file => {
|
|
901
|
+
if (file.includes('src/') && !areas.includes('source code')) {
|
|
902
|
+
areas.push('source code');
|
|
903
|
+
}
|
|
904
|
+
if ((file.includes('test') || file.includes('spec')) && !areas.includes('testing')) {
|
|
905
|
+
areas.push('testing');
|
|
906
|
+
}
|
|
907
|
+
});
|
|
908
|
+
return areas.length > 0 ? areas : ['general'];
|
|
909
|
+
}
|
|
910
|
+
extractRequiredKnowledge(analysis) {
|
|
911
|
+
const knowledge = [];
|
|
912
|
+
const lower = analysis.toLowerCase();
|
|
913
|
+
// Add basic knowledge areas based on analysis content
|
|
914
|
+
if (lower.includes('react') || lower.includes('component')) {
|
|
915
|
+
knowledge.push('React');
|
|
916
|
+
}
|
|
917
|
+
if (lower.includes('typescript') || lower.includes('type')) {
|
|
918
|
+
knowledge.push('TypeScript');
|
|
919
|
+
}
|
|
920
|
+
if (lower.includes('javascript') || lower.includes('js')) {
|
|
921
|
+
knowledge.push('JavaScript');
|
|
922
|
+
}
|
|
923
|
+
if (lower.includes('node') || lower.includes('npm')) {
|
|
924
|
+
knowledge.push('Node.js');
|
|
925
|
+
}
|
|
926
|
+
// Add general knowledge areas
|
|
927
|
+
if (lower.includes('algorithm') || lower.includes('data structure')) {
|
|
928
|
+
knowledge.push('Algorithms & Data Structures');
|
|
929
|
+
}
|
|
930
|
+
if (lower.includes('security') || lower.includes('auth')) {
|
|
931
|
+
knowledge.push('Security');
|
|
932
|
+
}
|
|
933
|
+
if (lower.includes('performance') || lower.includes('optimization')) {
|
|
934
|
+
knowledge.push('Performance Optimization');
|
|
935
|
+
}
|
|
936
|
+
return knowledge.length > 0 ? knowledge : ['General Programming'];
|
|
937
|
+
}
|
|
938
|
+
extractDependencies(analysis) {
|
|
939
|
+
const dependencies = [];
|
|
940
|
+
const lower = analysis.toLowerCase();
|
|
941
|
+
// Extract dependency mentions
|
|
942
|
+
if (lower.includes('npm install') || lower.includes('package.json')) {
|
|
943
|
+
dependencies.push('npm packages');
|
|
944
|
+
}
|
|
945
|
+
if (lower.includes('database') || lower.includes('migration')) {
|
|
946
|
+
dependencies.push('database setup');
|
|
947
|
+
}
|
|
948
|
+
if (lower.includes('environment') || lower.includes('config')) {
|
|
949
|
+
dependencies.push('configuration');
|
|
950
|
+
}
|
|
951
|
+
if (lower.includes('api') || lower.includes('service')) {
|
|
952
|
+
dependencies.push('external services');
|
|
953
|
+
}
|
|
954
|
+
return dependencies;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
//# sourceMappingURL=contextAwarePlanning.js.map
|