elanous 0.2.27 → 0.2.29

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 (700) 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/{Ev2jivDMTSoEc-5rIXdcy → cIpv5nU9AycwYWZI9H589}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.js → 058a98ba.7eb28d5e6dc03565.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{4565-67e4c620597965c8.js → 1015-9cba22a5a4554797.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +8 -0
  9. package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.js → 1142.65d002789ab3af7d.js} +2 -2
  10. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +34 -0
  12. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1516.dfaceff3fd2d0e0d.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +286 -0
  16. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +24 -0
  17. package/apps/pwa/out/_next/static/chunks/1782-59db1b5aa06df38a.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{1743.563d3168e95825ef.js → 1852.7f7b53991fcb99ef.js} +2 -2
  19. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +36 -0
  22. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +64 -0
  24. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{65ebff95.081daeff622d238e.js → 285adb1a.5654e605dddf86d2.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +115 -0
  31. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3160-95c96f4d2a21dd26.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +90 -0
  36. package/apps/pwa/out/_next/static/chunks/328bb3ab-6628a1114fe3fb3b.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 3396-97b97928c49190c9.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 3403.7199205e65124486.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/419.736c0d6f426249a7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{6def8a8e.c81f9ca41028eccf.js → 425cfc4d.fb91158e3971c39f.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 46bd8bea.2f4b4099172fcdb7.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{5081.a240b63fad28663a.js → 4759.1f76713aefb87db5.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +94 -0
  54. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +62 -0
  60. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +27 -0
  63. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +104 -0
  64. package/apps/pwa/out/_next/static/chunks/{9974.e77b4ff4884557b3.js → 5591.a35e7a217734a8b9.js} +2 -2
  65. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +93 -0
  66. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/{5492-e05e26a033ba80d2.js → 6013-2f769370d8b4c2c6.js} +3 -3
  69. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +24 -0
  70. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +2 -0
  72. package/apps/pwa/out/_next/static/chunks/{5408.377c8c543635b81f.js → 6534.1ab00f370db7b105.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +148 -0
  74. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +149 -0
  75. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +79 -0
  77. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/{8578.dff22d988cc2b106.js → 6767.1fcfc9b8be83975f.js} +16 -16
  79. package/apps/pwa/out/_next/static/chunks/6776.06ff1e3b464cc607.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.js → 6853.cc5174a9dee59593.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +287 -0
  86. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 7375.050ea0d72968e49f.js} +16 -16
  92. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +77 -0
  94. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +74 -0
  97. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7725-4f83d5541fbdb81b.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8332.6f0f49df772e163b.js +23 -0
  102. package/apps/pwa/out/_next/static/chunks/{7483.ba01c6c209b81bba.js → 8398.73a19b39715eda04.js} +1 -1
  103. package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.js → 8471.8d2a8c74f09c36ff.js} +3 -3
  104. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +226 -0
  106. package/apps/pwa/out/_next/static/chunks/{5785-ea8d2c633b6688e3.js → 8767-2f6a634f5abeaa01.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +32 -0
  109. package/apps/pwa/out/_next/static/chunks/8795.32573a185af18c7b.js +41 -0
  110. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.js → 9143.ff14585db1d275ff.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.js → 9907.49be0fcadaf214b5.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{973cbf1b.3bbcf2b41548eca7.js → a435ad95.577add051b4facb2.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/{page-ff27902d0b11ef4f.js → page-8aaa6dedc4c10dfb.js} +1 -1
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-25a302273b054fd7.js → page-33bf667a5fb297bf.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-29900ed0011b2c83.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-87b88f551f421d8b.js → page-9eb56166774eb256.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{f4dfbfc0.a69fb12f854882aa.js → bc324b7c.02a09dd93f6a399b.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +122 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +1 -0
  183. package/apps/pwa/out/approvals/index.html +1 -1
  184. package/apps/pwa/out/approvals/index.txt +22 -22
  185. package/apps/pwa/out/autopilot/index.html +1 -1
  186. package/apps/pwa/out/autopilot/index.txt +22 -22
  187. package/apps/pwa/out/board/index.html +1 -1
  188. package/apps/pwa/out/board/index.txt +22 -22
  189. package/apps/pwa/out/botlab/index.html +1 -1
  190. package/apps/pwa/out/botlab/index.txt +21 -21
  191. package/apps/pwa/out/bots/index.html +1 -1
  192. package/apps/pwa/out/bots/index.txt +21 -21
  193. package/apps/pwa/out/ceo/index.html +1 -1
  194. package/apps/pwa/out/ceo/index.txt +22 -22
  195. package/apps/pwa/out/chat/index.html +1 -1
  196. package/apps/pwa/out/chat/index.txt +21 -21
  197. package/apps/pwa/out/consult/index.html +1 -1
  198. package/apps/pwa/out/consult/index.txt +22 -22
  199. package/apps/pwa/out/control/index.html +1 -1
  200. package/apps/pwa/out/control/index.txt +22 -22
  201. package/apps/pwa/out/decisions/index.html +1 -1
  202. package/apps/pwa/out/decisions/index.txt +21 -21
  203. package/apps/pwa/out/design-check/index.html +1 -1
  204. package/apps/pwa/out/design-check/index.txt +22 -22
  205. package/apps/pwa/out/editor/index.html +1 -1
  206. package/apps/pwa/out/editor/index.txt +22 -22
  207. package/apps/pwa/out/exec/index.html +1 -1
  208. package/apps/pwa/out/exec/index.txt +22 -22
  209. package/apps/pwa/out/field/index.html +1 -1
  210. package/apps/pwa/out/field/index.txt +22 -22
  211. package/apps/pwa/out/healthz +1 -1
  212. package/apps/pwa/out/index.html +1 -1
  213. package/apps/pwa/out/index.txt +21 -21
  214. package/apps/pwa/out/inside/index.html +1 -1
  215. package/apps/pwa/out/inside/index.txt +21 -21
  216. package/apps/pwa/out/intake/index.html +1 -1
  217. package/apps/pwa/out/intake/index.txt +22 -22
  218. package/apps/pwa/out/live/index.html +1 -1
  219. package/apps/pwa/out/live/index.txt +22 -22
  220. package/apps/pwa/out/live-run/index.html +1 -1
  221. package/apps/pwa/out/live-run/index.txt +22 -22
  222. package/apps/pwa/out/loops/index.html +1 -1
  223. package/apps/pwa/out/loops/index.txt +21 -21
  224. package/apps/pwa/out/market/index.html +1 -1
  225. package/apps/pwa/out/market/index.txt +21 -21
  226. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  227. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  228. package/apps/pwa/out/morning/index.html +1 -1
  229. package/apps/pwa/out/morning/index.txt +22 -22
  230. package/apps/pwa/out/observatory/index.html +1 -1
  231. package/apps/pwa/out/observatory/index.txt +22 -22
  232. package/apps/pwa/out/ops/checklist/index.html +1 -1
  233. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  234. package/apps/pwa/out/ops/release/index.html +1 -1
  235. package/apps/pwa/out/ops/release/index.txt +21 -21
  236. package/apps/pwa/out/ops/seats/index.html +1 -1
  237. package/apps/pwa/out/ops/seats/index.txt +21 -21
  238. package/apps/pwa/out/outputs/index.html +1 -1
  239. package/apps/pwa/out/outputs/index.txt +21 -21
  240. package/apps/pwa/out/reflection/index.html +1 -1
  241. package/apps/pwa/out/reflection/index.txt +22 -22
  242. package/apps/pwa/out/scheduler/index.html +1 -1
  243. package/apps/pwa/out/scheduler/index.txt +22 -22
  244. package/apps/pwa/out/sessions/index.html +1 -1
  245. package/apps/pwa/out/sessions/index.txt +21 -21
  246. package/apps/pwa/out/settings/devices/index.html +1 -1
  247. package/apps/pwa/out/settings/devices/index.txt +22 -22
  248. package/apps/pwa/out/settings/index.html +1 -1
  249. package/apps/pwa/out/settings/index.txt +22 -22
  250. package/apps/pwa/out/setup/done/index.html +1 -1
  251. package/apps/pwa/out/setup/done/index.txt +22 -22
  252. package/apps/pwa/out/setup/index.html +1 -1
  253. package/apps/pwa/out/setup/index.txt +22 -22
  254. package/apps/pwa/out/share/index.html +1 -1
  255. package/apps/pwa/out/share/index.txt +22 -22
  256. package/apps/pwa/out/showroom/index.html +1 -1
  257. package/apps/pwa/out/showroom/index.txt +21 -21
  258. package/apps/pwa/out/tasks/index.html +1 -1
  259. package/apps/pwa/out/tasks/index.txt +22 -22
  260. package/apps/pwa/out/term/index.html +1 -1
  261. package/apps/pwa/out/term/index.txt +22 -22
  262. package/apps/pwa/out/today/index.html +1 -1
  263. package/apps/pwa/out/today/index.txt +22 -22
  264. package/apps/pwa/out/trace/index.html +1 -1
  265. package/apps/pwa/out/trace/index.txt +22 -22
  266. package/apps/pwa/out/vault/index.html +1 -1
  267. package/apps/pwa/out/vault/index.txt +22 -22
  268. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  269. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  270. package/apps/pwa/out/workflows/index.html +1 -1
  271. package/apps/pwa/out/workflows/index.txt +22 -22
  272. package/apps/pwa/out/workspace/index.html +1 -1
  273. package/apps/pwa/out/workspace/index.txt +22 -22
  274. package/apps/pwa/out/worktrees/index.html +1 -1
  275. package/apps/pwa/out/worktrees/index.txt +22 -22
  276. package/graphs/implement-loop.yaml +38 -1
  277. package/graphs/release/release-loop.yaml +6 -2
  278. package/graphs/steward/recipes.yaml +6 -0
  279. package/graphs/steward/release-day.yaml +23 -0
  280. package/graphs/steward/steward.yaml +9 -1
  281. package/graphs/work/code-pr.yaml +23 -0
  282. package/package.json +1 -1
  283. package/plugins/agent-team/agents/research.md +1 -0
  284. package/scripts/browser-observe-cycle.ts +76 -2
  285. package/scripts/ci-typecheck-changed.ts +53 -19
  286. package/scripts/coord-channel-watch.sh +26 -6
  287. package/scripts/coord-role-pack.ts +143 -0
  288. package/scripts/detect-test-interference.ts +31 -1
  289. package/scripts/lib/morning-report-options.ts +41 -0
  290. package/scripts/pr-land-extra-remote-gates.ts +49 -0
  291. package/scripts/release-loop/docs-node.ts +51 -22
  292. package/scripts/release-loop/gate-batch-safe.ts +23 -0
  293. package/scripts/release-loop/gate-history.ts +422 -0
  294. package/scripts/release-loop/gate-node.ts +336 -39
  295. package/scripts/release-loop/gate-triage-node.ts +190 -0
  296. package/scripts/release-loop/node-verdict.ts +3 -1
  297. package/scripts/release-loop/publish-node.ts +3 -0
  298. package/scripts/release-loop/spawn-lane.ts +68 -0
  299. package/scripts/release-loop/tui-node-checks.ts +28 -2
  300. package/scripts/release-loop/version-node.ts +62 -4
  301. package/scripts/skills/public-check.ts +5 -2
  302. package/scripts/test-deterministic.ts +549 -37
  303. package/scripts/usage-rollup.ts +11 -3
  304. package/scripts/ux-sim.ts +7 -1
  305. package/scripts/verify-kpack6-live.ts +230 -0
  306. package/src/acp/codex-plugins.ts +17 -0
  307. package/src/acp/core-turn-bridge.ts +98 -22
  308. package/src/acp/elanous-extensions.ts +2 -0
  309. package/src/acp/server.ts +2 -0
  310. package/src/agent/ref-grounding.ts +18 -0
  311. package/src/agent/task-notification.ts +2 -1
  312. package/src/agent-mission/in-agent-plugin.ts +8 -3
  313. package/src/agent-substrate/pr-reviewer.ts +29 -21
  314. package/src/agent-substrate/self-review-cli.ts +34 -10
  315. package/src/briefing/brief-items.ts +151 -35
  316. package/src/budget/llm-cost.ts +25 -2
  317. package/src/budget/pty-usage-reemit.ts +7 -0
  318. package/src/budget/run-usage-rollup.ts +9 -0
  319. package/src/budget/usage-daily-store.ts +98 -0
  320. package/src/budget/usage-outcomes.ts +32 -0
  321. package/src/capture/tui-self-report.ts +22 -4
  322. package/src/chat/index.ts +31 -10
  323. package/src/chat/pickers/modal-runtime.ts +1 -0
  324. package/src/chat/pickers/modals.ts +3 -1
  325. package/src/chat/turn-typeahead.ts +123 -16
  326. package/src/claims/claims-ledger.ts +23 -0
  327. package/src/claims/claims-render.ts +22 -2
  328. package/src/cli/brief-cli.ts +131 -10
  329. package/src/cli/claims-cli.ts +24 -4
  330. package/src/cli/dashboard-name-flag.ts +48 -0
  331. package/src/cli/doctor-cli.ts +80 -0
  332. package/src/cli/log-event-names.ts +12 -0
  333. package/src/cli/msg-cli.ts +210 -11
  334. package/src/cli/plugin-cli.ts +11 -3
  335. package/src/cli/pr-cli.ts +443 -104
  336. package/src/cli/pr-land-heavy-remote.ts +233 -0
  337. package/src/cli/pr-land-overlap-evidence.ts +104 -5
  338. package/src/cli/pr-land-refusal.ts +20 -0
  339. package/src/cli/pty-takeover-cli.ts +125 -16
  340. package/src/cli/release-cli.ts +46 -2
  341. package/src/cli/remote-resolve.ts +2 -1
  342. package/src/cli/rfc-cli.ts +24 -0
  343. package/src/cli/seat-cli.ts +26 -16
  344. package/src/cli/tailscale-serve.ts +5 -8
  345. package/src/cli/tasks-cli.ts +400 -27
  346. package/src/cli/usage-cli.ts +155 -16
  347. package/src/cli/usage-daily-cli.ts +84 -0
  348. package/src/context-bus/context-now.ts +82 -5
  349. package/src/core-turn/auth-rejected-notice.ts +41 -0
  350. package/src/core-turn/run-core-turn.ts +13 -2
  351. package/src/core-turn/run-goal-loop.ts +17 -1
  352. package/src/core-turn/short-question.ts +45 -12
  353. package/src/core-turn/types.ts +7 -0
  354. package/src/dashboard/acp-active-model.ts +40 -0
  355. package/src/dashboard/auto-compact-runtime.ts +2 -0
  356. package/src/dashboard/boot-banner.ts +80 -0
  357. package/src/dashboard/dashboard-status-lines.ts +11 -0
  358. package/src/dashboard/detail-viewer-runtime.ts +15 -2
  359. package/src/dashboard/event-loop-stall-monitor.ts +4 -0
  360. package/src/dashboard/first-screen-band.ts +63 -13
  361. package/src/dashboard/goal-loop-thinking.ts +16 -0
  362. package/src/dashboard/hitl-boot.ts +9 -4
  363. package/src/dashboard/index.ts +235 -389
  364. package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
  365. package/src/dashboard/input/chat-main-log-actions.ts +4 -0
  366. package/src/dashboard/input/chat-main-log-command.ts +12 -1
  367. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +172 -3
  368. package/src/dashboard/input/chat-main-session.ts +6 -2
  369. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  370. package/src/dashboard/input/chat-main-turn.ts +2 -1
  371. package/src/dashboard/input/compact-prepass-recovery.ts +97 -0
  372. package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
  373. package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
  374. package/src/dashboard/input/external-input-host.ts +45 -0
  375. package/src/dashboard/input/log-fold-binding.ts +18 -0
  376. package/src/dashboard/input/mouse-wiring.ts +17 -4
  377. package/src/dashboard/input/turn-steer-bridge.ts +94 -0
  378. package/src/dashboard/log-click-runtime.ts +5 -3
  379. package/src/dashboard/running-build-status.ts +74 -0
  380. package/src/dashboard/seat-boot-preamble.ts +113 -0
  381. package/src/dashboard/seat-local-instructions.ts +305 -0
  382. package/src/dashboard/skill-detection-runtime.ts +24 -4
  383. package/src/dashboard/slash-runtime/dashboard-handlers.ts +100 -28
  384. package/src/dashboard/slash-runtime/model-choices.ts +35 -0
  385. package/src/dashboard/term-slash-runtime.ts +15 -0
  386. package/src/dashboard/turn-preamble.ts +30 -2
  387. package/src/dashboard/turn-session-layers.ts +176 -0
  388. package/src/dashboard/turn-stream-formatter.ts +14 -6
  389. package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
  390. package/src/domains/morning-report.ts +3 -1
  391. package/src/domains/release-tool.ts +8 -9
  392. package/src/domains/surface-events.ts +4 -1
  393. package/src/domains/watch-default-scheduler.ts +8 -9
  394. package/src/fold-stack.ts +24 -1
  395. package/src/git-fs/dirty.ts +32 -4
  396. package/src/git-fs/index.ts +43 -1
  397. package/src/github/pr-labels.ts +10 -4
  398. package/src/graph-runner/runner.ts +102 -14
  399. package/src/harness/harness-clean.ts +21 -3
  400. package/src/harness/harness-cli-command.ts +22 -6
  401. package/src/harness/harness-gc.ts +32 -5
  402. package/src/harness/harness-pod-dispatch.ts +11 -4
  403. package/src/hq/seats.ts +17 -3
  404. package/src/index.ts +48 -6
  405. package/src/input/external-input-queue.ts +219 -0
  406. package/src/intelligence-map/model-bench-scores.ts +102 -0
  407. package/src/interactive-terminal-modal.ts +13 -0
  408. package/src/llm/route-decision.ts +25 -0
  409. package/src/llm-stream-retry-display.ts +59 -0
  410. package/src/llm.ts +253 -55
  411. package/src/log-entry.ts +3 -3
  412. package/src/log-pane/search.ts +29 -4
  413. package/src/loops/agent-reply.ts +256 -0
  414. package/src/loops/budget.ts +37 -7
  415. package/src/loops/loop-cli.ts +3 -2
  416. package/src/loops/msg-address.ts +57 -0
  417. package/src/loops/msg-wake.ts +282 -0
  418. package/src/loops/orchestrator/inbox.ts +130 -0
  419. package/src/loops/orchestrator/resync-shadow.ts +100 -12
  420. package/src/loops/orchestrator/tick.ts +94 -3
  421. package/src/loops/registry.ts +42 -4
  422. package/src/maturity/feature-maturity.ts +1 -1
  423. package/src/memory.ts +20 -5
  424. package/src/msg/msg-sse-server.ts +141 -0
  425. package/src/msg/msg-store.ts +84 -14
  426. package/src/native-tool-catalog.ts +125 -0
  427. package/src/nexus/api/http-server.ts +5 -0
  428. package/src/nexus/api/ops-api.ts +2 -0
  429. package/src/nexus/api/project-autopsy.ts +127 -0
  430. package/src/nexus/api/terminals.ts +3 -0
  431. package/src/nexus/api/workflow-approvals.ts +2 -0
  432. package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
  433. package/src/oauth/codex-account-store.ts +15 -3
  434. package/src/oauth/codex-billing-route.ts +31 -0
  435. package/src/ops/overview-collect.ts +19 -2
  436. package/src/panes/log-pane.ts +67 -8
  437. package/src/patents/ledger.ts +128 -0
  438. package/src/persona/presets.ts +44 -0
  439. package/src/plugins/install/market-fetch.ts +32 -1
  440. package/src/plugins/maker/wizard-generate.ts +6 -4
  441. package/src/pod-lease/admission.ts +116 -41
  442. package/src/preview/terminal.ts +14 -1
  443. package/src/prompt-cache/types.ts +2 -0
  444. package/src/prompt-enhance/enhance.ts +24 -8
  445. package/src/prompt-library/universal-preamble.ts +273 -56
  446. package/src/pty-shell/pty-control-ipc.ts +4 -1
  447. package/src/pty-shell/pty-manifest.ts +77 -5
  448. package/src/pty-shell/registry.ts +19 -2
  449. package/src/pty-shell/tui-run-state.ts +253 -0
  450. package/src/release-loop/checklist.ts +11 -0
  451. package/src/release-loop/light-rc.ts +28 -3
  452. package/src/release-loop/merged-pr-checklist.ts +24 -5
  453. package/src/release-loop/rehearsal.ts +1 -1
  454. package/src/release-loop/rubric.ts +70 -0
  455. package/src/render.ts +5 -1
  456. package/src/rfc-registry/registry.ts +88 -0
  457. package/src/seat-dispatch/seat-request-ledger.ts +4 -0
  458. package/src/seat-loop/knowhow-lint.ts +233 -0
  459. package/src/seat-loop/seat-pack.ts +16 -4
  460. package/src/seat-loop/seat-report.ts +42 -2
  461. package/src/seat-loop/traffic-signal.ts +7 -0
  462. package/src/self-dev/ask-launch-flow.ts +48 -8
  463. package/src/self-dev/ask-path-candidates.ts +69 -14
  464. package/src/self-dev/decompose-proposal.ts +43 -1
  465. package/src/self-dev/graph-journey-nodes.ts +2 -0
  466. package/src/self-dev/launch-preflight-text.ts +5 -1
  467. package/src/self-dev/launch-preflight.ts +143 -10
  468. package/src/self-dev/run-supervisor.ts +71 -5
  469. package/src/self-dev/shard-aggregate.ts +2 -0
  470. package/src/self-dev/shard-run.ts +23 -2
  471. package/src/self-health/signatures.ts +132 -0
  472. package/src/self-implement/doctor-visit.ts +118 -0
  473. package/src/self-implement/gate-cli.ts +17 -4
  474. package/src/self-implement/goal-author-decompose.ts +80 -16
  475. package/src/self-implement/goal-author.ts +116 -73
  476. package/src/self-implement/goal-authoring-grounding.ts +1 -1
  477. package/src/self-implement/goal-file-name.ts +65 -0
  478. package/src/self-implement/goal-new-paths.ts +4 -5
  479. package/src/self-implement/graph-authority.ts +17 -3
  480. package/src/self-implement/graph-yaml.ts +15 -7
  481. package/src/self-implement/ground-goal.ts +2 -1
  482. package/src/self-implement/headless-elanous-driver.ts +16 -1
  483. package/src/self-implement/host-regate.ts +58 -9
  484. package/src/self-implement/orchestrator.ts +3 -10
  485. package/src/self-implement/review-mustfix-class.ts +115 -0
  486. package/src/self-implement/rework-policy.ts +80 -2
  487. package/src/self-implement/run-ledger.ts +111 -7
  488. package/src/self-implement/running-runs.ts +10 -6
  489. package/src/self-implement/self-implement-runtime.ts +32 -0
  490. package/src/self-implement/speed-claims.ts +145 -6
  491. package/src/session/pending-input.ts +62 -11
  492. package/src/session-runtime/index.ts +7 -1
  493. package/src/skills/tools/ops-ledger.ts +707 -0
  494. package/src/skills/tools/persistent-grounding.ts +103 -8
  495. package/src/skills/tools/shell.ts +196 -2
  496. package/src/status/bar.ts +32 -2
  497. package/src/status/status-provider-info.ts +58 -0
  498. package/src/steward/rejudge-tick.ts +12 -1
  499. package/src/steward/release-day.ts +158 -0
  500. package/src/steward/resync-tick.ts +123 -0
  501. package/src/task-agent/actions.ts +1 -0
  502. package/src/task-agent/adopt-pr.ts +140 -0
  503. package/src/task-agent/board.ts +11 -1
  504. package/src/task-agent/card-evidence.ts +37 -5
  505. package/src/task-agent/cover.ts +84 -17
  506. package/src/task-agent/failure-notify.ts +61 -0
  507. package/src/task-agent/green-sweep.ts +170 -0
  508. package/src/task-agent/land-worktree.ts +52 -5
  509. package/src/task-agent/live-move-history.ts +1 -0
  510. package/src/task-agent/live-moves.ts +43 -12
  511. package/src/task-agent/parent-host.ts +1 -1
  512. package/src/task-agent/postland-card.ts +139 -0
  513. package/src/task-agent/rejudge-on-head.ts +109 -7
  514. package/src/task-agent/remote-rejudge-bind.ts +91 -0
  515. package/src/task-agent/repair-branch-cas.ts +182 -0
  516. package/src/task-agent/repair-cycle.ts +288 -0
  517. package/src/task-agent/repair-next-move.ts +31 -0
  518. package/src/task-agent/repair-review.ts +24 -0
  519. package/src/task-agent/repair-worker.ts +87 -0
  520. package/src/task-agent/review-result-capture.ts +2 -1
  521. package/src/task-agent/shadow.ts +13 -7
  522. package/src/task-agent/task-hand.ts +115 -6
  523. package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
  524. package/src/task-orchestrator/surfaces/pod-command-job.ts +63 -7
  525. package/src/task-orchestrator/surfaces/pod-install-slots.ts +6 -11
  526. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +76 -0
  527. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +96 -0
  528. package/src/task-orchestrator/surfaces/self-implement-pod.ts +175 -43
  529. package/src/telegram.ts +30 -1
  530. package/src/terminal/session-registry.ts +6 -0
  531. package/src/thinking-line.ts +12 -3
  532. package/src/tool-runtime/index.ts +4 -0
  533. package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
  534. package/src/tool-runtime/ref-consult-runtime.ts +17 -2
  535. package/src/tool-runtime/run-shell-runtime.ts +4 -1
  536. package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
  537. package/src/tui.ts +5 -0
  538. package/src/user-config.ts +62 -7
  539. package/src/ux-sim/fake-llm.ts +29 -0
  540. package/src/ux-sim/fault-sqlite-busy.ts +50 -0
  541. package/src/ux-sim/in-process-cli.ts +175 -0
  542. package/src/version/packed-revision.json +1 -1
  543. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
  548. package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +0 -148
  550. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/1454-a9c338f5bb556f42.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
  557. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +0 -24
  562. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
  565. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +0 -34
  567. package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
  572. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
  577. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
  582. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
  584. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
  586. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/599-a914cc0468f56143.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
  596. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
  600. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
  602. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
  604. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
  612. package/apps/pwa/out/_next/static/chunks/7752.5cbdd0b433c54af9.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
  621. package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
  623. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
  624. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
  627. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
  629. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
  630. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
  631. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +0 -90
  635. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +0 -79
  639. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/approvals/page-a1ce306364f08da9.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-07110da72c45e68f.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/board/page-d2d76d4a7eae91bd.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/botlab/page-30007380f2e2a3c1.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/bots/page-e5a9302c105725a3.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/ceo/page-b93c04b5311c97ec.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/chat/page-718a49e86bf25f9c.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/consult/page-20662900d6b4b455.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/control/page-f707a509515ac50c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/decisions/page-6a16a48d1aa6e91f.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/design-check/page-fcb06e305f515527.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/editor/page-6acf5ec4e6c6d1af.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/exec/page-39f82acf619cca23.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/field/page-7c2c8f81b185f9c0.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/inside/page-ae7aff07e32676bb.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/intake/page-482c60c1bc540d0a.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/layout-7cb996c1aa08b6f5.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/live/page-623e08fe4477d606.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/live-run/page-db460cd8aecb8490.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/market/page-8397a5c6ca569bf4.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1917ea87ea71ab6b.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/not-found-670510eda8b9443f.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d73c3f1e00d93986.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-65caacf54389081e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4bb7556e2e97a750.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-77e04b4f8762c666.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/outputs/page-15c0a4095baddfba.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/page-4eb96fc7241c2456.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/reflection/page-63e272a4cd3b6634.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d64ff212dc55d03.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/sessions/page-7f096248993fc2d4.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e47fc72049149a38.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/settings/page-f7d808e31e005895.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-5c2b24b5496dad73.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/setup/page-76cdb531668b5191.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/share/page-e2b63345bba1a11f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d376e0c83edc041a.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d6db55fe2c04d128.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/today/page-dab163b338e3b966.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/trace/page-08019efef111ed2e.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/vault/page-0260ffc7eda50db1.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-980ce6fe36ad95eb.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/workflows/page-99c4e6c7345a9156.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/workspace/page-0ab42e0f05823013.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ad9220422d20ba33.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/e117f801.e92bf10242653497.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +0 -122
  690. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
  696. package/src/dashboard/bench-slash-runtime.ts +0 -40
  697. package/src/dashboard/input/search-modal-router.ts +0 -9
  698. package/src/dashboard/modals/pane-key-router.ts +0 -27
  699. package/src/dashboard/view-slash-runtime.ts +0 -48
  700. /package/apps/pwa/out/_next/static/{Ev2jivDMTSoEc-5rIXdcy → cIpv5nU9AycwYWZI9H589}/_ssgManifest.js +0 -0
@@ -19,8 +19,8 @@
19
19
  // sandbox, conciseness, impl-discipline) move here as they're verified
20
20
  // surface-agnostic.
21
21
 
22
- import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
23
- import { join, basename, dirname, relative } from 'node:path';
22
+ import { closeSync, existsSync, lstatSync, openSync, readFileSync, readSync, readdirSync, realpathSync, statSync, writeFileSync } from 'node:fs';
23
+ import { join, basename, dirname, relative, resolve as resolvePath } from 'node:path';
24
24
  import type { LLMMessage } from '../llm.js';
25
25
  import type { ModelFamily } from '../models/prompts.js';
26
26
  import { debug } from '../debug/log.js';
@@ -31,6 +31,7 @@ import { buildAnthropicFamilyAddendum } from './anthropic-family-addendum.js';
31
31
  import { buildGrokFamilyAddendum } from './grok-family-addendum.js';
32
32
  import { buildSessionGuidanceAddendum } from './session-guidance.js';
33
33
  import { getHarnessSpace } from '../harness/harness-space.js';
34
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
34
35
 
35
36
  export const PROJECT_ANCHOR_MAX_CHARS = 36 * 1024; // 10-10 증액(32K→36K) — 줄이기는 AGENTS-CLAUDE-DIET(0.2.24)
36
37
  /** «lean» 예산(BACKLOG L2 · 2026-09-25) — 로컬 모델 구현 자식은 매 턴 이것을 prefill 한다.
@@ -52,6 +53,21 @@ export const PROJECT_ANCHOR_CANDIDATES = [
52
53
  // is intentionally excluded from project anchors by owner policy.
53
54
  export const PROJECT_ANCHOR_NON_CANDIDATE_FILENAMES = ['CLAUDE.md'] as const;
54
55
 
56
+ /** 🪪 자리 로컬 지시(L0 정체성 · 2026-10-14 · 대표 «TUI 가 자기를 인식 못하면 쓸 수 없다»).
57
+ * git 에 안 올라가는 «이 디렉터리만의» 지시 — 같은 저장소의 여러 자리(`seats/OP` 등)가 역할을 갈라 갖는 자리다.
58
+ * 한 디렉터리에서 «하나만» 읽는다: `AGENTS.local.md`(엘라누스 정본 이름)가 있으면 그것, 없으면 호환 `CLAUDE.local.md`.
59
+ * ⚠️ 위 정책 제외는 «공용» `CLAUDE.md` 만이다 — 로컬 파일은 자리 주인이 쓴 비공유 지시라 별개 축이다.
60
+ * 선례: codex `AGENTS.override.md`(`core/src/agents_md.rs:45`) · grok-build `CLAUDE.local.md`(`compat.rs:309-316`). */
61
+ export const PROJECT_ANCHOR_LOCAL_CANDIDATES = [
62
+ { filename: 'AGENTS.local.md', label: 'Directory-local instructions (overrides the shared guide)' },
63
+ { filename: 'CLAUDE.local.md', label: 'Directory-local instructions (compat · overrides the shared guide)' },
64
+ ] as const;
65
+ /** 로컬 지시는 공용 앵커와 «따로» 예산을 쓴다 — 공용 `AGENTS.md` 가 상한 가까이라 같은 예산이면 자리 지시가
66
+ * 통째로 빠진다(10-14 실측: 공용 33,050자 / 36K). 그 반대로 로컬이 공용을 밀어내지도 않는다. */
67
+ export const PROJECT_ANCHOR_LOCAL_MAX_CHARS = 8 * 1024;
68
+ export const PROJECT_ANCHOR_LOCAL_LEAN_MAX_CHARS = 2 * 1024;
69
+ export function projectAnchorLocalMaxChars(): number { return promptBudgetLean() ? PROJECT_ANCHOR_LOCAL_LEAN_MAX_CHARS : PROJECT_ANCHOR_LOCAL_MAX_CHARS; }
70
+
55
71
  // W4-B (2026-05-03) — codex-rs `realtime_context.rs` 패턴 차용:
56
72
  // per-dir DIR_ENTRY_LIMIT=20 으로 1차 통제, character cap 은 최종 안전망.
57
73
  // gemini-cli 의 MAX_ITEMS=200 글로벌 BFS 도 같은 의도. 문서:
@@ -81,10 +97,10 @@ Give one line explaining how to enable tools: \`elanous agent "<your question>"\
81
97
  const CODING_AGENT_LIFECYCLE = `# Coding Agent Pipelines — Tool-Batch Discipline
82
98
 
83
99
  For coding-style tasks (analysis, implementation, debugging), follow ONE
84
- of these three pipelines. State the pipeline you chose ONCE in your
85
- opening sentence (not every turn). On subsequent turns, just execute the
86
- next stage — your tool calls are the audit trail; re-narrating the
87
- pipeline every turn signals you are stuck.
100
+ of these three pipelines. Do not tell the user which pipeline you chose
101
+ (no "I'll use the analysis pipeline" / "○○ 파이프라인으로 하겠습니다") —
102
+ the user sees your tool calls, and the pipeline name adds nothing. Just
103
+ execute the next stage; your tool calls are the audit trail.
88
104
 
89
105
  ## Analysis (분석) — find → read → organize
90
106
  When a user's analysis question identifies a concrete, user-fixable code or
@@ -119,9 +135,9 @@ not claim a change was made before it is implemented and verified.
119
135
  you've established a clear blocker for the user.
120
136
 
121
137
  ## Pipeline Discipline
122
- - Pick ONE pipeline at the START of the task. State it ONCE in your
123
- opening sentence — do NOT re-state on every subsequent turn. On
124
- follow-up turns just call the next stage's tools directly.
138
+ - Pick ONE pipeline at the START of the task, silently — never name it
139
+ in your answer. On follow-up turns just call the next stage's tools
140
+ directly.
125
141
  - Each stage = ONE turn (or one parallel batch within a turn). Don't
126
142
  spread \`find\` across 4 sequential turns — batch the tools.
127
143
  - **find → read transition is MANDATORY** after the first \`find\` batch
@@ -131,8 +147,7 @@ not claim a change was made before it is implemented and verified.
131
147
  - For Analysis: stop at \`organize\`. Don't drift into edit/exec.
132
148
  - For Implementation/Debugging: \`verify\` is mandatory. "I made the
133
149
  change" without verification is incomplete output.
134
- - Do not announce your pipeline choice and then call zero tools — pick a
135
- pipeline ONLY when you actually need to use it. Pure conversational
150
+ - Pick a pipeline ONLY when you actually need to use it. Pure conversational
136
151
  questions don't need a pipeline.`;
137
152
 
138
153
  /** Build the family-agnostic coding-agent lifecycle addendum. Returns
@@ -192,9 +207,22 @@ export interface ProjectAnchorMeta {
192
207
  * Mirrors ref/codex's path-aware AGENTS.md ordering — the model
193
208
  * needs to know which scope a given fragment came from. */
194
209
  relDir: string;
210
+ /** 자리 로컬 지시(`AGENTS.local.md`·`CLAUDE.local.md`)에서 왔나 — 공용 앵커와 예산·순서가 다르다. */
211
+ local?: true;
212
+ /** 층(L0 v2): global = 우주 뿌리(`effectiveInstanceRoot`)의 `AGENTS.md` · root = 저장소 루트 · dir = 루트→cwd 사이·cwd 의 디렉터리 · local = `*.local.md`. */
213
+ layer?: ProjectAnchorLayer;
214
+ /** 읽은 파일의 절대 경로(관측용). */
215
+ path?: string;
195
216
  }
196
217
 
197
- export type ProjectAnchorSkipReason = 'budget-exhausted' | 'absent' | 'read-failed' | 'policy-excluded';
218
+ export type ProjectAnchorLayer = 'global' | 'root' | 'dir' | 'local' | 'last-session';
219
+
220
+ /** 🪪 TUI 가 통째로 소유하는 «지난 세션» 파일(`dashboard/seat-local-instructions.ts` 가 대화 끝마다 쓴다).
221
+ * 층 ④ 뒤에 싣는다. 작아야 정상이라 상한을 넘으면 자른다(사람 지시가 아니다). */
222
+ export const PROJECT_ANCHOR_LAST_SESSION_FILE = '.AGENTS.local.last-session.md';
223
+ export const PROJECT_ANCHOR_LAST_SESSION_MAX_CHARS = 2 * 1024;
224
+
225
+ export type ProjectAnchorSkipReason = 'budget-exhausted' | 'absent' | 'read-failed' | 'policy-excluded' | 'shadowed';
198
226
 
199
227
  export interface ProjectAnchorSkippedFile {
200
228
  filename: string;
@@ -510,77 +538,216 @@ function ancestorChain(root: string, cwd: string): string[] {
510
538
  * walk from project root (`.git` marker) down to cwd, reading the
511
539
  * configured anchor candidates at every level. Root-most fragments land
512
540
  * first so general project guidance precedes sub-package specifics. Same
513
- * character budget — ancestor fragments consume budget before cwd's, but
514
- * in practice the chain is shallow (≤ 5 dirs) and individual AGENTS
515
- * files are small. */
541
+ * character budget — allocate from cwd toward root and global so the
542
+ * most specific instructions remain intact; render outer-first. */
516
543
  export function loadProjectAnchorWithMeta(cwd: string): ProjectAnchorResult {
517
- const parts: string[] = [];
544
+ // L0 v2(대표 10-14) — 층 넷: ① 전역(우주 뿌리 `AGENTS.md`) ② 저장소 루트 AGENTS.md·DESIGN.md
545
+ // ③ 루트→cwd 사이 각 디렉터리(codex 식) ④ 로컬 `AGENTS.local.md`(호환 `CLAUDE.local.md`).
546
+ // «예산»은 ④ 먼저(자르지 않는다 · 로컬 상한을 넘으면 경고 관측) → ③(cwd→부모) → ② → ① 순으로 받고,
547
+ // «싣는» 순서는 ① → ② → ③(루트→cwd) → ④ — 안쪽이 바깥을 덮는다(codex·Claude Code 와 같은 규칙).
548
+ // ⇒ 예산이 모자라면 잘리는 순서는 ① → ② → ③(얕은 것부터), ④ 는 안 잘린다.
518
549
  const files: ProjectAnchorMeta[] = [];
519
550
  const skipped: ProjectAnchorSkippedFile[] = [];
520
- let charsUsed = 0;
521
551
  const TRUNCATION_MARKER = '\n…[truncated to fit anchor budget]';
522
552
  const root = findProjectRoot(cwd);
523
553
  const chain = ancestorChain(root, cwd);
524
- const readWithBudget = (dir: string, filename: string, label: string): void => {
525
- const relDir = relative(cwd, dir);
526
- const skip = (reason: ProjectAnchorSkipReason): void => {
527
- skipped.push({ filename, relDir, reason });
528
- };
529
- if (charsUsed >= projectAnchorMaxChars()) {
530
- skip('budget-exhausted');
531
- return;
532
- }
533
- const path = join(dir, filename);
534
- if (!existsSync(path)) {
535
- skip('absent');
536
- return;
537
- }
538
- let raw: string;
554
+ interface Slot { order: number; text?: string; meta?: ProjectAnchorMeta; skip?: ProjectAnchorSkippedFile }
555
+ const slots: Slot[] = [];
556
+ const fence = (label: string, filename: string, scope: string, content: string): string =>
557
+ `=== ${label} (${filename}${scope}) ===\n${content}\n=== end ${filename}${scope} ===`;
558
+ const readRaw = (path: string): string | null => {
539
559
  try {
540
- raw = readFileSync(path, 'utf8');
560
+ const raw = readFileSync(path, 'utf8');
541
561
  projectAnchorReadObserverForTest?.(path);
562
+ return raw;
542
563
  } catch {
543
- skip('read-failed');
564
+ return null;
565
+ }
566
+ };
567
+
568
+ const localRaw = new Map<string, string>();
569
+ // ④ 로컬 — 먼저 읽고 자르지 않는다. 디렉터리마다 하나(AGENTS.local.md 가 이기고 CLAUDE.local.md 는 shadowed).
570
+ const LOCAL_ORDER_BASE = 1_000_000;
571
+ let localUsed = 0;
572
+ chain.forEach((dir, index) => {
573
+ const relDir = relative(cwd, dir);
574
+ const present = PROJECT_ANCHOR_LOCAL_CANDIDATES.filter(({ filename }) => existsSync(join(dir, filename)));
575
+ const chosen = present[0];
576
+ if (!chosen) return;
577
+ for (const other of present.slice(1)) slots.push({ order: LOCAL_ORDER_BASE + index * 10 + 1, skip: { filename: other.filename, relDir, reason: 'shadowed' } });
578
+ const path = join(dir, chosen.filename);
579
+ const raw = readRaw(path);
580
+ if (raw === null) {
581
+ slots.push({ order: LOCAL_ORDER_BASE + index * 10, skip: { filename: chosen.filename, relDir, reason: 'read-failed' } });
544
582
  return;
545
583
  }
546
- const remaining = projectAnchorMaxChars() - charsUsed;
584
+ localUsed += raw.length;
585
+ localRaw.set(path, raw);
586
+ const scope = relDir === '' ? '' : ` @ ${relDir}`;
587
+ slots.push({
588
+ order: LOCAL_ORDER_BASE + index * 10,
589
+ text: fence(chosen.label, chosen.filename, scope, raw),
590
+ meta: { filename: chosen.filename, chars: raw.length, truncated: false, relDir, local: true, layer: 'local', path },
591
+ });
592
+ });
593
+ // ⑤ 지난 세션 — TUI 소유 파일. 로컬 지시 «뒤»(가장 안쪽 · 가장 최근 맥락). «cwd 의 자리 루트»(/seats/<자리>) 하나만 읽는다 —
594
+ // 자리 밖 TUI 나 상위 디렉터리의 같은 이름 파일을 «지난 세션»으로 싣지 않게. 사람 파일이 아니므로 상한에서 자르고 읽기도 상한만큼만.
595
+ const lastSessionPath = seatLastSessionPath(cwd);
596
+ if (lastSessionPath) {
597
+ const relDir = relative(cwd, dirname(lastSessionPath));
598
+ let regular: boolean | null = null;
599
+ try { regular = lstatSync(lastSessionPath).isFile(); } catch { regular = null; /* 없음 */ }
600
+ if (regular === false) {
601
+ // ⛔ 링크·비정규 파일은 읽지 않는다(바깥 파일 주입 차단 · 기록기도 링크를 거부한다).
602
+ slots.push({ order: 2_000_000, skip: { filename: PROJECT_ANCHOR_LAST_SESSION_FILE, relDir, reason: 'read-failed' } });
603
+ } else if (regular === true) {
604
+ const raw = readHeadChars(lastSessionPath, PROJECT_ANCHOR_LAST_SESSION_MAX_CHARS + 1);
605
+ if (raw === null) {
606
+ slots.push({ order: 2_000_000, skip: { filename: PROJECT_ANCHOR_LAST_SESSION_FILE, relDir, reason: 'read-failed' } });
607
+ } else {
608
+ const truncated = raw.length > PROJECT_ANCHOR_LAST_SESSION_MAX_CHARS;
609
+ const content = truncated ? `${raw.slice(0, PROJECT_ANCHOR_LAST_SESSION_MAX_CHARS - TRUNCATION_MARKER.length)}${TRUNCATION_MARKER}` : raw;
610
+ localUsed += content.length;
611
+ const scope = relDir === '' ? '' : ` @ ${relDir}`;
612
+ slots.push({
613
+ order: 2_000_000,
614
+ text: fence('Previous TUI session in this seat (TUI-owned)', PROJECT_ANCHOR_LAST_SESSION_FILE, scope, content),
615
+ meta: { filename: PROJECT_ANCHOR_LAST_SESSION_FILE, chars: content.length, truncated, relDir, layer: 'last-session', path: lastSessionPath },
616
+ });
617
+ }
618
+ }
619
+ }
620
+ const localCap = projectAnchorLocalMaxChars();
621
+ if (localUsed > localCap) {
622
+ // ⛔ 자르지 않는다(대표 «먼저 읽게») — 대신 넘친 만큼 공용 예산이 준다. 그 사실을 «읽을 때마다» 게이트 없이 남긴다
623
+ // (캐시 적중 턴은 같은 결과를 다시 쓰는 것이라 새로 남기지 않는다 — 파일이 바뀌면 다시 읽혀 다시 남는다).
624
+ debug.log('chat.project-anchor', 'local-over-cap', { cwd, localChars: localUsed, localCapChars: localCap });
625
+ }
626
+ // 공용 예산 = 공용 상한. 로컬이 자기 상한을 넘으면 넘친 만큼 공용에서 뺀다(합계 상한 = 공용 + 로컬).
627
+ const sharedCap = Math.max(0, Math.min(projectAnchorMaxChars(), projectAnchorMaxChars() + localCap - localUsed));
628
+ let sharedUsed = 0;
629
+
630
+ // ①②③ 를 «예산 우선순위»로 줄 세운다: cwd → 부모 디렉터리 → 루트 → 전역. order 는 «싣는» 순서다.
631
+ interface Want { order: number; path: string; filename: string; label: string; relDir: string; scope: string; layer: ProjectAnchorLayer; recordAbsent: boolean }
632
+ const wants: Want[] = [];
633
+ const globalPath = globalAnchorPath();
634
+ // 우주 뿌리가 저장소 트리 안이면(예: `--test=<트리>`) 전역 파일이 곧 ②·③ 의 AGENTS.md 다 — 두 번 싣지 않는다.
635
+ const chainAgents = new Set(chain.map((dir) => safeRealpath(join(dir, 'AGENTS.md'))));
636
+ const dirWants = (index: number): Want[] => {
637
+ const dir = chain[index]!;
638
+ const relDir = relative(cwd, dir);
639
+ return PROJECT_ANCHOR_CANDIDATES.map(({ filename, label }, k) => ({
640
+ order: 100 + index * 10 + k,
641
+ path: join(dir, filename),
642
+ filename,
643
+ label,
644
+ relDir,
645
+ scope: relDir === '' ? '' : ` @ ${relDir}`,
646
+ layer: (index === 0 ? 'root' : 'dir') as ProjectAnchorLayer,
647
+ recordAbsent: true,
648
+ }));
649
+ };
650
+ for (let index = chain.length - 1; index >= 0; index--) wants.push(...dirWants(index));
651
+ if (globalPath && existsSync(globalPath) && !chainAgents.has(safeRealpath(globalPath))) {
652
+ wants.push({ order: 0, path: globalPath, filename: basename(globalPath), label: 'User-global instructions', relDir: relative(cwd, dirname(globalPath)), scope: ' @ instance root', layer: 'global', recordAbsent: false });
653
+ }
654
+ for (const want of wants) {
655
+ const skip = (reason: ProjectAnchorSkipReason): void => {
656
+ slots.push({ order: want.order, skip: { filename: want.filename, relDir: want.relDir, reason } });
657
+ };
658
+ // 남은 예산이 절단 마커보다 «작으면» «잘라 싣기»가 상한을 넘긴다 — 그때는 통째로 뺀다(같으면 마커만 싣는다).
659
+ if (sharedCap - sharedUsed < TRUNCATION_MARKER.length) { if (want.recordAbsent || existsSync(want.path)) skip('budget-exhausted'); continue; }
660
+ if (!existsSync(want.path)) { if (want.recordAbsent) skip('absent'); continue; }
661
+ const raw = readRaw(want.path);
662
+ if (raw === null) { skip('read-failed'); continue; }
663
+ const remaining = sharedCap - sharedUsed;
547
664
  const truncated = raw.length > remaining;
548
665
  const sliceLen = truncated ? Math.max(0, remaining - TRUNCATION_MARKER.length) : raw.length;
549
666
  const content = truncated ? `${raw.slice(0, sliceLen)}${TRUNCATION_MARKER}` : raw;
550
- // Disambiguate fragments from different scopes in the inline
551
- // header so the model can tell "this is the root project guide"
552
- // from "this is the sub-package override". Empty relDir = cwd
553
- // itself, render plain filename for backwards-compat with the
554
- // single-fragment case.
555
- const scopeSuffix = relDir === '' ? '' : ` @ ${relDir}`;
556
- parts.push(`=== ${label} (${filename}${scopeSuffix}) ===\n${content}\n=== end ${filename}${scopeSuffix} ===`);
557
- charsUsed += content.length;
558
- files.push({ filename, chars: content.length, truncated, relDir });
559
- };
560
- for (const dir of chain) {
561
- for (const candidate of PROJECT_ANCHOR_CANDIDATES) {
562
- readWithBudget(dir, candidate.filename, candidate.label);
563
- }
667
+ sharedUsed += content.length;
668
+ slots.push({
669
+ order: want.order,
670
+ text: fence(want.label, want.filename, want.scope, content),
671
+ meta: { filename: want.filename, chars: content.length, truncated, relDir: want.relDir, layer: want.layer, path: want.path },
672
+ });
673
+ }
674
+ chain.forEach((dir, index) => {
564
675
  for (const filename of PROJECT_ANCHOR_NON_CANDIDATE_FILENAMES) {
565
676
  if (existsSync(join(dir, filename))) {
566
- skipped.push({ filename, relDir: relative(cwd, dir), reason: 'policy-excluded' });
677
+ slots.push({ order: 100 + index * 10 + 9, skip: { filename, relDir: relative(cwd, dir), reason: 'policy-excluded' } });
567
678
  }
568
679
  }
680
+ });
681
+
682
+ slots.sort((a, b) => a.order - b.order);
683
+ const parts: string[] = [];
684
+ for (const slot of slots) {
685
+ if (slot.text !== undefined && slot.meta) { parts.push(slot.text); files.push(slot.meta); }
686
+ if (slot.skip) skipped.push(slot.skip);
569
687
  }
570
- return {
688
+ const result: ProjectAnchorResult = {
571
689
  content: parts.length > 0 ? parts.join('\n\n') : null,
572
690
  files,
573
691
  skipped,
574
- totalChars: charsUsed,
692
+ totalChars: sharedUsed + localUsed,
575
693
  };
694
+ // 읽은 로컬 원문 — 자기 편집 비교·백업용(관측 로그에 안 실리게 결과 객체 밖에 둔다).
695
+ localRawByResult.set(result, localRaw);
696
+ return result;
697
+ }
698
+
699
+ function safeRealpath(path: string): string {
700
+ try { return realpathSync(path); } catch { return resolvePath(path); }
701
+ }
702
+
703
+ const SEAT_ROOT_IN_PATH = /^(.*?\/seats\/[A-Za-z][A-Za-z0-9_-]{0,63})(?:\/|$)/;
704
+ /** cwd 가 `/seats/<자리>` 아래면 그 자리 루트의 «지난 세션» 파일 경로. 자리 밖이면 null. */
705
+ export function seatLastSessionPath(cwd: string): string | null {
706
+ const m = SEAT_ROOT_IN_PATH.exec(cwd);
707
+ return m ? join(m[1]!, PROJECT_ANCHOR_LAST_SESSION_FILE) : null;
708
+ }
709
+
710
+ /** 파일 앞부분만 읽는다(문자 상한의 4배 바이트까지 — UTF-8 최대 폭). */
711
+ function readHeadChars(path: string, maxChars: number): string | null {
712
+ let fd: number | null = null;
713
+ try {
714
+ fd = openSync(path, 'r');
715
+ const buf = Buffer.alloc(maxChars * 4);
716
+ const n = readSync(fd, buf, 0, buf.length, 0);
717
+ projectAnchorReadObserverForTest?.(path);
718
+ return buf.subarray(0, n).toString('utf8').slice(0, maxChars);
719
+ } catch {
720
+ return null;
721
+ } finally {
722
+ if (fd !== null) { try { closeSync(fd); } catch { /* ignore */ } }
723
+ }
724
+ }
725
+
726
+ let globalAnchorPathOverride: string | null | undefined;
727
+ /** 시험 심 — 전역 앵커 경로를 바꾼다(null = 전역 층 끄기 · undefined = 기본 · 우주 뿌리의 `AGENTS.md`). */
728
+ export function setGlobalAnchorPathForTest(path: string | null | undefined): void {
729
+ globalAnchorPathOverride = path;
730
+ }
731
+ /** ① 전역 층 — 사용자 공통 지시. «이 프로세스의 우주» 뿌리(`effectiveInstanceRoot` — 운영이면 `~/.elanous`,
732
+ * `--test`·`--config-dir`·`ELANOUS_STATE_DIR` 면 그 우주)의 `AGENTS.md` 다. ⛔ 홈 경로를 박지 않는다 — 격리 우주가
733
+ * 운영 파일을 읽으면 안 된다(isolation-gate). 뿌리를 못 정하면 전역 층을 끈다. */
734
+ export function globalAnchorPath(): string | null {
735
+ if (globalAnchorPathOverride !== undefined) return globalAnchorPathOverride;
736
+ try {
737
+ return join(effectiveInstanceRoot(), 'AGENTS.md');
738
+ } catch {
739
+ return null;
740
+ }
576
741
  }
577
742
 
578
743
  function projectAnchorCandidates(cwd: string): string[] {
579
744
  const root = findProjectRoot(cwd);
580
- return ancestorChain(root, cwd).flatMap(dir => [
745
+ const globalPath = globalAnchorPath();
746
+ return [...(globalPath ? [globalPath] : []), ...ancestorChain(root, cwd).flatMap(dir => [
581
747
  ...PROJECT_ANCHOR_CANDIDATES.map(({ filename }) => join(dir, filename)),
582
748
  ...PROJECT_ANCHOR_NON_CANDIDATE_FILENAMES.map(filename => join(dir, filename)),
583
- ]);
749
+ ...PROJECT_ANCHOR_LOCAL_CANDIDATES.map(({ filename }) => join(dir, filename)),
750
+ ]), ...(seatLastSessionPath(cwd) ? [seatLastSessionPath(cwd)!] : [])];
584
751
  }
585
752
 
586
753
  function projectAnchorMtimes(candidates: string[]): ProjectAnchorCandidate[] {
@@ -629,10 +796,50 @@ function observeProjectAnchorLoss(cwd: string, result: ProjectAnchorResult): voi
629
796
  totalChars: result.totalChars,
630
797
  capChars: projectAnchorMaxChars(),
631
798
  // ⛔ 「얼마나 모자랐나」를 같이 낸다 — 「잘렸다」만으론 «얼마나» 키워야 할지 모른다
632
- overflowChars: Math.max(0, result.totalChars - projectAnchorMaxChars()),
799
+ // 로컬 지시는 따로 예산이라 공용 상한과 비교할 때는 뺀다.
800
+ overflowChars: Math.max(0, result.files.filter((file) => !file.local).reduce((sum, file) => sum + file.chars, 0) - projectAnchorMaxChars()),
633
801
  });
634
802
  }
635
803
 
804
+ /** 🪪 자리 로컬 지시가 «바뀌었다»를 남긴다 — TUI 에이전트가 자기 지시 파일을 고치면(Edit 등) 다음 조회에서
805
+ * mtime 이 바뀌어 다시 읽히고, 그때 «문면»이 달라졌으면(mtime 만 바뀐 touch 는 아니다) 관측 한 줄 ⊕ 직전 판 백업 한 벌.
806
+ * ⛔ 이 파일은 git 제외라 모델이 잘못 고치면 되돌릴 이력이 없다 ⇒ 직전 내용을 같은 폴더 `.<파일>.prev` 로 덮어쓴다.
807
+ * 드물고 결과가 크니 항상 남긴다(게이트 없음). 백업 실패는 관측만 하고 앵커를 막지 않는다. */
808
+ const localRawByResult = new WeakMap<ProjectAnchorResult, Map<string, string>>();
809
+
810
+ function observeLocalInstructionEdits(cwd: string, previous: ProjectAnchorResult | undefined, next: ProjectAnchorResult): void {
811
+ if (!previous) return;
812
+ for (const file of next.files) {
813
+ if (!file.local) continue;
814
+ const before = previous.files.find((f) => f.local && f.filename === file.filename && f.relDir === file.relDir);
815
+ if (!before) continue;
816
+ // ⛔ 펜스 문면을 역파싱하지 않는다(본문에 `=== end …` 줄이 있으면 잘린다) — 읽은 원문 그대로 비교·백업.
817
+ const prevBody = before.path ? localRawByResult.get(previous)?.get(before.path) ?? null : null;
818
+ const nextBody = file.path ? localRawByResult.get(next)?.get(file.path) ?? null : null;
819
+ if (prevBody === nextBody) continue;
820
+ let prevPath: string | null = null;
821
+ let backupError: string | undefined;
822
+ if (prevBody !== null && file.path) {
823
+ prevPath = join(dirname(file.path), `.${file.filename}.prev`);
824
+ try {
825
+ writeFileSync(prevPath, prevBody);
826
+ } catch (err) {
827
+ backupError = err instanceof Error ? err.message : String(err);
828
+ prevPath = null;
829
+ }
830
+ }
831
+ debug.log('tui.local-instructions', 'edited', {
832
+ cwd,
833
+ file: file.relDir ? `${file.relDir}/${file.filename}` : file.filename,
834
+ charsBefore: before.chars,
835
+ charsAfter: file.chars,
836
+ truncated: file.truncated,
837
+ prevPath,
838
+ ...(backupError ? { backupError } : {}),
839
+ });
840
+ }
841
+ }
842
+
636
843
  export function loadProjectAnchor(cwd: string): ProjectAnchorResult {
637
844
  const candidates = projectAnchorCandidates(cwd);
638
845
  const cached = _projectAnchorCache.get(cwd);
@@ -649,6 +856,7 @@ export function loadProjectAnchor(cwd: string): ProjectAnchorResult {
649
856
  const after = projectAnchorMtimes(candidates);
650
857
  if (projectAnchorSnapshotsMatch(before, after)) {
651
858
  _projectAnchorCache.set(cwd, { result, candidates: after });
859
+ observeLocalInstructionEdits(cwd, cached?.result, result);
652
860
  observeProjectAnchorLoss(cwd, result);
653
861
  if (debug.enabled) {
654
862
  debug.log('chat.project-anchor', result.content ? 'loaded' : 'empty', {
@@ -709,10 +917,16 @@ export function buildUniversalPreamble(ctx: UniversalPreambleContext): LLMMessag
709
917
  // list reflects what was read), so a project with only CLAUDE.md
710
918
  // doesn't see a misleading AGENTS.md reference.
711
919
  const fileList = result.files.map(f => `\`${f.filename}\``).join(' and ');
920
+ const hasLocal = result.files.some(f => f.local);
712
921
  const header = result.files.length > 0
713
922
  ? (
714
923
  `## Project Anchor — full text of ${fileList} inline below.\n` +
715
- `(Already in context — refer to this text instead of re-reading the file.)\n\n`
924
+ `(Already in context — refer to this text instead of re-reading the file.)\n` +
925
+ (hasLocal
926
+ ? `Directory-local instructions (\`*.local.md\`) come last and are specific to this working directory — they define your role here and take precedence over the shared guide where they differ.\n` +
927
+ `That local file is YOUR OWN instruction file: when you learn a lesson or your role changes, edit it yourself with your file-edit tools (keep sections short; never edit the TUI-owned \`.AGENTS.local.last-session.md\`). Your edits load on the next turn.\n`
928
+ : '') +
929
+ `\n`
716
930
  )
717
931
  : '';
718
932
  out.push({ role: 'system', content: `${header}${result.content}` });
@@ -793,6 +1007,9 @@ export function buildUniversalPreamble(ctx: UniversalPreambleContext): LLMMessag
793
1007
  hasProjectAnchor: result.content !== null,
794
1008
  anchorChars: result.totalChars,
795
1009
  anchorFiles: result.files.map(f => f.filename),
1010
+ // L0 v2 — 층·경로·잘림을 한 줄씩(어느 층이 실렸고 어디서 잘렸나).
1011
+ anchorLayers: result.files.map(f => ({ layer: f.layer ?? null, path: f.path ?? null, chars: f.chars, truncated: f.truncated })),
1012
+ anchorLocalFiles: result.files.filter(f => f.local).map(f => (f.relDir ? `${f.relDir}/${f.filename}` : f.filename)),
796
1013
  anchorSkipped: result.skipped,
797
1014
  hasProjectTree: tree.content !== null,
798
1015
  treeChars: tree.totalChars,
@@ -11,6 +11,7 @@ import { isPtyAccessMode } from './pty-ref.js';
11
11
  import { debug } from '../debug/log.js';
12
12
  import { encodeSgrMouse, mouseModeOffReason, type PtyMouseInput } from './pty-mouse.js';
13
13
  import { startPtyRecording, stopPtyRecording } from './pty-recording.js';
14
+ import { withExternalKeyCommand } from '../input/external-input-queue.js';
14
15
 
15
16
  const OWNER_PTY_CONTROL_ACTIONS = ['takeover', 'release', 'input-text', 'input-key', 'input-mouse', 'resize', 'snapshot', 'rename', 'terminate', 'capabilities', 'record-start', 'record-stop'] as const;
16
17
  export type PtyControlAction = typeof OWNER_PTY_CONTROL_ACTIONS[number];
@@ -412,7 +413,9 @@ async function processPtyControlRequestsOnce(getHandle: (id: string) => PtyContr
412
413
  } else if ((row.action === 'input-text' || row.action === 'input-key') && 'chars' in payload) {
413
414
  // ⛔⭐ 여기서 세지 «않는다» — 계기는 `registry.write`(진짜 초크포인트)에 있다.
414
415
  // 여기서도 세면 크로스-프로세스 쓰기가 **두 번** 세어진다(`[S]` 리뷰 후 이동).
415
- const outcome = writePtyWithOutcome(handle, payload.chars, authorized.actor);
416
+ // `input-key` 는 TUI 외부 입력 대기열(`input/external-input-queue`)을 타지 않는다 — 글이 아니라 키다.
417
+ const write = (): ReturnType<typeof writePtyWithOutcome> => writePtyWithOutcome(handle, payload.chars, authorized.actor);
418
+ const outcome = row.action === 'input-key' ? withExternalKeyCommand(write) : write();
416
419
  result = outcome === 'success'
417
420
  ? { status: 'success' }
418
421
  : outcome === 'denied'
@@ -64,6 +64,8 @@ export interface PtyManifestRow {
64
64
  nickname?: string;
65
65
  cmd: string;
66
66
  workdir?: string;
67
+ purpose?: string;
68
+ seat?: string;
67
69
  ownerPid: number;
68
70
  ptyPid: number;
69
71
  livenessSource?: 'pty-pid' | 'owner-pid';
@@ -96,6 +98,22 @@ export interface PtyManifestRow {
96
98
  externalToolName?: string;
97
99
  closedAt: number;
98
100
  codeSha: string;
101
+ /** TUI 턴 상태 — TUI 가 턴 시작·끝에 스스로 적는다(화면 글자 추정 아님). 없으면 기록 안 하는 행/옛 판. */
102
+ turnState?: PtyTurnState;
103
+ turnAt?: number;
104
+ /** 행 소유 프로세스가 «기동 때» 실은 코드 판 — 트리 HEAD(`codeSha`)와 다른 축이다. */
105
+ build?: PtyBuildIdentity;
106
+ }
107
+
108
+ export type PtyTurnState = 'busy' | 'idle';
109
+ export type PtyBuildSource = 'installed' | 'checkout' | 'unknown';
110
+ export interface PtyBuildIdentity {
111
+ readonly version: string;
112
+ /** 40자 커밋 — 모르면 ''. */
113
+ readonly sha: string;
114
+ readonly source: PtyBuildSource;
115
+ /** 기동한 코드의 뿌리 — checkout 이면 지금 HEAD 와 비교하는 자리. */
116
+ readonly codeRoot?: string;
99
117
  }
100
118
 
101
119
  const SNAPSHOT_TAIL_BYTES = 16 * 1024;
@@ -152,6 +170,8 @@ function db(): Database | null {
152
170
 
153
171
  export function migratePtyManifestSchema(d: Database): void {
154
172
  try { d.run('ALTER TABLE pty_manifest ADD COLUMN nickname TEXT'); } catch { /* already exists */ }
173
+ try { d.run('ALTER TABLE pty_manifest ADD COLUMN purpose TEXT'); } catch { /* already exists */ }
174
+ try { d.run('ALTER TABLE pty_manifest ADD COLUMN seat TEXT'); } catch { /* already exists */ }
155
175
  try { d.run(`ALTER TABLE pty_manifest ADD COLUMN frame TEXT NOT NULL DEFAULT ''`); } catch { /* already exists */ }
156
176
  try { d.run('ALTER TABLE pty_manifest ADD COLUMN frame_at INTEGER NOT NULL DEFAULT 0'); } catch { /* already exists */ }
157
177
  try { d.run(`ALTER TABLE pty_manifest ADD COLUMN run_id TEXT NOT NULL DEFAULT ''`); } catch { /* already exists */ }
@@ -176,6 +196,12 @@ export function migratePtyManifestSchema(d: Database): void {
176
196
  try { d.run('ALTER TABLE pty_manifest ADD COLUMN external_tool_name TEXT'); } catch { /* already exists */ }
177
197
  try { d.run('ALTER TABLE pty_manifest ADD COLUMN output_bytes_total INTEGER NOT NULL DEFAULT 0'); } catch { /* already exists */ }
178
198
  try { d.run('ALTER TABLE pty_manifest ADD COLUMN last_control_at INTEGER'); } catch { /* already exists */ }
199
+ try { d.run('ALTER TABLE pty_manifest ADD COLUMN turn_state TEXT'); } catch { /* already exists */ }
200
+ try { d.run('ALTER TABLE pty_manifest ADD COLUMN turn_at INTEGER'); } catch { /* already exists */ }
201
+ try { d.run('ALTER TABLE pty_manifest ADD COLUMN build_version TEXT'); } catch { /* already exists */ }
202
+ try { d.run('ALTER TABLE pty_manifest ADD COLUMN build_sha TEXT'); } catch { /* already exists */ }
203
+ try { d.run('ALTER TABLE pty_manifest ADD COLUMN build_source TEXT'); } catch { /* already exists */ }
204
+ try { d.run('ALTER TABLE pty_manifest ADD COLUMN build_code_root TEXT'); } catch { /* already exists */ }
179
205
  try { d.run('ALTER TABLE pty_manifest DROP COLUMN chain_depth'); } catch { /* legacy schema has no duplicate column */ }
180
206
  try { d.run('UPDATE pty_manifest SET closed_at=updated_at WHERE alive=0 AND closed_at=0'); } catch { /* fail-soft */ }
181
207
  }
@@ -236,9 +262,12 @@ export function upsertPtyManifest(row: {
236
262
  nickname?: string;
237
263
  cmd: string;
238
264
  workdir?: string;
265
+ purpose?: string;
266
+ seat?: string;
239
267
  startedAt: number;
240
268
  now: number;
241
269
  ptyPid?: number;
270
+ origin?: { originRoot: string; controller?: string };
242
271
  identity?: {
243
272
  spaceId?: string;
244
273
  parentPtyId?: string;
@@ -258,7 +287,10 @@ export function upsertPtyManifest(row: {
258
287
  const chainOrigin = getPtyChainOrigin();
259
288
  const registrarNestDepth = process.env.ELANOUS_NEST_DEPTH === undefined ? undefined : getNestDepth();
260
289
  const nestDepth = row.identity?.nestDepth ?? registrarNestDepth;
261
- const { originRoot, originAgent, originSession, controller } = originObservationFields();
290
+ const observedOrigin = originObservationFields();
291
+ const { originRoot, originAgent, originSession, controller } = row.origin
292
+ ? { originRoot: row.origin.originRoot, originAgent: undefined, originSession: undefined, controller: row.origin.controller }
293
+ : observedOrigin;
262
294
  const terminalOrigin = classifyTerminalOrigin({ originRoot, originAgent, originSession, controller });
263
295
  const codeSha = codeShaForWorkdir(row.workdir);
264
296
  d.run('BEGIN IMMEDIATE');
@@ -281,15 +313,15 @@ export function upsertPtyManifest(row: {
281
313
  : 'process';
282
314
  const shouldRecordSpawned = previous === null || previous.alive === 0;
283
315
  const values = [
284
- row.id, row.kind, row.nickname ?? null, row.cmd, row.workdir ?? null, process.pid, row.ptyPid ?? 0, resolveInstanceName(),
316
+ row.id, row.kind, row.nickname ?? null, row.cmd, row.workdir ?? null, row.purpose ?? null, row.seat ?? null, process.pid, row.ptyPid ?? 0, resolveInstanceName(),
285
317
  runId, runIdSource, spaceId, sessionId, codeSha, parentPtyId, parentPid, parentKind, chainOrigin ?? null, nestDepth ?? null,
286
318
  originRoot ?? null, originAgent ?? null, originSession ?? null, manifestController ?? null, terminalOrigin.category, terminalOrigin.reason,
287
319
  terminalOrigin.externalToolName ?? null, row.startedAt, 1, null, '', 0, row.now,
288
320
  ];
289
321
  d.run(
290
- `INSERT INTO pty_manifest (id, kind, nickname, cmd, workdir, owner_pid, pty_pid, instance, run_id, run_id_source, space_id, session_id, code_sha, parent_pty_id, parent_pid, parent_kind, chain_origin, nest_depth, origin_root, origin_agent, origin_session, controller, terminal_origin_category, terminal_origin_reason, external_tool_name, started_at, alive, exit_code, snapshot, snapshot_at, updated_at)
322
+ `INSERT INTO pty_manifest (id, kind, nickname, cmd, workdir, purpose, seat, owner_pid, pty_pid, instance, run_id, run_id_source, space_id, session_id, code_sha, parent_pty_id, parent_pid, parent_kind, chain_origin, nest_depth, origin_root, origin_agent, origin_session, controller, terminal_origin_category, terminal_origin_reason, external_tool_name, started_at, alive, exit_code, snapshot, snapshot_at, updated_at)
291
323
  VALUES (${values.map(() => '?').join(', ')})
292
- ON CONFLICT(id) DO UPDATE SET kind=excluded.kind, nickname=excluded.nickname, cmd=excluded.cmd, workdir=excluded.workdir,
324
+ ON CONFLICT(id) DO UPDATE SET kind=excluded.kind, nickname=excluded.nickname, cmd=excluded.cmd, workdir=excluded.workdir, purpose=excluded.purpose, seat=excluded.seat,
293
325
  owner_pid=excluded.owner_pid, pty_pid=excluded.pty_pid, instance=excluded.instance,
294
326
  run_id=excluded.run_id, run_id_source=excluded.run_id_source, space_id=excluded.space_id, session_id=excluded.session_id, code_sha=excluded.code_sha,
295
327
  parent_pty_id=excluded.parent_pty_id, parent_pid=excluded.parent_pid, parent_kind=excluded.parent_kind,
@@ -297,13 +329,16 @@ export function upsertPtyManifest(row: {
297
329
  origin_session=excluded.origin_session, controller=excluded.controller, terminal_origin_category=excluded.terminal_origin_category,
298
330
  terminal_origin_reason=excluded.terminal_origin_reason, external_tool_name=excluded.external_tool_name,
299
331
  started_at=excluded.started_at, alive=1, exit_code=NULL,
300
- snapshot='', snapshot_at=0, frame='', frame_at=0, closed_at=0, updated_at=excluded.updated_at`,
332
+ snapshot='', snapshot_at=0, frame='', frame_at=0, closed_at=0, updated_at=excluded.updated_at,
333
+ turn_state=NULL, turn_at=NULL, build_version=NULL, build_sha=NULL, build_source=NULL, build_code_root=NULL`,
301
334
  values,
302
335
  );
303
336
  d.run('COMMIT');
304
337
  if (shouldRecordSpawned) {
305
338
  recordPtyLifecycle('spawned', {
306
339
  id: row.id, kind: row.kind, ...(row.nickname ? { nickname: row.nickname } : {}), cmd: row.cmd,
340
+ ...(row.purpose ? { purpose: row.purpose } : {}),
341
+ ...(row.seat ? { seat: row.seat } : {}),
307
342
  ...(row.workdir ? { workdir: row.workdir } : {}), ownerPid: process.pid, ptyPid: row.ptyPid ?? 0, instance: resolveInstanceName(),
308
343
  startedAt: row.startedAt, alive: true, exitCode: null, snapshot: '', snapshotAt: 0, outputBytesTotal: 0, updatedAt: row.now,
309
344
  frame: '', frameAt: 0, runId, runIdSource, spaceId, sessionId, parentPtyId, parentPid, parentKind,
@@ -375,6 +410,29 @@ export function updatePtyManifestNickname(id: string, nickname: string | undefin
375
410
  } catch { /* fail-soft */ }
376
411
  }
377
412
 
413
+ /** 턴 상태 기록 — 행이 없거나 db 를 못 열면 false(호출자가 관측을 남긴다). */
414
+ export function updatePtyManifestTurn(id: string, turn: PtyTurnState, at: number): boolean {
415
+ try {
416
+ const d = db(); if (!d) return false;
417
+ return d.run('UPDATE pty_manifest SET turn_state=?, turn_at=? WHERE id=?', [turn, at, id]).changes > 0;
418
+ } catch {
419
+ return false;
420
+ }
421
+ }
422
+
423
+ /** 기동 판 기록 — 행 등록 직후 한 번. */
424
+ export function updatePtyManifestBuild(id: string, build: PtyBuildIdentity): boolean {
425
+ try {
426
+ const d = db(); if (!d) return false;
427
+ return d.run(
428
+ 'UPDATE pty_manifest SET build_version=?, build_sha=?, build_source=?, build_code_root=? WHERE id=?',
429
+ [build.version, build.sha, build.source, build.codeRoot ?? null, id],
430
+ ).changes > 0;
431
+ } catch {
432
+ return false;
433
+ }
434
+ }
435
+
378
436
  export function markPtyControlled(id: string, at: number): void {
379
437
  try {
380
438
  const d = db(); if (!d) return;
@@ -781,6 +839,8 @@ function mapRow(r: Record<string, unknown>): PtyManifestRow {
781
839
  ...(r.nickname ? { nickname: String(r.nickname) } : {}),
782
840
  cmd: String(r.cmd),
783
841
  ...(r.workdir ? { workdir: String(r.workdir) } : {}),
842
+ ...(r.purpose ? { purpose: String(r.purpose) } : {}),
843
+ ...(r.seat ? { seat: String(r.seat) } : {}),
784
844
  ownerPid: Number(r.owner_pid),
785
845
  ptyPid: Number(r.pty_pid ?? 0),
786
846
  ...(r.liveness_source === 'pty-pid' || r.liveness_source === 'owner-pid' ? { livenessSource: r.liveness_source } : {}),
@@ -812,6 +872,18 @@ function mapRow(r: Record<string, unknown>): PtyManifestRow {
812
872
  ...(terminalOrigin.externalToolName === undefined ? {} : { externalToolName: terminalOrigin.externalToolName }),
813
873
  closedAt: Number(r.closed_at ?? 0),
814
874
  codeSha: String(r.code_sha ?? ''),
875
+ ...(r.turn_state === 'busy' || r.turn_state === 'idle' ? { turnState: r.turn_state, turnAt: Number(r.turn_at ?? 0) } : {}),
876
+ ...(typeof r.build_sha === 'string' ? { build: mapBuild(r) } : {}),
815
877
  updatedAt: Number(r.updated_at),
816
878
  };
817
879
  }
880
+
881
+ function mapBuild(r: Record<string, unknown>): PtyBuildIdentity {
882
+ const source = r.build_source === 'installed' || r.build_source === 'checkout' ? r.build_source : 'unknown';
883
+ return {
884
+ version: String(r.build_version ?? ''),
885
+ sha: String(r.build_sha ?? ''),
886
+ source,
887
+ ...(typeof r.build_code_root === 'string' && r.build_code_root ? { codeRoot: r.build_code_root } : {}),
888
+ };
889
+ }