elanous 0.2.36 → 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/{uC-N0emedeNOFuaBQFv-I → 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/{4286.b70c4520306817e8.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/{3410.7f9af5ab77cbe65f.js → 1746.3563617ea64023a3.js} +1 -1
- 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/1ed5e8af.cf424815c7c0efad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9250-072df22eaadaa6b5.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/210.90b2cbd64926cf34.js +32 -0
- package/apps/pwa/out/_next/static/chunks/{3727.7949ccaacaa71242.js → 2283.edd9627b7bdfb546.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2318-450e75d07605b8fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4615.8525eb0add35eba6.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/{5711.957b095705c12560.js → 3199.6a1a9b0e6cd01dc6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2986.45d7652e4f13557e.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/{7481.39f7a4654907bf6e.js → 4313.76f232c304a15bde.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4337e36d.f42c3b391b3d8f20.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{6943.c6b24124853a47b2.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/{3757-180308bc61021b05.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/4833-7934c592c5569f00.js +1 -0
- 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/{771.c3cdb6c1f7f47c02.js → 4931.95cc6dbd230774ca.js} +3 -3
- 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/{552.b7d061ad91eeac51.js → 5046.7fd5cbd859299448.js} +2 -2
- 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/{9f31e478.fefcbcd3c388ebc5.js → 58edce7d.f1b0c72acf13b123.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +93 -0
- package/apps/pwa/out/_next/static/chunks/{3136.30aaaa5fa03662a3.js → 5952.294fc574a8625184.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{da5ecc5c-b005ad8cac737d57.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/{3324.a09703033abcbd2f.js → 6252.240578f10952e091.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8904.7d51af2dc033965c.js → 6680.6a693c28aae4cd19.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{275-02ea4c2a33980422.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/{528.38ce20ef8aa251ff.js → 6819.be5c9c4d67f22922.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3a3d9966.cc4d4585a2708e7c.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/{4304.e9b2512834a9e23e.js → 7424.c0fe2a595d4232b5.js} +1 -1
- 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/{2683.c9773a0c589b031b.js → 7867.e8725745ddd1d940.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/{6466-92e65a48490b68a9.js → 7893-e444a1b0809cd1e4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{ccae1c4b-0cf414f5eff1b10d.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/{3840-5825d56d46976a92.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/{873d6c12.09bd499f57171543.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/{575.d929793a53f27c4b.js → 9151.a2c51e93f9156dae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +1 -0
- 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/{190.285c832bd9626f8c.js → 958.53a8dcf4729e6997.js} +1 -1
- 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-e2de2e59111c9aad.js → page-3337c6a1328c2674.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/{page-f2b2e4bf6e981450.js → page-89acd5d68c0bc560.js} +1 -1
- 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-2af16e62c12f22df.js → page-fe986fe79b107546.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-1e5da297557d2354.js +1 -0
- 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-88a1edbff62eaf1d.js +1 -0
- 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-443364c9e4a23b31.js +1 -0
- 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-ac2c1e6169cfce57.js +1 -0
- 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/{053a429e.9a63436527cc751c.js → d9815f84.4918f682a45a8502.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{ceba0382.650712b56b85b582.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/graphs/drafts/recipes.yaml +27 -7
- 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/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/codex-fallback-live-probe.ts +17 -15
- package/scripts/fleet/node-setup.sh +32 -2
- package/scripts/fleet/run-light-worker.sh +9 -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 +140 -0
- package/scripts/release-loop/gate-closure.ts +48 -0
- package/scripts/release-loop/gate-diff.ts +2 -1
- package/scripts/release-loop/known-issues-node.ts +6 -4
- package/scripts/release-loop/notes-repair.ts +216 -0
- package/scripts/release-loop/prepare-node.ts +61 -5
- package/scripts/release-loop/resume-release.ts +114 -4
- package/scripts/release-loop/resume-test-traffic.ts +10 -0
- package/scripts/release-loop/version-node.ts +81 -12
- package/scripts/train/green-leg.ts +176 -0
- package/scripts/tui-continue-real-evidence.ts +47 -0
- package/scripts/ux-sim.ts +1 -1
- package/src/acp/client.ts +31 -5
- package/src/acp/core-turn-bridge.ts +6 -0
- package/src/acp/stderr-summary.ts +49 -0
- package/src/agent/monad-agent-turn.ts +1 -0
- package/src/agent/terminal-surface.ts +217 -0
- package/src/agent-substrate/pr-reviewer.ts +11 -3
- package/src/agent-substrate/self-review-cli.ts +343 -31
- package/src/autopilot/lineage/sources.ts +1 -1
- package/src/autopilot/pr-manager.ts +64 -13
- package/src/boot/daemon-runtime.ts +35 -3
- package/src/boot/daemon-tools/pty-shell.ts +2 -1
- package/src/budget/run-usage-rollup.ts +12 -7
- package/src/budget/unified-usage.ts +20 -0
- package/src/capture/tui-self-report.ts +32 -3
- package/src/cli/autopilot-cli.ts +24 -9
- package/src/cli/decisions-cli.ts +7 -4
- package/src/cli/doctor-cli.ts +116 -7
- package/src/cli/logs-cli.ts +357 -2
- package/src/cli/memory-cli.ts +30 -1
- package/src/cli/msg-cli.ts +15 -11
- package/src/cli/pr-granularity.ts +5 -3
- package/src/cli/release-checklist-read-cli.ts +109 -4
- package/src/cli/release-cli.ts +43 -10
- package/src/cli/self-update.ts +23 -5
- package/src/cli/self-utterances-cli.ts +13 -16
- package/src/cli/tasks-cli.ts +309 -11
- 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-goal-loop.ts +5 -2
- package/src/core-turn/types.ts +2 -0
- package/src/dashboard/chat/acp-chat.ts +9 -0
- package/src/dashboard/index.ts +97 -13
- package/src/dashboard/input/agent-wake.ts +43 -0
- package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
- package/src/dashboard/replay-preview.ts +25 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +17 -8
- package/src/dashboard/synchronized-frame-output.ts +74 -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/surface-events.ts +80 -1
- 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/graph-runner/graph-cli.ts +26 -2
- package/src/graph-runner/graph-run-api.ts +3 -2
- package/src/graph-runner/runner.ts +17 -5
- package/src/graph-wizard/generate.ts +29 -6
- package/src/harness/harness-cli-command.ts +179 -33
- package/src/harness/review-adapter.ts +26 -6
- package/src/index.ts +116 -13
- package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
- 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.ts +123 -11
- 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/orchestrator/anomaly-cluster.ts +243 -0
- package/src/loops/orchestrator/tick.ts +49 -4
- package/src/model-tier/llm-tier-map.ts +12 -17
- package/src/msg/msg-store.ts +17 -0
- package/src/native-tool-catalog.ts +1 -1
- package/src/nexus/api/graph-wizard-api.ts +27 -2
- 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/state/state.ts +7 -1
- package/src/oauth/codex-account-store.ts +34 -1
- package/src/ops/loops-map.ts +46 -0
- package/src/ops/overview-cache.ts +22 -4
- package/src/ops/overview.ts +41 -5
- package/src/policy/llm-policy.ts +3 -1
- package/src/prompt-enhance/enhance.ts +4 -4
- package/src/pty-shell/availability.ts +7 -0
- package/src/pty-shell/herdr-agent-report.ts +40 -31
- 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 +187 -18
- package/src/pty-shell/registry.ts +25 -15
- package/src/pty-shell/tui-run-state.ts +235 -1
- package/src/release-loop/checklist.ts +50 -5
- package/src/release-loop/feature-store.ts +9 -9
- package/src/release-loop/landed-but-yellow.ts +93 -12
- package/src/repl/index.ts +8 -0
- 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 +29 -18
- package/src/self-dev/dev-pipeline.ts +29 -7
- package/src/self-dev/draft-sweep.ts +241 -16
- package/src/self-dev/draft-triage-rules.ts +19 -5
- package/src/self-dev/review-provider-fallback.ts +45 -7
- package/src/self-dev/shard-plan.ts +48 -0
- package/src/self-dev/shard-run.ts +50 -3
- package/src/self-implement/doctor-visit.ts +83 -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.ts +333 -18
- package/src/self-implement/goal-supervisor-fill.ts +75 -26
- package/src/self-implement/importer-test-index.ts +215 -2
- package/src/self-implement/knowhow-pack.ts +5 -5
- package/src/self-implement/orchestrator.ts +318 -25
- package/src/self-implement/review-round-brief.ts +300 -0
- package/src/self-implement/rework-policy.ts +14 -0
- package/src/self-implement/run-ledger.ts +170 -6
- package/src/self-implement/run-stop.ts +1 -1
- package/src/self-implement/running-runs.ts +17 -3
- package/src/self-implement/seams.ts +12 -6
- 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/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/skills/tools/pty.ts +5 -0
- package/src/status/metrics.ts +12 -1
- package/src/steward/rejudge-tick.ts +12 -5
- package/src/steward/resync-tick.ts +31 -4
- package/src/task-agent/actions.ts +199 -4
- 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/live-moves.ts +48 -3
- 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/parent-host.ts +21 -11
- package/src/task-agent/rejudge-on-head.ts +72 -5
- package/src/task-agent/repair-cycle.ts +41 -0
- package/src/task-agent/repair-next-move.ts +12 -2
- package/src/task-agent/review-prior-fix.ts +12 -2
- package/src/task-agent/shadow.ts +188 -5
- package/src/task-agent/task-hand.ts +158 -13
- package/src/task-agent/task-parent-role-llm.ts +9 -0
- package/src/task-agent/tier-split.ts +4 -3
- 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-artifact-return.ts +16 -6
- 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-pool.ts +50 -4
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +15 -9
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +217 -36
- package/src/task-orchestrator/surfaces/self-implement.ts +4 -0
- package/src/testing/linux-env.ts +177 -0
- package/src/tui/chat/goal-interim.ts +5 -1
- package/src/tui/entry.ts +258 -4
- package/src/tui/input/at-picker.ts +55 -0
- package/src/tui/slash/resume.ts +35 -12
- 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 +4 -3
- 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 +158 -4
- package/src/ux-sim/fake-gh.ts +174 -0
- package/src/ux-sim/fake-kubectl.ts +142 -0
- package/src/ux-sim/fake-llm.ts +6 -1
- package/src/ux-sim/next-tui-seat-scenarios.ts +124 -6
- 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/task-agent-parent-host-device.ts +264 -0
- package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +0 -287
- package/apps/pwa/out/_next/static/chunks/1201.afbfc5b1c5e5cbe4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +0 -36
- package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +0 -149
- package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2500.cbc1257b774aae52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +0 -24
- package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +0 -1
- package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +0 -24
- package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3148-98efd4869d660a87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +0 -226
- package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +0 -8
- package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +0 -32
- package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +0 -286
- package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +0 -1
- package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +0 -74
- package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +0 -104
- package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +0 -148
- package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +0 -122
- package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +0 -41
- package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +0 -79
- package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +0 -1
- package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +0 -27
- package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +0 -1
- package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7891.03f910124a737985.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +0 -1
- package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +0 -62
- package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +0 -90
- package/apps/pwa/out/_next/static/chunks/914.8abefd48d579547b.js +0 -94
- package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +0 -77
- package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9514.131c52cc75fe6439.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9789.60f723d18097ec30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +0 -1
- /package/apps/pwa/out/_next/static/{uC-N0emedeNOFuaBQFv-I → 8kITumG9GAZ1LwT9POrAR}/_ssgManifest.js +0 -0
package/src/cli/doctor-cli.ts
CHANGED
|
@@ -44,9 +44,11 @@ import {
|
|
|
44
44
|
DOCTOR_SYMPTOMS,
|
|
45
45
|
DOCTOR_VISIT_SOURCES,
|
|
46
46
|
doctorVisitRunExists,
|
|
47
|
+
doctorReviewVisits,
|
|
47
48
|
isDoctorSymptom,
|
|
48
49
|
isDoctorVisitSource,
|
|
49
50
|
readDoctorVisits,
|
|
51
|
+
readDoctorReviewBrief,
|
|
50
52
|
recordAutoLongRunVisit,
|
|
51
53
|
recordDoctorVisit,
|
|
52
54
|
type DoctorSymptom,
|
|
@@ -55,6 +57,8 @@ import { formatHostDoctorLines, runHostDoctor, type HostDoctorExpected, type Hos
|
|
|
55
57
|
import { listMachineResources } from './control-cli.js';
|
|
56
58
|
import type { ResourceView } from '../control-plane/ledger.js';
|
|
57
59
|
import { loadMachineLedger } from '../machines/machine-ledger.js';
|
|
60
|
+
import { LogStore, logsDbPath, type LogStoreRow } from '../mss/logging/log-store.js';
|
|
61
|
+
import { reviewBriefEvidence } from '../self-implement/review-round-brief.js';
|
|
58
62
|
|
|
59
63
|
function defaultCheckPythonEnv(): { status: 'ok' | 'fixable' | 'manual'; evidence: string; remedy?: string } {
|
|
60
64
|
const c = checkPythonEnv(false);
|
|
@@ -223,10 +227,49 @@ export interface DoctorCliDeps extends DoctorOptions, Pick<DoctorFixDeps, 'home'
|
|
|
223
227
|
hostDoctorMachineResources?: () => Promise<ResourceView[]>;
|
|
224
228
|
/** `doctor visit`/`doctor status` 원장 디렉터리(시험 seam) — 기본 = `runLedgerDir()`. */
|
|
225
229
|
doctorVisitLedgerDir?: string;
|
|
230
|
+
/** Isolated saved-review and PR metadata seams. */
|
|
231
|
+
reviewResultsDir?: string;
|
|
232
|
+
readReviewBriefPr?: Parameters<typeof readDoctorReviewBrief>[1];
|
|
233
|
+
/** Optional isolated observation transport and status reader for CLI tests. */
|
|
234
|
+
reviewBriefLog?: (event: Record<string, unknown>) => void;
|
|
235
|
+
readReviewBriefEvents?: (runId?: string) => Array<{ timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }>;
|
|
226
236
|
/** `doctor visit` 사고 선례 연결 루트(시험 seam) — 기본 = `doctorVisitIncidentRoot()` · `null` 이면 건너뛴다. */
|
|
227
237
|
doctorVisitIncidentRoot?: string | null;
|
|
228
238
|
/** Deterministic clock for `doctor auto-long-run` isolated CLI tests. */
|
|
229
239
|
doctorAutoLongRunNow?: () => string;
|
|
240
|
+
/** Standalone logs.db registration seam for the two run-doctor CLI emitters. */
|
|
241
|
+
registerDoctorLogSink?: () => Promise<unknown>;
|
|
242
|
+
/** Flush seam paired with registerDoctorLogSink. */
|
|
243
|
+
flushDoctorLogs?: () => void;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function parseReviewBriefLogData(raw: unknown): Record<string, unknown> {
|
|
247
|
+
let data: unknown;
|
|
248
|
+
try { data = typeof raw === 'string' ? JSON.parse(raw) : raw; }
|
|
249
|
+
catch (error) { throw new Error(`malformed doctor.review/brief-issued event: ${error instanceof Error ? error.message : String(error)}`); }
|
|
250
|
+
if (!data || typeof data !== 'object' || Array.isArray(data)) throw new Error('malformed doctor.review/brief-issued event: expected object data');
|
|
251
|
+
const value = data as Record<string, unknown>;
|
|
252
|
+
if (typeof value.pr !== 'number' || typeof value.head !== 'string' || typeof value.round !== 'number') {
|
|
253
|
+
throw new Error('malformed doctor.review/brief-issued event: required pr/head/round fields are missing');
|
|
254
|
+
}
|
|
255
|
+
return value;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function readReviewBriefEventsFromLogs(dbPath = logsDbPath(), runId?: string): Array<{ timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }> {
|
|
259
|
+
if (!existsSync(dbPath)) return [];
|
|
260
|
+
let store: LogStore | undefined;
|
|
261
|
+
try {
|
|
262
|
+
store = LogStore.openReadOnly(dbPath);
|
|
263
|
+
return store.queryAll({ exactCategories: ['doctor.review'], events: ['brief-issued'] }).flatMap((row: LogStoreRow) => {
|
|
264
|
+
const data = parseReviewBriefLogData(row.data);
|
|
265
|
+
const rowRunId = typeof data.runId === 'string' && data.runId ? data.runId : undefined;
|
|
266
|
+
if (runId !== undefined && rowRunId !== runId) return [];
|
|
267
|
+
return [{ timestamp: new Date(row.ts_ms).toISOString(), sequence: row.id, ...(rowRunId ? { runId: rowRunId } : {}), key: String(data.pr), evidence: `PR #${data.pr} head ${data.head.slice(0, 12)} r${data.round} rx=${String(data.rx)}${data.source === 'pr-disposition' ? ' source=pr-disposition' : ''}` }];
|
|
268
|
+
});
|
|
269
|
+
} catch (error) {
|
|
270
|
+
throw new Error(`review event logs could not be read: ${error instanceof Error ? error.message : String(error)}`);
|
|
271
|
+
}
|
|
272
|
+
finally { store?.close(); }
|
|
230
273
|
}
|
|
231
274
|
|
|
232
275
|
const repositoryRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
|
|
@@ -1293,6 +1336,9 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
|
|
|
1293
1336
|
const out = deps.out ?? { log: (value: string) => console.log(value) };
|
|
1294
1337
|
const err = deps.err ?? { error: (value: string) => console.error(value) };
|
|
1295
1338
|
const setExitCode = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
|
|
1339
|
+
const registerDoctorLogSink = deps.registerDoctorLogSink ?? (async () =>
|
|
1340
|
+
(await import('../domains/standalone-log-sink.js')).registerStandaloneLogSink('cli'));
|
|
1341
|
+
const flushDoctorLogs = deps.flushDoctorLogs ?? (() => debug.flush());
|
|
1296
1342
|
const doctor = program.command('doctor')
|
|
1297
1343
|
.description('Reports whether credentials resolve and where each resolution comes from')
|
|
1298
1344
|
.option('--json', 'structured output');
|
|
@@ -1358,9 +1404,10 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
|
|
|
1358
1404
|
.argument('<runId>', 'run id whose ledger receives the visit')
|
|
1359
1405
|
.requiredOption('--started-at <iso>', 'Pod status.startTime as an ISO timestamp')
|
|
1360
1406
|
.option('--json', 'structured output')
|
|
1361
|
-
.action((runId: string, opts: { startedAt: string; json?: boolean }, command: Command) => {
|
|
1407
|
+
.action(async (runId: string, opts: { startedAt: string; json?: boolean }, command: Command) => {
|
|
1362
1408
|
const json = opts.json === true || command.parent?.opts().json === true;
|
|
1363
1409
|
try {
|
|
1410
|
+
await registerDoctorLogSink();
|
|
1364
1411
|
const result = recordAutoLongRunVisit({ runId, startedAt: opts.startedAt,
|
|
1365
1412
|
...(deps.doctorAutoLongRunNow ? { now: deps.doctorAutoLongRunNow() } : {}),
|
|
1366
1413
|
...(deps.doctorVisitLedgerDir !== undefined ? { dir: deps.doctorVisitLedgerDir } : {}) });
|
|
@@ -1370,6 +1417,8 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
|
|
|
1370
1417
|
if (json) out.log(JSON.stringify({ status: 'rejected', reason }));
|
|
1371
1418
|
else err.error(reason);
|
|
1372
1419
|
setExitCode(1);
|
|
1420
|
+
} finally {
|
|
1421
|
+
flushDoctorLogs();
|
|
1373
1422
|
}
|
|
1374
1423
|
});
|
|
1375
1424
|
doctor.command('visit')
|
|
@@ -1379,7 +1428,7 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
|
|
|
1379
1428
|
.requiredOption('--from <who>', `closed sender list: ${DOCTOR_VISIT_SOURCES.join(', ')}`)
|
|
1380
1429
|
.option('--evidence <text>', 'free-text evidence recorded with the visit')
|
|
1381
1430
|
.option('--json', 'structured output')
|
|
1382
|
-
.action((runId: string, opts: { symptom: string; from: string; evidence?: string; json?: boolean }, command: Command) => {
|
|
1431
|
+
.action(async (runId: string, opts: { symptom: string; from: string; evidence?: string; json?: boolean }, command: Command) => {
|
|
1383
1432
|
const json = opts.json === true || command.parent?.opts().json === true;
|
|
1384
1433
|
if (!isDoctorSymptom(opts.symptom)) {
|
|
1385
1434
|
const reason = `unknown symptom: ${opts.symptom} — closed list: ${DOCTOR_SYMPTOMS.join(', ')}`;
|
|
@@ -1396,6 +1445,7 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
|
|
|
1396
1445
|
return;
|
|
1397
1446
|
}
|
|
1398
1447
|
try {
|
|
1448
|
+
await registerDoctorLogSink();
|
|
1399
1449
|
const visit = recordDoctorVisit({
|
|
1400
1450
|
runId,
|
|
1401
1451
|
from: opts.from,
|
|
@@ -1410,6 +1460,54 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
|
|
|
1410
1460
|
if (json) out.log(JSON.stringify({ status: 'rejected', reason }));
|
|
1411
1461
|
else err.error(reason);
|
|
1412
1462
|
setExitCode(1);
|
|
1463
|
+
} finally {
|
|
1464
|
+
flushDoctorLogs();
|
|
1465
|
+
}
|
|
1466
|
+
});
|
|
1467
|
+
doctor.command('review-brief')
|
|
1468
|
+
.description('Build a review-round card from saved reviews for the current PR head')
|
|
1469
|
+
.requiredOption('--pr <number>', 'PR number')
|
|
1470
|
+
.option('--json', 'structured output')
|
|
1471
|
+
.action(async (opts: { pr: string; json?: boolean }, command: Command) => {
|
|
1472
|
+
const json = opts.json === true || command.parent?.opts().json === true;
|
|
1473
|
+
const pr = Number(opts.pr);
|
|
1474
|
+
if (!Number.isSafeInteger(pr) || pr <= 0) {
|
|
1475
|
+
const reason = 'PR number must be a positive integer';
|
|
1476
|
+
if (json) out.log(JSON.stringify({ status: 'rejected', reason })); else err.error(reason);
|
|
1477
|
+
setExitCode(1);
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
try {
|
|
1481
|
+
const brief = readDoctorReviewBrief(pr, deps.readReviewBriefPr, deps.reviewResultsDir);
|
|
1482
|
+
const event = reviewBriefEvidence(brief);
|
|
1483
|
+
const intentBlock = typeof event.intentBlock === 'string' ? event.intentBlock : null;
|
|
1484
|
+
if (deps.reviewBriefLog) deps.reviewBriefLog(event);
|
|
1485
|
+
else {
|
|
1486
|
+
await (await import('../domains/standalone-log-sink.js')).registerStandaloneLogSink('cli');
|
|
1487
|
+
debug.log('doctor.review', 'brief-issued', event);
|
|
1488
|
+
debug.flush();
|
|
1489
|
+
}
|
|
1490
|
+
out.log(json ? JSON.stringify({ ...brief, intentBlock }, null, 2) : [
|
|
1491
|
+
`PR #${pr} · ${brief.status} · rounds=${brief.rounds} · head=${brief.head.slice(0, 12)} · verdict=${brief.reviewedVerdict} · rx=${brief.rx}`,
|
|
1492
|
+
...(brief.dispositionEvidence ? [`Source: PR author disposition (current head review unmeasured) · ${brief.dispositionEvidence}`] : []),
|
|
1493
|
+
...(brief.goalQuestion ? [`Original question: ${brief.goalQuestion}`] : []),
|
|
1494
|
+
...(brief.acceptanceSignal.length ? ['Acceptance signal:', ...brief.acceptanceSignal.map((item) => ` - ${item}`)] : []),
|
|
1495
|
+
`Core items (${brief.coreItems.length}/${brief.totalCoreItems}):`,
|
|
1496
|
+
...brief.coreItems.map((item) => ` [${item.kind}] ${item.text}`),
|
|
1497
|
+
...(brief.omittedCoreItems ? [`Core items omitted: ${brief.omittedCoreItems}; source files: ${brief.resultPaths.join(', ')}`] : []),
|
|
1498
|
+
`Prior findings (${brief.priorFindings.length}/${brief.totalPriorFindings}):`, ...brief.priorFindings.map((item) => ` [${item.kind} · ${item.sourceHead.slice(0, 12)}] ${item.text}`),
|
|
1499
|
+
...(brief.omittedPriorFindings ? [`Prior findings omitted: ${brief.omittedPriorFindings}; source files: ${brief.resultPaths.join(', ')}`] : []),
|
|
1500
|
+
`Scope candidates (${brief.scopeItems.length}/${brief.totalScopeItems}):`, ...brief.scopeItems.map((item) => ` [${item.kind}] ${item.text}`),
|
|
1501
|
+
...(brief.omittedScopeItems ? [`Scope candidates omitted: ${brief.omittedScopeItems}; source files: ${brief.resultPaths.join(', ')}`] : []),
|
|
1502
|
+
...(brief.resultPaths.length ? [`Review source files: ${brief.resultPaths.join(', ')}`] : []),
|
|
1503
|
+
`Scope boundary: ${brief.scopeBoundary}`,
|
|
1504
|
+
...(intentBlock ? ['R3 intent shadow output:', intentBlock] : []),
|
|
1505
|
+
...(brief.reason ? [`Reason: ${brief.reason}`] : []),
|
|
1506
|
+
].join('\n'));
|
|
1507
|
+
} catch (error) {
|
|
1508
|
+
const reason = observationError(error);
|
|
1509
|
+
if (json) out.log(JSON.stringify({ status: 'unavailable', pr, reason })); else err.error(reason);
|
|
1510
|
+
setExitCode(1);
|
|
1413
1511
|
}
|
|
1414
1512
|
});
|
|
1415
1513
|
doctor.command('status')
|
|
@@ -1427,18 +1525,29 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
|
|
|
1427
1525
|
return;
|
|
1428
1526
|
}
|
|
1429
1527
|
const visits = readDoctorVisits(opts.run, ledgerScope);
|
|
1528
|
+
let reviewEvents: Array<{ timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }>;
|
|
1529
|
+
try {
|
|
1530
|
+
reviewEvents = (deps.readReviewBriefEvents ?? ((runId?: string) => readReviewBriefEventsFromLogs(logsDbPath(), runId)))(opts.run);
|
|
1531
|
+
} catch (error) {
|
|
1532
|
+
const reason = observationError(error);
|
|
1533
|
+
if (json) out.log(JSON.stringify({ status: 'unavailable', reason, recordedVisits: visits }, null, 2));
|
|
1534
|
+
else out.log(`Doctor status unavailable: ${reason}\nRecorded doctor visits: ${visits.length}`);
|
|
1535
|
+
setExitCode(1);
|
|
1536
|
+
return;
|
|
1537
|
+
}
|
|
1538
|
+
const statusVisits = [...visits, ...doctorReviewVisits(reviewEvents)];
|
|
1430
1539
|
const counts = Object.fromEntries(DOCTOR_SYMPTOMS.map((symptom: DoctorSymptom) => [symptom, 0])) as Record<DoctorSymptom, number>;
|
|
1431
|
-
for (const visit of
|
|
1540
|
+
for (const visit of statusVisits) counts[visit.symptom] += 1;
|
|
1432
1541
|
if (json) {
|
|
1433
|
-
out.log(JSON.stringify({ total:
|
|
1542
|
+
out.log(JSON.stringify({ total: statusVisits.length, counts, visits: statusVisits }, null, 2));
|
|
1434
1543
|
return;
|
|
1435
1544
|
}
|
|
1436
1545
|
out.log([
|
|
1437
|
-
`Doctor visits: ${
|
|
1546
|
+
`Doctor visits: ${statusVisits.length}`,
|
|
1438
1547
|
...DOCTOR_SYMPTOMS.map((symptom: DoctorSymptom) => ` ${symptom}: ${counts[symptom]}`),
|
|
1439
1548
|
'Recent visits:',
|
|
1440
|
-
...
|
|
1441
|
-
...(
|
|
1549
|
+
...statusVisits.map((visit) => ` ${visit.timestamp ?? 'unknown-time'}${visit.runId ? ` runId=${visit.runId}` : ''} from=${visit.from} symptom=${visit.symptom}${visit.evidence !== undefined ? ` evidence=${visit.evidence}` : ''}`),
|
|
1550
|
+
...(statusVisits.length === 0 ? [' none'] : []),
|
|
1442
1551
|
].join('\n'));
|
|
1443
1552
|
});
|
|
1444
1553
|
doctor
|
package/src/cli/logs-cli.ts
CHANGED
|
@@ -49,6 +49,8 @@ import { bookmarkAttachDefaults } from './remote-resolve.js';
|
|
|
49
49
|
import { RemotesStore } from './remotes.js';
|
|
50
50
|
import { detectRepeatedFailures, explainFailure } from '../domains/repeated-failure.js';
|
|
51
51
|
import { redactSecretText } from '../debug/log.js';
|
|
52
|
+
// 타입 전용 — `graph-templates` 는 typescript 를 무는 모듈이라 «런타임 정적 의존»으로 두지 않는다.
|
|
53
|
+
import type { GraphTemplate } from '../self-implement/graph-templates.js';
|
|
52
54
|
|
|
53
55
|
export interface LogsCliOpts {
|
|
54
56
|
follow?: boolean;
|
|
@@ -99,6 +101,14 @@ export interface LogsCliOpts {
|
|
|
99
101
|
all?: boolean;
|
|
100
102
|
/** --all 연합에 격리 test 인스턴스도 포함(기본 제외 · Phase A). */
|
|
101
103
|
includeTest?: boolean;
|
|
104
|
+
/** ⭐ 런 종료 «이후» L0 커버리지를 열린 스토어들(부모·Pod)의 걸음 행으로 다시 조인해 센다(ARG-L0-COVER). */
|
|
105
|
+
recompute?: boolean;
|
|
106
|
+
/** --recompute 조인 키 — runId. */
|
|
107
|
+
run?: string;
|
|
108
|
+
/** --recompute 조인 키 — journeyKey(Pod 자식이 물려받는 키). */
|
|
109
|
+
journey?: string;
|
|
110
|
+
/** --recompute 대상 그래프 id (기본 self-implement). */
|
|
111
|
+
graph?: string;
|
|
102
112
|
}
|
|
103
113
|
|
|
104
114
|
// ── 인스턴스 타겟 해석 (LF7-b) ────────────────────────────────────────
|
|
@@ -1522,14 +1532,349 @@ export function aggregateListEvents(
|
|
|
1522
1532
|
return { events, truncated, unreadable };
|
|
1523
1533
|
}
|
|
1524
1534
|
|
|
1535
|
+
// ── L0 커버리지 «런 종료 후» 조인 재계산 (ARG-L0-COVER · 2026-10-24) ──────
|
|
1536
|
+
//
|
|
1537
|
+
// 🩸 계기: `#25957` 은 런이 **끝나는 순간** logs.db «한 곳»만 읽어 `l0-coverage` 를 낸다.
|
|
1538
|
+
// 설치본 10-12 표본 = declarationCoverage 1 · traversalCoverage 11/26(0.423076923) · unjoinedNodes 15.
|
|
1539
|
+
// 그 15 는 «다른 프로세스(Pod)가 자기 우주에 남긴 걸음»이라 종료 시점엔 원리상 조인할 수 없다.
|
|
1540
|
+
// ⇒ 조회 시점에 부모·Pod 스토어를 `journeyKey`/`runId` 로 합쳐 다시 세는 경로가 «없어서»
|
|
1541
|
+
// 사람이 두 우주를 손으로 오가며 셌고, 그때마다 0.42 를 «미달»로 오독했다.
|
|
1542
|
+
//
|
|
1543
|
+
// ⛔ 이 재계산은 **조회 시점의 별도 표시**다 — 런 종료 관측(`l0-coverage`)과 원장 형식은 «그대로» 둔다.
|
|
1544
|
+
// ⛔ 미관측(unobserved)을 skipped 나 0 으로 접지 않는다. 셋은 서로 다른 값이다:
|
|
1545
|
+
// joined = 이 런/여정에서 실제로 걸었다(어느 스토어에서 봤는지까지 남긴다)
|
|
1546
|
+
// skipped = 조건이 거짓이라 안 걸었다 — **관측이 그렇게 판정한 행이 있을 때만**
|
|
1547
|
+
// unobserved = 아무도 안 봤다 — 분자에도 분모의 다른 칸에도 섞지 않는다
|
|
1548
|
+
// ⛔ 조인 안 된 노드를 `unjoinedNodes: ['a','b',…]` 하나로 뭉개지 않는다 —
|
|
1549
|
+
// **스토어(우주/호스트)별 + 사유별**로 낸다(사유가 다르면 처방이 다르다).
|
|
1550
|
+
|
|
1551
|
+
/** 조인되지 않은 «사유» — 닫힌 어휘. 자유 문자열이면 「왜 안 붙었나」를 셀 수 없다. */
|
|
1552
|
+
export type L0UnjoinedReason =
|
|
1553
|
+
/** 같은 그래프 선언이 아니다(다른 graphId/버전) — 노드 id 를 비교할 수 없다. */
|
|
1554
|
+
| 'graph-mismatch'
|
|
1555
|
+
/** 여정 단계(phase) 행이 아니다 — 걸음이 아니라 다른 관측이다. */
|
|
1556
|
+
| 'phase-mismatch'
|
|
1557
|
+
/** journeyKey 가 둘 다 있는데 다르다 — 다른 여정(프로세스)의 걸음이다. */
|
|
1558
|
+
| 'journey-key-mismatch'
|
|
1559
|
+
/** runId 가 둘 다 있는데 다르다 — 조인 키가 이 런이 아니다. */
|
|
1560
|
+
| 'run-id-mismatch'
|
|
1561
|
+
/** 행에 runId 도 journeyKey 도 없다 — «내 것인지» 판정할 근거가 없다(0 으로 접지 않는다). */
|
|
1562
|
+
| 'identity-absent';
|
|
1563
|
+
|
|
1564
|
+
export interface JoinedCoverageRow {
|
|
1565
|
+
readonly event: string;
|
|
1566
|
+
readonly data: string | null;
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
export interface JoinedCoverageStore {
|
|
1570
|
+
readonly name: string;
|
|
1571
|
+
readonly rows: readonly JoinedCoverageRow[];
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
export interface JoinedCoverageInput {
|
|
1575
|
+
readonly runId?: string;
|
|
1576
|
+
readonly journeyKey?: string;
|
|
1577
|
+
readonly stores: readonly JoinedCoverageStore[];
|
|
1578
|
+
/** 열지 못한 스토어(다른 우주/호스트) — «못 본» 사실을 수 옆에 남긴다. */
|
|
1579
|
+
readonly storesNotQueried?: readonly string[];
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
export interface JoinedCoverageUnjoined {
|
|
1583
|
+
readonly node: string;
|
|
1584
|
+
readonly host: string;
|
|
1585
|
+
readonly reason: L0UnjoinedReason;
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
export interface L0CoverageMeasureResult {
|
|
1589
|
+
readonly declarationCoverage: number | null;
|
|
1590
|
+
readonly traversalCoverage: number | null;
|
|
1591
|
+
readonly declaredStageCount: number;
|
|
1592
|
+
readonly listedStageCount: number;
|
|
1593
|
+
readonly accountedNodeCount: number;
|
|
1594
|
+
readonly declaredNodeCount: number;
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
/** 계량기는 주입받는다 — `graph-templates`(typescript 를 싣는다)를 CLI 정적 의존으로 끌어오지 않기 위해서다. */
|
|
1598
|
+
export type L0CoverageMeasure = (
|
|
1599
|
+
template: GraphTemplate,
|
|
1600
|
+
entered: Iterable<string>,
|
|
1601
|
+
skipped: Iterable<string>,
|
|
1602
|
+
) => L0CoverageMeasureResult;
|
|
1603
|
+
|
|
1604
|
+
export interface JoinedL0Coverage extends L0CoverageMeasureResult {
|
|
1605
|
+
readonly graphId: string;
|
|
1606
|
+
readonly graphVersion: string;
|
|
1607
|
+
readonly runId: string | null;
|
|
1608
|
+
readonly journeyKey: string | null;
|
|
1609
|
+
readonly joinedNodes: ReadonlyArray<{ readonly node: string; readonly hosts: readonly string[] }>;
|
|
1610
|
+
readonly skippedNodes: readonly string[];
|
|
1611
|
+
readonly unobservedNodes: readonly string[];
|
|
1612
|
+
readonly unjoinedNodes: readonly JoinedCoverageUnjoined[];
|
|
1613
|
+
readonly unjoinedByHost: ReadonlyArray<{
|
|
1614
|
+
readonly host: string;
|
|
1615
|
+
readonly count: number;
|
|
1616
|
+
readonly reasons: ReadonlyArray<{ readonly reason: L0UnjoinedReason; readonly nodes: readonly string[] }>;
|
|
1617
|
+
}>;
|
|
1618
|
+
readonly storesRead: ReadonlyArray<{
|
|
1619
|
+
readonly name: string;
|
|
1620
|
+
readonly nodeRows: number;
|
|
1621
|
+
readonly skippedRows: number;
|
|
1622
|
+
}>;
|
|
1623
|
+
readonly storesNotQueried: readonly string[];
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
interface ParsedPipelineNodeRow {
|
|
1627
|
+
readonly host: string;
|
|
1628
|
+
readonly node: string;
|
|
1629
|
+
readonly runId?: string;
|
|
1630
|
+
readonly journeyKey?: string;
|
|
1631
|
+
readonly graphId?: string;
|
|
1632
|
+
readonly graphVersion?: string;
|
|
1633
|
+
readonly phase?: string;
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
/** 원장 행(data JSON) → 조인 판정에 필요한 칸. `node` 가 없으면 걸음 행이 아니다. */
|
|
1637
|
+
function parsePipelineNodeRow(host: string, data: string | null): ParsedPipelineNodeRow | null {
|
|
1638
|
+
if (data === null) return null;
|
|
1639
|
+
let parsed: unknown;
|
|
1640
|
+
try { parsed = JSON.parse(data); } catch { return null; }
|
|
1641
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return null;
|
|
1642
|
+
const record = parsed as Record<string, unknown>;
|
|
1643
|
+
if (typeof record.node !== 'string' || record.node.length === 0) return null;
|
|
1644
|
+
const text = (key: string): string | undefined => {
|
|
1645
|
+
const value = record[key];
|
|
1646
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
1647
|
+
};
|
|
1648
|
+
const runId = text('runId');
|
|
1649
|
+
const journeyKey = text('journeyKey');
|
|
1650
|
+
const graphId = text('graphId');
|
|
1651
|
+
const graphVersion = text('graphVersion');
|
|
1652
|
+
const phase = text('phase');
|
|
1653
|
+
return {
|
|
1654
|
+
host,
|
|
1655
|
+
node: record.node,
|
|
1656
|
+
...(runId === undefined ? {} : { runId }),
|
|
1657
|
+
...(journeyKey === undefined ? {} : { journeyKey }),
|
|
1658
|
+
...(graphId === undefined ? {} : { graphId }),
|
|
1659
|
+
...(graphVersion === undefined ? {} : { graphVersion }),
|
|
1660
|
+
...(phase === undefined ? {} : { phase }),
|
|
1661
|
+
};
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
/** null = 이 런/여정의 걸음이다. 그 밖에는 «왜 아닌지» 하나. */
|
|
1665
|
+
function pipelineNodeRowMismatch(
|
|
1666
|
+
template: Pick<GraphTemplate, 'graphId' | 'version'>,
|
|
1667
|
+
key: Pick<JoinedCoverageInput, 'runId' | 'journeyKey'>,
|
|
1668
|
+
row: ParsedPipelineNodeRow,
|
|
1669
|
+
): L0UnjoinedReason | null {
|
|
1670
|
+
if (row.graphId !== undefined && row.graphId !== template.graphId) return 'graph-mismatch';
|
|
1671
|
+
if (row.graphVersion !== undefined && row.graphVersion !== template.version) return 'graph-mismatch';
|
|
1672
|
+
if (row.phase !== undefined && row.phase !== 'journey') return 'phase-mismatch';
|
|
1673
|
+
// ⭐ Pod 자식은 runId 가 다르다 — journeyKey 가 같으면 «같은 여정»이라 붙인다(이 조각의 요점).
|
|
1674
|
+
const byJourney = key.journeyKey !== undefined && row.journeyKey === key.journeyKey;
|
|
1675
|
+
const byRun = key.runId !== undefined && row.runId === key.runId;
|
|
1676
|
+
if (byJourney || byRun) return null;
|
|
1677
|
+
if (key.journeyKey !== undefined && row.journeyKey !== undefined) return 'journey-key-mismatch';
|
|
1678
|
+
if (key.runId !== undefined && row.runId !== undefined) return 'run-id-mismatch';
|
|
1679
|
+
return 'identity-absent';
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
/**
|
|
1683
|
+
* 여러 스토어(부모·Pod)의 `pipeline-node-entry`/`node-skipped` 를 조인 키로 합쳐
|
|
1684
|
+
* 선언·걸음 커버리지를 다시 센다. 런 종료 관측은 건드리지 않는다.
|
|
1685
|
+
*/
|
|
1686
|
+
export function recomputeJoinedL0Coverage(
|
|
1687
|
+
template: GraphTemplate,
|
|
1688
|
+
input: JoinedCoverageInput,
|
|
1689
|
+
measure: L0CoverageMeasure,
|
|
1690
|
+
): JoinedL0Coverage {
|
|
1691
|
+
const nodeRows: ParsedPipelineNodeRow[] = [];
|
|
1692
|
+
const skippedRows: ParsedPipelineNodeRow[] = [];
|
|
1693
|
+
const storesRead: Array<{ name: string; nodeRows: number; skippedRows: number }> = [];
|
|
1694
|
+
for (const store of input.stores) {
|
|
1695
|
+
let nodeRowCount = 0;
|
|
1696
|
+
let skippedRowCount = 0;
|
|
1697
|
+
for (const row of store.rows) {
|
|
1698
|
+
const parsed = parsePipelineNodeRow(store.name, row.data);
|
|
1699
|
+
if (parsed === null) continue;
|
|
1700
|
+
if (row.event === 'pipeline-node-entry') { nodeRows.push(parsed); nodeRowCount += 1; }
|
|
1701
|
+
else if (row.event === 'node-skipped') { skippedRows.push(parsed); skippedRowCount += 1; }
|
|
1702
|
+
}
|
|
1703
|
+
storesRead.push({ name: store.name, nodeRows: nodeRowCount, skippedRows: skippedRowCount });
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
const declaredNodeIds = template.nodes.map((node) => node.nodeId);
|
|
1707
|
+
const enteredHosts = new Map<string, Set<string>>();
|
|
1708
|
+
const unjoined: JoinedCoverageUnjoined[] = [];
|
|
1709
|
+
const unjoinedSeen = new Set<string>();
|
|
1710
|
+
|
|
1711
|
+
for (const nodeId of declaredNodeIds) {
|
|
1712
|
+
const joinedHosts = new Set<string>();
|
|
1713
|
+
for (const row of nodeRows) {
|
|
1714
|
+
if (row.node !== nodeId) continue;
|
|
1715
|
+
const reason = pipelineNodeRowMismatch(template, input, row);
|
|
1716
|
+
if (reason === null) { joinedHosts.add(row.host); continue; }
|
|
1717
|
+
const dedupeKey = `${row.host}\u0000${reason}\u0000${nodeId}`;
|
|
1718
|
+
if (unjoinedSeen.has(dedupeKey)) continue;
|
|
1719
|
+
unjoinedSeen.add(dedupeKey);
|
|
1720
|
+
unjoined.push({ node: nodeId, host: row.host, reason });
|
|
1721
|
+
}
|
|
1722
|
+
if (joinedHosts.size > 0) enteredHosts.set(nodeId, joinedHosts);
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
const unjoinedNodes = new Set(unjoined.map((entry) => entry.node));
|
|
1726
|
+
const joinedNodes = declaredNodeIds
|
|
1727
|
+
.filter((nodeId) => enteredHosts.has(nodeId))
|
|
1728
|
+
.map((nodeId) => ({ node: nodeId, hosts: [...enteredHosts.get(nodeId)!].sort() }));
|
|
1729
|
+
|
|
1730
|
+
const skipped = new Set<string>();
|
|
1731
|
+
for (const row of skippedRows) {
|
|
1732
|
+
if (!declaredNodeIds.includes(row.node)) continue;
|
|
1733
|
+
if (enteredHosts.has(row.node)) continue;
|
|
1734
|
+
if (pipelineNodeRowMismatch(template, input, row) !== null) continue;
|
|
1735
|
+
skipped.add(row.node);
|
|
1736
|
+
}
|
|
1737
|
+
const skippedNodes = [...skipped];
|
|
1738
|
+
|
|
1739
|
+
// ⛔ unobserved 는 «아무도 안 봤다» — joined·skipped·unjoined 중 어디에도 없는 칸에 그대로 남긴다.
|
|
1740
|
+
const unobservedNodes = declaredNodeIds.filter((nodeId) => (
|
|
1741
|
+
!enteredHosts.has(nodeId) && !skipped.has(nodeId) && !unjoinedNodes.has(nodeId)
|
|
1742
|
+
));
|
|
1743
|
+
|
|
1744
|
+
const byHost = new Map<string, Map<L0UnjoinedReason, Set<string>>>();
|
|
1745
|
+
for (const entry of unjoined) {
|
|
1746
|
+
let reasons = byHost.get(entry.host);
|
|
1747
|
+
if (reasons === undefined) { reasons = new Map(); byHost.set(entry.host, reasons); }
|
|
1748
|
+
let nodes = reasons.get(entry.reason);
|
|
1749
|
+
if (nodes === undefined) { nodes = new Set(); reasons.set(entry.reason, nodes); }
|
|
1750
|
+
nodes.add(entry.node);
|
|
1751
|
+
}
|
|
1752
|
+
const unjoinedByHost = [...byHost.entries()]
|
|
1753
|
+
.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
|
|
1754
|
+
.map(([host, reasons]) => ({
|
|
1755
|
+
host,
|
|
1756
|
+
count: [...reasons.values()].reduce((sum, nodes) => sum + nodes.size, 0),
|
|
1757
|
+
reasons: [...reasons.entries()]
|
|
1758
|
+
.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
|
|
1759
|
+
.map(([reason, nodes]) => ({ reason, nodes: [...nodes].sort() })),
|
|
1760
|
+
}));
|
|
1761
|
+
|
|
1762
|
+
const coverage = measure(template, joinedNodes.map(({ node }) => node), skippedNodes);
|
|
1763
|
+
return {
|
|
1764
|
+
...coverage,
|
|
1765
|
+
graphId: template.graphId,
|
|
1766
|
+
graphVersion: template.version,
|
|
1767
|
+
runId: input.runId ?? null,
|
|
1768
|
+
journeyKey: input.journeyKey ?? null,
|
|
1769
|
+
joinedNodes,
|
|
1770
|
+
skippedNodes,
|
|
1771
|
+
unobservedNodes,
|
|
1772
|
+
unjoinedNodes: [...unjoined].sort((a, b) => (
|
|
1773
|
+
a.host < b.host ? -1 : a.host > b.host ? 1 : a.node < b.node ? -1 : a.node > b.node ? 1 : 0
|
|
1774
|
+
)),
|
|
1775
|
+
unjoinedByHost,
|
|
1776
|
+
storesRead,
|
|
1777
|
+
storesNotQueried: input.storesNotQueried ?? [],
|
|
1778
|
+
};
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
/** 사람용 렌더 — 각 수 옆에 «무엇을 셌나»를 붙인다(미관측·미조인·안 읽은 스토어를 접지 않는다). */
|
|
1782
|
+
export function renderJoinedL0Coverage(result: JoinedL0Coverage): string {
|
|
1783
|
+
const ratio = (value: number | null): string => (value === null ? '미측정' : String(value));
|
|
1784
|
+
const lines = [
|
|
1785
|
+
`L0 커버리지 재계산(조인) — ${result.graphId}@${result.graphVersion} · runId=${result.runId ?? '(없음)'} · journeyKey=${result.journeyKey ?? '(없음)'}`,
|
|
1786
|
+
` 선언 커버리지 ${ratio(result.declarationCoverage)} (단계 ${result.declaredStageCount}/${result.listedStageCount})`,
|
|
1787
|
+
` 걸음 커버리지 ${ratio(result.traversalCoverage)} (노드 ${result.accountedNodeCount}/${result.declaredNodeCount} = 조인 ${result.joinedNodes.length} + 건너뜀 ${result.skippedNodes.length} · 미관측 ${result.unobservedNodes.length} 는 세지 않음)`,
|
|
1788
|
+
];
|
|
1789
|
+
if (result.storesRead.length > 0) {
|
|
1790
|
+
lines.push(` 읽은 스토어: ${result.storesRead.map((store) => `${store.name}(걸음 ${store.nodeRows}·건너뜀 ${store.skippedRows})`).join(' · ')}`);
|
|
1791
|
+
}
|
|
1792
|
+
if (result.joinedNodes.length > 0) {
|
|
1793
|
+
lines.push(` 조인된 노드 ${result.joinedNodes.length}개: ${result.joinedNodes.map(({ node, hosts }) => `${node}⟨${hosts.join('·')}⟩`).join(' ')}`);
|
|
1794
|
+
}
|
|
1795
|
+
if (result.skippedNodes.length > 0) {
|
|
1796
|
+
lines.push(` 건너뜀(조건 거짓 · 관측 판정) ${result.skippedNodes.length}개: ${result.skippedNodes.join(', ')}`);
|
|
1797
|
+
}
|
|
1798
|
+
if (result.unobservedNodes.length > 0) {
|
|
1799
|
+
lines.push(` ⛔ 미관측 ${result.unobservedNodes.length}개 — 건너뜀도 0도 아니다(아무도 안 봤다 · 읽은 스토어 원장에 이 런/여정 걸음이 없다): ${result.unobservedNodes.join(', ')}`);
|
|
1800
|
+
}
|
|
1801
|
+
for (const bucket of result.unjoinedByHost) {
|
|
1802
|
+
lines.push(` 미조인 ${bucket.host} ${bucket.count}개: ${bucket.reasons.map(({ reason, nodes }) => `${reason}=${nodes.join(',')}`).join(' · ')}`);
|
|
1803
|
+
}
|
|
1804
|
+
if (result.storesNotQueried.length > 0) {
|
|
1805
|
+
lines.push(` ⚠ 안 읽은 스토어 ${result.storesNotQueried.length}개: ${result.storesNotQueried.join(', ')} — 위 수는 «읽은 스토어 안에서만» 센 값이다(전체 미조인 수는 더 클 수 있다).`);
|
|
1806
|
+
}
|
|
1807
|
+
return lines.join('\n');
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
/** `--recompute` 조회 — 열린 스토어들의 걸음 이벤트 행을 «전부» 모아 조인 계층이 이 런/여정인지 판정하게 넘긴다. */
|
|
1811
|
+
async function runLogsCoverageRecompute(
|
|
1812
|
+
opts: LogsCliOpts,
|
|
1813
|
+
opened: ReadonlyArray<{ name: string; store: LogStore }>,
|
|
1814
|
+
storesNotQueried: readonly string[],
|
|
1815
|
+
): Promise<number> {
|
|
1816
|
+
const runId = opts.run?.trim() || undefined;
|
|
1817
|
+
const journeyKey = opts.journey?.trim() || undefined;
|
|
1818
|
+
const closeAll = (): void => { for (const { store } of opened) store.close(); };
|
|
1819
|
+
if (runId === undefined && journeyKey === undefined) {
|
|
1820
|
+
console.error('elanous logs: --recompute 는 조인 키가 필요하다 — --run <runId> 또는 --journey <journeyKey>');
|
|
1821
|
+
closeAll();
|
|
1822
|
+
return 1;
|
|
1823
|
+
}
|
|
1824
|
+
const graphId = opts.graph?.trim() || 'self-implement';
|
|
1825
|
+
// 동적 import — typescript 를 무는 모듈이라 «재계산 경로에서만» 싣는다(기본 조회 무회귀).
|
|
1826
|
+
const { GRAPH_TEMPLATES, measureL0Coverage } = await import('../self-implement/graph-templates.js');
|
|
1827
|
+
const template = GRAPH_TEMPLATES[graphId];
|
|
1828
|
+
if (template === undefined) {
|
|
1829
|
+
console.error(`elanous logs: --graph '${graphId}' 는 선언된 그래프가 아니다 (선언: ${Object.keys(GRAPH_TEMPLATES).join(', ')})`);
|
|
1830
|
+
closeAll();
|
|
1831
|
+
return 1;
|
|
1832
|
+
}
|
|
1833
|
+
// ⛔ 조회 단계에서 조인 키로 미리 거르지 않는다(`grep: runId|journeyKey` 사전필터 금지).
|
|
1834
|
+
// 미리 거르면 열린 스토어 안의 «다른 여정» 걸음 행이 조인 계층에 도달하지 못해,
|
|
1835
|
+
// `journey-key-mismatch` 로 잡혀야 할 선언 노드가 «아무도 안 봤다(unobserved)» 로 오분류된다.
|
|
1836
|
+
// ⇒ 이벤트 필터(`pipeline-node-entry`/`node-skipped`)로만 읽고 «내 것인가» 판정은 조인 계층에 전부 맡긴다.
|
|
1837
|
+
const stores: JoinedCoverageStore[] = [];
|
|
1838
|
+
const unreadable: string[] = [];
|
|
1839
|
+
for (const { name, store } of opened) {
|
|
1840
|
+
const rows: JoinedCoverageRow[] = [];
|
|
1841
|
+
try {
|
|
1842
|
+
for (const row of store.queryAll({ events: ['pipeline-node-entry', 'node-skipped'] })) {
|
|
1843
|
+
rows.push({ event: row.event, data: row.data });
|
|
1844
|
+
}
|
|
1845
|
+
} catch (error) {
|
|
1846
|
+
unreadable.push(name);
|
|
1847
|
+
console.error(`elanous logs: ${name} 조회 실패 — ${error instanceof Error ? error.message : String(error)}`);
|
|
1848
|
+
}
|
|
1849
|
+
stores.push({ name, rows });
|
|
1850
|
+
}
|
|
1851
|
+
const result = recomputeJoinedL0Coverage(template, {
|
|
1852
|
+
...(runId === undefined ? {} : { runId }),
|
|
1853
|
+
...(journeyKey === undefined ? {} : { journeyKey }),
|
|
1854
|
+
stores,
|
|
1855
|
+
storesNotQueried: [...storesNotQueried, ...unreadable],
|
|
1856
|
+
}, measureL0Coverage);
|
|
1857
|
+
if (opts.json) {
|
|
1858
|
+
console.log(JSON.stringify({ _meta: { type: 'log-query-l0-coverage-recomputed' }, ...result }));
|
|
1859
|
+
} else {
|
|
1860
|
+
console.log(renderJoinedL0Coverage(result));
|
|
1861
|
+
}
|
|
1862
|
+
closeAll();
|
|
1863
|
+
return unreadable.length > 0 ? 2 : 0;
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1525
1866
|
/** 조회 또는 follow. follow 는 Ctrl-C 까지 블록. 복수 타겟(--all)은 ts 병합. */
|
|
1526
1867
|
export async function runLogsCli(opts: LogsCliOpts, deps: RunLogsCliDeps = {}): Promise<number> {
|
|
1527
1868
|
const remoteFlag = resolveLogsRemoteFlag(opts);
|
|
1528
1869
|
if (remoteFlag !== undefined) {
|
|
1529
1870
|
if (opts.topFailures) { console.error('elanous logs: --top-failures 는 로컬 스토어 조회에서만 지원'); return 1; }
|
|
1871
|
+
// 조인 재계산은 «여러 스토어의 원장 행»을 합치는 일이다 — 원격 한 번 조회로는 성립하지 않는다.
|
|
1872
|
+
if (opts.recompute) { console.error('elanous logs: --recompute 는 로컬 스토어에서만 지원 — 원격은 로컬 원장을 못 본다'); return 1; }
|
|
1530
1873
|
return runLogsCliRemote(opts, remoteFlag, deps);
|
|
1531
1874
|
}
|
|
1532
1875
|
if (opts.topFailures && opts.follow) { console.error('elanous logs: --top-failures 는 --follow 와 함께 쓸 수 없다'); return 1; }
|
|
1876
|
+
// 한 번의 조인 재계산은 «한 시점의 스냅숏»이다 — follow 와 섞으면 폴마다 다른 답을 낸다.
|
|
1877
|
+
if (opts.recompute && opts.follow) { console.error('elanous logs: --recompute 는 --follow 와 함께 쓸 수 없다'); return 1; }
|
|
1533
1878
|
const threshold = opts.threshold === undefined ? 20 : Number(opts.threshold);
|
|
1534
1879
|
if (opts.topFailures && (!Number.isSafeInteger(threshold) || threshold < 1)) {
|
|
1535
1880
|
console.error('elanous logs: --threshold 는 양의 정수여야 한다'); return 1;
|
|
@@ -1548,10 +1893,12 @@ export async function runLogsCli(opts: LogsCliOpts, deps: RunLogsCliDeps = {}):
|
|
|
1548
1893
|
// read-only open — 타겟이 어느 인스턴스든 CLI 조회는 write 0 (연합 불변식).
|
|
1549
1894
|
const opened: Array<{ name: string; store: LogStore }> = [];
|
|
1550
1895
|
const missing: string[] = [];
|
|
1896
|
+
/** 열지 못한 타겟 이름 — 조인 재계산이 «못 본 우주»를 0 으로 접지 않게 그대로 넘긴다. */
|
|
1897
|
+
const missingNames: string[] = [];
|
|
1551
1898
|
for (const t of resolved.targets) {
|
|
1552
|
-
if (!existsSync(t.dbPath)) { missing.push(`${t.name} (${t.dbPath})`); continue; }
|
|
1899
|
+
if (!existsSync(t.dbPath)) { missing.push(`${t.name} (${t.dbPath})`); missingNames.push(t.name); continue; }
|
|
1553
1900
|
try { opened.push({ name: t.name, store: LogStore.openReadOnly(t.dbPath) }); }
|
|
1554
|
-
catch { missing.push(`${t.name} (${t.dbPath} — open 실패)`); }
|
|
1901
|
+
catch { missing.push(`${t.name} (${t.dbPath} — open 실패)`); missingNames.push(t.name); }
|
|
1555
1902
|
}
|
|
1556
1903
|
const openedStores = opened.map(({ name, store }) => ({ name, path: store.path }));
|
|
1557
1904
|
// 등록된 존재 DB의 고유 경로가 조회 가능 모집단이다. 선택 규칙은 건드리지 않고,
|
|
@@ -1589,6 +1936,8 @@ export async function runLogsCli(opts: LogsCliOpts, deps: RunLogsCliDeps = {}):
|
|
|
1589
1936
|
return 1;
|
|
1590
1937
|
}
|
|
1591
1938
|
if (missing.length > 0) console.error(`elanous logs: 스킵 — ${missing.join(' · ')}`);
|
|
1939
|
+
// ⭐ 런 종료 «이후» 조인 재계산 — 별도 표시 모드다(기본 조회·런 종료 관측·원장 형식 무변경).
|
|
1940
|
+
if (opts.recompute === true) return runLogsCoverageRecompute(opts, opened, missingNames);
|
|
1592
1941
|
if (opts.topFailures) {
|
|
1593
1942
|
const rows: LogStoreRow[] = [];
|
|
1594
1943
|
const unreadable: string[] = [];
|
|
@@ -2041,6 +2390,12 @@ const logsCmd = program.command('logs')
|
|
|
2041
2390
|
.option('--instance <name>', '레지스트리 등록 인스턴스 타겟 (prod|test:<repo>|…)')
|
|
2042
2391
|
.option('--all', '전 인스턴스 연합 조회 — read-only 병합·⟨instance⟩ 태그')
|
|
2043
2392
|
.option('--include-test', '--all 연합에 격리 test 인스턴스도 포함(기본 제외)')
|
|
2393
|
+
// ⭐ ARG-L0-COVER — 런이 «끝난 뒤» 부모·Pod 스토어의 걸음을 journeyKey/runId 로 합쳐 다시 센다.
|
|
2394
|
+
// ⛔ 런 종료 관측(`l0-coverage`)을 덮어쓰지 않는다 — 조회 시점의 별도 표시다.
|
|
2395
|
+
.option('--recompute', '열린 스토어들(부모·Pod)의 pipeline-node-entry 로 L0 커버리지를 다시 조인 계산 (--run 또는 --journey 필요)')
|
|
2396
|
+
.option('--run <id>', '--recompute 조인 키: runId')
|
|
2397
|
+
.option('--journey <key>', '--recompute 조인 키: journeyKey (Pod 자식이 물려받은 키)')
|
|
2398
|
+
.option('--graph <id>', '--recompute 대상 그래프 (기본 self-implement)')
|
|
2044
2399
|
// ⛔ `-r` 은 값을 받지 않는다 — default 북마크만. 이름은 `--remote <name>` 으로만 준다.
|
|
2045
2400
|
.option('-r', 'query logs on the default remote bookmark (does not take a value)')
|
|
2046
2401
|
.option('--remote <name>', 'query logs on a named remote bookmark via GET /v1/logs')
|
package/src/cli/memory-cli.ts
CHANGED
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
readIndex, memoryRoot, memoryIndexPath,
|
|
11
11
|
type MemoryType,
|
|
12
12
|
} from '../memory.js';
|
|
13
|
+
import { applyClaudeMemoryImport, claudeMemoryRoot, collectClaudeMemoryFiles } from '../context-bus/claude-memory-import.js';
|
|
14
|
+
import { importClaudeMemories } from '../context-bus/long-term-memory.js';
|
|
13
15
|
|
|
14
16
|
export function registerMemoryCommands(program: Command): void {
|
|
15
17
|
const memCmd = program.command('memory').description('Persistent memories injected into every chat turn (user / feedback / project / reference)');
|
|
@@ -179,4 +181,31 @@ export function registerMemoryCommands(program: Command): void {
|
|
|
179
181
|
console.log(`memory dir ${memoryRoot()}`);
|
|
180
182
|
console.log(`index file ${memoryIndexPath()}`);
|
|
181
183
|
});
|
|
182
|
-
|
|
184
|
+
|
|
185
|
+
// 대표 10-12 MEMORY-IMPORT-CLAUDE — Claude 자동 기억(~/.claude/projects/*/memory)을 엘라누스
|
|
186
|
+
// 장기 기억으로 가져온다. 에이전트 무관 — codex·elanous TUI 가 같은 기억을 바로 읽는다.
|
|
187
|
+
memCmd
|
|
188
|
+
.command('import-claude')
|
|
189
|
+
.description('Import Claude auto-memories (~/.claude/projects/*/memory) into elanous memories — same name overwrites')
|
|
190
|
+
.option('--root <path>', 'projects root or a single memory dir', claudeMemoryRoot())
|
|
191
|
+
.option('--as-of <date>', 'staleness basis «MM-DD 기준» (default: today)')
|
|
192
|
+
.option('--dry-run', 'preview without saving')
|
|
193
|
+
.action((opts: { root: string; asOf?: string; dryRun?: boolean }) => {
|
|
194
|
+
const asOf = opts.asOf ?? new Date().toISOString().slice(0, 10);
|
|
195
|
+
const files = collectClaudeMemoryFiles(opts.root);
|
|
196
|
+
if (opts.dryRun) {
|
|
197
|
+
const preview = importClaudeMemories(files, { asOf });
|
|
198
|
+
ui.header(`claude-memory (dry-run) ${files.length} files`);
|
|
199
|
+
for (const item of preview.items) console.log(` [${item.type.padEnd(9)}] ${item.name} ${item.summary}`);
|
|
200
|
+
if (preview.overwritten) console.log(` overwritten ${preview.overwritten}`);
|
|
201
|
+
for (const [reason, count] of Object.entries(preview.skipped)) console.log(` skipped ${reason}:${count}`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const result = applyClaudeMemoryImport(files, { asOf }, {
|
|
205
|
+
list: () => listMemories().map(entry => ({ id: entry.id, name: entry.name })),
|
|
206
|
+
save: record => { saveMemory(record); },
|
|
207
|
+
});
|
|
208
|
+
ui.info(`claude-memory: ${result.saved} new · ${result.updated} overwritten · ${result.items.length} imported (${files.length} files from ${opts.root})`);
|
|
209
|
+
for (const [reason, count] of Object.entries(result.skipped)) ui.info(` skipped ${reason}:${count}`);
|
|
210
|
+
});
|
|
211
|
+
}
|