@timurproko/a1 0.2.6 → 0.2.7-dev.1222

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 (419) hide show
  1. package/README.md +41 -3
  2. package/bin/automatic-update.js +7 -0
  3. package/bin/cli.js +4 -0
  4. package/bin/guardian.js +5 -0
  5. package/bin/tab-launch-context.d.ts +27 -0
  6. package/bin/tab-launch-context.js +94 -0
  7. package/bin/ui.js +107 -59
  8. package/dist/app/session-shell/clipboard-diagnostics.js +1 -1
  9. package/dist/app/session-shell/dialog-coordinator.d.ts +42 -0
  10. package/dist/app/session-shell/dialog-coordinator.js +133 -0
  11. package/dist/app/session-shell/dock-chrome.d.ts +34 -0
  12. package/dist/app/session-shell/dock-chrome.js +109 -0
  13. package/dist/app/session-shell/exit-notice.d.ts +1 -1
  14. package/dist/app/session-shell/exit-notice.js +1 -1
  15. package/dist/app/session-shell/extension-surface.d.ts +30 -0
  16. package/dist/app/session-shell/extension-surface.js +105 -0
  17. package/dist/app/session-shell/helper-pool.d.ts +3 -5
  18. package/dist/app/session-shell/helper-pool.js +3 -5
  19. package/dist/app/session-shell/input-surface-switch.d.ts +36 -0
  20. package/dist/app/session-shell/input-surface-switch.js +85 -0
  21. package/dist/app/session-shell/login-interaction.d.ts +27 -0
  22. package/dist/app/session-shell/login-interaction.js +91 -0
  23. package/dist/app/session-shell/prompt-submission.d.ts +48 -0
  24. package/dist/app/session-shell/prompt-submission.js +276 -0
  25. package/dist/app/session-shell/resident-tab-coordinator.d.ts +38 -0
  26. package/dist/app/session-shell/resident-tab-coordinator.js +77 -0
  27. package/dist/app/session-shell/response-copy-helper.js +21 -6
  28. package/dist/app/session-shell/response-copy-protocol.d.ts +1 -1
  29. package/dist/app/session-shell/response-copy-transport.d.ts +16 -6
  30. package/dist/app/session-shell/response-copy-transport.js +69 -17
  31. package/dist/app/session-shell/session-concern.d.ts +22 -0
  32. package/dist/app/session-shell/session-concern.js +29 -0
  33. package/dist/app/session-shell/session-lifecycle.d.ts +29 -0
  34. package/dist/app/session-shell/session-lifecycle.js +49 -0
  35. package/dist/app/session-shell/session-shell-root.d.ts +42 -6
  36. package/dist/app/session-shell/session-shell-root.js +197 -908
  37. package/dist/app/session-shell/session-shell.d.ts +3 -8
  38. package/dist/app/session-shell/session-shell.js +327 -835
  39. package/dist/app/session-shell/session-viewport-controller.d.ts +2 -1
  40. package/dist/app/session-shell/session-viewport-controller.js +41 -38
  41. package/dist/app/session-shell/settings-bindings.d.ts +17 -0
  42. package/dist/app/session-shell/settings-bindings.js +91 -0
  43. package/dist/app/session-shell/shell-editor-factory.d.ts +27 -0
  44. package/dist/app/session-shell/shell-editor-factory.js +105 -0
  45. package/dist/app/session-shell/shell-host.d.ts +6 -0
  46. package/dist/app/session-shell/shell-host.js +34 -7
  47. package/dist/app/session-shell/shell-layout.d.ts +64 -0
  48. package/dist/app/session-shell/shell-layout.js +18 -0
  49. package/dist/app/session-shell/suggestion-surface.d.ts +25 -0
  50. package/dist/app/session-shell/suggestion-surface.js +63 -0
  51. package/dist/app/session-shell/transcript-document.d.ts +78 -0
  52. package/dist/app/session-shell/transcript-document.js +365 -0
  53. package/dist/app/session-shell/viewport-layout.d.ts +31 -0
  54. package/dist/app/session-shell/viewport-layout.js +160 -0
  55. package/dist/app/session-shell/workflow-output.d.ts +33 -0
  56. package/dist/app/session-shell/workflow-output.js +174 -0
  57. package/dist/app/session-shell/workflow-router.d.ts +25 -0
  58. package/dist/app/session-shell/workflow-router.js +39 -0
  59. package/dist/cli/dispatch.d.ts +11 -1
  60. package/dist/cli/dispatch.js +79 -5
  61. package/dist/cli/tabs-request.d.ts +7 -0
  62. package/dist/cli/tabs-request.js +1 -0
  63. package/dist/cli/tabs.d.ts +14 -0
  64. package/dist/cli/tabs.js +151 -0
  65. package/dist/cli/version-stats.js +38 -3
  66. package/dist/composition/owned-settings.d.ts +12 -0
  67. package/dist/composition/owned-settings.js +36 -0
  68. package/dist/composition/owned-ui.d.ts +27 -28
  69. package/dist/composition/owned-ui.js +207 -153
  70. package/dist/composition/reference-selection-options.d.ts +3 -0
  71. package/dist/composition/reference-selection-options.js +16 -0
  72. package/dist/composition/resident-tab-bridge.d.ts +25 -0
  73. package/dist/composition/resident-tab-bridge.js +180 -0
  74. package/dist/composition/session-backend.d.ts +19 -0
  75. package/dist/composition/session-backend.js +1 -0
  76. package/dist/composition/session-runtime-registry.d.ts +20 -0
  77. package/dist/composition/session-runtime-registry.js +85 -0
  78. package/dist/composition/settings-route-host.d.ts +16 -2
  79. package/dist/composition/settings-route-host.js +42 -17
  80. package/dist/composition/settings-search-input.d.ts +9 -0
  81. package/dist/composition/settings-search-input.js +61 -0
  82. package/dist/composition/startup-route.d.ts +32 -0
  83. package/dist/composition/startup-route.js +72 -0
  84. package/dist/composition/utility-tab.d.ts +28 -0
  85. package/dist/composition/utility-tab.js +244 -0
  86. package/dist/contracts/owned-ui/index.d.ts +1 -1
  87. package/dist/contracts/owned-ui/model.d.ts +3 -0
  88. package/dist/contracts/owned-ui/session-backend.d.ts +3 -0
  89. package/dist/contracts/owned-ui/session-workflows.d.ts +11 -4
  90. package/dist/contracts/presentation/index.d.ts +11 -0
  91. package/dist/contracts/presentation/index.js +12 -0
  92. package/dist/features/launch/development-launch.js +6 -0
  93. package/dist/features/launch/index.d.ts +1 -1
  94. package/dist/features/launch/intent.d.ts +3 -1
  95. package/dist/features/launch/intent.js +7 -4
  96. package/dist/features/launch/profile-paths.js +4 -0
  97. package/dist/features/owned-ui/plus-menu-dialog.d.ts +22 -0
  98. package/dist/features/owned-ui/plus-menu-dialog.js +84 -0
  99. package/dist/features/owned-ui/project-trust-dialog.d.ts +1 -1
  100. package/dist/features/owned-ui/project-trust-dialog.js +6 -8
  101. package/dist/features/owned-ui/project-trust-prompt.d.ts +1 -0
  102. package/dist/features/owned-ui/project-trust-prompt.js +7 -3
  103. package/dist/features/owned-ui/reference-document-selection.d.ts +30 -0
  104. package/dist/features/owned-ui/reference-document-selection.js +179 -0
  105. package/dist/features/owned-ui/reference-screen-app.d.ts +6 -1
  106. package/dist/features/owned-ui/reference-screen-app.js +51 -10
  107. package/dist/features/owned-ui/settings-app.d.ts +13 -2
  108. package/dist/features/owned-ui/settings-app.js +136 -97
  109. package/dist/features/owned-ui/settings-search-input.d.ts +29 -0
  110. package/dist/features/owned-ui/settings-search-input.js +1 -0
  111. package/dist/features/prompt-history/index.d.ts +1 -1
  112. package/dist/features/prompt-history/paths.d.ts +2 -1
  113. package/dist/features/prompt-history/paths.js +10 -2
  114. package/dist/features/prompt-history/service.d.ts +5 -0
  115. package/dist/features/prompt-history/service.js +1 -1
  116. package/dist/features/resident-tab/auto-name.d.ts +11 -0
  117. package/dist/features/resident-tab/auto-name.js +44 -0
  118. package/dist/features/resident-tab/index.d.ts +5 -0
  119. package/dist/features/resident-tab/index.js +7 -0
  120. package/dist/features/resident-tab/shortcut-bindings-file.d.ts +8 -0
  121. package/dist/features/resident-tab/shortcut-bindings-file.js +40 -0
  122. package/dist/features/resident-tab/shortcut-declarations.d.ts +13 -0
  123. package/dist/features/resident-tab/shortcut-declarations.js +26 -0
  124. package/dist/features/resident-tab/shortcut-projection.d.ts +29 -0
  125. package/dist/features/resident-tab/shortcut-projection.js +64 -0
  126. package/dist/features/resident-tab/status-deriver.d.ts +10 -0
  127. package/dist/features/resident-tab/status-deriver.js +12 -0
  128. package/dist/foundation/launch-context/index.d.ts +12 -0
  129. package/dist/foundation/launch-context/index.js +26 -0
  130. package/dist/foundation/launch-guardian/exit-watcher.d.ts +14 -0
  131. package/dist/foundation/launch-guardian/exit-watcher.js +94 -0
  132. package/dist/foundation/launch-guardian/main.d.ts +7 -1
  133. package/dist/foundation/launch-guardian/main.js +60 -7
  134. package/dist/foundation/lifecycle/session-repository-context.js +16 -2
  135. package/dist/foundation/process-containment/{native-guardian-containment.d.ts → addon-containment.d.ts} +7 -5
  136. package/dist/foundation/process-containment/addon-containment.js +139 -0
  137. package/dist/foundation/process-containment/addon-process-inspector.d.ts +11 -0
  138. package/dist/foundation/process-containment/addon-process-inspector.js +36 -0
  139. package/dist/foundation/process-containment/addon.d.ts +42 -0
  140. package/dist/foundation/process-containment/addon.js +57 -0
  141. package/dist/foundation/process-containment/artifact.d.ts +1 -1
  142. package/dist/foundation/process-containment/artifact.js +6 -5
  143. package/dist/foundation/process-containment/contracts.d.ts +2 -0
  144. package/dist/foundation/process-containment/index.d.ts +4 -4
  145. package/dist/foundation/process-containment/index.js +3 -3
  146. package/dist/foundation/process-containment/native-process-inspector.d.ts +2 -1
  147. package/dist/foundation/process-containment/native-process-inspector.js +10 -10
  148. package/dist/foundation/release/automatic-update.d.ts +37 -0
  149. package/dist/foundation/release/automatic-update.js +265 -0
  150. package/dist/foundation/release/bootstrap.d.ts +7 -9
  151. package/dist/foundation/release/bootstrap.js +107 -24
  152. package/dist/foundation/release/cohort-state.d.ts +1 -1
  153. package/dist/foundation/release/cohort-state.js +1 -1
  154. package/dist/foundation/release/dependency-certification.js +54 -19
  155. package/dist/foundation/release/early-accent.d.ts +12 -0
  156. package/dist/foundation/release/early-accent.js +59 -0
  157. package/dist/foundation/release/index.d.ts +2 -2
  158. package/dist/foundation/release/index.js +2 -2
  159. package/dist/foundation/release/latest-release.d.ts +24 -2
  160. package/dist/foundation/release/latest-release.js +51 -1
  161. package/dist/foundation/release/progress-palette.generated.d.ts +137 -3
  162. package/dist/foundation/release/progress-palette.generated.js +137 -3
  163. package/dist/foundation/release/release-gc.d.ts +3 -0
  164. package/dist/foundation/release/release-gc.js +59 -8
  165. package/dist/foundation/release/release-store.d.ts +12 -0
  166. package/dist/foundation/release/release-store.js +124 -2
  167. package/dist/foundation/release/update-execution-lease.d.ts +48 -0
  168. package/dist/foundation/release/update-execution-lease.js +161 -0
  169. package/dist/foundation/release/update.d.ts +12 -7
  170. package/dist/foundation/release/update.js +281 -196
  171. package/dist/foundation/resident-tabs/bounded-host-command.d.ts +18 -0
  172. package/dist/foundation/resident-tabs/bounded-host-command.js +39 -0
  173. package/dist/foundation/resident-tabs/bridge-client.d.ts +70 -0
  174. package/dist/foundation/resident-tabs/bridge-client.js +321 -0
  175. package/dist/foundation/resident-tabs/doctor.d.ts +28 -0
  176. package/dist/foundation/resident-tabs/doctor.js +166 -0
  177. package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +27 -0
  178. package/dist/foundation/resident-tabs/draft-checkpoint.js +145 -0
  179. package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +36 -0
  180. package/dist/foundation/resident-tabs/ensure-terminal-host.js +151 -0
  181. package/dist/foundation/resident-tabs/fault-injection.d.ts +8 -0
  182. package/dist/foundation/resident-tabs/fault-injection.js +26 -0
  183. package/dist/foundation/resident-tabs/fixture-control.d.ts +7 -0
  184. package/dist/foundation/resident-tabs/fixture-control.js +35 -0
  185. package/dist/foundation/resident-tabs/host-entry.d.ts +1 -0
  186. package/dist/foundation/resident-tabs/host-entry.js +17 -0
  187. package/dist/foundation/resident-tabs/index.d.ts +12 -0
  188. package/dist/foundation/resident-tabs/index.js +6 -0
  189. package/dist/foundation/resident-tabs/maintenance.d.ts +39 -0
  190. package/dist/foundation/resident-tabs/maintenance.js +75 -0
  191. package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +34 -0
  192. package/dist/foundation/resident-tabs/progress-observation-schema.js +1 -0
  193. package/dist/foundation/resident-tabs/progress-observation.d.ts +4 -0
  194. package/dist/foundation/resident-tabs/progress-observation.js +150 -0
  195. package/dist/foundation/resident-tabs/prompt-journal.d.ts +63 -0
  196. package/dist/foundation/resident-tabs/prompt-journal.js +213 -0
  197. package/dist/foundation/resident-tabs/protocol.d.ts +12 -0
  198. package/dist/foundation/resident-tabs/protocol.js +195 -0
  199. package/dist/foundation/resident-tabs/recovery.d.ts +26 -0
  200. package/dist/foundation/resident-tabs/recovery.js +205 -0
  201. package/dist/foundation/resident-tabs/release-holds.d.ts +28 -0
  202. package/dist/foundation/resident-tabs/release-holds.js +75 -0
  203. package/dist/foundation/resident-tabs/routes.d.ts +5 -0
  204. package/dist/foundation/resident-tabs/routes.js +5 -0
  205. package/dist/foundation/resident-tabs/routing.d.ts +11 -0
  206. package/dist/foundation/resident-tabs/routing.js +10 -0
  207. package/dist/foundation/resident-tabs/session-sync.d.ts +14 -0
  208. package/dist/foundation/resident-tabs/session-sync.js +37 -0
  209. package/dist/foundation/resident-tabs/settings.d.ts +12 -0
  210. package/dist/foundation/resident-tabs/settings.js +58 -0
  211. package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +14 -0
  212. package/dist/foundation/resident-tabs/terminal-host-artifact.js +78 -0
  213. package/dist/foundation/resident-tabs/zip-archive.d.ts +9 -0
  214. package/dist/foundation/resident-tabs/zip-archive.js +56 -0
  215. package/dist/foundation/session-writer-lock/index.d.ts +30 -0
  216. package/dist/foundation/session-writer-lock/index.js +203 -0
  217. package/dist/foundation/startup/startup-descriptor.js +2 -2
  218. package/dist/foundation/terminal-cleanup/index.d.ts +1 -1
  219. package/dist/foundation/terminal-cleanup/index.js +1 -1
  220. package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +6 -0
  221. package/dist/foundation/terminal-cleanup/terminal-reset.js +6 -0
  222. package/dist/integrations/pi/components/editor-interaction.d.ts +2 -0
  223. package/dist/integrations/pi/components/modal-frame.d.ts +17 -1
  224. package/dist/integrations/pi/components/modal-frame.js +48 -9
  225. package/dist/integrations/pi/components/models-dialog.js +4 -52
  226. package/dist/integrations/pi/components/owned-editor-ux.d.ts +6 -1
  227. package/dist/integrations/pi/components/owned-editor-ux.js +138 -11
  228. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +4 -4
  229. package/dist/integrations/pi/components/resources/builtin-themes.js +4 -4
  230. package/dist/integrations/pi/components/share-operation-dialog.d.ts +2 -0
  231. package/dist/integrations/pi/components/share-operation-dialog.js +2 -1
  232. package/dist/integrations/pi/components/shell-editor-autocomplete.js +58 -36
  233. package/dist/integrations/pi/components/shell-extension-ui.js +79 -60
  234. package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
  235. package/dist/integrations/pi/components/shell-footer-status.js +21 -5
  236. package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
  237. package/dist/integrations/pi/components/shell-presenters-info.d.ts +5 -2
  238. package/dist/integrations/pi/components/shell-presenters-info.js +18 -4
  239. package/dist/integrations/pi/components/shell-presenters-transcript.js +4 -1
  240. package/dist/integrations/pi/components/shell-selectors-dialogs.js +5 -1
  241. package/dist/integrations/pi/components/shell-shared-facade.d.ts +12 -1
  242. package/dist/integrations/pi/components/skills-dialog.js +2 -2
  243. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
  244. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +17 -4
  245. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
  246. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
  247. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
  248. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
  249. package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
  250. package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
  251. package/dist/integrations/pi/components/upstream/components/extension-selector.js +1 -1
  252. package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
  253. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +8 -6
  254. package/dist/integrations/pi/components/upstream/components/owned-editor.js +16 -9
  255. package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
  256. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +4 -4
  257. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +2 -2
  258. package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
  259. package/dist/integrations/pi/components/upstream/components/session-footer.js +31 -25
  260. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
  261. package/dist/integrations/pi/components/upstream/components/session-selector.js +8 -7
  262. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
  263. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
  264. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +2 -2
  265. package/dist/integrations/pi/components/upstream/components/status-indicator.js +3 -3
  266. package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
  267. package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
  268. package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +8 -7
  269. package/dist/integrations/pi/components/upstream/components/thinking-selector.js +10 -9
  270. package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +2 -6
  271. package/dist/integrations/pi/components/upstream/components/tool-execution.js +103 -101
  272. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +9 -9
  273. package/dist/integrations/pi/components/upstream/components/tree-selector.js +13 -21
  274. package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
  275. package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
  276. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +2 -2
  277. package/dist/integrations/pi/components/upstream/history/editor-core.js +7 -5
  278. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
  279. package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
  280. package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
  281. package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
  282. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
  283. package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
  284. package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
  285. package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
  286. package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +1 -1
  287. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
  288. package/dist/integrations/pi/components/upstream/theme/theme.d.ts +5 -0
  289. package/dist/integrations/pi/components/upstream/theme/theme.js +29 -2
  290. package/dist/integrations/pi/engine/adapter.d.ts +5 -77
  291. package/dist/integrations/pi/engine/adapter.js +95 -394
  292. package/dist/integrations/pi/engine/command-dispatch.d.ts +13 -0
  293. package/dist/integrations/pi/engine/command-dispatch.js +57 -0
  294. package/dist/integrations/pi/engine/host.js +2 -2
  295. package/dist/integrations/pi/engine/offline-settings-port.d.ts +23 -0
  296. package/dist/integrations/pi/engine/offline-settings-port.js +53 -0
  297. package/dist/integrations/pi/engine/pi-settings-metadata.json +14 -2
  298. package/dist/integrations/pi/engine/ports.d.ts +56 -0
  299. package/dist/integrations/pi/engine/ports.js +93 -0
  300. package/dist/integrations/pi/engine/prompt-suggestions.d.ts +1 -0
  301. package/dist/integrations/pi/engine/prompt-suggestions.js +40 -0
  302. package/dist/integrations/pi/engine/resources/changelog.json +4 -4
  303. package/dist/integrations/pi/engine/runtime-integration.js +102 -29
  304. package/dist/integrations/pi/engine/session-runtime.d.ts +0 -6
  305. package/dist/integrations/pi/engine/session-runtime.js +13 -5
  306. package/dist/integrations/pi/engine/session-selection.d.ts +3 -0
  307. package/dist/integrations/pi/engine/session-selection.js +45 -9
  308. package/dist/integrations/pi/engine/settings-bridge.d.ts +5 -0
  309. package/dist/integrations/pi/engine/settings-bridge.js +15 -0
  310. package/dist/integrations/pi/engine/settings-port.js +11 -15
  311. package/dist/integrations/pi/engine/view-state.d.ts +42 -0
  312. package/dist/integrations/pi/engine/view-state.js +126 -0
  313. package/dist/integrations/pi/engine/workflow-contexts.js +10 -1
  314. package/dist/integrations/pi/engine/workflow-runner.js +74 -5
  315. package/dist/integrations/pi/engine/workflow-support.d.ts +12 -0
  316. package/dist/integrations/pi/engine/workflow-support.js +36 -0
  317. package/dist/integrations/pi/engine/workflows.d.ts +3 -1
  318. package/dist/integrations/pi/engine/workflows.js +1 -0
  319. package/dist/integrations/pi/startup-public.js +257 -310
  320. package/dist/integrations/pi/startup-public.manifest.json +564 -440
  321. package/dist/integrations/pi/tui-runtime/adapter.d.ts +6 -0
  322. package/dist/integrations/pi/tui-runtime/adapter.js +32 -1
  323. package/dist/integrations/pi/tui-runtime/contracts.d.ts +5 -0
  324. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +12 -1
  325. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +31 -2
  326. package/dist/native/darwin-arm64/manifest.json +10 -7
  327. package/dist/native/darwin-arm64/process-guardian.node +0 -0
  328. package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +10500 -0
  329. package/dist/native/darwin-arm64/terminal-host.manifest.json +46 -0
  330. package/dist/native/darwin-arm64/terminal-host.node +0 -0
  331. package/dist/native/darwin-x64/manifest.json +23 -0
  332. package/dist/native/darwin-x64/process-guardian.node +0 -0
  333. package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10737 -0
  334. package/dist/native/darwin-x64/terminal-host.manifest.json +46 -0
  335. package/dist/native/darwin-x64/terminal-host.node +0 -0
  336. package/dist/native/linux-x64/manifest.json +10 -7
  337. package/dist/native/linux-x64/process-guardian.node +0 -0
  338. package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +11226 -0
  339. package/dist/native/linux-x64/terminal-host.manifest.json +46 -0
  340. package/dist/native/linux-x64/terminal-host.node +0 -0
  341. package/dist/native/win32-x64/manifest.json +10 -7
  342. package/dist/native/win32-x64/process-guardian.node +0 -0
  343. package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10757 -0
  344. package/dist/native/win32-x64/terminal-host.manifest.json +46 -0
  345. package/dist/native/win32-x64/terminal-host.node +0 -0
  346. package/dist/product-identity.d.ts +3 -3
  347. package/dist/product-identity.js +4 -4
  348. package/dist/product-identity.json +16 -2
  349. package/dist/runtime-payload-inventory.json +6330 -6677
  350. package/dist/ui/apps/host.d.ts +2 -0
  351. package/dist/ui/apps/host.js +7 -1
  352. package/dist/ui/components/dialog-panel.d.ts +17 -8
  353. package/dist/ui/components/dialog-panel.js +117 -41
  354. package/dist/ui/components/index.d.ts +5 -5
  355. package/dist/ui/components/index.js +4 -4
  356. package/dist/ui/components/line-input.d.ts +4 -1
  357. package/dist/ui/components/line-input.js +3 -1
  358. package/dist/ui/components/prompt-input.d.ts +11 -8
  359. package/dist/ui/components/prompt-input.js +15 -13
  360. package/dist/ui/components/scrollbar.d.ts +1 -1
  361. package/dist/ui/components/scrollbar.js +1 -1
  362. package/dist/ui/components/selection-copy.d.ts +3 -3
  363. package/dist/ui/components/selection-copy.js +16 -1
  364. package/dist/ui/components/spans.js +2 -2
  365. package/dist/ui/components/submitted-prompt.d.ts +9 -6
  366. package/dist/ui/components/submitted-prompt.js +20 -12
  367. package/dist/ui/components/surface.js +4 -2
  368. package/dist/ui/components/text-selection.d.ts +1 -2
  369. package/dist/ui/components/text-selection.js +5 -2
  370. package/dist/ui/components/text.d.ts +3 -6
  371. package/dist/ui/components/text.js +6 -8
  372. package/dist/ui/components/transcript-viewport.d.ts +9 -2
  373. package/dist/ui/components/transcript-viewport.js +179 -58
  374. package/dist/ui/settings/declarations.d.ts +90 -16
  375. package/dist/ui/settings/declarations.js +67 -14
  376. package/dist/ui/settings/early-accent.d.ts +81 -0
  377. package/dist/ui/settings/early-accent.js +50 -0
  378. package/dist/ui/settings/index.d.ts +4 -2
  379. package/dist/ui/settings/index.js +2 -1
  380. package/dist/ui/settings/manager.d.ts +16 -3
  381. package/dist/ui/settings/manager.js +122 -33
  382. package/dist/ui/settings/migrations.d.ts +6 -0
  383. package/dist/ui/settings/migrations.js +73 -0
  384. package/dist/ui/settings/profile-document.d.ts +26 -0
  385. package/dist/ui/settings/profile-document.js +164 -0
  386. package/dist/ui/settings/progress-palette.generated.d.ts +139 -0
  387. package/dist/ui/settings/progress-palette.generated.js +139 -0
  388. package/dist/ui/settings/sections.d.ts +4 -0
  389. package/dist/ui/settings/sections.js +9 -3
  390. package/docs/architecture/boundaries.md +24 -9
  391. package/docs/architecture/evidence/resident-tabs/linux-x64.md +37 -0
  392. package/docs/architecture/evidence/resident-tabs/macos-arm64.md +36 -0
  393. package/docs/architecture/evidence/resident-tabs/macos-x64.md +35 -0
  394. package/docs/architecture/evidence/resident-tabs/windows-x64.md +36 -0
  395. package/docs/architecture/internal-naming.md +3 -1
  396. package/docs/architecture/process-guardian-provenance.md +18 -10
  397. package/docs/architecture/project-structure.md +8 -0
  398. package/docs/architecture/resident-tabs-requirements.md +18 -0
  399. package/docs/architecture/resident-tabs.md +649 -0
  400. package/docs/architecture/response-copy-delivery.md +1 -1
  401. package/docs/architecture/terminal-host-proof-gate.md +2 -0
  402. package/docs/architecture/terminal-host-provenance.md +16 -4
  403. package/docs/architecture/tool-image-presentation.md +2 -1
  404. package/docs/architecture/toolchain.md +11 -9
  405. package/docs/ci-release-runbook.md +14 -7
  406. package/docs/features/launch-profiles.md +11 -8
  407. package/docs/features/prompt-history.md +41 -20
  408. package/docs/manual-resident-tabs-acceptance.md +51 -0
  409. package/docs/openspec-archive-automation.md +49 -22
  410. package/docs/validation.md +49 -9
  411. package/package.json +19 -6
  412. package/dist/foundation/process-containment/darwin-process-inspector.d.ts +0 -5
  413. package/dist/foundation/process-containment/darwin-process-inspector.js +0 -7
  414. package/dist/foundation/process-containment/native-guardian-containment.js +0 -152
  415. package/dist/foundation/process-containment/windows-process-inspector.d.ts +0 -19
  416. package/dist/foundation/process-containment/windows-process-inspector.js +0 -56
  417. package/dist/native/darwin-arm64/process-guardian +0 -0
  418. package/dist/native/linux-x64/process-guardian +0 -0
  419. package/dist/native/win32-x64/process-guardian.exe +0 -0
@@ -26,6 +26,7 @@ export interface SessionViewportInputResult {
26
26
  readonly data: string;
27
27
  readonly consumed: boolean;
28
28
  readonly copySelection?: SelectionCopySnapshot;
29
+ readonly copyLastMessage?: true;
29
30
  }
30
31
  /**
31
32
  * Owns the stateful interaction policy of the bare-A1 session viewport. The
@@ -64,7 +65,7 @@ export declare class SessionViewportController {
64
65
  setOverlaySurfaces(surfaces: readonly PiTuiPointerSurface[] | null): void;
65
66
  get inputGeometryReady(): boolean;
66
67
  compose(input: Omit<TranscriptViewportFrameInput, "pointerPosition">): TranscriptViewportFrame;
67
- composeDockOnly(dockRows: readonly string[], width: number, height: number): TranscriptViewportFrame | null;
68
+ composeDockOnly(dockRows: readonly string[], width: number, height: number, copyableDockRows?: TranscriptViewportFrameInput["copyableDockRows"]): TranscriptViewportFrame | null;
68
69
  /** Returns true when document wrapping may have changed. */
69
70
  setConfig(config: OwnedUiViewportSettings): boolean;
70
71
  resumeFollowing(): void;
@@ -22,6 +22,7 @@ export class SessionViewportController {
22
22
  #pasteDiagnosticRequest = 0;
23
23
  #viewport = new TranscriptViewport();
24
24
  #config = {
25
+ timeFormat: "8:00 PM",
25
26
  scrollbarAppearance: "auto",
26
27
  scrollbarStyle: "thin",
27
28
  scrollbarSpeed: "normal",
@@ -165,16 +166,18 @@ export class SessionViewportController {
165
166
  }
166
167
  return frame;
167
168
  }
168
- composeDockOnly(dockRows, width, height) {
169
- return this.#viewport.composeDockOnly(dockRows, width, height);
169
+ composeDockOnly(dockRows, width, height, copyableDockRows = []) {
170
+ return this.#viewport.composeDockOnly(dockRows, width, height, copyableDockRows);
170
171
  }
171
172
  /** Returns true when document wrapping may have changed. */
172
173
  setConfig(config) {
173
- const appearanceChanged = config.scrollbarAppearance !== this.#config.scrollbarAppearance;
174
- this.#config = config;
175
- this.#viewport.setConfig(config);
174
+ const normalized = { ...config, timeFormat: config.timeFormat ?? "8:00 PM" };
175
+ const layoutChanged = normalized.scrollbarAppearance !== this.#config.scrollbarAppearance
176
+ || normalized.timeFormat !== this.#config.timeFormat;
177
+ this.#config = normalized;
178
+ this.#viewport.setConfig(normalized);
176
179
  this.#requestRender();
177
- return appearanceChanged;
180
+ return layoutChanged;
178
181
  }
179
182
  resumeFollowing() {
180
183
  if (!this.#enabled)
@@ -250,15 +253,13 @@ export class SessionViewportController {
250
253
  pasteRequest = this.#nextPasteDiagnosticRequest();
251
254
  this.#emitPasteRoute(pasteRequest, "shortcut-received");
252
255
  }
253
- // Compatibility: Pi components share one keybinding manager. Restore bare A1's aliases
254
- // before the focused vanilla editor handles this input.
256
+ // Invariant: activate A1 aliases before editor input.
255
257
  if (editorActive)
256
258
  this.#editor.activateKeybindings();
257
259
  // Protocol: bracketed paste is opaque input, even if its text resembles mouse reports.
258
260
  if (data.startsWith("\u001b[200~"))
259
261
  return { data, consumed: false };
260
- // Platform: handle the physical paste chord at the pre-input boundary. Windows
261
- // terminals vary between forwarding Ctrl+V and terminal-owned bracketed paste.
262
+ // Platform: Windows terminals may forward Ctrl+V or terminal-owned paste.
262
263
  if (editorActive && this.#editor.matchesTerminalKey(data, "ctrl+v")) {
263
264
  pasteRequest ??= this.#nextPasteDiagnosticRequest();
264
265
  if (data !== "\u0016")
@@ -274,8 +275,7 @@ export class SessionViewportController {
274
275
  this.#requestHyperlinkCleanup();
275
276
  this.#requestRender();
276
277
  }
277
- // Invariant: content shortcuts never reach the prompt, even before the first frame
278
- // or when scrolling is a no-op. Plain Home/End remain editor line navigation.
278
+ // Invariant: viewport shortcuts skip the prompt; Home/End do not.
279
279
  if (editorActive && allowWheel && this.#editor.matchesTerminalKey(data, "ctrl+home")) {
280
280
  if (this.#viewport.scrollTo(0, now)) {
281
281
  this.#scheduleActivityExpiry();
@@ -291,6 +291,9 @@ export class SessionViewportController {
291
291
  }
292
292
  return { data: "", consumed: true };
293
293
  }
294
+ if (data === "\u0018" && editorActive && !this.#viewport.hasSelection && !this.#editor.hasSelection()) {
295
+ return { data: "", consumed: true, copyLastMessage: true };
296
+ }
294
297
  if (this.#viewport.frame === null) {
295
298
  // Invariant: a not-yet-painted A1 screen is not Pi's selection surface.
296
299
  return routeMouseInput(data, event => {
@@ -301,23 +304,18 @@ export class SessionViewportController {
301
304
  return event.kind === "motion" || event.kind === "release" || (event.kind === "press" && event.button === 0);
302
305
  });
303
306
  }
304
- if (data === "\u0003") {
305
- if (editorActive && this.#editor.hasSelection()) {
306
- if (this.#viewport.clearSelection())
307
- this.#requestRender();
308
- }
309
- else if (this.#viewport.hasSelection) {
310
- const copySelection = this.#viewport.captureSelectedText();
311
- this.#viewport.clearSelection();
312
- this.#stopSelectionAutoScroll();
313
- this.#requestRender();
314
- return copySelection === null
315
- ? { data: "", consumed: true }
316
- : { data: "", consumed: true, copySelection };
317
- }
307
+ if ((data === "\u0003" || data === "\u0018") && this.#viewport.hasSelection) {
308
+ // Invariant: the newest frame selection wins over an older editor selection.
309
+ const copySelection = this.#viewport.captureSelectedText();
310
+ this.#viewport.clearSelection();
311
+ this.#stopSelectionAutoScroll();
312
+ this.#requestRender();
313
+ return copySelection === null
314
+ ? { data: "", consumed: true }
315
+ : { data: "", consumed: true, copySelection };
318
316
  }
319
- const previousPrompt = SHIFT_UP_INPUTS.has(data) || this.#editor.matchesTerminalKey(data, "alt+home");
320
- if (editorActive && allowWheel && (previousPrompt || SHIFT_DOWN_INPUTS.has(data))) {
317
+ const previousPrompt = PROMPT_UP_INPUTS.has(data) || this.#editor.matchesTerminalKey(data, "alt+home");
318
+ if (editorActive && allowWheel && (previousPrompt || PROMPT_DOWN_INPUTS.has(data))) {
321
319
  const scrolled = previousPrompt
322
320
  ? this.#viewport.scrollToPreviousPrompt(now)
323
321
  : this.#viewport.scrollToNextPrompt(now);
@@ -339,8 +337,7 @@ export class SessionViewportController {
339
337
  const hits = frame.hits;
340
338
  const overModal = this.#modalAt(event.column, event.row);
341
339
  const wheel = event.kind === "wheel-up" || event.kind === "wheel-down";
342
- // Invariant: ownership is latched for a complete gesture. Modal reports bypass the outer
343
- // fullscreen selection layer without ever invoking the hidden ordinary editor.
340
+ // Invariant: latch each gesture to one surface.
344
341
  if (this.#pointerOwner === "drain" || !this.inputGeometryReady) {
345
342
  if (event.kind === "release")
346
343
  this.#pointerOwner = undefined;
@@ -381,8 +378,7 @@ export class SessionViewportController {
381
378
  const wasOverBottom = hits.bottom !== null && previousPointer !== undefined
382
379
  && previousPointer.row === hits.bottom.row
383
380
  && previousPointer.column >= hits.bottom.columnStart && previousPointer.column <= hits.bottom.columnEnd;
384
- // Invariant: every report locates the pointer, independently of which surface owns the action.
385
- // Keep this location while the control is hidden; composition resolves its next hit region.
381
+ // Invariant: every report updates the pointer position.
386
382
  this.#pointerPosition = { column: event.column, row: event.row };
387
383
  repaint ||= wasOverBottom !== overBottom;
388
384
  const wasOverTailControl = tailControl !== undefined && previousPointer !== undefined
@@ -401,7 +397,7 @@ export class SessionViewportController {
401
397
  this.#viewport.setRailHovered(overRail);
402
398
  this.#viewport.setStickyHovered(overSticky);
403
399
  repaint = true;
404
- if (editorActive && this.#editor.ownsPointer() && this.#editorPointerFrame !== undefined) {
400
+ if (editorActive && this.#editorPointerSelecting && this.#editorPointerFrame !== undefined) {
405
401
  this.#editor.handlePointer({
406
402
  kind: "motion",
407
403
  button: event.button,
@@ -417,6 +413,12 @@ export class SessionViewportController {
417
413
  if (event.column === pendingEditorClick.column && event.row === pendingEditorClick.row)
418
414
  return true;
419
415
  this.#pendingEditorClick = undefined;
416
+ const editorFrame = editorActive ? this.#editorPointerFrame : undefined;
417
+ if (editorFrame !== undefined && this.#editor.handlePointer({ kind: "press", button: 0, column: pendingEditorClick.column, row: pendingEditorClick.row - editorFrame.rowStart + 1 })) {
418
+ this.#editorPointerSelecting = true;
419
+ this.#editor.handlePointer({ kind: "motion", button: event.button, column: event.column, row: event.row - editorFrame.rowStart + 1 });
420
+ return true;
421
+ }
420
422
  this.#viewport.pressSelection(pendingEditorClick.column, pendingEditorClick.row, now, { continueMultiClick: false });
421
423
  this.#viewport.extendSelection(event.column, event.row, now, false);
422
424
  this.#updateSelectionAutoScroll(event.column, event.row, hits.viewportHeight, frame.rows.length);
@@ -507,8 +509,7 @@ export class SessionViewportController {
507
509
  }
508
510
  if (event.row >= 1 && event.row <= frame.rows.length && event.column <= frame.descriptor.width) {
509
511
  if (editorFrame !== undefined && event.row >= editorFrame.rowStart && event.row <= editorFrame.rowEnd) {
510
- // Invariant: no-drag prompt clicks remain visually editor-owned. Distinct
511
- // motion promotes from this exact origin into complete-frame selection.
512
+ // Invariant: no-drag clicks remain editor-owned; first motion latches an editor drag.
512
513
  this.#pendingEditorClick = { column: event.column, row: event.row };
513
514
  }
514
515
  else {
@@ -521,7 +522,7 @@ export class SessionViewportController {
521
522
  return true;
522
523
  }
523
524
  if (event.kind === "release") {
524
- if (editorActive && this.#editor.ownsPointer() && this.#editorPointerFrame !== undefined) {
525
+ if (editorActive && this.#editorPointerSelecting && this.#editorPointerFrame !== undefined) {
525
526
  const wasEditorSelecting = this.#editorPointerSelecting;
526
527
  this.#editor.handlePointer({
527
528
  kind: "release",
@@ -658,5 +659,7 @@ export class SessionViewportController {
658
659
  }
659
660
  const SELECTION_AUTO_SCROLL_INTERVAL_MS = 30;
660
661
  const EDITOR_LINK_DELETION_INPUTS = new Set(["\b", "\u007f", "\u001b[3~"]);
661
- const SHIFT_UP_INPUTS = new Set(["\u001b[1;2A"]);
662
- const SHIFT_DOWN_INPUTS = new Set(["\u001b[1;2B"]);
662
+ // Platform: Windows Terminal may consume Shift+Arrow for native selection. Ctrl+Arrow matches
663
+ // solo A1's Windows binding while retaining Shift+Arrow whenever the terminal delivers it.
664
+ const PROMPT_UP_INPUTS = new Set(["\u001b[1;2A", "\u001b[1;5A"]);
665
+ const PROMPT_DOWN_INPUTS = new Set(["\u001b[1;2B", "\u001b[1;5B"]);
@@ -0,0 +1,17 @@
1
+ import type { OwnedUiSessionSettingsPort, OwnedUiSessionSettingsSnapshot } from "../../contracts/owned-ui/index.js";
2
+ import type { OwnedUiPresenterTerminal } from "./shell-host.js";
3
+ import type { OwnedUiSessionShellRoot } from "./session-shell-root.js";
4
+ /** What the session's live setting effects reach: terminal modes, root presentation, and the presenter's progress flag. */
5
+ export interface SessionSettingsTargets {
6
+ readonly terminal: Pick<OwnedUiPresenterTerminal, "setHardwareCursor" | "setClearOnShrink" | "setWheelScrollLines">;
7
+ readonly root: Pick<OwnedUiSessionShellRoot, "setEditorPaddingX" | "setAutocompleteMaxVisible" | "setOutputPad" | "setHideThinkingBlock" | "setMermaidRenderingMode" | "setImagePresentation" | "setFullscreenCopyOnSelect">;
8
+ setTerminalProgress(enabled: boolean): void;
9
+ }
10
+ /**
11
+ * Applies the snapshot's presentation settings, then binds every live setting effect the session
12
+ * owns, one owner at a time. The returned function releases the owners in reverse; a failed bind
13
+ * releases the owners already bound before it throws.
14
+ */
15
+ export declare function bindSessionSettings(settings: Pick<OwnedUiSessionSettingsPort, "bindOwner" | "productMode">, snapshot: OwnedUiSessionSettingsSnapshot, targets: SessionSettingsTargets, options: {
16
+ readonly customViewport: boolean;
17
+ }): () => void;
@@ -0,0 +1,91 @@
1
+ const isBoolean = (value) => typeof value === "boolean";
2
+ const isNumber = (value) => typeof value === "number";
3
+ const isOutputPad = (value) => value === 0 || value === 1;
4
+ const isMermaidMode = (value) => value === "off" || value === "final" || value === "streaming";
5
+ const isImageWidth = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 1;
6
+ const isWheelDistance = (value) => value === "auto" || typeof value === "number" && Number.isSafeInteger(value) && value >= 1 && value <= 100;
7
+ function snapshotValue(snapshot, key) {
8
+ const values = snapshot;
9
+ return values[key];
10
+ }
11
+ /** One validated setting; `seeded` also installs the snapshot's value at bind time. */
12
+ function setting(owner, key, invalid, accepts, apply, seeded = true) {
13
+ return {
14
+ owner,
15
+ key,
16
+ live: value => {
17
+ if (!accepts(value))
18
+ throw new TypeError(invalid);
19
+ apply(value);
20
+ },
21
+ ...(seeded ? {
22
+ seed: (snapshot) => {
23
+ const value = snapshotValue(snapshot, key);
24
+ if (accepts(value))
25
+ apply(value);
26
+ },
27
+ } : {}),
28
+ };
29
+ }
30
+ function settingBindings(targets, snapshot, customViewport, bare) {
31
+ const { root, terminal } = targets;
32
+ let showImages = snapshot.showImages;
33
+ let imageWidthCells = snapshot.imageWidthCells;
34
+ const presentImages = () => root.setImagePresentation(showImages, imageWidthCells);
35
+ return [
36
+ // Invariant: bare A1 prints only the resume hint at exit, so the pinned exit-output
37
+ // choice is hidden there and cannot be bound; the comparison profile binds and honors it.
38
+ ...(bare ? [] : [{ owner: "shutdown", key: "fullscreenExitOutput", live: () => { } }]),
39
+ setting("terminal", "showHardwareCursor", "Hardware cursor setting is invalid", isBoolean, value => terminal.setHardwareCursor(value)),
40
+ setting("terminal", "clearOnShrink", "Clear-on-shrink setting is invalid", isBoolean, value => terminal.setClearOnShrink(value)),
41
+ setting("terminal", "showTerminalProgress", "Terminal progress setting is invalid", isBoolean, value => targets.setTerminalProgress(value)),
42
+ setting("shell", "editorPaddingX", "Editor padding is invalid", isNumber, value => root.setEditorPaddingX(value)),
43
+ setting("shell", "autocompleteMaxVisible", "Autocomplete maximum is invalid", isNumber, value => root.setAutocompleteMaxVisible(value)),
44
+ setting("shell", "outputPad", "Output padding is invalid", isOutputPad, value => root.setOutputPad(value)),
45
+ setting("shell", "hideThinkingBlock", "Thinking-block visibility is invalid", isBoolean, value => root.setHideThinkingBlock(value)),
46
+ setting("shell", "mermaidRenderingMode", "Mermaid mode is invalid", isMermaidMode, value => root.setMermaidRenderingMode(value)),
47
+ setting("shell", "showImages", "Image visibility is invalid", isBoolean, value => { showImages = value; presentImages(); }, false),
48
+ setting("shell", "imageWidthCells", "Image width is invalid", isImageWidth, value => { imageWidthCells = value; presentImages(); }, false),
49
+ { owner: null, key: "imageWidthCells", live: () => { }, seed: presentImages },
50
+ // Invariant: the custom viewport owns copy-on-select; the pinned comparison profile keeps Pi's wheel distance.
51
+ customViewport
52
+ ? setting("shell", "fullscreenCopyOnSelect", "Fullscreen copy-on-select setting is invalid", isBoolean, value => root.setFullscreenCopyOnSelect(value))
53
+ : setting("shell", "fullscreenWheelScrollLines", "Fullscreen wheel-scroll distance is invalid", isWheelDistance, value => terminal.setWheelScrollLines(value), false),
54
+ ...(customViewport ? [] : [{
55
+ owner: null,
56
+ key: "fullscreenCopyOnSelect",
57
+ live: () => { },
58
+ seed: (initial) => root.setFullscreenCopyOnSelect(initial.fullscreenCopyOnSelect),
59
+ }]),
60
+ ];
61
+ }
62
+ /**
63
+ * Applies the snapshot's presentation settings, then binds every live setting effect the session
64
+ * owns, one owner at a time. The returned function releases the owners in reverse; a failed bind
65
+ * releases the owners already bound before it throws.
66
+ */
67
+ export function bindSessionSettings(settings, snapshot, targets, options) {
68
+ const bindings = settingBindings(targets, snapshot, options.customViewport, settings.productMode === "bare");
69
+ for (const binding of bindings)
70
+ binding.seed?.(snapshot);
71
+ const owners = [...new Set(bindings.flatMap(binding => binding.owner === null ? [] : [binding.owner]))];
72
+ const releases = [];
73
+ const release = () => {
74
+ for (const unbind of releases.splice(0).reverse())
75
+ unbind();
76
+ };
77
+ try {
78
+ for (const owner of owners) {
79
+ const handlers = {};
80
+ for (const binding of bindings.filter(candidate => candidate.owner === owner)) {
81
+ handlers[binding.key] = { apply: value => binding.live(value) };
82
+ }
83
+ releases.push(settings.bindOwner(owner, handlers));
84
+ }
85
+ }
86
+ catch (error) {
87
+ release();
88
+ throw error;
89
+ }
90
+ return release;
91
+ }
@@ -0,0 +1,27 @@
1
+ import { type PiShellEditorOptions, type PiShellEditorPort } from "../../integrations/pi/components/shell-shared-facade.js";
2
+ import type { PasteEvent, PasteSource } from "./paste-protocol.js";
3
+ import type { PromptChipStore } from "./prompt-chips.js";
4
+ /** The shell callbacks the editor is wired to; the editor receives the whole object as its own options. */
5
+ export type ShellEditorHandlers = Omit<PiShellEditorOptions, "onChange" | "onToolsExpand" | "keybindingProfile"> & {
6
+ readonly requestRender: (force?: boolean) => void;
7
+ readonly onEditorChange?: (text: string) => void;
8
+ readonly captureClipboardPaste?: () => PasteSource;
9
+ readonly pasteDiagnostics?: (event: PasteEvent) => void;
10
+ };
11
+ export interface ShellEditorPorts {
12
+ readonly handlers: ShellEditorHandlers;
13
+ readonly customViewport: boolean;
14
+ readonly cwd: string;
15
+ readonly agentDir?: string;
16
+ readonly promptChips: PromptChipStore;
17
+ /** True while a pointer drag selects editor text, which paints links as plain underlines. */
18
+ readonly editorPointerSelecting: () => boolean;
19
+ /** The next payload-free paste diagnostic id, shared with the viewport's own paste diagnostics. */
20
+ readonly nextPasteDiagnosticRequest: () => number;
21
+ readonly toggleToolsExpanded: () => void;
22
+ }
23
+ /**
24
+ * Builds the session's prompt editor: chip-aware paste, selection, and hyperlink decoration over
25
+ * the Pi editor, plus bare A1's prompt presentation and terminal paste diagnostics.
26
+ */
27
+ export declare function createShellEditor(ports: ShellEditorPorts): PiShellEditorPort;
@@ -0,0 +1,105 @@
1
+ import { caretCell } from "../../ui/components/line-input.js";
2
+ import { PromptInput } from "../../ui/components/prompt-input.js";
3
+ import { backgroundSgrSpan, hyperlinkSgrSpan } from "../../ui/components/spans.js";
4
+ import { faint, stripAnsi } from "../../ui/components/text.js";
5
+ import { paintTextSelection } from "../../ui/components/text-selection.js";
6
+ import { createPiShellEditor } from "../../integrations/pi/components/shell-editor-autocomplete.js";
7
+ import { piTheme } from "../../integrations/pi/components/upstream/theme/theme.js";
8
+ import { piShellTruncateToWidth, piShellVisibleWidth, } from "../../integrations/pi/components/shell-shared-facade.js";
9
+ import { EditorHyperlinkBudget } from "./editor-hyperlink-budget.js";
10
+ import { canPreparePasteInline } from "./paste-text-preparation.js";
11
+ /**
12
+ * Builds the session's prompt editor: chip-aware paste, selection, and hyperlink decoration over
13
+ * the Pi editor, plus bare A1's prompt presentation and terminal paste diagnostics.
14
+ */
15
+ export function createShellEditor(ports) {
16
+ const { handlers, customViewport, promptChips } = ports;
17
+ let terminalPasteDiagnosticRequest;
18
+ const editor = createPiShellEditor({
19
+ ...handlers,
20
+ keybindingProfile: customViewport ? "a1" : "pi",
21
+ ...(handlers.keybindings === undefined ? {} : { keybindings: handlers.keybindings }),
22
+ paintEditorSelection: (line, from, to, atomic) => atomic
23
+ ? backgroundSgrSpan(line, from, to, "\u001b[7m", "\u001b[27m", piShellVisibleWidth)
24
+ : paintTextSelection(line, from, to, piShellVisibleWidth, true),
25
+ transformPastedContent: content => {
26
+ try {
27
+ return promptChips.transformPastedContent(content, editor.getText());
28
+ }
29
+ catch (error) {
30
+ handlers.onPasteRejected?.(error);
31
+ return "";
32
+ }
33
+ },
34
+ ...(customViewport ? {
35
+ beginClipboardPaste: () => promptChips.beginPaste(editor.getText(), handlers.captureClipboardPaste?.() ?? { kind: "provided", read: signal => handlers.readClipboardContent?.(signal) ?? Promise.resolve(null) }, error => handlers.onPasteRejected?.(error), () => handlers.requestRender()),
36
+ onPasteInput: (bytes, phase) => {
37
+ try {
38
+ if (phase === "framing")
39
+ terminalPasteDiagnosticRequest = ports.nextPasteDiagnosticRequest();
40
+ const request = terminalPasteDiagnosticRequest ?? ports.nextPasteDiagnosticRequest();
41
+ handlers.pasteDiagnostics?.({ request, phase, bytes, atMs: performance.now(), pending: 0, transport: "terminal",
42
+ ...(phase === "settled" ? { outcome: "ready" } : {}) });
43
+ if (phase === "settled")
44
+ terminalPasteDiagnosticRequest = undefined;
45
+ }
46
+ catch { /* Invariant: payload-free diagnostics cannot interfere with the input path. */ }
47
+ },
48
+ deferTextPaste: text => !canPreparePasteInline(text),
49
+ beginTextPaste: text => promptChips.beginPaste(editor.getText(), { kind: "text", text }, error => handlers.onPasteRejected?.(error)),
50
+ } : {}),
51
+ editorAtomicRanges: line => promptChips.atomicRanges(line),
52
+ editorHiddenRanges: line => promptChips.hiddenRanges(line),
53
+ decorateEditorRow: editorRowDecorator(promptChips, ports.editorPointerSelecting),
54
+ expandCopiedEditorText: text => promptChips.expandCopiedText(text),
55
+ cwd: ports.cwd,
56
+ ...(ports.agentDir === undefined ? {} : { agentDir: ports.agentDir }),
57
+ onToolsExpand: () => ports.toggleToolsExpanded(),
58
+ ...(customViewport ? {
59
+ promptPresentation: {
60
+ input: new PromptInput({ fg: (token, text) => piTheme().fg(token, text) }, {
61
+ measure: piShellVisibleWidth,
62
+ truncate: piShellTruncateToWidth,
63
+ }),
64
+ styleSuggestion: faint,
65
+ styleSuggestionCaret: caretCell,
66
+ },
67
+ } : {}),
68
+ onChange: text => {
69
+ handlers.onEditorChange?.(text);
70
+ // Concurrency: Pi clears before onSubmit; capture waiting references before pruning removed chips.
71
+ queueMicrotask(() => promptChips.reconcileDraft(editor.getText()));
72
+ },
73
+ ...(handlers.onPromptSuggestionAccepted === undefined ? {} : { onPromptSuggestionAccepted: handlers.onPromptSuggestionAccepted }),
74
+ });
75
+ return editor;
76
+ }
77
+ /**
78
+ * Dims unsent chips and turns the draft's URLs into terminal hyperlinks, each target once per
79
+ * decoration pass; while a pointer drag selects, links paint as plain underlines instead.
80
+ */
81
+ function editorRowDecorator(promptChips, editorPointerSelecting) {
82
+ const editorHyperlinks = new EditorHyperlinkBudget();
83
+ return (row, width, rowIndex) => {
84
+ if (rowIndex === 0)
85
+ editorHyperlinks.reset();
86
+ const plain = stripAnsi(row);
87
+ const dimmed = promptChips.unsentRanges(plain).reduce((result, range) => backgroundSgrSpan(result, piShellVisibleWidth(plain.slice(0, range.start)), piShellVisibleWidth(plain.slice(0, range.end)), "\u001b[2m", "\u001b[22m", piShellVisibleWidth), row);
88
+ const ranges = promptChips.hyperlinkRanges(plain);
89
+ if (ranges.length === 0 || !editorHyperlinks.takeCleanup())
90
+ return dimmed;
91
+ const linkResetAndTail = `\u001b]8;;\u001b\\\u001b[24m${" ".repeat(Math.max(0, width - piShellVisibleWidth(dimmed)))}`;
92
+ // Platform: VS15 is zero-column and default-ignorable. It breaks Windows Terminal's
93
+ // plain-text URL detector only in the held-button paint; semantic text stays exact.
94
+ const selecting = editorPointerSelecting();
95
+ const paintRow = selecting
96
+ ? dimmed.replaceAll("https://", "https:︎//").replaceAll("http://", "http:︎//")
97
+ : dimmed;
98
+ const decorated = selecting
99
+ ? ranges.reduce((result, range) => backgroundSgrSpan(result, piShellVisibleWidth(plain.slice(0, range.start)), piShellVisibleWidth(plain.slice(0, range.end)), "\u001b[4:4m", "\u001b[24m", piShellVisibleWidth), paintRow)
100
+ : ranges.filter(range => editorHyperlinks.take(range.target)).reduce((result, range) => hyperlinkSgrSpan(result, piShellVisibleWidth(plain.slice(0, range.start)), piShellVisibleWidth(plain.slice(0, range.end)), range.target, piShellVisibleWidth), dimmed);
101
+ // Platform: Windows Terminal can retain stale native dotted-link cells when a mutable
102
+ // prompt replaces a longer URL. Explicit non-link spaces overwrite that tail.
103
+ return `${decorated}${linkResetAndTail}`;
104
+ };
105
+ }
@@ -78,6 +78,12 @@ export interface OwnedUiTerminalHostOptions {
78
78
  readonly backgroundSettings?: OwnedUiBackgroundSettingsPort;
79
79
  readonly quitOutro?: OwnedUiShellPresentationOptions["quitOutro"];
80
80
  }
81
+ /** The size and render request a Pi component reads from the terminal it is shown on, read on every call. */
82
+ export declare function componentRuntime(terminal: Pick<OwnedUiPresenterTerminal, "viewport" | "requestRender">): {
83
+ getColumns(): number;
84
+ getRows(): number;
85
+ requestRender(): void;
86
+ };
81
87
  /** The terminal a session's shell options call for: its layout, TUI mode, cursor, and presentation seams. */
82
88
  export declare function sessionTerminalHostOptions(options: OwnedUiSessionShellOptions): OwnedUiTerminalHostOptions;
83
89
  /**
@@ -1,10 +1,20 @@
1
1
  import { MOUSE_TRACKING_OFF, MOUSE_TRACKING_ON, parseMouseInput } from "../../ui/components/mouse.js";
2
2
  import { readVisibleHyperlinks } from "../../ui/components/visible-hyperlinks.js";
3
3
  import { piCanvasBackgroundAnsi } from "../../integrations/pi/components/theme.js";
4
+ import { residentFixtureControl } from "../../foundation/resident-tabs/fixture-control.js";
5
+ import { residentProgressObserver } from "../../foundation/resident-tabs/progress-observation.js";
4
6
  import { DamageAwareTerminalAdapter, } from "../../integrations/pi/tui-runtime/damage-aware-terminal.js";
5
- import { PiTuiRuntimeAdapter } from "../../integrations/pi/tui-runtime/adapter.js";
7
+ import { PiTuiRuntimeAdapter, legacyKeyInput } from "../../integrations/pi/tui-runtime/adapter.js";
6
8
  import { classifyPiTuiInput } from "../../integrations/pi/tui-runtime/input-presentation-coordinator.js";
7
9
  import { pinnedLayoutRoot, } from "./session-shell-root.js";
10
+ /** The size and render request a Pi component reads from the terminal it is shown on, read on every call. */
11
+ export function componentRuntime(terminal) {
12
+ return {
13
+ getColumns: () => terminal.viewport().columns,
14
+ getRows: () => terminal.viewport().rows,
15
+ requestRender: () => terminal.requestRender(),
16
+ };
17
+ }
8
18
  /** The terminal a session's shell options call for: its layout, TUI mode, cursor, and presentation seams. */
9
19
  export function sessionTerminalHostOptions(options) {
10
20
  const { backend, sessionLayout } = options.engine;
@@ -47,6 +57,8 @@ export class OwnedUiTerminalHost {
47
57
  this.#customViewport = options.layout === "custom-viewport";
48
58
  this.#quitOutro = options.quitOutro;
49
59
  const input = options.input;
60
+ const fixtureControl = residentFixtureControl();
61
+ const progressObserver = residentProgressObserver();
50
62
  let damageTerminal;
51
63
  const surface = {
52
64
  render: width => this.#active?.render(width) ?? [],
@@ -72,6 +84,13 @@ export class OwnedUiTerminalHost {
72
84
  inspectHyperlinks: readVisibleHyperlinks,
73
85
  onResize: () => this.#active?.noteImmediatePresentation(),
74
86
  onHyperlinkCleanupRequired: () => this.runtime?.requestRender(true),
87
+ ...(fixtureControl === null ? {} : {
88
+ allowWrite: () => !fixtureControl.stopped("child-render-write"),
89
+ writeChunks: data => fixtureControl.fragmentChildWrite(data),
90
+ }),
91
+ ...(progressObserver === null ? {} : {
92
+ onWrite: ({ bytes, fragments, transaction, frameId, cause }) => progressObserver.childRenderWrite(bytes, fragments, transaction, frameId, cause),
93
+ }),
75
94
  });
76
95
  return damageTerminal;
77
96
  },
@@ -83,10 +102,13 @@ export class OwnedUiTerminalHost {
83
102
  },
84
103
  }),
85
104
  } : { layoutRoot: pinnedLayoutRoot(this.#delegatingLayoutParts()) }),
86
- ...(input?.onEvent === undefined ? {} : {
105
+ ...(input?.onEvent === undefined && progressObserver === null ? {} : {
87
106
  inputDiagnostics: {
88
- onEvent: input.onEvent,
89
- ...(input.now === undefined ? {} : { now: input.now }),
107
+ onEvent: event => {
108
+ input?.onEvent?.(event);
109
+ progressObserver?.inputPhase?.(event.phase, event.revision);
110
+ },
111
+ ...(input?.now === undefined ? {} : { now: input.now }),
90
112
  },
91
113
  }),
92
114
  ...(options.terminal === undefined ? {} : { terminal: options.terminal }),
@@ -146,6 +168,8 @@ export class OwnedUiTerminalHost {
146
168
  active() {
147
169
  return this.#active;
148
170
  }
171
+ // Invariant: resident tab visibility never gates rendering here; a hidden tab keeps painting into its
172
+ // resident terminal, and the native holder alone withholds inactive surfaces from attach clients.
149
173
  requestRender(from, force = false) {
150
174
  if (from === this.#active)
151
175
  this.runtime.requestRender(force);
@@ -335,7 +359,8 @@ export class OwnedUiTerminalHost {
335
359
  callbacks.closed(rendered);
336
360
  };
337
361
  removeInterruptWatch = runtime.addInputListener(data => {
338
- if (!attached() || !data.includes(INTERRUPT))
362
+ // Compatibility: a kitty-keyboard child reports Ctrl+C as a CSI-u sequence rather than the byte.
363
+ if (!attached() || !data.includes(INTERRUPT) && legacyKeyInput(data) !== INTERRUPT)
339
364
  return undefined;
340
365
  // Protocol: route hosts decide whether one interrupt closes their app. Raw-input forwarding
341
366
  // is required because Pi handles Ctrl+C before the fullscreen overlay receives normal input.
@@ -393,8 +418,10 @@ export class OwnedUiTerminalHost {
393
418
  const { events, rest } = parseMouseInput(data);
394
419
  for (const event of events)
395
420
  surface.handleMouse(event);
396
- if (rest.length > 0)
397
- surface.handleInput(rest);
421
+ // Invariant: owned screens see legacy key bytes whether the terminal reports legacy or kitty keys.
422
+ const key = rest.length > 0 ? legacyKeyInput(rest) : "";
423
+ if (key.length > 0)
424
+ surface.handleInput(key);
398
425
  if (surface.isClosed()) {
399
426
  closeSurface(true);
400
427
  return;
@@ -0,0 +1,64 @@
1
+ import type { OwnedUiSessionViewModel } from "../../contracts/owned-ui/index.js";
2
+ import type { TranscriptViewportFrame, TranscriptViewportFrameInput, TranscriptViewportTheme } from "../../ui/components/transcript-viewport.js";
3
+ import type { PiShellEditorPort } from "../../integrations/pi/components/shell-shared-facade.js";
4
+ import type { DockChrome } from "./dock-chrome.js";
5
+ import type { InputSurfaceSwitch } from "./input-surface-switch.js";
6
+ import type { PromptChipStore } from "./prompt-chips.js";
7
+ import type { SessionViewportController } from "./session-viewport-controller.js";
8
+ import type { TranscriptDocumentLayout } from "./transcript-document.js";
9
+ /** The dock's rows and where its input and footer sit inside them. */
10
+ export interface DockLayout {
11
+ readonly rows: readonly string[];
12
+ readonly inputOffset: number;
13
+ readonly editorOffset: number;
14
+ readonly inputRows: number;
15
+ readonly footerRows: number;
16
+ /** Exact status, warning, error, command-result, and notice rows; queued and structural rows stay excluded. */
17
+ readonly copyableMessageRows: NonNullable<TranscriptViewportFrameInput["copyableDockRows"]>;
18
+ }
19
+ /** What a layout reads from the shell root to compose one frame. */
20
+ export interface ShellLayoutPorts {
21
+ readonly viewport: SessionViewportController;
22
+ readonly input: InputSurfaceSwitch;
23
+ readonly editor: Pick<PiShellEditorPort, "getText">;
24
+ readonly promptChips: Pick<PromptChipStore, "atomicRanges">;
25
+ readonly dockChrome: Pick<DockChrome, "renderCopyAcknowledgement" | "renderReleaseBanner" | "locateReleaseClose">;
26
+ readonly theme: TranscriptViewportTheme;
27
+ readonly onFrame?: (frame: TranscriptViewportFrame) => void;
28
+ rows(): number;
29
+ dock(width: number): DockLayout;
30
+ document(width: number): TranscriptDocumentLayout;
31
+ queued(width: number): readonly string[];
32
+ liveStatus(width: number): readonly string[];
33
+ diagnostics(): OwnedUiSessionViewModel["diagnostics"];
34
+ }
35
+ /**
36
+ * How one session's root composes a frame. The root picks one layout at construction and never
37
+ * consults the layout mode again on the render path.
38
+ */
39
+ export interface ShellLayout {
40
+ render(width: number): readonly string[];
41
+ /** Visible content changed outside a render, so the next frame may not reuse the last one. */
42
+ invalidate(): void;
43
+ /** What the last composed frame represented, for payload-free evidence; undefined before one exists. */
44
+ composed(): {
45
+ readonly viewportRevision: number;
46
+ readonly pointerPosition: TranscriptViewportFrameInput["pointerPosition"];
47
+ } | undefined;
48
+ compositions(): {
49
+ readonly full: number;
50
+ readonly dockOnly: number;
51
+ };
52
+ }
53
+ /** The pinned comparison profile: the whole document above the dock; the terminal host scrolls it. */
54
+ export declare class PinnedLayout implements ShellLayout {
55
+ #private;
56
+ constructor(ports: ShellLayoutPorts);
57
+ render(width: number): readonly string[];
58
+ invalidate(): void;
59
+ composed(): undefined;
60
+ compositions(): {
61
+ readonly full: number;
62
+ readonly dockOnly: number;
63
+ };
64
+ }
@@ -0,0 +1,18 @@
1
+ /** The pinned comparison profile: the whole document above the dock; the terminal host scrolls it. */
2
+ export class PinnedLayout {
3
+ #ports;
4
+ constructor(ports) {
5
+ this.#ports = ports;
6
+ }
7
+ render(width) {
8
+ this.#ports.viewport.setEditorPointerFrame(undefined);
9
+ return [...this.#ports.document(width).rows, ...this.#ports.dock(width).rows];
10
+ }
11
+ invalidate() { }
12
+ composed() {
13
+ return undefined;
14
+ }
15
+ compositions() {
16
+ return { full: 0, dockOnly: 0 };
17
+ }
18
+ }