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,311 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { mkdirSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { getSecretAsync } from '../../src/nexus/config/secrets/index.js';
5
+ import { commentLinearIssue } from '../../src/connectors/linear.js';
6
+ import { listChecklist, type Checklist, type ChecklistItem } from '../../src/release-loop/checklist.js';
7
+ import { DecisionLedger, type DecisionEntry } from '../../src/decisions/decision-ledger.js';
8
+ import { effectiveInstanceRoot } from '../../src/instance/resolve.js';
9
+ import { debug } from '../../src/debug/log.js';
10
+ import { acquireLockAsync } from '../../src/storage/file-lock.js';
11
+
12
+ export type ProgressIssue = {
13
+ id: string; identifier: string; title: string; url: string; description: string; state: string;
14
+ /** Verified Linear team key; live writes fail closed unless this is DEMO. */
15
+ teamKey: string;
16
+ };
17
+ export type ProgressLink = { issue: ProgressIssue; cells: ChecklistItem[]; decisions: DecisionEntry[]; sources: Array<{ cellId: string; field: string }> };
18
+ export type ProgressPreview = { identifier: string; body: string; sources: Array<{ cellId: string; field: string }> };
19
+ export type ProgressSyncResult = {
20
+ day: string; candidates: ProgressPreview[]; posted: string[]; alreadyPresent: string[];
21
+ skipped: string[]; failures: Array<{ identifier: string; reason: string }>;
22
+ };
23
+
24
+ const kstDay = (date: Date) => new Date(date.getTime() + 9 * 3_600_000).toISOString().slice(0, 10);
25
+ const escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
26
+
27
+ function exactReference(source: string, token: string): boolean {
28
+ return new RegExp(`(^|[^A-Z0-9_-])${escapeRegExp(token)}($|[^A-Z0-9_-])`).test(source);
29
+ }
30
+
31
+ function declaredIssueRefs(source: string): string[] {
32
+ const refs: string[] = [];
33
+ for (const declaration of source.matchAll(/\blinear-ref\s*[:=]\s*([^\r\n]+)/gi)) {
34
+ refs.push(...[...(declaration[1] ?? '').matchAll(/\b[A-Z]{2,8}-\d+\b/g)].map(match => match[0]!));
35
+ }
36
+ return [...new Set(refs)];
37
+ }
38
+
39
+ /** Only `linear-ref:` declarations in checklist fields and exact checklist IDs in issue descriptions create a link. */
40
+ export function resolveExplicitProgressLinks(issues: readonly ProgressIssue[], checklist: Checklist, decisions: readonly DecisionEntry[] = []): ProgressLink[] {
41
+ const links: ProgressLink[] = [];
42
+ for (const issue of issues) {
43
+ const cells = new Map<string, ChecklistItem>();
44
+ const sources: Array<{ cellId: string; field: string }> = [];
45
+ for (const cell of checklist.items) {
46
+ const declared: Array<[string, string]> = [
47
+ ['title', cell.title], ['evidence', cell.evidence ?? ''], ['refs', (cell.refs ?? []).join('\n')],
48
+ ];
49
+ for (const [field, value] of declared) {
50
+ if (declaredIssueRefs(value).includes(issue.identifier)) {
51
+ cells.set(cell.id, cell);
52
+ sources.push({ cellId: cell.id, field: `checklist.${field}` });
53
+ }
54
+ }
55
+ if (exactReference(issue.description, cell.id)) {
56
+ cells.set(cell.id, cell);
57
+ sources.push({ cellId: cell.id, field: 'issue.description' });
58
+ }
59
+ }
60
+ const linkedDecisions = decisions.filter(decision => decision.refs?.some(ref => ref === issue.identifier || ref === issue.url));
61
+ for (const decision of linkedDecisions) sources.push({ cellId: decision.id, field: 'decision.refs' });
62
+ if (cells.size || linkedDecisions.length) links.push({ issue, cells: [...cells.values()], decisions: linkedDecisions, sources });
63
+ }
64
+ return links;
65
+ }
66
+
67
+ function changedStatuses(checklist: Checklist, cellIds: ReadonlySet<string>, day: string): Array<{ id: string; from: string; to: string }> {
68
+ return checklist.history.flatMap(entry => {
69
+ if (!cellIds.has(entry.id) || entry.field !== 'status' || !entry.at || kstDay(new Date(entry.at)) !== day) return [];
70
+ return [{ id: entry.id, from: String(entry.from ?? 'unknown'), to: String(entry.to ?? 'unknown') }];
71
+ });
72
+ }
73
+
74
+ export function renderProgressPreview(link: ProgressLink, checklist: Checklist, day: string): ProgressPreview {
75
+ const ids = new Set(link.cells.map(cell => cell.id));
76
+ const transitions = changedStatuses(checklist, ids, day);
77
+ const statusLines = link.cells.map(cell => {
78
+ const evidence = cell.evidence ?? '';
79
+ const simulated = cell.status === 'green' && /green\(sim\)/i.test(evidence);
80
+ const e4Pending = simulated && /(?:설치본|installed)(?: CLI)?[^\n.]{0,24}E4[^\n.]{0,24}(?:미완|incomplete|not complete|not done)/i.test(evidence);
81
+ return `- 연결 칸: ${cell.id} — ${simulated ? `green(sim)${e4Pending ? ' · 설치본 E4 미완' : ''}` : cell.status}`;
82
+ });
83
+ const transitionLines = transitions.map(change => `- 오늘 상태 변화: ${change.id} ${change.from} → ${change.to}`);
84
+ const decisionLines = link.decisions.filter(decision => {
85
+ const timestamp = decision.decidedAt ?? decision.withdrawnAt ?? decision.raisedAt;
86
+ return !!timestamp && kstDay(new Date(timestamp)) === day;
87
+ })
88
+ .map(decision => `- 연결 결정: ${decision.id} — ${decision.status}`);
89
+ const landedPrs = [...new Set(link.cells.flatMap(cell => {
90
+ const text = cell.evidence ?? '';
91
+ return [...text.matchAll(/\bPR\s*#(\d+)\b[^\n]{0,120}\bmerged\b/gi)].map(match => `#${match[1]}`);
92
+ }))];
93
+ const nextCell = link.cells.find(cell => cell.status !== 'green' && cell.status !== 'done');
94
+ const simulatedCell = link.cells.find(cell => cell.status === 'green' && /green\(sim\)/i.test(cell.evidence ?? ''));
95
+ const simulatedEvidence = simulatedCell?.evidence ?? '';
96
+ const simulatedE4Pending = !!simulatedCell && /(?:설치본|installed)(?: CLI)?[^\n.]{0,24}E4[^\n.]{0,24}(?:미완|incomplete|not complete|not done)/i.test(simulatedEvidence);
97
+ const next = nextCell ? `연결 칸 ${nextCell.id}의 남은 완료 경계 진행`
98
+ : simulatedCell ? `연결 칸 ${simulatedCell.id}의 ${simulatedE4Pending ? '설치본 E4 실물 증거 확보' : '설치본 실물 증거 확인'}` : '연결된 칸은 현재 green/done';
99
+ const body = [
100
+ `${day} 진행 요약`,
101
+ `- 상태: ${link.issue.state} — ${link.issue.url}`,
102
+ ...statusLines,
103
+ ...transitionLines,
104
+ ...decisionLines,
105
+ ...(landedPrs.length ? [`- 연결 착지 PR: ${landedPrs.join(', ')}`] : []),
106
+ `- 다음: ${next}`,
107
+ `<!-- elanous-linear-progress:${day}:${link.issue.identifier} -->`,
108
+ ].join('\n');
109
+ return { identifier: link.issue.identifier, body, sources: link.sources };
110
+ }
111
+
112
+ async function fetchTeamIssues(apiKey: string, teamKey: string, fetchFn: typeof fetch = fetch): Promise<ProgressIssue[]> {
113
+ const query = `query LinearProgressIssues($teamKey: String!, $after: String) {
114
+ issues(filter: { team: { key: { eq: $teamKey } } }, first: 100, after: $after) {
115
+ nodes { id identifier title url description state { name } team { key } }
116
+ pageInfo { hasNextPage endCursor }
117
+ }
118
+ }`;
119
+ const issues: ProgressIssue[] = [];
120
+ const cursors = new Set<string>();
121
+ let after: string | null = null;
122
+ do {
123
+ const response = await fetchFn('https://api.linear.app/graphql', {
124
+ method: 'POST', headers: { Authorization: apiKey, 'Content-Type': 'application/json' },
125
+ body: JSON.stringify({ query, variables: { teamKey, after } }),
126
+ });
127
+ if (!response.ok) throw new Error(`Linear GraphQL HTTP ${response.status}`);
128
+ const result = await response.json() as { errors?: unknown[]; data?: { issues?: { nodes?: Array<Record<string, unknown>>; pageInfo?: { hasNextPage: boolean; endCursor: string | null } } } };
129
+ const page = result.data?.issues;
130
+ if (result.errors?.length || !Array.isArray(page?.nodes)) throw new Error(`Linear ${teamKey} issue query failed`);
131
+ for (const node of page.nodes) {
132
+ if (typeof node.id !== 'string' || typeof node.identifier !== 'string' || typeof node.title !== 'string' || typeof node.url !== 'string') continue;
133
+ const state = node.state && typeof node.state === 'object' ? (node.state as { name?: unknown }).name : undefined;
134
+ const team = node.team && typeof node.team === 'object' ? (node.team as { key?: unknown }).key : undefined;
135
+ issues.push({ id: node.id, identifier: node.identifier, title: node.title, url: node.url,
136
+ description: typeof node.description === 'string' ? node.description : '', state: typeof state === 'string' ? state : 'unknown',
137
+ teamKey: typeof team === 'string' ? team : '' });
138
+ }
139
+ const info = page.pageInfo;
140
+ if (info?.hasNextPage && (!info.endCursor || cursors.has(info.endCursor))) throw new Error(`Linear ${teamKey} cursor missing or repeated`);
141
+ after = info?.hasNextPage ? info.endCursor : null;
142
+ if (after) cursors.add(after);
143
+ } while (after);
144
+ return issues;
145
+ }
146
+
147
+ async function fetchAllowlistedIssue(apiKey: string, identifier: string, fetchFn: typeof fetch = fetch): Promise<ProgressIssue | null> {
148
+ const query = `query LinearAllowlistedProgressIssue($identifier: String!) {
149
+ issue(id: $identifier) { id identifier title url description state { name } team { key } }
150
+ }`;
151
+ const response = await fetchFn('https://api.linear.app/graphql', {
152
+ method: 'POST', headers: { Authorization: apiKey, 'Content-Type': 'application/json' },
153
+ body: JSON.stringify({ query, variables: { identifier } }),
154
+ });
155
+ if (!response.ok) throw new Error(`Linear ${identifier} lookup HTTP ${response.status}`);
156
+ const result = await response.json() as { errors?: unknown[]; data?: { issue?: Record<string, unknown> | null } };
157
+ const node = result.data?.issue;
158
+ if (result.errors?.length) throw new Error(`Linear ${identifier} lookup failed`);
159
+ if (!node || typeof node.id !== 'string' || typeof node.identifier !== 'string' || typeof node.title !== 'string' || typeof node.url !== 'string') return null;
160
+ const state = node.state && typeof node.state === 'object' ? (node.state as { name?: unknown }).name : undefined;
161
+ const team = node.team && typeof node.team === 'object' ? (node.team as { key?: unknown }).key : undefined;
162
+ return { id: node.id, identifier: node.identifier, title: node.title, url: node.url,
163
+ description: typeof node.description === 'string' ? node.description : '', state: typeof state === 'string' ? state : 'unknown',
164
+ teamKey: typeof team === 'string' ? team : '' };
165
+ }
166
+
167
+ async function countMarker(apiKey: string, issueId: string, marker: string, fetchFn: typeof fetch = fetch): Promise<number> {
168
+ const query = `query LinearProgressComments($id: String!, $after: String) {
169
+ issue(id: $id) { comments(first: 100, after: $after) { nodes { body } pageInfo { hasNextPage endCursor } } }
170
+ }`;
171
+ const cursors = new Set<string>();
172
+ let after: string | null = null;
173
+ let count = 0;
174
+ do {
175
+ const response = await fetchFn('https://api.linear.app/graphql', {
176
+ method: 'POST', headers: { Authorization: apiKey, 'Content-Type': 'application/json' },
177
+ body: JSON.stringify({ query, variables: { id: issueId, after } }),
178
+ });
179
+ if (!response.ok) throw new Error(`Linear comment lookup HTTP ${response.status}`);
180
+ const result = await response.json() as { errors?: unknown[]; data?: { issue?: { comments?: { nodes?: Array<{ body?: unknown }>; pageInfo?: { hasNextPage: boolean; endCursor: string | null } } } } };
181
+ const comments = result.data?.issue?.comments;
182
+ if (result.errors?.length || !Array.isArray(comments?.nodes)) throw new Error('Linear comment lookup failed');
183
+ count += comments.nodes.filter(comment => typeof comment.body === 'string' && comment.body.includes(marker)).length;
184
+ const info = comments.pageInfo;
185
+ if (info?.hasNextPage && (!info.endCursor || cursors.has(info.endCursor))) throw new Error('Linear comment cursor missing or repeated');
186
+ after = info?.hasNextPage ? info.endCursor : null;
187
+ if (after) cursors.add(after);
188
+ } while (after);
189
+ return count;
190
+ }
191
+
192
+ export async function runLinearProgressSync(options: {
193
+ version: string; now?: Date; root?: string; runId?: string; apply?: boolean;
194
+ allowIssueIdentifiers?: readonly string[];
195
+ checklist?: Checklist; issues?: readonly ProgressIssue[]; decisions?: readonly DecisionEntry[];
196
+ getApiKey?: (id: string) => Promise<string | undefined>;
197
+ fetch?: typeof fetch;
198
+ countMarker?: (issue: ProgressIssue, marker: string) => Promise<number>;
199
+ postComment?: (issue: ProgressIssue, body: string) => Promise<void>;
200
+ log?: (event: string, data: Record<string, unknown>) => void;
201
+ }): Promise<ProgressSyncResult> {
202
+ const now = options.now ?? new Date();
203
+ const day = kstDay(now);
204
+ const root = options.root ?? effectiveInstanceRoot();
205
+ const checklist = options.checklist ?? listChecklist(options.version, root);
206
+ const decisions = options.decisions ?? new DecisionLedger({ stateDir: root }).list({ status: 'all' });
207
+ const apiKey = (options.getApiKey ?? getSecretAsync)('connector.linear.apiKey');
208
+ const resolvedKey = await apiKey;
209
+ const fetchFn = options.fetch ?? fetch;
210
+ if (!resolvedKey) throw new Error('connector.linear.apiKey missing');
211
+ const allowedIdentifiers = [...new Set(options.allowIssueIdentifiers ?? [])];
212
+ const lookupFailures: Array<{ identifier: string; reason: string }> = [];
213
+ let issues: ProgressIssue[];
214
+ if (options.issues) issues = [...options.issues];
215
+ else if (options.apply) {
216
+ const lookups = await Promise.all(allowedIdentifiers.map(async identifier => {
217
+ try {
218
+ const issue = await fetchAllowlistedIssue(resolvedKey, identifier, fetchFn);
219
+ if (!issue) lookupFailures.push({ identifier, reason: 'allowlisted issue not found' });
220
+ return issue;
221
+ } catch (error) {
222
+ lookupFailures.push({ identifier, reason: (error instanceof Error ? error.message : String(error)).slice(0, 200) });
223
+ return null;
224
+ }
225
+ }));
226
+ issues = lookups.filter((issue): issue is ProgressIssue => issue !== null);
227
+ } else issues = await fetchTeamIssues(resolvedKey, 'DEMO', fetchFn);
228
+ const links = resolveExplicitProgressLinks(issues, checklist, decisions);
229
+ const previews = links.map(link => renderProgressPreview(link, checklist, day));
230
+ const linkedIdentifiers = new Set(links.map(link => link.issue.identifier));
231
+ const fetchedIdentifiers = new Set(issues.map(issue => issue.identifier));
232
+ const lookupFailureIdentifiers = new Set(lookupFailures.map(failure => failure.identifier));
233
+ const missingApproved = options.apply ? allowedIdentifiers.filter(identifier => !fetchedIdentifiers.has(identifier) && !lookupFailureIdentifiers.has(identifier))
234
+ .map(identifier => ({ identifier, reason: 'allowlisted issue not found' })) : [];
235
+ const unlinkedApproved = options.apply ? allowedIdentifiers.filter(identifier => issues.some(issue => issue.identifier === identifier) && !linkedIdentifiers.has(identifier))
236
+ .map(identifier => ({ identifier, reason: 'allowlisted issue has no explicit checklist/decision link' })) : [];
237
+ const unresolvedApproved = [...lookupFailures, ...missingApproved, ...unlinkedApproved];
238
+ const result: ProgressSyncResult = { day, candidates: previews, posted: [], alreadyPresent: [], skipped: [], failures: unresolvedApproved };
239
+ const log = (event: string, data: Record<string, unknown>) => {
240
+ const enriched = { day, ...data, ...(options.runId ? { runId: options.runId } : {}) };
241
+ if (options.log) options.log(event, enriched);
242
+ else debug.log('loop.rhythm-daily.linear-progress', event, enriched);
243
+ };
244
+ const check = options.countMarker ?? ((issue: ProgressIssue, marker: string) => countMarker(resolvedKey, issue.id, marker, fetchFn));
245
+ const post = options.postComment ?? ((issue: ProgressIssue, body: string) => commentLinearIssue({ apiKey: resolvedKey, issueId: issue.id, body }));
246
+ for (const failure of unresolvedApproved) log('approved-issue-unresolved', failure);
247
+ for (const preview of previews) {
248
+ const issue = links.find(link => link.issue.identifier === preview.identifier)!.issue;
249
+ const marker = `<!-- elanous-linear-progress:${day}:${issue.identifier} -->`;
250
+ if (issue.teamKey !== 'DEMO') {
251
+ result.skipped.push(issue.identifier);
252
+ log('not-demo-team', { identifier: issue.identifier, teamKey: issue.teamKey || 'unknown', sources: preview.sources });
253
+ continue;
254
+ }
255
+ let release: (() => void) | undefined;
256
+ let stillHeld: (() => boolean) | undefined;
257
+ try {
258
+ if (options.apply && !options.allowIssueIdentifiers?.includes(issue.identifier)) {
259
+ result.skipped.push(issue.identifier);
260
+ log('not-approved', { identifier: issue.identifier, sources: preview.sources });
261
+ continue;
262
+ }
263
+ if (options.apply) {
264
+ const lockDir = join(root, 'rhythm', 'linear-progress-sync');
265
+ mkdirSync(lockDir, { recursive: true, mode: 0o700 });
266
+ const lockName = createHash('sha256').update(`${day}:${issue.id}`).digest('hex');
267
+ const lock = await acquireLockAsync(join(lockDir, `${lockName}.lock`), { staleMs: 120_000, maxTries: 240 });
268
+ release = lock.release;
269
+ stillHeld = lock.stillHeld;
270
+ if (!stillHeld()) throw new Error('Linear progress lock lost before marker check');
271
+ }
272
+ const existing = await check(issue, marker);
273
+ if (existing > 1) {
274
+ result.failures.push({ identifier: issue.identifier, reason: `duplicate-marker-count=${existing}` });
275
+ log('duplicate-marker', { identifier: issue.identifier, markerCount: existing, sources: preview.sources });
276
+ continue;
277
+ }
278
+ if (existing === 1) {
279
+ result.alreadyPresent.push(issue.identifier);
280
+ log('already-present', { identifier: issue.identifier, markerCount: 1, sources: preview.sources });
281
+ continue;
282
+ }
283
+ if (!options.apply) {
284
+ result.skipped.push(issue.identifier);
285
+ log('dry-run', { identifier: issue.identifier, markerCount: 0, sources: preview.sources });
286
+ continue;
287
+ }
288
+ if (!release || !stillHeld?.()) throw new Error('Linear progress write lock unavailable or lost');
289
+ await post(issue, preview.body);
290
+ const verified = await check(issue, marker);
291
+ if (verified !== 1) throw new Error(`post-verification-marker-count=${verified}`);
292
+ result.posted.push(issue.identifier);
293
+ log('posted', { identifier: issue.identifier, markerCount: verified, sources: preview.sources });
294
+ } catch (error) {
295
+ const reason = error instanceof Error ? error.message : String(error);
296
+ result.failures.push({ identifier: issue.identifier, reason: reason.slice(0, 200) });
297
+ log('failed', { identifier: issue.identifier, reason: reason.slice(0, 200), sources: preview.sources });
298
+ } finally {
299
+ release?.();
300
+ }
301
+ }
302
+ return result;
303
+ }
304
+
305
+ if (import.meta.main) {
306
+ const version = process.argv.find((arg, index) => process.argv[index - 1] === '--version');
307
+ if (!version) throw new Error('--version required');
308
+ if (process.argv.includes('--apply')) throw new Error('live posting requires the approved scheduled daily path');
309
+ const result = await runLinearProgressSync({ version, apply: false });
310
+ console.log(JSON.stringify(result));
311
+ }
package/scripts/ux-sim.ts CHANGED
@@ -21,10 +21,11 @@
21
21
  // bun scripts/ux-sim.ts emit child-error-long --json # 사건 주입(L0): 격리 우주 원장에 주입 줄 → 소비자 목록
22
22
  //
23
23
  // catalog list/show 는 재사용 장치의 참조를 보여 준다. 선언된 TUI 장면은 실제 위젯 render() 를 부른다 — 흉내 렌더러가 아니다.
24
+ // catalog devices 는 장치별 진입 명령·logs/event·최근 사용 메타데이터를 읽기 전용으로 출력한다.
24
25
  import { simRenderLogFrame } from '../src/ux-sim/render-frame.js';
25
26
  import { simTypeaheadState, type TurnPhase, type TurnSimSpec } from '../src/ux-sim/turn-states.js';
26
27
  import { renderTurnTypeaheadQueueRow, renderTurnTypeaheadEcho } from '../src/chat/turn-typeahead.js';
27
- import { loadMockScenarioCatalog, renderMockScenarioDetails, renderMockScenarioList } from '../src/ux-sim/mock-scenario-catalog.js';
28
+ import { loadMockScenarioCatalog, renderMockScenarioDetails, renderMockScenarioDevices, renderMockScenarioList } from '../src/ux-sim/mock-scenario-catalog.js';
28
29
 
29
30
  const PHASES: TurnPhase[] = [
30
31
  'idle', 'thinking', 'streaming', 'streaming-with-subagents', 'harness-child', 'interrupted',
@@ -37,6 +38,11 @@ if (argv[0] === 'list') {
37
38
  console.log(renderMockScenarioList(loadMockScenarioCatalog()).join('\n'));
38
39
  process.exit(0);
39
40
  }
41
+ if (argv[0] === 'devices') {
42
+ if (argv.length !== 1) { console.error('usage: bun scripts/ux-sim.ts devices'); process.exit(2); }
43
+ console.log(renderMockScenarioDevices(loadMockScenarioCatalog()).join('\n'));
44
+ process.exit(0);
45
+ }
40
46
  if (argv[0] === 'show') {
41
47
  if (argv.length !== 2) { console.error('usage: bun scripts/ux-sim.ts show <MS-id>'); process.exit(2); }
42
48
  try {
@@ -1092,7 +1092,15 @@ async function plan() {
1092
1092
  ovSelections = sel.selections.map((x) => ({ overlayId: x.overlayId, verdict: x.verdict, detail: x.detail }));
1093
1093
  if (sel.applied.length > 0) {
1094
1094
  const applied = applyGraphOverlays(decl.template, sel.applied);
1095
- if (applied.ok) ovPatches = applied.patches.map((x) => ({ overlayId: x.overlayId, node: x.node, field: x.field, before: (x as { before: unknown }).before, after: (x as { after: unknown }).after }));
1095
+ if (applied.ok) ovPatches = applied.patches.map((x) => {
1096
+ if (x.field === 'edge-rerouted') return {
1097
+ overlayId: x.overlayId, node: x.from, field: x.field, before: x.was, after: x.to,
1098
+ };
1099
+ if (x.field === 'node-added') return {
1100
+ overlayId: x.overlayId, node: x.node, field: x.field, before: null, after: x.kind,
1101
+ };
1102
+ return { overlayId: x.overlayId, node: x.node, field: x.field, before: x.before, after: x.after };
1103
+ });
1096
1104
  else ovError = `얹다가 거절됐다 — ${applied.rejections.map((r) => r.kind).join(', ')}`;
1097
1105
  }
1098
1106
  }
@@ -4,6 +4,7 @@ import { dirname, isAbsolute, join } from 'node:path';
4
4
  import { randomUUID } from 'node:crypto';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { userConfigPath } from '../src/user-config.js';
7
+ import type { WarmWorkerCandidate } from '../src/task-orchestrator/surfaces/pod-warm-worker-provider.js';
7
8
 
8
9
  const TOKEN = /^[a-f0-9]{64}$/;
9
10
  const SHA = /^[a-f0-9]{40}$/;
@@ -14,7 +15,8 @@ const TIERS = new Set(['lite', 'standard']);
14
15
  type JsonObject = Record<string, unknown>;
15
16
 
16
17
  export interface WarmPoolProviderConfig {
17
- candidates: [];
18
+ candidates: WarmWorkerCandidate[];
19
+ expandPoolTemplatesToQuota: boolean;
18
20
  poolTemplates: Array<{
19
21
  host: string;
20
22
  tier: 'lite' | 'standard';
@@ -47,6 +49,25 @@ export interface AssembleWarmPoolProviderConfigInput {
47
49
  machineTokens: Record<string, string>;
48
50
  }
49
51
 
52
+ /** Keep a deployment canary to one explicit worker instead of expanding its profile quota. */
53
+ export function selectSingleWarmPoolCandidate(config: WarmPoolProviderConfig, selection: string): WarmPoolProviderConfig {
54
+ const match = /^([a-zA-Z0-9][a-zA-Z0-9._-]*)\/(lite|standard)$/.exec(selection);
55
+ if (!match) throw new Error('--single-candidate must be HOST/lite or HOST/standard');
56
+ const [, host, tier] = match;
57
+ const template = config.poolTemplates.find(candidate => candidate.host === host && candidate.tier === tier);
58
+ if (!template) throw new Error(`warm pool template not found: ${host}/${tier}`);
59
+ const index = 1;
60
+ return {
61
+ ...config,
62
+ candidates: [{ host, tier: tier as 'lite' | 'standard', spec: {
63
+ ...template.spec,
64
+ name: `warm-${host}-${tier}-${index}`,
65
+ workerId: `${template.spec.workerId}-${tier}-${index}`,
66
+ } }],
67
+ poolTemplates: [],
68
+ };
69
+ }
70
+
50
71
  function object(value: unknown, label: string): JsonObject {
51
72
  if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${label} is required`);
52
73
  return value as JsonObject;
@@ -117,6 +138,9 @@ export function assembleWarmPoolProviderConfig(input: AssembleWarmPoolProviderCo
117
138
  const imageRepository = text(pool.imageRepository, 'pod.warmPool.imageRepository').replace(/\/$/, '');
118
139
  const imageDigest = text(pool.imageDigest, 'pod.warmPool.imageDigest');
119
140
  if (!DIGEST.test(imageDigest)) throw new Error('pod.warmPool.imageDigest must be a sha256 digest');
141
+ const expandPoolTemplatesToQuota = pool.expandPoolTemplatesToQuota;
142
+ if (expandPoolTemplatesToQuota !== undefined && typeof expandPoolTemplatesToQuota !== 'boolean')
143
+ throw new Error('pod.warmPool.expandPoolTemplatesToQuota must be a boolean');
120
144
  const lockHash = text(pool.lockHash, 'pod.warmPool.lockHash');
121
145
  if (!LOCK_HASH.test(lockHash)) throw new Error('pod.warmPool.lockHash must be a 64-character SHA-256');
122
146
  const architecture = text(pool.architecture, 'pod.warmPool.architecture');
@@ -150,7 +174,8 @@ export function assembleWarmPoolProviderConfig(input: AssembleWarmPoolProviderCo
150
174
  },
151
175
  };
152
176
  });
153
- return { candidates: [], poolTemplates, profileConfig: { pod: { warmPoolProfile: profile } },
177
+ return { candidates: [], expandPoolTemplatesToQuota: expandPoolTemplatesToQuota === true,
178
+ poolTemplates, profileConfig: { pod: { warmPoolProfile: profile } },
154
179
  controlUrl: controlUrl(input.controlUrl), memberToken: token(input.memberToken, 'member token'), machineTokens };
155
180
  }
156
181
 
@@ -183,11 +208,12 @@ interface CliOptions {
183
208
  output: string;
184
209
  dryRun: boolean;
185
210
  serve: boolean;
211
+ singleCandidate?: string;
186
212
  }
187
213
 
188
214
  function parseArgs(argv: readonly string[]): CliOptions {
189
215
  let configPath = userConfigPath(), controlUrl = '', memberTokenFile = '', output = '';
190
- let dryRun = false, serve = false;
216
+ let dryRun = false, serve = false, singleCandidate: string | undefined;
191
217
  const machineTokenFiles: Record<string, string> = {};
192
218
  for (let index = 0; index < argv.length; index++) {
193
219
  const arg = argv[index];
@@ -206,14 +232,15 @@ function parseArgs(argv: readonly string[]): CliOptions {
206
232
  } else if (arg === '--output') output = next();
207
233
  else if (arg === '--dry-run') dryRun = true;
208
234
  else if (arg === '--serve') serve = true;
235
+ else if (arg === '--single-candidate') singleCandidate = next();
209
236
  else throw new Error(`unknown argument: ${arg}`);
210
237
  }
211
238
  if (!isAbsolute(configPath) || !controlUrl || !isAbsolute(memberTokenFile))
212
- throw new Error('usage: --config ABSOLUTE --control-url URL --member-token-file ABSOLUTE --machine-token HOST=ABSOLUTE [--output ABSOLUTE] [--dry-run|--serve]');
239
+ throw new Error('usage: --config ABSOLUTE --control-url URL --member-token-file ABSOLUTE --machine-token HOST=ABSOLUTE [--output ABSOLUTE] [--single-candidate HOST/TIER] [--dry-run|--serve]');
213
240
  if (Object.values(machineTokenFiles).some(file => !isAbsolute(file))) throw new Error('machine token files must be absolute');
214
241
  if (dryRun && serve) throw new Error('--dry-run and --serve cannot be combined');
215
242
  return { configPath, controlUrl, memberTokenFile, machineTokenFiles,
216
- output: output || join(dirname(configPath), 'warm-pod-provider.json'), dryRun, serve };
243
+ output: output || join(dirname(configPath), 'warm-pod-provider.json'), dryRun, serve, singleCandidate };
217
244
  }
218
245
 
219
246
  function readPrivateToken(path: string, label: string): string {
@@ -228,8 +255,9 @@ export async function runWarmPoolProviderConfig(argv: readonly string[]): Promis
228
255
  .map(([host, path]) => [host, readPrivateToken(path, `machine token for ${host}`)]));
229
256
  const assembled = assembleWarmPoolProviderConfig({ config, controlUrl: options.controlUrl,
230
257
  memberToken: readPrivateToken(options.memberTokenFile, 'member token'), machineTokens });
231
- if (!options.dryRun) writeWarmPoolProviderConfig(options.output, assembled);
232
- process.stdout.write(`${JSON.stringify({ output: options.output, config: redact(assembled),
258
+ const selected = options.singleCandidate ? selectSingleWarmPoolCandidate(assembled, options.singleCandidate) : assembled;
259
+ if (!options.dryRun) writeWarmPoolProviderConfig(options.output, selected);
260
+ process.stdout.write(`${JSON.stringify({ output: options.output, config: redact(selected),
233
261
  ...(options.serve ? { serve: { command: `ELANOUS_WARM_POD_PROVIDER_CONFIG=${shellQuote(options.output)} bun src/task-orchestrator/surfaces/pod-warm-worker-provider.ts --serve` } } : {}) })}\n`);
234
262
  if (!options.serve) return;
235
263
  const provider = fileURLToPath(new URL('../src/task-orchestrator/surfaces/pod-warm-worker-provider.ts', import.meta.url));
@@ -76,6 +76,7 @@ export class AcpAgentManager {
76
76
  agent = new CodexAppServerAgent({
77
77
  backendId,
78
78
  ...opts,
79
+ remoteSocketPath: process.env.ELANOUS_CODEX_REMOTE_SIDETAB_SOCKET || undefined,
79
80
  elicitationHandler: createAskUserElicitationHandler(),
80
81
  }) as unknown as AcpAgent;
81
82
  } else {
@@ -31,6 +31,7 @@
31
31
  import {
32
32
  CodexAppServerClient,
33
33
  spawnCodexAppServer,
34
+ spawnCodexRemoteTui,
34
35
  type SpawnCodexAppServerOpts,
35
36
  type SpawnedCodexAppServer,
36
37
  } from './codex-app-server-client.js';
@@ -713,6 +714,8 @@ export interface CodexAppServerAgentOpts {
713
714
  readonly codexBinary?: string;
714
715
  /** Session-scoped argv forwarded to `spawnCodexAppServer`. */
715
716
  readonly codexArgs?: readonly string[];
717
+ /** Explicit opt-in Codex remote side-tab Unix socket path. */
718
+ readonly remoteSocketPath?: string;
716
719
  readonly env?: Record<string, string>;
717
720
  readonly log?: (msg: string) => void;
718
721
  /** Called after a successful initialize with this backend's advertised capabilities.
@@ -770,6 +773,7 @@ export interface CodexAppServerAgentOpts {
770
773
  readonly _spawnFactory?: (
771
774
  opts: SpawnCodexAppServerOpts,
772
775
  ) => SpawnedCodexAppServer;
776
+ readonly _remoteTuiSpawnForTesting?: typeof spawnCodexRemoteTui;
773
777
  }
774
778
 
775
779
  export class CodexAppServerAgent {
@@ -777,12 +781,14 @@ export class CodexAppServerAgent {
777
781
  private readonly cwd?: string;
778
782
  private readonly codexBinary?: string;
779
783
  private readonly codexArgs?: readonly string[];
784
+ private readonly remoteSocketPath?: string;
780
785
  private readonly env?: Record<string, string>;
781
786
  private readonly log: (msg: string) => void;
782
787
  private readonly onCapabilities: ((capabilities: ElanousCapabilities) => void) | undefined;
783
788
 
784
789
  private client: CodexAppServerClient | null;
785
790
  private child: SpawnedCodexAppServer['child'] | null = null;
791
+ private remoteTuiChild: ReturnType<typeof spawnCodexRemoteTui> | null = null;
786
792
  private initialized = false;
787
793
 
788
794
  private readonly approvalAdapter: CodexApprovalAdapter;
@@ -877,12 +883,14 @@ export class CodexAppServerAgent {
877
883
  private readonly _spawnFactory:
878
884
  | ((opts: SpawnCodexAppServerOpts) => SpawnedCodexAppServer)
879
885
  | undefined;
886
+ private readonly _remoteTuiSpawnForTesting: typeof spawnCodexRemoteTui | undefined;
880
887
 
881
888
  constructor(opts: CodexAppServerAgentOpts) {
882
889
  this.backendId = opts.backendId;
883
890
  this.cwd = opts.cwd;
884
891
  this.codexBinary = opts.codexBinary;
885
892
  this.codexArgs = opts.codexArgs ? [...opts.codexArgs] : undefined;
893
+ this.remoteSocketPath = opts.remoteSocketPath;
886
894
  this.env = opts.env;
887
895
  this.log = opts.log ?? ((msg) => debug.log('acp.cxn.appserver.agent', msg));
888
896
  this.onCapabilities = opts.onCapabilities;
@@ -894,6 +902,7 @@ export class CodexAppServerAgent {
894
902
  this.imageTempDir = opts.imageTempDir ?? defaultImageTempDir();
895
903
  this._clientForTesting = opts._clientForTesting;
896
904
  this._spawnFactory = opts._spawnFactory;
905
+ this._remoteTuiSpawnForTesting = opts._remoteTuiSpawnForTesting;
897
906
  this.threadIndex = opts._threadIndexForTesting ?? globalCasThreadIndex();
898
907
  // M6 · idle hibernate config. Env override only applies when opts
899
908
  // didn't set it explicitly so tests can pin a value regardless of
@@ -979,6 +988,7 @@ export class CodexAppServerAgent {
979
988
  env: { ...rotatedCodexChildEnv(childEnv), ...(this.env ?? {}) },
980
989
  codexBinary,
981
990
  codexArgs: this.codexArgs,
991
+ remoteSocketPath: this.remoteSocketPath,
982
992
  };
983
993
  const spawned = spawnFn(spawnOpts);
984
994
  this.client = spawned.client;
@@ -1069,6 +1079,13 @@ export class CodexAppServerAgent {
1069
1079
  /* swallow */
1070
1080
  }
1071
1081
  }
1082
+ if (this.remoteTuiChild) {
1083
+ try {
1084
+ this.remoteTuiChild.kill('SIGTERM');
1085
+ } catch {
1086
+ /* swallow */
1087
+ }
1088
+ }
1072
1089
  if (this.child) {
1073
1090
  try {
1074
1091
  this.child.kill('SIGTERM');
@@ -1078,6 +1095,7 @@ export class CodexAppServerAgent {
1078
1095
  }
1079
1096
  this.client = null;
1080
1097
  this.child = null;
1098
+ this.remoteTuiChild = null;
1081
1099
  this.initialized = false;
1082
1100
  this.sessionToThread.clear();
1083
1101
  this.threadToSession.clear();
@@ -1110,6 +1128,7 @@ export class CodexAppServerAgent {
1110
1128
  * disabled. unref() so a CLI can still exit cleanly when the daemon
1111
1129
  * is the only thing keeping the loop alive. */
1112
1130
  private armIdleTimer(): void {
1131
+ if (this.remoteSocketPath) return;
1113
1132
  if (this.idleTimerHandle !== null) return;
1114
1133
  if (this.idleTimeoutMs <= 0) return;
1115
1134
  this.idleTimerHandle = setInterval(() => {
@@ -1328,6 +1347,20 @@ export class CodexAppServerAgent {
1328
1347
  // M6 · brand-new sessions are alive in the current daemon by
1329
1348
  // definition · no thread/resume needed before the first turn.
1330
1349
  this.currentDaemonSessions.add(sessionId);
1350
+ if (this.remoteSocketPath && !this.remoteTuiChild) {
1351
+ const explicitEnv = this.env ?? {};
1352
+ const tuiEnv = {
1353
+ ...rotatedCodexChildEnv({ ...process.env, ...explicitEnv }),
1354
+ ...explicitEnv,
1355
+ };
1356
+ const spawnRemoteTui = this._remoteTuiSpawnForTesting ?? spawnCodexRemoteTui;
1357
+ this.remoteTuiChild = spawnRemoteTui({
1358
+ codexBinary: this.codexBinary ?? resolvePreferredCodexBinary(),
1359
+ socketPath: this.remoteSocketPath,
1360
+ cwd: this.cwd,
1361
+ env: tuiEnv,
1362
+ });
1363
+ }
1331
1364
  debug.log('acp.client', 'session-new', { backendId: this.backendId, sessionId });
1332
1365
  return sessionId;
1333
1366
  }