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
|
@@ -3,18 +3,22 @@
|
|
|
3
3
|
// `herdr agent list` 에 안 잡힌다 — pane CLI 로 생애·세션을 직접 알린다.
|
|
4
4
|
//
|
|
5
5
|
// 활성은 HERDR_ENV=1 ⊕ HERDR_PANE_ID ⊕ 킬스위치가 아닐 때뿐.
|
|
6
|
-
// 실패(rc≠0·
|
|
6
|
+
// 실패(rc≠0·spawn·ENOENT·오류 봉투)는 던지지 않고 한 번 로그한 뒤 그 신고기를 끈다.
|
|
7
|
+
// 단 turn 신고의 timeout 은 끄지 않는다(TUI-HERDR-STATUS-STALE · 10-22 n8n): herdr 가 바쁜 한 번의 2s 초과로
|
|
8
|
+
// 신고기가 꺼져 턴 끝 idle 이 영영 안 나가 herdr 가 1.9h 동안 working 을 보였다. timeout 은 «결과 모름»이라
|
|
9
|
+
// 마지막 턴 상태를 잠시 뒤 다시 신고하고(새 seq · 더 새 턴이 오면 그만) 이후 턴 신고도 그대로 보낸다.
|
|
7
10
|
//
|
|
8
11
|
// herdr 는 같은 pane·source 에서 «직전보다 큰 seq» 만 받는다(작으면 rc0 인데 무시).
|
|
9
|
-
// 같은 pane 에서 TUI 를 다시 띄워도 신고가 살도록 seq 는 max(직전+1 · 시각 ·
|
|
10
|
-
// pane 기록 =
|
|
11
|
-
// ⛔ 턴 경로는 파일을 안 만진다:
|
|
12
|
+
// 같은 pane 에서 TUI 를 다시 띄워도 신고가 살도록 seq 는 max(직전+1 · 시각 · 예약 high-watermark+1) 이다.
|
|
13
|
+
// pane 기록 = 예약한 seq 범위의 high-watermark(기본 tmpdir 파일) — 정상·비정상 재기동에서 뒤 범위를 쓴다.
|
|
14
|
+
// ⛔ 턴 경로는 보통 파일을 안 만진다: 범위가 소진되면 next()가 새 범위를 파일에 예약한다.
|
|
12
15
|
// 기록을 못 읽고 못 쓰면(관측 `seq-store-failed` 한 번) 시각·직전+1 로만 간다.
|
|
13
|
-
// 한계: release 없이 죽은 프로세스의 마지막 seq 는 기록되지 않는다 — 그때 뒤 프로세스는 시각에 기댄다.
|
|
14
16
|
//
|
|
15
17
|
// 실패로 꺼지는 것은 «이후 turn» 뿐이다. release(권한 반납)는 start 실패가 «확인»됐을 때만 건너뛴다.
|
|
16
18
|
// start 의 비동기 신고가 아직 안 끝났으면(결과 모름) 반납을 미루지 않고 바로 동기로 시도한다(관측 `release-start-pending`) —
|
|
17
19
|
// 종료 경로에서 미루면 exit 뒤 반납이 영영 안 나간다. 반납 실패(rc≠0 등)는 `release-failed` 로 늘 남긴다.
|
|
20
|
+
// 그때 반납 직전에 더 큰 seq 로 동기 재등록한다(TUI-HERDR-EXIT-RACE) — 미등록 반납은 seq 를 안 남겨
|
|
21
|
+
// 늦게 닿은 비동기 등록이 유령이 되던 경합을 «동기 재등록 → 동기 반납» 순서로 닫는다.
|
|
18
22
|
|
|
19
23
|
import { spawn, spawnSync } from 'node:child_process';
|
|
20
24
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
@@ -22,6 +26,9 @@ import { tmpdir } from 'node:os';
|
|
|
22
26
|
import { join } from 'node:path';
|
|
23
27
|
|
|
24
28
|
import { debug } from '../debug/log.js';
|
|
29
|
+
import { pruneStaleHerdrAgent } from './herdr-prune-stale.js';
|
|
30
|
+
import { HerdrSequenceLease, type HerdrSeqStore } from './herdr-sequence-lease.js';
|
|
31
|
+
export type { HerdrSeqStore } from './herdr-sequence-lease.js';
|
|
25
32
|
|
|
26
33
|
/** 턴 값 — tui-run-state 의 PtyTurnState 와 같은 낱말이지만 순환 import 를 피하려 여기 둔다. */
|
|
27
34
|
export type HerdrTurn = 'busy' | 'idle';
|
|
@@ -29,6 +36,8 @@ export type HerdrTurn = 'busy' | 'idle';
|
|
|
29
36
|
export interface HerdrRunResult {
|
|
30
37
|
readonly ok: boolean;
|
|
31
38
|
readonly stderr?: string;
|
|
39
|
+
/** 시간 안에 답을 못 받았다 — herdr 가 이미 적용했을 수도 있는 «결과 모름»(TUI-HERDR-STATUS-STALE). */
|
|
40
|
+
readonly timedOut?: boolean;
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
export interface HerdrRunOpts {
|
|
@@ -48,15 +57,18 @@ export interface HerdrAgentReporterDeps {
|
|
|
48
57
|
readonly sessionId?: string;
|
|
49
58
|
/** seq 시작값의 시계(ms). 기본 Date.now. */
|
|
50
59
|
readonly now?: () => number;
|
|
51
|
-
/** pane 별
|
|
60
|
+
/** pane 별 예약 범위 끝 기록. 기본 = tmpdir 파일(`createFileSeqStore`). */
|
|
52
61
|
readonly seqStore?: HerdrSeqStore;
|
|
62
|
+
/** 재신고 타이머 — 기본 setTimeout(unref). 시험이 가짜 시계를 준다. */
|
|
63
|
+
readonly schedule?: (fn: () => void, ms: number) => void;
|
|
64
|
+
/** Injected runners skip production startup cleanup unless explicitly enabled. */
|
|
65
|
+
readonly pruneStaleOnStart?: boolean;
|
|
53
66
|
}
|
|
54
67
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
68
|
+
const defaultSchedule = (fn: () => void, ms: number): void => {
|
|
69
|
+
const t = setTimeout(fn, ms);
|
|
70
|
+
(t as unknown as { unref?: () => void }).unref?.();
|
|
71
|
+
};
|
|
60
72
|
|
|
61
73
|
export function defaultHerdrSeqDir(): string {
|
|
62
74
|
return join(tmpdir(), 'elanous-herdr-seq');
|
|
@@ -89,6 +101,10 @@ export interface HerdrAgentReporterLike {
|
|
|
89
101
|
}
|
|
90
102
|
|
|
91
103
|
const ASYNC_TIMEOUT_MS = 2000;
|
|
104
|
+
/** turn 신고가 timeout 이면 이만큼 뒤에 마지막 상태를 다시 신고한다. */
|
|
105
|
+
export const HERDR_TURN_RETRY_DELAY_MS = 3000;
|
|
106
|
+
/** 같은 턴 상태의 재신고 상한 — 넘으면 `report-gave-up` 을 남기고 다음 턴 신고를 기다린다(신고기는 켜 둔다). */
|
|
107
|
+
export const HERDR_TURN_RETRY_MAX = 3;
|
|
92
108
|
const SYNC_TIMEOUT_MS = 300;
|
|
93
109
|
const STDERR_HEAD = 240;
|
|
94
110
|
const STDOUT_CAP = 4096;
|
|
@@ -149,7 +165,10 @@ export function defaultHerdrRunner(env: NodeJS.ProcessEnv): HerdrRunner {
|
|
|
149
165
|
if (opts.sync) {
|
|
150
166
|
try {
|
|
151
167
|
const r = spawnSync(bin, argv, { timeout: cap, encoding: 'utf8', windowsHide: true });
|
|
152
|
-
if (r.error)
|
|
168
|
+
if (r.error) {
|
|
169
|
+
const timedOut = (r.error as NodeJS.ErrnoException).code === 'ETIMEDOUT';
|
|
170
|
+
return { ok: false, stderr: r.error.message, ...(timedOut ? { timedOut: true } : {}) };
|
|
171
|
+
}
|
|
153
172
|
const out = typeof r.stdout === 'string' ? r.stdout : '';
|
|
154
173
|
const overflow = Buffer.byteLength(out, 'utf8') > STDOUT_CAP;
|
|
155
174
|
return judgeHerdr(r.status, overflow ? '' : out, typeof r.stderr === 'string' ? r.stderr : '', overflow);
|
|
@@ -178,7 +197,7 @@ export function defaultHerdrRunner(env: NodeJS.ProcessEnv): HerdrRunner {
|
|
|
178
197
|
};
|
|
179
198
|
const timer = setTimeout(() => {
|
|
180
199
|
try { child.kill(); } catch { /* already gone */ }
|
|
181
|
-
finish({ ok: false, stderr: stderr || 'timeout' });
|
|
200
|
+
finish({ ok: false, stderr: stderr || 'timeout', timedOut: true });
|
|
182
201
|
}, cap);
|
|
183
202
|
child.stderr?.on('data', (chunk: Buffer | string) => {
|
|
184
203
|
if (stderr.length < STDERR_HEAD) stderr += String(chunk);
|
|
@@ -201,6 +220,43 @@ export function defaultHerdrRunner(env: NodeJS.ProcessEnv): HerdrRunner {
|
|
|
201
220
|
};
|
|
202
221
|
}
|
|
203
222
|
|
|
223
|
+
/** 신호 지킴이가 쓰는 process 의 좁은 면 — 시험이 가짜를 준다. */
|
|
224
|
+
export interface HerdrSignalTarget {
|
|
225
|
+
readonly pid: number;
|
|
226
|
+
on(sig: NodeJS.Signals, fn: (sig: NodeJS.Signals) => void): unknown;
|
|
227
|
+
removeListener(sig: NodeJS.Signals, fn: (sig: NodeJS.Signals) => void): unknown;
|
|
228
|
+
listenerCount(sig: NodeJS.Signals): number;
|
|
229
|
+
kill(pid: number, sig?: string | number): unknown;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const RELEASE_SIGNALS: readonly NodeJS.Signals[] = ['SIGINT', 'SIGTERM'];
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* SIGINT·SIGTERM 기본 죽음에도 반납한다(TUI-HERDR-EXIT-RACE).
|
|
236
|
+
* 대시보드가 raw 모드에 들기 «전»의 ctrl+c 는 SIGINT 기본 동작으로 프로세스를 죽여(rc130) 'exit' 훅이 안 돈다 —
|
|
237
|
+
* 10-22 격리 세션 실측: 반납 0 · `agent list` 에 elanous idle 이 남았다.
|
|
238
|
+
* 신호가 오면 반납(동기) → 자기 리스너를 걷고, 이제 아무도 안 들으면 같은 신호를 다시 올려 기본 죽음을 지킨다.
|
|
239
|
+
* 다른 리스너가 있으면 그쪽이 같은 신호를 이미 받았다 — 다시 올리지 않는다.
|
|
240
|
+
* @returns 해제(정상 종료 경로에서 부른다).
|
|
241
|
+
*/
|
|
242
|
+
export function guardHerdrReleaseOnSignal(release: () => void, proc: HerdrSignalTarget = process): () => void {
|
|
243
|
+
let off = false;
|
|
244
|
+
const remove = (): void => {
|
|
245
|
+
if (off) return;
|
|
246
|
+
off = true;
|
|
247
|
+
for (const sig of RELEASE_SIGNALS) { try { proc.removeListener(sig, onSignal); } catch { /* 종료 경로를 깨지 않는다 */ } }
|
|
248
|
+
};
|
|
249
|
+
function onSignal(sig: NodeJS.Signals): void {
|
|
250
|
+
try { release(); } catch { /* 신호 경로를 깨지 않는다 */ }
|
|
251
|
+
remove();
|
|
252
|
+
let alone = true;
|
|
253
|
+
try { alone = proc.listenerCount(sig) === 0; } catch { alone = true; }
|
|
254
|
+
if (alone) { try { proc.kill(proc.pid, sig); } catch { /* 이미 끝나는 중 */ } }
|
|
255
|
+
}
|
|
256
|
+
for (const sig of RELEASE_SIGNALS) proc.on(sig, onSignal);
|
|
257
|
+
return remove;
|
|
258
|
+
}
|
|
259
|
+
|
|
204
260
|
/**
|
|
205
261
|
* herdr pane 안에서만 신고기. 비활성이면 null (skipped 로그 한 번).
|
|
206
262
|
* 반환 메서드는 실패해도 던지지 않는다.
|
|
@@ -219,13 +275,17 @@ export function createHerdrAgentReporter(deps: HerdrAgentReporterDeps = {}): Her
|
|
|
219
275
|
}
|
|
220
276
|
const run = deps.run ?? defaultHerdrRunner(env);
|
|
221
277
|
const sessionId = deps.sessionId ?? '';
|
|
222
|
-
return new Reporter(
|
|
278
|
+
return new Reporter(
|
|
279
|
+
paneId, sessionId, run, log, deps.now ?? Date.now,
|
|
280
|
+
deps.seqStore ?? createFileSeqStore(paneId), deps.schedule ?? defaultSchedule,
|
|
281
|
+
deps.pruneStaleOnStart ?? deps.run === undefined,
|
|
282
|
+
);
|
|
223
283
|
}
|
|
224
284
|
|
|
225
285
|
type IssueResult = boolean | Promise<boolean>;
|
|
226
286
|
|
|
227
287
|
class Reporter implements HerdrAgentReporterLike {
|
|
228
|
-
private
|
|
288
|
+
private readonly sequence: HerdrSequenceLease;
|
|
229
289
|
private disabled = false;
|
|
230
290
|
/**
|
|
231
291
|
* idle 신고(에이전트 등록)의 상태: none → (pending →) ok | failed.
|
|
@@ -233,8 +293,6 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
233
293
|
*/
|
|
234
294
|
private startState: 'none' | 'pending' | 'ok' | 'failed' = 'none';
|
|
235
295
|
private released = false;
|
|
236
|
-
/** start 때 한 번 읽은 pane 기록(턴 경로는 파일을 안 만진다). */
|
|
237
|
-
private storedSeq: number | undefined;
|
|
238
296
|
/** idle 신고(비동기 포함)가 실패했다 — 등록된 적이 없으니 반납할 것이 없다. */
|
|
239
297
|
private idleFailed = false;
|
|
240
298
|
private seqStoreFailed = false;
|
|
@@ -255,12 +313,31 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
255
313
|
private readonly run: HerdrRunner,
|
|
256
314
|
private readonly log: (event: string, data: Record<string, unknown>) => void,
|
|
257
315
|
private readonly now: () => number,
|
|
258
|
-
|
|
259
|
-
|
|
316
|
+
seqStore: HerdrSeqStore,
|
|
317
|
+
private readonly schedule: (fn: () => void, ms: number) => void,
|
|
318
|
+
private readonly pruneStaleOnStart: boolean,
|
|
319
|
+
) {
|
|
320
|
+
this.sequence = new HerdrSequenceLease(seqStore, now, (error) => this.seqStoreFail(error));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** 마지막으로 요청된 턴 상태와 그 세대 — 재신고는 세대가 그대로일 때만(더 새 턴이 오면 그만). */
|
|
324
|
+
private lastTurn: HerdrTurn | null = null;
|
|
325
|
+
private turnGen = 0;
|
|
326
|
+
private turnRetries = 0;
|
|
260
327
|
|
|
261
328
|
start(): void {
|
|
262
329
|
if (this.startState !== 'none') return;
|
|
263
|
-
|
|
330
|
+
if (this.pruneStaleOnStart) {
|
|
331
|
+
const pruneSeq = this.nextSeq();
|
|
332
|
+
try {
|
|
333
|
+
const pruned = pruneStaleHerdrAgent(this.paneId, pruneSeq, this.run);
|
|
334
|
+
this.log(pruned.ok ? 'startup-prune-complete' : 'startup-prune-failed', {
|
|
335
|
+
seq: pruneSeq, ...(pruned.stderr ? { stderrHead: stderrHead(pruned.stderr) } : {}),
|
|
336
|
+
});
|
|
337
|
+
} catch (error) {
|
|
338
|
+
this.log('startup-prune-failed', { seq: pruneSeq, stderrHead: stderrHead(error instanceof Error ? error.message : String(error)) });
|
|
339
|
+
}
|
|
340
|
+
}
|
|
264
341
|
const idleOk = this.issue([
|
|
265
342
|
'pane', 'report-agent',
|
|
266
343
|
'--source', HERDR_SOURCE, '--agent', HERDR_AGENT,
|
|
@@ -301,8 +378,6 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
301
378
|
this.releasedWhilePending = false;
|
|
302
379
|
this.log('release-resend-after-late-start', {});
|
|
303
380
|
const seq = this.nextSeq();
|
|
304
|
-
// 재반납 seq 도 pane 기록에 남긴다 — 같은 ms 재기동의 첫 seq 가 이 값보다 커야 한다(r7 리뷰 mf).
|
|
305
|
-
try { this.seqStore.write(this.seq); } catch (error) { this.seqStoreFail(error); }
|
|
306
381
|
void this.runAndJudge([
|
|
307
382
|
'pane', 'release-agent',
|
|
308
383
|
this.paneId,
|
|
@@ -314,6 +389,13 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
314
389
|
turn(t: HerdrTurn): void {
|
|
315
390
|
// 반납 뒤 신고는 반납한 에이전트를 더 큰 seq 로 다시 등록한다 — 막는다.
|
|
316
391
|
if (this.disabled || this.released) return;
|
|
392
|
+
this.lastTurn = t;
|
|
393
|
+
this.turnGen += 1;
|
|
394
|
+
this.turnRetries = 0;
|
|
395
|
+
this.issueTurn(t);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
private issueTurn(t: HerdrTurn): void {
|
|
317
399
|
const state = t === 'busy' ? 'working' : 'idle';
|
|
318
400
|
this.issue([
|
|
319
401
|
'pane', 'report-agent',
|
|
@@ -328,14 +410,25 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
328
410
|
if (this.released) return;
|
|
329
411
|
// idle 등록 실패가 확인됐거나 start 전이면 건너뛴다. pending = 결과 모름 → 반납을 시도한다.
|
|
330
412
|
if (this.startState === 'none' || this.startState === 'failed' || this.idleFailed) return;
|
|
413
|
+
this.released = true;
|
|
331
414
|
if (this.startState === 'pending') {
|
|
332
415
|
this.log('release-start-pending', {});
|
|
333
416
|
this.releasedWhilePending = true;
|
|
417
|
+
// 즉시 종료 경합(TUI-HERDR-EXIT-RACE): 비동기 idle 등록은 herdr 자식 프로세스라 부모가 죽어도 간다.
|
|
418
|
+
// herdr 0.9.1 실측 — 미등록 에이전트 반납은 rc0 인데 seq 를 안 남긴다 ⇒ 반납 «뒤에» 닿은 작은 seq 등록이
|
|
419
|
+
// 유령으로 남는다(10-22 격리 세션 tf-exit-race). 기다릴 수 없으니(동기 ≤300ms) 순서를 동기로 고정한다:
|
|
420
|
+
// 더 큰 seq 로 동기 재등록 → 동기 반납. 반납이 «등록된» 에이전트를 지우며 seq 를 남기므로
|
|
421
|
+
// 늦게 닿는 앞 등록(작은 seq)은 herdr 가 버린다. 재등록 실패여도 반납은 그대로 시도한다(결과 모름).
|
|
422
|
+
this.issue([
|
|
423
|
+
'pane', 'report-agent',
|
|
424
|
+
'--source', HERDR_SOURCE, '--agent', HERDR_AGENT,
|
|
425
|
+
'--state', 'idle',
|
|
426
|
+
'--agent-session-id', this.sessionId,
|
|
427
|
+
'--seq', this.nextSeq(),
|
|
428
|
+
this.paneId,
|
|
429
|
+
], true, 'release');
|
|
334
430
|
}
|
|
335
|
-
this.released = true;
|
|
336
431
|
const seq = this.nextSeq();
|
|
337
|
-
// pane 기록 쓰기는 여기(동기 종료 경로)뿐이다.
|
|
338
|
-
try { this.seqStore.write(this.seq); } catch (error) { this.seqStoreFail(error); }
|
|
339
432
|
// ⛔ herdr 0.9.1 `release-agent` 는 PANE_ID 를 옵션 «앞»에 둬야 받는다 — 뒤에 두면
|
|
340
433
|
// «unknown option: custom:elanous» rc2 로 반납이 영영 안 됐다(10-18 라이브 실측 · report-agent 는 뒤도 받음).
|
|
341
434
|
this.issue([
|
|
@@ -346,26 +439,43 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
346
439
|
], true, 'release');
|
|
347
440
|
}
|
|
348
441
|
|
|
442
|
+
/**
|
|
443
|
+
* turn 신고 timeout — 신고기를 끄지 않고 마지막 턴 상태를 잠시 뒤 다시 신고한다(TUI-HERDR-STATUS-STALE).
|
|
444
|
+
* herdr 가 그 신고를 이미 적용했어도(답만 늦었다) 다시 보내는 것은 무해하다 — 더 큰 seq 의 같은 상태다.
|
|
445
|
+
*/
|
|
446
|
+
private retryTurnAfterTimeout(argv: string[], stderr: string | undefined): void {
|
|
447
|
+
const gen = this.turnGen;
|
|
448
|
+
const state = this.lastTurn;
|
|
449
|
+
const attempt = this.turnRetries + 1;
|
|
450
|
+
if (state === null) return;
|
|
451
|
+
if (attempt > HERDR_TURN_RETRY_MAX) {
|
|
452
|
+
this.log('report-gave-up', { cmd: argv[1] ?? '', state: state === 'busy' ? 'working' : 'idle', attempts: HERDR_TURN_RETRY_MAX, stderrHead: stderrHead(stderr) });
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
this.turnRetries = attempt;
|
|
456
|
+
this.log('report-timeout-retry', { cmd: argv[1] ?? '', state: state === 'busy' ? 'working' : 'idle', attempt, delayMs: HERDR_TURN_RETRY_DELAY_MS, stderrHead: stderrHead(stderr) });
|
|
457
|
+
this.schedule(() => {
|
|
458
|
+
if (this.disabled || this.released || this.turnGen !== gen) return;
|
|
459
|
+
this.issueTurn(state);
|
|
460
|
+
}, HERDR_TURN_RETRY_DELAY_MS);
|
|
461
|
+
}
|
|
462
|
+
|
|
349
463
|
private seqStoreFail(error: unknown): void {
|
|
350
464
|
if (this.seqStoreFailed) return;
|
|
351
465
|
this.seqStoreFailed = true;
|
|
352
466
|
this.log('seq-store-failed', { error: error instanceof Error ? error.message : String(error) });
|
|
353
467
|
}
|
|
354
468
|
|
|
355
|
-
/**
|
|
469
|
+
/** Reserved sequence lease advances monotonically across same-millisecond restarts. */
|
|
356
470
|
private nextSeq(): string {
|
|
357
|
-
|
|
358
|
-
let next = Number.isFinite(clock) ? Math.max(this.seq + 1, clock) : this.seq + 1;
|
|
359
|
-
if (this.storedSeq !== undefined) next = Math.max(next, this.storedSeq + 1);
|
|
360
|
-
this.seq = next;
|
|
361
|
-
return String(this.seq);
|
|
471
|
+
return String(this.sequence.next());
|
|
362
472
|
}
|
|
363
473
|
|
|
364
474
|
/**
|
|
365
475
|
* release 는 꺼진 뒤에도 보낸다(권한 반납 · start 성공 조건은 release() 가 본다).
|
|
366
476
|
* @returns false = 동기 실패(신고기 꺼짐) · true = 동기 성공 · Promise = 비동기 결과(성공이면 true).
|
|
367
477
|
*/
|
|
368
|
-
private issue(argv: string[], sync: boolean, phase: 'start' | 'session' | 'turn' | 'release'): IssueResult {
|
|
478
|
+
private issue(argv: string[], sync: boolean, phase: 'start' | 'session' | 'turn' | 'release' | 'stale-cleanup'): IssueResult {
|
|
369
479
|
if (this.disabled && phase !== 'release') return false;
|
|
370
480
|
const opts: HerdrRunOpts = { sync, timeoutMs: sync ? SYNC_TIMEOUT_MS : ASYNC_TIMEOUT_MS };
|
|
371
481
|
if (!sync && this.pending) {
|
|
@@ -388,7 +498,7 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
388
498
|
const judged = (result as Promise<HerdrRunResult>).then(
|
|
389
499
|
(r) => {
|
|
390
500
|
if (r.ok) return true;
|
|
391
|
-
this.fail(argv, phase, r.stderr);
|
|
501
|
+
this.fail(argv, phase, r.stderr, r.timedOut === true);
|
|
392
502
|
return false;
|
|
393
503
|
},
|
|
394
504
|
(error: unknown) => {
|
|
@@ -401,7 +511,7 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
401
511
|
}
|
|
402
512
|
const syncResult = result as HerdrRunResult;
|
|
403
513
|
if (!syncResult.ok) {
|
|
404
|
-
this.fail(argv, phase, syncResult.stderr);
|
|
514
|
+
this.fail(argv, phase, syncResult.stderr, syncResult.timedOut === true);
|
|
405
515
|
return false;
|
|
406
516
|
}
|
|
407
517
|
return true;
|
|
@@ -415,11 +525,11 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
415
525
|
}
|
|
416
526
|
|
|
417
527
|
/** 줄 선 비동기 한 건 — 러너 결과(동기·비동기 모두)를 성패로 접는다. */
|
|
418
|
-
private async runAndJudge(argv: string[], opts: HerdrRunOpts, phase: 'start' | 'session' | 'turn' | 'release'): Promise<boolean> {
|
|
528
|
+
private async runAndJudge(argv: string[], opts: HerdrRunOpts, phase: 'start' | 'session' | 'turn' | 'release' | 'stale-cleanup'): Promise<boolean> {
|
|
419
529
|
try {
|
|
420
530
|
const r = await this.run(argv, opts);
|
|
421
531
|
if (r.ok) return true;
|
|
422
|
-
this.fail(argv, phase, r.stderr);
|
|
532
|
+
this.fail(argv, phase, r.stderr, r.timedOut === true);
|
|
423
533
|
return false;
|
|
424
534
|
} catch (error) {
|
|
425
535
|
this.fail(argv, phase, error instanceof Error ? error.message : String(error));
|
|
@@ -427,13 +537,21 @@ class Reporter implements HerdrAgentReporterLike {
|
|
|
427
537
|
}
|
|
428
538
|
}
|
|
429
539
|
|
|
430
|
-
private fail(argv: string[], phase: 'start' | 'session' | 'turn' | 'release', stderr: string | undefined): void {
|
|
540
|
+
private fail(argv: string[], phase: 'start' | 'session' | 'turn' | 'release' | 'stale-cleanup', stderr: string | undefined, timedOut = false): void {
|
|
541
|
+
if (phase === 'turn' && timedOut && !this.disabled) {
|
|
542
|
+
this.retryTurnAfterTimeout(argv, stderr);
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
431
545
|
if (phase === 'start') this.idleFailed = true;
|
|
432
546
|
// 반납 실패는 신고기가 이미 꺼졌어도 늘 남긴다(종료 경로의 유일한 흔적).
|
|
433
547
|
if (phase === 'release') {
|
|
434
548
|
this.log('release-failed', { stderrHead: stderrHead(stderr) });
|
|
435
549
|
return;
|
|
436
550
|
}
|
|
551
|
+
if (phase === 'stale-cleanup') {
|
|
552
|
+
this.log('stale-agent-cleanup-failed', { stderrHead: stderrHead(stderr) });
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
437
555
|
if (this.disabled) return;
|
|
438
556
|
this.disabled = true;
|
|
439
557
|
const cmd = argv[1] ?? '';
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
// `eln herdr prompt <대상> "<문장>" [--wait] [--timeout MS]` — herdr pane 의 elanous TUI 를 밖에서 깨운다.
|
|
2
|
+
//
|
|
3
|
+
// 왜 herdr `agent prompt` 가 아닌가(10-22 실측 · herdr 소스 v0.9.1·v0.9.5·main 5bd900d 동일):
|
|
4
|
+
// `src/app/api/agents.rs` 의 prompt·send-keys 는 `terminal.effective_known_agent()`(내장 kind 라벨)와
|
|
5
|
+
// `runtime_hosts_agent`(전경 프로세스가 그 kind)를 요구한다. «Add Herdr support to your agent» 계약대로
|
|
6
|
+
// 자기 이름(`elanous`)으로 신고한 agent 는 list·get·wait·read·알림은 되지만 prompt 는
|
|
7
|
+
// `agent_not_ready: … is not an active named agent` 로 늘 거부된다.
|
|
8
|
+
// 그래서 같은 의미를 여기서 낸다:
|
|
9
|
+
// ① `herdr agent get` — 신고 라벨이 elanous 이고 idle/done 인지(blocked/working/unknown 은 입력 0 으로 거부)
|
|
10
|
+
// ② `herdr pane run <pane> <문장>` — agent prompt 와 «같은 바이트»: herdr 의 `pane run` 은 pane 의 bracketed-paste
|
|
11
|
+
// 모드를 따라 `ESC[200~문장ESC[201~` ⊕ Enter 를 한 번에 쓴다(격리 세션 실측 · `pane send-text` 는 날 바이트라 쓰지 않는다)
|
|
12
|
+
// ③ --wait — 제출 뒤 활동 창(5000ms) 안에 working/blocked 를 관측해야 하고(아니면 agent_prompt_stalled),
|
|
13
|
+
// 그 뒤 idle/done/blocked 정착까지 기다린다. 호출자 timeout 이 먼저 끝나면 timeout. herdr agent prompt --wait 의미 그대로.
|
|
14
|
+
// 관측: debug.log('pty.herdr', 'prompt', { target, paneId, accepted, reason, status, ms }) 한 줄.
|
|
15
|
+
// 호출자 둘: CLI `eln herdr prompt`(라벨 elanous 만) ⊕ 우편 깨움 `src/loops/msg-wake.ts`(anyAgent · beforeSubmit 으로 재해석·opt-in·마감 관문).
|
|
16
|
+
// 신고 계약(herdr-agent-report.ts)은 건드리지 않는다 — 이 명령은 그 신고(working/idle)를 «읽기만» 한다.
|
|
17
|
+
|
|
18
|
+
import { spawn } from 'node:child_process';
|
|
19
|
+
|
|
20
|
+
import { debug } from '../debug/log.js';
|
|
21
|
+
|
|
22
|
+
export const HERDR_PROMPT_ACTIVITY_WINDOW_MS = 5000;
|
|
23
|
+
const HERDR_PROMPT_AGENT = 'elanous';
|
|
24
|
+
const CALL_TIMEOUT_MS = 5000;
|
|
25
|
+
const KILL_GRACE_MS = 1500;
|
|
26
|
+
const OUTPUT_CAP = 64 * 1024;
|
|
27
|
+
|
|
28
|
+
export interface HerdrCliResult {
|
|
29
|
+
readonly code: number | null;
|
|
30
|
+
readonly stdout: string;
|
|
31
|
+
readonly stderr: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** herdr CLI 한 번. timeoutMs 가 Infinity 면 끝없이 기다린다. */
|
|
35
|
+
export type HerdrCliRunner = (argv: readonly string[], timeoutMs: number) => Promise<HerdrCliResult>;
|
|
36
|
+
|
|
37
|
+
export interface HerdrPromptOpts {
|
|
38
|
+
readonly target: string;
|
|
39
|
+
readonly text: string;
|
|
40
|
+
readonly wait?: boolean;
|
|
41
|
+
/** 호출자 timeout(제출 포함) — 없으면 정착 대기는 끝이 없다(herdr 와 같다). */
|
|
42
|
+
readonly timeoutMs?: number;
|
|
43
|
+
/**
|
|
44
|
+
* 라벨 확인을 끈다 — 호출자가 대상을 이미 정했을 때(우편 깨움: 자리 폴더 `herdr.pane`). 상태 확인(idle/done 만)과
|
|
45
|
+
* 제출(`pane run`)은 그대로다. CLI(`eln herdr prompt`)는 켜지 않는다 — herdr 내장 kind 는 herdr agent prompt 몫.
|
|
46
|
+
*/
|
|
47
|
+
readonly anyAgent?: boolean;
|
|
48
|
+
/** `agent get` 이 agent_not_found 면 `pane get` 의 agent_status 로 떨어진다(우편 깨움 · #30261 전 경로와 같은 관문).
|
|
49
|
+
* 10-22 cct 아래 Claude 자리가 agent get 에서 간헐적으로 안 잡혀 깨움 18건이 failed 됐다. */
|
|
50
|
+
readonly paneFallback?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** 상태 확인을 통과한 대상 — `beforeSubmit` 이 본다. */
|
|
54
|
+
export interface HerdrPromptView {
|
|
55
|
+
readonly agent: string;
|
|
56
|
+
readonly status: string;
|
|
57
|
+
readonly paneId: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface HerdrPromptDeps {
|
|
61
|
+
readonly run?: HerdrCliRunner;
|
|
62
|
+
readonly now?: () => number;
|
|
63
|
+
readonly log?: (event: string, data: Record<string, unknown>) => void;
|
|
64
|
+
/** 시험용 — 제출 뒤 활동 관측 창. 기본 5000ms(herdr 의미). */
|
|
65
|
+
readonly activityWindowMs?: number;
|
|
66
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
67
|
+
/**
|
|
68
|
+
* 상태 확인 «뒤»·제출 «바로 앞» 호출자 관문 — 이유 문자열을 돌려주면 입력 0 으로 그 이유로 끝난다(accepted:false).
|
|
69
|
+
* 우편 깨움이 대상 재해석·opt-in 재확인·마감을 여기서 본다(조회 사이 바뀐 것에 넣지 않는다).
|
|
70
|
+
*/
|
|
71
|
+
readonly beforeSubmit?: (view: HerdrPromptView) => string | undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export type HerdrPromptReason =
|
|
75
|
+
| 'submitted' | 'settled'
|
|
76
|
+
| 'empty_agent_prompt' | 'not_elanous' | 'agent_blocked' | 'agent_working' | 'agent_unknown'
|
|
77
|
+
| 'agent_prompt_stalled' | 'timeout'
|
|
78
|
+
| string; // herdr 오류 코드 그대로(agent_not_found · pane_not_found …)
|
|
79
|
+
|
|
80
|
+
export interface HerdrPromptResult {
|
|
81
|
+
readonly ok: boolean;
|
|
82
|
+
/** 문장이 pane 에 들어갔나(실패여도 true 일 수 있다 — 재제출 전에 화면을 읽어라). */
|
|
83
|
+
readonly accepted: boolean;
|
|
84
|
+
readonly reason: HerdrPromptReason;
|
|
85
|
+
readonly target: string;
|
|
86
|
+
readonly paneId?: string;
|
|
87
|
+
readonly agent?: string;
|
|
88
|
+
readonly status?: string;
|
|
89
|
+
readonly message?: string;
|
|
90
|
+
readonly ms: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface AgentView {
|
|
94
|
+
readonly agent: string;
|
|
95
|
+
readonly status: string;
|
|
96
|
+
readonly paneId: string;
|
|
97
|
+
readonly seq: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** herdr 오류 봉투(stderr 또는 stdout JSON `{"error":{code,message}}`). 없으면 undefined. */
|
|
101
|
+
function herdrError(r: HerdrCliResult): { code: string; message: string } | undefined {
|
|
102
|
+
for (const text of [r.stderr, r.stdout]) {
|
|
103
|
+
const t = text.trim();
|
|
104
|
+
if (!t.startsWith('{')) continue;
|
|
105
|
+
try {
|
|
106
|
+
const e = (JSON.parse(t) as { error?: { code?: unknown; message?: unknown } }).error;
|
|
107
|
+
if (e && typeof e === 'object') {
|
|
108
|
+
return { code: typeof e.code === 'string' ? e.code : 'herdr_error', message: typeof e.message === 'string' ? e.message : '' };
|
|
109
|
+
}
|
|
110
|
+
} catch { /* not an envelope */ }
|
|
111
|
+
}
|
|
112
|
+
if (r.code === 0) return undefined;
|
|
113
|
+
return { code: r.code === null ? 'herdr_killed' : `herdr_rc_${r.code}`, message: r.stderr.trim().slice(0, 240) };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function agentOf(r: HerdrCliResult): AgentView | undefined {
|
|
117
|
+
try {
|
|
118
|
+
const a = (JSON.parse(r.stdout.trim()) as { result?: { agent?: Record<string, unknown> } }).result?.agent;
|
|
119
|
+
if (!a || typeof a.pane_id !== 'string') return undefined;
|
|
120
|
+
return {
|
|
121
|
+
agent: typeof a.agent === 'string' ? a.agent : '',
|
|
122
|
+
status: typeof a.agent_status === 'string' ? a.agent_status : 'unknown',
|
|
123
|
+
paneId: a.pane_id,
|
|
124
|
+
seq: typeof a.state_change_seq === 'number' ? a.state_change_seq : 0,
|
|
125
|
+
};
|
|
126
|
+
} catch {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** `pane get` 봉투에서 agent·agent_status — paneFallback 전용(agent get 이 못 찾을 때). seq 는 없다(0). */
|
|
132
|
+
function paneViewOf(r: HerdrCliResult): AgentView | undefined {
|
|
133
|
+
if (herdrError(r)) return undefined;
|
|
134
|
+
try {
|
|
135
|
+
const p = (JSON.parse(r.stdout.trim()) as { result?: { pane?: Record<string, unknown> } }).result?.pane;
|
|
136
|
+
if (!p || typeof p.pane_id !== 'string' || typeof p.agent_status !== 'string') return undefined;
|
|
137
|
+
return { agent: typeof p.agent === 'string' ? p.agent : '', status: p.agent_status, paneId: p.pane_id, seq: 0 };
|
|
138
|
+
} catch {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** 기본 러너 — HERDR_BIN_PATH(없으면 PATH 의 herdr). HERDR_SOCKET_PATH 등 env 는 그대로 넘긴다. */
|
|
144
|
+
export function defaultHerdrCliRunner(env: NodeJS.ProcessEnv = process.env): HerdrCliRunner {
|
|
145
|
+
const bin = env.HERDR_BIN_PATH?.trim() || 'herdr';
|
|
146
|
+
return (argv, timeoutMs) => new Promise<HerdrCliResult>((resolve) => {
|
|
147
|
+
let child: ReturnType<typeof spawn>;
|
|
148
|
+
try {
|
|
149
|
+
child = spawn(bin, [...argv], { env, stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });
|
|
150
|
+
} catch (error) {
|
|
151
|
+
resolve({ code: null, stdout: '', stderr: error instanceof Error ? error.message : String(error) });
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
let stdout = '';
|
|
155
|
+
let stderr = '';
|
|
156
|
+
let settled = false;
|
|
157
|
+
const finish = (r: HerdrCliResult): void => {
|
|
158
|
+
if (settled) return;
|
|
159
|
+
settled = true;
|
|
160
|
+
if (timer) clearTimeout(timer);
|
|
161
|
+
resolve(r);
|
|
162
|
+
};
|
|
163
|
+
const timer = Number.isFinite(timeoutMs)
|
|
164
|
+
? setTimeout(() => {
|
|
165
|
+
try { child.kill(); } catch { /* gone */ }
|
|
166
|
+
finish({ code: null, stdout, stderr: stderr || 'herdr call timed out' });
|
|
167
|
+
}, Math.max(1, timeoutMs))
|
|
168
|
+
: undefined;
|
|
169
|
+
child.stdout?.on('data', (c: Buffer | string) => { if (stdout.length < OUTPUT_CAP) stdout += String(c); });
|
|
170
|
+
child.stderr?.on('data', (c: Buffer | string) => { if (stderr.length < OUTPUT_CAP) stderr += String(c); });
|
|
171
|
+
child.on('error', (error) => finish({ code: null, stdout, stderr: error.message }));
|
|
172
|
+
child.on('close', (code) => finish({ code, stdout, stderr }));
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export async function herdrPrompt(opts: HerdrPromptOpts, deps: HerdrPromptDeps = {}): Promise<HerdrPromptResult> {
|
|
177
|
+
const now = deps.now ?? Date.now;
|
|
178
|
+
const run = deps.run ?? defaultHerdrCliRunner(deps.env);
|
|
179
|
+
const log = deps.log ?? ((event: string, data: Record<string, unknown>) => debug.log('pty.herdr', event, data));
|
|
180
|
+
const windowMs = deps.activityWindowMs ?? HERDR_PROMPT_ACTIVITY_WINDOW_MS;
|
|
181
|
+
const start = now();
|
|
182
|
+
const deadline = opts.timeoutMs !== undefined ? start + opts.timeoutMs : undefined;
|
|
183
|
+
const remaining = (): number => (deadline === undefined ? Number.POSITIVE_INFINITY : Math.max(0, deadline - now()));
|
|
184
|
+
const callCap = (): number => Math.min(CALL_TIMEOUT_MS, Math.max(1, remaining()));
|
|
185
|
+
|
|
186
|
+
let view: AgentView | undefined;
|
|
187
|
+
const done = (ok: boolean, accepted: boolean, reason: HerdrPromptReason, message?: string): HerdrPromptResult => {
|
|
188
|
+
const result: HerdrPromptResult = {
|
|
189
|
+
ok, accepted, reason, target: opts.target,
|
|
190
|
+
...(view ? { paneId: view.paneId, agent: view.agent, status: view.status } : {}),
|
|
191
|
+
...(message ? { message } : {}),
|
|
192
|
+
ms: Math.max(0, Math.round(now() - start)),
|
|
193
|
+
};
|
|
194
|
+
log('prompt', { target: opts.target, paneId: view?.paneId, accepted, reason, status: view?.status, ms: result.ms });
|
|
195
|
+
return result;
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
if (opts.text.length === 0) return done(false, false, 'empty_agent_prompt', 'prompt text must not be empty');
|
|
199
|
+
|
|
200
|
+
// ① 대상 확인
|
|
201
|
+
const got = await run(['agent', 'get', opts.target], callCap());
|
|
202
|
+
const getErr = herdrError(got);
|
|
203
|
+
if (getErr) {
|
|
204
|
+
if (!(opts.paneFallback && getErr.code === 'agent_not_found')) return done(false, false, getErr.code, getErr.message);
|
|
205
|
+
const pane = paneViewOf(await run(['pane', 'get', opts.target], callCap()));
|
|
206
|
+
if (!pane) return done(false, false, getErr.code, getErr.message);
|
|
207
|
+
log('prompt-pane-fallback', { target: opts.target, paneId: pane.paneId, agent: pane.agent, status: pane.status });
|
|
208
|
+
view = pane;
|
|
209
|
+
} else view = agentOf(got);
|
|
210
|
+
if (!view) return done(false, false, 'unparseable_agent_get');
|
|
211
|
+
if (!opts.anyAgent && view.agent !== HERDR_PROMPT_AGENT) {
|
|
212
|
+
return done(false, false, 'not_elanous', `agent label ${view.agent || '(none)'} — use herdr agent prompt for herdr-supported agents`);
|
|
213
|
+
}
|
|
214
|
+
if (view.status === 'blocked') return done(false, false, 'agent_blocked', 'agent is blocked and requires interactive input');
|
|
215
|
+
if (view.status === 'working') return done(false, false, 'agent_working', 'agent is working — wait for idle first');
|
|
216
|
+
if (view.status !== 'idle' && view.status !== 'done') return done(false, false, 'agent_unknown', `agent status ${view.status}`);
|
|
217
|
+
const seq0 = view.seq;
|
|
218
|
+
const paneId = view.paneId;
|
|
219
|
+
const veto = deps.beforeSubmit?.({ agent: view.agent, status: view.status, paneId });
|
|
220
|
+
if (veto !== undefined) return done(false, false, veto);
|
|
221
|
+
|
|
222
|
+
// ② 제출 — agent prompt 와 같은 bracketed text ⊕ Enter 한 번
|
|
223
|
+
const sent = await run(['pane', 'run', paneId, opts.text], callCap());
|
|
224
|
+
const sendErr = herdrError(sent);
|
|
225
|
+
if (sendErr) return done(false, false, sendErr.code, sendErr.message);
|
|
226
|
+
if (!opts.wait) return done(true, true, 'submitted');
|
|
227
|
+
|
|
228
|
+
const refresh = async (): Promise<AgentView | undefined> => {
|
|
229
|
+
const r = await run(['agent', 'get', paneId], CALL_TIMEOUT_MS);
|
|
230
|
+
const v = herdrError(r) ? undefined : agentOf(r);
|
|
231
|
+
if (v) view = v;
|
|
232
|
+
return v;
|
|
233
|
+
};
|
|
234
|
+
const settledStatus = (s: string): boolean => s === 'idle' || s === 'done' || s === 'blocked';
|
|
235
|
+
|
|
236
|
+
// ③ 활동 관측(working/blocked) — 창 안에 없으면 stalled, 호출자 timeout 이 먼저면 timeout
|
|
237
|
+
const win = Math.min(windowMs, remaining());
|
|
238
|
+
const activity = await run(['agent', 'wait', paneId, '--until', 'working', '--until', 'blocked', '--timeout', String(Math.max(1, Math.floor(win)))], win + KILL_GRACE_MS);
|
|
239
|
+
const actErr = herdrError(activity);
|
|
240
|
+
if (actErr) {
|
|
241
|
+
const v = await refresh();
|
|
242
|
+
// wait 를 걸기 전에 턴이 이미 돌고 끝났다 — seq 가 움직였고 정착 상태면 성공이다.
|
|
243
|
+
if (v && v.seq > seq0 && settledStatus(v.status)) return done(true, true, 'settled');
|
|
244
|
+
if (!(v && v.seq > seq0 && v.status === 'working')) {
|
|
245
|
+
if (actErr.code !== 'timeout') return done(false, true, actErr.code, actErr.message);
|
|
246
|
+
return done(false, true, remaining() <= 0 ? 'timeout' : 'agent_prompt_stalled', 'no working/blocked activity observed after submission');
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
const v = agentOf(activity);
|
|
250
|
+
if (v) view = v;
|
|
251
|
+
if (v?.status === 'blocked') return done(true, true, 'settled');
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ④ 정착(idle/done/blocked)까지
|
|
255
|
+
const rem = remaining();
|
|
256
|
+
const settleArgs = ['agent', 'wait', paneId, ...(Number.isFinite(rem) ? ['--timeout', String(Math.max(1, Math.floor(rem)))] : [])];
|
|
257
|
+
const settled = await run(settleArgs, Number.isFinite(rem) ? rem + KILL_GRACE_MS : Number.POSITIVE_INFINITY);
|
|
258
|
+
const setErr = herdrError(settled);
|
|
259
|
+
if (setErr) {
|
|
260
|
+
await refresh();
|
|
261
|
+
return done(false, true, setErr.code, setErr.message);
|
|
262
|
+
}
|
|
263
|
+
const v = agentOf(settled);
|
|
264
|
+
if (v) view = v;
|
|
265
|
+
return done(true, true, 'settled');
|
|
266
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { HerdrRunResult, HerdrRunner } from './herdr-agent-report.js';
|
|
2
|
+
|
|
3
|
+
const PRUNE_TIMEOUT_MS = 300;
|
|
4
|
+
|
|
5
|
+
/** Best-effort removal of a prior custom agent left behind in this pane. */
|
|
6
|
+
export function pruneStaleHerdrAgent(
|
|
7
|
+
paneId: string,
|
|
8
|
+
seq: string,
|
|
9
|
+
run: HerdrRunner,
|
|
10
|
+
): HerdrRunResult {
|
|
11
|
+
const result = run([
|
|
12
|
+
'pane', 'release-agent', paneId,
|
|
13
|
+
'--source', 'custom:elanous', '--agent', 'elanous', '--seq', seq,
|
|
14
|
+
], { sync: true, timeoutMs: PRUNE_TIMEOUT_MS });
|
|
15
|
+
if (result instanceof Promise) throw new Error('startup prune requires a synchronous herdr runner');
|
|
16
|
+
return result;
|
|
17
|
+
}
|