@timurproko/a1 0.1.8-dev.49ff83a → 0.1.8-dev.508

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 (865) hide show
  1. package/README.md +168 -65
  2. package/bin/cli.js +33 -11
  3. package/bin/guardian.js +16 -6
  4. package/bin/module-identity.js +76 -69
  5. package/bin/module-resolver.js +138 -0
  6. package/bin/pinned-pi-public.d.ts +3 -0
  7. package/bin/pinned-pi-public.js +93 -0
  8. package/bin/release-cleanup.js +8 -0
  9. package/bin/supervisor.js +2 -2
  10. package/bin/ui.js +67 -22
  11. package/bin/update-recovery.js +343 -0
  12. package/bin/warmup.js +28 -0
  13. package/dist/app/session-shell/clipboard-diagnostics.d.ts +16 -0
  14. package/dist/app/session-shell/clipboard-diagnostics.js +65 -0
  15. package/dist/app/session-shell/clipboard-image.d.ts +11 -0
  16. package/dist/app/session-shell/clipboard-image.js +38 -0
  17. package/dist/app/session-shell/editor-hyperlink-budget.d.ts +9 -0
  18. package/dist/app/session-shell/editor-hyperlink-budget.js +23 -0
  19. package/dist/app/session-shell/helper-pool.d.ts +33 -0
  20. package/dist/app/session-shell/helper-pool.js +98 -0
  21. package/dist/app/session-shell/image-preparation-client.d.ts +20 -0
  22. package/dist/app/session-shell/image-preparation-client.js +145 -0
  23. package/dist/app/session-shell/image-preparation.d.ts +18 -0
  24. package/dist/app/session-shell/image-preparation.js +126 -0
  25. package/dist/app/session-shell/image-source.d.ts +13 -0
  26. package/dist/app/session-shell/image-source.js +171 -0
  27. package/dist/app/session-shell/image-worker.d.ts +17 -0
  28. package/dist/app/session-shell/image-worker.js +23 -0
  29. package/dist/app/session-shell/index.d.ts +7 -0
  30. package/dist/app/session-shell/index.js +4 -0
  31. package/dist/app/session-shell/paste-executor.d.ts +18 -0
  32. package/dist/app/session-shell/paste-executor.js +253 -0
  33. package/dist/app/session-shell/paste-helper.js +173 -0
  34. package/dist/app/session-shell/paste-preparation-client.d.ts +31 -0
  35. package/dist/app/session-shell/paste-preparation-client.js +170 -0
  36. package/dist/app/session-shell/paste-protocol.d.ts +78 -0
  37. package/dist/app/session-shell/paste-protocol.js +18 -0
  38. package/dist/app/session-shell/paste-text-preparation.d.ts +6 -0
  39. package/dist/app/session-shell/paste-text-preparation.js +134 -0
  40. package/dist/app/session-shell/paste-text-worker.js +12 -0
  41. package/dist/app/session-shell/paste-types.d.ts +17 -0
  42. package/dist/app/session-shell/path-chip-presentation.d.ts +7 -0
  43. package/dist/app/session-shell/path-chip-presentation.js +24 -0
  44. package/dist/app/session-shell/prompt-chips.d.ts +76 -0
  45. package/dist/app/session-shell/prompt-chips.js +507 -0
  46. package/dist/app/session-shell/prompt-history-controller.d.ts +36 -0
  47. package/dist/app/session-shell/prompt-history-controller.js +170 -0
  48. package/dist/app/session-shell/prompt-suggestion-controller.d.ts +35 -0
  49. package/dist/app/session-shell/prompt-suggestion-controller.js +207 -0
  50. package/dist/app/session-shell/quit-outro-effects.d.ts +29 -0
  51. package/dist/app/session-shell/quit-outro-effects.js +242 -0
  52. package/dist/app/session-shell/quit-outro.d.ts +38 -0
  53. package/dist/app/session-shell/quit-outro.js +98 -0
  54. package/dist/app/session-shell/response-copy-coordinator.d.ts +27 -0
  55. package/dist/app/session-shell/response-copy-coordinator.js +187 -0
  56. package/dist/app/session-shell/response-copy-helper.js +122 -0
  57. package/dist/app/session-shell/response-copy-protocol.d.ts +56 -0
  58. package/dist/app/session-shell/response-copy-protocol.js +5 -0
  59. package/dist/app/session-shell/response-copy-transport.d.ts +39 -0
  60. package/dist/app/session-shell/response-copy-transport.js +217 -0
  61. package/dist/app/session-shell/session-shell-root.d.ts +265 -0
  62. package/dist/app/session-shell/session-shell-root.js +1366 -0
  63. package/dist/app/session-shell/session-shell.d.ts +59 -0
  64. package/dist/app/session-shell/session-shell.js +1917 -0
  65. package/dist/app/session-shell/session-viewport-controller.d.ts +61 -0
  66. package/dist/app/session-shell/session-viewport-controller.js +597 -0
  67. package/dist/app/session-shell/stream-presentation-coalescer.d.ts +29 -0
  68. package/dist/app/session-shell/stream-presentation-coalescer.js +79 -0
  69. package/dist/app/session-shell/system-clipboard.d.ts +20 -0
  70. package/dist/app/session-shell/system-clipboard.js +159 -0
  71. package/dist/app/session-shell/text-paste.d.ts +5 -0
  72. package/dist/app/session-shell/text-paste.js +16 -0
  73. package/dist/cli/capabilities.d.ts +6 -0
  74. package/dist/cli/capabilities.js +7 -0
  75. package/dist/cli/dispatch.d.ts +46 -0
  76. package/dist/cli/dispatch.js +261 -0
  77. package/dist/cli/index.d.ts +8 -0
  78. package/dist/cli/index.js +4 -0
  79. package/dist/cli/package-messages.d.ts +26 -0
  80. package/dist/cli/package-messages.js +71 -0
  81. package/dist/cli/packages.d.ts +32 -0
  82. package/dist/cli/packages.js +81 -0
  83. package/dist/cli/version-stats.d.ts +22 -0
  84. package/dist/cli/version-stats.js +112 -0
  85. package/dist/composition/index.d.ts +2 -0
  86. package/dist/composition/index.js +2 -0
  87. package/dist/composition/owned-ui.d.ts +37 -0
  88. package/dist/composition/owned-ui.js +136 -0
  89. package/dist/composition/settings-route-host.d.ts +7 -0
  90. package/dist/composition/settings-route-host.js +110 -0
  91. package/dist/contracts/agent-engine/capability-ports.d.ts +95 -0
  92. package/dist/contracts/agent-engine/domain-validation.js +107 -0
  93. package/dist/contracts/agent-engine/domain.d.ts +138 -0
  94. package/dist/contracts/agent-engine/index.d.ts +11 -0
  95. package/dist/contracts/agent-engine/index.js +6 -0
  96. package/dist/contracts/agent-engine/package-ports.d.ts +60 -0
  97. package/dist/contracts/agent-engine/ports.js +1 -0
  98. package/dist/contracts/owned-ui/extension-ui.d.ts +310 -0
  99. package/dist/contracts/owned-ui/image-attachments.d.ts +36 -0
  100. package/dist/contracts/owned-ui/image-attachments.js +67 -0
  101. package/dist/contracts/owned-ui/index.d.ts +12 -0
  102. package/dist/contracts/owned-ui/index.js +8 -0
  103. package/dist/contracts/owned-ui/model.d.ts +378 -0
  104. package/dist/contracts/owned-ui/prompt-history.d.ts +55 -0
  105. package/dist/contracts/owned-ui/prompt-history.js +23 -0
  106. package/dist/contracts/owned-ui/prompt-suggestions.d.ts +3 -0
  107. package/dist/contracts/owned-ui/prompt-suggestions.js +44 -0
  108. package/dist/contracts/owned-ui/suggestion-diagnostics.d.ts +22 -0
  109. package/dist/contracts/owned-ui/suggestion-diagnostics.js +9 -0
  110. package/dist/contracts/owned-ui/transcript-lifecycle.d.ts +5 -0
  111. package/dist/contracts/owned-ui/transcript-lifecycle.js +33 -0
  112. package/dist/contracts/owned-ui/validation.d.ts +15 -0
  113. package/dist/contracts/owned-ui/validation.js +523 -0
  114. package/dist/contracts/presentation/index.d.ts +104 -0
  115. package/dist/features/launch/development-launch.js +36 -0
  116. package/dist/features/launch/index.d.ts +12 -0
  117. package/dist/features/launch/index.js +6 -0
  118. package/dist/features/launch/intent.d.ts +12 -0
  119. package/dist/features/launch/intent.js +8 -0
  120. package/dist/features/launch/prepare-launch.d.ts +11 -0
  121. package/dist/features/launch/prepare-launch.js +14 -0
  122. package/dist/features/launch/profile-paths.d.ts +16 -0
  123. package/dist/features/launch/profile-paths.js +36 -0
  124. package/dist/features/launch/runtime-selection.d.ts +16 -0
  125. package/dist/features/launch/runtime-selection.js +13 -0
  126. package/dist/features/owned-ui/index.d.ts +6 -0
  127. package/dist/features/owned-ui/index.js +4 -0
  128. package/dist/features/owned-ui/project-trust-prompt.d.ts +25 -0
  129. package/dist/features/owned-ui/project-trust-prompt.js +149 -0
  130. package/dist/features/owned-ui/run.d.ts +17 -0
  131. package/dist/features/owned-ui/run.js +64 -0
  132. package/dist/features/owned-ui/session-fork-prompt.d.ts +8 -0
  133. package/dist/features/owned-ui/session-fork-prompt.js +34 -0
  134. package/dist/features/owned-ui/settings-app.d.ts +21 -0
  135. package/dist/features/owned-ui/settings-app.js +807 -0
  136. package/dist/features/owned-ui/settings-route.d.ts +2 -0
  137. package/dist/features/owned-ui/settings-route.js +2 -0
  138. package/dist/features/prompt-history/image-sidecar.d.ts +32 -0
  139. package/dist/features/prompt-history/image-sidecar.js +130 -0
  140. package/dist/features/prompt-history/index.d.ts +4 -0
  141. package/dist/features/prompt-history/index.js +3 -0
  142. package/dist/features/prompt-history/paths.d.ts +5 -0
  143. package/dist/features/prompt-history/paths.js +17 -0
  144. package/dist/features/prompt-history/service.d.ts +54 -0
  145. package/dist/features/prompt-history/service.js +425 -0
  146. package/dist/features/prompt-history/store.d.ts +16 -0
  147. package/dist/features/prompt-history/store.js +219 -0
  148. package/dist/features/prompt-history/worker.d.ts +9 -0
  149. package/dist/features/prompt-history/worker.js +45 -0
  150. package/dist/features/prompt-suggestions/diagnostics.d.ts +18 -0
  151. package/dist/features/prompt-suggestions/diagnostics.js +82 -0
  152. package/dist/features/prompt-suggestions/index.d.ts +2 -0
  153. package/dist/features/prompt-suggestions/index.js +1 -0
  154. package/dist/foundation/launch-context/index.d.ts +59 -0
  155. package/dist/foundation/launch-context/index.js +136 -0
  156. package/dist/foundation/launch-guardian/index.d.ts +2 -0
  157. package/dist/foundation/launch-guardian/index.js +1 -0
  158. package/dist/foundation/launch-guardian/main.d.ts +33 -0
  159. package/dist/foundation/launch-guardian/main.js +180 -0
  160. package/dist/foundation/lifecycle/commands.js +1 -0
  161. package/dist/foundation/lifecycle/index.d.ts +11 -0
  162. package/dist/foundation/lifecycle/index.js +5 -0
  163. package/dist/foundation/lifecycle/model.d.ts +64 -0
  164. package/dist/foundation/lifecycle/model.js +40 -0
  165. package/dist/foundation/lifecycle/paths.d.ts +30 -0
  166. package/dist/foundation/lifecycle/paths.js +70 -0
  167. package/dist/foundation/lifecycle/session-selection.d.ts +9 -0
  168. package/dist/foundation/lifecycle/session-selection.js +39 -0
  169. package/dist/foundation/lifecycle/supervisor-startup.d.ts +30 -0
  170. package/dist/foundation/lifecycle/supervisor-startup.js +106 -0
  171. package/dist/foundation/process-containment/darwin-process-inspector.d.ts +5 -0
  172. package/dist/foundation/process-containment/darwin-process-inspector.js +7 -0
  173. package/dist/foundation/process-containment/index.d.ts +8 -0
  174. package/dist/foundation/process-containment/index.js +6 -0
  175. package/dist/foundation/process-containment/linux-process-inspector.d.ts +7 -0
  176. package/dist/foundation/process-containment/linux-process-inspector.js +27 -0
  177. package/dist/foundation/process-containment/native-guardian-containment.d.ts +17 -0
  178. package/dist/foundation/process-containment/native-guardian-containment.js +140 -0
  179. package/dist/foundation/process-containment/windows-process-inspector.d.ts +19 -0
  180. package/dist/foundation/process-containment/windows-process-inspector.js +56 -0
  181. package/dist/foundation/protocol/client.d.ts +18 -0
  182. package/dist/foundation/protocol/client.js +130 -0
  183. package/dist/foundation/protocol/index.d.ts +3 -0
  184. package/dist/foundation/protocol/index.js +2 -0
  185. package/dist/foundation/protocol/messages.d.ts +90 -0
  186. package/dist/foundation/protocol/messages.js +100 -0
  187. package/dist/foundation/release/bootstrap.d.ts +51 -0
  188. package/dist/foundation/release/bootstrap.js +427 -0
  189. package/dist/foundation/release/cohort-state.d.ts +157 -0
  190. package/dist/foundation/release/cohort-state.js +472 -0
  191. package/dist/foundation/release/dependency-certification-retention.d.ts +7 -0
  192. package/dist/foundation/release/dependency-certification-retention.js +88 -0
  193. package/dist/foundation/release/dependency-certification.d.ts +24 -0
  194. package/dist/foundation/release/dependency-certification.js +266 -0
  195. package/dist/foundation/release/dependency-layer.d.ts +78 -0
  196. package/dist/foundation/release/dependency-layer.js +466 -0
  197. package/dist/foundation/release/endpoints.d.ts +24 -0
  198. package/dist/foundation/release/endpoints.js +134 -0
  199. package/dist/foundation/release/immutable-platform.d.ts +6 -0
  200. package/dist/foundation/release/immutable-platform.js +13 -0
  201. package/dist/foundation/release/index.d.ts +30 -0
  202. package/dist/foundation/release/index.js +16 -0
  203. package/dist/foundation/release/release-gc.d.ts +71 -0
  204. package/dist/foundation/release/release-gc.js +764 -0
  205. package/dist/foundation/release/release-store.d.ts +49 -0
  206. package/dist/foundation/release/release-store.js +235 -0
  207. package/dist/foundation/release/release.d.ts +43 -0
  208. package/dist/foundation/release/release.js +215 -0
  209. package/dist/foundation/release/restart-certification.d.ts +68 -0
  210. package/dist/foundation/release/restart-certification.js +227 -0
  211. package/dist/foundation/release/types.d.ts +11 -0
  212. package/dist/foundation/release/types.js +1 -0
  213. package/dist/foundation/release/update-launch.d.ts +6 -0
  214. package/dist/foundation/release/update-launch.js +17 -0
  215. package/dist/foundation/release/update-recovery.d.ts +76 -0
  216. package/dist/foundation/release/update-recovery.js +356 -0
  217. package/dist/foundation/release/update-transaction.d.ts +42 -0
  218. package/dist/foundation/release/update-transaction.js +101 -0
  219. package/dist/foundation/release/update.d.ts +119 -0
  220. package/dist/foundation/release/update.js +632 -0
  221. package/dist/foundation/release/warmup.d.ts +3 -0
  222. package/dist/foundation/release/warmup.js +47 -0
  223. package/dist/foundation/startup/index.d.ts +4 -0
  224. package/dist/foundation/startup/index.js +2 -0
  225. package/dist/foundation/startup/startup-budget.d.ts +46 -0
  226. package/dist/foundation/startup/startup-budget.js +42 -0
  227. package/dist/foundation/startup/startup-descriptor.js +34 -0
  228. package/dist/foundation/startup/startup-runtime.d.ts +27 -0
  229. package/dist/foundation/startup/startup-runtime.js +128 -0
  230. package/dist/foundation/storage/control-store.d.ts +18 -0
  231. package/dist/foundation/storage/control-store.js +342 -0
  232. package/dist/foundation/storage/index.d.ts +1 -0
  233. package/dist/foundation/storage/index.js +1 -0
  234. package/dist/foundation/supervision/index.d.ts +3 -0
  235. package/dist/foundation/supervision/index.js +3 -0
  236. package/dist/foundation/supervision/main.d.ts +1 -0
  237. package/dist/foundation/supervision/main.js +84 -0
  238. package/dist/foundation/supervision/paths.d.ts +1 -0
  239. package/dist/foundation/supervision/paths.js +1 -0
  240. package/dist/foundation/supervision/server.d.ts +46 -0
  241. package/dist/foundation/supervision/server.js +573 -0
  242. package/dist/foundation/terminal-cleanup/fatal-exit.d.ts +12 -0
  243. package/dist/foundation/terminal-cleanup/fatal-exit.js +87 -0
  244. package/dist/foundation/terminal-cleanup/index.d.ts +3 -0
  245. package/dist/foundation/terminal-cleanup/index.js +2 -0
  246. package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +4 -0
  247. package/dist/foundation/terminal-cleanup/terminal-reset.js +40 -0
  248. package/dist/integrations/pi/components/components.d.ts +4 -0
  249. package/dist/integrations/pi/components/components.js +64 -0
  250. package/dist/integrations/pi/components/conformance.d.ts +18 -0
  251. package/dist/integrations/pi/components/conformance.js +70 -0
  252. package/dist/integrations/pi/components/editor-interaction.d.ts +38 -0
  253. package/dist/integrations/pi/components/editor-interaction.js +1 -0
  254. package/dist/integrations/pi/components/history-editor-loader.d.ts +5 -0
  255. package/dist/integrations/pi/components/history-editor-loader.js +5 -0
  256. package/dist/integrations/pi/components/index.d.ts +21 -0
  257. package/dist/integrations/pi/components/index.js +13 -0
  258. package/dist/integrations/pi/components/owned-editor-ux.d.ts +74 -0
  259. package/dist/integrations/pi/components/owned-editor-ux.js +1094 -0
  260. package/dist/integrations/pi/components/path-word-ranges.d.ts +2 -0
  261. package/dist/integrations/pi/components/path-word-ranges.js +37 -0
  262. package/dist/integrations/pi/components/prompt-input-port.d.ts +18 -0
  263. package/dist/integrations/pi/components/prompt-input-port.js +1 -0
  264. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +167 -0
  265. package/dist/integrations/pi/components/resources/builtin-themes.js +168 -0
  266. package/dist/integrations/pi/components/shell-components.d.ts +7 -0
  267. package/dist/integrations/pi/components/shell-components.js +7 -0
  268. package/dist/integrations/pi/components/shell-editor-autocomplete.js +298 -0
  269. package/dist/integrations/pi/components/shell-extension-ui.d.ts +35 -0
  270. package/dist/integrations/pi/components/shell-extension-ui.js +280 -0
  271. package/dist/integrations/pi/components/shell-footer-status.d.ts +7 -0
  272. package/dist/integrations/pi/components/shell-footer-status.js +248 -0
  273. package/dist/integrations/pi/components/shell-presenters-info.d.ts +43 -0
  274. package/dist/integrations/pi/components/shell-presenters-info.js +114 -0
  275. package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +29 -0
  276. package/dist/integrations/pi/components/shell-presenters-transcript.js +433 -0
  277. package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +123 -0
  278. package/dist/integrations/pi/components/shell-selectors-dialogs.js +242 -0
  279. package/dist/integrations/pi/components/shell-shared-facade.d.ts +217 -0
  280. package/dist/integrations/pi/components/shell-shared-facade.js +92 -0
  281. package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +17 -0
  282. package/dist/integrations/pi/components/submitted-prompt-adapter.js +49 -0
  283. package/dist/integrations/pi/components/tool-image-presentation.d.ts +21 -0
  284. package/dist/integrations/pi/components/tool-image-presentation.js +83 -0
  285. package/dist/integrations/pi/components/tool-result-adapter.d.ts +6 -0
  286. package/dist/integrations/pi/components/tool-result-adapter.js +27 -0
  287. package/dist/integrations/pi/components/transcript-image-resolver.d.ts +7 -0
  288. package/dist/integrations/pi/components/transcript-image-resolver.js +19 -0
  289. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +445 -0
  290. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +370 -0
  291. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +12 -0
  292. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +13 -0
  293. package/dist/integrations/pi/components/upstream/components/daxnuts.d.ts +29 -0
  294. package/dist/integrations/pi/components/upstream/components/daxnuts.js +146 -0
  295. package/dist/integrations/pi/components/upstream/components/earendil-announcement.d.ts +4 -0
  296. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +48 -0
  297. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +20 -0
  298. package/dist/integrations/pi/components/upstream/components/extension-editor.js +84 -0
  299. package/dist/integrations/pi/components/upstream/components/mermaid.js +81 -0
  300. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +46 -0
  301. package/dist/integrations/pi/components/upstream/components/owned-editor.js +187 -0
  302. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +59 -0
  303. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +346 -0
  304. package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +11 -0
  305. package/dist/integrations/pi/components/upstream/components/session-footer.js +123 -0
  306. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +161 -0
  307. package/dist/integrations/pi/components/upstream/components/session-selector.d.ts +95 -0
  308. package/dist/integrations/pi/components/upstream/components/session-selector.js +893 -0
  309. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +21 -0
  310. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +46 -0
  311. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +35 -0
  312. package/dist/integrations/pi/components/upstream/components/status-indicator.js +69 -0
  313. package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +67 -0
  314. package/dist/integrations/pi/components/upstream/components/tool-execution.js +365 -0
  315. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +101 -0
  316. package/dist/integrations/pi/components/upstream/components/tree-selector.js +1275 -0
  317. package/dist/integrations/pi/components/upstream/components/trust-selector.d.ts +33 -0
  318. package/dist/integrations/pi/components/upstream/components/trust-selector.js +81 -0
  319. package/dist/integrations/pi/components/upstream/external-editor.js +43 -0
  320. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +289 -0
  321. package/dist/integrations/pi/components/upstream/history/editor-core.js +2144 -0
  322. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +35 -0
  323. package/dist/integrations/pi/components/upstream/history/kill-ring.js +51 -0
  324. package/dist/integrations/pi/components/upstream/history/printable-key.d.ts +1 -0
  325. package/dist/integrations/pi/components/upstream/history/printable-key.js +43 -0
  326. package/dist/integrations/pi/components/upstream/history/text-helpers.d.ts +14 -0
  327. package/dist/integrations/pi/components/upstream/history/text-helpers.js +31 -0
  328. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +25 -0
  329. package/dist/integrations/pi/components/upstream/history/undo-stack.js +39 -0
  330. package/dist/integrations/pi/components/upstream/history/word-navigation.d.ts +24 -0
  331. package/dist/integrations/pi/components/upstream/history/word-navigation.js +103 -0
  332. package/dist/integrations/pi/components/upstream/model-search.d.ts +18 -0
  333. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +33 -0
  334. package/dist/integrations/pi/components/upstream/theme/theme-controller.js +114 -0
  335. package/dist/integrations/pi/components/upstream/theme/theme.d.ts +61 -0
  336. package/dist/integrations/pi/components/upstream/theme/theme.js +337 -0
  337. package/dist/integrations/pi/engine/adapter.d.ts +135 -0
  338. package/dist/integrations/pi/engine/adapter.js +648 -0
  339. package/dist/integrations/pi/engine/changelog.d.ts +2 -0
  340. package/dist/integrations/pi/engine/changelog.js +63 -0
  341. package/dist/integrations/pi/engine/command-dispatch.d.ts +41 -0
  342. package/dist/integrations/pi/engine/command-dispatch.js +125 -0
  343. package/dist/integrations/pi/engine/compaction-progress.d.ts +28 -0
  344. package/dist/integrations/pi/engine/compaction-progress.js +96 -0
  345. package/dist/integrations/pi/engine/conformance.d.ts +39 -0
  346. package/dist/integrations/pi/engine/conformance.js +140 -0
  347. package/dist/integrations/pi/engine/event-delivery.d.ts +100 -0
  348. package/dist/integrations/pi/engine/event-delivery.js +184 -0
  349. package/dist/integrations/pi/engine/extension-ui-binding.d.ts +35 -0
  350. package/dist/integrations/pi/engine/extension-ui-binding.js +81 -0
  351. package/dist/integrations/pi/engine/http-dispatcher.d.ts +4 -0
  352. package/dist/integrations/pi/engine/http-dispatcher.js +25 -0
  353. package/dist/integrations/pi/engine/index.d.ts +18 -0
  354. package/dist/integrations/pi/engine/index.js +10 -0
  355. package/dist/integrations/pi/engine/message-values.d.ts +29 -0
  356. package/dist/integrations/pi/engine/message-values.js +168 -0
  357. package/dist/integrations/pi/engine/package-integration.d.ts +13 -0
  358. package/dist/integrations/pi/engine/package-integration.js +118 -0
  359. package/dist/integrations/pi/engine/pending-delivery.d.ts +30 -0
  360. package/dist/integrations/pi/engine/pending-delivery.js +156 -0
  361. package/dist/integrations/pi/engine/pi-settings-metadata.json +385 -0
  362. package/dist/integrations/pi/engine/project-trust-preflight.d.ts +22 -0
  363. package/dist/integrations/pi/engine/project-trust-preflight.js +50 -0
  364. package/dist/integrations/pi/engine/prompt-suggestions.d.ts +30 -0
  365. package/dist/integrations/pi/engine/prompt-suggestions.js +102 -0
  366. package/dist/integrations/pi/engine/provider-authentication.d.ts +34 -0
  367. package/dist/integrations/pi/engine/provider-authentication.js +209 -0
  368. package/dist/integrations/pi/engine/resource-catalog.d.ts +49 -0
  369. package/dist/integrations/pi/engine/resource-catalog.js +289 -0
  370. package/dist/integrations/pi/engine/resources/changelog.json +12 -0
  371. package/dist/integrations/pi/engine/runtime-integration.d.ts +53 -0
  372. package/dist/integrations/pi/engine/runtime-integration.js +118 -0
  373. package/dist/integrations/pi/engine/session-events.d.ts +48 -0
  374. package/dist/integrations/pi/engine/session-events.js +223 -0
  375. package/dist/integrations/pi/engine/session-integration.d.ts +67 -0
  376. package/dist/integrations/pi/engine/session-integration.js +195 -0
  377. package/dist/integrations/pi/engine/session-runtime.d.ts +84 -0
  378. package/dist/integrations/pi/engine/session-runtime.js +249 -0
  379. package/dist/integrations/pi/engine/session-selection.d.ts +28 -0
  380. package/dist/integrations/pi/engine/session-selection.js +90 -0
  381. package/dist/integrations/pi/engine/settings-bridge.d.ts +121 -0
  382. package/dist/integrations/pi/engine/settings-bridge.js +514 -0
  383. package/dist/integrations/pi/engine/settings-metadata.d.ts +31 -0
  384. package/dist/integrations/pi/engine/settings-metadata.js +67 -0
  385. package/dist/integrations/pi/engine/settings-port.d.ts +42 -0
  386. package/dist/integrations/pi/engine/settings-port.js +353 -0
  387. package/dist/integrations/pi/engine/tool-rendering.d.ts +13 -0
  388. package/dist/integrations/pi/engine/tool-rendering.js +145 -0
  389. package/dist/integrations/pi/engine/transcript-image-assets.d.ts +11 -0
  390. package/dist/integrations/pi/engine/transcript-image-assets.js +86 -0
  391. package/dist/integrations/pi/engine/transcript-projection.d.ts +39 -0
  392. package/dist/integrations/pi/engine/transcript-projection.js +405 -0
  393. package/dist/integrations/pi/engine/usage-view.d.ts +4 -0
  394. package/dist/integrations/pi/engine/usage-view.js +56 -0
  395. package/dist/integrations/pi/engine/windows-filesystem-hygiene.d.ts +21 -0
  396. package/dist/integrations/pi/engine/windows-filesystem-hygiene.js +55 -0
  397. package/dist/integrations/pi/engine/workflow-contexts.d.ts +59 -0
  398. package/dist/integrations/pi/engine/workflow-contexts.js +316 -0
  399. package/dist/integrations/pi/engine/workflow-runner.d.ts +60 -0
  400. package/dist/integrations/pi/engine/workflow-runner.js +509 -0
  401. package/dist/integrations/pi/engine/workflow-support.d.ts +33 -0
  402. package/dist/integrations/pi/engine/workflow-support.js +352 -0
  403. package/dist/integrations/pi/engine/workflows.d.ts +251 -0
  404. package/dist/integrations/pi/engine/workflows.js +63 -0
  405. package/dist/integrations/pi/startup-public.d.ts +2 -0
  406. package/dist/integrations/pi/startup-public.js +2223 -0
  407. package/dist/integrations/pi/startup-public.manifest.json +12502 -0
  408. package/dist/integrations/pi/tui-runtime/adapter.d.ts +56 -0
  409. package/dist/integrations/pi/tui-runtime/adapter.js +783 -0
  410. package/dist/integrations/pi/tui-runtime/contracts.d.ts +156 -0
  411. package/dist/integrations/pi/tui-runtime/contracts.js +1 -0
  412. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +88 -0
  413. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +433 -0
  414. package/dist/integrations/pi/tui-runtime/index.d.ts +9 -0
  415. package/dist/integrations/pi/tui-runtime/index.js +5 -0
  416. package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +39 -0
  417. package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.js +139 -0
  418. package/dist/integrations/pi/tui-runtime/mouse-report-input.d.ts +13 -0
  419. package/dist/integrations/pi/tui-runtime/mouse-report-input.js +57 -0
  420. package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +32 -0
  421. package/dist/integrations/pi/tui-runtime/overlay-geometry.js +158 -0
  422. package/dist/integrations/pi/tui-runtime/presentation-adapter.d.ts +4 -0
  423. package/dist/integrations/pi/tui-runtime/presentation-adapter.js +48 -0
  424. package/dist/native/darwin-arm64/manifest.json +4 -4
  425. package/dist/native/darwin-arm64/process-guardian +0 -0
  426. package/dist/native/linux-x64/manifest.json +3 -3
  427. package/dist/native/linux-x64/process-guardian +0 -0
  428. package/dist/native/win32-x64/manifest.json +3 -3
  429. package/dist/native/win32-x64/process-guardian.exe +0 -0
  430. package/dist/product-identity.d.ts +37 -0
  431. package/dist/product-identity.js +119 -0
  432. package/dist/product-identity.json +85 -0
  433. package/dist/runtime-payload-inventory.json +127147 -0
  434. package/dist/ui/apps/contracts.d.ts +64 -0
  435. package/dist/ui/apps/host.d.ts +42 -0
  436. package/dist/ui/apps/host.js +156 -0
  437. package/dist/ui/apps/index.d.ts +5 -0
  438. package/dist/ui/apps/index.js +3 -0
  439. package/dist/ui/apps/registry.d.ts +12 -0
  440. package/dist/ui/apps/registry.js +33 -0
  441. package/dist/ui/components/dialog-panel.js +49 -0
  442. package/dist/ui/components/frame.d.ts +22 -0
  443. package/dist/ui/components/frame.js +55 -0
  444. package/dist/ui/components/index.d.ts +47 -0
  445. package/dist/ui/components/index.js +25 -0
  446. package/dist/ui/components/line-input.d.ts +68 -0
  447. package/dist/ui/components/line-input.js +224 -0
  448. package/dist/ui/components/list-view.d.ts +60 -0
  449. package/dist/ui/components/list-view.js +82 -0
  450. package/dist/ui/components/mouse.d.ts +25 -0
  451. package/dist/ui/components/mouse.js +70 -0
  452. package/dist/ui/components/progress-status.d.ts +2 -0
  453. package/dist/ui/components/progress-status.js +4 -0
  454. package/dist/ui/components/prompt-input.d.ts +32 -0
  455. package/dist/ui/components/prompt-input.js +51 -0
  456. package/dist/ui/components/scrollbar.d.ts +88 -0
  457. package/dist/ui/components/scrollbar.js +137 -0
  458. package/dist/ui/components/selection-copy.d.ts +24 -0
  459. package/dist/ui/components/selection-copy.js +39 -0
  460. package/dist/ui/components/shortcuts.d.ts +58 -0
  461. package/dist/ui/components/shortcuts.js +82 -0
  462. package/dist/ui/components/spans.d.ts +28 -0
  463. package/dist/ui/components/spans.js +266 -0
  464. package/dist/ui/components/submitted-prompt.d.ts +23 -0
  465. package/dist/ui/components/submitted-prompt.js +50 -0
  466. package/dist/ui/components/surface.d.ts +20 -0
  467. package/dist/ui/components/surface.js +44 -0
  468. package/dist/ui/components/text-selection.d.ts +62 -0
  469. package/dist/ui/components/text-selection.js +210 -0
  470. package/dist/ui/components/text.d.ts +38 -0
  471. package/dist/ui/components/text.js +185 -0
  472. package/dist/ui/components/transcript-viewport.d.ts +173 -0
  473. package/dist/ui/components/transcript-viewport.js +753 -0
  474. package/dist/ui/components/visible-hyperlinks.d.ts +26 -0
  475. package/dist/ui/components/visible-hyperlinks.js +97 -0
  476. package/dist/ui/settings/declarations.d.ts +141 -0
  477. package/dist/ui/settings/declarations.js +135 -0
  478. package/dist/ui/settings/index.d.ts +10 -0
  479. package/dist/ui/settings/index.js +5 -0
  480. package/dist/ui/settings/manager.d.ts +54 -0
  481. package/dist/ui/settings/manager.js +256 -0
  482. package/dist/ui/settings/migrations.d.ts +13 -0
  483. package/dist/ui/settings/migrations.js +74 -0
  484. package/dist/ui/settings/sections.d.ts +52 -0
  485. package/dist/ui/settings/sections.js +112 -0
  486. package/docs/architecture/boundaries.md +17 -13
  487. package/docs/architecture/code-documentation.md +77 -0
  488. package/docs/architecture/history-editor-provenance.md +100 -0
  489. package/docs/architecture/internal-naming.md +91 -0
  490. package/docs/architecture/process-guardian-provenance.md +3 -1
  491. package/docs/architecture/project-structure.md +69 -30
  492. package/docs/architecture/prompt-suggestions.md +68 -0
  493. package/docs/architecture/resource-and-data-policy.md +28 -2
  494. package/docs/architecture/response-copy-delivery.md +85 -0
  495. package/docs/architecture/terminal-host-proof-gate.md +1 -1
  496. package/docs/architecture/terminal-host-spike-evidence.md +1 -1
  497. package/docs/architecture/tool-image-presentation.md +62 -0
  498. package/docs/architecture/toolchain.md +32 -10
  499. package/docs/architecture/ui-reference-provenance.md +60 -6
  500. package/docs/ci-release-runbook.md +256 -79
  501. package/docs/features/launch-profiles.md +24 -17
  502. package/docs/features/modal-content-interaction.md +37 -0
  503. package/docs/features/prompt-history.md +149 -0
  504. package/docs/local-worktree-cleanup.md +212 -0
  505. package/docs/manual-code-streaming-cleanup.md +88 -0
  506. package/docs/manual-ghost-link-baseline.md +89 -0
  507. package/docs/manual-launch-instance-acceptance.md +12 -35
  508. package/docs/manual-owned-ui-checkpoint.md +79 -0
  509. package/docs/manual-pi-boundary-candidate.md +4 -5
  510. package/docs/manual-terminal-colour-check.md +4 -3
  511. package/docs/openspec-archive-automation.md +259 -0
  512. package/docs/repository-governance-live-acceptance.md +77 -0
  513. package/docs/validation.md +100 -0
  514. package/package.json +49 -34
  515. package/dist/src/cli/capabilities.d.ts +0 -15
  516. package/dist/src/cli/capabilities.js +0 -7
  517. package/dist/src/cli/dispatch.d.ts +0 -32
  518. package/dist/src/cli/dispatch.js +0 -142
  519. package/dist/src/cli/index.d.ts +0 -5
  520. package/dist/src/cli/index.js +0 -5
  521. package/dist/src/cli/packages.d.ts +0 -23
  522. package/dist/src/cli/packages.js +0 -84
  523. package/dist/src/cli/version-stats.d.ts +0 -16
  524. package/dist/src/cli/version-stats.js +0 -72
  525. package/dist/src/cli/version.d.ts +0 -2
  526. package/dist/src/cli/version.js +0 -23
  527. package/dist/src/composition/index.d.ts +0 -48
  528. package/dist/src/composition/index.js +0 -258
  529. package/dist/src/features/launch/development-launch.js +0 -28
  530. package/dist/src/features/launch/index.d.ts +0 -7
  531. package/dist/src/features/launch/index.js +0 -7
  532. package/dist/src/features/launch/intent.d.ts +0 -7
  533. package/dist/src/features/launch/intent.js +0 -4
  534. package/dist/src/features/launch/prepare-launch.d.ts +0 -13
  535. package/dist/src/features/launch/prepare-launch.js +0 -21
  536. package/dist/src/features/launch/profile-paths.d.ts +0 -15
  537. package/dist/src/features/launch/profile-paths.js +0 -31
  538. package/dist/src/features/launch/profiles.d.ts +0 -12
  539. package/dist/src/features/launch/profiles.js +0 -26
  540. package/dist/src/features/launch/runtime-selection.d.ts +0 -19
  541. package/dist/src/features/launch/runtime-selection.js +0 -13
  542. package/dist/src/features/owned-ui/customization.d.ts +0 -38
  543. package/dist/src/features/owned-ui/customization.js +0 -108
  544. package/dist/src/features/owned-ui/diagnostics.d.ts +0 -33
  545. package/dist/src/features/owned-ui/diagnostics.js +0 -94
  546. package/dist/src/features/owned-ui/index.d.ts +0 -4
  547. package/dist/src/features/owned-ui/index.js +0 -4
  548. package/dist/src/features/owned-ui/run.d.ts +0 -11
  549. package/dist/src/features/owned-ui/run.js +0 -15
  550. package/dist/src/features/owned-ui/settings-app.d.ts +0 -22
  551. package/dist/src/features/owned-ui/settings-app.js +0 -633
  552. package/dist/src/features/workspace/capabilities.d.ts +0 -31
  553. package/dist/src/features/workspace/capabilities.js +0 -75
  554. package/dist/src/features/workspace/index.d.ts +0 -6
  555. package/dist/src/features/workspace/index.js +0 -6
  556. package/dist/src/features/workspace/presentation.d.ts +0 -30
  557. package/dist/src/features/workspace/presentation.js +0 -70
  558. package/dist/src/features/workspace/reconciliation.d.ts +0 -15
  559. package/dist/src/features/workspace/reconciliation.js +0 -82
  560. package/dist/src/features/workspace/reducer.d.ts +0 -42
  561. package/dist/src/features/workspace/reducer.js +0 -213
  562. package/dist/src/features/workspace/router.d.ts +0 -31
  563. package/dist/src/features/workspace/router.js +0 -124
  564. package/dist/src/features/workspace/store.d.ts +0 -17
  565. package/dist/src/features/workspace/store.js +0 -54
  566. package/dist/src/foundation/agent-engine-contracts/capability-ports.d.ts +0 -95
  567. package/dist/src/foundation/agent-engine-contracts/domain-validation.js +0 -89
  568. package/dist/src/foundation/agent-engine-contracts/domain.d.ts +0 -116
  569. package/dist/src/foundation/agent-engine-contracts/index.d.ts +0 -8
  570. package/dist/src/foundation/agent-engine-contracts/index.js +0 -8
  571. package/dist/src/foundation/agent-engine-contracts/package-ports.d.ts +0 -54
  572. package/dist/src/foundation/launch-guardian/index.d.ts +0 -1
  573. package/dist/src/foundation/launch-guardian/index.js +0 -1
  574. package/dist/src/foundation/launch-guardian/main.d.ts +0 -31
  575. package/dist/src/foundation/launch-guardian/main.js +0 -165
  576. package/dist/src/foundation/lifecycle/index.d.ts +0 -4
  577. package/dist/src/foundation/lifecycle/index.js +0 -4
  578. package/dist/src/foundation/lifecycle/model.d.ts +0 -64
  579. package/dist/src/foundation/lifecycle/model.js +0 -40
  580. package/dist/src/foundation/lifecycle/paths.d.ts +0 -10
  581. package/dist/src/foundation/lifecycle/paths.js +0 -42
  582. package/dist/src/foundation/native-host-protocol/codec.d.ts +0 -11
  583. package/dist/src/foundation/native-host-protocol/codec.js +0 -56
  584. package/dist/src/foundation/native-host-protocol/evidence.d.ts +0 -67
  585. package/dist/src/foundation/native-host-protocol/evidence.js +0 -141
  586. package/dist/src/foundation/native-host-protocol/index.d.ts +0 -4
  587. package/dist/src/foundation/native-host-protocol/index.js +0 -4
  588. package/dist/src/foundation/native-host-protocol/messages.d.ts +0 -56
  589. package/dist/src/foundation/native-host-protocol/messages.js +0 -149
  590. package/dist/src/foundation/native-host-protocol/proof-gate.d.ts +0 -13
  591. package/dist/src/foundation/native-host-protocol/proof-gate.js +0 -33
  592. package/dist/src/foundation/owned-ui-contracts/extension-ui.d.ts +0 -302
  593. package/dist/src/foundation/owned-ui-contracts/index.d.ts +0 -3
  594. package/dist/src/foundation/owned-ui-contracts/index.js +0 -3
  595. package/dist/src/foundation/owned-ui-contracts/model.d.ts +0 -241
  596. package/dist/src/foundation/owned-ui-contracts/validation.d.ts +0 -11
  597. package/dist/src/foundation/owned-ui-contracts/validation.js +0 -395
  598. package/dist/src/foundation/owned-ui-settings/declarations.d.ts +0 -13
  599. package/dist/src/foundation/owned-ui-settings/declarations.js +0 -39
  600. package/dist/src/foundation/owned-ui-settings/index.d.ts +0 -6
  601. package/dist/src/foundation/owned-ui-settings/index.js +0 -6
  602. package/dist/src/foundation/owned-ui-settings/migrations.d.ts +0 -13
  603. package/dist/src/foundation/owned-ui-settings/migrations.js +0 -28
  604. package/dist/src/foundation/owned-ui-settings/sections.d.ts +0 -70
  605. package/dist/src/foundation/owned-ui-settings/sections.js +0 -93
  606. package/dist/src/foundation/owned-ui-settings/session.d.ts +0 -44
  607. package/dist/src/foundation/owned-ui-settings/session.js +0 -145
  608. package/dist/src/foundation/owned-ui-settings/store.d.ts +0 -28
  609. package/dist/src/foundation/owned-ui-settings/store.js +0 -90
  610. package/dist/src/foundation/pi-component-adapter/components.d.ts +0 -4
  611. package/dist/src/foundation/pi-component-adapter/components.js +0 -64
  612. package/dist/src/foundation/pi-component-adapter/conformance.d.ts +0 -17
  613. package/dist/src/foundation/pi-component-adapter/conformance.js +0 -69
  614. package/dist/src/foundation/pi-component-adapter/index.d.ts +0 -13
  615. package/dist/src/foundation/pi-component-adapter/index.js +0 -13
  616. package/dist/src/foundation/pi-component-adapter/resources/builtin-themes.d.ts +0 -165
  617. package/dist/src/foundation/pi-component-adapter/resources/builtin-themes.js +0 -166
  618. package/dist/src/foundation/pi-component-adapter/shell-components.d.ts +0 -6
  619. package/dist/src/foundation/pi-component-adapter/shell-components.js +0 -6
  620. package/dist/src/foundation/pi-component-adapter/shell-editor-autocomplete.js +0 -162
  621. package/dist/src/foundation/pi-component-adapter/shell-extension-ui.d.ts +0 -35
  622. package/dist/src/foundation/pi-component-adapter/shell-extension-ui.js +0 -279
  623. package/dist/src/foundation/pi-component-adapter/shell-footer-status.d.ts +0 -7
  624. package/dist/src/foundation/pi-component-adapter/shell-footer-status.js +0 -189
  625. package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.d.ts +0 -57
  626. package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.js +0 -429
  627. package/dist/src/foundation/pi-component-adapter/shell-selectors-dialogs.d.ts +0 -113
  628. package/dist/src/foundation/pi-component-adapter/shell-selectors-dialogs.js +0 -235
  629. package/dist/src/foundation/pi-component-adapter/shell-shared-facade.d.ts +0 -116
  630. package/dist/src/foundation/pi-component-adapter/shell-shared-facade.js +0 -87
  631. package/dist/src/foundation/pi-component-adapter/upstream/adjacent/core/keybindings.d.ts +0 -422
  632. package/dist/src/foundation/pi-component-adapter/upstream/adjacent/core/keybindings.js +0 -296
  633. package/dist/src/foundation/pi-component-adapter/upstream/components/countdown-timer.d.ts +0 -10
  634. package/dist/src/foundation/pi-component-adapter/upstream/components/custom-entry.d.ts +0 -17
  635. package/dist/src/foundation/pi-component-adapter/upstream/components/custom-entry.js +0 -51
  636. package/dist/src/foundation/pi-component-adapter/upstream/components/daxnuts.d.ts +0 -22
  637. package/dist/src/foundation/pi-component-adapter/upstream/components/daxnuts.js +0 -142
  638. package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.d.ts +0 -4
  639. package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.js +0 -19
  640. package/dist/src/foundation/pi-component-adapter/upstream/components/extension-editor.d.ts +0 -17
  641. package/dist/src/foundation/pi-component-adapter/upstream/components/extension-editor.js +0 -81
  642. package/dist/src/foundation/pi-component-adapter/upstream/components/first-time-setup.d.ts +0 -24
  643. package/dist/src/foundation/pi-component-adapter/upstream/components/first-time-setup.js +0 -105
  644. package/dist/src/foundation/pi-component-adapter/upstream/components/markdown-transform.d.ts +0 -2
  645. package/dist/src/foundation/pi-component-adapter/upstream/components/markdown-transform.js +0 -18
  646. package/dist/src/foundation/pi-component-adapter/upstream/components/mermaid.js +0 -77
  647. package/dist/src/foundation/pi-component-adapter/upstream/components/owned-editor.d.ts +0 -18
  648. package/dist/src/foundation/pi-component-adapter/upstream/components/owned-editor.js +0 -55
  649. package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.d.ts +0 -55
  650. package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.js +0 -342
  651. package/dist/src/foundation/pi-component-adapter/upstream/components/session-footer.d.ts +0 -10
  652. package/dist/src/foundation/pi-component-adapter/upstream/components/session-footer.js +0 -120
  653. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector-search.js +0 -159
  654. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector.d.ts +0 -95
  655. package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector.js +0 -889
  656. package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.d.ts +0 -19
  657. package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.js +0 -44
  658. package/dist/src/foundation/pi-component-adapter/upstream/components/status-indicator.d.ts +0 -30
  659. package/dist/src/foundation/pi-component-adapter/upstream/components/status-indicator.js +0 -59
  660. package/dist/src/foundation/pi-component-adapter/upstream/components/tree-selector.d.ts +0 -98
  661. package/dist/src/foundation/pi-component-adapter/upstream/components/tree-selector.js +0 -1272
  662. package/dist/src/foundation/pi-component-adapter/upstream/components/trust-selector.d.ts +0 -33
  663. package/dist/src/foundation/pi-component-adapter/upstream/components/trust-selector.js +0 -76
  664. package/dist/src/foundation/pi-component-adapter/upstream/external-editor.js +0 -39
  665. package/dist/src/foundation/pi-component-adapter/upstream/model-search.d.ts +0 -15
  666. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme-controller.d.ts +0 -25
  667. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme-controller.js +0 -117
  668. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.d.ts +0 -61
  669. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.js +0 -326
  670. package/dist/src/foundation/pi-engine-adapter/adapter.d.ts +0 -164
  671. package/dist/src/foundation/pi-engine-adapter/adapter.js +0 -2367
  672. package/dist/src/foundation/pi-engine-adapter/conformance.d.ts +0 -37
  673. package/dist/src/foundation/pi-engine-adapter/conformance.js +0 -130
  674. package/dist/src/foundation/pi-engine-adapter/index.d.ts +0 -10
  675. package/dist/src/foundation/pi-engine-adapter/index.js +0 -10
  676. package/dist/src/foundation/pi-engine-adapter/model-auth-integration.d.ts +0 -30
  677. package/dist/src/foundation/pi-engine-adapter/model-auth-integration.js +0 -61
  678. package/dist/src/foundation/pi-engine-adapter/package-integration.d.ts +0 -13
  679. package/dist/src/foundation/pi-engine-adapter/package-integration.js +0 -112
  680. package/dist/src/foundation/pi-engine-adapter/pi-settings-metadata.json +0 -374
  681. package/dist/src/foundation/pi-engine-adapter/resource-extension-integration.d.ts +0 -31
  682. package/dist/src/foundation/pi-engine-adapter/resource-extension-integration.js +0 -80
  683. package/dist/src/foundation/pi-engine-adapter/runtime-integration.d.ts +0 -35
  684. package/dist/src/foundation/pi-engine-adapter/runtime-integration.js +0 -67
  685. package/dist/src/foundation/pi-engine-adapter/session-integration.d.ts +0 -43
  686. package/dist/src/foundation/pi-engine-adapter/session-integration.js +0 -97
  687. package/dist/src/foundation/pi-engine-adapter/settings-integration.d.ts +0 -55
  688. package/dist/src/foundation/pi-engine-adapter/settings-integration.js +0 -233
  689. package/dist/src/foundation/pi-engine-adapter/workflow-controllers.d.ts +0 -20
  690. package/dist/src/foundation/pi-engine-adapter/workflow-controllers.js +0 -48
  691. package/dist/src/foundation/pi-engine-adapter/workflows.d.ts +0 -173
  692. package/dist/src/foundation/pi-engine-adapter/workflows.js +0 -60
  693. package/dist/src/foundation/pi-owned-ui-integration/index.d.ts +0 -2
  694. package/dist/src/foundation/pi-owned-ui-integration/index.js +0 -2
  695. package/dist/src/foundation/pi-owned-ui-integration/route-host.d.ts +0 -29
  696. package/dist/src/foundation/pi-owned-ui-integration/session-shell.d.ts +0 -106
  697. package/dist/src/foundation/pi-owned-ui-integration/session-shell.js +0 -1518
  698. package/dist/src/foundation/pi-tui-runtime-adapter/adapter.d.ts +0 -39
  699. package/dist/src/foundation/pi-tui-runtime-adapter/adapter.js +0 -493
  700. package/dist/src/foundation/pi-tui-runtime-adapter/conformance.d.ts +0 -18
  701. package/dist/src/foundation/pi-tui-runtime-adapter/conformance.js +0 -145
  702. package/dist/src/foundation/pi-tui-runtime-adapter/contracts.d.ts +0 -120
  703. package/dist/src/foundation/pi-tui-runtime-adapter/index.d.ts +0 -4
  704. package/dist/src/foundation/pi-tui-runtime-adapter/index.js +0 -4
  705. package/dist/src/foundation/pi-tui-runtime-adapter/presentation-adapter.d.ts +0 -4
  706. package/dist/src/foundation/pi-tui-runtime-adapter/presentation-adapter.js +0 -48
  707. package/dist/src/foundation/presentation-contracts/index.d.ts +0 -96
  708. package/dist/src/foundation/process-containment/index.d.ts +0 -5
  709. package/dist/src/foundation/process-containment/index.js +0 -5
  710. package/dist/src/foundation/process-containment/linux-process-inspector.d.ts +0 -6
  711. package/dist/src/foundation/process-containment/linux-process-inspector.js +0 -26
  712. package/dist/src/foundation/process-containment/native-guardian-containment.d.ts +0 -16
  713. package/dist/src/foundation/process-containment/native-guardian-containment.js +0 -139
  714. package/dist/src/foundation/process-containment/windows-process-inspector.d.ts +0 -17
  715. package/dist/src/foundation/process-containment/windows-process-inspector.js +0 -53
  716. package/dist/src/foundation/protocol/client.d.ts +0 -17
  717. package/dist/src/foundation/protocol/client.js +0 -129
  718. package/dist/src/foundation/protocol/index.d.ts +0 -2
  719. package/dist/src/foundation/protocol/index.js +0 -2
  720. package/dist/src/foundation/protocol/messages.d.ts +0 -89
  721. package/dist/src/foundation/protocol/messages.js +0 -99
  722. package/dist/src/foundation/release/bootstrap.d.ts +0 -29
  723. package/dist/src/foundation/release/bootstrap.js +0 -335
  724. package/dist/src/foundation/release/cohort-state.d.ts +0 -70
  725. package/dist/src/foundation/release/cohort-state.js +0 -202
  726. package/dist/src/foundation/release/index.d.ts +0 -10
  727. package/dist/src/foundation/release/index.js +0 -10
  728. package/dist/src/foundation/release/release-gc.d.ts +0 -5
  729. package/dist/src/foundation/release/release-gc.js +0 -16
  730. package/dist/src/foundation/release/release-store.d.ts +0 -43
  731. package/dist/src/foundation/release/release-store.js +0 -175
  732. package/dist/src/foundation/release/release.d.ts +0 -38
  733. package/dist/src/foundation/release/release.js +0 -204
  734. package/dist/src/foundation/release/update-transaction.d.ts +0 -31
  735. package/dist/src/foundation/release/update-transaction.js +0 -89
  736. package/dist/src/foundation/release/update.d.ts +0 -82
  737. package/dist/src/foundation/release/update.js +0 -529
  738. package/dist/src/foundation/storage/control-store.d.ts +0 -61
  739. package/dist/src/foundation/storage/control-store.js +0 -530
  740. package/dist/src/foundation/storage/index.d.ts +0 -1
  741. package/dist/src/foundation/storage/index.js +0 -1
  742. package/dist/src/foundation/structured-agent-runtime/backpressure.d.ts +0 -46
  743. package/dist/src/foundation/structured-agent-runtime/backpressure.js +0 -118
  744. package/dist/src/foundation/structured-agent-runtime/commands.d.ts +0 -52
  745. package/dist/src/foundation/structured-agent-runtime/commands.js +0 -164
  746. package/dist/src/foundation/structured-agent-runtime/handshake.d.ts +0 -41
  747. package/dist/src/foundation/structured-agent-runtime/handshake.js +0 -151
  748. package/dist/src/foundation/structured-agent-runtime/index.d.ts +0 -5
  749. package/dist/src/foundation/structured-agent-runtime/index.js +0 -5
  750. package/dist/src/foundation/structured-agent-runtime/reconnection.d.ts +0 -37
  751. package/dist/src/foundation/structured-agent-runtime/reconnection.js +0 -129
  752. package/dist/src/foundation/structured-agent-runtime/state.d.ts +0 -56
  753. package/dist/src/foundation/structured-agent-runtime/state.js +0 -118
  754. package/dist/src/foundation/supervision/index.d.ts +0 -3
  755. package/dist/src/foundation/supervision/index.js +0 -3
  756. package/dist/src/foundation/supervision/main.d.ts +0 -1
  757. package/dist/src/foundation/supervision/main.js +0 -41
  758. package/dist/src/foundation/supervision/paths.d.ts +0 -1
  759. package/dist/src/foundation/supervision/paths.js +0 -1
  760. package/dist/src/foundation/supervision/server.d.ts +0 -22
  761. package/dist/src/foundation/supervision/server.js +0 -451
  762. package/dist/src/foundation/ui-apps/contracts.d.ts +0 -42
  763. package/dist/src/foundation/ui-apps/host.d.ts +0 -42
  764. package/dist/src/foundation/ui-apps/host.js +0 -152
  765. package/dist/src/foundation/ui-apps/index.d.ts +0 -3
  766. package/dist/src/foundation/ui-apps/index.js +0 -3
  767. package/dist/src/foundation/ui-apps/registry.d.ts +0 -11
  768. package/dist/src/foundation/ui-apps/registry.js +0 -32
  769. package/dist/src/foundation/ui-components/dialog-panel.js +0 -47
  770. package/dist/src/foundation/ui-components/frame.d.ts +0 -21
  771. package/dist/src/foundation/ui-components/frame.js +0 -54
  772. package/dist/src/foundation/ui-components/index.d.ts +0 -18
  773. package/dist/src/foundation/ui-components/index.js +0 -18
  774. package/dist/src/foundation/ui-components/line-input.d.ts +0 -74
  775. package/dist/src/foundation/ui-components/line-input.js +0 -245
  776. package/dist/src/foundation/ui-components/list-view.d.ts +0 -66
  777. package/dist/src/foundation/ui-components/list-view.js +0 -76
  778. package/dist/src/foundation/ui-components/mouse.d.ts +0 -15
  779. package/dist/src/foundation/ui-components/mouse.js +0 -46
  780. package/dist/src/foundation/ui-components/scrollbar.d.ts +0 -62
  781. package/dist/src/foundation/ui-components/scrollbar.js +0 -102
  782. package/dist/src/foundation/ui-components/shortcuts.d.ts +0 -57
  783. package/dist/src/foundation/ui-components/shortcuts.js +0 -81
  784. package/dist/src/foundation/ui-components/spans.d.ts +0 -7
  785. package/dist/src/foundation/ui-components/spans.js +0 -59
  786. package/dist/src/foundation/ui-components/surface.d.ts +0 -20
  787. package/dist/src/foundation/ui-components/surface.js +0 -38
  788. package/dist/src/foundation/ui-components/text.d.ts +0 -24
  789. package/dist/src/foundation/ui-components/text.js +0 -123
  790. package/dist/src/foundation/workspace-contracts/index.d.ts +0 -2
  791. package/dist/src/foundation/workspace-contracts/index.js +0 -2
  792. package/dist/src/foundation/workspace-contracts/model.d.ts +0 -248
  793. package/dist/src/foundation/workspace-contracts/model.js +0 -2
  794. package/dist/src/foundation/workspace-contracts/validation.d.ts +0 -13
  795. package/dist/src/foundation/workspace-contracts/validation.js +0 -335
  796. package/dist/src/product-identity.d.ts +0 -37
  797. package/dist/src/product-identity.js +0 -150
  798. package/dist/src/product-identity.json +0 -99
  799. package/docs/manual-transparent-checkpoint.md +0 -53
  800. /package/dist/{src/foundation/agent-engine-contracts/domain.js → app/session-shell/paste-helper.d.ts} +0 -0
  801. /package/dist/{src/foundation/agent-engine-contracts/ports.js → app/session-shell/paste-text-worker.d.ts} +0 -0
  802. /package/dist/{src/foundation/lifecycle/commands.js → app/session-shell/paste-types.js} +0 -0
  803. /package/dist/{src/foundation/pi-owned-ui-integration/route-host.js → app/session-shell/response-copy-helper.d.ts} +0 -0
  804. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/capability-ports.js +0 -0
  805. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/domain-validation.d.ts +0 -0
  806. /package/dist/{src/foundation/pi-tui-runtime-adapter/contracts.js → contracts/agent-engine/domain.js} +0 -0
  807. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/model.d.ts +0 -0
  808. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/model.js +0 -0
  809. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/package-ports.js +0 -0
  810. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/ports.d.ts +0 -0
  811. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/serialization.d.ts +0 -0
  812. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/serialization.js +0 -0
  813. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/validation.d.ts +0 -0
  814. /package/dist/{src/foundation/agent-engine-contracts → contracts/agent-engine}/validation.js +0 -0
  815. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/extension-ui.js +0 -0
  816. /package/dist/{src/foundation/owned-ui-contracts → contracts/owned-ui}/model.js +0 -0
  817. /package/dist/{src/foundation/presentation-contracts → contracts/presentation}/index.js +0 -0
  818. /package/dist/{src/features → features}/launch/development-launch.d.ts +0 -0
  819. /package/dist/{src/features → features}/launch/initialize-profile.d.ts +0 -0
  820. /package/dist/{src/features → features}/launch/initialize-profile.js +0 -0
  821. /package/dist/{src/foundation → foundation}/lifecycle/commands.d.ts +0 -0
  822. /package/dist/{src/foundation → foundation}/lifecycle/launch-instance.d.ts +0 -0
  823. /package/dist/{src/foundation → foundation}/lifecycle/launch-instance.js +0 -0
  824. /package/dist/{src/foundation → foundation}/process-containment/artifact.d.ts +0 -0
  825. /package/dist/{src/foundation → foundation}/process-containment/artifact.js +0 -0
  826. /package/dist/{src/foundation → foundation}/process-containment/contracts.d.ts +0 -0
  827. /package/dist/{src/foundation → foundation}/process-containment/contracts.js +0 -0
  828. /package/dist/{src/foundation → foundation}/release/cohort-selection.d.ts +0 -0
  829. /package/dist/{src/foundation → foundation}/release/cohort-selection.js +0 -0
  830. /package/dist/{src/foundation → foundation}/release/concurrency.d.ts +0 -0
  831. /package/dist/{src/foundation → foundation}/release/concurrency.js +0 -0
  832. /package/dist/{src/foundation → foundation}/release/process-cleanup.d.ts +0 -0
  833. /package/dist/{src/foundation → foundation}/release/process-cleanup.js +0 -0
  834. /package/dist/{src/foundation → foundation}/release/stable-release.d.ts +0 -0
  835. /package/dist/{src/foundation → foundation}/release/stable-release.js +0 -0
  836. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/shell-editor-autocomplete.d.ts +0 -0
  837. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/theme.d.ts +0 -0
  838. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/theme.js +0 -0
  839. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/countdown-timer.js +0 -0
  840. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/mermaid.d.ts +0 -0
  841. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/components/session-selector-search.d.ts +0 -0
  842. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/external-editor.d.ts +0 -0
  843. /package/dist/{src/foundation/pi-component-adapter → integrations/pi/components}/upstream/model-search.js +0 -0
  844. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/public-main-entry.d.ts +0 -0
  845. /package/dist/{src/foundation/pi-engine-adapter → integrations/pi/engine}/public-main-entry.js +0 -0
  846. /package/dist/{src/foundation/ui-apps → ui/apps}/contracts.js +0 -0
  847. /package/dist/{src/foundation/ui-components → ui/components}/dialog-panel.d.ts +0 -0
  848. /package/dist/{src/foundation/ui-components → ui/components}/label.d.ts +0 -0
  849. /package/dist/{src/foundation/ui-components → ui/components}/label.js +0 -0
  850. /package/dist/{src/foundation/ui-components → ui/components}/list-block.d.ts +0 -0
  851. /package/dist/{src/foundation/ui-components → ui/components}/list-block.js +0 -0
  852. /package/dist/{src/foundation/ui-components → ui/components}/pane.d.ts +0 -0
  853. /package/dist/{src/foundation/ui-components → ui/components}/pane.js +0 -0
  854. /package/dist/{src/foundation/ui-components → ui/components}/revision.d.ts +0 -0
  855. /package/dist/{src/foundation/ui-components → ui/components}/revision.js +0 -0
  856. /package/dist/{src/foundation/ui-components → ui/components}/status-line.d.ts +0 -0
  857. /package/dist/{src/foundation/ui-components → ui/components}/status-line.js +0 -0
  858. /package/dist/{src/foundation/ui-components → ui/components}/stepper.d.ts +0 -0
  859. /package/dist/{src/foundation/ui-components → ui/components}/stepper.js +0 -0
  860. /package/dist/{src/foundation/ui-components → ui/components}/theme.d.ts +0 -0
  861. /package/dist/{src/foundation/ui-components → ui/components}/theme.js +0 -0
  862. /package/dist/{src/foundation/ui-components → ui/components}/value-menu.d.ts +0 -0
  863. /package/dist/{src/foundation/ui-components → ui/components}/value-menu.js +0 -0
  864. /package/dist/{src/foundation/owned-ui-settings → ui/settings}/resolution.d.ts +0 -0
  865. /package/dist/{src/foundation/owned-ui-settings → ui/settings}/resolution.js +0 -0
@@ -1,2367 +0,0 @@
1
- import { execFile } from "node:child_process";
2
- import { mkdir, rm, writeFile } from "node:fs/promises";
3
- import { tmpdir } from "node:os";
4
- import { dirname, join, resolve } from "node:path";
5
- import { promisify } from "node:util";
6
- import { PRODUCT_IDENTITY } from "../../product-identity.js";
7
- import { copyToClipboard, DefaultPackageManager, getAgentDir, ProjectTrustStore, SessionManager, } from "@earendil-works/pi-coding-agent";
8
- import { OWNED_UI_EXTENSION_CONTRACT_VERSION, OWNED_UI_EXTENSION_RENDER_CALLBACKS, OWNED_UI_EXTENSION_UI_CALLBACKS, OWNED_UI_EXTENSION_UI_PROPERTIES, assertOwnedUiCommand, assertOwnedUiExtensionUiPort, assertOwnedUiSnapshot, } from "../owned-ui-contracts/index.js";
9
- import { PINNED_PI_SETTINGS_CALLBACKS, PINNED_PI_WORKFLOW_COMMAND_NAMES, } from "./workflows.js";
10
- import { createPiRuntimeIntegration } from "./runtime-integration.js";
11
- import { PiSessionCommandIntegration } from "./session-integration.js";
12
- import { PiSettingsIntegration } from "./settings-integration.js";
13
- const execFileAsync = promisify(execFile);
14
- const DEFAULT_SURFACE = {
15
- columns: 100,
16
- rows: 32,
17
- focusedRegion: "editor",
18
- hardwareCursor: false,
19
- };
20
- export class PiEngineAdapter {
21
- #runtimeFactory;
22
- #checkPackageUpdates;
23
- #cwd;
24
- #agentDir;
25
- #sessionId;
26
- #workflowHost;
27
- #workflowInteraction;
28
- #listeners = new Set();
29
- #runtime;
30
- #session;
31
- #unsubscribe;
32
- #sequence = 0;
33
- #viewRevision = 0;
34
- #lifecycle = "starting";
35
- #editor = {
36
- text: "",
37
- queuedSubmissions: [],
38
- selection: null,
39
- cursorOffset: 0,
40
- historyRevision: 0,
41
- submitEnabled: false,
42
- };
43
- #sessionGeneration = 0;
44
- #status = {
45
- title: "Pi",
46
- workingMessage: null,
47
- diagnostics: [],
48
- badges: [],
49
- };
50
- #terminal = DEFAULT_SURFACE;
51
- #activeModel = null;
52
- #thinkingLevel = "medium";
53
- #activeCommandIds = [];
54
- #completedCommands = new Map();
55
- #transcript = [];
56
- #messageBlockIds = new WeakMap();
57
- #messageFallbackIds = new Map();
58
- #toolBlockIds = new Map();
59
- #nextBlockSequence = 0;
60
- #diagnostics = [];
61
- #eventQueue = [];
62
- #eventQueueProcessing;
63
- #droppedEventCount = 0;
64
- #sessionCommands;
65
- #gitBranch = null;
66
- #extensionUi;
67
- #extensionShutdown;
68
- #extensionBound = false;
69
- #disposed = false;
70
- /** Lists the themes installed on this machine, when the caller supplies one. */
71
- #availableThemes;
72
- constructor(options = {}) {
73
- this.#cwd = options.cwd ?? process.cwd();
74
- this.#agentDir = options.agentDir ?? getAgentDir();
75
- this.#sessionId = options.sessionId ?? "owned-session-1";
76
- this.#runtimeFactory = options.createRuntime ?? createDefaultPiRuntime;
77
- this.#checkPackageUpdates = options.checkPackageUpdates
78
- ?? (options.createRuntime
79
- ? async () => []
80
- : settingsManager => checkDefaultPiPackageUpdates(this.#cwd, this.#agentDir, settingsManager));
81
- this.#workflowHost = options.workflowHost ?? defaultWorkflowHost();
82
- this.#availableThemes = options.availableThemes ?? null;
83
- this.#workflowInteraction = { prompt: async () => null, notify() { } };
84
- }
85
- setWorkflowInteractionHost(interaction) {
86
- this.#workflowInteraction = interaction;
87
- }
88
- get sessionId() {
89
- return this.#sessionId;
90
- }
91
- get sessionGeneration() {
92
- return this.#sessionGeneration;
93
- }
94
- get agentDir() {
95
- return this.#agentDir;
96
- }
97
- get disposed() {
98
- return this.#disposed;
99
- }
100
- async start() {
101
- if (this.#runtime)
102
- return this.view();
103
- const runtime = await this.#runtimeFactory({
104
- cwd: this.#cwd,
105
- agentDir: this.#agentDir,
106
- sessionId: this.#sessionId,
107
- }).catch(error => {
108
- this.#lifecycle = "failed";
109
- this.#addDiagnostic("error", "engine-startup", error instanceof Error ? error.message : String(error), false);
110
- throw error;
111
- });
112
- this.#runtime = runtime;
113
- this.#gitBranch = await readGitBranch(this.#cwd);
114
- this.#terminal = {
115
- ...this.#terminal,
116
- hardwareCursor: runtime.services.settingsManager?.getShowHardwareCursor?.() ?? this.#terminal.hardwareCursor,
117
- };
118
- runtime.setRebindSession(async (session) => {
119
- this.#bindSession(session);
120
- this.#emitView();
121
- });
122
- for (const diagnostic of [...runtime.diagnostics, ...runtime.services.diagnostics]) {
123
- this.#addDiagnostic(diagnostic.type === "error" ? "error" : diagnostic.type === "warning" ? "warning" : "info", "engine-startup", diagnostic.message, diagnostic.type !== "error");
124
- }
125
- this.#bindSession(runtime.session);
126
- this.#lifecycle = "ready";
127
- this.#editor = { ...this.#editor, submitEnabled: true };
128
- this.#emitEvent({ type: "session-lifecycle", lifecycle: "ready", reason: null });
129
- this.#emitView();
130
- void this.#announcePackageUpdates(runtime.services.settingsManager);
131
- return this.view();
132
- }
133
- async #announcePackageUpdates(settingsManager) {
134
- if (process.env.PI_OFFLINE)
135
- return;
136
- let updates;
137
- try {
138
- updates = await this.#checkPackageUpdates(settingsManager);
139
- }
140
- catch {
141
- return;
142
- }
143
- if (this.#disposed || updates.length === 0)
144
- return;
145
- const packages = updates.map(name => `- ${name}`).join("\n");
146
- this.#addDiagnostic("info", "package-updates", `Package updates are available. Run pi update --extensions\nPackages:\n${packages}`, true);
147
- this.#emitView();
148
- }
149
- onEvent(listener) {
150
- this.#listeners.add(listener);
151
- listener(this.#event({ type: "session-view", view: this.view() }));
152
- return () => this.#listeners.delete(listener);
153
- }
154
- async flushEvents() {
155
- while (this.#eventQueueProcessing)
156
- await this.#eventQueueProcessing;
157
- }
158
- nonVisualResources() {
159
- const loader = this.#runtime?.services.resourceLoader;
160
- if (!loader)
161
- return [];
162
- const resources = [];
163
- const skills = collectionResult(loader.getSkills(), "skills");
164
- for (const [index, skill] of skills.values.entries()) {
165
- resources.push({
166
- kind: "skill",
167
- id: `skill-${index}-${stringProperty(skill, "name") ?? "unknown"}`,
168
- label: stringProperty(skill, "name") ?? "Unnamed skill",
169
- sourcePath: stringProperty(skill, "filePath") ?? stringProperty(skill, "path") ?? stringProperty(skill, "location") ?? null,
170
- diagnostic: null,
171
- });
172
- }
173
- resources.push(...skills.diagnostics.map((diagnostic, index) => ({
174
- kind: "skill",
175
- id: `skill-diagnostic-${index}`,
176
- label: "Skill diagnostic",
177
- sourcePath: null,
178
- diagnostic,
179
- })));
180
- const prompts = collectionResult(loader.getPrompts(), "prompts");
181
- for (const [index, prompt] of prompts.values.entries()) {
182
- resources.push({
183
- kind: "prompt-template",
184
- id: `prompt-${index}-${stringProperty(prompt, "name") ?? "unknown"}`,
185
- label: stringProperty(prompt, "name") ?? "Prompt template",
186
- sourcePath: stringProperty(prompt, "filePath") ?? stringProperty(prompt, "path") ?? null,
187
- diagnostic: null,
188
- });
189
- }
190
- resources.push(...prompts.diagnostics.map((diagnostic, index) => ({
191
- kind: "prompt-template",
192
- id: `prompt-diagnostic-${index}`,
193
- label: "Prompt diagnostic",
194
- sourcePath: null,
195
- diagnostic,
196
- })));
197
- const agentsFilesResult = loader.getAgentsFiles();
198
- const agentsFiles = unknownArray(isRecord(agentsFilesResult) ? agentsFilesResult.agentsFiles : undefined);
199
- for (const [index, file] of agentsFiles.entries()) {
200
- resources.push({
201
- kind: "agent-context",
202
- id: `agent-context-${index}`,
203
- label: "Agent context",
204
- sourcePath: stringProperty(file, "path") ?? null,
205
- diagnostic: null,
206
- });
207
- }
208
- const systemPrompt = loader.getSystemPromptSource();
209
- if (isRecord(systemPrompt) && typeof systemPrompt.path === "string") {
210
- resources.push({
211
- kind: "system-prompt",
212
- id: "system-prompt",
213
- label: "System prompt",
214
- sourcePath: systemPrompt.path,
215
- diagnostic: null,
216
- });
217
- }
218
- for (const [index, source] of unknownArray(loader.getAppendSystemPromptSources()).entries()) {
219
- resources.push({
220
- kind: "system-prompt",
221
- id: `append-system-prompt-${index}`,
222
- label: "Append system prompt",
223
- sourcePath: stringProperty(source, "path") ?? null,
224
- diagnostic: null,
225
- });
226
- }
227
- if (loader.getThemes !== undefined) {
228
- const themes = collectionResult(loader.getThemes(), "themes");
229
- for (const [index, theme] of themes.values.entries()) {
230
- const sourcePath = stringProperty(theme, "sourcePath");
231
- if (!sourcePath)
232
- continue;
233
- resources.push({
234
- kind: "theme",
235
- id: `theme-${index}-${stringProperty(theme, "name") ?? "unknown"}`,
236
- label: stringProperty(theme, "name") ?? compactResourceLabel(sourcePath),
237
- sourcePath,
238
- diagnostic: null,
239
- });
240
- }
241
- resources.push(...themes.diagnostics.map((diagnostic, index) => ({
242
- kind: "theme",
243
- id: `theme-diagnostic-${index}`,
244
- label: "Theme diagnostic",
245
- sourcePath: null,
246
- diagnostic,
247
- })));
248
- }
249
- return resources;
250
- }
251
- extensionResources() {
252
- const loader = this.#runtime?.services.resourceLoader;
253
- if (loader?.getExtensions === undefined)
254
- return [];
255
- let result;
256
- try {
257
- result = loader.getExtensions();
258
- }
259
- catch (error) {
260
- return [extensionResourceDiagnostic(0, null, `Extension discovery failed: ${error instanceof Error ? error.message : String(error)}`)];
261
- }
262
- if (!isRecord(result))
263
- return [extensionResourceDiagnostic(0, null, "Extension discovery returned a malformed result")];
264
- const resources = [];
265
- if (!Array.isArray(result.extensions)) {
266
- resources.push(extensionResourceDiagnostic(resources.length, null, "Extension discovery returned a malformed extensions collection"));
267
- }
268
- else {
269
- for (const extension of result.extensions) {
270
- if (!isRecord(extension) || typeof extension.path !== "string" || extension.path.length === 0
271
- || typeof extension.resolvedPath !== "string" || extension.resolvedPath.length === 0
272
- || (extension.hidden !== undefined && typeof extension.hidden !== "boolean")) {
273
- resources.push(extensionResourceDiagnostic(resources.length, null, "Extension discovery returned malformed extension metadata"));
274
- continue;
275
- }
276
- resources.push({
277
- kind: "extension",
278
- id: `extension-${resources.length}`,
279
- sourcePath: extension.path,
280
- resolvedPath: extension.resolvedPath,
281
- loaded: true,
282
- hidden: extension.hidden === true,
283
- diagnostic: null,
284
- });
285
- }
286
- }
287
- if (!Array.isArray(result.errors)) {
288
- resources.push(extensionResourceDiagnostic(resources.length, null, "Extension discovery returned a malformed errors collection"));
289
- }
290
- else {
291
- for (const error of result.errors) {
292
- if (!isRecord(error) || typeof error.path !== "string" || typeof error.error !== "string") {
293
- resources.push(extensionResourceDiagnostic(resources.length, null, "Extension discovery returned malformed error metadata"));
294
- continue;
295
- }
296
- resources.push(extensionResourceDiagnostic(resources.length, error.path, error.error));
297
- }
298
- }
299
- return resources;
300
- }
301
- visualExtensionSupport() {
302
- return {
303
- available: this.#extensionBound,
304
- contractComplete: true,
305
- contractVersion: OWNED_UI_EXTENSION_CONTRACT_VERSION,
306
- binding: this.#extensionBound ? "bound" : "unbound",
307
- uiCallbacks: OWNED_UI_EXTENSION_UI_CALLBACKS,
308
- uiProperties: OWNED_UI_EXTENSION_UI_PROPERTIES,
309
- renderCallbacks: OWNED_UI_EXTENSION_RENDER_CALLBACKS,
310
- diagnostic: this.#extensionBound
311
- ? `Pinned public extension UI lifecycle is bound through the ${PRODUCT_IDENTITY.displayName}-owned bridge.`
312
- : `The complete ${PRODUCT_IDENTITY.displayName}-owned extension UI contract is available; the active session has not been bound to the owned UI bridge.`,
313
- };
314
- }
315
- async bindExtensionUi(ui, shutdown) {
316
- assertPiExtensionUiContext(ui);
317
- this.#extensionUi = ui;
318
- this.#extensionShutdown = shutdown;
319
- await this.#bindExtensionUiToSession();
320
- }
321
- async unbindExtensionUi() {
322
- this.#extensionUi = undefined;
323
- this.#extensionShutdown = undefined;
324
- this.#extensionBound = false;
325
- }
326
- workflowAutocompleteCommands() {
327
- const commands = [
328
- {
329
- name: "model",
330
- description: "Select model (opens selector UI)",
331
- argumentHint: "<provider/model>",
332
- argumentOptions: this.#modelOptions(),
333
- source: "builtin",
334
- },
335
- {
336
- name: "login",
337
- description: "Configure provider authentication",
338
- argumentHint: "<provider>",
339
- argumentOptions: this.#loginOptions().map(option => ({ ...option, id: option.id.split(":").at(-1) ?? option.id })),
340
- source: "builtin",
341
- },
342
- ];
343
- const usedNames = new Set(PINNED_PI_WORKFLOW_COMMAND_NAMES);
344
- const loader = this.#runtime?.services.resourceLoader;
345
- if (!loader)
346
- return commands;
347
- const prompts = collectionResult(loader.getPrompts(), "prompts");
348
- for (const prompt of prompts.values) {
349
- const name = stringProperty(prompt, "name");
350
- if (!name || usedNames.has(name))
351
- continue;
352
- const argumentHint = stringProperty(prompt, "argumentHint");
353
- commands.push({
354
- name,
355
- description: stringProperty(prompt, "description") ?? "Prompt template",
356
- ...(argumentHint === undefined ? {} : { argumentHint }),
357
- source: "prompt",
358
- });
359
- usedNames.add(name);
360
- }
361
- const settings = this.#runtime?.services.settingsManager;
362
- const skillsEnabled = settings?.getEnableSkillCommands?.() !== false;
363
- if (skillsEnabled) {
364
- const skills = collectionResult(loader.getSkills(), "skills");
365
- for (const skill of skills.values) {
366
- const resourceName = stringProperty(skill, "name");
367
- const name = resourceName ? `skill:${resourceName}` : undefined;
368
- if (!name || usedNames.has(name))
369
- continue;
370
- commands.push({ name, description: stringProperty(skill, "description") ?? "Skill", source: "skill" });
371
- usedNames.add(name);
372
- }
373
- }
374
- const extensionCommands = this.#session?.extensionRunner?.getRegisteredCommands?.();
375
- if (Array.isArray(extensionCommands)) {
376
- for (const command of extensionCommands.filter(isRecord)) {
377
- const name = stringProperty(command, "name");
378
- if (!name || usedNames.has(name))
379
- continue;
380
- commands.push({ name, description: stringProperty(command, "description") ?? "Extension command", source: "extension" });
381
- usedNames.add(name);
382
- }
383
- }
384
- return commands;
385
- }
386
- async cycleModelWorkflow(direction) {
387
- try {
388
- const session = this.#requireWorkflowSession();
389
- const result = await requireCapability(session.cycleModel, "cycleModel").call(session, direction);
390
- if (!isRecord(result) || !isRecord(result.model)) {
391
- return workflowResult("model", "cancelled", "No other model is available");
392
- }
393
- const model = readModel(result.model);
394
- if (model)
395
- this.#activeModel = model;
396
- if (result.thinkingLevel !== undefined)
397
- this.#thinkingLevel = readThinkingLevel(result.thinkingLevel);
398
- this.#emitView();
399
- return workflowResult("model", "completed", model ? `Selected model ${model.providerId}/${model.modelId}` : "Selected model");
400
- }
401
- catch (error) {
402
- return workflowResult("model", "failed", error instanceof Error ? error.message : String(error));
403
- }
404
- }
405
- /**
406
- * The theme the engine is configured with, in the engine's own grammar: a
407
- * theme's name, or a `light/dark` pair meaning "follow the terminal".
408
- */
409
- configuredTheme() {
410
- return this.#runtime?.services.settingsManager.getThemeSetting();
411
- }
412
- /** Settings port for the live runtime, or null before the runtime is available. */
413
- settingsPort() {
414
- const settings = this.#runtime?.services.settingsManager;
415
- if (!settings)
416
- return null;
417
- const session = this.#runtime?.session;
418
- return new PiSettingsIntegration(settings, {
419
- ...(this.#availableThemes === null ? {} : { themes: this.#availableThemes }),
420
- thinkingLevels: () => {
421
- const levels = session?.getAvailableThinkingLevels?.();
422
- return Array.isArray(levels) ? levels.map(level => String(level)) : [];
423
- },
424
- });
425
- }
426
- pinnedModelSelectorContext() {
427
- const session = this.#requireWorkflowSession();
428
- const runtime = this.#runtime;
429
- if (!runtime)
430
- throw new Error("engine runtime is unavailable");
431
- const scoped = session.scopedModels;
432
- const modelRuntime = runtime.services.modelRuntime;
433
- const selectorRuntime = typeof modelRuntime.getAvailableSnapshot === "function"
434
- ? modelRuntime
435
- : {
436
- getAvailableSnapshot: () => session.model === undefined ? [] : [session.model],
437
- getModel: (providerId, modelId) => modelRuntime.getModel(providerId, modelId),
438
- getError: () => undefined,
439
- refresh: async () => undefined,
440
- };
441
- const settingsManager = runtime.services.settingsManager;
442
- const selectorSettings = typeof settingsManager?.setDefaultModelAndProvider === "function"
443
- ? settingsManager
444
- : { setDefaultModelAndProvider() { } };
445
- return {
446
- currentModel: this.#activeModel === null ? undefined : session.model,
447
- settingsManager: selectorSettings,
448
- modelRuntime: selectorRuntime,
449
- scopedModels: Array.isArray(scoped) ? scoped : [],
450
- };
451
- }
452
- pinnedProjectTrustContext() {
453
- const runtime = this.#runtime;
454
- if (!runtime)
455
- throw new Error("engine runtime is unavailable");
456
- const cwd = resolve(this.#cwd);
457
- const parent = dirname(cwd);
458
- const trustStore = new ProjectTrustStore(this.#agentDir);
459
- const trustOptions = [
460
- { label: "Trust", trusted: true, updates: [{ path: cwd, decision: true }], savedPath: cwd },
461
- ...(parent === cwd ? [] : [{
462
- label: `Trust parent folder (${parent})`,
463
- trusted: true,
464
- updates: [{ path: parent, decision: true }, { path: cwd, decision: null }],
465
- savedPath: parent,
466
- }]),
467
- { label: "Do not trust", trusted: false, updates: [{ path: cwd, decision: false }], savedPath: cwd },
468
- ];
469
- return {
470
- cwd,
471
- savedDecision: trustStore.getEntry(cwd),
472
- projectTrusted: runtime.services.settingsManager?.isProjectTrusted?.() === true,
473
- trustOptions,
474
- };
475
- }
476
- persistProjectTrust(updates) {
477
- new ProjectTrustStore(this.#agentDir).setMany([...updates]);
478
- }
479
- pinnedSessionSelectorContext() {
480
- const session = this.#requireWorkflowSession();
481
- const manager = session.sessionManager;
482
- const cwd = manager?.getCwd?.();
483
- const sessionDir = manager?.getSessionDir?.();
484
- const currentSessionFilePath = manager?.getSessionFile?.();
485
- const usesDefaultSessionDir = manager?.usesDefaultSessionDir?.() === true;
486
- const resolvedCwd = typeof cwd === "string" ? cwd : this.#cwd;
487
- const resolvedSessionDir = typeof sessionDir === "string" ? sessionDir : undefined;
488
- return {
489
- currentSessionFilePath: typeof currentSessionFilePath === "string" ? currentSessionFilePath : undefined,
490
- loadCurrentSessions: onProgress => SessionManager.list(resolvedCwd, resolvedSessionDir, onProgress),
491
- loadAllSessions: onProgress => usesDefaultSessionDir
492
- ? SessionManager.listAll(onProgress)
493
- : resolvedSessionDir === undefined ? SessionManager.listAll(onProgress) : SessionManager.listAll(resolvedSessionDir, onProgress),
494
- renameSession: async (sessionFilePath, nextName) => {
495
- const next = (nextName ?? "").trim();
496
- if (!next)
497
- return;
498
- SessionManager.open(sessionFilePath).appendSessionInfo(next);
499
- },
500
- };
501
- }
502
- pinnedScopedModelsContext() {
503
- const session = this.#requireWorkflowSession();
504
- const runtime = this.#runtime;
505
- if (!runtime)
506
- throw new Error("engine runtime is unavailable");
507
- const models = scopedModelRecords(runtime.services.modelRuntime);
508
- const scoped = session.scopedModels;
509
- if (Array.isArray(scoped) && scoped.length > 0) {
510
- return {
511
- models: models.map(item => item.descriptor),
512
- enabledModelIds: scoped.map(scopedModelReference).filter((id) => id !== undefined),
513
- };
514
- }
515
- const patterns = runtime.services.settingsManager?.getEnabledModels?.();
516
- return {
517
- models: models.map(item => item.descriptor),
518
- enabledModelIds: Array.isArray(patterns)
519
- ? resolveConfiguredModelIds(patterns.filter((value) => typeof value === "string"), models)
520
- : null,
521
- };
522
- }
523
- updateScopedModels(enabledModelIds) {
524
- const session = this.#requireWorkflowSession();
525
- const runtime = this.#runtime;
526
- if (!runtime)
527
- throw new Error("engine runtime is unavailable");
528
- const models = scopedModelRecords(runtime.services.modelRuntime);
529
- const availableIds = new Set(models.map(item => `${item.descriptor.provider}/${item.descriptor.id}`));
530
- const selected = enabledModelIds?.filter(id => availableIds.has(id)) ?? [];
531
- const allAvailableEnabled = enabledModelIds !== null && availableIds.size > 0 && selected.length === availableIds.size;
532
- const scoped = enabledModelIds !== null && selected.length > 0 && !allAvailableEnabled
533
- ? selected.flatMap(id => {
534
- const item = models.find(candidate => `${candidate.descriptor.provider}/${candidate.descriptor.id}` === id);
535
- return item === undefined ? [] : [{ model: item.model }];
536
- })
537
- : [];
538
- requireCapability(session.setScopedModels, "setScopedModels").call(session, scoped);
539
- this.#emitView();
540
- }
541
- persistScopedModels(enabledModelIds) {
542
- const runtime = this.#runtime;
543
- if (!runtime)
544
- throw new Error("engine runtime is unavailable");
545
- const availableCount = scopedModelRecords(runtime.services.modelRuntime).length;
546
- const patterns = enabledModelIds === null || enabledModelIds.length === availableCount
547
- ? undefined
548
- : [...enabledModelIds];
549
- requireCapability(runtime.services.settingsManager?.setEnabledModels, "setEnabledModels").call(runtime.services.settingsManager, patterns === undefined ? undefined : [...patterns]);
550
- }
551
- async refreshScopedModels(signal) {
552
- const runtime = this.#runtime;
553
- if (!runtime)
554
- throw new Error("engine runtime is unavailable");
555
- const result = await runtime.services.modelRuntime.refresh?.({ signal });
556
- const context = this.pinnedScopedModelsContext();
557
- if (isRecord(result) && result.aborted === true) {
558
- return { ...context, status: "Model refresh timed out; showing cached models.", statusKind: "warning" };
559
- }
560
- const errors = isRecord(result) ? result.errors : undefined;
561
- if (errors instanceof Map && errors.size > 0) {
562
- return {
563
- ...context,
564
- status: `Could not refresh ${[...errors.keys()].join(", ")}; showing cached models.`,
565
- statusKind: "warning",
566
- };
567
- }
568
- return { ...context, status: "Model catalogs refreshed.", statusKind: "success" };
569
- }
570
- pinnedLoginOptions(authType) {
571
- return this.#loginOptions(authType);
572
- }
573
- pinnedLoginMethodOptions(providerReference) {
574
- const runtime = this.#runtime;
575
- if (!runtime)
576
- throw new Error("engine runtime is unavailable");
577
- const modelRuntime = runtime.services.modelRuntime;
578
- const normalized = providerReference.trim().toLowerCase();
579
- const providers = modelRuntime.getProviders?.();
580
- const matches = Array.isArray(providers) ? providers.filter(isRecord).filter(candidate => stringProperty(candidate, "id")?.toLowerCase() === normalized
581
- || stringProperty(candidate, "name")?.toLowerCase() === normalized) : [];
582
- const providerId = matches.length === 1 ? stringProperty(matches[0], "id") ?? providerReference : providerReference;
583
- const provider = modelRuntime.getProvider?.(providerId);
584
- const providerName = stringProperty(provider, "name") ?? providerId;
585
- const oauth = dynamicObject(dynamicObject(provider, "auth"), "oauth");
586
- const loginLabel = stringProperty(oauth, "loginLabel") ?? "Sign in with an account";
587
- const options = this.#loginOptions().filter(option => option.id.endsWith(`:${providerId}`)).map(option => ({
588
- id: option.id,
589
- label: option.id.startsWith("api_key:") ? "Sign in with an API key" : loginLabel,
590
- ...(option.description === undefined ? {} : { description: option.description }),
591
- }));
592
- return { title: `Select authentication method for ${providerName}:`, options };
593
- }
594
- pinnedLogoutOptions() {
595
- return this.#logoutOptions();
596
- }
597
- pinnedForkOptions() {
598
- const session = this.#requireWorkflowSession();
599
- const messages = requireCapability(session.getUserMessagesForForking, "getUserMessagesForForking").call(session);
600
- return workflowOptions(messages, "entryId", "text");
601
- }
602
- pinnedTreeSelectorContext() {
603
- const manager = this.#requireWorkflowSession().sessionManager;
604
- const settings = this.#runtime?.services.settingsManager;
605
- const tree = manager?.getTree?.();
606
- const leaf = manager?.getLeafId?.();
607
- const configuredFilter = settings?.getTreeFilterMode?.();
608
- const filterMode = configuredFilter === "no-tools" || configuredFilter === "user-only" || configuredFilter === "labeled-only" || configuredFilter === "all"
609
- ? configuredFilter
610
- : "default";
611
- return {
612
- tree: Array.isArray(tree) ? tree : [],
613
- currentLeafId: typeof leaf === "string" ? leaf : null,
614
- filterMode,
615
- skipSummaryPrompt: settings?.getBranchSummarySkipPrompt?.() === true,
616
- appendLabelChange: (entryId, label) => {
617
- requireCapability(manager?.appendLabelChange, "appendLabelChange").call(manager, entryId, label);
618
- },
619
- };
620
- }
621
- pinnedSettingsSnapshot() {
622
- const session = this.#requireWorkflowSession();
623
- const settings = this.#runtime?.services.settingsManager;
624
- const setting = (getter, fallback) => {
625
- const value = getter?.call(settings);
626
- return value === undefined ? fallback : value;
627
- };
628
- const levels = session.getAvailableThinkingLevels?.();
629
- const themes = collectionResult(this.#runtime?.services.resourceLoader?.getThemes?.(), "themes").values
630
- .map(theme => stringProperty(theme, "name"))
631
- .filter((name) => !!name);
632
- return {
633
- autoCompact: typeof session.autoCompactionEnabled === "boolean"
634
- ? session.autoCompactionEnabled
635
- : setting(settings?.getCompactionEnabled, true),
636
- showImages: setting(settings?.getShowImages, true),
637
- imageWidthCells: setting(settings?.getImageWidthCells, 80),
638
- autoResizeImages: setting(settings?.getImageAutoResize, true),
639
- blockImages: setting(settings?.getBlockImages, false),
640
- enableSkillCommands: setting(settings?.getEnableSkillCommands, true),
641
- steeringMode: session.steeringMode ?? setting(settings?.getSteeringMode, "one-at-a-time"),
642
- followUpMode: session.followUpMode ?? setting(settings?.getFollowUpMode, "one-at-a-time"),
643
- transport: setting(settings?.getTransport, "sse"),
644
- httpIdleTimeoutMs: setting(settings?.getHttpIdleTimeoutMs, 300_000),
645
- thinkingLevel: readThinkingLevel(session.thinkingLevel),
646
- availableThinkingLevels: Array.isArray(levels) ? levels.map(readThinkingLevel) : ["off", "minimal", "low", "medium", "high", "xhigh"],
647
- currentTheme: setting(settings?.getThemeSetting, setting(settings?.getTheme, "dark")),
648
- terminalTheme: "dark",
649
- availableThemes: themes.length > 0 ? themes : ["dark", "light"],
650
- hideThinkingBlock: setting(settings?.getHideThinkingBlock, false),
651
- mermaidRenderingMode: setting(settings?.getMermaidRenderingMode, "off"),
652
- showCacheMissNotices: setting(settings?.getShowCacheMissNotices, false),
653
- collapseChangelog: setting(settings?.getCollapseChangelog, true),
654
- enableInstallTelemetry: setting(settings?.getEnableInstallTelemetry, true),
655
- doubleEscapeAction: setting(settings?.getDoubleEscapeAction, "tree"),
656
- treeFilterMode: setting(settings?.getTreeFilterMode, "default"),
657
- showHardwareCursor: setting(settings?.getShowHardwareCursor, false),
658
- editorPaddingX: setting(settings?.getEditorPaddingX, 0),
659
- outputPad: setting(settings?.getOutputPad, 1),
660
- autocompleteMaxVisible: setting(settings?.getAutocompleteMaxVisible, 5),
661
- quietStartup: setting(settings?.getQuietStartup, false),
662
- defaultProjectTrust: setting(settings?.getDefaultProjectTrust, "ask"),
663
- clearOnShrink: setting(settings?.getClearOnShrink, false),
664
- showTerminalProgress: setting(settings?.getShowTerminalProgress, false),
665
- tuiMode: setting(settings?.getTuiMode, "regular"),
666
- fullscreenExitOutput: setting(settings?.getFullscreenExitOutput, "transcript"),
667
- fullscreenScrollbar: setting(settings?.getFullscreenScrollbar, "auto"),
668
- warnings: setting(settings?.getWarnings, { anthropicExtraUsage: true }),
669
- };
670
- }
671
- pinnedMessageRenderer(customType) {
672
- return this.#requireWorkflowSession().extensionRunner?.getMessageRenderer?.(customType);
673
- }
674
- pinnedToolDefinition(toolName) {
675
- return this.#requireWorkflowSession().extensionRunner?.getToolDefinition?.(toolName);
676
- }
677
- clearQueuedWorkflows() {
678
- const session = this.#requireWorkflowSession();
679
- const result = session.clearQueue?.();
680
- if (!isRecord(result))
681
- return [];
682
- return [...readStringArray(result.steering), ...readStringArray(result.followUp)];
683
- }
684
- abortBashWorkflow() {
685
- this.#requireWorkflowSession().abortBash?.();
686
- }
687
- async executeBashWorkflow(command, excludeFromContext) {
688
- const session = this.#requireWorkflowSession();
689
- const result = await requireCapability(session.executeBash, "executeBash").call(session, command, undefined, { excludeFromContext });
690
- if (!isRecord(result))
691
- throw new Error("Pi bash workflow returned a malformed result");
692
- return {
693
- command,
694
- output: typeof result.output === "string" ? result.output : "",
695
- exitCode: typeof result.exitCode === "number" ? result.exitCode : undefined,
696
- cancelled: result.cancelled === true,
697
- truncated: result.truncated === true,
698
- excludeFromContext,
699
- };
700
- }
701
- applyPinnedSettingValue(callback, value) {
702
- try {
703
- return this.#applyPinnedSetting(callback, value, true);
704
- }
705
- catch (error) {
706
- return workflowResult("settings", "failed", error instanceof Error ? error.message : String(error));
707
- }
708
- }
709
- async executeWorkflow(request) {
710
- try {
711
- return await this.#performWorkflow(request);
712
- }
713
- catch (error) {
714
- const message = error instanceof Error ? error.message : String(error);
715
- const contextualMessage = request.command === "export"
716
- ? `Failed to export session: ${message}`
717
- : request.command === "reload" ? `Reload failed: ${message}` : message;
718
- return workflowResult(request.command, "failed", contextualMessage);
719
- }
720
- }
721
- view() {
722
- return {
723
- contractVersion: 1,
724
- sessionId: this.#sessionId,
725
- revision: this.#viewRevision,
726
- lifecycle: this.#lifecycle,
727
- transcript: this.#transcript.map(block => ({ ...block })),
728
- editor: { ...this.#editor, queuedSubmissions: [...this.#editor.queuedSubmissions] },
729
- status: {
730
- ...this.#status,
731
- diagnostics: [...this.#status.diagnostics],
732
- badges: [...this.#status.badges],
733
- usage: this.#readUsage(),
734
- footer: {
735
- branch: this.#gitBranch,
736
- sessionName: this.#session?.sessionManager?.getSessionName() ?? null,
737
- availableProviderCount: new Set(this.#runtime?.services.modelRuntime.getAvailableSnapshot?.().map(model => model.provider).filter(provider => provider !== undefined) ?? []).size,
738
- extensionStatuses: [],
739
- },
740
- },
741
- terminal: { ...this.#terminal },
742
- activeModel: this.#activeModel === null ? null : { ...this.#activeModel },
743
- thinkingLevel: this.#thinkingLevel,
744
- activeCommandIds: [...this.#activeCommandIds],
745
- dialog: null,
746
- overlay: null,
747
- customizations: [],
748
- diagnostics: this.#diagnostics.map(diagnostic => ({ ...diagnostic })),
749
- };
750
- }
751
- snapshot() {
752
- const snapshot = {
753
- contractVersion: 1,
754
- snapshotId: `snapshot-${this.#viewRevision}`,
755
- sessionId: this.#sessionId,
756
- sequence: this.#sequence,
757
- view: this.view(),
758
- };
759
- assertOwnedUiSnapshot(snapshot);
760
- return snapshot;
761
- }
762
- async execute(command) {
763
- assertOwnedUiCommand(command);
764
- if (command.sessionId !== this.#sessionId) {
765
- return this.#finishCommand(command, "rejected", "command targets a different owned session");
766
- }
767
- if (this.#disposed || !this.#runtime || !this.#session) {
768
- return this.#finishCommand(command, "rejected", "engine adapter is not running");
769
- }
770
- const existing = this.#completedCommands.get(command.correlationId);
771
- if (existing)
772
- return existing;
773
- if (this.#activeCommandIds.includes(command.correlationId)) {
774
- return this.#finishCommand(command, "rejected", "duplicate engine command correlation id");
775
- }
776
- this.#activeCommandIds.push(command.correlationId);
777
- this.#emitEvent({
778
- type: "command-outcome",
779
- correlationId: command.correlationId,
780
- outcome: "accepted",
781
- diagnostic: null,
782
- });
783
- try {
784
- await this.#perform(command);
785
- this.#emitView();
786
- return this.#recordCommand(command, "completed", null);
787
- }
788
- catch (error) {
789
- const diagnostic = error instanceof Error ? error.message : String(error);
790
- this.#addDiagnostic("error", "engine-command", diagnostic, true);
791
- this.#emitView();
792
- return this.#recordCommand(command, "failed", diagnostic);
793
- }
794
- }
795
- async dispose() {
796
- if (this.#disposed)
797
- return;
798
- this.#disposed = true;
799
- this.#extensionBound = false;
800
- this.#extensionUi = undefined;
801
- this.#extensionShutdown = undefined;
802
- this.#lifecycle = "stopping";
803
- this.#emitEvent({ type: "session-lifecycle", lifecycle: "stopping", reason: null });
804
- this.#unsubscribe?.();
805
- this.#unsubscribe = undefined;
806
- await this.#runtime?.dispose();
807
- this.#lifecycle = "stopped";
808
- this.#emitEvent({ type: "session-lifecycle", lifecycle: "stopped", reason: null });
809
- this.#emitView();
810
- await this.flushEvents();
811
- }
812
- async #performWorkflow(request) {
813
- const session = this.#requireWorkflowSession();
814
- const runtime = this.#runtime;
815
- if (!runtime)
816
- throw new Error("engine runtime is unavailable");
817
- const argument = request.argument.trim();
818
- const selected = request.selection?.trim();
819
- const selection = selected && selected.length > 0 ? selected : undefined;
820
- switch (request.command) {
821
- case "settings": {
822
- if (!selection)
823
- return workflowResult(request.command, "failed", "Settings requires the owned settings controller");
824
- return this.#applyPinnedSetting(selection);
825
- }
826
- case "model": {
827
- const reference = selection ?? argument;
828
- if (!reference)
829
- return workflowResult(request.command, "failed", "Model requires the owned model controller");
830
- const [providerId, modelId] = reference.split("/", 2);
831
- if (!providerId || !modelId)
832
- return workflowResult(request.command, "failed", "Model requires provider/model");
833
- const model = runtime.services.modelRuntime.getModel(providerId, modelId);
834
- if (!model)
835
- return workflowResult(request.command, "failed", `Model is unavailable: ${reference}`);
836
- await session.setModel(model);
837
- this.#activeModel = { providerId, modelId, displayName: stringProperty(model, "name") ?? modelId };
838
- this.#emitView();
839
- return workflowResult(request.command, "completed", `Model: ${modelId}`);
840
- }
841
- case "scoped-models": {
842
- if (!selection)
843
- return workflowResult(request.command, "failed", "Scoped models requires the owned scoped-model controller");
844
- const [providerId, modelId] = selection.split("/", 2);
845
- const model = providerId && modelId ? runtime.services.modelRuntime.getModel(providerId, modelId) : undefined;
846
- if (!model)
847
- return workflowResult(request.command, "failed", `Model is unavailable: ${selection}`);
848
- requireCapability(session.setScopedModels, "setScopedModels").call(session, [{ model }]);
849
- return workflowResult(request.command, "completed", `Enabled scoped model ${selection}`);
850
- }
851
- case "export": {
852
- const path = pathArgument(argument);
853
- const file = path?.toLowerCase().endsWith(".jsonl")
854
- ? requireCapability(session.exportToJsonl, "exportToJsonl").call(session, path)
855
- : await requireCapability(session.exportToHtml, "exportToHtml").call(session, path);
856
- return workflowResult(request.command, "completed", `Session exported to: ${String(file)}`);
857
- }
858
- case "import": {
859
- const path = pathArgument(argument);
860
- if (!path)
861
- return workflowResult(request.command, "failed", "Usage: /import <path.jsonl>");
862
- if (request.confirmed === undefined) {
863
- return workflowConfirmation(request.command, `Replace current session with ${path}?`);
864
- }
865
- if (!request.confirmed)
866
- return workflowResult(request.command, "cancelled", "Import cancelled");
867
- const result = await requireCapability(runtime.importFromJsonl, "importFromJsonl").call(runtime, path);
868
- if (isRecord(result) && result.cancelled === true)
869
- return workflowResult(request.command, "cancelled", "Import cancelled");
870
- return workflowResult(request.command, "completed", `Session imported from: ${path}`);
871
- }
872
- case "share": {
873
- const auth = await this.#workflowHost.runCommand("gh", ["auth", "status"]).catch(error => {
874
- throw new Error(`GitHub CLI is unavailable or not logged in: ${error instanceof Error ? error.message : String(error)}`);
875
- });
876
- if (auth.stderr && !auth.stdout)
877
- throw new Error(auth.stderr.trim());
878
- const temporary = join(tmpdir(), `${PRODUCT_IDENTITY.filesystem.temporaryPrefix}pi-session-${process.pid}.html`);
879
- try {
880
- await requireCapability(session.exportToHtml, "exportToHtml").call(session, temporary);
881
- const gist = await this.#workflowHost.runCommand("gh", ["gist", "create", "--public=false", temporary]);
882
- const gistUrl = gist.stdout.trim();
883
- const gistId = gistUrl.split("/").at(-1);
884
- if (!gistId)
885
- throw new Error("Failed to parse gist ID from gh output");
886
- return workflowResult(request.command, "completed", `Share URL: https://pi.gptscript.ai/gist/${gistId}`, gistUrl);
887
- }
888
- finally {
889
- await rm(temporary, { force: true });
890
- }
891
- }
892
- case "copy": {
893
- const text = requireCapability(session.getLastAssistantText, "getLastAssistantText").call(session);
894
- if (typeof text !== "string" || text.length === 0)
895
- return workflowResult(request.command, "failed", "No agent messages to copy yet.");
896
- await this.#workflowHost.copyText(text);
897
- return workflowResult(request.command, "completed", "Copied last agent message to clipboard");
898
- }
899
- case "name": {
900
- const manager = session.sessionManager;
901
- if (!argument) {
902
- const current = manager?.getSessionName();
903
- return typeof current === "string"
904
- ? workflowResult(request.command, "completed", `Session name: ${current}`)
905
- : workflowResult(request.command, "failed", "Usage: /name <name>");
906
- }
907
- requireCapability(session.setSessionName, "setSessionName").call(session, argument);
908
- const normalized = manager?.getSessionName();
909
- const actual = typeof normalized === "string" ? normalized : argument;
910
- return workflowResult(request.command, "completed", `Session name set: ${actual}`, actual === argument ? undefined : `Session name was normalized from ${JSON.stringify(argument)} to ${JSON.stringify(actual)}`);
911
- }
912
- case "session": {
913
- const manager = session.sessionManager;
914
- const stats = requireCapability(session.getSessionStats, "getSessionStats").call(session);
915
- const entries = manager?.getEntries();
916
- return {
917
- ...workflowResult(request.command, "completed", "Session Info"),
918
- presentation: pinnedSessionInfoPresentation(stats, manager?.getSessionName(), Array.isArray(entries) ? entries : [], runtime.services.modelRuntime),
919
- };
920
- }
921
- case "changelog": {
922
- const changelog = await this.#workflowHost.readChangelog();
923
- return workflowResult(request.command, "completed", "What's New", changelog);
924
- }
925
- case "hotkeys":
926
- return workflowResult(request.command, "completed", "Keyboard Shortcuts", pinnedHotkeySummary());
927
- case "fork": {
928
- if (!selection)
929
- return workflowResult(request.command, "failed", "Fork requires the owned user-message controller");
930
- const result = await requireCapability(runtime.fork, "fork").call(runtime, selection, { position: "before" });
931
- if (isRecord(result) && result.cancelled === true)
932
- return workflowResult(request.command, "cancelled", "Fork cancelled");
933
- return workflowResult(request.command, "completed", "Forked to new session");
934
- }
935
- case "clone": {
936
- const manager = session.sessionManager;
937
- const leaf = manager?.getLeafId?.();
938
- if (typeof leaf !== "string")
939
- return workflowResult(request.command, "failed", "No session position is available to clone");
940
- const result = await requireCapability(runtime.fork, "fork").call(runtime, leaf, { position: "at" });
941
- if (isRecord(result) && result.cancelled === true)
942
- return workflowResult(request.command, "cancelled", "Clone cancelled");
943
- return workflowResult(request.command, "completed", "Cloned to new session");
944
- }
945
- case "tree": {
946
- if (!selection)
947
- return workflowResult(request.command, "failed", "Tree navigation requires the owned tree controller");
948
- const navigateTree = requireCapability(session.navigateTree, "navigateTree");
949
- const result = request.treeSummary === undefined
950
- ? await navigateTree.call(session, selection)
951
- : await navigateTree.call(session, selection, {
952
- summarize: request.treeSummary.summarize,
953
- ...(request.treeSummary.customInstructions === undefined ? {} : { customInstructions: request.treeSummary.customInstructions }),
954
- });
955
- if (isRecord(result) && result.aborted === true)
956
- return workflowResult(request.command, "cancelled", "Branch summarization cancelled");
957
- if (isRecord(result) && result.cancelled === true)
958
- return workflowResult(request.command, "cancelled", "Navigation cancelled");
959
- return workflowResult(request.command, "completed", "Navigated to selected point");
960
- }
961
- case "trust": {
962
- if (!selection)
963
- return workflowResult(request.command, "failed", "Trust requires the owned trust controller");
964
- requireCapability(runtime.services.settingsManager?.setProjectTrusted, "setProjectTrusted").call(runtime.services.settingsManager, selection === "trust");
965
- return workflowResult(request.command, "completed", selection === "trust" ? "Project trusted" : "Project trust removed");
966
- }
967
- case "login": {
968
- if (!selection && !argument)
969
- return workflowResult(request.command, "failed", "Login requires the owned authentication controller");
970
- const modelRuntime = runtime.services.modelRuntime;
971
- let loginSelection = selection ?? argument;
972
- if (!selection && argument && !argument.includes(":")) {
973
- const normalized = argument.toLowerCase();
974
- const providers = modelRuntime.getProviders?.();
975
- const providerMatches = Array.isArray(providers) ? providers.filter(isRecord).filter(candidate => stringProperty(candidate, "id")?.toLowerCase() === normalized
976
- || stringProperty(candidate, "name")?.toLowerCase() === normalized) : [];
977
- const providerReference = providerMatches.length === 1 ? stringProperty(providerMatches[0], "id") ?? argument : argument;
978
- const matching = this.#loginOptions().filter(option => option.id.endsWith(`:${providerReference}`));
979
- if (matching.length > 1) {
980
- const provider = modelRuntime.getProvider?.(providerReference);
981
- const providerName = stringProperty(provider, "name") ?? providerReference;
982
- return workflowResult(request.command, "failed", `Authentication method for ${providerName} requires the owned authentication controller`);
983
- }
984
- if (matching[0])
985
- loginSelection = matching[0].id;
986
- }
987
- const [authTypeValue = "oauth", providerId = loginSelection] = loginSelection.includes(":")
988
- ? loginSelection.split(":", 2)
989
- : ["oauth", loginSelection];
990
- const authType = authTypeValue === "api_key" ? "api_key" : "oauth";
991
- const provider = modelRuntime.getProvider?.(providerId);
992
- const providerName = stringProperty(provider, "name") ?? providerId;
993
- this.#workflowInteraction.startLogin?.({ providerId, providerName, authType });
994
- try {
995
- await requireCapability(modelRuntime.login, "login").call(modelRuntime, providerId, authType, {
996
- signal: AbortSignal.timeout(120_000),
997
- prompt: async (prompt) => {
998
- const promptType = stringProperty(prompt, "type");
999
- const options = isRecord(prompt) && Array.isArray(prompt.options)
1000
- ? prompt.options.filter(isRecord).flatMap(option => {
1001
- const id = stringProperty(option, "id");
1002
- const label = stringProperty(option, "label");
1003
- return id && label ? [{ id, label }] : [];
1004
- })
1005
- : [];
1006
- const response = await this.#workflowInteraction.prompt({
1007
- type: promptType === "select"
1008
- ? "select"
1009
- : promptType === "manual_code"
1010
- ? "manual-code"
1011
- : authType === "api_key"
1012
- ? "secret"
1013
- : "text",
1014
- message: stringProperty(prompt, "message") ?? `Authenticate ${providerName}`,
1015
- ...(stringProperty(prompt, "placeholder") === undefined ? {} : { placeholder: stringProperty(prompt, "placeholder") }),
1016
- ...(options.length === 0 ? {} : { options }),
1017
- });
1018
- if (response === null)
1019
- throw new Error("Login cancelled");
1020
- return response;
1021
- },
1022
- notify: (event) => {
1023
- const notification = workflowLoginNotification(event);
1024
- if (notification)
1025
- this.#workflowInteraction.notify(notification);
1026
- },
1027
- });
1028
- }
1029
- catch (error) {
1030
- if (error instanceof Error && error.message === "Login cancelled")
1031
- return workflowResult(request.command, "cancelled", "Login cancelled");
1032
- throw error;
1033
- }
1034
- finally {
1035
- this.#workflowInteraction.finishLogin?.();
1036
- }
1037
- this.#reconcileActiveModelAvailability();
1038
- this.#emitView();
1039
- return workflowResult(request.command, "completed", `Logged in to ${providerName}. Credentials saved to ${join(this.#agentDir, "auth.json")}`);
1040
- }
1041
- case "logout": {
1042
- if (!selection)
1043
- return workflowResult(request.command, "failed", "Logout requires the owned authentication controller");
1044
- const [credentialType = "oauth", providerId = selection] = selection.includes(":") ? selection.split(":", 2) : ["oauth", selection];
1045
- const modelRuntime = runtime.services.modelRuntime;
1046
- await requireCapability(modelRuntime.logout, "logout").call(modelRuntime, providerId, { signal: AbortSignal.timeout(15_000) });
1047
- const provider = modelRuntime.getProvider?.(providerId);
1048
- const providerName = stringProperty(provider, "name") ?? providerId;
1049
- this.#reconcileActiveModelAvailability();
1050
- this.#emitView();
1051
- return workflowResult(request.command, "completed", credentialType === "api_key"
1052
- ? `Removed stored API key for ${providerName}. Environment variables and models.json config are unchanged.`
1053
- : `Logged out of ${providerName}`);
1054
- }
1055
- case "new": {
1056
- const result = await runtime.newSession();
1057
- if (isRecord(result) && result.cancelled === true)
1058
- return workflowResult(request.command, "cancelled", "New session cancelled");
1059
- return workflowResult(request.command, "completed", "✓ New session started");
1060
- }
1061
- case "compact": {
1062
- await session.compact(argument || undefined);
1063
- return workflowResult(request.command, "completed", "Compaction requested");
1064
- }
1065
- case "resume": {
1066
- if (!selection && !argument)
1067
- return workflowResult(request.command, "failed", "Resume requires the owned session controller");
1068
- const sessionPath = selection ?? argument;
1069
- try {
1070
- const result = await runtime.switchSession(sessionPath);
1071
- if (isRecord(result) && result.cancelled === true)
1072
- return workflowResult(request.command, "cancelled", "Resume cancelled");
1073
- return workflowResult(request.command, "completed", "Resumed session");
1074
- }
1075
- catch (error) {
1076
- const issue = isRecord(error) && isRecord(error.issue) ? error.issue : undefined;
1077
- const fallbackCwd = issue === undefined ? undefined : stringProperty(issue, "fallbackCwd");
1078
- if (fallbackCwd === undefined)
1079
- throw error;
1080
- if (request.confirmed === undefined) {
1081
- const sessionCwd = stringProperty(issue, "sessionCwd") ?? "the session working directory";
1082
- return workflowConfirmation(request.command, `cwd from session file does not exist\n${sessionCwd}\n\ncontinue in current cwd\n${fallbackCwd}`);
1083
- }
1084
- if (!request.confirmed)
1085
- return workflowResult(request.command, "cancelled", "Resume cancelled");
1086
- const result = await runtime.switchSession(sessionPath, { cwdOverride: fallbackCwd });
1087
- if (isRecord(result) && result.cancelled === true)
1088
- return workflowResult(request.command, "cancelled", "Resume cancelled");
1089
- return workflowResult(request.command, "completed", "Resumed session in current cwd");
1090
- }
1091
- }
1092
- case "reload": {
1093
- if (session.isStreaming)
1094
- return workflowResult(request.command, "failed", "Wait for the current response to finish before reloading.");
1095
- if (session.isCompacting)
1096
- return workflowResult(request.command, "failed", "Wait for compaction to finish before reloading.");
1097
- await requireCapability(session.reload, "reload").call(session);
1098
- await this.#bindExtensionUiToSession();
1099
- return workflowResult(request.command, "completed", "Reloaded keybindings, extensions, skills, prompts, themes, and context files");
1100
- }
1101
- case "quit": {
1102
- await this.dispose();
1103
- return workflowResult(request.command, "completed", "Shutdown complete");
1104
- }
1105
- case "debug": {
1106
- const debugPath = join(this.#agentDir, "pi-debug.log");
1107
- await mkdir(dirname(debugPath), { recursive: true });
1108
- await writeFile(debugPath, `${JSON.stringify(this.snapshot(), null, 2)}\n`, "utf8");
1109
- return workflowResult(request.command, "completed", "✓ Debug log written", debugPath);
1110
- }
1111
- case "arminsayshi":
1112
- return workflowResult(request.command, "completed", "Armin says hi");
1113
- case "dementedelves":
1114
- return workflowResult(request.command, "completed", "Demented elves announcement");
1115
- }
1116
- }
1117
- #requireWorkflowSession() {
1118
- if (this.#disposed || !this.#runtime || !this.#session)
1119
- throw new Error("engine adapter is not running");
1120
- return this.#session;
1121
- }
1122
- #modelOptions() {
1123
- const runtime = this.#runtime;
1124
- if (!runtime)
1125
- return [];
1126
- const models = runtime.services.modelRuntime.getAvailableSnapshot?.();
1127
- if (!Array.isArray(models)) {
1128
- const active = this.#activeModel;
1129
- return active ? [{ id: `${active.providerId}/${active.modelId}`, label: active.displayName, description: `${active.providerId}/${active.modelId}` }] : [];
1130
- }
1131
- return models.filter(isRecord).flatMap(model => {
1132
- const provider = stringProperty(model, "provider");
1133
- const id = stringProperty(model, "id");
1134
- if (!provider || !id)
1135
- return [];
1136
- return [{ id: `${provider}/${id}`, label: stringProperty(model, "name") ?? id, description: `${provider}/${id}` }];
1137
- });
1138
- }
1139
- #loginOptions(authType) {
1140
- const runtime = this.#runtime;
1141
- const modelRuntime = runtime?.services.modelRuntime;
1142
- if (!modelRuntime)
1143
- return [];
1144
- const providers = modelRuntime.getProviders?.();
1145
- if (!Array.isArray(providers))
1146
- return [];
1147
- return providers.filter(isRecord).flatMap(provider => {
1148
- const id = stringProperty(provider, "id");
1149
- if (!id)
1150
- return [];
1151
- const name = stringProperty(provider, "name") ?? id;
1152
- const auth = isRecord(provider.auth) ? provider.auth : {};
1153
- const authStatus = modelRuntime.getProviderAuthStatus?.(id);
1154
- const source = authStatus?.label ?? authStatus?.source;
1155
- const status = authStatus?.configured === true
1156
- ? {
1157
- type: modelRuntime.isUsingOAuth?.(id) === true ? "oauth" : "api_key",
1158
- ...(source === undefined ? {} : { source }),
1159
- }
1160
- : undefined;
1161
- return [
1162
- ...(authType !== "api_key" && auth.oauth ? [{
1163
- id: `oauth:${id}`,
1164
- providerId: id,
1165
- label: name,
1166
- description: "Account / OAuth",
1167
- authType: "oauth",
1168
- ...(status === undefined ? {} : { status }),
1169
- }] : []),
1170
- ...(authType !== "oauth" && auth.apiKey ? [{
1171
- id: `api_key:${id}`,
1172
- providerId: id,
1173
- label: name,
1174
- description: "API key",
1175
- authType: "api_key",
1176
- ...(status === undefined ? {} : { status }),
1177
- }] : []),
1178
- ];
1179
- }).sort((left, right) => left.label.localeCompare(right.label));
1180
- }
1181
- async #logoutOptions() {
1182
- const runtime = this.#runtime;
1183
- if (!runtime)
1184
- return [];
1185
- const modelRuntime = runtime.services.modelRuntime;
1186
- const credentials = await requireCapability(modelRuntime.listCredentials, "listCredentials").call(modelRuntime, { signal: AbortSignal.timeout(15_000) });
1187
- if (!Array.isArray(credentials))
1188
- return [];
1189
- return credentials.filter(isRecord).flatMap(credential => {
1190
- const providerId = stringProperty(credential, "providerId");
1191
- if (!providerId)
1192
- return [];
1193
- const credentialType = stringProperty(credential, "type") === "api_key" ? "api_key" : "oauth";
1194
- const provider = modelRuntime.getProvider?.(providerId);
1195
- return [{
1196
- id: `${credentialType}:${providerId}`,
1197
- providerId,
1198
- label: stringProperty(provider, "name") ?? providerId,
1199
- description: credentialType,
1200
- authType: credentialType,
1201
- status: { type: credentialType, source: "stored credential" },
1202
- }];
1203
- });
1204
- }
1205
- async #sessionOptions() {
1206
- const session = this.#requireWorkflowSession();
1207
- const manager = session.sessionManager;
1208
- const cwd = manager?.getCwd?.();
1209
- const sessionDir = manager?.getSessionDir?.();
1210
- if (typeof cwd !== "string")
1211
- return [];
1212
- return sessionInfoOptions(await SessionManager.list(cwd, typeof sessionDir === "string" ? sessionDir : undefined));
1213
- }
1214
- #applyPinnedSetting(selection, selectedValue, hasSelectedValue = false) {
1215
- if (!PINNED_PI_SETTINGS_CALLBACKS.includes(selection)) {
1216
- return workflowResult("settings", "failed", `Unknown setting callback: ${selection}`);
1217
- }
1218
- const callback = selection;
1219
- if (callback === "onCancel")
1220
- return workflowResult("settings", "cancelled", "Settings cancelled");
1221
- if (callback === "onThemePreview")
1222
- return workflowResult("settings", "completed", "Theme preview refreshed");
1223
- if (!hasSelectedValue) {
1224
- const snapshot = this.pinnedSettingsSnapshot();
1225
- const currentValues = {
1226
- onAutoCompactChange: snapshot.autoCompact,
1227
- onShowImagesChange: snapshot.showImages,
1228
- onImageWidthCellsChange: snapshot.imageWidthCells,
1229
- onAutoResizeImagesChange: snapshot.autoResizeImages,
1230
- onBlockImagesChange: snapshot.blockImages,
1231
- onEnableSkillCommandsChange: snapshot.enableSkillCommands,
1232
- onSteeringModeChange: snapshot.steeringMode,
1233
- onFollowUpModeChange: snapshot.followUpMode,
1234
- onTransportChange: snapshot.transport,
1235
- onHttpIdleTimeoutMsChange: snapshot.httpIdleTimeoutMs,
1236
- onThinkingLevelChange: snapshot.thinkingLevel,
1237
- onThemeChange: snapshot.currentTheme,
1238
- onHideThinkingBlockChange: snapshot.hideThinkingBlock,
1239
- onMermaidRenderingModeChange: snapshot.mermaidRenderingMode,
1240
- onShowCacheMissNoticesChange: snapshot.showCacheMissNotices,
1241
- onCollapseChangelogChange: snapshot.collapseChangelog,
1242
- onEnableInstallTelemetryChange: snapshot.enableInstallTelemetry,
1243
- onQuietStartupChange: snapshot.quietStartup,
1244
- onDefaultProjectTrustChange: snapshot.defaultProjectTrust,
1245
- onDoubleEscapeActionChange: snapshot.doubleEscapeAction,
1246
- onTreeFilterModeChange: snapshot.treeFilterMode,
1247
- onShowHardwareCursorChange: snapshot.showHardwareCursor,
1248
- onEditorPaddingXChange: snapshot.editorPaddingX,
1249
- onOutputPadChange: snapshot.outputPad,
1250
- onAutocompleteMaxVisibleChange: snapshot.autocompleteMaxVisible,
1251
- onClearOnShrinkChange: snapshot.clearOnShrink,
1252
- onShowTerminalProgressChange: snapshot.showTerminalProgress,
1253
- onTuiModeChange: snapshot.tuiMode,
1254
- onFullscreenExitOutputChange: snapshot.fullscreenExitOutput,
1255
- onFullscreenScrollbarChange: snapshot.fullscreenScrollbar,
1256
- onWarningsChange: snapshot.warnings,
1257
- };
1258
- selectedValue = currentValues[callback];
1259
- hasSelectedValue = true;
1260
- }
1261
- const settings = this.#runtime?.services.settingsManager;
1262
- if (!settings)
1263
- return workflowResult("settings", "failed", "Settings are unavailable");
1264
- const session = this.#requireWorkflowSession();
1265
- if (callback === "onThinkingLevelChange") {
1266
- if (!isThinkingLevel(selectedValue))
1267
- return workflowResult("settings", "failed", "Thinking level is invalid");
1268
- session.setThinkingLevel(selectedValue);
1269
- }
1270
- else {
1271
- const key = settingKeyForCallback(callback);
1272
- if (key === null)
1273
- return workflowResult("settings", "failed", `${settingLabel(callback)} is unavailable in this runtime`);
1274
- const value = agentJsonValue(selectedValue);
1275
- if (callback === "onAutoCompactChange") {
1276
- if (typeof value !== "boolean")
1277
- return workflowResult("settings", "failed", "Auto compact value is invalid");
1278
- session.setAutoCompactionEnabled?.(value);
1279
- }
1280
- new PiSettingsIntegration(settings).writeSettingNow(key, value);
1281
- }
1282
- this.#emitView();
1283
- return workflowResult("settings", "completed", `${settingLabel(callback)}: ${String(selectedValue)}`);
1284
- }
1285
- async #perform(command) {
1286
- const runtime = this.#runtime;
1287
- const session = this.#session;
1288
- if (!runtime || !session)
1289
- throw new Error("engine session is unavailable");
1290
- switch (command.type) {
1291
- case "prompt":
1292
- case "steer":
1293
- case "follow-up":
1294
- case "abort":
1295
- case "retry":
1296
- case "compact": {
1297
- const result = await this.#sessionCommands?.execute(command.type === "prompt" || command.type === "steer" || command.type === "follow-up"
1298
- ? { type: command.type, text: command.text }
1299
- : { type: command.type });
1300
- if (!result || result.outcome === "rejected" || result.outcome === "failed") {
1301
- throw new Error(command.type === "retry" ? "no previous prompt is available to retry" : `Pi session command failed: ${command.type}`);
1302
- }
1303
- return;
1304
- }
1305
- case "set-model": {
1306
- const model = runtime.services.modelRuntime.getModel(command.model.providerId, command.model.modelId);
1307
- if (!model) {
1308
- throw new Error(`model is unavailable: ${command.model.providerId}/${command.model.modelId}`);
1309
- }
1310
- await session.setModel(model);
1311
- this.#activeModel = { ...command.model };
1312
- return;
1313
- }
1314
- case "set-thinking-level":
1315
- session.setThinkingLevel(command.thinkingLevel);
1316
- this.#thinkingLevel = command.thinkingLevel;
1317
- return;
1318
- case "new-session":
1319
- await runtime.newSession();
1320
- return;
1321
- case "resume-session":
1322
- await runtime.switchSession(command.sessionPath);
1323
- return;
1324
- case "resize-surface":
1325
- this.#terminal = { ...command.surface };
1326
- this.#emitEvent({ type: "terminal-surface", surface: this.#terminal });
1327
- return;
1328
- case "shutdown":
1329
- await this.dispose();
1330
- return;
1331
- case "set-setting":
1332
- case "apply-customization":
1333
- case "remove-customization":
1334
- throw new Error("owned UI state commands belong to the owned UI layer, not the Pi engine adapter");
1335
- }
1336
- }
1337
- #bindSession(session) {
1338
- this.#unsubscribe?.();
1339
- this.#sessionGeneration += 1;
1340
- this.#session = session;
1341
- this.#activeCommandIds = [];
1342
- this.#completedCommands.clear();
1343
- this.#sessionCommands = new PiSessionCommandIntegration(session);
1344
- this.#editor = {
1345
- text: "",
1346
- queuedSubmissions: [],
1347
- selection: null,
1348
- cursorOffset: 0,
1349
- historyRevision: this.#editor.historyRevision + 1,
1350
- submitEnabled: true,
1351
- };
1352
- this.#status = { ...this.#status, workingMessage: null, badges: [] };
1353
- this.#activeModel = readModel(session.model);
1354
- this.#reconcileActiveModelAvailability();
1355
- this.#thinkingLevel = readThinkingLevel(session.thinkingLevel);
1356
- this.#rebuildTranscript(session.messages, "finalized");
1357
- this.#unsubscribe = session.subscribe(event => this.#handlePiEvent(event));
1358
- if (this.#extensionUi !== undefined)
1359
- void this.#bindExtensionUiToSession();
1360
- }
1361
- #reconcileActiveModelAvailability() {
1362
- const modelRuntime = this.#runtime?.services.modelRuntime;
1363
- if (!modelRuntime) {
1364
- this.#activeModel = null;
1365
- return;
1366
- }
1367
- const available = modelRuntime.getAvailableSnapshot?.() ?? [];
1368
- const sessionModel = readModel(this.#session?.model);
1369
- const authoritative = this.#activeModel ?? sessionModel;
1370
- if (authoritative === null)
1371
- return;
1372
- const remainsAvailable = available.some(model => stringProperty(model, "provider") === authoritative.providerId
1373
- && stringProperty(model, "id") === authoritative.modelId);
1374
- this.#activeModel = remainsAvailable ? authoritative : null;
1375
- }
1376
- async #bindExtensionUiToSession() {
1377
- const session = this.#session;
1378
- const ui = this.#extensionUi;
1379
- if (session === undefined || ui === undefined || session.bindExtensions === undefined) {
1380
- this.#extensionBound = false;
1381
- return;
1382
- }
1383
- try {
1384
- await session.bindExtensions({
1385
- uiContext: ui,
1386
- mode: "tui",
1387
- shutdownHandler: () => this.#extensionShutdown?.(),
1388
- onError: error => {
1389
- const message = isRecord(error) && typeof error.error === "string"
1390
- ? error.error
1391
- : error instanceof Error ? error.message : String(error);
1392
- this.#addDiagnostic("warning", "extension-ui", message, true);
1393
- this.#emitView();
1394
- },
1395
- });
1396
- this.#extensionBound = true;
1397
- this.#emitView();
1398
- }
1399
- catch (error) {
1400
- this.#extensionBound = false;
1401
- this.#addDiagnostic("error", "extension-ui-bind", error instanceof Error ? error.message : String(error), true);
1402
- this.#emitView();
1403
- }
1404
- }
1405
- #handlePiEvent(event) {
1406
- if (!isRecord(event) || typeof event.type !== "string")
1407
- return;
1408
- switch (event.type) {
1409
- case "agent_start":
1410
- this.#lifecycle = "busy";
1411
- this.#status = { ...this.#status, workingMessage: "Working..." };
1412
- this.#emitEvent({ type: "session-lifecycle", lifecycle: "busy", reason: null });
1413
- this.#emitEvent({ type: "status", status: this.#status });
1414
- return;
1415
- case "message_start":
1416
- this.#upsertMessageBlock(event.message, "live");
1417
- return;
1418
- case "message_update": {
1419
- const block = this.#upsertMessageBlock(event.message, "live");
1420
- if (block && isRecord(event.assistantMessageEvent) && typeof event.assistantMessageEvent.delta === "string") {
1421
- this.#upsertTranscriptBlock({
1422
- ...block,
1423
- text: block.text.endsWith(event.assistantMessageEvent.delta)
1424
- ? block.text
1425
- : `${block.text}${event.assistantMessageEvent.delta}`,
1426
- });
1427
- }
1428
- return;
1429
- }
1430
- case "message_end":
1431
- this.#upsertMessageBlock(event.message, "finalized");
1432
- return;
1433
- case "turn_end":
1434
- this.#upsertMessageBlock(event.message, "finalized");
1435
- if (Array.isArray(event.toolResults)) {
1436
- for (const result of event.toolResults)
1437
- this.#upsertMessageBlock(result, "finalized");
1438
- }
1439
- return;
1440
- case "tool_execution_start":
1441
- case "tool_execution_update":
1442
- case "tool_execution_end":
1443
- this.#upsertToolExecutionBlock(event);
1444
- return;
1445
- case "agent_settled":
1446
- case "agent_end": {
1447
- if (event.type === "agent_end" && event.willRetry === true)
1448
- return;
1449
- const finalMessages = Array.isArray(event.messages) && event.messages.length > 0
1450
- ? event.messages
1451
- : this.#session?.messages ?? [];
1452
- if (finalMessages.length > 0)
1453
- this.#rebuildTranscript(finalMessages, "finalized");
1454
- else
1455
- this.#transcript = this.#transcript.map(block => block.status === "live" ? { ...block, status: "finalized" } : block);
1456
- this.#lifecycle = "ready";
1457
- this.#status = { ...this.#status, workingMessage: null };
1458
- this.#emitEvent({ type: "session-lifecycle", lifecycle: "ready", reason: null });
1459
- this.#emitEvent({ type: "status", status: this.#status });
1460
- this.#emitView();
1461
- return;
1462
- }
1463
- case "queue_update": {
1464
- const steering = readStringArray(event.steering);
1465
- const followUp = readStringArray(event.followUp);
1466
- this.#editor = {
1467
- ...this.#editor,
1468
- queuedSubmissions: [...steering, ...followUp],
1469
- historyRevision: this.#editor.historyRevision + 1,
1470
- };
1471
- this.#emitEvent({ type: "editor-state", editor: this.#editor });
1472
- return;
1473
- }
1474
- case "auto_retry_start":
1475
- this.#lifecycle = "busy";
1476
- this.#status = { ...this.#status, workingMessage: "Retrying…" };
1477
- this.#emitEvent({ type: "status", status: this.#status });
1478
- return;
1479
- case "auto_retry_end":
1480
- case "compaction_end":
1481
- this.#lifecycle = "ready";
1482
- this.#status = { ...this.#status, workingMessage: null };
1483
- this.#emitEvent({ type: "status", status: this.#status });
1484
- return;
1485
- case "compaction_start":
1486
- this.#lifecycle = "busy";
1487
- this.#status = { ...this.#status, workingMessage: "Compacting…" };
1488
- this.#emitEvent({ type: "status", status: this.#status });
1489
- return;
1490
- case "thinking_level_changed":
1491
- this.#thinkingLevel = readThinkingLevel(event.level);
1492
- return;
1493
- default:
1494
- return;
1495
- }
1496
- }
1497
- #readUsage() {
1498
- let input = 0;
1499
- let output = 0;
1500
- let cacheRead = 0;
1501
- let cacheWrite = 0;
1502
- let cost = 0;
1503
- let latestCacheHitRate = null;
1504
- let latestPrompt = null;
1505
- const entries = this.#session?.sessionManager?.getEntries?.()
1506
- ?? (this.#session?.messages ?? []).map(message => ({ type: "message", message }));
1507
- for (const entry of entries) {
1508
- if (!isRecord(entry))
1509
- continue;
1510
- const message = entry.type === "message" && isRecord(entry.message) ? entry.message : undefined;
1511
- const usage = message !== undefined && isRecord(message.usage)
1512
- ? message.usage
1513
- : (entry.type === "branch_summary" || entry.type === "compaction") && isRecord(entry.usage) ? entry.usage : undefined;
1514
- if (usage === undefined)
1515
- continue;
1516
- input += finiteNumber(usage.input);
1517
- output += finiteNumber(usage.output);
1518
- cacheRead += finiteNumber(usage.cacheRead);
1519
- cacheWrite += finiteNumber(usage.cacheWrite);
1520
- cost += isRecord(usage.cost) ? finiteNumber(usage.cost.total) : 0;
1521
- if (message?.role === "assistant") {
1522
- latestPrompt = {
1523
- input: finiteNumber(usage.input),
1524
- cacheRead: finiteNumber(usage.cacheRead),
1525
- cacheWrite: finiteNumber(usage.cacheWrite),
1526
- };
1527
- const promptTokens = latestPrompt.input + latestPrompt.cacheRead + latestPrompt.cacheWrite;
1528
- latestCacheHitRate = promptTokens > 0 ? (latestPrompt.cacheRead / promptTokens) * 100 : null;
1529
- }
1530
- }
1531
- const context = this.#session?.getContextUsage?.();
1532
- const providerId = this.#activeModel?.providerId;
1533
- const usingSubscription = providerId === "kimi-coding"
1534
- || (providerId !== undefined && this.#runtime?.services.modelRuntime.isUsingSubscription?.(providerId) === true);
1535
- return {
1536
- input,
1537
- output,
1538
- cacheRead,
1539
- cacheWrite,
1540
- cost,
1541
- latestCacheHitRate,
1542
- latestPrompt,
1543
- contextAvailable: context !== undefined,
1544
- contextTokens: context?.tokens ?? null,
1545
- contextWindow: context?.contextWindow ?? 0,
1546
- contextPercent: context?.percent ?? null,
1547
- usingSubscription,
1548
- autoCompactEnabled: this.#runtime?.services.settingsManager?.getCompactionEnabled?.() ?? true,
1549
- };
1550
- }
1551
- #rebuildTranscript(messages, status) {
1552
- const blocks = [];
1553
- const blockIndexes = new Map();
1554
- const occurrences = new Map();
1555
- for (const [index, message] of messages.entries()) {
1556
- const key = messageFallbackKey(message, index);
1557
- const occurrence = occurrences.get(key) ?? 0;
1558
- occurrences.set(key, occurrence + 1);
1559
- for (const block of this.#messageBlocks(message, status, index, occurrence)) {
1560
- const existingIndex = blockIndexes.get(block.id);
1561
- if (existingIndex === undefined) {
1562
- blockIndexes.set(block.id, blocks.length);
1563
- blocks.push(block);
1564
- continue;
1565
- }
1566
- const existing = blocks[existingIndex];
1567
- if (existing !== undefined) {
1568
- blocks[existingIndex] = {
1569
- ...block,
1570
- payload: {
1571
- ...(isRecord(existing.payload) ? existing.payload : {}),
1572
- ...(isRecord(block.payload) ? block.payload : {}),
1573
- },
1574
- };
1575
- }
1576
- }
1577
- }
1578
- this.#transcript = blocks;
1579
- }
1580
- #upsertMessageBlock(message, status) {
1581
- const blocks = this.#messageBlocks(message, status, this.#transcript.length);
1582
- const first = blocks[0];
1583
- for (const block of blocks)
1584
- this.#upsertTranscriptBlock(block);
1585
- return first;
1586
- }
1587
- #messageBlocks(message, status, fallbackIndex, occurrence) {
1588
- if (!isRecord(message) || typeof message.role !== "string")
1589
- return [];
1590
- const baseId = this.#messageBlockId(message, fallbackIndex, status, occurrence);
1591
- if (message.role === "user") {
1592
- return [{
1593
- id: baseId,
1594
- kind: "user",
1595
- status,
1596
- revision: this.#nextBlockRevision(baseId),
1597
- title: "User",
1598
- text: textFromContent(message.content),
1599
- payload: { role: "user", imageCount: contentImageCount(message.content) },
1600
- }];
1601
- }
1602
- if (message.role === "bashExecution") {
1603
- return [{
1604
- id: baseId,
1605
- kind: "bash",
1606
- status,
1607
- revision: this.#nextBlockRevision(baseId),
1608
- title: stringValue(message.command) ?? "Bash",
1609
- text: stringValue(message.output) ?? "",
1610
- payload: {
1611
- role: "bashExecution",
1612
- command: stringValue(message.command) ?? "",
1613
- exitCode: typeof message.exitCode === "number" ? message.exitCode : null,
1614
- cancelled: message.cancelled === true,
1615
- truncated: message.truncated === true,
1616
- fullOutputPath: stringValue(message.fullOutputPath) ?? null,
1617
- excludeFromContext: message.excludeFromContext === true,
1618
- },
1619
- }];
1620
- }
1621
- if (message.role === "custom") {
1622
- if (message.display === false)
1623
- return [];
1624
- return [{
1625
- id: baseId,
1626
- kind: "custom",
1627
- status,
1628
- revision: this.#nextBlockRevision(baseId),
1629
- title: stringValue(message.customType) ?? "Custom",
1630
- text: textFromContent(message.content),
1631
- payload: {
1632
- role: "custom",
1633
- customType: stringValue(message.customType) ?? "custom",
1634
- display: true,
1635
- details: message.details,
1636
- timestamp: typeof message.timestamp === "number" ? message.timestamp : 0,
1637
- },
1638
- }];
1639
- }
1640
- if (message.role === "compactionSummary" || message.role === "branchSummary") {
1641
- return [{
1642
- id: baseId,
1643
- kind: "compaction",
1644
- status,
1645
- revision: this.#nextBlockRevision(baseId),
1646
- title: message.role === "branchSummary" ? "Branch summary" : "Compaction summary",
1647
- text: stringValue(message.summary) ?? "",
1648
- payload: {
1649
- role: message.role,
1650
- tokensBefore: typeof message.tokensBefore === "number" ? message.tokensBefore : 0,
1651
- fromId: stringValue(message.fromId) ?? null,
1652
- timestamp: typeof message.timestamp === "number" ? message.timestamp : 0,
1653
- },
1654
- }];
1655
- }
1656
- if (message.role === "toolResult") {
1657
- const toolCallId = stringValue(message.toolCallId);
1658
- const blockId = toolCallId === undefined
1659
- ? baseId
1660
- : this.#toolBlockIds.get(toolCallId) ?? `tool-${toolCallId}`;
1661
- if (toolCallId !== undefined)
1662
- this.#toolBlockIds.set(toolCallId, blockId);
1663
- const existing = this.#transcript.find(block => block.id === blockId);
1664
- const existingPayload = isRecord(existing?.payload) ? existing.payload : undefined;
1665
- return [{
1666
- id: blockId,
1667
- kind: "tool-result",
1668
- status,
1669
- revision: this.#nextBlockRevision(blockId),
1670
- title: stringValue(message.toolName) ?? existing?.title ?? "Tool result",
1671
- text: textFromContent(message.content),
1672
- payload: {
1673
- ...(existingPayload ?? {}),
1674
- role: "toolResult",
1675
- toolCallId: toolCallId ?? null,
1676
- toolName: stringValue(message.toolName) ?? stringValue(existingPayload?.toolName) ?? "unknown",
1677
- argsComplete: true,
1678
- isError: message.isError === true,
1679
- details: jsonSummary(message.details),
1680
- },
1681
- }];
1682
- }
1683
- if (message.role !== "assistant" || !Array.isArray(message.content))
1684
- return [];
1685
- const blocks = [{
1686
- id: baseId,
1687
- kind: "assistant",
1688
- status,
1689
- revision: this.#nextBlockRevision(baseId),
1690
- title: "Assistant",
1691
- text: textFromContent(message.content),
1692
- payload: {
1693
- role: "assistant",
1694
- content: assistantContent(message.content),
1695
- provider: stringValue(message.provider) ?? null,
1696
- model: stringValue(message.model) ?? null,
1697
- api: stringValue(message.api) ?? null,
1698
- usage: sanitizeJson(message.usage),
1699
- stopReason: stringValue(message.stopReason) ?? null,
1700
- errorMessage: stringValue(message.errorMessage) ?? null,
1701
- timestamp: typeof message.timestamp === "number" ? message.timestamp : 0,
1702
- },
1703
- }];
1704
- for (const item of message.content) {
1705
- if (!isRecord(item) || item.type !== "toolCall")
1706
- continue;
1707
- const toolCallId = stringValue(item.id) ?? `${baseId}:${blocks.length}`;
1708
- const blockId = this.#toolBlockIds.get(toolCallId) ?? `tool-${toolCallId}`;
1709
- this.#toolBlockIds.set(toolCallId, blockId);
1710
- blocks.push({
1711
- id: blockId,
1712
- kind: "tool-call",
1713
- status,
1714
- revision: this.#nextBlockRevision(blockId),
1715
- title: stringValue(item.name) ?? "Tool",
1716
- text: jsonSummary(item.arguments).summary,
1717
- payload: {
1718
- toolCallId,
1719
- toolName: stringValue(item.name) ?? "unknown",
1720
- arguments: jsonSummary(item.arguments),
1721
- argsComplete: status === "finalized",
1722
- },
1723
- });
1724
- }
1725
- return blocks;
1726
- }
1727
- #upsertToolExecutionBlock(event) {
1728
- const toolCallId = stringValue(event.toolCallId);
1729
- if (!toolCallId)
1730
- return;
1731
- const blockId = this.#toolBlockIds.get(toolCallId) ?? `tool-${toolCallId}`;
1732
- this.#toolBlockIds.set(toolCallId, blockId);
1733
- const ended = event.type === "tool_execution_end";
1734
- const source = ended ? event.result : event.partialResult;
1735
- this.#upsertTranscriptBlock({
1736
- id: blockId,
1737
- kind: ended ? "tool-result" : "tool-call",
1738
- status: ended ? "finalized" : "live",
1739
- revision: this.#nextBlockRevision(blockId),
1740
- title: stringValue(event.toolName) ?? "Tool",
1741
- text: textFromContent(isRecord(source) ? source.content : source),
1742
- payload: {
1743
- toolCallId,
1744
- toolName: stringValue(event.toolName) ?? "unknown",
1745
- arguments: jsonSummary(event.args),
1746
- result: jsonSummary(source),
1747
- partialResult: event.type === "tool_execution_update",
1748
- argsComplete: ended,
1749
- isError: event.isError === true,
1750
- },
1751
- });
1752
- }
1753
- #upsertTranscriptBlock(block) {
1754
- const index = this.#transcript.findIndex(existing => existing.id === block.id);
1755
- if (index >= 0)
1756
- this.#transcript[index] = block;
1757
- else
1758
- this.#transcript.push(block);
1759
- this.#emitEvent({ type: "transcript-block", block });
1760
- }
1761
- #messageBlockId(message, fallbackIndex, status, occurrence) {
1762
- const existing = this.#messageBlockIds.get(message);
1763
- if (existing)
1764
- return existing;
1765
- const fallback = messageFallbackKey(message, fallbackIndex);
1766
- const cached = this.#messageFallbackIds.get(fallback) ?? [];
1767
- let id;
1768
- if (occurrence !== undefined) {
1769
- id = cached[occurrence];
1770
- if (id === undefined) {
1771
- id = `${fallback}-${occurrence}`;
1772
- cached[occurrence] = id;
1773
- }
1774
- }
1775
- else {
1776
- id = [...cached].reverse().find(candidate => this.#transcript.some(block => block.id === candidate && block.status === "live"));
1777
- if (id === undefined && status === "finalized")
1778
- id = cached.at(-1);
1779
- if (id === undefined) {
1780
- id = `${fallback}-${cached.length}`;
1781
- cached.push(id);
1782
- }
1783
- }
1784
- this.#messageFallbackIds.set(fallback, cached);
1785
- this.#messageBlockIds.set(message, id);
1786
- return id;
1787
- }
1788
- #nextBlockRevision(id) {
1789
- const existing = this.#transcript.find(block => block.id === id);
1790
- if (existing)
1791
- return existing.revision + 1;
1792
- this.#nextBlockSequence += 1;
1793
- return this.#nextBlockSequence;
1794
- }
1795
- #recordCommand(command, outcome, diagnostic) {
1796
- const result = this.#finishCommand(command, outcome, diagnostic);
1797
- this.#completedCommands.set(command.correlationId, result);
1798
- if (this.#completedCommands.size > 256) {
1799
- const oldest = this.#completedCommands.keys().next().value;
1800
- if (oldest)
1801
- this.#completedCommands.delete(oldest);
1802
- }
1803
- return result;
1804
- }
1805
- #finishCommand(command, outcome, diagnostic) {
1806
- this.#activeCommandIds = this.#activeCommandIds.filter(id => id !== command.correlationId);
1807
- this.#emitEvent({
1808
- type: "command-outcome",
1809
- correlationId: command.correlationId,
1810
- outcome,
1811
- diagnostic,
1812
- });
1813
- return { outcome, diagnostic };
1814
- }
1815
- #addDiagnostic(severity, code, message, recoverable) {
1816
- const diagnostic = this.#recordDiagnostic(severity, code, message, recoverable);
1817
- this.#emitEvent({ type: "diagnostic", diagnostic });
1818
- }
1819
- #emitView() {
1820
- this.#viewRevision += 1;
1821
- this.#emitEvent({ type: "session-view", view: this.view() });
1822
- }
1823
- #emitEvent(value) {
1824
- const event = this.#event(value);
1825
- if (event.type !== "session-view")
1826
- this.#viewRevision += 1;
1827
- this.#enqueueEvent(event);
1828
- }
1829
- #enqueueEvent(event) {
1830
- const capacity = 1_024;
1831
- if (this.#eventQueue.length >= capacity) {
1832
- const coalescible = this.#eventQueue.findIndex(queued => queued.type === "session-view"
1833
- || queued.type === "status"
1834
- || queued.type === "editor-state"
1835
- || queued.type === "transcript-block");
1836
- if (coalescible >= 0)
1837
- this.#eventQueue.splice(coalescible, 1);
1838
- else
1839
- this.#eventQueue.shift();
1840
- this.#droppedEventCount += 1;
1841
- if (this.#droppedEventCount === 1 || this.#droppedEventCount % 128 === 0) {
1842
- this.#recordDiagnostic("warning", "event-backpressure", `owned UI coalesced ${this.#droppedEventCount} engine events under backpressure`, true);
1843
- }
1844
- }
1845
- this.#eventQueue.push(event);
1846
- this.#eventQueueProcessing ??= Promise.resolve().then(() => this.#processEventQueue());
1847
- }
1848
- async #processEventQueue() {
1849
- try {
1850
- while (this.#eventQueue.length > 0) {
1851
- const event = this.#eventQueue.shift();
1852
- if (!event)
1853
- continue;
1854
- for (const listener of this.#listeners) {
1855
- try {
1856
- listener(event);
1857
- }
1858
- catch (error) {
1859
- this.#recordDiagnostic("warning", "event-listener", error instanceof Error ? error.message : String(error), true);
1860
- }
1861
- }
1862
- }
1863
- }
1864
- finally {
1865
- this.#eventQueueProcessing = undefined;
1866
- if (this.#eventQueue.length > 0) {
1867
- this.#eventQueueProcessing = Promise.resolve().then(() => this.#processEventQueue());
1868
- }
1869
- }
1870
- }
1871
- #recordDiagnostic(severity, code, message, recoverable) {
1872
- const diagnostic = {
1873
- sequence: this.#diagnostics.length,
1874
- code,
1875
- severity,
1876
- message,
1877
- recoverable,
1878
- };
1879
- this.#diagnostics.push(diagnostic);
1880
- if (this.#diagnostics.length > 100)
1881
- this.#diagnostics.shift();
1882
- this.#status = {
1883
- ...this.#status,
1884
- diagnostics: [...this.#status.diagnostics, message].slice(-8),
1885
- };
1886
- return diagnostic;
1887
- }
1888
- #event(value) {
1889
- this.#sequence += 1;
1890
- return { ...value, sessionId: this.#sessionId, sequence: this.#sequence };
1891
- }
1892
- }
1893
- export async function createPiEngineAdapter(options = {}) {
1894
- const adapter = new PiEngineAdapter(options);
1895
- await adapter.start();
1896
- return adapter;
1897
- }
1898
- async function createDefaultPiRuntime(input) {
1899
- return createPiRuntimeIntegration({ cwd: input.cwd, agentDir: input.agentDir });
1900
- }
1901
- async function checkDefaultPiPackageUpdates(cwd, agentDir, settingsManager) {
1902
- const packageManager = new DefaultPackageManager({ cwd, agentDir, settingsManager });
1903
- const updates = await packageManager.checkForAvailableUpdates();
1904
- return updates.map(update => update.displayName);
1905
- }
1906
- function pinnedSessionInfoPresentation(value, sessionName, entries, modelRuntime) {
1907
- const stats = isRecord(value) ? value : {};
1908
- const tokens = dynamicObject(stats, "tokens");
1909
- return {
1910
- kind: "session-info",
1911
- ...(sessionName === undefined ? {} : { sessionName }),
1912
- stats: {
1913
- ...(stringProperty(stats, "sessionFile") === undefined ? {} : { sessionFile: stringProperty(stats, "sessionFile") }),
1914
- sessionId: stringProperty(stats, "sessionId") ?? "unknown",
1915
- userMessages: finiteNumber(stats.userMessages),
1916
- assistantMessages: finiteNumber(stats.assistantMessages),
1917
- toolCalls: finiteNumber(stats.toolCalls),
1918
- toolResults: finiteNumber(stats.toolResults),
1919
- totalMessages: finiteNumber(stats.totalMessages),
1920
- tokens: {
1921
- input: finiteNumber(tokens.input),
1922
- output: finiteNumber(tokens.output),
1923
- cacheRead: finiteNumber(tokens.cacheRead),
1924
- cacheWrite: finiteNumber(tokens.cacheWrite),
1925
- total: finiteNumber(tokens.total),
1926
- },
1927
- cost: finiteNumber(stats.cost),
1928
- },
1929
- cacheWaste: pinnedCacheWaste(entries, modelRuntime),
1930
- usageBreakdown: pinnedUsageCostBreakdown(entries),
1931
- };
1932
- }
1933
- function pinnedUsageCostBreakdown(entries) {
1934
- const totals = new Map();
1935
- for (const entry of entries) {
1936
- if (!isRecord(entry))
1937
- continue;
1938
- let key;
1939
- let usage;
1940
- const message = dynamicObject(entry, "message");
1941
- if (entry.type === "message" && message.role === "assistant") {
1942
- const provider = stringProperty(message, "provider");
1943
- const model = stringProperty(message, "responseModel") ?? stringProperty(message, "model");
1944
- if (provider && model)
1945
- key = `${provider}/${model}`;
1946
- usage = dynamicObject(message, "usage");
1947
- }
1948
- else if (entry.type === "message" && message.role === "toolResult" && isRecord(message.usage)) {
1949
- key = "Tools/summaries";
1950
- usage = message.usage;
1951
- }
1952
- else if ((entry.type === "branch_summary" || entry.type === "compaction") && isRecord(entry.usage)) {
1953
- key = "Tools/summaries";
1954
- usage = entry.usage;
1955
- }
1956
- if (!key || !usage)
1957
- continue;
1958
- const cost = finiteNumber(dynamicObject(usage, "cost").total);
1959
- const tokens = finiteNumber(usage.input) + finiteNumber(usage.output)
1960
- + finiteNumber(usage.cacheRead) + finiteNumber(usage.cacheWrite);
1961
- const current = totals.get(key) ?? { cost: 0, tokens: 0 };
1962
- current.cost += cost;
1963
- current.tokens += tokens;
1964
- totals.set(key, current);
1965
- }
1966
- return [...totals].map(([key, total]) => ({ key, ...total }))
1967
- .filter(entry => entry.cost > 0 || entry.tokens > 0)
1968
- .sort((a, b) => b.cost - a.cost);
1969
- }
1970
- function pinnedCacheWaste(entries, modelRuntime) {
1971
- let previous;
1972
- const totals = { missedTokens: 0, missedCost: 0, missCount: 0 };
1973
- for (const entry of entries) {
1974
- if (!isRecord(entry))
1975
- continue;
1976
- if (entry.type === "compaction" || entry.type === "branch_summary") {
1977
- previous = undefined;
1978
- continue;
1979
- }
1980
- const message = dynamicObject(entry, "message");
1981
- if (entry.type !== "message" || message.role !== "assistant")
1982
- continue;
1983
- const usage = dynamicObject(message, "usage");
1984
- const input = finiteNumber(usage.input);
1985
- const cacheRead = finiteNumber(usage.cacheRead);
1986
- const cacheWrite = finiteNumber(usage.cacheWrite);
1987
- const promptTokens = input + cacheRead + cacheWrite;
1988
- if (previous && promptTokens > 0 && (cacheRead + cacheWrite > 0 || previous.reportedCache)) {
1989
- const missedTokens = Math.min(previous.promptTokens, promptTokens) - cacheRead;
1990
- if (missedTokens > 1024) {
1991
- const cost = dynamicObject(usage, "cost");
1992
- const paidTokens = input + cacheWrite;
1993
- const paidRate = paidTokens > 0 ? (finiteNumber(cost.input) + finiteNumber(cost.cacheWrite)) / paidTokens : 0;
1994
- const provider = stringProperty(message, "provider") ?? "";
1995
- const modelId = stringProperty(message, "model") ?? "";
1996
- const model = modelRuntime.getModel(provider, modelId);
1997
- const modelCost = dynamicObject(dynamicObject(model, "cost"));
1998
- const readRate = cacheRead > 0
1999
- ? finiteNumber(cost.cacheRead) / cacheRead
2000
- : finiteNumber(modelCost.cacheRead) / 1_000_000;
2001
- totals.missedTokens += missedTokens;
2002
- totals.missedCost += missedTokens * Math.max(0, paidRate - readRate);
2003
- totals.missCount += 1;
2004
- }
2005
- }
2006
- if (promptTokens > 0) {
2007
- const provider = stringProperty(message, "provider") ?? "";
2008
- const model = stringProperty(message, "model") ?? "";
2009
- previous = {
2010
- promptTokens,
2011
- modelKey: `${provider}/${model}`,
2012
- timestamp: finiteNumber(message.timestamp),
2013
- reportedCache: (previous?.reportedCache ?? false) || cacheRead + cacheWrite > 0,
2014
- };
2015
- }
2016
- }
2017
- return totals;
2018
- }
2019
- function defaultWorkflowHost() {
2020
- return {
2021
- copyText: copyToClipboard,
2022
- async runCommand(command, arguments_) {
2023
- const result = await execFileAsync(command, [...arguments_], { encoding: "utf8" });
2024
- return { stdout: result.stdout, stderr: result.stderr };
2025
- },
2026
- readChangelog: async () => "No changelog entries found.",
2027
- };
2028
- }
2029
- function workflowLoginNotification(event) {
2030
- if (!isRecord(event))
2031
- return undefined;
2032
- if (event.type === "auth_url") {
2033
- const url = stringProperty(event, "url");
2034
- if (!url)
2035
- return undefined;
2036
- const instructions = stringProperty(event, "instructions");
2037
- return { type: "auth_url", url, ...(instructions === undefined ? {} : { instructions }) };
2038
- }
2039
- if (event.type === "device_code") {
2040
- const verificationUri = stringProperty(event, "verificationUri");
2041
- const userCode = stringProperty(event, "userCode");
2042
- return verificationUri && userCode ? { type: "device_code", verificationUri, userCode } : undefined;
2043
- }
2044
- const message = stringProperty(event, "message");
2045
- if (!message)
2046
- return undefined;
2047
- if (event.type === "info") {
2048
- const links = Array.isArray(event.links) ? event.links.filter(isRecord).flatMap(link => {
2049
- const url = stringProperty(link, "url");
2050
- if (!url)
2051
- return [];
2052
- const label = stringProperty(link, "label");
2053
- return [{ ...(label === undefined ? {} : { label }), url }];
2054
- }) : [];
2055
- return { type: "info", message, ...(links.length === 0 ? {} : { links }) };
2056
- }
2057
- return { type: event.type === "waiting" ? "waiting" : "progress", message };
2058
- }
2059
- function workflowResult(command, outcome, message, detail) {
2060
- return { command, outcome, message, ...(detail === undefined ? {} : { detail }) };
2061
- }
2062
- function workflowConfirmation(command, message) {
2063
- return {
2064
- command,
2065
- outcome: "requires-confirmation",
2066
- message,
2067
- selectorTitle: "Confirm",
2068
- options: [
2069
- { id: "yes", label: "Yes" },
2070
- { id: "no", label: "No" },
2071
- ],
2072
- };
2073
- }
2074
- function workflowOptions(value, idKey, labelKey) {
2075
- if (!Array.isArray(value))
2076
- return [];
2077
- return value.filter(isRecord).flatMap(item => {
2078
- const id = stringProperty(item, idKey);
2079
- if (!id)
2080
- return [];
2081
- return [{ id, label: stringProperty(item, labelKey) ?? id }];
2082
- });
2083
- }
2084
- function sessionInfoOptions(value) {
2085
- return value.filter(isRecord).flatMap(info => {
2086
- const path = stringProperty(info, "path");
2087
- if (!path)
2088
- return [];
2089
- const modified = info.modified instanceof Date ? info.modified.toISOString() : stringProperty(info, "modified") ?? "unknown time";
2090
- const messageCount = typeof info.messageCount === "number" ? info.messageCount : 0;
2091
- return [{
2092
- id: path,
2093
- label: stringProperty(info, "name") ?? stringProperty(info, "firstMessage") ?? stringProperty(info, "id") ?? path,
2094
- description: `${messageCount} messages · ${modified}`,
2095
- }];
2096
- });
2097
- }
2098
- function assertPiExtensionUiContext(value) {
2099
- assertOwnedUiExtensionUiPort(value);
2100
- }
2101
- function dynamicObject(value, key) {
2102
- const candidate = key === undefined ? value : isRecord(value) ? value[key] : undefined;
2103
- return isRecord(candidate) ? candidate : {};
2104
- }
2105
- function requireCapability(capability, name) {
2106
- if (typeof capability !== "function")
2107
- throw new Error(`Pi workflow capability is unavailable: ${name}`);
2108
- return capability;
2109
- }
2110
- function pathArgument(value) {
2111
- if (!value)
2112
- return undefined;
2113
- const quote = value[0];
2114
- if (quote === '"' || quote === "'") {
2115
- const closing = value.indexOf(quote, 1);
2116
- return closing < 0 ? undefined : value.slice(1, closing);
2117
- }
2118
- return value.split(/\s/, 1)[0] || undefined;
2119
- }
2120
- function settingKeyForCallback(callback) {
2121
- const keys = {
2122
- onAutoCompactChange: "autoCompact", onShowImagesChange: "showImages", onImageWidthCellsChange: "imageWidthCells",
2123
- onAutoResizeImagesChange: "autoResizeImages", onBlockImagesChange: "blockImages", onEnableSkillCommandsChange: "enableSkillCommands",
2124
- onSteeringModeChange: "steeringMode", onFollowUpModeChange: "followUpMode", onTransportChange: "transport",
2125
- onHttpIdleTimeoutMsChange: "httpIdleTimeoutMs", onThemeChange: "theme", onThemePreview: "theme",
2126
- onHideThinkingBlockChange: "hideThinkingBlock", onMermaidRenderingModeChange: "mermaidRenderingMode",
2127
- onShowCacheMissNoticesChange: "showCacheMissNotices", onCollapseChangelogChange: "collapseChangelog",
2128
- onEnableInstallTelemetryChange: "enableInstallTelemetry", onQuietStartupChange: "quietStartup",
2129
- onDefaultProjectTrustChange: "defaultProjectTrust", onDoubleEscapeActionChange: "doubleEscapeAction",
2130
- onTreeFilterModeChange: "treeFilterMode", onShowHardwareCursorChange: "showHardwareCursor",
2131
- onEditorPaddingXChange: "editorPaddingX", onOutputPadChange: "outputPad", onAutocompleteMaxVisibleChange: "autocompleteMaxVisible",
2132
- onClearOnShrinkChange: "clearOnShrink", onShowTerminalProgressChange: "showTerminalProgress", onTuiModeChange: "tuiMode",
2133
- onFullscreenExitOutputChange: "fullscreenExitOutput", onFullscreenScrollbarChange: "fullscreenScrollbar", onWarningsChange: "warnings",
2134
- };
2135
- return keys[callback] ?? null;
2136
- }
2137
- function agentJsonValue(value) {
2138
- if (value === null || typeof value === "string" || typeof value === "boolean" || (typeof value === "number" && Number.isFinite(value)))
2139
- return value;
2140
- if (Array.isArray(value))
2141
- return value.map(agentJsonValue);
2142
- if (isRecord(value))
2143
- return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined).map(([key, item]) => [key, agentJsonValue(item)]));
2144
- throw new TypeError("setting value must be JSON serializable");
2145
- }
2146
- function isThinkingLevel(value) {
2147
- return typeof value === "string" && ["off", "minimal", "low", "medium", "high", "xhigh"].includes(value);
2148
- }
2149
- function settingLabel(callback) {
2150
- return callback
2151
- .replace(/^on/, "")
2152
- .replace(/Change$|Preview$|Cancel$/, "")
2153
- .replace(/([a-z])([A-Z])/g, "$1 $2")
2154
- .replace(/^./, character => character.toUpperCase());
2155
- }
2156
- function pinnedHotkeySummary() {
2157
- return [
2158
- "Enter: send message · Alt+Enter: queue follow-up",
2159
- "Escape: cancel/abort · Ctrl+C: clear/exit · Ctrl+D: exit when empty",
2160
- "Shift+Tab: cycle thinking · Ctrl+P/Shift+Ctrl+P: cycle models · Ctrl+L: select model",
2161
- "Ctrl+O: expand tools · Ctrl+T: toggle thinking · Ctrl+X: copy message",
2162
- "Alt+Up: restore queued messages · /: commands · !/!!: bash",
2163
- ].join("\n");
2164
- }
2165
- function scopedModelRecords(modelRuntime) {
2166
- return modelRuntime.getAvailableSnapshot().map(model => ({
2167
- descriptor: { provider: model.provider, id: model.id, name: model.name ?? model.id },
2168
- model,
2169
- }));
2170
- }
2171
- function scopedModelReference(value) {
2172
- if (!isRecord(value) || !isRecord(value.model))
2173
- return undefined;
2174
- const provider = stringValue(value.model.provider);
2175
- const id = stringValue(value.model.id);
2176
- return provider && id ? `${provider}/${id}` : undefined;
2177
- }
2178
- function resolveConfiguredModelIds(patterns, models) {
2179
- const references = models.map(item => `${item.descriptor.provider}/${item.descriptor.id}`);
2180
- const resolved = [];
2181
- for (const pattern of patterns) {
2182
- const thinkingSuffix = /:(?:off|minimal|low|medium|high|xhigh)$/.exec(pattern);
2183
- const modelPattern = thinkingSuffix === null ? pattern : pattern.slice(0, -thinkingSuffix[0].length);
2184
- const matcher = wildcardMatcher(modelPattern);
2185
- const matches = references.filter((reference, index) => matcher.test(reference) || matcher.test(models[index]?.descriptor.id ?? ""));
2186
- if (matches.length === 0) {
2187
- resolved.push(pattern);
2188
- }
2189
- else {
2190
- for (const match of matches)
2191
- if (!resolved.includes(match))
2192
- resolved.push(match);
2193
- }
2194
- }
2195
- return resolved;
2196
- }
2197
- function wildcardMatcher(pattern) {
2198
- let source = "";
2199
- for (const character of pattern) {
2200
- if (character === "*")
2201
- source += ".*";
2202
- else if (character === "?")
2203
- source += ".";
2204
- else
2205
- source += character.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
2206
- }
2207
- return new RegExp(`^${source}$`, "i");
2208
- }
2209
- function readModel(value) {
2210
- if (!isRecord(value))
2211
- return null;
2212
- const providerId = stringValue(value.provider) ?? stringValue(value.providerId);
2213
- const modelId = stringValue(value.id) ?? stringValue(value.modelId);
2214
- if (!providerId || !modelId)
2215
- return null;
2216
- return {
2217
- providerId,
2218
- modelId,
2219
- displayName: stringValue(value.name) ?? modelId,
2220
- };
2221
- }
2222
- function readThinkingLevel(value) {
2223
- return value === "off" || value === "minimal" || value === "low" || value === "medium"
2224
- || value === "high" || value === "xhigh"
2225
- ? value
2226
- : "medium";
2227
- }
2228
- function readStringArray(value) {
2229
- return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
2230
- }
2231
- function stringValue(value) {
2232
- return typeof value === "string" && value.length > 0 ? value : undefined;
2233
- }
2234
- function messageFallbackKey(message, fallbackIndex) {
2235
- if (!isRecord(message))
2236
- return `message-unknown-${fallbackIndex}`;
2237
- const timestamp = typeof message.timestamp === "number" && Number.isSafeInteger(message.timestamp)
2238
- ? message.timestamp
2239
- : `index-${fallbackIndex}`;
2240
- return `message-${stringValue(message.role) ?? "unknown"}-${timestamp}`;
2241
- }
2242
- function extensionResourceDiagnostic(index, sourcePath, diagnostic) {
2243
- return {
2244
- kind: "extension",
2245
- id: `extension-diagnostic-${index}`,
2246
- sourcePath,
2247
- resolvedPath: null,
2248
- loaded: false,
2249
- hidden: false,
2250
- diagnostic,
2251
- };
2252
- }
2253
- function collectionResult(value, key) {
2254
- if (!isRecord(value))
2255
- return { values: [], diagnostics: [] };
2256
- const diagnostics = unknownArray(value.diagnostics).map(diagnostic => {
2257
- if (typeof diagnostic === "string")
2258
- return diagnostic;
2259
- if (isRecord(diagnostic)) {
2260
- const message = stringProperty(diagnostic, "message") ?? String(diagnostic);
2261
- const path = stringProperty(diagnostic, "path");
2262
- return path ? `${path}: ${message}` : message;
2263
- }
2264
- return String(diagnostic);
2265
- });
2266
- return { values: unknownArray(value[key]), diagnostics };
2267
- }
2268
- function unknownArray(value) {
2269
- return Array.isArray(value) ? value : [];
2270
- }
2271
- function stringProperty(value, key) {
2272
- if (!isRecord(value))
2273
- return undefined;
2274
- const item = value[key];
2275
- return typeof item === "string" && item.length > 0 ? item : undefined;
2276
- }
2277
- function compactResourceLabel(path) {
2278
- const segments = path.replaceAll("\\", "/").split("/").filter(Boolean);
2279
- return segments.at(-1) ?? path;
2280
- }
2281
- function textFromContent(content) {
2282
- if (typeof content === "string")
2283
- return content;
2284
- if (!Array.isArray(content))
2285
- return "";
2286
- return content
2287
- .map(item => isRecord(item) && item.type === "text" ? stringValue(item.text) ?? "" : "")
2288
- .filter(text => text.length > 0)
2289
- .join("\n");
2290
- }
2291
- function assistantContent(content) {
2292
- const result = [];
2293
- for (const item of content) {
2294
- if (!isRecord(item))
2295
- continue;
2296
- if (item.type === "text")
2297
- result.push({ type: "text", text: stringValue(item.text) ?? "" });
2298
- else if (item.type === "thinking") {
2299
- result.push({
2300
- type: "thinking",
2301
- thinking: stringValue(item.thinking) ?? "",
2302
- ...(item.redacted === true ? { redacted: true } : {}),
2303
- });
2304
- }
2305
- else if (item.type === "toolCall") {
2306
- result.push({
2307
- type: "toolCall",
2308
- id: stringValue(item.id) ?? "",
2309
- name: stringValue(item.name) ?? "unknown",
2310
- arguments: sanitizeJson(item.arguments),
2311
- });
2312
- }
2313
- }
2314
- return result;
2315
- }
2316
- function contentImageCount(content) {
2317
- return Array.isArray(content)
2318
- ? content.filter(item => isRecord(item) && item.type === "image").length
2319
- : 0;
2320
- }
2321
- function jsonSummary(value) {
2322
- const json = sanitizeJson(value);
2323
- let summary = "";
2324
- try {
2325
- summary = JSON.stringify(json);
2326
- }
2327
- catch {
2328
- summary = String(value);
2329
- }
2330
- if (summary.length > 512)
2331
- summary = `${summary.slice(0, 509)}...`;
2332
- return { summary, json };
2333
- }
2334
- function sanitizeJson(value, depth = 0) {
2335
- if (typeof value === "bigint")
2336
- return value.toString();
2337
- if (value === null || ["string", "number", "boolean"].includes(typeof value))
2338
- return value;
2339
- if (depth >= 8)
2340
- return "[truncated]";
2341
- if (Array.isArray(value))
2342
- return value.slice(0, 100).map(item => sanitizeJson(item, depth + 1));
2343
- if (isRecord(value)) {
2344
- const output = {};
2345
- for (const [key, item] of Object.entries(value).slice(0, 100)) {
2346
- output[key] = sanitizeJson(item, depth + 1);
2347
- }
2348
- return output;
2349
- }
2350
- return String(value);
2351
- }
2352
- async function readGitBranch(cwd) {
2353
- try {
2354
- const { stdout } = await execFileAsync("git", ["branch", "--show-current"], { cwd, windowsHide: true });
2355
- const branch = stdout.trim();
2356
- return branch.length > 0 ? branch : null;
2357
- }
2358
- catch {
2359
- return null;
2360
- }
2361
- }
2362
- function finiteNumber(value) {
2363
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
2364
- }
2365
- function isRecord(value) {
2366
- return typeof value === "object" && value !== null;
2367
- }