@adhdev/daemon-core 0.9.82-rc.220 → 0.9.82-rc.221
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/dist/index.d.ts +7 -6
- package/dist/index.js +844 -2657
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +839 -2650
- package/dist/index.mjs.map +1 -1
- package/dist/providers/spec/evaluator.d.ts +1 -48
- package/dist/providers/spec/fsm-driver.d.ts +122 -1
- package/dist/providers/spec/types.d.ts +7 -189
- package/package.json +1 -1
- package/src/index.ts +9 -8
- package/src/providers/provider-loader.ts +3 -11
- package/src/providers/spec/cli-adapter.ts +10 -38
- package/src/providers/spec/evaluator.ts +9 -292
- package/src/providers/spec/fsm-driver.ts +92 -6
- package/src/providers/spec/types.ts +24 -216
- package/dist/providers/spec/driver.d.ts +0 -287
- package/dist/providers/spec/loader.d.ts +0 -15
- package/dist/providers/spec/schema.gen.d.ts +0 -2039
- package/src/providers/spec/driver.ts +0 -1082
- package/src/providers/spec/loader.ts +0 -325
- package/src/providers/spec/schema.gen.ts +0 -693
- package/src/providers/spec/schema.json +0 -342
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Keep in sync with schema.gen.ts.
|
|
2
|
+
* Shared types for the adhdev:cli/spec@4 FSM spec system.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
* v3
|
|
7
|
-
*
|
|
8
|
-
* The loader auto-migrates v1 → v3. Callers receive a CliSpec (v3) after
|
|
9
|
-
* loadSpec; the v1 raw shape is only used during migration.
|
|
4
|
+
* These are the building blocks reused by fsm-types.ts, evaluator.ts, and
|
|
5
|
+
* the rest of the spec stack. v3/v1 types have been removed — all providers
|
|
6
|
+
* are on v4.
|
|
10
7
|
*/
|
|
11
8
|
'use strict';
|
|
12
9
|
|
|
13
10
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
14
|
-
// Shared /
|
|
11
|
+
// Shared / layout types
|
|
15
12
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
16
13
|
|
|
17
14
|
export type Size = number | string;
|
|
@@ -22,12 +19,19 @@ export interface SectionPattern {
|
|
|
22
19
|
flags?: string;
|
|
23
20
|
}
|
|
24
21
|
|
|
22
|
+
/** Inline wait_for shape used by open_picker control actions. */
|
|
23
|
+
export interface WaitForCondition {
|
|
24
|
+
section?: string;
|
|
25
|
+
regex?: string;
|
|
26
|
+
flags?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
25
29
|
export type ControlAction =
|
|
26
30
|
| { type: 'send_keys'; keys: string }
|
|
27
31
|
| {
|
|
28
32
|
type: 'open_picker';
|
|
29
33
|
trigger_keys: string;
|
|
30
|
-
wait_for:
|
|
34
|
+
wait_for: WaitForCondition;
|
|
31
35
|
extract_choices: SectionPattern;
|
|
32
36
|
submit_key: string;
|
|
33
37
|
}
|
|
@@ -58,15 +62,6 @@ export interface DelegateTrigger {
|
|
|
58
62
|
task_template: string;
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
/**
|
|
62
|
-
* Native history config — three modes, picked by which fields are present:
|
|
63
|
-
*
|
|
64
|
-
* 1. `reader`: built-in reader id (claude-cli / codex-cli / antigravity-cli / hermes-cli).
|
|
65
|
-
*
|
|
66
|
-
* 2. `source`: declarative source descriptor.
|
|
67
|
-
*
|
|
68
|
-
* 3. `override_path`: relative path to a provider-supplied reader module.
|
|
69
|
-
*/
|
|
70
65
|
export interface NativeHistoryConfig {
|
|
71
66
|
reader?: 'claude-cli' | 'codex-cli' | 'antigravity-cli' | 'hermes-cli';
|
|
72
67
|
source?: NativeHistorySource;
|
|
@@ -106,21 +101,20 @@ export interface NativeHistoryMessageMap {
|
|
|
106
101
|
}
|
|
107
102
|
|
|
108
103
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
109
|
-
//
|
|
104
|
+
// Section definition
|
|
110
105
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
111
106
|
|
|
112
|
-
export interface
|
|
113
|
-
id: string;
|
|
107
|
+
export interface SectionDef {
|
|
114
108
|
from_top?: Size;
|
|
115
109
|
from_bottom?: Size;
|
|
116
|
-
until?:
|
|
117
|
-
|
|
110
|
+
until?: string; // section id OR regex (starts with ^)
|
|
111
|
+
anchor?: string;
|
|
118
112
|
anchor_flags?: string;
|
|
119
113
|
anchor_last?: boolean;
|
|
120
114
|
anchor_context?: {
|
|
121
115
|
prev?: string;
|
|
122
|
-
prev_flags?: string;
|
|
123
116
|
next?: string;
|
|
117
|
+
prev_flags?: string;
|
|
124
118
|
next_flags?: string;
|
|
125
119
|
};
|
|
126
120
|
lines?: number;
|
|
@@ -128,63 +122,13 @@ export interface Section {
|
|
|
128
122
|
until_regex_flags?: string;
|
|
129
123
|
}
|
|
130
124
|
|
|
131
|
-
/** v1 condition — flat SectionRegex object. Also used in control_bar.wait_for. */
|
|
132
|
-
export interface SectionRegex {
|
|
133
|
-
section?: string;
|
|
134
|
-
regex?: string;
|
|
135
|
-
flags?: string;
|
|
136
|
-
cursor_row_min?: number;
|
|
137
|
-
cursor_row_max?: number;
|
|
138
|
-
cursor_col_min?: number;
|
|
139
|
-
cursor_col_max?: number;
|
|
140
|
-
/** v1 delta detection (cursor_above_lines + changed). */
|
|
141
|
-
cursor_above_lines?: number;
|
|
142
|
-
/** Required when cursor_above_lines is set. */
|
|
143
|
-
changed?: true;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export interface ModalButtonsRule {
|
|
147
|
-
section?: string;
|
|
148
|
-
pattern?: string;
|
|
149
|
-
flags?: string;
|
|
150
|
-
patterns?: Array<{ pattern: string; flags?: string }>;
|
|
151
|
-
key_for_index: string;
|
|
152
|
-
min_count?: number;
|
|
153
|
-
continuation_lines?: boolean;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
125
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
157
|
-
//
|
|
126
|
+
// Conditions (shared with fsm-types.ts FsmCondition leaves)
|
|
158
127
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
159
128
|
|
|
160
|
-
/**
|
|
161
|
-
* v3 section definition — keyed by id in `sections{}` object.
|
|
162
|
-
* `until` is EITHER a section-id string (no `^` prefix) OR a regex string (starts with `^`).
|
|
163
|
-
*/
|
|
164
|
-
export interface SectionDef {
|
|
165
|
-
// positional
|
|
166
|
-
from_top?: Size;
|
|
167
|
-
from_bottom?: Size;
|
|
168
|
-
until?: string; // section id OR regex (starts with ^)
|
|
169
|
-
// anchor-based
|
|
170
|
-
anchor?: string; // regex (replaces anchor_regex)
|
|
171
|
-
anchor_flags?: string;
|
|
172
|
-
anchor_last?: boolean;
|
|
173
|
-
anchor_context?: {
|
|
174
|
-
prev?: string;
|
|
175
|
-
next?: string;
|
|
176
|
-
prev_flags?: string;
|
|
177
|
-
next_flags?: string;
|
|
178
|
-
};
|
|
179
|
-
lines?: number;
|
|
180
|
-
until_regex?: string; // kept for anchor-based extension
|
|
181
|
-
until_regex_flags?: string;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/** v3 regex condition against a section (or full screen). */
|
|
185
129
|
export interface RegexCondition {
|
|
186
130
|
section?: string;
|
|
187
|
-
matches: string;
|
|
131
|
+
matches: string;
|
|
188
132
|
flags?: string;
|
|
189
133
|
cursor_row_min?: number;
|
|
190
134
|
cursor_row_max?: number;
|
|
@@ -192,28 +136,26 @@ export interface RegexCondition {
|
|
|
192
136
|
cursor_col_max?: number;
|
|
193
137
|
}
|
|
194
138
|
|
|
195
|
-
/** v3 delta condition: N lines above cursor changed vs prevLines.
|
|
196
|
-
* changed:false + stable_ms: region must be stable for at least N ms. */
|
|
197
139
|
export interface ChangedCondition {
|
|
198
140
|
cursor_above: number;
|
|
199
141
|
changed: boolean;
|
|
200
|
-
/** Only for changed:false — region must have been stable for this many ms. */
|
|
201
142
|
stable_ms?: number;
|
|
202
143
|
}
|
|
203
144
|
|
|
204
|
-
/** v3 AND composite. */
|
|
205
145
|
export interface AllCondition {
|
|
206
146
|
all: Condition[];
|
|
207
147
|
}
|
|
208
148
|
|
|
209
|
-
/** v3 OR composite. */
|
|
210
149
|
export interface AnyCondition {
|
|
211
150
|
any: Condition[];
|
|
212
151
|
}
|
|
213
152
|
|
|
214
153
|
export type Condition = RegexCondition | ChangedCondition | AllCondition | AnyCondition;
|
|
215
154
|
|
|
216
|
-
|
|
155
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
156
|
+
// Extraction helpers
|
|
157
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
158
|
+
|
|
217
159
|
export interface ExtractTitle {
|
|
218
160
|
section?: string;
|
|
219
161
|
regex?: string;
|
|
@@ -221,7 +163,6 @@ export interface ExtractTitle {
|
|
|
221
163
|
first_line?: true;
|
|
222
164
|
}
|
|
223
165
|
|
|
224
|
-
/** v3 extract_buttons config. */
|
|
225
166
|
export interface ExtractButtons {
|
|
226
167
|
section?: string;
|
|
227
168
|
pattern: string;
|
|
@@ -230,136 +171,3 @@ export interface ExtractButtons {
|
|
|
230
171
|
min_count?: number;
|
|
231
172
|
continuation_lines?: boolean;
|
|
232
173
|
}
|
|
233
|
-
|
|
234
|
-
/** v3 state. */
|
|
235
|
-
export interface SpecStateV3 {
|
|
236
|
-
id: string;
|
|
237
|
-
label: string;
|
|
238
|
-
when: AllCondition | AnyCondition;
|
|
239
|
-
extract?: {
|
|
240
|
-
title?: ExtractTitle;
|
|
241
|
-
buttons?: ExtractButtons;
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
246
|
-
// CliSpec — v3 (the canonical runtime type after loading)
|
|
247
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
248
|
-
|
|
249
|
-
export interface CliSpec {
|
|
250
|
-
$schema: 'adhdev:cli/spec@3';
|
|
251
|
-
id: string;
|
|
252
|
-
name: string;
|
|
253
|
-
binary: string;
|
|
254
|
-
spawn_args?: string[];
|
|
255
|
-
env?: Record<string, string>;
|
|
256
|
-
cli_version_range?: string;
|
|
257
|
-
send_message: {
|
|
258
|
-
submit_key: string;
|
|
259
|
-
delay_ms_before_submit?: number;
|
|
260
|
-
delay_ms_per_char?: number;
|
|
261
|
-
};
|
|
262
|
-
sections: Record<string, SectionDef>;
|
|
263
|
-
states: SpecStateV3[];
|
|
264
|
-
default_state: string;
|
|
265
|
-
control_bar?: Control[];
|
|
266
|
-
notifications?: NotificationRule[];
|
|
267
|
-
delegate?: DelegateTrigger[];
|
|
268
|
-
native_history?: NativeHistoryConfig;
|
|
269
|
-
requiresFinalAssistantBeforeIdle?: boolean;
|
|
270
|
-
/**
|
|
271
|
-
* Per-spec timing knobs. Replaces v1 `debounce`.
|
|
272
|
-
* Also accessible via the legacy `debounce` alias in the driver for
|
|
273
|
-
* backward compat with older callers.
|
|
274
|
-
*/
|
|
275
|
-
timing?: {
|
|
276
|
-
busy_hold_ms?: number;
|
|
277
|
-
idle_hold_ms?: number;
|
|
278
|
-
startup_grace_ms?: number;
|
|
279
|
-
/** Suppress idle downshift while the screen is actively changing.
|
|
280
|
-
* When set, any PTY frame that changes the screen resets a timer;
|
|
281
|
-
* idle transitions (busy_hold expiry and completion_idle_after) are
|
|
282
|
-
* blocked until the screen has been stable for this many ms. */
|
|
283
|
-
screen_active_hold_ms?: number;
|
|
284
|
-
completion_marker?: {
|
|
285
|
-
section?: string;
|
|
286
|
-
matches: string;
|
|
287
|
-
flags?: string;
|
|
288
|
-
hold_ms: number;
|
|
289
|
-
force_after_ms?: number;
|
|
290
|
-
};
|
|
291
|
-
};
|
|
292
|
-
/**
|
|
293
|
-
* Legacy alias: v1 callers (tests, tooling) may read `debounce`.
|
|
294
|
-
* The loader populates both `timing` and `debounce` pointing at the
|
|
295
|
-
* same object so callers that use either field see consistent values.
|
|
296
|
-
* @deprecated Use `timing` instead.
|
|
297
|
-
*/
|
|
298
|
-
debounce?: {
|
|
299
|
-
busy_hold_ms?: number;
|
|
300
|
-
idle_hold_ms?: number;
|
|
301
|
-
startup_grace_ms?: number;
|
|
302
|
-
screen_active_hold_ms?: number;
|
|
303
|
-
/**
|
|
304
|
-
* Legacy field name for completion_marker. Populated by the loader
|
|
305
|
-
* from `timing.completion_marker` for backward compat.
|
|
306
|
-
*/
|
|
307
|
-
completion_idle_after?: {
|
|
308
|
-
section?: string;
|
|
309
|
-
regex: string;
|
|
310
|
-
flags?: string;
|
|
311
|
-
hold_ms: number;
|
|
312
|
-
force_after_ms?: number;
|
|
313
|
-
};
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
318
|
-
// v1 CliSpec raw shape (for migration only — not exported as the primary type)
|
|
319
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
320
|
-
|
|
321
|
-
/** Raw v1 spec shape as loaded from JSON. Used only in migrateV1toV3. */
|
|
322
|
-
export interface RawCliSpecV1 {
|
|
323
|
-
$schema: 'adhdev:cli/spec@1';
|
|
324
|
-
id: string;
|
|
325
|
-
name: string;
|
|
326
|
-
binary: string;
|
|
327
|
-
spawn_args?: string[];
|
|
328
|
-
env?: Record<string, string>;
|
|
329
|
-
cli_version_range?: string;
|
|
330
|
-
send_message: {
|
|
331
|
-
submit_key: string;
|
|
332
|
-
delay_ms_before_submit?: number;
|
|
333
|
-
delay_ms_per_char?: number;
|
|
334
|
-
};
|
|
335
|
-
layout: { sections: Section[] };
|
|
336
|
-
states: Array<{
|
|
337
|
-
id: string;
|
|
338
|
-
label: string;
|
|
339
|
-
when: SectionRegex;
|
|
340
|
-
extract_title?: SectionRegex;
|
|
341
|
-
modal_buttons?: ModalButtonsRule;
|
|
342
|
-
}>;
|
|
343
|
-
default_state: string;
|
|
344
|
-
control_bar?: Control[];
|
|
345
|
-
notifications?: NotificationRule[];
|
|
346
|
-
delegate?: DelegateTrigger[];
|
|
347
|
-
native_history?: NativeHistoryConfig;
|
|
348
|
-
requiresFinalAssistantBeforeIdle?: boolean;
|
|
349
|
-
debounce?: {
|
|
350
|
-
busy_hold_ms?: number;
|
|
351
|
-
idle_hold_ms?: number;
|
|
352
|
-
startup_grace_ms?: number;
|
|
353
|
-
completion_idle_after?: {
|
|
354
|
-
section?: string;
|
|
355
|
-
regex: string;
|
|
356
|
-
flags?: string;
|
|
357
|
-
hold_ms: number;
|
|
358
|
-
force_after_ms?: number;
|
|
359
|
-
};
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// Keep SpecState as alias for backward compat with cli-adapter.ts and other code
|
|
364
|
-
// that imports SpecState from types.ts. In v3 we use SpecStateV3.
|
|
365
|
-
export type SpecState = SpecStateV3;
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import type { PtyTransportFactory } from '../../cli-adapters/pty-transport.js';
|
|
2
|
-
import { type SpecEvaluation, type TraceEntry } from './evaluator.js';
|
|
3
|
-
import type { CliSpec } from './types.js';
|
|
4
|
-
export type DashboardEvent = {
|
|
5
|
-
kind: 'pty_data';
|
|
6
|
-
chunk: string;
|
|
7
|
-
} | {
|
|
8
|
-
kind: 'state_changed';
|
|
9
|
-
state: {
|
|
10
|
-
id: string;
|
|
11
|
-
label: string;
|
|
12
|
-
title: string | null;
|
|
13
|
-
};
|
|
14
|
-
modal: {
|
|
15
|
-
title: string | null;
|
|
16
|
-
buttons: {
|
|
17
|
-
index: number;
|
|
18
|
-
label: string;
|
|
19
|
-
}[];
|
|
20
|
-
} | null;
|
|
21
|
-
controls: {
|
|
22
|
-
id: string;
|
|
23
|
-
label: string;
|
|
24
|
-
action_type: string;
|
|
25
|
-
}[];
|
|
26
|
-
} | {
|
|
27
|
-
kind: 'notification';
|
|
28
|
-
id: string;
|
|
29
|
-
title: string;
|
|
30
|
-
body: string;
|
|
31
|
-
} | {
|
|
32
|
-
kind: 'delegate';
|
|
33
|
-
id: string;
|
|
34
|
-
task: string;
|
|
35
|
-
} | {
|
|
36
|
-
kind: 'spec_trace';
|
|
37
|
-
entries: TraceEntry[];
|
|
38
|
-
} | {
|
|
39
|
-
kind: 'exit';
|
|
40
|
-
exit_code: number;
|
|
41
|
-
} | {
|
|
42
|
-
kind: 'spec_error';
|
|
43
|
-
errors: string[];
|
|
44
|
-
};
|
|
45
|
-
export type DashboardCommand = {
|
|
46
|
-
kind: 'send_message';
|
|
47
|
-
text: string;
|
|
48
|
-
} | {
|
|
49
|
-
kind: 'pty_write';
|
|
50
|
-
data: string;
|
|
51
|
-
} | {
|
|
52
|
-
kind: 'click_control';
|
|
53
|
-
control_id: string;
|
|
54
|
-
payload?: unknown;
|
|
55
|
-
} | {
|
|
56
|
-
kind: 'click_modal_button';
|
|
57
|
-
index: number;
|
|
58
|
-
} | {
|
|
59
|
-
kind: 'attach_image';
|
|
60
|
-
blob: string;
|
|
61
|
-
mime: string;
|
|
62
|
-
} | {
|
|
63
|
-
kind: 'resize';
|
|
64
|
-
cols: number;
|
|
65
|
-
rows: number;
|
|
66
|
-
} | {
|
|
67
|
-
kind: 'cancel';
|
|
68
|
-
} | {
|
|
69
|
-
kind: 'shutdown';
|
|
70
|
-
};
|
|
71
|
-
/** One state-history entry — the union of fields produced by the v3 SpecDriver
|
|
72
|
-
* (debounce-based) and the v4 FsmDriver (transition-based). The cli-adapter
|
|
73
|
-
* and debug panel read this shape from either driver. */
|
|
74
|
-
export interface DriverHistoryEntry {
|
|
75
|
-
stateId: string;
|
|
76
|
-
label: string;
|
|
77
|
-
at: number;
|
|
78
|
-
durationMs: number;
|
|
79
|
-
reason: string;
|
|
80
|
-
matchedStateId?: string;
|
|
81
|
-
matchedRules?: string[];
|
|
82
|
-
debounceKind?: string;
|
|
83
|
-
idleHoldMs?: number;
|
|
84
|
-
busyHoldMs?: number;
|
|
85
|
-
/** v4: the transition that fired, e.g. "idle→busy". */
|
|
86
|
-
via?: string;
|
|
87
|
-
}
|
|
88
|
-
/** The surface the cli-adapter drives. Implemented by both SpecDriver (v3,
|
|
89
|
-
* debounce) and FsmDriver (v4, FSM). Lets the adapter hold either without
|
|
90
|
-
* branching on the concrete type. */
|
|
91
|
-
export interface ISpecDriver {
|
|
92
|
-
subscribe(listener: (ev: DashboardEvent) => void): () => void;
|
|
93
|
-
start(): void;
|
|
94
|
-
dispatch(cmd: DashboardCommand): void;
|
|
95
|
-
snapshot(): string;
|
|
96
|
-
getCursorPosition(): {
|
|
97
|
-
row: number;
|
|
98
|
-
col: number;
|
|
99
|
-
};
|
|
100
|
-
getScreen(): string;
|
|
101
|
-
getSpecPath(): string;
|
|
102
|
-
shutdown(): void;
|
|
103
|
-
getStateHistory(): ReadonlyArray<DriverHistoryEntry>;
|
|
104
|
-
getSections(): Array<{
|
|
105
|
-
id: string;
|
|
106
|
-
text: string;
|
|
107
|
-
}> | null;
|
|
108
|
-
getLastBusyAt(): number;
|
|
109
|
-
hasIdleHoldPending(): boolean;
|
|
110
|
-
getCompletionIdleDebounceState(): {
|
|
111
|
-
active: boolean;
|
|
112
|
-
ageMs: number;
|
|
113
|
-
holdMs: number;
|
|
114
|
-
forceAfterMs: number;
|
|
115
|
-
} | null;
|
|
116
|
-
/** v4 only — present on FsmDriver. Returns the live transition table. */
|
|
117
|
-
getFsmDebug?(): unknown;
|
|
118
|
-
}
|
|
119
|
-
export interface SpecDriverOpts {
|
|
120
|
-
specPath: string;
|
|
121
|
-
workingDir: string;
|
|
122
|
-
extraEnv?: Record<string, string>;
|
|
123
|
-
cols?: number;
|
|
124
|
-
rows?: number;
|
|
125
|
-
/** Set false to skip the spec.json fs.watch. */
|
|
126
|
-
hotReload?: boolean;
|
|
127
|
-
/** Set true to forward trace entries on every state_changed. */
|
|
128
|
-
emitTrace?: boolean;
|
|
129
|
-
/** Inject the daemon's PTY transport (typically SessionHostPtyTransportFactory). */
|
|
130
|
-
transportFactory?: PtyTransportFactory;
|
|
131
|
-
/**
|
|
132
|
-
* Extra CLI args appended to spec.spawn_args. Used by the daemon to
|
|
133
|
-
* pass per-launch arguments like `--session-id <uuid>` so the agent
|
|
134
|
-
* uses the daemon's providerSessionId instead of generating its own.
|
|
135
|
-
*/
|
|
136
|
-
extraCliArgs?: string[];
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Pick the effective delay (ms) to wait between writing the prompt body and
|
|
140
|
-
* writing the submit_key. Exported for tests; production callers go through
|
|
141
|
-
* actuallySendMessage. Floors to SUBMIT_DELAY_FLOOR_MS so specs that omit
|
|
142
|
-
* delay_ms_before_submit (e.g. claude, antigravity) still get baseline
|
|
143
|
-
* protection against the paste→submit race. Adds line-count bonus so
|
|
144
|
-
* multi-line prompts get more settling time on TUIs that re-render per
|
|
145
|
-
* embedded `\n`.
|
|
146
|
-
*/
|
|
147
|
-
export declare function resolveSubmitDelayMs(specBeforeSubmit: number | undefined, text: string): number;
|
|
148
|
-
export declare function matchesCompletionIdleRule(spec: CliSpec, ev: SpecEvaluation, screen: string): string | null;
|
|
149
|
-
export declare function matchesCompletionIdleTargetState(spec: CliSpec, ev: SpecEvaluation, screen: string, cursor?: {
|
|
150
|
-
row: number;
|
|
151
|
-
col: number;
|
|
152
|
-
}): boolean;
|
|
153
|
-
export declare class SpecDriver implements ISpecDriver {
|
|
154
|
-
private readonly opts;
|
|
155
|
-
private spec;
|
|
156
|
-
private adapter;
|
|
157
|
-
private listeners;
|
|
158
|
-
private currentStateId;
|
|
159
|
-
/** Have we ever seen the spec's idle state *after* the startup grace
|
|
160
|
-
* window? Until we do, the agent's startup banner may still be
|
|
161
|
-
* painting and any send_message we forward to the PTY will be wiped
|
|
162
|
-
* when the banner clears the screen. Queue + drain on first valid
|
|
163
|
-
* idle. */
|
|
164
|
-
private idleSeenOnce;
|
|
165
|
-
private startedAtMs;
|
|
166
|
-
private pendingSends;
|
|
167
|
-
private currentEval;
|
|
168
|
-
private pickerInProgress;
|
|
169
|
-
private delegateTimers;
|
|
170
|
-
/** Timestamp of the last time the evaluator returned busy. Used to debounce
|
|
171
|
-
* the busy → idle transition (see reevaluate). */
|
|
172
|
-
private lastBusyAt;
|
|
173
|
-
/** The exact busy state object we last saw — held alongside lastBusyAt so
|
|
174
|
-
* the hold can re-emit the same { id: 'busy', label, title } payload the
|
|
175
|
-
* dashboard already learned about. currentEval can't fill this role
|
|
176
|
-
* because the evaluator already moved past busy by the time the hold
|
|
177
|
-
* kicks in. */
|
|
178
|
-
private lastBusyState;
|
|
179
|
-
/** Timestamp of the last time we entered a modal state (approval/picker or
|
|
180
|
-
* any non-busy non-idle state). Used to suppress brief busy blips that
|
|
181
|
-
* appear while the modal is still on screen — Claude Code streams body
|
|
182
|
-
* text that transiently shows a spinner even while an approval modal is
|
|
183
|
-
* visible, causing rapid approval→busy→approval flicker on the dashboard. */
|
|
184
|
-
private lastModalAt;
|
|
185
|
-
/** The modal state snapshot held across busy blips. */
|
|
186
|
-
private lastModalState;
|
|
187
|
-
/** Timestamp of when we last *exited* a modal state (approval/picker → idle
|
|
188
|
-
* or directly via completion_idle_after). Used to suppress completion_idle_after
|
|
189
|
-
* firings that were queued before the modal appeared and expire immediately
|
|
190
|
-
* after the modal is dismissed — without this the agent appears idle even
|
|
191
|
-
* though it is still generating. */
|
|
192
|
-
private lastModalExitAt;
|
|
193
|
-
private completionIdleFirstSeenAt;
|
|
194
|
-
private completionIdleKey;
|
|
195
|
-
/** Previous screen lines — passed to evaluate() for `changed` condition detection. */
|
|
196
|
-
private prevScreenLines;
|
|
197
|
-
/** Timestamp when idle was last committed (either direct or via idle_hold_ms).
|
|
198
|
-
* Used to suppress immediate idle → busy re-entry from transient `changed`
|
|
199
|
-
* condition blips (e.g. completion-marker counter "Completed for Xs" updating
|
|
200
|
-
* every second, which triggers cursor_above:changed and bounces back to busy
|
|
201
|
-
* right after an idle commit). */
|
|
202
|
-
private lastIdleCommittedAt;
|
|
203
|
-
/** Timestamp of the last PTY frame that changed the screen content.
|
|
204
|
-
* Used by screen_active_hold_ms to suppress idle downshifts while
|
|
205
|
-
* the terminal is still actively updating. */
|
|
206
|
-
private lastScreenChangedAt;
|
|
207
|
-
/** Per-cursor_above region last-changed timestamps for stable_ms tracking.
|
|
208
|
-
* Key: cursor_above value. Value: last time that region changed. */
|
|
209
|
-
private regionLastChangedAt;
|
|
210
|
-
/** Timer that re-runs evaluate() once the hold window expires. Needed
|
|
211
|
-
* because the PTY stops emitting once the agent finishes; without an
|
|
212
|
-
* explicit wake-up there's nothing to trigger the busy → idle
|
|
213
|
-
* downshift. */
|
|
214
|
-
private busyExpiryTimer;
|
|
215
|
-
/** Set true while reevaluate() is invoked from busyExpiryTimer callback. */
|
|
216
|
-
private busyExpiryFired;
|
|
217
|
-
/** Pending idle-commit timer. Armed when the evaluator first returns idle;
|
|
218
|
-
* fires after idle_hold_ms if no non-idle reading has cancelled it. */
|
|
219
|
-
private idleHoldTimer;
|
|
220
|
-
/** State snapshot captured when the idle hold was armed — emitted on commit. */
|
|
221
|
-
private pendingIdleState;
|
|
222
|
-
private specWatcher;
|
|
223
|
-
/** Ring buffer of committed state transitions (max 50). */
|
|
224
|
-
private stateHistory;
|
|
225
|
-
private prevStateAt;
|
|
226
|
-
constructor(opts: SpecDriverOpts);
|
|
227
|
-
/** Subscribe to outbound events. Returns an unsubscribe fn. */
|
|
228
|
-
subscribe(listener: (ev: DashboardEvent) => void): () => void;
|
|
229
|
-
start(): void;
|
|
230
|
-
dispatch(cmd: DashboardCommand): void;
|
|
231
|
-
snapshot(): string;
|
|
232
|
-
getCursorPosition(): {
|
|
233
|
-
row: number;
|
|
234
|
-
col: number;
|
|
235
|
-
};
|
|
236
|
-
shutdown(): void;
|
|
237
|
-
private cancelIdleHold;
|
|
238
|
-
private pushHistory;
|
|
239
|
-
getStateHistory(): ReadonlyArray<{
|
|
240
|
-
stateId: string;
|
|
241
|
-
label: string;
|
|
242
|
-
at: number;
|
|
243
|
-
durationMs: number;
|
|
244
|
-
reason: string;
|
|
245
|
-
matchedStateId?: string;
|
|
246
|
-
matchedRules?: string[];
|
|
247
|
-
debounceKind?: string;
|
|
248
|
-
idleHoldMs?: number;
|
|
249
|
-
busyHoldMs?: number;
|
|
250
|
-
}>;
|
|
251
|
-
getLastBusyAt(): number;
|
|
252
|
-
hasIdleHoldPending(): boolean;
|
|
253
|
-
getSpecPath(): string;
|
|
254
|
-
getCompletionIdleDebounceState(): {
|
|
255
|
-
active: boolean;
|
|
256
|
-
ageMs: number;
|
|
257
|
-
holdMs: number;
|
|
258
|
-
forceAfterMs: number;
|
|
259
|
-
} | null;
|
|
260
|
-
getScreen(): string;
|
|
261
|
-
getSections(): Array<{
|
|
262
|
-
id: string;
|
|
263
|
-
text: string;
|
|
264
|
-
}> | null;
|
|
265
|
-
private loadSpecOrThrow;
|
|
266
|
-
private buildAdapterOpts;
|
|
267
|
-
private armSpecWatcher;
|
|
268
|
-
private emitInitialState;
|
|
269
|
-
/** Re-arm the timer that wakes the driver up after BUSY_HOLD_MS so it
|
|
270
|
-
* can decide whether to downshift to idle. Always uses the most recent
|
|
271
|
-
* hold value so a spec hot-reload that shortens the hold takes effect
|
|
272
|
-
* on the next busy entry. Safe to call repeatedly; only the last call
|
|
273
|
-
* fires. */
|
|
274
|
-
private scheduleBusyExpiry;
|
|
275
|
-
private reevaluate;
|
|
276
|
-
private armOrCancelDelegateTimers;
|
|
277
|
-
private fireDelegate;
|
|
278
|
-
private handleSendMessage;
|
|
279
|
-
private actuallySendMessage;
|
|
280
|
-
private handleClickControl;
|
|
281
|
-
private handleClickModalButton;
|
|
282
|
-
private handleAttachImage;
|
|
283
|
-
private tryAdvancePicker;
|
|
284
|
-
private handleExit;
|
|
285
|
-
private emit;
|
|
286
|
-
}
|
|
287
|
-
export declare function guessExt(mime: string): string;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { CliSpec } from './types.js';
|
|
2
|
-
export interface SpecLoadResult {
|
|
3
|
-
ok: true;
|
|
4
|
-
spec: CliSpec;
|
|
5
|
-
sourcePath: string;
|
|
6
|
-
}
|
|
7
|
-
export interface SpecLoadError {
|
|
8
|
-
ok: false;
|
|
9
|
-
errors: string[];
|
|
10
|
-
sourcePath: string;
|
|
11
|
-
}
|
|
12
|
-
export declare function loadSpec(sourcePath: string): SpecLoadResult | SpecLoadError;
|
|
13
|
-
export declare function migrateV1toV3(raw: any): any;
|
|
14
|
-
/** Convenience: look up a provider's spec.json next to its provider dir. */
|
|
15
|
-
export declare function resolveSpecPath(providerDir: string): string;
|