A professional three-panel workstation for local-first development with AI orchestration. Built on data ownership, modular architecture, and autonomous agency.
What is XteVision Coder and who is it for?
XteVision Coder is an AI-assisted code editor and web-based IDE designed for developers who want to build, edit, and manage projects with integrated AI support. It provides a professional three-panel workstation layout with file exploration, code editing, AI chat, live preview, and terminal access—all running locally with support for various AI models.
High-level design and communication flow
┌──────────────────────────────────────────────────────────┐
│ Browser (Client) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Frontend (Vanilla JS) │ │
│ │ ┌────────┐ ┌────────┐ ┌──────┐ ┌────────┐ │ │
│ │ │ File │ │ Monaco │ │ AI │ │ Live │ │ │
│ │ │Explorer│ │ Editor │ │ Chat │ │Preview │ │ │
│ │ └────────┘ └────────┘ └──────┘ └────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
└──────────────────────┬───────────────────────────────────┘
│ HTTP/REST API (localhost:5004)
┌──────────────────────┴───────────────────────────────────┐
│ Python Backend Server │
│ ┌──────────┐ ┌────────┐ ┌────────┐ ┌──────────┐ ┌──────────┐ │
│ │ File I/O │ │ Shell │ │AI Proxy│ │Workspace │ │Auth/Chat │ │
│ └──────────┘ └────────┘ └────────┘ └──────────┘ └──────────┘ │
└──────────────────────┬───────────────────────────────────┘
┌───────────┬───────────┬───────────┐
│ │ │ │
┌─────▼──────┐ ┌──▼────────┐ ┌▼──────────┐
│ File │ │PostgreSQL │ │ AI Model │
│ System │ │ users + │ │ Server │
│ │ │ sessions │ │ │
└────────────┘ └───────────┘ └───────────┘XteVision Coder is designed for local-first development:
Frontend, backend, and AI integration technologies
| Technology | Version | Purpose |
|---|---|---|
| JavaScript (ES6+) | ES2020+ | Application logic |
| HTML5 | - | Semantic structure |
| CSS3 | - | Styling & layout |
| Monaco Editor | 0.52.2 | Code editing |
| Marked.js | - | Markdown parsing |
| Prism.js | - | Syntax highlighting |
| html2pdf.js | - | PDF generation |
| FontAwesome | Free | Icon library |
| Technology | Version | Purpose |
|---|---|---|
| Python | 3.8+ | HTTP server |
| http.server | stdlib | Base HTTP server |
| socketserver | stdlib | TCP threading |
| subprocess | stdlib | Shell execution |
| PostgreSQL | 12+ | User accounts, auth sessions, and chat sessions |
| psycopg2 | 2.9+ | PostgreSQL connectivity |
| argon2-cffi | 23+ | Password hashing |
| PyJWT | 2.8+ | Signed Prodigy handoff tokens |
| Browser | Support | Notes |
|---|---|---|
| Chrome/Edge | ✅ Full | File System Access API |
| Firefox | ⚠️ Partial | Server-based I/O |
| Safari | ⚠️ Partial | Limited file access |
Get XteVision Coder running in minutes
cd /path/to/mlx_coder
bash download-monaco.sh
mlx_lm.server --model <your-model-path> --port 5010
pip3 install -r requirements.txt
# Default configuration
python3 server.py
# Custom port
PORT=8080 python3 server.py
# With PostgreSQL-backed authentication
XTEVISION_DB_HOST=192.168.1.4 \
XTEVISION_DB_PORT=5432 \
XTEVISION_DB_NAME=codebase \
XTEVISION_DB_USER=postgres \
XTEVISION_DB_PASSWORD=your-db-password \
python3 server.py
http://localhost:5004
XteVision Coder now uses cookie-based standalone authentication backed by PostgreSQL. Each user sees only their own saved chat sessions and workspace restoration data.
codebase. On startup, Coder creates and migrates the coder schema automatically when the configured database is reachable.XTEVISION_AUTH_COOKIE_NAME: session cookie name, default xtevision_sessionXTEVISION_AUTH_SESSION_DAYS: cookie lifetime in days, default 14XTEVISION_AUTH_ALLOW_REGISTRATION: enable/disable local sign-upXTEVISION_PRODIGY_SHARED_SECRET: optional shared secret for future trusted Prodigy launch handoffTo use OpenRouter as the AI backend:
https://openrouter.ai/api/v1/chat/completionsqwen/qwen3.6-plus-previewWhen OpenRouter is selected, XteVision Coder attaches these headers:
Authorization: Bearer <OPENROUTER_API_KEY>HTTP-Referer: <configured site URL>X-OpenRouter-Title: <configured site title>Directory layout and module organization
mlx_coder/ ├── index.html # Main HTML entry point ├── style.css # Application styles ├── script.js # Bootstrap and module loader ├── server.py # Python HTTP backend ├── .mlx.json # Project state ├── js/ │ ├── modules/ # Frontend ES6 modules │ │ ├── state.js # Global state management │ │ ├── config.js # AI configuration and provider-specific settings │ │ ├── utils.js # Utility functions │ │ ├── filesystem.js # File I/O and workspace │ │ ├── editor.js # Monaco Editor initialization │ │ ├── chat.js # AI chat and streaming │ │ ├── agent.js # Agent loop and function calling │ │ ├── auth.js # Login/register/logout bootstrap │ │ ├── sessionPersistence.js # Chat session autosave and restore │ │ ├── tools.js # Tool definitions │ │ ├── diff.js # Diff-based editing │ │ ├── preview.js # Live preview and PDF export │ │ └── ui.js # UI rendering and interactions │ ├── marked.min.js # Markdown parser │ ├── prism.min.js # Syntax highlighter │ └── html2pdf.bundle.min.js # PDF generation ├── fontawesome-free-web/ # FontAwesome icons ├── requirements.txt # Python auth/database dependencies ├── projects/ # User project files └── logs/app.log # Application log
export const state = {
editor: null, // Monaco Editor instance
files: {}, // File content cache
openTabs: [], // Open editor tabs
activeTabPath: null, // Active tab path array
tabDirty: {}, // Dirty state per tab path
messageHistory: [], // Active chat message history
chatSessionId: null, // Current saved chat session id
chatSessions: [], // Available saved chat sessions
workspaceFolders: new Map() // Open workspace folders
};
File explorer, code editor, AI chat, preview, and terminal
Multi-root workspace, drag-and-drop operations, context menus, path traversal protection, and three workspace modes (Native, Server, Fallback).
Monaco Editor with 20+ languages, multi-tab editing, IntelliSense, minimap, find/replace, multi-cursor, and code folding.
Streaming and Agent modes, SSE responses, 7 tools, @-mentions, code block actions (Copy, Smart Merge, Insert, Create, Replace), and visual diff previews.
Persistent per-user AI sessions with rename, search, bookmark, autosave, and restore of chat history plus workspace/editor state.
HTML rendering in sandboxed iframe, Markdown to HTML conversion, YAML formatting, and PDF export via html2pdf.
LOG and SHELL tabs, 100-entry command history, 40+ command allowlist, blocked patterns defense-in-depth.
Standalone browser login, secure session cookies, Argon2-hashed passwords, and future signed Prodigy launch support.
| Property | Value |
|---|---|
| Max Iterations | 15 steps per task |
| Timeout | 1 hour maximum |
| Retry Logic | 3 retries with exponential backoff |
| Available Tools | read_file, write_file, edit_file, list_files, search_files, run_shell, create_directory |
Core modules and event system
Centralized state with lazy DOM caching via Proxy and typo detection.
AI server presets, provider-specific request headers, OpenRouter header injection, localStorage persistence, and connection health checking.
Shared helpers: escapeHtml, logToTerminal, safeFetchJson, cleanContent.
File I/O (native + server), workspace management, drag-and-drop, IndexedDB, AI helpers.
Monaco initialization, multi-tab management, save operations, dirty state tracking.
Message handling, provider-aware request headers, SSE streaming, agent coordination, code block actions, @-mentions, and session-aware message history updates.
Multi-step execution, provider-aware request headers, function calling, tool parsing, retry logic, Copilot protocol.
Login/register/logout flow, startup gating, and auth HUD updates for the protected IDE shell.
Autosaves chat sessions, restores the latest session, and rehydrates workspace root, tabs, dirty buffers, and bookmarks.
Tool schemas, execution logic, parameter validation for 7 tools.
// Custom event for settings changes
window.dispatchEvent(new CustomEvent('xtevision-settings-changed'));
// Listen for events
window.addEventListener('xtevision-settings-changed', () => {
// React to settings change
});
// Global error boundaries for async init
try {
await checkServerAvailability();
await connectToServerWorkspace();
} catch (error) {
logToTerminal(`Init error: ${error.message}`, 'error');
}
Python server configuration and request handling
PORT = int(os.environ.get('PORT', 5004))
PROJECTS_DIR = os.path.join(os.getcwd(), 'projects')
AI_PROXY_TIMEOUT_SEC = 3660
AUTH_COOKIE_NAME = os.environ.get('XTEVISION_AUTH_COOKIE_NAME', 'xtevision_session')
AUTH_DB_HOST = os.environ.get('XTEVISION_DB_HOST', '192.168.1.4')
AUTH_DB_NAME = os.environ.get('XTEVISION_DB_NAME', 'codebase')
PRODIGY_JWT_SECRET = os.environ.get('XTEVISION_PRODIGY_SHARED_SECRET', '')
_current_dir_lock = threading.Lock()
_current_dir = os.getcwd()
def get_current_dir():
with _current_dir_lock:
return _current_dir
The backend initializes a coder PostgreSQL schema containing:
users for local and future Prodigy-linked identitiesauth_sessions for secure session-cookie login stateauth_launch_tokens for one-time signed launch handoffschat_sessions for saved chats, titles, bookmarks, and UI restore payloadsclass CustomHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self): # Handle GET
def do_POST(self): # Handle POST
def do_OPTIONS(self): # CORS preflight
def end_headers(self): # Add CORS headers
The backend exposes two AI-related proxy endpoints:
/api/proxy for lightweight JSON fetches such as model discovery/api/ai-proxy for full request forwarding to OpenAI-compatible chat endpointsFor OpenRouter, both endpoints forward provider headers and permit openrouter.ai in the proxy allowlist so authenticated model discovery and chat completions work through the backend fallback path.
Supported servers, protocols, and function calling
| Server | Default URL | Port | Notes |
|---|---|---|---|
| MLX | http://localhost | 5010 | Apple Silicon optimized |
| Ollama | http://localhost | 11434 | Popular local models |
| LMStudio | http://localhost | 1234 | GUI-based model server |
| GitHub Copilot | http://localhost | 5015 | Via proxy |
| OpenRouter | https://openrouter.ai | 443 | Cloud API gateway |
| Custom | User-defined | Any | OpenAI-compatible API |
Endpoint: /v1/chat/completions
{
"model": "your-model-name",
"messages": [
{"role": "system", "content": "You are a coding assistant..."},
{"role": "user", "content": "Write a function to..."}
],
"stream": true,
"tools": [{"type":"function","function":{"name":"read_file","parameters":{"file_path":"string"}}}]
}
Server-Sent Events (SSE):
data: {"choices": [{"delta": {"content": "Hello"}}]}
data: {"choices": [{"delta": {"content": "!"}}]}
data: [DONE]
Tool Call Parsing (3 formats):
call:read_file{"file_path": "test.js"}{"name": "read_file", "arguments": {...}}
When using GitHub Copilot as the backend, the agent uses a JSON-only response format for structured tool calls and follows the planner-execution pattern.
Five-layer security implementation
40+ approved commands: ls, cat, echo, pwd, mkdir, touch, cp, mv, git, npm, python, node, curl, etc.
Blocked patterns (defense-in-depth):
rm -rf / and variantssudo commandschmod 777curl ... | shUses os.path.commonpath() + os.path.realpath() to prevent symlink-based path traversal attacks. All file operations are validated to stay within the workspace root.
AI proxy restricted to approved domains only:
localhost, 127.0.0.1, 0.0.0.0192.168.10.3 (user's local network AI server)openrouter.ai (cloud provider endpoint)Prevents use of the proxy to access internal network services.
Replaced wildcard CORS with localhost-only origins:
http://localhost:5004http://127.0.0.1:5004http://localhost:8080Prevents malicious websites from making requests to the local server.
XteVision Coder now protects the workspace with standalone browser authentication:
Complete REST API endpoints
Request:
{
"path": "projects/myapp/src/index.js",
"content": "console.log('Hello');"
}
Response:
{"success": true, "message": "File written successfully"}
Request:
{"path": "projects/myapp/package.json"}
Response:
{"content": "{...}", "success": true}
Request:
{"path": "projects/myapp/src/components"}
Response:
{"success": true, "message": "Folder created"}
Response:
{"folders": ["src", "public"], "files": ["index.html", "package.json"]}
Request:
{"path": "projects/myapp/old-file.js"}
Response:
{"success": true}
Request:
{"old_path": "projects/myapp/old-name.js", "new_path": "projects/myapp/new-name.js"}
Response:
{"success": true}
Request:
{"command": "ls -la"}
Response:
{"output": "total 48\ndrwxr-xr-x ...", "success": true}
Forwards requests to configured AI server for model discovery and lightweight operations.
Forwards full chat completion requests to the configured AI backend with provider-specific headers for OpenRouter integration.
Returns the authenticated user and backend availability state for the login bootstrap.
Creates a new standalone Coder user with username, optional email, and password.
Authenticates a local user and returns a session cookie.
Revokes the current auth session and clears the cookie.
Lists the current user's saved chat sessions ordered by bookmark state and recent activity.
Returns the latest active chat session for login restore.
Creates a new chat session with title, messages, bookmark state, and serialized UI state.
Updates an existing session with new messages, renamed title, bookmark flag, workspace root, open tabs, and unsaved buffer contents.
Deletes the selected chat session for the authenticated user.
Request:
{
"path": "projects/myapp/src/index.js",
"edits": [{
"search": "console.log('old')",
"replace": "console.log('new')"
}]
}
Response:
{"success": true, "message": "File updated"}
Environment variables and settings
| Variable | Default | Description |
|---|---|---|
PORT | 5004 | Backend server port |
XTEVISION_AUTH_COOKIE_NAME | xtevision_session | Session cookie name |
XTEVISION_AUTH_SESSION_DAYS | 14 | Cookie/session lifetime in days |
XTEVISION_AUTH_SECURE_COOKIE | false | Marks cookies secure when behind HTTPS |
XTEVISION_AUTH_ALLOW_REGISTRATION | true | Enable or disable local sign-up |
XTEVISION_DB_HOST | 192.168.1.4 | PostgreSQL host |
XTEVISION_DB_PORT | 5432 | PostgreSQL port |
XTEVISION_DB_NAME | codebase | PostgreSQL database name |
XTEVISION_DB_USER | postgres | PostgreSQL username |
XTEVISION_DB_PASSWORD | empty | PostgreSQL password |
XTEVISION_PRODIGY_SHARED_SECRET | empty | Optional signed Prodigy handoff secret |
| Setting | Type | Description |
|---|---|---|
xtevision_ai_server | string | Selected AI server preset |
xtevision_ai_url | string | AI server API URL |
xtevision_ai_model | string | Model name/ID |
openrouter_api_key | string | OpenRouter API key |
openrouter_site_url | string | OpenRouter HTTP-Referer header value |
openrouter_site_title | string | OpenRouter X-OpenRouter-Title header value |
xtevision_last_file | string | Last opened file path |
The following data is no longer stored only in localStorage:
| Presets | URL | Port |
|---|---|---|
| MLX | http://localhost | 5010 |
| Ollama | http://localhost | 11434 |
| LMStudio | http://localhost | 1234 |
| OpenRouter | https://openrouter.ai | 443 |
| Copilot | http://localhost | 5015 |
Module creation and debugging
// 1. Create js/modules/mymodule.js
import { state, elements } from './state.js';
import { logToTerminal } from './utils.js';
export function initMyModule() {
logToTerminal('MyModule initialized', 'info');
}
// 2. Import in script.js
import { initMyModule } from './js/modules/mymodule.js';
// 3. Call during initialization
initMyModule();
localStorage.setItem('debug', 'true')// Test AI connection from console
const response = await fetch('http://localhost:5004/api/proxy', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'test-model',
messages: [{role: 'user', content: 'Hello'}]
})
});
console.log(await response.json());
All JS modules use ?v=APP_VERSION query parameter for cache busting. Update APP_VERSION in config.js after making changes.
Common issues and solutions
bash download-monaco.sh or check network for CDN accesscodebase database exists, and the XTEVISION_DB_* variables match the server configurationALLOWED_SHELL_COMMANDS in server.py if neededhttp://localhost:5004 (no HTTPS). Use shouldForceBackendProxy() detectionAI_PROXY_TIMEOUT_SEC