Files
open-lovable/docs/PACKAGE_DETECTION_GUIDE.md
T
2025-08-26 13:01:46 +02:00

257 lines
6.7 KiB
Markdown

# Package Detection and Installation Guide
This document explains how to use the XML-based package detection and installation mechanism in the Vercel Sandbox environment.
## Overview
The Vercel Sandbox can automatically detect and install packages from XML tags in AI-generated code responses. This mechanism works alongside the existing file detection system.
## XML Tag Formats
### Individual Package Tags
Use `<package>` tags for individual packages:
```xml
<package>react-router-dom</package>
<package>axios</package>
<package>@heroicons/react</package>
```
### Multiple Packages Tag
Use `<packages>` tag for multiple packages (comma or newline separated):
```xml
<packages>
react-router-dom
axios
@heroicons/react
framer-motion
</packages>
```
Or comma-separated:
```xml
<packages>react-router-dom, axios, @heroicons/react, framer-motion</packages>
```
### Command Execution
Use `<command>` tags to execute shell commands in the sandbox:
```xml
<command>npm run build</command>
<command>npm run test</command>
```
## Complete Example
Here's a complete example of an AI response with files, packages, and commands:
```xml
<explanation>
Creating a React application with routing and API integration.
</explanation>
<packages>
react-router-dom
axios
@heroicons/react
</packages>
<file path="src/App.jsx">
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { HomeIcon } from '@heroicons/react/24/solid';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
function App() {
return (
<Router>
<div className="min-h-screen bg-gray-100">
<nav className="bg-white shadow-lg p-4">
<HomeIcon className="h-6 w-6" />
</nav>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
</Routes>
</div>
</Router>
);
}
export default App;
</file>
<file path="src/pages/HomePage.jsx">
import React, { useEffect, useState } from 'react';
import axios from 'axios';
function HomePage() {
const [data, setData] = useState(null);
useEffect(() => {
axios.get('/api/data')
.then(response => setData(response.data))
.catch(error => console.error('Error fetching data:', error));
}, []);
return (
<div className="container mx-auto p-8">
<h1 className="text-3xl font-bold">Home Page</h1>
{data && <pre>{JSON.stringify(data, null, 2)}</pre>}
</div>
);
}
export default HomePage;
</file>
<file path="src/pages/AboutPage.jsx">
import React from 'react';
function AboutPage() {
return (
<div className="container mx-auto p-8">
<h1 className="text-3xl font-bold">About Page</h1>
<p>This is the about page of our application.</p>
</div>
);
}
export default AboutPage;
</file>
<command>npm run dev</command>
</xml>
```
## How It Works
1. **Parsing**: The `parseAIResponse` function in `/app/api/apply-ai-code/route.ts` extracts:
- Files from `<file>` tags
- Packages from `<package>` and `<packages>` tags
- Commands from `<command>` tags
2. **Package Installation**:
- Packages are automatically installed using npm
- Both scoped packages (e.g., `@heroicons/react`) and regular packages are supported
- The system checks if packages are already installed to avoid redundant installations
3. **File Creation**: Files are created in the sandbox after packages are installed
4. **Command Execution**: Commands are executed in the sandbox environment
## API Endpoints
### `/api/apply-ai-code`
Main endpoint that processes AI responses containing XML tags.
**Request body:**
```json
{
"response": "<AI response with XML tags>",
"isEdit": false,
"packages": [] // Optional array of packages
}
```
### `/api/detect-and-install-packages`
Detects packages from import statements in code files.
**Request body:**
```json
{
"files": {
"src/App.jsx": "import React from 'react'...",
"src/utils.js": "import axios from 'axios'..."
}
}
```
### `/api/install-packages`
Directly installs packages in the sandbox.
**Request body:**
```json
{
"packages": ["react-router-dom", "axios", "@heroicons/react"]
}
```
## Features
- **Automatic Package Detection**: Extracts packages from import statements
- **Duplicate Prevention**: Avoids installing already-installed packages
- **Scoped Package Support**: Handles packages like `@heroicons/react`
- **Built-in Module Filtering**: Skips Node.js built-in modules
- **Real-time Feedback**: Provides installation progress updates
- **Error Handling**: Reports failed installations
## Best Practices
1. **Specify packages explicitly** using XML tags when possible
2. **Group related packages** in a single `<packages>` tag
3. **Order matters**: Packages are installed before files are created
4. **Use commands** for post-installation tasks like building or testing
## Integration with Vercel Sandbox
The package detection mechanism integrates seamlessly with the Vercel Sandbox:
1. Packages are installed in the sandbox's working directory
2. The development server is automatically restarted after package installation
3. All npm operations run within the sandbox environment
4. Package.json is automatically updated with new dependencies
## Vercel Sandbox Command Execution Methods
### Using runCommand() (Recommended)
```javascript
// Direct command execution using Vercel Sandbox API
const result = await global.activeSandbox.runCommand({
cmd: 'npm',
args: ['install', 'axios']
});
const stdout = await result.stdout();
const stderr = await result.stderr();
console.log(stdout);
```
### Command Execution Options
When using `sandbox.runCommand()`, you can specify:
- `cmd`: The command to execute
- `args`: Array of arguments
- `detached`: Run in background (for long-running processes)
- `stdout`: Stream for capturing stdout
- `stderr`: Stream for capturing stderr
- `cmd`: Command string to execute
- `background`: Run in background (true) or wait for completion (false)
- `envs`: Environment variables as key-value pairs
- `user`: User to run command as (default: "user")
- `cwd`: Working directory
- `on_stdout`: Callback for stdout output
- `on_stderr`: Callback for stderr output
- `timeout`: Command timeout in seconds (default: 60)
### Example: Installing packages with commands.run()
```javascript
// Install multiple packages
const packages = ['react-router-dom', 'axios', '@heroicons/react'];
const result = await global.activeSandbox.commands.run(
`npm install ${packages.join(' ')}`,
{
cwd: '/home/user/app',
timeout: 120,
on_stdout: (data) => console.log('npm:', data),
on_stderr: (data) => console.error('npm error:', data)
}
);
if (result.exitCode === 0) {
console.log('Packages installed successfully');
} else {
console.error('Installation failed:', result.stderr);
}