@code-yeongyu/senpi 2026.8.30 → 2026.9.2-3

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 (430) hide show
  1. package/CHANGELOG.md +234 -4
  2. package/README.md +3 -0
  3. package/dist/core/agent-session.d.ts +29 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +168 -18
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/compaction/compaction-execution.d.ts +14 -0
  8. package/dist/core/compaction/compaction-execution.d.ts.map +1 -0
  9. package/dist/core/compaction/compaction-execution.js +121 -0
  10. package/dist/core/compaction/compaction-execution.js.map +1 -0
  11. package/dist/core/compaction/compaction-settings.d.ts +17 -0
  12. package/dist/core/compaction/compaction-settings.d.ts.map +1 -0
  13. package/dist/core/compaction/compaction-settings.js +17 -0
  14. package/dist/core/compaction/compaction-settings.js.map +1 -0
  15. package/dist/core/compaction/compaction.d.ts +13 -26
  16. package/dist/core/compaction/compaction.d.ts.map +1 -1
  17. package/dist/core/compaction/compaction.js +7 -136
  18. package/dist/core/compaction/compaction.js.map +1 -1
  19. package/dist/core/compaction/ideal-compaction-settings.d.ts +9 -0
  20. package/dist/core/compaction/ideal-compaction-settings.d.ts.map +1 -0
  21. package/dist/core/compaction/ideal-compaction-settings.js +7 -0
  22. package/dist/core/compaction/ideal-compaction-settings.js.map +1 -0
  23. package/dist/core/compaction-settings-access.d.ts +19 -0
  24. package/dist/core/compaction-settings-access.d.ts.map +1 -0
  25. package/dist/core/compaction-settings-access.js +10 -0
  26. package/dist/core/compaction-settings-access.js.map +1 -0
  27. package/dist/core/compaction-settings-resolver.d.ts +22 -0
  28. package/dist/core/compaction-settings-resolver.d.ts.map +1 -0
  29. package/dist/core/compaction-settings-resolver.js +46 -0
  30. package/dist/core/compaction-settings-resolver.js.map +1 -0
  31. package/dist/core/extensions/builtin/claude-sdk-oauth/options.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/claude-sdk-oauth/options.js +6 -2
  33. package/dist/core/extensions/builtin/claude-sdk-oauth/options.js.map +1 -1
  34. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts +9 -1
  35. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts.map +1 -1
  36. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js +10 -3
  37. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js.map +1 -1
  38. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js +2 -1
  40. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -1
  41. package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts +24 -0
  42. package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts.map +1 -0
  43. package/dist/core/extensions/builtin/compaction/context-pipeline.js +43 -0
  44. package/dist/core/extensions/builtin/compaction/context-pipeline.js.map +1 -0
  45. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +1 -1
  46. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +8 -2
  48. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
  49. package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts +17 -0
  50. package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts.map +1 -0
  51. package/dist/core/extensions/builtin/compaction/emergency-prune.js +64 -0
  52. package/dist/core/extensions/builtin/compaction/emergency-prune.js.map +1 -0
  53. package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts +27 -0
  54. package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts.map +1 -0
  55. package/dist/core/extensions/builtin/compaction/extension-wiring.js +84 -0
  56. package/dist/core/extensions/builtin/compaction/extension-wiring.js.map +1 -0
  57. package/dist/core/extensions/builtin/compaction/idle-retry.d.ts +1 -1
  58. package/dist/core/extensions/builtin/compaction/idle-retry.d.ts.map +1 -1
  59. package/dist/core/extensions/builtin/compaction/idle-retry.js +1 -1
  60. package/dist/core/extensions/builtin/compaction/idle-retry.js.map +1 -1
  61. package/dist/core/extensions/builtin/compaction/idle.d.ts +1 -0
  62. package/dist/core/extensions/builtin/compaction/idle.d.ts.map +1 -1
  63. package/dist/core/extensions/builtin/compaction/idle.js +13 -2
  64. package/dist/core/extensions/builtin/compaction/idle.js.map +1 -1
  65. package/dist/core/extensions/builtin/compaction/index.d.ts +1 -1
  66. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  67. package/dist/core/extensions/builtin/compaction/index.js +152 -154
  68. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  69. package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
  70. package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
  71. package/dist/core/extensions/builtin/compaction/log.js +2 -0
  72. package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
  73. package/dist/core/extensions/builtin/compaction/model-selection.d.ts +14 -0
  74. package/dist/core/extensions/builtin/compaction/model-selection.d.ts.map +1 -0
  75. package/dist/core/extensions/builtin/compaction/model-selection.js +37 -0
  76. package/dist/core/extensions/builtin/compaction/model-selection.js.map +1 -0
  77. package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts +30 -0
  78. package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts.map +1 -0
  79. package/dist/core/extensions/builtin/compaction/model-usability-budget.js +74 -0
  80. package/dist/core/extensions/builtin/compaction/model-usability-budget.js.map +1 -0
  81. package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts +9 -0
  82. package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts.map +1 -0
  83. package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js +2 -0
  84. package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js.map +1 -0
  85. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -6
  86. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -1
  88. package/dist/core/extensions/builtin/compaction/orchestration.d.ts +46 -0
  89. package/dist/core/extensions/builtin/compaction/orchestration.d.ts.map +1 -0
  90. package/dist/core/extensions/builtin/compaction/orchestration.js +103 -0
  91. package/dist/core/extensions/builtin/compaction/orchestration.js.map +1 -0
  92. package/dist/core/extensions/builtin/compaction/policy.d.ts +12 -2
  93. package/dist/core/extensions/builtin/compaction/policy.d.ts.map +1 -1
  94. package/dist/core/extensions/builtin/compaction/policy.js +52 -26
  95. package/dist/core/extensions/builtin/compaction/policy.js.map +1 -1
  96. package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts +8 -0
  97. package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts.map +1 -0
  98. package/dist/core/extensions/builtin/compaction/speculation-lead.js +17 -0
  99. package/dist/core/extensions/builtin/compaction/speculation-lead.js.map +1 -0
  100. package/dist/core/extensions/builtin/compaction/speculative-job.d.ts +22 -0
  101. package/dist/core/extensions/builtin/compaction/speculative-job.d.ts.map +1 -0
  102. package/dist/core/extensions/builtin/compaction/speculative-job.js +16 -0
  103. package/dist/core/extensions/builtin/compaction/speculative-job.js.map +1 -0
  104. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts +23 -0
  105. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -0
  106. package/dist/core/extensions/builtin/compaction/speculative-summary.js +132 -0
  107. package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -0
  108. package/dist/core/extensions/builtin/compaction/speculative.d.ts +8 -13
  109. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  110. package/dist/core/extensions/builtin/compaction/speculative.js +21 -197
  111. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  112. package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts +24 -0
  113. package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts.map +1 -0
  114. package/dist/core/extensions/builtin/compaction/token-budget-reminder.js +25 -0
  115. package/dist/core/extensions/builtin/compaction/token-budget-reminder.js.map +1 -0
  116. package/dist/core/extensions/builtin/compaction/tool-admission.d.ts +27 -0
  117. package/dist/core/extensions/builtin/compaction/tool-admission.d.ts.map +1 -0
  118. package/dist/core/extensions/builtin/compaction/tool-admission.js +56 -0
  119. package/dist/core/extensions/builtin/compaction/tool-admission.js.map +1 -0
  120. package/dist/core/extensions/builtin/hooks/trust-state-json.d.ts +5 -0
  121. package/dist/core/extensions/builtin/hooks/trust-state-json.d.ts.map +1 -0
  122. package/dist/core/extensions/builtin/hooks/trust-state-json.js +76 -0
  123. package/dist/core/extensions/builtin/hooks/trust-state-json.js.map +1 -0
  124. package/dist/core/extensions/builtin/hooks/trust-storage.d.ts +7 -1
  125. package/dist/core/extensions/builtin/hooks/trust-storage.d.ts.map +1 -1
  126. package/dist/core/extensions/builtin/hooks/trust-storage.js +60 -8
  127. package/dist/core/extensions/builtin/hooks/trust-storage.js.map +1 -1
  128. package/dist/core/extensions/builtin/hooks/trust.d.ts +1 -2
  129. package/dist/core/extensions/builtin/hooks/trust.d.ts.map +1 -1
  130. package/dist/core/extensions/builtin/hooks/trust.js +1 -72
  131. package/dist/core/extensions/builtin/hooks/trust.js.map +1 -1
  132. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts +3 -0
  133. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts.map +1 -0
  134. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +110 -0
  135. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -0
  136. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.d.ts.map +1 -1
  137. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +2 -1
  138. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
  139. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.d.ts.map +1 -1
  140. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js +7 -1
  141. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js.map +1 -1
  142. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.d.ts.map +1 -1
  143. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js +7 -1
  144. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js.map +1 -1
  145. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.d.ts.map +1 -1
  146. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js +7 -1
  147. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js.map +1 -1
  148. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.d.ts.map +1 -1
  149. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js +7 -1
  150. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js.map +1 -1
  151. package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.d.ts.map +1 -1
  152. package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js +2 -1
  153. package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js.map +1 -1
  154. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +50 -0
  155. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts.map +1 -0
  156. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +66 -0
  157. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js.map +1 -0
  158. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +5 -1
  159. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
  160. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +6 -1
  161. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  162. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.d.ts.map +1 -1
  163. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js +11 -1
  164. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js.map +1 -1
  165. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts.map +1 -1
  166. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +11 -1
  167. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -1
  168. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -1
  169. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +2 -1
  170. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
  171. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  172. package/dist/core/extensions/builtin/prompt-preset/presets.js +18 -1
  173. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  174. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  175. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  176. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  177. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  178. package/dist/core/extensions/builtin/recommended-models/index.d.ts +1 -1
  179. package/dist/core/extensions/builtin/recommended-models/index.d.ts.map +1 -1
  180. package/dist/core/extensions/builtin/recommended-models/index.js +1 -1
  181. package/dist/core/extensions/builtin/recommended-models/index.js.map +1 -1
  182. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +11 -0
  183. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  184. package/dist/core/extensions/builtin/terminal/runtime-session.js +18 -2
  185. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  186. package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
  187. package/dist/core/extensions/builtin/ttsr/index.js +4 -0
  188. package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
  189. package/dist/core/extensions/builtin/ttsr/manager.d.ts +2 -0
  190. package/dist/core/extensions/builtin/ttsr/manager.d.ts.map +1 -1
  191. package/dist/core/extensions/builtin/ttsr/manager.js +28 -1
  192. package/dist/core/extensions/builtin/ttsr/manager.js.map +1 -1
  193. package/dist/core/extensions/runner.d.ts +5 -0
  194. package/dist/core/extensions/runner.d.ts.map +1 -1
  195. package/dist/core/extensions/runner.js +7 -0
  196. package/dist/core/extensions/runner.js.map +1 -1
  197. package/dist/core/provider-composer.d.ts.map +1 -1
  198. package/dist/core/provider-composer.js +17 -8
  199. package/dist/core/provider-composer.js.map +1 -1
  200. package/dist/core/retry-fallback/controller.d.ts +14 -0
  201. package/dist/core/retry-fallback/controller.d.ts.map +1 -1
  202. package/dist/core/retry-fallback/controller.js +33 -3
  203. package/dist/core/retry-fallback/controller.js.map +1 -1
  204. package/dist/core/retry-fallback/log.js +1 -1
  205. package/dist/core/retry-fallback/log.js.map +1 -1
  206. package/dist/core/retry-fallback/settings.d.ts.map +1 -1
  207. package/dist/core/retry-fallback/settings.js +1 -0
  208. package/dist/core/retry-fallback/settings.js.map +1 -1
  209. package/dist/core/sdk.d.ts.map +1 -1
  210. package/dist/core/sdk.js +5 -0
  211. package/dist/core/sdk.js.map +1 -1
  212. package/dist/core/session-activity.d.ts +47 -0
  213. package/dist/core/session-activity.d.ts.map +1 -0
  214. package/dist/core/session-activity.js +58 -0
  215. package/dist/core/session-activity.js.map +1 -0
  216. package/dist/core/session-manager.d.ts +8 -12
  217. package/dist/core/session-manager.d.ts.map +1 -1
  218. package/dist/core/session-manager.js +118 -7
  219. package/dist/core/session-manager.js.map +1 -1
  220. package/dist/core/session-resident-store.d.ts +8 -1
  221. package/dist/core/session-resident-store.d.ts.map +1 -1
  222. package/dist/core/session-resident-store.js +12 -5
  223. package/dist/core/session-resident-store.js.map +1 -1
  224. package/dist/core/settings-manager.d.ts +10 -87
  225. package/dist/core/settings-manager.d.ts.map +1 -1
  226. package/dist/core/settings-manager.js +14 -20
  227. package/dist/core/settings-manager.js.map +1 -1
  228. package/dist/core/settings-public-types.d.ts +11 -0
  229. package/dist/core/settings-public-types.d.ts.map +1 -0
  230. package/dist/core/settings-public-types.js +2 -0
  231. package/dist/core/settings-public-types.js.map +1 -0
  232. package/dist/core/settings-shapes.d.ts +36 -0
  233. package/dist/core/settings-shapes.d.ts.map +1 -0
  234. package/dist/core/settings-shapes.js +2 -0
  235. package/dist/core/settings-shapes.js.map +1 -0
  236. package/dist/core/shared-host-policy.d.ts +6 -0
  237. package/dist/core/shared-host-policy.d.ts.map +1 -0
  238. package/dist/core/shared-host-policy.js +7 -0
  239. package/dist/core/shared-host-policy.js.map +1 -0
  240. package/dist/core/terminal-settings.d.ts +22 -0
  241. package/dist/core/terminal-settings.d.ts.map +1 -0
  242. package/dist/core/terminal-settings.js +2 -0
  243. package/dist/core/terminal-settings.js.map +1 -0
  244. package/dist/index.d.ts +1 -1
  245. package/dist/index.d.ts.map +1 -1
  246. package/dist/index.js +1 -1
  247. package/dist/index.js.map +1 -1
  248. package/dist/main.d.ts +4 -4
  249. package/dist/main.d.ts.map +1 -1
  250. package/dist/main.js +27 -11
  251. package/dist/main.js.map +1 -1
  252. package/dist/modes/app-server/daemon/process.d.ts +13 -2
  253. package/dist/modes/app-server/daemon/process.d.ts.map +1 -1
  254. package/dist/modes/app-server/daemon/process.js +58 -12
  255. package/dist/modes/app-server/daemon/process.js.map +1 -1
  256. package/dist/modes/app-server/daemon.js +65 -7
  257. package/dist/modes/app-server/daemon.js.map +1 -1
  258. package/dist/modes/index.d.ts +1 -1
  259. package/dist/modes/index.d.ts.map +1 -1
  260. package/dist/modes/index.js +1 -1
  261. package/dist/modes/index.js.map +1 -1
  262. package/dist/modes/interactive/interactive-host-runtime.d.ts +84 -1
  263. package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -1
  264. package/dist/modes/interactive/interactive-host-runtime.js +435 -112
  265. package/dist/modes/interactive/interactive-host-runtime.js.map +1 -1
  266. package/dist/modes/interactive/interactive-mode.d.ts +11 -1
  267. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  268. package/dist/modes/interactive/interactive-mode.js +59 -6
  269. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  270. package/dist/modes/interactive/tips/catalog/ethos-tips.js +1 -1
  271. package/dist/modes/interactive/tips/catalog/ethos-tips.js.map +1 -1
  272. package/dist/modes/rpc/connection-handler.d.ts +12 -5
  273. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  274. package/dist/modes/rpc/connection-handler.js +180 -25
  275. package/dist/modes/rpc/connection-handler.js.map +1 -1
  276. package/dist/modes/rpc/custom-capability.d.ts +2 -0
  277. package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
  278. package/dist/modes/rpc/custom-capability.js +2 -0
  279. package/dist/modes/rpc/custom-capability.js.map +1 -1
  280. package/dist/modes/rpc/host-ensure.d.ts +17 -0
  281. package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
  282. package/dist/modes/rpc/host-ensure.js +150 -23
  283. package/dist/modes/rpc/host-ensure.js.map +1 -1
  284. package/dist/modes/rpc/host-lifecycle.d.ts +54 -0
  285. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
  286. package/dist/modes/rpc/host-lifecycle.js +259 -69
  287. package/dist/modes/rpc/host-lifecycle.js.map +1 -1
  288. package/dist/modes/rpc/host-watchdog.d.ts +2 -2
  289. package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
  290. package/dist/modes/rpc/host-watchdog.js +89 -21
  291. package/dist/modes/rpc/host-watchdog.js.map +1 -1
  292. package/dist/modes/rpc/multi-session-host.d.ts +38 -0
  293. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  294. package/dist/modes/rpc/multi-session-host.js +149 -61
  295. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  296. package/dist/modes/rpc/ownership-safe-lock.d.ts +14 -0
  297. package/dist/modes/rpc/ownership-safe-lock.d.ts.map +1 -0
  298. package/dist/modes/rpc/ownership-safe-lock.js +87 -0
  299. package/dist/modes/rpc/ownership-safe-lock.js.map +1 -0
  300. package/dist/modes/rpc/rpc-client.d.ts +13 -2
  301. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  302. package/dist/modes/rpc/rpc-client.js +46 -12
  303. package/dist/modes/rpc/rpc-client.js.map +1 -1
  304. package/dist/modes/rpc/rpc-types.d.ts +21 -3
  305. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  306. package/dist/modes/rpc/rpc-types.js +1 -0
  307. package/dist/modes/rpc/rpc-types.js.map +1 -1
  308. package/dist/modes/rpc/session-binding.d.ts +2 -1
  309. package/dist/modes/rpc/session-binding.d.ts.map +1 -1
  310. package/dist/modes/rpc/session-binding.js +1 -0
  311. package/dist/modes/rpc/session-binding.js.map +1 -1
  312. package/dist/modes/rpc/session-command-router.d.ts +54 -1
  313. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  314. package/dist/modes/rpc/session-command-router.js +180 -3
  315. package/dist/modes/rpc/session-command-router.js.map +1 -1
  316. package/dist/modes/rpc/session-event-writer.d.ts +18 -0
  317. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  318. package/dist/modes/rpc/session-event-writer.js +88 -8
  319. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  320. package/dist/modes/rpc/session-registry.d.ts +11 -1
  321. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  322. package/dist/modes/rpc/session-registry.js +25 -0
  323. package/dist/modes/rpc/session-registry.js.map +1 -1
  324. package/dist/modes/rpc/socket-transport.d.ts +13 -0
  325. package/dist/modes/rpc/socket-transport.d.ts.map +1 -0
  326. package/dist/modes/rpc/socket-transport.js +92 -0
  327. package/dist/modes/rpc/socket-transport.js.map +1 -0
  328. package/dist/modes/rpc/widget-line-renderer.d.ts +17 -0
  329. package/dist/modes/rpc/widget-line-renderer.d.ts.map +1 -0
  330. package/dist/modes/rpc/widget-line-renderer.js +73 -0
  331. package/dist/modes/rpc/widget-line-renderer.js.map +1 -0
  332. package/dist/utils/fs-watch.d.ts.map +1 -1
  333. package/dist/utils/fs-watch.js +11 -2
  334. package/dist/utils/fs-watch.js.map +1 -1
  335. package/docs/app-server.md +2 -2
  336. package/docs/containerization.md +2 -2
  337. package/docs/development.md +7 -7
  338. package/docs/extensions.md +5 -5
  339. package/docs/grok-neo.md +1 -1
  340. package/docs/index.md +1 -1
  341. package/docs/packages.md +2 -2
  342. package/docs/quickstart.md +4 -4
  343. package/docs/release-guide.md +21 -21
  344. package/docs/rpc.md +83 -6
  345. package/docs/sdk.md +1 -1
  346. package/docs/settings.md +8 -8
  347. package/docs/skills.md +2 -2
  348. package/docs/terminal-tools.md +1 -1
  349. package/docs/termux.md +1 -1
  350. package/docs/tui.md +1 -1
  351. package/examples/AGENTS.md +1 -1
  352. package/examples/sdk/README.md +1 -1
  353. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +85 -0
  354. package/node_modules/@code-yeongyu/senpi-codemode/README.md +6 -4
  355. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  356. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/skill-contribution.ts +105 -0
  357. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +6 -1
  358. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +10 -1
  359. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/SKILL.md +44 -0
  360. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/breaking-changes.md +75 -0
  361. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/build.md +114 -0
  362. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/dev-tooling.md +34 -0
  363. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/http-networking.md +113 -0
  364. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/install.md +93 -0
  365. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/node-compat-platforms.md +36 -0
  366. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/performance.md +33 -0
  367. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/runtime-apis.md +156 -0
  368. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/security.md +52 -0
  369. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/test.md +103 -0
  370. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +3 -1
  371. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +2 -0
  372. package/node_modules/@earendil-works/pi-agent-core/README.md +3 -0
  373. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts +3 -0
  374. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  375. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -2
  376. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  377. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  378. package/node_modules/@earendil-works/pi-ai/README.md +6 -3
  379. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  380. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +24 -7
  381. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  382. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +7 -0
  383. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
  384. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +316 -2
  385. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
  386. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts +4 -0
  387. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts.map +1 -1
  388. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js +23 -0
  389. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js.map +1 -1
  390. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +24 -0
  391. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  392. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +20 -2
  393. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  394. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  395. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  396. package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.json +1 -1
  397. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  398. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
  399. package/node_modules/@earendil-works/pi-ai/dist/providers/data/groq.json +1 -1
  400. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  401. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  402. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  403. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  404. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  405. package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.d.ts.map +1 -1
  406. package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.js +3 -1
  407. package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.js.map +1 -1
  408. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +1 -1
  409. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  410. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  411. package/node_modules/@earendil-works/pi-pty/dist/screen-operations.d.ts +42 -0
  412. package/node_modules/@earendil-works/pi-pty/dist/screen-operations.d.ts.map +1 -0
  413. package/node_modules/@earendil-works/pi-pty/dist/screen-operations.js +34 -0
  414. package/node_modules/@earendil-works/pi-pty/dist/screen-operations.js.map +1 -0
  415. package/node_modules/@earendil-works/pi-pty/dist/screen-text.d.ts +8 -0
  416. package/node_modules/@earendil-works/pi-pty/dist/screen-text.d.ts.map +1 -0
  417. package/node_modules/@earendil-works/pi-pty/dist/screen-text.js +51 -0
  418. package/node_modules/@earendil-works/pi-pty/dist/screen-text.js.map +1 -0
  419. package/node_modules/@earendil-works/pi-pty/dist/screen.d.ts +45 -0
  420. package/node_modules/@earendil-works/pi-pty/dist/screen.d.ts.map +1 -1
  421. package/node_modules/@earendil-works/pi-pty/dist/screen.js +178 -55
  422. package/node_modules/@earendil-works/pi-pty/dist/screen.js.map +1 -1
  423. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  424. package/node_modules/@earendil-works/pi-telemetry/README.md +6 -3
  425. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  426. package/node_modules/@earendil-works/pi-tui/README.md +5 -4
  427. package/node_modules/@earendil-works/pi-tui/native/darwin/README.md +2 -2
  428. package/node_modules/@earendil-works/pi-tui/native/win32/README.md +2 -2
  429. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  430. package/package.json +7 -7
@@ -1,38 +1,95 @@
1
1
  import xterm from "@xterm/headless";
2
+ import { MAX_PENDING_WRITE_CHARS, settleOperation, sharedSettler, } from "./screen-operations.js";
3
+ import { decodeInput, normalizeDimension, normalizeReplayHistoryLength, normalizeScrollback, readLine, sanitizeString, } from "./screen-text.js";
2
4
  const XtermTerminal = xterm.Terminal;
3
5
  const DEFAULT_COLS = 80;
4
6
  const DEFAULT_ROWS = 24;
5
- const DEFAULT_SCROLLBACK = 1000;
6
- const MIN_SIZE = 1;
7
- const MAX_SIZE = 10000;
8
- const MIN_REPLAY_HISTORY_LENGTH = 4096;
9
- const MAX_REPLAY_HISTORY_LENGTH = 1_000_000;
7
+ /**
8
+ * Headless xterm screen model with serialized, flow-controlled writes.
9
+ *
10
+ * Every terminal mutation (feed, resize, backlog replay) runs through one
11
+ * FIFO queue that awaits xterm's parse callback before issuing the next
12
+ * write, so xterm's pending-write watermark can never be exceeded. When the
13
+ * queued backlog outgrows {@link MAX_PENDING_WRITE_CHARS}, the queued writes
14
+ * collapse into a single bounded history replay that reconstructs the same
15
+ * screen state. After {@link TerminalScreen.dispose}, queued and future
16
+ * operations settle as resolved no-ops; a terminal is never created after
17
+ * disposal.
18
+ */
10
19
  export class TerminalScreen {
11
20
  constructor(options = {}) {
12
21
  this.history = [];
13
22
  this.historyLength = 0;
23
+ this.operations = [];
24
+ this.pendingChars = 0;
25
+ this.draining = false;
26
+ this.disposed = false;
27
+ this.notifyDisposed = () => undefined;
14
28
  const cols = normalizeDimension(options.cols, DEFAULT_COLS);
15
29
  const rows = normalizeDimension(options.rows, DEFAULT_ROWS);
16
30
  this.scrollback = normalizeScrollback(options.scrollback);
17
31
  this.maxReplayHistoryLength = normalizeReplayHistoryLength(cols, rows, this.scrollback);
32
+ this.whenDisposed = new Promise((resolve) => {
33
+ this.notifyDisposed = resolve;
34
+ });
18
35
  this.terminal = this.createTerminal(cols, rows);
19
36
  }
20
37
  feed(data) {
38
+ if (this.disposed)
39
+ return Promise.resolve();
21
40
  const payload = decodeInput(data);
22
41
  const sanitizedPayload = sanitizeString(payload);
23
42
  if (sanitizedPayload.length > 0)
24
43
  this.appendHistory(sanitizedPayload);
25
- return this.write(payload);
44
+ if (this.pendingChars + payload.length > MAX_PENDING_WRITE_CHARS) {
45
+ return this.coalesceFeedIntoReplay(payload);
46
+ }
47
+ this.pendingChars += payload.length;
48
+ const operation = { kind: "write", payload, settled: null, settlers: [] };
49
+ return this.enqueue(operation, sharedSettler(operation));
26
50
  }
27
51
  resize(cols, rows) {
52
+ if (this.disposed)
53
+ return Promise.resolve();
28
54
  const nextCols = normalizeDimension(cols, this.terminal.cols);
29
55
  const nextRows = normalizeDimension(rows, this.terminal.rows);
30
- this.terminal.dispose();
31
- this.terminal = this.createTerminal(nextCols, nextRows);
32
- return this.write(this.history.join(""));
56
+ const snapshot = this.history.join("");
57
+ const tail = this.operations[this.operations.length - 1];
58
+ if (tail !== undefined && tail.kind === "resize") {
59
+ tail.cols = nextCols;
60
+ tail.rows = nextRows;
61
+ this.pendingChars += snapshot.length - tail.replay.length;
62
+ tail.replay = snapshot;
63
+ return sharedSettler(tail);
64
+ }
65
+ if (this.pendingChars + snapshot.length > MAX_PENDING_WRITE_CHARS) {
66
+ return this.coalesceQueueIntoResize(nextCols, nextRows, snapshot);
67
+ }
68
+ const operation = {
69
+ kind: "resize",
70
+ cols: nextCols,
71
+ rows: nextRows,
72
+ replay: snapshot,
73
+ settled: null,
74
+ settlers: [],
75
+ };
76
+ this.pendingChars += snapshot.length;
77
+ return this.enqueue(operation, sharedSettler(operation));
33
78
  }
79
+ /**
80
+ * Resolves once everything fed before this call has been parsed. Attaches
81
+ * to the queue tail instead of enqueueing a marker so a flush can never
82
+ * split a tail replay (which would let over-cap feeds mint unbounded new
83
+ * replay operations); only an empty queue enqueues a zero-length write.
84
+ */
34
85
  flush() {
35
- return this.write("");
86
+ if (this.disposed)
87
+ return Promise.resolve();
88
+ const tail = this.operations[this.operations.length - 1];
89
+ if (tail !== undefined)
90
+ return sharedSettler(tail);
91
+ const operation = { kind: "write", payload: "", settled: null, settlers: [] };
92
+ return this.enqueue(operation, sharedSettler(operation));
36
93
  }
37
94
  snapshot() {
38
95
  const buffer = this.terminal.buffer.active;
@@ -58,6 +115,15 @@ export class TerminalScreen {
58
115
  };
59
116
  }
60
117
  dispose() {
118
+ if (this.disposed)
119
+ return;
120
+ this.disposed = true;
121
+ this.notifyDisposed();
122
+ const pending = this.operations.splice(0, this.operations.length);
123
+ this.pendingChars = 0;
124
+ for (const operation of pending) {
125
+ settleOperation(operation.settlers, null);
126
+ }
61
127
  this.terminal.dispose();
62
128
  }
63
129
  createTerminal(cols, rows) {
@@ -70,6 +136,108 @@ export class TerminalScreen {
70
136
  logLevel: "off",
71
137
  });
72
138
  }
139
+ enqueue(operation, settled) {
140
+ this.operations.push(operation);
141
+ void this.drain();
142
+ return settled;
143
+ }
144
+ /**
145
+ * Route an over-cap feed to the queue's tail replay instead of enqueueing
146
+ * another write. Replay payloads are owned snapshot strings (immune to
147
+ * history trimming) bounded to the replay budget, and every coalesced feed
148
+ * shares the tail's memoized promise, so a flood cannot grow the queue,
149
+ * its payload memory, or its settler memory past the configured bounds.
150
+ */
151
+ coalesceFeedIntoReplay(payload) {
152
+ const tail = this.operations[this.operations.length - 1];
153
+ if (tail !== undefined && tail.kind === "replay") {
154
+ const previousLength = tail.payload.length;
155
+ tail.payload = this.boundReplayPayload(tail.payload + payload);
156
+ this.pendingChars += tail.payload.length - previousLength;
157
+ return sharedSettler(tail);
158
+ }
159
+ const operation = {
160
+ kind: "replay",
161
+ payload: this.history.join(""),
162
+ settled: null,
163
+ settlers: [],
164
+ };
165
+ this.pendingChars += operation.payload.length;
166
+ return this.enqueue(operation, sharedSettler(operation));
167
+ }
168
+ /**
169
+ * A resize whose snapshot would push the queued payload past the cap
170
+ * collapses the whole queue into one resize at the latest dimensions:
171
+ * every dropped operation's payload is already covered by the bounded
172
+ * history snapshot, and their settlers settle with this operation.
173
+ */
174
+ coalesceQueueIntoResize(cols, rows, snapshot) {
175
+ const operation = {
176
+ kind: "resize",
177
+ cols,
178
+ rows,
179
+ replay: snapshot,
180
+ settled: null,
181
+ settlers: [],
182
+ };
183
+ for (const queued of this.operations.splice(0, this.operations.length)) {
184
+ for (const settler of queued.settlers)
185
+ operation.settlers.push(settler);
186
+ queued.settlers.length = 0;
187
+ }
188
+ this.pendingChars = snapshot.length;
189
+ return this.enqueue(operation, sharedSettler(operation));
190
+ }
191
+ boundReplayPayload(payload) {
192
+ if (payload.length <= this.maxReplayHistoryLength)
193
+ return payload;
194
+ return sanitizeString(payload.slice(-this.maxReplayHistoryLength));
195
+ }
196
+ async drain() {
197
+ if (this.draining)
198
+ return;
199
+ this.draining = true;
200
+ try {
201
+ while (!this.disposed) {
202
+ const operation = this.operations.shift();
203
+ if (operation === undefined)
204
+ return;
205
+ this.pendingChars -= operation.kind === "resize" ? operation.replay.length : operation.payload.length;
206
+ try {
207
+ await this.run(operation);
208
+ settleOperation(operation.settlers, null);
209
+ }
210
+ catch (error) {
211
+ settleOperation(operation.settlers, error instanceof Error ? error : new Error(String(error)));
212
+ }
213
+ }
214
+ }
215
+ finally {
216
+ this.draining = false;
217
+ }
218
+ }
219
+ async run(operation) {
220
+ if (this.disposed)
221
+ return;
222
+ switch (operation.kind) {
223
+ case "write":
224
+ await this.raceDisposal(this.write(operation.payload));
225
+ return;
226
+ case "replay":
227
+ this.terminal.reset();
228
+ await this.raceDisposal(this.write(operation.payload));
229
+ return;
230
+ case "resize":
231
+ this.terminal.dispose();
232
+ this.terminal = this.createTerminal(operation.cols, operation.rows);
233
+ await this.raceDisposal(this.write(operation.replay));
234
+ return;
235
+ }
236
+ }
237
+ /** A disposed terminal may never invoke its parse callback; do not hang. */
238
+ raceDisposal(written) {
239
+ return Promise.race([written, this.whenDisposed]);
240
+ }
73
241
  write(payload) {
74
242
  return new Promise((resolve, reject) => {
75
243
  try {
@@ -107,49 +275,4 @@ export class TerminalScreen {
107
275
  this.historyLength = trimmed.length;
108
276
  }
109
277
  }
110
- function readLine(buffer, lineIndex) {
111
- return buffer.getLine(lineIndex)?.translateToString(true) ?? "";
112
- }
113
- function normalizeDimension(value, fallback) {
114
- if (value === undefined || !Number.isFinite(value))
115
- return fallback;
116
- return Math.min(MAX_SIZE, Math.max(MIN_SIZE, Math.trunc(value)));
117
- }
118
- function normalizeScrollback(value) {
119
- if (value === undefined || !Number.isFinite(value))
120
- return DEFAULT_SCROLLBACK;
121
- return Math.max(0, Math.trunc(value));
122
- }
123
- function normalizeReplayHistoryLength(cols, rows, scrollback) {
124
- const visibleCells = Math.max(MIN_SIZE, cols) * Math.max(MIN_SIZE, rows + scrollback + 1);
125
- return Math.min(MAX_REPLAY_HISTORY_LENGTH, Math.max(MIN_REPLAY_HISTORY_LENGTH, visibleCells * 4));
126
- }
127
- function decodeInput(value) {
128
- if (typeof value === "string")
129
- return value;
130
- return new TextDecoder("utf-8", { fatal: false }).decode(value);
131
- }
132
- function sanitizeString(value) {
133
- let output = "";
134
- for (let index = 0; index < value.length; index += 1) {
135
- const code = value.charCodeAt(index);
136
- if (code >= 0xd800 && code <= 0xdbff) {
137
- const next = value.charCodeAt(index + 1);
138
- if (next >= 0xdc00 && next <= 0xdfff) {
139
- output += value[index] + value[index + 1];
140
- index += 1;
141
- }
142
- else {
143
- output += "\uFFFD";
144
- }
145
- }
146
- else if (code >= 0xdc00 && code <= 0xdfff) {
147
- output += "\uFFFD";
148
- }
149
- else {
150
- output += value[index];
151
- }
152
- }
153
- return output;
154
- }
155
278
  //# sourceMappingURL=screen.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"screen.js","sourceRoot":"","sources":["../src/screen.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Terminal as XtermTerminalType } from \"@xterm/headless\";\nimport xterm from \"@xterm/headless\";\n\nexport interface TerminalScreenOptions {\n\treadonly cols?: number;\n\treadonly rows?: number;\n\treadonly scrollback?: number;\n}\n\nexport interface TerminalScreenSnapshot {\n\treadonly cols: number;\n\treadonly rows: number;\n\treadonly visibleGrid: readonly string[];\n\treadonly scrollback: readonly string[];\n\treadonly cursor: {\n\t\treadonly x: number;\n\t\treadonly y: number;\n\t};\n}\n\nconst XtermTerminal = xterm.Terminal;\nconst DEFAULT_COLS = 80;\nconst DEFAULT_ROWS = 24;\nconst DEFAULT_SCROLLBACK = 1000;\nconst MIN_SIZE = 1;\nconst MAX_SIZE = 10000;\nconst MIN_REPLAY_HISTORY_LENGTH = 4096;\nconst MAX_REPLAY_HISTORY_LENGTH = 1_000_000;\n\nexport class TerminalScreen {\n\tprivate terminal: XtermTerminalType;\n\tprivate readonly history: string[] = [];\n\tprivate historyLength = 0;\n\tprivate readonly maxReplayHistoryLength: number;\n\tprivate readonly scrollback: number;\n\n\tconstructor(options: TerminalScreenOptions = {}) {\n\t\tconst cols = normalizeDimension(options.cols, DEFAULT_COLS);\n\t\tconst rows = normalizeDimension(options.rows, DEFAULT_ROWS);\n\t\tthis.scrollback = normalizeScrollback(options.scrollback);\n\t\tthis.maxReplayHistoryLength = normalizeReplayHistoryLength(cols, rows, this.scrollback);\n\t\tthis.terminal = this.createTerminal(cols, rows);\n\t}\n\n\tfeed(data: string | Uint8Array): Promise<void> {\n\t\tconst payload = decodeInput(data);\n\t\tconst sanitizedPayload = sanitizeString(payload);\n\t\tif (sanitizedPayload.length > 0) this.appendHistory(sanitizedPayload);\n\t\treturn this.write(payload);\n\t}\n\n\tresize(cols: number, rows: number): Promise<void> {\n\t\tconst nextCols = normalizeDimension(cols, this.terminal.cols);\n\t\tconst nextRows = normalizeDimension(rows, this.terminal.rows);\n\t\tthis.terminal.dispose();\n\t\tthis.terminal = this.createTerminal(nextCols, nextRows);\n\t\treturn this.write(this.history.join(\"\"));\n\t}\n\n\tflush(): Promise<void> {\n\t\treturn this.write(\"\");\n\t}\n\n\tsnapshot(): TerminalScreenSnapshot {\n\t\tconst buffer = this.terminal.buffer.active;\n\t\tconst viewportStart = buffer.viewportY;\n\t\tconst visibleGrid: string[] = [];\n\t\tconst scrollback: string[] = [];\n\t\tconst scrollbackStart = Math.max(0, viewportStart - this.scrollback);\n\n\t\tfor (let lineIndex = scrollbackStart; lineIndex < viewportStart; lineIndex += 1) {\n\t\t\tscrollback.push(readLine(buffer, lineIndex));\n\t\t}\n\t\tfor (let row = 0; row < this.terminal.rows; row += 1) {\n\t\t\tvisibleGrid.push(readLine(buffer, viewportStart + row));\n\t\t}\n\n\t\treturn {\n\t\t\tcols: this.terminal.cols,\n\t\t\trows: this.terminal.rows,\n\t\t\tvisibleGrid,\n\t\t\tscrollback,\n\t\t\tcursor: {\n\t\t\t\tx: buffer.cursorX,\n\t\t\t\ty: buffer.cursorY,\n\t\t\t},\n\t\t};\n\t}\n\n\tdispose(): void {\n\t\tthis.terminal.dispose();\n\t}\n\n\tprivate createTerminal(cols: number, rows: number): XtermTerminalType {\n\t\treturn new XtermTerminal({\n\t\t\tcols,\n\t\t\trows,\n\t\t\tscrollback: this.scrollback,\n\t\t\tdisableStdin: true,\n\t\t\tallowProposedApi: true,\n\t\t\tlogLevel: \"off\",\n\t\t});\n\t}\n\n\tprivate write(payload: string): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tthis.terminal.write(payload, resolve);\n\t\t\t} catch (error) {\n\t\t\t\tconst sanitizedPayload = sanitizeString(payload);\n\t\t\t\tif (sanitizedPayload === payload) {\n\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.terminal.write(sanitizedPayload, resolve);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate appendHistory(payload: string): void {\n\t\tthis.history.push(payload);\n\t\tthis.historyLength += payload.length;\n\t\tthis.trimHistory();\n\t}\n\n\tprivate trimHistory(): void {\n\t\twhile (this.historyLength > this.maxReplayHistoryLength && this.history.length > 1) {\n\t\t\tconst removed = this.history.shift();\n\t\t\tif (removed === undefined) return;\n\t\t\tthis.historyLength -= removed.length;\n\t\t}\n\n\t\tif (this.historyLength <= this.maxReplayHistoryLength) return;\n\t\tconst [onlyChunk] = this.history;\n\t\tif (onlyChunk === undefined) return;\n\t\tconst trimmed = sanitizeString(onlyChunk.slice(-this.maxReplayHistoryLength));\n\t\tthis.history[0] = trimmed;\n\t\tthis.historyLength = trimmed.length;\n\t}\n}\n\nfunction readLine(buffer: XtermTerminalType[\"buffer\"][\"active\"], lineIndex: number): string {\n\treturn buffer.getLine(lineIndex)?.translateToString(true) ?? \"\";\n}\n\nfunction normalizeDimension(value: number | undefined, fallback: number): number {\n\tif (value === undefined || !Number.isFinite(value)) return fallback;\n\treturn Math.min(MAX_SIZE, Math.max(MIN_SIZE, Math.trunc(value)));\n}\n\nfunction normalizeScrollback(value: number | undefined): number {\n\tif (value === undefined || !Number.isFinite(value)) return DEFAULT_SCROLLBACK;\n\treturn Math.max(0, Math.trunc(value));\n}\n\nfunction normalizeReplayHistoryLength(cols: number, rows: number, scrollback: number): number {\n\tconst visibleCells = Math.max(MIN_SIZE, cols) * Math.max(MIN_SIZE, rows + scrollback + 1);\n\treturn Math.min(MAX_REPLAY_HISTORY_LENGTH, Math.max(MIN_REPLAY_HISTORY_LENGTH, visibleCells * 4));\n}\n\nfunction decodeInput(value: string | Uint8Array): string {\n\tif (typeof value === \"string\") return value;\n\treturn new TextDecoder(\"utf-8\", { fatal: false }).decode(value);\n}\n\nfunction sanitizeString(value: string): string {\n\tlet output = \"\";\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\tconst code = value.charCodeAt(index);\n\t\tif (code >= 0xd800 && code <= 0xdbff) {\n\t\t\tconst next = value.charCodeAt(index + 1);\n\t\t\tif (next >= 0xdc00 && next <= 0xdfff) {\n\t\t\t\toutput += value[index] + value[index + 1];\n\t\t\t\tindex += 1;\n\t\t\t} else {\n\t\t\t\toutput += \"\\uFFFD\";\n\t\t\t}\n\t\t} else if (code >= 0xdc00 && code <= 0xdfff) {\n\t\t\toutput += \"\\uFFFD\";\n\t\t} else {\n\t\t\toutput += value[index];\n\t\t}\n\t}\n\treturn output;\n}\n"]}
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../src/screen.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Terminal as XtermTerminalType } from \"@xterm/headless\";\nimport xterm from \"@xterm/headless\";\nimport {\n\tMAX_PENDING_WRITE_CHARS,\n\ttype ReplayOperation,\n\ttype ResizeOperation,\n\ttype ScreenOperation,\n\tsettleOperation,\n\tsharedSettler,\n} from \"./screen-operations.ts\";\n\nimport {\n\tdecodeInput,\n\tnormalizeDimension,\n\tnormalizeReplayHistoryLength,\n\tnormalizeScrollback,\n\treadLine,\n\tsanitizeString,\n} from \"./screen-text.ts\";\n\nexport interface TerminalScreenOptions {\n\treadonly cols?: number;\n\treadonly rows?: number;\n\treadonly scrollback?: number;\n}\n\nexport interface TerminalScreenSnapshot {\n\treadonly cols: number;\n\treadonly rows: number;\n\treadonly visibleGrid: readonly string[];\n\treadonly scrollback: readonly string[];\n\treadonly cursor: {\n\t\treadonly x: number;\n\t\treadonly y: number;\n\t};\n}\n\nconst XtermTerminal = xterm.Terminal;\nconst DEFAULT_COLS = 80;\nconst DEFAULT_ROWS = 24;\n\n/**\n * Headless xterm screen model with serialized, flow-controlled writes.\n *\n * Every terminal mutation (feed, resize, backlog replay) runs through one\n * FIFO queue that awaits xterm's parse callback before issuing the next\n * write, so xterm's pending-write watermark can never be exceeded. When the\n * queued backlog outgrows {@link MAX_PENDING_WRITE_CHARS}, the queued writes\n * collapse into a single bounded history replay that reconstructs the same\n * screen state. After {@link TerminalScreen.dispose}, queued and future\n * operations settle as resolved no-ops; a terminal is never created after\n * disposal.\n */\nexport class TerminalScreen {\n\tprivate terminal: XtermTerminalType;\n\tprivate readonly history: string[] = [];\n\tprivate historyLength = 0;\n\tprivate readonly operations: ScreenOperation[] = [];\n\tprivate pendingChars = 0;\n\tprivate draining = false;\n\tprivate disposed = false;\n\tprivate notifyDisposed: () => void = () => undefined;\n\tprivate readonly whenDisposed: Promise<void>;\n\tprivate readonly maxReplayHistoryLength: number;\n\tprivate readonly scrollback: number;\n\n\tconstructor(options: TerminalScreenOptions = {}) {\n\t\tconst cols = normalizeDimension(options.cols, DEFAULT_COLS);\n\t\tconst rows = normalizeDimension(options.rows, DEFAULT_ROWS);\n\t\tthis.scrollback = normalizeScrollback(options.scrollback);\n\t\tthis.maxReplayHistoryLength = normalizeReplayHistoryLength(cols, rows, this.scrollback);\n\t\tthis.whenDisposed = new Promise((resolve) => {\n\t\t\tthis.notifyDisposed = resolve;\n\t\t});\n\t\tthis.terminal = this.createTerminal(cols, rows);\n\t}\n\n\tfeed(data: string | Uint8Array): Promise<void> {\n\t\tif (this.disposed) return Promise.resolve();\n\t\tconst payload = decodeInput(data);\n\t\tconst sanitizedPayload = sanitizeString(payload);\n\t\tif (sanitizedPayload.length > 0) this.appendHistory(sanitizedPayload);\n\t\tif (this.pendingChars + payload.length > MAX_PENDING_WRITE_CHARS) {\n\t\t\treturn this.coalesceFeedIntoReplay(payload);\n\t\t}\n\t\tthis.pendingChars += payload.length;\n\t\tconst operation: ScreenOperation = { kind: \"write\", payload, settled: null, settlers: [] };\n\t\treturn this.enqueue(operation, sharedSettler(operation));\n\t}\n\n\tresize(cols: number, rows: number): Promise<void> {\n\t\tif (this.disposed) return Promise.resolve();\n\t\tconst nextCols = normalizeDimension(cols, this.terminal.cols);\n\t\tconst nextRows = normalizeDimension(rows, this.terminal.rows);\n\t\tconst snapshot = this.history.join(\"\");\n\t\tconst tail = this.operations[this.operations.length - 1];\n\t\tif (tail !== undefined && tail.kind === \"resize\") {\n\t\t\ttail.cols = nextCols;\n\t\t\ttail.rows = nextRows;\n\t\t\tthis.pendingChars += snapshot.length - tail.replay.length;\n\t\t\ttail.replay = snapshot;\n\t\t\treturn sharedSettler(tail);\n\t\t}\n\t\tif (this.pendingChars + snapshot.length > MAX_PENDING_WRITE_CHARS) {\n\t\t\treturn this.coalesceQueueIntoResize(nextCols, nextRows, snapshot);\n\t\t}\n\t\tconst operation: ResizeOperation = {\n\t\t\tkind: \"resize\",\n\t\t\tcols: nextCols,\n\t\t\trows: nextRows,\n\t\t\treplay: snapshot,\n\t\t\tsettled: null,\n\t\t\tsettlers: [],\n\t\t};\n\t\tthis.pendingChars += snapshot.length;\n\t\treturn this.enqueue(operation, sharedSettler(operation));\n\t}\n\n\t/**\n\t * Resolves once everything fed before this call has been parsed. Attaches\n\t * to the queue tail instead of enqueueing a marker so a flush can never\n\t * split a tail replay (which would let over-cap feeds mint unbounded new\n\t * replay operations); only an empty queue enqueues a zero-length write.\n\t */\n\tflush(): Promise<void> {\n\t\tif (this.disposed) return Promise.resolve();\n\t\tconst tail = this.operations[this.operations.length - 1];\n\t\tif (tail !== undefined) return sharedSettler(tail);\n\t\tconst operation: ScreenOperation = { kind: \"write\", payload: \"\", settled: null, settlers: [] };\n\t\treturn this.enqueue(operation, sharedSettler(operation));\n\t}\n\n\tsnapshot(): TerminalScreenSnapshot {\n\t\tconst buffer = this.terminal.buffer.active;\n\t\tconst viewportStart = buffer.viewportY;\n\t\tconst visibleGrid: string[] = [];\n\t\tconst scrollback: string[] = [];\n\t\tconst scrollbackStart = Math.max(0, viewportStart - this.scrollback);\n\n\t\tfor (let lineIndex = scrollbackStart; lineIndex < viewportStart; lineIndex += 1) {\n\t\t\tscrollback.push(readLine(buffer, lineIndex));\n\t\t}\n\t\tfor (let row = 0; row < this.terminal.rows; row += 1) {\n\t\t\tvisibleGrid.push(readLine(buffer, viewportStart + row));\n\t\t}\n\n\t\treturn {\n\t\t\tcols: this.terminal.cols,\n\t\t\trows: this.terminal.rows,\n\t\t\tvisibleGrid,\n\t\t\tscrollback,\n\t\t\tcursor: {\n\t\t\t\tx: buffer.cursorX,\n\t\t\t\ty: buffer.cursorY,\n\t\t\t},\n\t\t};\n\t}\n\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tthis.notifyDisposed();\n\t\tconst pending = this.operations.splice(0, this.operations.length);\n\t\tthis.pendingChars = 0;\n\t\tfor (const operation of pending) {\n\t\t\tsettleOperation(operation.settlers, null);\n\t\t}\n\t\tthis.terminal.dispose();\n\t}\n\n\tprivate createTerminal(cols: number, rows: number): XtermTerminalType {\n\t\treturn new XtermTerminal({\n\t\t\tcols,\n\t\t\trows,\n\t\t\tscrollback: this.scrollback,\n\t\t\tdisableStdin: true,\n\t\t\tallowProposedApi: true,\n\t\t\tlogLevel: \"off\",\n\t\t});\n\t}\n\n\tprivate enqueue(operation: ScreenOperation, settled: Promise<void>): Promise<void> {\n\t\tthis.operations.push(operation);\n\t\tvoid this.drain();\n\t\treturn settled;\n\t}\n\n\t/**\n\t * Route an over-cap feed to the queue's tail replay instead of enqueueing\n\t * another write. Replay payloads are owned snapshot strings (immune to\n\t * history trimming) bounded to the replay budget, and every coalesced feed\n\t * shares the tail's memoized promise, so a flood cannot grow the queue,\n\t * its payload memory, or its settler memory past the configured bounds.\n\t */\n\tprivate coalesceFeedIntoReplay(payload: string): Promise<void> {\n\t\tconst tail = this.operations[this.operations.length - 1];\n\t\tif (tail !== undefined && tail.kind === \"replay\") {\n\t\t\tconst previousLength = tail.payload.length;\n\t\t\ttail.payload = this.boundReplayPayload(tail.payload + payload);\n\t\t\tthis.pendingChars += tail.payload.length - previousLength;\n\t\t\treturn sharedSettler(tail);\n\t\t}\n\t\tconst operation: ReplayOperation = {\n\t\t\tkind: \"replay\",\n\t\t\tpayload: this.history.join(\"\"),\n\t\t\tsettled: null,\n\t\t\tsettlers: [],\n\t\t};\n\t\tthis.pendingChars += operation.payload.length;\n\t\treturn this.enqueue(operation, sharedSettler(operation));\n\t}\n\n\t/**\n\t * A resize whose snapshot would push the queued payload past the cap\n\t * collapses the whole queue into one resize at the latest dimensions:\n\t * every dropped operation's payload is already covered by the bounded\n\t * history snapshot, and their settlers settle with this operation.\n\t */\n\tprivate coalesceQueueIntoResize(cols: number, rows: number, snapshot: string): Promise<void> {\n\t\tconst operation: ResizeOperation = {\n\t\t\tkind: \"resize\",\n\t\t\tcols,\n\t\t\trows,\n\t\t\treplay: snapshot,\n\t\t\tsettled: null,\n\t\t\tsettlers: [],\n\t\t};\n\t\tfor (const queued of this.operations.splice(0, this.operations.length)) {\n\t\t\tfor (const settler of queued.settlers) operation.settlers.push(settler);\n\t\t\tqueued.settlers.length = 0;\n\t\t}\n\t\tthis.pendingChars = snapshot.length;\n\t\treturn this.enqueue(operation, sharedSettler(operation));\n\t}\n\n\tprivate boundReplayPayload(payload: string): string {\n\t\tif (payload.length <= this.maxReplayHistoryLength) return payload;\n\t\treturn sanitizeString(payload.slice(-this.maxReplayHistoryLength));\n\t}\n\n\tprivate async drain(): Promise<void> {\n\t\tif (this.draining) return;\n\t\tthis.draining = true;\n\t\ttry {\n\t\t\twhile (!this.disposed) {\n\t\t\t\tconst operation = this.operations.shift();\n\t\t\t\tif (operation === undefined) return;\n\t\t\t\tthis.pendingChars -= operation.kind === \"resize\" ? operation.replay.length : operation.payload.length;\n\t\t\t\ttry {\n\t\t\t\t\tawait this.run(operation);\n\t\t\t\t\tsettleOperation(operation.settlers, null);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tsettleOperation(operation.settlers, error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.draining = false;\n\t\t}\n\t}\n\n\tprivate async run(operation: ScreenOperation): Promise<void> {\n\t\tif (this.disposed) return;\n\t\tswitch (operation.kind) {\n\t\t\tcase \"write\":\n\t\t\t\tawait this.raceDisposal(this.write(operation.payload));\n\t\t\t\treturn;\n\t\t\tcase \"replay\":\n\t\t\t\tthis.terminal.reset();\n\t\t\t\tawait this.raceDisposal(this.write(operation.payload));\n\t\t\t\treturn;\n\t\t\tcase \"resize\":\n\t\t\t\tthis.terminal.dispose();\n\t\t\t\tthis.terminal = this.createTerminal(operation.cols, operation.rows);\n\t\t\t\tawait this.raceDisposal(this.write(operation.replay));\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\t/** A disposed terminal may never invoke its parse callback; do not hang. */\n\tprivate raceDisposal(written: Promise<void>): Promise<void> {\n\t\treturn Promise.race([written, this.whenDisposed]);\n\t}\n\n\tprivate write(payload: string): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\ttry {\n\t\t\t\tthis.terminal.write(payload, resolve);\n\t\t\t} catch (error) {\n\t\t\t\tconst sanitizedPayload = sanitizeString(payload);\n\t\t\t\tif (sanitizedPayload === payload) {\n\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.terminal.write(sanitizedPayload, resolve);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate appendHistory(payload: string): void {\n\t\tthis.history.push(payload);\n\t\tthis.historyLength += payload.length;\n\t\tthis.trimHistory();\n\t}\n\n\tprivate trimHistory(): void {\n\t\twhile (this.historyLength > this.maxReplayHistoryLength && this.history.length > 1) {\n\t\t\tconst removed = this.history.shift();\n\t\t\tif (removed === undefined) return;\n\t\t\tthis.historyLength -= removed.length;\n\t\t}\n\n\t\tif (this.historyLength <= this.maxReplayHistoryLength) return;\n\t\tconst [onlyChunk] = this.history;\n\t\tif (onlyChunk === undefined) return;\n\t\tconst trimmed = sanitizeString(onlyChunk.slice(-this.maxReplayHistoryLength));\n\t\tthis.history[0] = trimmed;\n\t\tthis.historyLength = trimmed.length;\n\t}\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-pty",
3
3
  "private": true,
4
- "version": "2026.8.30",
4
+ "version": "2026.9.2-3",
5
5
  "description": "Typed PTY session loader for Senpi persistent terminals",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -34,6 +34,9 @@ Applications can use the in-memory reference or provide an adapter for OpenTelem
34
34
 
35
35
  ```bash
36
36
  npm install @earendil-works/pi-telemetry
37
+
38
+ # Bun alternative
39
+ bun add @earendil-works/pi-telemetry
37
40
  ```
38
41
 
39
42
  ## Telemetry Concepts
@@ -449,14 +452,14 @@ The package does not use `AsyncLocalStorage` or another runtime-specific ambient
449
452
  From this package directory:
450
453
 
451
454
  ```bash
452
- npm test
453
- npm run build
455
+ bun run test
456
+ bun run build
454
457
  ```
455
458
 
456
459
  Repository-wide type checking, formatting, linting, and smoke checks run with:
457
460
 
458
461
  ```bash
459
- npm run check
462
+ bun run check
460
463
  ```
461
464
 
462
465
  ## License
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-telemetry",
3
- "version": "2026.8.30",
3
+ "version": "2026.9.2-3",
4
4
  "description": "Vendor-neutral telemetry contracts and typed schema utilities for pi",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -828,7 +828,7 @@ See `test/chat-simple.ts` for a complete chat interface example with:
828
828
 
829
829
  Run it:
830
830
  ```bash
831
- npx tsx test/chat-simple.ts
831
+ bunx tsx test/chat-simple.ts
832
832
  ```
833
833
 
834
834
  ## Development
@@ -836,12 +836,13 @@ npx tsx test/chat-simple.ts
836
836
  ```bash
837
837
  # Install dependencies (from monorepo root)
838
838
  npm install
839
+ # Bun alternative: bun install
839
840
 
840
841
  # Run type checking
841
- npm run check
842
+ bun run check
842
843
 
843
844
  # Run the demo
844
- npx tsx test/chat-simple.ts
845
+ bunx tsx test/chat-simple.ts
845
846
  ```
846
847
 
847
848
  ### Debug logging
@@ -849,5 +850,5 @@ npx tsx test/chat-simple.ts
849
850
  Set `PI_TUI_WRITE_LOG` to capture the raw ANSI stream written to stdout.
850
851
 
851
852
  ```bash
852
- PI_TUI_WRITE_LOG=/tmp/tui-ansi.log npx tsx test/chat-simple.ts
853
+ PI_TUI_WRITE_LOG=/tmp/tui-ansi.log bunx tsx test/chat-simple.ts
853
854
  ```
@@ -3,7 +3,7 @@
3
3
  Build both macOS architectures from the repository root:
4
4
 
5
5
  ```sh
6
- npm --prefix packages/tui run build:native:darwin
6
+ bun run --cwd packages/tui build:native:darwin
7
7
  ```
8
8
 
9
9
  The build uses macOS 11.0 as the arm64 deployment target and macOS 10.15 as the x86_64 deployment target. On macOS, `build.sh` finds Apple clang and the active macOS SDK through `xcrun`. Either an Intel or Apple Silicon host can build both outputs.
@@ -12,7 +12,7 @@ A non-macOS host needs a complete Darwin cross-toolchain, including a macOS SDK
12
12
 
13
13
  ```sh
14
14
  CC=/path/to/osxcross/clang SDKROOT=/path/to/MacOSX.sdk \
15
- npm --prefix packages/tui run build:native:darwin
15
+ bun run --cwd packages/tui build:native:darwin
16
16
  ```
17
17
 
18
18
  The SDK must be obtained and used in accordance with Apple's license. Plain Linux or Windows clang is not enough because the addon includes and links CoreGraphics.
@@ -3,7 +3,7 @@
3
3
  Build both Windows architectures from the repository root:
4
4
 
5
5
  ```sh
6
- npm --prefix packages/tui run build:native:win32
6
+ bun run --cwd packages/tui build:native:win32
7
7
  ```
8
8
 
9
9
  On Windows, the build uses the Microsoft C++ Build Tools from Visual Studio. `build.mjs` locates `VsDevCmd.bat`, initializes a developer environment for `amd64` and `arm64`, and builds the addon with `cl.exe`/`link.exe`.
@@ -16,7 +16,7 @@ For non-Windows cross-builds, or for custom Windows toolchains, set `PI_TUI_WIN3
16
16
  PI_TUI_WIN32_TOOLCHAIN=mingw \
17
17
  CC_X64=/path/to/x86_64-w64-mingw32-gcc \
18
18
  CC_ARM64=/path/to/aarch64-w64-mingw32-gcc \
19
- npm --prefix packages/tui run build:native:win32
19
+ bun run --cwd packages/tui build:native:win32
20
20
  ```
21
21
 
22
22
  The addon intentionally avoids the C runtime and links only against `kernel32`.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-tui",
3
- "version": "2026.8.30",
3
+ "version": "2026.9.2-3",
4
4
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi",
3
- "version": "2026.8.30",
3
+ "version": "2026.9.2-3",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -48,9 +48,9 @@
48
48
  "qa:app-server": "node scripts/qa-app-server/run-all.mjs"
49
49
  },
50
50
  "dependencies": {
51
- "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.8.30",
52
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.30",
53
- "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.8.30",
51
+ "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.9.2-3",
52
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.2-3",
53
+ "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.9.2-3",
54
54
  "@silvia-odwyer/photon-node": "0.3.4",
55
55
  "chalk": "6.0.0",
56
56
  "cross-spawn": "7.0.6",
@@ -70,8 +70,8 @@
70
70
  "@anthropic-ai/sdk": "0.120.0",
71
71
  "@aws-sdk/client-bedrock-runtime": "3.1116.0",
72
72
  "@bufbuild/protobuf": "2.14.0",
73
- "@code-yeongyu/senpi-codemode": "2026.8.30",
74
- "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.8.30",
73
+ "@code-yeongyu/senpi-codemode": "2026.9.2-3",
74
+ "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.9.2-3",
75
75
  "@modelcontextprotocol/sdk": "1.30.0",
76
76
  "@mozilla/readability": "0.6.0",
77
77
  "@opentelemetry/api": "1.9.1",
@@ -119,7 +119,7 @@
119
119
  "@csstools/css-parser-algorithms": "4.0.0",
120
120
  "@csstools/css-syntax-patches-for-csstree": "1.1.8",
121
121
  "@csstools/css-tokenizer": "4.0.0",
122
- "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.8.30",
122
+ "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.2-3",
123
123
  "@exodus/bytes": "1.15.1",
124
124
  "@google/genai": "2.18.0",
125
125
  "@hono/node-server": "2.1.1",