@newsails/veil-cli 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.veil/agents/analyst/AGENT.md +21 -0
- package/.veil/agents/analyst/agent.json +23 -0
- package/.veil/agents/assistant/AGENT.md +15 -0
- package/.veil/agents/assistant/agent.json +19 -0
- package/.veil/agents/coder/AGENT.md +18 -0
- package/.veil/agents/coder/agent.json +19 -0
- package/.veil/agents/hello/AGENT.md +5 -0
- package/.veil/agents/hello/agent.json +13 -0
- package/.veil/agents/writer/AGENT.md +12 -0
- package/.veil/agents/writer/agent.json +17 -0
- package/.veil/memory/MEMORY.md +343 -0
- package/.veil/memory/agents/analyst/MEMORY.md +55 -0
- package/.veil/memory/agents/hello/MEMORY.md +12 -0
- package/.veil/runtime.pid +1 -0
- package/.veil/settings.json +10 -0
- package/.veil-studio/studio.db +0 -0
- package/.veil-studio/studio.db-shm +0 -0
- package/.veil-studio/studio.db-wal +0 -0
- package/PLAN/01-vision.md +26 -0
- package/PLAN/02-tech-stack.md +94 -0
- package/PLAN/03-agents.md +232 -0
- package/PLAN/04-runtime.md +171 -0
- package/PLAN/05-tools.md +211 -0
- package/PLAN/06-communication.md +243 -0
- package/PLAN/07-storage.md +218 -0
- package/PLAN/08-api-cli.md +153 -0
- package/PLAN/09-permissions.md +108 -0
- package/PLAN/10-ably.md +105 -0
- package/PLAN/11-file-formats.md +442 -0
- package/PLAN/12-folder-structure.md +205 -0
- package/PLAN/13-operations.md +212 -0
- package/PLAN/README.md +23 -0
- package/README.md +128 -0
- package/REPORT.md +174 -0
- package/TODO.md +45 -0
- package/ai-tests/FRONTEND_PROMPT.md +220 -0
- package/ai-tests/Research & Planning.md +814 -0
- package/ai-tests/prompt-001-basic-api.md +230 -0
- package/ai-tests/prompt-002-basic-flows.md +230 -0
- package/ai-tests/prompt-003-agent-behaviors.md +220 -0
- package/api/middleware.js +60 -0
- package/api/routes/agents.js +193 -0
- package/api/routes/chat.js +93 -0
- package/api/routes/completions.js +122 -0
- package/api/routes/daemons.js +80 -0
- package/api/routes/memory.js +169 -0
- package/api/routes/models.js +40 -0
- package/api/routes/remote-methods.js +74 -0
- package/api/routes/sessions.js +208 -0
- package/api/routes/settings.js +108 -0
- package/api/routes/system.js +50 -0
- package/api/routes/tasks.js +270 -0
- package/api/server.js +120 -0
- package/cli/formatter.js +70 -0
- package/cli/index.js +443 -0
- package/cli/parser.js +113 -0
- package/config/config.json +10 -0
- package/config/models.json +6826 -0
- package/core/agent.js +329 -0
- package/core/cancel.js +38 -0
- package/core/compaction.js +176 -0
- package/core/events.js +13 -0
- package/core/loop.js +564 -0
- package/core/memory.js +51 -0
- package/core/prompt.js +185 -0
- package/core/queue.js +96 -0
- package/core/registry.js +291 -0
- package/core/remote-methods.js +124 -0
- package/core/router.js +386 -0
- package/core/running-sessions.js +18 -0
- package/docs/api/01-system.md +84 -0
- package/docs/api/02-agents.md +374 -0
- package/docs/api/03-chat.md +269 -0
- package/docs/api/04-tasks.md +470 -0
- package/docs/api/05-sessions.md +444 -0
- package/docs/api/06-daemons.md +142 -0
- package/docs/api/07-memory.md +186 -0
- package/docs/api/08-settings.md +133 -0
- package/docs/api/09-models.md +119 -0
- package/docs/api/09-websocket.md +350 -0
- package/docs/api/10-completions.md +134 -0
- package/docs/api/README.md +116 -0
- package/docs/guide/01-quickstart.md +220 -0
- package/docs/guide/02-folder-structure.md +185 -0
- package/docs/guide/03-configuration.md +252 -0
- package/docs/guide/04-agents.md +267 -0
- package/docs/guide/05-cli.md +290 -0
- package/docs/guide/06-tools.md +643 -0
- package/docs/guide/07-permissions.md +236 -0
- package/docs/guide/08-memory.md +139 -0
- package/docs/guide/09-multi-agent.md +271 -0
- package/docs/guide/10-daemons.md +226 -0
- package/docs/guide/README.md +53 -0
- package/docs/index.html +623 -0
- package/examples/README.md +151 -0
- package/examples/agents/assistant/AGENT.md +31 -0
- package/examples/agents/assistant/SOUL.md +9 -0
- package/examples/agents/assistant/agent.json +74 -0
- package/examples/agents/hello/AGENT.md +15 -0
- package/examples/agents/hello/agent.json +14 -0
- package/examples/agents/monitor/AGENT.md +51 -0
- package/examples/agents/monitor/agent.json +33 -0
- package/examples/agents/monitor/heartbeats/monitor.md +24 -0
- package/examples/agents/orchestrator/AGENT.md +70 -0
- package/examples/agents/orchestrator/agent.json +30 -0
- package/examples/agents/researcher/AGENT.md +52 -0
- package/examples/agents/researcher/agent.json +49 -0
- package/examples/agents/researcher/skills/web-research.md +28 -0
- package/examples/skills/code-review.md +72 -0
- package/examples/skills/summarise.md +59 -0
- package/examples/skills/web-research.md +42 -0
- package/examples/tools/word-count/index.js +27 -0
- package/examples/tools/word-count/tool.json +18 -0
- package/infrastructure/database.js +563 -0
- package/infrastructure/scheduler.js +122 -0
- package/llm/client.js +206 -0
- package/migrations/001-initial.sql +121 -0
- package/migrations/002-debuggability.sql +13 -0
- package/migrations/003-drop-orphaned-columns.sql +72 -0
- package/migrations/004-session-message-token-fields.sql +78 -0
- package/migrations/005-session-thinking.sql +5 -0
- package/package.json +30 -0
- package/schemas/agent.json +143 -0
- package/schemas/settings.json +111 -0
- package/scripts/fetch-models.js +93 -0
- package/session-debug-scenario.md +248 -0
- package/settings/fields.js +52 -0
- package/system-prompts/base-core.md +7 -0
- package/system-prompts/environment.md +13 -0
- package/system-prompts/reminders/anti-drift.md +6 -0
- package/system-prompts/reminders/stall-recovery.md +10 -0
- package/system-prompts/safety-rules.md +25 -0
- package/system-prompts/task-heuristics.md +27 -0
- package/test/client.js +71 -0
- package/test/integration/01-health.test.js +25 -0
- package/test/integration/02-agents.test.js +80 -0
- package/test/integration/03-chat-hello.test.js +48 -0
- package/test/integration/04-chat-multiturn.test.js +61 -0
- package/test/integration/05-chat-writer.test.js +48 -0
- package/test/integration/06-task-basic.test.js +68 -0
- package/test/integration/07-task-tools.test.js +74 -0
- package/test/integration/08-task-code-analysis.test.js +69 -0
- package/test/integration/09-memory-analyst.test.js +63 -0
- package/test/integration/10-task-advanced.test.js +85 -0
- package/test/integration/11-sessions-advanced.test.js +84 -0
- package/test/integration/12-assistant-chat-tools.test.js +75 -0
- package/test/integration/13-edge-cases.test.js +99 -0
- package/test/integration/14-cancel.test.js +62 -0
- package/test/integration/15-debug.test.js +106 -0
- package/test/integration/16-memory-api.test.js +83 -0
- package/test/integration/17-settings-api.test.js +41 -0
- package/test/integration/18-tool-search-activation.test.js +119 -0
- package/test/results/.gitkeep +0 -0
- package/test/runner.js +206 -0
- package/test/smoke.js +216 -0
- package/tools/agent_message.js +85 -0
- package/tools/agent_send.js +80 -0
- package/tools/agent_spawn.js +44 -0
- package/tools/bash.js +49 -0
- package/tools/edit_file.js +41 -0
- package/tools/glob.js +64 -0
- package/tools/grep.js +82 -0
- package/tools/list_dir.js +63 -0
- package/tools/log_write.js +31 -0
- package/tools/memory_read.js +38 -0
- package/tools/memory_search.js +65 -0
- package/tools/memory_write.js +42 -0
- package/tools/read_file.js +48 -0
- package/tools/sleep.js +22 -0
- package/tools/task_create.js +41 -0
- package/tools/task_respond.js +37 -0
- package/tools/task_spawn.js +64 -0
- package/tools/task_status.js +39 -0
- package/tools/task_subscribe.js +37 -0
- package/tools/todo_read.js +26 -0
- package/tools/todo_write.js +38 -0
- package/tools/tool_activate.js +24 -0
- package/tools/tool_search.js +24 -0
- package/tools/web_fetch.js +50 -0
- package/tools/web_search.js +52 -0
- package/tools/write_file.js +28 -0
- package/ui/api.js +190 -0
- package/ui/app.js +281 -0
- package/ui/index.html +382 -0
- package/ui/views/agents.js +377 -0
- package/ui/views/chat.js +610 -0
- package/ui/views/connection.js +96 -0
- package/ui/views/daemons.js +129 -0
- package/ui/views/feed.js +194 -0
- package/ui/views/memory.js +263 -0
- package/ui/views/models.js +146 -0
- package/ui/views/sessions.js +314 -0
- package/ui/views/settings.js +142 -0
- package/ui/views/tasks.js +415 -0
- package/utils/context.js +49 -0
- package/utils/id.js +16 -0
- package/utils/models.js +88 -0
- package/utils/paths.js +213 -0
- package/utils/settings.js +172 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# 13 — Operations
|
|
2
|
+
|
|
3
|
+
## Failure & Recovery
|
|
4
|
+
|
|
5
|
+
### LLM Call Failure
|
|
6
|
+
- Retry up to `retry.maxAttempts` times with `retry.delaySeconds` delay (exponential backoff via `openai` SDK)
|
|
7
|
+
- If exhausted and `onExhausted: "fail"` → task status = failed
|
|
8
|
+
- If exhausted and `onExhausted: "wait"` → task status = waiting (human can retry)
|
|
9
|
+
|
|
10
|
+
### Iteration/Duration Limits
|
|
11
|
+
- `maxIterations` reached → task failed, error = "Max iterations exceeded"
|
|
12
|
+
- `maxDurationSeconds` reached → task failed, error = "Max duration exceeded"
|
|
13
|
+
- Both configurable globally (settings.json) and per-agent per-mode (agent.json)
|
|
14
|
+
|
|
15
|
+
### Startup Recovery
|
|
16
|
+
On server start:
|
|
17
|
+
1. Open SQLite database, run pending migrations
|
|
18
|
+
2. Scan for tasks with status `pending` or `processing`
|
|
19
|
+
3. Set all to `failed` with error: "Runtime terminated unexpectedly"
|
|
20
|
+
4. Auto-start all agents with `daemon.enabled: true`
|
|
21
|
+
5. Begin accepting API requests
|
|
22
|
+
|
|
23
|
+
### Graceful Shutdown
|
|
24
|
+
On `veil stop` or SIGTERM/SIGINT:
|
|
25
|
+
1. Stop accepting new HTTP connections
|
|
26
|
+
2. Stop all cron schedulers
|
|
27
|
+
3. Wait for active agent loops to reach a safe point (tool boundary)
|
|
28
|
+
4. Leave Ably presence, close Ably connection
|
|
29
|
+
5. Close SQLite database (checkpoints WAL)
|
|
30
|
+
6. Delete runtime.pid, exit 0
|
|
31
|
+
7. Failsafe: force exit after 10s timeout
|
|
32
|
+
|
|
33
|
+
### Multiple Instances
|
|
34
|
+
- Multiple one-shot instances: fully supported (SQLite WAL handles concurrent writes)
|
|
35
|
+
- Multiple server instances on same port: OS port conflict error
|
|
36
|
+
- Multiple server instances on different ports: supported, shared SQLite
|
|
37
|
+
- Concurrent memory file writes: last-write-wins in v1
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Testing Strategy (v1)
|
|
42
|
+
|
|
43
|
+
### Scope
|
|
44
|
+
**Smoke test + Unit tests + API tests** — fastest path to ship with confidence.
|
|
45
|
+
|
|
46
|
+
### Smoke Test (`test/smoke.js`) — Run First
|
|
47
|
+
A fast automated test run immediately after `npm install`. Catches ~14 of the 20 real bugs found during testing before any manual effort. Runs with `npm test`.
|
|
48
|
+
|
|
49
|
+
What it verifies:
|
|
50
|
+
1. Server starts without errors (Node version check passes, all deps resolve)
|
|
51
|
+
2. `GET /health` returns 200
|
|
52
|
+
3. Example agent (`examples/agents/hello/`) loads and validates against schema
|
|
53
|
+
4. `POST /agents/hello/chat` returns a response (mock LLM)
|
|
54
|
+
5. Server shuts down cleanly
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# package.json
|
|
58
|
+
{ "scripts": { "test": "node test/smoke.js && node --test test/unit/ test/api/" } }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Unit Tests
|
|
62
|
+
- Agentic loop logic (mock LLM responses via fetch mock)
|
|
63
|
+
- System prompt assembly (7-layer composition)
|
|
64
|
+
- Tool argument validation (ajv)
|
|
65
|
+
- Permission evaluation (deny/ask/allow resolution)
|
|
66
|
+
- Settings resolution (merge order — including field name constants)
|
|
67
|
+
- Agent discovery (file lookup logic with `getProjectAgentsDir(cwd)`)
|
|
68
|
+
- SQLite queries (in-memory test database)
|
|
69
|
+
- `context.js` singleton (set/get, throws if uninitialized)
|
|
70
|
+
- `id.js` ID generation (no nanoid, crypto-based)
|
|
71
|
+
|
|
72
|
+
### API Tests
|
|
73
|
+
- All REST endpoints (happy path + error cases)
|
|
74
|
+
- Authentication (with/without secret)
|
|
75
|
+
- Pagination
|
|
76
|
+
- Task lifecycle (create → process → finish)
|
|
77
|
+
- Session lifecycle (create → message → close)
|
|
78
|
+
|
|
79
|
+
### Integration Test (`test/integration.js`)
|
|
80
|
+
Boots the full server with mock LLM. Exercises task lifecycle end-to-end. Catches wiring bugs that unit tests miss (circular deps, wrong exports, signature mismatches). Should pass before any release.
|
|
81
|
+
|
|
82
|
+
### Mock LLM
|
|
83
|
+
For tests that need LLM responses: mock native `fetch` (not an openai SDK mock) to return predefined responses with tool calls. No real LLM calls in CI. Pattern:
|
|
84
|
+
```javascript
|
|
85
|
+
global.fetch = async (url, options) => {
|
|
86
|
+
return { ok: true, json: async () => ({ choices: [{ message: { content: 'Hello!', tool_calls: [] } }] }) };
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Test Runner
|
|
91
|
+
Node.js built-in test runner (`node:test`) — zero external deps.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Compatibility
|
|
96
|
+
|
|
97
|
+
### Claude Code Compatibility (via Import)
|
|
98
|
+
VeilCLI imports Claude Code project structures via `veil import`:
|
|
99
|
+
|
|
100
|
+
| Claude Code | VeilCLI Equivalent |
|
|
101
|
+
|-------------|---------------------|
|
|
102
|
+
| `CLAUDE.md` | Converted to `.veil/AGENT.md` via `veil import` |
|
|
103
|
+
| `.claude/` | Read as `.veil/` |
|
|
104
|
+
| `.claude/skills/` | Read as skills |
|
|
105
|
+
| `settings.json` | All Claude Code fields supported |
|
|
106
|
+
| MCP server definitions | Fully supported |
|
|
107
|
+
| Permission format | Fully supported |
|
|
108
|
+
| Template variables | Fully supported |
|
|
109
|
+
|
|
110
|
+
### Import Adapters
|
|
111
|
+
|
|
112
|
+
`veil import --type=<adapter> --source <path>`
|
|
113
|
+
|
|
114
|
+
| Adapter | Source | Transform |
|
|
115
|
+
|---------|--------|-----------|
|
|
116
|
+
| `claude-code` | Claude Code project | CLAUDE.md → AGENT.md, .claude/ → .veil/, generates agent.json with mode config |
|
|
117
|
+
| `openclaw` | OpenClaw project | Maps OpenClaw agent definitions to VeilCLI format |
|
|
118
|
+
| `raw` | Any folder | Copies as-is, creates minimal agent.json |
|
|
119
|
+
|
|
120
|
+
**Interactive import:** Since VeilCLI agents have modes (chat/task/daemon) which Claude Code doesn't, the import tool asks follow-up questions:
|
|
121
|
+
- Which modes should this agent support?
|
|
122
|
+
- What tools should be available per mode?
|
|
123
|
+
- What model should it use?
|
|
124
|
+
- Any permission overrides?
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Veil.com Integration (v1)
|
|
129
|
+
|
|
130
|
+
### API Surface
|
|
131
|
+
| Endpoint | Purpose |
|
|
132
|
+
|----------|---------|
|
|
133
|
+
| `POST /api/v1/validate-token` | Validate veil_token |
|
|
134
|
+
| `GET /api/v1/registry/agents` | List available agents |
|
|
135
|
+
| `GET /api/v1/registry/agents/:name` | Download agent |
|
|
136
|
+
| `GET /api/v1/registry/tools` | List available tools |
|
|
137
|
+
| `GET /api/v1/registry/tools/:name` | Download tool |
|
|
138
|
+
| `POST /api/v1/ably/token` | Get scoped Ably TokenRequest |
|
|
139
|
+
|
|
140
|
+
### Version Checking
|
|
141
|
+
- Each cached agent/tool has a `version.json` with SHA256 hash
|
|
142
|
+
- On startup (if connected), VeilCLI checks hashes against Veil.com manifest
|
|
143
|
+
- If different → auto-update global agents/tools
|
|
144
|
+
- Project-local agents are never auto-updated (user owns them)
|
|
145
|
+
|
|
146
|
+
### No Usage Analytics
|
|
147
|
+
VeilCLI does NOT send usage data to Veil.com. Token counts and costs are tracked locally in SQLite. The AI provider (OpenRouter, etc.) handles their own analytics.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Images & Files
|
|
152
|
+
|
|
153
|
+
### Image Handling
|
|
154
|
+
- **Vision:** Images sent as base64 in messages (Claude, GPT-4V, Gemini support)
|
|
155
|
+
- **From URL:** `web_fetch` auto-converts image URLs to base64
|
|
156
|
+
- **From file:** `read_file` on image files returns base64
|
|
157
|
+
- **Generation:** Via standard LLM API (models that support image generation)
|
|
158
|
+
- **MCP:** Available for users who want DALL-E, Stable Diffusion, etc.
|
|
159
|
+
|
|
160
|
+
### File/URL Resolution
|
|
161
|
+
Task input supports multiple file sources:
|
|
162
|
+
|
|
163
|
+
| Type | Format | Example |
|
|
164
|
+
|------|--------|---------|
|
|
165
|
+
| Local file | `./path/to/file` | `./src/auth.js` |
|
|
166
|
+
| Absolute path | `/path/to/file` | `/home/user/project/src/auth.js` |
|
|
167
|
+
| HTTP URL | `https://...` | `https://raw.githubusercontent.com/...` |
|
|
168
|
+
| Data URL | `data:...` | `data:text/plain;base64,SGVsbG8=` |
|
|
169
|
+
|
|
170
|
+
Unified resolver with mime type detection. URLs fetched and cached for the session duration.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Modularity & Extensibility
|
|
175
|
+
|
|
176
|
+
The codebase is designed to be modular, making it easy to add or modify features without touching unrelated code.
|
|
177
|
+
|
|
178
|
+
### Source Code Boundaries
|
|
179
|
+
| Module | Responsibility | Can change without affecting |
|
|
180
|
+
|--------|---------------|----------------------------|
|
|
181
|
+
| `core/loop.js` | Agentic loop | API routes, CLI |
|
|
182
|
+
| `core/registry.js` | Tool registration | Agent loading, prompts |
|
|
183
|
+
| `core/prompt.js` | System prompt assembly | Tool execution, storage |
|
|
184
|
+
| `core/memory.js` | Memory read/write/search/export | Loop, tools |
|
|
185
|
+
| `core/queue.js` | Agent message queue | Storage, prompts |
|
|
186
|
+
| `api/` | REST transport | Core logic |
|
|
187
|
+
| `cli/` | CLI transport | Core logic |
|
|
188
|
+
| `infrastructure/` | SQLite, Ably, MCP, cron | Core logic |
|
|
189
|
+
| `tools/` | Individual tool implementations | Each tool is independent |
|
|
190
|
+
| `utils/context.js` | CWD singleton | All modules (no circular deps) |
|
|
191
|
+
| `utils/paths.js` | Path construction | Prevents inline `.veil/` string bugs |
|
|
192
|
+
| `settings/fields.js` | Field name constants | Prevents field name drift across modules |
|
|
193
|
+
| `llm/client.js` | Native fetch LLM client | Replaces openai SDK, no version drift |
|
|
194
|
+
|
|
195
|
+
### Extension Points
|
|
196
|
+
- **New mode:** Add a new key to `modes` in agent.json, handle in `loop.js`
|
|
197
|
+
- **New built-in tool:** Add file to `tools/`, register in `registry.js`
|
|
198
|
+
- **New transport:** Add folder alongside `api/` and `cli/` (e.g., `grpc/`)
|
|
199
|
+
- **New storage backend:** Replace `infrastructure/database.js` (core uses abstract queries)
|
|
200
|
+
- **New MCP transport:** Add to `infrastructure/mcp.js`
|
|
201
|
+
|
|
202
|
+
### Implementation Standards (enforced by code review + tests)
|
|
203
|
+
|
|
204
|
+
1. **Schema-first loading:** `agent.json` and `settings.json` are validated against their JSON schemas using ajv at load time. Any invalid file produces a clear error and the agent/setting is not used. Never use unvalidated config.
|
|
205
|
+
|
|
206
|
+
2. **No `process.cwd()` in modules:** Only `src/cli/index.js` may call `process.cwd()`. All other modules receive `cwd` via `context.getCwd()`. Enforced by grep in CI: `grep -r 'process.cwd()' src/ --exclude='src/cli/*'` must return empty.
|
|
207
|
+
|
|
208
|
+
3. **Settings field names from constants:** All references to settings field names (`base_url`, `api_key`, etc.) must use `src/settings/fields.js` exports. No inline string literals.
|
|
209
|
+
|
|
210
|
+
4. **Locked dependencies:** `package.json` uses exact versions. CI runs `npm ci`. Before merging, run `node -e "const p = require('./package.json'); const used = []; /* grep all requires */"` to audit all `require()`d packages are listed.
|
|
211
|
+
|
|
212
|
+
5. **Example agent in CI:** `examples/agents/hello/agent.json` is validated against the schema in the smoke test. If it fails, the build fails. This is the canary for schema changes.
|
package/PLAN/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# VeilCLI — Specification v3.0
|
|
2
|
+
|
|
3
|
+
VeilCLI is an **enterprise autonomous agent runtime** — a locally-running Node.js server that manages autonomous AI agents via a REST API.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
| # | Section | Description |
|
|
10
|
+
|---|---------|-------------|
|
|
11
|
+
| 01 | [Vision](01-vision.md) | Identity, philosophy, non-goals |
|
|
12
|
+
| 02 | [Tech Stack](02-tech-stack.md) | Language, dependencies, confirmed choices |
|
|
13
|
+
| 03 | [Agents](03-agents.md) | Agent definition, modes (chat/task/daemon/subagent), agent.json, sub-agents |
|
|
14
|
+
| 04 | [Runtime](04-runtime.md) | Agentic loop, model delegation, context engineering, system prompts |
|
|
15
|
+
| 05 | [Tools](05-tools.md) | Built-in tools, custom JS tools, MCP, skills, discovery |
|
|
16
|
+
| 06 | [Communication](06-communication.md) | A2A messaging, sub-agent spawning, task system |
|
|
17
|
+
| 07 | [Storage](07-storage.md) | SQLite, retention, file-based config |
|
|
18
|
+
| 08 | [API & CLI](08-api-cli.md) | REST API endpoints, CLI commands |
|
|
19
|
+
| 09 | [Permissions & Hooks](09-permissions.md) | Permission system, PreToolUse/PostToolUse |
|
|
20
|
+
| 10 | [Ably](10-ably.md) | Remote access via Ably Realtime |
|
|
21
|
+
| 11 | [File Formats](11-file-formats.md) | agent.json, config.json, settings.json, AGENT.md, SKILL.md, tool.json |
|
|
22
|
+
| 12 | [Folder Structure](12-folder-structure.md) | Project-level, global |
|
|
23
|
+
| 13 | [Operations](13-operations.md) | Failure/recovery, testing, compatibility, import, Veil.com |
|
package/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# VeilCLI
|
|
2
|
+
|
|
3
|
+
**Enterprise autonomous agent runtime — local, API-first, multi-model.**
|
|
4
|
+
|
|
5
|
+
VeilCLI lets you define AI agents as simple files, run them as a local REST server, and control them through a clean HTTP API or interactive CLI. Agents can chat, run multi-step tasks with tools, spawn sub-agents, schedule cron jobs, and maintain persistent memory — all without external services.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Key Features
|
|
10
|
+
|
|
11
|
+
- **4 agent modes** — Chat, Task, Daemon (cron), Subagent
|
|
12
|
+
- **24 built-in tools** — bash, file I/O, web search/fetch, memory, multi-agent communication, todos, and more
|
|
13
|
+
- **Persistent memory** — per-agent and project-wide Markdown memory files
|
|
14
|
+
- **Multi-agent orchestration** — parallel fan-out, durable subscriptions, sync/async spawning
|
|
15
|
+
- **Layered config** — global → project → local → CLI flags
|
|
16
|
+
- **Any OpenAI-compatible LLM** — OpenRouter, local Ollama, Azure, etc.
|
|
17
|
+
- **Zero external dependencies** — SQLite storage, native fetch, Node.js only
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
- **Node.js ≥ 18.3.0**
|
|
24
|
+
- An OpenAI-compatible API key (e.g. [OpenRouter](https://openrouter.ai))
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g @newsails/veil-cli
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# 1. Set up a workspace
|
|
40
|
+
mkdir my-workspace && cd my-workspace
|
|
41
|
+
|
|
42
|
+
# 2. Save your API key (Optional)
|
|
43
|
+
veil login --key sk-or-v1-...
|
|
44
|
+
|
|
45
|
+
# 3. Start the server
|
|
46
|
+
veil start
|
|
47
|
+
|
|
48
|
+
# 4. Chat with the default agent
|
|
49
|
+
curl -X POST http://localhost:5050/agents/hello/chat \
|
|
50
|
+
-H "Content-Type: application/json" \
|
|
51
|
+
-d '{"message": "Hello!"}'
|
|
52
|
+
|
|
53
|
+
# 5. Run a task with tools
|
|
54
|
+
curl -X POST http://localhost:5050/agents/assistant/task \
|
|
55
|
+
-H "Content-Type: application/json" \
|
|
56
|
+
-d '{"input": "List all .js files in the current directory"}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
→ See **[docs/guide/01-quickstart.md](docs/guide/01-quickstart.md)** for the full walkthrough.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Documentation
|
|
64
|
+
|
|
65
|
+
### API Reference
|
|
66
|
+
| Doc | Contents |
|
|
67
|
+
|-----|----------|
|
|
68
|
+
| [docs/api/README.md](docs/api/README.md) | Overview, auth, error codes |
|
|
69
|
+
| [docs/api/01-system.md](docs/api/01-system.md) | `/health`, `/status`, `/shutdown` |
|
|
70
|
+
| [docs/api/02-agents.md](docs/api/02-agents.md) | List and inspect agents |
|
|
71
|
+
| [docs/api/03-chat.md](docs/api/03-chat.md) | Chat endpoint, multi-turn sessions |
|
|
72
|
+
| [docs/api/04-tasks.md](docs/api/04-tasks.md) | Task lifecycle, events, polling |
|
|
73
|
+
| [docs/api/05-sessions.md](docs/api/05-sessions.md) | Session management and messages |
|
|
74
|
+
| [docs/api/06-daemons.md](docs/api/06-daemons.md) | Daemon control endpoints |
|
|
75
|
+
|
|
76
|
+
### Project Guide
|
|
77
|
+
| Doc | Contents |
|
|
78
|
+
|-----|----------|
|
|
79
|
+
| [docs/guide/README.md](docs/guide/README.md) | Guide index |
|
|
80
|
+
| [docs/guide/01-quickstart.md](docs/guide/01-quickstart.md) | Install, first agent, first request |
|
|
81
|
+
| [docs/guide/02-folder-structure.md](docs/guide/02-folder-structure.md) | `.veil/` layout explained |
|
|
82
|
+
| [docs/guide/03-configuration.md](docs/guide/03-configuration.md) | `settings.json` + `auth.json` full reference |
|
|
83
|
+
| [docs/guide/04-agents.md](docs/guide/04-agents.md) | `agent.json`, `AGENT.md`, all 4 modes |
|
|
84
|
+
| [docs/guide/05-cli.md](docs/guide/05-cli.md) | `veil` CLI commands reference |
|
|
85
|
+
| [docs/guide/06-tools.md](docs/guide/06-tools.md) | All 24 built-in tools |
|
|
86
|
+
| [docs/guide/07-permissions.md](docs/guide/07-permissions.md) | Permissions system |
|
|
87
|
+
| [docs/guide/08-memory.md](docs/guide/08-memory.md) | Memory + context compaction |
|
|
88
|
+
| [docs/guide/09-multi-agent.md](docs/guide/09-multi-agent.md) | Orchestration patterns |
|
|
89
|
+
| [docs/guide/10-daemons.md](docs/guide/10-daemons.md) | Daemon / cron agents |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## CLI Reference (Quick)
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
veil start [--port 5050] [--folder ./workspace] [--secret <token>]
|
|
97
|
+
veil run --agent hello --input "What time is it?"
|
|
98
|
+
veil stop
|
|
99
|
+
veil status
|
|
100
|
+
veil agents list
|
|
101
|
+
veil agents inspect <name>
|
|
102
|
+
veil login --key <api-key> [--global]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
→ Full reference: [docs/guide/05-cli.md](docs/guide/05-cli.md)
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Project Layout
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
VeilCli/
|
|
113
|
+
cli/ ← Veil CLI entry point
|
|
114
|
+
api/ ← Express REST server + routes
|
|
115
|
+
core/ ← agent loader, loop, router, memory, compaction
|
|
116
|
+
tools/ ← 24 built-in tools
|
|
117
|
+
infrastructure/ ← SQLite database + scheduler
|
|
118
|
+
utils/ ← settings, paths, context
|
|
119
|
+
schemas/ ← JSON schemas for agent.json and settings.json
|
|
120
|
+
system-prompts/ ← base system prompt layers
|
|
121
|
+
examples/ ← reference agent definitions
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
MIT
|
package/REPORT.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Dead Code & Unused Dependencies Audit Report
|
|
2
|
+
|
|
3
|
+
**Project:** VeilCLI
|
|
4
|
+
**Date:** 2026-03-04
|
|
5
|
+
**Scope:** Production code in `core/`, `utils/`, `infrastructure/`, `api/`, `tools/`, `llm/`, `settings/`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
| Category | Count |
|
|
12
|
+
|----------|-------|
|
|
13
|
+
| Unused Exports | 14 |
|
|
14
|
+
| Dead Internal Functions | 2 |
|
|
15
|
+
| Orphaned Database Columns | 3 |
|
|
16
|
+
| Undocumented/Untested Routes | 0 |
|
|
17
|
+
| Orphaned Tools | 0 |
|
|
18
|
+
| Unused Dependencies | 0 |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Unused Exports
|
|
23
|
+
|
|
24
|
+
Functions/constants exported from modules but never imported elsewhere in production code.
|
|
25
|
+
|
|
26
|
+
| File | Export | Reason |
|
|
27
|
+
|------|--------|--------|
|
|
28
|
+
| `core/agent.js:182` | `loadAgentFromFolder` | Only used internally by `loadAgent()` in same file — no external imports |
|
|
29
|
+
| `core/agent.js:182` | `resolveAgentFolder` | Only used internally in `loadAgentFromFolder()` — no external imports |
|
|
30
|
+
| `core/compaction.js:177` | `applyObservationMasking` | Only called internally by `manageContext()` — no external imports |
|
|
31
|
+
| `core/compaction.js:178` | `applyToolResultClearing` | Only called internally by `manageContext()` — no external imports |
|
|
32
|
+
| `core/compaction.js:179` | `estimateContextUsage` | Only called internally by `manageContext()` — no external imports |
|
|
33
|
+
| `core/compaction.js:180` | `compactMessages` | Only called internally by `manageContext()` — no external imports |
|
|
34
|
+
| `core/loop.js:493` | `checkPermission` | Only used internally in `runLoop()` — no external imports |
|
|
35
|
+
| `core/registry.js:248` | `registerBuiltin` | Only called by `loadBuiltinTools()` in same file — no external imports |
|
|
36
|
+
| `core/registry.js:255` | `toolToOpenAIFormat` | Only used internally by `buildToolsForLLM()` — no external imports |
|
|
37
|
+
| `core/registry.js:256` | `getBuiltinNames` | Never imported anywhere — exposed but unused |
|
|
38
|
+
| `core/queue.js:99` | `hasPendingMessages` | Never imported anywhere — exposed but unused |
|
|
39
|
+
| `core/queue.js:99` | `drainNonFollowup` | Never imported anywhere — exposed but unused |
|
|
40
|
+
| `core/queue.js:99` | `drainFollowup` | Never imported anywhere — exposed but unused |
|
|
41
|
+
| `core/queue.js:99` | `postCorrelatedResponse` | Never imported anywhere — exposed but unused |
|
|
42
|
+
| `core/memory.js:99` | `readMemory` | Never imported anywhere (tools use direct fs access) — exposed but unused |
|
|
43
|
+
| `core/memory.js:99` | `searchMemory` | Never imported anywhere (memory_search.js uses its own implementation) — exposed but unused |
|
|
44
|
+
| `utils/settings.js:134` | `deepMerge` | Only used internally in `loadSettings()` — no external imports |
|
|
45
|
+
| `utils/settings.js:134` | `getDefaults` | Only used internally in `loadSettings()` — no external imports |
|
|
46
|
+
| `utils/paths.js:214` | `getBackupsDir` | Never imported anywhere — exposed but unused |
|
|
47
|
+
| `utils/paths.js:210` | `getGlobalSkillsDir` | Never imported anywhere — exposed but unused |
|
|
48
|
+
| `infrastructure/database.js:464` | `runMigrations` | Only called internally by `getDb()` — no external imports |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Dead Internal Functions
|
|
53
|
+
|
|
54
|
+
Private helpers defined but never called within their own file.
|
|
55
|
+
|
|
56
|
+
| File | Function | Reason |
|
|
57
|
+
|------|----------|--------|
|
|
58
|
+
| `core/memory.js:51` | `exportOldMemory` | Called by `writeMemory()` but `writeMemory()` itself is never called (tools use direct fs access) |
|
|
59
|
+
|
|
60
|
+
> **Note:** Most internal helper functions ARE called within their files. The `core/memory.js` module appears to be legacy — the actual `memory_write.js` tool uses direct filesystem operations instead of calling the core memory module.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Orphaned Database Columns
|
|
65
|
+
|
|
66
|
+
Columns defined in migrations but never read or written by production code.
|
|
67
|
+
|
|
68
|
+
| Table | Column | Reason |
|
|
69
|
+
|-------|--------|--------|
|
|
70
|
+
| `sessions` | `compaction_count` | No camelCase (`compactionCount`) usage in production code; only in `.OLD/` legacy code |
|
|
71
|
+
| `sessions` | `estimated_cost` | No camelCase (`estimatedCost`) usage in production code; only in `.OLD/` legacy code |
|
|
72
|
+
| `tasks` | `estimated_cost` | No camelCase (`estimatedCost`) usage in production code; only in `.OLD/` legacy code |
|
|
73
|
+
|
|
74
|
+
> **Note:** The `token_cache` column IS used — written via `tokenCache` in `core/loop.js:307` and `core/router.js`.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Undocumented/Untested Routes
|
|
79
|
+
|
|
80
|
+
All API routes are documented and tested.
|
|
81
|
+
|
|
82
|
+
| Route | Documented | Tested |
|
|
83
|
+
|-------|------------|--------|
|
|
84
|
+
| All routes in `api/routes/*.js` | ✅ `docs/api/*.md` | ✅ `test/integration/*.test.js` |
|
|
85
|
+
|
|
86
|
+
**Verification:**
|
|
87
|
+
- `/settings` — documented in `08-settings.md`, tested in `17-settings-api.test.js`
|
|
88
|
+
- `/memory/*` — documented in `07-memory.md`, tested in `16-memory-api.test.js`
|
|
89
|
+
- All other routes covered by existing docs and tests
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Orphaned Tools
|
|
94
|
+
|
|
95
|
+
All tools in `tools/` are properly registered and reachable.
|
|
96
|
+
|
|
97
|
+
| Tool | Status |
|
|
98
|
+
|------|--------|
|
|
99
|
+
| All 24 tools in `tools/*.js` | ✅ Loaded via `core/registry.js:loadBuiltinTools()` |
|
|
100
|
+
|
|
101
|
+
**Verification:**
|
|
102
|
+
- `loadBuiltinTools()` in `core/registry.js:37-48` iterates over all `.js` files in the `tools/` directory
|
|
103
|
+
- Each tool exports `{ schema, execute }` and is automatically registered
|
|
104
|
+
- No orphaned tools found
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Unused Dependencies
|
|
109
|
+
|
|
110
|
+
All dependencies in `package.json` are imported somewhere in production code.
|
|
111
|
+
|
|
112
|
+
| Package | Usage |
|
|
113
|
+
|---------|-------|
|
|
114
|
+
| `ajv` | `core/agent.js`, `core/registry.js`, `api/routes/settings.js` |
|
|
115
|
+
| `ajv-formats` | `core/registry.js`, `api/routes/settings.js` |
|
|
116
|
+
| `better-sqlite3` | `infrastructure/database.js` |
|
|
117
|
+
| `cors` | `api/server.js` |
|
|
118
|
+
| `express` | `api/server.js`, `api/routes/*.js` |
|
|
119
|
+
| `node-cron` | `infrastructure/scheduler.js` |
|
|
120
|
+
| `ws` | `api/server.js` (WebSocket server) |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Recommendations
|
|
125
|
+
|
|
126
|
+
### High Priority (Remove Dead Code)
|
|
127
|
+
|
|
128
|
+
1. **`core/queue.js`** — The entire module appears unused. The loop uses `drainMessageQueue()` defined inline in `core/loop.js:106-114`. Consider:
|
|
129
|
+
- Removing `core/queue.js` entirely, OR
|
|
130
|
+
- Refactoring `core/loop.js` to use `core/queue.js` functions
|
|
131
|
+
|
|
132
|
+
2. **`core/memory.js`** — The module is bypassed by tools (`memory_read.js`, `memory_write.js`, `memory_search.js` all use direct fs access). Consider:
|
|
133
|
+
- Having tools use this module, OR
|
|
134
|
+
- Removing the module
|
|
135
|
+
|
|
136
|
+
3. **Orphaned DB columns** (`compaction_count`, `estimated_cost`) — These columns are never written. Either:
|
|
137
|
+
- Implement cost tracking, OR
|
|
138
|
+
- Remove via a migration
|
|
139
|
+
|
|
140
|
+
### Low Priority (API Surface Cleanup)
|
|
141
|
+
|
|
142
|
+
4. **Unexported internal helpers** — Many functions are exported but only used internally. Consider reducing module.exports to only externally-used functions:
|
|
143
|
+
- `core/agent.js`: Remove `loadAgentFromFolder`, `resolveAgentFolder` from exports
|
|
144
|
+
- `core/compaction.js`: Only export `manageContext`
|
|
145
|
+
- `core/registry.js`: Remove `registerBuiltin`, `toolToOpenAIFormat`, `getBuiltinNames`
|
|
146
|
+
- `utils/settings.js`: Remove `deepMerge`, `getDefaults`
|
|
147
|
+
- `utils/paths.js`: Remove `getBackupsDir`, `getGlobalSkillsDir`
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Files Analyzed
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
core/agent.js, core/cancel.js, core/compaction.js, core/events.js,
|
|
155
|
+
core/loop.js, core/memory.js, core/prompt.js, core/queue.js,
|
|
156
|
+
core/registry.js, core/router.js
|
|
157
|
+
|
|
158
|
+
utils/context.js, utils/id.js, utils/paths.js, utils/settings.js
|
|
159
|
+
|
|
160
|
+
infrastructure/database.js, infrastructure/scheduler.js
|
|
161
|
+
|
|
162
|
+
llm/client.js
|
|
163
|
+
|
|
164
|
+
settings/fields.js
|
|
165
|
+
|
|
166
|
+
api/middleware.js, api/server.js
|
|
167
|
+
api/routes/agents.js, api/routes/chat.js, api/routes/daemons.js,
|
|
168
|
+
api/routes/memory.js, api/routes/sessions.js, api/routes/settings.js,
|
|
169
|
+
api/routes/system.js, api/routes/tasks.js
|
|
170
|
+
|
|
171
|
+
tools/*.js (24 files)
|
|
172
|
+
|
|
173
|
+
migrations/001-initial.sql, migrations/002-debuggability.sql
|
|
174
|
+
```
|
package/TODO.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
## TODO
|
|
2
|
+
|
|
3
|
+
<!-- - SYSTEM PROMPT URGENT FIXES:
|
|
4
|
+
+ Make it smaller
|
|
5
|
+
+ Remove full date+time, just date (Breaks cache at every call) -->
|
|
6
|
+
- API do not support generating/receiving multi modal (images, audio, video, ...)
|
|
7
|
+
<!-- - Create a Models.json file with all the models and their data to be used as default, until we build a dedicated endpoint to get models data from main domain veil.com (Use OpenRouter API to get the default models data) -->
|
|
8
|
+
<!-- - Expose the chat completion endpoint as a standalone function, so apps based on Veil can use it for independent AI usage -->
|
|
9
|
+
- Compaction, it should be more robust, clear and configurable with Multi methods compaction, Methods:
|
|
10
|
+
+ Context summarization (based on Claude's Automatic Context Compaction approach):
|
|
11
|
+
> **How it works:**
|
|
12
|
+
- Monitor token usage per turn via `context_token_threshold`
|
|
13
|
+
- When threshold exceeded, inject a summary prompt as a user turn
|
|
14
|
+
- Model generates a summary wrapped in `<summary></summary>` tags
|
|
15
|
+
- Clear conversation history and resume with only the summary
|
|
16
|
+
- Continue task with compressed context
|
|
17
|
+
> **Configuration options:**
|
|
18
|
+
- `enabled`: Boolean to enable/disable compaction
|
|
19
|
+
- `context_token_threshold`: Token count that triggers compaction (default: 100k, low: 5k-20k for sequential tasks, medium: 50k-100k for multi-phase, high: 100k-150k for context-heavy tasks)
|
|
20
|
+
- `model`: Optional cheaper/faster model for summarization (e.g., `claude-haiku-4-5`)
|
|
21
|
+
- `summary_prompt`: Custom prompt to guide what info to preserve in summaries
|
|
22
|
+
> **Config hierarchy (lowest wins):**
|
|
23
|
+
- Main level: `~/.veil/settings.json`
|
|
24
|
+
- Project level: `PROJECT/.veil/settings.json`
|
|
25
|
+
- Agent level: `AGENT/agent.json`
|
|
26
|
+
- NOTE: All used variables should be configurable (including summary prompt, model, ...)
|
|
27
|
+
> **When to use:**
|
|
28
|
+
- Sequential processing (multiple items one after another)
|
|
29
|
+
- Multi-phase workflows with natural checkpoints
|
|
30
|
+
- Batch operations with independent items
|
|
31
|
+
- Extended analysis sessions
|
|
32
|
+
> **When NOT to use:**
|
|
33
|
+
- Short tasks (<50k-100k tokens)
|
|
34
|
+
- Tasks requiring full audit trails
|
|
35
|
+
- Highly iterative refinement needing exact details from all steps
|
|
36
|
+
> **Limitations:**
|
|
37
|
+
- Information loss is inherent (mitigate via custom summary prompts)
|
|
38
|
+
- Higher thresholds preserve more detail but cost more per call
|
|
39
|
+
> Add Compaction endpoint to the sessions API to force run this method (usually for testing)
|
|
40
|
+
+ Files Clearing:
|
|
41
|
+
> Clearing attached files after a specific negative index threshold (exp: Truncate all tool calls before last 10 messages)
|
|
42
|
+
+ Long Tool Call results truncation:
|
|
43
|
+
> Truncating long toolcall results after a specific negative index threshold (exp: Truncate all tool calls before last 10 messages)
|
|
44
|
+
> Can be configured with a custom threshold per tool type (per tool key)
|
|
45
|
+
+ NOTE: Clear code to be able to add new methods easily
|