elanous 0.2.34 → 0.2.35

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 (611) 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/{L04y73dlwKeTW-GetaTF3 → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{5014f970-22bef0b5210f7d60.js → 0368f25d-ad84af92fefee68f.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/{2124.ed5bf480cea7f85b.js → 1530.0e612369b6fd7ea0.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
  9. package/apps/pwa/out/_next/static/chunks/1674.2a65fd5668e1cc5f.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
  11. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
  12. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.js → 2018.a741297bce759490.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
  23. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +34 -0
  25. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
  26. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
  29. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
  31. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{1644.35dd25240ae24e4b.js → 3408.21d1570602f4b6c0.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{3121.779fafe3e44612c5.js → 3589.5444a06bcf6e775c.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9131-fce7256c4180c4a5.js → 3677-4215f826f6aa68e5.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
  40. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
  42. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4346.8601952e73bf5803.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/{6053-d893974de92e6198.js → 4441-875b97f5821ed58a.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
  46. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
  49. package/apps/pwa/out/_next/static/chunks/{1895-60ed0e341c658bd4.js → 4705-194e64e47ca0fbdb.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.js → 4718-17d2af636796a330.js} +3 -3
  51. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{7431.3051e9b8a4372d2d.js → 5101.e32282718f99ed6f.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
  61. package/apps/pwa/out/_next/static/chunks/{2987-30cf9c2eb7b8bdd5.js → 5483-dd5d7697f6bdb106.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
  63. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/56d372f2.681ab4ec4c998fae.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/{7386.5d8e7e42e818dfb6.js → 5852.db1f7449f4f74612.js} +2 -2
  67. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/{3110.0a7065f25c841818.js → 6236.e18cced2d5ba6afb.js} +3 -3
  74. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
  75. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
  78. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
  80. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
  87. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
  88. package/apps/pwa/out/_next/static/chunks/{7005.1623d2aea78eb85f.js → 7385.50a308a477bdfc21.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.js → 7644.17e37ba6f1d4226e.js} +4 -4
  90. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{7193-cf355cca5ba6c5d5.js → 8437-8d5492094b166cfa.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/{2554.3b5e200f5f5cfcd6.js → 8444.4c26b379ca2b9596.js} +4 -4
  100. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
  101. package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
  104. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{2547.dd27303624cb4da8.js → 8637.47f5b35afcae5e6b.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{9550.d5f76828f972058c.js → 9214.63a510d39178e997.js} +2 -2
  111. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
  112. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{8548.036c344973968847.js → 938.66ad1ef0e5abae1c.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{3414.172ad4ca2d9b08e8.js → 9512.5a76207a730e0491.js} +2 -2
  115. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{6740.43de73fc427c9fe2.js → 9952.5daf5f94063a2b3e.js} +1 -1
  120. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/{page-d7bff0f0905a662c.js → page-26e6c18a1a750cf6.js} +1 -1
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-47c5d4db587266bd.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-df3445b207ceceab.js → page-dc0a532f5b9196ec.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{9a8cb466.cc9fc9e6e46038aa.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{4fa33ebd.21c1bd5b294496e6.js → cbe38a15.5a032598e39970c6.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{abb4b98b.163e0f56e84ae35d.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.js → da5176c6.6773b6c5994e1d99.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +1 -0
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/bin/elanous.mjs +3 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/README.md +4 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/default-loop.yaml +57 -3
  285. package/graphs/document-loop.yaml +51 -3
  286. package/graphs/implement-loop.yaml +53 -4
  287. package/graphs/journey/ta-journey.yaml +11 -1
  288. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  289. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  290. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  291. package/graphs/operate-loop.yaml +51 -3
  292. package/graphs/research-loop.yaml +137 -3
  293. package/graphs/test-diet/test-diet.yaml +3 -0
  294. package/package.json +1 -1
  295. package/scripts/coord-role-pack.ts +19 -6
  296. package/scripts/hq/standby-snapshot.ts +17 -12
  297. package/scripts/release-loop/docs-land-node.ts +21 -5
  298. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  299. package/scripts/release-loop/gate-node.ts +181 -22
  300. package/scripts/release-loop/gate-partial.ts +65 -11
  301. package/scripts/release-loop/gate-radius-live.ts +177 -0
  302. package/scripts/release-loop/gate-radius-shadow.ts +1 -1
  303. package/scripts/release-loop/node-verdict.ts +12 -1
  304. package/scripts/release-loop/npm-publish-node.ts +66 -12
  305. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  306. package/scripts/release-loop/pwa-remote.ts +166 -0
  307. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  308. package/scripts/release-loop/resume-release.ts +41 -4
  309. package/scripts/release-loop/unattended-release.ts +2 -0
  310. package/scripts/test-diet/lib.ts +6 -1
  311. package/scripts/test-diet/node.ts +194 -13
  312. package/scripts/ux-sim.ts +39 -0
  313. package/src/agent/self-ambient-cache.ts +8 -0
  314. package/src/agent-substrate/acp-reviewer.ts +39 -4
  315. package/src/agent-substrate/pr-reviewer.ts +17 -0
  316. package/src/agent-substrate/self-review-cli.ts +62 -13
  317. package/src/autopilot/pr-manager.ts +215 -36
  318. package/src/budget/run-usage-rollup.ts +1 -0
  319. package/src/chat/index.ts +0 -2
  320. package/src/chat/pickers/modal-runtime.ts +10 -27
  321. package/src/cli/agent-cli.ts +13 -2
  322. package/src/cli/doctor-cli.ts +4 -1
  323. package/src/cli/light-entry-route.ts +46 -6
  324. package/src/cli/pod-cli.ts +77 -3
  325. package/src/cli/pr-cli.ts +5 -2
  326. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  327. package/src/cli/release-checklist-read-cli.ts +79 -0
  328. package/src/cli/release-cli.ts +72 -102
  329. package/src/cli/remote-resolve.ts +1 -1
  330. package/src/cli/root-tui-entry.ts +48 -0
  331. package/src/cli/sim-cli.ts +22 -0
  332. package/src/cli/tasks-cli.ts +540 -31
  333. package/src/cli/usage-cli.ts +13 -11
  334. package/src/clipboard/history.ts +179 -13
  335. package/src/config.ts +8 -1
  336. package/src/dashboard/chat/acp-chat.ts +8 -0
  337. package/src/dashboard/index.ts +78 -10
  338. package/src/dashboard/render/theme-resolver.ts +33 -4
  339. package/src/domains/schedule-registry.ts +16 -2
  340. package/src/git-fs/idle-refresh.ts +76 -0
  341. package/src/git-fs/index.ts +18 -7
  342. package/src/git-fs/worktree.ts +42 -4
  343. package/src/graph-kinds/registry.ts +2 -2
  344. package/src/graph-runner/runner.ts +153 -10
  345. package/src/grok/credential.ts +10 -3
  346. package/src/harness/harness-cli-command.ts +112 -28
  347. package/src/harness/harness-incidents.ts +33 -0
  348. package/src/harness/launch-utterance-ledger.ts +208 -0
  349. package/src/impl-discipline/detector.ts +16 -4
  350. package/src/impl-discipline/system-prompt.ts +11 -0
  351. package/src/impl-discipline/types.ts +2 -2
  352. package/src/index.ts +496 -143
  353. package/src/intake-plane/already-built-hint.ts +4 -2
  354. package/src/intake-plane/requirement-funnel.ts +29 -1
  355. package/src/light-cli.ts +27 -11
  356. package/src/llm/opengateway-models.ts +11 -0
  357. package/src/llm/provider-credentials.ts +14 -0
  358. package/src/llm/provider-detect.ts +8 -1
  359. package/src/llm/runtime-model-family.ts +2 -1
  360. package/src/llm.ts +213 -56
  361. package/src/model-tier/llm-tier-map.ts +15 -1
  362. package/src/native-tool-catalog.ts +15 -1
  363. package/src/nexus/api/loop-resources.ts +13 -1
  364. package/src/oauth/codex.ts +7 -0
  365. package/src/ops/overview-collect.ts +18 -3
  366. package/src/ops/overview.ts +20 -7
  367. package/src/pr-tool/census.ts +261 -27
  368. package/src/pty-shell/pty-manifest.ts +7 -0
  369. package/src/release-loop/checklist.ts +24 -0
  370. package/src/release-loop/landed-but-yellow.ts +129 -5
  371. package/src/release-loop/light-rc.ts +1 -0
  372. package/src/release-loop/rehearsal.ts +2 -2
  373. package/src/repl/index.ts +174 -17
  374. package/src/repl/ops-msg-bridge.ts +32 -0
  375. package/src/self-dev/ask-launch-flow.ts +44 -5
  376. package/src/self-dev/cli-help-text.ts +17 -0
  377. package/src/self-dev/dev-cli.ts +11 -9
  378. package/src/self-dev/draft-residue.ts +37 -1
  379. package/src/self-dev/draft-sweep.ts +137 -11
  380. package/src/self-dev/draft-triage-rules.ts +107 -0
  381. package/src/self-dev/fleet-reduce.ts +3 -2
  382. package/src/self-dev/graph-front-nodes.ts +112 -0
  383. package/src/self-dev/graph-journey-nodes.ts +1 -0
  384. package/src/self-dev/harness-run-cli.ts +3 -15
  385. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  386. package/src/self-dev/review-provider-fallback.ts +35 -1
  387. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  388. package/src/self-dev/shard-aggregate.ts +42 -5
  389. package/src/self-dev/shard-run.ts +8 -1
  390. package/src/self-implement/blocked-draft-policy.ts +20 -0
  391. package/src/self-implement/classify-shadow.ts +3 -7
  392. package/src/self-implement/doctor-visit.ts +18 -1
  393. package/src/self-implement/gate-baseline.ts +56 -17
  394. package/src/self-implement/gate-cli.ts +1 -0
  395. package/src/self-implement/gate-remote.ts +31 -20
  396. package/src/self-implement/goal-author-decompose.ts +275 -47
  397. package/src/self-implement/goal-author.ts +250 -0
  398. package/src/self-implement/goal-elaborate.ts +295 -0
  399. package/src/self-implement/goal-refine.ts +270 -0
  400. package/src/self-implement/graph-overlay-yaml.ts +14 -3
  401. package/src/self-implement/orchestrator.ts +152 -45
  402. package/src/self-implement/rework-budget-judgment.ts +5 -8
  403. package/src/self-implement/run-stop.ts +10 -1
  404. package/src/self-implement/running-runs.ts +29 -1
  405. package/src/self-implement/scope-adjacency.ts +113 -0
  406. package/src/self-implement/seams.ts +127 -24
  407. package/src/self-implement/stop-autoheal.ts +87 -1
  408. package/src/session-runtime/index.ts +1 -1
  409. package/src/setup/llm-env-detect.ts +5 -0
  410. package/src/skills/tools/agent.ts +140 -14
  411. package/src/skills/tools/msg-ask.ts +100 -0
  412. package/src/skills/tools/ops-ledger.ts +2 -1
  413. package/src/steward/hold-hygiene.ts +24 -6
  414. package/src/steward/triage-budget.ts +194 -0
  415. package/src/steward/triage.ts +20 -3
  416. package/src/task-agent/actions.ts +69 -1
  417. package/src/task-agent/green-sweep.ts +4 -0
  418. package/src/task-agent/live-moves.ts +160 -4
  419. package/src/task-agent/parent-host.ts +123 -3
  420. package/src/task-agent/shadow.ts +7 -1
  421. package/src/task-agent/task-hand.ts +54 -41
  422. package/src/task-agent/tier-split.ts +127 -0
  423. package/src/task-agent/work-order-build.ts +2 -0
  424. package/src/task-agent/work-order.ts +3 -2
  425. package/src/task-orchestrator/generator-prompt.ts +60 -11
  426. package/src/task-orchestrator/surfaces/pod-account-broker.ts +33 -0
  427. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  428. package/src/task-orchestrator/surfaces/pod-command-job.ts +45 -7
  429. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  430. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  431. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
  432. package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
  433. package/src/task-orchestrator/surfaces/pod-source-receive.ts +18 -0
  434. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  435. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +6 -2
  436. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
  437. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +37 -5
  438. package/src/task-orchestrator/surfaces/self-implement-pod.ts +368 -36
  439. package/src/task-orchestrator/surfaces/self-implement.ts +23 -0
  440. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  441. package/src/tui/README.md +2 -0
  442. package/src/tui/chat/background-job-status.ts +54 -0
  443. package/src/tui/chat/log-view.ts +80 -0
  444. package/src/tui/entry.ts +406 -0
  445. package/src/tui/input/composer.ts +144 -0
  446. package/src/tui/seat-mail-boot.ts +59 -0
  447. package/src/tui/slash/compact.ts +100 -0
  448. package/src/tui/slash/new-session.ts +35 -0
  449. package/src/tui-client/local-chat-turn.ts +239 -0
  450. package/src/tui-client/local-harness-command.ts +63 -0
  451. package/src/tui-client/local-provider-command.ts +184 -0
  452. package/src/user-config.ts +4 -2
  453. package/src/ux-sim/event-monkey.ts +378 -0
  454. package/src/ux-sim/fake-bin.ts +42 -7
  455. package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
  456. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  457. package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
  458. package/src/version/packed-revision.json +1 -1
  459. package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +0 -79
  460. package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +0 -94
  463. package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +0 -23
  465. package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +0 -115
  467. package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +0 -8
  468. package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/3001-5a52788c813b6113.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/3103.84470c8445962f04.js +0 -34
  479. package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/3411-f87314c6c66ebc73.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/3498.cf2a15a8a9e5b926.js +0 -226
  485. package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +0 -32
  487. package/apps/pwa/out/_next/static/chunks/3837.722e053fb9f321ad.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +0 -104
  490. package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +0 -286
  491. package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +0 -149
  492. package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +0 -148
  493. package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +0 -64
  494. package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +0 -74
  497. package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/5028-f0722e6114c313e7.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/5249.96a848656b582a93.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +0 -62
  504. package/apps/pwa/out/_next/static/chunks/5446.edf141cff9ef647d.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/5489.ec2dd1b5272a19dc.js +0 -24
  506. package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +0 -77
  517. package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +0 -90
  520. package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/7448.478958ffbbba0ac0.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +0 -41
  527. package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +0 -27
  530. package/apps/pwa/out/_next/static/chunks/7952.b192c31b6a0e00cc.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +0 -36
  533. package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/8817.61bb7ffbba502ecb.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +0 -93
  547. package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +0 -24
  549. package/apps/pwa/out/_next/static/chunks/9739.8d5f36ac67a3b236.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/field/page-4fb31eb476dcbad3.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-398c0faa173203f7.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +0 -122
  603. package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/ffdc3a04.b9c23c1b28dd4a96.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +0 -1
  611. /package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
@@ -75,10 +75,11 @@ function configuredUsageHosts(): { local: string; remote: string[] } {
75
75
  return { local, remote: [...new Set(entries.map((entry) => entry.host?.trim()).filter((host): host is string => !!host && host !== local))] };
76
76
  }
77
77
 
78
- type UsageAxis = 'stage' | 'model' | 'account';
78
+ type UsageAxis = 'stage' | 'phase' | 'model' | 'account';
79
79
  type ExtendedRunUsageInput = RunUsageInput & { stage?: string | null; account?: string | null; origin?: string; podJob?: string; job?: string; measured?: boolean };
80
80
  type AxisUsageRow = {
81
81
  stage?: string;
82
+ phase?: string;
82
83
  model?: string;
83
84
  account?: string;
84
85
  hostIds: string[];
@@ -97,7 +98,7 @@ type AxisUsageRow = {
97
98
  };
98
99
 
99
100
  type FederatedUsageRow = {
100
- runId?: string; role?: string; site?: string; stage?: string; model?: string; account?: string;
101
+ runId?: string; role?: string; site?: string; stage?: string; phase?: string; model?: string; account?: string;
101
102
  billingProvider?: string; billing?: string; hostIds: string[]; rankUsd?: number;
102
103
  calls: number; inputTokens: number; outputTokens: number; cacheReadInputTokens: number;
103
104
  cacheCreationInputTokens: number; reasoningOutputTokens: number; usdKnown: number;
@@ -122,7 +123,7 @@ function validUsageRows(value: unknown, axis: 'run' | 'role' | UsageAxis): value
122
123
  const number = row[field];
123
124
  return typeof number === 'number' && Number.isFinite(number) && number >= 0;
124
125
  })
125
- && (axis !== 'stage' && axis !== 'model' && axis !== 'account'
126
+ && (axis !== 'stage' && axis !== 'phase' && axis !== 'model' && axis !== 'account'
126
127
  || typeof row.rankUsd === 'number' && Number.isFinite(row.rankUsd));
127
128
  });
128
129
  }
@@ -137,7 +138,7 @@ function mergeUsageRows(groups: readonly FederatedUsageRow[][], axis: 'run' | 'r
137
138
  if (!previous) { merged.set(key, { ...row, hostIds: [...row.hostIds] }); continue; }
138
139
  for (const field of SUM_FIELDS) previous[field] += row[field];
139
140
  previous.hostIds = [...new Set([...previous.hostIds, ...row.hostIds])];
140
- if (axis === 'stage' || axis === 'model' || axis === 'account') previous.rankUsd = previous.usdKnown + previous.apiEquivalentUsd;
141
+ if (axis === 'stage' || axis === 'phase' || axis === 'model' || axis === 'account') previous.rankUsd = previous.usdKnown + previous.apiEquivalentUsd;
141
142
  }
142
143
  return [...merged.values()];
143
144
  }
@@ -186,6 +187,7 @@ function rollupByAxis(inputs: readonly ExtendedRunUsageInput[], axis: UsageAxis)
186
187
  const groups = new Map<string, ExtendedRunUsageInput[]>();
187
188
  for (const data of inputs) {
188
189
  const value = axis === 'stage' ? stageForUsage(data)
190
+ : axis === 'phase' ? (typeof data.phase === 'string' && data.phase.length > 0 ? data.phase : '(none)')
189
191
  : axis === 'model' ? (data.model || '(none)')
190
192
  : (data.account || '(none)');
191
193
  const group = groups.get(value) ?? [];
@@ -216,7 +218,7 @@ function rollupByAxis(inputs: readonly ExtendedRunUsageInput[], axis: UsageAxis)
216
218
  }
217
219
 
218
220
  function isUsageAxis(value: string): value is 'run' | 'role' | UsageAxis {
219
- return value === 'run' || value === 'role' || value === 'stage' || value === 'model' || value === 'account';
221
+ return value === 'run' || value === 'role' || value === 'stage' || value === 'phase' || value === 'model' || value === 'account';
220
222
  }
221
223
 
222
224
  function formatAxisUsage(row: AxisUsageRow, axis: UsageAxis): string {
@@ -249,9 +251,9 @@ export function registerUsageCommand(program: Command, deps: UsageCliDeps = {}):
249
251
 
250
252
  usage
251
253
  .command('runs')
252
- .description('저장된 llm-usage 로그를 런·역할·단계·모델·계정별로 집계한다')
254
+ .description('저장된 llm-usage 로그를 런·역할·단계·phase·모델·계정별로 집계한다')
253
255
  .option('--run <runId>', '런 ID 정확 일치')
254
- .option('--by <axis>', '집계 축 (run | role | stage | model | account)', 'run')
256
+ .option('--by <axis>', '집계 축 (run | role | stage | phase | model | account)', 'run')
255
257
  .option(...LOGS_SINCE_OPTION)
256
258
  .option('--hosts <scope>', '호스트 연합 (all: 이 호스트 + 설정된 taskAgent.parentHost)')
257
259
  .option('--json', '집계 행 JSON 출력')
@@ -298,14 +300,14 @@ export function registerUsageCommand(program: Command, deps: UsageCliDeps = {}):
298
300
  const complete = !rosterReason && hosts.every((host) => host.status === 'ok');
299
301
  const rows = mergeUsageRows(parts, opts.by as 'run' | 'role' | UsageAxis);
300
302
  if (opts.by === 'role') rows.sort((a, b) => b.calls - a.calls);
301
- if (opts.by === 'stage' || opts.by === 'model' || opts.by === 'account') rows.sort((a, b) => (b.rankUsd ?? 0) - (a.rankUsd ?? 0) || b.calls - a.calls);
303
+ if (opts.by === 'stage' || opts.by === 'phase' || opts.by === 'model' || opts.by === 'account') rows.sort((a, b) => (b.rankUsd ?? 0) - (a.rankUsd ?? 0) || b.calls - a.calls);
302
304
  if (json) { out.log(JSON.stringify({ rows, hosts, complete, ...(rosterReason ? { reason: rosterReason } : {}) }, null, 2)); return; }
303
305
  out.log(`호스트 ${hosts.filter((host) => host.status === 'ok').length}/${hosts.length} 측정 · ${complete ? '완결' : '부분 합계'}`);
304
306
  if (rosterReason) out.log(`호스트 목록: 못 잼 (${rosterReason})`);
305
307
  for (const host of hosts) if (host.status === 'unmeasured') out.log(`${host.host}: 못 잼 (${host.reason})`);
306
308
  if (rows.length === 0) { out.log('(일치하는 런 사용량 없음)'); return; }
307
309
  for (const row of rows) {
308
- if (opts.by === 'stage' || opts.by === 'model' || opts.by === 'account') out.log(formatAxisUsage(row as AxisUsageRow, opts.by));
310
+ if (opts.by === 'stage' || opts.by === 'phase' || opts.by === 'model' || opts.by === 'account') out.log(formatAxisUsage(row as AxisUsageRow, opts.by));
309
311
  else if (opts.by === 'role') out.log(`${row.role} ${row.site} ${row.model} ${row.billingProvider}/${row.billing} calls=${row.calls} input=${row.inputTokens} output=${row.outputTokens} usdKnown=${row.usdKnown} unknownCostCalls=${row.unknownCostCalls} includedCalls=${row.includedCalls} apiEquivalentUsd=${row.apiEquivalentUsd}`);
310
312
  else out.log(`${row.runId} ${row.model} ${row.billingProvider}/${row.billing} hosts=${row.hostIds.join(',') || '(none)'} calls=${row.calls} input=${row.inputTokens} output=${row.outputTokens} cacheRead=${row.cacheReadInputTokens} cacheCreation=${row.cacheCreationInputTokens} reasoning=${row.reasoningOutputTokens} usdKnown=${row.usdKnown} unknownCostCalls=${row.unknownCostCalls} includedCalls=${row.includedCalls} apiEquivalentUsd=${row.apiEquivalentUsd}`);
311
313
  }
@@ -323,14 +325,14 @@ export function registerUsageCommand(program: Command, deps: UsageCliDeps = {}):
323
325
  localFailure = '로컬 logs.db 조회 실패';
324
326
  }
325
327
  }
326
- const unwrapPod = opts.by === 'stage' || opts.by === 'model' || opts.by === 'account';
328
+ const unwrapPod = opts.by === 'stage' || opts.by === 'phase' || opts.by === 'model' || opts.by === 'account';
327
329
  // ⭐ METER-POD-ROLLUP-GAP-2 — Pod 사용량 재방출 행(podRollupKey)은 «더 완전한 한 행»만 센다(키 없는 행은 그대로).
328
330
  const selected = rows.map((row) => usageData(row, unwrapPod))
329
331
  .filter((data): data is ExtendedRunUsageInput => data !== null)
330
332
  .filter((data) => opts.run === undefined || data.runId === opts.run);
331
333
  // A returned Pod raw row and its host rollup describe the same usage. Keep raw rows when no measured rollup exists.
332
334
  const inputs = dedupePodRollupRows(unwrapPod ? excludeCoveredPodRawRows(selected) : selected);
333
- if (opts.by === 'stage' || opts.by === 'model' || opts.by === 'account') {
335
+ if (opts.by === 'stage' || opts.by === 'phase' || opts.by === 'model' || opts.by === 'account') {
334
336
  const report = rollupByAxis(inputs, opts.by);
335
337
  if (opts.hosts === 'all') { emitFederated(report, localFailure); return; }
336
338
  if (json) {
@@ -8,15 +8,19 @@
8
8
  //
9
9
  // Why polling vs an OS event hook: macOS doesn't expose a clipboard-
10
10
  // changed notification to userland binaries without entitlements.
11
- // pbpaste at 1.5s cadence is cheap (sub-millisecond per call on a
12
- // recent Mac) and the small lag is fine for "look back at what I
13
- // copied 30s ago" use cases.
11
+ // Keep a short active cadence, then back off while the TUI is idle so
12
+ // an open terminal does not spawn pbpaste every 1.5s indefinitely.
13
+ // CLASSIC-IDLE-CLIPBOARD (2026-10-21): callers that only show the history
14
+ // inside a panel start with `active: false` and flip `setActive(true)` while
15
+ // the panel is visible — a closed panel spawns zero pbpaste processes
16
+ // (5-minute idle classic TUI measured 88 reads before this change).
14
17
  //
15
18
  // Image entries: we already track a separate path-based registry for
16
19
  // pasted screenshots (context.ts). This module is text-only by
17
20
  // design — image previews live in the main scratchpad already.
18
21
 
19
22
  import { readClipboardText, isClipboardSupported } from './index.js';
23
+ import { debug } from '../debug/log.js';
20
24
 
21
25
  export interface ClipboardEntry {
22
26
  /** UTF-8 text. Trimmed of a single trailing newline so visually
@@ -29,6 +33,19 @@ export interface ClipboardEntry {
29
33
  export interface ClipboardHistoryOpts {
30
34
  /** Polling interval in ms. Defaults to 1500. */
31
35
  intervalMs?: number;
36
+ /** Start slowing clipboard reads after this much user inactivity. Defaults to 2 minutes. */
37
+ idleAfterMs?: number;
38
+ /** Poll interval multiplier after idleAfterMs. Defaults to 10 (15s with the default cadence). */
39
+ idleIntervalMultiplier?: number;
40
+ /** Start the deepest backoff after this much user inactivity. Defaults to 10 minutes. */
41
+ longIdleAfterMs?: number;
42
+ /** Poll interval multiplier after longIdleAfterMs. Defaults to 60 (90s with the default cadence). */
43
+ longIdleIntervalMultiplier?: number;
44
+ /** Start polling immediately. Defaults to true. `false` keeps the poller
45
+ * dormant (no reads, no timer) until `setActive(true)`. */
46
+ active?: boolean;
47
+ /** Busy streams keep the active cadence and restart the idle grace period when they finish. */
48
+ isBusy?: () => boolean;
32
49
  /** Cap on stored entries; oldest fall off when exceeded. Defaults
33
50
  * to 50 — enough for a typical session, not so big the list
34
51
  * becomes unscrollable. */
@@ -40,6 +57,17 @@ export interface ClipboardHistoryOpts {
40
57
  maxBytes?: number;
41
58
  }
42
59
 
60
+ /** Dependencies are injectable so tests can exercise the real poller without
61
+ * process-wide `mock.module()` state. Production callers use the defaults. */
62
+ export interface ClipboardHistoryDependencies {
63
+ readClipboardText(): Promise<string | null>;
64
+ isClipboardSupported(): boolean;
65
+ /** Observation sink for poll-state transitions. Defaults to
66
+ * `debug.log('clipboard.history', …)`; tests inject a recorder because
67
+ * the debug sink arms its own flush timer. */
68
+ observe?(event: 'poll-state', data: { active: boolean; reason: string }): void;
69
+ }
70
+
43
71
  export interface ClipboardHistory {
44
72
  /** Snapshot list, newest first. Caller may read but should not
45
73
  * mutate — use `clear` to reset. */
@@ -54,12 +82,27 @@ export interface ClipboardHistory {
54
82
  * history reflects the just-promoted entry without waiting for
55
83
  * the next tick. */
56
84
  pokeNow(): Promise<void>;
85
+ /** Mark TUI input. Wakes the poller immediately if it had slowed down. */
86
+ noteActivity(): void;
87
+ /** Notify the poller immediately when its busy source changes state. */
88
+ noteBusyChange(): void;
89
+ /** Start/stop background polling (e.g. history panel opened/closed).
90
+ * Activating reads once immediately; deactivating clears the timer.
91
+ * Repeating the current state is a no-op. */
92
+ setActive(active: boolean, reason?: string): void;
57
93
  }
58
94
 
59
95
  /** Start polling. No-op on non-clipboard platforms — returns a stub
60
96
  * with empty entries so callers don't need to guard every call. */
61
- export function startClipboardHistory(opts: ClipboardHistoryOpts = {}): ClipboardHistory {
97
+ export function startClipboardHistory(
98
+ opts: ClipboardHistoryOpts = {},
99
+ dependencies: ClipboardHistoryDependencies = { readClipboardText, isClipboardSupported },
100
+ ): ClipboardHistory {
62
101
  const intervalMs = opts.intervalMs ?? 1500;
102
+ const idleAfterMs = opts.idleAfterMs ?? 2 * 60_000;
103
+ const idleIntervalMultiplier = opts.idleIntervalMultiplier ?? 10;
104
+ const longIdleAfterMs = opts.longIdleAfterMs ?? 10 * 60_000;
105
+ const longIdleIntervalMultiplier = opts.longIdleIntervalMultiplier ?? 60;
63
106
  const maxEntries = opts.maxEntries ?? 50;
64
107
  const maxBytes = opts.maxBytes ?? 8 * 1024;
65
108
 
@@ -67,15 +110,51 @@ export function startClipboardHistory(opts: ClipboardHistoryOpts = {}): Clipboar
67
110
  const subs = new Set<() => void>();
68
111
  let stopped = false;
69
112
  let lastSeenText: string | null = null;
70
- let timer: ReturnType<typeof setInterval> | null = null;
113
+ let timer: ReturnType<typeof setTimeout> | null = null;
114
+ let inFlight: Promise<void> | null = null;
115
+ let immediatePollAfterInFlight = false;
116
+ let queuedActivityPoll: Promise<void> | null = null;
117
+ let lastActivityAt = Date.now();
118
+ let wasBusy = readBusy();
119
+ let active = opts.active ?? true;
120
+
121
+ function readBusy(): boolean {
122
+ try { return opts.isBusy?.() ?? false; } catch { return false; }
123
+ }
124
+
125
+ const idleMs = (): number => {
126
+ const busy = readBusy();
127
+ if (wasBusy && !busy) lastActivityAt = Date.now();
128
+ wasBusy = busy;
129
+ return busy ? 0 : Math.max(0, Date.now() - lastActivityAt);
130
+ };
131
+
132
+ const nextDelayMs = (): number => {
133
+ const idle = idleMs();
134
+ if (idle >= longIdleAfterMs) return intervalMs * longIdleIntervalMultiplier;
135
+ if (idle >= idleAfterMs) return intervalMs * idleIntervalMultiplier;
136
+ return intervalMs;
137
+ };
138
+
139
+ const scheduleNext = (): void => {
140
+ if (stopped || !active) return;
141
+ if (timer) clearTimeout(timer);
142
+ timer = setTimeout(() => {
143
+ timer = null;
144
+ void poll();
145
+ }, nextDelayMs());
146
+ };
71
147
 
72
- if (!isClipboardSupported()) {
148
+ if (!dependencies.isClipboardSupported()) {
73
149
  return {
74
150
  entries,
75
151
  onChange: (fn) => { subs.add(fn); return () => subs.delete(fn); },
76
152
  stop: () => { stopped = true; },
77
153
  clear: () => { entries.length = 0; },
78
154
  pokeNow: async () => { /* no-op */ },
155
+ noteActivity: () => {},
156
+ noteBusyChange: () => {},
157
+ setActive: () => {},
79
158
  };
80
159
  }
81
160
 
@@ -97,25 +176,112 @@ export function startClipboardHistory(opts: ClipboardHistoryOpts = {}): Clipboar
97
176
  for (const fn of subs) { try { fn(); } catch { /* ignore */ } }
98
177
  };
99
178
 
100
- const poll = async (): Promise<void> => {
101
- if (stopped) return;
102
- try { ingest(await readClipboardText()); } catch { /* swallow */ }
179
+ const poll = (): Promise<void> => {
180
+ if (stopped) return Promise.resolve();
181
+ if (inFlight) return inFlight;
182
+ const run = Promise.resolve().then(async (): Promise<void> => {
183
+ try { ingest(await dependencies.readClipboardText()); } catch { /* swallow */ }
184
+ finally {
185
+ inFlight = null;
186
+ if (immediatePollAfterInFlight && !stopped) {
187
+ immediatePollAfterInFlight = false;
188
+ queuedActivityPoll = poll();
189
+ void queuedActivityPoll;
190
+ } else {
191
+ immediatePollAfterInFlight = false;
192
+ scheduleNext();
193
+ }
194
+ }
195
+ });
196
+ inFlight = run;
197
+ return run;
198
+ };
199
+
200
+ const pollImmediately = (): void => {
201
+ if (inFlight) {
202
+ immediatePollAfterInFlight = true;
203
+ return;
204
+ }
205
+ void poll();
206
+ };
207
+
208
+ const noteActivity = (): void => {
209
+ const wokeFromIdle = idleMs() >= idleAfterMs;
210
+ lastActivityAt = Date.now();
211
+ wasBusy = readBusy();
212
+ if (wokeFromIdle && active) {
213
+ if (timer) clearTimeout(timer);
214
+ timer = null;
215
+ pollImmediately();
216
+ }
217
+ };
218
+
219
+ const noteBusyChange = (): void => {
220
+ const busy = readBusy();
221
+ if (busy === wasBusy) return;
222
+ wasBusy = busy;
223
+ lastActivityAt = Date.now();
224
+ if (!active) return;
225
+ if (timer) clearTimeout(timer);
226
+ timer = null;
227
+ pollImmediately();
228
+ };
229
+
230
+ const setActive = (next: boolean, reason = 'unspecified'): void => {
231
+ if (stopped || next === active) return;
232
+ active = next;
233
+ const observe = dependencies.observe
234
+ ?? ((event: string, data: unknown) => { debug.log('clipboard.history', event, data); });
235
+ try { observe('poll-state', { active, reason }); } catch { /* observation must not break polling */ }
236
+ if (timer) clearTimeout(timer);
237
+ timer = null;
238
+ if (!active) {
239
+ immediatePollAfterInFlight = false;
240
+ return;
241
+ }
242
+ lastActivityAt = Date.now();
243
+ wasBusy = readBusy();
244
+ pollImmediately();
103
245
  };
104
246
 
105
247
  // Kick off immediately so the very first frame already has at
106
248
  // least one entry (whatever's currently on the clipboard).
107
- void poll();
108
- timer = setInterval(() => { void poll(); }, intervalMs);
249
+ // A dormant poller (active:false) reads on its first setActive(true).
250
+ if (active) void poll();
109
251
 
110
252
  return {
111
253
  entries,
112
254
  onChange: (fn) => { subs.add(fn); return () => subs.delete(fn); },
113
255
  stop: () => {
114
256
  stopped = true;
115
- if (timer) clearInterval(timer);
257
+ if (timer) clearTimeout(timer);
116
258
  timer = null;
117
259
  },
118
260
  clear: () => { entries.length = 0; lastSeenText = null; },
119
- pokeNow: async () => { await poll(); },
261
+ pokeNow: async () => {
262
+ // Keep this request independent from noteActivity. If a wake poll is
263
+ // already queued behind the current read, it will satisfy this poke.
264
+ lastActivityAt = Date.now();
265
+ wasBusy = readBusy();
266
+ const currentRead = inFlight;
267
+ const canUseQueuedWake = Boolean(currentRead && immediatePollAfterInFlight);
268
+ if (timer) clearTimeout(timer);
269
+ timer = null;
270
+ if (currentRead) {
271
+ await currentRead;
272
+ if (canUseQueuedWake && queuedActivityPoll) {
273
+ await queuedActivityPoll;
274
+ return;
275
+ }
276
+ if (timer) clearTimeout(timer);
277
+ timer = null;
278
+ }
279
+ // Reads already in progress may have captured the clipboard before
280
+ // this promotion, so take a fresh snapshot after they finish.
281
+ await poll();
282
+ },
283
+ noteActivity,
284
+ noteBusyChange,
285
+ setActive,
120
286
  };
121
287
  }
package/src/config.ts CHANGED
@@ -6,6 +6,7 @@ import { lookupLlmTierSpec } from './model-tier/llm-tier-map.js';
6
6
  import { listSshHosts } from './ssh/ssh-hosts.js';
7
7
  import { isInstalledPackagePath } from './instance/installed-package.js';
8
8
  import { defaultObsidianVault } from './obsidian/default-vault.js';
9
+ import { OPENGATEWAY_DEFAULT_MODEL } from './llm/opengateway-models.js';
9
10
 
10
11
  // ── User config ──
11
12
  export const REMOTE_HOME = homedir();
@@ -191,7 +192,7 @@ export function refreshKeyFromCache(envName: string): boolean {
191
192
  * 자식 프로세스도 이 env 를 물려받는다. 반환 = 캐시로 채운 이름(값은 절대 안 싣는다).
192
193
  */
193
194
  export const DAEMON_KEY_ENV_NAMES = [
194
- 'ANTHROPIC_API_KEY', 'GEMINI_API_KEY', 'OPENAI_API_KEY', 'XAI_API_KEY', 'OPENROUTER_API_KEY',
195
+ 'ANTHROPIC_API_KEY', 'GEMINI_API_KEY', 'OPENAI_API_KEY', 'XAI_API_KEY', 'OPENROUTER_API_KEY', 'OPENGATEWAY_API_KEY',
195
196
  'ELANOUS_OPENAI_RELAY_SHARED_SECRET',
196
197
  ] as const;
197
198
 
@@ -239,6 +240,12 @@ export const OPENROUTER_API_URL = 'https://openrouter.ai/api/v1/chat/completions
239
240
  // 기본 = 사다리 `balanced`(`llm-tier-map.ts` OPENROUTER). 카탈로그 id 는 `openrouter/<vendor>/<model>`,
240
241
  // wire 로는 `openrouter/` 를 떼고 보낸다(`makeOpenRouterProvider`).
241
242
  export const OPENROUTER_MODEL = process.env.OPENROUTER_MODEL || 'openrouter/z-ai/glm-5.3';
243
+ /** Optional OpenAI-compatible gateway. Cache wins over inherited env, as for other API keys. */
244
+ export function getOpenGatewayApiKey(): string | undefined {
245
+ return keyFromCacheOrEnv('OPENGATEWAY_API_KEY');
246
+ }
247
+ export const OPENGATEWAY_API_URL = 'https://apis.opengateway.ai/v1/chat/completions';
248
+ export const OPENGATEWAY_MODEL = process.env.OPENGATEWAY_MODEL || OPENGATEWAY_DEFAULT_MODEL;
242
249
  export function getLocalLLMUrl(): string | undefined {
243
250
  return process.env.LOCAL_LLM_URL; // e.g. http://localhost:11434/v1 (ollama)
244
251
  }
@@ -137,6 +137,8 @@ export interface DashboardAcpChatOpts {
137
137
  /** Logger for subprocess stderr / protocol events. Route into the
138
138
  * dashboard debug log (pushLog). */
139
139
  log?: (msg: string) => void;
140
+ /** Notify idle-sensitive dashboard services when an ACP turn starts or ends. */
141
+ onBusyChange?: () => void;
140
142
  /** Dependency injection hook for tests — overrides the default
141
143
  * `globalAcpAgentManager()` lookup. Production call sites omit
142
144
  * this field. */
@@ -180,6 +182,7 @@ export interface DashboardAcpChatOpts {
180
182
  export class DashboardAcpChat {
181
183
  private readonly getCwd: () => string;
182
184
  private readonly log: (msg: string) => void;
185
+ private readonly onBusyChange?: () => void;
183
186
  private readonly agentManager: NonNullable<DashboardAcpChatOpts['agentManager']>;
184
187
  private readonly sessionStore: NonNullable<DashboardAcpChatOpts['sessionStore']>;
185
188
  private readonly permissionApprover?: AcpPermissionApprover;
@@ -209,6 +212,7 @@ export class DashboardAcpChat {
209
212
  this.getCwd = () => getSessionCwd();
210
213
  }
211
214
  this.log = opts.log ?? ((_m) => { /* default: drop */ });
215
+ this.onBusyChange = opts.onBusyChange;
212
216
  this.agentManager = opts.agentManager ?? {
213
217
  getAgent: (backendId, o) => globalAcpAgentManager().getAgent(backendId, o) as any,
214
218
  };
@@ -321,6 +325,7 @@ export class DashboardAcpChat {
321
325
  throw new Error(`${displayBackendName(backendId)} already has a turn in flight — /acp cancel first`);
322
326
  }
323
327
  sess.inFlight = true;
328
+ this.onBusyChange?.();
324
329
  if (debug.enabled) {
325
330
  handlers.pushLine(` → sending to ${displayBackendName(backendId)}…`);
326
331
  }
@@ -359,11 +364,14 @@ export class DashboardAcpChat {
359
364
  }
360
365
  this.closeStreamBuffer(sess, 'flush');
361
366
  sess.inFlight = false;
367
+ this.onBusyChange?.();
362
368
  handlers.onDone(result.stopReason);
363
369
  } catch (err) {
364
370
  if (sess) {
365
371
  this.closeStreamBuffer(sess, 'flush');
372
+ const wasBusy = sess.inFlight;
366
373
  sess.inFlight = false;
374
+ if (wasBusy) this.onBusyChange?.();
367
375
  }
368
376
  handlers.onError(err instanceof Error ? err : new Error(formatAcpError(err)));
369
377
  }
@@ -889,7 +889,8 @@ import {
889
889
  refreshDirtyAsync as refreshGitDirtyAsync,
890
890
  refreshGitSnapshotAsync,
891
891
  } from '../git-fs/index.js';
892
- import { refreshSelfAmbientCache } from '../agent/self-ambient-cache.js';
892
+ import { createIdleGitPoll, dashboardIdleMs, gitDirtyRefreshIntervalMs } from '../git-fs/idle-refresh.js';
893
+ import { refreshSelfAmbientCache, selfAmbientKeepWarmIntervalMs } from '../agent/self-ambient-cache.js';
893
894
  import { getPty, listPty, requestPtyTakeover } from '../pty-shell/registry.js';
894
895
  import { listPtyManifestRowsAt } from '../pty-shell/pty-manifest.js';
895
896
  import { ptyManifestTargets } from '../domains/fleet.js';
@@ -1183,7 +1184,7 @@ export function registerDashboardCoreHostTools(host: Pick<PluginHost, 'registerH
1183
1184
  }
1184
1185
  import { registerDashboardPaneHostTools } from './panes/host-tools.js';
1185
1186
  import { type ThemeTokens } from '../theme/tokens.js';
1186
- import { resolveActiveTheme } from './render/theme-resolver.js';
1187
+ import { getActiveThemeName, resolveActiveTheme } from './render/theme-resolver.js';
1187
1188
  import { getTheme } from '../themes/index.js';
1188
1189
  import type { PaneFocus, PreviewSource, WorkingDirView } from '../workspace-types.js';
1189
1190
  import type { DisplayMouseEvent } from '../display/types.js';
@@ -2876,6 +2877,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
2876
2877
  // current value so log analysis can filter "what keys fired while
2877
2878
  // a turn was in flight".
2878
2879
  let streamingInFlight = false;
2880
+ let noteClipboardActivity: () => void = () => {};
2881
+ let noteClipboardBusyChange: () => void = () => {};
2882
+ let noteClipboardPanelState: (active: boolean, reason: string) => void = () => {};
2883
+ let dashboardAcpIsBusy: () => boolean = () => false;
2884
+ let lastDashboardInputAt = Date.now();
2879
2885
  /** 지금 턴의 escGate 중단 — 외부 `/stop`(TUI-STOP-INPUT-BYPASS)이 대기열을 건너뛰어 부른다. 턴 밖이면 null. */
2880
2886
  let currentTurnExternalStop: (() => void) | null = null;
2881
2887
  const resolveTmuxStatusLabel = (): string | null => {
@@ -4049,6 +4055,8 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4049
4055
  // makes the "*N" suffix tick up within the same frame so the
4050
4056
  // user sees feedback for their own action immediately.
4051
4057
  // TUI-TYPING-LAG — async probe: `git status` must not block key input.
4058
+ lastDashboardInputAt = Date.now();
4059
+ lastGitDirtyProbeAt = lastDashboardInputAt;
4052
4060
  void refreshGitDirtyAsync(getSessionCwd(), { force: true })
4053
4061
  .then(() => { try { draw(); } catch { /* TUI torn down */ } }, () => { /* noop */ });
4054
4062
  });
@@ -4073,9 +4081,11 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4073
4081
  // extras.
4074
4082
  // 3. SWD flip → dispose + re-wire (fresh repo root).
4075
4083
  let gitUnsub: (() => void) | null = null;
4084
+ let lastGitDirtyProbeAt = Date.now();
4076
4085
  const wireGitForSwd = (): void => {
4077
4086
  if (gitUnsub) { try { gitUnsub(); } catch {} gitUnsub = null; }
4078
4087
  const swd = getSessionCwd();
4088
+ lastGitDirtyProbeAt = Date.now();
4079
4089
  gitUnsub = subscribeGitChanges(swd, () => {
4080
4090
  try { draw(); } catch { /* noop */ }
4081
4091
  });
@@ -4113,17 +4123,18 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4113
4123
  // the git snapshot (async subprocesses) and the self-ambient store scan (worker thread). A turn
4114
4124
  // then serves them from cache instead of rebuilding synchronously on the turn path. Both are
4115
4125
  // no-ops while the cached value is younger than the threshold; failures are fail-soft.
4126
+ const currentDashboardIdleMs = (): number =>
4127
+ dashboardIdleMs(Date.now(), lastDashboardInputAt, streamingInFlight || dashboardAcpIsBusy());
4116
4128
  const warmTurnPreambleCaches = (): void => {
4117
- try { void refreshGitSnapshotAsync(getSessionCwd(), { ifOlderThanMs: 30_000 }); } catch { /* noop */ }
4118
- try { void refreshSelfAmbientCache({}, { ifOlderThanMs: 25_000 }); } catch { /* noop */ }
4129
+ const ambientCacheTtlMs = selfAmbientKeepWarmIntervalMs(currentDashboardIdleMs());
4130
+ try { void refreshSelfAmbientCache({}, { ifOlderThanMs: ambientCacheTtlMs }); } catch { /* noop */ }
4119
4131
  };
4120
- warmTurnPreambleCaches();
4121
- const gitDirtyTimer: ReturnType<typeof setInterval> = setInterval(() => {
4122
- warmTurnPreambleCaches();
4132
+ const probeGitDirty = (minIntervalMs: number): void => {
4133
+ lastGitDirtyProbeAt = Date.now();
4123
4134
  try {
4124
4135
  const before = getGitStatusView(getSessionCwd());
4125
4136
  // TUI-TYPING-LAG — the 5s probe ran `git status` synchronously (130ms+, hundreds under load).
4126
- void refreshGitDirtyAsync(getSessionCwd(), { minIntervalMs: 4_000 }).then((after) => {
4137
+ void refreshGitDirtyAsync(getSessionCwd(), { minIntervalMs }).then((after) => {
4127
4138
  if (
4128
4139
  (before.dirty?.total ?? -1) !== (after.dirty?.total ?? -1) ||
4129
4140
  (before.aheadBehind?.ahead ?? -1) !== (after.aheadBehind?.ahead ?? -1)
@@ -4132,6 +4143,26 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4132
4143
  }
4133
4144
  }, () => { /* noop */ });
4134
4145
  } catch { /* noop */ }
4146
+ };
4147
+ // CLASSIC-IDLE-GIT-POLL — no git children while idle (2 min without input); the next key warms once
4148
+ // off the input path (deferred) and polling resumes. `git-fs.idle poll-state` records each flip.
4149
+ const gitIdlePoll = createIdleGitPoll({
4150
+ idleMs: currentDashboardIdleMs,
4151
+ poll: (idleMs) => {
4152
+ try { void refreshGitSnapshotAsync(getSessionCwd(), { ifOlderThanMs: 30_000 }); } catch { /* noop */ }
4153
+ if (Date.now() - lastGitDirtyProbeAt < gitDirtyRefreshIntervalMs(idleMs)) return;
4154
+ probeGitDirty(gitDirtyRefreshIntervalMs(idleMs));
4155
+ },
4156
+ warm: () => {
4157
+ try { void refreshGitSnapshotAsync(getSessionCwd(), { ifOlderThanMs: 30_000 }); } catch { /* noop */ }
4158
+ probeGitDirty(0);
4159
+ },
4160
+ });
4161
+ warmTurnPreambleCaches();
4162
+ try { void refreshGitSnapshotAsync(getSessionCwd(), { ifOlderThanMs: 30_000 }); } catch { /* noop */ }
4163
+ const gitDirtyTimer: ReturnType<typeof setInterval> = setInterval(() => {
4164
+ warmTurnPreambleCaches();
4165
+ gitIdlePoll.tick();
4135
4166
  }, 5_000);
4136
4167
  (gitDirtyTimer as unknown as { unref?: () => void }).unref?.();
4137
4168
  // The running module's installed version, not the user's working directory, is the baseline.
@@ -4546,6 +4577,8 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4546
4577
  };
4547
4578
  let pluginHost: PluginHost;
4548
4579
  let lastThemeLoadError = '';
4580
+ let lastThemeResolutionName: string | null = null;
4581
+ let lastPluginThemeAppliedDebugKey: string | null = null;
4549
4582
  let iulThemePreviewOverride: string | null = null;
4550
4583
  let lastHostChromePolicyDebugKey = '';
4551
4584
  const observeEssentialFrameCursor = createDashboardEssentialCursorObserver({
@@ -4560,9 +4593,26 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
4560
4593
  const raw = iulThemePreviewOverride
4561
4594
  ? { ...(getUserConfig().dashboard.theme as object ?? {}), active: iulThemePreviewOverride }
4562
4595
  : getUserConfig().dashboard.theme;
4596
+ const activeThemeName = getActiveThemeName(raw);
4597
+ if (activeThemeName !== lastThemeResolutionName) {
4598
+ lastThemeResolutionName = activeThemeName;
4599
+ lastPluginThemeAppliedDebugKey = null;
4600
+ }
4563
4601
  return resolveActiveTheme({
4564
4602
  raw,
4565
- loadPlugin: (id) => pluginHost?.loadThemeTokens(id) ?? null,
4603
+ loadPlugin: (id) => {
4604
+ const tokens = pluginHost?.loadThemeTokens(id) ?? null;
4605
+ if (!tokens) lastPluginThemeAppliedDebugKey = null;
4606
+ return tokens;
4607
+ },
4608
+ onPluginApplied: (event) => {
4609
+ const key = `${event.id}:${event.tokensCount}:${event.source}`;
4610
+ if (key === lastPluginThemeAppliedDebugKey) return;
4611
+ try {
4612
+ debug.log('tui.theme', 'plugin-theme-applied', event);
4613
+ lastPluginThemeAppliedDebugKey = key;
4614
+ } catch { /* observation is best-effort */ }
4615
+ },
4566
4616
  onPluginError: (message) => {
4567
4617
  if (lastThemeLoadError !== message) {
4568
4618
  lastThemeLoadError = message;
@@ -6011,6 +6061,8 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6011
6061
  }
6012
6062
  };
6013
6063
  const syncCompanionPopups = (): void => {
6064
+ // CLASSIC-IDLE-CLIPBOARD: every clipboard open/close/dock path ends here — keep it the only gate.
6065
+ noteClipboardPanelState(companionPopupHost.isActive('clipboard'), companionPopupHost.isDocked('clipboard') ? 'panel-docked' : companionPopupHost.isOpen('clipboard') ? 'panel-open' : 'panel-close');
6014
6066
  const { cols, rows } = termSize();
6015
6067
  const workspaceHost = display.workspaceHostAPI();
6016
6068
  const ownerId = companionPopupHost.ownerId;
@@ -7011,6 +7063,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7011
7063
  };
7012
7064
 
7013
7065
  const cleanup = attachStreamingKeys(async (key) => {
7066
+ noteClipboardActivity();
7014
7067
  // ── Pre-dispatch gates ────────────────────────────────────
7015
7068
  //
7016
7069
  // These run BEFORE `routeInputEventAsync` because:
@@ -7108,6 +7161,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7108
7161
  // ⛔ TUI-STALE-BUSY-MARKER — busy 는 «끄는 closure 를 돌려주기 직전»에 켠다. 위 준비(ESC 게이트·키 리스너)가
7109
7162
  // 던지면 호출자는 cleanup 을 못 받으므로, 먼저 켜 두면 아무도 못 끄는 busy 가 남는다(#37).
7110
7163
  streamingInFlight = true;
7164
+ noteClipboardBusyChange();
7111
7165
  reportTuiTurn('busy');
7112
7166
  const externalStop = (): void => { stopTurnViaEscGate(escGate); };
7113
7167
  currentTurnExternalStop = externalStop;
@@ -7126,6 +7180,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7126
7180
  } finally {
7127
7181
  userScrolledDuringStream = false;
7128
7182
  streamingInFlight = false;
7183
+ noteClipboardBusyChange();
7129
7184
  reportTuiTurn('idle');
7130
7185
  const failedTurnRaw = autowakeTurnFailureRaw;
7131
7186
  autowakeTurnFailureRaw = null;
@@ -7196,6 +7251,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7196
7251
  const dashboardAcpChat = new DashboardAcpChat({
7197
7252
  cwd: () => workingDir.cwd,
7198
7253
  log: (msg) => pushLog('debug', ` [acp] ${msg}`),
7254
+ onBusyChange: () => noteClipboardBusyChange(),
7199
7255
  // Follow-up #9 — wrap the modal approver so BG records flip to
7200
7256
  // `waiting_for_confirmation` even when the peer (codex-acp /
7201
7257
  // gemini-cli) doesn't emit the `tool_call_update.status` field.
@@ -7205,6 +7261,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7205
7261
  globalBackgroundManager(),
7206
7262
  ),
7207
7263
  });
7264
+ dashboardAcpIsBusy = () => dashboardAcpChat.isBusy();
7208
7265
  activeAcpRuntimeModel = () => dashboardAcpChat.activeRuntimeModel();
7209
7266
 
7210
7267
  // Obsidian vault browser (Phase O3). Shares the FsEntry shape and
@@ -12358,7 +12415,17 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
12358
12415
  // ticks every ~1.5s on Darwin and stores up to 50 unique text
12359
12416
  // snapshots. Stopped during dashboard teardown to avoid leaking
12360
12417
  // intervals if the host re-enters showDashboard.
12361
- const clipHistory: ClipboardHistory = startClipboardHistory({});
12418
+ // CLASSIC-IDLE-CLIPBOARD: dormant until the clipboard companion is open.
12419
+ const clipHistory: ClipboardHistory = startClipboardHistory({
12420
+ active: companionPopupHost.isActive('clipboard'),
12421
+ isBusy: () => streamingInFlight || dashboardAcpChat.isBusy(),
12422
+ });
12423
+ noteClipboardPanelState = (active, reason) => clipHistory.setActive(active, reason);
12424
+ noteClipboardActivity = () => {
12425
+ lastDashboardInputAt = Date.now();
12426
+ clipHistory.noteActivity();
12427
+ };
12428
+ noteClipboardBusyChange = () => clipHistory.noteBusyChange();
12362
12429
  process.once('beforeExit', () => { clipHistory.stop(); });
12363
12430
  // Re-render whenever the poller picks up a new entry — only when
12364
12431
  // we're actually showing the history viewer, otherwise the side-
@@ -15160,6 +15227,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15160
15227
  const key: import('../tui.js').Key = wdAutoInput
15161
15228
  ? { name: CHAT_MAIN_AUTO_ENTRY_KEY_NAME, ctrl: false, shift: false }
15162
15229
  : await readKey();
15230
+ if (!wdAutoInput) { noteClipboardActivity(); gitIdlePoll.noteActivity('input'); }
15163
15231
  const helpModal = currentTransientTerminalModal('dashboard-help');
15164
15232
  if (key.name === 'escape' && helpModal) {
15165
15233
  helpModal.dispose();