@mattstack/rt-client 0.6.1 → 0.6.2
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/README.md +39 -0
- package/dist/client.d.ts +19 -1
- package/dist/commands.d.ts +150 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +129 -6
- package/package.json +1 -1
- package/src/client.ts +78 -1
- package/src/commands.ts +57 -1
- package/src/index.ts +17 -0
- package/src/settings/registry-defs.ts +52 -5
package/README.md
CHANGED
|
@@ -74,6 +74,45 @@ doesn't error, it resolves empty. `parseIdentity` is strict — only strings
|
|
|
74
74
|
`serializeIdentity` emitted parse — so validate payloads with it, and never
|
|
75
75
|
hand-assemble or string-split a wire.
|
|
76
76
|
|
|
77
|
+
## Chat
|
|
78
|
+
|
|
79
|
+
The `rt chat` surface the chat viewer (`~/Documents/GitHub/chat`) is built
|
|
80
|
+
on. Every call degrades to `{ ok: false, error }` instead of throwing, and a
|
|
81
|
+
daemon that is down and a daemon that refused look the same to the caller;
|
|
82
|
+
branch on `ok`, not on exceptions.
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { chatRooms, chatMessages, chatPost, createRelay, daemonHealth } from '@mattstack/rt-client';
|
|
86
|
+
|
|
87
|
+
const rooms = await chatRooms({ handle: 'matt' }); // { ok, data: { rooms } }
|
|
88
|
+
const page = await chatMessages({ room: 'build', limit: 50 }); // newest page; `before: <id>` pages older
|
|
89
|
+
await chatPost({ handle: 'matt', room: 'build', body: 'on it' });
|
|
90
|
+
|
|
91
|
+
const health = await daemonHealth(); // { reachable, error? }, never throws
|
|
92
|
+
const stop = createRelay({ // one daemon subscription, republished
|
|
93
|
+
match: t => t.startsWith('chat/'), // `chat/<room>/msg`, `chat/wake/<handle>`
|
|
94
|
+
topic: 'chat',
|
|
95
|
+
publish: (topic, data) => server.publish(topic, data),
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
| Function | Daemon verb |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| `chatSignIn` / `chatSignOut` / `chatAway` / `chatBack` / `chatPulse` | presence: the buddy-list row and its heartbeats |
|
|
102
|
+
| `chatBuddies` / `chatWho` / `chatRooms` | the roster, one room's members, a handle's rooms |
|
|
103
|
+
| `chatJoin` / `chatLeave` | membership (`wakeOn: mention \| all \| none`) |
|
|
104
|
+
| `chatPost` / `chatDm` / `chatRead` / `chatMessages` / `chatMark` | messages: post, DM, read-and-advance, page, advance the cursor |
|
|
105
|
+
| `chatArm` / `chatTouch` / `chatDisarm` / `chatUnreadWaking` | the tail's wake protocol; the CLI's `rt chat tail` uses these |
|
|
106
|
+
| `paneList` / `panePeek` / `paneSpawn` / `paneAccounts` / `paneDirectories` | herdr panes: list with presence joined, peek a screen, start claude in a tab, cswap accounts, directory suggestions |
|
|
107
|
+
| `chatInvite` | type `/chat:join <room>` into a pane; `accepted`, `queued` or `refused` |
|
|
108
|
+
| `createRelay` / `subscribe` | the event stream; `daemonHealth` the reachability probe |
|
|
109
|
+
|
|
110
|
+
Pass `{ sockPath }` as the trailing options to reach a non-default daemon
|
|
111
|
+
socket. The verbs, their payloads and the wake protocol are specified in
|
|
112
|
+
repo-tools `docs/superpowers/specs/2026-08-23-rt-chat-design.md` and
|
|
113
|
+
`2026-08-24-rt-chat-presence-design.md`; the agent-facing rules are
|
|
114
|
+
`skills/rt-chat/SKILL.md`.
|
|
115
|
+
|
|
77
116
|
## License
|
|
78
117
|
|
|
79
118
|
MIT
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RtResponse, RtClientOptions } from "./transport.ts";
|
|
2
|
-
import type { DemandDecl, ProjectMRsData, DiscussionsData, MrByBranchData, BranchEnrichment, ForgeSlug, ForgeTokenData, RunSummary, RunDetail, WakeMode, ChatMember, ChatMessage, RoomSummary, BuddyStatus, PresenceRow } from "./commands.ts";
|
|
2
|
+
import type { DemandDecl, ProjectMRsData, DiscussionsData, MrByBranchData, BranchEnrichment, ForgeSlug, ForgeTokenData, RunSummary, RunDetail, WakeMode, ChatMember, ChatMessage, RoomSummary, BuddyStatus, PresenceRow, AgentRecord, Commands } from "./commands.ts";
|
|
3
3
|
/**
|
|
4
4
|
* One repo's project open-MR store. A cold repo forces a full paginated sync
|
|
5
5
|
* on the daemon side when maxAgeMs demands it, which can run tens of seconds
|
|
@@ -102,6 +102,7 @@ export declare function chatArm(a: {
|
|
|
102
102
|
}, o?: RtClientOptions): Promise<RtResponse<Record<string, never>>>;
|
|
103
103
|
export declare function chatTouch(a: {
|
|
104
104
|
handle: string;
|
|
105
|
+
room?: string;
|
|
105
106
|
sessionId?: string;
|
|
106
107
|
}, o?: RtClientOptions): Promise<RtResponse<Record<string, never>>>;
|
|
107
108
|
export declare function chatDisarm(a: {
|
|
@@ -173,3 +174,20 @@ export declare function chatDm(a: {
|
|
|
173
174
|
export declare function eventsHead(o?: RtClientOptions): Promise<RtResponse<{
|
|
174
175
|
cursor: number;
|
|
175
176
|
}>>;
|
|
177
|
+
export declare function agentStart(a: Commands["agent:start"]["payload"], o?: RtClientOptions): Promise<RtResponse<AgentRecord>>;
|
|
178
|
+
export declare function agentResume(a: Commands["agent:resume"]["payload"], o?: RtClientOptions): Promise<RtResponse<AgentRecord>>;
|
|
179
|
+
export declare function agentGet(a: {
|
|
180
|
+
id: string;
|
|
181
|
+
}, o?: RtClientOptions): Promise<RtResponse<AgentRecord>>;
|
|
182
|
+
export declare function agentList(a: {
|
|
183
|
+
repo?: string;
|
|
184
|
+
}, o?: RtClientOptions): Promise<RtResponse<{
|
|
185
|
+
agents: AgentRecord[];
|
|
186
|
+
}>>;
|
|
187
|
+
export declare function paneList(o?: RtClientOptions): Promise<RtResponse<Commands["pane:list"]["data"]>>;
|
|
188
|
+
export declare function panePeek(a: Commands["pane:peek"]["payload"], o?: RtClientOptions): Promise<RtResponse<Commands["pane:peek"]["data"]>>;
|
|
189
|
+
/** The spawn waits on claude starting, so its budget is minutes, not seconds. */
|
|
190
|
+
export declare function paneSpawn(a: Commands["pane:spawn"]["payload"], o?: RtClientOptions): Promise<RtResponse<Commands["pane:spawn"]["data"]>>;
|
|
191
|
+
export declare function paneAccounts(o?: RtClientOptions): Promise<RtResponse<Commands["pane:accounts"]["data"]>>;
|
|
192
|
+
export declare function paneDirectories(a: Commands["pane:directories"]["payload"], o?: RtClientOptions): Promise<RtResponse<Commands["pane:directories"]["data"]>>;
|
|
193
|
+
export declare function chatInvite(a: Commands["chat:invite"]["payload"], o?: RtClientOptions): Promise<RtResponse<Commands["chat:invite"]["data"]>>;
|
package/dist/commands.d.ts
CHANGED
|
@@ -151,6 +151,39 @@ export interface PresenceRow {
|
|
|
151
151
|
armedAt?: number;
|
|
152
152
|
signedOutAt?: number;
|
|
153
153
|
}
|
|
154
|
+
export type AgentStatus = "idle" | "working" | "blocked" | "done" | "unknown";
|
|
155
|
+
/** Duplicated shape on purpose (see EventsBusEvent above): mirrors the daemon's pane row, which rt-client cannot import. */
|
|
156
|
+
export interface ChatPane {
|
|
157
|
+
paneId: string;
|
|
158
|
+
workspace: string;
|
|
159
|
+
title?: string;
|
|
160
|
+
cwd?: string;
|
|
161
|
+
repo?: string;
|
|
162
|
+
branch?: string;
|
|
163
|
+
agentStatus: AgentStatus;
|
|
164
|
+
sessionId?: string;
|
|
165
|
+
presence?: {
|
|
166
|
+
handle: string;
|
|
167
|
+
status: BuddyStatus;
|
|
168
|
+
rooms: string[];
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
export interface PaneAccount {
|
|
172
|
+
slot: number;
|
|
173
|
+
email: string;
|
|
174
|
+
alias?: string;
|
|
175
|
+
headroom?: string;
|
|
176
|
+
}
|
|
177
|
+
export interface PaneDirectory {
|
|
178
|
+
path: string;
|
|
179
|
+
repo: string;
|
|
180
|
+
branch?: string;
|
|
181
|
+
}
|
|
182
|
+
export interface InviteResult {
|
|
183
|
+
paneId: string;
|
|
184
|
+
delivered: "accepted" | "queued" | "refused";
|
|
185
|
+
reason?: string;
|
|
186
|
+
}
|
|
154
187
|
export type Attention = {
|
|
155
188
|
needs: boolean;
|
|
156
189
|
reason: "failed" | "stale" | "stranded" | "blocked" | null;
|
|
@@ -223,6 +256,29 @@ export interface RunDetail {
|
|
|
223
256
|
decisions: RunDecisionRow[];
|
|
224
257
|
schemaAhead: boolean;
|
|
225
258
|
}
|
|
259
|
+
export type AgentSurface = "herdr" | "headless";
|
|
260
|
+
export interface AgentRecord {
|
|
261
|
+
id: string;
|
|
262
|
+
repo: string;
|
|
263
|
+
cwd: string;
|
|
264
|
+
provider: string;
|
|
265
|
+
surface: AgentSurface;
|
|
266
|
+
sessionId: string;
|
|
267
|
+
model?: string;
|
|
268
|
+
effort?: string;
|
|
269
|
+
account?: string;
|
|
270
|
+
label?: string;
|
|
271
|
+
caller?: string;
|
|
272
|
+
paneId?: string;
|
|
273
|
+
tabId?: string;
|
|
274
|
+
workspaceId?: string;
|
|
275
|
+
extraArgs?: string;
|
|
276
|
+
exitCode?: number;
|
|
277
|
+
resultPath?: string;
|
|
278
|
+
createdAt: number;
|
|
279
|
+
lastResumedAt?: number;
|
|
280
|
+
finishedAt?: number;
|
|
281
|
+
}
|
|
226
282
|
export interface Commands {
|
|
227
283
|
"project-mrs:read": {
|
|
228
284
|
payload: {
|
|
@@ -456,6 +512,7 @@ export interface Commands {
|
|
|
456
512
|
"chat:touch": {
|
|
457
513
|
payload: {
|
|
458
514
|
handle: string;
|
|
515
|
+
room?: string;
|
|
459
516
|
sessionId?: string;
|
|
460
517
|
};
|
|
461
518
|
data: Record<string, never>;
|
|
@@ -554,6 +611,99 @@ export interface Commands {
|
|
|
554
611
|
recipients: string[];
|
|
555
612
|
};
|
|
556
613
|
};
|
|
614
|
+
"agent:start": {
|
|
615
|
+
payload: {
|
|
616
|
+
repo: string;
|
|
617
|
+
cwd: string;
|
|
618
|
+
prompt?: string;
|
|
619
|
+
surface?: AgentSurface;
|
|
620
|
+
model?: string;
|
|
621
|
+
effort?: string;
|
|
622
|
+
account?: string;
|
|
623
|
+
label?: string;
|
|
624
|
+
caller?: string;
|
|
625
|
+
workspace?: string;
|
|
626
|
+
tab?: string;
|
|
627
|
+
extraArgs?: string;
|
|
628
|
+
};
|
|
629
|
+
data: AgentRecord;
|
|
630
|
+
};
|
|
631
|
+
"agent:resume": {
|
|
632
|
+
payload: {
|
|
633
|
+
id: string;
|
|
634
|
+
prompt?: string;
|
|
635
|
+
surface?: AgentSurface;
|
|
636
|
+
};
|
|
637
|
+
data: AgentRecord;
|
|
638
|
+
};
|
|
639
|
+
"agent:get": {
|
|
640
|
+
payload: {
|
|
641
|
+
id: string;
|
|
642
|
+
};
|
|
643
|
+
data: AgentRecord;
|
|
644
|
+
};
|
|
645
|
+
"agent:list": {
|
|
646
|
+
payload: {
|
|
647
|
+
repo?: string;
|
|
648
|
+
};
|
|
649
|
+
data: {
|
|
650
|
+
agents: AgentRecord[];
|
|
651
|
+
};
|
|
652
|
+
};
|
|
653
|
+
"chat:invite": {
|
|
654
|
+
payload: {
|
|
655
|
+
paneId: string;
|
|
656
|
+
room: string;
|
|
657
|
+
note?: string;
|
|
658
|
+
from: string;
|
|
659
|
+
callerPane?: string;
|
|
660
|
+
};
|
|
661
|
+
data: InviteResult;
|
|
662
|
+
};
|
|
663
|
+
"pane:list": {
|
|
664
|
+
payload: Record<string, never>;
|
|
665
|
+
data: {
|
|
666
|
+
panes: ChatPane[];
|
|
667
|
+
};
|
|
668
|
+
};
|
|
669
|
+
"pane:peek": {
|
|
670
|
+
payload: {
|
|
671
|
+
paneId: string;
|
|
672
|
+
lines?: number;
|
|
673
|
+
};
|
|
674
|
+
data: {
|
|
675
|
+
paneId: string;
|
|
676
|
+
lines: string[];
|
|
677
|
+
};
|
|
678
|
+
};
|
|
679
|
+
"pane:accounts": {
|
|
680
|
+
payload: Record<string, never>;
|
|
681
|
+
data: {
|
|
682
|
+
accounts: PaneAccount[];
|
|
683
|
+
};
|
|
684
|
+
};
|
|
685
|
+
"pane:directories": {
|
|
686
|
+
payload: {
|
|
687
|
+
q?: string;
|
|
688
|
+
};
|
|
689
|
+
data: {
|
|
690
|
+
directories: PaneDirectory[];
|
|
691
|
+
};
|
|
692
|
+
};
|
|
693
|
+
"pane:spawn": {
|
|
694
|
+
payload: {
|
|
695
|
+
cwd: string;
|
|
696
|
+
account?: string;
|
|
697
|
+
model?: string;
|
|
698
|
+
effort?: string;
|
|
699
|
+
prompt?: string;
|
|
700
|
+
workspace?: string;
|
|
701
|
+
};
|
|
702
|
+
data: {
|
|
703
|
+
pane: ChatPane;
|
|
704
|
+
ready: boolean;
|
|
705
|
+
};
|
|
706
|
+
};
|
|
557
707
|
}
|
|
558
708
|
export type CommandName = keyof Commands;
|
|
559
709
|
export declare const COMMAND_NAMES: readonly CommandName[];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { rtCommand, DEFAULT_SOCK } from "./transport.ts";
|
|
2
2
|
export type { RtResponse, RtClientOptions } from "./transport.ts";
|
|
3
|
-
export { readProjectMRs, readDiscussions, readMrsByBranch, readBranchCache, resolveForgeToken, listRuns, getRun, abandonRun, chatJoin, chatLeave, chatPost, chatRead, chatRooms, chatWho, chatMark, chatMessages, chatArm, chatTouch, chatDisarm, chatUnreadWaking, chatSignIn, chatSignOut, chatAway, chatBack, chatBuddies, chatPulse, chatDm, eventsHead, } from "./client.ts";
|
|
3
|
+
export { readProjectMRs, readDiscussions, readMrsByBranch, readBranchCache, resolveForgeToken, listRuns, getRun, abandonRun, chatJoin, chatLeave, chatPost, chatRead, chatRooms, chatWho, chatMark, chatMessages, chatArm, chatTouch, chatDisarm, chatUnreadWaking, chatSignIn, chatSignOut, chatAway, chatBack, chatBuddies, chatPulse, chatDm, eventsHead, agentStart, agentResume, agentGet, agentList, paneList, panePeek, paneSpawn, paneAccounts, paneDirectories, chatInvite, } from "./client.ts";
|
|
4
4
|
export { COMMAND_NAMES } from "./commands.ts";
|
|
5
|
-
export type { Discussion, DemandDecl, ProjectMRsScope, ProjectMRsData, DiscussionsData, MrByBranchEntry, MrByBranchData, BranchEnrichment, Commands, CommandName, ForgeSlug, ForgeTokenData, Attention, RunSummary, RunStageRow, RunFieldRow, RunDecisionRow, RunDetail, WakeMode, ChatMember, ChatMessage, RoomSummary, BuddyStatus, PresenceRow, } from "./commands.ts";
|
|
5
|
+
export type { Discussion, DemandDecl, ProjectMRsScope, ProjectMRsData, DiscussionsData, MrByBranchEntry, MrByBranchData, BranchEnrichment, Commands, CommandName, ForgeSlug, ForgeTokenData, Attention, RunSummary, RunStageRow, RunFieldRow, RunDecisionRow, RunDetail, WakeMode, ChatMember, ChatMessage, RoomSummary, BuddyStatus, PresenceRow, AgentRecord, AgentSurface, AgentStatus, ChatPane, PaneAccount, PaneDirectory, InviteResult, } from "./commands.ts";
|
|
6
6
|
export { subscribe, createRelay, DEFAULT_WS_URL } from "./relay.ts";
|
|
7
7
|
export type { RelayEventType } from "./relay.ts";
|
|
8
8
|
export { daemonHealth } from "./health.ts";
|
package/dist/index.js
CHANGED
|
@@ -124,6 +124,8 @@ function chatArm(a, o = {}) {
|
|
|
124
124
|
}
|
|
125
125
|
function chatTouch(a, o = {}) {
|
|
126
126
|
const payload = { handle: a.handle };
|
|
127
|
+
if (a.room !== undefined)
|
|
128
|
+
payload.room = a.room;
|
|
127
129
|
if (a.sessionId !== undefined)
|
|
128
130
|
payload.sessionId = a.sessionId;
|
|
129
131
|
return rtCommand("chat:touch", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 1e4 });
|
|
@@ -187,6 +189,64 @@ function chatDm(a, o = {}) {
|
|
|
187
189
|
function eventsHead(o = {}) {
|
|
188
190
|
return rtCommand("events:head", {}, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 1e4 });
|
|
189
191
|
}
|
|
192
|
+
function agentStart(a, o = {}) {
|
|
193
|
+
const payload = { repo: a.repo, cwd: a.cwd };
|
|
194
|
+
for (const k of ["prompt", "surface", "model", "effort", "account", "label", "caller", "workspace", "tab", "extraArgs"]) {
|
|
195
|
+
if (a[k] !== undefined)
|
|
196
|
+
payload[k] = a[k];
|
|
197
|
+
}
|
|
198
|
+
return rtCommand("agent:start", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 30000 });
|
|
199
|
+
}
|
|
200
|
+
function agentResume(a, o = {}) {
|
|
201
|
+
const payload = { id: a.id };
|
|
202
|
+
if (a.prompt !== undefined)
|
|
203
|
+
payload.prompt = a.prompt;
|
|
204
|
+
if (a.surface !== undefined)
|
|
205
|
+
payload.surface = a.surface;
|
|
206
|
+
return rtCommand("agent:resume", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 30000 });
|
|
207
|
+
}
|
|
208
|
+
function agentGet(a, o = {}) {
|
|
209
|
+
return rtCommand("agent:get", { id: a.id }, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 1e4 });
|
|
210
|
+
}
|
|
211
|
+
function agentList(a, o = {}) {
|
|
212
|
+
const payload = {};
|
|
213
|
+
if (a.repo !== undefined)
|
|
214
|
+
payload.repo = a.repo;
|
|
215
|
+
return rtCommand("agent:list", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 1e4 });
|
|
216
|
+
}
|
|
217
|
+
function paneList(o = {}) {
|
|
218
|
+
return rtCommand("pane:list", {}, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 1e4 });
|
|
219
|
+
}
|
|
220
|
+
function panePeek(a, o = {}) {
|
|
221
|
+
const payload = { paneId: a.paneId };
|
|
222
|
+
if (a.lines !== undefined)
|
|
223
|
+
payload.lines = a.lines;
|
|
224
|
+
return rtCommand("pane:peek", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 1e4 });
|
|
225
|
+
}
|
|
226
|
+
function paneSpawn(a, o = {}) {
|
|
227
|
+
const payload = { cwd: a.cwd };
|
|
228
|
+
for (const k of ["account", "model", "effort", "prompt", "workspace"])
|
|
229
|
+
if (a[k] !== undefined)
|
|
230
|
+
payload[k] = a[k];
|
|
231
|
+
return rtCommand("pane:spawn", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 90000 });
|
|
232
|
+
}
|
|
233
|
+
function paneAccounts(o = {}) {
|
|
234
|
+
return rtCommand("pane:accounts", {}, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 1e4 });
|
|
235
|
+
}
|
|
236
|
+
function paneDirectories(a, o = {}) {
|
|
237
|
+
const payload = {};
|
|
238
|
+
if (a.q !== undefined)
|
|
239
|
+
payload.q = a.q;
|
|
240
|
+
return rtCommand("pane:directories", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 1e4 });
|
|
241
|
+
}
|
|
242
|
+
function chatInvite(a, o = {}) {
|
|
243
|
+
const payload = { paneId: a.paneId, room: a.room, from: a.from };
|
|
244
|
+
if (a.note !== undefined)
|
|
245
|
+
payload.note = a.note;
|
|
246
|
+
if (a.callerPane !== undefined)
|
|
247
|
+
payload.callerPane = a.callerPane;
|
|
248
|
+
return rtCommand("chat:invite", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 30000 });
|
|
249
|
+
}
|
|
190
250
|
// src/commands.ts
|
|
191
251
|
var COMMAND_NAMES = [
|
|
192
252
|
"project-mrs:read",
|
|
@@ -219,7 +279,17 @@ var COMMAND_NAMES = [
|
|
|
219
279
|
"chat:back",
|
|
220
280
|
"chat:buddies",
|
|
221
281
|
"chat:pulse",
|
|
222
|
-
"chat:dm"
|
|
282
|
+
"chat:dm",
|
|
283
|
+
"agent:start",
|
|
284
|
+
"agent:resume",
|
|
285
|
+
"agent:get",
|
|
286
|
+
"agent:list",
|
|
287
|
+
"chat:invite",
|
|
288
|
+
"pane:list",
|
|
289
|
+
"pane:peek",
|
|
290
|
+
"pane:accounts",
|
|
291
|
+
"pane:directories",
|
|
292
|
+
"pane:spawn"
|
|
223
293
|
];
|
|
224
294
|
// src/relay.ts
|
|
225
295
|
var DEFAULT_WS_URL = "ws://127.0.0.1:9401/ws";
|
|
@@ -659,7 +729,7 @@ var REGISTRY = [
|
|
|
659
729
|
type: "array",
|
|
660
730
|
scopes: ["team"],
|
|
661
731
|
merge: "replace",
|
|
662
|
-
description: "The
|
|
732
|
+
description: "The authors tab's roster: whose MRs the classic board lists, including hidden-by-default entries. Codeowners tabs list MRs from anyone."
|
|
663
733
|
},
|
|
664
734
|
{
|
|
665
735
|
key: "board.title",
|
|
@@ -680,14 +750,14 @@ var REGISTRY = [
|
|
|
680
750
|
type: "array",
|
|
681
751
|
scopes: ["team"],
|
|
682
752
|
merge: "replace",
|
|
683
|
-
description: "Ticket key prefixes (e.g. RT, MAT) the
|
|
753
|
+
description: "Ticket key prefixes (e.g. RT, MAT) that keep the authors tab to the team's own tickets and link out to Linear from an MR title; rows on a codeowners tab pass regardless of prefix."
|
|
684
754
|
},
|
|
685
755
|
{
|
|
686
756
|
key: "board.slack",
|
|
687
757
|
type: "object",
|
|
688
758
|
scopes: ["team"],
|
|
689
759
|
merge: "deep",
|
|
690
|
-
description: "The board's Slack posting config (app id, client id, channel, callback port);
|
|
760
|
+
description: "The board's Slack posting config (app id, client id, channel, callback port); channel is the default that a tab's slackChannel overrides per MR. Client secrets stay out of this store."
|
|
691
761
|
},
|
|
692
762
|
{
|
|
693
763
|
key: "board.doctorSkill",
|
|
@@ -708,7 +778,7 @@ var REGISTRY = [
|
|
|
708
778
|
type: "array",
|
|
709
779
|
scopes: ["team"],
|
|
710
780
|
merge: "replace",
|
|
711
|
-
description: "Board
|
|
781
|
+
description: "Board tabs ({id, label, source, slackChannel?, reviewSkill?}), editable from the board's settings modal. source.kind 'authors' is the classic roster board; 'codeowners' lists MRs from any author blocked on an unapproved CODEOWNERS section. Absent = one implicit authors tab (fallback lives in the board reader, never here)."
|
|
712
782
|
},
|
|
713
783
|
{
|
|
714
784
|
key: "board.staleAfterDays",
|
|
@@ -736,7 +806,7 @@ var REGISTRY = [
|
|
|
736
806
|
type: "array",
|
|
737
807
|
scopes: ["user"],
|
|
738
808
|
merge: "replace",
|
|
739
|
-
description: "Usernames this developer hides from the
|
|
809
|
+
description: "Usernames this developer hides from the authors tab's board.members roster; overlays the team truth without editing it."
|
|
740
810
|
},
|
|
741
811
|
{
|
|
742
812
|
key: "board.triage",
|
|
@@ -816,6 +886,21 @@ var REGISTRY = [
|
|
|
816
886
|
merge: "replace",
|
|
817
887
|
description: "The human's own chat handle, so agents can @-mention them by name."
|
|
818
888
|
},
|
|
889
|
+
{
|
|
890
|
+
key: "chat.viewerUrl",
|
|
891
|
+
type: "string",
|
|
892
|
+
scopes: ["user"],
|
|
893
|
+
merge: "replace",
|
|
894
|
+
description: "Base URL of the chat viewer, no trailing slash. When set, rt chat post and the tail's wake lines end with a link to the room or message."
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
key: "chat.herdrWorkspace",
|
|
898
|
+
type: "string",
|
|
899
|
+
scopes: ["user"],
|
|
900
|
+
default: "chat",
|
|
901
|
+
merge: "replace",
|
|
902
|
+
description: "herdr workspace label that rt pane spawn opens new agent tabs in; created when missing."
|
|
903
|
+
},
|
|
819
904
|
{
|
|
820
905
|
key: "chat.push.provider",
|
|
821
906
|
type: "string",
|
|
@@ -829,6 +914,34 @@ var REGISTRY = [
|
|
|
829
914
|
scopes: ["user"],
|
|
830
915
|
merge: "replace",
|
|
831
916
|
description: "Destination (topic/URL/token) the configured chat.push.provider sends to."
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
key: "agent.model",
|
|
920
|
+
type: "string",
|
|
921
|
+
scopes: ["user", "machine"],
|
|
922
|
+
merge: "replace",
|
|
923
|
+
description: "Default --model for rt agent launches; unset omits the flag."
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
key: "agent.effort",
|
|
927
|
+
type: "string",
|
|
928
|
+
scopes: ["user", "machine"],
|
|
929
|
+
merge: "replace",
|
|
930
|
+
description: "Default --effort for rt agent launches; unset omits the flag."
|
|
931
|
+
},
|
|
932
|
+
{
|
|
933
|
+
key: "agent.account",
|
|
934
|
+
type: "string",
|
|
935
|
+
scopes: ["user", "machine"],
|
|
936
|
+
merge: "replace",
|
|
937
|
+
description: "cswap account email rt agent launches under; unset uses the default claude profile."
|
|
938
|
+
},
|
|
939
|
+
{
|
|
940
|
+
key: "agent.extraArgs",
|
|
941
|
+
type: "string",
|
|
942
|
+
scopes: ["user", "machine"],
|
|
943
|
+
merge: "replace",
|
|
944
|
+
description: "Opaque extra claude arguments appended to every rt agent launch (escape hatch)."
|
|
832
945
|
}
|
|
833
946
|
];
|
|
834
947
|
|
|
@@ -1624,6 +1737,11 @@ export {
|
|
|
1624
1737
|
readDiscussions,
|
|
1625
1738
|
readBranchCache,
|
|
1626
1739
|
parseIdentity,
|
|
1740
|
+
paneSpawn,
|
|
1741
|
+
panePeek,
|
|
1742
|
+
paneList,
|
|
1743
|
+
paneDirectories,
|
|
1744
|
+
paneAccounts,
|
|
1627
1745
|
normalizeRemote,
|
|
1628
1746
|
listTeams,
|
|
1629
1747
|
listSettings,
|
|
@@ -1653,6 +1771,7 @@ export {
|
|
|
1653
1771
|
chatMark,
|
|
1654
1772
|
chatLeave,
|
|
1655
1773
|
chatJoin,
|
|
1774
|
+
chatInvite,
|
|
1656
1775
|
chatDm,
|
|
1657
1776
|
chatDisarm,
|
|
1658
1777
|
chatBuddies,
|
|
@@ -1660,6 +1779,10 @@ export {
|
|
|
1660
1779
|
chatAway,
|
|
1661
1780
|
chatArm,
|
|
1662
1781
|
allDefs,
|
|
1782
|
+
agentStart,
|
|
1783
|
+
agentResume,
|
|
1784
|
+
agentList,
|
|
1785
|
+
agentGet,
|
|
1663
1786
|
abandonRun,
|
|
1664
1787
|
SCOPE_ORDER,
|
|
1665
1788
|
REGISTRY,
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -21,6 +21,8 @@ import type {
|
|
|
21
21
|
RoomSummary,
|
|
22
22
|
BuddyStatus,
|
|
23
23
|
PresenceRow,
|
|
24
|
+
AgentRecord,
|
|
25
|
+
Commands,
|
|
24
26
|
} from "./commands.ts";
|
|
25
27
|
|
|
26
28
|
/**
|
|
@@ -227,10 +229,11 @@ export function chatArm(
|
|
|
227
229
|
}
|
|
228
230
|
|
|
229
231
|
export function chatTouch(
|
|
230
|
-
a: { handle: string; sessionId?: string },
|
|
232
|
+
a: { handle: string; room?: string; sessionId?: string },
|
|
231
233
|
o: RtClientOptions = {},
|
|
232
234
|
): Promise<RtResponse<Record<string, never>>> {
|
|
233
235
|
const payload: Record<string, unknown> = { handle: a.handle };
|
|
236
|
+
if (a.room !== undefined) payload.room = a.room;
|
|
234
237
|
if (a.sessionId !== undefined) payload.sessionId = a.sessionId;
|
|
235
238
|
return rtCommand<Record<string, never>>("chat:touch", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 10_000 });
|
|
236
239
|
}
|
|
@@ -323,3 +326,77 @@ export function chatDm(
|
|
|
323
326
|
export function eventsHead(o: RtClientOptions = {}): Promise<RtResponse<{ cursor: number }>> {
|
|
324
327
|
return rtCommand<{ cursor: number }>("events:head", {}, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 10_000 });
|
|
325
328
|
}
|
|
329
|
+
|
|
330
|
+
// ─── Agent handoff (rt agent) ─────────────────────────────────────────────
|
|
331
|
+
|
|
332
|
+
export function agentStart(
|
|
333
|
+
a: Commands["agent:start"]["payload"], o: RtClientOptions = {},
|
|
334
|
+
): Promise<RtResponse<AgentRecord>> {
|
|
335
|
+
const payload: Record<string, unknown> = { repo: a.repo, cwd: a.cwd };
|
|
336
|
+
for (const k of ["prompt", "surface", "model", "effort", "account", "label", "caller", "workspace", "tab", "extraArgs"] as const) {
|
|
337
|
+
if (a[k] !== undefined) payload[k] = a[k];
|
|
338
|
+
}
|
|
339
|
+
return rtCommand<AgentRecord>("agent:start", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 30_000 });
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export function agentResume(
|
|
343
|
+
a: Commands["agent:resume"]["payload"], o: RtClientOptions = {},
|
|
344
|
+
): Promise<RtResponse<AgentRecord>> {
|
|
345
|
+
const payload: Record<string, unknown> = { id: a.id };
|
|
346
|
+
if (a.prompt !== undefined) payload.prompt = a.prompt;
|
|
347
|
+
if (a.surface !== undefined) payload.surface = a.surface;
|
|
348
|
+
return rtCommand<AgentRecord>("agent:resume", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 30_000 });
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export function agentGet(a: { id: string }, o: RtClientOptions = {}): Promise<RtResponse<AgentRecord>> {
|
|
352
|
+
return rtCommand<AgentRecord>("agent:get", { id: a.id }, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 10_000 });
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export function agentList(a: { repo?: string }, o: RtClientOptions = {}): Promise<RtResponse<{ agents: AgentRecord[] }>> {
|
|
356
|
+
const payload: Record<string, unknown> = {};
|
|
357
|
+
if (a.repo !== undefined) payload.repo = a.repo;
|
|
358
|
+
return rtCommand<{ agents: AgentRecord[] }>("agent:list", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 10_000 });
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// ─── Panes (rt chat invite) ────────────────────────────────────────────────
|
|
362
|
+
// herdr-facing verbs; the daemon answers `herdr unavailable` without herdr.
|
|
363
|
+
|
|
364
|
+
export function paneList(o: RtClientOptions = {}): Promise<RtResponse<Commands["pane:list"]["data"]>> {
|
|
365
|
+
return rtCommand<Commands["pane:list"]["data"]>("pane:list", {}, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 10_000 });
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export function panePeek(a: Commands["pane:peek"]["payload"], o: RtClientOptions = {}): Promise<RtResponse<Commands["pane:peek"]["data"]>> {
|
|
369
|
+
const payload: Record<string, unknown> = { paneId: a.paneId };
|
|
370
|
+
if (a.lines !== undefined) payload.lines = a.lines;
|
|
371
|
+
return rtCommand<Commands["pane:peek"]["data"]>("pane:peek", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 10_000 });
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/** The spawn waits on claude starting, so its budget is minutes, not seconds. */
|
|
375
|
+
export function paneSpawn(
|
|
376
|
+
a: Commands["pane:spawn"]["payload"],
|
|
377
|
+
o: RtClientOptions = {},
|
|
378
|
+
): Promise<RtResponse<Commands["pane:spawn"]["data"]>> {
|
|
379
|
+
const payload: Record<string, unknown> = { cwd: a.cwd };
|
|
380
|
+
for (const k of ["account", "model", "effort", "prompt", "workspace"] as const) if (a[k] !== undefined) payload[k] = a[k];
|
|
381
|
+
return rtCommand<Commands["pane:spawn"]["data"]>("pane:spawn", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 90_000 });
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export function paneAccounts(o: RtClientOptions = {}): Promise<RtResponse<Commands["pane:accounts"]["data"]>> {
|
|
385
|
+
return rtCommand<Commands["pane:accounts"]["data"]>("pane:accounts", {}, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 10_000 });
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export function paneDirectories(a: Commands["pane:directories"]["payload"], o: RtClientOptions = {}): Promise<RtResponse<Commands["pane:directories"]["data"]>> {
|
|
389
|
+
const payload: Record<string, unknown> = {};
|
|
390
|
+
if (a.q !== undefined) payload.q = a.q;
|
|
391
|
+
return rtCommand<Commands["pane:directories"]["data"]>("pane:directories", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 10_000 });
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export function chatInvite(
|
|
395
|
+
a: Commands["chat:invite"]["payload"],
|
|
396
|
+
o: RtClientOptions = {},
|
|
397
|
+
): Promise<RtResponse<Commands["chat:invite"]["data"]>> {
|
|
398
|
+
const payload: Record<string, unknown> = { paneId: a.paneId, room: a.room, from: a.from };
|
|
399
|
+
if (a.note !== undefined) payload.note = a.note;
|
|
400
|
+
if (a.callerPane !== undefined) payload.callerPane = a.callerPane;
|
|
401
|
+
return rtCommand<Commands["chat:invite"]["data"]>("chat:invite", payload, { sockPath: o.sockPath, timeoutMs: o.timeoutMs ?? 30_000 });
|
|
402
|
+
}
|
package/src/commands.ts
CHANGED
|
@@ -146,6 +146,25 @@ export interface PresenceRow {
|
|
|
146
146
|
signedOutAt?: number;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
export type AgentStatus = "idle" | "working" | "blocked" | "done" | "unknown";
|
|
150
|
+
|
|
151
|
+
/** Duplicated shape on purpose (see EventsBusEvent above): mirrors the daemon's pane row, which rt-client cannot import. */
|
|
152
|
+
export interface ChatPane {
|
|
153
|
+
paneId: string;
|
|
154
|
+
workspace: string;
|
|
155
|
+
title?: string;
|
|
156
|
+
cwd?: string;
|
|
157
|
+
repo?: string;
|
|
158
|
+
branch?: string;
|
|
159
|
+
agentStatus: AgentStatus;
|
|
160
|
+
sessionId?: string;
|
|
161
|
+
presence?: { handle: string; status: BuddyStatus; rooms: string[] };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface PaneAccount { slot: number; email: string; alias?: string; headroom?: string }
|
|
165
|
+
export interface PaneDirectory { path: string; repo: string; branch?: string }
|
|
166
|
+
export interface InviteResult { paneId: string; delivered: "accepted" | "queued" | "refused"; reason?: string }
|
|
167
|
+
|
|
149
168
|
// SKILLS-53: one judgment, computed once in rt, so the console and the tray
|
|
150
169
|
// never derive two verdicts that can disagree.
|
|
151
170
|
export type Attention = {
|
|
@@ -192,6 +211,18 @@ export interface RunFieldRow { key: string; value: string; produced_by: string;
|
|
|
192
211
|
export interface RunDecisionRow { contract: string; scope: string; selection: string; decided_by: string; decided_at: number; }
|
|
193
212
|
export interface RunDetail { run: RunSummary; stages: RunStageRow[]; fields: RunFieldRow[]; decisions: RunDecisionRow[]; schemaAhead: boolean; }
|
|
194
213
|
|
|
214
|
+
export type AgentSurface = "herdr" | "headless";
|
|
215
|
+
|
|
216
|
+
export interface AgentRecord {
|
|
217
|
+
id: string; repo: string; cwd: string; provider: string;
|
|
218
|
+
surface: AgentSurface; sessionId: string;
|
|
219
|
+
model?: string; effort?: string; account?: string;
|
|
220
|
+
label?: string; caller?: string;
|
|
221
|
+
paneId?: string; tabId?: string; workspaceId?: string;
|
|
222
|
+
extraArgs?: string; exitCode?: number; resultPath?: string;
|
|
223
|
+
createdAt: number; lastResumedAt?: number; finishedAt?: number;
|
|
224
|
+
}
|
|
225
|
+
|
|
195
226
|
export interface Commands {
|
|
196
227
|
"project-mrs:read": { payload: { repoName: string; maxAgeMs?: number; demand?: DemandDecl }; data: ProjectMRsData };
|
|
197
228
|
"discussions:read": { payload: { repoName: string; iid: number }; data: DiscussionsData };
|
|
@@ -257,7 +288,7 @@ export interface Commands {
|
|
|
257
288
|
"chat:mark": { payload: { handle: string; room?: string }; data: Record<string, never> };
|
|
258
289
|
"chat:messages": { payload: { room: string; before?: number; limit?: number }; data: { messages: ChatMessage[] } };
|
|
259
290
|
"chat:arm": { payload: { handle: string; room?: string; sessionId?: string }; data: Record<string, never> };
|
|
260
|
-
"chat:touch": { payload: { handle: string; sessionId?: string }; data: Record<string, never> };
|
|
291
|
+
"chat:touch": { payload: { handle: string; room?: string; sessionId?: string }; data: Record<string, never> };
|
|
261
292
|
"chat:disarm": { payload: { handle: string; sessionId?: string }; data: Record<string, never> };
|
|
262
293
|
"chat:unread-waking": { payload: { handle: string; room?: string }; data: { rooms: { room: string; count: number; mentions: number; maxId: number }[] } };
|
|
263
294
|
|
|
@@ -277,6 +308,21 @@ export interface Commands {
|
|
|
277
308
|
data: { unread: { dms: number; mentions: number; rooms: number }; status: BuddyStatus };
|
|
278
309
|
};
|
|
279
310
|
"chat:dm": { payload: { from: string; to: string; body: string; sessionId?: string }; data: { room: string; id: number; recipients: string[] } };
|
|
311
|
+
|
|
312
|
+
// ─── Agent handoff (rt agent) ────────────────────────────────────────────
|
|
313
|
+
"agent:start": { payload: { repo: string; cwd: string; prompt?: string; surface?: AgentSurface; model?: string; effort?: string; account?: string; label?: string; caller?: string; workspace?: string; tab?: string; extraArgs?: string }; data: AgentRecord };
|
|
314
|
+
"agent:resume": { payload: { id: string; prompt?: string; surface?: AgentSurface }; data: AgentRecord };
|
|
315
|
+
"agent:get": { payload: { id: string }; data: AgentRecord };
|
|
316
|
+
"agent:list": { payload: { repo?: string }; data: { agents: AgentRecord[] } };
|
|
317
|
+
"chat:invite": { payload: { paneId: string; room: string; note?: string; from: string; callerPane?: string }; data: InviteResult };
|
|
318
|
+
"pane:list": { payload: Record<string, never>; data: { panes: ChatPane[] } };
|
|
319
|
+
"pane:peek": { payload: { paneId: string; lines?: number }; data: { paneId: string; lines: string[] } };
|
|
320
|
+
"pane:accounts": { payload: Record<string, never>; data: { accounts: PaneAccount[] } };
|
|
321
|
+
"pane:directories": { payload: { q?: string }; data: { directories: PaneDirectory[] } };
|
|
322
|
+
"pane:spawn": {
|
|
323
|
+
payload: { cwd: string; account?: string; model?: string; effort?: string; prompt?: string; workspace?: string };
|
|
324
|
+
data: { pane: ChatPane; ready: boolean };
|
|
325
|
+
};
|
|
280
326
|
}
|
|
281
327
|
|
|
282
328
|
export type CommandName = keyof Commands;
|
|
@@ -313,4 +359,14 @@ export const COMMAND_NAMES: readonly CommandName[] = [
|
|
|
313
359
|
"chat:buddies",
|
|
314
360
|
"chat:pulse",
|
|
315
361
|
"chat:dm",
|
|
362
|
+
"agent:start",
|
|
363
|
+
"agent:resume",
|
|
364
|
+
"agent:get",
|
|
365
|
+
"agent:list",
|
|
366
|
+
"chat:invite",
|
|
367
|
+
"pane:list",
|
|
368
|
+
"pane:peek",
|
|
369
|
+
"pane:accounts",
|
|
370
|
+
"pane:directories",
|
|
371
|
+
"pane:spawn",
|
|
316
372
|
];
|
package/src/index.ts
CHANGED
|
@@ -30,6 +30,16 @@ export {
|
|
|
30
30
|
chatPulse,
|
|
31
31
|
chatDm,
|
|
32
32
|
eventsHead,
|
|
33
|
+
agentStart,
|
|
34
|
+
agentResume,
|
|
35
|
+
agentGet,
|
|
36
|
+
agentList,
|
|
37
|
+
paneList,
|
|
38
|
+
panePeek,
|
|
39
|
+
paneSpawn,
|
|
40
|
+
paneAccounts,
|
|
41
|
+
paneDirectories,
|
|
42
|
+
chatInvite,
|
|
33
43
|
} from "./client.ts";
|
|
34
44
|
|
|
35
45
|
export { COMMAND_NAMES } from "./commands.ts";
|
|
@@ -58,6 +68,13 @@ export type {
|
|
|
58
68
|
RoomSummary,
|
|
59
69
|
BuddyStatus,
|
|
60
70
|
PresenceRow,
|
|
71
|
+
AgentRecord,
|
|
72
|
+
AgentSurface,
|
|
73
|
+
AgentStatus,
|
|
74
|
+
ChatPane,
|
|
75
|
+
PaneAccount,
|
|
76
|
+
PaneDirectory,
|
|
77
|
+
InviteResult,
|
|
61
78
|
} from "./commands.ts";
|
|
62
79
|
|
|
63
80
|
export { subscribe, createRelay, DEFAULT_WS_URL } from "./relay.ts";
|
|
@@ -308,7 +308,7 @@ export const REGISTRY: readonly SettingDef[] = [
|
|
|
308
308
|
type: "array",
|
|
309
309
|
scopes: ["team"],
|
|
310
310
|
merge: "replace",
|
|
311
|
-
description: "The
|
|
311
|
+
description: "The authors tab's roster: whose MRs the classic board lists, including hidden-by-default entries. Codeowners tabs list MRs from anyone.",
|
|
312
312
|
},
|
|
313
313
|
{
|
|
314
314
|
key: "board.title",
|
|
@@ -329,14 +329,14 @@ export const REGISTRY: readonly SettingDef[] = [
|
|
|
329
329
|
type: "array",
|
|
330
330
|
scopes: ["team"],
|
|
331
331
|
merge: "replace",
|
|
332
|
-
description: "Ticket key prefixes (e.g. RT, MAT) the
|
|
332
|
+
description: "Ticket key prefixes (e.g. RT, MAT) that keep the authors tab to the team's own tickets and link out to Linear from an MR title; rows on a codeowners tab pass regardless of prefix.",
|
|
333
333
|
},
|
|
334
334
|
{
|
|
335
335
|
key: "board.slack",
|
|
336
336
|
type: "object",
|
|
337
337
|
scopes: ["team"],
|
|
338
338
|
merge: "deep",
|
|
339
|
-
description: "The board's Slack posting config (app id, client id, channel, callback port);
|
|
339
|
+
description: "The board's Slack posting config (app id, client id, channel, callback port); channel is the default that a tab's slackChannel overrides per MR. Client secrets stay out of this store.",
|
|
340
340
|
},
|
|
341
341
|
{
|
|
342
342
|
key: "board.doctorSkill",
|
|
@@ -357,7 +357,7 @@ export const REGISTRY: readonly SettingDef[] = [
|
|
|
357
357
|
type: "array",
|
|
358
358
|
scopes: ["team"],
|
|
359
359
|
merge: "replace",
|
|
360
|
-
description: "Board
|
|
360
|
+
description: "Board tabs ({id, label, source, slackChannel?, reviewSkill?}), editable from the board's settings modal. source.kind 'authors' is the classic roster board; 'codeowners' lists MRs from any author blocked on an unapproved CODEOWNERS section. Absent = one implicit authors tab (fallback lives in the board reader, never here).",
|
|
361
361
|
},
|
|
362
362
|
|
|
363
363
|
// --- board (user) ----------------------------------------------------------
|
|
@@ -387,7 +387,7 @@ export const REGISTRY: readonly SettingDef[] = [
|
|
|
387
387
|
type: "array",
|
|
388
388
|
scopes: ["user"],
|
|
389
389
|
merge: "replace",
|
|
390
|
-
description: "Usernames this developer hides from the
|
|
390
|
+
description: "Usernames this developer hides from the authors tab's board.members roster; overlays the team truth without editing it.",
|
|
391
391
|
},
|
|
392
392
|
{
|
|
393
393
|
key: "board.triage",
|
|
@@ -473,6 +473,21 @@ export const REGISTRY: readonly SettingDef[] = [
|
|
|
473
473
|
merge: "replace",
|
|
474
474
|
description: "The human's own chat handle, so agents can @-mention them by name.",
|
|
475
475
|
},
|
|
476
|
+
{
|
|
477
|
+
key: "chat.viewerUrl",
|
|
478
|
+
type: "string",
|
|
479
|
+
scopes: ["user"],
|
|
480
|
+
merge: "replace",
|
|
481
|
+
description: "Base URL of the chat viewer, no trailing slash. When set, rt chat post and the tail's wake lines end with a link to the room or message.",
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
key: "chat.herdrWorkspace",
|
|
485
|
+
type: "string",
|
|
486
|
+
scopes: ["user"],
|
|
487
|
+
default: "chat",
|
|
488
|
+
merge: "replace",
|
|
489
|
+
description: "herdr workspace label that rt pane spawn opens new agent tabs in; created when missing.",
|
|
490
|
+
},
|
|
476
491
|
{
|
|
477
492
|
key: "chat.push.provider",
|
|
478
493
|
type: "string",
|
|
@@ -487,4 +502,36 @@ export const REGISTRY: readonly SettingDef[] = [
|
|
|
487
502
|
merge: "replace",
|
|
488
503
|
description: "Destination (topic/URL/token) the configured chat.push.provider sends to.",
|
|
489
504
|
},
|
|
505
|
+
|
|
506
|
+
// --- agent (rt agent handoff) --------------------------------------------
|
|
507
|
+
// No defaults by design: an unset key means the flag is omitted from the
|
|
508
|
+
// claude invocation entirely (spec "Settings").
|
|
509
|
+
{
|
|
510
|
+
key: "agent.model",
|
|
511
|
+
type: "string",
|
|
512
|
+
scopes: ["user", "machine"],
|
|
513
|
+
merge: "replace",
|
|
514
|
+
description: "Default --model for rt agent launches; unset omits the flag.",
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
key: "agent.effort",
|
|
518
|
+
type: "string",
|
|
519
|
+
scopes: ["user", "machine"],
|
|
520
|
+
merge: "replace",
|
|
521
|
+
description: "Default --effort for rt agent launches; unset omits the flag.",
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
key: "agent.account",
|
|
525
|
+
type: "string",
|
|
526
|
+
scopes: ["user", "machine"],
|
|
527
|
+
merge: "replace",
|
|
528
|
+
description: "cswap account email rt agent launches under; unset uses the default claude profile.",
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
key: "agent.extraArgs",
|
|
532
|
+
type: "string",
|
|
533
|
+
scopes: ["user", "machine"],
|
|
534
|
+
merge: "replace",
|
|
535
|
+
description: "Opaque extra claude arguments appended to every rt agent launch (escape hatch).",
|
|
536
|
+
},
|
|
490
537
|
];
|