Gateway: changed files, search across hosts, a richer complication summary, and question options in pushes
Gateway / check (push) Successful in 10s
Gateway / image (push) Successful in 23s

This commit is contained in:
gib committed 2026-11-02 13:39:49 -05:00
1 parent 45251b1a43
commit b08fd9bdb1
13 files changed
+500 -19

No files matched your search

+48 -1
View File
@@ -118,6 +118,8 @@ export interface FeedItem {
lastMessage: string | null;
/** What a working thread is doing right now. Null when nothing is in progress or not read yet. */
activity: Activity | null;
/** What the latest run changed, in total. Null when it changed no files or is not read yet. */
changes: ChangeTotals | null;
request: PendingRequest | null;
/**
* Set when `request` comes from a subagent this thread delegated to, rather than the thread
@@ -135,6 +137,35 @@ export interface Activity {
startedAt: string | null;
}
export interface ChangeTotals {
files: number;
additions: number;
deletions: number;
}
/** A file the latest run changed. `name` is the last part of `path`. */
export interface ChangedFile {
path: string;
name: string;
additions: number;
deletions: number;
}
/** A thread search hit: the thread, and where the words matched when it was inside a message. */
export interface SearchHit {
thread: ThreadRow;
projectTitle: string;
hostLabel: string;
/** Text around the match in a message, or null when only the title matched. */
snippet: string | null;
}
export interface SearchResponse {
hits: SearchHit[];
/** Labels of hosts that were offline or failed, so their threads were not searched. */
unsearched: string[];
}
/** A thread in a list: a project's threads, or a thread's subagents. */
export interface ThreadRow {
hostId: string;
@@ -162,7 +193,16 @@ export interface Summary {
needsYou: number;
working: number;
/** The thread that has waited longest for you, if any. */
next: { hostId: string; threadId: string; title: string; hostLabel: string } | null;
next: {
hostId: string;
threadId: string;
title: string;
hostLabel: string;
/** The command it wants to run or its first question, trimmed. Null until the gateway has read it. */
request: string | null;
} | null;
/** The working thread updated most recently, with what it is doing. Null when nothing is working. */
current: { hostId: string; threadId: string; title: string; activity: Activity | null } | null;
hostsOffline: number;
}
@@ -208,6 +248,8 @@ export interface ThreadDetail {
earlierCursor: string | null;
/** Subagents and delegated threads this thread started, newest first. */
subagents: ThreadRow[];
/** The files the latest run changed, most lines changed first. */
changedFiles: ChangedFile[];
}
export interface ThreadModeRequest {
@@ -290,6 +332,11 @@ export interface PushPayload {
/** Absent on `host` pushes, which are about a host rather than a thread. */
threadId?: string;
requestId?: string;
/**
* On `input` pushes that ask one single-choice question: its options, so the notification can
* offer each as a button. `allowCustomAnswer` adds a spoken answer.
*/
question?: { id: string; options: Array<{ label: string; value: string }>; allowCustomAnswer: boolean };
}
/** Notification categories the watch registers actions for. */