@agentuity/coder 1.0.37
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 +57 -0
- package/dist/chain-preview.d.ts +55 -0
- package/dist/chain-preview.d.ts.map +1 -0
- package/dist/chain-preview.js +472 -0
- package/dist/chain-preview.js.map +1 -0
- package/dist/client.d.ts +43 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +402 -0
- package/dist/client.js.map +1 -0
- package/dist/commands.d.ts +22 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +99 -0
- package/dist/commands.js.map +1 -0
- package/dist/footer.d.ts +34 -0
- package/dist/footer.d.ts.map +1 -0
- package/dist/footer.js +249 -0
- package/dist/footer.js.map +1 -0
- package/dist/handlers.d.ts +24 -0
- package/dist/handlers.d.ts.map +1 -0
- package/dist/handlers.js +83 -0
- package/dist/handlers.js.map +1 -0
- package/dist/hub-overlay.d.ts +107 -0
- package/dist/hub-overlay.d.ts.map +1 -0
- package/dist/hub-overlay.js +1794 -0
- package/dist/hub-overlay.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1585 -0
- package/dist/index.js.map +1 -0
- package/dist/output-viewer.d.ts +49 -0
- package/dist/output-viewer.d.ts.map +1 -0
- package/dist/output-viewer.js +389 -0
- package/dist/output-viewer.js.map +1 -0
- package/dist/overlay.d.ts +40 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +225 -0
- package/dist/overlay.js.map +1 -0
- package/dist/protocol.d.ts +118 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +3 -0
- package/dist/protocol.js.map +1 -0
- package/dist/remote-session.d.ts +113 -0
- package/dist/remote-session.d.ts.map +1 -0
- package/dist/remote-session.js +645 -0
- package/dist/remote-session.js.map +1 -0
- package/dist/remote-tui.d.ts +40 -0
- package/dist/remote-tui.d.ts.map +1 -0
- package/dist/remote-tui.js +606 -0
- package/dist/remote-tui.js.map +1 -0
- package/dist/renderers.d.ts +34 -0
- package/dist/renderers.d.ts.map +1 -0
- package/dist/renderers.js +669 -0
- package/dist/renderers.js.map +1 -0
- package/dist/review.d.ts +15 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +154 -0
- package/dist/review.js.map +1 -0
- package/dist/titlebar.d.ts +3 -0
- package/dist/titlebar.d.ts.map +1 -0
- package/dist/titlebar.js +59 -0
- package/dist/titlebar.js.map +1 -0
- package/dist/todo/index.d.ts +3 -0
- package/dist/todo/index.d.ts.map +1 -0
- package/dist/todo/index.js +3 -0
- package/dist/todo/index.js.map +1 -0
- package/dist/todo/store.d.ts +6 -0
- package/dist/todo/store.d.ts.map +1 -0
- package/dist/todo/store.js +43 -0
- package/dist/todo/store.js.map +1 -0
- package/dist/todo/types.d.ts +13 -0
- package/dist/todo/types.d.ts.map +1 -0
- package/dist/todo/types.js +2 -0
- package/dist/todo/types.js.map +1 -0
- package/package.json +44 -0
- package/src/chain-preview.ts +621 -0
- package/src/client.ts +515 -0
- package/src/commands.ts +132 -0
- package/src/footer.ts +305 -0
- package/src/handlers.ts +113 -0
- package/src/hub-overlay.ts +2324 -0
- package/src/index.ts +1907 -0
- package/src/output-viewer.ts +480 -0
- package/src/overlay.ts +294 -0
- package/src/protocol.ts +157 -0
- package/src/remote-session.ts +800 -0
- package/src/remote-tui.ts +707 -0
- package/src/renderers.ts +740 -0
- package/src/review.ts +201 -0
- package/src/titlebar.ts +63 -0
- package/src/todo/index.ts +2 -0
- package/src/todo/store.ts +49 -0
- package/src/todo/types.ts +14 -0
package/src/overlay.ts
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import type { Theme } from '@mariozechner/pi-coding-agent';
|
|
2
|
+
import { matchesKey } from '@mariozechner/pi-tui';
|
|
3
|
+
import type { AgentDefinition } from './protocol.ts';
|
|
4
|
+
import { truncateToWidth } from './renderers.ts';
|
|
5
|
+
|
|
6
|
+
export interface AgentManagerResult {
|
|
7
|
+
agent: string;
|
|
8
|
+
action: 'run';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface Component {
|
|
12
|
+
render(width: number): string[];
|
|
13
|
+
handleInput?(data: string): void;
|
|
14
|
+
invalidate(): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface Focusable {
|
|
18
|
+
focused: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type DoneFn = (result: AgentManagerResult | undefined) => void;
|
|
22
|
+
type Screen = 'list' | 'detail';
|
|
23
|
+
|
|
24
|
+
const ANSI_RE = /\x1b\[[0-9;]*m/g;
|
|
25
|
+
|
|
26
|
+
function visibleWidth(text: string): number {
|
|
27
|
+
return text.replace(ANSI_RE, '').length;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function padRight(text: string, width: number): string {
|
|
31
|
+
if (width <= 0) return '';
|
|
32
|
+
const truncated = truncateToWidth(text, width);
|
|
33
|
+
const remaining = width - visibleWidth(truncated);
|
|
34
|
+
return remaining > 0 ? truncated + ' '.repeat(remaining) : truncated;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function hLine(width: number): string {
|
|
38
|
+
return width > 0 ? '─'.repeat(width) : '';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function buildTopBorder(width: number, title: string): string {
|
|
42
|
+
if (width <= 0) return '';
|
|
43
|
+
if (width === 1) return '╭';
|
|
44
|
+
if (width === 2) return '╭╮';
|
|
45
|
+
|
|
46
|
+
const inner = width - 2;
|
|
47
|
+
const titleText = ` ${title} `;
|
|
48
|
+
if (titleText.length >= inner) {
|
|
49
|
+
return `╭${hLine(inner)}╮`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const left = Math.floor((inner - titleText.length) / 2);
|
|
53
|
+
const right = inner - titleText.length - left;
|
|
54
|
+
return `╭${hLine(left)}${titleText}${hLine(right)}╮`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function buildBottomBorder(width: number): string {
|
|
58
|
+
if (width <= 0) return '';
|
|
59
|
+
if (width === 1) return '╰';
|
|
60
|
+
if (width === 2) return '╰╯';
|
|
61
|
+
return `╰${hLine(width - 2)}╯`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export class AgentManagerOverlay implements Component, Focusable {
|
|
65
|
+
public focused = true;
|
|
66
|
+
|
|
67
|
+
private readonly theme: Theme;
|
|
68
|
+
private readonly agents: AgentDefinition[];
|
|
69
|
+
private readonly done: DoneFn;
|
|
70
|
+
|
|
71
|
+
private screen: Screen = 'list';
|
|
72
|
+
private selectedIndex = 0;
|
|
73
|
+
private readonly listWindowSize = 6;
|
|
74
|
+
private disposed = false;
|
|
75
|
+
|
|
76
|
+
constructor(theme: Theme, agents: AgentDefinition[], done: DoneFn) {
|
|
77
|
+
this.theme = theme;
|
|
78
|
+
this.agents = agents;
|
|
79
|
+
this.done = done;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
handleInput(data: string): void {
|
|
83
|
+
if (this.disposed) return;
|
|
84
|
+
|
|
85
|
+
if (matchesKey(data, 'escape')) {
|
|
86
|
+
if (this.screen === 'detail') {
|
|
87
|
+
this.screen = 'list';
|
|
88
|
+
this.invalidate();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.close(undefined);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (this.screen === 'list') {
|
|
96
|
+
this.handleListInput(data);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.handleDetailInput(data);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
render(width: number): string[] {
|
|
104
|
+
const safeWidth = Math.max(4, width);
|
|
105
|
+
const termHeight = process.stdout.rows || 40;
|
|
106
|
+
// Match overlay maxHeight of 95%, leave margin for overlay chrome
|
|
107
|
+
const maxLines = Math.max(10, Math.floor(termHeight * 0.95) - 2);
|
|
108
|
+
|
|
109
|
+
const lines =
|
|
110
|
+
this.screen === 'detail'
|
|
111
|
+
? this.renderDetailScreen(safeWidth)
|
|
112
|
+
: this.renderListScreen(safeWidth, maxLines);
|
|
113
|
+
return lines.map((line) => truncateToWidth(line, safeWidth));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
invalidate(): void {
|
|
117
|
+
// Stateless rendering; no cache invalidation required.
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
dispose(): void {
|
|
121
|
+
this.disposed = true;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private handleListInput(data: string): void {
|
|
125
|
+
const count = this.agents.length;
|
|
126
|
+
if (count === 0) return;
|
|
127
|
+
|
|
128
|
+
if (matchesKey(data, 'up')) {
|
|
129
|
+
this.selectedIndex = (this.selectedIndex - 1 + count) % count;
|
|
130
|
+
this.invalidate();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (matchesKey(data, 'down')) {
|
|
135
|
+
this.selectedIndex = (this.selectedIndex + 1) % count;
|
|
136
|
+
this.invalidate();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (matchesKey(data, 'enter')) {
|
|
141
|
+
this.screen = 'detail';
|
|
142
|
+
this.invalidate();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private handleDetailInput(data: string): void {
|
|
147
|
+
if (matchesKey(data, 'r') || data.toLowerCase() === 'r') {
|
|
148
|
+
const selected = this.agents[this.selectedIndex];
|
|
149
|
+
if (!selected) return;
|
|
150
|
+
this.close({ action: 'run', agent: selected.name });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private close(result: AgentManagerResult | undefined): void {
|
|
155
|
+
if (this.disposed) return;
|
|
156
|
+
this.disposed = true;
|
|
157
|
+
this.done(result);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private renderListScreen(width: number, maxLines: number): string[] {
|
|
161
|
+
const inner = Math.max(0, width - 2);
|
|
162
|
+
|
|
163
|
+
// Fixed header (always rendered)
|
|
164
|
+
const header: string[] = [
|
|
165
|
+
buildTopBorder(width, 'Agent Manager'),
|
|
166
|
+
this.contentLine('', inner),
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
// Fixed footer (always rendered)
|
|
170
|
+
const footer: string[] = [
|
|
171
|
+
this.contentLine(
|
|
172
|
+
this.theme.fg('dim', ' [↑↓] Navigate [Enter] Details [Esc] Close'),
|
|
173
|
+
inner
|
|
174
|
+
),
|
|
175
|
+
buildBottomBorder(width),
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
// Available lines for scrollable content area
|
|
179
|
+
const contentBudget = Math.max(4, maxLines - header.length - footer.length);
|
|
180
|
+
|
|
181
|
+
if (this.agents.length === 0) {
|
|
182
|
+
const content = [
|
|
183
|
+
this.contentLine(this.theme.fg('muted', ' No agents available'), inner),
|
|
184
|
+
this.contentLine('', inner),
|
|
185
|
+
];
|
|
186
|
+
return [...header, ...content, ...footer];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Each agent takes 4 lines: name, description, capabilities, empty line
|
|
190
|
+
const LINES_PER_AGENT = 4;
|
|
191
|
+
// Reserve 2 lines for possible scroll indicators
|
|
192
|
+
const scrollReserve = 2;
|
|
193
|
+
const maxAgents = Math.max(1, Math.floor((contentBudget - scrollReserve) / LINES_PER_AGENT));
|
|
194
|
+
|
|
195
|
+
// Dynamic window size based on available space
|
|
196
|
+
const windowSize = Math.min(maxAgents, this.agents.length);
|
|
197
|
+
const [start, end] = this.getVisibleRange(windowSize);
|
|
198
|
+
|
|
199
|
+
const content: string[] = [];
|
|
200
|
+
|
|
201
|
+
if (start > 0) {
|
|
202
|
+
content.push(this.contentLine(this.theme.fg('dim', ` ↑ ${start} more above`), inner));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
for (let i = start; i < end; i++) {
|
|
206
|
+
const agent = this.agents[i]!;
|
|
207
|
+
const selected = i === this.selectedIndex;
|
|
208
|
+
const prefix = selected ? this.theme.fg('accent', '› ') : ' ';
|
|
209
|
+
|
|
210
|
+
const model = agent.model ? this.theme.fg('dim', ` [${agent.model}]`) : '';
|
|
211
|
+
const readOnly = agent.readOnly ? this.theme.fg('warning', ' read-only') : '';
|
|
212
|
+
const title = `${prefix}${this.theme.bold(agent.name)}${model}${readOnly}`;
|
|
213
|
+
content.push(this.contentLine(title, inner));
|
|
214
|
+
|
|
215
|
+
const description = this.theme.fg('text', ` ${agent.description || 'No description'}`);
|
|
216
|
+
content.push(this.contentLine(description, inner));
|
|
217
|
+
|
|
218
|
+
const capsText = agent.capabilities?.length ? agent.capabilities.join(', ') : 'none';
|
|
219
|
+
const caps = this.theme.fg('muted', ` capabilities: ${capsText}`);
|
|
220
|
+
content.push(this.contentLine(caps, inner));
|
|
221
|
+
|
|
222
|
+
content.push(this.contentLine('', inner));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (end < this.agents.length) {
|
|
226
|
+
content.push(
|
|
227
|
+
this.contentLine(
|
|
228
|
+
this.theme.fg('dim', ` ↓ ${this.agents.length - end} more below`),
|
|
229
|
+
inner
|
|
230
|
+
)
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return [...header, ...content, ...footer];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private renderDetailScreen(width: number): string[] {
|
|
238
|
+
const inner = Math.max(0, width - 2);
|
|
239
|
+
const lines: string[] = [];
|
|
240
|
+
const agent = this.agents[this.selectedIndex];
|
|
241
|
+
|
|
242
|
+
lines.push(buildTopBorder(width, agent?.name || 'Agent'));
|
|
243
|
+
lines.push(this.contentLine('', inner));
|
|
244
|
+
|
|
245
|
+
if (!agent) {
|
|
246
|
+
lines.push(this.contentLine(this.theme.fg('error', ' Agent not found'), inner));
|
|
247
|
+
lines.push(this.contentLine('', inner));
|
|
248
|
+
lines.push(this.contentLine(this.theme.fg('dim', ' [Esc] Back'), inner));
|
|
249
|
+
lines.push(buildBottomBorder(width));
|
|
250
|
+
return lines;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const readOnly = agent.readOnly ? 'yes' : 'no';
|
|
254
|
+
const capabilities = agent.capabilities?.length ? agent.capabilities.join(', ') : 'none';
|
|
255
|
+
const status = agent.status || 'idle';
|
|
256
|
+
|
|
257
|
+
lines.push(this.fieldLine('Model', agent.model || 'default', inner));
|
|
258
|
+
lines.push(this.fieldLine('Read-only', readOnly, inner));
|
|
259
|
+
lines.push(this.fieldLine('Description', agent.description || 'No description', inner));
|
|
260
|
+
lines.push(this.fieldLine('Capabilities', capabilities, inner));
|
|
261
|
+
lines.push(this.fieldLine('Status', status, inner));
|
|
262
|
+
lines.push(this.contentLine('', inner));
|
|
263
|
+
lines.push(this.contentLine(this.theme.fg('dim', ' [r] Run agent [Esc] Back'), inner));
|
|
264
|
+
lines.push(buildBottomBorder(width));
|
|
265
|
+
return lines;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private fieldLine(label: string, value: string, innerWidth: number): string {
|
|
269
|
+
const labelText = this.theme.fg('dim', ` ${label}:`);
|
|
270
|
+
const content = `${labelText} ${this.theme.fg('text', value)}`;
|
|
271
|
+
return this.contentLine(content, innerWidth);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private contentLine(content: string, innerWidth: number): string {
|
|
275
|
+
return `│${padRight(content, innerWidth)}│`;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
private getVisibleRange(windowSize?: number): [number, number] {
|
|
279
|
+
const count = this.agents.length;
|
|
280
|
+
const ws = windowSize ?? this.listWindowSize;
|
|
281
|
+
if (count <= ws) return [0, count];
|
|
282
|
+
|
|
283
|
+
const half = Math.floor(ws / 2);
|
|
284
|
+
let start = Math.max(0, this.selectedIndex - half);
|
|
285
|
+
let end = start + ws;
|
|
286
|
+
|
|
287
|
+
if (end > count) {
|
|
288
|
+
end = count;
|
|
289
|
+
start = Math.max(0, end - ws);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return [start, end];
|
|
293
|
+
}
|
|
294
|
+
}
|
package/src/protocol.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// ---- Init Message (Server → Client on connect) ----
|
|
2
|
+
|
|
3
|
+
export interface HubToolDefinition {
|
|
4
|
+
name: string;
|
|
5
|
+
label: string;
|
|
6
|
+
description: string;
|
|
7
|
+
parameters: Record<string, unknown>; // JSON Schema object
|
|
8
|
+
promptSnippet?: string;
|
|
9
|
+
promptGuidelines?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Command definition sent by Hub for agent routing slash commands. */
|
|
13
|
+
export interface HubCommandDefinition {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AgentDefinition {
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
21
|
+
systemPrompt: string;
|
|
22
|
+
model?: string;
|
|
23
|
+
tools?: string[];
|
|
24
|
+
temperature?: number;
|
|
25
|
+
thinkingLevel?: string;
|
|
26
|
+
readOnly?: boolean;
|
|
27
|
+
hubTools?: HubToolDefinition[];
|
|
28
|
+
capabilities?: string[];
|
|
29
|
+
status?: 'available' | 'busy' | 'offline';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface HubConfig {
|
|
33
|
+
systemPromptPrefix?: string;
|
|
34
|
+
systemPromptSuffix?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface InitMessage {
|
|
38
|
+
type: 'init';
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
tools?: HubToolDefinition[];
|
|
41
|
+
commands?: HubCommandDefinition[];
|
|
42
|
+
agents?: AgentDefinition[];
|
|
43
|
+
config?: HubConfig;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ---- Request Messages (Client → Server) ----
|
|
47
|
+
|
|
48
|
+
export interface EventRequest {
|
|
49
|
+
id: string;
|
|
50
|
+
type: 'event';
|
|
51
|
+
event: string;
|
|
52
|
+
data: Record<string, unknown>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface ToolRequest {
|
|
56
|
+
id: string;
|
|
57
|
+
type: 'tool';
|
|
58
|
+
name: string;
|
|
59
|
+
toolCallId: string;
|
|
60
|
+
params: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Command request (Client -> Server) for slash command execution. */
|
|
64
|
+
export interface CommandRequest {
|
|
65
|
+
id: string;
|
|
66
|
+
type: 'command';
|
|
67
|
+
name: string;
|
|
68
|
+
args: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type HubRequest = EventRequest | ToolRequest | CommandRequest;
|
|
72
|
+
|
|
73
|
+
// ---- Actions ----
|
|
74
|
+
|
|
75
|
+
export interface AckAction {
|
|
76
|
+
action: 'ACK';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface BlockAction {
|
|
80
|
+
action: 'BLOCK';
|
|
81
|
+
reason: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ConfirmAction {
|
|
85
|
+
action: 'CONFIRM';
|
|
86
|
+
title: string;
|
|
87
|
+
message: string;
|
|
88
|
+
deny_reason?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface NotifyAction {
|
|
92
|
+
action: 'NOTIFY';
|
|
93
|
+
message: string;
|
|
94
|
+
level?: 'info' | 'warning' | 'error';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface ReturnAction {
|
|
98
|
+
action: 'RETURN';
|
|
99
|
+
result: unknown;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface StatusAction {
|
|
103
|
+
action: 'STATUS';
|
|
104
|
+
key: string;
|
|
105
|
+
text?: string; // undefined = clear status
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface SystemPromptAction {
|
|
109
|
+
action: 'SYSTEM_PROMPT';
|
|
110
|
+
systemPrompt: string;
|
|
111
|
+
mode?: 'replace' | 'prefix' | 'suffix';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface InjectMessageAction {
|
|
115
|
+
action: 'INJECT_MESSAGE';
|
|
116
|
+
message: {
|
|
117
|
+
role: 'user' | 'assistant';
|
|
118
|
+
content: string;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export type HubAction =
|
|
123
|
+
| AckAction
|
|
124
|
+
| BlockAction
|
|
125
|
+
| ConfirmAction
|
|
126
|
+
| NotifyAction
|
|
127
|
+
| ReturnAction
|
|
128
|
+
| StatusAction
|
|
129
|
+
| SystemPromptAction
|
|
130
|
+
| InjectMessageAction;
|
|
131
|
+
|
|
132
|
+
// ---- Progress Tracking (Sub-Agent → Parent) ----
|
|
133
|
+
|
|
134
|
+
/** Progress update from a running sub-agent */
|
|
135
|
+
export interface AgentProgressUpdate {
|
|
136
|
+
agentName: string;
|
|
137
|
+
status:
|
|
138
|
+
| 'running'
|
|
139
|
+
| 'tool_start'
|
|
140
|
+
| 'tool_end'
|
|
141
|
+
| 'completed'
|
|
142
|
+
| 'failed'
|
|
143
|
+
| 'thinking_delta'
|
|
144
|
+
| 'text_delta';
|
|
145
|
+
currentTool?: string;
|
|
146
|
+
currentToolArgs?: string;
|
|
147
|
+
elapsed: number;
|
|
148
|
+
tokens?: { input: number; output: number; cost: number };
|
|
149
|
+
delta?: string; // Streaming token delta for thinking_delta / text_delta
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ---- Response Message (Server → Client) ----
|
|
153
|
+
|
|
154
|
+
export interface HubResponse {
|
|
155
|
+
id: string;
|
|
156
|
+
actions: HubAction[];
|
|
157
|
+
}
|