@dreb/coding-agent 2.34.3 → 2.35.0
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/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session.d.ts +30 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +172 -130
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/export-html/template.js +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +5 -102
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/git-branch.d.ts +19 -0
- package/dist/core/git-branch.d.ts.map +1 -0
- package/dist/core/git-branch.js +109 -0
- package/dist/core/git-branch.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +21 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +117 -42
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +8 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/{modes/interactive → core}/tab-title.d.ts +12 -3
- package/dist/core/tab-title.d.ts.map +1 -0
- package/dist/{modes/interactive → core}/tab-title.js +58 -16
- package/dist/core/tab-title.js.map +1 -0
- package/dist/core/tools/search.d.ts.map +1 -1
- package/dist/core/tools/search.js +4 -1
- package/dist/core/tools/search.js.map +1 -1
- package/dist/core/tools/subagent.d.ts +63 -2
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js +459 -73
- package/dist/core/tools/subagent.js.map +1 -1
- package/dist/core/tools/web.d.ts +1 -1
- package/dist/core/tools/web.d.ts.map +1 -1
- package/dist/core/tools/web.js +60 -16
- package/dist/core/tools/web.js.map +1 -1
- package/dist/main.d.ts +10 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +54 -4
- package/dist/main.js.map +1 -1
- package/dist/modes/index.d.ts +2 -2
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +4 -40
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +2 -2
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/index.d.ts +2 -2
- package/dist/modes/rpc/index.d.ts.map +1 -1
- package/dist/modes/rpc/index.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +114 -6
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +140 -2
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +97 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +656 -27
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +312 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/dashboard.md +152 -0
- package/docs/development.md +8 -5
- package/docs/rpc.md +652 -5
- package/examples/sdk/12-full-control.ts +1 -1
- package/package.json +1 -1
- package/dist/modes/interactive/tab-title.d.ts.map +0 -1
- package/dist/modes/interactive/tab-title.js.map +0 -1
package/docs/rpc.md
CHANGED
|
@@ -6,10 +6,10 @@ RPC mode enables headless operation of the coding agent via a JSON protocol over
|
|
|
6
6
|
|
|
7
7
|
### Running the agent child as a specific OS user
|
|
8
8
|
|
|
9
|
-
When using the `RpcClient` from `@dreb/coding-agent`, `RpcClientOptions` accepts optional `uid` and `gid` fields. When set, they are forwarded directly to `child_process.spawn`, so the agent child (and every subprocess it spawns, including `bash`) runs under that OS user/group. When unset they are omitted entirely, leaving spawn behavior unchanged.
|
|
9
|
+
When using the `RpcClient` from `@dreb/coding-agent/rpc`, `RpcClientOptions` accepts optional `uid` and `gid` fields. When set, they are forwarded directly to `child_process.spawn`, so the agent child (and every subprocess it spawns, including `bash`) runs under that OS user/group. When unset they are omitted entirely, leaving spawn behavior unchanged.
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
|
-
import { RpcClient } from "@dreb/coding-agent";
|
|
12
|
+
import { RpcClient } from "@dreb/coding-agent/rpc";
|
|
13
13
|
|
|
14
14
|
// Parent must hold CAP_SETUID / CAP_SETGID (e.g. run as root) for this to succeed.
|
|
15
15
|
const client = new RpcClient({ cwd: "/srv/users/alice", uid: 4001, gid: 4001 });
|
|
@@ -187,6 +187,10 @@ Response:
|
|
|
187
187
|
"success": true,
|
|
188
188
|
"data": {
|
|
189
189
|
"model": {...},
|
|
190
|
+
"scopedModels": [
|
|
191
|
+
{"provider": "anthropic", "id": "claude-sonnet-4-5", "name": "Claude Sonnet 4.5", "reasoning": true, "thinkingLevel": "high"}
|
|
192
|
+
],
|
|
193
|
+
"usingSubscription": false,
|
|
190
194
|
"thinkingLevel": "medium",
|
|
191
195
|
"isStreaming": false,
|
|
192
196
|
"isCompacting": false,
|
|
@@ -197,12 +201,79 @@ Response:
|
|
|
197
201
|
"sessionName": "my-feature-work",
|
|
198
202
|
"autoCompactionEnabled": true,
|
|
199
203
|
"messageCount": 5,
|
|
200
|
-
"pendingMessageCount": 0
|
|
204
|
+
"pendingMessageCount": 0,
|
|
205
|
+
"contextUsage": {
|
|
206
|
+
"tokens": 60000,
|
|
207
|
+
"contextWindow": 200000,
|
|
208
|
+
"percent": 30
|
|
209
|
+
}
|
|
201
210
|
}
|
|
202
211
|
}
|
|
203
212
|
```
|
|
204
213
|
|
|
205
|
-
The `model` field is a full [Model](#model) object or `null`. The `sessionName` field is the display name set via `set_session_name
|
|
214
|
+
The `model` field is a full [Model](#model) object or `null`. `scopedModels` is the runtime model scope (from settings `enabledModels` / CLI `--models`) in the same order used by model cycling; it is an empty array when no scope is active. `usingSubscription` is true when the active model is using OAuth subscription credentials, matching the TUI footer's `(sub)` cost indicator. The `sessionName` field is the display name set via `set_session_name` or auto-naming, or omitted if not set.
|
|
215
|
+
|
|
216
|
+
`contextUsage` carries the same numbers the TUI footer shows, computed by the session itself — clients must render these rather than deriving their own estimate. `tokens` and `percent` are `null` when usage is unknown (right after compaction, before the next LLM response). The whole field is omitted when no model is set or the model has no context window.
|
|
217
|
+
|
|
218
|
+
#### get_resources
|
|
219
|
+
|
|
220
|
+
Get loaded resource metadata for the current session. This returns paths/names/descriptions only — it does not include context file contents, prompt bodies, skill bodies, or system prompt text.
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
{"type": "get_resources"}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Response:
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"type": "response",
|
|
230
|
+
"command": "get_resources",
|
|
231
|
+
"success": true,
|
|
232
|
+
"data": {
|
|
233
|
+
"contextFiles": [{"path": "/repo/AGENTS.md"}],
|
|
234
|
+
"skills": [{"name": "review-code", "description": "Review code"}],
|
|
235
|
+
"extensions": [{"name": "my-extension", "path": "/repo/.dreb/extensions/my-extension.ts"}],
|
|
236
|
+
"promptTemplates": [{"name": "plan", "description": "Create an implementation plan"}],
|
|
237
|
+
"systemPromptPresent": true
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
#### get_git_branch
|
|
243
|
+
|
|
244
|
+
Get the current git branch for the session cwd. Returns `null` outside a git repository and `"detached"` for detached HEAD.
|
|
245
|
+
|
|
246
|
+
```json
|
|
247
|
+
{"type": "get_git_branch"}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Response:
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"type": "response",
|
|
254
|
+
"command": "get_git_branch",
|
|
255
|
+
"success": true,
|
|
256
|
+
"data": {"branch": "feature/dashboard"}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### get_daily_cost
|
|
261
|
+
|
|
262
|
+
Get the same-day aggregate cost across all session files. The RPC process scans once on first call so the first response is current, then returns the cached value (refreshed periodically by the tracker).
|
|
263
|
+
|
|
264
|
+
```json
|
|
265
|
+
{"type": "get_daily_cost"}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Response:
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
"type": "response",
|
|
272
|
+
"command": "get_daily_cost",
|
|
273
|
+
"success": true,
|
|
274
|
+
"data": {"cost": 1.23}
|
|
275
|
+
}
|
|
276
|
+
```
|
|
206
277
|
|
|
207
278
|
#### get_messages
|
|
208
279
|
|
|
@@ -244,6 +315,29 @@ Response contains the full [Model](#model) object:
|
|
|
244
315
|
}
|
|
245
316
|
```
|
|
246
317
|
|
|
318
|
+
#### resolve_model
|
|
319
|
+
|
|
320
|
+
Resolve a model pattern using the same matching rules as the interactive `/model` command, without switching the current session. Returns `null` if no model matches; a warning may be included when the match required fallback behavior.
|
|
321
|
+
|
|
322
|
+
```json
|
|
323
|
+
{"type": "resolve_model", "pattern": "sonnet"}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Response:
|
|
327
|
+
```json
|
|
328
|
+
{
|
|
329
|
+
"type": "response",
|
|
330
|
+
"command": "resolve_model",
|
|
331
|
+
"success": true,
|
|
332
|
+
"data": {"model": {...}, "warning": "matched provider/model-id"}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
If no model matches:
|
|
337
|
+
```json
|
|
338
|
+
{"type": "response", "command": "resolve_model", "success": true, "data": null}
|
|
339
|
+
```
|
|
340
|
+
|
|
247
341
|
#### cycle_model
|
|
248
342
|
|
|
249
343
|
Cycle to the next available model. Returns `null` data if only one model available.
|
|
@@ -288,6 +382,46 @@ Response contains an array of full [Model](#model) objects:
|
|
|
288
382
|
}
|
|
289
383
|
```
|
|
290
384
|
|
|
385
|
+
### Buddy
|
|
386
|
+
|
|
387
|
+
Buddy commands run inside the agent process so provider credentials never leave the RPC child. They are exposed for clients that choose to render the terminal companion; most non-terminal clients can ignore them.
|
|
388
|
+
|
|
389
|
+
#### buddy_hatch
|
|
390
|
+
|
|
391
|
+
Create or load the current buddy state.
|
|
392
|
+
|
|
393
|
+
```json
|
|
394
|
+
{"type": "buddy_hatch"}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Response:
|
|
398
|
+
```json
|
|
399
|
+
{
|
|
400
|
+
"type": "response",
|
|
401
|
+
"command": "buddy_hatch",
|
|
402
|
+
"success": true,
|
|
403
|
+
"data": {"state": {...}}
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
#### buddy_reroll
|
|
408
|
+
|
|
409
|
+
Reroll buddy appearance/state.
|
|
410
|
+
|
|
411
|
+
```json
|
|
412
|
+
{"type": "buddy_reroll"}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Response:
|
|
416
|
+
```json
|
|
417
|
+
{
|
|
418
|
+
"type": "response",
|
|
419
|
+
"command": "buddy_reroll",
|
|
420
|
+
"success": true,
|
|
421
|
+
"data": {"state": {...}}
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
291
425
|
### Thinking
|
|
292
426
|
|
|
293
427
|
#### set_thinking_level
|
|
@@ -361,6 +495,32 @@ Response:
|
|
|
361
495
|
{"type": "response", "command": "set_follow_up_mode", "success": true}
|
|
362
496
|
```
|
|
363
497
|
|
|
498
|
+
#### get_pending_messages
|
|
499
|
+
|
|
500
|
+
Return queued steering and follow-up messages without clearing them. `steering` and `followUp` are the text-only compatibility view; `steeringMessages` and `followUpMessages` include inline image attachments for clients that need to restore queued multimodal turns.
|
|
501
|
+
|
|
502
|
+
```json
|
|
503
|
+
{"type": "get_pending_messages"}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
Response:
|
|
507
|
+
```json
|
|
508
|
+
{"type": "response", "command": "get_pending_messages", "success": true, "data": {"steering": ["steer text"], "followUp": ["follow-up text"], "steeringMessages": [{"text": "steer text", "images": [{"type": "image", "data": "...", "mimeType": "image/png"}]}], "followUpMessages": [{"text": "follow-up text"}]}}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
#### clear_pending_messages
|
|
512
|
+
|
|
513
|
+
Clear queued steering and follow-up messages, returning the cleared payloads. This mirrors the TUI restore-to-editor flow; multimodal clients should use `steeringMessages`/`followUpMessages` so inline images are not lost.
|
|
514
|
+
|
|
515
|
+
```json
|
|
516
|
+
{"type": "clear_pending_messages"}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
Response:
|
|
520
|
+
```json
|
|
521
|
+
{"type": "response", "command": "clear_pending_messages", "success": true, "data": {"steering": ["steer text"], "followUp": ["follow-up text"], "steeringMessages": [{"text": "steer text", "images": [{"type": "image", "data": "...", "mimeType": "image/png"}]}], "followUpMessages": [{"text": "follow-up text"}]}}
|
|
522
|
+
```
|
|
523
|
+
|
|
364
524
|
### Compaction
|
|
365
525
|
|
|
366
526
|
#### compact
|
|
@@ -404,6 +564,19 @@ Response:
|
|
|
404
564
|
{"type": "response", "command": "set_auto_compaction", "success": true}
|
|
405
565
|
```
|
|
406
566
|
|
|
567
|
+
#### abort_compaction
|
|
568
|
+
|
|
569
|
+
Abort an in-progress manual or automatic compaction.
|
|
570
|
+
|
|
571
|
+
```json
|
|
572
|
+
{"type": "abort_compaction"}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Response:
|
|
576
|
+
```json
|
|
577
|
+
{"type": "response", "command": "abort_compaction", "success": true}
|
|
578
|
+
```
|
|
579
|
+
|
|
407
580
|
### Retry
|
|
408
581
|
|
|
409
582
|
#### set_auto_retry
|
|
@@ -621,6 +794,39 @@ If an extension cancelled the switch:
|
|
|
621
794
|
{"type": "response", "command": "switch_session", "success": true, "data": {"cancelled": true}}
|
|
622
795
|
```
|
|
623
796
|
|
|
797
|
+
#### delete_session
|
|
798
|
+
|
|
799
|
+
Delete a session file. Deletion tries trash first and falls back to unlink. The currently active session cannot be deleted.
|
|
800
|
+
|
|
801
|
+
```json
|
|
802
|
+
{"type": "delete_session", "sessionPath": "/path/to/session.jsonl"}
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
Response:
|
|
806
|
+
```json
|
|
807
|
+
{"type": "response", "command": "delete_session", "success": true, "data": {"method": "trash"}}
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
If attempting to delete the currently active session:
|
|
811
|
+
```json
|
|
812
|
+
{
|
|
813
|
+
"type": "response",
|
|
814
|
+
"command": "delete_session",
|
|
815
|
+
"success": false,
|
|
816
|
+
"error": "Cannot delete the currently active session"
|
|
817
|
+
}
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
The path uses the same unrestricted, cross-project addressing as [`switch_session`](#switch_session): it is `resolve()`d (collapsing `.`/`..`/relative segments) and then checked against the active session. There is **no** sessions-directory containment guard — this is a trusted local channel, and any frontend exposing it (e.g. the web dashboard) is expected to enforce its own authorization. Deletion is refused only for the currently active session, non-`.jsonl` paths, and nonexistent files:
|
|
821
|
+
```json
|
|
822
|
+
{
|
|
823
|
+
"type": "response",
|
|
824
|
+
"command": "delete_session",
|
|
825
|
+
"success": false,
|
|
826
|
+
"error": "Not a session file (expected .jsonl): /tmp/evil.txt"
|
|
827
|
+
}
|
|
828
|
+
```
|
|
829
|
+
|
|
624
830
|
#### fork
|
|
625
831
|
|
|
626
832
|
Create a new fork from a previous user message. Can be cancelled by a `session_before_fork` extension event handler. Returns the text of the message being forked from.
|
|
@@ -709,7 +915,7 @@ Response:
|
|
|
709
915
|
}
|
|
710
916
|
```
|
|
711
917
|
|
|
712
|
-
The current session name is available via `get_state` in the `sessionName` field.
|
|
918
|
+
The current session name is available via `get_state` in the `sessionName` field. Successful renames also emit a `session_name_changed` event.
|
|
713
919
|
|
|
714
920
|
### Commands
|
|
715
921
|
|
|
@@ -795,6 +1001,386 @@ Each session has:
|
|
|
795
1001
|
- `messageCount`: Number of messages in the session
|
|
796
1002
|
- `firstMessage`: First user message text (for preview)
|
|
797
1003
|
|
|
1004
|
+
#### list_all_sessions
|
|
1005
|
+
|
|
1006
|
+
List sessions across all projects. Returns sessions sorted by most recently modified first. May be slow with many sessions. If the underlying listing fails (an I/O error reading the sessions store), the command responds `success: false` rather than a silently-empty list — so a client can distinguish "no sessions" from "listing failed."
|
|
1007
|
+
|
|
1008
|
+
```json
|
|
1009
|
+
{"type": "list_all_sessions"}
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
Response:
|
|
1013
|
+
```json
|
|
1014
|
+
{
|
|
1015
|
+
"type": "response",
|
|
1016
|
+
"command": "list_all_sessions",
|
|
1017
|
+
"success": true,
|
|
1018
|
+
"data": {
|
|
1019
|
+
"sessions": [
|
|
1020
|
+
{
|
|
1021
|
+
"path": "/home/user/.dreb/agent/sessions/--home-user-project--/2024-01-15T10-30-00_abc123.jsonl",
|
|
1022
|
+
"id": "abc123-def456-...",
|
|
1023
|
+
"cwd": "/home/user/project",
|
|
1024
|
+
"name": "feature-work",
|
|
1025
|
+
"created": "2024-01-15T10:30:00.000Z",
|
|
1026
|
+
"modified": "2024-01-15T11:45:00.000Z",
|
|
1027
|
+
"messageCount": 12,
|
|
1028
|
+
"firstMessage": "Help me refactor the auth module"
|
|
1029
|
+
}
|
|
1030
|
+
]
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
Each session has the same fields as `list_sessions`.
|
|
1036
|
+
|
|
1037
|
+
### Background Agents
|
|
1038
|
+
|
|
1039
|
+
#### list_background_agents
|
|
1040
|
+
|
|
1041
|
+
List background subagents tracked by this process's registry — running and recently completed (finished entries are pruned after ~5 minutes). `sessionDir` is known from launch; `sessionFile` appears once the child process exits. Live transcripts are delivered via `background_agent_event` events (see Events), not by reading these paths.
|
|
1042
|
+
|
|
1043
|
+
```json
|
|
1044
|
+
{"type": "list_background_agents"}
|
|
1045
|
+
```
|
|
1046
|
+
|
|
1047
|
+
Response:
|
|
1048
|
+
```json
|
|
1049
|
+
{
|
|
1050
|
+
"type": "response",
|
|
1051
|
+
"command": "list_background_agents",
|
|
1052
|
+
"success": true,
|
|
1053
|
+
"data": {
|
|
1054
|
+
"agents": [
|
|
1055
|
+
{
|
|
1056
|
+
"agentId": "a1b2c3d4e5f6",
|
|
1057
|
+
"agentType": "Explore",
|
|
1058
|
+
"taskSummary": "Explore task 1/2",
|
|
1059
|
+
"startedAt": "2026-07-07T12:00:00.000Z",
|
|
1060
|
+
"status": "running",
|
|
1061
|
+
"sessionDir": "/home/user/.dreb/agent/subagent-sessions/a1b2c3d4e5f6",
|
|
1062
|
+
"cwd": "/home/user/project"
|
|
1063
|
+
}
|
|
1064
|
+
]
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
#### list_agent_types
|
|
1070
|
+
|
|
1071
|
+
List discoverable subagent types for the current session working directory. This includes package-bundled agents, user-level agents, and project-level agents in `.dreb/agents/*.md`. Results are sorted by `name`.
|
|
1072
|
+
|
|
1073
|
+
```json
|
|
1074
|
+
{"type": "list_agent_types"}
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
Response:
|
|
1078
|
+
```json
|
|
1079
|
+
{
|
|
1080
|
+
"type": "response",
|
|
1081
|
+
"command": "list_agent_types",
|
|
1082
|
+
"success": true,
|
|
1083
|
+
"data": {
|
|
1084
|
+
"agentTypes": [
|
|
1085
|
+
{
|
|
1086
|
+
"name": "code-reviewer",
|
|
1087
|
+
"description": "Reviews code changes for correctness, idiomatic patterns, and maintainability"
|
|
1088
|
+
},
|
|
1089
|
+
{
|
|
1090
|
+
"name": "Explore",
|
|
1091
|
+
"description": "Codebase and web exploration — find files, search code, search the web, answer questions. Read-only."
|
|
1092
|
+
}
|
|
1093
|
+
]
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
Each agent type has:
|
|
1099
|
+
- `name`: Agent type name to use as an `agentModels` key.
|
|
1100
|
+
- `description`: Human-readable description from the agent frontmatter.
|
|
1101
|
+
|
|
1102
|
+
### Session Tree
|
|
1103
|
+
|
|
1104
|
+
Sessions are append-only trees: editing/retrying a message or navigating back creates a branch rather than discarding entries. These commands expose tree inspection and navigation — the scriptable equivalent of the TUI's `/tree` selector.
|
|
1105
|
+
|
|
1106
|
+
#### get_tree
|
|
1107
|
+
|
|
1108
|
+
Get the session tree as a serializable DTO, plus the current leaf position.
|
|
1109
|
+
|
|
1110
|
+
```json
|
|
1111
|
+
{"type": "get_tree"}
|
|
1112
|
+
```
|
|
1113
|
+
|
|
1114
|
+
Response:
|
|
1115
|
+
```json
|
|
1116
|
+
{
|
|
1117
|
+
"type": "response",
|
|
1118
|
+
"command": "get_tree",
|
|
1119
|
+
"success": true,
|
|
1120
|
+
"data": {
|
|
1121
|
+
"roots": [
|
|
1122
|
+
{
|
|
1123
|
+
"id": "a1b2c3d4",
|
|
1124
|
+
"parentId": null,
|
|
1125
|
+
"type": "message",
|
|
1126
|
+
"role": "user",
|
|
1127
|
+
"preview": "Help me refactor the auth module",
|
|
1128
|
+
"timestamp": "2024-01-15T10:30:00.000Z",
|
|
1129
|
+
"label": "start",
|
|
1130
|
+
"children": [
|
|
1131
|
+
{
|
|
1132
|
+
"id": "e5f6a7b8",
|
|
1133
|
+
"parentId": "a1b2c3d4",
|
|
1134
|
+
"type": "message",
|
|
1135
|
+
"role": "assistant",
|
|
1136
|
+
"preview": "Sure — let's look at the middleware first.",
|
|
1137
|
+
"timestamp": "2024-01-15T10:30:05.000Z",
|
|
1138
|
+
"children": []
|
|
1139
|
+
}
|
|
1140
|
+
]
|
|
1141
|
+
}
|
|
1142
|
+
],
|
|
1143
|
+
"leafId": "e5f6a7b8"
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
```
|
|
1147
|
+
|
|
1148
|
+
Each node has:
|
|
1149
|
+
- `id`: Entry id (use with `navigate_tree`, `fork`)
|
|
1150
|
+
- `parentId`: Parent entry id, or `null` for a root. Orphaned roots keep their original non-null `parentId` (referencing an entry not in the tree) — prefer `children` for hierarchy
|
|
1151
|
+
- `type`: Entry type (`message`, `compaction`, `branch_summary`, `model_change`, `thinking_level_change`, `custom`, `custom_message`, `label`, `session_info`)
|
|
1152
|
+
- `role`: Message role, present only for `type: "message"` entries (`user`, `assistant`, `toolResult`, `bashExecution`)
|
|
1153
|
+
- `preview`: Short single-line content preview (whitespace-collapsed, max 200 chars). Non-text entries use bracketed forms like `[compaction: 50k tokens]`, `[branch summary]: ...`, `[model: claude-sonnet-4]`, `[bash]: npm test`
|
|
1154
|
+
- `timestamp`: ISO timestamp of the entry
|
|
1155
|
+
- `label`: Resolved user label, if any
|
|
1156
|
+
- `children`: Child nodes, oldest first
|
|
1157
|
+
|
|
1158
|
+
`leafId` is the id of the current leaf entry (`null` for an empty session) — the "you are here" marker for a tree UI. The DTO is stable and deliberately does **not** include full message payloads; use `get_messages` for content after navigation.
|
|
1159
|
+
|
|
1160
|
+
A well-formed session has exactly one root; orphaned entries (broken parent chains) also surface as roots.
|
|
1161
|
+
|
|
1162
|
+
#### navigate_tree
|
|
1163
|
+
|
|
1164
|
+
Navigate the current session to a different tree node, optionally summarizing the abandoned branch. Unlike `fork` (which creates a new session file), navigation stays within the same session file.
|
|
1165
|
+
|
|
1166
|
+
```json
|
|
1167
|
+
{"type": "navigate_tree", "targetId": "a1b2c3d4"}
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
With branch summarization:
|
|
1171
|
+
```json
|
|
1172
|
+
{
|
|
1173
|
+
"type": "navigate_tree",
|
|
1174
|
+
"targetId": "a1b2c3d4",
|
|
1175
|
+
"summarize": true,
|
|
1176
|
+
"customInstructions": "Focus on decisions made",
|
|
1177
|
+
"replaceInstructions": false,
|
|
1178
|
+
"label": "before-refactor"
|
|
1179
|
+
}
|
|
1180
|
+
```
|
|
1181
|
+
|
|
1182
|
+
Options (all optional, passed through verbatim to the core navigation — the TUI's interactive summarize prompt is not replicated):
|
|
1183
|
+
- `summarize`: Generate an LLM summary of the branch being abandoned and attach it at the navigation target. Requires a model and API key.
|
|
1184
|
+
- `customInstructions`: Extra instructions for the summarizer.
|
|
1185
|
+
- `replaceInstructions`: If `true`, `customInstructions` replaces the default summarizer prompt instead of augmenting it.
|
|
1186
|
+
- `label`: Label to attach to the branch summary entry (or to the target entry when not summarizing).
|
|
1187
|
+
|
|
1188
|
+
Response:
|
|
1189
|
+
```json
|
|
1190
|
+
{
|
|
1191
|
+
"type": "response",
|
|
1192
|
+
"command": "navigate_tree",
|
|
1193
|
+
"success": true,
|
|
1194
|
+
"data": {"cancelled": false, "editorText": "Help me refactor the auth module"}
|
|
1195
|
+
}
|
|
1196
|
+
```
|
|
1197
|
+
|
|
1198
|
+
- `cancelled`: `true` if an extension (`session_before_tree`) cancelled the navigation or summarization was aborted.
|
|
1199
|
+
- `editorText`: Present when navigating to a `user` (or `custom_message`) entry — the text of that message. The leaf moves to the entry's *parent* so the message can be re-edited and resubmitted; a client should pre-fill its input with this text (this is what the TUI does). Navigating to any other entry type moves the leaf to the entry itself and returns no `editorText`.
|
|
1200
|
+
|
|
1201
|
+
After a successful `navigate_tree`, `get_state` and `get_messages` reflect the post-navigation session state.
|
|
1202
|
+
|
|
1203
|
+
Errors are explicit `success: false` responses:
|
|
1204
|
+
```json
|
|
1205
|
+
{
|
|
1206
|
+
"type": "response",
|
|
1207
|
+
"command": "navigate_tree",
|
|
1208
|
+
"success": false,
|
|
1209
|
+
"error": "Entry zzz not found"
|
|
1210
|
+
}
|
|
1211
|
+
```
|
|
1212
|
+
|
|
1213
|
+
- Unknown `targetId`: `Entry <id> not found`
|
|
1214
|
+
- Agent currently streaming: `Cannot navigate the session tree while the agent is streaming. Abort or wait for idle first.`
|
|
1215
|
+
- Branch summarization or compaction in progress: `Cannot navigate the session tree while summarization or compaction is in progress. Wait for idle first.`
|
|
1216
|
+
- `summarize: true` with no model available: `No model available for summarization`
|
|
1217
|
+
|
|
1218
|
+
Note: with `summarize: true` the command is LLM-bound and can take a while. `RpcClient.navigateTree` uses a 5-minute client timeout (overridable via its client-side `timeoutMs` option, which is not sent over the wire); raw-protocol clients should budget accordingly. There is no scriptable abort for an in-flight branch summarization over RPC. A client-side timeout does not stop the server: a timed-out `navigate_tree` may still complete server-side and move the leaf — after a timeout, resync with `get_tree`/`get_state` instead of assuming the navigation failed.
|
|
1219
|
+
|
|
1220
|
+
### Settings
|
|
1221
|
+
|
|
1222
|
+
Persistent default settings, backed by the settings file (see [settings.md](settings.md)). These are distinct from live session state:
|
|
1223
|
+
|
|
1224
|
+
- **Persistent defaults** (`get_settings` / `set_settings`): the values stored in `settings.json` that seed fresh runtimes — default provider/model, default thinking level, queue modes, compaction/retry/image/context/skill/thinking-display/transport toggles, and per-agent model fallback lists. Writing them does **not** change the running session.
|
|
1225
|
+
- **Runtime state** (`get_state` / `set_model` / `set_thinking_level` / `set_steering_mode` / `set_follow_up_mode` / `set_auto_compaction` / `set_auto_retry`): the state of the live session. Note that the runtime setters also persist their values as new defaults as a side effect.
|
|
1226
|
+
|
|
1227
|
+
A dashboard settings tab typically reads both: `get_state` for what's active now, `get_settings` for what the next startup will use.
|
|
1228
|
+
|
|
1229
|
+
#### get_settings
|
|
1230
|
+
|
|
1231
|
+
Get the persistent default settings (merged global + project view).
|
|
1232
|
+
|
|
1233
|
+
```json
|
|
1234
|
+
{"type": "get_settings"}
|
|
1235
|
+
```
|
|
1236
|
+
|
|
1237
|
+
Response:
|
|
1238
|
+
```json
|
|
1239
|
+
{
|
|
1240
|
+
"type": "response",
|
|
1241
|
+
"command": "get_settings",
|
|
1242
|
+
"success": true,
|
|
1243
|
+
"data": {
|
|
1244
|
+
"defaultProvider": "anthropic",
|
|
1245
|
+
"defaultModel": "claude-sonnet-4-5",
|
|
1246
|
+
"defaultThinkingLevel": "high",
|
|
1247
|
+
"steeringMode": "one-at-a-time",
|
|
1248
|
+
"followUpMode": "one-at-a-time",
|
|
1249
|
+
"compactionEnabled": true,
|
|
1250
|
+
"retryEnabled": true,
|
|
1251
|
+
"imageAutoResize": true,
|
|
1252
|
+
"blockImages": false,
|
|
1253
|
+
"enableSkillCommands": true,
|
|
1254
|
+
"autoLoadNestedContext": true,
|
|
1255
|
+
"transport": "sse",
|
|
1256
|
+
"hideThinkingBlock": false,
|
|
1257
|
+
"agentModels": {
|
|
1258
|
+
"Explore": ["anthropic/sonnet", "openai/gpt-5"]
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
`defaultProvider`, `defaultModel`, and `defaultThinkingLevel` are absent if never set. `agentModels` is the merged global + project view; project entries win per agent name.
|
|
1265
|
+
|
|
1266
|
+
#### set_settings
|
|
1267
|
+
|
|
1268
|
+
Update persistent default settings. Takes a partial payload — only the supplied keys change. The whole payload is validated before anything is applied: on any invalid field, nothing changes and the response is an explicit error. Writes target the global settings file (same scope as every runtime setter).
|
|
1269
|
+
|
|
1270
|
+
```json
|
|
1271
|
+
{"type": "set_settings", "settings": {"defaultThinkingLevel": "low", "retryEnabled": false}}
|
|
1272
|
+
```
|
|
1273
|
+
|
|
1274
|
+
Setting the default model (both keys required together, validated against available models — the provider must have credentials configured, same rule as `set_model`):
|
|
1275
|
+
|
|
1276
|
+
```json
|
|
1277
|
+
{"type": "set_settings", "settings": {"defaultProvider": "anthropic", "defaultModel": "claude-sonnet-4-5"}}
|
|
1278
|
+
```
|
|
1279
|
+
|
|
1280
|
+
Setting per-agent model fallback lists:
|
|
1281
|
+
|
|
1282
|
+
```json
|
|
1283
|
+
{
|
|
1284
|
+
"type": "set_settings",
|
|
1285
|
+
"settings": {
|
|
1286
|
+
"agentModels": {
|
|
1287
|
+
"Explore": ["anthropic/sonnet", "openai/gpt-5"],
|
|
1288
|
+
"code-reviewer": []
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
```
|
|
1293
|
+
|
|
1294
|
+
For `agentModels`, a non-empty array writes the global fallback list for that agent. An empty array removes the global entry, so that agent uses its agent-definition default unless a project-level override exists.
|
|
1295
|
+
|
|
1296
|
+
Response is the full settings snapshot after the write (same shape as `get_settings`), plus `warnings` when the write was accepted but a project-level override shadows part of it:
|
|
1297
|
+
|
|
1298
|
+
```json
|
|
1299
|
+
{
|
|
1300
|
+
"type": "response",
|
|
1301
|
+
"command": "set_settings",
|
|
1302
|
+
"success": true,
|
|
1303
|
+
"data": {
|
|
1304
|
+
"defaultProvider": "anthropic",
|
|
1305
|
+
"defaultModel": "claude-sonnet-4-5",
|
|
1306
|
+
"defaultThinkingLevel": "low",
|
|
1307
|
+
"steeringMode": "one-at-a-time",
|
|
1308
|
+
"followUpMode": "one-at-a-time",
|
|
1309
|
+
"compactionEnabled": true,
|
|
1310
|
+
"retryEnabled": false,
|
|
1311
|
+
"imageAutoResize": true,
|
|
1312
|
+
"blockImages": false,
|
|
1313
|
+
"enableSkillCommands": true,
|
|
1314
|
+
"autoLoadNestedContext": true,
|
|
1315
|
+
"transport": "sse",
|
|
1316
|
+
"hideThinkingBlock": false,
|
|
1317
|
+
"agentModels": {}
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
```
|
|
1321
|
+
|
|
1322
|
+
Project-shadow warning example (the global write still lands, but the returned merged `agentModels.Explore` remains the project value until `.dreb/settings.json` is edited):
|
|
1323
|
+
|
|
1324
|
+
```json
|
|
1325
|
+
{
|
|
1326
|
+
"type": "response",
|
|
1327
|
+
"command": "set_settings",
|
|
1328
|
+
"success": true,
|
|
1329
|
+
"data": {
|
|
1330
|
+
"steeringMode": "one-at-a-time",
|
|
1331
|
+
"followUpMode": "one-at-a-time",
|
|
1332
|
+
"compactionEnabled": true,
|
|
1333
|
+
"retryEnabled": true,
|
|
1334
|
+
"imageAutoResize": true,
|
|
1335
|
+
"blockImages": false,
|
|
1336
|
+
"enableSkillCommands": true,
|
|
1337
|
+
"autoLoadNestedContext": true,
|
|
1338
|
+
"transport": "sse",
|
|
1339
|
+
"hideThinkingBlock": false,
|
|
1340
|
+
"agentModels": {
|
|
1341
|
+
"Explore": ["project/model"]
|
|
1342
|
+
},
|
|
1343
|
+
"warnings": [
|
|
1344
|
+
"A project-level agentModels override for \"Explore\" (.dreb/settings.json) takes precedence — this change to global settings will have no effect. Edit the project settings file to change it."
|
|
1345
|
+
]
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
```
|
|
1349
|
+
|
|
1350
|
+
Valid keys and values:
|
|
1351
|
+
|
|
1352
|
+
| Key | Values |
|
|
1353
|
+
|-----|--------|
|
|
1354
|
+
| `defaultProvider` + `defaultModel` | Must be supplied together; must match a model from `get_available_models` |
|
|
1355
|
+
| `defaultThinkingLevel` | `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"` (validated against the full set — a stored default is not tied to the current model's capabilities) |
|
|
1356
|
+
| `steeringMode` | `"all"`, `"one-at-a-time"` |
|
|
1357
|
+
| `followUpMode` | `"all"`, `"one-at-a-time"` |
|
|
1358
|
+
| `compactionEnabled` | boolean |
|
|
1359
|
+
| `retryEnabled` | boolean |
|
|
1360
|
+
| `imageAutoResize` | boolean |
|
|
1361
|
+
| `blockImages` | boolean |
|
|
1362
|
+
| `enableSkillCommands` | boolean |
|
|
1363
|
+
| `autoLoadNestedContext` | boolean |
|
|
1364
|
+
| `transport` | `"sse"`, `"websocket"`, `"auto"` |
|
|
1365
|
+
| `hideThinkingBlock` | boolean |
|
|
1366
|
+
| `agentModels` | Plain object mapping agent names to arrays of non-empty model id strings; empty arrays remove the global entry for that agent |
|
|
1367
|
+
|
|
1368
|
+
Errors are explicit `success: false` responses (nothing is applied on any of them):
|
|
1369
|
+
|
|
1370
|
+
- Missing/empty payload: `set_settings requires at least one setting to change`
|
|
1371
|
+
- Unknown key: `Unknown settings key(s): ...`
|
|
1372
|
+
- Invalid enum value: `Invalid defaultThinkingLevel: "extreme". Valid values: off, minimal, low, medium, high, xhigh`
|
|
1373
|
+
- Invalid transport: `Invalid transport: "http". Valid values: sse, websocket, auto`
|
|
1374
|
+
- Non-boolean toggle: `Invalid retryEnabled: "yes". Must be a boolean`
|
|
1375
|
+
- Invalid `agentModels` object: `Invalid agentModels: must be a plain object mapping agent names to model fallback arrays`
|
|
1376
|
+
- Invalid `agentModels` entry (the offending agent key is named): `Invalid agentModels["Explore"]: expected an array of non-empty strings`
|
|
1377
|
+
- Provider without model (or vice versa): `defaultProvider and defaultModel must be set together`
|
|
1378
|
+
- Unavailable model: `Model not found: provider/model-id`
|
|
1379
|
+
- Corrupt settings file: `Cannot write settings: the global settings file failed to load (fix or remove the corrupt settings.json first)` — without this guard the write would silently no-op
|
|
1380
|
+
- Write failure (I/O error): `Failed to persist settings: ...`
|
|
1381
|
+
|
|
1382
|
+
Unlike `set_thinking_level` (which silently clamps to the current model's capabilities), `set_settings` rejects invalid values loudly — a dashboard needs the error, not a silent correction.
|
|
1383
|
+
|
|
798
1384
|
### Version
|
|
799
1385
|
|
|
800
1386
|
#### get_version
|
|
@@ -833,12 +1419,24 @@ Events are streamed to stdout as JSON lines during agent operation. Events do NO
|
|
|
833
1419
|
| `tool_execution_start` | Tool begins execution |
|
|
834
1420
|
| `tool_execution_update` | Tool execution progress (streaming output) |
|
|
835
1421
|
| `tool_execution_end` | Tool completes |
|
|
1422
|
+
| `stream_retry` | Stream dropped mid-turn; retrying (partial output discarded) |
|
|
1423
|
+
| `length_retry` | Response hit the token limit; retrying with a larger budget |
|
|
836
1424
|
| `auto_compaction_start` | Auto-compaction begins |
|
|
837
1425
|
| `auto_compaction_end` | Auto-compaction completes |
|
|
838
1426
|
| `auto_retry_start` | Auto-retry begins (after transient error) |
|
|
839
1427
|
| `auto_retry_end` | Auto-retry completes (success or final failure) |
|
|
1428
|
+
| `background_agent_start` | Background subagent launched (includes `sessionDir`) |
|
|
1429
|
+
| `background_agent_end` | Background subagent finished (includes `sessionFile` when known) |
|
|
1430
|
+
| `background_agent_event` | Relayed event from a background subagent's own stream |
|
|
1431
|
+
| `parent_paused_for_background_agents` | Parent paused waiting on background agents |
|
|
1432
|
+
| `session_name_changed` | Session display name changed (manual rename, extension rename, or auto-title) |
|
|
1433
|
+
| `tasks_update` | Session task list replaced (see the `tasks_update` tool) |
|
|
1434
|
+
| `suggest_next` | Agent suggested a next command |
|
|
840
1435
|
| `extension_error` | Extension threw an error |
|
|
841
1436
|
|
|
1437
|
+
Treat the event union as open — dispatch on `type` and ignore unknown values
|
|
1438
|
+
rather than validating against a closed list; new event types may be added.
|
|
1439
|
+
|
|
842
1440
|
### agent_start
|
|
843
1441
|
|
|
844
1442
|
Emitted when the agent begins processing a prompt. Includes the resolved model.
|
|
@@ -1032,6 +1630,55 @@ On final failure (max retries exceeded):
|
|
|
1032
1630
|
}
|
|
1033
1631
|
```
|
|
1034
1632
|
|
|
1633
|
+
### background_agent_start / background_agent_end / background_agent_event
|
|
1634
|
+
|
|
1635
|
+
Lifecycle and live-observability events for background subagents (the `subagent` tool's background mode).
|
|
1636
|
+
|
|
1637
|
+
`background_agent_start` fires at launch. `sessionDir` is the directory the child will write its session JSONL into (per-launch, known before spawn):
|
|
1638
|
+
|
|
1639
|
+
```json
|
|
1640
|
+
{
|
|
1641
|
+
"type": "background_agent_start",
|
|
1642
|
+
"agentId": "a1b2c3d4e5f6",
|
|
1643
|
+
"agentType": "Explore",
|
|
1644
|
+
"taskSummary": "Explore task 1/2",
|
|
1645
|
+
"sessionDir": "/home/user/.dreb/agent/subagent-sessions/a1b2c3d4e5f6"
|
|
1646
|
+
}
|
|
1647
|
+
```
|
|
1648
|
+
|
|
1649
|
+
`background_agent_end` fires after the result is delivered to the parent agent. `sessionFile` is the child's session JSONL path when one was written:
|
|
1650
|
+
|
|
1651
|
+
```json
|
|
1652
|
+
{
|
|
1653
|
+
"type": "background_agent_end",
|
|
1654
|
+
"agentId": "a1b2c3d4e5f6",
|
|
1655
|
+
"agentType": "Explore",
|
|
1656
|
+
"success": true,
|
|
1657
|
+
"sessionFile": "/home/user/.dreb/agent/subagent-sessions/a1b2c3d4e5f6/2026-07-07T12-00-00-000Z_uuid.jsonl"
|
|
1658
|
+
}
|
|
1659
|
+
```
|
|
1660
|
+
|
|
1661
|
+
`background_agent_event` relays every JSONL event the child process emits (the same event union documented here, plus the initial session header), verbatim, tagged with the child's `agentId`. This is the live-transcript transport for observers like the dashboard — no session-file tailing needed. Streaming children emit `message_update` deltas at high frequency; consumers that fan events out further (e.g. over a network) should batch or throttle:
|
|
1662
|
+
|
|
1663
|
+
```json
|
|
1664
|
+
{
|
|
1665
|
+
"type": "background_agent_event",
|
|
1666
|
+
"agentId": "a1b2c3d4e5f6",
|
|
1667
|
+
"event": {"type": "tool_execution_start", "toolName": "read", "args": {"path": "src/index.ts"}}
|
|
1668
|
+
}
|
|
1669
|
+
```
|
|
1670
|
+
|
|
1671
|
+
`parent_paused_for_background_agents` fires when the parent agent pauses because its background-agent turn guardrail was hit while agents are still running:
|
|
1672
|
+
|
|
1673
|
+
```json
|
|
1674
|
+
{
|
|
1675
|
+
"type": "parent_paused_for_background_agents",
|
|
1676
|
+
"runningAgentCount": 2,
|
|
1677
|
+
"turnsUsed": 10,
|
|
1678
|
+
"turnLimit": 10
|
|
1679
|
+
}
|
|
1680
|
+
```
|
|
1681
|
+
|
|
1035
1682
|
### extension_error
|
|
1036
1683
|
|
|
1037
1684
|
Emitted when an extension throws an error.
|