elanous 0.2.0 → 0.2.4

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 (1174) hide show
  1. package/.env.example +6 -0
  2. package/README.md +16 -14
  3. package/apps/pwa/out/404/index.html +1 -1
  4. package/apps/pwa/out/404.html +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1191-7b13a24117a689fa.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/2375-3fcae5186c64fe6b.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/2415.ed6428ff334c7ce2.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2929-617f1e66a55be184.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +25 -0
  17. package/apps/pwa/out/_next/static/chunks/{2a79f15a-2013e4d421d6df88.js → 2ea96958-e8c7e112de50b067.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/319-d37df1b6e0cbeff4.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +5 -0
  20. package/apps/pwa/out/_next/static/chunks/3441-a1dd4acfeda14488.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6804.8ed6ab492bc5fc0a.js → 4323.c5dfb6f503304775.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/4836-3c93795ab834381e.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{320-d7013ec072863e5e.js → 5080-1613752891fcadb4.js} +4 -4
  26. package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/6062-73e68343a9814f6a.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/6090-1bd6077591603947.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/7457-f5cb1cc8db9f7453.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/8046cadf-211ca3c0e00f2b72.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/8067-f74bf14d67ad98f1.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/8142-011e1f474efb8b33.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/8519-0059d82bdb4812bf.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/9740-52467f244755917f.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/9804-64c02c3c127d5014.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/app/approvals/page-21c3261af6ab377c.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-1991445b8ea86274.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/app/board/page-4ebfaee2369fe248.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/app/botlab/page-9fa879ebf5959096.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/app/bots/page-ca7c3cc305c3285a.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/app/chat/page-9951930add3d2051.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/app/control/page-4472ddf1e2458e69.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/app/design-check/page-4de08d4b766f134b.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/app/editor/page-7a975e2b9db1dfb7.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/app/intake/page-49270714ef35bb96.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/app/layout-33fbdf353e2a5982.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/app/live/page-259f122e2dd64317.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/app/market/page-65b82726753658e1.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-4b8df3748dc06285.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/app/morning/page-112f7e477bda77fd.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/app/not-found-542a5c0006da637c.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/app/observatory/page-63ffb347831262ea.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/app/page-98e4e359d97263b4.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/app/reflection/page-97e24ac675ce576e.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ac6391f26391d89d.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f45c9d45ffc43bd.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-36995b9cb5d98218.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/app/settings/page-0c795b577988d63f.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-b4311e2f71c6735a.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/app/setup/page-eb2381074df20dba.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/app/share/page-b01336e64eba01ae.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/app/showroom/page-7af7f21c1f2858ef.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/app/tasks/page-a98ecd364586c89b.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/app/term/page-57f0502dfbfa089b.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/app/trace/page-3467d2e1abd8a14a.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/app/vault/page-7842ca23d53ba682.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-ae9ac882912b0198.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/app/workflows/page-3a0d72e3f783bcef.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/app/workspace/page-f3b39fe8358c2a97.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-5a22af3181ac2afb.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/main-app-1457627bb302a22c.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/webpack-e5bea36f183b25e6.js +1 -0
  92. package/apps/pwa/out/_next/static/css/e66b7f5efc8df3f3.css +1 -0
  93. package/apps/pwa/out/_next/static/zoQX5iTvXOsIvCjxCe1Ji/_buildManifest.js +1 -0
  94. package/apps/pwa/out/approvals/index.html +1 -0
  95. package/apps/pwa/out/approvals/index.txt +30 -0
  96. package/apps/pwa/out/autopilot/index.html +1 -1
  97. package/apps/pwa/out/autopilot/index.txt +27 -26
  98. package/apps/pwa/out/board/index.html +1 -0
  99. package/apps/pwa/out/board/index.txt +30 -0
  100. package/apps/pwa/out/botlab/index.html +1 -1
  101. package/apps/pwa/out/botlab/index.txt +24 -23
  102. package/apps/pwa/out/bots/index.html +1 -1
  103. package/apps/pwa/out/bots/index.txt +24 -23
  104. package/apps/pwa/out/chat/index.html +1 -2
  105. package/apps/pwa/out/chat/index.txt +24 -23
  106. package/apps/pwa/out/control/index.html +1 -1
  107. package/apps/pwa/out/control/index.txt +27 -26
  108. package/apps/pwa/out/design-check/index.html +1 -1
  109. package/apps/pwa/out/design-check/index.txt +27 -26
  110. package/apps/pwa/out/editor/index.html +1 -0
  111. package/apps/pwa/out/editor/index.txt +31 -0
  112. package/apps/pwa/out/healthz +1 -1
  113. package/apps/pwa/out/index.html +1 -1
  114. package/apps/pwa/out/index.txt +24 -23
  115. package/apps/pwa/out/intake/index.html +1 -1
  116. package/apps/pwa/out/intake/index.txt +27 -26
  117. package/apps/pwa/out/live/index.html +1 -0
  118. package/apps/pwa/out/live/index.txt +30 -0
  119. package/apps/pwa/out/market/index.html +1 -0
  120. package/apps/pwa/out/market/index.txt +27 -0
  121. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  122. package/apps/pwa/out/missions/placeholder/index.txt +24 -23
  123. package/apps/pwa/out/morning/index.html +1 -1
  124. package/apps/pwa/out/morning/index.txt +27 -26
  125. package/apps/pwa/out/observatory/index.html +1 -1
  126. package/apps/pwa/out/observatory/index.txt +27 -26
  127. package/apps/pwa/out/reflection/index.html +1 -1
  128. package/apps/pwa/out/reflection/index.txt +25 -24
  129. package/apps/pwa/out/scheduler/index.html +1 -1
  130. package/apps/pwa/out/scheduler/index.txt +27 -26
  131. package/apps/pwa/out/sessions/index.html +1 -1
  132. package/apps/pwa/out/sessions/index.txt +24 -23
  133. package/apps/pwa/out/settings/devices/index.html +1 -1
  134. package/apps/pwa/out/settings/devices/index.txt +27 -26
  135. package/apps/pwa/out/settings/index.html +1 -1
  136. package/apps/pwa/out/settings/index.txt +27 -26
  137. package/apps/pwa/out/setup/done/index.html +1 -1
  138. package/apps/pwa/out/setup/done/index.txt +27 -26
  139. package/apps/pwa/out/setup/index.html +1 -1
  140. package/apps/pwa/out/setup/index.txt +27 -26
  141. package/apps/pwa/out/share/index.html +1 -1
  142. package/apps/pwa/out/share/index.txt +27 -26
  143. package/apps/pwa/out/showroom/index.html +1 -1
  144. package/apps/pwa/out/showroom/index.txt +24 -23
  145. package/apps/pwa/out/tasks/index.html +1 -1
  146. package/apps/pwa/out/tasks/index.txt +27 -26
  147. package/apps/pwa/out/term/index.html +1 -1
  148. package/apps/pwa/out/term/index.txt +27 -26
  149. package/apps/pwa/out/trace/index.html +1 -0
  150. package/apps/pwa/out/trace/index.txt +30 -0
  151. package/apps/pwa/out/vault/index.html +1 -1
  152. package/apps/pwa/out/vault/index.txt +27 -26
  153. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  154. package/apps/pwa/out/workflows/chat-ui/index.txt +27 -26
  155. package/apps/pwa/out/workflows/index.html +1 -1
  156. package/apps/pwa/out/workflows/index.txt +27 -27
  157. package/apps/pwa/out/workspace/index.html +1 -1
  158. package/apps/pwa/out/workspace/index.txt +27 -26
  159. package/apps/pwa/out/worktrees/index.html +1 -1
  160. package/apps/pwa/out/worktrees/index.txt +27 -26
  161. package/catalog/resources.yaml +8 -11
  162. package/docs/design/systems/LICENSE +201 -0
  163. package/docs/design/systems/NOTICE.md +29 -0
  164. package/docs/design/systems/SOURCE.json +291 -0
  165. package/docs/design/systems/application/DESIGN.md +71 -0
  166. package/docs/design/systems/application/manifest.json +54 -0
  167. package/docs/design/systems/application/tokens.css +63 -0
  168. package/docs/design/systems/artistic/DESIGN.md +71 -0
  169. package/docs/design/systems/artistic/manifest.json +54 -0
  170. package/docs/design/systems/artistic/tokens.css +63 -0
  171. package/docs/design/systems/bento/DESIGN.md +71 -0
  172. package/docs/design/systems/bento/manifest.json +54 -0
  173. package/docs/design/systems/bento/tokens.css +63 -0
  174. package/docs/design/systems/bold/DESIGN.md +71 -0
  175. package/docs/design/systems/bold/manifest.json +54 -0
  176. package/docs/design/systems/bold/tokens.css +63 -0
  177. package/docs/design/systems/brutalism/DESIGN.md +71 -0
  178. package/docs/design/systems/brutalism/manifest.json +54 -0
  179. package/docs/design/systems/brutalism/tokens.css +63 -0
  180. package/docs/design/systems/cafe/DESIGN.md +71 -0
  181. package/docs/design/systems/cafe/manifest.json +54 -0
  182. package/docs/design/systems/cafe/tokens.css +63 -0
  183. package/docs/design/systems/claymorphism/DESIGN.md +71 -0
  184. package/docs/design/systems/claymorphism/manifest.json +54 -0
  185. package/docs/design/systems/claymorphism/tokens.css +63 -0
  186. package/docs/design/systems/clean/DESIGN.md +71 -0
  187. package/docs/design/systems/clean/manifest.json +54 -0
  188. package/docs/design/systems/clean/tokens.css +63 -0
  189. package/docs/design/systems/colorful/DESIGN.md +71 -0
  190. package/docs/design/systems/colorful/manifest.json +54 -0
  191. package/docs/design/systems/colorful/tokens.css +63 -0
  192. package/docs/design/systems/contemporary/DESIGN.md +71 -0
  193. package/docs/design/systems/contemporary/manifest.json +54 -0
  194. package/docs/design/systems/contemporary/tokens.css +63 -0
  195. package/docs/design/systems/corporate/DESIGN.md +71 -0
  196. package/docs/design/systems/corporate/manifest.json +54 -0
  197. package/docs/design/systems/corporate/tokens.css +63 -0
  198. package/docs/design/systems/cosmic/DESIGN.md +71 -0
  199. package/docs/design/systems/cosmic/manifest.json +54 -0
  200. package/docs/design/systems/cosmic/tokens.css +63 -0
  201. package/docs/design/systems/creative/DESIGN.md +71 -0
  202. package/docs/design/systems/creative/manifest.json +54 -0
  203. package/docs/design/systems/creative/tokens.css +63 -0
  204. package/docs/design/systems/dashboard/DESIGN.md +71 -0
  205. package/docs/design/systems/dashboard/manifest.json +54 -0
  206. package/docs/design/systems/dashboard/tokens.css +63 -0
  207. package/docs/design/systems/default/DESIGN.md +62 -0
  208. package/docs/design/systems/default/manifest.json +69 -0
  209. package/docs/design/systems/default/tokens.css +200 -0
  210. package/docs/design/systems/dithered/DESIGN.md +71 -0
  211. package/docs/design/systems/dithered/manifest.json +54 -0
  212. package/docs/design/systems/dithered/tokens.css +63 -0
  213. package/docs/design/systems/doodle/DESIGN.md +71 -0
  214. package/docs/design/systems/doodle/manifest.json +54 -0
  215. package/docs/design/systems/doodle/tokens.css +63 -0
  216. package/docs/design/systems/dramatic/DESIGN.md +71 -0
  217. package/docs/design/systems/dramatic/manifest.json +54 -0
  218. package/docs/design/systems/dramatic/tokens.css +63 -0
  219. package/docs/design/systems/editorial/DESIGN.md +71 -0
  220. package/docs/design/systems/editorial/manifest.json +54 -0
  221. package/docs/design/systems/editorial/tokens.css +63 -0
  222. package/docs/design/systems/elegant/DESIGN.md +71 -0
  223. package/docs/design/systems/elegant/manifest.json +54 -0
  224. package/docs/design/systems/elegant/tokens.css +63 -0
  225. package/docs/design/systems/energetic/DESIGN.md +72 -0
  226. package/docs/design/systems/energetic/manifest.json +54 -0
  227. package/docs/design/systems/energetic/tokens.css +63 -0
  228. package/docs/design/systems/enterprise/DESIGN.md +71 -0
  229. package/docs/design/systems/enterprise/manifest.json +54 -0
  230. package/docs/design/systems/enterprise/tokens.css +63 -0
  231. package/docs/design/systems/expressive/DESIGN.md +71 -0
  232. package/docs/design/systems/expressive/manifest.json +54 -0
  233. package/docs/design/systems/expressive/tokens.css +63 -0
  234. package/docs/design/systems/fantasy/DESIGN.md +71 -0
  235. package/docs/design/systems/fantasy/manifest.json +54 -0
  236. package/docs/design/systems/fantasy/tokens.css +63 -0
  237. package/docs/design/systems/flat/DESIGN.md +71 -0
  238. package/docs/design/systems/flat/manifest.json +54 -0
  239. package/docs/design/systems/flat/tokens.css +63 -0
  240. package/docs/design/systems/friendly/DESIGN.md +71 -0
  241. package/docs/design/systems/friendly/manifest.json +54 -0
  242. package/docs/design/systems/friendly/tokens.css +63 -0
  243. package/docs/design/systems/glassmorphism/DESIGN.md +71 -0
  244. package/docs/design/systems/glassmorphism/manifest.json +54 -0
  245. package/docs/design/systems/glassmorphism/tokens.css +63 -0
  246. package/docs/design/systems/gradient/DESIGN.md +71 -0
  247. package/docs/design/systems/gradient/manifest.json +54 -0
  248. package/docs/design/systems/gradient/tokens.css +63 -0
  249. package/docs/design/systems/luxury/DESIGN.md +71 -0
  250. package/docs/design/systems/luxury/manifest.json +54 -0
  251. package/docs/design/systems/luxury/tokens.css +63 -0
  252. package/docs/design/systems/minimal/DESIGN.md +71 -0
  253. package/docs/design/systems/minimal/manifest.json +54 -0
  254. package/docs/design/systems/minimal/tokens.css +63 -0
  255. package/docs/design/systems/modern/DESIGN.md +71 -0
  256. package/docs/design/systems/modern/manifest.json +54 -0
  257. package/docs/design/systems/modern/tokens.css +63 -0
  258. package/docs/design/systems/mono/DESIGN.md +71 -0
  259. package/docs/design/systems/mono/manifest.json +54 -0
  260. package/docs/design/systems/mono/tokens.css +63 -0
  261. package/docs/design/systems/neobrutalism/DESIGN.md +71 -0
  262. package/docs/design/systems/neobrutalism/manifest.json +54 -0
  263. package/docs/design/systems/neobrutalism/tokens.css +63 -0
  264. package/docs/design/systems/neon/DESIGN.md +71 -0
  265. package/docs/design/systems/neon/manifest.json +54 -0
  266. package/docs/design/systems/neon/tokens.css +63 -0
  267. package/docs/design/systems/neumorphism/DESIGN.md +71 -0
  268. package/docs/design/systems/neumorphism/manifest.json +54 -0
  269. package/docs/design/systems/neumorphism/tokens.css +63 -0
  270. package/docs/design/systems/paper/DESIGN.md +71 -0
  271. package/docs/design/systems/paper/manifest.json +54 -0
  272. package/docs/design/systems/paper/tokens.css +63 -0
  273. package/docs/design/systems/perspective/DESIGN.md +71 -0
  274. package/docs/design/systems/perspective/manifest.json +54 -0
  275. package/docs/design/systems/perspective/tokens.css +63 -0
  276. package/docs/design/systems/premium/DESIGN.md +71 -0
  277. package/docs/design/systems/premium/manifest.json +54 -0
  278. package/docs/design/systems/premium/tokens.css +63 -0
  279. package/docs/design/systems/professional/DESIGN.md +71 -0
  280. package/docs/design/systems/professional/manifest.json +54 -0
  281. package/docs/design/systems/professional/tokens.css +63 -0
  282. package/docs/design/systems/publication/DESIGN.md +71 -0
  283. package/docs/design/systems/publication/manifest.json +54 -0
  284. package/docs/design/systems/publication/tokens.css +63 -0
  285. package/docs/design/systems/refined/DESIGN.md +71 -0
  286. package/docs/design/systems/refined/manifest.json +54 -0
  287. package/docs/design/systems/refined/tokens.css +63 -0
  288. package/docs/design/systems/retro/DESIGN.md +71 -0
  289. package/docs/design/systems/retro/manifest.json +54 -0
  290. package/docs/design/systems/retro/tokens.css +63 -0
  291. package/docs/design/systems/shadcn/DESIGN.md +71 -0
  292. package/docs/design/systems/shadcn/manifest.json +54 -0
  293. package/docs/design/systems/shadcn/tokens.css +255 -0
  294. package/docs/design/systems/simple/DESIGN.md +71 -0
  295. package/docs/design/systems/simple/manifest.json +54 -0
  296. package/docs/design/systems/simple/tokens.css +63 -0
  297. package/docs/design/systems/skeumorphism/DESIGN.md +71 -0
  298. package/docs/design/systems/skeumorphism/manifest.json +54 -0
  299. package/docs/design/systems/skeumorphism/tokens.css +63 -0
  300. package/docs/design/systems/sleek/DESIGN.md +71 -0
  301. package/docs/design/systems/sleek/manifest.json +54 -0
  302. package/docs/design/systems/sleek/tokens.css +63 -0
  303. package/docs/design/systems/spacious/DESIGN.md +71 -0
  304. package/docs/design/systems/spacious/manifest.json +54 -0
  305. package/docs/design/systems/spacious/tokens.css +63 -0
  306. package/docs/design/systems/storytelling/DESIGN.md +71 -0
  307. package/docs/design/systems/storytelling/manifest.json +54 -0
  308. package/docs/design/systems/storytelling/tokens.css +63 -0
  309. package/docs/design/systems/tom-modern/DESIGN.md +361 -0
  310. package/docs/design/systems/tom-modern/manifest.json +16 -0
  311. package/docs/design/systems/tom-modern/tokens.css +99 -0
  312. package/docs/design/systems/vibrant/DESIGN.md +71 -0
  313. package/docs/design/systems/vibrant/manifest.json +54 -0
  314. package/docs/design/systems/vibrant/tokens.css +63 -0
  315. package/docs/design/systems/vintage/DESIGN.md +71 -0
  316. package/docs/design/systems/vintage/manifest.json +54 -0
  317. package/docs/design/systems/vintage/tokens.css +63 -0
  318. package/docs/design/systems/warm-editorial/DESIGN.md +65 -0
  319. package/docs/design/systems/warm-editorial/manifest.json +54 -0
  320. package/docs/design/systems/warm-editorial/tokens.css +63 -0
  321. package/docs/goal-context/01-goal-authoring-checks.md +18 -0
  322. package/docs/goal-context/steward-directives-2026-09-28.md +44 -0
  323. package/graphs/catalog/catalog.yaml +615 -0
  324. package/graphs/default-loop.yaml +1 -1
  325. package/graphs/document-loop.yaml +1 -1
  326. package/graphs/examples/stale-draft-digest/digest.ts +26 -0
  327. package/graphs/examples/stale-draft-digest/recipes.yaml +8 -0
  328. package/graphs/examples/stale-draft-digest/stale-draft-digest.yaml +22 -0
  329. package/graphs/heal/heal-loop.yaml +155 -0
  330. package/graphs/heal/recipes.yaml +19 -0
  331. package/graphs/implement-loop.yaml +2 -2
  332. package/graphs/intake/intake-daily.yaml +55 -0
  333. package/graphs/intake/recipes.yaml +16 -0
  334. package/graphs/landing/landing-heal.yaml +22 -0
  335. package/graphs/landing/recipes.yaml +8 -0
  336. package/graphs/launch/launch-head.yaml +66 -0
  337. package/graphs/launch/recipes.yaml +8 -0
  338. package/graphs/operate-loop.yaml +1 -1
  339. package/graphs/ops/docs-publish.yaml +31 -0
  340. package/graphs/ops/recipes.yaml +8 -0
  341. package/graphs/release/recipes.yaml +38 -0
  342. package/graphs/release/release-loop.yaml +40 -0
  343. package/graphs/research-loop.yaml +1 -1
  344. package/graphs/steward/recipes.yaml +12 -0
  345. package/graphs/steward/steward.yaml +45 -0
  346. package/graphs/video/broll-line.yaml +54 -0
  347. package/package.json +7 -5
  348. package/plugins/job-coach/.agents/plugins/marketplace.json +12 -0
  349. package/plugins/job-coach/.codex-plugin/plugin.json +6 -0
  350. package/plugins/job-coach/.mcp.json +9 -0
  351. package/plugins/job-coach/README.md +20 -0
  352. package/plugins/job-coach/connectors/ncs/server.ts +89 -0
  353. package/plugins/job-coach/examples/interview-sample.md +11 -0
  354. package/plugins/job-coach/graphs/course-links.ts +46 -0
  355. package/plugins/job-coach/graphs/recipes.yaml +18 -0
  356. package/plugins/job-coach/graphs/report.yaml +20 -0
  357. package/plugins/job-coach/graphs/run-step.ts +108 -0
  358. package/plugins/job-coach/plugin.json +13 -0
  359. package/plugins/job-coach/plugin.ts +6 -0
  360. package/plugins/job-coach/skills/career-report/SKILL.md +6 -0
  361. package/plugins/job-coach/skills/interview-to-profile/SKILL.md +6 -0
  362. package/plugins/job-coach/skills/run-report/SKILL.md +15 -0
  363. package/scripts/backup/elanous-backup.sh +139 -13
  364. package/scripts/backup/elanous-restore.sh +122 -0
  365. package/scripts/ci-daemon-port-gate.ts +164 -0
  366. package/scripts/ci-typecheck-changed.ts +15 -1
  367. package/scripts/cli-json-exit-scan.ts +126 -0
  368. package/scripts/codex-quota-alert-format.ts +52 -0
  369. package/scripts/codex-quota-alert.ts +63 -13
  370. package/scripts/continuation-dogfood.ts +2 -1
  371. package/scripts/coord-channel-watch.sh +5 -5
  372. package/scripts/coord-tracks.json +5 -4
  373. package/scripts/cron-run.ts +37 -16
  374. package/scripts/daemon-port-baseline.txt +9 -0
  375. package/scripts/design/extract-corpus-bench.ts +469 -0
  376. package/scripts/design/extract-corpus-score.ts +510 -0
  377. package/scripts/design/vendor-open-design-systems.ts +100 -0
  378. package/scripts/docs-lint.ts +1 -1
  379. package/scripts/fleet/node-setup.sh +38 -4
  380. package/scripts/heal/run-role.ts +328 -0
  381. package/scripts/install-role-watch.sh +95 -0
  382. package/scripts/install.ps1 +11 -1
  383. package/scripts/install.sh +81 -9
  384. package/scripts/isolation-hardcode-baseline.txt +1 -1
  385. package/scripts/landing-heal/must-fix-match.ts +37 -0
  386. package/scripts/landing-heal/run-mission.ts +101 -0
  387. package/scripts/lib/pwa-scenarios/acp-replay.ts +79 -0
  388. package/scripts/lib/pwa-scenarios/cdp-driver.ts +67 -0
  389. package/scripts/lib/pwa-scenarios/runner.ts +200 -0
  390. package/scripts/lib/pwa-scenarios/scenarios.ts +202 -0
  391. package/scripts/market/db-check.ts +212 -0
  392. package/scripts/market-posture-cycle.ts +63 -4
  393. package/scripts/nightly-docops.ts +1 -1
  394. package/scripts/ops/channel-bot-token-migrate.ts +146 -0
  395. package/scripts/ops-health-check.ts +15 -3
  396. package/scripts/pty-scenarios/run.ts +272 -0
  397. package/scripts/public-leak-baseline.txt +0 -7
  398. package/scripts/publish-internal-dist.ts +119 -0
  399. package/scripts/pwa-scenarios.ts +106 -0
  400. package/scripts/rebrand-elanous.ts +1 -1
  401. package/scripts/release-loop/cutoff.ts +139 -0
  402. package/scripts/release-loop/docs-land-node.ts +65 -0
  403. package/scripts/release-loop/docs-node.ts +172 -0
  404. package/scripts/release-loop/gate-diff.ts +29 -0
  405. package/scripts/release-loop/gate-node.ts +353 -0
  406. package/scripts/release-loop/node-verdict.ts +85 -0
  407. package/scripts/release-loop/prepare-node.ts +31 -0
  408. package/scripts/release-loop/publish-node.ts +57 -0
  409. package/scripts/release-loop/pwa-node-verdict.ts +45 -0
  410. package/scripts/release-loop/pwa-scenarios-node.ts +140 -0
  411. package/scripts/release-loop/release-docs.ts +102 -0
  412. package/scripts/release-loop/tui-node-checks.ts +29 -0
  413. package/scripts/release-loop/tui-sim-node.ts +113 -0
  414. package/scripts/release-loop/upgrade-node.ts +25 -0
  415. package/scripts/release-loop/verify-node.ts +21 -0
  416. package/scripts/release-loop/version-node.ts +147 -0
  417. package/scripts/release-upgrade-check.sh +53 -0
  418. package/scripts/se-mission-prepare.ts +9 -15
  419. package/scripts/test-deterministic.ts +2 -1
  420. package/scripts/uninstall.sh +10 -3
  421. package/scripts/video-broll-line.ts +89 -0
  422. package/scripts/waitlist-daily-digest.ts +108 -0
  423. package/scripts/window-landings.sh +1 -1
  424. package/skills/motion-broll/LICENSE +25 -0
  425. package/skills/motion-broll/SKILL.md +150 -0
  426. package/skills/motion-broll/SOURCE.md +6 -0
  427. package/skills/motion-broll/engine/base.css +19 -0
  428. package/skills/motion-broll/engine/beats.js +11 -0
  429. package/skills/motion-broll/engine/build.py +21 -0
  430. package/skills/motion-broll/engine/fonts/Geist-Variable.woff2 +0 -0
  431. package/skills/motion-broll/engine/fonts/GeistMono-Medium.woff2 +0 -0
  432. package/skills/motion-broll/engine/fonts/OFL-Geist.txt +92 -0
  433. package/skills/motion-broll/engine/motion.js +146 -0
  434. package/skills/motion-broll/engine/render.js +22 -0
  435. package/skills/motion-broll/examples/opus-aoe2/01-opus-drop.html +41 -0
  436. package/skills/motion-broll/examples/opus-aoe2/02-pip-builds.html +110 -0
  437. package/skills/motion-broll/examples/opus-aoe2/03-effort-slider.html +38 -0
  438. package/skills/motion-broll/examples/opus-aoe2/04-master-prompt.html +56 -0
  439. package/skills/motion-broll/examples/opus-aoe2/05-low-vs-max.html +49 -0
  440. package/skills/motion-broll/examples/opus-aoe2/06-chapter.html +18 -0
  441. package/skills/motion-broll/examples/opus-aoe2/plan.json +14 -0
  442. package/skills/motion-broll/reference/engine-api.md +106 -0
  443. package/skills/motion-broll/scripts/composite.py +14 -0
  444. package/skills/motion-broll/scripts/inspect_video.py +34 -0
  445. package/skills/motion-broll/scripts/make_pages.py +34 -0
  446. package/skills/motion-broll/scripts/setup.sh +16 -0
  447. package/skills/motion-broll/scripts/words.py +13 -0
  448. package/skills/motion-broll/templates/compare.html +135 -0
  449. package/skills/motion-broll/templates/viewer.html +97 -0
  450. package/skills/omni-digest/SKILL.md +260 -0
  451. package/skills/omni-digest/digest.md +197 -0
  452. package/skills/omni-digest/docs/diagrams/noncode-terminal-promotion-path-2026-08-13.mmd +32 -0
  453. package/skills/omni-digest/package-lock.json +558 -0
  454. package/skills/omni-digest/package.json +13 -0
  455. package/skills/omni-digest/scripts/main.ts +404 -0
  456. package/skills/omni-digest/src/delegate.ts +34 -0
  457. package/skills/omni-digest/src/detect.ts +46 -0
  458. package/skills/omni-digest/src/diagram.ts +72 -0
  459. package/skills/omni-digest/src/domain-staging.ts +50 -0
  460. package/skills/omni-digest/src/env.ts +38 -0
  461. package/skills/omni-digest/src/fetch.ts +237 -0
  462. package/skills/omni-digest/src/media.ts +180 -0
  463. package/skills/omni-digest/src/obsidian.ts +69 -0
  464. package/skills/omni-digest/src/ocr.ts +149 -0
  465. package/skills/omni-digest/src/router.ts +60 -0
  466. package/skills/omni-digest/src/summarize.ts +87 -0
  467. package/skills/omni-digest/src/types.ts +124 -0
  468. package/skills/omni-digest/src/util.ts +34 -0
  469. package/skills/omni-digest/src/visual.ts +129 -0
  470. package/skills/omni-digest/src/x-api.ts +151 -0
  471. package/skills/omni-digest/tsconfig.json +13 -0
  472. package/src/a2a/agent-card.ts +29 -0
  473. package/src/a2a/server.ts +173 -0
  474. package/src/acp/auto-persist.ts +3 -6
  475. package/src/acp/backend-registry.ts +6 -10
  476. package/src/acp/channel-browser-shell.ts +1 -535
  477. package/src/acp/client.ts +106 -36
  478. package/src/acp/fs-roots.ts +20 -4
  479. package/src/acp/obsidian-tags.ts +6 -3
  480. package/src/acp/server.ts +189 -32
  481. package/src/agent/pty-binding.ts +1 -1
  482. package/src/agent/spawn-embodied-agent-in-vw.ts +5 -336
  483. package/src/agent/subagent-callable.ts +39 -1
  484. package/src/agent-mission/browser-login.ts +241 -0
  485. package/src/agent-mission/capabilities-cli.ts +33 -0
  486. package/src/agent-mission/capability-matrix.ts +31 -0
  487. package/src/agent-mission/capability-readers.ts +79 -0
  488. package/src/agent-mission/capability-types.ts +15 -0
  489. package/src/agent-mission/claude-headless.ts +131 -0
  490. package/src/agent-mission/claude-subscription.ts +57 -0
  491. package/src/agent-mission/doc-guided-install.ts +185 -0
  492. package/src/agent-mission/driver.ts +821 -69
  493. package/src/agent-mission/env-profile.ts +68 -0
  494. package/src/agent-mission/handoff.ts +128 -0
  495. package/src/agent-mission/in-agent-plugin.ts +311 -0
  496. package/src/agent-mission/mission-cli.ts +19 -1
  497. package/src/agent-mission/parse.ts +9 -4
  498. package/src/agent-mission/pr-review-watch.ts +62 -13
  499. package/src/agent-mission/resource-ladder.ts +187 -0
  500. package/src/agent-mission/tool-install.ts +249 -0
  501. package/src/agent-mission/tool-ladder.ts +37 -0
  502. package/src/agent-room/room-builder.ts +6 -600
  503. package/src/agent-substrate/review-intent.ts +43 -1
  504. package/src/auth/scope.ts +8 -4
  505. package/src/auth/temp-tokens.ts +131 -0
  506. package/src/auto-research/obsidian-bridge.ts +2 -0
  507. package/src/autopilot/build/integrity-gate.ts +27 -4
  508. package/src/autopilot/build/isolated-instance.ts +2 -1
  509. package/src/autopilot/build/llm-conflict-merge.ts +27 -0
  510. package/src/autopilot/llm-control-brain.ts +54 -12
  511. package/src/autopilot/mission-engine.ts +15 -1
  512. package/src/autopilot/mission-notify.ts +4 -2
  513. package/src/autopilot/mission-origin.ts +5 -5
  514. package/src/autopilot/mission-phase-track.ts +52 -0
  515. package/src/autopilot/mission-tool.ts +1 -1
  516. package/src/autopilot/pty-control-loop.ts +94 -2
  517. package/src/autopilot/track-agent.ts +138 -0
  518. package/src/autopilot/track-courier.ts +153 -0
  519. package/src/boot/acp-server.ts +16 -2
  520. package/src/boot/check-same-origin.ts +19 -5
  521. package/src/boot/daemon-multi-llm-runtime.ts +14 -8
  522. package/src/boot/daemon-prompt-turn.ts +2 -0
  523. package/src/boot/daemon-runtime.ts +36 -14
  524. package/src/boot/daemon-tools/index.ts +16 -0
  525. package/src/boot/daemon-tools/self-implement.ts +4 -0
  526. package/src/boot/daemon-tools/types.ts +3 -0
  527. package/src/browser-cdp/chrome-flags.ts +7 -0
  528. package/src/browser-cdp/client.ts +2 -0
  529. package/src/browser-pane/mount.ts +1 -246
  530. package/src/budget/codex-reset-credit-state.ts +15 -0
  531. package/src/budget/fetchers/codex.ts +2 -1
  532. package/src/budget/run-usage-rollup.ts +11 -4
  533. package/src/budget/unified-usage.ts +2 -1
  534. package/src/capture/tui-self-report.ts +10 -0
  535. package/src/channel-bot-token.ts +126 -0
  536. package/src/chat/index.ts +21 -45
  537. package/src/chat/input-text-key.ts +2 -2
  538. package/src/chat/mode/manual.ts +2 -4
  539. package/src/chat/pickers/state.ts +10 -27
  540. package/src/chat/search/modal.ts +14 -2
  541. package/src/chat/tool-render/types.ts +1 -1
  542. package/src/chat/turn-typeahead.ts +2 -1
  543. package/src/chat/wrap.ts +6 -8
  544. package/src/cli/__fixtures__/agent-help-before/agent.txt +18 -0
  545. package/src/cli/__fixtures__/agent-help-before/registry.txt +13 -0
  546. package/src/cli/__fixtures__/agent-help-before/root.txt +100 -0
  547. package/src/cli/__fixtures__/agent-help-before/tier.txt +15 -0
  548. package/src/cli/a2a-cli.ts +52 -0
  549. package/src/cli/agent-cli.ts +721 -0
  550. package/src/cli/autopilot-cli.ts +739 -0
  551. package/src/cli/bg-launch.ts +20 -4
  552. package/src/cli/claude-plugin-setup.ts +199 -0
  553. package/src/cli/config-test-sync.ts +94 -10
  554. package/src/cli/connector-cli.ts +204 -0
  555. package/src/cli/control-cli.ts +220 -0
  556. package/src/cli/control-join-cli.ts +142 -0
  557. package/src/cli/docs-cli.ts +38 -0
  558. package/src/cli/doctor-cli.ts +225 -26
  559. package/src/cli/doctor-distro.ts +17 -1
  560. package/src/cli/doctor-fix.ts +145 -17
  561. package/src/cli/doctor-llm-assist.ts +71 -0
  562. package/src/cli/doctor-private-files.ts +66 -0
  563. package/src/cli/doctor-readiness.ts +8 -5
  564. package/src/cli/fleet-cli.ts +63 -0
  565. package/src/cli/g6a-registration-probe.ts +16 -0
  566. package/src/cli/git-install-plan.ts +51 -0
  567. package/src/cli/hooks-cli.ts +44 -0
  568. package/src/cli/ingest-token-cli.ts +21 -0
  569. package/src/cli/intake-cli.ts +416 -0
  570. package/src/cli/labels-cli.ts +74 -0
  571. package/src/cli/leader-cli.ts +10 -159
  572. package/src/cli/live-cli.ts +48 -0
  573. package/src/cli/llm-detect-cli.ts +130 -0
  574. package/src/cli/logs-cli.ts +231 -7
  575. package/src/cli/machine-cli.ts +38 -0
  576. package/src/cli/mcp-call.ts +43 -13
  577. package/src/cli/mcp-gateway-cli.ts +90 -0
  578. package/src/cli/mcp-login.ts +116 -8
  579. package/src/cli/mcp-reload.ts +20 -3
  580. package/src/cli/nexus-dist.ts +18 -13
  581. package/src/cli/nexus-ios-bind.ts +20 -7
  582. package/src/cli/ops-cli.ts +225 -0
  583. package/src/cli/plugin-cli.ts +103 -0
  584. package/src/cli/pod-cli.ts +83 -0
  585. package/src/cli/port-lease-local.ts +124 -0
  586. package/src/cli/pr-cli.ts +12 -1
  587. package/src/cli/provider-cli.ts +720 -0
  588. package/src/cli/pty-record-cli.ts +63 -0
  589. package/src/cli/pty-takeover-cli.ts +57 -40
  590. package/src/cli/pty-web-address.ts +52 -0
  591. package/src/cli/publish-cli.ts +44 -0
  592. package/src/cli/pwa-build.ts +18 -12
  593. package/src/cli/pwa-dev.ts +13 -8
  594. package/src/cli/pwa-registry.ts +6 -0
  595. package/src/cli/pwa-share.ts +65 -22
  596. package/src/cli/pwa-show.ts +20 -4
  597. package/src/cli/pwa-start.ts +99 -27
  598. package/src/cli/pwa-test.ts +201 -96
  599. package/src/cli/release-cli.ts +90 -7
  600. package/src/cli/remotes-cli.ts +20 -1
  601. package/src/cli/remotes.ts +2 -1
  602. package/src/cli/repo-cli.ts +315 -36
  603. package/src/cli/research-cli.ts +66 -0
  604. package/src/cli/role-cli.ts +320 -0
  605. package/src/cli/schedule-cli.ts +246 -0
  606. package/src/cli/self-update.ts +98 -10
  607. package/src/cli/setup-cli.ts +64 -2
  608. package/src/cli/shadow-cli.ts +188 -0
  609. package/src/cli/share-auto-mount.ts +12 -8
  610. package/src/cli/start-cli.ts +221 -0
  611. package/src/cli/stdout-flush.ts +8 -0
  612. package/src/cli/storage-cli.ts +334 -0
  613. package/src/cli/tailscale-serve.ts +34 -19
  614. package/src/cli/tasks-cli.ts +176 -0
  615. package/src/cli/test-state-dir-flag.ts +1 -1
  616. package/src/cli/usage-cli.ts +15 -4
  617. package/src/cli/where-cli.ts +22 -55
  618. package/src/code-edit/diff-render.ts +6 -32
  619. package/src/code-edit/source-delta-browser.ts +0 -1
  620. package/src/codex/models.ts +1 -1
  621. package/src/config.ts +8 -13
  622. package/src/connectors/event-ledger.ts +41 -0
  623. package/src/connectors/linear-projector.ts +88 -0
  624. package/src/connectors/linear.ts +143 -0
  625. package/src/connectors/types.ts +19 -0
  626. package/src/control-plane/lease-holder.ts +41 -0
  627. package/src/control-plane/ledger.ts +146 -0
  628. package/src/control-plane/light-member.ts +164 -0
  629. package/src/control-plane/member-tokens.ts +88 -0
  630. package/src/control-plane/member.ts +159 -0
  631. package/src/control-plane/port-lease-heartbeat.ts +101 -0
  632. package/src/control-plane/ports.ts +40 -0
  633. package/src/control-plane/primary.ts +169 -0
  634. package/src/control-plane/server.ts +216 -0
  635. package/src/dashboard/acp-boot.ts +11 -38
  636. package/src/dashboard/assistant-render-state-runtime.ts +2 -2
  637. package/src/dashboard/assistant-sample-runtime.ts +2 -2
  638. package/src/dashboard/auto-compact-runtime.ts +11 -16
  639. package/src/dashboard/browser-help-runtime.ts +2 -3
  640. package/src/dashboard/chat/acp-chat.ts +2 -5
  641. package/src/dashboard/code-edit-post-turn-runtime.ts +1 -2
  642. package/src/dashboard/compact-surface-assembly.ts +0 -14
  643. package/src/dashboard/compact-surface-dispatch.ts +1 -38
  644. package/src/dashboard/compact-surface-inventory.ts +0 -8
  645. package/src/dashboard/compact-surface-runtime.ts +0 -14
  646. package/src/dashboard/context-menu-provider-boot.ts +0 -9
  647. package/src/dashboard/context-window-runtime-boot.ts +0 -37
  648. package/src/dashboard/index.ts +278 -2558
  649. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +0 -6
  650. package/src/dashboard/input/chat-main-slash-command.ts +2 -2
  651. package/src/dashboard/input/dashboard-priority-key-route.ts +1 -43
  652. package/src/dashboard/input/mouse-modal-surface-runtime.ts +1 -5
  653. package/src/dashboard/input/mouse-wiring.ts +2 -3
  654. package/src/dashboard/layout-display-runtime-registration.ts +0 -10
  655. package/src/dashboard/modals/pane-multi.ts +1 -1
  656. package/src/dashboard/replay-preview.ts +1 -1
  657. package/src/dashboard/runtime/approvers.ts +0 -1
  658. package/src/dashboard/runtime/state-snapshot.ts +0 -90
  659. package/src/dashboard/scenario-runtime-boot.ts +16 -16
  660. package/src/dashboard/slash-runtime/dashboard-handlers.ts +134 -1456
  661. package/src/dashboard/slash-runtime/design-pick.ts +96 -0
  662. package/src/dashboard/slash-runtime/help-from-registry.ts +77 -0
  663. package/src/dashboard/surface-registry-wiring.ts +2 -15
  664. package/src/dashboard/turn-message-runtime.ts +0 -4
  665. package/src/dashboard/turn-preamble.ts +1 -1
  666. package/src/dashboard/turn-stream-formatter.ts +2 -2
  667. package/src/dashboard/turn-stream-runtime.ts +2 -2
  668. package/src/dashboard-pane-context-menu.ts +0 -14
  669. package/src/debug/log.ts +7 -0
  670. package/src/decide/boundary-shadow.ts +131 -0
  671. package/src/design/apply-direction.ts +209 -0
  672. package/src/design/css-root-tokens.ts +89 -0
  673. package/src/design/custom-system-create.ts +230 -0
  674. package/src/design/design-directions.ts +61 -41
  675. package/src/design/design-gate.ts +241 -0
  676. package/src/design/design-library.ts +57 -0
  677. package/src/design/design-previews.ts +138 -0
  678. package/src/design/design-systems.ts +61 -0
  679. package/src/design/lint-artifact-run.ts +46 -6
  680. package/src/design/lint-artifact.ts +5 -1
  681. package/src/design/open-design-client.ts +247 -0
  682. package/src/design/system-from-extract.ts +767 -0
  683. package/src/design/system-schema.ts +123 -0
  684. package/src/discord-slash-wire.ts +2 -1
  685. package/src/discord-test-runner.ts +2 -1
  686. package/src/discord-voice-wire.ts +2 -1
  687. package/src/discord.ts +1 -1
  688. package/src/dispatch/opportunistic-launcher.ts +24 -1
  689. package/src/domains/ops-status.ts +35 -2
  690. package/src/domains/outbound-alert.ts +16 -4
  691. package/src/domains/repeated-failure.ts +89 -0
  692. package/src/domains/schedule-manage-tool.ts +28 -8
  693. package/src/domains/schedule-migrate.ts +22 -4
  694. package/src/domains/schedule-registry.ts +88 -33
  695. package/src/domains/schedule-runs.ts +132 -0
  696. package/src/domains/schedule-state.ts +152 -0
  697. package/src/element-registry/address.ts +1 -3
  698. package/src/git-fs/gh-cli.ts +47 -17
  699. package/src/git-fs/retry.ts +1 -0
  700. package/src/git-fs/runner.ts +1 -0
  701. package/src/git-fs/worktree.ts +6 -5
  702. package/src/github/pr-labels.ts +68 -0
  703. package/src/graph-kinds/plugin-nodes.ts +60 -0
  704. package/src/graph-kinds/registry.ts +118 -0
  705. package/src/graph-runner/graph-cli.ts +103 -0
  706. package/src/graph-runner/graph-notify.ts +220 -0
  707. package/src/graph-runner/graph-tick.ts +119 -0
  708. package/src/graph-runner/release-manifest.ts +93 -0
  709. package/src/graph-runner/runner.ts +457 -0
  710. package/src/grok/credential.ts +158 -5
  711. package/src/grounding/ensure-grounding.ts +131 -0
  712. package/src/grounding/mirror-export.ts +89 -0
  713. package/src/grounding/mirror-manifest.ts +252 -0
  714. package/src/grounding/sources-cli.ts +209 -0
  715. package/src/grounding/sources.ts +333 -0
  716. package/src/grounding/token.ts +115 -0
  717. package/src/harness/harness-cli-command.ts +352 -19
  718. package/src/harness/harness-pod-dispatch.ts +110 -0
  719. package/src/harness/harness-stop.ts +131 -0
  720. package/src/harness/harness-substrate-default.ts +40 -0
  721. package/src/harness/harness-worktrees.ts +1 -1
  722. package/src/harness/harness-write-boundary.ts +2 -0
  723. package/src/harness/llm-decompose.ts +2 -1
  724. package/src/harness/self-send-decide.ts +224 -0
  725. package/src/harness/shell-relay.ts +5 -0
  726. package/src/hooks/providers.ts +77 -0
  727. package/src/hooks/queue.ts +73 -0
  728. package/src/hooks/receiver.ts +133 -0
  729. package/src/index.ts +666 -3406
  730. package/src/input-core/dispatcher.ts +1 -1
  731. package/src/input-core/drag-esc-interceptor.ts +1 -1
  732. package/src/instance/current.ts +5 -5
  733. package/src/instance/leader.ts +10 -326
  734. package/src/instance/nexus-run-refusal.ts +27 -92
  735. package/src/instance/project-local-exclude.ts +27 -0
  736. package/src/instance/resolve.ts +40 -175
  737. package/src/intake-plane/capture.ts +14 -1
  738. package/src/intake-plane/check.ts +34 -14
  739. package/src/intake-plane/collect-github.ts +258 -0
  740. package/src/intake-plane/collect-pod.ts +100 -0
  741. package/src/intake-plane/collect-telegram-saved.ts +86 -0
  742. package/src/intake-plane/digest.ts +102 -0
  743. package/src/intake-plane/enrich-plugins.ts +1 -1
  744. package/src/intake-plane/front-classifier.ts +56 -0
  745. package/src/intake-plane/front-route-classifier.ts +80 -0
  746. package/src/intake-plane/front-route-rules.ts +152 -0
  747. package/src/intake-plane/grounding-docs.ts +185 -0
  748. package/src/intake-plane/harness-target.ts +20 -0
  749. package/src/intake-plane/intake-to-tasks.ts +303 -0
  750. package/src/intake-plane/items.ts +247 -0
  751. package/src/intake-plane/link-ledger.ts +27 -0
  752. package/src/intake-plane/route.ts +104 -0
  753. package/src/intake-plane/runtime-callables.ts +3 -1
  754. package/src/intake-plane/sketch-ledger.ts +34 -0
  755. package/src/intake-plane/slash.ts +30 -2
  756. package/src/intake-plane/submit-intake-work.ts +160 -0
  757. package/src/intake-plane/telegram-work.ts +56 -0
  758. package/src/iul/sidebar-shell.ts +0 -165
  759. package/src/launch-head/capability-check.ts +162 -0
  760. package/src/launch-head/launch-head-cli.ts +242 -0
  761. package/src/launch-head/load-balance.ts +81 -0
  762. package/src/live/detail-switch.ts +175 -0
  763. package/src/llm/provider-detect.ts +247 -0
  764. package/src/llm/provider-probe.ts +57 -0
  765. package/src/llm.ts +55 -23
  766. package/src/log-entry.ts +1 -1
  767. package/src/log-pane/attachment-popup.ts +1 -2
  768. package/src/loops/loop-cli.ts +37 -0
  769. package/src/loops/registry.ts +174 -0
  770. package/src/market/official-keys.ts +5 -0
  771. package/src/market/publish.ts +273 -0
  772. package/src/market/signed-index.ts +156 -0
  773. package/src/market/tgz.ts +121 -0
  774. package/src/mcp/client.ts +1 -1
  775. package/src/mcp/mcp-oauth.ts +40 -5
  776. package/src/mcp/server.ts +75 -7
  777. package/src/mcp-gateway/gateway.ts +128 -0
  778. package/src/mcp-gateway/pat-store.ts +124 -0
  779. package/src/mss/logging/log-store.ts +91 -2
  780. package/src/mss/logging/scoped-level.ts +5 -9
  781. package/src/native-tool-catalog.ts +64 -343
  782. package/src/nexus/api/connect-info.ts +23 -25
  783. package/src/nexus/api/context-url.ts +1 -1
  784. package/src/nexus/api/design-check.ts +90 -59
  785. package/src/nexus/api/design-previews-route.ts +182 -0
  786. package/src/nexus/api/design-system-create-route.ts +123 -0
  787. package/src/nexus/api/graph-kinds.ts +69 -0
  788. package/src/nexus/api/graphs-api.ts +221 -0
  789. package/src/nexus/api/harness-api.ts +31 -2
  790. package/src/nexus/api/health.ts +15 -0
  791. package/src/nexus/api/http-server.ts +274 -43
  792. package/src/nexus/api/image-generate.ts +3 -0
  793. package/src/nexus/api/ingest-token.ts +175 -0
  794. package/src/nexus/api/intake-ledger-api.ts +54 -0
  795. package/src/nexus/api/intake-route.ts +111 -0
  796. package/src/nexus/api/json-response.ts +33 -0
  797. package/src/nexus/api/live-detail.ts +47 -0
  798. package/src/nexus/api/live-shipped.ts +78 -0
  799. package/src/nexus/api/log-fabric.ts +33 -2
  800. package/src/nexus/api/markdown-publish.ts +3 -2
  801. package/src/nexus/api/mcp-http.ts +14 -9
  802. package/src/nexus/api/mcp-oauth-hint.ts +30 -0
  803. package/src/nexus/api/mcp-public-allowlist.ts +33 -0
  804. package/src/nexus/api/merge-approvals-gate.ts +79 -0
  805. package/src/nexus/api/merge-approvals.ts +306 -0
  806. package/src/nexus/api/meta-api.ts +4 -0
  807. package/src/nexus/api/next-fluent-wiring.ts +7 -9
  808. package/src/nexus/api/plugins-market.ts +125 -0
  809. package/src/nexus/api/pod-credential-api.ts +133 -0
  810. package/src/nexus/api/public-routes.ts +80 -0
  811. package/src/nexus/api/rest-route-paths.ts +15 -0
  812. package/src/nexus/api/schedules-action.ts +12 -3
  813. package/src/nexus/api/schedules-read.ts +228 -0
  814. package/src/nexus/api/sessions-store.ts +8 -2
  815. package/src/nexus/api/setup-answer-priority.ts +130 -0
  816. package/src/nexus/api/setup-channel-bot.ts +56 -0
  817. package/src/nexus/api/setup-child-llm.ts +228 -0
  818. package/src/nexus/api/setup-obsidian-skills.ts +93 -0
  819. package/src/nexus/api/task-cards-api.ts +34 -0
  820. package/src/nexus/api/tasks-create.ts +136 -0
  821. package/src/nexus/api/telegram-trigger-bot.ts +3 -3
  822. package/src/nexus/api/terminals.ts +204 -18
  823. package/src/nexus/api/trace.ts +354 -0
  824. package/src/nexus/api/vault-api.ts +140 -7
  825. package/src/nexus/api/worktrees.ts +18 -2
  826. package/src/nexus/boot/register-mcp-clients.ts +38 -4
  827. package/src/nexus/daemon-endpoint.ts +85 -0
  828. package/src/nexus/default-port.ts +1 -0
  829. package/src/nexus/index.ts +329 -111
  830. package/src/nexus/onboarding/pwa-share-prompt.ts +31 -8
  831. package/src/nexus/onboarding/tailscale-probe.ts +9 -1
  832. package/src/nexus/setup-status.ts +58 -0
  833. package/src/nexus/supervisor/lock.ts +8 -0
  834. package/src/nexus/webterm/pty.ts +15 -0
  835. package/src/oauth/codex-account-rotation.ts +122 -16
  836. package/src/oauth/codex-account-store.ts +88 -19
  837. package/src/oauth/codex-quota-policy.ts +55 -0
  838. package/src/oauth/store.ts +28 -25
  839. package/src/obsidian/default-vault.ts +17 -0
  840. package/src/obsidian/vault-write-guard.ts +46 -0
  841. package/src/onboarding/help/llm.md +2 -2
  842. package/src/onboarding.ts +2 -2
  843. package/src/panes/alt-skip-predicate.ts +4 -3
  844. package/src/panes/external-terminal-pane.ts +3 -4
  845. package/src/panes/factory.ts +1 -18
  846. package/src/panes/index.ts +1 -5
  847. package/src/panes/pane-cycle.ts +1 -1
  848. package/src/panes/types.ts +1 -1
  849. package/src/platform/env-literal.ts +4 -0
  850. package/src/plugin-hooks/dispatcher.ts +10 -4
  851. package/src/plugins/core/host.ts +94 -4
  852. package/src/plugins/core/manifest.ts +104 -7
  853. package/src/plugins/install/market-fetch.ts +249 -0
  854. package/src/plugins/install/plugin-install.ts +387 -0
  855. package/src/policy/claude-subscription-guard.ts +25 -0
  856. package/src/preview/terminal.ts +24 -1
  857. package/src/preview-pane/mount.ts +1 -142
  858. package/src/prompt/references.ts +4 -51
  859. package/src/pty-shell/pty-control-ipc.ts +57 -3
  860. package/src/pty-shell/pty-mouse.ts +75 -0
  861. package/src/pty-shell/pty-recording.ts +108 -0
  862. package/src/pty-shell/registry.ts +53 -3
  863. package/src/python/resolve-python.ts +1 -1
  864. package/src/release-loop/manifest.ts +65 -0
  865. package/src/release-loop/release-note.ts +174 -0
  866. package/src/roles/lease-cas.ts +52 -0
  867. package/src/roles/machine-name.ts +48 -0
  868. package/src/roles/machine-profile.ts +65 -0
  869. package/src/roles/role-lease-read.ts +81 -0
  870. package/src/roles/role-lease.ts +63 -0
  871. package/src/roles/role-watch.ts +69 -0
  872. package/src/self-dev/ask-launch-flow.ts +39 -22
  873. package/src/self-dev/ask-launch-io.ts +1 -1
  874. package/src/self-dev/dev-cli.ts +250 -139
  875. package/src/self-dev/dev-pipeline.ts +80 -8
  876. package/src/self-dev/draft-sweep.ts +231 -0
  877. package/src/self-dev/draft-triage-rules.ts +42 -0
  878. package/src/self-dev/entrance-baseline.ts +156 -4
  879. package/src/self-dev/fabric-decompose-adapter.ts +10 -0
  880. package/src/self-dev/launch-preflight.ts +1 -1
  881. package/src/self-dev/orchestrate.ts +297 -20
  882. package/src/self-dev/repair-signals.ts +6 -0
  883. package/src/self-dev/run-store.ts +20 -5
  884. package/src/self-dev/run-supervisor.ts +43 -3
  885. package/src/self-implement/abandoned-classification.ts +15 -1
  886. package/src/self-implement/blocked-draft-policy.ts +6 -0
  887. package/src/self-implement/budget-gate.ts +236 -0
  888. package/src/self-implement/child-llm-preference.ts +84 -0
  889. package/src/self-implement/decision-events.ts +57 -0
  890. package/src/self-implement/decision-signal-press.ts +5 -2
  891. package/src/self-implement/dependency-change-gate.ts +90 -0
  892. package/src/self-implement/gate-baseline.ts +32 -1
  893. package/src/self-implement/gate-cli.ts +29 -7
  894. package/src/self-implement/gate-scope.ts +7 -1
  895. package/src/self-implement/goal-author-decompose.ts +22 -4
  896. package/src/self-implement/goal-author.ts +23 -2
  897. package/src/self-implement/goal-boundary.ts +65 -0
  898. package/src/self-implement/goal-clarification-escalation.ts +1 -0
  899. package/src/self-implement/goal-documents-dir.ts +6 -1
  900. package/src/self-implement/goal-execution-records.ts +58 -0
  901. package/src/self-implement/goal-run-store.ts +42 -24
  902. package/src/self-implement/graph-authority.ts +13 -28
  903. package/src/self-implement/graph-catalog.ts +48 -0
  904. package/src/self-implement/graph-run-contract.ts +127 -0
  905. package/src/self-implement/graph-templates.ts +14 -7
  906. package/src/self-implement/graph-yaml.ts +35 -6
  907. package/src/self-implement/harness-policy-gates.ts +42 -0
  908. package/src/self-implement/headless-elanous-driver.ts +30 -6
  909. package/src/self-implement/heal-triage.ts +229 -0
  910. package/src/self-implement/host-regate.ts +240 -0
  911. package/src/self-implement/non-git-consent.ts +23 -0
  912. package/src/self-implement/orchestrator.ts +481 -132
  913. package/src/self-implement/pipeline-shape.ts +1 -1
  914. package/src/self-implement/pr-evidence-artifact.ts +6 -19
  915. package/src/self-implement/prior-draft-findings.ts +128 -0
  916. package/src/self-implement/pwa-import-graph.ts +65 -0
  917. package/src/self-implement/repo-provision.ts +18 -21
  918. package/src/self-implement/report-origin.ts +39 -0
  919. package/src/self-implement/rework-policy.ts +21 -0
  920. package/src/self-implement/run-ledger-compact.ts +438 -0
  921. package/src/self-implement/run-ledger.ts +212 -29
  922. package/src/self-implement/run-report.ts +24 -0
  923. package/src/self-implement/run-status-mapping.ts +2 -0
  924. package/src/self-implement/running-runs.ts +112 -14
  925. package/src/self-implement/scoped-typecheck-config.ts +49 -0
  926. package/src/self-implement/seams.ts +203 -38
  927. package/src/self-implement/self-implement-cli.ts +17 -2
  928. package/src/self-implement/shadow-repo.ts +350 -0
  929. package/src/self-implement/supervision-vocabulary.ts +7 -0
  930. package/src/shell-runner/dispatch.ts +3 -0
  931. package/src/shell-runner/index.ts +0 -7
  932. package/src/skills/runner.ts +0 -69
  933. package/src/skills/tools/agent-room-slash.ts +2 -1
  934. package/src/skills/tools/agent-room.ts +8 -140
  935. package/src/skills/tools/agent.ts +5 -3
  936. package/src/skills/tools/context.ts +5 -140
  937. package/src/skills/tools/control.ts +4 -188
  938. package/src/skills/tools/dashboard-slash.ts +3 -11
  939. package/src/skills/tools/dashboard-state.ts +3 -5
  940. package/src/skills/tools/dev-harness.ts +3 -2
  941. package/src/skills/tools/omni-search.ts +29 -1
  942. package/src/skills/tools/shell.ts +11 -29
  943. package/src/skills/tools/spawn-coding-agent-headless.ts +6 -9
  944. package/src/ssh/ssh-picker-modal.ts +1 -1
  945. package/src/steward/directive.ts +99 -0
  946. package/src/steward/triage.ts +203 -0
  947. package/src/storage/cli-bin.ts +67 -0
  948. package/src/storage/object-store-visibility.ts +169 -0
  949. package/src/storage/object-store.ts +452 -0
  950. package/src/storage/s3.ts +53 -10
  951. package/src/storage/storage-detect.ts +337 -0
  952. package/src/surface/address.ts +3 -5
  953. package/src/surface/index.ts +0 -6
  954. package/src/surface/llm-tools.ts +1 -2
  955. package/src/surface/shell-runner-boot.ts +4 -89
  956. package/src/task-cards/card-cli.ts +64 -0
  957. package/src/task-cards/card-store.ts +241 -0
  958. package/src/task-orchestrator/boot.ts +27 -1
  959. package/src/task-orchestrator/dispatcher.ts +49 -7
  960. package/src/task-orchestrator/external-fingerprint.ts +10 -0
  961. package/src/task-orchestrator/external-policy.ts +86 -0
  962. package/src/task-orchestrator/feedback-loop.ts +4 -2
  963. package/src/task-orchestrator/graph.ts +18 -1
  964. package/src/task-orchestrator/runtimes/create.ts +128 -0
  965. package/src/task-orchestrator/store.ts +78 -18
  966. package/src/task-orchestrator/surface-registry.ts +5 -2
  967. package/src/task-orchestrator/surfaces/external-exec.ts +180 -0
  968. package/src/task-orchestrator/surfaces/idea-approval-pr.ts +118 -0
  969. package/src/task-orchestrator/surfaces/index.ts +4 -3
  970. package/src/task-orchestrator/surfaces/pod-account-broker.ts +60 -5
  971. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +136 -0
  972. package/src/task-orchestrator/surfaces/pod-command-job.ts +348 -0
  973. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +177 -0
  974. package/src/task-orchestrator/surfaces/pod-pool.ts +128 -12
  975. package/src/task-orchestrator/surfaces/pod-skills.ts +11 -3
  976. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +132 -0
  977. package/src/task-orchestrator/surfaces/pod-source-receive.ts +91 -0
  978. package/src/task-orchestrator/surfaces/pod-source-spec.ts +77 -0
  979. package/src/task-orchestrator/surfaces/self-implement-pod.ts +782 -41
  980. package/src/task-orchestrator/surfaces/self-implement.ts +8 -1
  981. package/src/task-orchestrator/tox-loop.ts +204 -0
  982. package/src/task-orchestrator/types.ts +21 -1
  983. package/src/telegram-commands.ts +8 -0
  984. package/src/telegram-report.ts +2 -1
  985. package/src/telegram-run.ts +18 -5
  986. package/src/telegram.ts +92 -22
  987. package/src/tool-runtime/acp-session-runtime.ts +28 -7
  988. package/src/tool-runtime/agent-runtime.ts +1 -0
  989. package/src/tool-runtime/context-runtime.ts +18 -35
  990. package/src/tool-runtime/control-runtime.ts +8 -21
  991. package/src/tool-runtime/dashboard-state-runtime.ts +1 -5
  992. package/src/tool-runtime/elanous-asana-runtimes.ts +205 -0
  993. package/src/tool-runtime/elanous-control-runtimes.ts +16 -2
  994. package/src/tool-runtime/elanous-task-submit-runtime.ts +124 -0
  995. package/src/tool-runtime/index.ts +4 -1
  996. package/src/tool-runtime/scenario-runtimes.ts +22 -21
  997. package/src/tool-runtime/scenario-target-mount.ts +6 -32
  998. package/src/tool-runtime/types.ts +8 -0
  999. package/src/tui/chat/attachment-summary.ts +4 -4
  1000. package/src/tui-client/headless-core-guard.ts +0 -1
  1001. package/src/tui.ts +8 -5
  1002. package/src/typecheck-ratchet.ts +15 -0
  1003. package/src/ui/hover-presenter.ts +3 -7
  1004. package/src/user-config.ts +427 -190
  1005. package/src/version/code-revision.ts +33 -8
  1006. package/src/version/packed-revision.json +1 -1
  1007. package/src/video-pipeline/broll-agent.ts +102 -0
  1008. package/src/video-pipeline/recipes/broll.ts +263 -0
  1009. package/src/video-pipeline/walk-line.ts +2 -1
  1010. package/src/views/scratch-image-size.ts +10 -0
  1011. package/src/voice/channel-adapters/pwa-voice-adapter.ts +2 -18
  1012. package/src/voice/channel-adapters/telegram-voice-adapter.ts +1 -6
  1013. package/src/voice/voice-tts-singleton.ts +46 -8
  1014. package/src/web-push/vapid-keys.ts +1 -1
  1015. package/src/web-search/index.ts +5 -5
  1016. package/src/web-terminal/preview-tap-registry.ts +152 -43
  1017. package/src/workflow-runtime/executor.ts +18 -22
  1018. package/src/workflow-runtime/node-catalog.ts +20 -1
  1019. package/src/workflow-runtime/nodes/bash.ts +1 -0
  1020. package/src/workflow-runtime/nodes/task.ts +74 -0
  1021. package/src/workflow-runtime/nodes/triggers.ts +24 -1
  1022. package/src/workflow-runtime/plugin-kind-node.ts +138 -0
  1023. package/src/workflow-runtime/schema.ts +98 -2
  1024. package/src/workflow-runtime/triggers/webhook-router.ts +43 -3
  1025. package/src/workflow-runtime/triggers/webhook-source.ts +19 -1
  1026. package/src/workflow-runtime/types.ts +74 -4
  1027. package/apps/pwa/out/_next/static/Ksn99fVf2HUWhSyV1-FC8/_buildManifest.js +0 -1
  1028. package/apps/pwa/out/_next/static/chunks/1176-4943bd83b00e53a2.js +0 -25
  1029. package/apps/pwa/out/_next/static/chunks/1380-9c652e1002032c86.js +0 -1
  1030. package/apps/pwa/out/_next/static/chunks/1863-2ea170dfec26b88b.js +0 -1
  1031. package/apps/pwa/out/_next/static/chunks/2091-2d6b7f4f16300f83.js +0 -1
  1032. package/apps/pwa/out/_next/static/chunks/2347-366617ec73babe3b.js +0 -1
  1033. package/apps/pwa/out/_next/static/chunks/2598.814f64e3268634e7.js +0 -1
  1034. package/apps/pwa/out/_next/static/chunks/3089-e60cc8f5d35ee239.js +0 -1
  1035. package/apps/pwa/out/_next/static/chunks/3158-c77ed9ea34f9cc9f.js +0 -1
  1036. package/apps/pwa/out/_next/static/chunks/3607-f0b5c5ee18fcf56a.js +0 -1
  1037. package/apps/pwa/out/_next/static/chunks/3659-05b2d5d971b42dbc.js +0 -1
  1038. package/apps/pwa/out/_next/static/chunks/3736-b6a7bfdcb8f56ec6.js +0 -1
  1039. package/apps/pwa/out/_next/static/chunks/3839-eebf298e89a7bb77.js +0 -1
  1040. package/apps/pwa/out/_next/static/chunks/4012.832a2824b978e7ee.js +0 -5
  1041. package/apps/pwa/out/_next/static/chunks/4706-d85d7f3345f3ff91.js +0 -1
  1042. package/apps/pwa/out/_next/static/chunks/526-17a6a2e0e6dc4498.js +0 -1
  1043. package/apps/pwa/out/_next/static/chunks/5508-676ac75f2757ad40.js +0 -1
  1044. package/apps/pwa/out/_next/static/chunks/5583-8a0317f4b8e68db9.js +0 -1
  1045. package/apps/pwa/out/_next/static/chunks/5927.8378481a12cc8044.js +0 -1
  1046. package/apps/pwa/out/_next/static/chunks/6258-b58f722b10e8d31d.js +0 -1
  1047. package/apps/pwa/out/_next/static/chunks/6820-32fd097e6186fdc9.js +0 -1
  1048. package/apps/pwa/out/_next/static/chunks/6852-983db7ca958634b7.js +0 -1
  1049. package/apps/pwa/out/_next/static/chunks/7235-e583e4a015e159b9.js +0 -1
  1050. package/apps/pwa/out/_next/static/chunks/7482-7b417330b24a996a.js +0 -1
  1051. package/apps/pwa/out/_next/static/chunks/7701-99b7d4dedb955bf8.js +0 -1
  1052. package/apps/pwa/out/_next/static/chunks/77f1928d-bd3777589042d3ea.js +0 -1
  1053. package/apps/pwa/out/_next/static/chunks/8366-36956cafc5e33614.js +0 -1
  1054. package/apps/pwa/out/_next/static/chunks/8370-23d0de995be666f8.js +0 -1
  1055. package/apps/pwa/out/_next/static/chunks/8617-307421f3b0e8b2a2.js +0 -1
  1056. package/apps/pwa/out/_next/static/chunks/8837-e45de46a9fedf1f5.js +0 -1
  1057. package/apps/pwa/out/_next/static/chunks/9058-0e8055a5ea3ebdd6.js +0 -1
  1058. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-84b84eca12acada4.js +0 -1
  1059. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-1f23568c29e88f7a.js +0 -1
  1060. package/apps/pwa/out/_next/static/chunks/app/botlab/page-bf6fc9aafd6135a7.js +0 -1
  1061. package/apps/pwa/out/_next/static/chunks/app/bots/page-3f8539ae4b719d2e.js +0 -1
  1062. package/apps/pwa/out/_next/static/chunks/app/chat/page-d2900febb74ecf32.js +0 -1
  1063. package/apps/pwa/out/_next/static/chunks/app/control/page-e82dec647dd79c36.js +0 -1
  1064. package/apps/pwa/out/_next/static/chunks/app/dashboard/page-096ec743a8ee955a.js +0 -1
  1065. package/apps/pwa/out/_next/static/chunks/app/design-check/page-255c2ceded4b3493.js +0 -1
  1066. package/apps/pwa/out/_next/static/chunks/app/healthz/route-84b84eca12acada4.js +0 -1
  1067. package/apps/pwa/out/_next/static/chunks/app/intake/page-2db61b2f9efba61f.js +0 -1
  1068. package/apps/pwa/out/_next/static/chunks/app/layout-e11ee17f221aaa9b.js +0 -1
  1069. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e075974e029ce4c4.js +0 -1
  1070. package/apps/pwa/out/_next/static/chunks/app/morning/page-ec5b68a9af3366a0.js +0 -1
  1071. package/apps/pwa/out/_next/static/chunks/app/not-found-986c177afb4adae6.js +0 -1
  1072. package/apps/pwa/out/_next/static/chunks/app/observatory/page-a72781461af2f2a3.js +0 -1
  1073. package/apps/pwa/out/_next/static/chunks/app/page-92781cbaafc487ad.js +0 -1
  1074. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2c14d2a1f2930f33.js +0 -1
  1075. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-22ee4bf8070b2b4d.js +0 -1
  1076. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9c06e4a8297942a8.js +0 -1
  1077. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d0cd32f6d373798f.js +0 -1
  1078. package/apps/pwa/out/_next/static/chunks/app/settings/page-0c1642018d87ebb8.js +0 -1
  1079. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-93e5e97d614df487.js +0 -1
  1080. package/apps/pwa/out/_next/static/chunks/app/setup/layout-84b84eca12acada4.js +0 -1
  1081. package/apps/pwa/out/_next/static/chunks/app/setup/page-b1ce871940d7393e.js +0 -1
  1082. package/apps/pwa/out/_next/static/chunks/app/share/page-ae154addf345febe.js +0 -1
  1083. package/apps/pwa/out/_next/static/chunks/app/showroom/page-90af3aa813d2053c.js +0 -1
  1084. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f3f962fda428a738.js +0 -1
  1085. package/apps/pwa/out/_next/static/chunks/app/term/page-1c1f7cc1d5def06d.js +0 -1
  1086. package/apps/pwa/out/_next/static/chunks/app/vault/page-09d4cbdaaacf06c1.js +0 -1
  1087. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e877b8e8ca90b27f.js +0 -1
  1088. package/apps/pwa/out/_next/static/chunks/app/workflows/page-71d902f463dea526.js +0 -1
  1089. package/apps/pwa/out/_next/static/chunks/app/workspace/page-40ea576cefa25fe6.js +0 -1
  1090. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a56a3f178c3831f6.js +0 -1
  1091. package/apps/pwa/out/_next/static/chunks/bcc499d1-804a270d878e0842.js +0 -1
  1092. package/apps/pwa/out/_next/static/chunks/framework-b25b7c5501c59b6d.js +0 -1
  1093. package/apps/pwa/out/_next/static/chunks/main-a9ec9da43387afff.js +0 -1
  1094. package/apps/pwa/out/_next/static/chunks/main-app-aa2c05954aaa6754.js +0 -1
  1095. package/apps/pwa/out/_next/static/chunks/pages/_app-bb3768fb4b84aebb.js +0 -1
  1096. package/apps/pwa/out/_next/static/chunks/pages/_error-2820ba75b87b2f5e.js +0 -1
  1097. package/apps/pwa/out/_next/static/chunks/webpack-58c73b145f189b1c.js +0 -1
  1098. package/apps/pwa/out/_next/static/css/effec8adf767aa75.css +0 -1
  1099. package/apps/pwa/out/dashboard/index.html +0 -1
  1100. package/apps/pwa/out/dashboard/index.txt +0 -26
  1101. package/src/acp/resident-shell.ts +0 -244
  1102. package/src/agent/spawn-local-llm-in-vw.ts +0 -240
  1103. package/src/dashboard/agent-spawn-tools-boot.ts +0 -14
  1104. package/src/dashboard/dock-picker-inventory.ts +0 -41
  1105. package/src/dashboard/goal-plan-hud-bridge.ts +0 -112
  1106. package/src/dashboard/hud-mirror.ts +0 -207
  1107. package/src/dashboard/input/mouse-dock-runtime.ts +0 -156
  1108. package/src/dashboard/input/mouse-hover-runtime.ts +0 -46
  1109. package/src/dashboard/input/mouse-pill-context-runtime.ts +0 -74
  1110. package/src/dashboard/input/mouse-workspace-restore-runtime.ts +0 -64
  1111. package/src/dashboard/input/scratch-actions.ts +0 -36
  1112. package/src/dashboard/input/virtual-window-key-router.ts +0 -24
  1113. package/src/dashboard/rich-scratch-viewers.ts +0 -77
  1114. package/src/dashboard/scratch-slash-runtime.ts +0 -36
  1115. package/src/dashboard/scratch-state-runtime.ts +0 -42
  1116. package/src/dashboard/scratch-widget-runtime.ts +0 -37
  1117. package/src/dashboard/sim-shell.ts +0 -313
  1118. package/src/dashboard/virtual-window-control-runtime.ts +0 -57
  1119. package/src/dashboard/virtual-window-help-runtime.ts +0 -113
  1120. package/src/dashboard/virtual-window-input-runtime.ts +0 -99
  1121. package/src/dashboard/virtual-window-mutation-runtime.ts +0 -102
  1122. package/src/dashboard/virtual-window-split-runtime.ts +0 -70
  1123. package/src/dashboard/vw-popup-openers.ts +0 -126
  1124. package/src/dashboard/window-picker-popup.ts +0 -74
  1125. package/src/dashboard/window-slash-runtime.ts +0 -108
  1126. package/src/dashboard/windowing/companion-slash.ts +0 -78
  1127. package/src/dashboard/windowing/fast-switch.ts +0 -138
  1128. package/src/dashboard/windowing/lifecycle.ts +0 -185
  1129. package/src/dashboard/windowing/virtual-windows.ts +0 -259
  1130. package/src/dashboard/windowing/visibility-chord.ts +0 -77
  1131. package/src/iul/resident-vw.ts +0 -55
  1132. package/src/panes/content-adapter.ts +0 -162
  1133. package/src/prompt/vw-reference.ts +0 -153
  1134. package/src/shell-runner/external-terminal-pane.ts +0 -157
  1135. package/src/sim/resident-vw.ts +0 -48
  1136. package/src/skills/tools/spawn-coding-agent-vw.ts +0 -181
  1137. package/src/skills/tools/virtual-windows.ts +0 -632
  1138. package/src/surface/adapters/window-surface-adapter.ts +0 -141
  1139. package/src/tool-runtime/layout-runtimes.ts +0 -81
  1140. package/src/tool-runtime/scenario-window-mount.ts +0 -207
  1141. package/src/views/ui-mode.ts +0 -100
  1142. package/src/virtual-window-context-menu.ts +0 -97
  1143. package/src/virtual-windows/addressing.ts +0 -195
  1144. package/src/virtual-windows/benchmark-preset.ts +0 -119
  1145. package/src/virtual-windows/event-bus.ts +0 -202
  1146. package/src/virtual-windows/layout/apply-planner.ts +0 -189
  1147. package/src/virtual-windows/layout/index.ts +0 -68
  1148. package/src/virtual-windows/layout/layout-commands.ts +0 -186
  1149. package/src/virtual-windows/layout/layout-tools.ts +0 -262
  1150. package/src/virtual-windows/layout/persistence.ts +0 -219
  1151. package/src/virtual-windows/layout/presets.ts +0 -114
  1152. package/src/virtual-windows/layout/restore-planner.ts +0 -223
  1153. package/src/virtual-windows/layout/serializer.ts +0 -197
  1154. package/src/virtual-windows/layout/tree.ts +0 -147
  1155. package/src/virtual-windows/layout/types.ts +0 -63
  1156. package/src/virtual-windows/layout-tree.ts +0 -389
  1157. package/src/virtual-windows/navigation.ts +0 -251
  1158. package/src/virtual-windows/pane-capture.ts +0 -142
  1159. package/src/virtual-windows/pane-content.ts +0 -611
  1160. package/src/virtual-windows/pane-spawner.ts +0 -278
  1161. package/src/virtual-windows/pty-tail-content.ts +0 -291
  1162. package/src/virtual-windows/resident-window.ts +0 -59
  1163. package/src/virtual-windows/secondary-action.ts +0 -25
  1164. package/src/virtual-windows/terminal-slot-content.ts +0 -165
  1165. package/src/virtual-windows/virtual-window.ts +0 -1301
  1166. package/src/virtual-windows/vw-local-input-target-popup.ts +0 -110
  1167. package/src/virtual-windows/vw-rename-modal.ts +0 -77
  1168. package/src/virtual-windows/vw-selector-popup.ts +0 -177
  1169. package/src/virtual-windows/window-registry.ts +0 -519
  1170. package/src/voice/channel-adapters/discord-voice-adapter.ts +0 -202
  1171. package/src/voice/voice-pwa-dispatch.ts +0 -245
  1172. package/src/window-picker-modal.ts +0 -135
  1173. /package/apps/pwa/out/_next/static/{Ksn99fVf2HUWhSyV1-FC8 → zoQX5iTvXOsIvCjxCe1Ji}/_ssgManifest.js +0 -0
  1174. /package/src/dashboard/{companion-slash-runtime.ts → companion-messages-runtime.ts} +0 -0
@@ -1,21 +1,6 @@
1
1
  // Dashboard slash command handlers · migrated cases from the inline
2
2
  // switch in dashboard/index.ts. Sub-phase tracking:
3
3
  //
4
- // B-3.d — /workspace /ws /window /win + /codex-vw /acp-vw
5
- // /claude-vw — closes Phase B-3 (last cluster).
6
- // `workspaceSlash` ctx bundle threads windowSlash
7
- // Runtime + virtualWindows.registry subset + 7
8
- // spawn helpers + openWindowPicker + 2 companion
9
- // ops. `acpVwSlash` ctx bundle covers cwd() +
10
- // vwRegistry for the spawn-coding-agent paths.
11
- // /codex-vw + /acp-vw + /claude-vw share a body but
12
- // discriminate on cmdLower; registered as 3 names
13
- // each closing over the brand label (matches the
14
- // B-2.m /claude /codex /gemini pattern).
15
- // spawnAcpLiveSessionInVW + parseWindowCompanion
16
- // Slash hoisted from dynamic to static imports.
17
- // /codex-vw reuses ctx.conv.openModal (B-2.w) for
18
- // openConversationModal. Behavior preserved verbatim.
19
4
  // B-3.c.2 — /term /terminal — second half of the third B-3
20
5
  // cluster. The biggest single case (681 LOC inline ·
21
6
  // 23 subcommands across 6 host-local subsystems —
@@ -130,17 +115,6 @@
130
115
  // factory output (controlSignal · browserCdp ·
131
116
  // widgetHost). The runtimes are showDashboard-local,
132
117
  // so they're threaded via ctx as opaque shapes.
133
- // B-2.AA — /bench — LLM benchmark window spawner. The
134
- // `MAX_BENCHMARK_PANES` constant is static-imported.
135
- // `spawnLLMBenchmark` requires host-local
136
- // virtualWindows refs; threaded behind `bench.spawn`
137
- // ctx method that returns just the new window id +
138
- // pane count (only fields the case body reads).
139
- // The original case parsed `cmdText.slice('/bench'
140
- // .length)` to get the raw tail (because the
141
- // prompt may contain spaces + ::); the registry
142
- // passes args[], so we rebuild via args.join(' ').
143
- // Closes B-2 — B-2 medium tier fully migrated.
144
118
  // B-2.z — /setup — onboarding wizard launcher (inline /
145
119
  // popup / reset / help). resolveDashboardChatMain
146
120
  // SetupCommand + dashboardSetupHelpLines +
@@ -170,14 +144,6 @@
170
144
  // layout / focus / open). Four host-local actions
171
145
  // (listLiveSessions, setLayoutMode, focusPopup,
172
146
  // openModal) threaded via `conv` ctx bundle.
173
- // B-2.v — /scratch · /sc — scratchpad open/close/popup/
174
- // memo/clear/dump/append/replace. Many host-local
175
- // refs (mutable scratchClosed flag, scratchLines /
176
- // scratchTitle state, working-dir focus transition,
177
- // companion popup actions keyed to 'scratch').
178
- // Threads `scratch` ctx bundle as a thin shell over
179
- // the host actions; slash handler stays close to the
180
- // original case body shape.
181
147
  // B-2.u — /git — read-only inspection (status / branch /
182
148
  // log / diff / remote). All deps are pure module-
183
149
  // level helpers (getSessionCwd · getGitStatusView ·
@@ -204,14 +170,9 @@
204
170
  // requestDashboardRender threaded via `theme` ctx.
205
171
  // B-2.q — /sim · /simulator — declarative simulation cockpit
206
172
  // (open / web / list / run). simSlashRuntime line
207
- // helpers + 5 host-local actions (spawnVirtualWindow,
208
- // openWebCockpit, listScenarios, runById, resolveAlias)
173
+ // helpers + host-local actions (openWebCockpit,
174
+ // listScenarios, runById, resolveAlias)
209
175
  // threaded via `sim` ctx bundle.
210
- // B-2.p — /view · /v — yazi-style view switcher + config
211
- // reload/save/restore/reset/export. viewSlashRuntime
212
- // line helpers + view-registry actions threaded via
213
- // a single `view` ctx bundle. Each subcommand
214
- // delegates to a thin ctx method.
215
176
  // B-2.o — /intake — intake-plane review picker / modal /
216
177
  // refresh fire-and-forget. Many host-local deps
217
178
  // (display coordinator, theme tokens, workspace
@@ -258,25 +219,11 @@
258
219
  // itself (`openSourceDeltaBrowserPopup`) is show
259
220
  // Dashboard-local; threaded as `delta.openBrowser
260
221
  // Popup`. Sets exitInputLoop on a successful open.
261
- // B-2.h — /pty-pane · /pty-view — open a VirtualWindow with
262
- // a pty-tail pane that live-renders an already-
263
- // spawned registry PTY. pty-shell/registry helpers
264
- // are dynamic-imported. Only host-local dep is
265
- // `virtualWindows.registry.spawn(...)`, wrapped
266
- // behind one ctx method. Threads new `ptyPane` ctx.
267
222
  // B-2.g — /undo — snapshot ring restore/list/clear/toggle.
268
223
  // undo-turn helpers loaded via dynamic import. The
269
224
  // only host-local dep is `refreshGitDirty` over the
270
225
  // session cwd, wrapped behind a single ctx method.
271
226
  // Threads new `undo` ctx bundle (1 method).
272
- // B-2.f — /fullscreen · /fs — toggle fullscreen on the
273
- // currently-foregrounded terminal modal. terminal
274
- // modal router is a module-level singleton (static
275
- // import in this module); display coordinator is
276
- // showDashboard-local, so it's wrapped behind a
277
- // single `showFullscreenToast` ctx method instead
278
- // of leaking the DisplayCoordinator type. Threads
279
- // new `terminal` ctx bundle.
280
227
  // B-2.e — /history · /hist · /inputs — input history viewer
281
228
  // (list / find / show / clear / path).
282
229
  // Threads new `inputHistory` ctx bundle.
@@ -325,19 +272,12 @@
325
272
  // `../index.ts`) instead of importing the type — keeps this module free
326
273
  // of circular dependency on dashboard/index.ts.
327
274
 
328
- import { perf } from '../../perf-counters.js';
329
- import {
330
- runRebindCommand,
331
- readAuditTail,
332
- isInputAuditEntry,
333
- formatAuditEntry,
334
- parseDuration as parseAuditDuration,
335
- } from '../../input-core/index.js';
336
- import { resolveDashboardChatMainCacheCommand } from '../input/chat-main-cache-command.js';
275
+ import { runRebindCommand } from '../../input-core/index.js';
337
276
  // B4 (TUI half) — /design reuses the CLI's own resolution so the three
338
277
  // surfaces (CLI, PWA panel, this) cannot answer differently.
339
278
  import { resolveRepositoryDesignCheck } from '../../cli/repo-cli.js';
340
279
  import { renderDesignCheckLines, type DesignCheckTone } from '../../design/design-check-render.js';
280
+ import { handleDesignPick } from './design-pick.js';
341
281
  import { listDesignDirections, parseDeclaredDirection } from '../../design/design-directions.js';
342
282
  import {
343
283
  dashboardDeltaHelpLines,
@@ -350,7 +290,6 @@ import {
350
290
  resolveDashboardChatMainSetupCommand,
351
291
  } from '../input/chat-main-setup-command.js';
352
292
  import { resetOnboardingMarker } from '../../onboarding.js';
353
- import { MAX_BENCHMARK_PANES } from '../../virtual-windows/benchmark-preset.js';
354
293
  import { DEFAULT_THEME_TOKENS } from '../../theme/tokens.js';
355
294
  import { setActivePresetInConfig } from '../render/theme-resolver.js';
356
295
  import { getTheme, listThemes } from '../../themes/index.js';
@@ -364,14 +303,8 @@ import { lookupLlmTierSpec } from '../../model-tier/index.js';
364
303
  import { listProviders } from '../../llm.js';
365
304
  import { selfOrchestrateRuntime } from '../../self-dev/self-orchestrate-runtime.js';
366
305
  import type { ToolRuntime } from '../../tool-runtime/types.js';
367
- import {
368
- getGitStatusView,
369
- refreshDirty as refreshGitDirty,
370
- listBranches as listGitBranches,
371
- } from '../../git-fs/index.js';
372
306
  import { getSessionCwd } from '../../session/working-dir.js';
373
307
  import { listSkillNames, describeSkill } from '../../skills/runner.js';
374
- import { getSkillIndex } from '../../skills/index.js';
375
308
  import {
376
309
  REASONING_CYCLE,
377
310
  effectiveReasoningLevel,
@@ -402,6 +335,8 @@ import {
402
335
  import { inputHistoryDbPath, inputHistoryJsonPath } from '../../input-history.js';
403
336
  import { terminalModalRouter } from '../input/terminal-modal-router.js';
404
337
  import { termSize, stripAnsi } from '../../tui.js';
338
+ import { SLASH_COMMANDS } from '../../chat/index.js';
339
+ import { buildEssentialHelpLines } from './help-from-registry.js';
405
340
  import type { FoldMode } from '../../log-entry.js';
406
341
  import { resolveDashboardChatMainLogCommand } from '../input/chat-main-log-command.js';
407
342
  import {
@@ -449,18 +384,12 @@ import type { DashboardTermSlashRuntime } from '../term-slash-runtime.js';
449
384
  import { resolveTerminalMoveDestination } from '../../terminal-matrix/mobility.js';
450
385
  import { loadPersistedSessions } from '../../terminal/session-persistence.js';
451
386
  import { dispatchTerminalModalObserve } from '../../skills/tools/terminal-modal.js';
452
- import type { DashboardWindowSlashRuntime } from '../window-slash-runtime.js';
453
- import { parseWindowCompanionSlash } from '../windowing/companion-slash.js';
454
- // PLAN-tui-redundancy-cleanup T1 (2026-05-16) — vw-live-bridge trim.
455
- // `/codex-vw` slash 의 codex branch 가 의존했었지만 사용자 미사용 명시 ·
456
- // 본 trim 의 부차 path 정리. codex branch 는 error 메시지 출력으로 noop.
457
387
  import { SlashCommandRegistry } from './registry.js';
458
388
  import { executeImmediateDashboardSlash } from '../input/slash-executor.js';
459
389
  import {
460
390
  buildContextSlashCommand,
461
391
  buildCostSlashCommand,
462
392
  buildMemorySlashCommand,
463
- buildUsageSlashCommand,
464
393
  } from '../../context-display/index.js';
465
394
  import {
466
395
  formatInspectOutput,
@@ -481,7 +410,6 @@ import type { LogTurnSeparatorMode } from '../log-turn-separator-mode.js';
481
410
  const CONTEXT_SLASH_DESCRIPTOR = buildContextSlashCommand();
482
411
  const COST_SLASH_DESCRIPTOR = buildCostSlashCommand();
483
412
  const MEMORY_SLASH_DESCRIPTOR = buildMemorySlashCommand();
484
- const USAGE_SLASH_DESCRIPTOR = buildUsageSlashCommand();
485
413
 
486
414
  export interface DashboardSlashContext {
487
415
  // Chat surface refs / mutators
@@ -521,6 +449,7 @@ export interface DashboardSlashContext {
521
449
  /** Exit-only lifecycle hook: dashboard uses this to leave a session-resume notice. */
522
450
  exitTui?(): void;
523
451
  showHelp(scope: string): Promise<void>;
452
+ showHelpModal?(options: { title: string; lines: readonly string[] }): void;
524
453
 
525
454
  // Log search / filter
526
455
  clearLogSearch(): void;
@@ -576,10 +505,8 @@ export interface DashboardSlashContext {
576
505
  providerId: Parameters<typeof handleAutoTtsSlash>[1];
577
506
  };
578
507
 
579
- // B-1.g additions — three sub-runtime delegation cases (signals ·
580
- // browser-cdp · widget). Each one routes sub-commands to a slash-
581
- // runtime factory output. The runtimes are showDashboard-local so
582
- // we thread them via ctx as opaque shapes.
508
+ // B-1.g additions — signals and widget delegation runtimes are
509
+ // showDashboard-local, so they are threaded via ctx as opaque shapes.
583
510
  controlSignalSlashRuntime: {
584
511
  usageLines(): readonly string[];
585
512
  statusLines(): readonly string[];
@@ -617,6 +544,8 @@ export interface DashboardSlashContext {
617
544
  widgetModalPopup?: {
618
545
  open(spec: { widgetInstanceId: string; modalType: string; title: string }): { dispose(): void } | null;
619
546
  };
547
+ /** Essential dashboard prints /bg rows into chat instead of opening a popup. */
548
+ backgroundTasksTextOnly?: boolean;
620
549
 
621
550
  // B-1.h additions
622
551
  // - /preview · /pv: previewSlashRuntime is showDashboard-local (built
@@ -643,7 +572,7 @@ export interface DashboardSlashContext {
643
572
  dockedSnapshotRef: { value: { sourceMode: unknown } & Record<string, unknown> };
644
573
  };
645
574
  contextSlash: {
646
- renderContextList(): void;
575
+ renderContextList(): string[];
647
576
  contextRegistry: unknown;
648
577
  };
649
578
  pasteSlash: {
@@ -653,12 +582,6 @@ export interface DashboardSlashContext {
653
582
  attachClipboardImage(): Promise<string | null>;
654
583
  setNextInitial(token: string): void;
655
584
  };
656
- /** TUI 부활 T2 — /ui 모드 전환. setMode 는 uiMode 재할당 + chat-only
657
- * 동기 + config persist 를 수행 (dashboard 의 applyDashboardUiMode). */
658
- uiModeSlash: {
659
- getMode(): 'essential' | 'rich';
660
- setMode(mode: 'essential' | 'rich'): void;
661
- };
662
585
  /** TUI 부활 S-a — /resume 세션 픽커. openPicker 는 dashboard 의
663
586
  * openSessionResumePicker (createSearchModal 기반 · 선택 시
664
587
  * `/session load <id>` 합성 submit). */
@@ -684,16 +607,6 @@ export interface DashboardSlashContext {
684
607
  // B-1.i additions
685
608
  refreshReasoningHudSegment(): void;
686
609
 
687
- // B-2.f additions — /fullscreen toggle for the foregrounded terminal
688
- // modal. `terminalModalRouter` is a module-level singleton (static-
689
- // imported in this module). `display` is showDashboard-local, so the
690
- // toast wiring is wrapped behind `showFullscreenToast` instead of
691
- // leaking the DisplayCoordinator type through ctx.
692
- terminal: {
693
- fullscreenMissingLine(): string;
694
- showFullscreenToast(opts: { title: string; lines?: string[] }): void;
695
- };
696
-
697
610
  // B-2.g additions — /undo. The undo-turn helpers are dynamic-
698
611
  // imported in the handler body. Only `refreshGitDirty` over the
699
612
  // session cwd is host-local; wrapped behind a single ctx method.
@@ -702,14 +615,6 @@ export interface DashboardSlashContext {
702
615
  bold(text: string): string;
703
616
  };
704
617
 
705
- // B-2.h additions — /pty-pane · /pty-view. pty-shell/registry helpers
706
- // are dynamic-imported in the handler body. Only host-local dep is
707
- // `virtualWindows.registry.spawn(...)`, wrapped behind one ctx method
708
- // that returns the new window's id (only field the case body reads).
709
- ptyPane: {
710
- spawnPtyTailWindow(opts: { title: string; ptyId: string }): { id: number };
711
- };
712
-
713
618
  // B-2.i additions — /delta · /diffs source-delta browser popup.
714
619
  // The popup opener is showDashboard-local; threaded as
715
620
  // `delta.openBrowserPopup`.
@@ -726,27 +631,6 @@ export interface DashboardSlashContext {
726
631
  runCommand(args: readonly string[]): Promise<readonly string[]>;
727
632
  };
728
633
 
729
- // B-2.AA additions — /bench LLM benchmark window spawner.
730
- // `MAX_BENCHMARK_PANES` static-imported. `spawnLLMBenchmark`
731
- // wrapped behind `bench.spawn` ctx method (needs host-local
732
- // virtualWindows refs).
733
- bench: {
734
- slashRuntime: {
735
- helpLines(): readonly string[];
736
- missingSeparatorLine(): string;
737
- emptyPromptLine(): string;
738
- noProvidersLine(): string;
739
- tooManyProvidersLine(): string;
740
- spawnedLine(windowId: number, paneCount: number, providers: readonly string[]): string;
741
- failedLine(message: string): string;
742
- };
743
- /** Spawn a 2-4 pane LLM benchmark window. */
744
- spawn(spec: {
745
- prompt: string;
746
- providers: readonly { name: string; provider: string; model?: string }[];
747
- }): { window: { id: number }; paneIds: readonly string[] };
748
- };
749
-
750
634
  // B-2.z additions — /setup wizard launcher. The popup-launch and
751
635
  // inline-flow paths are wrapped behind two ctx methods that
752
636
  // encapsulate the host-local TerminalPopup + display + theme deps.
@@ -831,48 +715,6 @@ export interface DashboardSlashContext {
831
715
  openModal(sessionId: string): Promise<boolean>;
832
716
  };
833
717
 
834
- // B-2.v additions — /scratch · /sc scratchpad. Many host-local
835
- // refs (mutable scratchClosed flag, scratchLines / scratchTitle,
836
- // working-dir focus transition, companion popup keyed to 'scratch').
837
- scratch: {
838
- slashRuntime: {
839
- reopenedLine(): string;
840
- alreadyOpenLine(): string;
841
- popupLine(open: boolean): string;
842
- popupPromotedLine(): string;
843
- popupUsageLine(): string;
844
- closedLine(): string;
845
- clearedLine(): string;
846
- emptyDumpLine(): string;
847
- dumpHeaderLine(title: string): string;
848
- memoOpenedLine(): string;
849
- usageLine(): string;
850
- };
851
- isClosed(): boolean;
852
- /** Reopen the scratchpad pane. */
853
- open(): void;
854
- /** Close the scratchpad pane (also handles focus transition). */
855
- close(): void;
856
- /** Empty the scratchpad. */
857
- clear(): void;
858
- /** Snapshot for /scratch dump. */
859
- currentForCommand(): { title: string; lines: readonly string[] };
860
- /** Snapshot for /scratch + (append). */
861
- snapshotForAppend(): { title: string; lines: readonly string[] };
862
- /** Replace scratch content. */
863
- setText(title: string, lines: readonly string[]): void;
864
- /** Helper to format dump lines (host-side). */
865
- buildDumpLines(lines: readonly string[]): readonly string[];
866
- popup: {
867
- open(): void;
868
- close(): void;
869
- /** Returns whether the popup is open after toggle. */
870
- toggle(): boolean;
871
- promote(): void;
872
- };
873
- openMemo(): void;
874
- };
875
-
876
718
  // B-2.t additions — /compact summarise + history reset. The host
877
719
  // owns chat.history; the slash-runtime layer needs to read it for
878
720
  // the compact algorithm and clear+repopulate it for reset. Returns
@@ -881,7 +723,6 @@ export interface DashboardSlashContext {
881
723
  // case used via `as unknown as LLMMessage[]`).
882
724
  compact: {
883
725
  getHistory(): { role: string; [k: string]: unknown }[];
884
- compactBoundaryEnabled(): boolean;
885
726
  };
886
727
 
887
728
  // B-2.s additions — /provider · /p rotation switcher. Most logic
@@ -933,7 +774,6 @@ export interface DashboardSlashContext {
933
774
  unknownScenarioLine(input: string): string;
934
775
  runHeading(scenarioId: string): string;
935
776
  };
936
- spawnVirtualWindow(): string | number;
937
777
  openWebCockpit(): Promise<{ path: string }>;
938
778
  listScenarios(): readonly unknown[];
939
779
  runById(scenarioId: string): Promise<{ status: string; lines: readonly string[] }>;
@@ -941,46 +781,6 @@ export interface DashboardSlashContext {
941
781
  resolveScenarioId(raw: string): string | null;
942
782
  };
943
783
 
944
- // B-2.p additions — /view yazi-style view switcher + config mgmt.
945
- view: {
946
- slashRuntime: {
947
- listLines(items: readonly {
948
- active: boolean;
949
- id: string;
950
- label: string;
951
- enabled: boolean;
952
- shortcut?: string | null;
953
- baseView?: string;
954
- }[]): readonly string[];
955
- closedPaneLines(labels: readonly string[]): readonly string[];
956
- reloadedLine(): string;
957
- savedLine(): string;
958
- restoredLine(): string;
959
- resetLine(): string;
960
- exportedLine(): string;
961
- usageLine(): string;
962
- };
963
- buildListItems(): readonly {
964
- active: boolean;
965
- id: string;
966
- label: string;
967
- enabled: boolean;
968
- shortcut?: string;
969
- baseView?: string;
970
- }[];
971
- closedPaneLabels(): readonly string[];
972
- next(): void;
973
- prev(): void;
974
- reload(): void;
975
- save(): void;
976
- restoreAllClosed(): void;
977
- reset(): void;
978
- exportConfigJson(): string;
979
- /** Open a view by id/label/shortcut. Returns false if not found. */
980
- openByQuery(query: string): boolean;
981
- openDetailViewer(title: string, lines: string[]): void;
982
- };
983
-
984
784
  // B-2.o additions — /intake review picker / modal / refresh.
985
785
  // Whole IIFE wrapped behind one ctx method.
986
786
  intake: {
@@ -1224,12 +1024,15 @@ export interface DashboardSlashContext {
1224
1024
  /** Telegram chat id paired with the attached session, when handed off. */
1225
1025
  getAttachedChatId(): number | null;
1226
1026
  setAttachedChatId(id: number | null): void;
1027
+ /** Optional report delivery seam for slash dispatch tests; production uses the real config and sender. */
1028
+ telegramReport?: {
1029
+ getConfig(): ReturnType<typeof getUserConfig>;
1030
+ send: (cfg: ReturnType<typeof getUserConfig>, text: string) => Promise<boolean>;
1031
+ };
1227
1032
 
1228
1033
  sessionSlash: {
1229
1034
  /** opts.remote — when the dashboard is attached to a remote daemon. */
1230
1035
  remoteDaemon(): { url: string; token: string | undefined } | null;
1231
- /** opts.localDaemon — when the dashboard runs on a local daemon socket. */
1232
- localDaemon(): { socketPath: string } | null;
1233
1036
  /** Swap ACP session id via the existing connection (no restart). */
1234
1037
  acpSwapTo(sessionId: string, cwd: string): Promise<void>;
1235
1038
  };
@@ -1379,50 +1182,6 @@ export interface DashboardSlashContext {
1379
1182
  run(args: readonly string[]): Promise<void>;
1380
1183
  };
1381
1184
 
1382
- // B-3.d additions — /workspace /ws /window /win + /codex-vw /acp-vw /claude-vw.
1383
- // Closes the last B-3 cluster. The two cases share the virtualWindows
1384
- // registry but differ in surface: /workspace owns lifecycle (spawn /
1385
- // list / switch / close / picker) while /codex-vw spawns coding-agent
1386
- // sessions inside VWs. `windowSlashRuntime` slashRuntime + the seven
1387
- // spawn*VirtualWindow + openWindowPicker + toggleVwCompanion +
1388
- // setVwCompanionOpen helpers all thread via `workspaceSlash`.
1389
- // `spawnAcpLiveSessionInVW` is static-imported. /codex-vw reuses
1390
- // ctx.conv.openModal (B-2.w) for openConversationModal · workingDir
1391
- // cwd via ctx.acpVwSlash.cwd().
1392
- workspaceSlash: {
1393
- /** Line-formatter helpers (host-built per-dashboard). */
1394
- slashRuntime: DashboardWindowSlashRuntime;
1395
- /** Virtual-window registry surface used by /workspace. */
1396
- registry: {
1397
- list(): readonly { id: number; title: string; listPanes(): readonly unknown[] }[];
1398
- current(): { id: number } | null;
1399
- switchTo(id: number): boolean;
1400
- close(id: number): boolean;
1401
- get(id: number): { id: number } | null;
1402
- };
1403
- /** Spawn helpers (each returns the new VW id). */
1404
- spawnScratchVirtualWindow(title: string): number;
1405
- spawnBrowserVirtualWindow(title: string): number;
1406
- spawnPreviewVirtualWindow(title: string): number;
1407
- spawnBrowserPreviewVirtualWindow(title: string): number;
1408
- spawnIulVirtualWindow(title: string): number;
1409
- spawnAcpVirtualWindow(title: string): number;
1410
- spawnSimVirtualWindow(title: string): number;
1411
- /** Open the cross-window picker modal. */
1412
- openWindowPicker(): void;
1413
- /** Toggle a VW companion popup; returns the resulting open state. */
1414
- toggleVwCompanion(windowId: number, key: string): boolean;
1415
- /** Set a VW companion popup's open state explicitly. */
1416
- setVwCompanionOpen(windowId: number, key: string, open: boolean): void;
1417
- };
1418
-
1419
- acpVwSlash: {
1420
- /** Working-dir cwd for spawned coding-agent VWs. */
1421
- cwd(): string;
1422
- /** Virtual-windows registry handle (subset for spawnCodingAgentInVW). */
1423
- vwRegistry: unknown;
1424
- };
1425
-
1426
1185
  // B-3.c.1 additions — /shell list/kill/attach/rollup. /local has no
1427
1186
  // bundle (all deps are static-imported helpers + existing ctx
1428
1187
  // chatLines / chatScrollOffset / color funcs / config helpers).
@@ -1563,17 +1322,17 @@ export function _setSelfOrchestrateSlashRuntimeForTesting(runtime: SelfOrchestra
1563
1322
  export const DASHBOARD_SLASH_CATALOG_BASELINE = {
1564
1323
  registeredOnly: [
1565
1324
  'ag', 'agent', 'agents', 'attach-clear', 'attach-pin', 'attach-unpin',
1566
- 'bench', 'bg', 'branch', 'cb', 'ce', 'child', 'clip', 'clipboard',
1567
- 'code-edit', 'compact', 'compress', 'cost', 'detail', 'dv', 'git',
1568
- 'harness-llm', 'intake', 'me', 'mem-compact', 'memo',
1569
- 'memorize', 'note', 'pause', 'plan-board', 'preview', 'pv', 'report',
1570
- 'route', 'sh', 'shell', 'signal', 'signals', 'skill-reload',
1571
- 'skill-triggers', 'skills-reload', 'spend', 'squeeze', 'stats',
1572
- 'sweep-tool-results', 'tk', 'tokens', 'triggers', 'tslider',
1573
- 'turn-slider', 'turnslider', 'undo', 'usage', 'w', 'wd',
1325
+ 'bg', 'cb', 'ce', 'child', 'clip', 'clipboard',
1326
+ 'code-edit', 'compact', 'compress', 'cost', 'detail', 'dv',
1327
+ 'harness-llm', 'intake', 'me', 'memo',
1328
+ 'note', 'pause', 'plan-board', 'preview', 'pv', 'report',
1329
+ 'sh', 'shell', 'signal', 'signals', 'skill-reload',
1330
+ 'skills-reload', 'spend', 'squeeze',
1331
+ 'tk', 'tokens',
1332
+ 'undo', 'w', 'wd',
1574
1333
  ],
1575
1334
  listedOnly: [
1576
- 'acp', 'hint', 'media', 'mv', 'pg', 'rsh', 'sr', 'surf',
1335
+ 'acp', 'rsh', 'sr',
1577
1336
  ],
1578
1337
  } as const;
1579
1338
 
@@ -1612,11 +1371,38 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
1612
1371
  ctx.clearLogSearch();
1613
1372
  ctx.clearLogFilter();
1614
1373
  ctx.pushDebugLine(ctx.muted('Status cleared'));
1374
+ ctx.chatLines.push(ctx.muted('Status cleared'));
1615
1375
  ctx.setChatScrollOffset(-1);
1616
1376
  });
1617
1377
 
1618
- registry.register(['help', '?'], async (_args, ctx) => {
1619
- await ctx.showHelp('dashboard');
1378
+ registry.register(['help', '?'], (_args, ctx) => {
1379
+ const { cols, rows } = termSize();
1380
+ const lines = buildEssentialHelpLines({
1381
+ names: registry.names(),
1382
+ descriptions: SLASH_COMMANDS,
1383
+ width: Math.max(1, Math.floor(cols * 0.7) - 2),
1384
+ });
1385
+ // The transient modal paints only height - 2 content rows and does not scroll.
1386
+ // When the catalog outgrows it, use the scrollable chat log instead of hiding keys.
1387
+ const minHeight = Math.min(6, Math.max(3, rows - 2));
1388
+ const modalContentRows = Math.max(minHeight, Math.min(rows - 4, Math.floor(rows * 0.7))) - 2;
1389
+ if (ctx.showHelpModal && lines.length <= modalContentRows) {
1390
+ ctx.showHelpModal({ title: 'Dashboard help', lines });
1391
+ } else {
1392
+ if (ctx.showHelpModal) ctx.chatLines.push('Dashboard help — scroll the chat log with PgUp / PgDn');
1393
+ ctx.chatLines.push(...lines);
1394
+ ctx.setChatScrollOffset(-1);
1395
+ }
1396
+ });
1397
+
1398
+ registry.register('directive', async (args, ctx) => {
1399
+ try {
1400
+ const { addDirective } = await import('../../steward/directive.js');
1401
+ const result = await addDirective(args.join(' '), { source: 'tui' });
1402
+ ctx.pushChatLine(`${result.issue}: ${result.status}`);
1403
+ } catch {
1404
+ ctx.pushChatLine('지시 등록 실패 — Linear 연결과 자격을 확인하세요.');
1405
+ }
1620
1406
  });
1621
1407
 
1622
1408
  // ── B-1.b ─────────────────────────────────────────────────────────
@@ -1718,14 +1504,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
1718
1504
  ctx.setChatScrollOffset(-1);
1719
1505
  });
1720
1506
 
1721
- registry.register('ctoggle', (_args, ctx) => {
1722
- const next = ctx.toggleSessionControlMode(ctx.chatModeStateRef.value);
1723
- void ctx.inputCoreSetMode(ctx.resolveSessionInputModeFromChatMode({ chatModeState: ctx.chatModeStateRef.value }));
1724
- ctx.chatLines.push(next.posture === 'control'
1725
- ? ctx.error('-- CONTROL MODE (toggle) —') + ctx.text(' every message is a dashboard command. /ctoggle to exit.')
1726
- : ctx.muted('-- back to default chat mode --'));
1727
- ctx.setChatScrollOffset(-1);
1728
- });
1729
1507
 
1730
1508
  registry.register(['dashboard', 'dash'], (_args, ctx) => {
1731
1509
  // Explicit exit back to 3-pane layout — no-op if already there, so
@@ -1762,21 +1540,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
1762
1540
  });
1763
1541
 
1764
1542
  // ── B-1.c ─────────────────────────────────────────────────────────
1765
- registry.register('cache', async (args, ctx) => {
1766
- const cacheCommand = resolveDashboardChatMainCacheCommand(args);
1767
- const {
1768
- getSessionSummary, formatSessionSummary, resetSessionMetrics,
1769
- } = await import('../../prompt-cache/index.js');
1770
- if (cacheCommand.kind === 'reset') {
1771
- resetSessionMetrics();
1772
- ctx.pushDebugLine(ctx.muted(' cache metrics reset'));
1773
- } else {
1774
- const summary = formatSessionSummary(getSessionSummary());
1775
- for (const line of summary.split('\n')) ctx.pushDebugLine(ctx.muted(` ${line}`));
1776
- }
1777
- ctx.setChatScrollOffset(-1);
1778
- });
1779
-
1780
1543
  registry.register('attach-pin', (args, ctx) => {
1781
1544
  // BL-E3 — bookmark a session's latest block so it survives ring rotation.
1782
1545
  const target = args[0]?.trim();
@@ -1857,60 +1620,8 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
1857
1620
  ctx.setChatScrollOffset(-1);
1858
1621
  });
1859
1622
 
1860
- registry.register('perf', (args, ctx) => {
1861
- // Opt-in perf instrumentation. /perf on resets all buckets; report
1862
- // prints p50/p90/p99 + top categories; reset re-arms collection
1863
- // without toggling enabled.
1864
- const sub = (args[0] || 'status').toLowerCase();
1865
- if (sub === 'on') {
1866
- perf.enable();
1867
- emitReplyToChat(ctx, ctx.success(' perf counters ON — use /perf report to inspect'));
1868
- } else if (sub === 'off') {
1869
- perf.disable();
1870
- emitReplyToChat(ctx, ctx.muted(' perf counters OFF'));
1871
- } else if (sub === 'reset') {
1872
- if (perf.enabled) { perf.enable(); emitReplyToChat(ctx, ctx.muted(' perf reset (still ON)')); }
1873
- else emitReplyToChat(ctx, ctx.muted(' perf is OFF — `/perf on` to start'));
1874
- } else if (sub === 'report') {
1875
- for (const l of perf.report().split('\n')) ctx.pushDebugLine(ctx.text(l));
1876
- } else { // status
1877
- emitReplyToChat(ctx, ctx.muted(` perf: ${perf.enabled ? 'ON' : 'OFF'}`));
1878
- if (perf.enabled) {
1879
- for (const l of perf.report().split('\n')) ctx.pushDebugLine(ctx.muted(' ' + l));
1880
- }
1881
- }
1882
- ctx.setChatScrollOffset(-1);
1883
- });
1884
1623
 
1885
- registry.register(['pty-list', 'ptys'], async (_args, ctx) => {
1886
- // S3: visibility into PTYs the dashboard / skills spawned. Read-only;
1887
- // identical to PtyShellList native tool output.
1888
- const { dispatchPtyShellList } = await import('../../skills/tools/pty.js');
1889
- const { ptyAvailable } = await import('../../pty-shell/registry.js');
1890
- if (!ptyAvailable()) {
1891
- ctx.pushDebugLine(ctx.warning(' PtyShell unavailable — node-pty not installed'));
1892
- } else {
1893
- for (const line of dispatchPtyShellList().output.split('\n')) {
1894
- ctx.pushDebugLine(ctx.text(line));
1895
- }
1896
- }
1897
- ctx.setChatScrollOffset(-1);
1898
- });
1899
1624
 
1900
- registry.register('sweep-tool-results', async (_args, ctx) => {
1901
- try {
1902
- const { sweepToolResults, toolOutputStoreRoot } = await import('../../tool-runtime/truncation-store.js');
1903
- const removed = await sweepToolResults({
1904
- retentionDays: getUserConfig().chat.toolOutput.retentionDays,
1905
- });
1906
- ctx.pushDebugLine(ctx.success(
1907
- `[tool-results] sweep complete: removed ${removed.removedFiles} files, ${removed.removedDirs} dirs (${toolOutputStoreRoot()})`,
1908
- ));
1909
- } catch (err) {
1910
- ctx.pushDebugLine(ctx.warning(`[tool-results] sweep failed: ${err instanceof Error ? err.message : String(err)}`));
1911
- }
1912
- ctx.setChatScrollOffset(-1);
1913
- });
1914
1625
 
1915
1626
  // ── B-1.d ─────────────────────────────────────────────────────────
1916
1627
  // 9 deferred skill-tool slashes. All share the fire-and-forget
@@ -1918,16 +1629,7 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
1918
1629
  // distinct module paths and exporter names are the only per-case
1919
1630
  // variation.
1920
1631
 
1921
- registry.register(['budget', 'b'], (args, ctx) => {
1922
- runDeferredSkillToolSlash(
1923
- 'budget',
1924
- async () => (await import('../../skills/tools/budget-slash.js')).executeBudgetSlash,
1925
- args,
1926
- ctx,
1927
- );
1928
- });
1929
1632
  // /remaining — 명령(`elanous usage`)이 내는 구조화 산출을 그대로 읽는다. 화면 계산 없음.
1930
- // 기존 /usage 는 세션 토큰 통계라 이름·동작을 그대로 둔다.
1931
1633
  registry.register('remaining', (args, ctx) => {
1932
1634
  runDeferredSkillToolSlash(
1933
1635
  'remaining',
@@ -1937,14 +1639,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
1937
1639
  );
1938
1640
  });
1939
1641
 
1940
- registry.register('route', (args, ctx) => {
1941
- runDeferredSkillToolSlash(
1942
- 'route',
1943
- async () => (await import('../../skills/tools/route-slash.js')).executeRouteSlash,
1944
- args,
1945
- ctx,
1946
- );
1947
- });
1948
1642
 
1949
1643
  // `agent-room` and `showroom` go to the same module but pass distinct
1950
1644
  // names through to the executor. Two registrations keep the alias
@@ -2013,14 +1707,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
2013
1707
  );
2014
1708
  });
2015
1709
 
2016
- registry.register('llm', (args, ctx) => {
2017
- runDeferredSkillToolSlash(
2018
- 'llm',
2019
- async () => (await import('../../skills/tools/llm-manager-slash.js')).executeLlmSlash,
2020
- args,
2021
- ctx,
2022
- );
2023
- });
2024
1710
 
2025
1711
  // ── B-1.e ─────────────────────────────────────────────────────────
2026
1712
  // 4 tiny standalone toggles / state-mutation cases. Each is small and
@@ -2028,18 +1714,23 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
2028
1714
  // share the "tiny" tier.
2029
1715
 
2030
1716
  registry.register('bg', async (_args, ctx) => {
2031
- // Wave P4b-1 — open the unified background-tasks widget as an
2032
- // interactive modal popup. Falls back to the previous chatLines
2033
- // snapshot dump when the host hasn't wired the popup helper
2034
- // (e.g. test harnesses) so the slash stays usable everywhere.
2035
- const handle = ctx.widgetModalPopup?.open?.({
2036
- widgetInstanceId: 'wd-background-tasks',
2037
- modalType: 'background-tasks-popup',
2038
- title: 'Background tasks',
2039
- });
2040
- if (handle) {
2041
- ctx.setChatScrollOffset(-1);
2042
- return;
1717
+ if (!ctx.backgroundTasksTextOnly) {
1718
+ let handle: { dispose(): void } | null | undefined;
1719
+ try {
1720
+ handle = ctx.widgetModalPopup?.open({
1721
+ widgetInstanceId: 'wd-background-tasks', modalType: 'background-tasks-popup', title: 'Background tasks',
1722
+ });
1723
+ } catch (err) {
1724
+ if (!(err instanceof Error) || !err.message.includes("no modal type registered as 'background-tasks-popup'")) throw err;
1725
+ debug.log('dashboard.slash', 'modal-type-missing', { type: 'background-tasks-popup' });
1726
+ ctx.pushChatLine(ctx.warning(' 배경 작업 창을 열 수 없습니다'));
1727
+ ctx.setChatScrollOffset(-1);
1728
+ return;
1729
+ }
1730
+ if (handle) {
1731
+ ctx.setChatScrollOffset(-1);
1732
+ return;
1733
+ }
2043
1734
  }
2044
1735
  type Row = {
2045
1736
  id: string; source: string; label: string; status: string;
@@ -2048,16 +1739,16 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
2048
1739
  const inst = ctx.widgetHost.get('wd-background-tasks');
2049
1740
  const rows = (inst?.state as { rows?: Row[] } | undefined)?.rows ?? [];
2050
1741
  if (rows.length === 0) {
2051
- ctx.pushDebugLine(ctx.muted(' /bg: no active background tasks.'));
1742
+ ctx.pushChatLine(ctx.muted(' /bg: no active background tasks.'));
2052
1743
  } else {
2053
- ctx.pushDebugLine(ctx.muted(` /bg: ${rows.length} active background task${rows.length === 1 ? '' : 's'}`));
1744
+ ctx.pushChatLine(ctx.muted(` /bg: ${rows.length} active background task${rows.length === 1 ? '' : 's'}`));
2054
1745
  for (const r of rows) {
2055
1746
  const elapsed = typeof r.elapsedMs === 'number' && r.elapsedMs > 0
2056
1747
  ? `${Math.floor(r.elapsedMs / 1000)}s`
2057
1748
  : '';
2058
1749
  const tail = [r.detail, elapsed].filter(Boolean).join(' · ');
2059
1750
  const tailPart = tail ? ` ${tail}` : '';
2060
- ctx.pushDebugLine(` ${r.source} · ${r.status} · ${r.label}${tailPart}`);
1751
+ ctx.pushChatLine(` ${r.source} · ${r.status} · ${r.label}${tailPart}`);
2061
1752
  }
2062
1753
  }
2063
1754
  ctx.setChatScrollOffset(-1);
@@ -2086,11 +1777,17 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
2086
1777
  // `/resume`. The dynamic import keeps turn-checkpoint lazy-loaded.
2087
1778
  const { requestPause, isPauseRequested } = await import('../../turn-checkpoint/index.js');
2088
1779
  if (isPauseRequested()) {
2089
- ctx.pushDebugLine(ctx.muted(' /pause: already queued — the next decision-boundary tool call will halt the turn.'));
1780
+ const line = ctx.muted(' /pause: already queued — the next decision-boundary tool call will halt the turn.');
1781
+ ctx.pushDebugLine(line);
1782
+ ctx.chatLines.push(line);
2090
1783
  } else {
2091
1784
  requestPause();
2092
- ctx.pushDebugLine(ctx.success(' /pause: queued. The next decision-boundary tool call (Edit/Write/Bash/Agent) will checkpoint and end the turn.'));
2093
- ctx.pushDebugLine(ctx.muted(' Resume the captured state with /resume-turn (most recent) or /resume-turn <turn-suffix>.'));
1785
+ const line = ctx.success(' /pause: queued. The next decision-boundary tool call (Edit/Write/Bash/Agent) will checkpoint and end the turn.');
1786
+ ctx.pushDebugLine(line);
1787
+ ctx.chatLines.push(line);
1788
+ const resumeHint = ctx.muted(' Resume the captured state with /resume-turn (most recent) or /resume-turn <turn-suffix>.');
1789
+ ctx.pushDebugLine(resumeHint);
1790
+ ctx.chatLines.push(resumeHint);
2094
1791
  }
2095
1792
  ctx.setChatScrollOffset(-1);
2096
1793
  });
@@ -2241,24 +1938,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
2241
1938
  ctx.setChatScrollOffset(-1);
2242
1939
  });
2243
1940
 
2244
- registry.register(['browser-cdp', 'bcdp'], async (args, ctx) => {
2245
- const sub = (args[0] || 'status').toLowerCase();
2246
- const rt = ctx.browserCdpSlashRuntime;
2247
- ctx.chatLines.push('');
2248
- ctx.chatLines.push(ctx.accent(`❯ /browser-cdp ${args.join(' ').trim() || 'status'}`));
2249
- if (sub === 'help') {
2250
- for (const line of rt.usageLines()) ctx.chatLines.push(line);
2251
- } else if (sub === 'status') {
2252
- for (const line of rt.statusLines()) ctx.chatLines.push(line);
2253
- } else if (sub === 'smoke') {
2254
- for (const line of await rt.smokeLines()) ctx.chatLines.push(line);
2255
- } else if (sub === 'stop') {
2256
- for (const line of rt.stopLines()) ctx.chatLines.push(line);
2257
- } else {
2258
- for (const line of rt.usageLines()) ctx.chatLines.push(line);
2259
- }
2260
- ctx.setChatScrollOffset(-1);
2261
- });
2262
1941
 
2263
1942
  registry.register(['widget', 'widgets', 'w'], async (args, ctx) => {
2264
1943
  const sub = (args[0] || 'list').toLowerCase();
@@ -2305,7 +1984,7 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
2305
1984
  // hit before the alias-checking branches. Registry handlers don't
2306
1985
  // receive the matched name, so we register each alias separately and
2307
1986
  // hard-code the source name — fixes the typo by construction.
2308
- for (const sourceName of ['control', 'dm', 'default'] as const) {
1987
+ for (const sourceName of ['control', 'default'] as const) {
2309
1988
  registry.register(sourceName, (args, ctx) => {
2310
1989
  const outcome = parseSessionControlSlash(
2311
1990
  sourceName,
@@ -2400,7 +2079,8 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
2400
2079
  // helpers are statically imported.
2401
2080
  const subCmd = args[0]?.toLowerCase();
2402
2081
  if (!subCmd) {
2403
- ctx.contextSlash.renderContextList();
2082
+ const lines = ctx.contextSlash.renderContextList();
2083
+ ctx.chatLines.push(...(lines.length > 0 ? lines : [ctx.muted(' /context: (없음)')]));
2404
2084
  ctx.setChatScrollOffset(-1);
2405
2085
  return;
2406
2086
  }
@@ -2467,23 +2147,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
2467
2147
  ctx.setChatScrollOffset(-1);
2468
2148
  });
2469
2149
 
2470
- // /ui — TUI 부활 T2: essential(chat 전체화면) ↔ rich(full dashboard)
2471
- // 런타임 전환 + config persist. 인자 없으면 현재 모드 + 사용법.
2472
- registry.register('ui', async (args, ctx) => {
2473
- ctx.chatLines.push('');
2474
- const arg = (args[0] ?? '').trim().toLowerCase();
2475
- if (arg === 'essential' || arg === 'rich') {
2476
- ctx.chatLines.push(ctx.accent(`❯ /ui ${arg}`));
2477
- ctx.uiModeSlash.setMode(arg);
2478
- return;
2479
- }
2480
- ctx.chatLines.push(ctx.accent('❯ /ui'));
2481
- if (arg) ctx.chatLines.push(ctx.warning(` unknown mode: ${arg}`));
2482
- ctx.chatLines.push(ctx.text(` ui mode: ${ctx.uiModeSlash.getMode()}`));
2483
- ctx.chatLines.push(ctx.muted(' /ui essential — chat 전체화면 (기본) · /ui rich — full dashboard (VW·grid·dock)'));
2484
- ctx.setChatScrollOffset(-1);
2485
- });
2486
-
2487
2150
  // /resume — TUI 부활 S-a: 세션 픽커 (codex 패리티). 인자 없으면
2488
2151
  // 필터형 모달 픽커 오픈 · `<prefix>` 지정 시 기존 `/session load`
2489
2152
  // 파이프라인에 그대로 위임 (registry 재진입 · return 의미 보존).
@@ -2562,7 +2225,7 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
2562
2225
  if (sub === 'runs') {
2563
2226
  if (args.length !== 1) return usage('/harness runs');
2564
2227
  const { queryRunningRuns, renderRunningRuns } = await import('../../self-implement/running-runs.js');
2565
- const result = queryRunningRuns({ includeTest: false });
2228
+ const result = queryRunningRuns({ includeTest: false, caller: 'dashboard' });
2566
2229
  // Keep the TUI transcript readable while preserving the renderer's full summary.
2567
2230
  const visibleRunLimit = 8;
2568
2231
  const renderedLines = renderRunningRuns(result).split('\n');
@@ -3130,265 +2793,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
3130
2793
  ctx.setChatScrollOffset(-1);
3131
2794
  });
3132
2795
 
3133
- registry.register(['workspace', 'ws', 'window', 'win'], (args, ctx) => {
3134
- // TUI 부활 T3 — essential 은 VW slash 표면 OFF (비가시 윈도우
3135
- // 생성/조작 방지). /ui rich 전환 즉시 복원.
3136
- if (ctx.uiModeSlash.getMode() !== 'rich') {
3137
- ctx.chatLines.push('');
3138
- ctx.chatLines.push(ctx.muted(' virtual workspace 는 rich 모드 전용 — /ui rich 로 전환하세요'));
3139
- ctx.setChatScrollOffset(-1);
3140
- return;
3141
- }
3142
- // T2-P5 — virtual-window slash commands. Q2 (substrate Occam,
3143
- // 2026-05-03): primary name is now `/workspace`; `/window` `/win`
3144
- // `/ws` preserved as muscle-memory aliases. Internal terminology
3145
- // (VirtualWindow class, virtualWindows registry) will migrate in a
3146
- // follow-up — slash rename is the user-facing first step.
3147
- //
3148
- // Static-imported in this module: parseWindowCompanionSlash from
3149
- // ../windowing/companion-slash.js. The 7 spawn helpers + picker +
3150
- // companion toggle are showDashboard-local closures threaded via
3151
- // ctx.workspaceSlash.
3152
- const sub = (args[0] ?? '').toLowerCase();
3153
- const slashRuntime = ctx.workspaceSlash.slashRuntime;
3154
- const reg = ctx.workspaceSlash.registry;
3155
- if (!sub || sub === 'help') {
3156
- for (const line of slashRuntime.helpLines()) ctx.chatLines.push(line);
3157
- ctx.setChatScrollOffset(-1);
3158
- return;
3159
- }
3160
- if (sub === 'list') {
3161
- const current = reg.current();
3162
- ctx.chatLines.push(
3163
- ...slashRuntime.listLines(
3164
- reg.list().map((window) => ({
3165
- id: window.id,
3166
- title: window.title,
3167
- paneCount: window.listPanes().length,
3168
- isCurrent: window.id === current?.id,
3169
- })),
3170
- ),
3171
- );
3172
- ctx.setChatScrollOffset(-1);
3173
- return;
3174
- }
3175
- const spawnSubs: Record<string, (title: string) => number> = {
3176
- 'new': ctx.workspaceSlash.spawnScratchVirtualWindow,
3177
- 'browser': ctx.workspaceSlash.spawnBrowserVirtualWindow,
3178
- 'preview': ctx.workspaceSlash.spawnPreviewVirtualWindow,
3179
- 'browser-preview': ctx.workspaceSlash.spawnBrowserPreviewVirtualWindow,
3180
- 'bp': ctx.workspaceSlash.spawnBrowserPreviewVirtualWindow,
3181
- 'iul': ctx.workspaceSlash.spawnIulVirtualWindow,
3182
- 'acp': ctx.workspaceSlash.spawnAcpVirtualWindow,
3183
- 'sim': ctx.workspaceSlash.spawnSimVirtualWindow,
3184
- };
3185
- if (spawnSubs[sub]) {
3186
- type SpawnedFlavour = Parameters<DashboardWindowSlashRuntime['spawnedLine']>[0];
3187
- type FailedFlavour = Parameters<DashboardWindowSlashRuntime['spawnFailedLine']>[0];
3188
- const spawnedFlavour: SpawnedFlavour = sub === 'new' ? 'scratch'
3189
- : sub === 'bp' ? 'browser-preview'
3190
- : sub as SpawnedFlavour;
3191
- const failedFlavour: FailedFlavour = sub === 'bp' ? 'browser-preview' : sub as FailedFlavour;
3192
- const defaultTitlePrefix = sub === 'new' ? 'window'
3193
- : sub === 'bp' ? 'browser+preview'
3194
- : sub === 'iul' ? 'IUL UX Lab'
3195
- : sub === 'acp' ? 'ACP channels'
3196
- : sub === 'sim' ? 'Simulator'
3197
- : sub;
3198
- const title = args.slice(1).join(' ').trim() || `${defaultTitlePrefix} ${reg.list().length + 1}`;
3199
- try {
3200
- const id = spawnSubs[sub]!(title);
3201
- ctx.chatLines.push(slashRuntime.spawnedLine(spawnedFlavour, id, title));
3202
- } catch (err) {
3203
- ctx.chatLines.push(slashRuntime.spawnFailedLine(
3204
- failedFlavour,
3205
- err instanceof Error ? err.message : String(err),
3206
- ));
3207
- }
3208
- ctx.setChatScrollOffset(-1);
3209
- return;
3210
- }
3211
- if (sub === 'switch') {
3212
- const id = parseInt(args[1] ?? '', 10);
3213
- if (!Number.isInteger(id)) {
3214
- ctx.chatLines.push(slashRuntime.switchInvalidIdLine());
3215
- } else if (!reg.switchTo(id)) {
3216
- ctx.chatLines.push(slashRuntime.switchMissingLine(id));
3217
- } else {
3218
- ctx.chatLines.push(slashRuntime.switchedLine(id));
3219
- }
3220
- ctx.setChatScrollOffset(-1);
3221
- return;
3222
- }
3223
- if (sub === 'close') {
3224
- const raw = (args[1] ?? '').trim();
3225
- if (raw === 'all' || raw === '*') {
3226
- const ids = reg.list().map(w => w.id);
3227
- for (const id of ids) reg.close(id);
3228
- ctx.chatLines.push(slashRuntime.closeAllLine(ids.length));
3229
- ctx.setChatScrollOffset(-1);
3230
- return;
3231
- }
3232
- const id = parseInt(raw, 10);
3233
- if (!Number.isInteger(id)) {
3234
- ctx.chatLines.push(slashRuntime.closeInvalidLine());
3235
- } else if (!reg.close(id)) {
3236
- ctx.chatLines.push(slashRuntime.closeMissingLine(id));
3237
- } else {
3238
- ctx.chatLines.push(slashRuntime.closedLine(id));
3239
- }
3240
- ctx.setChatScrollOffset(-1);
3241
- return;
3242
- }
3243
- if (sub === 'closeall') {
3244
- const ids = reg.list().map(w => w.id);
3245
- for (const id of ids) reg.close(id);
3246
- ctx.chatLines.push(slashRuntime.closeAllLine(ids.length));
3247
- ctx.setChatScrollOffset(-1);
3248
- return;
3249
- }
3250
- if (sub === 'picker') {
3251
- ctx.workspaceSlash.openWindowPicker();
3252
- return;
3253
- }
3254
- if (sub === 'companion' || sub === 'comp') {
3255
- const currentWindowId = reg.current()?.id ?? null;
3256
- const outcome = parseWindowCompanionSlash(args.slice(1), { currentWindowId });
3257
- if (!outcome.ok) {
3258
- ctx.chatLines.push(ctx.warning(` ${outcome.message}`));
3259
- ctx.setChatScrollOffset(-1);
3260
- return;
3261
- }
3262
- const { key, action, windowId } = outcome.value;
3263
- if (!reg.get(windowId)) {
3264
- ctx.chatLines.push(ctx.warning(` no window with id ${windowId}`));
3265
- ctx.setChatScrollOffset(-1);
3266
- return;
3267
- }
3268
- if (action === 'toggle') {
3269
- const opened = ctx.workspaceSlash.toggleVwCompanion(windowId, key);
3270
- ctx.chatLines.push(slashRuntime.companionLine(action, opened, key, windowId));
3271
- } else {
3272
- ctx.workspaceSlash.setVwCompanionOpen(windowId, key, action === 'open');
3273
- ctx.chatLines.push(
3274
- slashRuntime.companionLine(action, action === 'open', key, windowId),
3275
- );
3276
- }
3277
- ctx.setChatScrollOffset(-1);
3278
- return;
3279
- }
3280
- ctx.chatLines.push(slashRuntime.unknownSubcommandLine(sub));
3281
- ctx.setChatScrollOffset(-1);
3282
- });
3283
-
3284
- // /codex-vw, /claude-vw, and /acp-vw have shared body but discriminate
3285
- // on cmdLower (passed via args[args.length] doesn't work — registry
3286
- // only delivers args. We register each name separately and pass the
3287
- // brand at registration time, matching the B-2.m /claude /codex /gemini
3288
- // pattern.). Each entry calls the same factory.
3289
- const buildAcpVwHandler = (cmdLower: 'acp-vw' | 'claude-vw' | 'codex-vw') =>
3290
- async (args: string[], ctx: DashboardSlashContext): Promise<void> => {
3291
- const subArg0 = (args[0] ?? '').toLowerCase();
3292
- const cwd = ctx.acpVwSlash.cwd();
3293
- const vwRegistry = ctx.acpVwSlash.vwRegistry;
3294
-
3295
- // H5 P3 — claude-pty / gemini-pty adapters via embodied-agent bus.
3296
- if (cmdLower === 'acp-vw' && (subArg0 === 'clc' || subArg0 === 'claude-pty' || subArg0 === 'claude-code')) {
3297
- (async () => {
3298
- try {
3299
- const { spawnEmbodiedAgentInVW } = await import('../../agent/spawn-embodied-agent-in-vw.js');
3300
- const r = await spawnEmbodiedAgentInVW({ brand: 'claude-code', mode: 'hybrid', cwd });
3301
- ctx.chatLines.push(ctx.success(` ✓ claude-code (pty) in win:${r.windowId} (pane:${r.paneId})`));
3302
- ctx.chatLines.push(ctx.muted(` • H5 Embodied Agent Bus · session:${r.session.id} · pty:${r.ptyId}`));
3303
- ctx.chatLines.push(ctx.muted(` • @pane:${r.paneId} inlines output in next LLM turn`));
3304
- void ctx.conv.openModal(r.session.id);
3305
- } catch (err) {
3306
- ctx.chatLines.push(ctx.error(` /acp-vw clc failed: ${err instanceof Error ? err.message : String(err)}`));
3307
- }
3308
- ctx.setChatScrollOffset(-1);
3309
- ctx.draw();
3310
- })().catch(() => {});
3311
- return;
3312
- }
3313
- if (cmdLower === 'acp-vw' && (subArg0 === 'gem' || subArg0 === 'gemini' || subArg0 === 'gemini-cli')) {
3314
- (async () => {
3315
- try {
3316
- const { spawnEmbodiedAgentInVW } = await import('../../agent/spawn-embodied-agent-in-vw.js');
3317
- const r = await spawnEmbodiedAgentInVW({ brand: 'gemini', mode: 'hybrid', cwd });
3318
- ctx.chatLines.push(ctx.success(` ✓ gemini (pty) in win:${r.windowId} (pane:${r.paneId})`));
3319
- ctx.chatLines.push(ctx.muted(` • H5 Embodied Agent Bus · session:${r.session.id} · pty:${r.ptyId}`));
3320
- ctx.chatLines.push(ctx.muted(` • @pane:${r.paneId} inlines output in next LLM turn`));
3321
- void ctx.conv.openModal(r.session.id);
3322
- } catch (err) {
3323
- ctx.chatLines.push(ctx.error(` /acp-vw gem failed: ${err instanceof Error ? err.message : String(err)}`));
3324
- }
3325
- ctx.setChatScrollOffset(-1);
3326
- ctx.draw();
3327
- })().catch(() => {});
3328
- return;
3329
- }
3330
- // H6 P2 Bundle 2 A — local-llm embodied session via `lms chat <model>`.
3331
- if (cmdLower === 'acp-vw' && (subArg0 === 'lll' || subArg0 === 'local-llm' || subArg0 === 'lmstudio')) {
3332
- (async () => {
3333
- try {
3334
- const rawSpec = args.slice(1).join(' ').trim();
3335
- if (!rawSpec) {
3336
- ctx.chatLines.push(ctx.error(` /acp-vw lll <model> · example: /acp-vw lll local:qwen3.5-35b-a3b`));
3337
- ctx.chatLines.push(ctx.muted(` • run /llm models to list available models`));
3338
- ctx.setChatScrollOffset(-1);
3339
- ctx.draw();
3340
- return;
3341
- }
3342
- ctx.chatLines.push(ctx.muted(` … launching local-llm '${rawSpec}'`));
3343
- ctx.setChatScrollOffset(-1);
3344
- ctx.draw();
3345
- const { spawnLocalLlmInVW } = await import('../../agent/spawn-local-llm-in-vw.js');
3346
- const r = await spawnLocalLlmInVW({ rawSpec, cwd });
3347
- ctx.chatLines.push(ctx.success(` ✓ local-llm (pty) in win:${r.windowId} (pane:${r.paneId})`));
3348
- ctx.chatLines.push(ctx.muted(` • H5 Embodied Agent Bus · session:${r.session.id} · pty:${r.ptyId}`));
3349
- ctx.chatLines.push(ctx.muted(` • @pane:${r.paneId} inlines output in next LLM turn`));
3350
- void ctx.conv.openModal(r.session.id);
3351
- } catch (err) {
3352
- ctx.chatLines.push(ctx.error(` /acp-vw lll failed: ${err instanceof Error ? err.message : String(err)}`));
3353
- }
3354
- ctx.setChatScrollOffset(-1);
3355
- ctx.draw();
3356
- })().catch(() => {});
3357
- return;
3358
- }
3359
- // Default: spawn coding-agent (codex via ACP live · claude via dispatchSpawnCodingAgentInVW).
3360
- const brand: 'claude-code' | 'codex' =
3361
- cmdLower === 'codex-vw' ? 'codex'
3362
- : cmdLower === 'claude-vw' ? 'claude-code'
3363
- : (subArg0 === 'codex' ? 'codex' : 'claude-code');
3364
- (async () => {
3365
- try {
3366
- if (brand === 'codex') {
3367
- // PLAN-tui-redundancy-cleanup T1 (2026-05-16) — `codex-vw`
3368
- // (vw-live-bridge spawn) 트림. backend chip 의 codex 선택 +
3369
- // chat panel 의 main ACP wire 가 동일 capability 제공.
3370
- ctx.chatLines.push(ctx.muted(` /${cmdLower} codex: deprecated — use chat panel with backend = codex-app-server.`));
3371
- } else {
3372
- const { dispatchSpawnCodingAgentInVW } = await import('../../skills/tools/spawn-coding-agent-vw.js');
3373
- const r = await dispatchSpawnCodingAgentInVW(
3374
- { brand, cwd },
3375
- { registry: vwRegistry as Parameters<typeof dispatchSpawnCodingAgentInVW>[1] extends { registry?: infer R } | undefined ? R : never },
3376
- );
3377
- ctx.chatLines.push(ctx.success(` ✓ ${brand} running in win:${r.windowId} (pane:${r.paneId})`));
3378
- ctx.chatLines.push(ctx.muted(` • @pane:${r.paneId} inlines recent output in the next LLM turn`));
3379
- ctx.chatLines.push(ctx.muted(' • PaneInject queues input (approval-gated)'));
3380
- }
3381
- } catch (err) {
3382
- ctx.chatLines.push(ctx.error(` /${cmdLower} failed: ${err instanceof Error ? err.message : String(err)}`));
3383
- }
3384
- ctx.setChatScrollOffset(-1);
3385
- ctx.draw();
3386
- })().catch(() => {});
3387
- };
3388
- registry.register('acp-vw', buildAcpVwHandler('acp-vw'));
3389
- registry.register('claude-vw', buildAcpVwHandler('claude-vw'));
3390
- registry.register('codex-vw', buildAcpVwHandler('codex-vw'));
3391
-
3392
2796
  // ── B-3.c.2 ───────────────────────────────────────────────────────
3393
2797
 
3394
2798
  registry.register(['term', 'terminal'], async (args, ctx) => {
@@ -4314,12 +3718,11 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
4314
3718
  // Originally inline; the session/index.js + acp-boot.js + replay-
4315
3719
  // preview.js helpers are now static-imported in this module.
4316
3720
  // Host-local refs (attachedSessionId / attachedChatId mutable +
4317
- // opts.remote / opts.localDaemon ref + dashboardAcpSession.swapTo)
3721
+ // opts.remote ref + dashboardAcpSession.swapTo)
4318
3722
  // are threaded via ctx.sessionSlash + the four top-level
4319
3723
  // get/setAttached* fields.
4320
3724
  const seSub = (args[0] ?? 'list').toLowerCase();
4321
3725
  const remote = ctx.sessionSlash.remoteDaemon();
4322
- const localDaemon = ctx.sessionSlash.localDaemon();
4323
3726
 
4324
3727
  if (seSub === 'list' || seSub === 'ls') {
4325
3728
  const limit = args[1] ? Math.max(1, Math.min(50, Number(args[1]) || 10)) : 10;
@@ -4395,11 +3798,7 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
4395
3798
  resolved: resolvedId,
4396
3799
  error: resolveErr,
4397
3800
  attachedSessionId: ctx.getAttachedSessionId(),
4398
- daemon: remote
4399
- ? `remote:${remote.url}`
4400
- : localDaemon
4401
- ? `local:${localDaemon.socketPath}`
4402
- : 'in-process',
3801
+ daemon: remote ? `remote:${remote.url}` : 'in-process',
4403
3802
  });
4404
3803
  }
4405
3804
  if (resolveErr) {
@@ -4445,9 +3844,7 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
4445
3844
  return;
4446
3845
  }
4447
3846
  // Swap succeeded — replay history if the daemon exposes
4448
- // it via REST. Local-daemon (unix socket) has no REST
4449
- // endpoint today, so this branch is remote-only by
4450
- // design; an empty history just leaves chat.history
3847
+ // it via REST; an empty history just leaves chat.history
4451
3848
  // as-is (no destructive wipe on miss).
4452
3849
  const past = await fetchDaemonSessionHistory(httpBase, match.id, remote.token);
4453
3850
  const chatHistory = ctx.compactSlash.chatHistory;
@@ -4483,10 +3880,8 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
4483
3880
  }
4484
3881
  }
4485
3882
  ctx.chatLines.push(ctx.warning(` No session matches prefix "${prefix}"`));
4486
- if (remote || localDaemon) {
4487
- const daemonNote = remote
4488
- ? `remote daemon ${remote.url}`
4489
- : `local daemon ${localDaemon!.socketPath}`;
3883
+ if (remote) {
3884
+ const daemonNote = `remote daemon ${remote.url}`;
4490
3885
  ctx.chatLines.push(ctx.muted(` note: TUI's /session store is local-only.`));
4491
3886
  ctx.chatLines.push(ctx.muted(` sessions minted by web/PWA or other clients live on the ${daemonNote},`));
4492
3887
  ctx.chatLines.push(ctx.muted(` not in TUI storage — full daemon-side resume is a follow-up.`));
@@ -4864,7 +4259,7 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
4864
4259
  ctx.setChatScrollOffset(-1);
4865
4260
  return;
4866
4261
  }
4867
- const cfg = getUserConfig();
4262
+ const cfg = ctx.telegramReport?.getConfig() ?? getUserConfig();
4868
4263
  const { resolveReportTarget, sendTelegramReport } = await import('../../telegram-report.js');
4869
4264
  const target = resolveReportTarget(cfg);
4870
4265
  if (!target) {
@@ -4873,7 +4268,7 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
4873
4268
  return;
4874
4269
  }
4875
4270
  try {
4876
- await sendTelegramReport(cfg, msg);
4271
+ await (ctx.telegramReport?.send ?? sendTelegramReport)(cfg, msg);
4877
4272
  ctx.chatLines.push(ctx.success(` ✓ report sent to chat ${target.chatId}`));
4878
4273
  } catch (e: unknown) {
4879
4274
  const m = e instanceof Error ? e.message : String(e);
@@ -5327,19 +4722,20 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
5327
4722
  } else if (sub === 'path') {
5328
4723
  ctx.pushDebugLine(ctx.muted(` debug log path: ${debug.path()}`));
5329
4724
  } else {
5330
- ctx.pushDebugLine(ctx.undo.bold(
4725
+ const output = (line: string): void => { ctx.pushDebugLine(line); ctx.chatLines.push(line); };
4726
+ output(ctx.undo.bold(
5331
4727
  ` debug: file=${debug.isFileEnabled() ? ctx.success('ON') : ctx.muted('OFF')} ` +
5332
4728
  `mirror=${debug.isMirrorEnabled() ? ctx.success('ON') : ctx.muted('OFF')} ` +
5333
4729
  `diag=${debug.isDiagEnabled() ? ctx.warning('ON') : ctx.muted('OFF')} ` +
5334
4730
  `verbose=${debug.isVerboseEnabled() ? ctx.warning('ON') : ctx.muted('OFF')} ` +
5335
4731
  `level=${debug.level()}`,
5336
4732
  ));
5337
- ctx.pushDebugLine(ctx.muted(` log: ${debug.path()}`));
5338
- ctx.pushDebugLine(ctx.muted(' quick: /debug on (mirror+file) /debug off /debug file (quiet trail) /debug diag (loud trail)'));
5339
- ctx.pushDebugLine(ctx.muted(' fine: /debug mirror on|off /debug file on|off /debug diag on|off /debug verbose on|off /debug level off|trail|diag|normal|detail'));
5340
- ctx.pushDebugLine(ctx.muted(' log view: /debug filter [query|clear] /debug tail [N] /debug clear /debug trace [<turn-suffix>]'));
5341
- ctx.pushDebugLine(ctx.muted(' surfaces: /debug window [open|close|toggle] /debug popup [events|detail|stack|prompts|all] [open|close|toggle] /debug workbench [open|close|toggle]'));
5342
- ctx.pushDebugLine(ctx.muted(' misc: /debug toggle | tail [N] | clear | path | view | status'));
4733
+ output(ctx.muted(` log: ${debug.path()}`));
4734
+ output(ctx.muted(' quick: /debug on (mirror+file) /debug off /debug file (quiet trail) /debug diag (loud trail)'));
4735
+ output(ctx.muted(' fine: /debug mirror on|off /debug file on|off /debug diag on|off /debug verbose on|off /debug level off|trail|diag|normal|detail'));
4736
+ output(ctx.muted(' log view: /debug filter [query|clear] /debug tail [N] /debug clear /debug trace [<turn-suffix>]'));
4737
+ output(ctx.muted(' surfaces: /debug window [open|close|toggle] /debug popup [events|detail|stack|prompts|all] [open|close|toggle] /debug workbench [open|close|toggle]'));
4738
+ output(ctx.muted(' misc: /debug toggle | tail [N] | clear | path | view | status'));
5343
4739
  }
5344
4740
  ctx.setChatScrollOffset(-1);
5345
4741
  });
@@ -5548,64 +4944,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
5548
4944
  ctx.setChatScrollOffset(-1);
5549
4945
  });
5550
4946
 
5551
- // ── B-2.AA ────────────────────────────────────────────────────────
5552
-
5553
- registry.register('bench', (args, ctx) => {
5554
- // T2-P5 — spawn a 2-4 pane LLM benchmark window.
5555
- // /bench <prompt> :: <provider[:model]>,<provider[:model]>[,...]
5556
- // The original case parsed cmdText.slice('/bench'.length); the
5557
- // registry passes args[], so we rebuild via args.join(' ') to
5558
- // preserve the prompt's spaces + :: separator.
5559
- const tail = args.join(' ').trim();
5560
- if (!tail || tail === 'help' || tail === '-h' || tail === '--help') {
5561
- ctx.chatLines.push(...ctx.bench.slashRuntime.helpLines());
5562
- ctx.setChatScrollOffset(-1);
5563
- return;
5564
- }
5565
- const sepIdx = tail.indexOf('::');
5566
- if (sepIdx < 0) {
5567
- ctx.chatLines.push(ctx.bench.slashRuntime.missingSeparatorLine());
5568
- ctx.setChatScrollOffset(-1);
5569
- return;
5570
- }
5571
- const prompt = tail.slice(0, sepIdx).trim();
5572
- const providerList = tail.slice(sepIdx + 2).trim();
5573
- if (!prompt) {
5574
- ctx.chatLines.push(ctx.bench.slashRuntime.emptyPromptLine());
5575
- ctx.setChatScrollOffset(-1);
5576
- return;
5577
- }
5578
- const providers = providerList.split(',').map(p => p.trim()).filter(Boolean).map(raw => {
5579
- const [name, model] = raw.split(':');
5580
- return { name: name!, provider: name!, model };
5581
- });
5582
- if (providers.length === 0) {
5583
- ctx.chatLines.push(ctx.bench.slashRuntime.noProvidersLine());
5584
- ctx.setChatScrollOffset(-1);
5585
- return;
5586
- }
5587
- if (providers.length > MAX_BENCHMARK_PANES) {
5588
- ctx.chatLines.push(ctx.bench.slashRuntime.tooManyProvidersLine());
5589
- ctx.setChatScrollOffset(-1);
5590
- return;
5591
- }
5592
- try {
5593
- const handle = ctx.bench.spawn({ prompt, providers });
5594
- ctx.chatLines.push(
5595
- ctx.bench.slashRuntime.spawnedLine(
5596
- handle.window.id,
5597
- handle.paneIds.length,
5598
- providers.map((p) => p.name),
5599
- ),
5600
- );
5601
- } catch (err) {
5602
- ctx.chatLines.push(ctx.bench.slashRuntime.failedLine(
5603
- err instanceof Error ? err.message : String(err),
5604
- ));
5605
- }
5606
- ctx.setChatScrollOffset(-1);
5607
- });
5608
-
5609
4947
  // ── B-2.z ─────────────────────────────────────────────────────────
5610
4948
 
5611
4949
  registry.register('setup', (args, ctx) => {
@@ -5727,46 +5065,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
5727
5065
 
5728
5066
  // ── B-2.x ─────────────────────────────────────────────────────────
5729
5067
 
5730
- registry.register(['skill-triggers', 'triggers'], (args, ctx) => {
5731
- // Phase 3 debug — show the triggers the router sees for a given
5732
- // skill, split by provenance (explicit vs auto-extracted from
5733
- // description). Useful when tuning a SKILL.md description so
5734
- // routing fires right.
5735
- const target = args[0];
5736
- const idx = getSkillIndex();
5737
- ctx.chatLines.push('');
5738
- if (!target) {
5739
- ctx.chatLines.push(...ctx.skill.triggersSlashRuntime.usageLines());
5740
- ctx.setChatScrollOffset(-1);
5741
- return;
5742
- }
5743
- if (target === '*') {
5744
- ctx.chatLines.push(...ctx.skill.triggersSlashRuntime.summaryLines(
5745
- idx.map((entry) => ({
5746
- name: entry.name,
5747
- explicitCount: entry.triggers.length,
5748
- extractedCount: entry.extractedTriggers.length,
5749
- triggerSource: entry.triggerSource,
5750
- })),
5751
- ));
5752
- ctx.setChatScrollOffset(-1);
5753
- return;
5754
- }
5755
- const entry = idx.find(e => e.name === target);
5756
- if (!entry) {
5757
- ctx.chatLines.push(ctx.skill.triggersSlashRuntime.missingSkillLine(target));
5758
- ctx.setChatScrollOffset(-1);
5759
- return;
5760
- }
5761
- ctx.chatLines.push(...ctx.skill.triggersSlashRuntime.detailLines({
5762
- name: target,
5763
- triggerSource: entry.triggerSource,
5764
- triggers: entry.triggers,
5765
- extractedTriggers: entry.extractedTriggers,
5766
- autoTrigger: entry.autoTrigger,
5767
- }));
5768
- ctx.setChatScrollOffset(-1);
5769
- });
5770
5068
 
5771
5069
  registry.register(['run-skill', 'rs', 'run'], async (args, ctx) => {
5772
5070
  const skillArg = args[0];
@@ -5877,280 +5175,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
5877
5175
  ctx.draw();
5878
5176
  });
5879
5177
 
5880
- // ── B-2.v ─────────────────────────────────────────────────────────
5881
-
5882
- registry.register(['scratch', 'sc'], (args, ctx) => {
5883
- // `/scratch <text>` — replace scratchpad with text.
5884
- // `/scratch + <text>` — append (current + blank + text).
5885
- // `/scratch clear` — empty scratchpad.
5886
- // `/scratch dump` — copy scratchpad lines into the log.
5887
- // `/scratch memo` — interactive multi-line memo capture
5888
- // (Ctrl+S save / Esc cancel).
5889
- const sub = (args[0] ?? '').toLowerCase();
5890
- if (sub === 'open' || sub === 'show') {
5891
- if (ctx.scratch.isClosed()) {
5892
- ctx.scratch.open();
5893
- ctx.chatLines.push(ctx.scratch.slashRuntime.reopenedLine());
5894
- } else {
5895
- ctx.chatLines.push(ctx.scratch.slashRuntime.alreadyOpenLine());
5896
- }
5897
- ctx.setChatScrollOffset(-1);
5898
- return;
5899
- }
5900
- if (sub === 'popup' || sub === 'companion') {
5901
- const mode = (args[1] ?? 'toggle').toLowerCase();
5902
- if (mode === 'open' || mode === 'show') {
5903
- ctx.scratch.popup.open();
5904
- ctx.chatLines.push(ctx.scratch.slashRuntime.popupLine(true));
5905
- } else if (mode === 'close' || mode === 'hide') {
5906
- ctx.scratch.popup.close();
5907
- ctx.chatLines.push(ctx.scratch.slashRuntime.popupLine(false));
5908
- } else if (mode === 'toggle' || mode === 't') {
5909
- const opened = ctx.scratch.popup.toggle();
5910
- ctx.chatLines.push(ctx.scratch.slashRuntime.popupLine(opened));
5911
- } else if (mode === 'promote' || mode === 'foreground') {
5912
- ctx.scratch.popup.promote();
5913
- ctx.chatLines.push(ctx.scratch.slashRuntime.popupPromotedLine());
5914
- } else {
5915
- ctx.chatLines.push(ctx.scratch.slashRuntime.popupUsageLine());
5916
- }
5917
- ctx.setChatScrollOffset(-1);
5918
- return;
5919
- }
5920
- if (sub === 'close' || sub === 'hide') {
5921
- if (!ctx.scratch.isClosed()) {
5922
- ctx.scratch.close();
5923
- ctx.chatLines.push(ctx.scratch.slashRuntime.closedLine());
5924
- }
5925
- ctx.setChatScrollOffset(-1);
5926
- return;
5927
- }
5928
- if (sub === 'clear' || sub === 'cls') {
5929
- ctx.scratch.clear();
5930
- ctx.chatLines.push(ctx.scratch.slashRuntime.clearedLine());
5931
- ctx.setChatScrollOffset(-1);
5932
- return;
5933
- }
5934
- if (sub === 'dump' || sub === 'log') {
5935
- const currentScratch = ctx.scratch.currentForCommand();
5936
- if (currentScratch.lines.length === 0) {
5937
- ctx.chatLines.push(ctx.scratch.slashRuntime.emptyDumpLine());
5938
- } else {
5939
- ctx.chatLines.push(ctx.scratch.slashRuntime.dumpHeaderLine(currentScratch.title));
5940
- for (const ln of ctx.scratch.buildDumpLines(currentScratch.lines)) ctx.chatLines.push(ln);
5941
- }
5942
- ctx.setChatScrollOffset(-1);
5943
- return;
5944
- }
5945
- if (sub === 'memo' || sub === 'm') {
5946
- ctx.scratch.openMemo();
5947
- ctx.chatLines.push(ctx.scratch.slashRuntime.memoOpenedLine());
5948
- ctx.setChatScrollOffset(-1);
5949
- return;
5950
- }
5951
- if (args.length === 0) {
5952
- ctx.chatLines.push(ctx.scratch.slashRuntime.usageLine());
5953
- ctx.setChatScrollOffset(-1);
5954
- return;
5955
- }
5956
- // Append vs replace based on a leading `+` token.
5957
- if (args[0] === '+') {
5958
- const body = args.slice(1).join(' ');
5959
- const snapshot = ctx.scratch.snapshotForAppend();
5960
- const next = snapshot.lines.length
5961
- ? [...snapshot.lines, '', ...body.split('\n')]
5962
- : body.split('\n');
5963
- ctx.scratch.setText(snapshot.title || 'Note', next);
5964
- } else {
5965
- ctx.scratch.setText('Note', args.join(' ').split('\n'));
5966
- }
5967
- });
5968
-
5969
- // ── B-2.u ─────────────────────────────────────────────────────────
5970
-
5971
- registry.register('git', async (args, ctx) => {
5972
- // GT3 — read-only git inspection.
5973
- // /git / /git status → porcelain summary
5974
- // /git branch [list] → list all branches
5975
- // /git log [N] → last N commits (default 5)
5976
- // /git diff → git diff HEAD (unified)
5977
- // /git remote → git remote -v
5978
- const swd = getSessionCwd();
5979
- const gitView = getGitStatusView(swd);
5980
- if (!gitView.head) {
5981
- ctx.pushDebugLine(ctx.warning(' /git: not inside a git repo (session cwd has no .git)'));
5982
- ctx.setChatScrollOffset(-1);
5983
- return;
5984
- }
5985
- const sub = (args[0] || 'status').toLowerCase();
5986
- const { runGitCommand } = await import('../../git-fs/runner.js');
5987
- const runGitCmd = (a: string[]): { out: string; status: number } => {
5988
- const r = runGitCommand(swd, a, {
5989
- encoding: 'utf8', timeout: 10_000,
5990
- maxBuffer: 4 * 1024 * 1024,
5991
- });
5992
- return { out: r.stdout + r.stderr, status: r.status ?? -1 };
5993
- };
5994
- if (sub === 'status' || sub === '') {
5995
- refreshGitDirty(swd, { force: true });
5996
- const v = getGitStatusView(swd);
5997
- ctx.pushDebugLine(ctx.undo.bold(` git — ${v.head!.branch ?? `HEAD@${v.head!.sha?.slice(0, 7)}`} ${v.head!.isWorktree ? '(worktree)' : ''}`));
5998
- if (v.dirty) {
5999
- ctx.pushDebugLine(ctx.muted(` staged=${v.dirty.staged} modified=${v.dirty.modified} untracked=${v.dirty.untracked} total=${v.dirty.total}`));
6000
- }
6001
- if (v.aheadBehind) {
6002
- ctx.pushDebugLine(ctx.muted(` upstream: ahead ${v.aheadBehind.ahead} behind ${v.aheadBehind.behind}`));
6003
- }
6004
- const { out } = runGitCmd(['status', '--short']);
6005
- for (const line of out.split('\n').filter(Boolean).slice(0, 40)) {
6006
- ctx.pushDebugLine(ctx.muted(` ${line}`));
6007
- }
6008
- } else if (sub === 'branch') {
6009
- const sub2 = (args[1] || 'list').toLowerCase();
6010
- if (sub2 === 'list' || sub2 === 'ls') {
6011
- const branches = listGitBranches(swd, gitView.head);
6012
- const locals = branches.filter(b => !b.isRemote);
6013
- const remotes = branches.filter(b => b.isRemote);
6014
- ctx.pushDebugLine(ctx.undo.bold(` branches — ${locals.length} local, ${remotes.length} remote`));
6015
- for (const b of locals) {
6016
- const mark = b.isHead ? ctx.success('▸ ') : ' ';
6017
- ctx.pushDebugLine(ctx.muted(` ${mark}${b.name} ${b.sha.slice(0, 7)}`));
6018
- }
6019
- if (remotes.length) {
6020
- ctx.pushDebugLine(ctx.muted(' — remotes —'));
6021
- for (const b of remotes.slice(0, 20)) {
6022
- ctx.pushDebugLine(ctx.muted(` ${b.name} ${b.sha.slice(0, 7)}`));
6023
- }
6024
- }
6025
- } else {
6026
- ctx.pushDebugLine(ctx.warning(' /git branch [list]'));
6027
- }
6028
- } else if (sub === 'log') {
6029
- const n = Math.max(1, Math.min(50, Number.parseInt(args[1] ?? '5', 10) || 5));
6030
- const { out, status } = runGitCmd([
6031
- 'log', `-n${n}`, '--pretty=format:%h %ad %s', '--date=short',
6032
- ]);
6033
- if (status !== 0) {
6034
- ctx.pushDebugLine(ctx.warning(` /git log failed: ${out.trim()}`));
6035
- } else {
6036
- ctx.pushDebugLine(ctx.undo.bold(` last ${n} commits`));
6037
- for (const line of out.split('\n').filter(Boolean)) {
6038
- ctx.pushDebugLine(ctx.muted(` ${line}`));
6039
- }
6040
- }
6041
- } else if (sub === 'diff') {
6042
- const { out } = runGitCmd(['diff', 'HEAD', '--stat']);
6043
- if (!out.trim()) {
6044
- ctx.pushDebugLine(ctx.muted(' no diff against HEAD — clean working tree'));
6045
- } else {
6046
- ctx.pushDebugLine(ctx.undo.bold(' diff --stat vs HEAD'));
6047
- for (const line of out.split('\n').filter(Boolean).slice(0, 60)) {
6048
- ctx.pushDebugLine(ctx.muted(` ${line}`));
6049
- }
6050
- }
6051
- } else if (sub === 'remote') {
6052
- const { out } = runGitCmd(['remote', '-v']);
6053
- if (!out.trim()) {
6054
- ctx.pushDebugLine(ctx.muted(' (no remotes)'));
6055
- } else {
6056
- for (const line of out.split('\n').filter(Boolean)) {
6057
- ctx.pushDebugLine(ctx.muted(` ${line}`));
6058
- }
6059
- }
6060
- } else {
6061
- ctx.pushDebugLine(ctx.warning(' usage: /git [status | branch [list] | log [N] | diff | remote]'));
6062
- }
6063
- ctx.setChatScrollOffset(-1);
6064
- });
6065
-
6066
- // ── B-2.t ─────────────────────────────────────────────────────────
6067
-
6068
- // F1 (2026-05-04) — Renamed from `/compact` to `/memorize`
6069
- // (alias `mem-compact`) to resolve the duplicate registration with
6070
- // the Wave 5 PR #1481 4-layer pipeline `/compact` (line ~3126
6071
- // below). Both registered the same `compact` name, causing
6072
- // `SlashCommandRegistry: duplicate registration for 'compact'`
6073
- // and blocking baseline scenario boot.
6074
- //
6075
- // Naming rationale: this handler's unique feature is
6076
- // `appendCompactToMemory` — writing the summary to MEMORY.md's
6077
- // "Recent work" section + resetting history. The Wave 5 pipeline
6078
- // (`/compact`) does in-context 4-layer reduction without MEMORY.md
6079
- // touch. So:
6080
- // - `/compact` → 4-layer pipeline (in-context reduction)
6081
- // - `/memorize` → summarize-and-archive to MEMORY.md + reset
6082
- //
6083
- // The `mem-compact` alias preserves the legacy semantic for users
6084
- // who muscle-memory `/compact` for the MEMORY.md flow.
6085
- registry.register(['memorize', 'mem-compact'], async (args, ctx) => {
6086
- // WF6 — summarise the current conversation, append to MEMORY.md's
6087
- // "Recent work", and reset chat.history (keeping the system
6088
- // message). Optional --preserve N keeps the last N turns in
6089
- // context.
6090
- const {
6091
- compactConversation,
6092
- compactConversationPartial,
6093
- appendCompactToMemory,
6094
- } = await import('../../compact/index.js');
6095
- const { renderCompactBoundary } = await import('../../chat/compact-boundary.js');
6096
- const preserveArg = args.find((a) => a.startsWith('--preserve'));
6097
- const partial = args.includes('--partial');
6098
- const preserveLastN = preserveArg
6099
- ? Math.max(0, Number.parseInt(preserveArg.split('=')[1] ?? args[args.indexOf(preserveArg) + 1] ?? '0', 10) || 0)
6100
- : partial ? 2 : 0;
6101
- const history = ctx.compact.getHistory();
6102
- ctx.pushDebugLine(ctx.muted(`[compact] summarising ${history.filter(m => m.role !== 'system').length} turns${partial ? ` (partial, keeping last ${preserveLastN})` : ''}…`));
6103
- ctx.setChatScrollOffset(-1);
6104
- try { ctx.draw(); } catch { /* noop */ }
6105
- try {
6106
- // The compact helpers expect LLMMessage[]; the host owns the
6107
- // typed array. Cast through unknown — same pattern the inline
6108
- // case used.
6109
- const compactHistory = history as unknown as Parameters<typeof compactConversation>[0];
6110
- let upToIndex = compactHistory.length - 1;
6111
- if (partial) {
6112
- let trailing = preserveLastN;
6113
- upToIndex = -1;
6114
- for (let i = compactHistory.length - 1; i >= 0; i--) {
6115
- if (compactHistory[i]!.role === 'system') continue;
6116
- if (trailing > 0) {
6117
- trailing--;
6118
- continue;
6119
- }
6120
- upToIndex = i;
6121
- break;
6122
- }
6123
- }
6124
- const { summary } = partial
6125
- ? await compactConversationPartial(compactHistory, { preserveLastN, upToIndex })
6126
- : await compactConversation(compactHistory, { preserveLastN });
6127
- if (summary) {
6128
- const { path } = await appendCompactToMemory(summary);
6129
- ctx.pushDebugLine(ctx.success(`[compact] summary appended to ${path}`));
6130
- const sections = ['Goal', 'Instructions', 'Discoveries', 'Accomplished', 'Relevant files / directories']
6131
- .filter((name) => summary.includes(`## ${name}`));
6132
- ctx.pushDebugLine(ctx.muted(`[compact] sections: ${sections.join(', ') || '(none)'}`));
6133
- } else {
6134
- ctx.pushDebugLine(ctx.muted('[compact] nothing to summarise'));
6135
- }
6136
- // Reset history, keep the system message, keep preserveLastN trailing turns.
6137
- const sys = history.find((m) => m.role === 'system');
6138
- const tail = history.filter((m) => m.role !== 'system').slice(-preserveLastN);
6139
- history.length = 0;
6140
- if (sys) history.push(sys);
6141
- for (const t of tail) history.push(t);
6142
- if (ctx.compact.compactBoundaryEnabled()) {
6143
- ctx.pushChatLine(renderCompactBoundary(
6144
- partial ? 'partial' : 'manual',
6145
- partial && preserveLastN > 0 ? `last ${preserveLastN}` : undefined,
6146
- ));
6147
- }
6148
- ctx.pushDebugLine(ctx.muted(`[compact] history reset${preserveLastN ? ` (kept last ${preserveLastN} turns)` : ''}`));
6149
- } catch (err) {
6150
- ctx.pushDebugLine(ctx.warning(`[compact] failed: ${err instanceof Error ? err.message : String(err)}`));
6151
- }
6152
- ctx.setChatScrollOffset(-1);
6153
- });
6154
5178
 
6155
5179
  // ── B-2.s ─────────────────────────────────────────────────────────
6156
5180
 
@@ -6353,93 +5377,9 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
6353
5377
 
6354
5378
  // ── B-2.q ─────────────────────────────────────────────────────────
6355
5379
 
6356
- registry.register(['sim', 'simulator'], async (args, ctx) => {
6357
- const sub = (args[0] || 'open').toLowerCase();
6358
- ctx.chatLines.push('');
6359
- ctx.chatLines.push(ctx.accent(`❯ /sim ${args.join(' ').trim() || 'open'}`));
6360
- if (sub === 'help') {
6361
- for (const line of ctx.sim.slashRuntime.usageLines()) ctx.chatLines.push(line);
6362
- ctx.setChatScrollOffset(-1);
6363
- return;
6364
- }
6365
- if (sub === 'open') {
6366
- const id = ctx.sim.spawnVirtualWindow();
6367
- ctx.chatLines.push(ctx.sim.slashRuntime.openedLine(id));
6368
- ctx.setChatScrollOffset(-1);
6369
- return;
6370
- }
6371
- if (sub === 'web') {
6372
- const result = await ctx.sim.openWebCockpit();
6373
- ctx.chatLines.push(ctx.sim.slashRuntime.openedWebLine(result.path));
6374
- ctx.setChatScrollOffset(-1);
6375
- return;
6376
- }
6377
- if (sub === 'list' || sub === 'ls') {
6378
- for (const line of ctx.sim.slashRuntime.listLines(ctx.sim.listScenarios())) ctx.chatLines.push(line);
6379
- ctx.setChatScrollOffset(-1);
6380
- return;
6381
- }
6382
- if (sub === 'run') {
6383
- const scenarioId = ctx.sim.resolveScenarioId(args[1] || '');
6384
- if (!scenarioId) {
6385
- ctx.chatLines.push(ctx.sim.slashRuntime.unknownScenarioLine(args[1] || ''));
6386
- ctx.setChatScrollOffset(-1);
6387
- return;
6388
- }
6389
- ctx.chatLines.push(ctx.sim.slashRuntime.runHeading(scenarioId));
6390
- const result = await ctx.sim.runById(scenarioId);
6391
- for (const line of result.lines) {
6392
- ctx.chatLines.push(result.status === 'error' ? ctx.warning(` ${line}`) : ctx.muted(` ${line}`));
6393
- }
6394
- ctx.setChatScrollOffset(-1);
6395
- return;
6396
- }
6397
- for (const line of ctx.sim.slashRuntime.usageLines()) ctx.chatLines.push(line);
6398
- ctx.setChatScrollOffset(-1);
6399
- });
6400
5380
 
6401
5381
  // ── B-2.p ─────────────────────────────────────────────────────────
6402
5382
 
6403
- registry.register(['view', 'v'], (args, ctx) => {
6404
- // `/view <id|label|shortcut>` switches configured views.
6405
- // `/view list`, `/view next`, `/view prev`, `/view reload`
6406
- // expose the yazi-style user-config registry.
6407
- const sub = (args[0] ?? '').trim();
6408
- if (sub === 'list' || sub === 'ls') {
6409
- ctx.chatLines.push(...ctx.view.slashRuntime.listLines(ctx.view.buildListItems()));
6410
- const closed = ctx.view.closedPaneLabels();
6411
- if (closed.length > 0) {
6412
- ctx.chatLines.push(...ctx.view.slashRuntime.closedPaneLines(closed));
6413
- }
6414
- } else if (sub === 'next' || sub === '+') {
6415
- ctx.view.next();
6416
- } else if (sub === 'prev' || sub === '-') {
6417
- ctx.view.prev();
6418
- } else if (sub === 'reload') {
6419
- ctx.view.reload();
6420
- ctx.chatLines.push(ctx.view.slashRuntime.reloadedLine());
6421
- } else if (sub === 'save') {
6422
- ctx.view.save();
6423
- ctx.chatLines.push(ctx.view.slashRuntime.savedLine());
6424
- } else if (sub === 'restore') {
6425
- ctx.view.restoreAllClosed();
6426
- ctx.chatLines.push(ctx.view.slashRuntime.restoredLine());
6427
- } else if (sub === 'reset') {
6428
- ctx.view.reset();
6429
- ctx.chatLines.push(ctx.view.slashRuntime.resetLine());
6430
- } else if (sub === 'export') {
6431
- const json = ctx.view.exportConfigJson();
6432
- ctx.view.openDetailViewer('Dashboard Views JSON', json.split('\n'));
6433
- ctx.chatLines.push(ctx.view.slashRuntime.exportedLine());
6434
- } else {
6435
- const opened = ctx.view.openByQuery(sub);
6436
- if (!opened) {
6437
- ctx.chatLines.push(ctx.view.slashRuntime.usageLine());
6438
- }
6439
- }
6440
- ctx.setChatScrollOffset(-1);
6441
- });
6442
-
6443
5383
  // ── B-2.o ─────────────────────────────────────────────────────────
6444
5384
 
6445
5385
  registry.register('intake', (args, ctx) => {
@@ -6451,65 +5391,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
6451
5391
 
6452
5392
  // ── B-2.n ─────────────────────────────────────────────────────────
6453
5393
 
6454
- registry.register(['turn-slider', 'turnslider', 'tslider'], async (args, ctx) => {
6455
- // Arc 2.3 (PLAN §4.7) — render the UndoTurn time-travel slider as
6456
- // text. Reads the existing snapshot ring; pure read-only display
6457
- // + an explicit `restore` sub-command that delegates to the same
6458
- // backend /undo uses.
6459
- // /turn-slider → bar + detail
6460
- // /turn-slider <id> → move cursor to <id>
6461
- // /turn-slider restore → restore to current cursor
6462
- // /turn-slider restore <id>→ restore to specified id
6463
- const {
6464
- buildSliderState, setSliderCursor, renderSliderDetail,
6465
- restoreToCursor,
6466
- } = await import('../../undo-turn/index.js');
6467
- const sub = (args[0] || '').trim();
6468
-
6469
- if (sub === 'restore') {
6470
- let state = buildSliderState();
6471
- const targetId = (args[1] || '').trim();
6472
- if (targetId) {
6473
- const idx = state.entries.findIndex((e) => e.id === targetId || e.shaShort === targetId);
6474
- if (idx === -1) {
6475
- ctx.pushDebugLine(ctx.warning(` /turn-slider: no snapshot matches "${targetId}"`));
6476
- ctx.setChatScrollOffset(-1);
6477
- return;
6478
- }
6479
- state = setSliderCursor(state, idx);
6480
- }
6481
- const result = restoreToCursor(state);
6482
- if (result.ok) {
6483
- ctx.pushDebugLine(ctx.success(` ✓ /turn-slider: restored — ${result.summary}`));
6484
- try { ctx.undo.refreshGitDirty(); } catch { /* noop */ }
6485
- } else {
6486
- ctx.pushDebugLine(ctx.error(` /turn-slider: ${result.error ?? result.summary}`));
6487
- }
6488
- ctx.setChatScrollOffset(-1);
6489
- return;
6490
- }
6491
-
6492
- // Default: render bar + detail. Optional positional arg moves the
6493
- // cursor to a specific id before rendering so the user can scrub
6494
- // by typing.
6495
- let state = buildSliderState();
6496
- if (sub) {
6497
- const idx = state.entries.findIndex((e) => e.id === sub || e.shaShort === sub);
6498
- if (idx >= 0) state = setSliderCursor(state, idx);
6499
- }
6500
- const lines = renderSliderDetail(state);
6501
- ctx.pushDebugLine(ctx.undo.bold(' /turn-slider'));
6502
- for (const line of lines) {
6503
- if (/^\(no/.test(line)) ctx.pushDebugLine(ctx.muted(' ' + line));
6504
- else if (/^turn /.test(line)) ctx.pushDebugLine(ctx.accent(' ' + line));
6505
- else if (/description:/.test(line)) ctx.pushDebugLine(ctx.muted(' ' + line));
6506
- else ctx.pushDebugLine(' ' + line);
6507
- }
6508
- if (state.entries.length > 0) {
6509
- ctx.pushDebugLine(ctx.muted(' → /turn-slider <id|sha7> to scrub · /turn-slider restore [id] to restore'));
6510
- }
6511
- ctx.setChatScrollOffset(-1);
6512
- });
6513
5394
 
6514
5395
  // ── B-2.m ─────────────────────────────────────────────────────────
6515
5396
 
@@ -6619,17 +5500,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
6619
5500
 
6620
5501
  // ── B-2.j ─────────────────────────────────────────────────────────
6621
5502
 
6622
- registry.register('playground', async (args, ctx) => {
6623
- // F-B2 — declarative scenario harness. Usage:
6624
- // /playground [list] → enumerate registered scenarios
6625
- // /playground run <id> [-v] → execute + print result
6626
- // Default scenarios (dialog/picker/theme) are registered once per
6627
- // process at init; follow-up arcs can append via
6628
- // `getDefaultScenarioRegistry().register(...)`.
6629
- const lines = await ctx.playground.runCommand(args);
6630
- for (const l of lines) ctx.chatLines.push(ctx.text(l));
6631
- ctx.setChatScrollOffset(-1);
6632
- });
6633
5503
 
6634
5504
  // ── B-2.i ─────────────────────────────────────────────────────────
6635
5505
 
@@ -6670,48 +5540,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
6670
5540
 
6671
5541
  // ── B-2.h ─────────────────────────────────────────────────────────
6672
5542
 
6673
- registry.register(['pty-pane', 'pty-view'], async (args, ctx) => {
6674
- // V3 (DESIGN-background-terminal-port.md §5 V3): open a
6675
- // VirtualWindow containing a pty-tail pane that live-renders an
6676
- // already-spawned registry PTY. Usage:
6677
- // /pty-pane — auto-pick when exactly 1 alive
6678
- // /pty-pane <pty_id> — pick by id (partial ok)
6679
- const { listPty: lp, ptyAvailable: pa } = await import('../../pty-shell/registry.js');
6680
- if (!pa()) {
6681
- ctx.chatLines.push(ctx.warning(' PtyShell unavailable — node-pty not installed'));
6682
- ctx.setChatScrollOffset(-1);
6683
- return;
6684
- }
6685
- const live = lp().filter(h => h.isAlive());
6686
- const target = (() => {
6687
- const wanted = (args[0] ?? '').trim();
6688
- if (!wanted) {
6689
- if (live.length === 0) return { err: 'no live PTY shells — spawn one via PtyShellStart first' };
6690
- if (live.length > 1) return { err: `${live.length} PTYs alive; pass an id (see /pty-list)` };
6691
- return { handle: live[0]! };
6692
- }
6693
- const match = live.find(h => h.id === wanted)
6694
- ?? live.find(h => h.id.startsWith(wanted))
6695
- ?? lp().find(h => h.id === wanted);
6696
- if (!match) return { err: `no PTY matches "${wanted}"` };
6697
- return { handle: match };
6698
- })();
6699
- if ('err' in target) {
6700
- ctx.pushDebugLine(ctx.warning(` ${target.err}`));
6701
- } else {
6702
- try {
6703
- const w = ctx.ptyPane.spawnPtyTailWindow({
6704
- title: `pty:${target.handle.id}`,
6705
- ptyId: target.handle.id,
6706
- });
6707
- ctx.pushDebugLine(ctx.success(` opened win:${w.id} tailing ${target.handle.id}`));
6708
- } catch (e) {
6709
- ctx.pushDebugLine(ctx.warning(` could not open pane: ${e instanceof Error ? e.message : String(e)}`));
6710
- }
6711
- }
6712
- ctx.setChatScrollOffset(-1);
6713
- });
6714
-
6715
5543
  // ── B-2.g ─────────────────────────────────────────────────────────
6716
5544
 
6717
5545
  registry.register('undo', async (args, ctx) => {
@@ -6730,14 +5558,15 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
6730
5558
  const sub = (args[0] || '').toLowerCase();
6731
5559
  if (sub === 'list' || sub === 'ls') {
6732
5560
  const snaps = listSnapshots();
5561
+ const output = (line: string): void => { ctx.pushDebugLine(line); ctx.chatLines.push(line); };
6733
5562
  if (snaps.length === 0) {
6734
- ctx.pushDebugLine(ctx.muted(' /undo: no snapshots yet'));
5563
+ output(ctx.muted(' /undo: no snapshots yet'));
6735
5564
  } else {
6736
- ctx.pushDebugLine(ctx.undo.bold(` undo history — ${snaps.length} snapshot${snaps.length === 1 ? '' : 's'} (newest last)`));
5565
+ output(ctx.undo.bold(` undo history — ${snaps.length} snapshot${snaps.length === 1 ? '' : 's'} (newest last)`));
6737
5566
  for (const s of snaps) {
6738
5567
  const ageSec = Math.round((Date.now() - s.capturedAt) / 1000);
6739
5568
  const desc = s.description ? ` · ${s.description.slice(0, 60)}` : '';
6740
- ctx.pushDebugLine(ctx.muted(` ${s.id} ${s.sha.slice(0, 7)} ${ageSec}s ago${desc}`));
5569
+ output(ctx.muted(` ${s.id} ${s.sha.slice(0, 7)} ${ageSec}s ago${desc}`));
6741
5570
  }
6742
5571
  }
6743
5572
  } else if (sub === 'clear') {
@@ -6775,24 +5604,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
6775
5604
 
6776
5605
  // ── B-2.f ─────────────────────────────────────────────────────────
6777
5606
 
6778
- registry.register(['fullscreen', 'fs'], (_args, ctx) => {
6779
- const current = terminalModalRouter.current();
6780
- if (!current) {
6781
- ctx.chatLines.push(ctx.terminal.fullscreenMissingLine());
6782
- ctx.setChatScrollOffset(-1);
6783
- return;
6784
- }
6785
- const { cols: tc, rows: tr } = termSize();
6786
- if (current.isFullscreen(tc, tr)) {
6787
- current.exitFullscreen(tc, tr);
6788
- ctx.terminal.showFullscreenToast({ title: 'Fullscreen off' });
6789
- } else {
6790
- current.enterFullscreen(tc, tr);
6791
- ctx.terminal.showFullscreenToast({ title: 'Fullscreen on', lines: ['Esc to detach'] });
6792
- }
6793
- ctx.draw();
6794
- });
6795
-
6796
5607
  // ── B-2.e ─────────────────────────────────────────────────────────
6797
5608
 
6798
5609
  registry.register(['history', 'hist', 'inputs'], (args, ctx) => {
@@ -6901,17 +5712,18 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
6901
5712
  }
6902
5713
  } else if (sub === 'list') {
6903
5714
  const entries = listAllowed();
5715
+ const output = (line: string): void => { ctx.pushDebugLine(line); ctx.chatLines.push(line); };
6904
5716
  if (entries.length === 0) {
6905
- ctx.pushDebugLine(ctx.muted(' api-allow: empty (api_call will refuse every URL)'));
6906
- ctx.pushDebugLine(ctx.muted(' add a host with /api-allow add <host>'));
5717
+ output(ctx.muted(' api-allow: empty (api_call will refuse every URL)'));
5718
+ output(ctx.muted(' add a host with /api-allow add <host>'));
6907
5719
  } else {
6908
- ctx.pushDebugLine(ctx.muted(` api-allow: ${entries.length} entr${entries.length === 1 ? 'y' : 'ies'}`));
5720
+ output(ctx.muted(` api-allow: ${entries.length} entr${entries.length === 1 ? 'y' : 'ies'}`));
6909
5721
  for (const e of entries) {
6910
5722
  const reason = e.reason ? ` — ${e.reason}` : '';
6911
5723
  const ageMin = Math.round((Date.now() - e.addedAt) / 60_000);
6912
- ctx.pushDebugLine(ctx.muted(` ${e.host.padEnd(28)} added ${ageMin}m ago${reason}`));
5724
+ output(ctx.muted(` ${e.host.padEnd(28)} added ${ageMin}m ago${reason}`));
6913
5725
  const status = rateLimitStatus(`https://${e.host}/`);
6914
- ctx.pushDebugLine(ctx.muted(` rate budget — host:${status.hostRemaining} global:${status.globalRemaining}`));
5726
+ output(ctx.muted(` rate budget — host:${status.hostRemaining} global:${status.globalRemaining}`));
6915
5727
  }
6916
5728
  }
6917
5729
  } else if (sub === 'clear') {
@@ -6937,15 +5749,16 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
6937
5749
  const sub = (args[0] || '').trim();
6938
5750
  if (sub === 'list' || sub === 'ls') {
6939
5751
  const turns = listCheckpointTurns();
5752
+ const output = (line: string): void => { ctx.pushDebugLine(line); ctx.chatLines.push(line); };
6940
5753
  if (turns.length === 0) {
6941
- ctx.pushDebugLine(ctx.muted(' /resume: no checkpoints on disk yet — invoke /pause mid-turn or run a decision-boundary tool first.'));
5754
+ output(ctx.muted(' /resume: no checkpoints on disk yet — invoke /pause mid-turn or run a decision-boundary tool first.'));
6942
5755
  } else {
6943
- ctx.pushDebugLine(ctx.accent(` resume — ${turns.length} checkpointed turn${turns.length === 1 ? '' : 's'} (newest first)`));
5756
+ output(ctx.accent(` resume — ${turns.length} checkpointed turn${turns.length === 1 ? '' : 's'} (newest first)`));
6944
5757
  for (const turn of turns.slice(0, 10)) {
6945
- ctx.pushDebugLine(ctx.muted(` ${turn}`));
5758
+ output(ctx.muted(` ${turn}`));
6946
5759
  }
6947
5760
  if (turns.length > 10) {
6948
- ctx.pushDebugLine(ctx.muted(` …${turns.length - 10} more`));
5761
+ output(ctx.muted(` …${turns.length - 10} more`));
6949
5762
  }
6950
5763
  }
6951
5764
  ctx.setChatScrollOffset(-1);
@@ -7014,67 +5827,6 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
7014
5827
  ctx.setChatScrollOffset(-1);
7015
5828
  });
7016
5829
 
7017
- registry.register('branch', async (args, ctx) => {
7018
- // GT4 — git worktree mgmt mirrored at slash surface.
7019
- const { enterWorktreeRuntime, exitWorktreeRuntime, currentWorktreeSummary } =
7020
- await import('../../tool-runtime/git-worktree-runtimes.js');
7021
- const { getSessionCwd } = await import('../../session/working-dir.js');
7022
- const sub = (args[0] || 'list').toLowerCase();
7023
- const swd = getSessionCwd();
7024
- if (sub === 'list' || sub === 'ls') {
7025
- const summary = currentWorktreeSummary(swd);
7026
- if (!summary.repoRoot) {
7027
- ctx.pushDebugLine(ctx.warning(' /branch: not inside a git repo'));
7028
- } else {
7029
- ctx.pushDebugLine(ctx.accent(` worktrees — ${summary.entries.length} total${summary.isWorktree ? ' (you are IN a secondary worktree)' : ''}`));
7030
- for (const e of summary.entries) {
7031
- const mark = e.isMain ? '★' : (e.path === swd ? '▸' : ' ');
7032
- const label = e.isDetached ? `(detached ${e.sha.slice(0, 7)})` : (e.branch ?? '');
7033
- ctx.pushDebugLine(ctx.muted(` ${mark} ${e.path} ${label}${e.isLocked ? ' [locked]' : ''}`));
7034
- }
7035
- }
7036
- } else if (sub === 'new') {
7037
- const name = args.slice(1).join(' ').trim();
7038
- if (!name) {
7039
- ctx.pushDebugLine(ctx.warning(' usage: /branch new <branch-name>'));
7040
- } else {
7041
- try {
7042
- const r = await enterWorktreeRuntime.run({ name }, { surface: 'tui' });
7043
- ctx.pushDebugLine(ctx.success(` ${r.output}`));
7044
- } catch (err) {
7045
- ctx.pushDebugLine(ctx.error(` /branch new: ${err instanceof Error ? err.message : String(err)}`));
7046
- }
7047
- }
7048
- } else if (sub === 'exit') {
7049
- const prune = args.slice(1).includes('prune');
7050
- const force = args.slice(1).includes('force');
7051
- try {
7052
- const r = await exitWorktreeRuntime.run({ prune, force }, { surface: 'tui' });
7053
- ctx.pushDebugLine(ctx.success(` ${r.output}`));
7054
- } catch (err) {
7055
- ctx.pushDebugLine(ctx.error(` /branch exit: ${err instanceof Error ? err.message : String(err)}`));
7056
- }
7057
- } else if (sub === 'switch' || sub === 'checkout') {
7058
- const target = args.slice(1).join(' ').trim();
7059
- if (!target) {
7060
- ctx.pushDebugLine(ctx.warning(' usage: /branch switch <branch>'));
7061
- } else {
7062
- const { runGitCommand } = await import('../../git-fs/runner.js');
7063
- const r = runGitCommand(swd, ['switch', target], {
7064
- encoding: 'utf8', timeout: 10_000,
7065
- });
7066
- if (r.status === 0) {
7067
- ctx.pushDebugLine(ctx.success(` ✓ switched to ${target}`));
7068
- } else {
7069
- const msg = (r.stderr || r.stdout || '').trim();
7070
- ctx.pushDebugLine(ctx.error(` /branch switch failed: ${msg}`));
7071
- }
7072
- }
7073
- } else {
7074
- ctx.pushDebugLine(ctx.warning(' usage: /branch [list | new <name> | exit [prune] [force] | switch <name>]'));
7075
- }
7076
- ctx.setChatScrollOffset(-1);
7077
- });
7078
5830
 
7079
5831
  // ── B-2.b ─────────────────────────────────────────────────────────
7080
5832
 
@@ -7083,11 +5835,12 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
7083
5835
  const sub = (args[0] || 'status').toLowerCase();
7084
5836
  if (sub === 'status' || sub === '') {
7085
5837
  const s = getPlanModeState();
5838
+ const output = (line: string): void => { ctx.pushDebugLine(line); ctx.chatLines.push(line); };
7086
5839
  if (s.active) {
7087
- ctx.pushDebugLine(ctx.accent(` plan mode: ${ctx.success('ACTIVE')} (session ${s.sessionId}, phase ${s.phase})`));
7088
- ctx.pushDebugLine(ctx.muted(` plan file: ${s.planFilePath}`));
5840
+ output(ctx.accent(` plan mode: ${ctx.success('ACTIVE')} (session ${s.sessionId}, phase ${s.phase})`));
5841
+ output(ctx.muted(` plan file: ${s.planFilePath}`));
7089
5842
  } else {
7090
- ctx.pushDebugLine(ctx.muted(' plan mode: inactive — /plan start [title] to enter'));
5843
+ output(ctx.muted(' plan mode: inactive — /plan start [title] to enter'));
7091
5844
  }
7092
5845
  } else if (sub === 'start') {
7093
5846
  const title = args.slice(1).join(' ').trim();
@@ -7142,83 +5895,16 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
7142
5895
  ctx.pushDebugLine(ctx.muted(' code-edit policy reset to default (ask-edit)'));
7143
5896
  } else {
7144
5897
  const p = getPolicy();
7145
- ctx.pushDebugLine(ctx.muted(` code-edit policy: ${p.mode}${p.mode === 'trusted-dirs' && p.trustedDirs ? ` (${p.trustedDirs.length} dirs)` : ''}`));
5898
+ const line = ctx.muted(` code-edit policy: ${p.mode}${p.mode === 'trusted-dirs' && p.trustedDirs ? ` (${p.trustedDirs.length} dirs)` : ''}`);
5899
+ ctx.pushDebugLine(line);
5900
+ ctx.chatLines.push(line);
7146
5901
  }
7147
5902
  ctx.setChatScrollOffset(-1);
7148
5903
  });
7149
5904
 
7150
5905
  // ── B-2.a (medium-tier first round) ──────────────────────────────
7151
5906
 
7152
- registry.register('audit', (args, ctx) => {
7153
- // R4 — tail the control audit log. Default scope: input policy
7154
- // changes; `/audit all` shows every category. Optional --tail N /
7155
- // --since DUR.
7156
- const scope = (args[0] || 'input').toLowerCase();
7157
- let tailN = 20;
7158
- let sinceMs: number | undefined;
7159
- for (let i = 1; i < args.length; i++) {
7160
- const a = args[i]!;
7161
- if (a === '--tail' && i + 1 < args.length) {
7162
- const n = Number.parseInt(args[++i]!, 10);
7163
- if (Number.isFinite(n) && n > 0) tailN = n;
7164
- } else if (a === '--since' && i + 1 < args.length) {
7165
- const d = parseAuditDuration(args[++i]!);
7166
- if (d !== null) sinceMs = d;
7167
- }
7168
- }
7169
- const predicate = scope === 'all' ? undefined : isInputAuditEntry;
7170
- const result = readAuditTail({
7171
- ...(predicate ? { match: predicate } : {}),
7172
- tail: tailN,
7173
- ...(sinceMs !== undefined ? { sinceMs } : {}),
7174
- });
7175
- if (result.filesScanned.length === 0) {
7176
- ctx.pushDebugLine(ctx.muted(' [audit] no audit files found (today + yesterday checked)'));
7177
- } else if (result.entries.length === 0) {
7178
- const scopeLabel = scope === 'all' ? 'all' : 'input';
7179
- const sinceLabel = sinceMs !== undefined ? ` (within ${sinceMs}ms window)` : '';
7180
- ctx.pushDebugLine(ctx.muted(` [audit] no ${scopeLabel} entries${sinceLabel}`));
7181
- } else {
7182
- const truncLabel = result.truncated ? ` (showing last ${tailN})` : '';
7183
- ctx.pushDebugLine(ctx.muted(` [audit] ${scope}${truncLabel} — ${result.entries.length} entries`));
7184
- for (const e of result.entries) {
7185
- const line = formatAuditEntry(e);
7186
- ctx.pushDebugLine(e.ok ? ctx.text(' ' + line) : ctx.warning(' ' + line));
7187
- }
7188
- }
7189
- ctx.setChatScrollOffset(-1);
7190
- });
7191
5907
 
7192
- registry.register(['substrate-stats', 'sst'], (_args, ctx) => {
7193
- // Phase 5 — operator-on-demand observability for the 3-layer
7194
- // paint pipeline cache + L5 mount churn + F8 generation bumps.
7195
- const s = ctx.substrateStats;
7196
- const paintStats = s.paintCacheStats();
7197
- const overlayStats = s.overlayWriteStats();
7198
- const genStats = s.generationStats();
7199
- const f8Shadow = s.f8ShadowStats();
7200
- ctx.pushDebugLine(ctx.accent(' substrate stats'));
7201
- ctx.pushDebugLine(ctx.muted(
7202
- ` paint-cache hits=${paintStats.hits} misses=${paintStats.misses} size=${paintStats.size}`,
7203
- ));
7204
- ctx.pushDebugLine(ctx.muted(
7205
- ` overlay skipped=${overlayStats.skipped} written=${overlayStats.written}`,
7206
- ));
7207
- ctx.pushDebugLine(ctx.muted(
7208
- ` f8 shadow mode=${f8Shadow.mode ? 'ON' : 'off'} divergences=${f8Shadow.divergences}`,
7209
- ));
7210
- if (genStats.length > 0) {
7211
- ctx.pushDebugLine(ctx.muted(` bumps (top ${Math.min(5, genStats.length)})`));
7212
- const now = Date.now();
7213
- for (const e of genStats.slice(0, 5)) {
7214
- const ageS = Math.max(0, Math.round((now - e.lastBumpAt) / 1000));
7215
- ctx.pushDebugLine(ctx.muted(` ${e.id} bumps=${e.bumps} age=${ageS}s`));
7216
- }
7217
- } else {
7218
- ctx.pushDebugLine(ctx.muted(' bumps (none recorded)'));
7219
- }
7220
- ctx.setChatScrollOffset(-1);
7221
- });
7222
5908
 
7223
5909
  registry.register('wd', async (args, ctx) => {
7224
5910
  // WD8 — session working directory control.
@@ -7229,8 +5915,11 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
7229
5915
  if (args.length === 0 || sub === 'show' || sub === 'status') {
7230
5916
  const s = getSessionWorkingDir();
7231
5917
  const ageSec = Math.round((Date.now() - s.setAt) / 1000);
7232
- ctx.pushDebugLine(ctx.accent(` session working dir: ${s.cwd}`));
7233
- ctx.pushDebugLine(ctx.muted(` origin: ${s.origin} · set ${ageSec}s ago`));
5918
+ const location = ctx.accent(` session working dir: ${s.cwd}`);
5919
+ const origin = ctx.muted(` origin: ${s.origin} · set ${ageSec}s ago`);
5920
+ ctx.pushDebugLine(location);
5921
+ ctx.pushDebugLine(origin);
5922
+ ctx.chatLines.push(location, origin);
7234
5923
  } else if (sub === 'reset') {
7235
5924
  const restored = initSessionWorkingDir(process.cwd());
7236
5925
  ctx.pushDebugLine(ctx.success(` ✓ working dir reset to boot cwd → ${restored.cwd}`));
@@ -7538,15 +6227,7 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
7538
6227
  }
7539
6228
  }, { immediateDuringStream: true });
7540
6229
 
7541
- registry.register(['usage', 'stats'], (_args, ctx) => {
7542
- const text = USAGE_SLASH_DESCRIPTOR.render();
7543
- for (const line of text.split('\n')) ctx.chatLines.push(line);
7544
- ctx.setChatScrollOffset(-1);
7545
- });
7546
6230
 
7547
- // /cost alias note: 'budget' is already taken by the B-1.d
7548
- // skill-tool budget slash (registered above), so we use only
7549
- // ['cost', 'spend'].
7550
6231
  // ── B4 (TUI half) — /design shows the craft-rulebook verdict ─────────
7551
6232
  // The same verdict `elanous repo design-check` prints and the PWA
7552
6233
  // `/design-check` panel renders, resolved through the SAME
@@ -7557,6 +6238,10 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
7557
6238
  // pane is the "slash output only reaches a hidden pane" problem this
7558
6239
  // track has on its backlog, and there is no reason to inherit it here.
7559
6240
  registry.register(['design', 'design-check'], (args, ctx) => {
6241
+ if (args[0] === 'pick') {
6242
+ handleDesignPick(args.slice(1), ctx);
6243
+ return;
6244
+ }
7560
6245
  const tone: Record<DesignCheckTone, (t: string) => string> = {
7561
6246
  heading: ctx.highlight,
7562
6247
  ok: ctx.success,
@@ -7628,12 +6313,5 @@ export function buildDashboardSlashRegistry(): SlashCommandRegistry<DashboardSla
7628
6313
  ctx.setChatScrollOffset(-1);
7629
6314
  });
7630
6315
 
7631
- // Interactive OAuth cannot finish inside this screen — name the CLI to type.
7632
- registry.register(['codex-setup', 'codex-init'], (_args, ctx) => {
7633
- ctx.chatLines.push(' Interactive OAuth cannot finish inside this screen.');
7634
- ctx.chatLines.push(' Type `elanous codex setup` in a terminal to continue.');
7635
- ctx.setChatScrollOffset(-1);
7636
- });
7637
-
7638
6316
  return registry;
7639
6317
  }