@adhdev/daemon-core 0.9.82-rc.22 → 0.9.82-rc.220

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.
Files changed (277) hide show
  1. package/dist/boot/daemon-lifecycle.d.ts +1 -0
  2. package/dist/boot/process-hardening.d.ts +50 -0
  3. package/dist/chat/source-machine.d.ts +166 -0
  4. package/dist/chat/source-resolver.d.ts +104 -0
  5. package/dist/chat/subscription-updates.d.ts +1 -0
  6. package/dist/cli-adapter-types.d.ts +23 -2
  7. package/dist/cli-adapters/cli-script-runner.d.ts +117 -0
  8. package/dist/cli-adapters/cli-state-engine.d.ts +178 -0
  9. package/dist/cli-adapters/provider-cli-adapter.d.ts +106 -63
  10. package/dist/cli-adapters/provider-cli-parse.d.ts +4 -0
  11. package/dist/cli-adapters/provider-cli-shared.d.ts +29 -0
  12. package/dist/cli-adapters/raw-terminal-io.d.ts +37 -0
  13. package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +3 -3
  14. package/dist/cli-adapters/terminal-backends/types.d.ts +1 -2
  15. package/dist/cli-adapters/terminal-screen.d.ts +2 -11
  16. package/dist/commands/cli-manager.d.ts +2 -1
  17. package/dist/commands/handler.d.ts +110 -0
  18. package/dist/commands/mesh-coordinator.d.ts +85 -1
  19. package/dist/commands/router.d.ts +32 -1
  20. package/dist/config/chat-history.d.ts +9 -0
  21. package/dist/config/config.d.ts +5 -0
  22. package/dist/config/mesh-config.d.ts +72 -1
  23. package/dist/git/git-commands.d.ts +9 -1
  24. package/dist/git/git-diff.d.ts +6 -0
  25. package/dist/git/git-types.d.ts +2 -0
  26. package/dist/index.d.ts +46 -11
  27. package/dist/index.js +36322 -15614
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +36182 -15568
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/installer.d.ts +1 -4
  32. package/dist/ipc/local-ipc-server.d.ts +91 -0
  33. package/dist/launch.d.ts +1 -1
  34. package/dist/logging/async-batch-writer.d.ts +10 -0
  35. package/dist/mesh/contracts.d.ts +164 -0
  36. package/dist/mesh/coordinator-prompt.d.ts +36 -0
  37. package/dist/mesh/coordinator-registry.d.ts +59 -0
  38. package/dist/mesh/mesh-active-work.d.ts +90 -0
  39. package/dist/mesh/mesh-delivery-policy.d.ts +131 -0
  40. package/dist/mesh/mesh-events-coordinator.d.ts +151 -0
  41. package/dist/mesh/mesh-events-pending.d.ts +33 -0
  42. package/dist/mesh/mesh-events-stale.d.ts +40 -0
  43. package/dist/mesh/mesh-events-utils.d.ts +14 -0
  44. package/dist/mesh/mesh-events.d.ts +5 -40
  45. package/dist/mesh/mesh-fast-forward.d.ts +41 -0
  46. package/dist/mesh/mesh-host-ownership.d.ts +9 -0
  47. package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -3
  48. package/dist/mesh/mesh-ledger.d.ts +77 -1
  49. package/dist/mesh/mesh-missions.d.ts +58 -0
  50. package/dist/mesh/mesh-refine-status.d.ts +26 -0
  51. package/dist/mesh/mesh-review-inbox.d.ts +90 -0
  52. package/dist/mesh/mesh-runtime-store.d.ts +324 -0
  53. package/dist/mesh/mesh-task-stats.d.ts +49 -0
  54. package/dist/mesh/mesh-work-queue.d.ts +137 -6
  55. package/dist/mesh/preview-freshness.d.ts +18 -0
  56. package/dist/mesh/refine-config.d.ts +215 -0
  57. package/dist/mesh/worktree-bootstrap-config.d.ts +135 -0
  58. package/dist/providers/acp-provider-instance.d.ts +2 -0
  59. package/dist/providers/approval-utils.d.ts +13 -0
  60. package/dist/providers/cli-provider-instance.d.ts +39 -3
  61. package/dist/providers/contracts.d.ts +130 -6
  62. package/dist/providers/external-sources.d.ts +71 -0
  63. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
  64. package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
  65. package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
  66. package/dist/providers/native-history/dispatcher.d.ts +27 -0
  67. package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
  68. package/dist/providers/native-history/index.d.ts +13 -0
  69. package/dist/providers/provider-instance-manager.d.ts +12 -0
  70. package/dist/providers/provider-instance.d.ts +13 -1
  71. package/dist/providers/provider-loader.d.ts +26 -4
  72. package/dist/providers/provider-trust.d.ts +31 -0
  73. package/dist/providers/read-chat-contract.d.ts +29 -0
  74. package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
  75. package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +85 -0
  76. package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
  77. package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
  78. package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
  79. package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
  80. package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
  81. package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
  82. package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
  83. package/dist/providers/sdk/v1/index.d.ts +30 -0
  84. package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
  85. package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
  86. package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
  87. package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
  88. package/dist/providers/sdk/v1/types/common/index.d.ts +203 -0
  89. package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
  90. package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
  91. package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
  92. package/dist/providers/spec/adapter.d.ts +52 -0
  93. package/dist/providers/spec/cli-adapter.d.ts +102 -0
  94. package/dist/providers/spec/driver.d.ts +287 -0
  95. package/dist/providers/spec/evaluator.d.ts +70 -0
  96. package/dist/providers/spec/fsm-driver.d.ts +110 -0
  97. package/dist/providers/spec/fsm-evaluator.d.ts +72 -0
  98. package/dist/providers/spec/fsm-loader.d.ts +14 -0
  99. package/dist/providers/spec/fsm-types.d.ts +91 -0
  100. package/dist/providers/spec/loader.d.ts +15 -0
  101. package/dist/providers/spec/native-history-executor.d.ts +41 -0
  102. package/dist/providers/spec/route.d.ts +4 -0
  103. package/dist/providers/spec/schema.gen.d.ts +2039 -0
  104. package/dist/providers/spec/types.d.ts +311 -0
  105. package/dist/providers/transcript-v2.d.ts +176 -0
  106. package/dist/providers/types/interactive-prompt.d.ts +48 -0
  107. package/dist/repo-mesh-types.d.ts +126 -1
  108. package/dist/sessions/registry.d.ts +3 -0
  109. package/dist/shared-types-extra.d.ts +2 -4
  110. package/dist/shared-types.d.ts +42 -1
  111. package/dist/status/normalize.d.ts +1 -1
  112. package/dist/status/normalize.js +1 -0
  113. package/dist/status/normalize.js.map +1 -1
  114. package/dist/status/normalize.mjs +1 -0
  115. package/dist/status/normalize.mjs.map +1 -1
  116. package/dist/status/reporter.d.ts +2 -0
  117. package/dist/status/snapshot.d.ts +1 -0
  118. package/dist/types.d.ts +5 -0
  119. package/package.json +6 -3
  120. package/src/agent-stream/poller.ts +2 -3
  121. package/src/boot/daemon-lifecycle.ts +22 -10
  122. package/src/boot/process-hardening.ts +89 -0
  123. package/src/chat/source-machine.ts +534 -0
  124. package/src/chat/source-resolver.ts +0 -0
  125. package/src/chat/subscription-updates.ts +20 -1
  126. package/src/cli-adapter-types.d.ts +1 -0
  127. package/src/cli-adapter-types.ts +22 -2
  128. package/src/cli-adapters/cli-script-runner.ts +421 -0
  129. package/src/cli-adapters/cli-state-engine.ts +1162 -0
  130. package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
  131. package/src/cli-adapters/provider-cli-adapter.ts +673 -1139
  132. package/src/cli-adapters/provider-cli-parse.d.ts +1 -0
  133. package/src/cli-adapters/provider-cli-parse.ts +13 -0
  134. package/src/cli-adapters/provider-cli-runtime.ts +3 -1
  135. package/src/cli-adapters/provider-cli-shared.d.ts +2 -0
  136. package/src/cli-adapters/provider-cli-shared.ts +59 -11
  137. package/src/cli-adapters/raw-terminal-io.ts +252 -0
  138. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +35 -29
  139. package/src/cli-adapters/terminal-backends/types.ts +1 -3
  140. package/src/cli-adapters/terminal-screen.ts +11 -81
  141. package/src/commands/chat-commands.ts +1787 -60
  142. package/src/commands/cli-manager.ts +283 -14
  143. package/src/commands/handler.ts +809 -2
  144. package/src/commands/mesh-coordinator.ts +332 -122
  145. package/src/commands/router.ts +4369 -558
  146. package/src/config/chat-history.ts +95 -24
  147. package/src/config/config.ts +12 -0
  148. package/src/config/mesh-config.ts +303 -3
  149. package/src/config/recent-activity.ts +8 -2
  150. package/src/daemon/dev-auto-implement.ts +3 -2
  151. package/src/daemon/dev-cli-debug.ts +10 -1
  152. package/src/detection/ide-detector.ts +26 -16
  153. package/src/git/git-commands.ts +42 -12
  154. package/src/git/git-diff.ts +53 -0
  155. package/src/git/git-status.ts +35 -6
  156. package/src/git/git-types.ts +2 -0
  157. package/src/git/git-worktree.ts +8 -1
  158. package/src/index.ts +126 -10
  159. package/src/installer.d.ts +1 -1
  160. package/src/installer.ts +8 -6
  161. package/src/ipc/local-ipc-server.ts +278 -0
  162. package/src/launch.d.ts +1 -1
  163. package/src/launch.ts +37 -28
  164. package/src/logging/async-batch-writer.ts +55 -0
  165. package/src/logging/logger.ts +2 -1
  166. package/src/mesh/contracts.ts +329 -0
  167. package/src/mesh/coordinator-prompt.ts +218 -31
  168. package/src/mesh/coordinator-registry.ts +121 -0
  169. package/src/mesh/mesh-active-work.ts +437 -0
  170. package/src/mesh/mesh-delivery-policy.ts +315 -0
  171. package/src/mesh/mesh-events-coordinator.ts +1447 -0
  172. package/src/mesh/mesh-events-pending.ts +371 -0
  173. package/src/mesh/mesh-events-stale.ts +283 -0
  174. package/src/mesh/mesh-events-utils.ts +166 -0
  175. package/src/mesh/mesh-events.ts +24 -908
  176. package/src/mesh/mesh-fast-forward.ts +438 -0
  177. package/src/mesh/mesh-host-ownership.ts +73 -0
  178. package/src/mesh/mesh-ledger-reconciliation.ts +12 -5
  179. package/src/mesh/mesh-ledger.ts +587 -102
  180. package/src/mesh/mesh-missions.ts +151 -0
  181. package/src/mesh/mesh-refine-status.ts +144 -0
  182. package/src/mesh/mesh-review-inbox.ts +307 -0
  183. package/src/mesh/mesh-runtime-store.ts +1305 -0
  184. package/src/mesh/mesh-task-stats.ts +154 -0
  185. package/src/mesh/mesh-work-queue.ts +490 -166
  186. package/src/mesh/preview-freshness.ts +118 -0
  187. package/src/mesh/refine-config.ts +403 -0
  188. package/src/mesh/worktree-bootstrap-config.ts +326 -0
  189. package/src/providers/acp-provider-instance.ts +15 -1
  190. package/src/providers/approval-utils.d.ts +4 -0
  191. package/src/providers/approval-utils.ts +47 -5
  192. package/src/providers/chat-message-normalization.ts +4 -11
  193. package/src/providers/cli-provider-instance.ts +834 -64
  194. package/src/providers/contracts.d.ts +55 -0
  195. package/src/providers/contracts.ts +141 -6
  196. package/src/providers/external-sources.ts +218 -0
  197. package/src/providers/ide-provider-instance.ts +19 -5
  198. package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
  199. package/src/providers/native-history/claude-cli-transcript.ts +396 -0
  200. package/src/providers/native-history/codex-cli-transcript.ts +479 -0
  201. package/src/providers/native-history/dispatcher.ts +340 -0
  202. package/src/providers/native-history/hermes-cli-transcript.ts +230 -0
  203. package/src/providers/native-history/index.ts +30 -0
  204. package/src/providers/provider-instance-manager.ts +30 -0
  205. package/src/providers/provider-instance.ts +10 -1
  206. package/src/providers/provider-loader.ts +592 -50
  207. package/src/providers/provider-schema.ts +87 -14
  208. package/src/providers/provider-trust.ts +114 -0
  209. package/src/providers/read-chat-contract.ts +76 -16
  210. package/src/providers/sdk/README.md +49 -0
  211. package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
  212. package/src/providers/sdk/v1/builders/cli/detect-status.ts +262 -0
  213. package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
  214. package/src/providers/sdk/v1/builders/cli/parse-approval.ts +250 -0
  215. package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
  216. package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
  217. package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
  218. package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
  219. package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
  220. package/src/providers/sdk/v1/index.ts +152 -0
  221. package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
  222. package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
  223. package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
  224. package/src/providers/sdk/v1/schemas/cli/provider.schema.json +504 -0
  225. package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
  226. package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
  227. package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
  228. package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
  229. package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
  230. package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
  231. package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
  232. package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
  233. package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
  234. package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
  235. package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
  236. package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
  237. package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
  238. package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
  239. package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
  240. package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
  241. package/src/providers/sdk/v1/types/cli/index.ts +365 -0
  242. package/src/providers/sdk/v1/types/common/index.ts +229 -0
  243. package/src/providers/sdk/v1/validators/index.ts +19 -0
  244. package/src/providers/sdk/v1/validators/manifest.ts +110 -0
  245. package/src/providers/sdk/v1/validators/taint.ts +309 -0
  246. package/src/providers/spec/adapter.ts +138 -0
  247. package/src/providers/spec/cli-adapter.ts +674 -0
  248. package/src/providers/spec/driver.ts +1082 -0
  249. package/src/providers/spec/evaluator.ts +604 -0
  250. package/src/providers/spec/fsm-driver.ts +663 -0
  251. package/src/providers/spec/fsm-evaluator.ts +255 -0
  252. package/src/providers/spec/fsm-loader.ts +102 -0
  253. package/src/providers/spec/fsm-types.ts +184 -0
  254. package/src/providers/spec/loader.ts +325 -0
  255. package/src/providers/spec/native-history-executor.ts +939 -0
  256. package/src/providers/spec/route.ts +51 -0
  257. package/src/providers/spec/schema.gen.ts +693 -0
  258. package/src/providers/spec/schema.json +342 -0
  259. package/src/providers/spec/types.ts +365 -0
  260. package/src/providers/transcript-v2.ts +567 -0
  261. package/src/providers/types/interactive-prompt.ts +425 -0
  262. package/src/providers/version-archive.ts +38 -20
  263. package/src/repo-mesh-types.ts +138 -1
  264. package/src/sessions/registry.ts +3 -0
  265. package/src/shared-types-extra.ts +2 -4
  266. package/src/shared-types.ts +45 -1
  267. package/src/status/builders.ts +24 -6
  268. package/src/status/normalize.ts +2 -0
  269. package/src/status/reporter.ts +15 -0
  270. package/src/status/snapshot.ts +84 -25
  271. package/src/system/host-memory.ts +29 -12
  272. package/src/types.ts +5 -0
  273. package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
  274. package/dist/mesh/mesh-sync.d.ts +0 -53
  275. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
  276. package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -97
  277. package/src/mesh/mesh-sync.ts +0 -111
@@ -0,0 +1,287 @@
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;
@@ -0,0 +1,70 @@
1
+ import type { CliSpec, SectionDef, Condition, ExtractTitle, ExtractButtons } from './types.js';
2
+ export interface ResolvedSection {
3
+ id: string;
4
+ fromLine: number;
5
+ toLine: number;
6
+ text: string;
7
+ }
8
+ export interface ModalSnapshot {
9
+ title: string | null;
10
+ buttons: {
11
+ index: number;
12
+ label: string;
13
+ key: string;
14
+ }[];
15
+ }
16
+ export interface VisibleControl {
17
+ id: string;
18
+ label: string;
19
+ actionType: 'send_keys' | 'open_picker' | 'attach_image';
20
+ }
21
+ export interface FiredNotification {
22
+ id: string;
23
+ title: string;
24
+ body: string;
25
+ }
26
+ export interface FiredDelegate {
27
+ id: string;
28
+ task: string;
29
+ }
30
+ export interface TraceEntry {
31
+ kind: 'section' | 'state_match' | 'state_skip' | 'modal' | 'control' | 'notification' | 'delegate';
32
+ text: string;
33
+ }
34
+ export interface SpecEvaluation {
35
+ state: {
36
+ id: string;
37
+ label: string;
38
+ title: string | null;
39
+ };
40
+ modal: ModalSnapshot | null;
41
+ controls: VisibleControl[];
42
+ notifications: FiredNotification[];
43
+ delegates: FiredDelegate[];
44
+ sections: ResolvedSection[];
45
+ trace: TraceEntry[];
46
+ }
47
+ /**
48
+ * Resolve v3 sections{} object into an ordered array of ResolvedSection.
49
+ * Two-pass: first anchor/positional, then apply `until` cross-references.
50
+ */
51
+ export declare function resolveSections(sectionsObj: Record<string, SectionDef>, lines: string[]): ResolvedSection[];
52
+ export declare function sectionText(sections: ResolvedSection[], sectionId: string | undefined, fullScreen: string): string;
53
+ export declare function evaluateCondition(cond: Condition, sections: ResolvedSection[], fullScreen: string, cursor: {
54
+ row: number;
55
+ col: number;
56
+ } | undefined, prevLines: string[] | undefined, trace: TraceEntry[], stateId: string): boolean;
57
+ export declare function extractTitle(rule: ExtractTitle, sections: ResolvedSection[], fullScreen: string): string | null;
58
+ export declare function extractButtonsFromRule(rule: ExtractButtons, hay: string): {
59
+ index: number;
60
+ label: string;
61
+ key: string;
62
+ }[];
63
+ export declare function evaluate(spec: CliSpec, screenText: string,
64
+ /** Optional cursor position (0-based row and col). */
65
+ cursor?: {
66
+ row: number;
67
+ col: number;
68
+ },
69
+ /** Optional previous screen lines for `changed` condition detection. */
70
+ prevLines?: string[]): SpecEvaluation;
@@ -0,0 +1,110 @@
1
+ import { type TransitionEval } from './fsm-evaluator.js';
2
+ import { type DashboardEvent, type DashboardCommand, type SpecDriverOpts, type ISpecDriver, type DriverHistoryEntry } from './driver.js';
3
+ type HistoryEntry = DriverHistoryEntry;
4
+ export declare class FsmDriver implements ISpecDriver {
5
+ private readonly opts;
6
+ private spec;
7
+ private adapter;
8
+ private listeners;
9
+ private currentStateId;
10
+ private stateEnteredAt;
11
+ private startedAtMs;
12
+ private prevScreenLines;
13
+ /** Per cursor_above region (key: cursor_above, -1 = whole screen) → last
14
+ * time that region's content changed. Drives stable_ms conditions. */
15
+ private regionLastChangedAt;
16
+ /** Timer that re-runs evaluate() when a time-condition would flip true
17
+ * with no PTY frame to trigger it. */
18
+ private wakeTimer;
19
+ private currentEval;
20
+ private stateHistory;
21
+ private prevStateAt;
22
+ private readySeenOnce;
23
+ private pendingSends;
24
+ private pickerInProgress;
25
+ private delegateTimers;
26
+ private specWatcher;
27
+ /** Last full FSM evaluation, kept for the debugger. */
28
+ private lastFsmEval;
29
+ constructor(opts: SpecDriverOpts);
30
+ subscribe(listener: (ev: DashboardEvent) => void): () => void;
31
+ start(): void;
32
+ dispatch(cmd: DashboardCommand): void;
33
+ snapshot(): string;
34
+ getCursorPosition(): {
35
+ row: number;
36
+ col: number;
37
+ };
38
+ getScreen(): string;
39
+ getSpecPath(): string;
40
+ shutdown(): void;
41
+ getFsmDebug(): {
42
+ currentState: string;
43
+ label: string;
44
+ stateAgeMs: number;
45
+ status: string;
46
+ cursor: {
47
+ row: number;
48
+ col: number;
49
+ };
50
+ transitions: TransitionEval[];
51
+ };
52
+ getStateHistory(): ReadonlyArray<HistoryEntry>;
53
+ getSections(): Array<{
54
+ id: string;
55
+ text: string;
56
+ }> | null;
57
+ /** v3-compat shims so the cli-adapter's existing debug snapshot keeps
58
+ * working without branching on driver type. */
59
+ getLastBusyAt(): number;
60
+ hasIdleHoldPending(): boolean;
61
+ getCompletionIdleDebounceState(): {
62
+ active: boolean;
63
+ ageMs: number;
64
+ holdMs: number;
65
+ forceAfterMs: number;
66
+ } | null;
67
+ private loadSpecOrThrow;
68
+ private buildAdapterOpts;
69
+ private armSpecWatcher;
70
+ private emitInitialState;
71
+ private buildClock;
72
+ private evalFsmNow;
73
+ private reevaluate;
74
+ private commitTransition;
75
+ /** Re-derive the visible modal + controls for the current state and emit a
76
+ * state_changed if anything differs from the last emit. */
77
+ private emitStateChanged;
78
+ private deriveModal;
79
+ private deriveTitle;
80
+ private deriveControls;
81
+ /** Track which cursor_above regions changed since the previous frame so
82
+ * stable_ms conditions can measure quiet time. We record every region
83
+ * size referenced by a stable_ms condition in the spec, plus the whole
84
+ * screen (-1). */
85
+ private trackRegionChanges;
86
+ /** All cursor_above region sizes referenced by stable_ms conditions in the
87
+ * current state's outgoing transitions, plus whole-screen. Cached lazily
88
+ * per spec load would be nicer but the set is tiny. */
89
+ private stableRegionSizes;
90
+ /** Schedule a re-evaluation for the soonest pending time-condition on any
91
+ * outgoing transition (elapsed_ms / stable_ms / min_hold_ms). Without
92
+ * this, a state whose only exit is time-based would never leave once the
93
+ * PTY goes quiet. */
94
+ private scheduleWakeForState;
95
+ private maybeMarkReady;
96
+ private fireNotifications;
97
+ private armOrCancelDelegateTimers;
98
+ private fireDelegate;
99
+ private handleSendMessage;
100
+ private actuallySendMessage;
101
+ private handleClickControl;
102
+ private handleClickModalButton;
103
+ private handleAttachImage;
104
+ private tryAdvancePicker;
105
+ private handleExit;
106
+ private pushHistory;
107
+ private specTag;
108
+ private emit;
109
+ }
110
+ export {};
@@ -0,0 +1,72 @@
1
+ import type { SectionDef } from './types.js';
2
+ import { type ResolvedSection, type TraceEntry } from './evaluator.js';
3
+ import { type CliSpecV4, type FsmCondition } from './fsm-types.js';
4
+ export interface FsmClock {
5
+ /** Wall-clock now (ms). Passed in so the evaluator stays pure. */
6
+ now: number;
7
+ /** When the current state was entered (ms). */
8
+ stateEnteredAt: number;
9
+ /** Last-changed timestamp per cursor_above region. Key = cursor_above
10
+ * value (0 / undefined → whole-screen, keyed as -1). Missing key means
11
+ * "never observed changing" → treated as stable since stateEnteredAt. */
12
+ regionLastChangedAt: Map<number, number>;
13
+ }
14
+ /** Per-condition evaluation detail — the debugging payload. */
15
+ export interface CondResult {
16
+ kind: 'regex' | 'changed' | 'elapsed' | 'stable' | 'all' | 'any' | 'not';
17
+ result: boolean;
18
+ detail: string;
19
+ /** Remaining ms until a time-based condition would flip to true. 0 if
20
+ * already true or not applicable. Lets the UI show a countdown. */
21
+ remainingMs?: number;
22
+ children?: CondResult[];
23
+ }
24
+ /** One evaluated transition with its full reasoning. */
25
+ export interface TransitionEval {
26
+ to: string;
27
+ label: string;
28
+ /** Did the `from` clause include the current state? (Always true for the
29
+ * transitions we return — kept for completeness.) */
30
+ eligible: boolean;
31
+ /** min_hold_ms guard satisfied? */
32
+ holdSatisfied: boolean;
33
+ holdRemainingMs: number;
34
+ /** Guard condition result (true if no `when`). */
35
+ condResult: boolean;
36
+ cond?: CondResult;
37
+ /** Overall: would this transition fire? */
38
+ fires: boolean;
39
+ priority: number;
40
+ }
41
+ export interface FsmEvaluation {
42
+ /** Sections resolved from the screen (shared with v3 shape). */
43
+ sections: ResolvedSection[];
44
+ /** Every outgoing transition from the current state, priority-ordered,
45
+ * each annotated with why it fired or didn't. */
46
+ transitions: TransitionEval[];
47
+ /** The transition that fires (first in priority order with fires===true),
48
+ * or null to stay in the current state. */
49
+ fired: TransitionEval | null;
50
+ /** v3-compatible trace lines for the legacy inspector. */
51
+ trace: TraceEntry[];
52
+ }
53
+ /**
54
+ * Evaluate the FSM: given the current state id and screen, return every
55
+ * outgoing transition annotated with why it fires/doesn't, plus the one that
56
+ * fires (if any).
57
+ */
58
+ export declare function evaluateFsm(spec: CliSpecV4, currentStateId: string, screenText: string, cursor: {
59
+ row: number;
60
+ col: number;
61
+ } | undefined, prevLines: string[] | undefined, clock: FsmClock): FsmEvaluation;
62
+ /**
63
+ * Evaluate a single condition against a screen + section map — for the spec
64
+ * editor's live preview ("does this regex match the current screen right
65
+ * now?"). Time leaves (elapsed_ms/stable_ms) are evaluated against a synthetic
66
+ * clock where the state was just entered, so they report their countdown
67
+ * rather than firing; the preview is about screen-content match, not timing.
68
+ */
69
+ export declare function evaluateConditionPreview(cond: FsmCondition, sections: Record<string, SectionDef> | undefined, screenText: string, cursor?: {
70
+ row: number;
71
+ col: number;
72
+ }): CondResult;
@@ -0,0 +1,14 @@
1
+ import { type CliSpecV4 } from './fsm-types.js';
2
+ export interface FsmLoadOk {
3
+ ok: true;
4
+ spec: CliSpecV4;
5
+ sourcePath: string;
6
+ }
7
+ export interface FsmLoadErr {
8
+ ok: false;
9
+ errors: string[];
10
+ sourcePath: string;
11
+ }
12
+ export declare function loadFsmSpec(sourcePath: string): FsmLoadOk | FsmLoadErr;
13
+ /** Pure validator — usable from a "validate before save" API in the panel. */
14
+ export declare function validateFsmSpec(raw: unknown): string[];
@@ -0,0 +1,91 @@
1
+ import type { RegexCondition, ChangedCondition, Control, NotificationRule, DelegateTrigger, NativeHistoryConfig, SectionDef, ExtractTitle, ExtractButtons } from './types.js';
2
+ /** True once `ms` have elapsed since the current state was entered. */
3
+ export interface ElapsedCondition {
4
+ elapsed_ms: number;
5
+ }
6
+ /** True once the region `cursor_above` lines above the cursor has been
7
+ * unchanged for `ms`. A stability gate — the inverse of a busy signal. */
8
+ export interface StableCondition {
9
+ stable_ms: number;
10
+ /** Lines above the cursor that must be stable. Default: whole screen. */
11
+ cursor_above?: number;
12
+ }
13
+ export interface FsmAllCondition {
14
+ all: FsmCondition[];
15
+ }
16
+ export interface FsmAnyCondition {
17
+ any: FsmCondition[];
18
+ }
19
+ /** Negation — true when the inner condition is false. Lets a transition say
20
+ * "go busy unless the completion marker is present", etc. */
21
+ export interface FsmNotCondition {
22
+ not: FsmCondition;
23
+ }
24
+ export type FsmCondition = RegexCondition | ChangedCondition | ElapsedCondition | StableCondition | FsmAllCondition | FsmAnyCondition | FsmNotCondition;
25
+ export interface FsmState {
26
+ id: string;
27
+ label: string;
28
+ /** Exactly one state must be `initial: true` — the state at spawn. */
29
+ initial?: boolean;
30
+ /** Modal states (approval/picker) expose modal buttons in the UI and are
31
+ * treated as "interesting" — the dashboard surfaces them distinctly. */
32
+ modal?: boolean;
33
+ /** Status this state maps to for the dashboard/cli-adapter status field.
34
+ * One of: idle | generating | approval. Defaults: modal→approval,
35
+ * initial→idle, id==='busy'→generating, else idle. Explicit wins. */
36
+ status?: 'idle' | 'generating' | 'approval';
37
+ /** Optional extraction run whenever this state is the committed state —
38
+ * used by modal states to surface a title + buttons. */
39
+ extract?: {
40
+ title?: ExtractTitle;
41
+ buttons?: ExtractButtons;
42
+ };
43
+ }
44
+ export interface FsmTransition {
45
+ /** Source state id, or list of source ids, or "*" for any state. */
46
+ from: string | string[];
47
+ /** Destination state id. */
48
+ to: string;
49
+ /** Guard condition. Omitted → always eligible (only gated by `from` +
50
+ * min_hold_ms). Evaluated against the current screen + clock. */
51
+ when?: FsmCondition;
52
+ /** Minimum time the machine must have been in `from` before this edge can
53
+ * fire. Replaces busy_hold_ms / idle_hold_ms (per-edge, not global). */
54
+ min_hold_ms?: number;
55
+ /** Higher priority transitions are evaluated first. Default 0. Ties broken
56
+ * by declaration order. */
57
+ priority?: number;
58
+ /** Human label for the debugger. */
59
+ label?: string;
60
+ }
61
+ export interface CliSpecV4 {
62
+ $schema: 'adhdev:cli/spec@4';
63
+ id: string;
64
+ name: string;
65
+ binary: string;
66
+ spawn_args?: string[];
67
+ env?: Record<string, string>;
68
+ cli_version_range?: string;
69
+ send_message: {
70
+ submit_key: string;
71
+ delay_ms_before_submit?: number;
72
+ delay_ms_per_char?: number;
73
+ };
74
+ sections: Record<string, SectionDef>;
75
+ states: FsmState[];
76
+ transitions: FsmTransition[];
77
+ control_bar?: Control[];
78
+ notifications?: NotificationRule[];
79
+ delegate?: DelegateTrigger[];
80
+ native_history?: NativeHistoryConfig;
81
+ requiresFinalAssistantBeforeIdle?: boolean;
82
+ }
83
+ export declare function isV4Spec(raw: unknown): raw is CliSpecV4;
84
+ export declare function initialState(spec: CliSpecV4): FsmState;
85
+ export declare function stateById(spec: CliSpecV4, id: string): FsmState | undefined;
86
+ /** Outgoing transitions from `stateId`, highest priority first, declaration
87
+ * order as tiebreak. Includes wildcard ("*") and list-membership sources. */
88
+ export declare function outgoingTransitions(spec: CliSpecV4, stateId: string): FsmTransition[];
89
+ /** Map a state to the dashboard status string, applying the documented
90
+ * defaults when `status` is not explicit. */
91
+ export declare function statusForState(state: FsmState): 'idle' | 'generating' | 'approval';
@@ -0,0 +1,15 @@
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;