elanous 0.2.42 → 0.2.43

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 (685) 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/{X1ucLw10Cds_h614NoEnh → Om5xS9jpjSXJCeTNGYEi4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{7a98bc80.fa935989e829f9c2.js → 0966f8a1.745fcd44f64a87ea.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{73d2eb0e.4966ad55293c801a.js → 0ad6802e.ae7afb63fdcb4491.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1200.6a37c202f9f17e9a.js +226 -0
  9. package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1313-19f737e0222c4444.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{3507.97e1977bc4d5fb0a.js → 1406.a1dc2ab6f8449374.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1961.a81b12872c3e93a9.js +23 -0
  17. package/apps/pwa/out/_next/static/chunks/{53c73f84.373b6160adfa89a4.js → 1970cf59.2d4d8ce5d6c81853.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{9211-330b6736a63d4cb3.js → 2073-ba274e00e4f9efb4.js} +1 -1
  20. package/apps/pwa/out/_next/static/chunks/{7411.9b4b8b747dc7b802.js → 2144.25b292396712196d.js} +2 -2
  21. package/apps/pwa/out/_next/static/chunks/2268-53861f339e0b65a2.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2312.0c8b61e22d3136d7.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6632.0eac1c554f8f2ef3.js → 2573.387a707f6f9d720c.js} +2 -2
  24. package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/{1262.e804feb8fd1acb8c.js → 3072.01338851ca21a6f7.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +90 -0
  28. package/apps/pwa/out/_next/static/chunks/{2456.b6de0e1c05f28843.js → 3095.dc44586a5f83b86d.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{3207.a756c95e9ec8c3c8.js → 3113.d7472bbc27d580c7.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3402.44b565b314f2263c.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3557ac4a.c8931684475018ad.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/{8505.fd803c6c33b54cc3.js → 360.ae9f9f4c33c395e8.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +286 -0
  35. package/apps/pwa/out/_next/static/chunks/{b450776b.3db34d8d965f82d3.js → 363bfab3.9623b9f89363541f.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3694.e0099884345f0198.js +64 -0
  37. package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3903.3ef4656c67572764.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3935.16701e33f8982dc9.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3955.6922286237f2ac2b.js +24 -0
  41. package/apps/pwa/out/_next/static/chunks/3969.272ee7f9fd6c62e5.js +34 -0
  42. package/apps/pwa/out/_next/static/chunks/{8138.6c10b2a356d52fca.js → 4199.ce86b281fd0a60b7.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{2690.0521c738b7749931.js → 4445.7990c76b3751a918.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/{1945.7b54990d578c119b.js → 4894.fec2ca9e99caefa2.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +94 -0
  52. package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +36 -0
  54. package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +93 -0
  56. package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{9427.96aa912ddb5801e0.js → 5564.9e72532188f57586.js} +16 -16
  59. package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/{4043.6b91203436c9c86b.js → 5628.6ddb2d5ffba4ff4c.js} +4 -4
  63. package/apps/pwa/out/_next/static/chunks/{1319.b9b815ae0f181e06.js → 5730.43d7ccc09988e646.js} +1 -1
  64. package/apps/pwa/out/_next/static/chunks/{3482.a9ae9d2ad6a5bd97.js → 5789.2da35c258292e1e5.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5824.da9527b15a3221e5.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5866.366966af47fdde5d.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{1487.2f67b79444062da6.js → 5930.8b4df3b46c32b05a.js} +1 -1
  68. package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +27 -0
  70. package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +104 -0
  73. package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +287 -0
  75. package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{3347.f846266b5e5f3ede.js → 6540.c7bef57ad8f90a87.js} +3 -3
  78. package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{8262.ddc03e06b733f184.js → 6944.309f4e3ea54d1537.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/{4770.769c9cd9c7034eba.js → 7483.427a2fe2049e388d.js} +2 -2
  88. package/apps/pwa/out/_next/static/chunks/{1147-5196d19c222051b3.js → 7502-be74718178e13e56.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +24 -0
  90. package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7900.096f455c7c1efc53.js +77 -0
  93. package/apps/pwa/out/_next/static/chunks/7910-6f139bcafd238b9f.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{8673-bab689a55f7e13b9.js → 8062-7cd0bcc7f01455ba.js} +3 -3
  96. package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +74 -0
  98. package/apps/pwa/out/_next/static/chunks/8205.282ca4bb62d54a0a.js +62 -0
  99. package/apps/pwa/out/_next/static/chunks/8313-dfa1021bb58a46d6.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/837-81336ebaca8198a8.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8588.d1c6a2903727ce87.js +149 -0
  104. package/apps/pwa/out/_next/static/chunks/8637.90f92d5c8db4732c.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/868.6e953be05bcf6dca.js +41 -0
  106. package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{9656-374232558fd528d0.js → 8861-cc1fa1c7b920fa8e.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/{5440-4236de26c5ea5856.js → 8967-7dfebf710c9dec9d.js} +1 -1
  110. package/apps/pwa/out/_next/static/chunks/{1063.2fb8a9dc55c731f2.js → 8986.8e2e4efbfa655c59.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/{4320.583cbab64db6be02.js → 923.2034d10ae91e9c20.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{1574.878c18ecc97b1bd4.js → 943.39ae5e82f4f1893f.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +32 -0
  116. package/apps/pwa/out/_next/static/chunks/9770.5f75bc6088b16109.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +8 -0
  119. package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/aa57532f.510551854ff239b1.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-0f291d3c8fd55a3a.js → page-9ee28f7df07428ea.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-79a8b5fee4c20871.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ca2d09128c585ca4.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-0a815f34367b6db6.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/c7945435-b44d4dbe90ba0dcb.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{3d0154af.5331fec737ffe8c3.js → cb0f8df8.09a4a6be97e3fc5f.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{e8543907.5b040a5f22a0b0e5.js → d96660fb.cbc21a2a88539dbb.js} +7 -7
  176. package/apps/pwa/out/_next/static/chunks/{50061469.0326382241ef3b2d.js → ea514caa.05a24f78d9dffe5f.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/fb7d20d5-6892502b6ee39ca6.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +1 -0
  184. package/apps/pwa/out/_next/static/css/d1f8bb401740a549.css +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/catalog/external-commands.yaml +5 -3
  279. package/catalog/meta/catalogVersion.yaml +2 -1
  280. package/catalog/signing/catalog-signing-public.pem +3 -0
  281. package/graphs/intake/intake-daily.yaml +16 -0
  282. package/graphs/intake/news-sources.yaml +1 -0
  283. package/graphs/intake/recipes.yaml +7 -0
  284. package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
  285. package/graphs/profiles/local.yaml +5 -0
  286. package/graphs/profiles/pod.yaml +4 -0
  287. package/package.json +6 -2
  288. package/plugins/demo-absorption-briefing/plugin.json +18 -0
  289. package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
  290. package/plugins/demo-browser-hand/plugin.json +13 -0
  291. package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
  292. package/plugins/demo-linear-secretary/plugin.json +15 -0
  293. package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
  294. package/plugins/demo-plugin-wizard/plugin.json +11 -0
  295. package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
  296. package/plugins/demo-research/plugin.json +16 -0
  297. package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
  298. package/plugins/demo-video-briefing/plugin.json +15 -0
  299. package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
  300. package/scripts/build-signed-catalog.ts +48 -0
  301. package/scripts/ci-typecheck-main-delta.sh +88 -0
  302. package/scripts/codex-fallback-live-probe.ts +1 -1
  303. package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
  304. package/scripts/demo/demo1104-stage.config.ts +21 -0
  305. package/scripts/demo/demo1104-stage.ts +316 -0
  306. package/scripts/goal-method-audit.ts +17 -1
  307. package/scripts/graph-units/land-enqueue.ts +90 -0
  308. package/scripts/hooks/codex-notify.sh +32 -0
  309. package/scripts/install.sh +10 -38
  310. package/scripts/landing-heal/land-plan.ts +57 -0
  311. package/scripts/release-loop/auto-approve-node.ts +1 -1
  312. package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
  313. package/scripts/release-loop/gate-method.ts +139 -0
  314. package/scripts/release-loop/gate-node.ts +180 -20
  315. package/scripts/release-loop/gate-traffic-mode.ts +151 -3
  316. package/scripts/release-loop/node-verdict.ts +38 -25
  317. package/scripts/release-loop/preflight.ts +362 -8
  318. package/scripts/release-loop/unattended-release.ts +20 -9
  319. package/scripts/rhythm/daily.ts +36 -4
  320. package/scripts/rhythm/linear-progress-sync.ts +298 -0
  321. package/scripts/video-pipeline.ts +9 -1
  322. package/scripts/warm-pool-provider-config.ts +29 -6
  323. package/src/acp/agent-manager.ts +1 -0
  324. package/src/acp/codex-app-server-agent.ts +33 -0
  325. package/src/acp/codex-app-server-client.ts +153 -16
  326. package/src/acp/core-turn-bridge.ts +17 -12
  327. package/src/acp/event-router.ts +20 -1
  328. package/src/acp/server.ts +6 -0
  329. package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
  330. package/src/agent-mission/claude-headless.ts +4 -1
  331. package/src/agent-mission/codex-exec.ts +105 -0
  332. package/src/agent-mission/driver.ts +192 -11
  333. package/src/agent-mission/grok-auth-status.ts +47 -0
  334. package/src/agent-mission/hand-hooks.ts +101 -0
  335. package/src/agent-mission/mission-cli.ts +56 -21
  336. package/src/agent-mission/mission-hand-reply.ts +118 -0
  337. package/src/agent-mission/mission-line.ts +180 -0
  338. package/src/agent-mission/mission-out.ts +256 -18
  339. package/src/agent-mission/tool-install.ts +122 -11
  340. package/src/agents/general-purpose.md +1 -1
  341. package/src/auto-research/research-turn.ts +95 -10
  342. package/src/autopilot/pr-manager.ts +31 -3
  343. package/src/boot/daemon-tools/self-implement.ts +3 -1
  344. package/src/boot/daemon-tools/web-search.ts +1 -2
  345. package/src/briefing/brief-items.ts +55 -11
  346. package/src/cli/agent-cli.ts +2 -1
  347. package/src/cli/catalog-cli.ts +31 -0
  348. package/src/cli/connector-cli.ts +16 -0
  349. package/src/cli/doctor-fix.ts +2 -2
  350. package/src/cli/intake-source-cli.ts +44 -8
  351. package/src/cli/msg-cli.ts +32 -3
  352. package/src/cli/pr-cli.ts +21 -1
  353. package/src/cli/pr-land-heavy-remote.ts +44 -6
  354. package/src/cli/pr-land-overlap-evidence.ts +13 -1
  355. package/src/cli/pr-land-pod-shadow-job.ts +143 -5
  356. package/src/cli/pr-land-pod-shadow.ts +9 -2
  357. package/src/cli/release-checklist-read-cli.ts +44 -16
  358. package/src/cli/release-cli.ts +23 -3
  359. package/src/cli/research-cli.ts +9 -0
  360. package/src/cli/setup-cli.ts +166 -6
  361. package/src/cli/setup-keys.ts +187 -0
  362. package/src/cli/task-plugin-wizard-host.ts +114 -0
  363. package/src/cli/tasks-cli.ts +54 -9
  364. package/src/cli/tui-test-cli.ts +186 -0
  365. package/src/config.ts +4 -2
  366. package/src/connectors/linear-daily-progress.ts +228 -0
  367. package/src/connectors/linear-projector.ts +34 -12
  368. package/src/connectors/linear.ts +151 -7
  369. package/src/core-turn/deep-turn-bloom.ts +67 -0
  370. package/src/core-turn/research-policy.ts +37 -0
  371. package/src/core-turn/run-core-turn.ts +320 -30
  372. package/src/core-turn/types.ts +2 -0
  373. package/src/dashboard/chat/acp-chat.ts +10 -0
  374. package/src/dashboard/classic-sidetab-mission-job.ts +103 -0
  375. package/src/dashboard/classic-sidetab-mission-pair.ts +81 -0
  376. package/src/dashboard/classic-sidetab-mission-trio.ts +219 -0
  377. package/src/dashboard/classic-sidetab-mission.ts +167 -5
  378. package/src/dashboard/index.ts +378 -13
  379. package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
  380. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +8 -0
  381. package/src/dashboard/mission-cli-consumer.ts +20 -8
  382. package/src/dashboard/plugin-wizard-runtime.ts +50 -0
  383. package/src/dashboard/plugin-wizard-tool.ts +55 -0
  384. package/src/dashboard/sidetab-runtime.ts +1 -1
  385. package/src/dashboard/terminal-popup-runtime.ts +6 -3
  386. package/src/decisions/linear-progress-summary.ts +78 -0
  387. package/src/decisions/linear-progress-sync.ts +152 -0
  388. package/src/domains/outbound-alert.ts +49 -11
  389. package/src/domains/telegram-kind-route.ts +16 -9
  390. package/src/graph-runner/arg-allowance.ts +13 -0
  391. package/src/graph-runner/graph-run-api.ts +3 -1
  392. package/src/graph-runner/runner.ts +85 -17
  393. package/src/graph-wizard/mission-compose.ts +407 -12
  394. package/src/harness/dispatch-backpressure.ts +54 -1
  395. package/src/harness/dispatch-shadow-compare.ts +74 -0
  396. package/src/harness/harness-cli-command.ts +11 -1
  397. package/src/harness/skill-exec.ts +21 -9
  398. package/src/harness/skill-select.ts +1 -1
  399. package/src/hooks/error-report-cloud.ts +101 -0
  400. package/src/hooks/receiver.ts +29 -2
  401. package/src/index.ts +127 -10
  402. package/src/intake-plane/actions.ts +354 -0
  403. package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
  404. package/src/intake-plane/intake-sources.ts +78 -8
  405. package/src/intake-plane/items.ts +14 -4
  406. package/src/intake-plane/linear-mission-sync.ts +80 -0
  407. package/src/intake-plane/linear-secretary-runtime.ts +178 -0
  408. package/src/intake-plane/linear-wish.ts +227 -1
  409. package/src/life/life-cli.ts +168 -0
  410. package/src/life/life-kinds.ts +160 -0
  411. package/src/live-supply/budget-consumer.ts +78 -0
  412. package/src/live-supply/read.ts +3 -0
  413. package/src/live-supply/snapshot.ts +45 -0
  414. package/src/llm/provider-credentials.ts +8 -2
  415. package/src/llm.ts +2 -1
  416. package/src/maturity/feature-maturity.ts +3 -3
  417. package/src/msg/msg-sse-server.ts +3 -3
  418. package/src/msg/msg-store.ts +177 -19
  419. package/src/native-tool-catalog.ts +36 -2
  420. package/src/nexus/api/http-server.ts +37 -1
  421. package/src/nexus/api/mcp-public-allowlist.ts +2 -0
  422. package/src/nexus/index.ts +7 -2
  423. package/src/nexus/outbound/format.ts +9 -0
  424. package/src/nexus/outbound/router.ts +98 -13
  425. package/src/nexus/setup-status.ts +9 -0
  426. package/src/nexus/state/state.ts +3 -0
  427. package/src/oauth/codex-account-store.ts +20 -7
  428. package/src/oauth/codex-owner-mirror.ts +44 -0
  429. package/src/oauth/codex.ts +17 -2
  430. package/src/oauth/fallback-chain.ts +47 -17
  431. package/src/onboarding/first-run-doctor.ts +8 -1
  432. package/src/onboarding/first-run.ts +85 -26
  433. package/src/onboarding/key-setup.ts +103 -0
  434. package/src/onboarding/menu-answer.ts +13 -0
  435. package/src/onboarding/secret-prompt.ts +37 -0
  436. package/src/plugins/install/plugin-install.ts +59 -0
  437. package/src/pr-tool/census.ts +130 -0
  438. package/src/pty-shell/pty-control-ipc.ts +4 -1
  439. package/src/registry/catalog-server.ts +232 -0
  440. package/src/registry/loader.ts +45 -1
  441. package/src/registry/types.ts +1 -2
  442. package/src/research/axis-fanout.ts +43 -28
  443. package/src/self-dev/ask-launch-flow.ts +72 -1
  444. package/src/self-dev/dev-cli.ts +4 -1
  445. package/src/self-dev/dev-pipeline.ts +5 -0
  446. package/src/self-dev/draft-residue.ts +64 -5
  447. package/src/self-dev/graph-front-nodes.ts +2 -1
  448. package/src/self-dev/graph-journey-route.ts +76 -21
  449. package/src/self-dev/launch-preflight.ts +58 -0
  450. package/src/self-dev/orchestrate.ts +1 -1
  451. package/src/self-dev/shard-aggregate.ts +4 -0
  452. package/src/self-dev/shard-run.ts +36 -15
  453. package/src/self-implement/abandoned-classification.ts +12 -3
  454. package/src/self-implement/budget-gate.ts +7 -0
  455. package/src/self-implement/child-llm-preference.ts +10 -1
  456. package/src/self-implement/doctor-visit.ts +30 -8
  457. package/src/self-implement/elanous-tui-spawn.ts +3 -0
  458. package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
  459. package/src/self-implement/gate-artifacts.ts +2 -1
  460. package/src/self-implement/goal-author-cli.ts +4 -2
  461. package/src/self-implement/goal-author.ts +358 -4
  462. package/src/self-implement/graph-overlay-yaml.ts +30 -4
  463. package/src/self-implement/graph-overlay.ts +3 -1
  464. package/src/self-implement/graph-profile-yaml.ts +107 -0
  465. package/src/self-implement/graph-yaml.ts +26 -3
  466. package/src/self-implement/off-diff-evidence.ts +249 -5
  467. package/src/self-implement/orchestrator.ts +240 -15
  468. package/src/self-implement/run-chart.ts +6 -3
  469. package/src/self-implement/run-ledger.ts +51 -1
  470. package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
  471. package/src/self-implement/tdd-evidence-tags.ts +9 -0
  472. package/src/self-implement/train-gate-receipt.ts +166 -0
  473. package/src/self-implement/train-gate-remote.ts +62 -18
  474. package/src/session/chat.ts +4 -2
  475. package/src/session/session-fanout.ts +2 -0
  476. package/src/session/streaming/acp-stream-sink.ts +2 -1
  477. package/src/session/streaming/chunk-producer.ts +6 -0
  478. package/src/session/streaming/stream-compositor.ts +3 -2
  479. package/src/session-runtime/index.ts +37 -1
  480. package/src/session-runtime/retry-policy.ts +1 -1
  481. package/src/setup/llm-env-detect.ts +3 -0
  482. package/src/setup/service-key-catalog.ts +46 -0
  483. package/src/setup/service-keys.ts +241 -0
  484. package/src/sidetab-core/visible-agent-mission.ts +98 -22
  485. package/src/skills/tools/agent.ts +23 -4
  486. package/src/skills/tools/omni-search.ts +123 -25
  487. package/src/task-agent/parent-host.ts +10 -0
  488. package/src/task-agent/repair-outcomes.ts +65 -0
  489. package/src/task-agent/task-hand.ts +20 -7
  490. package/src/task-orchestrator/dispatcher.ts +14 -1
  491. package/src/task-orchestrator/linear-capture-events.ts +55 -0
  492. package/src/task-orchestrator/store.ts +16 -5
  493. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +4 -0
  494. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +92 -1
  495. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
  496. package/src/task-orchestrator/surfaces/pod-source-receive.ts +23 -11
  497. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
  498. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +35 -9
  499. package/src/task-orchestrator/surfaces/self-implement-pod.ts +172 -6
  500. package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
  501. package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
  502. package/src/task-orchestrator/types.ts +14 -0
  503. package/src/telegram.ts +14 -16
  504. package/src/terminal/coding-agent.ts +14 -5
  505. package/src/terminal/session-registry.ts +1 -1
  506. package/src/tool-hints/gate.ts +1 -0
  507. package/src/tool-runtime/agent-runtime.ts +1 -0
  508. package/src/tool-runtime/browser-hand-runtime.ts +381 -0
  509. package/src/tool-runtime/browser-runtime.ts +2 -1
  510. package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
  511. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +57 -0
  512. package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
  513. package/src/tool-runtime/index.ts +6 -0
  514. package/src/tool-runtime/types.ts +3 -0
  515. package/src/tui/entry.ts +24 -1
  516. package/src/tui/sidetab/attach.ts +140 -11
  517. package/src/tui/sidetab/herdr-portal.ts +225 -0
  518. package/src/user-config.ts +34 -9
  519. package/src/user-intent/types.ts +4 -3
  520. package/src/ux-sim/browser-hand.ts +165 -0
  521. package/src/ux-sim/draft-inventory-builder.ts +198 -0
  522. package/src/ux-sim/fake-browser-page.ts +81 -0
  523. package/src/ux-sim/fake-linear-device.ts +31 -0
  524. package/src/ux-sim/graph-engine-sim.ts +47 -0
  525. package/src/ux-sim/linear-secretary.ts +216 -0
  526. package/src/ux-sim/mock-scenario-catalog.json +75 -23
  527. package/src/ux-sim/mock-scenario-catalog.ts +120 -2
  528. package/src/ux-sim/onboarding-first-run-device.ts +31 -21
  529. package/src/ux-sim/scenario.ts +70 -26
  530. package/src/ux-sim/service-key-setup.ts +50 -0
  531. package/src/ux-sim/term-slash-device.ts +74 -0
  532. package/src/ux-sim/turn-throw-sim.ts +31 -0
  533. package/src/version/packed-revision.json +1 -1
  534. package/src/web-search/exa.ts +77 -0
  535. package/src/web-search/index.ts +30 -9
  536. package/src/web-search/provider.ts +4 -1
  537. package/src/web-search/x-intent.ts +5 -0
  538. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +0 -36
  540. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +0 -32
  543. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +0 -286
  548. package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +0 -23
  549. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +0 -34
  552. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/2974.595d1e29d040cb6a.js +0 -64
  557. package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +0 -93
  558. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +0 -41
  559. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +0 -24
  561. package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +0 -77
  567. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +0 -74
  572. package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +0 -149
  573. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +0 -27
  575. package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +0 -287
  583. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +0 -226
  586. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +0 -90
  587. package/apps/pwa/out/_next/static/chunks/6377.bc7df239edbff244.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +0 -104
  594. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +0 -94
  595. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +0 -24
  602. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +0 -8
  610. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/8546-6f03f8ea34dd61d9.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/9249.976f1e69a9d80754.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/9415.69e4a21c60c7d2db.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +0 -62
  626. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +0 -1
  684. package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
  685. /package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → Om5xS9jpjSXJCeTNGYEi4}/_ssgManifest.js +0 -0
@@ -27,6 +27,16 @@ import { debug, redactSecretText, withAmbientSessionScope } from '../debug/log.j
27
27
  import { applyDeferredTools } from '../session-runtime/tier-flip.js';
28
28
  import { isResearchAgentIntent } from '../tool-hints/signals.js';
29
29
  import { buildResearchDateSystemMessage, resolveSessionSurfaceProfile } from '../session-runtime/index.js';
30
+ import {
31
+ isResearchToolAllowed,
32
+ RESEARCH_DOCUMENT_WRITE_TOOLS,
33
+ requestsResearchDocumentWrite,
34
+ RESEARCH_TOOL_ALLOWLIST,
35
+ RESEARCH_TURN_DEEP_BUDGET_MS,
36
+ RESEARCH_TURN_DEADLINE_STOP_ERROR,
37
+ RESEARCH_TURN_FIRST_REPLY_BUDGET_MS,
38
+ RESEARCH_TURN_MAX_TOOL_TURNS,
39
+ } from './research-policy.js';
30
40
  import type {
31
41
  CoreTurnContext,
32
42
  CoreTurnResult,
@@ -35,6 +45,14 @@ import type {
35
45
 
36
46
  const CORE_TURN_TOOL_RESULT_INLINE_LIMIT_BYTES = 50 * 1024;
37
47
 
48
+ // A deep, non-research prompt gets the same-call Bloom frame, but should not
49
+ // silently grow into multi-source research just because the model can reach
50
+ // generic skill/search tools. Explicit research turns and explicit named-skill
51
+ // requests keep the normal tool surface.
52
+ const DEEP_NON_RESEARCH_SEARCH_TOOLS = new Set([
53
+ 'skill_exec', 'elanous_skills_list', 'websearch', 'web_search', 'omnisearch', 'omni_search', 'webfetch', 'web_fetch',
54
+ ]);
55
+
38
56
  /** Classify an error thrown out of `streamLLMWithTools` into the
39
57
  * Core-turn stop-reason set. Abort wins over everything else;
40
58
  * credential rejection (`isAuthRejectionError`) is distinct from a
@@ -82,8 +100,31 @@ function selectSurfaceUserText(ctx: CoreTurnContext): string | undefined {
82
100
  * the research turn's text-only provisional answer. That provisional pass
83
101
  * has no tools by design and otherwise tells the user the requested skill
84
102
  * cannot be invoked, even when the skill router already resolved it. */
85
- function requestsNamedSkill(text: string | undefined): boolean {
103
+ function requestedInstalledSkillName(text: string | undefined, installedSkillNames: readonly string[]): string | undefined {
104
+ if (!text) return undefined;
105
+ return installedSkillNames
106
+ .filter((name) => name.includes('-'))
107
+ .sort((a, b) => b.length - a.length)
108
+ .find((name) => {
109
+ const parts = name.trim().split(/[-\s]+/).filter(Boolean);
110
+ if (parts.length < 2 || !parts.every((part) => /^[a-z0-9]+$/i.test(part))) return false;
111
+ const slug = parts.join('[\\s-]*');
112
+ return new RegExp('(?:^|[^\\p{L}\\p{N}])' + slug + '(?=$|[^a-z0-9])\\s*(?:으로|로)(?=[^\\n!?]{0,120}(?:찾아|조사|정리))', 'iu').test(text);
113
+ });
114
+ }
115
+
116
+ export function requestsNamedSkill(text: string | undefined, installedSkillNames: readonly string[] = []): boolean {
86
117
  if (!text) return false;
118
+ const requestedInstalledSkill = installedSkillNames
119
+ .filter((name) => name.includes('-'))
120
+ .sort((a, b) => b.length - a.length)
121
+ .some((name) => {
122
+ const parts = name.trim().split(/[-\s]+/).filter(Boolean);
123
+ if (parts.length < 2 || !parts.every((part) => /^[a-z0-9]+$/i.test(part))) return false;
124
+ const slug = parts.join('[\\s-]*');
125
+ return new RegExp('(?:^|[^\\p{L}\\p{N}])' + slug + '(?=$|[^a-z0-9])\\s*(?:으로|로)(?=[^\\n!?]{0,120}(?:찾아|조사|정리))', 'iu').test(text);
126
+ });
127
+ if (requestedInstalledSkill) return true;
87
128
  const action = '(?:use|invoke|run|call|execute|launch|trigger|apply|start)';
88
129
  return new RegExp(`\\b${action}\\s+(?:(?:the|a|an)\\s+)?skill\\s+(?:named|called)\\s+['"“‘]([a-z0-9][a-z0-9 _-]{1,60}?)['"”’](?=$|[\\s.,;!?])`, 'i').test(text)
89
130
  || new RegExp(`\\b${action}\\s+(?:the\\s+)?['"“‘]([a-z0-9][a-z0-9 _-]{1,60}?)['"”’](?=$|[\\s.,;!?])`, 'i').test(text)
@@ -119,9 +160,14 @@ function requestsNamedSkill(text: string | undefined): boolean {
119
160
  */
120
161
  export interface RunCoreTurnOptions {
121
162
  now?: () => number;
122
- runResearch?: (request: string, signal: AbortSignal) => Promise<{ ok: boolean; output: string; error?: string }>;
163
+ timers?: { setTimeout(callback: () => void, delayMs: number): ReturnType<typeof setTimeout>; clearTimeout(handle: ReturnType<typeof setTimeout>): void };
164
+ firstReplyBudgetMs?: number;
165
+ researchWallClockBudgetMs?: number;
166
+ runResearch?: (request: string, signal: AbortSignal, admitToolCall?: (name: string) => boolean) => Promise<{ ok: boolean; output: string; error?: string }>;
123
167
  }
124
168
 
169
+ type ResearchTimer = ReturnType<typeof setTimeout>;
170
+
125
171
  type AbortRace<T> = { aborted: true } | { aborted: false; value: T };
126
172
 
127
173
  function settleBeforeAbort<T>(work: Promise<T>, signal: AbortSignal): Promise<AbortRace<T>> {
@@ -191,6 +237,10 @@ export async function runCoreTurn(
191
237
  options: RunCoreTurnOptions = {},
192
238
  ): Promise<CoreTurnResult> {
193
239
  const now = options.now ?? Date.now;
240
+ const timers = options.timers ?? {
241
+ setTimeout: (callback: () => void, delayMs: number) => setTimeout(callback, delayMs),
242
+ clearTimeout: (handle: ReturnType<typeof setTimeout>) => clearTimeout(handle),
243
+ };
194
244
  let turnStartedAt: number | undefined;
195
245
  let researchStartedAt: number | undefined;
196
246
  let researchFirstTokenRecorded = false;
@@ -214,6 +264,55 @@ export async function runCoreTurn(
214
264
  let accumulatedText = '';
215
265
  let dispatchCount = 0;
216
266
  let finalPhaseAnswer = false;
267
+ let enforceResearchToolAllowlist = false;
268
+ let enforceResearchDocumentWrite = false;
269
+ const isAllowedResearchTool = (name: string): boolean => isResearchToolAllowed(name)
270
+ || (enforceResearchDocumentWrite && (RESEARCH_DOCUMENT_WRITE_TOOLS as readonly string[]).includes(name));
271
+ let enforceResearchToolBudget = false;
272
+ let researchToolCallCount = 0;
273
+ let researchStopReason: string | undefined;
274
+ const loggedResearchStops = new Set<string>();
275
+ const logResearchStop = (reason: string, extra: Record<string, unknown> = {}): void => {
276
+ if (loggedResearchStops.has(reason)) return;
277
+ loggedResearchStops.add(reason);
278
+ debug.log('research.stop', 'stopped', { sessionId: ctx.sessionId, reason, ...extra });
279
+ };
280
+ const admitResearchToolCall = (name: string): boolean => {
281
+ if (!enforceResearchToolBudget) return true;
282
+ if (researchToolCallCount >= RESEARCH_TURN_MAX_TOOL_TURNS) {
283
+ // A prior denied tool is observable, but it must not mask the hard
284
+ // budget stop that requires tool-free synthesis. A wall-clock stop is
285
+ // already terminal and keeps its more specific reason.
286
+ if (researchStopReason !== 'wall-clock-budget') researchStopReason = 'tool-budget';
287
+ logResearchStop('tool-budget', { stage: 'tool-dispatch', tool: name, count: researchToolCallCount, limit: RESEARCH_TURN_MAX_TOOL_TURNS });
288
+ return false;
289
+ }
290
+ researchToolCallCount += 1;
291
+ return true;
292
+ };
293
+ const constrainResearchToolArgs = (name: string, args: Record<string, unknown>): Record<string, unknown> => {
294
+ if (!enforceResearchToolAllowlist || name !== 'Agent' || !args || typeof args !== 'object' || Array.isArray(args)) return args;
295
+ const raw = args;
296
+ const rawFilter = raw.tool_filter && typeof raw.tool_filter === 'object' && !Array.isArray(raw.tool_filter)
297
+ ? raw.tool_filter as { deny?: unknown }
298
+ : {};
299
+ const deny = Array.isArray(rawFilter.deny) ? rawFilter.deny.filter((tool): tool is string => typeof tool === 'string') : [];
300
+ return {
301
+ ...raw,
302
+ subagent_type: typeof raw.subagent_type === 'string' && raw.subagent_type.trim()
303
+ ? raw.subagent_type
304
+ : 'general-purpose',
305
+ run_in_background: false,
306
+ wait_for_slot: false,
307
+ max_turns: typeof raw.max_turns === 'number' && Number.isFinite(raw.max_turns)
308
+ ? Math.max(1, Math.min(RESEARCH_TURN_MAX_TOOL_TURNS, Math.floor(raw.max_turns)))
309
+ : RESEARCH_TURN_MAX_TOOL_TURNS,
310
+ tool_filter: {
311
+ allow: ['Read', 'WebFetch'],
312
+ deny: [...new Set([...deny, 'Bash', 'Edit', 'Grep'])],
313
+ },
314
+ };
315
+ };
217
316
 
218
317
  const handlers: StreamWithToolsHandlers = {
219
318
  onText: (delta, full) => {
@@ -254,9 +353,28 @@ export async function runCoreTurn(
254
353
 
255
354
  let success = false;
256
355
  try {
257
- const result = await ctx.dispatchTool(
258
- name,
259
- args,
356
+ let result: unknown;
357
+ if (enforceResearchToolAllowlist && !isAllowedResearchTool(name)) {
358
+ researchStopReason ??= 'tool-not-allowed';
359
+ logResearchStop('tool-not-allowed', { stage: 'tool-dispatch', tool: name, allowedTools: [...RESEARCH_TOOL_ALLOWLIST, ...(enforceResearchDocumentWrite ? ['Edit', 'Write'] : [])] });
360
+ debug.log('core.turn', 'research-tool-denied', {
361
+ sessionId: ctx.sessionId,
362
+ tool: name,
363
+ dispatchCount: currentDispatchCount,
364
+ }, { level: 'warn' });
365
+ result = { error: enforceResearchDocumentWrite
366
+ ? 'This research turn may use research tools and Edit/Write only for the explicitly requested document.'
367
+ : 'This research turn may only use the research tool allowlist.' };
368
+ } else if (enforceResearchToolAllowlist && !admitResearchToolCall(name)) {
369
+ debug.log('core.turn', 'research-tool-budget-reached', {
370
+ sessionId: ctx.sessionId, tool: name, count: researchToolCallCount,
371
+ maxToolTurns: RESEARCH_TURN_MAX_TOOL_TURNS,
372
+ }, { level: 'warn' });
373
+ result = { error: 'Research tool budget reached. Answer with the evidence collected so far.' };
374
+ } else {
375
+ result = await ctx.dispatchTool(
376
+ name,
377
+ constrainResearchToolArgs(name, args),
260
378
  // Image-pipeline followup #1 (2026-05-05) — forward sessionId so
261
379
  // the dispatcher can auto-inject into session-keyed tool calls
262
380
  // (WebTerminal* etc.) when the LLM didn't supply one. `c` may
@@ -269,7 +387,8 @@ export async function runCoreTurn(
269
387
  c
270
388
  ? { ...c, sessionId: ctx.sessionId, signal: ctx.signal, ...(ctx.userText ? { userText: ctx.userText } : {}) }
271
389
  : { callId: '', sessionId: ctx.sessionId, signal: ctx.signal, ...(ctx.userText ? { userText: ctx.userText } : {}) },
272
- );
390
+ );
391
+ }
273
392
  success = true;
274
393
  return result;
275
394
  } finally {
@@ -344,20 +463,105 @@ export async function runCoreTurn(
344
463
  // Use the shared #31663 research-intent verdict. Surface labels are a
345
464
  // presentation/routing result and may remain `chat` for a research turn.
346
465
  const researchTurn = isResearchAgentIntent(surfaceUserText);
347
- const { messages, tools, stats } = applyDeferredTools(
466
+ const { selectDeepBloom } = await import('./deep-turn-bloom.js');
467
+ const deepBloomDecision = selectDeepBloom(surfaceUserText, {
468
+ researchIntent: researchTurn,
469
+ reasoningEffort: ctx.reasoningEffort,
470
+ });
471
+ const { messages, tools: tieredTools, stats } = applyDeferredTools(
348
472
  ctx.messages,
349
473
  ctx.tools,
350
474
  { enabled: deferredEnabled, ...(recentUserText ? { userText: recentUserText } : {}) },
351
475
  );
476
+ // Preserve the pre-routing contract: a named skill only skips the research
477
+ // prepass when skill_exec is actually active after the normal tier split.
478
+ let explicitSkillToolRequest = requestsNamedSkill(surfaceUserText)
479
+ && tieredTools.some((tool) => tool.name === 'skill_exec');
480
+ if (!explicitSkillToolRequest && researchTurn && surfaceUserText?.trim()
481
+ && tieredTools.some((tool) => tool.name === 'skill_exec')) {
482
+ // Korean named-skill requests need the installed index to recognize the
483
+ // skill slug before the research allowlist filters the normal tool loop.
484
+ const { getSkillIndex } = await import('../skills/index.js');
485
+ explicitSkillToolRequest = requestsNamedSkill(surfaceUserText, getSkillIndex().map(({ name }) => name));
486
+ }
487
+ const constrainDeepNonResearchTools = deepBloomDecision.apply && !researchTurn;
488
+ // ToolSearch routes against the surface's full live pool, so hiding a tool
489
+ // from the model alone is insufficient. Remove the summoner from the
490
+ // model-visible tiered set while retaining original split stats/messages.
491
+ const bloomFilteredTools = constrainDeepNonResearchTools
492
+ ? tieredTools.filter((tool) => {
493
+ const name = tool.name.toLowerCase();
494
+ return name === 'skill_exec' && explicitSkillToolRequest
495
+ ? true
496
+ : name !== 'toolsearch' && !DEEP_NON_RESEARCH_SEARCH_TOOLS.has(name);
497
+ })
498
+ : tieredTools;
499
+ if (constrainDeepNonResearchTools) {
500
+ const suppressed = tieredTools.filter((tool) => !bloomFilteredTools.includes(tool)).map((tool) => tool.name);
501
+ debug.log('research.turn', 'deep-bloom-search-tools-suppressed', {
502
+ sessionId: ctx.sessionId, reason: deepBloomDecision.reason, suppressed,
503
+ explicitSkillToolRequest,
504
+ });
505
+ }
506
+ enforceResearchToolBudget = researchTurn;
507
+ enforceResearchToolAllowlist = researchTurn && !explicitSkillToolRequest;
508
+ enforceResearchDocumentWrite = enforceResearchToolAllowlist && requestsResearchDocumentWrite(surfaceUserText);
509
+ const tools = enforceResearchToolAllowlist
510
+ ? bloomFilteredTools.filter((tool) => isAllowedResearchTool(tool.name))
511
+ : bloomFilteredTools;
512
+ const maxToolTurns = researchTurn
513
+ ? Math.min(ctx.maxToolTurns ?? RESEARCH_TURN_MAX_TOOL_TURNS, RESEARCH_TURN_MAX_TOOL_TURNS)
514
+ : ctx.maxToolTurns;
352
515
  if (researchTurn && !messages.some((message) =>
353
516
  message.role === 'system' && typeof message.content === 'string'
354
517
  && message.content.startsWith('Current local date:'))
355
518
  ) {
356
519
  messages.unshift(buildResearchDateSystemMessage());
520
+ }
521
+ if (researchTurn) {
522
+ messages.unshift({
523
+ role: 'system',
524
+ content: [
525
+ '<research-answer-guidance>',
526
+ '작은 후속 작업은 추가 질문 없이 현재 턴에서 먼저 처리한다.',
527
+ '답은 결론(무엇을 찾았고 무엇을 해 두었는지)을 먼저 말하고, 근거를 짧게 덧붙인다.',
528
+ '비용·외부 노출·되돌리기 어려움이 큰 다음 단계만 그 하나를 확인한다. 그 밖에는 묻지 않는다.',
529
+ '다음 할 일 목록을 형식으로 요구하지 않는다.',
530
+ '본문은 질문이 요구한 범위만 답하고, 가정 나열과 반복 설명을 줄인다.',
531
+ '근거는 출처 링크로 짧게 붙인다.',
532
+ '질문에 필요한 만큼 읽기 좋게 설명하며, 고정 줄 수나 글자 수로 자르지 않는다.',
533
+ '</research-answer-guidance>',
534
+ ].join('\n'),
535
+ });
536
+ }
537
+ if (deepBloomDecision.apply) {
538
+ const { buildDeepBloomInstruction } = await import('./deep-turn-bloom.js');
539
+ const instruction = await buildDeepBloomInstruction(surfaceUserText ?? '', deepBloomDecision.reason);
540
+ messages.unshift({ role: 'system', content: instruction.prompt! });
541
+ debug.log('research.turn', 'deep-bloom-applied', {
542
+ sessionId: ctx.sessionId, levels: instruction.levels, trigger: instruction.reason,
543
+ questionCount: instruction.questionCount, stage: researchTurn ? 'first-answer' : 'answer',
544
+ exemplarDomain: instruction.exemplarDomain,
545
+ exemplarLevels: instruction.exemplarLevels,
546
+ });
547
+ } else if (!deepBloomDecision.apply) {
548
+ debug.log('research.turn', 'deep-bloom-skipped', {
549
+ sessionId: ctx.sessionId, reason: deepBloomDecision.reason,
550
+ });
357
551
  }
358
552
  let researchResultPromise: Promise<{ ok: boolean; output: string; error?: string } | null> | undefined;
359
- const explicitSkillToolRequest = requestsNamedSkill(surfaceUserText)
360
- && tools.some((tool) => tool.name === 'skill_exec');
553
+ let requestedSkillName: string | undefined;
554
+ if (researchTurn && surfaceUserText?.trim() && explicitSkillToolRequest) {
555
+ // Resolve a display name only for the research opening plan; ordinary
556
+ // turns and unrequested research keep the core startup lean.
557
+ const { getSkillIndex } = await import('../skills/index.js');
558
+ const skillNames = getSkillIndex().map(({ name }) => name);
559
+ requestedSkillName = requestedInstalledSkillName(surfaceUserText, skillNames);
560
+ }
561
+ if (researchTurn && surfaceUserText?.trim()) {
562
+ const plan = (requestedSkillName ?? '검색 도구') + '로 요청한 주제의 근거를 찾습니다.\n질문 범위에 맞춰 결론과 근거를 정리합니다.';
563
+ try { ctx.callbacks?.onStatus?.(plan); } catch { /* UI feedback is fail-soft. */ }
564
+ }
361
565
  if (researchTurn && surfaceUserText?.trim() && !explicitSkillToolRequest) {
362
566
  turnStartedAt = now();
363
567
  researchStartedAt = turnStartedAt;
@@ -365,17 +569,48 @@ export async function runCoreTurn(
365
569
  sessionId: ctx.sessionId,
366
570
  sinceTurnStartMs: researchStartedAt - turnStartedAt,
367
571
  });
368
- // Start evidence collection beside the first answer. The user gets an
369
- // immediate, visible status and an initial answer while research runs;
370
- // a second text-only synthesis then reconciles that answer with evidence.
371
- try { ctx.callbacks?.onStatus?.('먼저 답변을 시작하고 근거를 확인합니다.'); } catch { /* UI feedback is fail-soft. */ }
572
+ // The opening plan was already emitted above. Do not add a generic
573
+ // answer-first status that contradicts that plan; stream the provisional
574
+ // answer while evidence collection runs, then reconcile in the second pass.
575
+ const researchController = new AbortController();
576
+ const abortResearchFromParent = (): void => {
577
+ if (researchStopReason !== 'wall-clock-budget') researchStopReason = 'parent-abort';
578
+ researchController.abort(ctx.signal.reason);
579
+ };
580
+ if (ctx.signal.aborted) abortResearchFromParent();
581
+ else ctx.signal.addEventListener('abort', abortResearchFromParent, { once: true });
582
+ const researchWallClockBudgetMs = options.researchWallClockBudgetMs ?? RESEARCH_TURN_DEEP_BUDGET_MS;
583
+ let researchDeadlineTimer: ResearchTimer | undefined;
584
+ if (!researchController.signal.aborted) {
585
+ researchDeadlineTimer = timers.setTimeout(() => {
586
+ if (researchController.signal.aborted) return;
587
+ researchStopReason = 'wall-clock-budget';
588
+ logResearchStop('wall-clock-budget', {
589
+ stage: 'research-prepass',
590
+ elapsedMs: researchStartedAt === undefined ? undefined : now() - researchStartedAt,
591
+ limitMs: researchWallClockBudgetMs,
592
+ });
593
+ researchController.abort(new Error('Research wall-clock budget reached'));
594
+ }, researchWallClockBudgetMs);
595
+ }
372
596
  researchResultPromise = (async () => {
373
597
  try {
374
- const result = await (options.runResearch ?? (async (request, signal) => {
598
+ const work = (options.runResearch ?? (async (request, signal, admitToolCall) => {
375
599
  // Keep the Bloom/skill pipeline out of ordinary and packaged TUI startup graphs.
376
600
  const { researchTurnForGrounding, runResearchQuestionLadder } = await import('../auto-research/research-turn.js');
377
- return researchTurnForGrounding(await runResearchQuestionLadder(request, { signal }));
378
- }))(surfaceUserText, ctx.signal);
601
+ return researchTurnForGrounding(await runResearchQuestionLadder(request, {
602
+ signal, admitToolCall, allowPartialOnAbort: true, allowOutputSkill: false,
603
+ }));
604
+ }))(surfaceUserText, researchController.signal, admitResearchToolCall);
605
+ const result = await work;
606
+ if (researchController.signal.aborted && !researchStopReason) researchStopReason = ctx.signal.aborted ? 'parent-abort' : 'research-aborted';
607
+ if (researchStopReason) logResearchStop(researchStopReason, {
608
+ stage: 'research-prepass',
609
+ elapsedMs: researchStartedAt === undefined ? undefined : now() - researchStartedAt,
610
+ });
611
+ logResearchStop(result.ok ? 'evidence-complete' : 'evidence-incomplete', {
612
+ stage: 'research-prepass', outputChars: result.output.length,
613
+ });
379
614
  debug.log('research.turn', 'tui-research-completed', {
380
615
  sessionId: ctx.sessionId,
381
616
  ok: result.ok,
@@ -385,23 +620,29 @@ export async function runCoreTurn(
385
620
  });
386
621
  return result;
387
622
  } catch (error) {
623
+ logResearchStop('research-error', { stage: 'research-prepass', error: error instanceof Error ? error.message : String(error) });
388
624
  debug.log('research.turn', 'tui-research-fallback', {
389
625
  sessionId: ctx.sessionId,
390
626
  reason: error instanceof Error ? error.message : String(error),
391
627
  elapsedMs: researchStartedAt === undefined ? undefined : now() - researchStartedAt,
392
628
  }, { level: 'warn' });
393
629
  return null;
630
+ } finally {
631
+ if (researchDeadlineTimer !== undefined) timers.clearTimeout(researchDeadlineTimer);
632
+ ctx.signal.removeEventListener('abort', abortResearchFromParent);
394
633
  }
395
634
  })();
396
635
  }
397
- const streamOptions = (turnTools: typeof tools) => ({
636
+ const streamOptions = (turnTools: typeof tools, signal: AbortSignal = ctx.signal) => ({
398
637
  tools: turnTools,
399
638
  researchTurn,
400
- signal: ctx.signal,
639
+ ...(explicitSkillToolRequest ? { toolChoice: { name: 'skill_exec' } } : {}),
640
+ signal,
401
641
  ...(ctx.requestSizeGuard ? { requestSizeGuard: ctx.requestSizeGuard } : {}),
642
+ ...(ctx.reasoningEffort !== undefined ? { reasoningEffort: ctx.reasoningEffort } : {}),
402
643
  toolResultInlineLimitBytes: CORE_TURN_TOOL_RESULT_INLINE_LIMIT_BYTES,
403
644
  ...(ctx.sessionId !== undefined ? { sessionId: ctx.sessionId } : {}),
404
- ...(ctx.maxToolTurns !== undefined ? { maxTurns: ctx.maxToolTurns } : {}),
645
+ ...(maxToolTurns !== undefined ? { maxTurns: maxToolTurns } : {}),
405
646
  ...(ctx.initialProvider !== undefined
406
647
  ? { initialProvider: ctx.initialProvider, ...(ctx.skipProviders ? { skipProviders: ctx.skipProviders } : {}) }
407
648
  : ctx.modelOverride !== undefined ? { model: ctx.modelOverride } : {}),
@@ -431,7 +672,7 @@ export async function runCoreTurn(
431
672
  surfaceSelectionReason: surface.selectionReason,
432
673
  activeCount: stats.activeCount,
433
674
  deferredCount: stats.deferredCount,
434
- immediateCount: stats.activeCount,
675
+ immediateCount: tools.length,
435
676
  immediate: tools.map((tool) => tool.name),
436
677
  warmPreloaded: stats.warmPreloaded,
437
678
  deferred: stats.deferredNames,
@@ -447,8 +688,13 @@ export async function runCoreTurn(
447
688
 
448
689
  try {
449
690
  let provisionalTurnMessages: Parameters<NonNullable<StreamWithToolsHandlers['onTurnComplete']>>[0] | undefined;
450
- const firstPassHandlers: StreamWithToolsHandlers = researchResultPromise && handlers.onTurnComplete
451
- ? { ...handlers, onTurnComplete: (newMessages) => { provisionalTurnMessages = newMessages; } }
691
+ let firstPassTimedOut = false;
692
+ const firstPassHandlers: StreamWithToolsHandlers = researchResultPromise
693
+ ? {
694
+ ...handlers,
695
+ onText: (delta, full) => { if (!firstPassTimedOut) handlers.onText?.(delta, full); },
696
+ onTurnComplete: (newMessages) => { if (!firstPassTimedOut) provisionalTurnMessages = newMessages; },
697
+ }
452
698
  : handlers;
453
699
  const firstPassMessages = researchResultPromise
454
700
  ? [...messages, {
@@ -457,7 +703,38 @@ export async function runCoreTurn(
457
703
  }]
458
704
  : messages;
459
705
  const firstPassStartedAt = researchResultPromise ? now() : undefined;
460
- finalText = await streamLLMWithTools(firstPassMessages, firstPassHandlers, streamOptions(researchResultPromise ? [] : tools));
706
+ if (researchResultPromise && firstPassStartedAt !== undefined) {
707
+ const firstPassController = new AbortController();
708
+ const abortFirstPassFromParent = (): void => firstPassController.abort(ctx.signal.reason);
709
+ if (ctx.signal.aborted) abortFirstPassFromParent();
710
+ else ctx.signal.addEventListener('abort', abortFirstPassFromParent, { once: true });
711
+ const firstReplyBudgetMs = options.firstReplyBudgetMs ?? RESEARCH_TURN_FIRST_REPLY_BUDGET_MS;
712
+ let firstReplyTimer: ResearchTimer | undefined;
713
+ const deadline = new Promise<{ timedOut: true }>(resolve => {
714
+ firstReplyTimer = timers.setTimeout(() => resolve({ timedOut: true }), firstReplyBudgetMs);
715
+ });
716
+ try {
717
+ const firstPass = streamLLMWithTools(firstPassMessages, firstPassHandlers, streamOptions([], firstPassController.signal))
718
+ .then(text => ({ timedOut: false as const, text }));
719
+ const outcome = await Promise.race([firstPass, deadline]);
720
+ if (outcome.timedOut) {
721
+ firstPassTimedOut = true;
722
+ firstPassController.abort(new Error('First answer budget reached'));
723
+ logResearchStop('first-reply-budget', { stage: 'first-response', limitMs: firstReplyBudgetMs, elapsedMs: now() - firstPassStartedAt });
724
+ const partial = accumulatedText.trim();
725
+ finalText = partial || '질문을 확인하고 있습니다. 근거를 조사한 뒤 제한 시간 안에 답을 정리하겠습니다.';
726
+ if (!partial) handlers.onText?.(finalText, finalText);
727
+ provisionalTurnMessages = [{ role: 'assistant', content: finalText, phase: 'final_answer' }];
728
+ } else {
729
+ finalText = outcome.text;
730
+ }
731
+ } finally {
732
+ if (firstReplyTimer !== undefined) timers.clearTimeout(firstReplyTimer);
733
+ ctx.signal.removeEventListener('abort', abortFirstPassFromParent);
734
+ }
735
+ } else {
736
+ finalText = await streamLLMWithTools(firstPassMessages, firstPassHandlers, streamOptions(tools));
737
+ }
461
738
  if (researchResultPromise && firstPassStartedAt !== undefined) {
462
739
  debug.log('research.turn', 'first-pass-answer-ready', {
463
740
  sessionId: ctx.sessionId,
@@ -478,7 +755,14 @@ export async function runCoreTurn(
478
755
  commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
479
756
  return { stopReason: 'aborted', finalText };
480
757
  }
481
- if (result?.ok && result.output.trim() && !ctx.signal.aborted) {
758
+ const forcedSynthesis = researchStopReason === 'wall-clock-budget' || researchStopReason === 'tool-budget';
759
+ const hasUsableResearch = Boolean(result?.output.trim())
760
+ && (result?.ok === true || result?.error === RESEARCH_TURN_DEADLINE_STOP_ERROR);
761
+ if (forcedSynthesis) {
762
+ logResearchStop('forced-synthesis', { stage: 'synthesis', trigger: researchStopReason, toolCalls: researchToolCallCount });
763
+ try { ctx.callbacks?.onStatus?.('조사 한도에 도달해 확인된 근거만으로 답을 정리합니다.'); } catch { /* UI feedback is fail-soft. */ }
764
+ }
765
+ if (hasUsableResearch && result && !ctx.signal.aborted) {
482
766
  try { ctx.callbacks?.onStatus?.('근거를 반영해 답변을 보강합니다.'); } catch { /* UI feedback is fail-soft. */ }
483
767
  const synthesisStartedAt = now();
484
768
  debug.log('research.turn', 'synthesis-started', {
@@ -492,9 +776,11 @@ export async function runCoreTurn(
492
776
  messages.push(
493
777
  { role: 'assistant', content: provisionalText.trim() },
494
778
  { role: 'system', content: `<bloom-research>\n${result.output.trim()}\n</bloom-research>` },
495
- { role: 'system', content: 'Revise the answer above using this research evidence. Correct any unsupported or contradicted claims, preserve uncertainty, and answer in natural prose. Do not output JSON or a tool transcript. If the evidence does not materially change the answer, state the answer directly.' },
779
+ { role: 'system', content: forcedSynthesis
780
+ ? 'The research budget has ended. Synthesize now using only the partial evidence above. State uncertainty and gaps clearly. Do not call tools or continue research.'
781
+ : 'Revise the answer above using this research evidence. Correct any unsupported or contradicted claims, preserve uncertainty, and answer in natural prose. Do not output JSON or a tool transcript. If the evidence does not materially change the answer, state the answer directly.' },
496
782
  );
497
- const synthesisTools = tools.filter(tool => !['WebSearch', 'OmniSearch'].includes(tool.name));
783
+ const synthesisTools = forcedSynthesis ? [] : tools.filter(tool => !['WebSearch', 'OmniSearch'].includes(tool.name));
498
784
  try {
499
785
  const synthesizedText = await streamLLMWithTools(messages, staged.handlers, streamOptions(synthesisTools));
500
786
  if (ctx.signal.aborted) {
@@ -509,6 +795,7 @@ export async function runCoreTurn(
509
795
  sinceTurnStartMs: turnStartedAt === undefined ? undefined : now() - turnStartedAt,
510
796
  outputChars: finalText.length,
511
797
  });
798
+ logResearchStop('synthesis-complete', { stage: 'synthesis', outputChars: finalText.length });
512
799
  if (staged.completion()) {
513
800
  commitStagedTurn(staged.completion(), handlers, finalText, finalText !== provisionalText,
514
801
  value => { finalPhaseAnswer = value; }, ctx.callbacks?.onReplaceText);
@@ -529,15 +816,18 @@ export async function runCoreTurn(
529
816
  try { ctx.callbacks?.onStatus?.('근거 반영에 실패해 첫 답변을 유지합니다.'); } catch { /* UI feedback is fail-soft. */ }
530
817
  return { stopReason: 'end_turn', finalText: provisionalText, ...(handlers.onTurnComplete ? { finalPhaseAnswer } : {}) };
531
818
  }
532
- } else if (tools.some(tool => !['WebSearch', 'OmniSearch'].includes(tool.name))) {
533
- try { ctx.callbacks?.onStatus?.('근거 검색은 실패해 사용할 수 있는 도구로 답변을 마무리합니다.'); } catch { /* UI feedback is fail-soft. */ }
819
+ } else if (forcedSynthesis || tools.some(tool => !['WebSearch', 'OmniSearch'].includes(tool.name))) {
820
+ try { ctx.callbacks?.onStatus?.(forcedSynthesis ? '조사 한도에 도달해 첫 답변을 근거 없이 확장하지 않고 마무리합니다.' : '근거 검색은 실패해 사용할 수 있는 도구로 답변을 마무리합니다.'); } catch { /* UI feedback is fail-soft. */ }
534
821
  const provisionalText = finalText;
535
822
  const staged = createStagedHandlers(handlers);
536
823
  messages.push(
537
824
  { role: 'assistant', content: provisionalText.trim() },
538
- { role: 'system', content: 'Research evidence was unavailable. Continue answering the user using available non-search tools as needed. Do not invoke web search.' },
825
+ ...(result?.output.trim() ? [{ role: 'system' as const, content: `<partial-research>\n${result.output.trim()}\n</partial-research>` }] : []),
826
+ { role: 'system', content: forcedSynthesis
827
+ ? 'The research budget has ended. Synthesize now without tools. Use any partial evidence above and clearly state uncertainty; do not continue research.'
828
+ : 'Research evidence was unavailable. Continue answering the user using available non-search tools as needed. Do not invoke web search.' },
539
829
  );
540
- const fallbackTools = tools.filter(tool => !['WebSearch', 'OmniSearch'].includes(tool.name));
830
+ const fallbackTools = forcedSynthesis ? [] : tools.filter(tool => !['WebSearch', 'OmniSearch'].includes(tool.name));
541
831
  try {
542
832
  const fallbackText = await streamLLMWithTools(messages, staged.handlers, streamOptions(fallbackTools));
543
833
  if (ctx.signal.aborted) {
@@ -149,6 +149,8 @@ export interface CoreTurnContext {
149
149
  /** Optional provider request-size hook. Only providers with a measured
150
150
  * serializer consume it; all others retain their existing request path. */
151
151
  requestSizeGuard?: LLMOpts['requestSizeGuard'];
152
+ /** Optional per-turn reasoning effort; high/xhigh/max also opts into the default deep Bloom frame. */
153
+ reasoningEffort?: LLMOpts['reasoningEffort'];
152
154
  /** Tool catalog the model may call this turn. Empty array means
153
155
  * "text-only" — the loop delegates to plain `streamLLM`. */
154
156
  tools: LLMToolSpec[];
@@ -89,6 +89,8 @@ export interface AcpChatHandlers {
89
89
  /** Append streamed assistant text. Caller accumulates + redraws.
90
90
  * Receives each chunk exactly as the ACP agent emits it. */
91
91
  appendChunk: (delta: string) => void;
92
+ /** Replace the current streamed assistant answer with its authoritative final text. */
93
+ replaceText?: (fullText: string) => void;
92
94
  /** A goal iteration ended; fold only that interim reply in the visible pane. */
93
95
  foldGoalInterim?: (text: string) => void;
94
96
  /** Called once per tool_call event with a rendered label like
@@ -441,6 +443,14 @@ export class DashboardAcpChat {
441
443
  }
442
444
  const c = update.content;
443
445
  if (c.type === 'text') {
446
+ const meta = (update as typeof update & { _meta?: { elanous?: { textOperation?: unknown } } })._meta;
447
+ if (meta?.elanous?.textOperation === 'replace') {
448
+ this.closeStreamBuffer(sess, 'flush');
449
+ if (handlers.replaceText) handlers.replaceText(c.text);
450
+ else handlers.appendChunk(c.text);
451
+ handlers.redraw?.();
452
+ return;
453
+ }
444
454
  this.routeText(sess, c.text, handlers);
445
455
  }
446
456
  return;