elanous 0.2.24 → 0.2.27
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/{Q-7iofoxOEv1WX18S35of → Ev2jivDMTSoEc-5rIXdcy}/_buildManifest.js +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-a9c338f5bb556f42.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-a1ce306364f08da9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-07110da72c45e68f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-d2d76d4a7eae91bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-30007380f2e2a3c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e5a9302c105725a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-b93c04b5311c97ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-718a49e86bf25f9c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-20662900d6b4b455.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-f707a509515ac50c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-6a16a48d1aa6e91f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/{page-26345242e4049f55.js → page-fcb06e305f515527.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-6acf5ec4e6c6d1af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-39f82acf619cca23.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-7c2c8f81b185f9c0.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-ae7aff07e32676bb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-482c60c1bc540d0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-7cb996c1aa08b6f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-623e08fe4477d606.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-db460cd8aecb8490.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-ff27902d0b11ef4f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-8397a5c6ca569bf4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1917ea87ea71ab6b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-25a302273b054fd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-670510eda8b9443f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-d73c3f1e00d93986.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-65caacf54389081e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4bb7556e2e97a750.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-77e04b4f8762c666.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/{page-b92caddb5c715f30.js → page-15c0a4095baddfba.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/page-4eb96fc7241c2456.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-63e272a4cd3b6634.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d64ff212dc55d03.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-7f096248993fc2d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e47fc72049149a38.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-f7d808e31e005895.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-5c2b24b5496dad73.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-76cdb531668b5191.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-e2b63345bba1a11f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-d376e0c83edc041a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d6db55fe2c04d128.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-87b88f551f421d8b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-dab163b338e3b966.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-08019efef111ed2e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-0260ffc7eda50db1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-980ce6fe36ad95eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-99c4e6c7345a9156.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-0ab42e0f05823013.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ad9220422d20ba33.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/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 +88 -7
- package/scripts/coord-msg-bridge.ts +209 -0
- package/scripts/coord-post.sh +40 -7
- package/scripts/coord-requests-bridge.ts +10 -5
- package/scripts/expose-rubric-suggest.ts +1 -1
- package/scripts/measure-tsc-affected-roots.ts +10 -1
- package/scripts/release-loop/auto-approve-node.ts +6 -0
- package/scripts/release-loop/export-check-node.ts +8 -5
- 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/node-verdict.ts +7 -2
- 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/task-notification.ts +30 -1
- package/src/agent-substrate/acp-implementer.ts +14 -7
- package/src/agent-substrate/pr-reviewer.ts +30 -10
- package/src/agent-substrate/review-observation.ts +9 -2
- package/src/agent-substrate/self-review-cli.ts +154 -16
- package/src/boot/daemon-tools/self-implement.ts +72 -4
- package/src/budget/cost-tier-advisor.ts +91 -0
- package/src/budget/llm-cost.ts +5 -1
- 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/control-cli.ts +29 -0
- package/src/cli/doctor-cli.ts +106 -3
- 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/msg-cli.ts +15 -5
- package/src/cli/pr-cli.ts +53 -0
- package/src/cli/pr-land-overlap-evidence.ts +18 -10
- package/src/cli/pr-land-pod-shadow.ts +54 -0
- package/src/cli/release-cli.ts +41 -12
- 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-cli.ts +121 -0
- package/src/cli/seat-requests-cli.ts +25 -0
- package/src/cli/self-utterances-cli.ts +140 -0
- package/src/cli/tasks-cli.ts +168 -14
- package/src/cli/usage-cli.ts +3 -1
- package/src/compact/verify-probe.ts +23 -3
- package/src/context-card/cell.ts +40 -0
- package/src/context-card/index.ts +50 -0
- package/src/control/control-status.ts +30 -1
- package/src/dashboard/boot-timing.ts +35 -0
- package/src/dashboard/index.ts +86 -24
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +26 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +10 -138
- package/src/dashboard/slash-runtime/shell-slash.ts +145 -0
- package/src/debug/log-diet.ts +16 -4
- package/src/debug/log.ts +1 -1
- package/src/domains/morning-essential.ts +18 -3
- package/src/domains/release-tool.ts +29 -8
- package/src/domains/surface-events.ts +16 -0
- package/src/elanous-config-dir.ts +2 -2
- package/src/execution-loop/launch-gate.ts +158 -2
- package/src/fleet/host-doctor.ts +446 -0
- package/src/goals/judge.ts +20 -6
- package/src/graph-runner/runner.ts +12 -6
- 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 +102 -51
- package/src/harness/harness-stop.ts +93 -19
- package/src/index.ts +52 -179
- package/src/instance/current.ts +2 -6
- package/src/instance/resolve.ts +5 -6
- 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/openai-sampling-fields.ts +89 -0
- package/src/llm/runtime-model-family.ts +61 -0
- package/src/llm/zai-coding-plan.ts +27 -1
- package/src/llm.ts +17 -97
- package/src/machines/machine-ledger.ts +31 -3
- package/src/maturity/cli-maturity.ts +13 -3
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/msg/msg-store.ts +69 -7
- 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/ops/overview-collect.ts +3 -2
- package/src/ops/overview-owner.ts +29 -0
- package/src/plugin-hooks/shell-hook.ts +17 -2
- package/src/plugin-missions/evaluator-runner.ts +18 -2
- package/src/plugins/install/plugin-install.ts +11 -1
- package/src/preview/terminal.ts +15 -5
- package/src/project/project-store.ts +20 -0
- package/src/prompt-enhance/enhance.ts +11 -0
- package/src/release-loop/auto-start.ts +7 -5
- package/src/release-loop/checklist.ts +52 -5
- package/src/release-loop/feature-store.ts +10 -9
- 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/seat-loop/seat-loop.ts +5 -1
- 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 +75 -18
- package/src/self-dev/fabric-decompose-adapter.ts +9 -2
- package/src/self-dev/orchestrate.ts +6 -2
- package/src/self-dev/run-supervisor.ts +72 -8
- 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 +15 -29
- package/src/self-implement/goal-command-execution.ts +26 -0
- 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 +90 -20
- package/src/self-implement/premise-review.ts +159 -0
- package/src/self-implement/pwa-import-graph.ts +194 -7
- 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/self-implement/self-implement-runtime.ts +126 -21
- package/src/session/index.ts +14 -4
- package/src/session-runtime/index.ts +55 -11
- 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 +85 -1
- package/src/task-agent/live-moves.ts +14 -6
- package/src/task-agent/parent-host.ts +27 -3
- package/src/task-agent/rejudge-on-head.ts +370 -29
- package/src/task-agent/review-result-capture.ts +67 -2
- package/src/task-agent/shadow.ts +148 -21
- package/src/task-agent/task-hand.ts +22 -3
- 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 +236 -28
- package/src/tool-runtime/tool-search-runtime.ts +25 -0
- package/src/tui.ts +20 -1
- package/src/user-config.ts +21 -63
- 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/botlab/page-24282bf9f90031a5.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/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/release/page-1d809a87139dd024.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 → Ev2jivDMTSoEc-5rIXdcy}/_ssgManifest.js +0 -0
|
@@ -4,6 +4,7 @@ import { getUserConfig } from '../user-config.js';
|
|
|
4
4
|
import { resolve } from 'node:path';
|
|
5
5
|
import type { ModelFamily } from '../models/prompts.js';
|
|
6
6
|
import type { InputSourceKind, InputSourceRef } from '../input/input-source-kind.js';
|
|
7
|
+
import type { ControlTurnIntent, SubmitTurnIntent } from '../input/input-intent.js';
|
|
7
8
|
import { getSessionCwd } from '../session/working-dir.js';
|
|
8
9
|
import {
|
|
9
10
|
armQuickControlOnce,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
import type { LLMMessage, LLMToolSpec } from '../llm.js';
|
|
23
24
|
import type { LLMToolDef } from '../plugins/core/types.js';
|
|
24
25
|
import type { ToolRunResult, ToolRuntime } from '../tool-runtime/types.js';
|
|
26
|
+
import { blockWriteToolSearchHydration, type ToolSearchRunResult } from '../tool-runtime/tool-search-runtime.js';
|
|
25
27
|
import { findNativeTool, isNativeToolModelExposed } from '../native-tool-catalog.js';
|
|
26
28
|
import { hasAstGrep } from '../skills/tools/ast-grep.js';
|
|
27
29
|
import { buildOmniSearchTool, omniSearchAvailable } from '../skills/tools/omni-search.js';
|
|
@@ -1731,6 +1733,8 @@ const ESSENTIAL_NATIVE_RULE_IDS = [
|
|
|
1731
1733
|
'agent', 'agent-output', 'agent-reply', 'agent-stop', 'agent-list', 'self-implement', 'self-orchestrate', 'dev-harness',
|
|
1732
1734
|
] as const;
|
|
1733
1735
|
const ESSENTIAL_HOST_FAMILY_IDS = ['self-ops', 'release-read'] as const;
|
|
1736
|
+
// Keep this TUI essential addition out of the shared control/agent self-ops family.
|
|
1737
|
+
const ESSENTIAL_HOST_EXTRA_NAMES = ['logs_query'] as const;
|
|
1734
1738
|
const ESSENTIAL_RUNTIME_FAMILY_IDS = ['bash', 'run-shell', 'pty-shell', 'run-tests', 'elanous_skills_list', 'skill_exec', 'code-grounding'] as const;
|
|
1735
1739
|
const ESSENTIAL_OPTIONAL_TOOL_NAMES = [
|
|
1736
1740
|
'GetDashboardState',
|
|
@@ -1764,7 +1768,11 @@ function buildEssentialSessionRuntimeToolSpecs(opts: {
|
|
|
1764
1768
|
.filter((tool): tool is LLMToolDef => !!tool)
|
|
1765
1769
|
.map(toSpec)
|
|
1766
1770
|
: [];
|
|
1767
|
-
})
|
|
1771
|
+
}).concat(ESSENTIAL_HOST_EXTRA_NAMES
|
|
1772
|
+
.filter(name => isToolAvailable(name, opts.toolAvailability))
|
|
1773
|
+
.map(name => hostByName.get(name))
|
|
1774
|
+
.filter((tool): tool is LLMToolDef => !!tool)
|
|
1775
|
+
.map(toSpec));
|
|
1768
1776
|
const runtimeById = new Map(opts.runtimeTools.map(tool => [tool.id, tool] as const));
|
|
1769
1777
|
const runtimeSpecs = ESSENTIAL_RUNTIME_FAMILY_IDS.flatMap(id => {
|
|
1770
1778
|
const rule = RUNTIME_TOOL_FAMILY_RULE_MAP.get(id);
|
|
@@ -1833,12 +1841,23 @@ export function buildSessionRuntimeToolSpecs(opts: {
|
|
|
1833
1841
|
// toolset (incident 2026-05-04 — Opus replied "no file tools in this
|
|
1834
1842
|
// session" while Bash was actually exposed at position 7+).
|
|
1835
1843
|
const finalSpecs: LLMToolSpec[] = opts.rich === false
|
|
1836
|
-
?
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1844
|
+
? (() => {
|
|
1845
|
+
const essentialSpecs = buildEssentialSessionRuntimeToolSpecs({
|
|
1846
|
+
hostTools: opts.hostTools,
|
|
1847
|
+
runtimeTools: opts.runtimeTools ?? [],
|
|
1848
|
+
optionalTools: opts.optionalTools ?? [],
|
|
1849
|
+
toolAvailability: opts.toolAvailability,
|
|
1850
|
+
});
|
|
1851
|
+
if (!hasDevHarnessIntent(opts.userText)) return essentialSpecs;
|
|
1852
|
+
const droppedNames = new Set(['Edit', 'Write']);
|
|
1853
|
+
const filteredSpecs = essentialSpecs.filter(spec => !droppedNames.has(spec.name));
|
|
1854
|
+
if (filteredSpecs.length !== essentialSpecs.length) {
|
|
1855
|
+
debug.log('session-runtime.tools', 'harness-phrase-write-tools-dropped', {
|
|
1856
|
+
dropped: ['Edit', 'Write'],
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
return filteredSpecs;
|
|
1860
|
+
})()
|
|
1842
1861
|
: [
|
|
1843
1862
|
...dynamicNativeTools,
|
|
1844
1863
|
...hostSpecs,
|
|
@@ -2084,6 +2103,10 @@ export async function dispatchSessionRuntimeTool(
|
|
|
2084
2103
|
args: Record<string, unknown>,
|
|
2085
2104
|
deps: SessionRuntimeDispatchDeps,
|
|
2086
2105
|
): Promise<unknown> {
|
|
2106
|
+
const finishRuntimeResult = (result: unknown): unknown =>
|
|
2107
|
+
name === 'ToolSearch' && isDevHarnessIntent(deps.userText ?? '')
|
|
2108
|
+
? blockWriteToolSearchHydration(result as ToolSearchRunResult)
|
|
2109
|
+
: result;
|
|
2087
2110
|
// Fix W-bis (2026-04-25): codex family always enables scoped-analysis
|
|
2088
2111
|
// mode regardless of userText vocabulary. Rationale (see docs/RESEARCH-
|
|
2089
2112
|
// codex-reread-pathology-2refs-2026-04-25.md): codex's search-heavy
|
|
@@ -2178,8 +2201,9 @@ export async function dispatchSessionRuntimeTool(
|
|
|
2178
2201
|
const nativeRuntime = nativeRule?.preferRuntime ? deps.getToolRuntime(name) : undefined;
|
|
2179
2202
|
if (nativeRuntime) {
|
|
2180
2203
|
const result = await deps.dispatchToolRuntime(name, normalizedArgs, deps.toolCallId);
|
|
2181
|
-
|
|
2182
|
-
|
|
2204
|
+
const safeResult = finishRuntimeResult(result);
|
|
2205
|
+
rememberCandidateListingResult(name, normalizedArgs, safeResult, scopedAnalysis, deps.searchPlannerState);
|
|
2206
|
+
return safeResult;
|
|
2183
2207
|
}
|
|
2184
2208
|
if (nativeRule?.dispatch) {
|
|
2185
2209
|
let result: unknown;
|
|
@@ -2213,8 +2237,9 @@ export async function dispatchSessionRuntimeTool(
|
|
|
2213
2237
|
const isPtyTool = name.startsWith('PtyShell') || name.startsWith('pty_shell');
|
|
2214
2238
|
if (!isPtyTool || deps.ptyDashboardOn) {
|
|
2215
2239
|
const result = await deps.dispatchToolRuntime(name, normalizedArgs, deps.toolCallId);
|
|
2216
|
-
|
|
2217
|
-
|
|
2240
|
+
const safeResult = finishRuntimeResult(result);
|
|
2241
|
+
rememberCandidateListingResult(name, normalizedArgs, safeResult, scopedAnalysis, deps.searchPlannerState);
|
|
2242
|
+
return safeResult;
|
|
2218
2243
|
}
|
|
2219
2244
|
}
|
|
2220
2245
|
|
|
@@ -2699,6 +2724,25 @@ function hasDevHarnessIntent(text: string): boolean {
|
|
|
2699
2724
|
return hasAny(text, DEV_HARNESS_INTENT_TERMS);
|
|
2700
2725
|
}
|
|
2701
2726
|
|
|
2727
|
+
export function isDevHarnessIntent(text: string): boolean {
|
|
2728
|
+
return hasDevHarnessIntent(text);
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2731
|
+
/** The dashboard calls this immediately after submitIntent resolution. A
|
|
2732
|
+
* fixed plain turn becomes the same control turn used by `/harness ask`, so
|
|
2733
|
+
* the model dispatch branch is never reached for that turn. */
|
|
2734
|
+
export function routeDevHarnessSubmitIntent(
|
|
2735
|
+
intent: SubmitTurnIntent | ControlTurnIntent,
|
|
2736
|
+
): SubmitTurnIntent | ControlTurnIntent {
|
|
2737
|
+
if (intent.kind !== 'submit-turn' || intent.route !== 'plain' || !isDevHarnessIntent(intent.text)) return intent;
|
|
2738
|
+
return {
|
|
2739
|
+
kind: 'control-turn',
|
|
2740
|
+
source: intent.source,
|
|
2741
|
+
command: 'slash-command',
|
|
2742
|
+
commandText: `/harness ask ${intent.text}`,
|
|
2743
|
+
};
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2702
2746
|
export function shouldExposeDevHarnessSessionTool(text: string): boolean {
|
|
2703
2747
|
return isDevHarnessModelSurfaceEnabled() && hasDevHarnessIntent(text);
|
|
2704
2748
|
}
|
|
@@ -44,7 +44,7 @@ import { enhanceAgentResultWithSeed } from '../../agent/seed.js';
|
|
|
44
44
|
import { resolveAgent } from '../../agent/loader.js';
|
|
45
45
|
import { resolveAgentLayered } from '../../agent/definition-registry.js';
|
|
46
46
|
import type { AgentDefinition } from '../../agent/types.js';
|
|
47
|
-
import { getSessionCwd } from '../../session/working-dir.js';
|
|
47
|
+
import { getSessionCwd, setSessionCwd } from '../../session/working-dir.js';
|
|
48
48
|
import {
|
|
49
49
|
agentCacheKey, dedupeStub, logDedupHit, type SessionCache,
|
|
50
50
|
DEDUP_CASCADE_HALT_THRESHOLD, CONSECUTIVE_DEDUP_BLOCK_THRESHOLD,
|
|
@@ -485,6 +485,11 @@ export async function dispatchAgent(
|
|
|
485
485
|
} else if (isolation === 'worktree') {
|
|
486
486
|
const { enterWorktreeRuntime } = await import('../../tool-runtime/git-worktree-runtimes.js');
|
|
487
487
|
const wtName = `${spawnName ?? definition.name}-${debugCorrelationId}`.replace(/[^a-zA-Z0-9._/-]/g, '-');
|
|
488
|
+
// enterWorktreeRuntime.run mutates the parent session cwd via
|
|
489
|
+
// setSessionCwd(path, 'tool'). Capture and restore so Agent(isolation:
|
|
490
|
+
// 'worktree') never leaks the child's worktree into the parent status
|
|
491
|
+
// line — enter_worktree (human-invoked) still moves cwd intentionally.
|
|
492
|
+
const parentCwd = getSessionCwd();
|
|
488
493
|
try {
|
|
489
494
|
const wt = await enterWorktreeRuntime.run({ name: wtName }, { surface: 'skill' as any });
|
|
490
495
|
childCwd = wt.path;
|
|
@@ -506,6 +511,16 @@ export async function dispatchAgent(
|
|
|
506
511
|
requestedIsolation: 'worktree',
|
|
507
512
|
reason: message,
|
|
508
513
|
}, { level: 'warn' });
|
|
514
|
+
} finally {
|
|
515
|
+
const afterCwd = getSessionCwd();
|
|
516
|
+
if (afterCwd !== parentCwd) {
|
|
517
|
+
setSessionCwd(parentCwd, 'tool');
|
|
518
|
+
debug.log('agent.spawn', 'worktree-parent-cwd-restored', {
|
|
519
|
+
agent: definition.name,
|
|
520
|
+
from: afterCwd,
|
|
521
|
+
to: parentCwd,
|
|
522
|
+
});
|
|
523
|
+
}
|
|
509
524
|
}
|
|
510
525
|
} else {
|
|
511
526
|
childCwd = opts.cwd ?? getSessionCwd();
|
|
@@ -153,6 +153,16 @@ function rejectionSample(value: string): string {
|
|
|
153
153
|
return value.slice(0, EVIDENCE_REJECTION_SAMPLE_PREFIX_LENGTH);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
function stripLeadingListMarkers(line: string): string {
|
|
157
|
+
let stripped = line;
|
|
158
|
+
let previous: string;
|
|
159
|
+
do {
|
|
160
|
+
previous = stripped;
|
|
161
|
+
stripped = stripped.replace(/^\s*(?:[-*+•]|\d+[.)])\s+/, '');
|
|
162
|
+
} while (stripped !== previous);
|
|
163
|
+
return stripped;
|
|
164
|
+
}
|
|
165
|
+
|
|
156
166
|
function verifiedEvidenceFromCompletion(evidence: string, readFiles: Set<string>): { files: string[]; evidence: string[]; rejection: EvidenceRejection } {
|
|
157
167
|
const lines = evidence.split(/\r?\n/).filter((line) => line.trim());
|
|
158
168
|
const rejection: {
|
|
@@ -185,7 +195,7 @@ function verifiedEvidenceFromCompletion(evidence: string, readFiles: Set<string>
|
|
|
185
195
|
return hasPath && insideRoot && unreadPaths.length === 0 && hasMeaningfulText;
|
|
186
196
|
});
|
|
187
197
|
const files = Array.from(new Set(verifiedLines.flatMap(repositoryRelativeCodePaths)));
|
|
188
|
-
return { files, evidence: verifiedLines, rejection };
|
|
198
|
+
return { files, evidence: verifiedLines.map(stripLeadingListMarkers), rejection };
|
|
189
199
|
}
|
|
190
200
|
|
|
191
201
|
function groundingMessages(goal: string, terms: readonly string[]): LLMMessage[] {
|
|
@@ -113,7 +113,7 @@ export interface RunShellDispatchResult extends Record<string, unknown> {
|
|
|
113
113
|
* follow in the structured fields below. */
|
|
114
114
|
output: string;
|
|
115
115
|
exitCode: number | null;
|
|
116
|
-
outcome: ShellResult['outcome'];
|
|
116
|
+
outcome: ShellResult['outcome'] | 'started';
|
|
117
117
|
elapsedMs: number;
|
|
118
118
|
stdout: string;
|
|
119
119
|
stderr: string;
|
|
@@ -260,6 +260,38 @@ async function dispatchViaRunner(args: {
|
|
|
260
260
|
...(args.signal !== undefined ? { signal: args.signal } : {}),
|
|
261
261
|
};
|
|
262
262
|
const handle = runnerDispatch(req, args.deps);
|
|
263
|
+
if (args.mode === 'bg') {
|
|
264
|
+
const bgStartedAt = Date.now();
|
|
265
|
+
void handle.result.then(
|
|
266
|
+
(result) => {
|
|
267
|
+
debug.log('skill-tool.shell', 'bg-finished', {
|
|
268
|
+
handle: handle.id,
|
|
269
|
+
exitCode: result.exitCode ?? null,
|
|
270
|
+
durationMs: result.durationMs,
|
|
271
|
+
});
|
|
272
|
+
},
|
|
273
|
+
(err: unknown) => {
|
|
274
|
+
debug.log('skill-tool.shell', 'bg-finished', {
|
|
275
|
+
handle: handle.id,
|
|
276
|
+
exitCode: null,
|
|
277
|
+
durationMs: Date.now() - bgStartedAt,
|
|
278
|
+
error: err instanceof Error ? err.message : String(err),
|
|
279
|
+
});
|
|
280
|
+
},
|
|
281
|
+
);
|
|
282
|
+
return {
|
|
283
|
+
output: `RunShell outcome=started handle=${handle.id} bg=${handle.id}`,
|
|
284
|
+
exitCode: null,
|
|
285
|
+
outcome: 'started',
|
|
286
|
+
elapsedMs: 0,
|
|
287
|
+
stdout: '',
|
|
288
|
+
stderr: '',
|
|
289
|
+
truncated: false,
|
|
290
|
+
approvalKey: `runner:${handle.id}`,
|
|
291
|
+
sandboxed: false,
|
|
292
|
+
sandboxTool: 'none',
|
|
293
|
+
};
|
|
294
|
+
}
|
|
263
295
|
const result = await handle.result;
|
|
264
296
|
return runnerToLegacyResult(handle.id, result);
|
|
265
297
|
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TA-REJUDGE-PERIODIC — the steward (coordinator) tick re-runs `tasks rejudge --all` on a cadence.
|
|
3
|
+
*
|
|
4
|
+
* `tasks rejudge` only ran when someone typed it (OP bridged the gap with a 30-minute shell loop). This node is the
|
|
5
|
+
* product form: the steward graph already ticks every 15 minutes, so the rejudge rides that tick — no new resident loop.
|
|
6
|
+
*
|
|
7
|
+
* - Off by default: `taskAgent.rejudgeEveryMinutes` absent/0 → one `disabled` line per tick and nothing else.
|
|
8
|
+
* Rejudge can land PRs (per `taskAgent.liveMoves`), so it is switched on by an operator, not by an upgrade.
|
|
9
|
+
* - Cadence: due when the last started run is ≥ interval − 2 min ago (tick start jitter must not skip a whole tick).
|
|
10
|
+
* - Load guard: 1-minute load average above `taskAgent.rejudgeMaxLoad` (default 60) skips this tick without stamping,
|
|
11
|
+
* so the next tick retries.
|
|
12
|
+
* - Fail-soft: every outcome exits 0 — a rejudge problem never stops the steward's own stages.
|
|
13
|
+
* - Observation: one `debug.log('loop.steward', 'rejudge-tick', …)` per tick.
|
|
14
|
+
*/
|
|
15
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
16
|
+
import { loadavg } from 'node:os';
|
|
17
|
+
import { dirname, join } from 'node:path';
|
|
18
|
+
import { debug } from '../debug/log.js';
|
|
19
|
+
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
20
|
+
import { spawnElanous } from '../instance/spawn-elanous.js';
|
|
21
|
+
import { getUserConfig } from '../user-config.js';
|
|
22
|
+
|
|
23
|
+
export const REJUDGE_TICK_EVENT = 'rejudge-tick';
|
|
24
|
+
export const REJUDGE_DEFAULT_MAX_LOAD = 60;
|
|
25
|
+
export const REJUDGE_JITTER_MS = 2 * 60_000;
|
|
26
|
+
export const REJUDGE_TIMEOUT_MS = 600_000;
|
|
27
|
+
|
|
28
|
+
export type RejudgeTickDecision = 'disabled' | 'not-due' | 'load-skip' | 'ran' | 'failed';
|
|
29
|
+
|
|
30
|
+
export interface RejudgeTickResult {
|
|
31
|
+
decision: RejudgeTickDecision;
|
|
32
|
+
everyMinutes: number | null;
|
|
33
|
+
load?: number;
|
|
34
|
+
maxLoad?: number;
|
|
35
|
+
lastStartedAt?: string | null;
|
|
36
|
+
rc?: number | null;
|
|
37
|
+
timedOut?: boolean;
|
|
38
|
+
cards?: number;
|
|
39
|
+
decisions?: Record<string, number>;
|
|
40
|
+
ms?: number;
|
|
41
|
+
reason?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface RejudgeRun { code: number | null; stdout: string; stderr: string; timedOut: boolean }
|
|
45
|
+
|
|
46
|
+
export interface RejudgeTickDeps {
|
|
47
|
+
now?: () => Date;
|
|
48
|
+
/** `taskAgent.rejudgeEveryMinutes` / `taskAgent.rejudgeMaxLoad` — default reads the user config. */
|
|
49
|
+
config?: () => { rejudgeEveryMinutes?: number; rejudgeMaxLoad?: number } | undefined;
|
|
50
|
+
load?: () => number;
|
|
51
|
+
stampPath?: string;
|
|
52
|
+
run?: () => Promise<RejudgeRun>;
|
|
53
|
+
log?: (event: string, data: Record<string, unknown>) => void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function defaultStampPath(): string {
|
|
57
|
+
// Resolved at call time, in the node process's own universe (prod cron vs --test graph run).
|
|
58
|
+
return join(effectiveInstanceRoot(), 'steward', 'rejudge-tick.json');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function readStamp(path: string): string | null {
|
|
62
|
+
try {
|
|
63
|
+
const value = (JSON.parse(readFileSync(path, 'utf8')) as { startedAt?: unknown }).startedAt;
|
|
64
|
+
return typeof value === 'string' && Number.isFinite(Date.parse(value)) ? value : null;
|
|
65
|
+
} catch { return null; }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Same universe as this process (env inherited) · same installed version (entry next to this module). */
|
|
69
|
+
export function defaultRejudgeRun(timeoutMs = REJUDGE_TIMEOUT_MS): Promise<RejudgeRun> {
|
|
70
|
+
return new Promise(done => {
|
|
71
|
+
const child = spawnElanous(['tasks', 'rejudge', '--all', '--json'], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
72
|
+
let stdout = '';
|
|
73
|
+
let stderr = '';
|
|
74
|
+
let timedOut = false;
|
|
75
|
+
const timer = setTimeout(() => { timedOut = true; child.kill('SIGTERM'); }, timeoutMs);
|
|
76
|
+
child.stdout?.on('data', chunk => { stdout += String(chunk); });
|
|
77
|
+
child.stderr?.on('data', chunk => { stderr += String(chunk); });
|
|
78
|
+
child.on('error', error => { clearTimeout(timer); done({ code: null, stdout, stderr: `${stderr}${error.message}`, timedOut }); });
|
|
79
|
+
child.on('close', code => { clearTimeout(timer); done({ code, stdout, stderr, timedOut }); });
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** The last `[...]` line of `tasks rejudge --all --json` → card count and a decision histogram. */
|
|
84
|
+
function summarize(stdout: string): { cards: number; decisions: Record<string, number> } | null {
|
|
85
|
+
const line = stdout.split('\n').map(text => text.trim()).filter(text => text.startsWith('[')).at(-1);
|
|
86
|
+
if (!line) return null;
|
|
87
|
+
try {
|
|
88
|
+
const rows = JSON.parse(line) as Array<{ card?: unknown; decision?: unknown }>;
|
|
89
|
+
if (!Array.isArray(rows)) return null;
|
|
90
|
+
const decisions: Record<string, number> = {};
|
|
91
|
+
for (const row of rows) { const key = String(row?.decision ?? 'unknown'); decisions[key] = (decisions[key] ?? 0) + 1; }
|
|
92
|
+
return { cards: new Set(rows.map(row => String(row?.card))).size, decisions };
|
|
93
|
+
} catch { return null; }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function positive(value: unknown): number | null {
|
|
97
|
+
return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export async function rejudgeTick(deps: RejudgeTickDeps = {}): Promise<RejudgeTickResult> {
|
|
101
|
+
const log = deps.log ?? ((event, data) => debug.log('loop.steward', event, data));
|
|
102
|
+
const emit = (result: RejudgeTickResult): RejudgeTickResult => {
|
|
103
|
+
try { log(REJUDGE_TICK_EVENT, { ...result }); } catch { /* fail-soft */ }
|
|
104
|
+
return result;
|
|
105
|
+
};
|
|
106
|
+
try {
|
|
107
|
+
const cfg = (deps.config ?? (() => getUserConfig().taskAgent))();
|
|
108
|
+
const everyMinutes = positive(cfg?.rejudgeEveryMinutes);
|
|
109
|
+
if (everyMinutes === null) return emit({ decision: 'disabled', everyMinutes: null, reason: 'taskAgent.rejudgeEveryMinutes unset' });
|
|
110
|
+
const now = (deps.now ?? (() => new Date()))();
|
|
111
|
+
const stampPath = deps.stampPath ?? defaultStampPath();
|
|
112
|
+
const lastStartedAt = readStamp(stampPath);
|
|
113
|
+
if (lastStartedAt && now.getTime() - Date.parse(lastStartedAt) < everyMinutes * 60_000 - REJUDGE_JITTER_MS) {
|
|
114
|
+
return emit({ decision: 'not-due', everyMinutes, lastStartedAt });
|
|
115
|
+
}
|
|
116
|
+
const maxLoad = positive(cfg?.rejudgeMaxLoad) ?? REJUDGE_DEFAULT_MAX_LOAD;
|
|
117
|
+
const load = (deps.load ?? (() => loadavg()[0] ?? 0))();
|
|
118
|
+
if (load > maxLoad) return emit({ decision: 'load-skip', everyMinutes, load, maxLoad, lastStartedAt });
|
|
119
|
+
// Claim before running so an overlapping steward tick does not start a second rejudge.
|
|
120
|
+
mkdirSync(dirname(stampPath), { recursive: true });
|
|
121
|
+
writeFileSync(stampPath, JSON.stringify({ startedAt: now.toISOString() }));
|
|
122
|
+
const started = Date.now();
|
|
123
|
+
const run = await (deps.run ?? (() => defaultRejudgeRun()))();
|
|
124
|
+
const summary = summarize(run.stdout);
|
|
125
|
+
const ok = run.code === 0 && !run.timedOut && summary !== null;
|
|
126
|
+
return emit({
|
|
127
|
+
decision: ok ? 'ran' : 'failed', everyMinutes, load, maxLoad, lastStartedAt, rc: run.code, timedOut: run.timedOut,
|
|
128
|
+
cards: summary?.cards ?? 0, decisions: summary?.decisions ?? {}, ms: Date.now() - started,
|
|
129
|
+
...(ok ? {} : { reason: (run.stderr || run.stdout).trim().slice(-300) || (summary === null ? 'no JSON result line' : 'nonzero exit') }),
|
|
130
|
+
});
|
|
131
|
+
} catch (error) {
|
|
132
|
+
return emit({ decision: 'failed', everyMinutes: null, reason: (error instanceof Error ? error.message : String(error)).slice(-300) });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (import.meta.main) {
|
|
137
|
+
try { await (await import('../domains/standalone-log-sink.js')).registerStandaloneLogSink('steward'); }
|
|
138
|
+
catch (error) { console.error(`steward rejudge: log sink registration failed — ${error instanceof Error ? error.message : String(error)}`); }
|
|
139
|
+
const result = await rejudgeTick();
|
|
140
|
+
console.log(`steward rejudge: ${result.decision}${result.reason ? ` — ${result.reason}` : ''}`);
|
|
141
|
+
process.exitCode = 0;
|
|
142
|
+
}
|
package/src/task-agent/board.ts
CHANGED
|
@@ -7,13 +7,42 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { existsSync } from 'node:fs';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
|
+
import { debug } from '../debug/log.js';
|
|
10
11
|
import { releaseLedgerRoot } from '../instance/resolve.js';
|
|
11
12
|
import { listChecklist, type ChecklistStatus } from '../release-loop/checklist.js';
|
|
12
|
-
import {
|
|
13
|
+
import { buildRunProgressRows, queryRunningRuns, type RunningRunsResult, type RunProgressRow } from '../self-implement/running-runs.js';
|
|
14
|
+
import {
|
|
15
|
+
cardPrNumber, CLOSED_BY_HAND_EVENT, HAND_MOVE_HISTORY_EVENT, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, readTaskAgentState,
|
|
16
|
+
type CompletionKind, type TaskCard,
|
|
17
|
+
} from './task-hand.js';
|
|
13
18
|
|
|
14
19
|
export type BoardLevel = 'project' | 'goal' | 'milestone' | 'task';
|
|
15
20
|
export type BoardStatus = 'open' | 'done' | 'blocked';
|
|
16
21
|
|
|
22
|
+
/** 카드 원장(task-agent-actions.json)에 적힌 사실만 — 없는 칸은 null(지어내지 않는다). */
|
|
23
|
+
export interface BoardTaskLedger {
|
|
24
|
+
runId: string | null;
|
|
25
|
+
pr: number | null;
|
|
26
|
+
/** 카드 상태(handed · launched · launch-failed · failed). */
|
|
27
|
+
lastStatus: TaskCard['status'];
|
|
28
|
+
/** 관측 기록(live-move · hand-move)을 뺀 history 의 마지막 줄. */
|
|
29
|
+
lastEvent: { at: string; event: string; detail: string | null } | null;
|
|
30
|
+
/** 카드가 failed · launch-failed 일 때 마지막 줄의 사유(예: `failed/needs-owner — exit 1 · pod-failure`). 그 밖에는 null. */
|
|
31
|
+
exitReason: string | null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** `GET /api/task-agent/board` 응답 — progress 는 진전 관측(`queryRunningRuns`)을 싣는다; 관측을 못 얻으면 null(0을 «없다»로 쓰지 않는다). */
|
|
35
|
+
export interface TaskAgentBoardResponse { board: BoardNode[]; progress: TaskAgentBoardProgress | null }
|
|
36
|
+
|
|
37
|
+
/** 진전 관측 칸 — 행은 기존 `RunProgressRow` 형식 그대로(새 행 형식을 만들지 않는다). 과제 노드와는 `ledger.runId` ↔ `rows[].runId` 로만 짝짓는다(ledger 에 새 칸은 없다). */
|
|
38
|
+
export interface TaskAgentBoardProgress {
|
|
39
|
+
readonly rows: readonly RunProgressRow[];
|
|
40
|
+
/** 관측이 부분(running 수가 `{ count: null, lowerBound }` 꼴이거나 읽지 못한 원장 unreadable 이 있으면)이면 true · 아니면 false. */
|
|
41
|
+
readonly partial: boolean;
|
|
42
|
+
/** 부분 관측일 때의 최소 running 수 · 완전 관측이면 null. */
|
|
43
|
+
readonly lowerBound: number | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
17
46
|
export interface BoardNode {
|
|
18
47
|
level: BoardLevel;
|
|
19
48
|
id: string;
|
|
@@ -21,6 +50,8 @@ export interface BoardNode {
|
|
|
21
50
|
status: BoardStatus;
|
|
22
51
|
/** 과제 노드만 — 카드의 종결 종류(비면 code-pr 로 읽는다 · 칸은 싣지 않는다). */
|
|
23
52
|
completion?: CompletionKind;
|
|
53
|
+
/** 과제 노드만 · `cardsBoard(…, { ledger: true })` 일 때만 — 카드 원장에서 읽은 런·PR·마지막 상태·종료 이유. */
|
|
54
|
+
ledger?: BoardTaskLedger;
|
|
24
55
|
/** 부모 노드 id(프로젝트는 없다). */
|
|
25
56
|
parent?: string;
|
|
26
57
|
/** 프로젝트 노드만 — 프로젝트 없는 카드의 자리(id 는 빈 문자열이라 실제 프로젝트 id 와 겹치지 않는다). */
|
|
@@ -60,8 +91,28 @@ function cardStatus(card: TaskCard): BoardStatus {
|
|
|
60
91
|
return card.greenProposal ? 'done' : 'open';
|
|
61
92
|
}
|
|
62
93
|
|
|
63
|
-
|
|
64
|
-
|
|
94
|
+
function cardLedger(card: TaskCard): BoardTaskLedger {
|
|
95
|
+
const last = (card.history ?? [])
|
|
96
|
+
.filter((item) => item.event !== LIVE_MOVE_HISTORY_EVENT && item.event !== LIVE_MOVE_RESULT_EVENT && item.event !== HAND_MOVE_HISTORY_EVENT)
|
|
97
|
+
.at(-1);
|
|
98
|
+
const ended = card.status === 'failed' || card.status === 'launch-failed';
|
|
99
|
+
// ⚠️ 종료 이유 = «관측 줄을 뺀 마지막 줄»의 detail 만 본다 — 그 줄이 detail 없는 run-bound·pr-bound 면 null(지어내지 않음 · 앞줄을 거슬러 찾지 않는다).
|
|
100
|
+
// 관측 줄 거르기는 task-hand.ts(wait 사유)와 같은 셋이다 — 공용 헬퍼로 묶는 것은 다음 조각(UX 수확 리뷰 should-fix).
|
|
101
|
+
const reason = last ? (last.event === CLOSED_BY_HAND_EVENT ? last.reason ?? last.detail : last.detail) : undefined;
|
|
102
|
+
return {
|
|
103
|
+
runId: card.runId ?? null,
|
|
104
|
+
pr: cardPrNumber(card) ?? null,
|
|
105
|
+
lastStatus: card.status,
|
|
106
|
+
lastEvent: last ? { at: last.at, event: last.event, detail: last.detail ?? null } : null,
|
|
107
|
+
exitReason: ended ? reason ?? null : null,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* 과제 카드 → 프로젝트 트리. 프로젝트 없는 카드는 «무소속»(`unassigned: true` · id '') 아래 — 어떤 프로젝트 id 로도 걸러지지 않는다.
|
|
113
|
+
* `ledger: true` 면 과제 노드마다 카드 원장 사실(`ledger`)을 붙인다 — 기본(CLI)은 그대로다.
|
|
114
|
+
*/
|
|
115
|
+
export function cardsBoard(statePath: string, options: { ledger?: boolean } = {}): BoardNode[] {
|
|
65
116
|
const projects: BoardNode[] = [];
|
|
66
117
|
const cards = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(statePath).tasks ?? {};
|
|
67
118
|
for (const card of Object.values(cards)) {
|
|
@@ -77,6 +128,7 @@ export function cardsBoard(statePath: string): BoardNode[] {
|
|
|
77
128
|
milestone.children!.push({
|
|
78
129
|
level: 'task', id: card.id, title: card.text, status: cardStatus(card),
|
|
79
130
|
...(card.completion ? { completion: card.completion } : {}),
|
|
131
|
+
...(options.ledger ? { ledger: cardLedger(card) } : {}),
|
|
80
132
|
parent: milestone.id,
|
|
81
133
|
});
|
|
82
134
|
}
|
|
@@ -84,6 +136,43 @@ export function cardsBoard(statePath: string): BoardNode[] {
|
|
|
84
136
|
return projects;
|
|
85
137
|
}
|
|
86
138
|
|
|
139
|
+
/** `taskAgentBoard` 주입 자리 — 시험은 관측을 갈아끼워 결정성을 얻는다. */
|
|
140
|
+
export interface TaskAgentBoardDeps {
|
|
141
|
+
/** 진전 관측. 기본 = `queryRunningRuns({ caller: 'task-agent.board' })`. 던지면 progress=null — 보드는 그대로 돌려준다. */
|
|
142
|
+
readonly runningRuns?: () => RunningRunsResult;
|
|
143
|
+
/** 경과 계산의 기준 시각(`buildRunProgressRows` 의 nowMs) · 기본 = Date.now(). */
|
|
144
|
+
readonly nowMs?: number;
|
|
145
|
+
/** 진전 관측을 돌릴지 — 기본 false(progress=null · «요청 안 함»). ⛔ 운영 원장에서 queryRunningRuns 는 동기 수 초(10-12 실측 4.3초)라
|
|
146
|
+
* 데몬 이벤트 루프를 멈춘다 → 라우트는 `?progress=1` 일 때만 켠다(UX 수확 리뷰 should-fix). runningRuns 를 주입하면 이 값과 무관하게 돈다. */
|
|
147
|
+
readonly withProgress?: boolean;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** 관측 결과 → progress 칸. running 수가 `{ count: null, lowerBound }` 꼴이거나 읽지 못한 원장(unreadable)이 있으면 부분 관측으로 친다. */
|
|
151
|
+
function runProgressFrom(result: RunningRunsResult, nowMs: number): TaskAgentBoardProgress {
|
|
152
|
+
const objectCount = result.count !== undefined && typeof result.count !== 'number' ? result.count : null;
|
|
153
|
+
// 판정 출처는 관측 결과의 completeness 가 1순위 — count 꼴·unreadable 은 그것이 없을 때의 보조다.
|
|
154
|
+
const partial = result.completeness === 'partial' || objectCount !== null || (result.unreadable?.length ?? 0) > 0;
|
|
155
|
+
return {
|
|
156
|
+
rows: buildRunProgressRows(result, nowMs),
|
|
157
|
+
partial,
|
|
158
|
+
lowerBound: partial ? (objectCount !== null ? objectCount.lowerBound : result.counts.running + result.counts['probable-running']) : null,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** 읽기 전용 — 원장이 없으면 빈 보드. 원장이 손상됐으면 `TaskAgentStateError` 를 그대로 던진다(빈 보드로 속이지 않는다). progress 는 진전 관측을 싣는다 — 관측이 던지면 progress=null(0을 «없다»로 쓰지 않는다) · 보드는 그대로. */
|
|
163
|
+
export function taskAgentBoard(statePath: string, deps: TaskAgentBoardDeps = {}): TaskAgentBoardResponse {
|
|
164
|
+
const board = cardsBoard(statePath, { ledger: true });
|
|
165
|
+
if (!deps.runningRuns && !deps.withProgress) return { board, progress: null };
|
|
166
|
+
const observe = deps.runningRuns ?? (() => queryRunningRuns({ caller: 'task-agent.board' }));
|
|
167
|
+
let progress: TaskAgentBoardProgress | null = null;
|
|
168
|
+
try {
|
|
169
|
+
progress = runProgressFrom(observe(), deps.nowMs ?? Date.now());
|
|
170
|
+
} catch (error) {
|
|
171
|
+
debug.log('task-agent', 'board-progress-unavailable', { error: error instanceof Error ? error.message : String(error) });
|
|
172
|
+
}
|
|
173
|
+
return { board, progress };
|
|
174
|
+
}
|
|
175
|
+
|
|
87
176
|
function releaseStatus(status: ChecklistStatus): BoardStatus {
|
|
88
177
|
return status === 'green' || status === 'done' ? 'done' : status === 'red' ? 'blocked' : 'open';
|
|
89
178
|
}
|
|
@@ -13,7 +13,7 @@ import { readRunExits, type RunExit } from '../harness/harness-incidents.js';
|
|
|
13
13
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
14
14
|
import { debug } from '../debug/log.js';
|
|
15
15
|
import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
|
|
16
|
-
import type
|
|
16
|
+
import { appendRunLedgerEntry, type RunLedgerEntry } from '../self-implement/run-ledger.js';
|
|
17
17
|
import { cardPrNumber, taskAgentStatePath, updateTaskCard, readTaskCard, type TaskCard } from './task-hand.js';
|
|
18
18
|
import { judgeNextMove, type TaskJudgeInput } from './judge.js';
|
|
19
19
|
import { remoteParentAlive, type SshRunner } from './parent-host.js';
|
|
@@ -342,3 +342,90 @@ export async function refreshCardRunBinding(cardId: string, statePath = taskAgen
|
|
|
342
342
|
}
|
|
343
343
|
return { card: next, evidence };
|
|
344
344
|
}
|
|
345
|
+
|
|
346
|
+
/** TA-WIRING-CHECK — `live-verified` 원장 줄의 이벤트 이름 · 카드 런 원장에 적는다. */
|
|
347
|
+
export const WIRING_LIVE_VERIFIED_EVENT = 'live-verified';
|
|
348
|
+
|
|
349
|
+
export interface WiringLiveVerifiedInput { pr: number; ref: string; ok: boolean }
|
|
350
|
+
export interface WiringLiveVerifiedDeps { ledgerDir?: string; now?: () => Date }
|
|
351
|
+
export type WiringLiveVerifiedOutcome = { written: true; entry: RunLedgerEntry } | { written: false; reason: string };
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* 실물 1회를 돌린 뒤 남기는 기록 — 카드 런 원장에 `live-verified {pr, ref, ok, card}` 한 줄.
|
|
355
|
+
* `ref`(실물로 돌린 명령·화면 근거)가 비거나 카드에 런이 없거나 PR 번호가 자연수가 아니면 거부하고 쓰지 않는다.
|
|
356
|
+
*/
|
|
357
|
+
export function recordWiringLiveVerified(card: Pick<TaskCard, 'id' | 'runId'>, input: WiringLiveVerifiedInput, deps: WiringLiveVerifiedDeps = {}): WiringLiveVerifiedOutcome {
|
|
358
|
+
const ref = typeof input.ref === 'string' ? input.ref.trim() : '';
|
|
359
|
+
if (!ref) return { written: false, reason: 'ref 가 비었다 — 실물로 돌린 명령·화면 근거 한 줄이 필요하다' };
|
|
360
|
+
if (!Number.isSafeInteger(input.pr) || input.pr <= 0) return { written: false, reason: `pr 은 자연수다: ${input.pr}` };
|
|
361
|
+
if (!card.runId) return { written: false, reason: `카드 ${card.id} 에 런(runId)이 없다 — 기록할 원장이 없다` };
|
|
362
|
+
const entry: RunLedgerEntry = {
|
|
363
|
+
timestamp: (deps.now ?? (() => new Date()))().toISOString(),
|
|
364
|
+
runId: card.runId,
|
|
365
|
+
event: WIRING_LIVE_VERIFIED_EVENT,
|
|
366
|
+
data: { pr: input.pr, ref, ok: input.ok, card: card.id },
|
|
367
|
+
};
|
|
368
|
+
try {
|
|
369
|
+
appendRunLedgerEntry(entry, deps.ledgerDir);
|
|
370
|
+
} catch (error) {
|
|
371
|
+
return { written: false, reason: `원장 쓰기 실패: ${(error instanceof Error ? error.message : String(error)).slice(0, 200)}` };
|
|
372
|
+
}
|
|
373
|
+
return { written: true, entry };
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export interface WiringEvidence {
|
|
377
|
+
/** 이 PR 이 배선(진입점·명령 등록·호출자 대입)을 바꿨나 — 그렇다면 실물 1회가 필요하다. */
|
|
378
|
+
required: boolean;
|
|
379
|
+
/** 카드 런 원장에 이 PR 의 `live-verified` ok 기록이 있나. */
|
|
380
|
+
liveRunRecorded: boolean;
|
|
381
|
+
/** 근거를 못 읽었다(gh 실패 · 원장 읽기 실패) — 관측만 하고 green 을 막지 않는다. */
|
|
382
|
+
unknown: boolean;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export interface WiringEvidenceDeps {
|
|
386
|
+
/** 카드 — 없으면 liveRunRecorded 는 false. */
|
|
387
|
+
card?: Pick<TaskCard, 'id' | 'runId'>;
|
|
388
|
+
/** `gh pr diff <pr>` 의 통합 diff 원문 — 한 번만 부른다(시험 주입). */
|
|
389
|
+
prDiff?: (pr: number) => string | Promise<string>;
|
|
390
|
+
loadLedger?: (runId: string) => RunLedgerEntry[] | null;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const WIRING_PATH = /(^|\/)(bin|scripts|cli)\/|(^|\/)[^/]*(install|auth|entrypoint)[^/]*$/i;
|
|
394
|
+
const NON_WIRING_PATH = /^docs\/|\.md$|\.test\.[cm]?[jt]sx?$/;
|
|
395
|
+
const WIRING_LINE = /\bregisterCommand\b|\.command\(|\.set\(|\.on\(|\bhandlers(?:\.\w+|\[[^\]]+\])\s*=(?!=)/;
|
|
396
|
+
|
|
397
|
+
async function defaultPrDiff(pr: number): Promise<string> {
|
|
398
|
+
const { execFile } = await import('node:child_process');
|
|
399
|
+
return new Promise((resolveDiff, reject) => {
|
|
400
|
+
execFile('gh', ['pr', 'diff', String(pr)], { encoding: 'utf8', timeout: 30_000, maxBuffer: 32 * 1024 * 1024 }, (error, stdout) => (error ? reject(error) : resolveDiff(stdout)));
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/** 순수 — 통합 diff 가 배선을 바꾸나. 문서·시험 파일은 보지 않는다. */
|
|
405
|
+
export function diffTouchesWiring(diff: string): boolean {
|
|
406
|
+
for (const chunk of diff.split(/^diff --git /m)) {
|
|
407
|
+
const path = /^\S+ b\/(\S+)/.exec(chunk)?.[1] ?? '';
|
|
408
|
+
if (path && NON_WIRING_PATH.test(path)) continue;
|
|
409
|
+
if (path && WIRING_PATH.test(path)) return true;
|
|
410
|
+
const added = chunk.split('\n').filter((line) => line.startsWith('+') && !line.startsWith('+++'));
|
|
411
|
+
if (added.some((line) => WIRING_LINE.test(line))) return true;
|
|
412
|
+
}
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* 수집기 — 판단부(judge.ts) 밖에서만 gh 를 부른다. PR diff 는 «한 번» 읽고, gh·원장 읽기 실패는 던지지 않고 `unknown: true` 로 돌려준다.
|
|
418
|
+
*/
|
|
419
|
+
export async function collectWiringEvidence(pr: number, deps: WiringEvidenceDeps = {}): Promise<WiringEvidence> {
|
|
420
|
+
let unknown = false;
|
|
421
|
+
let required = false;
|
|
422
|
+
try { required = diffTouchesWiring(await (deps.prDiff ?? defaultPrDiff)(pr)); } catch { unknown = true; }
|
|
423
|
+
let liveRunRecorded = false;
|
|
424
|
+
if (deps.card?.runId) {
|
|
425
|
+
try {
|
|
426
|
+
const entries = (deps.loadLedger ?? await defaultLoadLedger())(deps.card.runId) ?? [];
|
|
427
|
+
liveRunRecorded = entries.some((entry) => entry.event === WIRING_LIVE_VERIFIED_EVENT && entry.data?.ok === true && entry.data?.pr === pr);
|
|
428
|
+
} catch { unknown = true; }
|
|
429
|
+
}
|
|
430
|
+
return { required, liveRunRecorded, unknown };
|
|
431
|
+
}
|