diff --git a/.gitignore b/.gitignore index 308ba6d..496fb30 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,7 @@ typings/ !.vscode/extensions.json # End of https://www.gitignore.io/api/node,visualstudiocode,macos + +### Vitepress ### +docs/.vitepress/cache +docs/.vitepress/dist \ No newline at end of file diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts new file mode 100644 index 0000000..2401984 --- /dev/null +++ b/docs/.vitepress/config.ts @@ -0,0 +1,152 @@ +import { defineConfig } from 'vitepress' + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: "CodeSandbox SDK", + description: "The power of CodeSandbox in a library", + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + nav: [ + { text: 'Home', link: '/' }, + { text: 'Guides', link: '/guides/getting-started/quick-start' }, + { text: 'API Reference', link: '/api/core-classes/codesandbox' }, + { text: 'CLI', link: '/cli/overview' } + ], + + sidebar: { + '/guides/': [ + { + text: 'Getting Started', + collapsed: false, + items: [ + { text: 'Quick Start', link: '/guides/getting-started/quick-start' }, + { text: 'Platform Setup', link: '/guides/getting-started/platform-setup' }, + { text: 'Authentication', link: '/guides/getting-started/authentication' } + ] + }, + { + text: 'Core Concepts', + collapsed: false, + items: [ + { text: 'Understanding Sandboxes', link: '/guides/core-concepts/sandboxes' }, + { text: 'Sandbox Lifecycle', link: '/guides/core-concepts/lifecycle' }, + { text: 'VM Tiers & Resources', link: '/guides/core-concepts/vm-tiers' } + ] + }, + { + text: 'SDK Usage', + collapsed: false, + items: [ + { text: 'Basic Operations', link: '/guides/sdk-usage/basic-operations' }, + { text: 'File System Operations', link: '/guides/sdk-usage/filesystem' }, + { text: 'Command Execution', link: '/guides/sdk-usage/commands' }, + { text: 'Terminal Management', link: '/guides/sdk-usage/terminals' } + ] + }, + { + text: 'Advanced Features', + collapsed: false, + items: [ + { text: 'Port Management', link: '/guides/advanced/ports' }, + { text: 'Source Control', link: '/guides/advanced/git' }, + { text: 'Code Interpretation', link: '/guides/advanced/interpreters' }, + { text: 'Browser Integration', link: '/guides/advanced/browser' } + ] + }, + { + text: 'Use Cases', + collapsed: false, + items: [ + { text: 'AI Agents & Code Interpretation', link: '/guides/use-cases/ai-agents' }, + { text: 'Development Environments', link: '/guides/use-cases/dev-environments' }, + { text: 'CI/CD Integration', link: '/guides/use-cases/cicd' }, + { text: 'Educational Platforms', link: '/guides/use-cases/education' } + ] + }, + { + text: 'Best Practices', + collapsed: false, + items: [ + { text: 'Performance Optimization', link: '/guides/best-practices/performance' }, + { text: 'Error Handling', link: '/guides/best-practices/error-handling' }, + { text: 'Monitoring & Debugging', link: '/guides/best-practices/monitoring' } + ] + } + ], + '/api/': [ + { + text: 'Core Classes', + collapsed: false, + items: [ + { text: 'CodeSandbox', link: '/api/core-classes/codesandbox' }, + { text: 'Sandboxes', link: '/api/core-classes/sandboxes' }, + { text: 'Sandbox', link: '/api/core-classes/sandbox' }, + { text: 'SandboxClient', link: '/api/core-classes/sandbox-client' } + ] + }, + { + text: 'SandboxClient APIs', + collapsed: false, + items: [ + { text: 'File System', link: '/api/sandbox-client/filesystem' }, + { text: 'Commands', link: '/api/sandbox-client/commands' }, + { text: 'Terminals', link: '/api/sandbox-client/terminals' }, + { text: 'Ports', link: '/api/sandbox-client/ports' }, + { text: 'Tasks', link: '/api/sandbox-client/tasks' }, + { text: 'Interpreters', link: '/api/sandbox-client/interpreters' }, + { text: 'Setup', link: '/api/sandbox-client/setup' } + ] + }, + { + text: 'Browser APIs', + collapsed: false, + items: [ + { text: 'Browser Connection', link: '/api/browser/connection' }, + { text: 'Preview Management', link: '/api/browser/previews' } + ] + }, + { + text: 'Host Tokens', + collapsed: false, + items: [ + { text: 'HostTokens Class', link: '/api/host-tokens/host-tokens' } + ] + }, + { + text: 'Types & Interfaces', + collapsed: false, + items: [ + { text: 'Configuration Types', link: '/api/types/configuration' }, + { text: 'Event Types', link: '/api/types/events' }, + { text: 'Error Types', link: '/api/types/errors' } + ] + } + ], + '/cli/': [ + { + text: 'CLI Documentation', + collapsed: false, + items: [ + { text: 'Overview', link: '/cli/overview' }, + { text: 'Interactive Mode', link: '/cli/interactive' }, + { text: 'Build Command', link: '/cli/build' }, + { text: 'Sandbox Management', link: '/cli/sandboxes' }, + { text: 'Host Tokens', link: '/cli/host-tokens' } + ] + } + ] + }, + + socialLinks: [ + { icon: 'github', link: 'https://github.com/codesandbox/codesandbox-sdk' } + ], + + search: { + provider: 'local' + }, + + editLink: { + pattern: 'https://github.com/codesandbox/codesandbox-sdk/edit/main/docs/:path' + } + } +}) \ No newline at end of file diff --git a/docs/api-examples.md b/docs/api-examples.md new file mode 100644 index 0000000..6bd8bb5 --- /dev/null +++ b/docs/api-examples.md @@ -0,0 +1,49 @@ +--- +outline: deep +--- + +# Runtime API Examples + +This page demonstrates usage of some of the runtime APIs provided by VitePress. + +The main `useData()` API can be used to access site, theme, and page data for the current page. It works in both `.md` and `.vue` files: + +```md + + +## Results + +### Theme Data +
{{ theme }}
+ +### Page Data +
{{ page }}
+ +### Page Frontmatter +
{{ frontmatter }}
+``` + + + +## Results + +### Theme Data +
{{ theme }}
+ +### Page Data +
{{ page }}
+ +### Page Frontmatter +
{{ frontmatter }}
+ +## More + +Check out the documentation for the [full list of runtime APIs](https://vitepress.dev/reference/runtime-api#usedata). diff --git a/docs/api/core-classes/codesandbox.md b/docs/api/core-classes/codesandbox.md new file mode 100644 index 0000000..9115358 --- /dev/null +++ b/docs/api/core-classes/codesandbox.md @@ -0,0 +1,211 @@ +# CodeSandbox + +The main entry point for the CodeSandbox SDK. This class provides access to sandbox management and host token operations. + +## Constructor + +### `new CodeSandbox(apiToken?, opts?)` + +Creates a new CodeSandbox SDK instance. + +**Parameters:** +- `apiToken` (string, optional) - Your CodeSandbox API token. If not provided, will use `CSB_API_KEY` environment variable +- `opts` (ClientOpts, optional) - Configuration options + +**Example:** +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +// Using environment variable +const sdk = new CodeSandbox(); + +// Using explicit token +const sdk = new CodeSandbox("csb_your_token_here"); + +// With options +const sdk = new CodeSandbox(process.env.CSB_API_KEY, { + apiUrl: "https://api.codesandbox.io", + tracer: myTracer +}); +``` + +## Properties + +### `sandboxes` + +**Type:** [`Sandboxes`](/api/core-classes/sandboxes) + +Provides access to sandbox management operations including creating, listing, getting, and forking sandboxes. + +**Example:** +```javascript +const sdk = new CodeSandbox(); + +// Create a new sandbox +const sandbox = await sdk.sandboxes.create(); + +// List existing sandboxes +const sandboxes = await sdk.sandboxes.list(); + +// Get a specific sandbox +const sandbox = await sdk.sandboxes.get("sandbox-id"); +``` + +### `hosts` + +**Type:** [`HostTokens`](/api/host-tokens/host-tokens) + +Provides access to host token management for generating signed URLs and headers for private sandboxes. + +**Example:** +```javascript +const sdk = new CodeSandbox(); + +// Create a host token +const hostToken = await sdk.hosts.create("sandbox-id", { + expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 hours +}); + +// List host tokens +const tokens = await sdk.hosts.list("sandbox-id"); +``` + +## Configuration Options + +### `ClientOpts` + +Configuration options for the CodeSandbox SDK. + +**Properties:** +- `apiUrl` (string, optional) - Custom API endpoint URL. Defaults to `https://api.codesandbox.io` +- `tracer` (Tracer, optional) - OpenTelemetry tracer for observability +- `timeout` (number, optional) - Request timeout in milliseconds + +**Example:** +```javascript +const sdk = new CodeSandbox(process.env.CSB_API_KEY, { + apiUrl: "https://your-enterprise.codesandbox.io/api", + timeout: 30000, // 30 seconds + tracer: myOpenTelemetryTracer +}); +``` + +## Environment Variables + +The SDK automatically detects these environment variables: + +### `CSB_API_KEY` + +Your CodeSandbox API token. Used automatically if no token is provided to the constructor. + +```bash +export CSB_API_KEY="csb_your_token_here" +``` + +### `CSB_API_URL` + +Custom API endpoint URL for enterprise installations. + +```bash +export CSB_API_URL="https://your-enterprise.codesandbox.io/api" +``` + +## Error Handling + +The CodeSandbox class will throw errors for: + +- **Invalid API token** - 401 Unauthorized +- **Insufficient permissions** - 403 Forbidden +- **Network issues** - Connection timeouts, DNS failures +- **API errors** - Server errors, rate limiting + +**Example:** +```javascript +try { + const sdk = new CodeSandbox("invalid-token"); + const sandbox = await sdk.sandboxes.create(); +} catch (error) { + if (error.status === 401) { + console.error("Invalid API token"); + } else if (error.status === 403) { + console.error("Insufficient permissions"); + } else { + console.error("API error:", error.message); + } +} +``` + +## Usage Patterns + +### Basic Usage + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +const sdk = new CodeSandbox(process.env.CSB_API_KEY); + +// Create and connect to a sandbox +const sandbox = await sdk.sandboxes.create({ + title: "My Development Environment" +}); + +const client = await sandbox.connect(); + +// Use the sandbox +const result = await client.commands.run("echo 'Hello World'"); +console.log(result.output); + +// Clean up +await client.disconnect(); +await sandbox.shutdown(); +``` + +### Enterprise Usage + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +const sdk = new CodeSandbox(process.env.CSB_API_KEY, { + apiUrl: "https://your-company.codesandbox.io/api", + timeout: 60000 // Longer timeout for enterprise +}); +``` + +### With Observability + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; +import { trace } from "@opentelemetry/api"; + +const tracer = trace.getTracer("my-app"); + +const sdk = new CodeSandbox(process.env.CSB_API_KEY, { + tracer: tracer +}); + +// All SDK operations will be traced +const sandbox = await sdk.sandboxes.create(); +``` + +## TypeScript Support + +The CodeSandbox class is fully typed: + +```typescript +import { CodeSandbox, ClientOpts, Sandbox } from "@codesandbox/sdk"; + +const opts: ClientOpts = { + apiUrl: "https://api.codesandbox.io", + timeout: 30000 +}; + +const sdk: CodeSandbox = new CodeSandbox(process.env.CSB_API_KEY, opts); +const sandbox: Sandbox = await sdk.sandboxes.create(); +``` + +## Related + +- [`Sandboxes`](/api/core-classes/sandboxes) - Sandbox management operations +- [`HostTokens`](/api/host-tokens/host-tokens) - Host token management +- [Quick Start Guide](/guides/getting-started/quick-start) - Getting started tutorial +- [Authentication](/guides/getting-started/authentication) - Authentication setup diff --git a/docs/cli/overview.md b/docs/cli/overview.md new file mode 100644 index 0000000..ad43a56 --- /dev/null +++ b/docs/cli/overview.md @@ -0,0 +1,284 @@ +# CLI Overview + +The CodeSandbox SDK includes a powerful command-line interface (CLI) for managing sandboxes, building projects, and working with host tokens. + +## Installation + +The CLI is included when you install the SDK: + +```bash +npm install -g @codesandbox/sdk +``` + +Or use it locally in your project: + +```bash +npm install @codesandbox/sdk +npx csb --help +``` + +## Authentication + +Set your API token as an environment variable: + +```bash +export CSB_API_KEY="your-api-token-here" +``` + +Or create a `.env` file: + +```bash +# .env +CSB_API_KEY=your-api-token-here +``` + +## Interactive Mode + +Run `csb` without any arguments to enter interactive mode: + +```bash +csb +``` + +This launches a full-screen dashboard where you can: + +- **View running sandboxes** with real-time status +- **Navigate between sandboxes** using arrow keys +- **Connect to sandbox terminals** directly +- **Monitor resource usage** and performance +- **Manage sandbox lifecycle** (hibernate, shutdown) + +### Interactive Mode Features + +- **Real-time updates** - Sandbox status updates automatically +- **Keyboard shortcuts** - Efficient navigation and control +- **Terminal integration** - Direct access to sandbox terminals +- **Resource monitoring** - CPU, memory, and storage usage +- **Bulk operations** - Select and manage multiple sandboxes + +## Command-Line Mode + +Use specific commands for automation and scripting: + +```bash +csb [options] +``` + +## Available Commands + +### Sandbox Management + +```bash +# List all sandboxes +csb sandboxes list + +# List with filtering +csb sandboxes list --tags development --status running + +# Fork a sandbox +csb sandboxes fork + +# Hibernate sandboxes +csb sandboxes hibernate +csb sandboxes hibernate < sandbox-ids.txt # Bulk hibernation + +# Shutdown sandboxes +csb sandboxes shutdown +csb sandboxes shutdown < sandbox-ids.txt # Bulk shutdown +``` + +### Project Building + +```bash +# Build and deploy current directory +csb build . + +# Build with custom name and VM tier +csb build . --name "My App" --vm-tier SMALL + +# Build for CI/CD +csb build . --ci --log-path ./build.log +``` + +### Host Token Management + +```bash +# List host tokens for a sandbox +csb host-tokens list + +# Create a host token +csb host-tokens create --expires-at 2024-12-31T23:59:59Z + +# Update token expiration +csb host-tokens update --expires-at 2024-12-31T23:59:59Z + +# Revoke a specific token +csb host-tokens revoke + +# Revoke all tokens +csb host-tokens revoke --all +``` + +## Global Options + +All commands support these global options: + +- `--help` - Show command help +- `--version` - Show CLI version +- `--api-key ` - Override API token +- `--api-url ` - Custom API endpoint (for enterprise) + +## Output Formats + +### JSON Output + +Most commands support JSON output for scripting: + +```bash +csb sandboxes list --output json | jq '.[] | .id' +``` + +### Custom Fields + +Specify which fields to display: + +```bash +csb sandboxes list --output id,title,status,createdAt +``` + +### No Headers + +Remove headers for cleaner output: + +```bash +csb sandboxes list --no-headers +``` + +## Scripting and Automation + +### Bash Integration + +```bash +#!/bin/bash + +# Get all running sandbox IDs +RUNNING_SANDBOXES=$(csb sandboxes list --status running --output id --no-headers) + +# Hibernate all running sandboxes +echo "$RUNNING_SANDBOXES" | csb sandboxes hibernate +``` + +### CI/CD Integration + +```yaml +# GitHub Actions example +- name: Build and deploy + run: | + csb build . --ci --name "PR-${{ github.event.number }}" + env: + CSB_API_KEY: ${{ secrets.CSB_API_KEY }} +``` + +### Bulk Operations + +```bash +# Create a list of sandbox IDs to process +csb sandboxes list --tags "cleanup" --output id --no-headers > cleanup-list.txt + +# Shutdown all sandboxes in the list +csb sandboxes shutdown < cleanup-list.txt +``` + +## Configuration + +### Environment Variables + +- `CSB_API_KEY` - Your CodeSandbox API token +- `CSB_API_URL` - Custom API endpoint (enterprise) +- `CSB_DEFAULT_VM_TIER` - Default VM tier for new sandboxes + +### Config File + +Create a `.csbrc` file in your home directory: + +```json +{ + "apiUrl": "https://your-enterprise.codesandbox.io/api", + "defaultVmTier": "SMALL", + "timeout": 30000 +} +``` + +## Error Handling + +The CLI provides detailed error messages and exit codes: + +```bash +csb sandboxes list +echo $? # 0 for success, non-zero for errors +``` + +Common exit codes: +- `0` - Success +- `1` - General error +- `2` - Authentication error +- `3` - Network error +- `4` - Resource not found + +## Debugging + +Enable debug output: + +```bash +DEBUG=csb:* csb sandboxes list +``` + +Or for specific components: + +```bash +DEBUG=csb:api csb sandboxes create +``` + +## Examples + +### Development Workflow + +```bash +# Create a development sandbox +csb build . --name "Feature Branch" --tags development + +# List development sandboxes +csb sandboxes list --tags development + +# Clean up old development sandboxes +csb sandboxes list --tags development --since "7 days ago" --output id --no-headers | \ + csb sandboxes shutdown +``` + +### Production Deployment + +```bash +# Build for production +csb build . --name "Production v1.2.3" --vm-tier LARGE --ci + +# Create host tokens for external access +csb host-tokens create $SANDBOX_ID --expires-at "2024-12-31T23:59:59Z" +``` + +### Monitoring and Maintenance + +```bash +# Check running sandboxes +csb sandboxes list --status running + +# Hibernate idle sandboxes (older than 1 hour) +csb sandboxes list --status running --since "1 hour ago" --output id --no-headers | \ + csb sandboxes hibernate +``` + +## Next Steps + +- Learn about [Interactive Mode](/cli/interactive) in detail +- Explore [Build Command](/cli/build) options +- Check out [Sandbox Management](/cli/sandboxes) commands +- See [Host Token Management](/cli/host-tokens) for access control diff --git a/docs/guides/core-concepts/lifecycle.md b/docs/guides/core-concepts/lifecycle.md new file mode 100644 index 0000000..a6dbeff --- /dev/null +++ b/docs/guides/core-concepts/lifecycle.md @@ -0,0 +1,331 @@ +# Sandbox Lifecycle + +Understanding the complete lifecycle of a CodeSandbox sandbox from creation to cleanup. + +## Lifecycle Overview + +```mermaid +graph TD + A[Create Sandbox] --> B[Initializing] + B --> C[Running] + C --> D{User Action} + D -->|Disconnect| E[Hibernated] + D -->|Shutdown| F[Terminated] + E -->|Reconnect| C + F --> G[Destroyed] + C -->|Timeout| E + E -->|Timeout| F +``` + +## Creation Phase + +### Basic Creation + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +const sdk = new CodeSandbox(process.env.CSB_API_KEY); + +// Create a new sandbox +const sandbox = await sdk.sandboxes.create({ + title: "My Development Environment", + // Optional: specify template, VM tier, etc. +}); + +console.log(`Created sandbox: ${sandbox.id}`); +``` + +### Advanced Creation Options + +```javascript +const sandbox = await sdk.sandboxes.create({ + title: "Full-Stack App", + vmTier: "SMALL", // More resources + source: { + type: "git", + url: "https://github.com/user/repo.git", + branch: "main" + }, + // Environment setup + environment: { + NODE_ENV: "development" + } +}); +``` + +## Initialization Phase + +After creation, the sandbox goes through initialization: + +```javascript +const client = await sandbox.connect(); + +// Monitor initialization progress +client.setup.onSetupProgressUpdate((progress) => { + console.log(`Setup progress: ${progress.completed}/${progress.total}`); + + progress.steps.forEach(step => { + console.log(`${step.name}: ${step.status}`); + }); +}); + +// Wait for setup to complete +await client.setup.waitForCompletion(); +console.log("Sandbox is ready!"); +``` + +## Active Phase + +### Connection Management + +```javascript +// Connect to the sandbox +const client = await sandbox.connect(); + +// Monitor connection state +client.onStateChange((state) => { + console.log(`Connection state: ${state}`); + // States: "CONNECTED", "DISCONNECTED", "HIBERNATED" +}); + +// Check if sandbox agent is up to date +if (!client.isUpToDate) { + console.log("Sandbox agent needs update - restart recommended"); +} +``` + +### Keep-Alive Management + +```javascript +// Prevent automatic hibernation +client.keepActiveWhileConnected(true); + +// The sandbox will stay active as long as the client is connected +// Automatically sends keep-alive signals every 10 seconds + +// Disable keep-alive (allow hibernation) +client.keepActiveWhileConnected(false); +``` + +## Hibernation + +### Automatic Hibernation + +Sandboxes automatically hibernate after a period of inactivity: + +- **Default timeout**: 30 minutes of inactivity +- **Configurable**: Can be adjusted per sandbox +- **State preservation**: All files and processes are preserved + +### Manual Hibernation + +```javascript +// Gracefully disconnect +await client.disconnect(); + +// Hibernate the sandbox +await sandbox.hibernate(); + +console.log("Sandbox hibernated - resources freed but state preserved"); +``` + +### Resuming from Hibernation + +```javascript +// Resume a hibernated sandbox +const client = await sandbox.connect(); + +// The sandbox will wake up and restore its previous state +// Files, environment variables, and process state are preserved +console.log("Sandbox resumed from hibernation"); +``` + +## Reconnection Handling + +### Automatic Reconnection + +The SDK handles reconnection automatically: + +```javascript +const client = await sandbox.connect(); + +// Automatic reconnection on network issues +client.onStateChange((state) => { + if (state === "DISCONNECTED") { + console.log("Connection lost - attempting to reconnect..."); + } else if (state === "CONNECTED") { + console.log("Reconnected successfully!"); + } +}); +``` + +### Manual Reconnection + +```javascript +try { + await client.reconnect(); + console.log("Manual reconnection successful"); +} catch (error) { + console.error("Reconnection failed:", error); +} +``` + +### Browser-Specific Reconnection + +In browsers, reconnection happens automatically when the tab regains focus: + +```javascript +import { connectToSandbox } from "@codesandbox/sdk/browser"; + +const client = await connectToSandbox({ + session: sandboxSession, + getSession: async (id) => await resumeSandbox(id), + // Automatic reconnection on focus + onFocusChange: (notify) => { + const listener = () => notify(document.hasFocus()); + window.addEventListener("visibilitychange", listener); + return () => window.removeEventListener("visibilitychange", listener); + } +}); +``` + +## Shutdown and Cleanup + +### Graceful Shutdown + +```javascript +// Disconnect the client first +await client.disconnect(); + +// Shutdown the sandbox (permanent) +await sandbox.shutdown(); + +console.log("Sandbox shut down - all resources freed"); +``` + +### Resource Cleanup + +```javascript +// Always dispose of clients when done +client.dispose(); + +// This will: +// - Close all WebSocket connections +// - Clean up event listeners +// - Free memory resources +``` + +### Bulk Operations + +```javascript +// Shutdown multiple sandboxes +const sandboxes = await sdk.sandboxes.list({ status: "running" }); + +for (const sandbox of sandboxes) { + await sandbox.shutdown(); +} + +console.log(`Shut down ${sandboxes.length} sandboxes`); +``` + +## Error Handling Throughout Lifecycle + +### Connection Errors + +```javascript +try { + const client = await sandbox.connect(); +} catch (error) { + if (error.code === "SANDBOX_NOT_FOUND") { + console.error("Sandbox was deleted"); + } else if (error.code === "CONNECTION_TIMEOUT") { + console.error("Connection timed out - sandbox may be starting"); + } else { + console.error("Connection failed:", error.message); + } +} +``` + +### Operation Errors + +```javascript +client.onStateChange((state) => { + if (state === "HIBERNATED") { + console.log("Sandbox hibernated - operations will fail until reconnected"); + } +}); + +try { + await client.commands.run("echo 'test'"); +} catch (error) { + if (client.state === "HIBERNATED") { + console.log("Reconnecting hibernated sandbox..."); + await client.reconnect(); + // Retry the operation + await client.commands.run("echo 'test'"); + } +} +``` + +## Lifecycle Best Practices + +### 1. Always Handle State Changes + +```javascript +const client = await sandbox.connect(); + +client.onStateChange((state) => { + switch (state) { + case "CONNECTED": + console.log("Ready for operations"); + break; + case "DISCONNECTED": + console.log("Connection lost - operations will fail"); + break; + case "HIBERNATED": + console.log("Sandbox hibernated - call reconnect() to resume"); + break; + } +}); +``` + +### 2. Implement Retry Logic + +```javascript +async function runCommandWithRetry(client, command, maxRetries = 3) { + for (let i = 0; i < maxRetries; i++) { + try { + if (client.state === "HIBERNATED") { + await client.reconnect(); + } + return await client.commands.run(command); + } catch (error) { + if (i === maxRetries - 1) throw error; + await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); + } + } +} +``` + +### 3. Clean Up Resources + +```javascript +// Use try/finally to ensure cleanup +let client; +try { + client = await sandbox.connect(); + await client.commands.run("npm install"); + // ... other operations +} finally { + if (client) { + await client.disconnect(); + client.dispose(); + } +} +``` + +## Next Steps + +- Learn about [VM Tiers & Resources](/guides/core-concepts/vm-tiers) +- Explore [Basic Operations](/guides/sdk-usage/basic-operations) +- Check out [Error Handling](/guides/best-practices/error-handling) best practices diff --git a/docs/guides/core-concepts/sandboxes.md b/docs/guides/core-concepts/sandboxes.md new file mode 100644 index 0000000..8d78373 --- /dev/null +++ b/docs/guides/core-concepts/sandboxes.md @@ -0,0 +1,247 @@ +# Understanding Sandboxes + +Learn about CodeSandbox microVMs and how they provide secure, isolated environments for code execution. + +## What are CodeSandbox Sandboxes? + +CodeSandbox sandboxes are lightweight microVMs that provide: + +- **Isolated environments** for running untrusted code safely +- **Full Linux environments** with complete file system access +- **Persistent storage** that survives hibernation +- **Network access** with configurable port forwarding +- **Snapshotting capabilities** for instant environment restoration + +## Sandbox Architecture + +### MicroVM Infrastructure + +Each sandbox runs in its own microVM with: + +``` +┌─────────────────────────────────────┐ +│ Sandbox (microVM) │ +├─────────────────────────────────────┤ +│ ┌─────────────┐ ┌─────────────┐ │ +│ │ File System │ │ Network │ │ +│ │ │ │ Stack │ │ +│ └─────────────┘ └─────────────┘ │ +├─────────────────────────────────────┤ +│ ┌─────────────┐ ┌─────────────┐ │ +│ │ Terminals │ │ Processes │ │ +│ │ │ │ │ │ +│ └─────────────┘ └─────────────┘ │ +└─────────────────────────────────────┘ +``` + +### Resource Isolation + +- **CPU**: Dedicated CPU allocation based on VM tier +- **Memory**: Isolated memory space (512MB to 32GB) +- **Storage**: Persistent disk storage (up to 20GB) +- **Network**: Isolated network namespace with port forwarding + +## Sandbox States + +Sandboxes have several states throughout their lifecycle: + +### Creating +The sandbox is being provisioned and initialized. + +```javascript +const sandbox = await sdk.sandboxes.create(); +// Sandbox is in "creating" state +``` + +### Running +The sandbox is active and ready for connections. + +```javascript +const client = await sandbox.connect(); +// Sandbox is now "running" +``` + +### Hibernated +The sandbox is paused to save resources but maintains state. + +```javascript +await sandbox.hibernate(); +// Sandbox is "hibernated" - can be resumed quickly +``` + +### Shutdown +The sandbox is completely stopped and resources are freed. + +```javascript +await sandbox.shutdown(); +// Sandbox is "shutdown" - cannot be resumed +``` + +## Sandbox Properties + +### Basic Information + +```javascript +const sandbox = await sdk.sandboxes.get("sandbox-id"); + +console.log({ + id: sandbox.id, + title: sandbox.title, + privacy: sandbox.privacy, // "public" or "private" + tags: sandbox.tags, + createdAt: sandbox.createdAt, + updatedAt: sandbox.updatedAt +}); +``` + +### Runtime Information + +```javascript +const client = await sandbox.connect(); + +console.log({ + state: client.state, // "CONNECTED", "DISCONNECTED", "HIBERNATED" + workspacePath: client.workspacePath, // "/project" + editorUrl: client.editorUrl, // Browser editor URL + isUpToDate: client.isUpToDate // Agent version status +}); +``` + +## Sandbox Templates + +### Using Default Templates + +```javascript +// Create from default Node.js template +const sandbox = await sdk.sandboxes.create({ + title: "My Node.js App" +}); +``` + +### Using Custom Templates + +```javascript +// Create from your custom template +const sandbox = await sdk.sandboxes.create({ + title: "My Custom App", + templateId: "your-template-id" +}); +``` + +### Creating from Git Repositories + +```javascript +const sandbox = await sdk.sandboxes.create({ + title: "GitHub Project", + source: { + type: "git", + url: "https://github.com/user/repo.git", + branch: "main" + } +}); +``` + +## Sandbox Networking + +### Port Management + +Sandboxes can expose services on various ports: + +```javascript +const client = await sandbox.connect(); + +// List open ports +const ports = await client.ports.list(); + +// Get preview URL for a port +const previewUrl = await client.ports.getPreviewUrl(3000); +console.log(`App running at: ${previewUrl}`); +``` + +### Preview URLs + +Preview URLs allow external access to sandbox services: + +- **Public sandboxes**: Direct preview URLs +- **Private sandboxes**: Require host tokens for access + +## Sandbox Persistence + +### File System Persistence + +Files written to the sandbox persist across hibernation: + +```javascript +const client = await sandbox.connect(); + +// Write a file +await client.fs.writeFile("/project/data.txt", "Hello World"); + +// Hibernate the sandbox +await client.disconnect(); +await sandbox.hibernate(); + +// Resume and read the file +const newClient = await sandbox.connect(); +const content = await newClient.fs.readFile("/project/data.txt"); +console.log(content); // "Hello World" +``` + +### Process State + +Running processes are paused during hibernation and resumed when the sandbox wakes up. + +## Sandbox Limits + +### Resource Limits + +Different VM tiers have different limits: + +| Tier | CPU | Memory | Storage | Network | +|------|-----|--------|---------|---------| +| Nano | 0.5 vCPU | 512MB | 5GB | 1Gbps | +| Micro | 1 vCPU | 2GB | 10GB | 1Gbps | +| Small | 2 vCPU | 4GB | 20GB | 1Gbps | +| Medium | 4 vCPU | 8GB | 20GB | 1Gbps | +| Large | 8 vCPU | 16GB | 20GB | 1Gbps | +| XLarge | 16 vCPU | 32GB | 20GB | 1Gbps | + +### Usage Limits + +- **Concurrent sandboxes**: Based on your workspace plan +- **Monthly usage**: CPU-hours and storage limits +- **Hibernation timeout**: Automatic hibernation after inactivity + +## Security Model + +### Isolation Guarantees + +- **Process isolation**: Sandboxes cannot access each other +- **Network isolation**: Controlled network access +- **File system isolation**: Separate file systems per sandbox +- **Resource isolation**: CPU and memory limits enforced + +### Safe Code Execution + +Perfect for running untrusted code: + +```javascript +const client = await sandbox.connect(); + +// Safely execute user-provided code +const result = await client.commands.run(` + python3 -c " + import sys + print('User code executed safely') + print(f'Python version: {sys.version}') + " +`); + +console.log(result.output); +``` + +## Next Steps + +- Learn about [Sandbox Lifecycle](/guides/core-concepts/lifecycle) +- Understand [VM Tiers & Resources](/guides/core-concepts/vm-tiers) +- Explore [Basic Operations](/guides/sdk-usage/basic-operations) diff --git a/docs/guides/getting-started/authentication.md b/docs/guides/getting-started/authentication.md new file mode 100644 index 0000000..dd41abb --- /dev/null +++ b/docs/guides/getting-started/authentication.md @@ -0,0 +1,163 @@ +# Authentication + +Learn how to authenticate with the CodeSandbox SDK and manage API tokens securely. + +## API Token Creation + +1. Visit [https://codesandbox.io/t/api](https://codesandbox.io/t/api) +2. Click "Create API Token" +3. Give your token a descriptive name +4. Copy the generated token (you won't be able to see it again) + +## Setting Up Authentication + +### Environment Variables (Recommended) + +Set your API token as an environment variable: + +```bash +export CSB_API_KEY="csb_your_token_here" +``` + +The SDK will automatically detect and use this token: + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +// Automatically uses CSB_API_KEY environment variable +const sdk = new CodeSandbox(); +``` + +### Direct Token Passing + +You can also pass the token directly: + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +const sdk = new CodeSandbox("csb_your_token_here"); +``` + +### Configuration File + +For development, you can use a `.env` file: + +```bash +# .env +CSB_API_KEY=csb_your_token_here +``` + +Then load it in your application: + +```javascript +import dotenv from 'dotenv'; +dotenv.config(); + +import { CodeSandbox } from "@codesandbox/sdk"; +const sdk = new CodeSandbox(); // Uses process.env.CSB_API_KEY +``` + +## Token Security + +### Best Practices + +- **Never commit tokens to version control** +- **Use environment variables in production** +- **Rotate tokens regularly** +- **Use different tokens for different environments** + +### Token Scopes + +API tokens have access to: +- Create and manage sandboxes in your workspace +- Access private sandboxes +- Generate host tokens for preview URLs +- All sandbox operations (files, commands, terminals, etc.) + +## Workspace Integration + +Your API token is tied to your CodeSandbox workspace: + +- **Billing**: All sandbox usage is billed to your workspace +- **Resources**: Sandboxes count against your workspace limits +- **Privacy**: Private sandboxes remain private to your workspace +- **Templates**: You can use your workspace templates + +## Host Tokens + +For accessing private sandboxes from external applications, you'll need host tokens: + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +const sdk = new CodeSandbox(process.env.CSB_API_KEY); + +// Create a host token for a private sandbox +const hostToken = await sdk.hosts.create("sandbox-id", { + expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 hours +}); + +// Use the host token to access the sandbox +const previewUrl = `https://codesandbox.io/p/devbox/${sandboxId}?token=${hostToken.token}`; +``` + +## Error Handling + +Handle authentication errors gracefully: + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +try { + const sdk = new CodeSandbox(process.env.CSB_API_KEY); + const sandbox = await sdk.sandboxes.create(); +} catch (error) { + if (error.status === 401) { + console.error("Invalid API token. Please check your CSB_API_KEY"); + } else if (error.status === 403) { + console.error("Insufficient permissions. Check your workspace access"); + } else { + console.error("Authentication error:", error.message); + } +} +``` + +## Token Management + +### Listing Active Tokens + +Currently, token management is done through the CodeSandbox dashboard at [https://codesandbox.io/t/api](https://codesandbox.io/t/api). + +### Revoking Tokens + +To revoke a token: +1. Go to [https://codesandbox.io/t/api](https://codesandbox.io/t/api) +2. Find the token you want to revoke +3. Click "Revoke" + +### Token Rotation + +For security, regularly rotate your API tokens: + +1. Create a new token +2. Update your environment variables +3. Test the new token +4. Revoke the old token + +## Enterprise Authentication + +For CodeSandbox Enterprise customers: + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +const sdk = new CodeSandbox(process.env.CSB_API_KEY, { + apiUrl: "https://your-enterprise-domain.codesandbox.io/api" +}); +``` + +## Next Steps + +- Learn about [Understanding Sandboxes](/guides/core-concepts/sandboxes) +- Explore [Basic Operations](/guides/sdk-usage/basic-operations) +- Check out [Host Tokens](/api/host-tokens/host-tokens) for advanced access control diff --git a/docs/guides/getting-started/platform-setup.md b/docs/guides/getting-started/platform-setup.md new file mode 100644 index 0000000..3186fac --- /dev/null +++ b/docs/guides/getting-started/platform-setup.md @@ -0,0 +1,164 @@ +# Platform Setup + +The CodeSandbox SDK supports both Node.js and browser environments with platform-specific optimizations. + +## Node.js Setup + +### Requirements + +- Node.js 16+ +- npm or yarn package manager + +### Installation + +```bash +npm install @codesandbox/sdk +``` + +### Basic Node.js Usage + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; +// or +const { CodeSandbox } = require("@codesandbox/sdk"); + +const sdk = new CodeSandbox(process.env.CSB_API_KEY); +``` + +### Node.js-Specific Features + +The Node.js build includes additional features: + +```javascript +import { connectToSandbox } from "@codesandbox/sdk/node"; + +const client = await connectToSandbox({ + session: sandboxSession, + getSession: async (id) => await resumeSandbox(id), + // Node.js specific: no focus change handling needed +}); +``` + +## Browser Setup + +### Installation + +```bash +npm install @codesandbox/sdk +``` + +### Browser Usage + +```javascript +import { connectToSandbox, createPreview } from "@codesandbox/sdk/browser"; + +const client = await connectToSandbox({ + session: sandboxSession, + getSession: async (id) => await resumeSandbox(id), + // Browser-specific: automatic reconnection on focus + onFocusChange: (notify) => { + const listener = () => notify(document.hasFocus()); + window.addEventListener("visibilitychange", listener); + return () => window.removeEventListener("visibilitychange", listener); + } +}); +``` + +### Browser-Specific Features + +#### Preview Management + +```javascript +import { createPreview } from "@codesandbox/sdk/browser"; + +const preview = createPreview({ + sandboxId: "your-sandbox-id", + port: 3000, + // Preview-specific configuration +}); + +preview.on("ready", () => { + console.log("Preview is ready"); +}); +``` + +#### Automatic Reconnection + +The browser build automatically handles: +- Reconnection when the tab regains focus +- Connection state management during tab switching +- Optimized WebSocket handling for browser environments + +## Environment Variables + +Both platforms support these environment variables: + +```bash +# Required: Your CodeSandbox API token +CSB_API_KEY="your-api-token" + +# Optional: Custom API endpoint (for enterprise) +CSB_API_URL="https://api.codesandbox.io" +``` + +## TypeScript Support + +The SDK includes full TypeScript definitions: + +```typescript +import { CodeSandbox, SandboxClient, VMTier } from "@codesandbox/sdk"; + +const sdk = new CodeSandbox(process.env.CSB_API_KEY); + +// Type-safe sandbox creation +const sandbox = await sdk.sandboxes.create({ + title: "My Sandbox", + vmTier: VMTier.NANO +}); + +// Type-safe client usage +const client: SandboxClient = await sandbox.connect(); +``` + +## Build Tools Integration + +### Webpack + +```javascript +// webpack.config.js +module.exports = { + resolve: { + fallback: { + "buffer": require.resolve("buffer"), + "crypto": require.resolve("crypto-browserify"), + "path": require.resolve("path-browserify"), + "os": require.resolve("os-browserify/browser") + } + } +}; +``` + +### Vite + +```javascript +// vite.config.js +export default { + define: { + global: 'globalThis', + }, + resolve: { + alias: { + buffer: 'buffer', + }, + }, + optimizeDeps: { + include: ['buffer'], + }, +}; +``` + +## Next Steps + +- Learn about [Authentication](/guides/getting-started/authentication) +- Explore [Basic Operations](/guides/sdk-usage/basic-operations) +- Check out [Browser Integration](/guides/advanced/browser) for advanced browser features diff --git a/docs/guides/getting-started/quick-start.md b/docs/guides/getting-started/quick-start.md new file mode 100644 index 0000000..3306f2e --- /dev/null +++ b/docs/guides/getting-started/quick-start.md @@ -0,0 +1,81 @@ +# Quick Start + +Get up and running with the CodeSandbox SDK in minutes. + +## Installation + +Install the SDK using npm: + +```bash +npm install @codesandbox/sdk +``` + +## Authentication + +Create an API token by visiting [https://codesandbox.io/t/api](https://codesandbox.io/t/api) and clicking "Create API Token". + +Set your API token as an environment variable: + +```bash +export CSB_API_KEY="your-api-token-here" +``` + +## Basic Usage + +Here's a simple example to create a sandbox and run a command: + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +// Initialize the SDK +const sdk = new CodeSandbox(process.env.CSB_API_KEY); + +// Create a new sandbox +const sandbox = await sdk.sandboxes.create(); +console.log(`Created sandbox: ${sandbox.id}`); + +// Connect to the sandbox +const client = await sandbox.connect(); + +// Run a command +const output = await client.commands.run("echo 'Hello World'"); +console.log(output); // Hello World + +// Clean up +await client.disconnect(); +``` + +## Browser Usage + +For browser environments, use the browser-specific build: + +```javascript +import { connectToSandbox } from "@codesandbox/sdk/browser"; + +const client = await connectToSandbox({ + session: yourSandboxSession, + getSession: async (id) => { + // Your session retrieval logic + return await fetchSession(id); + } +}); + +const output = await client.commands.run("ls -la"); +console.log(output); +``` + +## Next Steps + +- Learn about [Platform Setup](/guides/getting-started/platform-setup) for Node.js and browser environments +- Understand [Authentication](/guides/getting-started/authentication) in detail +- Explore [Basic Operations](/guides/sdk-usage/basic-operations) for common SDK patterns + +## Common Use Cases + +The CodeSandbox SDK is perfect for: + +- **AI Agents**: Run code safely in isolated environments +- **Code Interpretation**: Execute untrusted user code securely +- **Development Environments**: Spin up consistent dev environments +- **CI/CD**: Run tests and builds in reproducible containers +- **Educational Platforms**: Provide interactive coding environments diff --git a/docs/guides/sdk-usage/basic-operations.md b/docs/guides/sdk-usage/basic-operations.md new file mode 100644 index 0000000..0d89d38 --- /dev/null +++ b/docs/guides/sdk-usage/basic-operations.md @@ -0,0 +1,402 @@ +# Basic Operations + +Learn the fundamental operations for working with CodeSandbox sandboxes through the SDK. + +## Creating Sandboxes + +### Simple Creation + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +const sdk = new CodeSandbox(process.env.CSB_API_KEY); + +// Create with minimal configuration +const sandbox = await sdk.sandboxes.create(); +console.log(`Created sandbox: ${sandbox.id}`); +``` + +### Creation with Options + +```javascript +const sandbox = await sdk.sandboxes.create({ + title: "My Development Environment", + privacy: "private", // or "public" + tags: ["development", "nodejs"], + vmTier: "SMALL" +}); +``` + +### Creating from Templates + +```javascript +// Use a specific template +const sandbox = await sdk.sandboxes.create({ + title: "React App", + templateId: "react-typescript" +}); + +// Create from Git repository +const sandbox = await sdk.sandboxes.create({ + title: "GitHub Project", + source: { + type: "git", + url: "https://github.com/user/repo.git", + branch: "main" + } +}); +``` + +## Connecting to Sandboxes + +### Basic Connection + +```javascript +// Connect to a newly created sandbox +const client = await sandbox.connect(); + +// Or connect to an existing sandbox by ID +const existingSandbox = await sdk.sandboxes.get("sandbox-id"); +const client2 = await existingSandbox.connect(); +``` + +### Connection with Monitoring + +```javascript +const client = await sandbox.connect(); + +// Monitor connection state +client.onStateChange((state) => { + console.log(`Connection state changed to: ${state}`); +}); + +// Check current state +console.log(`Current state: ${client.state}`); +``` + +## Listing and Retrieving Sandboxes + +### List All Sandboxes + +```javascript +const sandboxes = await sdk.sandboxes.list(); +console.log(`Found ${sandboxes.length} sandboxes`); + +sandboxes.forEach(sandbox => { + console.log(`${sandbox.title} (${sandbox.id})`); +}); +``` + +### Filtered Listing + +```javascript +// Filter by tags +const devSandboxes = await sdk.sandboxes.list({ + tags: ["development"] +}); + +// Filter by status +const runningSandboxes = await sdk.sandboxes.list({ + status: "running" +}); + +// Pagination +const page1 = await sdk.sandboxes.list({ + pagination: { page: 1, pageSize: 10 } +}); +``` + +### Efficient Single Retrieval + +```javascript +// More efficient than listing and filtering +const sandbox = await sdk.sandboxes.get("specific-sandbox-id"); +console.log(sandbox.title, sandbox.tags); +``` + +## Forking Sandboxes + +### Basic Forking + +```javascript +// Fork an existing sandbox +const originalSandbox = await sdk.sandboxes.get("original-id"); +const forkedSandbox = await sdk.sandboxes.fork(originalSandbox.id); + +console.log(`Forked ${originalSandbox.title} to ${forkedSandbox.id}`); +``` + +### Forking with Customization + +```javascript +const forkedSandbox = await sdk.sandboxes.fork("original-id", { + title: "My Fork of Original", + privacy: "private" +}); +``` + +## Basic File Operations + +### Reading Files + +```javascript +const client = await sandbox.connect(); + +// Read a single file +const packageJson = await client.fs.readFile("/project/package.json"); +console.log(JSON.parse(packageJson)); + +// Check if file exists +const exists = await client.fs.exists("/project/README.md"); +if (exists) { + const readme = await client.fs.readFile("/project/README.md"); + console.log(readme); +} +``` + +### Writing Files + +```javascript +// Write a new file +await client.fs.writeFile("/project/config.json", JSON.stringify({ + environment: "development", + debug: true +}, null, 2)); + +// Create a directory and file +await client.fs.createDir("/project/src/components"); +await client.fs.writeFile("/project/src/components/Button.tsx", ` +import React from 'react'; + +export const Button = ({ children, onClick }) => ( + +); +`); +``` + +### Directory Operations + +```javascript +// List directory contents +const files = await client.fs.readDir("/project"); +console.log("Project files:", files); + +// Create nested directories +await client.fs.createDir("/project/src/utils", { recursive: true }); + +// Remove files and directories +await client.fs.deleteFile("/project/temp.txt"); +await client.fs.deleteDir("/project/old-folder"); +``` + +## Running Commands + +### Simple Command Execution + +```javascript +const client = await sandbox.connect(); + +// Run a simple command +const result = await client.commands.run("ls -la"); +console.log(result.output); + +// Run with working directory +const result2 = await client.commands.run("npm install", { + cwd: "/project" +}); +``` + +### Command with Environment Variables + +```javascript +const result = await client.commands.run("node app.js", { + env: { + NODE_ENV: "development", + PORT: "3000" + } +}); +``` + +### Long-Running Commands + +```javascript +// Start a development server +const serverProcess = await client.commands.runInteractive("npm run dev", { + cwd: "/project" +}); + +// Listen for output +serverProcess.on("data", (data) => { + console.log("Server output:", data); +}); + +// Stop the server later +setTimeout(() => { + serverProcess.kill(); +}, 30000); +``` + +## Managing Sandbox State + +### Hibernation + +```javascript +// Disconnect client +await client.disconnect(); + +// Hibernate to save resources +await sandbox.hibernate(); +console.log("Sandbox hibernated"); + +// Resume later +const newClient = await sandbox.connect(); +console.log("Sandbox resumed"); +``` + +### Shutdown + +```javascript +// Graceful shutdown +await client.disconnect(); +await sandbox.shutdown(); +console.log("Sandbox shut down permanently"); +``` + +### Keep-Alive + +```javascript +const client = await sandbox.connect(); + +// Prevent automatic hibernation +client.keepActiveWhileConnected(true); + +// Your long-running operations here... + +// Allow hibernation again +client.keepActiveWhileConnected(false); +``` + +## Error Handling + +### Basic Error Handling + +```javascript +try { + const client = await sandbox.connect(); + const result = await client.commands.run("invalid-command"); +} catch (error) { + console.error("Operation failed:", error.message); + + if (error.code === "COMMAND_FAILED") { + console.error("Command stderr:", error.stderr); + } +} +``` + +### Connection Error Handling + +```javascript +const client = await sandbox.connect(); + +client.onStateChange((state) => { + if (state === "DISCONNECTED") { + console.log("Connection lost - operations will fail until reconnected"); + } +}); + +// Robust command execution +async function runCommandSafely(command) { + try { + if (client.state === "HIBERNATED") { + console.log("Reconnecting hibernated sandbox..."); + await client.reconnect(); + } + + return await client.commands.run(command); + } catch (error) { + if (error.code === "CONNECTION_LOST") { + console.log("Attempting to reconnect..."); + await client.reconnect(); + return await client.commands.run(command); + } + throw error; + } +} +``` + +## Resource Cleanup + +### Proper Cleanup + +```javascript +let client; +try { + client = await sandbox.connect(); + + // Your operations here + await client.commands.run("npm test"); + +} finally { + // Always clean up + if (client) { + await client.disconnect(); + client.dispose(); + } +} +``` + +### Bulk Cleanup + +```javascript +// Clean up multiple sandboxes +const sandboxes = await sdk.sandboxes.list({ + tags: ["temporary"] +}); + +for (const sandbox of sandboxes) { + try { + await sandbox.shutdown(); + console.log(`Cleaned up sandbox: ${sandbox.id}`); + } catch (error) { + console.error(`Failed to clean up ${sandbox.id}:`, error.message); + } +} +``` + +## Working with Multiple Sandboxes + +### Parallel Operations + +```javascript +// Create multiple sandboxes in parallel +const sandboxPromises = Array.from({ length: 3 }, (_, i) => + sdk.sandboxes.create({ + title: `Test Environment ${i + 1}`, + tags: ["test", "parallel"] + }) +); + +const sandboxes = await Promise.all(sandboxPromises); +console.log(`Created ${sandboxes.length} sandboxes`); + +// Connect to all sandboxes +const clients = await Promise.all( + sandboxes.map(sandbox => sandbox.connect()) +); + +// Run commands in parallel +const results = await Promise.all( + clients.map(client => client.commands.run("echo 'Hello from sandbox'")) +); + +// Clean up +await Promise.all(clients.map(client => client.disconnect())); +await Promise.all(sandboxes.map(sandbox => sandbox.shutdown())); +``` + +## Next Steps + +- Learn about [File System Operations](/guides/sdk-usage/filesystem) in detail +- Explore [Command Execution](/guides/sdk-usage/commands) patterns +- Check out [Terminal Management](/guides/sdk-usage/terminals) +- See [Use Cases](/guides/use-cases/ai-agents) for real-world examples diff --git a/docs/guides/use-cases/ai-agents.md b/docs/guides/use-cases/ai-agents.md new file mode 100644 index 0000000..8ac1f93 --- /dev/null +++ b/docs/guides/use-cases/ai-agents.md @@ -0,0 +1,538 @@ +# AI Agents & Code Interpretation + +Learn how to use CodeSandbox SDK for AI agents and safe code interpretation scenarios. + +## Overview + +The CodeSandbox SDK is perfect for AI applications that need to execute code safely: + +- **Isolated execution** - Run untrusted code without security risks +- **Multiple languages** - Support Python, Node.js, and more +- **Resource limits** - Control CPU, memory, and execution time +- **Output capture** - Get stdout, stderr, and file outputs +- **Persistent state** - Maintain context between executions + +## Basic Code Interpretation + +### Simple Code Execution + +```javascript +import { CodeSandbox } from "@codesandbox/sdk"; + +const sdk = new CodeSandbox(process.env.CSB_API_KEY); + +async function executeCode(code, language = "python") { + // Create a sandbox for code execution + const sandbox = await sdk.sandboxes.create({ + title: "Code Interpreter", + tags: ["ai", "code-execution"] + }); + + try { + const client = await sandbox.connect(); + + // Execute the code + const result = await client.commands.run(`${language} -c "${code}"`); + + return { + output: result.output, + error: result.error, + exitCode: result.exitCode + }; + } finally { + // Clean up + await sandbox.shutdown(); + } +} + +// Example usage +const pythonCode = ` +print("Hello from AI agent!") +import math +result = math.sqrt(16) +print(f"Square root of 16 is: {result}") +`; + +const result = await executeCode(pythonCode, "python3"); +console.log(result.output); +``` + +### Advanced Code Interpretation + +```javascript +class CodeInterpreter { + constructor(apiKey) { + this.sdk = new CodeSandbox(apiKey); + this.sandbox = null; + this.client = null; + } + + async initialize() { + // Create a persistent sandbox for the session + this.sandbox = await this.sdk.sandboxes.create({ + title: "AI Code Interpreter Session", + tags: ["ai", "persistent"], + vmTier: "SMALL" // More resources for complex operations + }); + + this.client = await this.sandbox.connect(); + + // Install common packages + await this.client.commands.run("pip install numpy pandas matplotlib requests", { + cwd: "/project" + }); + } + + async executeCode(code, language = "python3") { + if (!this.client) { + await this.initialize(); + } + + try { + // Write code to a file for better error handling + const filename = `code_${Date.now()}.py`; + await this.client.fs.writeFile(`/project/${filename}`, code); + + // Execute the code + const result = await this.client.commands.run(`${language} ${filename}`, { + cwd: "/project", + timeout: 30000 // 30 second timeout + }); + + // Clean up the file + await this.client.fs.deleteFile(`/project/${filename}`); + + return { + success: result.exitCode === 0, + output: result.output, + error: result.error, + exitCode: result.exitCode + }; + } catch (error) { + return { + success: false, + output: "", + error: error.message, + exitCode: -1 + }; + } + } + + async installPackage(packageName, language = "python") { + const commands = { + python: `pip install ${packageName}`, + node: `npm install ${packageName}`, + rust: `cargo add ${packageName}` + }; + + const command = commands[language]; + if (!command) { + throw new Error(`Unsupported language: ${language}`); + } + + return await this.client.commands.run(command, { cwd: "/project" }); + } + + async getFileContent(path) { + return await this.client.fs.readFile(path); + } + + async saveFile(path, content) { + return await this.client.fs.writeFile(path, content); + } + + async cleanup() { + if (this.client) { + await this.client.disconnect(); + } + if (this.sandbox) { + await this.sandbox.shutdown(); + } + } +} +``` + +## AI Agent Integration + +### OpenAI Integration Example + +```javascript +import OpenAI from "openai"; +import { CodeSandbox } from "@codesandbox/sdk"; + +class AICodeAgent { + constructor(openaiKey, csbKey) { + this.openai = new OpenAI({ apiKey: openaiKey }); + this.interpreter = new CodeInterpreter(csbKey); + } + + async processQuery(userQuery) { + // Get code from AI + const response = await this.openai.chat.completions.create({ + model: "gpt-4", + messages: [ + { + role: "system", + content: "You are a helpful assistant that writes Python code to solve problems. Only return the code, no explanations." + }, + { + role: "user", + content: userQuery + } + ] + }); + + const code = response.choices[0].message.content; + + // Execute the code safely + const result = await this.interpreter.executeCode(code); + + if (result.success) { + return { + code: code, + output: result.output, + success: true + }; + } else { + // Try to fix the error with AI + const fixResponse = await this.openai.chat.completions.create({ + model: "gpt-4", + messages: [ + { + role: "system", + content: "Fix the following Python code based on the error message. Only return the corrected code." + }, + { + role: "user", + content: `Code: ${code}\nError: ${result.error}` + } + ] + }); + + const fixedCode = fixResponse.choices[0].message.content; + const fixedResult = await this.interpreter.executeCode(fixedCode); + + return { + code: fixedCode, + output: fixedResult.output, + success: fixedResult.success, + wasFixed: true + }; + } + } + + async cleanup() { + await this.interpreter.cleanup(); + } +} + +// Usage +const agent = new AICodeAgent(process.env.OPENAI_API_KEY, process.env.CSB_API_KEY); + +const result = await agent.processQuery( + "Create a bar chart showing the population of the top 5 most populous countries" +); + +console.log("Generated code:", result.code); +console.log("Output:", result.output); + +await agent.cleanup(); +``` + +## Data Analysis Workflows + +### Jupyter-like Environment + +```javascript +class DataAnalysisEnvironment { + constructor(apiKey) { + this.sdk = new CodeSandbox(apiKey); + this.sandbox = null; + this.client = null; + this.cellHistory = []; + } + + async initialize() { + this.sandbox = await this.sdk.sandboxes.create({ + title: "Data Analysis Environment", + tags: ["data-science", "jupyter"], + vmTier: "MEDIUM" // More resources for data processing + }); + + this.client = await this.sandbox.connect(); + + // Install data science packages + await this.client.commands.run(` + pip install pandas numpy matplotlib seaborn jupyter plotly scikit-learn + `, { cwd: "/project" }); + + // Set up matplotlib for non-interactive use + await this.executeCell(` +import matplotlib +matplotlib.use('Agg') +import matplotlib.pyplot as plt +import pandas as pd +import numpy as np + `); + } + + async executeCell(code) { + const cellId = this.cellHistory.length; + const filename = `cell_${cellId}.py`; + + try { + // Add cell to history + this.cellHistory.push({ code, filename, timestamp: new Date() }); + + // Write code to file + await this.client.fs.writeFile(`/project/${filename}`, code); + + // Execute + const result = await this.client.commands.run(`python ${filename}`, { + cwd: "/project" + }); + + // Check for generated plots + const plotFiles = await this.findGeneratedPlots(); + + return { + cellId, + success: result.exitCode === 0, + output: result.output, + error: result.error, + plots: plotFiles + }; + } catch (error) { + return { + cellId, + success: false, + output: "", + error: error.message, + plots: [] + }; + } + } + + async findGeneratedPlots() { + try { + const files = await this.client.fs.readDir("/project"); + return files.filter(file => + file.endsWith('.png') || + file.endsWith('.jpg') || + file.endsWith('.svg') + ); + } catch { + return []; + } + } + + async getPlot(filename) { + return await this.client.fs.readFile(`/project/${filename}`); + } + + async uploadDataset(filename, data) { + await this.client.fs.writeFile(`/project/${filename}`, data); + } + + async getCellHistory() { + return this.cellHistory; + } +} +``` + +## Security Best Practices + +### Resource Limits + +```javascript +async function executeWithLimits(code) { + const sandbox = await sdk.sandboxes.create({ + title: "Limited Execution", + vmTier: "NANO", // Minimal resources + tags: ["restricted"] + }); + + const client = await sandbox.connect(); + + try { + // Set execution limits + const result = await client.commands.run(` + timeout 30s python3 -c "${code}" + `, { + cwd: "/project", + timeout: 35000, // SDK timeout slightly higher than command timeout + env: { + PYTHONPATH: "/project", + // Restrict network access if needed + no_proxy: "*" + } + }); + + return result; + } finally { + // Always clean up + await client.disconnect(); + await sandbox.shutdown(); + } +} +``` + +### Input Sanitization + +```javascript +function sanitizeCode(code) { + // Remove potentially dangerous operations + const dangerous = [ + 'import os', + 'import subprocess', + 'import sys', + '__import__', + 'exec(', + 'eval(', + 'open(', + 'file(', + 'input(', + 'raw_input(' + ]; + + for (const danger of dangerous) { + if (code.includes(danger)) { + throw new Error(`Potentially dangerous operation detected: ${danger}`); + } + } + + return code; +} + +async function safeExecute(code) { + const sanitized = sanitizeCode(code); + return await executeCode(sanitized); +} +``` + +## Error Recovery and Debugging + +### Robust Execution + +```javascript +class RobustCodeExecutor { + constructor(apiKey) { + this.sdk = new CodeSandbox(apiKey); + this.maxRetries = 3; + } + + async executeWithRetry(code, language = "python3") { + let lastError; + + for (let attempt = 1; attempt <= this.maxRetries; attempt++) { + try { + const sandbox = await this.sdk.sandboxes.create({ + title: `Execution Attempt ${attempt}`, + tags: ["retry", `attempt-${attempt}`] + }); + + const client = await sandbox.connect(); + + try { + const result = await client.commands.run(`${language} -c "${code}"`, { + timeout: 30000 + }); + + // Success - clean up and return + await client.disconnect(); + await sandbox.shutdown(); + + return { + success: true, + output: result.output, + attempt: attempt + }; + } finally { + await client.disconnect(); + await sandbox.shutdown(); + } + } catch (error) { + lastError = error; + console.log(`Attempt ${attempt} failed:`, error.message); + + if (attempt < this.maxRetries) { + // Wait before retry + await new Promise(resolve => setTimeout(resolve, 1000 * attempt)); + } + } + } + + return { + success: false, + error: lastError.message, + attempts: this.maxRetries + }; + } +} +``` + +## Performance Optimization + +### Sandbox Pooling + +```javascript +class SandboxPool { + constructor(apiKey, poolSize = 3) { + this.sdk = new CodeSandbox(apiKey); + this.pool = []; + this.poolSize = poolSize; + this.busy = new Set(); + } + + async initialize() { + // Pre-create sandboxes + for (let i = 0; i < this.poolSize; i++) { + const sandbox = await this.sdk.sandboxes.create({ + title: `Pool Sandbox ${i}`, + tags: ["pool", "reusable"] + }); + + const client = await sandbox.connect(); + + // Pre-install common packages + await client.commands.run("pip install numpy pandas matplotlib"); + + this.pool.push({ sandbox, client }); + } + } + + async execute(code) { + // Get available sandbox + const available = this.pool.find(item => !this.busy.has(item)); + + if (!available) { + throw new Error("No available sandboxes in pool"); + } + + this.busy.add(available); + + try { + const result = await available.client.commands.run(`python3 -c "${code}"`); + return result; + } finally { + this.busy.delete(available); + } + } + + async cleanup() { + for (const { client, sandbox } of this.pool) { + await client.disconnect(); + await sandbox.shutdown(); + } + this.pool = []; + this.busy.clear(); + } +} +``` + +## Next Steps + +- Explore [Development Environments](/guides/use-cases/dev-environments) for persistent coding environments +- Learn about [CI/CD Integration](/guides/use-cases/cicd) for automated testing +- Check out [Performance Optimization](/guides/best-practices/performance) best practices +- See [Error Handling](/guides/best-practices/error-handling) for robust applications diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..593f705 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,30 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "CodeSandbox SDK" + tagline: Programmatically spin up development environments and run untrusted code securely + actions: + - theme: brand + text: Get Started + link: /guides/getting-started/quick-start + - theme: alt + text: API Reference + link: /api/core-classes/codesandbox + +features: + - title: 🚀 Fast VM Creation + details: Spin up microVMs in seconds with snapshot restore times under 1 second + - title: 🔒 Secure Execution + details: Run untrusted code safely in isolated environments with full resource control + - title: 📁 Full File System Access + details: Complete file system operations with real-time watching and event handling + - title: 🖥️ Terminal Management + details: Create and manage interactive terminals with full I/O control + - title: 🌐 Port Forwarding + details: Expose services with automatic port management and preview URLs + - title: 🔧 Multi-Platform + details: Works in Node.js and browsers with platform-specific optimizations +--- + diff --git a/docs/markdown-examples.md b/docs/markdown-examples.md new file mode 100644 index 0000000..f9258a5 --- /dev/null +++ b/docs/markdown-examples.md @@ -0,0 +1,85 @@ +# Markdown Extension Examples + +This page demonstrates some of the built-in markdown extensions provided by VitePress. + +## Syntax Highlighting + +VitePress provides Syntax Highlighting powered by [Shiki](https://github.com/shikijs/shiki), with additional features like line-highlighting: + +**Input** + +````md +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` +```` + +**Output** + +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` + +## Custom Containers + +**Input** + +```md +::: info +This is an info box. +::: + +::: tip +This is a tip. +::: + +::: warning +This is a warning. +::: + +::: danger +This is a dangerous warning. +::: + +::: details +This is a details block. +::: +``` + +**Output** + +::: info +This is an info box. +::: + +::: tip +This is a tip. +::: + +::: warning +This is a warning. +::: + +::: danger +This is a dangerous warning. +::: + +::: details +This is a details block. +::: + +## More + +Check out the documentation for the [full list of markdown extensions](https://vitepress.dev/guide/markdown). diff --git a/package-lock.json b/package-lock.json index 19c5746..c9d6796 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "@hey-api/client-fetch": "^0.7.3", "@inkjs/ui": "^2.0.0", - "@msgpack/msgpack": "^3.1.0", "@opentelemetry/api": "^1.9.0", "@xterm/addon-serialize": "^0.13.0", "@xterm/headless": "^5.5.0", @@ -32,6 +31,7 @@ }, "devDependencies": { "@hey-api/openapi-ts": "^0.63.2", + "@msgpack/msgpack": "^2.7.1", "@parcel/watcher": "^2.5.1", "@tanstack/react-query": "^5.76.1", "@types/blessed": "^0.1.25", @@ -52,6 +52,7 @@ "semver": "^6.3.0", "tslib": "^2.1.0", "typescript": "^5.7.2", + "vitepress": "^2.0.0-alpha.11", "why-is-node-running": "^2.3.0" }, "optionalDependencies": { @@ -97,6 +98,56 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", + "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -107,6 +158,20 @@ "node": ">=0.1.90" } }, + "node_modules/@docsearch/css": { + "version": "4.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.0.0-beta.7.tgz", + "integrity": "sha512-hBIwf14yLasrUcDNS7jrneM1ibFD/JFJVDjdxd1h/LUHx7eyLrS726pKHVr3cTdToNXP/7jrTbnC1MAuDHPoow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@docsearch/js": { + "version": "4.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-4.0.0-beta.7.tgz", + "integrity": "sha512-0RJALbDpLMuFy3H/26rjms/qwi5KjsGMN8Lu4k/bs6kBfOWHUN6Dzg/ybj8qB2OLdT2UegsavRIDZKW3QrzQ4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.4", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", @@ -584,6 +649,23 @@ "typescript": "^5.5.3" } }, + "node_modules/@iconify-json/simple-icons": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.48.tgz", + "integrity": "sha512-EACOtZMoPJtERiAbX1De0asrrCtlwI27+03c9OJlYWsly9w1O5vcD8rTzh+kDPjo+K8FOVnq2Qy+h/CzljSKDA==", + "dev": true, + "license": "CC0-1.0", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true, + "license": "MIT" + }, "node_modules/@inkjs/ui": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@inkjs/ui/-/ui-2.0.0.tgz", @@ -657,6 +739,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, "node_modules/@jsdevtools/ono": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", @@ -665,12 +754,13 @@ "license": "MIT" }, "node_modules/@msgpack/msgpack": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.1.1.tgz", - "integrity": "sha512-DnBpqkMOUGayNVKyTLlkM6ILmU/m/+VUxGkuQlPQVAcvreLz5jn1OlQnWd8uHKL/ZSiljpM12rjRhr51VtvJUQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-2.8.0.tgz", + "integrity": "sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==", + "dev": true, "license": "ISC", "engines": { - "node": ">= 18" + "node": ">= 10" } }, "node_modules/@opentelemetry/api": { @@ -1579,6 +1669,293 @@ "@opentelemetry/api": "^1.8" } }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.29.tgz", + "integrity": "sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.4.tgz", + "integrity": "sha512-B2wfzCJ+ps/OBzRjeds7DlJumCU3rXMxJJS1vzURyj7+KBHGONm7c9q1TfdBl4vCuNMkDvARn3PBl2wZzuR5mw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.4.tgz", + "integrity": "sha512-FGJYXvYdn8Bs6lAlBZYT5n+4x0ciEp4cmttsvKAZc/c8/JiPaQK8u0c/86vKX8lA7OY/+37lIQSe0YoAImvBAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.4.tgz", + "integrity": "sha512-/9qwE/BM7ATw/W/OFEMTm3dmywbJyLQb4f4v5nmOjgYxPIGpw7HaxRi6LnD4Pjn/q7k55FGeHe1/OD02w63apA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.4.tgz", + "integrity": "sha512-QkWfNbeRuzFnv2d0aPlrzcA3Ebq2mE8kX/5Pl7VdRShbPBjSnom7dbT8E3Jmhxo2RL784hyqGvR5KHavCJQciw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.4.tgz", + "integrity": "sha512-+ToyOMYnSfV8D+ckxO6NthPln/PDNp1P6INcNypfZ7muLmEvPKXqduUiD8DlJpMMT8LxHcE5W0dK9kXfJke9Zw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.4.tgz", + "integrity": "sha512-cGT6ey/W+sje6zywbLiqmkfkO210FgRz7tepWAzzEVgQU8Hn91JJmQWNqs55IuglG8sJdzk7XfNgmGRtcYlo1w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.4.tgz", + "integrity": "sha512-9fhTJyOb275w5RofPSl8lpr4jFowd+H4oQKJ9XTYzD1JWgxdZKE8bA6d4npuiMemkecQOcigX01FNZNCYnQBdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.4.tgz", + "integrity": "sha512-+6kCIM5Zjvz2HwPl/udgVs07tPMIp1VU2Y0c72ezjOvSvEfAIWsUgpcSDvnC7g9NrjYR6X9bZT92mZZ90TfvXw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.4.tgz", + "integrity": "sha512-SWuXdnsayCZL4lXoo6jn0yyAj7TTjWE4NwDVt9s7cmu6poMhtiras5c8h6Ih6Y0Zk6Z+8t/mLumvpdSPTWub2Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.4.tgz", + "integrity": "sha512-vDknMDqtMhrrroa5kyX6tuC0aRZZlQ+ipDfbXd2YGz5HeV2t8HOl/FDAd2ynhs7Ki5VooWiiZcCtxiZ4IjqZwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.4.tgz", + "integrity": "sha512-mCBkjRZWhvjtl/x+Bd4fQkWZT8canStKDxGrHlBiTnZmJnWygGcvBylzLVCZXka4dco5ymkWhZlLwKCGFF4ivw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.4.tgz", + "integrity": "sha512-YMdz2phOTFF+Z66dQfGf0gmeDSi5DJzY5bpZyeg9CPBkV9QDzJ1yFRlmi/j7WWRf3hYIWrOaJj5jsfwgc8GTHQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.4.tgz", + "integrity": "sha512-r0WKLSfFAK8ucG024v2yiLSJMedoWvk8yWqfNICX28NHDGeu3F/wBf8KG6mclghx4FsLePxJr/9N8rIj1PtCnw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.4.tgz", + "integrity": "sha512-IaizpPP2UQU3MNyPH1u0Xxbm73D+4OupL0bjo4Hm0496e2wg3zuvoAIhubkD1NGy9fXILEExPQy87mweujEatA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.4.tgz", + "integrity": "sha512-aCM29orANR0a8wk896p6UEgIfupReupnmISz6SUwMIwTGaTI8MuKdE0OD2LvEg8ondDyZdMvnaN3bW4nFbATPA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.4.tgz", + "integrity": "sha512-0Xj1vZE3cbr/wda8d/m+UeuSL+TDpuozzdD4QaSzu/xSOMK0Su5RhIkF7KVHFQsobemUNHPLEcYllL7ZTCP/Cg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.4.tgz", + "integrity": "sha512-kM/orjpolfA5yxsx84kI6bnK47AAZuWxglGKcNmokw2yy9i5eHY5UAjcX45jemTJnfHAWo3/hOoRqEeeTdL5hw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.4.tgz", + "integrity": "sha512-cNLH4psMEsWKILW0isbpQA2OvjXLbKvnkcJFmqAptPQbtLrobiapBJVj6RoIvg6UXVp5w0wnIfd/Q56cNpF+Ew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.4.tgz", + "integrity": "sha512-OiEa5lRhiANpv4SfwYVgQ3opYWi/QmPDC5ve21m8G9pf6ZO+aX1g2EEF1/IFaM1xPSP7mK0msTRXlPs6mIagkg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.4.tgz", + "integrity": "sha512-IKL9mewGZ5UuuX4NQlwOmxPyqielvkAPUS2s1cl6yWjjQvyN3h5JTdVFGD5Jr5xMjRC8setOfGQDVgX8V+dkjg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sentry/core": { "version": "9.29.0", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.29.0.tgz", @@ -1672,15 +2049,100 @@ "@opentelemetry/semantic-conventions": "^1.34.0" } }, - "node_modules/@tanstack/query-core": { - "version": "5.76.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.76.0.tgz", - "integrity": "sha512-FN375hb8ctzfNAlex5gHI6+WDXTNpe0nbxp/d2YJtnP+IBM6OUm7zcaoCW6T63BawGOYZBbKC0iPvr41TteNVg==", + "node_modules/@shikijs/core": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.11.0.tgz", + "integrity": "sha512-oJwU+DxGqp6lUZpvtQgVOXNZcVsirN76tihOLBmwILkKuRuwHteApP8oTXmL4tF5vS5FbOY0+8seXmiCoslk4g==", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" + "dependencies": { + "@shikijs/types": "3.11.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.11.0.tgz", + "integrity": "sha512-6/ov6pxrSvew13k9ztIOnSBOytXeKs5kfIR7vbhdtVRg+KPzvp2HctYGeWkqv7V6YIoLicnig/QF3iajqyElZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.11.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.3" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.11.0.tgz", + "integrity": "sha512-4DwIjIgETK04VneKbfOE4WNm4Q7WC1wo95wv82PoHKdqX4/9qLRUwrfKlmhf0gAuvT6GHy0uc7t9cailk6Tbhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.11.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.11.0.tgz", + "integrity": "sha512-Njg/nFL4HDcf/ObxcK2VeyidIq61EeLmocrwTHGGpOQx0BzrPWM1j55XtKQ1LvvDWH15cjQy7rg96aJ1/l63uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.11.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.11.0.tgz", + "integrity": "sha512-BhhWRzCTEk2CtWt4S4bgsOqPJRkapvxdsifAwqP+6mk5uxboAQchc0etiJ0iIasxnMsb764qGD24DK9albcU9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.11.0" + } + }, + "node_modules/@shikijs/transformers": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.11.0.tgz", + "integrity": "sha512-fhSpVoq0FoCtKbBpzE3mXcIbr0b7ozFDSSWiVjWrQy+wrOfaFfwxgJqh8kY3Pbv/i+4pcuMIVismLD2MfO62eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.11.0", + "@shikijs/types": "3.11.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.11.0.tgz", + "integrity": "sha512-RB7IMo2E7NZHyfkqAuaf4CofyY8bPzjWPjJRzn6SEak3b46fIQyG6Vx5fG/obqkfppQ+g8vEsiD7Uc6lqQt32Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tanstack/query-core": { + "version": "5.76.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.76.0.tgz", + "integrity": "sha512-FN375hb8ctzfNAlex5gHI6+WDXTNpe0nbxp/d2YJtnP+IBM6OUm7zcaoCW6T63BawGOYZBbKC0iPvr41TteNVg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/react-query": { @@ -1720,6 +2182,23 @@ "@types/node": "*" } }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1727,6 +2206,41 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mysql": { "version": "2.15.26", "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz", @@ -1796,6 +2310,20 @@ "@types/node": "*" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", + "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -1813,6 +2341,283 @@ "dev": true, "license": "MIT" }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.1.tgz", + "integrity": "sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-beta.29" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.18.tgz", + "integrity": "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@vue/shared": "3.5.18", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.18.tgz", + "integrity": "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.18", + "@vue/shared": "3.5.18" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.18.tgz", + "integrity": "sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@vue/compiler-core": "3.5.18", + "@vue/compiler-dom": "3.5.18", + "@vue/compiler-ssr": "3.5.18", + "@vue/shared": "3.5.18", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.17", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.18.tgz", + "integrity": "sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.18", + "@vue/shared": "3.5.18" + } + }, + "node_modules/@vue/devtools-api": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.0.0.tgz", + "integrity": "sha512-I2jF/knesMU36zTw1hnExjoixDZvDoantiWKVrHpLd2J160zqqe8vp3vrGfjWdfuHmPJwSXe/YNG3rYOYiwy1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^8.0.0" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.0.0.tgz", + "integrity": "sha512-b11OeQODkE0bctdT0RhL684pEV2DPXJ80bjpywVCbFn1PxuL3bmMPDoJKjbMnnoWbrnUYXYzFfmMWBZAMhORkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^8.0.0", + "birpc": "^2.5.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.0.0.tgz", + "integrity": "sha512-jrKnbjshQCiOAJanoeJjTU7WaCg0Dz2BUal6SaR6VM/P3hiFdX5Q6Pxl73ZMnrhCxNK9nAg5hvvRGqs+6dtU1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.18.tgz", + "integrity": "sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.18" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.18.tgz", + "integrity": "sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.18", + "@vue/shared": "3.5.18" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.18.tgz", + "integrity": "sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.18", + "@vue/runtime-core": "3.5.18", + "@vue/shared": "3.5.18", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.18.tgz", + "integrity": "sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.18", + "@vue/shared": "3.5.18" + }, + "peerDependencies": { + "vue": "3.5.18" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.18.tgz", + "integrity": "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vueuse/core": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-13.7.0.tgz", + "integrity": "sha512-myagn09+c6BmS6yHc1gTwwsdZilAovHslMjyykmZH3JNyzI5HoWhv114IIdytXiPipdHJ2gDUx0PB93jRduJYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.21", + "@vueuse/metadata": "13.7.0", + "@vueuse/shared": "13.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/@vueuse/integrations": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-13.7.0.tgz", + "integrity": "sha512-Na5p0ONLepNV/xCBi8vBMuzCOZh9CFT/OHnrUlABWXgWTWSHM3wrVaLS1xvAijPLU5B1ysyJDDW/hKak80oLGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vueuse/core": "13.7.0", + "@vueuse/shared": "13.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "async-validator": "^4", + "axios": "^1", + "change-case": "^5", + "drauu": "^0.4", + "focus-trap": "^7", + "fuse.js": "^7", + "idb-keyval": "^6", + "jwt-decode": "^4", + "nprogress": "^0.2", + "qrcode": "^1.5", + "sortablejs": "^1", + "universal-cookie": "^7 || ^8", + "vue": "^3.5.0" + }, + "peerDependenciesMeta": { + "async-validator": { + "optional": true + }, + "axios": { + "optional": true + }, + "change-case": { + "optional": true + }, + "drauu": { + "optional": true + }, + "focus-trap": { + "optional": true + }, + "fuse.js": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "jwt-decode": { + "optional": true + }, + "nprogress": { + "optional": true + }, + "qrcode": { + "optional": true + }, + "sortablejs": { + "optional": true + }, + "universal-cookie": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-13.7.0.tgz", + "integrity": "sha512-8okFhS/1ite8EwUdZZfvTYowNTfXmVCOrBFlA31O0HD8HKXhY+WtTRyF0LwbpJfoFPc+s9anNJIXMVrvP7UTZg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-13.7.0.tgz", + "integrity": "sha512-Wi2LpJi4UA9kM0OZ0FCZslACp92HlVNw1KPaDY6RAzvQ+J1s7seOtcOpmkfbD5aBSmMn9NvOakc8ZxMxmDXTIg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, "node_modules/@xterm/addon-serialize": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.13.0.tgz", @@ -1969,6 +2774,16 @@ "devOptional": true, "license": "MIT" }, + "node_modules/birpc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.5.0.tgz", + "integrity": "sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/blessed": { "version": "0.1.81", "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", @@ -2290,6 +3105,17 @@ "cdl": "bin/cdl.js" } }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chalk": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.5.0.tgz", @@ -2302,6 +3128,28 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/charm": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", @@ -2595,6 +3443,17 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/commander": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/commander/-/commander-13.0.0.tgz", @@ -2631,6 +3490,22 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -2793,6 +3668,16 @@ "dev": true, "license": "MIT" }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/des.js": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", @@ -2823,6 +3708,20 @@ "node": ">=0.10" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -2924,6 +3823,19 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", @@ -3048,6 +3960,13 @@ "node": ">=4" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, "node_modules/event-stream": { "version": "0.9.8", "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-0.9.8.tgz", @@ -3119,6 +4038,16 @@ "node": ">=8" } }, + "node_modules/focus-trap": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.5.tgz", + "integrity": "sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tabbable": "^6.2.0" + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -3184,6 +4113,21 @@ "node": ">=8" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3438,6 +4382,44 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/here": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/here/-/here-0.0.2.tgz", @@ -3456,6 +4438,24 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ignore": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", @@ -3850,6 +4850,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -3987,6 +5000,16 @@ "node": "20 || >=22" } }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/map-canvas": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/map-canvas/-/map-canvas-0.1.5.tgz", @@ -3997,6 +5020,13 @@ "xml2js": "^0.4.5" } }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", @@ -4050,6 +5080,28 @@ "safe-buffer": "^5.1.2" } }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/memory-streams": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/memory-streams/-/memory-streams-0.1.3.tgz", @@ -4091,6 +5143,100 @@ "node": ">= 0.10.0" } }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -4197,6 +5343,13 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/minisearch": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.2.tgz", + "integrity": "sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA==", + "dev": true, + "license": "MIT" + }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", @@ -4224,6 +5377,13 @@ "node": ">=8" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -4271,6 +5431,25 @@ "license": "MIT", "optional": true }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -4374,6 +5553,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.3.tgz", + "integrity": "sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, "node_modules/optimist": { "version": "0.3.7", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", @@ -4610,6 +5808,13 @@ "node": ">=4" } }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -4676,6 +5881,35 @@ "node": ">= 0.4" } }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/postgres-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", @@ -4751,6 +5985,17 @@ "dev": true, "license": "MIT" }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -4887,6 +6132,33 @@ "esprima": "~4.0.0" } }, + "node_modules/regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", + "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "dev": true, + "license": "MIT" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4948,6 +6220,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, "node_modules/rimraf": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", @@ -4979,6 +6258,46 @@ "inherits": "^2.0.1" } }, + "node_modules/rollup": { + "version": "4.46.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.4.tgz", + "integrity": "sha512-YbxoxvoqNg9zAmw4+vzh1FkGAiZRK+LhnSrbSrSXMdZYsRPDWoshcSd/pldKRO6lWzv/e9TiJAVQyirYIeSIPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.46.4", + "@rollup/rollup-android-arm64": "4.46.4", + "@rollup/rollup-darwin-arm64": "4.46.4", + "@rollup/rollup-darwin-x64": "4.46.4", + "@rollup/rollup-freebsd-arm64": "4.46.4", + "@rollup/rollup-freebsd-x64": "4.46.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.4", + "@rollup/rollup-linux-arm-musleabihf": "4.46.4", + "@rollup/rollup-linux-arm64-gnu": "4.46.4", + "@rollup/rollup-linux-arm64-musl": "4.46.4", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.4", + "@rollup/rollup-linux-ppc64-gnu": "4.46.4", + "@rollup/rollup-linux-riscv64-gnu": "4.46.4", + "@rollup/rollup-linux-riscv64-musl": "4.46.4", + "@rollup/rollup-linux-s390x-gnu": "4.46.4", + "@rollup/rollup-linux-x64-gnu": "4.46.4", + "@rollup/rollup-linux-x64-musl": "4.46.4", + "@rollup/rollup-win32-arm64-msvc": "4.46.4", + "@rollup/rollup-win32-ia32-msvc": "4.46.4", + "@rollup/rollup-win32-x64-msvc": "4.46.4", + "fsevents": "~2.3.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5096,6 +6415,23 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.11.0.tgz", + "integrity": "sha512-VgKumh/ib38I1i3QkMn6mAQA6XjjQubqaAYhfge71glAll0/4xnt8L2oSuC45Qcr/G5Kbskj4RliMQddGmy/Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.11.0", + "@shikijs/engine-javascript": "3.11.0", + "@shikijs/engine-oniguruma": "3.11.0", + "@shikijs/langs": "3.11.0", + "@shikijs/themes": "3.11.0", + "@shikijs/types": "3.11.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, "node_modules/shimmer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", @@ -5175,6 +6511,27 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/sparkline": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/sparkline/-/sparkline-0.1.2.tgz", @@ -5190,6 +6547,16 @@ "node": ">= 0.8.0" } }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -5321,6 +6688,21 @@ "node": ">=8" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -5372,6 +6754,19 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, + "node_modules/superjson": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", + "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -5419,6 +6814,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "dev": true, + "license": "MIT" + }, "node_modules/tar": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", @@ -5459,6 +6861,54 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5472,6 +6922,17 @@ "node": ">=8.0" } }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -5521,6 +6982,79 @@ "devOptional": true, "license": "MIT" }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/utf-8-validate": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.5.tgz", @@ -5555,6 +7089,210 @@ "dev": true, "license": "MIT" }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.3.tgz", + "integrity": "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.14" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitepress": { + "version": "2.0.0-alpha.11", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-2.0.0-alpha.11.tgz", + "integrity": "sha512-l3FFkGtcB3u3iMlpnvkCR+MdOYqNaz2z+xPRlgZZnx8Xne4XLgQR0yfEfTqY/UyloTymXwxvRvu443Yo9Cr8pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@docsearch/css": "^4.0.0-beta.6", + "@docsearch/js": "^4.0.0-beta.6", + "@iconify-json/simple-icons": "^1.2.47", + "@shikijs/core": "^3.9.2", + "@shikijs/transformers": "^3.9.2", + "@shikijs/types": "^3.9.2", + "@types/markdown-it": "^14.1.2", + "@vitejs/plugin-vue": "^6.0.1", + "@vue/devtools-api": "^8.0.0", + "@vue/shared": "^3.5.18", + "@vueuse/core": "^13.6.0", + "@vueuse/integrations": "^13.6.0", + "focus-trap": "^7.6.5", + "mark.js": "8.11.1", + "minisearch": "^7.1.2", + "shiki": "^3.9.2", + "vite": "^7.1.1", + "vue": "^3.5.18" + }, + "bin": { + "vitepress": "bin/vitepress.js" + }, + "peerDependencies": { + "markdown-it-mathjax3": "^4", + "oxc-minify": "^0.81.0", + "postcss": "^8" + }, + "peerDependenciesMeta": { + "markdown-it-mathjax3": { + "optional": true + }, + "oxc-minify": { + "optional": true + }, + "postcss": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.18.tgz", + "integrity": "sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.18", + "@vue/compiler-sfc": "3.5.18", + "@vue/runtime-dom": "3.5.18", + "@vue/server-renderer": "3.5.18", + "@vue/shared": "3.5.18" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5878,6 +7616,17 @@ "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", "license": "MIT" + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index c1c04dc..0150999 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,10 @@ "format": "prettier '**/*.{md,js,jsx,json,ts,tsx}' --write", "postbuild": "rimraf {lib,es}/**/__tests__ {lib,es}/**/*.{spec,test}.{js,d.ts,js.map}", "postversion": "git push && git push --tags", - "prepublish": "npm run build" + "prepublish": "npm run build", + "docs:dev": "vitepress dev docs", + "docs:build": "vitepress build docs", + "docs:preview": "vitepress preview docs" }, "keywords": [ "typescript", @@ -70,6 +73,7 @@ ], "devDependencies": { "@hey-api/openapi-ts": "^0.63.2", + "@msgpack/msgpack": "^2.7.1", "@parcel/watcher": "^2.5.1", "@tanstack/react-query": "^5.76.1", "@types/blessed": "^0.1.25", @@ -81,6 +85,7 @@ "esbuild": "^0.25.0", "ignore": "^6.0.2", "ink": "^6.1.0", + "isomorphic-ws": "^5.0.0", "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", "prettier": "^2.2.1", @@ -89,9 +94,8 @@ "semver": "^6.3.0", "tslib": "^2.1.0", "typescript": "^5.7.2", - "why-is-node-running": "^2.3.0", - "isomorphic-ws": "^5.0.0", - "@msgpack/msgpack": "^2.7.1" + "vitepress": "^2.0.0-alpha.11", + "why-is-node-running": "^2.3.0" }, "dependencies": { "@hey-api/client-fetch": "^0.7.3",