elanous 0.2.42 → 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 (764) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/08334415.f0e80896acbef722.js +1 -0
  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/{2160.a097e7b138ae1c55.js → 118.2a89982fe4276880.js} +1 -1
  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/1306.967240ede9a0f757.js +24 -0
  14. package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
  15. package/apps/pwa/out/_next/static/chunks/{4043.6b91203436c9c86b.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/{6632.0eac1c554f8f2ef3.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/1850-522de4ee34957210.js +1 -0
  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/{3507.97e1977bc4d5fb0a.js → 1978.eeb60a606dc5deac.js} +2 -2
  26. package/apps/pwa/out/_next/static/chunks/2043.e233e3b5a3e790f5.js +1 -0
  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/2216.802962c04f40a26e.js +64 -0
  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/{5885.0a3e52c8faccec98.js → 239.de075467b5523469.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/249.ba7051590d603c8f.js +226 -0
  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/2954.bbefc95d6b20e0d8.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/2e0f720a.a0697c08e3806a60.js +1 -0
  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/{1487.2f67b79444062da6.js → 3349.b5f09ee474d9533e.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/3503.a47a9755fb4d97b0.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/3843.bad404d008893291.js +77 -0
  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/4393.28fa5228d0eec217.js +149 -0
  52. package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/{8673-bab689a55f7e13b9.js → 4415-b9d6a90960920a4a.js} +3 -3
  54. package/apps/pwa/out/_next/static/chunks/447-5b304de1fe098f43.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{8262.ddc03e06b733f184.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/{1262.e804feb8fd1acb8c.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/{1063.2fb8a9dc55c731f2.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/{6377.bc7df239edbff244.js → 4891.3f80ba517a3b2373.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/4998.810ca8833084caa9.js +62 -0
  66. package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{3482.a9ae9d2ad6a5bd97.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/5439.3fec6dbce29ecb36.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/5612-074d9a5e00dfac6a.js +1 -0
  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/5790.5eb06a653ebd8571.js +34 -0
  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/{3347.f846266b5e5f3ede.js → 5989.7ecd362c5c44b747.js} +3 -3
  81. package/apps/pwa/out/_next/static/chunks/{73d2eb0e.4966ad55293c801a.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
  82. package/apps/pwa/out/_next/static/chunks/{7a98bc80.fa935989e829f9c2.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/{7411.9b4b8b747dc7b802.js → 6245.1182e007e9d230d9.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{b450776b.3db34d8d965f82d3.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/{e8543907.5b040a5f22a0b0e5.js → 6549dad0.2740b25e51bf8f05.js} +1 -1
  92. package/apps/pwa/out/_next/static/chunks/{9427.96aa912ddb5801e0.js → 6881.9e7955847640c7fe.js} +17 -17
  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/7010.1bbd17a7f2b3e376.js +1 -0
  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/7679.32c40cdd14f20b4a.js +1 -0
  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/{8138.6c10b2a356d52fca.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/{9415.69e4a21c60c7d2db.js → 8551.f762945c2cda2e95.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/86961958-4b0689a5048f756b.js +1 -0
  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/{9a852a62-6192a6ea9346ced3.js → 87f498e5-0881de09f2e44707.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{3d0154af.5331fec737ffe8c3.js → 892fd990.456232f326cc39c2.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/8965-135a2c9eaa2464cb.js +1 -0
  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/9398.1f56e3f17795f43f.js +1 -0
  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-da787e8a10b8a82e.js +1 -0
  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/_next/static/css/d1f8bb401740a549.css +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/catalog/external-commands.yaml +5 -3
  279. package/catalog/meta/catalogVersion.yaml +2 -1
  280. package/catalog/signing/catalog-signing-public.pem +3 -0
  281. package/graphs/intake/intake-daily.yaml +16 -0
  282. package/graphs/intake/news-sources.yaml +1 -0
  283. package/graphs/intake/recipes.yaml +7 -0
  284. package/graphs/overlays/README.md +6 -0
  285. package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
  286. package/graphs/profiles/local.yaml +5 -0
  287. package/graphs/profiles/pod.yaml +4 -0
  288. package/graphs/release/release-loop.yaml +33 -17
  289. package/graphs/units/verbs/make-doc.yaml +1 -0
  290. package/package.json +6 -2
  291. package/plugins/demo-absorption-briefing/plugin.json +18 -0
  292. package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
  293. package/plugins/demo-browser-hand/plugin.json +13 -0
  294. package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
  295. package/plugins/demo-linear-secretary/plugin.json +15 -0
  296. package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
  297. package/plugins/demo-plugin-wizard/plugin.json +11 -0
  298. package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
  299. package/plugins/demo-research/plugin.json +16 -0
  300. package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
  301. package/plugins/demo-video-briefing/plugin.json +15 -0
  302. package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
  303. package/scripts/bench-metering-plan.ts +229 -0
  304. package/scripts/build-signed-catalog.ts +48 -0
  305. package/scripts/ci-typecheck-main-delta.sh +88 -0
  306. package/scripts/codex-fallback-live-probe.ts +1 -1
  307. package/scripts/demo/demo1104-parallel-host.ts +56 -0
  308. package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
  309. package/scripts/demo/demo1104-parallel.ts +72 -0
  310. package/scripts/demo/demo1104-stage.config.ts +21 -0
  311. package/scripts/demo/demo1104-stage.ts +316 -0
  312. package/scripts/goal-method-audit.ts +17 -1
  313. package/scripts/graph-units/land-enqueue.ts +90 -0
  314. package/scripts/hooks/codex-notify.sh +32 -0
  315. package/scripts/install.sh +10 -38
  316. package/scripts/landing-heal/land-plan.ts +57 -0
  317. package/scripts/public-leak-baseline.txt +0 -1
  318. package/scripts/release-loop/auto-approve-node.ts +1 -1
  319. package/scripts/release-loop/docs-node.ts +4 -2
  320. package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
  321. package/scripts/release-loop/gate-image-pin.ts +116 -2
  322. package/scripts/release-loop/gate-method.ts +139 -0
  323. package/scripts/release-loop/gate-node.ts +395 -43
  324. package/scripts/release-loop/gate-progress-sim.ts +73 -0
  325. package/scripts/release-loop/gate-traffic-mode.ts +151 -3
  326. package/scripts/release-loop/node-verdict.ts +38 -25
  327. package/scripts/release-loop/notes-repair.ts +18 -1
  328. package/scripts/release-loop/preflight.ts +544 -10
  329. package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
  330. package/scripts/release-loop/resume-release.ts +9 -7
  331. package/scripts/release-loop/resume.ts +13 -4
  332. package/scripts/release-loop/unattended-release.ts +20 -9
  333. package/scripts/release-loop/warm-control-forward.ts +178 -0
  334. package/scripts/retro-cycle.ts +30 -8
  335. package/scripts/rhythm/daily.ts +39 -4
  336. package/scripts/rhythm/linear-progress-sync.ts +311 -0
  337. package/scripts/ux-sim.ts +7 -1
  338. package/scripts/video-pipeline.ts +9 -1
  339. package/scripts/warm-pool-provider-config.ts +35 -7
  340. package/src/acp/agent-manager.ts +1 -0
  341. package/src/acp/codex-app-server-agent.ts +33 -0
  342. package/src/acp/codex-app-server-client.ts +153 -16
  343. package/src/acp/core-turn-bridge.ts +17 -12
  344. package/src/acp/event-router.ts +20 -1
  345. package/src/acp/server.ts +6 -0
  346. package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
  347. package/src/agent-mission/claude-headless.ts +4 -1
  348. package/src/agent-mission/codex-exec.ts +105 -0
  349. package/src/agent-mission/driver.ts +192 -11
  350. package/src/agent-mission/grok-auth-status.ts +107 -0
  351. package/src/agent-mission/hand-hooks.ts +101 -0
  352. package/src/agent-mission/mission-cli.ts +56 -21
  353. package/src/agent-mission/mission-hand-reply.ts +118 -0
  354. package/src/agent-mission/mission-line.ts +180 -0
  355. package/src/agent-mission/mission-out.ts +256 -18
  356. package/src/agent-mission/tool-install.ts +122 -11
  357. package/src/agent-substrate/pr-reviewer.ts +147 -11
  358. package/src/agent-substrate/self-review-cli.ts +10 -2
  359. package/src/agents/general-purpose.md +1 -1
  360. package/src/auto-research/research-fanout.ts +221 -0
  361. package/src/auto-research/research-turn.ts +362 -31
  362. package/src/autopilot/mission-codebase-gate.ts +7 -3
  363. package/src/autopilot/pr-manager.ts +31 -3
  364. package/src/boot/daemon-tools/self-implement.ts +3 -1
  365. package/src/boot/daemon-tools/web-search.ts +1 -2
  366. package/src/briefing/brief-items.ts +55 -11
  367. package/src/cli/agent-cli.ts +2 -1
  368. package/src/cli/catalog-cli.ts +31 -0
  369. package/src/cli/connector-cli.ts +16 -0
  370. package/src/cli/control-cli.ts +15 -6
  371. package/src/cli/doctor-fix.ts +2 -2
  372. package/src/cli/intake-source-cli.ts +44 -8
  373. package/src/cli/log-event-names.ts +8 -0
  374. package/src/cli/msg-cli.ts +32 -3
  375. package/src/cli/pr-cli.ts +21 -1
  376. package/src/cli/pr-land-heavy-remote.ts +44 -6
  377. package/src/cli/pr-land-overlap-evidence.ts +13 -1
  378. package/src/cli/pr-land-pod-shadow-job.ts +143 -5
  379. package/src/cli/pr-land-pod-shadow.ts +9 -2
  380. package/src/cli/release-checklist-read-cli.ts +44 -16
  381. package/src/cli/release-cli.ts +23 -3
  382. package/src/cli/research-cli.ts +9 -0
  383. package/src/cli/setup-cli.ts +166 -6
  384. package/src/cli/setup-keys.ts +199 -0
  385. package/src/cli/task-plugin-wizard-host.ts +114 -0
  386. package/src/cli/tasks-cli.ts +54 -9
  387. package/src/cli/tui-test-cli.ts +190 -0
  388. package/src/config.ts +4 -2
  389. package/src/connectors/linear-daily-progress.ts +228 -0
  390. package/src/connectors/linear-projector.ts +34 -12
  391. package/src/connectors/linear.ts +151 -7
  392. package/src/control-plane/ledger.ts +42 -4
  393. package/src/control-plane/member-tokens.ts +25 -2
  394. package/src/control-plane/ports.ts +8 -3
  395. package/src/control-plane/server.ts +26 -5
  396. package/src/core-turn/deep-turn-bloom.ts +67 -0
  397. package/src/core-turn/research-policy.ts +43 -0
  398. package/src/core-turn/run-core-turn.ts +488 -51
  399. package/src/core-turn/types.ts +4 -0
  400. package/src/dashboard/chat/acp-chat.ts +10 -0
  401. package/src/dashboard/classic-sidetab-mission-job.ts +192 -0
  402. package/src/dashboard/classic-sidetab-mission-pair.ts +82 -0
  403. package/src/dashboard/classic-sidetab-mission-trio.ts +242 -0
  404. package/src/dashboard/classic-sidetab-mission.ts +169 -5
  405. package/src/dashboard/index.ts +387 -14
  406. package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
  407. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +8 -0
  408. package/src/dashboard/mission-cli-consumer.ts +20 -8
  409. package/src/dashboard/plugin-wizard-runtime.ts +50 -0
  410. package/src/dashboard/plugin-wizard-tool.ts +55 -0
  411. package/src/dashboard/sidetab-runtime.ts +3 -1
  412. package/src/dashboard/terminal-popup-runtime.ts +6 -3
  413. package/src/dashboard/visible-mission-diagnostics.ts +16 -0
  414. package/src/decisions/linear-progress-summary.ts +78 -0
  415. package/src/decisions/linear-progress-sync.ts +152 -0
  416. package/src/domains/outbound-alert.ts +49 -11
  417. package/src/domains/retro-cycle-observation.ts +43 -0
  418. package/src/domains/retro-cycle.ts +13 -2
  419. package/src/domains/retro-proposals.ts +92 -0
  420. package/src/domains/retro-report.ts +6 -1
  421. package/src/domains/telegram-kind-route.ts +16 -9
  422. package/src/graph-runner/arg-allowance.ts +13 -0
  423. package/src/graph-runner/graph-cli.ts +24 -1
  424. package/src/graph-runner/graph-grow-llm.ts +3 -1
  425. package/src/graph-runner/graph-run-api.ts +3 -1
  426. package/src/graph-runner/runner.ts +310 -46
  427. package/src/graph-wizard/mission-compose.ts +407 -12
  428. package/src/harness/dispatch-backpressure.ts +54 -1
  429. package/src/harness/dispatch-shadow-compare.ts +74 -0
  430. package/src/harness/harness-cli-command.ts +15 -3
  431. package/src/harness/harness-pod-dispatch.ts +3 -0
  432. package/src/harness/skill-exec.ts +21 -9
  433. package/src/harness/skill-select.ts +1 -1
  434. package/src/hooks/error-report-cloud.ts +101 -0
  435. package/src/hooks/receiver.ts +29 -2
  436. package/src/index.ts +129 -12
  437. package/src/intake-plane/actions.ts +354 -0
  438. package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
  439. package/src/intake-plane/intake-sources.ts +78 -8
  440. package/src/intake-plane/items.ts +14 -4
  441. package/src/intake-plane/linear-mission-sync.ts +80 -0
  442. package/src/intake-plane/linear-secretary-runtime.ts +178 -0
  443. package/src/intake-plane/linear-wish.ts +227 -1
  444. package/src/life/life-cli.ts +168 -0
  445. package/src/life/life-kinds.ts +160 -0
  446. package/src/live-supply/budget-consumer.ts +78 -0
  447. package/src/live-supply/read.ts +3 -0
  448. package/src/live-supply/snapshot.ts +45 -0
  449. package/src/llm/child-first-llm-observation.ts +112 -0
  450. package/src/llm/provider-credentials.ts +68 -6
  451. package/src/llm/provider-failure-evidence.ts +44 -0
  452. package/src/llm.ts +172 -12
  453. package/src/maturity/feature-maturity.ts +3 -3
  454. package/src/mcp/client.ts +7 -0
  455. package/src/mcp/proxy-runtime.ts +6 -1
  456. package/src/mcp/server.ts +54 -0
  457. package/src/msg/msg-sse-server.ts +3 -3
  458. package/src/msg/msg-store.ts +177 -19
  459. package/src/native-tool-catalog.ts +36 -2
  460. package/src/nexus/api/consult-requests.ts +18 -6
  461. package/src/nexus/api/discord-trigger-bot.ts +6 -6
  462. package/src/nexus/api/graphs-api.ts +4 -2
  463. package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
  464. package/src/nexus/api/http-server.ts +37 -1
  465. package/src/nexus/api/mcp-public-allowlist.ts +2 -0
  466. package/src/nexus/api/telegram-trigger-bot.ts +6 -6
  467. package/src/nexus/boot/register-mcp-clients.ts +114 -8
  468. package/src/nexus/index.ts +22 -2
  469. package/src/nexus/outbound/format.ts +9 -0
  470. package/src/nexus/outbound/grokbot-adapter.ts +71 -0
  471. package/src/nexus/outbound/router.ts +121 -16
  472. package/src/nexus/setup-status.ts +9 -0
  473. package/src/nexus/state/state.ts +3 -0
  474. package/src/oauth/codex-account-store.ts +20 -7
  475. package/src/oauth/codex-owner-mirror.ts +81 -0
  476. package/src/oauth/codex.ts +17 -2
  477. package/src/oauth/fallback-chain.ts +47 -17
  478. package/src/onboarding/first-run-doctor.ts +8 -1
  479. package/src/onboarding/first-run.ts +126 -29
  480. package/src/onboarding/key-setup.ts +103 -0
  481. package/src/onboarding/menu-answer.ts +13 -0
  482. package/src/onboarding/secret-prompt.ts +37 -0
  483. package/src/plugins/install/plugin-install.ts +59 -0
  484. package/src/pr-tool/census.ts +130 -0
  485. package/src/preview/terminal.ts +22 -7
  486. package/src/prompt-enhance/enhance.ts +10 -0
  487. package/src/pty-shell/pty-control-ipc.ts +4 -1
  488. package/src/pty-shell/pty-write-provenance.ts +21 -3
  489. package/src/pty-shell/registry.ts +9 -2
  490. package/src/registry/catalog-server.ts +232 -0
  491. package/src/registry/loader.ts +45 -1
  492. package/src/registry/types.ts +1 -2
  493. package/src/release-loop/proposal-auto-place.ts +83 -0
  494. package/src/research/axis-fanout.ts +79 -29
  495. package/src/research/lenses/second-order.ts +312 -0
  496. package/src/self-dev/ask-launch-flow.ts +72 -1
  497. package/src/self-dev/dev-cli.ts +7 -2
  498. package/src/self-dev/dev-pipeline.ts +5 -0
  499. package/src/self-dev/draft-residue.ts +64 -5
  500. package/src/self-dev/draft-sweep.ts +31 -10
  501. package/src/self-dev/draft-triage-rules.ts +60 -3
  502. package/src/self-dev/graph-front-nodes.ts +2 -1
  503. package/src/self-dev/graph-journey-route.ts +76 -21
  504. package/src/self-dev/launch-preflight.ts +58 -0
  505. package/src/self-dev/orchestrate.ts +1 -1
  506. package/src/self-dev/run-supervisor.ts +152 -2
  507. package/src/self-dev/shard-aggregate.ts +4 -0
  508. package/src/self-dev/shard-run.ts +36 -15
  509. package/src/self-implement/abandoned-classification.ts +12 -3
  510. package/src/self-implement/budget-gate.ts +7 -0
  511. package/src/self-implement/child-llm-preference.ts +10 -1
  512. package/src/self-implement/doctor-visit.ts +30 -8
  513. package/src/self-implement/elanous-tui-spawn.ts +3 -0
  514. package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
  515. package/src/self-implement/gate-artifacts.ts +2 -1
  516. package/src/self-implement/goal-author-cli.ts +4 -2
  517. package/src/self-implement/goal-author.ts +549 -10
  518. package/src/self-implement/graph-overlay-yaml.ts +181 -4
  519. package/src/self-implement/graph-overlay.ts +3 -1
  520. package/src/self-implement/graph-profile-yaml.ts +107 -0
  521. package/src/self-implement/graph-yaml.ts +94 -5
  522. package/src/self-implement/off-diff-evidence.ts +249 -5
  523. package/src/self-implement/orchestrator.ts +298 -26
  524. package/src/self-implement/run-chart.ts +6 -3
  525. package/src/self-implement/run-ledger.ts +51 -1
  526. package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
  527. package/src/self-implement/tdd-evidence-tags.ts +9 -0
  528. package/src/self-implement/test-scenario-request.ts +37 -6
  529. package/src/self-implement/train-gate-receipt.ts +166 -0
  530. package/src/self-implement/train-gate-remote.ts +62 -18
  531. package/src/session/chat.ts +6 -4
  532. package/src/session/session-fanout.ts +2 -0
  533. package/src/session/streaming/acp-stream-sink.ts +2 -1
  534. package/src/session/streaming/chunk-producer.ts +6 -0
  535. package/src/session/streaming/stream-compositor.ts +3 -2
  536. package/src/session-runtime/index.ts +74 -6
  537. package/src/session-runtime/retry-policy.ts +1 -1
  538. package/src/setup/llm-env-detect.ts +3 -0
  539. package/src/setup/service-key-catalog.ts +46 -0
  540. package/src/setup/service-keys.ts +241 -0
  541. package/src/sidetab-core/model.ts +205 -10
  542. package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
  543. package/src/sidetab-core/visible-agent-mission.ts +182 -48
  544. package/src/skills/tools/agent.ts +23 -4
  545. package/src/skills/tools/omni-search.ts +127 -27
  546. package/src/task-agent/parent-host.ts +29 -1
  547. package/src/task-agent/recall-inject.ts +98 -0
  548. package/src/task-agent/repair-outcomes.ts +65 -0
  549. package/src/task-agent/task-hand.ts +46 -14
  550. package/src/task-orchestrator/dispatcher.ts +14 -1
  551. package/src/task-orchestrator/linear-capture-events.ts +55 -0
  552. package/src/task-orchestrator/store.ts +16 -5
  553. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +23 -1
  554. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +107 -1
  555. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
  556. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
  557. package/src/task-orchestrator/surfaces/pod-source-receive.ts +23 -11
  558. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
  559. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
  560. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +467 -77
  561. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
  562. package/src/task-orchestrator/surfaces/self-implement-pod.ts +210 -14
  563. package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
  564. package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
  565. package/src/task-orchestrator/types.ts +14 -0
  566. package/src/telegram.ts +14 -16
  567. package/src/terminal/coding-agent.ts +14 -5
  568. package/src/terminal/session-registry.ts +1 -1
  569. package/src/tool-hints/gate.ts +46 -14
  570. package/src/tool-hints/signals.ts +1 -1
  571. package/src/tool-hints/types.ts +2 -0
  572. package/src/tool-runtime/agent-runtime.ts +1 -0
  573. package/src/tool-runtime/browser-hand-runtime.ts +391 -0
  574. package/src/tool-runtime/browser-runtime.ts +33 -19
  575. package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
  576. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +173 -0
  577. package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
  578. package/src/tool-runtime/index.ts +6 -0
  579. package/src/tool-runtime/types.ts +5 -0
  580. package/src/tui/entry.ts +51 -8
  581. package/src/tui/sidetab/attach.ts +252 -11
  582. package/src/tui/sidetab/herdr-portal.ts +225 -0
  583. package/src/tui/sidetab/list.ts +3 -2
  584. package/src/tui-client/next-dashboard-runtime.ts +52 -0
  585. package/src/user-config.ts +34 -9
  586. package/src/user-intent/types.ts +4 -3
  587. package/src/ux-sim/browser-hand.ts +165 -0
  588. package/src/ux-sim/draft-inventory-builder.ts +199 -0
  589. package/src/ux-sim/fake-browser-page.ts +81 -0
  590. package/src/ux-sim/fake-linear-device.ts +31 -0
  591. package/src/ux-sim/graph-engine-sim.ts +47 -0
  592. package/src/ux-sim/linear-secretary.ts +208 -0
  593. package/src/ux-sim/mock-scenario-catalog.json +81 -26
  594. package/src/ux-sim/mock-scenario-catalog.ts +175 -5
  595. package/src/ux-sim/onboarding-first-run-device.ts +31 -21
  596. package/src/ux-sim/release-sim-rig.ts +62 -18
  597. package/src/ux-sim/scenario.ts +70 -26
  598. package/src/ux-sim/service-key-setup.ts +113 -0
  599. package/src/ux-sim/term-slash-device.ts +74 -0
  600. package/src/ux-sim/turn-throw-sim.ts +31 -0
  601. package/src/version/packed-revision.json +1 -1
  602. package/src/web-search/exa.ts +77 -0
  603. package/src/web-search/index.ts +30 -9
  604. package/src/web-search/provider.ts +4 -1
  605. package/src/web-search/x-intent.ts +5 -0
  606. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +0 -36
  608. package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +0 -32
  614. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +0 -286
  620. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +0 -34
  623. package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +0 -115
  629. package/apps/pwa/out/_next/static/chunks/2974.595d1e29d040cb6a.js +0 -64
  630. package/apps/pwa/out/_next/static/chunks/3207.a756c95e9ec8c3c8.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +0 -93
  632. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +0 -41
  633. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +0 -24
  635. package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +0 -77
  641. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +0 -148
  647. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +0 -74
  648. package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +0 -122
  649. package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +0 -149
  650. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +0 -27
  652. package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +0 -226
  664. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +0 -90
  665. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +0 -104
  671. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +0 -94
  672. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +0 -24
  679. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +0 -8
  687. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +0 -79
  689. package/apps/pwa/out/_next/static/chunks/8546-6f03f8ea34dd61d9.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/9249.976f1e69a9d80754.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/9656-374232558fd528d0.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +0 -62
  705. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +0 -1
  763. package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
  764. /package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
@@ -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
+ }
@@ -32,8 +32,10 @@ import { CARD_FOLLOWUP_PATH, createCardFollowupJobs, type CardFollowupJobs } fro
32
32
  import { SKILL_EXEC_PATH, createSkillExecJobs, type SkillExecJobs } from './skill-exec-route.js';
33
33
  import { compareTokenConstTime } from '../../acp/transport/auth.js';
34
34
  import { ensureAuthToken } from '../../auth/acp-token.js';
35
- import type { NexusState } from '../state/state.js';
35
+ import { pushEvent, type NexusState } from '../state/state.js';
36
36
  import { DEFAULT_NEXUS_HTTP_PORT } from '../default-port.js';
37
+ import { effectiveInstanceRoot } from '../../instance/resolve.js';
38
+ import { handleMissionLineRequest, MissionLineHttpError } from '../../agent-mission/mission-line.js';
37
39
 
38
40
  export { DEFAULT_NEXUS_HTTP_PORT } from '../default-port.js';
39
41
  import type { TabRegistry } from '../state/tab-registry.js';
@@ -497,6 +499,8 @@ export interface NexusHttpServerOpts {
497
499
  projectFolderRoots?: string[];
498
500
  /** Optional installer state root for isolated API consumers and tests. */
499
501
  pluginStateRoot?: string;
502
+ /** Mission-addressed hand line storage; production uses the current instance state root. */
503
+ missionLineRoot?: string;
500
504
  outputs?: OutputsDeps;
501
505
  /** Read-only grid measurement seam; omitted in production for live HQ and Pod pool reads. */
502
506
  grid?: GridDeps;
@@ -1008,6 +1012,38 @@ export async function routeRequest(
1008
1012
  registerAuthPeerAddress(req, (server as BunServerLike & {
1009
1013
  requestIP?: (request: Request) => { address: string } | null;
1010
1014
  }).requestIP?.(req)?.address);
1015
+ // Mission lines use a scoped per-mission bearer issued by the mission
1016
+ // parent, not the owner/API bearer checked by the general scope guard.
1017
+ if (new URL(req.url).pathname.startsWith('/v1/missions/')) {
1018
+ // MissionOutStore uses effectiveInstanceRoot too; share the resolver
1019
+ // directly so custom ELANOUS_STATE_DIR/config-dir cannot split the token
1020
+ // authority from the reply ledger.
1021
+ const root = opts.missionLineRoot ?? effectiveInstanceRoot();
1022
+ const response = await handleMissionLineRequest(req, root, async (input, authority) => {
1023
+ const { createMissionOutStore, MissionReplyStateError } = await import('../../agent-mission/mission-out.js');
1024
+ const reply = await createMissionOutStore(root).reply(input.missionId, input.text, input.type === 'final', {
1025
+ lineId: input.lineId,
1026
+ ...(input.runId ? { runId: input.runId } : {}), ...(input.ptyId ? { ptyId: input.ptyId } : {}),
1027
+ ...(input.replyTo ? { replyTo: input.replyTo } : {}),
1028
+ attemptId: input.attemptId, agent: input.agent, lineType: input.type, source: input.source,
1029
+ ...(input.kind ? { kind: input.kind } : {}),
1030
+ ...(input.defaults ? { defaults: input.defaults } : {}),
1031
+ ...(input.deadline ? { deadline: input.deadline } : {}),
1032
+ ...(input.scope ? { scope: input.scope } : {}),
1033
+ ...(input.stop !== undefined ? { stop: input.stop } : {}),
1034
+ ...(input.priority ? { priority: input.priority } : {}),
1035
+ ...(input.state ? { state: input.state } : {}), who: authority.who, what: authority.what,
1036
+ ...(input.type === 'ask' || input.type === 'answer' || input.type === 'correct' ? { kind: input.type } : {}),
1037
+ }).catch((error: unknown) => {
1038
+ if (error instanceof MissionReplyStateError) throw new MissionLineHttpError(error.status);
1039
+ throw error;
1040
+ });
1041
+ return { ...input, sequence: reply.sequence, createdAt: reply.createdAt, done: reply.done, ...(reply.deadline ? { deadline: reply.deadline } : {}), ...(reply.replyTo ? { replyTo: reply.replyTo } : {}), ...(reply.graphEvents ? { graphEvents: reply.graphEvents } : {}) };
1042
+ }, (event) => {
1043
+ pushEvent(opts.state, { kind: 'mission.line', detail: event as unknown as Record<string, unknown> });
1044
+ });
1045
+ if (response) return response;
1046
+ }
1011
1047
  if (opts.metaApi && setupBearerScopeDenied(req, opts.metaApi)) {
1012
1048
  return jsonResponse({ error: 'forbidden' }, 403);
1013
1049
  }
@@ -14,6 +14,8 @@ export const MCP_PUBLIC_TOOLS = new Set([
14
14
  'elanous_obsidian_search',
15
15
  'agent_list',
16
16
  'agent_output',
17
+ 'graph_compose',
18
+ 'graph_run_status',
17
19
  ]);
18
20
 
19
21
  function catalogId(name: string): string | undefined {
@@ -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;
@@ -252,7 +252,7 @@ import type { HealthProbeBackend } from './supervisor/health.js';
252
252
  import { gracefulExit, cleanExit } from './supervisor/graceful-exit.js';
253
253
  import { restoreFromPending } from './supervisor/restore-state.js';
254
254
  import { resolveHeadlessMode } from './headless-mode.js';
255
- import { checkSetupStatus, readNexusSetupMode, renderSetupStatus, setupBootMode, setupModeBootPlan } from './setup-status.js';
255
+ import { checkSetupStatus, readNexusSetupMode, renderSetupStatus, setupBootMode, setupModeBootPlan, shouldCheckHeadlessSetup } from './setup-status.js';
256
256
  import { probeTailscale } from './onboarding/tailscale-probe.js';
257
257
  import {
258
258
  runPwaSharePrompt,
@@ -859,7 +859,12 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
859
859
  }
860
860
 
861
861
  const headless = resolveHeadlessMode({ ...(opts.headless !== undefined ? { headless: opts.headless } : {}) });
862
- if (headless && !opts.detachForTesting && !opts.skipHeadlessSetupCheckForTesting) {
862
+ if (shouldCheckHeadlessSetup({
863
+ headless,
864
+ detachedForTesting: opts.detachForTesting === true,
865
+ skipForTesting: opts.skipHeadlessSetupCheckForTesting === true,
866
+ testInstance: resolveCurrentInstance().kind === 'test',
867
+ })) {
863
868
  const setup = checkSetupStatus({ argvBin: process.argv[1] ?? '' });
864
869
  const boot = setupBootMode(setup);
865
870
  if (boot.mode === 'refuse') {
@@ -1351,6 +1356,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1351
1356
  // Wired below once the workflow daemon is constructed.
1352
1357
  let webPushDecisionTimer: ReturnType<typeof setInterval> | undefined;
1353
1358
  let workflowDiscordBot: NexusDiscordTriggerBotHandle | undefined;
1359
+ let workflowGrokbotBot: { start(): void; stop(): Promise<void> } | undefined;
1354
1360
  // V2.2-4 (2026-05-12) — NEXUS-hosted Telegram workflow trigger bot.
1355
1361
  let workflowTelegramBot: NexusTelegramTriggerBotHandle | undefined;
1356
1362
  /** R1 — 토큰마다 뜬 Q&A 폴러 «전부»(재시작 때 함께 비운다 · `workflowTelegramBot` 은 주 토큰 하나뿐). */
@@ -2807,6 +2813,16 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2807
2813
  for (const wired of handles) adopt(wired);
2808
2814
  }
2809
2815
  }
2816
+ if (process.env.ELANOUS_GROKBOT_ENABLED === '1' && !isAutonomousRunContext()) {
2817
+ const { createGrokbotMainSessionDispatcher, createNexusGrokbotTriggerBot, createSshGrokbotMailbox } = await import('./api/grokbot-trigger-bot.js');
2818
+ const { makeElanousAgentRunTurn } = await import('../agent/monad-agent-turn.js');
2819
+ workflowGrokbotBot = createNexusGrokbotTriggerBot({
2820
+ mailbox: createSshGrokbotMailbox(),
2821
+ dispatch: createGrokbotMainSessionDispatcher(cfg, makeElanousAgentRunTurn(cfg, 'telegram')),
2822
+ });
2823
+ workflowGrokbotBot.start();
2824
+ debug.log('channel.grokbot', 'attached', { agent: 'COO', pollIntervalMs: 15_000 });
2825
+ }
2810
2826
  } catch (err: unknown) {
2811
2827
  const msg = err instanceof Error ? err.message : String(err);
2812
2828
  console.warn(`[nexus] trigger bot boot skipped: ${msg}`);
@@ -3587,6 +3603,10 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3587
3603
  await Promise.all([...handles].map(async (handle) => {
3588
3604
  try { await handle.stop(); } catch { /* 종료는 계속 */ }
3589
3605
  }));
3606
+ if (workflowGrokbotBot) {
3607
+ try { await workflowGrokbotBot.stop(); } catch { /* 종료는 계속 */ }
3608
+ workflowGrokbotBot = undefined;
3609
+ }
3590
3610
  await next();
3591
3611
  };
3592
3612
 
@@ -14,6 +14,15 @@ export interface OutboundMsg {
14
14
  kind: string;
15
15
  /** Optional routing role; absent preserves per-kind fan-out. */
16
16
  role?: string;
17
+ /** Optional transport metadata. A router must not send these fields to a connector that does not declare support. */
18
+ threadId?: string;
19
+ topicId?: string;
20
+ persona?: { name: string; avatarUrl?: string };
21
+ attachments?: readonly { url: string; name?: string }[];
22
+ buttons?: readonly { label: string; value: string }[];
23
+ choices?: readonly { label: string; value: string }[];
24
+ /** Requested channel-side authorization; delivery fails closed when unsupported or denied. */
25
+ permissionAction?: string;
17
26
  }
18
27
 
19
28
  export interface FormattedMessage {
@@ -0,0 +1,71 @@
1
+ import { debug } from '../../debug/log.js';
2
+ import { registerOutboundAdapter } from './router.js';
3
+ import type {
4
+ ChannelAdapter,
5
+ ChannelEnvelope,
6
+ ChannelResult,
7
+ OutboundChannelConfig,
8
+ RouterDeps,
9
+ } from './router.js';
10
+ import type { OutboundMsg } from './format.js';
11
+ import type { UserConfig } from '../../user-config.js';
12
+
13
+ export interface GrokbotAdapterOptions {
14
+ sendPrompt: (agent: string, prompt: string) => Promise<{ preview?: string }>;
15
+ now?: () => string;
16
+ log?: (event: string, data: Record<string, unknown>) => void;
17
+ agent?: string;
18
+ }
19
+
20
+ function safeError(error: unknown): string {
21
+ const message = error instanceof Error ? error.message : String(error);
22
+ return message.replace(/Bearer\s+\S+/gi, 'Bearer [redacted]').slice(0, 240);
23
+ }
24
+
25
+ function inboundEnvelope(payload: unknown): Omit<ChannelEnvelope, 'text'> & { text: string } | null {
26
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return null;
27
+ const event = payload as Record<string, unknown>;
28
+ if (typeof event.text !== 'string' || event.text.length === 0) return null;
29
+ if (typeof event.id !== 'string' && typeof event.id !== 'number') return null;
30
+ const kind = typeof event.kind === 'string' && event.kind.trim() ? event.kind : 'request';
31
+ return { text: event.text, kind, channel: 'COO', senderId: 'COO', messageId: event.id };
32
+ }
33
+
34
+ export function createGrokbotAdapter(options: GrokbotAdapterOptions): ChannelAdapter {
35
+ const agent = options.agent ?? 'COO';
36
+ const now = options.now ?? (() => new Date().toISOString());
37
+ const log = options.log ?? ((event, data) => debug.log('channel.grokbot', event, data));
38
+ return {
39
+ type: 'grokbot',
40
+ capabilities: {
41
+ send: true, receive: true, thread: false, topic: false, persona: false,
42
+ channelLifecycle: false, permissions: false, commands: false, attachments: false,
43
+ buttons: false, choices: true, deliveryConfirmation: false, rateLimit: false,
44
+ },
45
+ parseConfig: (raw): OutboundChannelConfig | undefined => raw.type === 'grokbot' ? { type: 'grokbot' } : undefined,
46
+ receive: (payload): ChannelEnvelope | null => {
47
+ const envelope = inboundEnvelope(payload);
48
+ if (!envelope) return null;
49
+ log('received', { id: envelope.messageId, text: envelope.text, receivedAt: now() });
50
+ return envelope;
51
+ },
52
+ send: async (_config: OutboundChannelConfig, message: OutboundMsg, _cfg: UserConfig, _deps: RouterDeps): Promise<ChannelResult> => {
53
+ const requestedAt = now();
54
+ log('request', { agent, text: message.text, requestedAt, kind: message.kind });
55
+ try {
56
+ const prompt = `[엘라누스 알림 — 아래를 대표님께 그대로 전해 주세요. 덧붙이지 마세요]\n\n${message.text}`;
57
+ const result = await options.sendPrompt(agent, prompt);
58
+ log('reply', { agent, repliedAt: now(), ...(result.preview ? { preview: result.preview } : {}) });
59
+ return { type: 'grokbot', ok: true };
60
+ } catch (error) {
61
+ const reason = safeError(error);
62
+ log('failure', { agent, failedAt: now(), reason });
63
+ return { type: 'grokbot', ok: false, error: reason };
64
+ }
65
+ },
66
+ };
67
+ }
68
+
69
+ export function registerGrokbotAdapter(options: GrokbotAdapterOptions): () => void {
70
+ return registerOutboundAdapter(createGrokbotAdapter(options));
71
+ }