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.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 1262.a89bb27a5b2f844e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1746.3563617ea64023a3.js +115 -0
- package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1dc5a567.9b092bfae3d7099b.js → 1ed5e8af.cf424815c7c0efad.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 2002-a43a3f380df873ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{13.02a07436dec15f89.js → 210.90b2cbd64926cf34.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 2283.edd9627b7bdfb546.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{6866-79aa5b4e47cac6aa.js → 2318-450e75d07605b8fe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 2375.bf364c85dbb6f085.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +148 -0
- package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +27 -0
- package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3199.6a1a9b0e6cd01dc6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 3578.4e9f9948a9a6f2f4.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +36 -0
- package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +90 -0
- package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +226 -0
- package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +287 -0
- package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 4313.76f232c304a15bde.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1165.bad13fc9151a7288.js → 4324.c99ba3e83eb1b691.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3f7c4ee5.3dde54f01a816613.js → 4337e36d.f42c3b391b3d8f20.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 4383.18e5c54db3a22c88.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 4725-34bed25720cc326b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5483-dd5d7697f6bdb106.js → 4833-7934c592c5569f00.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 4931.95cc6dbd230774ca.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 5046.7fd5cbd859299448.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +104 -0
- package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +1 -0
- package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/58edce7d.f1b0c72acf13b123.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +93 -0
- package/apps/pwa/out/_next/static/chunks/5952.294fc574a8625184.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → 5f6af561-f90b7a67f4f75d13.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +74 -0
- package/apps/pwa/out/_next/static/chunks/6252.240578f10952e091.js +34 -0
- package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 6680.6a693c28aae4cd19.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 6745-5a63492933959dd9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +149 -0
- package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 6819.be5c9c4d67f22922.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2833-0fe47af99ed13c29.js → 6971-fb5f9dc0a2cb5d2d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 709a918c.4fd3b4e2a32cb4e3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +41 -0
- package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7424.c0fe2a595d4232b5.js +23 -0
- package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +1 -0
- package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 7867.e8725745ddd1d940.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → 7c5ed21f-f286708e57cf88f7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 8080-40d781e7704d3671.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +77 -0
- package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +1 -0
- package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +286 -0
- package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +79 -0
- package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 8c58d09b.e8724a299658d86f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 9151.a2c51e93f9156dae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4441-875b97f5821ed58a.js → 9175-7d383df15a82e2be.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +1 -0
- package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +94 -0
- package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +1 -0
- package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +64 -0
- package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-3337c6a1328c2674.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-47c5d4db587266bd.js → page-1e5da297557d2354.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-1f5a60f70cb4dd0c.js → page-88a1edbff62eaf1d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/{page-bac7dee94e5eae4a.js → page-443364c9e4a23b31.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-dc0a532f5b9196ec.js → page-ac2c1e6169cfce57.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-c1c80e345fa9d6f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{d06f9160.a3d9062f95de8ad7.js → d9815f84.4918f682a45a8502.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → de8446d3.31b73eb239fecd7b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +1 -0
- package/apps/pwa/out/_next/static/css/{b5d88eba78a3d7bf.css → be9019f696217521.css} +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
- package/docs/goal-context/README.md +3 -0
- package/graphs/default-loop.yaml +6 -1
- package/graphs/drafts/recipes.yaml +27 -7
- package/graphs/implement-loop.yaml +24 -0
- package/graphs/release/recipes.yaml +6 -0
- package/graphs/release/release-loop.yaml +17 -4
- package/graphs/wizard/recipes.yaml +44 -0
- package/graphs/wizard/wizard-loop.yaml +44 -0
- package/graphs/work/draft-close.yaml +54 -0
- package/graphs/work/green-close.yaml +37 -0
- package/graphs/work/recipes.yaml +46 -1
- package/graphs/work/research-report.yaml +2 -0
- package/graphs/work/run-research.yaml +35 -0
- package/package.json +1 -1
- package/scripts/__fixtures__/authoring-paths-10x3.json +32 -0
- package/scripts/boundary-proof-mapping-audit.ts +88 -0
- package/scripts/ci-typecheck-changed.ts +139 -5
- package/scripts/codex-fallback-live-probe.ts +17 -15
- package/scripts/coord-role-pack.ts +1 -1
- package/scripts/first10-gate.ts +416 -0
- package/scripts/fleet/node-setup.sh +32 -2
- package/scripts/fleet/run-light-worker.sh +9 -0
- package/scripts/fleet/wsl-node-setup.sh +432 -0
- package/scripts/gate-0226-failure-census.ts +507 -0
- package/scripts/goals/authoring-metrics.ts +258 -0
- package/scripts/graph-units/draft-close-node.ts +222 -0
- package/scripts/hook-order-sweep.ts +7 -4
- package/scripts/land-global-checks.ts +69 -1
- package/scripts/measure-nl-routing-corpus.ts +207 -2
- package/scripts/release-loop/docs-node.ts +344 -8
- package/scripts/release-loop/gate-closure.ts +48 -0
- package/scripts/release-loop/gate-diff.ts +2 -1
- package/scripts/release-loop/gate-node.ts +249 -53
- package/scripts/release-loop/known-issues-node.ts +6 -4
- package/scripts/release-loop/node-verdict.ts +2 -0
- package/scripts/release-loop/notes-repair.ts +216 -0
- package/scripts/release-loop/prepare-node.ts +61 -5
- package/scripts/release-loop/resume-cap.ts +14 -34
- package/scripts/release-loop/resume-release.ts +151 -15
- package/scripts/release-loop/resume-test-traffic.ts +10 -0
- package/scripts/release-loop/traffic-node.ts +59 -0
- package/scripts/release-loop/traffic-transition.ts +159 -0
- package/scripts/release-loop/version-node.ts +81 -12
- package/scripts/rhythm/daily.ts +137 -3
- package/scripts/train/green-leg.ts +176 -0
- package/scripts/tui-continue-real-evidence.ts +47 -0
- package/scripts/ux-sim.ts +53 -0
- package/skills/README.md +1 -0
- package/src/acp/client.ts +31 -5
- package/src/acp/core-turn-bridge.ts +54 -6
- package/src/acp/stderr-summary.ts +49 -0
- package/src/agent/delegate-hint.ts +16 -0
- package/src/agent/monad-agent-turn.ts +1 -0
- package/src/agent/runner.ts +82 -2
- package/src/agent/task-notification.ts +56 -10
- package/src/agent/terminal-surface.ts +217 -0
- package/src/agent/types.ts +4 -0
- package/src/agent-substrate/pr-reviewer.ts +64 -4
- package/src/agent-substrate/review-intent.ts +29 -2
- package/src/agent-substrate/review-observation.ts +3 -0
- package/src/agent-substrate/self-review-cli.ts +490 -26
- package/src/autopilot/lineage/sources.ts +1 -1
- package/src/autopilot/mission-codebase-gate.ts +141 -12
- package/src/autopilot/pr-manager.ts +89 -18
- package/src/boot/daemon-runtime.ts +35 -3
- package/src/boot/daemon-tools/pty-shell.ts +2 -1
- package/src/boot/daemon-tools/self-implement.ts +1 -0
- package/src/budget/run-usage-rollup.ts +12 -7
- package/src/budget/unified-usage.ts +20 -0
- package/src/budget/usage-outcomes.ts +8 -4
- package/src/capture/tui-self-report.ts +132 -1
- package/src/chat/goal-continue-verdict.ts +41 -0
- package/src/chat/index.ts +30 -4
- package/src/chat/internal-turn-origin.ts +1 -0
- package/src/chat/paste-fold.ts +86 -0
- package/src/chat/tool-render/block.ts +32 -0
- package/src/chat/tool-render/dispatch.ts +2 -20
- package/src/chat/tool-render/result-text.ts +98 -0
- package/src/chat/turn-typeahead.ts +70 -7
- package/src/cli/autopilot-cli.ts +24 -9
- package/src/cli/config-audit.ts +119 -0
- package/src/cli/decisions-cli.ts +7 -4
- package/src/cli/doctor-cli.ts +137 -6
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/herdr-cli.ts +34 -0
- package/src/cli/light-entry-route.ts +6 -3
- package/src/cli/log-event-names.ts +2 -0
- package/src/cli/logs-cli.ts +357 -2
- package/src/cli/make-cli.ts +247 -11
- package/src/cli/memory-cli.ts +30 -1
- package/src/cli/msg-cli.ts +132 -14
- package/src/cli/pr-cli.ts +29 -16
- package/src/cli/pr-granularity.ts +5 -3
- package/src/cli/pr-land-base-read.ts +11 -2
- package/src/cli/pr-land-heavy-remote.ts +6 -3
- package/src/cli/pr-land-overlap-evidence.ts +23 -4
- package/src/cli/pr-land-recovery.ts +117 -1
- package/src/cli/pty-takeover-cli.ts +8 -7
- package/src/cli/release-checklist-read-cli.ts +109 -4
- package/src/cli/release-cli.ts +64 -15
- package/src/cli/release-single-flight.ts +1 -1
- package/src/cli/self-update.ts +23 -5
- package/src/cli/self-utterances-cli.ts +13 -16
- package/src/cli/tasks-card-show.ts +162 -0
- package/src/cli/tasks-cli.ts +868 -352
- package/src/cli/tasks-read-cli.ts +197 -0
- package/src/cli/usage-cli.ts +12 -10
- package/src/context-bus/claude-memory-import.ts +99 -0
- package/src/context-bus/long-term-memory.ts +125 -0
- package/src/core-turn/run-core-turn.ts +4 -2
- package/src/core-turn/run-goal-loop.ts +76 -16
- package/src/core-turn/types.ts +8 -1
- package/src/dashboard/chat/acp-chat.ts +9 -0
- package/src/dashboard/context/keys.ts +8 -31
- package/src/dashboard/index.ts +299 -62
- package/src/dashboard/input/agent-wake.ts +50 -1
- package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
- package/src/dashboard/input/chat-main-slash-command.ts +4 -2
- package/src/dashboard/input/goal-continue.ts +210 -0
- package/src/dashboard/input/goal-interim.ts +2 -0
- package/src/dashboard/input/internal-turn.ts +2 -8
- package/src/dashboard/input/seat-autowake.ts +9 -7
- package/src/dashboard/input/turn-autoheal.ts +52 -0
- package/src/dashboard/replay-preview.ts +25 -0
- package/src/dashboard/seat-boot-preamble.ts +132 -5
- package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -10
- package/src/dashboard/slash-runtime/model-choices.ts +15 -0
- package/src/dashboard/stale-install-check.ts +3 -99
- package/src/dashboard/synchronized-frame-output.ts +74 -0
- package/src/debug/batch-queue.ts +119 -0
- package/src/debug/tui-log-tag.ts +67 -0
- package/src/display/agent-surface.ts +7 -0
- package/src/display/coordinator.ts +45 -12
- package/src/display/resize-listener.ts +41 -20
- package/src/display/synchronized-output-region.ts +60 -0
- package/src/domains/standalone-log-sink.ts +15 -2
- package/src/domains/surface-events.ts +80 -1
- package/src/esc-abort-gate.ts +69 -0
- package/src/exec-requests/planner.ts +37 -2
- package/src/execution-loop/launch-gate.ts +4 -3
- package/src/git-fs/cli-stderr.ts +45 -0
- package/src/git-fs/gh-cli.ts +6 -3
- package/src/git-fs/git-cli.ts +11 -5
- package/src/git-fs/worktree.ts +95 -1
- package/src/graph-runner/graph-cli.ts +44 -2
- package/src/graph-runner/graph-run-api.ts +3 -2
- package/src/graph-runner/runner.ts +37 -16
- package/src/graph-wizard/generate.ts +131 -4
- package/src/graph-wizard/steps.ts +15 -0
- package/src/grounding/proactive-ground.ts +86 -0
- package/src/harness/control-inbox.ts +49 -1
- package/src/harness/harness-cli-command.ts +230 -40
- package/src/harness/harness-incidents.ts +52 -1
- package/src/harness/pod-control-send.ts +33 -5
- package/src/harness/review-adapter.ts +26 -6
- package/src/harness/self-send-remote.ts +69 -0
- package/src/harness/self-send-routing-guard.ts +6 -0
- package/src/harness/self-send-target.ts +4 -3
- package/src/index.ts +443 -25
- package/src/input-core/context-key-runtime.ts +21 -0
- package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
- package/src/light-cli.ts +6 -1
- package/src/llm/route-decision.ts +13 -0
- package/src/llm-tool-name.ts +37 -0
- package/src/llm-tool-schema.ts +35 -0
- package/src/llm-wellformed.ts +70 -0
- package/src/llm.ts +158 -15
- package/src/loops/checker.ts +100 -0
- package/src/loops/consensus.ts +26 -2
- package/src/loops/loop-cli.ts +9 -4
- package/src/loops/msg-wake.ts +35 -39
- package/src/loops/orchestrator/anomaly-cluster.ts +243 -0
- package/src/loops/orchestrator/inbox.ts +59 -11
- package/src/loops/orchestrator/knowhow-pack.ts +364 -0
- package/src/loops/orchestrator/tick.ts +54 -5
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/model-tier/llm-tier-map.ts +12 -17
- package/src/models/prompts.ts +17 -2
- package/src/msg/msg-post-office.ts +116 -0
- package/src/msg/msg-store.ts +17 -0
- package/src/mss/logging/log-store.ts +79 -22
- package/src/native-tool-catalog.ts +1 -1
- package/src/nexus/api/decisions-route.ts +38 -18
- package/src/nexus/api/graph-wizard-api.ts +46 -3
- package/src/nexus/api/grid.ts +24 -4
- package/src/nexus/api/http-server.ts +1 -1
- package/src/nexus/api/ops-api.ts +14 -6
- package/src/nexus/boot/register-mcp-clients.ts +263 -38
- package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
- package/src/nexus/state/state.ts +7 -1
- package/src/oauth/codex-account-store.ts +34 -1
- package/src/onboarding/first-run.ts +37 -6
- package/src/onboarding/web-first.ts +43 -11
- package/src/ops/loops-map.ts +46 -0
- package/src/ops/overview-cache.ts +22 -4
- package/src/ops/overview-collect.ts +12 -6
- package/src/ops/overview.ts +44 -8
- package/src/persona/loader.ts +11 -0
- package/src/persona/types.ts +8 -0
- package/src/policy/llm-policy.ts +3 -1
- package/src/prompt-enhance/enhance.ts +4 -4
- package/src/prompt-library/session-guidance.ts +14 -0
- package/src/provider-summary.ts +8 -0
- package/src/pty-shell/availability.ts +7 -0
- package/src/pty-shell/herdr-agent-report.ts +155 -37
- package/src/pty-shell/herdr-prompt.ts +266 -0
- package/src/pty-shell/herdr-prune-stale.ts +17 -0
- package/src/pty-shell/herdr-sequence-lease.ts +60 -0
- package/src/pty-shell/pty-control-ipc.ts +327 -15
- package/src/pty-shell/pty-special-keys.ts +42 -2
- package/src/pty-shell/registry.ts +25 -15
- package/src/pty-shell/stale-install-check.ts +99 -0
- package/src/pty-shell/tui-run-state.ts +249 -3
- package/src/release-loop/auto-start.ts +20 -2
- package/src/release-loop/checklist.ts +126 -9
- package/src/release-loop/feature-store.ts +9 -9
- package/src/release-loop/landed-but-yellow.ts +93 -12
- package/src/release-loop/rehearsal.ts +36 -20
- package/src/repl/index.ts +27 -1
- package/src/seat-loop/knowhow-lint.ts +1 -1
- package/src/seat-loop/seat-report.ts +1 -0
- package/src/self-dev/ask-launch-flow.ts +86 -10
- package/src/self-dev/decompose-proposal.ts +183 -20
- package/src/self-dev/decompose.ts +61 -0
- package/src/self-dev/dev-cli.ts +37 -3
- package/src/self-dev/dev-pipeline.ts +37 -9
- package/src/self-dev/draft-sweep.ts +241 -16
- package/src/self-dev/draft-triage-rules.ts +50 -5
- package/src/self-dev/glm-credential-guard.ts +77 -0
- package/src/self-dev/graph-journey-nodes.ts +1 -0
- package/src/self-dev/graph-journey-route.ts +12 -2
- package/src/self-dev/orchestrate-cli.ts +68 -3
- package/src/self-dev/orchestrate.ts +116 -17
- package/src/self-dev/review-provider-fallback.ts +45 -7
- package/src/self-dev/run-supervisor.ts +55 -2
- package/src/self-dev/run-types.ts +1 -1
- package/src/self-dev/shard-plan.ts +48 -0
- package/src/self-dev/shard-run.ts +50 -3
- package/src/self-health/autoheal.ts +153 -0
- package/src/self-health/signatures.ts +6 -0
- package/src/self-implement/device-first.ts +116 -0
- package/src/self-implement/doctor-visit.ts +322 -1
- package/src/self-implement/evidence-command-budget.ts +80 -0
- package/src/self-implement/gate-artifacts.ts +6 -2
- package/src/self-implement/gate-baseline.ts +64 -1
- package/src/self-implement/gate-cli.ts +93 -9
- package/src/self-implement/gate-remote.ts +28 -4
- package/src/self-implement/gate-scope.ts +13 -1
- package/src/self-implement/goal-author-cli.ts +1 -0
- package/src/self-implement/goal-author-decompose.ts +265 -4
- package/src/self-implement/goal-author.ts +366 -26
- package/src/self-implement/goal-elaborate.ts +176 -22
- package/src/self-implement/goal-refine.ts +3 -0
- package/src/self-implement/goal-supervisor-fill.ts +75 -26
- package/src/self-implement/graph-variant.ts +40 -6
- package/src/self-implement/headless-elanous-driver.ts +19 -3
- package/src/self-implement/importer-test-index.ts +215 -2
- package/src/self-implement/knowhow-pack.ts +5 -5
- package/src/self-implement/off-diff-evidence.ts +58 -6
- package/src/self-implement/orchestrator.ts +536 -42
- package/src/self-implement/pod-warm-pool-profile.ts +1 -0
- package/src/self-implement/pwa-import-graph.ts +1 -1
- package/src/self-implement/review-round-brief.ts +300 -0
- package/src/self-implement/rework-policy.ts +44 -0
- package/src/self-implement/run-ledger.ts +278 -6
- package/src/self-implement/run-stop.ts +1 -1
- package/src/self-implement/run-ttl.ts +38 -24
- package/src/self-implement/running-runs.ts +17 -3
- package/src/self-implement/scope-adjacency.ts +3 -1
- package/src/self-implement/seams.ts +72 -10
- package/src/self-implement/stop-autoheal.ts +1 -0
- package/src/self-implement/test-seams.ts +13 -1
- package/src/self-implement/train-reach-grouping.ts +8 -2
- package/src/self-implement/wiring-check.ts +358 -0
- package/src/session/chat.ts +7 -1
- package/src/session/id-prefix.ts +60 -0
- package/src/session/index.ts +4 -0
- package/src/session-runtime/index.ts +9 -1
- package/src/shell-env-bootstrap.ts +11 -4
- package/src/skills/runner.ts +4 -2
- package/src/skills/tools/agent.ts +290 -48
- package/src/skills/tools/pty.ts +5 -0
- package/src/skills/tools/schedule-wakeup.ts +23 -4
- package/src/skills/tools/shell.ts +61 -6
- package/src/skills/tools/terminal-modal-inject.ts +1 -2
- package/src/skills/tools/terminal-modal.ts +10 -8
- package/src/skills/url-router.ts +41 -1
- package/src/smart-wizard/run.ts +66 -0
- package/src/status/bar.ts +34 -6
- package/src/status/metrics.ts +12 -1
- package/src/status/status-provider-info.ts +37 -6
- package/src/steward/rejudge-tick.ts +22 -7
- package/src/steward/resync-tick.ts +31 -4
- package/src/steward/ta-repair-event-collect.ts +17 -6
- package/src/task-agent/actions.ts +202 -5
- package/src/task-agent/boundary-proof-mapping.ts +12 -0
- package/src/task-agent/boundary-proof-producer.ts +147 -0
- package/src/task-agent/completion-evidence.ts +2 -1
- package/src/task-agent/green-close-recipe.ts +239 -0
- package/src/task-agent/green-sweep.ts +64 -10
- package/src/task-agent/land-queue.ts +21 -8
- package/src/task-agent/live-moves.ts +70 -9
- package/src/task-agent/map-host-adapter.ts +134 -0
- package/src/task-agent/map-reduce.ts +158 -0
- package/src/task-agent/map-run-ledger.ts +226 -0
- package/src/task-agent/mission.ts +30 -0
- package/src/task-agent/parent-host.ts +21 -11
- package/src/task-agent/rejudge-on-head.ts +87 -5
- package/src/task-agent/repair-cycle.ts +179 -32
- package/src/task-agent/repair-next-move.ts +42 -4
- package/src/task-agent/repair-outcomes.ts +29 -0
- package/src/task-agent/repair-worker.ts +14 -4
- package/src/task-agent/review-prior-fix.ts +12 -2
- package/src/task-agent/shadow.ts +229 -8
- package/src/task-agent/task-card-prefix.ts +2 -0
- package/src/task-agent/task-hand.ts +630 -30
- package/src/task-agent/task-parent-role-llm.ts +45 -0
- package/src/task-agent/tier-split.ts +80 -10
- package/src/task-agent/work-order.ts +53 -2
- package/src/task-orchestrator/dispatcher.ts +46 -1
- package/src/task-orchestrator/generator-prompt.ts +6 -0
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +16 -6
- package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
- package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +8 -6
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +97 -0
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +126 -8
- package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
- package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
- package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +491 -36
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +612 -54
- package/src/task-orchestrator/surfaces/self-implement.ts +46 -2
- package/src/testing/linux-env.ts +177 -0
- package/src/tool-runtime/index.ts +15 -2
- package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
- package/src/tty-foreground.ts +155 -0
- package/src/tui/chat/goal-interim.ts +177 -0
- package/src/tui/chat/log-view.ts +205 -18
- package/src/tui/chat/self-health-status.ts +232 -0
- package/src/tui/entry.ts +623 -80
- package/src/tui/input/at-picker.ts +55 -0
- package/src/tui/input/composer.ts +8 -1
- package/src/tui/slash/compact-command.ts +7 -0
- package/src/tui/slash/compact.ts +1 -7
- package/src/tui/slash/resume.ts +98 -0
- package/src/tui/slash/signals.ts +114 -0
- package/src/tui/slash/term-next.ts +71 -0
- package/src/tui-client/local-chat-turn.ts +49 -5
- package/src/tui-client/next-dashboard-runtime.ts +8 -0
- package/src/tui-client/next-loop-command.ts +70 -0
- package/src/tui-client/next-wakeup.ts +191 -0
- package/src/tui.ts +37 -0
- package/src/ui/modal-adapter.ts +2 -2
- package/src/user-config.ts +19 -1
- package/src/ux-sim/boot-daemon-tools-pty-shell-device.ts +136 -0
- package/src/ux-sim/classic-tui-seat-scenarios.ts +670 -0
- package/src/ux-sim/cli-config-audit-device.ts +121 -0
- package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
- package/src/ux-sim/event-monkey.ts +3 -2
- package/src/ux-sim/fake-bin.ts +45 -0
- package/src/ux-sim/fake-gh.ts +174 -0
- package/src/ux-sim/fake-herdr.ts +238 -0
- package/src/ux-sim/fake-kubectl.ts +142 -0
- package/src/ux-sim/fake-llm.ts +116 -6
- package/src/ux-sim/fault-glm-no-credential.ts +116 -0
- package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
- package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
- package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
- package/src/ux-sim/goal-device.ts +619 -0
- package/src/ux-sim/in-process-cli.ts +22 -5
- package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
- package/src/ux-sim/mock-authoring-first-run.ts +97 -0
- package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
- package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
- package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
- package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
- package/src/ux-sim/next-tui-seat-scenarios.ts +749 -0
- package/src/ux-sim/onboarding-first-run-device.ts +269 -0
- package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
- package/src/ux-sim/resume-picker-device.ts +173 -0
- package/src/ux-sim/session-id-seed.ts +60 -0
- package/src/ux-sim/skills-tools-shell-device.ts +156 -0
- package/src/ux-sim/subagent-tools-device.ts +81 -0
- package/src/ux-sim/task-agent-parent-host-device.ts +264 -0
- package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
- package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
- package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
- package/apps/pwa/out/_next/static/chunks/1674.2a65fd5668e1cc5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
- package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
- package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
- package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
- package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
- package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
- package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
- package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
- package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3677-4215f826f6aa68e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
- package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4346.8601952e73bf5803.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
- package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
- package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/56d372f2.681ab4ec4c998fae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
- package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
- package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
- package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
- package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
- package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
- package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
- package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
- package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
- package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8637.47f5b35afcae5e6b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
- package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
- /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as readline from 'node:readline/promises';
|
|
2
2
|
import { detectProviders, type DetectedProvider } from '../llm/provider-detect.js';
|
|
3
3
|
import { debug } from '../debug/log.js';
|
|
4
|
+
import { detectLocale, type Locale } from '../expression/locale.js';
|
|
4
5
|
import { unattendedNextStepLine } from './entry-hints.js';
|
|
5
6
|
import { resolveProviderCredential } from '../llm/provider-credentials.js';
|
|
6
7
|
import {
|
|
@@ -13,6 +14,8 @@ export interface FirstRunDeps {
|
|
|
13
14
|
path?: string;
|
|
14
15
|
detectProviders?: () => Promise<DetectedProvider[]>;
|
|
15
16
|
isTTY?: boolean;
|
|
17
|
+
/** Locale for user-facing wording; defaults to the shared ambient decision (detectLocale). */
|
|
18
|
+
locale?: Locale;
|
|
16
19
|
chooseProvider?: (detected: readonly LLMProviderName[]) => Promise<LLMProviderName | null>;
|
|
17
20
|
print?: (message: string) => void;
|
|
18
21
|
saveConfig?: (config: UserConfig, path: string) => void;
|
|
@@ -44,12 +47,21 @@ export function parseMenuAnswer(answer: string, choices: readonly LLMProviderNam
|
|
|
44
47
|
return provider !== undefined ? { kind: 'chosen', provider } : { kind: 'miss' };
|
|
45
48
|
}
|
|
46
49
|
|
|
50
|
+
/**
|
|
51
|
+
* The fixed choice line of the first-run menu (`1 Codex, 2 Grok, 3 Claude`).
|
|
52
|
+
* Single source of the wording: the prompt below renders it, and the ux-sim
|
|
53
|
+
* first-run device asserts against it, so a wording change cannot drift apart.
|
|
54
|
+
*/
|
|
55
|
+
export function formatProviderMenu(choices: readonly LLMProviderName[]): string {
|
|
56
|
+
return choices.map((name, i) => `${i + 1} ${CHOICE_LABEL[name] ?? name}`).join(', ');
|
|
57
|
+
}
|
|
58
|
+
|
|
47
59
|
export async function promptProviderMenu(
|
|
48
60
|
ask: (prompt: string) => Promise<string>,
|
|
49
61
|
detected: readonly LLMProviderName[] = [],
|
|
50
62
|
): Promise<LLMProviderName | null> {
|
|
51
63
|
const choices = orderProviderChoices(detected);
|
|
52
|
-
const menu = choices
|
|
64
|
+
const menu = formatProviderMenu(choices);
|
|
53
65
|
for (;;) {
|
|
54
66
|
const parsed = parseMenuAnswer(await ask(`Choose LLM (${menu}; Enter to cancel): `), choices);
|
|
55
67
|
if (parsed.kind === 'chosen') return parsed.provider;
|
|
@@ -66,7 +78,23 @@ async function chooseProvider(detected: readonly LLMProviderName[] = []): Promis
|
|
|
66
78
|
}
|
|
67
79
|
}
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
/** User-facing first-run fallback wording, routed by the shared locale decision (detectLocale). */
|
|
82
|
+
const FIRST_RUN_TEXT = {
|
|
83
|
+
ko: {
|
|
84
|
+
detectedPrefix: '감지: ',
|
|
85
|
+
subscription: ' 구독',
|
|
86
|
+
needsLlm: 'eln setup llm 으로 고르세요',
|
|
87
|
+
claudeNoPath: 'claude-code 구독은 구독으로 쓸 수 있는 경로가 없어 자동 선택하지 않음',
|
|
88
|
+
multipleDetected: '둘 이상 감지되어 고르세요',
|
|
89
|
+
},
|
|
90
|
+
en: {
|
|
91
|
+
detectedPrefix: 'detected: ',
|
|
92
|
+
subscription: ' subscription',
|
|
93
|
+
needsLlm: 'pick a provider via eln setup llm',
|
|
94
|
+
claudeNoPath: 'claude-code subscription has no usable path in elanous; not auto-selecting',
|
|
95
|
+
multipleDetected: 'more than one detected; pick one',
|
|
96
|
+
},
|
|
97
|
+
} as const;
|
|
70
98
|
|
|
71
99
|
export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
|
|
72
100
|
outcome: 'ready' | 'needs-llm' | 'cancelled'; provider?: string; inputs: number;
|
|
@@ -74,6 +102,9 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
|
|
|
74
102
|
const path = deps.path ?? userConfigPath();
|
|
75
103
|
const cfg = deps.config ?? getUserConfig(path);
|
|
76
104
|
const print = deps.print ?? console.log;
|
|
105
|
+
const text = FIRST_RUN_TEXT[(deps.locale ?? detectLocale()) === 'en' ? 'en' : 'ko'];
|
|
106
|
+
const detectionLabel = (provider: string) =>
|
|
107
|
+
`${provider === 'openai-codex' ? 'codex' : provider}${text.subscription}`;
|
|
77
108
|
let detected: DetectedProvider[] = [];
|
|
78
109
|
try { detected = await (deps.detectProviders ?? detectProviders)(); }
|
|
79
110
|
catch { /* Detection is advisory; a TTY can still choose. */ }
|
|
@@ -93,9 +124,9 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
|
|
|
93
124
|
// claude-code is detected but has no subscription path in elanous: mapping it to the 'anthropic'
|
|
94
125
|
// API-key provider would save a provider whose first call fails for a subscription-only user.
|
|
95
126
|
const usable = SUBSCRIPTION_PRIORITY.filter((name) => providers.includes(name));
|
|
96
|
-
const detectionLine = (outcome: string) =>
|
|
127
|
+
const detectionLine = (outcome: string) => `${text.detectedPrefix}${providers.map(detectionLabel).join(' · ')} → ${outcome}`;
|
|
97
128
|
const needsLlm = (inputs: number, extra: string[] = []) => {
|
|
98
|
-
print(
|
|
129
|
+
print(text.needsLlm);
|
|
99
130
|
for (const line of extra) print(line);
|
|
100
131
|
observe('needs-llm', inputs);
|
|
101
132
|
return { outcome: 'needs-llm' as const, inputs };
|
|
@@ -106,8 +137,8 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
|
|
|
106
137
|
if (!provider) {
|
|
107
138
|
if (providers.length > 0) {
|
|
108
139
|
print(detectionLine(usable.length === 0
|
|
109
|
-
?
|
|
110
|
-
:
|
|
140
|
+
? text.claudeNoPath
|
|
141
|
+
: text.multipleDetected));
|
|
111
142
|
}
|
|
112
143
|
if ((deps.isTTY ?? process.stdin.isTTY) !== true) {
|
|
113
144
|
// FIRST-CHAT-NONTTY — bare `elanous` with no TTY gets the same one-line next step as the other entrances.
|
|
@@ -7,6 +7,7 @@ import { runBgLaunch, type BgLaunchResult } from '../cli/bg-launch.js';
|
|
|
7
7
|
import { joinRestHealthUrl, runNexusShow, type NexusShowResult } from '../cli/nexus-show.js';
|
|
8
8
|
import { issueSetupLinkToken } from '../auth/setup-link-tokens.js';
|
|
9
9
|
import { debug } from '../debug/log.js';
|
|
10
|
+
import { detectLocale, type Locale } from '../expression/locale.js';
|
|
10
11
|
import { browserUnavailableReason } from '../oauth/browser-availability.js';
|
|
11
12
|
import type { UserConfig } from '../user-config.js';
|
|
12
13
|
|
|
@@ -18,6 +19,8 @@ export interface WebFirstSetupDeps {
|
|
|
18
19
|
/** Bare first run never starts or waits for a missing daemon; explicit setup retains web launch. */
|
|
19
20
|
startIfMissing?: boolean;
|
|
20
21
|
startedAt?: number;
|
|
22
|
+
/** Locale for user-facing wording; defaults to the shared ambient decision (detectLocale). */
|
|
23
|
+
locale?: Locale;
|
|
21
24
|
showNexus?: () => Promise<NexusShowResult>;
|
|
22
25
|
startDaemon?: () => Promise<BgLaunchResult>;
|
|
23
26
|
probeHealth?: (url: string, timeoutMs: number) => Promise<boolean>;
|
|
@@ -37,6 +40,34 @@ export interface WebFirstSetupDeps {
|
|
|
37
40
|
|
|
38
41
|
const STARTUP_TIMEOUT_MS = 12_000;
|
|
39
42
|
|
|
43
|
+
/** User-facing web-first fallback wording, routed by the shared locale decision (detectLocale). */
|
|
44
|
+
const WEB_FIRST_TEXT = {
|
|
45
|
+
ko: {
|
|
46
|
+
unavailable: (reason: string) => `웹 셋업을 사용할 수 없습니다 (${reason}). 터미널 설정으로 전환합니다.`,
|
|
47
|
+
offline: '오프라인 모드',
|
|
48
|
+
startingDaemon: '웹 셋업을 위해 데몬을 시작합니다.',
|
|
49
|
+
continueInBrowser: '브라우저에서 셋업을 이어가세요',
|
|
50
|
+
phoneOnSameWifi: (link: string) => `같은 와이파이의 폰이면: ${link}`,
|
|
51
|
+
linkSingleUse: '이 링크는 10분 안에 한 번만 열 수 있습니다',
|
|
52
|
+
sameWifiRestart: '같은 와이파이에서 열려면 `elanous nexus run` 을 루프백 없이 다시 띄우세요',
|
|
53
|
+
scanTailnet: '같은 와이파이·tailnet 의 폰 카메라로 스캔하세요',
|
|
54
|
+
scanSameWifi: '같은 와이파이의 폰 카메라로 스캔하세요',
|
|
55
|
+
terminalInstead: '터미널에서 하려면: `elanous setup --terminal`',
|
|
56
|
+
},
|
|
57
|
+
en: {
|
|
58
|
+
unavailable: (reason: string) => `web setup is unavailable (${reason}); switching to terminal setup.`,
|
|
59
|
+
offline: 'offline mode',
|
|
60
|
+
startingDaemon: 'starting the daemon for web setup.',
|
|
61
|
+
continueInBrowser: 'continue setup in your browser',
|
|
62
|
+
phoneOnSameWifi: (link: string) => `on a phone on the same wifi: ${link}`,
|
|
63
|
+
linkSingleUse: 'this link can be opened only once within 10 minutes',
|
|
64
|
+
sameWifiRestart: 'to open it from the same wifi, restart `elanous nexus run` without a loopback-only bind',
|
|
65
|
+
scanTailnet: 'scan with a phone camera on the same wifi/tailnet',
|
|
66
|
+
scanSameWifi: 'scan with a phone camera on the same wifi',
|
|
67
|
+
terminalInstead: 'to use the terminal instead: `elanous setup --terminal`',
|
|
68
|
+
},
|
|
69
|
+
} as const;
|
|
70
|
+
|
|
40
71
|
async function probeHealth(url: string, timeoutMs: number): Promise<boolean> {
|
|
41
72
|
try {
|
|
42
73
|
const response = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
|
|
@@ -53,12 +84,13 @@ function setupUrl(pwa: string, token: string): string {
|
|
|
53
84
|
export async function runWebFirstSetup(deps: WebFirstSetupDeps): Promise<'link-shown' | 'fallback'> {
|
|
54
85
|
const startedAt = deps.startedAt ?? Date.now();
|
|
55
86
|
const print = deps.print ?? console.log;
|
|
87
|
+
const text = WEB_FIRST_TEXT[(deps.locale ?? detectLocale()) === 'en' ? 'en' : 'ko'];
|
|
56
88
|
const observe = (event: 'link-shown' | 'fallback', reason?: string, qr = false, browserOpened = false, remote: 'loopback' | 'tailnet' = 'loopback', ms?: number, lan?: 'shown' | 'loopback-bind' | 'no-address', ssh?: boolean) => {
|
|
57
89
|
try { debug.log('onboarding.web-first', event, { ...(reason ? { reason } : {}), qr, browserOpened, remote, ...(ms !== undefined ? { ms } : {}), ...(lan ? { lan, ssh } : {}) }); }
|
|
58
90
|
catch { /* Observability must not block onboarding. */ }
|
|
59
91
|
};
|
|
60
92
|
const fallback = (reason: string): 'fallback' => {
|
|
61
|
-
print(
|
|
93
|
+
print(text.unavailable(reason));
|
|
62
94
|
observe('fallback', reason);
|
|
63
95
|
return 'fallback';
|
|
64
96
|
};
|
|
@@ -70,7 +102,7 @@ export async function runWebFirstSetup(deps: WebFirstSetupDeps): Promise<'link-s
|
|
|
70
102
|
try { shown = await show(); } catch { /* A missing daemon may make inspection fail. */ }
|
|
71
103
|
const running = shown?.status === 'unregistered' || (shown?.status === 'registered' && shown.instance?.alive === true);
|
|
72
104
|
if (deps.startIfMissing === false && !running) {
|
|
73
|
-
print(
|
|
105
|
+
print(text.offline);
|
|
74
106
|
observe('fallback', 'offline');
|
|
75
107
|
return 'fallback';
|
|
76
108
|
}
|
|
@@ -85,11 +117,11 @@ export async function runWebFirstSetup(deps: WebFirstSetupDeps): Promise<'link-s
|
|
|
85
117
|
const deadline = Date.now() + STARTUP_TIMEOUT_MS;
|
|
86
118
|
if (!running || !shown?.urls?.pwa.loopback) {
|
|
87
119
|
if (deps.startIfMissing === false) {
|
|
88
|
-
print(
|
|
120
|
+
print(text.offline);
|
|
89
121
|
observe('fallback', 'offline');
|
|
90
122
|
return 'fallback';
|
|
91
123
|
}
|
|
92
|
-
print(
|
|
124
|
+
print(text.startingDaemon);
|
|
93
125
|
let launch: BgLaunchResult;
|
|
94
126
|
try {
|
|
95
127
|
launch = await (deps.startDaemon ?? (() => runBgLaunch({ out: { log: () => {}, error: () => {} } })))();
|
|
@@ -115,7 +147,7 @@ export async function runWebFirstSetup(deps: WebFirstSetupDeps): Promise<'link-s
|
|
|
115
147
|
if (remaining > 0) await Bun.sleep(Math.min(200, remaining));
|
|
116
148
|
}
|
|
117
149
|
if (!healthy && deps.startIfMissing === false) {
|
|
118
|
-
print(
|
|
150
|
+
print(text.offline);
|
|
119
151
|
observe('fallback', 'offline');
|
|
120
152
|
return 'fallback';
|
|
121
153
|
}
|
|
@@ -154,13 +186,13 @@ export async function runWebFirstSetup(deps: WebFirstSetupDeps): Promise<'link-s
|
|
|
154
186
|
const lan: 'shown' | 'loopback-bind' | 'no-address' = !confirmedBind ? 'no-address' : !reachable ? 'loopback-bind' : lanAddress ? 'shown' : 'no-address';
|
|
155
187
|
const lanLink = lanAddress ? setupUrl(`http://${lanAddress}:${port}/app/`, token) : undefined;
|
|
156
188
|
const phoneLink = shown.urls.pwa.tailnet ? setupUrl(shown.urls.pwa.tailnet, token) : lanLink;
|
|
157
|
-
print(
|
|
189
|
+
print(text.continueInBrowser);
|
|
158
190
|
print(link);
|
|
159
191
|
if (lanLink) {
|
|
160
|
-
print(
|
|
161
|
-
print(
|
|
192
|
+
print(text.phoneOnSameWifi(lanLink));
|
|
193
|
+
print(text.linkSingleUse);
|
|
162
194
|
} else if (lan === 'loopback-bind') {
|
|
163
|
-
print(
|
|
195
|
+
print(text.sameWifiRestart);
|
|
164
196
|
}
|
|
165
197
|
const linkShownMs = Date.now() - startedAt;
|
|
166
198
|
let qr = false;
|
|
@@ -172,12 +204,12 @@ export async function runWebFirstSetup(deps: WebFirstSetupDeps): Promise<'link-s
|
|
|
172
204
|
}))(phoneLink);
|
|
173
205
|
if (rendered) {
|
|
174
206
|
print(rendered);
|
|
175
|
-
print(shown.urls.pwa.tailnet ?
|
|
207
|
+
print(shown.urls.pwa.tailnet ? text.scanTailnet : text.scanSameWifi);
|
|
176
208
|
qr = true;
|
|
177
209
|
}
|
|
178
210
|
} catch { /* QR is optional. */ }
|
|
179
211
|
}
|
|
180
|
-
print(
|
|
212
|
+
print(text.terminalInstead);
|
|
181
213
|
let browserOpened = false;
|
|
182
214
|
const env = deps.browserEnv ?? process.env;
|
|
183
215
|
const ssh = !!(env.SSH_CONNECTION || env.SSH_CLIENT || env.SSH_TTY);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { LoopRow, OverviewSnapshot } from './overview.js';
|
|
2
|
+
|
|
3
|
+
/** 루프 지도의 한 칸 — 캐시 스냅숏의 루프 행을 그대로 옮긴다(합성 없음). */
|
|
4
|
+
export interface LoopsMapRow {
|
|
5
|
+
name: string;
|
|
6
|
+
era: LoopRow['era'];
|
|
7
|
+
/** 이 주기 이상 박동이 없으면 정지로 본다. null = 주기 미상(판정에서 뺀다) — 캐시 값 그대로. */
|
|
8
|
+
staleAfterSeconds: number | null;
|
|
9
|
+
/** 박동 칸: 못 잼이면 value·observedAt 이 null 이고 reason 이 남는다(캐시 그대로). */
|
|
10
|
+
beat: LoopRow['beat'];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* LOOP-MAP-API 응답 — overviewCache 의 loops 스냅숏만 투영한 것.
|
|
15
|
+
* edges(loop-edges 결합)는 후속 조각이라 여기에 넣지 않는다.
|
|
16
|
+
*/
|
|
17
|
+
export interface LoopsMap {
|
|
18
|
+
/** 캐시 스냅숏이 만든 시각. 캐시가 비면 null. */
|
|
19
|
+
generatedAt: string | null;
|
|
20
|
+
/** 요청 시각(캐시 시계)과 generatedAt 의 차이. 캐시가 비면 null. */
|
|
21
|
+
cacheAgeMs: number | null;
|
|
22
|
+
loops: LoopsMapRow[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 캐시 미스 응답 — 원격 조회를 유발하지 않고 «아직 캐시 없음»을 그대로 말한다. */
|
|
26
|
+
const EMPTY_LOOPS_MAP: LoopsMap = { generatedAt: null, cacheAgeMs: null, loops: [] };
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* overviewCache.peek() 결과 하나를 루프 지도 응답으로 투영한다.
|
|
30
|
+
* `at` 은 캐시의 시계로 잰 «읽은 시각»이라 가짜 시계를 주입하면 cacheAgeMs 가 결정적이다.
|
|
31
|
+
* 여기서 원천을 더 읽지 않는다 — 순수 투영이다.
|
|
32
|
+
*/
|
|
33
|
+
export function loopsMapFromCache(peeked: { snapshot: OverviewSnapshot; at: number } | null): LoopsMap {
|
|
34
|
+
if (!peeked) return EMPTY_LOOPS_MAP;
|
|
35
|
+
const generatedAtMs = Date.parse(peeked.snapshot.generatedAt);
|
|
36
|
+
return {
|
|
37
|
+
generatedAt: peeked.snapshot.generatedAt,
|
|
38
|
+
cacheAgeMs: Number.isFinite(generatedAtMs) ? Math.max(0, peeked.at - generatedAtMs) : null,
|
|
39
|
+
loops: peeked.snapshot.loops.map((loop) => ({
|
|
40
|
+
name: loop.name,
|
|
41
|
+
era: loop.era,
|
|
42
|
+
staleAfterSeconds: loop.staleAfterSeconds,
|
|
43
|
+
beat: loop.beat,
|
|
44
|
+
})),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { debug } from '../debug/log.js';
|
|
2
2
|
import { parentPort, Worker } from 'node:worker_threads';
|
|
3
3
|
import { collectOverview, type CollectOptions } from './overview-collect.js';
|
|
4
|
-
import { computeVerdict, unmeasured, okCell, type OverviewSnapshot, type PodMemberRow } from './overview.js';
|
|
4
|
+
import { computeVerdict, unmeasured, okCell, type Cell, type GateReservation, type OverviewSnapshot, type PodMemberRow } from './overview.js';
|
|
5
5
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
6
6
|
import { getElanousConfigDirOverride, setElanousConfigDir } from '../elanous-config-dir.js';
|
|
7
7
|
|
|
@@ -12,7 +12,7 @@ const POD_STALE_MS = 2 * POD_MS;
|
|
|
12
12
|
const MAX_MEMO = 32;
|
|
13
13
|
const MAX_PENDING = 2;
|
|
14
14
|
|
|
15
|
-
type PodReading = { context: string; occupied: number | null; reason: string | null; observedAt: number };
|
|
15
|
+
type PodReading = { context: string; occupied: number | null; reason: string | null; observedAt: number; gate?: GateReservation };
|
|
16
16
|
type OverviewData = OverviewSnapshot & ReturnType<typeof computeVerdict> & { cacheAgeMs: number; durationMs: number; sources: string[]; refreshFailed: string | null };
|
|
17
17
|
type WorkerMessage = ({ kind: 'pods' } | { kind: 'snapshot'; options: CollectOptions }) & { configDir?: string };
|
|
18
18
|
|
|
@@ -25,7 +25,7 @@ if (port) {
|
|
|
25
25
|
if (message.configDir) setElanousConfigDir(message.configDir);
|
|
26
26
|
if (message.kind === 'pods') {
|
|
27
27
|
const { buildGridData } = await import('../nexus/api/grid.js');
|
|
28
|
-
const rows = buildGridData().members.map((m) => ({ context: m.context, occupied: m.occupied, reason: m.reason, observedAt: Date.now() }));
|
|
28
|
+
const rows = buildGridData().members.map((m) => ({ context: m.context, occupied: m.occupied, reason: m.reason, observedAt: Date.now(), ...(m.gate ? { gate: m.gate } : {}) }));
|
|
29
29
|
port.postMessage({ rows });
|
|
30
30
|
} else port.postMessage({ snapshot: await collectOverview(message.options) });
|
|
31
31
|
} catch (error) {
|
|
@@ -106,6 +106,24 @@ export function createOverviewCache(deps: {
|
|
|
106
106
|
podTimer = schedule(() => { void refreshPods(); }, POD_MS);
|
|
107
107
|
podTimer.unref();
|
|
108
108
|
};
|
|
109
|
+
/**
|
|
110
|
+
* 게이트 예약 축(RES-FLOOR-BINDING 다섯째 축) — 「게이트 안 돎」은 측정된 값('none'), 못 잼은 사유를 남긴다.
|
|
111
|
+
* 둘 다 구속 조건 후보에서 빠지지만 뜻은 다르다: 하나는 «게이트가 안 돈다», 다른 하나는 «모른다».
|
|
112
|
+
*/
|
|
113
|
+
const overlayGate = (row: PodReading | undefined, at: number): Cell<GateReservation | 'none'> => {
|
|
114
|
+
const observedAt = row ? new Date(row.observedAt).toISOString() : null;
|
|
115
|
+
const stale = row !== undefined && at - row.observedAt >= POD_STALE_MS;
|
|
116
|
+
if (podFailure || !row || stale) {
|
|
117
|
+
return unmeasured('pod pool background measure', podFailure ?? (stale ? '낡음(120초)' : '측정 대기'), observedAt);
|
|
118
|
+
}
|
|
119
|
+
if (!row.gate) return unmeasured('pod pool background measure', row.reason ?? '게이트 예약 못 잼', observedAt);
|
|
120
|
+
if (row.gate.jobs === 0) return okCell<GateReservation | 'none'>('none', 'pod pool background measure', observedAt);
|
|
121
|
+
const gate = row.gate;
|
|
122
|
+
if (!Number.isFinite(gate.unbound) || !Number.isFinite(gate.reservedMillicores) || !Number.isFinite(gate.schedulableMillicores)) {
|
|
123
|
+
return unmeasured('pod pool background measure', '게이트 CPU 못 잼', observedAt);
|
|
124
|
+
}
|
|
125
|
+
return okCell<GateReservation | 'none'>(gate, 'pod pool background measure', observedAt);
|
|
126
|
+
};
|
|
109
127
|
/** Response-time Pod occupancy overlay — shared by /v1/ops/overview and /v1/ops/resources. */
|
|
110
128
|
const overlayPods = (snapshot: OverviewSnapshot, at: number): PodMemberRow[] => {
|
|
111
129
|
const byContext = new Map(podRows.map((row) => [row.context, row]));
|
|
@@ -115,7 +133,7 @@ export function createOverviewCache(deps: {
|
|
|
115
133
|
const occupied = !podFailure && row && !stale && row.occupied !== null
|
|
116
134
|
? okCell(row.occupied, 'pod pool background measure', new Date(row.observedAt).toISOString())
|
|
117
135
|
: unmeasured<number>('pod pool background measure', podFailure ?? (stale ? '낡음(120초)' : row?.reason ?? '측정 대기'), row ? new Date(row.observedAt).toISOString() : null);
|
|
118
|
-
return { ...pod, occupied };
|
|
136
|
+
return { ...pod, occupied, gate: overlayGate(row, at) };
|
|
119
137
|
});
|
|
120
138
|
};
|
|
121
139
|
const present = (entry: Entry): OverviewData => {
|
|
@@ -234,6 +234,16 @@ export interface CollectDeps {
|
|
|
234
234
|
gitLog?: (sinceIso: string) => { lines: string[]; observedAt: string } ;
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
/** Production schedule.run ledger reader; dbPath is explicit so replays never open the operating ledger. */
|
|
238
|
+
export async function readSchedulerExecutionRows(dbPath: string, sinceMs: number, untilMs: number): Promise<SchedulerExecutionObservation[]> {
|
|
239
|
+
const { LogStore } = await import('../mss/logging/log-store.js');
|
|
240
|
+
const store = LogStore.openReadOnly(dbPath);
|
|
241
|
+
try {
|
|
242
|
+
return store.queryAll({ exactCategories: ['schedule.run'], sinceMs, untilMs })
|
|
243
|
+
.map(({ ts_ms, data }) => ({ ts_ms, data }));
|
|
244
|
+
} finally { store.close(); }
|
|
245
|
+
}
|
|
246
|
+
|
|
237
247
|
async function defaultDeps(root: string): Promise<Required<CollectDeps>> {
|
|
238
248
|
const [{ listSchedules }, { listChecklist }, { readReleaseRuns }, { readTaskAgentState, taskAgentStatePath }, { ResourceLedger }, { getUserConfig }] = await Promise.all([
|
|
239
249
|
import('../release-loop/release-schedule.js'), import('../release-loop/checklist.js'), import('../nexus/api/ops-api.js'),
|
|
@@ -242,12 +252,8 @@ async function defaultDeps(root: string): Promise<Required<CollectDeps>> {
|
|
|
242
252
|
return {
|
|
243
253
|
listSchedules: () => listSchedules(),
|
|
244
254
|
readSchedulerRuns: async (sinceMs, untilMs) => {
|
|
245
|
-
const {
|
|
246
|
-
|
|
247
|
-
try {
|
|
248
|
-
return store.queryAll({ exactCategories: ['schedule.run'], sinceMs, untilMs })
|
|
249
|
-
.map(({ ts_ms, data }) => ({ ts_ms, data }));
|
|
250
|
-
} finally { store.close(); }
|
|
255
|
+
const { logsDbPath } = await import('../mss/logging/log-store.js');
|
|
256
|
+
return readSchedulerExecutionRows(logsDbPath(), sinceMs, untilMs);
|
|
251
257
|
},
|
|
252
258
|
listChecklist: (v) => listChecklist(v),
|
|
253
259
|
readRuns: (dir) => readReleaseRuns(null, dir),
|
package/src/ops/overview.ts
CHANGED
|
@@ -60,7 +60,28 @@ export interface MachineLoad {
|
|
|
60
60
|
ioPressure?: IoPressure | null;
|
|
61
61
|
}
|
|
62
62
|
export interface MachineRow { name: string; load: Cell<MachineLoad> }
|
|
63
|
-
|
|
63
|
+
/**
|
|
64
|
+
* GATE-RESERVE-AUTO 가 잰 «게이트 예약 몫» — 발행 게이트 샤드가 쥔 CPU. 자원 지도의 다섯째 축이다.
|
|
65
|
+
* `harnessCpuSlotsBesideGate` 와 같은 fail-closed 규칙: 샤드가 아직 노드에 안 붙었으면 하니스 Pod 는 들어가지 않는다.
|
|
66
|
+
*/
|
|
67
|
+
export interface GateReservation {
|
|
68
|
+
/** 종결 전 게이트 샤드 Job 수 — 0 이면 게이트가 안 돈다(축 아님). */
|
|
69
|
+
jobs: number;
|
|
70
|
+
/** 그중 아직 노드에 안 붙은 샤드. */
|
|
71
|
+
unbound: number;
|
|
72
|
+
/** 샤드가 예약한 CPU(밀리코어). */
|
|
73
|
+
reservedMillicores: number;
|
|
74
|
+
/** 스케줄 가능한 노드들의 CPU 합(밀리코어). */
|
|
75
|
+
schedulableMillicores: number;
|
|
76
|
+
}
|
|
77
|
+
export interface PodMemberRow {
|
|
78
|
+
context: string; capacity: number; occupied: Cell<number>;
|
|
79
|
+
/**
|
|
80
|
+
* 게이트 예약 축 — `'none'` 은 «게이트가 안 돈다»(측정됨), `unmeasured` 는 못 잼(축에서 뺀다), 항목 없음은
|
|
81
|
+
* 이 칸에 게이트 원천이 없는 스냅숏(로컬 CLI 는 호출 경로 kubectl 0 규율로 늘 여기다).
|
|
82
|
+
*/
|
|
83
|
+
gate?: Cell<GateReservation | 'none'>;
|
|
84
|
+
}
|
|
64
85
|
export interface ParentsInfo { count: number; staleOver6h: number; oldestHours: number | null }
|
|
65
86
|
export interface SchedulerMetrics {
|
|
66
87
|
scheduleRuns: number | null;
|
|
@@ -110,7 +131,7 @@ export interface VerdictResult { verdict: Verdict; reasons: string[]; nextAction
|
|
|
110
131
|
/** 부하/코어가 이 값을 넘으면 «기계 압박»(흐름 저하의 사유). */
|
|
111
132
|
export const LOAD_PER_CORE_PRESSURE = 3;
|
|
112
133
|
|
|
113
|
-
/** 자원 지도의 축 어휘(닫힌 집합 · RES-FLOOR-BINDING).
|
|
134
|
+
/** 자원 지도의 축 어휘(닫힌 집합 · RES-FLOOR-BINDING). */
|
|
114
135
|
export type ResourceKind = 'memory' | 'cpu' | 'io' | 'slots' | 'gate';
|
|
115
136
|
|
|
116
137
|
/** 구속 조건 — 남은 비율이 최소인 축. 남은 비율 = 남은 양/전체 양(CPU 는 압박선 LOAD_PER_CORE_PRESSURE×코어를 전체로 본다). */
|
|
@@ -132,26 +153,28 @@ function remainingAmount(n: number): string {
|
|
|
132
153
|
|
|
133
154
|
/**
|
|
134
155
|
* 구속 조건 규칙(RES-FLOOR-BINDING) — 메모리·CPU·I/O·슬롯·게이트 예약 중 «남은 비율 최소»인 축이 흐름을 묶는다.
|
|
135
|
-
* 못 잰 축(하트비트 없는 호스트 · 용량 못 잼 · 하트비트에 PSI 가 없는 I/O ·
|
|
156
|
+
* 못 잰 축(하트비트 없는 호스트 · 용량 못 잼 · 하트비트에 PSI 가 없는 I/O · 게이트 CPU 못 잼)은 후보에서 뺀다
|
|
136
157
|
* — «넉넉»으로도 «바닥»으로도 읽지 않는다.
|
|
137
|
-
*
|
|
158
|
+
* 게이트 예약의 남은 비율 = (스케줄 가능 CPU − 샤드가 쥔 CPU) / 스케줄 가능 CPU. 샤드가 아직 노드에 안 붙었으면 0
|
|
159
|
+
* (하니스 Pod 는 들어가지 않는다 · `harnessCpuSlotsBesideGate` 와 같은 규칙).
|
|
160
|
+
* 측정 축이 하나도 없으면 null. 동율은 정해진 순서(호스트 순 메모리→CPU→I/O, 그 다음 슬롯, 그 다음 게이트 예약)의 첫 축이 이긴다.
|
|
138
161
|
*/
|
|
139
162
|
export function bindingResource(s: OverviewSnapshot): ResourceBinding | null {
|
|
140
163
|
const candidates: ResourceBinding[] = [];
|
|
141
164
|
for (const host of s.machines.hosts) {
|
|
142
165
|
const l = host.load.value;
|
|
143
166
|
if (!l) continue;
|
|
144
|
-
if (l.totalGb > 0) {
|
|
167
|
+
if (Number.isFinite(l.freeGb) && Number.isFinite(l.totalGb) && l.totalGb > 0) {
|
|
145
168
|
const remaining = Math.max(0, l.freeGb);
|
|
146
169
|
candidates.push({ kind: 'memory', label: `${host.name} 메모리`, remainingRatio: ratio01(remaining / l.totalGb), remainingText: `${remainingAmount(remaining)}/${l.totalGb.toFixed(0)}GB` });
|
|
147
170
|
}
|
|
148
|
-
if (l.cpuCount > 0) {
|
|
171
|
+
if (Number.isFinite(l.load5) && Number.isFinite(l.cpuCount) && l.cpuCount > 0) {
|
|
149
172
|
const cpuCap = l.cpuCount * LOAD_PER_CORE_PRESSURE;
|
|
150
173
|
const remaining = Math.max(0, cpuCap - l.load5);
|
|
151
174
|
candidates.push({ kind: 'cpu', label: `${host.name} CPU`, remainingRatio: ratio01(remaining / cpuCap), remainingText: `${remainingAmount(remaining)}/${cpuCap.toFixed(0)}코어(압박선 ${LOAD_PER_CORE_PRESSURE}/코어)` });
|
|
152
175
|
}
|
|
153
176
|
const io = l.ioPressure;
|
|
154
|
-
if (io) {
|
|
177
|
+
if (io && Number.isFinite(io.someAvg10) && Number.isFinite(io.fullAvg10)) {
|
|
155
178
|
const remaining = Math.max(0, 100 - io.someAvg10);
|
|
156
179
|
candidates.push({ kind: 'io', label: `${host.name} I/O`, remainingRatio: ratio01(remaining / 100), remainingText: `${remainingAmount(remaining)}/100(압박 ${remainingAmount(io.someAvg10)}% · full ${remainingAmount(io.fullAvg10)}% · 10초 평균)` });
|
|
157
180
|
}
|
|
@@ -161,6 +184,16 @@ export function bindingResource(s: OverviewSnapshot): ResourceBinding | null {
|
|
|
161
184
|
const total = capacity.podTarget + capacity.localMax;
|
|
162
185
|
candidates.push({ kind: 'slots', label: '슬롯', remainingRatio: ratio01(capacity.free / total), remainingText: `${capacity.free}/${total}자리` });
|
|
163
186
|
}
|
|
187
|
+
for (const pod of s.machines.pods) {
|
|
188
|
+
const gate = pod.gate?.value;
|
|
189
|
+
if (!gate || gate === 'none') continue;
|
|
190
|
+
const total = gate.schedulableMillicores;
|
|
191
|
+
if (!Number.isFinite(total) || total <= 0 || !Number.isFinite(gate.reservedMillicores)) continue;
|
|
192
|
+
const remaining = gate.unbound > 0 ? 0 : Math.max(0, total - gate.reservedMillicores);
|
|
193
|
+
const unbound = gate.unbound > 0 ? ` · 미배치 ${gate.unbound}` : '';
|
|
194
|
+
candidates.push({ kind: 'gate', label: `${pod.context} 게이트 예약`, remainingRatio: ratio01(remaining / total),
|
|
195
|
+
remainingText: `${remainingAmount(remaining)}/${total.toFixed(0)}밀리코어(게이트 샤드 ${gate.jobs} · 예약 ${remainingAmount(gate.reservedMillicores)}${unbound})` });
|
|
196
|
+
}
|
|
164
197
|
let binding: ResourceBinding | null = null;
|
|
165
198
|
for (const c of candidates) if (binding === null || c.remainingRatio < binding.remainingRatio) binding = c;
|
|
166
199
|
return binding;
|
|
@@ -255,7 +288,10 @@ export function unmeasuredCells(s: OverviewSnapshot): string[] {
|
|
|
255
288
|
visit('tasks.byOwner', s.tasks.byOwner); visit('tasks.done', s.tasks.done);
|
|
256
289
|
visit('tasks.launchable', s.tasks.launchable); visit('tasks.capacity', s.tasks.capacity);
|
|
257
290
|
for (const h of s.machines.hosts) visit(`machines.${h.name}`, h.load);
|
|
258
|
-
for (const p of s.machines.pods)
|
|
291
|
+
for (const p of s.machines.pods) {
|
|
292
|
+
visit(`pods.${p.context}`, p.occupied);
|
|
293
|
+
if (p.gate) visit(`pods.${p.context}.gate`, p.gate);
|
|
294
|
+
}
|
|
259
295
|
visit('machines.parents', s.machines.parents); visit('landings', s.landings);
|
|
260
296
|
if (s.throughput) visit('throughput', s.throughput);
|
|
261
297
|
if (s.schedulerMetrics) visit('schedulerMetrics', s.schedulerMetrics);
|
package/src/persona/loader.ts
CHANGED
|
@@ -154,6 +154,16 @@ export function validatePersonaShape(
|
|
|
154
154
|
todo = obj['todo'];
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
// 🗣️ 말투(speech style) — TUI-SPEECH-STYLE-CHARACTER. ⛔ 위 `actionHosts` 주석이
|
|
158
|
+
// 못 박은 그 이유로 ***여기에 명시로 옮긴다*** — 타입에만 더하면 YAML 의 그 줄은 영영 안 읽힌다.
|
|
159
|
+
let speechStyle: string | undefined;
|
|
160
|
+
if (Object.hasOwn(obj, 'speechStyle')) {
|
|
161
|
+
if (typeof obj['speechStyle'] !== 'string' || !obj['speechStyle'].trim()) {
|
|
162
|
+
return err(path, 'speechStyle must be a non-empty string');
|
|
163
|
+
}
|
|
164
|
+
speechStyle = obj['speechStyle'];
|
|
165
|
+
}
|
|
166
|
+
|
|
157
167
|
let mentionPatterns: readonly string[] | undefined;
|
|
158
168
|
if (obj['mentionPatterns'] !== undefined) {
|
|
159
169
|
if (!Array.isArray(obj['mentionPatterns'])
|
|
@@ -169,6 +179,7 @@ export function validatePersonaShape(
|
|
|
169
179
|
...(todo !== undefined ? { todo } : {}),
|
|
170
180
|
...(description.value !== undefined ? { description: description.value } : {}),
|
|
171
181
|
...(systemPrompt.value !== undefined ? { systemPrompt: systemPrompt.value } : {}),
|
|
182
|
+
...(speechStyle !== undefined ? { speechStyle } : {}),
|
|
172
183
|
...(brand !== undefined ? { brand } : {}),
|
|
173
184
|
...(models !== undefined ? { models } : {}),
|
|
174
185
|
...(mentionPatterns !== undefined ? { mentionPatterns } : {}),
|
package/src/persona/types.ts
CHANGED
|
@@ -30,6 +30,14 @@ export interface PersonaProfile {
|
|
|
30
30
|
* v1 = no resolution, raw passthrough). */
|
|
31
31
|
readonly systemPrompt?: string;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* 🗣️ **말투(speech style)** — 이 페르소나가 «어떻게» 말하는가(TUI-SPEECH-STYLE-CHARACTER).
|
|
35
|
+
*
|
|
36
|
+
* ⛔ 안 적으면 «없다» — 기본 말투를 조용히 채우지 않는다(`actionHosts`·`capabilities`
|
|
37
|
+
* 와 같은 규율: 관측이 「선언이 없다」고 말한다).
|
|
38
|
+
*/
|
|
39
|
+
readonly speechStyle?: string;
|
|
40
|
+
|
|
33
41
|
/**
|
|
34
42
|
* 🚧 **이 봇이 «손을 쓸 수 있는» 호스트들** — 되돌릴 수 없는 브라우저 조작의 «경계».
|
|
35
43
|
*
|
package/src/policy/llm-policy.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { isScalar, parseDocument } from 'yaml';
|
|
|
4
4
|
import { getElanousConfigDir } from '../elanous-config-dir.js';
|
|
5
5
|
import { DEFAULT_FALLBACK_CHAIN, isFallbackStep, type FallbackStep } from '../oauth/fallback-chain.js';
|
|
6
6
|
import { isCodexQuotaPolicy } from '../oauth/codex-quota-policy.js';
|
|
7
|
-
import { DEFAULT_BUDGET_GATE_MAX_USED_PERCENT, MODEL_ROLES, RUNTIME_LLM_PROVIDER_NAMES, parseRoleLlmEntry, parseSubscriptionReviewerSpec, type RoleLlmConfig, type SubscriptionReviewerSpec } from '../user-config.js';
|
|
7
|
+
import { DEFAULT_BUDGET_GATE_MAX_USED_PERCENT, MODEL_ROLES, RUNTIME_LLM_PROVIDER_NAMES, parseReviewerMixSpec, parseRoleLlmEntry, parseSubscriptionReviewerSpec, type RoleLlmConfig, type SubscriptionReviewerSpec } from '../user-config.js';
|
|
8
8
|
|
|
9
9
|
export interface LlmPolicy {
|
|
10
10
|
version: 1;
|
|
@@ -106,6 +106,7 @@ export function validateLlmPolicy(input: unknown): LlmPolicyValidation {
|
|
|
106
106
|
&& nonempty(g.account) && positive(g.amount) && date(g.expires) && nonempty(g.source));
|
|
107
107
|
const roles = (v: unknown) => object(v) && Object.entries(v).every(([role, spec]) => role === 'reviewer'
|
|
108
108
|
? !!parseSubscriptionReviewerSpec(spec)
|
|
109
|
+
: role === 'reviewerMix' ? !!parseReviewerMixSpec(spec)
|
|
109
110
|
: MODEL_ROLES.some(r => r === role) && object(spec)
|
|
110
111
|
&& Object.keys(spec).every(k => ['provider', 'tier', 'model'].includes(k)) && parseRoleLlmEntry(spec).ok);
|
|
111
112
|
check(input, 'policy', {
|
|
@@ -209,6 +210,7 @@ export function loadLlmPolicy(opts: LoadLlmPolicyOptions = {}): LoadedLlmPolicy
|
|
|
209
210
|
if (Object.keys(base).length) overlay.default = base;
|
|
210
211
|
add('roleLlm', legacy.roleLlm, overlay, 'roles', v => object(v) && Object.entries(v).every(([r, spec]) => r === 'reviewer'
|
|
211
212
|
? !!parseSubscriptionReviewerSpec(spec)
|
|
213
|
+
: r === 'reviewerMix' ? !!parseReviewerMixSpec(spec)
|
|
212
214
|
: MODEL_ROLES.some(k => k === r) && parseRoleLlmEntry(spec).ok));
|
|
213
215
|
add('llm.fallbackChain', llm.fallbackChain, overlay, 'fallback', v => Array.isArray(v) && v.length > 0 && v.every(isFallbackStep) && new Set(v).size === v.length);
|
|
214
216
|
const codex: Obj = {};
|
|
@@ -134,7 +134,7 @@ function askMarkerCount(ask: string): number {
|
|
|
134
134
|
return (ask.match(/(?:^|\s)(?:불변식|경계|판정\s*신호|invariant|boundary|decision\s+signal)\s*:/gi) ?? []).length;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
type EnhanceSelectionSource = 'opts' | 'env' | 'config-role' | 'fallback-child' | 'default';
|
|
137
|
+
type EnhanceSelectionSource = 'opts' | 'env' | 'config-role' | 'child' | 'fallback-child' | 'default';
|
|
138
138
|
const PLANNING_FALLBACK_REASONS = new Set(['quota-exhausted', 'quota-unmeasured', 'quota-unavailable', 'no-credential-source', 'expiring', 'credential-shape', 'credential-error', 'credential-unavailable', 'unavailable']);
|
|
139
139
|
export function normalizePlanningFallbackReason(value: unknown): string {
|
|
140
140
|
return typeof value === 'string' && PLANNING_FALLBACK_REASONS.has(value) ? value : 'unavailable';
|
|
@@ -153,7 +153,7 @@ export function selectEnhanceLlm(
|
|
|
153
153
|
const forwardedModelSource = env.ELANOUS_PROMPT_ENHANCE_MODEL_RELAY === 'pod' ? env.ELANOUS_PROMPT_ENHANCE_MODEL_SOURCE : undefined;
|
|
154
154
|
const modelSource: EnhanceSelectionSource = opts.model !== undefined ? 'opts'
|
|
155
155
|
: env.ELANOUS_PROMPT_ENHANCE_MODEL
|
|
156
|
-
? forwardedModelSource === 'config-role' || forwardedModelSource === 'fallback-child' || forwardedModelSource === 'default' ? forwardedModelSource : 'env'
|
|
156
|
+
? forwardedModelSource === 'config-role' || forwardedModelSource === 'child' || forwardedModelSource === 'fallback-child' || forwardedModelSource === 'default' ? forwardedModelSource : 'env'
|
|
157
157
|
: configuredModel !== undefined ? 'config-role' : 'default';
|
|
158
158
|
const model = opts.model ?? (env.ELANOUS_PROMPT_ENHANCE_MODEL || configuredModel || env.ELANOUS_PR_REVIEW_MODEL || tierModel('better'));
|
|
159
159
|
const envEffort = env.ELANOUS_PROMPT_ENHANCE_EFFORT;
|
|
@@ -176,7 +176,7 @@ export function selectEnhanceLlm(
|
|
|
176
176
|
export function selectPlanningLlm(
|
|
177
177
|
env: NodeJS.ProcessEnv = process.env,
|
|
178
178
|
config: UserConfig = getUserConfig(),
|
|
179
|
-
): { model: string | undefined; effort: 'low' | 'medium' | 'high'; modelSource: 'env' | 'config-role' | 'fallback-child' | 'default'; fallbackReason?: string; requestedModel?: string; requestedSource?: string } {
|
|
179
|
+
): { model: string | undefined; effort: 'low' | 'medium' | 'high'; modelSource: 'env' | 'config-role' | 'child' | 'fallback-child' | 'default'; fallbackReason?: string; requestedModel?: string; requestedSource?: string } {
|
|
180
180
|
const planning = config.roleLlm?.planning;
|
|
181
181
|
const envModel = env.ELANOUS_PROMPT_ENHANCE_MODEL;
|
|
182
182
|
const roleModel = !envModel && planning && (planning.model || planning.tier || planning.provider)
|
|
@@ -186,7 +186,7 @@ export function selectPlanningLlm(
|
|
|
186
186
|
const relayed = env.ELANOUS_PROMPT_ENHANCE_MODEL_RELAY === 'pod';
|
|
187
187
|
const forwardedSource = relayed ? env.ELANOUS_PROMPT_ENHANCE_MODEL_SOURCE : undefined;
|
|
188
188
|
const modelSource = envModel
|
|
189
|
-
? forwardedSource === 'config-role' || forwardedSource === 'fallback-child' || forwardedSource === 'default' ? forwardedSource : 'env'
|
|
189
|
+
? forwardedSource === 'config-role' || forwardedSource === 'child' || forwardedSource === 'fallback-child' || forwardedSource === 'default' ? forwardedSource : 'env'
|
|
190
190
|
: roleModel ? 'config-role' : 'default';
|
|
191
191
|
const envEffort = env.ELANOUS_PROMPT_ENHANCE_EFFORT;
|
|
192
192
|
const validEnvEffort = envEffort === 'low' || envEffort === 'medium' || envEffort === 'high' ? envEffort : undefined;
|
|
@@ -33,6 +33,11 @@ function hasTool(enabled: ReadonlySet<string>, ...names: string[]): boolean {
|
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/** One working tab per site: each one-shot `aside repl "<js>"` call starts a new REPL
|
|
37
|
+
* session, so `page` from the previous call is gone — reattach, don't reopen. */
|
|
38
|
+
export const ASIDE_BROWSER_GUIDANCE =
|
|
39
|
+
'When you drive a browser with `aside repl "<js>"`: each call is a new REPL session, so reuse ONE working tab instead of opening a new one per step (extra tabs of the same app trigger «open in another tab» locks and lost connections). Start every script by reattaching: `const t1=(await listBrowserTabs()).find(t=>t.url.startsWith(\'<origin+path>\')); if (t1) await attachBrowserTab(t1.targetId); else await openTab(\'<url>\');` then use `page`. Call `openTab()` only when no matching tab exists or the user asks for a new page. Always pass the script as the argument — a bare `aside repl` waits for input until the shell timeout. A REPL call may run up to 120s, so give long browser steps a shell timeout above that (e.g. 150000 ms) and split very long flows into several calls.';
|
|
40
|
+
|
|
36
41
|
/** Build the session guidance addendum. Returns 0 or 1 system message
|
|
37
42
|
* containing per-tool one-liner directives, gated on what's active.
|
|
38
43
|
* When `enabledTools` is undefined or every relevant tool is absent,
|
|
@@ -114,6 +119,15 @@ export function buildSessionGuidanceAddendum(
|
|
|
114
119
|
);
|
|
115
120
|
}
|
|
116
121
|
|
|
122
|
+
// Browser via Aside (ASIDE-TAB-REUSE · 10-22). Observed in the n8n lecture
|
|
123
|
+
// session: every step ran `aside repl "var p=await openTab('<same url>')…"`.
|
|
124
|
+
// A one-shot `aside repl` is a fresh REPL session, so each call opened another
|
|
125
|
+
// tab → n8n «Editing in another tab» lock → lost connection → the step repeated.
|
|
126
|
+
// A bare `aside repl` (no script) also hung until the shell timeout.
|
|
127
|
+
if (hasTool(active, 'Bash', 'bash', 'RunShell', 'run_shell', 'aside.repl', 'aside_repl')) {
|
|
128
|
+
items.push(ASIDE_BROWSER_GUIDANCE);
|
|
129
|
+
}
|
|
130
|
+
|
|
117
131
|
if (items.length === 0) return [];
|
|
118
132
|
// B4 — 파일 수 규칙. 명령을 실제로 돌릴 도구(Bash·PtyShellStart·WebTerminal*)가 있을 때만 `git ls-files` 로 세라고 하고,
|
|
119
133
|
// Read 만 켜진 세션에선 셀 수 없으니 추측하지 말고 확인 불가라고 답하게 한다(EVAL q09 «959» vs 실측 778 · 리뷰 3라운드 must-fix).
|
package/src/provider-summary.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { loadTokens, isExpiringSoon } from './oauth/store.js';
|
|
|
17
17
|
import { CODEX_REFRESH_BUFFER_MS } from './oauth/codex.js';
|
|
18
18
|
import { findCodexModel } from './codex/models.js';
|
|
19
19
|
import { getLocalLLMUrl } from './config.js';
|
|
20
|
+
import { zaiCodingPlanAvailable } from './llm/zai-coding-plan.js';
|
|
20
21
|
|
|
21
22
|
export type AuthKind = 'oauth' | 'apikey' | 'local' | 'none';
|
|
22
23
|
|
|
@@ -105,6 +106,13 @@ function authDetailForDecision(
|
|
|
105
106
|
? llm.apiKey ? 'API key (config)' : 'API key (~/.cache/openrouter_api_key · env OPENROUTER_API_KEY)'
|
|
106
107
|
: 'not configured — bash scripts/add-api-key.sh OPENROUTER_API_KEY';
|
|
107
108
|
}
|
|
109
|
+
// GLM-NO-CREDENTIAL-FALLBACK (OP #28375 · 🩸 run-6c85c69f) — 종전엔 glm 칸이 없어 자격이 «있어도» 아래 일반 문면
|
|
110
|
+
// 「no provider configured」가 찍혔고(자식 PTY 첫 줄), 부검이 그 줄을 «자격 결손» 원인으로 읽었다. 판정은 glm 직결이 서는 조건 그 함수다.
|
|
111
|
+
if (provider === 'glm') {
|
|
112
|
+
return zaiCodingPlanAvailable()
|
|
113
|
+
? 'GLM Coding Plan 키 (~/.cache/zai_api_key · env ZAI_API_KEY)'
|
|
114
|
+
: 'not configured — ZAI_API_KEY 없음 (~/.cache/zai_api_key · env ZAI_API_KEY)';
|
|
115
|
+
}
|
|
108
116
|
if (provider === 'local') {
|
|
109
117
|
const url = llm.baseUrl || getLocalLLMUrl();
|
|
110
118
|
return auth === 'local' && url ? `OpenAI-compat endpoint — ${url}` : 'not configured — set llm.baseUrl';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { bunNativePtyAvailable } from './bun-native-pty.js';
|
|
2
|
+
|
|
3
|
+
/** Keep the capability probe independent of PTY runtime initialization. */
|
|
4
|
+
export function ptyAvailable(): boolean {
|
|
5
|
+
if (bunNativePtyAvailable()) return true;
|
|
6
|
+
try { require.resolve('node-pty'); return true; } catch { return false; }
|
|
7
|
+
}
|