@code-yeongyu/senpi 2026.9.24-3 → 2026.9.25

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 (256) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/bundle/chunks/{app-server-command-OTRHYRIB.js → app-server-command-RB6QUPRI.js} +1 -1
  3. package/dist/bundle/chunks/{chunk-UM43CBL4.js → chunk-JJ3NJZBD.js} +118 -111
  4. package/dist/bundle/chunks/chunk-SGYEOIOJ.js +8 -0
  5. package/dist/bundle/chunks/chunk-YS5YEX4S.js +2 -0
  6. package/dist/bundle/chunks/{cli-main-TX6I4X4F.js → cli-main-KO53KYDN.js} +1 -1
  7. package/dist/bundle/chunks/{interactive-mode-UI5Q6FGY.js → interactive-mode-ABDNLJSI.js} +1 -1
  8. package/dist/bundle/chunks/{multi-session-host-D6HMI3RQ.js → multi-session-host-JV3MNWXZ.js} +1 -1
  9. package/dist/bundle/chunks/{package-manager-cli-3UWH3ZZS.js → package-manager-cli-ZYYAVCXU.js} +1 -1
  10. package/dist/bundle/chunks/{rpc-mode-LXIZHJSJ.js → rpc-mode-Q2OUJURB.js} +1 -1
  11. package/dist/bundle/chunks/runtime-session-XBT646O5.js +2 -0
  12. package/dist/bundle/chunks/session-worker.js +184 -177
  13. package/dist/bundle/cli.js +1 -1
  14. package/dist/bundle/index.js +1 -1
  15. package/dist/bundle/rpc-entry.js +1 -1
  16. package/dist/core/agent-session.d.ts.map +1 -1
  17. package/dist/core/agent-session.js +1 -1
  18. package/dist/core/agent-session.js.map +1 -1
  19. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts +7 -0
  20. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts.map +1 -1
  21. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js +23 -4
  22. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js.map +1 -1
  23. package/dist/core/extensions/builtin/terminal/durable-command.d.ts +11 -16
  24. package/dist/core/extensions/builtin/terminal/durable-command.d.ts.map +1 -1
  25. package/dist/core/extensions/builtin/terminal/durable-command.js +97 -43
  26. package/dist/core/extensions/builtin/terminal/durable-command.js.map +1 -1
  27. package/dist/core/extensions/builtin/terminal/durable-file.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/terminal/durable-file.js +11 -4
  29. package/dist/core/extensions/builtin/terminal/durable-file.js.map +1 -1
  30. package/dist/core/extensions/builtin/terminal/extension-state.d.ts +26 -0
  31. package/dist/core/extensions/builtin/terminal/extension-state.d.ts.map +1 -0
  32. package/dist/core/extensions/builtin/terminal/extension-state.js +151 -0
  33. package/dist/core/extensions/builtin/terminal/extension-state.js.map +1 -0
  34. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/terminal/extension.js +32 -308
  36. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  37. package/dist/core/extensions/builtin/terminal/lease-file.d.ts +52 -0
  38. package/dist/core/extensions/builtin/terminal/lease-file.d.ts.map +1 -0
  39. package/dist/core/extensions/builtin/terminal/lease-file.js +205 -0
  40. package/dist/core/extensions/builtin/terminal/lease-file.js.map +1 -0
  41. package/dist/core/extensions/builtin/terminal/lease-keeper.d.ts +33 -0
  42. package/dist/core/extensions/builtin/terminal/lease-keeper.d.ts.map +1 -0
  43. package/dist/core/extensions/builtin/terminal/lease-keeper.js +110 -0
  44. package/dist/core/extensions/builtin/terminal/lease-keeper.js.map +1 -0
  45. package/dist/core/extensions/builtin/terminal/manager.d.ts +1 -0
  46. package/dist/core/extensions/builtin/terminal/manager.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/terminal/manager.js +6 -0
  48. package/dist/core/extensions/builtin/terminal/manager.js.map +1 -1
  49. package/dist/core/extensions/builtin/terminal/manifest-lease.d.ts +48 -4
  50. package/dist/core/extensions/builtin/terminal/manifest-lease.d.ts.map +1 -1
  51. package/dist/core/extensions/builtin/terminal/manifest-lease.js +141 -59
  52. package/dist/core/extensions/builtin/terminal/manifest-lease.js.map +1 -1
  53. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +2 -0
  54. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  55. package/dist/core/extensions/builtin/terminal/monitor-registry.js +15 -10
  56. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  57. package/dist/core/extensions/builtin/terminal/monitor-state-dir.d.ts +11 -0
  58. package/dist/core/extensions/builtin/terminal/monitor-state-dir.d.ts.map +1 -0
  59. package/dist/core/extensions/builtin/terminal/monitor-state-dir.js +28 -0
  60. package/dist/core/extensions/builtin/terminal/monitor-state-dir.js.map +1 -0
  61. package/dist/core/extensions/builtin/terminal/orphan-reaper.d.ts +41 -0
  62. package/dist/core/extensions/builtin/terminal/orphan-reaper.d.ts.map +1 -0
  63. package/dist/core/extensions/builtin/terminal/orphan-reaper.js +131 -0
  64. package/dist/core/extensions/builtin/terminal/orphan-reaper.js.map +1 -0
  65. package/dist/core/extensions/builtin/terminal/process-identity.d.ts +21 -0
  66. package/dist/core/extensions/builtin/terminal/process-identity.d.ts.map +1 -0
  67. package/dist/core/extensions/builtin/terminal/process-identity.js +34 -0
  68. package/dist/core/extensions/builtin/terminal/process-identity.js.map +1 -0
  69. package/dist/core/extensions/builtin/terminal/process-start-probe.d.ts +6 -0
  70. package/dist/core/extensions/builtin/terminal/process-start-probe.d.ts.map +1 -0
  71. package/dist/core/extensions/builtin/terminal/process-start-probe.js +60 -0
  72. package/dist/core/extensions/builtin/terminal/process-start-probe.js.map +1 -0
  73. package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
  74. package/dist/core/extensions/builtin/terminal/prompt.js +8 -4
  75. package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
  76. package/dist/core/extensions/builtin/terminal/restore-digest.d.ts +54 -0
  77. package/dist/core/extensions/builtin/terminal/restore-digest.d.ts.map +1 -0
  78. package/dist/core/extensions/builtin/terminal/restore-digest.js +133 -0
  79. package/dist/core/extensions/builtin/terminal/restore-digest.js.map +1 -0
  80. package/dist/core/extensions/builtin/terminal/restore-session.d.ts +56 -0
  81. package/dist/core/extensions/builtin/terminal/restore-session.d.ts.map +1 -0
  82. package/dist/core/extensions/builtin/terminal/restore-session.js +238 -0
  83. package/dist/core/extensions/builtin/terminal/restore-session.js.map +1 -0
  84. package/dist/core/extensions/builtin/terminal/restore.d.ts +52 -19
  85. package/dist/core/extensions/builtin/terminal/restore.d.ts.map +1 -1
  86. package/dist/core/extensions/builtin/terminal/restore.js +63 -138
  87. package/dist/core/extensions/builtin/terminal/restore.js.map +1 -1
  88. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +5 -0
  89. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  90. package/dist/core/extensions/builtin/terminal/runtime-session.js +17 -0
  91. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  92. package/dist/core/extensions/builtin/terminal/session-activity.d.ts +8 -0
  93. package/dist/core/extensions/builtin/terminal/session-activity.d.ts.map +1 -0
  94. package/dist/core/extensions/builtin/terminal/session-activity.js +41 -0
  95. package/dist/core/extensions/builtin/terminal/session-activity.js.map +1 -0
  96. package/dist/core/extensions/builtin/terminal/shared.d.ts +14 -0
  97. package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
  98. package/dist/core/extensions/builtin/terminal/shared.js +14 -0
  99. package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
  100. package/dist/core/extensions/builtin/terminal/terminal-manifest-model.d.ts +8 -0
  101. package/dist/core/extensions/builtin/terminal/terminal-manifest-model.d.ts.map +1 -1
  102. package/dist/core/extensions/builtin/terminal/terminal-manifest-model.js.map +1 -1
  103. package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.d.ts +15 -0
  104. package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.d.ts.map +1 -0
  105. package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.js +148 -0
  106. package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.js.map +1 -0
  107. package/dist/core/extensions/builtin/terminal/terminal-manifest.d.ts +15 -2
  108. package/dist/core/extensions/builtin/terminal/terminal-manifest.d.ts.map +1 -1
  109. package/dist/core/extensions/builtin/terminal/terminal-manifest.js +62 -11
  110. package/dist/core/extensions/builtin/terminal/terminal-manifest.js.map +1 -1
  111. package/dist/core/extensions/builtin/terminal/terminal-state-gc.d.ts +17 -0
  112. package/dist/core/extensions/builtin/terminal/terminal-state-gc.d.ts.map +1 -0
  113. package/dist/core/extensions/builtin/terminal/terminal-state-gc.js +81 -0
  114. package/dist/core/extensions/builtin/terminal/terminal-state-gc.js.map +1 -0
  115. package/dist/core/extensions/builtin/terminal/tools/context.d.ts +5 -0
  116. package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
  117. package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
  118. package/dist/core/extensions/builtin/terminal/tools/kill-bash.d.ts.map +1 -1
  119. package/dist/core/extensions/builtin/terminal/tools/kill-bash.js +16 -1
  120. package/dist/core/extensions/builtin/terminal/tools/kill-bash.js.map +1 -1
  121. package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.d.ts +27 -0
  122. package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.d.ts.map +1 -0
  123. package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.js +75 -0
  124. package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.js.map +1 -0
  125. package/dist/core/extensions/builtin/terminal/tools/monitor-schema.d.ts +35 -0
  126. package/dist/core/extensions/builtin/terminal/tools/monitor-schema.d.ts.map +1 -0
  127. package/dist/core/extensions/builtin/terminal/tools/monitor-schema.js +67 -0
  128. package/dist/core/extensions/builtin/terminal/tools/monitor-schema.js.map +1 -0
  129. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +14 -35
  130. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
  131. package/dist/core/extensions/builtin/terminal/tools/monitor.js +30 -110
  132. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
  133. package/dist/core/extensions/builtin/todotools/first-turn.d.ts +7 -6
  134. package/dist/core/extensions/builtin/todotools/first-turn.d.ts.map +1 -1
  135. package/dist/core/extensions/builtin/todotools/first-turn.js +8 -8
  136. package/dist/core/extensions/builtin/todotools/first-turn.js.map +1 -1
  137. package/dist/core/extensions/builtin/todotools/index.js +1 -1
  138. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  139. package/dist/core/extensions/builtin/todotools/todo-format.js +1 -1
  140. package/dist/core/extensions/builtin/todotools/todo-format.js.map +1 -1
  141. package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.d.ts.map +1 -1
  142. package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js +4 -0
  143. package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js.map +1 -1
  144. package/dist/core/extensions/builtin/ttsr/prompts.js +1 -1
  145. package/dist/core/extensions/builtin/ttsr/prompts.js.map +1 -1
  146. package/dist/core/extensions/runner.d.ts +1 -0
  147. package/dist/core/extensions/runner.d.ts.map +1 -1
  148. package/dist/core/extensions/runner.js +1 -0
  149. package/dist/core/extensions/runner.js.map +1 -1
  150. package/dist/core/extensions/types.d.ts +6 -0
  151. package/dist/core/extensions/types.d.ts.map +1 -1
  152. package/dist/core/extensions/types.js.map +1 -1
  153. package/docs/extensions.md +2 -0
  154. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
  155. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  156. package/node_modules/@code-yeongyu/senpi-desktop-engine/README.md +31 -0
  157. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.d.ts +38 -0
  158. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.d.ts.map +1 -0
  159. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.js +117 -0
  160. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.js.map +1 -0
  161. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.d.ts +3 -0
  162. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.d.ts.map +1 -0
  163. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.js +3 -0
  164. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.js.map +1 -0
  165. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.d.ts +42 -0
  166. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.d.ts.map +1 -0
  167. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.js +79 -0
  168. package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.js.map +1 -0
  169. package/node_modules/@code-yeongyu/senpi-desktop-engine/native/check-prebuild-fresh.mjs +160 -0
  170. package/node_modules/@code-yeongyu/senpi-desktop-engine/native/index.d.ts +20 -0
  171. package/node_modules/@code-yeongyu/senpi-desktop-engine/native/index.js +23 -0
  172. package/node_modules/@code-yeongyu/senpi-desktop-engine/native/prebuilds/darwin-arm64/senpi-desktop-engine +0 -0
  173. package/node_modules/@code-yeongyu/senpi-desktop-engine/package.json +53 -0
  174. package/node_modules/@code-yeongyu/senpi-desktop-prelude/README.md +20 -0
  175. package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.d.ts +2 -0
  176. package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.d.ts.map +1 -0
  177. package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.js +2 -0
  178. package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.js.map +1 -0
  179. package/node_modules/@code-yeongyu/senpi-desktop-prelude/package.json +44 -0
  180. package/node_modules/@code-yeongyu/senpi-desktop-protocol/README.md +20 -0
  181. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.d.ts +38 -0
  182. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.d.ts.map +1 -0
  183. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.js +2 -0
  184. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.js.map +1 -0
  185. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.d.ts +28 -0
  186. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.d.ts.map +1 -0
  187. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.js +102 -0
  188. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.js.map +1 -0
  189. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.d.ts +14 -0
  190. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.d.ts.map +1 -0
  191. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.js +71 -0
  192. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.js.map +1 -0
  193. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.d.ts +7 -0
  194. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.d.ts.map +1 -0
  195. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.js +4 -0
  196. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.js.map +1 -0
  197. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.d.ts +66 -0
  198. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.d.ts.map +1 -0
  199. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.js +8 -0
  200. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.js.map +1 -0
  201. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.d.ts +44 -0
  202. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.d.ts.map +1 -0
  203. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.js +2 -0
  204. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.js.map +1 -0
  205. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.d.ts +59 -0
  206. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.d.ts.map +1 -0
  207. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.js +2 -0
  208. package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.js.map +1 -0
  209. package/node_modules/@code-yeongyu/senpi-desktop-protocol/package.json +45 -0
  210. package/node_modules/@code-yeongyu/senpi-desktop-service/README.md +27 -0
  211. package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.d.ts +2 -0
  212. package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.d.ts.map +1 -0
  213. package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.js +2 -0
  214. package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.js.map +1 -0
  215. package/node_modules/@code-yeongyu/senpi-desktop-service/package.json +44 -0
  216. package/node_modules/@code-yeongyu/senpi-desktop-tool/README.md +20 -0
  217. package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.d.ts +2 -0
  218. package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.d.ts.map +1 -0
  219. package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.js +2 -0
  220. package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.js.map +1 -0
  221. package/node_modules/@code-yeongyu/senpi-desktop-tool/package.json +44 -0
  222. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  223. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cerebras.json +1 -1
  225. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  227. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  228. package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts +2 -0
  229. package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts.map +1 -1
  230. package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js +6 -0
  231. package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js.map +1 -1
  232. package/node_modules/@earendil-works/pi-pty/dist/session-bun.d.ts +1 -0
  233. package/node_modules/@earendil-works/pi-pty/dist/session-bun.d.ts.map +1 -1
  234. package/node_modules/@earendil-works/pi-pty/dist/session-bun.js +1 -0
  235. package/node_modules/@earendil-works/pi-pty/dist/session-bun.js.map +1 -1
  236. package/node_modules/@earendil-works/pi-pty/dist/session-native.js +5 -0
  237. package/node_modules/@earendil-works/pi-pty/dist/session-native.js.map +1 -1
  238. package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.d.ts +11 -0
  239. package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.d.ts.map +1 -0
  240. package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.js +24 -0
  241. package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.js.map +1 -0
  242. package/node_modules/@earendil-works/pi-pty/dist/session-types.d.ts +2 -0
  243. package/node_modules/@earendil-works/pi-pty/dist/session-types.d.ts.map +1 -1
  244. package/node_modules/@earendil-works/pi-pty/dist/session-types.js.map +1 -1
  245. package/node_modules/@earendil-works/pi-pty/dist/session.d.ts +4 -5
  246. package/node_modules/@earendil-works/pi-pty/dist/session.d.ts.map +1 -1
  247. package/node_modules/@earendil-works/pi-pty/dist/session.js +11 -16
  248. package/node_modules/@earendil-works/pi-pty/dist/session.js.map +1 -1
  249. package/node_modules/@earendil-works/pi-pty/native/prebuilds/darwin-arm64/senpi_pty.darwin-arm64.node +0 -0
  250. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  251. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  252. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  253. package/package.json +22 -7
  254. package/dist/bundle/chunks/chunk-GFUZPFHN.js +0 -2
  255. package/dist/bundle/chunks/chunk-JBOV6VNK.js +0 -8
  256. package/dist/bundle/chunks/runtime-session-F3EXC44D.js +0 -2
@@ -42,10 +42,14 @@ const DEFAULT_RESTORED_WATCH_MS = 300_000;
42
42
  */
43
43
  export function createCheckpointedFileRestoreHandler(deps) {
44
44
  const now = deps.now ?? Date.now;
45
- return async (monitor) => {
45
+ return async (monitor, context) => {
46
46
  if (monitor.runtimeKind !== "file" || monitor.path === undefined || monitor.cwd === undefined) {
47
47
  return lost(`monitor ${monitor.monitorId} is not a restorable file watch`);
48
48
  }
49
+ const ephemeral = monitor.durabilityClass === "ephemeral";
50
+ if (ephemeral && context.remainingMs === undefined) {
51
+ return lost(`monitor ${monitor.monitorId} has no time left on its deadline`);
52
+ }
49
53
  const saved = monitor.lastCheckpoint;
50
54
  if (saved === null)
51
55
  return lost(`monitor ${monitor.monitorId} has no checkpoint to compare against`);
@@ -63,14 +67,17 @@ export function createCheckpointedFileRestoreHandler(deps) {
63
67
  }
64
68
  let runtimeId;
65
69
  try {
70
+ const startedAt = now();
71
+ // An ephemeral watch resumes with only the time it had left; a durable one has no deadline.
72
+ const lifetime = ephemeral && context.remainingMs !== undefined
73
+ ? { persistent: false, deadlineMs: startedAt + context.remainingMs, timeoutMs: context.remainingMs }
74
+ : { persistent: true, deadlineMs: null, timeoutMs: remainingMs(monitor, startedAt) };
66
75
  const registered = await deps.registry.registerFile({
67
76
  description: monitor.description,
68
77
  path: monitor.path,
69
78
  monitorId: monitor.monitorId,
70
- persistent: true,
71
- deadlineMs: null,
79
+ ...lifetime,
72
80
  event: monitor.event ?? "create",
73
- timeoutMs: remainingMs(monitor, now()),
74
81
  cwd: monitor.cwd,
75
82
  // Preserve the parent approved at permission time: registerFile re-checks it.
76
83
  ...(monitor.approvedParent !== undefined ? { approvedParent: monitor.approvedParent } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"durable-file.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/durable-file.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The `checkpointed-file` durability class: the restore handler that makes a persistent file\n * watch survive a restart. On create the monitor tool persists the registry's own identity\n * tuple (dev/ino/size/mtimeMs/digest/present) as the manifest checkpoint; here that checkpoint\n * is compared ONCE against the file as it is now, and any change that happened while the process\n * was gone is reported as EXACTLY ONE line through the registry's normal event sink — so the\n * notifier's coalescing and wake budget apply to it exactly as they do to a live watch event.\n *\n * `digest` is load-bearing: without it a same-size, same-mtime rewrite is invisible across a restart.\n */\n\nimport { stat } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { MonitorRegistry } from \"./monitor-registry.ts\";\nimport type { RestoreHandler, RestoreHandlerResult } from \"./restore.ts\";\nimport type { ManifestMonitor, TerminalManifestCheckpoint, TerminalManifestWriter } from \"./terminal-manifest.ts\";\n\n/**\n * What a detached change is reported as. `null` means the file is byte-identical to the checkpoint;\n * `\"gone\"` means it existed at checkpoint time and does not now, which is not restorable.\n */\nexport type DetachedChange = \"created\" | \"replaced\" | \"modified\" | \"gone\" | null;\n\n/** Only what the handler needs, so a caller can hand it a narrower registry/writer. */\nexport interface CheckpointedFileRestoreDeps {\n\treadonly registry: Pick<MonitorRegistry, \"registerFile\" | \"fileCheckpoint\" | \"emitFileLine\" | \"stopFile\">;\n\t/** Optional: the durable checkpoint is re-persisted through the writer when one is bound. */\n\treadonly writer?: Pick<TerminalManifestWriter, \"scheduleCheckpoint\">;\n\t/** Optional: re-bind the stable `mon_` id to its fresh runtime id so kill_bash keeps resolving it. */\n\treadonly bindMonitorId?: (monitorId: string, runtimeId: string) => void;\n\treadonly now?: () => number;\n}\n\n/** The live tuple `registry.fileCheckpoint` returns; identical in shape to the persisted checkpoint. */\ntype LiveCheckpoint = NonNullable<ReturnType<MonitorRegistry[\"fileCheckpoint\"]>>;\n\n/**\n * The single comparison, run once per restore. `created` and `replaced` outrank `modified`:\n * an absent→present transition or a new dev/ino is a stronger statement about the same file.\n */\nexport function classifyDetachedChange(saved: TerminalManifestCheckpoint, live: LiveCheckpoint): DetachedChange {\n\tif (!saved.present) return live.present ? \"created\" : null;\n\tif (!live.present) return \"gone\";\n\tif (live.dev !== saved.dev || live.ino !== saved.ino) return \"replaced\";\n\tif (live.mtimeMs !== saved.mtimeMs || live.size !== saved.size || live.digest !== saved.digest) return \"modified\";\n\treturn null;\n}\n\nfunction lost(reason: string): RestoreHandlerResult {\n\treturn { outcome: \"lost\", reason };\n}\n\n/** Remaining lifetime of a durable watch; a watch with no recorded expiry keeps its default window. */\nfunction remainingMs(monitor: ManifestMonitor, now: number): number {\n\tif (monitor.expiresAt === null) return DEFAULT_RESTORED_WATCH_MS;\n\treturn Math.max(1, monitor.expiresAt - now);\n}\n\nconst DEFAULT_RESTORED_WATCH_MS = 300_000;\n\n/**\n * Build the `checkpointed-file` restore handler. It re-registers the watch under its original\n * `mon_` id and approved parent (so the permission decision still holds), then reports at most\n * one detached-change line. Returns `lost` when the path is gone or unreadable, `restored` otherwise.\n */\nexport function createCheckpointedFileRestoreHandler(deps: CheckpointedFileRestoreDeps): RestoreHandler {\n\tconst now = deps.now ?? Date.now;\n\treturn async (monitor: ManifestMonitor): Promise<RestoreHandlerResult> => {\n\t\tif (monitor.runtimeKind !== \"file\" || monitor.path === undefined || monitor.cwd === undefined) {\n\t\t\treturn lost(`monitor ${monitor.monitorId} is not a restorable file watch`);\n\t\t}\n\t\tconst saved = monitor.lastCheckpoint;\n\t\tif (saved === null) return lost(`monitor ${monitor.monitorId} has no checkpoint to compare against`);\n\t\t// A watch whose file existed at checkpoint time but is gone or unreadable now cannot be\n\t\t// resumed; probe BEFORE re-registering so a lost restore never leaves a live watch behind.\n\t\tif (saved.present) {\n\t\t\ttry {\n\t\t\t\tconst target = await stat(resolve(monitor.cwd, monitor.path));\n\t\t\t\tif (!target.isFile()) return lost(`watched path is no longer a regular file: ${monitor.path}`);\n\t\t\t} catch (error) {\n\t\t\t\treturn lost(`watched path is gone: ${monitor.path} (${error instanceof Error ? error.message : error})`);\n\t\t\t}\n\t\t}\n\n\t\tlet runtimeId: string;\n\t\ttry {\n\t\t\tconst registered = await deps.registry.registerFile({\n\t\t\t\tdescription: monitor.description,\n\t\t\t\tpath: monitor.path,\n\t\t\t\tmonitorId: monitor.monitorId,\n\t\t\t\tpersistent: true,\n\t\t\t\tdeadlineMs: null,\n\t\t\t\tevent: monitor.event ?? \"create\",\n\t\t\t\ttimeoutMs: remainingMs(monitor, now()),\n\t\t\t\tcwd: monitor.cwd,\n\t\t\t\t// Preserve the parent approved at permission time: registerFile re-checks it.\n\t\t\t\t...(monitor.approvedParent !== undefined ? { approvedParent: monitor.approvedParent } : {}),\n\t\t\t\t// The persisted deadline rides through verbatim; a restore never extends it.\n\t\t\t\t...(monitor.expiresAt !== null ? { expiresAt: monitor.expiresAt } : {}),\n\t\t\t});\n\t\t\truntimeId = registered.id;\n\t\t} catch (error) {\n\t\t\treturn lost(`cannot re-watch ${monitor.path}: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\n\t\tconst live = deps.registry.fileCheckpoint(runtimeId);\n\t\tif (live === undefined) return lost(`monitor ${monitor.monitorId} settled before its checkpoint was compared`);\n\n\t\tconst change = classifyDetachedChange(saved, live);\n\t\tif (change === \"gone\") {\n\t\t\t// Lost the race with a deletion between the probe and re-registration: report lost, not a\n\t\t\t// change, and settle the watch just registered so a lost restore leaves nothing behind.\n\t\t\tawait deps.registry.stopFile(runtimeId);\n\t\t\treturn lost(`watched path is gone: ${monitor.path}`);\n\t\t}\n\n\t\tdeps.bindMonitorId?.(monitor.monitorId, runtimeId);\n\t\tif (change !== null) deps.registry.emitFileLine(runtimeId, `changed while detached: ${change} ${monitor.path}`);\n\t\t// Re-checkpoint on every restore: after `replaced` this is the new identity, and otherwise\n\t\t// it re-states the tuple the next restart compares against.\n\t\tdeps.writer?.scheduleCheckpoint(monitor.monitorId, live);\n\t\treturn { outcome: \"restored\" };\n\t};\n}\n"]}
1
+ {"version":3,"file":"durable-file.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/durable-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAiC,EAAE,IAAoB;IAC7F,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IACjC,IAAI,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG;QAAE,OAAO,UAAU,CAAC;IACxE,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;QAAE,OAAO,UAAU,CAAC;IAClH,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,IAAI,CAAC,MAAc;IAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED,uGAAuG;AACvG,SAAS,WAAW,CAAC,OAAwB,EAAE,GAAW;IACzD,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI;QAAE,OAAO,yBAAyB,CAAC;IACjE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,yBAAyB,GAAG,OAAO,CAAC;AAE1C;;;;GAIG;AACH,MAAM,UAAU,oCAAoC,CAAC,IAAiC;IACrF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,OAAO,KAAK,EAAE,OAAwB,EAAE,OAAuB,EAAiC,EAAE;QACjG,IAAI,OAAO,CAAC,WAAW,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC/F,OAAO,IAAI,CAAC,WAAW,OAAO,CAAC,SAAS,iCAAiC,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,KAAK,WAAW,CAAC;QAC1D,IAAI,SAAS,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC,WAAW,OAAO,CAAC,SAAS,mCAAmC,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC;QACrC,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,WAAW,OAAO,CAAC,SAAS,uCAAuC,CAAC,CAAC;QACrG,wFAAwF;QACxF,2FAA2F;QAC3F,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC9D,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;oBAAE,OAAO,IAAI,CAAC,6CAA6C,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAChG,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,IAAI,CAAC,yBAAyB,OAAO,CAAC,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;YAC1G,CAAC;QACF,CAAC;QAED,IAAI,SAAiB,CAAC;QACtB,IAAI,CAAC;YACJ,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;YACxB,4FAA4F;YAC5F,MAAM,QAAQ,GACb,SAAS,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;gBAC7C,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,WAAW,EAAE;gBACpG,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;YACvF,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;gBACnD,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,GAAG,QAAQ;gBACX,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ;gBAChC,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,8EAA8E;gBAC9E,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3F,6EAA6E;gBAC7E,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvE,CAAC,CAAC;YACH,SAAS,GAAG,UAAU,CAAC,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,mBAAmB,OAAO,CAAC,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3G,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QACrD,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,WAAW,OAAO,CAAC,SAAS,6CAA6C,CAAC,CAAC;QAE/G,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACnD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACvB,0FAA0F;YAC1F,wFAAwF;YACxF,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACxC,OAAO,IAAI,CAAC,yBAAyB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACnD,IAAI,MAAM,KAAK,IAAI;YAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,2BAA2B,MAAM,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAChH,2FAA2F;QAC3F,4DAA4D;QAC5D,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACzD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IAChC,CAAC,CAAC;AACH,CAAC","sourcesContent":["/**\n * The `checkpointed-file` durability class: the restore handler that makes a persistent file\n * watch survive a restart. On create the monitor tool persists the registry's own identity\n * tuple (dev/ino/size/mtimeMs/digest/present) as the manifest checkpoint; here that checkpoint\n * is compared ONCE against the file as it is now, and any change that happened while the process\n * was gone is reported as EXACTLY ONE line through the registry's normal event sink — so the\n * notifier's coalescing and wake budget apply to it exactly as they do to a live watch event.\n *\n * `digest` is load-bearing: without it a same-size, same-mtime rewrite is invisible across a restart.\n */\n\nimport { stat } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { MonitorRegistry } from \"./monitor-registry.ts\";\nimport type { RestoreContext, RestoreHandler, RestoreHandlerResult } from \"./restore.ts\";\nimport type { ManifestMonitor, TerminalManifestCheckpoint, TerminalManifestWriter } from \"./terminal-manifest.ts\";\n\n/**\n * What a detached change is reported as. `null` means the file is byte-identical to the checkpoint;\n * `\"gone\"` means it existed at checkpoint time and does not now, which is not restorable.\n */\nexport type DetachedChange = \"created\" | \"replaced\" | \"modified\" | \"gone\" | null;\n\n/** Only what the handler needs, so a caller can hand it a narrower registry/writer. */\nexport interface CheckpointedFileRestoreDeps {\n\treadonly registry: Pick<MonitorRegistry, \"registerFile\" | \"fileCheckpoint\" | \"emitFileLine\" | \"stopFile\">;\n\t/** Optional: the durable checkpoint is re-persisted through the writer when one is bound. */\n\treadonly writer?: Pick<TerminalManifestWriter, \"scheduleCheckpoint\">;\n\t/** Optional: re-bind the stable `mon_` id to its fresh runtime id so kill_bash keeps resolving it. */\n\treadonly bindMonitorId?: (monitorId: string, runtimeId: string) => void;\n\treadonly now?: () => number;\n}\n\n/** The live tuple `registry.fileCheckpoint` returns; identical in shape to the persisted checkpoint. */\ntype LiveCheckpoint = NonNullable<ReturnType<MonitorRegistry[\"fileCheckpoint\"]>>;\n\n/**\n * The single comparison, run once per restore. `created` and `replaced` outrank `modified`:\n * an absent→present transition or a new dev/ino is a stronger statement about the same file.\n */\nexport function classifyDetachedChange(saved: TerminalManifestCheckpoint, live: LiveCheckpoint): DetachedChange {\n\tif (!saved.present) return live.present ? \"created\" : null;\n\tif (!live.present) return \"gone\";\n\tif (live.dev !== saved.dev || live.ino !== saved.ino) return \"replaced\";\n\tif (live.mtimeMs !== saved.mtimeMs || live.size !== saved.size || live.digest !== saved.digest) return \"modified\";\n\treturn null;\n}\n\nfunction lost(reason: string): RestoreHandlerResult {\n\treturn { outcome: \"lost\", reason };\n}\n\n/** Remaining lifetime of a durable watch; a watch with no recorded expiry keeps its default window. */\nfunction remainingMs(monitor: ManifestMonitor, now: number): number {\n\tif (monitor.expiresAt === null) return DEFAULT_RESTORED_WATCH_MS;\n\treturn Math.max(1, monitor.expiresAt - now);\n}\n\nconst DEFAULT_RESTORED_WATCH_MS = 300_000;\n\n/**\n * Build the `checkpointed-file` restore handler. It re-registers the watch under its original\n * `mon_` id and approved parent (so the permission decision still holds), then reports at most\n * one detached-change line. Returns `lost` when the path is gone or unreadable, `restored` otherwise.\n */\nexport function createCheckpointedFileRestoreHandler(deps: CheckpointedFileRestoreDeps): RestoreHandler {\n\tconst now = deps.now ?? Date.now;\n\treturn async (monitor: ManifestMonitor, context: RestoreContext): Promise<RestoreHandlerResult> => {\n\t\tif (monitor.runtimeKind !== \"file\" || monitor.path === undefined || monitor.cwd === undefined) {\n\t\t\treturn lost(`monitor ${monitor.monitorId} is not a restorable file watch`);\n\t\t}\n\t\tconst ephemeral = monitor.durabilityClass === \"ephemeral\";\n\t\tif (ephemeral && context.remainingMs === undefined) {\n\t\t\treturn lost(`monitor ${monitor.monitorId} has no time left on its deadline`);\n\t\t}\n\t\tconst saved = monitor.lastCheckpoint;\n\t\tif (saved === null) return lost(`monitor ${monitor.monitorId} has no checkpoint to compare against`);\n\t\t// A watch whose file existed at checkpoint time but is gone or unreadable now cannot be\n\t\t// resumed; probe BEFORE re-registering so a lost restore never leaves a live watch behind.\n\t\tif (saved.present) {\n\t\t\ttry {\n\t\t\t\tconst target = await stat(resolve(monitor.cwd, monitor.path));\n\t\t\t\tif (!target.isFile()) return lost(`watched path is no longer a regular file: ${monitor.path}`);\n\t\t\t} catch (error) {\n\t\t\t\treturn lost(`watched path is gone: ${monitor.path} (${error instanceof Error ? error.message : error})`);\n\t\t\t}\n\t\t}\n\n\t\tlet runtimeId: string;\n\t\ttry {\n\t\t\tconst startedAt = now();\n\t\t\t// An ephemeral watch resumes with only the time it had left; a durable one has no deadline.\n\t\t\tconst lifetime =\n\t\t\t\tephemeral && context.remainingMs !== undefined\n\t\t\t\t\t? { persistent: false, deadlineMs: startedAt + context.remainingMs, timeoutMs: context.remainingMs }\n\t\t\t\t\t: { persistent: true, deadlineMs: null, timeoutMs: remainingMs(monitor, startedAt) };\n\t\t\tconst registered = await deps.registry.registerFile({\n\t\t\t\tdescription: monitor.description,\n\t\t\t\tpath: monitor.path,\n\t\t\t\tmonitorId: monitor.monitorId,\n\t\t\t\t...lifetime,\n\t\t\t\tevent: monitor.event ?? \"create\",\n\t\t\t\tcwd: monitor.cwd,\n\t\t\t\t// Preserve the parent approved at permission time: registerFile re-checks it.\n\t\t\t\t...(monitor.approvedParent !== undefined ? { approvedParent: monitor.approvedParent } : {}),\n\t\t\t\t// The persisted deadline rides through verbatim; a restore never extends it.\n\t\t\t\t...(monitor.expiresAt !== null ? { expiresAt: monitor.expiresAt } : {}),\n\t\t\t});\n\t\t\truntimeId = registered.id;\n\t\t} catch (error) {\n\t\t\treturn lost(`cannot re-watch ${monitor.path}: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\n\t\tconst live = deps.registry.fileCheckpoint(runtimeId);\n\t\tif (live === undefined) return lost(`monitor ${monitor.monitorId} settled before its checkpoint was compared`);\n\n\t\tconst change = classifyDetachedChange(saved, live);\n\t\tif (change === \"gone\") {\n\t\t\t// Lost the race with a deletion between the probe and re-registration: report lost, not a\n\t\t\t// change, and settle the watch just registered so a lost restore leaves nothing behind.\n\t\t\tawait deps.registry.stopFile(runtimeId);\n\t\t\treturn lost(`watched path is gone: ${monitor.path}`);\n\t\t}\n\n\t\tdeps.bindMonitorId?.(monitor.monitorId, runtimeId);\n\t\tif (change !== null) deps.registry.emitFileLine(runtimeId, `changed while detached: ${change} ${monitor.path}`);\n\t\t// Re-checkpoint on every restore: after `replaced` this is the new identity, and otherwise\n\t\t// it re-states the tuple the next restart compares against.\n\t\tdeps.writer?.scheduleCheckpoint(monitor.monitorId, live);\n\t\treturn { outcome: \"restored\" };\n\t};\n}\n"]}
@@ -0,0 +1,26 @@
1
+ /** The terminal extension's per-generation state, the bundle event sinks it binds, and the tool context over it. */
2
+ import type { ExtensionAPI, ExtensionContext } from "../../types.ts";
3
+ import type { MonitorNotifier } from "./monitor-notify.ts";
4
+ import type { MonitorStatusTicker } from "./monitor-status-ticker.ts";
5
+ import type { TerminalNotifier } from "./notify.ts";
6
+ import type { PersistenceState } from "./restore-session.ts";
7
+ import { type TerminalEventSinks, TerminalSessionBundle } from "./session-bundle.ts";
8
+ import type { ResolvedTerminalSettings } from "./settings.ts";
9
+ import type { TerminalToolContext } from "./tools/context.ts";
10
+ export interface TerminalExtensionState extends PersistenceState {
11
+ settings: ResolvedTerminalSettings;
12
+ notifier: TerminalNotifier | null;
13
+ monitorNotifier: MonitorNotifier | null;
14
+ statusTicker: MonitorStatusTicker;
15
+ shellPath: string | undefined;
16
+ steppedAside: boolean;
17
+ noticeShown: boolean;
18
+ parked: boolean;
19
+ }
20
+ /** Tests and SDK callers may hand partial contexts without a session manager. */
21
+ export declare function sessionKeyOf(ctx: ExtensionContext | undefined): string | undefined;
22
+ export declare function createBundle(state: TerminalExtensionState): TerminalSessionBundle;
23
+ /** Sinks read the live instance state at call time, so notifier swaps need no re-bind. */
24
+ export declare function bundleSinks(pi: ExtensionAPI, state: TerminalExtensionState): TerminalEventSinks;
25
+ export declare function buildToolContext(pi: ExtensionAPI, state: TerminalExtensionState): TerminalToolContext;
26
+ //# sourceMappingURL=extension-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-state.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/extension-state.ts"],"names":[],"mappings":"AAAA,oHAAoH;AAGpH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAMrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,KAAK,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC/D,QAAQ,EAAE,wBAAwB,CAAC;IACnC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,YAAY,EAAE,mBAAmB,CAAC;IAClC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;CAChB;AAED,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAElF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,sBAAsB,GAAG,qBAAqB,CAKjF;AAED,0FAA0F;AAC1F,wBAAgB,WAAW,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,sBAAsB,GAAG,kBAAkB,CA+E/F;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,sBAAsB,GAAG,mBAAmB,CAgDrG"}
@@ -0,0 +1,151 @@
1
+ /** The terminal extension's per-generation state, the bundle event sinks it binds, and the tool context over it. */
2
+ import { getShellEnv } from "../../../../utils/shell.js";
3
+ import { TERMINAL_MONITOR_ENDED_EVENT, TERMINAL_MONITOR_STATE_EVENT, WAKE_SOURCE_STATE_EVENT, } from "../monitor-state-event.js";
4
+ import { removeMonitorStateDir, terminalStateDir } from "./monitor-state-dir.js";
5
+ import { TerminalSessionBundle } from "./session-bundle.js";
6
+ /** Tests and SDK callers may hand partial contexts without a session manager. */
7
+ export function sessionKeyOf(ctx) {
8
+ return ctx?.sessionManager?.getSessionId?.();
9
+ }
10
+ export function createBundle(state) {
11
+ return new TerminalSessionBundle({
12
+ maxSessions: state.settings.maxSessions,
13
+ scrollback: state.settings.scrollback,
14
+ });
15
+ }
16
+ /** Sinks read the live instance state at call time, so notifier swaps need no re-bind. */
17
+ export function bundleSinks(pi, state) {
18
+ return {
19
+ onMonitorEvent: (event) => state.monitorNotifier?.notifyEvent(event),
20
+ onMonitorEnded: (event) => {
21
+ pi.events?.emit(TERMINAL_MONITOR_ENDED_EVENT, event);
22
+ pi.rpc?.emit(TERMINAL_MONITOR_ENDED_EVENT, event);
23
+ // A watch that ended in this process (its command exited, it was killed or expired) never
24
+ // runs again, so its restore baseline goes. Disposal is a shutdown or reload: the watch is
25
+ // suspended, not ended, and a later restore still needs the dir.
26
+ if (event.reason === "disposed")
27
+ return;
28
+ const dir = terminalStateDir(state.ctx);
29
+ const monitorId = state.bundle?.manager.monitorIdOf(event.id);
30
+ if (dir === undefined || monitorId === undefined)
31
+ return;
32
+ removeMonitorStateDir(dir, monitorId).catch((error) => {
33
+ state.ctx?.ui?.notify?.(`Could not remove the state dir of ${monitorId}: ${error instanceof Error ? error.message : String(error)}`, "warning");
34
+ });
35
+ },
36
+ onMonitorState: (snapshot, transition = true) => {
37
+ if (!state.parked)
38
+ state.statusTicker.sync(snapshot);
39
+ const payload = {
40
+ activeCount: snapshot.length,
41
+ monitors: snapshot.map((entry) => ({
42
+ id: entry.id,
43
+ description: entry.description,
44
+ paused: entry.paused,
45
+ startedAtMs: entry.startedAtMs,
46
+ command: entry.command,
47
+ filter: entry.filter,
48
+ persistent: entry.persistent,
49
+ deadlineMs: entry.deadlineMs,
50
+ fireCount: entry.fireCount,
51
+ lastFiredAtMs: entry.lastFiredAtMs,
52
+ })),
53
+ };
54
+ pi.events?.emit(TERMINAL_MONITOR_STATE_EVENT, payload);
55
+ pi.rpc?.emit(TERMINAL_MONITOR_STATE_EVENT, payload);
56
+ if (!transition)
57
+ return;
58
+ pi.events?.emit(WAKE_SOURCE_STATE_EVENT, {
59
+ source: "terminal-monitors",
60
+ activeCount: snapshot.length,
61
+ monitors: snapshot.map((entry) => ({
62
+ id: entry.id,
63
+ description: entry.description,
64
+ startedAtMs: entry.startedAtMs,
65
+ })),
66
+ });
67
+ if (state.manifestWriter)
68
+ void state.manifestWriter.observeMonitorState(snapshot);
69
+ },
70
+ onBackgroundState: (snapshot) => {
71
+ pi.events?.emit(WAKE_SOURCE_STATE_EVENT, {
72
+ source: "terminal-background-sessions",
73
+ activeCount: snapshot.length,
74
+ items: snapshot,
75
+ });
76
+ const record = () => {
77
+ const writer = state.manifestWriter;
78
+ if (!writer)
79
+ return;
80
+ for (const entry of snapshot) {
81
+ if (state.recordedBackgroundIds.has(entry.id))
82
+ continue;
83
+ state.recordedBackgroundIds.add(entry.id);
84
+ const identity = state.bundle?.manager.get(entry.id)?.identity();
85
+ void writer.recordBackgroundStart(entry.id, entry.description ?? entry.id, entry.startedAtMs, identity);
86
+ }
87
+ };
88
+ if (state.manifestWriter === null && state.ensurePersistence !== null && snapshot.length > 0) {
89
+ void state.ensurePersistence().then(record);
90
+ return;
91
+ }
92
+ record();
93
+ },
94
+ onBackgroundExit: (id, runtime) => {
95
+ state.recordedBackgroundIds.delete(id);
96
+ if (state.manifestWriter)
97
+ void state.manifestWriter.recordBackgroundExit(id);
98
+ state.notifier?.notifyCompletion(id, runtime);
99
+ },
100
+ };
101
+ }
102
+ export function buildToolContext(pi, state) {
103
+ const requireBundle = () => {
104
+ // Lazily create a bundle so the tools work even when invoked directly (e.g. via the
105
+ // SDK) before `session_start` initializes one. `session_start` replaces it with a
106
+ // settings-configured bundle and tears down any earlier one.
107
+ if (!state.bundle) {
108
+ state.bundle = createBundle(state);
109
+ state.bundle.monitors.setParked(state.parked);
110
+ state.bundle.bind(bundleSinks(pi, state));
111
+ }
112
+ return state.bundle;
113
+ };
114
+ return {
115
+ get manager() {
116
+ return requireBundle().manager;
117
+ },
118
+ get cwd() {
119
+ return state.ctx?.cwd ?? process.cwd();
120
+ },
121
+ get shellPath() {
122
+ return state.shellPath;
123
+ },
124
+ get defaultCols() {
125
+ return state.settings.defaultCols;
126
+ },
127
+ get defaultRows() {
128
+ return state.settings.defaultRows;
129
+ },
130
+ get timeoutAction() {
131
+ return state.settings.timeoutAction;
132
+ },
133
+ get monitorRegistry() {
134
+ return requireBundle().monitors;
135
+ },
136
+ getEnv: () => getShellEnv(),
137
+ getSessionContext: () => state.ctx,
138
+ // Exit listeners registered before a reload reach the post-reload owner through the
139
+ // shared bundle, so this must dispatch via the bundle, never the instance notifier.
140
+ onBackgroundStart: (id, description, startedAtMs) => {
141
+ state.bundle?.notifyBackgroundStart(id, description, startedAtMs);
142
+ },
143
+ onBackgroundExit: (id, runtime) => {
144
+ state.bundle?.notifyBackgroundExit(id, runtime);
145
+ },
146
+ onMonitorRearmed: (id) => state.monitorNotifier?.rearm(id),
147
+ onMonitorsResumed: (ids) => state.monitorNotifier?.resume(ids),
148
+ ensurePersistence: () => state.ensurePersistence?.() ?? Promise.resolve(),
149
+ };
150
+ }
151
+ //# sourceMappingURL=extension-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-state.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/extension-state.ts"],"names":[],"mappings":"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","sourcesContent":["/** The terminal extension's per-generation state, the bundle event sinks it binds, and the tool context over it. */\n\nimport { getShellEnv } from \"../../../../utils/shell.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport {\n\tTERMINAL_MONITOR_ENDED_EVENT,\n\tTERMINAL_MONITOR_STATE_EVENT,\n\tWAKE_SOURCE_STATE_EVENT,\n} from \"../monitor-state-event.ts\";\nimport type { MonitorNotifier } from \"./monitor-notify.ts\";\nimport { removeMonitorStateDir, terminalStateDir } from \"./monitor-state-dir.ts\";\nimport type { MonitorStatusTicker } from \"./monitor-status-ticker.ts\";\nimport type { TerminalNotifier } from \"./notify.ts\";\nimport type { PersistenceState } from \"./restore-session.ts\";\nimport type { TerminalRuntimeSession } from \"./runtime-session.ts\";\nimport { type TerminalEventSinks, TerminalSessionBundle } from \"./session-bundle.ts\";\nimport type { ResolvedTerminalSettings } from \"./settings.ts\";\nimport type { TerminalToolContext } from \"./tools/context.ts\";\n\nexport interface TerminalExtensionState extends PersistenceState {\n\tsettings: ResolvedTerminalSettings;\n\tnotifier: TerminalNotifier | null;\n\tmonitorNotifier: MonitorNotifier | null;\n\tstatusTicker: MonitorStatusTicker;\n\tshellPath: string | undefined;\n\tsteppedAside: boolean;\n\tnoticeShown: boolean;\n\tparked: boolean;\n}\n\n/** Tests and SDK callers may hand partial contexts without a session manager. */\nexport function sessionKeyOf(ctx: ExtensionContext | undefined): string | undefined {\n\treturn ctx?.sessionManager?.getSessionId?.();\n}\n\nexport function createBundle(state: TerminalExtensionState): TerminalSessionBundle {\n\treturn new TerminalSessionBundle({\n\t\tmaxSessions: state.settings.maxSessions,\n\t\tscrollback: state.settings.scrollback,\n\t});\n}\n\n/** Sinks read the live instance state at call time, so notifier swaps need no re-bind. */\nexport function bundleSinks(pi: ExtensionAPI, state: TerminalExtensionState): TerminalEventSinks {\n\treturn {\n\t\tonMonitorEvent: (event) => state.monitorNotifier?.notifyEvent(event),\n\t\tonMonitorEnded: (event) => {\n\t\t\tpi.events?.emit(TERMINAL_MONITOR_ENDED_EVENT, event);\n\t\t\tpi.rpc?.emit(TERMINAL_MONITOR_ENDED_EVENT, event);\n\t\t\t// A watch that ended in this process (its command exited, it was killed or expired) never\n\t\t\t// runs again, so its restore baseline goes. Disposal is a shutdown or reload: the watch is\n\t\t\t// suspended, not ended, and a later restore still needs the dir.\n\t\t\tif (event.reason === \"disposed\") return;\n\t\t\tconst dir = terminalStateDir(state.ctx);\n\t\t\tconst monitorId = state.bundle?.manager.monitorIdOf(event.id);\n\t\t\tif (dir === undefined || monitorId === undefined) return;\n\t\t\tremoveMonitorStateDir(dir, monitorId).catch((error: unknown) => {\n\t\t\t\tstate.ctx?.ui?.notify?.(\n\t\t\t\t\t`Could not remove the state dir of ${monitorId}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\tonMonitorState: (snapshot, transition = true) => {\n\t\t\tif (!state.parked) state.statusTicker.sync(snapshot);\n\t\t\tconst payload = {\n\t\t\t\tactiveCount: snapshot.length,\n\t\t\t\tmonitors: snapshot.map((entry) => ({\n\t\t\t\t\tid: entry.id,\n\t\t\t\t\tdescription: entry.description,\n\t\t\t\t\tpaused: entry.paused,\n\t\t\t\t\tstartedAtMs: entry.startedAtMs,\n\t\t\t\t\tcommand: entry.command,\n\t\t\t\t\tfilter: entry.filter,\n\t\t\t\t\tpersistent: entry.persistent,\n\t\t\t\t\tdeadlineMs: entry.deadlineMs,\n\t\t\t\t\tfireCount: entry.fireCount,\n\t\t\t\t\tlastFiredAtMs: entry.lastFiredAtMs,\n\t\t\t\t})),\n\t\t\t};\n\t\t\tpi.events?.emit(TERMINAL_MONITOR_STATE_EVENT, payload);\n\t\t\tpi.rpc?.emit(TERMINAL_MONITOR_STATE_EVENT, payload);\n\t\t\tif (!transition) return;\n\t\t\tpi.events?.emit(WAKE_SOURCE_STATE_EVENT, {\n\t\t\t\tsource: \"terminal-monitors\",\n\t\t\t\tactiveCount: snapshot.length,\n\t\t\t\tmonitors: snapshot.map((entry) => ({\n\t\t\t\t\tid: entry.id,\n\t\t\t\t\tdescription: entry.description,\n\t\t\t\t\tstartedAtMs: entry.startedAtMs,\n\t\t\t\t})),\n\t\t\t});\n\t\t\tif (state.manifestWriter) void state.manifestWriter.observeMonitorState(snapshot);\n\t\t},\n\t\tonBackgroundState: (snapshot) => {\n\t\t\tpi.events?.emit(WAKE_SOURCE_STATE_EVENT, {\n\t\t\t\tsource: \"terminal-background-sessions\",\n\t\t\t\tactiveCount: snapshot.length,\n\t\t\t\titems: snapshot,\n\t\t\t});\n\t\t\tconst record = (): void => {\n\t\t\t\tconst writer = state.manifestWriter;\n\t\t\t\tif (!writer) return;\n\t\t\t\tfor (const entry of snapshot) {\n\t\t\t\t\tif (state.recordedBackgroundIds.has(entry.id)) continue;\n\t\t\t\t\tstate.recordedBackgroundIds.add(entry.id);\n\t\t\t\t\tconst identity = state.bundle?.manager.get(entry.id)?.identity();\n\t\t\t\t\tvoid writer.recordBackgroundStart(entry.id, entry.description ?? entry.id, entry.startedAtMs, identity);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (state.manifestWriter === null && state.ensurePersistence !== null && snapshot.length > 0) {\n\t\t\t\tvoid state.ensurePersistence().then(record);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\trecord();\n\t\t},\n\t\tonBackgroundExit: (id, runtime) => {\n\t\t\tstate.recordedBackgroundIds.delete(id);\n\t\t\tif (state.manifestWriter) void state.manifestWriter.recordBackgroundExit(id);\n\t\t\tstate.notifier?.notifyCompletion(id, runtime);\n\t\t},\n\t};\n}\n\nexport function buildToolContext(pi: ExtensionAPI, state: TerminalExtensionState): TerminalToolContext {\n\tconst requireBundle = (): TerminalSessionBundle => {\n\t\t// Lazily create a bundle so the tools work even when invoked directly (e.g. via the\n\t\t// SDK) before `session_start` initializes one. `session_start` replaces it with a\n\t\t// settings-configured bundle and tears down any earlier one.\n\t\tif (!state.bundle) {\n\t\t\tstate.bundle = createBundle(state);\n\t\t\tstate.bundle.monitors.setParked(state.parked);\n\t\t\tstate.bundle.bind(bundleSinks(pi, state));\n\t\t}\n\t\treturn state.bundle;\n\t};\n\treturn {\n\t\tget manager() {\n\t\t\treturn requireBundle().manager;\n\t\t},\n\t\tget cwd() {\n\t\t\treturn state.ctx?.cwd ?? process.cwd();\n\t\t},\n\t\tget shellPath() {\n\t\t\treturn state.shellPath;\n\t\t},\n\t\tget defaultCols() {\n\t\t\treturn state.settings.defaultCols;\n\t\t},\n\t\tget defaultRows() {\n\t\t\treturn state.settings.defaultRows;\n\t\t},\n\t\tget timeoutAction() {\n\t\t\treturn state.settings.timeoutAction;\n\t\t},\n\t\tget monitorRegistry() {\n\t\t\treturn requireBundle().monitors;\n\t\t},\n\t\tgetEnv: () => getShellEnv(),\n\t\tgetSessionContext: () => state.ctx,\n\t\t// Exit listeners registered before a reload reach the post-reload owner through the\n\t\t// shared bundle, so this must dispatch via the bundle, never the instance notifier.\n\t\tonBackgroundStart: (id: string, description: string, startedAtMs: number) => {\n\t\t\tstate.bundle?.notifyBackgroundStart(id, description, startedAtMs);\n\t\t},\n\t\tonBackgroundExit: (id: string, runtime: TerminalRuntimeSession) => {\n\t\t\tstate.bundle?.notifyBackgroundExit(id, runtime);\n\t\t},\n\t\tonMonitorRearmed: (id: string) => state.monitorNotifier?.rearm(id),\n\t\tonMonitorsResumed: (ids: readonly string[]) => state.monitorNotifier?.resume(ids),\n\t\tensurePersistence: () => state.ensurePersistence?.() ?? Promise.resolve(),\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/extension.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAkYrE,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA6JhE;eAEc,yBAAyB"}
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/extension.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AA2DrE,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA0KhE;eAEc,yBAAyB"}