elanous 0.2.34 → 0.2.36

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 (802) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/chunks/{abb4b98b.163e0f56e84ae35d.js → 053a429e.9a63436527cc751c.js} +1 -1
  4. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +287 -0
  5. package/apps/pwa/out/_next/static/chunks/1201.afbfc5b1c5e5cbe4.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +64 -0
  11. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +36 -0
  12. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +149 -0
  15. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/2500.cbc1257b774aae52.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.js → 2683.c9773a0c589b031b.js} +4 -4
  20. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
  21. package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.js → 275-02ea4c2a33980422.js} +3 -3
  22. package/apps/pwa/out/_next/static/chunks/{ffdc3a04.b9c23c1b28dd4a96.js → 2812ca6a.3b9f4a7a08885744.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/{9550.d5f76828f972058c.js → 2986.45d7652e4f13557e.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/{8817.61bb7ffbba502ecb.js → 3136.30aaaa5fa03662a3.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{9131-fce7256c4180c4a5.js → 3148-98efd4869d660a87.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{3498.cf2a15a8a9e5b926.js → 3155.2587a55196ecb394.js} +3 -3
  31. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/{3103.84470c8445962f04.js → 3324.a09703033abcbd2f.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +8 -0
  36. package/apps/pwa/out/_next/static/chunks/3410.7f9af5ab77cbe65f.js +115 -0
  37. package/apps/pwa/out/_next/static/chunks/{3819.163d4777f0a597f6.js → 3538.a445e50bb359d068.js} +2 -2
  38. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +286 -0
  40. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{3414.172ad4ca2d9b08e8.js → 3727.7949ccaacaa71242.js} +2 -2
  42. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3757-180308bc61021b05.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
  45. package/apps/pwa/out/_next/static/chunks/3840-5825d56d46976a92.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.js → 3a3d9966.cc4d4585a2708e7c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +104 -0
  51. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{6740.43de73fc427c9fe2.js → 4286.b70c4520306817e8.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/4304.e9b2512834a9e23e.js +23 -0
  54. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{8548.036c344973968847.js → 4615.8525eb0add35eba6.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/{3411-f87314c6c66ebc73.js → 5085-bce4904931767ca6.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +93 -0
  59. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/{3110.0a7065f25c841818.js → 528.38ce20ef8aa251ff.js} +16 -16
  61. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +122 -0
  62. package/apps/pwa/out/_next/static/chunks/{1644.35dd25240ae24e4b.js → 552.b7d061ad91eeac51.js} +2 -2
  63. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{3837.722e053fb9f321ad.js → 5711.957b095705c12560.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/{2124.ed5bf480cea7f85b.js → 575.d929793a53f27c4b.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{7562.948255cbc3e79d33.js → 599.c39c571b6733f2a2.js} +2 -2
  70. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +79 -0
  71. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +27 -0
  84. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/{5446.edf141cff9ef647d.js → 6925.562d532110879886.js} +1 -1
  86. package/apps/pwa/out/_next/static/chunks/{7005.1623d2aea78eb85f.js → 6943.c6b24124853a47b2.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.js → 7481.39f7a4654907bf6e.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{2554.3b5e200f5f5cfcd6.js → 771.c3cdb6c1f7f47c02.js} +16 -16
  92. package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{3121.779fafe3e44612c5.js → 7891.03f910124a737985.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +62 -0
  100. package/apps/pwa/out/_next/static/chunks/{9a8cb466.cc9fc9e6e46038aa.js → 873d6c12.09bd499f57171543.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/{7431.3051e9b8a4372d2d.js → 8904.7d51af2dc033965c.js} +2 -2
  102. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +90 -0
  104. package/apps/pwa/out/_next/static/chunks/914.8abefd48d579547b.js +94 -0
  105. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{1895-60ed0e341c658bd4.js → 9250-072df22eaadaa6b5.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +77 -0
  111. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{2547.dd27303624cb4da8.js → 9514.131c52cc75fe6439.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9789.60f723d18097ec30.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9f31e478.fefcbcd3c388ebc5.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/{page-4fb31eb476dcbad3.js → page-083747f1d4518f61.js} +1 -1
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{5014f970-22bef0b5210f7d60.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{4fa33ebd.21c1bd5b294496e6.js → ceba0382.650712b56b85b582.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/da5ecc5c-b005ad8cac737d57.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +1 -0
  183. package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → uC-N0emedeNOFuaBQFv-I}/_buildManifest.js +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/bin/elanous.mjs +3 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  283. package/docs/goal-context/README.md +7 -0
  284. package/graphs/catalog/catalog.yaml +1 -1
  285. package/graphs/default-loop.yaml +63 -4
  286. package/graphs/document-loop.yaml +51 -3
  287. package/graphs/implement-loop.yaml +77 -4
  288. package/graphs/journey/ta-journey.yaml +11 -1
  289. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  290. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  291. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  292. package/graphs/operate-loop.yaml +51 -3
  293. package/graphs/release/recipes.yaml +6 -0
  294. package/graphs/release/release-loop.yaml +17 -4
  295. package/graphs/research-loop.yaml +137 -3
  296. package/graphs/test-diet/test-diet.yaml +3 -0
  297. package/graphs/wizard/recipes.yaml +44 -0
  298. package/graphs/wizard/wizard-loop.yaml +44 -0
  299. package/graphs/work/research-report.yaml +2 -0
  300. package/package.json +1 -1
  301. package/scripts/ci-typecheck-changed.ts +139 -5
  302. package/scripts/coord-role-pack.ts +19 -6
  303. package/scripts/first10-gate.ts +416 -0
  304. package/scripts/fleet/wsl-node-setup.sh +432 -0
  305. package/scripts/hq/standby-snapshot.ts +17 -12
  306. package/scripts/release-loop/docs-land-node.ts +21 -5
  307. package/scripts/release-loop/docs-node.ts +204 -8
  308. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  309. package/scripts/release-loop/gate-node.ts +427 -72
  310. package/scripts/release-loop/gate-partial.ts +65 -11
  311. package/scripts/release-loop/gate-radius-live.ts +177 -0
  312. package/scripts/release-loop/gate-radius-shadow.ts +1 -1
  313. package/scripts/release-loop/node-verdict.ts +14 -1
  314. package/scripts/release-loop/npm-publish-node.ts +66 -12
  315. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  316. package/scripts/release-loop/pwa-remote.ts +166 -0
  317. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  318. package/scripts/release-loop/resume-cap.ts +14 -34
  319. package/scripts/release-loop/resume-release.ts +78 -15
  320. package/scripts/release-loop/traffic-node.ts +59 -0
  321. package/scripts/release-loop/traffic-transition.ts +159 -0
  322. package/scripts/release-loop/unattended-release.ts +2 -0
  323. package/scripts/rhythm/daily.ts +137 -3
  324. package/scripts/test-diet/lib.ts +6 -1
  325. package/scripts/test-diet/node.ts +194 -13
  326. package/scripts/ux-sim.ts +92 -0
  327. package/skills/README.md +1 -0
  328. package/src/acp/core-turn-bridge.ts +48 -6
  329. package/src/agent/delegate-hint.ts +16 -0
  330. package/src/agent/runner.ts +82 -2
  331. package/src/agent/self-ambient-cache.ts +8 -0
  332. package/src/agent/task-notification.ts +56 -10
  333. package/src/agent/types.ts +4 -0
  334. package/src/agent-substrate/acp-reviewer.ts +39 -4
  335. package/src/agent-substrate/pr-reviewer.ts +72 -3
  336. package/src/agent-substrate/review-intent.ts +29 -2
  337. package/src/agent-substrate/review-observation.ts +3 -0
  338. package/src/agent-substrate/self-review-cli.ts +229 -28
  339. package/src/autopilot/mission-codebase-gate.ts +141 -12
  340. package/src/autopilot/pr-manager.ts +240 -41
  341. package/src/boot/daemon-tools/self-implement.ts +1 -0
  342. package/src/budget/run-usage-rollup.ts +1 -0
  343. package/src/budget/usage-outcomes.ts +8 -4
  344. package/src/capture/tui-self-report.ts +102 -0
  345. package/src/chat/goal-continue-verdict.ts +41 -0
  346. package/src/chat/index.ts +30 -6
  347. package/src/chat/internal-turn-origin.ts +1 -0
  348. package/src/chat/paste-fold.ts +86 -0
  349. package/src/chat/pickers/modal-runtime.ts +10 -27
  350. package/src/chat/tool-render/block.ts +32 -0
  351. package/src/chat/tool-render/dispatch.ts +2 -20
  352. package/src/chat/tool-render/result-text.ts +98 -0
  353. package/src/chat/turn-typeahead.ts +70 -7
  354. package/src/cli/agent-cli.ts +13 -2
  355. package/src/cli/config-audit.ts +119 -0
  356. package/src/cli/doctor-cli.ts +26 -1
  357. package/src/cli/guardian-cli.ts +10 -0
  358. package/src/cli/herdr-cli.ts +34 -0
  359. package/src/cli/light-entry-route.ts +50 -7
  360. package/src/cli/log-event-names.ts +2 -0
  361. package/src/cli/make-cli.ts +247 -11
  362. package/src/cli/msg-cli.ts +117 -3
  363. package/src/cli/pod-cli.ts +77 -3
  364. package/src/cli/pr-cli.ts +34 -18
  365. package/src/cli/pr-land-base-read.ts +11 -2
  366. package/src/cli/pr-land-heavy-remote.ts +6 -3
  367. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  368. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  369. package/src/cli/pr-land-recovery.ts +117 -1
  370. package/src/cli/pty-takeover-cli.ts +8 -7
  371. package/src/cli/release-checklist-read-cli.ts +79 -0
  372. package/src/cli/release-cli.ts +92 -106
  373. package/src/cli/release-single-flight.ts +1 -1
  374. package/src/cli/remote-resolve.ts +1 -1
  375. package/src/cli/root-tui-entry.ts +48 -0
  376. package/src/cli/sim-cli.ts +22 -0
  377. package/src/cli/tasks-card-show.ts +162 -0
  378. package/src/cli/tasks-cli.ts +1065 -338
  379. package/src/cli/tasks-read-cli.ts +197 -0
  380. package/src/cli/usage-cli.ts +13 -11
  381. package/src/clipboard/history.ts +179 -13
  382. package/src/config.ts +8 -1
  383. package/src/core-turn/run-core-turn.ts +4 -2
  384. package/src/core-turn/run-goal-loop.ts +73 -16
  385. package/src/core-turn/types.ts +6 -1
  386. package/src/dashboard/chat/acp-chat.ts +8 -0
  387. package/src/dashboard/context/keys.ts +8 -31
  388. package/src/dashboard/index.ts +280 -59
  389. package/src/dashboard/input/agent-wake.ts +7 -1
  390. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  391. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  392. package/src/dashboard/input/goal-continue.ts +210 -0
  393. package/src/dashboard/input/goal-interim.ts +2 -0
  394. package/src/dashboard/input/internal-turn.ts +2 -8
  395. package/src/dashboard/input/seat-autowake.ts +9 -7
  396. package/src/dashboard/input/turn-autoheal.ts +52 -0
  397. package/src/dashboard/render/theme-resolver.ts +33 -4
  398. package/src/dashboard/seat-boot-preamble.ts +132 -5
  399. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  400. package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
  401. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  402. package/src/dashboard/stale-install-check.ts +3 -99
  403. package/src/debug/batch-queue.ts +119 -0
  404. package/src/debug/tui-log-tag.ts +67 -0
  405. package/src/display/agent-surface.ts +7 -0
  406. package/src/domains/schedule-registry.ts +16 -2
  407. package/src/domains/standalone-log-sink.ts +15 -2
  408. package/src/esc-abort-gate.ts +69 -0
  409. package/src/git-fs/idle-refresh.ts +76 -0
  410. package/src/git-fs/index.ts +18 -7
  411. package/src/git-fs/worktree.ts +137 -5
  412. package/src/graph-kinds/registry.ts +2 -2
  413. package/src/graph-runner/graph-cli.ts +18 -0
  414. package/src/graph-runner/runner.ts +173 -21
  415. package/src/graph-wizard/generate.ts +108 -4
  416. package/src/graph-wizard/steps.ts +15 -0
  417. package/src/grok/credential.ts +10 -3
  418. package/src/grounding/proactive-ground.ts +86 -0
  419. package/src/harness/control-inbox.ts +49 -1
  420. package/src/harness/harness-cli-command.ts +163 -35
  421. package/src/harness/harness-incidents.ts +85 -1
  422. package/src/harness/launch-utterance-ledger.ts +208 -0
  423. package/src/harness/pod-control-send.ts +33 -5
  424. package/src/harness/self-send-remote.ts +69 -0
  425. package/src/harness/self-send-routing-guard.ts +6 -0
  426. package/src/harness/self-send-target.ts +4 -3
  427. package/src/impl-discipline/detector.ts +16 -4
  428. package/src/impl-discipline/system-prompt.ts +11 -0
  429. package/src/impl-discipline/types.ts +2 -2
  430. package/src/index.ts +822 -154
  431. package/src/input-core/context-key-runtime.ts +21 -0
  432. package/src/intake-plane/already-built-hint.ts +4 -2
  433. package/src/intake-plane/requirement-funnel.ts +29 -1
  434. package/src/light-cli.ts +32 -11
  435. package/src/llm/opengateway-models.ts +11 -0
  436. package/src/llm/provider-credentials.ts +14 -0
  437. package/src/llm/provider-detect.ts +8 -1
  438. package/src/llm/runtime-model-family.ts +2 -1
  439. package/src/llm-wellformed.ts +70 -0
  440. package/src/llm.ts +247 -59
  441. package/src/loops/msg-wake.ts +35 -39
  442. package/src/loops/orchestrator/inbox.ts +59 -11
  443. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  444. package/src/loops/orchestrator/tick.ts +5 -1
  445. package/src/maturity/feature-maturity.ts +1 -1
  446. package/src/model-tier/llm-tier-map.ts +15 -1
  447. package/src/models/prompts.ts +17 -2
  448. package/src/msg/msg-post-office.ts +116 -0
  449. package/src/mss/logging/log-store.ts +79 -22
  450. package/src/native-tool-catalog.ts +15 -1
  451. package/src/nexus/api/decisions-route.ts +38 -18
  452. package/src/nexus/api/graph-wizard-api.ts +20 -2
  453. package/src/nexus/api/loop-resources.ts +13 -1
  454. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  455. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  456. package/src/oauth/codex.ts +7 -0
  457. package/src/onboarding/first-run.ts +37 -6
  458. package/src/onboarding/web-first.ts +43 -11
  459. package/src/ops/overview-collect.ts +30 -9
  460. package/src/ops/overview.ts +22 -9
  461. package/src/persona/loader.ts +11 -0
  462. package/src/persona/types.ts +8 -0
  463. package/src/pr-tool/census.ts +261 -27
  464. package/src/prompt-library/session-guidance.ts +14 -0
  465. package/src/provider-summary.ts +8 -0
  466. package/src/pty-shell/herdr-agent-report.ts +118 -9
  467. package/src/pty-shell/herdr-prompt.ts +266 -0
  468. package/src/pty-shell/pty-control-ipc.ts +151 -8
  469. package/src/pty-shell/pty-manifest.ts +7 -0
  470. package/src/pty-shell/pty-special-keys.ts +42 -2
  471. package/src/pty-shell/stale-install-check.ts +99 -0
  472. package/src/pty-shell/tui-run-state.ts +14 -2
  473. package/src/release-loop/auto-start.ts +20 -2
  474. package/src/release-loop/checklist.ts +100 -4
  475. package/src/release-loop/landed-but-yellow.ts +129 -5
  476. package/src/release-loop/light-rc.ts +1 -0
  477. package/src/release-loop/rehearsal.ts +37 -21
  478. package/src/repl/index.ts +192 -17
  479. package/src/repl/ops-msg-bridge.ts +32 -0
  480. package/src/seat-loop/knowhow-lint.ts +1 -1
  481. package/src/self-dev/ask-launch-flow.ts +44 -5
  482. package/src/self-dev/cli-help-text.ts +17 -0
  483. package/src/self-dev/decompose-proposal.ts +172 -20
  484. package/src/self-dev/decompose.ts +61 -0
  485. package/src/self-dev/dev-cli.ts +48 -12
  486. package/src/self-dev/dev-pipeline.ts +8 -2
  487. package/src/self-dev/draft-residue.ts +37 -1
  488. package/src/self-dev/draft-sweep.ts +137 -11
  489. package/src/self-dev/draft-triage-rules.ts +138 -0
  490. package/src/self-dev/fleet-reduce.ts +3 -2
  491. package/src/self-dev/glm-credential-guard.ts +77 -0
  492. package/src/self-dev/graph-front-nodes.ts +112 -0
  493. package/src/self-dev/graph-journey-nodes.ts +2 -0
  494. package/src/self-dev/graph-journey-route.ts +12 -2
  495. package/src/self-dev/harness-run-cli.ts +3 -15
  496. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  497. package/src/self-dev/orchestrate-cli.ts +68 -3
  498. package/src/self-dev/orchestrate.ts +116 -17
  499. package/src/self-dev/review-provider-fallback.ts +35 -1
  500. package/src/self-dev/run-supervisor.ts +55 -2
  501. package/src/self-dev/run-types.ts +1 -1
  502. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  503. package/src/self-dev/shard-aggregate.ts +42 -5
  504. package/src/self-dev/shard-run.ts +8 -1
  505. package/src/self-health/autoheal.ts +153 -0
  506. package/src/self-health/signatures.ts +6 -0
  507. package/src/self-implement/blocked-draft-policy.ts +20 -0
  508. package/src/self-implement/classify-shadow.ts +3 -7
  509. package/src/self-implement/device-first.ts +116 -0
  510. package/src/self-implement/doctor-visit.ts +257 -2
  511. package/src/self-implement/evidence-command-budget.ts +80 -0
  512. package/src/self-implement/gate-baseline.ts +56 -17
  513. package/src/self-implement/gate-cli.ts +1 -0
  514. package/src/self-implement/gate-remote.ts +31 -20
  515. package/src/self-implement/goal-author-cli.ts +1 -0
  516. package/src/self-implement/goal-author-decompose.ts +534 -45
  517. package/src/self-implement/goal-author.ts +282 -7
  518. package/src/self-implement/goal-elaborate.ts +449 -0
  519. package/src/self-implement/goal-refine.ts +273 -0
  520. package/src/self-implement/graph-overlay-yaml.ts +14 -3
  521. package/src/self-implement/graph-variant.ts +40 -6
  522. package/src/self-implement/headless-elanous-driver.ts +19 -3
  523. package/src/self-implement/off-diff-evidence.ts +58 -6
  524. package/src/self-implement/orchestrator.ts +370 -62
  525. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  526. package/src/self-implement/pwa-import-graph.ts +1 -1
  527. package/src/self-implement/rework-budget-judgment.ts +5 -8
  528. package/src/self-implement/rework-policy.ts +30 -0
  529. package/src/self-implement/run-ledger.ts +108 -0
  530. package/src/self-implement/run-stop.ts +10 -1
  531. package/src/self-implement/run-ttl.ts +38 -24
  532. package/src/self-implement/running-runs.ts +29 -1
  533. package/src/self-implement/scope-adjacency.ts +115 -0
  534. package/src/self-implement/seams.ts +187 -28
  535. package/src/self-implement/stop-autoheal.ts +87 -1
  536. package/src/self-implement/wiring-check.ts +358 -0
  537. package/src/session-runtime/index.ts +1 -1
  538. package/src/setup/llm-env-detect.ts +5 -0
  539. package/src/shell-env-bootstrap.ts +11 -4
  540. package/src/skills/runner.ts +4 -2
  541. package/src/skills/tools/agent.ts +408 -40
  542. package/src/skills/tools/msg-ask.ts +100 -0
  543. package/src/skills/tools/ops-ledger.ts +2 -1
  544. package/src/skills/tools/schedule-wakeup.ts +23 -4
  545. package/src/skills/tools/shell.ts +61 -6
  546. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  547. package/src/skills/tools/terminal-modal.ts +10 -8
  548. package/src/skills/url-router.ts +41 -1
  549. package/src/smart-wizard/run.ts +66 -0
  550. package/src/status/bar.ts +34 -6
  551. package/src/status/status-provider-info.ts +37 -6
  552. package/src/steward/hold-hygiene.ts +24 -6
  553. package/src/steward/rejudge-tick.ts +10 -2
  554. package/src/steward/ta-repair-event-collect.ts +17 -6
  555. package/src/steward/triage-budget.ts +194 -0
  556. package/src/steward/triage.ts +20 -3
  557. package/src/task-agent/actions.ts +72 -2
  558. package/src/task-agent/green-sweep.ts +4 -0
  559. package/src/task-agent/land-queue.ts +21 -8
  560. package/src/task-agent/live-moves.ts +182 -10
  561. package/src/task-agent/mission.ts +30 -0
  562. package/src/task-agent/parent-host.ts +123 -3
  563. package/src/task-agent/rejudge-on-head.ts +15 -0
  564. package/src/task-agent/repair-cycle.ts +138 -32
  565. package/src/task-agent/repair-next-move.ts +31 -3
  566. package/src/task-agent/repair-outcomes.ts +29 -0
  567. package/src/task-agent/repair-worker.ts +14 -4
  568. package/src/task-agent/shadow.ts +48 -4
  569. package/src/task-agent/task-card-prefix.ts +2 -0
  570. package/src/task-agent/task-hand.ts +525 -57
  571. package/src/task-agent/task-parent-role-llm.ts +36 -0
  572. package/src/task-agent/tier-split.ts +196 -0
  573. package/src/task-agent/work-order-build.ts +2 -0
  574. package/src/task-agent/work-order.ts +3 -2
  575. package/src/task-orchestrator/generator-prompt.ts +60 -11
  576. package/src/task-orchestrator/surfaces/pod-account-broker.ts +42 -0
  577. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  578. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  579. package/src/task-orchestrator/surfaces/pod-command-job.ts +130 -11
  580. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  581. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  582. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  583. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  584. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +19 -2
  585. package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
  586. package/src/task-orchestrator/surfaces/pod-provenance.ts +82 -0
  587. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  588. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  589. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  590. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  591. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  592. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  593. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  594. package/src/task-orchestrator/surfaces/pod-source-receive.ts +18 -0
  595. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  596. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +6 -2
  597. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +7 -0
  598. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +521 -40
  599. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  600. package/src/task-orchestrator/surfaces/self-implement-pod.ts +759 -50
  601. package/src/task-orchestrator/surfaces/self-implement.ts +65 -2
  602. package/src/tool-runtime/index.ts +15 -2
  603. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  604. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  605. package/src/tty-foreground.ts +155 -0
  606. package/src/tui/README.md +2 -0
  607. package/src/tui/chat/background-job-status.ts +54 -0
  608. package/src/tui/chat/goal-interim.ts +173 -0
  609. package/src/tui/chat/log-view.ts +267 -0
  610. package/src/tui/chat/self-health-status.ts +232 -0
  611. package/src/tui/entry.ts +695 -0
  612. package/src/tui/input/composer.ts +151 -0
  613. package/src/tui/seat-mail-boot.ts +59 -0
  614. package/src/tui/slash/compact-command.ts +7 -0
  615. package/src/tui/slash/compact.ts +94 -0
  616. package/src/tui/slash/new-session.ts +35 -0
  617. package/src/tui/slash/resume.ts +75 -0
  618. package/src/tui-client/local-chat-turn.ts +282 -0
  619. package/src/tui-client/local-harness-command.ts +63 -0
  620. package/src/tui-client/local-provider-command.ts +184 -0
  621. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  622. package/src/tui-client/next-loop-command.ts +70 -0
  623. package/src/tui-client/next-wakeup.ts +191 -0
  624. package/src/tui.ts +37 -0
  625. package/src/ui/modal-adapter.ts +2 -2
  626. package/src/user-config.ts +4 -2
  627. package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
  628. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  629. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  630. package/src/ux-sim/event-monkey.ts +379 -0
  631. package/src/ux-sim/fake-bin.ts +87 -7
  632. package/src/ux-sim/fake-herdr.ts +238 -0
  633. package/src/ux-sim/fake-llm.ts +111 -6
  634. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  635. package/src/ux-sim/fault-nextmove-dispatch.ts +367 -0
  636. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  637. package/src/ux-sim/fault-scope-escape-lift.ts +216 -0
  638. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  639. package/src/ux-sim/goal-device.ts +619 -0
  640. package/src/ux-sim/in-process-cli.ts +22 -5
  641. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  642. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  643. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  644. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  645. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  646. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  647. package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
  648. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  649. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  650. package/src/ux-sim/subagent-tools-device.ts +81 -0
  651. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  652. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  653. package/src/version/packed-revision.json +1 -1
  654. package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +0 -79
  655. package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +0 -94
  658. package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +0 -23
  660. package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +0 -115
  662. package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +0 -8
  663. package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/2987-30cf9c2eb7b8bdd5.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/3001-5a52788c813b6113.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +0 -104
  681. package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +0 -286
  682. package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +0 -149
  683. package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +0 -148
  684. package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +0 -64
  685. package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +0 -74
  688. package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/5028-f0722e6114c313e7.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/5249.96a848656b582a93.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +0 -62
  695. package/apps/pwa/out/_next/static/chunks/5489.ec2dd1b5272a19dc.js +0 -24
  696. package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +0 -77
  708. package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +0 -90
  711. package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +0 -287
  717. package/apps/pwa/out/_next/static/chunks/7448.478958ffbbba0ac0.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +0 -27
  722. package/apps/pwa/out/_next/static/chunks/7952.b192c31b6a0e00cc.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +0 -36
  725. package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +0 -93
  738. package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +0 -24
  740. package/apps/pwa/out/_next/static/chunks/9739.8d5f36ac67a3b236.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-398c0faa173203f7.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/term/page-df3445b207ceceab.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +0 -122
  795. package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +0 -1
  802. /package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
@@ -45,6 +45,8 @@ import {
45
45
  import { writeHarnessScreen } from '../harness/harness-screen.js';
46
46
  import { runningBuild, startTuiRunStateRecorder } from '../pty-shell/tui-run-state.js';
47
47
  import { debug } from '../debug/log.js';
48
+ import { setTuiLogName, setTuiLogSession } from '../debug/tui-log-tag.js';
49
+ import { getActiveSessionId } from '../session/index.js';
48
50
  import { routeExternalInput, type ExternalInputRoute } from '../input/external-input-queue.js';
49
51
 
50
52
  export interface TuiFrameObserverCfg {
@@ -151,6 +153,97 @@ export function createTuiControlTarget(surfaceId: string, deps: TuiControlTarget
151
153
  };
152
154
  }
153
155
 
156
+ // ── 재기동 세션 소유(TUI-H9-ACTIVE-SESSION-ID · 0.2.36) ──
157
+ //
158
+ // 재기동은 «지금 이 TUI 가 보여 주던 대화» 로만 이어 간다. 기동 때의 `--resume` 값이나 전역 최신
159
+ // 세션은 이 TUI 의 것이 아닐 수 있으므로, 이 TUI 가 화면을 그리며 «직접 본» 활성 id 만 여기 적는다.
160
+ // 확인이 안 되면 재기동을 막는 쪽이 기본값이다(⛔ 비슷한 id 로 메우지 않는다).
161
+
162
+ export interface TuiOwnedSession {
163
+ readonly sessionId: string;
164
+ /** 이 TUI 가 그 대화를 «화면으로 확인한» 시각(`at`). */
165
+ readonly at: number;
166
+ }
167
+
168
+ let ownedSession: TuiOwnedSession | null = null;
169
+
170
+ function normalizeSessionId(value: string | null | undefined): string | null {
171
+ const id = typeof value === 'string' ? value.trim() : '';
172
+ return id || null;
173
+ }
174
+
175
+ /** 이 TUI 가 지금 보여 주는 대화 id 를 적는다. 빈 값이면 «소유 없음» 으로 되돌린다(추측 금지). */
176
+ export function claimTuiOwnedSession(
177
+ sessionId: string | null | undefined,
178
+ at: number = Date.now(),
179
+ ): TuiOwnedSession | null {
180
+ const id = normalizeSessionId(sessionId);
181
+ ownedSession = id ? { sessionId: id, at } : null;
182
+ setTuiLogSession(id);
183
+ return ownedSession;
184
+ }
185
+
186
+ /** 이 TUI 가 화면으로 확인한 대화 — 모르면 null(전역 최신·기동 resume 으로 메우지 않는다). */
187
+ export function getTuiOwnedSession(): TuiOwnedSession | null {
188
+ return ownedSession;
189
+ }
190
+
191
+ // 재기동 «요청» — 사용자가 q 로 끄는 것은 재기동이 아니다(기본 동작 보존). 재기동은 누군가(H9 유휴
192
+ // 재기동 방아쇠 등)가 «다시 뜨려고» TUI 를 닫을 때만 일어난다 — 그 쪽이 닫기 전에 이것을 부른다.
193
+ let restartRequest: { readonly reason: string; readonly at: number } | null = null;
194
+
195
+ /** TUI 를 «다시 뜨려고» 닫는다고 적는다 — 종료 경계(`exitTuiRun`)가 한 번 읽고 지운다. */
196
+ export function requestTuiSelfRestart(reason: string, at: number = Date.now()): void {
197
+ const why = reason.trim();
198
+ restartRequest = { reason: why || 'unspecified', at };
199
+ }
200
+
201
+ /** 재기동 요청을 꺼낸다(꺼내면 사라진다) — 없으면 null = 사용자 종료. */
202
+ export function takeTuiSelfRestartRequest(): { readonly reason: string; readonly at: number } | null {
203
+ const request = restartRequest;
204
+ restartRequest = null;
205
+ return request;
206
+ }
207
+
208
+ /** 재기동을 막는 이유 — 전부 «확인 실패» 다(전역 최신·기동 resume 으로 폴백하지 않는다). */
209
+ export type TuiRestartBlockReason =
210
+ /** 지금 이 TUI 가 보여 주는 활성 대화가 없다(집중 표식 비었음·읽기 실패). */
211
+ | 'no-active-session'
212
+ /** 이 TUI 가 화면으로 확인한 대화 기록이 없다(발행된 프레임 0). */
213
+ | 'no-owned-session'
214
+ /** 마지막 관측 뒤 활성 대화가 움직였다 — 어느 쪽이 맞는지 확인할 수 없다. */
215
+ | 'owned-session-mismatch'
216
+ /** 확인한 id 의 대화가 저장소에 없다. */
217
+ | 'active-session-missing';
218
+
219
+ export type TuiRestartSessionDecision =
220
+ | { readonly ok: true; readonly sessionId: string; readonly claimedAt: number }
221
+ | { readonly ok: false; readonly reason: TuiRestartBlockReason };
222
+
223
+ /**
224
+ * 재기동에 실을 세션 id 를 정한다. `owned`(이 TUI 가 본 것)와 `liveActiveSessionId`(지금 집중된 것)가
225
+ * «같고 그 대화가 실재할 때만» 통과한다 — 하나라도 어긋나면 막는다.
226
+ */
227
+ export function decideTuiRestartSession(input: {
228
+ readonly owned: TuiOwnedSession | null;
229
+ readonly liveActiveSessionId: string | null | undefined;
230
+ readonly sessionExists: (sessionId: string) => boolean;
231
+ }): TuiRestartSessionDecision {
232
+ const live = normalizeSessionId(input.liveActiveSessionId);
233
+ if (!live) return { ok: false, reason: 'no-active-session' };
234
+ const owned = input.owned;
235
+ if (!owned) return { ok: false, reason: 'no-owned-session' };
236
+ if (owned.sessionId !== live) return { ok: false, reason: 'owned-session-mismatch' };
237
+ let exists = false;
238
+ try {
239
+ exists = input.sessionExists(live);
240
+ } catch {
241
+ exists = false;
242
+ }
243
+ if (!exists) return { ok: false, reason: 'active-session-missing' };
244
+ return { ok: true, sessionId: live, claimedAt: owned.at };
245
+ }
246
+
154
247
  export interface TuiSelfReportDeps {
155
248
  surfaceId?: string;
156
249
  /** `elanous --name <name>` — 자기 manifest 행 별명. `pty list`·`pty snapshot <name>` 이 이것으로 부른다. */
@@ -192,6 +285,9 @@ export interface TuiSelfReportDeps {
192
285
  lookupRow?: (surfaceId: string) => TuiOwnRowView | null;
193
286
  /** 재등록 뒤 실행 판(build) 칸을 다시 적는다 — 기본 = 기동 때 판(`runningBuild`). */
194
287
  restoreBuild?: (surfaceId: string) => void;
288
+ /** 이 TUI 가 지금 보여 주는 대화 id 를 읽는다 — 프레임을 발행할 때마다 소유 기록을 갱신한다
289
+ * (TUI-H9). 기본 = `getActiveSessionId()`. ⛔ 읽기 실패는 «모른다»(소유 없음)로 접는다. */
290
+ readActiveSessionId?: () => string | null;
195
291
  /** 박동 스케줄러 — 기본 setInterval(unref). 시험이 박동을 손으로 돌린다. */
196
292
  driveHeartbeat?: (tick: () => void, ms: number) => (() => void);
197
293
  /** SIGCONT 수신 훅(행 상실 단서) — 반환 = 해제. 기본 = process.on('SIGCONT'). */
@@ -290,6 +386,7 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
290
386
  controlInitStage = 'publish-manifest';
291
387
  initDisposers.push({ stage: 'rollback-manifest', dispose: () => rollbackRow(surfaceId) });
292
388
  const nickname = deps.nickname?.trim() || undefined;
389
+ setTuiLogName(nickname);
293
390
  registerRow(surfaceId, now(), nickname);
294
391
  if (nickname) debug.log('pty.rename', 'tui-launch-name', { ptyId: surfaceId, nickname });
295
392
  } catch (error) {
@@ -338,6 +435,9 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
338
435
  const emitText = (text: string, cols: number, rows: number): void => {
339
436
  const at = now();
340
437
  lastEmittedText = text;
438
+ // TUI-H9 — 이 프레임이 «지금 이 TUI 가 보여 주는 대화» 의 소유 기록이다. 재기동은 이 id 로만 잇는다
439
+ // (읽기 실패 → 소유 없음 → 재기동 막힘 · 다른 세션으로 대체하지 않는다).
440
+ try { claimTuiOwnedSession(readActiveSessionId(), at); } catch { claimTuiOwnedSession(null, at); }
341
441
  const frame: SelfReportFrame = { surfaceId, instance, kind: 'tui', mode: 'self-report', text, cols, rows, at, ...(runId ? { runId } : {}) };
342
442
  try { publishFrame(frame); } catch { /* fail-soft */ }
343
443
  // `at` is shared with the manifest write → its internal throttle keys
@@ -391,6 +491,8 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
391
491
  ?? (deps.registerRow ? () => ({ alive: true }) : (id: string) => getPtyManifest(id, { strict: true }));
392
492
  const restoreBuild = deps.restoreBuild ?? (deps.registerRow ? () => {} : (id: string) => { updatePtyManifestBuild(id, runningBuild()); });
393
493
  const logRowMissing = deps.logRowMissing ?? ((data: TuiRowMissingEvent) => debug.log('tui.self-report', 'row-missing', data));
494
+ const readActiveSessionId: () => string | null = deps.readActiveSessionId
495
+ ?? (() => { try { return getActiveSessionId(); } catch { return null; } });
394
496
  const rowNickname = deps.nickname?.trim() || undefined;
395
497
  let lastSeenAt = now();
396
498
  let lastBeatAt = lastSeenAt;
@@ -0,0 +1,41 @@
1
+ const TAIL_CHARS = 160;
2
+ // eslint-disable-next-line no-control-regex
3
+ const ANSI = /\x1b\[[0-9;?]*[ -/]*[@-~]/g;
4
+ const NON_REPLY_LINE = /^\s*(?:✔ 완료|✘ 실패|응답 완료|응답 중|라우팅:|󰧑|⚙️|도구:|나:|↻ 자동 재개|⏰|⏸|⏹|❯)/u;
5
+ const PLEDGE_ALTS = [
6
+ '[가-힣]+겠습니다', '[가-힣]+겠다', '[가-힣]*[갈낼될들랄릴볼할줄쓸올만]게요',
7
+ '(?:해야|진행해야|완료해야|만들어야|실행해야|마쳐야|끝내야) (?:합니다|한다|해요|됩니다)',
8
+ '(?:멈췄습니다|멈춰 있었습니다|중단했습니다)', "\\bI(?:'ll| will| need to| should)\\b[^?]*",
9
+ "\\blet me\\b[^?]*", "\\bnext,? I\\b[^?]*",
10
+ ].map((p) => `(?:${p})`).join('|');
11
+ const PLEDGE_RE = new RegExp(`(?:${PLEDGE_ALTS})[.!。…\\s]*$`, 'iu');
12
+ const ACK_END = /(?:알겠|좋겠|감사하겠|되겠|모르겠|있겠|없겠|같겠)(?:습니다|다)[.!。…\s]*$/u;
13
+ const ASKS_HUMAN = /(?:\?|?|까요[.!]?\s*$|주세요[.!]?\s*$|주시면|원하시면|알려 주|말씀해|선택해|승인(?:해 주세요|이 필요)|괜찮을까|어떨까|확인 부탁|let me know|please (?:confirm|choose)|tell me (?:if|which|what))/iu;
14
+
15
+ export type GoalContinueVerdict =
16
+ | { pledge: true; phrase: string }
17
+ | { pledge: false; reason: 'no-reply' | 'asks-human' | 'not-pledge' };
18
+
19
+ export function replyTailFromLines(lines: readonly string[]): string | null {
20
+ const reply: string[] = [];
21
+ for (let i = lines.length - 1; i >= 0 && reply.length < 6; i--) {
22
+ const plain = lines[i]!.replace(ANSI, '').trimEnd();
23
+ if (!plain.trim()) { if (reply.length) break; continue; }
24
+ if (NON_REPLY_LINE.test(plain)) { if (reply.length) break; continue; }
25
+ reply.unshift(plain.trim());
26
+ }
27
+ if (!reply.length) return null;
28
+ const text = reply.join(' ').replace(/\s+/g, ' ').trim();
29
+ return text.length > TAIL_CHARS ? text.slice(-TAIL_CHARS) : text;
30
+ }
31
+
32
+ export function classifyReplyTail(tail: string | null): GoalContinueVerdict {
33
+ if (!tail) return { pledge: false, reason: 'no-reply' };
34
+ const sentences = tail.split(/(?<=[.!?。?])\s+/u).filter(Boolean);
35
+ const last = sentences.at(-1) ?? tail;
36
+ if (ASKS_HUMAN.test(last)) return { pledge: false, reason: 'asks-human' };
37
+ if (ACK_END.test(last)) return { pledge: false, reason: 'not-pledge' };
38
+ const m = PLEDGE_RE.exec(last);
39
+ if (!m) return { pledge: false, reason: 'not-pledge' };
40
+ return { pledge: true, phrase: m[0].trim() };
41
+ }
package/src/chat/index.ts CHANGED
@@ -19,6 +19,8 @@ import type { PromptRowOwner } from '../display/prompt-row-owner.js';
19
19
  // "history-as-source-of-truth" pattern claude-code-fork uses.
20
20
  import type { ContentBlock } from '../llm.js';
21
21
  import { debug } from '../debug/log.js';
22
+ import { createPasteFold } from './paste-fold.js';
23
+ import { hasClipboardImage, readClipboardText } from '../clipboard/index.js';
22
24
  import { matchTextInputGlobalAction } from './global-actions.js';
23
25
  import { CTRL_C_ARM_MS, resolveCtrlCInInput } from './ctrl-c-in-input.js';
24
26
  import { isTextInputQuitChord } from './input-quit-chord.js';
@@ -742,6 +744,9 @@ export async function textInput(opts: {
742
744
  * abort the input session.
743
745
  */
744
746
  onPasteImage?: () => Promise<string | null>;
747
+ /** TUI-PASTE-ECHO — Ctrl+V 클립보드 읽기(시험 주입용 · 기본 = clipboard 모듈). 이미지가 없으면 글을 붙여넣는다. */
748
+ clipboardHasImage?: () => Promise<boolean>;
749
+ clipboardText?: () => Promise<string | null>;
745
750
  /** Dynamic completer for arg-level suggestions (e.g. plugin names). */
746
751
  getArgSuggestions?: GetArgSuggestions;
747
752
  /** Dynamic completer for `$` skill invocations. */
@@ -927,7 +932,12 @@ export async function textInput(opts: {
927
932
  host?: TextInputHost;
928
933
  /** H2 내부 턴 문 — 버퍼가 비었을 때 입력 루프가 물러나 호스트가 내부 턴을 실행하게 한다. */
929
934
  internalTurnYield?: TextInputInternalTurnYieldPort;
935
+ /** TUI-PASTE-WHILE-STREAMING — `initialText` 속 붙여넣기 토큰의 원문(턴 중 typeahead 가 접은 것). */
936
+ initialPastes?: ReadonlyArray<readonly [token: string, raw: string]>;
930
937
  }): Promise<InputResult> {
938
+ // TUI-PASTE-ECHO — 긴 붙여넣기는 입력창에 «[붙여넣음 #k · N줄 · M자]» 로 보이고, 제출 때 원문 전체로 되돌린다.
939
+ const pasteFold = createPasteFold();
940
+ if (opts.initialPastes?.length) pasteFold.adopt(opts.initialPastes.filter(([token]) => opts.initialText?.includes(token)));
931
941
  const { row: initialRow, col, width, maxLines = 5, prompt = '\u276f ', placeholder = '' } = opts;
932
942
  const getWidth = (): number => opts.getWidth?.() ?? width;
933
943
  const getRow = (): number => opts.getRow?.() ?? initialRow;
@@ -1022,7 +1032,6 @@ export async function textInput(opts: {
1022
1032
  modalSink: opts.modalSink,
1023
1033
  picker,
1024
1034
  getBufferView: bufView,
1025
- writeTerminal,
1026
1035
  getBounds: () => ({ row: getRow(), col, width: getWidth(), height: 1 }),
1027
1036
  getInputZoneHeight: () => Math.min(lines.length, maxLines),
1028
1037
  onDispatchResult: async (dispatched) => processPickerDispatch(dispatched),
@@ -1336,7 +1345,6 @@ export async function textInput(opts: {
1336
1345
  }
1337
1346
  pickerModalRuntime.syncFamily({
1338
1347
  activeKind: activePickerKind(),
1339
- clearRows: MAX_PICKER + 3,
1340
1348
  debugLayout: { row: getRow(), col, width: getWidth() },
1341
1349
  family: pickerModalFamily,
1342
1350
  });
@@ -1453,10 +1461,12 @@ export async function textInput(opts: {
1453
1461
  return result;
1454
1462
  };
1455
1463
  const submitBufferResult = (text: string): InputResult => {
1456
- debug.log('chat.input.submit', 'summary', summarizeSubmitText(text.trim()));
1464
+ // 입력칸 글만 다듬고(앞뒤 공백) 그다음 원문을 펼친다 — 붙여넣은 원문의 앞뒤 공백·끝 줄바꿈·CRLF 는 그대로 간다(r2 must-fix).
1465
+ const expanded = pasteFold.expand(text.trim());
1466
+ debug.log('chat.input.submit', 'summary', summarizeSubmitText(expanded));
1457
1467
  lastSubmitAt = Date.now();
1458
1468
  return finalizeInput({
1459
- text: text.trim(),
1469
+ text: expanded,
1460
1470
  submitted: true,
1461
1471
  ...(pendingExternalSubmitSource ? { externalSubmitSource: pendingExternalSubmitSource } : {}),
1462
1472
  });
@@ -1617,7 +1627,8 @@ export async function textInput(opts: {
1617
1627
  // host routing so embedded newlines cannot reach a submit handler.
1618
1628
  if (key.name === 'paste') {
1619
1629
  const pasted = key.paste ?? '';
1620
- const inserted = opts.onPaste ? await opts.onPaste(pasted) : pasted;
1630
+ const hosted = opts.onPaste ? await opts.onPaste(pasted) : pasted;
1631
+ const inserted = pasteFold.fold(hosted);
1621
1632
  const beforeNumLines = lines.length;
1622
1633
  applyBufferState(insertMultilineTextAtCursor(bufferState(), inserted));
1623
1634
  if (debug.enabled) {
@@ -1819,7 +1830,11 @@ export async function textInput(opts: {
1819
1830
  // to the app (it's their own paste shortcut). Ctrl+V survives in
1820
1831
  // raw mode, so bind there. Also accept `ㅍ` for 한글 IME.
1821
1832
  if (key.ctrl && (key.name === 'v' || key.name === 'V' || key.name === 'ㅍ')) {
1822
- if (opts.onPasteImage) {
1833
+ // TUI-PASTE-ECHO — 이미지가 있으면 첨부(기존), 없으면 클립보드 «글»을 붙여넣기와 같은 규칙으로 넣는다
1834
+ // (짧으면 그대로 · 길면 «[붙여넣음 #k · N줄 · M자]»). 예전엔 글이면 «No image» 만 남고 아무것도 안 들어갔다.
1835
+ let hasImage = false;
1836
+ try { hasImage = opts.onPasteImage ? await (opts.clipboardHasImage ?? hasClipboardImage)() : false; } catch { hasImage = false; }
1837
+ if (opts.onPasteImage && hasImage) {
1823
1838
  let token: string | null = null;
1824
1839
  try { token = await opts.onPasteImage(); }
1825
1840
  catch { /* swallow — leave buffer unchanged */ }
@@ -1830,6 +1845,15 @@ export async function textInput(opts: {
1830
1845
  drawAll();
1831
1846
  continue;
1832
1847
  }
1848
+ let clip: string | null = null;
1849
+ try { clip = await (opts.clipboardText ?? readClipboardText)(); } catch { clip = null; }
1850
+ debug.log('tui.paste', 'clipboard-read', { surface: 'classic', chars: clip?.length ?? 0, image: hasImage });
1851
+ if (clip) {
1852
+ applyBufferState(insertMultilineTextAtCursor(bufferState(), pasteFold.fold(clip)));
1853
+ onUserBufferEdit();
1854
+ }
1855
+ drawAll();
1856
+ continue;
1833
1857
  }
1834
1858
 
1835
1859
  if (!key.ctrl && (key.name === 'pageup' || key.name === 'pagedown') && opts.onScrollKey) {
@@ -0,0 +1 @@
1
+ export type InternalTurnOrigin = 'autowake' | 'msg-wake' | 'scheduled' | 'child-complete' | 'goal-continue' | 'test';
@@ -0,0 +1,86 @@
1
+ // ── 긴 붙여넣기 자리표시 `paste-fold` (TUI-PASTE-ECHO · 0.2.36 · 2026-10-22 · 대표 P0 «classic·next 둘 다») ──────
2
+ //
3
+ // 🚨 무엇을 푸는가: 여러 줄을 붙여넣으면 입력창이 그 줄 수만큼 펼쳐져 화면을 덮거나(classic) 끝 몇 줄만
4
+ // «↵» 로 이어 보인다(next) — 무엇이 몇 줄 들어갔는지 한눈에 안 보인다(10-22 설치본 재현).
5
+ // ⭐ 긴 붙여넣기는 입력창에 «[붙여넣음 #k · N줄 · M자]» 토큰 한 덩어리로 넣고 원문은 여기 쥔다.
6
+ // 제출할 때 토큰을 원문으로 되돌린다 — 모델이 받는 글은 붙여넣은 글 전부다. 짧은 글은 그대로 넣는다.
7
+ // ⛔ 토큰을 지우면 그 붙여넣기도 빠진다(사람이 지운 것) · 토큰 글자를 손으로 고치면 원문 대신 그 글이 간다.
8
+ //
9
+ // 세 얼굴:
10
+ // 관측 = debug.log('tui.paste', 'folded', { id, lines, chars }) · 'expanded' { count, chars }
11
+ // 인지 = 줄 수 ≥ PASTE_FOLD_MIN_LINES 또는 글자 ≥ PASTE_FOLD_MIN_CHARS
12
+ // 힐링 = 자리표시로 보이고 제출 때 원문 전체 · 실패 없음(접지 않으면 원문 그대로)
13
+
14
+ import { debug } from '../debug/log.js';
15
+
16
+ export const PASTE_FOLD_MIN_LINES = 4;
17
+ export const PASTE_FOLD_MIN_CHARS = 800;
18
+
19
+ export interface PasteFold {
20
+ /** 붙여넣은 글 — 길면 자리표시 토큰, 짧으면 그대로. */
21
+ fold(text: string): string;
22
+ /** 제출 글 — 남아 있는 토큰을 원문으로 되돌린다. */
23
+ expand(text: string): string;
24
+ /** 쥐고 있는 붙여넣기 수. */
25
+ size(): number;
26
+ /** 아직 살아 있는 글(입력칸·대기열)에 없는 토큰의 원문을 놓는다 — 지운 붙여넣기 회수. 놓은 수. */
27
+ retainOnly(liveTexts: readonly string[]): number;
28
+ /** 다른 입력칸(턴 중 typeahead)이 접은 토큰·원문 짝을 넘겨받는다 — 넘김 뒤에도 토큰으로 보이고 제출 때 펴진다. */
29
+ adopt(pairs: ReadonlyArray<readonly [token: string, raw: string]>): void;
30
+ }
31
+
32
+ export function pasteFoldToken(id: number, text: string): string {
33
+ const lines = text.split('\n').length;
34
+ return `[붙여넣음 #${id} · ${lines}줄 · ${text.length}자]`;
35
+ }
36
+
37
+ export function shouldFoldPaste(text: string): boolean {
38
+ return text.split('\n').length >= PASTE_FOLD_MIN_LINES || text.length >= PASTE_FOLD_MIN_CHARS;
39
+ }
40
+
41
+ export function createPasteFold(log: (category: string, event: string, data: Record<string, unknown>) => void = (c, e, d) => debug.log(c, e, d)): PasteFold {
42
+ const held = new Map<string, string>();
43
+ let seq = 0;
44
+ return {
45
+ fold(text) {
46
+ // 표시(줄 수·글자 수)만 정규화한다 — 끝 줄바꿈 하나는 터미널이 붙이는 것 · CRLF 는 한 줄바꿈.
47
+ // 쥐는 것·제출하는 것은 붙여넣은 원문 그대로다(r1 must-fix).
48
+ const shown = text.replace(/\r\n?/g, '\n').replace(/\n$/, '');
49
+ if (!shouldFoldPaste(shown)) return text;
50
+ const token = pasteFoldToken(++seq, shown);
51
+ held.set(token, text);
52
+ log('tui.paste', 'folded', { id: seq, lines: shown.split('\n').length, chars: shown.length });
53
+ return token;
54
+ },
55
+ expand(text) {
56
+ if (held.size === 0) return text;
57
+ // 한 번에 훑는다 — 펼친 원문 안에 다른 토큰 글이 있어도 다시 치환하지 않는다(지운 붙여넣기가 되살아나지 않게 · r3 must-fix).
58
+ const tokens = [...held.keys()].filter((t) => text.includes(t));
59
+ if (tokens.length === 0) return text;
60
+ const re = new RegExp(tokens.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|'), 'g');
61
+ const used = new Set<string>();
62
+ const out = text.replace(re, (m) => { used.add(m); return held.get(m) ?? m; });
63
+ for (const t of used) held.delete(t);
64
+ log('tui.paste', 'expanded', { count: used.size, chars: out.length });
65
+ return out;
66
+ },
67
+ retainOnly(liveTexts) {
68
+ // 입력칸·대기열 어디에도 없는 토큰(사람이 지운 것)의 원문을 놓는다 — 메모리 누적·나중에 같은 글을 쳤을 때 되살아남 방지(r3 must-fix).
69
+ let dropped = 0;
70
+ for (const token of [...held.keys()]) {
71
+ if (!liveTexts.some((t) => t.includes(token))) { held.delete(token); dropped++; }
72
+ }
73
+ if (dropped > 0) log('tui.paste', 'dropped', { count: dropped, held: held.size });
74
+ return dropped;
75
+ },
76
+ adopt(pairs) {
77
+ for (const [token, raw] of pairs) {
78
+ held.set(token, raw);
79
+ const id = Number(/^\[붙여넣음 #(\d+) /.exec(token)?.[1] ?? 0);
80
+ if (id > seq) seq = id;
81
+ }
82
+ if (pairs.length > 0) log('tui.paste', 'adopted', { count: pairs.length, held: held.size });
83
+ },
84
+ size: () => held.size,
85
+ };
86
+ }
@@ -1,5 +1,5 @@
1
1
  import { debug } from '../../debug/log.js';
2
- import { ansi, type Key } from '../../tui.js';
2
+ import type { Key } from '../../tui.js';
3
3
  import { createChatPickerModalFamily, type ChatPickerFamilySources, type ChatPickerModalBindings, type ChatPickerModalFamily, type PickerOnKey, type PickerOnRowClick } from './modals.js';
4
4
  import { CHAT_PICKER_KINDS, type ChatPickerKind } from './kinds.js';
5
5
  import type { ModalSink } from '../index.js';
@@ -10,7 +10,6 @@ export interface ChatPickerModalRuntimeDeps {
10
10
  modalSink?: ModalSink;
11
11
  picker: PickerState;
12
12
  getBufferView: () => PickerBufferView;
13
- writeTerminal: (s: string) => void;
14
13
  getBounds: () => { row: number; col: number; width: number; height: number };
15
14
  getInputZoneHeight: () => number;
16
15
  onDispatchResult: (
@@ -26,30 +25,15 @@ interface PickerHandle {
26
25
  interface SyncPickerModalSpec {
27
26
  kind: ChatPickerKind;
28
27
  active: boolean;
29
- clearRows: number;
30
28
  createSurface: () => ModalSurface;
31
29
  }
32
30
 
33
31
  interface SyncPickerFamilySpec {
34
32
  activeKind: ChatPickerKind | null;
35
- clearRows: number;
36
33
  debugLayout?: { row: number; col: number; width: number };
37
34
  family: ChatPickerModalFamily;
38
35
  }
39
36
 
40
- export function paintChatPickerClear(spec: {
41
- bounds: { row: number; col: number };
42
- rows: number;
43
- inputZoneHeight: number;
44
- }): string {
45
- const out: string[] = [];
46
- for (let i = 0; i < spec.rows; i++) {
47
- const r = spec.bounds.row - spec.inputZoneHeight - 1 - i;
48
- if (r >= 1) out.push(ansi.moveTo(r, spec.bounds.col) + '\x1b[2K');
49
- }
50
- return out.join('');
51
- }
52
-
53
37
  export function createChatPickerModalRuntime(deps: ChatPickerModalRuntimeDeps): {
54
38
  dispatchKey: (input: { key: Key; source: 'onKey' | 'input-loop'; label: string }) => Promise<boolean>;
55
39
  makePickerOnKey: (label: string) => PickerOnKey;
@@ -112,15 +96,15 @@ export function createChatPickerModalRuntime(deps: ChatPickerModalRuntimeDeps):
112
96
  });
113
97
  };
114
98
 
115
- const clearHandle = (kind: ChatPickerKind, clearRows: number): void => {
99
+ // TUI-DIRECT-WRITE-ROWS — no direct terminal clear here. The sink is the
100
+ // display coordinator, whose popModal marks every row dirty and forces the
101
+ // next frame (Q7 / F9), so the picker rows repaint through the frame cache.
102
+ // The old CUP+EL clear bypassed that cache and was off by one row: it
103
+ // erased the row above the picker band (ChatLog header) and left it blank
104
+ // until the forced repaint arrived.
105
+ const clearHandle = (kind: ChatPickerKind): void => {
116
106
  const handle = handles.get(kind);
117
107
  if (!handle) return;
118
- const bounds = deps.getBounds();
119
- deps.writeTerminal(paintChatPickerClear({
120
- bounds,
121
- rows: clearRows,
122
- inputZoneHeight: deps.getInputZoneHeight(),
123
- }));
124
108
  handle.dispose();
125
109
  handles.delete(kind);
126
110
  };
@@ -133,7 +117,7 @@ export function createChatPickerModalRuntime(deps: ChatPickerModalRuntimeDeps):
133
117
  return;
134
118
  }
135
119
  if (!spec.active && handle) {
136
- clearHandle(spec.kind, spec.clearRows);
120
+ clearHandle(spec.kind);
137
121
  }
138
122
  };
139
123
 
@@ -188,7 +172,6 @@ export function createChatPickerModalRuntime(deps: ChatPickerModalRuntimeDeps):
188
172
  syncModal({
189
173
  kind,
190
174
  active: kind === input.activeKind && itemCount > 0,
191
- clearRows: input.clearRows,
192
175
  createSurface: () => input.family.createSurface(kind),
193
176
  });
194
177
  }
@@ -196,7 +179,7 @@ export function createChatPickerModalRuntime(deps: ChatPickerModalRuntimeDeps):
196
179
 
197
180
  const clearAll = (): void => {
198
181
  for (const kind of [...handles.keys()]) {
199
- clearHandle(kind, 9);
182
+ clearHandle(kind);
200
183
  }
201
184
  };
202
185
 
@@ -5,6 +5,7 @@ import type { ToolRenderModel } from './types.js';
5
5
 
6
6
  const PERSISTED_REF_PREFIX = '... Full output saved to ';
7
7
  const LISTING_TOOL_MAX_LINES = 8;
8
+ const WARNING_LINE_PREFIX = '⚠';
8
9
 
9
10
  interface ToolBlockLineBudget {
10
11
  maxLines: number;
@@ -67,11 +68,42 @@ export function toolBlockGrouping(model: ToolRenderModel, foldMode: FoldMode = '
67
68
  return { operationKind: model.operationKind };
68
69
  }
69
70
 
71
+ /**
72
+ * ⚠ lines (RunShell long-sleep 등) are pinned: folding them away hides a warning
73
+ * from the human eye, so they always render above the fold marker.
74
+ */
75
+ function splitWarningLines(lines: string[]): { warnings: string[]; foldable: string[] } {
76
+ const warnings: string[] = [];
77
+ const foldable: string[] = [];
78
+ for (const line of lines) {
79
+ if (line.startsWith(WARNING_LINE_PREFIX)) warnings.push(line);
80
+ else foldable.push(line);
81
+ }
82
+ return { warnings, foldable };
83
+ }
84
+
70
85
  function truncateBlockBody(
71
86
  lines: string[],
72
87
  maxLines: number,
73
88
  foldMode: FoldMode = 'line',
74
89
  expandHint?: boolean,
90
+ ): string[] {
91
+ const { warnings, foldable } = splitWarningLines(lines);
92
+ if (warnings.length === 0) return foldBlockBody(lines, maxLines, foldMode, expandHint);
93
+ // 본문이 전부 경고면 접을 것이 없다 — 그대로 보여주고 폴드 마커를 내지 않는다.
94
+ if (foldable.length === 0) return warnings;
95
+ // 고정된 경고는 접힌 줄 수에 넣지 않는다 — 예산만 경고 줄 수만큼 줄인다.
96
+ return [
97
+ ...warnings,
98
+ ...foldBlockBody(foldable, maxLines - warnings.length, foldMode, expandHint),
99
+ ];
100
+ }
101
+
102
+ function foldBlockBody(
103
+ lines: string[],
104
+ maxLines: number,
105
+ foldMode: FoldMode = 'line',
106
+ expandHint?: boolean,
75
107
  ): string[] {
76
108
  const hint = (hidden: number): string => foldHint('line', hidden, { expandHint });
77
109
  if (
@@ -17,6 +17,8 @@ import type {
17
17
  } from './types.js';
18
18
  import { renderToolBlock } from './block.js';
19
19
  import { renderToolInline } from './inline.js';
20
+ // Shared with the next TUI chat log (TUI-NEXT-TOOL-RESULT-RENDER) — one extractor for both surfaces.
21
+ import { toolResultBodyText as extractBodyText, toolResultErrorText as extractErrorText } from './result-text.js';
20
22
 
21
23
  /** 접힌 결과 요약 첫 조각은 `MsgPost` 하나뿐이라 이름 확장을 `dispatch.ts` 안에 둔다.
22
24
  * `types.ts:ToolRenderName` 은 나머지 도구의 공용 계약 그대로 두고, 이 파일의 내부
@@ -425,19 +427,6 @@ function extractSyntheticGuardSummary(result: unknown): string | null {
425
427
  return null;
426
428
  }
427
429
 
428
- function extractBodyText(result: unknown): string | null {
429
- if (typeof result === 'string') return result;
430
- if (result && typeof result === 'object' && typeof (result as Record<string, unknown>).output === 'string') {
431
- return (result as Record<string, string>).output;
432
- }
433
- if (result === null || result === undefined) return null;
434
- try {
435
- return JSON.stringify(result, null, 2);
436
- } catch {
437
- return String(result);
438
- }
439
- }
440
-
441
430
  function maybeHighlightCodePreview(
442
431
  kind: ToolRenderName,
443
432
  args: Record<string, unknown>,
@@ -515,13 +504,6 @@ function highlightPreviewLine(line: string, ext: string): string {
515
504
  return line;
516
505
  }
517
506
 
518
- function extractErrorText(result: unknown): string | null {
519
- if (result && typeof result === 'object' && typeof (result as Record<string, unknown>).error === 'string') {
520
- return String((result as Record<string, unknown>).error);
521
- }
522
- return null;
523
- }
524
-
525
507
  function asRecord(value: unknown): Record<string, unknown> | null {
526
508
  return value && typeof value === 'object' ? value as Record<string, unknown> : null;
527
509
  }
@@ -0,0 +1,98 @@
1
+ // Tool-result text extraction shared by the classic dashboard renderer (dispatch.ts)
2
+ // and the next TUI chat log (src/tui/chat/log-view.ts).
3
+ //
4
+ // TUI-NEXT-TOOL-RESULT-RENDER (0.2.36): the next TUI only has the persisted tool
5
+ // result — `JSON.stringify(result)` cut at 2000 chars (session/chat.ts
6
+ // truncateForPersist) — so it showed the raw envelope on one line with escaped
7
+ // `\n`. `parseToolResultEnvelope` turns that string back into the result value;
8
+ // `toolResultBodyText` / `toolResultErrorText` are classic's own extractors, moved
9
+ // here so both surfaces read the same «human text» out of a result.
10
+ //
11
+ // Pure, no imports: safe to load from either surface.
12
+
13
+ /** The persisted suffix `truncateForPersist` appends when it cuts a value. */
14
+ const PERSIST_TRUNCATION_SUFFIX = /… \(\+\d+ chars\)$/;
15
+
16
+ /** Body text of a tool result: a string as-is, the `output` field, else pretty JSON. */
17
+ export function toolResultBodyText(result: unknown): string | null {
18
+ if (typeof result === 'string') return result;
19
+ if (result && typeof result === 'object' && typeof (result as Record<string, unknown>).output === 'string') {
20
+ return (result as Record<string, string>).output;
21
+ }
22
+ if (result === null || result === undefined) return null;
23
+ try {
24
+ return JSON.stringify(result, null, 2);
25
+ } catch {
26
+ return String(result);
27
+ }
28
+ }
29
+
30
+ /** `error` field text of a tool result, or null. */
31
+ export function toolResultErrorText(result: unknown): string | null {
32
+ if (result && typeof result === 'object' && typeof (result as Record<string, unknown>).error === 'string') {
33
+ return String((result as Record<string, unknown>).error);
34
+ }
35
+ return null;
36
+ }
37
+
38
+ export interface ParsedToolResultEnvelope {
39
+ /** The result value (an object for JSON envelopes; the raw string otherwise). */
40
+ value: unknown;
41
+ /** The persisted string was cut (by `truncateForPersist`) — the body is partial. */
42
+ truncated: boolean;
43
+ }
44
+
45
+ /**
46
+ * Turn a persisted tool result string back into the result value.
47
+ * - Plain text (not a JSON object) stays the same string.
48
+ * - A whole JSON object parses normally.
49
+ * - A cut JSON object (`{"output":"…` ⊕ «… (+N chars)») keeps what can be read: the
50
+ * `output` string up to the cut, decoded (real newlines), marked `truncated`.
51
+ */
52
+ export function parseToolResultEnvelope(raw: string): ParsedToolResultEnvelope {
53
+ const text = raw.trim();
54
+ if (!text.startsWith('{')) return { value: raw, truncated: false };
55
+ try {
56
+ const value: unknown = JSON.parse(text);
57
+ return { value, truncated: false };
58
+ } catch { /* fall through — maybe cut by truncateForPersist */ }
59
+ if (!PERSIST_TRUNCATION_SUFFIX.test(text)) return { value: raw, truncated: false };
60
+ const body = text.replace(PERSIST_TRUNCATION_SUFFIX, '');
61
+ const output = readPartialJsonStringField(body, 'output');
62
+ if (output === null) return { value: raw, truncated: false };
63
+ return { value: { output }, truncated: true };
64
+ }
65
+
66
+ /** Decode the string value of `"<field>":"…` from a possibly cut JSON text (to its end or the cut). */
67
+ function readPartialJsonStringField(json: string, field: string): string | null {
68
+ const key = `"${field}":"`;
69
+ const at = json.indexOf(key);
70
+ if (at < 0) return null;
71
+ let i = at + key.length;
72
+ let literal = '';
73
+ while (i < json.length) {
74
+ const ch = json[i]!;
75
+ if (ch === '"') break;
76
+ if (ch === '\\') {
77
+ const next = json[i + 1];
78
+ if (next === undefined) break; // escape cut in half
79
+ if (next === 'u') {
80
+ const hex = json.slice(i + 2, i + 6);
81
+ if (!/^[0-9a-fA-F]{4}$/.test(hex)) break;
82
+ literal += json.slice(i, i + 6);
83
+ i += 6;
84
+ continue;
85
+ }
86
+ literal += json.slice(i, i + 2);
87
+ i += 2;
88
+ continue;
89
+ }
90
+ literal += ch;
91
+ i += 1;
92
+ }
93
+ try {
94
+ return JSON.parse(`"${literal}"`) as string;
95
+ } catch {
96
+ return null;
97
+ }
98
+ }