elanous 0.2.37 → 0.2.40

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 (727) 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/{8kITumG9GAZ1LwT9POrAR → HjeK7zONHfR7op1hKXp4k}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{1746.3563617ea64023a3.js → 1060.014f1f01a17aec26.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{9151.a2c51e93f9156dae.js → 1281.d81877e35b9068f4.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1350.59f40e39e02d91b1.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +286 -0
  10. package/apps/pwa/out/_next/static/chunks/1537-6bb97b5214928ea9.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +149 -0
  12. package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +90 -0
  14. package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +104 -0
  15. package/apps/pwa/out/_next/static/chunks/{3578.4e9f9948a9a6f2f4.js → 2047.8f23e210995d4548.js} +2 -2
  16. package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/{7424.c0fe2a595d4232b5.js → 2066.a77257c8c350770a.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{4931.95cc6dbd230774ca.js → 2177.df8547f9d7215c4e.js} +16 -16
  20. package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{6680.6a693c28aae4cd19.js → 2226.2cf61ec781827219.js} +2 -2
  22. package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2499.02fbfd18126c10c0.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{6252.240578f10952e091.js → 2522.f2766b76d22c8bdf.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/{1262.a89bb27a5b2f844e.js → 2566.beaffc3a5e1fcd2e.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/261.0d471e8aded799f3.js +226 -0
  27. package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +27 -0
  30. package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{2318-450e75d07605b8fe.js → 2774-719820e3f5b2a3eb.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{4725-34bed25720cc326b.js → 2829-734fe8bf2eee7347.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3330.7443183b7e6fdbdf.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3746-f80a78f220bf37b5.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +24 -0
  45. package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +77 -0
  46. package/apps/pwa/out/_next/static/chunks/{4337e36d.f42c3b391b3d8f20.js → 3b355b3d.6f73c98bf6f9c749.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +36 -0
  48. package/apps/pwa/out/_next/static/chunks/{58edce7d.f1b0c72acf13b123.js → 409c787b.e48c5bec8ec10456.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +287 -0
  52. package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4351.0f37a6db2b34d50b.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{5046.7fd5cbd859299448.js → 470.51a72a2348306455.js} +2 -2
  56. package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/{2375.bf364c85dbb6f085.js → 4769.9fd582071301f382.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{de8446d3.31b73eb239fecd7b.js → 4864a2ca.1c1c280a7772c5e5.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +74 -0
  63. package/apps/pwa/out/_next/static/chunks/{4383.18e5c54db3a22c88.js → 5383.bdfa5d886e39a826.js} +1 -1
  64. package/apps/pwa/out/_next/static/chunks/5436.fdf6fa8ae3e9588d.js +64 -0
  65. package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +8 -0
  70. package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +62 -0
  72. package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +94 -0
  76. package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{6745-5a63492933959dd9.js → 6051-0ae955eedb10adb9.js} +3 -3
  78. package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/{2283.edd9627b7bdfb546.js → 6257.c0037b8949239f5e.js} +2 -2
  80. package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +32 -0
  85. package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{6819.be5c9c4d67f22922.js → 6749.0744ce6eb08d40e9.js} +16 -16
  87. package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +148 -0
  90. package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/6cc1d1d6.9a98dd4622f1afc6.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7219-15bdd9a80661af8e.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +93 -0
  96. package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +24 -0
  100. package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/7611.85f045bf232053ac.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8099.1cccf31c1baa7e1c.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{2002-a43a3f380df873ec.js → 8272-025653884f9645d2.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/{7867.e8725745ddd1d940.js → 8357.1aaa713b052a78b1.js} +4 -4
  110. package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/8d173e38.18a2f7b4e1848bdb.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +41 -0
  115. package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{4313.76f232c304a15bde.js → 9175.2de5209a5ce6f68a.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9184.45afbf44fec87574.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{8c58d09b.e8724a299658d86f.js → 9189505a.980427ac048c8c60.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +79 -0
  123. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ba957ff875a026a0.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live/{page-3337c6a1328c2674.js → page-4edb8df90f4537ce.js} +1 -1
  143. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83d27757e2b8060a.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/morning/{page-1e5da297557d2354.js → page-fca2e59a81744d9e.js} +1 -1
  148. package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/term/{page-ac2c1e6169cfce57.js → page-139d722de1dcd6c1.js} +1 -1
  167. package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workspace/{page-c1c80e345fa9d6f5.js → page-ccde99f07aaf71f7.js} +1 -1
  173. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{d9815f84.4918f682a45a8502.js → b84cad00.594027ebe0531fe2.js} +3 -3
  175. package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{709a918c.4fd3b4e2a32cb4e3.js → ca3702f8.2913182e73889fa2.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/{5f6af561-f90b7a67f4f75d13.js → d8de0de2-dd0f4ac8e5ab1832.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +22 -22
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +22 -22
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +22 -22
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +21 -21
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +21 -21
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +22 -22
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +21 -21
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +22 -22
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +22 -22
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +21 -21
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +22 -22
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +22 -22
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +22 -22
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +22 -22
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +21 -21
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +21 -21
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +22 -22
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +22 -22
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +22 -22
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +21 -21
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +21 -21
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +22 -22
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +22 -22
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +21 -21
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +21 -21
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +21 -21
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +22 -22
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +22 -22
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +21 -21
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +22 -22
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +22 -22
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +22 -22
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +22 -22
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +22 -22
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +21 -21
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +22 -22
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +22 -22
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +22 -22
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +22 -22
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +22 -22
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +22 -22
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +22 -22
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +22 -22
  278. package/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
  279. package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
  280. package/graphs/demo/persona-marketer/recipes.yaml +19 -0
  281. package/graphs/release/recipes.yaml +9 -0
  282. package/graphs/release/release-loop.yaml +26 -18
  283. package/graphs/video/explainer-line.yaml +4 -1
  284. package/package.json +1 -1
  285. package/scripts/ask-op-inbox-once.ts +17 -0
  286. package/scripts/brand/check.ts +13 -4
  287. package/scripts/dead-code/report.ts +169 -0
  288. package/scripts/gate-0226-accepted-remaining-90.txt +91 -0
  289. package/scripts/gate-0226-failure-census.ts +39 -0
  290. package/scripts/intake-collect-telegram-saved-stage.ts +48 -0
  291. package/scripts/lib/morning-report-options.ts +3 -4
  292. package/scripts/lib/tui-regress-evidence.ts +56 -0
  293. package/scripts/morning-report.ts +5 -1
  294. package/scripts/provision-export-redactions.ts +15 -0
  295. package/scripts/public-copy-lint.ts +122 -0
  296. package/scripts/public-export.ts +77 -2
  297. package/scripts/ratchets/next-tui-entry-budget.ts +124 -0
  298. package/scripts/ratchets/train-side-invariants.sh +7 -1
  299. package/scripts/release-loop/cut-branch.ts +61 -12
  300. package/scripts/release-loop/export-check-node.ts +21 -3
  301. package/scripts/release-loop/gate-node.ts +527 -60
  302. package/scripts/release-loop/gate-partial.ts +82 -3
  303. package/scripts/release-loop/gate-prewarm-plan.ts +35 -0
  304. package/scripts/release-loop/gate-radius-live.ts +4 -2
  305. package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
  306. package/scripts/release-loop/gate-shard-receipts.ts +89 -0
  307. package/scripts/release-loop/gate-wall.ts +5 -5
  308. package/scripts/release-loop/preflight.ts +6 -2
  309. package/scripts/release-loop/resume-cap.ts +2 -1
  310. package/scripts/release-loop/resume-release.ts +317 -13
  311. package/scripts/release-loop/resume.ts +61 -5
  312. package/scripts/release-loop/traffic-node.ts +12 -4
  313. package/scripts/release-loop/traffic-transition.ts +53 -13
  314. package/scripts/release-loop/version-node.ts +35 -5
  315. package/scripts/release-story/draft.ts +1 -1
  316. package/scripts/research-bench/README.md +53 -0
  317. package/scripts/research-bench/questions.json +66 -0
  318. package/scripts/research-bench/rubric.md +33 -0
  319. package/scripts/research-bench/run.ts +523 -0
  320. package/scripts/tui-regress.ts +85 -10
  321. package/scripts/ux-sim.ts +1 -1
  322. package/scripts/video-pipeline.ts +2 -2
  323. package/src/acp/core-turn-bridge.ts +14 -1
  324. package/src/agent/autonomous-tools.ts +10 -3
  325. package/src/agent/monad-agent-turn.ts +4 -1
  326. package/src/agent/registry.ts +26 -2
  327. package/src/agent/run-context.ts +1 -1
  328. package/src/agent/shared-app-tools.ts +1 -1
  329. package/src/agent/surface-ux/build.ts +12 -3
  330. package/src/agent/surface-ux/types.ts +1 -1
  331. package/src/agent/task-notification.ts +78 -7
  332. package/src/agent/types.ts +3 -0
  333. package/src/agent-mission/driver.ts +29 -3
  334. package/src/agent-mission/mission-cli.ts +2 -1
  335. package/src/agent-substrate/review-context-pack.ts +365 -0
  336. package/src/agent-substrate/review-observation.ts +10 -0
  337. package/src/agent-substrate/self-review-cli.ts +419 -42
  338. package/src/ask-user-question/index.ts +6 -0
  339. package/src/ask-user-question/inline-resolver.ts +49 -0
  340. package/src/auto-research/question-ladder-contract.ts +156 -0
  341. package/src/auto-research/research-turn.ts +467 -0
  342. package/src/autopilot/agent-loop.ts +1 -1
  343. package/src/autopilot/discovery/doc-lint.ts +1 -1
  344. package/src/autopilot/pty-control-loop.ts +8 -1
  345. package/src/boot/daemon-tools/index.ts +4 -3
  346. package/src/boot/daemon-tools/self-implement.ts +270 -2
  347. package/src/boot/daemon-tools/types.ts +2 -0
  348. package/src/bots/screen-probe.ts +1 -1
  349. package/src/budget/llm-cost.ts +44 -5
  350. package/src/budget/unified-usage.ts +17 -1
  351. package/src/capture/tui-self-report.ts +24 -2
  352. package/src/chat/index.ts +34 -7
  353. package/src/chat/tool-render/dispatch.ts +8 -1
  354. package/src/cli/agent-cli.ts +43 -8
  355. package/src/cli/guardian-cli.ts +3 -1
  356. package/src/cli/intake-cli.ts +70 -13
  357. package/src/cli/lesson-cli.ts +86 -10
  358. package/src/cli/log-event-names.ts +1 -0
  359. package/src/cli/pod-cli.ts +17 -2
  360. package/src/cli/pr-land-overlap-evidence.ts +38 -5
  361. package/src/cli/pr-land-refusal.ts +1 -1
  362. package/src/cli/pty-takeover-cli.ts +125 -12
  363. package/src/cli/release-checklist-read-cli.ts +5 -2
  364. package/src/cli/release-cli.ts +99 -15
  365. package/src/cli/repo-cli.ts +2 -1
  366. package/src/cli/review-carry.ts +77 -0
  367. package/src/cli/self-update.ts +1 -1
  368. package/src/cli/tasks-card-show.ts +31 -1
  369. package/src/cli/tasks-cli.ts +98 -32
  370. package/src/cli/tasks-read-cli.ts +13 -5
  371. package/src/context-bus/context-now.ts +86 -2
  372. package/src/control-plane/ledger.ts +21 -4
  373. package/src/core-turn/run-core-turn.ts +51 -3
  374. package/src/core-turn/run-goal-loop.ts +152 -8
  375. package/src/core-turn/types.ts +12 -0
  376. package/src/dashboard/chat/acp-chat.ts +2 -2
  377. package/src/dashboard/classic-sigquit.ts +16 -0
  378. package/src/dashboard/index.ts +339 -44
  379. package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
  380. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
  381. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  382. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  383. package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
  384. package/src/dashboard/input/external-input-host.ts +2 -0
  385. package/src/dashboard/input/terminal-modal-router.ts +8 -159
  386. package/src/dashboard/side-basic-runtime.ts +61 -0
  387. package/src/dashboard/sidetab-runtime.ts +228 -0
  388. package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
  389. package/src/dashboard/slash-runtime/dashboard-handlers.ts +22 -8
  390. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
  391. package/src/dashboard/term-slash-runtime.ts +18 -18
  392. package/src/dashboard/turn-preamble.ts +30 -4
  393. package/src/domains/guardian-tick.ts +9 -0
  394. package/src/domains/knowledge.ts +1 -1
  395. package/src/esc-abort-gate.ts +33 -1
  396. package/src/execution-loop/launch-gate.ts +206 -1
  397. package/src/git-fs/watcher.ts +27 -22
  398. package/src/git-fs/worktree.ts +19 -3
  399. package/src/graph-runner/graph-cli.ts +6 -4
  400. package/src/graph-runner/graph-grow.ts +37 -9
  401. package/src/graph-runner/runner.ts +48 -11
  402. package/src/graph-wizard/generate.ts +16 -7
  403. package/src/graph-wizard/mission-compose.ts +201 -0
  404. package/src/grok/agent-search.ts +8 -2
  405. package/src/grok/credential.ts +112 -36
  406. package/src/grounding/ref-index.ts +11 -0
  407. package/src/grounding/ref-vector.ts +61 -0
  408. package/src/grounding/sources-cli.ts +2 -2
  409. package/src/grounding/sources.ts +15 -1
  410. package/src/harness/harness-cli-command.ts +38 -9
  411. package/src/harness/harness-pod-dispatch.ts +7 -1
  412. package/src/hq/fence-wrapper.ts +1 -1
  413. package/src/hq/transfer.ts +1 -1
  414. package/src/index.ts +60 -16
  415. package/src/input/external-input-queue.ts +10 -0
  416. package/src/intake-plane/collect-telegram-saved.ts +90 -6
  417. package/src/intake-plane/intake-to-tasks.ts +246 -3
  418. package/src/interactive-terminal-modal.ts +3 -0
  419. package/src/keybindings.ts +17 -22
  420. package/src/lessons/friction-ledger.ts +154 -0
  421. package/src/live-supply/collector.ts +149 -0
  422. package/src/live-supply/probes.ts +52 -0
  423. package/src/live-supply/snapshot.ts +40 -0
  424. package/src/llm/provider-credentials.ts +1 -1
  425. package/src/llm-tool-schema.ts +20 -0
  426. package/src/llm.ts +486 -61
  427. package/src/loops/orchestrator/inbox-once.ts +28 -0
  428. package/src/loops/orchestrator/inbox.ts +130 -1
  429. package/src/loops/orchestrator/tick.ts +14 -3
  430. package/src/maturity/feature-maturity.ts +1 -0
  431. package/src/nexus/api/channel-ask-op.ts +96 -0
  432. package/src/nexus/api/discord-trigger-bot.ts +28 -1
  433. package/src/nexus/api/harness-api.ts +2 -1
  434. package/src/nexus/api/telegram-trigger-bot.ts +24 -0
  435. package/src/nexus/api/terminals.ts +28 -6
  436. package/src/patents/ledger.ts +18 -1
  437. package/src/preview/terminal.ts +4 -2
  438. package/src/prompt-cache/anthropic.ts +2 -0
  439. package/src/prompt-enhance/enhance.ts +5 -0
  440. package/src/pty/snapshot.py +132 -0
  441. package/src/pty-shell/pty-control-ipc.ts +29 -2
  442. package/src/pty-shell/pty-manifest.ts +75 -5
  443. package/src/pty-shell/registry.ts +2 -0
  444. package/src/pty-shell/tui-run-state.ts +80 -3
  445. package/src/release-loop/gate-host-reservation.ts +13 -4
  446. package/src/release-loop/gate-shard-ledger.ts +68 -0
  447. package/src/release-loop/gate-shards.ts +61 -0
  448. package/src/release-loop/light-rc.ts +7 -4
  449. package/src/release-loop/merged-pr-checklist.ts +25 -2
  450. package/src/release-loop/rehearsal-shard-plan.ts +6 -1
  451. package/src/release-loop/rehearsal.ts +28 -1
  452. package/src/repl/index.ts +10 -0
  453. package/src/research/axis-fanout.ts +133 -0
  454. package/src/research/edge-decision.ts +197 -0
  455. package/src/research/gap-followup.ts +249 -0
  456. package/src/research/lenses/counter-evidence.ts +100 -0
  457. package/src/research/lenses/working-backwards.ts +89 -0
  458. package/src/research/output-router.ts +127 -0
  459. package/src/research/plugin-discovery.ts +242 -0
  460. package/src/research-bridge/format.ts +16 -1
  461. package/src/research-bridge/index.ts +1 -0
  462. package/src/research-bridge/invoke.ts +45 -7
  463. package/src/research-bridge/types.ts +2 -0
  464. package/src/self-dev/ask-launch-flow.ts +34 -106
  465. package/src/self-dev/decompose.ts +45 -9
  466. package/src/self-dev/dev-cli.ts +2 -0
  467. package/src/self-dev/dev-pipeline.ts +8 -4
  468. package/src/self-dev/draft-residue.ts +221 -2
  469. package/src/self-dev/draft-sweep.ts +29 -16
  470. package/src/self-dev/graph-journey-route.ts +10 -2
  471. package/src/self-dev/launch-preflight-text.ts +2 -2
  472. package/src/self-dev/launch-preflight.ts +38 -7
  473. package/src/self-dev/orchestrate-cli.ts +1 -0
  474. package/src/self-dev/orchestrate.ts +1 -0
  475. package/src/self-dev/run-supervisor.ts +41 -7
  476. package/src/self-dev/shard-run.ts +260 -3
  477. package/src/self-implement/comment-only-source.ts +54 -0
  478. package/src/self-implement/device-first.ts +8 -2
  479. package/src/self-implement/doctor-visit.ts +100 -57
  480. package/src/self-implement/gate-artifacts.ts +5 -2
  481. package/src/self-implement/gate-baseline.ts +119 -13
  482. package/src/self-implement/gate-cli.ts +466 -93
  483. package/src/self-implement/gate-failure-signature.ts +44 -0
  484. package/src/self-implement/gate-receipt-registry.ts +180 -0
  485. package/src/self-implement/gate-remote.ts +147 -22
  486. package/src/self-implement/goal-author-clarification.ts +178 -24
  487. package/src/self-implement/goal-author-decompose.ts +24 -15
  488. package/src/self-implement/goal-author.ts +82 -7
  489. package/src/self-implement/goal-doc/section.ts +22 -0
  490. package/src/self-implement/goal-supervisor-fill.ts +38 -4
  491. package/src/self-implement/host-regate.ts +120 -45
  492. package/src/self-implement/impl-findings-feedback.ts +188 -0
  493. package/src/self-implement/knowhow-pack.ts +301 -9
  494. package/src/self-implement/l8-merge-queue.ts +198 -32
  495. package/src/self-implement/off-diff-evidence.ts +147 -0
  496. package/src/self-implement/orchestrator.ts +137 -16
  497. package/src/self-implement/pod-inplace-worktree.ts +82 -0
  498. package/src/self-implement/pod-warm-pool-profile.ts +2 -2
  499. package/src/self-implement/premise-review.ts +7 -5
  500. package/src/self-implement/run-ledger.ts +304 -8
  501. package/src/self-implement/run-stop.ts +12 -0
  502. package/src/self-implement/seams.ts +39 -13
  503. package/src/self-implement/self-implement-cli.ts +30 -4
  504. package/src/session/channel-ask-op-envelope.ts +36 -0
  505. package/src/session/channel-op-reply-route.ts +200 -0
  506. package/src/session/chat.ts +92 -15
  507. package/src/session/index.ts +2 -0
  508. package/src/session-runtime/index.ts +9 -22
  509. package/src/session-runtime/provider-circuit.ts +140 -0
  510. package/src/shell-runner/file-engine.ts +1 -0
  511. package/src/shell-runner/types.ts +4 -0
  512. package/src/sidetab-core/model.ts +176 -0
  513. package/src/skills/runner.ts +7 -3
  514. package/src/skills/tools/dev-harness.ts +2 -2
  515. package/src/skills/tools/schedule-wakeup.ts +24 -7
  516. package/src/skills/tools/shell.ts +51 -5
  517. package/src/status/bar.ts +3 -3
  518. package/src/steward/directive-audit.ts +354 -0
  519. package/src/storage/file-lock.ts +17 -4
  520. package/src/surface/child-process.ts +31 -0
  521. package/src/surface/tui-stderr-owner.ts +48 -0
  522. package/src/task-agent/adopt-pr.ts +63 -2
  523. package/src/task-agent/cover.ts +30 -12
  524. package/src/task-agent/evidence-command-normalize.ts +42 -0
  525. package/src/task-agent/export-redactions-provision.ts +43 -0
  526. package/src/task-agent/judge.ts +56 -0
  527. package/src/task-agent/parent-host.ts +59 -12
  528. package/src/task-agent/postland-card.ts +35 -2
  529. package/src/task-agent/rejudge-on-head.ts +46 -2
  530. package/src/task-agent/repair-cycle.ts +68 -9
  531. package/src/task-agent/repair-worker.ts +37 -1
  532. package/src/task-agent/task-hand.ts +226 -33
  533. package/src/task-agent/tier-split.ts +142 -24
  534. package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
  535. package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
  536. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +57 -5
  537. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
  538. package/src/task-orchestrator/surfaces/pod-pool.ts +27 -4
  539. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
  540. package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
  541. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
  542. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
  543. package/src/task-orchestrator/surfaces/self-implement-pod.ts +310 -79
  544. package/src/task-orchestrator/surfaces/self-implement.ts +33 -2
  545. package/src/terminal/session-registry.ts +1 -0
  546. package/src/terminal/terminal-modal-router.ts +156 -0
  547. package/src/tool-hints/gate.ts +6 -4
  548. package/src/tool-hints/signals.ts +33 -1
  549. package/src/tool-runtime/skill-exec-runtime.ts +95 -5
  550. package/src/tui/chat/background-job-status.ts +8 -2
  551. package/src/tui/entry.ts +483 -32
  552. package/src/tui/inline-choice.ts +188 -0
  553. package/src/tui/sidetab/attach.ts +304 -0
  554. package/src/tui/sidetab/list.ts +2 -0
  555. package/src/tui/sidetab/nl-tool.ts +136 -0
  556. package/src/tui/slash/resume-command.ts +23 -0
  557. package/src/tui/slash/resume.ts +3 -23
  558. package/src/tui/slash/term-next.ts +2 -1
  559. package/src/tui/slash/term.ts +12 -1
  560. package/src/tui-client/dashboard-session.ts +7 -1
  561. package/src/tui-client/local-chat-turn.ts +29 -8
  562. package/src/user-config.ts +42 -3
  563. package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
  564. package/src/ux-sim/fake-land-queue.ts +88 -0
  565. package/src/ux-sim/fake-llm.ts +11 -5
  566. package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
  567. package/src/ux-sim/goal-interim-trace.ts +24 -0
  568. package/src/ux-sim/next-tui-seat-scenarios.ts +61 -14
  569. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
  570. package/src/version/packed-revision.json +1 -1
  571. package/src/video-pipeline/recipes/explainer.ts +54 -2
  572. package/src/web-search/grok.ts +32 -6
  573. package/src/web-search/index.ts +8 -7
  574. package/src/workflow-runtime/node-catalog.ts +53 -4
  575. package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +0 -62
  579. package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/1ed5e8af.cf424815c7c0efad.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/210.90b2cbd64926cf34.js +0 -32
  587. package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +0 -148
  590. package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +0 -27
  594. package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/3199.6a1a9b0e6cd01dc6.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +0 -36
  601. package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +0 -90
  603. package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +0 -226
  604. package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +0 -287
  605. package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/4833-7934c592c5569f00.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +0 -24
  612. package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +0 -104
  615. package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +0 -93
  622. package/apps/pwa/out/_next/static/chunks/5952.294fc574a8625184.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +0 -74
  624. package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +0 -149
  627. package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +0 -41
  631. package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +0 -24
  634. package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/7c5ed21f-f286708e57cf88f7.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +0 -8
  647. package/apps/pwa/out/_next/static/chunks/8080-40d781e7704d3671.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +0 -77
  649. package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +0 -286
  652. package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +0 -79
  656. package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +0 -94
  664. package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +0 -64
  666. package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-88a1edbff62eaf1d.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/outputs/page-443364c9e4a23b31.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +0 -1
  725. package/scripts/migrate-monad-to-elanous.ts +0 -195
  726. package/scripts/rebrand-elanous.ts +0 -242
  727. /package/apps/pwa/out/_next/static/{8kITumG9GAZ1LwT9POrAR → HjeK7zONHfR7op1hKXp4k}/_ssgManifest.js +0 -0
@@ -0,0 +1,28 @@
1
+ import { join } from 'node:path';
2
+ import { effectiveInstanceRoot } from '../../instance/resolve.js';
3
+ import { resolveConfiguredAgentRoleLlm } from '../../user-config.js';
4
+ import type { RoleLlmSpec } from '../../user-config.js';
5
+ import { loadAgentRolePack } from '../agent-reply.js';
6
+ import type { MsgStore } from '../../msg/msg-store.js';
7
+ import { runAskOpContextInbox, runCoordinatorAgentInbox, type CoordinatorInboxResult } from './inbox.js';
8
+ import type { AskOpContextBundle } from '../../context-bus/context-now.js';
9
+
10
+ export interface InboxOnceOptions {
11
+ root?: string;
12
+ store?: MsgStore;
13
+ role?: RoleLlmSpec | null;
14
+ limit?: number;
15
+ context?: (question: string, options: { audience?: string; limit?: number }) => Promise<AskOpContextBundle>;
16
+ }
17
+
18
+ /** One scan of the same durable inbox as the orchestrator tick, without running its graph. */
19
+ export async function runCoordinatorInboxOnce(options: InboxOnceOptions = {}): Promise<CoordinatorInboxResult> {
20
+ const root = options.root ?? effectiveInstanceRoot();
21
+ const path = join(root, 'msg', 'messages.db');
22
+ const role = options.role === undefined ? resolveConfiguredAgentRoleLlm('coordinator') : options.role;
23
+ if (role) return runCoordinatorAgentInbox({ role, pack: loadAgentRolePack('coordinator'), root, path,
24
+ limit: options.limit ?? 100, ...(options.store ? { store: options.store } : {}) });
25
+ return runAskOpContextInbox({ path, limit: options.limit ?? 100,
26
+ ...(options.store ? { store: options.store } : {}),
27
+ ...(options.context ? { context: options.context } : {}) });
28
+ }
@@ -1,15 +1,90 @@
1
+ import { ASK_OP_COMMAND } from '../../session/channel-ask-op-envelope.js';
1
2
  import { openMsgStore, type Message, type MsgStore } from '../../msg/msg-store.js';
2
3
  import { classifySeatTrafficProposal } from '../../seat-loop/traffic-signal.js';
3
- import { debug } from '../../debug/log.js';
4
+ import { debug, redactSecretText } from '../../debug/log.js';
4
5
  import { LOOP_MESSAGE_ROUTES } from '../msg-address.js';
5
6
  import { replyWithAgent, type AgentReplyInput } from '../agent-reply.js';
6
7
  import { knowhowAdvice, type KnowhowAdvice, type KnowhowOptions } from './knowhow-pack.js';
7
8
  import type { RoleLlmSpec } from '../../user-config.js';
8
9
  import type { LLMProvider } from '../../llm.js';
10
+ import { askOpContextBundle, type AskOpContextBundle } from '../../context-bus/context-now.js';
9
11
 
10
12
  const RECIPIENT = LOOP_MESSAGE_ROUTES.orchestrator.msgAddress;
11
13
 
12
14
  export interface CoordinatorInboxResult { replied: number; acknowledged: number }
15
+ export interface AskOpTestHarness {
16
+ /** A test-only sink; this never defaults to a real surface transport. */
17
+ replySink: (reply: { from: string; to: string; body: string; kind: 'reply'; replyTo: number }) => Message;
18
+ /** Capture both clocks without writing to the production log store in tests. */
19
+ eventSink?: (event: { requestId: number; requestToReplyMs: number | null; processingMs: number }) => void;
20
+ }
21
+ export interface AskOpContextInboxOptions {
22
+ store?: MsgStore;
23
+ path?: string;
24
+ limit?: number;
25
+ context?: typeof askOpContextBundle;
26
+ knowhow?: KnowhowOptions | false;
27
+ /** Only the ordered tick scan may advance the durable cursor. */
28
+ acknowledge?: boolean;
29
+ /** SSE delivery handles exactly its message; the ordered tick scans the cursor. */
30
+ request?: Message;
31
+ /** Explicit opt-in for synthetic TEST ASK-OP questions only. Production callers must omit this. */
32
+ testHarness?: AskOpTestHarness;
33
+ }
34
+
35
+ const ASK_OP_SENDERS = new Set(['TELEGRAM', 'DISCORD']);
36
+ const REFUSE = '모름 — 확인된 근거가 없어 답할 수 없습니다.';
37
+
38
+ function isAskOpRequest(request: Message, allowTestSource = false): boolean {
39
+ const testSource = allowTestSource && request.from === 'TEST'
40
+ && /^Test \/(?:askop|ask-op)(?:\r?\n|$)/.test(request.body);
41
+ return request.kind === 'question' && (ASK_OP_SENDERS.has(request.from) || testSource)
42
+ && (testSource || new RegExp(`^(?:Telegram|Discord) \/(?:${ASK_OP_COMMAND}|ask-op)(?:\\r?\\n|$)`).test(request.body));
43
+ }
44
+
45
+ function askOpLatencyMs(request: Message, repliedAt: number): number | null {
46
+ const createdAt = Date.parse(request.createdAt);
47
+ const latencyMs = repliedAt - createdAt;
48
+ return Number.isFinite(createdAt) && latencyMs >= 0 ? latencyMs : null;
49
+ }
50
+
51
+ function writeAskOpReply(store: MsgStore, request: Message, replyText: string, options: AskOpContextInboxOptions) {
52
+ if (options.testHarness && request.from === 'TEST') {
53
+ const marker = `re #${request.id}\n`;
54
+ const body = replyText.startsWith(marker) ? replyText.slice(marker.length) : replyText;
55
+ const reply = options.testHarness.replySink({ from: RECIPIENT, to: request.from,
56
+ body, kind: 'reply', replyTo: request.id });
57
+ return { id: reply.id, posted: true };
58
+ }
59
+ return writeCoordinatorReply(store, request, replyText);
60
+ }
61
+
62
+ function askOpQuestion(request: Message): string {
63
+ const match = /^question: (.*)$/m.exec(request.body);
64
+ return match?.[1]?.trim() ?? '';
65
+ }
66
+
67
+ function unsafeAskOp(question: string): boolean {
68
+ // Reject explicit commands, not descriptive questions such as "What changed since the release?".
69
+ return /^(?:(?:please|can you|could you|would you)\s+)?(?:run|execute|deploy|publish|push|merge|delete|drop|write|edit|change|set)\b|(?:실행해|발행해|배포해|푸시해|병합해|삭제해|수정해|바꿔|설정해)(?:줘|주세요)?|\b(?:show|reveal|give|tell|display|print|read|open|what is|what's)\b.{0,80}\b(?:secret|token|password|credential|api[ -]?key|private[ -]?key)\b|(?:비밀|토큰|암호|패스워드|인증키|API\s*키).{0,80}(?:보여|알려|공개|읽어)/i.test(question);
70
+ }
71
+
72
+ async function askOpAnswer(request: Message, options: AskOpContextInboxOptions): Promise<string> {
73
+ const question = askOpQuestion(request);
74
+ if (!question) return `제안: ${REFUSE}\n근거: 질문이 비었습니다.`;
75
+ if (unsafeAskOp(question)) return '제안: 요청한 권한 실행·비밀 조회·traffic/칸 변경은 실행할 수 없습니다.\n근거: OP 질문 답변은 읽기 전용입니다.';
76
+ let bundle: AskOpContextBundle;
77
+ // These replies are delivered to an external channel, not the private operator console.
78
+ try { bundle = await (options.context ?? askOpContextBundle)(question, { audience: 'public-demo', limit: 8 }); }
79
+ catch { return `제안: ${REFUSE}\n근거: 맥락 조회 실패.`; }
80
+ const facts = bundle.facts.filter(fact => fact.source?.trim() && fact.summary?.trim()).slice(0, 8);
81
+ if (!facts.length) {
82
+ const gaps = bundle.gaps.slice(0, 3).map(gap => `${redactSecretText(gap.kind)}: ${redactSecretText(gap.reason)}`).join('; ');
83
+ return `제안: ${REFUSE}\n근거: ${gaps || '미관측'}.`;
84
+ }
85
+ const evidence = facts.map(fact => `- ${redactSecretText(fact.summary)} — ${redactSecretText(fact.source)} (관측 ${redactSecretText(fact.observedAt)})`).join('\n');
86
+ return `제안: 다음은 관측된 OP 맥락입니다 (${redactSecretText(bundle.topic)}; 조회 ${redactSecretText(bundle.queriedAt)}).\n근거:\n${evidence}\n판단·승인·실행은 하지 않았습니다.`;
87
+ }
13
88
  export interface CoordinatorAgentInboxOptions {
14
89
  role: RoleLlmSpec;
15
90
  pack: string;
@@ -95,6 +170,57 @@ function writeCoordinatorReply(store: MsgStore, request: Message, replyText: str
95
170
  return { id: reply.id, posted: true };
96
171
  }
97
172
 
173
+ /** Surface ask-op questions use the same linked reply and durable acknowledgement as the resident inbox. */
174
+ export async function runAskOpContextInbox(options: AskOpContextInboxOptions = {}): Promise<CoordinatorInboxResult> {
175
+ const store = options.store ?? openMsgStore(options.path);
176
+ const ownStore = options.store === undefined;
177
+ const result = { replied: 0, acknowledged: 0 };
178
+ const acknowledge = options.acknowledge !== false;
179
+ try {
180
+ const requests = options.request ? [options.request]
181
+ : store.listByRecipient(RECIPIENT, store.getCursor(RECIPIENT), options.limit ?? 100);
182
+ for (const request of requests) {
183
+ if (request.to !== RECIPIENT || request.from === RECIPIENT ||
184
+ (request.kind !== undefined && request.kind !== 'request' && request.kind !== 'question')) {
185
+ if (acknowledge) { store.ack(RECIPIENT, request.id); result.acknowledged++; }
186
+ continue;
187
+ }
188
+ const testAskOp = request.from === 'TEST' && isAskOpRequest(request, true);
189
+ if (testAskOp && !options.testHarness) continue;
190
+ const key = `coord-inbox:${request.id}:${request.from}`;
191
+ const existing = store.db.query('SELECT message_id FROM msg_provenance WHERE provenance_key = ?')
192
+ .get(key) as { message_id: number } | null;
193
+ // Legacy seat traffic and knowhow requests preserve the existing answer path.
194
+ const startedAt = Date.now();
195
+ const replyText = existing ? '' : (isAskOpRequest(request, options.testHarness !== undefined)
196
+ ? `re #${request.id}\n${await askOpAnswer(request, options)}` : coordinatorReply(request, options.knowhow ?? {}));
197
+ const one = store.db.transaction(() => {
198
+ const receipt = store.db.query('SELECT message_id FROM msg_provenance WHERE provenance_key = ?')
199
+ .get(key) as { message_id: number } | null;
200
+ const reply = receipt ? { id: receipt.message_id, posted: false } : writeAskOpReply(store, request, replyText, options);
201
+ if (!receipt) store.db.query('INSERT INTO msg_provenance(provenance_key, message_id) VALUES (?, ?)').run(key, reply.id);
202
+ if (acknowledge) store.ack(RECIPIENT, request.id);
203
+ return reply.posted;
204
+ }).immediate();
205
+ if (one) result.replied++;
206
+ if (acknowledge) result.acknowledged++;
207
+ debug.log('loop.coordinator-inbox', 'reply', { requestId: request.id, recipient: request.from, duplicate: !one });
208
+ if (one && isAskOpRequest(request, options.testHarness !== undefined)) {
209
+ const repliedAt = Date.now();
210
+ const latencyMs = askOpLatencyMs(request, repliedAt);
211
+ const processingMs = Math.max(0, repliedAt - startedAt);
212
+ if (options.testHarness && request.from === 'TEST') {
213
+ options.testHarness.eventSink?.({ requestId: request.id, requestToReplyMs: latencyMs, processingMs });
214
+ } else {
215
+ debug.log('ask-op.inbox', 'replied', { requestId: request.id, requestToReplyMs: latencyMs,
216
+ processingMs, clockSkew: latencyMs === null });
217
+ }
218
+ }
219
+ }
220
+ return result;
221
+ } finally { if (ownStore) store.close(); }
222
+ }
223
+
98
224
  /** One transaction ties a reply to its acknowledgement. A retry finds the durable receipt. */
99
225
  export function runCoordinatorInbox(inputStore?: MsgStore, limit = 100, path?: string,
100
226
  options: CoordinatorInboxOptions = {}): CoordinatorInboxResult {
@@ -144,6 +270,9 @@ export async function handleCoordinatorAgentMessage(
144
270
  const ownStore = input.store === undefined;
145
271
  const acknowledge = input.acknowledge === true;
146
272
  try {
273
+ if (isAskOpRequest(request) && request.to === RECIPIENT) {
274
+ return await runAskOpContextInbox({ store, request, acknowledge });
275
+ }
147
276
  if (request.to !== RECIPIENT || request.from === RECIPIENT ||
148
277
  (request.kind !== undefined && request.kind !== 'request' && request.kind !== 'question')) {
149
278
  if (acknowledge) store.ack(RECIPIENT, request.id);
@@ -6,6 +6,7 @@ import { Database } from 'bun:sqlite';
6
6
  import { checklistDevVersion, listChecklist, type ChecklistItem } from '../../release-loop/checklist.js';
7
7
  import { readTrafficSignal } from '../../seat-loop/traffic-signal.js';
8
8
  import { runHoldHygiene, type HygieneCell, type HygieneDeps } from '../../steward/hold-hygiene.js';
9
+ import { runDirectiveAudit, type DirectiveAuditDeps } from '../../steward/directive-audit.js';
9
10
  import { effectiveInstanceRoot } from '../../instance/resolve.js';
10
11
  import { getUserConfig, ORCHESTRATOR_DEFAULTS, resolveConfiguredAgentRoleLlm, type OrchestratorLoopConfig } from '../../user-config.js';
11
12
  import { rubricPriority } from '../../release-loop/rubric.js';
@@ -25,7 +26,7 @@ import * as testGuard from '../../instance/test-write-guard.js';
25
26
  import { seatCapDetails } from '../budget.js';
26
27
  export { isLaunchEligible } from './traffic.js';
27
28
  import { readTaskAgentState, TASK_SEATS, type HandTaskOptions, type TaskCard as TaskAgentCard, type HandTaskResult, type TaskLauncher, type TaskSeat } from '../../task-agent/task-hand.js';
28
- import { runCoordinatorAgentInbox, runCoordinatorInbox, type CoordinatorInboxResult } from './inbox.js';
29
+ import { runAskOpContextInbox, runCoordinatorAgentInbox, type CoordinatorInboxResult } from './inbox.js';
29
30
  import type { KnowhowOptions } from './knowhow-pack.js';
30
31
  import { loadAgentRolePack, type AgentReplyInput } from '../agent-reply.js';
31
32
  import type { LLMProvider } from '../../llm.js';
@@ -70,6 +71,7 @@ export interface TickDeps {
70
71
  heartbeatIntervalMs?: number;
71
72
  hygieneCells?: () => HygieneCell[];
72
73
  hygienePaths?: Pick<HygieneDeps, 'trafficPath' | 'metaPath' | 'dispatcherDir'>;
74
+ directiveAudit?: DirectiveAuditDeps;
73
75
  cards?: () => TaskCard[]; split?: SplitAdapter; placeCell?: PlaceAdapter;
74
76
  degradation?: () => { llm: boolean; board: boolean };
75
77
  gridHosts?: readonly GridHost[];
@@ -97,6 +99,8 @@ export interface TickDeps {
97
99
  coordinatorAgentProvider?: LLMProvider;
98
100
  /** Resident knowhow pack seam; the real intake reads 내부 문서 `KNOWHOW` every tick. */
99
101
  coordinatorKnowhow?: KnowhowOptions | false;
102
+ /** Deterministic read-only ask-op context seam for isolated tick tests. */
103
+ coordinatorContext?: typeof import('../../context-bus/context-now.js').askOpContextBundle;
100
104
  }
101
105
 
102
106
  /** ORCH-TA-HAND ledger — one row per handed `orch:<card>:<cell>` key so a cell is handed once across ticks and processes. */
@@ -521,8 +525,9 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
521
525
  ? runCoordinatorAgentInbox({ role, pack: loadAgentRolePack('coordinator'), path: inboxPath, root,
522
526
  ...(deps.coordinatorAgentRun ? { runAgent: deps.coordinatorAgentRun } : {}),
523
527
  ...(deps.coordinatorAgentProvider ? { provider: deps.coordinatorAgentProvider } : {}) })
524
- : runCoordinatorInbox(undefined, 100, inboxPath,
525
- deps.coordinatorKnowhow === undefined ? {} : { knowhow: deps.coordinatorKnowhow });
528
+ : runAskOpContextInbox({ path: inboxPath, limit: 100,
529
+ ...(deps.coordinatorKnowhow === undefined ? {} : { knowhow: deps.coordinatorKnowhow }),
530
+ ...(deps.coordinatorContext ? { context: deps.coordinatorContext } : {}) });
526
531
  }))();
527
532
  if (inbox.replied || inbox.acknowledged) {
528
533
  observe('exchange', 'coordinator-inbox-replied', inbox.replied);
@@ -957,6 +962,12 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
957
962
  const sent = runHoldHygiene({ root, now, cells, ...deps.hygienePaths });
958
963
  for (const notice of sent) observe('exchange', `hold-hygiene:${notice.key}`, 1, SEAT_LOOP_IDS[notice.to]);
959
964
  } catch (error) { observe('hold-hygiene-failed', String(error).slice(0, 160), 0); }
965
+ // COORD-DIRECTIVE-AUDIT — 지시 원장 행마다 로직 점검(원장·로그·config)을 실제로 돌린다.
966
+ try {
967
+ const audit = runDirectiveAudit({ root, now: currentTime, ...deps.directiveAudit });
968
+ if (audit.alerts.length > 0) observe('directive-audit', `alerts:${audit.alerts.length}`, audit.alerts.length);
969
+ for (const proposal of audit.proposals) observe('directive-audit', `repair-proposal:${proposal.id}`, 1);
970
+ } catch (error) { observe('directive-audit-failed', String(error).slice(0, 160), 0); }
960
971
  }
961
972
  (deps.print ?? console.log)(reportLine(state));
962
973
  }
@@ -137,6 +137,7 @@ export const FEATURE_MATURITY = {
137
137
  tablet: 'ops',
138
138
  surface: 'ops',
139
139
  term: 'tool',
140
+ side: 'tool',
140
141
  claude: 'tool',
141
142
  codex: 'tool',
142
143
  gemini: 'tool',
@@ -0,0 +1,96 @@
1
+ import type { Message, MessageEnvelope } from '../../msg/msg-store.js';
2
+ import type { TgSlashCommand } from '../../telegram-commands.js';
3
+ import { ASK_OP_COMMAND, formatAskOpQuestionEnvelope } from '../../session/channel-ask-op-envelope.js';
4
+
5
+ export interface AskOpTelegramOptions {
6
+ allowedUserIds: readonly number[];
7
+ append: (message: MessageEnvelope, provenanceKey: string) => Message;
8
+ }
9
+
10
+ export interface AskOpDiscordOptions {
11
+ allowedUserIds: readonly string[];
12
+ allowedChannelIds: readonly string[];
13
+ resolveBotId: () => Promise<string>;
14
+ append: (message: MessageEnvelope, provenanceKey: string) => Message;
15
+ }
16
+
17
+ export interface AskOpDiscordContext {
18
+ userId: string;
19
+ channelId: string;
20
+ messageId: string;
21
+ text: string;
22
+ }
23
+
24
+ function appendAskOpQuestion(
25
+ options: { append: AskOpTelegramOptions['append'] },
26
+ input: { from: 'TELEGRAM' | 'DISCORD'; surface: string; correlation: string[]; question: string; provenanceKey: string },
27
+ ): Message {
28
+ return options.append({
29
+ from: input.from,
30
+ to: 'COORDINATOR',
31
+ kind: 'question',
32
+ body: [`${input.surface} /${ASK_OP_COMMAND}`, ...input.correlation, `question: ${input.question}`].join('\n'),
33
+ }, input.provenanceKey);
34
+ }
35
+
36
+ function extractQuestion(text: string): string | null {
37
+ const match = new RegExp(`^/(?:${ASK_OP_COMMAND}|ask-op)(?:@[-_a-z0-9]+)?(?:\\s+([\\s\\S]*))?$`, 'i').exec(text.trim());
38
+ const question = match?.[1]?.trim();
39
+ return question || null;
40
+ }
41
+
42
+ export function createAskOpTelegramSlashCommand(options: AskOpTelegramOptions): TgSlashCommand {
43
+ return {
44
+ name: ASK_OP_COMMAND,
45
+ description: '운영 책임자에게 질문을 보냅니다',
46
+ handler: async (_args, ctx) => {
47
+ if (!options.allowedUserIds.includes(ctx.userId)) return '허용된 사용자만 OP에게 질문할 수 있습니다.';
48
+ const question = extractQuestion(ctx.text);
49
+ if (!question) return `사용법: /${ASK_OP_COMMAND} <질문>`;
50
+ if (!Number.isSafeInteger(ctx.updateId) || ctx.updateId < 0) return 'Telegram update 식별값을 확인할 수 없어 질문을 저장하지 못했습니다.';
51
+
52
+ const botId = (ctx.botId ?? 'unknown').replace(/[^a-zA-Z0-9_-]/g, '_');
53
+ const message = options.append({
54
+ from: 'TELEGRAM',
55
+ to: 'COORDINATOR',
56
+ kind: 'question',
57
+ body: formatAskOpQuestionEnvelope({
58
+ surface: 'telegram', botId, chatId: ctx.chatId, threadId: ctx.threadId,
59
+ messageId: ctx.messageId, updateId: ctx.updateId, question,
60
+ }),
61
+ }, `coord:tg-${botId}-${ctx.updateId}:COORDINATOR`);
62
+
63
+ return `OP에게 질문 #${message.id}로 접수했습니다.`;
64
+ },
65
+ };
66
+ }
67
+
68
+ /** Handle a Discord text command from an already-routed message. Returning
69
+ * undefined leaves every non-/askop message on its existing chat path. */
70
+ export function createAskOpDiscordIngress(options: AskOpDiscordOptions) {
71
+ return async (ctx: AskOpDiscordContext): Promise<string | undefined> => {
72
+ const match = new RegExp(`^/${ASK_OP_COMMAND}(?:\\s+([\\s\\S]*))?$`, 'i').exec(ctx.text.trim());
73
+ if (!match) return undefined;
74
+ if (!options.allowedUserIds.includes(ctx.userId)) return '허용된 사용자만 OP에게 질문할 수 있습니다.';
75
+ if (!options.allowedChannelIds.includes(ctx.channelId)) return '허용된 Discord 채널에서만 OP에게 질문할 수 있습니다.';
76
+ const question = match[1]?.trim();
77
+ if (!question) return `사용법: /${ASK_OP_COMMAND} <질문>`;
78
+ if (!/^\d+$/.test(ctx.messageId)) return 'Discord 메시지 식별값을 확인할 수 없어 질문을 저장하지 못했습니다.';
79
+
80
+ let botId: string;
81
+ try { botId = await options.resolveBotId(); }
82
+ catch { return 'Discord 봇 식별값을 확인할 수 없어 질문을 저장하지 못했습니다.'; }
83
+ if (!/^[A-Za-z0-9_-]+$/.test(botId)) return 'Discord 봇 식별값이 올바르지 않아 질문을 저장하지 못했습니다.';
84
+
85
+ const message = appendAskOpQuestion(options, {
86
+ from: 'DISCORD', surface: 'Discord',
87
+ correlation: [
88
+ `botId=${botId}`, `channelId=${ctx.channelId}`,
89
+ `messageId=${ctx.messageId}`, `updateId=${ctx.messageId}`,
90
+ ],
91
+ question,
92
+ provenanceKey: `coord:dc-${botId}-${ctx.messageId}:COORDINATOR`,
93
+ });
94
+ return `OP에게 질문 #${message.id}로 접수했습니다.`;
95
+ };
96
+ }
@@ -37,6 +37,8 @@ import { createDiscordStreamSink } from '../../session/streaming/discord-stream-
37
37
  import { splitForDiscord } from '../../discord.js';
38
38
  import { formatForDiscord } from '../../discord-markdown.js';
39
39
  import { receiveChannelEvent } from '../outbound/router.js';
40
+ import { openMsgStore } from '../../msg/msg-store.js';
41
+ import { createAskOpDiscordIngress } from './channel-ask-op.js';
40
42
 
41
43
  export interface NexusDiscordTriggerBotOpts {
42
44
  /** Bot token (without `Bot ` prefix). Production reads
@@ -156,6 +158,30 @@ export function createNexusDiscordTriggerBot(
156
158
  // LF2 — 콘솔 하트비트 유지 + debug.log 병행(telegram-trigger 동형).
157
159
  const log = opts.log ?? createDiscordTriggerLogger();
158
160
  const onTriggerTap = buildDiscordTriggerTap(opts.dispatch, log);
161
+ let botRef: DiscordBot | undefined;
162
+ let botIdPromise: Promise<string> | undefined;
163
+ const askOpIngress = createAskOpDiscordIngress({
164
+ allowedUserIds: opts.allowedUsers,
165
+ allowedChannelIds: opts.guildTextChannels ?? [],
166
+ resolveBotId: () => {
167
+ if (!botRef) return Promise.reject(new Error('Discord bot is not ready'));
168
+ botIdPromise ??= botRef.getMe().then(({ id }) => id).catch((error: unknown) => {
169
+ botIdPromise = undefined;
170
+ throw error;
171
+ });
172
+ return botIdPromise;
173
+ },
174
+ append: (message, provenanceKey) => {
175
+ const store = openMsgStore();
176
+ try { return store.appendWithProvenance(message, provenanceKey); }
177
+ finally { store.close(); }
178
+ },
179
+ });
180
+ const onMessage: DcMessageHandler = async (ctx, streamer) => {
181
+ const askReply = await askOpIngress(ctx);
182
+ if (askReply !== undefined) return askReply;
183
+ return opts.onMessage?.(ctx, streamer);
184
+ };
159
185
 
160
186
  const botWasInjected = opts.bot !== undefined;
161
187
  const bot = opts.bot ?? new DiscordBot({
@@ -165,7 +191,7 @@ export function createNexusDiscordTriggerBot(
165
191
  // Chat path: the injected self-turn handler (M4b nexus wire) or the
166
192
  // legacy trigger-only no-op. Workflows wanting a chat reply can
167
193
  // still declare a `chatTrigger` (routes via `/v1/workflows/chat/*`).
168
- onMessage: opts.onMessage ?? (async () => undefined),
194
+ onMessage,
169
195
  log,
170
196
  onTriggerTap,
171
197
  ...(opts.voiceTap ? { voiceTap: opts.voiceTap } : {}),
@@ -173,6 +199,7 @@ export function createNexusDiscordTriggerBot(
173
199
  ...(opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}),
174
200
  ...(opts.wsImpl ? { wsImpl: opts.wsImpl } : {}),
175
201
  });
202
+ botRef = bot;
176
203
 
177
204
  // §C3 — discord 서피스 sink(config gate·telegram-trigger 동형). shadowFanout OR
178
205
  // primary.discord 시 등록. endpoint 완전스코프면 parse→인스턴스 가드 후 channelId 배달,
@@ -9,6 +9,7 @@ import { queryRunScreenKey } from '../../self-implement/run-ledger.js';
9
9
  import { logsDbPath } from '../../mss/logging/log-store.js';
10
10
  import { redactSecretText } from '../../debug/log.js';
11
11
  import { runAskLaunchFlow, type AskLaunchFlowResult } from '../../self-dev/ask-launch-flow.js';
12
+ import { defaultGoalAuthorSelfResolve } from '../../self-implement/goal-author-clarification.js';
12
13
  import * as askIo from '../../self-dev/ask-launch-io.js';
13
14
  import { DAEMON_HARNESS_ASK_ENTRANCE } from '../../self-dev/entrance-registry.js';
14
15
  import { prepareAskLaunch } from '../../self-dev/launch-preflight.js';
@@ -211,12 +212,12 @@ function defaultAskDeps(rows: Awaited<ReturnType<typeof askIo.readAskPreflightLo
211
212
  print: () => {},
212
213
  log: (event: string, data: Record<string, unknown>, level?: 'info' | 'warn' | 'error') => debug.log('harness-http', event, data, { level }),
213
214
  readLine: async () => '',
214
- readClarification: async () => '',
215
215
  readFile: (file: string) => readFileSync(file, 'utf8'),
216
216
  writeFile: (file: string, data: string) => writeFileSync(file, data, 'utf8'),
217
217
  cwd: () => process.cwd(),
218
218
  now: () => Date.now(),
219
219
  isInteractive: () => false,
220
+ selfResolveClarification: defaultGoalAuthorSelfResolve,
220
221
  buildPreflightDeps: askIo.buildAskPreflightDeps,
221
222
  priorBlockSamples: () => askIo.priorBlockSamplesFrom(rows),
222
223
  recentAuthoringSamples: () => askIo.recentAuthoringSamplesFrom(rows),
@@ -37,6 +37,12 @@ import { createTelegramStreamSink } from '../../session/streaming/telegram-strea
37
37
  import { splitMarkdownForTelegram } from '../../telegram-format.js';
38
38
  import { formatTablesAndRules } from '../../discord-markdown.js';
39
39
  import { receiveChannelEvent } from '../outbound/router.js';
40
+ import { openMsgStore } from '../../msg/msg-store.js';
41
+ import { createAskOpTelegramSlashCommand } from './channel-ask-op.js';
42
+ import { createTelegramChannelOpReplyTransport, startChannelOpReplyRoute } from '../../session/channel-op-reply-route.js';
43
+ import { resolveInstanceName } from '../../instance-identity.js';
44
+ import { elanousStateRoot } from '../../autopilot/state-paths.js';
45
+ import { join } from 'node:path';
40
46
 
41
47
  export interface NexusTelegramTriggerBotOpts {
42
48
  /** Bot token (without `Bot ` prefix). Production reads
@@ -167,6 +173,14 @@ export function createNexusTelegramTriggerBot(
167
173
  const onTriggerTap = buildTelegramTriggerTap(opts.dispatch, log);
168
174
 
169
175
  const botWasInjected = opts.bot !== undefined;
176
+ const askOpCommand = createAskOpTelegramSlashCommand({
177
+ allowedUserIds: opts.allowedUsers,
178
+ append: (message, provenanceKey) => {
179
+ const store = openMsgStore();
180
+ try { return store.appendWithProvenance(message, provenanceKey); }
181
+ finally { store.close(); }
182
+ },
183
+ });
170
184
  const bot = opts.bot ?? (opts.userConfig
171
185
  // Unified inbound: botFromConfig gives the full Q&A handler
172
186
  // (onMessage → runTurn, sessions, attachments, slash) and we graft
@@ -174,6 +188,7 @@ export function createNexusTelegramTriggerBot(
174
188
  ? botFromConfig({
175
189
  userConfig: opts.userConfig,
176
190
  log,
191
+ extraSlashCommands: [askOpCommand],
177
192
  ...(opts.runTurnImpl ? { runTurnImpl: opts.runTurnImpl } : {}),
178
193
  telegramBotOpts: {
179
194
  token: opts.token,
@@ -286,6 +301,14 @@ export function createNexusTelegramTriggerBot(
286
301
  });
287
302
  }
288
303
 
304
+ const opReplyInstance = resolveInstanceName();
305
+ const opReplyRoute = !botWasInjected ? startChannelOpReplyRoute({
306
+ transport: createTelegramChannelOpReplyTransport({ bot, botId: thisBotId, instance: opReplyInstance }),
307
+ botId: thisBotId,
308
+ instance: opReplyInstance,
309
+ cursorPath: join(elanousStateRoot(), 'msg', 'sse-cursor', `TELEGRAM-channel-op-replies-${thisBotId}.json`),
310
+ }) : undefined;
311
+
289
312
  // One drain promise for every caller. A second stop (SIGINT then
290
313
  // SIGTERM, or a duplicate SIGTERM) must wait for the same bound —
291
314
  // returning immediately would let the process exit before the turn
@@ -297,6 +320,7 @@ export function createNexusTelegramTriggerBot(
297
320
  if (drainPromise) return drainPromise;
298
321
  const timeoutMs = stopOpts?.timeoutMs ?? TELEGRAM_TRIGGER_DRAIN_TIMEOUT_MS;
299
322
  drainPromise = (async (): Promise<void> => {
323
+ try { await opReplyRoute?.stop(); } catch { /* swallow */ }
300
324
  try { offTelegramSink?.(); } catch { /* swallow */ }
301
325
  try { offTelegramStream?.(); } catch { /* swallow */ }
302
326
  try { bot.stop(); } catch { /* swallow */ }
@@ -102,6 +102,11 @@ export interface TerminalSummary {
102
102
  startedAt: number;
103
103
  /** Total bytes currently held in the head/tail buffer (after trim). */
104
104
  outputBytes: number;
105
+ /** Seat copied from the joined lifecycle row for this PTY id; omitted when unknown. */
106
+ seat?: string;
107
+ /** Cumulative output from the joined lifecycle row; omitted when unknown (NULL/missing/0 legacy row).
108
+ * Only a recorded positive total is a fact — same rule as the lineage endpoint. Distinct from outputBytes (buffer length). */
109
+ outputBytesTotal?: number;
105
110
  /** The owner-process access mode, or null when this row is manifest-only. */
106
111
  accessMode: 'read' | 'write' | 'auto' | null;
107
112
  /** Why accessMode is unavailable; null when an access mode is present. */
@@ -266,6 +271,18 @@ function terminalOriginFields(row: Pick<PtyManifestRow, 'terminalOriginCategory'
266
271
  return { terminalOriginCategory: 'unknown', terminalOriginReason: 'legacy-or-malformed-origin-decision' };
267
272
  }
268
273
 
274
+ /** `> 0` 만 사실이다 — legacy 행의 NULL/누락(그리고 매니페스트가 0을 «기록값»으로 구분 못 하는 한 0 전부)은
275
+ * 미상으로 칸을 비운다. 계보 쪽 `lineageRowFromManifest`(`src/cli/pty-takeover-cli.ts`)와 같은 규칙이라
276
+ * 두 엔드포인트가 같은 행을 같게 판정한다. */
277
+ function lifecycleFieldsFromJoinedRow(row: { seat?: string; outputBytesTotal?: number } | undefined): Pick<TerminalSummary, 'seat' | 'outputBytesTotal'> {
278
+ return {
279
+ ...(row?.seat ? { seat: row.seat } : {}),
280
+ ...(typeof row?.outputBytesTotal === 'number' && Number.isFinite(row.outputBytesTotal) && row.outputBytesTotal > 0
281
+ ? { outputBytesTotal: row.outputBytesTotal }
282
+ : {}),
283
+ };
284
+ }
285
+
269
286
  function summarize(
270
287
  handle: PtyHandle,
271
288
  manifest: PtyManifestRow | null,
@@ -300,6 +317,7 @@ function summarize(
300
317
  exitCode: handle.exitCode,
301
318
  startedAt: handle.startedAt,
302
319
  outputBytes: snapshot.length,
320
+ ...lifecycleFieldsFromJoinedRow(manifest ? { seat: manifest.seat, outputBytesTotal: manifest.outputBytesTotal } : undefined),
303
321
  accessMode: handle.accessMode,
304
322
  accessModeUnavailableReason: accessModeUnavailableReason('process', handle.accessMode),
305
323
  ownerRunUsage: ownerRunUsage(manifest?.ownerPid !== undefined ? isOwnerProcessAlive(manifest.ownerPid) : undefined, manifest?.runId ?? '', resolveRunTerminationForRow),
@@ -337,6 +355,7 @@ function summarizeManifest(
337
355
  producer: 'process',
338
356
  alive: row.alive, exitCode: row.exitCode, startedAt: row.startedAt,
339
357
  outputBytes: Buffer.byteLength(row.snapshot, 'utf8'),
358
+ ...lifecycleFieldsFromJoinedRow({ seat: row.seat, outputBytesTotal: row.outputBytesTotal }),
340
359
  // Access mode lives in the owner process, so manifest-only rows cannot know it without IPC.
341
360
  accessMode: null,
342
361
  accessModeUnavailableReason: accessModeUnavailableReason('process', null),
@@ -1102,12 +1121,15 @@ export function handleTerminalsList(req: Request, opts: MetaApiOpts, deps: Termi
1102
1121
  try { cleanupStale(Date.now()); } catch { /* fail-soft */ }
1103
1122
  const manifestAfterInitialCleanup = readLocalManifest();
1104
1123
  const manifestById = new Map(manifestAfterInitialCleanup.map((row) => [row.id, row]));
1105
- const local = (deps.listPty ?? listPty)().map((handle) => summarize(
1106
- handle,
1107
- manifestById.get(handle.id) ?? null,
1108
- resolveRunTerminationForRow,
1109
- deps.isProcessAlive,
1110
- ));
1124
+ const local = (deps.listPty ?? listPty)().map((handle) => {
1125
+ const manifest = manifestById.get(handle.id) ?? null;
1126
+ return summarize(
1127
+ handle,
1128
+ manifest,
1129
+ resolveRunTerminationForRow,
1130
+ deps.isProcessAlive,
1131
+ );
1132
+ });
1111
1133
  const localIds = new Set(local.map((t) => t.id));
1112
1134
  try { cleanupOrphans(localIds); } catch { /* fail-soft */ }
1113
1135
  const isVisible = (row: PtyManifestRow): boolean => isVisibleManifestRow(row, deps.isProcessAlive);
@@ -1,5 +1,5 @@
1
1
  import { Database } from 'bun:sqlite';
2
- import { chmodSync, mkdirSync } from 'node:fs';
2
+ import { chmodSync, existsSync, mkdirSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { elanousStateRoot } from '../autopilot/state-paths.js';
5
5
  import { debug } from '../debug/log.js';
@@ -80,6 +80,12 @@ export class PatentLedger {
80
80
  try { return work(db); } finally { db.close(); }
81
81
  }
82
82
 
83
+ private usingExisting<T>(work: (db: Database) => T): T {
84
+ if (!existsSync(this.path)) throw new Error('patent ledger unavailable');
85
+ const db = new Database(this.path, { readonly: true, create: false, strict: true });
86
+ try { return work(db); } finally { db.close(); }
87
+ }
88
+
83
89
  private transaction<T>(db: Database, work: () => T): T {
84
90
  db.exec('BEGIN IMMEDIATE');
85
91
  try { const result = work(); db.exec('COMMIT'); return result; }
@@ -125,4 +131,15 @@ export class PatentLedger {
125
131
  return this.using(db =>
126
132
  db.query(`SELECT id, title, track, status, deadline, created_at, updated_at FROM patent_candidates WHERE status = '공개 허용' ORDER BY created_at, id`).all() as PatentCandidate[]);
127
133
  }
134
+
135
+ /** Return only line numbers; candidate identifiers and titles remain private. */
136
+ unapprovedCandidateLineNumbers(text: string): number[] {
137
+ return this.usingExisting(db => {
138
+ if (!text.trim()) return [];
139
+ const rows = db.query(`SELECT title FROM patent_candidates WHERE status != '공개 허용'`).all() as Array<{ title: string }>;
140
+ const titles = rows.map(({ title }) => title.toLocaleLowerCase()).filter((title) => title.length >= 3);
141
+ return text.split(/\r?\n/).flatMap((line, index) =>
142
+ titles.some((title) => line.toLocaleLowerCase().includes(title)) ? [index + 1] : []);
143
+ });
144
+ }
128
145
  }
@@ -67,6 +67,8 @@ export interface PreviewTerminalOpts {
67
67
  * splitting honest). */
68
68
  shellArgs?: readonly string[];
69
69
  env?: Record<string, string>;
70
+ /** Remove captured environment keys after env composition (for subscription-only child auth). */
71
+ unsetEnv?: readonly string[];
70
72
  /** Defaults to `xterm-256color` (universal). Override with
71
73
  * `xterm-ghostty` to match a ghostty host, or another terminfo
72
74
  * name for testing. The chosen name lands in $TERM of the child
@@ -343,7 +345,7 @@ export class PreviewTerminal {
343
345
  // PreviewTerminal 자체 에뮬레이터가 렌더 담당이라 무관). 출력 구독/exit 배선은 아래 pump 분기에서.
344
346
  this.registryHandle = this.registryDeps.startPty({
345
347
  // 합성자 = registry(resolveSpawnShape) — 여기서는 overlay 만 넘긴다.
346
- cmd: shell, args, workdir: this.opts.cwd, env: childEnv,
348
+ cmd: shell, args, workdir: this.opts.cwd, env: childEnv, unsetEnv: this.opts.unsetEnv,
347
349
  cols: this.term.cols, rows: this.term.rows,
348
350
  kind: this.opts.registryKind ?? 'preview',
349
351
  nickname: this.opts.registryNickname,
@@ -360,7 +362,7 @@ export class PreviewTerminal {
360
362
  cols: this.term.cols,
361
363
  rows: this.term.rows,
362
364
  cwd: this.opts.cwd,
363
- env: buildPtyEnv(childEnv),
365
+ env: buildPtyEnv(childEnv, process.env, { unset: this.opts.unsetEnv }),
364
366
  });
365
367
  const masterFd = this.resolveMasterFd(this.pty);
366
368
  if (masterFd === null) throw new Error('PreviewTerminal: could not resolve PTY master fd');
@@ -20,6 +20,7 @@
20
20
  // caching went GA without a version bump.
21
21
 
22
22
  import type { LLMMessage, LLMToolSpec } from '../llm.js';
23
+ import { assertNoTopLevelToolSchemaCombinators } from '../llm-tool-schema.js';
23
24
  import {
24
25
  cacheControlFor,
25
26
  type CacheControl,
@@ -98,6 +99,7 @@ export function toAnthropicToolsCached(
98
99
  opts: CacheOpts,
99
100
  ): AnthropicToolBlock[] | undefined {
100
101
  if (!tools || tools.length === 0) return undefined;
102
+ assertNoTopLevelToolSchemaCombinators(tools);
101
103
  // ⭐ Anthropic 은 tool name UNIQUE 를 강제(400 "Tool names must be unique.")한다.
102
104
  // OpenAI/codex 는 중복을 조용히 관대 처리 → 하니스가 codex 위주로 개발되며 중복 tool spec
103
105
  // (예: goal-loop 이 카탈로그에 이미 있는 spec 을 append)이 claude 에서만 400 으로 터졌다.