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
@@ -18,6 +18,7 @@
18
18
 
19
19
  import { loadFederatedRunLedger, loadRunLedger, runLedgerDir, type RunLedgerEntry } from '../../self-implement/run-ledger.js';
20
20
  import { redactSecretText } from '../../debug/log.js';
21
+ import { projectRunLedgerSteps, type RunStep } from '../../self-implement/run-step-projection.js';
21
22
 
22
23
  export interface TraversalStepWire {
23
24
  node: string;
@@ -29,6 +30,8 @@ export interface TraversalStepWire {
29
30
  visit: number;
30
31
  maxVisits: number | null;
31
32
  detail: string | null;
33
+ /** Ledger sequence of this traversal entry; absent on legacy records. */
34
+ sourceSeq?: number;
32
35
  }
33
36
 
34
37
  export interface RunTraversalWire {
@@ -43,6 +46,8 @@ export interface RunTraversalWire {
43
46
  prNumber: number | null;
44
47
  substrate: string | null;
45
48
  steps: TraversalStepWire[];
49
+ /** Structural graph changes in the same per-run sequence domain as `steps[].sourceSeq`. */
50
+ graphEvents?: RunStep[];
46
51
  ledgerEvents: number;
47
52
  }
48
53
 
@@ -153,6 +158,7 @@ export function buildRunTraversal(runId: string, entries: readonly RunLedgerEntr
153
158
  if (isLast && terminal) outcome = TERMINAL_FAIL.has(status) ? 'fail' : (outcome ?? 'pass');
154
159
  const endIso = nextAt !== undefined ? sorted[nextAt]!.timestamp : terminal?.timestamp;
155
160
  const duration = ms(endIso) - ms(entry.timestamp);
161
+ const sourceSeq = (entry as RunLedgerEntry & { seq?: unknown }).seq ?? entry.data.seq;
156
162
  return {
157
163
  node,
158
164
  round: num(entry.data.round),
@@ -162,11 +168,15 @@ export function buildRunTraversal(runId: string, entries: readonly RunLedgerEntr
162
168
  visit,
163
169
  maxVisits: num(budget?.data.maxVisits),
164
170
  detail,
171
+ ...(typeof sourceSeq === 'number' && Number.isSafeInteger(sourceSeq) && sourceSeq > 0 ? { sourceSeq } : {}),
165
172
  };
166
173
  });
167
174
 
168
175
  const contract = sorted.find((entry) => entry.event === 'graph-run-contract-resolved')?.data;
169
176
  const pr = [...sorted].reverse().find((entry) => entry.event === 'pr-opened')?.data;
177
+ const projected = projectRunLedgerSteps(runId, sorted);
178
+ const graphEvents = projected.steps.filter((step) =>
179
+ step.type === 'node-added' || step.type === 'edge-rerouted' || step.type === 'unit-expanded' || step.type === 'unit-collapsed');
170
180
  return {
171
181
  runId,
172
182
  graphId: str(contract?.graphId) ?? str(sorted.find((entry) => entry.event === 'pipeline-node-entry')?.data.graphId),
@@ -178,6 +188,7 @@ export function buildRunTraversal(runId: string, entries: readonly RunLedgerEntr
178
188
  prNumber: num(pr?.number),
179
189
  substrate: str(contract?.actualSubstrate),
180
190
  steps,
191
+ ...(graphEvents.length ? { graphEvents } : {}),
181
192
  ledgerEvents: sorted.length,
182
193
  };
183
194
  }
@@ -41,7 +41,7 @@ export interface GuardReason { code: GuardCode; detail: string; prs?: readonly n
41
41
  /** PR-GUARD-HUNK-WARN (대표 10-17): 줄 겹침은 기본 경고 — 착지 쪽 스마트 머지가 푼다. 'refuse' = 옛 거부 동작. */
42
42
  export type HunkOverlapMode = 'refuse' | 'warn';
43
43
  export interface GuardVerdict { status: 'allow' | 'refuse' | 'unknown'; reasons: readonly GuardReason[]; warnings: readonly GuardReason[];
44
- sameCellConflicts?: readonly { pr: number; cardId: string | null; slice?: { slice: number; total: number } | null }[];
44
+ sameCellConflicts?: readonly { pr: number; branch: string | null; headSha: string; cardId: string | null; slice?: { slice: number; total: number } | null }[];
45
45
  sameCellReuse?: { number: number; branch: string; headSha: string; cellId: string; cardId: string; legacyBound?: true } }
46
46
 
47
47
  const SEATS = ['OP', 'TC', 'MK', 'UX'] as const;
@@ -511,7 +511,8 @@ export function guardNewPr(input: { files: readonly string[] | null; seat?: Seat
511
511
  ? { number: sameCell[0].number, branch: sameCell[0].headRefName, headSha: sameCell[0].headSha,
512
512
  cellId: input.cellId!, cardId: input.cardId, ...(legacyBound ? { legacyBound: true as const } : {}) } : undefined;
513
513
  return { status, reasons, warnings,
514
- ...(sameCell.length ? { sameCellConflicts: sameCell.map(pr => ({ pr: pr.number, cardId: pr.cardId ?? null, slice: pr.slice ?? null })) } : {}),
514
+ ...(sameCell.length ? { sameCellConflicts: sameCell.map(pr => ({ pr: pr.number, branch: pr.headRefName ?? null,
515
+ headSha: pr.headSha, cardId: pr.cardId ?? null, slice: pr.slice ?? null })) } : {}),
515
516
  ...(reusable ? { sameCellReuse: reusable } : {}) };
516
517
  }
517
518
 
@@ -12,7 +12,7 @@
12
12
  // 판독(CLI 쪽): `describePtyRunState` 가 행 ⊕ 설치본 기록 ⊕ (체크아웃이면) 그 뿌리의 HEAD 로 판정한다.
13
13
 
14
14
  import { spawn } from 'node:child_process';
15
- import { readFileSync } from 'node:fs';
15
+ import { appendFileSync, mkdirSync, readFileSync } from 'node:fs';
16
16
  import { homedir } from 'node:os';
17
17
  import { dirname, join, resolve } from 'node:path';
18
18
  import { fileURLToPath } from 'node:url';
@@ -30,6 +30,7 @@ import {
30
30
  updatePtyManifestAbortRequested, updatePtyManifestBuild, updatePtyManifestProgress, updatePtyManifestTurn,
31
31
  type PtyBuildIdentity, type PtyManifestRow, type PtyTurnState,
32
32
  } from './pty-manifest.js';
33
+ import { ptyEventLogDbPath, readPtyEventsAfterAt } from './pty-event-log.js';
33
34
 
34
35
  const CODE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
35
36
 
@@ -496,6 +497,139 @@ export function judgeTurnProgress(input: TurnProgressInput): TurnProgressJudgmen
496
497
  return 'progressing';
497
498
  }
498
499
 
500
+ // ── TUI-SEAT-PILOT-2H-COMPARE — 좌석 대조 판정 신호 한 줄 ──
501
+ //
502
+ // 완료 경계는 «실행 명령·runId·시작/끝 시각·두 표면의 원장 행·산출 바이트·오류 수·결과» 를
503
+ // `seat-state/OP/tools/sim-log.sh` 한 줄로 남기라고 한다. 그 한 줄의 «형식» 은 순수 함수가 정하고,
504
+ // 두 표면의 원장 행은 각자의 생산 원장에서 읽는다 — tui-run-state 는 pty_manifest 행, pty-event-log 는
505
+ // `pty_events` 의 그 표면 행이다. ⛔ 재지 못한 항목은 «미측정» 으로 남긴다 — 측정된 `0` 과 섞지 않는다(null ≠ 0).
506
+
507
+ /** 재지 못한 항목의 직렬화 값. 측정된 `0`·빈 문자열과 구별된다. */
508
+ export const SEAT_COMPARE_UNMEASURED = '미측정';
509
+
510
+ /** 한 표면의 원장 요약. `rows === null` 은 «못 읽었다» 이지 «0행» 이 아니다. */
511
+ export interface SeatCompareLedgerSummary {
512
+ readonly surface: string;
513
+ readonly rows: number | null;
514
+ readonly lastSeq: number | null;
515
+ readonly lastState: string | null;
516
+ }
517
+
518
+ /** 판정 신호 입력 — 완료 경계가 이름으로 요구한 항목 그대로. */
519
+ export interface SeatCompareSignalInput {
520
+ readonly runId: string | null;
521
+ readonly command: string | null;
522
+ readonly startedAt: number | null;
523
+ readonly endedAt: number | null;
524
+ /** 이 TUI 좌석 표면의 원장 행 요약(pty_manifest 턴 행). */
525
+ readonly tuiRunState: SeatCompareLedgerSummary;
526
+ /** 비교 상대 표면의 원장 행 요약(`pty_events`). */
527
+ readonly ptyEventLog: SeatCompareLedgerSummary;
528
+ readonly outputBytes: number | null;
529
+ readonly errors: number | null;
530
+ readonly result: string | null;
531
+ }
532
+
533
+ function seatCompareText(value: string | null | undefined): string {
534
+ if (value === null || value === undefined) return SEAT_COMPARE_UNMEASURED;
535
+ // 한 줄 계약 — 값 안의 개행·연속 공백은 접어서 줄을 쪼개지 못하게 한다.
536
+ const flat = value.replace(/\s+/g, ' ').trim();
537
+ return flat.length > 0 ? flat : SEAT_COMPARE_UNMEASURED;
538
+ }
539
+
540
+ function seatCompareCount(value: number | null | undefined): string {
541
+ if (value === null || value === undefined || !Number.isFinite(value)) return SEAT_COMPARE_UNMEASURED;
542
+ return String(value);
543
+ }
544
+
545
+ function seatCompareAt(ms: number | null | undefined): string {
546
+ if (ms === null || ms === undefined || !Number.isFinite(ms)) return SEAT_COMPARE_UNMEASURED;
547
+ return new Date(ms).toISOString();
548
+ }
549
+
550
+ function seatCompareLedger(summary: SeatCompareLedgerSummary): string {
551
+ return [
552
+ `ledger:${seatCompareText(summary.surface)}`,
553
+ `rows=${seatCompareCount(summary.rows)}`,
554
+ `lastSeq=${seatCompareCount(summary.lastSeq)}`,
555
+ `lastState=${seatCompareText(summary.lastState)}`,
556
+ ].join(' ');
557
+ }
558
+
559
+ /** 판정 신호 한 줄 — 새 줄 없이 ` · ` 로 잇는다. 못 잰 항목은 «미측정» 으로 남는다. */
560
+ export function buildSeatCompareSignalLine(input: SeatCompareSignalInput): string {
561
+ return [
562
+ `run=${seatCompareText(input.runId)}`,
563
+ `cmd=${seatCompareText(input.command)}`,
564
+ `start=${seatCompareAt(input.startedAt)}`,
565
+ `end=${seatCompareAt(input.endedAt)}`,
566
+ seatCompareLedger(input.tuiRunState),
567
+ seatCompareLedger(input.ptyEventLog),
568
+ `bytes=${seatCompareCount(input.outputBytes)}`,
569
+ `errors=${seatCompareCount(input.errors)}`,
570
+ `result=${seatCompareText(input.result)}`,
571
+ ].join(' · ');
572
+ }
573
+
574
+ /** 생산 이음매 — `pty_events` 원장에서 이 표면의 행을 실제로 읽어 요약한다. 못 읽으면 rows=null(미측정). */
575
+ export function readPtyEventLogLedger(surfaceId: string, dbPath: string = ptyEventLogDbPath()): SeatCompareLedgerSummary {
576
+ const surface = 'pty-event-log';
577
+ const read = readPtyEventsAfterAt(dbPath, 0, { surfaceId });
578
+ if (read.status !== 'ok') return { surface, rows: null, lastSeq: null, lastState: null };
579
+ const last = read.rows.length > 0 ? read.rows[read.rows.length - 1] : undefined;
580
+ return { surface, rows: read.rows.length, lastSeq: last ? last.seq : 0, lastState: last?.state ?? null };
581
+ }
582
+
583
+ /** 기본 기록 위치 — 셸 도구와 같은 파일(`seat-state/OP/tools/sim-log.log`). `ELANOUS_SEAT_COMPARE_LOG` 로 바꾼다. */
584
+ export const SEAT_COMPARE_LOG_PATH = join(CODE_ROOT, 'seat-state', 'OP', 'tools', 'sim-log.log');
585
+
586
+ export interface SeatCompareWriteDeps {
587
+ readonly path?: string;
588
+ /** append 이음매 — 시험이 임시 파일·메모리로 바꾼다. */
589
+ readonly append?: (path: string, line: string) => void;
590
+ }
591
+
592
+ /** 판정 신호 한 줄을 sim-log 에 append 한다. 실패(권한 등)는 false — 종료 경로를 깨지 않는다. */
593
+ export function appendSeatCompareSignalLine(line: string, deps: SeatCompareWriteDeps = {}): boolean {
594
+ const path = deps.path ?? (process.env.ELANOUS_SEAT_COMPARE_LOG?.trim() || SEAT_COMPARE_LOG_PATH);
595
+ try {
596
+ if (deps.append) {
597
+ deps.append(path, line);
598
+ } else {
599
+ mkdirSync(dirname(path), { recursive: true });
600
+ appendFileSync(path, `${line}\n`, 'utf8');
601
+ }
602
+ return true;
603
+ } catch {
604
+ return false;
605
+ }
606
+ }
607
+
608
+ /**
609
+ * 생산 진입점 스위치 — `ELANOUS_SEAT_COMPARE_RUN_ID` 가 있을 때만 좌석 대조 원장을 켠다.
610
+ * 없으면 `null` = 녹음기가 그 한 줄을 안 남긴다(«미실행은 미측정»).
611
+ */
612
+ export function seatCompareDepsFromEnv(env: NodeJS.ProcessEnv = process.env): TuiSeatCompareDeps | null {
613
+ const runId = env.ELANOUS_SEAT_COMPARE_RUN_ID?.trim();
614
+ if (!runId) return null;
615
+ const command = env.ELANOUS_SEAT_COMPARE_COMMAND?.trim() || [process.execPath, ...process.argv.slice(1)].join(' ');
616
+ return { runId, command };
617
+ }
618
+
619
+ /** 좌석 대조 판정 신호를 켜는 손잡이 — 주면 녹음기 종료 경로가 두 표면 원장을 읽어 한 줄을 남긴다. */
620
+ export interface TuiSeatCompareDeps {
621
+ readonly runId: string | null;
622
+ readonly command?: string | null;
623
+ /** 산출 바이트 — 녹음기가 못 재면 생략(«미측정»). */
624
+ readonly outputBytes?: number | null;
625
+ /** 결과 판정 문구 — 생략하면 종료 시 마지막 턴 상태. */
626
+ readonly result?: string | null;
627
+ /** 원장 요약 읽기 이음매(시험: 가짜 원장). 생략하면 실 `pty_events`. */
628
+ readonly readLedger?: (surfaceId: string) => SeatCompareLedgerSummary;
629
+ /** 기록 이음매(시험: 메모리). 생략하면 sim-log 파일 append. */
630
+ readonly write?: (line: string) => boolean;
631
+ }
632
+
499
633
  // ── 기록(TUI) ──
500
634
 
501
635
  export interface TuiRunStateRecorderDeps {
@@ -524,6 +658,11 @@ export interface TuiRunStateRecorderDeps {
524
658
  * 생략하면 감시를 안 건다 — 이 축을 켜는 것은 호출자(생산 진입점)의 결정이다.
525
659
  */
526
660
  readonly selfRestart?: TuiSelfRestartDeps;
661
+ /**
662
+ * TUI-SEAT-PILOT-2H-COMPARE 좌석 대조 판정 신호. 주면 종료 경로가 두 표면(pty_manifest 턴 행 ⊕
663
+ * `pty_events`)의 원장행을 읽어 «한 줄» 을 sim-log 에 남긴다. 생략하면 아무것도 안 남긴다(미실행=미측정).
664
+ */
665
+ readonly seatCompare?: TuiSeatCompareDeps;
527
666
  }
528
667
 
529
668
  interface ActiveRecorder {
@@ -550,9 +689,29 @@ const defaultLog = (event: string, data: Record<string, unknown>): void => { deb
550
689
  export function startTuiRunStateRecorder(surfaceId: string, deps: TuiRunStateRecorderDeps = {}): () => void {
551
690
  const now = deps.now ?? Date.now;
552
691
  const log = deps.log ?? defaultLog;
553
- const writeTurn = deps.writeTurn ?? updatePtyManifestTurn;
692
+ const writeTurnBase = deps.writeTurn ?? updatePtyManifestTurn;
554
693
  const writeProgress = deps.writeProgress ?? updatePtyManifestProgress;
555
694
  const writeAbortRequested = deps.writeAbortRequested ?? updatePtyManifestAbortRequested;
695
+ // 좌석 대조 신호가 켜졌을 때만 턴 행 수·쓰기 실패를 센다 — 꺼져 있으면 판정 신호 비용 0.
696
+ const seatCompare = deps.seatCompare ?? null;
697
+ // 시작 시각도 신호가 켜졌을 때만 잰다 — 꺼져 있으면 종전과 같이 now() 를 한 번도 더 부르지 않는다.
698
+ const seatCompareStartedAt = seatCompare ? now() : 0;
699
+ let seatCompareTurnRows = 0;
700
+ let seatCompareWriteFailures = 0;
701
+ const writeTurn = seatCompare
702
+ ? (id: string, turn: PtyTurnState, at: number): boolean => {
703
+ let ok = false;
704
+ try {
705
+ ok = writeTurnBase(id, turn, at);
706
+ } catch (error) {
707
+ seatCompareWriteFailures += 1;
708
+ throw error;
709
+ }
710
+ if (ok) seatCompareTurnRows += 1;
711
+ else seatCompareWriteFailures += 1;
712
+ return ok;
713
+ }
714
+ : writeTurnBase;
556
715
  // 기본 신고기는 기본 manifest 쓰기와 짝일 때만. writeTurn 주입(시험)은 herdr 를 안 만든다.
557
716
  const herdr = deps.herdr !== undefined
558
717
  ? deps.herdr
@@ -564,6 +723,7 @@ export function startTuiRunStateRecorder(surfaceId: string, deps: TuiRunStateRec
564
723
  if (build) {
565
724
  const ok = (() => { try { return (deps.writeBuild ?? updatePtyManifestBuild)(surfaceId, build); } catch { return false; } })();
566
725
  log(ok ? 'build-recorded' : 'build-write-failed', { ptyId: surfaceId, sha: build.sha, version: build.version, source: build.source });
726
+ if (!ok) seatCompareWriteFailures += 1;
567
727
  }
568
728
  // 기동 순서: 판 → manifest 초기 idle → herdr 신고. herdr start 가 idle 을 신고하므로 초기 idle 을 turn 으로 다시 안 보낸다.
569
729
  const recorder: ActiveRecorder = { surfaceId, now, writeTurn, writeProgress, writeAbortRequested, log, herdr, herdrLast: herdr ? 'idle' : undefined };
@@ -662,6 +822,32 @@ export function startTuiRunStateRecorder(surfaceId: string, deps: TuiRunStateRec
662
822
  try { unwatch(); } catch { /* 종료 경로를 깨지 않는다 */ }
663
823
  try { unguard(); } catch { /* 종료 경로를 깨지 않는다 */ }
664
824
  if (herdr) { try { herdr.release(); } catch { /* 종료 경로를 깨지 않는다 */ } }
825
+ // 좌석 대조 판정 신호 — 두 표면의 원장 행을 «여기서» 읽어 한 줄로 남긴다.
826
+ if (seatCompare) {
827
+ try {
828
+ const readLedger = seatCompare.readLedger ?? readPtyEventLogLedger;
829
+ const line = buildSeatCompareSignalLine({
830
+ runId: seatCompare.runId,
831
+ command: seatCompare.command ?? null,
832
+ startedAt: seatCompareStartedAt,
833
+ endedAt: now(),
834
+ tuiRunState: {
835
+ surface: 'tui-run-state',
836
+ rows: seatCompareTurnRows,
837
+ lastSeq: null,
838
+ lastState: recorder.last ?? null,
839
+ },
840
+ ptyEventLog: readLedger(surfaceId),
841
+ outputBytes: seatCompare.outputBytes ?? null,
842
+ errors: seatCompareWriteFailures,
843
+ result: seatCompare.result ?? recorder.last ?? null,
844
+ });
845
+ const written = (seatCompare.write ?? appendSeatCompareSignalLine)(line);
846
+ log(written ? 'seat-compare-signal' : 'seat-compare-signal-write-failed', { ptyId: surfaceId, line });
847
+ } catch (error) {
848
+ log('seat-compare-signal-failed', { ptyId: surfaceId, error: error instanceof Error ? error.message : String(error) });
849
+ }
850
+ }
665
851
  if (active === recorder) active = null;
666
852
  };
667
853
  }
@@ -0,0 +1,13 @@
1
+ export interface TargetPathHintLine {
2
+ readonly fragments: readonly string[];
3
+ readonly labelMissing: boolean;
4
+ }
5
+
6
+ /** Parse the first declared target-path line shared by checklist storage and ask preflight. */
7
+ export function parseTargetPathHintLine(text: string): TargetPathHintLine {
8
+ const firstLine = text.split(/\r?\n/).find((line) => line.trim() !== '');
9
+ if (firstLine === undefined) return { fragments: [], labelMissing: true };
10
+ const match = /^\s*(?:대상\s*경로|target\s*paths?)\s*[::]\s*(.*)$/i.exec(firstLine);
11
+ if (!match) return { fragments: [], labelMissing: true };
12
+ return { fragments: match[1]!.split(/[·,;]/), labelMissing: false };
13
+ }
@@ -5,6 +5,9 @@ import { isAbsolute, join } from 'node:path';
5
5
  import * as store from './feature-store.js';
6
6
  import { debug } from '../debug/log.js';
7
7
  import { CliUserError } from '../cli/cli-user-error.js';
8
+ import { parseTargetPathHintLine } from './checklist-target-path-hint.js';
9
+ export { parseTargetPathHintLine } from './checklist-target-path-hint.js';
10
+ export type { TargetPathHintLine } from './checklist-target-path-hint.js';
8
11
 
9
12
  export type ChecklistStatus = 'green' | 'yellow' | 'red' | 'done';
10
13
  export type ChecklistDisposition = 'move' | 'known-issue' | 'block';
@@ -248,6 +251,11 @@ export function isMergeOrTypecheckOnlyEvidence(value: string): boolean {
248
251
  return signal;
249
252
  }
250
253
 
254
+ /** Parsed target path fragments, preserving order and raw path spelling while trimming separator whitespace. */
255
+ export function parseChecklistTargetPaths(text: string): string[] {
256
+ return parseTargetPathHintLine(text).fragments.map((fragment) => fragment.trim().replace(/^`+|`+$/g, ''));
257
+ }
258
+
251
259
  /** Shadow check at checklist authorship. Callers supply the origin/main file probe and merged-PR file reader. */
252
260
  export function inspectChecklistTargetPaths(input: {
253
261
  title: string; evidence?: string; refs?: readonly string[]; dispatchKind?: ChecklistDispatchKind;
@@ -256,7 +264,7 @@ export function inspectChecklistTargetPaths(input: {
256
264
  } {
257
265
  const lines = input.title.split(/\r?\n/);
258
266
  const first = /^대상 경로:\s*(.*)$/.exec(lines[0] ?? '');
259
- const rawTargets = first?.[1]?.split(' · ').map((path) => path.trim()) ?? [];
267
+ const rawTargets = parseChecklistTargetPaths(lines[0] ?? '');
260
268
  const validPath = (path: string): boolean => path.length > 0 && path.length < 4096
261
269
  && !path.startsWith('/') && !path.includes('\\') && !/[\u0000-\u001f\u007f]/u.test(path)
262
270
  && path.split('/').every((segment) => segment !== '' && segment !== '.' && segment !== '..');
package/src/repl/index.ts CHANGED
@@ -41,6 +41,8 @@ import {
41
41
  type UserConfig,
42
42
  } from '../user-config.js';
43
43
  import { setAmbientSessionId, debug } from '../debug/log.js';
44
+ import { buildInstalledSkillCatalogMessage, type InstalledSkillSummary } from '../dashboard/skill-catalog-preamble.js';
45
+ import { resolveModelContextWindow } from '../models/context-window.js';
44
46
  import { decideSigintAction } from './sigint.js';
45
47
  import { decideSessionStart, observeSessionStart } from '../session/session-start.js';
46
48
  import { buildReplayTurnsFromSession } from './replay.js';
@@ -275,13 +277,39 @@ export function buildReplSystemPrompt(ctx: {
275
277
  sessionId?: string | undefined;
276
278
  /** 시험·임베디드 호출부용 시임 — 기본은 실제 홈·msg 원장·process.env. */
277
279
  seatBootDeps?: SeatBootDeps | undefined;
280
+ /** Installed skill summaries are injectable for deterministic prompt tests. */
281
+ skillCatalog?: readonly InstalledSkillSummary[] | undefined;
282
+ skillCatalogContextWindow?: number | null | undefined;
278
283
  }): string | undefined {
279
284
  const base = ctx.enabledToolNames === undefined
280
285
  ? undefined
281
286
  : buildAgentSystemPrompt(ctx.cfg, ctx.enabledToolNames);
287
+ const skillToolsEnabled = ctx.enabledToolNames?.includes('skill_exec') === true
288
+ && ctx.enabledToolNames.includes('elanous_skills_list');
289
+ let skillCatalogText = '';
290
+ if (skillToolsEnabled) {
291
+ try {
292
+ const catalog = ctx.skillCatalog ?? (() => {
293
+ const skills = require('../skills/index.js') as typeof import('../skills/index.js');
294
+ return skills.applySkillFilter(skills.getSkillIndex(), ctx.cfg.skills)
295
+ .map(({ name, description }) => ({ name, description }));
296
+ })();
297
+ const built = buildInstalledSkillCatalogMessage(
298
+ catalog,
299
+ ctx.skillCatalogContextWindow ?? resolveModelContextWindow(ctx.cfg.llm.model),
300
+ );
301
+ skillCatalogText = built.message?.content ?? '';
302
+ debug.log('repl.skill-catalog', 'built', {
303
+ skillCount: built.skillCount, estimatedTokens: built.estimatedTokens,
304
+ budgetTokens: built.budgetTokens, mode: built.mode,
305
+ });
306
+ } catch (error) {
307
+ debug.log('repl.skill-catalog', 'failed', { reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' });
308
+ }
309
+ }
282
310
  const card = buildSeatBootCardText(ctx);
283
- if (card.length === 0) return base;
284
- return base === undefined || base.length === 0 ? card : `${base}\n\n${card}`;
311
+ const parts = [skillCatalogText, base ?? '', card].filter(part => part.length > 0);
312
+ return parts.length > 0 ? parts.join('\n\n') : undefined;
285
313
  }
286
314
 
287
315
  /** 자리 부트 카드 문면(system 메시지 0~1개를 이어 붙인 것). 자리가 아니면 ''. */
@@ -344,6 +372,7 @@ async function runOneTurn(
344
372
  nextTuiDelivery?: { pending: PendingTaskNotification[] },
345
373
  onJsonDelta?: (delta: string) => void,
346
374
  onJsonStatus?: (line: string) => void,
375
+ onJsonReplace?: (fullText: string) => void,
347
376
  ): Promise<{ reply: string; provider: string; model: string | null; durationMs: number; logPath: string | null }> {
348
377
  const startedAt = Date.now();
349
378
  const replyChunks: string[] = [];
@@ -374,6 +403,7 @@ async function runOneTurn(
374
403
  userConfig: cfg,
375
404
  sessionId,
376
405
  userText,
406
+ utteranceSurface: 'tui',
377
407
  systemPrompt,
378
408
  userImages: userImages.length > 0 ? userImages : undefined,
379
409
  ...(process.env.ELANOUS_TEST_FAKE_LLM === '1' && Number.isFinite(Number(process.env.ELANOUS_TEST_FAKE_LLM_IDLE_TIMEOUT_MS))
@@ -387,6 +417,14 @@ async function runOneTurn(
387
417
  }
388
418
  else process.stdout.write(d);
389
419
  },
420
+ onReplaceText: (fullText) => {
421
+ if (jsonOutput) {
422
+ replyChunks.splice(0, replyChunks.length, fullText);
423
+ onJsonReplace?.(fullText);
424
+ } else {
425
+ process.stdout.write(`\n\n [근거 반영된 답변]\n ${fullText}\n`);
426
+ }
427
+ },
390
428
  onStatusLine: (line) => { onJsonStatus?.(line); },
391
429
  tools: replToolSpecs,
392
430
  dispatchTool: tools?.dispatch,
@@ -795,6 +833,9 @@ export async function runRepl(opts: ReplOpts): Promise<number> {
795
833
  process.env.ELANOUS_NEXT_TUI_STREAM === '1' && typeof turn.id === 'string'
796
834
  ? (text) => { process.stdout.write(`${JSON.stringify({ event: 'status', turnId: turn.id, text })}\n`); }
797
835
  : undefined,
836
+ process.env.ELANOUS_NEXT_TUI_STREAM === '1' && typeof turn.id === 'string'
837
+ ? (text) => { process.stdout.write(`${JSON.stringify({ event: 'replace', turnId: turn.id, text })}\n`); }
838
+ : undefined,
798
839
  );
799
840
  } catch (error) {
800
841
  if (!backgroundBridge) throw error;
@@ -1,7 +1,15 @@
1
1
  // Research-only native fanout. The caller supplies Bloom's question ladder;
2
2
  // each axis gets its own direct tool call and evidence stays attributed to it.
3
3
  import type { BloomResearchQuestion, ResearchEvidenceEnvelope } from '../auto-research/question-ladder-contract.js';
4
- import type { WebSearchHit } from '../web-search/provider.js';
4
+ import { getAvailableWebSearchProviders } from '../web-search/index.js';
5
+ import type { WebSearchHit, WebSearchProvider } from '../web-search/provider.js';
6
+ import { debug } from '../debug/log.js';
7
+
8
+ const RESEARCH_SEARCH_ENGINES = ['grok', 'grok-api', 'firecrawl'] as const;
9
+ const RESEARCH_GROK_TIMEOUT_MS = 8_000;
10
+ // Leave scheduler/logging headroom under the user-visible 15s aggregate cap.
11
+ export const RESEARCH_SEARCH_BUDGET_MS = 14_500;
12
+ const ENGINE_BREAKER_FAILURE_LIMIT = 2;
5
13
 
6
14
  export interface AxisToolCallPlan {
7
15
  questionId: string;
@@ -25,10 +33,119 @@ export interface AxisSearchResult {
25
33
  hits: AxisSearchHit[];
26
34
  errors: string[];
27
35
  }
28
- export type AxisSearch = (query: string) => Promise<AxisSearchHit[] | AxisSearchResult>;
36
+ export type AxisSearch = (query: string, signal?: AbortSignal) => Promise<AxisSearchHit[] | AxisSearchResult>;
29
37
 
30
38
  export interface AxisFanoutDeps {
31
39
  search?: AxisSearch;
40
+ signal?: AbortSignal;
41
+ }
42
+
43
+ interface ProviderHealth {
44
+ failures: number;
45
+ open: boolean;
46
+ }
47
+
48
+ /** Build one bounded searcher per research prepass. Free/DDG is deliberately
49
+ * excluded: it is not a safe fallback for stock research and can consume a
50
+ * full 15s timeout for every query. Per-engine serialization lets the first
51
+ * timeout open that engine's breaker before queued Bloom axes start. */
52
+ export function createResearchAxisSearcher(
53
+ availableProviders: readonly WebSearchProvider[] = getAvailableWebSearchProviders(),
54
+ now: () => number = Date.now,
55
+ ): AxisSearch {
56
+ const grok = availableProviders.find(provider => provider.id === 'grok')
57
+ ?? availableProviders.find(provider => provider.id === 'grok-api');
58
+ const allowed = [
59
+ ...(grok ? [grok] : []),
60
+ ...availableProviders.filter(provider => provider.id === 'firecrawl'),
61
+ ];
62
+ const health = new Map(allowed.map(provider => [provider.id, { failures: 0, open: false }]));
63
+ const deadline = now() + RESEARCH_SEARCH_BUDGET_MS;
64
+ const tails = new Map<string, Promise<void>>();
65
+
66
+ debug.log('research.search', 'provider-preflight', {
67
+ allowed: RESEARCH_SEARCH_ENGINES,
68
+ available: allowed.map(provider => provider.id),
69
+ excluded: availableProviders.filter(provider => !(RESEARCH_SEARCH_ENGINES as readonly string[]).includes(provider.id))
70
+ .map(provider => provider.id),
71
+ budgetMs: RESEARCH_SEARCH_BUDGET_MS,
72
+ });
73
+
74
+ const enqueue = <T>(providerId: string, run: () => Promise<T>): Promise<T> => {
75
+ const previous = tails.get(providerId) ?? Promise.resolve();
76
+ const current = previous.then(run, run);
77
+ tails.set(providerId, current.then(() => undefined, () => undefined));
78
+ return current;
79
+ };
80
+
81
+ return async (query, signal) => {
82
+ const hits: AxisSearchHit[] = [];
83
+ const errors: string[] = [];
84
+ const selected = allowed.filter(provider => !health.get(provider.id)?.open);
85
+ if (selected.length === 0) return { hits, errors: ['no healthy Grok/Firecrawl research provider'] };
86
+
87
+ await Promise.all(selected.map(provider => enqueue(provider.id, async () => {
88
+ const state = health.get(provider.id)!;
89
+ if (state.open) return;
90
+ const remainingMs = deadline - now();
91
+ if (remainingMs <= 0) {
92
+ state.open = true;
93
+ errors.push(`${provider.id}: research search budget exhausted`);
94
+ return;
95
+ }
96
+ const activeCount = Math.max(1, allowed.filter(candidate => !health.get(candidate.id)?.open).length);
97
+ const isGrok = provider.id === 'grok' || provider.id === 'grok-api';
98
+ const timeoutMs = isGrok
99
+ ? Math.min(RESEARCH_GROK_TIMEOUT_MS, remainingMs)
100
+ : Math.max(1, Math.floor(remainingMs / activeCount));
101
+ const startedAt = now();
102
+ try {
103
+ const controller = new AbortController();
104
+ const abortFromCaller = (): void => controller.abort(signal?.reason);
105
+ if (signal?.aborted) abortFromCaller();
106
+ else signal?.addEventListener('abort', abortFromCaller, { once: true });
107
+ let timer: ReturnType<typeof setTimeout> | undefined;
108
+ let result;
109
+ try {
110
+ result = await Promise.race([
111
+ provider.search({ query, limit: 5 }, controller.signal),
112
+ new Promise<never>((_, reject) => {
113
+ timer = setTimeout(() => {
114
+ controller.abort();
115
+ reject(new DOMException(`${provider.id} research search timed out after ${timeoutMs}ms`, 'TimeoutError'));
116
+ }, timeoutMs);
117
+ }),
118
+ ]);
119
+ } finally {
120
+ if (timer !== undefined) clearTimeout(timer);
121
+ signal?.removeEventListener('abort', abortFromCaller);
122
+ }
123
+ if (result.hits.length === 0) {
124
+ state.failures += 1;
125
+ if (state.failures >= ENGINE_BREAKER_FAILURE_LIMIT) state.open = true;
126
+ } else {
127
+ state.failures = 0;
128
+ hits.push(...result.hits.map(hit => ({ ...hit, engine: provider.id })));
129
+ }
130
+ debug.log('research.search', 'provider-complete', {
131
+ provider: provider.id, queryLength: query.length, hits: result.hits.length,
132
+ durationMs: now() - startedAt, breakerOpen: state.open,
133
+ });
134
+ } catch (error) {
135
+ const message = error instanceof Error ? error.message : String(error);
136
+ const timeout = error instanceof Error && /timeout|timed out|abort/i.test(`${error.name} ${error.message}`);
137
+ const quota = /quota|credit|rate.?limit|\b429\b|exhaust/i.test(message);
138
+ state.failures += 1;
139
+ if (timeout || quota || state.failures >= ENGINE_BREAKER_FAILURE_LIMIT) state.open = true;
140
+ errors.push(`${provider.id}: ${message}`);
141
+ debug.log('research.search', 'provider-failed', {
142
+ provider: provider.id, queryLength: query.length, durationMs: now() - startedAt,
143
+ timeout, quota, failures: state.failures, breakerOpen: state.open,
144
+ }, { level: 'warn' });
145
+ }
146
+ })));
147
+ return { hits, errors };
148
+ };
32
149
  }
33
150
 
34
151
  /** Keep every query attached to the Bloom question that produced it. */
@@ -39,18 +156,6 @@ export function planAxisToolCalls(questions: readonly BloomResearchQuestion[]):
39
156
  .map(query => ({ questionId: question.id, tool: 'OmniSearch' as const, query })));
40
157
  }
41
158
 
42
- async function directOmniSearch(query: string): Promise<AxisSearchResult> {
43
- const { dispatchOmniSearch } = await import('../skills/tools/omni-search.js');
44
- const hits: AxisSearchHit[] = [];
45
- const result = await dispatchOmniSearch({ query }, { onSource: hit => { hits.push(hit); } });
46
- if (Object.keys(result.metadata.perEngine).length === 0) {
47
- throw new Error('no available web-search providers');
48
- }
49
- const errors = Object.entries(result.metadata.perEngine)
50
- .flatMap(([engine, info]) => info.error ? [`${engine}: ${info.error}`] : []);
51
- return { hits, errors };
52
- }
53
-
54
159
  function evidenceFromHit(question: BloomResearchQuestion, hit: AxisSearchHit): ResearchEvidenceEnvelope {
55
160
  const published = hit.publishedAt;
56
161
  const date = published !== undefined && Number.isFinite(published) && published > 0
@@ -89,8 +194,8 @@ export async function fanOutAxisEvidence(
89
194
  if (new Set(questions.map(question => question.id)).size !== questions.length) {
90
195
  throw new Error('research axis question IDs must be unique');
91
196
  }
92
- const search = deps.search ?? directOmniSearch;
93
- const settled = await Promise.allSettled(plan.map(call => search(call.query)));
197
+ const search = deps.search ?? createResearchAxisSearcher();
198
+ const settled = await Promise.allSettled(plan.map(call => search(call.query, deps.signal)));
94
199
  const axes: AxisEvidenceGroup[] = questions.map(question => ({ questionId: question.id, evidence: [] }));
95
200
  const groups = new Map(axes.map(axis => [axis.questionId, axis]));
96
201
  const byQuestion = new Map(questions.map(question => [question.id, question]));
@@ -34,10 +34,12 @@ const BLOOM_BY_LEVEL = Object.fromEntries(COGNITIVE_BY_LEVEL.map((cognitive, ind
34
34
  return [index + 1, cell];
35
35
  })) as Record<BloomExemplarLevel, Bloom2D>;
36
36
 
37
- // Public source tree intentionally contains only two original exemplars.
37
+ // Public source tree intentionally contains a small set of original exemplars.
38
38
  const PUBLIC_EXEMPLARS: readonly BloomExemplar[] = [
39
39
  { domain: 'finance', level: 4, bloom: BLOOM_BY_LEVEL[4], question: '채권 금리 변화가 만기 구조와 발행자의 차환 위험에 어떤 경로로 연결되는가?' },
40
40
  { domain: 'finance', level: 5, bloom: BLOOM_BY_LEVEL[5], question: '현재 금리 전망을 반박할 수 있는 시장 지표와 그 신뢰도는 무엇인가?' },
41
+ { domain: 'technology', level: 4, bloom: BLOOM_BY_LEVEL[4], question: 'AI 데이터센터의 추론 처리량 증가가 GPU 전력밀도와 냉각 부하, 랙당 계통용량 요구에 어떤 경로로 이어지는가?' },
42
+ { domain: 'technology', level: 5, bloom: BLOOM_BY_LEVEL[5], question: 'AI 데이터센터 전력수요 전망을 반박할 수 있는 GPU 이용률·전력사용효율·계통접속 자료는 무엇이며 각 지표의 한계는 무엇인가?' },
41
43
  ];
42
44
 
43
45
  const DOMAIN_TERMS: Record<BloomExemplarDomain, readonly string[]> = {