@timurproko/a1 0.2.6-dev.736 → 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 (423) 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/resources/release-notes.json +4 -0
  104. package/dist/features/owned-ui/settings-app.d.ts +12 -2
  105. package/dist/features/owned-ui/settings-app.js +119 -84
  106. package/dist/features/owned-ui/settings-search-input.d.ts +29 -0
  107. package/dist/features/owned-ui/settings-search-input.js +1 -0
  108. package/dist/features/prompt-history/index.d.ts +1 -1
  109. package/dist/features/prompt-history/paths.d.ts +2 -1
  110. package/dist/features/prompt-history/paths.js +10 -2
  111. package/dist/features/prompt-history/service.d.ts +5 -0
  112. package/dist/features/prompt-history/service.js +1 -1
  113. package/dist/features/resident-tab/auto-name.d.ts +11 -0
  114. package/dist/features/resident-tab/auto-name.js +44 -0
  115. package/dist/features/resident-tab/index.d.ts +5 -0
  116. package/dist/features/resident-tab/index.js +7 -0
  117. package/dist/features/resident-tab/shortcut-bindings-file.d.ts +8 -0
  118. package/dist/features/resident-tab/shortcut-bindings-file.js +40 -0
  119. package/dist/features/resident-tab/shortcut-declarations.d.ts +13 -0
  120. package/dist/features/resident-tab/shortcut-declarations.js +26 -0
  121. package/dist/features/resident-tab/shortcut-projection.d.ts +29 -0
  122. package/dist/features/resident-tab/shortcut-projection.js +64 -0
  123. package/dist/features/resident-tab/status-deriver.d.ts +10 -0
  124. package/dist/features/resident-tab/status-deriver.js +12 -0
  125. package/dist/foundation/launch-context/index.d.ts +12 -0
  126. package/dist/foundation/launch-context/index.js +26 -0
  127. package/dist/foundation/launch-guardian/exit-watcher.d.ts +14 -0
  128. package/dist/foundation/launch-guardian/exit-watcher.js +94 -0
  129. package/dist/foundation/launch-guardian/main.d.ts +7 -1
  130. package/dist/foundation/launch-guardian/main.js +60 -7
  131. package/dist/foundation/lifecycle/session-repository-context.js +16 -2
  132. package/dist/foundation/process-containment/{native-guardian-containment.d.ts → addon-containment.d.ts} +7 -5
  133. package/dist/foundation/process-containment/addon-containment.js +139 -0
  134. package/dist/foundation/process-containment/addon-process-inspector.d.ts +11 -0
  135. package/dist/foundation/process-containment/addon-process-inspector.js +36 -0
  136. package/dist/foundation/process-containment/addon.d.ts +42 -0
  137. package/dist/foundation/process-containment/addon.js +57 -0
  138. package/dist/foundation/process-containment/artifact.d.ts +1 -1
  139. package/dist/foundation/process-containment/artifact.js +6 -5
  140. package/dist/foundation/process-containment/contracts.d.ts +2 -0
  141. package/dist/foundation/process-containment/index.d.ts +4 -4
  142. package/dist/foundation/process-containment/index.js +3 -3
  143. package/dist/foundation/process-containment/native-process-inspector.d.ts +2 -1
  144. package/dist/foundation/process-containment/native-process-inspector.js +10 -10
  145. package/dist/foundation/release/automatic-update.d.ts +37 -0
  146. package/dist/foundation/release/automatic-update.js +265 -0
  147. package/dist/foundation/release/bootstrap.d.ts +7 -9
  148. package/dist/foundation/release/bootstrap.js +107 -24
  149. package/dist/foundation/release/cohort-state.d.ts +1 -1
  150. package/dist/foundation/release/cohort-state.js +6 -3
  151. package/dist/foundation/release/dependency-certification.js +54 -19
  152. package/dist/foundation/release/early-accent.d.ts +12 -0
  153. package/dist/foundation/release/early-accent.js +59 -0
  154. package/dist/foundation/release/index.d.ts +2 -2
  155. package/dist/foundation/release/index.js +2 -2
  156. package/dist/foundation/release/latest-release.d.ts +24 -2
  157. package/dist/foundation/release/latest-release.js +51 -1
  158. package/dist/foundation/release/progress-palette.generated.d.ts +137 -3
  159. package/dist/foundation/release/progress-palette.generated.js +137 -3
  160. package/dist/foundation/release/release-gc.d.ts +3 -0
  161. package/dist/foundation/release/release-gc.js +59 -8
  162. package/dist/foundation/release/release-store.d.ts +12 -0
  163. package/dist/foundation/release/release-store.js +124 -2
  164. package/dist/foundation/release/update-execution-lease.d.ts +48 -0
  165. package/dist/foundation/release/update-execution-lease.js +161 -0
  166. package/dist/foundation/release/update.d.ts +12 -7
  167. package/dist/foundation/release/update.js +281 -196
  168. package/dist/foundation/resident-tabs/bounded-host-command.d.ts +18 -0
  169. package/dist/foundation/resident-tabs/bounded-host-command.js +39 -0
  170. package/dist/foundation/resident-tabs/bridge-client.d.ts +70 -0
  171. package/dist/foundation/resident-tabs/bridge-client.js +321 -0
  172. package/dist/foundation/resident-tabs/doctor.d.ts +28 -0
  173. package/dist/foundation/resident-tabs/doctor.js +166 -0
  174. package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +27 -0
  175. package/dist/foundation/resident-tabs/draft-checkpoint.js +145 -0
  176. package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +36 -0
  177. package/dist/foundation/resident-tabs/ensure-terminal-host.js +151 -0
  178. package/dist/foundation/resident-tabs/fault-injection.d.ts +8 -0
  179. package/dist/foundation/resident-tabs/fault-injection.js +26 -0
  180. package/dist/foundation/resident-tabs/fixture-control.d.ts +7 -0
  181. package/dist/foundation/resident-tabs/fixture-control.js +35 -0
  182. package/dist/foundation/resident-tabs/host-entry.d.ts +1 -0
  183. package/dist/foundation/resident-tabs/host-entry.js +17 -0
  184. package/dist/foundation/resident-tabs/index.d.ts +12 -0
  185. package/dist/foundation/resident-tabs/index.js +6 -0
  186. package/dist/foundation/resident-tabs/maintenance.d.ts +39 -0
  187. package/dist/foundation/resident-tabs/maintenance.js +75 -0
  188. package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +34 -0
  189. package/dist/foundation/resident-tabs/progress-observation-schema.js +1 -0
  190. package/dist/foundation/resident-tabs/progress-observation.d.ts +4 -0
  191. package/dist/foundation/resident-tabs/progress-observation.js +150 -0
  192. package/dist/foundation/resident-tabs/prompt-journal.d.ts +63 -0
  193. package/dist/foundation/resident-tabs/prompt-journal.js +213 -0
  194. package/dist/foundation/resident-tabs/protocol.d.ts +12 -0
  195. package/dist/foundation/resident-tabs/protocol.js +195 -0
  196. package/dist/foundation/resident-tabs/recovery.d.ts +26 -0
  197. package/dist/foundation/resident-tabs/recovery.js +205 -0
  198. package/dist/foundation/resident-tabs/release-holds.d.ts +28 -0
  199. package/dist/foundation/resident-tabs/release-holds.js +75 -0
  200. package/dist/foundation/resident-tabs/routes.d.ts +5 -0
  201. package/dist/foundation/resident-tabs/routes.js +5 -0
  202. package/dist/foundation/resident-tabs/routing.d.ts +11 -0
  203. package/dist/foundation/resident-tabs/routing.js +10 -0
  204. package/dist/foundation/resident-tabs/session-sync.d.ts +14 -0
  205. package/dist/foundation/resident-tabs/session-sync.js +37 -0
  206. package/dist/foundation/resident-tabs/settings.d.ts +12 -0
  207. package/dist/foundation/resident-tabs/settings.js +58 -0
  208. package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +14 -0
  209. package/dist/foundation/resident-tabs/terminal-host-artifact.js +78 -0
  210. package/dist/foundation/resident-tabs/zip-archive.d.ts +9 -0
  211. package/dist/foundation/resident-tabs/zip-archive.js +56 -0
  212. package/dist/foundation/session-writer-lock/index.d.ts +30 -0
  213. package/dist/foundation/session-writer-lock/index.js +203 -0
  214. package/dist/foundation/startup/startup-descriptor.js +2 -2
  215. package/dist/foundation/terminal-cleanup/index.d.ts +1 -1
  216. package/dist/foundation/terminal-cleanup/index.js +1 -1
  217. package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +6 -0
  218. package/dist/foundation/terminal-cleanup/terminal-reset.js +6 -0
  219. package/dist/integrations/pi/components/editor-interaction.d.ts +2 -0
  220. package/dist/integrations/pi/components/modal-frame.d.ts +17 -1
  221. package/dist/integrations/pi/components/modal-frame.js +48 -9
  222. package/dist/integrations/pi/components/models-dialog.js +4 -52
  223. package/dist/integrations/pi/components/owned-editor-ux.d.ts +6 -1
  224. package/dist/integrations/pi/components/owned-editor-ux.js +90 -6
  225. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +4 -4
  226. package/dist/integrations/pi/components/resources/builtin-themes.js +4 -4
  227. package/dist/integrations/pi/components/share-operation-dialog.d.ts +2 -0
  228. package/dist/integrations/pi/components/share-operation-dialog.js +2 -1
  229. package/dist/integrations/pi/components/shell-editor-autocomplete.js +58 -36
  230. package/dist/integrations/pi/components/shell-extension-ui.js +79 -60
  231. package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
  232. package/dist/integrations/pi/components/shell-footer-status.js +21 -5
  233. package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
  234. package/dist/integrations/pi/components/shell-presenters-info.d.ts +5 -2
  235. package/dist/integrations/pi/components/shell-presenters-info.js +18 -4
  236. package/dist/integrations/pi/components/shell-presenters-transcript.js +4 -1
  237. package/dist/integrations/pi/components/shell-selectors-dialogs.js +5 -1
  238. package/dist/integrations/pi/components/shell-shared-facade.d.ts +12 -1
  239. package/dist/integrations/pi/components/skills-dialog.js +2 -2
  240. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
  241. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +17 -4
  242. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
  243. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
  244. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
  245. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
  246. package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
  247. package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
  248. package/dist/integrations/pi/components/upstream/components/extension-selector.js +1 -1
  249. package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
  250. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +8 -6
  251. package/dist/integrations/pi/components/upstream/components/owned-editor.js +16 -9
  252. package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
  253. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +4 -4
  254. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +2 -2
  255. package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
  256. package/dist/integrations/pi/components/upstream/components/session-footer.js +31 -25
  257. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
  258. package/dist/integrations/pi/components/upstream/components/session-selector.js +8 -7
  259. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
  260. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
  261. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +2 -2
  262. package/dist/integrations/pi/components/upstream/components/status-indicator.js +3 -3
  263. package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
  264. package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
  265. package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +8 -7
  266. package/dist/integrations/pi/components/upstream/components/thinking-selector.js +10 -9
  267. package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +2 -6
  268. package/dist/integrations/pi/components/upstream/components/tool-execution.js +103 -101
  269. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +9 -9
  270. package/dist/integrations/pi/components/upstream/components/tree-selector.js +13 -21
  271. package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
  272. package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
  273. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +2 -2
  274. package/dist/integrations/pi/components/upstream/history/editor-core.js +7 -5
  275. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
  276. package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
  277. package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
  278. package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
  279. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
  280. package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
  281. package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
  282. package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
  283. package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +1 -1
  284. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
  285. package/dist/integrations/pi/components/upstream/theme/theme.d.ts +5 -0
  286. package/dist/integrations/pi/components/upstream/theme/theme.js +29 -2
  287. package/dist/integrations/pi/engine/adapter.d.ts +5 -77
  288. package/dist/integrations/pi/engine/adapter.js +95 -394
  289. package/dist/integrations/pi/engine/command-dispatch.d.ts +13 -0
  290. package/dist/integrations/pi/engine/command-dispatch.js +57 -0
  291. package/dist/integrations/pi/engine/host.js +2 -2
  292. package/dist/integrations/pi/engine/offline-settings-port.d.ts +23 -0
  293. package/dist/integrations/pi/engine/offline-settings-port.js +53 -0
  294. package/dist/integrations/pi/engine/pi-settings-metadata.json +14 -2
  295. package/dist/integrations/pi/engine/ports.d.ts +56 -0
  296. package/dist/integrations/pi/engine/ports.js +93 -0
  297. package/dist/integrations/pi/engine/prompt-suggestions.d.ts +1 -0
  298. package/dist/integrations/pi/engine/prompt-suggestions.js +40 -0
  299. package/dist/integrations/pi/engine/resources/changelog.json +4 -4
  300. package/dist/integrations/pi/engine/runtime-integration.js +102 -29
  301. package/dist/integrations/pi/engine/session-runtime.d.ts +0 -6
  302. package/dist/integrations/pi/engine/session-runtime.js +13 -5
  303. package/dist/integrations/pi/engine/session-selection.d.ts +3 -0
  304. package/dist/integrations/pi/engine/session-selection.js +45 -9
  305. package/dist/integrations/pi/engine/settings-bridge.d.ts +5 -0
  306. package/dist/integrations/pi/engine/settings-bridge.js +15 -0
  307. package/dist/integrations/pi/engine/settings-port.js +11 -15
  308. package/dist/integrations/pi/engine/view-state.d.ts +42 -0
  309. package/dist/integrations/pi/engine/view-state.js +126 -0
  310. package/dist/integrations/pi/engine/workflow-contexts.js +10 -1
  311. package/dist/integrations/pi/engine/workflow-runner.js +73 -4
  312. package/dist/integrations/pi/engine/workflow-support.d.ts +12 -0
  313. package/dist/integrations/pi/engine/workflow-support.js +36 -0
  314. package/dist/integrations/pi/engine/workflows.d.ts +3 -1
  315. package/dist/integrations/pi/engine/workflows.js +1 -0
  316. package/dist/integrations/pi/startup-public.js +257 -310
  317. package/dist/integrations/pi/startup-public.manifest.json +564 -440
  318. package/dist/integrations/pi/tui-runtime/adapter.d.ts +6 -0
  319. package/dist/integrations/pi/tui-runtime/adapter.js +32 -1
  320. package/dist/integrations/pi/tui-runtime/contracts.d.ts +5 -0
  321. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +12 -1
  322. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +31 -2
  323. package/dist/native/darwin-arm64/manifest.json +10 -7
  324. package/dist/native/darwin-arm64/process-guardian.node +0 -0
  325. package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +10500 -0
  326. package/dist/native/darwin-arm64/terminal-host.manifest.json +46 -0
  327. package/dist/native/darwin-arm64/terminal-host.node +0 -0
  328. package/dist/native/darwin-x64/manifest.json +23 -0
  329. package/dist/native/darwin-x64/process-guardian.node +0 -0
  330. package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10737 -0
  331. package/dist/native/darwin-x64/terminal-host.manifest.json +46 -0
  332. package/dist/native/darwin-x64/terminal-host.node +0 -0
  333. package/dist/native/linux-x64/manifest.json +10 -7
  334. package/dist/native/linux-x64/process-guardian.node +0 -0
  335. package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +11226 -0
  336. package/dist/native/linux-x64/terminal-host.manifest.json +46 -0
  337. package/dist/native/linux-x64/terminal-host.node +0 -0
  338. package/dist/native/win32-x64/manifest.json +10 -7
  339. package/dist/native/win32-x64/process-guardian.node +0 -0
  340. package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10757 -0
  341. package/dist/native/win32-x64/terminal-host.manifest.json +46 -0
  342. package/dist/native/win32-x64/terminal-host.node +0 -0
  343. package/dist/product-identity.d.ts +3 -3
  344. package/dist/product-identity.js +4 -4
  345. package/dist/product-identity.json +16 -2
  346. package/dist/runtime-payload-inventory.json +6330 -6677
  347. package/dist/ui/apps/host.d.ts +2 -0
  348. package/dist/ui/apps/host.js +7 -1
  349. package/dist/ui/components/dialog-panel.js +35 -30
  350. package/dist/ui/components/index.d.ts +2 -2
  351. package/dist/ui/components/index.js +1 -1
  352. package/dist/ui/components/line-input.d.ts +4 -1
  353. package/dist/ui/components/line-input.js +3 -1
  354. package/dist/ui/components/prompt-input.d.ts +11 -8
  355. package/dist/ui/components/prompt-input.js +15 -13
  356. package/dist/ui/components/selection-copy.d.ts +2 -0
  357. package/dist/ui/components/selection-copy.js +13 -0
  358. package/dist/ui/components/spans.js +2 -2
  359. package/dist/ui/components/submitted-prompt.d.ts +9 -6
  360. package/dist/ui/components/submitted-prompt.js +20 -12
  361. package/dist/ui/components/surface.js +4 -2
  362. package/dist/ui/components/text.d.ts +3 -6
  363. package/dist/ui/components/text.js +6 -8
  364. package/dist/ui/components/transcript-viewport.d.ts +9 -2
  365. package/dist/ui/components/transcript-viewport.js +176 -55
  366. package/dist/ui/components/value-menu.d.ts +6 -3
  367. package/dist/ui/components/value-menu.js +6 -5
  368. package/dist/ui/settings/declarations.d.ts +90 -16
  369. package/dist/ui/settings/declarations.js +67 -14
  370. package/dist/ui/settings/early-accent.d.ts +81 -0
  371. package/dist/ui/settings/early-accent.js +50 -0
  372. package/dist/ui/settings/index.d.ts +4 -2
  373. package/dist/ui/settings/index.js +2 -1
  374. package/dist/ui/settings/manager.d.ts +16 -3
  375. package/dist/ui/settings/manager.js +122 -33
  376. package/dist/ui/settings/migrations.d.ts +6 -0
  377. package/dist/ui/settings/migrations.js +73 -0
  378. package/dist/ui/settings/profile-document.d.ts +26 -0
  379. package/dist/ui/settings/profile-document.js +164 -0
  380. package/dist/ui/settings/progress-palette.generated.d.ts +139 -0
  381. package/dist/ui/settings/progress-palette.generated.js +139 -0
  382. package/dist/ui/settings/sections.d.ts +4 -0
  383. package/dist/ui/settings/sections.js +9 -3
  384. package/docs/architecture/boundaries.md +25 -10
  385. package/docs/architecture/evidence/resident-tabs/linux-x64.md +37 -0
  386. package/docs/architecture/evidence/resident-tabs/macos-arm64.md +36 -0
  387. package/docs/architecture/evidence/resident-tabs/macos-x64.md +35 -0
  388. package/docs/architecture/evidence/resident-tabs/windows-x64.md +36 -0
  389. package/docs/architecture/evidence/terminal-host-spike/manual-one-pane-terminal-host.md +70 -0
  390. package/docs/architecture/evidence/terminal-host-spike/manual-two-by-two-basic-terminal-host.md +32 -0
  391. package/docs/architecture/evidence/terminal-host-spike/milestone-baseline.json +115 -0
  392. package/docs/architecture/evidence/terminal-host-spike/owned-ui-foundation-prerequisite.json +48 -0
  393. package/docs/architecture/evidence/terminal-host-spike/terminal-host-provenance.json +125 -0
  394. package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-1.json +56 -0
  395. package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-3.json +174 -0
  396. package/docs/architecture/evidence/terminal-host-spike/terminal-spike-acceptance-record.json +18 -0
  397. package/docs/architecture/internal-naming.md +3 -1
  398. package/docs/architecture/process-guardian-provenance.md +18 -10
  399. package/docs/architecture/project-structure.md +8 -0
  400. package/docs/architecture/resident-tabs-requirements.md +18 -0
  401. package/docs/architecture/resident-tabs.md +648 -0
  402. package/docs/architecture/response-copy-delivery.md +1 -1
  403. package/docs/architecture/terminal-host-proof-gate.md +3 -1
  404. package/docs/architecture/terminal-host-provenance.md +16 -4
  405. package/docs/architecture/terminal-host-spike-evidence.md +1 -1
  406. package/docs/architecture/tool-image-presentation.md +2 -1
  407. package/docs/architecture/toolchain.md +11 -9
  408. package/docs/ci-release-runbook.md +14 -7
  409. package/docs/features/launch-profiles.md +11 -8
  410. package/docs/features/prompt-history.md +41 -20
  411. package/docs/manual-resident-tabs-acceptance.md +51 -0
  412. package/docs/openspec-archive-automation.md +49 -22
  413. package/docs/releases/0.2.6.md +44 -0
  414. package/docs/validation.md +49 -9
  415. package/package.json +19 -6
  416. package/dist/foundation/process-containment/darwin-process-inspector.d.ts +0 -5
  417. package/dist/foundation/process-containment/darwin-process-inspector.js +0 -7
  418. package/dist/foundation/process-containment/native-guardian-containment.js +0 -152
  419. package/dist/foundation/process-containment/windows-process-inspector.d.ts +0 -19
  420. package/dist/foundation/process-containment/windows-process-inspector.js +0 -56
  421. package/dist/native/darwin-arm64/process-guardian +0 -0
  422. package/dist/native/linux-x64/process-guardian +0 -0
  423. package/dist/native/win32-x64/process-guardian.exe +0 -0
@@ -0,0 +1,174 @@
1
+ import { createPiShellArmin, createPiShellEarendilAnnouncement, } from "../../integrations/pi/components/shell-selectors-dialogs.js";
2
+ import { createPiShellChangelog, createPiShellHotkeys, createPiShellSessionInfo, renderPiShellCommandMessage, renderPiShellStatusText, } from "../../integrations/pi/components/shell-presenters-info.js";
3
+ import { piShellHyperlink } from "../../integrations/pi/components/shell-shared-facade.js";
4
+ /**
5
+ * Presents workflow results: bare A1 answers in the dock notice, the pinned profile appends
6
+ * transcript-anchored output, and consecutive status lines at the same anchor replace each other.
7
+ */
8
+ export class WorkflowOutput {
9
+ #ports;
10
+ #sequence = 0;
11
+ #statusMessages = new Map();
12
+ #lastStatusId;
13
+ constructor(ports) {
14
+ this.#ports = ports;
15
+ }
16
+ appendStatus(message) {
17
+ // Rationale: bare A1 acknowledges commands in one dock notice above the editor, where the
18
+ // reader's eye already is, instead of a transcript row that opens an empty session at the
19
+ // top-left or sinks into a long feed. The pinned route keeps Pi's chat placement.
20
+ if (this.#ports.customViewport) {
21
+ this.#ports.dock.setNotice({ kind: "status", message });
22
+ return;
23
+ }
24
+ const { document } = this.#ports;
25
+ const previousId = this.#lastStatusId;
26
+ if (previousId !== undefined
27
+ && document.lastId === previousId
28
+ && document.anchorOf(previousId) === this.#ports.transcriptLength()) {
29
+ this.#statusMessages.set(previousId, message);
30
+ document.invalidate("workflow-status");
31
+ this.#ports.invalidate();
32
+ return;
33
+ }
34
+ const id = this.#appendAnchored(width => [
35
+ "",
36
+ ...renderPiShellStatusText(this.#statusMessages.get(id) ?? message, width),
37
+ ]);
38
+ this.#statusMessages.set(id, message);
39
+ this.#lastStatusId = id;
40
+ }
41
+ appendMessage(message, errorCode) {
42
+ if (message.kind === "status") {
43
+ this.appendStatus(message.message);
44
+ return;
45
+ }
46
+ if (this.#ports.customViewport && (message.kind === "warning" || message.kind === "error")) {
47
+ this.#ports.dock.setNotice({
48
+ kind: errorCode === "image-count" ? "warning" : message.kind,
49
+ message: message.message,
50
+ ...(errorCode === undefined ? {} : { errorCode }),
51
+ });
52
+ return;
53
+ }
54
+ this.#lastStatusId = undefined;
55
+ const presentation = { kind: message.kind, message: message.message };
56
+ this.#appendAnchored(width => renderPiShellCommandMessage(presentation, width, this.#ports.outputPad()));
57
+ }
58
+ appendResult(result, errorCode) {
59
+ if (result.messages !== undefined) {
60
+ for (const message of result.messages)
61
+ this.appendMessage(message, errorCode);
62
+ return;
63
+ }
64
+ if (result.messageKind === "silent" || (result.outcome === "cancelled" && result.messageKind === undefined))
65
+ return;
66
+ if (result.command === "reload" && result.outcome === "completed") {
67
+ this.appendStatus(result.message);
68
+ return;
69
+ }
70
+ if (result.outcome === "completed" && this.#appendPresentation(result))
71
+ return;
72
+ if (result.outcome === "failed") {
73
+ this.appendMessage({
74
+ kind: result.messageKind === "warning" ? "warning" : "error",
75
+ message: result.message,
76
+ }, errorCode);
77
+ return;
78
+ }
79
+ if (result.outcome === "completed" && (result.command === "quit" || result.command === "compact"))
80
+ return;
81
+ if (result.outcome === "completed" && result.command === "new" && this.#ports.customViewport) {
82
+ // Rationale: bare A1 keeps the replacement session visually empty while preserving Pi's accent notice shape.
83
+ this.#ports.dock.setNotice({ kind: "new-session", message: result.message });
84
+ return;
85
+ }
86
+ if (result.outcome === "completed" && (result.command === "new" || result.command === "name" || result.command === "debug")) {
87
+ this.#lastStatusId = undefined;
88
+ const presentation = { kind: result.command, message: result.message, ...(result.detail === undefined ? {} : { detail: result.detail }) };
89
+ this.#appendAnchored(width => renderPiShellCommandMessage(presentation, width, this.#ports.outputPad()));
90
+ return;
91
+ }
92
+ if (result.outcome === "completed" && this.#appendAnnouncement(result.command))
93
+ return;
94
+ // Rationale: the pinned engine links both share URLs; the workflow result carries the plain URLs.
95
+ const message = result.command !== "share" ? result.message
96
+ : result.detail ? `${linkShareUrl(result.message)}\nGist: ${piShellHyperlink(result.detail)}`
97
+ // Protocol: Radius shares carry only the artifact URL.
98
+ : linkShareUrl(result.message);
99
+ this.appendStatus(message);
100
+ }
101
+ /** Drops every anchored output and the status-replacement chain. */
102
+ reset() {
103
+ this.#ports.document.removeAnchored();
104
+ this.#statusMessages.clear();
105
+ this.#lastStatusId = undefined;
106
+ }
107
+ // Invariant: session info, hotkeys, and changelog draw their own components; false for any other completed command.
108
+ #appendPresentation(result) {
109
+ if (result.command === "session" && result.presentation?.kind === "session-info") {
110
+ this.#lastStatusId = undefined;
111
+ const sessionInfo = createPiShellSessionInfo(result.presentation);
112
+ this.#appendAnchored(width => sessionInfo.render(width), () => sessionInfo.dispose?.());
113
+ return true;
114
+ }
115
+ if (result.command === "hotkeys") {
116
+ this.#lastStatusId = undefined;
117
+ const presentation = this.#ports.hotkeysPresentation();
118
+ const hotkeys = createPiShellHotkeys(presentation.bindings, presentation.getShortcuts, presentation.profile, presentation.residentTabs);
119
+ this.#appendAnchored(width => hotkeys.render(width), () => hotkeys.dispose?.());
120
+ return true;
121
+ }
122
+ if (result.command === "changelog") {
123
+ this.#lastStatusId = undefined;
124
+ const changelog = createPiShellChangelog(result.detail ?? "No changelog entries found.");
125
+ this.#appendAnchored(width => changelog.render(width), () => changelog.dispose?.());
126
+ return true;
127
+ }
128
+ return false;
129
+ }
130
+ // Invariant: the two easter-egg announcements; false for any other command.
131
+ #appendAnnouncement(command) {
132
+ if (command === "arminsayshi") {
133
+ this.#lastStatusId = undefined;
134
+ const armin = createPiShellArmin(this.#ports.componentRuntime);
135
+ this.#appendAnchored(width => ["", ...armin.render(width)], () => armin.dispose?.());
136
+ return true;
137
+ }
138
+ if (command === "dementedelves") {
139
+ this.#lastStatusId = undefined;
140
+ const announcement = createPiShellEarendilAnnouncement();
141
+ this.#appendAnchored(width => ["", ...announcement.render(width)], () => announcement.dispose?.());
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+ #appendAnchored(render, dispose) {
147
+ // Invariant: transcript-bound workflow output supersedes a pending acknowledgement.
148
+ this.#ports.dock.dismissNotice();
149
+ this.#sequence += 1;
150
+ const id = `workflow-status-${this.#sequence}`;
151
+ const component = {
152
+ id,
153
+ revision: 1,
154
+ render,
155
+ handleInput() { },
156
+ invalidate() { },
157
+ update() { },
158
+ setExpanded() { },
159
+ setOutputPad() { },
160
+ setHideThinkingBlock() { },
161
+ setMermaidRenderingMode() { },
162
+ setImagePresentation() { },
163
+ ...(dispose === undefined ? {} : { dispose }),
164
+ };
165
+ this.#ports.document.appendAnchored(id, component, this.#ports.transcriptLength());
166
+ this.#ports.invalidate();
167
+ return id;
168
+ }
169
+ }
170
+ /** "Share URL: <url>" with the URL made clickable; other share wordings pass through unchanged. */
171
+ function linkShareUrl(message) {
172
+ const match = /^Share URL: (\S+)$/.exec(message);
173
+ return match === null ? message : `Share URL: ${piShellHyperlink(match[1])}`;
174
+ }
@@ -0,0 +1,25 @@
1
+ import type { OwnedUiCommandResult, OwnedUiWorkflowRequest } from "../../contracts/owned-ui/index.js";
2
+ /** The owned selectors a workflow can open in place of asking the engine to choose. */
3
+ export interface WorkflowSelectors {
4
+ showScopedModelsSelector(): void;
5
+ showModelsDialog(initialQuery?: string): void;
6
+ showModelSelector(initialSearchInput?: string): void;
7
+ showForkSelector(): void;
8
+ showThinkingSelector(): Promise<void>;
9
+ showTrustSelector(): void;
10
+ showSettingsSelector(): void;
11
+ showSessionSelector(): Promise<void>;
12
+ showLoginAuthTypeSelector(): void;
13
+ showLoginMethodSelector(providerReference: string): void;
14
+ showLogoutSelector(): Promise<void>;
15
+ showTreeSelector(): Promise<void>;
16
+ }
17
+ /**
18
+ * Opens the owned selector a workflow request asks for when the user has not chosen yet. Returns
19
+ * the command result when a selector handled the request, settling once an asynchronous selector
20
+ * has opened, or undefined when the request goes to the engine. The decision itself is synchronous,
21
+ * so a request that goes to the engine reaches it in the same turn.
22
+ */
23
+ export declare function openWorkflowSelector(request: OwnedUiWorkflowRequest, selectors: WorkflowSelectors, options: {
24
+ readonly residentTab: boolean;
25
+ }): OwnedUiCommandResult | Promise<OwnedUiCommandResult> | undefined;
@@ -0,0 +1,39 @@
1
+ const unchosen = (request) => request.selection === undefined && request.confirmed === undefined;
2
+ const unchosenBare = (request) => unchosen(request) && request.argument.trim().length === 0;
3
+ // Invariant: the routes are checked in this order, matching the order the workflows were introduced.
4
+ const SELECTOR_ROUTES = [
5
+ { command: "scoped-models", pending: unchosen, open: selectors => selectors.showScopedModelsSelector() },
6
+ { command: "models", pending: request => request.selection === undefined, open: (selectors, request) => selectors.showModelsDialog(request.argument.trim() || undefined) },
7
+ { command: "model", pending: unchosenBare, open: selectors => selectors.showModelSelector() },
8
+ { command: "fork", pending: unchosen, open: selectors => selectors.showForkSelector() },
9
+ { command: "thinking", pending: request => request.selection === undefined && request.argument.trim().length === 0, open: selectors => selectors.showThinkingSelector() },
10
+ { command: "trust", pending: unchosen, open: selectors => selectors.showTrustSelector() },
11
+ { command: "settings", pending: unchosen, open: selectors => selectors.showSettingsSelector() },
12
+ { command: "resume", pending: unchosenBare, open: selectors => selectors.showSessionSelector() },
13
+ {
14
+ command: "login",
15
+ pending: unchosen,
16
+ open: (selectors, request) => request.argument.trim().length === 0
17
+ ? selectors.showLoginAuthTypeSelector()
18
+ : selectors.showLoginMethodSelector(request.argument),
19
+ },
20
+ { command: "logout", pending: unchosen, open: selectors => selectors.showLogoutSelector() },
21
+ { command: "tree", pending: unchosenBare, open: selectors => selectors.showTreeSelector() },
22
+ ];
23
+ /**
24
+ * Opens the owned selector a workflow request asks for when the user has not chosen yet. Returns
25
+ * the command result when a selector handled the request, settling once an asynchronous selector
26
+ * has opened, or undefined when the request goes to the engine. The decision itself is synchronous,
27
+ * so a request that goes to the engine reaches it in the same turn.
28
+ */
29
+ export function openWorkflowSelector(request, selectors, options) {
30
+ const route = SELECTOR_ROUTES.find(candidate => candidate.command === request.command && candidate.pending(request));
31
+ if (route === undefined)
32
+ return undefined;
33
+ if (route.command === "settings" && options.residentTab) {
34
+ return { outcome: "rejected", diagnostic: "Settings is available from the global Settings tab." };
35
+ }
36
+ const completed = { outcome: "completed", diagnostic: null };
37
+ const opened = route.open(selectors, request);
38
+ return opened instanceof Promise ? opened.then(() => completed) : completed;
39
+ }
@@ -1,7 +1,8 @@
1
- import { type InteractiveLaunchIntent, type LaunchProfileId, type SessionSelection } from "../features/launch/index.js";
1
+ import { type InteractiveLaunchIntent, type InteractiveLaunchMode, type LaunchProfileId, type SessionSelection } from "../features/launch/index.js";
2
2
  import type { CliCapabilities } from "./capabilities.js";
3
3
  import type { PackageCommandRequest } from "./packages.js";
4
4
  import type { SessionContextRequest } from "./session-context.js";
5
+ import type { TabsRequest } from "./tabs-request.js";
5
6
  import { type PackageCliVerb, type PackageCommandNamespace, type PackageSyntaxDiagnostic } from "./package-messages.js";
6
7
  export type UpdateChannel = "stable" | "next";
7
8
  export interface CliHandlers {
@@ -10,6 +11,7 @@ export interface CliHandlers {
10
11
  readonly update: (channel: UpdateChannel, target?: string) => Promise<number>;
11
12
  readonly packages: (request: PackageCommandRequest) => Promise<number>;
12
13
  readonly sessionContext: (request: SessionContextRequest) => Promise<number>;
14
+ readonly tabs: (request: TabsRequest) => Promise<number>;
13
15
  }
14
16
  export interface CliOutput {
15
17
  readonly stdout: (message: string) => void;
@@ -17,6 +19,8 @@ export interface CliOutput {
17
19
  }
18
20
  export declare function cliUsage(capabilities: CliCapabilities): string;
19
21
  export declare function cliHelp(capabilities: CliCapabilities): string;
22
+ /** Focused help for the resident-tab maintenance forms; printing it contacts no host. */
23
+ export declare function tabsHelp(): string;
20
24
  export declare function dispatchCli(arguments_: readonly string[], handlers: CliHandlers, output: CliOutput, capabilities: CliCapabilities): Promise<number>;
21
25
  export type CliCommand = {
22
26
  readonly kind: "noop";
@@ -33,6 +37,7 @@ export type CliCommand = {
33
37
  } | {
34
38
  readonly kind: "launch";
35
39
  readonly profileId: LaunchProfileId;
40
+ readonly launchMode: InteractiveLaunchMode;
36
41
  readonly sessionSelection?: SessionSelection;
37
42
  } | {
38
43
  readonly kind: "version";
@@ -46,6 +51,11 @@ export type CliCommand = {
46
51
  } | {
47
52
  readonly kind: "session-context";
48
53
  readonly request: SessionContextRequest;
54
+ } | {
55
+ readonly kind: "tabs";
56
+ readonly request: TabsRequest;
57
+ } | {
58
+ readonly kind: "tabs-help";
49
59
  } | {
50
60
  readonly kind: "error";
51
61
  readonly message: string;
@@ -6,6 +6,7 @@ export function cliUsage(capabilities) {
6
6
  "",
7
7
  "--session <path|id>",
8
8
  "--session-dir <dir> --session <path|id>",
9
+ "solo",
9
10
  ...(capabilities.developmentComparison ? ["pi"] : []),
10
11
  "help",
11
12
  "version",
@@ -21,6 +22,10 @@ export function cliUsage(capabilities) {
21
22
  "session worktrees",
22
23
  "session link-worktree <path>",
23
24
  "session unlink-worktree",
25
+ "tabs",
26
+ "tabs stop <id>|--all",
27
+ "tabs host status|stop",
28
+ "tabs doctor",
24
29
  ]);
25
30
  }
26
31
  export function cliHelp(capabilities) {
@@ -30,6 +35,7 @@ export function cliHelp(capabilities) {
30
35
  ` ${command}`,
31
36
  ` ${command} --session <path|id>`,
32
37
  ` ${command} --session-dir <dir> --session <path|id>`,
38
+ ` ${command} solo`,
33
39
  ...(capabilities.developmentComparison ? [` ${command} pi`] : []),
34
40
  ` ${command} help`,
35
41
  ` ${command} version`,
@@ -52,9 +58,32 @@ export function cliHelp(capabilities) {
52
58
  ` ${command} session link-worktree <path>`,
53
59
  ` ${command} session unlink-worktree`,
54
60
  "",
61
+ "Tabs:",
62
+ ` ${command} tabs`,
63
+ ` ${command} tabs stop <id>|--all`,
64
+ ` ${command} tabs host status|stop`,
65
+ ` ${command} tabs doctor`,
66
+ "",
67
+ ].join("\n");
68
+ }
69
+ /** Focused help for the resident-tab maintenance forms; printing it contacts no host. */
70
+ export function tabsHelp() {
71
+ const command = PRODUCT_TEXT.commandName;
72
+ return [
73
+ "Resident tabs:",
74
+ ` ${command} tabs List running tabs`,
75
+ ` ${command} tabs stop <id> Stop one tab; its session stays resumable`,
76
+ ` ${command} tabs stop --all Stop every tab and keep the host`,
77
+ ` ${command} tabs host status Show host identity, limits, and health counters`,
78
+ ` ${command} tabs host stop Stop every tab and the host`,
79
+ ` ${command} tabs doctor Write a redacted diagnostic bundle`,
80
+ "",
81
+ "Options:",
82
+ " --json Print the versioned machine-readable report",
83
+ "",
55
84
  ].join("\n");
56
85
  }
57
- const PROFILE_WORDS = new Set(["pi"]);
86
+ const PROFILE_WORDS = new Set(["pi", "solo"]);
58
87
  export async function dispatchCli(arguments_, handlers, output, capabilities) {
59
88
  const command = parseCliCommand(arguments_, capabilities);
60
89
  if (command.kind === "noop")
@@ -76,23 +105,29 @@ export async function dispatchCli(arguments_, handlers, output, capabilities) {
76
105
  return 2;
77
106
  }
78
107
  if (command.kind === "launch")
79
- return await handlers.launch(interactiveLaunchIntent(command.profileId, command.sessionSelection));
108
+ return await handlers.launch(interactiveLaunchIntent(command.profileId, command.sessionSelection, command.launchMode));
80
109
  if (command.kind === "version")
81
110
  return await handlers.version();
82
111
  if (command.kind === "packages")
83
112
  return await handlers.packages(command.request);
84
113
  if (command.kind === "session-context")
85
114
  return await handlers.sessionContext(command.request);
115
+ if (command.kind === "tabs-help") {
116
+ output.stdout(tabsHelp());
117
+ return 0;
118
+ }
119
+ if (command.kind === "tabs")
120
+ return await handlers.tabs(command.request);
86
121
  return await handlers.update(command.channel, command.target);
87
122
  }
88
123
  export function parseCliCommand(arguments_, capabilities) {
89
124
  if (arguments_.length === 0)
90
- return { kind: "launch", profileId: "a1" };
125
+ return { kind: "launch", profileId: "a1", launchMode: "tabs" };
91
126
  const [command, ...rest] = arguments_;
92
127
  if (command === "--session" || command === "--session-dir") {
93
128
  try {
94
129
  const sessionSelection = parseSessionSelection(arguments_);
95
- return { kind: "launch", profileId: "a1", ...(sessionSelection === undefined ? {} : { sessionSelection }) };
130
+ return { kind: "launch", profileId: "a1", launchMode: "tabs", ...(sessionSelection === undefined ? {} : { sessionSelection }) };
96
131
  }
97
132
  catch (error) {
98
133
  return { kind: "error", message: PRODUCT_TEXT.diagnostic(`could not parse session launch: ${error instanceof Error ? error.message : String(error)}`) };
@@ -108,18 +143,57 @@ export function parseCliCommand(arguments_, capabilities) {
108
143
  if (command === "pi") {
109
144
  if (rest.length > 0)
110
145
  return parsePackageCommand(rest, "pi");
111
- return capabilities.developmentComparison ? { kind: "launch", profileId: "pi" } : { kind: "noop" };
146
+ return capabilities.developmentComparison ? { kind: "launch", profileId: "pi", launchMode: "solo" } : { kind: "noop" };
112
147
  }
148
+ if (command === "solo")
149
+ return withoutArguments(rest, { kind: "launch", profileId: "a1", launchMode: "solo" });
113
150
  if (command === "update")
114
151
  return parseUpdate(rest);
115
152
  if (command === "session")
116
153
  return parseSessionContext(rest);
154
+ if (command === "tabs")
155
+ return parseTabs(rest);
117
156
  if (command?.startsWith("update:"))
118
157
  return { kind: "noop" };
119
158
  // Rationale: unsupported and reserved command spaces are deliberately quiet. Help is
120
159
  // explicit, and a typo must never start an interactive or maintenance path.
121
160
  return { kind: "noop" };
122
161
  }
162
+ /** Parses `a1 tabs` before any I/O; a malformed form fails with one line and contacts no host. */
163
+ function parseTabs(rest) {
164
+ if (rest.some(value => value === "--help" || value === "-h"))
165
+ return { kind: "tabs-help" };
166
+ const json = rest.includes("--json");
167
+ const words = rest.filter(value => value !== "--json");
168
+ const fail = (detail) => ({ kind: "error", message: PRODUCT_TEXT.diagnostic(`could not parse tabs: ${detail}`) });
169
+ const [action, value, extra] = words;
170
+ if (action === undefined)
171
+ return { kind: "tabs", request: { action: "list", json } };
172
+ if (action === "stop") {
173
+ if (value === undefined)
174
+ return fail("stop requires a tab id or --all.");
175
+ if (extra !== undefined)
176
+ return fail("stop accepts one tab id or --all.");
177
+ if (value === "--all")
178
+ return { kind: "tabs", request: { action: "stop-all", json } };
179
+ if (value.startsWith("-"))
180
+ return fail(`unknown option ${value}.`);
181
+ return { kind: "tabs", request: { action: "stop", tabId: value, json } };
182
+ }
183
+ if (action === "host") {
184
+ if (extra !== undefined || (value !== "status" && value !== "stop"))
185
+ return fail("host accepts status or stop.");
186
+ return { kind: "tabs", request: { action: value === "status" ? "host-status" : "host-stop", json } };
187
+ }
188
+ if (action === "doctor") {
189
+ if (value !== undefined)
190
+ return fail("doctor does not accept arguments.");
191
+ return { kind: "tabs", request: { action: "doctor", json } };
192
+ }
193
+ if (action.startsWith("-"))
194
+ return fail(`unknown option ${action}.`);
195
+ return fail(`unknown subcommand ${action}; use list, stop, host, or doctor.`);
196
+ }
123
197
  function parseSessionContext(rest) {
124
198
  const [action, value, extra] = rest;
125
199
  if (action === "link-worktree") {
@@ -0,0 +1,7 @@
1
+ export type TabsAction = "list" | "stop" | "stop-all" | "host-status" | "host-stop" | "doctor";
2
+ /** One parsed `a1 tabs` form. Parsing finishes before any host is contacted. */
3
+ export interface TabsRequest {
4
+ readonly action: TabsAction;
5
+ readonly tabId?: string;
6
+ readonly json: boolean;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ import { runTerminalHostMaintenance, writeDoctorBundle } from "../foundation/resident-tabs/index.js";
2
+ import type { TabsRequest } from "./tabs-request.js";
3
+ export type { TabsRequest } from "./tabs-request.js";
4
+ export interface TabsCommandOptions {
5
+ /** The invoking package, never a different active or retained release. */
6
+ readonly packageRoot?: string;
7
+ readonly environment?: NodeJS.ProcessEnv;
8
+ readonly stdout?: (message: string) => void;
9
+ readonly stderr?: (message: string) => void;
10
+ readonly maintenance?: typeof runTerminalHostMaintenance;
11
+ readonly doctor?: typeof writeDoctorBundle;
12
+ }
13
+ /** `a1 tabs`: inspect or stop resident tabs without attaching, and never start a host to report state. */
14
+ export declare function runTabsCommand(request: TabsRequest, options?: TabsCommandOptions): Promise<number>;
@@ -0,0 +1,151 @@
1
+ import { resolveProductPaths } from "../foundation/lifecycle/index.js";
2
+ import { materializeRelease } from "../foundation/release/index.js";
3
+ import { readResidentTabLaunchSettings, runTerminalHostMaintenance, writeDoctorBundle, } from "../foundation/resident-tabs/index.js";
4
+ import { PRODUCT_IDENTITY, PRODUCT_TEXT } from "../product-identity.js";
5
+ /** `a1 tabs`: inspect or stop resident tabs without attaching, and never start a host to report state. */
6
+ export async function runTabsCommand(request, options = {}) {
7
+ const environment = options.environment ?? process.env;
8
+ const stdout = options.stdout ?? (message => process.stdout.write(message));
9
+ const stderr = options.stderr ?? (message => process.stderr.write(message));
10
+ const paths = resolveProductPaths(environment);
11
+ const profileRoot = environment[PRODUCT_IDENTITY.environment.profileHome] ?? paths.configDir;
12
+ const releaseRoots = await invokingReleaseRoots(paths.dataDir, options.packageRoot, environment);
13
+ const maintenance = options.maintenance ?? runTerminalHostMaintenance;
14
+ const report = await maintenance({
15
+ action: request.action === "doctor" ? "host-status" : request.action,
16
+ ...(request.tabId === undefined ? {} : { tabId: request.tabId }),
17
+ profileRoot,
18
+ dataDir: paths.dataDir,
19
+ runtimeDir: paths.runtimeDir,
20
+ releaseRoots,
21
+ environment,
22
+ });
23
+ if (request.action === "doctor") {
24
+ if (!report.stateDir) {
25
+ stderr(`${PRODUCT_TEXT.diagnostic(`tabs doctor could not locate resident state: ${report.message ?? report.host}`)}\n`);
26
+ return 1;
27
+ }
28
+ const settings = await readResidentTabLaunchSettings(environment.PI_CODING_AGENT_DIR ?? paths.configDir, PRODUCT_IDENTITY.commandName, paths.configDir, "a1");
29
+ const bundle = await (options.doctor ?? writeDoctorBundle)({
30
+ stateDir: report.stateDir,
31
+ hostStatus: report,
32
+ releaseRoots,
33
+ settings: { tabsAutoName: settings.tabsAutoName },
34
+ });
35
+ if (request.json)
36
+ stdout(`${JSON.stringify({ schema: "a1-tabs-doctor-v1", path: bundle.path, bytes: bundle.bytes, dropped: bundle.dropped })}\n`);
37
+ else
38
+ stdout(`Wrote ${bundle.path}\n`);
39
+ return 0;
40
+ }
41
+ if (request.json) {
42
+ const { exitCode: _exitCode, ...printed } = report;
43
+ stdout(`${JSON.stringify(printed)}\n`);
44
+ }
45
+ else {
46
+ const text = describe(request, report);
47
+ if (report.exitCode === 0)
48
+ stdout(text);
49
+ else
50
+ stderr(text);
51
+ }
52
+ return report.exitCode === 0 ? 0 : 1;
53
+ }
54
+ async function invokingReleaseRoots(dataDir, packageRoot, environment) {
55
+ if (!packageRoot)
56
+ return [];
57
+ if (environment[PRODUCT_IDENTITY.environment.developmentInstanceId])
58
+ return [packageRoot];
59
+ try {
60
+ // Invariant: immutable materialization selects exact payload bytes without activating or starting a host.
61
+ return [(await materializeRelease(packageRoot, dataDir)).releaseRoot];
62
+ }
63
+ catch {
64
+ return [];
65
+ }
66
+ }
67
+ const NO_TABS = "No resident tabs are running.\n";
68
+ function describe(request, report) {
69
+ const command = PRODUCT_TEXT.commandName;
70
+ if (report.host === "none")
71
+ return NO_TABS;
72
+ if (report.host === "unavailable")
73
+ return `${PRODUCT_TEXT.diagnostic(`tabs could not run maintenance: ${report.message ?? "terminal host unavailable"}`)}\n`;
74
+ if (report.host === "unresponsive") {
75
+ return `The resident host (pid ${report.pid ?? "unknown"}) is not responding. Run \`${command} tabs host stop\` to stop it.\n`;
76
+ }
77
+ if (report.host === "incompatible") {
78
+ return `${PRODUCT_TEXT.diagnostic(report.message ?? "running tabs use another version")} Run \`${command} tabs host stop\` from that version.\n`;
79
+ }
80
+ if (report.host === "unverifiable" || report.host === "refused") {
81
+ return `${PRODUCT_TEXT.diagnostic(report.message ?? "the resident host could not be verified; nothing was changed")}\n`;
82
+ }
83
+ const result = report.result ?? {};
84
+ if (request.action === "list")
85
+ return listing(result);
86
+ if (request.action === "host-status")
87
+ return status(result);
88
+ if (request.action === "host-stop") {
89
+ if (report.host === "stopped")
90
+ return "Stopped every tab and the resident host.\n";
91
+ return `Could not stop every tab: ${remaining(result)}. The host is still running.\n`;
92
+ }
93
+ if (result.accepted === false && typeof result.message === "string") {
94
+ return `${PRODUCT_TEXT.diagnostic(`tabs stop: ${result.message === "unknown tab" ? `no tab ${request.tabId ?? ""}` : result.message}`)}\n`;
95
+ }
96
+ const stopped = Array.isArray(result.stopped) ? result.stopped.length : 0;
97
+ if (result.accepted === false)
98
+ return `Could not stop: ${remaining(result)}.\n`;
99
+ if (request.action === "stop")
100
+ return `Stopped tab ${request.tabId ?? ""}; its session can be resumed.\n`;
101
+ return stopped === 0 ? NO_TABS : `Stopped ${stopped} tab${stopped === 1 ? "" : "s"}; their sessions can be resumed.\n`;
102
+ }
103
+ function remaining(result) {
104
+ return Array.isArray(result.remaining) && result.remaining.length > 0 ? result.remaining.join(", ") : "unknown tabs";
105
+ }
106
+ function listing(result) {
107
+ const tabs = Array.isArray(result.tabs) ? result.tabs : [];
108
+ if (tabs.length === 0)
109
+ return NO_TABS;
110
+ const rows = [
111
+ ["ID", "NAME", "STATUS", "CWD", "RELEASE", "HOLDER"],
112
+ ...tabs.map(tab => [tab.tabId, tab.name, tab.status, tab.cwd, tab.release, tab.holderPid ?? "-"].map(value => String(value ?? "-"))),
113
+ ];
114
+ const widths = rows[0].map((_, column) => Math.max(...rows.map(row => row[column].length)));
115
+ return `${rows.map(row => row.map((cell, column) => column === row.length - 1 ? cell : cell.padEnd(widths[column])).join(" ")).join("\n")}\n`;
116
+ }
117
+ function status(result) {
118
+ const limits = (result.limits ?? {});
119
+ const counters = (result.counters ?? {});
120
+ const byStatus = (result.tabsByStatus ?? {});
121
+ const lines = [
122
+ `pid: ${String(result.pid ?? "-")}`,
123
+ `build: ${String(result.build ?? "-")}`,
124
+ `release: ${String(result.release ?? "-")}`,
125
+ `generation: ${String(result.generation ?? "-")}`,
126
+ `epoch: ${String(result.epoch ?? "-")}`,
127
+ `uptime: ${String(result.uptimeSeconds ?? "-")}s`,
128
+ `detachment: ${String(result.detachmentMode ?? "unknown")}${result.detachmentVerified === false ? " (not verified)" : ""}`,
129
+ `tabs: ${String(result.tabs ?? 0)}${Object.keys(byStatus).length > 0 ? ` (${Object.entries(byStatus).map(([key, value]) => `${key} ${String(value)}`).join(", ")})` : ""}`,
130
+ `clients: ${String(result.clients ?? 0)}`,
131
+ ...startsAndLifecycle(result),
132
+ `limits: ${Object.entries(limits).map(([key, value]) => `${key} ${String(value)}`).join(", ")}`,
133
+ `counters: ${Object.entries(counters).map(([key, value]) => `${key} ${String(value)}`).join(", ")}`,
134
+ ...(Array.isArray(result.logs) ? result.logs.map(path => `log: ${String(path)}`) : []),
135
+ ];
136
+ return `${lines.join("\n")}\n`;
137
+ }
138
+ /** Lifecycle work running this long means a terminal's tab requests are stuck. */
139
+ const LIFECYCLE_STALL_MS = 10_000;
140
+ function startsAndLifecycle(result) {
141
+ const lines = [];
142
+ const starts = result.starts;
143
+ if (starts)
144
+ lines.push(`starts: active ${String(starts.active ?? 0)}, waiting ${String(starts.interactiveWaiting ?? 0)}, recovering ${String(starts.recoverySlots ?? 0)}`);
145
+ const lifecycle = result.lifecycle;
146
+ if (lifecycle) {
147
+ const oldest = typeof lifecycle.oldestMs === "number" ? lifecycle.oldestMs : 0;
148
+ lines.push(`lifecycle: pending ${String(lifecycle.pending ?? 0)}, oldest ${oldest}ms${oldest > LIFECYCLE_STALL_MS ? " (stalled)" : ""}`);
149
+ }
150
+ return lines;
151
+ }