elanous 0.2.24 → 0.2.25
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/chunks/1027.a0f04663d24c2779.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +1 -0
- package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +36 -0
- package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +148 -0
- package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1454-37fd16f479f5554a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8532.a86e99acf9b761cb.js → 1516.83dd2c1b86b4e507.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{89849432.9eaa2f4c9c010965.js → 16e57f67.3ea19e893461e611.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1505.5826671109111e75.js → 1743.563d3168e95825ef.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +24 -0
- package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +32 -0
- package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2846.d6a433b8663819a5.js +309 -0
- package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{5967-c0a80f8ffe5d4050.js → 3259-86f3be56e43eaf6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +287 -0
- package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5578.ac963634373b28c6.js → 4084.15ecaf4240bd9e77.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8438.ee7f0df3b3f6fcb4.js → 4204.a409ab6250c0f6a8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +8 -0
- package/apps/pwa/out/_next/static/chunks/4565-67e4c620597965c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7905.b230b9d06cb4ad5d.js → 4593.10f5b9bd702d4a6c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +104 -0
- package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +149 -0
- package/apps/pwa/out/_next/static/chunks/{8569.b853a8daa8f31d12.js → 5081.a240b63fad28663a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2528.0af5c0e1fad88df6.js → 5408.377c8c543635b81f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9502-32c5dc22e8f120f5.js → 5492-e05e26a033ba80d2.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/5785-ea8d2c633b6688e3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/599-a914cc0468f56143.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +23 -0
- package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5974.360f8441eb0ac1ec.js → 6196.34d6b229079e9e28.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +77 -0
- package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +64 -0
- package/apps/pwa/out/_next/static/chunks/{ce383d63.d2ede338788ed18e.js → 65ebff95.081daeff622d238e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +2 -0
- package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{83cfc5c8.349535543c1548b6.js → 6def8a8e.c81f9ca41028eccf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2721.bc9a8f36bd85c07a.js → 7483.ba01c6c209b81bba.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{6702.ebbd165d5e4a4a14.js → 7752.5cbdd0b433c54af9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8925-2abfb48af477fb7f.js → 8085-1e5fce59500a2cc2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{b4e12462-5fab4a813a63dadd.js → 83a80514-b897b64df43ce108.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +93 -0
- package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{8264.00e434fbd02e9311.js → 8578.dff22d988cc2b106.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +115 -0
- package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +41 -0
- package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +74 -0
- package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7518.49161e8f5814abdb.js → 9311.24c8f5ea793253dd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9976.8f28864317639fe6.js → 94.4cfed21c0b781a06.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +90 -0
- package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{0e3acd34.d42b2ef87fdf4234.js → 973cbf1b.3bbcf2b41548eca7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6571-926ddf024a6ad5df.js → 9917-9e26abc5f7772735.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +79 -0
- package/apps/pwa/out/_next/static/chunks/{740.90b31555290236a9.js → 9974.e77b4ff4884557b3.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{4c5e95ce.83e9b16add6fcd8c.js → ab4d57c2.e90bc2cb31949045.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-9360b1285b2a346e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f08f6529d09ffae1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-f000d54d258f9ef6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-24282bf9f90031a5.js → page-b12149c51f7d04b1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-22f674e7e4c2c9d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8888733e40cea6d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-9717ec6964b92276.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-44eaad486bc98a45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-97fa6cf3d34c7eb9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-305cd294e754906e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-dea4b795741126fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-35e05d7450461a67.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-45889e7070d11126.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-16a2e893f83ae4d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-b2638013c0bf7dfd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-56888bc744e08dac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-c44f93a41167536f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-952c6ceec6d9de38.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-6d0202af568f4c63.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-1b810474507f3702.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-74366ae2693a7d95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-4fb6fc34e20c07b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-e9502921f4f01b1f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-b6169ea2f09cf287.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6a14333d1b1b3967.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8c91a9a66c9ec90a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-1d809a87139dd024.js → page-4e634c5b98fd4e93.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ed3070d637850548.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/{page-b92caddb5c715f30.js → page-b9cc8a10bc6078b4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/page-3d3fc73dd187ed52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-128458c8d86fbb5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9c04dac0831c2bbb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-cf0c2b0183991d09.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-04de9ca6d52a3893.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-62527677bbc2fdc4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9a2e09c4a311764c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-bfeb35d69e8b24bb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-89cb33bced824e4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-b008aff96be56654.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-814394dcbae789b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-6a87325c87f09dd2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-6445ac4cbb8dd869.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-852170303c6cd755.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-087ceeb975ef272b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-97c7361cc2a19319.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-20162174b77f96cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-8c6901833f897496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-05a4b2c9b91034aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{53746282.1be36038d1abd949.js → e117f801.e92bf10242653497.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{0673cc54.8e2ef1c23e49e190.js → f4dfbfc0.a69fb12f854882aa.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +1 -0
- package/apps/pwa/out/_next/static/{Q-7iofoxOEv1WX18S35of → dRS6lEhSRRBr1abbzp7fJ}/_buildManifest.js +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/graphs/release/release-loop.yaml +5 -5
- package/graphs/steward/recipes.yaml +4 -0
- package/graphs/steward/steward.yaml +10 -1
- package/package.json +1 -1
- package/scripts/bench-report.ts +46 -1
- package/scripts/ci-typecheck-changed.ts +7 -5
- package/scripts/release-loop/auto-approve-node.ts +6 -0
- package/scripts/release-loop/gate-closure.ts +286 -0
- package/scripts/release-loop/gate-node.ts +73 -13
- package/scripts/release-loop/gate-partial.ts +34 -6
- package/scripts/release-loop/ops-upgrade-node.ts +63 -42
- package/scripts/release-loop/publish-node.ts +6 -0
- package/scripts/release-loop/resume-release.ts +37 -10
- package/scripts/release-loop/resume.ts +69 -4
- package/scripts/tsc-baseline-cache.ts +28 -3
- package/scripts/usage-rollup.ts +27 -13
- package/scripts/ux-sim.ts +30 -1
- package/skills/youtube-master/scripts/main.ts +4 -1
- package/skills/youtube-master/src/obsidian.ts +9 -0
- package/src/agent-substrate/acp-implementer.ts +14 -7
- package/src/agent-substrate/pr-reviewer.ts +30 -10
- package/src/agent-substrate/self-review-cli.ts +126 -10
- package/src/budget/cost-tier-advisor.ts +91 -0
- package/src/budget/shadow-arms.ts +77 -0
- package/src/budget/types.ts +5 -3
- package/src/budget/unified-usage.ts +172 -8
- package/src/cli/doctor-cli.ts +21 -0
- package/src/cli/friendly-errors.ts +113 -0
- package/src/cli/intake-cli.ts +3 -1
- package/src/cli/memory-cli.ts +182 -0
- package/src/cli/model-watch-cli.ts +4 -1
- package/src/cli/pr-land-pod-shadow.ts +54 -0
- package/src/cli/release-cli.ts +9 -7
- package/src/cli/release-run-if-ready.ts +11 -0
- package/src/cli/resource-cli.ts +48 -0
- package/src/cli/retro-cli.ts +12 -3
- package/src/cli/seat-requests-cli.ts +25 -0
- package/src/cli/tasks-cli.ts +31 -7
- package/src/cli/usage-cli.ts +3 -1
- package/src/compact/verify-probe.ts +23 -3
- package/src/context-card/index.ts +50 -0
- package/src/control/control-status.ts +30 -1
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +4 -138
- package/src/dashboard/slash-runtime/shell-slash.ts +145 -0
- package/src/debug/log-diet.ts +16 -4
- package/src/domains/morning-essential.ts +18 -3
- package/src/domains/release-tool.ts +4 -0
- package/src/execution-loop/launch-gate.ts +158 -2
- package/src/fleet/host-doctor.ts +375 -0
- package/src/goals/judge.ts +20 -6
- package/src/graph-runner/runner.ts +9 -5
- package/src/graph-wizard/archetypes.ts +14 -8
- package/src/graph-wizard/generate.ts +77 -1
- package/src/grok.ts +13 -7
- package/src/harness/harness-cli-command.ts +56 -47
- package/src/harness/harness-stop.ts +82 -12
- package/src/index.ts +17 -175
- package/src/intake-plane/collect-github.ts +7 -2
- package/src/intake-plane/lens.ts +46 -4
- package/src/intake-plane/requirement-funnel.ts +53 -1
- package/src/intelligence-map/catalog-feed.ts +119 -0
- package/src/intelligence-map/model-watch-intake.ts +40 -0
- package/src/intelligence-map/model-watch-mission.ts +14 -1
- package/src/llm/open-weight-discipline.ts +21 -0
- package/src/llm.ts +4 -8
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/nexus/api/http-server.ts +22 -0
- package/src/oauth/codex-account-rotation.ts +4 -1
- package/src/oauth/codex-account-store.ts +20 -7
- package/src/oauth/codex-quota-policy.ts +33 -4
- package/src/preview/terminal.ts +15 -5
- package/src/project/project-store.ts +20 -0
- package/src/release-loop/auto-start.ts +7 -5
- package/src/release-loop/checklist.ts +11 -1
- package/src/release-loop/gate-shards.ts +4 -0
- package/src/release-loop/light-rc.ts +84 -13
- package/src/release-loop/merged-pr-checklist.ts +35 -5
- package/src/release-loop/rehearsal.ts +1 -1
- package/src/seat-loop/duty-ledger.ts +64 -0
- package/src/self-dev/decompose.ts +37 -3
- package/src/self-dev/dev-pipeline.ts +32 -7
- package/src/self-dev/draft-residue.ts +16 -6
- package/src/self-dev/draft-sweep.ts +52 -4
- package/src/self-dev/fabric-decompose-adapter.ts +9 -2
- package/src/self-dev/run-supervisor.ts +37 -7
- package/src/self-implement/gate-cli.ts +29 -10
- package/src/self-implement/gate-remote.ts +4 -1
- package/src/self-implement/goal-author.ts +12 -2
- package/src/self-implement/goal-new-paths.ts +42 -0
- package/src/self-implement/host-regate.ts +124 -30
- package/src/self-implement/importer-test-index.ts +3 -1
- package/src/self-implement/l8-merge-queue.ts +80 -2
- package/src/self-implement/merge-train.ts +19 -0
- package/src/self-implement/off-diff-evidence.ts +40 -1
- package/src/self-implement/orchestrator.ts +88 -19
- package/src/self-implement/premise-review.ts +159 -0
- package/src/self-implement/regate-detail.ts +79 -0
- package/src/self-implement/review-deferred-to-host.ts +21 -0
- package/src/self-implement/rework-budget-judgment.ts +23 -3
- package/src/self-implement/running-runs.ts +2 -2
- package/src/self-implement/scope-adjacency.ts +23 -0
- package/src/self-implement/seams.ts +42 -7
- package/src/skills/tools/agent.ts +16 -1
- package/src/skills/tools/persistent-grounding.ts +11 -1
- package/src/skills/tools/shell.ts +33 -1
- package/src/steward/rejudge-tick.ts +142 -0
- package/src/task-agent/board.ts +92 -3
- package/src/task-agent/card-evidence.ts +88 -1
- package/src/task-agent/cover.ts +65 -0
- package/src/task-agent/parent-host.ts +27 -3
- package/src/task-agent/rejudge-on-head.ts +151 -7
- package/src/task-agent/review-result-capture.ts +3 -1
- package/src/task-agent/shadow.ts +12 -0
- package/src/task-agent/task-hand.ts +4 -1
- package/src/task-orchestrator/surfaces/pod-command-job.ts +14 -0
- package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +122 -0
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +23 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +53 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +235 -28
- package/src/user-config.ts +18 -4
- package/src/ux-sim/fault-cred-expiry.ts +100 -0
- package/src/ux-sim/fault-pod-death.ts +74 -0
- package/src/ux-sim/fault-pool-cap.ts +81 -0
- package/src/version/packed-revision.json +1 -1
- package/src/webclone/qa-table.ts +22 -0
- package/apps/pwa/out/_next/static/chunks/0a09e062-34f747a17d8d8c2e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +0 -77
- package/apps/pwa/out/_next/static/chunks/1325-dc3f3c21eb181cb4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +0 -34
- package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1669-da843ed73aa301f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +0 -36
- package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +0 -122
- package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/272-0eed0fb0aab716b6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +0 -149
- package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3961-aaae04ed1d32622f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +0 -309
- package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5313.1697309c532b9856.js +0 -2
- package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +0 -74
- package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +0 -64
- package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +0 -93
- package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +0 -148
- package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +0 -226
- package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +0 -27
- package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +0 -115
- package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +0 -8
- package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +0 -23
- package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +0 -90
- package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +0 -94
- package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +0 -41
- package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +0 -287
- package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +0 -79
- package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +0 -104
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-3b9fc39362473ae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f2b62c19ca68fef8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-d7602d489edf5f37.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-8b7c5ab6b5bc8d64.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-4eb84d454f8c3415.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-b2e494bdad57fcb5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-c0ab229673a8b0eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-3e2b45f3c36dbac4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-c22aa511b28743ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-26345242e4049f55.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-bf88c0f558d8ef54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-52fec523e5b5d3ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-67723dfdcde92b31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-22725e2570f1126b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-1891335950d68b70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-3267af1ebdc73cf5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-c314b75c11234998.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-9f9c85415f61782b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-c1d4276059085587.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-833aab587f26ad4c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8526c17ae38e6a50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-f998637a8402115c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-b7bb53828b17b335.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-1b1850de0257e46d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6f23159fedb41f67.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-da9e570234d481fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-8ce3a38e210b810a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-57ffeeb6019440fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-abbb417bf514630b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2c2b3f29cec1efa4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-9369279f72fc7b51.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-64861f14039499c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ddc4c93efd8ab94b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-901a1391b81053bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-68d9bbaac9841a58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-b5c0c996f329371e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-89881ccbcf728978.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-0e87a803b3d7165e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-58d4e5cb30ef4871.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-02ce4c3b5f39e4d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-e620d1bb8eadcec2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-acf868c64d77f950.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-54fa605fa6dba457.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-bc79f0833533fa84.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d5c4398eea03d8f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-b2763b10dc6b3836.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +0 -1
- /package/apps/pwa/out/_next/static/{Q-7iofoxOEv1WX18S35of → dRS6lEhSRRBr1abbzp7fJ}/_ssgManifest.js +0 -0
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
// Codex: enumerate known account names, fetch each via the existing
|
|
4
4
|
// ProviderFetcher with CODEX_HOME on the child env only.
|
|
5
5
|
// Grok: this wiring has no multi-account list — 0 or 1 current-credential row.
|
|
6
|
-
// Claude
|
|
6
|
+
// Claude Code (2026-10-11 CLAUDE-USAGE-WINDOW): subscription row — 5-hour window
|
|
7
|
+
// (credits axis) + 7-day window (subscription axis), from the OAuth usage endpoint.
|
|
8
|
+
// Gemini is intentionally out of this landing.
|
|
7
9
|
|
|
8
10
|
import { createCodexFetcher, type CodexFetcherOpts } from './fetchers/codex.js';
|
|
11
|
+
import { createClaudeFetcher, resolveClaudeAccessToken } from './fetchers/claude.js';
|
|
9
12
|
import {
|
|
10
13
|
fetchGrokUsage,
|
|
11
14
|
GROK_SUBSCRIPTION_AXIS,
|
|
@@ -20,6 +23,7 @@ import { loadTokens } from '../oauth/store.js';
|
|
|
20
23
|
import { envLiteral } from '../platform/env-literal.js';
|
|
21
24
|
import { describeResetCreditExpiry } from './codex-reset-credit-state.js';
|
|
22
25
|
import { visibleWidth } from '../tui.js';
|
|
26
|
+
import { debug } from '../debug/log.js';
|
|
23
27
|
import { listCodexResetCredits, type CodexResetCreditsResult } from './codex-reset-credits.js';
|
|
24
28
|
import {
|
|
25
29
|
buildZaiUsageView, fetchZaiQuota, getZaiApiKey, readZaiLedger,
|
|
@@ -28,6 +32,7 @@ import {
|
|
|
28
32
|
import type {
|
|
29
33
|
AccountUsageRow,
|
|
30
34
|
CreditAxis,
|
|
35
|
+
RateWindow,
|
|
31
36
|
ResetCreditExpiryAxis,
|
|
32
37
|
SubscriptionAxis,
|
|
33
38
|
UnifiedUsageReport,
|
|
@@ -59,25 +64,179 @@ export interface UnifiedUsageDeps {
|
|
|
59
64
|
readonly zaiKey?: () => string | undefined;
|
|
60
65
|
readonly fetchZaiQuota?: () => Promise<ZaiQuotaResult>;
|
|
61
66
|
readonly readZaiLedger?: () => ZaiLedgerRecord[];
|
|
67
|
+
/** Claude Code OAuth 토큰 해석 심 — 없으면 조회를 안 탄다(토큰 없음 = 행 없음). */
|
|
68
|
+
readonly resolveClaudeToken?: () => string | null;
|
|
69
|
+
/** Claude 사용량 조회 심 — `createClaudeFetcher().fetch()` 모양. */
|
|
70
|
+
readonly fetchClaude?: () => Promise<UsageSnapshot>;
|
|
71
|
+
/** 캐시 «아래»의 원 조회 심 — 주면 15분/5분 캐시를 거친다(`fetchClaude` 는 캐시를 우회한다). */
|
|
72
|
+
readonly fetchClaudeUncached?: () => Promise<UsageSnapshot>;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** 공급자별 실패 격리(2026-10-11) — collector 가 «try 밖에서» 던지면 그 공급자만 한 error 행으로 바꾼다.
|
|
76
|
+
* ⛔ 종전 `Promise.all` 은 한 공급자의 예외(예: 키 조회 seam throw)가 usage «전체» 를 죽였다.
|
|
77
|
+
* `allSettled` 로 바꾸고 rejected 는 여기서 한 행으로 접는다 — 다른 공급자 행은 그대로 산다. */
|
|
78
|
+
type ZaiOutcome = { rows: AccountUsageRow[]; view: ZaiUsageView };
|
|
79
|
+
|
|
80
|
+
function isolateProviderRows(
|
|
81
|
+
provider: AccountUsageRow['provider'],
|
|
82
|
+
settled: PromiseSettledResult<AccountUsageRow[] | ZaiOutcome | null>,
|
|
83
|
+
): { rows: AccountUsageRow[]; zai: ZaiOutcome | null } {
|
|
84
|
+
if (settled.status === 'fulfilled') {
|
|
85
|
+
const value = settled.value;
|
|
86
|
+
if (value === null) return { rows: [], zai: null };
|
|
87
|
+
if (Array.isArray(value)) return { rows: value, zai: null };
|
|
88
|
+
return { rows: value.rows, zai: value };
|
|
89
|
+
}
|
|
90
|
+
const detail = settled.reason instanceof Error ? settled.reason.message : String(settled.reason);
|
|
91
|
+
debug.log('usage', 'provider-failed', { provider, detail });
|
|
92
|
+
return {
|
|
93
|
+
rows: [{
|
|
94
|
+
provider,
|
|
95
|
+
accountName: 'default',
|
|
96
|
+
accountCount: 1,
|
|
97
|
+
soleAccount: true,
|
|
98
|
+
credits: { status: 'error', detail },
|
|
99
|
+
subscription: { status: 'unavailable', reason: 'query-does-not-supply' },
|
|
100
|
+
resetCredits: { status: 'unavailable', detail },
|
|
101
|
+
}],
|
|
102
|
+
zai: null,
|
|
103
|
+
};
|
|
62
104
|
}
|
|
63
105
|
|
|
64
106
|
export async function collectUnifiedUsage(deps: UnifiedUsageDeps = {}): Promise<UnifiedUsageReport> {
|
|
65
|
-
const [
|
|
107
|
+
const [codexSettled, claudeSettled, grokSettled, openRouterSettled, zaiSettled] = await Promise.allSettled([
|
|
66
108
|
collectCodexRows(deps),
|
|
109
|
+
collectClaudeRows(deps),
|
|
67
110
|
collectGrokRows(deps),
|
|
68
111
|
collectOpenRouterRows(deps),
|
|
69
112
|
collectZaiRows(deps),
|
|
70
113
|
]);
|
|
114
|
+
const codex = isolateProviderRows('codex', codexSettled);
|
|
115
|
+
const claude = isolateProviderRows('claude', claudeSettled);
|
|
116
|
+
const grok = isolateProviderRows('grok', grokSettled);
|
|
117
|
+
const openRouter = isolateProviderRows('openrouter', openRouterSettled);
|
|
118
|
+
const zai = isolateProviderRows('zai', zaiSettled);
|
|
119
|
+
const zaiRows = zai.zai?.rows ?? zai.rows;
|
|
71
120
|
return {
|
|
72
|
-
rows: [...
|
|
121
|
+
rows: [...codex.rows, ...claude.rows, ...grok.rows, ...openRouter.rows, ...zaiRows],
|
|
73
122
|
accountCounts: {
|
|
74
|
-
codex:
|
|
75
|
-
grok:
|
|
76
|
-
openrouter:
|
|
123
|
+
codex: codex.rows.length,
|
|
124
|
+
grok: grok.rows.length,
|
|
125
|
+
openrouter: openRouter.rows.length,
|
|
126
|
+
// ⛔ claude 도 토큰이 없으면(행 0) 칸을 안 싣는다 — 종전 JSON·문면과 바이트 동일(0행 ≠ 0% 사용).
|
|
127
|
+
...(claude.rows.length > 0 ? { claude: claude.rows.length } : {}),
|
|
77
128
|
// ⛔ 키가 없으면 칸 자체를 안 싣는다 — 종전 JSON·문면과 바이트 동일.
|
|
78
|
-
|
|
129
|
+
// 종전과 같게: 조회가 성공했으면(창이 비어도) zai 1 · 실패해 error 행만 남았어도 1(실패 행도 센다).
|
|
130
|
+
...(zai.zai || zai.rows.length > 0 ? { zai: 1 } : {}),
|
|
79
131
|
},
|
|
80
|
-
...(zai ? { zaiCodingPlan: zai.view } : {}),
|
|
132
|
+
...(zai.zai ? { zaiCodingPlan: zai.zai.view } : {}),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** 실 OAuth usage 엔드포인트는 5~10분 간격에도 429 를 낸다(fetchers/claude.ts 머리말 · 기본 주기 15분).
|
|
137
|
+
* nexus `/api/usage` 는 30초 캐시로 이 조립을 부르므로, 기본 조회 경로(심 없음)는 성공 스냅숏을 15분 재사용한다. */
|
|
138
|
+
const CLAUDE_USAGE_CACHE_MS = 15 * 60_000;
|
|
139
|
+
/** 실패(429 등)도 5분 재사용한다 — 429 가 이어지는 동안 30초마다 다시 치지 않게. */
|
|
140
|
+
const CLAUDE_USAGE_FAILURE_CACHE_MS = 5 * 60_000;
|
|
141
|
+
type ClaudeUsageCacheEntry = { readonly at: number; readonly token: string } & (
|
|
142
|
+
| { readonly ok: true; readonly snap: UsageSnapshot }
|
|
143
|
+
| { readonly ok: false; readonly error: unknown });
|
|
144
|
+
let claudeUsageCache: ClaudeUsageCacheEntry | null = null;
|
|
145
|
+
|
|
146
|
+
/** 시험 전용 — 모듈 캐시를 비운다. */
|
|
147
|
+
export function resetClaudeUsageCacheForTest(): void {
|
|
148
|
+
claudeUsageCache = null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function fetchClaudeCached(token: string, nowMs: number, fetchRaw: () => Promise<UsageSnapshot>): Promise<UsageSnapshot> {
|
|
152
|
+
const c = claudeUsageCache;
|
|
153
|
+
// 캐시 키 = 토큰 — 토큰이 바뀌면(재로그인·계정 교체) 옛 계정 값을 새 행으로 보이지 않는다.
|
|
154
|
+
if (c && c.token === token && nowMs - c.at < (c.ok ? CLAUDE_USAGE_CACHE_MS : CLAUDE_USAGE_FAILURE_CACHE_MS)) {
|
|
155
|
+
if (c.ok) return c.snap;
|
|
156
|
+
throw c.error;
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
const snap = await fetchRaw();
|
|
160
|
+
claudeUsageCache = { at: nowMs, token, ok: true, snap };
|
|
161
|
+
return snap;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
claudeUsageCache = { at: nowMs, token, ok: false, error };
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Claude Code 구독 행 — 5시간 창(credits 축) ⊕ 7일 창(subscription 축).
|
|
169
|
+
* ⛔ 토큰이 없으면 행을 «안» 만든다(0행 ≠ 0% 사용) — openrouter·zai 키와 같은 접기. */
|
|
170
|
+
async function collectClaudeRows(deps: UnifiedUsageDeps): Promise<AccountUsageRow[]> {
|
|
171
|
+
// ⛔ 시험 런타임은 심이 없으면 «토큰 없음»으로 본다 — 실제 자격 파일을 읽으면
|
|
172
|
+
// 심을 모르는 옛 시험이 실제 네트워크를 치게 된다(openrouter·zai 키와 같은 이유).
|
|
173
|
+
const resolveToken = deps.resolveClaudeToken
|
|
174
|
+
?? (process.env.NODE_ENV === 'test' ? () => null : resolveClaudeAccessToken);
|
|
175
|
+
let token: string | null;
|
|
176
|
+
try {
|
|
177
|
+
token = resolveToken();
|
|
178
|
+
} catch (err) {
|
|
179
|
+
// 자격 파일이 깨진 경우를 «토큰 없음»과 가를 수 있게 관측만 남긴다(행은 안 만든다).
|
|
180
|
+
debug.log('usage', 'claude-token-resolve-failed', { detail: err instanceof Error ? err.message : String(err) });
|
|
181
|
+
token = null;
|
|
182
|
+
}
|
|
183
|
+
if (!token) return [];
|
|
184
|
+
const base = {
|
|
185
|
+
provider: 'claude' as const,
|
|
186
|
+
accountName: 'default',
|
|
187
|
+
accountCount: 1,
|
|
188
|
+
soleAccount: true,
|
|
189
|
+
resetCredits: { status: 'not-applicable' } as const,
|
|
190
|
+
};
|
|
191
|
+
const tokenKey = token;
|
|
192
|
+
const fetchClaude = deps.fetchClaude ?? (() => fetchClaudeCached(
|
|
193
|
+
tokenKey, (deps.now ?? Date.now)(), deps.fetchClaudeUncached ?? (() => createClaudeFetcher().fetch())));
|
|
194
|
+
try {
|
|
195
|
+
const snap = await fetchClaude();
|
|
196
|
+
const fiveHour = snap.windows.find((w) => w.model === undefined && w.kind === 'session');
|
|
197
|
+
const weekly = snap.windows.find((w) => w.model === undefined && w.kind === 'weekly');
|
|
198
|
+
return [{ ...base, credits: claudeCreditsFromWindow(fiveHour), subscription: claudeSubscriptionFromWindow(weekly) }];
|
|
199
|
+
} catch (err) {
|
|
200
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
201
|
+
debug.log('usage', 'claude-fetch-failed', { detail });
|
|
202
|
+
return [{
|
|
203
|
+
...base,
|
|
204
|
+
credits: { status: 'error', detail },
|
|
205
|
+
subscription: { status: 'unavailable', reason: 'query-does-not-supply' },
|
|
206
|
+
}];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function claudeCreditsFromWindow(window: RateWindow | undefined): CreditAxis {
|
|
211
|
+
const periodEnd = window && isValidEpochMs(window.resetsAt) ? new Date(window.resetsAt) : null;
|
|
212
|
+
const periodStartEpoch = periodEnd !== null && window !== undefined && isPositiveFinite(window.windowMinutes)
|
|
213
|
+
? periodEnd.getTime() - window.windowMinutes * 60_000
|
|
214
|
+
: null;
|
|
215
|
+
const periodStart = periodStartEpoch !== null && isValidDateMs(periodStartEpoch) ? new Date(periodStartEpoch) : null;
|
|
216
|
+
return {
|
|
217
|
+
status: 'ok',
|
|
218
|
+
usedPercent: window ? window.used : null,
|
|
219
|
+
periodType: window?.kind ?? null,
|
|
220
|
+
periodStart: periodStart?.toISOString() ?? null,
|
|
221
|
+
periodEnd: periodEnd?.toISOString() ?? null,
|
|
222
|
+
monthlyLimit: null,
|
|
223
|
+
used: window ? window.used : null,
|
|
224
|
+
onDemandCap: null,
|
|
225
|
+
onDemandUsed: null,
|
|
226
|
+
prepaidBalance: null,
|
|
227
|
+
balance: null,
|
|
228
|
+
hasCredits: null,
|
|
229
|
+
unlimited: null,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function claudeSubscriptionFromWindow(window: RateWindow | undefined): SubscriptionAxis {
|
|
234
|
+
if (!window) return { status: 'unavailable', reason: 'query-does-not-supply' };
|
|
235
|
+
return {
|
|
236
|
+
status: 'available',
|
|
237
|
+
remainingPercent: window.remainingPercent,
|
|
238
|
+
resetsAt: window.resetsAt,
|
|
239
|
+
windowKind: window.kind,
|
|
81
240
|
};
|
|
82
241
|
}
|
|
83
242
|
|
|
@@ -429,6 +588,11 @@ export function formatUnifiedUsage(report: UnifiedUsageReport): string {
|
|
|
429
588
|
const count = report.accountCounts[provider];
|
|
430
589
|
lines.push(` ${provider} accounts=${count}${count === 1 ? ' (하나뿐)' : count === 0 ? ' (없음)' : ''}`);
|
|
431
590
|
}
|
|
591
|
+
// ⛔ claude 토큰이 없으면 줄을 안 낸다 — 종전 문면과 바이트 동일.
|
|
592
|
+
if (report.accountCounts.claude !== undefined) {
|
|
593
|
+
const count = report.accountCounts.claude;
|
|
594
|
+
lines.push(` claude accounts=${count}${count === 1 ? ' (하나뿐)' : ''} (Claude Code 구독 · 5시간 창 ⊕ 7일 창)`);
|
|
595
|
+
}
|
|
432
596
|
// ⛔ 키가 없으면 줄을 안 낸다 — 종전 문면과 바이트 동일.
|
|
433
597
|
if (report.accountCounts.zai !== undefined) lines.push(` zai accounts=${report.accountCounts.zai} (GLM Coding Plan)`);
|
|
434
598
|
lines.push(' provider account accounts credits.usedPercent credits.window window-resets-in reset-credit-expiry subscription');
|
package/src/cli/doctor-cli.ts
CHANGED
|
@@ -40,6 +40,7 @@ import type { LlmInventory } from '../llm/local-manager/types.js';
|
|
|
40
40
|
import { buildDoctorBundle } from './doctor-bundle.js';
|
|
41
41
|
import { uploadDoctorBundle } from './doctor-bundle-upload.js';
|
|
42
42
|
import { checkNodeModules, formatNodeModulesCheck, nodeModulesTrees } from './doctor-node-modules.js';
|
|
43
|
+
import { formatHostDoctorLines, runHostDoctor, type HostDoctorExpected, type HostDoctorRemote } from '../fleet/host-doctor.js';
|
|
43
44
|
|
|
44
45
|
function defaultCheckPythonEnv(): { status: 'ok' | 'fixable' | 'manual'; evidence: string; remedy?: string } {
|
|
45
46
|
const c = checkPythonEnv(false);
|
|
@@ -198,6 +199,10 @@ export interface DoctorCliDeps extends DoctorOptions, Pick<DoctorFixDeps, 'home'
|
|
|
198
199
|
/** Inject the upload transport and consent for isolated CLI tests. */
|
|
199
200
|
uploadFetch?: typeof globalThis.fetch;
|
|
200
201
|
confirmBundleUpload?: (message: string) => Promise<boolean>;
|
|
202
|
+
/** `doctor host` 원격 실행(시험 seam) — 기본 = ssh BatchMode · `local` 이면 이 기계. */
|
|
203
|
+
hostDoctorRemote?: HostDoctorRemote;
|
|
204
|
+
/** `doctor host` 가 대조할 HQ 실측값(설치 판 · 이미지 핀) — 없으면 해당 점검은 unmeasured. */
|
|
205
|
+
hostDoctorExpected?: HostDoctorExpected;
|
|
201
206
|
}
|
|
202
207
|
|
|
203
208
|
const repositoryRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
|
|
@@ -1240,6 +1245,22 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
|
|
|
1240
1245
|
out.log(json ? JSON.stringify(opts.all ? checks : checks[0], null, 2) : checks.map(formatNodeModulesCheck).join('\n'));
|
|
1241
1246
|
if (checks.some((check) => check.status !== 'ok')) setExitCode(1);
|
|
1242
1247
|
});
|
|
1248
|
+
doctor.command('host')
|
|
1249
|
+
.description('Check whether a fleet host stands ready for its role (read-only · setup-status shape)')
|
|
1250
|
+
.argument('<host>', "ssh name, or 'local' for this machine")
|
|
1251
|
+
.option('--role <role>', 'host role: worker or hq', 'worker')
|
|
1252
|
+
.option('--json', 'structured output')
|
|
1253
|
+
.action((host: string, opts: { role: string; json?: boolean }, command: Command) => {
|
|
1254
|
+
if (opts.role !== 'worker' && opts.role !== 'hq') {
|
|
1255
|
+
err.error('--role must be worker or hq');
|
|
1256
|
+
setExitCode(1);
|
|
1257
|
+
return;
|
|
1258
|
+
}
|
|
1259
|
+
const json = opts.json === true || command.parent?.opts().json === true;
|
|
1260
|
+
const report = runHostDoctor({ host, role: opts.role, remote: deps.hostDoctorRemote, expected: deps.hostDoctorExpected });
|
|
1261
|
+
out.log(json ? JSON.stringify(report, null, 2) : formatHostDoctorLines(report).join('\n'));
|
|
1262
|
+
if (!report.ok) setExitCode(1);
|
|
1263
|
+
});
|
|
1243
1264
|
doctor
|
|
1244
1265
|
.option('--credentials', 'show per-credential details in human-readable output')
|
|
1245
1266
|
.option('--bundle', 'write a redacted diagnostics archive for support')
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { detectLocale, type Locale } from '../expression/locale.js';
|
|
2
|
+
import { classifyError } from '../session-runtime/retry-policy.js';
|
|
3
|
+
|
|
4
|
+
export type FriendlyErrorCode =
|
|
5
|
+
| 'credential-missing'
|
|
6
|
+
| 'provider-unknown'
|
|
7
|
+
| 'model-unavailable'
|
|
8
|
+
| 'network'
|
|
9
|
+
| 'quota'
|
|
10
|
+
| 'context-too-long'
|
|
11
|
+
| 'config-broken'
|
|
12
|
+
| 'daemon-down'
|
|
13
|
+
| 'permission'
|
|
14
|
+
| 'unknown-command';
|
|
15
|
+
|
|
16
|
+
export interface FriendlyMessage {
|
|
17
|
+
what: string;
|
|
18
|
+
why: string;
|
|
19
|
+
next: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type FriendlyLanguage = 'ko' | 'en';
|
|
23
|
+
|
|
24
|
+
export const FRIENDLY_ERRORS: Readonly<Record<FriendlyErrorCode, Readonly<Record<FriendlyLanguage, FriendlyMessage>>>> = {
|
|
25
|
+
'credential-missing': {
|
|
26
|
+
ko: { what: '모델에 접속할 자격이 없습니다', why: '이 provider 에 로그인하지 않았거나 키가 없습니다', next: 'elanous login' },
|
|
27
|
+
en: { what: 'No credentials for this model provider', why: 'You have not signed in or set a key', next: 'elanous login' },
|
|
28
|
+
},
|
|
29
|
+
'provider-unknown': {
|
|
30
|
+
ko: { what: '설정된 provider 를 모릅니다', why: 'llm.provider 값이 지원 목록에 없습니다', next: 'elanous config get llm.provider' },
|
|
31
|
+
en: { what: 'Unknown model provider', why: 'llm.provider is not a supported name', next: 'elanous config get llm.provider' },
|
|
32
|
+
},
|
|
33
|
+
'model-unavailable': {
|
|
34
|
+
ko: { what: '이 모델을 쓸 수 없습니다', why: 'provider 와 모델이 맞지 않거나 모델이 없습니다', next: 'elanous config get llm.model' },
|
|
35
|
+
en: { what: 'This model is not available', why: 'The provider and model do not match, or the model does not exist', next: 'elanous config get llm.model' },
|
|
36
|
+
},
|
|
37
|
+
network: {
|
|
38
|
+
ko: { what: '서버에 연결하지 못했습니다', why: '네트워크가 끊겼거나 서버가 응답하지 않습니다', next: 'elanous doctor' },
|
|
39
|
+
en: { what: 'Could not reach the server', why: 'The network is down or the server did not answer', next: 'elanous doctor' },
|
|
40
|
+
},
|
|
41
|
+
quota: {
|
|
42
|
+
ko: { what: '사용 한도에 걸렸습니다', why: '이 계정의 할당량을 다 썼거나 요청이 너무 잦습니다', next: 'elanous usage' },
|
|
43
|
+
en: { what: 'Usage limit reached', why: 'The account quota is used up or requests are too frequent', next: 'elanous usage' },
|
|
44
|
+
},
|
|
45
|
+
'context-too-long': {
|
|
46
|
+
ko: { what: '입력이 너무 깁니다', why: '모델이 한 번에 읽는 양을 넘었습니다', next: 'elanous ask "<더 짧은 질문>"' },
|
|
47
|
+
en: { what: 'The input is too long', why: 'It exceeds what the model reads at once', next: 'elanous ask "<shorter question>"' },
|
|
48
|
+
},
|
|
49
|
+
'config-broken': {
|
|
50
|
+
ko: { what: '설정 파일을 읽지 못했습니다', why: 'config 파일의 JSON 이 깨졌습니다', next: 'elanous doctor --fix' },
|
|
51
|
+
en: { what: 'Could not read the config file', why: 'The config JSON is malformed', next: 'elanous doctor --fix' },
|
|
52
|
+
},
|
|
53
|
+
'daemon-down': {
|
|
54
|
+
ko: { what: '엘라누스 데몬이 떠 있지 않습니다', why: '백그라운드 서비스가 꺼져 있습니다', next: 'elanous nexus' },
|
|
55
|
+
en: { what: 'The elanous daemon is not running', why: 'The background service is stopped', next: 'elanous nexus' },
|
|
56
|
+
},
|
|
57
|
+
permission: {
|
|
58
|
+
ko: { what: '파일에 접근할 권한이 없습니다', why: '이 사용자로 그 경로를 읽거나 쓸 수 없습니다', next: 'elanous doctor' },
|
|
59
|
+
en: { what: 'Permission denied', why: 'This user cannot read or write that path', next: 'elanous doctor' },
|
|
60
|
+
},
|
|
61
|
+
'unknown-command': {
|
|
62
|
+
ko: { what: '모르는 명령입니다', why: '명령 이름이 틀렸거나 이 판에 없습니다', next: 'elanous --help' },
|
|
63
|
+
en: { what: 'Unknown command', why: 'The name is misspelled or not in this version', next: 'elanous --help' },
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function messageOf(err: unknown): string {
|
|
68
|
+
if (err instanceof Error) return err.message;
|
|
69
|
+
return typeof err === 'string' ? err : '';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function errnoOf(err: unknown): string {
|
|
73
|
+
if (err && typeof err === 'object') {
|
|
74
|
+
const code = (err as { code?: unknown }).code;
|
|
75
|
+
if (typeof code === 'string') return code;
|
|
76
|
+
}
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Maps a thrown value to a friendly-error code by its wording and by the
|
|
81
|
+
* retry-policy category. Returns null when nothing matches. */
|
|
82
|
+
export function classifyFriendlyError(err: unknown): FriendlyErrorCode | null {
|
|
83
|
+
const msg = messageOf(err);
|
|
84
|
+
const errno = errnoOf(err);
|
|
85
|
+
|
|
86
|
+
if (/provider-model compatibility/i.test(msg)) return 'model-unavailable';
|
|
87
|
+
if (/\bunknown provider:/i.test(msg)) return 'provider-unknown';
|
|
88
|
+
if (/\bunavailable:\s+(set|run|configure)\b/i.test(msg)) return 'credential-missing';
|
|
89
|
+
if (/the elanous daemon is not running/i.test(msg)) return 'daemon-down';
|
|
90
|
+
if (/unknown command '/i.test(msg)) return 'unknown-command';
|
|
91
|
+
if (/input exceeds the \d+-token context budget/i.test(msg)) return 'context-too-long';
|
|
92
|
+
if (
|
|
93
|
+
/Unexpected token .*JSON|JSON Parse error|is not valid JSON|JSON at position/i.test(msg) ||
|
|
94
|
+
(err instanceof Error && err.name === 'SyntaxError' && /json/i.test(msg))
|
|
95
|
+
) return 'config-broken';
|
|
96
|
+
if (errno === 'EACCES' || errno === 'EPERM' || /\b(EACCES|EPERM)\b/.test(msg)) return 'permission';
|
|
97
|
+
|
|
98
|
+
switch (classifyError(err)) {
|
|
99
|
+
case 'network-transient': return 'network';
|
|
100
|
+
case 'quota-exceeded':
|
|
101
|
+
case 'rate-limit': return 'quota';
|
|
102
|
+
case 'context-window-exceeded': return 'context-too-long';
|
|
103
|
+
case 'provider-unavailable': return 'credential-missing';
|
|
104
|
+
default: return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Renders one language only (ko, otherwise en). The last line is the one command to run. */
|
|
109
|
+
export function formatFriendlyError(code: FriendlyErrorCode, locale: Locale = detectLocale()): string {
|
|
110
|
+
const language: FriendlyLanguage = locale === 'ko' ? 'ko' : 'en';
|
|
111
|
+
const { what, why, next } = FRIENDLY_ERRORS[code][language];
|
|
112
|
+
return `❌ ${what}\n ↳ ${why}\n ${next}`;
|
|
113
|
+
}
|
package/src/cli/intake-cli.ts
CHANGED
|
@@ -173,7 +173,9 @@ export async function runIntakeDigestCli(
|
|
|
173
173
|
const { getUserConfig } = await import('../user-config.js');
|
|
174
174
|
return sendTelegramReport(getUserConfig(), text, { markdown: true, kind: 'intake' });
|
|
175
175
|
})();
|
|
176
|
-
|
|
176
|
+
const judgedCount = (entries: { verdict: string }[] | undefined) => (entries ?? []).filter((entry) => entry.verdict !== '판정 대기').length;
|
|
177
|
+
debug.log('intake.digest', 'telegram', { day, absorbed: d.absorbed.length, goals: d.goals.length,
|
|
178
|
+
github: d.githubNew?.length ?? 0, githubJudged: judgedCount(d.githubNew), x: d.xTrends?.length ?? 0, xJudged: judgedCount(d.xTrends), sent });
|
|
177
179
|
if (seat && sent) recordSeatBriefed(root, seat, day, d.absorbed.map((entry) => entry.id));
|
|
178
180
|
if (seat === 'user') debug.log('watch.default', 'brief', { topics: (await import('../intake-plane/intake-sources.js')).listSources({ seat }, root).length, items: d.absorbed.length, sent });
|
|
179
181
|
console.log(sent ? `텔레그램 보고 채널로 보냈다 (${day} · 흡수 ${d.absorbed.length} · 골 후보 ${d.goals.length})` : '텔레그램 보고 채널 설정이 없다(telegram.reportChannel) — 보내지 않음');
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `elanous memory` 명령 묶음 등록 — BIG-FILE-index-1 첫 조각(순수 이동 · src/index.ts → src/cli/memory-cli.ts).
|
|
3
|
+
* 로직·문면·옵션·종료 코드는 이동 원본과 동일하다.
|
|
4
|
+
*/
|
|
5
|
+
import type { Command } from 'commander';
|
|
6
|
+
import * as ui from '../ui.js';
|
|
7
|
+
import { readPipedStdin } from './piped-stdin.js';
|
|
8
|
+
import {
|
|
9
|
+
saveMemory, loadMemory, listMemories, deleteMemory, searchMemories,
|
|
10
|
+
readIndex, memoryRoot, memoryIndexPath,
|
|
11
|
+
type MemoryType,
|
|
12
|
+
} from '../memory.js';
|
|
13
|
+
|
|
14
|
+
export function registerMemoryCommands(program: Command): void {
|
|
15
|
+
const memCmd = program.command('memory').description('Persistent memories injected into every chat turn (user / feedback / project / reference)');
|
|
16
|
+
|
|
17
|
+
memCmd
|
|
18
|
+
.command('list [type]')
|
|
19
|
+
.description('List memories (optionally filtered by type)')
|
|
20
|
+
.option('-n, --limit <n>', 'Max entries to show', '30')
|
|
21
|
+
.action((type?: string, opts?: { limit: string }) => {
|
|
22
|
+
const t = type as MemoryType | undefined;
|
|
23
|
+
const entries = listMemories({ type: t, limit: parseInt(opts?.limit ?? '30', 10) });
|
|
24
|
+
if (entries.length === 0) {
|
|
25
|
+
ui.info('No memories yet. Add one with `elanous memory add <type> "<name>" "<description>"`.');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
ui.header(`memories (${entries.length})`);
|
|
29
|
+
for (const e of entries) {
|
|
30
|
+
console.log(` ${e.id.slice(0, 8)} [${e.type.padEnd(9)}] ${e.name}`);
|
|
31
|
+
if (e.description) console.log(` ${e.description.slice(0, 100)}`);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
memCmd
|
|
36
|
+
.command('add <type> <name> [description...]')
|
|
37
|
+
.description('Create a memory (type: user|feedback|project|reference). Body piped via stdin if available.')
|
|
38
|
+
.action(async (type: string, name: string, descParts: string[]) => {
|
|
39
|
+
if (!['user', 'feedback', 'project', 'reference'].includes(type)) {
|
|
40
|
+
ui.error(`invalid type "${type}". Use: user | feedback | project | reference`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
const description = (descParts || []).join(' ');
|
|
44
|
+
// Read body from stdin if piped; otherwise use description as body too.
|
|
45
|
+
let body = description;
|
|
46
|
+
const pipedBody = await readPipedStdin(); // ★ OBS-T3 — 비-TTY 는 파이프를 뜻하지 않는다(소켓이면 EOF 가 안 온다)
|
|
47
|
+
if (pipedBody) body = pipedBody;
|
|
48
|
+
const e = saveMemory({ type: type as MemoryType, name, description, body });
|
|
49
|
+
ui.info(`saved ${e.id.slice(0, 8)} [${e.type}] "${e.name}"`);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// 3번째 recall 레버(2026-07-19) — pin(항상주입) / priority(매칭 시 순위 부스트).
|
|
53
|
+
memCmd
|
|
54
|
+
.command('pin <idPrefix>')
|
|
55
|
+
.description('Pin a memory so it is ALWAYS injected (bypass keyword gate). Optionally set priority.')
|
|
56
|
+
.option('-p, --priority <n>', 'priority boost (higher = ranked/kept first)', '5')
|
|
57
|
+
.action((prefix: string, opts: { priority: string }) => {
|
|
58
|
+
const e = loadMemory(prefix);
|
|
59
|
+
if (!e) { ui.error(`no memory matching "${prefix}"`); process.exit(1); }
|
|
60
|
+
saveMemory({ type: e.type, name: e.name, description: e.description, body: e.body, id: e.id, pinned: true, priority: parseInt(opts.priority, 10) || 0 });
|
|
61
|
+
ui.info(`📌 pinned ${e.id.slice(0, 8)} "${e.name}" (priority ${opts.priority})`);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
memCmd
|
|
65
|
+
.command('unpin <idPrefix>')
|
|
66
|
+
.description('Un-pin a memory (back to keyword-gated recall).')
|
|
67
|
+
.action((prefix: string) => {
|
|
68
|
+
const e = loadMemory(prefix);
|
|
69
|
+
if (!e) { ui.error(`no memory matching "${prefix}"`); process.exit(1); }
|
|
70
|
+
saveMemory({ type: e.type, name: e.name, description: e.description, body: e.body, id: e.id, pinned: false, priority: e.priority });
|
|
71
|
+
ui.info(`unpinned ${e.id.slice(0, 8)} "${e.name}"`);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
memCmd
|
|
75
|
+
.command('priority <idPrefix> <n>')
|
|
76
|
+
.description('Set a memory\'s injection priority boost (0 = default). Added to match score.')
|
|
77
|
+
.action((prefix: string, n: string) => {
|
|
78
|
+
const e = loadMemory(prefix);
|
|
79
|
+
if (!e) { ui.error(`no memory matching "${prefix}"`); process.exit(1); }
|
|
80
|
+
saveMemory({ type: e.type, name: e.name, description: e.description, body: e.body, id: e.id, priority: parseInt(n, 10) || 0, pinned: e.pinned });
|
|
81
|
+
ui.info(`priority ${e.id.slice(0, 8)} "${e.name}" → ${parseInt(n, 10) || 0}`);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// 통합 관리 뷰(2026-07-19) — 2 시스템(큐레이션 파일메모리 + 에피소드 self-log)을 한 화면에.
|
|
85
|
+
memCmd
|
|
86
|
+
.command('status')
|
|
87
|
+
.description('Unified memory overview — ① curated file-memory + ② self-log (surface_events)')
|
|
88
|
+
.action(async () => {
|
|
89
|
+
const { memoryRoot } = await import('../memory.js');
|
|
90
|
+
const mems = listMemories();
|
|
91
|
+
const byType: Record<string, number> = {};
|
|
92
|
+
let pinned = 0;
|
|
93
|
+
for (const e of mems) { byType[e.type] = (byType[e.type] ?? 0) + 1; if (e.pinned) pinned += 1; }
|
|
94
|
+
ui.header('memory (unified)');
|
|
95
|
+
console.log(`① 큐레이션 파일메모리: ${mems.length}건 [${Object.entries(byType).map(([k, v]) => `${k}:${v}`).join(' ') || '-'}] 📌pinned ${pinned}`);
|
|
96
|
+
console.log(` ${memoryRoot()} (LLM-judge/luna recall · MEMORY.md 항상주입)`);
|
|
97
|
+
try {
|
|
98
|
+
const { surfaceEventsDbPath, openSurfaceEventsDb } = await import('../domains/surface-events.js');
|
|
99
|
+
const path = surfaceEventsDbPath();
|
|
100
|
+
// 항상 open — legacy conatus/ → memory/ 자가치유 마이그레이션이 여기서 실행된다(존재 체크 먼저
|
|
101
|
+
// 하면 신 경로 부재로 마이그레이션이 스킵됨). 없으면 빈 store 생성(무해).
|
|
102
|
+
const db = openSurfaceEventsDb(path);
|
|
103
|
+
const n = (db.prepare('SELECT count(*) c FROM events').get() as { c: number }).c;
|
|
104
|
+
const recent = (db.prepare('SELECT ts FROM events ORDER BY ts DESC LIMIT 1').get() as { ts: string } | undefined)?.ts;
|
|
105
|
+
db.close();
|
|
106
|
+
console.log(`② 에피소드 self-log: ${n.toLocaleString()} events (최근 ${recent?.slice(0, 16) ?? '-'})`);
|
|
107
|
+
console.log(` ${path} (FTS5 bm25+recency+myelin rerank · ambient 회상)`);
|
|
108
|
+
} catch (e) { console.log(`② self-log 조회 실패: ${(e as Error).message}`); }
|
|
109
|
+
try {
|
|
110
|
+
const { openKnowledgeDb, knowledgeDbPath } = await import('../domains/knowledge.js');
|
|
111
|
+
const kdb = openKnowledgeDb(); // 기본 경로 → legacy conatus/ 자가치유 이전
|
|
112
|
+
const kn = (kdb.prepare('SELECT count(*) c FROM docs').get() as { c: number }).c;
|
|
113
|
+
const dom = (kdb.prepare("SELECT domain, count(*) c FROM docs GROUP BY domain ORDER BY c DESC LIMIT 3").all() as Array<{ domain: string | null; c: number }>);
|
|
114
|
+
kdb.close();
|
|
115
|
+
console.log(`③ 시맨틱 knowledge: ${kn.toLocaleString()} docs [${dom.map(d => `${d.domain ?? 'null'}:${d.c}`).join(' ')}]`);
|
|
116
|
+
console.log(` ${knowledgeDbPath()} (임베딩 벡터+BM25 하이브리드 · 의미 회상)`);
|
|
117
|
+
} catch (e) { console.log(`③ knowledge 조회 실패: ${(e as Error).message}`); }
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
memCmd
|
|
121
|
+
.command('show <idPrefix>')
|
|
122
|
+
.description('Print full memory body')
|
|
123
|
+
.action((prefix: string) => {
|
|
124
|
+
const entries = listMemories();
|
|
125
|
+
const hit = entries.find(e => e.id.startsWith(prefix));
|
|
126
|
+
if (!hit) { ui.error(`no memory matching "${prefix}"`); process.exit(1); }
|
|
127
|
+
const full = loadMemory(hit.id)!;
|
|
128
|
+
ui.header(`${full.type}: ${full.name}`);
|
|
129
|
+
console.log(` id ${full.id}`);
|
|
130
|
+
console.log(` created ${full.createdAt}`);
|
|
131
|
+
console.log(` updated ${full.updatedAt}`);
|
|
132
|
+
console.log(` description ${full.description}`);
|
|
133
|
+
console.log('');
|
|
134
|
+
console.log(full.body);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
memCmd
|
|
138
|
+
.command('search <query...>')
|
|
139
|
+
.description('Keyword search across all memories')
|
|
140
|
+
.option('--type <t>', 'Filter by type')
|
|
141
|
+
.option('-n, --limit <n>', 'Max results', '10')
|
|
142
|
+
.action((parts: string[], opts) => {
|
|
143
|
+
const hits = searchMemories(parts.join(' '), {
|
|
144
|
+
type: opts.type as MemoryType | undefined,
|
|
145
|
+
limit: parseInt(opts.limit, 10),
|
|
146
|
+
});
|
|
147
|
+
if (hits.length === 0) { ui.info('No matches.'); return; }
|
|
148
|
+
ui.header(`matches (${hits.length})`);
|
|
149
|
+
for (const h of hits) {
|
|
150
|
+
console.log(` ${h.entry.id.slice(0, 8)} score ${h.score} [${h.entry.type}] ${h.entry.name}`);
|
|
151
|
+
if (h.entry.description) console.log(` ${h.entry.description.slice(0, 100)}`);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
memCmd
|
|
156
|
+
.command('delete <idPrefix>')
|
|
157
|
+
.description('Delete a memory')
|
|
158
|
+
.action((prefix: string) => {
|
|
159
|
+
const entries = listMemories();
|
|
160
|
+
const hit = entries.find(e => e.id.startsWith(prefix));
|
|
161
|
+
if (!hit) { ui.error(`no memory matching "${prefix}"`); process.exit(1); }
|
|
162
|
+
deleteMemory(hit.id);
|
|
163
|
+
ui.info(`deleted ${hit.id.slice(0, 8)}`);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
memCmd
|
|
167
|
+
.command('index')
|
|
168
|
+
.description('Print MEMORY.md index verbatim')
|
|
169
|
+
.action(() => {
|
|
170
|
+
const idx = readIndex();
|
|
171
|
+
if (!idx) { ui.info('empty (no memories yet)'); return; }
|
|
172
|
+
console.log(idx);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
memCmd
|
|
176
|
+
.command('where')
|
|
177
|
+
.description('Show the memory storage path')
|
|
178
|
+
.action(() => {
|
|
179
|
+
console.log(`memory dir ${memoryRoot()}`);
|
|
180
|
+
console.log(`index file ${memoryIndexPath()}`);
|
|
181
|
+
});
|
|
182
|
+
}
|
|
@@ -5,7 +5,7 @@ import { loadCatalog, type CatalogIoOpts } from '../intelligence-map/model-catal
|
|
|
5
5
|
import { getModelWatchProposalPath, runModelIntelligenceWatch, type ModelWatchDeps } from '../intelligence-map/model-watch-mission.js';
|
|
6
6
|
import { fetchProviderModelPages, type ModelWatchFetchResult } from '../intelligence-map/model-watch-fetch.js';
|
|
7
7
|
import type { ModelCandidate } from '../intelligence-map/model-classifier.js';
|
|
8
|
-
import type
|
|
8
|
+
import { detectPriceChanges, formatPriceChange, type PriceChange, type WatchIntakeResult } from '../intelligence-map/model-watch-intake.js';
|
|
9
9
|
import type { LlmRunner } from '../model-tier/preset-suggest-llm.js';
|
|
10
10
|
|
|
11
11
|
export interface ModelWatchCliResult {
|
|
@@ -14,6 +14,7 @@ export interface ModelWatchCliResult {
|
|
|
14
14
|
failures: ModelWatchFetchResult['failures'];
|
|
15
15
|
proposal: Pick<WatchIntakeResult['proposal'], 'added' | 'updated'>;
|
|
16
16
|
candidates: WatchIntakeResult['candidates'];
|
|
17
|
+
priceChanges: PriceChange[];
|
|
17
18
|
perSource: WatchIntakeResult['perSource'];
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -93,6 +94,7 @@ export async function runModelWatchCli(deps: ModelWatchCliDeps = {}): Promise<Mo
|
|
|
93
94
|
failures: fetched.failures,
|
|
94
95
|
proposal: { added: intake.proposal.added, updated: intake.proposal.updated },
|
|
95
96
|
candidates: intake.candidates,
|
|
97
|
+
priceChanges: detectPriceChanges(intake),
|
|
96
98
|
perSource: intake.perSource,
|
|
97
99
|
};
|
|
98
100
|
}
|
|
@@ -103,6 +105,7 @@ export function formatModelWatchResult(result: ModelWatchCliResult): string {
|
|
|
103
105
|
`Proposal: ${result.proposal.added.length} added, ${result.proposal.updated.length} updated (not applied).`,
|
|
104
106
|
];
|
|
105
107
|
if (result.candidates.length > 0) lines.push(`Candidates: ${result.candidates.map((candidate) => candidate.id).join(', ')}`);
|
|
108
|
+
if (result.priceChanges.length > 0) lines.push(`Price changes: ${result.priceChanges.map(formatPriceChange).join('; ')}`);
|
|
106
109
|
const abnormalEmptySources = Object.entries(result.perSource)
|
|
107
110
|
.filter(([, source]) => source.candidateCount === 0 && source.status !== 'completed')
|
|
108
111
|
.map(([source]) => source);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRLAND-HEAVY-ON-POD-1 — `pr land` 무거운 판정을 Pod 에서 그림자 리허설한다.
|
|
3
|
+
*
|
|
4
|
+
* 착지 경로에 아직 잇지 않는다. `--heavy-on-pod-shadow` 플래그·실제 Pod 러너 바인딩은
|
|
5
|
+
* 다음 조각(pr-cli.ts · pod-command-job.ts 무접촉). 이번 단위는 주입형 순수 함수만:
|
|
6
|
+
* 켜지면 가짜/실 Pod 러너를 한 번 부르고 `pr.land`/`heavy-on-pod-shadow` 관측 한 줄을 남긴 뒤
|
|
7
|
+
* 로컬 판정을 그대로 반환한다. 끄면 러너 0회. 러너가 던져도 경고 한 줄만 내고 로컬을 지킨다.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface HeavyOnPodShadowInput<T> {
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
pr: number;
|
|
13
|
+
head: string;
|
|
14
|
+
local: T;
|
|
15
|
+
runPod: () => T | Promise<T>;
|
|
16
|
+
log: (category: string, event: string, data: Record<string, unknown>) => void;
|
|
17
|
+
warn: (message: string) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function agree(local: unknown, pod: unknown): boolean {
|
|
21
|
+
if (Object.is(local, pod)) return true;
|
|
22
|
+
try {
|
|
23
|
+
return JSON.stringify(local) === JSON.stringify(pod);
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function elapsedMs(started: number): number {
|
|
30
|
+
return Math.max(0, performance.now() - started);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function runHeavyOnPodShadow<T>(input: HeavyOnPodShadowInput<T>): Promise<T> {
|
|
34
|
+
const { enabled, pr, head, local, runPod, log, warn } = input;
|
|
35
|
+
if (!enabled) return local;
|
|
36
|
+
|
|
37
|
+
const localMs = 0;
|
|
38
|
+
const started = performance.now();
|
|
39
|
+
try {
|
|
40
|
+
const pod = await runPod();
|
|
41
|
+
log('pr.land', 'heavy-on-pod-shadow', {
|
|
42
|
+
pr,
|
|
43
|
+
head,
|
|
44
|
+
local,
|
|
45
|
+
pod,
|
|
46
|
+
agree: agree(local, pod),
|
|
47
|
+
podMs: elapsedMs(started),
|
|
48
|
+
localMs,
|
|
49
|
+
});
|
|
50
|
+
} catch (error) {
|
|
51
|
+
warn(error instanceof Error ? error.message : String(error));
|
|
52
|
+
}
|
|
53
|
+
return local;
|
|
54
|
+
}
|