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,173 @@
1
+ import { debug } from '../debug/log.js';
2
+ import { fetchLinearIssueDescription, fetchLinearMissionIssueIdentity } from '../connectors/linear.js';
3
+ import { DecisionLedger } from '../decisions/decision-ledger.js';
4
+ import { elanousStateRoot } from '../autopilot/state-paths.js';
5
+ import { getSecretAsync } from '../nexus/config/secrets/index.js';
6
+ import { parseLinearSecretaryManifest, updateLinearSecretaryProgress, type LinearSecretaryCaptureInput } from '../intake-plane/linear-wish.js';
7
+ import { submitIntakeWork, type SubmitIntakeWorkDeps } from '../intake-plane/submit-intake-work.js';
8
+ import type { LLMToolSpec } from '../llm.js';
9
+ import type { ToolRuntime, ToolRuntimeContext } from './types.js';
10
+
11
+ export type ElanousLinearSecretaryArgs =
12
+ | { action: 'create'; request: string }
13
+ | { action: 'progress'; teamKey: 'DEMO'; parentIssueId: string; taskIssueId: string; state: 'started' | 'completed' | 'comment'; summary: string; absorbText?: string; captureArtifact?: LinearSecretaryCaptureInput; workaround?: string }
14
+ | { action: 'approval'; teamKey: 'DEMO'; parentIssueId: string; title: string; context: string };
15
+ export interface ElanousLinearSecretaryResult extends Record<string, unknown> { ok: boolean; output: string }
16
+
17
+ type CreateRunner = (request: string) => Promise<{ replyCard: string; parentIssueId: string; childIssueIds: string[] }>;
18
+ const productionCreate: CreateRunner = async request =>
19
+ (await import('../intake-plane/linear-secretary-runtime.js')).runLinearSecretaryRequest(request);
20
+ let createRunner = productionCreate;
21
+
22
+ export function setElanousLinearSecretaryRunnerForTest(next?: CreateRunner): () => void {
23
+ if (createRunner !== productionCreate) throw new Error('Linear secretary runner already replaced');
24
+ createRunner = next ?? productionCreate;
25
+ const installed = createRunner;
26
+ return () => { if (createRunner === installed) createRunner = productionCreate; };
27
+ }
28
+
29
+ export interface ElanousLinearSecretaryRuntimeDeps {
30
+ create?: CreateRunner;
31
+ getApiKey?: () => Promise<string | undefined>;
32
+ fetch?: typeof fetch;
33
+ verifyParent?: typeof ensureDemoParent;
34
+ readChildManifest?: typeof readDemoChildManifest;
35
+ updateProgress?: typeof updateLinearSecretaryProgress;
36
+ intake?: SubmitIntakeWorkDeps;
37
+ ledger?: () => DecisionLedger;
38
+ }
39
+
40
+ async function ensureDemoParent(apiKey: string, parentIssueId: string, fetchFn: typeof fetch): Promise<void> {
41
+ const query = `query SecretaryDemoParent($id: String!) { issue(id: $id) { id team { key } } }`;
42
+ const response = await fetchFn('https://api.linear.app/graphql', { method: 'POST', headers: { Authorization: apiKey, 'Content-Type': 'application/json' },
43
+ body: JSON.stringify({ query, variables: { id: parentIssueId } }) });
44
+ if (!response.ok) throw new Error('Linear parent lookup failed');
45
+ const result = await response.json() as { errors?: unknown[]; data?: { issue?: { id?: string; team?: { key?: string } } | null } };
46
+ const issue = result.data?.issue;
47
+ if (result.errors?.length || !issue || issue.id !== parentIssueId || issue.team?.key !== 'DEMO') {
48
+ throw new Error('Linear secretary only accepts a parent issue in the DEMO team');
49
+ }
50
+ }
51
+
52
+ async function readDemoChildManifest(apiKey: string, parentIssueId: string, taskIssueId: string, fetchFn: typeof fetch) {
53
+ const identity = await fetchLinearMissionIssueIdentity({ apiKey, issueId: taskIssueId, fetch: fetchFn });
54
+ if (identity.teamKey !== 'DEMO' || identity.parentId !== parentIssueId) throw new Error('Linear secretary child is not listed in the DEMO parent manifest');
55
+ const description = await fetchLinearIssueDescription({ apiKey, issueId: taskIssueId, fetch: fetchFn });
56
+ const manifest = parseLinearSecretaryManifest(description, taskIssueId);
57
+ if (!manifest || manifest.parentIssueId !== parentIssueId) throw new Error('Linear secretary child is not listed in the DEMO parent manifest');
58
+ return manifest;
59
+ }
60
+
61
+ async function runProgress(args: Extract<ElanousLinearSecretaryArgs, { action: 'progress' }>, deps: ElanousLinearSecretaryRuntimeDeps) {
62
+ if (args.captureArtifact && (args.captureArtifact.externalShare !== true || args.captureArtifact.sensitivity !== 'public' ||
63
+ args.captureArtifact.linearIssueId !== args.parentIssueId || !args.captureArtifact.runId.trim() || !Number.isFinite(args.captureArtifact.createdAt))) {
64
+ return { ok: false, output: 'Linear 캡처는 현재 DEMO 부모에 대해 명시 승인된 공개 브라우저 증거여야 합니다.' };
65
+ }
66
+ const apiKey = await (deps.getApiKey?.() ?? getSecretAsync('connector.linear.apiKey'));
67
+ if (!apiKey?.trim()) throw new Error('Linear API key is missing; run elanous connector linear set-key');
68
+ const fetchFn = deps.fetch ?? globalThis.fetch;
69
+ await (deps.verifyParent ?? ensureDemoParent)(apiKey, args.parentIssueId, fetchFn);
70
+ const manifest = await (deps.readChildManifest ?? readDemoChildManifest)(apiKey, args.parentIssueId, args.taskIssueId, fetchFn);
71
+ const task = manifest.tasks.find(item => item.issueId === args.taskIssueId);
72
+ if (!task) throw new Error('Linear secretary child is not listed in the DEMO parent manifest');
73
+ const absorbed = args.absorbText?.trim() ? await (async text => {
74
+ const result = await submitIntakeWork({ text, track: 'absorb', origin: { kind: 'owner', ledgerSource: 'memo' } }, deps.intake);
75
+ return result.ok && result.track === 'absorb' ? { ok: true as const, ids: result.ids }
76
+ : { ok: false as const, reason: result.ok ? 'unexpected-intake-track' : result.reason };
77
+ })(args.absorbText.trim()) : undefined;
78
+ if (absorbed && (!absorbed.ok || !absorbed.ids.length)) throw new Error('흡수 근거를 intake 원장에 기록하지 못해 진행을 보류했습니다.');
79
+ const refs = absorbed?.ok ? absorbed.ids.map(id => `elanous:intake:${id}`) : [];
80
+ const summary = [args.summary.trim(), ...(refs.length ? [`흡수 근거: ${refs.join(' · ')}`] : [])].join('\n');
81
+ await (deps.updateProgress ?? updateLinearSecretaryProgress)({ apiKey, parentIssueId: args.parentIssueId, taskIssueId: task.issueId, taskTitle: task.title,
82
+ tasks: manifest.tasks, state: args.state, summary, ...(args.workaround ? { workaround: args.workaround } : {}),
83
+ ...(args.captureArtifact ? { captureArtifact: args.captureArtifact } : {}), fetch: fetchFn });
84
+ return { ok: true, output: `DEMO 하위 이슈 진행을 기록했습니다: ${task.issueId}`, parentIssueId: args.parentIssueId, taskIssueId: task.issueId, state: args.state,
85
+ ...(refs.length ? { evidenceRefs: refs } : {}) };
86
+ }
87
+
88
+ async function runApproval(args: Extract<ElanousLinearSecretaryArgs, { action: 'approval' }>, deps: ElanousLinearSecretaryRuntimeDeps) {
89
+ const apiKey = await (deps.getApiKey?.() ?? getSecretAsync('connector.linear.apiKey'));
90
+ if (!apiKey?.trim()) throw new Error('Linear API key is missing; run elanous connector linear set-key');
91
+ await (deps.verifyParent ?? ensureDemoParent)(apiKey, args.parentIssueId, deps.fetch ?? globalThis.fetch);
92
+ const refs = [args.parentIssueId];
93
+ const title = args.title.trim();
94
+ const context = args.context.trim();
95
+ if (!title || !context) throw new Error('Approval title and context are required');
96
+ const ledger = deps.ledger?.() ?? new DecisionLedger({ stateDir: elanousStateRoot() });
97
+ const ref = `linear-secretary-approval:${args.parentIssueId}`;
98
+ const entry = ledger.raiseOnce({ title, category: 'publish', scqa: { s: 'DEMO Linear 결과와 근거가 준비됐다.', c: context },
99
+ options: [{ key: 'a', label: '승인', consequence: '사람이 명시적으로 승인한 뒤 다음 동작을 진행한다' },
100
+ { key: 'b', label: '보류', consequence: '외부 공개를 멈춘다' }],
101
+ recommendation: { option: 'b', why: '승인 전에는 보류한다' }, raisedBy: { agent: 'OPT', track: 'OP' }, refs: [...refs, ref] }, ref);
102
+ // Local durable pending card only. No Telegram/card transport is invoked here.
103
+ const output = entry.status === 'open' ? `승인 대기 카드를 열었습니다: ${entry.id}` : `기존 승인 카드 ${entry.id}의 상태는 ${entry.status}입니다. 새 카드는 열지 않았습니다.`;
104
+ return { ok: true, output, decisionId: entry.id, status: entry.status };
105
+ }
106
+
107
+ export function createElanousLinearSecretaryRuntime(deps: ElanousLinearSecretaryRuntimeDeps = {}): ToolRuntime<ElanousLinearSecretaryArgs, ElanousLinearSecretaryResult> {
108
+ return {
109
+ id: 'elanous_linear_secretary', surfaces: ['tui', 'mcp'],
110
+ spec: {
111
+ name: 'elanous_linear_secretary',
112
+ description: 'DEMO 팀 전용 grounded Linear secretary. create는 due date가 포함된 근거 기반 부모/하위 이슈를 만든다. progress는 intake 원문을 흡수한 ID와 명시 승인된 브라우저 캡처를 연결하고 하위 상태를 갱신한다. approval은 부모당 하나의 로컬 open 카드를 만든다. 같은 부모 재호출은 기존 카드 상태를 돌려주며 외부 발송은 없다.',
113
+ parameters: { type: 'object', properties: {
114
+ action: { type: 'string', enum: ['create', 'progress', 'approval'] },
115
+ request: { type: 'string', minLength: 1, description: 'create에 필수. 명시적 YYYY-MM-DD 날짜를 포함한다.' },
116
+ teamKey: { type: 'string', enum: ['DEMO'] }, parentIssueId: { type: 'string' }, taskIssueId: { type: 'string' },
117
+ state: { type: 'string', enum: ['started', 'completed', 'comment'] }, summary: { type: 'string' },
118
+ absorbText: { type: 'string', description: '흡수 원장에 실제 기록할 원문 또는 URL; 성공한 intake id만 진행 근거로 연결한다.' },
119
+ captureArtifact: { type: 'object', description: 'browser-runtime이 생성하고 Linear 공유가 명시 승인된 정확한 캡처 artifact',
120
+ properties: { path: { type: 'string' }, mimeType: { type: 'string', enum: ['image/png', 'image/jpeg', 'image/webp', 'image/gif'] },
121
+ runId: { type: 'string' }, linearIssueId: { type: 'string' }, externalShare: { type: 'boolean', enum: [true] },
122
+ sensitivity: { type: 'string', enum: ['public'] }, createdAt: { type: 'number' } },
123
+ required: ['path', 'mimeType', 'runId', 'linearIssueId', 'externalShare', 'sensitivity', 'createdAt'], additionalProperties: false },
124
+ workaround: { type: 'string' }, title: { type: 'string' }, context: { type: 'string' },
125
+ }, required: ['action'], additionalProperties: false },
126
+ } satisfies LLMToolSpec,
127
+ async run(args, _ctx): Promise<ElanousLinearSecretaryResult> {
128
+ try {
129
+ if (args?.action === 'create') {
130
+ const request = typeof args.request === 'string' ? args.request.trim() : '';
131
+ if (!request) return { ok: false, output: 'Linear 비서 요청 내용이 필요합니다.' };
132
+ const teamTokens = [...request.matchAll(/(?:^|\s)teamKey\s*=\s*([^\s]+)/gi)].map(match => match[1]);
133
+ const projectlessTokens = [...request.matchAll(/(?:^|\s)projectless\s*=\s*([^\s]+)/gi)].map(match => match[1]?.toLowerCase());
134
+ const declaredTeam = teamTokens[0];
135
+ if (teamTokens.length > 1 || (declaredTeam && declaredTeam.toUpperCase() !== 'DEMO') ||
136
+ projectlessTokens.length > 1 || projectlessTokens.some(token => token !== 'true') || (projectlessTokens.length === 1 && !declaredTeam)) {
137
+ return { ok: false, output: 'DEMO 팀만 지원합니다.' };
138
+ }
139
+ const normalizedRequest = request
140
+ .replace(/(^|\s)teamKey\s*=\s*[^\s]+/gi, '$1teamKey=DEMO')
141
+ .replace(/(^|\s)projectless\s*=\s*[^\s]+/gi, '$1projectless=true');
142
+ const scopedRequest = projectlessTokens.length === 1 ? normalizedRequest
143
+ : declaredTeam ? `projectless=true ${normalizedRequest}` : `projectless=true teamKey=DEMO ${request}`;
144
+ const result = await (deps.create ?? createRunner)(scopedRequest);
145
+ debug.log('tool.linear-secretary', 'created', { childCount: result.childIssueIds.length, teamKey: 'DEMO' });
146
+ return { ok: true, output: result.replyCard, parentIssueId: result.parentIssueId, childIssueIds: result.childIssueIds, teamKey: 'DEMO' };
147
+ }
148
+ if (args?.action === 'progress') {
149
+ if (args.teamKey !== 'DEMO' || !args.parentIssueId?.trim() || !args.taskIssueId?.trim() || !args.summary?.trim() || !args.state) return { ok: false, output: 'DEMO 진행 기록에는 팀·부모·하위 이슈·상태·요약이 필요합니다.' };
150
+ return await runProgress(args, deps);
151
+ }
152
+ if (args?.action === 'approval') {
153
+ if (args.teamKey !== 'DEMO' || !args.parentIssueId?.trim() || !args.title?.trim() || !args.context?.trim()) return { ok: false, output: 'DEMO 승인 카드에는 팀·부모 이슈·제목·맥락이 필요합니다.' };
154
+ return await runApproval(args, deps);
155
+ }
156
+ return { ok: false, output: '지원하지 않는 Linear secretary 작업입니다.' };
157
+ } catch (error) {
158
+ const message = error instanceof Error ? error.message : 'Linear 비서 실행 실패';
159
+ debug.log('tool.linear-secretary', 'failed', { action: args?.action ?? 'unknown', errorType: error instanceof Error ? 'Error' : 'unknown' });
160
+ const safeMessage = ['Linear secretary only accepts a parent issue in the DEMO team', 'Linear secretary child is not listed in the DEMO parent manifest',
161
+ 'Linear API key is missing; run elanous connector linear set-key',
162
+ 'Linear COO 프로젝트 설정이 없어 이슈 등록을 보류했습니다. 프로젝트를 지정해 주세요.',
163
+ '저장소 근거 검색 총 시간 제한(20초)을 초과했습니다.', '저장소 근거 검색 도구를 실행하지 못해 근거 확인을 완료하지 못했습니다.',
164
+ '저장소·문서·기억에서 확인된 근거가 없어 등록을 보류했습니다.', '요청에 마감일이 없어 등록을 보류했습니다. 요청에 YYYY-MM-DD 날짜를 넣어 주세요.',
165
+ '마감일이 없어 등록하지 않았습니다. 요청에 날짜를 넣어 주세요.', '흡수 근거를 intake 원장에 기록하지 못해 진행을 보류했습니다.']
166
+ .find(known => message.includes(known));
167
+ return { ok: false, output: safeMessage ?? 'Linear 비서 작업을 진행하지 못했습니다. 팀 키·이슈 ID·근거·권한을 확인해 주세요.' };
168
+ }
169
+ },
170
+ };
171
+ }
172
+
173
+ export const elanousLinearSecretaryRuntime = createElanousLinearSecretaryRuntime();
@@ -0,0 +1,240 @@
1
+ // External graph control uses the same wizard, editor run API, and runner as the local UI.
2
+ // The MCP HTTP boundary filters mutating tools by token scope before dispatch.
3
+ import { readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import type { LLMToolSpec } from '../llm.js';
6
+ import { debug } from '../debug/log.js';
7
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
8
+ import { generateGraphFromPrompt } from '../graph-wizard/generate.js';
9
+ import { handleGraphsCreate } from '../nexus/api/graphs-api.js';
10
+ import { handleGraphRunGet, handleGraphRunStart } from '../graph-runner/graph-run-api.js';
11
+ import { proposeGrowth } from '../graph-runner/graph-grow.js';
12
+ import { runGraph, type GraphRunState } from '../graph-runner/runner.js';
13
+ import { parseGraphTemplateYaml } from '../self-implement/graph-yaml.js';
14
+ import type { ToolRuntime, ToolRuntimeContext } from './types.js';
15
+
16
+ const GRAPH_ID = /^[a-z0-9-]+$/;
17
+ const RUN_ID = /^ed-[a-z0-9]+-[a-f0-9]{6}$/;
18
+ type Args = Record<string, unknown>;
19
+ type Result = { output: string; [key: string]: unknown };
20
+ export interface GraphMcpDeps {
21
+ root?: string;
22
+ mineDir?: string;
23
+ recipesFile?: string;
24
+ generate?: typeof generateGraphFromPrompt;
25
+ growth?: typeof proposeGrowth;
26
+ run?: typeof runGraph;
27
+ }
28
+ let testDeps: GraphMcpDeps = {};
29
+ export function setGraphMcpDepsForTest(deps: GraphMcpDeps | undefined): void { testDeps = deps ?? {}; }
30
+ const rootOf = () => testDeps.root ?? effectiveInstanceRoot();
31
+
32
+ function value(args: Args, key: string): string | null {
33
+ const item = args[key];
34
+ return typeof item === 'string' && item.trim() ? item.trim() : null;
35
+ }
36
+
37
+ function error(tool: string, reason: string): Result {
38
+ return { output: `${tool}: ${reason}`, error: reason };
39
+ }
40
+
41
+ function observe(tool: string, action: string, ctx: ToolRuntimeContext, fields: Record<string, unknown>): void {
42
+ debug.log('mcp.graph', action, { tool, caller: ctx.mcpClient ?? 'unknown', ...fields });
43
+ }
44
+
45
+ function spec(name: string, description: string, properties: Record<string, unknown>, required: string[]): LLMToolSpec {
46
+ return { name, description, parameters: { type: 'object', properties, required } };
47
+ }
48
+
49
+ const composeSpec = spec('graph_compose', 'Preview a validated graph from one research goal. Does not save or run it.',
50
+ { goal: { type: 'string' } }, ['goal']);
51
+ const startSpec = spec('graph_run_start', 'Start an existing saved graph, or save and start a graph_compose result. Requires a write-scoped MCP token.',
52
+ { graphId: { type: 'string' }, compose: { type: 'object', description: 'graph_compose result: id, yaml, optional validated steps.' },
53
+ reason: { type: 'string' } }, ['reason']);
54
+ const statusSpec = spec('graph_run_status', 'Read bounded node states, outputs, and source IDs for a graph run.',
55
+ { graphId: { type: 'string' }, runId: { type: 'string' } }, ['graphId', 'runId']);
56
+ const nodeSpec = spec('graph_node_op', 'Operate on a saved run: retry from a failed node, or add a validated growth node as a new linked run. Requires a write-scoped MCP token.',
57
+ { graphId: { type: 'string' }, runId: { type: 'string' }, op: { type: 'string', enum: ['retry', 'add-node'] },
58
+ nodeId: { type: 'string' }, outcome: { type: 'string' }, reason: { type: 'string' } },
59
+ ['graphId', 'runId', 'op', 'nodeId', 'reason']);
60
+
61
+ function storedRun(graphId: string, runId: string, root: string): GraphRunState | null {
62
+ if (!GRAPH_ID.test(graphId) || !RUN_ID.test(runId)) return null;
63
+ try {
64
+ const state = JSON.parse(readFileSync(join(root, 'graph-runs', graphId, `${runId}.json`), 'utf8')) as GraphRunState;
65
+ return state.graphId === graphId && state.runId === runId ? state : null;
66
+ } catch { return null; }
67
+ }
68
+
69
+ async function compose(args: Args, ctx: ToolRuntimeContext): Promise<Result> {
70
+ const goal = value(args, 'goal');
71
+ if (!goal) return error('graph_compose', 'goal is required');
72
+ try {
73
+ const result = await (testDeps.generate ?? generateGraphFromPrompt)({ prompt: goal, kind: 'harness' });
74
+ observe('graph_compose', result.ok ? 'composed' : 'rejected', ctx, { graphId: result.id, reason: result.summary });
75
+ return { output: result.summary, ...result, compose: result.ok
76
+ ? { id: result.id, yaml: result.yaml, ...(result.steps ? { steps: result.steps } : {}) } : null };
77
+ } catch (cause) {
78
+ const reason = cause instanceof Error ? cause.message : String(cause);
79
+ observe('graph_compose', 'failed', ctx, { reason });
80
+ return error('graph_compose', reason);
81
+ }
82
+ }
83
+
84
+ async function start(args: Args, ctx: ToolRuntimeContext): Promise<Result> {
85
+ const reason = value(args, 'reason');
86
+ const supplied = args.compose;
87
+ const candidate = supplied && typeof supplied === 'object' && !Array.isArray(supplied)
88
+ ? supplied as Record<string, unknown> : null;
89
+ const graphId = candidate ? value(candidate, 'id') : value(args, 'graphId');
90
+ if (!reason || !graphId || !GRAPH_ID.test(graphId)) return error('graph_run_start', 'valid graphId and reason are required');
91
+ if (candidate) {
92
+ if (typeof candidate.yaml !== 'string') return error('graph_run_start', 'compose.yaml is required');
93
+ const created = await handleGraphsCreate(new Request('http://localhost/v1/graphs', {
94
+ method: 'POST', headers: { 'content-type': 'application/json' },
95
+ body: JSON.stringify({ id: graphId, yaml: candidate.yaml, ...(candidate.steps ? { steps: candidate.steps } : {}) }),
96
+ }), { ...(testDeps.mineDir ? { mineDir: testDeps.mineDir } : {}) });
97
+ if (!created.ok) {
98
+ const detail = await created.text();
99
+ observe('graph_run_start', 'refused', ctx, { graphId, reason, status: created.status });
100
+ return error('graph_run_start', `save refused (${created.status}): ${detail.slice(0, 300)}`);
101
+ }
102
+ }
103
+ const response = handleGraphRunStart(graphId, {
104
+ ...(testDeps.mineDir ? { mineDir: testDeps.mineDir } : {}),
105
+ root: rootOf(),
106
+ ...(testDeps.recipesFile ? { recipesFile: testDeps.recipesFile } : {}),
107
+ });
108
+ const body = await response.json() as Record<string, unknown>;
109
+ observe('graph_run_start', response.ok ? 'started' : 'refused', ctx,
110
+ { graphId, runId: body.runId ?? null, reason, status: response.status });
111
+ return { output: response.ok ? `Started ${graphId} run ${body.runId}` : `Start refused: ${JSON.stringify(body)}`,
112
+ ...body, status: response.status };
113
+ }
114
+
115
+ async function status(args: Args, ctx: ToolRuntimeContext): Promise<Result> {
116
+ const graphId = value(args, 'graphId');
117
+ const runId = value(args, 'runId');
118
+ if (!graphId || !runId || !GRAPH_ID.test(graphId) || !RUN_ID.test(runId)) return error('graph_run_status', 'invalid graphId or runId');
119
+ const response = handleGraphRunGet(graphId, runId, { root: rootOf() });
120
+ const body = await response.json() as Record<string, unknown>;
121
+ if (!response.ok) {
122
+ const reason = typeof body.reason === 'string' ? body.reason
123
+ : typeof body.error === 'string' ? body.error : `request failed (${response.status})`;
124
+ observe('graph_run_status', 'refused', ctx, { graphId, runId, status: response.status, error: reason });
125
+ return error('graph_run_status', reason);
126
+ }
127
+ const state = storedRun(graphId, runId, rootOf());
128
+ let truncated = false;
129
+ const clip = (text: string, max: number) => {
130
+ if (text.length > max) truncated = true;
131
+ return text.slice(0, max);
132
+ };
133
+ const allNodes = state?.nodes.map(node => {
134
+ const record = node.output && typeof node.output === 'object' && !Array.isArray(node.output)
135
+ ? node.output as Record<string, unknown> : null;
136
+ const sourceIds = [record?.sourceIds, record?.refs, record?.citations]
137
+ .flatMap(item => Array.isArray(item) ? item.filter((id): id is string => typeof id === 'string') : [])
138
+ .slice(0, 30);
139
+ const encodedOutput = node.output === undefined ? undefined : JSON.stringify(node.output);
140
+ if (sourceIds.length > 10) truncated = true;
141
+ return { nodeId: clip(node.nodeId, 160), ok: node.ok, exit: node.exit, executed: node.executed,
142
+ ...(node.error ? { error: clip(node.error, 300) } : {}),
143
+ sourceIds: sourceIds.slice(0, 10).map(id => clip(id, 120)),
144
+ ...(encodedOutput === undefined ? {} : { output: clip(encodedOutput, 800) }) };
145
+ }) ?? [];
146
+ const rawPath = Array.isArray(body.path) ? body.path : [];
147
+ const errorText = typeof body.error === 'string' ? body.error : undefined;
148
+ let nodes = [...allNodes].sort((a, b) => Number(b.ok === false) - Number(a.ok === false)).slice(0, 30);
149
+ let path = rawPath.slice(0, 100).map(nodeId => clip(String(nodeId), 160));
150
+ if (allNodes.length > nodes.length || rawPath.length > path.length) truncated = true;
151
+ const statusValue = clip(String(body.status ?? 'unknown'), 40);
152
+ const graphIdValue = clip(graphId, 120);
153
+ const runIdValue = clip(runId, 120);
154
+ const startedAt = typeof body.startedAt === 'string' ? clip(body.startedAt, 100) : undefined;
155
+ const finishedAt = typeof body.finishedAt === 'string' ? clip(body.finishedAt, 100) : undefined;
156
+ const boundedError = errorText ? clip(errorText, 1000) : undefined;
157
+ const serialize = () => JSON.stringify({
158
+ graphId: graphIdValue, runId: runIdValue, status: statusValue,
159
+ ...(startedAt ? { startedAt } : {}), ...(finishedAt ? { finishedAt } : {}),
160
+ ...(boundedError ? { error: boundedError } : {}), path, nodes, truncated,
161
+ });
162
+ let encoded = serialize();
163
+ while (Buffer.byteLength(encoded, 'utf8') > 24000 && nodes.length > 0) {
164
+ nodes = nodes.slice(0, -1);
165
+ truncated = true;
166
+ encoded = serialize();
167
+ }
168
+ while (Buffer.byteLength(encoded, 'utf8') > 24000 && path.length > 0) {
169
+ path = path.slice(0, -1);
170
+ truncated = true;
171
+ encoded = serialize();
172
+ }
173
+ if (Buffer.byteLength(encoded, 'utf8') > 24000) {
174
+ truncated = true;
175
+ path = [];
176
+ nodes = [];
177
+ encoded = serialize();
178
+ }
179
+ observe('graph_run_status', 'read', ctx, { graphId, runId, status: body.status ?? response.status });
180
+ return { output: encoded, ...JSON.parse(encoded) as Record<string, unknown> };
181
+ }
182
+
183
+ async function nodeOp(args: Args, ctx: ToolRuntimeContext): Promise<Result> {
184
+ const graphId = value(args, 'graphId');
185
+ const runId = value(args, 'runId');
186
+ const op = value(args, 'op');
187
+ const nodeId = value(args, 'nodeId');
188
+ const reason = value(args, 'reason');
189
+ if (!graphId || !runId || !GRAPH_ID.test(graphId) || !RUN_ID.test(runId) || !nodeId || !reason
190
+ || !['retry', 'add-node'].includes(op ?? '')) return error('graph_node_op', 'invalid graphId, runId, op, nodeId, or reason');
191
+ if (op === 'add-node' && !value(args, 'outcome'))
192
+ return error('graph_node_op', 'add-node requires the observed node outcome');
193
+ const root = rootOf();
194
+ const state = storedRun(graphId, runId, root);
195
+ if (!state || state.status !== 'failed' || !state.path.includes(nodeId))
196
+ return error('graph_node_op', 'a failed run and node on its saved path are required');
197
+ const graphFile = join(root, 'graph-run-work', graphId, runId, 'graph.yaml');
198
+ if (op === 'retry') {
199
+ try {
200
+ // Runner enforces the saved source hash, approval boundary, and failed-path limit.
201
+ const next = await (testDeps.run ?? runGraph)(graphFile, { resumeRunId: runId, fromNodeId: nodeId, deps: { root } });
202
+ observe('graph_node_op', op, ctx, { graphId, runId, nodeId, reason, status: next.status });
203
+ return { output: `${op}: ${next.status}`, graphId, runId, status: next.status, path: next.path };
204
+ } catch (cause) {
205
+ const message = cause instanceof Error ? cause.message : String(cause);
206
+ observe('graph_node_op', 'refused', ctx, { graphId, runId, nodeId, op, reason, error: message });
207
+ return error('graph_node_op', message);
208
+ }
209
+ }
210
+ try {
211
+ const parsed = parseGraphTemplateYaml(readFileSync(graphFile, 'utf8'), graphFile);
212
+ if (!parsed.template || parsed.errors.length) return error('graph_node_op', 'saved graph is invalid');
213
+ const nodeOutput = [...state.nodes].reverse().find(node => node.nodeId === nodeId)?.output;
214
+ const outcome = value(args, 'outcome')!;
215
+ const growth = await (testDeps.growth ?? proposeGrowth)({ graph: parsed.template, nodeId, outcome, runId, output: nodeOutput },
216
+ undefined, () => 'unknown', { root });
217
+ if (!growth.ok) {
218
+ observe('graph_node_op', 'refused', ctx, { graphId, runId, nodeId, op, reason, detail: growth.reason });
219
+ return error('graph_node_op', growth.reason);
220
+ }
221
+ const returnTo = growth.growth.edges.find(edge => edge.from === growth.growth.node.nodeId)?.to;
222
+ if (!returnTo) return error('graph_node_op', 'growth has no return node');
223
+ const next = await (testDeps.run ?? runGraph)(graphFile, { variant: { goal: `mcp_${runId}`,
224
+ plan: { growth: { node: growth.growth.node, from: nodeId, outcome,
225
+ returnTo } } }, input: { source: 'mcp', parentRunId: runId, reason }, deps: { root } });
226
+ observe('graph_node_op', 'add-node', ctx, { graphId, runId: next.runId, parentRunId: runId, nodeId, reason, status: next.status });
227
+ return { output: `add-node: ${next.status}`, graphId, runId: next.runId, parentRunId: runId, status: next.status };
228
+ } catch (cause) {
229
+ const message = cause instanceof Error ? cause.message : String(cause);
230
+ observe('graph_node_op', 'refused', ctx, { graphId, runId, nodeId, op, reason, error: message });
231
+ return error('graph_node_op', message);
232
+ }
233
+ }
234
+
235
+ export const GRAPH_MCP_RUNTIMES: ToolRuntime<Args, Result>[] = [
236
+ { id: 'graph_compose', spec: composeSpec, surfaces: ['mcp'], run: compose },
237
+ { id: 'graph_run_start', spec: startSpec, surfaces: ['mcp'], run: start },
238
+ { id: 'graph_run_status', spec: statusSpec, surfaces: ['mcp'], run: status },
239
+ { id: 'graph_node_op', spec: nodeSpec, surfaces: ['mcp'], run: nodeOp },
240
+ ];
@@ -62,11 +62,14 @@ import { skillExecRuntime } from './skill-exec-runtime.js';
62
62
  import { elanousObsidianSearchRuntime } from './elanous-obsidian-search-runtime.js';
63
63
  import { elanousObsidianInfoRuntime } from './elanous-obsidian-info-runtime.js';
64
64
  import { ELANOUS_ASANA_RUNTIMES } from './elanous-asana-runtimes.js';
65
+ import { elanousLinearSecretaryRuntime } from './elanous-linear-secretary-runtime.js';
66
+ import { elanousLinearIssueRuntime } from './elanous-linear-issue-runtime.js';
65
67
  import { elanousFsListRuntime } from './elanous-fs-list-runtime.js';
66
68
  import { elanousFsReadRuntime } from './elanous-fs-read-runtime.js';
67
69
  import { elanousShowroomBroadcastRuntime } from './elanous-showroom-broadcast-runtime.js';
68
70
  import { elanousAutopilotLaunchRuntime } from './elanous-autopilot-launch-runtime.js';
69
71
  import { elanousTaskSubmitRuntime } from './elanous-task-submit-runtime.js';
72
+ import { GRAPH_MCP_RUNTIMES } from './graph-mcp-runtimes.js';
70
73
  import { persistentGroundingRuntime } from './persistent-grounding-runtime.js';
71
74
  import { goalAuthorRuntime } from './goal-author-runtime.js';
72
75
  import { bootstrapMcpProxyRuntimes } from './mcp-proxy-bootstrap.js';
@@ -167,11 +170,14 @@ export function registerAllDefaultToolRuntimes(opts: RegisterAllDefaultToolRunti
167
170
  registerToolRuntime(elanousObsidianSearchRuntime);
168
171
  registerToolRuntime(elanousObsidianInfoRuntime);
169
172
  for (const rt of ELANOUS_ASANA_RUNTIMES) registerToolRuntime(rt);
173
+ registerToolRuntime(elanousLinearSecretaryRuntime);
174
+ registerToolRuntime(elanousLinearIssueRuntime);
170
175
  registerToolRuntime(elanousFsListRuntime);
171
176
  registerToolRuntime(elanousFsReadRuntime);
172
177
  registerToolRuntime(elanousShowroomBroadcastRuntime);
173
178
  registerToolRuntime(elanousAutopilotLaunchRuntime);
174
179
  registerToolRuntime(elanousTaskSubmitRuntime);
180
+ for (const rt of GRAPH_MCP_RUNTIMES) registerToolRuntime(rt);
175
181
  for (const rt of SELF_COGNITION_RUNTIMES) registerToolRuntime(rt);
176
182
  for (const rt of ELANOUS_CONTROL_RUNTIMES) registerToolRuntime(rt);
177
183
  // External MCP proxies already declare surfaces `['mcp','tui']`, but the
@@ -52,6 +52,8 @@ export interface ToolRuntimeContext {
52
52
  /** MCP only — the connected client's `clientInfo.name` from `initialize`
53
53
  * (e.g. `claude-code`, `codex-mcp-client`). Unset on other surfaces. */
54
54
  mcpClient?: string;
55
+ /** Optional caller-supplied MCP join key. Correlation only; never an authorization input. */
56
+ runId?: string;
55
57
  /** Cancellation — forwarded to underlying dispatcher when
56
58
  * supported (e.g. streaming fetch, long-running agent calls). */
57
59
  signal?: AbortSignal;
@@ -66,6 +68,9 @@ export interface ToolRuntimeContext {
66
68
  dispatch: (name: string, args: Record<string, unknown>) => Promise<unknown>;
67
69
  workingDirectory: string;
68
70
  };
71
+ /** TUI-only opt-in for inheriting the parent's policy-filtered catalog when
72
+ * the general-purpose agent definition omits its own tool allowlist. */
73
+ inheritGeneralPurposeToolCatalog?: boolean;
69
74
  /** M5 (PLAN-rich-dev-feedback-multi-surface · 2026-05-13) —
70
75
  * optional progress emitter. Runtimes that produce streaming
71
76
  * side effects (bash stdout tail, search hit streaming, edit
package/src/tui/entry.ts CHANGED
@@ -99,6 +99,9 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
99
99
  let sidetabChordTimer: ReturnType<typeof setTimeout> | null = null;
100
100
  let sidetabRemoteFrame: string | null = null;
101
101
  let sidetabRows: import('./sidetab/list.js').SidetabRow[] = [];
102
+ let herdrSidetabRows: import('./sidetab/list.js').SidetabRow[] = [];
103
+ let herdrSidetabRefreshPending = false;
104
+ let herdrSidetabPortal: import('./sidetab/herdr-portal.js').HerdrSidetabPortal | null = null;
102
105
  let sidetabApi: typeof import('./sidetab/list.js') | null = null;
103
106
  // ⚠️ `as` 단언은 «null 로 좁혀지는» 흐름 분석을 푸는 것 — 값은 클로저(ensureSidetabAttachments) 안에서만 바뀐다.
104
107
  let sidetabAttachments: import('./sidetab/attach.js').SidetabAttachmentController | null = null as import('./sidetab/attach.js').SidetabAttachmentController | null;
@@ -357,6 +360,8 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
357
360
 
358
361
  const ensureSidetabAttachments = async (): Promise<void> => {
359
362
  if (sidetabAttachments) return;
363
+ const herdrPortalModule = await import('./sidetab/herdr-portal.js');
364
+ herdrSidetabPortal ??= herdrPortalModule.createHerdrSidetabPortal();
360
365
  const installer = await import('../agent-mission/tool-install.js') as unknown as {
361
366
  detectAgentCli?: (agent: 'codex' | 'claude') => Promise<{
362
367
  agent: 'codex' | 'claude'; installed: boolean; version: string | null;
@@ -364,6 +369,8 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
364
369
  }>;
365
370
  };
366
371
  sidetabAttachments = (await import('./sidetab/attach.js')).createSidetabAttachmentController({
372
+ herdrPortal: herdrSidetabPortal,
373
+ logEvent: (category, event, data) => debug.log(category, event, data),
367
374
  drawBase: () => {
368
375
  paintingCoordinatorFrame = true;
369
376
  try { render(); } finally { paintingCoordinatorFrame = false; }
@@ -403,9 +410,11 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
403
410
  sidetabSelected = next.selected;
404
411
  sidetabMode = 'list';
405
412
  if (sidetabOpen && sidetabRefreshTimer === null) {
413
+ void refreshHerdrSidetabRows();
406
414
  sidetabRefreshTimer = setInterval(() => {
407
415
  if (!sidetabOpen || !sidetabApi) return;
408
416
  refreshSidetabRows();
417
+ void refreshHerdrSidetabRows();
409
418
  render();
410
419
  }, 1000);
411
420
  } else if (!sidetabOpen && sidetabRefreshTimer !== null) {
@@ -417,12 +426,24 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
417
426
  const refreshSidetabRows = (): void => {
418
427
  if (!sidetabApi) return;
419
428
  const selectedId = sidetabRows[sidetabSelected]?.id;
420
- sidetabRows = sidetabApi.loadSidetabRows(sidetabAll);
429
+ sidetabRows = [...sidetabApi.loadSidetabRows(sidetabAll), ...herdrSidetabRows];
421
430
  const preservedIndex = selectedId ? sidetabRows.findIndex((row) => row.id === selectedId) : -1;
422
431
  sidetabSelected = preservedIndex >= 0
423
432
  ? preservedIndex
424
433
  : Math.min(sidetabSelected, Math.max(0, sidetabRows.length - 1));
425
434
  };
435
+ const refreshHerdrSidetabRows = async (): Promise<void> => {
436
+ if (herdrSidetabRefreshPending) return;
437
+ herdrSidetabRefreshPending = true;
438
+ try {
439
+ const portal = await import('./sidetab/herdr-portal.js');
440
+ herdrSidetabPortal ??= portal.createHerdrSidetabPortal();
441
+ await herdrSidetabPortal.refreshRows();
442
+ herdrSidetabRows = [...herdrSidetabPortal.rows()];
443
+ refreshSidetabRows();
444
+ } catch { /* Herdr is optional; TUI rows remain available. */ }
445
+ finally { herdrSidetabRefreshPending = false; }
446
+ };
426
447
  const switchSidetabSession = async (requestedSessionId?: string): Promise<void> => {
427
448
  const selected = sidetabRows[sidetabSelected];
428
449
  const targetId = requestedSessionId ?? (selected?.kind === 'tui' ? selected.sessionId : undefined);
@@ -590,10 +611,21 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
590
611
  firstResponseSeen = true;
591
612
  dashboardRuntime.endTurnStartSegments(turnSessionId, 'stream-open');
592
613
  }
593
- // The first model token is visible before the final JSONL frame. Keep only
594
- // a bounded tail until session history becomes the canonical display.
595
- streamingReply = replace ? delta.slice(-32_768) : (streamingReply + delta).slice(-32_768);
596
- activity = streamReplyLines(streamingReply, process.stdout.columns || 80);
614
+ // The first model token is visible while the turn runs. Once the core
615
+ // replaces that provisional answer, let the persisted final message
616
+ // become canonical instead of showing the same answer in both layers.
617
+ if (replace) {
618
+ streamingReply = '';
619
+ activity = [];
620
+ if (streamRenderTimer !== null) clearTimeout(streamRenderTimer);
621
+ streamRenderTimer = null;
622
+ streamRenderAt = performance.now();
623
+ render();
624
+ return;
625
+ } else {
626
+ streamingReply = (streamingReply + delta).slice(-32_768);
627
+ activity = streamReplyLines(streamingReply, process.stdout.columns || 80);
628
+ }
597
629
  const now = performance.now();
598
630
  if (streamRenderAt === 0 || now - streamRenderAt >= 33) {
599
631
  streamRenderAt = now;
@@ -636,7 +668,6 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
636
668
  activity = [];
637
669
  streamingReply = '';
638
670
  busy = false;
639
- reportTuiTurn('idle');
640
671
  turnAbort = null;
641
672
  scroll = 0;
642
673
  settle();
@@ -659,17 +690,28 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
659
690
  }
660
691
  const switchAfterTurn = pendingSidetabSwitch;
661
692
  pendingSidetabSwitch = null;
662
- if (switchAfterTurn) await switchSidetabSession(switchAfterTurn);
663
- render();
693
+ try {
694
+ if (switchAfterTurn) await switchSidetabSession(switchAfterTurn);
695
+ } finally {
696
+ try {
697
+ render();
698
+ } finally {
699
+ // Publish idle only after the canonical history has replaced the stream preview
700
+ // on screen. External PTY observers use this edge as their capture boundary.
701
+ reportTuiTurn('idle');
702
+ }
703
+ }
664
704
  });
665
705
  };
666
706
 
667
707
  if (sidetabOpen) {
668
708
  sidetabApi = await import('./sidetab/list.js');
669
709
  sidetabRows = sidetabApi.loadSidetabRows(sidetabAll);
710
+ void refreshHerdrSidetabRows();
670
711
  sidetabRefreshTimer = setInterval(() => {
671
712
  if (!sidetabApi || !sidetabOpen) return;
672
713
  refreshSidetabRows();
714
+ void refreshHerdrSidetabRows();
673
715
  render();
674
716
  }, 1_000);
675
717
  }
@@ -731,6 +773,7 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
731
773
  detach: () => { if (sidetabAttachments?.hasRemoteView()) sidetabAttachments.showMain(); else if (sidetabAttachments?.hasModal()) { sidetabAttachments.handleKey({ name: '\\', ctrl: true, shift: false, raw: '' }); sidetabAttachments.handleKey({ name: 'd', ctrl: false, shift: false, raw: 'd' }); } render(); return { ok: true, action: 'detach' }; },
732
774
  spawn: async (character) => { await ensureSidetabAttachments(); const ok = sidetabAttachments!.spawn(character); refreshSidetabRows(); render(); return { ok, action: 'new', character }; },
733
775
  runMission: async (agent, mission) => { await ensureSidetabAttachments(); const result = await sidetabAttachments!.runMission(agent, mission); refreshSidetabRows(); render(); return result; },
776
+ runMissionPair: async (agent, mission, parallelMission) => { await ensureSidetabAttachments(); const result = await sidetabAttachments!.runMissionPair(agent, mission, parallelMission); refreshSidetabRows(); render(); return result; },
734
777
  kill: async (row) => { await ensureSidetabAttachments(); const ok = sidetabAttachments!.kill(row); refreshSidetabRows(); render(); return { ok, action: 'kill', target: row.id }; },
735
778
  }));
736
779
  const gate = wakeup.gate;