elanous 0.2.43 → 0.2.44

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 (544) 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/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{3557ac4a.c8931684475018ad.js → 08334415.f0e80896acbef722.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1032-78ba4f6391258cab.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1082-53f86a26e03d309d.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1109-7d0e264f6f2edbc7.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1124-7c26330402481143.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/118.2a89982fe4276880.js +23 -0
  10. package/apps/pwa/out/_next/static/chunks/1244.6c435dbf1bf21d8a.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1252.9e665904d3aa3b1a.js +32 -0
  12. package/apps/pwa/out/_next/static/chunks/1266.a46cc33cb6a72d75.js +104 -0
  13. package/apps/pwa/out/_next/static/chunks/{3955.6922286237f2ac2b.js → 1306.967240ede9a0f757.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
  15. package/apps/pwa/out/_next/static/chunks/{5628.6ddb2d5ffba4ff4c.js → 1401.22dfe92640a2b1ac.js} +4 -4
  16. package/apps/pwa/out/_next/static/chunks/1431-f7c78bd5be21e011.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1451-cdd35a8a0b31834b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{2573.387a707f6f9d720c.js → 1694.18debfd77562e56d.js} +2 -2
  19. package/apps/pwa/out/_next/static/chunks/1708-f03d587b7a7545c8.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1775-fa7152bdeff6c95f.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/178-4da509cd7266672a.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/{7910-6f139bcafd238b9f.js → 1850-522de4ee34957210.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/1876-c6f6e0ddcc76c6a1.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/1976.097066b072432242.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{1406.a1dc2ab6f8449374.js → 1978.eeb60a606dc5deac.js} +2 -2
  26. package/apps/pwa/out/_next/static/chunks/{3402.44b565b314f2263c.js → 2043.e233e3b5a3e790f5.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/2150.71b94e3348107c83.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2158.ebc6fc5a10280ab7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{3694.e0099884345f0198.js → 2216.802962c04f40a26e.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2294.7890edcfa046c97d.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/235.c89aaae4bcd6233a.js +74 -0
  32. package/apps/pwa/out/_next/static/chunks/239.de075467b5523469.js +287 -0
  33. package/apps/pwa/out/_next/static/chunks/{1200.6a37c202f9f17e9a.js → 249.ba7051590d603c8f.js} +3 -3
  34. package/apps/pwa/out/_next/static/chunks/2571.a6ac4e26c8618403.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/2610.e149cd564a08913e.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/2705.9816f3c244f8b85f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/2801.afeb8a4dae22f85f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{3935.16701e33f8982dc9.js → 2954.bbefc95d6b20e0d8.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/{aa57532f.510551854ff239b1.js → 2e0f720a.a0697c08e3806a60.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/3042.96ec235fe41c8d4e.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3097-8e358f158acef46b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3205-93b1abe28b4fb16a.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3273.b4434f0dcae7eb29.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3311.9cbc43ea0c90d60c.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{5930.8b4df3b46c32b05a.js → 3349.b5f09ee474d9533e.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/{5866.366966af47fdde5d.js → 3503.a47a9755fb4d97b0.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/{7900.096f455c7c1efc53.js → 3843.bad404d008893291.js} +2 -2
  49. package/apps/pwa/out/_next/static/chunks/3877-4b40e530b47e3bf9.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/435-ce2958253cf7de61.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/{8588.d1c6a2903727ce87.js → 4393.28fa5228d0eec217.js} +3 -3
  52. package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/{8062-7cd0bcc7f01455ba.js → 4415-b9d6a90960920a4a.js} +3 -3
  54. package/apps/pwa/out/_next/static/chunks/{8313-dfa1021bb58a46d6.js → 447-5b304de1fe098f43.js} +1 -1
  55. package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{6944.309f4e3ea54d1537.js → 4502.bdcc877abd437a05.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/4599-f95790fc5c65b8df.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{3072.01338851ca21a6f7.js → 46.57c783fa4884714f.js} +2 -2
  59. package/apps/pwa/out/_next/static/chunks/463-b9114e411f33728e.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/4659.a57d1f0c5d754cd2.js +36 -0
  61. package/apps/pwa/out/_next/static/chunks/4722-a847e7a28115035f.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/{8986.8e2e4efbfa655c59.js → 4757.67c6d7473a038e78.js} +1 -1
  63. package/apps/pwa/out/_next/static/chunks/4874-c86f878ec4502ad3.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/4891.3f80ba517a3b2373.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/{8205.282ca4bb62d54a0a.js → 4998.810ca8833084caa9.js} +2 -2
  66. package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{5789.2da35c258292e1e5.js → 5052.7dbb12a55d4f18f5.js} +1 -1
  68. package/apps/pwa/out/_next/static/chunks/5166-ca73b3e361085a6d.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5180-039f4a18b07ad387.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/5232.5a2ce4daf7a9e11d.js +115 -0
  71. package/apps/pwa/out/_next/static/chunks/{9770.5f75bc6088b16109.js → 5439.3fec6dbce29ecb36.js} +1 -1
  72. package/apps/pwa/out/_next/static/chunks/{1313-19f737e0222c4444.js → 5612-074d9a5e00dfac6a.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/5675-01989d524a84c505.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/5751.af641a1adf5ec697.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/5758-c6cb98714d18ab0c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/578eded8.b582637306e16964.js +122 -0
  77. package/apps/pwa/out/_next/static/chunks/{3969.272ee7f9fd6c62e5.js → 5790.5eb06a653ebd8571.js} +1 -1
  78. package/apps/pwa/out/_next/static/chunks/5853-4033e5bd5afbe06b.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/5904.97d70bb7f46b2db7.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{6540.c7bef57ad8f90a87.js → 5989.7ecd362c5c44b747.js} +3 -3
  81. package/apps/pwa/out/_next/static/chunks/{0ad6802e.ae7afb63fdcb4491.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
  82. package/apps/pwa/out/_next/static/chunks/{0966f8a1.745fcd44f64a87ea.js → 5a5078f8.2099200e5ea95e16.js} +1 -1
  83. package/apps/pwa/out/_next/static/chunks/6036-c302c34ff0b3d410.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/606.ef81c313381f4264.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/616.1af54a928b1ba704.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/6201.bc936f71f613a8e9.js +41 -0
  87. package/apps/pwa/out/_next/static/chunks/6204-fdc86e0e64c4f92d.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{2144.25b292396712196d.js → 6245.1182e007e9d230d9.js} +2 -2
  89. package/apps/pwa/out/_next/static/chunks/{363bfab3.9623b9f89363541f.js → 63699a35.17262e162bc514b2.js} +1 -1
  90. package/apps/pwa/out/_next/static/chunks/6420.494801a80030160c.js +27 -0
  91. package/apps/pwa/out/_next/static/chunks/{d96660fb.cbc21a2a88539dbb.js → 6549dad0.2740b25e51bf8f05.js} +7 -7
  92. package/apps/pwa/out/_next/static/chunks/{5564.9e72532188f57586.js → 6881.9e7955847640c7fe.js} +4 -4
  93. package/apps/pwa/out/_next/static/chunks/6931.fcdfb94141e67b3d.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/6991-8e081c6ce38c0ba1.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{3903.3ef4656c67572764.js → 7010.1bbd17a7f2b3e376.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7029.d1466acf55fae2ed.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7152-a123aa8e129c131f.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7455.196168fffac3b9c4.js +24 -0
  99. package/apps/pwa/out/_next/static/chunks/7638.6ca4770dd1129138.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/7649-f37d76260e5e2a5a.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/{2312.0c8b61e22d3136d7.js → 7679.32c40cdd14f20b4a.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/7751.04bfbd16b4c6cd0a.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/7864.b1ff31d4030b8994.js +148 -0
  104. package/apps/pwa/out/_next/static/chunks/7869-c47bd2c075c1fefa.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{4199.ce86b281fd0a60b7.js → 8442.2f09ca969d631615.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8445.2738dbd59a78c78c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8447.5510c439f9938c6d.js +286 -0
  108. package/apps/pwa/out/_next/static/chunks/8551.f762945c2cda2e95.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{fb7d20d5-6892502b6ee39ca6.js → 86961958-4b0689a5048f756b.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/8709.3c6019bb18f8554f.js +8 -0
  112. package/apps/pwa/out/_next/static/chunks/8759.c999528a0a907bf6.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/87f498e5-0881de09f2e44707.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{cb0f8df8.09a4a6be97e3fc5f.js → 892fd990.456232f326cc39c2.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/{837-81336ebaca8198a8.js → 8965-135a2c9eaa2464cb.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/8971-8d3b9c96f8a6c958.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9059.c8598d96f8e5e9cd.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9115.90447ae198b84eae.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9147.d9b0a02e0babc9b4.js +93 -0
  121. package/apps/pwa/out/_next/static/chunks/9204-83075f4b70c61cdc.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9244-c32ef14b5dc72bdf.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/930.2a9a30f964350c66.js +90 -0
  124. package/apps/pwa/out/_next/static/chunks/{8637.90f92d5c8db4732c.js → 9398.1f56e3f17795f43f.js} +1 -1
  125. package/apps/pwa/out/_next/static/chunks/9527.3e5ad31c891c5fcb.js +79 -0
  126. package/apps/pwa/out/_next/static/chunks/9571-4ac933e774d1225c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-9fc644de2d8edae3.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/approvals/page-0c9dace2db62bee8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f5e65c3dc9d89f2a.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/board/page-2a9c19b9a140b7b1.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/botlab/page-61533ad92141adfb.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/bots/page-112004ced6fd0329.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f733318c237a49d8.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/chat/page-51ea677d2d33bbc0.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/consult/page-428b41f2f9566e3c.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/control/page-1b29396ea90a61e5.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/decisions/page-cf83ec613ac904bf.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/design-check/page-3f4c0ecbc284bb5f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/editor/page-b63c322f54f70cc6.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/exec/page-fe328c4ee9aac6b4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/field/page-bfb855c584f0fb98.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/healthz/route-9fc644de2d8edae3.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/inside/page-47b1710c110eabd7.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/intake/page-42895214458bc6d2.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/layout-d03de0ebd8366e23.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live/page-3ed6c47e4b1c61c2.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/live-run/page-ae653e9bf261c738.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/loops/page-23f3f0a0209c0ac4.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/market/page-88c691273aae66f9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e187ac52a95538b3.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/morning/page-6e45828daed1295e.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/not-found-edb5d7287bb46186.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4a7eaacd93c3f6a5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ca073d43d74cc84.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1e9fee67b1199436.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-df1283ea963c6816.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/outputs/page-19fcf8d8301ccd18.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/page-5ab699e0303bbb40.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7cde0d29756984c5.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9d4c598e8ee22f7a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/sessions/page-cc1609a71f44ec62.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7659a9a1345bfaa9.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/settings/page-0afef60ecc0c4af5.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a3553949f8f34f5f.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/layout-9fc644de2d8edae3.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/setup/page-057a69702f3c67c7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/share/page-c0f0e570f3f74c73.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/showroom/page-1825071ae34e3b89.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/tasks/page-6244e3e135d8ccfc.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/term/{page-0a815f34367b6db6.js → page-da787e8a10b8a82e.js} +1 -1
  171. package/apps/pwa/out/_next/static/chunks/app/today/page-1316d32498e2be42.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/trace/page-4df94572e343de2e.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/vault/page-708969f7475e88c1.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c58add08c919a1dc.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workflows/page-a24847f45e5d5bf9.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/workspace/page-acfec65a3a60e22e.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-3dfc598e6fbde245.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-c658a626118411b7.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-4c73685fd891445b.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-6310f7e5de7dd01d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-51c326bf48610be1.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-d0beadf754da59b0.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-acd243bfbf3f6732.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/overlays/README.md +6 -0
  278. package/graphs/release/release-loop.yaml +33 -17
  279. package/graphs/units/verbs/make-doc.yaml +1 -0
  280. package/package.json +1 -1
  281. package/scripts/bench-metering-plan.ts +229 -0
  282. package/scripts/demo/demo1104-parallel-host.ts +56 -0
  283. package/scripts/demo/demo1104-parallel.ts +72 -0
  284. package/scripts/public-leak-baseline.txt +0 -1
  285. package/scripts/release-loop/docs-node.ts +4 -2
  286. package/scripts/release-loop/gate-image-pin.ts +116 -2
  287. package/scripts/release-loop/gate-node.ts +217 -25
  288. package/scripts/release-loop/gate-progress-sim.ts +73 -0
  289. package/scripts/release-loop/notes-repair.ts +18 -1
  290. package/scripts/release-loop/preflight.ts +188 -8
  291. package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
  292. package/scripts/release-loop/resume-release.ts +9 -7
  293. package/scripts/release-loop/resume.ts +13 -4
  294. package/scripts/release-loop/warm-control-forward.ts +178 -0
  295. package/scripts/retro-cycle.ts +30 -8
  296. package/scripts/rhythm/daily.ts +4 -1
  297. package/scripts/rhythm/linear-progress-sync.ts +28 -15
  298. package/scripts/ux-sim.ts +7 -1
  299. package/scripts/warm-pool-provider-config.ts +6 -1
  300. package/src/agent-mission/grok-auth-status.ts +78 -18
  301. package/src/agent-mission/mission-out.ts +2 -2
  302. package/src/agent-substrate/pr-reviewer.ts +147 -11
  303. package/src/agent-substrate/self-review-cli.ts +10 -2
  304. package/src/auto-research/research-fanout.ts +221 -0
  305. package/src/auto-research/research-turn.ts +282 -36
  306. package/src/autopilot/mission-codebase-gate.ts +7 -3
  307. package/src/cli/control-cli.ts +15 -6
  308. package/src/cli/log-event-names.ts +8 -0
  309. package/src/cli/setup-keys.ts +20 -8
  310. package/src/cli/tui-test-cli.ts +9 -5
  311. package/src/control-plane/ledger.ts +42 -4
  312. package/src/control-plane/member-tokens.ts +25 -2
  313. package/src/control-plane/ports.ts +8 -3
  314. package/src/control-plane/server.ts +26 -5
  315. package/src/core-turn/research-policy.ts +7 -1
  316. package/src/core-turn/run-core-turn.ts +186 -39
  317. package/src/core-turn/types.ts +2 -0
  318. package/src/dashboard/classic-sidetab-mission-job.ts +113 -24
  319. package/src/dashboard/classic-sidetab-mission-pair.ts +3 -2
  320. package/src/dashboard/classic-sidetab-mission-trio.ts +35 -12
  321. package/src/dashboard/classic-sidetab-mission.ts +2 -0
  322. package/src/dashboard/index.ts +9 -1
  323. package/src/dashboard/sidetab-runtime.ts +2 -0
  324. package/src/dashboard/visible-mission-diagnostics.ts +16 -0
  325. package/src/domains/retro-cycle-observation.ts +43 -0
  326. package/src/domains/retro-cycle.ts +13 -2
  327. package/src/domains/retro-proposals.ts +92 -0
  328. package/src/domains/retro-report.ts +6 -1
  329. package/src/graph-runner/graph-cli.ts +24 -1
  330. package/src/graph-runner/graph-grow-llm.ts +3 -1
  331. package/src/graph-runner/runner.ts +226 -30
  332. package/src/harness/harness-cli-command.ts +4 -2
  333. package/src/harness/harness-pod-dispatch.ts +3 -0
  334. package/src/index.ts +2 -2
  335. package/src/llm/child-first-llm-observation.ts +112 -0
  336. package/src/llm/provider-credentials.ts +60 -4
  337. package/src/llm/provider-failure-evidence.ts +44 -0
  338. package/src/llm.ts +170 -11
  339. package/src/mcp/client.ts +7 -0
  340. package/src/mcp/proxy-runtime.ts +6 -1
  341. package/src/mcp/server.ts +54 -0
  342. package/src/native-tool-catalog.ts +2 -2
  343. package/src/nexus/api/consult-requests.ts +18 -6
  344. package/src/nexus/api/discord-trigger-bot.ts +6 -6
  345. package/src/nexus/api/graphs-api.ts +4 -2
  346. package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
  347. package/src/nexus/api/telegram-trigger-bot.ts +6 -6
  348. package/src/nexus/boot/register-mcp-clients.ts +114 -8
  349. package/src/nexus/index.ts +15 -0
  350. package/src/nexus/outbound/grokbot-adapter.ts +71 -0
  351. package/src/nexus/outbound/router.ts +33 -13
  352. package/src/oauth/codex-owner-mirror.ts +47 -10
  353. package/src/onboarding/first-run.ts +44 -6
  354. package/src/preview/terminal.ts +22 -7
  355. package/src/prompt-enhance/enhance.ts +10 -0
  356. package/src/pty-shell/pty-write-provenance.ts +21 -3
  357. package/src/pty-shell/registry.ts +9 -2
  358. package/src/release-loop/proposal-auto-place.ts +83 -0
  359. package/src/research/axis-fanout.ts +40 -5
  360. package/src/research/lenses/second-order.ts +312 -0
  361. package/src/self-dev/dev-cli.ts +3 -1
  362. package/src/self-dev/draft-sweep.ts +31 -10
  363. package/src/self-dev/draft-triage-rules.ts +60 -3
  364. package/src/self-dev/run-supervisor.ts +152 -2
  365. package/src/self-implement/goal-author.ts +208 -23
  366. package/src/self-implement/graph-overlay-yaml.ts +151 -0
  367. package/src/self-implement/graph-yaml.ts +68 -2
  368. package/src/self-implement/orchestrator.ts +62 -15
  369. package/src/self-implement/test-scenario-request.ts +37 -6
  370. package/src/session/chat.ts +2 -2
  371. package/src/session-runtime/index.ts +37 -5
  372. package/src/sidetab-core/model.ts +205 -10
  373. package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
  374. package/src/sidetab-core/visible-agent-mission.ts +105 -47
  375. package/src/skills/tools/omni-search.ts +4 -2
  376. package/src/task-agent/parent-host.ts +19 -1
  377. package/src/task-agent/recall-inject.ts +98 -0
  378. package/src/task-agent/task-hand.ts +26 -7
  379. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +19 -1
  380. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +15 -0
  381. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
  382. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
  383. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +460 -96
  384. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
  385. package/src/task-orchestrator/surfaces/self-implement-pod.ts +38 -8
  386. package/src/tool-hints/gate.ts +45 -14
  387. package/src/tool-hints/signals.ts +1 -1
  388. package/src/tool-hints/types.ts +2 -0
  389. package/src/tool-runtime/browser-hand-runtime.ts +11 -1
  390. package/src/tool-runtime/browser-runtime.ts +31 -18
  391. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +152 -36
  392. package/src/tool-runtime/types.ts +2 -0
  393. package/src/tui/entry.ts +27 -7
  394. package/src/tui/sidetab/attach.ts +112 -0
  395. package/src/tui/sidetab/list.ts +3 -2
  396. package/src/tui-client/next-dashboard-runtime.ts +52 -0
  397. package/src/ux-sim/draft-inventory-builder.ts +2 -1
  398. package/src/ux-sim/linear-secretary.ts +4 -12
  399. package/src/ux-sim/mock-scenario-catalog.json +32 -29
  400. package/src/ux-sim/mock-scenario-catalog.ts +55 -3
  401. package/src/ux-sim/release-sim-rig.ts +62 -18
  402. package/src/ux-sim/service-key-setup.ts +63 -0
  403. package/src/version/packed-revision.json +1 -1
  404. package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +0 -1
  405. package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +0 -1
  406. package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +0 -1
  407. package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +0 -1
  408. package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +0 -1
  409. package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +0 -1
  410. package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +0 -1
  411. package/apps/pwa/out/_next/static/chunks/1961.a81b12872c3e93a9.js +0 -23
  412. package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +0 -1
  413. package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +0 -1
  414. package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +0 -1
  415. package/apps/pwa/out/_next/static/chunks/2268-53861f339e0b65a2.js +0 -1
  416. package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +0 -1
  417. package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +0 -1
  418. package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +0 -90
  419. package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +0 -1
  420. package/apps/pwa/out/_next/static/chunks/3113.d7472bbc27d580c7.js +0 -1
  421. package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +0 -1
  422. package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +0 -79
  423. package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +0 -286
  424. package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +0 -1
  425. package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +0 -1
  426. package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +0 -1
  427. package/apps/pwa/out/_next/static/chunks/4445.7990c76b3751a918.js +0 -115
  428. package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +0 -1
  429. package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +0 -1
  430. package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +0 -1
  431. package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +0 -1
  432. package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +0 -1
  433. package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +0 -94
  434. package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +0 -1
  435. package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +0 -36
  436. package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +0 -1
  437. package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +0 -93
  438. package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +0 -1
  439. package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/5824.da9527b15a3221e5.js +0 -1
  445. package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +0 -27
  447. package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +0 -104
  450. package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +0 -287
  452. package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +0 -1
  454. package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +0 -148
  463. package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +0 -24
  465. package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +0 -74
  470. package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/868.6e953be05bcf6dca.js +0 -41
  473. package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/8861-cc1fa1c7b920fa8e.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +0 -32
  482. package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +0 -8
  484. package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-79a8b5fee4c20871.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ca2d09128c585ca4.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/c7945435-b44d4dbe90ba0dcb.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +0 -122
  538. package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +0 -1
  544. /package/apps/pwa/out/_next/static/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
package/src/mcp/server.ts CHANGED
@@ -29,6 +29,7 @@ import { buildCliAgentTools } from '../cli/agent-cli.js';
29
29
  import { getUserConfig } from '../user-config.js';
30
30
  import type { TokenScope } from '../auth/scope.js';
31
31
  import { filterToolsForScope, isToolAllowedForScope } from '../nexus/api/mcp-public-allowlist.js';
32
+ import { normalizeRunId } from '../harness/harness-space.js';
32
33
 
33
34
  // ─── JSON-RPC shapes ─────────────────────────────────────────────
34
35
 
@@ -102,6 +103,30 @@ export interface McpServerContext {
102
103
  tokenScope?: TokenScope;
103
104
  }
104
105
 
106
+ /** Accept only an already-safe run identifier from standard MCP params._meta. */
107
+ function mcpRunId(params: Record<string, unknown> | undefined): string | undefined {
108
+ const meta = params?._meta;
109
+ if (!meta || typeof meta !== 'object' || Array.isArray(meta)) return undefined;
110
+ const value = (meta as Record<string, unknown>).elanousRunId;
111
+ if (typeof value !== 'string' || !/^[A-Za-z0-9_-]{1,64}$/.test(value)) return undefined;
112
+ const normalized = normalizeRunId(value);
113
+ return normalized === value ? value : undefined;
114
+ }
115
+
116
+ function logAsideRunIdDrop(toolName: string, params: Record<string, unknown> | undefined): void {
117
+ const meta = params?._meta;
118
+ const raw = meta && typeof meta === 'object' && !Array.isArray(meta)
119
+ ? (meta as Record<string, unknown>).elanousRunId
120
+ : undefined;
121
+ const reason = typeof raw !== 'string'
122
+ ? 'missing-or-non-string'
123
+ : !/^[A-Za-z0-9_-]{1,64}$/.test(raw)
124
+ ? 'invalid-format'
125
+ : normalizeRunId(raw) !== raw ? 'not-normalized' : 'validation-rejected';
126
+ try { debug.log('mcp-server.aside', 'elanous-tool-call-run-id-dropped', { toolName, reason }); }
127
+ catch { /* observation must not block the caller */ }
128
+ }
129
+
105
130
  /** Emit a `system.mcp.proxy_call` user-intent event for a single
106
131
  * tool dispatch. Best-effort — sink failures swallowed upstream by
107
132
  * `userIntentLogger.emit`, and the outer try/catch keeps the
@@ -177,8 +202,20 @@ export async function handleMcpRequest(
177
202
  const args = (req.params?.arguments as Record<string, unknown>) ?? {};
178
203
  const surface = ctx.surface ?? 'mcp';
179
204
  const rt = getToolRuntime(name);
205
+ const runId = ctx.clientName === 'aside' ? mcpRunId(req.params) : undefined;
206
+ if (ctx.clientName === 'aside' && !runId) logAsideRunIdDrop(name, req.params);
207
+ const asideReturn = runId !== undefined;
180
208
  const isExposedOnSurface = listToolRuntimes(surface).some(runtime => runtime.id === rt?.id);
181
209
  if (!rt || !isExposedOnSurface) {
210
+ if (asideReturn) {
211
+ try {
212
+ debug.log('mcp-server.aside', 'elanous-tool-call', { runId, toolName: name });
213
+ debug.log('mcp-server.aside', 'elanous-tool-result', {
214
+ runId, toolName: name, ok: false,
215
+ errorClass: rt ? 'tool_not_exposed' : 'unknown_tool',
216
+ });
217
+ } catch { /* observation must not block the caller */ }
218
+ }
182
219
  emitProxyCallIntent(name, ctx.origin, false, 'unknown_tool');
183
220
  return {
184
221
  ...base,
@@ -186,6 +223,10 @@ export async function handleMcpRequest(
186
223
  };
187
224
  }
188
225
  try {
226
+ if (asideReturn) {
227
+ try { debug.log('mcp-server.aside', 'elanous-tool-call', { runId, toolName: name }); }
228
+ catch { /* observation must not block the caller */ }
229
+ }
189
230
  const isMcpAgent = surface === 'mcp' && rt.id === 'agent';
190
231
  const agentArgs = isMcpAgent
191
232
  ? { ...args, run_in_background: args.run_in_background ?? true }
@@ -198,6 +239,7 @@ export async function handleMcpRequest(
198
239
  const out = await dispatchToolByName(name, agentArgs, {
199
240
  surface,
200
241
  ...(ctx.clientName ? { mcpClient: ctx.clientName } : {}),
242
+ ...(runId ? { runId } : {}),
201
243
  ...(agentTools ? {
202
244
  agentHostTools: agentTools.specs,
203
245
  agentCwd,
@@ -212,10 +254,22 @@ export async function handleMcpRequest(
212
254
  background: agentArgs.run_in_background === true,
213
255
  });
214
256
  }
257
+ if (asideReturn) {
258
+ const resultRecord = out && typeof out === 'object' ? out as Record<string, unknown> : {};
259
+ const toolOk = resultRecord.ok === false || resultRecord.isError === true
260
+ ? false
261
+ : resultRecord.ok === true ? true : null;
262
+ try { debug.log('mcp-server.aside', 'elanous-tool-result', { runId, toolName: name, ok: toolOk }); }
263
+ catch { /* observation must not block the caller */ }
264
+ }
215
265
  emitProxyCallIntent(name, ctx.origin, true);
216
266
  return { ...base, result: toMcpToolCallResult(out) };
217
267
  } catch (err) {
218
268
  const msg = err instanceof Error ? err.message : String(err);
269
+ if (asideReturn) {
270
+ try { debug.log('mcp-server.aside', 'elanous-tool-result', { runId, toolName: name, ok: false, errorClass: err instanceof Error ? err.name : 'unknown' }); }
271
+ catch { /* observation must not block the caller */ }
272
+ }
219
273
  emitProxyCallIntent(name, ctx.origin, false, msg);
220
274
  throw err;
221
275
  }
@@ -734,8 +734,8 @@ export const nativeToolCatalog: NativeToolCatalogEntry[] = [
734
734
  {
735
735
  id: 'elanous_linear_secretary',
736
736
  kind: 'other', aliases: ['ElanousLinearSecretary'], displayName: 'ElanousLinearSecretary',
737
- description: 'Ground a request in repository evidence and create a Linear parent issue with 3–5 assigned subtasks. Requires an explicit due date and verified evidence. Uses the configured project unless the request contains `projectless=true` and exactly one explicit `teamKey=<KEY>` token; never guesses a destination, date or citation.',
738
- promptSummary: '`elanous_linear_secretary` (ground and create a parent with 3–5 evidence-backed subtasks; team-only needs projectless=true plus one explicit teamKey=<KEY>)',
737
+ description: 'DEMO-only grounded Linear secretary. Create a dated evidence-backed parent with 3–5 subtasks, record a child progress/Done transition using actual intake records and approved browser evidence, or open one local pending approval per parent. Repeated approval calls return the existing card state; no external notifications are sent.',
738
+ promptSummary: '`elanous_linear_secretary` (DEMO create/progress/Done/evidence/approval; approval is local and sends nothing externally)',
739
739
  host: ['tui', 'mcp'], safety: ['mutating', 'network'], supportsParallel: false, defaultEnabled: true,
740
740
  intentScope: 'ops-fleet',
741
741
  },
@@ -2,9 +2,10 @@ import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, re
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { debug } from '../../debug/log.js';
5
- import { sendTelegramReport } from '../../telegram-report.js';
6
- import { getUserConfig } from '../../user-config.js';
5
+ import { getUserConfig, type UserConfig } from '../../user-config.js';
6
+ import { roleForKind } from '../../domains/telegram-kind-route.js';
7
7
  import { effectiveInstanceRoot } from '../../instance/resolve.js';
8
+ import { routeOutbound, type RouterDeps } from '../outbound/router.js';
8
9
  import { jsonResponse } from './json-response.js';
9
10
 
10
11
  export const CONSULT_REQUESTS_PATH = '/v1/consult-requests';
@@ -27,6 +28,8 @@ export interface ConsultRequestsDeps {
27
28
  * ⛔ Never `sendOutbound` here: it is a synchronous curl to this very daemon's `/v1/outbound`, so inside the
28
29
  * daemon it blocks the event loop until it times out (~25 s · `unreachable`) and the alert is lost (CS1 · 10-01). */
29
30
  send?: (text: string, kind: string) => unknown;
31
+ /** In-process ChannelAdapter delivery seams for mock verification. */
32
+ routeDeps?: RouterDeps;
30
33
  }
31
34
 
32
35
  function file(root: string): string {
@@ -114,12 +117,21 @@ export async function handleConsultRequests(req: Request, deps: ConsultRequestsD
114
117
  const alert = `📮 상담 문의 ${entry.receiptId} · ${entry.name}(${entry.kind === 'personal' ? '개인' : (entry.org ?? '회사')}) · 관심 ${entry.interest}\n앱에서 보기`;
115
118
  // Fire and forget — the receipt is already on disk; the answer must not wait for the channel.
116
119
  void Promise.resolve()
117
- .then(() => (deps.send ?? notifyInProcess)(alert, 'ops-alert'))
120
+ .then(() => deps.send ? deps.send(alert, 'ops-alert') : notifyInProcess(alert, 'ops-alert', deps.routeDeps))
118
121
  .catch((error: unknown) => { debug.log('consult.request', 'notify-failed', { receiptId: entry.receiptId, reason: error instanceof Error ? error.message : String(error) }); });
119
122
  return jsonResponse({ receiptId: entry.receiptId, receivedAt: entry.receivedAt }, 202);
120
123
  }
121
124
 
122
- async function notifyInProcess(text: string, kind: string): Promise<void> {
123
- const delivered = await sendTelegramReport(getUserConfig(), text, { markdown: false, kind });
124
- debug.log('consult.request', delivered ? 'notified' : 'notify-failed', { delivered, channels: [`telegram:${delivered ? 'ok' : 'fail'}`] });
125
+ function telegramOnlyConfig(cfg: UserConfig, kind: string): UserConfig {
126
+ // Deliberately replace all outbound policy for this one notification: it must stay Telegram-only.
127
+ // The existing Telegram sender resolves credentials and chat targets from cfg.telegram.
128
+ return { ...cfg, raw: { ...cfg.raw, outbound: { channels: [{ type: 'telegram' }], routes: { [kind]: ['telegram'] } } } };
129
+ }
130
+
131
+ async function notifyInProcess(text: string, kind: string, routeDeps: RouterDeps = {}): Promise<void> {
132
+ const cfg = getUserConfig();
133
+ const route = await routeOutbound(telegramOnlyConfig(cfg, kind), { text, markdown: false, kind, role: roleForKind(cfg, kind) }, routeDeps);
134
+ debug.log('consult.request', route.delivered ? 'notified' : 'notify-failed', {
135
+ delivered: route.delivered, channels: route.channels.map(channel => `telegram:${channel.ok ? 'ok' : 'fail'}`),
136
+ });
125
137
  }
@@ -111,9 +111,9 @@ export function createDiscordTriggerLogger(
111
111
  * DiscordEvent shape. The two were intentionally kept congruent
112
112
  * (`src/discord.ts:160-172` comment) so the wire is a near-identity
113
113
  * with `raw` carrying the full gateway payload for debugging. */
114
- export function toDiscordEvent(tap: DcTriggerEvent): DiscordEvent {
115
- const envelope = receiveChannelEvent('discord', tap);
116
- if (!envelope || envelope instanceof Promise) throw new Error('discord connector cannot normalize accepted tap');
114
+ export async function toDiscordEvent(tap: DcTriggerEvent): Promise<DiscordEvent> {
115
+ const envelope = await receiveChannelEvent('discord', tap);
116
+ if (!envelope) throw new Error('discord connector cannot normalize accepted tap');
117
117
  return {
118
118
  kind: tap.kind,
119
119
  channel: envelope.channel ?? tap.channel,
@@ -136,10 +136,10 @@ export function buildDiscordTriggerTap(
136
136
  return (tap: DcTriggerEvent): void => {
137
137
  // Fire-and-forget — workflow dispatch errors are surfaced via the
138
138
  // workflow daemon's lifecycle bus, not the gateway loop. Any
139
- // synchronous throw lands here so the chat reply (no-op in this
140
- // bot) keeps flowing.
139
+ // normalization and dispatch rejections land here so the gateway
140
+ // loop and other accepted taps keep flowing.
141
141
  void Promise.resolve()
142
- .then(() => dispatch(toDiscordEvent(tap)))
142
+ .then(async () => dispatch(await toDiscordEvent(tap)))
143
143
  .catch((err: unknown) => {
144
144
  const reason = err instanceof Error ? err.message : String(err);
145
145
  log(`workflow dispatch failed: ${reason}`);
@@ -207,11 +207,13 @@ function detailOf(id: string, source: 'core' | 'mine', editable: boolean, dir: s
207
207
  const group = (node as { group?: unknown }).group;
208
208
  return { node_id: nodeId, kind, recipe, max_visits: maxVisits, ...(typeof group === 'string' && group.trim() ? { group: group.trim() } : {}) };
209
209
  }),
210
- edges: spec.edges.map(({ from, to, on, map }) => ({
210
+ edges: spec.edges.map(({ from, to, on, map, branches, join }) => ({
211
211
  from,
212
212
  ...(to === undefined ? {} : { to }),
213
213
  ...(on === undefined ? {} : { on }),
214
214
  ...(map === undefined ? {} : { map }),
215
+ ...(branches === undefined ? {} : { branches }),
216
+ ...(join === undefined ? {} : { join }),
215
217
  })),
216
218
  });
217
219
  }
@@ -287,7 +289,7 @@ export function handleGraphsGet(pathname: string, dir = defaultGraphsDir(), deps
287
289
  terminal_nodes: flat.terminalNodes,
288
290
  graph_hash: graphVersionHash(flat),
289
291
  nodes: flat.nodes.map(({ nodeId, kind, recipe, maxVisits }) => ({ node_id: nodeId, kind, recipe, max_visits: maxVisits })),
290
- edges: flat.edges.map(({ from, to, on, map, fallback }) => ({ from, ...(to === undefined ? {} : { to }), ...(on === undefined ? {} : { on }), ...(map === undefined ? {} : { map }), ...(fallback === undefined ? {} : { fallback }) })),
292
+ edges: flat.edges.map(({ from, to, on, map, fallback, branches, join }) => ({ from, ...(to === undefined ? {} : { to }), ...(on === undefined ? {} : { on }), ...(map === undefined ? {} : { map }), ...(fallback === undefined ? {} : { fallback }), ...(branches === undefined ? {} : { branches }), ...(join === undefined ? {} : { join }) })),
291
293
  });
292
294
  } catch (error) {
293
295
  return jsonResponse({ error: 'unit-flatten-failed', id, message: error instanceof Error ? error.message : String(error) }, 422);
@@ -0,0 +1,206 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { debug } from '../../debug/log.js';
3
+ import { receiveChannelEvent } from '../outbound/router.js';
4
+ import { registerGrokbotAdapter } from '../outbound/grokbot-adapter.js';
5
+ import { createSession, listSessions } from '../../session/index.js';
6
+ import type { UserConfig } from '../../user-config.js';
7
+ import type { runTurn } from '../../session/chat.js';
8
+ import type { ChannelEnvelope } from '../outbound/router.js';
9
+
10
+ const DEFAULT_AGENT = 'COO';
11
+ const DEFAULT_POLL_INTERVAL_MS = 15_000;
12
+ const MAX_MESSAGE_BYTES = 64 * 1024;
13
+
14
+ export interface GrokbotPendingMessage {
15
+ id: string;
16
+ }
17
+
18
+ export interface GrokbotMailbox {
19
+ listPending(): Promise<GrokbotPendingMessage[]>;
20
+ /** Atomically move a pending request into processing; null means another consumer claimed it. */
21
+ claim(id: string): Promise<string | null>;
22
+ acknowledge(id: string, text: string): Promise<void>;
23
+ complete(id: string, text: string): Promise<void>;
24
+ sendPrompt(agent: string, prompt: string): Promise<{ preview?: string }>;
25
+ }
26
+
27
+ export interface NexusGrokbotTriggerBotOptions {
28
+ mailbox: GrokbotMailbox;
29
+ dispatch: (event: ChannelEnvelope) => Promise<string>;
30
+ pollIntervalMs?: number;
31
+ now?: () => string;
32
+ log?: (event: string, data: Record<string, unknown>) => void;
33
+ }
34
+
35
+ const GROKBOT_SESSION_CHAT_ID = -707151151;
36
+ const GROKBOT_SESSION_BOT_ID = 'grokbot-coo';
37
+
38
+ function grokbotMainSessionId(): string {
39
+ const existing = listSessions().find((session) => session.origin === 'grokbot' && session.personaId === 'grokbot-coo');
40
+ if (existing) return existing.id;
41
+ return createSession({
42
+ source: 'cli', sourceKind: 'telegram', origin: 'grokbot', personaId: 'grokbot-coo',
43
+ title: 'Grok Bot COO · 주 세션',
44
+ }).id;
45
+ }
46
+
47
+ /** Reuse one durable main-agent session for the bot's conversation across requests and restarts. */
48
+ export function createGrokbotMainSessionDispatcher(
49
+ userConfig: UserConfig,
50
+ runTurnImpl: typeof runTurn,
51
+ getSessionId: () => string = grokbotMainSessionId,
52
+ ): (event: ChannelEnvelope) => Promise<string> {
53
+ const sessionId = getSessionId();
54
+ return async (event) => {
55
+ const result = await runTurnImpl({
56
+ userConfig,
57
+ sessionId,
58
+ userText: event.text,
59
+ utteranceSurface: 'telegram',
60
+ tgChat: { botId: GROKBOT_SESSION_BOT_ID, chatId: GROKBOT_SESSION_CHAT_ID },
61
+ });
62
+ return result.text;
63
+ };
64
+ }
65
+
66
+ export interface NexusGrokbotTriggerBotHandle {
67
+ pollOnce(): Promise<void>;
68
+ start(): void;
69
+ stop(): Promise<void>;
70
+ }
71
+
72
+ function safeReason(error: unknown): string {
73
+ const text = error instanceof Error ? error.message : String(error);
74
+ return text.replace(/Bearer\s+\S+/gi, 'Bearer [redacted]').slice(0, 240);
75
+ }
76
+
77
+ function validId(id: string): boolean {
78
+ return /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/.test(id);
79
+ }
80
+
81
+ function runRemote(script: string, timeoutMs = 20_000): Promise<string> {
82
+ return new Promise((resolve, reject) => {
83
+ const child = spawn('ssh', ['-o', 'BatchMode=yes', 'box@grbot-coo', 'bash -s'], { stdio: ['pipe', 'pipe', 'ignore'] });
84
+ let stdout = '';
85
+ const timeout = setTimeout(() => child.kill('SIGTERM'), timeoutMs);
86
+ child.stdout.setEncoding('utf8');
87
+ child.stdout.on('data', (chunk: string) => { stdout += chunk; });
88
+ child.on('error', () => { clearTimeout(timeout); reject(new Error('grokbot transport unavailable')); });
89
+ child.on('close', (code) => {
90
+ clearTimeout(timeout);
91
+ if (code === 0) resolve(stdout.trimEnd());
92
+ else reject(new Error('grokbot transport failed'));
93
+ });
94
+ child.stdin.end(script);
95
+ });
96
+ }
97
+
98
+ function encoded(value: string): string {
99
+ const bytes = Buffer.from(value, 'utf8');
100
+ if (bytes.byteLength > MAX_MESSAGE_BYTES) throw new Error('grokbot message exceeds 64 KiB');
101
+ return bytes.toString('base64');
102
+ }
103
+
104
+ function remoteWrite(relativePath: string, value: string): string {
105
+ if (!/^[A-Za-z0-9_./-]+$/.test(relativePath)) throw new Error('invalid grokbot output path');
106
+ const body = encoded(value);
107
+ const target = `"$HOME/${relativePath}"`;
108
+ return `set -eu\nmkdir -p "$(dirname ${target})"\nprintf '%s' '${body}' | base64 -d > ${target}\n`;
109
+ }
110
+
111
+ /** SSH-only transport to the COO bot host. The gateway credential remains on that host. */
112
+ export function createSshGrokbotMailbox(): GrokbotMailbox {
113
+ return {
114
+ async listPending() {
115
+ const output = await runRemote(`set -eu\nfor f in "$HOME"/elanous-inbox/*.txt; do\n [ -f "$f" ] || continue\n b=\${f##*/}; printf '%s\\n' "\${b%.txt}"\ndone\n`);
116
+ return output.split('\n').filter(validId).map((id) => ({ id }));
117
+ },
118
+ async claim(id) {
119
+ if (!validId(id)) throw new Error('invalid grokbot request id');
120
+ const output = await runRemote(`set -eu\nroot="$HOME/elanous-inbox"\nmkdir -p "$root/processing"\nsrc="$root/${id}.txt"\ndst="$root/processing/${id}.txt"\n[ -f "$src" ] || exit 3\n[ ! -e "$dst" ] || exit 4\nmv "$src" "$dst"\nbase64 "$dst" | tr -d '\\n'\n`);
121
+ return Buffer.from(output, 'base64').toString('utf8');
122
+ },
123
+ async acknowledge(id, text) {
124
+ if (!validId(id)) throw new Error('invalid grokbot request id');
125
+ await runRemote(`${remoteWrite(`elanous-outbox/${id}.ack`, text)}printf '%s\\n' "$(date -Is)" >> "$HOME/elanous-inbox/processing/${id}.accepted"\n`);
126
+ },
127
+ async complete(id, text) {
128
+ if (!validId(id)) throw new Error('invalid grokbot request id');
129
+ await runRemote(`${remoteWrite(`elanous-outbox/${id}.md`, text)}mkdir -p "$HOME/elanous-inbox/done"\nif [ -f "$HOME/elanous-inbox/processing/${id}.txt" ]; then mv "$HOME/elanous-inbox/processing/${id}.txt" "$HOME/elanous-inbox/done/${id}.txt"; fi\n`);
130
+ },
131
+ async sendPrompt(agent, prompt) {
132
+ if (agent !== DEFAULT_AGENT) throw new Error('grokbot agent is not allowlisted');
133
+ const body = encoded(prompt);
134
+ const script = `set -eu\ntoken=$(jq -er '.token | strings | select(length > 0)' "$HOME/sand-data/gateway.json")\nagent=$(curl -fsS -m 15 -X POST http://127.0.0.1:1340/api/listAgents -H 'Content-Type: application/json' -H "Authorization: Bearer $token" -d '{}' | jq -er '.[] | select(.name == "COO") | .id' | head -n 1)\n[ -n "$agent" ]\nprintf '%s' '${body}' | base64 -d | jq -Rs --arg agentId "$agent" '{agentId:$agentId,prompt:.}' | curl -fsS -m 30 -X POST http://127.0.0.1:1340/api/sendPrompt -H 'Content-Type: application/json' -H "Authorization: Bearer $token" --data-binary @- | jq -c '{preview:(.lastMessagePreview // .preview // "")}'\n`;
135
+ const response = await runRemote(script, 45_000);
136
+ const parsed = JSON.parse(response) as { preview?: unknown };
137
+ return { ...(typeof parsed.preview === 'string' && parsed.preview ? { preview: parsed.preview } : {}) };
138
+ },
139
+ };
140
+ }
141
+
142
+ export function createNexusGrokbotTriggerBot(options: NexusGrokbotTriggerBotOptions): NexusGrokbotTriggerBotHandle {
143
+ const now = options.now ?? (() => new Date().toISOString());
144
+ const log = options.log ?? ((event, data) => debug.log('channel.grokbot', event, data));
145
+ const unregister = registerGrokbotAdapter({
146
+ sendPrompt: (agent, prompt) => options.mailbox.sendPrompt(agent, prompt),
147
+ now,
148
+ log,
149
+ });
150
+ let stopped = false;
151
+ let polling = false;
152
+ let timer: ReturnType<typeof setInterval> | undefined;
153
+ let currentPoll: Promise<void> | undefined;
154
+
155
+ const pollOnce = async (): Promise<void> => {
156
+ if (stopped || polling) return currentPoll;
157
+ polling = true;
158
+ currentPoll = (async () => {
159
+ try {
160
+ const messages = await options.mailbox.listPending();
161
+ for (const { id } of messages) {
162
+ if (stopped) break;
163
+ let text: string | null;
164
+ try { text = await options.mailbox.claim(id); }
165
+ catch (error) { log('failure', { id, failedAt: now(), reason: safeReason(error), stage: 'claim' }); continue; }
166
+ if (text === null) continue;
167
+ try {
168
+ const kind = /^(승인|보류|수정)(?:\s|[::]|$)/.test(text.trim()) ? 'decision' : 'request';
169
+ const envelope = await receiveChannelEvent('grokbot', { id, text, kind });
170
+ if (!envelope || envelope instanceof Promise) throw new Error('grokbot request normalization failed');
171
+ await options.mailbox.acknowledge(id, 'OP 접수 — 답을 준비 중입니다.');
172
+ const reply = await options.dispatch(envelope);
173
+ if (!reply.trim()) throw new Error('main session returned an empty reply');
174
+ await options.mailbox.complete(id, reply);
175
+ log('reply', { id, repliedAt: now(), replyChars: reply.length });
176
+ } catch (error) {
177
+ const reason = safeReason(error);
178
+ log('failure', { id, failedAt: now(), reason, stage: 'dispatch-or-reply' });
179
+ try { await options.mailbox.complete(id, '요청을 처리하지 못했습니다. 주 세션 연결과 eln logs의 channel.grokbot 기록을 확인해 주세요.'); }
180
+ catch (replyError) { log('failure', { id, failedAt: now(), reason: safeReason(replyError), stage: 'failure-reply' }); }
181
+ }
182
+ }
183
+ } catch (error) {
184
+ log('failure', { failedAt: now(), reason: safeReason(error), stage: 'poll' });
185
+ }
186
+ })().finally(() => { polling = false; });
187
+ return currentPoll;
188
+ };
189
+
190
+ return {
191
+ pollOnce,
192
+ start() {
193
+ if (stopped || timer) return;
194
+ void pollOnce();
195
+ timer = setInterval(() => { void pollOnce(); }, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
196
+ timer.unref?.();
197
+ },
198
+ async stop() {
199
+ stopped = true;
200
+ if (timer) clearInterval(timer);
201
+ timer = undefined;
202
+ await currentPoll;
203
+ unregister();
204
+ },
205
+ };
206
+ }
@@ -123,9 +123,9 @@ export function createTelegramTriggerLogger(
123
123
  * TelegramEvent shape. Congruent fields (`src/telegram.ts:166-180`
124
124
  * comment) so the wire is a near-identity with `raw` carrying the
125
125
  * full payload (messageId · isDm) for debugging. */
126
- export function toTelegramEvent(tap: TgTriggerEvent): TelegramEvent {
127
- const envelope = receiveChannelEvent('telegram', tap);
128
- if (!envelope || envelope instanceof Promise) throw new Error('telegram connector cannot normalize accepted tap');
126
+ export async function toTelegramEvent(tap: TgTriggerEvent): Promise<TelegramEvent> {
127
+ const envelope = await receiveChannelEvent('telegram', tap);
128
+ if (!envelope) throw new Error('telegram connector cannot normalize accepted tap');
129
129
  return {
130
130
  kind: tap.kind,
131
131
  chat: envelope.channel ?? tap.chat,
@@ -149,10 +149,10 @@ export function buildTelegramTriggerTap(
149
149
  return (tap: TgTriggerEvent): void => {
150
150
  // Fire-and-forget — workflow dispatch errors surface via the
151
151
  // workflow daemon's lifecycle bus, not the polling loop. Any
152
- // synchronous throw lands here so the chat reply (no-op in this
153
- // bot) keeps flowing.
152
+ // normalization and dispatch rejections land here so the polling
153
+ // loop and other accepted taps keep flowing.
154
154
  void Promise.resolve()
155
- .then(() => dispatch(toTelegramEvent(tap)))
155
+ .then(async () => dispatch(await toTelegramEvent(tap)))
156
156
  .catch((err: unknown) => {
157
157
  const reason = err instanceof Error ? err.message : String(err);
158
158
  log(`workflow dispatch failed: ${reason}`);
@@ -28,7 +28,7 @@
28
28
  // daemon exit.
29
29
 
30
30
  import type { McpServerSpec } from '../../user-config.js';
31
- import { McpClient, McpConnectionError, type McpTool, type McpToolCallResult } from '../../mcp/client.js';
31
+ import { McpClient, McpConnectionError, type McpCallMeta, type McpTool, type McpToolCallResult } from '../../mcp/client.js';
32
32
  import {
33
33
  createMcpProxyRuntime,
34
34
  createMcpToolAuthorizer,
@@ -41,7 +41,8 @@ import { listNodeKinds } from '../../graph-kinds/registry.js';
41
41
  import { syncInstalledPluginNodes } from '../../graph-kinds/installed-plugin-nodes.js';
42
42
  import { listInstalledPlugins } from '../../plugins/install/plugin-install.js';
43
43
  import { pluginEnv, credentialStatus } from '../../plugins/install/plugin-credentials.js';
44
- import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
44
+ import { getHarnessRunId } from '../../harness/harness-space.js';
45
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
45
46
  import { join, resolve, sep } from 'node:path';
46
47
 
47
48
  export interface McpClientsHandle {
@@ -143,6 +144,8 @@ export interface RegisterMcpClientsOpts {
143
144
  toolIndexStore?: McpToolIndexStore;
144
145
  /** `lazy` 자식의 SIGTERM→SIGKILL 유예(ms). 기본 2500 — 종료 3초 계약 안쪽. */
145
146
  lazyShutdownGraceMs?: number;
147
+ /** BROWSER-ROUNDTRIP-ASIDE test seam; production defaults to the state-root JSONL ledger. */
148
+ asideLedger?: AsideRoundtripLedger;
146
149
  }
147
150
 
148
151
  /** 한 서버가 지난 부팅에서 알린 툴 목록. `mcp-tool-index.json` 의 값. */
@@ -156,6 +159,77 @@ export interface McpToolIndexStore {
156
159
 
157
160
  export const MCP_TOOL_INDEX_FILENAME = 'mcp-tool-index.json';
158
161
 
162
+ export interface AsideRoundtripEntry {
163
+ runId: string;
164
+ phase: 'call' | 'result';
165
+ toolName: string;
166
+ /** null means the caller did not provide a reason; do not invent one. */
167
+ reason: string | null;
168
+ at: string;
169
+ ok?: boolean;
170
+ classification?: string;
171
+ outputLength?: number;
172
+ errorClass?: string;
173
+ }
174
+
175
+ export interface AsideRoundtripLedger {
176
+ append(entry: AsideRoundtripEntry): void;
177
+ list(runId: string): AsideRoundtripEntry[];
178
+ }
179
+
180
+ const ASIDE_RUN_LEDGER_FILENAME = 'aside-run-roundtrip.jsonl';
181
+
182
+ /** Persist only the run join and result receipt metadata, never prompt/result contents. */
183
+ export function defaultAsideRoundtripLedger(root: string = elanousStateRoot()): AsideRoundtripLedger {
184
+ const file = join(root, ASIDE_RUN_LEDGER_FILENAME);
185
+ return {
186
+ append(entry) {
187
+ try {
188
+ mkdirSync(root, { recursive: true });
189
+ appendFileSync(file, `${JSON.stringify(entry)}\n`, 'utf8');
190
+ } catch (error) {
191
+ try { debug.log('mcp-client.aside', 'ledger-append-failed', { errorClass: error instanceof Error ? error.name : 'unknown' }); }
192
+ catch { /* a ledger failure must not block the MCP call */ }
193
+ }
194
+ },
195
+ list(runId) {
196
+ try {
197
+ return readFileSync(file, 'utf8').split('\n').flatMap((line) => {
198
+ if (!line.trim()) return [];
199
+ try {
200
+ const row = JSON.parse(line) as AsideRoundtripEntry;
201
+ return row && row.runId === runId && (row.phase === 'call' || row.phase === 'result') ? [row] : [];
202
+ } catch { return []; }
203
+ });
204
+ } catch { return []; }
205
+ },
206
+ };
207
+ }
208
+
209
+ function asideReason(args: Record<string, unknown>): string | null {
210
+ const raw = args.reason;
211
+ return typeof raw === 'string' && raw.trim().length > 0
212
+ ? redactSecretText(raw.trim()).slice(0, 240)
213
+ : null;
214
+ }
215
+
216
+ function asidePrompt(args: Record<string, unknown>, runId: string, reason: string | null): Record<string, unknown> {
217
+ if (typeof args.prompt !== 'string') return args;
218
+ const joinLine = `elanous 런 ${runId} · 결과는 elanous 도구로 돌려라.`;
219
+ if (args.prompt.includes(joinLine)) return args;
220
+ const instructions = [
221
+ joinLine,
222
+ ...(reason ? [`Delegation reason: ${reason}.`] : []),
223
+ 'Use TaskGet to load this run’s task context, then return findings through Elanous MCP tools to the same runId. Keep browser credentials in the browser.',
224
+ ].join(' ');
225
+ return { ...args, prompt: `${instructions}\n\n${args.prompt}` };
226
+ }
227
+
228
+ function asideTextLength(result: McpToolCallResult): number {
229
+ return (result.content ?? []).reduce((length, block) =>
230
+ block.type === 'text' && typeof block.text === 'string' ? length + block.text.length : length, 0);
231
+ }
232
+
159
233
  /** 지연 기동 자식의 정리 유예. `McpClient` 기본 5000ms 는 「SIGTERM 3초 안에
160
234
  * 안 끝남」이던 classic 종료 계약을 넘긴다 — 2500ms 면 SIGKILL 까지 3초 안쪽. */
161
235
  const DEFAULT_LAZY_SHUTDOWN_GRACE_MS = 2500;
@@ -209,11 +283,11 @@ class DeferredMcpClient implements DeferredInner {
209
283
  return this.inner.listTools();
210
284
  }
211
285
 
212
- async callTool(name: string, args: Record<string, unknown>): Promise<McpToolCallResult> {
286
+ async callTool(name: string, args: Record<string, unknown>, meta?: McpCallMeta): Promise<McpToolCallResult> {
213
287
  await this.ensureStarted();
214
288
  // ⚠️ 기동 «뒤»의 inner.callTool 을 부른다 — 자격증명 마스킹 래퍼가
215
289
  // createClient 직후 client.callTool 에 씌워지므로 그 래퍼를 탄다.
216
- return this.inner.callTool(name, args);
290
+ return this.inner.callTool(name, args, meta);
217
291
  }
218
292
 
219
293
  async dispose(): Promise<void> {
@@ -259,6 +333,8 @@ export async function registerMcpClients(
259
333
  // A boot owns its ledger: same configured ids in concurrent/restarted boots
260
334
  // cannot inherit grants or revoke one another's authorization lifetime.
261
335
  const authorizer = createMcpToolAuthorizer();
336
+ let asideLedger = opts.asideLedger;
337
+ const asideLedgerFor = (): AsideRoundtripLedger => (asideLedger ??= defaultAsideRoundtripLedger());
262
338
  // FU3 (2026-05-13) — pipe McpClient lifecycle events into elanous's
263
339
  // keytrace logger so `mcp.client.spawn / .ready / .exit / .parse-error
264
340
  // / .stderr` all land in the daemon's debug log. Without this hook
@@ -420,14 +496,44 @@ export async function registerMcpClients(
420
496
  let client: McpClient | undefined;
421
497
  try {
422
498
  client = createClient(spec) as McpClient;
423
- if (!opts.createClient && spec.transport === 'stdio') {
499
+ if (spec.transport === 'stdio' && (!opts.createClient || spec.id === 'aside')) {
424
500
  const originalCallTool = client.callTool.bind(client);
425
- client.callTool = async (name: string, args: Record<string, unknown>): Promise<McpToolCallResult> => {
426
- const values = injectedValuesByServer.get(spec.id) ?? [];
501
+ client.callTool = async (name: string, args: Record<string, unknown>, meta?: McpCallMeta): Promise<McpToolCallResult> => {
502
+ // Aside test clients use this same invocation boundary but bypass production credential injection.
503
+ const values = opts.createClient ? [] : injectedValuesByServer.get(spec.id) ?? [];
504
+ const isAsideExec = spec.id === 'aside' && name === 'exec';
505
+ const runId = isAsideExec ? (meta?.elanousRunId ?? getHarnessRunId()).trim() : '';
506
+ const reason = isAsideExec ? asideReason(args) : null;
507
+ const ledger = isAsideExec && runId ? asideLedgerFor() : undefined;
508
+ const now = () => new Date().toISOString();
509
+ const appendReceipt = (entry: AsideRoundtripEntry) => {
510
+ if (!ledger || !runId) return;
511
+ try { ledger.append(entry); } catch { /* bookkeeping must not block an MCP call */ }
512
+ };
513
+ const callArgs = isAsideExec && runId ? asidePrompt(args, runId, reason) : args;
514
+ if (isAsideExec && runId) {
515
+ try { debug.log('mcp-client.aside', 'exec-request', { runId, reason, toolName: name }); }
516
+ catch { /* observability is best-effort */ }
517
+ appendReceipt({ runId, phase: 'call', toolName: name, reason, at: now() });
518
+ }
427
519
  try {
428
- const result = await originalCallTool(name, args);
520
+ const result = await originalCallTool(name, callArgs, meta);
521
+ if (isAsideExec && runId) {
522
+ const isError = result.isError === true;
523
+ const classification = isError ? 'mcp-server-error' : undefined;
524
+ const outputLength = asideTextLength(result);
525
+ appendReceipt({ runId, phase: 'result', toolName: name, reason, at: now(), ok: !isError, ...(classification ? { classification } : {}), outputLength });
526
+ try { debug.log('mcp-client.aside', 'exec-result', { runId, reason, toolName: name, ok: !isError, ...(classification ? { classification } : {}), isError, outputLength }); }
527
+ catch { /* observability is best-effort */ }
528
+ }
429
529
  return maskInjectedValues(result, values) as McpToolCallResult;
430
530
  } catch (err) {
531
+ if (isAsideExec && runId) {
532
+ const errorClass = err instanceof Error ? err.name : 'unknown';
533
+ appendReceipt({ runId, phase: 'result', toolName: name, reason, at: now(), ok: false, classification: 'mcp-transport-error', errorClass });
534
+ try { debug.log('mcp-client.aside', 'exec-error', { runId, reason, toolName: name, callToolRejected: true, errorClass }); }
535
+ catch { /* observability is best-effort */ }
536
+ }
431
537
  if (err instanceof Error) err.message = redactValues(err.message, values);
432
538
  else throw new Error(redactValues(String(err), values));
433
539
  throw err;