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
@@ -26,27 +26,31 @@
26
26
  // personal :443 forwards).
27
27
  //
28
28
  // Auto port collision recovery:
29
- // - NEXUS port: prefer 31415 → 31420 (skip 31416-31419 to keep the
30
- // classic +5 NEXUS spacing) → 31421+. Skip if production daemon
31
- // (`~/.elanous/nexus/.lock`) holds it OR an unrelated process binds
32
- // it (lsof check).
29
+ // - NEXUS port: coordinator lease in 31450–31499; if the coordinator is
30
+ // absent or answers with any error, fall back to the machine-local
31
+ // test-band lease (`leaseTestPort`, 31450–31499). Never pick
32
+ // production-reserved ports (31413 · 31415 · 31420).
33
33
  // - Next dev port (HMR mode only): prefer 3210 → 3211 → 3212+.
34
34
  // Skip if any process binds the port.
35
35
  // - Stale `<repo>/.elanous-test/.lock` is an idempotent reuse — the
36
36
  // command refuses with a clear hint unless `--force` is passed.
37
37
 
38
- import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
39
- import { execFileSync } from 'node:child_process';
38
+ import { leaseTestPort } from './port-lease-local.js';
39
+ import { debug } from '../debug/log.js';
40
+ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
41
+ import { createServer } from 'node:net';
40
42
  import { dirname, join as joinPath, resolve as resolvePath } from 'node:path';
41
43
 
42
- import { setTestStateRoot, getTestStateRoot } from '../nexus/paths.js';
44
+ import { setTestStateRoot } from '../nexus/paths.js';
45
+ import { readNexusRuntimeAt } from '../nexus/runtime.js';
46
+ import { isPidAlive } from '../process/pid-liveness.js';
47
+ import { lastMeaningfulLogLine } from './bg-launch.js';
48
+ import { PORT_BANDS } from '../control-plane/ports.js';
49
+ import { PORT_LEASE_TTL_MS } from '../control-plane/port-lease-heartbeat.js';
50
+ import { resolvePrimary, type PrimaryAddress, type PrimaryConfig } from '../control-plane/primary.js';
43
51
  import { runPwaStart, type PwaStartMode, type PwaStartOpts, type PwaStartResult } from './pwa-start.js';
44
52
  import { runPwaStop, type PwaStopOpts, type PwaStopResult } from './pwa-stop.js';
45
- import {
46
- isAliveNexusLock,
47
- readNexusLock,
48
- type NexusLockMeta,
49
- } from '../nexus/supervisor/lock.js';
53
+ import { isAliveNexusLock, type NexusLockMeta } from '../nexus/supervisor/lock.js';
50
54
  import {
51
55
  mountTailscaleServe,
52
56
  unmountTailscaleServe,
@@ -123,13 +127,18 @@ export interface PwaTestOpts {
123
127
  // ─── Test seams ─────────────────────────────────────────────
124
128
  /** Override the repo root resolution from `argvBin`. */
125
129
  repoRoot?: string;
126
- /** Replace the production-daemon lock probe. Defaults to reading
127
- * `~/.elanous/nexus/.lock` via the public helpers. */
128
- productionLockProbeFn?: () => NexusLockMeta | null;
129
- /** Replace the production-daemon liveness check. */
130
+ /** Replace the lock liveness check used for stale project locks. */
130
131
  productionLockAliveFn?: (meta: NexusLockMeta) => boolean;
131
- /** Replace the port collision probe. Defaults to `lsof -ti :<port>`. */
132
- portInUseFn?: (port: number) => boolean;
132
+ /** Replace the port collision probe. Defaults to a local bind probe. */
133
+ portInUseFn?: (port: number) => boolean | Promise<boolean>;
134
+ /** Explicit primary address and scoped write token for coordinator leases. */
135
+ coordinatorPrimary?: PrimaryConfig;
136
+ /** Coordinator request seam; null means coordinator unavailable. A lease must carry its id. */
137
+ leasePortFn?: (excluded?: readonly number[]) => Promise<CoordinatorPortLease | null>;
138
+ /** Release a failed central claim before retrying. */
139
+ releasePortFn?: (port: number) => Promise<void>;
140
+ /** Test seam — lease directory for the local test-band port lease (default: OS tmp). */
141
+ leaseDir?: string;
133
142
  /** Replace the runPwaStart dependency (the underlying daemon + dev
134
143
  * bring-up · we compose this rather than reimplement). */
135
144
  pwaStartFn?: (opts: PwaStartOpts) => Promise<PwaStartResult>;
@@ -165,8 +174,6 @@ export interface PwaTestResult {
165
174
  tailscaleMounted?: boolean;
166
175
  }
167
176
 
168
- const DEFAULT_NEXUS_PORT = 31415;
169
- const NEXUS_FALLBACK_PORTS = [31420, 31421, 31422, 31423, 31424];
170
177
  const DEFAULT_DEV_PORT = 3210;
171
178
  const DEV_FALLBACK_RANGE = [3211, 3212, 3213, 3214, 3215];
172
179
 
@@ -209,18 +216,12 @@ function resolveLayout(opts: PwaTestOpts): RepoLayout | null {
209
216
  };
210
217
  }
211
218
 
212
- function defaultPortInUse(port: number): boolean {
213
- try {
214
- // `lsof -ti :<port>` exits 0 + prints PIDs when something is
215
- // listening; exits 1 with empty stdout when free.
216
- const stdout = execFileSync('lsof', ['-ti', `:${port}`, '-sTCP:LISTEN'], {
217
- stdio: ['ignore', 'pipe', 'ignore'],
218
- timeout: 3000,
219
- });
220
- return String(stdout).trim().length > 0;
221
- } catch {
222
- return false;
223
- }
219
+ async function defaultPortInUse(port: number): Promise<boolean> {
220
+ return new Promise(resolve => {
221
+ const server = createServer();
222
+ server.once('error', () => resolve(true));
223
+ server.listen(port, '0.0.0.0', () => server.close(() => resolve(false)));
224
+ });
224
225
  }
225
226
 
226
227
  function readProjectLock(lockPath: string): NexusLockMeta | null {
@@ -236,81 +237,134 @@ function readProjectLock(lockPath: string): NexusLockMeta | null {
236
237
  }
237
238
  }
238
239
 
239
- function pickNexusPort(
240
+ async function coordinatorPortRequest(path: string, method: string, body?: unknown, primary?: PrimaryAddress): Promise<Response | null> {
241
+ primary ??= await resolvePrimary({ role: 'member' });
242
+ if (!primary.token) return null;
243
+ try {
244
+ return await fetch(`${primary.url}${path}`, {
245
+ method,
246
+ headers: { Authorization: `Bearer ${primary.token}`, ...(body !== undefined ? { 'content-type': 'application/json' } : {}) },
247
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
248
+ signal: AbortSignal.timeout(1000),
249
+ });
250
+ } catch { return null; }
251
+ }
252
+
253
+ export type CoordinatorPortLease = { port: number; leaseId: string };
254
+
255
+ export async function requestCoordinatorPort(
256
+ excluded: readonly number[] = [],
257
+ send: typeof coordinatorPortRequest = coordinatorPortRequest,
258
+ ): Promise<CoordinatorPortLease | null> {
259
+ return requestCoordinatorPortForPrimary(excluded, await resolvePrimary({ role: 'member' }), send);
260
+ }
261
+
262
+ async function requestCoordinatorPortForPrimary(
263
+ excluded: readonly number[], primary: PrimaryAddress, send: typeof coordinatorPortRequest = coordinatorPortRequest,
264
+ ): Promise<CoordinatorPortLease | null> {
265
+ const response = await send('/v1/leases/port', 'POST', {
266
+ machine: primary.machine ?? (process.env.HOSTNAME || 'local'), purpose: 'nexus-test', ttlMs: PORT_LEASE_TTL_MS, excluded,
267
+ }, primary);
268
+ if (!response) return null;
269
+ if (response.status === 409) {
270
+ const body: unknown = await response.json();
271
+ if ((body as { error?: unknown })?.error === 'no-port') return null;
272
+ }
273
+ if (!response.ok) throw new Error(`coordinator port lease HTTP ${response.status}`);
274
+ const body: unknown = await response.json();
275
+ const port = (body as { port?: unknown })?.port;
276
+ const leaseId = (body as { lease?: { attrs?: { leaseId?: unknown } } })?.lease?.attrs?.leaseId;
277
+ if (typeof port !== 'number' || !Number.isInteger(port) || port < PORT_BANDS.test.start || port > PORT_BANDS.test.end ||
278
+ typeof leaseId !== 'string' || !leaseId) {
279
+ throw new Error('invalid coordinator port lease');
280
+ }
281
+ return { port, leaseId };
282
+ }
283
+
284
+ async function releaseCoordinatorPort(lease: CoordinatorPortLease, primary?: PrimaryAddress): Promise<void> {
285
+ primary ??= await resolvePrimary({ role: 'member' });
286
+ if (!primary.token) return;
287
+ const response = await fetch(`${primary.url}/v1/leases/port/${lease.port}`, {
288
+ method: 'DELETE', headers: { Authorization: `Bearer ${primary.token}`, 'x-port-lease-id': lease.leaseId },
289
+ signal: AbortSignal.timeout(1000),
290
+ }).catch(() => null);
291
+ if (!response?.ok && response?.status !== 404 && response?.status !== 403) throw new Error(`coordinator port release ${response ? `HTTP ${response.status}` : 'unavailable'}`);
292
+ }
293
+
294
+ async function pickNexusPort(
240
295
  preferred: number | undefined,
241
296
  layout: RepoLayout,
242
297
  opts: PwaTestOpts,
243
- ): { port: number; reason: string } | { error: string } {
298
+ ): Promise<{ port: number; reason: string; leaseId?: string; primary?: PrimaryAddress } | { error: string }> {
244
299
  const inUseFn = opts.portInUseFn ?? defaultPortInUse;
245
- const productionProbeFn =
246
- opts.productionLockProbeFn ?? readNexusLock;
247
- const productionAliveFn = opts.productionLockAliveFn ?? isAliveNexusLock;
248
-
300
+ // ⓐ 명시 `--port` 가 이긴다(불변).
249
301
  if (preferred !== undefined) {
250
- if (inUseFn(preferred)) {
251
- return { error: `port ${preferred} already in use (lsof match)` };
252
- }
302
+ if (await inUseFn(preferred)) return { error: `port ${preferred} already in use` };
253
303
  return { port: preferred, reason: 'explicit --port' };
254
304
  }
305
+ // ⓑ 관제부 임대 — 없거나(null) «어떤 오류든»(409 no-port · 503 · 네트워크 · 잘못된 응답) ⓒ 로 넘어간다.
306
+ const central = await pickCoordinatorPort(opts, inUseFn);
307
+ if (central) return central;
308
+ // ⓒ 기계 안 로컬 임대(#20864) — 시험 대역(31450~31499)에서만 준다. 운영 대역(31413·31415·31420)은 절대 안 고른다.
309
+ const claim = await leaseTestPort({
310
+ owner: layout.repoRoot,
311
+ ...(opts.leaseDir ? { dir: opts.leaseDir } : {}),
312
+ ...(opts.portInUseFn ? { inUse: opts.portInUseFn } : {}),
313
+ });
314
+ if ('error' in claim) return { error: '시험 대역에 빈 포트가 없습니다 (31450..31499)' };
315
+ return { port: claim.port, reason: `시험 대역에서 :${claim.port} 임대` };
316
+ }
255
317
 
256
- // Default: 31415. Production daemon (`~/.elanous/nexus/.lock`) takes
257
- // precedence — we never want to clobber the user's primary daemon.
258
- const candidates = [DEFAULT_NEXUS_PORT, ...NEXUS_FALLBACK_PORTS];
259
-
260
- // Production probe must read `~/.elanous/nexus/.lock`, not our test
261
- // lock. Temporarily clear any in-process test state override so
262
- // `readNexusLock` falls through to the default config-dir path.
263
- // (Same-process re-entry only — fresh `elanous` invocations start
264
- // with testStateRoot=undefined automatically.)
265
- const savedTestStateRoot = getTestStateRoot();
266
- setTestStateRoot(null);
267
- let prodLock: NexusLockMeta | null = null;
268
- try { prodLock = productionProbeFn(); } catch { /* swallow */ }
269
- finally {
270
- if (savedTestStateRoot !== undefined) setTestStateRoot(savedTestStateRoot);
271
- }
272
- const productionAlive = prodLock && productionAliveFn(prodLock);
273
-
274
- // Project test lock — distinct path; reuse when alive (idempotent
275
- // start = informative status), force-take when --force.
276
- const projectLock = readProjectLock(layout.lockPath);
318
+ async function releaseCentral(opts: PwaTestOpts, lease: CoordinatorPortLease, primary?: PrimaryAddress): Promise<void> {
319
+ if (opts.releasePortFn) await opts.releasePortFn(lease.port);
320
+ else await releaseCoordinatorPort(lease, primary);
321
+ }
277
322
 
278
- for (const port of candidates) {
279
- if (port === DEFAULT_NEXUS_PORT && productionAlive) continue;
280
- if (inUseFn(port)) {
281
- // The test lock might describe THIS port — if so, it's our own
282
- // prior instance and the orchestrator's flow handles that
283
- // separately (errors with reuse/force hint at the entry point).
284
- if (
285
- projectLock
286
- && projectLock.pid !== prodLock?.pid
287
- && opts.force !== true
288
- ) {
289
- // We can't tell which port the prior test was on without
290
- // reading runtime.json — leave that to the entry point.
291
- // Continue to next candidate so a second port lookup keeps
292
- // working when the prior is stale.
293
- }
294
- continue;
323
+ /** 관제부에서 시험 대역 포트를 받는다. 받지 못하면(관제부 부재·오류·잘못된 응답·대역 소진) null — 호출자가 로컬 임대로 넘어간다. */
324
+ async function pickCoordinatorPort(
325
+ opts: PwaTestOpts,
326
+ inUseFn: (port: number) => boolean | Promise<boolean>,
327
+ ): Promise<{ port: number; reason: string; leaseId: string; primary?: PrimaryAddress } | null> {
328
+ const primary = opts.leasePortFn ? undefined : await resolvePrimary({ role: 'member', config: opts.coordinatorPrimary });
329
+ const request = opts.leasePortFn ?? ((excluded: readonly number[]) => requestCoordinatorPortForPrimary(excluded, primary!));
330
+ const excluded: number[] = [];
331
+ for (let attempt = PORT_BANDS.test.start; attempt <= PORT_BANDS.test.end; attempt++) {
332
+ let claimed: CoordinatorPortLease | null;
333
+ try { claimed = await request(excluded); }
334
+ catch (err) {
335
+ debug.log('nexus.port-lease', 'coordinator-fallback', { reason: 'coordinator-error', error: err instanceof Error ? err.message : String(err) });
336
+ return null;
295
337
  }
296
- return {
297
- port,
298
- reason:
299
- port === DEFAULT_NEXUS_PORT
300
- ? 'default :31415 free'
301
- : productionAlive
302
- ? `:31415 taken by production daemon (pid ${prodLock!.pid}) → fallback`
303
- : 'collision · auto-pick',
304
- };
338
+ if (claimed === null) {
339
+ debug.log('nexus.port-lease', 'coordinator-fallback', { reason: 'coordinator-unavailable-or-no-port' });
340
+ return null;
341
+ }
342
+ const { port, leaseId } = claimed;
343
+ if (!Number.isInteger(port) || port < PORT_BANDS.test.start || port > PORT_BANDS.test.end
344
+ || (PORT_BANDS.reserved as readonly number[]).includes(port) || excluded.includes(port)
345
+ || typeof leaseId !== 'string' || !leaseId) {
346
+ debug.log('nexus.port-lease', 'coordinator-fallback', { reason: 'invalid-lease', port });
347
+ return null;
348
+ }
349
+ let occupied: boolean;
350
+ try { occupied = await inUseFn(port); }
351
+ catch (err) {
352
+ await releaseCentral(opts, claimed, primary);
353
+ throw err;
354
+ }
355
+ if (!occupied) return { port, reason: 'coordinator lease', leaseId, ...(primary ? { primary } : {}) };
356
+ await releaseCentral(opts, claimed, primary);
357
+ excluded.push(port);
305
358
  }
306
- return { error: `no free port in [${candidates.join(', ')}]` };
359
+ debug.log('nexus.port-lease', 'coordinator-fallback', { reason: 'coordinator-band-exhausted' });
360
+ return null;
307
361
  }
308
362
 
309
- function pickDevPort(opts: PwaTestOpts): number | { error: string } {
363
+ async function pickDevPort(opts: PwaTestOpts): Promise<number | { error: string }> {
310
364
  const inUseFn = opts.portInUseFn ?? defaultPortInUse;
311
365
  const candidates = [DEFAULT_DEV_PORT, ...DEV_FALLBACK_RANGE];
312
366
  for (const port of candidates) {
313
- if (!inUseFn(port)) return port;
367
+ if (!await inUseFn(port)) return port;
314
368
  }
315
369
  return { error: `no free Next dev port in [${candidates.join(', ')}]` };
316
370
  }
@@ -436,18 +490,37 @@ async function runStart(
436
490
  }
437
491
  }
438
492
 
439
- const nexusPick = pickNexusPort(opts.port, layout, opts);
493
+ let nexusPick: Awaited<ReturnType<typeof pickNexusPort>>;
494
+ try { nexusPick = await pickNexusPort(opts.port, layout, opts); }
495
+ catch (err) {
496
+ out.error(`✗ coordinator port lease failed: ${err instanceof Error ? err.message : String(err)}`);
497
+ return { exitCode: 1 };
498
+ }
440
499
  if ('error' in nexusPick) {
441
500
  out.error(`✗ ${nexusPick.error}`);
442
501
  return { exitCode: 1 };
443
502
  }
444
503
  const nexusPort = nexusPick.port;
504
+ const coordinatorPrimary = 'primary' in nexusPick ? nexusPick.primary : undefined;
505
+ const coordinatorToken = coordinatorPrimary?.token;
506
+ const releasePickedLease = async (): Promise<void> => {
507
+ if (nexusPick.reason === 'coordinator lease') {
508
+ if (opts.releasePortFn) await opts.releasePortFn(nexusPort);
509
+ else if (nexusPick.leaseId) await releaseCoordinatorPort({ port: nexusPort, leaseId: nexusPick.leaseId }, coordinatorPrimary);
510
+ }
511
+ };
445
512
 
446
513
  let devPort: number | undefined;
447
514
  if (isHmr) {
448
- const devPick = pickDevPort(opts);
515
+ let devPick: Awaited<ReturnType<typeof pickDevPort>>;
516
+ try { devPick = await pickDevPort(opts); }
517
+ catch (error) {
518
+ await releasePickedLease();
519
+ throw error;
520
+ }
449
521
  if (typeof devPick !== 'number') {
450
522
  out.error(`✗ ${devPick.error}`);
523
+ await releasePickedLease();
451
524
  return { exitCode: 1 };
452
525
  }
453
526
  devPort = devPick;
@@ -477,6 +550,7 @@ async function runStart(
477
550
  }
478
551
  } catch (e) {
479
552
  out.error(`✗ config 격리 실패: ${e instanceof Error ? e.message : String(e)} — 운영 오염 위험이라 기동 중단`);
553
+ await releasePickedLease();
480
554
  return { exitCode: 1 };
481
555
  }
482
556
 
@@ -494,6 +568,7 @@ async function runStart(
494
568
  mode,
495
569
  httpHost,
496
570
  httpPort: nexusPort,
571
+ ...(nexusPick.reason === 'coordinator lease' ? { coordinatorLeasePort: nexusPort, ...(coordinatorToken ? { coordinatorLeaseToken: coordinatorToken } : {}), ...(nexusPick.leaseId ? { coordinatorLeaseId: nexusPick.leaseId } : {}) } : {}),
497
572
  out,
498
573
  ...(opts.force ? { force: true } : {}),
499
574
  ...(opts.toolCwd !== undefined ? { toolCwd: opts.toolCwd } : {}),
@@ -512,8 +587,16 @@ async function runStart(
512
587
  // tailscale-serve.ts (TLS-tcp mode · WS-friendly).
513
588
  readShareSwitchFn: () => 'disabled',
514
589
  };
515
- const startRes = await pwaStartFn(startOpts);
516
- if (startRes.exitCode !== 0) return { exitCode: startRes.exitCode };
590
+ let startRes: PwaStartResult;
591
+ try { startRes = await pwaStartFn(startOpts); }
592
+ catch (err) {
593
+ await releasePickedLease();
594
+ throw err;
595
+ }
596
+ if (startRes.exitCode !== 0) {
597
+ await releasePickedLease();
598
+ return { exitCode: startRes.exitCode };
599
+ }
517
600
 
518
601
  let url: string | undefined;
519
602
  let tailscaleMounted = false;
@@ -674,11 +757,33 @@ function runStatus(
674
757
  if (parsed.url) out.log(` url ${parsed.url}`);
675
758
  out.log(` started ${parsed.startedAt ?? '(unknown)'}`);
676
759
 
760
+ // The daemon writes under nexus/ after setTestStateRoot(stateDir); also read
761
+ // the project-root sidecar when that daemon path does not exist.
762
+ const daemonRuntimePath = joinPath(layout.stateDir, 'nexus', 'runtime.json');
763
+ const runtime = readNexusRuntimeAt(existsSync(daemonRuntimePath) ? daemonRuntimePath : layout.runtimePath);
764
+ const pid = runtime?.pid;
765
+ const alive = pid !== undefined && isPidAlive(pid);
766
+ debug.log('nexus.test-status', 'liveness', { pid, alive });
767
+ out.log(pid === undefined ? ' alive unknown — runtime.json 에 pid 없음'
768
+ : alive ? ` alive yes (pid ${pid})` : ` alive NO — pid ${pid} 없음`);
769
+
677
770
  const tsState = readMountedState(layout.tailscaleStatePath);
678
771
  if (tsState && tsState.mode.kind === 'tls-tcp') {
679
772
  out.log(` tailscale port=${tsState.mode.port} hostname=${tsState.hostname ?? '?'}`);
680
773
  }
681
- return { exitCode: 0 };
774
+ if (!alive) {
775
+ // bg-launch names its detached logs nexus-<Date.now()>.log in this test root.
776
+ const logsDir = joinPath(layout.stateDir, 'nexus', 'logs');
777
+ try {
778
+ const logName = readdirSync(logsDir).filter(name => /^nexus-\d+\.log$/.test(name)).sort().at(-1);
779
+ if (logName) {
780
+ const lastLine = lastMeaningfulLogLine(joinPath(logsDir, logName));
781
+ if (lastLine) out.log(` last log ${lastLine}`);
782
+ }
783
+ } catch { /* log is optional when the daemon died before creating it */ }
784
+ out.log(' fix elanous nexus run --test --stop 으로 기록을 치운 뒤 다시 띄운다');
785
+ }
786
+ return { exitCode: alive ? 0 : 1 };
682
787
  } catch (err) {
683
788
  out.error(`elanous nexus run --test --status: state file unreadable — ${(err as Error).message}`);
684
789
  return { exitCode: 1 };
@@ -2,6 +2,7 @@
2
2
  //
3
3
  // elanous release prepare --version <x.y.z[-rc.N]> [--source <ref>] [--out <dir>] [--notes-from <ref>] [--skip-e2e]
4
4
  // elanous release publish --dir <prepare 산출> --notes-file <본문> [--yes]
5
+ // elanous release tag --version <x.y.z> --source <commit> [--yes]
5
6
  // elanous release verify [--version <x.y.z>]
6
7
  // elanous release notes --from <ref> [--to <ref>]
7
8
  //
@@ -12,11 +13,13 @@
12
13
  // ⛔ 공개본은 «원본 매니페스트»(`release/public-export.yaml`)대로만 만든다 — 매매 실행 코드는 그 매니페스트가 이미 뺀다(🅢 #20529).
13
14
  import { spawnSync } from 'node:child_process';
14
15
  import { createHash } from 'node:crypto';
15
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
16
+ import { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
16
17
  import { tmpdir } from 'node:os';
17
18
  import { dirname, join, resolve } from 'node:path';
18
19
  import type { Command } from 'commander';
19
20
  import { debug } from '../debug/log.js';
21
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
22
+ import { envLiteral } from '../platform/env-literal.js';
20
23
 
21
24
  export const DEFAULT_PUBLIC_REPO = 'ElanvitalAI/elanous';
22
25
  const SEMVER = /^\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\.\d+)?$/;
@@ -207,7 +210,54 @@ export function readManifest(dir: string): ReleaseManifest {
207
210
  return JSON.parse(readFileSync(join(resolve(dir), 'release.json'), 'utf8')) as ReleaseManifest;
208
211
  }
209
212
 
210
- export async function publishRelease(opts: { dir: string; notesFile: string; yes?: boolean; log?: (l: string) => void }, run: Runner = defaultRunner): Promise<{ published: boolean; steps: PublishStep[] }> {
213
+ const COMMIT_SHA = /^[0-9a-f]{40}$/i;
214
+
215
+ export interface TagOptions { version: string; source: string; yes?: boolean; repoRoot?: string; log?: (line: string) => void }
216
+
217
+ /** 로컬과 origin 의 태그를 모두 대조한다. 주석 태그는 반드시 peel 해서 원본 커밋을 비교한다. */
218
+ function checkSourceTag(version: string, source: string, repoRoot: string, run: Runner): { tag: string; commit: string; local: boolean; remote: boolean } {
219
+ if (!isReleaseVersion(version)) throw new Error(`버전 모양이 아니다: ${version}`);
220
+ if (!COMMIT_SHA.test(source)) throw new Error(`원본 커밋 SHA가 아니다: ${source}`);
221
+ const tag = `v${version}`;
222
+ const commit = must(run('git', ['rev-parse', '--verify', `${source}^{commit}`], repoRoot), '원본 커밋 확인');
223
+ if (commit !== source.toLowerCase()) throw new Error(`원본 커밋 불일치: ${source} ≠ ${commit}`);
224
+ const localRef = `refs/tags/${tag}`;
225
+ // `--quiet` 없이 없는 ref 를 물으면 git 은 1 이 아니라 128 을 낸다(📏 2026-09-27 · 0.2.2 소급 태깅이 여기서 멈췄다).
226
+ const local = run('git', ['show-ref', '--verify', '--quiet', localRef], repoRoot);
227
+ if (local.status !== 0 && local.status !== 1) must(local, `로컬 태그 ${tag} 조회`);
228
+ if (local.status === 0) {
229
+ const target = must(run('git', ['rev-parse', '--verify', `${localRef}^{commit}`], repoRoot), `로컬 태그 ${tag} 확인`);
230
+ if (target !== commit) throw new Error(`태그 충돌: ${tag} 로컬 ${target} ≠ 원본 ${commit} — 덮지 않는다`);
231
+ }
232
+ const remote = must(run('git', ['ls-remote', '--tags', 'origin', localRef, `${localRef}^{}`], repoRoot), `origin 태그 ${tag} 조회`);
233
+ const refs = new Map(remote.split('\n').filter(Boolean).map((line) => {
234
+ const [hash, ref] = line.split(/\s+/);
235
+ return [ref, hash];
236
+ }));
237
+ const target = refs.get(`${localRef}^{}`) ?? refs.get(localRef);
238
+ if (target && target !== commit) throw new Error(`태그 충돌: ${tag} origin ${target} ≠ 원본 ${commit} — 덮지 않는다`);
239
+ return { tag, commit, local: local.status === 0, remote: Boolean(target) };
240
+ }
241
+
242
+ function applySourceTag(version: string, source: string, repoRoot: string, run: Runner): void {
243
+ const state = checkSourceTag(version, source, repoRoot, run);
244
+ if (!state.local) must(run('git', ['tag', '-a', state.tag, state.commit, '-m', `elanous ${state.tag}`], repoRoot), `내부 태그 ${state.tag} 생성`);
245
+ if (!state.remote) must(run('git', ['push', 'origin', `refs/tags/${state.tag}:refs/tags/${state.tag}`], repoRoot), `내부 태그 ${state.tag} push`);
246
+ debug.log('release.publish', 'tagged', { version, commit: state.commit });
247
+ }
248
+
249
+ /** 이미 발행한 판의 내부 기준점을 소급 태깅한다. --yes 없으면 저장소를 읽거나 쓰지 않는다. */
250
+ export async function tagRelease(opts: TagOptions, run: Runner = defaultRunner): Promise<{ tagged: boolean }> {
251
+ const log = opts.log ?? ((line: string) => console.log(line));
252
+ if (!isReleaseVersion(opts.version)) throw new Error(`버전 모양이 아니다: ${opts.version}`);
253
+ if (!COMMIT_SHA.test(opts.source)) throw new Error(`원본 커밋 SHA가 아니다: ${opts.source}`);
254
+ log(`${opts.yes ? '▶' : '·'} 내부 태그 v${opts.version} → ${opts.source} (origin push${opts.yes ? '' : ' 예정'})`);
255
+ if (!opts.yes) return { tagged: false };
256
+ applySourceTag(opts.version, opts.source, resolve(opts.repoRoot ?? join(import.meta.dir, '..', '..')), run);
257
+ return { tagged: true };
258
+ }
259
+
260
+ export async function publishRelease(opts: { dir: string; notesFile: string; yes?: boolean; repoRoot?: string; instanceRoot?: string; log?: (l: string) => void }, run: Runner = defaultRunner): Promise<{ published: boolean; steps: PublishStep[] }> {
211
261
  const log = opts.log ?? ((l: string) => console.log(l));
212
262
  const m = readManifest(opts.dir);
213
263
  if (!existsSync(opts.notesFile)) throw new Error(`릴리스 본문 파일이 없다: ${opts.notesFile} (초안: ${m.notesDraft ?? 'release notes --from <ref>'})`);
@@ -219,7 +269,15 @@ export async function publishRelease(opts: { dir: string; notesFile: string; yes
219
269
  const steps = planPublish(m, resolve(opts.notesFile));
220
270
  for (const s of steps) log(`${opts.yes ? '▶' : '·'} ${s.what}\n ${s.command} ${s.args.join(' ')}`);
221
271
  if (!opts.yes) { log('⛔ 보기만 했다 — 공개는 되돌릴 수 없다. 실행하려면 --yes'); return { published: false, steps }; }
272
+ const repoRoot = resolve(opts.repoRoot ?? join(import.meta.dir, '..', '..'));
273
+ checkSourceTag(m.version, m.sourceCommit, repoRoot, run);
222
274
  for (const s of steps) must(run(s.command, s.args, s.cwd), s.what);
275
+ applySourceTag(m.version, m.sourceCommit, repoRoot, run);
276
+ const recordDir = join(opts.instanceRoot ?? effectiveInstanceRoot(), 'release', m.version);
277
+ mkdirSync(recordDir, { recursive: true });
278
+ const record = join(recordDir, 'release.json');
279
+ writeFileSync(record, `${JSON.stringify({ ...m, publishedAt: new Date().toISOString() }, null, 2)}\n`, { mode: 0o600 });
280
+ chmodSync(record, 0o600);
223
281
  log(`✅ 공개: https://github.com/${m.publicRepo}/releases/tag/${m.tag} — 이어서 \`elanous release verify --version ${m.version}\``);
224
282
  return { published: true, steps };
225
283
  }
@@ -317,7 +375,23 @@ export function stateRoundTrip(elanous: string, home: string, env: NodeJS.Proces
317
375
  return { memory, logs: /"registeredStores":0\b/.test(`${read.stdout}${read.stderr}`) ? 'no-store' : 'fail' };
318
376
  }
319
377
 
320
- export async function verifyRelease(opts: { version?: string; publicRepo?: string; log?: (l: string) => void }, run: Runner = defaultRunner): Promise<{ ok: boolean; versionLine: string; installerUrl: string; steps?: { install: number | null; selfUpdate: number | null; uninstall: number | null }; state?: { memory: boolean; logs: LogRoundTrip } }> {
378
+ /** 공개 판의 노트가 문서 사이트에 있나 — 🅕 제보(09-27): 0.2.2 노트가 GitHub 릴리스에만 있고 docs 에 없었다(#21137 이 뒤에 옮김).
379
+ * `publish` 는 아무 경로의 본문 파일을 받으므로 원본(`release/public/내부 문서 `<판>``)·사이트 배포를 빼먹어도 모른다 ⇒ verify 가 사이트를 잰다.
380
+ * 정식 판만(`-rc.N` 같은 선행 판은 노트 페이지를 두지 않는다). */
381
+ export const DOCS_SITE = 'https://docs.elanous.ai';
382
+ export function releaseNotesPageUrl(version: string): string | null {
383
+ if (version.includes('-')) return null;
384
+ return `${DOCS_SITE}/releases/${version.replace(/\./g, '-')}/`;
385
+ }
386
+ export type NotesPage = 'ok' | 'missing' | 'not-required';
387
+ export function checkReleaseNotesPage(version: string | undefined, run: Runner, cwd: string): { notesPage: NotesPage; url: string | null } {
388
+ const url = version ? releaseNotesPageUrl(version) : null;
389
+ if (!url) return { notesPage: 'not-required', url };
390
+ const r = run('curl', ['-sL', '-o', '/dev/null', '-w', '%{http_code}', url], cwd);
391
+ return { notesPage: r.status === 0 && r.stdout.trim() === '200' ? 'ok' : 'missing', url };
392
+ }
393
+
394
+ export async function verifyRelease(opts: { version?: string; publicRepo?: string; log?: (l: string) => void }, run: Runner = defaultRunner): Promise<{ ok: boolean; versionLine: string; installerUrl: string; steps?: { install: number | null; selfUpdate: number | null; uninstall: number | null }; state?: { memory: boolean; logs: LogRoundTrip }; notesPage?: NotesPage }> {
321
395
  const log = opts.log ?? ((l: string) => console.log(l));
322
396
  if (opts.version !== undefined && !isReleaseVersion(opts.version)) throw new Error(`버전 모양이 아니다: ${opts.version}`);
323
397
  const repo = opts.publicRepo ?? DEFAULT_PUBLIC_REPO;
@@ -330,7 +404,7 @@ export async function verifyRelease(opts: { version?: string; publicRepo?: strin
330
404
  mkdirSync(home);
331
405
  // 검증은 «빈 HOME» 에서만 쓴다 — 물려받은 ELANOUS_*(STATE_DIR 등)·XDG_* 가 있으면 상태 왕복이 운영 저장소에 쓴다.
332
406
  const inherited = Object.fromEntries(Object.entries(process.env).filter(([key]) => !key.startsWith('ELANOUS_') && !key.startsWith('XDG_')));
333
- const env: NodeJS.ProcessEnv = { ...inherited, HOME: home, ELANOUS_INSTALL_PREFIX: prefix, ELANOUS_INSTALL_SOURCE: '', ELANOUS_VERSION: opts.version ?? '', SHELL: '/bin/zsh' };
407
+ const env = envLiteral({ ...inherited, HOME: home, ELANOUS_INSTALL_PREFIX: prefix, ELANOUS_INSTALL_SOURCE: '', ELANOUS_VERSION: opts.version ?? '', SHELL: '/bin/zsh' });
334
408
  const script = must(run('curl', ['-fsSL', installerUrl], home), `설치기 받기 ${installerUrl}`);
335
409
  const install = run('bash', ['-s', '--', '--no-modify-path'], home, { env, input: script });
336
410
  const versionLine = run(join(prefix, 'bin', 'elanous'), ['--version'], home, { env }).stdout.trim();
@@ -339,9 +413,10 @@ export async function verifyRelease(opts: { version?: string; publicRepo?: strin
339
413
  const uninstall = existsSync(join(prefix, 'current', 'node_modules', 'elanous', 'scripts', 'uninstall.sh'))
340
414
  ? run('bash', [join(prefix, 'current', 'node_modules', 'elanous', 'scripts', 'uninstall.sh')], home, { env })
341
415
  : { status: null, stdout: '', stderr: 'uninstall.sh 없음' };
342
- const ok = install.status === 0 && (opts.version ? versionLine.startsWith(`${opts.version} `) : versionLine.length > 0) && update.status === 0 && state.memory && state.logs !== 'fail';
343
- log(`${ok ? '✅' : '⛔'} ${installerUrl}\n 설치 rc=${install.status} · --version «${versionLine}» · 기억 왕복 ${state.memory ? 'ok' : 'FAIL'} · 로그 왕복 ${state.logs === 'ok' ? 'ok' : state.logs === 'fail' ? 'FAIL' : '안 잼(스토어 없음 — 데몬이 한 번 떠야 생긴다)'} · self-update rc=${update.status} · 제거 rc=${uninstall.status}`);
344
- return { ok, versionLine, installerUrl, steps: { install: install.status, selfUpdate: update.status, uninstall: uninstall.status }, state };
416
+ const notes = checkReleaseNotesPage(opts.version, run, home);
417
+ const ok = install.status === 0 && (opts.version ? versionLine.startsWith(`${opts.version} `) : versionLine.length > 0) && update.status === 0 && state.memory && state.logs !== 'fail' && notes.notesPage !== 'missing';
418
+ log(`${ok ? '✅' : '⛔'} ${installerUrl}\n 설치 rc=${install.status} · --version «${versionLine}» · 기억 왕복 ${state.memory ? 'ok' : 'FAIL'} · 로그 왕복 ${state.logs === 'ok' ? 'ok' : state.logs === 'fail' ? 'FAIL' : '안 잼(스토어 없음 — 데몬이 한 번 떠야 생긴다)'} · self-update rc=${update.status} · 제거 rc=${uninstall.status} · 노트 페이지 ${notes.notesPage === 'ok' ? 'ok' : notes.notesPage === 'missing' ? `없음 — release/public/docs/releases/${opts.version}.md ⊕ website/pages.json ⊕ \`bun website/scripts/deploy-pages.ts\` (${notes.url})` : '해당 없음'}`);
419
+ return { ok, versionLine, installerUrl, steps: { install: install.status, selfUpdate: update.status, uninstall: uninstall.status }, state, notesPage: notes.notesPage };
345
420
  } finally {
346
421
  rmSync(root, { recursive: true, force: true });
347
422
  }
@@ -398,6 +473,14 @@ export function registerReleaseCommands(program: Command): void {
398
473
  return { ...r, tag: m.tag, publicRepo: m.publicRepo, publicCommit: m.publicCommit, assets: [...new Set([...m.files.map((f) => f.name), 'SHA256SUMS'])].map((name) => join(m.distDir, name)) };
399
474
  }, () => true);
400
475
  });
476
+ release.command('tag')
477
+ .description('이미 발행된 판의 내부 원본 커밋에 주석 태그를 달고 origin 에 push. --yes 없으면 계획만')
478
+ .requiredOption('--version <x.y.z>', '이미 발행된 판')
479
+ .requiredOption('--source <commit>', '내부 원본 커밋 SHA')
480
+ .option('--yes', '태그를 실제로 만든다')
481
+ .action(async (o: { version: string; source: string; yes?: boolean }) => {
482
+ await jsonAction(undefined, (log) => tagRelease({ ...o, log }), () => true);
483
+ });
401
484
  release.command('verify')
402
485
  .description('공개 주소로 끝까지 — 깨끗한 임시 홈에서 설치 → --version → self-update → 제거')
403
486
  .option('--version <x.y.z>', '고정 버전(없으면 latest)')
@@ -5,6 +5,8 @@
5
5
  // tested without re-running the CLI via Bun.spawn.
6
6
 
7
7
  import { existsSync, readFileSync } from 'node:fs';
8
+ import { defaultAcpTokenPath } from '../nexus/api/connect-info.js';
9
+ import { DEFAULT_NEXUS_HTTP_PORT } from '../nexus/default-port.js';
8
10
  import {
9
11
  RemotesStore,
10
12
  deriveNameFromHost,
@@ -12,6 +14,9 @@ import {
12
14
  type RemoteEntry,
13
15
  } from './remotes.js';
14
16
 
17
+ /** 이 기계를 가리키는 주소 — 토큰 파일을 직접 읽어도 되는 경우(같은 uid). */
18
+ const LOOPBACK_BOOTSTRAP_HOSTS = new Set(['127.0.0.1', 'localhost', '::1', '[::1]']);
19
+
15
20
  export interface ConnectRemoteOpts {
16
21
  host: string;
17
22
  name?: string;
@@ -24,6 +29,8 @@ export interface ConnectRemoteOpts {
24
29
  ping?: boolean;
25
30
  /** Test seam — fetch override. */
26
31
  fetchImpl?: typeof fetch;
32
+ /** Test seam — same-host token file (default `~/.elanous/acp-token`). */
33
+ localTokenPath?: string;
27
34
  /** Test seam — store override (alternate paths). */
28
35
  store?: RemotesStore;
29
36
  /** Stdout sink (test). */
@@ -45,7 +52,7 @@ export async function connectRemote(opts: ConnectRemoteOpts): Promise<number> {
45
52
  const store = opts.store ?? new RemotesStore();
46
53
  let parsed: ReturnType<typeof normalizeHost>;
47
54
  try {
48
- parsed = normalizeHost(opts.host, opts.port ?? 31415);
55
+ parsed = normalizeHost(opts.host, opts.port ?? DEFAULT_NEXUS_HTTP_PORT);
49
56
  } catch (err) {
50
57
  out.error(`elanous nexus connect: ${(err as Error).message}`);
51
58
  return 1;
@@ -95,9 +102,21 @@ export async function connectRemote(opts: ConnectRemoteOpts): Promise<number> {
95
102
  token = readFileSync(opts.tokenFile, 'utf-8').trim();
96
103
  }
97
104
  if (!token && autoToken) {
105
+ // 옛 서버(원문을 싣던 판)와의 호환 — 새 서버는 늘 null 이다.
98
106
  token = autoToken;
99
107
  out.log(`auto_token loaded from ${parsed.host} (loopback bootstrap).`);
100
108
  }
109
+ if (!token && LOOPBACK_BOOTSTRAP_HOSTS.has(parsed.host)) {
110
+ // 🔐 같은 기계 · 같은 uid — 서버에게 원문을 받지 않고 토큰 파일을 직접 읽는다.
111
+ const localTokenPath = opts.localTokenPath ?? defaultAcpTokenPath();
112
+ if (existsSync(localTokenPath)) {
113
+ const local = readFileSync(localTokenPath, 'utf-8').trim();
114
+ if (local) {
115
+ token = local;
116
+ out.log(`token loaded from ${localTokenPath} (same-host bootstrap).`);
117
+ }
118
+ }
119
+ }
101
120
  if (!token) {
102
121
  out.error(
103
122
  'token required. Pass --token <value> or --token-file <path>. ' +
@@ -18,6 +18,7 @@
18
18
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, chmodSync, unlinkSync } from 'node:fs';
19
19
  import { join as joinPath, dirname } from 'node:path';
20
20
  import { getElanousConfigDir } from '../elanous-config-dir.js';
21
+ import { DEFAULT_NEXUS_HTTP_PORT } from '../nexus/default-port.js';
21
22
 
22
23
  export const REMOTES_FILE_VERSION = 1;
23
24
 
@@ -212,7 +213,7 @@ export function deriveNameFromHost(host: string): string {
212
213
 
213
214
  /** Parse a host/URL spec the user passed: `mbp.tailnet`, `mbp.tailnet:31415`,
214
215
  * or `http://mbp.tailnet:31415`. Returns base URL (no trailing slash). */
215
- export function normalizeHost(spec: string, defaultPort = 31415): { url: string; host: string; port: number } {
216
+ export function normalizeHost(spec: string, defaultPort = DEFAULT_NEXUS_HTTP_PORT): { url: string; host: string; port: number } {
216
217
  let raw = spec.trim();
217
218
  if (raw.length === 0) throw new Error('host required');
218
219
  if (!/^https?:\/\//.test(raw)) raw = `http://${raw}`;