@adhdev/daemon-core 0.9.82-rc.35 → 0.9.82-rc.350

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 (318) hide show
  1. package/dist/boot/daemon-lifecycle.d.ts +8 -0
  2. package/dist/boot/process-hardening.d.ts +50 -0
  3. package/dist/build-info.d.ts +37 -0
  4. package/dist/chat/source-machine.d.ts +166 -0
  5. package/dist/chat/source-resolver.d.ts +104 -0
  6. package/dist/chat/subscription-updates.d.ts +1 -0
  7. package/dist/cli-adapter-types.d.ts +46 -2
  8. package/dist/cli-adapters/cli-script-runner.d.ts +117 -0
  9. package/dist/cli-adapters/cli-state-engine.d.ts +198 -0
  10. package/dist/cli-adapters/provider-cli-adapter.d.ts +116 -64
  11. package/dist/cli-adapters/provider-cli-parse.d.ts +4 -0
  12. package/dist/cli-adapters/provider-cli-runtime.d.ts +34 -0
  13. package/dist/cli-adapters/provider-cli-shared.d.ts +53 -0
  14. package/dist/cli-adapters/raw-terminal-io.d.ts +37 -0
  15. package/dist/cli-adapters/resolve-executable.d.ts +14 -0
  16. package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +6 -3
  17. package/dist/cli-adapters/terminal-backends/types.d.ts +10 -2
  18. package/dist/cli-adapters/terminal-screen.d.ts +4 -11
  19. package/dist/commands/cli-manager.d.ts +2 -1
  20. package/dist/commands/handler.d.ts +110 -0
  21. package/dist/commands/mesh-coordinator.d.ts +85 -1
  22. package/dist/commands/router.d.ts +324 -1
  23. package/dist/commands/upgrade-helper.d.ts +12 -0
  24. package/dist/config/chat-history.d.ts +9 -0
  25. package/dist/config/config.d.ts +5 -0
  26. package/dist/config/mesh-config.d.ts +77 -1
  27. package/dist/detection/ide-detector.d.ts +13 -0
  28. package/dist/detection/win32-ide-version.d.ts +37 -0
  29. package/dist/git/change-impact-config.d.ts +159 -0
  30. package/dist/git/git-commands.d.ts +11 -1
  31. package/dist/git/git-diff.d.ts +6 -0
  32. package/dist/git/git-executor.d.ts +11 -0
  33. package/dist/git/git-status.d.ts +23 -0
  34. package/dist/git/git-types.d.ts +2 -50
  35. package/dist/git/index.d.ts +2 -0
  36. package/dist/index.d.ts +52 -13
  37. package/dist/index.js +39739 -14302
  38. package/dist/index.js.map +1 -1
  39. package/dist/index.mjs +41369 -16055
  40. package/dist/index.mjs.map +1 -1
  41. package/dist/installer.d.ts +1 -4
  42. package/dist/ipc/local-ipc-server.d.ts +91 -0
  43. package/dist/launch.d.ts +1 -1
  44. package/dist/logging/async-batch-writer.d.ts +10 -0
  45. package/dist/logging/log-redactor.d.ts +24 -0
  46. package/dist/logging/log-tail-reader.d.ts +46 -0
  47. package/dist/mesh/contracts.d.ts +164 -0
  48. package/dist/mesh/coordinator-prompt.d.ts +36 -0
  49. package/dist/mesh/coordinator-registry.d.ts +59 -0
  50. package/dist/mesh/mesh-active-work.d.ts +174 -0
  51. package/dist/mesh/mesh-delivery-policy.d.ts +131 -0
  52. package/dist/mesh/mesh-events-coordinator.d.ts +169 -0
  53. package/dist/mesh/mesh-events-pending.d.ts +55 -0
  54. package/dist/mesh/mesh-events-stale.d.ts +40 -0
  55. package/dist/mesh/mesh-events-utils.d.ts +62 -0
  56. package/dist/mesh/mesh-events.d.ts +6 -49
  57. package/dist/mesh/mesh-fast-forward.d.ts +81 -0
  58. package/dist/mesh/mesh-host-ownership.d.ts +9 -0
  59. package/dist/mesh/mesh-init.d.ts +86 -0
  60. package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -3
  61. package/dist/mesh/mesh-ledger.d.ts +77 -1
  62. package/dist/mesh/mesh-missions.d.ts +164 -0
  63. package/dist/mesh/mesh-reconcile-loop.d.ts +7 -0
  64. package/dist/mesh/mesh-refine-batch.d.ts +68 -0
  65. package/dist/mesh/mesh-refine-status.d.ts +62 -0
  66. package/dist/mesh/mesh-review-inbox.d.ts +90 -0
  67. package/dist/mesh/mesh-routing.d.ts +70 -0
  68. package/dist/mesh/mesh-runtime-store.d.ts +419 -0
  69. package/dist/mesh/mesh-task-stats.d.ts +49 -0
  70. package/dist/mesh/mesh-unresolved-forward-outbox.d.ts +30 -0
  71. package/dist/mesh/mesh-work-queue.d.ts +218 -5
  72. package/dist/mesh/preview-freshness.d.ts +18 -0
  73. package/dist/mesh/refine-config.d.ts +216 -0
  74. package/dist/mesh/worktree-bootstrap-config.d.ts +135 -0
  75. package/dist/providers/acp-provider-instance.d.ts +2 -0
  76. package/dist/providers/approval-utils.d.ts +13 -0
  77. package/dist/providers/chat-message-normalization.d.ts +12 -0
  78. package/dist/providers/cli-provider-instance.d.ts +77 -3
  79. package/dist/providers/contracts.d.ts +139 -6
  80. package/dist/providers/external-sources.d.ts +71 -0
  81. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
  82. package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
  83. package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
  84. package/dist/providers/native-history/dispatcher.d.ts +27 -0
  85. package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
  86. package/dist/providers/native-history/index.d.ts +13 -0
  87. package/dist/providers/provider-instance-manager.d.ts +14 -0
  88. package/dist/providers/provider-instance.d.ts +15 -1
  89. package/dist/providers/provider-loader.d.ts +26 -4
  90. package/dist/providers/provider-trust.d.ts +31 -0
  91. package/dist/providers/read-chat-contract.d.ts +29 -0
  92. package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
  93. package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +85 -0
  94. package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
  95. package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
  96. package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
  97. package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
  98. package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
  99. package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
  100. package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
  101. package/dist/providers/sdk/v1/index.d.ts +30 -0
  102. package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
  103. package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
  104. package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
  105. package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
  106. package/dist/providers/sdk/v1/types/common/index.d.ts +203 -0
  107. package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
  108. package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
  109. package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
  110. package/dist/providers/spec/adapter.d.ts +69 -0
  111. package/dist/providers/spec/cli-adapter.d.ts +217 -0
  112. package/dist/providers/spec/evaluator.d.ts +23 -0
  113. package/dist/providers/spec/fsm-driver.d.ts +322 -0
  114. package/dist/providers/spec/fsm-evaluator.d.ts +72 -0
  115. package/dist/providers/spec/fsm-loader.d.ts +14 -0
  116. package/dist/providers/spec/fsm-types.d.ts +144 -0
  117. package/dist/providers/spec/native-history-executor.d.ts +41 -0
  118. package/dist/providers/spec/pre-launch-trust.d.ts +16 -0
  119. package/dist/providers/spec/route.d.ts +4 -0
  120. package/dist/providers/spec/types.d.ts +180 -0
  121. package/dist/providers/status-monitor.d.ts +7 -7
  122. package/dist/providers/transcript-v2.d.ts +176 -0
  123. package/dist/providers/types/interactive-prompt.d.ts +84 -0
  124. package/dist/providers/working-dir.d.ts +17 -0
  125. package/dist/repo-mesh-types.d.ts +295 -13
  126. package/dist/sessions/registry.d.ts +6 -0
  127. package/dist/shared-types-extra.d.ts +2 -4
  128. package/dist/shared-types.d.ts +59 -2
  129. package/dist/status/normalize.d.ts +1 -1
  130. package/dist/status/normalize.js +1 -0
  131. package/dist/status/normalize.js.map +1 -1
  132. package/dist/status/normalize.mjs +1 -0
  133. package/dist/status/normalize.mjs.map +1 -1
  134. package/dist/status/reporter.d.ts +2 -0
  135. package/dist/status/snapshot.d.ts +26 -0
  136. package/dist/system/load-better-sqlite3.d.ts +21 -0
  137. package/dist/types.d.ts +5 -0
  138. package/package.json +7 -3
  139. package/src/agent-stream/poller.ts +2 -3
  140. package/src/agent-stream/provider-adapter.ts +1 -1
  141. package/src/boot/daemon-lifecycle.ts +55 -12
  142. package/src/boot/process-hardening.ts +89 -0
  143. package/src/build-info.ts +73 -0
  144. package/src/chat/source-machine.ts +534 -0
  145. package/src/chat/source-resolver.ts +0 -0
  146. package/src/chat/subscription-updates.ts +20 -1
  147. package/src/cli-adapter-types.d.ts +1 -0
  148. package/src/cli-adapter-types.ts +47 -2
  149. package/src/cli-adapters/cli-script-runner.ts +421 -0
  150. package/src/cli-adapters/cli-state-engine.ts +1215 -0
  151. package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
  152. package/src/cli-adapters/provider-cli-adapter.ts +774 -1141
  153. package/src/cli-adapters/provider-cli-parse.d.ts +1 -0
  154. package/src/cli-adapters/provider-cli-parse.ts +13 -0
  155. package/src/cli-adapters/provider-cli-runtime.ts +56 -7
  156. package/src/cli-adapters/provider-cli-shared.d.ts +4 -0
  157. package/src/cli-adapters/provider-cli-shared.ts +100 -11
  158. package/src/cli-adapters/pty-transport.ts +2 -1
  159. package/src/cli-adapters/raw-terminal-io.ts +252 -0
  160. package/src/cli-adapters/resolve-executable.ts +90 -0
  161. package/src/cli-adapters/session-host-transport.ts +2 -1
  162. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +53 -29
  163. package/src/cli-adapters/terminal-backends/types.ts +10 -3
  164. package/src/cli-adapters/terminal-screen.ts +16 -81
  165. package/src/commands/chat-commands.ts +1823 -62
  166. package/src/commands/cli-manager.ts +304 -14
  167. package/src/commands/handler.ts +809 -2
  168. package/src/commands/mesh-coordinator.ts +332 -122
  169. package/src/commands/router.ts +7505 -1311
  170. package/src/commands/stream-commands.ts +8 -0
  171. package/src/commands/upgrade-helper.ts +81 -30
  172. package/src/config/chat-history.ts +483 -24
  173. package/src/config/config.ts +12 -0
  174. package/src/config/mesh-config.ts +388 -6
  175. package/src/config/recent-activity.ts +8 -2
  176. package/src/daemon/dev-auto-implement.ts +3 -2
  177. package/src/daemon/dev-cli-debug.ts +10 -1
  178. package/src/detection/cli-detector.ts +28 -9
  179. package/src/detection/ide-detector.ts +55 -16
  180. package/src/detection/win32-ide-version.ts +106 -0
  181. package/src/git/change-impact-config.ts +354 -0
  182. package/src/git/git-commands.ts +55 -14
  183. package/src/git/git-diff.ts +53 -0
  184. package/src/git/git-executor.ts +12 -0
  185. package/src/git/git-status.ts +574 -43
  186. package/src/git/git-types.ts +14 -62
  187. package/src/git/git-worktree.ts +8 -1
  188. package/src/git/index.ts +16 -0
  189. package/src/index.ts +146 -12
  190. package/src/installer.d.ts +1 -1
  191. package/src/installer.ts +8 -6
  192. package/src/ipc/local-ipc-server.ts +278 -0
  193. package/src/launch.d.ts +1 -1
  194. package/src/launch.ts +37 -28
  195. package/src/logging/async-batch-writer.ts +55 -0
  196. package/src/logging/log-redactor.ts +100 -0
  197. package/src/logging/log-tail-reader.ts +220 -0
  198. package/src/logging/logger.ts +2 -1
  199. package/src/mesh/contracts.ts +329 -0
  200. package/src/mesh/coordinator-prompt.ts +234 -31
  201. package/src/mesh/coordinator-registry.ts +121 -0
  202. package/src/mesh/mesh-active-work.ts +623 -0
  203. package/src/mesh/mesh-delivery-policy.ts +315 -0
  204. package/src/mesh/mesh-events-coordinator.ts +2224 -0
  205. package/src/mesh/mesh-events-pending.ts +558 -0
  206. package/src/mesh/mesh-events-stale.ts +290 -0
  207. package/src/mesh/mesh-events-utils.ts +381 -0
  208. package/src/mesh/mesh-events.ts +30 -1035
  209. package/src/mesh/mesh-fast-forward.ts +839 -0
  210. package/src/mesh/mesh-host-ownership.ts +73 -0
  211. package/src/mesh/mesh-init.ts +260 -0
  212. package/src/mesh/mesh-ledger-reconciliation.ts +12 -5
  213. package/src/mesh/mesh-ledger.ts +590 -102
  214. package/src/mesh/mesh-missions.ts +322 -0
  215. package/src/mesh/mesh-reconcile-loop.ts +989 -0
  216. package/src/mesh/mesh-refine-batch.ts +197 -0
  217. package/src/mesh/mesh-refine-status.ts +231 -0
  218. package/src/mesh/mesh-review-inbox.ts +307 -0
  219. package/src/mesh/mesh-routing.ts +291 -0
  220. package/src/mesh/mesh-runtime-store.ts +1660 -0
  221. package/src/mesh/mesh-task-stats.ts +154 -0
  222. package/src/mesh/mesh-unresolved-forward-outbox.ts +185 -0
  223. package/src/mesh/mesh-work-queue.ts +901 -141
  224. package/src/mesh/preview-freshness.ts +118 -0
  225. package/src/mesh/refine-config.ts +423 -0
  226. package/src/mesh/worktree-bootstrap-config.ts +331 -0
  227. package/src/providers/acp-provider-instance.ts +25 -9
  228. package/src/providers/approval-utils.d.ts +4 -0
  229. package/src/providers/approval-utils.ts +47 -5
  230. package/src/providers/chat-message-normalization.ts +45 -5
  231. package/src/providers/cli-provider-instance.ts +1041 -99
  232. package/src/providers/contracts.d.ts +55 -0
  233. package/src/providers/contracts.ts +150 -6
  234. package/src/providers/extension-provider-instance.ts +12 -7
  235. package/src/providers/external-sources.ts +218 -0
  236. package/src/providers/ide-provider-instance.ts +35 -12
  237. package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
  238. package/src/providers/native-history/claude-cli-transcript.ts +396 -0
  239. package/src/providers/native-history/codex-cli-transcript.ts +479 -0
  240. package/src/providers/native-history/dispatcher.ts +340 -0
  241. package/src/providers/native-history/hermes-cli-transcript.ts +230 -0
  242. package/src/providers/native-history/index.ts +30 -0
  243. package/src/providers/provider-instance-manager.ts +30 -0
  244. package/src/providers/provider-instance.ts +10 -1
  245. package/src/providers/provider-loader.ts +670 -50
  246. package/src/providers/provider-schema.ts +87 -14
  247. package/src/providers/provider-trust.ts +114 -0
  248. package/src/providers/read-chat-contract.ts +76 -16
  249. package/src/providers/sdk/README.md +49 -0
  250. package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
  251. package/src/providers/sdk/v1/builders/cli/detect-status.ts +262 -0
  252. package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
  253. package/src/providers/sdk/v1/builders/cli/parse-approval.ts +250 -0
  254. package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
  255. package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
  256. package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
  257. package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
  258. package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
  259. package/src/providers/sdk/v1/index.ts +152 -0
  260. package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
  261. package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
  262. package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
  263. package/src/providers/sdk/v1/schemas/cli/provider.schema.json +504 -0
  264. package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
  265. package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
  266. package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
  267. package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
  268. package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
  269. package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
  270. package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
  271. package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
  272. package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
  273. package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
  274. package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
  275. package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
  276. package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
  277. package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
  278. package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
  279. package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
  280. package/src/providers/sdk/v1/types/cli/index.ts +365 -0
  281. package/src/providers/sdk/v1/types/common/index.ts +229 -0
  282. package/src/providers/sdk/v1/validators/index.ts +19 -0
  283. package/src/providers/sdk/v1/validators/manifest.ts +110 -0
  284. package/src/providers/sdk/v1/validators/taint.ts +309 -0
  285. package/src/providers/spec/adapter.ts +168 -0
  286. package/src/providers/spec/cli-adapter.ts +986 -0
  287. package/src/providers/spec/evaluator.ts +345 -0
  288. package/src/providers/spec/fsm-driver.ts +1065 -0
  289. package/src/providers/spec/fsm-evaluator.ts +255 -0
  290. package/src/providers/spec/fsm-loader.ts +120 -0
  291. package/src/providers/spec/fsm-types.ts +238 -0
  292. package/src/providers/spec/native-history-executor.ts +1136 -0
  293. package/src/providers/spec/pre-launch-trust.ts +104 -0
  294. package/src/providers/spec/route.ts +51 -0
  295. package/src/providers/spec/types.ts +226 -0
  296. package/src/providers/status-monitor.d.ts +7 -7
  297. package/src/providers/status-monitor.ts +37 -22
  298. package/src/providers/transcript-v2.ts +567 -0
  299. package/src/providers/types/interactive-prompt.ts +536 -0
  300. package/src/providers/version-archive.ts +64 -24
  301. package/src/providers/working-dir.ts +23 -0
  302. package/src/repo-mesh-types.ts +378 -14
  303. package/src/sessions/registry.ts +6 -0
  304. package/src/shared-types-extra.ts +2 -4
  305. package/src/shared-types.d.ts +8 -0
  306. package/src/shared-types.ts +64 -1
  307. package/src/status/builders.ts +26 -6
  308. package/src/status/normalize.ts +2 -0
  309. package/src/status/reporter.ts +19 -1
  310. package/src/status/snapshot.ts +95 -26
  311. package/src/system/host-memory.ts +29 -12
  312. package/src/system/load-better-sqlite3.ts +68 -0
  313. package/src/types.ts +5 -0
  314. package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
  315. package/dist/mesh/mesh-sync.d.ts +0 -53
  316. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
  317. package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -97
  318. package/src/mesh/mesh-sync.ts +0 -111
@@ -0,0 +1,276 @@
1
+ /**
2
+ * buildParseSessionFromTui — synthesize a parseSession function from the
3
+ * manifest tui block alone.
4
+ *
5
+ * Composition:
6
+ * 1. detectStatus from tui.spinner/modal/settledPrompt/dispatchOrder
7
+ * (delegated to buildDetectStatusFromTui)
8
+ * 2. parseApproval from tui.modal (delegated to buildParseApprovalFromTui)
9
+ * 3. message extraction from tui.transcriptPty (this file)
10
+ *
11
+ * The result has the same shape as the legacy parse_output:
12
+ * { status, messages, activeModal, transcriptAuthority?, coverage?, providerSessionId? }
13
+ *
14
+ * Identity stamping (providerUnitKey, bubbleId, sequence, bubbleState) is
15
+ * applied by the caller, mirroring _shared/parse_session.js. We export the
16
+ * stamper as `normalizeMessageIdentity` for reuse.
17
+ */
18
+
19
+ import { buildDetectStatusFromTui, type DetectStatusTuiSpec } from './detect-status.js'
20
+ import { buildParseApprovalFromTui, type ModalTuiSpec } from './parse-approval.js'
21
+ import * as crypto from 'node:crypto'
22
+
23
+ // ─── Schema types ────────────────────────────────
24
+
25
+ export interface PrefixSpec {
26
+ regex: string
27
+ flags?: string
28
+ }
29
+
30
+ export interface ToolPrefixSpec extends PrefixSpec {
31
+ skip?: boolean
32
+ }
33
+
34
+ export interface ChromePatternSpec {
35
+ regex: string
36
+ flags?: string
37
+ label?: string
38
+ }
39
+
40
+ export interface TranscriptPtySpec {
41
+ $schema?: 'adhdev:tui/transcript-pty@1'
42
+ assistantPrefix: PrefixSpec
43
+ userPrefix?: PrefixSpec
44
+ toolPrefix?: ToolPrefixSpec
45
+ continuationLine?: { indented?: boolean }
46
+ chromePatterns?: ChromePatternSpec[]
47
+ stripLeadingChrome?: boolean
48
+ scope?: 'screen' | 'buffer' | 'tail'
49
+ }
50
+
51
+ export interface SessionIdExtractionSpec {
52
+ $schema?: 'adhdev:tui/session-id-extraction@1'
53
+ regex: string
54
+ flags?: string
55
+ scope?: 'screen' | 'tail' | 'buffer'
56
+ label?: string
57
+ }
58
+
59
+ export interface ParseSessionTuiSpec {
60
+ spinner?: any
61
+ settledPrompt?: any
62
+ modal?: ModalTuiSpec
63
+ dispatchOrder?: any
64
+ transcriptPty: TranscriptPtySpec
65
+ sessionIdExtraction?: SessionIdExtractionSpec
66
+ }
67
+
68
+ // ─── Output shape ────────────────────────────────
69
+
70
+ export interface SynthesizedMessage {
71
+ role: 'user' | 'assistant'
72
+ kind?: 'standard' | 'tool'
73
+ content: string
74
+ receivedAt?: number
75
+ }
76
+
77
+ export interface SynthesizedSession {
78
+ status: string | null
79
+ messages: SynthesizedMessage[]
80
+ activeModal: { message: string; buttons: string[] } | null
81
+ modal: { message: string; buttons: string[] } | null
82
+ parsedStatus: string | null
83
+ transcriptAuthority?: 'provider' | 'daemon'
84
+ coverage?: 'full' | 'tail' | 'current-turn'
85
+ providerSessionId?: string
86
+ }
87
+
88
+ // ─── ANSI / line helpers ─────────────────────────
89
+
90
+ const ANSI_RE = /\x1b\[[0-?]*[ -/]*[@-~]/g
91
+ const OSC_RE = /\x1b\][^\x07\x1b\n]*(?:\x07|\x1b\\|(?=\n|$))/g
92
+
93
+ function stripAnsi(text: string): string {
94
+ return String(text || '')
95
+ .replace(/\x1b\[(\d*)C/g, (_m, n) => ' '.repeat(Math.max(1, Number(n) || 1)))
96
+ .replace(/\x1b\[\d*D/g, '')
97
+ .replace(ANSI_RE, '')
98
+ .replace(OSC_RE, '')
99
+ .replace(/\x1b[P^_X][\s\S]*?(?:\x07|\x1b\\)/g, '')
100
+ .replace(/\x1b(?:[@-Z\\-_])/g, '')
101
+ }
102
+
103
+ function splitLines(text: string): string[] {
104
+ return stripAnsi(text)
105
+ .replace(//g, '')
106
+ .split(/\r?\n/)
107
+ .map(l => l.replace(/\s+$/, ''))
108
+ }
109
+
110
+ function pickInputText(input: any, scope: TranscriptPtySpec['scope']): string {
111
+ if (!input) return ''
112
+ if (scope === 'screen') return String(input.screenText || input.screen?.text || '')
113
+ if (scope === 'tail') return String(input.tail || input.recentBuffer || input.buffer || '')
114
+ return String(input.buffer || input.rawBuffer || input.screenText || '')
115
+ }
116
+
117
+ // ─── Identity stamping (mirrors _shared/parse_session.js) ─────
118
+
119
+ function stableHash(value: string): string {
120
+ return crypto.createHash('sha1').update(String(value || '')).digest('hex').slice(0, 12)
121
+ }
122
+
123
+ export function normalizeMessageIdentity<T extends { role?: string; kind?: string; content?: string }>(
124
+ messages: T[],
125
+ status: string,
126
+ ): Array<T & {
127
+ providerUnitKey: string
128
+ bubbleId: string
129
+ sequence: number
130
+ _turnKey: string
131
+ bubbleState: 'streaming' | 'final'
132
+ }> {
133
+ const list = Array.isArray(messages) ? messages : []
134
+ let turnIndex = -1
135
+ return list.map((message, index) => {
136
+ const role = message?.role || 'assistant'
137
+ const kind = message?.kind || 'standard'
138
+ const content = typeof message?.content === 'string' ? message.content : ''
139
+ if (role === 'user' || turnIndex < 0) turnIndex += 1
140
+ const seed = [role, kind, '', index, content].join('\n')
141
+ const providerUnitKey = `v2-pty:${role}:${kind}:${index}:${stableHash(seed)}`
142
+ const bubbleId = `bubble:${providerUnitKey}`
143
+ const turnKey = `turn:${turnIndex}`
144
+ const isStreamingTail = status === 'generating' && role === 'assistant' && index === list.length - 1
145
+ return {
146
+ ...message,
147
+ providerUnitKey,
148
+ bubbleId,
149
+ sequence: index,
150
+ _turnKey: turnKey,
151
+ bubbleState: isStreamingTail ? 'streaming' as const : 'final' as const,
152
+ }
153
+ })
154
+ }
155
+
156
+ // ─── Main builder ────────────────────────────────
157
+
158
+ export function buildParseSessionFromTui(spec: ParseSessionTuiSpec): (input: any) => SynthesizedSession {
159
+ if (!spec.transcriptPty) {
160
+ throw new Error('buildParseSessionFromTui: spec.transcriptPty is required')
161
+ }
162
+
163
+ // Compile regexes once
164
+ const assistantRe = new RegExp(spec.transcriptPty.assistantPrefix.regex, spec.transcriptPty.assistantPrefix.flags || '')
165
+ const userRe = spec.transcriptPty.userPrefix
166
+ ? new RegExp(spec.transcriptPty.userPrefix.regex, spec.transcriptPty.userPrefix.flags || '')
167
+ : null
168
+ const toolRe = spec.transcriptPty.toolPrefix
169
+ ? new RegExp(spec.transcriptPty.toolPrefix.regex, spec.transcriptPty.toolPrefix.flags || '')
170
+ : null
171
+ const toolSkip = spec.transcriptPty.toolPrefix?.skip ?? false
172
+ const chromeRes = (spec.transcriptPty.chromePatterns || []).map(p =>
173
+ new RegExp(p.regex, p.flags || ''))
174
+ const requireIndentForContinuation = spec.transcriptPty.continuationLine?.indented ?? false
175
+ const stripLeadingChrome = spec.transcriptPty.stripLeadingChrome ?? true
176
+ const scope = spec.transcriptPty.scope ?? 'buffer'
177
+
178
+ // Compose detect + approval helpers if their inputs are present.
179
+ const detectStatus = (spec.spinner || spec.settledPrompt || spec.modal || spec.dispatchOrder)
180
+ ? buildDetectStatusFromTui({
181
+ spinner: spec.spinner,
182
+ settledPrompt: spec.settledPrompt,
183
+ modal: spec.modal,
184
+ dispatchOrder: spec.dispatchOrder,
185
+ })
186
+ : () => null
187
+ const parseApproval = spec.modal ? buildParseApprovalFromTui(spec.modal) : () => null
188
+
189
+ // Optional session-id extraction (tui/session-id-extraction@1). Compile once
190
+ // so each parseSession call is a single regex.exec on the chosen scope.
191
+ const sessionIdRe = spec.sessionIdExtraction
192
+ ? new RegExp(
193
+ spec.sessionIdExtraction.regex,
194
+ spec.sessionIdExtraction.flags ?? 'i',
195
+ )
196
+ : null
197
+ const sessionIdScope: TranscriptPtySpec['scope'] = spec.sessionIdExtraction?.scope ?? 'tail'
198
+
199
+ return function parseSession(input: any): SynthesizedSession {
200
+ // status + modal first
201
+ const status = detectStatus(input as any) ?? 'idle'
202
+ const modal = parseApproval(input as any)
203
+
204
+ const text = pickInputText(input, scope)
205
+ const lines = splitLines(text)
206
+
207
+ const messages: SynthesizedMessage[] = []
208
+ let seenFirstRoleLine = !stripLeadingChrome
209
+
210
+ for (const raw of lines) {
211
+ const line = raw
212
+ if (line.trim() === '') {
213
+ // Blank line: ends streaming continuation but doesn't add a message.
214
+ continue
215
+ }
216
+
217
+ // Chrome filter
218
+ let isChrome = false
219
+ for (const cre of chromeRes) {
220
+ if (cre.test(line)) { isChrome = true; break }
221
+ }
222
+ if (isChrome) continue
223
+
224
+ // Role detection
225
+ const userMatch = userRe ? line.match(userRe) : null
226
+ const toolMatch = toolRe ? line.match(toolRe) : null
227
+ const assistMatch = line.match(assistantRe)
228
+
229
+ if (userMatch) {
230
+ seenFirstRoleLine = true
231
+ const content = (userMatch[1] ?? userMatch[0]).trim()
232
+ if (content) messages.push({ role: 'user', kind: 'standard', content })
233
+ continue
234
+ }
235
+ if (toolMatch) {
236
+ seenFirstRoleLine = true
237
+ if (toolSkip) continue
238
+ const content = (toolMatch[1] ?? toolMatch[0]).trim()
239
+ if (content) messages.push({ role: 'assistant', kind: 'tool', content })
240
+ continue
241
+ }
242
+ if (assistMatch) {
243
+ seenFirstRoleLine = true
244
+ const content = (assistMatch[1] ?? assistMatch[0]).trim()
245
+ if (content) messages.push({ role: 'assistant', kind: 'standard', content })
246
+ continue
247
+ }
248
+
249
+ if (!seenFirstRoleLine) continue
250
+
251
+ // Continuation rule
252
+ if (requireIndentForContinuation && !/^\s/.test(line)) continue
253
+ const last = messages[messages.length - 1]
254
+ if (!last) continue
255
+ const cont = line.replace(/^\s+/, '')
256
+ if (cont) last.content = last.content ? `${last.content}\n${cont}` : cont
257
+ }
258
+
259
+ const result: SynthesizedSession = {
260
+ status,
261
+ messages,
262
+ activeModal: modal,
263
+ modal,
264
+ parsedStatus: status,
265
+ }
266
+
267
+ if (sessionIdRe) {
268
+ const haystack = stripAnsi(pickInputText(input, sessionIdScope))
269
+ const match = haystack.match(sessionIdRe)
270
+ const captured = match?.[1]?.trim()
271
+ if (captured) result.providerSessionId = captured
272
+ }
273
+
274
+ return result
275
+ }
276
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * applyVisibleRegion
3
+ *
4
+ * Scopes the raw terminal text to the "visible region" declared by a
5
+ * `tui/visible-region@1` spec before handing it to detect-status and
6
+ * parse-approval matchers.
7
+ *
8
+ * Scope semantics:
9
+ * screen → full text unchanged (daemon already passes rendered screen)
10
+ * buffer → full text unchanged
11
+ * tail → last `tailChars` characters (default 4000)
12
+ * between-anchors → text between most recent (or first) top/bottom anchor
13
+ * regex matches; falls back to full text if anchors not found
14
+ *
15
+ * selectAnchor:
16
+ * "last" → use the LAST occurrence of the top anchor — useful for providers
17
+ * like Antigravity that redraw a separator + prompt on every turn;
18
+ * this excludes all scrollback above the current session frame.
19
+ * "first" → use the FIRST occurrence (default per schema).
20
+ */
21
+
22
+ // ─── Spec shape (mirrors tui-visible-region-v1.json) ───────────────────
23
+
24
+ interface AnchorPatternSpec {
25
+ pattern: string;
26
+ flags?: string;
27
+ }
28
+
29
+ interface AnchorsSpec {
30
+ top?: AnchorPatternSpec;
31
+ bottom?: AnchorPatternSpec;
32
+ }
33
+
34
+ export interface VisibleRegionSpec {
35
+ $schema?: 'adhdev:tui/visible-region@1';
36
+ scope: 'screen' | 'tail' | 'buffer' | 'between-anchors';
37
+ tailChars?: number;
38
+ anchors?: AnchorsSpec;
39
+ selectAnchor?: 'first' | 'last';
40
+ stripCues?: string[];
41
+ }
42
+
43
+ // ─── Helpers ───────────────────────────────────────────────────────────
44
+
45
+ function compile(re: string, flags?: string): RegExp {
46
+ try {
47
+ return new RegExp(re, flags ?? '');
48
+ } catch (e) {
49
+ throw new Error(`Invalid visible-region anchor regex /${re}/${flags ?? ''}: ${(e as Error).message}`);
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Find all non-overlapping matches of `re` in `text`.
55
+ * Returns them in order of occurrence (earliest first).
56
+ */
57
+ function findAllMatches(re: RegExp, text: string): RegExpExecArray[] {
58
+ const results: RegExpExecArray[] = [];
59
+ // Operate on a non-global copy with sticky-safe iteration to avoid
60
+ // mutating the caller's RegExp state.
61
+ const iter = new RegExp(re.source, re.flags.replace('g', '') + 'g');
62
+ let m: RegExpExecArray | null;
63
+ while ((m = iter.exec(text)) !== null) {
64
+ results.push(m);
65
+ // Advance past zero-width matches to prevent infinite loop.
66
+ if (m[0].length === 0) iter.lastIndex += 1;
67
+ }
68
+ return results;
69
+ }
70
+
71
+ // ─── Public API ────────────────────────────────────────────────────────
72
+
73
+ /**
74
+ * Apply the visible-region spec to `text` and return the scoped substring.
75
+ * Never throws on missing anchors — falls back to the full text instead.
76
+ */
77
+ export function applyVisibleRegion(spec: VisibleRegionSpec, text: string): string {
78
+ if (!text) return text;
79
+
80
+ switch (spec.scope) {
81
+ case 'screen':
82
+ case 'buffer':
83
+ return text;
84
+
85
+ case 'tail': {
86
+ const limit = spec.tailChars ?? 4000;
87
+ if (text.length <= limit) return text;
88
+ return text.slice(-limit);
89
+ }
90
+
91
+ case 'between-anchors': {
92
+ const anchors = spec.anchors;
93
+ if (!anchors?.top && !anchors?.bottom) return text;
94
+
95
+ const selectLast = (spec.selectAnchor ?? 'first') === 'last';
96
+
97
+ // ── Top anchor ──
98
+ let topEnd = 0; // default: start of text
99
+ if (anchors.top) {
100
+ const topRe = compile(anchors.top.pattern, anchors.top.flags);
101
+ const topMatches = findAllMatches(topRe, text);
102
+ if (topMatches.length === 0) {
103
+ // Top anchor not found — fall back to full text.
104
+ return text;
105
+ }
106
+ const chosen = selectLast
107
+ ? topMatches[topMatches.length - 1]
108
+ : topMatches[0];
109
+ // Region starts just after the end of the top anchor match.
110
+ topEnd = chosen.index + chosen[0].length;
111
+ }
112
+
113
+ // ── Bottom anchor ──
114
+ let bottomStart = text.length; // default: end of text
115
+ if (anchors.bottom) {
116
+ const bottomRe = compile(anchors.bottom.pattern, anchors.bottom.flags);
117
+ // Only search the portion that comes AFTER the top anchor end so we
118
+ // always pick the immediately-following bottom anchor.
119
+ const searchFrom = topEnd;
120
+ const suffix = text.slice(searchFrom);
121
+ const bottomMatches = findAllMatches(bottomRe, suffix);
122
+ if (bottomMatches.length === 0) {
123
+ // Bottom anchor not found — fall back to full text.
124
+ return text;
125
+ }
126
+ const chosen = selectLast
127
+ ? bottomMatches[bottomMatches.length - 1]
128
+ : bottomMatches[0];
129
+ bottomStart = searchFrom + chosen.index;
130
+ }
131
+
132
+ if (topEnd >= bottomStart) {
133
+ // Degenerate / overlapping anchors — fall back to full text.
134
+ return text;
135
+ }
136
+
137
+ return text.slice(topEnd, bottomStart);
138
+ }
139
+
140
+ default:
141
+ return text;
142
+ }
143
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Provider fixture format — v1.
3
+ *
4
+ * A fixture is two files committed alongside a provider:
5
+ *
6
+ * fixtures/<scenario>.pty — raw PTY byte capture (binary or text)
7
+ * fixtures/<scenario>.expected.json — expected handler outputs at one
8
+ * or more anchor frames
9
+ *
10
+ * Scenarios cover one concrete agent behaviour: cold start, prompt sent,
11
+ * generating with tool call, approval modal, idle after assistant complete,
12
+ * etc.
13
+ *
14
+ * The replay runner feeds the .pty bytes through the daemon's terminal
15
+ * emulator (TerminalTranscriptAccumulator) building up snapshots at each
16
+ * declared anchor, invokes the provider handlers, and compares results
17
+ * to the .expected.json shape.
18
+ *
19
+ * This file is the source of truth for the format. Schema mirror at
20
+ * sdk/v1/schemas/fixture-expected.schema.json.
21
+ */
22
+
23
+ import type {
24
+ CliApprovalModal,
25
+ CliChatMessage,
26
+ CliStatus,
27
+ } from '../types/cli/index.js';
28
+
29
+ /**
30
+ * The top-level shape of <scenario>.expected.json.
31
+ *
32
+ * `anchors` is an ordered list; each anchor declares a point in the
33
+ * PTY stream (by byte offset or by sentinel string) and the expected
34
+ * handler outputs at that point.
35
+ */
36
+ export interface FixtureExpected {
37
+ /** Schema version. Currently always 1. */
38
+ version: 1;
39
+ /** Free-form human description of the scenario. */
40
+ description?: string;
41
+ /** Provider type this fixture is for. */
42
+ providerType: string;
43
+ /** Path (relative to the .expected.json file) of the corresponding .pty file. */
44
+ ptyFile: string;
45
+ /** Optional cols/rows the recording was captured under. Defaults to 80x24. */
46
+ terminal?: { cols: number; rows: number };
47
+ /** Anchor points. Order matters; bytes are replayed up to each anchor. */
48
+ anchors: FixtureAnchor[];
49
+ }
50
+
51
+ export interface FixtureAnchor {
52
+ /** Human-readable identifier. Used in test reporter output. */
53
+ name: string;
54
+ /** Optional description. */
55
+ description?: string;
56
+ /**
57
+ * Where to stop replaying bytes. Exactly one of:
58
+ * - `untilByte` — stop after the Nth raw byte
59
+ * - `untilSentinel` — stop the first time `sentinel` appears in the
60
+ * accumulated rendered screen text
61
+ */
62
+ untilByte?: number;
63
+ untilSentinel?: string;
64
+ /**
65
+ * Expected handler outputs. All keys optional; the replay runner only
66
+ * checks the keys you provide.
67
+ */
68
+ expect: {
69
+ detectStatus?: CliStatus | null;
70
+ parseApproval?: CliApprovalModal | null;
71
+ parseSession?: {
72
+ status?: CliStatus;
73
+ modal?: CliApprovalModal | null;
74
+ providerSessionId?: string;
75
+ /**
76
+ * Either an exact array (deep-equal) or a shape declaration that lets
77
+ * you match only the role/kind/content shape without pinning specific
78
+ * fields. Pin specific message-by-message when you care about content.
79
+ */
80
+ messages?: CliChatMessage[] | MessageShape[];
81
+ };
82
+ };
83
+ /**
84
+ * Optional notes about why this anchor exists. Encouraged for
85
+ * regression-style fixtures so future maintainers know what bug the
86
+ * fixture catches.
87
+ */
88
+ notes?: string;
89
+ }
90
+
91
+ /**
92
+ * A shape declaration that matches a message by role/kind plus optional
93
+ * content substring or regex. Use this instead of an exact CliChatMessage
94
+ * when you do not want to pin exact text.
95
+ */
96
+ export interface MessageShape {
97
+ role: CliChatMessage['role'];
98
+ kind?: CliChatMessage['kind'];
99
+ /** Substring the content must contain. Plain string only. */
100
+ contentIncludes?: string;
101
+ /** Regex the content must match. */
102
+ contentMatches?: { source: string; flags?: string };
103
+ }
104
+
105
+ /**
106
+ * Result of replaying one anchor — what the handlers actually emitted.
107
+ * Used by the test runner to produce diff output.
108
+ */
109
+ export interface AnchorReplayResult {
110
+ anchor: FixtureAnchor;
111
+ passes: boolean;
112
+ diffs: string[];
113
+ actual: {
114
+ detectStatus?: CliStatus | null;
115
+ parseApproval?: CliApprovalModal | null;
116
+ parseSession?: {
117
+ status: CliStatus;
118
+ modal: CliApprovalModal | null;
119
+ providerSessionId?: string;
120
+ messages: CliChatMessage[];
121
+ };
122
+ };
123
+ }
124
+
125
+ export interface FixtureReplayResult {
126
+ fixturePath: string;
127
+ expected: FixtureExpected;
128
+ perAnchor: AnchorReplayResult[];
129
+ overallPasses: boolean;
130
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Fixture tooling — public surface.
3
+ *
4
+ * Imported by `adhdev provider test` and by daemon-core's CI regression
5
+ * suite. Format types and the replay runner are stable v1.
6
+ */
7
+
8
+ export type {
9
+ FixtureExpected,
10
+ FixtureAnchor,
11
+ MessageShape,
12
+ AnchorReplayResult,
13
+ FixtureReplayResult,
14
+ } from './format.js';
15
+
16
+ export {
17
+ loadFixtureExpected,
18
+ replayFixture,
19
+ formatReplayReport,
20
+ type CliProviderHandlers,
21
+ type ReplayOptions,
22
+ } from './replay.js';