elanous 0.2.37 → 0.2.38

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 (588) 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/{8kITumG9GAZ1LwT9POrAR → RrjXTwz-urRAbChP1bX02}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{2002-a43a3f380df873ec.js → 1026-44010f405704050c.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +27 -0
  6. package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{7424.c0fe2a595d4232b5.js → 1632.7d87f998e714bede.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/{4937-28d437999b77c9dd.js → 1923-5c1695332240246a.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/1938.0e6c60ee91c4d7f5.js +148 -0
  14. package/apps/pwa/out/_next/static/chunks/2104.70e086d5174a4736.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/214.186a430da28338f1.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +93 -0
  18. package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +104 -0
  19. package/apps/pwa/out/_next/static/chunks/{3199.6a1a9b0e6cd01dc6.js → 2415.738b777642a02233.js} +1 -1
  20. package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/{1262.a89bb27a5b2f844e.js → 3086.fb14b60ce98b53d3.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/3124-561f7f037943cde2.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +24 -0
  31. package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{2283.edd9627b7bdfb546.js → 3291.f6c1005387d514bd.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +36 -0
  34. package/apps/pwa/out/_next/static/chunks/{6877-84d47b7e85d0c41e.js → 3341-f09b9efbd7a82f70.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/3389.012c70767a872f9b.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +287 -0
  38. package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/{6680.6a693c28aae4cd19.js → 3528.e4b8ab70d339f965.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +94 -0
  45. package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/3f0de3de-2340c532c00395db.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4199-f7c6eb40cd0322f8.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +32 -0
  57. package/apps/pwa/out/_next/static/chunks/{4036.d54e55e1ebf5acdc.js → 4804.6012b5cd33c22792.js} +2 -2
  58. package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +79 -0
  60. package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +74 -0
  63. package/apps/pwa/out/_next/static/chunks/5041-5aada92ca215ffdd.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{6819.be5c9c4d67f22922.js → 5203.51e5d8b5f1dcfe53.js} +16 -16
  65. package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/{757-4fbaf50942b8c424.js → 5255-1b60d50eabe9f057.js} +1 -1
  67. package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +286 -0
  68. package/apps/pwa/out/_next/static/chunks/5300.677c97e0393742e6.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{7867.e8725745ddd1d940.js → 5307.d7328020227880c2.js} +4 -4
  70. package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +8 -0
  73. package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{5046.7fd5cbd859299448.js → 5638.107314dc479e2f37.js} +1 -1
  75. package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6142.913b44e260a3f925.js +64 -0
  80. package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6493.27ad77de7aac7966.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/{1224.2ceca6c180d5130b.js → 7000.28157393caaf5343.js} +1 -1
  88. package/apps/pwa/out/_next/static/chunks/{6745-5a63492933959dd9.js → 7161-8f22db3ec5ed005e.js} +3 -3
  89. package/apps/pwa/out/_next/static/chunks/{2479-fe7e188bd9402d14.js → 7311-60a7ea80d23c7521.js} +1 -1
  90. package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{5952.294fc574a8625184.js → 7488.966b116789f3d41a.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/7524.ce973525d30b3d52.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7573.2376e13c9c21f1f8.js +77 -0
  95. package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{6252.240578f10952e091.js → 7628.6b16863ac3972333.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{1746.3563617ea64023a3.js → 7954.4f7a8832663ee979.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/{4931.95cc6dbd230774ca.js → 8019.21ca554a821dad01.js} +16 -16
  102. package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{2375.bf364c85dbb6f085.js → 8487.291666583bebe640.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/8509.3a54d4e61893d7cb.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{4383.18e5c54db3a22c88.js → 8879.ac06755bcf3e44a1.js} +1 -1
  110. package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +149 -0
  111. package/apps/pwa/out/_next/static/chunks/{9151.a2c51e93f9156dae.js → 8911.bf5e712acb25fb6c.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/{58edce7d.f1b0c72acf13b123.js → 8994d93e.33ba491f95345fc2.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/{5f6af561-f90b7a67f4f75d13.js → 89d6c04f-6b8ab341748e468a.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9223.cbcc88e0e9950426.js +41 -0
  115. package/apps/pwa/out/_next/static/chunks/9299.24e2a7d9b6d1f91b.js +226 -0
  116. package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +24 -0
  117. package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9581.da63ddf41acfad46.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +2 -0
  121. package/apps/pwa/out/_next/static/chunks/{de8446d3.31b73eb239fecd7b.js → 9fe1b809.738da85c8b17e3fb.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-866aac5ff226a7f3.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/{page-5c112c6d7c33656e.js → page-c348a3959c5b5fc6.js} +1 -1
  140. package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-88a1edbff62eaf1d.js → page-d1d1210f99f620ae.js} +1 -1
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-291ab19fe2acb173.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/{page-b9af2ac1c4737ce8.js → page-7f569e533ddeecba.js} +1 -1
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/{page-fb9e639c107f5f72.js → page-a9d9a3e66459c1e0.js} +1 -1
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-6b140f77593576eb.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{709a918c.4fd3b4e2a32cb4e3.js → b7459770.6539b11860eb8a9c.js} +7 -7
  174. package/apps/pwa/out/_next/static/chunks/{d9815f84.4918f682a45a8502.js → b7478fef.5917716286213fcc.js} +3 -3
  175. package/apps/pwa/out/_next/static/chunks/{4337e36d.f42c3b391b3d8f20.js → bb6987f9.3647e1a23b0e3217.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/de8b930d.d94c0f42acf807fc.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{8c58d09b.e8724a299658d86f.js → eaad0cba.771200940c529df7.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-4b12a946f352cee2.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +1 -0
  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/graphs/release/recipes.yaml +9 -0
  278. package/graphs/release/release-loop.yaml +26 -18
  279. package/package.json +1 -1
  280. package/scripts/ask-op-inbox-once.ts +17 -0
  281. package/scripts/brand/check.ts +13 -4
  282. package/scripts/gate-0226-accepted-remaining-90.txt +91 -0
  283. package/scripts/gate-0226-failure-census.ts +39 -0
  284. package/scripts/intake-collect-telegram-saved-stage.ts +48 -0
  285. package/scripts/provision-export-redactions.ts +15 -0
  286. package/scripts/public-copy-lint.ts +122 -0
  287. package/scripts/public-export.ts +69 -2
  288. package/scripts/ratchets/next-tui-entry-budget.ts +124 -0
  289. package/scripts/ratchets/train-side-invariants.sh +7 -1
  290. package/scripts/release-loop/cut-branch.ts +61 -12
  291. package/scripts/release-loop/gate-node.ts +161 -25
  292. package/scripts/release-loop/gate-partial.ts +82 -3
  293. package/scripts/release-loop/gate-prewarm-plan.ts +35 -0
  294. package/scripts/release-loop/gate-radius-live.ts +4 -2
  295. package/scripts/release-loop/resume-cap.ts +2 -1
  296. package/scripts/release-loop/resume-release.ts +297 -8
  297. package/scripts/release-loop/resume.ts +13 -5
  298. package/scripts/release-loop/traffic-node.ts +12 -4
  299. package/scripts/release-loop/traffic-transition.ts +53 -13
  300. package/scripts/release-loop/version-node.ts +29 -4
  301. package/scripts/ux-sim.ts +1 -1
  302. package/scripts/video-pipeline.ts +2 -2
  303. package/src/acp/core-turn-bridge.ts +6 -1
  304. package/src/agent/run-context.ts +1 -1
  305. package/src/agent/task-notification.ts +3 -1
  306. package/src/agent-substrate/review-observation.ts +10 -0
  307. package/src/agent-substrate/self-review-cli.ts +195 -27
  308. package/src/auto-research/question-ladder-contract.ts +137 -0
  309. package/src/auto-research/research-turn.ts +134 -0
  310. package/src/autopilot/discovery/doc-lint.ts +1 -1
  311. package/src/bots/screen-probe.ts +1 -1
  312. package/src/capture/tui-self-report.ts +10 -2
  313. package/src/chat/index.ts +1 -0
  314. package/src/chat/tool-render/dispatch.ts +8 -1
  315. package/src/cli/guardian-cli.ts +3 -1
  316. package/src/cli/intake-cli.ts +48 -12
  317. package/src/cli/lesson-cli.ts +69 -9
  318. package/src/cli/pr-land-overlap-evidence.ts +38 -5
  319. package/src/cli/pr-land-refusal.ts +1 -1
  320. package/src/cli/pty-takeover-cli.ts +58 -5
  321. package/src/cli/release-checklist-read-cli.ts +5 -2
  322. package/src/cli/release-cli.ts +47 -9
  323. package/src/cli/review-carry.ts +77 -0
  324. package/src/cli/self-update.ts +1 -1
  325. package/src/cli/tasks-card-show.ts +31 -1
  326. package/src/cli/tasks-cli.ts +62 -23
  327. package/src/cli/tasks-read-cli.ts +13 -5
  328. package/src/context-bus/context-now.ts +86 -2
  329. package/src/core-turn/run-core-turn.ts +9 -2
  330. package/src/core-turn/types.ts +3 -0
  331. package/src/dashboard/index.ts +18 -17
  332. package/src/dashboard/input/terminal-modal-router.ts +8 -159
  333. package/src/dashboard/side-basic-runtime.ts +61 -0
  334. package/src/dashboard/slash-runtime/dashboard-handlers.ts +2 -0
  335. package/src/dashboard/term-slash-runtime.ts +2 -0
  336. package/src/dashboard/turn-preamble.ts +28 -4
  337. package/src/domains/guardian-tick.ts +9 -0
  338. package/src/git-fs/watcher.ts +27 -22
  339. package/src/git-fs/worktree.ts +19 -3
  340. package/src/graph-runner/graph-grow.ts +37 -9
  341. package/src/graph-runner/runner.ts +17 -2
  342. package/src/grok/credential.ts +107 -36
  343. package/src/hq/fence-wrapper.ts +1 -1
  344. package/src/hq/transfer.ts +1 -1
  345. package/src/index.ts +44 -14
  346. package/src/intake-plane/collect-telegram-saved.ts +54 -5
  347. package/src/interactive-terminal-modal.ts +3 -0
  348. package/src/keybindings.ts +17 -22
  349. package/src/llm/provider-credentials.ts +1 -1
  350. package/src/llm-tool-schema.ts +20 -0
  351. package/src/llm.ts +81 -11
  352. package/src/loops/orchestrator/inbox-once.ts +28 -0
  353. package/src/loops/orchestrator/inbox.ts +130 -1
  354. package/src/loops/orchestrator/tick.ts +6 -3
  355. package/src/maturity/feature-maturity.ts +1 -0
  356. package/src/nexus/api/channel-ask-op.ts +96 -0
  357. package/src/nexus/api/discord-trigger-bot.ts +28 -1
  358. package/src/nexus/api/telegram-trigger-bot.ts +24 -0
  359. package/src/nexus/api/terminals.ts +28 -6
  360. package/src/patents/ledger.ts +18 -1
  361. package/src/preview/terminal.ts +4 -2
  362. package/src/prompt-cache/anthropic.ts +2 -0
  363. package/src/prompt-enhance/enhance.ts +5 -0
  364. package/src/pty-shell/pty-manifest.ts +16 -2
  365. package/src/release-loop/gate-shards.ts +61 -0
  366. package/src/release-loop/light-rc.ts +7 -4
  367. package/src/release-loop/rehearsal.ts +1 -1
  368. package/src/repl/index.ts +10 -0
  369. package/src/research/axis-fanout.ts +133 -0
  370. package/src/research/edge-decision.ts +88 -0
  371. package/src/research/output-router.ts +127 -0
  372. package/src/research-bridge/format.ts +16 -1
  373. package/src/research-bridge/index.ts +1 -0
  374. package/src/research-bridge/invoke.ts +41 -5
  375. package/src/self-dev/decompose.ts +45 -9
  376. package/src/self-dev/draft-residue.ts +221 -2
  377. package/src/self-dev/draft-sweep.ts +29 -16
  378. package/src/self-dev/orchestrate.ts +1 -0
  379. package/src/self-dev/run-supervisor.ts +22 -7
  380. package/src/self-dev/shard-run.ts +260 -3
  381. package/src/self-implement/comment-only-source.ts +54 -0
  382. package/src/self-implement/doctor-visit.ts +25 -0
  383. package/src/self-implement/gate-artifacts.ts +2 -2
  384. package/src/self-implement/gate-baseline.ts +44 -9
  385. package/src/self-implement/gate-cli.ts +151 -86
  386. package/src/self-implement/gate-failure-signature.ts +44 -0
  387. package/src/self-implement/gate-remote.ts +2 -0
  388. package/src/self-implement/goal-author.ts +74 -3
  389. package/src/self-implement/goal-doc/section.ts +22 -0
  390. package/src/self-implement/goal-supervisor-fill.ts +38 -4
  391. package/src/self-implement/knowhow-pack.ts +120 -7
  392. package/src/self-implement/l8-merge-queue.ts +198 -32
  393. package/src/self-implement/off-diff-evidence.ts +23 -0
  394. package/src/self-implement/orchestrator.ts +55 -12
  395. package/src/self-implement/pod-inplace-worktree.ts +82 -0
  396. package/src/self-implement/pod-warm-pool-profile.ts +2 -2
  397. package/src/self-implement/premise-review.ts +7 -5
  398. package/src/self-implement/run-ledger.ts +258 -0
  399. package/src/self-implement/seams.ts +33 -10
  400. package/src/self-implement/self-implement-cli.ts +26 -2
  401. package/src/session/channel-ask-op-envelope.ts +36 -0
  402. package/src/session/channel-op-reply-route.ts +200 -0
  403. package/src/session/chat.ts +3 -0
  404. package/src/session/index.ts +2 -0
  405. package/src/session-runtime/index.ts +9 -22
  406. package/src/skills/runner.ts +7 -3
  407. package/src/skills/tools/dev-harness.ts +2 -2
  408. package/src/skills/tools/schedule-wakeup.ts +1 -6
  409. package/src/status/bar.ts +3 -3
  410. package/src/storage/file-lock.ts +17 -4
  411. package/src/task-agent/adopt-pr.ts +63 -2
  412. package/src/task-agent/evidence-command-normalize.ts +42 -0
  413. package/src/task-agent/export-redactions-provision.ts +43 -0
  414. package/src/task-agent/parent-host.ts +59 -12
  415. package/src/task-agent/repair-cycle.ts +67 -8
  416. package/src/task-agent/repair-worker.ts +37 -1
  417. package/src/task-agent/task-hand.ts +98 -10
  418. package/src/task-agent/tier-split.ts +37 -3
  419. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +31 -4
  420. package/src/task-orchestrator/surfaces/pod-pool.ts +27 -4
  421. package/src/task-orchestrator/surfaces/self-implement-pod.ts +126 -48
  422. package/src/task-orchestrator/surfaces/self-implement.ts +33 -2
  423. package/src/terminal/session-registry.ts +1 -0
  424. package/src/terminal/terminal-modal-router.ts +156 -0
  425. package/src/tool-hints/gate.ts +6 -4
  426. package/src/tool-hints/signals.ts +33 -1
  427. package/src/tui/chat/background-job-status.ts +8 -2
  428. package/src/tui/entry.ts +469 -31
  429. package/src/tui/sidetab/attach.ts +304 -0
  430. package/src/tui/sidetab/list.ts +176 -0
  431. package/src/tui/sidetab/nl-tool.ts +136 -0
  432. package/src/tui/slash/resume-command.ts +23 -0
  433. package/src/tui/slash/resume.ts +3 -23
  434. package/src/tui/slash/term-next.ts +2 -1
  435. package/src/tui-client/local-chat-turn.ts +29 -8
  436. package/src/user-config.ts +11 -2
  437. package/src/ux-sim/fake-llm.ts +11 -5
  438. package/src/ux-sim/next-tui-seat-scenarios.ts +53 -1
  439. package/src/version/packed-revision.json +1 -1
  440. package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +0 -1
  445. package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +0 -1
  447. package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/1ed5e8af.cf424815c7c0efad.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/210.90b2cbd64926cf34.js +0 -32
  451. package/apps/pwa/out/_next/static/chunks/2318-450e75d07605b8fe.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +0 -148
  454. package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +0 -27
  458. package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/3578.4e9f9948a9a6f2f4.js +0 -2
  463. package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +0 -36
  465. package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +0 -226
  467. package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +0 -287
  468. package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/4313.76f232c304a15bde.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/4725-34bed25720cc326b.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/4833-7934c592c5569f00.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +0 -24
  477. package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +0 -104
  479. package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +0 -93
  486. package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +0 -74
  487. package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +0 -149
  490. package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +0 -41
  493. package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +0 -24
  496. package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/7c5ed21f-f286708e57cf88f7.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +0 -8
  508. package/apps/pwa/out/_next/static/chunks/8080-40d781e7704d3671.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +0 -77
  510. package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +0 -286
  513. package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +0 -79
  517. package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +0 -94
  525. package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +0 -64
  527. package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/app/live/page-3337c6a1328c2674.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/morning/page-1e5da297557d2354.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/outputs/page-443364c9e4a23b31.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/term/page-ac2c1e6169cfce57.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/workspace/page-c1c80e345fa9d6f5.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +0 -1
  586. package/scripts/migrate-monad-to-elanous.ts +0 -195
  587. package/scripts/rebrand-elanous.ts +0 -242
  588. /package/apps/pwa/out/_next/static/{8kITumG9GAZ1LwT9POrAR → RrjXTwz-urRAbChP1bX02}/_ssgManifest.js +0 -0
package/src/llm.ts CHANGED
@@ -62,7 +62,7 @@ import { BUILTIN_CATALOG, reasoningEffortCeiling as reasoningEffortCeilingOf } f
62
62
  import { inferProviderFromModel as registryInferProviderFromModel } from './registry/normalize.js';
63
63
  import { closestMatches } from './tool-name-suggest.js';
64
64
  import { createProviderToolNameMap } from './llm-tool-name.js';
65
- import { isOpenRouterGrokModel, sanitizeToolSchemaForGrok } from './llm-tool-schema.js';
65
+ import { assertNoTopLevelToolSchemaCombinators, isOpenRouterGrokModel, sanitizeToolSchemaForGrok } from './llm-tool-schema.js';
66
66
  import { undoTurnRuntime } from './tool-runtime/undo-turn-runtime.js';
67
67
  import { listSnapshots } from './undo-turn/index.js';
68
68
  // Zero-dep spec module (no tool-runtime registry) — safe for this hot path.
@@ -403,6 +403,9 @@ export type ToolChoice = 'auto' | 'required' | 'none' | { name: string };
403
403
 
404
404
  export interface LLMOpts {
405
405
  model?: string;
406
+ /** Explicit research surface verdict from the turn router. Relaxes early
407
+ * exploration guards while retaining a finite tool-loop hard stop. */
408
+ researchTurn?: boolean;
406
409
  /** Reports the provider and model actually attempted, including fallbacks. */
407
410
  onResolvedProvider?(provider: string, model: string): void;
408
411
  temperature?: number;
@@ -4471,6 +4474,7 @@ function explainAndLogFallbackCandidates(
4471
4474
 
4472
4475
  /** 스트림 중 끊김 재시도 상한 — codex `DEFAULT_STREAM_MAX_RETRIES`(5) 와 같은 값. */
4473
4476
  const STREAM_DISCONNECT_MAX_RETRIES = 5;
4477
+ const STREAM_IDLE_TIMEOUT_MAX_RETRIES = 1;
4474
4478
  let streamDisconnectRetryDelayMs: (attempt: number) => number = backoffMs;
4475
4479
 
4476
4480
  /** @internal 시험 seam — 재시도 대기(기본 `backoffMs`)를 바꾼다. `undefined` 면 원복. */
@@ -4904,6 +4908,7 @@ export async function streamLLM(
4904
4908
  );
4905
4909
  activeProvider = finalized.provider;
4906
4910
  const activeModel = finalized.model;
4911
+ if (getModelFamily(activeModel) === 'claude') assertNoTopLevelToolSchemaCombinators(opts.tools);
4907
4912
  opts.onResolvedProvider?.(activeProvider.name, activeModel);
4908
4913
  debug.log('llm.router', 'streamLLM', {
4909
4914
  provider: activeProvider.name,
@@ -5118,6 +5123,8 @@ export function resolveDefaultProvider(model?: string): LLMProvider {
5118
5123
  export interface StreamWithToolsHandlers {
5119
5124
  /** Streaming text delta — invoked for every text chunk across all turns. */
5120
5125
  onText(delta: string, fullAcrossTurns: string): void;
5126
+ /** Optional status line for hosts that surface transient stream recovery. */
5127
+ onStatus?(line: string): void;
5121
5128
  /** Dispatch a tool call. Returning undefined/null throws in the loop so
5122
5129
  * callers should always return a JSON-serializable value (can be an
5123
5130
  * error object — the model will see it as a tool_result either way).
@@ -7382,6 +7389,16 @@ function resultText(result: unknown): string {
7382
7389
  return '';
7383
7390
  }
7384
7391
 
7392
+ /** skill_exec returns structured host metadata, but its model-facing tool result is the answer body. */
7393
+ function toolResultContentForCall(toolName: string, result: unknown): string {
7394
+ if (toolName === 'skill_exec' && result && typeof result === 'object'
7395
+ && typeof (result as { output?: unknown }).output === 'string') {
7396
+ if ((result as { ok?: unknown }).ok === false) return JSON.stringify(result);
7397
+ return (result as { output: string }).output;
7398
+ }
7399
+ return typeof result === 'string' ? result : JSON.stringify(result);
7400
+ }
7401
+
7385
7402
  function detectExecutionFailure(result: unknown): boolean {
7386
7403
  if (!result || typeof result !== 'object') return false;
7387
7404
  const typed = result as Record<string, unknown>;
@@ -8409,7 +8426,9 @@ export async function streamLLMWithTools(
8409
8426
  const familyDefaultMaxTurns = resolved === 0 ? Number.POSITIVE_INFINITY : (resolved || baselineForFamily);
8410
8427
  // `let` (not const) — the conditional budget-grant hook (opts.budgetGrant)
8411
8428
  // may extend this mid-loop when a designated multi-round tool is called.
8412
- let maxTurns = opts.maxTurns ?? familyDefaultMaxTurns;
8429
+ let maxTurns = opts.maxTurns ?? (opts.researchTurn
8430
+ ? Math.min(32, Math.max(16, familyDefaultMaxTurns))
8431
+ : familyDefaultMaxTurns);
8413
8432
  const budgetGrant = opts.budgetGrant;
8414
8433
  // ⭐ Hydration-capable tool list (F2 gap④ · 2026-07-26). The provider tool
8415
8434
  // array used to be `opts.tools`, FIXED for the whole loop. That made
@@ -8428,7 +8447,9 @@ export async function streamLLMWithTools(
8428
8447
  } catch { /* config unreadable — default 비-면제·hot-path 는 config 손상에 안 막힌다 */ }
8429
8448
  const inspectBudgetThreshold = getInspectBudgetThreshold(history, modelFamily, codexInspectExemptFlag);
8430
8449
  const inspectFollowupMode = getInspectFollowupMode(history);
8431
- const explorationThresholdForTurn = getExplorationThreshold(history, maxTurns, modelFamily);
8450
+ const explorationThresholdForTurn = opts.researchTurn
8451
+ ? Number.POSITIVE_INFINITY
8452
+ : getExplorationThreshold(history, maxTurns, modelFamily);
8432
8453
  const maxTurnsUnbounded = maxTurns === Infinity;
8433
8454
  const familyDefaultMaxTurnsUnbounded = familyDefaultMaxTurns === Infinity;
8434
8455
  const explorationUnbounded = !Number.isFinite(explorationThresholdForTurn);
@@ -8443,6 +8464,7 @@ export async function streamLLMWithTools(
8443
8464
  inspectBudgetThreshold,
8444
8465
  inspectFollowupMode,
8445
8466
  explorationThresholdForTurn,
8467
+ researchTurn: opts.researchTurn === true,
8446
8468
  // ★ Infinity 는 JSON 직렬화 시 null 이 되므로 boolean 으로도 남긴다(관측·제1원칙).
8447
8469
  // true = 프론티어 면제로 read/search 스트릭 컷 없음(대표 방침 2026-07-17).
8448
8470
  explorationUnbounded,
@@ -8831,7 +8853,7 @@ export async function streamLLMWithTools(
8831
8853
  let turnOpts = buildTurnOpts();
8832
8854
  // reasoning-heavy family(codex/claude/gemini/grok/local)는 침묵 추론 구간이 길어 idle watchdog 를
8833
8855
  // family-aware 로 상향(2026-07-19 goal-exec → 아크4 전-family). fast/mini(gpt·other)만 45s 유지.
8834
- const streamIdleTimeoutMs = usesLongReasoningIdle(modelFamily, activeProvider.name) ? STREAM_IDLE_TIMEOUT_MS_REASONING : STREAM_IDLE_TIMEOUT_MS;
8856
+ const streamIdleTimeoutMs = opts.streamIdleTimeoutMs ?? (usesLongReasoningIdle(modelFamily, activeProvider.name) ? STREAM_IDLE_TIMEOUT_MS_REASONING : STREAM_IDLE_TIMEOUT_MS);
8835
8857
  // ⚠️ hang 진단(2026-07-17) — codex SSE 스트림이 완료 신호 없이 안 끝나는 케이스 확정용.
8836
8858
  // consume-start 후 consume-end 가 없으면 = for-await(streamChat SSE) hang. lastEvType 로 어느
8837
8859
  // 이벤트 뒤에서 멈추는지(usage/text/tool_call) 특정. 무장할 상한도 남겨 실험 런을 구별한다.
@@ -8847,6 +8869,7 @@ export async function streamLLMWithTools(
8847
8869
  // ⭐ TUI-STREAM-RETRY(2026-10-14 실측) — 200 OK 로 흐르던 스트림이 소켓 끊김으로 죽으면 같은 공급자로
8848
8870
  // 다시 건다(codex `stream_max_retries` 동형). 이 턴에서 받은 tool_call·image 가 있으면 재시도하지 않는다.
8849
8871
  let streamDisconnectRetries = 0;
8872
+ let streamIdleTimeoutRetries = 0;
8850
8873
  let streamEmittedImage = false;
8851
8874
  // 끊긴 조각을 이력(turnText·fullText)에서 «조용히» 되감는다 — 화면엔 지우라고 알리지 않는다
8852
8875
  // (TUI 의 빈 델타는 «커밋»이다). 이미 보인 글과 겹치는 재시도 본문은 `retryDisplay` 가 막는다.
@@ -8878,6 +8901,9 @@ export async function streamLLMWithTools(
8878
8901
  while (true) {
8879
8902
  let idleTimer: ReturnType<typeof setTimeout> | undefined;
8880
8903
  let step: { idle: true } | { idle: false; r: IteratorResult<LLMStreamEvent, void> };
8904
+ // Validate before entering the provider stream's catch/fallback boundary.
8905
+ // An incompatible request is deterministic and must not be retried elsewhere.
8906
+ if (getModelFamily(activeModel) === 'claude') assertNoTopLevelToolSchemaCombinators(turnOpts.tools);
8881
8907
  try {
8882
8908
  if (!streamIter) {
8883
8909
  const finalized = finalizeStreamingProviderModel(activeProvider, activeModel);
@@ -8918,8 +8944,46 @@ export async function streamLLMWithTools(
8918
8944
  streamIter.next().then((r) => ({ idle: false as const, r })),
8919
8945
  new Promise<{ idle: true }>((res) => { idleTimer = setTimeout(() => res({ idle: true }), streamIdleTimeoutMs); }),
8920
8946
  ]);
8947
+ if (step.idle) {
8948
+ const error = new Error(`stream idle timeout after ${streamIdleTimeoutMs}ms`);
8949
+ error.name = 'StreamIdleTimeoutError';
8950
+ Object.assign(error, { code: 'ETIMEDOUT' });
8951
+ throw error;
8952
+ }
8921
8953
  } catch (err) {
8922
8954
  if (idleTimer) clearTimeout(idleTimer);
8955
+ if (err instanceof Error && err.name === 'StreamIdleTimeoutError') {
8956
+ debug.log('llm.stream', 'idle-timeout', {
8957
+ turn, evCount, lastEvType, idleMs: streamIdleTimeoutMs,
8958
+ textChars: turnText.length, pendingCalls: pendingCalls.length,
8959
+ }, { level: 'warn' });
8960
+ // A provider async iterator can queue return() behind the pending next().
8961
+ // Detach cleanup so it cannot keep the user turn busy forever.
8962
+ const timedOutIterator = streamIter;
8963
+ if (timedOutIterator?.return) {
8964
+ try { void Promise.resolve(timedOutIterator.return(undefined)).catch(() => {}); } catch { /* fail-soft cleanup */ }
8965
+ }
8966
+ if (streamIdleTimeoutRetries < STREAM_IDLE_TIMEOUT_MAX_RETRIES
8967
+ && pendingCalls.length === 0 && !streamEmittedImage && !opts.signal?.aborted) {
8968
+ streamIdleTimeoutRetries++;
8969
+ debug.log('llm.retry', 'idle-timeout-retry', {
8970
+ provider: activeProvider.name, model: activeModel, turn,
8971
+ attempt: streamIdleTimeoutRetries, maxRetries: STREAM_IDLE_TIMEOUT_MAX_RETRIES,
8972
+ delayMs: 0, statusLine: '스트림 무응답 · 재시도',
8973
+ }, { level: 'warn' });
8974
+ handlers.onStatus?.(`스트림 무응답 · 재시도 ${streamIdleTimeoutRetries}/${STREAM_IDLE_TIMEOUT_MAX_RETRIES}`);
8975
+ rewindDisconnectedStream();
8976
+ streamIter = undefined;
8977
+ continue;
8978
+ }
8979
+ // Once a tool call/image escaped, keep the old behavior: finish this
8980
+ // provider turn and never replay or switch providers around side effects.
8981
+ if (pendingCalls.length > 0 || streamEmittedImage || opts.signal?.aborted) break;
8982
+ if (opts.provider) break; // pinned route preserves the prior partial-text result
8983
+ // The retry's text was already sent to the view; drop it from the
8984
+ // logical result before allowing the normal provider fallback path.
8985
+ if (pendingCalls.length === 0 && !streamEmittedImage) rewindDisconnectedStream();
8986
+ }
8923
8987
  if (err instanceof OverloadFailoverError && !opts.provider) {
8924
8988
  const switched = activeProvider.name === 'openai-codex'
8925
8989
  ? firstAvailableFallbackProvider(attemptedProviders, opts)
@@ -8934,6 +8998,7 @@ export async function streamLLMWithTools(
8934
8998
  status: err.status,
8935
8999
  kind: err.kind,
8936
9000
  }, { level: 'warn' });
9001
+ handlers.onStatus?.(`⚠ 공급자 전환: ${activeProvider.name} → ${switched.name} (${err.kind ?? err.name ?? 'unknown'})`);
8937
9002
  const finalized = finalizeStreamingProviderModel(switched, switched.defaultModel);
8938
9003
  activeProvider = finalized.provider;
8939
9004
  activeModel = finalized.model;
@@ -8944,7 +9009,8 @@ export async function streamLLMWithTools(
8944
9009
  continue;
8945
9010
  }
8946
9011
  }
8947
- if (evCount > 0 && isStreamDisconnectRetryable(err, pendingCalls.length, streamEmittedImage) && !opts.signal?.aborted) {
9012
+ if (!(err instanceof Error && err.name === 'StreamIdleTimeoutError')
9013
+ && evCount > 0 && isStreamDisconnectRetryable(err, pendingCalls.length, streamEmittedImage) && !opts.signal?.aborted) {
8948
9014
  const retryData = {
8949
9015
  provider: activeProvider.name,
8950
9016
  model: activeModel,
@@ -9013,6 +9079,7 @@ export async function streamLLMWithTools(
9013
9079
  tools: activeTools.map((tool) => tool.name),
9014
9080
  ...(opts.model ? { modelOverrideDropped: opts.model } : {}),
9015
9081
  }, { level: 'warn' });
9082
+ handlers.onStatus?.(`⚠ 공급자 전환: ${activeProvider.name} → ${fallback.name} (${verdict.category})`);
9016
9083
  const finalized = finalizeStreamingProviderModel(fallback, fallback.defaultModel);
9017
9084
  activeProvider = finalized.provider;
9018
9085
  activeModel = finalized.model;
@@ -9025,9 +9092,9 @@ export async function streamLLMWithTools(
9025
9092
  }
9026
9093
  if (idleTimer) clearTimeout(idleTimer);
9027
9094
  if (step.idle) {
9028
- debug.log('llm.stream', 'idle-timeout', { turn, evCount, lastEvType, idleMs: streamIdleTimeoutMs, textChars: turnText.length, pendingCalls: pendingCalls.length }, { level: 'warn' });
9029
- try { await streamIter.return?.(undefined); } catch { /* fail-soft — 스트림 정리 실패 무시 */ }
9030
- break;
9095
+ // The race's idle branch is converted to StreamIdleTimeoutError above.
9096
+ // Keep a fail-closed guard for future changes to this loop.
9097
+ throw new Error('stream idle timeout branch escaped recovery');
9031
9098
  }
9032
9099
  if (step.r.done) break;
9033
9100
  const ev = step.r.value;
@@ -10289,7 +10356,8 @@ export async function streamLLMWithTools(
10289
10356
  // rejection without colliding with the auto-narrow path)
10290
10357
  // - call is in SEARCH_ONLY_TOOLS
10291
10358
  if (
10292
- dispatchedReadCount === 0
10359
+ !opts.researchTurn
10360
+ && dispatchedReadCount === 0
10293
10361
  && autoNarrowedReadCount === 0
10294
10362
  && searchOnlyTurnStreak >= 3
10295
10363
  && SEARCH_ONLY_TOOLS.has(call.name)
@@ -11066,7 +11134,7 @@ export async function streamLLMWithTools(
11066
11134
  resultBlocks.push({
11067
11135
  type: 'tool_result',
11068
11136
  tool_use_id: call.id,
11069
- content: typeof result === 'string' ? result : JSON.stringify(result),
11137
+ content: toolResultContentForCall(call.name, result),
11070
11138
  ...(isError ? { isError: true } : {}),
11071
11139
  });
11072
11140
  }
@@ -11245,7 +11313,8 @@ export async function streamLLMWithTools(
11245
11313
  // synthesis attempt. Extended to gemini 2026-05-04 alongside
11246
11314
  // W5-E/W5-F for the same pathology shape.
11247
11315
  if (
11248
- !forceSynthesisAttempted
11316
+ !opts.researchTurn
11317
+ && !forceSynthesisAttempted
11249
11318
  && noContentReadTurnStreak >= 4
11250
11319
  && (modelFamily === 'gemini'
11251
11320
  || applyCodexBehaviorGuard('force-synthesis', effectiveModel, codexGuardCandidate, true))
@@ -11500,6 +11569,7 @@ function makeOpenAICompatProvider(
11500
11569
  throw new Error(`${name} unavailable: configure apiKey via \`elanous setup\``);
11501
11570
  }
11502
11571
  const activeModel = opts.model || model;
11572
+ if (getModelFamily(activeModel) === 'claude') assertNoTopLevelToolSchemaCombinators(opts.tools);
11503
11573
  const wireModel = name === 'openrouter' ? openRouterWireModel(activeModel) : activeModel;
11504
11574
  const tools = toOpenAITools(
11505
11575
  opts.tools,
@@ -0,0 +1,28 @@
1
+ import { join } from 'node:path';
2
+ import { effectiveInstanceRoot } from '../../instance/resolve.js';
3
+ import { resolveConfiguredAgentRoleLlm } from '../../user-config.js';
4
+ import type { RoleLlmSpec } from '../../user-config.js';
5
+ import { loadAgentRolePack } from '../agent-reply.js';
6
+ import type { MsgStore } from '../../msg/msg-store.js';
7
+ import { runAskOpContextInbox, runCoordinatorAgentInbox, type CoordinatorInboxResult } from './inbox.js';
8
+ import type { AskOpContextBundle } from '../../context-bus/context-now.js';
9
+
10
+ export interface InboxOnceOptions {
11
+ root?: string;
12
+ store?: MsgStore;
13
+ role?: RoleLlmSpec | null;
14
+ limit?: number;
15
+ context?: (question: string, options: { audience?: string; limit?: number }) => Promise<AskOpContextBundle>;
16
+ }
17
+
18
+ /** One scan of the same durable inbox as the orchestrator tick, without running its graph. */
19
+ export async function runCoordinatorInboxOnce(options: InboxOnceOptions = {}): Promise<CoordinatorInboxResult> {
20
+ const root = options.root ?? effectiveInstanceRoot();
21
+ const path = join(root, 'msg', 'messages.db');
22
+ const role = options.role === undefined ? resolveConfiguredAgentRoleLlm('coordinator') : options.role;
23
+ if (role) return runCoordinatorAgentInbox({ role, pack: loadAgentRolePack('coordinator'), root, path,
24
+ limit: options.limit ?? 100, ...(options.store ? { store: options.store } : {}) });
25
+ return runAskOpContextInbox({ path, limit: options.limit ?? 100,
26
+ ...(options.store ? { store: options.store } : {}),
27
+ ...(options.context ? { context: options.context } : {}) });
28
+ }
@@ -1,15 +1,90 @@
1
+ import { ASK_OP_COMMAND } from '../../session/channel-ask-op-envelope.js';
1
2
  import { openMsgStore, type Message, type MsgStore } from '../../msg/msg-store.js';
2
3
  import { classifySeatTrafficProposal } from '../../seat-loop/traffic-signal.js';
3
- import { debug } from '../../debug/log.js';
4
+ import { debug, redactSecretText } from '../../debug/log.js';
4
5
  import { LOOP_MESSAGE_ROUTES } from '../msg-address.js';
5
6
  import { replyWithAgent, type AgentReplyInput } from '../agent-reply.js';
6
7
  import { knowhowAdvice, type KnowhowAdvice, type KnowhowOptions } from './knowhow-pack.js';
7
8
  import type { RoleLlmSpec } from '../../user-config.js';
8
9
  import type { LLMProvider } from '../../llm.js';
10
+ import { askOpContextBundle, type AskOpContextBundle } from '../../context-bus/context-now.js';
9
11
 
10
12
  const RECIPIENT = LOOP_MESSAGE_ROUTES.orchestrator.msgAddress;
11
13
 
12
14
  export interface CoordinatorInboxResult { replied: number; acknowledged: number }
15
+ export interface AskOpTestHarness {
16
+ /** A test-only sink; this never defaults to a real surface transport. */
17
+ replySink: (reply: { from: string; to: string; body: string; kind: 'reply'; replyTo: number }) => Message;
18
+ /** Capture both clocks without writing to the production log store in tests. */
19
+ eventSink?: (event: { requestId: number; requestToReplyMs: number | null; processingMs: number }) => void;
20
+ }
21
+ export interface AskOpContextInboxOptions {
22
+ store?: MsgStore;
23
+ path?: string;
24
+ limit?: number;
25
+ context?: typeof askOpContextBundle;
26
+ knowhow?: KnowhowOptions | false;
27
+ /** Only the ordered tick scan may advance the durable cursor. */
28
+ acknowledge?: boolean;
29
+ /** SSE delivery handles exactly its message; the ordered tick scans the cursor. */
30
+ request?: Message;
31
+ /** Explicit opt-in for synthetic TEST ASK-OP questions only. Production callers must omit this. */
32
+ testHarness?: AskOpTestHarness;
33
+ }
34
+
35
+ const ASK_OP_SENDERS = new Set(['TELEGRAM', 'DISCORD']);
36
+ const REFUSE = '모름 — 확인된 근거가 없어 답할 수 없습니다.';
37
+
38
+ function isAskOpRequest(request: Message, allowTestSource = false): boolean {
39
+ const testSource = allowTestSource && request.from === 'TEST'
40
+ && /^Test \/(?:askop|ask-op)(?:\r?\n|$)/.test(request.body);
41
+ return request.kind === 'question' && (ASK_OP_SENDERS.has(request.from) || testSource)
42
+ && (testSource || new RegExp(`^(?:Telegram|Discord) \/(?:${ASK_OP_COMMAND}|ask-op)(?:\\r?\\n|$)`).test(request.body));
43
+ }
44
+
45
+ function askOpLatencyMs(request: Message, repliedAt: number): number | null {
46
+ const createdAt = Date.parse(request.createdAt);
47
+ const latencyMs = repliedAt - createdAt;
48
+ return Number.isFinite(createdAt) && latencyMs >= 0 ? latencyMs : null;
49
+ }
50
+
51
+ function writeAskOpReply(store: MsgStore, request: Message, replyText: string, options: AskOpContextInboxOptions) {
52
+ if (options.testHarness && request.from === 'TEST') {
53
+ const marker = `re #${request.id}\n`;
54
+ const body = replyText.startsWith(marker) ? replyText.slice(marker.length) : replyText;
55
+ const reply = options.testHarness.replySink({ from: RECIPIENT, to: request.from,
56
+ body, kind: 'reply', replyTo: request.id });
57
+ return { id: reply.id, posted: true };
58
+ }
59
+ return writeCoordinatorReply(store, request, replyText);
60
+ }
61
+
62
+ function askOpQuestion(request: Message): string {
63
+ const match = /^question: (.*)$/m.exec(request.body);
64
+ return match?.[1]?.trim() ?? '';
65
+ }
66
+
67
+ function unsafeAskOp(question: string): boolean {
68
+ // Reject explicit commands, not descriptive questions such as "What changed since the release?".
69
+ return /^(?:(?:please|can you|could you|would you)\s+)?(?:run|execute|deploy|publish|push|merge|delete|drop|write|edit|change|set)\b|(?:실행해|발행해|배포해|푸시해|병합해|삭제해|수정해|바꿔|설정해)(?:줘|주세요)?|\b(?:show|reveal|give|tell|display|print|read|open|what is|what's)\b.{0,80}\b(?:secret|token|password|credential|api[ -]?key|private[ -]?key)\b|(?:비밀|토큰|암호|패스워드|인증키|API\s*키).{0,80}(?:보여|알려|공개|읽어)/i.test(question);
70
+ }
71
+
72
+ async function askOpAnswer(request: Message, options: AskOpContextInboxOptions): Promise<string> {
73
+ const question = askOpQuestion(request);
74
+ if (!question) return `제안: ${REFUSE}\n근거: 질문이 비었습니다.`;
75
+ if (unsafeAskOp(question)) return '제안: 요청한 권한 실행·비밀 조회·traffic/칸 변경은 실행할 수 없습니다.\n근거: OP 질문 답변은 읽기 전용입니다.';
76
+ let bundle: AskOpContextBundle;
77
+ // These replies are delivered to an external channel, not the private operator console.
78
+ try { bundle = await (options.context ?? askOpContextBundle)(question, { audience: 'public-demo', limit: 8 }); }
79
+ catch { return `제안: ${REFUSE}\n근거: 맥락 조회 실패.`; }
80
+ const facts = bundle.facts.filter(fact => fact.source?.trim() && fact.summary?.trim()).slice(0, 8);
81
+ if (!facts.length) {
82
+ const gaps = bundle.gaps.slice(0, 3).map(gap => `${redactSecretText(gap.kind)}: ${redactSecretText(gap.reason)}`).join('; ');
83
+ return `제안: ${REFUSE}\n근거: ${gaps || '미관측'}.`;
84
+ }
85
+ const evidence = facts.map(fact => `- ${redactSecretText(fact.summary)} — ${redactSecretText(fact.source)} (관측 ${redactSecretText(fact.observedAt)})`).join('\n');
86
+ return `제안: 다음은 관측된 OP 맥락입니다 (${redactSecretText(bundle.topic)}; 조회 ${redactSecretText(bundle.queriedAt)}).\n근거:\n${evidence}\n판단·승인·실행은 하지 않았습니다.`;
87
+ }
13
88
  export interface CoordinatorAgentInboxOptions {
14
89
  role: RoleLlmSpec;
15
90
  pack: string;
@@ -95,6 +170,57 @@ function writeCoordinatorReply(store: MsgStore, request: Message, replyText: str
95
170
  return { id: reply.id, posted: true };
96
171
  }
97
172
 
173
+ /** Surface ask-op questions use the same linked reply and durable acknowledgement as the resident inbox. */
174
+ export async function runAskOpContextInbox(options: AskOpContextInboxOptions = {}): Promise<CoordinatorInboxResult> {
175
+ const store = options.store ?? openMsgStore(options.path);
176
+ const ownStore = options.store === undefined;
177
+ const result = { replied: 0, acknowledged: 0 };
178
+ const acknowledge = options.acknowledge !== false;
179
+ try {
180
+ const requests = options.request ? [options.request]
181
+ : store.listByRecipient(RECIPIENT, store.getCursor(RECIPIENT), options.limit ?? 100);
182
+ for (const request of requests) {
183
+ if (request.to !== RECIPIENT || request.from === RECIPIENT ||
184
+ (request.kind !== undefined && request.kind !== 'request' && request.kind !== 'question')) {
185
+ if (acknowledge) { store.ack(RECIPIENT, request.id); result.acknowledged++; }
186
+ continue;
187
+ }
188
+ const testAskOp = request.from === 'TEST' && isAskOpRequest(request, true);
189
+ if (testAskOp && !options.testHarness) continue;
190
+ const key = `coord-inbox:${request.id}:${request.from}`;
191
+ const existing = store.db.query('SELECT message_id FROM msg_provenance WHERE provenance_key = ?')
192
+ .get(key) as { message_id: number } | null;
193
+ // Legacy seat traffic and knowhow requests preserve the existing answer path.
194
+ const startedAt = Date.now();
195
+ const replyText = existing ? '' : (isAskOpRequest(request, options.testHarness !== undefined)
196
+ ? `re #${request.id}\n${await askOpAnswer(request, options)}` : coordinatorReply(request, options.knowhow ?? {}));
197
+ const one = store.db.transaction(() => {
198
+ const receipt = store.db.query('SELECT message_id FROM msg_provenance WHERE provenance_key = ?')
199
+ .get(key) as { message_id: number } | null;
200
+ const reply = receipt ? { id: receipt.message_id, posted: false } : writeAskOpReply(store, request, replyText, options);
201
+ if (!receipt) store.db.query('INSERT INTO msg_provenance(provenance_key, message_id) VALUES (?, ?)').run(key, reply.id);
202
+ if (acknowledge) store.ack(RECIPIENT, request.id);
203
+ return reply.posted;
204
+ }).immediate();
205
+ if (one) result.replied++;
206
+ if (acknowledge) result.acknowledged++;
207
+ debug.log('loop.coordinator-inbox', 'reply', { requestId: request.id, recipient: request.from, duplicate: !one });
208
+ if (one && isAskOpRequest(request, options.testHarness !== undefined)) {
209
+ const repliedAt = Date.now();
210
+ const latencyMs = askOpLatencyMs(request, repliedAt);
211
+ const processingMs = Math.max(0, repliedAt - startedAt);
212
+ if (options.testHarness && request.from === 'TEST') {
213
+ options.testHarness.eventSink?.({ requestId: request.id, requestToReplyMs: latencyMs, processingMs });
214
+ } else {
215
+ debug.log('ask-op.inbox', 'replied', { requestId: request.id, requestToReplyMs: latencyMs,
216
+ processingMs, clockSkew: latencyMs === null });
217
+ }
218
+ }
219
+ }
220
+ return result;
221
+ } finally { if (ownStore) store.close(); }
222
+ }
223
+
98
224
  /** One transaction ties a reply to its acknowledgement. A retry finds the durable receipt. */
99
225
  export function runCoordinatorInbox(inputStore?: MsgStore, limit = 100, path?: string,
100
226
  options: CoordinatorInboxOptions = {}): CoordinatorInboxResult {
@@ -144,6 +270,9 @@ export async function handleCoordinatorAgentMessage(
144
270
  const ownStore = input.store === undefined;
145
271
  const acknowledge = input.acknowledge === true;
146
272
  try {
273
+ if (isAskOpRequest(request) && request.to === RECIPIENT) {
274
+ return await runAskOpContextInbox({ store, request, acknowledge });
275
+ }
147
276
  if (request.to !== RECIPIENT || request.from === RECIPIENT ||
148
277
  (request.kind !== undefined && request.kind !== 'request' && request.kind !== 'question')) {
149
278
  if (acknowledge) store.ack(RECIPIENT, request.id);
@@ -25,7 +25,7 @@ import * as testGuard from '../../instance/test-write-guard.js';
25
25
  import { seatCapDetails } from '../budget.js';
26
26
  export { isLaunchEligible } from './traffic.js';
27
27
  import { readTaskAgentState, TASK_SEATS, type HandTaskOptions, type TaskCard as TaskAgentCard, type HandTaskResult, type TaskLauncher, type TaskSeat } from '../../task-agent/task-hand.js';
28
- import { runCoordinatorAgentInbox, runCoordinatorInbox, type CoordinatorInboxResult } from './inbox.js';
28
+ import { runAskOpContextInbox, runCoordinatorAgentInbox, type CoordinatorInboxResult } from './inbox.js';
29
29
  import type { KnowhowOptions } from './knowhow-pack.js';
30
30
  import { loadAgentRolePack, type AgentReplyInput } from '../agent-reply.js';
31
31
  import type { LLMProvider } from '../../llm.js';
@@ -97,6 +97,8 @@ export interface TickDeps {
97
97
  coordinatorAgentProvider?: LLMProvider;
98
98
  /** Resident knowhow pack seam; the real intake reads 내부 문서 `KNOWHOW` every tick. */
99
99
  coordinatorKnowhow?: KnowhowOptions | false;
100
+ /** Deterministic read-only ask-op context seam for isolated tick tests. */
101
+ coordinatorContext?: typeof import('../../context-bus/context-now.js').askOpContextBundle;
100
102
  }
101
103
 
102
104
  /** ORCH-TA-HAND ledger — one row per handed `orch:<card>:<cell>` key so a cell is handed once across ticks and processes. */
@@ -521,8 +523,9 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
521
523
  ? runCoordinatorAgentInbox({ role, pack: loadAgentRolePack('coordinator'), path: inboxPath, root,
522
524
  ...(deps.coordinatorAgentRun ? { runAgent: deps.coordinatorAgentRun } : {}),
523
525
  ...(deps.coordinatorAgentProvider ? { provider: deps.coordinatorAgentProvider } : {}) })
524
- : runCoordinatorInbox(undefined, 100, inboxPath,
525
- deps.coordinatorKnowhow === undefined ? {} : { knowhow: deps.coordinatorKnowhow });
526
+ : runAskOpContextInbox({ path: inboxPath, limit: 100,
527
+ ...(deps.coordinatorKnowhow === undefined ? {} : { knowhow: deps.coordinatorKnowhow }),
528
+ ...(deps.coordinatorContext ? { context: deps.coordinatorContext } : {}) });
526
529
  }))();
527
530
  if (inbox.replied || inbox.acknowledged) {
528
531
  observe('exchange', 'coordinator-inbox-replied', inbox.replied);
@@ -137,6 +137,7 @@ export const FEATURE_MATURITY = {
137
137
  tablet: 'ops',
138
138
  surface: 'ops',
139
139
  term: 'tool',
140
+ side: 'tool',
140
141
  claude: 'tool',
141
142
  codex: 'tool',
142
143
  gemini: 'tool',
@@ -0,0 +1,96 @@
1
+ import type { Message, MessageEnvelope } from '../../msg/msg-store.js';
2
+ import type { TgSlashCommand } from '../../telegram-commands.js';
3
+ import { ASK_OP_COMMAND, formatAskOpQuestionEnvelope } from '../../session/channel-ask-op-envelope.js';
4
+
5
+ export interface AskOpTelegramOptions {
6
+ allowedUserIds: readonly number[];
7
+ append: (message: MessageEnvelope, provenanceKey: string) => Message;
8
+ }
9
+
10
+ export interface AskOpDiscordOptions {
11
+ allowedUserIds: readonly string[];
12
+ allowedChannelIds: readonly string[];
13
+ resolveBotId: () => Promise<string>;
14
+ append: (message: MessageEnvelope, provenanceKey: string) => Message;
15
+ }
16
+
17
+ export interface AskOpDiscordContext {
18
+ userId: string;
19
+ channelId: string;
20
+ messageId: string;
21
+ text: string;
22
+ }
23
+
24
+ function appendAskOpQuestion(
25
+ options: { append: AskOpTelegramOptions['append'] },
26
+ input: { from: 'TELEGRAM' | 'DISCORD'; surface: string; correlation: string[]; question: string; provenanceKey: string },
27
+ ): Message {
28
+ return options.append({
29
+ from: input.from,
30
+ to: 'COORDINATOR',
31
+ kind: 'question',
32
+ body: [`${input.surface} /${ASK_OP_COMMAND}`, ...input.correlation, `question: ${input.question}`].join('\n'),
33
+ }, input.provenanceKey);
34
+ }
35
+
36
+ function extractQuestion(text: string): string | null {
37
+ const match = new RegExp(`^/(?:${ASK_OP_COMMAND}|ask-op)(?:@[-_a-z0-9]+)?(?:\\s+([\\s\\S]*))?$`, 'i').exec(text.trim());
38
+ const question = match?.[1]?.trim();
39
+ return question || null;
40
+ }
41
+
42
+ export function createAskOpTelegramSlashCommand(options: AskOpTelegramOptions): TgSlashCommand {
43
+ return {
44
+ name: ASK_OP_COMMAND,
45
+ description: '운영 책임자에게 질문을 보냅니다',
46
+ handler: async (_args, ctx) => {
47
+ if (!options.allowedUserIds.includes(ctx.userId)) return '허용된 사용자만 OP에게 질문할 수 있습니다.';
48
+ const question = extractQuestion(ctx.text);
49
+ if (!question) return `사용법: /${ASK_OP_COMMAND} <질문>`;
50
+ if (!Number.isSafeInteger(ctx.updateId) || ctx.updateId < 0) return 'Telegram update 식별값을 확인할 수 없어 질문을 저장하지 못했습니다.';
51
+
52
+ const botId = (ctx.botId ?? 'unknown').replace(/[^a-zA-Z0-9_-]/g, '_');
53
+ const message = options.append({
54
+ from: 'TELEGRAM',
55
+ to: 'COORDINATOR',
56
+ kind: 'question',
57
+ body: formatAskOpQuestionEnvelope({
58
+ surface: 'telegram', botId, chatId: ctx.chatId, threadId: ctx.threadId,
59
+ messageId: ctx.messageId, updateId: ctx.updateId, question,
60
+ }),
61
+ }, `coord:tg-${botId}-${ctx.updateId}:COORDINATOR`);
62
+
63
+ return `OP에게 질문 #${message.id}로 접수했습니다.`;
64
+ },
65
+ };
66
+ }
67
+
68
+ /** Handle a Discord text command from an already-routed message. Returning
69
+ * undefined leaves every non-/askop message on its existing chat path. */
70
+ export function createAskOpDiscordIngress(options: AskOpDiscordOptions) {
71
+ return async (ctx: AskOpDiscordContext): Promise<string | undefined> => {
72
+ const match = new RegExp(`^/${ASK_OP_COMMAND}(?:\\s+([\\s\\S]*))?$`, 'i').exec(ctx.text.trim());
73
+ if (!match) return undefined;
74
+ if (!options.allowedUserIds.includes(ctx.userId)) return '허용된 사용자만 OP에게 질문할 수 있습니다.';
75
+ if (!options.allowedChannelIds.includes(ctx.channelId)) return '허용된 Discord 채널에서만 OP에게 질문할 수 있습니다.';
76
+ const question = match[1]?.trim();
77
+ if (!question) return `사용법: /${ASK_OP_COMMAND} <질문>`;
78
+ if (!/^\d+$/.test(ctx.messageId)) return 'Discord 메시지 식별값을 확인할 수 없어 질문을 저장하지 못했습니다.';
79
+
80
+ let botId: string;
81
+ try { botId = await options.resolveBotId(); }
82
+ catch { return 'Discord 봇 식별값을 확인할 수 없어 질문을 저장하지 못했습니다.'; }
83
+ if (!/^[A-Za-z0-9_-]+$/.test(botId)) return 'Discord 봇 식별값이 올바르지 않아 질문을 저장하지 못했습니다.';
84
+
85
+ const message = appendAskOpQuestion(options, {
86
+ from: 'DISCORD', surface: 'Discord',
87
+ correlation: [
88
+ `botId=${botId}`, `channelId=${ctx.channelId}`,
89
+ `messageId=${ctx.messageId}`, `updateId=${ctx.messageId}`,
90
+ ],
91
+ question,
92
+ provenanceKey: `coord:dc-${botId}-${ctx.messageId}:COORDINATOR`,
93
+ });
94
+ return `OP에게 질문 #${message.id}로 접수했습니다.`;
95
+ };
96
+ }
@@ -37,6 +37,8 @@ import { createDiscordStreamSink } from '../../session/streaming/discord-stream-
37
37
  import { splitForDiscord } from '../../discord.js';
38
38
  import { formatForDiscord } from '../../discord-markdown.js';
39
39
  import { receiveChannelEvent } from '../outbound/router.js';
40
+ import { openMsgStore } from '../../msg/msg-store.js';
41
+ import { createAskOpDiscordIngress } from './channel-ask-op.js';
40
42
 
41
43
  export interface NexusDiscordTriggerBotOpts {
42
44
  /** Bot token (without `Bot ` prefix). Production reads
@@ -156,6 +158,30 @@ export function createNexusDiscordTriggerBot(
156
158
  // LF2 — 콘솔 하트비트 유지 + debug.log 병행(telegram-trigger 동형).
157
159
  const log = opts.log ?? createDiscordTriggerLogger();
158
160
  const onTriggerTap = buildDiscordTriggerTap(opts.dispatch, log);
161
+ let botRef: DiscordBot | undefined;
162
+ let botIdPromise: Promise<string> | undefined;
163
+ const askOpIngress = createAskOpDiscordIngress({
164
+ allowedUserIds: opts.allowedUsers,
165
+ allowedChannelIds: opts.guildTextChannels ?? [],
166
+ resolveBotId: () => {
167
+ if (!botRef) return Promise.reject(new Error('Discord bot is not ready'));
168
+ botIdPromise ??= botRef.getMe().then(({ id }) => id).catch((error: unknown) => {
169
+ botIdPromise = undefined;
170
+ throw error;
171
+ });
172
+ return botIdPromise;
173
+ },
174
+ append: (message, provenanceKey) => {
175
+ const store = openMsgStore();
176
+ try { return store.appendWithProvenance(message, provenanceKey); }
177
+ finally { store.close(); }
178
+ },
179
+ });
180
+ const onMessage: DcMessageHandler = async (ctx, streamer) => {
181
+ const askReply = await askOpIngress(ctx);
182
+ if (askReply !== undefined) return askReply;
183
+ return opts.onMessage?.(ctx, streamer);
184
+ };
159
185
 
160
186
  const botWasInjected = opts.bot !== undefined;
161
187
  const bot = opts.bot ?? new DiscordBot({
@@ -165,7 +191,7 @@ export function createNexusDiscordTriggerBot(
165
191
  // Chat path: the injected self-turn handler (M4b nexus wire) or the
166
192
  // legacy trigger-only no-op. Workflows wanting a chat reply can
167
193
  // still declare a `chatTrigger` (routes via `/v1/workflows/chat/*`).
168
- onMessage: opts.onMessage ?? (async () => undefined),
194
+ onMessage,
169
195
  log,
170
196
  onTriggerTap,
171
197
  ...(opts.voiceTap ? { voiceTap: opts.voiceTap } : {}),
@@ -173,6 +199,7 @@ export function createNexusDiscordTriggerBot(
173
199
  ...(opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}),
174
200
  ...(opts.wsImpl ? { wsImpl: opts.wsImpl } : {}),
175
201
  });
202
+ botRef = bot;
176
203
 
177
204
  // §C3 — discord 서피스 sink(config gate·telegram-trigger 동형). shadowFanout OR
178
205
  // primary.discord 시 등록. endpoint 완전스코프면 parse→인스턴스 가드 후 channelId 배달,