elanous 0.2.21 → 0.2.23
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/NOTICE +7 -0
- package/README.md +32 -22
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
- package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
- package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
- package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
- package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
- package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
- package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
- package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
- package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
- package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
- package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
- package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
- package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
- package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
- package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
- package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/{page-111cabe4d1fd69ae.js → page-6168a7c43e6ef8f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
- package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
- package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
- package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +24 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +24 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
- package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
- package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
- package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
- package/catalog/models/openai/gpt-6-astra.yaml +6 -0
- package/catalog/models/openai/gpt-6-luna.yaml +6 -0
- package/catalog/models/openai/gpt-6-sol.yaml +6 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/drafts/recipes.yaml +2 -2
- package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
- package/graphs/log-horizon/recipes.yaml +3 -0
- package/graphs/release/recipes.yaml +1 -1
- package/graphs/release/release-loop.yaml +6 -2
- package/graphs/release-rehearsal/recipes.yaml +12 -0
- package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
- package/graphs/test-diet/recipes.yaml +3 -0
- package/graphs/test-diet/test-diet.yaml +3 -1
- package/package.json +4 -1
- package/scripts/bench-report.ts +82 -3
- package/scripts/ci-typecheck-changed.ts +10 -1
- package/scripts/f-session-monitor.ts +69 -0
- package/scripts/hq/hq-fence-wrapper.sh +148 -0
- package/scripts/hq/standby-snapshot.ts +7 -3
- package/scripts/knowledge-compress.ts +11 -0
- package/scripts/lib/typecheck-ratchet.ts +51 -0
- package/scripts/nightly-docops.ts +90 -3
- package/scripts/openai-relay-server.ts +5 -1
- package/scripts/release-loop/docs-node.ts +258 -43
- package/scripts/release-loop/gate-method.ts +59 -0
- package/scripts/release-loop/gate-node.ts +73 -7
- package/scripts/release-loop/gate-wall.ts +208 -0
- package/scripts/release-loop/known-issues-node.ts +53 -8
- package/scripts/release-loop/publish-at.ts +14 -0
- package/scripts/release-loop/publish-node.ts +17 -2
- package/scripts/release-loop/resume-release.ts +34 -4
- package/scripts/release-loop/resume.ts +53 -0
- package/scripts/release-loop/shard-plan.ts +3 -11
- package/scripts/release-loop/tui-node-checks.ts +22 -0
- package/scripts/release-loop/unattended-release.ts +8 -1
- package/scripts/research-coo-admin-dates.ts +39 -0
- package/scripts/rhythm/daily.ts +51 -2
- package/scripts/rhythm/weekly.ts +3 -2
- package/scripts/skills/public-check.ts +7 -2
- package/scripts/smart-merge/resync-shadow.ts +5 -3
- package/scripts/test-diet/lib.ts +81 -1
- package/scripts/test-diet/node.ts +48 -2
- package/scripts/tsc-main-safety-net.ts +189 -0
- package/scripts/usage-rollup.ts +8 -4
- package/scripts/verify-coo-admin-evidence.ts +83 -0
- package/src/acp/client.ts +4 -2
- package/src/acp/codex-plugins.ts +48 -6
- package/src/agent/monad-agent-turn.ts +67 -5
- package/src/agent/run-context.ts +14 -0
- package/src/agent/tool-profile.ts +28 -2
- package/src/agent-env/profile.ts +25 -5
- package/src/agent-mission/acp-judge.ts +8 -2
- package/src/agent-mission/capabilities-cli.ts +16 -1
- package/src/agent-mission/driver.ts +27 -13
- package/src/agent-mission/pr-review-watch.ts +6 -2
- package/src/agent-mission/review-loop.ts +33 -5
- package/src/agent-mission/supervisor-metrics.ts +17 -2
- package/src/agent-substrate/acp-reviewer.ts +25 -9
- package/src/agent-substrate/pr-reviewer.ts +175 -32
- package/src/agent-substrate/review-intent.ts +106 -5
- package/src/agent-substrate/self-review-cli.ts +111 -16
- package/src/agent-substrate/shard-boundary-intent.ts +92 -26
- package/src/ask-user-question/pending-questions.ts +8 -2
- package/src/autopilot/build/llm-conflict-merge.ts +238 -20
- package/src/autopilot/codebase-grounding.ts +44 -0
- package/src/autopilot/llm-control-brain.ts +13 -1
- package/src/autopilot/mission-codebase-gate.ts +8 -77
- package/src/autopilot/pr-manager.ts +30 -11
- package/src/away/release-watch.ts +47 -8
- package/src/boot/acp-server.ts +4 -7
- package/src/boot/acp-socket-path.ts +7 -0
- package/src/briefing/brief-items.ts +123 -22
- package/src/chat/index.ts +13 -3
- package/src/cli/agent-cli.ts +20 -0
- package/src/cli/brief-cli.ts +46 -22
- package/src/cli/cli-user-error.ts +9 -2
- package/src/cli/config-classify.ts +83 -0
- package/src/cli/control-cli.ts +14 -0
- package/src/cli/decisions-cli.ts +26 -16
- package/src/cli/log-event-names.ts +3 -0
- package/src/cli/logs-cli.ts +1 -0
- package/src/cli/logs-model-input.ts +1 -1
- package/src/cli/mcp-login.ts +111 -37
- package/src/cli/plugin-cli.ts +21 -1
- package/src/cli/pod-cli.ts +26 -0
- package/src/cli/pr-cli.ts +94 -9
- package/src/cli/pr-land-overlap-evidence.ts +131 -0
- package/src/cli/release-cli.ts +74 -15
- package/src/cli/self-update.ts +173 -10
- package/src/cli/skills-cli.ts +12 -3
- package/src/cli/tasks-cli.ts +241 -28
- package/src/connectors/types.ts +6 -6
- package/src/context-bus/context-first.ts +51 -2
- package/src/context-bus/context-now-surfaces.ts +29 -0
- package/src/context-bus/coord-events.ts +32 -4
- package/src/context-bus/long-term-memory.ts +26 -7
- package/src/context-bus/nightly-condense.ts +170 -21
- package/src/control/control-status.ts +87 -0
- package/src/control-plane/light-member.ts +5 -3
- package/src/control-plane/member.ts +172 -7
- package/src/core-turn/run-goal-loop.ts +108 -3
- package/src/dashboard/chat-fold.ts +20 -0
- package/src/dashboard/first-screen-band.ts +151 -1
- package/src/dashboard/index.ts +27 -5
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +14 -3
- package/src/dashboard/stale-install-check.ts +13 -2
- package/src/dashboard/turn-stream-formatter.ts +25 -0
- package/src/debug/log-diet.ts +159 -0
- package/src/debug/log.ts +52 -17
- package/src/decisions/decision-cards.ts +20 -1
- package/src/decisions/decision-ledger.ts +11 -8
- package/src/decisions/web-push-decision-cards.ts +19 -3
- package/src/discord-self-message.ts +2 -2
- package/src/display/coordinator.ts +25 -2
- package/src/domains/coo-admin-dates.evidence.json +876 -0
- package/src/domains/coo-admin-tool.ts +75 -14
- package/src/domains/cron-match.ts +1 -0
- package/src/domains/ops-status.ts +53 -0
- package/src/domains/outbound-alert.ts +41 -7
- package/src/domains/release-tool.ts +119 -10
- package/src/domains/schedule-registry.ts +10 -7
- package/src/domains/schedule-runner.ts +1 -0
- package/src/elanous-config-dir.ts +2 -2
- package/src/elanous-daemon.ts +3 -3
- package/src/exec-requests/planner.ts +6 -0
- package/src/execution-loop/launch-gate.ts +1 -1
- package/src/expression/i18n/messages.en.ts +5 -0
- package/src/expression/i18n/messages.ja.ts +5 -0
- package/src/expression/i18n/messages.ko.ts +5 -0
- package/src/expression/i18n/messages.zh.ts +5 -0
- package/src/expression/i18n/types.ts +8 -0
- package/src/github/pr-labels.ts +1 -0
- package/src/graph-kinds/registry.ts +6 -6
- package/src/graph-runner/graph-cli.ts +34 -2
- package/src/graph-runner/graph-run-api.ts +7 -0
- package/src/graph-runner/graph-tick.ts +73 -12
- package/src/graph-runner/runner.ts +94 -13
- package/src/graph-unify/wf-to-graph.ts +79 -0
- package/src/graph-wizard/generate.ts +34 -2
- package/src/graph-wizard/steps.ts +13 -0
- package/src/harness/dispatch-backpressure.ts +259 -0
- package/src/harness/harness-cli-command.ts +227 -50
- package/src/harness/harness-queue.ts +58 -14
- package/src/harness/harness-seams.ts +2 -20
- package/src/harness/harness-substrate-default.ts +72 -1
- package/src/harness/launch-advice.ts +23 -0
- package/src/harness/nested-elanous-policy.ts +4 -2
- package/src/hq/fence-wrapper.ts +7 -0
- package/src/hq/hq.ts +33 -2
- package/src/hq/lease.ts +13 -0
- package/src/hq/seats.ts +114 -18
- package/src/index.ts +199 -71
- package/src/intake-plane/collect-github.ts +19 -1
- package/src/intake-plane/digest.ts +45 -20
- package/src/intake-plane/lens.ts +36 -8
- package/src/intelligence-map/model-alias.ts +6 -0
- package/src/intelligence-map/model-catalog.ts +41 -0
- package/src/knowledge/conclusion-compress.ts +93 -0
- package/src/knowledge/kgs/pack.ts +5 -2
- package/src/knowledge/kgs/sqlite-store.ts +15 -0
- package/src/knowledge/know-find.ts +9 -2
- package/src/knowledge/query.ts +20 -0
- package/src/knowledge/tools/knowledge-query.ts +20 -2
- package/src/knowledge/write.ts +234 -2
- package/src/llm/bedrock-provider.ts +175 -0
- package/src/llm/bedrock.ts +345 -0
- package/src/llm/provider-credentials.ts +3 -1
- package/src/llm.ts +332 -51
- package/src/loops/budget.ts +150 -0
- package/src/loops/neighbor-runtime.ts +88 -0
- package/src/loops/orchestrator/author-depth.ts +29 -11
- package/src/loops/orchestrator/overlap.ts +7 -1
- package/src/loops/orchestrator/resync-shadow.ts +1 -1
- package/src/loops/orchestrator/seat-share.ts +6 -49
- package/src/loops/orchestrator/tick.ts +35 -2
- package/src/loops/orchestrator/traffic.ts +6 -80
- package/src/loops/registry.ts +5 -0
- package/src/market/publish.ts +17 -1
- package/src/market/signed-index.ts +42 -0
- package/src/maturity/feature-maturity.ts +2 -1
- package/src/mcp/mcp-oauth.ts +136 -17
- package/src/model-tier/llm-tier-map.ts +48 -4
- package/src/models/prompts.ts +22 -1
- package/src/mss/logging/horizon-watch.ts +168 -0
- package/src/mss/logging/log-store.ts +204 -15
- package/src/mss/logging/redaction.ts +17 -0
- package/src/native-tool-catalog.ts +1 -1
- package/src/nexus/api/consult-requests.ts +7 -10
- package/src/nexus/api/discord-trigger-bot.ts +6 -3
- package/src/nexus/api/draft-metrics.ts +22 -8
- package/src/nexus/api/error-reports.ts +30 -8
- package/src/nexus/api/graph-peer-edit.ts +77 -0
- package/src/nexus/api/graph-wizard-api.ts +9 -1
- package/src/nexus/api/graphs-api.ts +145 -7
- package/src/nexus/api/http-server.ts +101 -8
- package/src/nexus/api/loop-resources.ts +42 -0
- package/src/nexus/api/outbound-report.ts +8 -3
- package/src/nexus/api/plugins-market.ts +24 -0
- package/src/nexus/api/telegram-trigger-bot.ts +6 -3
- package/src/nexus/index.ts +13 -2
- package/src/nexus/outbound/format.ts +2 -0
- package/src/nexus/outbound/router.ts +198 -13
- package/src/oauth/claude-pty-maturity.ts +24 -0
- package/src/oauth/codex-account-rotation.ts +16 -18
- package/src/oauth/codex-account-store.ts +134 -5
- package/src/oauth/fallback-chain.ts +50 -15
- package/src/onboarding.ts +2 -1
- package/src/plugins/adapters/claude-package.ts +4 -12
- package/src/plugins/core/capability-policy.ts +141 -0
- package/src/plugins/core/host.ts +21 -8
- package/src/plugins/core/manifest.ts +19 -2
- package/src/plugins/core/trust-store.ts +15 -0
- package/src/plugins/core/types.ts +12 -0
- package/src/plugins/install/market-fetch.ts +68 -16
- package/src/plugins/install/plugin-install.ts +187 -16
- package/src/plugins/maker/market-bundle.ts +9 -0
- package/src/plugins/maker/plugin-maker.ts +32 -21
- package/src/plugins/maker/wizard-generate.ts +87 -9
- package/src/policy/llm-policy.ts +24 -6
- package/src/process/pid-liveness.ts +1 -1
- package/src/prompt-cache/openai.ts +10 -6
- package/src/prompt-cache/openrouter.ts +94 -0
- package/src/prompt-enhance/enhance.ts +46 -5
- package/src/prompt-library/family-prompt-coverage.ts +1 -0
- package/src/prompt-library/universal-preamble.ts +2 -2
- package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
- package/src/registry/loader.ts +6 -1
- package/src/release-loop/checklist-board.ts +27 -0
- package/src/release-loop/checklist.ts +62 -9
- package/src/release-loop/feature-store.ts +3 -0
- package/src/release-loop/gate-shards.ts +48 -4
- package/src/release-loop/landed-to-green.ts +81 -0
- package/src/release-loop/light-rc.ts +11 -1
- package/src/release-loop/merged-pr-checklist.ts +10 -0
- package/src/release-loop/placement.ts +91 -22
- package/src/release-loop/rehearsal.ts +317 -0
- package/src/release-loop/release-schedule.ts +13 -1
- package/src/release-loop/rubric-types.ts +1 -0
- package/src/release-loop/rubric.ts +2 -2
- package/src/retro/daily.ts +23 -9
- package/src/seat-address/seat-address.ts +1 -0
- package/src/seat-loop/seat-loop.ts +208 -21
- package/src/seat-loop/seat-report.ts +29 -1
- package/src/seat-loop/traffic-signal.ts +44 -0
- package/src/self-dev/ask-launch-flow.ts +2 -2
- package/src/self-dev/dev-cli.ts +157 -11
- package/src/self-dev/dev-pipeline.ts +18 -1
- package/src/self-dev/draft-residue.ts +463 -0
- package/src/self-dev/draft-sweep.ts +195 -17
- package/src/self-dev/draft-triage-rules.ts +27 -1
- package/src/self-dev/launch-preflight-text.ts +549 -0
- package/src/self-dev/launch-preflight.ts +10 -545
- package/src/self-dev/orchestrate-cli.ts +57 -2
- package/src/self-dev/orchestrate-summary-line.ts +13 -0
- package/src/self-dev/orchestrate.ts +9 -133
- package/src/self-dev/review-provider-fallback.ts +179 -0
- package/src/self-dev/run-store.ts +1 -3
- package/src/self-dev/run-supervisor.ts +8 -23
- package/src/self-dev/run-types.ts +178 -0
- package/src/self-dev/shard-aggregate.ts +61 -13
- package/src/self-dev/shard-plan.ts +5 -1
- package/src/self-dev/shard-run.ts +23 -5
- package/src/self-dev/supervisor-verdict-edges.ts +2 -4
- package/src/self-implement/blocked-draft-policy.ts +3 -19
- package/src/self-implement/draft-on-stop-mode.ts +18 -0
- package/src/self-implement/follow-up-goals.ts +114 -38
- package/src/self-implement/gate-baseline-reap.ts +157 -0
- package/src/self-implement/gate-baseline.ts +78 -16
- package/src/self-implement/gate-cli.ts +12 -2
- package/src/self-implement/gate-remote.ts +17 -6
- package/src/self-implement/goal-author.ts +24 -4
- package/src/self-implement/goal-digest.ts +19 -0
- package/src/self-implement/graph-overlay-condition.ts +4 -0
- package/src/self-implement/harness-policy-gates.ts +7 -5
- package/src/self-implement/headless-elanous-driver.ts +11 -9
- package/src/self-implement/host-regate.ts +148 -43
- package/src/self-implement/l8-merge-queue.ts +147 -13
- package/src/self-implement/merge-train.ts +131 -0
- package/src/self-implement/off-diff-evidence.ts +9 -0
- package/src/self-implement/orchestrator.ts +201 -43
- package/src/self-implement/review-finding-recurrence.ts +28 -0
- package/src/self-implement/rework-policy.ts +2 -1
- package/src/self-implement/round-summary-card.ts +63 -0
- package/src/self-implement/run-ledger.ts +4 -3
- package/src/self-implement/run-step-projection.ts +147 -0
- package/src/self-implement/run-stop.ts +1 -1
- package/src/self-implement/seams.ts +41 -6
- package/src/self-implement/self-implement-cli.ts +6 -0
- package/src/self-implement/train-gate-remote.ts +158 -0
- package/src/session-runtime/index.ts +10 -1
- package/src/session-runtime/retry-api.ts +11 -1
- package/src/shell-env-bootstrap.ts +19 -4
- package/src/skills/gift-install.ts +119 -0
- package/src/skills/runner.ts +59 -2
- package/src/skills/skill-feedback.ts +31 -1
- package/src/skills/skill-tier.ts +1 -0
- package/src/smart-wizard/capability-index.ts +231 -0
- package/src/smart-wizard/rung.ts +74 -0
- package/src/steward/launch.ts +20 -9
- package/src/steward/triage.ts +29 -10
- package/src/storage/file-lock.ts +40 -4
- package/src/task-agent/actions.ts +4 -0
- package/src/task-agent/card-evidence.ts +59 -13
- package/src/task-agent/completion-evidence.ts +31 -3
- package/src/task-agent/cover.ts +61 -0
- package/src/task-agent/judge.ts +4 -3
- package/src/task-agent/land-worktree.ts +201 -0
- package/src/task-agent/live-move-history.ts +133 -0
- package/src/task-agent/live-moves.ts +222 -12
- package/src/task-agent/parent-host.ts +117 -8
- package/src/task-agent/rejudge-on-head.ts +297 -0
- package/src/task-agent/review-result-capture.ts +218 -0
- package/src/task-agent/shadow.ts +118 -7
- package/src/task-agent/task-hand.ts +138 -11
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
- package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
- package/src/task-orchestrator/surfaces/pod-pool.ts +203 -28
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
- package/src/task-orchestrator/surfaces/self-implement.ts +11 -0
- package/src/telegram-commands.ts +8 -0
- package/src/telegram-project-command.ts +6 -0
- package/src/telegram-service.ts +5 -1
- package/src/telegram.ts +17 -4
- package/src/time/format.ts +13 -4
- package/src/tool-runtime/goal-author-runtime.ts +1 -0
- package/src/tool-runtime/self-cognition-catalog.ts +23 -0
- package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
- package/src/typecheck-ratchet.ts +2 -1
- package/src/user-config.ts +167 -28
- package/src/ux-sim/slash-menu-frames.ts +168 -0
- package/src/version/packed-revision.json +1 -1
- package/src/web-terminal/preview-tap-registry.ts +5 -2
- package/src/workflow-runtime/executor.ts +24 -2
- package/src/workflow-runtime/triggers/registry.ts +27 -0
- package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
- package/src/workflow-runtime/triggers/scheduler.ts +1 -0
- package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
- package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
- package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
- package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
- package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
- package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
- package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
- package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
- package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
- package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
- package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
- package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
- package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
- package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +0 -1
- package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
- package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
- package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
- package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
- package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
- package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
- package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
- package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
- package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d781be3e3a9cfd74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b0a80997903852d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-2b1263165630d9c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-e2d6bed48ac20120.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-544dd4bd4847eeb7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-3ee191319bf97d87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a449f1ed472b81c2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-9045094d6d3b5cd0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-be8b4615c919e36c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7a12f61be4a579d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-dc39ee7a36d26385.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-84ae759f76053672.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-3db58ddb61fe2be9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-2fe368efb6de3b6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-c69762987b751174.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-7f8d7fcdf058a845.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-22163556cd38bc88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
- package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +0 -1
- /package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
package/src/cli/mcp-login.ts
CHANGED
|
@@ -5,9 +5,11 @@ import { getUserConfig, reloadUserConfig, saveUserConfig, type McpServerSpec } f
|
|
|
5
5
|
import {
|
|
6
6
|
discoverMcpOAuth,
|
|
7
7
|
exchangeAuthorizationCode,
|
|
8
|
+
ensureClientRegistration,
|
|
8
9
|
loadStoredRegistration,
|
|
9
10
|
loopbackRedirectPort,
|
|
10
11
|
prepareMcpOAuthAuthorization,
|
|
12
|
+
authorizeMcpDevice,
|
|
11
13
|
type McpOAuthFetch,
|
|
12
14
|
} from '../mcp/mcp-oauth.js';
|
|
13
15
|
import { parseWwwAuthenticate } from '../mcp/client.js';
|
|
@@ -31,7 +33,15 @@ export interface McpLoginOpts {
|
|
|
31
33
|
out?: Output;
|
|
32
34
|
readConfigFn?: () => { mcp?: { servers: McpServerSpec[] } };
|
|
33
35
|
fetch?: McpOAuthFetch;
|
|
36
|
+
storePath?: string;
|
|
34
37
|
openBrowser?: (url: string) => Promise<void>;
|
|
38
|
+
/** Aside browser agent; failures fall back to the existing browser flow. */
|
|
39
|
+
approveBrowser?: (url: string) => Promise<void>;
|
|
40
|
+
/** How long to wait for the approval callback after aside returns before falling back to the browser. */
|
|
41
|
+
asideCallbackGraceMs?: number;
|
|
42
|
+
/** Device-poll timing seam (test only). */
|
|
43
|
+
deviceSleep?: (ms: number) => Promise<void>;
|
|
44
|
+
deviceNow?: () => number;
|
|
35
45
|
browserEnv?: NodeJS.ProcessEnv;
|
|
36
46
|
browserPlatform?: NodeJS.Platform;
|
|
37
47
|
createListener?: (handler: (req: IncomingMessage, res: ServerResponse) => void) => Server;
|
|
@@ -69,21 +79,58 @@ export async function runMcpLogin(opts: McpLoginOpts): Promise<McpLoginResult> {
|
|
|
69
79
|
|
|
70
80
|
let server: Server | undefined;
|
|
71
81
|
try {
|
|
72
|
-
const
|
|
73
|
-
|
|
82
|
+
const why = browserUnavailableReason(opts.browserEnv ?? process.env, opts.browserPlatform ?? process.platform);
|
|
83
|
+
const oauthOpts = { ...(opts.fetch ? { fetch: opts.fetch } : {}), ...(opts.storePath ? { storePath: opts.storePath } : {}) };
|
|
84
|
+
const early = why && !opts.createListener ? undefined : await listenForCallback(opts.createListener, 0);
|
|
85
|
+
server = early?.server;
|
|
74
86
|
const challenge = await requestChallenge(spec.url, opts.fetch);
|
|
75
87
|
if (!challenge.resourceMetadata) {
|
|
76
88
|
out.error(`✗ server '${opts.serverId}' did not provide a 401 Bearer resource_metadata challenge`);
|
|
77
89
|
return { exitCode: 1 };
|
|
78
90
|
}
|
|
91
|
+
const discovered = await discoverMcpOAuth(challenge.resourceMetadata, {
|
|
92
|
+
resourceUrl: spec.url, ...oauthOpts,
|
|
93
|
+
});
|
|
94
|
+
if ((why || !discovered.metadata.authorizationEndpoint) && discovered.metadata.deviceAuthorizationEndpoint) {
|
|
95
|
+
if (early?.server.listening) await closeServer(early.server);
|
|
96
|
+
if (why) out.log(why);
|
|
97
|
+
const stored = loadStoredRegistration(discovered.metadata.issuer, oauthOpts);
|
|
98
|
+
const deviceRegistration = await ensureClientRegistration(discovered.metadata, { ...oauthOpts, deviceCode: true });
|
|
99
|
+
const authorizeDevice = (registration: typeof deviceRegistration) => authorizeMcpDevice(discovered.metadata, registration, {
|
|
100
|
+
scope: challenge.scope,
|
|
101
|
+
resource: discovered.resource.resource,
|
|
102
|
+
...oauthOpts,
|
|
103
|
+
...(opts.deviceSleep ? { sleep: opts.deviceSleep } : {}),
|
|
104
|
+
...(opts.deviceNow ? { now: opts.deviceNow } : {}),
|
|
105
|
+
onDeviceCode: ({ userCode, verificationUri, verificationUriComplete }) => {
|
|
106
|
+
out.log(`Authorize '${opts.serverId}' at ${verificationUriComplete ?? verificationUri}`);
|
|
107
|
+
out.log(`Device code: ${userCode}`);
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
try {
|
|
111
|
+
await authorizeDevice(deviceRegistration);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
// A reused client the server does not accept for the device grant (e.g. an old browser client stored
|
|
114
|
+
// without its loopback URI) gets one fresh device registration; anything else fails as before.
|
|
115
|
+
const reused = stored?.clientId === deviceRegistration.clientId;
|
|
116
|
+
if (!reused || !discovered.metadata.registrationEndpoint || !/\((?:unauthorized_client|invalid_client)\)/.test(String(error))) throw error;
|
|
117
|
+
await authorizeDevice(await ensureClientRegistration(discovered.metadata, { ...oauthOpts, deviceCode: true, forceReregister: true }));
|
|
118
|
+
}
|
|
119
|
+
out.log(`✓ credentials saved for '${opts.serverId}' (${discovered.metadata.issuer})`);
|
|
120
|
+
persistLoginDiscovery(opts, discovered.metadata, out);
|
|
121
|
+
return { exitCode: 0 };
|
|
122
|
+
}
|
|
123
|
+
const callbackListener = early ?? await listenForCallback(opts.createListener, 0);
|
|
124
|
+
server = callbackListener.server;
|
|
79
125
|
const opened = await openLoginListener({
|
|
80
|
-
early,
|
|
126
|
+
early: callbackListener,
|
|
81
127
|
serverId: opts.serverId,
|
|
82
128
|
resourceMetadataUrl: challenge.resourceMetadata,
|
|
83
129
|
...(challenge.scope ? { scope: challenge.scope } : {}),
|
|
84
130
|
resourceUrl: spec.url,
|
|
85
|
-
...
|
|
131
|
+
...oauthOpts,
|
|
86
132
|
...(opts.createListener ? { createListener: opts.createListener } : {}),
|
|
133
|
+
onListener: (openedServer) => { server = openedServer; },
|
|
87
134
|
});
|
|
88
135
|
const listener = opened.listener;
|
|
89
136
|
server = listener.server;
|
|
@@ -94,47 +141,39 @@ export async function runMcpLogin(opts: McpLoginOpts): Promise<McpLoginResult> {
|
|
|
94
141
|
void callbackPromise.catch(() => undefined);
|
|
95
142
|
out.log(`Open this URL to authorize '${opts.serverId}':`);
|
|
96
143
|
out.log(authorization.request.url);
|
|
97
|
-
const why = browserUnavailableReason(opts.browserEnv ?? process.env, opts.browserPlatform ?? process.platform);
|
|
98
144
|
if (why) {
|
|
99
145
|
out.log(why);
|
|
100
146
|
debug.log('browser.open', 'skipped', { reason: why.includes('ssh') ? 'ssh' : 'no-display' });
|
|
101
147
|
} else {
|
|
102
148
|
try {
|
|
103
|
-
|
|
149
|
+
if (opts.approveBrowser || !opts.openBrowser) {
|
|
150
|
+
await (opts.approveBrowser ?? approveWithAside)(authorization.request.url);
|
|
151
|
+
// A clean aside exit is not an approval: only the loopback callback is. If it has not arrived
|
|
152
|
+
// shortly after aside finished, fall back to the browser (the listener stays open for it).
|
|
153
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
154
|
+
const arrived = await Promise.race([
|
|
155
|
+
callbackPromise.then(() => true, () => true),
|
|
156
|
+
new Promise<boolean>((resolve) => { timer = setTimeout(() => resolve(false), opts.asideCallbackGraceMs ?? 15_000); }),
|
|
157
|
+
]);
|
|
158
|
+
if (timer) clearTimeout(timer);
|
|
159
|
+
if (!arrived) throw new Error('aside finished without an approval callback');
|
|
160
|
+
} else await opts.openBrowser(authorization.request.url);
|
|
104
161
|
} catch {
|
|
105
|
-
|
|
162
|
+
if (!opts.approveBrowser && opts.openBrowser) {
|
|
163
|
+
out.error('Could not open the default browser; open the URL above manually.');
|
|
164
|
+
} else {
|
|
165
|
+
try {
|
|
166
|
+
await (opts.openBrowser ?? openDefaultBrowser)(authorization.request.url);
|
|
167
|
+
} catch {
|
|
168
|
+
out.error('Could not open the default browser; open the URL above manually.');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
106
171
|
}
|
|
107
172
|
}
|
|
108
173
|
const callback = await callbackPromise;
|
|
109
|
-
await exchangeAuthorizationCode(authorization.metadata, authorization.request, callback,
|
|
110
|
-
...(opts.fetch ? { fetch: opts.fetch } : {}),
|
|
111
|
-
});
|
|
174
|
+
await exchangeAuthorizationCode(authorization.metadata, authorization.request, callback, oauthOpts);
|
|
112
175
|
out.log(`✓ credentials saved for '${opts.serverId}' (${authorization.metadata.issuer})`);
|
|
113
|
-
|
|
114
|
-
//
|
|
115
|
-
// 초판은 issuer 를 «화면에 찍고 끝»이었다. 그런데 자격증명 저장소는
|
|
116
|
-
// issuer 를 «키»로 쓰고(`getValidAccessToken(issuer, …)`), 데몬은 그
|
|
117
|
-
// issuer 를 오직 config 의 `mcp.servers[].oauthIssuer` 에서만 얻는다
|
|
118
|
-
// (`register-mcp-clients.ts` 는 spec 에 «있을 때만» 넘기고,
|
|
119
|
-
// `McpClient.oauthAccessToken()` 은 `if (!this.oauthIssuer) return null`).
|
|
120
|
-
//
|
|
121
|
-
// ⇒ 그래서 `mcp login` 이 «성공하고 ✓ 를 찍어도» 사람이 config 를 손으로
|
|
122
|
-
// 고치지 않으면 그 토큰은 영영 안 쓰인다. 2026-09-10 에 krea 를 붙이며
|
|
123
|
-
// 실제로 그 두 줄을 손으로 박았다. 「로그인했는데 도구가 0개」의 원인이다.
|
|
124
|
-
const persist = (opts.persistDiscoveryFn ?? persistDiscoveredIssuer)({
|
|
125
|
-
serverId: opts.serverId,
|
|
126
|
-
issuer: authorization.metadata.issuer,
|
|
127
|
-
...(authorization.metadata.tokenEndpoint ? { tokenEndpoint: authorization.metadata.tokenEndpoint } : {}),
|
|
128
|
-
});
|
|
129
|
-
if (persist.error) {
|
|
130
|
-
// ⛔ 자격증명은 «이미 저장됐다» — 되쓰기 실패로 로그인 자체를 실패로 접으면
|
|
131
|
-
// 사람이 같은 브라우저 왕복을 또 한다. 경고로 내고 손 처방을 같이 준다.
|
|
132
|
-
out.error(`⚠ config 에 oauthIssuer 를 못 적었습니다: ${persist.error}`);
|
|
133
|
-
out.error(` 손으로: mcp.servers[] 의 '${opts.serverId}' 칸에 "oauthIssuer": "${authorization.metadata.issuer}" 를 더하세요.`);
|
|
134
|
-
} else if (persist.written) {
|
|
135
|
-
out.log(`✓ config 갱신 — '${opts.serverId}'.oauthIssuer = ${authorization.metadata.issuer}`);
|
|
136
|
-
}
|
|
137
|
-
out.log(` 도는 데몬에 반영하려면: elanous mcp reload`);
|
|
176
|
+
persistLoginDiscovery(opts, authorization.metadata, out);
|
|
138
177
|
return { exitCode: 0 };
|
|
139
178
|
} catch (error) {
|
|
140
179
|
const stage = loginFailureStage(error);
|
|
@@ -146,8 +185,29 @@ export async function runMcpLogin(opts: McpLoginOpts): Promise<McpLoginResult> {
|
|
|
146
185
|
out.error(`✗ MCP login failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
147
186
|
return { exitCode: 1 };
|
|
148
187
|
} finally {
|
|
149
|
-
if (server) await closeServer(server);
|
|
188
|
+
if (server?.listening) await closeServer(server);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function persistLoginDiscovery(
|
|
193
|
+
opts: McpLoginOpts,
|
|
194
|
+
metadata: { issuer: string; tokenEndpoint: string },
|
|
195
|
+
out: Output,
|
|
196
|
+
): void {
|
|
197
|
+
// ⭐⭐ issuer 를 config 에도 적어야 저장한 토큰을 데몬이 찾는다.
|
|
198
|
+
const persist = (opts.persistDiscoveryFn ?? persistDiscoveredIssuer)({
|
|
199
|
+
serverId: opts.serverId,
|
|
200
|
+
issuer: metadata.issuer,
|
|
201
|
+
tokenEndpoint: metadata.tokenEndpoint,
|
|
202
|
+
});
|
|
203
|
+
if (persist.error) {
|
|
204
|
+
// 자격은 이미 저장됐다. config 쓰기 실패는 경고로 남긴다.
|
|
205
|
+
out.error(`⚠ config 에 oauthIssuer 를 못 적었습니다: ${persist.error}`);
|
|
206
|
+
out.error(` 손으로: mcp.servers[] 의 '${opts.serverId}' 칸에 "oauthIssuer": "${metadata.issuer}" 를 더하세요.`);
|
|
207
|
+
} else if (persist.written) {
|
|
208
|
+
out.log(`✓ config 갱신 — '${opts.serverId}'.oauthIssuer = ${metadata.issuer}`);
|
|
150
209
|
}
|
|
210
|
+
out.log(` 도는 데몬에 반영하려면: elanous mcp reload`);
|
|
151
211
|
}
|
|
152
212
|
|
|
153
213
|
async function requestChallenge(url: string, fetchFn?: McpOAuthFetch): Promise<{ resourceMetadata?: string; scope?: string }> {
|
|
@@ -175,7 +235,9 @@ async function openLoginListener(opts: {
|
|
|
175
235
|
scope?: string;
|
|
176
236
|
resourceUrl: string;
|
|
177
237
|
fetch?: McpOAuthFetch;
|
|
238
|
+
storePath?: string;
|
|
178
239
|
createListener?: McpLoginOpts['createListener'];
|
|
240
|
+
onListener?: (server: Server) => void;
|
|
179
241
|
early: Awaited<ReturnType<typeof listenForCallback>>;
|
|
180
242
|
}): Promise<{ listener: Awaited<ReturnType<typeof listenForCallback>>; authorization: Awaited<ReturnType<typeof prepareMcpOAuthAuthorization>> }> {
|
|
181
243
|
const prior = await priorRegistration(opts);
|
|
@@ -189,6 +251,7 @@ async function openLoginListener(opts: {
|
|
|
189
251
|
redirectUri: listener.redirectUri,
|
|
190
252
|
resourceUrl: opts.resourceUrl,
|
|
191
253
|
...(opts.fetch ? { fetch: opts.fetch } : {}),
|
|
254
|
+
...(opts.storePath ? { storePath: opts.storePath } : {}),
|
|
192
255
|
});
|
|
193
256
|
return { listener, authorization };
|
|
194
257
|
}
|
|
@@ -196,6 +259,7 @@ async function openLoginListener(opts: {
|
|
|
196
259
|
if (preferred !== null) {
|
|
197
260
|
try {
|
|
198
261
|
const listener = await listenForCallback(opts.createListener, preferred);
|
|
262
|
+
opts.onListener?.(listener.server);
|
|
199
263
|
debug.log('mcp.login', 'callback-port', { serverId: opts.serverId, source: 'registered' });
|
|
200
264
|
const authorization = await prepareMcpOAuthAuthorization({
|
|
201
265
|
resourceMetadataUrl: opts.resourceMetadataUrl,
|
|
@@ -203,6 +267,7 @@ async function openLoginListener(opts: {
|
|
|
203
267
|
redirectUri: listener.redirectUri,
|
|
204
268
|
resourceUrl: opts.resourceUrl,
|
|
205
269
|
...(opts.fetch ? { fetch: opts.fetch } : {}),
|
|
270
|
+
...(opts.storePath ? { storePath: opts.storePath } : {}),
|
|
206
271
|
});
|
|
207
272
|
return { listener, authorization };
|
|
208
273
|
} catch (error) {
|
|
@@ -210,6 +275,7 @@ async function openLoginListener(opts: {
|
|
|
210
275
|
}
|
|
211
276
|
}
|
|
212
277
|
const listener = await listenForCallback(opts.createListener, 0);
|
|
278
|
+
opts.onListener?.(listener.server);
|
|
213
279
|
debug.log('mcp.login', 'callback-port', {
|
|
214
280
|
serverId: opts.serverId,
|
|
215
281
|
source: 'reregistered',
|
|
@@ -221,6 +287,7 @@ async function openLoginListener(opts: {
|
|
|
221
287
|
redirectUri: listener.redirectUri,
|
|
222
288
|
resourceUrl: opts.resourceUrl,
|
|
223
289
|
...(opts.fetch ? { fetch: opts.fetch } : {}),
|
|
290
|
+
...(opts.storePath ? { storePath: opts.storePath } : {}),
|
|
224
291
|
forceReregister: true,
|
|
225
292
|
});
|
|
226
293
|
return { listener, authorization };
|
|
@@ -230,13 +297,14 @@ async function priorRegistration(opts: {
|
|
|
230
297
|
resourceMetadataUrl: string;
|
|
231
298
|
resourceUrl: string;
|
|
232
299
|
fetch?: McpOAuthFetch;
|
|
300
|
+
storePath?: string;
|
|
233
301
|
}): Promise<ReturnType<typeof loadStoredRegistration>> {
|
|
234
302
|
try {
|
|
235
303
|
const discovered = await discoverMcpOAuth(opts.resourceMetadataUrl, {
|
|
236
304
|
resourceUrl: opts.resourceUrl,
|
|
237
305
|
...(opts.fetch ? { fetch: opts.fetch } : {}),
|
|
238
306
|
});
|
|
239
|
-
return loadStoredRegistration(discovered.metadata.issuer);
|
|
307
|
+
return loadStoredRegistration(discovered.metadata.issuer, opts);
|
|
240
308
|
} catch {
|
|
241
309
|
return null;
|
|
242
310
|
}
|
|
@@ -368,6 +436,12 @@ async function closeServer(server: Server): Promise<void> {
|
|
|
368
436
|
await new Promise<void>((resolve) => server.close(() => resolve()));
|
|
369
437
|
}
|
|
370
438
|
|
|
439
|
+
async function approveWithAside(url: string): Promise<void> {
|
|
440
|
+
// Aside decides how to interact with the provider page; only the state-checked
|
|
441
|
+
// loopback callback (not the agent's answer) can complete this login.
|
|
442
|
+
await execFileAsync('aside', ['exec', '--effort', 'low', `Open this OAuth authorization URL in your browser and approve access for elanous: ${url}. Do not reveal passwords, codes or tokens in your response.`], { timeout: 90_000 });
|
|
443
|
+
}
|
|
444
|
+
|
|
371
445
|
async function openDefaultBrowser(url: string): Promise<void> {
|
|
372
446
|
const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'cmd' : 'xdg-open';
|
|
373
447
|
const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];
|
package/src/cli/plugin-cli.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
6
6
|
import { elanousStateRoot } from '../autopilot/state-paths.js';
|
|
7
7
|
import { userConfigPath } from '../user-config.js';
|
|
8
8
|
import { debug, redactSecretText } from '../debug/log.js';
|
|
9
|
-
import { addMarket, listMarkets, MarketFetchError, updateMarket } from '../plugins/install/market-fetch.js';
|
|
9
|
+
import { addMarket, ensureInternalMarketIndex, listMarkets, MarketFetchError, updateMarket } from '../plugins/install/market-fetch.js';
|
|
10
10
|
import { emitDecision } from '../live/detail-switch.js';
|
|
11
11
|
import { OFFICIAL_INDEX_KEYS } from '../market/official-keys.js';
|
|
12
12
|
import { installPlugin, listInstalledPlugins, PluginInstallError, removePlugin, type InstallEvent } from '../plugins/install/plugin-install.js';
|
|
@@ -145,6 +145,26 @@ export function registerPluginCommands(program: Command): void {
|
|
|
145
145
|
}
|
|
146
146
|
});
|
|
147
147
|
const market = plugin.command('market').description('Manage signed plugin marketplaces');
|
|
148
|
+
market.command('internal <name> <enterpriseId>').description('Fetch signed entries from a configured internal HTTPS market for an allowed enterprise')
|
|
149
|
+
.option('--refresh', 'Refresh the signed internal market index')
|
|
150
|
+
.option('--json', 'Print verified knowledge packs and loop bundles as JSON')
|
|
151
|
+
.action(async (name: string, enterpriseId: string, opts: { refresh?: boolean; json?: boolean }) => {
|
|
152
|
+
try {
|
|
153
|
+
const root = elanousStateRoot();
|
|
154
|
+
const result = await ensureInternalMarketIndex(name, enterpriseId, {
|
|
155
|
+
root, marketDir: join(root, 'plugins', 'markets'), refresh: opts.refresh,
|
|
156
|
+
});
|
|
157
|
+
const entries = { name: result.market.name, enterpriseId, sequence: result.index.sequence,
|
|
158
|
+
knowledgePacks: result.index.knowledgePacks ?? [], loopBundles: result.index.loopBundles ?? [] };
|
|
159
|
+
debug.log('plugin.cli', 'market.internal', { name: result.market.name, sequence: result.index.sequence });
|
|
160
|
+
if (opts.json) stdout.write(JSON.stringify(entries) + '\n');
|
|
161
|
+
else console.log(`Fetched internal market ${entries.name} (sequence ${entries.sequence}): ${entries.knowledgePacks.length} knowledge packs, ${entries.loopBundles.length} loop bundles`);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (opts.json) stdout.write(JSON.stringify({ event: 'failed', cause: safeCause(error) }) + '\n');
|
|
164
|
+
else console.error(`plugin market internal failed: ${safeCause(error)}`);
|
|
165
|
+
process.exitCode = 1;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
148
168
|
market.command('add <name> <url>').description('Register a marketplace URL')
|
|
149
169
|
.action((name: string, url: string) => {
|
|
150
170
|
try {
|
package/src/cli/pod-cli.ts
CHANGED
|
@@ -33,6 +33,27 @@ const HELP = `elanous pod run [--pool <스펙>] [--skill <이름,…>] [--llm gr
|
|
|
33
33
|
하니스 없이 명령 하나를 Pod 에서 돌리고 산출 경로를 한 줄로 알린다.
|
|
34
34
|
--deadline 생략 시 ${POD_COMMAND_DEADLINE_SECONDS}초(기존 Pod Job 수명 상한).`;
|
|
35
35
|
|
|
36
|
+
/** clone 트리는 `bun install` 없이 뜨므로 `bun test`·`bun run` 은 «Cannot find package» 로 실패한다
|
|
37
|
+
* (실측 2026-10-10 21:47 node-b · `pod run --clone -- bun test src/steward/launch.test.ts` → 1 fail ·
|
|
38
|
+
* 설치만 붙여 다시 치니 58초 Completed). Pod 문제로 오인하기 쉬워 «발사 전»에 한 줄로 알린다 — 발사는 막지 않는다. */
|
|
39
|
+
export const POD_CLONE_WITHOUT_INSTALL_WARNING =
|
|
40
|
+
'⚠ --clone 트리에는 node_modules 가 없다 — 시험이면 sh -c "bun install --frozen-lockfile && <명령>" 꼴로 감싸라';
|
|
41
|
+
|
|
42
|
+
/** `--clone` ⊕ 명령 첫 낱말이 `bun` ⊕ 둘째가 `test`·`run` ⊕ 명령 어디에도 `install` 낱말(토큰)이 없으면 경고 대상이다. */
|
|
43
|
+
export function podCloneWithoutInstallWarning(
|
|
44
|
+
commandArgs: readonly string[],
|
|
45
|
+
clone: boolean | undefined,
|
|
46
|
+
): string | null {
|
|
47
|
+
if (!clone) return null;
|
|
48
|
+
const [argv0, argv1] = commandArgs;
|
|
49
|
+
if (argv0 !== 'bun') return null;
|
|
50
|
+
if (argv1 !== 'test' && argv1 !== 'run') return null;
|
|
51
|
+
// Exact argv token only: `installation.test.ts` or a single `install helper` argument is not an install
|
|
52
|
+
// (a shell string like `sh -c "bun install && …"` never reaches here — its argv0 is `sh`).
|
|
53
|
+
if (commandArgs.includes('install')) return null;
|
|
54
|
+
return POD_CLONE_WITHOUT_INSTALL_WARNING;
|
|
55
|
+
}
|
|
56
|
+
|
|
36
57
|
export function registerPodCommands(program: Command, deps: PodCliDeps = {}): void {
|
|
37
58
|
const io = deps.io ?? {
|
|
38
59
|
log: (line: string) => console.log(line),
|
|
@@ -148,6 +169,11 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
148
169
|
}
|
|
149
170
|
}
|
|
150
171
|
const skills = (opts.skill ?? '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
172
|
+
const cloneWarning = podCloneWithoutInstallWarning(commandArgs, opts.clone);
|
|
173
|
+
if (cloneWarning !== null) {
|
|
174
|
+
io.error(cloneWarning);
|
|
175
|
+
debug.log('pod.run', 'clone-without-install', { argv0: commandArgs[0], argv1: commandArgs[1] });
|
|
176
|
+
}
|
|
151
177
|
try {
|
|
152
178
|
const result = await run({
|
|
153
179
|
command: commandArgs,
|
package/src/cli/pr-cli.ts
CHANGED
|
@@ -57,11 +57,15 @@ import { branchLineageSlug, findSiblingPrs } from './pr-lineage.js';
|
|
|
57
57
|
import { parseReleaseNoteSection } from '../release-loop/release-note.js';
|
|
58
58
|
import { landingFreezeMessage } from '../release-loop/landing-freeze.js';
|
|
59
59
|
import { admitLandingMerge } from '../self-implement/frozen-merges.js';
|
|
60
|
+
import { verifyOverlapEvidence } from './pr-land-overlap-evidence.js';
|
|
60
61
|
import { enqueueL8ShadowQueue, runL8ShadowQueue, shadowPrNumber, statusL8ShadowQueue, type L8ShadowQueueDeps } from '../self-implement/l8-merge-queue.js';
|
|
61
62
|
|
|
62
63
|
export { branchLineageSlug, findSiblingPrs };
|
|
63
64
|
|
|
64
65
|
export interface PrLandOpts {
|
|
66
|
+
/** Pin an existing PR and its reviewed head; both must be supplied together. */
|
|
67
|
+
pr?: string;
|
|
68
|
+
expectedHead?: string;
|
|
65
69
|
base?: string;
|
|
66
70
|
cwd?: string;
|
|
67
71
|
dryRun?: boolean;
|
|
@@ -80,6 +84,8 @@ export interface PrLandOpts {
|
|
|
80
84
|
forceFreeze?: string;
|
|
81
85
|
/** Land even though changed files would leak into the public export (the reason goes in --land-reason). */
|
|
82
86
|
allowPublicLeak?: boolean;
|
|
87
|
+
/** Pinned landing only: JSON evidence (rebased · re-gated · reviewed head) that replaces the unavailable non-interactive overlap approval. */
|
|
88
|
+
overlapEvidence?: string;
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
export interface PrGranularityOpts {
|
|
@@ -995,6 +1001,7 @@ function emitLandingOverlapAdvisory(
|
|
|
995
1001
|
base: string,
|
|
996
1002
|
currentFiles: readonly string[],
|
|
997
1003
|
out: { log: (message: string) => void },
|
|
1004
|
+
overlappingLandings: string[] = [],
|
|
998
1005
|
): boolean {
|
|
999
1006
|
if (currentFiles.length === 0) {
|
|
1000
1007
|
record('overlap', true, { outcome: 'no-changed-files' });
|
|
@@ -1006,6 +1013,8 @@ function emitLandingOverlapAdvisory(
|
|
|
1006
1013
|
return false;
|
|
1007
1014
|
}
|
|
1008
1015
|
const overlaps = overlapWithCurrentChanges(commits, currentFiles);
|
|
1016
|
+
const current = new Set(currentFiles);
|
|
1017
|
+
overlappingLandings.push(...commits.filter((commit) => commit.files.some((file) => current.has(file))).map((commit) => commit.hash));
|
|
1009
1018
|
const line = formatOverlapAdvisory(overlaps);
|
|
1010
1019
|
if (line) {
|
|
1011
1020
|
record('overlap', true, {
|
|
@@ -1180,10 +1189,37 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1180
1189
|
|
|
1181
1190
|
const cwd = opts.cwd ?? process.cwd();
|
|
1182
1191
|
const run = deps.run ?? defaultCmdRunner;
|
|
1192
|
+
const pinned = opts.pr !== undefined || opts.expectedHead !== undefined;
|
|
1193
|
+
if (opts.overlapEvidence !== undefined && (!pinned || !opts.overlapEvidence.trim())) {
|
|
1194
|
+
out.error('✗ overlap-evidence: --overlap-evidence <file> 는 --pr ⊕ --expected-head 머리 고정 착지에서만 쓴다.');
|
|
1195
|
+
return 1;
|
|
1196
|
+
}
|
|
1197
|
+
let pinnedBranch: string | undefined;
|
|
1198
|
+
let pinnedUrl: string | undefined;
|
|
1199
|
+
if (pinned) {
|
|
1200
|
+
const pr = Number(opts.pr);
|
|
1201
|
+
if (!/^[1-9]\d*$/.test(opts.pr ?? '') || !Number.isSafeInteger(pr) || !/^[a-f0-9]{40}$/i.test(opts.expectedHead ?? '') || opts.hold || opts.dryRun) {
|
|
1202
|
+
out.error('✗ expected-head: --pr and --expected-head (full SHA) are required together without --hold/--dry-run');
|
|
1203
|
+
return 1;
|
|
1204
|
+
}
|
|
1205
|
+
const viewed = run('gh', ['pr', 'view', String(pr), '--json', 'headRefOid,headRefName,state,isDraft,url'], { cwd });
|
|
1206
|
+
let value: { headRefOid?: string; headRefName?: string; state?: string; isDraft?: boolean; url?: string } = {};
|
|
1207
|
+
try { if (viewed.ok) value = JSON.parse(viewed.out) as typeof value; } catch { /* unreadable is not approval */ }
|
|
1208
|
+
const local = run('git', ['rev-parse', 'HEAD'], { cwd });
|
|
1209
|
+
const dirty = run('git', ['status', '--porcelain'], { cwd });
|
|
1210
|
+
if (value.state !== 'OPEN' || value.isDraft !== false || value.headRefOid?.toLowerCase() !== opts.expectedHead!.toLowerCase()
|
|
1211
|
+
|| !value.url?.endsWith(`/pull/${pr}`) || !value.headRefName || !local.ok || local.out.trim().toLowerCase() !== opts.expectedHead!.toLowerCase()
|
|
1212
|
+
|| !dirty.ok || dirty.out.trim()) {
|
|
1213
|
+
out.error('✗ expected-head: PR OPEN non-draft, matching local HEAD and clean worktree required');
|
|
1214
|
+
return 1;
|
|
1215
|
+
}
|
|
1216
|
+
pinnedBranch = value.headRefName;
|
|
1217
|
+
pinnedUrl = value.url;
|
|
1218
|
+
}
|
|
1183
1219
|
const resolveBase = deps.resolveBase ?? resolveDeliverableBase;
|
|
1184
1220
|
const branch = (deps.currentBranch ?? liveCurrentBranch)(cwd);
|
|
1185
|
-
if (!branch) {
|
|
1186
|
-
const detail = '현재 브랜치를 해석하지 못했습니다.';
|
|
1221
|
+
if (!branch || (pinned && branch !== pinnedBranch)) {
|
|
1222
|
+
const detail = pinned ? 'PR head branch와 현재 브랜치가 다릅니다.' : '현재 브랜치를 해석하지 못했습니다.';
|
|
1187
1223
|
record('branch', false);
|
|
1188
1224
|
out.error(`✗ branch: ${detail}`);
|
|
1189
1225
|
return 1;
|
|
@@ -1536,7 +1572,8 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1536
1572
|
return 1;
|
|
1537
1573
|
}
|
|
1538
1574
|
|
|
1539
|
-
const
|
|
1575
|
+
const overlappingLandings: string[] = [];
|
|
1576
|
+
const overlapFound = emitLandingOverlapAdvisory(run, cwd, base, changedPaths, out, overlappingLandings);
|
|
1540
1577
|
const siblingFound = emitSiblingPrAdvisory(
|
|
1541
1578
|
branch,
|
|
1542
1579
|
deps.listOpenPrs ?? (() => lookupOpenPrs(run, cwd)),
|
|
@@ -1567,6 +1604,26 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1567
1604
|
});
|
|
1568
1605
|
}
|
|
1569
1606
|
const hold = !!opts.hold || overlapDecision?.outcome === 'user-hold';
|
|
1607
|
+
// TA-LAND-OVERLAP — 비대화형 «승인 불가»만 증거로 대신한다(사람의 hold 는 증거로 뒤집지 않는다) · 증거가 없거나 어긋나면 종전 거부 그대로.
|
|
1608
|
+
let overlapEvidenceAccepted = false;
|
|
1609
|
+
if (pinned && overlapDecision?.outcome === 'unavailable' && opts.overlapEvidence !== undefined) {
|
|
1610
|
+
const ref = resolveRemoteBranchRef(run, cwd, base);
|
|
1611
|
+
const verdict = verifyOverlapEvidence({
|
|
1612
|
+
evidencePath: opts.overlapEvidence, pr: Number(opts.pr), expectedHead: opts.expectedHead!,
|
|
1613
|
+
remote: ref.remote, branch: ref.branch, cwd, run, readFile, overlappingLandings,
|
|
1614
|
+
});
|
|
1615
|
+
overlapEvidenceAccepted = verdict.ok;
|
|
1616
|
+
if (verdict.ok) {
|
|
1617
|
+
out.log(verdict.mode === 'already-ancestor'
|
|
1618
|
+
? `✓ overlap-evidence: already-ancestor — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass must-fix 0 (${verdict.reviewResult})`
|
|
1619
|
+
: `✓ overlap-evidence: ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · gate passed on that base · review pass must-fix 0 (${verdict.reviewResult})`);
|
|
1620
|
+
}
|
|
1621
|
+
else out.error(`✗ overlap-evidence: ${verdict.reason}`);
|
|
1622
|
+
}
|
|
1623
|
+
if (pinned && overlapDecision && overlapDecision.outcome !== 'user-merge' && !overlapEvidenceAccepted) {
|
|
1624
|
+
out.error('✗ expected-head: overlap merge approval unavailable for the reviewed head');
|
|
1625
|
+
return 1;
|
|
1626
|
+
}
|
|
1570
1627
|
|
|
1571
1628
|
const manager = deps.manager ?? makePrManager(run);
|
|
1572
1629
|
const existing = manager.findPrForBranchOutcome(branch, cwd);
|
|
@@ -1638,7 +1695,12 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1638
1695
|
}
|
|
1639
1696
|
}
|
|
1640
1697
|
|
|
1641
|
-
|
|
1698
|
+
// A pinned, already-reviewed commit must not go through upsertPr (git add/commit/force-push/PR edit).
|
|
1699
|
+
const upsert = pinned
|
|
1700
|
+
? existing.status === 'ok OUTPUT' && existing.url === pinnedUrl
|
|
1701
|
+
? { ok: true as const, url: pinnedUrl!, reused: true }
|
|
1702
|
+
: { ok: false as const, reason: 'gh' as const, detail: 'pinned PR is not the branch open PR' }
|
|
1703
|
+
: manager.upsertPr({
|
|
1642
1704
|
branch,
|
|
1643
1705
|
worktreePath: cwd,
|
|
1644
1706
|
base,
|
|
@@ -1654,7 +1716,7 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1654
1716
|
...(excludingActiveRunFiles ? { excludePaths } : {}),
|
|
1655
1717
|
});
|
|
1656
1718
|
if (!upsert.ok) {
|
|
1657
|
-
if (upsert.reason === 'noop' && excludingActiveRunFiles) {
|
|
1719
|
+
if (upsert.reason === 'noop' && excludingActiveRunFiles && !pinned) {
|
|
1658
1720
|
record('upsert-ready-noop', true, { excludePaths, detail: upsert.detail });
|
|
1659
1721
|
out.log(`✓ upsert-ready: 제외 후 올릴 것이 없습니다 — ${upsert.detail}`);
|
|
1660
1722
|
return 0;
|
|
@@ -1664,6 +1726,13 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1664
1726
|
return 1;
|
|
1665
1727
|
}
|
|
1666
1728
|
record('upsert-ready', true);
|
|
1729
|
+
if (pinned) {
|
|
1730
|
+
const upsertHead = run('git', ['rev-parse', 'HEAD'], { cwd });
|
|
1731
|
+
if (!upsert.reused || upsert.url !== pinnedUrl || !upsertHead.ok || upsertHead.out.trim().toLowerCase() !== opts.expectedHead!.toLowerCase()) {
|
|
1732
|
+
out.error('✗ expected-head: pinned PR identity or reviewed HEAD changed');
|
|
1733
|
+
return 1;
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1667
1736
|
out.log(`✓ upsert-ready: ${upsert.url}${upsert.reused ? ' (기존 PR)' : ' (새 PR)'}`);
|
|
1668
1737
|
|
|
1669
1738
|
if (hold) {
|
|
@@ -1688,21 +1757,34 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1688
1757
|
debug.log('harness.merge', 'frozen', { prUrl: upsert.url, reason: frozen.reason, until: frozen.until });
|
|
1689
1758
|
record('freeze', true, { url: upsert.url, reason: frozen.reason, until: frozen.until });
|
|
1690
1759
|
out.log(`✓ ready: ${upsert.url} — ${landingFreezeMessage(frozen)} · 병합 연기`);
|
|
1691
|
-
return 0;
|
|
1760
|
+
return pinned ? 1 : 0;
|
|
1692
1761
|
}
|
|
1693
1762
|
if (admission.kind === 'taken') {
|
|
1694
1763
|
record('freeze', true, { url: upsert.url, resumedElsewhere: true });
|
|
1695
1764
|
out.log(`✓ ready: ${upsert.url} — 동결이 막 풀려 보류 병합 재개가 이 PR 을 맡았습니다`);
|
|
1696
|
-
return 0;
|
|
1765
|
+
return pinned ? 1 : 0;
|
|
1697
1766
|
}
|
|
1698
1767
|
const landing = admission;
|
|
1768
|
+
if (pinned) {
|
|
1769
|
+
const view = run('gh', ['pr', 'view', String(opts.pr), '--json', 'headRefOid,state,isDraft'], { cwd });
|
|
1770
|
+
let current: { headRefOid?: string; state?: string; isDraft?: boolean } = {};
|
|
1771
|
+
try { if (view.ok) current = JSON.parse(view.out) as typeof current; } catch { /* fail closed */ }
|
|
1772
|
+
const finalHead = run('git', ['rev-parse', 'HEAD'], { cwd });
|
|
1773
|
+
if (current.headRefOid?.toLowerCase() !== opts.expectedHead!.toLowerCase() || current.state !== 'OPEN' || current.isDraft !== false
|
|
1774
|
+
|| !finalHead.ok || finalHead.out.trim().toLowerCase() !== opts.expectedHead!.toLowerCase()) {
|
|
1775
|
+
landing.end(false);
|
|
1776
|
+
out.error('✗ expected-head: PR head/state changed before merge');
|
|
1777
|
+
return 1;
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1699
1780
|
let merged: ReturnType<typeof manager.mergePrOutcome>;
|
|
1700
1781
|
try {
|
|
1701
|
-
merged = manager.mergePrOutcome(upsert.url);
|
|
1782
|
+
merged = manager.mergePrOutcome(upsert.url, pinned ? opts.expectedHead : undefined, pinned ? cwd : undefined);
|
|
1702
1783
|
// `GIT-S14` — 병합이 «미완료(OPEN)»로 끝났고 GitHub 가 아직 `mergeable=UNKNOWN`(병합 가능 여부 계산 중)이면
|
|
1703
1784
|
// 짧게 기다렸다 다시 병합한다. 표본 셋(08-25 · 09-24 🅢 #20233 등)이 모두 «같은 명령 재시도에 병합»이었다.
|
|
1704
1785
|
// ⛔ UNKNOWN 일 때만 재시도한다 — CONFLICTING 등 다른 값은 기다려도 안 풀린다(그대로 실패를 낸다).
|
|
1705
1786
|
const sleep = deps.sleep ?? ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
|
|
1787
|
+
// pinned 도 재시도한다 — mergePrOutcome 이 머리를 다시 확인하고 --match-head-commit 으로 병합하므로 바뀐 머리로는 안 들어간다.
|
|
1706
1788
|
for (let attempt = 1; !merged.ok && merged.kind === 'not-merged' && merged.state === 'OPEN' && attempt <= PR_LAND_MERGEABLE_UNKNOWN_RETRIES; attempt += 1) {
|
|
1707
1789
|
const mergeable = run('gh', ['pr', 'view', upsert.url, '--json', 'mergeable', '--jq', '.mergeable'], { cwd });
|
|
1708
1790
|
const value = mergeable.ok ? mergeable.out.trim() : '';
|
|
@@ -1710,7 +1792,7 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1710
1792
|
record('merge-retry', true, { attempt, mergeable: value, waitMs: PR_LAND_MERGEABLE_UNKNOWN_WAIT_MS });
|
|
1711
1793
|
out.log(`⏳ merge: mergeable=UNKNOWN — GitHub 가 병합 가능 여부를 아직 계산 중입니다 · ${PR_LAND_MERGEABLE_UNKNOWN_WAIT_MS / 1000}초 뒤 다시 병합 (${attempt}/${PR_LAND_MERGEABLE_UNKNOWN_RETRIES})`);
|
|
1712
1794
|
await sleep(PR_LAND_MERGEABLE_UNKNOWN_WAIT_MS);
|
|
1713
|
-
merged = manager.mergePrOutcome(upsert.url);
|
|
1795
|
+
merged = manager.mergePrOutcome(upsert.url, pinned ? opts.expectedHead : undefined, pinned ? cwd : undefined);
|
|
1714
1796
|
}
|
|
1715
1797
|
} finally { landing.end(merged!?.ok === true); }
|
|
1716
1798
|
if (!merged.ok) {
|
|
@@ -1781,6 +1863,8 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
|
|
|
1781
1863
|
.description('현재 브랜치 PR을 생성 또는 갱신해 ready 상태로 만들고 squash merge')
|
|
1782
1864
|
.option('--base <branch>', 'PR base branch')
|
|
1783
1865
|
.option('--cwd <path>', '작업 트리 경로')
|
|
1866
|
+
.option('--pr <number>', '기존 PR 번호 고정 (--expected-head 와 함께)')
|
|
1867
|
+
.option('--expected-head <sha>', '리뷰된 PR 머리 SHA 고정 (--pr 와 함께)')
|
|
1784
1868
|
.option('--dry-run', '변경 없이 landing 계획만 출력')
|
|
1785
1869
|
.option('--hold', 'PR을 생성 또는 갱신한 뒤 병합하지 않고 쌓아 둔다')
|
|
1786
1870
|
.option('--title <title>', 'PR title')
|
|
@@ -1795,6 +1879,7 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
|
|
|
1795
1879
|
.option('--land-reason <text>', '권고를 보고도 지금 내는 이유(예: 남이 기다리는 차단 해제)')
|
|
1796
1880
|
.option('--force-freeze <reason>', '동결을 넘겨 병합할 명시적 이유(필수)')
|
|
1797
1881
|
.option('--allow-public-leak', '바뀐 파일이 공개본에 사적 흔적을 실어도 착지(이유는 --land-reason)')
|
|
1882
|
+
.option('--overlap-evidence <file>', '머리 고정 착지 전용: 비대화형 겹침 승인을 대신할 증거 JSON {pr, head, gate:{head,baseCommit,passed}, reviewResult} — 재기반·재게이트·리뷰를 CLI 가 다시 잰다(겹친 착지가 전부 머리의 조상이면 리뷰만 · gate 생략 가능)')
|
|
1798
1883
|
.action(async (opts: PrLandOpts) => {
|
|
1799
1884
|
// ⛔⭐⭐⭐ **관측 sink 를 먼저 건다** — 라이브 도그푸드가 잡은 결함(2026-08-03).
|
|
1800
1885
|
// 단위 테스트는 `debug.log` 가 **불렸다**를 단언하지만, standalone CLI 는 sink 를 등록하지
|