@alumbwe/anvil 1.0.0 → 1.0.1

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 (529) hide show
  1. package/bin/anvil +1 -1
  2. package/dist/bundled.js +79559 -0
  3. package/dist/bundled.js.map +581 -0
  4. package/package.json +5 -2
  5. package/src/__tests__/README.md +0 -256
  6. package/src/__tests__/bash-mode.test.ts +0 -442
  7. package/src/__tests__/cli-args.test.ts +0 -181
  8. package/src/__tests__/cli-harness.test.ts +0 -52
  9. package/src/__tests__/e2e/first-time-login.test.ts +0 -173
  10. package/src/__tests__/e2e/logout-relogin-flow.test.ts +0 -110
  11. package/src/__tests__/e2e/returning-user-auth.test.ts +0 -113
  12. package/src/__tests__/e2e-cli.test.ts +0 -183
  13. package/src/__tests__/helpers/launcher-disconnect-fixture.cjs +0 -176
  14. package/src/__tests__/helpers/mock-api-client.ts +0 -64
  15. package/src/__tests__/helpers/renderer-cleanup-fixture.tsx +0 -89
  16. package/src/__tests__/helpers/terminal-watchdog-fixture.ts +0 -75
  17. package/src/__tests__/home-directory-detection.test.ts +0 -213
  18. package/src/__tests__/integration/api-integration.test.ts +0 -288
  19. package/src/__tests__/integration/credentials-storage.test.ts +0 -486
  20. package/src/__tests__/integration/local-agents.test.ts +0 -1187
  21. package/src/__tests__/integration/login-flow-instrumentation.test.ts +0 -134
  22. package/src/__tests__/integration/login-polling-working.test.ts +0 -285
  23. package/src/__tests__/integration/queue-editing.test.tsx +0 -261
  24. package/src/__tests__/integration/usage-refresh-on-completion.test.ts +0 -168
  25. package/src/__tests__/integration-tmux.test.ts +0 -188
  26. package/src/__tests__/launcher-avx2-fallback.test.ts +0 -630
  27. package/src/__tests__/launcher-disconnect.test.ts +0 -104
  28. package/src/__tests__/mocks/hover-toggle-controller.ts +0 -71
  29. package/src/__tests__/open-tui-native-bundle.test.ts +0 -378
  30. package/src/__tests__/path-completion.test.ts +0 -243
  31. package/src/__tests__/project-files-chat-id.test.ts +0 -34
  32. package/src/__tests__/release/proxy-http-get.test.ts +0 -667
  33. package/src/__tests__/release/wrapper-safety.test.ts +0 -412
  34. package/src/__tests__/renderer-cleanup.test.ts +0 -174
  35. package/src/__tests__/rerender-perf.integration.test.ts +0 -283
  36. package/src/__tests__/terminal-reset-sequences.test.ts +0 -36
  37. package/src/__tests__/terminal-watchdog.test.ts +0 -388
  38. package/src/__tests__/test-utils.ts +0 -271
  39. package/src/__tests__/tmux-poc.ts +0 -150
  40. package/src/__tests__/unit/agent-mode-toggle.test.ts +0 -137
  41. package/src/__tests__/unit/copy-button.test.ts +0 -157
  42. package/src/__tests__/unit/create-run-config.test.ts +0 -66
  43. package/src/__tests__/unit/publish-confirmation.test.ts +0 -70
  44. package/src/__tests__/unit/segmented-control.test.ts +0 -152
  45. package/src/__tests__/utils/env.test.ts +0 -169
  46. package/src/__tests__/utils/project-picker.test.ts +0 -39
  47. package/src/agents/bundled-agents.generated.d.ts +0 -14
  48. package/src/agents/bundled-agents.generated.ts +0 -3692
  49. package/src/app.tsx +0 -399
  50. package/src/chat.tsx +0 -1698
  51. package/src/cli-args.ts +0 -134
  52. package/src/commands/__tests__/bash-command.test.ts +0 -445
  53. package/src/commands/__tests__/command-args.test.ts +0 -349
  54. package/src/commands/__tests__/copy-conversation-clipboard.test.ts +0 -108
  55. package/src/commands/__tests__/copy-conversation.test.ts +0 -226
  56. package/src/commands/__tests__/diagnostics-command.test.ts +0 -35
  57. package/src/commands/__tests__/freebuff-command-aliases.test.ts +0 -56
  58. package/src/commands/__tests__/image.test.ts +0 -99
  59. package/src/commands/__tests__/init.test.ts +0 -456
  60. package/src/commands/__tests__/new-command-rotates-chat.test.ts +0 -91
  61. package/src/commands/__tests__/process-diagnostics.test.ts +0 -54
  62. package/src/commands/__tests__/prompt-builders.test.ts +0 -28
  63. package/src/commands/__tests__/router-input.test.ts +0 -298
  64. package/src/commands/ads.ts +0 -44
  65. package/src/commands/command-registry.ts +0 -726
  66. package/src/commands/copy-conversation.ts +0 -392
  67. package/src/commands/help.ts +0 -13
  68. package/src/commands/image.ts +0 -20
  69. package/src/commands/init.ts +0 -121
  70. package/src/commands/process-diagnostics.ts +0 -120
  71. package/src/commands/prompt-builders.ts +0 -100
  72. package/src/commands/publish.ts +0 -203
  73. package/src/commands/router-utils.ts +0 -80
  74. package/src/commands/router.ts +0 -487
  75. package/src/commands/usage.ts +0 -26
  76. package/src/components/__tests__/ad-banner.test.tsx +0 -83
  77. package/src/components/__tests__/chat-input-bar.test.tsx +0 -130
  78. package/src/components/__tests__/freebuff-landing-heading-row.test.tsx +0 -91
  79. package/src/components/__tests__/freebuff-model-selector.test.tsx +0 -519
  80. package/src/components/__tests__/freebuff-offer-invariants.test.ts +0 -54
  81. package/src/components/__tests__/freebuff-takeover-prompt.test.tsx +0 -212
  82. package/src/components/__tests__/grid-layout.integration.test.tsx +0 -304
  83. package/src/components/__tests__/grid-layout.test.tsx +0 -1051
  84. package/src/components/__tests__/message-block.completion.test.tsx +0 -104
  85. package/src/components/__tests__/message-block.streaming.test.tsx +0 -78
  86. package/src/components/__tests__/message-with-agents.test.tsx +0 -579
  87. package/src/components/__tests__/multiline-input.test.tsx +0 -1132
  88. package/src/components/__tests__/queue-panel.test.tsx +0 -398
  89. package/src/components/__tests__/selectable-list.test.ts +0 -232
  90. package/src/components/__tests__/status-bar.test.tsx +0 -44
  91. package/src/components/__tests__/status-indicator.test.tsx +0 -204
  92. package/src/components/__tests__/terminal-thinking-orb.test.tsx +0 -111
  93. package/src/components/__tests__/user-error-banner.test.tsx +0 -102
  94. package/src/components/ad-banner.tsx +0 -323
  95. package/src/components/agent-checklist.tsx +0 -350
  96. package/src/components/agent-mode-toggle.tsx +0 -241
  97. package/src/components/anvil-mark.tsx +0 -52
  98. package/src/components/ask-user/__tests__/multiple-choice-form.test.ts +0 -432
  99. package/src/components/ask-user/__tests__/validation.test.ts +0 -213
  100. package/src/components/ask-user/components/accordion-question.tsx +0 -153
  101. package/src/components/ask-user/components/custom-answer-input.tsx +0 -66
  102. package/src/components/ask-user/components/options-list.tsx +0 -133
  103. package/src/components/ask-user/components/question-header.tsx +0 -80
  104. package/src/components/ask-user/components/question-option.tsx +0 -89
  105. package/src/components/ask-user/constants.ts +0 -38
  106. package/src/components/ask-user/index.tsx +0 -631
  107. package/src/components/ask-user/utils/validation.ts +0 -85
  108. package/src/components/attachment-card.tsx +0 -65
  109. package/src/components/blocks/agent-block-grid.tsx +0 -58
  110. package/src/components/blocks/agent-branch-item.tsx +0 -311
  111. package/src/components/blocks/agent-branch-wrapper.tsx +0 -493
  112. package/src/components/blocks/agent-list-branch.tsx +0 -77
  113. package/src/components/blocks/ask-user-branch.tsx +0 -81
  114. package/src/components/blocks/block-helpers.ts +0 -11
  115. package/src/components/blocks/blocks-renderer.tsx +0 -289
  116. package/src/components/blocks/content-with-markdown.tsx +0 -33
  117. package/src/components/blocks/image-block.tsx +0 -128
  118. package/src/components/blocks/implementor-row.tsx +0 -429
  119. package/src/components/blocks/single-block.tsx +0 -201
  120. package/src/components/blocks/thinking-block.tsx +0 -67
  121. package/src/components/blocks/tool-block-group.tsx +0 -57
  122. package/src/components/blocks/tool-branch.tsx +0 -206
  123. package/src/components/blocks/user-content-copy.tsx +0 -157
  124. package/src/components/bottom-banner.tsx +0 -136
  125. package/src/components/build-mode-buttons.tsx +0 -110
  126. package/src/components/button.tsx +0 -66
  127. package/src/components/chat-header.tsx +0 -77
  128. package/src/components/chat-history-screen.tsx +0 -413
  129. package/src/components/chat-input-bar.tsx +0 -523
  130. package/src/components/clickable-title-box.tsx +0 -66
  131. package/src/components/clickable.tsx +0 -119
  132. package/src/components/collapse-button.tsx +0 -34
  133. package/src/components/copy-button.tsx +0 -203
  134. package/src/components/elapsed-timer.tsx +0 -55
  135. package/src/components/error-boundary.tsx +0 -55
  136. package/src/components/feedback-container.tsx +0 -181
  137. package/src/components/feedback-icon-button.tsx +0 -89
  138. package/src/components/feedback-input-mode.tsx +0 -344
  139. package/src/components/file-attachment-card.tsx +0 -98
  140. package/src/components/freebuff-active-session-summary.tsx +0 -63
  141. package/src/components/freebuff-landing-screen.tsx +0 -865
  142. package/src/components/freebuff-model-selector.tsx +0 -1087
  143. package/src/components/freebuff-referral-banner.tsx +0 -604
  144. package/src/components/freebuff-superseded-screen.tsx +0 -62
  145. package/src/components/grid-layout.tsx +0 -80
  146. package/src/components/help-banner.tsx +0 -127
  147. package/src/components/highlighted-text.tsx +0 -52
  148. package/src/components/image-card.tsx +0 -167
  149. package/src/components/image-thumbnail.tsx +0 -114
  150. package/src/components/input-cursor.tsx +0 -77
  151. package/src/components/input-mode-banner.tsx +0 -57
  152. package/src/components/load-previous-button.tsx +0 -48
  153. package/src/components/login-modal.tsx +0 -475
  154. package/src/components/message-block.tsx +0 -346
  155. package/src/components/message-footer.tsx +0 -258
  156. package/src/components/message-with-agents.tsx +0 -506
  157. package/src/components/mode-divider.tsx +0 -43
  158. package/src/components/multiline-input.tsx +0 -1241
  159. package/src/components/out-of-credits-banner.tsx +0 -160
  160. package/src/components/pending-attachments-banner.tsx +0 -116
  161. package/src/components/pending-bash-message.tsx +0 -59
  162. package/src/components/progress-bar.tsx +0 -81
  163. package/src/components/project-picker-screen.tsx +0 -485
  164. package/src/components/publish-confirmation.tsx +0 -493
  165. package/src/components/publish-container.tsx +0 -687
  166. package/src/components/queue-panel.tsx +0 -310
  167. package/src/components/raised-pill.tsx +0 -95
  168. package/src/components/renderers/plan-box.tsx +0 -59
  169. package/src/components/review-screen.tsx +0 -112
  170. package/src/components/scroll-to-bottom-button.tsx +0 -34
  171. package/src/components/segmented-control.tsx +0 -187
  172. package/src/components/selectable-list.tsx +0 -248
  173. package/src/components/selected-chips.tsx +0 -80
  174. package/src/components/separator.tsx +0 -40
  175. package/src/components/session-ended-banner.tsx +0 -226
  176. package/src/components/shimmer-text.tsx +0 -248
  177. package/src/components/status-bar.tsx +0 -313
  178. package/src/components/subscription-limit-banner.tsx +0 -206
  179. package/src/components/suggested-prompts.tsx +0 -184
  180. package/src/components/suggestion-menu.tsx +0 -215
  181. package/src/components/terminal-command-display.tsx +0 -151
  182. package/src/components/terminal-link.tsx +0 -97
  183. package/src/components/terminal-thinking-orb.tsx +0 -95
  184. package/src/components/text-attachment-card.tsx +0 -77
  185. package/src/components/thinking.tsx +0 -109
  186. package/src/components/tools/__tests__/apply-patch.test.tsx +0 -84
  187. package/src/components/tools/__tests__/code-search.test.tsx +0 -45
  188. package/src/components/tools/__tests__/gravity-index.test.ts +0 -76
  189. package/src/components/tools/__tests__/render-ui.test.tsx +0 -92
  190. package/src/components/tools/__tests__/run-terminal-command.test.ts +0 -233
  191. package/src/components/tools/apply-patch.tsx +0 -95
  192. package/src/components/tools/code-search.tsx +0 -45
  193. package/src/components/tools/composio.tsx +0 -152
  194. package/src/components/tools/diff-viewer.tsx +0 -76
  195. package/src/components/tools/glob.tsx +0 -61
  196. package/src/components/tools/gravity-index.tsx +0 -77
  197. package/src/components/tools/list-directory.tsx +0 -61
  198. package/src/components/tools/read-docs.tsx +0 -37
  199. package/src/components/tools/read-files.tsx +0 -91
  200. package/src/components/tools/read-subtree.tsx +0 -44
  201. package/src/components/tools/read-url.tsx +0 -33
  202. package/src/components/tools/registry.ts +0 -126
  203. package/src/components/tools/render-ui.tsx +0 -122
  204. package/src/components/tools/run-terminal-command.tsx +0 -79
  205. package/src/components/tools/skill.tsx +0 -29
  206. package/src/components/tools/str-replace.tsx +0 -77
  207. package/src/components/tools/suggest-followups.tsx +0 -369
  208. package/src/components/tools/task-completed.tsx +0 -16
  209. package/src/components/tools/tool-call-item.tsx +0 -273
  210. package/src/components/tools/types.ts +0 -55
  211. package/src/components/tools/web-search.tsx +0 -33
  212. package/src/components/tools/write-file.tsx +0 -16
  213. package/src/components/tools/write-todos.tsx +0 -95
  214. package/src/components/top-banner.tsx +0 -178
  215. package/src/components/usage-banner.tsx +0 -244
  216. package/src/components/user-error-banner.tsx +0 -56
  217. package/src/components/validation-error-popover.tsx +0 -192
  218. package/src/contexts/__tests__/chat-runtime-context.test.tsx +0 -149
  219. package/src/contexts/chat-runtime-context.tsx +0 -240
  220. package/src/data/slash-commands.test.ts +0 -24
  221. package/src/data/slash-commands.ts +0 -249
  222. package/src/entry.ts +0 -12
  223. package/src/hooks/__tests__/holds-live-freebuff-slot.test.ts +0 -49
  224. package/src/hooks/__tests__/session-fetch-signal.test.ts +0 -63
  225. package/src/hooks/__tests__/use-activity-query.test.ts +0 -1000
  226. package/src/hooks/__tests__/use-ask-user-bridge.test.ts +0 -176
  227. package/src/hooks/__tests__/use-auth-query.test.ts +0 -21
  228. package/src/hooks/__tests__/use-chat-input-remount.test.tsx +0 -66
  229. package/src/hooks/__tests__/use-clipboard.test.tsx +0 -73
  230. package/src/hooks/__tests__/use-connection-status.test.ts +0 -112
  231. package/src/hooks/__tests__/use-directory-browser.test.ts +0 -203
  232. package/src/hooks/__tests__/use-gravity-ad.test.ts +0 -73
  233. package/src/hooks/__tests__/use-grid-layout.test.ts +0 -349
  234. package/src/hooks/__tests__/use-input-history.test.ts +0 -699
  235. package/src/hooks/__tests__/use-message-queue-editing.test.tsx +0 -209
  236. package/src/hooks/__tests__/use-message-queue.test.tsx +0 -71
  237. package/src/hooks/__tests__/use-path-tab-completion.test.ts +0 -315
  238. package/src/hooks/__tests__/use-queue-controls.test.ts +0 -68
  239. package/src/hooks/__tests__/use-queue-ui.test.tsx +0 -83
  240. package/src/hooks/__tests__/use-searchable-list.test.ts +0 -359
  241. package/src/hooks/__tests__/use-send-message-timer.test.ts +0 -146
  242. package/src/hooks/__tests__/use-suggestion-engine-mention.test.ts +0 -361
  243. package/src/hooks/__tests__/use-suggestion-engine.test.ts +0 -485
  244. package/src/hooks/__tests__/use-terminal-focus.test.ts +0 -66
  245. package/src/hooks/__tests__/use-terminal-layout.test.ts +0 -675
  246. package/src/hooks/__tests__/use-timeout.test.ts +0 -330
  247. package/src/hooks/__tests__/use-usage-query.test.ts +0 -502
  248. package/src/hooks/__tests__/use-user-details-query.test.ts +0 -195
  249. package/src/hooks/helpers/__tests__/send-message.test.ts +0 -1918
  250. package/src/hooks/helpers/send-message.ts +0 -654
  251. package/src/hooks/stream-state.ts +0 -83
  252. package/src/hooks/use-activity-query.ts +0 -668
  253. package/src/hooks/use-agent-validation.ts +0 -74
  254. package/src/hooks/use-ask-user-bridge.ts +0 -92
  255. package/src/hooks/use-auth-query.ts +0 -253
  256. package/src/hooks/use-auth-state.ts +0 -152
  257. package/src/hooks/use-chat-input.ts +0 -105
  258. package/src/hooks/use-chat-keyboard.ts +0 -321
  259. package/src/hooks/use-chat-messages.ts +0 -254
  260. package/src/hooks/use-chat-state.ts +0 -165
  261. package/src/hooks/use-chat-streaming.ts +0 -180
  262. package/src/hooks/use-chat-ui.ts +0 -131
  263. package/src/hooks/use-clipboard.ts +0 -151
  264. package/src/hooks/use-connection-status.ts +0 -142
  265. package/src/hooks/use-directory-browser.ts +0 -88
  266. package/src/hooks/use-elapsed-time.ts +0 -116
  267. package/src/hooks/use-event.ts +0 -34
  268. package/src/hooks/use-exit-handler.ts +0 -66
  269. package/src/hooks/use-fetch-login-url.ts +0 -65
  270. package/src/hooks/use-fingerprint.ts +0 -61
  271. package/src/hooks/use-freebuff-ctrl-c-exit.ts +0 -23
  272. package/src/hooks/use-freebuff-session-progress.ts +0 -34
  273. package/src/hooks/use-freebuff-session.ts +0 -806
  274. package/src/hooks/use-freebuff-streak-query.ts +0 -61
  275. package/src/hooks/use-gravity-ad.ts +0 -656
  276. package/src/hooks/use-grid-layout.ts +0 -73
  277. package/src/hooks/use-input-history.ts +0 -173
  278. package/src/hooks/use-login-keyboard-handlers.ts +0 -75
  279. package/src/hooks/use-login-polling.ts +0 -114
  280. package/src/hooks/use-logo.tsx +0 -161
  281. package/src/hooks/use-message-queue.ts +0 -387
  282. package/src/hooks/use-now.ts +0 -20
  283. package/src/hooks/use-path-tab-completion.ts +0 -88
  284. package/src/hooks/use-publish-mutation.ts +0 -60
  285. package/src/hooks/use-queue-controls.ts +0 -68
  286. package/src/hooks/use-queue-ui.ts +0 -74
  287. package/src/hooks/use-scroll-management.ts +0 -184
  288. package/src/hooks/use-searchable-list.ts +0 -98
  289. package/src/hooks/use-send-message.ts +0 -773
  290. package/src/hooks/use-sheen-animation.tsx +0 -88
  291. package/src/hooks/use-subscription-query.ts +0 -71
  292. package/src/hooks/use-suggestion-engine.ts +0 -783
  293. package/src/hooks/use-terminal-breakpoints.ts +0 -77
  294. package/src/hooks/use-terminal-dimensions.ts +0 -46
  295. package/src/hooks/use-terminal-focus.ts +0 -29
  296. package/src/hooks/use-terminal-layout.ts +0 -189
  297. package/src/hooks/use-theme.tsx +0 -140
  298. package/src/hooks/use-timeout.ts +0 -85
  299. package/src/hooks/use-update-preference.ts +0 -66
  300. package/src/hooks/use-usage-monitor.ts +0 -55
  301. package/src/hooks/use-usage-query.ts +0 -124
  302. package/src/hooks/use-user-details-query.ts +0 -93
  303. package/src/hooks/use-why-did-you-update.ts +0 -177
  304. package/src/index.tsx +0 -441
  305. package/src/init/__tests__/init-direnv.test.ts +0 -526
  306. package/src/init/init-app.ts +0 -34
  307. package/src/init/init-direnv.ts +0 -133
  308. package/src/login/constants.ts +0 -60
  309. package/src/login/login-flow.ts +0 -204
  310. package/src/login/plain-login.ts +0 -108
  311. package/src/login/utils.ts +0 -183
  312. package/src/native/ripgrep.ts +0 -80
  313. package/src/polyfills/bun-strip-ansi.ts +0 -12
  314. package/src/pre-init/tree-sitter-wasm.ts +0 -96
  315. package/src/project-files.ts +0 -102
  316. package/src/smoke/terminal-command-broker.ts +0 -439
  317. package/src/state/__tests__/chat-store-focus.test.ts +0 -22
  318. package/src/state/__tests__/feedback-store.test.ts +0 -257
  319. package/src/state/chat-history-store.ts +0 -30
  320. package/src/state/chat-store.ts +0 -544
  321. package/src/state/feedback-store.ts +0 -160
  322. package/src/state/freebuff-model-store.ts +0 -42
  323. package/src/state/freebuff-session-store.ts +0 -53
  324. package/src/state/login-store.ts +0 -150
  325. package/src/state/message-block-store.ts +0 -149
  326. package/src/state/publish-store.ts +0 -146
  327. package/src/state/queue-panel-store.ts +0 -26
  328. package/src/state/review-store.ts +0 -24
  329. package/src/testing/env.ts +0 -46
  330. package/src/types/chat-state.ts +0 -15
  331. package/src/types/chat.ts +0 -241
  332. package/src/types/contracts/send-message.ts +0 -12
  333. package/src/types/env.ts +0 -98
  334. package/src/types/freebuff-session.ts +0 -17
  335. package/src/types/function-params.ts +0 -28
  336. package/src/types/react19-compat.d.ts +0 -19
  337. package/src/types/store.ts +0 -111
  338. package/src/types/theme-system.ts +0 -144
  339. package/src/types/utils.ts +0 -3
  340. package/src/utils/__tests__/active-run.test.ts +0 -140
  341. package/src/utils/__tests__/activity-tracker.test.ts +0 -440
  342. package/src/utils/__tests__/agent-display.test.ts +0 -139
  343. package/src/utils/__tests__/analytics-client.test.ts +0 -262
  344. package/src/utils/__tests__/anonymous-id.test.ts +0 -74
  345. package/src/utils/__tests__/anvil-api.test.ts +0 -578
  346. package/src/utils/__tests__/arrays.test.ts +0 -264
  347. package/src/utils/__tests__/bash-context-processor.test.ts +0 -38
  348. package/src/utils/__tests__/block-processor.test.ts +0 -810
  349. package/src/utils/__tests__/chat-history.test.ts +0 -203
  350. package/src/utils/__tests__/chat-input-key-intercept.test.ts +0 -40
  351. package/src/utils/__tests__/chat-meta.test.ts +0 -130
  352. package/src/utils/__tests__/clipboard-linux.test.ts +0 -359
  353. package/src/utils/__tests__/clipboard.test.ts +0 -910
  354. package/src/utils/__tests__/code-search-summary.test.ts +0 -84
  355. package/src/utils/__tests__/collapse-helpers.test.ts +0 -1109
  356. package/src/utils/__tests__/error-handling.test.ts +0 -658
  357. package/src/utils/__tests__/exit-cleanly.test.ts +0 -110
  358. package/src/utils/__tests__/feedback-helpers.test.ts +0 -444
  359. package/src/utils/__tests__/feedback-submission.test.ts +0 -26
  360. package/src/utils/__tests__/fetch-usage.test.ts +0 -355
  361. package/src/utils/__tests__/fingerprint.test.ts +0 -144
  362. package/src/utils/__tests__/fixtures/terminal-command-broker-child.ts +0 -7
  363. package/src/utils/__tests__/fixtures/terminal-command-broker-entry.ts +0 -3
  364. package/src/utils/__tests__/fixtures/terminal-command-broker-owner.ts +0 -33
  365. package/src/utils/__tests__/format-elapsed-time.test.ts +0 -103
  366. package/src/utils/__tests__/format-timeout.test.ts +0 -87
  367. package/src/utils/__tests__/freebuff-instance-owner.test.ts +0 -69
  368. package/src/utils/__tests__/freebuff-model-navigation.test.ts +0 -102
  369. package/src/utils/__tests__/freebuff-premium-reset.test.ts +0 -79
  370. package/src/utils/__tests__/freebuff-referral-cache.test.ts +0 -116
  371. package/src/utils/__tests__/freebuff-session-api.test.ts +0 -215
  372. package/src/utils/__tests__/freebuff-session-display.test.ts +0 -23
  373. package/src/utils/__tests__/freebuff-streak-line.test.ts +0 -217
  374. package/src/utils/__tests__/image-dimensions.test.ts +0 -249
  375. package/src/utils/__tests__/image-processor.test.ts +0 -209
  376. package/src/utils/__tests__/implementor-helpers.test.ts +0 -1458
  377. package/src/utils/__tests__/keyboard-actions.test.ts +0 -660
  378. package/src/utils/__tests__/layout-helpers.test.ts +0 -36
  379. package/src/utils/__tests__/lazy-response-ads.test.ts +0 -167
  380. package/src/utils/__tests__/log-shipper.test.ts +0 -53
  381. package/src/utils/__tests__/markdown-renderer.test.tsx +0 -421
  382. package/src/utils/__tests__/message-block-helpers.test.ts +0 -1263
  383. package/src/utils/__tests__/message-updater.test.ts +0 -645
  384. package/src/utils/__tests__/osc-timeout-scenarios.test.ts +0 -172
  385. package/src/utils/__tests__/pending-attachments.test.ts +0 -277
  386. package/src/utils/__tests__/polling-backoff.test.ts +0 -51
  387. package/src/utils/__tests__/queue-panel-actions.test.ts +0 -148
  388. package/src/utils/__tests__/run-state-storage.test.ts +0 -919
  389. package/src/utils/__tests__/safe-json.test.ts +0 -77
  390. package/src/utils/__tests__/sdk-event-handlers.test.ts +0 -685
  391. package/src/utils/__tests__/send-message-helpers.test.ts +0 -1898
  392. package/src/utils/__tests__/send-message-timer.test.ts +0 -64
  393. package/src/utils/__tests__/settings.test.ts +0 -99
  394. package/src/utils/__tests__/strings.test.ts +0 -192
  395. package/src/utils/__tests__/terminal-color-detection.test.ts +0 -425
  396. package/src/utils/__tests__/terminal-command-broker.test.ts +0 -528
  397. package/src/utils/__tests__/terminal-enter-detection.test.ts +0 -77
  398. package/src/utils/__tests__/terminal-io.test.ts +0 -137
  399. package/src/utils/__tests__/terminal-protocol-controller.test.ts +0 -119
  400. package/src/utils/__tests__/text-layout.test.ts +0 -82
  401. package/src/utils/__tests__/theme-platform-detection.test.ts +0 -125
  402. package/src/utils/__tests__/think-tag-parser.test.ts +0 -159
  403. package/src/utils/__tests__/trace-writer.test.ts +0 -223
  404. package/src/utils/__tests__/trim-chat-logs.test.ts +0 -78
  405. package/src/utils/__tests__/usage-banner-state.test.ts +0 -298
  406. package/src/utils/__tests__/validation-error-formatting.test.ts +0 -126
  407. package/src/utils/__tests__/windows-terminal-health.test.ts +0 -101
  408. package/src/utils/__tests__/write-file-atomic.test.ts +0 -127
  409. package/src/utils/active-run.ts +0 -131
  410. package/src/utils/activity-tracker.ts +0 -66
  411. package/src/utils/agent-display.ts +0 -87
  412. package/src/utils/agent-helpers.ts +0 -27
  413. package/src/utils/agent-id-utils.ts +0 -14
  414. package/src/utils/ai-message-id.ts +0 -12
  415. package/src/utils/analytics.ts +0 -361
  416. package/src/utils/anonymous-id.ts +0 -87
  417. package/src/utils/anvil-api.ts +0 -612
  418. package/src/utils/anvil-client.ts +0 -217
  419. package/src/utils/arrays.ts +0 -117
  420. package/src/utils/auth.ts +0 -258
  421. package/src/utils/bash-context-processor.ts +0 -47
  422. package/src/utils/bash-messages.ts +0 -108
  423. package/src/utils/block-margins.ts +0 -35
  424. package/src/utils/block-operations.ts +0 -523
  425. package/src/utils/block-processor.ts +0 -213
  426. package/src/utils/chat-history.ts +0 -253
  427. package/src/utils/chat-input-key-intercept.ts +0 -52
  428. package/src/utils/chat-meta.ts +0 -90
  429. package/src/utils/chat-scroll-accel.ts +0 -151
  430. package/src/utils/clipboard-image.ts +0 -588
  431. package/src/utils/clipboard.ts +0 -397
  432. package/src/utils/code-search-summary.ts +0 -70
  433. package/src/utils/collapse-helpers.ts +0 -256
  434. package/src/utils/config-dir.ts +0 -24
  435. package/src/utils/constants.ts +0 -190
  436. package/src/utils/create-event-handler-state.ts +0 -73
  437. package/src/utils/create-run-config.ts +0 -121
  438. package/src/utils/detect-shell.ts +0 -116
  439. package/src/utils/directory-browser.ts +0 -72
  440. package/src/utils/engagement.ts +0 -55
  441. package/src/utils/env.ts +0 -92
  442. package/src/utils/error-handling.ts +0 -255
  443. package/src/utils/error-messages.ts +0 -62
  444. package/src/utils/exit-cleanly.ts +0 -86
  445. package/src/utils/feedback-helpers.ts +0 -103
  446. package/src/utils/feedback-submission.ts +0 -22
  447. package/src/utils/fetch-usage.ts +0 -76
  448. package/src/utils/fingerprint.ts +0 -245
  449. package/src/utils/format-elapsed-time.ts +0 -33
  450. package/src/utils/format-session-units.ts +0 -6
  451. package/src/utils/format-timeout.ts +0 -28
  452. package/src/utils/format-validation-errors-for-message.ts +0 -84
  453. package/src/utils/freebuff-agent-selection.ts +0 -33
  454. package/src/utils/freebuff-instance-owner.ts +0 -66
  455. package/src/utils/freebuff-model-navigation.ts +0 -50
  456. package/src/utils/freebuff-premium-reset.ts +0 -55
  457. package/src/utils/freebuff-referral-cache.ts +0 -51
  458. package/src/utils/freebuff-session-api.ts +0 -243
  459. package/src/utils/freebuff-session-display.ts +0 -21
  460. package/src/utils/freebuff-streak-line.ts +0 -93
  461. package/src/utils/git.ts +0 -17
  462. package/src/utils/helpers.ts +0 -47
  463. package/src/utils/image-display.ts +0 -67
  464. package/src/utils/image-handler.ts +0 -325
  465. package/src/utils/image-processor.ts +0 -133
  466. package/src/utils/image-thumbnail.ts +0 -78
  467. package/src/utils/implementor-helpers.ts +0 -787
  468. package/src/utils/input-modes.ts +0 -174
  469. package/src/utils/keyboard-actions.ts +0 -392
  470. package/src/utils/keypad-keys.ts +0 -47
  471. package/src/utils/layout-helpers.ts +0 -33
  472. package/src/utils/lazy-response-ads.ts +0 -1
  473. package/src/utils/local-agent-registry.ts +0 -474
  474. package/src/utils/log-shipper.ts +0 -126
  475. package/src/utils/logger.ts +0 -327
  476. package/src/utils/markdown-renderer.tsx +0 -1090
  477. package/src/utils/math.ts +0 -3
  478. package/src/utils/message-block-helpers.ts +0 -684
  479. package/src/utils/message-history.ts +0 -143
  480. package/src/utils/message-tree-utils.ts +0 -67
  481. package/src/utils/message-updater.ts +0 -279
  482. package/src/utils/open-file.ts +0 -146
  483. package/src/utils/open-url.ts +0 -63
  484. package/src/utils/path-completion.ts +0 -111
  485. package/src/utils/path-helpers.ts +0 -38
  486. package/src/utils/pending-attachments.ts +0 -360
  487. package/src/utils/polling-backoff.ts +0 -59
  488. package/src/utils/project-picker.ts +0 -12
  489. package/src/utils/queue-panel-actions.ts +0 -70
  490. package/src/utils/recent-projects.ts +0 -156
  491. package/src/utils/renderer-cleanup.ts +0 -233
  492. package/src/utils/response-ad-positions.ts +0 -1
  493. package/src/utils/run-state-storage.ts +0 -603
  494. package/src/utils/safe-json.ts +0 -153
  495. package/src/utils/sdk-event-handlers.ts +0 -571
  496. package/src/utils/send-message-helpers.ts +0 -210
  497. package/src/utils/send-message-timer.ts +0 -110
  498. package/src/utils/settings.ts +0 -226
  499. package/src/utils/skill-registry.ts +0 -94
  500. package/src/utils/spawn-agent-matcher.ts +0 -55
  501. package/src/utils/status-indicator-state.ts +0 -107
  502. package/src/utils/stream-chunk-processor.ts +0 -57
  503. package/src/utils/strings.ts +0 -271
  504. package/src/utils/subscription.ts +0 -31
  505. package/src/utils/syntax-highlighter.tsx +0 -19
  506. package/src/utils/terminal-color-detection.ts +0 -474
  507. package/src/utils/terminal-command-broker.ts +0 -467
  508. package/src/utils/terminal-enter-detection.ts +0 -63
  509. package/src/utils/terminal-images.ts +0 -229
  510. package/src/utils/terminal-io.ts +0 -85
  511. package/src/utils/terminal-protocol-controller.ts +0 -173
  512. package/src/utils/terminal-reset-sequences.ts +0 -33
  513. package/src/utils/terminal-title.ts +0 -84
  514. package/src/utils/terminal-watchdog.ts +0 -366
  515. package/src/utils/text-layout.ts +0 -149
  516. package/src/utils/theme-config.ts +0 -141
  517. package/src/utils/theme-system.ts +0 -1206
  518. package/src/utils/think-tag-parser.ts +0 -95
  519. package/src/utils/time-format.ts +0 -21
  520. package/src/utils/trace-writer.ts +0 -162
  521. package/src/utils/ui-constants.ts +0 -69
  522. package/src/utils/update-checker.ts +0 -110
  523. package/src/utils/usage-banner-state.ts +0 -146
  524. package/src/utils/validation-error-formatting.ts +0 -86
  525. package/src/utils/validation-error-helpers.ts +0 -19
  526. package/src/utils/windows-terminal-health.ts +0 -124
  527. package/src/utils/word-wrap-utils.ts +0 -53
  528. package/src/utils/write-file-atomic.ts +0 -54
  529. package/src/utils/yield-to-event-loop.ts +0 -9
@@ -1,96 +0,0 @@
1
- // Find tree-sitter.wasm so the SDK's tree-sitter parser singleton can load
2
- // it at runtime. Must be the very first import in `index.tsx`: subsequent
3
- // imports (the SDK / code-map) eagerly construct the parser, and its init
4
- // reads what we publish here on `globalThis` and via the env var.
5
- //
6
- // Final approach after several attempts to embed the wasm into the bun
7
- // --compile binary all failed on Windows (the bytes ended up in the
8
- // binary, but every JS-level retrieval mechanism — `with { type: 'file' }`
9
- // import binding, base64 string literals, chunked base64 in a generated
10
- // module, function-export wrappers — was either tree-shaken, transformed
11
- // by the minifier, or otherwise stripped):
12
- //
13
- // ship tree-sitter.wasm as a sibling file next to the binary.
14
- //
15
- // It's 200KB, the npm tarball already contains the binary; adding one
16
- // more file is trivial. The build script copies the wasm into `cli/bin/`
17
- // after compile, the release workflow tarballs both, and the freebuff /
18
- // anvil downloader extracts both into the same directory. At runtime,
19
- // `process.execPath` plus a relative file lookup gets us the wasm with
20
- // zero bundler involvement.
21
-
22
- import { existsSync, readFileSync } from 'fs'
23
- import { dirname, isAbsolute, join, resolve } from 'path'
24
-
25
- // Where to look for the sibling tree-sitter.wasm. We can't just use
26
- // `dirname(process.execPath)`: at pre-init time inside a bun --compile
27
- // binary on Windows, `process.execPath` returns the *bunfs* internal
28
- // path (`B:\~BUN\root\<binary>.exe`) rather than the on-disk path of
29
- // the .exe the user invoked. By the time main() runs it switches to
30
- // the disk path, but pre-init has long since bailed out.
31
- //
32
- // Try several sources in order; the first whose sibling .wasm exists
33
- // wins. argv[0] is normally the path the binary was invoked with —
34
- // always a real disk path, never bunfs. execPath is kept as a fallback
35
- // for environments where argv[0] is something exotic.
36
- const candidates = (
37
- [process.argv[0], process.execPath] as Array<string | undefined>
38
- )
39
- .filter((p): p is string => typeof p === 'string' && p.length > 0)
40
- .map((p) => (isAbsolute(p) ? p : resolve(p)))
41
- .map((p) => join(dirname(p), 'tree-sitter.wasm'))
42
-
43
- const siblingPath = candidates.find((p) => existsSync(p))
44
-
45
- // Pre-init diagnostic — only fires when --smoke-tree-sitter is set so we
46
- // don't spam every run. We need to see what argv[0] / execPath looked
47
- // like at this exact phase on Windows: the round-7 main() diag showed
48
- // disk paths, but pre-init silently bailed, meaning module-init time
49
- // gives different values. argv[0] alone wasn't enough to fix it.
50
- if (process.argv.includes('--smoke-tree-sitter')) {
51
- console.error(
52
- `[pre-init diag] argv[0]=${process.argv[0]}\n` +
53
- `[pre-init diag] execPath=${process.execPath}\n` +
54
- `[pre-init diag] candidates=${JSON.stringify(candidates)}\n` +
55
- `[pre-init diag] resolved siblingPath=${siblingPath ?? '<none>'}\n`,
56
- )
57
- }
58
-
59
- if (siblingPath) {
60
- // Tell init-node.ts (in code-map / the SDK bundle) where the wasm
61
- // is. The locateFile callback there will hand this path to
62
- // emscripten, which fs.readFile's it.
63
- process.env.ANVIL_TREE_SITTER_WASM_PATH = siblingPath
64
-
65
- // Also publish on globalThis so the smoke handler in index.tsx can
66
- // read it without touching process.env (which is gated by the env
67
- // architecture check outside the allowlisted pre-init files).
68
- ;(
69
- globalThis as { __ANVIL_TREE_SITTER_WASM_PATH__?: string }
70
- ).__ANVIL_TREE_SITTER_WASM_PATH__ = siblingPath
71
-
72
- // Also try the synchronous-bytes path: hand the bytes straight to
73
- // Parser.init({ wasmBinary }) so the SDK doesn't need to round-trip
74
- // through emscripten's path resolution. Both channels feed the same
75
- // tree-sitter init; whichever one trips first wins.
76
- try {
77
- const buf = readFileSync(siblingPath)
78
- ;(
79
- globalThis as { __ANVIL_TREE_SITTER_WASM_BINARY__?: Uint8Array }
80
- ).__ANVIL_TREE_SITTER_WASM_BINARY__ = new Uint8Array(
81
- buf.buffer,
82
- buf.byteOffset,
83
- buf.byteLength,
84
- )
85
- } catch (err) {
86
- console.error(
87
- '[tree-sitter pre-init] readFileSync failed for sibling wasm at',
88
- siblingPath,
89
- '—',
90
- err instanceof Error ? err.message : String(err),
91
- )
92
- }
93
- }
94
-
95
- // `--smoke-tree-sitter` is the deterministic CI gate. The handler lives at
96
- // the top of main() in cli/src/index.tsx (before parseArgs).
@@ -1,102 +0,0 @@
1
- import { mkdirSync, readdirSync, statSync } from 'fs'
2
- import path from 'path'
3
-
4
- import { getConfigDir } from './utils/auth'
5
-
6
- let projectRoot: string | undefined
7
- let currentChatId: string | undefined
8
-
9
- function ensureChatDirectory(dir: string) {
10
- mkdirSync(dir, { recursive: true })
11
- }
12
-
13
- export function setProjectRoot(dir: string) {
14
- projectRoot = dir
15
- return projectRoot
16
- }
17
-
18
- export function getProjectRoot() {
19
- if (!projectRoot) {
20
- throw new Error('Project root not set')
21
- }
22
- return projectRoot
23
- }
24
-
25
- export function tryGetProjectRoot() {
26
- return projectRoot
27
- }
28
-
29
- export function getCurrentChatId() {
30
- if (!currentChatId) {
31
- currentChatId = new Date().toISOString().replace(/:/g, '-')
32
- }
33
- return currentChatId
34
- }
35
-
36
- export function setCurrentChatId(chatId: string) {
37
- currentChatId = chatId
38
- return currentChatId
39
- }
40
-
41
- export function startNewChat() {
42
- currentChatId = new Date().toISOString().replace(/:/g, '-')
43
- return currentChatId
44
- }
45
-
46
- // Get the project-specific data directory
47
- export function getProjectDataDir(): string {
48
- const root = getProjectRoot()
49
- if (!root) {
50
- throw new Error('Project root not set')
51
- }
52
-
53
- const baseName = path.basename(root)
54
- const baseDir = path.join(getConfigDir(), 'projects', baseName)
55
-
56
- return baseDir
57
- }
58
-
59
- /**
60
- * Find the most recent chat directory based on modification time
61
- * Returns null if no chat directories exist
62
- */
63
- export function getMostRecentChatDir(): string | null {
64
- try {
65
- const chatsDir = path.join(getProjectDataDir(), 'chats')
66
- if (!statSync(chatsDir, { throwIfNoEntry: false })) {
67
- return null
68
- }
69
-
70
- const chatDirs = readdirSync(chatsDir)
71
- .map((name) => {
72
- const fullPath = path.join(chatsDir, name)
73
- try {
74
- const stat = statSync(fullPath)
75
- return { name, fullPath, mtime: stat.mtime }
76
- } catch {
77
- return null
78
- }
79
- })
80
- .filter(
81
- (item): item is { name: string; fullPath: string; mtime: Date } =>
82
- item !== null && statSync(item.fullPath).isDirectory(),
83
- )
84
-
85
- if (chatDirs.length === 0) {
86
- return null
87
- }
88
-
89
- // Sort by modification time, most recent first
90
- chatDirs.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())
91
- return chatDirs[0].fullPath
92
- } catch {
93
- return null
94
- }
95
- }
96
-
97
- export function getCurrentChatDir(): string {
98
- const chatId = getCurrentChatId()
99
- const dir = path.join(getProjectDataDir(), 'chats', chatId)
100
- ensureChatDirectory(dir)
101
- return dir
102
- }
@@ -1,439 +0,0 @@
1
- import { runTerminalCommand } from '@anvil/sdk'
2
- import { createCliRenderer } from '@opentui/core'
3
- import { existsSync, mkdirSync, writeFileSync } from 'fs'
4
- import path from 'path'
5
-
6
- import { installProcessCleanupHandlers } from '../utils/renderer-cleanup'
7
- import { startTerminalWatchdog } from '../utils/terminal-watchdog'
8
- import {
9
- createTerminalCommandBroker,
10
- terminalCommandBroker,
11
- } from '../utils/terminal-command-broker'
12
- import { installTerminalProtocolController } from '../utils/terminal-protocol-controller'
13
- import { writeTerminalControlSync } from '../utils/terminal-io'
14
-
15
- import type { CliRenderer } from '@opentui/core'
16
- import type { AnvilToolOutput } from '@anvil/sdk'
17
-
18
- const WAIT_INTERVAL_MS = 25
19
-
20
- type TerminalResult =
21
- AnvilToolOutput<'run_terminal_command'>[number]['value']
22
-
23
- type SmokeResult = {
24
- ok: boolean
25
- platform: NodeJS.Platform
26
- stdinIsTTY: boolean
27
- stdoutIsTTY: boolean
28
- simpleCommand?: { stdout: string; stderr: string; exitCode: number | null }
29
- repeatedCommands?: { completed: number }
30
- overlap?: {
31
- focusStates: boolean[]
32
- controlWrites: string[]
33
- mouseStayedEnabledDuringOverlap: boolean
34
- mouseStayedEnabledAfterCancellation: boolean
35
- mouseStayedEnabledAfterCompletion: boolean
36
- firstCancellationMessage: string
37
- secondStdout: string
38
- consoleReaderStdout: string
39
- }
40
- brokerFailure?: { message: string; commandStarted: boolean }
41
- error?: string
42
- stack?: string
43
- }
44
-
45
- function assertSmoke(condition: unknown, message: string): asserts condition {
46
- if (!condition) throw new Error(message)
47
- }
48
-
49
- function shellQuote(value: string): string {
50
- return `'${value.replace(/'/g, `'\\''`)}'`
51
- }
52
-
53
- function toBashPath(value: string): string {
54
- return value.replace(/\\/g, '/')
55
- }
56
-
57
- function asTerminalResult(
58
- output: AnvilToolOutput<'run_terminal_command'>,
59
- ): TerminalResult {
60
- assertSmoke(output.length === 1, 'terminal command returned no result')
61
- return output[0].value
62
- }
63
-
64
- function readString(value: TerminalResult, key: 'stdout' | 'stderr'): string {
65
- if (key === 'stdout') {
66
- return 'stdout' in value && typeof value.stdout === 'string'
67
- ? value.stdout
68
- : ''
69
- }
70
- return 'stderr' in value && typeof value.stderr === 'string'
71
- ? value.stderr
72
- : ''
73
- }
74
-
75
- function readExitCode(value: TerminalResult): number | null {
76
- return 'exitCode' in value && typeof value.exitCode === 'number'
77
- ? value.exitCode
78
- : null
79
- }
80
-
81
- function readMessage(value: TerminalResult): string {
82
- return 'message' in value && typeof value.message === 'string'
83
- ? value.message
84
- : ''
85
- }
86
-
87
- async function waitFor(
88
- condition: () => boolean,
89
- timeoutMs: number,
90
- failureMessage: string,
91
- ): Promise<void> {
92
- const deadline = Date.now() + timeoutMs
93
- while (!condition()) {
94
- if (Date.now() >= deadline) throw new Error(failureMessage)
95
- await Bun.sleep(WAIT_INTERVAL_MS)
96
- }
97
- }
98
-
99
- function writeResult(resultPath: string, result: SmokeResult): void {
100
- mkdirSync(path.dirname(resultPath), { recursive: true })
101
- writeFileSync(resultPath, JSON.stringify(result, null, 2))
102
- }
103
-
104
- async function destroyRenderer(renderer: CliRenderer): Promise<void> {
105
- if (renderer.isDestroyed) return
106
- await new Promise<void>((resolve, reject) => {
107
- const onDestroy = () => {
108
- clearTimeout(timeout)
109
- resolve()
110
- }
111
- const timeout = setTimeout(() => {
112
- renderer.removeListener('destroy', onDestroy)
113
- renderer.isDestroyed
114
- ? resolve()
115
- : reject(new Error('OpenTUI renderer did not finish destroying'))
116
- }, 2_000)
117
- renderer.once('destroy', onDestroy)
118
- renderer.destroy()
119
- })
120
- }
121
-
122
- /**
123
- * `markerPath` is written before the CONIN$ probe so the harness knows the descendant is alive and
124
- * can start injecting terminal reports for a leaked console to pick up. It cannot also stand for
125
- * "the probe finished" — it is written while the outcome is still unknown.
126
- *
127
- * `verdictPath` is written once the probe has resolved, down both branches, and is what makes the
128
- * abort deterministic. Waiting a fixed interval after the ready marker instead raced PowerShell's
129
- * startup on a loaded runner and aborted before the verdict reached stdout.
130
- *
131
- * The flush is load-bearing: the broker force-kills on Windows (`taskkill /f`), so a line still
132
- * sitting in PowerShell's own buffer is lost outright rather than drained from the pipe.
133
- */
134
- function createConsoleReaderScript(
135
- markerPath: string,
136
- verdictPath: string,
137
- ): string {
138
- const quotedMarker = markerPath.replace(/'/g, "''")
139
- const quotedVerdict = verdictPath.replace(/'/g, "''")
140
- return [
141
- `$ErrorActionPreference = 'Stop'`,
142
- `[System.IO.File]::WriteAllText('${quotedMarker}', 'ready')`,
143
- `try {`,
144
- ` $stream = [System.IO.File]::Open('CONIN$', [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)`,
145
- ` $buffer = New-Object byte[] 4096`,
146
- ` $count = $stream.Read($buffer, 0, $buffer.Length)`,
147
- ` if ($count -gt 0) {`,
148
- ` $hex = [System.BitConverter]::ToString($buffer, 0, $count).Replace('-', '')`,
149
- ` [Console]::Out.WriteLine('CONSOLE_LEAK_HEX:' + $hex)`,
150
- ` }`,
151
- `} catch {`,
152
- ` [Console]::Out.WriteLine('CONSOLE_UNAVAILABLE')`,
153
- `}`,
154
- `[Console]::Out.Flush()`,
155
- `[System.IO.File]::WriteAllText('${quotedVerdict}', 'done')`,
156
- `Start-Sleep -Seconds 20`,
157
- ].join('\r\n')
158
- }
159
-
160
- export async function runPackagedTerminalBrokerSmoke({
161
- resultPath,
162
- exchangeDir,
163
- }: {
164
- resultPath: string
165
- exchangeDir: string
166
- }): Promise<number> {
167
- const result: SmokeResult = {
168
- ok: false,
169
- platform: process.platform,
170
- stdinIsTTY: Boolean(process.stdin.isTTY),
171
- stdoutIsTTY: Boolean(process.stdout.isTTY),
172
- }
173
- let renderer: CliRenderer | null = null
174
-
175
- try {
176
- assertSmoke(process.platform === 'win32', 'broker smoke requires Windows')
177
- assertSmoke(
178
- process.stdin.isTTY && process.stdout.isTTY,
179
- 'broker smoke requires a native Windows console',
180
- )
181
-
182
- mkdirSync(exchangeDir, { recursive: true })
183
- const harnessReadyPath = path.join(exchangeDir, 'broker-ready')
184
- const reportsSentPath = path.join(exchangeDir, 'reports-sent')
185
- const consoleReaderReadyPath = path.join(
186
- exchangeDir,
187
- 'console-reader-ready',
188
- )
189
- const consoleReaderVerdictPath = path.join(
190
- exchangeDir,
191
- 'console-reader-verdict',
192
- )
193
- const consoleReaderScriptPath = path.join(exchangeDir, 'console-reader.ps1')
194
- const forbiddenSpawnPath = path.join(exchangeDir, 'broker-failure-spawned')
195
- writeFileSync(
196
- consoleReaderScriptPath,
197
- createConsoleReaderScript(
198
- consoleReaderReadyPath,
199
- consoleReaderVerdictPath,
200
- ),
201
- )
202
-
203
- startTerminalWatchdog()
204
- renderer = await createCliRenderer({
205
- backgroundColor: 'transparent',
206
- exitOnCtrlC: false,
207
- screenMode: 'alternate-screen',
208
- })
209
- installProcessCleanupHandlers(renderer)
210
-
211
- const controlWrites: string[] = []
212
- const controller = installTerminalProtocolController(renderer, {
213
- writeControl: (sequence) => {
214
- controlWrites.push(sequence)
215
- return writeTerminalControlSync(sequence)
216
- },
217
- })
218
- renderer.once('destroy', () => controller.dispose())
219
- const focusStates: boolean[] = []
220
- const unsubscribeFocus = controller.subscribeToFocus({
221
- onFocusChange: (focused) => focusStates.push(focused),
222
- })
223
-
224
- const simple = asTerminalResult(
225
- await runTerminalCommand({
226
- command: `printf 'COMMAND_OK'; printf 'COMMAND_ERR' >&2`,
227
- process_type: 'SYNC',
228
- cwd: process.cwd(),
229
- timeout_seconds: 10,
230
- terminalCommandBroker,
231
- }),
232
- )
233
- const simpleStdout = readString(simple, 'stdout')
234
- const simpleStderr = readString(simple, 'stderr')
235
- const simpleExitCode = readExitCode(simple)
236
- assertSmoke(simpleStdout === 'COMMAND_OK', 'simple command stdout was lost')
237
- assertSmoke(
238
- simpleStderr === 'COMMAND_ERR',
239
- 'simple command stderr was lost',
240
- )
241
- assertSmoke(
242
- simpleExitCode === 0,
243
- 'simple command did not exit successfully',
244
- )
245
- result.simpleCommand = {
246
- stdout: simpleStdout,
247
- stderr: simpleStderr,
248
- exitCode: simpleExitCode,
249
- }
250
-
251
- const overlapWriteStart = controlWrites.length
252
- const firstAbort = new AbortController()
253
- const readerCommand =
254
- `powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File ` +
255
- shellQuote(toBashPath(consoleReaderScriptPath))
256
- const firstRun = runTerminalCommand({
257
- command: readerCommand,
258
- process_type: 'SYNC',
259
- cwd: process.cwd(),
260
- timeout_seconds: 30,
261
- signal: firstAbort.signal,
262
- terminalCommandBroker,
263
- })
264
- const secondRun = runTerminalCommand({
265
- command: `sleep 5; printf 'SECOND_DONE'`,
266
- process_type: 'SYNC',
267
- cwd: process.cwd(),
268
- timeout_seconds: 15,
269
- terminalCommandBroker,
270
- })
271
-
272
- const mouseStayedEnabledDuringOverlap = renderer.useMouse === true
273
- assertSmoke(
274
- mouseStayedEnabledDuringOverlap,
275
- 'brokers changed mouse reporting',
276
- )
277
- assertSmoke(
278
- controlWrites.length === overlapWriteStart,
279
- 'brokers changed focus reporting',
280
- )
281
- await waitFor(
282
- () => existsSync(consoleReaderReadyPath),
283
- 10_000,
284
- 'console reader descendant did not start',
285
- )
286
- writeFileSync(harnessReadyPath, 'ready')
287
- await waitFor(
288
- () => existsSync(reportsSentPath),
289
- 10_000,
290
- 'native Windows harness did not inject terminal reports',
291
- )
292
- await waitFor(
293
- () => focusStates.includes(false) && focusStates.includes(true),
294
- 5_000,
295
- 'OpenTUI did not receive focus activity while commands ran',
296
- )
297
- // Only abort once the descendant has actually resolved its CONIN$ probe and flushed the
298
- // verdict. This sits after the reports-sent wait deliberately: a descendant that DID inherit a
299
- // console is blocked in $stream.Read until those reports arrive, and only then writes its leak
300
- // line and the verdict. A descendant with no console fails File.Open immediately, so if the
301
- // verdict never lands the open must have succeeded — which is itself the leak this asserts
302
- // against, hence the wording below rather than a bare timeout.
303
- // 10s to match the waits above, and because the abort has a real budget: the script exits on
304
- // its own after Start-Sleep -Seconds 20 and firstRun times out at 30, either of which would
305
- // turn the cancellation assertion below into a confusing failure. In practice the verdict is
306
- // already on disk by the time this runs — a console-free open throws at once.
307
- await waitFor(
308
- () => existsSync(consoleReaderVerdictPath),
309
- 10_000,
310
- 'console reader never resolved its CONIN$ probe — an open that blocks instead of failing means the descendant did have a Windows console',
311
- )
312
-
313
- firstAbort.abort()
314
- const first = asTerminalResult(await firstRun)
315
- const firstCancellationMessage = readMessage(first)
316
- assertSmoke(
317
- firstCancellationMessage.includes('aborted by the user'),
318
- 'first overlapping command did not report cancellation',
319
- )
320
- const mouseStayedEnabledAfterCancellation = renderer.useMouse === true
321
- assertSmoke(
322
- mouseStayedEnabledAfterCancellation,
323
- 'broker cancellation changed mouse reporting',
324
- )
325
-
326
- const second = asTerminalResult(await secondRun)
327
- const secondStdout = readString(second, 'stdout')
328
- assertSmoke(secondStdout === 'SECOND_DONE', 'overlapping command was lost')
329
- const mouseStayedEnabledAfterCompletion = renderer.useMouse === true
330
- const overlapWrites = controlWrites.slice(overlapWriteStart)
331
- assertSmoke(
332
- overlapWrites.length === 0,
333
- 'completion changed focus reporting',
334
- )
335
-
336
- const consoleReaderStdout = readString(first, 'stdout')
337
- assertSmoke(
338
- !consoleReaderStdout.includes('CONSOLE_LEAK_HEX:'),
339
- 'a command descendant read terminal reports from CONIN$',
340
- )
341
- assertSmoke(
342
- consoleReaderStdout.includes('CONSOLE_UNAVAILABLE'),
343
- 'the command descendant still had a Windows console',
344
- )
345
- result.overlap = {
346
- focusStates,
347
- controlWrites: overlapWrites,
348
- mouseStayedEnabledDuringOverlap,
349
- mouseStayedEnabledAfterCancellation,
350
- mouseStayedEnabledAfterCompletion,
351
- firstCancellationMessage,
352
- secondStdout,
353
- consoleReaderStdout,
354
- }
355
-
356
- // The Windows failure that motivated this gate appeared only after users
357
- // had run several agent commands. Exercise repeated packaged-broker stdio
358
- // setup after the driver has completed its time-sensitive report injection.
359
- const repeatedCommandCount = 64
360
- for (let index = 0; index < repeatedCommandCount; index++) {
361
- const marker = `REPEATED_${index}`
362
- const repeated = asTerminalResult(
363
- await runTerminalCommand({
364
- command: `printf '${marker}'`,
365
- process_type: 'SYNC',
366
- cwd: process.cwd(),
367
- timeout_seconds: 10,
368
- terminalCommandBroker,
369
- }),
370
- )
371
- assertSmoke(
372
- readString(repeated, 'stdout') === marker,
373
- `repeated broker command ${index} lost its output`,
374
- )
375
- assertSmoke(
376
- readExitCode(repeated) === 0,
377
- `repeated broker command ${index} failed`,
378
- )
379
- }
380
- result.repeatedCommands = { completed: repeatedCommandCount }
381
-
382
- let failureMessage = ''
383
- try {
384
- await runTerminalCommand({
385
- command: `printf 'spawned' > ${shellQuote(toBashPath(forbiddenSpawnPath))}`,
386
- process_type: 'SYNC',
387
- cwd: process.cwd(),
388
- timeout_seconds: 10,
389
- terminalCommandBroker: createTerminalCommandBroker({
390
- invocation: () => ({
391
- executable: path.join(
392
- exchangeDir,
393
- `missing-terminal-broker-${crypto.randomUUID()}.exe`,
394
- ),
395
- args: [],
396
- }),
397
- }),
398
- })
399
- throw new Error('command unexpectedly started without its broker')
400
- } catch (error) {
401
- failureMessage = error instanceof Error ? error.message : String(error)
402
- }
403
- result.brokerFailure = {
404
- message: failureMessage,
405
- commandStarted: existsSync(forbiddenSpawnPath),
406
- }
407
- assertSmoke(
408
- failureMessage.includes('Restart Freebuff'),
409
- 'broker failure did not include actionable recovery guidance',
410
- )
411
- assertSmoke(
412
- !existsSync(forbiddenSpawnPath),
413
- 'command spawned after broker startup failed',
414
- )
415
-
416
- unsubscribeFocus()
417
- controller.dispose()
418
- await destroyRenderer(renderer)
419
- result.ok = true
420
- writeResult(resultPath, result)
421
- return 0
422
- } catch (error) {
423
- result.error = error instanceof Error ? error.message : String(error)
424
- if (error instanceof Error && error.stack) result.stack = error.stack
425
- if (renderer && !renderer.isDestroyed) {
426
- try {
427
- await destroyRenderer(renderer)
428
- } catch (cleanupError) {
429
- result.error += `; cleanup failed: ${errorMessage(cleanupError)}`
430
- }
431
- }
432
- writeResult(resultPath, result)
433
- return 1
434
- }
435
- }
436
-
437
- function errorMessage(error: unknown): string {
438
- return error instanceof Error ? error.message : String(error)
439
- }
@@ -1,22 +0,0 @@
1
- import { afterEach, describe, expect, test } from 'bun:test'
2
-
3
- import { useChatStore } from '../chat-store'
4
-
5
- afterEach(() => {
6
- const store = useChatStore.getState()
7
- store.setInputFocused(true)
8
- store.setIsFocusSupported(false)
9
- })
10
-
11
- describe('chat store focus state', () => {
12
- test('chat reset preserves terminal focus and detected capabilities', () => {
13
- const store = useChatStore.getState()
14
- store.setInputFocused(false)
15
- store.setIsFocusSupported(true)
16
-
17
- store.reset()
18
-
19
- expect(useChatStore.getState().inputFocused).toBe(false)
20
- expect(useChatStore.getState().isFocusSupported).toBe(true)
21
- })
22
- })