elanous 0.2.0 → 0.2.5

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 (1249) hide show
  1. package/.env.example +6 -0
  2. package/README.md +17 -15
  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/06ef2eba-d1b99ac6d2ea663c.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1413-7179a49332db5a80.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/150-25c277137a9638ab.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1640-bc99ec23bbe29d12.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/1751.50b96ea9c37b49b6.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/2300-de059d0ab2a16630.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/2684-05b0a81e75298c16.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/3026-2ed7e317d9b02102.js +25 -0
  13. package/apps/pwa/out/_next/static/chunks/3611-77496ada38cd6358.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/3717-68957c4dc9ceec90.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/3929-46ba9af6f9d895cc.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/4015-62c5a3744698a8da.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/4217-3c4317a7905f9eeb.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/4240-3230f230fae2d7d5.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/4271-e53e075ebd48593b.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/4377.3b125fef79576dfd.js +5 -0
  21. package/apps/pwa/out/_next/static/chunks/4440-18bb160d95819f4e.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/4853-35fdbe6bdbcdc0fc.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{2a79f15a-2013e4d421d6df88.js → 4daa2798-1363d725c79f3593.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/5007-6a3b30e23ff68a6e.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/5244-12b424c42070f5ff.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/5348-bbf838e119661eee.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/5391-8793f88b03b30161.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/5611-df00af3e4e4a61bb.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/5890-dca2321773be829a.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/6123-37c9dc57ddaa7ab0.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/6588-b7975304a302ab91.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/6604-c03961962b6273b6.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/7109-cf8c87e968e83a65.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/7178-30f77877525a2efb.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/7262-871563fc9663730b.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/7294-f0eeebb92aa93459.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/7429-881af44deed6958f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{5927.8378481a12cc8044.js → 7527.943753b6ed829f09.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/764-a01e858525a190c0.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/7868-e35d5f7985ecd3f1.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/8320-51484af7b01fdfa5.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{6804.8ed6ab492bc5fc0a.js → 8617.465ca22a319c95b3.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/{320-d7013ec072863e5e.js → 8918-482b30ce2a8ebf4c.js} +4 -4
  44. package/apps/pwa/out/_next/static/chunks/9131-52f5fad51cceca04.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{2598.814f64e3268634e7.js → 9238.2cd5f47f4bf7a2c3.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/9704-3221c102623c8d73.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-70c404c7bb6d7f0f.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/app/approvals/page-3ffd80166b1050aa.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f89e9a303515a033.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/app/board/page-4f403cd060442c95.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/app/botlab/page-0ac5d053f0444d21.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/app/bots/page-4bcc63e272ae8205.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/app/chat/page-880734bd07d62882.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/app/control/page-72bd384898d88955.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1018bbc9586ecae5.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/app/editor/page-de86f8c38076dd7b.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/app/healthz/route-70c404c7bb6d7f0f.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/app/intake/page-cd6447196d8bafe6.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/app/layout-e733630c47fa102b.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/app/live/page-d1c1a8357b161875.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/app/market/page-60c514128e81d787.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8b637b7e325e13c1.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/app/morning/page-bccce0babceae30f.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/app/not-found-63301d11dbe73836.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/app/observatory/page-a8cf0dc472060db2.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/app/page-02fba54881ccfa49.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/app/reflection/page-d5e8e90f0038f8de.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-b1ef6824f494466a.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d589bb0f233b1009.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c9bbaebef4cda059.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/app/settings/page-3639ce7916b92fed.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7450ae7478955653.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/app/setup/layout-70c404c7bb6d7f0f.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/app/setup/page-b41ca4abfd618452.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/app/share/page-b333dd79ebee3fa9.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/app/showroom/page-8be1227492793655.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/app/tasks/page-6e03e9371b552e0d.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/app/term/page-911411e9fca18d03.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/app/trace/page-792170e649b37088.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/app/vault/page-c40463466937bc91.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-509c798b80384536.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/app/workflows/page-1cac2aa21d77c417.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/app/workspace/page-9626799d9b4a2cd1.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-84cd419494e16b0f.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/f6f3850d-7f324c6566002113.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/framework-361487d2da603917.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/main-app-607f5beb94cb2e07.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/main-d0222d219e29dddf.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/pages/_app-a26980a31126decc.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/pages/_error-edb2b37decf23e4d.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/webpack-2bf59c720fe9542c.js +1 -0
  92. package/apps/pwa/out/_next/static/css/eaa74e8bb2f62269.css +1 -0
  93. package/apps/pwa/out/_next/static/ktMqfrBbf8BMGac0jqLrb/_buildManifest.js +1 -0
  94. package/apps/pwa/out/approvals/index.html +1 -0
  95. package/apps/pwa/out/approvals/index.txt +32 -0
  96. package/apps/pwa/out/autopilot/index.html +1 -1
  97. package/apps/pwa/out/autopilot/index.txt +29 -26
  98. package/apps/pwa/out/board/index.html +1 -0
  99. package/apps/pwa/out/board/index.txt +32 -0
  100. package/apps/pwa/out/botlab/index.html +1 -1
  101. package/apps/pwa/out/botlab/index.txt +26 -23
  102. package/apps/pwa/out/bots/index.html +1 -1
  103. package/apps/pwa/out/bots/index.txt +26 -23
  104. package/apps/pwa/out/chat/index.html +1 -2
  105. package/apps/pwa/out/chat/index.txt +26 -23
  106. package/apps/pwa/out/control/index.html +1 -1
  107. package/apps/pwa/out/control/index.txt +29 -26
  108. package/apps/pwa/out/design-check/index.html +1 -1
  109. package/apps/pwa/out/design-check/index.txt +29 -26
  110. package/apps/pwa/out/editor/index.html +1 -0
  111. package/apps/pwa/out/editor/index.txt +33 -0
  112. package/apps/pwa/out/healthz +1 -1
  113. package/apps/pwa/out/icons/elanous-16.png +0 -0
  114. package/apps/pwa/out/icons/elanous-180.png +0 -0
  115. package/apps/pwa/out/icons/elanous-192.png +0 -0
  116. package/apps/pwa/out/icons/elanous-32.png +0 -0
  117. package/apps/pwa/out/icons/elanous-512.png +0 -0
  118. package/apps/pwa/out/index.html +1 -1
  119. package/apps/pwa/out/index.txt +26 -23
  120. package/apps/pwa/out/intake/index.html +1 -1
  121. package/apps/pwa/out/intake/index.txt +29 -26
  122. package/apps/pwa/out/live/index.html +1 -0
  123. package/apps/pwa/out/live/index.txt +32 -0
  124. package/apps/pwa/out/manifest.webmanifest +5 -2
  125. package/apps/pwa/out/market/index.html +1 -0
  126. package/apps/pwa/out/market/index.txt +29 -0
  127. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  128. package/apps/pwa/out/missions/placeholder/index.txt +26 -23
  129. package/apps/pwa/out/morning/index.html +1 -1
  130. package/apps/pwa/out/morning/index.txt +29 -26
  131. package/apps/pwa/out/observatory/index.html +1 -1
  132. package/apps/pwa/out/observatory/index.txt +29 -26
  133. package/apps/pwa/out/reflection/index.html +1 -1
  134. package/apps/pwa/out/reflection/index.txt +27 -24
  135. package/apps/pwa/out/scheduler/index.html +1 -1
  136. package/apps/pwa/out/scheduler/index.txt +29 -26
  137. package/apps/pwa/out/sessions/index.html +1 -1
  138. package/apps/pwa/out/sessions/index.txt +26 -23
  139. package/apps/pwa/out/settings/devices/index.html +1 -1
  140. package/apps/pwa/out/settings/devices/index.txt +29 -26
  141. package/apps/pwa/out/settings/index.html +1 -1
  142. package/apps/pwa/out/settings/index.txt +29 -26
  143. package/apps/pwa/out/setup/done/index.html +1 -1
  144. package/apps/pwa/out/setup/done/index.txt +29 -26
  145. package/apps/pwa/out/setup/index.html +1 -1
  146. package/apps/pwa/out/setup/index.txt +29 -26
  147. package/apps/pwa/out/share/index.html +1 -1
  148. package/apps/pwa/out/share/index.txt +29 -26
  149. package/apps/pwa/out/showroom/index.html +1 -1
  150. package/apps/pwa/out/showroom/index.txt +26 -23
  151. package/apps/pwa/out/sw-strategies.js +44 -0
  152. package/apps/pwa/out/sw.js +6 -44
  153. package/apps/pwa/out/tasks/index.html +1 -1
  154. package/apps/pwa/out/tasks/index.txt +29 -26
  155. package/apps/pwa/out/term/index.html +1 -1
  156. package/apps/pwa/out/term/index.txt +29 -26
  157. package/apps/pwa/out/trace/index.html +1 -0
  158. package/apps/pwa/out/trace/index.txt +32 -0
  159. package/apps/pwa/out/vault/index.html +1 -1
  160. package/apps/pwa/out/vault/index.txt +29 -26
  161. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  162. package/apps/pwa/out/workflows/chat-ui/index.txt +29 -26
  163. package/apps/pwa/out/workflows/index.html +1 -1
  164. package/apps/pwa/out/workflows/index.txt +29 -27
  165. package/apps/pwa/out/workspace/index.html +1 -1
  166. package/apps/pwa/out/workspace/index.txt +29 -26
  167. package/apps/pwa/out/worktrees/index.html +1 -1
  168. package/apps/pwa/out/worktrees/index.txt +29 -26
  169. package/catalog/resources.yaml +14 -17
  170. package/docs/design/systems/LICENSE +201 -0
  171. package/docs/design/systems/NOTICE.md +29 -0
  172. package/docs/design/systems/SOURCE.json +291 -0
  173. package/docs/design/systems/application/DESIGN.md +71 -0
  174. package/docs/design/systems/application/manifest.json +54 -0
  175. package/docs/design/systems/application/tokens.css +63 -0
  176. package/docs/design/systems/artistic/DESIGN.md +71 -0
  177. package/docs/design/systems/artistic/manifest.json +54 -0
  178. package/docs/design/systems/artistic/tokens.css +63 -0
  179. package/docs/design/systems/bento/DESIGN.md +71 -0
  180. package/docs/design/systems/bento/manifest.json +54 -0
  181. package/docs/design/systems/bento/tokens.css +63 -0
  182. package/docs/design/systems/bold/DESIGN.md +71 -0
  183. package/docs/design/systems/bold/manifest.json +54 -0
  184. package/docs/design/systems/bold/tokens.css +63 -0
  185. package/docs/design/systems/brutalism/DESIGN.md +71 -0
  186. package/docs/design/systems/brutalism/manifest.json +54 -0
  187. package/docs/design/systems/brutalism/tokens.css +63 -0
  188. package/docs/design/systems/cafe/DESIGN.md +71 -0
  189. package/docs/design/systems/cafe/manifest.json +54 -0
  190. package/docs/design/systems/cafe/tokens.css +63 -0
  191. package/docs/design/systems/claymorphism/DESIGN.md +71 -0
  192. package/docs/design/systems/claymorphism/manifest.json +54 -0
  193. package/docs/design/systems/claymorphism/tokens.css +63 -0
  194. package/docs/design/systems/clean/DESIGN.md +71 -0
  195. package/docs/design/systems/clean/manifest.json +54 -0
  196. package/docs/design/systems/clean/tokens.css +63 -0
  197. package/docs/design/systems/colorful/DESIGN.md +71 -0
  198. package/docs/design/systems/colorful/manifest.json +54 -0
  199. package/docs/design/systems/colorful/tokens.css +63 -0
  200. package/docs/design/systems/contemporary/DESIGN.md +71 -0
  201. package/docs/design/systems/contemporary/manifest.json +54 -0
  202. package/docs/design/systems/contemporary/tokens.css +63 -0
  203. package/docs/design/systems/corporate/DESIGN.md +71 -0
  204. package/docs/design/systems/corporate/manifest.json +54 -0
  205. package/docs/design/systems/corporate/tokens.css +63 -0
  206. package/docs/design/systems/cosmic/DESIGN.md +71 -0
  207. package/docs/design/systems/cosmic/manifest.json +54 -0
  208. package/docs/design/systems/cosmic/tokens.css +63 -0
  209. package/docs/design/systems/creative/DESIGN.md +71 -0
  210. package/docs/design/systems/creative/manifest.json +54 -0
  211. package/docs/design/systems/creative/tokens.css +63 -0
  212. package/docs/design/systems/dashboard/DESIGN.md +71 -0
  213. package/docs/design/systems/dashboard/manifest.json +54 -0
  214. package/docs/design/systems/dashboard/tokens.css +63 -0
  215. package/docs/design/systems/default/DESIGN.md +62 -0
  216. package/docs/design/systems/default/manifest.json +69 -0
  217. package/docs/design/systems/default/tokens.css +200 -0
  218. package/docs/design/systems/dithered/DESIGN.md +71 -0
  219. package/docs/design/systems/dithered/manifest.json +54 -0
  220. package/docs/design/systems/dithered/tokens.css +63 -0
  221. package/docs/design/systems/doodle/DESIGN.md +71 -0
  222. package/docs/design/systems/doodle/manifest.json +54 -0
  223. package/docs/design/systems/doodle/tokens.css +63 -0
  224. package/docs/design/systems/dramatic/DESIGN.md +71 -0
  225. package/docs/design/systems/dramatic/manifest.json +54 -0
  226. package/docs/design/systems/dramatic/tokens.css +63 -0
  227. package/docs/design/systems/editorial/DESIGN.md +71 -0
  228. package/docs/design/systems/editorial/manifest.json +54 -0
  229. package/docs/design/systems/editorial/tokens.css +63 -0
  230. package/docs/design/systems/elegant/DESIGN.md +71 -0
  231. package/docs/design/systems/elegant/manifest.json +54 -0
  232. package/docs/design/systems/elegant/tokens.css +63 -0
  233. package/docs/design/systems/energetic/DESIGN.md +72 -0
  234. package/docs/design/systems/energetic/manifest.json +54 -0
  235. package/docs/design/systems/energetic/tokens.css +63 -0
  236. package/docs/design/systems/enterprise/DESIGN.md +71 -0
  237. package/docs/design/systems/enterprise/manifest.json +54 -0
  238. package/docs/design/systems/enterprise/tokens.css +63 -0
  239. package/docs/design/systems/expressive/DESIGN.md +71 -0
  240. package/docs/design/systems/expressive/manifest.json +54 -0
  241. package/docs/design/systems/expressive/tokens.css +63 -0
  242. package/docs/design/systems/fantasy/DESIGN.md +71 -0
  243. package/docs/design/systems/fantasy/manifest.json +54 -0
  244. package/docs/design/systems/fantasy/tokens.css +63 -0
  245. package/docs/design/systems/flat/DESIGN.md +71 -0
  246. package/docs/design/systems/flat/manifest.json +54 -0
  247. package/docs/design/systems/flat/tokens.css +63 -0
  248. package/docs/design/systems/friendly/DESIGN.md +71 -0
  249. package/docs/design/systems/friendly/manifest.json +54 -0
  250. package/docs/design/systems/friendly/tokens.css +63 -0
  251. package/docs/design/systems/glassmorphism/DESIGN.md +71 -0
  252. package/docs/design/systems/glassmorphism/manifest.json +54 -0
  253. package/docs/design/systems/glassmorphism/tokens.css +63 -0
  254. package/docs/design/systems/gradient/DESIGN.md +71 -0
  255. package/docs/design/systems/gradient/manifest.json +54 -0
  256. package/docs/design/systems/gradient/tokens.css +63 -0
  257. package/docs/design/systems/luxury/DESIGN.md +71 -0
  258. package/docs/design/systems/luxury/manifest.json +54 -0
  259. package/docs/design/systems/luxury/tokens.css +63 -0
  260. package/docs/design/systems/minimal/DESIGN.md +71 -0
  261. package/docs/design/systems/minimal/manifest.json +54 -0
  262. package/docs/design/systems/minimal/tokens.css +63 -0
  263. package/docs/design/systems/modern/DESIGN.md +71 -0
  264. package/docs/design/systems/modern/manifest.json +54 -0
  265. package/docs/design/systems/modern/tokens.css +63 -0
  266. package/docs/design/systems/mono/DESIGN.md +71 -0
  267. package/docs/design/systems/mono/manifest.json +54 -0
  268. package/docs/design/systems/mono/tokens.css +63 -0
  269. package/docs/design/systems/neobrutalism/DESIGN.md +71 -0
  270. package/docs/design/systems/neobrutalism/manifest.json +54 -0
  271. package/docs/design/systems/neobrutalism/tokens.css +63 -0
  272. package/docs/design/systems/neon/DESIGN.md +71 -0
  273. package/docs/design/systems/neon/manifest.json +54 -0
  274. package/docs/design/systems/neon/tokens.css +63 -0
  275. package/docs/design/systems/neumorphism/DESIGN.md +71 -0
  276. package/docs/design/systems/neumorphism/manifest.json +54 -0
  277. package/docs/design/systems/neumorphism/tokens.css +63 -0
  278. package/docs/design/systems/paper/DESIGN.md +71 -0
  279. package/docs/design/systems/paper/manifest.json +54 -0
  280. package/docs/design/systems/paper/tokens.css +63 -0
  281. package/docs/design/systems/perspective/DESIGN.md +71 -0
  282. package/docs/design/systems/perspective/manifest.json +54 -0
  283. package/docs/design/systems/perspective/tokens.css +63 -0
  284. package/docs/design/systems/premium/DESIGN.md +71 -0
  285. package/docs/design/systems/premium/manifest.json +54 -0
  286. package/docs/design/systems/premium/tokens.css +63 -0
  287. package/docs/design/systems/professional/DESIGN.md +71 -0
  288. package/docs/design/systems/professional/manifest.json +54 -0
  289. package/docs/design/systems/professional/tokens.css +63 -0
  290. package/docs/design/systems/publication/DESIGN.md +71 -0
  291. package/docs/design/systems/publication/manifest.json +54 -0
  292. package/docs/design/systems/publication/tokens.css +63 -0
  293. package/docs/design/systems/refined/DESIGN.md +71 -0
  294. package/docs/design/systems/refined/manifest.json +54 -0
  295. package/docs/design/systems/refined/tokens.css +63 -0
  296. package/docs/design/systems/retro/DESIGN.md +71 -0
  297. package/docs/design/systems/retro/manifest.json +54 -0
  298. package/docs/design/systems/retro/tokens.css +63 -0
  299. package/docs/design/systems/shadcn/DESIGN.md +71 -0
  300. package/docs/design/systems/shadcn/manifest.json +54 -0
  301. package/docs/design/systems/shadcn/tokens.css +255 -0
  302. package/docs/design/systems/simple/DESIGN.md +71 -0
  303. package/docs/design/systems/simple/manifest.json +54 -0
  304. package/docs/design/systems/simple/tokens.css +63 -0
  305. package/docs/design/systems/skeumorphism/DESIGN.md +71 -0
  306. package/docs/design/systems/skeumorphism/manifest.json +54 -0
  307. package/docs/design/systems/skeumorphism/tokens.css +63 -0
  308. package/docs/design/systems/sleek/DESIGN.md +71 -0
  309. package/docs/design/systems/sleek/manifest.json +54 -0
  310. package/docs/design/systems/sleek/tokens.css +63 -0
  311. package/docs/design/systems/spacious/DESIGN.md +71 -0
  312. package/docs/design/systems/spacious/manifest.json +54 -0
  313. package/docs/design/systems/spacious/tokens.css +63 -0
  314. package/docs/design/systems/storytelling/DESIGN.md +71 -0
  315. package/docs/design/systems/storytelling/manifest.json +54 -0
  316. package/docs/design/systems/storytelling/tokens.css +63 -0
  317. package/docs/design/systems/tom-modern/DESIGN.md +361 -0
  318. package/docs/design/systems/tom-modern/manifest.json +16 -0
  319. package/docs/design/systems/tom-modern/tokens.css +99 -0
  320. package/docs/design/systems/vibrant/DESIGN.md +71 -0
  321. package/docs/design/systems/vibrant/manifest.json +54 -0
  322. package/docs/design/systems/vibrant/tokens.css +63 -0
  323. package/docs/design/systems/vintage/DESIGN.md +71 -0
  324. package/docs/design/systems/vintage/manifest.json +54 -0
  325. package/docs/design/systems/vintage/tokens.css +63 -0
  326. package/docs/design/systems/warm-editorial/DESIGN.md +65 -0
  327. package/docs/design/systems/warm-editorial/manifest.json +54 -0
  328. package/docs/design/systems/warm-editorial/tokens.css +63 -0
  329. package/docs/goal-context/01-goal-authoring-checks.md +18 -0
  330. package/docs/goal-context/steward-directives-2026-09-28.md +42 -0
  331. package/graphs/catalog/catalog.yaml +615 -0
  332. package/graphs/default-loop.yaml +1 -1
  333. package/graphs/document-loop.yaml +1 -1
  334. package/graphs/examples/stale-draft-digest/digest.ts +26 -0
  335. package/graphs/examples/stale-draft-digest/recipes.yaml +8 -0
  336. package/graphs/examples/stale-draft-digest/stale-draft-digest.yaml +22 -0
  337. package/graphs/heal/heal-loop.yaml +155 -0
  338. package/graphs/heal/recipes.yaml +19 -0
  339. package/graphs/implement-loop.yaml +2 -2
  340. package/graphs/intake/intake-daily.yaml +55 -0
  341. package/graphs/intake/recipes.yaml +16 -0
  342. package/graphs/landing/landing-heal.yaml +22 -0
  343. package/graphs/landing/recipes.yaml +8 -0
  344. package/graphs/launch/launch-head.yaml +66 -0
  345. package/graphs/launch/recipes.yaml +8 -0
  346. package/graphs/operate-loop.yaml +1 -1
  347. package/graphs/ops/docs-publish.yaml +31 -0
  348. package/graphs/ops/recipes.yaml +8 -0
  349. package/graphs/release/recipes.yaml +45 -0
  350. package/graphs/release/release-loop.yaml +45 -0
  351. package/graphs/research-loop.yaml +1 -1
  352. package/graphs/steward/recipes.yaml +12 -0
  353. package/graphs/steward/steward.yaml +45 -0
  354. package/graphs/video/README.md +1 -0
  355. package/graphs/video/broll-line.yaml +54 -0
  356. package/graphs/video/explainer-line.yaml +58 -0
  357. package/package.json +9 -5
  358. package/plugins/job-coach/.agents/plugins/marketplace.json +12 -0
  359. package/plugins/job-coach/.codex-plugin/plugin.json +23 -0
  360. package/plugins/job-coach/.mcp.json +9 -0
  361. package/plugins/job-coach/README.md +32 -0
  362. package/plugins/job-coach/connectors/ncs/server.ts +90 -0
  363. package/plugins/job-coach/examples/interview-sample.md +11 -0
  364. package/plugins/job-coach/graphs/course-links.ts +46 -0
  365. package/plugins/job-coach/graphs/gap-judge.ts +44 -0
  366. package/plugins/job-coach/graphs/recipes.yaml +45 -0
  367. package/plugins/job-coach/graphs/report-enterprise.yaml +28 -0
  368. package/plugins/job-coach/graphs/report.yaml +20 -0
  369. package/plugins/job-coach/graphs/run-step.ts +302 -0
  370. package/plugins/job-coach/plugin.json +26 -0
  371. package/plugins/job-coach/plugin.ts +6 -0
  372. package/plugins/job-coach/skills/career-report/SKILL.md +6 -0
  373. package/plugins/job-coach/skills/enterprise-ai-fit/SKILL.md +8 -0
  374. package/plugins/job-coach/skills/enterprise-competency/SKILL.md +8 -0
  375. package/plugins/job-coach/skills/enterprise-needs/SKILL.md +8 -0
  376. package/plugins/job-coach/skills/enterprise-roadmap/SKILL.md +8 -0
  377. package/plugins/job-coach/skills/enterprise-task-analysis/SKILL.md +8 -0
  378. package/plugins/job-coach/skills/interview-to-profile/SKILL.md +23 -0
  379. package/plugins/job-coach/skills/run-report/SKILL.md +15 -0
  380. package/scripts/backup/elanous-backup.sh +143 -14
  381. package/scripts/backup/elanous-restore.sh +122 -0
  382. package/scripts/build-docs-site.ts +4 -3
  383. package/scripts/ci-daemon-port-gate.ts +164 -0
  384. package/scripts/ci-typecheck-changed.ts +15 -1
  385. package/scripts/cli-json-exit-scan.ts +126 -0
  386. package/scripts/codex-quota-alert-format.ts +52 -0
  387. package/scripts/codex-quota-alert.ts +63 -13
  388. package/scripts/continuation-dogfood.ts +2 -1
  389. package/scripts/coord-channel-watch.sh +28 -9
  390. package/scripts/coord-post.sh +49 -12
  391. package/scripts/coord-tracks.json +6 -5
  392. package/scripts/cron-run.ts +37 -16
  393. package/scripts/daemon-port-baseline.txt +9 -0
  394. package/scripts/design/extract-corpus-bench.ts +469 -0
  395. package/scripts/design/extract-corpus-score.ts +510 -0
  396. package/scripts/design/vendor-open-design-systems.ts +100 -0
  397. package/scripts/docs-lint.ts +1 -1
  398. package/scripts/eval-bot-vs-grok.ts +79 -0
  399. package/scripts/eval-grok-live-baseline.ts +36 -0
  400. package/scripts/fixtures/front-route-corpus.sample.json +17 -0
  401. package/scripts/fleet/node-setup.sh +80 -7
  402. package/scripts/heal/run-role.ts +328 -0
  403. package/scripts/install-role-watch.sh +95 -0
  404. package/scripts/install.ps1 +11 -1
  405. package/scripts/install.sh +81 -9
  406. package/scripts/isolation-hardcode-baseline.txt +1 -1
  407. package/scripts/landing-heal/must-fix-match.ts +63 -0
  408. package/scripts/landing-heal/run-mission.ts +195 -0
  409. package/scripts/lib/front-route-measurement.ts +131 -0
  410. package/scripts/lib/pwa-scenarios/acp-replay.ts +79 -0
  411. package/scripts/lib/pwa-scenarios/cdp-driver.ts +67 -0
  412. package/scripts/lib/pwa-scenarios/runner.ts +200 -0
  413. package/scripts/lib/pwa-scenarios/scenarios.ts +202 -0
  414. package/scripts/lib/tui-sim-keys.ts +42 -0
  415. package/scripts/market/db-check.ts +212 -0
  416. package/scripts/market-posture-cycle.ts +63 -4
  417. package/scripts/measure-front-route-classifier.ts +56 -0
  418. package/scripts/media/ocr-leak-scan.sh +21 -0
  419. package/scripts/nightly-docops.ts +1 -1
  420. package/scripts/ops/channel-bot-token-migrate.ts +146 -0
  421. package/scripts/ops-health-check.ts +15 -3
  422. package/scripts/pty-scenarios/run.ts +272 -0
  423. package/scripts/public-export.ts +2 -3
  424. package/scripts/public-import-pr.ts +80 -6
  425. package/scripts/public-leak-baseline.txt +0 -7
  426. package/scripts/publish-internal-dist.ts +118 -0
  427. package/scripts/pwa-scenarios.ts +106 -0
  428. package/scripts/rebrand-elanous.ts +1 -1
  429. package/scripts/red-sweep-diff.ts +1 -1
  430. package/scripts/release-loop/auto-approve-node.ts +72 -0
  431. package/scripts/release-loop/cutoff.ts +139 -0
  432. package/scripts/release-loop/docs-land-node.ts +65 -0
  433. package/scripts/release-loop/docs-node.ts +172 -0
  434. package/scripts/release-loop/gate-diff.ts +29 -0
  435. package/scripts/release-loop/gate-node.ts +641 -0
  436. package/scripts/release-loop/node-verdict.ts +85 -0
  437. package/scripts/release-loop/prepare-node.ts +31 -0
  438. package/scripts/release-loop/publish-node.ts +61 -0
  439. package/scripts/release-loop/pwa-node-verdict.ts +45 -0
  440. package/scripts/release-loop/pwa-scenarios-node.ts +140 -0
  441. package/scripts/release-loop/release-docs.ts +109 -0
  442. package/scripts/release-loop/test-durations.ts +63 -0
  443. package/scripts/release-loop/tui-node-checks.ts +29 -0
  444. package/scripts/release-loop/tui-sim-node.ts +113 -0
  445. package/scripts/release-loop/upgrade-node.ts +26 -0
  446. package/scripts/release-loop/verify-node.ts +21 -0
  447. package/scripts/release-loop/version-node.ts +147 -0
  448. package/scripts/release-upgrade-check.sh +53 -0
  449. package/scripts/se-mission-prepare.ts +9 -15
  450. package/scripts/test-audit-coverage-per-file.sh +16 -0
  451. package/scripts/test-audit-meaningless.ts +88 -0
  452. package/scripts/test-audit-overlap-and-weak.ts +73 -0
  453. package/scripts/test-deterministic.ts +29 -6
  454. package/scripts/tui-sim.ts +59 -14
  455. package/scripts/uninstall.sh +10 -3
  456. package/scripts/ux/bump-installed.sh +20 -0
  457. package/scripts/ux/lib/cdp.ts +72 -0
  458. package/scripts/ux/record-page.ts +50 -0
  459. package/scripts/video-broll-line.ts +89 -0
  460. package/scripts/waitlist-daily-digest.ts +108 -0
  461. package/scripts/window-landings.sh +1 -1
  462. package/skills/explainer-video/SKILL.md +99 -0
  463. package/skills/explainer-video/engine/brand/elanous-mark-on-dark.svg +1 -0
  464. package/skills/explainer-video/engine/build.mjs +431 -0
  465. package/skills/explainer-video/engine/vo.ts +37 -0
  466. package/skills/explainer-video/examples/elanous-0.2.5/script.json +155 -0
  467. package/skills/motion-broll/LICENSE +25 -0
  468. package/skills/motion-broll/SKILL.md +150 -0
  469. package/skills/motion-broll/SOURCE.md +6 -0
  470. package/skills/motion-broll/engine/base.css +19 -0
  471. package/skills/motion-broll/engine/beats.js +11 -0
  472. package/skills/motion-broll/engine/build.py +21 -0
  473. package/skills/motion-broll/engine/fonts/Geist-Variable.woff2 +0 -0
  474. package/skills/motion-broll/engine/fonts/GeistMono-Medium.woff2 +0 -0
  475. package/skills/motion-broll/engine/fonts/OFL-Geist.txt +92 -0
  476. package/skills/motion-broll/engine/motion.js +146 -0
  477. package/skills/motion-broll/engine/render.js +22 -0
  478. package/skills/motion-broll/examples/opus-aoe2/01-opus-drop.html +41 -0
  479. package/skills/motion-broll/examples/opus-aoe2/02-pip-builds.html +110 -0
  480. package/skills/motion-broll/examples/opus-aoe2/03-effort-slider.html +38 -0
  481. package/skills/motion-broll/examples/opus-aoe2/04-master-prompt.html +56 -0
  482. package/skills/motion-broll/examples/opus-aoe2/05-low-vs-max.html +49 -0
  483. package/skills/motion-broll/examples/opus-aoe2/06-chapter.html +18 -0
  484. package/skills/motion-broll/examples/opus-aoe2/plan.json +14 -0
  485. package/skills/motion-broll/reference/engine-api.md +106 -0
  486. package/skills/motion-broll/scripts/composite.py +14 -0
  487. package/skills/motion-broll/scripts/inspect_video.py +34 -0
  488. package/skills/motion-broll/scripts/make_pages.py +34 -0
  489. package/skills/motion-broll/scripts/setup.sh +16 -0
  490. package/skills/motion-broll/scripts/words.py +13 -0
  491. package/skills/motion-broll/templates/compare.html +135 -0
  492. package/skills/motion-broll/templates/viewer.html +97 -0
  493. package/skills/omni-digest/SKILL.md +260 -0
  494. package/skills/omni-digest/digest.md +197 -0
  495. package/skills/omni-digest/docs/diagrams/noncode-terminal-promotion-path-2026-08-13.mmd +32 -0
  496. package/skills/omni-digest/package-lock.json +558 -0
  497. package/skills/omni-digest/package.json +13 -0
  498. package/skills/omni-digest/scripts/main.ts +404 -0
  499. package/skills/omni-digest/src/delegate.ts +34 -0
  500. package/skills/omni-digest/src/detect.ts +46 -0
  501. package/skills/omni-digest/src/diagram.ts +72 -0
  502. package/skills/omni-digest/src/domain-staging.ts +50 -0
  503. package/skills/omni-digest/src/env.ts +38 -0
  504. package/skills/omni-digest/src/fetch.ts +237 -0
  505. package/skills/omni-digest/src/media.ts +180 -0
  506. package/skills/omni-digest/src/obsidian.ts +69 -0
  507. package/skills/omni-digest/src/ocr.ts +149 -0
  508. package/skills/omni-digest/src/router.ts +60 -0
  509. package/skills/omni-digest/src/summarize.ts +87 -0
  510. package/skills/omni-digest/src/types.ts +124 -0
  511. package/skills/omni-digest/src/util.ts +34 -0
  512. package/skills/omni-digest/src/visual.ts +129 -0
  513. package/skills/omni-digest/src/x-api.ts +151 -0
  514. package/skills/omni-digest/tsconfig.json +13 -0
  515. package/src/a2a/agent-card.ts +29 -0
  516. package/src/a2a/server.ts +173 -0
  517. package/src/acp/auto-persist.ts +3 -6
  518. package/src/acp/backend-registry.ts +6 -10
  519. package/src/acp/channel-browser-shell.ts +1 -535
  520. package/src/acp/client.ts +106 -36
  521. package/src/acp/fs-roots.ts +20 -4
  522. package/src/acp/obsidian-tags.ts +6 -3
  523. package/src/acp/server.ts +189 -32
  524. package/src/agent/nested-agent-env.ts +1 -0
  525. package/src/agent/pty-binding.ts +1 -1
  526. package/src/agent/spawn-embodied-agent-in-vw.ts +5 -336
  527. package/src/agent/subagent-callable.ts +39 -1
  528. package/src/agent-mission/browser-login.ts +241 -0
  529. package/src/agent-mission/capabilities-cli.ts +33 -0
  530. package/src/agent-mission/capability-matrix.ts +31 -0
  531. package/src/agent-mission/capability-readers.ts +79 -0
  532. package/src/agent-mission/capability-types.ts +15 -0
  533. package/src/agent-mission/claude-headless.ts +131 -0
  534. package/src/agent-mission/claude-subscription.ts +57 -0
  535. package/src/agent-mission/doc-guided-install.ts +185 -0
  536. package/src/agent-mission/driver.ts +900 -69
  537. package/src/agent-mission/env-profile.ts +68 -0
  538. package/src/agent-mission/handoff.ts +128 -0
  539. package/src/agent-mission/in-agent-plugin.ts +311 -0
  540. package/src/agent-mission/mission-cli.ts +25 -1
  541. package/src/agent-mission/parse.ts +9 -4
  542. package/src/agent-mission/pr-review-watch.ts +62 -13
  543. package/src/agent-mission/resource-ladder.ts +235 -0
  544. package/src/agent-mission/tool-install.ts +249 -0
  545. package/src/agent-mission/tool-ladder.ts +37 -0
  546. package/src/agent-room/room-builder.ts +6 -600
  547. package/src/agent-substrate/review-intent.ts +43 -1
  548. package/src/auth/acp-token.ts +16 -0
  549. package/src/auth/github-app-token.ts +112 -0
  550. package/src/auth/scope.ts +8 -4
  551. package/src/auth/temp-tokens.ts +131 -0
  552. package/src/auto-research/obsidian-bridge.ts +2 -0
  553. package/src/autopilot/build/integrity-gate.ts +27 -4
  554. package/src/autopilot/build/isolated-instance.ts +2 -1
  555. package/src/autopilot/build/llm-conflict-merge.ts +27 -0
  556. package/src/autopilot/gh-rest-fallback.ts +177 -0
  557. package/src/autopilot/llm-control-brain.ts +54 -12
  558. package/src/autopilot/mission-engine.ts +15 -1
  559. package/src/autopilot/mission-notify.ts +4 -2
  560. package/src/autopilot/mission-origin.ts +5 -5
  561. package/src/autopilot/mission-phase-track.ts +52 -0
  562. package/src/autopilot/mission-tool.ts +1 -1
  563. package/src/autopilot/pr-manager.ts +51 -4
  564. package/src/autopilot/pty-control-loop.ts +94 -2
  565. package/src/autopilot/track-agent.ts +138 -0
  566. package/src/autopilot/track-courier.ts +153 -0
  567. package/src/boot/acp-server.ts +18 -18
  568. package/src/boot/check-same-origin.ts +19 -5
  569. package/src/boot/daemon-multi-llm-runtime.ts +14 -8
  570. package/src/boot/daemon-prompt-turn.ts +2 -0
  571. package/src/boot/daemon-runtime.ts +36 -14
  572. package/src/boot/daemon-tools/index.ts +16 -0
  573. package/src/boot/daemon-tools/self-implement.ts +4 -0
  574. package/src/boot/daemon-tools/types.ts +3 -0
  575. package/src/boot/daemon-tools/web-search.ts +2 -1
  576. package/src/boot/ws-bridge.ts +11 -0
  577. package/src/browser-cdp/chrome-flags.ts +7 -0
  578. package/src/browser-cdp/client.ts +2 -0
  579. package/src/browser-pane/mount.ts +1 -246
  580. package/src/budget/codex-reset-credit-state.ts +15 -0
  581. package/src/budget/fetchers/codex.ts +2 -1
  582. package/src/budget/run-usage-rollup.ts +11 -4
  583. package/src/budget/unified-usage.ts +2 -1
  584. package/src/capture/tui-self-report.ts +10 -0
  585. package/src/channel-bot-token.ts +126 -0
  586. package/src/chat/index.ts +57 -52
  587. package/src/chat/input-text-key.ts +2 -2
  588. package/src/chat/log-scroll-key.ts +12 -0
  589. package/src/chat/mode/manual.ts +2 -4
  590. package/src/chat/pickers/state.ts +10 -27
  591. package/src/chat/search/modal.ts +14 -2
  592. package/src/chat/submit-trace.ts +30 -0
  593. package/src/chat/tool-render/types.ts +1 -1
  594. package/src/chat/turn-typeahead.ts +2 -1
  595. package/src/chat/wrap.ts +6 -8
  596. package/src/cli/__fixtures__/agent-help-before/agent.txt +18 -0
  597. package/src/cli/__fixtures__/agent-help-before/registry.txt +13 -0
  598. package/src/cli/__fixtures__/agent-help-before/root.txt +100 -0
  599. package/src/cli/__fixtures__/agent-help-before/tier.txt +15 -0
  600. package/src/cli/a2a-cli.ts +52 -0
  601. package/src/cli/agent-cli.ts +726 -0
  602. package/src/cli/autopilot-cli.ts +739 -0
  603. package/src/cli/bg-launch.ts +20 -4
  604. package/src/cli/claude-plugin-setup.ts +199 -0
  605. package/src/cli/config-test-sync.ts +94 -10
  606. package/src/cli/connector-cli.ts +204 -0
  607. package/src/cli/control-cli.ts +220 -0
  608. package/src/cli/control-join-cli.ts +142 -0
  609. package/src/cli/decisions-cli.ts +94 -0
  610. package/src/cli/docs-cli.ts +38 -0
  611. package/src/cli/doctor-cli.ts +262 -77
  612. package/src/cli/doctor-distro.ts +17 -1
  613. package/src/cli/doctor-fix.ts +145 -17
  614. package/src/cli/doctor-llm-assist.ts +71 -0
  615. package/src/cli/doctor-private-files.ts +66 -0
  616. package/src/cli/doctor-readiness.ts +23 -28
  617. package/src/cli/fleet-cli.ts +63 -0
  618. package/src/cli/g6a-registration-probe.ts +16 -0
  619. package/src/cli/git-install-plan.ts +51 -0
  620. package/src/cli/hooks-cli.ts +44 -0
  621. package/src/cli/ingest-token-cli.ts +21 -0
  622. package/src/cli/intake-cli.ts +416 -0
  623. package/src/cli/labels-cli.ts +74 -0
  624. package/src/cli/leader-cli.ts +10 -159
  625. package/src/cli/live-cli.ts +48 -0
  626. package/src/cli/llm-detect-cli.ts +130 -0
  627. package/src/cli/logs-cli.ts +231 -7
  628. package/src/cli/machine-cli.ts +38 -0
  629. package/src/cli/mcp-call.ts +52 -13
  630. package/src/cli/mcp-gateway-cli.ts +94 -0
  631. package/src/cli/mcp-login.ts +116 -8
  632. package/src/cli/mcp-reload.ts +20 -3
  633. package/src/cli/nexus-dist.ts +18 -13
  634. package/src/cli/nexus-ios-bind.ts +20 -7
  635. package/src/cli/ops-cli.ts +225 -0
  636. package/src/cli/plugin-cli.ts +201 -0
  637. package/src/cli/pod-cli.ts +83 -0
  638. package/src/cli/port-lease-local.ts +124 -0
  639. package/src/cli/pr-cli.ts +12 -1
  640. package/src/cli/pr-lineage.ts +2 -1
  641. package/src/cli/provider-cli.ts +720 -0
  642. package/src/cli/pty-record-cli.ts +63 -0
  643. package/src/cli/pty-takeover-cli.ts +57 -40
  644. package/src/cli/pty-web-address.ts +52 -0
  645. package/src/cli/publish-cli.ts +44 -0
  646. package/src/cli/pwa-build.ts +18 -12
  647. package/src/cli/pwa-dev.ts +13 -8
  648. package/src/cli/pwa-registry.ts +6 -0
  649. package/src/cli/pwa-share.ts +65 -22
  650. package/src/cli/pwa-show.ts +20 -4
  651. package/src/cli/pwa-start.ts +102 -27
  652. package/src/cli/pwa-test.ts +201 -96
  653. package/src/cli/release-cli.ts +177 -7
  654. package/src/cli/remotes-cli.ts +20 -1
  655. package/src/cli/remotes.ts +2 -1
  656. package/src/cli/repo-cli.ts +315 -36
  657. package/src/cli/research-cli.ts +66 -0
  658. package/src/cli/role-cli.ts +320 -0
  659. package/src/cli/schedule-cli.ts +246 -0
  660. package/src/cli/self-update.ts +103 -12
  661. package/src/cli/setup-cli.ts +64 -2
  662. package/src/cli/shadow-cli.ts +188 -0
  663. package/src/cli/share-auto-mount.ts +12 -8
  664. package/src/cli/start-cli.ts +240 -0
  665. package/src/cli/stdout-flush.ts +8 -0
  666. package/src/cli/storage-cli.ts +334 -0
  667. package/src/cli/tailscale-serve.ts +34 -19
  668. package/src/cli/tasks-cli.ts +176 -0
  669. package/src/cli/test-state-dir-flag.ts +1 -1
  670. package/src/cli/usage-cli.ts +15 -4
  671. package/src/cli/where-cli.ts +22 -55
  672. package/src/code-edit/diff-render.ts +6 -32
  673. package/src/code-edit/source-delta-browser.ts +0 -1
  674. package/src/codex/models.ts +1 -1
  675. package/src/config.ts +8 -13
  676. package/src/connectors/event-ledger.ts +41 -0
  677. package/src/connectors/linear-projector.ts +88 -0
  678. package/src/connectors/linear.ts +143 -0
  679. package/src/connectors/types.ts +19 -0
  680. package/src/control-plane/lease-holder.ts +41 -0
  681. package/src/control-plane/ledger.ts +146 -0
  682. package/src/control-plane/light-member.ts +164 -0
  683. package/src/control-plane/member-tokens.ts +88 -0
  684. package/src/control-plane/member.ts +159 -0
  685. package/src/control-plane/port-lease-heartbeat.ts +101 -0
  686. package/src/control-plane/ports.ts +40 -0
  687. package/src/control-plane/primary.ts +169 -0
  688. package/src/control-plane/server.ts +216 -0
  689. package/src/dashboard/acp-boot.ts +14 -38
  690. package/src/dashboard/assistant-render-state-runtime.ts +2 -2
  691. package/src/dashboard/assistant-sample-runtime.ts +2 -2
  692. package/src/dashboard/auto-compact-runtime.ts +11 -16
  693. package/src/dashboard/browser-help-runtime.ts +2 -3
  694. package/src/dashboard/chat/acp-chat.ts +2 -5
  695. package/src/dashboard/code-edit-post-turn-runtime.ts +1 -2
  696. package/src/dashboard/compact-surface-assembly.ts +0 -14
  697. package/src/dashboard/compact-surface-dispatch.ts +1 -38
  698. package/src/dashboard/compact-surface-inventory.ts +0 -8
  699. package/src/dashboard/compact-surface-runtime.ts +0 -14
  700. package/src/dashboard/context-menu-provider-boot.ts +0 -9
  701. package/src/dashboard/context-window-runtime-boot.ts +0 -37
  702. package/src/dashboard/index.ts +331 -2562
  703. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +0 -6
  704. package/src/dashboard/input/chat-main-slash-command.ts +2 -2
  705. package/src/dashboard/input/dashboard-priority-key-route.ts +1 -43
  706. package/src/dashboard/input/mouse-modal-surface-runtime.ts +1 -5
  707. package/src/dashboard/input/mouse-wiring.ts +2 -3
  708. package/src/dashboard/input/no-provider-reply.ts +13 -0
  709. package/src/dashboard/layout-display-runtime-registration.ts +0 -10
  710. package/src/dashboard/modals/pane-multi.ts +1 -1
  711. package/src/dashboard/replay-preview.ts +1 -1
  712. package/src/dashboard/runtime/approvers.ts +0 -1
  713. package/src/dashboard/runtime/state-snapshot.ts +0 -90
  714. package/src/dashboard/scenario-runtime-boot.ts +16 -16
  715. package/src/dashboard/slash-runtime/dashboard-handlers.ts +134 -1456
  716. package/src/dashboard/slash-runtime/design-pick.ts +96 -0
  717. package/src/dashboard/slash-runtime/help-from-registry.ts +77 -0
  718. package/src/dashboard/slash-runtime/unknown-slash-reply.ts +78 -0
  719. package/src/dashboard/stale-install-check.ts +77 -0
  720. package/src/dashboard/surface-registry-wiring.ts +2 -15
  721. package/src/dashboard/turn-message-runtime.ts +0 -4
  722. package/src/dashboard/turn-preamble.ts +1 -1
  723. package/src/dashboard/turn-stream-formatter.ts +2 -2
  724. package/src/dashboard/turn-stream-runtime.ts +2 -2
  725. package/src/dashboard-pane-context-menu.ts +0 -14
  726. package/src/debug/log.ts +7 -0
  727. package/src/decide/boundary-shadow.ts +131 -0
  728. package/src/decisions/decision-ledger.ts +404 -0
  729. package/src/design/apply-direction.ts +209 -0
  730. package/src/design/css-root-tokens.ts +89 -0
  731. package/src/design/custom-system-create.ts +230 -0
  732. package/src/design/design-directions.ts +61 -41
  733. package/src/design/design-gate.ts +241 -0
  734. package/src/design/design-library.ts +57 -0
  735. package/src/design/design-previews.ts +138 -0
  736. package/src/design/design-systems.ts +61 -0
  737. package/src/design/lint-artifact-run.ts +46 -6
  738. package/src/design/lint-artifact.ts +5 -1
  739. package/src/design/open-design-client.ts +247 -0
  740. package/src/design/system-from-extract.ts +767 -0
  741. package/src/design/system-schema.ts +123 -0
  742. package/src/discord-slash-wire.ts +2 -1
  743. package/src/discord-test-runner.ts +2 -1
  744. package/src/discord-voice-wire.ts +2 -1
  745. package/src/discord.ts +1 -1
  746. package/src/dispatch/opportunistic-launcher.ts +24 -1
  747. package/src/domains/ops-status.ts +35 -2
  748. package/src/domains/outbound-alert.ts +24 -6
  749. package/src/domains/repeated-failure.ts +89 -0
  750. package/src/domains/schedule-manage-tool.ts +28 -8
  751. package/src/domains/schedule-migrate.ts +22 -4
  752. package/src/domains/schedule-registry.ts +88 -33
  753. package/src/domains/schedule-runs.ts +132 -0
  754. package/src/domains/schedule-state.ts +152 -0
  755. package/src/domains/telegram-kind-route.ts +21 -0
  756. package/src/element-registry/address.ts +1 -3
  757. package/src/execution-loop/dispatch-task.ts +139 -0
  758. package/src/execution-loop/gate-decision-summary.ts +29 -0
  759. package/src/execution-loop/gates.ts +197 -0
  760. package/src/git-fs/gh-cli.ts +47 -17
  761. package/src/git-fs/retry.ts +1 -0
  762. package/src/git-fs/runner.ts +1 -0
  763. package/src/git-fs/worktree.ts +6 -5
  764. package/src/github/pr-labels.ts +68 -0
  765. package/src/graph-kinds/installed-plugin-nodes.ts +95 -0
  766. package/src/graph-kinds/plugin-nodes.ts +68 -0
  767. package/src/graph-kinds/registry.ts +118 -0
  768. package/src/graph-runner/graph-cli.ts +103 -0
  769. package/src/graph-runner/graph-notify.ts +220 -0
  770. package/src/graph-runner/graph-tick.ts +119 -0
  771. package/src/graph-runner/release-manifest.ts +93 -0
  772. package/src/graph-runner/runner.ts +487 -0
  773. package/src/grok/credential.ts +158 -5
  774. package/src/grounding/ensure-grounding.ts +131 -0
  775. package/src/grounding/mirror-export.ts +89 -0
  776. package/src/grounding/mirror-manifest.ts +252 -0
  777. package/src/grounding/sources-cli.ts +209 -0
  778. package/src/grounding/sources.ts +333 -0
  779. package/src/grounding/token.ts +121 -0
  780. package/src/harness/harness-cli-command.ts +415 -23
  781. package/src/harness/harness-pod-dispatch.ts +116 -0
  782. package/src/harness/harness-stop.ts +260 -0
  783. package/src/harness/harness-substrate-default.ts +40 -0
  784. package/src/harness/harness-worktrees.ts +1 -1
  785. package/src/harness/harness-write-boundary.ts +2 -0
  786. package/src/harness/llm-decompose.ts +2 -1
  787. package/src/harness/self-send-decide.ts +233 -0
  788. package/src/harness/self-send-target.ts +22 -1
  789. package/src/harness/shell-relay.ts +5 -0
  790. package/src/harness/worktree-branch-prefix.ts +4 -3
  791. package/src/hooks/providers.ts +77 -0
  792. package/src/hooks/queue.ts +73 -0
  793. package/src/hooks/receiver.ts +133 -0
  794. package/src/index.ts +712 -3409
  795. package/src/input-core/dispatcher.ts +1 -1
  796. package/src/input-core/drag-esc-interceptor.ts +1 -1
  797. package/src/instance/current.ts +5 -5
  798. package/src/instance/leader.ts +10 -326
  799. package/src/instance/nexus-run-refusal.ts +27 -92
  800. package/src/instance/project-local-exclude.ts +27 -0
  801. package/src/instance/resolve.ts +46 -175
  802. package/src/intake-plane/capture.ts +14 -1
  803. package/src/intake-plane/check.ts +34 -14
  804. package/src/intake-plane/collect-github.ts +258 -0
  805. package/src/intake-plane/collect-pod.ts +100 -0
  806. package/src/intake-plane/collect-telegram-saved.ts +91 -0
  807. package/src/intake-plane/digest.ts +111 -0
  808. package/src/intake-plane/enrich-plugins.ts +1 -1
  809. package/src/intake-plane/front-classifier.ts +56 -0
  810. package/src/intake-plane/front-route-classifier.ts +80 -0
  811. package/src/intake-plane/front-route-rules.ts +152 -0
  812. package/src/intake-plane/grounding-docs.ts +185 -0
  813. package/src/intake-plane/harness-target.ts +20 -0
  814. package/src/intake-plane/intake-to-tasks.ts +303 -0
  815. package/src/intake-plane/items.ts +247 -0
  816. package/src/intake-plane/link-ledger.ts +27 -0
  817. package/src/intake-plane/route.ts +104 -0
  818. package/src/intake-plane/runtime-callables.ts +3 -1
  819. package/src/intake-plane/sketch-ledger.ts +34 -0
  820. package/src/intake-plane/slash.ts +30 -2
  821. package/src/intake-plane/submit-intake-work.ts +160 -0
  822. package/src/intake-plane/telegram-work.ts +56 -0
  823. package/src/iul/sidebar-shell.ts +0 -165
  824. package/src/launch-head/capability-check.ts +162 -0
  825. package/src/launch-head/launch-head-cli.ts +242 -0
  826. package/src/launch-head/load-balance.ts +81 -0
  827. package/src/live/detail-switch.ts +180 -0
  828. package/src/llm/provider-detect.ts +247 -0
  829. package/src/llm/provider-probe.ts +57 -0
  830. package/src/llm/usable-llm.ts +32 -0
  831. package/src/llm.ts +55 -23
  832. package/src/log-entry.ts +1 -1
  833. package/src/log-pane/attachment-popup.ts +1 -2
  834. package/src/loops/loop-cli.ts +37 -0
  835. package/src/loops/registry.ts +196 -0
  836. package/src/market/official-keys.ts +5 -0
  837. package/src/market/publish.ts +329 -0
  838. package/src/market/signed-index.ts +156 -0
  839. package/src/market/tgz.ts +121 -0
  840. package/src/mcp/client.ts +1 -1
  841. package/src/mcp/mcp-oauth.ts +40 -5
  842. package/src/mcp/server.ts +75 -7
  843. package/src/mcp-gateway/gateway.ts +128 -0
  844. package/src/mcp-gateway/pat-store.ts +124 -0
  845. package/src/mss/logging/log-store.ts +91 -2
  846. package/src/mss/logging/scoped-level.ts +5 -9
  847. package/src/native-tool-catalog.ts +66 -345
  848. package/src/nexus/api/connect-info.ts +23 -25
  849. package/src/nexus/api/context-url.ts +1 -1
  850. package/src/nexus/api/design-check.ts +90 -59
  851. package/src/nexus/api/design-previews-route.ts +182 -0
  852. package/src/nexus/api/design-system-create-route.ts +123 -0
  853. package/src/nexus/api/graph-approvals.ts +125 -0
  854. package/src/nexus/api/graph-kinds.ts +69 -0
  855. package/src/nexus/api/graphs-api.ts +221 -0
  856. package/src/nexus/api/harness-api.ts +31 -2
  857. package/src/nexus/api/health.ts +15 -0
  858. package/src/nexus/api/http-server.ts +328 -43
  859. package/src/nexus/api/image-generate.ts +3 -0
  860. package/src/nexus/api/ingest-token.ts +175 -0
  861. package/src/nexus/api/intake-ledger-api.ts +54 -0
  862. package/src/nexus/api/intake-route.ts +111 -0
  863. package/src/nexus/api/json-response.ts +33 -0
  864. package/src/nexus/api/live-detail.ts +47 -0
  865. package/src/nexus/api/live-shipped.ts +78 -0
  866. package/src/nexus/api/log-fabric.ts +42 -2
  867. package/src/nexus/api/markdown-publish.ts +3 -2
  868. package/src/nexus/api/mcp-http.ts +14 -9
  869. package/src/nexus/api/mcp-oauth-hint.ts +31 -0
  870. package/src/nexus/api/mcp-public-allowlist.ts +33 -0
  871. package/src/nexus/api/merge-approvals-gate.ts +79 -0
  872. package/src/nexus/api/merge-approvals.ts +307 -0
  873. package/src/nexus/api/meta-api.ts +18 -0
  874. package/src/nexus/api/next-fluent-wiring.ts +7 -9
  875. package/src/nexus/api/plugins-credentials-api.ts +47 -0
  876. package/src/nexus/api/plugins-market.ts +209 -0
  877. package/src/nexus/api/pod-credential-api.ts +187 -0
  878. package/src/nexus/api/public-routes.ts +87 -0
  879. package/src/nexus/api/rest-route-paths.ts +15 -0
  880. package/src/nexus/api/schedules-action.ts +12 -3
  881. package/src/nexus/api/schedules-read.ts +228 -0
  882. package/src/nexus/api/sessions-store.ts +8 -2
  883. package/src/nexus/api/setup-answer-priority.ts +130 -0
  884. package/src/nexus/api/setup-channel-bot.ts +56 -0
  885. package/src/nexus/api/setup-child-llm.ts +228 -0
  886. package/src/nexus/api/setup-obsidian-skills.ts +93 -0
  887. package/src/nexus/api/task-cards-api.ts +34 -0
  888. package/src/nexus/api/tasks-create.ts +136 -0
  889. package/src/nexus/api/telegram-trigger-bot.ts +3 -3
  890. package/src/nexus/api/terminals.ts +204 -18
  891. package/src/nexus/api/trace.ts +405 -0
  892. package/src/nexus/api/vault-api.ts +140 -7
  893. package/src/nexus/api/worktrees.ts +18 -2
  894. package/src/nexus/boot/register-mcp-clients.ts +135 -16
  895. package/src/nexus/daemon-endpoint.ts +85 -0
  896. package/src/nexus/default-port.ts +1 -0
  897. package/src/nexus/index.ts +362 -143
  898. package/src/nexus/onboarding/pwa-share-prompt.ts +31 -8
  899. package/src/nexus/onboarding/tailscale-probe.ts +9 -1
  900. package/src/nexus/outbound/router.ts +1 -1
  901. package/src/nexus/setup-status.ts +58 -0
  902. package/src/nexus/supervisor/lock.ts +8 -0
  903. package/src/nexus/webterm/pty.ts +15 -0
  904. package/src/oauth/codex-account-rotation.ts +122 -16
  905. package/src/oauth/codex-account-store.ts +88 -19
  906. package/src/oauth/codex-quota-policy.ts +55 -0
  907. package/src/oauth/store.ts +28 -25
  908. package/src/obsidian/default-vault.ts +17 -0
  909. package/src/obsidian/vault-write-guard.ts +46 -0
  910. package/src/onboarding/help/llm.md +2 -2
  911. package/src/onboarding.ts +27 -4
  912. package/src/panes/alt-skip-predicate.ts +4 -3
  913. package/src/panes/external-terminal-pane.ts +3 -4
  914. package/src/panes/factory.ts +1 -18
  915. package/src/panes/index.ts +1 -5
  916. package/src/panes/pane-cycle.ts +1 -1
  917. package/src/panes/types.ts +1 -1
  918. package/src/platform/env-literal.ts +4 -0
  919. package/src/plugin-hooks/dispatcher.ts +10 -4
  920. package/src/plugins/core/host.ts +108 -4
  921. package/src/plugins/core/manifest.ts +104 -7
  922. package/src/plugins/install/market-fetch.ts +250 -0
  923. package/src/plugins/install/plugin-credentials.ts +106 -0
  924. package/src/plugins/install/plugin-install.ts +518 -0
  925. package/src/policy/claude-subscription-guard.ts +25 -0
  926. package/src/preview/terminal.ts +24 -1
  927. package/src/preview-pane/mount.ts +1 -142
  928. package/src/prompt/references.ts +4 -51
  929. package/src/prompt-library/universal-preamble.ts +8 -2
  930. package/src/pty-shell/pty-control-ipc.ts +57 -3
  931. package/src/pty-shell/pty-mouse.ts +75 -0
  932. package/src/pty-shell/pty-recording.ts +108 -0
  933. package/src/pty-shell/registry.ts +53 -3
  934. package/src/python/resolve-python.ts +1 -1
  935. package/src/release-loop/checklist.ts +191 -0
  936. package/src/release-loop/manifest.ts +65 -0
  937. package/src/release-loop/release-note.ts +177 -0
  938. package/src/roles/lease-cas.ts +52 -0
  939. package/src/roles/machine-name.ts +48 -0
  940. package/src/roles/machine-profile.ts +65 -0
  941. package/src/roles/role-lease-read.ts +81 -0
  942. package/src/roles/role-lease.ts +63 -0
  943. package/src/roles/role-watch.ts +69 -0
  944. package/src/self-dev/ask-launch-flow.ts +39 -22
  945. package/src/self-dev/ask-launch-io.ts +1 -1
  946. package/src/self-dev/dev-cli.ts +290 -159
  947. package/src/self-dev/dev-pipeline.ts +157 -9
  948. package/src/self-dev/draft-sweep.ts +231 -0
  949. package/src/self-dev/draft-triage-rules.ts +42 -0
  950. package/src/self-dev/entrance-baseline.ts +156 -4
  951. package/src/self-dev/fabric-decompose-adapter.ts +10 -0
  952. package/src/self-dev/launch-preflight.ts +1 -1
  953. package/src/self-dev/orchestrate.ts +297 -20
  954. package/src/self-dev/repair-signals.ts +6 -0
  955. package/src/self-dev/run-store.ts +20 -5
  956. package/src/self-dev/run-supervisor.ts +43 -3
  957. package/src/self-implement/abandoned-classification.ts +15 -1
  958. package/src/self-implement/blocked-draft-policy.ts +6 -0
  959. package/src/self-implement/budget-gate.ts +236 -0
  960. package/src/self-implement/child-llm-preference.ts +84 -0
  961. package/src/self-implement/decision-events.ts +57 -0
  962. package/src/self-implement/decision-signal-press.ts +5 -2
  963. package/src/self-implement/dependency-change-gate.ts +90 -0
  964. package/src/self-implement/gate-baseline.ts +35 -2
  965. package/src/self-implement/gate-cli.ts +29 -7
  966. package/src/self-implement/gate-scope.ts +7 -1
  967. package/src/self-implement/goal-author-decompose.ts +22 -4
  968. package/src/self-implement/goal-author.ts +41 -3
  969. package/src/self-implement/goal-boundary.ts +65 -0
  970. package/src/self-implement/goal-clarification-escalation.ts +1 -0
  971. package/src/self-implement/goal-documents-dir.ts +6 -1
  972. package/src/self-implement/goal-execution-records.ts +58 -0
  973. package/src/self-implement/goal-run-store.ts +42 -24
  974. package/src/self-implement/graph-authority.ts +13 -28
  975. package/src/self-implement/graph-catalog.ts +48 -0
  976. package/src/self-implement/graph-run-contract.ts +127 -0
  977. package/src/self-implement/graph-templates.ts +14 -7
  978. package/src/self-implement/graph-yaml.ts +35 -6
  979. package/src/self-implement/harness-policy-gates.ts +42 -0
  980. package/src/self-implement/headless-elanous-driver.ts +30 -6
  981. package/src/self-implement/heal-triage.ts +229 -0
  982. package/src/self-implement/host-regate.ts +244 -0
  983. package/src/self-implement/non-git-consent.ts +23 -0
  984. package/src/self-implement/orchestrator.ts +488 -134
  985. package/src/self-implement/pipeline-shape.ts +1 -1
  986. package/src/self-implement/pr-evidence-artifact.ts +6 -19
  987. package/src/self-implement/prior-draft-findings.ts +128 -0
  988. package/src/self-implement/pwa-import-graph.ts +65 -0
  989. package/src/self-implement/repo-provision.ts +18 -21
  990. package/src/self-implement/report-origin.ts +39 -0
  991. package/src/self-implement/rework-policy.ts +21 -0
  992. package/src/self-implement/run-ledger-compact.ts +438 -0
  993. package/src/self-implement/run-ledger.ts +212 -29
  994. package/src/self-implement/run-report.ts +24 -0
  995. package/src/self-implement/run-status-mapping.ts +2 -0
  996. package/src/self-implement/running-runs.ts +112 -14
  997. package/src/self-implement/scoped-typecheck-config.ts +49 -0
  998. package/src/self-implement/seams.ts +207 -40
  999. package/src/self-implement/self-implement-cli.ts +17 -2
  1000. package/src/self-implement/shadow-repo.ts +350 -0
  1001. package/src/self-implement/supervision-vocabulary.ts +7 -0
  1002. package/src/shell-runner/dispatch.ts +3 -0
  1003. package/src/shell-runner/index.ts +0 -7
  1004. package/src/skills/runner.ts +0 -69
  1005. package/src/skills/tools/agent-room-slash.ts +2 -1
  1006. package/src/skills/tools/agent-room.ts +8 -140
  1007. package/src/skills/tools/agent.ts +5 -3
  1008. package/src/skills/tools/context.ts +5 -140
  1009. package/src/skills/tools/control.ts +4 -188
  1010. package/src/skills/tools/dashboard-slash.ts +3 -11
  1011. package/src/skills/tools/dashboard-state.ts +3 -5
  1012. package/src/skills/tools/dev-harness.ts +45 -2
  1013. package/src/skills/tools/omni-search.ts +29 -1
  1014. package/src/skills/tools/shell.ts +11 -29
  1015. package/src/skills/tools/spawn-coding-agent-headless.ts +6 -9
  1016. package/src/ssh/ssh-picker-modal.ts +1 -1
  1017. package/src/steward/directive.ts +99 -0
  1018. package/src/steward/steward-cards.ts +45 -0
  1019. package/src/steward/triage.ts +239 -0
  1020. package/src/storage/cli-bin.ts +67 -0
  1021. package/src/storage/object-store-visibility.ts +169 -0
  1022. package/src/storage/object-store.ts +452 -0
  1023. package/src/storage/s3.ts +53 -10
  1024. package/src/storage/storage-detect.ts +337 -0
  1025. package/src/surface/address.ts +3 -5
  1026. package/src/surface/index.ts +0 -6
  1027. package/src/surface/llm-tools.ts +1 -2
  1028. package/src/surface/shell-runner-boot.ts +4 -89
  1029. package/src/task-cards/card-cli.ts +64 -0
  1030. package/src/task-cards/card-store.ts +241 -0
  1031. package/src/task-orchestrator/boot.ts +27 -1
  1032. package/src/task-orchestrator/dispatcher.ts +49 -7
  1033. package/src/task-orchestrator/external-fingerprint.ts +10 -0
  1034. package/src/task-orchestrator/external-policy.ts +86 -0
  1035. package/src/task-orchestrator/feedback-loop.ts +4 -2
  1036. package/src/task-orchestrator/graph.ts +18 -1
  1037. package/src/task-orchestrator/runtimes/create.ts +128 -0
  1038. package/src/task-orchestrator/store.ts +78 -18
  1039. package/src/task-orchestrator/surface-registry.ts +5 -2
  1040. package/src/task-orchestrator/surfaces/external-exec.ts +180 -0
  1041. package/src/task-orchestrator/surfaces/idea-approval-pr.ts +118 -0
  1042. package/src/task-orchestrator/surfaces/index.ts +4 -3
  1043. package/src/task-orchestrator/surfaces/pod-account-broker.ts +60 -5
  1044. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +194 -0
  1045. package/src/task-orchestrator/surfaces/pod-command-job.ts +369 -0
  1046. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +207 -0
  1047. package/src/task-orchestrator/surfaces/pod-pool.ts +128 -12
  1048. package/src/task-orchestrator/surfaces/pod-skills.ts +11 -3
  1049. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +147 -0
  1050. package/src/task-orchestrator/surfaces/pod-source-receive.ts +129 -0
  1051. package/src/task-orchestrator/surfaces/pod-source-spec.ts +77 -0
  1052. package/src/task-orchestrator/surfaces/self-implement-pod.ts +930 -45
  1053. package/src/task-orchestrator/surfaces/self-implement.ts +8 -1
  1054. package/src/task-orchestrator/tox-loop.ts +204 -0
  1055. package/src/task-orchestrator/types.ts +21 -1
  1056. package/src/telegram-commands.ts +8 -0
  1057. package/src/telegram-report.ts +14 -7
  1058. package/src/telegram-run.ts +18 -5
  1059. package/src/telegram.ts +92 -22
  1060. package/src/tool-runtime/acp-session-runtime.ts +28 -7
  1061. package/src/tool-runtime/agent-runtime.ts +1 -0
  1062. package/src/tool-runtime/context-runtime.ts +18 -35
  1063. package/src/tool-runtime/control-runtime.ts +8 -21
  1064. package/src/tool-runtime/dashboard-state-runtime.ts +1 -5
  1065. package/src/tool-runtime/elanous-asana-runtimes.ts +205 -0
  1066. package/src/tool-runtime/elanous-control-runtimes.ts +16 -2
  1067. package/src/tool-runtime/elanous-task-submit-runtime.ts +124 -0
  1068. package/src/tool-runtime/index.ts +4 -1
  1069. package/src/tool-runtime/scenario-runtimes.ts +22 -21
  1070. package/src/tool-runtime/scenario-target-mount.ts +6 -32
  1071. package/src/tool-runtime/types.ts +8 -0
  1072. package/src/tui/chat/attachment-summary.ts +4 -4
  1073. package/src/tui-client/acp-transport-ws-client.ts +72 -5
  1074. package/src/tui-client/headless-core-guard.ts +0 -1
  1075. package/src/tui.ts +11 -7
  1076. package/src/typecheck-ratchet.ts +15 -0
  1077. package/src/ui/hover-presenter.ts +3 -7
  1078. package/src/user-config.ts +453 -190
  1079. package/src/util/spawn-sync-output.ts +15 -0
  1080. package/src/version/code-revision.ts +34 -9
  1081. package/src/version/packed-revision.json +1 -1
  1082. package/src/video-pipeline/broll-agent.ts +102 -0
  1083. package/src/video-pipeline/recipes/broll.ts +263 -0
  1084. package/src/video-pipeline/walk-line.ts +2 -1
  1085. package/src/views/scratch-image-size.ts +10 -0
  1086. package/src/voice/channel-adapters/pwa-voice-adapter.ts +2 -18
  1087. package/src/voice/channel-adapters/telegram-voice-adapter.ts +1 -6
  1088. package/src/voice/voice-tts-singleton.ts +46 -8
  1089. package/src/web-push/vapid-keys.ts +1 -1
  1090. package/src/web-search/free.ts +77 -0
  1091. package/src/web-search/index.ts +7 -5
  1092. package/src/web-terminal/preview-tap-registry.ts +152 -43
  1093. package/src/workflow-runtime/deps-bridge.ts +4 -3
  1094. package/src/workflow-runtime/executor.ts +18 -22
  1095. package/src/workflow-runtime/node-catalog.ts +20 -1
  1096. package/src/workflow-runtime/nodes/bash.ts +1 -0
  1097. package/src/workflow-runtime/nodes/task.ts +74 -0
  1098. package/src/workflow-runtime/nodes/triggers.ts +24 -1
  1099. package/src/workflow-runtime/plugin-kind-node.ts +166 -0
  1100. package/src/workflow-runtime/schema.ts +98 -2
  1101. package/src/workflow-runtime/triggers/webhook-router.ts +43 -3
  1102. package/src/workflow-runtime/triggers/webhook-source.ts +19 -1
  1103. package/src/workflow-runtime/types.ts +76 -5
  1104. package/apps/pwa/out/_next/static/Ksn99fVf2HUWhSyV1-FC8/_buildManifest.js +0 -1
  1105. package/apps/pwa/out/_next/static/chunks/1176-4943bd83b00e53a2.js +0 -25
  1106. package/apps/pwa/out/_next/static/chunks/1380-9c652e1002032c86.js +0 -1
  1107. package/apps/pwa/out/_next/static/chunks/1863-2ea170dfec26b88b.js +0 -1
  1108. package/apps/pwa/out/_next/static/chunks/2091-2d6b7f4f16300f83.js +0 -1
  1109. package/apps/pwa/out/_next/static/chunks/2347-366617ec73babe3b.js +0 -1
  1110. package/apps/pwa/out/_next/static/chunks/3089-e60cc8f5d35ee239.js +0 -1
  1111. package/apps/pwa/out/_next/static/chunks/3158-c77ed9ea34f9cc9f.js +0 -1
  1112. package/apps/pwa/out/_next/static/chunks/3607-f0b5c5ee18fcf56a.js +0 -1
  1113. package/apps/pwa/out/_next/static/chunks/3659-05b2d5d971b42dbc.js +0 -1
  1114. package/apps/pwa/out/_next/static/chunks/3736-b6a7bfdcb8f56ec6.js +0 -1
  1115. package/apps/pwa/out/_next/static/chunks/3839-eebf298e89a7bb77.js +0 -1
  1116. package/apps/pwa/out/_next/static/chunks/4012.832a2824b978e7ee.js +0 -5
  1117. package/apps/pwa/out/_next/static/chunks/4706-d85d7f3345f3ff91.js +0 -1
  1118. package/apps/pwa/out/_next/static/chunks/526-17a6a2e0e6dc4498.js +0 -1
  1119. package/apps/pwa/out/_next/static/chunks/5508-676ac75f2757ad40.js +0 -1
  1120. package/apps/pwa/out/_next/static/chunks/5583-8a0317f4b8e68db9.js +0 -1
  1121. package/apps/pwa/out/_next/static/chunks/6258-b58f722b10e8d31d.js +0 -1
  1122. package/apps/pwa/out/_next/static/chunks/6820-32fd097e6186fdc9.js +0 -1
  1123. package/apps/pwa/out/_next/static/chunks/6852-983db7ca958634b7.js +0 -1
  1124. package/apps/pwa/out/_next/static/chunks/7235-e583e4a015e159b9.js +0 -1
  1125. package/apps/pwa/out/_next/static/chunks/7482-7b417330b24a996a.js +0 -1
  1126. package/apps/pwa/out/_next/static/chunks/7701-99b7d4dedb955bf8.js +0 -1
  1127. package/apps/pwa/out/_next/static/chunks/77f1928d-bd3777589042d3ea.js +0 -1
  1128. package/apps/pwa/out/_next/static/chunks/8366-36956cafc5e33614.js +0 -1
  1129. package/apps/pwa/out/_next/static/chunks/8370-23d0de995be666f8.js +0 -1
  1130. package/apps/pwa/out/_next/static/chunks/8617-307421f3b0e8b2a2.js +0 -1
  1131. package/apps/pwa/out/_next/static/chunks/8837-e45de46a9fedf1f5.js +0 -1
  1132. package/apps/pwa/out/_next/static/chunks/9058-0e8055a5ea3ebdd6.js +0 -1
  1133. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-84b84eca12acada4.js +0 -1
  1134. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-1f23568c29e88f7a.js +0 -1
  1135. package/apps/pwa/out/_next/static/chunks/app/botlab/page-bf6fc9aafd6135a7.js +0 -1
  1136. package/apps/pwa/out/_next/static/chunks/app/bots/page-3f8539ae4b719d2e.js +0 -1
  1137. package/apps/pwa/out/_next/static/chunks/app/chat/page-d2900febb74ecf32.js +0 -1
  1138. package/apps/pwa/out/_next/static/chunks/app/control/page-e82dec647dd79c36.js +0 -1
  1139. package/apps/pwa/out/_next/static/chunks/app/dashboard/page-096ec743a8ee955a.js +0 -1
  1140. package/apps/pwa/out/_next/static/chunks/app/design-check/page-255c2ceded4b3493.js +0 -1
  1141. package/apps/pwa/out/_next/static/chunks/app/healthz/route-84b84eca12acada4.js +0 -1
  1142. package/apps/pwa/out/_next/static/chunks/app/intake/page-2db61b2f9efba61f.js +0 -1
  1143. package/apps/pwa/out/_next/static/chunks/app/layout-e11ee17f221aaa9b.js +0 -1
  1144. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e075974e029ce4c4.js +0 -1
  1145. package/apps/pwa/out/_next/static/chunks/app/morning/page-ec5b68a9af3366a0.js +0 -1
  1146. package/apps/pwa/out/_next/static/chunks/app/not-found-986c177afb4adae6.js +0 -1
  1147. package/apps/pwa/out/_next/static/chunks/app/observatory/page-a72781461af2f2a3.js +0 -1
  1148. package/apps/pwa/out/_next/static/chunks/app/page-92781cbaafc487ad.js +0 -1
  1149. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2c14d2a1f2930f33.js +0 -1
  1150. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-22ee4bf8070b2b4d.js +0 -1
  1151. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9c06e4a8297942a8.js +0 -1
  1152. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d0cd32f6d373798f.js +0 -1
  1153. package/apps/pwa/out/_next/static/chunks/app/settings/page-0c1642018d87ebb8.js +0 -1
  1154. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-93e5e97d614df487.js +0 -1
  1155. package/apps/pwa/out/_next/static/chunks/app/setup/layout-84b84eca12acada4.js +0 -1
  1156. package/apps/pwa/out/_next/static/chunks/app/setup/page-b1ce871940d7393e.js +0 -1
  1157. package/apps/pwa/out/_next/static/chunks/app/share/page-ae154addf345febe.js +0 -1
  1158. package/apps/pwa/out/_next/static/chunks/app/showroom/page-90af3aa813d2053c.js +0 -1
  1159. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f3f962fda428a738.js +0 -1
  1160. package/apps/pwa/out/_next/static/chunks/app/term/page-1c1f7cc1d5def06d.js +0 -1
  1161. package/apps/pwa/out/_next/static/chunks/app/vault/page-09d4cbdaaacf06c1.js +0 -1
  1162. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e877b8e8ca90b27f.js +0 -1
  1163. package/apps/pwa/out/_next/static/chunks/app/workflows/page-71d902f463dea526.js +0 -1
  1164. package/apps/pwa/out/_next/static/chunks/app/workspace/page-40ea576cefa25fe6.js +0 -1
  1165. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a56a3f178c3831f6.js +0 -1
  1166. package/apps/pwa/out/_next/static/chunks/bcc499d1-804a270d878e0842.js +0 -1
  1167. package/apps/pwa/out/_next/static/chunks/framework-b25b7c5501c59b6d.js +0 -1
  1168. package/apps/pwa/out/_next/static/chunks/main-a9ec9da43387afff.js +0 -1
  1169. package/apps/pwa/out/_next/static/chunks/main-app-aa2c05954aaa6754.js +0 -1
  1170. package/apps/pwa/out/_next/static/chunks/pages/_app-bb3768fb4b84aebb.js +0 -1
  1171. package/apps/pwa/out/_next/static/chunks/pages/_error-2820ba75b87b2f5e.js +0 -1
  1172. package/apps/pwa/out/_next/static/chunks/webpack-58c73b145f189b1c.js +0 -1
  1173. package/apps/pwa/out/_next/static/css/effec8adf767aa75.css +0 -1
  1174. package/apps/pwa/out/dashboard/index.html +0 -1
  1175. package/apps/pwa/out/dashboard/index.txt +0 -26
  1176. package/src/acp/resident-shell.ts +0 -244
  1177. package/src/agent/spawn-local-llm-in-vw.ts +0 -240
  1178. package/src/dashboard/agent-spawn-tools-boot.ts +0 -14
  1179. package/src/dashboard/dock-picker-inventory.ts +0 -41
  1180. package/src/dashboard/goal-plan-hud-bridge.ts +0 -112
  1181. package/src/dashboard/hud-mirror.ts +0 -207
  1182. package/src/dashboard/input/mouse-dock-runtime.ts +0 -156
  1183. package/src/dashboard/input/mouse-hover-runtime.ts +0 -46
  1184. package/src/dashboard/input/mouse-pill-context-runtime.ts +0 -74
  1185. package/src/dashboard/input/mouse-workspace-restore-runtime.ts +0 -64
  1186. package/src/dashboard/input/scratch-actions.ts +0 -36
  1187. package/src/dashboard/input/virtual-window-key-router.ts +0 -24
  1188. package/src/dashboard/rich-scratch-viewers.ts +0 -77
  1189. package/src/dashboard/scratch-slash-runtime.ts +0 -36
  1190. package/src/dashboard/scratch-state-runtime.ts +0 -42
  1191. package/src/dashboard/scratch-widget-runtime.ts +0 -37
  1192. package/src/dashboard/sim-shell.ts +0 -313
  1193. package/src/dashboard/virtual-window-control-runtime.ts +0 -57
  1194. package/src/dashboard/virtual-window-help-runtime.ts +0 -113
  1195. package/src/dashboard/virtual-window-input-runtime.ts +0 -99
  1196. package/src/dashboard/virtual-window-mutation-runtime.ts +0 -102
  1197. package/src/dashboard/virtual-window-split-runtime.ts +0 -70
  1198. package/src/dashboard/vw-popup-openers.ts +0 -126
  1199. package/src/dashboard/window-picker-popup.ts +0 -74
  1200. package/src/dashboard/window-slash-runtime.ts +0 -108
  1201. package/src/dashboard/windowing/companion-slash.ts +0 -78
  1202. package/src/dashboard/windowing/fast-switch.ts +0 -138
  1203. package/src/dashboard/windowing/lifecycle.ts +0 -185
  1204. package/src/dashboard/windowing/virtual-windows.ts +0 -259
  1205. package/src/dashboard/windowing/visibility-chord.ts +0 -77
  1206. package/src/iul/resident-vw.ts +0 -55
  1207. package/src/panes/content-adapter.ts +0 -162
  1208. package/src/prompt/vw-reference.ts +0 -153
  1209. package/src/shell-runner/external-terminal-pane.ts +0 -157
  1210. package/src/sim/resident-vw.ts +0 -48
  1211. package/src/skills/tools/spawn-coding-agent-vw.ts +0 -181
  1212. package/src/skills/tools/virtual-windows.ts +0 -632
  1213. package/src/surface/adapters/window-surface-adapter.ts +0 -141
  1214. package/src/tool-runtime/layout-runtimes.ts +0 -81
  1215. package/src/tool-runtime/scenario-window-mount.ts +0 -207
  1216. package/src/views/ui-mode.ts +0 -100
  1217. package/src/virtual-window-context-menu.ts +0 -97
  1218. package/src/virtual-windows/addressing.ts +0 -195
  1219. package/src/virtual-windows/benchmark-preset.ts +0 -119
  1220. package/src/virtual-windows/event-bus.ts +0 -202
  1221. package/src/virtual-windows/layout/apply-planner.ts +0 -189
  1222. package/src/virtual-windows/layout/index.ts +0 -68
  1223. package/src/virtual-windows/layout/layout-commands.ts +0 -186
  1224. package/src/virtual-windows/layout/layout-tools.ts +0 -262
  1225. package/src/virtual-windows/layout/persistence.ts +0 -219
  1226. package/src/virtual-windows/layout/presets.ts +0 -114
  1227. package/src/virtual-windows/layout/restore-planner.ts +0 -223
  1228. package/src/virtual-windows/layout/serializer.ts +0 -197
  1229. package/src/virtual-windows/layout/tree.ts +0 -147
  1230. package/src/virtual-windows/layout/types.ts +0 -63
  1231. package/src/virtual-windows/layout-tree.ts +0 -389
  1232. package/src/virtual-windows/navigation.ts +0 -251
  1233. package/src/virtual-windows/pane-capture.ts +0 -142
  1234. package/src/virtual-windows/pane-content.ts +0 -611
  1235. package/src/virtual-windows/pane-spawner.ts +0 -278
  1236. package/src/virtual-windows/pty-tail-content.ts +0 -291
  1237. package/src/virtual-windows/resident-window.ts +0 -59
  1238. package/src/virtual-windows/secondary-action.ts +0 -25
  1239. package/src/virtual-windows/terminal-slot-content.ts +0 -165
  1240. package/src/virtual-windows/virtual-window.ts +0 -1301
  1241. package/src/virtual-windows/vw-local-input-target-popup.ts +0 -110
  1242. package/src/virtual-windows/vw-rename-modal.ts +0 -77
  1243. package/src/virtual-windows/vw-selector-popup.ts +0 -177
  1244. package/src/virtual-windows/window-registry.ts +0 -519
  1245. package/src/voice/channel-adapters/discord-voice-adapter.ts +0 -202
  1246. package/src/voice/voice-pwa-dispatch.ts +0 -245
  1247. package/src/window-picker-modal.ts +0 -135
  1248. /package/apps/pwa/out/_next/static/{Ksn99fVf2HUWhSyV1-FC8 → ktMqfrBbf8BMGac0jqLrb}/_ssgManifest.js +0 -0
  1249. /package/src/dashboard/{companion-slash-runtime.ts → companion-messages-runtime.ts} +0 -0
@@ -28,6 +28,10 @@ import {
28
28
  import { nexusLockPath, nexusRuntimePath, nexusRootDir } from './paths.js';
29
29
  import { createPwaRegistration, type PwaRegistrationDeps } from './pwa-registration.js';
30
30
  import { resolveCurrentInstance } from '../instance/current.js';
31
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
32
+ import { startPortLeaseHeartbeat } from '../control-plane/port-lease-heartbeat.js';
33
+ import { PORT_BANDS } from '../control-plane/ports.js';
34
+ import { DEFAULT_NEXUS_HTTP_PORT } from './default-port.js';
31
35
  import { createNexusState } from './state/state.js';
32
36
  import { TabRegistry } from './state/tab-registry.js';
33
37
  import { createChatTabSpec } from './kinds/chat.js';
@@ -71,10 +75,12 @@ import { registerAllCloudBackends } from './config/secrets/register-cloud.js';
71
75
  // → nexus/webterm/pty.ts 통합. `MiniTerminal` class + `createMiniTermSpawn`
72
76
  // 은 TUI-only 였고 T4 이후 dead → 정리. `PtyBackend` + `createWebtermSpawn`
73
77
  // 만 살아남아 iOS/PWA webterm 의 PTY substrate 로 사용.
74
- import { type PtyBackend, createWebtermSpawn } from './webterm/pty.js';
78
+ import { type PtyBackend, createWebtermSpawn, resolveWebtermCwd } from './webterm/pty.js';
75
79
  import { SettingsTabController } from './config/settings-controller.js';
76
80
  import { tryRegisterSettings } from './boot/register-settings.js';
77
81
  import { registerMcpClients, type McpClientsHandle } from './boot/register-mcp-clients.js';
82
+ import { syncInstalledPluginNodes } from '../graph-kinds/installed-plugin-nodes.js';
83
+ import { elanousStateRoot } from '../autopilot/state-paths.js';
78
84
  import type { McpReloadOutcome, McpReloadServerResult } from './api/admin-mcp-reload.js';
79
85
  import { loadOrCreateSigningKey, NonceStore } from './api/edit-in-pwa-core.js';
80
86
  import { subscribeErrorSnapshotWriter } from './supervisor/error-snapshot.js';
@@ -104,6 +110,9 @@ import {
104
110
  import { discoverWorkflows as discoverWorkflowsForDaemon } from '../workflow-runtime/discovery.js';
105
111
  import { buildDefaultWorkflowDeps as buildWorkflowDaemonDeps } from './api/workflows.js';
106
112
  import { startNexusHttpServer, type NexusHttpServer, type NexusWsBridgeInit } from './api/http-server.js';
113
+ import { startControlServer } from '../control-plane/server.js';
114
+ import { nexusMemberMachine, startMemberHeartbeat } from '../control-plane/member.js';
115
+ import { resolvePrimary } from '../control-plane/primary.js';
107
116
  import { cleanGhostTailscaleServe } from '../cli/tailscale-serve.js';
108
117
  import { buildNextFluentRouteOpts } from './api/next-fluent-wiring.js';
109
118
  import { bootDefaultOcrProviders, type OcrRegistry } from '../ocr/index.js';
@@ -208,6 +217,7 @@ import { fetchCodexPlugins } from '../acp/codex-plugins.js';
208
217
  import { globalAgentCliConversationStore } from './api/agent-cli-conversation-store.js';
209
218
  import { globalMissionRouter } from '../llm/mission-router.js';
210
219
  import { getUserConfig, type UserConfig } from '../user-config.js';
220
+ import { resolveChannelBotToken } from '../channel-bot-token.js';
211
221
  import { debug } from '../debug/log.js';
212
222
  import { createNotificationActionLoopback } from '../web-push/notification-action-loopback.js';
213
223
  import {
@@ -218,7 +228,8 @@ import type {
218
228
  AcpConnectionHandler,
219
229
  AcpTransportServer,
220
230
  } from '../acp/transport/types.js';
221
- import { createAuthVerifier, type AcpAuthTokenRecord } from '../acp/transport/auth.js';
231
+ import { createAuthVerifier, type AcpAuthTokenRecord, type AcpAuthVerifier } from '../acp/transport/auth.js';
232
+ import { matchTempToken } from '../auth/temp-tokens.js';
222
233
  import { loadEnvelope, type TokenStoreEnvelope, type TokenStorePaths } from '../auth/token-store.js';
223
234
  import {
224
235
  createVoiceRestHandler,
@@ -229,15 +240,14 @@ import {
229
240
  type PwaVoiceAdapter,
230
241
  } from '../voice/channel-adapters/pwa-voice-adapter.js';
231
242
  import { getIntakeStore } from '../intake-plane/runtime.js';
232
- import { existsSync, readFileSync } from 'node:fs';
233
243
  import { join as joinPath } from 'node:path';
234
- import { getElanousConfigDir } from '../elanous-config-dir.js';
244
+ import { ensureAuthToken } from '../auth/acp-token.js';
235
245
  import type { SupervisorSpawnBackend } from './supervisor/spawn.js';
236
246
  import type { HealthProbeBackend } from './supervisor/health.js';
237
247
  import { gracefulExit, cleanExit } from './supervisor/graceful-exit.js';
238
248
  import { restoreFromPending } from './supervisor/restore-state.js';
239
249
  import { resolveHeadlessMode } from './headless-mode.js';
240
- import { checkSetupStatus, renderSetupStatus } from './setup-status.js';
250
+ import { checkSetupStatus, readNexusSetupMode, renderSetupStatus, setupBootMode, setupModeBootPlan } from './setup-status.js';
241
251
  import { probeTailscale } from './onboarding/tailscale-probe.js';
242
252
  import {
243
253
  runPwaSharePrompt,
@@ -248,12 +258,17 @@ import { runFirstBootWizard } from './onboarding/first-boot-wizard.js';
248
258
  // Phase 2 of RESEARCH-tox-surface-agnostic-boot-2026-05-13 — surface-
249
259
  // agnostic TOX bootstrap + subagent surface bridge to globalAgentRegistry.
250
260
  import { wireTox, type ToxBootHandle } from '../task-orchestrator/boot.js';
261
+ import { createExternalExecAdapter } from '../task-orchestrator/surfaces/external-exec.js';
262
+ import { dispatchSelfImplement } from '../boot/daemon-tools/self-implement.js';
263
+ import { TaskStore, hydrateGraph } from '../task-orchestrator/store.js';
251
264
  import { createGlobalSubagentCallable } from '../agent/subagent-callable.js';
252
265
  import { setAgentHopCap } from '../agent/registry.js';
253
266
  import type { SidebarTabSurface } from '../ui/widgets/sidebar-tab-surface.js';
254
267
  import { defaultIO, runOnboardingStep, type WizardIO } from '../onboarding.js';
268
+ import { packageVersion } from '../version/code-revision.js';
255
269
 
256
- export const NEXUS_VERSION = '0.17.0';
270
+ // 데몬 배너·`nexus status`·연결 라벨이 보이는 판 = 제품 판(`package.json`) — 옛 내부 상수 `0.17.0` 이 0.2.x 제품 옆에 떴다(🅞 M5 · M5c).
271
+ export const NEXUS_VERSION = packageVersion();
257
272
  export const NEXUS_PHASE = 'N-5 PR χ (graceful exit + restart pending)';
258
273
 
259
274
  type TelegramAgentRunTurnFactory = typeof import('../telegram-agent.js').makeTelegramAgentRunTurn;
@@ -285,11 +300,10 @@ export function wireNexusTelegramQaPollers(
285
300
  deps: NexusTelegramQaPollerWireDeps,
286
301
  ): NexusTelegramQaPollerWireHandle[] {
287
302
  const handles: NexusTelegramQaPollerWireHandle[] = [];
288
- const pollers = deps.interactivePollerTokens(deps.resolveTelegramChannels(cfg.telegram));
303
+ const mainToken = resolveChannelBotToken('telegram', cfg)?.token;
304
+ const pollers = deps.interactivePollerTokens(deps.resolveTelegramChannels({ ...cfg.telegram, botToken: mainToken }));
289
305
  for (const channelConfig of pollers) {
290
- const channelScopedConfig = channelConfig.botToken === cfg.telegram.botToken
291
- ? cfg
292
- : { ...cfg, telegram: { ...cfg.telegram, botToken: channelConfig.botToken } };
306
+ const channelScopedConfig = { ...cfg, telegram: { ...cfg.telegram, botToken: channelConfig.botToken } };
293
307
  const start = (release?: () => void): NexusTelegramQaPollerWireHandle | null => {
294
308
  const handle = deps.createTriggerBot({
295
309
  token: channelConfig.botToken,
@@ -386,12 +400,16 @@ export interface RunNexusOptions {
386
400
  * registry stays empty so the dispatcher's webterm interception
387
401
  * is a no-op). */
388
402
  webtermSpawn?: (spec: { id: string; cwd?: string }) => PtyBackend;
403
+ /** Explicitly disable HTTP and ACP websocket token auth for this run. */
404
+ noAuth?: boolean;
389
405
  /** Skip the HTTP API server boot. Default: true in tests via
390
406
  * detachForTesting; production runs always start the server. Tests
391
407
  * that DO want the server can pass false explicitly. */
392
408
  skipHttpServer?: boolean;
393
409
  /** Override starting port for the HTTP server. Defaults to 31415. */
394
410
  httpStartPort?: number;
411
+ /** Control-plane port; passing 0 also enables an isolated listener in detached tests. */
412
+ controlPort?: number;
395
413
  /** Override host for the HTTP server. Defaults to '127.0.0.1'. */
396
414
  httpHost?: string;
397
415
  /** Test seam for the best-effort stale Tailscale Serve cleanup before bind. */
@@ -551,6 +569,8 @@ export interface RunNexusOptions {
551
569
  mountShareIfEnabledFn?: (opts: { httpPort: number }) => Promise<import('../cli/share-auto-mount.js').ShareMountResult>;
552
570
  /** Test-only replacement for the headless Tailscale Serve unmount on shutdown. */
553
571
  pwaShareDisableFn?: typeof import('../cli/pwa-share.js').pwaShareDisable;
572
+ /** Test-only share reconciliation cadence; production checks every 60 seconds. */
573
+ shareCoordinatorIntervalMsForTesting?: number;
554
574
  /** Test-only completion signal that lets the real headless branch exit without a process signal. */
555
575
  headlessDoneForTesting?: Promise<void>;
556
576
  /** Skip the interactive setup prerequisite only while exercising the real headless branch in tests. */
@@ -638,7 +658,7 @@ export interface RunNexusHandle {
638
658
  /** ACP WS auth gate for the NEXUS HTTP bridge.
639
659
  * Same shape as `src/boot/acp-server.ts` websocket auth: pass
640
660
  * `createAuthVerifier` only when a bearer token is configured;
641
- * omit the field entirely for first-boot tokenless dogfood.
661
+ * explicit no-auth opt-out omits the verifier.
642
662
  * ⛔ `noAuth` was declared on WsBridgeOpts but the bridge NEVER read it
643
663
  * (0 executable references) while this file assigned it — a value that
644
664
  * flowed in and died. We removed the field rather than leave a knob that
@@ -695,14 +715,49 @@ export function buildNexusWsBridgeAuth(
695
715
  bearerToken: string | undefined,
696
716
  paths?: TokenStorePaths,
697
717
  ): Pick<NexusWsBridgeInit, 'wsAuthVerifier'> {
698
- // ⛔ 첫 부팅 무인증 도그푸드는 그대로다 — 부팅 토큰이 «없으면» 검증기를 안 넘긴다.
718
+ // Explicit opt-out supplies no boot token, so the bridge has no verifier.
699
719
  if (!bearerToken) return {};
700
720
  return {
701
721
  // ⭐ 배열이 아니라 «공급자» — 매 핸드셰이크마다 봉투를 다시 읽는다.
702
- wsAuthVerifier: createAuthVerifier(() => acceptedAcpTokens(bearerToken, paths)),
722
+ wsAuthVerifier: withTempTokens(createAuthVerifier(() => acceptedAcpTokens(bearerToken, paths)), paths?.configDir),
703
723
  };
704
724
  }
705
725
 
726
+ /** 단기 소유자 토큰(`elanous token issue`)도 ACP 웹소켓에서 받는다 — 기존 검증이 거부할 때만 해시·만료로 한 번 더 본다. */
727
+ function withTempTokens(base: AcpAuthVerifier, dir?: string): AcpAuthVerifier {
728
+ return {
729
+ verify(raw) {
730
+ const first = base.verify(raw);
731
+ if (first.ok) return first;
732
+ const token = (raw as { token?: unknown } | null)?.token;
733
+ return typeof token === 'string' && matchTempToken(token, dir ? { dir } : {}) ? { ok: true } : first;
734
+ },
735
+ };
736
+ }
737
+
738
+ /**
739
+ * 관제부가 준 포트 임대(`ELANOUS_TEST_COORDINATOR_LEASE_PORT`)로 뜨는 자식이 «그 포트로만» 뜨는지 Nexus 락을 잡기 «전»에 확인한다.
740
+ * 임대가 없으면 undefined, 있으면 그 포트를 돌려준다 — 조건이 하나라도 어긋나면 throw.
741
+ */
742
+ export function checkLauncherLeaseBoot(
743
+ opts: Pick<RunNexusOptions, 'httpStartPort' | 'skipHttpServer' | 'detachForTesting'>,
744
+ env: NodeJS.ProcessEnv,
745
+ instanceKind: () => string,
746
+ ): number | undefined {
747
+ const launcherLease = env.ELANOUS_TEST_COORDINATOR_LEASE_PORT;
748
+ if (launcherLease === undefined) return undefined;
749
+ const leasePort = Number(launcherLease);
750
+ if (!env.ELANOUS_TEST_COORDINATOR_LEASE_ID?.trim()) throw new Error('missing coordinator lease id');
751
+ if (instanceKind() !== 'test' ||
752
+ !Number.isInteger(leasePort) ||
753
+ leasePort < PORT_BANDS.test.start || leasePort > PORT_BANDS.test.end ||
754
+ opts.httpStartPort !== leasePort ||
755
+ (opts.skipHttpServer ?? !!opts.detachForTesting)) {
756
+ throw new Error('coordinator port lease boot mismatch');
757
+ }
758
+ return leasePort;
759
+ }
760
+
706
761
  export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHandle | undefined> {
707
762
  if (opts.status) {
708
763
  await printStatus();
@@ -713,6 +768,15 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
713
768
  return undefined;
714
769
  }
715
770
 
771
+ const leasePortFromLauncher = checkLauncherLeaseBoot(opts, process.env, () => resolveCurrentInstance().kind);
772
+ const noAuth = opts.noAuth === true || process.env.ELANOUS_NEXUS_NO_AUTH === '1';
773
+ // Resolve before acquiring the daemon lock or binding HTTP. A broken token
774
+ // store must fail closed without leaving a half-booted Nexus behind.
775
+ const httpBootEnabled = !(opts.skipHttpServer ?? !!opts.detachForTesting);
776
+ const needsToken = httpBootEnabled && !(opts.skipRuntimeApi ?? !!opts.detachForTesting) && !noAuth;
777
+ const bearerToken = needsToken ? ensureAuthToken().token : undefined;
778
+ if (needsToken && !bearerToken) throw new Error('Nexus auth token is empty');
779
+
716
780
  // 설치본 전환 RFC 0b — 키는 launchd plist 가 아니라 키 캐시에서(캐시 우선 · 자식도 물려받는다). 값은 안 찍고 «이름만».
717
781
  if (!opts.detachForTesting) {
718
782
  const { hydrateEnvFromKeyCache } = await import('../config.js');
@@ -723,13 +787,34 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
723
787
  const headless = resolveHeadlessMode({ ...(opts.headless !== undefined ? { headless: opts.headless } : {}) });
724
788
  if (headless && !opts.detachForTesting && !opts.skipHeadlessSetupCheckForTesting) {
725
789
  const setup = checkSetupStatus({ argvBin: process.argv[1] ?? '' });
726
- if (!setup.ok) {
790
+ const boot = setupBootMode(setup);
791
+ if (boot.mode === 'refuse') {
727
792
  console.error('✗ elanous nexus --headless: setup incomplete');
728
793
  renderSetupStatus(setup, console);
729
794
  console.log('');
730
795
  console.log(' Run `elanous nexus` (interactive) once to walk through the wizard.');
731
796
  process.exit(1);
732
797
  }
798
+ if (boot.mode === 'setup') {
799
+ process.env.ELANOUS_NEXUS_SETUP_MODE = '1';
800
+ const host = opts.httpHost ?? '127.0.0.1';
801
+ const port = opts.httpStartPort ?? DEFAULT_NEXUS_HTTP_PORT;
802
+ console.log(`셋업 모드로 떴습니다 — 브라우저로 셋업: http://${host}:${port}/app/setup/ (빠진 것: ${boot.missing.join(', ')})`);
803
+ }
804
+ }
805
+
806
+ // 기동 때 한 번. 요청마다 다시 읽지 않고 이 값을 탭·크론·health 에 넘긴다.
807
+ // 셋업이 채워진 뒤 정상 모드로 넘어가는 것은 재시작 한 번이다 — 자동 전환은 짓지 않는다.
808
+ const nexusSetup = readNexusSetupMode(process.env);
809
+ const setupPlan = setupModeBootPlan(nexusSetup.setupMode);
810
+ debug.log('nexus.boot', 'setup-mode-plan', {
811
+ setupMode: nexusSetup.setupMode,
812
+ setupMissing: nexusSetup.setupMissing,
813
+ skipTabKinds: setupPlan.skipTabKinds,
814
+ skipCrons: setupPlan.skipCrons,
815
+ });
816
+ if (nexusSetup.setupMode) {
817
+ console.log('셋업 모드 — 채널 봇·크론은 셋업 뒤 재시작 때 켜진다');
733
818
  }
734
819
 
735
820
  // #24 — 이벤트루프 stall watchdog(2026-07-21). 데몬 메인스레드가 무한루프로 굶으면(telegram 폴링
@@ -816,6 +901,9 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
816
901
  return run;
817
902
  };
818
903
 
904
+ let stopCoordinatorLease: (() => Promise<void>) | undefined;
905
+ let leaseReleasePending: Promise<void> | undefined;
906
+
819
907
  let release: () => void;
820
908
  try {
821
909
  release = acquireNexusLock({ label: 'nexus', ...(opts.force ? { force: true } : {}) });
@@ -839,6 +927,22 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
839
927
  throw err;
840
928
  }
841
929
 
930
+ if (leasePortFromLauncher !== undefined) {
931
+ try {
932
+ stopCoordinatorLease = await startPortLeaseHeartbeat(leasePortFromLauncher, process.env.ELANOUS_TEST_COORDINATOR_LEASE_ID!, {
933
+ ...(process.env.ELANOUS_TEST_COORDINATOR_LEASE_TOKEN ? { token: process.env.ELANOUS_TEST_COORDINATOR_LEASE_TOKEN } : {}),
934
+ onError: error => debug.log('control.port-lease', 'renew-failed', { port: leasePortFromLauncher, reason: error.message }, { level: 'warn' }),
935
+ onLeaseLost: error => {
936
+ try { debug.log('control.port-lease', 'lease-lost', { port: leasePortFromLauncher, reason: error.message }, { level: 'error' }); }
937
+ finally { process.exit(1); }
938
+ },
939
+ });
940
+ } catch (error) {
941
+ release();
942
+ throw error;
943
+ }
944
+ }
945
+
842
946
  const startedAt = new Date().toISOString();
843
947
  const runtime: NexusRuntimeMeta = {
844
948
  pid: process.pid,
@@ -881,18 +985,21 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
881
985
  });
882
986
  const startLevel = resolvedLevel.level;
883
987
  dbgMod.debug.setLevel(startLevel);
988
+ if (httpBootEnabled && noAuth) {
989
+ dbgMod.debug.log('nexus.auth', 'explicit-opt-out', {
990
+ source: opts.noAuth === true ? '--no-auth' : 'ELANOUS_NEXUS_NO_AUTH',
991
+ }, { level: 'warn' });
992
+ }
884
993
  dbgMod.debug.log('logging.level', 'startup-resolved', {
885
994
  level: startLevel, source: resolvedLevel.source,
886
995
  gateOpen: scopedMod.hotPathGateOpen(startLevel), surface: 'nexus',
887
996
  });
888
997
  dbgMod.debug.setFileEnabled(dbgCfg.file);
889
- // OH9 — 렌더 무음 시드(레벨 직교). 데몬은 uiMode 가 없으므로
890
- // essential=false(기본 비억제) — level.json.render 명시 또는
998
+ // OH9 — 렌더 무음 시드(레벨 직교). 데몬은 기본 비억제 — level.json.render 명시 또는
891
999
  // config.debug.renderLogs 만 억제/override 를 결정한다.
892
1000
  dbgMod.debug.setRenderSuppressed(scopedMod.resolveRenderSuppressed({
893
1001
  scopedRender: scopedMod.readScopedRenderLogs(),
894
1002
  configRenderLogs: dbgCfg.renderLogs,
895
- uiModeEssential: false,
896
1003
  }));
897
1004
  if (dbgCfg.file) {
898
1005
  console.log(`debug: level=${dbgMod.debug.level()} file: ${dbgMod.debug.path()}`);
@@ -1116,6 +1223,18 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1116
1223
 
1117
1224
  const skipHttp = opts.skipHttpServer ?? !!opts.detachForTesting;
1118
1225
  let httpServer: NexusHttpServer | undefined;
1226
+ let stopMemberHeartbeat: (() => void) | undefined;
1227
+ // ⛔ 관제부는 운영 넥서스와 «별도 프로세스»다(RFC 관제 평면 A2 · P0 골 경계) — 넥서스는 기본으로 띄우지 않는다.
1228
+ // 🩸 2026-09-27: 넥서스 부팅이 31413 을 늘 잡고 실패하면 throw 해서, 운영이 31413 을 쥔 뒤엔 모든 격리 데몬(`nexus run --test`)이
1229
+ // 부팅에서 죽을 뻔했다. 명시(`controlPort`)일 때만 띄우고, 실패해도 넥서스 부팅은 막지 않는다(관측만).
1230
+ let controlServer: ReturnType<typeof startControlServer> | undefined;
1231
+ if (opts.controlPort !== undefined) {
1232
+ try {
1233
+ controlServer = startControlServer({ port: opts.controlPort });
1234
+ } catch (err) {
1235
+ debug.log('control.server', 'start-failed-in-nexus', { port: opts.controlPort, reason: (err as Error).message }, { level: 'warn' });
1236
+ }
1237
+ }
1119
1238
  // Surface-unification v2.1 FU-3 (2026-05-11) — workflow-runtime
1120
1239
  // daemon. Owns trigger source lifecycle (schedule/webhook/discord/
1121
1240
  // telegram/chat). Schedule + webhook + chat fire from in-process
@@ -1128,6 +1247,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1128
1247
  // (PWA Intake, iPhone, ACP, MCP, future). Disposed in the shutdown
1129
1248
  // hook below.
1130
1249
  let toxHandle: ToxBootHandle | undefined;
1250
+ let toxStore: TaskStore | undefined;
1131
1251
  // §5-③ — autonomous idle-continuation scheduler. Only constructed when
1132
1252
  // `dispatch.enabled` is set (default off); stopped in the shutdown hook.
1133
1253
  let continuationScheduler: import('../dispatch/continuation-scheduler.js').ContinuationScheduler | undefined;
@@ -1237,6 +1357,10 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1237
1357
  current: () => false,
1238
1358
  };
1239
1359
 
1360
+ // Installed graph kinds do not depend on the runtime API or MCP server configuration.
1361
+ try { syncInstalledPluginNodes(elanousStateRoot()); }
1362
+ catch (error) { debug.log('graph.kinds', 'installed-sync-failed', { reason: String(error) }); }
1363
+
1240
1364
  if (!skipRuntime) {
1241
1365
  // Tool surface — flag · env · UserConfig switch · switch default.
1242
1366
  // See resolveToolsKind() jsdoc for resolution order.
@@ -1822,7 +1946,16 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1822
1946
  if (!tab || tab.spec.kind !== 'webterm') return;
1823
1947
  const cwdMeta = (tab.spec.meta as { cwd?: string } | undefined)?.cwd;
1824
1948
  const backendFactory = effectiveWebtermSpawn
1825
- ? () => effectiveWebtermSpawn({ id: tab.spec.id, ...(cwdMeta ? { cwd: cwdMeta } : {}) })
1949
+ ? () => {
1950
+ const decided = resolveWebtermCwd({
1951
+ ...(cwdMeta ? { tabCwd: cwdMeta } : {}),
1952
+ ...(runtimeToolCwd ? { toolCwd: runtimeToolCwd } : {}),
1953
+ instance: resolveCurrentInstance(),
1954
+ processCwd: process.cwd(),
1955
+ });
1956
+ debug.log('nexus.webterm', 'spawn-cwd', { tabId: tab.spec.id, cwd: decided.cwd, source: decided.source });
1957
+ return effectiveWebtermSpawn({ id: tab.spec.id, cwd: decided.cwd });
1958
+ }
1826
1959
  : undefined;
1827
1960
  const session = new NexusWebtermSession({
1828
1961
  ...(backendFactory ? { spawn: backendFactory } : {}),
@@ -1873,7 +2006,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1873
2006
 
1874
2007
  if (!skipHttp) {
1875
2008
  const httpHost = opts.httpHost ?? '127.0.0.1';
1876
- const httpStartPort = opts.httpStartPort ?? 31415;
2009
+ const httpStartPort = opts.httpStartPort ?? DEFAULT_NEXUS_HTTP_PORT;
1877
2010
  const editInPwaCtx = {
1878
2011
  signingKey: editInPwaSigningKey,
1879
2012
  nonceStore: editInPwaNonceStore,
@@ -1888,11 +2021,6 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1888
2021
  let metaApiOpts: import('./api/meta-api.js').MetaApiOpts | undefined;
1889
2022
 
1890
2023
  if (!skipRuntime && runtimeHistory) {
1891
- // Bearer token — read from getElanousConfigDir()/acp-token (the
1892
- // canonical store `elanous serve` uses). Loopback default is
1893
- // noAuth; tests opt in by writing a token file before boot.
1894
- const bearerToken = readAcpToken();
1895
-
1896
2024
  // Voice REST + adapter. createVoiceRestHandler is stateless;
1897
2025
  // the STT provider singleton (getDaemonSttProvider) returns
1898
2026
  // null until `initDaemonSttProvider()` is called — fine, the
@@ -1928,34 +2056,32 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1928
2056
  const streamingStt = getDaemonStreamingSttProvider();
1929
2057
  const ttsProvider = getDaemonTtsProvider();
1930
2058
  if (streamingStt) {
1931
- const { createPwaVoiceAdapter, isPwaVoiceEnabled } =
2059
+ const { createPwaVoiceAdapter } =
1932
2060
  await import('../voice/channel-adapters/pwa-voice-adapter.js');
1933
- if (isPwaVoiceEnabled()) {
1934
- if (ttsProvider) {
1935
- const { createPwaTtsBridge } =
1936
- await import('../voice/voice-pwa-tts-bridge.js');
1937
- pwaTtsBridge = createPwaTtsBridge({ ttsProvider });
1938
- // FU-2 webterm wire — same instance the ACP server
1939
- // dereferences via the holder wrapper (line ~547).
1940
- // chat REST path uses local var below; both reach
1941
- // the same per-session bridge.
1942
- pwaTtsBridgeHolder.current = pwaTtsBridge;
1943
- }
1944
- const bridge = pwaTtsBridge;
1945
- realPwaAdapter = createPwaVoiceAdapter({
1946
- sttProvider: streamingStt,
1947
- onSessionOpen: (session) => {
1948
- if (bridge && session.sessionId && session.emitDownstream) {
1949
- const emit = session.emitDownstream.bind(session);
1950
- bridge.attach(session.sessionId, (frame) => emit(frame));
1951
- }
1952
- },
1953
- onSessionClose: (session) => {
1954
- if (bridge && session.sessionId) bridge.detach(session.sessionId);
1955
- },
1956
- });
1957
- console.log(`voice: NEXUS PWA WS adapter functional (streaming STT wired · TTS bridge ${bridge ? 'wired' : 'absent (no TTS provider)'})`);
2061
+ if (ttsProvider) {
2062
+ const { createPwaTtsBridge } =
2063
+ await import('../voice/voice-pwa-tts-bridge.js');
2064
+ pwaTtsBridge = createPwaTtsBridge({ ttsProvider });
2065
+ // FU-2 webterm wire — same instance the ACP server
2066
+ // dereferences via the holder wrapper (line ~547).
2067
+ // chat REST path uses local var below; both reach
2068
+ // the same per-session bridge.
2069
+ pwaTtsBridgeHolder.current = pwaTtsBridge;
1958
2070
  }
2071
+ const bridge = pwaTtsBridge;
2072
+ realPwaAdapter = createPwaVoiceAdapter({
2073
+ sttProvider: streamingStt,
2074
+ onSessionOpen: (session) => {
2075
+ if (bridge && session.sessionId && session.emitDownstream) {
2076
+ const emit = session.emitDownstream.bind(session);
2077
+ bridge.attach(session.sessionId, (frame) => emit(frame));
2078
+ }
2079
+ },
2080
+ onSessionClose: (session) => {
2081
+ if (bridge && session.sessionId) bridge.detach(session.sessionId);
2082
+ },
2083
+ });
2084
+ console.log(`voice: NEXUS PWA WS adapter functional (streaming STT wired · TTS bridge ${bridge ? 'wired' : 'absent (no TTS provider)'})`);
1959
2085
  } else {
1960
2086
  console.log('voice: NEXUS streaming STT inactive (set OPENAI_API_KEY for openai-realtime-stt) — voice WS will use stub adapter');
1961
2087
  }
@@ -1971,9 +2097,8 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1971
2097
  const surfaceForOpts = toolSurface(toolsKind);
1972
2098
  const toolCwdForOpts = resolveToolCwd({ tools: toolsKind, toolCwd: opts.toolCwd });
1973
2099
 
1974
- // Same shape as src/boot/acp-server.ts websocket auth: pass
1975
- // createAuthVerifier only when a token is present; omit it
1976
- // entirely for first-boot dogfood (tokenless ACP upgrade).
2100
+ // ACP websocket and REST share the same boot token; explicit
2101
+ // opt-out omits the websocket verifier as well.
1977
2102
  wsBridgeOpts = {
1978
2103
  ...(acpHandlerRef ? {
1979
2104
  acpOnConnection: async (conn) => {
@@ -1989,7 +2114,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1989
2114
  metaApiOpts = {
1990
2115
  voiceRest,
1991
2116
  ...(bearerToken ? { bearerToken } : {}),
1992
- noAuth: !bearerToken,
2117
+ noAuth,
1993
2118
  history: runtimeHistory,
1994
2119
  intakeStore: getIntakeStore(),
1995
2120
  toolSurface: surfaceForOpts,
@@ -2068,10 +2193,9 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2068
2193
  // schedule-trigger nodes that register a TOX task on fire have a
2069
2194
  // live graph + dispatcher to land in. The `subagent` surface bridges
2070
2195
  // to `globalAgentRegistry` so `Agent`-tool spawns and TOX-driven
2071
- // subagent tasks share a single live registry. Other surface
2072
- // callables (skill / chatPrompt / vwSlot / acxSession / cron /
2073
- // terminalPane / llmDirect) stay unwired here — they land in
2074
- // follow-up PRs as each becomes load-bearing for production work.
2196
+ // subagent tasks share a single live registry. External llm-direct
2197
+ // tasks are triaged to current self-implement or the same subagent callable.
2198
+ // Other surface callables stay unwired here.
2075
2199
  try {
2076
2200
  // Wave 5 E3 — pick up `tools.agentSpawn.hopCap` from user-config
2077
2201
  // before any spawn can fire (the global registry reads the cap
@@ -2084,11 +2208,44 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2084
2208
  setAgentHopCap(cap);
2085
2209
  }
2086
2210
  } catch { /* keep default cap */ }
2211
+ const agentToolSurface = toolSurface(resolveToolsKind(opts));
2212
+ const agentToolCwd = runtimeToolCwd ?? resolveToolCwd({ tools: 'chat', toolCwd: opts.toolCwd });
2213
+ const subagent = createGlobalSubagentCallable({
2214
+ hostTools: agentToolSurface.specs,
2215
+ ...(agentToolCwd ? {
2216
+ dispatchTool: (name: string, args: Record<string, unknown>, signal?: AbortSignal) => agentToolSurface.dispatch(name, args, {
2217
+ cwd: agentToolCwd, signal: signal ?? new AbortController().signal, entry: 'elanous-apparatus',
2218
+ }),
2219
+ cwd: agentToolCwd,
2220
+ } : {}),
2221
+ });
2222
+ toxStore = new TaskStore();
2087
2223
  toxHandle = wireTox({
2088
- surfaces: { subagent: createGlobalSubagentCallable() },
2224
+ graph: hydrateGraph(toxStore), store: toxStore,
2225
+ getWorkflowDaemon: () => workflowDaemon ?? null,
2226
+ surfaces: {
2227
+ subagent,
2228
+ externalExec: createExternalExecAdapter({
2229
+ dispatch: dispatchSelfImplement,
2230
+ cwd: runtimeToolCwd ?? resolveToolCwd({ tools: 'chat', toolCwd: opts.toolCwd })!, subagent,
2231
+ gh: async (args) => {
2232
+ const proc = Bun.spawn(['bun', joinPath(import.meta.dir, '../../bin/elanous.mjs'), 'gh', ...args], {
2233
+ cwd: runtimeToolCwd ?? resolveToolCwd({ tools: 'chat', toolCwd: opts.toolCwd })!,
2234
+ stdout: 'pipe', stderr: 'pipe',
2235
+ });
2236
+ const [stdout, stderr, exitCode] = await Promise.all([
2237
+ new Response(proc.stdout).text(), new Response(proc.stderr).text(), proc.exited,
2238
+ ]);
2239
+ if (exitCode !== 0) throw new Error(stderr.trim() || `gh exited ${exitCode}`);
2240
+ return stdout;
2241
+ },
2242
+ }),
2243
+ },
2089
2244
  log: (line) => console.debug('[nexus]', line),
2090
2245
  });
2091
2246
  } catch (err) {
2247
+ toxStore?.close();
2248
+ toxStore = undefined;
2092
2249
  const msg = err instanceof Error ? err.message : String(err);
2093
2250
  console.warn(`[nexus] wireTox failed: ${msg}`);
2094
2251
  }
@@ -2298,8 +2455,11 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2298
2455
  // TaskStore 의 scheduleText 달린 비-terminal task 를 start() 전에 데몬 entries
2299
2456
  // 로 등록해, 이관잡이 데몬 재시작 후에도 발화하게 한다. best-effort.
2300
2457
  try {
2301
- const { registerScheduledToxTasks } = await import('../domains/schedule-migrate.js');
2302
- const rr = registerScheduledToxTasks(bridgeTaskStore, (e) => workflowDaemon!.registerWorkflow(e));
2458
+ const { registerScheduledToxTasks, scheduledRunViaById } = await import('../domains/schedule-migrate.js');
2459
+ const { listSchedules } = await import('../domains/schedule-registry.js');
2460
+ // 레지스트리의 enabled trigger 만 등록한다(release 뒤 고아·수동 비활성 task 의 발화 방지).
2461
+ const runViaById = scheduledRunViaById(listSchedules(bridgeScheduleDb));
2462
+ const rr = registerScheduledToxTasks(bridgeTaskStore, (e) => workflowDaemon!.registerWorkflow(e), (jobId) => runViaById.get(jobId) ?? null);
2303
2463
  if (rr.registered > 0) {
2304
2464
  console.log(`[nexus] re-registered ${rr.registered} scheduled TOX task(s) as Schedule Triggers`);
2305
2465
  }
@@ -2414,13 +2574,13 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2414
2574
  // so `discordTrigger` nodes fire from real traffic. Skipped
2415
2575
  // when `cfg.discord.enabled` is false or the bot token isn't
2416
2576
  // set. The HITL Discord bot (token = ELANOUS_DISCORD_HITL_*) is
2417
- // a separate Discord application; this trigger bot uses the
2418
- // main `cfg.discord.botToken` populated from
2419
- // ELANOUS_DISCORD_BOT_TOKEN via env-bridge.
2577
+ // a separate Discord application; the trigger bot resolves the
2578
+ // main credential via tokenRef, env, then legacy plaintext.
2420
2579
  try {
2421
2580
  const userConfigMod = await import('../user-config.js');
2422
2581
  const cfg = userConfigMod.getUserConfig();
2423
- if (cfg.discord.enabled && cfg.discord.botToken && !isAutonomousRunContext()) {
2582
+ const discordToken = resolveChannelBotToken('discord', cfg)?.token;
2583
+ if (cfg.discord.enabled && discordToken && !isAutonomousRunContext()) {
2424
2584
  // M4b (2026-07-12) — the production discord bot answers DMs
2425
2585
  // with the elanous self turn + /cc·/cdx·/gem interweaving
2426
2586
  // (텔레그램 동형·대표 확정: 기본 self·명시 위임). The
@@ -2467,7 +2627,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2467
2627
  allowedUsers: [...cfg.discord.allowedUsers],
2468
2628
  });
2469
2629
  const handle = createNexusDiscordTriggerBot({
2470
- token: cfg.discord.botToken,
2630
+ token: discordToken,
2471
2631
  allowedUsers: [...cfg.discord.allowedUsers],
2472
2632
  dispatch: (event) => workflowDaemon!.dispatchDiscord(event),
2473
2633
  onMessage: composedOnMessage,
@@ -2486,32 +2646,30 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2486
2646
  });
2487
2647
  }
2488
2648
  }
2489
- // V2.2-4 (2026-05-12) — parallel Telegram wire. Reuses the
2490
- // same `cfg.telegram.botToken` / `allowedUsers` shape via
2491
- // env-bridge so ELANOUS_TELEGRAM_BOT_TOKEN populates the
2492
- // config under the standard flow.
2649
+ // V2.2-4 (2026-05-12) — parallel Telegram wire. Uses the
2650
+ // resolved main token alongside the existing allowedUsers.
2493
2651
  // 2026-07-05 — unified inbound: pass `userConfig` so the ONE
2494
2652
  // nexus telegram bot answers Q&A (onMessage → runTurn) on top
2495
2653
  // of firing workflow triggers. A separate Q&A poller would 409
2496
2654
  // against this one (single getUpdates consumer per token).
2497
- if (cfg.telegram.enabled && cfg.telegram.botToken && !isAutonomousRunContext()) {
2655
+ const telegramToken = resolveChannelBotToken('telegram', cfg)?.token;
2656
+ if (cfg.telegram.enabled && telegramToken && !isAutonomousRunContext()) {
2498
2657
  // T1 (2026-07-05) — give the Q&A bot the full agent tool surface;
2499
2658
  // A0 folds in the finance analyst orientation only when
2500
2659
  // cfg.finance.enabled (optional domain pack).
2501
2660
  //
2502
2661
  // ★ 멀티 채널(2026-07-09 대표 지시): resolveTelegramChannels 로 채널 목록을
2503
2662
  // 얻고, interactivePollerTokens 로 **봇 토큰당 폴러 1개**만 띄운다(토큰별
2504
- // dedup → 409 자기충돌 원천차단). botFromConfig 가 userConfig.telegram.
2505
- // botToken 을 읽으므로(telegram.ts), 각 폴러엔 그 채널 토큰으로 덮어쓴
2506
- // userConfig 를 넘겨 **올바른 토큰을 폴링**하게 한다(오늘 토큰 버그 정타).
2663
+ // dedup → 409 자기충돌 원천차단). 각 폴러엔 채널 토큰을 명시로
2664
+ // 넘겨 **올바른 토큰을 폴링**하게 한다(오늘 토큰 버그 정타).
2507
2665
  // interactive:false(noti-only) 채널은 폴러 없이 발송 전용.
2508
2666
  const { makeTelegramAgentRunTurn } = await import('../telegram-agent.js');
2509
2667
  const { resolveTelegramChannels, interactivePollerTokens } = await import('../domains/telegram-channels.js');
2510
2668
  const { tryAcquireTelegramPollLock, acquireTelegramPollLock } = await import('../telegram-poll-lock.js');
2511
2669
  const adopt = ({ channel, handle }: NexusTelegramQaPollerWireHandle): void => {
2512
2670
  telegramPollerHandles.push(handle);
2513
- if (channel.botToken === cfg.telegram.botToken) workflowTelegramBot = handle;
2514
- console.log(`[nexus] telegram 채널 '${channel.name}' Q&A 폴러 활성 (${channel.botToken.slice(0, 8)}…·roles ${channel.roles.join('/')})`);
2671
+ if (channel.botToken === telegramToken) workflowTelegramBot = handle;
2672
+ console.log(`[nexus] telegram 채널 '${channel.name}' Q&A 폴러 활성 (roles ${channel.roles.join('/')})`);
2515
2673
  };
2516
2674
  if (cfg.telegram.poller === 'standalone') {
2517
2675
  // 폴링은 `elanous telegram run` 이 맡는다 — 넥서스는 보내기만 한다. 배달 싱크는 «프로세스 안» 등록이라
@@ -2525,7 +2683,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2525
2683
  });
2526
2684
  for (const { channel, handle } of sendOnly) {
2527
2685
  telegramPollerHandles.push(handle);
2528
- if (channel.botToken === cfg.telegram.botToken) workflowTelegramBot = handle;
2686
+ if (channel.botToken === telegramToken) workflowTelegramBot = handle;
2529
2687
  }
2530
2688
  console.log(`[nexus] telegram Q&A 폴러를 띄우지 않는다 (telegram.poller=standalone — elanous telegram run 이 폴링) · 보내기 전용 싱크 ${sendOnly.length}개`);
2531
2689
  } else {
@@ -2673,13 +2831,17 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2673
2831
  // off; today the only flag is the source's missing-file path
2674
2832
  // (returns empty fleet → no-change tick → no router call).
2675
2833
  try {
2676
- devicesSubstrateHandle = buildDevicesSubstrate({
2677
- ...(outboundSubstrate?.router ? { router: outboundSubstrate.router } : {}),
2678
- });
2679
- if (devicesSubstrateHandle.skipReason) {
2680
- console.warn(`[nexus] devices cron skipped (${devicesSubstrateHandle.skipReason}): ${devicesSubstrateHandle.detail ?? ''}`);
2834
+ if (setupPlan.skipCrons.includes('devices')) {
2835
+ debug.log('nexus.boot', 'setup-mode-skip-cron', { cron: 'devices' });
2681
2836
  } else {
2682
- console.info('[nexus] devices fleet cron started');
2837
+ devicesSubstrateHandle = buildDevicesSubstrate({
2838
+ ...(outboundSubstrate?.router ? { router: outboundSubstrate.router } : {}),
2839
+ });
2840
+ if (devicesSubstrateHandle.skipReason) {
2841
+ console.warn(`[nexus] devices cron skipped (${devicesSubstrateHandle.skipReason}): ${devicesSubstrateHandle.detail ?? ''}`);
2842
+ } else {
2843
+ console.info('[nexus] devices fleet cron started');
2844
+ }
2683
2845
  }
2684
2846
  } catch (err: unknown) {
2685
2847
  const msg = err instanceof Error ? err.message : String(err);
@@ -2758,9 +2920,11 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2758
2920
  state,
2759
2921
  registry,
2760
2922
  eventBus,
2923
+ setup: { mode: nexusSetup.setupMode, missing: nexusSetup.setupMissing },
2761
2924
  ...(supervisor ? { supervisor } : {}),
2762
2925
  ...(outboundSubstrate ? { outboundTokens: { tokenStore: outboundSubstrate.tokenStore } } : {}),
2763
2926
  ...(opts.httpStartPort !== undefined ? { startPort: opts.httpStartPort } : {}),
2927
+ ...(leasePortFromLauncher !== undefined ? { portRange: 1 } : {}),
2764
2928
  ...(opts.httpHost !== undefined ? { hostname: opts.httpHost } : {}),
2765
2929
  editInPwa: editInPwaCtx,
2766
2930
  ...(wsBridgeOpts ? { wsBridge: wsBridgeOpts } : {}),
@@ -2771,7 +2935,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2771
2935
  ...(pwaStaticDir ? { staticDir: pwaStaticDir } : {}),
2772
2936
  ...(runtimeIntentPrediction ? { intentPrediction: runtimeIntentPrediction } : {}),
2773
2937
  // next-fluent(태스크 완료 → 다음 액션 1-클릭 칩·2026-07-15) — mission-fabric-aware source +
2774
- // config-gated enabled thunk(기본 OFF). 항상 배선 → route 는 더는 503(not-wired) 안 냄.
2938
+ // 항상 켜진 라우트(기본 ON). personas 만 선택 사항이며, route 는 503(not-wired) 안 냄.
2775
2939
  nextFluent: buildNextFluentRouteOpts(),
2776
2940
  // iPhone Showroom Phase 1 P1-4 (2026-05-14) + FU1 (2026-05-14) —
2777
2941
  // mission router DI seam. Pass a configProvider thunk so user
@@ -2891,9 +3055,40 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2891
3055
  // have moved us off startPort).
2892
3056
  editInPwaCtx.audience = `${httpServer.hostname}:${httpServer.port}`;
2893
3057
  editInPwaCtx.nexusOrigin = httpServer.url;
3058
+ if (leasePortFromLauncher !== undefined && httpServer.port !== leasePortFromLauncher) {
3059
+ httpServer.stop();
3060
+ await stopCoordinatorLease?.();
3061
+ release();
3062
+ throw new Error('coordinator port lease boot mismatch');
3063
+ }
2894
3064
  runtime.httpPort = httpServer.port;
2895
3065
  runtime.httpHost = httpServer.hostname;
2896
- runtime.httpAuth = 'off';
3066
+ runtime.httpAuth = metaApiOpts && !metaApiOpts.noAuth ? 'on' : 'off';
3067
+ // The actual bound port (not the requested port or registry entry) is the member endpoint.
3068
+ try {
3069
+ const configured = (getUserConfig().raw?.nexus as { primary?: unknown } | undefined)?.primary;
3070
+ const { url: coordinatorUrl, token } = resolvePrimary({
3071
+ role: 'member',
3072
+ ...(configured === undefined || configured === '' ? {} : { config: { url: configured as string } }),
3073
+ });
3074
+ if (!token) {
3075
+ try { debug.log('control.member', 'start-skipped', { reason: 'member-token-missing' }); } catch { /* fail-soft */ }
3076
+ } else {
3077
+ const machine = nexusMemberMachine();
3078
+ stopMemberHeartbeat = startMemberHeartbeat({
3079
+ coordinatorUrl, token,
3080
+ machine,
3081
+ instance: {
3082
+ id: `instance:${machine.name}:${effectiveInstanceRoot()}`, name: 'nexus',
3083
+ endpoint: httpServer.url,
3084
+ attrs: { port: httpServer.port, pid: process.pid },
3085
+ },
3086
+ });
3087
+ try { debug.log('control.member', 'started', { machine: machine.id, coordinatorUrl }); } catch { /* fail-soft */ }
3088
+ }
3089
+ } catch {
3090
+ try { debug.log('control.member', 'start-skipped', { reason: 'member-configuration-invalid' }); } catch { /* fail-soft */ }
3091
+ }
2897
3092
  pwaRegistration.register({
2898
3093
  pid: process.pid,
2899
3094
  port: httpServer.port,
@@ -2932,7 +3127,11 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2932
3127
  // FU A8 — boot the discovery cron alongside the reflection
2933
3128
  // scheduler. Dormant when env unset (zero CPU/network cost on
2934
3129
  // a fresh install).
2935
- discoveryCron = startDiscoveryCron();
3130
+ if (setupPlan.skipCrons.includes('discovery')) {
3131
+ debug.log('nexus.boot', 'setup-mode-skip-cron', { cron: 'discovery' });
3132
+ } else {
3133
+ discoveryCron = startDiscoveryCron();
3134
+ }
2936
3135
  // Mission Fabric 통합 U4d (2026-07-09) — schedule-runner 은퇴(B안 완성).
2937
3136
  // 모든 예약잡이 fabric Schedule Trigger(run_via='trigger')로 이관됨 →
2938
3137
  // 정시 발화=workflow 데몬, 놓친발화 복구=catchUpTriggerJobs(위 U4b). run_via=
@@ -2987,6 +3186,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2987
3186
  opts: {
2988
3187
  ...(opts.autoStartDaemonTab !== undefined ? { autoStartDaemonTab: opts.autoStartDaemonTab } : {}),
2989
3188
  ...(opts.detachForTesting !== undefined ? { detachForTesting: opts.detachForTesting } : {}),
3189
+ ...(setupPlan.skipTabKinds.includes('daemon') ? { autoStartDaemonTab: false } : {}),
2990
3190
  },
2991
3191
  });
2992
3192
 
@@ -3011,6 +3211,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3011
3211
  opts: {
3012
3212
  ...(opts.autoStartChannelBots !== undefined ? { autoStartChannelBots: opts.autoStartChannelBots } : {}),
3013
3213
  ...(opts.detachForTesting !== undefined ? { detachForTesting: opts.detachForTesting } : {}),
3214
+ ...(setupPlan.skipTabKinds.includes('channel-bot') ? { autoStartChannelBots: false } : {}),
3014
3215
  },
3015
3216
  });
3016
3217
 
@@ -3024,6 +3225,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3024
3225
  for (const entry of templateTabs) {
3025
3226
  if (entry.start === false) continue;
3026
3227
  if (entry.kind !== 'daemon' && entry.kind !== 'pwa-host' && entry.kind !== 'channel-bot') continue;
3228
+ if (setupPlan.skipTabKinds.includes(entry.kind)) continue;
3027
3229
  if (!autoStart) continue;
3028
3230
  const id = entry.id ?? '';
3029
3231
  if (!id || !registry.has(id)) continue;
@@ -3033,7 +3235,12 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3033
3235
  }
3034
3236
  }
3035
3237
 
3238
+ let shareCoordinatorTimer: ReturnType<typeof setInterval> | undefined;
3239
+ let shareCoordinatorStopped = false;
3240
+ let shareCoordinatorPending: Promise<void> | undefined;
3036
3241
  const wrappedRelease = (): void => {
3242
+ shareCoordinatorStopped = true;
3243
+ if (shareCoordinatorTimer) { clearInterval(shareCoordinatorTimer); shareCoordinatorTimer = undefined; }
3037
3244
  pushEvent(state, { kind: 'nexus.shutdown' });
3038
3245
  pwaRegistration.unregister();
3039
3246
  try { unsubscribeWebtermTabLifecycle(); } catch { /* swallow */ }
@@ -3121,6 +3328,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3121
3328
  console.warn(`[nexus] tox dispose failed: ${msg}`);
3122
3329
  }
3123
3330
  }
3331
+ if (toxStore) { try { toxStore.close(); } catch { /* shutdown best effort */ } toxStore = undefined; }
3124
3332
  // V2.2-3 (2026-05-12) — stop the workflow Discord trigger bot.
3125
3333
  if (workflowDiscordBot) {
3126
3334
  void workflowDiscordBot.stop().catch(() => { /* swallow */ });
@@ -3192,6 +3400,13 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3192
3400
  }
3193
3401
  };
3194
3402
  void disposeMcp().catch(() => { /* swallow */ });
3403
+ try { stopMemberHeartbeat?.(); } catch { /* best-effort shutdown */ }
3404
+ if (stopCoordinatorLease) {
3405
+ const stopLease = stopCoordinatorLease;
3406
+ stopCoordinatorLease = undefined;
3407
+ leaseReleasePending = stopLease().catch(error => debug.log('control.port-lease', 'release-failed', { port: leasePortFromLauncher, reason: String(error) }, { level: 'warn' }));
3408
+ }
3409
+ controlServer?.stop();
3195
3410
  httpServer?.stop();
3196
3411
  try { deleteNexusRuntime(); } catch { /* best-effort */ }
3197
3412
  release();
@@ -3230,8 +3445,14 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3230
3445
  };
3231
3446
 
3232
3447
  const releaseWithShareUnmount = async (): Promise<void> => {
3233
- await unmountAutoMountedShare();
3234
- wrappedRelease();
3448
+ shareCoordinatorStopped = true;
3449
+ if (shareCoordinatorTimer) { clearInterval(shareCoordinatorTimer); shareCoordinatorTimer = undefined; }
3450
+ await shareCoordinatorPending;
3451
+ try { await unmountAutoMountedShare(); }
3452
+ finally {
3453
+ wrappedRelease();
3454
+ await leaseReleasePending;
3455
+ }
3235
3456
  };
3236
3457
 
3237
3458
  const recordShareMount = (result: Awaited<ReturnType<NonNullable<RunNexusOptions['mountShareIfEnabledFn']>>>): void => {
@@ -3269,6 +3490,9 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3269
3490
  }
3270
3491
 
3271
3492
  printBootBanner(runtime, pwaStaticDir);
3493
+ if (runtime.httpPort && noAuth) {
3494
+ console.warn(' ⚠ NEXUS AUTH DISABLED (--no-auth / ELANOUS_NEXUS_NO_AUTH=1) — HTTP API and ACP websocket are unprotected.');
3495
+ }
3272
3496
 
3273
3497
  // P.3 — first-boot PWA share wizard. Only runs in interactive TUI mode
3274
3498
  // when the switch is still 'ask'. Headless / non-TTY boots skip it (the
@@ -3280,21 +3504,22 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3280
3504
  const io = defaultIO();
3281
3505
  // Phase 4 (2026-05-19) — tailscale probe 결과 + PWA build 상태 + port
3282
3506
  // 를 first-boot wizard 에 전달해서 banner 가 PWA URL 을 표시하도록.
3283
- const httpPort = runtime.httpPort ?? 31415;
3507
+ const httpPort = httpServer?.port;
3284
3508
  const pwaBuilt = Boolean(pwaStaticDir);
3285
- const tailscale = await probeTailscale().catch(() => undefined);
3509
+ const tailscale = httpPort !== undefined ? await probeTailscale().catch(() => undefined) : undefined;
3286
3510
  try {
3287
3511
  await runFirstBootWizard({
3288
3512
  io,
3289
3513
  setupStatus,
3290
- shouldRunTailscale: shouldAskPwaShareSwitch(),
3291
- httpPort,
3514
+ shouldRunTailscale: httpPort !== undefined && shouldAskPwaShareSwitch(),
3515
+ ...(httpPort !== undefined ? { httpPort } : {}),
3292
3516
  pwaBuilt,
3293
3517
  ...(tailscale ? { tailscale } : {}),
3294
3518
  runLlmStep: async (wizardIo) => {
3295
3519
  await runOnboardingStep('llm', { io: wizardIo });
3296
3520
  },
3297
3521
  runTailscaleWizard: async (wizardIo) => {
3522
+ if (httpPort === undefined) return;
3298
3523
  await runPwaShareWizardIfAsk({
3299
3524
  port: httpPort,
3300
3525
  pwaBuilt,
@@ -3322,29 +3547,37 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3322
3547
  try {
3323
3548
  const mountShareIfEnabled = opts.mountShareIfEnabledFn
3324
3549
  ?? (await import('../cli/share-auto-mount.js')).mountShareIfEnabled;
3325
- const r = await mountShareIfEnabled({ httpPort });
3326
- if (r.outcome === 'serving') {
3327
- shareMounted = true;
3328
- autoMountedSharePort = httpPort;
3329
- recordShareMount(r);
3330
- console.log(` share ON ${r.url ?? '(tailnet host unknown)'} (Tailscale Serve · auto-managed)`);
3331
- } else if (r.outcome === 'failed') {
3332
- // FU2 — most common fail in fork+detach is `sudo -n` cache
3333
- // empty (bg-launch child inherits parent sudo cache; cache
3334
- // expires after ~5-15min). Surface both recovery paths so
3335
- // the user doesn't have to guess between "fix Tailscale" and
3336
- // "run sudo -v".
3337
- console.log(` share ERR serve exit ${r.serveExitCode ?? '?'} (likely sudo cache empty in bg-launch child)`);
3338
- console.log(' recover with EITHER:');
3339
- console.log(' a) `sudo -v` once in a TTY, then `elanous nexus stop && elanous nexus run`');
3340
- console.log(' b) `elanous nexus pwa share enable` (parent-side mount · independent of daemon)');
3341
- } else if (r.reason === 'tailscale-missing') {
3342
- console.log(' share OFF Tailscale not installed — https://tailscale.com/download');
3343
- } else if (r.reason === 'tailscale-down') {
3344
- console.log(' share OFF Tailscale not active — start Tailscale, then `pwa share enable`');
3345
- }
3346
- // switch-disabled / switch-ask: stay quiet (user choice or fresh
3347
- // install where the wizard hasn't run yet).
3550
+ const reconcileShare = (): Promise<void> => {
3551
+ if (shareCoordinatorStopped || shareCoordinatorPending) return shareCoordinatorPending ?? Promise.resolve();
3552
+ const pending = (async (): Promise<void> => {
3553
+ try {
3554
+ const r = await mountShareIfEnabled({ httpPort });
3555
+ if (r.outcome === 'serving') {
3556
+ shareMounted = true;
3557
+ autoMountedSharePort = httpPort;
3558
+ recordShareMount(r);
3559
+ console.log(` share ON ${r.url ?? '(tailnet host unknown)'} (Tailscale Serve · auto-managed)`);
3560
+ } else if (r.outcome === 'failed') {
3561
+ console.log(` share ERR serve exit ${r.serveExitCode ?? '?'} (likely sudo cache empty in bg-launch child)`);
3562
+ console.log(' recover with EITHER:');
3563
+ console.log(' a) `sudo -v` once in a TTY, then `elanous nexus stop && elanous nexus run`');
3564
+ console.log(' b) `elanous nexus pwa share enable` (parent-side mount · independent of daemon)');
3565
+ } else if (r.reason === 'tailscale-missing') {
3566
+ console.log(' share OFF Tailscale not installed — https://tailscale.com/download');
3567
+ } else if (r.reason === 'tailscale-down') {
3568
+ console.log(' share OFF Tailscale not active — start Tailscale, then `pwa share enable`');
3569
+ }
3570
+ } catch (err) {
3571
+ console.error(` share ERR ${(err as Error).message}`);
3572
+ }
3573
+ })();
3574
+ shareCoordinatorPending = pending;
3575
+ void pending.then(() => { if (shareCoordinatorPending === pending) shareCoordinatorPending = undefined; });
3576
+ return pending;
3577
+ };
3578
+ await reconcileShare();
3579
+ shareCoordinatorTimer = setInterval(() => { void reconcileShare(); }, opts.shareCoordinatorIntervalMsForTesting ?? 60_000);
3580
+ shareCoordinatorTimer.unref?.();
3348
3581
  } catch (err) {
3349
3582
  console.error(` share ERR ${(err as Error).message}`);
3350
3583
  }
@@ -3392,17 +3625,19 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3392
3625
  console.log(' elanous nexus: headless mode (TUI suppressed) — Ctrl-C / SIGTERM to exit.\n');
3393
3626
  let resolveDone: () => void = () => {};
3394
3627
  const done = new Promise<void>((r) => { resolveDone = r; });
3628
+ let sigtermExit: Promise<void> | undefined;
3395
3629
  const onSigterm = (): void => {
3396
3630
  console.error('\nelanous nexus: received SIGTERM, graceful restart pending (exit 75)...');
3397
3631
  if (pwaWatchHandle) { try { pwaWatchHandle.stop(); } catch { /* */ } }
3398
3632
  // R1(재시작 최소화 RFC) — 이미 텔레그램에 «확인»된 턴이 재시작으로 말없이 사라지지 않게,
3399
3633
  // SIGTERM 을 받은 «지금부터» 상한 안에서 봇의 대기 턴을 비운 뒤 나간다(부팅 시각 기준이 아니다).
3400
- void drainTelegramThen(() => gracefulExit({
3634
+ sigtermExit = drainTelegramThen(() => gracefulExit({
3401
3635
  state,
3402
3636
  registry,
3403
3637
  ...(supervisor ? { supervisor } : {}),
3404
3638
  release: releaseWithShareUnmount,
3405
3639
  }));
3640
+ resolveDone();
3406
3641
  };
3407
3642
  const onSigint = (): void => {
3408
3643
  console.error('\nelanous nexus: received SIGINT, shutting down...');
@@ -3415,7 +3650,8 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3415
3650
  process.removeListener('SIGINT', onSigint);
3416
3651
  process.removeListener('SIGTERM', onSigterm);
3417
3652
 
3418
- await cleanExit({
3653
+ if (sigtermExit) await sigtermExit;
3654
+ else await cleanExit({
3419
3655
  state,
3420
3656
  registry,
3421
3657
  ...(supervisor ? { supervisor } : {}),
@@ -3452,9 +3688,10 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3452
3688
  console.log(' elanous nexus: TUI mount path deprecated (T4) — Ctrl-C / SIGTERM to exit.\n');
3453
3689
  let resolveDone: () => void = () => {};
3454
3690
  const done = new Promise<void>((r) => { resolveDone = r; });
3691
+ let sigtermExit: Promise<void> | undefined;
3455
3692
  const onSigterm = (): void => {
3456
3693
  console.error('\nelanous nexus: received SIGTERM, graceful restart pending (exit 75)...');
3457
- void drainTelegramThen(() => gracefulExit({
3694
+ sigtermExit = drainTelegramThen(() => gracefulExit({
3458
3695
  state,
3459
3696
  registry,
3460
3697
  ...(supervisor ? { supervisor } : {}),
@@ -3469,10 +3706,12 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3469
3706
  process.once('SIGINT', onSigint);
3470
3707
  process.once('SIGTERM', onSigterm);
3471
3708
  await done;
3709
+ process.removeListener('SIGINT', onSigint);
3710
+ process.removeListener('SIGTERM', onSigterm);
3472
3711
 
3473
- // SIGINT path — clean exit 0, clears any leftover restart-state so the
3474
- // OS supervisor doesn't respawn after an explicit user stop.
3475
- await cleanExit({
3712
+ // SIGTERM completes its graceful exit; SIGINT clears restart-state.
3713
+ if (sigtermExit) await sigtermExit;
3714
+ else await cleanExit({
3476
3715
  state,
3477
3716
  registry,
3478
3717
  ...(supervisor ? { supervisor } : {}),
@@ -3563,27 +3802,10 @@ function shouldAskPwaShareSwitch(): boolean {
3563
3802
  }
3564
3803
  }
3565
3804
 
3566
- /** PR k — load the persistent ACP bearer token at
3567
- * `getElanousConfigDir()/acp-token`. Mirrors the helper in
3568
- * `boot/acp-server.ts` that `elanous serve` uses, so the same token
3569
- * gates daemon and NEXUS HTTP. Returns undefined when the token
3570
- * file is absent (loopback noAuth default — first-boot dogfood
3571
- * works without configuration). Read failures are swallowed. */
3572
- export function readAcpToken(): string | undefined {
3573
- try {
3574
- const tokenPath = joinPath(getElanousConfigDir(), 'acp-token');
3575
- if (existsSync(tokenPath)) {
3576
- const tok = readFileSync(tokenPath, 'utf-8').trim();
3577
- return tok || undefined;
3578
- }
3579
- } catch { /* swallow */ }
3580
- return undefined;
3581
- }
3582
-
3583
3805
  function printBootBanner(runtime: NexusRuntimeMeta, pwaStaticDir?: string): void {
3584
3806
  const lines = [
3585
3807
  '',
3586
- ` elanous NEXUS · ${runtime.nexusVersion} · ${runtime.phase}`,
3808
+ ` elanous NEXUS · ${runtime.nexusVersion}`,
3587
3809
  ' ──────────────────────────────────────────────────────',
3588
3810
  ` pid ${runtime.pid}`,
3589
3811
  ` host ${hostname()}`,
@@ -3606,12 +3828,9 @@ function printBootBanner(runtime: NexusRuntimeMeta, pwaStaticDir?: string): void
3606
3828
  }
3607
3829
  lines.push(
3608
3830
  '',
3609
- ' Phase N-5 PR χ — graceful exit 75 (OS supervisor restart).',
3610
3831
  ' Read-only routes: GET /v1/{health,nexus,nexus/tabs,events}',
3611
3832
  ' Toggle keys: Ctrl-` (primary) · Ctrl-\\ (Korean IME / SSH friendly).',
3612
- ' SIGINT (Ctrl-C) → exit 0 (OS supervisor leaves nexus stopped).',
3613
- ' SIGTERM → exit 75 + restart-state.json (OS supervisor respawns).',
3614
- ' PR ψ/ω add `elanous nexus install --launchd|--systemd-user`.',
3833
+ ' Install service: elanous nexus install --launchd (macOS) or --systemd-user (Linux).',
3615
3834
  '',
3616
3835
  ' Ctrl-C to release lock and exit.',
3617
3836
  '',