Gateway: snooze finished threads, and name the files a file approval would change
Gateway / check (push) Successful in 9s
Gateway / image (push) Successful in 22s

This commit is contained in:
gib committed 2026-11-02 14:20:39 -05:00
1 parent d10df56cc9
commit 4dc4e57dac
8 files changed
+295 -10

No files matched your search

+34 -3
View File
@@ -59,14 +59,16 @@ GET /v1/feed
"working": [FeedItem],
"recent": [FeedItem],
"recentTotal": 12,
"snoozedTotal": 2,
"hosts": [{ "id": "...", "label": "Mac mini", "status": "online", "error": null }]
}
```
`needsYou` holds threads waiting for an approval or an answer, oldest first. `working` holds running
threads, most recently updated first. `recent` holds threads that completed or failed and are not
settled yet, however old, newest first and at most 10. `recentTotal` counts all of them. When it is
larger, the rest come from `GET /v1/recent`. Host `status` is one of `connecting`, `online`, `offline`, `auth_invalid`, or
settled or snoozed yet, however old, newest first and at most 10. `recentTotal` counts all of them. When it is
larger, the rest come from `GET /v1/recent`. `snoozedTotal` counts finished threads snoozed for
later, which `GET /v1/snoozed` lists. Host `status` is one of `connecting`, `online`, `offline`, `auth_invalid`, or
`incompatible`.
```
@@ -79,6 +81,7 @@ FeedItem {
"lastMessage": "Parser and tests are written. I want to run the suite.",
"activity": { "kind": "command", "text": "bun test", "startedAt": "..." } | null,
"changes": { "files": 3, "additions": 42, "deletions": 8 } | null,
"snoozedUntil": "..." | null,
"request": PendingRequest | null,
"via": { "hostId": "...", "threadId": "...", "title": "Check Panama PATH" } | null
}
@@ -110,10 +113,17 @@ PendingRequest {
"prompt": "bun test --filter ocr",
"reason": null,
"options": [{ "decision": "accept", "label": "Allow" }, { "decision": "decline", "label": "Deny" }],
"files": [],
"questions": []
}
```
For `kind: "file-change"`, `files` lists the files the agent wants to change as
`{ path, name, additions, deletions, preview }`. `name` is the last part of `path`. Most providers,
Claude included, send the diff only after the edit runs, so `additions` and `deletions` are usually
null and `preview` is empty. When a diff comes with the request, `preview` holds its first 4
changed lines, each starting with `+` or `-`.
An option may also carry `warning`, a short note about a risky choice such as "Applies to every
thread". For questions (`kind: "user_input"`), `options` is empty and `questions` lists
`{ id, header, question, options: [{ label, value }], allowCustomAnswer, multiSelect }`.
@@ -205,6 +215,27 @@ POST /v1/recent/settle
Settles every completed thread in Recent, including those past the first 10. Failed threads stay.
`failed` counts threads T3 refused or whose host was offline.
```
GET /v1/snoozed
200 { "items": [FeedItem] }
```
Finished threads snoozed for later, the soonest to come back first, with `snoozedUntil` set. Like
`GET /v1/recent`, it uses only cached summaries.
```
POST /v1/threads/:hostId/:threadId/snooze
{ "until": "2026-11-03T14:00:00.000Z" }
202
POST /v1/threads/:hostId/:threadId/unsnooze
202
```
Snoozing hides a finished thread from Recent until `until`, which must be in the next 30 days. Then
it comes back on its own. A snoozed thread that starts working or waiting on you shows as usual.
Thread detail fills `request` and `via` the same way as the feed when a subagent waits on you.
## Summary
@@ -294,7 +325,7 @@ its body starts with "Subagent <title>:", and its `hostId` and `threadId` are th
| --- | --- | --- |
| `approval` | A thread needs an approval | Allow (`accept`), Deny (`decline`) |
| `input` | A thread asked a question | Answer, Open. With `question`: one button per option, Say an answer (text input) when `allowCustomAnswer`, Open |
| `finished` | A turn completed | Reply (text input), Open |
| `finished` | A turn completed | Reply (text input), Settle, Open |
| `failed` | A turn failed | Open |
| `host` | A host's T3 token expires within 7 days, or was rejected | none |
| `test` | The watch asked for a test push | none |