elanous 0.2.23 → 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-ad3bd8084048bee4.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-a648bc464c9dc754.js → page-dea4b795741126fd.js} +1 -1
- 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-48fb31810693c357.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-cb154acadb025414.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/css/72becfd42807b50d.css +1 -0
- package/apps/pwa/out/_next/static/{rfkMm4movqkqMebBrCXiR → dRS6lEhSRRBr1abbzp7fJ}/_buildManifest.js +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/catalog/models/openrouter/deepseek-v4-pro-0813.yaml +39 -0
- package/catalog/models/openrouter/deepseek-v4.1-flash.yaml +38 -0
- package/catalog/models/openrouter/glm-5.3-flash.yaml +35 -0
- package/catalog/providers/openrouter.yaml +2 -0
- package/graphs/implement-loop.yaml +31 -0
- package/graphs/ops/harness-gc.yaml +17 -0
- package/graphs/ops/recipes.yaml +3 -0
- package/graphs/overlays/README.md +1 -1
- package/graphs/overlays/stop-heal-ladder.yaml +105 -0
- 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/add-api-key.sh +1 -1
- package/scripts/bench-report.ts +46 -1
- package/scripts/ci-typecheck-changed.ts +73 -14
- package/scripts/fleet/bedrock-pod-secret.ts +122 -0
- package/scripts/fleet/node-setup-linux.sh +97 -0
- package/scripts/fleet/node-setup.sh +11 -0
- package/scripts/fleet/zai-pod-secret.ts +86 -0
- package/scripts/land-global-checks.ts +3 -0
- package/scripts/measure-log-diet-2.ts +213 -0
- package/scripts/measure-tsc-affected-roots.ts +289 -0
- package/scripts/release-loop/auto-approve-node.ts +6 -0
- package/scripts/release-loop/gate-closure.ts +286 -0
- package/scripts/release-loop/gate-executor.ts +28 -0
- package/scripts/release-loop/gate-node.ts +333 -37
- 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 +46 -13
- package/scripts/release-loop/resume.ts +110 -4
- package/scripts/release-loop/unattended-release.ts +22 -7
- package/scripts/tsc-baseline-cache.ts +172 -0
- package/scripts/usage-rollup.ts +72 -6
- 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/run-context.ts +10 -0
- package/src/agent-mission/driver.ts +18 -3
- package/src/agent-mission/resource-ladder.ts +8 -3
- package/src/agent-mission/review-loop.ts +8 -2
- package/src/agent-substrate/acp-implementer.ts +146 -0
- package/src/agent-substrate/pr-reviewer.ts +60 -13
- package/src/agent-substrate/self-review-cli.ts +170 -15
- package/src/autopilot/mission-critique.ts +18 -5
- package/src/autopilot/mission-feasibility-negotiate.ts +11 -10
- package/src/autopilot/mission-trace.ts +12 -1
- package/src/autopilot/system-lookback-run.ts +16 -10
- package/src/bench/bench.ts +183 -0
- package/src/budget/cost-tier-advisor.ts +91 -0
- package/src/budget/fetchers/grok.ts +15 -5
- package/src/budget/llm-cost.ts +37 -5
- package/src/budget/shadow-arms.ts +77 -0
- package/src/budget/types.ts +10 -2
- package/src/budget/unified-usage.ts +256 -10
- package/src/cli/bench-cli.ts +34 -0
- package/src/cli/doctor-cli.ts +21 -0
- package/src/cli/friendly-errors.ts +113 -0
- package/src/cli/guardian-cli.ts +26 -1
- package/src/cli/image-cli.ts +101 -0
- package/src/cli/intake-cli.ts +3 -1
- package/src/cli/log-event-names.ts +4 -0
- package/src/cli/memory-cli.ts +182 -0
- package/src/cli/model-watch-cli.ts +4 -1
- package/src/cli/pr-cli.ts +62 -5
- package/src/cli/pr-land-overlap-evidence.ts +160 -12
- package/src/cli/pr-land-pod-shadow.ts +54 -0
- package/src/cli/release-cli.ts +27 -16
- 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/rfc-status.ts +52 -2
- package/src/cli/seat-requests-cli.ts +25 -0
- package/src/cli/self-update.ts +104 -0
- package/src/cli/tasks-cli.ts +139 -10
- package/src/cli/usage-cli.ts +93 -8
- 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/core-turn/run-goal-loop.ts +5 -4
- package/src/dashboard/ad-run-setup-bindings.ts +279 -0
- package/src/dashboard/index.ts +18 -276
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +4 -138
- package/src/dashboard/slash-runtime/shell-slash.ts +145 -0
- package/src/dashboard/stale-install-check.ts +11 -0
- package/src/debug/log-diet.ts +53 -10
- package/src/debug/log.ts +19 -1
- package/src/domains/morning-essential.ts +18 -3
- package/src/domains/release-tool.ts +43 -0
- package/src/error-report/report.ts +21 -4
- package/src/execution-loop/launch-gate.ts +158 -2
- package/src/fleet/host-doctor.ts +375 -0
- package/src/github/pr-labels.ts +1 -0
- package/src/goals/judge.ts +20 -6
- package/src/graph-runner/graph-cli.ts +42 -1
- package/src/graph-runner/runner.ts +176 -11
- package/src/graph-wizard/archetypes.ts +14 -8
- package/src/graph-wizard/generate.ts +77 -1
- package/src/grok/usage.ts +23 -2
- package/src/grok.ts +13 -7
- package/src/grounding/ref-index.ts +253 -0
- package/src/harness/dispatch-backpressure.ts +10 -2
- package/src/harness/harness-clean.ts +199 -78
- package/src/harness/harness-cli-command.ts +176 -52
- package/src/harness/harness-gc.ts +331 -0
- package/src/harness/harness-stop.ts +82 -10
- package/src/harness/harness-substrate-default.ts +142 -7
- package/src/harness/launch-registry.ts +6 -0
- package/src/harness/worktree-branch-prefix.ts +9 -0
- package/src/hq/fence.ts +187 -0
- package/src/hq/seats.ts +38 -22
- package/src/images/image-ledger.ts +179 -0
- package/src/index.ts +110 -186
- package/src/instance/child-scope.ts +32 -1
- package/src/instance/dev-project.ts +133 -0
- package/src/instance/resolve.ts +24 -0
- package/src/instance/spawn-elanous.ts +45 -0
- package/src/intake-plane/collect-github.ts +7 -2
- package/src/intake-plane/lens.ts +46 -4
- package/src/intake-plane/ref-prefetch.ts +110 -0
- package/src/intake-plane/requirement-funnel.ts +53 -1
- package/src/intelligence-map/catalog-feed.ts +119 -0
- package/src/intelligence-map/model-catalog.ts +72 -0
- package/src/intelligence-map/model-watch-intake.ts +40 -0
- package/src/intelligence-map/model-watch-mission.ts +14 -1
- package/src/llm/bedrock-eventstream.ts +215 -0
- package/src/llm/bedrock-provider.ts +114 -41
- package/src/llm/bedrock.ts +174 -28
- package/src/llm/open-weight-discipline.ts +21 -0
- package/src/llm/openrouter-byok-cost.ts +96 -0
- package/src/llm/openrouter-deepseek.ts +151 -0
- package/src/llm/openrouter-upstream-pins.config.ts +25 -0
- package/src/llm/zai-coding-plan.ts +700 -0
- package/src/llm.ts +91 -24
- package/src/loops/checker.ts +148 -9
- package/src/loops/orchestrator/resync-shadow.ts +34 -7
- package/src/maturity/feature-maturity.ts +3 -3
- package/src/model-tier/llm-tier-map.ts +9 -5
- package/src/models/prompts.ts +2 -1
- package/src/mss/logging/log-store.ts +58 -11
- package/src/nexus/api/http-server.ts +22 -0
- package/src/nexus/api/missions.ts +73 -2
- package/src/nexus/api/ops-api.ts +18 -0
- package/src/nexus/index.ts +7 -75
- package/src/nexus/tools-kind.ts +78 -0
- package/src/oauth/codex-account-rotation.ts +43 -3
- package/src/oauth/codex-account-store.ts +339 -27
- package/src/oauth/codex-quota-policy.ts +33 -4
- package/src/oauth/fallback-chain.ts +53 -15
- package/src/onboarding/first-run.ts +37 -18
- package/src/onboarding/web-first.ts +20 -2
- package/src/ops/machine-heartbeat.ts +185 -0
- package/src/ops/overview-cache.ts +175 -0
- package/src/ops/overview.ts +8 -0
- package/src/preview/terminal.ts +15 -5
- package/src/project/project-store.ts +20 -0
- package/src/prompt-cache/openai.ts +3 -0
- package/src/prompt-cache/types.ts +5 -0
- package/src/prompt-enhance/enhance.ts +23 -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/placement.ts +16 -1
- package/src/release-loop/rehearsal.ts +1 -1
- package/src/requirements/requirement-ledger.ts +536 -0
- package/src/retro/daily.ts +5 -5
- package/src/seat-loop/duty-ledger.ts +64 -0
- package/src/seat-loop/seat-loop.ts +32 -10
- package/src/self-dev/decompose.ts +37 -3
- package/src/self-dev/dev-cli.ts +44 -10
- package/src/self-dev/dev-pipeline.ts +39 -9
- package/src/self-dev/draft-residue.ts +27 -5
- package/src/self-dev/draft-sweep.ts +151 -0
- package/src/self-dev/fabric-decompose-adapter.ts +9 -2
- package/src/self-dev/graph-journey-route.ts +6 -0
- package/src/self-dev/orchestrate-cli.ts +25 -3
- package/src/self-dev/orchestrate.ts +41 -6
- package/src/self-dev/run-supervisor.ts +218 -15
- package/src/self-dev/run-types.ts +13 -0
- package/src/self-dev/supervisor-verdict-edges.ts +1 -0
- package/src/self-implement/budget-gate.ts +53 -13
- package/src/self-implement/child-context-composition.ts +139 -0
- package/src/self-implement/child-llm-preference.ts +13 -5
- package/src/self-implement/claude-acp-implement.ts +67 -0
- package/src/self-implement/flex-signals.ts +59 -0
- package/src/self-implement/frozen-merges.ts +8 -3
- package/src/self-implement/gate-cli.ts +29 -10
- package/src/self-implement/gate-remote.ts +4 -1
- package/src/self-implement/goal-author-decompose.ts +10 -2
- package/src/self-implement/goal-author.ts +36 -11
- package/src/self-implement/goal-new-paths.ts +42 -0
- package/src/self-implement/graph-overlay-condition.ts +28 -0
- package/src/self-implement/graph-overlay-yaml.ts +41 -7
- package/src/self-implement/graph-templates.ts +33 -1
- package/src/self-implement/graph-yaml.ts +56 -0
- package/src/self-implement/heal-intake.ts +5 -1
- 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 +230 -32
- 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 +75 -5
- package/src/self-implement/scope-adjacency.ts +23 -0
- package/src/self-implement/seams.ts +89 -8
- package/src/self-implement/self-implement-cli.ts +9 -4
- package/src/self-implement/stop-autoheal.ts +69 -2
- package/src/session-runtime/retry-policy.ts +2 -1
- 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/launch.ts +5 -4
- package/src/steward/rejudge-tick.ts +142 -0
- package/src/steward/triage-budget.ts +62 -0
- package/src/steward/triage.ts +83 -22
- package/src/task-agent/actions.ts +62 -5
- package/src/task-agent/board.ts +92 -3
- package/src/task-agent/card-evidence.ts +88 -1
- package/src/task-agent/completion-evidence.ts +5 -0
- package/src/task-agent/cover.ts +166 -3
- package/src/task-agent/judge.ts +16 -0
- package/src/task-agent/land-order-ledger.ts +95 -0
- package/src/task-agent/live-move-history.ts +87 -1
- package/src/task-agent/live-moves.ts +350 -20
- package/src/task-agent/parent-host.ts +27 -3
- package/src/task-agent/rejudge-on-head.ts +223 -24
- package/src/task-agent/review-prior-fix.ts +146 -0
- package/src/task-agent/review-result-capture.ts +3 -1
- package/src/task-agent/run-adopt.ts +136 -0
- package/src/task-agent/shadow.ts +65 -9
- package/src/task-agent/task-hand.ts +57 -7
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +38 -5
- package/src/task-orchestrator/surfaces/pod-bedrock-child.ts +74 -0
- package/src/task-orchestrator/surfaces/pod-child-default.ts +50 -0
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +14 -1
- package/src/task-orchestrator/surfaces/pod-command-job.ts +14 -0
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +79 -6
- package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +122 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +17 -5
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +11 -5
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +23 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +73 -4
- package/src/task-orchestrator/surfaces/pod-zai-child.ts +101 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +432 -35
- package/src/task-orchestrator/surfaces/self-implement.ts +19 -1
- package/src/typecheck-ratchet.ts +1 -0
- package/src/user-config.ts +69 -15
- 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/src/workflow-runtime/triggers/registry.ts +59 -0
- package/src/workflow-runtime/triggers/webhook-source.ts +35 -5
- 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-b23d2e92161d11fd.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-fbef064c213b2b18.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-d5341ac96203a983.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-6168a7c43e6ef8f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.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-2bd9ce9c020d02d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.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-745d9b6c015076f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.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/css/5619d59e87eddf66.css +0 -1
- /package/apps/pwa/out/_next/static/{rfkMm4movqkqMebBrCXiR → dRS6lEhSRRBr1abbzp7fJ}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// ── ACP Claude Code 를 «구현» 실행기로 (CLAUDE-IMPL-LANE · `--child-llm-provider claude-acp`) ──
|
|
2
|
+
//
|
|
3
|
+
// acp-reviewer.ts 의 짝이다. 리뷰어는 read-only 라 읽기 툴만 허가하지만, 구현 실행기는 런 워크트리 안에서
|
|
4
|
+
// 쓰기·실행을 허가해야 한다. 대표 대표 결정(10-12): ACP 세션 권한 모드는 호스트 설정(auto)을 그대로 두고
|
|
5
|
+
// 바꾸지 않으며, approver 가 불려도 «워크트리 밖 경로 쓰기»를 거부하지 않고 허가하되 insideWorktree 로 관측한다.
|
|
6
|
+
// 자식은 claude 구독 ACP 어댑터(`claude-agent-acp`)이며 env 는 subscriptionReviewerSpawn 의 과금 스크럽
|
|
7
|
+
// (ANTHROPIC_API_KEY 등 제거)을 그대로 쓴다 — 지우지 않으면 구독이 아니라 API 로 과금된다.
|
|
8
|
+
import { isAbsolute, relative, resolve } from 'node:path';
|
|
9
|
+
import { AcpAgent, type AcpAgentOpts } from '../acp/client.js';
|
|
10
|
+
import { debug } from '../debug/log.js';
|
|
11
|
+
import { subscriptionReviewerSpawn } from '../self-dev/review-provider-fallback.js';
|
|
12
|
+
import type { SubscriptionReviewerSpec } from '../user-config.js';
|
|
13
|
+
import { isReadOnlyReviewTool } from './acp-reviewer.js';
|
|
14
|
+
|
|
15
|
+
const WRITE_TOOL_KINDS = new Set(['edit', 'delete', 'move']);
|
|
16
|
+
const PATH_INPUT_KEYS = ['file_path', 'filePath', 'path', 'notebook_path', 'destination', 'source'] as const;
|
|
17
|
+
|
|
18
|
+
export interface ImplementerPermissionRequest {
|
|
19
|
+
title: string;
|
|
20
|
+
kind?: string;
|
|
21
|
+
rawInput?: unknown;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ImplementerPermissionDecision {
|
|
25
|
+
tool: string;
|
|
26
|
+
path: string | null;
|
|
27
|
+
/** 판정에 쓴 경로가 워크트리 안인가 — 경로가 없으면 null. 밖이어도 허가한다(대표 10-12); 이 칸이 그 관측이다. */
|
|
28
|
+
insideWorktree: boolean | null;
|
|
29
|
+
decision: 'allow' | 'deny';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function requestedPaths(rawInput: unknown): string[] {
|
|
33
|
+
if (!rawInput || typeof rawInput !== 'object') return [];
|
|
34
|
+
const input = rawInput as Record<string, unknown>;
|
|
35
|
+
return PATH_INPUT_KEYS.flatMap((key) => (typeof input[key] === 'string' && input[key] ? [input[key] as string] : []));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function insideWorktree(worktree: string, target: string): boolean {
|
|
39
|
+
const rel = relative(resolve(worktree), resolve(worktree, target));
|
|
40
|
+
return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** 허가 판정(순수 함수). 쓰기 계열(edit·delete·move)은 경로가 있으면 워크트리 안팎을 가리지 않고 허가한다
|
|
44
|
+
* (대표 10-12 — 밖 쓰기 거부를 걷었다 · insideWorktree 로 관측만 한다). 실행(execute)·읽기 계열은 허가,
|
|
45
|
+
* 그 외(모르는 kind)는 경로가 있을 때만 허가 — 경로 없는 쓰기·모르는 요청은 여전히 거부. */
|
|
46
|
+
export function decideImplementerPermission(req: ImplementerPermissionRequest, worktree: string): ImplementerPermissionDecision {
|
|
47
|
+
const paths = requestedPaths(req.rawInput);
|
|
48
|
+
const outside = paths.find((p) => !insideWorktree(worktree, p));
|
|
49
|
+
const tool = req.title.slice(0, 80);
|
|
50
|
+
const shown = outside ?? paths[0] ?? null;
|
|
51
|
+
const inside = paths.length === 0 ? null : outside === undefined;
|
|
52
|
+
const verdict = (allow: boolean): ImplementerPermissionDecision => ({ tool, path: shown, insideWorktree: inside, decision: allow ? 'allow' : 'deny' });
|
|
53
|
+
if (req.kind && WRITE_TOOL_KINDS.has(req.kind)) return verdict(paths.length > 0);
|
|
54
|
+
if (req.kind === 'execute') return verdict(true);
|
|
55
|
+
if (isReadOnlyReviewTool(req.kind, req.title)) return verdict(true);
|
|
56
|
+
return verdict(paths.length > 0);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface AcpImplementerOpts {
|
|
60
|
+
/** 런 워크트리 — ACP 자식의 cwd 이자 쓰기 허용 경계. */
|
|
61
|
+
worktree: string;
|
|
62
|
+
/** 자식 env 의 원천(기본 process.env). 과금 키는 subscriptionReviewerSpawn 이 제거한다. */
|
|
63
|
+
env?: NodeJS.ProcessEnv;
|
|
64
|
+
/** cct 실행기가 `teamclaude env --no-mitm` 에서 읽은 프록시 주소. */
|
|
65
|
+
proxyBaseUrl?: string;
|
|
66
|
+
spec?: SubscriptionReviewerSpec;
|
|
67
|
+
/** 모델 별칭 — 지정 시 session/set_model 로 고정. */
|
|
68
|
+
model?: string;
|
|
69
|
+
/** 이어갈 ACP 세션 id — 주면 newSession 대신 loadSession 으로 이어간다. */
|
|
70
|
+
resumeSessionId?: string;
|
|
71
|
+
/** 구현 1턴 최대 대기(ms). 초과 시 cancel → throw. 기본 1_800_000. */
|
|
72
|
+
timeoutMs?: number;
|
|
73
|
+
/** spawn → initialize → session 준비까지의 단일 기한(ms). 기본 60_000. */
|
|
74
|
+
handshakeTimeoutMs?: number;
|
|
75
|
+
/** 테스트용 ACP 에이전트 생성기. */
|
|
76
|
+
createAgent?: (opts: AcpAgentOpts) => AcpAgent;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface AcpImplementerResult {
|
|
80
|
+
text: string;
|
|
81
|
+
sessionId: string;
|
|
82
|
+
allowed: number;
|
|
83
|
+
denied: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const OBS = 'agent-substrate.acp-implementer';
|
|
87
|
+
|
|
88
|
+
export function makeAcpImplementer(opts: AcpImplementerOpts): (prompt: string) => Promise<AcpImplementerResult> {
|
|
89
|
+
return async (prompt) => {
|
|
90
|
+
const spawn = subscriptionReviewerSpawn(opts.spec ?? { provider: 'claude-acp' }, opts.env ?? process.env, opts.proxyBaseUrl);
|
|
91
|
+
const timeoutMs = opts.timeoutMs ?? 1_800_000;
|
|
92
|
+
const handshakeTimeoutMs = opts.handshakeTimeoutMs ?? 60_000;
|
|
93
|
+
let allowed = 0;
|
|
94
|
+
let denied = 0;
|
|
95
|
+
const agentOpts: AcpAgentOpts = {
|
|
96
|
+
backendId: 'claude',
|
|
97
|
+
backendSpec: spawn.backendSpec,
|
|
98
|
+
env: spawn.env,
|
|
99
|
+
cwd: opts.worktree,
|
|
100
|
+
log: (message) => debug.log(OBS, 'agent-log', { message }),
|
|
101
|
+
permissionApprover: async (req) => {
|
|
102
|
+
const verdict = decideImplementerPermission(req, opts.worktree);
|
|
103
|
+
if (verdict.decision === 'allow') allowed++; else denied++;
|
|
104
|
+
debug.log(OBS, 'permission', {
|
|
105
|
+
tool: verdict.tool, path: verdict.path, insideWorktree: verdict.insideWorktree, allowed: verdict.decision === 'allow',
|
|
106
|
+
});
|
|
107
|
+
return verdict.decision === 'allow';
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
const agent = opts.createAgent ? opts.createAgent(agentOpts) : new AcpAgent(agentOpts);
|
|
111
|
+
let handshakeTimer: ReturnType<typeof setTimeout> | undefined;
|
|
112
|
+
const withinHandshake = <T>(step: Promise<T>): Promise<T> => Promise.race([step, new Promise<never>((_, reject) => {
|
|
113
|
+
handshakeTimer = setTimeout(() => reject(new Error(`ACP handshake timeout (${handshakeTimeoutMs}ms)`)), handshakeTimeoutMs);
|
|
114
|
+
})]).finally(() => { if (handshakeTimer) clearTimeout(handshakeTimer); });
|
|
115
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
116
|
+
let timedOut = false;
|
|
117
|
+
let text = '';
|
|
118
|
+
try {
|
|
119
|
+
await withinHandshake(agent.start());
|
|
120
|
+
let sid: string;
|
|
121
|
+
if (opts.resumeSessionId) {
|
|
122
|
+
await withinHandshake(agent.loadSession({ sessionId: opts.resumeSessionId, cwd: opts.worktree }));
|
|
123
|
+
sid = opts.resumeSessionId;
|
|
124
|
+
} else {
|
|
125
|
+
sid = await withinHandshake(agent.newSession());
|
|
126
|
+
}
|
|
127
|
+
if (opts.model) await withinHandshake(agent.selectSessionModel(sid, opts.model));
|
|
128
|
+
debug.log(OBS, 'start', { cwd: opts.worktree, model: opts.model ?? '(default)', resumed: Boolean(opts.resumeSessionId) });
|
|
129
|
+
timer = setTimeout(() => { timedOut = true; agent.cancel(sid).catch(() => { /* noop */ }); }, timeoutMs);
|
|
130
|
+
await agent.prompt(sid, [{ type: 'text', text: prompt }], (u) => {
|
|
131
|
+
if (u.sessionUpdate === 'agent_message_chunk' && u.content.type === 'text' && u.content.text) text += u.content.text;
|
|
132
|
+
});
|
|
133
|
+
if (timedOut) throw new Error(`ACP 구현 타임아웃(${timeoutMs}ms)`);
|
|
134
|
+
debug.log(OBS, 'done', { chars: text.length, allowed, denied });
|
|
135
|
+
return { text, sessionId: sid, allowed, denied };
|
|
136
|
+
} catch (e) {
|
|
137
|
+
debug.log(OBS, 'error', { message: (e as Error).message, allowed, denied }, { level: 'error' });
|
|
138
|
+
throw e;
|
|
139
|
+
} finally {
|
|
140
|
+
if (timer) clearTimeout(timer);
|
|
141
|
+
try { await agent.stop(); } catch (e) {
|
|
142
|
+
debug.log(OBS, 'stop-fail', { message: (e as Error).message }, { level: 'error' });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
@@ -652,20 +652,48 @@ export function buildReviewPrompt(
|
|
|
652
652
|
* `none of the tests …`. 표지 낱말로 시작하는 실제 블로커를 지우면 PASS/WARN 리뷰에서 블로커가 사라진다. */
|
|
653
653
|
const NONE_WORD = String.raw`(?:없음|해당\s*없음|n\/a|none|nothing)`;
|
|
654
654
|
const BARE_SENTINEL = new RegExp(String.raw`^${NONE_WORD}\s*[.。]?$`, 'i');
|
|
655
|
-
const BRACKETED_SENTINEL = new RegExp(String.raw`^[([(【]\s*${NONE_WORD}(?:\s*[
|
|
655
|
+
const BRACKETED_SENTINEL = new RegExp(String.raw`^[([(【]\s*${NONE_WORD}(?:\s*[—–\-:.,;·]\s*([^)\])】]*))?\s*[)\])】]$`, 'i');
|
|
656
656
|
// ⭐ 설명 «전체»가 「지적 없음」 한 문장일 때만 — 일부만 맞아도 접으면 `(none: no blockers are checked because …)` 같은 지적이 사라진다.
|
|
657
657
|
const NO_FINDING_REMARK = new RegExp([
|
|
658
658
|
String.raw`^(?:(?:블로커|차단)\s*)?(?:수준의?\s*)?(?:결함|문제|이슈|지적|블로커)(?:은|는|이|가)?\s*(?:발견되지\s*않(?:음|았(?:다|습니다)?)|없(?:음|다|습니다))[.。]?$`,
|
|
659
659
|
String.raw`^(?:no|zero)\s+(?:blocking\s+)?(?:blockers?|issues?|problems?|findings?|must-?fix(?:es)?)(?:\s+found)?\.?$`,
|
|
660
660
|
String.raw`^nothing\s+(?:blocking|to\s+fix)\.?$`,
|
|
661
|
+
// REVIEW-MUSTFIX-NONE-SENTINEL — `(없음 — 수용기준 충족)` · `(none — acceptance criteria met)` (GLM 실측 6건). «미충족» 은 ^ 앵커로 안 맞는다.
|
|
662
|
+
String.raw`^수용\s*기준(?:을|이)?\s*(?:(?:모두|전부)\s*)?충족(?:함|됨|했다|합니다)?[.。]?$`,
|
|
663
|
+
String.raw`^(?:all\s+)?acceptance\s+criteria\s+(?:are\s+)?(?:all\s+)?met\.?$`,
|
|
661
664
|
].join('|'), 'i');
|
|
662
|
-
|
|
665
|
+
// REVIEW-MUSTFIX-NONE-SENTINEL 후속 — GLM 이 괄호 안에 «무소견 머리 + 긴 근거»를 쓴다(10-11 TC `pr land` 가 `review-must-fix-1` 로 거부):
|
|
666
|
+
// `(없음 — 수용기준 충족: 머리말에 … 반영됨 …)` · `(없음 — 수용기준 3항 모두 충족: … (\`'failed'\` 반환) · …)`(근거 안에 괄호가 또 있다).
|
|
667
|
+
// ⭐ 길이 무관 0 은 «머리»가 무소견 서술이고 바로 구분자가 올 때만 — 머리가 결함 서술이면(`(없음 — 하지만 X 가 깨진다)`) 지적으로 남긴다.
|
|
668
|
+
// ⛔ 근거에 역접·미충족(`하지만`·`다만`·`미충족`·`but`·`except`·`not met` …)이 있으면 보수적으로 지적으로 남긴다.
|
|
669
|
+
const LONG_BRACKETED_SENTINEL = new RegExp(String.raw`^[([(【]\s*${NONE_WORD}\s*[—–\-:·]\s*([\s\S]+?)\s*[)\])】]$`, 'i');
|
|
670
|
+
const NO_FINDING_HEAD = new RegExp('^(?:' + [
|
|
671
|
+
String.raw`수용\s*기준(?:\s*\d+\s*(?:항|개|건)(?:목)?)?(?:을|이)?\s*(?:(?:모두|전부)\s*)?충족(?:함|됨|했다|합니다)?`,
|
|
672
|
+
String.raw`(?:all\s+)?acceptance\s+criteria\s+(?:are\s+)?(?:all\s+)?met`,
|
|
673
|
+
String.raw`must-?fix\s*(?:항목)?(?:은|는|이|가)?\s*(?:없(?:음|다|습니다)|0\s*건)`,
|
|
674
|
+
String.raw`(?:no|zero)\s+(?:blocking\s+)?(?:blockers?|must-?fix(?:es)?)(?:\s+found)?`,
|
|
675
|
+
String.raw`(?:(?:블로커|차단)\s*)?(?:수준의?\s*)?(?:결함|블로커)(?:은|는|이|가)?\s*(?:발견되지\s*않(?:음|았(?:다|습니다)?)|없(?:음|다|습니다))`,
|
|
676
|
+
].join('|') + String.raw`)\s*(?:[::—–\-·,;.。(]|$)`, 'i');
|
|
677
|
+
const LONG_REMARK_DISSENT = /하지만|그러나|다만|(?<![가-힣])단(?:,|\s)|미\s*충족|불\s*충족|충족하지|충족되지|\bbut\b|\bhowever\b|\bexcept\b|\balthough\b|\bnot\s+(?:yet\s+)?met\b|\bunmet\b/i;
|
|
678
|
+
/** 괄호 안이 «없음 + 구분자 + 무소견 머리 …» 인가 — 길이 무관(근거 안 괄호도 허용). `isNoneSentinelFinding` 의 갈래. */
|
|
679
|
+
function isLongNoFindingBracket(text: string): boolean {
|
|
680
|
+
const m = LONG_BRACKETED_SENTINEL.exec(text.trim());
|
|
681
|
+
if (!m) return false;
|
|
682
|
+
const remark = m[1]!.trim();
|
|
683
|
+
return NO_FINDING_HEAD.test(remark) && !LONG_REMARK_DISSENT.test(remark);
|
|
684
|
+
}
|
|
685
|
+
/** must-fix 항목이 «지적 없음» 표지인가 — must-fix 를 세는 자리는 전부 `parseReviewResult` 를 거친다
|
|
686
|
+
* (`self review --json` 의 `mustFix` → TA `parseReviewResultOutput` → `pr land --overlap-evidence` 의 `review-must-fix-N`).
|
|
687
|
+
* ⭐ export — `parseReviewResultOutput` 가 «같은» 판정으로 저장된 결과의 표지 줄을 다시 접는다(PR-LAND-MUSTFIX-NONE · 복제 금지). */
|
|
688
|
+
export function isNoneSentinelFinding(finding: string): boolean {
|
|
663
689
|
const text = finding.trim();
|
|
664
690
|
if (BARE_SENTINEL.test(text)) return true;
|
|
665
691
|
const bracketed = BRACKETED_SENTINEL.exec(text);
|
|
666
|
-
if (
|
|
667
|
-
|
|
668
|
-
|
|
692
|
+
if (bracketed) {
|
|
693
|
+
const remark = bracketed[1]?.trim();
|
|
694
|
+
if (!remark || NO_FINDING_REMARK.test(remark)) return true;
|
|
695
|
+
}
|
|
696
|
+
return isLongNoFindingBracket(text);
|
|
669
697
|
}
|
|
670
698
|
|
|
671
699
|
/** critic 응답 파싱 → ReviewResult. 순수함수. VERDICT + MUST-FIX/SHOULD-FIX/REQUIREMENTS 섹션 분해.
|
|
@@ -738,6 +766,25 @@ function reviewedResultFromRaw(raw: string, runId: string | undefined, pass?: {
|
|
|
738
766
|
return { verdict: 'pass', mustFix: [], shouldFix: [], reviewed: false, failureReason: NO_VERDICT_LINE_REASON };
|
|
739
767
|
}
|
|
740
768
|
|
|
769
|
+
/** REVIEW-PROMPT-SIZE — llmReview 호출 하나(단일·청크 패스)마다 프롬프트·응답 크기를 남긴다.
|
|
770
|
+
* 관측이 리뷰를 막지 않는다(다른 review.* 관측과 같은 계약). */
|
|
771
|
+
function logReviewPromptSize(
|
|
772
|
+
prompt: string,
|
|
773
|
+
response: string,
|
|
774
|
+
pass: { pass: number; chunked: boolean },
|
|
775
|
+
runId: string | undefined,
|
|
776
|
+
): void {
|
|
777
|
+
try {
|
|
778
|
+
debug.log('review.prompt-size', 'call', {
|
|
779
|
+
pass: pass.pass,
|
|
780
|
+
promptChars: prompt.length,
|
|
781
|
+
responseChars: response.length,
|
|
782
|
+
chunked: pass.chunked,
|
|
783
|
+
...(runId !== undefined ? { runId } : {}),
|
|
784
|
+
});
|
|
785
|
+
} catch { /* Observation must not prevent the review. */ }
|
|
786
|
+
}
|
|
787
|
+
|
|
741
788
|
function failureReasonText(error: unknown): string {
|
|
742
789
|
if (error instanceof Error) return safeLogText(error.message, 400);
|
|
743
790
|
if (typeof error === 'string') return safeLogText(error, 400);
|
|
@@ -889,10 +936,11 @@ export async function reviewPullRequest(
|
|
|
889
936
|
+ ' 「여기 안 보인다」를 결함으로 판정하지 마십시오.',
|
|
890
937
|
].filter(Boolean).join('\n'),
|
|
891
938
|
};
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
939
|
+
const passPrompt = buildReviewPrompt(passInput, passBudget, '', passContext[index]?.budget);
|
|
940
|
+
const passImages = reviewImages.length > 0 && index === 0 ? reviewImages : undefined;
|
|
941
|
+
const passRaw = await llmReview(passPrompt, passImages);
|
|
942
|
+
logReviewPromptSize(passPrompt, passRaw, { pass: index + 1, chunked: true }, input.reviewContext?.runId);
|
|
943
|
+
passResults.push(reviewedResultFromRaw(passRaw, input.reviewContext?.runId, { index, of: plan.passes.length }));
|
|
896
944
|
}
|
|
897
945
|
return {
|
|
898
946
|
...foldReviewResults(passResults),
|
|
@@ -916,10 +964,9 @@ export async function reviewPullRequest(
|
|
|
916
964
|
} : {}),
|
|
917
965
|
};
|
|
918
966
|
}
|
|
919
|
-
const
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
);
|
|
967
|
+
const prompt = buildReviewPrompt(input, diffBudget, referencedContext.text, singleContextBudget);
|
|
968
|
+
const raw = await llmReview(prompt, reviewImages.length > 0 ? reviewImages : undefined);
|
|
969
|
+
logReviewPromptSize(prompt, raw, { pass: 1, chunked: false }, input.reviewContext?.runId);
|
|
923
970
|
return {
|
|
924
971
|
...reviewedResultFromRaw(raw, input.reviewContext?.runId),
|
|
925
972
|
diffBudget: {
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
//
|
|
15
15
|
// index.ts 의 액션은 옵션 파싱과 실제 의존 배선만 남는다(얇은 껍데기).
|
|
16
16
|
|
|
17
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
18
|
+
import { tmpdir } from 'node:os';
|
|
19
|
+
import { join } from 'node:path';
|
|
17
20
|
import { tierModel } from '../llm/model-defaults.js';
|
|
18
21
|
import { buildReviewObservation, safeLogText } from './review-observation.js';
|
|
19
22
|
import { DEFAULT_REVIEW_BACKEND } from './acp-reviewer.js';
|
|
@@ -24,6 +27,9 @@ import type { ReferencedFileReader } from '../self-implement/goal-file-reader.js
|
|
|
24
27
|
import type { SubscriptionReviewerSpec } from '../user-config.js';
|
|
25
28
|
import { listRunLedgers, lookupPrGoalAcceptance, lookupRunLedger, type PrGoalAcceptanceLookup, type RunLedgerEntry, type RunLedgerLookup } from '../self-implement/run-ledger.js';
|
|
26
29
|
|
|
30
|
+
/** SUBSCRIPTION-EXHAUST-REROUTE — API reviewer when the configured `roleLlm.reviewer` lane is unavailable (off codex). */
|
|
31
|
+
export const ROLE_REVIEWER_FALLBACK_MODEL = 'openrouter/z-ai/glm-5.3';
|
|
32
|
+
|
|
27
33
|
export interface SelfReviewCliOpts {
|
|
28
34
|
intent?: string | undefined;
|
|
29
35
|
model?: string | undefined;
|
|
@@ -54,8 +60,13 @@ export interface SelfReviewCliDeps {
|
|
|
54
60
|
* (`#7486` 리뷰 must-fix · 실제로 `index.ts` 래퍼가 그렇게 한 번 떨어뜨렸다). */
|
|
55
61
|
reviewPullRequest(input: ReviewInput, llm: (prompt: string, images?: readonly ReviewImage[]) => Promise<string>): Promise<ReviewResult>;
|
|
56
62
|
renderReview(review: ReviewResult): string;
|
|
57
|
-
/**
|
|
58
|
-
|
|
63
|
+
/**
|
|
64
|
+
* 기본 경로 리뷰어 LLM(API).
|
|
65
|
+
* `o.pinProvider` — 명시 `--model` 일 때 true: 구현은 streamLLM 의 provider 를 그 모델의 provider 로 고정해
|
|
66
|
+
* 라우터 폴백(grok 등)으로 조용히 넘어가지 않고 실패를 오류로 낸다.
|
|
67
|
+
* `o.onResolved` — streamLLM 이 «실제로 응답한» provider·model 을 알린다.
|
|
68
|
+
*/
|
|
69
|
+
makeApiLlm(model: string, o?: { pinProvider?: boolean; onResolved?: (provider: string, model: string) => void }): (prompt: string) => Promise<string>;
|
|
59
70
|
/** `--acp` 경로 리뷰어 LLM(독립 프로세스). */
|
|
60
71
|
/**
|
|
61
72
|
* ⭐ `P4b` — 두 번째 인자가 **멀티미디어 통로**다.
|
|
@@ -67,15 +78,20 @@ export interface SelfReviewCliDeps {
|
|
|
67
78
|
*
|
|
68
79
|
* ⚠️ API 백엔드(`makeApiLlm`)는 이 인자를 안 받는다 — ACP 경로만 이미지를 나른다.
|
|
69
80
|
*/
|
|
70
|
-
makeAcpLlm(o: { backend: string; model?: string; timeoutMs: number }): (prompt: string, images?: readonly ReviewImage[]) => Promise<string>;
|
|
81
|
+
makeAcpLlm(o: { backend: string; model?: string; timeoutMs: number; cwd?: string }): (prompt: string, images?: readonly ReviewImage[]) => Promise<string>;
|
|
71
82
|
/**
|
|
72
83
|
* Reviewer ACP lane selected by `roleLlm.reviewer` (no explicit flag). Returns the LLM when the
|
|
73
84
|
* subscription is usable, or a reason code when it is not — the caller then reviews on the API
|
|
74
85
|
* exactly as before. Absent seam = the lane is unavailable (`role-reviewer-seam-missing`).
|
|
75
86
|
*/
|
|
76
|
-
makeRoleReviewerLlm?(spec: SubscriptionReviewerSpec, o: { timeoutMs: number }):
|
|
87
|
+
makeRoleReviewerLlm?(spec: SubscriptionReviewerSpec, o: { timeoutMs: number; cwd?: string }):
|
|
77
88
|
| { llm: (prompt: string, images?: readonly ReviewImage[]) => Promise<string>; backend: string }
|
|
78
89
|
| { reason: string };
|
|
90
|
+
/**
|
|
91
|
+
* SUBSCRIPTION-EXHAUST-REROUTE — API model used when `roleLlm.reviewer` is configured (no explicit flag) but its
|
|
92
|
+
* lane is unavailable or fails. Absent seam or empty answer = the codex-ladder default as before.
|
|
93
|
+
*/
|
|
94
|
+
roleFallbackModel?(): string | undefined;
|
|
79
95
|
/** 관측 sink 등록 — ⭐ 이 호출이 분기 밖에 있는지가 이 트랙의 계약이다. */
|
|
80
96
|
registerSink(surface: string): Promise<void>;
|
|
81
97
|
/** `data` 는 payload 객체 — 순수 헬퍼가 만든 관측 타입도 그대로 받는다(인덱스 시그니처 강요 금지). */
|
|
@@ -95,6 +111,8 @@ export interface SelfReviewCliDeps {
|
|
|
95
111
|
|
|
96
112
|
export interface SelfReviewCliOutcome {
|
|
97
113
|
results: Array<Record<string, unknown>>;
|
|
114
|
+
/** 리뷰하지 못한 PR 수(`gh pr diff` 실패 · ACP 리뷰 reviewed=false) — json·비json 둘 다 센다. index.ts 가 1 이상이면 rc=1. */
|
|
115
|
+
failed: number;
|
|
98
116
|
}
|
|
99
117
|
|
|
100
118
|
interface GhResult {
|
|
@@ -1149,6 +1167,65 @@ export function renderReviewerContextStatus(loaded: LoadedReviewerContext, decom
|
|
|
1149
1167
|
return `Reviewer context: ${loaded.items.length} loaded, ${loaded.failed.length} not loaded.${source}${truncation}${decompositionStatus}${labels ? `\n${labels}` : ''}${failures ? `\n${failures}` : ''}`;
|
|
1150
1168
|
}
|
|
1151
1169
|
|
|
1170
|
+
/**
|
|
1171
|
+
* 머지된 PR 의 사후 리뷰 격리 — 리뷰어 cwd 가 main 최신이면 그 뒤 수리를 인용한다.
|
|
1172
|
+
* `merged` 는 그 PR 의 머지 커밋, `open` 은 종전(cwd 불변), `unpinnable` 은 MERGED 인데 머지 커밋을 못 구한 경우다.
|
|
1173
|
+
*/
|
|
1174
|
+
type PrMergeState =
|
|
1175
|
+
| { kind: 'open' }
|
|
1176
|
+
| { kind: 'merged'; commit: string }
|
|
1177
|
+
| { kind: 'unpinnable'; reason: 'merge-commit-unknown' };
|
|
1178
|
+
|
|
1179
|
+
function readPrMergeState(pr: string, deps: SelfReviewCliDeps): PrMergeState {
|
|
1180
|
+
const view = deps.gh(['pr', 'view', pr, '--json', 'state,mergeCommit'], 15_000);
|
|
1181
|
+
if (view.status !== 0) return { kind: 'open' };
|
|
1182
|
+
try {
|
|
1183
|
+
const parsed = JSON.parse(view.stdout) as { state?: unknown; mergeCommit?: { oid?: unknown } | null };
|
|
1184
|
+
if (parsed?.state !== 'MERGED') return { kind: 'open' };
|
|
1185
|
+
const oid = parsed.mergeCommit?.oid;
|
|
1186
|
+
return typeof oid === 'string' && COMMIT_OID.test(oid)
|
|
1187
|
+
? { kind: 'merged', commit: oid }
|
|
1188
|
+
: { kind: 'unpinnable', reason: 'merge-commit-unknown' };
|
|
1189
|
+
} catch {
|
|
1190
|
+
return { kind: 'open' };
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
interface ReviewWorktree {
|
|
1195
|
+
cwd: string;
|
|
1196
|
+
commit: string;
|
|
1197
|
+
/** 멱등 — 두 번 불러도 안전하다. */
|
|
1198
|
+
remove(): void;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
type ReviewWorktreeResult = ReviewWorktree | { reason: 'no-git-seam' | 'worktree-add-failed' };
|
|
1202
|
+
|
|
1203
|
+
function createDetachedReviewWorktree(commit: string, deps: SelfReviewCliDeps): ReviewWorktreeResult {
|
|
1204
|
+
const git = deps.git;
|
|
1205
|
+
if (!git) return { reason: 'no-git-seam' };
|
|
1206
|
+
const parent = mkdtempSync(join(tmpdir(), 'elanous-review-pin-'));
|
|
1207
|
+
const cwd = join(parent, 'wt');
|
|
1208
|
+
const add = () => git(['worktree', 'add', '--detach', cwd, commit], 120_000);
|
|
1209
|
+
let added = add();
|
|
1210
|
+
if (added.status !== 0) {
|
|
1211
|
+
git(['fetch', 'origin', commit], 120_000);
|
|
1212
|
+
added = add();
|
|
1213
|
+
}
|
|
1214
|
+
let removed = false;
|
|
1215
|
+
const remove = (): void => {
|
|
1216
|
+
if (removed) return;
|
|
1217
|
+
removed = true;
|
|
1218
|
+
git(['worktree', 'remove', '--force', cwd], 60_000);
|
|
1219
|
+
rmSync(parent, { recursive: true, force: true });
|
|
1220
|
+
// ⛔ `git worktree prune` 은 부르지 않는다 — 저장소 «전체»의 stale 메타데이터를 지워 남의 worktree 까지 건드린다.
|
|
1221
|
+
};
|
|
1222
|
+
if (added.status !== 0) {
|
|
1223
|
+
remove();
|
|
1224
|
+
return { reason: 'worktree-add-failed' };
|
|
1225
|
+
}
|
|
1226
|
+
return { cwd, commit, remove };
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1152
1229
|
/** `elanous self review <pr...>` 본문. read-only — 머지하지 않는다. */
|
|
1153
1230
|
/**
|
|
1154
1231
|
* `self review --json` stdout 한 줄 — 결과가 하나면 객체, 여럿이면 배열. index.ts 액션이 이것을 그대로 쓴다.
|
|
@@ -1162,6 +1239,20 @@ export async function runSelfReviewCliCommand(
|
|
|
1162
1239
|
prArgs: string[],
|
|
1163
1240
|
opts: SelfReviewCliOpts,
|
|
1164
1241
|
deps: SelfReviewCliDeps,
|
|
1242
|
+
): Promise<SelfReviewCliOutcome> {
|
|
1243
|
+
const pins: ReviewWorktree[] = [];
|
|
1244
|
+
try {
|
|
1245
|
+
return await runSelfReviewCliCommandPinned(prArgs, opts, deps, pins);
|
|
1246
|
+
} finally {
|
|
1247
|
+
for (const pin of pins) pin.remove();
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
async function runSelfReviewCliCommandPinned(
|
|
1252
|
+
prArgs: string[],
|
|
1253
|
+
opts: SelfReviewCliOpts,
|
|
1254
|
+
deps: SelfReviewCliDeps,
|
|
1255
|
+
pins: ReviewWorktree[],
|
|
1165
1256
|
): Promise<SelfReviewCliOutcome> {
|
|
1166
1257
|
// 관측 sink는 모든 종료 경로보다 먼저 등록해 거부도 운영 로그에 남긴다.
|
|
1167
1258
|
await deps.registerSink('self-review');
|
|
@@ -1175,7 +1266,7 @@ export async function runSelfReviewCliCommand(
|
|
|
1175
1266
|
invalidPrArgs: safeInvalidPrArgs,
|
|
1176
1267
|
}, { level: 'warn' });
|
|
1177
1268
|
deps.error(`PR 인자가 올바르지 않습니다: ${safeInvalidPrArgs.join(', ')}. PR 번호는 숫자 형식이어야 합니다 (예: elanous self review 5502).`);
|
|
1178
|
-
return { results: [] };
|
|
1269
|
+
return { results: [], failed: 0 };
|
|
1179
1270
|
}
|
|
1180
1271
|
|
|
1181
1272
|
const useAcp = opts.acp === true;
|
|
@@ -1197,11 +1288,19 @@ export async function runSelfReviewCliCommand(
|
|
|
1197
1288
|
if (useAcp) {
|
|
1198
1289
|
acpReviewLLM = deps.makeAcpLlm({ backend: acpBackend, ...(acpModel ? { model: acpModel } : {}), timeoutMs: acpTimeoutSec * 1000 });
|
|
1199
1290
|
}
|
|
1200
|
-
const model = useAcp ? `acp:${acpBackend}${acpModel ? `/${acpModel}` : ''}` : (opts.model || deps.envModel() || tierModel('better'));
|
|
1201
1291
|
// ⭐ Reviewer selection source. An explicit flag always wins byte-for-byte; only without one does
|
|
1202
1292
|
// `roleLlm.reviewer` (the harness's reviewer row) pick the ACP lane. Worst case = today's API review.
|
|
1203
1293
|
const explicitReviewerFlag = opts.acp === true || Boolean(opts.acpBackend) || Boolean(opts.acpModel?.trim()) || Boolean(opts.model?.trim());
|
|
1204
1294
|
const reviewerSource: 'cli' | 'role-config' | 'default' = explicitReviewerFlag ? 'cli' : opts.roleReviewer ? 'role-config' : 'default';
|
|
1295
|
+
// SUBSCRIPTION-EXHAUST-REROUTE (0.2.24): when `roleLlm.reviewer` is configured but its lane is unavailable
|
|
1296
|
+
// (10-11 prod: «Claude subscription usage unavailable or at harness cap (60%)»), the API fallback was the codex
|
|
1297
|
+
// ladder default (`tierModel('better')` = gpt-6-sol) — the CLI read roleLlm.reviewer, then spent codex anyway.
|
|
1298
|
+
// ⇒ the role-config lane falls back to `roleFallbackModel()` (off codex) when the seam gives one. Explicit flag
|
|
1299
|
+
// and ELANOUS_PR_REVIEW_MODEL still win; no seam / no answer = today's default byte-for-byte.
|
|
1300
|
+
const envModel = deps.envModel();
|
|
1301
|
+
const roleFallbackModel = !useAcp && !opts.model && !envModel && reviewerSource === 'role-config'
|
|
1302
|
+
? deps.roleFallbackModel?.()?.trim() || undefined : undefined;
|
|
1303
|
+
const model = useAcp ? `acp:${acpBackend}${acpModel ? `/${acpModel}` : ''}` : (opts.model || envModel || roleFallbackModel || tierModel('better'));
|
|
1205
1304
|
let roleReviewer: { llm: (prompt: string, images?: readonly ReviewImage[]) => Promise<string>; model: string } | undefined;
|
|
1206
1305
|
let roleReviewerUnavailableReason: string | undefined;
|
|
1207
1306
|
let roleReviewerAvailabilityMs: number | undefined;
|
|
@@ -1223,6 +1322,7 @@ export async function runSelfReviewCliCommand(
|
|
|
1223
1322
|
deps.log('role-reviewer-fallback', {
|
|
1224
1323
|
reviewerSource, roleReviewerProvider: opts.roleReviewer.provider, roleReviewerAvailabilityMs,
|
|
1225
1324
|
stage: 'availability', reason: roleReviewerUnavailableReason, fallbackModel: safeLogText(model),
|
|
1325
|
+
fallbackModelSource: roleFallbackModel ? 'role-fallback' : 'default',
|
|
1226
1326
|
}, { level: 'warn' });
|
|
1227
1327
|
}
|
|
1228
1328
|
}
|
|
@@ -1234,6 +1334,7 @@ export async function runSelfReviewCliCommand(
|
|
|
1234
1334
|
...(roleReviewerUnavailableReason ? { roleReviewerFallbackReason: roleReviewerUnavailableReason } : {}),
|
|
1235
1335
|
});
|
|
1236
1336
|
const results: Array<Record<string, unknown>> = [];
|
|
1337
|
+
let failed = 0;
|
|
1237
1338
|
const providedReviewerContext = loadReviewerContext(opts, deps.readReferencedFile);
|
|
1238
1339
|
const hasProvidedReviewerContext = (opts.contextOrder?.length ?? 0) > 0 || (opts.context?.length ?? 0) > 0 || (opts.contextText?.length ?? 0) > 0;
|
|
1239
1340
|
for (const pr of prArgs) {
|
|
@@ -1247,6 +1348,7 @@ export async function runSelfReviewCliCommand(
|
|
|
1247
1348
|
// ⛔ `relation-unknown` 도 경고한다(위 주석 · 리뷰가 두 라운드 반복 지적) — 그 밖 unavailable 은 조용하다.
|
|
1248
1349
|
// ⭐ 경고 여부 판정은 `localHeadWarningDetails` 한 곳에 있다(호출부에서 같은 함수를 두 번 부르지 않는다).
|
|
1249
1350
|
const mismatchWarning = localHeadWarningDetails(localHeadComparison);
|
|
1351
|
+
const mergeState = readPrMergeState(pr, deps);
|
|
1250
1352
|
const view = deps.gh(['pr', 'view', pr, '--json', 'title,body'], 15_000);
|
|
1251
1353
|
let prView: { title?: string; body?: string } | undefined;
|
|
1252
1354
|
if (view.status === 0) {
|
|
@@ -1311,6 +1413,7 @@ export async function runSelfReviewCliCommand(
|
|
|
1311
1413
|
const contextOutput = reviewerContextOutput(reviewerContext, decompositionContext);
|
|
1312
1414
|
if (opts.json) results.push({ pr, error: err, ...contextOutput, ...comparisonData, ...(mismatchWarning ?? {}) });
|
|
1313
1415
|
else deps.error(`PR ${pr}: ${err}\n${reviewerContextStatus}`);
|
|
1416
|
+
failed += 1;
|
|
1314
1417
|
continue;
|
|
1315
1418
|
}
|
|
1316
1419
|
// ⭐ S2(2026-07-30) — 리뷰 증거를 **이 PR 이 저작한 변경**으로 좁힌다. 실측 7건에서 1건만
|
|
@@ -1373,9 +1476,44 @@ export async function runSelfReviewCliCommand(
|
|
|
1373
1476
|
else deps.print(`\n━━ PR ${pr} (${primaryModel}) ━━\n${renderStaleRefusal(diffRead)}\n${reviewerContextStatus}`);
|
|
1374
1477
|
continue;
|
|
1375
1478
|
}
|
|
1479
|
+
// ⭐ 머지된 PR 만 머지 커밋 detached worktree 에서 리뷰한다 — main 최신이 아니라 그 PR 이 머지된 시점의 코드를 본다.
|
|
1480
|
+
// 열린 PR 은 종전 그대로(cwd = process.cwd() · 리뷰어 심이 cwd 를 받지 않는다).
|
|
1481
|
+
let reviewPin: ReviewWorktree | undefined;
|
|
1482
|
+
let reviewCwdPinFallbackReason: string | undefined;
|
|
1483
|
+
// cwd 를 받는 레인(ACP · role 리뷰어)일 때만 worktree 를 뜬다 — API 리뷰어는 cwd 를 안 받으므로 떠도 그 위에서 돌지 않는다.
|
|
1484
|
+
const pinLane = useAcp || Boolean(roleReviewer && opts.roleReviewer && deps.makeRoleReviewerLlm);
|
|
1485
|
+
let rolePinned = false;
|
|
1486
|
+
if (!pinLane) {
|
|
1487
|
+
// 비-ACP 레인 — 격리하지 않는다(종전 그대로 · reviewCwdCommit 없음).
|
|
1488
|
+
} else if (mergeState.kind === 'merged') {
|
|
1489
|
+
const made = createDetachedReviewWorktree(mergeState.commit, deps);
|
|
1490
|
+
if ('cwd' in made) {
|
|
1491
|
+
reviewPin = made;
|
|
1492
|
+
pins.push(made);
|
|
1493
|
+
} else reviewCwdPinFallbackReason = made.reason;
|
|
1494
|
+
} else if (mergeState.kind === 'unpinnable') reviewCwdPinFallbackReason = mergeState.reason;
|
|
1495
|
+
const reviewCwd = reviewPin?.cwd;
|
|
1496
|
+
const prAcpReviewLLM = reviewCwd && useAcp
|
|
1497
|
+
? deps.makeAcpLlm({ backend: acpBackend, ...(acpModel ? { model: acpModel } : {}), timeoutMs: acpTimeoutSec * 1000, cwd: reviewCwd })
|
|
1498
|
+
: acpReviewLLM;
|
|
1499
|
+
let prRoleReviewer = roleReviewer;
|
|
1500
|
+
if (reviewCwd && roleReviewer && opts.roleReviewer && deps.makeRoleReviewerLlm) {
|
|
1501
|
+
try {
|
|
1502
|
+
const pinned = deps.makeRoleReviewerLlm(opts.roleReviewer, { timeoutMs: acpTimeoutSec * 1000, cwd: reviewCwd });
|
|
1503
|
+
if ('llm' in pinned) { prRoleReviewer = { llm: pinned.llm, model: `acp:${pinned.backend}` }; rolePinned = true; }
|
|
1504
|
+
else reviewCwdPinFallbackReason = 'role-reviewer-cwd-unavailable';
|
|
1505
|
+
} catch {
|
|
1506
|
+
reviewCwdPinFallbackReason = 'role-reviewer-cwd-unavailable';
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1376
1509
|
const startedAt = deps.now();
|
|
1377
1510
|
// Role-config lane builds the API reviewer only when it falls back (`made().api` stays 0 on ACP success).
|
|
1378
|
-
const
|
|
1511
|
+
const responded: { provider?: string; model?: string } = {};
|
|
1512
|
+
const makeApi = () => deps.makeApiLlm(model, {
|
|
1513
|
+
pinProvider: Boolean(opts.model?.trim()),
|
|
1514
|
+
onResolved: (provider, respondedModel) => { responded.provider = provider; responded.model = respondedModel; },
|
|
1515
|
+
});
|
|
1516
|
+
const llmReview = prRoleReviewer ? undefined : (prAcpReviewLLM ?? makeApi());
|
|
1379
1517
|
// ⛔ evidenceNote 는 **별도 채널**이다 — phaseIntent 에 섞으면 의도 채널이 오염된다(실측: 그렇게
|
|
1380
1518
|
// 했다가 intent 배선 테스트 3개가 즉시 깨졌다).
|
|
1381
1519
|
// ⛔ 사람 `--intent`(phaseIntent) 와 골 acceptance 는 다른 인자 — 충돌하지 않고, 충돌해도 intent 가 이긴다.
|
|
@@ -1395,10 +1533,10 @@ export async function runSelfReviewCliCommand(
|
|
|
1395
1533
|
let roleReview: ReviewResult | undefined;
|
|
1396
1534
|
let roleReviewerFallbackReason = roleReviewerUnavailableReason;
|
|
1397
1535
|
let roleReviewMs: number | undefined;
|
|
1398
|
-
if (
|
|
1536
|
+
if (prRoleReviewer) {
|
|
1399
1537
|
const roleStartedAt = deps.now();
|
|
1400
1538
|
try {
|
|
1401
|
-
const attempt = await deps.reviewPullRequest(reviewInput,
|
|
1539
|
+
const attempt = await deps.reviewPullRequest(reviewInput, prRoleReviewer.llm);
|
|
1402
1540
|
if (attempt.reviewed === true) roleReview = attempt;
|
|
1403
1541
|
// Code, not the reviewer's raw failure text (same rule as the throw path above).
|
|
1404
1542
|
else roleReviewerFallbackReason = 'acp-review-not-completed';
|
|
@@ -1414,8 +1552,8 @@ export async function runSelfReviewCliCommand(
|
|
|
1414
1552
|
}, { level: 'warn' });
|
|
1415
1553
|
}
|
|
1416
1554
|
}
|
|
1417
|
-
let review = roleReview ?? await deps.reviewPullRequest(reviewInput, llmReview ??
|
|
1418
|
-
let selectedModel = roleReview &&
|
|
1555
|
+
let review = roleReview ?? await deps.reviewPullRequest(reviewInput, llmReview ?? prAcpReviewLLM ?? makeApi());
|
|
1556
|
+
let selectedModel = roleReview && prRoleReviewer ? prRoleReviewer.model : model;
|
|
1419
1557
|
let reviewRoute: 'api' | 'acp' | 'acp-fallback' = useAcp || roleReview ? 'acp' : 'api';
|
|
1420
1558
|
let fallbackAttempted = false;
|
|
1421
1559
|
let fallbackBackend: string | undefined;
|
|
@@ -1435,7 +1573,7 @@ export async function runSelfReviewCliCommand(
|
|
|
1435
1573
|
try {
|
|
1436
1574
|
const fallbackReview = await deps.reviewPullRequest(
|
|
1437
1575
|
reviewInput,
|
|
1438
|
-
deps.makeAcpLlm({ backend, timeoutMs: acpTimeoutSec * 1000 }),
|
|
1576
|
+
deps.makeAcpLlm({ backend, timeoutMs: acpTimeoutSec * 1000, ...(reviewCwd ? { cwd: reviewCwd } : {}) }),
|
|
1439
1577
|
);
|
|
1440
1578
|
if (fallbackReview.reviewed === true) {
|
|
1441
1579
|
review = fallbackReview;
|
|
@@ -1451,6 +1589,14 @@ export async function runSelfReviewCliCommand(
|
|
|
1451
1589
|
}
|
|
1452
1590
|
}
|
|
1453
1591
|
}
|
|
1592
|
+
reviewPin?.remove();
|
|
1593
|
+
// reviewCwdCommit 은 «최종 판정을 낸 LLM 이 실제로 그 cwd 를 받았을 때만» 싣는다(role 실패 → API 폴백이면 안 싣는다).
|
|
1594
|
+
const reviewedOnPin = Boolean(reviewPin) && (roleReview ? rolePinned : reviewRoute === 'acp-fallback' ? true : reviewRoute === 'acp' && useAcp);
|
|
1595
|
+
if (reviewPin && !reviewedOnPin) reviewCwdPinFallbackReason ??= 'final-reviewer-not-pinned';
|
|
1596
|
+
const reviewCwdOutput = {
|
|
1597
|
+
...(reviewPin && reviewedOnPin ? { reviewCwdCommit: reviewPin.commit } : {}),
|
|
1598
|
+
...(reviewCwdPinFallbackReason ? { reviewCwdPinFallbackReason } : {}),
|
|
1599
|
+
};
|
|
1454
1600
|
if (!fallbackAttempted) {
|
|
1455
1601
|
fallbackNotAttemptedReason = useAcp ? 'explicit-acp' : 'primary-review-succeeded';
|
|
1456
1602
|
}
|
|
@@ -1463,6 +1609,11 @@ export async function runSelfReviewCliCommand(
|
|
|
1463
1609
|
...(fallbackFailures.length ? { fallbackFailures } : {}),
|
|
1464
1610
|
...(skippedAcpFallbackBackends.length ? { skippedAcpFallbackBackends } : {}),
|
|
1465
1611
|
};
|
|
1612
|
+
// API 경로로 «성공한» 리뷰만 응답 provider·model 을 싣는다(요청 model 과 다르면 둘 다 보인다).
|
|
1613
|
+
// ⚠️ streamLLM 의 onResolvedProvider 는 시도 «전»에 불린다 — 실패한 리뷰에 실으면 응답 안 한 provider 를 «응답했다»로 적는다.
|
|
1614
|
+
const respondedOutput = reviewRoute === 'api' && review.reviewed === true && responded.provider
|
|
1615
|
+
? { respondedProvider: responded.provider, respondedModel: responded.model }
|
|
1616
|
+
: {};
|
|
1466
1617
|
// ⚠️ `buildReviewObservation` drops unknown keys — the selection rides next to it, not inside it.
|
|
1467
1618
|
const reviewerSelection = {
|
|
1468
1619
|
...reviewerSourceObservation(),
|
|
@@ -1486,20 +1637,24 @@ export async function runSelfReviewCliCommand(
|
|
|
1486
1637
|
goalLoaded: goalAcceptance.goalLoaded,
|
|
1487
1638
|
acceptanceChars: goalAcceptance.acceptanceChars,
|
|
1488
1639
|
...reviewerSelection,
|
|
1640
|
+
...reviewCwdOutput,
|
|
1489
1641
|
},
|
|
1490
1642
|
{ level: review.reviewed === false ? 'warn' : 'info' });
|
|
1491
1643
|
// --acp 는 대표가 명시 요청한 리뷰 — fail-soft(reviewed=false)면 조용히 pass 하지 말고 표면화(관측=acp-review).
|
|
1492
1644
|
if (useAcp && review.reviewed === false) {
|
|
1493
1645
|
const err = 'ACP 리뷰 실행 실패(reviewed=false) — 관측: elanous logs --category acp-review';
|
|
1494
1646
|
const contextOutput = reviewerContextOutput(reviewerContext, decompositionContext);
|
|
1495
|
-
if (opts.json) results.push({ pr, error: err, ...review, verdict: null, ...reviewProvenance, ...reviewerSelection, ...provenance, ...contextOutput });
|
|
1647
|
+
if (opts.json) results.push({ pr, error: err, ...review, verdict: null, ...reviewProvenance, ...respondedOutput, ...reviewerSelection, ...reviewCwdOutput, ...provenance, ...contextOutput });
|
|
1496
1648
|
else deps.error(`PR ${pr}: ${err}\n${renderProvenance(diffRead)}\n${reviewerContextStatus}`);
|
|
1649
|
+
failed += 1;
|
|
1497
1650
|
continue;
|
|
1498
1651
|
}
|
|
1499
1652
|
const contextOutput = reviewerContextOutput(reviewerContext, decompositionContext);
|
|
1500
1653
|
const jsonReview = review.reviewed === true ? review : { ...review, verdict: null };
|
|
1501
|
-
if (opts.json) results.push({ pr, model: selectedModel, ...jsonReview, ...reviewProvenance, ...reviewerSelection, ...provenance, ...contextOutput, evidence: evidence.evidence, prDiffFiles: evidence.prDiffFiles, ...(evidence.authoredFiles !== undefined ? { authoredFiles: evidence.authoredFiles } : {}) });
|
|
1654
|
+
if (opts.json) results.push({ pr, model: selectedModel, ...jsonReview, ...reviewProvenance, ...respondedOutput, ...reviewerSelection, ...reviewCwdOutput, ...provenance, ...contextOutput, evidence: evidence.evidence, prDiffFiles: evidence.prDiffFiles, ...(evidence.authoredFiles !== undefined ? { authoredFiles: evidence.authoredFiles } : {}) });
|
|
1502
1655
|
else deps.print(`\n━━ PR ${pr} (${selectedModel}) ━━\n${renderProvenance(diffRead)}\n${evidenceLine}\n${reviewerContextStatus}\n${deps.renderReview(review)}`);
|
|
1656
|
+
// REVIEW-ERROR-RC — 기본(API)·role 경로가 1차·폴백 모두 실패해 reviewed≠true 로 끝나도 «못 리뷰한 PR» 이다(verdict:null).
|
|
1657
|
+
if (review.reviewed !== true) failed += 1;
|
|
1503
1658
|
}
|
|
1504
|
-
return { results };
|
|
1659
|
+
return { results, failed };
|
|
1505
1660
|
}
|
|
@@ -106,12 +106,25 @@ export function buildCritiquePrompt(input: { planBody: string; changedFiles: str
|
|
|
106
106
|
].join('\n');
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
/**
|
|
109
|
+
/** 판정 줄 — «줄 머리» VERDICT 만 판정으로 읽는다(본문 중간 인용·설명 속 «VERDICT:» 오인 방지).
|
|
110
|
+
* 들여쓰기는 허용(mission-engine 의 미션 판정 파서와 같은 앵커). */
|
|
111
|
+
const CRITIQUE_VERDICT_LINE = /^[ \t]*VERDICT:\s*(PASS|WARN|FAIL)/im;
|
|
112
|
+
/** 판정 줄이 없을 때 findings 에 남기는 fail-closed 사유(REVIEW-NO-VERDICT-FAILCLOSED #25937). */
|
|
113
|
+
const NO_VERDICT_FINDING = '비평 판정 줄(VERDICT) 없음 — 판정 없음은 통과가 아니다(fail-closed · REVIEW-NO-VERDICT-FAILCLOSED #25937)';
|
|
114
|
+
const MAX_CRITIQUE_FINDINGS = 4;
|
|
115
|
+
|
|
116
|
+
/** LLM 응답 파싱 → verdict + findings. 순수함수(LLM node 규칙).
|
|
117
|
+
* ⛔ 판정 줄이 «없으면» pass 로 기본하지 않는다(칸 MISSION-CRITIQUE-FAILCLOSED · #25937):
|
|
118
|
+
* «판정 없음 = 통과 아님» ⇒ verdict 'warn' + 사유 finding.
|
|
119
|
+
* 'fail' 이 아니라 'warn' 인 이유 — 소비측(nocturnal-runner)은 critique verdict==='fail' 에
|
|
120
|
+
* gate-failed(재구현 요구)를 건다. «비평가 응답의 형식 결함»을 «구현 훼손」으로
|
|
121
|
+
* 오귀속시키는 것이다. 'warn' 은 PR 본문(renderCritique)·자율 원장에 그대로 표시되어 사람(HITL)이 판단한다.
|
|
122
|
+
* (post-PR 리뷰 축 parseReviewResult 는 substrate 가 `reviewed:false` 로 같은 fail-closed 를 이미 한다.) */
|
|
110
123
|
export function parseLLMCritique(text: string): { verdict: CritiqueResult['verdict']; findings: string[] } {
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
return { verdict, findings };
|
|
124
|
+
const bullets = text.split('\n').map((l) => l.trim()).filter((l) => l.startsWith('- ')).map((l) => l.slice(2).trim());
|
|
125
|
+
const vm = CRITIQUE_VERDICT_LINE.exec(text);
|
|
126
|
+
if (!vm) return { verdict: 'warn', findings: [NO_VERDICT_FINDING, ...bullets].slice(0, MAX_CRITIQUE_FINDINGS) };
|
|
127
|
+
return { verdict: vm[1]!.toLowerCase() as CritiqueResult['verdict'], findings: bullets.slice(0, MAX_CRITIQUE_FINDINGS) };
|
|
115
128
|
}
|
|
116
129
|
|
|
117
130
|
/** ★ R1 결정론 + LLM 비평(대표 2026-07-12) — 결정론(R0) 먼저, llmReview 주입 시 LLM 심층 비평
|