elanous 0.2.35 → 0.2.37

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 (827) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +62 -0
  8. package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 1262.a89bb27a5b2f844e.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1746.3563617ea64023a3.js +115 -0
  12. package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/{1dc5a567.9b092bfae3d7099b.js → 1ed5e8af.cf424815c7c0efad.js} +1 -1
  16. package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 2002-a43a3f380df873ec.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{13.02a07436dec15f89.js → 210.90b2cbd64926cf34.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 2283.edd9627b7bdfb546.js} +2 -2
  20. package/apps/pwa/out/_next/static/chunks/{6866-79aa5b4e47cac6aa.js → 2318-450e75d07605b8fe.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 2375.bf364c85dbb6f085.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +148 -0
  25. package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +27 -0
  29. package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3199.6a1a9b0e6cd01dc6.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 3578.4e9f9948a9a6f2f4.js} +2 -2
  35. package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +90 -0
  39. package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +226 -0
  40. package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +287 -0
  41. package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 4313.76f232c304a15bde.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/{1165.bad13fc9151a7288.js → 4324.c99ba3e83eb1b691.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/{3f7c4ee5.3dde54f01a816613.js → 4337e36d.f42c3b391b3d8f20.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 4383.18e5c54db3a22c88.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 4725-34bed25720cc326b.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/{5483-dd5d7697f6bdb106.js → 4833-7934c592c5569f00.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +24 -0
  52. package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 4931.95cc6dbd230774ca.js} +17 -17
  53. package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 5046.7fd5cbd859299448.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +104 -0
  57. package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/58edce7d.f1b0c72acf13b123.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +93 -0
  65. package/apps/pwa/out/_next/static/chunks/5952.294fc574a8625184.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → 5f6af561-f90b7a67f4f75d13.js} +1 -1
  67. package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +74 -0
  68. package/apps/pwa/out/_next/static/chunks/6252.240578f10952e091.js +34 -0
  69. package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 6680.6a693c28aae4cd19.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 6745-5a63492933959dd9.js} +3 -3
  72. package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +149 -0
  74. package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 6819.be5c9c4d67f22922.js} +16 -16
  75. package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/{2833-0fe47af99ed13c29.js → 6971-fb5f9dc0a2cb5d2d.js} +1 -1
  77. package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 709a918c.4fd3b4e2a32cb4e3.js} +1 -1
  78. package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +41 -0
  80. package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +24 -0
  83. package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7424.c0fe2a595d4232b5.js +23 -0
  87. package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 7867.e8725745ddd1d940.js} +4 -4
  93. package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → 7c5ed21f-f286708e57cf88f7.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +8 -0
  98. package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 8080-40d781e7704d3671.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +77 -0
  100. package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +286 -0
  103. package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +79 -0
  107. package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 8c58d09b.e8724a299658d86f.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 9151.a2c51e93f9156dae.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/{4441-875b97f5821ed58a.js → 9175-7d383df15a82e2be.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +94 -0
  117. package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +64 -0
  119. package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-3337c6a1328c2674.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/{page-47c5d4db587266bd.js → page-1e5da297557d2354.js} +1 -1
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-1f5a60f70cb4dd0c.js → page-88a1edbff62eaf1d.js} +1 -1
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/{page-bac7dee94e5eae4a.js → page-443364c9e4a23b31.js} +1 -1
  155. package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/{page-dc0a532f5b9196ec.js → page-ac2c1e6169cfce57.js} +1 -1
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-c1c80e345fa9d6f5.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{d06f9160.a3d9062f95de8ad7.js → d9815f84.4918f682a45a8502.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → de8446d3.31b73eb239fecd7b.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b5d88eba78a3d7bf.css → be9019f696217521.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  279. package/docs/goal-context/README.md +3 -0
  280. package/graphs/default-loop.yaml +6 -1
  281. package/graphs/drafts/recipes.yaml +27 -7
  282. package/graphs/implement-loop.yaml +24 -0
  283. package/graphs/release/recipes.yaml +6 -0
  284. package/graphs/release/release-loop.yaml +17 -4
  285. package/graphs/wizard/recipes.yaml +44 -0
  286. package/graphs/wizard/wizard-loop.yaml +44 -0
  287. package/graphs/work/draft-close.yaml +54 -0
  288. package/graphs/work/green-close.yaml +37 -0
  289. package/graphs/work/recipes.yaml +46 -1
  290. package/graphs/work/research-report.yaml +2 -0
  291. package/graphs/work/run-research.yaml +35 -0
  292. package/package.json +1 -1
  293. package/scripts/__fixtures__/authoring-paths-10x3.json +32 -0
  294. package/scripts/boundary-proof-mapping-audit.ts +88 -0
  295. package/scripts/ci-typecheck-changed.ts +139 -5
  296. package/scripts/codex-fallback-live-probe.ts +17 -15
  297. package/scripts/coord-role-pack.ts +1 -1
  298. package/scripts/first10-gate.ts +416 -0
  299. package/scripts/fleet/node-setup.sh +32 -2
  300. package/scripts/fleet/run-light-worker.sh +9 -0
  301. package/scripts/fleet/wsl-node-setup.sh +432 -0
  302. package/scripts/gate-0226-failure-census.ts +507 -0
  303. package/scripts/goals/authoring-metrics.ts +258 -0
  304. package/scripts/graph-units/draft-close-node.ts +222 -0
  305. package/scripts/hook-order-sweep.ts +7 -4
  306. package/scripts/land-global-checks.ts +69 -1
  307. package/scripts/measure-nl-routing-corpus.ts +207 -2
  308. package/scripts/release-loop/docs-node.ts +344 -8
  309. package/scripts/release-loop/gate-closure.ts +48 -0
  310. package/scripts/release-loop/gate-diff.ts +2 -1
  311. package/scripts/release-loop/gate-node.ts +249 -53
  312. package/scripts/release-loop/known-issues-node.ts +6 -4
  313. package/scripts/release-loop/node-verdict.ts +2 -0
  314. package/scripts/release-loop/notes-repair.ts +216 -0
  315. package/scripts/release-loop/prepare-node.ts +61 -5
  316. package/scripts/release-loop/resume-cap.ts +14 -34
  317. package/scripts/release-loop/resume-release.ts +151 -15
  318. package/scripts/release-loop/resume-test-traffic.ts +10 -0
  319. package/scripts/release-loop/traffic-node.ts +59 -0
  320. package/scripts/release-loop/traffic-transition.ts +159 -0
  321. package/scripts/release-loop/version-node.ts +81 -12
  322. package/scripts/rhythm/daily.ts +137 -3
  323. package/scripts/train/green-leg.ts +176 -0
  324. package/scripts/tui-continue-real-evidence.ts +47 -0
  325. package/scripts/ux-sim.ts +53 -0
  326. package/skills/README.md +1 -0
  327. package/src/acp/client.ts +31 -5
  328. package/src/acp/core-turn-bridge.ts +54 -6
  329. package/src/acp/stderr-summary.ts +49 -0
  330. package/src/agent/delegate-hint.ts +16 -0
  331. package/src/agent/monad-agent-turn.ts +1 -0
  332. package/src/agent/runner.ts +82 -2
  333. package/src/agent/task-notification.ts +56 -10
  334. package/src/agent/terminal-surface.ts +217 -0
  335. package/src/agent/types.ts +4 -0
  336. package/src/agent-substrate/pr-reviewer.ts +64 -4
  337. package/src/agent-substrate/review-intent.ts +29 -2
  338. package/src/agent-substrate/review-observation.ts +3 -0
  339. package/src/agent-substrate/self-review-cli.ts +490 -26
  340. package/src/autopilot/lineage/sources.ts +1 -1
  341. package/src/autopilot/mission-codebase-gate.ts +141 -12
  342. package/src/autopilot/pr-manager.ts +89 -18
  343. package/src/boot/daemon-runtime.ts +35 -3
  344. package/src/boot/daemon-tools/pty-shell.ts +2 -1
  345. package/src/boot/daemon-tools/self-implement.ts +1 -0
  346. package/src/budget/run-usage-rollup.ts +12 -7
  347. package/src/budget/unified-usage.ts +20 -0
  348. package/src/budget/usage-outcomes.ts +8 -4
  349. package/src/capture/tui-self-report.ts +132 -1
  350. package/src/chat/goal-continue-verdict.ts +41 -0
  351. package/src/chat/index.ts +30 -4
  352. package/src/chat/internal-turn-origin.ts +1 -0
  353. package/src/chat/paste-fold.ts +86 -0
  354. package/src/chat/tool-render/block.ts +32 -0
  355. package/src/chat/tool-render/dispatch.ts +2 -20
  356. package/src/chat/tool-render/result-text.ts +98 -0
  357. package/src/chat/turn-typeahead.ts +70 -7
  358. package/src/cli/autopilot-cli.ts +24 -9
  359. package/src/cli/config-audit.ts +119 -0
  360. package/src/cli/decisions-cli.ts +7 -4
  361. package/src/cli/doctor-cli.ts +137 -6
  362. package/src/cli/guardian-cli.ts +10 -0
  363. package/src/cli/herdr-cli.ts +34 -0
  364. package/src/cli/light-entry-route.ts +6 -3
  365. package/src/cli/log-event-names.ts +2 -0
  366. package/src/cli/logs-cli.ts +357 -2
  367. package/src/cli/make-cli.ts +247 -11
  368. package/src/cli/memory-cli.ts +30 -1
  369. package/src/cli/msg-cli.ts +132 -14
  370. package/src/cli/pr-cli.ts +29 -16
  371. package/src/cli/pr-granularity.ts +5 -3
  372. package/src/cli/pr-land-base-read.ts +11 -2
  373. package/src/cli/pr-land-heavy-remote.ts +6 -3
  374. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  375. package/src/cli/pr-land-recovery.ts +117 -1
  376. package/src/cli/pty-takeover-cli.ts +8 -7
  377. package/src/cli/release-checklist-read-cli.ts +109 -4
  378. package/src/cli/release-cli.ts +64 -15
  379. package/src/cli/release-single-flight.ts +1 -1
  380. package/src/cli/self-update.ts +23 -5
  381. package/src/cli/self-utterances-cli.ts +13 -16
  382. package/src/cli/tasks-card-show.ts +162 -0
  383. package/src/cli/tasks-cli.ts +868 -352
  384. package/src/cli/tasks-read-cli.ts +197 -0
  385. package/src/cli/usage-cli.ts +12 -10
  386. package/src/context-bus/claude-memory-import.ts +99 -0
  387. package/src/context-bus/long-term-memory.ts +125 -0
  388. package/src/core-turn/run-core-turn.ts +4 -2
  389. package/src/core-turn/run-goal-loop.ts +76 -16
  390. package/src/core-turn/types.ts +8 -1
  391. package/src/dashboard/chat/acp-chat.ts +9 -0
  392. package/src/dashboard/context/keys.ts +8 -31
  393. package/src/dashboard/index.ts +299 -62
  394. package/src/dashboard/input/agent-wake.ts +50 -1
  395. package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
  396. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  397. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  398. package/src/dashboard/input/goal-continue.ts +210 -0
  399. package/src/dashboard/input/goal-interim.ts +2 -0
  400. package/src/dashboard/input/internal-turn.ts +2 -8
  401. package/src/dashboard/input/seat-autowake.ts +9 -7
  402. package/src/dashboard/input/turn-autoheal.ts +52 -0
  403. package/src/dashboard/replay-preview.ts +25 -0
  404. package/src/dashboard/seat-boot-preamble.ts +132 -5
  405. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  406. package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -10
  407. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  408. package/src/dashboard/stale-install-check.ts +3 -99
  409. package/src/dashboard/synchronized-frame-output.ts +74 -0
  410. package/src/debug/batch-queue.ts +119 -0
  411. package/src/debug/tui-log-tag.ts +67 -0
  412. package/src/display/agent-surface.ts +7 -0
  413. package/src/display/coordinator.ts +45 -12
  414. package/src/display/resize-listener.ts +41 -20
  415. package/src/display/synchronized-output-region.ts +60 -0
  416. package/src/domains/standalone-log-sink.ts +15 -2
  417. package/src/domains/surface-events.ts +80 -1
  418. package/src/esc-abort-gate.ts +69 -0
  419. package/src/exec-requests/planner.ts +37 -2
  420. package/src/execution-loop/launch-gate.ts +4 -3
  421. package/src/git-fs/cli-stderr.ts +45 -0
  422. package/src/git-fs/gh-cli.ts +6 -3
  423. package/src/git-fs/git-cli.ts +11 -5
  424. package/src/git-fs/worktree.ts +95 -1
  425. package/src/graph-runner/graph-cli.ts +44 -2
  426. package/src/graph-runner/graph-run-api.ts +3 -2
  427. package/src/graph-runner/runner.ts +37 -16
  428. package/src/graph-wizard/generate.ts +131 -4
  429. package/src/graph-wizard/steps.ts +15 -0
  430. package/src/grounding/proactive-ground.ts +86 -0
  431. package/src/harness/control-inbox.ts +49 -1
  432. package/src/harness/harness-cli-command.ts +230 -40
  433. package/src/harness/harness-incidents.ts +52 -1
  434. package/src/harness/pod-control-send.ts +33 -5
  435. package/src/harness/review-adapter.ts +26 -6
  436. package/src/harness/self-send-remote.ts +69 -0
  437. package/src/harness/self-send-routing-guard.ts +6 -0
  438. package/src/harness/self-send-target.ts +4 -3
  439. package/src/index.ts +443 -25
  440. package/src/input-core/context-key-runtime.ts +21 -0
  441. package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
  442. package/src/light-cli.ts +6 -1
  443. package/src/llm/route-decision.ts +13 -0
  444. package/src/llm-tool-name.ts +37 -0
  445. package/src/llm-tool-schema.ts +35 -0
  446. package/src/llm-wellformed.ts +70 -0
  447. package/src/llm.ts +158 -15
  448. package/src/loops/checker.ts +100 -0
  449. package/src/loops/consensus.ts +26 -2
  450. package/src/loops/loop-cli.ts +9 -4
  451. package/src/loops/msg-wake.ts +35 -39
  452. package/src/loops/orchestrator/anomaly-cluster.ts +243 -0
  453. package/src/loops/orchestrator/inbox.ts +59 -11
  454. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  455. package/src/loops/orchestrator/tick.ts +54 -5
  456. package/src/maturity/feature-maturity.ts +1 -1
  457. package/src/model-tier/llm-tier-map.ts +12 -17
  458. package/src/models/prompts.ts +17 -2
  459. package/src/msg/msg-post-office.ts +116 -0
  460. package/src/msg/msg-store.ts +17 -0
  461. package/src/mss/logging/log-store.ts +79 -22
  462. package/src/native-tool-catalog.ts +1 -1
  463. package/src/nexus/api/decisions-route.ts +38 -18
  464. package/src/nexus/api/graph-wizard-api.ts +46 -3
  465. package/src/nexus/api/grid.ts +24 -4
  466. package/src/nexus/api/http-server.ts +1 -1
  467. package/src/nexus/api/ops-api.ts +14 -6
  468. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  469. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  470. package/src/nexus/state/state.ts +7 -1
  471. package/src/oauth/codex-account-store.ts +34 -1
  472. package/src/onboarding/first-run.ts +37 -6
  473. package/src/onboarding/web-first.ts +43 -11
  474. package/src/ops/loops-map.ts +46 -0
  475. package/src/ops/overview-cache.ts +22 -4
  476. package/src/ops/overview-collect.ts +12 -6
  477. package/src/ops/overview.ts +44 -8
  478. package/src/persona/loader.ts +11 -0
  479. package/src/persona/types.ts +8 -0
  480. package/src/policy/llm-policy.ts +3 -1
  481. package/src/prompt-enhance/enhance.ts +4 -4
  482. package/src/prompt-library/session-guidance.ts +14 -0
  483. package/src/provider-summary.ts +8 -0
  484. package/src/pty-shell/availability.ts +7 -0
  485. package/src/pty-shell/herdr-agent-report.ts +155 -37
  486. package/src/pty-shell/herdr-prompt.ts +266 -0
  487. package/src/pty-shell/herdr-prune-stale.ts +17 -0
  488. package/src/pty-shell/herdr-sequence-lease.ts +60 -0
  489. package/src/pty-shell/pty-control-ipc.ts +327 -15
  490. package/src/pty-shell/pty-special-keys.ts +42 -2
  491. package/src/pty-shell/registry.ts +25 -15
  492. package/src/pty-shell/stale-install-check.ts +99 -0
  493. package/src/pty-shell/tui-run-state.ts +249 -3
  494. package/src/release-loop/auto-start.ts +20 -2
  495. package/src/release-loop/checklist.ts +126 -9
  496. package/src/release-loop/feature-store.ts +9 -9
  497. package/src/release-loop/landed-but-yellow.ts +93 -12
  498. package/src/release-loop/rehearsal.ts +36 -20
  499. package/src/repl/index.ts +27 -1
  500. package/src/seat-loop/knowhow-lint.ts +1 -1
  501. package/src/seat-loop/seat-report.ts +1 -0
  502. package/src/self-dev/ask-launch-flow.ts +86 -10
  503. package/src/self-dev/decompose-proposal.ts +183 -20
  504. package/src/self-dev/decompose.ts +61 -0
  505. package/src/self-dev/dev-cli.ts +37 -3
  506. package/src/self-dev/dev-pipeline.ts +37 -9
  507. package/src/self-dev/draft-sweep.ts +241 -16
  508. package/src/self-dev/draft-triage-rules.ts +50 -5
  509. package/src/self-dev/glm-credential-guard.ts +77 -0
  510. package/src/self-dev/graph-journey-nodes.ts +1 -0
  511. package/src/self-dev/graph-journey-route.ts +12 -2
  512. package/src/self-dev/orchestrate-cli.ts +68 -3
  513. package/src/self-dev/orchestrate.ts +116 -17
  514. package/src/self-dev/review-provider-fallback.ts +45 -7
  515. package/src/self-dev/run-supervisor.ts +55 -2
  516. package/src/self-dev/run-types.ts +1 -1
  517. package/src/self-dev/shard-plan.ts +48 -0
  518. package/src/self-dev/shard-run.ts +50 -3
  519. package/src/self-health/autoheal.ts +153 -0
  520. package/src/self-health/signatures.ts +6 -0
  521. package/src/self-implement/device-first.ts +116 -0
  522. package/src/self-implement/doctor-visit.ts +322 -1
  523. package/src/self-implement/evidence-command-budget.ts +80 -0
  524. package/src/self-implement/gate-artifacts.ts +6 -2
  525. package/src/self-implement/gate-baseline.ts +64 -1
  526. package/src/self-implement/gate-cli.ts +93 -9
  527. package/src/self-implement/gate-remote.ts +28 -4
  528. package/src/self-implement/gate-scope.ts +13 -1
  529. package/src/self-implement/goal-author-cli.ts +1 -0
  530. package/src/self-implement/goal-author-decompose.ts +265 -4
  531. package/src/self-implement/goal-author.ts +366 -26
  532. package/src/self-implement/goal-elaborate.ts +176 -22
  533. package/src/self-implement/goal-refine.ts +3 -0
  534. package/src/self-implement/goal-supervisor-fill.ts +75 -26
  535. package/src/self-implement/graph-variant.ts +40 -6
  536. package/src/self-implement/headless-elanous-driver.ts +19 -3
  537. package/src/self-implement/importer-test-index.ts +215 -2
  538. package/src/self-implement/knowhow-pack.ts +5 -5
  539. package/src/self-implement/off-diff-evidence.ts +58 -6
  540. package/src/self-implement/orchestrator.ts +536 -42
  541. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  542. package/src/self-implement/pwa-import-graph.ts +1 -1
  543. package/src/self-implement/review-round-brief.ts +300 -0
  544. package/src/self-implement/rework-policy.ts +44 -0
  545. package/src/self-implement/run-ledger.ts +278 -6
  546. package/src/self-implement/run-stop.ts +1 -1
  547. package/src/self-implement/run-ttl.ts +38 -24
  548. package/src/self-implement/running-runs.ts +17 -3
  549. package/src/self-implement/scope-adjacency.ts +3 -1
  550. package/src/self-implement/seams.ts +72 -10
  551. package/src/self-implement/stop-autoheal.ts +1 -0
  552. package/src/self-implement/test-seams.ts +13 -1
  553. package/src/self-implement/train-reach-grouping.ts +8 -2
  554. package/src/self-implement/wiring-check.ts +358 -0
  555. package/src/session/chat.ts +7 -1
  556. package/src/session/id-prefix.ts +60 -0
  557. package/src/session/index.ts +4 -0
  558. package/src/session-runtime/index.ts +9 -1
  559. package/src/shell-env-bootstrap.ts +11 -4
  560. package/src/skills/runner.ts +4 -2
  561. package/src/skills/tools/agent.ts +290 -48
  562. package/src/skills/tools/pty.ts +5 -0
  563. package/src/skills/tools/schedule-wakeup.ts +23 -4
  564. package/src/skills/tools/shell.ts +61 -6
  565. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  566. package/src/skills/tools/terminal-modal.ts +10 -8
  567. package/src/skills/url-router.ts +41 -1
  568. package/src/smart-wizard/run.ts +66 -0
  569. package/src/status/bar.ts +34 -6
  570. package/src/status/metrics.ts +12 -1
  571. package/src/status/status-provider-info.ts +37 -6
  572. package/src/steward/rejudge-tick.ts +22 -7
  573. package/src/steward/resync-tick.ts +31 -4
  574. package/src/steward/ta-repair-event-collect.ts +17 -6
  575. package/src/task-agent/actions.ts +202 -5
  576. package/src/task-agent/boundary-proof-mapping.ts +12 -0
  577. package/src/task-agent/boundary-proof-producer.ts +147 -0
  578. package/src/task-agent/completion-evidence.ts +2 -1
  579. package/src/task-agent/green-close-recipe.ts +239 -0
  580. package/src/task-agent/green-sweep.ts +64 -10
  581. package/src/task-agent/land-queue.ts +21 -8
  582. package/src/task-agent/live-moves.ts +70 -9
  583. package/src/task-agent/map-host-adapter.ts +134 -0
  584. package/src/task-agent/map-reduce.ts +158 -0
  585. package/src/task-agent/map-run-ledger.ts +226 -0
  586. package/src/task-agent/mission.ts +30 -0
  587. package/src/task-agent/parent-host.ts +21 -11
  588. package/src/task-agent/rejudge-on-head.ts +87 -5
  589. package/src/task-agent/repair-cycle.ts +179 -32
  590. package/src/task-agent/repair-next-move.ts +42 -4
  591. package/src/task-agent/repair-outcomes.ts +29 -0
  592. package/src/task-agent/repair-worker.ts +14 -4
  593. package/src/task-agent/review-prior-fix.ts +12 -2
  594. package/src/task-agent/shadow.ts +229 -8
  595. package/src/task-agent/task-card-prefix.ts +2 -0
  596. package/src/task-agent/task-hand.ts +630 -30
  597. package/src/task-agent/task-parent-role-llm.ts +45 -0
  598. package/src/task-agent/tier-split.ts +80 -10
  599. package/src/task-agent/work-order.ts +53 -2
  600. package/src/task-orchestrator/dispatcher.ts +46 -1
  601. package/src/task-orchestrator/generator-prompt.ts +6 -0
  602. package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
  603. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +16 -6
  604. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  605. package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
  606. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  607. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  608. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +8 -6
  609. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +97 -0
  610. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
  611. package/src/task-orchestrator/surfaces/pod-pool.ts +126 -8
  612. package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
  613. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  614. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  615. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  616. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  617. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  618. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  619. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  620. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
  621. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +491 -36
  622. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  623. package/src/task-orchestrator/surfaces/self-implement-pod.ts +612 -54
  624. package/src/task-orchestrator/surfaces/self-implement.ts +46 -2
  625. package/src/testing/linux-env.ts +177 -0
  626. package/src/tool-runtime/index.ts +15 -2
  627. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  628. package/src/tty-foreground.ts +155 -0
  629. package/src/tui/chat/goal-interim.ts +177 -0
  630. package/src/tui/chat/log-view.ts +205 -18
  631. package/src/tui/chat/self-health-status.ts +232 -0
  632. package/src/tui/entry.ts +623 -80
  633. package/src/tui/input/at-picker.ts +55 -0
  634. package/src/tui/input/composer.ts +8 -1
  635. package/src/tui/slash/compact-command.ts +7 -0
  636. package/src/tui/slash/compact.ts +1 -7
  637. package/src/tui/slash/resume.ts +98 -0
  638. package/src/tui/slash/signals.ts +114 -0
  639. package/src/tui/slash/term-next.ts +71 -0
  640. package/src/tui-client/local-chat-turn.ts +49 -5
  641. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  642. package/src/tui-client/next-loop-command.ts +70 -0
  643. package/src/tui-client/next-wakeup.ts +191 -0
  644. package/src/tui.ts +37 -0
  645. package/src/ui/modal-adapter.ts +2 -2
  646. package/src/user-config.ts +19 -1
  647. package/src/ux-sim/boot-daemon-tools-pty-shell-device.ts +136 -0
  648. package/src/ux-sim/classic-tui-seat-scenarios.ts +670 -0
  649. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  650. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  651. package/src/ux-sim/event-monkey.ts +3 -2
  652. package/src/ux-sim/fake-bin.ts +45 -0
  653. package/src/ux-sim/fake-gh.ts +174 -0
  654. package/src/ux-sim/fake-herdr.ts +238 -0
  655. package/src/ux-sim/fake-kubectl.ts +142 -0
  656. package/src/ux-sim/fake-llm.ts +116 -6
  657. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  658. package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
  659. package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
  660. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  661. package/src/ux-sim/goal-device.ts +619 -0
  662. package/src/ux-sim/in-process-cli.ts +22 -5
  663. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  664. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  665. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  666. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  667. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  668. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  669. package/src/ux-sim/next-tui-seat-scenarios.ts +749 -0
  670. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  671. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  672. package/src/ux-sim/resume-picker-device.ts +173 -0
  673. package/src/ux-sim/session-id-seed.ts +60 -0
  674. package/src/ux-sim/skills-tools-shell-device.ts +156 -0
  675. package/src/ux-sim/subagent-tools-device.ts +81 -0
  676. package/src/ux-sim/task-agent-parent-host-device.ts +264 -0
  677. package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
  678. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  679. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  680. package/src/version/packed-revision.json +1 -1
  681. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
  682. package/apps/pwa/out/_next/static/chunks/1674.2a65fd5668e1cc5f.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
  684. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
  685. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
  694. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
  696. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
  697. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
  699. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
  701. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
  705. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/3677-4215f826f6aa68e5.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
  708. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/4346.8601952e73bf5803.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
  712. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
  715. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
  724. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +0 -94
  725. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/56d372f2.681ab4ec4c998fae.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
  729. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
  736. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
  739. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
  741. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
  747. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
  748. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
  758. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
  760. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/8637.47f5b35afcae5e6b.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
  767. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
  795. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
  802. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
  803. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
  804. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
  805. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
  806. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
  807. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
  808. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
  809. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
  810. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
  811. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
  812. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
  813. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
  814. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
  815. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
  816. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
  817. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
  818. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
  819. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
  820. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
  821. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
  822. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
  823. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
  824. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
  825. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
  826. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
  827. /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_ssgManifest.js +0 -0
@@ -1523,7 +1523,7 @@ export async function routeRequest(
1523
1523
  if (method === 'POST' && pathname === '/v1/graphs/wizard') {
1524
1524
  if (!opts.metaApi) return jsonResponse({ error: 'meta-api-not-wired' }, 503);
1525
1525
  if (!checkAuth(req, opts.metaApi)) return jsonResponse({ error: 'unauthorized' }, 401);
1526
- return handleGraphWizardPost(req, opts.graphWizard);
1526
+ return handleGraphWizardPost(req, opts.graphWizard, opts.eventBus);
1527
1527
  }
1528
1528
 
1529
1529
  if (pathname === '/v1/fabric/decompose' || pathname.startsWith('/v1/fabric/plans/')) {
@@ -11,6 +11,7 @@ import { createSeatsCache, todayKst } from './ops-seats.js';
11
11
  import { liveSeatsSources } from './ops-seats-sources.js';
12
12
  import { createOverviewCache } from '../../ops/overview-cache.js';
13
13
  import { resourcesFromOverview } from '../../ops/resources.js';
14
+ import { loopsMapFromCache } from '../../ops/loops-map.js';
14
15
  import { parseSince } from '../../ops/overview-collect.js';
15
16
  import type { MetaApiOpts } from './meta-api.js';
16
17
 
@@ -184,6 +185,14 @@ export function readReleaseRuns(version: string | null = null,
184
185
  }).sort((a, b) => b.startedAt.localeCompare(a.startedAt)).slice(0, 20);
185
186
  }
186
187
 
188
+ /**
189
+ * 요청이 «자격을 하나라도 실어 왔는가» — operatorSignal 이 판정에 쓰는 축(베어러·프록시 헤더·쿠키)만 본다.
190
+ * 아무것도 없으면 401(인증 없음), 있는데 운영자가 아니면 403(권한 없음)으로 가른다.
191
+ */
192
+ function offeredCredential(req: Request): boolean {
193
+ return Boolean(req.headers.get('authorization') || req.headers.get('x-elanous-operator') || req.headers.get('cookie'));
194
+ }
195
+
187
196
  /** The sole data gate for every read-only /v1/ops endpoint. */
188
197
  export function handleOpsApi(req: Request, metaApi: MetaApiOpts | undefined): Response | Promise<Response> {
189
198
  const url = new URL(req.url);
@@ -195,6 +204,9 @@ export function handleOpsApi(req: Request, metaApi: MetaApiOpts | undefined): Re
195
204
  debug.log('ops.api', 'refused', { path: pathname, source: signal.operatorSource });
196
205
  // RES-FLOOR-API: no credential was offered at all — this endpoint names it 401; every other path keeps 403.
197
206
  if (pathname === '/v1/ops/resources') return jsonResponse({ error: 'unauthorized' }, 401);
207
+ // LOOP-MAP-API: a request that offers no credential at all is 401 in the same body shape;
208
+ // a credential that is not an operator stays 403, exactly like the neighbouring ops paths.
209
+ if (pathname === '/v1/ops/loops-map' && !offeredCredential(req)) return jsonResponse({ error: 'unauthorized' }, 401);
198
210
  return jsonResponse({ error: 'forbidden' }, 403);
199
211
  }
200
212
  const served = (response: Response): Response => {
@@ -226,12 +238,8 @@ export function handleOpsApi(req: Request, metaApi: MetaApiOpts | undefined): Re
226
238
  // (name·era·beat cell observedAt; null/unmeasured value and reason preserved);
227
239
  // no new remote fan-out of its own. Loop-edge joining is a later shard.
228
240
  overviewCache ??= createOverviewCache();
229
- return overviewCache.get()
230
- .then((overview) => served(jsonResponse({
231
- generatedAt: overview.generatedAt,
232
- cacheAgeMs: overview.cacheAgeMs,
233
- loops: overview.loops.map((loop) => ({ name: loop.name, era: loop.era, beat: loop.beat })),
234
- })), () => jsonResponse({ error: 'overview-unavailable' }, 500));
241
+ // peek, not get: a cold cache answers «아직 캐시 없음» instead of starting a collection.
242
+ return Promise.resolve(served(jsonResponse(loopsMapFromCache(overviewCache.peek()))));
235
243
  }
236
244
  if (pathname === '/v1/ops/seats') {
237
245
  const date = url.searchParams.get('date') ?? todayKst();
@@ -28,7 +28,7 @@
28
28
  // daemon exit.
29
29
 
30
30
  import type { McpServerSpec } from '../../user-config.js';
31
- import { McpClient, McpConnectionError, type McpToolCallResult } from '../../mcp/client.js';
31
+ import { McpClient, McpConnectionError, type McpTool, type McpToolCallResult } from '../../mcp/client.js';
32
32
  import {
33
33
  createMcpProxyRuntime,
34
34
  createMcpToolAuthorizer,
@@ -36,13 +36,13 @@ import {
36
36
  import { registerToolRuntime, unregisterToolRuntime } from '../../tool-runtime/registry.js';
37
37
  import { debug, redactSecretText } from '../../debug/log.js';
38
38
  import { elanousStateRoot } from '../../autopilot/state-paths.js';
39
- import { spawn as nodeSpawn } from 'node:child_process';
39
+ import { spawn as nodeSpawn, type ChildProcess } from 'node:child_process';
40
40
  import { listNodeKinds } from '../../graph-kinds/registry.js';
41
41
  import { syncInstalledPluginNodes } from '../../graph-kinds/installed-plugin-nodes.js';
42
42
  import { listInstalledPlugins } from '../../plugins/install/plugin-install.js';
43
43
  import { pluginEnv, credentialStatus } from '../../plugins/install/plugin-credentials.js';
44
- import { existsSync, realpathSync } from 'node:fs';
45
- import { resolve, sep } from 'node:path';
44
+ import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
45
+ import { join, resolve, sep } from 'node:path';
46
46
 
47
47
  export interface McpClientsHandle {
48
48
  /** Live clients (one per successfully started server). */
@@ -56,6 +56,9 @@ export interface McpClientsHandle {
56
56
  // ⇒ 노출하지 않는다. 허가 상태는 「등록된 런타임이 거부하나」로 «행동»으로 관측한다.
57
57
  /** Stop all clients gracefully and revoke this handle's grants. Safe to call multiple times. */
58
58
  shutdown(): Promise<void>;
59
+ /** 동기 마지막 수단 — 프로세스 exit 훅은 `await` 할 수 없다. 살아 있는 자식에
60
+ * SIGTERM 만 «즉시» 쏘고 신호를 보낸 수를 돌려준다(유예·SIGKILL 은 `shutdown` 몫). */
61
+ terminateChildrenSync?(): number;
59
62
  }
60
63
 
61
64
  export interface McpServerBootResult {
@@ -65,6 +68,10 @@ export interface McpServerBootResult {
65
68
  status: 'ready' | 'disabled' | 'failed';
66
69
  /** Number of tools registered from this server. 0 unless status=='ready'. */
67
70
  toolCount: number;
71
+ /** When status=='ready' under `lazy`: the tools above were announced from the
72
+ * cached tool index and the child has NOT been spawned yet — the first
73
+ * `callTool` on one of them spawns it (once). Absent = spawned eagerly. */
74
+ deferred?: boolean;
68
75
  /** When status=='failed', the error message captured (string only —
69
76
  * callers should not depend on Error identity). */
70
77
  reason?: string;
@@ -126,8 +133,33 @@ export interface RegisterMcpClientsOpts {
126
133
  setTimeoutFn?: (cb: () => void, ms: number) => { unref?(): void };
127
134
  /** Test seam — replaces `clearTimeout`. */
128
135
  clearTimeoutFn?: (handle: { unref?(): void }) => void;
136
+ /** CLASSIC-IDLE-MCP-LAZY (0.2.35) — classic TUI 백그라운드 경량화.
137
+ * true 면 자식은 «기동 때»가 아니라 «첫 도구 호출» 때 한 번 뜬다.
138
+ * 그 전까지 알리는 툴 «목록»은 지난 부팅이 적어 둔 인덱스
139
+ * (`MCP_TOOL_INDEX_FILENAME`) 그대로다 — 목록·권한은 무변경.
140
+ * 인덱스가 없는 서버(콜드 스타트)는 종전대로 즉시 기동하고 인덱스를 적는다. */
141
+ lazy?: boolean;
142
+ /** `lazy` 가 읽고 쓰는 툴 인덱스. 기본은 상태 루트의 `mcp-tool-index.json`. */
143
+ toolIndexStore?: McpToolIndexStore;
144
+ /** `lazy` 자식의 SIGTERM→SIGKILL 유예(ms). 기본 2500 — 종료 3초 계약 안쪽. */
145
+ lazyShutdownGraceMs?: number;
129
146
  }
130
147
 
148
+ /** 한 서버가 지난 부팅에서 알린 툴 목록. `mcp-tool-index.json` 의 값. */
149
+ export type McpToolIndex = Record<string, McpTool[]>;
150
+
151
+ /** 툴 목록 캐시의 읽기/쓰기 자리 — 테스트가 임시 저장소로 갈아 끼운다. */
152
+ export interface McpToolIndexStore {
153
+ read(): McpToolIndex;
154
+ write(index: McpToolIndex): void;
155
+ }
156
+
157
+ export const MCP_TOOL_INDEX_FILENAME = 'mcp-tool-index.json';
158
+
159
+ /** 지연 기동 자식의 정리 유예. `McpClient` 기본 5000ms 는 「SIGTERM 3초 안에
160
+ * 안 끝남」이던 classic 종료 계약을 넘긴다 — 2500ms 면 SIGKILL 까지 3초 안쪽. */
161
+ const DEFAULT_LAZY_SHUTDOWN_GRACE_MS = 2500;
162
+
131
163
  const DEFAULT_HANDSHAKE_TIMEOUT_MS = 8000;
132
164
 
133
165
  /** Race `op` against a timeout. Resolves to `op` on success; rejects
@@ -151,6 +183,60 @@ function withTimeout<T>(
151
183
  });
152
184
  }
153
185
 
186
+ type DeferredInner = Pick<McpClient, 'start' | 'listTools' | 'callTool' | 'dispose'>;
187
+
188
+ /** 첫 도구 호출까지 자식을 띄우지 않는 MCP 클라이언트 프록시.
189
+ * - `callTool` 이 «한 번» 기동하고 동시 호출은 같은 기동을 기다린다.
190
+ * - 기동 실패는 캐시하지 않는다 — 자식이 늦게 뜨면 다음 호출이 다시 시도한다.
191
+ * - `dispose()` 는 진행 중 기동을 먼저 기다린다 — 자식이 새지 않는다. */
192
+ class DeferredMcpClient implements DeferredInner {
193
+ private pending: Promise<void> | null = null;
194
+ private started = false;
195
+ private disposed = false;
196
+
197
+ constructor(
198
+ private readonly inner: DeferredInner,
199
+ private readonly boot: () => Promise<void>,
200
+ private readonly serverId: string,
201
+ ) {}
202
+
203
+ get spawned(): boolean { return this.started; }
204
+
205
+ async start(): Promise<void> { await this.ensureStarted(); }
206
+
207
+ async listTools(): Promise<McpTool[]> {
208
+ await this.ensureStarted();
209
+ return this.inner.listTools();
210
+ }
211
+
212
+ async callTool(name: string, args: Record<string, unknown>): Promise<McpToolCallResult> {
213
+ await this.ensureStarted();
214
+ // ⚠️ 기동 «뒤»의 inner.callTool 을 부른다 — 자격증명 마스킹 래퍼가
215
+ // createClient 직후 client.callTool 에 씌워지므로 그 래퍼를 탄다.
216
+ return this.inner.callTool(name, args);
217
+ }
218
+
219
+ async dispose(): Promise<void> {
220
+ this.disposed = true;
221
+ if (this.pending) {
222
+ try { await this.pending; } catch { /* 기동 실패는 정리를 막지 않는다 */ }
223
+ }
224
+ try { await this.inner.dispose(); } catch { /* dispose() is best-effort */ }
225
+ }
226
+
227
+ private async ensureStarted(): Promise<void> {
228
+ if (this.disposed) {
229
+ throw new Error(`mcp.${this.serverId}: lazy client was disposed before its first tool call`);
230
+ }
231
+ if (this.started) return;
232
+ if (!this.pending) {
233
+ this.pending = this.boot().then(() => { this.started = true; });
234
+ this.pending.catch(() => { this.pending = null; });
235
+ }
236
+ await this.pending;
237
+ }
238
+ }
239
+
154
240
  export interface McpBootLogger {
155
241
  info(line: string): void;
156
242
  warn(line: string): void;
@@ -196,6 +282,9 @@ export async function registerMcpClients(
196
282
  debug.log('mcp.client.boot', event, { id, ...safe });
197
283
  } catch { /* logger must never throw the boot */ }
198
284
  };
285
+ // 이 부팅이 띄운 자식들. 지연 기동이면 «첫 도구 호출» 뒤에야 채워지고,
286
+ // 프로세스가 그냥 죽는 경로(exit 훅)에서는 여기 남은 자식에 SIGTERM 을 쏜다.
287
+ const spawnedChildren = new Set<ChildProcess>();
199
288
  const createClient =
200
289
  opts.createClient ??
201
290
  ((spec: McpServerSpec) => {
@@ -221,6 +310,8 @@ export async function registerMcpClients(
221
310
  const selected = commandOwners.length === 1 && owners.length === 1 && owners[0] === commandOwners[0]
222
311
  ? commandOwners[0] : undefined;
223
312
  return new McpClient({ id: spec.id, command: spec.command, logger: bootLogger(spec.id),
313
+ // 지연 기동이면 정리 유예를 좁힌다 — classic 종료는 3초 안에 끝나야 한다.
314
+ ...(opts.lazy === true ? { shutdownGraceMs: opts.lazyShutdownGraceMs ?? DEFAULT_LAZY_SHUTDOWN_GRACE_MS } : {}),
224
315
  spawn: (cmd, args) => {
225
316
  const declaredEnv = [...new Set(listInstalledPlugins(root).map(item => item.name))]
226
317
  .flatMap(name => credentialStatus(name, root).fields.map(field => field.env));
@@ -234,7 +325,10 @@ export async function registerMcpClients(
234
325
  Object.assign(childEnv, env);
235
326
  injectedValuesByServer.set(spec.id, Object.values(env));
236
327
  }
237
- return nodeSpawn(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'], env: childEnv });
328
+ const child = nodeSpawn(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'], env: childEnv });
329
+ spawnedChildren.add(child);
330
+ child.once('exit', () => { spawnedChildren.delete(child); });
331
+ return child;
238
332
  },
239
333
  });
240
334
  });
@@ -252,6 +346,66 @@ export async function registerMcpClients(
252
346
  const perServer: Record<string, McpServerBootResult> = {};
253
347
  let registered = 0;
254
348
 
349
+ // ── CLASSIC-IDLE-MCP-LAZY ────────────────────────────────────────────────
350
+ // classic TUI 는 MCP 서버 둘(xcodebuildmcp · aside mcp)을 «기동 때» 띄워
351
+ // 상주시켰다 — TUI 하나당 node⊕aside 자손 RSS 약 267MB, SIGTERM 3초 안에
352
+ // 안 끝남(0.2.35 OP 실측). ⇒ `lazy` 면 자식은 «첫 도구 호출» 때 한 번 뜨고,
353
+ // 그 전에 알리는 툴 «목록»은 지난 부팅이 적어 둔 인덱스 그대로다.
354
+ const lazy = opts.lazy === true;
355
+ const toolIndexStore = lazy ? (opts.toolIndexStore ?? defaultMcpToolIndexStore()) : undefined;
356
+ const toolIndex: McpToolIndex = toolIndexStore ? readToolIndex(toolIndexStore) : {};
357
+ const deferredClients: DeferredMcpClient[] = [];
358
+ const lazyToolsFor = (serverId: string): McpTool[] | undefined => {
359
+ if (!lazy) return undefined;
360
+ const cached = toolIndex[serverId];
361
+ return cached && cached.length > 0 ? cached : undefined;
362
+ };
363
+ const recordToolIndex = (serverId: string, tools: readonly McpTool[]): void => {
364
+ if (!toolIndexStore) return;
365
+ toolIndex[serverId] = [...tools];
366
+ toolIndexStore.write(toolIndex);
367
+ };
368
+ const logLazyBoot = (
369
+ serverId: string,
370
+ reason: 'deferred' | 'first-call' | 'no-index',
371
+ toolCount?: number,
372
+ ): void => {
373
+ try {
374
+ debug.log('mcp.client', 'lazy-boot', {
375
+ server: serverId,
376
+ reason,
377
+ ...(toolCount === undefined ? {} : { toolCount }),
378
+ });
379
+ } catch { /* logger must never throw the boot */ }
380
+ };
381
+ /** 허가 관문 보고 — 지연·즉시 두 경로가 «같은 문면»을 낸다. */
382
+ const reportAuthorization = (serverId: string, tools: readonly { name: string }[]): void => {
383
+ const grantedCount = tools.filter((t) => authorizer.isGranted(serverId, t.name)).length;
384
+ if (tools.length > 0 && grantedCount === 0) {
385
+ logger.warn(
386
+ // ⛔ 접두 «라벨»도 같은 문자열이다 — 본문만 이스케이프하면 개행이 여기로 샌다.
387
+ `[nexus] mcp-client ${JSON.stringify(serverId)}: ${tools.length} tool(s) registered but NONE authorized — every call will be denied. ` +
388
+ // ⛔ 「복사해 붙일 수 있게」라고 말하려면 «붙일 수 있는 것»을 줘야 한다.
389
+ // ⇒ 서버 항목 «전체»를 흉내 내지 말고 ***더할 필드 한 줄***만 준다.
390
+ `Add this field to the ${JSON.stringify(serverId)} entry of mcp.servers in your elanous config: ` +
391
+ `"authorizedTools": [${tools.slice(0, 3).map((t) => JSON.stringify(t.name)).join(', ')}]`,
392
+ );
393
+ } else if (grantedCount < tools.length) {
394
+ logger.warn(
395
+ `[nexus] mcp-client ${JSON.stringify(serverId)}: ${tools.length} tool(s) registered but only ${grantedCount} authorized — unlisted tool calls will be denied.`,
396
+ );
397
+ }
398
+ debug.log('mcp.authorization', 'boot-summary', {
399
+ serverId,
400
+ toolCount: tools.length,
401
+ grantedCount,
402
+ });
403
+ logger.info(
404
+ `[nexus] mcp-client connected: ${serverId} (${tools.length} tool${tools.length === 1 ? '' : 's'}` +
405
+ `${grantedCount === tools.length ? '' : ` · ${grantedCount} authorized`})`,
406
+ );
407
+ };
408
+
255
409
  if (opts.servers.some(spec => spec.transport === 'stdio') && !opts.createClient) {
256
410
  try { syncInstalledPluginNodes(elanousStateRoot()); }
257
411
  catch (error) { debug.log('graph.kinds', 'installed-sync-failed', { reason: String(error) }); }
@@ -280,6 +434,45 @@ export async function registerMcpClients(
280
434
  }
281
435
  };
282
436
  }
437
+ const announced = lazyToolsFor(spec.id);
438
+ if (lazy && !announced) logLazyBoot(spec.id, 'no-index');
439
+ if (announced) {
440
+ // ⭐ 지연 기동 — 여기서 자식은 «하나도» 안 뜬다. 허가는 즉시 경로와
441
+ // 같은 관문에 미리 넣고, 등록하는 툴은 지난 부팅이 알린 목록 그대로다.
442
+ for (const toolName of spec.authorizedTools ?? []) {
443
+ authorizer.grant({ serverId: spec.id, toolName });
444
+ }
445
+ const deferred = new DeferredMcpClient(client, async () => {
446
+ await withTimeout(`mcp.${spec.id}.start`, () => client!.start(), serverHandshakeTimeoutMs, setTimeoutFn, clearTimeoutFn);
447
+ const live = await withTimeout(
448
+ `mcp.${spec.id}.listTools`,
449
+ () => client!.listTools(),
450
+ serverHandshakeTimeoutMs,
451
+ setTimeoutFn,
452
+ clearTimeoutFn,
453
+ );
454
+ // 이제 자식이 있다 — 리소스 경로·종료 스냅샷이 보는 clients 에 넣는다.
455
+ clients.push(client!);
456
+ recordToolIndex(spec.id, live);
457
+ logLazyBoot(spec.id, 'first-call', live.length);
458
+ }, spec.id);
459
+ deferredClients.push(deferred);
460
+ for (const t of announced) {
461
+ const runtime = createMcpProxyRuntime({
462
+ serverId: spec.id,
463
+ mcpTool: t,
464
+ client: deferred,
465
+ authorizer,
466
+ });
467
+ register(runtime);
468
+ registeredIds.push(runtime.id);
469
+ registered += 1;
470
+ }
471
+ perServer[spec.id] = { status: 'ready', toolCount: announced.length, deferred: true };
472
+ reportAuthorization(spec.id, announced);
473
+ logLazyBoot(spec.id, 'deferred', announced.length);
474
+ continue;
475
+ }
283
476
  await withTimeout(`mcp.${spec.id}.start`, () => client!.start(), serverHandshakeTimeoutMs, setTimeoutFn, clearTimeoutFn);
284
477
  const tools = await withTimeout(
285
478
  `mcp.${spec.id}.listTools`,
@@ -304,37 +497,14 @@ export async function registerMcpClients(
304
497
  }
305
498
  clients.push(client);
306
499
  perServer[spec.id] = { status: 'ready', toolCount: tools.length };
500
+ // 콜드 스타트(인덱스 없음) 1회 뒤에는 다음 부팅이 지연 기동할 수 있게 적어 둔다.
501
+ if (lazy) recordToolIndex(spec.id, tools);
307
502
  // ⛔⭐ **금지에는 «길»을 붙인다.** 허가 관문은 fail-closed 라 `authorizedTools` 를
308
503
  // 안 적은 서버의 툴은 «전부» 거부된다 — 그것이 의도지만, 조용하면 사용자는
309
504
  // ***「어제 되던 툴이 오늘 안 된다」***만 겪고 이유도 고치는 법도 모른다.
310
505
  // ⇒ 붙었는데 허가가 «하나도 없는» 서버는 이름을 대고 «무엇을 적어야 하는지»까지 말한다.
311
506
  // ⚠️ 부팅을 막지는 않는다 — 이 배선의 계약은 「한 서버가 실패해도 계속」이다.
312
- const grantedCount = tools.filter((t) => authorizer.isGranted(spec.id, t.name)).length;
313
- if (tools.length > 0 && grantedCount === 0) {
314
- logger.warn(
315
- // ⛔ 접두 «라벨»도 같은 문자열이다 — 본문만 이스케이프하면 개행이 여기로 샌다.
316
- `[nexus] mcp-client ${JSON.stringify(spec.id)}: ${tools.length} tool(s) registered but NONE authorized — every call will be denied. ` +
317
- // ⛔ 「복사해 붙일 수 있게」라고 말하려면 «붙일 수 있는 것»을 줘야 한다.
318
- // 초판은 `{"id":…, ..., "authorizedTools":[…]}` 를 줬는데 그 `...` 때문에
319
- // «유효한 JSON 이 아니었다» — 말과 산출이 어긋났다(리뷰가 잡음).
320
- // ⇒ 서버 항목 «전체»를 흉내 내지 말고 ***더할 필드 한 줄***만 준다.
321
- `Add this field to the ${JSON.stringify(spec.id)} entry of mcp.servers in your elanous config: ` +
322
- `"authorizedTools": [${tools.slice(0, 3).map((t) => JSON.stringify(t.name)).join(', ')}]`,
323
- );
324
- } else if (grantedCount < tools.length) {
325
- logger.warn(
326
- `[nexus] mcp-client ${JSON.stringify(spec.id)}: ${tools.length} tool(s) registered but only ${grantedCount} authorized — unlisted tool calls will be denied.`,
327
- );
328
- }
329
- debug.log('mcp.authorization', 'boot-summary', {
330
- serverId: spec.id,
331
- toolCount: tools.length,
332
- grantedCount,
333
- });
334
- logger.info(
335
- `[nexus] mcp-client connected: ${spec.id} (${tools.length} tool${tools.length === 1 ? '' : 's'}` +
336
- `${grantedCount === tools.length ? '' : ` · ${grantedCount} authorized`})`,
337
- );
507
+ reportAuthorization(spec.id, tools);
338
508
  } catch (err) {
339
509
  // ⛔⭐ **이 줄은 「방어적 no-op」이 아니다.** try 블록이 등록 «루프»까지 감싸므로,
340
510
  // 툴 3개 중 2개까지 `register()` 가 성공한 뒤 3번째가 던지면 ***이미 등록된 두 개가
@@ -381,6 +551,19 @@ export async function registerMcpClients(
381
551
  async shutdown() {
382
552
  // Snapshot + clear so a re-entrant call (e.g. SIGTERM races) is a no-op.
383
553
  const snapshot = clients.splice(0);
554
+ // 아직 «안 뜬» 지연 클라이언트도 여기서 내린다 — 기동 중이면 그 기동을
555
+ // 기다렸다가 내리므로 자식이 새지 않는다. 이미 뜬 것은 snapshot 이 맡는다.
556
+ const pendingDeferred = deferredClients.splice(0).filter((d) => !d.spawned);
557
+ // ⭐ 자식에게 SIGTERM 을 «먼저» 보낸다 — 유예(지연 기동 기본 2500ms)가 지나면
558
+ // SIGKILL 이라 종료 전체가 3초 안에 끝난다. 등록·허가 걷기는 그 뒤.
559
+ const teardown = [
560
+ ...snapshot.map((c) =>
561
+ c.dispose().catch(() => {
562
+ /* dispose() is best-effort; swallow */
563
+ }),
564
+ ),
565
+ ...pendingDeferred.map((d) => d.dispose().catch(() => { /* 아직 안 뜬 클라이언트 */ })),
566
+ ];
384
567
  for (const spec of opts.servers) authorizer.revokeServer(spec.id);
385
568
  // ⭐ 등록도 «되돌린다». 데몬 종료 때는 어차피 프로세스가 죽으니 무해하고,
386
569
  // 재장전 때는 ***이 줄이 없으면 다음 등록이 전부 id 충돌로 죽는다***.
@@ -389,18 +572,60 @@ export async function registerMcpClients(
389
572
  for (const id of ids) {
390
573
  try { unregister(id); } catch { /* best-effort */ }
391
574
  }
392
- await Promise.all(
393
- snapshot.map((c) =>
394
- c.dispose().catch(() => {
395
- /* dispose() is best-effort; swallow */
396
- }),
397
- ),
398
- );
575
+ await Promise.all(teardown);
399
576
  injectedValuesByServer.clear();
400
577
  },
578
+ terminateChildrenSync(): number {
579
+ let signalled = 0;
580
+ for (const child of [...spawnedChildren]) {
581
+ spawnedChildren.delete(child);
582
+ try {
583
+ if (child.exitCode === null && child.signalCode === null && child.kill('SIGTERM')) signalled += 1;
584
+ } catch {
585
+ /* 이미 죽은 자식 — 쏠 대상이 없다 */
586
+ }
587
+ }
588
+ return signalled;
589
+ },
590
+ };
591
+ }
592
+
593
+ /** 기본 툴 인덱스 저장소 — `<state>/mcp-tool-index.json`.
594
+ * ⚠️ 읽기·쓰기 모두 «부팅을 막지 않는다»: 깨진 JSON 은 빈 인덱스(콜드 스타트)로
595
+ * 떨어지고, 쓰기 실패는 debug 한 줄만 남긴다. */
596
+ export function defaultMcpToolIndexStore(root: string = elanousStateRoot()): McpToolIndexStore {
597
+ const file = join(root, MCP_TOOL_INDEX_FILENAME);
598
+ return {
599
+ read(): McpToolIndex {
600
+ try {
601
+ const parsed: unknown = JSON.parse(readFileSync(file, 'utf8'));
602
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {};
603
+ const index: McpToolIndex = {};
604
+ for (const [serverId, tools] of Object.entries(parsed as Record<string, unknown>)) {
605
+ if (!Array.isArray(tools)) continue;
606
+ const kept = tools.filter((tool): tool is McpTool =>
607
+ !!tool && typeof tool === 'object' && typeof (tool as { name?: unknown }).name === 'string');
608
+ if (kept.length > 0) index[serverId] = kept;
609
+ }
610
+ return index;
611
+ } catch { return {}; }
612
+ },
613
+ write(index: McpToolIndex): void {
614
+ try {
615
+ mkdirSync(root, { recursive: true });
616
+ writeFileSync(file, `${JSON.stringify(index, null, 2)}\n`, 'utf8');
617
+ } catch (error) {
618
+ try { debug.log('mcp.client', 'tool-index-write-failed', { reason: String(error) }); }
619
+ catch { /* logger must never throw the boot */ }
620
+ }
621
+ },
401
622
  };
402
623
  }
403
624
 
625
+ function readToolIndex(store: McpToolIndexStore): McpToolIndex {
626
+ try { return store.read(); } catch { return {}; }
627
+ }
628
+
404
629
  function defaultLogger(): McpBootLogger {
405
630
  return {
406
631
  info: (line) => console.info(line),
@@ -1,7 +1,7 @@
1
1
  import type { WizardIO } from '../../onboarding.js';
2
2
  import type { SetupCheckResult } from '../setup-status.js';
3
3
  import type { TailscaleProbe } from './tailscale-probe.js';
4
- import { createManagementStarterContract } from '../../persona/presets.js';
4
+ import { clonePreset, createManagementStarterContract, type PersonaPreset, type PersonaWriteOptions, type PersonaWriteResult } from '../../persona/presets.js';
5
5
 
6
6
  export interface FirstBootWizardDeps {
7
7
  io: WizardIO;
@@ -39,9 +39,12 @@ export type FirstBootResult =
39
39
 
40
40
  /** 직업 질문 답의 정규화 — «1»·«경영»·«management» 는 경영,
41
41
  * 나머지(빈 답 포함)는 일반(현재 첫 실행 동작 유지). */
42
- export function normalizeOccupationChoice(input: string): 'management' | 'general' {
42
+ export type OccupationChoice = 'management' | 'marketing' | 'general';
43
+
44
+ export function normalizeOccupationChoice(input: string): OccupationChoice {
43
45
  const v = input.trim().toLowerCase();
44
46
  if (v === '1' || v === '경영' || v === 'management') return 'management';
47
+ if (v === '3' || v === '마케팅' || v === 'marketing') return 'marketing';
45
48
  return 'general';
46
49
  }
47
50
 
@@ -108,6 +111,45 @@ function printPwaSetupBanner(deps: FirstBootWizardDeps): void {
108
111
  deps.io.print('');
109
112
  }
110
113
 
114
+ /** 0.2.35 PERSONA-STARTER-FU — 첫 실행 «마케팅» 스타터 계약 원본. 경계 계약상
115
+ * 완료 경계 코드(first-boot-wizard.ts) 안에서 기존 clonePreset 파이프라인으로
116
+ * persona store 에 정확히 한 장 쓴다. */
117
+ const MARKETING_STARTER_PRESET: PersonaPreset = {
118
+ personaId: 'starter-marketing',
119
+ displayName: '마케팅 스타터',
120
+ names: ['마케팅 스타터', '마케팅', 'starter-marketing'],
121
+ role: '마케팅 파트너',
122
+ title: '첫 실행 스타터',
123
+ oneLine: '고객·메시지·채널을 같이 세우는 짝.',
124
+ voice: {
125
+ rule: '짧고 단정하게 — 고객 말로 먼저, 근거 한 줄.',
126
+ examples: [
127
+ '이번 주 메시지는 하나로 좁힙니다 — 첫 화면에서 5초 안에 남는 문장.',
128
+ '그 채널은 도달 근거가 부족합니다 — 가장 싼 실험부터 하시죠.',
129
+ ],
130
+ },
131
+ tasks: [
132
+ { when: '아침 루프', what: '채널 반응·미결 발행물을 한 화면에 모아 첫 판단을 준다' },
133
+ { when: '메시지가 갈릴 때', what: '후보 문장을 셋으로 좁혀 고객·채널·되돌림 수단을 나란히 놓는다' },
134
+ { when: '주간 정산', what: '지난 발행과 실제 반응을 대조해 다음 메시지 기준을 고친다' },
135
+ ],
136
+ tools: [],
137
+ firstQuestions: [
138
+ '지금 가장 급한 고객 메시지는 무엇인가요?',
139
+ '이번 주에 꼭 내보낼 채널이 있나요?',
140
+ ],
141
+ doesNot: [
142
+ '고객 개인정보를 외부에 전송하지 않는다',
143
+ '합의되지 않은 광고·발행을 대신 실행하지 않는다',
144
+ ],
145
+ forWhom: '처음 elanous 를 여는 마케터 — 고객·메시지·채널을 함께 시작하려는 사람.',
146
+ };
147
+
148
+ /** 첫 실행 «마케팅» 선택이 부르는 유일한 제작 입구 — 스타터 계약 한 장을 persona store 에 쓴다. */
149
+ export function createMarketingStarterContract(opts: PersonaWriteOptions = {}): PersonaWriteResult {
150
+ return clonePreset(MARKETING_STARTER_PRESET, MARKETING_STARTER_PRESET.displayName, opts);
151
+ }
152
+
111
153
  /** 0.2.29 PERSONA-STARTER — 직업 질문. «경영»이면 경영 스타터 계약 한 장을
112
154
  * 만들고, 일반이면 계약 없이 현재 흐름 그대로. 계약 생성이 실패해도
113
155
  * wizard 결과는 completed 로 유지한다(fail-soft). */
@@ -120,20 +162,26 @@ async function askOccupationAndCreateStarter(
120
162
  io.print('');
121
163
  io.print(' 어떤 일을 하세요? 고르면 스타터 계약 한 장을 만듭니다.');
122
164
  io.print(' 1) 경영 — 방향·판단·운영을 함께 세우는 경영 스타터');
165
+ io.print(' 3) 마케팅 — 고객·메시지·채널을 함께 세우는 마케팅 스타터');
123
166
  io.print(' 2) 일반 — 지금처럼 계속 (스타터 계약 없이)');
124
167
  let answer: string;
125
168
  try {
126
- answer = await io.ask(' 선택 (1/2 · Enter=일반): ');
169
+ answer = await io.ask(' 선택 (1/2/3 · Enter=일반): ');
127
170
  } catch (err) {
128
171
  out.error(`first-boot wizard: occupation question failed: ${(err as Error).message}`);
129
172
  return undefined;
130
173
  }
131
- if (normalizeOccupationChoice(answer) !== 'management') return undefined;
174
+ const choice = normalizeOccupationChoice(answer);
175
+ if (choice === 'general') return undefined;
132
176
  try {
133
- const written = createManagementStarterContract(
134
- deps.starterContractDir ? { dir: deps.starterContractDir } : {},
135
- );
136
- io.print(` ✓ 경영 스타터 계약이 만들어졌습니다: ${written.path}`);
177
+ const written = choice === 'management'
178
+ ? createManagementStarterContract(
179
+ deps.starterContractDir ? { dir: deps.starterContractDir } : {},
180
+ )
181
+ : createMarketingStarterContract(
182
+ deps.starterContractDir ? { dir: deps.starterContractDir } : {},
183
+ );
184
+ io.print(` ✓ ${choice === 'management' ? '경영' : '마케팅'} 스타터 계약이 만들어졌습니다: ${written.path}`);
137
185
  return { personaId: written.personaId, displayName: written.displayName, path: written.path };
138
186
  } catch (err) {
139
187
  out.error(`first-boot wizard: starter contract failed: ${(err as Error).message}`);
@@ -113,7 +113,13 @@ export interface NexusEvent {
113
113
  // · tone? · glyph?). PWA's M4 `subscribeHudSegmentEvents`
114
114
  // synthesizes a FeedbackEnvelope { kind: 'hud.segment' } and routes
115
115
  // it through the M1 `applyHudSegmentEnvelope` accumulator.
116
- | 'hud.segment';
116
+ | 'hud.segment'
117
+ // GRAPH-WIZARD variant 관측 (ARG-L2-DESIGNER-FU1 · 2026-10-23) — POST /v1/graphs/wizard 의
118
+ // variant 한 턴이 끝날 때 호출 경계(handleGraphWizardPost)가 한 건 발행한다. `detail` =
119
+ // { mode: 'variant', status: 'composed'|'fallback-standard', reason, goal, templateId,
120
+ // growth?: { from, outcome, nodeId, returnTo? }, overlayId?, patches? }.
121
+ // SSE 구독자는 `?topics=graph.compose` 로 받는다.
122
+ | 'graph.compose';
117
123
  tabId?: string;
118
124
  detail?: Record<string, unknown>;
119
125
  }
@@ -32,6 +32,8 @@ import {
32
32
  decideFallback, normalizeFallbackChain, grokQuotaFromUsageSnapshot,
33
33
  type FallbackDecision, type FallbackInput, type FallbackStep, type RotationOutcome,
34
34
  } from './fallback-chain.js';
35
+ import { collectClaudePtyMaturitySample, judgeClaudePtyMaturity, type ClaudePtyMaturity } from './claude-pty-maturity.js';
36
+ import type { UsageOutcomesDeps } from '../budget/usage-outcomes.js';
35
37
  import { resolveGrokCredential } from '../grok/credential.js';
36
38
  import { getOpenRouterApiKey } from '../config.js';
37
39
  import { lookupOpenRouterModelSpec } from '../model-tier/llm-tier-map.js';
@@ -1087,6 +1089,29 @@ function richestCreditCandidate(candidates: readonly RotationCandidate[], reserv
1087
1089
  return creditCandidatesByBalance(candidates, reserve)[0];
1088
1090
  }
1089
1091
 
1092
+ /**
1093
+ * CLAUDE-FAILOVER-FU — 체인에 `claude-pty` 칸이 «있을 때만» 런 원장의 최근 표본을 읽어 성숙도를 낸다.
1094
+ *
1095
+ * ⛔ 다른 체인에서는 원장을 «안 읽는다» — 비용도 0 이고, claude 를 안 쓰는 구성의 판정 입력도 안 바뀐다.
1096
+ * ⛔ 읽기 실패·표본 결손을 «전환 가능»으로 접지 않는다 — `judgeClaudePtyMaturity(null)` 이
1097
+ * `sample-unreadable`(미성숙)을 내고, 판정은 `claude-pty-immature` 로 닫힌다.
1098
+ * ⛔ 예외도 삼켜 미성숙으로 닫는다 — 원장 I/O 때문에 폴백 판정 자체가 죽으면 안 된다.
1099
+ */
1100
+ function claudePtyMaturityForChain(
1101
+ chain: readonly FallbackStep[],
1102
+ ledger: UsageOutcomesDeps | undefined,
1103
+ ): ClaudePtyMaturity | undefined {
1104
+ if (!chain.includes('claude-pty')) return undefined;
1105
+ try {
1106
+ return judgeClaudePtyMaturity(collectClaudePtyMaturitySample(ledger ?? {}));
1107
+ } catch (error) {
1108
+ debug.log('oauth.claude-pty', 'maturity-read-failed', {
1109
+ reason: error instanceof Error ? error.message.slice(0, 120) : String(error).slice(0, 120),
1110
+ }, { level: 'warn' });
1111
+ return judgeClaudePtyMaturity(null);
1112
+ }
1113
+ }
1114
+
1090
1115
  export function resolveRunFallback(
1091
1116
  env: NodeJS.ProcessEnv = process.env,
1092
1117
  deps: {
@@ -1098,6 +1123,8 @@ export function resolveRunFallback(
1098
1123
  readonly openrouterAvailable?: boolean;
1099
1124
  /** codex 크레딧 잔액 «확인» seam — 안 주면 회전 후보의 크레딧 신호(잔액 > 0 · 보유 ≠ false)로 잰다. */
1100
1125
  readonly codexCreditsAvailable?: boolean;
1126
+ /** ⛔ 런 원장 «읽기» seam — 체인에 `claude-pty` 가 있을 때만 쓴다. 안 주면 실제 런 원장을 읽는다. */
1127
+ readonly claudePtyLedger?: UsageOutcomesDeps;
1101
1128
  } & Pick<FallbackInput, 'currentStep' | 'currentCredentialRateLimited'> = {},
1102
1129
  ): FallbackDecision {
1103
1130
  try {
@@ -1160,7 +1187,13 @@ export function resolveRunFallback(
1160
1187
  : explicitAccount ? (explicitAccountHasCredits(snapshot, creditReserve) ? [snapshot.current.name] : [])
1161
1188
  : codexCreditAccountNames(snapshot.candidates, creditReserve);
1162
1189
  const codexCreditsAvailable = effectiveChain.includes('codex-credits') && (deps.codexCreditsAvailable ?? creditAccounts.length > 0);
1163
- const fallbackBase = { rotation, chain: effectiveChain, grokAvailable, grokQuota, openrouterFallbackModel, openrouterAvailable, codexCreditsAvailable };
1190
+ // CLAUDE-FAILOVER-FU — 체인에 `claude-pty` 가 «있을 때만» 원장 성숙도를 재서 판정 입력에 싣는다.
1191
+ // ⛔ 없으면 `undefined` 이고 판정은 종전 그대로다(수집 0회 · 판정식 무변경).
1192
+ const claudePtyMaturity = claudePtyMaturityForChain(effectiveChain, deps.claudePtyLedger);
1193
+ const fallbackBase = {
1194
+ rotation, chain: effectiveChain, grokAvailable, grokQuota, openrouterFallbackModel, openrouterAvailable, codexCreditsAvailable,
1195
+ ...(claudePtyMaturity ? { claudePtyMaturity } : {}),
1196
+ };
1164
1197
  const fallbackInput: FallbackInput = deps.currentCredentialRateLimited === true && deps.currentStep
1165
1198
  ? { ...fallbackBase, currentStep: deps.currentStep, currentCredentialRateLimited: true }
1166
1199
  : { ...fallbackBase, ...(deps.currentStep ? { currentStep: deps.currentStep } : {}) };