elanous 0.2.36 → 0.2.38

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 (741) 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/{uC-N0emedeNOFuaBQFv-I → RrjXTwz-urRAbChP1bX02}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{9250-072df22eaadaa6b5.js → 1026-44010f405704050c.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +27 -0
  6. package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{4304.e9b2512834a9e23e.js → 1632.7d87f998e714bede.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1923-5c1695332240246a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1938.0e6c60ee91c4d7f5.js +148 -0
  14. package/apps/pwa/out/_next/static/chunks/{7784.1f0ac4a16d190cf4.js → 2104.70e086d5174a4736.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{6566.926a1d1b7c911442.js → 214.186a430da28338f1.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +93 -0
  18. package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +104 -0
  19. package/apps/pwa/out/_next/static/chunks/{5711.957b095705c12560.js → 2415.738b777642a02233.js} +1 -1
  20. package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/{4286.b70c4520306817e8.js → 3086.fb14b60ce98b53d3.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/{3148-98efd4869d660a87.js → 3124-561f7f037943cde2.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +24 -0
  31. package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{3727.7949ccaacaa71242.js → 3291.f6c1005387d514bd.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +36 -0
  34. package/apps/pwa/out/_next/static/chunks/3341-f09b9efbd7a82f70.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3389.012c70767a872f9b.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +287 -0
  38. package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/{8904.7d51af2dc033965c.js → 3528.e4b8ab70d339f965.js} +2 -2
  40. package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +94 -0
  45. package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/3f0de3de-2340c532c00395db.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/{3031-85328a92fcce4da6.js → 4199-f7c6eb40cd0322f8.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +32 -0
  57. package/apps/pwa/out/_next/static/chunks/4804.6012b5cd33c22792.js +90 -0
  58. package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +79 -0
  60. package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +74 -0
  63. package/apps/pwa/out/_next/static/chunks/5041-5aada92ca215ffdd.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{528.38ce20ef8aa251ff.js → 5203.51e5d8b5f1dcfe53.js} +16 -16
  65. package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5255-1b60d50eabe9f057.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +286 -0
  68. package/apps/pwa/out/_next/static/chunks/5300.677c97e0393742e6.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{2683.c9773a0c589b031b.js → 5307.d7328020227880c2.js} +4 -4
  70. package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +8 -0
  73. package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{552.b7d061ad91eeac51.js → 5638.107314dc479e2f37.js} +2 -2
  75. package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6142.913b44e260a3f925.js +64 -0
  80. package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/{6925.562d532110879886.js → 6493.27ad77de7aac7966.js} +1 -1
  84. package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7000.28157393caaf5343.js +62 -0
  88. package/apps/pwa/out/_next/static/chunks/{275-02ea4c2a33980422.js → 7161-8f22db3ec5ed005e.js} +3 -3
  89. package/apps/pwa/out/_next/static/chunks/7311-60a7ea80d23c7521.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{3136.30aaaa5fa03662a3.js → 7488.966b116789f3d41a.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/{4116.a84a92a2492c080e.js → 7524.ce973525d30b3d52.js} +1 -1
  94. package/apps/pwa/out/_next/static/chunks/7573.2376e13c9c21f1f8.js +77 -0
  95. package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{3324.a09703033abcbd2f.js → 7628.6b16863ac3972333.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{3410.7f9af5ab77cbe65f.js → 7954.4f7a8832663ee979.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/{771.c3cdb6c1f7f47c02.js → 8019.21ca554a821dad01.js} +16 -16
  102. package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{4615.8525eb0add35eba6.js → 8487.291666583bebe640.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/8509.3a54d4e61893d7cb.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{6943.c6b24124853a47b2.js → 8879.ac06755bcf3e44a1.js} +1 -1
  110. package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +149 -0
  111. package/apps/pwa/out/_next/static/chunks/{575.d929793a53f27c4b.js → 8911.bf5e712acb25fb6c.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/{9f31e478.fefcbcd3c388ebc5.js → 8994d93e.33ba491f95345fc2.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/{da5ecc5c-b005ad8cac737d57.js → 89d6c04f-6b8ab341748e468a.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{599.c39c571b6733f2a2.js → 9223.cbcc88e0e9950426.js} +2 -2
  115. package/apps/pwa/out/_next/static/chunks/9299.24e2a7d9b6d1f91b.js +226 -0
  116. package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +24 -0
  117. package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{8037.e254fd797aa224d1.js → 9581.da63ddf41acfad46.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +2 -0
  121. package/apps/pwa/out/_next/static/chunks/{ceba0382.650712b56b85b582.js → 9fe1b809.738da85c8b17e3fb.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-866aac5ff226a7f3.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-c348a3959c5b5fc6.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d1d1210f99f620ae.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/{page-e7abc34a48a6f71e.js → page-291ab19fe2acb173.js} +1 -1
  153. package/apps/pwa/out/_next/static/chunks/app/page-7f569e533ddeecba.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a9d9a3e66459c1e0.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-c15958835534404b.js → page-6b140f77593576eb.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{3a3d9966.cc4d4585a2708e7c.js → b7459770.6539b11860eb8a9c.js} +7 -7
  174. package/apps/pwa/out/_next/static/chunks/{053a429e.9a63436527cc751c.js → b7478fef.5917716286213fcc.js} +3 -3
  175. package/apps/pwa/out/_next/static/chunks/bb6987f9.3647e1a23b0e3217.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/{2812ca6a.3b9f4a7a08885744.js → de8b930d.d94c0f42acf807fc.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{873d6c12.09bd499f57171543.js → eaad0cba.771200940c529df7.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-4b12a946f352cee2.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b5d88eba78a3d7bf.css → be9019f696217521.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/graphs/drafts/recipes.yaml +27 -7
  279. package/graphs/release/recipes.yaml +9 -0
  280. package/graphs/release/release-loop.yaml +26 -18
  281. package/graphs/work/draft-close.yaml +54 -0
  282. package/graphs/work/green-close.yaml +37 -0
  283. package/graphs/work/recipes.yaml +46 -1
  284. package/graphs/work/run-research.yaml +35 -0
  285. package/package.json +1 -1
  286. package/scripts/__fixtures__/authoring-paths-10x3.json +32 -0
  287. package/scripts/ask-op-inbox-once.ts +17 -0
  288. package/scripts/boundary-proof-mapping-audit.ts +88 -0
  289. package/scripts/brand/check.ts +13 -4
  290. package/scripts/codex-fallback-live-probe.ts +17 -15
  291. package/scripts/fleet/node-setup.sh +32 -2
  292. package/scripts/fleet/run-light-worker.sh +9 -0
  293. package/scripts/gate-0226-accepted-remaining-90.txt +91 -0
  294. package/scripts/gate-0226-failure-census.ts +546 -0
  295. package/scripts/goals/authoring-metrics.ts +258 -0
  296. package/scripts/graph-units/draft-close-node.ts +222 -0
  297. package/scripts/hook-order-sweep.ts +7 -4
  298. package/scripts/intake-collect-telegram-saved-stage.ts +48 -0
  299. package/scripts/land-global-checks.ts +69 -1
  300. package/scripts/measure-nl-routing-corpus.ts +207 -2
  301. package/scripts/provision-export-redactions.ts +15 -0
  302. package/scripts/public-copy-lint.ts +122 -0
  303. package/scripts/public-export.ts +69 -2
  304. package/scripts/ratchets/next-tui-entry-budget.ts +124 -0
  305. package/scripts/ratchets/train-side-invariants.sh +7 -1
  306. package/scripts/release-loop/cut-branch.ts +61 -12
  307. package/scripts/release-loop/docs-node.ts +140 -0
  308. package/scripts/release-loop/gate-closure.ts +48 -0
  309. package/scripts/release-loop/gate-diff.ts +2 -1
  310. package/scripts/release-loop/gate-node.ts +161 -25
  311. package/scripts/release-loop/gate-partial.ts +82 -3
  312. package/scripts/release-loop/gate-prewarm-plan.ts +35 -0
  313. package/scripts/release-loop/gate-radius-live.ts +4 -2
  314. package/scripts/release-loop/known-issues-node.ts +6 -4
  315. package/scripts/release-loop/notes-repair.ts +216 -0
  316. package/scripts/release-loop/prepare-node.ts +61 -5
  317. package/scripts/release-loop/resume-cap.ts +2 -1
  318. package/scripts/release-loop/resume-release.ts +406 -7
  319. package/scripts/release-loop/resume-test-traffic.ts +10 -0
  320. package/scripts/release-loop/resume.ts +13 -5
  321. package/scripts/release-loop/traffic-node.ts +12 -4
  322. package/scripts/release-loop/traffic-transition.ts +53 -13
  323. package/scripts/release-loop/version-node.ts +109 -15
  324. package/scripts/train/green-leg.ts +176 -0
  325. package/scripts/tui-continue-real-evidence.ts +47 -0
  326. package/scripts/ux-sim.ts +1 -1
  327. package/scripts/video-pipeline.ts +2 -2
  328. package/src/acp/client.ts +31 -5
  329. package/src/acp/core-turn-bridge.ts +12 -1
  330. package/src/acp/stderr-summary.ts +49 -0
  331. package/src/agent/monad-agent-turn.ts +1 -0
  332. package/src/agent/run-context.ts +1 -1
  333. package/src/agent/task-notification.ts +3 -1
  334. package/src/agent/terminal-surface.ts +217 -0
  335. package/src/agent-substrate/pr-reviewer.ts +11 -3
  336. package/src/agent-substrate/review-observation.ts +10 -0
  337. package/src/agent-substrate/self-review-cli.ts +537 -57
  338. package/src/auto-research/question-ladder-contract.ts +137 -0
  339. package/src/auto-research/research-turn.ts +134 -0
  340. package/src/autopilot/discovery/doc-lint.ts +1 -1
  341. package/src/autopilot/lineage/sources.ts +1 -1
  342. package/src/autopilot/pr-manager.ts +64 -13
  343. package/src/boot/daemon-runtime.ts +35 -3
  344. package/src/boot/daemon-tools/pty-shell.ts +2 -1
  345. package/src/bots/screen-probe.ts +1 -1
  346. package/src/budget/run-usage-rollup.ts +12 -7
  347. package/src/budget/unified-usage.ts +20 -0
  348. package/src/capture/tui-self-report.ts +42 -5
  349. package/src/chat/index.ts +1 -0
  350. package/src/chat/tool-render/dispatch.ts +8 -1
  351. package/src/cli/autopilot-cli.ts +24 -9
  352. package/src/cli/decisions-cli.ts +7 -4
  353. package/src/cli/doctor-cli.ts +116 -7
  354. package/src/cli/guardian-cli.ts +3 -1
  355. package/src/cli/intake-cli.ts +48 -12
  356. package/src/cli/lesson-cli.ts +69 -9
  357. package/src/cli/logs-cli.ts +357 -2
  358. package/src/cli/memory-cli.ts +30 -1
  359. package/src/cli/msg-cli.ts +15 -11
  360. package/src/cli/pr-granularity.ts +5 -3
  361. package/src/cli/pr-land-overlap-evidence.ts +38 -5
  362. package/src/cli/pr-land-refusal.ts +1 -1
  363. package/src/cli/pty-takeover-cli.ts +58 -5
  364. package/src/cli/release-checklist-read-cli.ts +112 -4
  365. package/src/cli/release-cli.ts +89 -18
  366. package/src/cli/review-carry.ts +77 -0
  367. package/src/cli/self-update.ts +24 -6
  368. package/src/cli/self-utterances-cli.ts +13 -16
  369. package/src/cli/tasks-card-show.ts +31 -1
  370. package/src/cli/tasks-cli.ts +370 -33
  371. package/src/cli/tasks-read-cli.ts +13 -5
  372. package/src/cli/usage-cli.ts +12 -10
  373. package/src/context-bus/claude-memory-import.ts +99 -0
  374. package/src/context-bus/context-now.ts +86 -2
  375. package/src/context-bus/long-term-memory.ts +125 -0
  376. package/src/core-turn/run-core-turn.ts +9 -2
  377. package/src/core-turn/run-goal-loop.ts +5 -2
  378. package/src/core-turn/types.ts +5 -0
  379. package/src/dashboard/chat/acp-chat.ts +9 -0
  380. package/src/dashboard/index.ts +115 -30
  381. package/src/dashboard/input/agent-wake.ts +43 -0
  382. package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
  383. package/src/dashboard/input/terminal-modal-router.ts +8 -159
  384. package/src/dashboard/replay-preview.ts +25 -0
  385. package/src/dashboard/side-basic-runtime.ts +61 -0
  386. package/src/dashboard/slash-runtime/dashboard-handlers.ts +19 -8
  387. package/src/dashboard/synchronized-frame-output.ts +74 -0
  388. package/src/dashboard/term-slash-runtime.ts +2 -0
  389. package/src/dashboard/turn-preamble.ts +28 -4
  390. package/src/display/coordinator.ts +45 -12
  391. package/src/display/resize-listener.ts +41 -20
  392. package/src/display/synchronized-output-region.ts +60 -0
  393. package/src/domains/guardian-tick.ts +9 -0
  394. package/src/domains/surface-events.ts +80 -1
  395. package/src/exec-requests/planner.ts +37 -2
  396. package/src/execution-loop/launch-gate.ts +4 -3
  397. package/src/git-fs/cli-stderr.ts +45 -0
  398. package/src/git-fs/gh-cli.ts +6 -3
  399. package/src/git-fs/git-cli.ts +11 -5
  400. package/src/git-fs/watcher.ts +27 -22
  401. package/src/git-fs/worktree.ts +19 -3
  402. package/src/graph-runner/graph-cli.ts +26 -2
  403. package/src/graph-runner/graph-grow.ts +37 -9
  404. package/src/graph-runner/graph-run-api.ts +3 -2
  405. package/src/graph-runner/runner.ts +34 -7
  406. package/src/graph-wizard/generate.ts +29 -6
  407. package/src/grok/credential.ts +107 -36
  408. package/src/harness/harness-cli-command.ts +179 -33
  409. package/src/harness/review-adapter.ts +26 -6
  410. package/src/hq/fence-wrapper.ts +1 -1
  411. package/src/hq/transfer.ts +1 -1
  412. package/src/index.ts +151 -18
  413. package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
  414. package/src/intake-plane/collect-telegram-saved.ts +54 -5
  415. package/src/interactive-terminal-modal.ts +3 -0
  416. package/src/keybindings.ts +17 -22
  417. package/src/llm/provider-credentials.ts +1 -1
  418. package/src/llm/route-decision.ts +13 -0
  419. package/src/llm-tool-name.ts +37 -0
  420. package/src/llm-tool-schema.ts +55 -0
  421. package/src/llm.ts +203 -21
  422. package/src/loops/checker.ts +100 -0
  423. package/src/loops/consensus.ts +26 -2
  424. package/src/loops/loop-cli.ts +9 -4
  425. package/src/loops/orchestrator/anomaly-cluster.ts +243 -0
  426. package/src/loops/orchestrator/inbox-once.ts +28 -0
  427. package/src/loops/orchestrator/inbox.ts +130 -1
  428. package/src/loops/orchestrator/tick.ts +55 -7
  429. package/src/maturity/feature-maturity.ts +1 -0
  430. package/src/model-tier/llm-tier-map.ts +12 -17
  431. package/src/msg/msg-store.ts +17 -0
  432. package/src/native-tool-catalog.ts +1 -1
  433. package/src/nexus/api/channel-ask-op.ts +96 -0
  434. package/src/nexus/api/discord-trigger-bot.ts +28 -1
  435. package/src/nexus/api/graph-wizard-api.ts +27 -2
  436. package/src/nexus/api/grid.ts +24 -4
  437. package/src/nexus/api/http-server.ts +1 -1
  438. package/src/nexus/api/ops-api.ts +14 -6
  439. package/src/nexus/api/telegram-trigger-bot.ts +24 -0
  440. package/src/nexus/api/terminals.ts +28 -6
  441. package/src/nexus/state/state.ts +7 -1
  442. package/src/oauth/codex-account-store.ts +34 -1
  443. package/src/ops/loops-map.ts +46 -0
  444. package/src/ops/overview-cache.ts +22 -4
  445. package/src/ops/overview.ts +41 -5
  446. package/src/patents/ledger.ts +18 -1
  447. package/src/policy/llm-policy.ts +3 -1
  448. package/src/preview/terminal.ts +4 -2
  449. package/src/prompt-cache/anthropic.ts +2 -0
  450. package/src/prompt-enhance/enhance.ts +9 -4
  451. package/src/pty-shell/availability.ts +7 -0
  452. package/src/pty-shell/herdr-agent-report.ts +40 -31
  453. package/src/pty-shell/herdr-prune-stale.ts +17 -0
  454. package/src/pty-shell/herdr-sequence-lease.ts +60 -0
  455. package/src/pty-shell/pty-control-ipc.ts +187 -18
  456. package/src/pty-shell/pty-manifest.ts +16 -2
  457. package/src/pty-shell/registry.ts +25 -15
  458. package/src/pty-shell/tui-run-state.ts +235 -1
  459. package/src/release-loop/checklist.ts +50 -5
  460. package/src/release-loop/feature-store.ts +9 -9
  461. package/src/release-loop/gate-shards.ts +61 -0
  462. package/src/release-loop/landed-but-yellow.ts +93 -12
  463. package/src/release-loop/light-rc.ts +7 -4
  464. package/src/release-loop/rehearsal.ts +1 -1
  465. package/src/repl/index.ts +18 -0
  466. package/src/research/axis-fanout.ts +133 -0
  467. package/src/research/edge-decision.ts +88 -0
  468. package/src/research/output-router.ts +127 -0
  469. package/src/research-bridge/format.ts +16 -1
  470. package/src/research-bridge/index.ts +1 -0
  471. package/src/research-bridge/invoke.ts +41 -5
  472. package/src/seat-loop/seat-report.ts +1 -0
  473. package/src/self-dev/ask-launch-flow.ts +86 -10
  474. package/src/self-dev/decompose-proposal.ts +29 -18
  475. package/src/self-dev/decompose.ts +45 -9
  476. package/src/self-dev/dev-pipeline.ts +29 -7
  477. package/src/self-dev/draft-residue.ts +221 -2
  478. package/src/self-dev/draft-sweep.ts +254 -16
  479. package/src/self-dev/draft-triage-rules.ts +19 -5
  480. package/src/self-dev/orchestrate.ts +1 -0
  481. package/src/self-dev/review-provider-fallback.ts +45 -7
  482. package/src/self-dev/run-supervisor.ts +22 -7
  483. package/src/self-dev/shard-plan.ts +48 -0
  484. package/src/self-dev/shard-run.ts +310 -6
  485. package/src/self-implement/comment-only-source.ts +54 -0
  486. package/src/self-implement/doctor-visit.ts +108 -0
  487. package/src/self-implement/gate-artifacts.ts +6 -2
  488. package/src/self-implement/gate-baseline.ts +99 -1
  489. package/src/self-implement/gate-cli.ts +231 -82
  490. package/src/self-implement/gate-failure-signature.ts +44 -0
  491. package/src/self-implement/gate-remote.ts +30 -4
  492. package/src/self-implement/gate-scope.ts +13 -1
  493. package/src/self-implement/goal-author.ts +407 -21
  494. package/src/self-implement/goal-doc/section.ts +22 -0
  495. package/src/self-implement/goal-supervisor-fill.ts +110 -27
  496. package/src/self-implement/importer-test-index.ts +215 -2
  497. package/src/self-implement/knowhow-pack.ts +125 -12
  498. package/src/self-implement/l8-merge-queue.ts +198 -32
  499. package/src/self-implement/off-diff-evidence.ts +23 -0
  500. package/src/self-implement/orchestrator.ts +369 -33
  501. package/src/self-implement/pod-inplace-worktree.ts +82 -0
  502. package/src/self-implement/pod-warm-pool-profile.ts +2 -2
  503. package/src/self-implement/premise-review.ts +7 -5
  504. package/src/self-implement/review-round-brief.ts +300 -0
  505. package/src/self-implement/rework-policy.ts +14 -0
  506. package/src/self-implement/run-ledger.ts +428 -6
  507. package/src/self-implement/run-stop.ts +1 -1
  508. package/src/self-implement/running-runs.ts +17 -3
  509. package/src/self-implement/seams.ts +45 -16
  510. package/src/self-implement/self-implement-cli.ts +26 -2
  511. package/src/self-implement/stop-autoheal.ts +1 -0
  512. package/src/self-implement/test-seams.ts +13 -1
  513. package/src/self-implement/train-reach-grouping.ts +8 -2
  514. package/src/session/channel-ask-op-envelope.ts +36 -0
  515. package/src/session/channel-op-reply-route.ts +200 -0
  516. package/src/session/chat.ts +10 -1
  517. package/src/session/id-prefix.ts +60 -0
  518. package/src/session/index.ts +6 -0
  519. package/src/session-runtime/index.ts +18 -23
  520. package/src/skills/runner.ts +7 -3
  521. package/src/skills/tools/dev-harness.ts +2 -2
  522. package/src/skills/tools/pty.ts +5 -0
  523. package/src/skills/tools/schedule-wakeup.ts +1 -6
  524. package/src/status/bar.ts +3 -3
  525. package/src/status/metrics.ts +12 -1
  526. package/src/steward/rejudge-tick.ts +12 -5
  527. package/src/steward/resync-tick.ts +31 -4
  528. package/src/storage/file-lock.ts +17 -4
  529. package/src/task-agent/actions.ts +199 -4
  530. package/src/task-agent/adopt-pr.ts +63 -2
  531. package/src/task-agent/boundary-proof-mapping.ts +12 -0
  532. package/src/task-agent/boundary-proof-producer.ts +147 -0
  533. package/src/task-agent/completion-evidence.ts +2 -1
  534. package/src/task-agent/evidence-command-normalize.ts +42 -0
  535. package/src/task-agent/export-redactions-provision.ts +43 -0
  536. package/src/task-agent/green-close-recipe.ts +239 -0
  537. package/src/task-agent/green-sweep.ts +64 -10
  538. package/src/task-agent/live-moves.ts +48 -3
  539. package/src/task-agent/map-host-adapter.ts +134 -0
  540. package/src/task-agent/map-reduce.ts +158 -0
  541. package/src/task-agent/map-run-ledger.ts +226 -0
  542. package/src/task-agent/parent-host.ts +74 -17
  543. package/src/task-agent/rejudge-on-head.ts +72 -5
  544. package/src/task-agent/repair-cycle.ts +108 -8
  545. package/src/task-agent/repair-next-move.ts +12 -2
  546. package/src/task-agent/repair-worker.ts +37 -1
  547. package/src/task-agent/review-prior-fix.ts +12 -2
  548. package/src/task-agent/shadow.ts +188 -5
  549. package/src/task-agent/task-hand.ts +253 -20
  550. package/src/task-agent/task-parent-role-llm.ts +9 -0
  551. package/src/task-agent/tier-split.ts +40 -5
  552. package/src/task-agent/work-order.ts +53 -2
  553. package/src/task-orchestrator/dispatcher.ts +46 -1
  554. package/src/task-orchestrator/generator-prompt.ts +6 -0
  555. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +16 -6
  556. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +31 -4
  557. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +8 -6
  558. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +97 -0
  559. package/src/task-orchestrator/surfaces/pod-pool.ts +77 -8
  560. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +15 -9
  561. package/src/task-orchestrator/surfaces/self-implement-pod.ts +338 -79
  562. package/src/task-orchestrator/surfaces/self-implement.ts +37 -2
  563. package/src/terminal/session-registry.ts +1 -0
  564. package/src/terminal/terminal-modal-router.ts +156 -0
  565. package/src/testing/linux-env.ts +177 -0
  566. package/src/tool-hints/gate.ts +6 -4
  567. package/src/tool-hints/signals.ts +33 -1
  568. package/src/tui/chat/background-job-status.ts +8 -2
  569. package/src/tui/chat/goal-interim.ts +5 -1
  570. package/src/tui/entry.ts +722 -30
  571. package/src/tui/input/at-picker.ts +55 -0
  572. package/src/tui/sidetab/attach.ts +304 -0
  573. package/src/tui/sidetab/list.ts +176 -0
  574. package/src/tui/sidetab/nl-tool.ts +136 -0
  575. package/src/tui/slash/resume-command.ts +23 -0
  576. package/src/tui/slash/resume.ts +38 -35
  577. package/src/tui/slash/signals.ts +114 -0
  578. package/src/tui/slash/term-next.ts +72 -0
  579. package/src/tui-client/local-chat-turn.ts +31 -9
  580. package/src/user-config.ts +30 -3
  581. package/src/ux-sim/boot-daemon-tools-pty-shell-device.ts +136 -0
  582. package/src/ux-sim/classic-tui-seat-scenarios.ts +158 -4
  583. package/src/ux-sim/fake-gh.ts +174 -0
  584. package/src/ux-sim/fake-kubectl.ts +142 -0
  585. package/src/ux-sim/fake-llm.ts +17 -6
  586. package/src/ux-sim/next-tui-seat-scenarios.ts +176 -6
  587. package/src/ux-sim/resume-picker-device.ts +173 -0
  588. package/src/ux-sim/session-id-seed.ts +60 -0
  589. package/src/ux-sim/skills-tools-shell-device.ts +156 -0
  590. package/src/ux-sim/task-agent-parent-host-device.ts +264 -0
  591. package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
  592. package/src/version/packed-revision.json +1 -1
  593. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +0 -287
  594. package/apps/pwa/out/_next/static/chunks/1201.afbfc5b1c5e5cbe4.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +0 -64
  600. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +0 -36
  601. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +0 -149
  604. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/2500.cbc1257b774aae52.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +0 -24
  609. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +0 -24
  612. package/apps/pwa/out/_next/static/chunks/2986.45d7652e4f13557e.js +0 -2
  613. package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +0 -226
  614. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +0 -8
  618. package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +0 -32
  619. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +0 -286
  621. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/3757-180308bc61021b05.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +0 -74
  625. package/apps/pwa/out/_next/static/chunks/3840-5825d56d46976a92.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +0 -104
  629. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +0 -148
  632. package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +0 -93
  634. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +0 -122
  636. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +0 -79
  641. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +0 -27
  653. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/7481.39f7a4654907bf6e.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/7891.03f910124a737985.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +0 -62
  664. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +0 -90
  666. package/apps/pwa/out/_next/static/chunks/914.8abefd48d579547b.js +0 -94
  667. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +0 -77
  672. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/9514.131c52cc75fe6439.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/9789.60f723d18097ec30.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/ccae1c4b-0cf414f5eff1b10d.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +0 -1
  739. package/scripts/migrate-monad-to-elanous.ts +0 -195
  740. package/scripts/rebrand-elanous.ts +0 -242
  741. /package/apps/pwa/out/_next/static/{uC-N0emedeNOFuaBQFv-I → RrjXTwz-urRAbChP1bX02}/_ssgManifest.js +0 -0
@@ -39,16 +39,35 @@ import { createTuiScreenMirror } from './tui-screen-mirror.js';
39
39
  import { getChannelBus } from '../terminal-matrix/index.js';
40
40
  import { publishSelfReportFrame } from './self-report-frame.js';
41
41
  import {
42
- upsertPtyManifest, updatePtyManifestFrame, touchLivePtyManifest, markPtyManifestClosed, removePtyManifest, getPtyManifest,
42
+ upsertPtyManifest, updatePtyManifestFrame, updatePtyManifestSession, touchLivePtyManifest, markPtyManifestClosed, removePtyManifest, getPtyManifest,
43
43
  updatePtyManifestBuild,
44
44
  } from '../pty-shell/pty-manifest.js';
45
45
  import { writeHarnessScreen } from '../harness/harness-screen.js';
46
46
  import { runningBuild, startTuiRunStateRecorder } from '../pty-shell/tui-run-state.js';
47
+ import type { TuiSelfRestartDeps } from '../pty-shell/tui-run-state.js';
48
+ import { lastHumanKeyAt } from '../tui.js';
47
49
  import { debug } from '../debug/log.js';
48
50
  import { setTuiLogName, setTuiLogSession } from '../debug/tui-log-tag.js';
49
51
  import { getActiveSessionId } from '../session/index.js';
50
52
  import { routeExternalInput, type ExternalInputRoute } from '../input/external-input-queue.js';
51
53
 
54
+ /**
55
+ * 사람 손이 «아직 떠난 것으로 안 본» 조용창 — 마지막 사람 키가 이 창 안이면 입력 중으로 친다.
56
+ * 유휴 임계(H9 기본 90초)보다 길게 잡아 «방금 만지던 사람» 을 절대 끊지 않는다.
57
+ */
58
+ const SELF_RESTART_HUMAN_QUIET_MS = 10 * 60_000;
59
+
60
+ /** 실제 TUI 가 쓰는 H9 신호: 낡음=기동 판⊕설치본⊕HEAD · 사람 입력=마지막 사람 키 · 세션=지금 대화. */
61
+ export function productionTuiSelfRestart(readSessionId: () => string | null): TuiSelfRestartDeps {
62
+ return {
63
+ humanInputPending: () => {
64
+ const last = lastHumanKeyAt();
65
+ return last > 0 && Date.now() - last < SELF_RESTART_HUMAN_QUIET_MS;
66
+ },
67
+ readSessionId,
68
+ };
69
+ }
70
+
52
71
  export interface TuiFrameObserverCfg {
53
72
  surfaceId: string;
54
73
  instance: string;
@@ -279,6 +298,9 @@ export interface TuiSelfReportDeps {
279
298
  reportControlCleanupFailure?: (stage: TuiControlCleanupStage, error: unknown) => void;
280
299
  /** 행 등록 직후 실행 판 ⊕ 턴(idle) 기록을 연다 — `elanous pty state` 가 읽는다. 반환 = 정리. */
281
300
  startRunState?: (surfaceId: string) => (() => void);
301
+ /** 자기 재기동 신호(TUI-H9)를 갈아 끼운다 — 기본 = 실 신호(`lastHumanKeyAt` ⊕ `getActiveSessionId`).
302
+ * 시험은 가짜 시계·가짜 restart 로 판정선을 증명한다. */
303
+ selfRestart?: TuiSelfRestartDeps | null;
282
304
  /** 미룬 우편 깨움 폴러(TUI-H4)를 연다 — 반환 = 정리. 기본은 실 행 등록과 짝일 때만 늦게 불러온 `startPendingWakePoller`. */
283
305
  startWakePoller?: (surfaceId: string) => (() => void);
284
306
  /** 박동마다 자기 행을 본다 — 없으면 null · ⛔ 조회 실패는 «던진다»(없다로 읽지 않는다). 기본 = `getPtyManifest(id, { strict })`. */
@@ -399,9 +421,18 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
399
421
  return () => {};
400
422
  }
401
423
  const activeControlTarget = controlTarget;
424
+ const readActiveSessionId: () => string | null = deps.readActiveSessionId
425
+ ?? (() => { try { return getActiveSessionId(); } catch { return null; } });
402
426
  let stopRunState: () => void = () => {};
403
427
  // 행 등록을 갈아 끼운 호출자(시험)는 실 manifest 를 안 건드린다 — 기본 녹음기는 기본 행 등록과 짝일 때만.
404
- const startRunState = deps.startRunState ?? (deps.registerRow ? () => () => {} : startTuiRunStateRecorder);
428
+ // TUI-H9: 그 기본 녹음기에 «사람 입력 없음»(마지막 사람 키 입력) ⊕ «지금 대화» 를 실 신호로 주입한다 —
429
+ // judged-stale ∧ idle ∧ 사람 없음 이면 스스로 재기동(새 세션 ⊕ 자리 맥락)한다(자세한 판정선은 startTuiRunStateRecorder).
430
+ const startRunState = deps.startRunState
431
+ ?? (deps.registerRow
432
+ ? () => () => {}
433
+ : (id: string) => startTuiRunStateRecorder(id, {
434
+ selfRestart: deps.selfRestart === null ? undefined : (deps.selfRestart ?? productionTuiSelfRestart(readActiveSessionId)),
435
+ }));
405
436
  try { stopRunState = startRunState(surfaceId); } catch { /* fail-soft — recorder logs its own write failures */ }
406
437
  // 미룬 우편 깨움(TUI-H4) — 이 TUI 가 턴 중·5분 창이라 못 받은 깨움을 idle 로 «기록»된 뒤 한 번 다시 두드린다.
407
438
  // 실 행 등록과 짝일 때만(시험이 행 등록을 갈아 끼우면 0) · 무거운 모듈은 늦게 불러온다.
@@ -437,7 +468,15 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
437
468
  lastEmittedText = text;
438
469
  // TUI-H9 — 이 프레임이 «지금 이 TUI 가 보여 주는 대화» 의 소유 기록이다. 재기동은 이 id 로만 잇는다
439
470
  // (읽기 실패 → 소유 없음 → 재기동 막힘 · 다른 세션으로 대체하지 않는다).
440
- try { claimTuiOwnedSession(readActiveSessionId(), at); } catch { claimTuiOwnedSession(null, at); }
471
+ let sessionId: string | null = null;
472
+ try {
473
+ sessionId = readActiveSessionId();
474
+ claimTuiOwnedSession(sessionId, at);
475
+ } catch {
476
+ sessionId = null;
477
+ claimTuiOwnedSession(null, at);
478
+ }
479
+ try { updatePtyManifestSession(surfaceId, sessionId ?? '', at); } catch { /* fail-soft */ }
441
480
  const frame: SelfReportFrame = { surfaceId, instance, kind: 'tui', mode: 'self-report', text, cols, rows, at, ...(runId ? { runId } : {}) };
442
481
  try { publishFrame(frame); } catch { /* fail-soft */ }
443
482
  // `at` is shared with the manifest write → its internal throttle keys
@@ -491,8 +530,6 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
491
530
  ?? (deps.registerRow ? () => ({ alive: true }) : (id: string) => getPtyManifest(id, { strict: true }));
492
531
  const restoreBuild = deps.restoreBuild ?? (deps.registerRow ? () => {} : (id: string) => { updatePtyManifestBuild(id, runningBuild()); });
493
532
  const logRowMissing = deps.logRowMissing ?? ((data: TuiRowMissingEvent) => debug.log('tui.self-report', 'row-missing', data));
494
- const readActiveSessionId: () => string | null = deps.readActiveSessionId
495
- ?? (() => { try { return getActiveSessionId(); } catch { return null; } });
496
533
  const rowNickname = deps.nickname?.trim() || undefined;
497
534
  let lastSeenAt = now();
498
535
  let lastBeatAt = lastSeenAt;
package/src/chat/index.ts CHANGED
@@ -514,6 +514,7 @@ export const SLASH_COMMANDS: SlashCommand[] = [
514
514
  { name: 'tablet', aliases: [], description: 'Tablet mode — collapse layout to log + input', subcommands: ['on', 'off', 'toggle', 'auto', 'status', 'browser-preview', 'bp'] },
515
515
  { name: 'surface', aliases: [], description: 'Surface control — open a pane/catalog launcher (/surface catalog · browser · preview · log · scratch · obsidian · skill) OR set a preferred LLM surface (/surface coding-agent · research-agent · control-agent · ops-agent · … · clear · status)', subcommands: ['catalog', 'browser', 'preview', 'browser-preview', 'log', 'scratch', 'obsidian', 'skill', 'skill-file', 'agents', 'coding-agent', 'coding-chat', 'research-agent', 'research-chat', 'control-agent', 'ops-ui-agent', 'ops-fleet-agent', 'ops-agent', 'clear', 'status'] },
516
516
  { name: 'term', aliases: ['terminal'], description: 'Interactive terminal modal — new / list / attach / detach / switch / kill / snapshot / resume', subcommands: ['new', 'list', 'attach', 'detach', 'switch', 'kill', 'snapshot', 'resume'] },
517
+ { name: 'side', aliases: [], description: '사이드탭 기초 — 목록 · 셸 생성 · 번호로 PTY 보기/attach', subcommands: ['list', 'new', 'attach'] },
517
518
  { name: 'claude', aliases: [], description: 'Spawn claude-code CLI in a terminal modal' },
518
519
  { name: 'codex', aliases: [], description: 'Spawn codex CLI in a terminal modal' },
519
520
  { name: 'gemini', aliases: [], description: 'Spawn gemini CLI in a terminal modal' },
@@ -89,7 +89,7 @@ export function renderToolResultVariants(
89
89
  // Only successful MsgPost results enter the compact renderer. Returning
90
90
  // null for errors lets the dashboard formatter use its existing generic
91
91
  // result path, including its expanded argument/result view.
92
- if (kind === 'MsgPost' && extractErrorText(call.result)) return null;
92
+ if (kind === 'MsgPost' && isMsgPostErrorResult(call.result)) return null;
93
93
  const model = buildToolRenderModel(kind, call, config);
94
94
  const collapsed = renderToolBlock(model, config.blockMaxLines, config.foldMode, config.expandHint);
95
95
  // ⭐ MsgPost 는 접힌 행에서 본문을 빼고 펼친 행에서만 싣는다 ⇒ 같은 model 로는 두 변형을
@@ -113,6 +113,13 @@ interface ToolRenderModelOptions {
113
113
  includeMsgPostBody?: boolean;
114
114
  }
115
115
 
116
+ /** MsgPost 오류 — `llm.ts` 가 throw 를 `{ error }` 로 감싼 형태와, `ok: false` 결과. */
117
+ function isMsgPostErrorResult(result: unknown): boolean {
118
+ if (extractErrorText(result)) return true;
119
+ const rec = asRecord(result);
120
+ return rec?.ok === false;
121
+ }
122
+
116
123
  function normalizeToolRenderName(name: string): ToolRenderKind | null {
117
124
  if (name === 'update_plan' || name === 'UpdatePlan') return 'UpdatePlan';
118
125
  if (name === 'update_goal' || name === 'UpdateGoal') return 'UpdateGoal';
@@ -9,6 +9,8 @@ import { writeStdoutJson } from './stdout-json.js';
9
9
  export interface AutopilotCliDeps {
10
10
  /** logs.db 싱크 등록(시험 주입). 기본 = `registerStandaloneLogSink`. `task-agent-action` 이 부른다. */
11
11
  registerSink?: (surface: string) => Promise<unknown>;
12
+ /** Deterministic action execution ports for isolated dispatcher tests. */
13
+ actionDeps?: Pick<import('../task-agent/actions.js').ActionDeps, 'mode' | 'command' | 'observe'>;
12
14
  }
13
15
 
14
16
  export function registerAutopilotCommands(program: Command, cliDeps: AutopilotCliDeps = {}): void {
@@ -22,7 +24,7 @@ export function registerAutopilotCommands(program: Command, cliDeps: AutopilotCl
22
24
  // 독립 프로세스 — 싱크를 붙이지 않으면 `task-agent`/`action` 관측이 logs.db 에 안 닿는다(fail-open).
23
25
  const { registerTaskAgentSink } = await import('./tasks-cli.js');
24
26
  await registerTaskAgentSink(cliDeps.registerSink);
25
- const { executeNextAction } = await import('../task-agent/actions.js');
27
+ const { executeEntranceTick, executeNextAction } = await import('../task-agent/actions.js');
26
28
  const { getUserConfig } = await import('../user-config.js');
27
29
  const { spawnSync } = await import('node:child_process');
28
30
  const { writeFileSync, mkdirSync } = await import('node:fs');
@@ -41,15 +43,23 @@ export function registerAutopilotCommands(program: Command, cliDeps: AutopilotCl
41
43
  process.exitCode = 1;
42
44
  return;
43
45
  }
44
- const action = JSON.parse(actionJson) as import('../task-agent/actions.js').NextAction;
46
+ const parsedInput = JSON.parse(actionJson) as import('../task-agent/actions.js').NextAction | import('../task-agent/actions.js').EntranceTickCandidate[];
47
+ const isEntranceTick = Array.isArray(parsedInput);
48
+ const action = isEntranceTick ? parsedInput[0]?.action : parsedInput;
49
+ if (!action) {
50
+ process.stderr.write('task-agent-action: action or non-empty entrance tick is required\n');
51
+ process.exitCode = 1;
52
+ return;
53
+ }
45
54
  const deps: import('../task-agent/actions.js').ActionDeps = {
46
55
  ...state,
56
+ ...cliDeps.actionDeps,
47
57
  failureCounts: state.failureCounts ?? {},
48
58
  saveState: () => {
49
59
  mkdirSync(dirname(statePath), { recursive: true });
50
60
  // 실패 횟수는 incrementFailure 가 잠금 안에서 키별로 더한다 — 여기선 덮어쓰지 않는다.
51
61
  },
52
- mode: config.taskAgent?.mode,
62
+ mode: cliDeps.actionDeps?.mode ?? config.taskAgent?.mode,
53
63
  // 하루 착지 칸은 상태 파일 잠금 안에서 확보·반환한다 — 두 CLI 프로세스가 같은 잔여 칸을 쓰지 않게.
54
64
  reserveLanding: (day, limit) => withFileLockSync(`${statePath}.lock`, () => {
55
65
  const disk = readTaskAgentState<ActionState>(statePath);
@@ -74,18 +84,23 @@ export function registerAutopilotCommands(program: Command, cliDeps: AutopilotCl
74
84
  writeFileSync(statePath, JSON.stringify({ ...disk, landingsToday: disk.landingsToday - 1 }));
75
85
  deps.landingsToday = disk.landingsToday - 1;
76
86
  }),
77
- observe: (_event, data) => debug.log('task-agent', 'action', data),
78
- command: async args => {
87
+ observe: cliDeps.actionDeps?.observe ?? ((_event, data) => debug.log('task-agent', 'action', data)),
88
+ command: cliDeps.actionDeps?.command ?? (async (args, cwd) => {
79
89
  const p = args[0] === 'gh'
80
- // PR 조회는 착지할 작업 트리에서 — 다른 저장소에서 불러도 엉뚱한 PR 을 읽지 않게.
81
- ? spawnSync('gh', args.slice(1), { encoding: 'utf8', ...(action.cwd ? { cwd: action.cwd } : {}) })
90
+ // PR 조회는 해당 후보의 작업 트리에서 — 배열 후보 간 저장소가 섞이지 않게.
91
+ ? spawnSync('gh', args.slice(1), { encoding: 'utf8', ...(cwd ? { cwd } : {}) })
82
92
  // 지금 돌고 있는 진입점으로 부른다 — 저장소 밖(설치본)에서 불러도 같은 elanous 를 쓴다.
83
93
  : spawnSync(process.execPath, [process.argv[1]!, ...(process.argv.includes('--test') ? ['--test'] : []), ...args], { encoding: 'utf8' });
84
94
  return { status: p.status ?? 1, stdout: p.stdout ?? '', stderr: p.stderr ?? '' };
85
- },
95
+ }),
86
96
  };
87
97
  let result: string;
88
- try { result = await executeNextAction(action, deps); } catch (error) {
98
+ try {
99
+ if (isEntranceTick) {
100
+ const results = await executeEntranceTick(parsedInput, deps);
101
+ result = results.join('\n');
102
+ } else result = await executeNextAction(action, deps);
103
+ } catch (error) {
89
104
  // 잠금 안 읽기가 손상을 만나면 쓰지 않고 여기로 온다 — 실패로 끝낸다. 그 밖의 오류는 종전대로 올린다.
90
105
  if (!(error instanceof TaskAgentStateError)) throw error;
91
106
  process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
@@ -64,7 +64,7 @@ export function formatSeatDecisionRow(e: SeatDecisionRecord): string {
64
64
  }
65
65
 
66
66
  export function formatProposalRow(p: ProposalCard): string {
67
- return `${p.id} · ${categoryLabel(p.category)} · ${p.title} · 사실 ${p.factId} · 비용 ${p.cost} · 되돌리기 ${p.undo}${p.thresholds.length ? ` · ${CROWN_MARK} 몫 ${p.thresholds.join('|')}` : ''} · 제안 ${representativeLabel(p.proposedBy)} · ${kst(p.proposedAt)} · 왕복 ${p.roundTrips}/${MAX_REVIEW_ROUND_TRIPS} · ${p.status === 'open' ? '검토 중' : p.status === 'agreed' ? '합의·실행·기록' : '불합의'}`;
67
+ return `${p.id} · ${categoryLabel(p.category)} · ${p.title} · 사실 ${p.factId} · 비용 ${p.cost} · 되돌리기 ${p.undo}${p.thresholds.length ? ` · ${CROWN_MARK} 몫 ${p.thresholds.join('|')}` : ''} · 제안 ${representativeLabel(p.proposedBy)} · ${kst(p.proposedAt)} · 왕복 ${p.roundTrips}/${MAX_REVIEW_ROUND_TRIPS} · ${p.status === 'open' ? '검토 중' : p.status === 'agreed' ? (p.thresholds.length ? '합의·승인 대기' : '합의·실행·기록') : '불합의'}`;
68
68
  }
69
69
 
70
70
  export function formatCrownCardRow(c: CrownCard): string {
@@ -235,14 +235,15 @@ export function registerDecisionsCommands(program: Command, config: DecisionLedg
235
235
  .requiredOption('--category <category>', `합의 범주 (${CONSENSUS_CATEGORIES.join('|')})`)
236
236
  .requiredOption('--title <text>').requiredOption('--fact-id <id>', '사실 id')
237
237
  .requiredOption('--cost <text>', '비용').requiredOption('--undo <text>', '되돌리기')
238
+ .option('--work-key <orch:card:cell>', 'splitter 교차 영향 작업 키')
238
239
  .option('--threshold <category>', `${CROWN_MARK} 몫 임계 범주 (반복: ${CROWN_THRESHOLD_CATEGORIES.join('|')})`, repeat, [])
239
240
  .option('--provider <name>', 'LLM 제공자 표식 — 가능하면 상대와 다른 제공자 (메아리 방지)')
240
241
  .option('--json').option('--hq-override')
241
- .action((o: { by: string; category: string; title: string; factId: string; cost: string; undo: string; threshold: string[]; provider?: string; json?: boolean; hqOverride?: boolean }) => fail(() => {
242
+ .action((o: { by: string; category: string; title: string; factId: string; cost: string; undo: string; workKey?: string; threshold: string[]; provider?: string; json?: boolean; hqOverride?: boolean }) => fail(() => {
242
243
  if (!mayWrite('consensus propose', o.hqOverride)) return;
243
244
  const proposal = consensusEngine().propose({
244
245
  by: o.by as ConsensusRepresentative, category: o.category as ConsensusCategory, title: o.title, factId: o.factId, cost: o.cost, undo: o.undo,
245
- thresholds: o.threshold.map(threshold => threshold as DecisionCategory), provider: o.provider,
246
+ workKey: o.workKey, thresholds: o.threshold.map(threshold => threshold as DecisionCategory), provider: o.provider,
246
247
  });
247
248
  return emit(proposal, o.json, `제안: ${formatProposalRow(proposal)}`);
248
249
  }));
@@ -263,7 +264,9 @@ export function registerDecisionsCommands(program: Command, config: DecisionLedg
263
264
  .option('--json').option('--hq-override')
264
265
  .action((id: string, o: { by: string; claim?: string; provider?: string; json?: boolean; hqOverride?: boolean }) => fail(() => {
265
266
  if (!mayWrite('consensus agree', o.hqOverride)) return;
266
- const { proposal, crownCard } = consensusEngine().agree(id, { by: o.by as ConsensusRepresentative, claim: o.claim, provider: o.provider });
267
+ const consensus = consensusEngine();
268
+ const { proposal, crownCard } = consensus.agree(id, { by: o.by as ConsensusRepresentative, claim: o.claim, provider: o.provider });
269
+ if (!crownCard && !consensus.canExecute(proposal.id)) throw new Error(`합의 실행 관문 거부: ${proposal.id}`);
267
270
  return emit({ proposal, ...(crownCard ? { crownCard } : {}) }, o.json,
268
271
  `합의: ${formatProposalRow(proposal)}${crownCard ? `\n${CROWN_MARK} 카드: ${formatCrownCardRow(crownCard)}` : ''}`);
269
272
  }));
@@ -44,9 +44,11 @@ import {
44
44
  DOCTOR_SYMPTOMS,
45
45
  DOCTOR_VISIT_SOURCES,
46
46
  doctorVisitRunExists,
47
+ doctorReviewVisits,
47
48
  isDoctorSymptom,
48
49
  isDoctorVisitSource,
49
50
  readDoctorVisits,
51
+ readDoctorReviewBrief,
50
52
  recordAutoLongRunVisit,
51
53
  recordDoctorVisit,
52
54
  type DoctorSymptom,
@@ -55,6 +57,8 @@ import { formatHostDoctorLines, runHostDoctor, type HostDoctorExpected, type Hos
55
57
  import { listMachineResources } from './control-cli.js';
56
58
  import type { ResourceView } from '../control-plane/ledger.js';
57
59
  import { loadMachineLedger } from '../machines/machine-ledger.js';
60
+ import { LogStore, logsDbPath, type LogStoreRow } from '../mss/logging/log-store.js';
61
+ import { reviewBriefEvidence } from '../self-implement/review-round-brief.js';
58
62
 
59
63
  function defaultCheckPythonEnv(): { status: 'ok' | 'fixable' | 'manual'; evidence: string; remedy?: string } {
60
64
  const c = checkPythonEnv(false);
@@ -223,10 +227,49 @@ export interface DoctorCliDeps extends DoctorOptions, Pick<DoctorFixDeps, 'home'
223
227
  hostDoctorMachineResources?: () => Promise<ResourceView[]>;
224
228
  /** `doctor visit`/`doctor status` 원장 디렉터리(시험 seam) — 기본 = `runLedgerDir()`. */
225
229
  doctorVisitLedgerDir?: string;
230
+ /** Isolated saved-review and PR metadata seams. */
231
+ reviewResultsDir?: string;
232
+ readReviewBriefPr?: Parameters<typeof readDoctorReviewBrief>[1];
233
+ /** Optional isolated observation transport and status reader for CLI tests. */
234
+ reviewBriefLog?: (event: Record<string, unknown>) => void;
235
+ readReviewBriefEvents?: (runId?: string) => Array<{ timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }>;
226
236
  /** `doctor visit` 사고 선례 연결 루트(시험 seam) — 기본 = `doctorVisitIncidentRoot()` · `null` 이면 건너뛴다. */
227
237
  doctorVisitIncidentRoot?: string | null;
228
238
  /** Deterministic clock for `doctor auto-long-run` isolated CLI tests. */
229
239
  doctorAutoLongRunNow?: () => string;
240
+ /** Standalone logs.db registration seam for the two run-doctor CLI emitters. */
241
+ registerDoctorLogSink?: () => Promise<unknown>;
242
+ /** Flush seam paired with registerDoctorLogSink. */
243
+ flushDoctorLogs?: () => void;
244
+ }
245
+
246
+ export function parseReviewBriefLogData(raw: unknown): Record<string, unknown> {
247
+ let data: unknown;
248
+ try { data = typeof raw === 'string' ? JSON.parse(raw) : raw; }
249
+ catch (error) { throw new Error(`malformed doctor.review/brief-issued event: ${error instanceof Error ? error.message : String(error)}`); }
250
+ if (!data || typeof data !== 'object' || Array.isArray(data)) throw new Error('malformed doctor.review/brief-issued event: expected object data');
251
+ const value = data as Record<string, unknown>;
252
+ if (typeof value.pr !== 'number' || typeof value.head !== 'string' || typeof value.round !== 'number') {
253
+ throw new Error('malformed doctor.review/brief-issued event: required pr/head/round fields are missing');
254
+ }
255
+ return value;
256
+ }
257
+
258
+ function readReviewBriefEventsFromLogs(dbPath = logsDbPath(), runId?: string): Array<{ timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }> {
259
+ if (!existsSync(dbPath)) return [];
260
+ let store: LogStore | undefined;
261
+ try {
262
+ store = LogStore.openReadOnly(dbPath);
263
+ return store.queryAll({ exactCategories: ['doctor.review'], events: ['brief-issued'] }).flatMap((row: LogStoreRow) => {
264
+ const data = parseReviewBriefLogData(row.data);
265
+ const rowRunId = typeof data.runId === 'string' && data.runId ? data.runId : undefined;
266
+ if (runId !== undefined && rowRunId !== runId) return [];
267
+ return [{ timestamp: new Date(row.ts_ms).toISOString(), sequence: row.id, ...(rowRunId ? { runId: rowRunId } : {}), key: String(data.pr), evidence: `PR #${data.pr} head ${data.head.slice(0, 12)} r${data.round} rx=${String(data.rx)}${data.source === 'pr-disposition' ? ' source=pr-disposition' : ''}` }];
268
+ });
269
+ } catch (error) {
270
+ throw new Error(`review event logs could not be read: ${error instanceof Error ? error.message : String(error)}`);
271
+ }
272
+ finally { store?.close(); }
230
273
  }
231
274
 
232
275
  const repositoryRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
@@ -1293,6 +1336,9 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1293
1336
  const out = deps.out ?? { log: (value: string) => console.log(value) };
1294
1337
  const err = deps.err ?? { error: (value: string) => console.error(value) };
1295
1338
  const setExitCode = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
1339
+ const registerDoctorLogSink = deps.registerDoctorLogSink ?? (async () =>
1340
+ (await import('../domains/standalone-log-sink.js')).registerStandaloneLogSink('cli'));
1341
+ const flushDoctorLogs = deps.flushDoctorLogs ?? (() => debug.flush());
1296
1342
  const doctor = program.command('doctor')
1297
1343
  .description('Reports whether credentials resolve and where each resolution comes from')
1298
1344
  .option('--json', 'structured output');
@@ -1358,9 +1404,10 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1358
1404
  .argument('<runId>', 'run id whose ledger receives the visit')
1359
1405
  .requiredOption('--started-at <iso>', 'Pod status.startTime as an ISO timestamp')
1360
1406
  .option('--json', 'structured output')
1361
- .action((runId: string, opts: { startedAt: string; json?: boolean }, command: Command) => {
1407
+ .action(async (runId: string, opts: { startedAt: string; json?: boolean }, command: Command) => {
1362
1408
  const json = opts.json === true || command.parent?.opts().json === true;
1363
1409
  try {
1410
+ await registerDoctorLogSink();
1364
1411
  const result = recordAutoLongRunVisit({ runId, startedAt: opts.startedAt,
1365
1412
  ...(deps.doctorAutoLongRunNow ? { now: deps.doctorAutoLongRunNow() } : {}),
1366
1413
  ...(deps.doctorVisitLedgerDir !== undefined ? { dir: deps.doctorVisitLedgerDir } : {}) });
@@ -1370,6 +1417,8 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1370
1417
  if (json) out.log(JSON.stringify({ status: 'rejected', reason }));
1371
1418
  else err.error(reason);
1372
1419
  setExitCode(1);
1420
+ } finally {
1421
+ flushDoctorLogs();
1373
1422
  }
1374
1423
  });
1375
1424
  doctor.command('visit')
@@ -1379,7 +1428,7 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1379
1428
  .requiredOption('--from <who>', `closed sender list: ${DOCTOR_VISIT_SOURCES.join(', ')}`)
1380
1429
  .option('--evidence <text>', 'free-text evidence recorded with the visit')
1381
1430
  .option('--json', 'structured output')
1382
- .action((runId: string, opts: { symptom: string; from: string; evidence?: string; json?: boolean }, command: Command) => {
1431
+ .action(async (runId: string, opts: { symptom: string; from: string; evidence?: string; json?: boolean }, command: Command) => {
1383
1432
  const json = opts.json === true || command.parent?.opts().json === true;
1384
1433
  if (!isDoctorSymptom(opts.symptom)) {
1385
1434
  const reason = `unknown symptom: ${opts.symptom} — closed list: ${DOCTOR_SYMPTOMS.join(', ')}`;
@@ -1396,6 +1445,7 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1396
1445
  return;
1397
1446
  }
1398
1447
  try {
1448
+ await registerDoctorLogSink();
1399
1449
  const visit = recordDoctorVisit({
1400
1450
  runId,
1401
1451
  from: opts.from,
@@ -1410,6 +1460,54 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1410
1460
  if (json) out.log(JSON.stringify({ status: 'rejected', reason }));
1411
1461
  else err.error(reason);
1412
1462
  setExitCode(1);
1463
+ } finally {
1464
+ flushDoctorLogs();
1465
+ }
1466
+ });
1467
+ doctor.command('review-brief')
1468
+ .description('Build a review-round card from saved reviews for the current PR head')
1469
+ .requiredOption('--pr <number>', 'PR number')
1470
+ .option('--json', 'structured output')
1471
+ .action(async (opts: { pr: string; json?: boolean }, command: Command) => {
1472
+ const json = opts.json === true || command.parent?.opts().json === true;
1473
+ const pr = Number(opts.pr);
1474
+ if (!Number.isSafeInteger(pr) || pr <= 0) {
1475
+ const reason = 'PR number must be a positive integer';
1476
+ if (json) out.log(JSON.stringify({ status: 'rejected', reason })); else err.error(reason);
1477
+ setExitCode(1);
1478
+ return;
1479
+ }
1480
+ try {
1481
+ const brief = readDoctorReviewBrief(pr, deps.readReviewBriefPr, deps.reviewResultsDir);
1482
+ const event = reviewBriefEvidence(brief);
1483
+ const intentBlock = typeof event.intentBlock === 'string' ? event.intentBlock : null;
1484
+ if (deps.reviewBriefLog) deps.reviewBriefLog(event);
1485
+ else {
1486
+ await (await import('../domains/standalone-log-sink.js')).registerStandaloneLogSink('cli');
1487
+ debug.log('doctor.review', 'brief-issued', event);
1488
+ debug.flush();
1489
+ }
1490
+ out.log(json ? JSON.stringify({ ...brief, intentBlock }, null, 2) : [
1491
+ `PR #${pr} · ${brief.status} · rounds=${brief.rounds} · head=${brief.head.slice(0, 12)} · verdict=${brief.reviewedVerdict} · rx=${brief.rx}`,
1492
+ ...(brief.dispositionEvidence ? [`Source: PR author disposition (current head review unmeasured) · ${brief.dispositionEvidence}`] : []),
1493
+ ...(brief.goalQuestion ? [`Original question: ${brief.goalQuestion}`] : []),
1494
+ ...(brief.acceptanceSignal.length ? ['Acceptance signal:', ...brief.acceptanceSignal.map((item) => ` - ${item}`)] : []),
1495
+ `Core items (${brief.coreItems.length}/${brief.totalCoreItems}):`,
1496
+ ...brief.coreItems.map((item) => ` [${item.kind}] ${item.text}`),
1497
+ ...(brief.omittedCoreItems ? [`Core items omitted: ${brief.omittedCoreItems}; source files: ${brief.resultPaths.join(', ')}`] : []),
1498
+ `Prior findings (${brief.priorFindings.length}/${brief.totalPriorFindings}):`, ...brief.priorFindings.map((item) => ` [${item.kind} · ${item.sourceHead.slice(0, 12)}] ${item.text}`),
1499
+ ...(brief.omittedPriorFindings ? [`Prior findings omitted: ${brief.omittedPriorFindings}; source files: ${brief.resultPaths.join(', ')}`] : []),
1500
+ `Scope candidates (${brief.scopeItems.length}/${brief.totalScopeItems}):`, ...brief.scopeItems.map((item) => ` [${item.kind}] ${item.text}`),
1501
+ ...(brief.omittedScopeItems ? [`Scope candidates omitted: ${brief.omittedScopeItems}; source files: ${brief.resultPaths.join(', ')}`] : []),
1502
+ ...(brief.resultPaths.length ? [`Review source files: ${brief.resultPaths.join(', ')}`] : []),
1503
+ `Scope boundary: ${brief.scopeBoundary}`,
1504
+ ...(intentBlock ? ['R3 intent shadow output:', intentBlock] : []),
1505
+ ...(brief.reason ? [`Reason: ${brief.reason}`] : []),
1506
+ ].join('\n'));
1507
+ } catch (error) {
1508
+ const reason = observationError(error);
1509
+ if (json) out.log(JSON.stringify({ status: 'unavailable', pr, reason })); else err.error(reason);
1510
+ setExitCode(1);
1413
1511
  }
1414
1512
  });
1415
1513
  doctor.command('status')
@@ -1427,18 +1525,29 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1427
1525
  return;
1428
1526
  }
1429
1527
  const visits = readDoctorVisits(opts.run, ledgerScope);
1528
+ let reviewEvents: Array<{ timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }>;
1529
+ try {
1530
+ reviewEvents = (deps.readReviewBriefEvents ?? ((runId?: string) => readReviewBriefEventsFromLogs(logsDbPath(), runId)))(opts.run);
1531
+ } catch (error) {
1532
+ const reason = observationError(error);
1533
+ if (json) out.log(JSON.stringify({ status: 'unavailable', reason, recordedVisits: visits }, null, 2));
1534
+ else out.log(`Doctor status unavailable: ${reason}\nRecorded doctor visits: ${visits.length}`);
1535
+ setExitCode(1);
1536
+ return;
1537
+ }
1538
+ const statusVisits = [...visits, ...doctorReviewVisits(reviewEvents)];
1430
1539
  const counts = Object.fromEntries(DOCTOR_SYMPTOMS.map((symptom: DoctorSymptom) => [symptom, 0])) as Record<DoctorSymptom, number>;
1431
- for (const visit of visits) counts[visit.symptom] += 1;
1540
+ for (const visit of statusVisits) counts[visit.symptom] += 1;
1432
1541
  if (json) {
1433
- out.log(JSON.stringify({ total: visits.length, counts, visits }, null, 2));
1542
+ out.log(JSON.stringify({ total: statusVisits.length, counts, visits: statusVisits }, null, 2));
1434
1543
  return;
1435
1544
  }
1436
1545
  out.log([
1437
- `Doctor visits: ${visits.length}`,
1546
+ `Doctor visits: ${statusVisits.length}`,
1438
1547
  ...DOCTOR_SYMPTOMS.map((symptom: DoctorSymptom) => ` ${symptom}: ${counts[symptom]}`),
1439
1548
  'Recent visits:',
1440
- ...visits.map((visit) => ` ${visit.timestamp ?? 'unknown-time'} runId=${visit.runId} from=${visit.from} symptom=${visit.symptom}${visit.evidence !== undefined ? ` evidence=${visit.evidence}` : ''}`),
1441
- ...(visits.length === 0 ? [' none'] : []),
1549
+ ...statusVisits.map((visit) => ` ${visit.timestamp ?? 'unknown-time'}${visit.runId ? ` runId=${visit.runId}` : ''} from=${visit.from} symptom=${visit.symptom}${visit.evidence !== undefined ? ` evidence=${visit.evidence}` : ''}`),
1550
+ ...(statusVisits.length === 0 ? [' none'] : []),
1442
1551
  ].join('\n'));
1443
1552
  });
1444
1553
  doctor
@@ -72,7 +72,9 @@ export function registerGuardianCommands(program: Command): void {
72
72
  debug.log('ops.orphan-cli', 'observation-failed', { error: String(error) });
73
73
  } catch { /* guardian shadow still runs */ }
74
74
  }
75
- const result = await guardianTick(tickAt, plan, { config: cfg });
75
+ const result = await guardianTick(tickAt, plan, { config: cfg,
76
+ doctorShadow: async () => { (await import('../self-implement/doctor-visit.js')).recordPendingShadowDoctorReevaluations(); },
77
+ });
76
78
  await writeStdoutJson(JSON.stringify(result, null, 2) + '\n');
77
79
  } finally { db.close(); }
78
80
  });
@@ -13,6 +13,7 @@ import { debug } from '../debug/log.js';
13
13
  import { getUserConfig } from '../user-config.js';
14
14
  import { registerIntakeSourceCommands } from './intake-source-cli.js';
15
15
  import type { IntakeItem } from '../intake-plane/items.js';
16
+ import type { CollectSavedResult, FetchSavedMessages } from '../intake-plane/collect-telegram-saved.js';
16
17
  import type { TaskCard } from '../task-cards/card-store.js';
17
18
  import { collectFunnelCandidates, type FunnelDirectiveRow } from '../intake-plane/requirement-funnel.js';
18
19
 
@@ -31,6 +32,13 @@ export interface IntakeCandidatesCliDeps {
31
32
  write?: (text: string) => Promise<void>;
32
33
  }
33
34
 
35
+ export interface IntakeCliDeps extends IntakeCandidatesCliDeps {
36
+ /** 흡수 원장 우주 (기본 effectiveInstanceRoot()) — 시험은 격리 임시 root 를 넣는다. */
37
+ root?: string;
38
+ /** 텔레그램 «저장된 메시지» 연결 (기본 gramjsFetchSaved) — 시험은 가짜 fetch 를 넣는다. */
39
+ connectSaved?: () => Promise<{ fetch: FetchSavedMessages; close: () => Promise<void> }>;
40
+ }
41
+
34
42
  /** `--limit` 원 문자열 → 0 이상의 정수. 숫자만(`/^\d+$/`) 받고 나머지('' · 공백 · 음수 · 소수)는 거부한다. */
35
43
  export function parseCandidatesLimit(raw: string): number {
36
44
  const limit = /^\d+$/.test(raw) ? Number(raw) : NaN;
@@ -187,6 +195,40 @@ export async function runIntakeDigestCli(
187
195
  return {};
188
196
  }
189
197
 
198
+ export interface CollectTelegramSavedCliDeps {
199
+ root?: string;
200
+ connect?: () => Promise<{ fetch: FetchSavedMessages; close: () => Promise<void> }>;
201
+ write?: (text: string) => Promise<void>;
202
+ error?: (message: string) => void;
203
+ }
204
+
205
+ /**
206
+ * `intake collect-telegram-saved` — 읽기만 · 커서 이후만.
207
+ * «메시지 0»(필터로 비었나 · 커서를 다른 주체가 넘겼나)과 «원장 입력 0»(다른 주체가 이미 가져갔나)을 갈라 보여준다.
208
+ */
209
+ export async function runCollectTelegramSavedCli(
210
+ opts: { max?: string; dryRun?: boolean; json?: boolean },
211
+ deps: CollectTelegramSavedCliDeps = {},
212
+ ): Promise<CollectSavedResult | undefined> {
213
+ const { collectTelegramSaved, gramjsFetchSaved, renderCollectTelegramSavedResult } = await import('../intake-plane/collect-telegram-saved.js');
214
+ const root = deps.root ?? (await import('../instance/resolve.js')).effectiveInstanceRoot();
215
+ let conn: { fetch: FetchSavedMessages; close: () => Promise<void> };
216
+ try { conn = await (deps.connect ?? (() => gramjsFetchSaved()))(); }
217
+ catch (e) { (deps.error ?? ((message: string) => console.error(message)))(String((e as Error).message ?? e)); process.exitCode = 2; return undefined; }
218
+ try {
219
+ const res = await collectTelegramSaved(root, conn.fetch, {
220
+ max: Math.max(1, Number(opts.max ?? 300) || 300),
221
+ ...(opts.dryRun ? { dryRun: true } : {}),
222
+ });
223
+ const write = deps.write ?? writeStdoutFully;
224
+ if (opts.json) await write(JSON.stringify(res, null, 2));
225
+ else await write(renderCollectTelegramSavedResult(res));
226
+ return res;
227
+ } finally {
228
+ await conn.close();
229
+ }
230
+ }
231
+
190
232
  export function resolveIntakeCheckRoot(
191
233
  cwd: string,
192
234
  git: typeof runGitCommand = runGitCommand,
@@ -200,7 +242,7 @@ export function resolveIntakeCheckRoot(
200
242
  }
201
243
  }
202
244
 
203
- export function registerIntakeCommands(program: Command, candidateDeps: IntakeCandidatesCliDeps = {}): void {
245
+ export function registerIntakeCommands(program: Command, candidateDeps: IntakeCliDeps = {}): void {
204
246
  // ── intake check — 바깥 사실을 elanous 현재와 대조 (태스크 등록 없음) ──
205
247
  const intakeCmd = program.command('intake').description('바깥 사실·문서를 elanous 현재와 대조하거나 태스크로 받는다');
206
248
  registerIntakeSourceCommands(intakeCmd);
@@ -500,17 +542,11 @@ export function registerIntakeCommands(program: Command, candidateDeps: IntakeCa
500
542
  .option('--dry-run', '원장·커서를 바꾸지 않고 건수만')
501
543
  .option('--json', '구조화 출력')
502
544
  .action(async (opts: { max?: string; dryRun?: boolean; json?: boolean }) => {
503
- const { collectTelegramSaved, gramjsFetchSaved } = await import('../intake-plane/collect-telegram-saved.js');
504
- const { effectiveInstanceRoot } = await import('../instance/resolve.js');
505
- let conn: Awaited<ReturnType<typeof gramjsFetchSaved>>;
506
- try { conn = await gramjsFetchSaved(); } catch (e) { console.error(String((e as Error).message ?? e)); process.exitCode = 2; return; }
507
- try {
508
- const res = await collectTelegramSaved(effectiveInstanceRoot(), conn.fetch, { max: Math.max(1, Number(opts.max ?? 300) || 300), ...(opts.dryRun ? { dryRun: true } : {}) });
509
- if (opts.json) await writeStdoutFully(JSON.stringify(res, null, 2));
510
- else console.log(`텔레그램 저장된 메시지: 메시지 ${res.messages} · 원장 입력 ${res.raws} · 커서 ${res.cursorBefore} → ${res.cursorAfter}${res.dryRun ? ' (dry-run · 안 씀)' : res.ingest ? ` · 새 ${res.ingest.added} · 합침 ${res.ingest.merged} · 이미 끝난 것 ${res.ingest.seen}` : ''}`);
511
- } finally {
512
- await conn.close();
513
- }
545
+ await runCollectTelegramSavedCli(opts, {
546
+ ...(candidateDeps.root ? { root: candidateDeps.root } : {}),
547
+ ...(candidateDeps.connectSaved ? { connect: candidateDeps.connectSaved } : {}),
548
+ ...(candidateDeps.write ? { write: candidateDeps.write } : {}),
549
+ });
514
550
  });
515
551
 
516
552
  intakeCmd