elanous 0.2.35 → 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 (686) 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/{d06f9160.a3d9062f95de8ad7.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/{4346.8601952e73bf5803.js → 1201.afbfc5b1c5e5cbe4.js} +1 -1
  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/{3103.0df8da390948bb84.js → 2500.cbc1257b774aae52.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 2683.c9773a0c589b031b.js} +3 -3
  20. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
  21. package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 275-02ea4c2a33980422.js} +3 -3
  22. package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{8714.ff0b7ce3ec3e3ae2.js → 2941.3c3546f96bc6efa7.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.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/3136.30aaaa5fa03662a3.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{3677-4215f826f6aa68e5.js → 3148-98efd4869d660a87.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +226 -0
  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/3324.a09703033abcbd2f.js +34 -0
  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/3538.a445e50bb359d068.js +32 -0
  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/{9512.5a76207a730e0491.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/{8557-e7898769499cd56f.js → 3757-180308bc61021b05.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
  45. package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 3840-5825d56d46976a92.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.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/{9952.5daf5f94063a2b3e.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/{938.66ad1ef0e5abae1c.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/5085-bce4904931767ca6.js +1 -0
  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/{6236.e18cced2d5ba6afb.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/{3408.21d1570602f4b6c0.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/5711.957b095705c12560.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.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/599.c39c571b6733f2a2.js +41 -0
  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/6925.562d532110879886.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 6943.c6b24124853a47b2.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/{630.fe5a46428d63b013.js → 727.7deb87749b0a343a.js} +1 -1
  88. package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.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/{8444.4c26b379ca2b9596.js → 771.c3cdb6c1f7f47c02.js} +17 -17
  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/{3589.5444a06bcf6e775c.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/{b2f6ba4d.fb56fdbbf798df33.js → 873d6c12.09bd499f57171543.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.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/{5637.281e5dec4ea6ecf1.js → 914.8abefd48d579547b.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.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/{8637.47f5b35afcae5e6b.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/{1674.2a65fd5668e1cc5f.js → 9789.60f723d18097ec30.js} +1 -1
  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-083747f1d4518f61.js +1 -0
  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/{0368f25d-ad84af92fefee68f.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → ceba0382.650712b56b85b582.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → da5ecc5c-b005ad8cac737d57.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{56d372f2.681ab4ec4c998fae.js → f9a61e4d.1fc2c1dbdd49fe46.js} +1 -1
  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/{T1mBQqmkwKDLGtyisDCOd → 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/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  278. package/docs/goal-context/README.md +3 -0
  279. package/graphs/default-loop.yaml +6 -1
  280. package/graphs/implement-loop.yaml +24 -0
  281. package/graphs/release/recipes.yaml +6 -0
  282. package/graphs/release/release-loop.yaml +17 -4
  283. package/graphs/wizard/recipes.yaml +44 -0
  284. package/graphs/wizard/wizard-loop.yaml +44 -0
  285. package/graphs/work/research-report.yaml +2 -0
  286. package/package.json +1 -1
  287. package/scripts/ci-typecheck-changed.ts +139 -5
  288. package/scripts/coord-role-pack.ts +1 -1
  289. package/scripts/first10-gate.ts +416 -0
  290. package/scripts/fleet/wsl-node-setup.sh +432 -0
  291. package/scripts/release-loop/docs-node.ts +204 -8
  292. package/scripts/release-loop/gate-node.ts +249 -53
  293. package/scripts/release-loop/node-verdict.ts +2 -0
  294. package/scripts/release-loop/resume-cap.ts +14 -34
  295. package/scripts/release-loop/resume-release.ts +37 -11
  296. package/scripts/release-loop/traffic-node.ts +59 -0
  297. package/scripts/release-loop/traffic-transition.ts +159 -0
  298. package/scripts/rhythm/daily.ts +137 -3
  299. package/scripts/ux-sim.ts +53 -0
  300. package/skills/README.md +1 -0
  301. package/src/acp/core-turn-bridge.ts +48 -6
  302. package/src/agent/delegate-hint.ts +16 -0
  303. package/src/agent/runner.ts +82 -2
  304. package/src/agent/task-notification.ts +56 -10
  305. package/src/agent/types.ts +4 -0
  306. package/src/agent-substrate/pr-reviewer.ts +55 -3
  307. package/src/agent-substrate/review-intent.ts +29 -2
  308. package/src/agent-substrate/review-observation.ts +3 -0
  309. package/src/agent-substrate/self-review-cli.ts +168 -16
  310. package/src/autopilot/mission-codebase-gate.ts +141 -12
  311. package/src/autopilot/pr-manager.ts +25 -5
  312. package/src/boot/daemon-tools/self-implement.ts +1 -0
  313. package/src/budget/usage-outcomes.ts +8 -4
  314. package/src/capture/tui-self-report.ts +102 -0
  315. package/src/chat/goal-continue-verdict.ts +41 -0
  316. package/src/chat/index.ts +30 -4
  317. package/src/chat/internal-turn-origin.ts +1 -0
  318. package/src/chat/paste-fold.ts +86 -0
  319. package/src/chat/tool-render/block.ts +32 -0
  320. package/src/chat/tool-render/dispatch.ts +2 -20
  321. package/src/chat/tool-render/result-text.ts +98 -0
  322. package/src/chat/turn-typeahead.ts +70 -7
  323. package/src/cli/config-audit.ts +119 -0
  324. package/src/cli/doctor-cli.ts +22 -0
  325. package/src/cli/guardian-cli.ts +10 -0
  326. package/src/cli/herdr-cli.ts +34 -0
  327. package/src/cli/light-entry-route.ts +6 -3
  328. package/src/cli/log-event-names.ts +2 -0
  329. package/src/cli/make-cli.ts +247 -11
  330. package/src/cli/msg-cli.ts +117 -3
  331. package/src/cli/pr-cli.ts +29 -16
  332. package/src/cli/pr-land-base-read.ts +11 -2
  333. package/src/cli/pr-land-heavy-remote.ts +6 -3
  334. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  335. package/src/cli/pr-land-recovery.ts +117 -1
  336. package/src/cli/pty-takeover-cli.ts +8 -7
  337. package/src/cli/release-cli.ts +21 -5
  338. package/src/cli/release-single-flight.ts +1 -1
  339. package/src/cli/tasks-card-show.ts +162 -0
  340. package/src/cli/tasks-cli.ts +574 -356
  341. package/src/cli/tasks-read-cli.ts +197 -0
  342. package/src/core-turn/run-core-turn.ts +4 -2
  343. package/src/core-turn/run-goal-loop.ts +73 -16
  344. package/src/core-turn/types.ts +6 -1
  345. package/src/dashboard/context/keys.ts +8 -31
  346. package/src/dashboard/index.ts +202 -49
  347. package/src/dashboard/input/agent-wake.ts +7 -1
  348. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  349. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  350. package/src/dashboard/input/goal-continue.ts +210 -0
  351. package/src/dashboard/input/goal-interim.ts +2 -0
  352. package/src/dashboard/input/internal-turn.ts +2 -8
  353. package/src/dashboard/input/seat-autowake.ts +9 -7
  354. package/src/dashboard/input/turn-autoheal.ts +52 -0
  355. package/src/dashboard/seat-boot-preamble.ts +132 -5
  356. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  357. package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
  358. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  359. package/src/dashboard/stale-install-check.ts +3 -99
  360. package/src/debug/batch-queue.ts +119 -0
  361. package/src/debug/tui-log-tag.ts +67 -0
  362. package/src/display/agent-surface.ts +7 -0
  363. package/src/domains/standalone-log-sink.ts +15 -2
  364. package/src/esc-abort-gate.ts +69 -0
  365. package/src/git-fs/worktree.ts +95 -1
  366. package/src/graph-runner/graph-cli.ts +18 -0
  367. package/src/graph-runner/runner.ts +20 -11
  368. package/src/graph-wizard/generate.ts +108 -4
  369. package/src/graph-wizard/steps.ts +15 -0
  370. package/src/grounding/proactive-ground.ts +86 -0
  371. package/src/harness/control-inbox.ts +49 -1
  372. package/src/harness/harness-cli-command.ts +51 -7
  373. package/src/harness/harness-incidents.ts +52 -1
  374. package/src/harness/pod-control-send.ts +33 -5
  375. package/src/harness/self-send-remote.ts +69 -0
  376. package/src/harness/self-send-routing-guard.ts +6 -0
  377. package/src/harness/self-send-target.ts +4 -3
  378. package/src/index.ts +327 -12
  379. package/src/input-core/context-key-runtime.ts +21 -0
  380. package/src/light-cli.ts +6 -1
  381. package/src/llm-wellformed.ts +70 -0
  382. package/src/llm.ts +35 -4
  383. package/src/loops/msg-wake.ts +35 -39
  384. package/src/loops/orchestrator/inbox.ts +59 -11
  385. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  386. package/src/loops/orchestrator/tick.ts +5 -1
  387. package/src/maturity/feature-maturity.ts +1 -1
  388. package/src/models/prompts.ts +17 -2
  389. package/src/msg/msg-post-office.ts +116 -0
  390. package/src/mss/logging/log-store.ts +79 -22
  391. package/src/nexus/api/decisions-route.ts +38 -18
  392. package/src/nexus/api/graph-wizard-api.ts +20 -2
  393. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  394. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  395. package/src/onboarding/first-run.ts +37 -6
  396. package/src/onboarding/web-first.ts +43 -11
  397. package/src/ops/overview-collect.ts +12 -6
  398. package/src/ops/overview.ts +3 -3
  399. package/src/persona/loader.ts +11 -0
  400. package/src/persona/types.ts +8 -0
  401. package/src/prompt-library/session-guidance.ts +14 -0
  402. package/src/provider-summary.ts +8 -0
  403. package/src/pty-shell/herdr-agent-report.ts +118 -9
  404. package/src/pty-shell/herdr-prompt.ts +266 -0
  405. package/src/pty-shell/pty-control-ipc.ts +151 -8
  406. package/src/pty-shell/pty-special-keys.ts +42 -2
  407. package/src/pty-shell/stale-install-check.ts +99 -0
  408. package/src/pty-shell/tui-run-state.ts +14 -2
  409. package/src/release-loop/auto-start.ts +20 -2
  410. package/src/release-loop/checklist.ts +76 -4
  411. package/src/release-loop/rehearsal.ts +36 -20
  412. package/src/repl/index.ts +19 -1
  413. package/src/seat-loop/knowhow-lint.ts +1 -1
  414. package/src/self-dev/decompose-proposal.ts +172 -20
  415. package/src/self-dev/decompose.ts +61 -0
  416. package/src/self-dev/dev-cli.ts +37 -3
  417. package/src/self-dev/dev-pipeline.ts +8 -2
  418. package/src/self-dev/draft-triage-rules.ts +31 -0
  419. package/src/self-dev/glm-credential-guard.ts +77 -0
  420. package/src/self-dev/graph-journey-nodes.ts +1 -0
  421. package/src/self-dev/graph-journey-route.ts +12 -2
  422. package/src/self-dev/orchestrate-cli.ts +68 -3
  423. package/src/self-dev/orchestrate.ts +116 -17
  424. package/src/self-dev/run-supervisor.ts +55 -2
  425. package/src/self-dev/run-types.ts +1 -1
  426. package/src/self-health/autoheal.ts +153 -0
  427. package/src/self-health/signatures.ts +6 -0
  428. package/src/self-implement/device-first.ts +116 -0
  429. package/src/self-implement/doctor-visit.ts +239 -1
  430. package/src/self-implement/evidence-command-budget.ts +80 -0
  431. package/src/self-implement/goal-author-cli.ts +1 -0
  432. package/src/self-implement/goal-author-decompose.ts +265 -4
  433. package/src/self-implement/goal-author.ts +33 -8
  434. package/src/self-implement/goal-elaborate.ts +176 -22
  435. package/src/self-implement/goal-refine.ts +3 -0
  436. package/src/self-implement/graph-variant.ts +40 -6
  437. package/src/self-implement/headless-elanous-driver.ts +19 -3
  438. package/src/self-implement/off-diff-evidence.ts +58 -6
  439. package/src/self-implement/orchestrator.ts +222 -21
  440. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  441. package/src/self-implement/pwa-import-graph.ts +1 -1
  442. package/src/self-implement/rework-policy.ts +30 -0
  443. package/src/self-implement/run-ledger.ts +108 -0
  444. package/src/self-implement/run-ttl.ts +38 -24
  445. package/src/self-implement/scope-adjacency.ts +3 -1
  446. package/src/self-implement/seams.ts +60 -4
  447. package/src/self-implement/wiring-check.ts +358 -0
  448. package/src/shell-env-bootstrap.ts +11 -4
  449. package/src/skills/runner.ts +4 -2
  450. package/src/skills/tools/agent.ts +290 -48
  451. package/src/skills/tools/schedule-wakeup.ts +23 -4
  452. package/src/skills/tools/shell.ts +61 -6
  453. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  454. package/src/skills/tools/terminal-modal.ts +10 -8
  455. package/src/skills/url-router.ts +41 -1
  456. package/src/smart-wizard/run.ts +66 -0
  457. package/src/status/bar.ts +34 -6
  458. package/src/status/status-provider-info.ts +37 -6
  459. package/src/steward/rejudge-tick.ts +10 -2
  460. package/src/steward/ta-repair-event-collect.ts +17 -6
  461. package/src/task-agent/actions.ts +3 -1
  462. package/src/task-agent/land-queue.ts +21 -8
  463. package/src/task-agent/live-moves.ts +22 -6
  464. package/src/task-agent/mission.ts +30 -0
  465. package/src/task-agent/rejudge-on-head.ts +15 -0
  466. package/src/task-agent/repair-cycle.ts +138 -32
  467. package/src/task-agent/repair-next-move.ts +31 -3
  468. package/src/task-agent/repair-outcomes.ts +29 -0
  469. package/src/task-agent/repair-worker.ts +14 -4
  470. package/src/task-agent/shadow.ts +41 -3
  471. package/src/task-agent/task-card-prefix.ts +2 -0
  472. package/src/task-agent/task-hand.ts +477 -22
  473. package/src/task-agent/task-parent-role-llm.ts +36 -0
  474. package/src/task-agent/tier-split.ts +78 -9
  475. package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
  476. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  477. package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
  478. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  479. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  480. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
  481. package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
  482. package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
  483. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  484. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  485. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  486. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  487. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  488. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  489. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  490. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
  491. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +485 -36
  492. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  493. package/src/task-orchestrator/surfaces/self-implement-pod.ts +396 -19
  494. package/src/task-orchestrator/surfaces/self-implement.ts +42 -2
  495. package/src/tool-runtime/index.ts +15 -2
  496. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  497. package/src/tty-foreground.ts +155 -0
  498. package/src/tui/chat/goal-interim.ts +173 -0
  499. package/src/tui/chat/log-view.ts +205 -18
  500. package/src/tui/chat/self-health-status.ts +232 -0
  501. package/src/tui/entry.ts +370 -81
  502. package/src/tui/input/composer.ts +8 -1
  503. package/src/tui/slash/compact-command.ts +7 -0
  504. package/src/tui/slash/compact.ts +1 -7
  505. package/src/tui/slash/resume.ts +75 -0
  506. package/src/tui-client/local-chat-turn.ts +45 -2
  507. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  508. package/src/tui-client/next-loop-command.ts +70 -0
  509. package/src/tui-client/next-wakeup.ts +191 -0
  510. package/src/tui.ts +37 -0
  511. package/src/ui/modal-adapter.ts +2 -2
  512. package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
  513. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  514. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  515. package/src/ux-sim/event-monkey.ts +3 -2
  516. package/src/ux-sim/fake-bin.ts +45 -0
  517. package/src/ux-sim/fake-herdr.ts +238 -0
  518. package/src/ux-sim/fake-llm.ts +111 -6
  519. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  520. package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
  521. package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
  522. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  523. package/src/ux-sim/goal-device.ts +619 -0
  524. package/src/ux-sim/in-process-cli.ts +22 -5
  525. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  526. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  527. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  528. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  529. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  530. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  531. package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
  532. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  533. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  534. package/src/ux-sim/subagent-tools-device.ts +81 -0
  535. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  536. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  537. package/src/version/packed-revision.json +1 -1
  538. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +0 -32
  540. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
  541. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
  542. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
  543. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
  553. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
  555. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
  556. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
  559. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
  560. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
  563. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
  565. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +0 -122
  567. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
  570. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
  582. package/apps/pwa/out/_next/static/chunks/5483-dd5d7697f6bdb106.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
  586. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
  593. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
  595. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
  597. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
  604. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
  605. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
  615. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
  617. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
  622. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/morning/page-47c5d4db587266bd.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/term/page-dc0a532f5b9196ec.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
  686. /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
@@ -8,13 +8,13 @@
8
8
  // 턴 경로에서 컨텍스트 버스를 읽지 않는다).
9
9
  // - 대시보드의 ACP sessionId 는 TUI 수명 내내 같다 ⇒ `/session new`·`/session clear` 는
10
10
  // `startSeatBootConversation` 으로 카드 캐시를 비워 «새 대화 = 새 카드»를 만든다.
11
- // 관측: `dashboard.seat-boot` card-injected / card-skipped / conversation-start.
11
+ // 관측: `dashboard.seat-boot` card-injected / card-skipped / conversation-start / memory-recall(직전 인계 회상 한 줄).
12
12
 
13
- import { statSync } from 'node:fs';
13
+ import { closeSync, lstatSync, openSync, readdirSync, readSync, statSync } from 'node:fs';
14
14
  import { homedir } from 'node:os';
15
- import { join } from 'node:path';
15
+ import { basename, join } from 'node:path';
16
16
  import type { LLMMessage } from '../llm.js';
17
- import { debug } from '../debug/log.js';
17
+ import { debug, redactSecretText } from '../debug/log.js';
18
18
  import { collectSeatBootSections, renderSeatBootCard } from '../cli/seat-cli.js';
19
19
  import { defaultMsgStorePath } from '../msg/msg-store.js';
20
20
 
@@ -70,6 +70,120 @@ export function resetSeatBootCacheForTest(): void {
70
70
  cardCache.clear();
71
71
  }
72
72
 
73
+ /** 🧭 의도 승격 흐름(TUI-SELFIMPLEMENT-UNDERUSE-MEASURE · 대표 10-22 «확인도 결국 하다 보면 원인이 나오고 자연스럽게
74
+ * 구현이 나오게끔») — 10-22 prod 자리 세션 셋(UX GLM i57ey0 · UX Luna 7x2rxn · OPT Luna 7d3o49)은 노출된 SelfImplement·
75
+ * tasks hand 를 한 번도 안 불렀다. 끊긴 자리 = 처방까지 세우고 «다음 턴에 SelfImplement 로 발사»·«TA 발사 보류 · 재점검
76
+ * 예약» 으로 턴을 닫거나, 구현을 자리에서 Edit 로 직접 했다(격리 실물 전: SelfImplement 0 · Edit/Write 직접).
77
+ * 자리 카드에 실어 «자리 대화의 매 턴» 이 같은 흐름을 본다(사람 대화 TUI 에는 안 실린다). */
78
+ export const SEAT_INTENT_ESCALATION_FLOW =
79
+ '## 일의 흐름 — 확인에서 구현 골까지 한 흐름\n' +
80
+ '확인 → 원인 발견 → 조사 → 처방 확정 → 구현 골 넘기기 를 «이 턴 안에서» 잇는다. 확인·조사 지시도 원인을 찾으면 여기서 멈추지 않는다.\n' +
81
+ '- 원인과 처방이 섰으면 «다음 턴에»·«보고 뒤에»·«재점검 예약» 으로 미루지 말고 바로 구현 골로 넘긴다 — TUI 에서는 SelfImplement 도구(자리 규칙이 손 발사를 정했으면 `eln tasks hand`). 넘긴 뒤 보고는 한 줄.\n' +
82
+ '- 자리에서 기능·수정·여러 파일 구현을 Edit/Write 로 직접 하지 않는다 — 한 줄 설정·문서·오타만 예외.\n' +
83
+ '- 원인이 없으면 «원인 없음 · 근거(무엇을 봤나)» 한 줄로 끝낸다. 넘기지 못하면(권한·선행 조건) 막힌 이유와 필요한 판단 하나를 적는다.';
84
+
85
+ /** 🧠 직전 인계 회상 한 줄(TUI-SEAT-MEMORY-RECALL · COMPARE ④ · 대표 «메모리»).
86
+ * S: 10-22 prod 자리 세션 셋(UX GLM · UX Luna · OPT Luna)이 memory_recall·self_recall 을 한 번도 안 불렀다 — 기억 도구가
87
+ * «있는데 안 씀». codex 는 AGENTS.md 를, Claude Code 는 자동 메모리를 턴 머리에 스스로 싣는다.
88
+ * A: 소스를 «하나»로 잰다 — `seat-state/<자리>/HANDOFF-*.md` 중 mtime 이 가장 최근인 손 인계. 없으면 줄 없음
89
+ * (`HANDOFF.md` 는 자동 갱신 카드이고 카드 «HANDOFF» 절이 이미 제목을 싣는다 — 본문은 싣지 않는 그 계약을 지킨다).
90
+ * memory_recall·self_recall 은 자리 구분 없는 전역 원장(surface_events·knowledge.db)이라 «이 자리의 직전 인계»를
91
+ * 못 고르고, 우편 결정은 원장 질의가 필요하다 — 자리마다 이미 있는 HANDOFF 가 가장 작은 1급 소스다.
92
+ * 손 인계(HANDOFF-*.md)는 카드 어디에도 안 실렸다 — 그 제목·첫 줄이 여기 실린다.
93
+ * 줄 = 머리말 · 파일 · 갱신 시각 · 제목 · 첫 본문 줄 · 전문 경로 · 더 넓은 회상 도구. 상한 `SEAT_MEMORY_RECALL_MAX_CHARS`.
94
+ * 실패는 줄 없음(fail-soft) — 카드·턴을 막지 않는다. */
95
+ export const SEAT_MEMORY_RECALL_PREFIX = '🧠 직전 인계 회상:';
96
+ export const SEAT_MEMORY_RECALL_MAX_CHARS = 360;
97
+ const RECALL_READ_BYTES = 16_384;
98
+ /** 발췌(제목 — 첫 줄)에 남길 최소 글자 — 이보다 모자라면 전문 경로를 짧은 꼴로 바꾼다. */
99
+ const RECALL_MIN_EXCERPT = 60;
100
+ /** 줄에 싣는 파일명 최대 글자. */
101
+ const RECALL_MAX_NAME = 80;
102
+
103
+ interface SeatMemoryRecall { line: string | null; source: string | null }
104
+
105
+ /** 제어 문자·줄 구분자 — 하나라도 섞이면 «한 줄» 계약이 깨진다(파일명·경로·본문 모두). */
106
+ const LINE_BREAKING = /[\u0000-\u001f\u007f\u0085\u2028\u2029]/;
107
+ /** 셸 문자 — 카드 HANDOFF 절과 같은 안전 규칙. 본문 줄뿐 아니라 파일명·경로에도 적용한다(r4). */
108
+ const SHELL_CHARS = /[`$;|<>]/;
109
+ const oneLine = (text: string): string => redactSecretText(text.replace(new RegExp(LINE_BREAKING.source, 'g'), ' ').replace(/\s+/g, ' ').trim());
110
+
111
+ /** 앞 `RECALL_READ_BYTES` 만 읽는다 — 큰 인계 파일도 턴 시작을 막지 않는다. */
112
+ function readHead(path: string): string {
113
+ const fd = openSync(path, 'r');
114
+ try {
115
+ const buf = Buffer.alloc(RECALL_READ_BYTES);
116
+ const n = readSync(fd, buf, 0, RECALL_READ_BYTES, 0);
117
+ return buf.subarray(0, n).toString('utf8');
118
+ } finally { closeSync(fd); }
119
+ }
120
+
121
+ function newestHandoff(seatDir: string): { path: string; mtime: Date } | null {
122
+ if (LINE_BREAKING.test(seatDir)) return null;
123
+ const pick = (names: string[]): { path: string; mtime: Date } | null => {
124
+ let best: { path: string; mtime: Date } | null = null;
125
+ for (const name of names) {
126
+ const path = join(seatDir, name);
127
+ try {
128
+ const st = lstatSync(path);
129
+ if (!st.isFile()) continue; // 디렉터리·링크는 건너뛴다
130
+ if (!best || st.mtimeMs > best.mtime.getTime()) best = { path, mtime: st.mtime };
131
+ } catch { /* 사라진 후보 — 건너뛴다 */ }
132
+ }
133
+ return best;
134
+ };
135
+ // 제어 문자가 든 파일명은 후보에서 뺀다 — 이름·경로를 줄에 그대로 싣기 때문이다.
136
+ // 파일명은 안전 문자만(영숫자 · . _ -) — 셸 문자·제어 문자가 든 이름은 후보에서 뺀다(이름을 줄에 그대로 싣는다).
137
+ return pick(readdirSync(seatDir).filter((name) => /^HANDOFF-[A-Za-z0-9._-]+\.md$/.test(name)));
138
+ }
139
+
140
+ /** 자리의 직전 인계 회상 한 줄. 소스가 없거나 읽을 수 없으면 `line: null`.
141
+ * 카드 HANDOFF 절과 같은 안전 규칙 — 셸 문자(`` ` `` `$` `;` `|` `<` `>`)가 든 줄은 싣지 않는다 · 비밀은 가린다. */
142
+ function buildSeatMemoryRecall(seatDir: string): SeatMemoryRecall {
143
+ const found = newestHandoff(seatDir);
144
+ if (!found) return { line: null, source: null };
145
+ const raw = readHead(found.path).split(/\r\n|[\n\r\u0085\u2028\u2029]/)
146
+ .map((line) => line.trim()).filter((line) => line && !/[`$;|<>]/.test(line));
147
+ const title = raw.find((line) => /^#{1,6}\s/.test(line))?.replace(/^#{1,6}\s*/, '') ?? '';
148
+ const first = raw.find((line) => !/^#{1,6}\s/.test(line))?.replace(/^[-*]\s*/, '') ?? '';
149
+ const excerpt = oneLine([title, first].filter(Boolean).join(' — '));
150
+ if (!excerpt) return { line: null, source: found.path };
151
+ const fullName = found.path.slice(seatDir.length + 1);
152
+ // 파일명은 머리에 한 번만, 길면 앞 RECALL_MAX_NAME 자로 자른다 — 이름 길이가 발췌를 밀어내지 않는다.
153
+ const name = fullName.length > RECALL_MAX_NAME ? `${fullName.slice(0, RECALL_MAX_NAME - 1)}…` : fullName;
154
+ const head = `${SEAT_MEMORY_RECALL_PREFIX} ${name}(갱신 ${found.mtime.toISOString()}) `;
155
+ // 경로가 길어 발췌 자리가 모자라면 전문 경로 대신 «자리 폴더(seat-state/<자리>/)»만 가리킨다 — 줄을 버리지 않는다.
156
+ const tools = ' · 더 넓게는 self_recall·memory_recall';
157
+ // 경로·자리 폴더 이름에 셸 문자가 있으면 싣지 않는다(본문 줄과 같은 규칙) · 비밀은 가린다.
158
+ const pathSafe = !SHELL_CHARS.test(found.path);
159
+ const seatName = basename(seatDir);
160
+ const seatSafe = !SHELL_CHARS.test(seatName);
161
+ const fullTail = pathSafe ? ` · 전문 ${redactSecretText(found.path)}${tools}` : '';
162
+ const shortTail = seatSafe
163
+ ? ` · 전문은 seat-state/${redactSecretText(seatName).slice(0, 64)}/ 의 같은 파일${tools}`
164
+ : ` · 전문은 이 자리 seat-state 폴더의 같은 파일${tools}`;
165
+ const tail = fullTail && SEAT_MEMORY_RECALL_MAX_CHARS - head.length - fullTail.length >= RECALL_MIN_EXCERPT ? fullTail : shortTail;
166
+ // 머리(≤ ~130)·짧은 꼬리(≤ ~120)의 상한 덕에 발췌 자리는 늘 남는다 — 아래는 상수가 바뀔 때의 안전망.
167
+ const room = SEAT_MEMORY_RECALL_MAX_CHARS - head.length - tail.length;
168
+ if (room < 8) return { line: null, source: found.path };
169
+ const body = excerpt.length > room ? `${excerpt.slice(0, room - 1)}…` : excerpt;
170
+ return { line: `${head}${body}${tail}`, source: found.path };
171
+ }
172
+
173
+ function seatMemoryRecallLine(seatDir: string): string | null {
174
+ let recall: SeatMemoryRecall = { line: null, source: null };
175
+ let failed = false;
176
+ try { recall = buildSeatMemoryRecall(seatDir); }
177
+ catch { failed = true; }
178
+ debug.log('dashboard.seat-boot', 'memory-recall', {
179
+ source: recall.source,
180
+ chars: recall.line?.length ?? 0,
181
+ hit: recall.line !== null,
182
+ ...(failed ? { reason: 'error' } : {}),
183
+ });
184
+ return recall.line;
185
+ }
186
+
73
187
  function buildCardMessages(cwd: string, deps: SeatBootDeps): { messages: LLMMessage[]; observed: Record<string, unknown> } {
74
188
  const detection = detectSeat(cwd, deps.env ?? process.env);
75
189
  if (!detection) return { messages: [], observed: { reason: 'no-seat' } };
@@ -81,10 +195,14 @@ function buildCardMessages(cwd: string, deps: SeatBootDeps): { messages: LLMMess
81
195
  const { sections, unread } = collectSeatBootSections(detection.seat, { home, msgPath: deps.msgPath ?? defaultMsgStorePath() });
82
196
  const card = renderSeatBootCard(detection.seat, sections, null);
83
197
  const at = (deps.now?.() ?? new Date()).toISOString();
198
+ const recall = seatMemoryRecallLine(seatDir);
84
199
  const content =
85
200
  `## 자리 부트 카드 — 너는 이 작업 디렉터리의 ${detection.seat} 자리에서 일한다\n` +
86
201
  `(판정: ${detection.source === 'cwd' ? `cwd 의 /seats/${detection.seat}` : 'COORD_ID'} · 세션 시작 스냅샷 ${at} · 이후 바뀐 값은 다시 조회하라)\n` +
87
- `사람이 다른 일을 먼저 시키지 않았다면, 첫 답에서 자리 이름·'자리 역할' 절의 역할·안 읽은 우편 수를 각각 명시하고 처리할 일을 제안하라. 역할이 미관측이면 추측하지 말고 미관측이라고 말하라.\n\n` +
202
+ `사람이 다른 일을 먼저 시키지 않았다면, 첫 답에서 자리 이름·'자리 역할' 절의 역할·안 읽은 우편 수를 각각 명시하고 처리할 일을 제안하라. 역할이 미관측이면 추측하지 말고 미관측이라고 말하라.\n` +
203
+ (recall ? `${recall}\n` : '') +
204
+ '\n' +
205
+ `${SEAT_INTENT_ESCALATION_FLOW}\n\n` +
88
206
  card;
89
207
  return {
90
208
  messages: [{ role: 'system', content }],
@@ -103,6 +221,15 @@ function conversationCard(cwd: string, deps: SeatBootDeps, sessionId?: string):
103
221
  sessionId: sessionId ?? null,
104
222
  ...entry.observed,
105
223
  });
224
+ // 🧭 이 대화에 «확인 → … → 구현 골 넘기기» 흐름을 실었다 — 단계·근거·다음 행동(넘김 도구). 대화마다 한 번.
225
+ if (entry.messages.length) {
226
+ debug.log('dashboard.seat-boot', 'intent.escalate', {
227
+ stage: 'guidance',
228
+ evidence: { seat: entry.observed.seat, source: entry.observed.source },
229
+ next: ['SelfImplement', 'eln tasks hand'],
230
+ sessionId: sessionId ?? null,
231
+ });
232
+ }
106
233
  } catch (err) {
107
234
  // 부트 카드가 턴을 막지 않는다 — 실패는 관측만.
108
235
  debug.log('dashboard.seat-boot', 'card-skipped', { cwd, reason: 'error', error: err instanceof Error ? err.message : String(err) });
@@ -2,16 +2,24 @@ import { awaitGlobalPersonaLoad, getGlobalPersonaRegistry } from '../../persona/
2
2
  import { resolvePersonaAddress } from '../../intake-plane/persona-answer.js';
3
3
  import { loadSession, updateSessionMeta } from '../../session/index.js';
4
4
  import { assemblePersonaPrompt } from '../../persona/prompt-assembler.js';
5
+ import type { PromptSource } from '../../persona/prompt-assembler.js';
5
6
  import type { LLMMessage } from '../../llm.js';
6
7
 
7
8
  /** Unattached conversations use a dashboard-local id; attached sessions use persisted metadata. */
8
9
  export class TuiChatPersonaSelection {
9
10
  private readonly selected = new Map<string, string>();
11
+ /** 적용 시점 캡처 스냅샷 — registry와 별개 저장소, 조회는 이 값을 반환한다. */
12
+ private readonly applied = new Map<string, TuiChatPersonaAppliedSource>();
10
13
 
11
14
  get(sessionId: string): string | undefined {
12
15
  return loadSession(sessionId)?.meta.chatPersonaId ?? this.selected.get(sessionId);
13
16
  }
14
17
 
18
+ /** Application-time source snapshot; survives later registry replacement. */
19
+ appliedSource(sessionId: string): TuiChatPersonaAppliedSource | undefined {
20
+ return this.applied.get(sessionId);
21
+ }
22
+
15
23
  set(sessionId: string, personaId: string | undefined): void {
16
24
  const meta = updateSessionMeta(sessionId, (m) => {
17
25
  if (personaId) m.chatPersonaId = personaId;
@@ -23,6 +31,22 @@ export class TuiChatPersonaSelection {
23
31
  } else {
24
32
  this.selected.delete(sessionId);
25
33
  }
34
+ if (!personaId) {
35
+ this.applied.delete(sessionId);
36
+ return;
37
+ }
38
+ const persona = getGlobalPersonaRegistry().get(personaId);
39
+ if (!persona) {
40
+ this.applied.delete(sessionId);
41
+ return;
42
+ }
43
+ const { systemPrompt, sources } = assemblePersonaPrompt(persona, '');
44
+ this.applied.set(sessionId, {
45
+ personaId: persona.personaId,
46
+ displayName: persona.displayName,
47
+ sources,
48
+ systemPrompt,
49
+ });
26
50
  }
27
51
  }
28
52
 
@@ -41,8 +65,10 @@ export async function handleTuiChatPersona(
41
65
  if (!args.length) {
42
66
  const selected = selection.get(sessionId);
43
67
  const personas = registry.list().sort((a, b) => a.displayName.localeCompare(b.displayName));
44
- const current = personas.find(p => p.personaId === selected);
45
- return `이 대화의 페르소나: ${current ? `${current.displayName} (${current.personaId})` : '없음'}\n고를 수 있는 페르소나: ${personas.map(p => `${p.displayName} (${p.personaId})${p.personaId === selected ? ' (지금)' : ''}`).join(' · ') || '없음'}\n고르기: /persona <이름> · 빼기: /persona -`;
68
+ // 조각 7/9 출처 보존 — 지금 적용된 출처는 적용 시점 스냅샷으로 보여준다.
69
+ // registry 가 이후 교체·오염돼도 이 대화에 적용된 출처는 그대로다.
70
+ const applied = tuiChatPersonaSources(sessionId, selection);
71
+ return `이 대화의 페르소나: ${applied ? `${applied.displayName} (${applied.personaId})` : '없음'}\n고를 수 있는 페르소나: ${personas.map(p => `${p.displayName} (${p.personaId})${p.personaId === selected ? ' (지금)' : ''}`).join(' · ') || '없음'}\n고르기: /persona <이름> · 빼기: /persona -`;
46
72
  }
47
73
  const name = args.join(' ');
48
74
  const persona = resolvePersonaAddress(name, registry);
@@ -54,13 +80,44 @@ export async function handleTuiChatPersona(
54
80
  }
55
81
  }
56
82
 
57
- export function tuiChatPersonaMessages(
83
+ /** Applied persona source captured at application time (조각 7/9 출처 보존).
84
+ * The snapshot lives in a store separate from the registry — the session
85
+ * meta `chatPersonaId` holds the applied id durably, and this
86
+ * application-time snapshot holds displayName, sources and systemPrompt —
87
+ * so replacing or contaminating the registry after the apply cannot
88
+ * rewrite what this conversation applied. */
89
+ export interface TuiChatPersonaAppliedSource {
90
+ /** Source identifier — string-identical to the loader personaId. */
91
+ readonly personaId: string;
92
+ /** Display name as loaded when the persona was applied. */
93
+ readonly displayName: string;
94
+ /** Source breakdown from prompt assembly, captured at apply time. */
95
+ readonly sources: readonly PromptSource[];
96
+ /** System prompt assembled when the persona was applied. */
97
+ readonly systemPrompt: string;
98
+ }
99
+
100
+ /** Resolve the applied persona source (조각 7/9 출처 보존). Serves the
101
+ * application-time snapshot captured in the selection — per-call registry
102
+ * re-derivation is not preservation. Falls back to the persisted session
103
+ * meta `chatPersonaId` plus a registry lookup only when no snapshot exists
104
+ * yet, e.g. a fresh process restoring a persisted session. */
105
+ export function tuiChatPersonaSources(
58
106
  sessionId: string, selection: TuiChatPersonaSelection,
59
- ): LLMMessage[] {
107
+ ): TuiChatPersonaAppliedSource | undefined {
108
+ const captured = selection.appliedSource(sessionId);
109
+ if (captured) return captured;
60
110
  const id = selection.get(sessionId);
61
- if (!id) return [];
111
+ if (!id) return undefined;
62
112
  const persona = getGlobalPersonaRegistry().get(id);
63
- if (!persona) return [];
64
- const prompt = assemblePersonaPrompt(persona, '').systemPrompt;
65
- return prompt ? [{ role: 'system', content: prompt }] : [];
113
+ if (!persona) return undefined;
114
+ const { systemPrompt, sources } = assemblePersonaPrompt(persona, '');
115
+ return { personaId: id, displayName: persona.displayName, sources, systemPrompt };
116
+ }
117
+
118
+ export function tuiChatPersonaMessages(
119
+ sessionId: string, selection: TuiChatPersonaSelection,
120
+ ): LLMMessage[] {
121
+ const applied = tuiChatPersonaSources(sessionId, selection);
122
+ return applied?.systemPrompt ? [{ role: 'system', content: applied.systemPrompt }] : [];
66
123
  }
@@ -344,7 +344,8 @@ import { termSize, stripAnsi } from '../../tui.js';
344
344
  import { SLASH_COMMANDS } from '../../chat/index.js';
345
345
  import { buildEssentialHelpLines } from './help-from-registry.js';
346
346
  import { registerDashboardLogSlash } from './dashboard-log-slash.js';
347
- import { HUMAN_MODEL_WORDS, MODEL_CODE_NAMES, humanWordForModel, modelChangeLine, modelOverviewLines, modelScopeLine, modelSwitchScope, parseModelSlashArgs, resolveModelChoice } from './model-choices.js';
347
+ import { HUMAN_MODEL_WORDS, MODEL_CODE_NAMES, humanWordForModel, modelActualNote, modelChangeLine, modelOverviewLines, modelScopeLine, modelSwitchScope, parseModelSlashArgs, resolveModelChoice } from './model-choices.js';
348
+ import { statusModelActual } from '../../status/status-provider-info.js';
348
349
  import type { FoldMode } from '../../log-entry.js';
349
350
  import { debug } from '../../debug/log.js';
350
351
  import { observeSessionStart } from '../../session/session-start.js';
@@ -4800,7 +4801,7 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
4800
4801
  const [, codes] = modelOverviewLines(curProvider, curModel, curReasoning);
4801
4802
  // A model outside the 빠름/보통/깊음 map (codename or custom) says so explicitly instead of dropping the tier slot.
4802
4803
  const tierName = humanWordForModel(curProvider, curModel, curReasoning) ?? '단계 밖';
4803
- ctx.chatLines.push(`지금: ${curModel?.trim() || '기본 모델'} (${tierName} · 생각 ${curReasoning}${pin ? ' · 이 세션 핀' : ''}) · 고르기: /model ${HUMAN_MODEL_WORDS.join(' | ')}`);
4804
+ ctx.chatLines.push(`지금: ${curModel?.trim() || '기본 모델'} (${tierName} · 생각 ${curReasoning}${pin ? ' · 이 세션 핀' : ''})${modelActualNote(curModel, statusModelActual('dashboard'))} · 고르기: /model ${HUMAN_MODEL_WORDS.join(' | ')}`);
4804
4805
  ctx.chatLines.push(ctx.muted(codes));
4805
4806
  ctx.setChatScrollOffset(-1);
4806
4807
  return;
@@ -8,6 +8,7 @@
8
8
  import type { LLMProviderName, ReasoningLevel } from '../../user-config.js';
9
9
  import { lookupLlmTierSpec } from '../../model-tier/index.js';
10
10
  import type { ModelTier } from '../../model-tier/types.js';
11
+ import type { ModelExecutionActual } from '../../status/bar.js';
11
12
 
12
13
  export interface ModelTarget {
13
14
  readonly model: string;
@@ -72,6 +73,20 @@ export function resolveModelChoice(rawArg: string, currentProvider: LLMProviderN
72
73
  return { kind: 'unknown', arg };
73
74
  }
74
75
 
76
+ /** `/model` «지금:» 에 덧붙는 «이번 턴 실제» (TUI-MODEL-BADGE-ACTUAL · 10-16 · #24·#66).
77
+ * 상태줄 배지와 «같은» 원천(`statusModelActual`)을 쓰므로 두 화면이 다른 말을 하지 않는다.
78
+ * 이번 턴 실행이 없거나 이미 보이는 모델과 같으면 '' — 꾸미지 않는다(기본 출력 보존). */
79
+ export function modelActualNote(
80
+ shownModel: string | null | undefined,
81
+ actual: ModelExecutionActual | null | undefined,
82
+ ): string {
83
+ const model = actual?.model?.trim();
84
+ if (!model) return '';
85
+ const from = actual?.fallbackFrom?.trim();
86
+ if (!from && model === shownModel?.trim()) return '';
87
+ return ` · 이번 턴 실제: ${from ? `${from} → ${model}` : model}`;
88
+ }
89
+
75
90
  /**
76
91
  * The human word for (`model`, `reasoning`) on `provider`: an exact tier match first; without a reasoning
77
92
  * level (or no exact match) only a model that names a single tier counts — an ambiguous model gets no word.
@@ -1,99 +1,3 @@
1
- import { realpathSync } from 'node:fs';
2
- import { homedir } from 'node:os';
3
- import { basename, dirname, join, resolve } from 'node:path';
4
-
5
- import { readInstallMetadataCommit } from '../version/code-revision.js';
6
-
7
- export type StaleInstallResult = {
8
- state: 'same' | 'changed' | 'unknown' | 'not-installed';
9
- bootCommit: string | undefined;
10
- installedCommit: string | undefined;
11
- };
12
-
13
- export const STALE_INSTALL_CHECK_INTERVAL_MS = 60_000;
14
-
15
- /**
16
- * Builds the command that relaunches the TUI on the same daemon session: `elanous --resume <id>` boots the dashboard,
17
- * loads that session (ACP session/load) and replays its turns (src/index.ts resumeSessionId · dashboard acp-boot).
18
- * The user-facing hint and its key binding land with the dashboard wiring slice (`r` is the render toggle today).
19
- * Intentional wiring boundary: the dashboard owns the key binding and executes this command;
20
- * this scoped helper only constructs it and does not spawn a child process.
21
- */
22
- export function buildStaleInstallRelaunchCommand(sessionId: string): string {
23
- return `elanous --resume ${JSON.stringify(sessionId)}`;
24
- }
25
-
26
- export function formatStaleInstallNotice(result: StaleInstallResult, notifiedCount: number): string {
27
- const message = `새 판이 깔렸습니다 (부팅 판 ${result.bootCommit!.slice(0, 7)} → 지금 ${result.installedCommit!.slice(0, 7)}) · TUI 를 다시 띄우면 새 판으로 돕니다`;
28
- return notifiedCount >= 2 ? `${message} · 이 TUI 가 뜬 뒤 ${notifiedCount}번째 새 판` : message;
29
- }
30
-
31
- /** Identify the immutable installed version containing this module, never the session cwd. */
32
- export function versionedDashboardInstallDir(
33
- codeRoot: string,
34
- installRoot = join(homedir(), '.local', 'share', 'elanous'),
35
- ): string | undefined {
36
- try {
37
- const packageRoot = realpathSync(codeRoot);
38
- if (basename(packageRoot) !== 'elanous' || basename(dirname(packageRoot)) !== 'node_modules') return undefined;
39
- const versionDir = dirname(dirname(packageRoot));
40
- let canonicalInstallRoot: string;
41
- try { canonicalInstallRoot = realpathSync(installRoot); }
42
- catch { canonicalInstallRoot = resolve(installRoot); }
43
- if (dirname(versionDir) !== join(canonicalInstallRoot, 'versions')) return undefined;
44
- const requestedVersionDir = dirname(dirname(resolve(codeRoot)));
45
- return dirname(requestedVersionDir) === resolve(installRoot, 'versions')
46
- && realpathSync(requestedVersionDir) === versionDir
47
- ? requestedVersionDir : versionDir;
48
- } catch {
49
- return undefined;
50
- }
51
- }
52
-
53
- export function createStaleInstallCheck(input: {
54
- bootCommit: string | undefined;
55
- readInstalledCommit: () => string | undefined;
56
- now: () => number;
57
- codeRoot?: string;
58
- installRoot?: string;
59
- }) {
60
- const installed = input.codeRoot === undefined
61
- || versionedDashboardInstallDir(input.codeRoot, input.installRoot) !== undefined;
62
- const notifiedCommits = new Set<string>();
63
- let lastReadAt = -Infinity;
64
- let lastResult: StaleInstallResult | undefined;
65
- const check = (): StaleInstallResult => {
66
- if (!installed) return { state: 'not-installed', bootCommit: input.bootCommit, installedCommit: undefined };
67
- const time = input.now();
68
- if (lastResult && time - lastReadAt < STALE_INSTALL_CHECK_INTERVAL_MS) return lastResult;
69
- lastReadAt = time;
70
- let installedCommit: string | undefined;
71
- try { installedCommit = input.readInstalledCommit(); } catch { /* unreadable metadata */ }
72
- const result: StaleInstallResult = {
73
- state: !input.bootCommit || !installedCommit
74
- ? 'unknown'
75
- : input.bootCommit === installedCommit ? 'same' : 'changed',
76
- bootCommit: input.bootCommit,
77
- installedCommit,
78
- };
79
- lastResult = result;
80
- return result;
81
- };
82
- return {
83
- check,
84
- shouldNotify(result: StaleInstallResult): boolean {
85
- if (result.state !== 'changed' || !result.installedCommit || notifiedCommits.has(result.installedCommit)) return false;
86
- notifiedCommits.add(result.installedCommit);
87
- return true;
88
- },
89
- };
90
- }
91
-
92
- /** Only the current pointer is polled; boot metadata is read once from the immutable version. */
93
- export function readDashboardBootCommit(versionDir: string): string | undefined {
94
- return readInstallMetadataCommit(join(versionDir, 'install.json'));
95
- }
96
-
97
- export function readCurrentInstalledCommit(installRoot = join(homedir(), '.local', 'share', 'elanous')): string | undefined {
98
- return readInstallMetadataCommit(join(installRoot, 'current', 'install.json'));
99
- }
1
+ // Dashboard compatibility entry. The implementation is kept in pty-shell so
2
+ // non-dashboard observers can read install state without loading dashboard code.
3
+ export * from '../pty-shell/stale-install-check.js';
@@ -0,0 +1,119 @@
1
+ // TUI-TYPING-LAG — bounded-chunk drain queue for the log plane.
2
+ //
3
+ // A worker that floods the log (streaming chunks, subagent output) used to hand
4
+ // the main thread one synchronous drain of the whole burst (e.g. StoreSink's
5
+ // detached flush inserting thousands of sqlite rows in one macrotask), so a key
6
+ // typed meanwhile waited for the entire drain (0.25–2.4s stalls). This queue
7
+ // drains at most `batchSize` items per scheduled tick and schedules the remainder
8
+ // as a NEW tick, so the event loop gets back to I/O (stdin) between chunks.
9
+ //
10
+ // Zero imports on purpose: the log sinks under
11
+ // src/mss/logging import it without creating a cycle.
12
+
13
+ /** Scheduler seam — production uses setImmediate / setTimeout(unref); stages inject a fake clock. */
14
+ export interface DebugBatchScheduler {
15
+ schedule(run: () => void, delayMs: number): unknown;
16
+ cancel(handle: unknown): void;
17
+ }
18
+
19
+ export const defaultDebugBatchScheduler: DebugBatchScheduler = {
20
+ schedule(run, delayMs) {
21
+ if (delayMs <= 0) return { immediate: setImmediate(run) };
22
+ const timer = setTimeout(run, delayMs);
23
+ (timer as unknown as { unref?: () => void }).unref?.();
24
+ return { timeout: timer };
25
+ },
26
+ cancel(handle) {
27
+ const h = handle as { immediate?: ReturnType<typeof setImmediate>; timeout?: ReturnType<typeof setTimeout> } | null;
28
+ if (!h) return;
29
+ if (h.immediate !== undefined) clearImmediate(h.immediate);
30
+ if (h.timeout !== undefined) clearTimeout(h.timeout);
31
+ },
32
+ };
33
+
34
+ export interface DebugLogBatchQueueOptions<T> {
35
+ /** Max items handed to `drain` per scheduled tick. `Infinity` = whole queue in one tick. */
36
+ batchSize: number;
37
+ /** Delay before each scheduled tick (0 = next loop iteration). */
38
+ flushDelayMs?: number;
39
+ scheduler?: DebugBatchScheduler;
40
+ /** Return `false` to stop chunking (e.g. the store is contended) — the remainder stays queued, unscheduled. */
41
+ drain: (items: T[]) => void | boolean;
42
+ }
43
+
44
+ export class DebugLogBatchQueue<T> {
45
+ private items: T[] = [];
46
+ private handle: unknown = null;
47
+ private hasHandle = false;
48
+ private flushCount = 0;
49
+ private readonly batchSize: number;
50
+ private readonly flushDelayMs: number;
51
+ private readonly scheduler: DebugBatchScheduler;
52
+ private readonly drainFn: (items: T[]) => void | boolean;
53
+
54
+ constructor(opts: DebugLogBatchQueueOptions<T>) {
55
+ this.batchSize = opts.batchSize > 0 ? opts.batchSize : 1;
56
+ this.flushDelayMs = Math.max(0, opts.flushDelayMs ?? 0);
57
+ this.scheduler = opts.scheduler ?? defaultDebugBatchScheduler;
58
+ this.drainFn = opts.drain;
59
+ }
60
+
61
+ get pending(): number { return this.items.length; }
62
+ get flushes(): number { return this.flushCount; }
63
+ get scheduled(): boolean { return this.hasHandle; }
64
+
65
+ /** Enqueue without draining — the caller decides when to `schedule()`. */
66
+ push(item: T): void { this.items.push(item); }
67
+
68
+ /** Arm one drain tick (idempotent while a tick is in flight). */
69
+ schedule(): void {
70
+ if (this.hasHandle || this.items.length === 0) return;
71
+ this.hasHandle = true;
72
+ this.handle = this.scheduler.schedule(() => this.tick(), this.flushDelayMs);
73
+ }
74
+
75
+ /** Drop up to `count` oldest items; returns how many were dropped. */
76
+ dropOldest(count: number): number {
77
+ if (count <= 0) return 0;
78
+ const dropped = Math.min(count, this.items.length);
79
+ this.items.splice(0, dropped);
80
+ return dropped;
81
+ }
82
+
83
+ /** Synchronous full drain (exit / explicit flush) — one `drain` call, pending tick cancelled. */
84
+ flushAll(): void {
85
+ this.cancelTick();
86
+ if (this.items.length === 0) return;
87
+ const all = this.items;
88
+ this.items = [];
89
+ this.flushCount += 1;
90
+ this.drainFn(all);
91
+ }
92
+
93
+ /** Disarm the pending tick (items stay queued) — e.g. the store is contended. */
94
+ cancelScheduled(): void { this.cancelTick(); }
95
+
96
+ private cancelTick(): void {
97
+ if (!this.hasHandle) return;
98
+ this.scheduler.cancel(this.handle);
99
+ this.handle = null;
100
+ this.hasHandle = false;
101
+ }
102
+
103
+ private tick(): void {
104
+ this.handle = null;
105
+ this.hasHandle = false;
106
+ if (this.items.length === 0) return;
107
+ const chunk = Number.isFinite(this.batchSize)
108
+ ? this.items.splice(0, this.batchSize)
109
+ : this.items.splice(0, this.items.length);
110
+ this.flushCount += 1;
111
+ let keepGoing = true;
112
+ try {
113
+ keepGoing = this.drainFn(chunk) !== false;
114
+ } finally {
115
+ // The remainder is a separate tick so stdin can be served between chunks.
116
+ if (keepGoing) this.schedule();
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,67 @@
1
+ // TUI-LOG-SESSION-TAG (0.2.36 · 10-23) — tell TUIs apart in one logs.db.
2
+ //
3
+ // Several TUIs (classic `elanous` / `--legacy` and `--tui next`) on one host write to the same logs.db
4
+ // with surface `tui`. Their rows had no pid and usually no session_id (the dashboard does not set the
5
+ // ambient session), so the 10-23 n8n SIGTTIN incident could not tell which TUI's `tui.event-loop stall`
6
+ // was which. This wraps the TUI's logs.db sink and stamps every plain-object payload with:
7
+ // tuiPid — the TUI process id
8
+ // tuiName — the `--name` launch alias (when given)
9
+ // tuiSession — the chat session the TUI currently owns (getTuiOwnedSession, when known)
10
+ // Caller-supplied fields win; primitive / non-plain payloads are left untouched; an absent payload becomes
11
+ // the tag object. No schema change — the tag rides in the existing `data` column.
12
+ //
13
+ // Query: `elanous logs --surface tui --grep '"tuiName":"n8n"'` · `--grep '"tuiPid":20960'`
14
+ // or `--json | jq 'select((.data|fromjson? // {}).tuiName == "n8n")'`.
15
+
16
+ import type { LogSink } from '../mss/logging/sink.js';
17
+ import type { LogRecord } from '../mss/logging/record.js';
18
+
19
+ export interface TuiLogTag {
20
+ pid: number;
21
+ name?: string;
22
+ /** Current owned chat session id, or null. Called per record — keep it cheap. */
23
+ session?: () => string | null | undefined;
24
+ }
25
+
26
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
27
+ if (value === null || typeof value !== 'object') return false;
28
+ const p = Object.getPrototypeOf(value);
29
+ return p === Object.prototype || p === null;
30
+ }
31
+
32
+ /** Pure — returns the record with the tag applied (a new object when changed). */
33
+ export function tagTuiRecord(rec: LogRecord, tag: TuiLogTag): LogRecord {
34
+ let session: string | null | undefined;
35
+ try { session = tag.session?.(); } catch { session = undefined; }
36
+ const add: Record<string, unknown> = { tuiPid: tag.pid };
37
+ const name = tag.name?.trim();
38
+ if (name) add.tuiName = name;
39
+ if (session) add.tuiSession = session;
40
+ if (rec.data === undefined) return { ...rec, data: add };
41
+ if (!isPlainObject(rec.data)) return rec;
42
+ const data = rec.data;
43
+ const missing = Object.entries(add).filter(([k]) => !Object.hasOwn(data, k));
44
+ if (missing.length === 0) return rec;
45
+ return { ...rec, data: { ...data, ...Object.fromEntries(missing) } };
46
+ }
47
+
48
+ // Process-wide tag state — the TUI's self-report fills it (`--name` at launch, the owned session on every
49
+ // claim) so the sink wrapper needs no import of the TUI modules (no cycle · no hub edit).
50
+ let processName: string | undefined;
51
+ let processSession: string | null = null;
52
+ export function setTuiLogName(name: string | undefined): void { processName = name?.trim() || undefined; }
53
+ export function setTuiLogSession(id: string | null): void { processSession = id || null; }
54
+ /** The tag for this process: pid ⊕ the state above. */
55
+ export function processTuiLogTag(): TuiLogTag {
56
+ return { pid: process.pid, get name() { return processName; }, session: () => processSession };
57
+ }
58
+
59
+ /** Wraps a sink so every record it receives is tagged. */
60
+ export function withTuiLogTag(inner: LogSink, tag: TuiLogTag): LogSink {
61
+ return {
62
+ name: inner.name,
63
+ emit(rec: LogRecord): void { inner.emit(tagTuiRecord(rec, tag)); },
64
+ ...(inner.flush ? { flush: () => inner.flush?.() } : {}),
65
+ ...(inner.clear ? { clear: () => inner.clear?.() } : {}),
66
+ };
67
+ }
@@ -447,7 +447,14 @@ function recentToolTrail(task: AgentTask, limit: number, cache: ScanCache): Agen
447
447
  return trail;
448
448
  }
449
449
 
450
+ /** Tool calls the child made: the live counter (bumped as each call starts) or the
451
+ * tool_use blocks in its history, whichever is larger — history lags until a tool
452
+ * loop completes and stays short when the run is aborted or errors. */
450
453
  function countToolUses(task: AgentTask, cache: ScanCache): number {
454
+ return Math.max(task.toolCallCount ?? 0, countHistoryToolUses(task, cache));
455
+ }
456
+
457
+ function countHistoryToolUses(task: AgentTask, cache: ScanCache): number {
451
458
  const len = task.messages?.length ?? 0;
452
459
  if (len === 0) return 0;
453
460
  const cached = cache.count.get(task.id);