@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,153 @@
|
|
|
1
|
+
# 08 — API & CLI
|
|
2
|
+
|
|
3
|
+
## REST API
|
|
4
|
+
|
|
5
|
+
**Base URL:** `http://localhost:5050` (configurable)
|
|
6
|
+
**Auth:** Optional `X-Veil-Secret` header
|
|
7
|
+
**Format:** JSON request/response. No streaming. No WebSocket. Chat requests block until the agent responds (HTTP long-poll). Clients should set appropriate timeouts.
|
|
8
|
+
**Pagination:** Cursor-based for list endpoints (`?cursor=<id>&limit=20`)
|
|
9
|
+
**Errors:** Standard format: `{ "error": { "code": "ERROR_CODE", "message": "..." } }`
|
|
10
|
+
|
|
11
|
+
> **CWD in routes:** Routes never call `process.cwd()`. The project working directory is passed from the CLI at startup and stored in `src/utils/context.js`. Routes call `context.getCwd()` to get the correct project directory. This prevents routes from silently scanning the wrong folder when the server is started from a different directory.
|
|
12
|
+
|
|
13
|
+
### Endpoints
|
|
14
|
+
|
|
15
|
+
#### Agents
|
|
16
|
+
| Method | Path | Description |
|
|
17
|
+
|--------|------|-------------|
|
|
18
|
+
| GET | `/agents` | List all discovered agents |
|
|
19
|
+
| GET | `/agents/:name` | Get agent details (config, modes, skills, tools) |
|
|
20
|
+
|
|
21
|
+
#### Chat Mode
|
|
22
|
+
| Method | Path | Description |
|
|
23
|
+
|--------|------|-------------|
|
|
24
|
+
| POST | `/agents/:name/chat` | Send message (creates session or resumes) |
|
|
25
|
+
|
|
26
|
+
**Request:**
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"message": "Hello, agent!",
|
|
30
|
+
"sessionId": "sess_abc123",
|
|
31
|
+
"files": [{ "path": "./src/auth.js" }]
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
**Response:**
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"sessionId": "sess_abc123",
|
|
38
|
+
"message": { "role": "assistant", "content": "..." },
|
|
39
|
+
"tokenUsage": { "input": 1500, "output": 300, "cache": 0 }
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### Task Mode
|
|
44
|
+
| Method | Path | Description |
|
|
45
|
+
|--------|------|-------------|
|
|
46
|
+
| POST | `/agents/:name/task` | Create a new task |
|
|
47
|
+
| GET | `/tasks` | List tasks (filter: agent, status, priority, tags) |
|
|
48
|
+
| GET | `/tasks/:id` | Get task details |
|
|
49
|
+
| GET | `/tasks/:id/events` | Get task progress events |
|
|
50
|
+
| POST | `/tasks/:id/respond` | Respond to a waiting task |
|
|
51
|
+
| POST | `/tasks/:id/cancel` | Cancel a task |
|
|
52
|
+
|
|
53
|
+
**Create task request:**
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"input": "Research the best auth libraries for Node.js",
|
|
57
|
+
"priority": "high",
|
|
58
|
+
"tags": ["research", "auth"],
|
|
59
|
+
"files": [{ "path": "./requirements.md" }],
|
|
60
|
+
"maxIterations": 30,
|
|
61
|
+
"maxDurationSeconds": 600
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
**Create task response:**
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"taskId": "task_xyz789",
|
|
68
|
+
"status": "pending"
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### Daemon Mode
|
|
73
|
+
| Method | Path | Description |
|
|
74
|
+
|--------|------|-------------|
|
|
75
|
+
| GET | `/daemons` | List active daemons (status, next tick, last result). State is in-memory, rebuilt from agent.json on restart. |
|
|
76
|
+
| POST | `/agents/:name/daemon/trigger` | Trigger a daemon tick manually |
|
|
77
|
+
| POST | `/agents/:name/daemon/start` | Start a daemon |
|
|
78
|
+
| POST | `/agents/:name/daemon/stop` | Stop a daemon |
|
|
79
|
+
|
|
80
|
+
#### Sessions
|
|
81
|
+
| Method | Path | Description |
|
|
82
|
+
|--------|------|-------------|
|
|
83
|
+
| GET | `/sessions` | List sessions (filter: agent, mode, status) |
|
|
84
|
+
| GET | `/sessions/:id` | Get session details |
|
|
85
|
+
| GET | `/sessions/:id/messages` | Get messages (paginated) |
|
|
86
|
+
| DELETE | `/sessions/:id` | Close/delete session |
|
|
87
|
+
|
|
88
|
+
#### System
|
|
89
|
+
| Method | Path | Description |
|
|
90
|
+
|--------|------|-------------|
|
|
91
|
+
| GET | `/health` | Health check |
|
|
92
|
+
| GET | `/status` | System status (uptime, agents, sessions, tasks, daemons) |
|
|
93
|
+
| POST | `/shutdown` | Graceful shutdown |
|
|
94
|
+
|
|
95
|
+
### Error Codes
|
|
96
|
+
|
|
97
|
+
| Code | HTTP Status | Description |
|
|
98
|
+
|------|-------------|-------------|
|
|
99
|
+
| `AGENT_NOT_FOUND` | 404 | Agent doesn't exist |
|
|
100
|
+
| `MODE_NOT_SUPPORTED` | 400 | Agent doesn't support requested mode |
|
|
101
|
+
| `TASK_NOT_FOUND` | 404 | Task doesn't exist |
|
|
102
|
+
| `SESSION_NOT_FOUND` | 404 | Session doesn't exist |
|
|
103
|
+
| `SESSION_CLOSED` | 400 | Session is closed |
|
|
104
|
+
| `TASK_NOT_WAITING` | 400 | Task is not in waiting status |
|
|
105
|
+
| `PERMISSION_DENIED` | 403 | Invalid or missing secret |
|
|
106
|
+
| `VALIDATION_ERROR` | 400 | Invalid request body |
|
|
107
|
+
| `INTERNAL_ERROR` | 500 | Unexpected error |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## CLI
|
|
112
|
+
|
|
113
|
+
### Server Mode
|
|
114
|
+
```
|
|
115
|
+
veil start [--port <n>] [--folder <path>] [--secret <s>] [--ably]
|
|
116
|
+
```
|
|
117
|
+
- Loads all agent definitions, auto-starts daemons, exposes REST API
|
|
118
|
+
- Writes PID file to `.veil/runtime.pid`
|
|
119
|
+
- Sets `context.setCwd(cwd)` at startup — used by all routes and agents internally
|
|
120
|
+
|
|
121
|
+
> **Settings location:** Project settings must be in `.veil/settings.json`, NOT `./settings.json` at the project root. The root-level `settings.json` is never read. This is a common mistake when setting up a new project.
|
|
122
|
+
|
|
123
|
+
### One-Shot Mode
|
|
124
|
+
```
|
|
125
|
+
veil run --agent <name> --input "..." [--input-file <path>] [--output-file <path>] [--timeout <s>]
|
|
126
|
+
```
|
|
127
|
+
- Creates a task, runs to completion, exits
|
|
128
|
+
- Progress to stdout: `VEIL_PROGRESS={"type":"tool.end","name":"grep","duration":120}`
|
|
129
|
+
- Exit 0 on success (result JSON to stdout), exit 1 on failure (error JSON to stderr)
|
|
130
|
+
- Multiple one-shot instances can run in parallel (shared SQLite via WAL)
|
|
131
|
+
|
|
132
|
+
### Management Commands
|
|
133
|
+
```
|
|
134
|
+
veil stop # Graceful shutdown
|
|
135
|
+
veil status # Show running server info
|
|
136
|
+
veil agents list # List all discovered agents
|
|
137
|
+
veil agents inspect <name> # Show agent details
|
|
138
|
+
veil agents create # Interactive agent creation wizard
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Import
|
|
142
|
+
```
|
|
143
|
+
veil import --type=claude-code|openclaw|raw --source <path>
|
|
144
|
+
```
|
|
145
|
+
- Transforms source format to VeilCLI format
|
|
146
|
+
- Interactive: asks follow-up questions to configure agent modes
|
|
147
|
+
- Extensible adapter system
|
|
148
|
+
|
|
149
|
+
### Login
|
|
150
|
+
```
|
|
151
|
+
veil login --key <token> [--global]
|
|
152
|
+
```
|
|
153
|
+
- Default: stores in project `.veil/auth.json`. With `--global`: stores in `~/.veil/auth.json`.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# 09 — Permissions & Hooks
|
|
2
|
+
|
|
3
|
+
## Permission System
|
|
4
|
+
|
|
5
|
+
Adopted from Claude Code. Evaluated in order: **deny → ask → allow**.
|
|
6
|
+
|
|
7
|
+
### Permission Format
|
|
8
|
+
```
|
|
9
|
+
tool_name(pattern)
|
|
10
|
+
|
|
11
|
+
Examples:
|
|
12
|
+
bash(npm run *) ← bash commands starting with "npm run"
|
|
13
|
+
read_file(**) ← read any file recursively
|
|
14
|
+
write_file(./src/**) ← write anywhere in src/
|
|
15
|
+
edit_file(./src/**) ← edit anywhere in src/
|
|
16
|
+
web_fetch(https://api.*) ← fetch from api.* domains
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Tool names are snake_case** — must match exactly. All built-in tools use snake_case (`bash`, `read_file`, `write_file`, `web_fetch`, etc.).
|
|
20
|
+
|
|
21
|
+
### MCP Tool Permissions
|
|
22
|
+
|
|
23
|
+
MCP tools use the format `mcp:<server>.<tool>`:
|
|
24
|
+
```
|
|
25
|
+
mcp:filesystem.read_file(**) ← MCP filesystem server's read_file
|
|
26
|
+
mcp:database.query(SELECT *) ← MCP database server's query tool
|
|
27
|
+
mcp:*.*(**) ← all MCP tools (wildcard)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Defaults
|
|
31
|
+
- **Always denied:** `read_file(./.veil/auth.json)`, `read_file(~/.veil/auth.json)`
|
|
32
|
+
- **Interactive mode (chat):** default `ask` — agent requests permission, user approves
|
|
33
|
+
- **Non-interactive mode (task, daemon, subagent, one-shot):** default `deny` — must be explicitly allowed
|
|
34
|
+
|
|
35
|
+
### Configuration Layers
|
|
36
|
+
|
|
37
|
+
Permissions resolved in order (last wins):
|
|
38
|
+
```
|
|
39
|
+
1. Built-in defaults (auth.json always denied)
|
|
40
|
+
2. ~/.veil/settings.json → permissions
|
|
41
|
+
3. ./.veil/settings.json → permissions
|
|
42
|
+
4. ./.veil/settings.local.json → permissions
|
|
43
|
+
5. agent.json → modes.<mode>.permissions ← per-agent, per-mode overrides
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Interaction with `disallowedTools`
|
|
47
|
+
|
|
48
|
+
The permission system and `disallowedTools` in agent.json are complementary:
|
|
49
|
+
- **`disallowedTools`** — removes the tool entirely from the agent's toolset (LLM never sees it)
|
|
50
|
+
- **Permissions** — controls whether a visible tool can actually execute (deny/ask/allow)
|
|
51
|
+
|
|
52
|
+
Resolution order: `disallowedTools` checked first (tool removed) → then permissions checked (tool allowed/denied).
|
|
53
|
+
|
|
54
|
+
Per-agent, per-mode permissions in agent.json support `allow` and `deny` only. The `ask` level is only available in settings.json because it requires interactive user approval, which is a global behavior — not agent-specific.
|
|
55
|
+
|
|
56
|
+
Example:
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"modes": {
|
|
60
|
+
"task": {
|
|
61
|
+
"permissions": {
|
|
62
|
+
"allow": ["bash(npm run *)", "read_file(**)", "write_file(./src/**)"],
|
|
63
|
+
"deny": ["bash(rm *)"]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Hooks
|
|
73
|
+
|
|
74
|
+
Two hooks only: **PreToolUse** and **PostToolUse**. Shell commands defined in settings.json.
|
|
75
|
+
|
|
76
|
+
### Configuration
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"hooks": {
|
|
80
|
+
"PreToolUse": "node .veil/hooks/pre-tool.js",
|
|
81
|
+
"PostToolUse": "node .veil/hooks/post-tool.js"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Environment Variables
|
|
87
|
+
Hooks receive context via environment variables:
|
|
88
|
+
|
|
89
|
+
| Variable | Description |
|
|
90
|
+
|----------|-------------|
|
|
91
|
+
| `VEIL_TOOL_NAME` | Tool being called (e.g., `bash`, `write_file`) |
|
|
92
|
+
| `VEIL_TOOL_INPUT` | JSON-encoded tool input |
|
|
93
|
+
| `VEIL_TOOL_OUTPUT` | JSON-encoded tool output (PostToolUse only) |
|
|
94
|
+
| `VEIL_AGENT_NAME` | Agent calling the tool |
|
|
95
|
+
| `VEIL_SESSION_ID` | Current session ID |
|
|
96
|
+
| `VEIL_TASK_ID` | Current task ID (if in task mode) |
|
|
97
|
+
| `VEIL_MODE` | Current mode: chat/task/daemon/subagent |
|
|
98
|
+
| `VEIL_AGENT_FOLDER` | Absolute path to agent's folder |
|
|
99
|
+
|
|
100
|
+
### Behavior
|
|
101
|
+
- **PreToolUse:** Exit 0 → allow tool execution. Exit 1 → block (tool returns error to LLM).
|
|
102
|
+
- **PostToolUse:** Exit 0 → continue. Exit 1 → log warning (tool already executed).
|
|
103
|
+
- **Timeout:** 10s default. Hook killed on timeout, tool proceeds.
|
|
104
|
+
|
|
105
|
+
### Use Cases
|
|
106
|
+
- `PreToolUse` where `VEIL_TOOL_NAME=bash` → validate bash commands before execution
|
|
107
|
+
- `PostToolUse` where `VEIL_TOOL_NAME=write_file` → trigger lint/format after file write
|
|
108
|
+
- `PreToolUse` → log all tool calls to external audit system
|
package/PLAN/10-ably.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# 10 — Ably Remote Access
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
When enabled, VeilCLI subscribes to an Ably channel and relays REST API calls over it. This allows remote consumers (web app, mobile app, Veil.com dashboard) to interact with a local VeilCLI instance without port forwarding.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
[Remote Client] → [Veil.com] → [Ably Channel] → [VeilCLI (local)]
|
|
9
|
+
↓
|
|
10
|
+
REST API handler
|
|
11
|
+
↓
|
|
12
|
+
[Ably Channel] → [Veil.com] → [Remote Client]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Channel Architecture
|
|
16
|
+
|
|
17
|
+
**One channel per VeilCLI instance** (not per agent or session).
|
|
18
|
+
|
|
19
|
+
- Channel name: `veil:instance:<instanceId>`
|
|
20
|
+
- `instanceId` assigned by Veil.com on registration
|
|
21
|
+
- Namespace `veil:` allows applying Ably channel rules globally
|
|
22
|
+
|
|
23
|
+
**Message name routing** on the single channel:
|
|
24
|
+
- `api:request` — remote client → VeilCLI
|
|
25
|
+
- `api:response` — VeilCLI → remote client
|
|
26
|
+
- `task:progress` — VeilCLI pushes task progress events
|
|
27
|
+
- `system:ping` / `system:pong` — health checks
|
|
28
|
+
|
|
29
|
+
## Message Format (RPC over Pub/Sub)
|
|
30
|
+
|
|
31
|
+
Request/response via **correlation IDs** (`requestId`).
|
|
32
|
+
|
|
33
|
+
**Request:**
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"requestId": "req_a1b2c3d4",
|
|
37
|
+
"method": "POST",
|
|
38
|
+
"path": "/agents/researcher/task",
|
|
39
|
+
"headers": { "X-Veil-Secret": "mysecret" },
|
|
40
|
+
"body": { "input": "Research topic X" },
|
|
41
|
+
"timestamp": 1740793200000,
|
|
42
|
+
"timeout": 30000
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Response:**
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"requestId": "req_a1b2c3d4",
|
|
50
|
+
"status": 200,
|
|
51
|
+
"body": { "taskId": "task_xyz789", "status": "pending" },
|
|
52
|
+
"timestamp": 1740793201500,
|
|
53
|
+
"duration": 1500
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Authentication Flow
|
|
58
|
+
|
|
59
|
+
1. VeilCLI starts with `ably.enabled: true`
|
|
60
|
+
2. Creates Ably Realtime client with `authCallback`
|
|
61
|
+
3. `authCallback` calls Veil.com: `POST /api/v1/ably/token` with `veil_token`
|
|
62
|
+
4. Veil.com validates token, issues scoped Ably TokenRequest (1h TTL)
|
|
63
|
+
5. Ably SDK handles automatic token refresh before expiry
|
|
64
|
+
6. VeilCLI enters presence on its channel to signal "online"
|
|
65
|
+
|
|
66
|
+
**Remote clients never connect to Ably directly.** Veil.com relays on their behalf.
|
|
67
|
+
|
|
68
|
+
## Reliability
|
|
69
|
+
|
|
70
|
+
| Offline Duration | Ably State | Behavior |
|
|
71
|
+
|-----------------|------------|----------|
|
|
72
|
+
| 0–2 min | `disconnected` | Auto-reconnect. Missed messages replayed. |
|
|
73
|
+
| >2 min | `suspended` | Messages during gap are lost. Re-enter presence on reconnect. |
|
|
74
|
+
| Extended | `failed` | Auth token expired. Log error, await manual reconnect. |
|
|
75
|
+
|
|
76
|
+
**Stale request handling:** Requests with `timestamp` older than `timeout` are skipped — remote client already timed out.
|
|
77
|
+
|
|
78
|
+
## Limits
|
|
79
|
+
|
|
80
|
+
- **Message size:** 64 KiB. Responses >60 KiB truncated with `{ "truncated": true, "fetchUrl": "/messages/msg_xyz/full" }`.
|
|
81
|
+
- **Rate:** 50 msg/s per channel (sufficient for VeilCLI's use case).
|
|
82
|
+
- **Latency overhead:** ~100-300ms round-trip. Negligible vs LLM call time.
|
|
83
|
+
|
|
84
|
+
## Security
|
|
85
|
+
|
|
86
|
+
Even though VeilCLI trusts Veil.com:
|
|
87
|
+
- Validate incoming message schema (required fields, method whitelist)
|
|
88
|
+
- Local `X-Veil-Secret` still required in relayed requests
|
|
89
|
+
- Track recent `requestId`s to reject duplicates
|
|
90
|
+
- Permission system still applies to all tool calls via Ably
|
|
91
|
+
- Optional: AES-256-CBC per-channel encryption for high-security deployments
|
|
92
|
+
|
|
93
|
+
## Settings
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"ably": {
|
|
98
|
+
"enabled": false,
|
|
99
|
+
"instanceId": "",
|
|
100
|
+
"tokenEndpoint": "https://veil.com/api/v1/ably/token",
|
|
101
|
+
"requestTimeout": 30000,
|
|
102
|
+
"maxRequestAge": 60000
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|