@newsails/veil-studio
v1.0.1
Published
Visual IDE for Veil CLI agents — drag-and-drop canvas, real-time chat, and agent editor
Downloads
199
Readme
Veil Studio
Visual workflow IDE for VeilCLI — an LLM agent runner.
Drag agents, sessions, tasks, memories, and data blocks onto an infinite canvas, wire them together, and watch everything run in real time.
Features
- Infinite canvas — place any element type, wire ports, organize with zones and saved views
- Real-time sync — all board mutations broadcast to every connected client instantly
- Live chat — stream token-by-token responses from any agent session, directly in the canvas
- External session monitoring — sessions started by other apps or agent tools appear in Studio in real time, with live streaming, tool indicators, and user messages
- File explorer — browse, edit, and add project files to the board as elements
- Custom elements — drop a folder into
.veil-studio/elements/to add any element type without rebuilding - No build step — Express server is plain CommonJS; starts instantly
Quick Start
# Install globally
npm install -g @newsails/veil-studio
# Run (from any directory — that directory becomes the workspace)
veil-studioOpen http://localhost:4444
Node ≥18 required for running. Node 20 is only needed if building the frontend from source.
CLI Options
veil-studio [options]
--port, -p <number> Studio port (default: 4444)
--api, -a <url> VeilCLI API base URL (default: http://localhost:5050)
--api-port, -ap <number> VeilCLI port on localhost (shortcut for --api)
--project, -d <path> Workspace directory (default: cwd)
--secret, -s <token> VeilCLI API secret token
--dev, -D Force dev mode
--help, -h Show helpPositional shorthand: veil-studio <port> [api] [project] [secret]
Run from source
npm install
node bin/veil-studio.js
# or
npm startArchitecture
Browser (Nuxt 3 SPA — TypeScript, Pinia, TailwindCSS)
│ Socket.IO ← board mutations, chat, VeilCLI proxy
│ REST /api/files/* ← file system only
▼
Express server (port 4444) — Plain CommonJS, no build step
├── Socket.IO handlers server/socket.js
├── REST routes server/routes/files.js
├── SQLite (sync) .veil-studio/studio.db
├── In-memory Maps board state (elements, links, zones, views)
└── WebSocket client ──► VeilCLI /ws (port 5050)
real-time events for all sessions & tasksKey rules:
- Browser never talks to VeilCLI directly — all calls proxied via Studio Socket.IO
- Board state is server-authoritative — clients never optimistically mutate
- Socket.IO for everything board/agent/chat; REST only for
/api/files/*
Environment Variables
| Variable | Default | Purpose |
|---|---|---|
| STUDIO_PORT | 4444 | Studio server port |
| VEIL_API | http://localhost:5050 | VeilCLI base URL (auto-read from .veil/settings.json) |
| VEIL_SECRET | (empty) | X-Veil-Secret auth header (auto-read from .veil/settings.json) |
| PROJECT_DIR | process.cwd() | Working directory (files, custom elements, DB) |
Project Structure
VeilCLI_Studio/
├── server/ Backend — plain CommonJS
│ ├── index.js Entry: startup sequence, dev proxy, listen
│ ├── socket.js All Socket.IO event handlers
│ ├── routes/files.js REST /api/files/*
│ └── utils/
│ ├── config.js All env/config resolution
│ ├── db.js SQLite singleton + schema
│ ├── board-state.js In-memory Maps + DB sync + broadcasts
│ ├── element-registry.js 55 built-in + custom type registry
│ ├── element-instances.js Running element instance Map
│ ├── veil-client.js VeilCLI REST + SSE streaming wrapper
│ ├── veil-ws.js Persistent WS to VeilCLI /ws
│ ├── session-watcher.js Message-count baseline tracker
│ ├── socket-io.js getIO()/setIO() singleton
│ ├── file-utils.js Path-safe file operations
│ └── elements/ 55 built-in element definitions
│
├── nuxt-app/ Frontend — Nuxt 3, TypeScript, SPA
│ ├── stores/ board.ts · ui.ts · chat.ts
│ ├── composables/ useSocket · useBoard · useCamera · useChat
│ │ useVeil · useElementRegistry · useFileExplorer
│ ├── components/ canvas/ · elements/ · sidebar/ · chat/
│ └── .output/ Production build (served by Express in prod)
│
└── docs/ Full reference documentationBuilt-in Element Types (55)
| Category | Types |
|---|---|
| CLI | agent agent-instance chat-view task skill memory todo-list custom-tool |
| Data | text rich-text code-block json-object file-reference image image-local url-card web-snapshot |
| Research | source-collection research-note comparison-table fact-claim question web-search-query |
| Docs | document-draft outline section template |
| Dev | diff-patch error-log test-case |
| Thinking | idea pro-con-list decision assumption constraint goal blocker |
| PM | project milestone status-update |
| Comm | chat-room message feedback-request approval-gate |
| Flow | generator processor splitter merger filter queue |
| Org | collapsible-group annotation label-tag divider primitive |
Custom Elements
Drop a folder in .veil-studio/elements/<type>/ containing:
element.json — metadata (type, name, icon, defaultWidth/Height, …)
index.js — server-side factory: createInstance(context) → { getViewData, getPorts, actions }
vue-component.js — frontend Vue component (receives viewData, elementId props; emits action)Click Reload Custom Elements in the palette sidebar — no server restart needed. Custom types with the same name as a built-in override the built-in completely.
Documentation
| Document | Contents |
|---|---|
| docs/README.md | Architecture deep-dive, data flow, key decisions |
| docs/Server.md | All server modules, DB schema, element system reference |
| docs/SocketIO.md | Every Socket.IO event — payloads, handlers, end-to-end flows |
| docs/UI.md | Stores, composables, canvas components, chat components |
Production Build
When installed via npm, the pre-built frontend is included in the package (nuxt-app/.output/public/). The server auto-detects it and serves it statically.
To rebuild the frontend from source (requires Node 20):
npm run build
# runs scripts/build-ui.js → cd nuxt-app && nuxt buildThe server auto-detects whether nuxt-app/.output/public/ exists — if yes, production mode; if no, dev mode (spawns Nuxt dev automatically).
