elanous 0.2.41 → 0.2.42

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 (589) 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/{GiOLWmt4MqDZePubBjA4Q → X1ucLw10Cds_h614NoEnh}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/{5159.115f1c2ca471386c.js → 1063.2fb8a9dc55c731f2.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +36 -0
  7. package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/{9048.212083de42d25be3.js → 1262.e804feb8fd1acb8c.js} +2 -2
  9. package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/{4527.a69f2894d1bc9f4a.js → 1487.2f67b79444062da6.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +32 -0
  15. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +286 -0
  21. package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +23 -0
  22. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +34 -0
  25. package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{530.d26346e18089640a.js → 2690.0521c738b7749931.js} +1 -1
  31. package/apps/pwa/out/_next/static/chunks/{4702.4a4adc1f16d7c93b.js → 2974.595d1e29d040cb6a.js} +1 -1
  32. package/apps/pwa/out/_next/static/chunks/{2263.e09b6edea33bad2d.js → 3207.a756c95e9ec8c3c8.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/{9541.eb8e2f8480c7feca.js → 3285.89ee2f298682f5e5.js} +2 -2
  34. package/apps/pwa/out/_next/static/chunks/{9507.7026657a2f47eb64.js → 3347.f846266b5e5f3ede.js} +16 -16
  35. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +41 -0
  36. package/apps/pwa/out/_next/static/chunks/{1178.1aa9cad0e7695427.js → 3482.a9ae9d2ad6a5bd97.js} +1 -1
  37. package/apps/pwa/out/_next/static/chunks/3507.97e1977bc4d5fb0a.js +2 -0
  38. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +24 -0
  40. package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{1661.0dd330f3d89f73f3.js → 3837.a210d7d0db8d8abd.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/{2fdf2931.b431eee4fb468bc3.js → 3d0154af.5331fec737ffe8c3.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4043.6b91203436c9c86b.js +309 -0
  47. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +77 -0
  48. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +148 -0
  54. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +74 -0
  55. package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +122 -0
  56. package/apps/pwa/out/_next/static/chunks/{1115.434ae2ecb0ad986d.js → 5112.4b9f300124fab7b3.js} +3 -3
  57. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +27 -0
  59. package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +287 -0
  69. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +226 -0
  72. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +90 -0
  73. package/apps/pwa/out/_next/static/chunks/{2073.689dcb2680113d76.js → 6377.bc7df239edbff244.js} +1 -1
  74. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/{1800.f7ff51dc4978a958.js → 6632.0eac1c554f8f2ef3.js} +1 -1
  77. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +104 -0
  81. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +94 -0
  82. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/{2527-5c636a43c7cc5dde.js → 7279-c199ea83f34338fa.js} +1 -1
  85. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{385e4574.e9886ab32759eda3.js → 73d2eb0e.4966ad55293c801a.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{5471.1e611302ed3a7c53.js → 7411.9b4b8b747dc7b802.js} +2 -2
  90. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +24 -0
  91. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{2fe2c302.41b517f88d6fe502.js → 7a98bc80.fa935989e829f9c2.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8138.6c10b2a356d52fca.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{5574.f35accf4f132b29d.js → 8262.ddc03e06b733f184.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +8 -0
  102. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +79 -0
  104. package/apps/pwa/out/_next/static/chunks/{8050-9b364bdef8f71927.js → 8546-6f03f8ea34dd61d9.js} +1 -1
  105. package/apps/pwa/out/_next/static/chunks/{5947-135e26537d80a6b9.js → 8673-bab689a55f7e13b9.js} +3 -3
  106. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{5937.c2df9e3447e1f667.js → 9249.976f1e69a9d80754.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{1971-7efb628c471dc5a0.js → 9353-12bfff0c130104cf.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/{7191.fdc955f7d96064a4.js → 9415.69e4a21c60c7d2db.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/{1219.7e17964e0e7cd8e5.js → 9427.96aa912ddb5801e0.js} +16 -16
  118. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{5964-7e21164a8f2cf0ce.js → 9656-374232558fd528d0.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{6552.a3840aa7da35ad68.js → 9832.f4a98c878ecf2c0a.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{a0a01613.6d1cca322238d7fe.js → b450776b.3db34d8d965f82d3.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{c0c1a699.0ba79f97005965d4.js → e8543907.5b040a5f22a0b0e5.js} +7 -7
  178. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +22 -22
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +22 -22
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +22 -22
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +21 -21
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +21 -21
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +22 -22
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +21 -21
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +22 -22
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +22 -22
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +21 -21
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +22 -22
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -24
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +22 -22
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +22 -22
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +21 -21
  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 +22 -22
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -24
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -24
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +21 -21
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +21 -21
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +22 -22
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +22 -22
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +21 -21
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +21 -21
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +21 -21
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +22 -22
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +22 -22
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +21 -21
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +22 -22
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +22 -22
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +22 -22
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +22 -22
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +22 -22
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +21 -21
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +22 -22
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +22 -22
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +22 -22
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +22 -22
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +22 -22
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +22 -22
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +22 -22
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +22 -22
  278. package/docs/goal-context/04-mock-scenarios.md +13 -0
  279. package/graphs/catalog/catalog.yaml +1 -1
  280. package/graphs/heal/heal-loop.yaml +1 -0
  281. package/graphs/overlays/stop-heal-ladder.yaml +113 -0
  282. package/graphs/units/verbs/recipes.yaml +11 -11
  283. package/graphs/work/research-report.yaml +10 -2
  284. package/package.json +1 -1
  285. package/scripts/heal/run-role.ts +99 -5
  286. package/scripts/land-global-checks.ts +6 -1
  287. package/scripts/lib/decompose-ab.ts +1 -0
  288. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  289. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  290. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  291. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  292. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  293. package/scripts/lib/tui-regress-checks.ts +33 -13
  294. package/scripts/release-loop/gate-baseline-receipt.ts +47 -9
  295. package/scripts/release-loop/gate-image-pin.ts +81 -0
  296. package/scripts/release-loop/gate-node-sim.ts +207 -0
  297. package/scripts/release-loop/gate-node.ts +285 -46
  298. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  299. package/scripts/release-loop/gate-radius-live.ts +97 -13
  300. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  301. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  302. package/scripts/release-loop/resume-release.ts +83 -8
  303. package/scripts/ux-sim.ts +18 -1
  304. package/scripts/warm-pool-provider-config.ts +263 -0
  305. package/skills/omni-crawl/SKILL.md +5 -2
  306. package/skills/omni-crawl/scripts/main.ts +84 -23
  307. package/src/acp/core-turn-bridge.ts +13 -0
  308. package/src/agent/registry.ts +2 -0
  309. package/src/agent/task-notification.ts +25 -5
  310. package/src/agent/types.ts +6 -0
  311. package/src/agent-mission/mission-cli.ts +24 -0
  312. package/src/agent-mission/mission-out.ts +595 -0
  313. package/src/agent-mission/tool-install.ts +88 -2
  314. package/src/agent-substrate/context-strategy.ts +4 -4
  315. package/src/agent-substrate/self-review-cli.ts +178 -13
  316. package/src/auto-research/research-turn.ts +123 -50
  317. package/src/autopilot/pr-manager.ts +38 -7
  318. package/src/autopilot/pty-control-loop.ts +2 -0
  319. package/src/capture/tui-self-report.ts +22 -6
  320. package/src/chat/index.ts +1 -1
  321. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  322. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  323. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  324. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  325. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  326. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  327. package/src/cli/pr-land-heavy-remote.ts +32 -0
  328. package/src/cli/pr-land-overlap-evidence.ts +100 -1
  329. package/src/cli/pr-land-pod-shadow-job.ts +60 -0
  330. package/src/cli/release-checklist-read-cli.ts +20 -10
  331. package/src/cli/research-cli.ts +4 -5
  332. package/src/cli/tasks-cli.ts +7 -0
  333. package/src/compact/auto.ts +8 -1
  334. package/src/control-plane/ledger.ts +52 -2
  335. package/src/control-plane/server.ts +16 -2
  336. package/src/core-turn/run-core-turn.ts +311 -90
  337. package/src/core-turn/run-goal-loop.ts +18 -0
  338. package/src/core-turn/types.ts +2 -0
  339. package/src/dashboard/classic-sidetab-mission-job.ts +58 -0
  340. package/src/dashboard/classic-sidetab-mission.ts +185 -0
  341. package/src/dashboard/index.ts +149 -15
  342. package/src/dashboard/input/agent-wake.ts +23 -1
  343. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +9 -0
  344. package/src/dashboard/mission-cli-consumer.ts +153 -0
  345. package/src/dashboard/seat-boot-preamble.ts +171 -1
  346. package/src/dashboard/side-basic-runtime.ts +54 -1
  347. package/src/dashboard/sidetab-runtime.ts +90 -1
  348. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  349. package/src/dashboard/skill-detection-runtime.ts +55 -15
  350. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  351. package/src/dashboard/turn-preamble.ts +53 -15
  352. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  353. package/src/graph-runner/graph-cli.ts +23 -7
  354. package/src/graph-runner/graph-tick.ts +10 -2
  355. package/src/graph-runner/runner.ts +1 -1
  356. package/src/grok/agent-search.ts +14 -4
  357. package/src/grok/credential.ts +28 -11
  358. package/src/harness/harness-pod-dispatch.ts +81 -15
  359. package/src/harness/harness-stop.ts +155 -11
  360. package/src/index.ts +34 -5
  361. package/src/instance/spawn-elanous.ts +6 -4
  362. package/src/llm.ts +166 -8
  363. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  364. package/src/loops/orchestrator/tick.ts +13 -0
  365. package/src/maturity/feature-maturity.ts +1 -1
  366. package/src/native-tool-catalog.ts +2 -2
  367. package/src/nexus/api/harness-traversal.ts +11 -0
  368. package/src/pr-tool/census.ts +3 -2
  369. package/src/pty-shell/tui-run-state.ts +188 -2
  370. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  371. package/src/release-loop/checklist.ts +9 -1
  372. package/src/repl/index.ts +43 -2
  373. package/src/research/axis-fanout.ts +121 -16
  374. package/src/research/bloom-exemplars.ts +3 -1
  375. package/src/research/gap-followup.ts +13 -1
  376. package/src/research/plugin-discovery.ts +36 -14
  377. package/src/research-bridge/invoke.ts +22 -5
  378. package/src/research-bridge/types.ts +2 -0
  379. package/src/self-dev/decompose.ts +119 -5
  380. package/src/self-dev/launch-preflight-text.ts +5 -6
  381. package/src/self-dev/orchestrate.ts +12 -2
  382. package/src/self-dev/review-provider-fallback.ts +9 -2
  383. package/src/self-dev/run-supervisor.ts +42 -4
  384. package/src/self-dev/run-types.ts +4 -0
  385. package/src/self-implement/doctor-visit.ts +88 -0
  386. package/src/self-implement/goal-author.ts +326 -3
  387. package/src/self-implement/graph-overlay-yaml.ts +7 -0
  388. package/src/self-implement/headless-elanous-driver.ts +31 -2
  389. package/src/self-implement/heal-intake.ts +112 -4
  390. package/src/self-implement/heal-triage.ts +20 -0
  391. package/src/self-implement/host-regate.ts +27 -4
  392. package/src/self-implement/merge-train.ts +5 -0
  393. package/src/self-implement/orchestrator.ts +126 -11
  394. package/src/self-implement/regate-detail.ts +38 -1
  395. package/src/self-implement/rework-child-provider.ts +25 -0
  396. package/src/self-implement/run-chart.ts +119 -0
  397. package/src/self-implement/run-ledger.ts +112 -11
  398. package/src/self-implement/run-stop.ts +188 -4
  399. package/src/self-implement/stop-autoheal.ts +13 -0
  400. package/src/session/chat.ts +38 -4
  401. package/src/session-runtime/index.ts +98 -4
  402. package/src/session-runtime/tier-flip.ts +3 -3
  403. package/src/sidetab-core/model.ts +19 -5
  404. package/src/sidetab-core/visible-agent-mission.ts +186 -0
  405. package/src/skills/name-match.ts +20 -0
  406. package/src/skills/tools/agent.ts +30 -2
  407. package/src/skills/tools/omni-search.ts +67 -5
  408. package/src/task-agent/pod-distributor-entry.ts +3 -0
  409. package/src/task-agent/task-hand.ts +27 -0
  410. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  411. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  412. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  413. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  414. package/src/task-orchestrator/surfaces/pod-source-receive.ts +163 -13
  415. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  416. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +209 -39
  417. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  418. package/src/task-orchestrator/surfaces/self-implement-pod.ts +165 -45
  419. package/src/tokens.ts +35 -2
  420. package/src/tool-runtime/agent-runtime.ts +1 -0
  421. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  422. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  423. package/src/tool-runtime/types.ts +1 -0
  424. package/src/tui/entry.ts +14 -4
  425. package/src/tui/sidetab/attach.ts +47 -0
  426. package/src/tui-client/local-chat-turn.ts +26 -13
  427. package/src/tui.ts +22 -0
  428. package/src/ux-sim/fake-kubectl.ts +37 -3
  429. package/src/ux-sim/fault-pool-cap.ts +11 -6
  430. package/src/ux-sim/mock-scenario-catalog.json +41 -0
  431. package/src/ux-sim/mock-scenario-catalog.ts +156 -0
  432. package/src/ux-sim/scenario.ts +116 -23
  433. package/src/version/packed-revision.json +1 -1
  434. package/src/voice/voice-tts-singleton.ts +18 -3
  435. package/src/web-search/grok.ts +5 -9
  436. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +0 -36
  437. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +0 -1
  438. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +0 -287
  439. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +0 -90
  443. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +0 -77
  445. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +0 -1
  447. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/2743.5d3f76948be32b34.js +0 -41
  453. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +0 -32
  454. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +0 -79
  456. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/3230-49298c3b73ef2268.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +0 -74
  461. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +0 -1
  463. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +0 -1
  465. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/4133.2056bb4d78f621af.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +0 -148
  472. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +0 -226
  473. package/apps/pwa/out/_next/static/chunks/4667.97e31aa38c95c475.js +0 -309
  474. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +0 -94
  481. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +0 -8
  483. package/apps/pwa/out/_next/static/chunks/53aeb4ee-51c92f8d683f5220.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +0 -24
  487. package/apps/pwa/out/_next/static/chunks/5744.b9415e18ad623100.js +0 -23
  488. package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +0 -286
  490. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +0 -27
  494. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +0 -24
  496. package/apps/pwa/out/_next/static/chunks/6874.d5cf7eb8edb2cabe.js +0 -2
  497. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +0 -122
  499. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/83184dcd-0ee6247ff41eb3f2.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +0 -104
  510. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +0 -34
  527. package/apps/pwa/out/_next/static/chunks/9834.63ab2bbc3153172e.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/addc2b32.8c4ff8f0aefe987d.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/app/botlab/page-14949db884bfa672.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-40f9e19149024298.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a142dfb0331a05f5.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/b2271e54.c1de3347976e90b0.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +0 -1
  588. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  589. /package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → X1ucLw10Cds_h614NoEnh}/_ssgManifest.js +0 -0
package/src/tui/entry.ts CHANGED
@@ -357,6 +357,12 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
357
357
 
358
358
  const ensureSidetabAttachments = async (): Promise<void> => {
359
359
  if (sidetabAttachments) return;
360
+ const installer = await import('../agent-mission/tool-install.js') as unknown as {
361
+ detectAgentCli?: (agent: 'codex' | 'claude') => Promise<{
362
+ agent: 'codex' | 'claude'; installed: boolean; version: string | null;
363
+ login: 'ready' | 'needed' | 'unknown'; message: string;
364
+ }>;
365
+ };
360
366
  sidetabAttachments = (await import('./sidetab/attach.js')).createSidetabAttachmentController({
361
367
  drawBase: () => {
362
368
  paintingCoordinatorFrame = true;
@@ -364,6 +370,7 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
364
370
  },
365
371
  termSize: () => ({ cols: process.stdout.columns || 80, rows: process.stdout.rows || 24 }),
366
372
  setStatus: (message) => { status = safeStatusText(message); },
373
+ ...(installer.detectAgentCli ? { detectAgentCli: installer.detectAgentCli } : {}),
367
374
  drawRemoteFrame: (frame) => {
368
375
  sidetabRemoteFrame = frame || null;
369
376
  if (sidetabRemoteFrame !== null) {
@@ -575,7 +582,7 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
575
582
  .then(({ runLocalChatTurn, onLocalChatBackgroundStatus, onLocalChatSelfHealthStatus }) => {
576
583
  observeSession(turnSessionId, onLocalChatBackgroundStatus, onLocalChatSelfHealthStatus);
577
584
  let firstResponseSeen = false;
578
- return runLocalChatTurn(turnSessionId, turnText, abort.signal, undefined, undefined, (delta) => {
585
+ return runLocalChatTurn(turnSessionId, turnText, abort.signal, undefined, undefined, (delta, replace = false) => {
579
586
  // 스트림 텍스트 = 진전 신호 — 마지막 진전 시각을 올린다(녹음기 없으면 아무 일도 안 한다).
580
587
  reportTuiProgress();
581
588
  // 첫 응답 경계: 첫 스트림 델타에서 턴 시작 트레이스를 닫는다(endedBy=stream-open).
@@ -585,7 +592,7 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
585
592
  }
586
593
  // The first model token is visible before the final JSONL frame. Keep only
587
594
  // a bounded tail until session history becomes the canonical display.
588
- streamingReply = (streamingReply + delta).slice(-32_768);
595
+ streamingReply = replace ? delta.slice(-32_768) : (streamingReply + delta).slice(-32_768);
589
596
  activity = streamReplyLines(streamingReply, process.stdout.columns || 80);
590
597
  const now = performance.now();
591
598
  if (streamRenderAt === 0 || now - streamRenderAt >= 33) {
@@ -692,8 +699,9 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
692
699
  try {
693
700
  {
694
701
  const { createNextTuiWakeup, setNextTuiWakeupTool } = await import('../tui-client/next-wakeup.js');
695
- const { setNextSidetabHandler } = await import('../tui-client/local-chat-turn.js');
702
+ const { setNextSidetabHandler, setNextSidetabIpcEnabled } = await import('../tui-client/local-chat-turn.js');
696
703
  const { createNextSidetabHostHandler } = await import('./sidetab/nl-tool.js');
704
+ setNextSidetabIpcEnabled(true);
697
705
  wakeup = createNextTuiWakeup({
698
706
  isTurnRunning: () => busy,
699
707
  getBufferText: () => editor.text,
@@ -722,6 +730,7 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
722
730
  attach: async (row) => { await ensureSidetabAttachments(); const ok = sidetabAttachments!.select(row); render(); return { ok, action: 'attach', target: row.id }; },
723
731
  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' }; },
724
732
  spawn: async (character) => { await ensureSidetabAttachments(); const ok = sidetabAttachments!.spawn(character); refreshSidetabRows(); render(); return { ok, action: 'new', character }; },
733
+ runMission: async (agent, mission) => { await ensureSidetabAttachments(); const result = await sidetabAttachments!.runMission(agent, mission); refreshSidetabRows(); render(); return result; },
725
734
  kill: async (row) => { await ensureSidetabAttachments(); const ok = sidetabAttachments!.kill(row); refreshSidetabRows(); render(); return { ok, action: 'kill', target: row.id }; },
726
735
  }));
727
736
  const gate = wakeup.gate;
@@ -1390,8 +1399,9 @@ export async function showNextTui(options: NextTuiOptions = {}): Promise<void> {
1390
1399
  const { setNextTuiWakeupTool } = await import('../tui-client/next-wakeup.js');
1391
1400
  setNextTuiWakeupTool(null);
1392
1401
  }
1393
- const { setNextSidetabHandler } = await import('../tui-client/local-chat-turn.js');
1402
+ const { setNextSidetabHandler, setNextSidetabIpcEnabled } = await import('../tui-client/local-chat-turn.js');
1394
1403
  setNextSidetabHandler(null);
1404
+ setNextSidetabIpcEnabled(false);
1395
1405
  turnAbort?.abort();
1396
1406
  await turnDone;
1397
1407
  backgroundSubscription.stop?.();
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { join } from 'node:path';
2
3
  import { resolveBackendSpawn, claudeBackend, codexBackend } from '../../agent-mission/driver.js';
3
4
  import { DisplayCoordinator } from '../../display/coordinator.js';
4
5
  import { createDisplayEventBus } from '../../display/events.js';
@@ -6,6 +7,7 @@ import { createTerminalModalRouter } from '../../terminal/terminal-modal-router.
6
7
  import { getSessionCwd } from '../../session/working-dir.js';
7
8
  import { TerminalSessionRegistry, type TerminalSession } from '../../terminal/session-registry.js';
8
9
  import { requestRemotePtyControl } from '../../pty-shell/pty-control-ipc.js';
10
+ import { runVisibleAgentMission } from '../../sidetab-core/visible-agent-mission.js';
9
11
  import type { Key } from '../../tui.js';
10
12
  import type { SidetabRow } from './list.js';
11
13
 
@@ -16,6 +18,7 @@ export interface SidetabAttachmentController {
16
18
  select(row: SidetabRow): boolean;
17
19
  showMain(): void;
18
20
  spawn(character: SidetabCharacter): boolean;
21
+ runMission(agent: 'codex' | 'claude', mission: string): Promise<Awaited<ReturnType<typeof runVisibleAgentMission>>>;
19
22
  kill(row: SidetabRow): boolean;
20
23
  handleKey(key: Key): boolean;
21
24
  hasModal(): boolean;
@@ -24,11 +27,21 @@ export interface SidetabAttachmentController {
24
27
  close(): void;
25
28
  }
26
29
 
30
+ export interface AgentCliDetection {
31
+ agent: 'codex' | 'claude';
32
+ installed: boolean;
33
+ version: string | null;
34
+ login: 'ready' | 'needed' | 'unknown';
35
+ message: string;
36
+ }
37
+
27
38
  export function createSidetabAttachmentController(deps: {
28
39
  drawBase(): void;
29
40
  termSize(): { cols: number; rows: number };
30
41
  setStatus(message: string): void;
31
42
  drawRemoteFrame(frame: string): void;
43
+ /** Owned by OPT; a missing detector keeps the hook inert until its API lands. */
44
+ detectAgentCli?(agent: 'codex' | 'claude'): Promise<AgentCliDetection>;
32
45
  }): SidetabAttachmentController {
33
46
  const eventBus = createDisplayEventBus();
34
47
  const coordinator = new DisplayCoordinator({
@@ -45,6 +58,7 @@ export function createSidetabAttachmentController(deps: {
45
58
  let remoteFrameTimer: ReturnType<typeof setInterval> | null = null;
46
59
  let remoteFramePending = false;
47
60
  let remoteHasFrame = false;
61
+ let lastSpawnedSession: TerminalSession | null = null;
48
62
 
49
63
  const stopRemote = (): void => {
50
64
  if (remoteFrameTimer !== null) clearInterval(remoteFrameTimer);
@@ -164,6 +178,7 @@ export function createSidetabAttachmentController(deps: {
164
178
  }
165
179
  },
166
180
  }, { termCols: cols, termRows: rows });
181
+ lastSpawnedSession = session;
167
182
  if (character === 'codex' || character === 'claude') {
168
183
  deps.setStatus(`${character} 실행 · agent-mission 구독 경로 scrub 적용(${unsetEnv?.length ?? 0}개 env 제거)`);
169
184
  }
@@ -204,6 +219,38 @@ export function createSidetabAttachmentController(deps: {
204
219
  },
205
220
  showMain,
206
221
  spawn,
222
+ async runMission(agent, mission) {
223
+ if (deps.detectAgentCli) {
224
+ let detection: AgentCliDetection;
225
+ try { detection = await deps.detectAgentCli(agent); }
226
+ catch (error) {
227
+ const message = `${agent} CLI 확인에 실패했습니다: ${error instanceof Error ? error.message : String(error)}`;
228
+ deps.setStatus(message);
229
+ return { ok: false, path: '', promptReady: false, missionVisible: false, completionMarker: false, error: message };
230
+ }
231
+ if (!detection.installed) {
232
+ const message = `${detection.message} · 설치 확인 후 미션을 다시 요청하세요`;
233
+ deps.setStatus(message);
234
+ return { ok: false, path: '', promptReady: false, missionVisible: false, completionMarker: false, error: message };
235
+ }
236
+ }
237
+ lastSpawnedSession = null;
238
+ if (!spawn(agent) || !lastSpawnedSession?.modal) {
239
+ return { ok: false, path: '', promptReady: false, missionVisible: false, completionMarker: false, error: `${agent} side-tab PTY could not start` };
240
+ }
241
+ const session = lastSpawnedSession;
242
+ const outputPath = join(session.cwd, '.elanous', 'mission-results', `sidetab-${Date.now()}.md`);
243
+ const backend = agent === 'codex' ? codexBackend : claudeBackend;
244
+ const result = await runVisibleAgentMission({
245
+ pty: session.modal,
246
+ mission,
247
+ outputPath,
248
+ handleTrust: (screen, write) => backend.handleTrust?.(screen, write) ?? false,
249
+ });
250
+ showMain();
251
+ deps.setStatus(result.ok ? `미션 결과 확인 · ${result.path}` : `미션 확인 실패 · ${result.error}`);
252
+ return result;
253
+ },
207
254
  kill(row) {
208
255
  if (row.currentProcess) {
209
256
  deps.setStatus('현재 TUI 세션은 사이드탭에서 종료할 수 없습니다');
@@ -6,11 +6,17 @@ import { answerNextSidetabCall, isNextSidetabCall, type NextSidetabHandler } fro
6
6
 
7
7
  const STATUS_PREFIX = 'ELANOUS_TUI_BG_STATUS\t';
8
8
  let nextSidetabHandler: NextSidetabHandler | null = null;
9
+ let nextSidetabIpcEnabled = false;
9
10
 
10
11
  export function setNextSidetabHandler(handler: NextSidetabHandler | null): void {
11
12
  nextSidetabHandler = handler;
12
13
  }
13
14
 
15
+ /** The Next TUI host enables this before any sticky REPL child is created. */
16
+ export function setNextSidetabIpcEnabled(enabled: boolean): void {
17
+ nextSidetabIpcEnabled = enabled;
18
+ }
19
+
14
20
  interface TurnResult {
15
21
  event?: string | null;
16
22
  turnId?: string | null;
@@ -23,7 +29,7 @@ interface TurnResult {
23
29
  }
24
30
  interface WaitingTurn {
25
31
  turnId: string;
26
- onDelta?: (text: string) => void;
32
+ onDelta?: (text: string, replace?: boolean) => void;
27
33
  onStatus?: (text: string) => void;
28
34
  resolve: (result: TurnResult) => void;
29
35
  reject: (error: Error) => void;
@@ -44,7 +50,6 @@ class LocalChatSession {
44
50
  // TUI-NEXT-QUEUE-AND-WAKE: the child's ScheduleWakeup asks this process over Bun IPC — the scheduler
45
51
  // lives here because the child dies on Esc and /new. No tool registered → no IPC, env unchanged.
46
52
  const wakeupTool = nextTuiWakeupTool();
47
- const sidetabHandler = nextSidetabHandler;
48
53
  this.child = Bun.spawn({
49
54
  cmd: [process.execPath, cli, 'repl', '--session', sessionId, '--json', '--stdin-jsonl'],
50
55
  stdin: 'pipe', stdout: 'pipe', stderr: 'pipe',
@@ -52,21 +57,23 @@ class LocalChatSession {
52
57
  ...process.env, ELANOUS_NEXT_TUI_BG_STATUS: '1', ELANOUS_NEXT_TUI_STREAM: '1',
53
58
  ELANOUS_NEXT_TUI_SELF_HEALTH: '1',
54
59
  ...(wakeupTool ? { [NEXT_TUI_WAKEUP_IPC_ENV]: '1' } : {}),
55
- ELANOUS_NEXT_TUI_SIDETAB_IPC: sidetabHandler ? '1' : '0',
60
+ // The Next TUI explicitly enables this before child startup. The
61
+ // callback itself stays live so a child created before handler wiring
62
+ // can still serve the host once it is installed.
63
+ ELANOUS_NEXT_TUI_SIDETAB_IPC: nextSidetabIpcEnabled ? '1' : '0',
56
64
  },
57
- ...(wakeupTool || sidetabHandler ? {
58
- ipc: (message: unknown, child: { send(message: unknown): unknown }) => {
65
+ ipc: (message: unknown, child: { send(message: unknown): unknown }) => {
59
66
  if (wakeupTool && isWakeupCallMessage(message)) {
60
67
  void answerWakeupCall(wakeupTool, message).then((reply) => {
61
68
  try { child.send(reply); } catch { /* the child exited mid-call; its dispatch times out */ }
62
69
  });
63
- } else if (sidetabHandler && isNextSidetabCall(message)) {
64
- void answerNextSidetabCall(sidetabHandler, message).then((reply) => {
70
+ } else if (isNextSidetabCall(message)) {
71
+ const handler = nextSidetabHandler ?? (async () => ({ error: 'Next TUI sidetab handler is not ready' }));
72
+ void answerNextSidetabCall(handler, message).then((reply) => {
65
73
  try { child.send(reply); } catch { /* the child exited mid-call; its dispatch times out */ }
66
74
  });
67
75
  }
68
- },
69
- } : {}),
76
+ },
70
77
  });
71
78
  const input = this.child.stdin;
72
79
  const output = this.child.stdout;
@@ -100,6 +107,12 @@ class LocalChatSession {
100
107
  }
101
108
  return;
102
109
  }
110
+ if (result.event === 'replace') {
111
+ if (result.turnId === waiting.turnId && typeof result.text === 'string') {
112
+ try { waiting.onDelta?.(result.text, true); } catch { /* renderer cannot break the turn */ }
113
+ }
114
+ return;
115
+ }
103
116
  if (result.event === 'status') {
104
117
  if (result.turnId === waiting.turnId && typeof result.text === 'string') {
105
118
  try { waiting.onStatus?.(result.text); } catch { /* renderer cannot break the turn */ }
@@ -175,7 +188,7 @@ class LocalChatSession {
175
188
  }
176
189
  }
177
190
 
178
- async turn(prompt: string, writePrompt?: (payload: string) => Promise<void>, onDelta?: (text: string) => void, attachments: readonly string[] = [], onStatus?: (text: string) => void): Promise<TurnResult> {
191
+ async turn(prompt: string, writePrompt?: (payload: string) => Promise<void>, onDelta?: (text: string, replace?: boolean) => void, attachments: readonly string[] = [], onStatus?: (text: string) => void): Promise<TurnResult> {
179
192
  if (this.closed) throw new Error('REPL child exited');
180
193
  if (this.waiting) throw new Error('REPL turn already running');
181
194
  const turnId = `tui-${++this.turnCount}`;
@@ -255,7 +268,7 @@ export async function runLocalChatTurn(
255
268
  signal: AbortSignal,
256
269
  cli = process.argv[1],
257
270
  writePrompt?: (payload: string) => Promise<void>,
258
- onDelta?: (text: string) => void,
271
+ onDelta?: (text: string, replace?: boolean) => void,
259
272
  compact: LocalChatTurnCompact = {},
260
273
  attachments: readonly string[] = [],
261
274
  onStatus?: (line: string) => void,
@@ -278,8 +291,8 @@ export async function runLocalChatTurn(
278
291
  if (signal.aborted) abort();
279
292
  let result: TurnResult;
280
293
  try {
281
- result = await session.turn(text, writePrompt, (delta) => {
282
- if (!signal.aborted) onDelta?.(delta);
294
+ result = await session.turn(text, writePrompt, (delta, replace) => {
295
+ if (!signal.aborted) onDelta?.(delta, replace);
283
296
  }, attachments, (line) => { if (!signal.aborted) onStatus?.(line); });
284
297
  } catch (error) {
285
298
  if (signal.aborted) throw new Error('응답을 취소했습니다');
package/src/tui.ts CHANGED
@@ -1014,6 +1014,28 @@ export function injectKey(key: Key): boolean {
1014
1014
  return true;
1015
1015
  }
1016
1016
 
1017
+ // A foreground dashboard may own an interactive child terminal modal. External
1018
+ // control-IPC input must be routed to that modal before it enters the dashboard
1019
+ // readKey queue; while the parent loop is busy there may be no readKey consumer.
1020
+ let _externalTuiKeyRoutes: Array<{ token: symbol; route: (key: Key) => boolean }> = [];
1021
+
1022
+ export function setExternalTuiKeyRoute(route: ((key: Key) => boolean) | null): () => void {
1023
+ if (!route) return () => {};
1024
+ const entry = { token: Symbol('external-tui-key-route'), route };
1025
+ _externalTuiKeyRoutes.push(entry);
1026
+ return () => {
1027
+ _externalTuiKeyRoutes = _externalTuiKeyRoutes.filter((candidate) => candidate.token !== entry.token);
1028
+ };
1029
+ }
1030
+
1031
+ export function routeExternalTuiKey(key: Key): boolean {
1032
+ const routes = [..._externalTuiKeyRoutes];
1033
+ for (let index = routes.length - 1; index >= 0; index -= 1) {
1034
+ if (routes[index]!.route(key)) return true;
1035
+ }
1036
+ return false;
1037
+ }
1038
+
1017
1039
  /** `injectKey` 로 들어온 키 표지 — `takeInjectedKeys` 가 stdin 잔여 키(readKey 몫)는 두고 주입 키만 꺼낸다. */
1018
1040
  const _injectedKeys = new WeakSet<Key>();
1019
1041
 
@@ -1,7 +1,10 @@
1
+ #!/usr/bin/env bun
2
+ import { readFileSync } from 'node:fs';
1
3
  import type { PoolKubectl } from '../task-orchestrator/surfaces/pod-pool.js';
2
4
 
3
5
  /** In-memory Kubernetes boundary for real pool admission and warm-provider tests. Unknown operations fail closed. */
4
- export function createFakeKubectl(options: { context: string; node: string; jobState?: 'running' | 'complete' }) {
6
+ export function createFakeKubectl(options: { context: string; node: string; jobState?: 'running' | 'complete';
7
+ failGetPods?: string; podReadinessOnCreate?: boolean }) {
5
8
  const jobs = new Map<string, Record<string, unknown>>();
6
9
  const pods = new Map<string, Record<string, any>>();
7
10
  const calls: string[][] = [];
@@ -9,6 +12,7 @@ export function createFakeKubectl(options: { context: string; node: string; jobS
9
12
  const jobCreates: string[] = [];
10
13
  const jobDeletes: string[] = [];
11
14
  let lease: { workerId: string; podUid: string; key: unknown; job?: string; state: 'idle' | 'leased' | 'released' | 'quarantined' } | null = null;
15
+ let loseNextLeaseResponse = false;
12
16
  const ok = (value: unknown) => ({ status: 0, stdout: JSON.stringify(value), stderr: '' });
13
17
  const missing = (kind: string) => ({ status: 1, stdout: '', stderr: `${kind} not found` });
14
18
  const kubectl: PoolKubectl = (args, input) => {
@@ -59,7 +63,10 @@ export function createFakeKubectl(options: { context: string; node: string; jobS
59
63
  if (query.includes('.status.conditions')) return { status: 0, stdout: (job.status as { conditions?: Array<{ type?: string }> })?.conditions?.map((condition) => condition.type).join(' ') ?? '', stderr: '' };
60
64
  return ok(job);
61
65
  }
62
- if (verb === 'get' && args[at + 1] === 'pods') return ok({ items: [...pods.values()] });
66
+ if (verb === 'get' && args[at + 1] === 'pods') {
67
+ if (options.failGetPods) return { status: 1, stdout: '', stderr: options.failGetPods };
68
+ return ok({ apiVersion: 'v1', kind: 'PodList', metadata: { resourceVersion: '1', continue: '' }, items: [...pods.values()] });
69
+ }
63
70
  if (verb === 'get' && (args[at + 1] === 'pod' || args[at + 1]?.startsWith('pod/'))) {
64
71
  const name = args[at + 1] === 'pod' ? args[at + 2] : args[at + 1]?.slice(4);
65
72
  const pod = pods.get(name ?? '');
@@ -70,7 +77,8 @@ export function createFakeKubectl(options: { context: string; node: string; jobS
70
77
  try { manifest = JSON.parse(input); } catch { return missing('invalid manifest'); }
71
78
  const name = manifest.metadata?.name;
72
79
  if (typeof name !== 'string' || pods.has(name)) return missing('existing or invalid pod');
73
- const created = { ...manifest, metadata: { ...manifest.metadata, uid: `${name}-uid`, resourceVersion: '1' } };
80
+ const created = { ...manifest, metadata: { ...manifest.metadata, uid: `${name}-uid`, resourceVersion: '1' },
81
+ ...(options.podReadinessOnCreate ? { status: { phase: 'Running', conditions: [{ type: 'Ready', status: 'True' }] } } : {}) };
74
82
  pods.set(name, created);
75
83
  return ok(created);
76
84
  }
@@ -102,6 +110,10 @@ export function createFakeKubectl(options: { context: string; node: string; jobS
102
110
  if (!lease || lease.state !== 'idle' || (lease.job && !jobs.has(lease.job)))
103
111
  return Response.json({ unavailable: true }, { status: 503 });
104
112
  lease.state = 'leased';
113
+ if (loseNextLeaseResponse) {
114
+ loseNextLeaseResponse = false;
115
+ throw new TypeError('simulated response lost after lease commit');
116
+ }
105
117
  return Response.json({ name: lease.workerId, attrs: { key: lease.key, leaseId: 'lease-1',
106
118
  generation: 1, podUid: lease.podUid, state: 'leased' } });
107
119
  }
@@ -127,6 +139,7 @@ export function createFakeKubectl(options: { context: string; node: string; jobS
127
139
  setWarmLease: (value: { workerId: string; podUid: string; key: unknown; job?: string }) => {
128
140
  lease = { ...value, state: 'idle' };
129
141
  },
142
+ loseNextLeaseResponse: () => { loseNextLeaseResponse = true; },
130
143
  warmLeaseState: () => lease?.state ?? null,
131
144
  putPod: (pod: Record<string, any>) => { pods.set(pod.metadata.name, structuredClone(pod)); },
132
145
  replacePodUid: (name: string, uid: string) => {
@@ -140,3 +153,24 @@ export function createFakeKubectl(options: { context: string; node: string; jobS
140
153
  hasJob: (name: string) => jobs.has(name),
141
154
  };
142
155
  }
156
+
157
+ if (import.meta.main) {
158
+ const endpoint = process.env.ELANOUS_FAKE_KUBECTL_URL;
159
+ if (!endpoint) {
160
+ process.stderr.write('fake-kubectl requires ELANOUS_FAKE_KUBECTL_URL\n');
161
+ process.exitCode = 2;
162
+ } else {
163
+ try {
164
+ const input = readFileSync(0, 'utf8');
165
+ const response = await fetch(endpoint, { method: 'POST', headers: { 'content-type': 'application/json' },
166
+ body: JSON.stringify({ args: process.argv.slice(2), input }) });
167
+ const result = await response.json() as { status: number | null; stdout: string; stderr: string };
168
+ if (result.stdout) process.stdout.write(result.stdout);
169
+ if (result.stderr) process.stderr.write(result.stderr);
170
+ process.exitCode = result.status ?? 2;
171
+ } catch (error) {
172
+ process.stderr.write(`fake-kubectl: ${error instanceof Error ? error.message : String(error)}\n`);
173
+ process.exitCode = 2;
174
+ }
175
+ }
176
+ }
@@ -18,12 +18,14 @@ export interface PoolCapScenario {
18
18
  readonly spec: string;
19
19
  /** 멤버(컨텍스트)마다 지금 Running 인 하니스 Pod 수 — 멤버마다 «반드시» 준다(빠지면 0 으로 꾸미지 않고 던진다). */
20
20
  readonly running: Readonly<Record<string, number>>;
21
+ /** Query failures for a context stay unknown and suppress the admission recommendation. */
22
+ readonly queryFailures?: Readonly<Record<string, string>>;
21
23
  }
22
24
 
23
25
  export interface PoolCapObservation {
24
26
  readonly scenario: PoolCapScenario;
25
- readonly members: ReadonlyArray<{ context: string; capacity: number; capacityDefaulted: boolean; running: number }>;
26
- readonly recommendation: PoolLeaseRecommendation;
27
+ readonly members: ReadonlyArray<{ context: string; capacity: number; capacityDefaulted: boolean; running?: number; queryError?: string }>;
28
+ readonly recommendation: PoolLeaseRecommendation | null;
27
29
  }
28
30
 
29
31
  /** 메모리·CPU 가 넉넉한 노드 한 대 — 승인이 상한(capacity)으로만 갈리게 한다. */
@@ -48,10 +50,13 @@ export function simPoolCap(scenario: PoolCapScenario): PoolCapObservation {
48
50
  const parsed = parsePodPool(scenario.spec);
49
51
  const members = parsed.map((m) => ({
50
52
  context: m.context, capacity: m.capacity, capacityDefaulted: (m as { capacityDefaulted?: boolean }).capacityDefaulted === true,
51
- running: runningOf(scenario, m.context),
53
+ ...(scenario.queryFailures?.[m.context]
54
+ ? { queryError: scenario.queryFailures[m.context] }
55
+ : { running: runningOf(scenario, m.context) }),
52
56
  }));
57
+ if (members.some((member) => member.queryError)) return { scenario, members, recommendation: null };
53
58
  const recommendation = recommendConcurrency(
54
- { members: members.map((m) => roomyMember(m.context, m.capacity, m.capacityDefaulted, m.running)) },
59
+ { members: members.map((m) => roomyMember(m.context, m.capacity, m.capacityDefaulted, m.running!)) },
55
60
  { capacity: members.reduce((sum, m) => sum + m.capacity, 0), accounts: -1, perAccount: -1 },
56
61
  );
57
62
  return { scenario, members, recommendation };
@@ -74,8 +79,8 @@ export function renderPoolCap(rows: readonly PoolCapObservation[]): string[] {
74
79
  return [
75
80
  'pool-cap · `:N` 없는 멤버 = 기본 상한 2(capacityDefaulted)',
76
81
  ...rows.map((r) => {
77
- const occ = r.members.map((m) => `${m.context} ${m.running}/${m.capacity}${m.capacityDefaulted ? '(기본)' : ''}`).join(' · ');
78
- return ` ${r.scenario.spec.padEnd(36)} ${occ.padEnd(40)} → 승인 ${String(r.recommendation.recommended)} · limitedBy=${String(r.recommendation.limitedBy)}`;
82
+ const occ = r.members.map((m) => `${m.context} ${m.running === undefined ? 'unknown' : m.running}/${m.capacity}${m.capacityDefaulted ? '(기본)' : ''}${m.queryError ? ` query-error=${m.queryError}` : ''}`).join(' · ');
83
+ return ` ${r.scenario.spec.padEnd(36)} ${occ.padEnd(40)} → 승인 ${String(r.recommendation?.recommended ?? 'unknown')} · limitedBy=${String(r.recommendation?.limitedBy ?? 'unknown')}`;
79
84
  }),
80
85
  ];
81
86
  }
@@ -0,0 +1,41 @@
1
+ {
2
+ "version": 1,
3
+ "runEvidence": {
4
+ "scope": "ScenarioV0 YAML runs only; catalog entries reference reusable devices/tests, and list/show do not execute them",
5
+ "runId": "uuid per execution",
6
+ "event": { "category": "ux.sim.scenario", "name": "completed" },
7
+ "persistence": "the isolated test instance logs/logs.db; query by exact category and data.runId",
8
+ "artifact": "<test-state>/ux-sim/evidence/<scenario>-seed-<seed>-run-<runId>.json"
9
+ },
10
+ "devices": [
11
+ { "id": "fake-llm", "name": "Fake LLM", "implementation": ["src/ux-sim/fake-llm.ts"], "tests": ["src/ux-sim/fake-llm.test.ts"], "target": "LLM response and streaming boundary", "inputs": ["fixed or scripted response", "delay", "error/status"], "observations": ["captured calls", "stream chunks", "completion or failure"] },
12
+ { "id": "fake-executable", "name": "Fake executable and PATH", "implementation": ["src/ux-sim/fake-bin.ts"], "tests": ["src/ux-sim/fake-bin.test.ts"], "target": "external executable process boundary", "inputs": ["stdout", "stderr", "exit code", "signal", "delay", "argv"], "observations": ["spawn arguments", "output", "exit result"] },
13
+ { "id": "fake-github", "name": "Fake GitHub CLI and API", "implementation": ["src/ux-sim/fake-gh.ts"], "tests": ["src/ux-sim/fake-gh.test.ts"], "target": "PR list/edit/review/merge responses", "inputs": ["PR records", "pagination", "injected API failure"], "observations": ["requested operations", "deterministic response", "mutated fake state"] },
14
+ { "id": "fake-kubectl", "name": "Fake kubectl", "implementation": ["src/ux-sim/fake-kubectl.ts"], "tests": ["src/ux-sim/fake-kubectl.test.ts"], "target": "Pod and Job query/termination boundary", "inputs": ["Pod/Job fixtures", "query result or failure"], "observations": ["kubectl argv", "returned resource state", "failure"] },
15
+ { "id": "fake-herdr", "name": "Fake herdr", "implementation": ["src/ux-sim/fake-herdr.ts"], "tests": ["src/ux-sim/fake-herdr.test.ts"], "target": "pane lifecycle and report-agent handoff", "inputs": ["pane transitions", "missing report", "timeout"], "observations": ["pane state", "handoff result", "timeout classification"] },
16
+ { "id": "fake-clock", "name": "Fake clock", "implementation": ["src/ux-sim/fake-clock.ts"], "tests": ["src/ux-sim/fake-clock.test.ts"], "target": "process-local time and timer boundary", "inputs": ["clock advance", "scheduled callback"], "observations": ["elapsed time", "fired timers"] },
17
+ { "id": "temp-git-remote", "name": "Temporary Git remote", "implementation": ["src/ux-sim/temp-git-remote.ts"], "tests": ["src/ux-sim/temp-git-remote.test.ts"], "target": "real local git bare/clone boundary without GitHub", "inputs": ["temporary refs and commits"], "observations": ["local remote state", "branch and commit result"] },
18
+ { "id": "fake-land-queue", "name": "Fake landing queue", "implementation": ["src/ux-sim/fake-land-queue.ts"], "tests": ["src/ux-sim/fake-land-queue.test.ts"], "target": "landing train scheduling", "inputs": ["load", "gate verdict", "priority", "cut window", "conflict"], "observations": ["queue choice", "wait/reject reason", "slot availability"] },
19
+ { "id": "scenario-runner", "name": "Scenario file runner and human CLI", "implementation": ["src/ux-sim/scenario.ts", "src/ux-sim/mock-scenario-catalog.ts", "scripts/ux-sim.ts"], "tests": ["src/ux-sim/scenario.test.ts", "src/ux-sim/mock-scenario-catalog.test.ts"], "target": "registered test-only provider-response fault through the real Codex path; catalog list/show CLI", "inputs": ["scenario file", "seed", "registered HTTP/network fault", "MS-id"], "observations": ["widget snapshot", "debug event", "persistent logs.db row", "runId evidence artifact", "catalog listing/detail"] },
20
+ { "id": "release-graph-rig", "name": "Release graph simulation rig", "implementation": ["src/ux-sim/release-sim-rig.ts"], "tests": ["src/ux-sim/release-sim-rig.test.ts", "scripts/release-loop/gate-flow-sim.test.ts"], "target": "release graph routing, resume and failure paths", "inputs": ["node outcome", "evidence", "resume state"], "observations": ["visited nodes", "unexpected edges", "ledger events", "final graph state"] },
21
+ { "id": "tui-interaction", "name": "TUI interaction and rendering", "implementation": ["src/ux-sim/interaction.ts", "src/ux-sim/turn-states.ts", "src/ux-sim/render-frame.ts", "src/ux-sim/headless-tui.ts", "src/ux-sim/input-history.ts", "src/ux-sim/slash-menu-frames.ts", "src/ux-sim/mock-seat-pty-frame.ts", "src/ux-sim/mock-seat-pty-frame-child.ts", "src/ux-sim/mock-seat-pty-sequence.ts", "src/ux-sim/mock-seat-pty-sequence-child.ts", "src/ux-sim/pty-key-modifiers-device.ts", "src/ux-sim/tty-foreground-steal-child.ts"], "tests": ["src/ux-sim/interaction.test.ts", "src/ux-sim/turn-states.test.ts", "src/ux-sim/render-frame.test.ts", "src/ux-sim/headless-tui.test.ts", "src/ux-sim/input-history.test.ts", "src/ux-sim/slash-menu-frames.test.ts", "src/ux-sim/mock-seat-pty-frame.test.ts", "src/ux-sim/mock-seat-pty-sequence.test.ts", "src/ux-sim/pty-key-modifiers-device.test.ts"], "target": "TUI event, state, frame, input history and PTY boundaries", "inputs": ["keys", "turn phase", "PTY bytes", "frame dimensions", "queued input"], "observations": ["production renderer output", "state transitions", "PTY input/output", "event history"] },
22
+ { "id": "fault-injection", "name": "Fault injection devices", "implementation": ["src/ux-sim/fault-cred-expiry.ts", "src/ux-sim/fault-glm-no-credential.ts", "src/ux-sim/fault-needs-human-reason-repair.ts", "src/ux-sim/fault-nextmove-dispatch.ts", "src/ux-sim/fault-pod-child-result.ts", "src/ux-sim/fault-pod-codex-503.ts", "src/ux-sim/fault-pod-death.ts", "src/ux-sim/fault-pool-cap.ts", "src/ux-sim/fault-scope-escape-lift.ts", "src/ux-sim/fault-sqlite-busy.ts", "src/ux-sim/fault-tui-400-autoheal.ts", "src/ux-sim/gate-shard-host-reroute.ts"], "tests": ["src/ux-sim/fault-cred-expiry.test.ts", "src/ux-sim/fault-glm-no-credential.test.ts", "src/ux-sim/fault-needs-human-reason-repair.test.ts", "src/ux-sim/fault-nextmove-dispatch.test.ts", "src/ux-sim/fault-pod-child-result.test.ts", "src/ux-sim/fault-pod-codex-503.test.ts", "src/ux-sim/fault-pod-death.test.ts", "src/ux-sim/fault-pool-cap.test.ts", "src/ux-sim/fault-scope-escape-lift.test.ts", "src/ux-sim/fault-sqlite-busy.test.ts", "src/ux-sim/fault-tui-400-autoheal.test.ts", "src/ux-sim/gate-shard-host-reroute.test.ts"], "target": "credential, Pod, pool, routing, autoheal, scope and persistence failure boundaries", "inputs": ["explicit fault kind", "isolated fixture", "clock or resource outcome"], "observations": ["production decision function output", "reason/event", "recovery or refusal"] },
23
+ { "id": "product-devices", "name": "Product and task-agent devices", "implementation": ["src/ux-sim/boot-daemon-tools-pty-shell-device.ts", "src/ux-sim/cli-config-audit-device.ts", "src/ux-sim/computer-use.ts", "src/ux-sim/dashboard-event-loop-stall-monitor-device.ts", "src/ux-sim/event-monkey.ts", "src/ux-sim/goal-device.ts", "src/ux-sim/goal-interim-trace.ts", "src/ux-sim/onboarding-first-run-device.ts", "src/ux-sim/resume-picker-device.ts", "src/ux-sim/skills-tools-shell-device.ts", "src/ux-sim/subagent-tools-device.ts", "src/ux-sim/task-agent-parent-host-device.ts", "src/ux-sim/task-agent-rejudge-on-head-device.ts", "src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts"], "tests": ["src/ux-sim/boot-daemon-tools-pty-shell-device.test.ts", "src/ux-sim/cli-config-audit-device.test.ts", "src/ux-sim/computer-use.test.ts", "src/ux-sim/dashboard-event-loop-stall-monitor-device.test.ts", "src/ux-sim/event-monkey.test.ts", "src/ux-sim/goal-device.test.ts", "src/ux-sim/onboarding-first-run-device.test.ts", "src/ux-sim/resume-picker-device.test.ts", "src/ux-sim/self-implement-author-clarification.test.ts", "src/ux-sim/skills-tools-shell-device.test.ts", "src/ux-sim/subagent-tools-device.test.ts", "src/ux-sim/task-agent-parent-host-device.test.ts", "src/ux-sim/task-agent-rejudge-on-head-device.test.ts", "src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.test.ts"], "target": "selected product, PTY, agent and orchestration seams", "inputs": ["UI state", "task outcome", "host/review decision", "tool result"], "observations": ["rendered state", "decision result", "event sequence", "stop reason"] },
24
+ { "id": "first-run-and-seminar", "name": "First-run authoring and seminar scenarios", "implementation": ["src/ux-sim/mock-authoring-first-run.ts", "src/ux-sim/mock-authoring-first-run-child.ts", "src/ux-sim/seminar-rehearsal.ts", "src/ux-sim/classic-tui-seat-scenarios.ts", "src/ux-sim/next-tui-seat-scenarios.ts", "src/ux-sim/session-id-seed.ts"], "tests": ["src/ux-sim/mock-authoring-first-run.test.ts", "src/ux-sim/seminar-rehearsal.test.ts", "src/ux-sim/classic-tui-seat-scenarios.test.ts", "src/ux-sim/next-tui-seat-scenarios.test.ts"], "target": "first-run, authoring and scripted TUI flows", "inputs": ["mock author response", "scenario steps", "seeded session id"], "observations": ["step result", "TUI snapshot", "completion and failure markers"] },
25
+ { "id": "support-fakes", "name": "Additional fake and in-process CLI fixtures", "implementation": ["test/ux-sim/aimock-local.ts", "src/ux-sim/in-process-cli.ts"], "tests": ["src/ux-sim/aimock-local.test.ts", "src/ux-sim/in-process-cli.test.ts"], "target": "local fake LLM server and test CLI instance", "inputs": ["test state root", "fake endpoint response", "temporary git repository"], "observations": ["isolated CLI result", "server requests", "repository state"] }
26
+ ],
27
+ "scenarios": [
28
+ { "id": "UX-MS-01", "name": "Child report deficit with later harvest", "kind": "report-deficit", "device": "fault-injection", "implementation": ["src/ux-sim/fault-pod-child-result.ts"], "tests": ["src/ux-sim/fault-pod-child-result.test.ts"], "trigger": "A child completes with report-deficit while a later child has a harvestable PR.", "observe": ["failure classification remains report-deficit", "Pod terminal data stays attached", "later harvest remains independent"], "expected": "report-deficit is preserved and harvest result is visible" },
29
+ { "id": "UX-MS-02", "name": "Release gate regression routing", "kind": "gate-regression", "device": "release-graph-rig", "implementation": ["src/ux-sim/release-sim-rig.ts"], "tests": ["src/ux-sim/release-sim-rig.test.ts"], "trigger": "Inject a regression verdict into the release gate node.", "observe": ["visited graph nodes", "unexpected edge list", "terminal status"], "expected": "failure follows the configured repair/review route, not publish" },
30
+ { "id": "UX-MS-03", "name": "Review cap and no-verdict boundary", "kind": "review-cap-no-verdict", "device": "product-devices", "implementation": ["src/ux-sim/task-agent-rejudge-on-head-device.ts"], "tests": ["src/ux-sim/task-agent-rejudge-on-head-device.test.ts"], "trigger": "Stored review count reaches the cap or a review result is absent.", "observe": ["review request count", "verdict classification", "decision reason"], "expected": "the cap blocks another request and missing verdict stays unmeasured" },
31
+ { "id": "UX-MS-04", "name": "Pod credential failure", "kind": "pod-auth-failure", "device": "fault-injection", "implementation": ["src/ux-sim/fault-glm-no-credential.ts", "src/ux-sim/fault-pod-codex-503.ts"], "tests": ["src/ux-sim/fault-glm-no-credential.test.ts", "src/ux-sim/fault-pod-codex-503.test.ts"], "trigger": "Remove the child credential or inject a Codex 401/503 response.", "observe": ["credential readiness", "provider error event", "launch/recovery disposition"], "expected": "credential absence and temporary provider unavailability remain distinguishable" },
32
+ { "id": "UX-MS-05", "name": "TUI and gate worker stall", "kind": "stall", "device": "product-devices", "implementation": ["src/ux-sim/dashboard-event-loop-stall-monitor-device.ts"], "tests": ["src/ux-sim/dashboard-event-loop-stall-monitor-device.test.ts", "scripts/release-loop/gate-pod-stall.test.ts"], "trigger": "Delay the UI event loop or stop gate shard output.", "observe": ["typing lag/stall sample", "stalled shard reason", "bounded completion"], "expected": "stall is named and unrelated work can finish" },
33
+ { "id": "UX-MS-06", "name": "Landing train rejection", "kind": "train-rejection", "device": "fake-land-queue", "implementation": ["src/ux-sim/fake-land-queue.ts"], "tests": ["src/ux-sim/fake-land-queue.test.ts"], "trigger": "Inject a full queue, failed gate, conflicting head or closed cut window.", "observe": ["queue decision", "rejection reason", "slot state"], "expected": "the queue refuses with a reason and does not grant a slot" },
34
+ { "id": "UX-MS-07", "name": "Pod pool capacity and query errors", "kind": "pod-pool-error", "device": "fault-injection", "implementation": ["src/ux-sim/fault-pool-cap.ts", "src/ux-sim/fake-kubectl.ts"], "tests": ["src/ux-sim/fault-pool-cap.test.ts", "src/ux-sim/fake-kubectl.test.ts"], "trigger": "Omit a pool limit, saturate members, or inject a kubectl query failure.", "observe": ["recommended concurrency", "limitedBy", "query error"], "expected": "known running counts are capped; a query failure preserves unknown occupancy and emits no concurrency recommendation" }
35
+ ],
36
+ "discovery": {
37
+ "trackedRoot": "src/ux-sim/*.ts runtime modules",
38
+ "candidateRoots": ["scripts/*sim*.ts", "scripts/release-loop/*sim*.ts", "scripts/lib/pwa-scenarios/*.ts", "test/**/*fake*", "test/**/*stub*", "test/scenarios/**/*"],
39
+ "limits": "The index records reviewed reusable simulation devices and named acceptance scenarios. Candidate paths outside the tracked root are surfaced for review; this is not proof that every repository fake/stub has scenario value."
40
+ }
41
+ }