@timurproko/a1 0.1.0

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 (455) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +68 -0
  3. package/bin/addone-supervisor.js +7 -0
  4. package/bin/addone-ui.js +20 -0
  5. package/bin/addone.js +26 -0
  6. package/dist/src/cli/dispatch.d.ts +26 -0
  7. package/dist/src/cli/dispatch.d.ts.map +1 -0
  8. package/dist/src/cli/dispatch.js +35 -0
  9. package/dist/src/cli/dispatch.js.map +1 -0
  10. package/dist/src/cli/index.d.ts +4 -0
  11. package/dist/src/cli/index.d.ts.map +1 -0
  12. package/dist/src/cli/index.js +4 -0
  13. package/dist/src/cli/index.js.map +1 -0
  14. package/dist/src/cli/version-stats.d.ts +17 -0
  15. package/dist/src/cli/version-stats.d.ts.map +1 -0
  16. package/dist/src/cli/version-stats.js +68 -0
  17. package/dist/src/cli/version-stats.js.map +1 -0
  18. package/dist/src/cli/version.d.ts +3 -0
  19. package/dist/src/cli/version.d.ts.map +1 -0
  20. package/dist/src/cli/version.js +23 -0
  21. package/dist/src/cli/version.js.map +1 -0
  22. package/dist/src/features/launch/development-launch.d.ts +9 -0
  23. package/dist/src/features/launch/development-launch.d.ts.map +1 -0
  24. package/dist/src/features/launch/development-launch.js +27 -0
  25. package/dist/src/features/launch/development-launch.js.map +1 -0
  26. package/dist/src/features/launch/index.d.ts +8 -0
  27. package/dist/src/features/launch/index.d.ts.map +1 -0
  28. package/dist/src/features/launch/index.js +8 -0
  29. package/dist/src/features/launch/index.js.map +1 -0
  30. package/dist/src/features/launch/initialize-profile.d.ts +7 -0
  31. package/dist/src/features/launch/initialize-profile.d.ts.map +1 -0
  32. package/dist/src/features/launch/initialize-profile.js +59 -0
  33. package/dist/src/features/launch/initialize-profile.js.map +1 -0
  34. package/dist/src/features/launch/intent.d.ts +8 -0
  35. package/dist/src/features/launch/intent.d.ts.map +1 -0
  36. package/dist/src/features/launch/intent.js +5 -0
  37. package/dist/src/features/launch/intent.js.map +1 -0
  38. package/dist/src/features/launch/prepare-launch.d.ts +14 -0
  39. package/dist/src/features/launch/prepare-launch.d.ts.map +1 -0
  40. package/dist/src/features/launch/prepare-launch.js +22 -0
  41. package/dist/src/features/launch/prepare-launch.js.map +1 -0
  42. package/dist/src/features/launch/profile-paths.d.ts +16 -0
  43. package/dist/src/features/launch/profile-paths.d.ts.map +1 -0
  44. package/dist/src/features/launch/profile-paths.js +30 -0
  45. package/dist/src/features/launch/profile-paths.js.map +1 -0
  46. package/dist/src/features/launch/profiles.d.ts +13 -0
  47. package/dist/src/features/launch/profiles.d.ts.map +1 -0
  48. package/dist/src/features/launch/profiles.js +27 -0
  49. package/dist/src/features/launch/profiles.js.map +1 -0
  50. package/dist/src/features/launch/runtime-selection.d.ts +15 -0
  51. package/dist/src/features/launch/runtime-selection.d.ts.map +1 -0
  52. package/dist/src/features/launch/runtime-selection.js +14 -0
  53. package/dist/src/features/launch/runtime-selection.js.map +1 -0
  54. package/dist/src/features/owned-ui/customization.d.ts +36 -0
  55. package/dist/src/features/owned-ui/customization.d.ts.map +1 -0
  56. package/dist/src/features/owned-ui/customization.js +110 -0
  57. package/dist/src/features/owned-ui/customization.js.map +1 -0
  58. package/dist/src/features/owned-ui/diagnostics.d.ts +34 -0
  59. package/dist/src/features/owned-ui/diagnostics.d.ts.map +1 -0
  60. package/dist/src/features/owned-ui/diagnostics.js +95 -0
  61. package/dist/src/features/owned-ui/diagnostics.js.map +1 -0
  62. package/dist/src/features/owned-ui/index.d.ts +5 -0
  63. package/dist/src/features/owned-ui/index.d.ts.map +1 -0
  64. package/dist/src/features/owned-ui/index.js +5 -0
  65. package/dist/src/features/owned-ui/index.js.map +1 -0
  66. package/dist/src/features/owned-ui/pi-session-shell.d.ts +97 -0
  67. package/dist/src/features/owned-ui/pi-session-shell.d.ts.map +1 -0
  68. package/dist/src/features/owned-ui/pi-session-shell.js +1437 -0
  69. package/dist/src/features/owned-ui/pi-session-shell.js.map +1 -0
  70. package/dist/src/features/owned-ui/run.d.ts +9 -0
  71. package/dist/src/features/owned-ui/run.d.ts.map +1 -0
  72. package/dist/src/features/owned-ui/run.js +21 -0
  73. package/dist/src/features/owned-ui/run.js.map +1 -0
  74. package/dist/src/features/workspace/capabilities.d.ts +32 -0
  75. package/dist/src/features/workspace/capabilities.d.ts.map +1 -0
  76. package/dist/src/features/workspace/capabilities.js +76 -0
  77. package/dist/src/features/workspace/capabilities.js.map +1 -0
  78. package/dist/src/features/workspace/index.d.ts +7 -0
  79. package/dist/src/features/workspace/index.d.ts.map +1 -0
  80. package/dist/src/features/workspace/index.js +7 -0
  81. package/dist/src/features/workspace/index.js.map +1 -0
  82. package/dist/src/features/workspace/presentation.d.ts +31 -0
  83. package/dist/src/features/workspace/presentation.d.ts.map +1 -0
  84. package/dist/src/features/workspace/presentation.js +69 -0
  85. package/dist/src/features/workspace/presentation.js.map +1 -0
  86. package/dist/src/features/workspace/reconciliation.d.ts +16 -0
  87. package/dist/src/features/workspace/reconciliation.d.ts.map +1 -0
  88. package/dist/src/features/workspace/reconciliation.js +83 -0
  89. package/dist/src/features/workspace/reconciliation.js.map +1 -0
  90. package/dist/src/features/workspace/reducer.d.ts +43 -0
  91. package/dist/src/features/workspace/reducer.d.ts.map +1 -0
  92. package/dist/src/features/workspace/reducer.js +214 -0
  93. package/dist/src/features/workspace/reducer.js.map +1 -0
  94. package/dist/src/features/workspace/router.d.ts +32 -0
  95. package/dist/src/features/workspace/router.d.ts.map +1 -0
  96. package/dist/src/features/workspace/router.js +125 -0
  97. package/dist/src/features/workspace/router.js.map +1 -0
  98. package/dist/src/features/workspace/store.d.ts +18 -0
  99. package/dist/src/features/workspace/store.d.ts.map +1 -0
  100. package/dist/src/features/workspace/store.js +55 -0
  101. package/dist/src/features/workspace/store.js.map +1 -0
  102. package/dist/src/foundation/lifecycle/index.d.ts +3 -0
  103. package/dist/src/foundation/lifecycle/index.d.ts.map +1 -0
  104. package/dist/src/foundation/lifecycle/index.js +3 -0
  105. package/dist/src/foundation/lifecycle/index.js.map +1 -0
  106. package/dist/src/foundation/lifecycle/model.d.ts +101 -0
  107. package/dist/src/foundation/lifecycle/model.d.ts.map +1 -0
  108. package/dist/src/foundation/lifecycle/model.js +40 -0
  109. package/dist/src/foundation/lifecycle/model.js.map +1 -0
  110. package/dist/src/foundation/lifecycle/paths.d.ts +11 -0
  111. package/dist/src/foundation/lifecycle/paths.d.ts.map +1 -0
  112. package/dist/src/foundation/lifecycle/paths.js +26 -0
  113. package/dist/src/foundation/lifecycle/paths.js.map +1 -0
  114. package/dist/src/foundation/native-host-protocol/codec.d.ts +12 -0
  115. package/dist/src/foundation/native-host-protocol/codec.d.ts.map +1 -0
  116. package/dist/src/foundation/native-host-protocol/codec.js +57 -0
  117. package/dist/src/foundation/native-host-protocol/codec.js.map +1 -0
  118. package/dist/src/foundation/native-host-protocol/evidence.d.ts +68 -0
  119. package/dist/src/foundation/native-host-protocol/evidence.d.ts.map +1 -0
  120. package/dist/src/foundation/native-host-protocol/evidence.js +141 -0
  121. package/dist/src/foundation/native-host-protocol/evidence.js.map +1 -0
  122. package/dist/src/foundation/native-host-protocol/index.d.ts +5 -0
  123. package/dist/src/foundation/native-host-protocol/index.d.ts.map +1 -0
  124. package/dist/src/foundation/native-host-protocol/index.js +5 -0
  125. package/dist/src/foundation/native-host-protocol/index.js.map +1 -0
  126. package/dist/src/foundation/native-host-protocol/messages.d.ts +57 -0
  127. package/dist/src/foundation/native-host-protocol/messages.d.ts.map +1 -0
  128. package/dist/src/foundation/native-host-protocol/messages.js +149 -0
  129. package/dist/src/foundation/native-host-protocol/messages.js.map +1 -0
  130. package/dist/src/foundation/native-host-protocol/proof-gate.d.ts +14 -0
  131. package/dist/src/foundation/native-host-protocol/proof-gate.d.ts.map +1 -0
  132. package/dist/src/foundation/native-host-protocol/proof-gate.js +34 -0
  133. package/dist/src/foundation/native-host-protocol/proof-gate.js.map +1 -0
  134. package/dist/src/foundation/owned-ui-contracts/extension-ui.d.ts +303 -0
  135. package/dist/src/foundation/owned-ui-contracts/extension-ui.d.ts.map +1 -0
  136. package/dist/src/foundation/owned-ui-contracts/extension-ui.js +69 -0
  137. package/dist/src/foundation/owned-ui-contracts/extension-ui.js.map +1 -0
  138. package/dist/src/foundation/owned-ui-contracts/index.d.ts +4 -0
  139. package/dist/src/foundation/owned-ui-contracts/index.d.ts.map +1 -0
  140. package/dist/src/foundation/owned-ui-contracts/index.js +4 -0
  141. package/dist/src/foundation/owned-ui-contracts/index.js.map +1 -0
  142. package/dist/src/foundation/owned-ui-contracts/model.d.ts +242 -0
  143. package/dist/src/foundation/owned-ui-contracts/model.d.ts.map +1 -0
  144. package/dist/src/foundation/owned-ui-contracts/model.js +2 -0
  145. package/dist/src/foundation/owned-ui-contracts/model.js.map +1 -0
  146. package/dist/src/foundation/owned-ui-contracts/validation.d.ts +12 -0
  147. package/dist/src/foundation/owned-ui-contracts/validation.d.ts.map +1 -0
  148. package/dist/src/foundation/owned-ui-contracts/validation.js +396 -0
  149. package/dist/src/foundation/owned-ui-contracts/validation.js.map +1 -0
  150. package/dist/src/foundation/pi-component-adapter/components.d.ts +5 -0
  151. package/dist/src/foundation/pi-component-adapter/components.d.ts.map +1 -0
  152. package/dist/src/foundation/pi-component-adapter/components.js +65 -0
  153. package/dist/src/foundation/pi-component-adapter/components.js.map +1 -0
  154. package/dist/src/foundation/pi-component-adapter/conformance.d.ts +17 -0
  155. package/dist/src/foundation/pi-component-adapter/conformance.d.ts.map +1 -0
  156. package/dist/src/foundation/pi-component-adapter/conformance.js +63 -0
  157. package/dist/src/foundation/pi-component-adapter/conformance.js.map +1 -0
  158. package/dist/src/foundation/pi-component-adapter/index.d.ts +13 -0
  159. package/dist/src/foundation/pi-component-adapter/index.d.ts.map +1 -0
  160. package/dist/src/foundation/pi-component-adapter/index.js +13 -0
  161. package/dist/src/foundation/pi-component-adapter/index.js.map +1 -0
  162. package/dist/src/foundation/pi-component-adapter/shell-components.d.ts +7 -0
  163. package/dist/src/foundation/pi-component-adapter/shell-components.d.ts.map +1 -0
  164. package/dist/src/foundation/pi-component-adapter/shell-components.js +7 -0
  165. package/dist/src/foundation/pi-component-adapter/shell-components.js.map +1 -0
  166. package/dist/src/foundation/pi-component-adapter/shell-editor-autocomplete.d.ts +12 -0
  167. package/dist/src/foundation/pi-component-adapter/shell-editor-autocomplete.d.ts.map +1 -0
  168. package/dist/src/foundation/pi-component-adapter/shell-editor-autocomplete.js +165 -0
  169. package/dist/src/foundation/pi-component-adapter/shell-editor-autocomplete.js.map +1 -0
  170. package/dist/src/foundation/pi-component-adapter/shell-extension-ui.d.ts +36 -0
  171. package/dist/src/foundation/pi-component-adapter/shell-extension-ui.d.ts.map +1 -0
  172. package/dist/src/foundation/pi-component-adapter/shell-extension-ui.js +280 -0
  173. package/dist/src/foundation/pi-component-adapter/shell-extension-ui.js.map +1 -0
  174. package/dist/src/foundation/pi-component-adapter/shell-footer-status.d.ts +8 -0
  175. package/dist/src/foundation/pi-component-adapter/shell-footer-status.d.ts.map +1 -0
  176. package/dist/src/foundation/pi-component-adapter/shell-footer-status.js +246 -0
  177. package/dist/src/foundation/pi-component-adapter/shell-footer-status.js.map +1 -0
  178. package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.d.ts +43 -0
  179. package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.d.ts.map +1 -0
  180. package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.js +397 -0
  181. package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.js.map +1 -0
  182. package/dist/src/foundation/pi-component-adapter/shell-selectors-dialogs.d.ts +106 -0
  183. package/dist/src/foundation/pi-component-adapter/shell-selectors-dialogs.d.ts.map +1 -0
  184. package/dist/src/foundation/pi-component-adapter/shell-selectors-dialogs.js +234 -0
  185. package/dist/src/foundation/pi-component-adapter/shell-selectors-dialogs.js.map +1 -0
  186. package/dist/src/foundation/pi-component-adapter/shell-shared-facade.d.ts +117 -0
  187. package/dist/src/foundation/pi-component-adapter/shell-shared-facade.d.ts.map +1 -0
  188. package/dist/src/foundation/pi-component-adapter/shell-shared-facade.js +88 -0
  189. package/dist/src/foundation/pi-component-adapter/shell-shared-facade.js.map +1 -0
  190. package/dist/src/foundation/pi-component-adapter/theme.d.ts +2 -0
  191. package/dist/src/foundation/pi-component-adapter/theme.d.ts.map +1 -0
  192. package/dist/src/foundation/pi-component-adapter/theme.js +2 -0
  193. package/dist/src/foundation/pi-component-adapter/theme.js.map +1 -0
  194. package/dist/src/foundation/pi-component-adapter/upstream/adjacent/core/keybindings.d.ts +423 -0
  195. package/dist/src/foundation/pi-component-adapter/upstream/adjacent/core/keybindings.d.ts.map +1 -0
  196. package/dist/src/foundation/pi-component-adapter/upstream/adjacent/core/keybindings.js +297 -0
  197. package/dist/src/foundation/pi-component-adapter/upstream/adjacent/core/keybindings.js.map +1 -0
  198. package/dist/src/foundation/pi-component-adapter/upstream/components/countdown-timer.d.ts +11 -0
  199. package/dist/src/foundation/pi-component-adapter/upstream/components/countdown-timer.d.ts.map +1 -0
  200. package/dist/src/foundation/pi-component-adapter/upstream/components/countdown-timer.js +30 -0
  201. package/dist/src/foundation/pi-component-adapter/upstream/components/countdown-timer.js.map +1 -0
  202. package/dist/src/foundation/pi-component-adapter/upstream/components/custom-entry.d.ts +18 -0
  203. package/dist/src/foundation/pi-component-adapter/upstream/components/custom-entry.d.ts.map +1 -0
  204. package/dist/src/foundation/pi-component-adapter/upstream/components/custom-entry.js +52 -0
  205. package/dist/src/foundation/pi-component-adapter/upstream/components/custom-entry.js.map +1 -0
  206. package/dist/src/foundation/pi-component-adapter/upstream/components/daxnuts.d.ts +23 -0
  207. package/dist/src/foundation/pi-component-adapter/upstream/components/daxnuts.d.ts.map +1 -0
  208. package/dist/src/foundation/pi-component-adapter/upstream/components/daxnuts.js +143 -0
  209. package/dist/src/foundation/pi-component-adapter/upstream/components/daxnuts.js.map +1 -0
  210. package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.d.ts +5 -0
  211. package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.d.ts.map +1 -0
  212. package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.js +43 -0
  213. package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.js.map +1 -0
  214. package/dist/src/foundation/pi-component-adapter/upstream/components/extension-editor.d.ts +18 -0
  215. package/dist/src/foundation/pi-component-adapter/upstream/components/extension-editor.d.ts.map +1 -0
  216. package/dist/src/foundation/pi-component-adapter/upstream/components/extension-editor.js +82 -0
  217. package/dist/src/foundation/pi-component-adapter/upstream/components/extension-editor.js.map +1 -0
  218. package/dist/src/foundation/pi-component-adapter/upstream/components/first-time-setup.d.ts +25 -0
  219. package/dist/src/foundation/pi-component-adapter/upstream/components/first-time-setup.d.ts.map +1 -0
  220. package/dist/src/foundation/pi-component-adapter/upstream/components/first-time-setup.js +106 -0
  221. package/dist/src/foundation/pi-component-adapter/upstream/components/first-time-setup.js.map +1 -0
  222. package/dist/src/foundation/pi-component-adapter/upstream/components/markdown-transform.d.ts +3 -0
  223. package/dist/src/foundation/pi-component-adapter/upstream/components/markdown-transform.d.ts.map +1 -0
  224. package/dist/src/foundation/pi-component-adapter/upstream/components/markdown-transform.js +19 -0
  225. package/dist/src/foundation/pi-component-adapter/upstream/components/markdown-transform.js.map +1 -0
  226. package/dist/src/foundation/pi-component-adapter/upstream/components/mermaid.d.ts +10 -0
  227. package/dist/src/foundation/pi-component-adapter/upstream/components/mermaid.d.ts.map +1 -0
  228. package/dist/src/foundation/pi-component-adapter/upstream/components/mermaid.js +78 -0
  229. package/dist/src/foundation/pi-component-adapter/upstream/components/mermaid.js.map +1 -0
  230. package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.d.ts +56 -0
  231. package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.d.ts.map +1 -0
  232. package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.js +343 -0
  233. package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.js.map +1 -0
  234. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector-search.d.ts +23 -0
  235. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector-search.d.ts.map +1 -0
  236. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector-search.js +160 -0
  237. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector-search.js.map +1 -0
  238. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector.d.ts +96 -0
  239. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector.d.ts.map +1 -0
  240. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector.js +890 -0
  241. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector.js.map +1 -0
  242. package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.d.ts +20 -0
  243. package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.d.ts.map +1 -0
  244. package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.js +45 -0
  245. package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.js.map +1 -0
  246. package/dist/src/foundation/pi-component-adapter/upstream/components/status-indicator.d.ts +31 -0
  247. package/dist/src/foundation/pi-component-adapter/upstream/components/status-indicator.d.ts.map +1 -0
  248. package/dist/src/foundation/pi-component-adapter/upstream/components/status-indicator.js +60 -0
  249. package/dist/src/foundation/pi-component-adapter/upstream/components/status-indicator.js.map +1 -0
  250. package/dist/src/foundation/pi-component-adapter/upstream/components/tree-selector.d.ts +99 -0
  251. package/dist/src/foundation/pi-component-adapter/upstream/components/tree-selector.d.ts.map +1 -0
  252. package/dist/src/foundation/pi-component-adapter/upstream/components/tree-selector.js +1273 -0
  253. package/dist/src/foundation/pi-component-adapter/upstream/components/tree-selector.js.map +1 -0
  254. package/dist/src/foundation/pi-component-adapter/upstream/components/trust-selector.d.ts +34 -0
  255. package/dist/src/foundation/pi-component-adapter/upstream/components/trust-selector.d.ts.map +1 -0
  256. package/dist/src/foundation/pi-component-adapter/upstream/components/trust-selector.js +77 -0
  257. package/dist/src/foundation/pi-component-adapter/upstream/components/trust-selector.js.map +1 -0
  258. package/dist/src/foundation/pi-component-adapter/upstream/external-editor.d.ts +10 -0
  259. package/dist/src/foundation/pi-component-adapter/upstream/external-editor.d.ts.map +1 -0
  260. package/dist/src/foundation/pi-component-adapter/upstream/external-editor.js +40 -0
  261. package/dist/src/foundation/pi-component-adapter/upstream/external-editor.js.map +1 -0
  262. package/dist/src/foundation/pi-component-adapter/upstream/model-search.d.ts +16 -0
  263. package/dist/src/foundation/pi-component-adapter/upstream/model-search.d.ts.map +1 -0
  264. package/dist/src/foundation/pi-component-adapter/upstream/model-search.js +15 -0
  265. package/dist/src/foundation/pi-component-adapter/upstream/model-search.js.map +1 -0
  266. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme-controller.d.ts +26 -0
  267. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme-controller.d.ts.map +1 -0
  268. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme-controller.js +118 -0
  269. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme-controller.js.map +1 -0
  270. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.d.ts +54 -0
  271. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.d.ts.map +1 -0
  272. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.js +311 -0
  273. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.js.map +1 -0
  274. package/dist/src/foundation/pi-engine-adapter/adapter.d.ts +343 -0
  275. package/dist/src/foundation/pi-engine-adapter/adapter.d.ts.map +1 -0
  276. package/dist/src/foundation/pi-engine-adapter/adapter.js +2365 -0
  277. package/dist/src/foundation/pi-engine-adapter/adapter.js.map +1 -0
  278. package/dist/src/foundation/pi-engine-adapter/conformance.d.ts +14 -0
  279. package/dist/src/foundation/pi-engine-adapter/conformance.d.ts.map +1 -0
  280. package/dist/src/foundation/pi-engine-adapter/conformance.js +85 -0
  281. package/dist/src/foundation/pi-engine-adapter/conformance.js.map +1 -0
  282. package/dist/src/foundation/pi-engine-adapter/index.d.ts +4 -0
  283. package/dist/src/foundation/pi-engine-adapter/index.d.ts.map +1 -0
  284. package/dist/src/foundation/pi-engine-adapter/index.js +4 -0
  285. package/dist/src/foundation/pi-engine-adapter/index.js.map +1 -0
  286. package/dist/src/foundation/pi-engine-adapter/workflows.d.ts +165 -0
  287. package/dist/src/foundation/pi-engine-adapter/workflows.d.ts.map +1 -0
  288. package/dist/src/foundation/pi-engine-adapter/workflows.js +61 -0
  289. package/dist/src/foundation/pi-engine-adapter/workflows.js.map +1 -0
  290. package/dist/src/foundation/pi-tui-runtime-adapter/adapter.d.ts +34 -0
  291. package/dist/src/foundation/pi-tui-runtime-adapter/adapter.d.ts.map +1 -0
  292. package/dist/src/foundation/pi-tui-runtime-adapter/adapter.js +485 -0
  293. package/dist/src/foundation/pi-tui-runtime-adapter/adapter.js.map +1 -0
  294. package/dist/src/foundation/pi-tui-runtime-adapter/conformance.d.ts +14 -0
  295. package/dist/src/foundation/pi-tui-runtime-adapter/conformance.d.ts.map +1 -0
  296. package/dist/src/foundation/pi-tui-runtime-adapter/conformance.js +132 -0
  297. package/dist/src/foundation/pi-tui-runtime-adapter/conformance.js.map +1 -0
  298. package/dist/src/foundation/pi-tui-runtime-adapter/contracts.d.ts +122 -0
  299. package/dist/src/foundation/pi-tui-runtime-adapter/contracts.d.ts.map +1 -0
  300. package/dist/src/foundation/pi-tui-runtime-adapter/contracts.js +2 -0
  301. package/dist/src/foundation/pi-tui-runtime-adapter/contracts.js.map +1 -0
  302. package/dist/src/foundation/pi-tui-runtime-adapter/index.d.ts +4 -0
  303. package/dist/src/foundation/pi-tui-runtime-adapter/index.d.ts.map +1 -0
  304. package/dist/src/foundation/pi-tui-runtime-adapter/index.js +4 -0
  305. package/dist/src/foundation/pi-tui-runtime-adapter/index.js.map +1 -0
  306. package/dist/src/foundation/protocol/client.d.ts +17 -0
  307. package/dist/src/foundation/protocol/client.d.ts.map +1 -0
  308. package/dist/src/foundation/protocol/client.js +127 -0
  309. package/dist/src/foundation/protocol/client.js.map +1 -0
  310. package/dist/src/foundation/protocol/index.d.ts +3 -0
  311. package/dist/src/foundation/protocol/index.d.ts.map +1 -0
  312. package/dist/src/foundation/protocol/index.js +3 -0
  313. package/dist/src/foundation/protocol/index.js.map +1 -0
  314. package/dist/src/foundation/protocol/messages.d.ts +90 -0
  315. package/dist/src/foundation/protocol/messages.d.ts.map +1 -0
  316. package/dist/src/foundation/protocol/messages.js +99 -0
  317. package/dist/src/foundation/protocol/messages.js.map +1 -0
  318. package/dist/src/foundation/release/bootstrap.d.ts +30 -0
  319. package/dist/src/foundation/release/bootstrap.d.ts.map +1 -0
  320. package/dist/src/foundation/release/bootstrap.js +283 -0
  321. package/dist/src/foundation/release/bootstrap.js.map +1 -0
  322. package/dist/src/foundation/release/cohort-selection.d.ts +40 -0
  323. package/dist/src/foundation/release/cohort-selection.d.ts.map +1 -0
  324. package/dist/src/foundation/release/cohort-selection.js +76 -0
  325. package/dist/src/foundation/release/cohort-selection.js.map +1 -0
  326. package/dist/src/foundation/release/cohort-state.d.ts +68 -0
  327. package/dist/src/foundation/release/cohort-state.d.ts.map +1 -0
  328. package/dist/src/foundation/release/cohort-state.js +201 -0
  329. package/dist/src/foundation/release/cohort-state.js.map +1 -0
  330. package/dist/src/foundation/release/development-preview-release.d.ts +49 -0
  331. package/dist/src/foundation/release/development-preview-release.d.ts.map +1 -0
  332. package/dist/src/foundation/release/development-preview-release.js +113 -0
  333. package/dist/src/foundation/release/development-preview-release.js.map +1 -0
  334. package/dist/src/foundation/release/index.d.ts +12 -0
  335. package/dist/src/foundation/release/index.d.ts.map +1 -0
  336. package/dist/src/foundation/release/index.js +12 -0
  337. package/dist/src/foundation/release/index.js.map +1 -0
  338. package/dist/src/foundation/release/process-cleanup.d.ts +15 -0
  339. package/dist/src/foundation/release/process-cleanup.d.ts.map +1 -0
  340. package/dist/src/foundation/release/process-cleanup.js +67 -0
  341. package/dist/src/foundation/release/process-cleanup.js.map +1 -0
  342. package/dist/src/foundation/release/release-gc.d.ts +6 -0
  343. package/dist/src/foundation/release/release-gc.d.ts.map +1 -0
  344. package/dist/src/foundation/release/release-gc.js +17 -0
  345. package/dist/src/foundation/release/release-gc.js.map +1 -0
  346. package/dist/src/foundation/release/release-store.d.ts +11 -0
  347. package/dist/src/foundation/release/release-store.d.ts.map +1 -0
  348. package/dist/src/foundation/release/release-store.js +115 -0
  349. package/dist/src/foundation/release/release-store.js.map +1 -0
  350. package/dist/src/foundation/release/release.d.ts +24 -0
  351. package/dist/src/foundation/release/release.d.ts.map +1 -0
  352. package/dist/src/foundation/release/release.js +151 -0
  353. package/dist/src/foundation/release/release.js.map +1 -0
  354. package/dist/src/foundation/release/stable-release.d.ts +30 -0
  355. package/dist/src/foundation/release/stable-release.d.ts.map +1 -0
  356. package/dist/src/foundation/release/stable-release.js +38 -0
  357. package/dist/src/foundation/release/stable-release.js.map +1 -0
  358. package/dist/src/foundation/release/update-transaction.d.ts +31 -0
  359. package/dist/src/foundation/release/update-transaction.d.ts.map +1 -0
  360. package/dist/src/foundation/release/update-transaction.js +88 -0
  361. package/dist/src/foundation/release/update-transaction.js.map +1 -0
  362. package/dist/src/foundation/release/update.d.ts +55 -0
  363. package/dist/src/foundation/release/update.d.ts.map +1 -0
  364. package/dist/src/foundation/release/update.js +316 -0
  365. package/dist/src/foundation/release/update.js.map +1 -0
  366. package/dist/src/foundation/storage/control-store.d.ts +61 -0
  367. package/dist/src/foundation/storage/control-store.d.ts.map +1 -0
  368. package/dist/src/foundation/storage/control-store.js +459 -0
  369. package/dist/src/foundation/storage/control-store.js.map +1 -0
  370. package/dist/src/foundation/storage/index.d.ts +2 -0
  371. package/dist/src/foundation/storage/index.d.ts.map +1 -0
  372. package/dist/src/foundation/storage/index.js +2 -0
  373. package/dist/src/foundation/storage/index.js.map +1 -0
  374. package/dist/src/foundation/structured-agent-runtime/backpressure.d.ts +47 -0
  375. package/dist/src/foundation/structured-agent-runtime/backpressure.d.ts.map +1 -0
  376. package/dist/src/foundation/structured-agent-runtime/backpressure.js +119 -0
  377. package/dist/src/foundation/structured-agent-runtime/backpressure.js.map +1 -0
  378. package/dist/src/foundation/structured-agent-runtime/commands.d.ts +53 -0
  379. package/dist/src/foundation/structured-agent-runtime/commands.d.ts.map +1 -0
  380. package/dist/src/foundation/structured-agent-runtime/commands.js +165 -0
  381. package/dist/src/foundation/structured-agent-runtime/commands.js.map +1 -0
  382. package/dist/src/foundation/structured-agent-runtime/handshake.d.ts +42 -0
  383. package/dist/src/foundation/structured-agent-runtime/handshake.d.ts.map +1 -0
  384. package/dist/src/foundation/structured-agent-runtime/handshake.js +151 -0
  385. package/dist/src/foundation/structured-agent-runtime/handshake.js.map +1 -0
  386. package/dist/src/foundation/structured-agent-runtime/index.d.ts +6 -0
  387. package/dist/src/foundation/structured-agent-runtime/index.d.ts.map +1 -0
  388. package/dist/src/foundation/structured-agent-runtime/index.js +6 -0
  389. package/dist/src/foundation/structured-agent-runtime/index.js.map +1 -0
  390. package/dist/src/foundation/structured-agent-runtime/reconnection.d.ts +38 -0
  391. package/dist/src/foundation/structured-agent-runtime/reconnection.d.ts.map +1 -0
  392. package/dist/src/foundation/structured-agent-runtime/reconnection.js +130 -0
  393. package/dist/src/foundation/structured-agent-runtime/reconnection.js.map +1 -0
  394. package/dist/src/foundation/structured-agent-runtime/state.d.ts +57 -0
  395. package/dist/src/foundation/structured-agent-runtime/state.d.ts.map +1 -0
  396. package/dist/src/foundation/structured-agent-runtime/state.js +119 -0
  397. package/dist/src/foundation/structured-agent-runtime/state.js.map +1 -0
  398. package/dist/src/foundation/supervision/index.d.ts +4 -0
  399. package/dist/src/foundation/supervision/index.d.ts.map +1 -0
  400. package/dist/src/foundation/supervision/index.js +4 -0
  401. package/dist/src/foundation/supervision/index.js.map +1 -0
  402. package/dist/src/foundation/supervision/main.d.ts +2 -0
  403. package/dist/src/foundation/supervision/main.d.ts.map +1 -0
  404. package/dist/src/foundation/supervision/main.js +40 -0
  405. package/dist/src/foundation/supervision/main.js.map +1 -0
  406. package/dist/src/foundation/supervision/paths.d.ts +2 -0
  407. package/dist/src/foundation/supervision/paths.d.ts.map +1 -0
  408. package/dist/src/foundation/supervision/paths.js +2 -0
  409. package/dist/src/foundation/supervision/paths.js.map +1 -0
  410. package/dist/src/foundation/supervision/server.d.ts +21 -0
  411. package/dist/src/foundation/supervision/server.d.ts.map +1 -0
  412. package/dist/src/foundation/supervision/server.js +283 -0
  413. package/dist/src/foundation/supervision/server.js.map +1 -0
  414. package/dist/src/foundation/transparent-terminal/command-resolution.d.ts +14 -0
  415. package/dist/src/foundation/transparent-terminal/command-resolution.d.ts.map +1 -0
  416. package/dist/src/foundation/transparent-terminal/command-resolution.js +70 -0
  417. package/dist/src/foundation/transparent-terminal/command-resolution.js.map +1 -0
  418. package/dist/src/foundation/transparent-terminal/foreground-broker.d.ts +33 -0
  419. package/dist/src/foundation/transparent-terminal/foreground-broker.d.ts.map +1 -0
  420. package/dist/src/foundation/transparent-terminal/foreground-broker.js +88 -0
  421. package/dist/src/foundation/transparent-terminal/foreground-broker.js.map +1 -0
  422. package/dist/src/foundation/transparent-terminal/index.d.ts +4 -0
  423. package/dist/src/foundation/transparent-terminal/index.d.ts.map +1 -0
  424. package/dist/src/foundation/transparent-terminal/index.js +4 -0
  425. package/dist/src/foundation/transparent-terminal/index.js.map +1 -0
  426. package/dist/src/foundation/transparent-terminal/main.d.ts +10 -0
  427. package/dist/src/foundation/transparent-terminal/main.d.ts.map +1 -0
  428. package/dist/src/foundation/transparent-terminal/main.js +107 -0
  429. package/dist/src/foundation/transparent-terminal/main.js.map +1 -0
  430. package/dist/src/foundation/transparent-terminal/native-launcher.d.ts +26 -0
  431. package/dist/src/foundation/transparent-terminal/native-launcher.d.ts.map +1 -0
  432. package/dist/src/foundation/transparent-terminal/native-launcher.js +147 -0
  433. package/dist/src/foundation/transparent-terminal/native-launcher.js.map +1 -0
  434. package/dist/src/foundation/workspace-contracts/index.d.ts +3 -0
  435. package/dist/src/foundation/workspace-contracts/index.d.ts.map +1 -0
  436. package/dist/src/foundation/workspace-contracts/index.js +3 -0
  437. package/dist/src/foundation/workspace-contracts/index.js.map +1 -0
  438. package/dist/src/foundation/workspace-contracts/model.d.ts +249 -0
  439. package/dist/src/foundation/workspace-contracts/model.d.ts.map +1 -0
  440. package/dist/src/foundation/workspace-contracts/model.js +3 -0
  441. package/dist/src/foundation/workspace-contracts/model.js.map +1 -0
  442. package/dist/src/foundation/workspace-contracts/validation.d.ts +14 -0
  443. package/dist/src/foundation/workspace-contracts/validation.d.ts.map +1 -0
  444. package/dist/src/foundation/workspace-contracts/validation.js +336 -0
  445. package/dist/src/foundation/workspace-contracts/validation.js.map +1 -0
  446. package/docs/architecture/boundaries.md +46 -0
  447. package/docs/architecture/project-structure.md +81 -0
  448. package/docs/architecture/resource-and-data-policy.md +55 -0
  449. package/docs/architecture/terminal-host-proof-gate.md +32 -0
  450. package/docs/architecture/terminal-host-provenance.md +69 -0
  451. package/docs/architecture/terminal-host-spike-evidence.md +39 -0
  452. package/docs/architecture/toolchain.md +66 -0
  453. package/docs/features/launch-profiles.md +50 -0
  454. package/docs/manual-transparent-checkpoint.md +53 -0
  455. package/package.json +73 -0
@@ -0,0 +1,1437 @@
1
+ import { PINNED_PI_HIDDEN_COMMAND_NAMES, PINNED_PI_WORKFLOW_COMMAND_NAMES, } from "../../foundation/pi-engine-adapter/index.js";
2
+ import { createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellDaxnuts, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellOperationLoader, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellStatus, createPiShellTranscriptComponent, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, piTheme, renderPiShellStatusText, renderPiShellTranscriptBlock, } from "../../foundation/pi-component-adapter/index.js";
3
+ import { PiTuiRuntimeAdapter, } from "../../foundation/pi-tui-runtime-adapter/index.js";
4
+ export class PiSessionShellRoot {
5
+ editor;
6
+ header;
7
+ resources;
8
+ #cwd;
9
+ #transcript = new Map();
10
+ #transcriptOrder = [];
11
+ #view;
12
+ #status;
13
+ #footer;
14
+ #queued;
15
+ #extensionRenderers;
16
+ #componentRuntime;
17
+ #toolsExpanded = false;
18
+ #thinkingVisible = true;
19
+ #workflowTranscriptSequence = 0;
20
+ #workflowStatusAnchors = new Map();
21
+ #workflowStatusMessages = new Map();
22
+ #lastWorkflowStatusId;
23
+ #inputSurface;
24
+ #extensionHeader = null;
25
+ #extensionFooter = null;
26
+ #extensionWidgets = new Map();
27
+ #extensionStatuses = new Map();
28
+ #extensionWorkingMessage;
29
+ #extensionWorkingVisible = true;
30
+ constructor(view, cwd, handlers, startup = {}, agentDir, extensionRenderers = {
31
+ getMessageRenderer: () => undefined,
32
+ getToolDefinition: () => undefined,
33
+ }) {
34
+ this.#view = view;
35
+ this.#cwd = cwd;
36
+ this.#extensionRenderers = extensionRenderers;
37
+ this.#componentRuntime = handlers;
38
+ this.header = createPiShellHeader(startup);
39
+ this.resources = createPiShellLoadedResources(startup.resources ?? [], startup.expanded ?? false);
40
+ this.#status = createPiShellStatus(view, handlers);
41
+ this.#footer = createPiShellFooter(this.#viewWithExtensionStatuses(view), cwd);
42
+ this.#queued = createPiQueuedInputStatus(view.editor.queuedSubmissions);
43
+ this.editor = createPiShellEditor({
44
+ ...handlers,
45
+ cwd,
46
+ ...(agentDir === undefined ? {} : { agentDir }),
47
+ onToolsExpand: () => this.#setToolsExpanded(!this.#toolsExpanded),
48
+ });
49
+ this.editor.setThinkingLevel(view.thinkingLevel);
50
+ this.#inputSurface = this.editor;
51
+ for (const block of view.transcript) {
52
+ if (block.kind === "user")
53
+ this.editor.addToHistory(block.text);
54
+ }
55
+ this.#syncTranscript(view.transcript);
56
+ }
57
+ update(view) {
58
+ this.#view = view;
59
+ this.#status.update(view);
60
+ this.#footer.update(this.#viewWithExtensionStatuses(view));
61
+ this.#queued.update(view.editor.queuedSubmissions);
62
+ this.#syncTranscript(view.transcript);
63
+ this.editor.setSubmitEnabled(view.lifecycle !== "stopping" && view.lifecycle !== "stopped" && view.lifecycle !== "failed");
64
+ this.editor.setThinkingLevel(view.thinkingLevel);
65
+ this.invalidate();
66
+ }
67
+ render(width) {
68
+ const queued = this.#view.editor.queuedSubmissions.length === 0 ? [] : this.#queued.render(width);
69
+ return [
70
+ ...this.#renderDocument(width),
71
+ ...queued,
72
+ ...this.#renderStatus(width),
73
+ ...this.#renderWidgets("aboveEditor", width),
74
+ ...this.#inputSurface.render(width),
75
+ ...this.#renderWidgets("belowEditor", width),
76
+ ...this.#renderFooter(width),
77
+ ];
78
+ }
79
+ layoutRoot() {
80
+ const document = layoutPort(width => this.#renderDocument(width), () => this.invalidate());
81
+ const queued = layoutPort(width => this.#view.editor.queuedSubmissions.length === 0 ? [] : this.#queued.render(width), () => this.#queued.invalidate());
82
+ const aboveWidgets = layoutPort(width => this.#renderWidgets("aboveEditor", width), () => this.#invalidateExtensions());
83
+ const status = layoutPort(width => this.#renderStatus(width), () => this.#status.invalidate());
84
+ const editor = layoutPort(width => this.#inputSurface.render(width), () => this.#inputSurface.invalidate(), data => this.#inputSurface.handleInput?.(data));
85
+ const belowWidgets = layoutPort(width => this.#renderWidgets("belowEditor", width), () => this.#invalidateExtensions());
86
+ const footer = layoutPort(width => this.#renderFooter(width), () => (this.#extensionFooter ?? this.#footer).invalidate());
87
+ return {
88
+ type: "stack",
89
+ direction: "vertical",
90
+ children: [
91
+ {
92
+ basis: 0,
93
+ grow: 1,
94
+ shrink: 1,
95
+ minSize: 1,
96
+ node: {
97
+ type: "scroll",
98
+ id: "transcript",
99
+ follow: "end",
100
+ primary: true,
101
+ overscroll: "chain",
102
+ scrollbar: "auto",
103
+ scrollbarStyle: text => piTheme().bg("scrollbarThumb", text),
104
+ child: { type: "component", component: document },
105
+ },
106
+ },
107
+ {
108
+ basis: "auto",
109
+ grow: 0,
110
+ shrink: 1,
111
+ minSize: 1,
112
+ node: {
113
+ type: "stack",
114
+ direction: "vertical",
115
+ children: [
116
+ { shrink: 1, minSize: 0, node: { type: "component", component: queued } },
117
+ { shrink: 1, minSize: 0, node: { type: "component", component: status } },
118
+ { shrink: 1, minSize: 0, node: { type: "component", component: aboveWidgets } },
119
+ { shrink: 1, minSize: 3, node: { type: "component", component: editor } },
120
+ { shrink: 1, minSize: 0, node: { type: "component", component: belowWidgets } },
121
+ { shrink: 1, minSize: 1, node: { type: "component", component: footer } },
122
+ ],
123
+ },
124
+ },
125
+ ],
126
+ };
127
+ }
128
+ #renderDocument(width) {
129
+ const transcript = this.#transcriptOrder.flatMap((id, index) => {
130
+ const block = this.#view.transcript.find(item => item.id === id);
131
+ if (!this.#thinkingVisible && block?.kind === "thinking")
132
+ return [];
133
+ const rows = this.#transcript.get(id)?.render(width) ?? [];
134
+ if (index > 0 && block?.kind === "user")
135
+ return ["", ...rows];
136
+ return rows;
137
+ });
138
+ const diagnosticRows = this.#view.diagnostics.slice(-3).flatMap(diagnostic => renderPiShellTranscriptBlock({
139
+ id: `diagnostic-${diagnostic.sequence}`,
140
+ kind: diagnostic.severity === "error" ? "error" : "system",
141
+ status: "finalized",
142
+ revision: diagnostic.sequence,
143
+ title: diagnostic.code,
144
+ text: diagnostic.message,
145
+ payload: {},
146
+ }, width, this.#cwd));
147
+ const resourceRows = [...this.resources.render(width)];
148
+ if (resourceRows.at(-1) === "")
149
+ resourceRows.pop();
150
+ return [
151
+ ...(this.#extensionHeader ?? this.header).render(width),
152
+ ...resourceRows,
153
+ ...transcript,
154
+ ...diagnosticRows,
155
+ ];
156
+ }
157
+ transcriptComponent(id) {
158
+ return this.#transcript.get(id);
159
+ }
160
+ appendWorkflowStatus(message) {
161
+ const previousId = this.#lastWorkflowStatusId;
162
+ if (previousId !== undefined
163
+ && this.#transcriptOrder.at(-1) === previousId
164
+ && this.#workflowStatusAnchors.get(previousId) === this.#view.transcript.length) {
165
+ this.#workflowStatusMessages.set(previousId, message);
166
+ this.invalidate();
167
+ return;
168
+ }
169
+ const id = this.#appendAnchoredWorkflowComponent(width => [
170
+ "",
171
+ ...renderPiShellStatusText(this.#workflowStatusMessages.get(id) ?? message, width),
172
+ ]);
173
+ this.#workflowStatusMessages.set(id, message);
174
+ this.#lastWorkflowStatusId = id;
175
+ }
176
+ appendWorkflowResult(result) {
177
+ if (result.command === "reload" && result.outcome === "completed") {
178
+ this.appendWorkflowStatus(result.message);
179
+ return;
180
+ }
181
+ if (result.command === "session" && result.outcome === "completed" && result.presentation?.kind === "session-info") {
182
+ this.#lastWorkflowStatusId = undefined;
183
+ const sessionInfo = createPiShellSessionInfo(result.presentation);
184
+ this.#appendAnchoredWorkflowComponent(width => sessionInfo.render(width), () => sessionInfo.dispose?.());
185
+ return;
186
+ }
187
+ if (result.command === "hotkeys" && result.outcome === "completed") {
188
+ this.#lastWorkflowStatusId = undefined;
189
+ const hotkeys = createPiShellHotkeys();
190
+ this.#appendAnchoredWorkflowComponent(width => hotkeys.render(width), () => hotkeys.dispose?.());
191
+ return;
192
+ }
193
+ if (result.command === "changelog" && result.outcome === "completed") {
194
+ this.#lastWorkflowStatusId = undefined;
195
+ const changelog = createPiShellChangelog(result.detail ?? "No changelog entries found.");
196
+ this.#appendAnchoredWorkflowComponent(width => changelog.render(width), () => changelog.dispose?.());
197
+ return;
198
+ }
199
+ if (result.outcome === "failed") {
200
+ this.#lastWorkflowStatusId = undefined;
201
+ const warning = (result.command === "name" && result.message.startsWith("Usage:"))
202
+ || (result.command === "reload" && result.message.startsWith("Wait for "));
203
+ const prefix = warning ? "Warning" : "Error";
204
+ const color = warning ? "warning" : "error";
205
+ this.#appendAnchoredWorkflowComponent(() => ["", ` ${piTheme().fg(color, `${prefix}: ${result.message}`)}`]);
206
+ return;
207
+ }
208
+ if (result.outcome === "completed" && (result.command === "quit" || result.command === "compact"))
209
+ return;
210
+ if (result.command === "new" && result.outcome === "completed") {
211
+ this.#lastWorkflowStatusId = undefined;
212
+ this.#appendAnchoredWorkflowComponent(() => ["", ` ${piTheme().fg("accent", result.message)}`]);
213
+ return;
214
+ }
215
+ if (result.command === "name" && result.outcome === "completed") {
216
+ this.#lastWorkflowStatusId = undefined;
217
+ this.#appendAnchoredWorkflowComponent(() => [
218
+ ...(result.detail ? ["", ` ${piTheme().fg("warning", `Warning: ${result.detail}`)}`] : []),
219
+ "",
220
+ ` ${piTheme().fg("dim", result.message)}`,
221
+ ]);
222
+ return;
223
+ }
224
+ if (result.command === "debug" && result.outcome === "completed") {
225
+ this.#lastWorkflowStatusId = undefined;
226
+ this.#appendAnchoredWorkflowComponent(() => [
227
+ "",
228
+ ` ${piTheme().fg("accent", result.message)}`,
229
+ ...(result.detail ? [` ${piTheme().fg("muted", result.detail)}`] : []),
230
+ ]);
231
+ return;
232
+ }
233
+ if (result.command === "arminsayshi" && result.outcome === "completed") {
234
+ this.#lastWorkflowStatusId = undefined;
235
+ const armin = createPiShellArmin(this.#componentRuntime);
236
+ this.#appendAnchoredWorkflowComponent(width => ["", ...armin.render(width)], () => armin.dispose?.());
237
+ return;
238
+ }
239
+ if (result.command === "dementedelves" && result.outcome === "completed") {
240
+ this.#lastWorkflowStatusId = undefined;
241
+ const announcement = createPiShellEarendilAnnouncement();
242
+ this.#appendAnchoredWorkflowComponent(width => ["", ...announcement.render(width)], () => announcement.dispose?.());
243
+ return;
244
+ }
245
+ const message = result.command === "share" && result.detail
246
+ ? `${result.message}\nGist: ${result.detail}`
247
+ : result.message;
248
+ this.appendWorkflowStatus(message);
249
+ }
250
+ appendDaxnuts() {
251
+ this.#lastWorkflowStatusId = undefined;
252
+ const daxnuts = createPiShellDaxnuts(this.#componentRuntime);
253
+ this.#appendAnchoredWorkflowComponent(width => ["", ...daxnuts.render(width)], () => daxnuts.dispose?.());
254
+ }
255
+ toggleThinkingVisibility() {
256
+ this.#thinkingVisible = !this.#thinkingVisible;
257
+ this.invalidate();
258
+ }
259
+ get toolsExpanded() {
260
+ return this.#toolsExpanded;
261
+ }
262
+ setToolsExpanded(expanded) {
263
+ this.#setToolsExpanded(expanded);
264
+ }
265
+ setExtensionWidget(key, component, placement) {
266
+ const previous = this.#extensionWidgets.get(key)?.component;
267
+ if (component === null)
268
+ this.#extensionWidgets.delete(key);
269
+ else
270
+ this.#extensionWidgets.set(key, { component, placement });
271
+ if (previous !== undefined && previous !== component)
272
+ previous.dispose?.();
273
+ this.invalidate();
274
+ }
275
+ setExtensionHeader(component) {
276
+ if (this.#extensionHeader !== component)
277
+ this.#extensionHeader?.dispose?.();
278
+ this.#extensionHeader = component;
279
+ this.invalidate();
280
+ }
281
+ setExtensionFooter(component) {
282
+ if (this.#extensionFooter !== component)
283
+ this.#extensionFooter?.dispose?.();
284
+ this.#extensionFooter = component;
285
+ this.invalidate();
286
+ }
287
+ setExtensionStatus(key, text) {
288
+ if (text === undefined)
289
+ this.#extensionStatuses.delete(key);
290
+ else
291
+ this.#extensionStatuses.set(key, text);
292
+ this.#footer.update(this.#viewWithExtensionStatuses(this.#view));
293
+ this.invalidate();
294
+ }
295
+ setExtensionWorking(message, visible = this.#extensionWorkingVisible) {
296
+ this.#extensionWorkingMessage = message;
297
+ this.#extensionWorkingVisible = visible;
298
+ this.#status.setWorkingOverride(visible ? message : undefined);
299
+ this.invalidate();
300
+ }
301
+ resetWorkflowPresentation() {
302
+ for (const id of this.#workflowStatusAnchors.keys()) {
303
+ this.#transcript.get(id)?.dispose?.();
304
+ this.#transcript.delete(id);
305
+ }
306
+ this.#workflowStatusAnchors.clear();
307
+ this.#workflowStatusMessages.clear();
308
+ this.#transcriptOrder = this.#transcriptOrder.filter(id => !id.startsWith("workflow-status-"));
309
+ this.#lastWorkflowStatusId = undefined;
310
+ this.invalidate();
311
+ }
312
+ resetExtensionUi() {
313
+ this.#extensionHeader?.dispose?.();
314
+ this.#extensionFooter?.dispose?.();
315
+ for (const { component } of this.#extensionWidgets.values())
316
+ component.dispose?.();
317
+ this.#extensionHeader = null;
318
+ this.#extensionFooter = null;
319
+ this.#extensionWidgets.clear();
320
+ this.#extensionStatuses.clear();
321
+ this.#extensionWorkingMessage = undefined;
322
+ this.#status.setWorkingOverride(undefined);
323
+ this.#footer.update(this.#viewWithExtensionStatuses(this.#view));
324
+ this.invalidate();
325
+ }
326
+ addExtensionNotification(message, type) {
327
+ if (type === "info") {
328
+ this.appendWorkflowStatus(message);
329
+ return;
330
+ }
331
+ this.#lastWorkflowStatusId = undefined;
332
+ const prefix = type === "warning" ? "Warning" : "Error";
333
+ this.#appendAnchoredWorkflowComponent(() => ["", ` ${piTheme().fg(type, `${prefix}: ${message}`)}`]);
334
+ }
335
+ extensionFooterData() {
336
+ return {
337
+ getGitBranch: () => this.#view.status.footer?.branch ?? null,
338
+ getExtensionStatuses: () => new Map(this.#extensionStatuses),
339
+ getAvailableProviderCount: () => this.#view.status.footer?.availableProviderCount ?? 1,
340
+ onBranchChange: () => () => { },
341
+ };
342
+ }
343
+ setInputSurface(component, disposePrevious = true) {
344
+ const next = component ?? this.editor;
345
+ if (next === this.#inputSurface)
346
+ return;
347
+ this.#inputSurface.setFocused?.(false);
348
+ if (disposePrevious && this.#inputSurface !== this.editor)
349
+ this.#inputSurface.dispose?.();
350
+ this.#inputSurface = next;
351
+ this.#inputSurface.setFocused?.(true);
352
+ this.invalidate();
353
+ }
354
+ handleInput(data) {
355
+ this.#inputSurface.handleInput?.(data);
356
+ }
357
+ invalidate() {
358
+ this.header.invalidate();
359
+ this.resources.invalidate();
360
+ for (const component of this.#transcript.values())
361
+ component.invalidate();
362
+ this.editor.invalidate();
363
+ if (this.#inputSurface !== this.editor)
364
+ this.#inputSurface.invalidate();
365
+ this.#invalidateExtensions();
366
+ this.#status.invalidate();
367
+ this.#footer.invalidate();
368
+ this.#queued.invalidate();
369
+ }
370
+ setFocused(focused) {
371
+ this.#inputSurface.setFocused?.(focused);
372
+ }
373
+ dispose() {
374
+ this.header.dispose?.();
375
+ this.resources.dispose?.();
376
+ for (const component of this.#transcript.values())
377
+ component.dispose?.();
378
+ this.#transcript.clear();
379
+ if (this.#inputSurface !== this.editor)
380
+ this.#inputSurface.dispose?.();
381
+ this.#extensionHeader?.dispose?.();
382
+ this.#extensionFooter?.dispose?.();
383
+ for (const { component } of this.#extensionWidgets.values())
384
+ component.dispose?.();
385
+ this.#extensionWidgets.clear();
386
+ this.editor.dispose?.();
387
+ this.#status.dispose?.();
388
+ this.#footer.dispose?.();
389
+ this.#queued.dispose?.();
390
+ }
391
+ #syncTranscript(blocks) {
392
+ const nextIds = new Set(blocks.map(block => block.id));
393
+ for (const [id, component] of this.#transcript) {
394
+ if (id.startsWith("workflow-status-") || nextIds.has(id))
395
+ continue;
396
+ component.dispose?.();
397
+ this.#transcript.delete(id);
398
+ }
399
+ for (const block of blocks) {
400
+ const component = this.#transcript.get(block.id);
401
+ if (component === undefined) {
402
+ const created = createPiShellTranscriptComponent(block, this.#cwd, this.#extensionRenderers);
403
+ created.setExpanded(this.#toolsExpanded);
404
+ this.#transcript.set(block.id, created);
405
+ }
406
+ else if (component.revision !== block.revision) {
407
+ component.update(block);
408
+ }
409
+ }
410
+ const statusIds = [...this.#workflowStatusAnchors.keys()];
411
+ const order = [];
412
+ for (let index = 0; index <= blocks.length; index += 1) {
413
+ for (const statusId of statusIds) {
414
+ if (this.#workflowStatusAnchors.get(statusId) === index)
415
+ order.push(statusId);
416
+ }
417
+ const block = blocks[index];
418
+ if (block !== undefined)
419
+ order.push(block.id);
420
+ }
421
+ for (const statusId of statusIds) {
422
+ if (!order.includes(statusId))
423
+ order.push(statusId);
424
+ }
425
+ this.#transcriptOrder = order;
426
+ }
427
+ #appendAnchoredWorkflowComponent(render, dispose) {
428
+ this.#workflowTranscriptSequence += 1;
429
+ const id = `workflow-status-${this.#workflowTranscriptSequence}`;
430
+ const component = {
431
+ id,
432
+ revision: 1,
433
+ render,
434
+ handleInput() { },
435
+ invalidate() { },
436
+ update() { },
437
+ setExpanded() { },
438
+ ...(dispose === undefined ? {} : { dispose }),
439
+ };
440
+ this.#transcript.set(id, component);
441
+ this.#workflowStatusAnchors.set(id, this.#view.transcript.length);
442
+ this.#transcriptOrder.push(id);
443
+ this.invalidate();
444
+ return id;
445
+ }
446
+ #renderWidgets(placement, width) {
447
+ const rows = [...this.#extensionWidgets.values()]
448
+ .filter(widget => widget.placement === placement)
449
+ .flatMap(widget => widget.component.render(width));
450
+ return placement === "aboveEditor" ? ["", ...rows] : rows;
451
+ }
452
+ #renderStatus(width) {
453
+ return this.#status.render(width);
454
+ }
455
+ #renderFooter(width) {
456
+ return (this.#extensionFooter ?? this.#footer).render(width);
457
+ }
458
+ #viewWithExtensionStatuses(view) {
459
+ const footer = view.status.footer;
460
+ const statuses = new Map(footer?.extensionStatuses ?? []);
461
+ for (const [key, text] of this.#extensionStatuses)
462
+ statuses.set(key, text);
463
+ return {
464
+ ...view,
465
+ status: {
466
+ ...view.status,
467
+ footer: {
468
+ branch: footer?.branch ?? null,
469
+ sessionName: footer?.sessionName ?? null,
470
+ availableProviderCount: footer?.availableProviderCount ?? 1,
471
+ extensionStatuses: [...statuses],
472
+ },
473
+ },
474
+ };
475
+ }
476
+ #invalidateExtensions() {
477
+ this.#extensionHeader?.invalidate();
478
+ this.#extensionFooter?.invalidate();
479
+ for (const { component } of this.#extensionWidgets.values())
480
+ component.invalidate();
481
+ }
482
+ #setToolsExpanded(expanded) {
483
+ this.#toolsExpanded = expanded;
484
+ this.header.setExpanded(expanded);
485
+ this.resources.setExpanded(expanded);
486
+ for (const component of this.#transcript.values())
487
+ component.setExpanded(expanded);
488
+ this.invalidate();
489
+ }
490
+ }
491
+ function layoutPort(render, invalidate, handleInput) {
492
+ return {
493
+ render,
494
+ invalidate,
495
+ ...(handleInput === undefined ? {} : { handleInput }),
496
+ };
497
+ }
498
+ function shellResourceEntries(adapter) {
499
+ const resources = adapter.nonVisualResources().map(resource => ({
500
+ section: resource.kind === "skill"
501
+ ? "Skills"
502
+ : resource.kind === "prompt-template"
503
+ ? "Prompts"
504
+ : resource.kind === "theme"
505
+ ? "Themes"
506
+ : "Context",
507
+ label: resource.kind === "prompt-template"
508
+ ? `/${resource.label}`
509
+ : resource.kind === "agent-context" || resource.kind === "system-prompt"
510
+ ? compactResourceLabel(resource.sourcePath ?? resource.label)
511
+ : resource.label,
512
+ sourcePath: resource.sourcePath,
513
+ diagnostic: resource.diagnostic,
514
+ }));
515
+ for (const extension of adapter.extensionResources()) {
516
+ if (extension.hidden)
517
+ continue;
518
+ resources.push({
519
+ section: "Extensions",
520
+ label: compactResourceLabel(extension.sourcePath ?? extension.resolvedPath ?? "extension"),
521
+ sourcePath: extension.sourcePath ?? extension.resolvedPath,
522
+ diagnostic: extension.diagnostic,
523
+ });
524
+ }
525
+ return resources;
526
+ }
527
+ function compactResourceLabel(path) {
528
+ const segments = path.replaceAll("\\", "/").split("/").filter(Boolean);
529
+ const leaf = segments.at(-1) ?? path;
530
+ if ((leaf === "index.ts" || leaf === "index.js") && segments.length > 1)
531
+ return segments.at(-2) ?? leaf;
532
+ return leaf;
533
+ }
534
+ export class PiSessionShell {
535
+ adapter;
536
+ root;
537
+ runtime;
538
+ #cwd;
539
+ #listeners = new Set();
540
+ #unsubscribe;
541
+ #extensionBridge;
542
+ #stopped;
543
+ #resolveStopped;
544
+ #dialogId;
545
+ #dialogHandle;
546
+ #sequence = 0;
547
+ #started = false;
548
+ #disposed = false;
549
+ #compactionQueue = [];
550
+ #lastClearTime = 0;
551
+ #activeLoginDialog;
552
+ #sessionGeneration;
553
+ constructor(options) {
554
+ this.adapter = options.adapter;
555
+ this.#sessionGeneration = this.adapter.sessionGeneration;
556
+ this.#cwd = options.cwd;
557
+ this.#stopped = new Promise(resolve => {
558
+ this.#resolveStopped = resolve;
559
+ });
560
+ let runtime;
561
+ this.root = new PiSessionShellRoot(this.adapter.view(), options.cwd, {
562
+ getColumns: () => runtime?.viewport().columns ?? options.terminal?.columns ?? 80,
563
+ getRows: () => runtime?.viewport().rows ?? options.terminal?.rows ?? 24,
564
+ requestRender: () => runtime?.requestRender(),
565
+ onSubmit: text => { void this.submit(text); },
566
+ onInterrupt: () => { void this.interrupt(); },
567
+ onClear: () => { void this.clearOrExit(); },
568
+ onExit: () => { void this.shutdown(); },
569
+ onModelSelect: () => this.showModelSelector(),
570
+ onModelCycle: direction => { void this.cycleModel(direction); },
571
+ onThinkingCycle: () => { void this.cycleThinkingLevel(); },
572
+ onThinkingToggle: () => {
573
+ this.root.toggleThinkingVisibility();
574
+ this.runtime.requestRender();
575
+ },
576
+ onMessageCopy: () => { void this.runWorkflow({ command: "copy", argument: "" }); },
577
+ onFollowUp: () => { void this.queueFollowUp(); },
578
+ onDequeue: () => this.restoreQueuedInput(),
579
+ }, {
580
+ ...options.startup,
581
+ resources: options.startup?.resources ?? shellResourceEntries(this.adapter),
582
+ }, this.adapter.agentDir, {
583
+ getMessageRenderer: customType => this.adapter.pinnedMessageRenderer(customType),
584
+ getToolDefinition: toolName => this.adapter.pinnedToolDefinition(toolName),
585
+ });
586
+ const tuiMode = this.adapter.disposed ? "regular" : this.adapter.pinnedSettingsSnapshot().tuiMode;
587
+ const runtimeOptions = options.terminal === undefined
588
+ ? { root: this.root, mode: tuiMode, layoutRoot: this.root.layoutRoot(), hardwareCursor: this.adapter.view().terminal.hardwareCursor }
589
+ : { root: this.root, mode: tuiMode, layoutRoot: this.root.layoutRoot(), terminal: options.terminal, hardwareCursor: this.adapter.view().terminal.hardwareCursor };
590
+ runtime = new PiTuiRuntimeAdapter(runtimeOptions);
591
+ this.runtime = runtime;
592
+ this.#extensionBridge = createPiExtensionUiBridge({
593
+ runtime: {
594
+ getColumns: () => this.runtime.viewport().columns,
595
+ getRows: () => this.runtime.viewport().rows,
596
+ requestRender: () => this.runtime.requestRender(),
597
+ },
598
+ agentDir: this.adapter.agentDir,
599
+ setInputSurface: component => this.root.setInputSurface(component),
600
+ showOverlay: (component, overlayOptions) => this.runtime.showOverlay(component, overlayOptions),
601
+ listenInput: handler => this.runtime.addInputListener(handler),
602
+ replaceWidget: (key, component, placement) => this.root.setExtensionWidget(key, component, placement),
603
+ replaceHeader: component => this.root.setExtensionHeader(component),
604
+ replaceFooter: component => this.root.setExtensionFooter(component),
605
+ setStatus: (key, text) => this.root.setExtensionStatus(key, text),
606
+ setWorking: (message, visible) => this.root.setExtensionWorking(message, visible),
607
+ notify: (message, type) => this.root.addExtensionNotification(message, type),
608
+ setTitle: title => this.runtime.setTitle(title),
609
+ getEditorText: () => this.root.editor.getText(),
610
+ setEditorText: text => this.root.editor.setText(text),
611
+ pasteToEditor: text => this.root.editor.insertText(text),
612
+ addAutocompleteProvider: factory => this.root.editor.addAutocompleteProvider(factory),
613
+ setCustomEditor: component => this.root.setInputSurface(component),
614
+ getFooterData: () => this.root.extensionFooterData(),
615
+ getToolsExpanded: () => this.root.toolsExpanded,
616
+ setToolsExpanded: expanded => this.root.setToolsExpanded(expanded),
617
+ });
618
+ this.adapter.setWorkflowInteractionHost({
619
+ startLogin: request => this.#startWorkflowLogin(request),
620
+ prompt: request => this.#requestWorkflowInput(request),
621
+ notify: event => this.#notifyWorkflowLogin(event),
622
+ finishLogin: () => this.#finishWorkflowLogin(),
623
+ });
624
+ this.root.editor.setAutocompleteCommands(this.adapter.workflowAutocompleteCommands());
625
+ this.#unsubscribe = this.adapter.onEvent(event => {
626
+ this.#syncView();
627
+ if (this.view().lifecycle === "ready" && this.#compactionQueue.length > 0)
628
+ void this.#flushCompactionQueue();
629
+ if (event.type === "session-lifecycle" && event.lifecycle === "stopped")
630
+ this.#resolveStopped?.();
631
+ });
632
+ if (this.adapter.view().lifecycle === "stopped")
633
+ this.#resolveStopped?.();
634
+ }
635
+ view() {
636
+ return this.adapter.view();
637
+ }
638
+ start() {
639
+ if (this.#started)
640
+ return;
641
+ this.#started = true;
642
+ this.runtime.start();
643
+ void this.adapter.bindExtensionUi(this.#extensionBridge.context, () => { void this.shutdown(); });
644
+ this.#syncView();
645
+ }
646
+ onView(listener) {
647
+ this.#listeners.add(listener);
648
+ listener(this.view());
649
+ return () => this.#listeners.delete(listener);
650
+ }
651
+ waitUntilStopped() {
652
+ return this.#stopped;
653
+ }
654
+ async submit(text) {
655
+ const input = text.trim();
656
+ if (!input)
657
+ return { outcome: "completed", diagnostic: null };
658
+ if (input.startsWith("/"))
659
+ return this.#slashCommand(input);
660
+ if (input.startsWith("!")) {
661
+ const excludeFromContext = input.startsWith("!!");
662
+ const command = input.slice(excludeFromContext ? 2 : 1).trim();
663
+ if (command) {
664
+ this.root.editor.addToHistory(input);
665
+ try {
666
+ const result = await this.adapter.executeBashWorkflow(command, excludeFromContext);
667
+ const workflow = {
668
+ command: "debug",
669
+ outcome: result.cancelled ? "cancelled" : result.exitCode === 0 || result.exitCode === undefined ? "completed" : "failed",
670
+ message: result.cancelled ? "Bash command cancelled" : `Bash exited ${result.exitCode ?? 0}: ${command}`,
671
+ ...(result.output ? { detail: result.output } : {}),
672
+ };
673
+ this.root.appendWorkflowResult(workflow);
674
+ this.runtime.requestRender();
675
+ return workflow.outcome === "failed" ? rejected(workflow.message) : { outcome: "completed", diagnostic: null };
676
+ }
677
+ catch (error) {
678
+ const message = `Bash command failed: ${error instanceof Error ? error.message : String(error)}`;
679
+ this.root.appendWorkflowResult({ command: "debug", outcome: "failed", message });
680
+ this.runtime.requestRender();
681
+ return rejected(message);
682
+ }
683
+ }
684
+ }
685
+ if (this.view().status.workingMessage?.startsWith("Compacting") === true) {
686
+ this.root.editor.addToHistory(input);
687
+ this.#compactionQueue.push({ text: input, type: "steer" });
688
+ this.root.appendWorkflowResult({ command: "compact", outcome: "completed", message: `Queued during compaction: ${input}` });
689
+ this.runtime.requestRender();
690
+ return { outcome: "completed", diagnostic: null };
691
+ }
692
+ const type = this.view().lifecycle === "busy" ? "steer" : "prompt";
693
+ this.root.editor.addToHistory(input);
694
+ return this.#execute({
695
+ type,
696
+ correlationId: this.#correlation(type),
697
+ sessionId: this.adapter.sessionId,
698
+ text: input,
699
+ });
700
+ }
701
+ async clearOrExit(now = Date.now()) {
702
+ if (now - this.#lastClearTime < 500)
703
+ return this.shutdown();
704
+ this.root.editor.setText("");
705
+ this.#lastClearTime = now;
706
+ this.runtime.requestRender();
707
+ return { outcome: "completed", diagnostic: null };
708
+ }
709
+ async interrupt() {
710
+ if (this.view().lifecycle === "busy")
711
+ return this.abort();
712
+ if (this.root.editor.getText().length > 0) {
713
+ this.root.editor.setText("");
714
+ return { outcome: "completed", diagnostic: null };
715
+ }
716
+ return { outcome: "rejected", diagnostic: "nothing to interrupt" };
717
+ }
718
+ async abort() {
719
+ return this.#execute(this.#simple("abort"));
720
+ }
721
+ async retry() {
722
+ return this.#execute(this.#simple("retry"));
723
+ }
724
+ async compact() {
725
+ return this.#execute(this.#simple("compact"));
726
+ }
727
+ async newSession() {
728
+ return this.#execute(this.#simple("new-session"));
729
+ }
730
+ async resumeSession(sessionPath) {
731
+ return this.#execute({
732
+ type: "resume-session",
733
+ correlationId: this.#correlation("resume"),
734
+ sessionId: this.adapter.sessionId,
735
+ sessionPath,
736
+ });
737
+ }
738
+ async setModel(providerId, modelId) {
739
+ return this.#execute({
740
+ type: "set-model",
741
+ correlationId: this.#correlation("model"),
742
+ sessionId: this.adapter.sessionId,
743
+ model: { providerId, modelId, displayName: modelId },
744
+ });
745
+ }
746
+ async setThinkingLevel(thinkingLevel) {
747
+ return this.#execute({
748
+ type: "set-thinking-level",
749
+ correlationId: this.#correlation("thinking"),
750
+ sessionId: this.adapter.sessionId,
751
+ thinkingLevel,
752
+ });
753
+ }
754
+ async cycleThinkingLevel() {
755
+ const levels = ["off", "minimal", "low", "medium", "high", "xhigh"];
756
+ const current = Math.max(0, levels.indexOf(this.view().thinkingLevel));
757
+ return this.setThinkingLevel(levels[(current + 1) % levels.length] ?? "off");
758
+ }
759
+ async cycleModel(direction) {
760
+ const result = await this.adapter.cycleModelWorkflow(direction);
761
+ this.root.appendWorkflowResult(result);
762
+ if (result.outcome === "completed")
763
+ this.#showDaxnutsForActiveModel();
764
+ this.runtime.requestRender();
765
+ return workflowAdapterResult(result);
766
+ }
767
+ async queueFollowUp() {
768
+ const text = this.root.editor.getText().trim();
769
+ if (!text)
770
+ return rejected("nothing to queue");
771
+ this.root.editor.addToHistory(text);
772
+ this.root.editor.setText("");
773
+ if (this.view().status.workingMessage?.startsWith("Compacting") === true) {
774
+ this.#compactionQueue.push({ text, type: "follow-up" });
775
+ return { outcome: "completed", diagnostic: null };
776
+ }
777
+ return this.#execute({
778
+ type: "follow-up",
779
+ correlationId: this.#correlation("follow-up"),
780
+ sessionId: this.adapter.sessionId,
781
+ text,
782
+ });
783
+ }
784
+ restoreQueuedInput() {
785
+ const queued = [...this.adapter.clearQueuedWorkflows(), ...this.#compactionQueue.map(item => item.text)];
786
+ this.#compactionQueue = [];
787
+ if (queued.length === 0)
788
+ return;
789
+ this.root.editor.setText(queued.join("\n"));
790
+ this.runtime.requestRender();
791
+ }
792
+ showSelector(title, options, onSelect, onCancel) {
793
+ this.#dialogHandle?.hide();
794
+ const component = createPiShellSelector({
795
+ title,
796
+ options,
797
+ onSelect: id => {
798
+ onSelect(id);
799
+ this.#dialogHandle?.hide();
800
+ this.#dialogHandle = undefined;
801
+ },
802
+ onCancel: () => {
803
+ this.#dialogHandle?.hide();
804
+ this.#dialogHandle = undefined;
805
+ onCancel?.();
806
+ },
807
+ });
808
+ const handle = this.runtime.showOverlay(component, { width: "70%", maxHeight: "80%", anchor: "center" });
809
+ this.#dialogHandle = handle;
810
+ return handle;
811
+ }
812
+ showModelSelector() {
813
+ const context = this.adapter.pinnedModelSelectorContext();
814
+ const close = () => {
815
+ this.root.setInputSurface(null);
816
+ this.runtime.requestRender();
817
+ };
818
+ const component = createPiShellModelSelector({
819
+ ...context,
820
+ runtime: {
821
+ getColumns: () => this.runtime.viewport().columns,
822
+ getRows: () => this.runtime.viewport().rows,
823
+ requestRender: () => this.runtime.requestRender(),
824
+ },
825
+ onSelect: model => {
826
+ close();
827
+ void this.runWorkflow({ command: "model", argument: "", selection: modelReference(model) });
828
+ },
829
+ onCancel: close,
830
+ });
831
+ this.root.setInputSurface(component);
832
+ this.runtime.requestRender();
833
+ }
834
+ showForkSelector() {
835
+ const options = this.adapter.pinnedForkOptions();
836
+ if (options.length === 0) {
837
+ this.root.appendWorkflowResult({ command: "fork", outcome: "failed", message: "No user messages available to fork from" });
838
+ this.runtime.requestRender();
839
+ return;
840
+ }
841
+ const close = () => {
842
+ this.root.setInputSurface(null);
843
+ this.runtime.requestRender();
844
+ };
845
+ const component = createPiShellUserMessageSelector(options, selection => {
846
+ close();
847
+ void this.runWorkflow({ command: "fork", argument: "", selection });
848
+ }, close);
849
+ this.root.setInputSurface(component);
850
+ this.runtime.requestRender();
851
+ }
852
+ async showLogoutSelector() {
853
+ const options = await this.adapter.pinnedLogoutOptions();
854
+ if (options.length === 0) {
855
+ this.root.appendWorkflowStatus("No authenticated providers available.");
856
+ this.runtime.requestRender();
857
+ return;
858
+ }
859
+ const close = () => {
860
+ this.root.setInputSurface(null);
861
+ this.runtime.requestRender();
862
+ };
863
+ const component = createPiShellAuthProviderSelector("logout", options, selection => {
864
+ close();
865
+ void this.runWorkflow({ command: "logout", argument: "", selection });
866
+ }, close);
867
+ this.root.setInputSurface(component);
868
+ this.runtime.requestRender();
869
+ }
870
+ showLoginMethodSelector(providerReference) {
871
+ const method = this.adapter.pinnedLoginMethodOptions(providerReference);
872
+ if (method.options.length === 0) {
873
+ this.root.appendWorkflowResult({ command: "login", outcome: "failed", message: `No authentication methods available for ${providerReference}` });
874
+ this.runtime.requestRender();
875
+ return;
876
+ }
877
+ if (method.options.length === 1) {
878
+ const selection = method.options[0]?.id;
879
+ if (selection)
880
+ void this.runWorkflow({ command: "login", argument: "", selection });
881
+ return;
882
+ }
883
+ const close = () => {
884
+ this.root.setInputSurface(null);
885
+ this.runtime.requestRender();
886
+ };
887
+ const labels = method.options.map(option => option.label);
888
+ const component = createPiShellExtensionSelector(method.title, labels, label => {
889
+ const selection = method.options.find(option => option.label === label)?.id;
890
+ if (!selection)
891
+ return;
892
+ close();
893
+ void this.runWorkflow({ command: "login", argument: "", selection });
894
+ }, close);
895
+ this.root.setInputSurface(component);
896
+ this.runtime.requestRender();
897
+ }
898
+ showTreeSelector(initialSelectedId) {
899
+ const context = this.adapter.pinnedTreeSelectorContext();
900
+ if (context.tree.length === 0) {
901
+ this.root.appendWorkflowStatus("No entries in session");
902
+ this.runtime.requestRender();
903
+ return;
904
+ }
905
+ const close = () => {
906
+ this.root.setInputSurface(null);
907
+ this.runtime.requestRender();
908
+ };
909
+ const component = createPiShellTreeSelector({
910
+ tree: context.tree,
911
+ currentLeafId: context.currentLeafId,
912
+ terminalHeight: this.runtime.viewport().rows,
913
+ initialFilterMode: context.filterMode,
914
+ ...(initialSelectedId === undefined ? {} : { initialSelectedId }),
915
+ onLabelChange: context.appendLabelChange,
916
+ onCancel: close,
917
+ onSelect: entryId => {
918
+ close();
919
+ if (entryId === context.currentLeafId) {
920
+ this.root.appendWorkflowStatus("Already at this point");
921
+ this.runtime.requestRender();
922
+ return;
923
+ }
924
+ void this.#completeTreeSelection(entryId, context.skipSummaryPrompt);
925
+ },
926
+ });
927
+ this.root.setInputSurface(component);
928
+ this.runtime.requestRender();
929
+ }
930
+ showLoginAuthTypeSelector() {
931
+ const close = () => {
932
+ this.root.setInputSurface(null);
933
+ this.runtime.requestRender();
934
+ };
935
+ const labels = ["Sign in with an account", "Sign in with an API key"];
936
+ const component = createPiShellExtensionSelector("Select authentication method:", labels, label => {
937
+ close();
938
+ this.showLoginProviderSelector(label === labels[0] ? "oauth" : "api_key");
939
+ }, close);
940
+ this.root.setInputSurface(component);
941
+ this.runtime.requestRender();
942
+ }
943
+ showLoginProviderSelector(authType) {
944
+ const options = this.adapter.pinnedLoginOptions(authType);
945
+ if (options.length === 0) {
946
+ this.root.appendWorkflowStatus(authType === "oauth" ? "No subscription providers available." : "No API key providers available.");
947
+ this.runtime.requestRender();
948
+ return;
949
+ }
950
+ const close = () => {
951
+ this.root.setInputSurface(null);
952
+ this.runtime.requestRender();
953
+ };
954
+ const component = createPiShellAuthProviderSelector("login", options, id => {
955
+ close();
956
+ void this.runWorkflow({ command: "login", argument: "", selection: id });
957
+ }, () => {
958
+ close();
959
+ this.showLoginAuthTypeSelector();
960
+ });
961
+ this.root.setInputSurface(component);
962
+ this.runtime.requestRender();
963
+ }
964
+ showSessionSelector() {
965
+ const context = this.adapter.pinnedSessionSelectorContext();
966
+ const close = () => {
967
+ this.root.setInputSurface(null);
968
+ this.runtime.requestRender();
969
+ };
970
+ const component = createPiShellSessionSelector({
971
+ currentSessionsLoader: context.loadCurrentSessions,
972
+ allSessionsLoader: context.loadAllSessions,
973
+ currentSessionFilePath: context.currentSessionFilePath,
974
+ renameSession: context.renameSession,
975
+ requestRender: () => this.runtime.requestRender(),
976
+ onSelect: sessionPath => {
977
+ close();
978
+ void this.runWorkflow({ command: "resume", argument: sessionPath });
979
+ },
980
+ onCancel: close,
981
+ onExit: () => {
982
+ close();
983
+ void this.shutdown();
984
+ },
985
+ });
986
+ this.root.setInputSurface(component);
987
+ this.runtime.requestRender();
988
+ }
989
+ showSettingsSelector() {
990
+ const snapshot = this.adapter.pinnedSettingsSnapshot();
991
+ const close = () => {
992
+ this.root.setInputSurface(null);
993
+ this.runtime.requestRender();
994
+ };
995
+ const component = createPiShellSettingsSelector({
996
+ config: {
997
+ ...snapshot,
998
+ availableThinkingLevels: [...snapshot.availableThinkingLevels],
999
+ availableThemes: [...snapshot.availableThemes],
1000
+ warnings: { ...snapshot.warnings },
1001
+ },
1002
+ onChange: (callback, value) => {
1003
+ if (callback === "onCancel") {
1004
+ close();
1005
+ return;
1006
+ }
1007
+ if (callback === "onTuiModeChange") {
1008
+ if (value !== "regular" && value !== "fullscreen")
1009
+ return;
1010
+ if (!this.runtime.switchMode(value)) {
1011
+ this.root.appendWorkflowStatus("Close active overlays before changing TUI mode");
1012
+ this.runtime.requestRender();
1013
+ return;
1014
+ }
1015
+ }
1016
+ const result = this.adapter.applyPinnedSettingValue(callback, value);
1017
+ if (result.outcome === "failed")
1018
+ this.root.appendWorkflowResult(result);
1019
+ else if (callback === "onTuiModeChange")
1020
+ this.root.appendWorkflowStatus(`TUI mode: ${value}`);
1021
+ this.runtime.requestRender();
1022
+ },
1023
+ onCancel: close,
1024
+ });
1025
+ this.root.setInputSurface(component);
1026
+ this.runtime.requestRender();
1027
+ }
1028
+ async shutdown() {
1029
+ return this.runWorkflow({ command: "quit", argument: "" });
1030
+ }
1031
+ async runWorkflow(request) {
1032
+ if (request.command === "scoped-models" && request.selection === undefined && request.confirmed === undefined) {
1033
+ this.showScopedModelsSelector();
1034
+ return { outcome: "completed", diagnostic: null };
1035
+ }
1036
+ if (request.command === "model" && request.selection === undefined && request.confirmed === undefined && request.argument.trim().length === 0) {
1037
+ this.showModelSelector();
1038
+ return { outcome: "completed", diagnostic: null };
1039
+ }
1040
+ if (request.command === "fork" && request.selection === undefined && request.confirmed === undefined) {
1041
+ this.showForkSelector();
1042
+ return { outcome: "completed", diagnostic: null };
1043
+ }
1044
+ if (request.command === "trust" && request.selection === undefined && request.confirmed === undefined) {
1045
+ this.showTrustSelector();
1046
+ return { outcome: "completed", diagnostic: null };
1047
+ }
1048
+ if (request.command === "settings" && request.selection === undefined && request.confirmed === undefined) {
1049
+ this.showSettingsSelector();
1050
+ return { outcome: "completed", diagnostic: null };
1051
+ }
1052
+ if (request.command === "resume" && request.selection === undefined && request.confirmed === undefined && request.argument.trim().length === 0) {
1053
+ this.showSessionSelector();
1054
+ return { outcome: "completed", diagnostic: null };
1055
+ }
1056
+ if (request.command === "login" && request.selection === undefined && request.confirmed === undefined) {
1057
+ if (request.argument.trim().length === 0)
1058
+ this.showLoginAuthTypeSelector();
1059
+ else
1060
+ this.showLoginMethodSelector(request.argument);
1061
+ return { outcome: "completed", diagnostic: null };
1062
+ }
1063
+ if (request.command === "logout" && request.selection === undefined && request.confirmed === undefined) {
1064
+ await this.showLogoutSelector();
1065
+ return { outcome: "completed", diagnostic: null };
1066
+ }
1067
+ if (request.command === "import" && request.confirmed === undefined && request.argument.trim().length > 0) {
1068
+ const confirmed = await this.#extensionBridge.context.confirm("Import session", `Replace current session with ${request.argument.trim()}?`);
1069
+ return this.runWorkflow({ ...request, confirmed: confirmed === true });
1070
+ }
1071
+ if (request.command === "tree" && request.selection === undefined && request.confirmed === undefined && request.argument.trim().length === 0) {
1072
+ this.showTreeSelector();
1073
+ return { outcome: "completed", diagnostic: null };
1074
+ }
1075
+ if (request.command === "reload") {
1076
+ this.root.resetExtensionUi();
1077
+ this.root.resetWorkflowPresentation();
1078
+ }
1079
+ const operationSurface = request.command === "share"
1080
+ ? createPiShellOperationLoader({
1081
+ getColumns: () => this.runtime.viewport().columns,
1082
+ getRows: () => this.runtime.viewport().rows,
1083
+ requestRender: () => this.runtime.requestRender(),
1084
+ }, "Creating gist...")
1085
+ : request.command === "reload"
1086
+ ? createPiShellReloadBox()
1087
+ : undefined;
1088
+ if (operationSurface) {
1089
+ this.root.setInputSurface(operationSurface);
1090
+ this.runtime.requestRender();
1091
+ }
1092
+ let result;
1093
+ try {
1094
+ result = await this.adapter.executeWorkflow(request);
1095
+ }
1096
+ finally {
1097
+ if (operationSurface) {
1098
+ this.root.setInputSurface(null);
1099
+ this.runtime.requestRender();
1100
+ }
1101
+ }
1102
+ if (result.outcome === "requires-confirmation" && request.command === "resume") {
1103
+ const confirmed = await this.#extensionBridge.context.confirm("Session cwd not found", result.message);
1104
+ return this.runWorkflow({ ...request, confirmed: confirmed === true });
1105
+ }
1106
+ if (result.outcome === "requires-selection" || result.outcome === "requires-confirmation") {
1107
+ this.root.appendWorkflowResult({ command: request.command, outcome: "failed", message: `Owned controller missing for ${request.command}` });
1108
+ this.runtime.requestRender();
1109
+ return { outcome: "failed", diagnostic: `Owned controller missing for ${request.command}` };
1110
+ }
1111
+ if (request.command === "reload" && result.outcome === "completed") {
1112
+ this.root.editor.setAutocompleteCommands(this.adapter.workflowAutocompleteCommands());
1113
+ }
1114
+ this.root.appendWorkflowResult(result);
1115
+ if (request.command === "model" && result.outcome === "completed")
1116
+ this.#showDaxnutsForActiveModel();
1117
+ this.runtime.requestRender();
1118
+ return workflowAdapterResult(result);
1119
+ }
1120
+ showTrustSelector() {
1121
+ const context = this.adapter.pinnedProjectTrustContext();
1122
+ const close = () => {
1123
+ this.root.setInputSurface(null);
1124
+ this.runtime.requestRender();
1125
+ };
1126
+ const component = createPiShellTrustSelector({
1127
+ ...context,
1128
+ onSelect: selection => {
1129
+ try {
1130
+ this.adapter.persistProjectTrust(selection.updates);
1131
+ close();
1132
+ this.root.appendWorkflowStatus(`Saved trust decision: ${selection.trusted ? "trusted" : "untrusted"}. Restart pi for this to take effect.`);
1133
+ }
1134
+ catch (error) {
1135
+ close();
1136
+ this.root.appendWorkflowResult({ command: "trust", outcome: "failed", message: error instanceof Error ? error.message : String(error) });
1137
+ }
1138
+ this.runtime.requestRender();
1139
+ },
1140
+ onCancel: close,
1141
+ });
1142
+ this.root.setInputSurface(component);
1143
+ this.runtime.requestRender();
1144
+ }
1145
+ showScopedModelsSelector() {
1146
+ const initial = this.adapter.pinnedScopedModelsContext();
1147
+ let currentEnabledIds = initial.enabledModelIds === null ? null : [...initial.enabledModelIds];
1148
+ let selectionChanged = false;
1149
+ let disposed = false;
1150
+ let timedOut = false;
1151
+ const controller = new AbortController();
1152
+ const timeout = setTimeout(() => {
1153
+ timedOut = true;
1154
+ controller.abort();
1155
+ }, 15_000);
1156
+ const close = () => {
1157
+ disposed = true;
1158
+ clearTimeout(timeout);
1159
+ controller.abort();
1160
+ this.root.setInputSurface(null);
1161
+ this.runtime.requestRender();
1162
+ };
1163
+ const selector = createPiShellScopedModelsSelector({
1164
+ models: initial.models,
1165
+ enabledModelIds: currentEnabledIds,
1166
+ refreshStatus: "Refreshing model catalogs…",
1167
+ onChange: enabledIds => {
1168
+ selectionChanged = true;
1169
+ currentEnabledIds = enabledIds === null ? null : [...enabledIds];
1170
+ this.adapter.updateScopedModels(currentEnabledIds);
1171
+ this.runtime.requestRender();
1172
+ },
1173
+ onPersist: enabledIds => {
1174
+ currentEnabledIds = enabledIds === null ? null : [...enabledIds];
1175
+ this.adapter.persistScopedModels(currentEnabledIds);
1176
+ this.root.appendWorkflowStatus("Model selection saved to settings");
1177
+ this.runtime.requestRender();
1178
+ },
1179
+ onCancel: close,
1180
+ });
1181
+ const component = {
1182
+ ...selector,
1183
+ dispose: () => {
1184
+ disposed = true;
1185
+ clearTimeout(timeout);
1186
+ controller.abort();
1187
+ selector.dispose?.();
1188
+ },
1189
+ };
1190
+ this.root.setInputSurface(component);
1191
+ this.runtime.requestRender();
1192
+ void this.adapter.refreshScopedModels(controller.signal).then(refreshed => {
1193
+ if (disposed)
1194
+ return;
1195
+ if (!selectionChanged) {
1196
+ currentEnabledIds = refreshed.enabledModelIds === null ? null : [...refreshed.enabledModelIds];
1197
+ component.updateModels(refreshed.models, currentEnabledIds);
1198
+ }
1199
+ else {
1200
+ component.updateModels(refreshed.models);
1201
+ this.adapter.updateScopedModels(currentEnabledIds);
1202
+ }
1203
+ component.setRefreshStatus(timedOut ? "Model refresh timed out; showing cached models." : refreshed.status, timedOut ? "warning" : refreshed.statusKind);
1204
+ this.runtime.requestRender();
1205
+ }).catch(error => {
1206
+ if (disposed)
1207
+ return;
1208
+ component.setRefreshStatus(timedOut
1209
+ ? "Model refresh timed out; showing cached models."
1210
+ : `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`, "warning");
1211
+ this.runtime.requestRender();
1212
+ }).finally(() => clearTimeout(timeout));
1213
+ }
1214
+ #showDaxnutsForActiveModel() {
1215
+ const model = this.view().activeModel;
1216
+ if (model?.providerId === "opencode" && model.modelId.toLowerCase().includes("kimi-k2.5")) {
1217
+ this.root.appendDaxnuts();
1218
+ }
1219
+ }
1220
+ async dispose() {
1221
+ if (this.#disposed)
1222
+ return;
1223
+ this.#disposed = true;
1224
+ this.#unsubscribe();
1225
+ this.#dialogHandle?.hide();
1226
+ await this.adapter.unbindExtensionUi();
1227
+ this.#extensionBridge.dispose();
1228
+ await this.runtime.dispose();
1229
+ }
1230
+ #syncView() {
1231
+ const view = this.view();
1232
+ if (this.adapter.sessionGeneration !== this.#sessionGeneration) {
1233
+ this.#sessionGeneration = this.adapter.sessionGeneration;
1234
+ this.#activeLoginDialog = undefined;
1235
+ this.#extensionBridge.reset();
1236
+ this.root.setInputSurface(null);
1237
+ this.root.resetExtensionUi();
1238
+ this.root.resetWorkflowPresentation();
1239
+ }
1240
+ this.root.update(view);
1241
+ this.#syncDialog(view.dialog);
1242
+ this.runtime.requestRender();
1243
+ for (const listener of this.#listeners)
1244
+ listener(view);
1245
+ }
1246
+ #syncDialog(dialog) {
1247
+ if (!this.runtime.active)
1248
+ return;
1249
+ if (dialog === null) {
1250
+ this.#dialogHandle?.hide();
1251
+ this.#dialogHandle = undefined;
1252
+ this.#dialogId = undefined;
1253
+ return;
1254
+ }
1255
+ if (this.#dialogId === dialog.id)
1256
+ return;
1257
+ this.#dialogHandle?.hide();
1258
+ const component = createPiShellDialog(dialog, {
1259
+ onSelect: () => {
1260
+ this.#dialogHandle?.hide();
1261
+ this.#dialogHandle = undefined;
1262
+ },
1263
+ onCancel: () => {
1264
+ this.#dialogHandle?.hide();
1265
+ this.#dialogHandle = undefined;
1266
+ },
1267
+ });
1268
+ this.#dialogHandle = this.runtime.showOverlay(component, { width: "70%", maxHeight: "80%", anchor: "center" });
1269
+ this.#dialogId = dialog.id;
1270
+ }
1271
+ async #slashCommand(text) {
1272
+ const body = text.slice(1).trim();
1273
+ const separator = body.search(/\s/);
1274
+ const name = separator < 0 ? body : body.slice(0, separator);
1275
+ const argument = separator < 0 ? "" : body.slice(separator + 1).trimStart();
1276
+ if (isWorkflowRoute(name))
1277
+ return this.runWorkflow({ command: name, argument });
1278
+ // Unknown slash input, prompt templates, skills, and extension commands remain Pi prompt input.
1279
+ this.root.editor.addToHistory(text);
1280
+ return this.#execute({
1281
+ type: this.view().lifecycle === "busy" ? "steer" : "prompt",
1282
+ correlationId: this.#correlation("prompt-command"),
1283
+ sessionId: this.adapter.sessionId,
1284
+ text,
1285
+ });
1286
+ }
1287
+ async #completeTreeSelection(entryId, skipSummaryPrompt) {
1288
+ let summarize = false;
1289
+ let customInstructions;
1290
+ if (!skipSummaryPrompt) {
1291
+ while (true) {
1292
+ const choice = await this.#extensionBridge.context.select("Summarize branch?", [
1293
+ "No summary",
1294
+ "Summarize",
1295
+ "Summarize with custom prompt",
1296
+ ]);
1297
+ if (choice === undefined) {
1298
+ this.showTreeSelector(entryId);
1299
+ return;
1300
+ }
1301
+ summarize = choice !== "No summary";
1302
+ if (choice === "Summarize with custom prompt") {
1303
+ customInstructions = await this.#extensionBridge.context.editor("Custom summarization instructions", "");
1304
+ if (customInstructions === undefined)
1305
+ continue;
1306
+ }
1307
+ break;
1308
+ }
1309
+ }
1310
+ const result = await this.runWorkflow({
1311
+ command: "tree",
1312
+ argument: "",
1313
+ selection: entryId,
1314
+ treeSummary: {
1315
+ summarize,
1316
+ ...(customInstructions === undefined ? {} : { customInstructions }),
1317
+ },
1318
+ });
1319
+ if (result.diagnostic === "Branch summarization cancelled")
1320
+ this.showTreeSelector(entryId);
1321
+ }
1322
+ #startWorkflowLogin(request) {
1323
+ this.#finishWorkflowLogin();
1324
+ const dialog = createPiShellLoginDialog({
1325
+ getColumns: () => this.runtime.viewport().columns,
1326
+ getRows: () => this.runtime.viewport().rows,
1327
+ requestRender: () => this.runtime.requestRender(),
1328
+ }, request.providerId, success => {
1329
+ if (!success)
1330
+ this.#finishWorkflowLogin();
1331
+ }, request.providerName);
1332
+ this.#activeLoginDialog = dialog;
1333
+ this.root.setInputSurface(dialog);
1334
+ this.runtime.requestRender();
1335
+ }
1336
+ #requestWorkflowInput(request) {
1337
+ const dialog = this.#activeLoginDialog;
1338
+ if (!dialog)
1339
+ return Promise.resolve(null);
1340
+ if (request.type === "select") {
1341
+ return new Promise(resolve => {
1342
+ const options = request.options ?? [];
1343
+ const labels = options.map(option => option.label);
1344
+ const restoreDialog = () => {
1345
+ if (this.#activeLoginDialog === dialog)
1346
+ this.root.setInputSurface(dialog);
1347
+ this.runtime.requestRender();
1348
+ };
1349
+ const selector = createPiShellExtensionSelector(request.message, labels, label => {
1350
+ const id = options.find(option => option.label === label)?.id;
1351
+ restoreDialog();
1352
+ resolve(id ?? null);
1353
+ }, () => {
1354
+ restoreDialog();
1355
+ resolve(null);
1356
+ });
1357
+ this.root.setInputSurface(selector, false);
1358
+ this.runtime.requestRender();
1359
+ });
1360
+ }
1361
+ const response = request.type === "manual-code"
1362
+ ? dialog.showManualInput(request.message)
1363
+ : dialog.showPrompt(request.message, request.placeholder);
1364
+ this.runtime.requestRender();
1365
+ return response.then(value => value.trim() || null, () => null);
1366
+ }
1367
+ #notifyWorkflowLogin(event) {
1368
+ const dialog = this.#activeLoginDialog;
1369
+ if (!dialog)
1370
+ return;
1371
+ if (event.type === "auth_url")
1372
+ dialog.showAuth(event.url, event.instructions);
1373
+ else if (event.type === "device_code") {
1374
+ dialog.showDeviceCode(event);
1375
+ dialog.showWaiting("Waiting for authentication...");
1376
+ }
1377
+ else if (event.type === "info")
1378
+ dialog.showInfo(event.message, event.links);
1379
+ else if (event.type === "waiting")
1380
+ dialog.showWaiting(event.message);
1381
+ else
1382
+ dialog.showProgress(event.message);
1383
+ this.runtime.requestRender();
1384
+ }
1385
+ #finishWorkflowLogin() {
1386
+ if (!this.#activeLoginDialog)
1387
+ return;
1388
+ this.#activeLoginDialog = undefined;
1389
+ this.root.setInputSurface(null);
1390
+ this.runtime.requestRender();
1391
+ }
1392
+ async #flushCompactionQueue() {
1393
+ const queued = this.#compactionQueue;
1394
+ this.#compactionQueue = [];
1395
+ for (const item of queued) {
1396
+ await this.#execute({
1397
+ type: item.type,
1398
+ correlationId: this.#correlation(`compaction-${item.type}`),
1399
+ sessionId: this.adapter.sessionId,
1400
+ text: item.text,
1401
+ });
1402
+ }
1403
+ }
1404
+ async #execute(command) {
1405
+ return this.adapter.execute(command);
1406
+ }
1407
+ #simple(type) {
1408
+ return { type, correlationId: this.#correlation(type), sessionId: this.adapter.sessionId };
1409
+ }
1410
+ #correlation(prefix) {
1411
+ this.#sequence += 1;
1412
+ return `pi-shell-${prefix}-${this.#sequence}`;
1413
+ }
1414
+ }
1415
+ function modelReference(model) {
1416
+ if (typeof model !== "object" || model === null)
1417
+ return "";
1418
+ const value = model;
1419
+ const provider = typeof value.provider === "string" ? value.provider : "";
1420
+ const id = typeof value.id === "string" ? value.id : typeof value.modelId === "string" ? value.modelId : "";
1421
+ return provider && id ? `${provider}/${id}` : "";
1422
+ }
1423
+ function rejected(diagnostic) {
1424
+ return { outcome: "rejected", diagnostic };
1425
+ }
1426
+ function workflowAdapterResult(result) {
1427
+ if (result.outcome === "completed")
1428
+ return { outcome: "completed", diagnostic: null };
1429
+ if (result.outcome === "failed")
1430
+ return { outcome: "failed", diagnostic: result.message };
1431
+ return { outcome: "rejected", diagnostic: result.message };
1432
+ }
1433
+ function isWorkflowRoute(value) {
1434
+ return PINNED_PI_WORKFLOW_COMMAND_NAMES.includes(value)
1435
+ || PINNED_PI_HIDDEN_COMMAND_NAMES.includes(value);
1436
+ }
1437
+ //# sourceMappingURL=pi-session-shell.js.map