@timurproko/a1 0.2.7-dev.1245 → 0.2.7-dev.1252

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 (342) hide show
  1. package/README.md +11 -36
  2. package/bin/cli.js +2 -17
  3. package/bin/ui.js +7 -48
  4. package/dist/app/session-shell/exit-notice.d.ts +2 -2
  5. package/dist/app/session-shell/exit-notice.js +10 -10
  6. package/dist/app/session-shell/prompt-submission.d.ts +2 -4
  7. package/dist/app/session-shell/prompt-submission.js +3 -23
  8. package/dist/app/session-shell/response-copy-transport.js +1 -2
  9. package/dist/app/session-shell/session-lifecycle.d.ts +1 -2
  10. package/dist/app/session-shell/session-lifecycle.js +2 -4
  11. package/dist/app/session-shell/session-shell-root.d.ts +0 -31
  12. package/dist/app/session-shell/session-shell-root.js +3 -4
  13. package/dist/app/session-shell/session-shell.js +6 -47
  14. package/dist/app/session-shell/session-viewport-controller.js +3 -6
  15. package/dist/app/session-shell/shell-host.js +2 -18
  16. package/dist/app/session-shell/transcript-document.d.ts +1 -2
  17. package/dist/app/session-shell/transcript-document.js +3 -28
  18. package/dist/app/session-shell/workflow-output.js +1 -1
  19. package/dist/app/session-shell/workflow-router.d.ts +1 -3
  20. package/dist/app/session-shell/workflow-router.js +1 -4
  21. package/dist/cli/dispatch.d.ts +1 -11
  22. package/dist/cli/dispatch.js +5 -92
  23. package/dist/cli/session-context.js +5 -7
  24. package/dist/cli/uninstall.d.ts +1 -5
  25. package/dist/cli/uninstall.js +6 -35
  26. package/dist/cli/version-stats.js +4 -7
  27. package/dist/composition/owned-settings.d.ts +0 -1
  28. package/dist/composition/owned-settings.js +0 -1
  29. package/dist/composition/owned-ui.d.ts +2 -24
  30. package/dist/composition/owned-ui.js +11 -87
  31. package/dist/composition/release-update-observation.d.ts +4 -4
  32. package/dist/composition/release-update-observation.js +17 -47
  33. package/dist/composition/session-backend.d.ts +0 -1
  34. package/dist/composition/session-runtime-registry.d.ts +3 -3
  35. package/dist/composition/settings-route-host.d.ts +0 -7
  36. package/dist/composition/settings-route-host.js +4 -10
  37. package/dist/composition/startup-route.d.ts +0 -1
  38. package/dist/composition/startup-route.js +0 -1
  39. package/dist/contracts/owned-ui/index.d.ts +1 -1
  40. package/dist/contracts/owned-ui/model.d.ts +0 -3
  41. package/dist/contracts/owned-ui/session-workflows.d.ts +1 -4
  42. package/dist/features/launch/development-launch.js +0 -1
  43. package/dist/features/launch/index.d.ts +1 -1
  44. package/dist/features/launch/intent.d.ts +1 -3
  45. package/dist/features/launch/intent.js +2 -4
  46. package/dist/features/launch/session-context.d.ts +2 -2
  47. package/dist/features/owned-ui/reference-screen-app.d.ts +0 -2
  48. package/dist/features/owned-ui/reference-screen-app.js +2 -9
  49. package/dist/features/owned-ui/settings-app.d.ts +0 -6
  50. package/dist/features/owned-ui/settings-app.js +5 -36
  51. package/dist/foundation/launch-context/index.d.ts +0 -12
  52. package/dist/foundation/launch-context/index.js +0 -26
  53. package/dist/foundation/lifecycle/claim-gate.d.ts +8 -0
  54. package/dist/foundation/lifecycle/claim-gate.js +37 -0
  55. package/dist/foundation/lifecycle/index.d.ts +5 -9
  56. package/dist/foundation/lifecycle/index.js +3 -4
  57. package/dist/foundation/lifecycle/model.d.ts +2 -59
  58. package/dist/foundation/lifecycle/model.js +0 -35
  59. package/dist/foundation/lifecycle/paths.d.ts +0 -24
  60. package/dist/foundation/lifecycle/paths.js +0 -40
  61. package/dist/foundation/lifecycle/process-liveness.d.ts +8 -0
  62. package/dist/foundation/lifecycle/process-liveness.js +18 -0
  63. package/dist/foundation/lifecycle/session-claim-lock.d.ts +1 -1
  64. package/dist/foundation/lifecycle/session-claim-lock.js +2 -2
  65. package/dist/foundation/lifecycle/session-repository-context.d.ts +6 -6
  66. package/dist/foundation/lifecycle/session-repository-context.js +2 -3
  67. package/dist/foundation/release/automatic-update.d.ts +1 -3
  68. package/dist/foundation/release/automatic-update.js +9 -30
  69. package/dist/foundation/release/bootstrap.d.ts +2 -25
  70. package/dist/foundation/release/bootstrap.js +33 -344
  71. package/dist/foundation/release/cohort-state.d.ts +21 -46
  72. package/dist/foundation/release/cohort-state.js +30 -62
  73. package/dist/foundation/release/dependency-certification.d.ts +1 -1
  74. package/dist/foundation/release/index.d.ts +10 -17
  75. package/dist/foundation/release/index.js +7 -11
  76. package/dist/foundation/release/latest-release.d.ts +1 -2
  77. package/dist/foundation/release/latest-release.js +1 -2
  78. package/dist/foundation/release/process-liveness.d.ts +2 -0
  79. package/dist/foundation/release/process-liveness.js +12 -0
  80. package/dist/foundation/release/release-gc.d.ts +12 -9
  81. package/dist/foundation/release/release-gc.js +34 -98
  82. package/dist/foundation/release/release-store.d.ts +2 -2
  83. package/dist/foundation/release/release-store.js +2 -2
  84. package/dist/foundation/release/restart-certification.js +1 -1
  85. package/dist/foundation/release/update-activation.d.ts +2 -9
  86. package/dist/foundation/release/update-activation.js +28 -43
  87. package/dist/foundation/release/update-execution-lease.js +1 -1
  88. package/dist/foundation/release/update-launch.d.ts +0 -2
  89. package/dist/foundation/release/update-launch.js +0 -7
  90. package/dist/foundation/release/update-recovery.js +1 -1
  91. package/dist/foundation/release/update-transaction.d.ts +1 -1
  92. package/dist/foundation/release/update-transaction.js +5 -2
  93. package/dist/foundation/release/update.d.ts +2 -10
  94. package/dist/foundation/release/update.js +23 -200
  95. package/dist/foundation/session-writer-lock/index.d.ts +14 -6
  96. package/dist/foundation/session-writer-lock/index.js +48 -103
  97. package/dist/foundation/startup/startup-runtime.d.ts +1 -1
  98. package/dist/foundation/terminal-cleanup/exit-notice.d.ts +6 -0
  99. package/dist/foundation/terminal-cleanup/exit-notice.js +36 -0
  100. package/dist/foundation/terminal-cleanup/index.d.ts +2 -1
  101. package/dist/foundation/terminal-cleanup/index.js +2 -1
  102. package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +0 -5
  103. package/dist/foundation/terminal-cleanup/terminal-reset.js +0 -5
  104. package/dist/integrations/pi/components/index.d.ts +1 -1
  105. package/dist/integrations/pi/components/index.js +1 -1
  106. package/dist/integrations/pi/components/shell-editor-autocomplete.js +1 -4
  107. package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
  108. package/dist/integrations/pi/components/shell-footer-status.js +2 -2
  109. package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
  110. package/dist/integrations/pi/components/shell-presenters-info.d.ts +2 -5
  111. package/dist/integrations/pi/components/shell-presenters-info.js +4 -18
  112. package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +1 -1
  113. package/dist/integrations/pi/components/shell-presenters-transcript.js +1 -1
  114. package/dist/integrations/pi/components/shell-shared-facade.d.ts +0 -2
  115. package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +2 -5
  116. package/dist/integrations/pi/components/submitted-prompt-adapter.js +2 -16
  117. package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +1 -2
  118. package/dist/integrations/pi/components/upstream/components/session-footer.js +6 -8
  119. package/dist/integrations/pi/engine/adapter.d.ts +0 -1
  120. package/dist/integrations/pi/engine/adapter.js +1 -16
  121. package/dist/integrations/pi/engine/compaction-progress.js +13 -5
  122. package/dist/integrations/pi/engine/diagnostics-state.d.ts +0 -1
  123. package/dist/integrations/pi/engine/diagnostics-state.js +0 -14
  124. package/dist/integrations/pi/engine/prompt-suggestions.d.ts +0 -1
  125. package/dist/integrations/pi/engine/prompt-suggestions.js +0 -40
  126. package/dist/integrations/pi/engine/session-runtime.js +0 -2
  127. package/dist/integrations/pi/engine/workflow-runner.js +1 -1
  128. package/dist/integrations/pi/tui-runtime/adapter.d.ts +2 -2
  129. package/dist/integrations/pi/tui-runtime/adapter.js +2 -2
  130. package/dist/product-identity.d.ts +4 -6
  131. package/dist/product-identity.js +6 -11
  132. package/dist/product-identity.json +1 -40
  133. package/dist/runtime-payload-inventory.json +0 -3
  134. package/dist/ui/components/index.d.ts +2 -2
  135. package/dist/ui/components/index.js +1 -1
  136. package/dist/ui/components/submitted-prompt.d.ts +3 -13
  137. package/dist/ui/components/submitted-prompt.js +8 -41
  138. package/dist/ui/components/transcript-viewport.d.ts +1 -3
  139. package/dist/ui/components/transcript-viewport.js +1 -4
  140. package/dist/ui/settings/declarations.d.ts +3 -97
  141. package/dist/ui/settings/declarations.js +3 -78
  142. package/dist/ui/settings/migrations.js +18 -2
  143. package/docs/architecture/boundaries.md +22 -39
  144. package/docs/architecture/code-documentation.md +2 -2
  145. package/docs/architecture/internal-naming.md +9 -17
  146. package/docs/architecture/project-structure.md +30 -29
  147. package/docs/architecture/resource-and-data-policy.md +16 -31
  148. package/docs/architecture/toolchain.md +14 -19
  149. package/docs/architecture/ui-reference-provenance.md +2 -2
  150. package/docs/ci-release-runbook.md +6 -4
  151. package/docs/features/launch-profiles.md +11 -17
  152. package/docs/features/prompt-history.md +10 -11
  153. package/docs/local-worktree-cleanup.md +32 -1
  154. package/docs/manual-owned-ui-checkpoint.md +0 -1
  155. package/docs/openspec-archive-automation.md +11 -3
  156. package/docs/validation.md +5 -9
  157. package/docs/worktree-link-recovery.md +6 -6
  158. package/package.json +7 -19
  159. package/bin/guardian.js +0 -42
  160. package/bin/supervisor.js +0 -7
  161. package/bin/tab-launch-context.d.ts +0 -27
  162. package/bin/tab-launch-context.js +0 -94
  163. package/dist/app/session-shell/resident-tab-coordinator.d.ts +0 -38
  164. package/dist/app/session-shell/resident-tab-coordinator.js +0 -77
  165. package/dist/cli/tabs-request.d.ts +0 -7
  166. package/dist/cli/tabs-request.js +0 -1
  167. package/dist/cli/tabs.d.ts +0 -14
  168. package/dist/cli/tabs.js +0 -151
  169. package/dist/composition/resident-tab-bridge.d.ts +0 -41
  170. package/dist/composition/resident-tab-bridge.js +0 -209
  171. package/dist/composition/utility-tab.d.ts +0 -28
  172. package/dist/composition/utility-tab.js +0 -244
  173. package/dist/features/owned-ui/plus-menu-dialog.d.ts +0 -28
  174. package/dist/features/owned-ui/plus-menu-dialog.js +0 -89
  175. package/dist/features/resident-tab/auto-name.d.ts +0 -11
  176. package/dist/features/resident-tab/auto-name.js +0 -44
  177. package/dist/features/resident-tab/index.d.ts +0 -5
  178. package/dist/features/resident-tab/index.js +0 -7
  179. package/dist/features/resident-tab/shortcut-bindings-file.d.ts +0 -8
  180. package/dist/features/resident-tab/shortcut-bindings-file.js +0 -40
  181. package/dist/features/resident-tab/shortcut-declarations.d.ts +0 -13
  182. package/dist/features/resident-tab/shortcut-declarations.js +0 -26
  183. package/dist/features/resident-tab/shortcut-projection.d.ts +0 -29
  184. package/dist/features/resident-tab/shortcut-projection.js +0 -64
  185. package/dist/features/resident-tab/status-deriver.d.ts +0 -10
  186. package/dist/features/resident-tab/status-deriver.js +0 -12
  187. package/dist/foundation/launch-guardian/exit-watcher.d.ts +0 -14
  188. package/dist/foundation/launch-guardian/exit-watcher.js +0 -103
  189. package/dist/foundation/launch-guardian/index.d.ts +0 -2
  190. package/dist/foundation/launch-guardian/index.js +0 -1
  191. package/dist/foundation/launch-guardian/main.d.ts +0 -39
  192. package/dist/foundation/launch-guardian/main.js +0 -232
  193. package/dist/foundation/lifecycle/commands.d.ts +0 -40
  194. package/dist/foundation/lifecycle/commands.js +0 -1
  195. package/dist/foundation/lifecycle/launch-instance.d.ts +0 -46
  196. package/dist/foundation/lifecycle/launch-instance.js +0 -134
  197. package/dist/foundation/lifecycle/native-claim-gate.d.ts +0 -5
  198. package/dist/foundation/lifecycle/native-claim-gate.js +0 -41
  199. package/dist/foundation/lifecycle/supervisor-startup.d.ts +0 -30
  200. package/dist/foundation/lifecycle/supervisor-startup.js +0 -106
  201. package/dist/foundation/process-containment/addon-containment.d.ts +0 -20
  202. package/dist/foundation/process-containment/addon-containment.js +0 -139
  203. package/dist/foundation/process-containment/addon-process-inspector.d.ts +0 -11
  204. package/dist/foundation/process-containment/addon-process-inspector.js +0 -36
  205. package/dist/foundation/process-containment/addon.d.ts +0 -47
  206. package/dist/foundation/process-containment/addon.js +0 -57
  207. package/dist/foundation/process-containment/artifact.d.ts +0 -1
  208. package/dist/foundation/process-containment/artifact.js +0 -35
  209. package/dist/foundation/process-containment/contracts.d.ts +0 -33
  210. package/dist/foundation/process-containment/contracts.js +0 -35
  211. package/dist/foundation/process-containment/index.d.ts +0 -9
  212. package/dist/foundation/process-containment/index.js +0 -7
  213. package/dist/foundation/process-containment/linux-process-inspector.d.ts +0 -7
  214. package/dist/foundation/process-containment/linux-process-inspector.js +0 -27
  215. package/dist/foundation/process-containment/native-process-inspector.d.ts +0 -4
  216. package/dist/foundation/process-containment/native-process-inspector.js +0 -21
  217. package/dist/foundation/protocol/client.d.ts +0 -18
  218. package/dist/foundation/protocol/client.js +0 -130
  219. package/dist/foundation/protocol/index.d.ts +0 -3
  220. package/dist/foundation/protocol/index.js +0 -2
  221. package/dist/foundation/protocol/messages.d.ts +0 -90
  222. package/dist/foundation/protocol/messages.js +0 -100
  223. package/dist/foundation/release/cohort-selection.d.ts +0 -33
  224. package/dist/foundation/release/cohort-selection.js +0 -67
  225. package/dist/foundation/release/endpoint-lock.d.ts +0 -2
  226. package/dist/foundation/release/endpoint-lock.js +0 -37
  227. package/dist/foundation/release/endpoint-recovery.d.ts +0 -10
  228. package/dist/foundation/release/endpoint-recovery.js +0 -45
  229. package/dist/foundation/release/endpoints.d.ts +0 -32
  230. package/dist/foundation/release/endpoints.js +0 -152
  231. package/dist/foundation/release/prepared-update-activation.d.ts +0 -3
  232. package/dist/foundation/release/prepared-update-activation.js +0 -27
  233. package/dist/foundation/release/process-cleanup.d.ts +0 -14
  234. package/dist/foundation/release/process-cleanup.js +0 -76
  235. package/dist/foundation/release/supervisor-identity.d.ts +0 -15
  236. package/dist/foundation/release/supervisor-identity.js +0 -63
  237. package/dist/foundation/resident-tabs/boot-identity.d.ts +0 -6
  238. package/dist/foundation/resident-tabs/boot-identity.js +0 -16
  239. package/dist/foundation/resident-tabs/bounded-host-command.d.ts +0 -20
  240. package/dist/foundation/resident-tabs/bounded-host-command.js +0 -62
  241. package/dist/foundation/resident-tabs/bridge-client.d.ts +0 -73
  242. package/dist/foundation/resident-tabs/bridge-client.js +0 -327
  243. package/dist/foundation/resident-tabs/continuity.d.ts +0 -12
  244. package/dist/foundation/resident-tabs/continuity.js +0 -63
  245. package/dist/foundation/resident-tabs/doctor.d.ts +0 -28
  246. package/dist/foundation/resident-tabs/doctor.js +0 -166
  247. package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +0 -27
  248. package/dist/foundation/resident-tabs/draft-checkpoint.js +0 -145
  249. package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +0 -36
  250. package/dist/foundation/resident-tabs/ensure-terminal-host.js +0 -151
  251. package/dist/foundation/resident-tabs/fault-injection.d.ts +0 -8
  252. package/dist/foundation/resident-tabs/fault-injection.js +0 -26
  253. package/dist/foundation/resident-tabs/fixture-control.d.ts +0 -7
  254. package/dist/foundation/resident-tabs/fixture-control.js +0 -35
  255. package/dist/foundation/resident-tabs/host-entry.d.ts +0 -1
  256. package/dist/foundation/resident-tabs/host-entry.js +0 -17
  257. package/dist/foundation/resident-tabs/index.d.ts +0 -15
  258. package/dist/foundation/resident-tabs/index.js +0 -10
  259. package/dist/foundation/resident-tabs/maintenance.d.ts +0 -39
  260. package/dist/foundation/resident-tabs/maintenance.js +0 -75
  261. package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +0 -34
  262. package/dist/foundation/resident-tabs/progress-observation-schema.js +0 -1
  263. package/dist/foundation/resident-tabs/progress-observation.d.ts +0 -4
  264. package/dist/foundation/resident-tabs/progress-observation.js +0 -150
  265. package/dist/foundation/resident-tabs/prompt-journal.d.ts +0 -63
  266. package/dist/foundation/resident-tabs/prompt-journal.js +0 -213
  267. package/dist/foundation/resident-tabs/protocol.d.ts +0 -12
  268. package/dist/foundation/resident-tabs/protocol.js +0 -195
  269. package/dist/foundation/resident-tabs/recovery.d.ts +0 -26
  270. package/dist/foundation/resident-tabs/recovery.js +0 -205
  271. package/dist/foundation/resident-tabs/release-holds.d.ts +0 -28
  272. package/dist/foundation/resident-tabs/release-holds.js +0 -78
  273. package/dist/foundation/resident-tabs/routes.d.ts +0 -5
  274. package/dist/foundation/resident-tabs/routes.js +0 -5
  275. package/dist/foundation/resident-tabs/routing.d.ts +0 -11
  276. package/dist/foundation/resident-tabs/routing.js +0 -10
  277. package/dist/foundation/resident-tabs/runtime-control.d.ts +0 -38
  278. package/dist/foundation/resident-tabs/runtime-control.js +0 -74
  279. package/dist/foundation/resident-tabs/session-sync.d.ts +0 -14
  280. package/dist/foundation/resident-tabs/session-sync.js +0 -37
  281. package/dist/foundation/resident-tabs/settings.d.ts +0 -16
  282. package/dist/foundation/resident-tabs/settings.js +0 -60
  283. package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +0 -14
  284. package/dist/foundation/resident-tabs/terminal-host-artifact.js +0 -78
  285. package/dist/foundation/resident-tabs/zip-archive.d.ts +0 -9
  286. package/dist/foundation/resident-tabs/zip-archive.js +0 -56
  287. package/dist/foundation/storage/control-store.d.ts +0 -20
  288. package/dist/foundation/storage/control-store.js +0 -331
  289. package/dist/foundation/storage/index.d.ts +0 -1
  290. package/dist/foundation/storage/index.js +0 -1
  291. package/dist/foundation/supervision/index.d.ts +0 -3
  292. package/dist/foundation/supervision/index.js +0 -3
  293. package/dist/foundation/supervision/main.d.ts +0 -1
  294. package/dist/foundation/supervision/main.js +0 -86
  295. package/dist/foundation/supervision/paths.d.ts +0 -1
  296. package/dist/foundation/supervision/paths.js +0 -1
  297. package/dist/foundation/supervision/server.d.ts +0 -46
  298. package/dist/foundation/supervision/server.js +0 -606
  299. package/dist/integrations/pi/engine/offline-settings-port.d.ts +0 -23
  300. package/dist/integrations/pi/engine/offline-settings-port.js +0 -54
  301. package/dist/native/darwin-arm64/manifest.json +0 -23
  302. package/dist/native/darwin-arm64/process-guardian.node +0 -0
  303. package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10500
  304. package/dist/native/darwin-arm64/terminal-host.manifest.json +0 -46
  305. package/dist/native/darwin-arm64/terminal-host.node +0 -0
  306. package/dist/native/darwin-x64/manifest.json +0 -23
  307. package/dist/native/darwin-x64/process-guardian.node +0 -0
  308. package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10737
  309. package/dist/native/darwin-x64/terminal-host.manifest.json +0 -46
  310. package/dist/native/darwin-x64/terminal-host.node +0 -0
  311. package/dist/native/linux-x64/manifest.json +0 -23
  312. package/dist/native/linux-x64/process-guardian.node +0 -0
  313. package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -11226
  314. package/dist/native/linux-x64/terminal-host.manifest.json +0 -46
  315. package/dist/native/linux-x64/terminal-host.node +0 -0
  316. package/dist/native/win32-x64/manifest.json +0 -23
  317. package/dist/native/win32-x64/process-guardian.node +0 -0
  318. package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10757
  319. package/dist/native/win32-x64/terminal-host.manifest.json +0 -46
  320. package/dist/native/win32-x64/terminal-host.node +0 -0
  321. package/docs/architecture/evidence/resident-tabs/linux-x64.md +0 -37
  322. package/docs/architecture/evidence/resident-tabs/macos-arm64.md +0 -36
  323. package/docs/architecture/evidence/resident-tabs/macos-x64.md +0 -35
  324. package/docs/architecture/evidence/resident-tabs/windows-x64.md +0 -36
  325. package/docs/architecture/evidence/terminal-host-spike/manual-one-pane-terminal-host.md +0 -70
  326. package/docs/architecture/evidence/terminal-host-spike/manual-two-by-two-basic-terminal-host.md +0 -32
  327. package/docs/architecture/evidence/terminal-host-spike/milestone-baseline.json +0 -115
  328. package/docs/architecture/evidence/terminal-host-spike/owned-ui-foundation-prerequisite.json +0 -48
  329. package/docs/architecture/evidence/terminal-host-spike/terminal-host-provenance.json +0 -125
  330. package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-1.json +0 -56
  331. package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-3.json +0 -174
  332. package/docs/architecture/evidence/terminal-host-spike/terminal-spike-acceptance-record.json +0 -18
  333. package/docs/architecture/native-fixture-isolation.md +0 -23
  334. package/docs/architecture/process-guardian-provenance.md +0 -36
  335. package/docs/architecture/resident-tabs-requirements.md +0 -18
  336. package/docs/architecture/resident-tabs.md +0 -668
  337. package/docs/architecture/terminal-host-proof-gate.md +0 -34
  338. package/docs/architecture/terminal-host-provenance.md +0 -81
  339. package/docs/architecture/terminal-host-spike-evidence.md +0 -39
  340. package/docs/launch-recovery.md +0 -23
  341. package/docs/manual-launch-instance-acceptance.md +0 -43
  342. package/docs/manual-resident-tabs-acceptance.md +0 -51
@@ -1,327 +0,0 @@
1
- import { connect } from "node:net";
2
- import { encodeResidentFrame, ResidentFrameDecoder } from "./protocol.js";
3
- import { RESIDENT_TAB_ROUTES } from "./routes.js";
4
- export { residentUtilityRoute } from "./routes.js";
5
- const RESIDENT_TAB_ROUTE_SET = new Set(RESIDENT_TAB_ROUTES);
6
- /** Metadata-only advisory bridge. Terminal input and transcript bytes have no API here. */
7
- export class TabBridgeClient {
8
- #options;
9
- #transport = null;
10
- #connected = false;
11
- #available = true;
12
- #features = new Set();
13
- #sequence = 0;
14
- #request = 0;
15
- #attachment = null;
16
- #closed = false;
17
- #retry = null;
18
- #latestStatus = null;
19
- #accent = null;
20
- #latestSession = null;
21
- #latestShortcuts = null;
22
- #heartbeat = null;
23
- #pending = new Map();
24
- #startWaiter = null;
25
- #commandListeners = new Set();
26
- #pendingCommands = [];
27
- #boundaryInputRemainder = "";
28
- constructor(options) { this.#options = options; }
29
- get tabId() { return this.#options.credentials.tabId; }
30
- get available() { return this.#available && this.#connected; }
31
- captureAttachment() { return this.#attachment === null ? null : { ...this.#attachment }; }
32
- onCommand(listener) {
33
- this.#commandListeners.add(listener);
34
- for (const command of this.#pendingCommands.splice(0))
35
- listener(command);
36
- return () => this.#commandListeners.delete(listener);
37
- }
38
- async start(timeoutMs = 4_000) {
39
- if (this.#closed || this.#transport !== null)
40
- return this.available;
41
- const transport = (this.#options.connect ?? (endpoint => connect(endpoint)))(this.#options.credentials.endpoint);
42
- this.#transport = transport;
43
- const decoder = new ResidentFrameDecoder();
44
- transport.on("data", bytes => {
45
- try {
46
- for (const message of decoder.push(bytes))
47
- this.#receive(message);
48
- }
49
- catch {
50
- if (this.#transport === transport)
51
- this.#fail();
52
- }
53
- });
54
- transport.once("close", () => { if (this.#transport === transport)
55
- this.#fail(); });
56
- transport.once("error", () => { if (this.#transport === transport)
57
- this.#fail(); });
58
- return await new Promise(resolvePromise => {
59
- let settled = false;
60
- let timer;
61
- const finish = (value) => {
62
- if (settled)
63
- return;
64
- settled = true;
65
- if (timer !== undefined)
66
- clearTimeout(timer);
67
- this.#startWaiter = null;
68
- resolvePromise(value);
69
- };
70
- this.#startWaiter = finish;
71
- transport.once("connect", () => {
72
- this.#send("hello", {
73
- role: "bridge", generation: 1, build: this.#options.build ?? "a1", releaseId: this.#options.credentials.releaseId,
74
- features: ["bridge-status", "bridge-detach", "bridge-heartbeat", "bridge-restart", "bridge-visibility", "bridge-rename", "bridge-route", "bridge-stop", "bridge-shortcuts", "controller-boundary", "recovery-journal", "client-identity"],
75
- token: [...Buffer.from(this.#options.credentials.token, "base64")], tabId: this.#options.credentials.tabId,
76
- pid: this.#options.pid ?? process.pid, startIdentity: this.#options.startIdentity ?? `${process.pid}:node`,
77
- }, ++this.#request);
78
- });
79
- transport.once("error", () => finish(false));
80
- timer = setTimeout(() => { this.#fail(); finish(false); }, timeoutMs);
81
- timer.unref();
82
- });
83
- }
84
- status(state, degraded = false, pendingRequests = 0, queuedInput = 0) {
85
- this.#latestStatus = { state, degraded, accent: this.#accent, pendingRequests, queuedInput };
86
- const recoveryState = state === "unresponsive" || state === "crashed" || state === "restarting" || state === "failed";
87
- if (recoveryState && !this.#supports("recovery-status"))
88
- return;
89
- this.#send("bridge.status", {
90
- seq: ++this.#sequence,
91
- state,
92
- pendingRequests: Math.max(0, Math.trunc(pendingRequests)),
93
- queuedInput: Math.max(0, Math.trunc(queuedInput)),
94
- ...(this.#accent === null ? {} : { accent: this.#accent }),
95
- ...(degraded && this.#supports("recovery-status") ? { degraded: true } : {}),
96
- });
97
- }
98
- degraded(degraded) {
99
- this.status(this.#latestStatus?.state ?? "idle", degraded);
100
- }
101
- accent(accent) {
102
- this.#accent = accent;
103
- if (this.#latestStatus !== null)
104
- this.status(this.#latestStatus.state, this.#latestStatus.degraded, this.#latestStatus.pendingRequests, this.#latestStatus.queuedInput);
105
- }
106
- session(file, name, nameSource = "default") {
107
- this.#latestSession = { file, name, nameSource };
108
- this.#send("bridge.session", { file, name, nameSource });
109
- }
110
- prompt(interrupted) {
111
- this.#send("bridge.prompt", { interrupted });
112
- }
113
- /** Publishes the effective tab shortcut assignments so the host dispatches and labels the same keys. */
114
- shortcuts(assignments) {
115
- this.#latestShortcuts = Object.entries(assignments).map(([action, key]) => [action, key]);
116
- this.#sendShortcuts();
117
- }
118
- #sendShortcuts() {
119
- if (this.#latestShortcuts === null || !this.#supports("bridge-shortcuts"))
120
- return;
121
- this.#send("bridge.shortcuts", { assignments: this.#latestShortcuts.map(([action, key]) => [action, key]) });
122
- }
123
- requestDetach(origin = this.captureAttachment(), timeoutMs = 1_000) {
124
- return this.requestAction("detach", origin, timeoutMs);
125
- }
126
- requestRestart(origin = this.captureAttachment(), timeoutMs = 1_000) {
127
- return this.requestAction("restart", origin, timeoutMs);
128
- }
129
- requestClose(origin = this.captureAttachment(), timeoutMs = 1_000) {
130
- return this.requestAction("close", origin, timeoutMs);
131
- }
132
- consumeControllerBoundaryInput(data) {
133
- const prefix = "\x1bP+a1;controller=";
134
- const suffix = "\x1b\\";
135
- let pending = this.#boundaryInputRemainder + data;
136
- this.#boundaryInputRemainder = "";
137
- let output = "";
138
- while (pending.length > 0) {
139
- const start = pending.indexOf(prefix);
140
- if (start === -1) {
141
- let retained = 0;
142
- const maximum = Math.min(prefix.length - 1, pending.length);
143
- // Invariant: a lone trailing Esc is a user key and passes at once; only `\x1bP` or more is withheld.
144
- for (let length = maximum; length > 1; length--) {
145
- if (pending.endsWith(prefix.slice(0, length))) {
146
- retained = length;
147
- break;
148
- }
149
- }
150
- const split = pending.length - retained;
151
- output += pending.slice(0, split);
152
- this.#boundaryInputRemainder = pending.slice(split);
153
- break;
154
- }
155
- output += pending.slice(0, start);
156
- const end = pending.indexOf(suffix, start + prefix.length);
157
- if (end === -1) {
158
- this.#boundaryInputRemainder = pending.slice(start);
159
- break;
160
- }
161
- const body = pending.slice(start + prefix.length, end);
162
- const separator = body.indexOf(";");
163
- const generation = Number(body.slice(0, separator));
164
- const nonceHex = body.slice(separator + 1);
165
- if (separator > 0 && Number.isSafeInteger(generation) && generation > 0 && /^[0-9a-f]{32}$/u.test(nonceHex)) {
166
- this.#send("bridge.boundary", {
167
- generation,
168
- nonce: [...Buffer.from(nonceHex, "hex")],
169
- });
170
- }
171
- else {
172
- output += pending.slice(start, end + suffix.length);
173
- }
174
- pending = pending.slice(end + suffix.length);
175
- }
176
- return output;
177
- }
178
- close() {
179
- this.#closed = true;
180
- if (this.#retry !== null)
181
- clearTimeout(this.#retry);
182
- this.#retry = null;
183
- this.#stopHeartbeat();
184
- const transport = this.#transport;
185
- this.#transport = null;
186
- transport?.destroy();
187
- this.#fail(false);
188
- }
189
- #emitCommand(command) {
190
- if (this.#commandListeners.size === 0) {
191
- if (this.#pendingCommands.length >= 16)
192
- this.#pendingCommands.shift();
193
- this.#pendingCommands.push(command);
194
- return;
195
- }
196
- for (const listener of this.#commandListeners)
197
- listener(command);
198
- }
199
- #send(type, body, requestId) {
200
- if (this.#transport === null || (!this.#connected && type !== "hello"))
201
- return;
202
- try {
203
- this.#transport.write(encodeResidentFrame({ type, ...(requestId === undefined ? {} : { requestId }), body }));
204
- }
205
- catch {
206
- this.#fail();
207
- }
208
- }
209
- #receive(message) {
210
- if (message.type === "welcome" && message.body["generation"] === 1) {
211
- const id = this.#options.credentials.releaseId;
212
- if (id !== undefined && message.body["releaseId"] !== id) {
213
- this.#fail(false);
214
- return;
215
- }
216
- const advertised = message.body["features"];
217
- this.#features = new Set(Array.isArray(advertised) ? advertised.filter((feature) => typeof feature === "string") : []);
218
- this.#connected = true;
219
- this.#available = true;
220
- this.#startWaiter?.(true);
221
- if (this.#supports("bridge-heartbeat"))
222
- this.#startHeartbeat();
223
- if (this.#latestStatus !== null)
224
- this.status(this.#latestStatus.state, this.#latestStatus.degraded, this.#latestStatus.pendingRequests, this.#latestStatus.queuedInput);
225
- if (this.#latestSession !== null)
226
- this.#send("bridge.session", this.#latestSession);
227
- this.#sendShortcuts();
228
- return;
229
- }
230
- if (message.type === "incompatible-generation") {
231
- this.#fail();
232
- return;
233
- }
234
- if (message.type === "bridge.client" && typeof message.body["version"] === "string") {
235
- const version = message.body["version"];
236
- if (version.length <= 128 && /^\d+\.\d+\.\d+(?:[-+][a-z0-9.+-]+)?$/iu.test(version))
237
- this.#emitCommand({ type: "client", version });
238
- return;
239
- }
240
- if (message.type === "bridge.visibility" && typeof message.body["visible"] === "boolean") {
241
- this.#emitCommand({ type: "visibility", visible: message.body["visible"] });
242
- return;
243
- }
244
- if (message.type === "bridge.rename" && typeof message.body["name"] === "string") {
245
- const source = message.body["nameSource"];
246
- this.#emitCommand({ type: "rename", name: message.body["name"], nameSource: source === "auto" || source === "default" ? source : "user" });
247
- return;
248
- }
249
- if (message.type === "bridge.route" && RESIDENT_TAB_ROUTE_SET.has(message.body["route"])) {
250
- this.#emitCommand({ type: "route", route: message.body["route"] });
251
- return;
252
- }
253
- if (message.type === "bridge.stop" && typeof message.body["deadlineMs"] === "number") {
254
- this.#emitCommand({ type: "stop", deadlineMs: message.body["deadlineMs"] });
255
- return;
256
- }
257
- if (message.type === "attachment") {
258
- const clientId = message.body["clientId"];
259
- const revision = message.body["controllerRevision"];
260
- if (typeof clientId === "string" && typeof revision === "number")
261
- this.#attachment = { clientId, controllerRevision: revision };
262
- return;
263
- }
264
- if ((message.type === "bridge.result" || message.type === "result") && typeof message.requestId === "number") {
265
- const resolvePromise = this.#pending.get(message.requestId);
266
- if (resolvePromise) {
267
- this.#pending.delete(message.requestId);
268
- resolvePromise(message.body["accepted"] === true);
269
- }
270
- }
271
- }
272
- /**
273
- * Asks the server to act for the client that controls this tab, as `origin`: leave it, restart or close the tab,
274
- * or open the tab bar's Plus Menu dialog (`configure-plus`).
275
- */
276
- async requestAction(action, origin = this.captureAttachment(), timeoutMs = 1_000) {
277
- if (!this.available || origin === null || (action === "restart" && !this.#supports("bridge-restart")))
278
- return false;
279
- const requestId = ++this.#request;
280
- const result = new Promise(resolvePromise => this.#pending.set(requestId, resolvePromise));
281
- this.#send("bridge.request", { action, clientId: origin.clientId, controllerRevision: origin.controllerRevision }, requestId);
282
- const timeout = new Promise(resolvePromise => {
283
- const timer = setTimeout(() => { this.#pending.delete(requestId); resolvePromise(false); }, timeoutMs);
284
- timer.unref();
285
- });
286
- return await Promise.race([result, timeout]);
287
- }
288
- #startHeartbeat() {
289
- if (this.#heartbeat !== null)
290
- return;
291
- const schedule = this.#options.setInterval ?? ((callback, milliseconds) => setInterval(callback, milliseconds));
292
- this.#heartbeat = schedule(() => this.#send("bridge.heartbeat", { seq: ++this.#sequence }), this.#options.heartbeatIntervalMs ?? 5_000);
293
- this.#heartbeat.unref?.();
294
- }
295
- #stopHeartbeat() {
296
- if (this.#heartbeat === null)
297
- return;
298
- (this.#options.clearInterval ?? (timer => clearInterval(timer)))(this.#heartbeat);
299
- this.#heartbeat = null;
300
- }
301
- #supports(feature) {
302
- return this.#features.has("crash-recovery") || this.#features.has(feature);
303
- }
304
- #fail(retry = true) {
305
- const transport = this.#transport;
306
- this.#stopHeartbeat();
307
- this.#available = false;
308
- this.#connected = false;
309
- this.#features.clear();
310
- this.#attachment = null;
311
- this.#transport = null;
312
- transport?.destroy();
313
- this.#startWaiter?.(false);
314
- this.#startWaiter = null;
315
- for (const resolvePromise of this.#pending.values())
316
- resolvePromise(false);
317
- this.#pending.clear();
318
- if (retry && !this.#closed && this.#retry === null) {
319
- this.#retry = setTimeout(() => {
320
- this.#retry = null;
321
- void this.start().then(connected => { if (!connected)
322
- this.#fail(); });
323
- }, 250);
324
- this.#retry.unref();
325
- }
326
- }
327
- }
@@ -1,12 +0,0 @@
1
- export interface ContinuityOptions {
2
- readonly releaseRoot: string;
3
- readonly dataDir: string;
4
- readonly profileRoot: string;
5
- readonly runtimeDir: string;
6
- readonly environment: NodeJS.ProcessEnv;
7
- readonly inspect?: (options: Omit<ContinuityOptions, "inspect">) => Promise<string>;
8
- }
9
- /** Activation authority requires a stable authenticated source-contract set, never an idle Agent. */
10
- export declare function assertResidentContinuity(options: ContinuityOptions): Promise<void>;
11
- /** Native inspection/import is read-only toward execution and never starts or stops a source. */
12
- export declare function inspectResidentContinuity(options: Omit<ContinuityOptions, "inspect">): Promise<string>;
@@ -1,63 +0,0 @@
1
- import { readdir, readFile } from "node:fs/promises";
2
- import { resolve } from "node:path";
3
- import { RUNTIME_CONTROL_API } from "./runtime-control.js";
4
- import { runBoundedHostCommand } from "./bounded-host-command.js";
5
- import { resolveTerminalHostEntryPath, resolveTerminalHostPath } from "./ensure-terminal-host.js";
6
- import { verifyTerminalHostArtifact } from "./terminal-host-artifact.js";
7
- /** Activation authority requires a stable authenticated source-contract set, never an idle Agent. */
8
- export async function assertResidentContinuity(options) {
9
- const { inspect = inspectResidentContinuity, ...context } = options;
10
- const first = await inspect(context);
11
- const second = await inspect(context);
12
- if (first !== second && second !== await inspect(context)) {
13
- throw new Error("Resident workspace changed during update readiness");
14
- }
15
- }
16
- /** Native inspection/import is read-only toward execution and never starts or stops a source. */
17
- export async function inspectResidentContinuity(options) {
18
- let hasRecords = false;
19
- for (const directory of ["tabs", "resident-workspaces"]) {
20
- try {
21
- hasRecords ||= (await readdir(resolve(options.dataDir, directory))).length > 0;
22
- }
23
- catch (error) {
24
- if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
25
- throw new Error("Resident workspace discovery is unavailable; update activation was refused.");
26
- }
27
- }
28
- }
29
- if (!hasRecords)
30
- return "empty";
31
- const manifest = JSON.parse(await readFile(resolve(options.releaseRoot, "package.json"), "utf8"));
32
- const contracts = manifest.residentControlContracts;
33
- if (!Array.isArray(contracts)
34
- || ![RUNTIME_CONTROL_API, "resident-workspace-v1"].every(contract => contracts.includes(contract))) {
35
- throw new Error("Candidate does not preserve the stable resident control and workspace contracts; activation was refused.");
36
- }
37
- const addon = resolveTerminalHostPath(options.releaseRoot, {}, process.platform, process.arch);
38
- await verifyTerminalHostArtifact(addon, process.platform, process.arch);
39
- const result = await runBoundedHostCommand({ executable: process.execPath, entry: resolveTerminalHostEntryPath(options.releaseRoot) }, [
40
- "workspace-check", "--profile", options.profileRoot,
41
- "--data-dir", options.dataDir, "--runtime-dir", options.runtimeDir,
42
- ], { label: "resident continuity check", maxStdoutBytes: 4096, timeoutMs: 8_000, environment: options.environment });
43
- const unverified = new Error(continuityFailure(result.stderr));
44
- let report;
45
- try {
46
- report = JSON.parse(result.stdout.trim());
47
- }
48
- catch {
49
- throw unverified;
50
- }
51
- if (result.code !== 0 || report.schema !== "resident-workspace-check-v1" || report.compatible !== true
52
- || typeof report.fingerprint !== "string" || !/^[a-f0-9]{64}$/u.test(report.fingerprint)) {
53
- throw unverified;
54
- }
55
- return report.fingerprint;
56
- }
57
- /** Names the native reason when the host reported one, without the host's own prefix. */
58
- function continuityFailure(diagnostic) {
59
- const reason = diagnostic.replace(/^a1-terminal-host:\s*/u, "").replace(/[.\s]+$/u, "");
60
- return reason.length > 0
61
- ? `Resident control compatibility could not be verified: ${reason}`
62
- : "Resident control compatibility could not be verified";
63
- }
@@ -1,28 +0,0 @@
1
- import type { MaintenanceReport } from "./maintenance.js";
2
- export declare const DOCTOR_MAX_BYTES: number;
3
- export interface DoctorOptions {
4
- /** The profile's resident state directory, as reported by the terminal host. */
5
- readonly stateDir: string;
6
- readonly hostStatus: MaintenanceReport;
7
- readonly releaseRoots: readonly string[];
8
- readonly settings: {
9
- readonly tabsAutoName: boolean;
10
- };
11
- readonly home?: string;
12
- readonly platform?: NodeJS.Platform;
13
- readonly architecture?: string;
14
- readonly now?: Date;
15
- readonly maxBytes?: number;
16
- }
17
- export interface DoctorBundle {
18
- readonly path: string;
19
- readonly bytes: number;
20
- readonly dropped: readonly string[];
21
- }
22
- /**
23
- * Writes an owner-only diagnostic bundle by allowlist: structured logs, crash records, host
24
- * status, a redacted registry, the owner marker without secrets, artifact verification, platform
25
- * facts, and the Tabs settings. Secrets, tokens, environment values, prompt journals, drafts,
26
- * last screens, the private child-stderr sink, and terminal content are never read.
27
- */
28
- export declare function writeDoctorBundle(options: DoctorOptions): Promise<DoctorBundle>;
@@ -1,166 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
3
- import { homedir, release as osRelease } from "node:os";
4
- import { basename, dirname, resolve, sep } from "node:path";
5
- import { resolveTerminalHostPath } from "./ensure-terminal-host.js";
6
- import { TERMINAL_HOST_MANIFEST_FILENAME, verifyTerminalHostArtifact } from "./terminal-host-artifact.js";
7
- import { encodeZip } from "./zip-archive.js";
8
- export const DOCTOR_MAX_BYTES = 25 * 1024 * 1024;
9
- const LOG_NAME = /^terminal-host-[a-z0-9-]+\.log(?:\.(\d{1,2}))?$/u;
10
- const CRASH_NAME = /^crash-[a-z0-9-]+\.json$/u;
11
- /**
12
- * Writes an owner-only diagnostic bundle by allowlist: structured logs, crash records, host
13
- * status, a redacted registry, the owner marker without secrets, artifact verification, platform
14
- * facts, and the Tabs settings. Secrets, tokens, environment values, prompt journals, drafts,
15
- * last screens, the private child-stderr sink, and terminal content are never read.
16
- */
17
- export async function writeDoctorBundle(options) {
18
- const home = options.home ?? homedir();
19
- const redact = (value) => homeRelative(value, home);
20
- const now = options.now ?? new Date();
21
- const maxBytes = options.maxBytes ?? DOCTOR_MAX_BYTES;
22
- const diagnostics = resolve(options.stateDir, "diagnostics");
23
- const names = await readdir(diagnostics).catch(() => []);
24
- const fixed = [
25
- json("host-status.json", redactHostStatus(options.hostStatus, redact)),
26
- json("registry.json", await redactedRegistry(resolve(options.stateDir, "registry.json"), redact)),
27
- json("server-marker.json", await redactedMarker(resolve(options.stateDir, "server.json"), redact)),
28
- json("artifacts.json", await artifactFacts(options.releaseRoots, options.platform ?? process.platform, options.architecture ?? process.arch, redact)),
29
- json("platform.json", {
30
- platform: options.platform ?? process.platform,
31
- architecture: options.architecture ?? process.arch,
32
- osRelease: osRelease(),
33
- node: process.version,
34
- detachmentMode: options.hostStatus.result?.detachmentMode ?? null,
35
- }),
36
- json("settings.json", { tabsAutoName: options.settings.tabsAutoName }),
37
- ];
38
- const crashes = [];
39
- for (const name of names.filter(name => CRASH_NAME.test(name)).sort()) {
40
- crashes.push({ name: `crashes/${name}`, data: await readFile(resolve(diagnostics, name)) });
41
- }
42
- // Rationale: when the bundle would exceed its cap, the oldest log generations go first.
43
- const logs = names
44
- .filter(name => LOG_NAME.test(name))
45
- .map(name => ({ name, generation: Number(LOG_NAME.exec(name)?.[1] ?? 0) }))
46
- .sort((left, right) => left.generation - right.generation || left.name.localeCompare(right.name));
47
- const dropped = [];
48
- const included = [...fixed, ...crashes];
49
- let budget = maxBytes - 64 * 1024 - included.reduce((total, entry) => total + entry.data.length, 0);
50
- for (const log of logs) {
51
- const size = (await stat(resolve(diagnostics, log.name))).size;
52
- if (size > budget) {
53
- dropped.push(log.name);
54
- continue;
55
- }
56
- budget -= size;
57
- included.push({ name: `logs/${log.name}`, data: await readFile(resolve(diagnostics, log.name)) });
58
- }
59
- const manifest = [
60
- "a1 tabs doctor bundle",
61
- `created: ${now.toISOString()}`,
62
- ...included.map(entry => `included: ${entry.name}`),
63
- ...dropped.map(name => `dropped to stay within ${maxBytes} bytes: logs/${name}`),
64
- "",
65
- ].join("\n");
66
- const archive = encodeZip([{ name: "manifest.txt", data: Buffer.from(manifest, "utf8") }, ...included], now);
67
- const directory = resolve(options.stateDir, "doctor");
68
- await mkdir(directory, { recursive: true, mode: 0o700 });
69
- const path = resolve(directory, `a1-tabs-doctor-${now.toISOString().replace(/[:.]/gu, "-")}.zip`);
70
- await writeFile(path, archive, { mode: 0o600, flag: "wx" });
71
- return { path, bytes: archive.length, dropped };
72
- }
73
- function json(name, value) {
74
- return { name, data: Buffer.from(`${JSON.stringify(value, null, 2)}\n`, "utf8") };
75
- }
76
- function stableHash(value) {
77
- return createHash("sha256").update(value).digest("hex").slice(0, 16);
78
- }
79
- function homeRelative(value, home) {
80
- const normalized = resolve(value);
81
- const root = resolve(home);
82
- const comparable = (path) => process.platform === "win32" ? path.toLowerCase() : path;
83
- if (comparable(normalized) === comparable(root))
84
- return "~";
85
- return comparable(normalized).startsWith(comparable(`${root}${sep}`)) ? `~${normalized.slice(root.length).replaceAll("\\", "/")}` : normalized;
86
- }
87
- function redactHostStatus(report, redact) {
88
- const result = report.result ? { ...report.result } : undefined;
89
- if (result && Array.isArray(result.logs))
90
- result.logs = result.logs.map(path => typeof path === "string" ? basename(path) : null);
91
- if (result && typeof result.release === "string")
92
- result.release = redact(result.release);
93
- return {
94
- host: report.host,
95
- pid: report.pid ?? null,
96
- exitCode: report.exitCode,
97
- result: result ?? null,
98
- };
99
- }
100
- async function redactedRegistry(path, redact) {
101
- let document;
102
- try {
103
- document = JSON.parse(await readFile(path, "utf8"));
104
- }
105
- catch (error) {
106
- return { readable: false, reason: error instanceof Error && "code" in error ? String(error.code) : "unparseable" };
107
- }
108
- const tabs = Array.isArray(document.tabs) ? document.tabs : [];
109
- const text = (value) => typeof value === "string" ? value : null;
110
- return {
111
- readable: true,
112
- registryRevision: document.registryRevision ?? null,
113
- epoch: document.epoch ?? null,
114
- tabs: tabs.map(tab => {
115
- const sessionFile = text(tab.sessionFile);
116
- return {
117
- tabId: text(tab.tabId),
118
- // Security: names can be generated from prompts, so only a stable hash is kept.
119
- nameHash: text(tab.displayName) === null ? null : stableHash(text(tab.displayName)),
120
- nameSource: text(tab.nameSource),
121
- order: tab.order ?? null,
122
- cwd: text(tab.cwd) === null ? null : redact(text(tab.cwd)),
123
- sessionDirectory: sessionFile === null ? null : redact(dirname(sessionFile)),
124
- sessionFileHash: sessionFile === null ? null : stableHash(basename(sessionFile)),
125
- desired: text(tab.desired),
126
- lifecycle: text(tab.lifecycle),
127
- incarnation: tab.incarnation ?? null,
128
- holderPid: tab.holderPid ?? null,
129
- childPid: tab.childPid ?? null,
130
- release: text(tab.release) === null ? null : redact(text(tab.release)),
131
- lastExit: text(tab.lastExit),
132
- restarts: tab.restarts ?? null,
133
- };
134
- }),
135
- };
136
- }
137
- async function redactedMarker(path, redact) {
138
- try {
139
- const marker = JSON.parse(await readFile(path, "utf8"));
140
- return {
141
- present: true,
142
- pid: marker.pid ?? null,
143
- generation: marker.generation ?? null,
144
- verified: marker.verified ?? null,
145
- detachmentMode: marker.detachmentMode ?? null,
146
- releaseRoot: typeof marker.releaseRoot === "string" ? redact(marker.releaseRoot) : null,
147
- };
148
- }
149
- catch {
150
- return { present: false };
151
- }
152
- }
153
- async function artifactFacts(roots, platform, architecture, redact) {
154
- const facts = [];
155
- for (const root of roots) {
156
- const addon = resolveTerminalHostPath(root, {}, platform, architecture);
157
- const manifest = await readFile(resolve(dirname(addon), TERMINAL_HOST_MANIFEST_FILENAME), "utf8")
158
- .then(text => JSON.parse(text))
159
- .catch(() => null);
160
- const verification = await verifyTerminalHostArtifact(addon, platform, architecture)
161
- .then(() => "verified")
162
- .catch((error) => error instanceof Error && "code" in error ? String(error.code) : "failed");
163
- facts.push({ releaseRoot: redact(root), verification, manifest });
164
- }
165
- return facts;
166
- }
@@ -1,27 +0,0 @@
1
- import { ResidentTabFaultInjection } from "./fault-injection.js";
2
- export interface DraftCheckpointState {
3
- readonly text: string;
4
- readonly savedAt: string;
5
- }
6
- export interface DraftCheckpointOptions {
7
- readonly intervalMs?: number;
8
- readonly maximumDirtyMs?: number;
9
- readonly faults?: ResidentTabFaultInjection;
10
- readonly now?: () => number;
11
- readonly onDegraded?: (degraded: boolean) => void;
12
- readonly write?: (path: string, text: string) => Promise<void>;
13
- readonly move?: (from: string, to: string) => Promise<void>;
14
- readonly schedule?: (callback: () => void | Promise<void>, delayMs: number) => unknown;
15
- readonly cancel?: (timer: unknown) => void;
16
- }
17
- /** Periodic rather than inactivity-debounced: continuous input still checkpoints every interval. */
18
- export declare class DraftCheckpointer {
19
- #private;
20
- readonly path: string;
21
- constructor(path: string, options?: DraftCheckpointOptions);
22
- get degraded(): boolean;
23
- change(text: string): void;
24
- restore(): Promise<DraftCheckpointState | null>;
25
- flush(): Promise<void>;
26
- close(): Promise<void>;
27
- }