@timurproko/a1 0.1.8-dev.472 → 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 (370) hide show
  1. package/bin/cli.js +4 -5
  2. package/bin/guardian.js +5 -1
  3. package/bin/module-identity.js +53 -98
  4. package/bin/module-resolver.js +138 -0
  5. package/bin/pinned-pi-public.js +25 -6
  6. package/bin/ui.js +7 -2
  7. package/bin/update-recovery.js +76 -7
  8. package/bin/warmup.js +3 -0
  9. package/dist/{integrations/pi/session-ui → app/session-shell}/clipboard-diagnostics.d.ts +1 -1
  10. package/dist/{integrations/pi/session-ui → app/session-shell}/clipboard-image.js +1 -1
  11. package/dist/app/session-shell/helper-pool.d.ts +33 -0
  12. package/dist/app/session-shell/helper-pool.js +98 -0
  13. package/dist/{integrations/pi/session-ui → app/session-shell}/image-preparation-client.d.ts +1 -1
  14. package/dist/{integrations/pi/session-ui → app/session-shell}/image-preparation-client.js +1 -1
  15. package/dist/{integrations/pi/session-ui → app/session-shell}/image-preparation.js +1 -1
  16. package/dist/{integrations/pi/session-ui → app/session-shell}/image-source.js +1 -1
  17. package/dist/{integrations/pi/session-ui → app/session-shell}/image-worker.js +1 -1
  18. package/dist/app/session-shell/index.d.ts +7 -0
  19. package/dist/app/session-shell/index.js +4 -0
  20. package/dist/app/session-shell/paste-executor.d.ts +18 -0
  21. package/dist/{integrations/pi/session-ui → app/session-shell}/paste-executor.js +50 -29
  22. package/dist/{integrations/pi/session-ui → app/session-shell}/paste-helper.js +1 -1
  23. package/dist/app/session-shell/paste-preparation-client.d.ts +31 -0
  24. package/dist/{integrations/pi/session-ui → app/session-shell}/paste-preparation-client.js +19 -8
  25. package/dist/{integrations/pi/session-ui → app/session-shell}/paste-protocol.d.ts +1 -1
  26. package/dist/{integrations/pi/session-ui → app/session-shell}/paste-protocol.js +1 -1
  27. package/dist/app/session-shell/paste-text-preparation.d.ts +6 -0
  28. package/dist/{integrations/pi/session-ui/paste-text-preparation.d.ts → app/session-shell/paste-types.d.ts} +1 -4
  29. package/dist/{integrations/pi/session-ui → app/session-shell}/path-chip-presentation.d.ts +1 -1
  30. package/dist/{integrations/pi/session-ui → app/session-shell}/prompt-chips.d.ts +5 -1
  31. package/dist/{integrations/pi/session-ui → app/session-shell}/prompt-chips.js +6 -2
  32. package/dist/{integrations/pi/session-ui → app/session-shell}/prompt-history-controller.d.ts +2 -2
  33. package/dist/{integrations/pi/session-ui → app/session-shell}/prompt-history-controller.js +2 -2
  34. package/dist/{integrations/pi/session-ui → app/session-shell}/prompt-suggestion-controller.d.ts +1 -1
  35. package/dist/{integrations/pi/session-ui → app/session-shell}/prompt-suggestion-controller.js +2 -2
  36. package/dist/{integrations/pi/session-ui → app/session-shell}/quit-outro.js +1 -1
  37. package/dist/{integrations/pi/session-ui → app/session-shell}/response-copy-coordinator.d.ts +1 -1
  38. package/dist/{integrations/pi/session-ui → app/session-shell}/response-copy-coordinator.js +3 -5
  39. package/dist/{integrations/pi/session-ui → app/session-shell}/response-copy-helper.js +1 -1
  40. package/dist/{integrations/pi/session-ui → app/session-shell}/response-copy-protocol.d.ts +1 -1
  41. package/dist/{integrations/pi/session-ui → app/session-shell}/response-copy-transport.d.ts +10 -2
  42. package/dist/{integrations/pi/session-ui → app/session-shell}/response-copy-transport.js +45 -19
  43. package/dist/{integrations/pi/session-ui → app/session-shell}/session-shell-root.d.ts +75 -53
  44. package/dist/{integrations/pi/session-ui → app/session-shell}/session-shell-root.js +30 -20
  45. package/dist/{integrations/pi/session-ui → app/session-shell}/session-shell.d.ts +9 -8
  46. package/dist/{integrations/pi/session-ui → app/session-shell}/session-shell.js +108 -67
  47. package/dist/{integrations/pi/session-ui → app/session-shell}/session-viewport-controller.d.ts +5 -5
  48. package/dist/{integrations/pi/session-ui → app/session-shell}/session-viewport-controller.js +5 -5
  49. package/dist/{integrations/pi/session-ui → app/session-shell}/system-clipboard.d.ts +1 -1
  50. package/dist/{integrations/pi/session-ui → app/session-shell}/system-clipboard.js +1 -1
  51. package/dist/cli/index.d.ts +8 -5
  52. package/dist/cli/index.js +4 -5
  53. package/dist/composition/index.d.ts +0 -1
  54. package/dist/composition/index.js +0 -1
  55. package/dist/composition/owned-ui.d.ts +2 -2
  56. package/dist/composition/owned-ui.js +35 -36
  57. package/dist/composition/settings-route-host.d.ts +2 -2
  58. package/dist/contracts/agent-engine/domain.d.ts +6 -1
  59. package/dist/contracts/agent-engine/index.d.ts +11 -8
  60. package/dist/contracts/agent-engine/index.js +6 -8
  61. package/dist/contracts/owned-ui/extension-ui.d.ts +8 -0
  62. package/dist/contracts/owned-ui/index.d.ts +12 -8
  63. package/dist/contracts/owned-ui/index.js +8 -8
  64. package/dist/features/launch/index.d.ts +12 -6
  65. package/dist/features/launch/index.js +6 -6
  66. package/dist/features/launch/intent.d.ts +5 -5
  67. package/dist/features/launch/intent.js +2 -2
  68. package/dist/features/owned-ui/index.d.ts +6 -6
  69. package/dist/features/owned-ui/index.js +4 -6
  70. package/dist/features/owned-ui/run.d.ts +2 -2
  71. package/dist/features/owned-ui/settings-app.d.ts +2 -2
  72. package/dist/features/owned-ui/settings-app.js +18 -5
  73. package/dist/features/prompt-history/service.d.ts +1 -1
  74. package/dist/features/prompt-history/service.js +1 -1
  75. package/dist/features/prompt-history/store.js +3 -7
  76. package/dist/features/prompt-suggestions/diagnostics.js +1 -1
  77. package/dist/features/prompt-suggestions/index.d.ts +2 -1
  78. package/dist/features/prompt-suggestions/index.js +1 -1
  79. package/dist/foundation/launch-guardian/index.d.ts +2 -1
  80. package/dist/foundation/launch-guardian/index.js +1 -1
  81. package/dist/foundation/lifecycle/index.d.ts +11 -6
  82. package/dist/foundation/lifecycle/index.js +5 -6
  83. package/dist/foundation/process-containment/index.d.ts +8 -6
  84. package/dist/foundation/process-containment/index.js +6 -6
  85. package/dist/foundation/process-containment/native-guardian-containment.js +3 -3
  86. package/dist/foundation/protocol/index.d.ts +3 -2
  87. package/dist/foundation/protocol/index.js +2 -2
  88. package/dist/foundation/release/bootstrap.d.ts +0 -4
  89. package/dist/foundation/release/bootstrap.js +1 -82
  90. package/dist/foundation/release/dependency-layer.d.ts +2 -5
  91. package/dist/foundation/release/endpoints.d.ts +4 -0
  92. package/dist/foundation/release/endpoints.js +86 -2
  93. package/dist/foundation/release/index.d.ts +30 -16
  94. package/dist/foundation/release/index.js +16 -16
  95. package/dist/foundation/release/release.d.ts +1 -1
  96. package/dist/foundation/release/types.d.ts +11 -0
  97. package/dist/foundation/release/types.js +1 -0
  98. package/dist/foundation/release/update-transaction.d.ts +1 -1
  99. package/dist/foundation/release/update.d.ts +2 -1
  100. package/dist/foundation/release/update.js +3 -18
  101. package/dist/foundation/startup/index.d.ts +4 -2
  102. package/dist/foundation/startup/index.js +2 -2
  103. package/dist/foundation/startup/startup-descriptor.js +2 -2
  104. package/dist/foundation/storage/control-store.d.ts +1 -45
  105. package/dist/foundation/storage/control-store.js +54 -277
  106. package/dist/foundation/storage/index.d.ts +1 -1
  107. package/dist/foundation/storage/index.js +1 -1
  108. package/dist/foundation/supervision/index.d.ts +2 -2
  109. package/dist/foundation/supervision/index.js +2 -2
  110. package/dist/foundation/supervision/server.d.ts +5 -10
  111. package/dist/foundation/supervision/server.js +7 -7
  112. package/dist/foundation/terminal-cleanup/index.d.ts +3 -2
  113. package/dist/foundation/terminal-cleanup/index.js +2 -2
  114. package/dist/integrations/pi/components/editor-interaction.d.ts +1 -1
  115. package/dist/integrations/pi/components/history-editor-loader.d.ts +1 -1
  116. package/dist/integrations/pi/components/index.d.ts +20 -13
  117. package/dist/integrations/pi/components/index.js +12 -13
  118. package/dist/integrations/pi/components/owned-editor-ux.js +5 -8
  119. package/dist/integrations/pi/components/resources/builtin-themes.d.ts +7 -5
  120. package/dist/integrations/pi/components/resources/builtin-themes.js +7 -5
  121. package/dist/integrations/pi/components/shell-editor-autocomplete.js +1 -1
  122. package/dist/integrations/pi/components/shell-extension-ui.js +2 -1
  123. package/dist/integrations/pi/components/shell-footer-status.js +1 -1
  124. package/dist/integrations/pi/components/shell-presenters-info.d.ts +1 -1
  125. package/dist/integrations/pi/components/shell-presenters-info.js +1 -1
  126. package/dist/integrations/pi/components/shell-presenters-transcript.js +1 -1
  127. package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +9 -3
  128. package/dist/integrations/pi/components/shell-selectors-dialogs.js +9 -6
  129. package/dist/integrations/pi/components/shell-shared-facade.d.ts +3 -1
  130. package/dist/integrations/pi/components/shell-shared-facade.js +4 -2
  131. package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +1 -1
  132. package/dist/integrations/pi/components/submitted-prompt-adapter.js +1 -1
  133. package/dist/integrations/pi/components/tool-image-presentation.d.ts +1 -1
  134. package/dist/integrations/pi/components/tool-image-presentation.js +4 -7
  135. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +36 -22
  136. package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +43 -7
  137. package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
  138. package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +6 -3
  139. package/dist/integrations/pi/components/upstream/components/daxnuts.d.ts +8 -1
  140. package/dist/integrations/pi/components/upstream/components/daxnuts.js +7 -3
  141. package/dist/integrations/pi/components/upstream/components/earendil-announcement.d.ts +1 -1
  142. package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +10 -4
  143. package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +7 -4
  144. package/dist/integrations/pi/components/upstream/components/extension-editor.js +7 -4
  145. package/dist/integrations/pi/components/upstream/components/mermaid.js +8 -4
  146. package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +9 -5
  147. package/dist/integrations/pi/components/upstream/components/owned-editor.js +10 -6
  148. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +8 -4
  149. package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +27 -25
  150. package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +1 -1
  151. package/dist/integrations/pi/components/upstream/components/session-footer.js +8 -10
  152. package/dist/integrations/pi/components/upstream/components/session-selector-search.js +6 -4
  153. package/dist/integrations/pi/components/upstream/components/session-selector.d.ts +1 -1
  154. package/dist/integrations/pi/components/upstream/components/session-selector.js +8 -4
  155. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +7 -5
  156. package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +8 -6
  157. package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +9 -4
  158. package/dist/integrations/pi/components/upstream/components/status-indicator.js +15 -5
  159. package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +8 -2
  160. package/dist/integrations/pi/components/upstream/components/tool-execution.js +58 -37
  161. package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +7 -4
  162. package/dist/integrations/pi/components/upstream/components/tree-selector.js +7 -4
  163. package/dist/integrations/pi/components/upstream/components/trust-selector.d.ts +1 -1
  164. package/dist/integrations/pi/components/upstream/components/trust-selector.js +10 -5
  165. package/dist/integrations/pi/components/upstream/external-editor.js +8 -4
  166. package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +13 -4
  167. package/dist/integrations/pi/components/upstream/history/editor-core.js +112 -30
  168. package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +6 -3
  169. package/dist/integrations/pi/components/upstream/history/kill-ring.js +6 -3
  170. package/dist/integrations/pi/components/upstream/history/printable-key.js +7 -4
  171. package/dist/integrations/pi/components/upstream/history/text-helpers.js +6 -3
  172. package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +6 -3
  173. package/dist/integrations/pi/components/upstream/history/undo-stack.js +6 -3
  174. package/dist/integrations/pi/components/upstream/history/word-navigation.js +6 -3
  175. package/dist/integrations/pi/components/upstream/model-search.d.ts +5 -2
  176. package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +8 -0
  177. package/dist/integrations/pi/components/upstream/theme/theme-controller.js +0 -3
  178. package/dist/integrations/pi/components/upstream/theme/theme.d.ts +2 -2
  179. package/dist/integrations/pi/components/upstream/theme/theme.js +17 -6
  180. package/dist/integrations/pi/engine/adapter.d.ts +39 -138
  181. package/dist/integrations/pi/engine/adapter.js +338 -3226
  182. package/dist/integrations/pi/engine/command-dispatch.d.ts +41 -0
  183. package/dist/integrations/pi/engine/command-dispatch.js +125 -0
  184. package/dist/integrations/pi/engine/event-delivery.d.ts +100 -0
  185. package/dist/integrations/pi/engine/event-delivery.js +184 -0
  186. package/dist/integrations/pi/engine/extension-ui-binding.d.ts +35 -0
  187. package/dist/integrations/pi/engine/extension-ui-binding.js +81 -0
  188. package/dist/integrations/pi/engine/index.d.ts +18 -14
  189. package/dist/integrations/pi/engine/index.js +10 -14
  190. package/dist/integrations/pi/engine/message-values.d.ts +29 -0
  191. package/dist/integrations/pi/engine/message-values.js +168 -0
  192. package/dist/integrations/pi/engine/pending-delivery.d.ts +2 -2
  193. package/dist/integrations/pi/engine/pending-delivery.js +2 -4
  194. package/dist/integrations/pi/engine/pi-settings-metadata.json +382 -371
  195. package/dist/integrations/pi/engine/prompt-suggestions.d.ts +30 -0
  196. package/dist/integrations/pi/engine/prompt-suggestions.js +102 -0
  197. package/dist/integrations/pi/engine/provider-authentication.d.ts +34 -0
  198. package/dist/integrations/pi/engine/provider-authentication.js +209 -0
  199. package/dist/integrations/pi/engine/resource-catalog.d.ts +49 -0
  200. package/dist/integrations/pi/engine/resource-catalog.js +289 -0
  201. package/dist/integrations/pi/engine/resources/changelog.json +4 -4
  202. package/dist/integrations/pi/engine/session-events.d.ts +48 -0
  203. package/dist/integrations/pi/engine/session-events.js +223 -0
  204. package/dist/integrations/pi/engine/session-integration.js +2 -4
  205. package/dist/integrations/pi/engine/session-runtime.d.ts +84 -0
  206. package/dist/integrations/pi/engine/session-runtime.js +249 -0
  207. package/dist/integrations/pi/engine/{settings-effects.d.ts → settings-bridge.d.ts} +57 -2
  208. package/dist/integrations/pi/engine/settings-bridge.js +514 -0
  209. package/dist/integrations/pi/engine/settings-metadata.d.ts +31 -0
  210. package/dist/integrations/pi/engine/settings-metadata.js +67 -0
  211. package/dist/integrations/pi/engine/settings-port.d.ts +42 -0
  212. package/dist/integrations/pi/engine/settings-port.js +353 -0
  213. package/dist/integrations/pi/engine/transcript-projection.d.ts +39 -0
  214. package/dist/integrations/pi/engine/transcript-projection.js +405 -0
  215. package/dist/integrations/pi/engine/usage-view.d.ts +4 -0
  216. package/dist/integrations/pi/engine/usage-view.js +56 -0
  217. package/dist/integrations/pi/engine/workflow-contexts.d.ts +59 -0
  218. package/dist/integrations/pi/engine/workflow-contexts.js +316 -0
  219. package/dist/integrations/pi/engine/workflow-runner.d.ts +60 -0
  220. package/dist/integrations/pi/engine/workflow-runner.js +509 -0
  221. package/dist/integrations/pi/engine/workflow-support.d.ts +33 -0
  222. package/dist/integrations/pi/engine/workflow-support.js +352 -0
  223. package/dist/integrations/pi/engine/workflows.d.ts +63 -2
  224. package/dist/integrations/pi/engine/workflows.js +5 -2
  225. package/dist/integrations/pi/startup-public.js +576 -554
  226. package/dist/integrations/pi/startup-public.manifest.json +1730 -984
  227. package/dist/integrations/pi/tui-runtime/adapter.js +10 -13
  228. package/dist/integrations/pi/tui-runtime/contracts.d.ts +11 -1
  229. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +1 -1
  230. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +4 -7
  231. package/dist/integrations/pi/tui-runtime/index.d.ts +8 -6
  232. package/dist/integrations/pi/tui-runtime/index.js +4 -6
  233. package/dist/integrations/pi/tui-runtime/mouse-report-input.js +2 -4
  234. package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +2 -2
  235. package/dist/integrations/pi/tui-runtime/overlay-geometry.js +4 -5
  236. package/dist/integrations/pi/tui-runtime/presentation-adapter.js +1 -1
  237. package/dist/native/darwin-arm64/manifest.json +1 -1
  238. package/dist/native/linux-x64/manifest.json +1 -1
  239. package/dist/native/win32-x64/manifest.json +2 -2
  240. package/dist/native/win32-x64/process-guardian.exe +0 -0
  241. package/dist/runtime-payload-inventory.json +51320 -46509
  242. package/dist/ui/apps/index.d.ts +5 -3
  243. package/dist/ui/apps/index.js +3 -3
  244. package/dist/ui/components/index.d.ts +47 -25
  245. package/dist/ui/components/index.js +25 -25
  246. package/dist/ui/components/prompt-input.js +1 -4
  247. package/dist/ui/settings/declarations.d.ts +119 -0
  248. package/dist/ui/settings/declarations.js +20 -11
  249. package/dist/ui/settings/index.d.ts +10 -6
  250. package/dist/ui/settings/index.js +5 -6
  251. package/dist/ui/settings/manager.d.ts +54 -0
  252. package/dist/ui/settings/{session.js → manager.js} +101 -9
  253. package/dist/ui/settings/sections.d.ts +2 -7
  254. package/docs/architecture/boundaries.md +4 -4
  255. package/docs/architecture/history-editor-provenance.md +1 -1
  256. package/docs/architecture/project-structure.md +6 -6
  257. package/docs/architecture/prompt-suggestions.md +1 -1
  258. package/docs/architecture/terminal-host-proof-gate.md +1 -1
  259. package/docs/architecture/terminal-host-spike-evidence.md +1 -1
  260. package/docs/architecture/toolchain.md +8 -0
  261. package/docs/architecture/ui-reference-provenance.md +4 -4
  262. package/docs/ci-release-runbook.md +7 -1
  263. package/docs/features/modal-content-interaction.md +2 -2
  264. package/docs/local-worktree-cleanup.md +4 -2
  265. package/docs/validation.md +6 -4
  266. package/package.json +7 -11
  267. package/bin/pi-tui.d.ts +0 -6
  268. package/bin/pi-tui.js +0 -28
  269. package/bin/sync-pi-tui-proxy.js +0 -97
  270. package/dist/cli/version.d.ts +0 -2
  271. package/dist/cli/version.js +0 -23
  272. package/dist/composition/agent-engine-bridge.d.ts +0 -3
  273. package/dist/composition/agent-engine-bridge.js +0 -108
  274. package/dist/composition/process.d.ts +0 -16
  275. package/dist/composition/process.js +0 -45
  276. package/dist/contracts/workspace/index.d.ts +0 -2
  277. package/dist/contracts/workspace/index.js +0 -2
  278. package/dist/contracts/workspace/model.d.ts +0 -248
  279. package/dist/contracts/workspace/model.js +0 -2
  280. package/dist/contracts/workspace/validation.d.ts +0 -13
  281. package/dist/contracts/workspace/validation.js +0 -335
  282. package/dist/features/owned-ui/customization.d.ts +0 -40
  283. package/dist/features/owned-ui/customization.js +0 -110
  284. package/dist/features/owned-ui/diagnostics.d.ts +0 -34
  285. package/dist/features/owned-ui/diagnostics.js +0 -95
  286. package/dist/features/workspace/capabilities.d.ts +0 -31
  287. package/dist/features/workspace/capabilities.js +0 -75
  288. package/dist/features/workspace/index.d.ts +0 -6
  289. package/dist/features/workspace/index.js +0 -6
  290. package/dist/features/workspace/presentation.d.ts +0 -30
  291. package/dist/features/workspace/presentation.js +0 -70
  292. package/dist/features/workspace/reconciliation.d.ts +0 -15
  293. package/dist/features/workspace/reconciliation.js +0 -82
  294. package/dist/features/workspace/reducer.d.ts +0 -43
  295. package/dist/features/workspace/reducer.js +0 -214
  296. package/dist/features/workspace/router.d.ts +0 -32
  297. package/dist/features/workspace/router.js +0 -125
  298. package/dist/features/workspace/store.d.ts +0 -18
  299. package/dist/features/workspace/store.js +0 -55
  300. package/dist/foundation/native-host-protocol/codec.d.ts +0 -13
  301. package/dist/foundation/native-host-protocol/codec.js +0 -58
  302. package/dist/foundation/native-host-protocol/evidence.d.ts +0 -67
  303. package/dist/foundation/native-host-protocol/evidence.js +0 -141
  304. package/dist/foundation/native-host-protocol/index.d.ts +0 -4
  305. package/dist/foundation/native-host-protocol/index.js +0 -4
  306. package/dist/foundation/native-host-protocol/messages.d.ts +0 -56
  307. package/dist/foundation/native-host-protocol/messages.js +0 -149
  308. package/dist/foundation/native-host-protocol/proof-gate.d.ts +0 -13
  309. package/dist/foundation/native-host-protocol/proof-gate.js +0 -33
  310. package/dist/foundation/structured-agent-runtime/backpressure.d.ts +0 -47
  311. package/dist/foundation/structured-agent-runtime/backpressure.js +0 -119
  312. package/dist/foundation/structured-agent-runtime/commands.d.ts +0 -53
  313. package/dist/foundation/structured-agent-runtime/commands.js +0 -165
  314. package/dist/foundation/structured-agent-runtime/handshake.d.ts +0 -41
  315. package/dist/foundation/structured-agent-runtime/handshake.js +0 -151
  316. package/dist/foundation/structured-agent-runtime/index.d.ts +0 -5
  317. package/dist/foundation/structured-agent-runtime/index.js +0 -5
  318. package/dist/foundation/structured-agent-runtime/reconnection.d.ts +0 -38
  319. package/dist/foundation/structured-agent-runtime/reconnection.js +0 -130
  320. package/dist/foundation/structured-agent-runtime/state.d.ts +0 -57
  321. package/dist/foundation/structured-agent-runtime/state.js +0 -119
  322. package/dist/integrations/pi/components/upstream/components/custom-entry.d.ts +0 -17
  323. package/dist/integrations/pi/components/upstream/components/custom-entry.js +0 -51
  324. package/dist/integrations/pi/components/upstream/components/first-time-setup.d.ts +0 -24
  325. package/dist/integrations/pi/components/upstream/components/first-time-setup.js +0 -105
  326. package/dist/integrations/pi/components/upstream/components/markdown-transform.d.ts +0 -2
  327. package/dist/integrations/pi/components/upstream/components/markdown-transform.js +0 -18
  328. package/dist/integrations/pi/engine/model-auth-integration.d.ts +0 -31
  329. package/dist/integrations/pi/engine/model-auth-integration.js +0 -62
  330. package/dist/integrations/pi/engine/resource-extension-integration.d.ts +0 -32
  331. package/dist/integrations/pi/engine/resource-extension-integration.js +0 -81
  332. package/dist/integrations/pi/engine/settings-effects.js +0 -249
  333. package/dist/integrations/pi/engine/settings-integration.d.ts +0 -43
  334. package/dist/integrations/pi/engine/settings-integration.js +0 -227
  335. package/dist/integrations/pi/engine/workflow-controllers.d.ts +0 -21
  336. package/dist/integrations/pi/engine/workflow-controllers.js +0 -49
  337. package/dist/integrations/pi/session-ui/index.d.ts +0 -5
  338. package/dist/integrations/pi/session-ui/index.js +0 -5
  339. package/dist/integrations/pi/session-ui/paste-executor.d.ts +0 -10
  340. package/dist/integrations/pi/session-ui/paste-preparation-client.d.ts +0 -16
  341. package/dist/integrations/pi/session-ui/route-host.d.ts +0 -5
  342. package/dist/integrations/pi/tui-runtime/conformance.d.ts +0 -18
  343. package/dist/integrations/pi/tui-runtime/conformance.js +0 -145
  344. package/dist/ui/components/prompt-row.d.ts +0 -14
  345. package/dist/ui/components/prompt-row.js +0 -20
  346. package/dist/ui/settings/session.d.ts +0 -36
  347. package/dist/ui/settings/store.d.ts +0 -29
  348. package/dist/ui/settings/store.js +0 -91
  349. package/dist/{integrations/pi/session-ui → app/session-shell}/clipboard-diagnostics.js +2 -2
  350. package/dist/{integrations/pi/session-ui → app/session-shell}/clipboard-image.d.ts +0 -0
  351. package/dist/{integrations/pi/session-ui → app/session-shell}/editor-hyperlink-budget.d.ts +0 -0
  352. package/dist/{integrations/pi/session-ui → app/session-shell}/editor-hyperlink-budget.js +0 -0
  353. package/dist/{integrations/pi/session-ui → app/session-shell}/image-preparation.d.ts +0 -0
  354. package/dist/{integrations/pi/session-ui → app/session-shell}/image-source.d.ts +0 -0
  355. package/dist/{integrations/pi/session-ui → app/session-shell}/image-worker.d.ts +0 -0
  356. package/dist/{integrations/pi/session-ui → app/session-shell}/paste-helper.d.ts +0 -0
  357. package/dist/{integrations/pi/session-ui → app/session-shell}/paste-text-preparation.js +0 -0
  358. package/dist/{integrations/pi/session-ui → app/session-shell}/paste-text-worker.d.ts +0 -0
  359. package/dist/{integrations/pi/session-ui → app/session-shell}/paste-text-worker.js +0 -0
  360. package/dist/{integrations/pi/session-ui/response-copy-helper.d.ts → app/session-shell/paste-types.js} +0 -0
  361. package/dist/{integrations/pi/session-ui → app/session-shell}/path-chip-presentation.js +0 -0
  362. package/dist/{integrations/pi/session-ui → app/session-shell}/quit-outro-effects.d.ts +0 -0
  363. package/dist/{integrations/pi/session-ui → app/session-shell}/quit-outro-effects.js +0 -0
  364. package/dist/{integrations/pi/session-ui → app/session-shell}/quit-outro.d.ts +0 -0
  365. package/dist/{integrations/pi/session-ui/route-host.js → app/session-shell/response-copy-helper.d.ts} +0 -0
  366. package/dist/{integrations/pi/session-ui → app/session-shell}/response-copy-protocol.js +0 -0
  367. package/dist/{integrations/pi/session-ui → app/session-shell}/stream-presentation-coalescer.d.ts +0 -0
  368. package/dist/{integrations/pi/session-ui → app/session-shell}/stream-presentation-coalescer.js +3 -3
  369. /package/dist/{integrations/pi/session-ui → app/session-shell}/text-paste.d.ts +0 -0
  370. /package/dist/{integrations/pi/session-ui → app/session-shell}/text-paste.js +0 -0
@@ -9,19 +9,46 @@ import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
10
10
 
11
11
  const SCHEMA = "a1-update-recovery-v1";
12
+
13
+ /**
14
+ * @typedef {object} Capsule
15
+ * @property {string} transactionId
16
+ * @property {string} packageName
17
+ * @property {string} targetVersion
18
+ * @property {string} packageRoot
19
+ * @property {string} globalRoot
20
+ * @property {string} launcherRoot
21
+ * @property {string[]} launchers
22
+ * @property {string} priorReleaseId
23
+ * @property {string} priorReleaseRoot
24
+ * @property {string} priorContentDigest
25
+ * @property {string} releaseManifestName
26
+ * @property {string} recoveryEntry
27
+ * @property {string} recoveryEntryDigest
28
+ * @property {string} nodeExecutable
29
+ * @property {string} npmCli
30
+ * @property {string[]} npmArguments
31
+ * @property {string} resultPath
32
+ * @property {string} cancellationPath
33
+ * @property {string} ownerPath
34
+ */
35
+
12
36
  const [, , mode, manifestPath, separator, ...forwarded] = process.argv;
13
37
 
14
38
  if ((mode !== "--worker" && mode !== "--launch") || !manifestPath || (mode === "--launch" && separator !== "--")) {
15
39
  throw new Error("invalid A1 update recovery invocation");
16
40
  }
17
41
 
18
- const capsule = await readCapsule(manifestPath);
42
+ /** @type {string} */
43
+ const capsuleManifestPath = manifestPath;
44
+ const capsule = await readCapsule(capsuleManifestPath);
19
45
  if (mode === "--worker") {
20
46
  await runWorker(capsule);
21
47
  } else {
22
48
  process.exitCode = await runRecoveredCommand(capsule, forwarded);
23
49
  }
24
50
 
51
+ /** @param {Capsule} value */
25
52
  async function runWorker(value) {
26
53
  await rm(value.resultPath, { force: true });
27
54
  await writeJson(value.ownerPath, {
@@ -46,12 +73,15 @@ async function runWorker(value) {
46
73
  windowsHide: true,
47
74
  stdio: ["ignore", "pipe", "pipe"],
48
75
  });
76
+ /** @type {Buffer[]} */
49
77
  const stdout = [];
78
+ /** @type {Buffer[]} */
50
79
  const stderr = [];
51
80
  child.stdout?.on("data", chunk => stdout.push(Buffer.from(chunk)));
52
81
  child.stderr?.on("data", chunk => stderr.push(Buffer.from(chunk)));
53
82
  let cancelled = false;
54
83
  let forced = false;
84
+ /** @type {ReturnType<typeof setTimeout> | null} */
55
85
  let forceTimer = null;
56
86
  const cancellationPoll = setInterval(async () => {
57
87
  if (cancelled || !await exists(value.cancellationPath)) return;
@@ -104,20 +134,25 @@ async function runWorker(value) {
104
134
  if (launcherDisposition === "unavailable") process.exitCode = 1;
105
135
  }
106
136
 
137
+ /**
138
+ * @param {Capsule} value
139
+ * @param {string[]} arguments_
140
+ * @returns {Promise<number>}
141
+ */
107
142
  async function runRecoveredCommand(value, arguments_) {
108
143
  let entry = await installedTargetEntry(value);
109
144
  if (entry === null && arguments_[0] === "update") {
110
145
  await rm(value.cancellationPath, { force: true });
111
146
  await rm(value.resultPath, { force: true });
112
147
  await rm(value.ownerPath, { force: true });
113
- const worker = spawn(process.execPath, [fileURLToPath(import.meta.url), "--worker", manifestPath], {
148
+ const worker = spawn(process.execPath, [fileURLToPath(import.meta.url), "--worker", capsuleManifestPath], {
114
149
  detached: true,
115
150
  windowsHide: true,
116
151
  stdio: "ignore",
117
152
  });
118
153
  worker.unref();
119
154
  const deadline = Date.now() + 15 * 60 * 1000;
120
- const requestCancellation = signal => { void writeJson(value.cancellationPath, { schema: SCHEMA, transactionId: value.transactionId, signal, requestedAt: new Date().toISOString() }); };
155
+ const requestCancellation = (/** @type {string} */ signal) => { void writeJson(value.cancellationPath, { schema: SCHEMA, transactionId: value.transactionId, signal, requestedAt: new Date().toISOString() }); };
121
156
  const onSigint = () => requestCancellation("SIGINT");
122
157
  const onSigterm = () => requestCancellation("SIGTERM");
123
158
  process.on("SIGINT", onSigint);
@@ -138,6 +173,10 @@ async function runRecoveredCommand(value, arguments_) {
138
173
  });
139
174
  }
140
175
 
176
+ /**
177
+ * @param {string} path
178
+ * @returns {Promise<Capsule>}
179
+ */
141
180
  async function readCapsule(path) {
142
181
  const value = JSON.parse(await readFile(path, "utf8"));
143
182
  if (value.launchContract !== "neutral-launch-v1") throw new Error("Unsupported private recovery contract; stop existing processes and install directly with npm. Preserve settings, sessions, and history.");
@@ -167,10 +206,10 @@ async function readCapsule(path) {
167
206
  const expectedLaunchers = process.platform === "win32"
168
207
  ? [resolve(launcherRoot, "a1"), resolve(launcherRoot, "a1.cmd"), resolve(launcherRoot, "a1.ps1")]
169
208
  : [resolve(launcherRoot, "a1")];
170
- if (JSON.stringify(value.launchers.map(path => resolve(path))) !== JSON.stringify(expectedLaunchers)) throw new Error("A1 update recovery launcher set is invalid");
209
+ if (JSON.stringify(value.launchers.map((/** @type {string} */ path) => resolve(path))) !== JSON.stringify(expectedLaunchers)) throw new Error("A1 update recovery launcher set is invalid");
171
210
  for (const launcher of value.launchers) assertDirectChild(launcherRoot, resolve(launcher));
172
211
  const expectedSidecars = [resolve(lexicalCapsuleRoot, "cancel.json"), resolve(lexicalCapsuleRoot, "result.json"), resolve(lexicalCapsuleRoot, "owner.json")];
173
- if (![value.cancellationPath, value.resultPath, value.ownerPath].every((candidate, index) => samePath(candidate, expectedSidecars[index]))) {
212
+ if (![value.cancellationPath, value.resultPath, value.ownerPath].every((candidate, index) => samePath(candidate, expectedSidecars[index] ?? ""))) {
174
213
  throw new Error("A1 update recovery sidecar paths are invalid");
175
214
  }
176
215
  const dataDir = dirname(dirname(capsuleRoot));
@@ -188,6 +227,7 @@ async function readCapsule(path) {
188
227
  return value;
189
228
  }
190
229
 
230
+ /** @param {Capsule} value */
191
231
  async function installedTargetEntry(value) {
192
232
  try {
193
233
  const manifest = JSON.parse(await readFile(resolve(value.packageRoot, "package.json"), "utf8"));
@@ -197,6 +237,7 @@ async function installedTargetEntry(value) {
197
237
  } catch { return null; }
198
238
  }
199
239
 
240
+ /** @param {Capsule} value */
200
241
  async function installedTargetIsCallable(value) {
201
242
  if (await installedTargetEntry(value) === null) return false;
202
243
  const token = `node_modules/${value.packageName}/bin/cli.js`;
@@ -212,18 +253,20 @@ async function installedTargetIsCallable(value) {
212
253
  return true;
213
254
  }
214
255
 
256
+ /** @param {Capsule} value */
215
257
  async function writeRecoveryLaunchers(value) {
216
258
  const node = value.nodeExecutable ?? process.execPath;
217
259
  const entry = value.recoveryEntry;
218
- const manifest = manifestPath;
260
+ const manifest = capsuleManifestPath;
219
261
  const shell = `#!/bin/sh\nexec ${shellQuote(node)} ${shellQuote(entry)} --launch ${shellQuote(manifest)} -- "$@"\n`;
220
262
  const command = `@ECHO off\r\n"${node}" "${entry}" --launch "${manifest}" -- %*\r\n`;
221
263
  const powershell = `& '${psQuote(node)}' '${psQuote(entry)}' --launch '${psQuote(manifest)}' -- $args\nexit $LASTEXITCODE\n`;
222
264
  const content = process.platform === "win32" ? [shell, command, powershell] : [shell];
223
265
  await mkdir(value.launcherRoot, { recursive: true });
224
- for (let index = 0; index < value.launchers.length; index += 1) await atomicWrite(value.launchers[index], content[index], 0o755);
266
+ for (let index = 0; index < value.launchers.length; index += 1) await atomicWrite(value.launchers[index] ?? "", content[index] ?? "", 0o755);
225
267
  }
226
268
 
269
+ /** @param {Capsule} value */
227
270
  async function recoveryLaunchersAreCallable(value) {
228
271
  for (const path of value.launchers) {
229
272
  try {
@@ -236,6 +279,11 @@ async function recoveryLaunchersAreCallable(value) {
236
279
  return true;
237
280
  }
238
281
 
282
+ /**
283
+ * @param {string} path
284
+ * @param {string} content
285
+ * @param {number} mode
286
+ */
239
287
  async function atomicWrite(path, content, mode) {
240
288
  const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`;
241
289
  await writeFile(temporary, content, { mode });
@@ -244,6 +292,10 @@ async function atomicWrite(path, content, mode) {
244
292
  await rename(temporary, path);
245
293
  }
246
294
 
295
+ /**
296
+ * @param {string} path
297
+ * @param {unknown} value
298
+ */
247
299
  async function writeJson(path, value) {
248
300
  await mkdir(dirname(path), { recursive: true, mode: 0o700 });
249
301
  const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`;
@@ -254,21 +306,38 @@ async function writeJson(path, value) {
254
306
  await rename(temporary, path);
255
307
  }
256
308
 
309
+ /**
310
+ * @param {string} left
311
+ * @param {string} right
312
+ */
257
313
  function samePath(left, right) {
258
314
  return process.platform === "win32" ? resolve(left).toLowerCase() === resolve(right).toLowerCase() : resolve(left) === resolve(right);
259
315
  }
316
+ /**
317
+ * @param {string} parent
318
+ * @param {string} child
319
+ */
260
320
  function containedBy(parent, child) {
261
321
  const fromParent = relative(parent, child);
262
322
  return fromParent.length > 0 && fromParent !== ".." && !fromParent.startsWith(`..${sep}`) && !isAbsolute(fromParent);
263
323
  }
324
+ /**
325
+ * @param {string} parent
326
+ * @param {string} child
327
+ */
264
328
  function assertDirectChild(parent, child) {
265
329
  const expectedParent = resolve(parent);
266
330
  const actualParent = dirname(resolve(child));
267
331
  const matches = process.platform === "win32" ? actualParent.toLowerCase() === expectedParent.toLowerCase() : actualParent === expectedParent;
268
332
  if (!matches) throw new Error(`A1 update recovery path escapes its managed root: ${child}`);
269
333
  }
334
+ /** @param {string} value */
270
335
  function shellQuote(value) { return `'${String(value).replaceAll("'", `'"'"'`)}'`; }
336
+ /** @param {string} value */
271
337
  function psQuote(value) { return String(value).replaceAll("'", "''"); }
338
+ /** @param {string} value */
272
339
  function bounded(value) { return value.length <= 64 * 1024 ? value : value.slice(-64 * 1024); }
340
+ /** @param {string} path */
273
341
  async function exists(path) { return await lstat(path).then(() => true).catch(() => false); }
342
+ /** @param {number} ms */
274
343
  async function sleep(ms) { await new Promise(resolvePromise => setTimeout(resolvePromise, ms)); }
package/bin/warmup.js CHANGED
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // Invariant: one terminal module identity per process, decided before any A1 or Pi module loads.
4
+ const [{ installPinnedPiTuiResolver }, { fileURLToPath: toPath }] = await Promise.all([import("./module-resolver.js"), import("node:url")]);
5
+ installPinnedPiTuiResolver(toPath(new URL("..", import.meta.url)));
3
6
  const startup = await import("../dist/foundation/startup/startup-runtime.js");
4
7
  startup.assertImmutableWarmupEnvironment(process.env);
5
8
  startup.enableEnvironmentCompileCache(process.env);
@@ -1,4 +1,4 @@
1
- import type { PiTuiInputDiagnosticsEvent } from "../tui-runtime/contracts.js";
1
+ import type { PiTuiInputDiagnosticsEvent } from "../../integrations/pi/tui-runtime/contracts.js";
2
2
  import type { ResponseCopyEvent } from "./response-copy-protocol.js";
3
3
  import type { PasteEvent } from "./paste-protocol.js";
4
4
  /** Opt-in scalar-only snapshots, bounded to 128 rows and one pending asynchronous write. */
@@ -1,4 +1,4 @@
1
- import { ImageAttachmentError, MAX_IMAGE_DATA_BYTES } from "../../../contracts/owned-ui/index.js";
1
+ import { ImageAttachmentError, MAX_IMAGE_DATA_BYTES } from "../../contracts/owned-ui/index.js";
2
2
  import { MAX_SOURCE_IMAGE_BYTES } from "./image-source.js";
3
3
  const STANDARD_BASE64 = /^[A-Za-z0-9+/]*={0,2}$/u;
4
4
  /**
@@ -0,0 +1,33 @@
1
+ import type { ChildProcess } from "node:child_process";
2
+ /** How long an unused spare helper may idle before it is stopped so a background session holds no extra process. */
3
+ export declare const HELPER_SPARE_IDLE_MS: number;
4
+ export interface SpareHelper {
5
+ readonly child: ChildProcess;
6
+ /** Whether the helper already announced itself; the taker must then send the first request itself. */
7
+ readonly ready: boolean;
8
+ }
9
+ export interface HelperPoolOptions {
10
+ readonly fork: () => ChildProcess;
11
+ /** Stops a spare that is no longer wanted; the paste helper needs its process group killed on POSIX. */
12
+ readonly stop: (child: ChildProcess) => void;
13
+ readonly idleMs?: number;
14
+ }
15
+ /**
16
+ * Keeps one forked IPC helper ready so a request takes a live child instead of paying fork and module
17
+ * load on its own critical path. The spare stays idle on its channel until it is taken; a spare that
18
+ * exits or idles too long is dropped, and the next request forks cold and warms a replacement afterwards.
19
+ */
20
+ export declare class HelperPool {
21
+ #private;
22
+ constructor(options: HelperPoolOptions);
23
+ /** Whether a spare is currently held (ready or still starting). */
24
+ get warmed(): boolean;
25
+ /** Opts the pool in and forks the first spare; from here on `replenish` keeps one ready after each request. */
26
+ warm(): void;
27
+ /** Forks the next spare after a request released its child; a no-op until the owner warmed the pool. A fork failure leaves the pool empty. */
28
+ replenish(): void;
29
+ /** Hands the spare to a request, with the pool's listeners removed; returns nothing when no live spare is held. */
30
+ take(): SpareHelper | undefined;
31
+ /** Stops the held spare and refuses further warming. */
32
+ dispose(): void;
33
+ }
@@ -0,0 +1,98 @@
1
+ /** How long an unused spare helper may idle before it is stopped so a background session holds no extra process. */
2
+ export const HELPER_SPARE_IDLE_MS = 5 * 60_000;
3
+ /**
4
+ * Keeps one forked IPC helper ready so a request takes a live child instead of paying fork and module
5
+ * load on its own critical path. The spare stays idle on its channel until it is taken; a spare that
6
+ * exits or idles too long is dropped, and the next request forks cold and warms a replacement afterwards.
7
+ */
8
+ export class HelperPool {
9
+ #fork;
10
+ #stop;
11
+ #idleMs;
12
+ #spare;
13
+ #enabled = false;
14
+ #disposed = false;
15
+ constructor(options) {
16
+ this.#fork = options.fork;
17
+ this.#stop = options.stop;
18
+ this.#idleMs = options.idleMs ?? HELPER_SPARE_IDLE_MS;
19
+ }
20
+ /** Whether a spare is currently held (ready or still starting). */
21
+ get warmed() { return this.#spare !== undefined; }
22
+ /** Opts the pool in and forks the first spare; from here on `replenish` keeps one ready after each request. */
23
+ warm() {
24
+ if (this.#disposed)
25
+ return;
26
+ this.#enabled = true;
27
+ this.replenish();
28
+ }
29
+ /** Forks the next spare after a request released its child; a no-op until the owner warmed the pool. A fork failure leaves the pool empty. */
30
+ replenish() {
31
+ if (!this.#enabled || this.#disposed || this.#spare !== undefined)
32
+ return;
33
+ let child;
34
+ try {
35
+ child = this.#fork();
36
+ }
37
+ catch {
38
+ return;
39
+ }
40
+ const onMessage = (value) => {
41
+ if (this.#spare?.child === child && value?.kind === "ready")
42
+ this.#spare.ready = true;
43
+ };
44
+ const onExit = () => { if (this.#spare?.child === child) {
45
+ this.#drop();
46
+ } };
47
+ const detach = () => {
48
+ child.off("message", onMessage);
49
+ child.off("exit", onExit);
50
+ child.off("close", onExit);
51
+ child.off("error", onExit);
52
+ };
53
+ // Performance: an idle spare must not keep a background session alive or hold a process forever.
54
+ const timer = setTimeout(() => { if (this.#spare?.child === child)
55
+ this.#discard(); }, this.#idleMs);
56
+ timer.unref();
57
+ child.on("message", onMessage);
58
+ child.once("exit", onExit);
59
+ child.once("close", onExit);
60
+ child.once("error", onExit);
61
+ // Invariant: an idle spare never keeps the owner's process alive; taking it refs it again.
62
+ child.unref();
63
+ child.channel?.unref();
64
+ this.#spare = { child, ready: false, timer, detach };
65
+ }
66
+ /** Hands the spare to a request, with the pool's listeners removed; returns nothing when no live spare is held. */
67
+ take() {
68
+ const spare = this.#spare;
69
+ if (spare === undefined)
70
+ return undefined;
71
+ this.#drop();
72
+ if (spare.child.exitCode !== null || spare.child.signalCode !== null || !spare.child.connected)
73
+ return undefined;
74
+ spare.child.ref();
75
+ spare.child.channel?.ref();
76
+ return { child: spare.child, ready: spare.ready };
77
+ }
78
+ /** Stops the held spare and refuses further warming. */
79
+ dispose() {
80
+ this.#disposed = true;
81
+ this.#discard();
82
+ }
83
+ #drop() {
84
+ const spare = this.#spare;
85
+ if (spare === undefined)
86
+ return;
87
+ this.#spare = undefined;
88
+ clearTimeout(spare.timer);
89
+ spare.detach();
90
+ }
91
+ #discard() {
92
+ const spare = this.#spare;
93
+ if (spare === undefined)
94
+ return;
95
+ this.#drop();
96
+ this.#stop(spare.child);
97
+ }
98
+ }
@@ -1,4 +1,4 @@
1
- import type { PiShellClipboardContent } from "../components/index.js";
1
+ import type { PiShellClipboardContent } from "../../integrations/pi/components/index.js";
2
2
  import type { ImagePreparationLimits, PreparedImage } from "./image-preparation.js";
3
3
  import type { ImageWorkerRequest } from "./image-worker.js";
4
4
  export type PreparedClipboardContent = {
@@ -1,5 +1,5 @@
1
1
  import { Worker } from "node:worker_threads";
2
- import { ImageAttachmentError } from "../../../contracts/owned-ui/index.js";
2
+ import { ImageAttachmentError } from "../../contracts/owned-ui/index.js";
3
3
  import { IMAGE_PREPARATION_MS, MAX_SOURCE_IMAGE_BYTES } from "./image-source.js";
4
4
  /** Owns bounded paste acquisition and one off-thread conversion, canceled on session disposal. */
5
5
  export class ImagePreparationClient {
@@ -1,5 +1,5 @@
1
1
  import { isMainThread } from "node:worker_threads";
2
- import { ImageAttachmentError } from "../../../contracts/owned-ui/index.js";
2
+ import { ImageAttachmentError } from "../../contracts/owned-ui/index.js";
3
3
  import { canonicalizeClipboardImage } from "./clipboard-image.js";
4
4
  import { sourceImageInfo } from "./image-source.js";
5
5
  export const IMAGE_TARGET_BASE64_BYTES = 4.5 * 1024 * 1024;
@@ -1,4 +1,4 @@
1
- import { ImageAttachmentError } from "../../../contracts/owned-ui/index.js";
1
+ import { ImageAttachmentError } from "../../contracts/owned-ui/index.js";
2
2
  export const MAX_SOURCE_IMAGE_BYTES = 20 * 1024 * 1024;
3
3
  export const MAX_SOURCE_PIXELS = 40_000_000;
4
4
  export const MAX_SOURCE_DIMENSION = 32_768;
@@ -1,5 +1,5 @@
1
1
  import { parentPort, workerData } from "node:worker_threads";
2
- import { ImageAttachmentError } from "../../../contracts/owned-ui/index.js";
2
+ import { ImageAttachmentError } from "../../contracts/owned-ui/index.js";
3
3
  import { prepareImage } from "./image-preparation.js";
4
4
  import { canonicalizeClipboardImage } from "./clipboard-image.js";
5
5
  import { readSystemClipboardContent } from "./system-clipboard.js";
@@ -0,0 +1,7 @@
1
+ export { ClipboardDiagnosticCapture } from "./clipboard-diagnostics.js";
2
+ export { ContextualPromptSuggestionController, samePromptSuggestionIdentity } from "./prompt-suggestion-controller.js";
3
+ export type { ContextualPromptSuggestionControllerOptions, ContextualPromptSuggestionSurface } from "./prompt-suggestion-controller.js";
4
+ export { OwnedUiSessionShell, OwnedUiSessionShellRoot, formatSessionResumeCommand, quoteCommandArgument } from "./session-shell.js";
5
+ export type { OwnedUiSessionShellOptions, OwnedUiShellDiagnosticOptions, OwnedUiShellEngineOptions, OwnedUiShellHistoryOptions, OwnedUiShellPresentationOptions, OwnedUiShellSuggestionOptions, SessionResumeCommandMetadata, } from "./session-shell.js";
6
+ export { STREAM_PRESENTATION_INTERVAL_MS, StreamPresentationCoalescer } from "./stream-presentation-coalescer.js";
7
+ export type { StreamPresentationScheduler } from "./stream-presentation-coalescer.js";
@@ -0,0 +1,4 @@
1
+ export { ClipboardDiagnosticCapture } from "./clipboard-diagnostics.js";
2
+ export { ContextualPromptSuggestionController, samePromptSuggestionIdentity } from "./prompt-suggestion-controller.js";
3
+ export { OwnedUiSessionShell, OwnedUiSessionShellRoot, formatSessionResumeCommand, quoteCommandArgument } from "./session-shell.js";
4
+ export { STREAM_PRESENTATION_INTERVAL_MS, StreamPresentationCoalescer } from "./stream-presentation-coalescer.js";
@@ -0,0 +1,18 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ import type { PiShellClipboardContent } from "../../integrations/pi/components/shell-shared-facade.js";
3
+ import { type PreparedPaste, type PasteEvent } from "./paste-protocol.js";
4
+ import { HelperPool } from "./helper-pool.js";
5
+ export interface PasteExecutorJob {
6
+ readonly result: Promise<PreparedPaste>;
7
+ readonly stopped: Promise<void>;
8
+ cancel(): void;
9
+ }
10
+ export type PastePhase = (phase: PasteEvent["phase"], bytes?: number) => void;
11
+ /** Forks one paste helper: no inherited descriptors, JSON IPC only, and its own process group on POSIX. */
12
+ export declare function forkPasteHelper(helper?: URL): ChildProcess;
13
+ /** Kills a paste helper and everything it spawned, then lets the parent exit without waiting for it. */
14
+ export declare function stopPasteHelper(child: ChildProcess): void;
15
+ /** A spare-of-one pool of paste helpers; `startPasteExecutor` takes its child and warms the next one after each paste. */
16
+ export declare function createPasteHelperPool(helper?: URL, idleMs?: number): HelperPool;
17
+ /** Streams bounded fragments through a killable child; native/codec/filesystem work never runs on the UI thread. */
18
+ export declare function startPasteExecutor(content: PiShellClipboardContent | undefined, signal: AbortSignal, phase?: PastePhase, helper?: URL, pool?: HelperPool): PasteExecutorJob;
@@ -1,7 +1,8 @@
1
1
  import { fork } from "node:child_process";
2
- import { ImageAttachmentError } from "../../../contracts/owned-ui/image-attachments.js";
2
+ import { ImageAttachmentError } from "../../contracts/owned-ui/index.js";
3
3
  import { MAX_SOURCE_IMAGE_BYTES } from "./image-source.js";
4
4
  import { PASTE_CHUNK_UNITS, PASTE_REQUESTS, PASTE_STOP_MS, PASTE_TEXT_BYTES, pasteFragments } from "./paste-protocol.js";
5
+ import { HelperPool } from "./helper-pool.js";
5
6
  const live = new Set();
6
7
  const conversionQueue = [];
7
8
  let converting;
@@ -18,14 +19,8 @@ function permitConversion() {
18
19
  converting = child;
19
20
  child.send({ kind: "convert" }, () => { });
20
21
  }
21
- /** Streams bounded fragments through a killable child; native/codec/filesystem work never runs on the UI thread. */
22
- export function startPasteExecutor(content, signal, phase = () => { }, helper) {
23
- const tooLarge = content?.kind === "text" && content.text.length > PASTE_TEXT_BYTES;
24
- if (signal.aborted || live.size >= PASTE_REQUESTS || tooLarge) {
25
- const result = Promise.reject(new ImageAttachmentError(signal.aborted ? "image-canceled" : tooLarge ? "paste-size" : "paste-busy"));
26
- void result.catch(() => { });
27
- return { result, stopped: Promise.resolve(), cancel() { } };
28
- }
22
+ /** Forks one paste helper: no inherited descriptors, JSON IPC only, and its own process group on POSIX. */
23
+ export function forkPasteHelper(helper) {
29
24
  const source = new URL(import.meta.url).pathname.endsWith(".ts");
30
25
  const entry = helper ?? new URL(source ? "./paste-helper.ts" : "./paste-helper.js", import.meta.url);
31
26
  const options = {
@@ -33,22 +28,40 @@ export function startPasteExecutor(content, signal, phase = () => { }, helper) {
33
28
  stdio: ["ignore", "ignore", "ignore", "ipc"], serialization: "json", windowsHide: true,
34
29
  detached: process.platform !== "win32",
35
30
  };
36
- const child = fork(entry, [], options);
37
- const forceStop = () => {
38
- // Concurrency: POSIX command fallbacks share this isolated process group; kill descendants too.
39
- if (process.platform !== "win32" && child.pid !== undefined) {
40
- try {
41
- process.kill(-child.pid, "SIGKILL");
42
- }
43
- catch {
44
- child.kill("SIGKILL");
45
- }
31
+ return fork(entry, [], options);
32
+ }
33
+ /** Kills a paste helper and everything it spawned, then lets the parent exit without waiting for it. */
34
+ export function stopPasteHelper(child) {
35
+ // Concurrency: POSIX command fallbacks share this isolated process group; kill descendants too.
36
+ if (process.platform !== "win32" && child.pid !== undefined) {
37
+ try {
38
+ process.kill(-child.pid, "SIGKILL");
46
39
  }
47
- else
40
+ catch {
48
41
  child.kill("SIGKILL");
49
- child.unref();
50
- child.channel?.unref();
51
- };
42
+ }
43
+ }
44
+ else
45
+ child.kill("SIGKILL");
46
+ child.unref();
47
+ child.channel?.unref();
48
+ }
49
+ /** A spare-of-one pool of paste helpers; `startPasteExecutor` takes its child and warms the next one after each paste. */
50
+ export function createPasteHelperPool(helper, idleMs) {
51
+ return new HelperPool({ fork: () => forkPasteHelper(helper), stop: stopPasteHelper, ...(idleMs === undefined ? {} : { idleMs }) });
52
+ }
53
+ /** Streams bounded fragments through a killable child; native/codec/filesystem work never runs on the UI thread. */
54
+ export function startPasteExecutor(content, signal, phase = () => { }, helper, pool) {
55
+ const tooLarge = content?.kind === "text" && content.text.length > PASTE_TEXT_BYTES;
56
+ if (signal.aborted || live.size >= PASTE_REQUESTS || tooLarge) {
57
+ const result = Promise.reject(new ImageAttachmentError(signal.aborted ? "image-canceled" : tooLarge ? "paste-size" : "paste-busy"));
58
+ void result.catch(() => { });
59
+ return { result, stopped: Promise.resolve(), cancel() { } };
60
+ }
61
+ // Performance: a warm spare skips fork and module load on the paste's own critical path.
62
+ const spare = pool?.take();
63
+ const child = spare?.child ?? forkPasteHelper(helper);
64
+ const forceStop = () => stopPasteHelper(child);
52
65
  live.add(child);
53
66
  let input = sourceMessages(content);
54
67
  let canceled = false, done = false;
@@ -84,6 +97,14 @@ export function startPasteExecutor(content, signal, phase = () => { }, helper) {
84
97
  stopTimer.unref();
85
98
  };
86
99
  const fail = (code = "paste-unavailable") => { failure = new ImageAttachmentError(code); cancel(); };
100
+ const advance = () => {
101
+ const next = input?.next();
102
+ if (!next || next.done) {
103
+ fail();
104
+ return;
105
+ }
106
+ send(next.value);
107
+ };
87
108
  signal.addEventListener("abort", cancel, { once: true });
88
109
  child.on("message", value => {
89
110
  if (canceled)
@@ -91,12 +112,7 @@ export function startPasteExecutor(content, signal, phase = () => { }, helper) {
91
112
  const message = value;
92
113
  try {
93
114
  if (message?.kind === "ready") {
94
- const next = input?.next();
95
- if (!next || next.done) {
96
- fail();
97
- return;
98
- }
99
- send(next.value);
115
+ advance();
100
116
  }
101
117
  else if (message?.kind === "phase") {
102
118
  if (!["acquired-text", "acquired-image", "classifying", "path-fallback", "prepared"].includes(message.phase) || phases.has(message.phase)) {
@@ -210,9 +226,14 @@ export function startPasteExecutor(content, signal, phase = () => { }, helper) {
210
226
  phase("cleanup");
211
227
  }
212
228
  catch { /* Invariant: cleanup observation cannot retain an exited executor. */ }
229
+ // Performance: the next paste finds a spare that was forked while nothing waited on it.
230
+ pool?.replenish();
213
231
  };
214
232
  child.once("exit", cleanup);
215
233
  child.once("close", cleanup);
234
+ // Protocol: a spare already announced itself while pooled, so its first request is sent now rather than on "ready".
235
+ if (spare?.ready)
236
+ advance();
216
237
  void result.catch(() => { });
217
238
  return { result, stopped: exit, cancel };
218
239
  }
@@ -1,5 +1,5 @@
1
1
  import { Worker } from "node:worker_threads";
2
- import { ImageAttachmentError } from "../../../contracts/owned-ui/index.js";
2
+ import { ImageAttachmentError } from "../../contracts/owned-ui/index.js";
3
3
  import { readSystemClipboardContent } from "./system-clipboard.js";
4
4
  import { MAX_SOURCE_IMAGE_BYTES } from "./image-source.js";
5
5
  import { preparePasteText } from "./paste-text-preparation.js";
@@ -0,0 +1,31 @@
1
+ import { startPasteExecutor } from "./paste-executor.js";
2
+ import { type PasteEvent, type PasteSource, type PreparedPaste } from "./paste-protocol.js";
3
+ export interface PreparedPasteJob<T> {
4
+ readonly result: Promise<T>;
5
+ cancel(): void;
6
+ complete(): void;
7
+ isCurrent(): boolean;
8
+ }
9
+ /** Starts one isolated preparation; the production starter forks the paste helper, tests may prepare in process. */
10
+ export type PasteExecutorStarter = typeof startPasteExecutor;
11
+ export interface PastePreparationClientOptions {
12
+ readonly onEvent?: (event: PasteEvent) => void;
13
+ /** Test seam: replaces the forked helper entirely; no spare is kept when it is set. */
14
+ readonly execute?: PasteExecutorStarter;
15
+ /** Package/fault-test seam for the forked helper's entry. */
16
+ readonly helper?: URL;
17
+ /** Idle bound for the spare helper; production keeps the default. */
18
+ readonly spareIdleMs?: number;
19
+ }
20
+ /** Keeps eight distinct paste transactions alive through insertion; canceled executors retain capacity until fenced. */
21
+ export declare class PastePreparationClient {
22
+ #private;
23
+ constructor(options?: PastePreparationClientOptions);
24
+ /** Forks the spare helper now so the first paste takes a live child; later pastes rewarm it themselves. */
25
+ warm(): void;
26
+ /** Whether a spare helper is held; diagnostics and tests only. */
27
+ get warmed(): boolean;
28
+ start<T>(source: PasteSource, adopt: (value: PreparedPaste, signal: AbortSignal) => Promise<T> | T, onImage: () => void, onText?: () => void): PreparedPasteJob<T>;
29
+ reset(): void;
30
+ dispose(): Promise<void>;
31
+ }