@timurproko/a1 0.2.6 → 0.2.7-dev.1221

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 (410) 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 +196 -908
  37. package/dist/app/session-shell/session-shell.d.ts +3 -8
  38. package/dist/app/session-shell/session-shell.js +324 -835
  39. package/dist/app/session-shell/session-viewport-controller.d.ts +2 -2
  40. package/dist/app/session-shell/session-viewport-controller.js +29 -15
  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 +102 -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 +205 -153
  70. package/dist/composition/resident-tab-bridge.d.ts +25 -0
  71. package/dist/composition/resident-tab-bridge.js +180 -0
  72. package/dist/composition/session-backend.d.ts +19 -0
  73. package/dist/composition/session-backend.js +1 -0
  74. package/dist/composition/session-runtime-registry.d.ts +20 -0
  75. package/dist/composition/session-runtime-registry.js +85 -0
  76. package/dist/composition/settings-route-host.d.ts +16 -1
  77. package/dist/composition/settings-route-host.js +29 -10
  78. package/dist/composition/settings-search-input.d.ts +9 -0
  79. package/dist/composition/settings-search-input.js +58 -0
  80. package/dist/composition/startup-route.d.ts +32 -0
  81. package/dist/composition/startup-route.js +72 -0
  82. package/dist/composition/utility-tab.d.ts +28 -0
  83. package/dist/composition/utility-tab.js +242 -0
  84. package/dist/contracts/owned-ui/index.d.ts +1 -1
  85. package/dist/contracts/owned-ui/model.d.ts +3 -0
  86. package/dist/contracts/owned-ui/session-backend.d.ts +3 -0
  87. package/dist/contracts/owned-ui/session-workflows.d.ts +11 -4
  88. package/dist/contracts/presentation/index.d.ts +11 -0
  89. package/dist/contracts/presentation/index.js +12 -0
  90. package/dist/features/launch/development-launch.js +6 -0
  91. package/dist/features/launch/index.d.ts +1 -1
  92. package/dist/features/launch/intent.d.ts +3 -1
  93. package/dist/features/launch/intent.js +7 -4
  94. package/dist/features/launch/profile-paths.js +4 -0
  95. package/dist/features/owned-ui/plus-menu-dialog.d.ts +22 -0
  96. package/dist/features/owned-ui/plus-menu-dialog.js +76 -0
  97. package/dist/features/owned-ui/project-trust-dialog.d.ts +1 -1
  98. package/dist/features/owned-ui/project-trust-dialog.js +6 -8
  99. package/dist/features/owned-ui/project-trust-prompt.d.ts +1 -0
  100. package/dist/features/owned-ui/project-trust-prompt.js +7 -3
  101. package/dist/features/owned-ui/reference-screen-app.d.ts +2 -0
  102. package/dist/features/owned-ui/reference-screen-app.js +12 -2
  103. package/dist/features/owned-ui/settings-app.d.ts +12 -2
  104. package/dist/features/owned-ui/settings-app.js +116 -81
  105. package/dist/features/owned-ui/settings-search-input.d.ts +29 -0
  106. package/dist/features/owned-ui/settings-search-input.js +1 -0
  107. package/dist/features/prompt-history/index.d.ts +1 -1
  108. package/dist/features/prompt-history/paths.d.ts +2 -1
  109. package/dist/features/prompt-history/paths.js +10 -2
  110. package/dist/features/prompt-history/service.d.ts +5 -0
  111. package/dist/features/prompt-history/service.js +1 -1
  112. package/dist/features/resident-tab/auto-name.d.ts +11 -0
  113. package/dist/features/resident-tab/auto-name.js +44 -0
  114. package/dist/features/resident-tab/index.d.ts +5 -0
  115. package/dist/features/resident-tab/index.js +7 -0
  116. package/dist/features/resident-tab/shortcut-bindings-file.d.ts +8 -0
  117. package/dist/features/resident-tab/shortcut-bindings-file.js +40 -0
  118. package/dist/features/resident-tab/shortcut-declarations.d.ts +13 -0
  119. package/dist/features/resident-tab/shortcut-declarations.js +26 -0
  120. package/dist/features/resident-tab/shortcut-projection.d.ts +29 -0
  121. package/dist/features/resident-tab/shortcut-projection.js +64 -0
  122. package/dist/features/resident-tab/status-deriver.d.ts +10 -0
  123. package/dist/features/resident-tab/status-deriver.js +12 -0
  124. package/dist/foundation/launch-context/index.d.ts +12 -0
  125. package/dist/foundation/launch-context/index.js +26 -0
  126. package/dist/foundation/launch-guardian/exit-watcher.d.ts +14 -0
  127. package/dist/foundation/launch-guardian/exit-watcher.js +94 -0
  128. package/dist/foundation/launch-guardian/main.d.ts +7 -1
  129. package/dist/foundation/launch-guardian/main.js +60 -7
  130. package/dist/foundation/lifecycle/session-repository-context.js +16 -2
  131. package/dist/foundation/process-containment/{native-guardian-containment.d.ts → addon-containment.d.ts} +7 -5
  132. package/dist/foundation/process-containment/addon-containment.js +139 -0
  133. package/dist/foundation/process-containment/addon-process-inspector.d.ts +11 -0
  134. package/dist/foundation/process-containment/addon-process-inspector.js +36 -0
  135. package/dist/foundation/process-containment/addon.d.ts +42 -0
  136. package/dist/foundation/process-containment/addon.js +57 -0
  137. package/dist/foundation/process-containment/artifact.d.ts +1 -1
  138. package/dist/foundation/process-containment/artifact.js +6 -5
  139. package/dist/foundation/process-containment/contracts.d.ts +2 -0
  140. package/dist/foundation/process-containment/index.d.ts +4 -4
  141. package/dist/foundation/process-containment/index.js +3 -3
  142. package/dist/foundation/process-containment/native-process-inspector.d.ts +2 -1
  143. package/dist/foundation/process-containment/native-process-inspector.js +10 -10
  144. package/dist/foundation/release/automatic-update.d.ts +37 -0
  145. package/dist/foundation/release/automatic-update.js +265 -0
  146. package/dist/foundation/release/bootstrap.d.ts +7 -9
  147. package/dist/foundation/release/bootstrap.js +107 -24
  148. package/dist/foundation/release/cohort-state.d.ts +1 -1
  149. package/dist/foundation/release/cohort-state.js +1 -1
  150. package/dist/foundation/release/dependency-certification.js +54 -19
  151. package/dist/foundation/release/early-accent.d.ts +12 -0
  152. package/dist/foundation/release/early-accent.js +59 -0
  153. package/dist/foundation/release/index.d.ts +2 -2
  154. package/dist/foundation/release/index.js +2 -2
  155. package/dist/foundation/release/latest-release.d.ts +24 -2
  156. package/dist/foundation/release/latest-release.js +51 -1
  157. package/dist/foundation/release/progress-palette.generated.d.ts +137 -3
  158. package/dist/foundation/release/progress-palette.generated.js +137 -3
  159. package/dist/foundation/release/release-gc.d.ts +3 -0
  160. package/dist/foundation/release/release-gc.js +59 -8
  161. package/dist/foundation/release/release-store.d.ts +12 -0
  162. package/dist/foundation/release/release-store.js +124 -2
  163. package/dist/foundation/release/update-execution-lease.d.ts +48 -0
  164. package/dist/foundation/release/update-execution-lease.js +161 -0
  165. package/dist/foundation/release/update.d.ts +12 -7
  166. package/dist/foundation/release/update.js +281 -196
  167. package/dist/foundation/resident-tabs/bounded-host-command.d.ts +18 -0
  168. package/dist/foundation/resident-tabs/bounded-host-command.js +39 -0
  169. package/dist/foundation/resident-tabs/bridge-client.d.ts +70 -0
  170. package/dist/foundation/resident-tabs/bridge-client.js +321 -0
  171. package/dist/foundation/resident-tabs/doctor.d.ts +28 -0
  172. package/dist/foundation/resident-tabs/doctor.js +166 -0
  173. package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +27 -0
  174. package/dist/foundation/resident-tabs/draft-checkpoint.js +145 -0
  175. package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +36 -0
  176. package/dist/foundation/resident-tabs/ensure-terminal-host.js +151 -0
  177. package/dist/foundation/resident-tabs/fault-injection.d.ts +8 -0
  178. package/dist/foundation/resident-tabs/fault-injection.js +26 -0
  179. package/dist/foundation/resident-tabs/fixture-control.d.ts +7 -0
  180. package/dist/foundation/resident-tabs/fixture-control.js +35 -0
  181. package/dist/foundation/resident-tabs/host-entry.d.ts +1 -0
  182. package/dist/foundation/resident-tabs/host-entry.js +17 -0
  183. package/dist/foundation/resident-tabs/index.d.ts +12 -0
  184. package/dist/foundation/resident-tabs/index.js +6 -0
  185. package/dist/foundation/resident-tabs/maintenance.d.ts +39 -0
  186. package/dist/foundation/resident-tabs/maintenance.js +75 -0
  187. package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +34 -0
  188. package/dist/foundation/resident-tabs/progress-observation-schema.js +1 -0
  189. package/dist/foundation/resident-tabs/progress-observation.d.ts +4 -0
  190. package/dist/foundation/resident-tabs/progress-observation.js +150 -0
  191. package/dist/foundation/resident-tabs/prompt-journal.d.ts +63 -0
  192. package/dist/foundation/resident-tabs/prompt-journal.js +213 -0
  193. package/dist/foundation/resident-tabs/protocol.d.ts +12 -0
  194. package/dist/foundation/resident-tabs/protocol.js +195 -0
  195. package/dist/foundation/resident-tabs/recovery.d.ts +26 -0
  196. package/dist/foundation/resident-tabs/recovery.js +205 -0
  197. package/dist/foundation/resident-tabs/release-holds.d.ts +28 -0
  198. package/dist/foundation/resident-tabs/release-holds.js +75 -0
  199. package/dist/foundation/resident-tabs/routes.d.ts +5 -0
  200. package/dist/foundation/resident-tabs/routes.js +5 -0
  201. package/dist/foundation/resident-tabs/routing.d.ts +11 -0
  202. package/dist/foundation/resident-tabs/routing.js +10 -0
  203. package/dist/foundation/resident-tabs/session-sync.d.ts +14 -0
  204. package/dist/foundation/resident-tabs/session-sync.js +37 -0
  205. package/dist/foundation/resident-tabs/settings.d.ts +12 -0
  206. package/dist/foundation/resident-tabs/settings.js +58 -0
  207. package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +14 -0
  208. package/dist/foundation/resident-tabs/terminal-host-artifact.js +78 -0
  209. package/dist/foundation/resident-tabs/zip-archive.d.ts +9 -0
  210. package/dist/foundation/resident-tabs/zip-archive.js +56 -0
  211. package/dist/foundation/session-writer-lock/index.d.ts +30 -0
  212. package/dist/foundation/session-writer-lock/index.js +203 -0
  213. package/dist/foundation/startup/startup-descriptor.js +2 -2
  214. package/dist/foundation/terminal-cleanup/index.d.ts +1 -1
  215. package/dist/foundation/terminal-cleanup/index.js +1 -1
  216. package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +6 -0
  217. package/dist/foundation/terminal-cleanup/terminal-reset.js +6 -0
  218. package/dist/integrations/pi/components/editor-interaction.d.ts +2 -0
  219. package/dist/integrations/pi/components/modal-frame.d.ts +17 -1
  220. package/dist/integrations/pi/components/modal-frame.js +48 -9
  221. package/dist/integrations/pi/components/models-dialog.js +4 -52
  222. package/dist/integrations/pi/components/owned-editor-ux.d.ts +6 -1
  223. package/dist/integrations/pi/components/owned-editor-ux.js +90 -6
  224. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +4 -4
  225. package/dist/integrations/pi/components/resources/builtin-themes.js +4 -4
  226. package/dist/integrations/pi/components/share-operation-dialog.d.ts +2 -0
  227. package/dist/integrations/pi/components/share-operation-dialog.js +2 -1
  228. package/dist/integrations/pi/components/shell-editor-autocomplete.js +58 -36
  229. package/dist/integrations/pi/components/shell-extension-ui.js +79 -60
  230. package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
  231. package/dist/integrations/pi/components/shell-footer-status.js +21 -5
  232. package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
  233. package/dist/integrations/pi/components/shell-presenters-info.d.ts +5 -2
  234. package/dist/integrations/pi/components/shell-presenters-info.js +18 -4
  235. package/dist/integrations/pi/components/shell-presenters-transcript.js +4 -1
  236. package/dist/integrations/pi/components/shell-selectors-dialogs.js +5 -1
  237. package/dist/integrations/pi/components/shell-shared-facade.d.ts +12 -1
  238. package/dist/integrations/pi/components/skills-dialog.js +2 -2
  239. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
  240. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +17 -4
  241. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
  242. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
  243. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
  244. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
  245. package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
  246. package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
  247. package/dist/integrations/pi/components/upstream/components/extension-selector.js +1 -1
  248. package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
  249. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +8 -6
  250. package/dist/integrations/pi/components/upstream/components/owned-editor.js +16 -9
  251. package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
  252. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +4 -4
  253. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +2 -2
  254. package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
  255. package/dist/integrations/pi/components/upstream/components/session-footer.js +31 -25
  256. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
  257. package/dist/integrations/pi/components/upstream/components/session-selector.js +8 -7
  258. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
  259. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
  260. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +2 -2
  261. package/dist/integrations/pi/components/upstream/components/status-indicator.js +3 -3
  262. package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
  263. package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
  264. package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +8 -7
  265. package/dist/integrations/pi/components/upstream/components/thinking-selector.js +10 -9
  266. package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +2 -6
  267. package/dist/integrations/pi/components/upstream/components/tool-execution.js +103 -101
  268. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +9 -9
  269. package/dist/integrations/pi/components/upstream/components/tree-selector.js +13 -21
  270. package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
  271. package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
  272. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +2 -2
  273. package/dist/integrations/pi/components/upstream/history/editor-core.js +7 -5
  274. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
  275. package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
  276. package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
  277. package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
  278. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
  279. package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
  280. package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
  281. package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
  282. package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +1 -1
  283. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
  284. package/dist/integrations/pi/components/upstream/theme/theme.d.ts +5 -0
  285. package/dist/integrations/pi/components/upstream/theme/theme.js +29 -2
  286. package/dist/integrations/pi/engine/adapter.d.ts +5 -77
  287. package/dist/integrations/pi/engine/adapter.js +95 -394
  288. package/dist/integrations/pi/engine/command-dispatch.d.ts +13 -0
  289. package/dist/integrations/pi/engine/command-dispatch.js +57 -0
  290. package/dist/integrations/pi/engine/host.js +2 -2
  291. package/dist/integrations/pi/engine/offline-settings-port.d.ts +23 -0
  292. package/dist/integrations/pi/engine/offline-settings-port.js +53 -0
  293. package/dist/integrations/pi/engine/pi-settings-metadata.json +14 -2
  294. package/dist/integrations/pi/engine/ports.d.ts +56 -0
  295. package/dist/integrations/pi/engine/ports.js +93 -0
  296. package/dist/integrations/pi/engine/prompt-suggestions.d.ts +1 -0
  297. package/dist/integrations/pi/engine/prompt-suggestions.js +40 -0
  298. package/dist/integrations/pi/engine/resources/changelog.json +4 -4
  299. package/dist/integrations/pi/engine/runtime-integration.js +102 -29
  300. package/dist/integrations/pi/engine/session-runtime.d.ts +0 -6
  301. package/dist/integrations/pi/engine/session-runtime.js +13 -5
  302. package/dist/integrations/pi/engine/session-selection.d.ts +3 -0
  303. package/dist/integrations/pi/engine/session-selection.js +45 -9
  304. package/dist/integrations/pi/engine/settings-bridge.d.ts +5 -0
  305. package/dist/integrations/pi/engine/settings-bridge.js +15 -0
  306. package/dist/integrations/pi/engine/settings-port.js +11 -15
  307. package/dist/integrations/pi/engine/view-state.d.ts +42 -0
  308. package/dist/integrations/pi/engine/view-state.js +126 -0
  309. package/dist/integrations/pi/engine/workflow-contexts.js +10 -1
  310. package/dist/integrations/pi/engine/workflow-runner.js +73 -4
  311. package/dist/integrations/pi/engine/workflow-support.d.ts +12 -0
  312. package/dist/integrations/pi/engine/workflow-support.js +36 -0
  313. package/dist/integrations/pi/engine/workflows.d.ts +3 -1
  314. package/dist/integrations/pi/engine/workflows.js +1 -0
  315. package/dist/integrations/pi/startup-public.js +257 -310
  316. package/dist/integrations/pi/startup-public.manifest.json +564 -440
  317. package/dist/integrations/pi/tui-runtime/adapter.d.ts +6 -0
  318. package/dist/integrations/pi/tui-runtime/adapter.js +32 -1
  319. package/dist/integrations/pi/tui-runtime/contracts.d.ts +5 -0
  320. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +12 -1
  321. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +31 -2
  322. package/dist/native/darwin-arm64/manifest.json +10 -7
  323. package/dist/native/darwin-arm64/process-guardian.node +0 -0
  324. package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +10500 -0
  325. package/dist/native/darwin-arm64/terminal-host.manifest.json +46 -0
  326. package/dist/native/darwin-arm64/terminal-host.node +0 -0
  327. package/dist/native/darwin-x64/manifest.json +23 -0
  328. package/dist/native/darwin-x64/process-guardian.node +0 -0
  329. package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10737 -0
  330. package/dist/native/darwin-x64/terminal-host.manifest.json +46 -0
  331. package/dist/native/darwin-x64/terminal-host.node +0 -0
  332. package/dist/native/linux-x64/manifest.json +10 -7
  333. package/dist/native/linux-x64/process-guardian.node +0 -0
  334. package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +11226 -0
  335. package/dist/native/linux-x64/terminal-host.manifest.json +46 -0
  336. package/dist/native/linux-x64/terminal-host.node +0 -0
  337. package/dist/native/win32-x64/manifest.json +10 -7
  338. package/dist/native/win32-x64/process-guardian.node +0 -0
  339. package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10757 -0
  340. package/dist/native/win32-x64/terminal-host.manifest.json +46 -0
  341. package/dist/native/win32-x64/terminal-host.node +0 -0
  342. package/dist/product-identity.d.ts +3 -3
  343. package/dist/product-identity.js +4 -4
  344. package/dist/product-identity.json +16 -2
  345. package/dist/runtime-payload-inventory.json +6330 -6677
  346. package/dist/ui/apps/host.d.ts +2 -0
  347. package/dist/ui/apps/host.js +7 -1
  348. package/dist/ui/components/dialog-panel.js +35 -30
  349. package/dist/ui/components/index.d.ts +2 -2
  350. package/dist/ui/components/index.js +1 -1
  351. package/dist/ui/components/line-input.d.ts +4 -1
  352. package/dist/ui/components/line-input.js +3 -1
  353. package/dist/ui/components/prompt-input.d.ts +11 -8
  354. package/dist/ui/components/prompt-input.js +15 -13
  355. package/dist/ui/components/selection-copy.d.ts +2 -0
  356. package/dist/ui/components/selection-copy.js +13 -0
  357. package/dist/ui/components/spans.js +2 -2
  358. package/dist/ui/components/submitted-prompt.d.ts +9 -6
  359. package/dist/ui/components/submitted-prompt.js +20 -12
  360. package/dist/ui/components/surface.js +4 -2
  361. package/dist/ui/components/text.d.ts +3 -6
  362. package/dist/ui/components/text.js +6 -8
  363. package/dist/ui/components/transcript-viewport.d.ts +9 -2
  364. package/dist/ui/components/transcript-viewport.js +176 -55
  365. package/dist/ui/settings/declarations.d.ts +90 -16
  366. package/dist/ui/settings/declarations.js +67 -14
  367. package/dist/ui/settings/early-accent.d.ts +81 -0
  368. package/dist/ui/settings/early-accent.js +50 -0
  369. package/dist/ui/settings/index.d.ts +4 -2
  370. package/dist/ui/settings/index.js +2 -1
  371. package/dist/ui/settings/manager.d.ts +16 -3
  372. package/dist/ui/settings/manager.js +122 -33
  373. package/dist/ui/settings/migrations.d.ts +6 -0
  374. package/dist/ui/settings/migrations.js +73 -0
  375. package/dist/ui/settings/profile-document.d.ts +26 -0
  376. package/dist/ui/settings/profile-document.js +164 -0
  377. package/dist/ui/settings/progress-palette.generated.d.ts +139 -0
  378. package/dist/ui/settings/progress-palette.generated.js +139 -0
  379. package/dist/ui/settings/sections.d.ts +4 -0
  380. package/dist/ui/settings/sections.js +9 -3
  381. package/docs/architecture/boundaries.md +24 -9
  382. package/docs/architecture/evidence/resident-tabs/linux-x64.md +37 -0
  383. package/docs/architecture/evidence/resident-tabs/macos-arm64.md +36 -0
  384. package/docs/architecture/evidence/resident-tabs/macos-x64.md +35 -0
  385. package/docs/architecture/evidence/resident-tabs/windows-x64.md +36 -0
  386. package/docs/architecture/internal-naming.md +3 -1
  387. package/docs/architecture/process-guardian-provenance.md +18 -10
  388. package/docs/architecture/project-structure.md +8 -0
  389. package/docs/architecture/resident-tabs-requirements.md +18 -0
  390. package/docs/architecture/resident-tabs.md +648 -0
  391. package/docs/architecture/response-copy-delivery.md +1 -1
  392. package/docs/architecture/terminal-host-proof-gate.md +2 -0
  393. package/docs/architecture/terminal-host-provenance.md +16 -4
  394. package/docs/architecture/tool-image-presentation.md +2 -1
  395. package/docs/architecture/toolchain.md +11 -9
  396. package/docs/ci-release-runbook.md +14 -7
  397. package/docs/features/launch-profiles.md +11 -8
  398. package/docs/features/prompt-history.md +41 -20
  399. package/docs/manual-resident-tabs-acceptance.md +51 -0
  400. package/docs/openspec-archive-automation.md +49 -22
  401. package/docs/validation.md +49 -9
  402. package/package.json +19 -6
  403. package/dist/foundation/process-containment/darwin-process-inspector.d.ts +0 -5
  404. package/dist/foundation/process-containment/darwin-process-inspector.js +0 -7
  405. package/dist/foundation/process-containment/native-guardian-containment.js +0 -152
  406. package/dist/foundation/process-containment/windows-process-inspector.d.ts +0 -19
  407. package/dist/foundation/process-containment/windows-process-inspector.js +0 -56
  408. package/dist/native/darwin-arm64/process-guardian +0 -0
  409. package/dist/native/linux-x64/process-guardian +0 -0
  410. package/dist/native/win32-x64/process-guardian.exe +0 -0
@@ -39,6 +39,14 @@ export class OwnedEditorUxInterception {
39
39
  hasSelection() {
40
40
  return this.interceptors.some(interceptor => interceptor.hasSelection?.() === true);
41
41
  }
42
+ selectedText() {
43
+ for (const interceptor of this.interceptors) {
44
+ const selected = interceptor.selectedText?.();
45
+ if (selected !== undefined)
46
+ return selected;
47
+ }
48
+ return undefined;
49
+ }
42
50
  ownsPointer() {
43
51
  return this.interceptors.some(interceptor => interceptor.ownsPointer?.() === true);
44
52
  }
@@ -73,7 +81,7 @@ class PromptSelectionInterceptor {
73
81
  installAtomicSegmentation(editor, options.atomicRanges, () => this.#wordDirection);
74
82
  }
75
83
  handleInput(data, next) {
76
- if (this.#handleTerminalPaste(data, next))
84
+ if (this.options.pasteEnabled === false ? discardTerminalPaste(this, data, value => this.handleInput(value, next)) : this.#handleTerminalPaste(data, next))
77
85
  return;
78
86
  if (this.keybindings.matches(data, "owned.editor.selectAll")) {
79
87
  this.#selectAll();
@@ -88,18 +96,19 @@ class PromptSelectionInterceptor {
88
96
  return;
89
97
  }
90
98
  if (this.keybindings.matches(data, "tui.input.copy") && this.hasSelection()) {
91
- this.options.copyText(this.options.expandCopiedText(this.#selectedText()));
99
+ this.options.copyText(this.options.expandCopiedText(this.#selectedText()), false);
92
100
  this.#collapseCopiedSelection();
93
101
  return;
94
102
  }
95
103
  if (this.keybindings.matches(data, "owned.editor.cut") && this.hasSelection()) {
96
- this.options.copyText(this.options.expandCopiedText(this.#selectedText()));
104
+ this.options.copyText(this.options.expandCopiedText(this.#selectedText()), true);
97
105
  if (!this.#deleteSelection())
98
106
  this.#deleteAtomicFocus();
99
107
  return;
100
108
  }
101
109
  if (this.keybindings.matches(data, "owned.editor.paste")) {
102
- this.pasteClipboard();
110
+ if (this.options.pasteEnabled !== false)
111
+ this.pasteClipboard();
103
112
  return;
104
113
  }
105
114
  if (this.keybindings.matches(data, "owned.editor.redo")) {
@@ -124,7 +133,7 @@ class PromptSelectionInterceptor {
124
133
  this.#deleteSelection();
125
134
  return;
126
135
  }
127
- const inserted = insertedText(data);
136
+ const inserted = editorInsertedText(data);
128
137
  if (inserted !== undefined) {
129
138
  this.#replaceSelection(inserted);
130
139
  return;
@@ -272,16 +281,25 @@ class PromptSelectionInterceptor {
272
281
  this.#pointerSelecting = false;
273
282
  this.#lastClick = undefined;
274
283
  this.#redoStack = [];
284
+ DISABLED_TERMINAL_PASTES.delete(this);
275
285
  this.#selectionRevision += 1;
276
286
  }
277
287
  cancelPendingPastes() {
278
288
  this.#pasteGeneration += 1;
279
289
  this.#terminalPaste = undefined;
290
+ DISABLED_TERMINAL_PASTES.delete(this);
280
291
  }
281
292
  hasSelection() {
282
293
  return this.#activeRange() !== undefined;
283
294
  }
295
+ selectedText() {
296
+ return this.#activeRange() === undefined
297
+ ? undefined
298
+ : this.options.expandCopiedText(this.#selectedText());
299
+ }
284
300
  pasteClipboard() {
301
+ if (this.options.pasteEnabled === false)
302
+ return false;
285
303
  this.#pasteFromClipboard();
286
304
  return true;
287
305
  }
@@ -920,7 +938,73 @@ function isEditorSegment(value) {
920
938
  const input = Reflect.get(value, "input");
921
939
  return typeof segment === "string" && typeof index === "number" && typeof input === "string";
922
940
  }
923
- function insertedText(data) {
941
+ const DISABLED_TERMINAL_PASTES = new WeakMap();
942
+ function discardTerminalPaste(owner, data, forward) {
943
+ const startMarker = "\x1b[200~";
944
+ const endMarker = "\x1b[201~";
945
+ const state = DISABLED_TERMINAL_PASTES.get(owner) ?? { startTail: "", bodyTail: null };
946
+ if (state.bodyTail !== null) {
947
+ const framed = state.bodyTail + data;
948
+ const end = framed.indexOf(endMarker);
949
+ if (end < 0) {
950
+ state.bodyTail = delimiterTail(framed, endMarker);
951
+ DISABLED_TERMINAL_PASTES.set(owner, state);
952
+ return true;
953
+ }
954
+ DISABLED_TERMINAL_PASTES.delete(owner);
955
+ const remaining = framed.slice(end + endMarker.length);
956
+ if (remaining.length > 0)
957
+ forward(remaining);
958
+ return true;
959
+ }
960
+ const hadStartTail = state.startTail.length > 0;
961
+ const candidate = state.startTail + data;
962
+ state.startTail = "";
963
+ const start = candidate.indexOf(startMarker);
964
+ if (start >= 0) {
965
+ if (start > 0)
966
+ forward(candidate.slice(0, start));
967
+ const framed = candidate.slice(start + startMarker.length);
968
+ const end = framed.indexOf(endMarker);
969
+ if (end < 0) {
970
+ state.bodyTail = delimiterTail(framed, endMarker);
971
+ DISABLED_TERMINAL_PASTES.set(owner, state);
972
+ }
973
+ else {
974
+ DISABLED_TERMINAL_PASTES.delete(owner);
975
+ const remaining = framed.slice(end + endMarker.length);
976
+ if (remaining.length > 0)
977
+ forward(remaining);
978
+ }
979
+ return true;
980
+ }
981
+ const partial = delimiterTail(candidate, startMarker);
982
+ // Compatibility: standalone Escape still cancels; marker fragments stay pending.
983
+ if (partial.length > 1) {
984
+ const before = candidate.slice(0, candidate.length - partial.length);
985
+ if (before.length > 0)
986
+ forward(before);
987
+ state.startTail = partial;
988
+ DISABLED_TERMINAL_PASTES.set(owner, state);
989
+ return true;
990
+ }
991
+ DISABLED_TERMINAL_PASTES.delete(owner);
992
+ if (hadStartTail) {
993
+ forward(candidate);
994
+ return true;
995
+ }
996
+ return false;
997
+ }
998
+ function delimiterTail(text, delimiter) {
999
+ const limit = Math.min(text.length, delimiter.length - 1);
1000
+ for (let length = limit; length > 0; length -= 1) {
1001
+ const suffix = text.slice(text.length - length);
1002
+ if (delimiter.startsWith(suffix))
1003
+ return suffix;
1004
+ }
1005
+ return "";
1006
+ }
1007
+ export function editorInsertedText(data) {
924
1008
  if (!data || data.includes("\u001b[200~"))
925
1009
  return undefined;
926
1010
  const kitty = decodeKittyPrintable(data);
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.1.0 (MIT),
3
- * commit abe508e1b89912adde45528136c3221eb69acdd7.
4
- * Upstream dark.json SHA-256: c11a588b714d35300293079b425fb09a3693d4b2d453585d211b08163c648b75
5
- * Upstream light.json SHA-256: f590c51c2bc8b238891efd0e983473ed2e2a6487b6692cc1d4b2845165e703f7
2
+ * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.4.0 (MIT),
3
+ * commit 4a080252f06caf63a525d7873c5d94d3c23887e0.
4
+ * Upstream dark.json SHA-256: e1f96982f8cb7d2a48eca7db03c9cb282cb1e14a243680cd855638ecd6a251b6
5
+ * Upstream light.json SHA-256: 2dee6a4be7f765e7fd7728166b7ebf8c29e4ce313f8ec6b38ae50699e3abc2f3
6
6
  * Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
7
7
  */
8
8
  export declare const BUILTIN_THEME_RESOURCES: Readonly<{
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.1.0 (MIT),
3
- * commit abe508e1b89912adde45528136c3221eb69acdd7.
4
- * Upstream dark.json SHA-256: c11a588b714d35300293079b425fb09a3693d4b2d453585d211b08163c648b75
5
- * Upstream light.json SHA-256: f590c51c2bc8b238891efd0e983473ed2e2a6487b6692cc1d4b2845165e703f7
2
+ * Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.4.0 (MIT),
3
+ * commit 4a080252f06caf63a525d7873c5d94d3c23887e0.
4
+ * Upstream dark.json SHA-256: e1f96982f8cb7d2a48eca7db03c9cb282cb1e14a243680cd855638ecd6a251b6
5
+ * Upstream light.json SHA-256: 2dee6a4be7f765e7fd7728166b7ebf8c29e4ce313f8ec6b38ae50699e3abc2f3
6
6
  * Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
7
7
  */
8
8
  export const BUILTIN_THEME_RESOURCES = Object.freeze({
@@ -1,6 +1,8 @@
1
1
  import { type PiShellComponentPort, type PiShellEditorOptions } from "./shell-shared-facade.js";
2
2
  export interface PiShellOperationLoaderPort extends PiShellComponentPort {
3
3
  readonly signal: AbortSignal;
4
+ /** Relabels the running operation; the pinned comparison loader keeps its first label. */
5
+ readonly setMessage?: (message: string) => void;
4
6
  }
5
7
  export declare function createPiShellShareOperationDialog(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, message: string): PiShellOperationLoaderPort;
6
8
  export declare function createPiShellOperationLoader(runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">, message: string): PiShellOperationLoaderPort;
@@ -18,6 +18,7 @@ class ShareOperationDialog {
18
18
  ], new DynamicBorder(paintPiBorder));
19
19
  }
20
20
  get signal() { return this.#loader.signal; }
21
+ setMessage(message) { this.#loader.setMessage(message); }
21
22
  invalidate() { this.#frame.invalidate(); }
22
23
  render(width) { return this.#frame.render(width); }
23
24
  handleInput(data) { this.#loader.handleInput(data); }
@@ -26,7 +27,7 @@ class ShareOperationDialog {
26
27
  export function createPiShellShareOperationDialog(runtime, message) {
27
28
  ensureTheme();
28
29
  const dialog = new ShareOperationDialog(runtime, message);
29
- return { ...componentPort(dialog), signal: dialog.signal };
30
+ return { ...componentPort(dialog), signal: dialog.signal, setMessage: message => dialog.setMessage(message) };
30
31
  }
31
32
  export function createPiShellOperationLoader(runtime, message) {
32
33
  ensureTheme();
@@ -5,6 +5,8 @@ import { OwnedEditorUxInterception, createPromptSelectionInterceptor, editorVisu
5
5
  import { PINNED_PI_LAYOUT, getPiSelectListTheme, piTheme, renderPiListSelection, } from "./theme.js";
6
6
  import { createPiKeybindingsHost, createTuiFacade, ensureTheme, isAutocompleteProvider, } from "./shell-shared-facade.js";
7
7
  import { SKILLS_COMMAND_NAME, collapseSkillCommands, createSkillsTunnelProvider, } from "./skills-command.js";
8
+ /** The built-in commands resident A1 serves from its tab bar instead: utility tabs, and the tab rename for `/name`. */
9
+ const RESIDENT_UTILITY_TAB_COMMANDS = new Set(["settings", "changelog", "name"]);
8
10
  /** A selected autocomplete row: its arrow/primary column, then the aligned description. */
9
11
  const SELECTED_DESCRIBED_ROW = /^(→ .*?\S)(\s{2,}.*)$/u;
10
12
  const INPUT_COUNTER_INSET = 3;
@@ -62,6 +64,8 @@ export function createPiShellEditor(options) {
62
64
  ensureTheme();
63
65
  const tui = createTuiFacade(options);
64
66
  const inputPresentation = options.keybindingProfile === "a1" ? options.promptPresentation?.input : undefined;
67
+ const inputCapabilities = options.inputCapabilities ?? {};
68
+ const autocompleteEnabled = inputCapabilities.autocomplete !== false;
65
69
  // Invariant: the process shares one manager; a standalone editor gets its own host for its profile.
66
70
  const host = options.keybindings ?? createPiKeybindingsHost({
67
71
  profile: options.keybindingProfile ?? "pi",
@@ -74,7 +78,7 @@ export function createPiShellEditor(options) {
74
78
  }
75
79
  const scrollInfo = { emitted: false, counter: undefined };
76
80
  const selectListTheme = getPiSelectListTheme();
77
- let tunnelSkills = [];
81
+ const autocomplete = { provider: emptyAutocompleteProvider(), skills: [] };
78
82
  const EditorClass = options.keybindingProfile === "a1" && options.persistentHistory === true ? options.historyEditor : OwnedEditor;
79
83
  const editor = new EditorClass(tui, {
80
84
  borderColor: (value) => inputPresentation === undefined ? piTheme().fg("borderMuted", value) : inputPresentation.styleRule(value),
@@ -100,13 +104,14 @@ export function createPiShellEditor(options) {
100
104
  ...(options.keybindingProfile === "a1" ? {
101
105
  terminalRows: options.getRows,
102
106
  getVisualLineCount: (width) => editorVisualLineCount(editor, width),
103
- clearCommandSearchOnEscape: true,
104
- commandTunnels: () => tunnelSkills.length === 0 ? [] : [SKILLS_COMMAND_NAME],
107
+ clearCommandSearchOnEscape: autocompleteEnabled,
108
+ commandTunnels: () => !autocompleteEnabled || autocomplete.skills.length === 0 ? [] : [SKILLS_COMMAND_NAME],
105
109
  } : {}),
106
110
  ...(options.keybindingProfile === "a1" && options.promptPresentation !== undefined ? {
107
111
  ...(inputPresentation === undefined ? {} : { inputPresentation }),
108
112
  styleSuggestion: options.promptPresentation.styleSuggestion,
109
113
  styleSuggestionCaret: options.promptPresentation.styleSuggestionCaret,
114
+ ...(inputCapabilities.placeholder === undefined ? {} : { placeholder: inputCapabilities.placeholder }),
110
115
  } : {}),
111
116
  });
112
117
  const editorUx = options.keybindingProfile === "a1"
@@ -117,6 +122,7 @@ export function createPiShellEditor(options) {
117
122
  ...(options.beginClipboardPaste === undefined ? {} : { beginClipboardPaste: options.beginClipboardPaste }),
118
123
  ...(options.beginTextPaste === undefined ? {} : { beginTextPaste: options.beginTextPaste }),
119
124
  ...(options.deferTextPaste === undefined ? {} : { deferTextPaste: options.deferTextPaste }),
125
+ pasteEnabled: inputCapabilities.paste !== false,
120
126
  ...(options.onPasteRejected === undefined ? {} : { onPasteRejected: options.onPasteRejected }),
121
127
  ...(options.onPasteInput === undefined ? {} : { onPasteInput: options.onPasteInput }),
122
128
  transformPastedContent: options.transformPastedContent ?? (content => content.kind === "text" ? content.text : ""),
@@ -142,36 +148,7 @@ export function createPiShellEditor(options) {
142
148
  : isBashMode ? piTheme().getBashModeBorderColor() : piTheme().getThinkingBorderColor(thinkingLevel);
143
149
  tui.requestRender();
144
150
  };
145
- let autocompleteProvider;
146
- const builtInCatalog = options.keybindingProfile === "a1" ? OWNED_BUILTIN_SLASH_COMMANDS : PINNED_PI_BUILTIN_SLASH_COMMANDS;
147
- const setAutocompleteCommands = (installed) => {
148
- // Invariant: collapse is a bare-A1 presentation; the comparison profile installs the pinned list.
149
- const collapsed = options.keybindingProfile === "a1" && options.skillsPresentation?.() === "collapse"
150
- ? collapseSkillCommands(installed)
151
- : { commands: installed, skills: [] };
152
- tunnelSkills = collapsed.skills;
153
- const commands = collapsed.commands;
154
- const additions = new Map(commands.map(command => [command.name, command]));
155
- const builtInNames = new Set(builtInCatalog.map(command => command.name));
156
- const builtIns = builtInCatalog.flatMap(command => [
157
- autocompleteCommand(command, additions.get(command.name)),
158
- // Rationale: the collapsed browser is a primary bare-A1 command, not a resource after quit.
159
- ...(command.name === "settings" && collapsed.collapsedCommand !== undefined
160
- ? [autocompleteCommand(collapsed.collapsedCommand)]
161
- : []),
162
- ]);
163
- // Invariant: built-in additions and the promoted collapsed browser never reappear as resources.
164
- const resources = commands
165
- .filter(command => command.name !== collapsed.collapsedCommand?.name && command.source !== "builtin" && !builtInNames.has(command.name))
166
- .map(command => autocompleteCommand(command));
167
- const catalog = [...builtIns, ...resources];
168
- const combined = new CombinedAutocompleteProvider(catalog, options.cwd ?? process.cwd());
169
- const tunnelAware = tunnelSkills.length === 0 ? combined : createSkillsTunnelProvider(combined, tunnelSkills);
170
- autocompleteProvider = options.keybindingProfile === "a1"
171
- ? createDelimiterReadyCommandProvider(tunnelAware, catalog)
172
- : tunnelAware;
173
- editor.setAutocompleteProvider(autocompleteProvider);
174
- };
151
+ const setAutocompleteCommands = autocompleteCommandSetter(options, editor, autocomplete, autocompleteEnabled);
175
152
  setAutocompleteCommands(options.autocompleteCommands ?? []);
176
153
  let submitHandler = options.onSubmit;
177
154
  let interruptHandler = options.onInterrupt ?? (() => { });
@@ -258,6 +235,9 @@ export function createPiShellEditor(options) {
258
235
  reloadKeybindings: () => host.reload(),
259
236
  matchesTerminalKey: (data, key) => matchesKey(data, key),
260
237
  handleInput: data => {
238
+ if (inputCapabilities.singleLine === true
239
+ && (keybindings.matches(data, "tui.input.newLine") || keybindings.matches(data, "tui.input.submit")))
240
+ return;
261
241
  // Compatibility: an unassigned reverse Tab must not clear selection or reach autocomplete fallback.
262
242
  if (editorUx !== undefined && matchesKey(data, "shift+tab")
263
243
  && !Object.values(keybindings.getEffectiveConfig()).some(keys => (Array.isArray(keys) ? keys : [keys]).some(key => key !== undefined && matchesKey(data, key))))
@@ -315,13 +295,15 @@ export function createPiShellEditor(options) {
315
295
  tui.requestRender();
316
296
  },
317
297
  addAutocompleteProvider(factory) {
298
+ if (!autocompleteEnabled)
299
+ return;
318
300
  if (typeof factory !== "function")
319
301
  throw new TypeError("extension autocomplete factory must be a function");
320
- const candidate = Reflect.apply(factory, undefined, [autocompleteProvider]);
302
+ const candidate = Reflect.apply(factory, undefined, [autocomplete.provider]);
321
303
  if (!isAutocompleteProvider(candidate))
322
304
  throw new TypeError("extension autocomplete factory returned a malformed provider");
323
- autocompleteProvider = candidate;
324
- editor.setAutocompleteProvider(autocompleteProvider);
305
+ autocomplete.provider = candidate;
306
+ editor.setAutocompleteProvider(autocomplete.provider);
325
307
  },
326
308
  setThinkingLevel(level) {
327
309
  if (thinkingLevel === level)
@@ -346,12 +328,52 @@ export function createPiShellEditor(options) {
346
328
  return editor.canPresentPromptSuggestion() ? null : "prompt-mode";
347
329
  },
348
330
  hasSelection: () => editorUx?.hasSelection() ?? false,
331
+ selectedText: () => editorUx?.selectedText(),
349
332
  ownsPointer: () => editorUx?.ownsPointer() ?? false,
350
333
  handlePointer: event => editorUx?.handlePointer(event) ?? false,
351
334
  pasteClipboard: () => editorUx?.pasteClipboard() ?? false,
352
335
  cancelPendingPastes: () => editorUx?.cancelPendingPastes(),
353
336
  };
354
337
  }
338
+ function autocompleteCommandSetter(options, editor, state, enabled) {
339
+ const builtInCatalog = (options.keybindingProfile === "a1" ? OWNED_BUILTIN_SLASH_COMMANDS : PINNED_PI_BUILTIN_SLASH_COMMANDS)
340
+ .filter(command => !options.hideUtilityTabCommands || !RESIDENT_UTILITY_TAB_COMMANDS.has(command.name));
341
+ return installed => {
342
+ if (!enabled) {
343
+ state.provider = emptyAutocompleteProvider();
344
+ editor.setAutocompleteProvider(state.provider);
345
+ return;
346
+ }
347
+ // Invariant: collapse is a bare-A1 presentation; the comparison profile installs the pinned list.
348
+ const collapsed = options.keybindingProfile === "a1" && options.skillsPresentation?.() === "collapse"
349
+ ? collapseSkillCommands(installed)
350
+ : { commands: installed, skills: [] };
351
+ state.skills = collapsed.skills;
352
+ const additions = new Map(collapsed.commands.map(command => [command.name, command]));
353
+ const builtInNames = new Set(builtInCatalog.map(command => command.name));
354
+ const builtIns = builtInCatalog.flatMap(command => [
355
+ autocompleteCommand(command, additions.get(command.name)),
356
+ // Rationale: the collapsed browser is a primary bare-A1 command, not a resource after quit.
357
+ ...(command.name === "settings" && collapsed.collapsedCommand !== undefined
358
+ ? [autocompleteCommand(collapsed.collapsedCommand)] : []),
359
+ ]);
360
+ const resources = collapsed.commands
361
+ .filter(command => command.name !== collapsed.collapsedCommand?.name && command.source !== "builtin" && !builtInNames.has(command.name))
362
+ .map(command => autocompleteCommand(command));
363
+ const catalog = [...builtIns, ...resources];
364
+ const combined = new CombinedAutocompleteProvider(catalog, options.cwd ?? process.cwd());
365
+ const tunnelAware = state.skills.length === 0 ? combined : createSkillsTunnelProvider(combined, state.skills);
366
+ state.provider = options.keybindingProfile === "a1" ? createDelimiterReadyCommandProvider(tunnelAware, catalog) : tunnelAware;
367
+ editor.setAutocompleteProvider(state.provider);
368
+ };
369
+ }
370
+ function emptyAutocompleteProvider() {
371
+ return {
372
+ getSuggestions: async () => null,
373
+ applyCompletion: (lines, cursorLine, cursorCol) => ({ lines, cursorLine, cursorCol }),
374
+ shouldTriggerFileCompletion: () => false,
375
+ };
376
+ }
355
377
  /** Bare A1 leaves an applied catalog command ready for `:`, a user-entered space, or submission. */
356
378
  function createDelimiterReadyCommandProvider(base, commands) {
357
379
  const commandNames = new Set(commands.map(command => command.name));
@@ -15,22 +15,8 @@ export function createPiExtensionUiBridge(host) {
15
15
  const keybindings = KeybindingsManager.create(host.agentDir);
16
16
  const disposers = new Set();
17
17
  let customEditorFactory;
18
- let activeSurface;
19
- let activeCancel;
20
- const closeSurface = (surface) => {
21
- if (surface !== undefined && activeSurface !== surface)
22
- return;
23
- activeSurface = undefined;
24
- host.setInputSurface(null);
25
- host.runtime.requestRender();
26
- };
27
- const mountSurface = (surface) => {
28
- if (activeSurface !== undefined && activeSurface !== surface)
29
- activeSurface.dispose?.();
30
- activeSurface = surface;
31
- host.setInputSurface(surface);
32
- host.runtime.requestRender();
33
- };
18
+ const dialogs = createExtensionDialogStack(host);
19
+ const overlayCancels = new Set();
34
20
  const trackAbort = (signal, cancel) => {
35
21
  if (signal === undefined)
36
22
  return () => { };
@@ -54,26 +40,24 @@ export function createPiExtensionUiBridge(host) {
54
40
  if (settled)
55
41
  return;
56
42
  settled = true;
57
- if (activeCancel === cancel)
58
- activeCancel = undefined;
59
43
  untrack();
60
- const ownedSurface = activeSurface === surface;
61
- if (retainSurfaceOnSettle && ownedSurface)
62
- activeSurface = undefined;
63
- else
64
- closeSurface(surface);
65
- if (ownedSurface)
66
- host.setProgramStatusBlocked(undefined);
44
+ if (surface !== undefined) {
45
+ const retained = retainSurfaceOnSettle && dialogs.isOnly(surface);
46
+ // Rationale: like pinned Pi, a settled dialog is disposed so its countdown stops, unless it stays painted.
47
+ if (!retained)
48
+ surface.dispose?.();
49
+ dialogs.remove(surface, retained);
50
+ }
67
51
  resolve(value);
68
52
  };
69
53
  const cancel = () => finish(undefined);
70
- surface = create(finish, cancel);
54
+ const created = create(finish, cancel);
55
+ surface = created;
71
56
  untrack = trackAbort(options?.signal, cancel);
72
- if (!settled) {
73
- activeCancel = cancel;
74
- mountSurface(surface);
75
- host.setProgramStatusBlocked(blocked);
76
- }
57
+ if (!settled)
58
+ dialogs.push({ surface: created, blocked, cancel });
59
+ else
60
+ created.dispose?.();
77
61
  });
78
62
  const createFactoryComponent = (factory, ...arguments_) => {
79
63
  if (typeof factory !== "function")
@@ -148,28 +132,26 @@ export function createPiExtensionUiBridge(host) {
148
132
  let settled = false;
149
133
  let surface;
150
134
  let overlay;
151
- const done = (value) => {
152
- if (settled)
153
- return;
154
- settled = true;
155
- if (activeCancel === cancelCustom)
156
- activeCancel = undefined;
157
- overlay?.hide();
158
- if (surface !== undefined)
159
- closeSurface(surface);
160
- resolve(value);
161
- };
162
- const cancelCustom = () => {
135
+ const close = (settle) => {
163
136
  if (settled)
164
137
  return;
165
138
  settled = true;
166
- if (activeCancel === cancelCustom)
167
- activeCancel = undefined;
168
- overlay?.hide();
169
- if (surface !== undefined)
170
- closeSurface(surface);
171
- Reflect.apply(resolve, undefined, []);
139
+ overlayCancels.delete(cancelCustom);
140
+ // Invariant: remove this dialog or overlay, not the topmost one; another may have opened above it.
141
+ if (overlay !== undefined)
142
+ overlay.hide();
143
+ else if (surface !== undefined)
144
+ dialogs.remove(surface);
145
+ settle();
146
+ if (overlay === undefined) {
147
+ try {
148
+ surface?.dispose?.();
149
+ }
150
+ catch { /* Rationale: a settled dialog's dispose failure must not leak. */ }
151
+ }
172
152
  };
153
+ const done = (value) => close(() => resolve(value));
154
+ const cancelCustom = () => close(() => Reflect.apply(resolve, undefined, []));
173
155
  let created;
174
156
  try {
175
157
  created = Reflect.apply(factory, undefined, [tui, piTheme(), keybindings, done]);
@@ -187,19 +169,18 @@ export function createPiExtensionUiBridge(host) {
187
169
  return;
188
170
  }
189
171
  surface = withPiDialogCancel(componentPort(component), cancelCustom);
190
- activeCancel = cancelCustom;
191
172
  if (options?.overlay) {
192
173
  const overlayOptions = typeof options.overlayOptions === "function" ? options.overlayOptions() : options.overlayOptions;
174
+ overlayCancels.add(cancelCustom);
193
175
  overlay = host.showOverlay(surface, overlayOptions);
194
176
  options.onHandle?.(publicOverlayHandle(overlay));
195
177
  }
196
178
  else
197
- mountSurface(surface);
179
+ dialogs.push({ surface, blocked: undefined, cancel: cancelCustom });
198
180
  }).catch(error => {
199
- if (activeCancel === cancelCustom)
200
- activeCancel = undefined;
201
- if (surface !== undefined)
202
- closeSurface(surface);
181
+ overlayCancels.delete(cancelCustom);
182
+ if (surface !== undefined && overlay === undefined)
183
+ dialogs.remove(surface);
203
184
  reject(error);
204
185
  });
205
186
  }),
@@ -251,11 +232,9 @@ export function createPiExtensionUiBridge(host) {
251
232
  setToolsExpanded: expanded => host.setToolsExpanded(expanded),
252
233
  };
253
234
  const reset = () => {
254
- const cancel = activeCancel;
255
- activeCancel = undefined;
256
- cancel?.();
257
- activeSurface?.dispose?.();
258
- activeSurface = undefined;
235
+ dialogs.cancelAll();
236
+ for (const cancel of [...overlayCancels])
237
+ cancel();
259
238
  host.setInputSurface(null);
260
239
  host.setProgramStatusBlocked(undefined);
261
240
  };
@@ -276,6 +255,46 @@ export function createPiExtensionUiBridge(host) {
276
255
  },
277
256
  };
278
257
  }
258
+ /**
259
+ * Pinned Pi's extension dialog stack over the shell's single input slot. The last entry is visible; closing it shows
260
+ * the previous one with its program status, and a covered dialog stays answerable, so no dialog promise is left pending.
261
+ */
262
+ function createExtensionDialogStack(host) {
263
+ const dialogs = [];
264
+ const showTop = () => {
265
+ const top = dialogs.at(-1);
266
+ host.setInputSurface(top?.surface ?? null);
267
+ host.setProgramStatusBlocked(top?.blocked);
268
+ host.runtime.requestRender();
269
+ };
270
+ return {
271
+ push(dialog) {
272
+ dialogs.push(dialog);
273
+ showTop();
274
+ },
275
+ /** Only removing the visible dialog changes the slot; a retained last surface stays painted without its status. */
276
+ remove(surface, retainSurface = false) {
277
+ const index = dialogs.findIndex(dialog => dialog.surface === surface);
278
+ if (index === -1)
279
+ return;
280
+ dialogs.splice(index, 1);
281
+ if (index !== dialogs.length)
282
+ return;
283
+ if (!retainSurface || dialogs.length > 0)
284
+ return showTop();
285
+ host.setProgramStatusBlocked(undefined);
286
+ host.runtime.requestRender();
287
+ },
288
+ isOnly: (surface) => dialogs.length === 1 && dialogs[0].surface === surface,
289
+ /** Rationale: unlike pinned Pi, which drops stacked dialogs unresolved, A1 settles each as cancelled, top first. */
290
+ cancelAll() {
291
+ for (const dialog of [...dialogs].reverse())
292
+ dialog.cancel();
293
+ for (const dialog of dialogs.splice(0))
294
+ dialog.surface.dispose?.();
295
+ },
296
+ };
297
+ }
279
298
  function extensionError(surface, error) {
280
299
  return `Extension ${surface} failed: ${error instanceof Error ? error.message : String(error)}`;
281
300
  }
@@ -4,5 +4,5 @@ import { type PiShellViewComponentPort, type PiShellStatusPort, type PiShellProg
4
4
  export declare function createPiShellHeader(options?: PiShellHeaderOptions): PiShellHeaderPort;
5
5
  export declare function createPiShellLoadedResources(resources: readonly PiShellResourceEntry[], initialExpanded?: boolean): PiShellLoadedResourcesPort;
6
6
  export declare function createPiShellStatus(view: OwnedUiSessionViewModel, progressStatus: PiShellProgressStatusPresentation, runtime?: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">): PiShellStatusPort;
7
- export declare function createPiShellFooter(view: OwnedUiSessionViewModel, cwd: string, profile?: "pi" | "a1", showLevel?: () => boolean): PiShellViewComponentPort;
7
+ export declare function createPiShellFooter(view: OwnedUiSessionViewModel, cwd: string, profile?: "pi" | "a1", showLevel?: () => boolean, showSessionName?: boolean): PiShellViewComponentPort;
8
8
  export declare function createPiQueuedInputStatus(submissions: readonly string[], presentation?: "pinned" | "custom-viewport", getKeybindings?: () => KeybindingsConfig): PiShellQueuedInputPort;
@@ -7,7 +7,7 @@ import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
7
7
  import { StatusIndicator, WorkingStatusIndicator } from "./upstream/components/status-indicator.js";
8
8
  import { protectPiPromptChipPresentation } from "./prompt-chip-presentation.js";
9
9
  import { PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
10
- import { createTuiFacade, ensureTheme, } from "./shell-shared-facade.js";
10
+ import { createTuiFacade, ensureTheme, piShellTruncateToWidth, piShellVisibleWidth, } from "./shell-shared-facade.js";
11
11
  export function createPiShellHeader(options = {}) {
12
12
  ensureTheme();
13
13
  let expanded = options.expanded ?? false;
@@ -107,9 +107,9 @@ export function createPiShellStatus(view, progressStatus, runtime) {
107
107
  component = statusComponent(view, statusUi, outputPad, liveStatusText, placement, progressPresentation, progressStatus);
108
108
  };
109
109
  return {
110
- render: width => component?.render(width) ?? [],
110
+ render: width => appendInstalledUpdateStatus(component?.render(width) ?? [], width, view),
111
111
  renderDock: width => placement === "dock" ? component?.render(width) ?? [] : [],
112
- renderLive: width => placement === "live" ? component?.render(width) ?? [] : [],
112
+ renderLive: width => appendInstalledUpdateStatus(placement === "live" ? component?.render(width) ?? [] : [], width, view),
113
113
  placement: () => placement,
114
114
  invalidate: () => component?.invalidate(),
115
115
  update(next) {
@@ -136,9 +136,9 @@ export function createPiShellStatus(view, progressStatus, runtime) {
136
136
  },
137
137
  };
138
138
  }
139
- export function createPiShellFooter(view, cwd, profile = "pi", showLevel = () => true) {
139
+ export function createPiShellFooter(view, cwd, profile = "pi", showLevel = () => true, showSessionName = true) {
140
140
  ensureTheme();
141
- const footer = new SessionFooter(() => view, cwd, profile, showLevel);
141
+ const footer = new SessionFooter(() => view, cwd, profile, showLevel, showSessionName);
142
142
  return {
143
143
  render: width => footer.render(width),
144
144
  invalidate: () => footer.invalidate(),
@@ -228,6 +228,22 @@ function statusSignature(view, workingOverride, outputPad, placement, progressPr
228
228
  const message = withMessage ? `${workingOverride ?? ""}\u0000${view.status.workingMessage ?? ""}\u0000${view.status.workingProgress ?? ""}` : "";
229
229
  return `${placement}\u0000${outputPad}\u0000${view.lifecycle}\u0000${progressPresentation}\u0000${message}\u0000${view.status.diagnostics.at(-1) ?? ""}`;
230
230
  }
231
+ function appendInstalledUpdateStatus(rows, width, view) {
232
+ if (width <= 0 || !view.diagnostics.some(diagnostic => diagnostic.code === "release-update-installed"))
233
+ return rows;
234
+ const theme = piTheme();
235
+ const full = `${theme.fg("success", "Update installed")} ${theme.fg("muted", "·")} ${theme.fg("accent", "Restart to update")}`;
236
+ const status = piShellTruncateToWidth(full, width);
237
+ const statusWidth = piShellVisibleWidth(status);
238
+ const target = rows.findLastIndex(row => piShellVisibleWidth(row.trimEnd()) > 0);
239
+ if (target < 0)
240
+ return [`${" ".repeat(Math.max(0, width - statusWidth))}${status}`];
241
+ const base = (rows[target] ?? "").trimEnd();
242
+ const gap = width - piShellVisibleWidth(base) - statusWidth;
243
+ if (gap >= 2)
244
+ return rows.map((row, index) => index === target ? `${base}${" ".repeat(gap)}${status}` : row);
245
+ return [...rows.slice(0, target + 1), `${" ".repeat(Math.max(0, width - statusWidth))}${status}`, ...rows.slice(target + 1)];
246
+ }
231
247
  function queuedInputChipWrapping(text, presentation, width) {
232
248
  return presentation === "custom-viewport"
233
249
  ? protectPiPromptChipPresentation(text, width)
@@ -6,7 +6,7 @@ import { hotkeysMarkdown } from "./shell-presenters-info.js";
6
6
  export function renderPiShellHotkeySections(presentation, width) {
7
7
  ensureTheme();
8
8
  const shortcuts = presentation.getShortcuts ?? (() => []);
9
- const markdown = hotkeysMarkdown(presentation.bindings, shortcuts, presentation.profile ?? "pi");
9
+ const markdown = hotkeysMarkdown(presentation.bindings, shortcuts, presentation.profile ?? "pi", presentation.residentTabs);
10
10
  const sections = [];
11
11
  for (const line of markdown.split("\n")) {
12
12
  const heading = /^\*\*(.+)\*\*$/.exec(line)?.[1];