Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 130 additions & 6 deletions docs/AI_CODING_AGENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ The AI assistant is **FDO SDK-aware** and can help with plugin development using

## Features

The AI Coding Agent supports four main actions:
The AI Coding Agent supports the following actions:

1. **Generate Code** - Create new code based on natural language descriptions
2. **Edit Code** - Modify selected code according to instructions
3. **Explain Code** - Get explanations for selected code blocks
4. **Fix Code** - Debug and fix code with error messages
1. **Smart Mode** - AI automatically determines the best action based on context
2. **Generate Code** - Create new code based on natural language descriptions
3. **Edit Code** - Modify selected code according to instructions
4. **Explain Code** - Get explanations for selected code blocks
5. **Fix Code** - Debug and fix code with error messages
6. **Plan Code (Plugin Scaffold)** - Generate complete plugin project structures with multiple files

## FDO SDK Integration

Expand Down Expand Up @@ -70,25 +72,30 @@ export default class MyPlugin extends FDO_SDK implements FDOInterface {

### IPC Channels (`src/ipc/channels.js`)
- Added `AiCodingAgentChannels` with the following operations:
- `SMART_MODE`
- `GENERATE_CODE`
- `EDIT_CODE`
- `EXPLAIN_CODE`
- `FIX_CODE`
- `PLAN_CODE`
- Streaming events: `STREAM_DELTA`, `STREAM_DONE`, `STREAM_ERROR`

### Main Process Handler (`src/ipc/ai_coding_agent.js`)
- Implements handlers for all four AI operations
- Implements handlers for all AI operations including Plan Code
- Uses the existing coding assistant configuration from settings
- Supports streaming responses for real-time feedback
- Each operation creates a unique request ID for tracking
- **System prompt includes FDO SDK knowledge**
- **Plan Code handler supports vision models for UI mockup analysis**

### Preload API (`src/preload.js`)
- Exposes `window.electron.aiCodingAgent` with methods:
- `smartMode(data)` - AI-determined action
- `generateCode(data)` - Generate new code
- `editCode(data)` - Edit existing code
- `explainCode(data)` - Explain code functionality
- `fixCode(data)` - Fix code errors
- `planCode(data)` - Generate plugin scaffold
- Event listeners for streaming updates

### UI Component (`src/components/editor/AiCodingAgentPanel.jsx`)
Expand Down Expand Up @@ -157,6 +164,123 @@ Explain how this plugin uses the FDO_SDK base class and lifecycle hooks
This plugin fails to render - TypeError: Cannot read property 'render' of undefined
```

**Plan Code (Plugin Scaffold):**
```
Create a weather dashboard plugin that displays current weather and a 5-day forecast
```

Or upload a UI mockup image and describe:
```
Analyze the uploaded mockup and create a plugin matching this design
```

## Plan Code (Plugin Scaffold) Feature

The **Plan Code** action is a powerful feature that generates complete plugin project structures with multiple files. This is ideal for quickly scaffolding new plugins or creating complex multi-file projects.

### How It Works

1. **Describe Your Plugin**: Provide a detailed description of what you want to build
2. **Optional UI Mockup**: Upload an image of a UI mockup for the AI to analyze
3. **AI Generates Plan**: The AI creates a comprehensive plan with file structure and content
4. **Execute Plan**: Click "Execute Plan" to automatically create all files in the editor

### Plan Format

The AI generates plans in a structured markdown format:

```markdown
## Plan Overview
Brief description of the plugin and its features.

## File Structure
```
/package.json
/tsconfig.json
/index.ts
/render.tsx
/components/
/WeatherCard.tsx
/ForecastList.tsx
```

## Implementation

### File: /package.json
```json
{
"name": "weather-plugin",
"version": "1.0.0",
...
}
```

### File: /index.ts
```typescript
import { FDO_SDK, FDOInterface, PluginMetadata } from "@anikitenko/fdo-sdk";
...
```

### File: /components/WeatherCard.tsx
```tsx
import React from 'react';
...
```
```

### Features

- **Multi-file Generation**: Creates entire project structures with one click
- **Vision Support**: Analyzes UI mockups when using vision-capable models (GPT-4 Vision, Claude with vision)
- **FDO SDK Integration**: Generated code follows FDO plugin patterns automatically
- **Snapshot Before Apply**: Creates an automatic snapshot so you can undo if needed
- **Smart Parsing**: Automatically extracts file paths and content from AI response
- **Language Detection**: Determines file language from extension for proper syntax highlighting

### Example Usage

**Prompt:**
```
Create a todo list plugin with the following features:
- Add, edit, and delete tasks
- Mark tasks as complete
- Filter by status (all, active, completed)
- Persist tasks using FDO storage
- Use DOMTable for displaying tasks
```

**With UI Mockup:**
1. Upload a screenshot or design mockup
2. Describe: "Create a plugin matching this UI design with full functionality"
3. AI analyzes the image and generates matching code

### Execution Process

When you click "Execute Plan":
1. Creates a snapshot of current workspace (for undo)
2. Parses the AI response to extract files
3. Creates folder structure
4. Creates Monaco editor models for each file
5. Registers files with VirtualFS
6. Shows success message with file count

### Troubleshooting

**No files created:**
- Ensure AI response contains file sections with format: `### File: /path/to/file`
- Check that code blocks are properly formatted with triple backticks
- Try regenerating the plan with more specific instructions

**Partial execution:**
- Check console for specific file errors
- Some files may have been created successfully
- Use the snapshot feature to undo and try again

**Vision models not working:**
- Ensure your selected AI assistant supports vision (GPT-4 Vision, Claude 3+)
- Image must be in a supported format (PNG, JPEG, WebP)
- Image size should be under 20MB

### Keyboard Shortcuts

Currently no keyboard shortcuts are assigned, but they can be added in the future for:
Expand Down
118 changes: 111 additions & 7 deletions src/components/editor/AiCodingAgentPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import * as styles from "./AiCodingAgentPanel.module.css";
import * as styles2 from "../ai-chat/MarkdownRenderer.module.scss";
import Markdown from "markdown-to-jsx";
import virtualFS from "./utils/VirtualFS";
import {createVirtualFile} from "./utils/createVirtualFile";

import hljs from "../../assets/js/hljs/highlight.min"
import "../../assets/css/hljs/xt256.min.css"
Expand Down Expand Up @@ -338,9 +339,116 @@ export default function AiCodingAgentPanel({ codeEditor, response, setResponse }

const handleExecutePlan = async () => {
if (!response) return;
// TODO: Parse plan and generate files in VirtualFS

console.log('[AI Coding Agent] Executing plan...');
setError('Plan execution coming soon!');
setIsLoading(true);
setError(null);

try {
// Create snapshot before making changes
const snapshot = createSnapshotBeforeApply();
if (!snapshot) {
setError('Failed to create snapshot before applying plan');
setIsLoading(false);
return;
}

// Parse the plan and extract files
const files = parsePlanResponse(response);

if (files.length === 0) {
setError('No files found in the plan. Please ensure the AI response contains file sections with code blocks.');
setIsLoading(false);
return;
}

console.log('[AI Coding Agent] Creating files from plan', { fileCount: files.length });

// Create folders first (extract unique folder paths)
const folders = new Set();
files.forEach(file => {
const parts = file.path.split('/').filter(Boolean);
for (let i = 1; i < parts.length; i++) {
const folderPath = '/' + parts.slice(0, i).join('/');
folders.add(folderPath);
}
});

// Create folders in order
const sortedFolders = Array.from(folders).sort();
for (const folder of sortedFolders) {
try {
virtualFS.createFolder(folder);
console.log('[AI Coding Agent] Created folder:', folder);
} catch (err) {
console.warn('[AI Coding Agent] Folder may already exist:', folder, err);
}
}

// Create files
let successCount = 0;
let errorCount = 0;
const errorDetails = [];

for (const file of files) {
try {
// Use createVirtualFile which handles Monaco model creation properly
createVirtualFile(file.path, file.content);
console.log('[AI Coding Agent] Created file:', file.path);
successCount++;
} catch (err) {
console.error('[AI Coding Agent] Error creating file:', file.path, err);
errorCount++;
errorDetails.push(`${file.path}: ${err.message}`);
}
}

console.log('[AI Coding Agent] Plan execution complete', { successCount, errorCount });

if (successCount > 0) {
// Show success message
const message = `✓ Plan executed successfully: ${successCount} file(s) created${errorCount > 0 ? `, ${errorCount} failed` : ''}`;

setError(null);
setResponse(message);
responseRef.current = message;

// Clear response and image after a delay (10 seconds to give users time to review)
setTimeout(() => {
setResponse('');
responseRef.current = '';
handleRemoveImage();
}, 10000);
} else {
setError(`Failed to create any files from the plan. Errors: ${errorDetails.join('; ')}`);
}
} catch (err) {
console.error('[AI Coding Agent] Error executing plan:', err);
setError(`Failed to execute plan: ${err.message}`);
} finally {
setIsLoading(false);
}
};

// Helper function to parse plan response and extract files
const parsePlanResponse = (response) => {
const files = [];

// Match file sections: ### File: /path/to/file followed by code block
// Limit code block content to 50,000 characters to avoid catastrophic backtracking on malformed input
const filePattern = /###\s+File:\s+(\/[^\s\n]+)\s*\n\s*```(\w+)?\s*\n([^]{0,50000}?)```/g;

let match;
while ((match = filePattern.exec(response)) !== null) {
const [, path, language, content] = match;
files.push({
path: path.trim(),
language: language || '',
content: content.trim()
});
}

return files;
};

const handleSubmit = async () => {
Expand Down Expand Up @@ -804,11 +912,7 @@ export default function AiCodingAgentPanel({ codeEditor, response, setResponse }
<Button
text="Refine Response"
icon="lightbulb"
onClick={() => {
console.log('[AI Coding Agent] Entering refinement mode');
setIsRefining(true);
setPrompt('');
}}
onClick={handleRefine}
disabled={isLoading}
/>
)}
Expand Down
Loading