elanous 0.2.19 → 0.2.21
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/MObU8ujkMciAKr6ljAV05/_buildManifest.js +1 -0
- package/apps/pwa/out/_next/static/chunks/088d8e8a.8069543d082bec12.js +160 -0
- package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +148 -0
- package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +32 -0
- package/apps/pwa/out/_next/static/chunks/119fc678.6f591cdb84ca5791.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +309 -0
- package/apps/pwa/out/_next/static/chunks/{4323.c5dfb6f503304775.js → 1268.0840ff91e083fcbd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +122 -0
- package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +149 -0
- package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +79 -0
- package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1948.5f35b39eef222a94.js +5 -0
- package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2977-e38442e86289f1d3.js → 211-9c9090c59e2c5907.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +36 -0
- package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +286 -0
- package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +94 -0
- package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3522-1de1319d028ac89c.js +25 -0
- package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +74 -0
- package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +34 -0
- package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +115 -0
- package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4588.ad3364cb7fb97ada.js +86 -0
- package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +77 -0
- package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +90 -0
- package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +1 -0
- package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{4847.56f5bc454fbcc827.js → 6110.1297d4093fdfbb0d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6158.566c890adc06a459.js +2 -0
- package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +64 -0
- package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +287 -0
- package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +226 -0
- package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6767.8e6c5f6e744fcd9f.js +38 -0
- package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7175-350f4ce2873bc038.js +1 -0
- package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +41 -0
- package/apps/pwa/out/_next/static/chunks/{1470.98a6ab61ccb4131c.js → 726.83532d69452ee24b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6062-73e68343a9814f6a.js → 7327-2d69fb321ba73389.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7630.2b9a68659053ff4e.js +193 -0
- package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7899.597af4a9996c907f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/79b78388.663188133449d707.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8194.484f51e273d9abd2.js +217 -0
- package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +104 -0
- package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/88729267.9c6c000157c83f2f.js +62 -0
- package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9070.067c106528ec1ae6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7647.2fcd30d894d5ee30.js → 935.4ddaa99fc1d1126c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +23 -0
- package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/9832.2ab2e818013574c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/a9f2b54d-40c16bd0efdb04b8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d781be3e3a9cfd74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-b0a80997903852d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-2b1263165630d9c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-e2d6bed48ac20120.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-111cabe4d1fd69ae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-544dd4bd4847eeb7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-3ee191319bf97d87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a449f1ed472b81c2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-9045094d6d3b5cd0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/{page-b70cd005d9169e25.js → page-be8b4615c919e36c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7a12f61be4a579d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-dc39ee7a36d26385.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-84ae759f76053672.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-3db58ddb61fe2be9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-2fe368efb6de3b6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-c69762987b751174.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-7f8d7fcdf058a845.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-22163556cd38bc88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/d70879db.c66c56a95a91efc6.js +66 -0
- package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → f6231284-45726550aba08fca.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2ea96958.e8c7e112de50b067.js → f6b7c9ba.64a895b8b2fedbdc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/f8626309.a4e5d362b1d55e59.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-5c169757551134ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +1 -0
- package/apps/pwa/out/_next/static/css/{d3427996da11e480.css → b9d8151e48998417.css} +1 -1
- package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +1 -0
- 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 +24 -24
- 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 +23 -23
- 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 -0
- package/apps/pwa/out/live-run/index.txt +35 -0
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/graphs/demo/editor-recipes.yaml +22 -0
- package/graphs/drafts/recipes.yaml +4 -4
- package/graphs/implement-loop.yaml +277 -5
- package/graphs/retro/daily.yaml +25 -0
- package/graphs/retro/recipes.yaml +24 -0
- package/package.json +1 -1
- package/scripts/ask-marker-check.ts +3 -1
- package/scripts/coord-channel-watch.sh +31 -4
- package/scripts/docs-lint.ts +4 -1
- package/scripts/land-global-checks.ts +89 -0
- package/scripts/lib/pch-regress-map.ts +2 -1
- package/scripts/marketing/generate-ax-brief.ts +18 -1
- package/scripts/measure-nl-routing-corpus.ts +11 -3
- package/scripts/release-loop/gate-node.ts +296 -25
- package/scripts/release-loop/gate-timing.ts +116 -7
- package/scripts/release-loop/preflight.ts +6 -4
- package/scripts/release-loop/publish-window.ts +141 -0
- package/scripts/release-loop/release-docs.ts +1 -4
- package/scripts/release-loop/release-universe.ts +38 -0
- package/scripts/release-loop/resume-release.ts +4 -1
- package/scripts/release-loop/shard-plan.ts +50 -5
- package/scripts/release-loop/unattended-release.ts +10 -2
- package/scripts/release-story/draft.ts +5 -1
- package/scripts/retro/shadow-compare.ts +71 -0
- package/scripts/rhythm/daily.ts +8 -2
- package/src/agent-mission/driver.ts +34 -6
- package/src/autopilot/build/llm-conflict-merge.ts +132 -7
- package/src/autopilot/build/merge-intent.ts +135 -7
- package/src/away/release-watch.ts +20 -3
- package/src/browser-cdp/client.ts +10 -5
- package/src/cli/config-drift.ts +513 -0
- package/src/cli/log-event-names.ts +4 -0
- package/src/cli/ops-cli.ts +11 -0
- package/src/cli/ops-overview-cli.ts +50 -0
- package/src/cli/pod-cli.ts +1 -0
- package/src/cli/pr-cli.ts +20 -0
- package/src/cli/release-cli.ts +20 -5
- package/src/cli/retro-cli.ts +78 -0
- package/src/cli/tasks-cli.ts +200 -8
- package/src/dashboard/index.ts +40 -4
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -4
- package/src/dashboard/slash-runtime/help-from-registry.ts +57 -31
- package/src/domains/outbound-log-probe.ts +6 -1
- package/src/esc-abort-gate.ts +3 -1
- package/src/graph-runner/graph-cli.ts +57 -0
- package/src/graph-runner/graph-run-api.ts +218 -0
- package/src/graph-runner/runner.ts +11 -1
- package/src/graph-wizard/archetypes.ts +88 -0
- package/src/graph-wizard/generate.ts +545 -0
- package/src/graph-wizard/saved-steps.ts +120 -0
- package/src/graph-wizard/steps.ts +193 -0
- package/src/harness/harness-cli-command.ts +482 -59
- package/src/harness/harness-queue.ts +315 -25
- package/src/harness/harness-salvage-cli.ts +62 -0
- package/src/hq/fence-outcomes.ts +63 -0
- package/src/hq/fence-wrapper.ts +33 -0
- package/src/hq/hq.ts +11 -1
- package/src/index.ts +76 -10
- package/src/intake-plane/digest.ts +18 -11
- package/src/maturity/feature-maturity.ts +4 -3
- package/src/nexus/api/draft-metrics.ts +114 -0
- package/src/nexus/api/graph-kinds.ts +10 -4
- package/src/nexus/api/graph-wizard-api.ts +53 -0
- package/src/nexus/api/graphs-api.ts +220 -10
- package/src/nexus/api/harness-traversal.ts +205 -0
- package/src/nexus/api/http-server.ts +69 -3
- package/src/nexus/api/loop-edges.ts +4 -2
- package/src/nexus/api/ops-api.ts +22 -7
- package/src/nexus/api/ops-board-route.ts +48 -0
- package/src/nexus/outbound/router.ts +28 -8
- package/src/onboarding/entry-hints.ts +5 -0
- package/src/onboarding/first-run.ts +3 -0
- package/src/onboarding.ts +24 -6
- package/src/ops/overview-collect.ts +345 -0
- package/src/ops/overview-seat-era.ts +90 -0
- package/src/ops/overview.ts +223 -0
- package/src/release-loop/feature-store.ts +14 -11
- package/src/release-loop/gate-shards.ts +163 -0
- package/src/release-loop/release-schedule.ts +6 -2
- package/src/retro/daily.ts +372 -0
- package/src/seat-loop/op-decide.ts +173 -0
- package/src/seat-loop/seat-loop.ts +60 -3
- package/src/seat-loop/seat-report.ts +58 -3
- package/src/self-dev/ask-launch-flow.ts +9 -6
- package/src/self-dev/ask-launch-io.ts +52 -2
- package/src/self-dev/ask-path-candidates.ts +40 -2
- package/src/self-dev/draft-sweep.ts +371 -16
- package/src/self-dev/draft-triage-rules.ts +19 -4
- package/src/self-dev/graph-journey-nodes.ts +157 -0
- package/src/self-dev/graph-journey-route.ts +105 -0
- package/src/self-dev/launch-preflight.ts +43 -3
- package/src/self-dev/pr-preview.ts +84 -16
- package/src/self-dev/release-path-guard.ts +7 -4
- package/src/self-implement/blocked-draft-policy.ts +101 -0
- package/src/self-implement/execution-clarification.ts +11 -0
- package/src/self-implement/frozen-merges.ts +23 -0
- package/src/self-implement/gate-env-retry.ts +83 -0
- package/src/self-implement/goal-author.ts +14 -0
- package/src/self-implement/heal-intake.ts +3 -0
- package/src/self-implement/orchestrator.ts +234 -6
- package/src/self-implement/run-stop.ts +123 -0
- package/src/self-implement/run-ttl.ts +258 -0
- package/src/self-implement/salvage-retention.ts +123 -0
- package/src/self-implement/seams.ts +7 -0
- package/src/self-implement/self-implement-cli.ts +2 -0
- package/src/self-implement/self-implement-runtime.ts +12 -0
- package/src/self-implement/sibling-resync.ts +223 -0
- package/src/self-implement/stop-autoheal.ts +204 -0
- package/src/session-runtime/index.ts +5 -3
- package/src/shell-env-bootstrap.ts +17 -3
- package/src/task-agent/board.ts +1 -1
- package/src/task-agent/card-evidence.ts +105 -10
- package/src/task-agent/judge.ts +7 -0
- package/src/task-agent/live-moves.ts +120 -20
- package/src/task-agent/mission.ts +1 -1
- package/src/task-agent/parent-host.ts +315 -0
- package/src/task-agent/shadow.ts +10 -1
- package/src/task-agent/task-hand.ts +16 -4
- package/src/task-orchestrator/surfaces/pod-command-job.ts +60 -11
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +4 -0
- package/src/task-orchestrator/surfaces/pod-gate-deps.ts +123 -0
- package/src/task-orchestrator/surfaces/pod-install-slots.ts +89 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +93 -10
- package/src/task-orchestrator/surfaces/pod-pool.ts +147 -34
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +58 -9
- package/src/telegram-commands.ts +41 -0
- package/src/testing/real-cli-spawn.ts +106 -0
- package/src/tool-runtime/browser-runtime.ts +87 -3
- package/src/tool-runtime/index.ts +1 -0
- package/src/user-config.ts +76 -7
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/J5H7BvqgSI8DUjtRRcA_S/_buildManifest.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1157-cba0e8553d35a980.js +0 -1
- package/apps/pwa/out/_next/static/chunks/171-23a877ed11720de9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2336-e830c777eb6bce04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2375-e061bb24cd2b5cde.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2415.ed6428ff334c7ce2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3094.67339318c7f72a3a.js +0 -2
- package/apps/pwa/out/_next/static/chunks/338-ceb956612dcfaa86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3395-835e4ceaa6335ba4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
- package/apps/pwa/out/_next/static/chunks/3441-be82e3595aef3a20.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3689-89905039bf3e7257.js +0 -1
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3822-6f268bc26c6a84ac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4457-d7df81c90f9d0268.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4551-77dadae76f6cbace.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4978.6fd93b974441e87f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5012-f746f6549b869f91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
- package/apps/pwa/out/_next/static/chunks/62-5bfed1e23790b745.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6320-9bc8561fde416e07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/649-ca96d1c5d09e02b8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6726-85a7db59b288c53f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6735-33267c4630d0d963.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7633-141682015873beb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8067-143791231c99bd02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8430-a10cfba8ef282d4e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8870-9614a213b990b10b.js +0 -25
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9454-12c2f30dea62291c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/976-4a9b4ebdca7c739a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9989-15cdf568bafa9fc8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ae787e4c-e5b1ef00b2dbceca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-deef5ee191830f14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-b193da485f9a14b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b6e1a79df0e214f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-e84df4d907f703c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a5fb9a5db89ae4ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-1499f481d7fc52d6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c7cf753aeb648790.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-4118469e514e10fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-e968f7630654332a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-505915052f947022.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-c2f962fb4a3b06c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-7b5ed0bd8a589ec4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-cf8193250dd42dd4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-cf3f5dfa35dea8e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-5b29d9b06ceadade.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a15e7fcc283e9ca7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-d2915e7b70ff3d0e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2595f0eba29f57e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-c776322454156e36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-77bbd17f4435aa10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-049689e611ecc936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-85954a4fb09c44eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-e773e552e1068ee6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5633c4bfa7684b4a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d829b92bd01b4994.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-061c317fc771becf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3a45ece8865ed4b6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-0be990618c0d56bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-bfea4865dc244b73.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d6ba8e337741484.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-76a88b55d816482e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-bba1542df59f61ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-4185c95689bb372e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-b699e1a8d5d34b8b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-c225e338c31bf274.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-449353f70507ca1f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-90b889714102476d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f1ee7fbeb7f96ddc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-d59a95e1434dfaa0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-71491a23414d1a47.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-de7112bdb65fa4fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-feb4d0d88079660d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-f17d887b40dd6b1d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-8da77be2192bcd5d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-72c3b9a5e9582b29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c3afe4c8d0c48c39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-b9308f2d8a931531.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-6f35f9d892fa630b.js +0 -1
- package/apps/pwa/out/_next/static/css/85f53c6f35d11382.css +0 -1
- /package/apps/pwa/out/_next/static/{J5H7BvqgSI8DUjtRRcA_S → MObU8ujkMciAKr6ljAV05}/_ssgManifest.js +0 -0
- /package/skills/project-onboarding/{skill.md → SKILL.md} +0 -0
package/src/cli/release-cli.ts
CHANGED
|
@@ -45,6 +45,7 @@ import type { PrereleaseKind } from '../../scripts/release-loop/release-version.
|
|
|
45
45
|
import { releaseReadiness } from '../../scripts/release-loop/release-readiness.js';
|
|
46
46
|
import { runReleaseIfReady } from './release-run-if-ready.js';
|
|
47
47
|
import { formatPreflight, releasePreflight } from '../../scripts/release-loop/preflight.js';
|
|
48
|
+
import { defaultReleaseGraphRunsRoot, formatPublishProposal, measurePublishWindow, proposePublishAt, publishWindowWarning } from '../../scripts/release-loop/publish-window.js';
|
|
48
49
|
import { autoStartScheduledRelease, type AutoStartDeferral } from '../release-loop/auto-start.js';
|
|
49
50
|
import { landingFreezeMessage, LandingFrozenError, readLandingFreeze } from '../release-loop/landing-freeze.js';
|
|
50
51
|
import { formatLightRc, runLightRc, type LightRcDeps } from '../release-loop/light-rc.js';
|
|
@@ -609,6 +610,8 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
|
|
|
609
610
|
}
|
|
610
611
|
return hqCliWriteAllowed(command, override, ledgerFenceDeps());
|
|
611
612
|
};
|
|
613
|
+
// PUBLISH-TIME-FROM-GATE: the measured cut→publish window comes from the same ledger as the schedule (prod by default).
|
|
614
|
+
const publishMeasure = () => measurePublishWindow({ root: defaultReleaseGraphRunsRoot(scheduleLedgerRoot()) });
|
|
612
615
|
schedule.command('list').option('--json', '결과 JSON').action((o: { json?: boolean }) => {
|
|
613
616
|
const rows = listSchedules(scheduleLedgerRoot());
|
|
614
617
|
if (o.json) console.log(JSON.stringify(rows));
|
|
@@ -618,15 +621,27 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
|
|
|
618
621
|
.action((o: { version: string; json?: boolean }) => {
|
|
619
622
|
const row = getSchedule(o.version, scheduleLedgerRoot());
|
|
620
623
|
if (!row) throw new CliUserError(`없는 판 일정: ${o.version}`, '판 일정 등록: elanous release schedule set --version <v> --cut-at <iso> --land-by <iso>');
|
|
621
|
-
|
|
624
|
+
const measure = publishMeasure();
|
|
625
|
+
const proposedPublishAt = proposePublishAt(row.cutAt, measure);
|
|
626
|
+
if (o.json) console.log(JSON.stringify({ ...row, proposedPublishAt, measuredPublishMedianSeconds: measure.medianSeconds, measuredPublishSamples: measure.samples.map(({ version, seconds }) => ({ version, seconds })) }));
|
|
627
|
+
else { console.log(formatSchedule(row)); console.log(formatPublishProposal(row.cutAt, measure)); }
|
|
622
628
|
});
|
|
623
629
|
schedule.command('set').requiredOption('--version <v>', '갱신할 판')
|
|
624
630
|
.option('--cut-at <iso>', '오프셋 포함 컷 시각').option('--land-by <iso>', '오프셋 포함 착지 마감')
|
|
625
|
-
.option('--freeze-from <iso>', '동결 시작').option('--freeze-until <iso>', '동결 종료')
|
|
626
|
-
.
|
|
627
|
-
|
|
631
|
+
.option('--freeze-from <iso>', '동결 시작').option('--freeze-until <iso>', '동결 종료')
|
|
632
|
+
.option('--publish-at <iso>', '오프셋 포함 발행 시각(실측 컷→발행 중앙값보다 짧으면 경고 · 제안은 schedule show)')
|
|
633
|
+
.option('--json', '결과 JSON').option('--hq-override')
|
|
634
|
+
.action((o: { version: string; cutAt?: string; landBy?: string; freezeFrom?: string; freezeUntil?: string; publishAt?: string; json?: boolean; hqOverride?: boolean }) => {
|
|
635
|
+
if (o.cutAt === undefined && o.landBy === undefined && o.freezeFrom === undefined && o.freezeUntil === undefined && o.publishAt === undefined) throw new CliUserError('갱신할 시각을 지정하라', '--cut-at <iso> 또는 --land-by <iso> 또는 --publish-at <iso>');
|
|
628
636
|
if (!mayWriteLedger('release schedule set', Boolean(o.hqOverride), scheduleLedgerRoot())) return;
|
|
629
|
-
const row = setSchedule(o.version, { cutAt: o.cutAt, landBy: o.landBy, freezeFrom: o.freezeFrom, freezeUntil: o.freezeUntil }, process.env.ELANOUS_TRACK || 'cli', scheduleLedgerRoot());
|
|
637
|
+
const row = setSchedule(o.version, { cutAt: o.cutAt, landBy: o.landBy, freezeFrom: o.freezeFrom, freezeUntil: o.freezeUntil, publishAt: o.publishAt }, process.env.ELANOUS_TRACK || 'cli', scheduleLedgerRoot());
|
|
638
|
+
// A stored publish time shorter than the measured median warns on stderr (one line) — --json stdout stays parseable.
|
|
639
|
+
if (row.publishAt && (o.publishAt !== undefined || o.cutAt !== undefined)) {
|
|
640
|
+
const measure = publishMeasure();
|
|
641
|
+
const warning = publishWindowWarning(row.cutAt, row.publishAt, measure);
|
|
642
|
+
debug.log('release.schedule', 'publish-window', { version: row.version, cutAt: row.cutAt, publishAt: row.publishAt, medianSeconds: measure.medianSeconds, samples: measure.samples.length, warned: warning !== null });
|
|
643
|
+
if (warning) console.error(warning);
|
|
644
|
+
}
|
|
630
645
|
if (o.json) console.log(JSON.stringify(row)); else console.log(formatSchedule(row));
|
|
631
646
|
});
|
|
632
647
|
release.command('place <id>').description('칸의 우선순위·마감·용량으로 판 배치')
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import type { Command } from 'commander';
|
|
3
|
+
import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
|
|
4
|
+
|
|
5
|
+
type RetroFact = { store: string; at: string; category: string; event: string; kind: 'draft-birth' | 'draft-death' | 'stop-reason' | 'ta-outcome'; data: unknown };
|
|
6
|
+
|
|
7
|
+
const FACT_EVENTS = new Map<string, RetroFact['kind']>([
|
|
8
|
+
['rework-blocked-draft-pr', 'draft-birth'],
|
|
9
|
+
['lineage-supersede', 'draft-death'],
|
|
10
|
+
['resolved', 'stop-reason'],
|
|
11
|
+
['decision', 'stop-reason'],
|
|
12
|
+
['action', 'ta-outcome'],
|
|
13
|
+
['task-agent.action', 'ta-outcome'],
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
export function parseRetroSince(value: string, now = Date.now()): number {
|
|
17
|
+
const match = /^([1-9]\d*)([smhd])$/.exec(value);
|
|
18
|
+
if (!match) throw new Error('--since requires a positive duration (e.g. 24h)');
|
|
19
|
+
const duration = Number(match[1]) * ({ s: 1000, m: 60000, h: 3600000, d: 86400000 }[match[2]!] ?? 0);
|
|
20
|
+
if (!Number.isSafeInteger(duration) || !Number.isSafeInteger(now - duration)) throw new Error('--since duration is out of range');
|
|
21
|
+
return now - duration;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function collectRetroFacts(sinceMs: number, targets: readonly { name: string; dbPath: string }[] = [{ name: 'current', dbPath: logsDbPath() }]): { facts: RetroFact[]; unavailable: string[] } {
|
|
25
|
+
const facts: RetroFact[] = [];
|
|
26
|
+
const unavailable: string[] = [];
|
|
27
|
+
const untilMs = Date.now();
|
|
28
|
+
for (const target of targets) {
|
|
29
|
+
if (!existsSync(target.dbPath)) { unavailable.push(target.name); continue; }
|
|
30
|
+
try {
|
|
31
|
+
const store = LogStore.openReadOnly(target.dbPath);
|
|
32
|
+
try {
|
|
33
|
+
let beforeId: number | undefined;
|
|
34
|
+
for (;;) {
|
|
35
|
+
const rows = store.query({ sinceMs, beforeId, limit: 1000 });
|
|
36
|
+
for (const row of rows) {
|
|
37
|
+
if (Date.parse(row.ts) > untilMs) continue;
|
|
38
|
+
const kind = FACT_EVENTS.get(row.event);
|
|
39
|
+
if (!kind || (row.event === 'resolved' && row.category !== 'self-dev.supervisor') || ((row.event === 'task-agent.action' || row.event === 'action') && row.category !== 'task-agent')) continue;
|
|
40
|
+
let data: unknown;
|
|
41
|
+
try { data = row.data === null ? null : JSON.parse(row.data); } catch { data = row.data; }
|
|
42
|
+
const record = data && typeof data === 'object' && !Array.isArray(data) ? data as Record<string, unknown> : {};
|
|
43
|
+
if (row.event === 'rework-blocked-draft-pr' && (row.category !== 'self-implement' || !Number.isInteger(record.number) || record.skipped || record.error)) continue;
|
|
44
|
+
if (row.event === 'lineage-supersede' && (row.category !== 'self-implement' || !Array.isArray(record.closed) || record.closed.length === 0)) continue;
|
|
45
|
+
if (row.event === 'resolved' && typeof record.stopReason !== 'string') continue;
|
|
46
|
+
if (row.event === 'decision' && (row.category !== 'self-dev.supervisor' || record.action !== 'stop' || typeof record.stopReason !== 'string')) continue;
|
|
47
|
+
if ((row.event === 'task-agent.action' || row.event === 'action') && (row.category !== 'task-agent' || typeof record.result !== 'string' || !record.result.trim())) continue;
|
|
48
|
+
facts.push({ store: target.name, at: row.ts, category: row.category, event: row.event, kind, data });
|
|
49
|
+
}
|
|
50
|
+
if (rows.length < 1000) break;
|
|
51
|
+
beforeId = rows.at(-1)!.id;
|
|
52
|
+
}
|
|
53
|
+
} finally { store.close(); }
|
|
54
|
+
} catch { unavailable.push(target.name); }
|
|
55
|
+
}
|
|
56
|
+
facts.sort((a, b) => b.at.localeCompare(a.at));
|
|
57
|
+
return { facts, unavailable };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function registerRetroCommands(program: Command): void {
|
|
61
|
+
program.command('retro').description('Read-only retrospective facts from existing logs')
|
|
62
|
+
.command('facts').description('Draft births/deaths, stop reasons and task-agent outcomes')
|
|
63
|
+
.option('--since <duration>', 'Lookback duration', '24h')
|
|
64
|
+
.option('--json', 'JSON output')
|
|
65
|
+
.action((opts: { since: string; json?: boolean }) => {
|
|
66
|
+
try {
|
|
67
|
+
const sinceMs = parseRetroSince(opts.since);
|
|
68
|
+
const result = { since: new Date(sinceMs).toISOString(), ...collectRetroFacts(sinceMs) };
|
|
69
|
+
console.log(opts.json ? JSON.stringify(result) : [
|
|
70
|
+
`retro facts since ${result.since} · ${result.facts.length} facts · unavailable: ${result.unavailable.join(', ') || 'none'}`,
|
|
71
|
+
...result.facts.map((fact) => `${fact.at} ${fact.kind} ${fact.category}.${fact.event} ${JSON.stringify(fact.data)}`),
|
|
72
|
+
].join('\n'));
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error(`retro facts: ${error instanceof Error ? error.message : String(error)}`);
|
|
75
|
+
process.exitCode = 2;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
package/src/cli/tasks-cli.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
1
|
+
import { closeSync, mkdirSync, openSync, readFileSync, readSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { loadRunLedger as loadRunLedgerSync } from '../self-implement/run-ledger.js';
|
|
2
4
|
import { join, resolve } from 'node:path';
|
|
3
5
|
import { InvalidArgumentError, Option, type Command } from 'commander';
|
|
4
6
|
import { debug } from '../debug/log.js';
|
|
@@ -8,7 +10,7 @@ import { checklistDevVersion } from '../release-loop/checklist.js';
|
|
|
8
10
|
import { cardsBoard, countBoardTasks, INTERNAL_PACK_PROJECT, mergeBoards, releasePackBoard, type BoardNode } from '../task-agent/board.js';
|
|
9
11
|
import type { Task } from '../task-orchestrator/types.js';
|
|
10
12
|
import { cardPrNumber, COMPLETION_KINDS, handTask, nextMoveFor, readTaskAgentState, readTaskCard, taskAgentStatePath as taskStatePathDefault, shellQuote, TASK_CARD_PREFIX, TASK_SEATS, type CompletionKind, type TaskCard, type TaskLaunchContext, type TaskLaunchReceipt, type TaskLauncher, type TaskSeat } from '../task-agent/task-hand.js';
|
|
11
|
-
import { refreshCardRunBinding, type CardRunEvidenceDeps } from '../task-agent/card-evidence.js';
|
|
13
|
+
import { readCardSalvageBranch, refreshCardRunBinding, type CardRunEvidenceDeps } from '../task-agent/card-evidence.js';
|
|
12
14
|
import { advanceMission, handMission, MissionAdvanceError, openMissionIds, recordPieceRef, type AdvanceMissionResult, type MissionDecompose, type PieceEvidenceReader } from '../task-agent/mission.js';
|
|
13
15
|
|
|
14
16
|
type TaskRow = Pick<Task, 'id' | 'title' | 'priority' | 'status' | 'createdAt' | 'approval' | 'generatedBy'>;
|
|
@@ -32,6 +34,10 @@ export interface TasksCliDeps {
|
|
|
32
34
|
releaseBoard?: () => BoardNode[];
|
|
33
35
|
/** `tasks show`·`advance` 의 런 근거 읽기(시험 주입) — 기본 = 런 원장(이 우주 ⊕ 연합) ⊕ 호스트 logs 의 Pod job-finished. */
|
|
34
36
|
cardRunEvidence?: CardRunEvidenceDeps;
|
|
37
|
+
/** HARNESS-PARENT-ON-MSB1 — 원격 부모 카드의 원장 거울(시험 주입). 기본 = ssh 로 `<prodRoot>/remote-parents/<host>/run-ledger`. */
|
|
38
|
+
remoteLedgerMirror?: (card: TaskCard) => void;
|
|
39
|
+
/** `tasks parents` 의 낡은 부모 보고 의존(시험 주입). */
|
|
40
|
+
staleParents?: import('../task-agent/parent-host.js').StaleParentDeps;
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
/** `<조각id>=<값>` 반복 인자. */
|
|
@@ -82,14 +88,147 @@ export function taskLauncherArgv(configDir: string, args: readonly string[]): st
|
|
|
82
88
|
return [ELANOUS_CLI_ENTRY, '--config-dir', configDir, ...args];
|
|
83
89
|
}
|
|
84
90
|
|
|
85
|
-
|
|
91
|
+
/** STOP-RECORD launch-failed: 발사 직후 이 창 안에 자식이 비0 으로 끝나면 «발사 실패»로 본다. */
|
|
92
|
+
export const LAUNCH_EARLY_EXIT_WINDOW_MS = 3_000;
|
|
93
|
+
|
|
94
|
+
export interface DefaultTaskLauncherDeps {
|
|
95
|
+
spawn?: DetachedSpawn;
|
|
96
|
+
/** 조기 종료 감시 창(ms) — context(런 id)가 있을 때만 · 0 이면 감시하지 않는다(옛 동작). */
|
|
97
|
+
earlyExitWindowMs?: number;
|
|
98
|
+
/** 자식 stderr 를 받을 디렉토리(시험 주입). 기본 = `<tmpdir>/elanous-task-launch`. */
|
|
99
|
+
stderrDir?: string;
|
|
100
|
+
/** stop 줄 기록기(시험 주입). 기본 = 런 원장. */
|
|
101
|
+
writeStop?: import('../self-implement/run-ledger.js').RunLedgerWriter;
|
|
102
|
+
/** 이미 stop 이 있나(시험 주입). 기본 = 이 우주 런 원장 ⊕ 이 프로세스 기록. */
|
|
103
|
+
hasStop?: (runId: string) => boolean;
|
|
104
|
+
/** HARNESS-PARENT-ON-MSB1 — 원격 부모 대상(시험 주입). undefined = 설정·env 에서 푼다 · null = 끔. */
|
|
105
|
+
parentHost?: import('../task-agent/parent-host.js').ParentHostConfig | null;
|
|
106
|
+
/** 원격 ssh(시험 주입). */
|
|
107
|
+
ssh?: import('../task-agent/parent-host.js').SshRunner;
|
|
108
|
+
/** HQ 발사 동결(holdLaunches) 여부(시험 주입). */
|
|
109
|
+
launchHoldActive?: () => boolean;
|
|
110
|
+
/** HQ 판(시험 주입). */
|
|
111
|
+
localVersion?: string;
|
|
112
|
+
/** 원격 → 로컬 되돌림 알림(시험 주입). 기본 = stderr 한 줄. */
|
|
113
|
+
notice?: (line: string) => void;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* HARNESS-PARENT-ON-MSB1 — 켜져 있고 발사 전 점검이 통과하면 원격(ssh)에서 부모를 띄운다(PR 까지만 · 병합은 HQ).
|
|
118
|
+
* 막히면 null — 호출부가 종전 로컬 발사로 간다(관측: task-agent parent-host-fallback).
|
|
119
|
+
*/
|
|
120
|
+
async function tryRemoteParent(args: string[], cwd: string | undefined, context: TaskLaunchContext, deps: DefaultTaskLauncherDeps): Promise<TaskLaunchReceipt | null> {
|
|
121
|
+
const parentHostModule = await import('../task-agent/parent-host.js');
|
|
122
|
+
let target = deps.parentHost;
|
|
123
|
+
if (target === undefined) {
|
|
124
|
+
const { getUserConfig } = await import('../user-config.js');
|
|
125
|
+
let configured: Parameters<typeof parentHostModule.resolveParentHost>[0];
|
|
126
|
+
try { configured = getUserConfig().taskAgent?.parentHost; } catch { configured = undefined; }
|
|
127
|
+
target = parentHostModule.resolveParentHost(configured);
|
|
128
|
+
}
|
|
129
|
+
if (!target) return null;
|
|
130
|
+
const notice = deps.notice ?? ((line: string) => { try { process.stderr.write(`${line}\n`); } catch { /* ignore */ } });
|
|
131
|
+
const fallback = (gaps: string[], facts: Record<string, string> = {}): null => {
|
|
132
|
+
try { debug.log('task-agent', 'parent-host-fallback', { host: target!.host, runId: context.runId, gaps, facts }); } catch { /* fail-soft */ }
|
|
133
|
+
notice(`[parent-host] ${target!.host} 로 못 띄움 — 로컬 발사로 간다: ${gaps.join(' · ')}`);
|
|
134
|
+
return null;
|
|
135
|
+
};
|
|
136
|
+
if (cwd) return fallback(['project-target-is-local']);
|
|
137
|
+
let launchHoldActive = false;
|
|
138
|
+
try {
|
|
139
|
+
if (deps.launchHoldActive) launchHoldActive = deps.launchHoldActive();
|
|
140
|
+
else {
|
|
141
|
+
const { readLandingFreeze } = await import('../release-loop/landing-freeze.js');
|
|
142
|
+
const { prodInstanceRoot } = await import('../instance/resolve.js');
|
|
143
|
+
launchHoldActive = readLandingFreeze(prodInstanceRoot())?.holdLaunches === true;
|
|
144
|
+
}
|
|
145
|
+
} catch { launchHoldActive = true; /* 못 읽으면 막힌 것으로(fail-closed) */ }
|
|
146
|
+
const preflight = parentHostModule.preflightParentHost({ target, localVersion: deps.localVersion ?? parentHostModule.localElanousVersion(), launchHoldActive, ...(deps.ssh ? { ssh: deps.ssh } : {}) });
|
|
147
|
+
if (!preflight.ok) return fallback(preflight.gaps, preflight.facts);
|
|
148
|
+
try {
|
|
149
|
+
const launched = parentHostModule.launchRemoteParent(target, args, context.env, deps.ssh);
|
|
150
|
+
try { debug.log('task-agent', 'parent-host-launched', { host: target.host, runId: context.runId, pid: launched.pid, log: launched.log }); } catch { /* fail-soft */ }
|
|
151
|
+
return { runId: context.runId, parentHost: { host: target.host, ...(target.configDir ? { configDir: target.configDir } : {}), pid: launched.pid, log: launched.log } };
|
|
152
|
+
} catch (error) {
|
|
153
|
+
// «확실히 안 떴다»일 때만 로컬로 — 불확실(ssh 끊김 등)은 던져 카드를 launch-failed 로 남긴다(중복 발사 방지).
|
|
154
|
+
if (error instanceof parentHostModule.RemoteParentNotLaunchedError) return fallback([error.message]);
|
|
155
|
+
try { debug.log('task-agent', 'parent-host-launch-uncertain', { host: target.host, runId: context.runId, error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** stderr 파일의 첫 비어 있지 않은 줄(최대 4KB 만 읽는다 — 원 로그 꼬리를 싣지 않는다). */
|
|
161
|
+
function firstStderrLine(path: string): string {
|
|
162
|
+
try {
|
|
163
|
+
const fd = openSync(path, 'r');
|
|
164
|
+
try {
|
|
165
|
+
const buf = Buffer.alloc(4096);
|
|
166
|
+
const n = readSync(fd, buf, 0, buf.length, 0);
|
|
167
|
+
return buf.subarray(0, n).toString('utf8').split(/\r?\n/).map((line) => line.trim()).find((line) => line.length > 0) ?? '';
|
|
168
|
+
} finally { closeSync(fd); }
|
|
169
|
+
} catch { return ''; }
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export async function defaultTaskLauncher(args: string[], cwd?: string, context?: TaskLaunchContext, deps: DefaultTaskLauncherDeps = {}): Promise<void | TaskLaunchReceipt> {
|
|
173
|
+
if (context) {
|
|
174
|
+
const remote = await tryRemoteParent(args, cwd, context, deps);
|
|
175
|
+
if (remote) return remote;
|
|
176
|
+
}
|
|
86
177
|
const spawn = deps.spawn ?? ((await import('node:child_process')).spawn as unknown as DetachedSpawn);
|
|
87
178
|
const { getElanousConfigDirOverride } = await import('../elanous-config-dir.js');
|
|
88
179
|
const { prodInstanceRoot } = await import('../instance/resolve.js');
|
|
89
180
|
const configDir = getElanousConfigDirOverride() ?? prodInstanceRoot();
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
181
|
+
const argv = taskLauncherArgv(configDir, args);
|
|
182
|
+
const window = context ? deps.earlyExitWindowMs ?? LAUNCH_EARLY_EXIT_WINDOW_MS : 0;
|
|
183
|
+
if (!context || window <= 0) {
|
|
184
|
+
// TA-CARD-RUN-LINK: 런 id 를 자식 환경에 얹는다 — `harness say` 의 런(호스트 orchestrate)이 그 id 를 상속한다.
|
|
185
|
+
await spawnDetachedConfirmed(spawn, process.execPath, argv, SPAWN_CONFIRM_TIMEOUT_MS, cwd, context?.env);
|
|
186
|
+
return context ? { runId: context.runId } : undefined;
|
|
187
|
+
}
|
|
188
|
+
// STOP-RECORD launch-failed: stdio 를 버리면 자식이 exit 2 로 죽어도 흔적이 0 이고 카드는 «launched» 로 남는다
|
|
189
|
+
// (ORCH-LIVE-1008). stderr 만 파일로 받고(파이프는 부모가 먼저 끝나면 자식을 EPIPE 로 죽인다), 짧은 창 안의 종료를 본다.
|
|
190
|
+
const stderrDir = deps.stderrDir ?? join(tmpdir(), 'elanous-task-launch');
|
|
191
|
+
mkdirSync(stderrDir, { recursive: true });
|
|
192
|
+
const stderrPath = join(stderrDir, `${context.runId}.stderr`);
|
|
193
|
+
// 'w' — 같은 runId 재발사가 지난 시도의 stderr 를 이번 cause 로 읽지 않게(리뷰 must-fix).
|
|
194
|
+
const fd = openSync(stderrPath, 'w');
|
|
195
|
+
let exited: Promise<{ code: number | null; signal: string | null }> | undefined;
|
|
196
|
+
const watched: DetachedSpawn = (command, spawnArgs, options) => {
|
|
197
|
+
const child = (spawn as unknown as (c: string, a: string[], o: unknown) => ReturnType<DetachedSpawn>)(command, spawnArgs, { ...options, stdio: ['ignore', 'ignore', fd] });
|
|
198
|
+
const emitter = child as unknown as { once?: (event: 'exit', listener: (code: number | null, signal: string | null) => void) => unknown };
|
|
199
|
+
exited = new Promise((done) => { emitter.once?.('exit', (code, signal) => done({ code, signal })); });
|
|
200
|
+
return child;
|
|
201
|
+
};
|
|
202
|
+
try {
|
|
203
|
+
await spawnDetachedConfirmed(watched, process.execPath, argv, SPAWN_CONFIRM_TIMEOUT_MS, cwd, context.env);
|
|
204
|
+
} finally {
|
|
205
|
+
try { closeSync(fd); } catch { /* the child keeps its own copy */ }
|
|
206
|
+
}
|
|
207
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
208
|
+
const early = exited
|
|
209
|
+
? await Promise.race([exited, new Promise<undefined>((done) => { timer = setTimeout(() => done(undefined), window); })])
|
|
210
|
+
: undefined;
|
|
211
|
+
if (timer) clearTimeout(timer);
|
|
212
|
+
if (early && early.code !== 0) {
|
|
213
|
+
const first = firstStderrLine(stderrPath);
|
|
214
|
+
const cause = `child rc=${early.code ?? early.signal ?? 'unknown'}${first ? `: ${first}` : ''}`;
|
|
215
|
+
const { boundRunStopCause, recordRunStop, runStopRecorded, RUN_STOP_EVENT } = await import('../self-implement/run-stop.js');
|
|
216
|
+
const hasStop = deps.hasStop ?? ((id: string) => {
|
|
217
|
+
if (runStopRecorded(id)) return true;
|
|
218
|
+
try { return (loadRunLedgerSync(id) ?? []).some((entry) => entry.event === RUN_STOP_EVENT); } catch { return false; }
|
|
219
|
+
});
|
|
220
|
+
// 자식이 같은 runId 로 이미 stop 을 썼으면 더하지 않는다(런마다 한 줄 · 리뷰 must-fix).
|
|
221
|
+
if (hasStop(context.runId)) throw new Error(`발사 직후 자식이 종료했다 — ${boundRunStopCause(cause)}`);
|
|
222
|
+
const entry = recordRunStop({
|
|
223
|
+
runId: context.runId, site: 'launch-failed', class: 'launch-failed',
|
|
224
|
+
cause,
|
|
225
|
+
evidenceRef: stderrPath,
|
|
226
|
+
nextMove: 'Fix the launch argv/config from the stderr evidence, then re-hand the card',
|
|
227
|
+
}, ...(deps.writeStop ? [deps.writeStop] : []));
|
|
228
|
+
// handTask 가 이 예외로 카드를 `launch-failed` 로 적는다(«launched» 로 남지 않게).
|
|
229
|
+
throw new Error(`발사 직후 자식이 종료했다 — ${String(entry.data.cause)}`);
|
|
230
|
+
}
|
|
231
|
+
return { runId: context.runId };
|
|
93
232
|
}
|
|
94
233
|
|
|
95
234
|
/** `spawn` 의 필요한 면만(시험 주입). */
|
|
@@ -131,6 +270,21 @@ export function spawnDetachedConfirmed(spawnFn: DetachedSpawn, command: string,
|
|
|
131
270
|
});
|
|
132
271
|
}
|
|
133
272
|
|
|
273
|
+
/** HARNESS-PARENT-ON-MSB1 — 카드가 원격 부모면 그 런 원장(⊕ Pod 자식)을 HQ 거울로 당긴다. 실패는 관측만(«없음»으로 읽히지 않게). */
|
|
274
|
+
async function mirrorRemoteCardLedger(cardId: string, deps: TasksCliDeps): Promise<void> {
|
|
275
|
+
let card: TaskCard | undefined;
|
|
276
|
+
try { card = readTaskCard(cardId, deps.taskStatePath); } catch { return; }
|
|
277
|
+
if (!card?.parentHost || !card.runId) return;
|
|
278
|
+
try {
|
|
279
|
+
if (deps.remoteLedgerMirror) { deps.remoteLedgerMirror(card); return; }
|
|
280
|
+
const { mirrorRemoteRunLedgers } = await import('../task-agent/parent-host.js');
|
|
281
|
+
const { prodInstanceRoot } = await import('../instance/resolve.js');
|
|
282
|
+
mirrorRemoteRunLedgers(card.parentHost, card.runId, prodInstanceRoot());
|
|
283
|
+
} catch (error) {
|
|
284
|
+
try { debug.log('task-agent', 'remote-ledger-mirror-failed', { card: cardId, host: card.parentHost.host, runId: card.runId, error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
134
288
|
function moveLine(card: TaskCard): string {
|
|
135
289
|
const move = nextMoveFor(card);
|
|
136
290
|
return `${move.kind}${move.command ? ` — elanous ${move.command.map(shellQuote).join(' ')}` : ''} (${move.reason})`;
|
|
@@ -365,6 +519,32 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
|
|
|
365
519
|
}
|
|
366
520
|
});
|
|
367
521
|
|
|
522
|
+
tasks.command('parents')
|
|
523
|
+
.description('낡은 하니스 부모 보고(읽기 전용 · 죽이지 않는다) — 나이 ≥ N 시간이고 런 원장이 끝났거나(run-status) Pod 이 없는 `harness say|ask` 부모')
|
|
524
|
+
.option('--older-than <hours>', '나이 하한(시간)', '6')
|
|
525
|
+
.option('--no-pods', 'Pod 목록을 재지 않는다(원장 근거만)')
|
|
526
|
+
.option('--json', 'JSON 출력')
|
|
527
|
+
.action(async (opts: { olderThan: string; pods?: boolean; json?: boolean }) => {
|
|
528
|
+
const hours = Number(opts.olderThan);
|
|
529
|
+
if (!Number.isFinite(hours) || hours < 0) { out(`--older-than 는 0 이상 수다: ${opts.olderThan}`); process.exitCode = 1; return; }
|
|
530
|
+
const { staleHarnessParents } = await import('../task-agent/parent-host.js');
|
|
531
|
+
const injected = deps.staleParents ?? {};
|
|
532
|
+
const loadLedger = injected.loadLedger ?? ((runId: string) => loadRunLedgerSync(runId));
|
|
533
|
+
let podRuns = injected.podRuns;
|
|
534
|
+
let labelOf = injected.labelOf;
|
|
535
|
+
if (!podRuns && opts.pods !== false) {
|
|
536
|
+
const queue = await import('../harness/harness-queue.js');
|
|
537
|
+
podRuns = () => queue.readHarnessQueuePodRuns();
|
|
538
|
+
labelOf = queue.queueRunLabelValue;
|
|
539
|
+
}
|
|
540
|
+
const report = staleHarnessParents(hours, { ...injected, loadLedger, ...(podRuns ? { podRuns } : {}), ...(labelOf ? { labelOf } : {}) });
|
|
541
|
+
try { debug.log('task-agent', 'stale-parents', { olderThanHours: hours, scanned: report.scanned, stale: report.rows.length, podRunsMeasured: report.podRunsMeasured }); } catch { /* fail-soft */ }
|
|
542
|
+
if (opts.json) { out(JSON.stringify({ olderThanHours: hours, ...report })); return; }
|
|
543
|
+
out(`하니스 부모 ${report.scanned} · 나이 ≥ ${hours}h 중 낡음 후보 ${report.rows.length}${report.podRunsMeasured ? '' : ' · ⚠ Pod 목록 못 잼(원장 근거만)'} — 읽기 전용(죽이지 않는다)`);
|
|
544
|
+
out('pid\t나이h\t자리\t판\t런\t사유');
|
|
545
|
+
for (const row of report.rows) out([row.pid, row.ageHours, row.seat ?? '-', row.version ?? '-', row.runId ?? '-', row.reasons.join(',')].join('\t'));
|
|
546
|
+
});
|
|
547
|
+
|
|
368
548
|
tasks.command('board')
|
|
369
549
|
.description('보드 — 프로젝트 › 목표 › 이정표 › 과제. 과제 카드(project·goal·milestone)와 내부 팩(릴리스 체크리스트 = elanous › 판 › 칸)을 합쳐 읽는다(쓰지 않는다)')
|
|
370
550
|
.option('--project <id>', '이 프로젝트만')
|
|
@@ -492,6 +672,8 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
|
|
|
492
672
|
// 런 id 가 있으면 원장에서 골 id · PR 을 묶는다(찾았을 때만 적는다 · 실패는 그대로 보인다).
|
|
493
673
|
const bindable = card?.pieces ? card.pieces : card ? [card.id] : [];
|
|
494
674
|
for (const cardId of bindable) {
|
|
675
|
+
// HARNESS-PARENT-ON-MSB1: 원격 부모 런은 원장이 그 호스트에 있다 — HQ 거울로 먼저 당긴다(읽기 전용).
|
|
676
|
+
await mirrorRemoteCardLedger(cardId, deps);
|
|
495
677
|
try { await refreshCardRunBinding(cardId, deps.taskStatePath ?? taskStatePathDefault(), deps.cardRunEvidence ?? {}); } catch (error) {
|
|
496
678
|
// 근거 없음으로 보인다 — 원장 부재와 갈리게 실패는 남긴다.
|
|
497
679
|
try { debug.log('task-agent', 'card-bind-failed', { card: cardId, via: 'show', error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
|
|
@@ -523,8 +705,18 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
|
|
|
523
705
|
}
|
|
524
706
|
return;
|
|
525
707
|
}
|
|
526
|
-
|
|
527
|
-
|
|
708
|
+
// DRAFT-NOT-ARCHIVE: 멈춘 런이 draft PR 대신 남긴 수확 가지(원장 `salvaged`). 못 읽었으면 «못 읽음»(⛔ 없음 아님).
|
|
709
|
+
let salvage: Awaited<ReturnType<typeof readCardSalvageBranch>> = { salvageBranch: null };
|
|
710
|
+
try { salvage = await readCardSalvageBranch(card, deps.cardRunEvidence ?? {}); }
|
|
711
|
+
catch (error) { salvage = { salvageBranch: null, readErrors: [error instanceof Error ? error.message : String(error)] }; }
|
|
712
|
+
const salvageUnread = !salvage.salvageBranch && !!salvage.readErrors?.length;
|
|
713
|
+
if (opts.json) out(JSON.stringify({ card, nextMove: nextMoveFor(card), salvageBranch: salvage.salvageBranch, ...(salvageUnread ? { salvageBranchUnread: true } : {}) }));
|
|
714
|
+
else {
|
|
715
|
+
for (const line of taskCardLines(card)) out(line);
|
|
716
|
+
if (card.parentHost) out(`부모 호스트: ${card.parentHost.host}${card.parentHost.pid ? ` (pid ${card.parentHost.pid})` : ''} · PR 까지만 — 병합은 HQ${card.parentHost.log ? ` · 로그 ${card.parentHost.host}:${card.parentHost.log}` : ''}`);
|
|
717
|
+
if (salvage.salvageBranch) out(`수확 가지: ${salvage.salvageBranch} (draft PR 대신)`);
|
|
718
|
+
else if (salvageUnread) out('수확 가지: 못 읽음(원장 읽기 실패)');
|
|
719
|
+
}
|
|
528
720
|
return;
|
|
529
721
|
}
|
|
530
722
|
try {
|
package/src/dashboard/index.ts
CHANGED
|
@@ -769,6 +769,15 @@ export function clearEscAbortToolState(toolState: EscAbortToolState): void {
|
|
|
769
769
|
toolState.activeToolNamesByCallId.clear();
|
|
770
770
|
}
|
|
771
771
|
|
|
772
|
+
export function activeEscHarnessSpace(
|
|
773
|
+
toolState: EscAbortToolState,
|
|
774
|
+
spacesByCallId: ReadonlyMap<string, string>,
|
|
775
|
+
): string | null {
|
|
776
|
+
const active = [...toolState.activeToolNamesByCallId].filter(([, name]) =>
|
|
777
|
+
(SELF_IMPLEMENT_TOOL_NAMES as readonly string[]).includes(name));
|
|
778
|
+
return active.length === 1 ? spacesByCallId.get(active[0]![0]) ?? null : null;
|
|
779
|
+
}
|
|
780
|
+
|
|
772
781
|
/** Reset per-turn ESC tool tracking before a new stream runtime begins. */
|
|
773
782
|
export function createDashboardTurnStreamRuntimeEscBoundary(toolState: EscAbortToolState): void {
|
|
774
783
|
clearEscAbortToolState(toolState);
|
|
@@ -1324,6 +1333,8 @@ import {
|
|
|
1324
1333
|
PULSE_HALF_PERIOD_MS,
|
|
1325
1334
|
} from '../agent-activity-hud.js';
|
|
1326
1335
|
import { DASHBOARD_CLARIFICATION_REQUEST, consumeStreamingTopModalEscape, createEscAbortGate, createHarnessEscHint, routeStreamingEscapeKey } from '../esc-abort-gate.js';
|
|
1336
|
+
import { enqueueSoftStop, readSoftStopRequestStatus } from '../harness/control-inbox.js';
|
|
1337
|
+
import { setSelfImplementSoftStopSpaceObserver } from '../self-implement/self-implement-runtime.js';
|
|
1327
1338
|
import { createViEditor, type ViEditorHandle } from '../vi-editor.js';
|
|
1328
1339
|
import { launchEditor, canLaunchEditor } from '../editor-launcher.js';
|
|
1329
1340
|
import { createSshPickerModal } from '../ssh/ssh-picker-modal.js';
|
|
@@ -6700,6 +6711,13 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
6700
6711
|
* this function is invoked.
|
|
6701
6712
|
*/
|
|
6702
6713
|
const escAbortToolState = createEscAbortToolState();
|
|
6714
|
+
const escHarnessSpacesByCallId = new Map<string, string>();
|
|
6715
|
+
setSelfImplementSoftStopSpaceObserver((callId, spaceId) => {
|
|
6716
|
+
const toolName = escAbortToolState.activeToolNamesByCallId.get(callId);
|
|
6717
|
+
if (toolName && (SELF_IMPLEMENT_TOOL_NAMES as readonly string[]).includes(toolName)) {
|
|
6718
|
+
escHarnessSpacesByCallId.set(callId, spaceId);
|
|
6719
|
+
}
|
|
6720
|
+
});
|
|
6703
6721
|
let clarificationModalId: string | null = null;
|
|
6704
6722
|
|
|
6705
6723
|
const attachChatStreamingKeys = (abortCtrl: AbortController): () => void => {
|
|
@@ -6713,6 +6731,8 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
6713
6731
|
// so the user can make an informed call.
|
|
6714
6732
|
let abortGateModalId: string | null = null;
|
|
6715
6733
|
const showHarnessEscHint = createHarnessEscHint((line) => pushChatLine(line));
|
|
6734
|
+
let stoppedHarnessSpace: string | null = null;
|
|
6735
|
+
const activeHarnessSpace = (): string | null => activeEscHarnessSpace(escAbortToolState, escHarnessSpacesByCallId);
|
|
6716
6736
|
const escGate = createEscAbortGate({
|
|
6717
6737
|
abortCtrl,
|
|
6718
6738
|
getRunningCount: () => getEscAbortRunningCount(escAbortToolState),
|
|
@@ -6726,14 +6746,25 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
6726
6746
|
requestRedraw: () => draw(),
|
|
6727
6747
|
getTheme: () => currentThemeTokens(),
|
|
6728
6748
|
getWaitingTargetNames: () => getEscAbortWaitingToolNames(escAbortToolState),
|
|
6749
|
+
shouldAbortImmediately: () => activeHarnessSpace() !== null,
|
|
6729
6750
|
onAbortPending: ({ targets }) => {
|
|
6730
|
-
|
|
6751
|
+
const spaceId = activeHarnessSpace();
|
|
6752
|
+
if (spaceId) {
|
|
6753
|
+
try {
|
|
6754
|
+
enqueueSoftStop(spaceId);
|
|
6755
|
+
if (readSoftStopRequestStatus(spaceId).status !== 'present') throw new Error('soft-stop marker not persisted');
|
|
6756
|
+
stoppedHarnessSpace = spaceId;
|
|
6757
|
+
pushChatLine(' ⏹ 멈췄다 — 해당 하니스 런에 중단 요청을 보냈습니다.');
|
|
6758
|
+
} catch {
|
|
6759
|
+
pushChatLine(' ⚠ 하니스 런 중단 요청을 보내지 못했습니다. /harness runs 에서 확인해 주세요.');
|
|
6760
|
+
}
|
|
6761
|
+
} else if (!showHarnessEscHint(targets)) {
|
|
6731
6762
|
pushChatLine(` ⏳ 중단 요청됨 — ${formatEscAbortWaitingTargets(targets)} 종료를 기다리는 중입니다.`);
|
|
6732
6763
|
}
|
|
6733
6764
|
chatScrollOffset = -1;
|
|
6734
6765
|
},
|
|
6735
6766
|
onAbortRepeat: ({ repeat, targets }) => {
|
|
6736
|
-
if (!showHarnessEscHint(targets)) {
|
|
6767
|
+
if (!stoppedHarnessSpace && !showHarnessEscHint(targets)) {
|
|
6737
6768
|
pushChatLine(` ⏳ ESC 재시도 ${repeat}회 — ${formatEscAbortWaitingTargets(targets)} 종료를 기다리는 중입니다.`);
|
|
6738
6769
|
}
|
|
6739
6770
|
chatScrollOffset = -1;
|
|
@@ -7251,7 +7282,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
7251
7282
|
return () => {
|
|
7252
7283
|
cleanup();
|
|
7253
7284
|
escGate.dispose();
|
|
7254
|
-
settleEscAbortPendingLines(chatLines, chatLinesStartIndex);
|
|
7285
|
+
if (!stoppedHarnessSpace) settleEscAbortPendingLines(chatLines, chatLinesStartIndex);
|
|
7255
7286
|
userScrolledDuringStream = false;
|
|
7256
7287
|
streamingInFlight = false;
|
|
7257
7288
|
};
|
|
@@ -15674,6 +15705,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
15674
15705
|
pushChatLine,
|
|
15675
15706
|
draw,
|
|
15676
15707
|
signal: acpTurnRef.abortCtrl?.signal ?? new AbortController().signal,
|
|
15708
|
+
toolCallId: ctx?.callId,
|
|
15677
15709
|
// ⛔⭐ 폴백은 `''` 가 아니라 `undefined` 다 — 「안 넘김」과 「말했는데 어휘가 없음」은 «다른 값»이다.
|
|
15678
15710
|
// harnessMentionState(session-runtime 소비처)는 `undefined → 'absent'` · `'' → 'not-matched'` 로
|
|
15679
15711
|
// 가른다. `?? ''` 로 접으면 그 둘이 같은 값이 되고, 그것이 2026-08-06 에 「TUI 가 하니스에게
|
|
@@ -15695,9 +15727,10 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
15695
15727
|
ptyDashboardOn:
|
|
15696
15728
|
uc.shell.allowDashboardPty === true && (acpPtyAvailable?.() ?? false),
|
|
15697
15729
|
getToolRuntime: (toolName) => runtime.getToolRuntime(toolName),
|
|
15698
|
-
dispatchToolRuntime: (toolName, input) =>
|
|
15730
|
+
dispatchToolRuntime: (toolName, input, toolCallId) =>
|
|
15699
15731
|
runtime.dispatchToolByName(toolName, input, {
|
|
15700
15732
|
surface: 'tui',
|
|
15733
|
+
toolCallId,
|
|
15701
15734
|
signal: acpTurnRef.abortCtrl?.signal,
|
|
15702
15735
|
// ⭐ Agent-family context. Without these two the sub-agent runs
|
|
15703
15736
|
// text-only (see getTools above). `agentDispatchTool` routes the
|
|
@@ -19171,6 +19204,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
19171
19204
|
createTurnStreamRuntime: (initialAssistantStart) => {
|
|
19172
19205
|
latestTurnUsage = undefined;
|
|
19173
19206
|
createDashboardTurnStreamRuntimeEscBoundary(escAbortToolState);
|
|
19207
|
+
escHarnessSpacesByCallId.clear();
|
|
19174
19208
|
liveTypeaheadEchoes.length = 0;
|
|
19175
19209
|
const toolRendering = {
|
|
19176
19210
|
...getUserConfig().chat.rendering.tool,
|
|
@@ -19225,6 +19259,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
19225
19259
|
const toolCall = call as DashboardTurnStreamCall;
|
|
19226
19260
|
turnStreamRuntime.onToolResult(toolCall);
|
|
19227
19261
|
settleEscAbortToolCall(escAbortToolState, toolCall);
|
|
19262
|
+
escHarnessSpacesByCallId.delete(toolCall.id);
|
|
19228
19263
|
},
|
|
19229
19264
|
};
|
|
19230
19265
|
},
|
|
@@ -19524,6 +19559,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
19524
19559
|
closeDashboardTui();
|
|
19525
19560
|
throw err;
|
|
19526
19561
|
} finally {
|
|
19562
|
+
setSelfImplementSoftStopSpaceObserver(null);
|
|
19527
19563
|
if (tuiSeatAskTimer) clearInterval(tuiSeatAskTimer);
|
|
19528
19564
|
}
|
|
19529
19565
|
}
|
|
@@ -1505,15 +1505,16 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
|
|
|
1505
1505
|
|
|
1506
1506
|
registry.register(['help', '?'], (_args, ctx) => {
|
|
1507
1507
|
const { cols, rows } = termSize();
|
|
1508
|
+
// The transient modal paints only height - 2 content rows and does not scroll.
|
|
1509
|
+
// The builder adds columns to fit that budget; only when it still overflows, use the scrollable chat log.
|
|
1510
|
+
const minHeight = Math.min(6, Math.max(3, rows - 2));
|
|
1511
|
+
const modalContentRows = Math.max(minHeight, Math.min(rows - 4, Math.floor(rows * 0.7))) - 2;
|
|
1508
1512
|
const lines = buildEssentialHelpLines({
|
|
1509
1513
|
names: registry.names(),
|
|
1510
1514
|
descriptions: SLASH_COMMANDS,
|
|
1511
1515
|
width: Math.max(1, Math.floor(cols * 0.7) - 2),
|
|
1516
|
+
maxRows: modalContentRows,
|
|
1512
1517
|
});
|
|
1513
|
-
// The transient modal paints only height - 2 content rows and does not scroll.
|
|
1514
|
-
// When the catalog outgrows it, use the scrollable chat log instead of hiding keys.
|
|
1515
|
-
const minHeight = Math.min(6, Math.max(3, rows - 2));
|
|
1516
|
-
const modalContentRows = Math.max(minHeight, Math.min(rows - 4, Math.floor(rows * 0.7))) - 2;
|
|
1517
1518
|
if (ctx.showHelpModal && lines.length <= modalContentRows) {
|
|
1518
1519
|
ctx.showHelpModal({ title: 'Dashboard help', lines });
|
|
1519
1520
|
} else {
|