elanous 0.2.34 → 0.2.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/{abb4b98b.163e0f56e84ae35d.js → 053a429e.9a63436527cc751c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +287 -0
- package/apps/pwa/out/_next/static/chunks/1201.afbfc5b1c5e5cbe4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +64 -0
- package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +36 -0
- package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +149 -0
- package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2500.cbc1257b774aae52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.js → 2683.c9773a0c589b031b.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.js → 275-02ea4c2a33980422.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{ffdc3a04.b9c23c1b28dd4a96.js → 2812ca6a.3b9f4a7a08885744.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{9550.d5f76828f972058c.js → 2986.45d7652e4f13557e.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8817.61bb7ffbba502ecb.js → 3136.30aaaa5fa03662a3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9131-fce7256c4180c4a5.js → 3148-98efd4869d660a87.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3498.cf2a15a8a9e5b926.js → 3155.2587a55196ecb394.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3103.84470c8445962f04.js → 3324.a09703033abcbd2f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +8 -0
- package/apps/pwa/out/_next/static/chunks/3410.7f9af5ab77cbe65f.js +115 -0
- package/apps/pwa/out/_next/static/chunks/{3819.163d4777f0a597f6.js → 3538.a445e50bb359d068.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +286 -0
- package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3414.172ad4ca2d9b08e8.js → 3727.7949ccaacaa71242.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3757-180308bc61021b05.js +1 -0
- package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
- package/apps/pwa/out/_next/static/chunks/3840-5825d56d46976a92.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.js → 3a3d9966.cc4d4585a2708e7c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +104 -0
- package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6740.43de73fc427c9fe2.js → 4286.b70c4520306817e8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4304.e9b2512834a9e23e.js +23 -0
- package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8548.036c344973968847.js → 4615.8525eb0add35eba6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +148 -0
- package/apps/pwa/out/_next/static/chunks/{3411-f87314c6c66ebc73.js → 5085-bce4904931767ca6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +93 -0
- package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3110.0a7065f25c841818.js → 528.38ce20ef8aa251ff.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{1644.35dd25240ae24e4b.js → 552.b7d061ad91eeac51.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3837.722e053fb9f321ad.js → 5711.957b095705c12560.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2124.ed5bf480cea7f85b.js → 575.d929793a53f27c4b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7562.948255cbc3e79d33.js → 599.c39c571b6733f2a2.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +79 -0
- package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +1 -0
- package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5446.edf141cff9ef647d.js → 6925.562d532110879886.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7005.1623d2aea78eb85f.js → 6943.c6b24124853a47b2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.js → 7481.39f7a4654907bf6e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2554.3b5e200f5f5cfcd6.js → 771.c3cdb6c1f7f47c02.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3121.779fafe3e44612c5.js → 7891.03f910124a737985.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +1 -0
- package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{9a8cb466.cc9fc9e6e46038aa.js → 873d6c12.09bd499f57171543.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7431.3051e9b8a4372d2d.js → 8904.7d51af2dc033965c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +90 -0
- package/apps/pwa/out/_next/static/chunks/914.8abefd48d579547b.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1895-60ed0e341c658bd4.js → 9250-072df22eaadaa6b5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +77 -0
- package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2547.dd27303624cb4da8.js → 9514.131c52cc75fe6439.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9789.60f723d18097ec30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9f31e478.fefcbcd3c388ebc5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/{page-4fb31eb476dcbad3.js → page-083747f1d4518f61.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5014f970-22bef0b5210f7d60.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4fa33ebd.21c1bd5b294496e6.js → ceba0382.650712b56b85b582.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/da5ecc5c-b005ad8cac737d57.js +1 -0
- package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +1 -0
- package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → uC-N0emedeNOFuaBQFv-I}/_buildManifest.js +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/bin/elanous.mjs +3 -2
- package/catalog/providers/opengateway.yaml +25 -0
- package/docs/goal-context/01-goal-authoring-checks.md +8 -0
- package/docs/goal-context/03-verification-menu.md +24 -0
- package/docs/goal-context/04-mock-scenarios.md +100 -0
- package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
- package/docs/goal-context/README.md +7 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/default-loop.yaml +63 -4
- package/graphs/document-loop.yaml +51 -3
- package/graphs/implement-loop.yaml +77 -4
- package/graphs/journey/ta-journey.yaml +11 -1
- package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
- package/graphs/journey/units/author-dialogue/observe.ts +96 -0
- package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
- package/graphs/operate-loop.yaml +51 -3
- package/graphs/release/recipes.yaml +6 -0
- package/graphs/release/release-loop.yaml +17 -4
- package/graphs/research-loop.yaml +137 -3
- package/graphs/test-diet/test-diet.yaml +3 -0
- package/graphs/wizard/recipes.yaml +44 -0
- package/graphs/wizard/wizard-loop.yaml +44 -0
- package/graphs/work/research-report.yaml +2 -0
- package/package.json +1 -1
- package/scripts/ci-typecheck-changed.ts +139 -5
- package/scripts/coord-role-pack.ts +19 -6
- package/scripts/first10-gate.ts +416 -0
- package/scripts/fleet/wsl-node-setup.sh +432 -0
- package/scripts/hq/standby-snapshot.ts +17 -12
- package/scripts/release-loop/docs-land-node.ts +21 -5
- package/scripts/release-loop/docs-node.ts +204 -8
- package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
- package/scripts/release-loop/gate-node.ts +427 -72
- package/scripts/release-loop/gate-partial.ts +65 -11
- package/scripts/release-loop/gate-radius-live.ts +177 -0
- package/scripts/release-loop/gate-radius-shadow.ts +1 -1
- package/scripts/release-loop/node-verdict.ts +14 -1
- package/scripts/release-loop/npm-publish-node.ts +66 -12
- package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
- package/scripts/release-loop/pwa-remote.ts +166 -0
- package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
- package/scripts/release-loop/resume-cap.ts +14 -34
- package/scripts/release-loop/resume-release.ts +78 -15
- package/scripts/release-loop/traffic-node.ts +59 -0
- package/scripts/release-loop/traffic-transition.ts +159 -0
- package/scripts/release-loop/unattended-release.ts +2 -0
- package/scripts/rhythm/daily.ts +137 -3
- package/scripts/test-diet/lib.ts +6 -1
- package/scripts/test-diet/node.ts +194 -13
- package/scripts/ux-sim.ts +92 -0
- package/skills/README.md +1 -0
- package/src/acp/core-turn-bridge.ts +48 -6
- package/src/agent/delegate-hint.ts +16 -0
- package/src/agent/runner.ts +82 -2
- package/src/agent/self-ambient-cache.ts +8 -0
- package/src/agent/task-notification.ts +56 -10
- package/src/agent/types.ts +4 -0
- package/src/agent-substrate/acp-reviewer.ts +39 -4
- package/src/agent-substrate/pr-reviewer.ts +72 -3
- package/src/agent-substrate/review-intent.ts +29 -2
- package/src/agent-substrate/review-observation.ts +3 -0
- package/src/agent-substrate/self-review-cli.ts +229 -28
- package/src/autopilot/mission-codebase-gate.ts +141 -12
- package/src/autopilot/pr-manager.ts +240 -41
- package/src/boot/daemon-tools/self-implement.ts +1 -0
- package/src/budget/run-usage-rollup.ts +1 -0
- package/src/budget/usage-outcomes.ts +8 -4
- package/src/capture/tui-self-report.ts +102 -0
- package/src/chat/goal-continue-verdict.ts +41 -0
- package/src/chat/index.ts +30 -6
- package/src/chat/internal-turn-origin.ts +1 -0
- package/src/chat/paste-fold.ts +86 -0
- package/src/chat/pickers/modal-runtime.ts +10 -27
- package/src/chat/tool-render/block.ts +32 -0
- package/src/chat/tool-render/dispatch.ts +2 -20
- package/src/chat/tool-render/result-text.ts +98 -0
- package/src/chat/turn-typeahead.ts +70 -7
- package/src/cli/agent-cli.ts +13 -2
- package/src/cli/config-audit.ts +119 -0
- package/src/cli/doctor-cli.ts +26 -1
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/herdr-cli.ts +34 -0
- package/src/cli/light-entry-route.ts +50 -7
- package/src/cli/log-event-names.ts +2 -0
- package/src/cli/make-cli.ts +247 -11
- package/src/cli/msg-cli.ts +117 -3
- package/src/cli/pod-cli.ts +77 -3
- package/src/cli/pr-cli.ts +34 -18
- package/src/cli/pr-land-base-read.ts +11 -2
- package/src/cli/pr-land-heavy-remote.ts +6 -3
- package/src/cli/pr-land-overlap-evidence.ts +23 -4
- package/src/cli/pr-land-pod-shadow-job.ts +3 -0
- package/src/cli/pr-land-recovery.ts +117 -1
- package/src/cli/pty-takeover-cli.ts +8 -7
- package/src/cli/release-checklist-read-cli.ts +79 -0
- package/src/cli/release-cli.ts +92 -106
- package/src/cli/release-single-flight.ts +1 -1
- package/src/cli/remote-resolve.ts +1 -1
- package/src/cli/root-tui-entry.ts +48 -0
- package/src/cli/sim-cli.ts +22 -0
- package/src/cli/tasks-card-show.ts +162 -0
- package/src/cli/tasks-cli.ts +1065 -338
- package/src/cli/tasks-read-cli.ts +197 -0
- package/src/cli/usage-cli.ts +13 -11
- package/src/clipboard/history.ts +179 -13
- package/src/config.ts +8 -1
- package/src/core-turn/run-core-turn.ts +4 -2
- package/src/core-turn/run-goal-loop.ts +73 -16
- package/src/core-turn/types.ts +6 -1
- package/src/dashboard/chat/acp-chat.ts +8 -0
- package/src/dashboard/context/keys.ts +8 -31
- package/src/dashboard/index.ts +280 -59
- package/src/dashboard/input/agent-wake.ts +7 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
- package/src/dashboard/input/chat-main-slash-command.ts +4 -2
- package/src/dashboard/input/goal-continue.ts +210 -0
- package/src/dashboard/input/goal-interim.ts +2 -0
- package/src/dashboard/input/internal-turn.ts +2 -8
- package/src/dashboard/input/seat-autowake.ts +9 -7
- package/src/dashboard/input/turn-autoheal.ts +52 -0
- package/src/dashboard/render/theme-resolver.ts +33 -4
- package/src/dashboard/seat-boot-preamble.ts +132 -5
- package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
- package/src/dashboard/slash-runtime/model-choices.ts +15 -0
- package/src/dashboard/stale-install-check.ts +3 -99
- package/src/debug/batch-queue.ts +119 -0
- package/src/debug/tui-log-tag.ts +67 -0
- package/src/display/agent-surface.ts +7 -0
- package/src/domains/schedule-registry.ts +16 -2
- package/src/domains/standalone-log-sink.ts +15 -2
- package/src/esc-abort-gate.ts +69 -0
- package/src/git-fs/idle-refresh.ts +76 -0
- package/src/git-fs/index.ts +18 -7
- package/src/git-fs/worktree.ts +137 -5
- package/src/graph-kinds/registry.ts +2 -2
- package/src/graph-runner/graph-cli.ts +18 -0
- package/src/graph-runner/runner.ts +173 -21
- package/src/graph-wizard/generate.ts +108 -4
- package/src/graph-wizard/steps.ts +15 -0
- package/src/grok/credential.ts +10 -3
- package/src/grounding/proactive-ground.ts +86 -0
- package/src/harness/control-inbox.ts +49 -1
- package/src/harness/harness-cli-command.ts +163 -35
- package/src/harness/harness-incidents.ts +85 -1
- package/src/harness/launch-utterance-ledger.ts +208 -0
- package/src/harness/pod-control-send.ts +33 -5
- package/src/harness/self-send-remote.ts +69 -0
- package/src/harness/self-send-routing-guard.ts +6 -0
- package/src/harness/self-send-target.ts +4 -3
- package/src/impl-discipline/detector.ts +16 -4
- package/src/impl-discipline/system-prompt.ts +11 -0
- package/src/impl-discipline/types.ts +2 -2
- package/src/index.ts +822 -154
- package/src/input-core/context-key-runtime.ts +21 -0
- package/src/intake-plane/already-built-hint.ts +4 -2
- package/src/intake-plane/requirement-funnel.ts +29 -1
- package/src/light-cli.ts +32 -11
- package/src/llm/opengateway-models.ts +11 -0
- package/src/llm/provider-credentials.ts +14 -0
- package/src/llm/provider-detect.ts +8 -1
- package/src/llm/runtime-model-family.ts +2 -1
- package/src/llm-wellformed.ts +70 -0
- package/src/llm.ts +247 -59
- package/src/loops/msg-wake.ts +35 -39
- package/src/loops/orchestrator/inbox.ts +59 -11
- package/src/loops/orchestrator/knowhow-pack.ts +364 -0
- package/src/loops/orchestrator/tick.ts +5 -1
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/model-tier/llm-tier-map.ts +15 -1
- package/src/models/prompts.ts +17 -2
- package/src/msg/msg-post-office.ts +116 -0
- package/src/mss/logging/log-store.ts +79 -22
- package/src/native-tool-catalog.ts +15 -1
- package/src/nexus/api/decisions-route.ts +38 -18
- package/src/nexus/api/graph-wizard-api.ts +20 -2
- package/src/nexus/api/loop-resources.ts +13 -1
- package/src/nexus/boot/register-mcp-clients.ts +263 -38
- package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
- package/src/oauth/codex.ts +7 -0
- package/src/onboarding/first-run.ts +37 -6
- package/src/onboarding/web-first.ts +43 -11
- package/src/ops/overview-collect.ts +30 -9
- package/src/ops/overview.ts +22 -9
- package/src/persona/loader.ts +11 -0
- package/src/persona/types.ts +8 -0
- package/src/pr-tool/census.ts +261 -27
- package/src/prompt-library/session-guidance.ts +14 -0
- package/src/provider-summary.ts +8 -0
- package/src/pty-shell/herdr-agent-report.ts +118 -9
- package/src/pty-shell/herdr-prompt.ts +266 -0
- package/src/pty-shell/pty-control-ipc.ts +151 -8
- package/src/pty-shell/pty-manifest.ts +7 -0
- package/src/pty-shell/pty-special-keys.ts +42 -2
- package/src/pty-shell/stale-install-check.ts +99 -0
- package/src/pty-shell/tui-run-state.ts +14 -2
- package/src/release-loop/auto-start.ts +20 -2
- package/src/release-loop/checklist.ts +100 -4
- package/src/release-loop/landed-but-yellow.ts +129 -5
- package/src/release-loop/light-rc.ts +1 -0
- package/src/release-loop/rehearsal.ts +37 -21
- package/src/repl/index.ts +192 -17
- package/src/repl/ops-msg-bridge.ts +32 -0
- package/src/seat-loop/knowhow-lint.ts +1 -1
- package/src/self-dev/ask-launch-flow.ts +44 -5
- package/src/self-dev/cli-help-text.ts +17 -0
- package/src/self-dev/decompose-proposal.ts +172 -20
- package/src/self-dev/decompose.ts +61 -0
- package/src/self-dev/dev-cli.ts +48 -12
- package/src/self-dev/dev-pipeline.ts +8 -2
- package/src/self-dev/draft-residue.ts +37 -1
- package/src/self-dev/draft-sweep.ts +137 -11
- package/src/self-dev/draft-triage-rules.ts +138 -0
- package/src/self-dev/fleet-reduce.ts +3 -2
- package/src/self-dev/glm-credential-guard.ts +77 -0
- package/src/self-dev/graph-front-nodes.ts +112 -0
- package/src/self-dev/graph-journey-nodes.ts +2 -0
- package/src/self-dev/graph-journey-route.ts +12 -2
- package/src/self-dev/harness-run-cli.ts +3 -15
- package/src/self-dev/orchestrate-cli-text.ts +10 -0
- package/src/self-dev/orchestrate-cli.ts +68 -3
- package/src/self-dev/orchestrate.ts +116 -17
- package/src/self-dev/review-provider-fallback.ts +35 -1
- package/src/self-dev/run-supervisor.ts +55 -2
- package/src/self-dev/run-types.ts +1 -1
- package/src/self-dev/self-orchestrate-runtime.ts +1 -11
- package/src/self-dev/shard-aggregate.ts +42 -5
- package/src/self-dev/shard-run.ts +8 -1
- package/src/self-health/autoheal.ts +153 -0
- package/src/self-health/signatures.ts +6 -0
- package/src/self-implement/blocked-draft-policy.ts +20 -0
- package/src/self-implement/classify-shadow.ts +3 -7
- package/src/self-implement/device-first.ts +116 -0
- package/src/self-implement/doctor-visit.ts +257 -2
- package/src/self-implement/evidence-command-budget.ts +80 -0
- package/src/self-implement/gate-baseline.ts +56 -17
- package/src/self-implement/gate-cli.ts +1 -0
- package/src/self-implement/gate-remote.ts +31 -20
- package/src/self-implement/goal-author-cli.ts +1 -0
- package/src/self-implement/goal-author-decompose.ts +534 -45
- package/src/self-implement/goal-author.ts +282 -7
- package/src/self-implement/goal-elaborate.ts +449 -0
- package/src/self-implement/goal-refine.ts +273 -0
- package/src/self-implement/graph-overlay-yaml.ts +14 -3
- package/src/self-implement/graph-variant.ts +40 -6
- package/src/self-implement/headless-elanous-driver.ts +19 -3
- package/src/self-implement/off-diff-evidence.ts +58 -6
- package/src/self-implement/orchestrator.ts +370 -62
- package/src/self-implement/pod-warm-pool-profile.ts +1 -0
- package/src/self-implement/pwa-import-graph.ts +1 -1
- package/src/self-implement/rework-budget-judgment.ts +5 -8
- package/src/self-implement/rework-policy.ts +30 -0
- package/src/self-implement/run-ledger.ts +108 -0
- package/src/self-implement/run-stop.ts +10 -1
- package/src/self-implement/run-ttl.ts +38 -24
- package/src/self-implement/running-runs.ts +29 -1
- package/src/self-implement/scope-adjacency.ts +115 -0
- package/src/self-implement/seams.ts +187 -28
- package/src/self-implement/stop-autoheal.ts +87 -1
- package/src/self-implement/wiring-check.ts +358 -0
- package/src/session-runtime/index.ts +1 -1
- package/src/setup/llm-env-detect.ts +5 -0
- package/src/shell-env-bootstrap.ts +11 -4
- package/src/skills/runner.ts +4 -2
- package/src/skills/tools/agent.ts +408 -40
- package/src/skills/tools/msg-ask.ts +100 -0
- package/src/skills/tools/ops-ledger.ts +2 -1
- package/src/skills/tools/schedule-wakeup.ts +23 -4
- package/src/skills/tools/shell.ts +61 -6
- package/src/skills/tools/terminal-modal-inject.ts +1 -2
- package/src/skills/tools/terminal-modal.ts +10 -8
- package/src/skills/url-router.ts +41 -1
- package/src/smart-wizard/run.ts +66 -0
- package/src/status/bar.ts +34 -6
- package/src/status/status-provider-info.ts +37 -6
- package/src/steward/hold-hygiene.ts +24 -6
- package/src/steward/rejudge-tick.ts +10 -2
- package/src/steward/ta-repair-event-collect.ts +17 -6
- package/src/steward/triage-budget.ts +194 -0
- package/src/steward/triage.ts +20 -3
- package/src/task-agent/actions.ts +72 -2
- package/src/task-agent/green-sweep.ts +4 -0
- package/src/task-agent/land-queue.ts +21 -8
- package/src/task-agent/live-moves.ts +182 -10
- package/src/task-agent/mission.ts +30 -0
- package/src/task-agent/parent-host.ts +123 -3
- package/src/task-agent/rejudge-on-head.ts +15 -0
- package/src/task-agent/repair-cycle.ts +138 -32
- package/src/task-agent/repair-next-move.ts +31 -3
- package/src/task-agent/repair-outcomes.ts +29 -0
- package/src/task-agent/repair-worker.ts +14 -4
- package/src/task-agent/shadow.ts +48 -4
- package/src/task-agent/task-card-prefix.ts +2 -0
- package/src/task-agent/task-hand.ts +525 -57
- package/src/task-agent/task-parent-role-llm.ts +36 -0
- package/src/task-agent/tier-split.ts +196 -0
- package/src/task-agent/work-order-build.ts +2 -0
- package/src/task-agent/work-order.ts +3 -2
- package/src/task-orchestrator/generator-prompt.ts +60 -11
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +42 -0
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +130 -11
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
- package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
- package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +19 -2
- package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
- package/src/task-orchestrator/surfaces/pod-provenance.ts +82 -0
- package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
- package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +18 -0
- package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +6 -2
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +7 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +521 -40
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +759 -50
- package/src/task-orchestrator/surfaces/self-implement.ts +65 -2
- package/src/tool-runtime/index.ts +15 -2
- package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
- package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
- package/src/tty-foreground.ts +155 -0
- package/src/tui/README.md +2 -0
- package/src/tui/chat/background-job-status.ts +54 -0
- package/src/tui/chat/goal-interim.ts +173 -0
- package/src/tui/chat/log-view.ts +267 -0
- package/src/tui/chat/self-health-status.ts +232 -0
- package/src/tui/entry.ts +695 -0
- package/src/tui/input/composer.ts +151 -0
- package/src/tui/seat-mail-boot.ts +59 -0
- package/src/tui/slash/compact-command.ts +7 -0
- package/src/tui/slash/compact.ts +94 -0
- package/src/tui/slash/new-session.ts +35 -0
- package/src/tui/slash/resume.ts +75 -0
- package/src/tui-client/local-chat-turn.ts +282 -0
- package/src/tui-client/local-harness-command.ts +63 -0
- package/src/tui-client/local-provider-command.ts +184 -0
- package/src/tui-client/next-dashboard-runtime.ts +8 -0
- package/src/tui-client/next-loop-command.ts +70 -0
- package/src/tui-client/next-wakeup.ts +191 -0
- package/src/tui.ts +37 -0
- package/src/ui/modal-adapter.ts +2 -2
- package/src/user-config.ts +4 -2
- package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
- package/src/ux-sim/cli-config-audit-device.ts +121 -0
- package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
- package/src/ux-sim/event-monkey.ts +379 -0
- package/src/ux-sim/fake-bin.ts +87 -7
- package/src/ux-sim/fake-herdr.ts +238 -0
- package/src/ux-sim/fake-llm.ts +111 -6
- package/src/ux-sim/fault-glm-no-credential.ts +116 -0
- package/src/ux-sim/fault-nextmove-dispatch.ts +367 -0
- package/src/ux-sim/fault-pod-codex-503.ts +211 -0
- package/src/ux-sim/fault-scope-escape-lift.ts +216 -0
- package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
- package/src/ux-sim/goal-device.ts +619 -0
- package/src/ux-sim/in-process-cli.ts +22 -5
- package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
- package/src/ux-sim/mock-authoring-first-run.ts +97 -0
- package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
- package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
- package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
- package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
- package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
- package/src/ux-sim/onboarding-first-run-device.ts +269 -0
- package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
- package/src/ux-sim/subagent-tools-device.ts +81 -0
- package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
- package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +0 -79
- package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +0 -94
- package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +0 -23
- package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +0 -115
- package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +0 -8
- package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +0 -1
- package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2987-30cf9c2eb7b8bdd5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3001-5a52788c813b6113.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +0 -104
- package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +0 -149
- package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +0 -148
- package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +0 -64
- package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +0 -74
- package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5028-f0722e6114c313e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5249.96a848656b582a93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5489.ec2dd1b5272a19dc.js +0 -24
- package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +0 -1
- package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +0 -77
- package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +0 -90
- package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +0 -287
- package/apps/pwa/out/_next/static/chunks/7448.478958ffbbba0ac0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +0 -27
- package/apps/pwa/out/_next/static/chunks/7952.b192c31b6a0e00cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +0 -36
- package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +0 -1
- package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +0 -93
- package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +0 -24
- package/apps/pwa/out/_next/static/chunks/9739.8d5f36ac67a3b236.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +0 -1
- package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-398c0faa173203f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-df3445b207ceceab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +0 -122
- package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +0 -1
- /package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
package/src/index.ts
CHANGED
|
@@ -1,22 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// cron/launchd 최소 PATH 에서도 내부 gh/git subprocess 를 찾도록 PATH 를 먼저 보강(무음실패 근본·2026-07-25).
|
|
3
3
|
import './ensure-bin-path.js';
|
|
4
|
+
import './instance/resolve.js';
|
|
4
5
|
import { WORKFLOW_NODE_VARIANT_KEYS } from './workflow-runtime/schema.js';
|
|
5
6
|
import { accessSync, constants as fsConstants, existsSync, lstatSync, readFileSync, readlinkSync, realpathSync, statSync } from 'node:fs';
|
|
6
7
|
import type { SelfDevRunParticipant, SelfDevRunState } from './self-dev/run-store.js';
|
|
7
8
|
import { applyConfigDirFlagFromArgv } from './cli/config-dir-flag.js';
|
|
8
9
|
import { LOGS_SINCE_OPTION, registerLogsCommands } from './cli/logs-cli.js';
|
|
9
|
-
|
|
10
|
-
import { registerBenchCommands } from './cli/bench-cli.js';
|
|
11
|
-
import { registerRetroCommands } from './cli/retro-cli.js';
|
|
12
|
-
import { registerMemoryCommands } from './cli/memory-cli.js';
|
|
13
|
-
import { registerA2ACommands } from './cli/a2a-cli.js';
|
|
14
|
-
import { registerPluginCommands } from './cli/plugin-cli.js';
|
|
15
|
-
import { registerMakeCommand } from './cli/make-cli.js';
|
|
16
|
-
import { registerConnectCommand, registerSkillsCommands } from './cli/skills-cli.js';
|
|
17
|
-
import { registerImportCommand } from './cli/import-cli.js';
|
|
18
|
-
import { registerPersonaCommands } from './cli/persona-cli.js';
|
|
19
|
-
import { registerFleetCommands } from './cli/fleet-cli.js';
|
|
10
|
+
|
|
20
11
|
import { readPipedStdin } from './cli/piped-stdin.js';
|
|
21
12
|
import { writeStdoutJson } from './cli/stdout-json.js';
|
|
22
13
|
import { writeStdoutFully } from './cli/stdout-flush.js';
|
|
@@ -28,77 +19,26 @@ import { ensureRunIdentity, getHarnessSpace, normalizeSpaceId } from './harness/
|
|
|
28
19
|
// ⇒ «정적» import 로 올린다. 이 모듈은 부작용이 없어 부팅 비용이 사실상 0 이다.
|
|
29
20
|
import { installDevCompletionGuard } from './self-dev/dev-completion-guard.js';
|
|
30
21
|
import { formatOrchestrateResultLine } from './self-dev/orchestrate-summary-line.js';
|
|
31
|
-
import {
|
|
22
|
+
import { normalizeOrchestrateRequest, splitOrchestrateGoalTexts } from './self-dev/orchestrate-cli-text.js';
|
|
23
|
+
import { DEV_PLAN_REPLACEMENT, formatDevPlanOptionHelp, HARNESS_RUN_DEPRECATION_HELP } from './self-dev/cli-help-text.js';
|
|
32
24
|
import { CLI_ENTRANCE_BASELINE, evaluateCommandEntranceBaseline } from './self-dev/entrance-baseline.js';
|
|
33
25
|
import { CLI_HARNESS_DOGFOOD_ENTRANCE, CLI_HARNESS_ORCHESTRATE_ENTRANCE, describeEntranceCommand, listEntrancesWithModelExposure, renderLaunchEntrances, summarizeEntrances, type EntranceId } from './self-dev/entrance-registry.js';
|
|
34
26
|
import { isOldDoorInternalCall, refuseOldDoor } from './self-dev/old-door.js';
|
|
35
27
|
import { collectCommandEntrances, renderCommandEntrances } from './self-dev/entrance-inventory.js';
|
|
36
28
|
import { isGoalAuthorFileName } from './self-implement/goal-document.js';
|
|
37
29
|
import { DEV_PIPELINE_SINK_SURFACE } from './self-implement/self-cli-sink-surface.js';
|
|
38
|
-
|
|
39
|
-
import { registerKnowCommand } from './cli/know-cli.js';
|
|
40
|
-
import { registerSeatRequestsCommands } from './cli/seat-requests-cli.js';
|
|
41
|
-
import { registerSeatBootCommands } from './cli/seat-cli.js';
|
|
30
|
+
|
|
42
31
|
import { applyTestStateDirFlagFromArgv } from './cli/test-state-dir-flag.js';
|
|
43
32
|
import { applyTestFlagFromArgv, observeTestFlagOwnership, uncoveredTestFlagPaths, staleTestFlagPaths } from './cli/test-flag.js';
|
|
44
|
-
|
|
45
|
-
import { registerPtyRecordCommand } from './cli/pty-record-cli.js';
|
|
46
|
-
import { registerLeaderCommands } from './cli/leader-cli.js';
|
|
47
|
-
import { registerRepoCommands } from './cli/repo-cli.js';
|
|
48
|
-
import { registerAgentCommands, runChatTurnCli, emitDetachedProgress } from './cli/agent-cli.js';
|
|
49
|
-
export { runChatTurnCli, buildCliAgentTools, setCliAgentDispatchForTesting, emitDetachedProgress, emitHarnessFeedbackProgress } from './cli/agent-cli.js';
|
|
50
|
-
import { registerOpsCommands } from './cli/ops-cli.js';
|
|
51
|
-
import { registerOutputsCommands } from './cli/outputs-cli.js';
|
|
52
|
-
import { registerPublishCommands } from './cli/publish-cli.js';
|
|
53
|
-
import { registerAutopilotCommands } from './cli/autopilot-cli.js';
|
|
54
|
-
import { registerRoleCommands } from './cli/role-cli.js';
|
|
55
|
-
import { registerMachineCommands } from './cli/machine-cli.js';
|
|
33
|
+
|
|
56
34
|
import { recordImagePinFromConfigSet, registerImageCommands } from './cli/image-cli.js';
|
|
57
|
-
|
|
58
|
-
import { registerScheduleCommands } from './cli/schedule-cli.js';
|
|
59
|
-
import { registerGuardianCommands } from './cli/guardian-cli.js';
|
|
35
|
+
|
|
60
36
|
export { runSchedule, scheduleCreatePlan } from './cli/schedule-cli.js';
|
|
61
37
|
export type { ScheduleDispatch } from './cli/schedule-cli.js';
|
|
62
38
|
import { registerReviewLoopOptions, buildReviewLoopOpts } from './agent-mission/review-loop-cli.js';
|
|
63
|
-
|
|
64
|
-
import { registerSupervisorMetricsCommand } from './agent-mission/supervisor-metrics-cli.js';
|
|
65
|
-
import { agentBackendNames } from './agent-mission/driver.js';
|
|
66
|
-
import { registerWhereCommand } from './cli/where-cli.js';
|
|
67
|
-
import { registerShadowCommand } from './cli/shadow-cli.js';
|
|
68
|
-
import { registerLlmDetectCommand } from './cli/llm-detect-cli.js';
|
|
69
|
-
import { registerStorageDetectCommand } from './cli/storage-cli.js';
|
|
70
|
-
import { registerPodCommands } from './cli/pod-cli.js';
|
|
71
|
-
import { registerBrowserAnnotateCommand } from './cli/browser-annotate-cli.js';
|
|
72
|
-
import { registerPendingQuestionsCommand } from './cli/pending-questions-cli.js';
|
|
73
|
-
import { registerUsageCommand } from './cli/usage-cli.js';
|
|
74
|
-
import { registerUsageDailyCommand } from './cli/usage-daily-cli.js';
|
|
75
|
-
import { registerLiveCommands } from './cli/live-cli.js';
|
|
76
|
-
import { registerResearchCommand } from './cli/research-cli.js';
|
|
77
|
-
import { registerReleaseCommands } from './cli/release-cli.js';
|
|
78
|
-
import { registerFreezeCommands } from './cli/freeze-cli.js';
|
|
79
|
-
import { registerFlowCommands } from './cli/flow-cli.js';
|
|
80
|
-
import { registerModelWatchCommand } from './cli/model-watch-cli.js';
|
|
81
|
-
import { registerIntakeCommands } from './cli/intake-cli.js';
|
|
82
|
-
import { registerTasksCommands } from './cli/tasks-cli.js';
|
|
83
|
-
import { registerBriefCommands } from './cli/brief-cli.js';
|
|
84
|
-
import { registerNotifyCommand } from './cli/notify-cli.js';
|
|
85
|
-
import { registerAwayCommand } from './cli/away-cli.js';
|
|
86
|
-
import { registerLabelsCommands } from './cli/labels-cli.js';
|
|
87
|
-
import { registerMsgCommands } from './cli/msg-cli.js';
|
|
88
|
-
import { registerDoctorCommand } from './cli/doctor-cli.js';
|
|
89
|
-
import { registerProviderCommands } from './cli/provider-cli.js';
|
|
39
|
+
|
|
90
40
|
export { buildCodexAccountImportGuidance, setCodexAccountLogSinkModuleForTesting } from './cli/provider-cli.js';
|
|
91
|
-
|
|
92
|
-
import { registerHooksCommands } from './cli/hooks-cli.js';
|
|
93
|
-
import { registerSetupCommand } from './cli/setup-cli.js';
|
|
94
|
-
import { registerStartCommand } from './cli/start-cli.js';
|
|
95
|
-
import { registerGroundingSourcesCli } from './grounding/sources-cli.js';
|
|
96
|
-
import { registerGraphCommands } from './graph-runner/graph-cli.js';
|
|
97
|
-
import { registerLoopCommands } from './loops/loop-cli.js';
|
|
98
|
-
import { registerResourceCommands } from './cli/resource-cli.js';
|
|
99
|
-
import { registerHqMovePlanCommand } from './hq/hq.js';
|
|
100
|
-
import { registerCardCommand } from './task-cards/card-cli.js';
|
|
101
|
-
import { registerLaunchHeadCommands } from './launch-head/launch-head-cli.js';
|
|
41
|
+
|
|
102
42
|
import { acpServerHelpText } from './boot/acp-server-help.js';
|
|
103
43
|
// IMPORTANT: parse `--config-dir <dir>` + `--test-state-dir <dir>`
|
|
104
44
|
// BEFORE Commander loads — the resolvers are read at module-init
|
|
@@ -116,54 +56,314 @@ applyTestFlagFromArgv();
|
|
|
116
56
|
// test-instance default so scoped storage commands stay inside that directory.
|
|
117
57
|
applyConfigDirFlagFromArgv();
|
|
118
58
|
|
|
59
|
+
// Only unambiguous root commands take the small registrar path. Root help,
|
|
60
|
+
// unknown commands and unrecognized global flags keep the complete tree.
|
|
61
|
+
const INDEX_FAST_ROOTS = new Set(['a2a', 'agent-env', 'away', 'bench', 'brief', 'card', 'connect', 'control', 'docs', 'doctor', 'fleet', 'flow', 'freeze', 'graph', 'guardian', 'import', 'intake', 'know', 'labels', 'launch-head', 'leader', 'live', 'llm', 'loop', 'machine', 'make', 'memory', 'msg', 'notify', 'ops', 'outputs', 'plugin', 'pod', 'provider', 'pty', 'publish', 'questions', 'relay', 'release', 'repo', 'research', 'resource', 'retro', 'role', 'schedule', 'seat', 'shadow', 'skills', 'start', 'storage', 'tasks', 'where']);
|
|
62
|
+
function selectedIndexFastRoot(args: readonly string[]): string | undefined {
|
|
63
|
+
if (process.env.ELANOUS_TEST_FLAG_AUDIT === '1') return undefined;
|
|
64
|
+
let index = 0;
|
|
65
|
+
while (index < args.length && args[index]?.startsWith('-')) {
|
|
66
|
+
const flag = args[index]!;
|
|
67
|
+
index++;
|
|
68
|
+
if (flag === '--test' || flag.startsWith('--test=')) continue;
|
|
69
|
+
if (flag === '--config-dir' || flag === '--test-state-dir') {
|
|
70
|
+
if (!args[index] || args[index]!.startsWith('-')) return undefined;
|
|
71
|
+
index++;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (flag.startsWith('--config-dir=') || flag.startsWith('--test-state-dir=')) continue;
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
const root = args[index];
|
|
78
|
+
// We cannot know every registrar's local options before it is loaded. Keep
|
|
79
|
+
// only universally recognized help (and where's measured JSON action) on
|
|
80
|
+
// the small path; all other options take the complete parser.
|
|
81
|
+
const fastOptions = new Set(root === 'where' ? ['--help', '-h', '--json'] : ['--help', '-h']);
|
|
82
|
+
if (args.slice(index + 1).some((arg) => arg.startsWith('-') && !fastOptions.has(arg))) return undefined;
|
|
83
|
+
return root && INDEX_FAST_ROOTS.has(root) ? root : undefined;
|
|
84
|
+
}
|
|
85
|
+
// An explicit `--tui next` launch does not dispatch a CLI subcommand. Keep command
|
|
86
|
+
// registrars out of the first-frame path while retaining the full tree for
|
|
87
|
+
// help, unknown commands and unrecognized global flags.
|
|
88
|
+
function selectedIndexNextTuiRoot(args: readonly string[]): '__tui_next__' | undefined {
|
|
89
|
+
const rootTui = extractRootTuiEntry(args);
|
|
90
|
+
if (rootTui.error || rootTui.entry !== 'next') return undefined;
|
|
91
|
+
const remaining = rootTui.args.filter((arg) => arg !== '--test' && !arg.startsWith('--test='));
|
|
92
|
+
return remaining.length === 0 ? '__tui_next__' : undefined;
|
|
93
|
+
}
|
|
94
|
+
// Test files import this module to inspect the complete Commander tree. An
|
|
95
|
+
// empty test-runner argv also looks like a bare next launch, so only the real
|
|
96
|
+
// CLI entry may take the next-only registrar path.
|
|
97
|
+
const isCliEntry = import.meta.main || /[\\/]bin[\\/]elanous\.mjs$/.test(process.argv[1] ?? '');
|
|
98
|
+
const INDEX_FAST_ROOT = selectedIndexFastRoot(process.argv.slice(2))
|
|
99
|
+
?? (isCliEntry ? selectedIndexNextTuiRoot(process.argv.slice(2)) : undefined);
|
|
100
|
+
// Keep the historical index exports without forcing the agent engine into
|
|
101
|
+
// unrelated CLI commands at module load time.
|
|
102
|
+
export const runChatTurnCli: typeof import('./cli/agent-cli.js').runChatTurnCli =
|
|
103
|
+
async (...args) => (await import('./cli/agent-cli.js')).runChatTurnCli(...args);
|
|
104
|
+
export const buildCliAgentTools: typeof import('./cli/agent-cli.js').buildCliAgentTools =
|
|
105
|
+
(...args) => (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).buildCliAgentTools(...args);
|
|
106
|
+
export const setCliAgentDispatchForTesting: typeof import('./cli/agent-cli.js').setCliAgentDispatchForTesting =
|
|
107
|
+
(...args) => (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).setCliAgentDispatchForTesting(...args);
|
|
108
|
+
export const emitDetachedProgress: typeof import('./cli/agent-cli.js').emitDetachedProgress =
|
|
109
|
+
(...args) => (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).emitDetachedProgress(...args);
|
|
110
|
+
export const emitHarnessFeedbackProgress: typeof import('./cli/agent-cli.js').emitHarnessFeedbackProgress =
|
|
111
|
+
(...args) => (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).emitHarnessFeedbackProgress(...args);
|
|
112
|
+
|
|
113
|
+
// Selected root imports only its registrar; complete help and unknown routes load all.
|
|
114
|
+
const registerDocsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'docs'
|
|
115
|
+
? (() => undefined)
|
|
116
|
+
: (require('./cli/docs-cli.js') as typeof import('./cli/docs-cli.js')).registerDocsCommands) as typeof import('./cli/docs-cli.js').registerDocsCommands;
|
|
117
|
+
const registerBenchCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'bench'
|
|
118
|
+
? (() => undefined)
|
|
119
|
+
: (require('./cli/bench-cli.js') as typeof import('./cli/bench-cli.js')).registerBenchCommands) as typeof import('./cli/bench-cli.js').registerBenchCommands;
|
|
120
|
+
const registerRetroCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'retro'
|
|
121
|
+
? (() => undefined)
|
|
122
|
+
: (require('./cli/retro-cli.js') as typeof import('./cli/retro-cli.js')).registerRetroCommands) as typeof import('./cli/retro-cli.js').registerRetroCommands;
|
|
123
|
+
const registerMemoryCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'memory'
|
|
124
|
+
? (() => undefined)
|
|
125
|
+
: (require('./cli/memory-cli.js') as typeof import('./cli/memory-cli.js')).registerMemoryCommands) as typeof import('./cli/memory-cli.js').registerMemoryCommands;
|
|
126
|
+
const registerA2ACommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'a2a'
|
|
127
|
+
? (() => undefined)
|
|
128
|
+
: (require('./cli/a2a-cli.js') as typeof import('./cli/a2a-cli.js')).registerA2ACommands) as typeof import('./cli/a2a-cli.js').registerA2ACommands;
|
|
129
|
+
const registerPluginCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'plugin'
|
|
130
|
+
? (() => undefined)
|
|
131
|
+
: (await import('./cli/plugin-cli.js')).registerPluginCommands) as typeof import('./cli/plugin-cli.js').registerPluginCommands;
|
|
132
|
+
const registerMakeCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'make'
|
|
133
|
+
? (() => undefined)
|
|
134
|
+
: (require('./cli/make-cli.js') as typeof import('./cli/make-cli.js')).registerMakeCommand) as typeof import('./cli/make-cli.js').registerMakeCommand;
|
|
135
|
+
const registerConnectCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'connect'
|
|
136
|
+
? (() => undefined)
|
|
137
|
+
: (require('./cli/skills-cli.js') as typeof import('./cli/skills-cli.js')).registerConnectCommand) as typeof import('./cli/skills-cli.js').registerConnectCommand;
|
|
138
|
+
const registerSkillsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'skills'
|
|
139
|
+
? (() => undefined)
|
|
140
|
+
: (require('./cli/skills-cli.js') as typeof import('./cli/skills-cli.js')).registerSkillsCommands) as typeof import('./cli/skills-cli.js').registerSkillsCommands;
|
|
141
|
+
const registerImportCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'import'
|
|
142
|
+
? (() => undefined)
|
|
143
|
+
: (require('./cli/import-cli.js') as typeof import('./cli/import-cli.js')).registerImportCommand) as typeof import('./cli/import-cli.js').registerImportCommand;
|
|
144
|
+
const registerPersonaCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
145
|
+
? (() => undefined)
|
|
146
|
+
: (await import('./cli/persona-cli.js')).registerPersonaCommands) as typeof import('./cli/persona-cli.js').registerPersonaCommands;
|
|
147
|
+
const registerFleetCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'fleet'
|
|
148
|
+
? (() => undefined)
|
|
149
|
+
: (require('./cli/fleet-cli.js') as typeof import('./cli/fleet-cli.js')).registerFleetCommands) as typeof import('./cli/fleet-cli.js').registerFleetCommands;
|
|
150
|
+
const registerPrivateLedgerCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
151
|
+
? (() => undefined)
|
|
152
|
+
: (require('./cli/private-ledger-commands.js') as typeof import('./cli/private-ledger-commands.js')).registerPrivateLedgerCommands) as typeof import('./cli/private-ledger-commands.js').registerPrivateLedgerCommands;
|
|
153
|
+
const registerKnowCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'know'
|
|
154
|
+
? (() => undefined)
|
|
155
|
+
: (require('./cli/know-cli.js') as typeof import('./cli/know-cli.js')).registerKnowCommand) as typeof import('./cli/know-cli.js').registerKnowCommand;
|
|
156
|
+
const registerSeatRequestsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'seat'
|
|
157
|
+
? (() => undefined)
|
|
158
|
+
: (require('./cli/seat-requests-cli.js') as typeof import('./cli/seat-requests-cli.js')).registerSeatRequestsCommands) as typeof import('./cli/seat-requests-cli.js').registerSeatRequestsCommands;
|
|
159
|
+
const registerSeatBootCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'seat'
|
|
160
|
+
? (() => undefined)
|
|
161
|
+
: (require('./cli/seat-cli.js') as typeof import('./cli/seat-cli.js')).registerSeatBootCommands) as typeof import('./cli/seat-cli.js').registerSeatBootCommands;
|
|
162
|
+
const registerPtyTakeoverCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'pty'
|
|
163
|
+
? (() => undefined)
|
|
164
|
+
: (require('./cli/pty-takeover-cli.js') as typeof import('./cli/pty-takeover-cli.js')).registerPtyTakeoverCommands) as typeof import('./cli/pty-takeover-cli.js').registerPtyTakeoverCommands;
|
|
165
|
+
const registerPtyRecordCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'pty'
|
|
166
|
+
? (() => undefined)
|
|
167
|
+
: (require('./cli/pty-record-cli.js') as typeof import('./cli/pty-record-cli.js')).registerPtyRecordCommand) as typeof import('./cli/pty-record-cli.js').registerPtyRecordCommand;
|
|
168
|
+
const registerLeaderCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'leader'
|
|
169
|
+
? (() => undefined)
|
|
170
|
+
: (require('./cli/leader-cli.js') as typeof import('./cli/leader-cli.js')).registerLeaderCommands) as typeof import('./cli/leader-cli.js').registerLeaderCommands;
|
|
171
|
+
const registerRepoCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'repo'
|
|
172
|
+
? (() => undefined)
|
|
173
|
+
: (require('./cli/repo-cli.js') as typeof import('./cli/repo-cli.js')).registerRepoCommands) as typeof import('./cli/repo-cli.js').registerRepoCommands;
|
|
174
|
+
const registerOpsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'ops'
|
|
175
|
+
? (() => undefined)
|
|
176
|
+
: (require('./cli/ops-cli.js') as typeof import('./cli/ops-cli.js')).registerOpsCommands) as typeof import('./cli/ops-cli.js').registerOpsCommands;
|
|
177
|
+
const registerOutputsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'outputs'
|
|
178
|
+
? (() => undefined)
|
|
179
|
+
: (require('./cli/outputs-cli.js') as typeof import('./cli/outputs-cli.js')).registerOutputsCommands) as typeof import('./cli/outputs-cli.js').registerOutputsCommands;
|
|
180
|
+
const registerPublishCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'publish'
|
|
181
|
+
? (() => undefined)
|
|
182
|
+
: (require('./cli/publish-cli.js') as typeof import('./cli/publish-cli.js')).registerPublishCommands) as typeof import('./cli/publish-cli.js').registerPublishCommands;
|
|
183
|
+
const registerAutopilotCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
184
|
+
? (() => undefined)
|
|
185
|
+
: (require('./cli/autopilot-cli.js') as typeof import('./cli/autopilot-cli.js')).registerAutopilotCommands) as typeof import('./cli/autopilot-cli.js').registerAutopilotCommands;
|
|
186
|
+
const registerRoleCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'role'
|
|
187
|
+
? (() => undefined)
|
|
188
|
+
: (require('./cli/role-cli.js') as typeof import('./cli/role-cli.js')).registerRoleCommands) as typeof import('./cli/role-cli.js').registerRoleCommands;
|
|
189
|
+
const registerMachineCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'machine'
|
|
190
|
+
? (() => undefined)
|
|
191
|
+
: (require('./cli/machine-cli.js') as typeof import('./cli/machine-cli.js')).registerMachineCommands) as typeof import('./cli/machine-cli.js').registerMachineCommands;
|
|
192
|
+
const registerAgentEnvCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'agent-env'
|
|
193
|
+
? (() => undefined)
|
|
194
|
+
: (require('./cli/agent-env-cli.js') as typeof import('./cli/agent-env-cli.js')).registerAgentEnvCommands) as typeof import('./cli/agent-env-cli.js').registerAgentEnvCommands;
|
|
195
|
+
const registerScheduleCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'schedule'
|
|
196
|
+
? (() => undefined)
|
|
197
|
+
: (require('./cli/schedule-cli.js') as typeof import('./cli/schedule-cli.js')).registerScheduleCommands) as typeof import('./cli/schedule-cli.js').registerScheduleCommands;
|
|
198
|
+
const registerGuardianCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'guardian'
|
|
199
|
+
? (() => undefined)
|
|
200
|
+
: (require('./cli/guardian-cli.js') as typeof import('./cli/guardian-cli.js')).registerGuardianCommands) as typeof import('./cli/guardian-cli.js').registerGuardianCommands;
|
|
201
|
+
const registerCapabilitiesCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
202
|
+
? (() => undefined)
|
|
203
|
+
: (require('./agent-mission/capabilities-cli.js') as typeof import('./agent-mission/capabilities-cli.js')).registerCapabilitiesCommand) as typeof import('./agent-mission/capabilities-cli.js').registerCapabilitiesCommand;
|
|
204
|
+
const registerSupervisorMetricsCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
205
|
+
? (() => undefined)
|
|
206
|
+
: (require('./agent-mission/supervisor-metrics-cli.js') as typeof import('./agent-mission/supervisor-metrics-cli.js')).registerSupervisorMetricsCommand) as typeof import('./agent-mission/supervisor-metrics-cli.js').registerSupervisorMetricsCommand;
|
|
207
|
+
const registerWhereCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'where'
|
|
208
|
+
? (() => undefined)
|
|
209
|
+
: (require('./cli/where-cli.js') as typeof import('./cli/where-cli.js')).registerWhereCommand) as typeof import('./cli/where-cli.js').registerWhereCommand;
|
|
210
|
+
const registerShadowCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'shadow'
|
|
211
|
+
? (() => undefined)
|
|
212
|
+
: (require('./cli/shadow-cli.js') as typeof import('./cli/shadow-cli.js')).registerShadowCommand) as typeof import('./cli/shadow-cli.js').registerShadowCommand;
|
|
213
|
+
const registerLlmDetectCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'llm'
|
|
214
|
+
? (() => undefined)
|
|
215
|
+
: (require('./cli/llm-detect-cli.js') as typeof import('./cli/llm-detect-cli.js')).registerLlmDetectCommand) as typeof import('./cli/llm-detect-cli.js').registerLlmDetectCommand;
|
|
216
|
+
const registerStorageDetectCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'storage'
|
|
217
|
+
? (() => undefined)
|
|
218
|
+
: (require('./cli/storage-cli.js') as typeof import('./cli/storage-cli.js')).registerStorageDetectCommand) as typeof import('./cli/storage-cli.js').registerStorageDetectCommand;
|
|
219
|
+
const registerPodCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'pod'
|
|
220
|
+
? (() => undefined)
|
|
221
|
+
: (require('./cli/pod-cli.js') as typeof import('./cli/pod-cli.js')).registerPodCommands) as typeof import('./cli/pod-cli.js').registerPodCommands;
|
|
222
|
+
const registerBrowserAnnotateCommand = (require('./cli/browser-annotate-cli.js') as typeof import('./cli/browser-annotate-cli.js')).registerBrowserAnnotateCommand;
|
|
223
|
+
const registerPendingQuestionsCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'questions'
|
|
224
|
+
? (() => undefined)
|
|
225
|
+
: (require('./cli/pending-questions-cli.js') as typeof import('./cli/pending-questions-cli.js')).registerPendingQuestionsCommand) as typeof import('./cli/pending-questions-cli.js').registerPendingQuestionsCommand;
|
|
226
|
+
const registerUsageCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
227
|
+
? (() => undefined)
|
|
228
|
+
: (require('./cli/usage-cli.js') as typeof import('./cli/usage-cli.js')).registerUsageCommand) as typeof import('./cli/usage-cli.js').registerUsageCommand;
|
|
229
|
+
const registerUsageDailyCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
230
|
+
? (() => undefined)
|
|
231
|
+
: (require('./cli/usage-daily-cli.js') as typeof import('./cli/usage-daily-cli.js')).registerUsageDailyCommand) as typeof import('./cli/usage-daily-cli.js').registerUsageDailyCommand;
|
|
232
|
+
const registerLiveCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'live'
|
|
233
|
+
? (() => undefined)
|
|
234
|
+
: (require('./cli/live-cli.js') as typeof import('./cli/live-cli.js')).registerLiveCommands) as typeof import('./cli/live-cli.js').registerLiveCommands;
|
|
235
|
+
const registerResearchCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'research'
|
|
236
|
+
? (() => undefined)
|
|
237
|
+
: (require('./cli/research-cli.js') as typeof import('./cli/research-cli.js')).registerResearchCommand) as typeof import('./cli/research-cli.js').registerResearchCommand;
|
|
238
|
+
const registerReleaseCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'release'
|
|
239
|
+
? (() => undefined)
|
|
240
|
+
: (require('./cli/release-cli.js') as typeof import('./cli/release-cli.js')).registerReleaseCommands) as typeof import('./cli/release-cli.js').registerReleaseCommands;
|
|
241
|
+
const registerFreezeCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'freeze'
|
|
242
|
+
? (() => undefined)
|
|
243
|
+
: (require('./cli/freeze-cli.js') as typeof import('./cli/freeze-cli.js')).registerFreezeCommands) as typeof import('./cli/freeze-cli.js').registerFreezeCommands;
|
|
244
|
+
// TUI-HERDR-NAMED-AGENT (10-22): `herdr prompt` — herdr agent prompt rejects custom-reported agents.
|
|
245
|
+
const registerHerdrCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
246
|
+
? (() => undefined)
|
|
247
|
+
: (require('./cli/herdr-cli.js') as typeof import('./cli/herdr-cli.js')).registerHerdrCommands) as typeof import('./cli/herdr-cli.js').registerHerdrCommands;
|
|
248
|
+
const registerFlowCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'flow'
|
|
249
|
+
? (() => undefined)
|
|
250
|
+
: (require('./cli/flow-cli.js') as typeof import('./cli/flow-cli.js')).registerFlowCommands) as typeof import('./cli/flow-cli.js').registerFlowCommands;
|
|
251
|
+
const registerModelWatchCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
252
|
+
? (() => undefined)
|
|
253
|
+
: (require('./cli/model-watch-cli.js') as typeof import('./cli/model-watch-cli.js')).registerModelWatchCommand) as typeof import('./cli/model-watch-cli.js').registerModelWatchCommand;
|
|
254
|
+
const registerIntakeCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'intake'
|
|
255
|
+
? (() => undefined)
|
|
256
|
+
: (require('./cli/intake-cli.js') as typeof import('./cli/intake-cli.js')).registerIntakeCommands) as typeof import('./cli/intake-cli.js').registerIntakeCommands;
|
|
257
|
+
const registerTasksCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'tasks'
|
|
258
|
+
? (() => undefined)
|
|
259
|
+
: (require('./cli/tasks-cli.js') as typeof import('./cli/tasks-cli.js')).registerTasksCommands) as typeof import('./cli/tasks-cli.js').registerTasksCommands;
|
|
260
|
+
const registerBriefCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'brief'
|
|
261
|
+
? (() => undefined)
|
|
262
|
+
: (await import('./cli/brief-cli.js')).registerBriefCommands) as typeof import('./cli/brief-cli.js').registerBriefCommands;
|
|
263
|
+
const registerNotifyCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'notify'
|
|
264
|
+
? (() => undefined)
|
|
265
|
+
: (require('./cli/notify-cli.js') as typeof import('./cli/notify-cli.js')).registerNotifyCommand) as typeof import('./cli/notify-cli.js').registerNotifyCommand;
|
|
266
|
+
const registerAwayCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'away'
|
|
267
|
+
? (() => undefined)
|
|
268
|
+
: (await import('./cli/away-cli.js')).registerAwayCommand) as typeof import('./cli/away-cli.js').registerAwayCommand;
|
|
269
|
+
const registerLabelsCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'labels'
|
|
270
|
+
? (() => undefined)
|
|
271
|
+
: (require('./cli/labels-cli.js') as typeof import('./cli/labels-cli.js')).registerLabelsCommands) as typeof import('./cli/labels-cli.js').registerLabelsCommands;
|
|
272
|
+
const registerMsgCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'msg'
|
|
273
|
+
? (() => undefined)
|
|
274
|
+
: (require('./cli/msg-cli.js') as typeof import('./cli/msg-cli.js')).registerMsgCommands) as typeof import('./cli/msg-cli.js').registerMsgCommands;
|
|
275
|
+
const registerDoctorCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'doctor'
|
|
276
|
+
? (() => undefined)
|
|
277
|
+
: (require('./cli/doctor-cli.js') as typeof import('./cli/doctor-cli.js')).registerDoctorCommand) as typeof import('./cli/doctor-cli.js').registerDoctorCommand;
|
|
278
|
+
const registerProviderCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'provider'
|
|
279
|
+
? (() => undefined)
|
|
280
|
+
: (require('./cli/provider-cli.js') as typeof import('./cli/provider-cli.js')).registerProviderCommands) as typeof import('./cli/provider-cli.js').registerProviderCommands;
|
|
281
|
+
const registerAgentCommands = (INDEX_FAST_ROOT
|
|
282
|
+
? (() => undefined)
|
|
283
|
+
: (require('./cli/agent-cli.js') as typeof import('./cli/agent-cli.js')).registerAgentCommands) as typeof import('./cli/agent-cli.js').registerAgentCommands;
|
|
284
|
+
const registerControlCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'control'
|
|
285
|
+
? (() => undefined)
|
|
286
|
+
: (require('./cli/control-cli.js') as typeof import('./cli/control-cli.js')).registerControlCommands) as typeof import('./cli/control-cli.js').registerControlCommands;
|
|
287
|
+
const registerHooksCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
288
|
+
? (() => undefined)
|
|
289
|
+
: (require('./cli/hooks-cli.js') as typeof import('./cli/hooks-cli.js')).registerHooksCommands) as typeof import('./cli/hooks-cli.js').registerHooksCommands;
|
|
290
|
+
const registerSetupCommand = (INDEX_FAST_ROOT === '__tui_next__'
|
|
291
|
+
? (() => undefined)
|
|
292
|
+
: (require('./cli/setup-cli.js') as typeof import('./cli/setup-cli.js')).registerSetupCommand) as typeof import('./cli/setup-cli.js').registerSetupCommand;
|
|
293
|
+
const registerStartCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'start'
|
|
294
|
+
? (() => undefined)
|
|
295
|
+
: (require('./cli/start-cli.js') as typeof import('./cli/start-cli.js')).registerStartCommand) as typeof import('./cli/start-cli.js').registerStartCommand;
|
|
296
|
+
const registerGroundingSourcesCli = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
297
|
+
? (() => undefined)
|
|
298
|
+
: (require('./grounding/sources-cli.js') as typeof import('./grounding/sources-cli.js')).registerGroundingSourcesCli) as typeof import('./grounding/sources-cli.js').registerGroundingSourcesCli;
|
|
299
|
+
const registerGraphCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'graph'
|
|
300
|
+
? (() => undefined)
|
|
301
|
+
: (require('./graph-runner/graph-cli.js') as typeof import('./graph-runner/graph-cli.js')).registerGraphCommands) as typeof import('./graph-runner/graph-cli.js').registerGraphCommands;
|
|
302
|
+
const registerLoopCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'loop'
|
|
303
|
+
? (() => undefined)
|
|
304
|
+
: (require('./loops/loop-cli.js') as typeof import('./loops/loop-cli.js')).registerLoopCommands) as typeof import('./loops/loop-cli.js').registerLoopCommands;
|
|
305
|
+
const registerResourceCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'resource'
|
|
306
|
+
? (() => undefined)
|
|
307
|
+
: (require('./cli/resource-cli.js') as typeof import('./cli/resource-cli.js')).registerResourceCommands) as typeof import('./cli/resource-cli.js').registerResourceCommands;
|
|
308
|
+
const registerHqMovePlanCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
309
|
+
? (() => undefined)
|
|
310
|
+
: (require('./hq/hq.js') as typeof import('./hq/hq.js')).registerHqMovePlanCommand) as typeof import('./hq/hq.js').registerHqMovePlanCommand;
|
|
311
|
+
const registerCardCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'card'
|
|
312
|
+
? (() => undefined)
|
|
313
|
+
: (require('./task-cards/card-cli.js') as typeof import('./task-cards/card-cli.js')).registerCardCommand) as typeof import('./task-cards/card-cli.js').registerCardCommand;
|
|
314
|
+
const registerLaunchHeadCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'launch-head'
|
|
315
|
+
? (() => undefined)
|
|
316
|
+
: (require('./launch-head/launch-head-cli.js') as typeof import('./launch-head/launch-head-cli.js')).registerLaunchHeadCommands) as typeof import('./launch-head/launch-head-cli.js').registerLaunchHeadCommands;
|
|
317
|
+
const registerIngestTokenCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
318
|
+
? (() => undefined)
|
|
319
|
+
: (require('./cli/ingest-token-cli.js') as typeof import('./cli/ingest-token-cli.js')).registerIngestTokenCommands) as typeof import('./cli/ingest-token-cli.js').registerIngestTokenCommands;
|
|
320
|
+
const registerMcpGatewayCommands = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== '__full__'
|
|
321
|
+
? (() => undefined)
|
|
322
|
+
: (require('./cli/mcp-gateway-cli.js') as typeof import('./cli/mcp-gateway-cli.js')).registerMcpGatewayCommands) as typeof import('./cli/mcp-gateway-cli.js').registerMcpGatewayCommands;
|
|
323
|
+
const registerRelayCommand = (INDEX_FAST_ROOT && INDEX_FAST_ROOT !== 'relay'
|
|
324
|
+
? (() => undefined)
|
|
325
|
+
: (require('./relay/relay-cli.js') as typeof import('./relay/relay-cli.js')).registerRelayCommand) as typeof import('./relay/relay-cli.js').registerRelayCommand;
|
|
326
|
+
|
|
327
|
+
|
|
119
328
|
import { Command, Option } from 'commander';
|
|
120
329
|
import { filterCliRootHelp } from './maturity/cli-maturity.js';
|
|
121
330
|
import type { AdPipelinePlan, AdPipelineResult } from './ad-pipeline/run.js';
|
|
122
331
|
import type { AcpPermissionApprover } from './acp/client.js';
|
|
123
332
|
import { runGitCommand } from './git-fs/runner.js';
|
|
124
333
|
import { debug, redactSecretText, redactSecrets } from './debug/log.js';
|
|
125
|
-
import {
|
|
334
|
+
import type { HarnessAskSayChildLlmOptions, HarnessAskSayOptions, HarnessPlanOptions } from './harness/harness-cli-command.js';
|
|
126
335
|
import { CliUserError, formatCliUserError, isCliUserError } from './cli/cli-user-error.js';
|
|
127
336
|
import { classifyFriendlyError, formatFriendlyError } from './cli/friendly-errors.js';
|
|
128
337
|
import { detectLocale } from './expression/locale.js';
|
|
129
|
-
import { dispatchSolveMission } from './skills/tools/solve-mission.js';
|
|
130
338
|
import { performBrowserAction, type BrowserActionDeps, type BrowserActionResult } from './harness/browser-act.js';
|
|
131
339
|
import { decideTypeAction, type TypeActionDecision, type TypeTarget } from './harness/browser-act-type.js';
|
|
132
|
-
import { resolveSelfSendTarget } from './harness/self-send-target.js';
|
|
133
340
|
import { awaitGlobalPersonaLoad, describeMissingPersona, getGlobalPersonaRegistry } from './persona/global-registry.js';
|
|
134
|
-
import { HARNESS_RUN_DEPRECATION_HELP } from './self-dev/harness-run-cli.js';
|
|
135
|
-
import { DEV_PLAN_REPLACEMENT, formatDevPlanOptionHelp } from './self-dev/dev-cli.js';
|
|
136
341
|
import type { InventoryMeta, SortKey } from './llm/local-manager/benchmark/scores.js';
|
|
137
342
|
import { syncServers, SERVICE_NAMES } from './config.js';
|
|
138
343
|
import { getLocalSkills, executeSync } from './sync.js';
|
|
139
|
-
import { showSyncSelector, showSyncProgress } from './selector.js'; // kept for CLI sync subcommand
|
|
140
344
|
import { inspectRemote } from './inspect.js';
|
|
141
345
|
import { showRecentHistory, showSessionDetail, showSkillDetail, showTargetDetail, showStatus } from './history.js';
|
|
142
|
-
import { showDashboard } from './dashboard/index.js';
|
|
143
346
|
import { initTui, closeTui } from './tui.js';
|
|
347
|
+
import { effectiveRootTuiEntry, extractRootTuiEntry } from './cli/root-tui-entry.js';
|
|
144
348
|
import * as ui from './ui.js';
|
|
145
|
-
import { DEFAULT_REVIEW_BACKEND } from './agent-substrate/acp-reviewer.js';
|
|
146
349
|
import type { ReviewResult } from './agent-substrate/pr-reviewer.js';
|
|
147
350
|
import type { ReviewVerdict } from './agent-mission/review-loop.js';
|
|
148
351
|
import type { SyncMode } from './types.js';
|
|
149
|
-
import {
|
|
150
|
-
import { firstChatGate } from './onboarding/first-chat-gate.js';
|
|
352
|
+
import type { OnboardingStepId } from './onboarding.js';
|
|
151
353
|
import {
|
|
152
354
|
getUserConfig, reloadUserConfig, userConfigPath, saveUserConfig,
|
|
153
355
|
backupUserConfig, backupConfigPath, addRotationEntry, type RotationEntry,
|
|
154
356
|
resolveRoleLlm,
|
|
155
357
|
} from './user-config.js';
|
|
156
358
|
import { reviewReasoningEffort } from './model-tier/review-effort.js';
|
|
157
|
-
import { isKeylessProvider, resolveProviderCredential } from './llm/provider-credentials.js';
|
|
359
|
+
import { configuredOpenGatewayKeys, isKeylessProvider, resolveProviderCredential } from './llm/provider-credentials.js';
|
|
158
360
|
import {
|
|
159
361
|
listSessions, loadSession, deleteSession, resolveSessionId,
|
|
160
362
|
setActiveSessionId, getActiveSessionId,
|
|
161
363
|
lastConversationMessage, isSessionSource,
|
|
162
364
|
} from './session/index.js';
|
|
163
365
|
import { requestSessionTurnControl } from './session/session-turn-control.js';
|
|
164
|
-
import { ensureCliSession, sessionBudget } from './session/chat.js';
|
|
165
366
|
import { suggestProjectForFolder } from './project/project-store.js';
|
|
166
|
-
import { botFromConfig, TelegramBot } from './telegram.js';
|
|
167
367
|
import { acquireTelegramLock, TelegramLockError, defaultLockPath, safeReadLock } from './telegram-lock.js';
|
|
168
368
|
import { basename, join as _joinPath, resolve } from 'node:path';
|
|
169
369
|
import * as nodeReadline from 'node:readline/promises';
|
|
@@ -189,14 +389,13 @@ import { renderKeyHelp, CONTEXT_LABELS, type KeyContext } from './keybindings.js
|
|
|
189
389
|
import { auditKeybindings, renderKeymapAudit } from './keymap-audit.js';
|
|
190
390
|
import { runCodexSetup } from './codex/setup.js';
|
|
191
391
|
import { renderAllModels } from './codex/models.js';
|
|
192
|
-
import { realIO } from './onboarding.js';
|
|
193
392
|
import { inspectActiveProvider, oneLineProvider } from './provider-summary.js';
|
|
194
393
|
import { renderStatusLines, renderPrimaryStatus, renderSecondaryStatus } from './status/bar.js';
|
|
195
394
|
import { initSessionWorkingDir } from './session/working-dir.js';
|
|
196
395
|
import { rewriteBareNexusToStatus } from './cli/nexus-entry.js';
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
200
399
|
import type { ReviewImage } from './agent-substrate/pr-reviewer.js';
|
|
201
400
|
import {
|
|
202
401
|
describeMissionRouting,
|
|
@@ -218,6 +417,8 @@ function resolveCliDirOption(dir: string): string {
|
|
|
218
417
|
import { cliVersion, setInstallMetadataRootForTesting } from './version/code-revision.js';
|
|
219
418
|
export { cliVersion, setInstallMetadataRootForTesting };
|
|
220
419
|
|
|
420
|
+
|
|
421
|
+
|
|
221
422
|
export const program = new Command();
|
|
222
423
|
program.enablePositionalOptions();
|
|
223
424
|
|
|
@@ -242,6 +443,7 @@ program.command('preview <target>')
|
|
|
242
443
|
export { SELF_SEND_RECENT_FRAME_WINDOW_MS, SELF_SEND_STALE_HEARTBEAT_MS, formatSelfSendCandidateDisplay } from './harness/self-send-decide.js';
|
|
243
444
|
export type { SelfSendCandidate, SelfSendCandidateDisplay } from './harness/self-send-decide.js';
|
|
244
445
|
import { decideSelfSend, type SelfSendCandidate } from './harness/self-send-decide.js';
|
|
446
|
+
import { mayLookupRemotePodRun } from './harness/self-send-routing-guard.js';
|
|
245
447
|
type RunDevAskBuildDevCliSpec = typeof import('./self-dev/dev-cli.js')['buildDevCliSpec'];
|
|
246
448
|
type RunDevAskExecuteDevSelfRun = typeof import('./self-dev/dev-cli.js')['executeDevSelfRun'];
|
|
247
449
|
type RunDevAskStartDraftTriage = typeof import('./self-dev/dev-cli.js')['startDraftTriage'];
|
|
@@ -379,8 +581,12 @@ async function runDefaultAskFileLaunchFlow(
|
|
|
379
581
|
import('node:path'),
|
|
380
582
|
import('./self-dev/entrance-registry.js'),
|
|
381
583
|
]);
|
|
382
|
-
|
|
584
|
+
// Read the source bytes ONCE: the same bytes feed the ledger and the launch flow (a read failure → launch 0).
|
|
585
|
+
const askBytes = readFileSync(askPath);
|
|
586
|
+
const askText = askBytes.toString('utf8');
|
|
383
587
|
if (!askText.trim()) throw new Error('--ask 파일 입력이 비었다');
|
|
588
|
+
const { newLaunchUtteranceId, recordLaunchUtterance } = await import('./harness/launch-utterance-ledger.js');
|
|
589
|
+
recordLaunchUtterance({ source: 'ask-file', utterance: askText, rawBytes: askBytes, launchId: newLaunchUtteranceId() });
|
|
384
590
|
const askIo = await import('./self-dev/ask-launch-io.js');
|
|
385
591
|
const askLogRows = await askIo.readAskPreflightLogRows();
|
|
386
592
|
const askLaunchPrep = (await import('./self-dev/launch-preflight.js')).prepareAskLaunch(
|
|
@@ -401,7 +607,7 @@ async function runDefaultAskFileLaunchFlow(
|
|
|
401
607
|
print: (line) => console.error(line),
|
|
402
608
|
log: (event, data, level) => debug.log('dev-pipeline', event, data, { level }),
|
|
403
609
|
readLine: (prompt) => readStdinLine(prompt),
|
|
404
|
-
readFile: (file) => readFileSync(file, 'utf8'),
|
|
610
|
+
readFile: (file) => file === askPath ? askText : readFileSync(file, 'utf8'),
|
|
405
611
|
writeFile: (file, data) => writeFileSync(file, data, 'utf8'),
|
|
406
612
|
cwd: () => process.cwd(),
|
|
407
613
|
now: () => Date.now(),
|
|
@@ -1049,6 +1255,7 @@ registerKnowCommand(program);
|
|
|
1049
1255
|
registerNotifyCommand(program);
|
|
1050
1256
|
registerAwayCommand(program);
|
|
1051
1257
|
registerFreezeCommands(program);
|
|
1258
|
+
registerHerdrCommands(program);
|
|
1052
1259
|
registerFlowCommands(program);
|
|
1053
1260
|
// HQ-HB · HQ-FENCE (10-04): one writer across mbp · node-b · cloud-vm — lease on the arbiter, 2-of-3 quorum, generation fencing.
|
|
1054
1261
|
const hqCmd = program.command('hq').description('본부 임대 — 하트비트·중재·단일 작성자 래퍼');
|
|
@@ -1383,14 +1590,16 @@ registerDoctorCommand(program);
|
|
|
1383
1590
|
registerControlCommands(program);
|
|
1384
1591
|
registerHooksCommands(program);
|
|
1385
1592
|
registerSetupCommand(program);
|
|
1386
|
-
|
|
1387
|
-
.
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1593
|
+
if (INDEX_FAST_ROOT !== '__tui_next__') {
|
|
1594
|
+
program.commands.find(command => command.name() === 'setup')!
|
|
1595
|
+
.option('--terminal', 'Run the terminal onboarding wizard')
|
|
1596
|
+
.hook('preAction', async (_command, action) => {
|
|
1597
|
+
if (action.name() === 'setup' && action.opts().terminal) {
|
|
1598
|
+
const completed = await runOnboardingForCli();
|
|
1599
|
+
process.exit(completed ? 0 : (process.exitCode || 2));
|
|
1600
|
+
}
|
|
1601
|
+
});
|
|
1602
|
+
}
|
|
1394
1603
|
registerStartCommand(program);
|
|
1395
1604
|
registerGroundingSourcesCli(program);
|
|
1396
1605
|
registerGraphCommands(program);
|
|
@@ -1601,6 +1810,8 @@ program
|
|
|
1601
1810
|
)
|
|
1602
1811
|
// Documentation-only — `readDashboardNameFlag` 가 Commander «전»에 argv 에서 걷어낸다.
|
|
1603
1812
|
.option('--name <name>', '대시보드 TUI 의 PTY 행(tui:<pid>)에 별명을 달고 뜬다 — `elanous pty list` 에 보이고 `pty snapshot <name>` 으로 부른다. 뜬 뒤 바꾸려면 `elanous pty rename <ref> <name>`.')
|
|
1813
|
+
.option('--legacy', '기존 대시보드 TUI로 시작한다(--tui classic 의 짧은 표기). 기본 진입도 기존 대시보드이며 새 TUI는 --tui next 로만 연다.')
|
|
1814
|
+
.option('--tui <mode>', '루트 TUI를 명시한다(classic|next). 기본은 classic이고 새 TUI는 --tui next 로 연다. --legacy는 classic의 짧은 표기다.')
|
|
1604
1815
|
.option('--help-all', '시스템 명령을 제외한 모든 최상위 명령 표시');
|
|
1605
1816
|
program.addHelpText('after', acpServerHelpText());
|
|
1606
1817
|
|
|
@@ -2430,7 +2641,8 @@ async function runHarnessMissionLoop(
|
|
|
2430
2641
|
}
|
|
2431
2642
|
}
|
|
2432
2643
|
|
|
2433
|
-
const harnessCmd =
|
|
2644
|
+
const harnessCmd = (INDEX_FAST_ROOT ? new Command('harness')
|
|
2645
|
+
: (require('./harness/harness-cli-command.js') as typeof import('./harness/harness-cli-command.js')).installHarnessCliCommand(program, {
|
|
2434
2646
|
registerSink: async (surface) => { await (await import('./domains/standalone-log-sink.js')).registerStandaloneLogSink(surface); },
|
|
2435
2647
|
resolveSurface: async () => {
|
|
2436
2648
|
const { getHarnessSpace, harnessSpaceSurface } = await import('./harness/harness-space.js');
|
|
@@ -2444,9 +2656,65 @@ const harnessCmd = installHarnessCliCommand(program, {
|
|
|
2444
2656
|
// (그 함수는 planStaged dispatch → 대표 2026-09-04 은퇴한 staged 하니스로 간다).
|
|
2445
2657
|
// ⇒ 즉 이 «한 줄»이 은퇴를 되돌린다. 주입 자리는 시험용으로 남는다.
|
|
2446
2658
|
mission: async (missionId, opts) => {
|
|
2447
|
-
await dispatchSolveMission({ mission_id: missionId, ...opts });
|
|
2659
|
+
await (await import('./skills/tools/solve-mission.js')).dispatchSolveMission({ mission_id: missionId, ...opts });
|
|
2448
2660
|
},
|
|
2449
2661
|
missionLoop: runHarnessMissionLoop,
|
|
2662
|
+
}));
|
|
2663
|
+
|
|
2664
|
+
let podAskSnapshot: string | undefined;
|
|
2665
|
+
let podAskSnapshotCleanup: (() => void) | undefined;
|
|
2666
|
+
harnessCmd.hook('preAction', async (_parent, action) => {
|
|
2667
|
+
if (action.name() === 'ask' && action.opts().substrate === 'pod' && typeof action.args[0] === 'string' && !isGoalAuthorFileName(basename(action.args[0]))) {
|
|
2668
|
+
// Read the source once; onPod and its orchestrator consume the same private snapshot.
|
|
2669
|
+
const askBytes = readFileSync(action.args[0]!);
|
|
2670
|
+
const askText = askBytes.toString('utf8');
|
|
2671
|
+
if (!askText.trim()) throw new Error('--ask 파일 입력이 비었다');
|
|
2672
|
+
const { mkdtempSync, writeFileSync, rmSync } = await import('node:fs');
|
|
2673
|
+
const { tmpdir } = await import('node:os');
|
|
2674
|
+
const { join } = await import('node:path');
|
|
2675
|
+
const snapshotDir = mkdtempSync(join(tmpdir(), 'elanous-ask-snapshot-'));
|
|
2676
|
+
try {
|
|
2677
|
+
const snapshot = join(snapshotDir, basename(action.args[0]!));
|
|
2678
|
+
writeFileSync(snapshot, askBytes, { mode: 0o600 });
|
|
2679
|
+
podAskSnapshot = snapshotDir;
|
|
2680
|
+
podAskSnapshotCleanup = () => {
|
|
2681
|
+
try { rmSync(snapshotDir, { recursive: true, force: true }); }
|
|
2682
|
+
catch (error) { console.error(`[launch-utterance] snapshot cleanup failed: ${String(error)}`); }
|
|
2683
|
+
};
|
|
2684
|
+
process.once('exit', podAskSnapshotCleanup);
|
|
2685
|
+
action.processedArgs[0] = snapshot;
|
|
2686
|
+
} catch (error) {
|
|
2687
|
+
rmSync(snapshotDir, { recursive: true, force: true });
|
|
2688
|
+
throw error;
|
|
2689
|
+
}
|
|
2690
|
+
const { newLaunchUtteranceId, recordLaunchUtterance } = await import('./harness/launch-utterance-ledger.js');
|
|
2691
|
+
recordLaunchUtterance({ source: 'ask-file', utterance: askText, rawBytes: askBytes, launchId: newLaunchUtteranceId() });
|
|
2692
|
+
return;
|
|
2693
|
+
}
|
|
2694
|
+
if (action.name() !== 'say') return;
|
|
2695
|
+
try {
|
|
2696
|
+
const { consumeHandLaunchId, recordLaunchUtterance } = await import('./harness/launch-utterance-ledger.js');
|
|
2697
|
+
const argv = (action.args as string[]).map(String);
|
|
2698
|
+
if (argv.length === 0) return; // nothing was received — no empty start row
|
|
2699
|
+
// New ID per process; only the explicit hand→say pair (same sentence sha ⊕ same run) inherits, once —
|
|
2700
|
+
// and then records the hand's exact original text (recovers a failed hand-parent append in this instance).
|
|
2701
|
+
const { launchId, utterance } = consumeHandLaunchId(argv.join(' '), process.env);
|
|
2702
|
+
recordLaunchUtterance({ source: 'say', utterance, argv, launchId, dryRun: action.opts().dryRun === true });
|
|
2703
|
+
} catch (error) {
|
|
2704
|
+
try { debug.log('harness.launch-utterance', 'prepare-failed', { operation: 'say-hook', reason: String(error) }, { level: 'warn' }); } catch { /* fail-soft */ }
|
|
2705
|
+
}
|
|
2706
|
+
});
|
|
2707
|
+
harnessCmd.hook('postAction', async (_parent, action) => {
|
|
2708
|
+
if (action.name() !== 'ask' || !podAskSnapshot) return;
|
|
2709
|
+
try {
|
|
2710
|
+
const { rmSync } = await import('node:fs');
|
|
2711
|
+
rmSync(podAskSnapshot, { recursive: true, force: true });
|
|
2712
|
+
if (podAskSnapshotCleanup) process.removeListener('exit', podAskSnapshotCleanup);
|
|
2713
|
+
podAskSnapshot = undefined;
|
|
2714
|
+
podAskSnapshotCleanup = undefined;
|
|
2715
|
+
} catch (error) {
|
|
2716
|
+
console.error(`[launch-utterance] snapshot cleanup failed: ${String(error)}`);
|
|
2717
|
+
}
|
|
2450
2718
|
});
|
|
2451
2719
|
|
|
2452
2720
|
// (internal) 데몬이 dev-harness 를 subprocess 로 위임(#24 A) — 하니스 동기 op 가 데몬 이벤트루프를
|
|
@@ -2484,6 +2752,7 @@ harnessCmd
|
|
|
2484
2752
|
try { process.stdout.write(line, () => process.exit(code)); }
|
|
2485
2753
|
catch { process.exit(code); }
|
|
2486
2754
|
};
|
|
2755
|
+
const { emitDetachedProgress } = await import('./cli/agent-cli.js');
|
|
2487
2756
|
const detachedCtx = {
|
|
2488
2757
|
cwd: process.cwd(),
|
|
2489
2758
|
signal: new AbortController().signal,
|
|
@@ -3216,6 +3485,7 @@ export async function runHarnessOrchestrateExecution(
|
|
|
3216
3485
|
const { prepareOrchestrateDecomposeGoals } = await import('./self-dev/self-orchestrate-runtime.js');
|
|
3217
3486
|
return prepareOrchestrateDecomposeGoals(input as never) as Promise<HarnessOrchestratePreparedGoals>;
|
|
3218
3487
|
});
|
|
3488
|
+
const { buildOrchestrateDecomposePrepareArgs } = await import('./self-dev/self-orchestrate-runtime.js');
|
|
3219
3489
|
const prepared = await prepareGoals(buildOrchestrateDecomposePrepareArgs({
|
|
3220
3490
|
request,
|
|
3221
3491
|
goals,
|
|
@@ -4446,7 +4716,7 @@ selfCmd
|
|
|
4446
4716
|
.option('--fixed-shard-distribution', '--shards N 과 함께만: RSS 사전 측정 없이 정렬된 파일을 N 조각에 라운드로빈 고정 배정한다(opt-in · 메모리 보증 아님 · 조각 타임아웃/OOM = unmeasured)')
|
|
4447
4717
|
.option('--include-importers', '변경 모듈을 가져오는 importer 시험도 실행한다 (기본 caller 한도 밖까지)')
|
|
4448
4718
|
.option('--remote [host]', 'GATE-REMOTE — 같은 커밋을 원격 호스트(기본 config gateRemote.host=node-b)에서 돌리고 결과만 가져온다(깨끗한 트리 · --pr 은 로컬)')
|
|
4449
|
-
.option('--local', '원격
|
|
4719
|
+
.option('--local', '원격 실행을 끄고 명시적으로 로컬에서 돌린다')
|
|
4450
4720
|
.option('--artifact-dir <dir>', '조각별 지금/기준 JUnit ⊕ summary.json 을 이 디렉토리에 남긴다(판정 불변 · JUnit 은 --shards 경로만 · 원격 실행이면 그 호스트에서 가져온다)')
|
|
4451
4721
|
.action(async (opts: { changed?: boolean; base?: string; pr?: string; shards?: string | boolean; fixedShardDistribution?: boolean; includeImporters?: boolean; remote?: string | boolean; local?: boolean; artifactDir?: string }) => {
|
|
4452
4722
|
if (!opts.changed && opts.shards === undefined) { ui.error('self gate requires --changed or --shards'); process.exitCode = 2; return; }
|
|
@@ -4482,8 +4752,8 @@ selfCmd
|
|
|
4482
4752
|
if (topLevel.status !== 0) throw new Error(`git rev-parse --show-toplevel failed: ${topLevel.stderr.trim() || `rc=${topLevel.status}`}`);
|
|
4483
4753
|
const repo = topLevel.stdout.trim();
|
|
4484
4754
|
// Only a committed --base range is reproducible on another host: the default mode measures uncommitted files, --pr
|
|
4485
|
-
// reads files through gh on this host, and the remote checkout runs from the repository root —
|
|
4486
|
-
//
|
|
4755
|
+
// reads files through gh on this host, and the remote checkout runs from the repository root — these cases
|
|
4756
|
+
// fall back locally for automatic placement; an explicitly requested remote run is unmeasured.
|
|
4487
4757
|
const { realpathSync } = await import('node:fs');
|
|
4488
4758
|
const localOnlyReason = opts.pr ? 'self gate --pr reads PR files through gh on this host'
|
|
4489
4759
|
: !opts.base ? 'self gate without --base measures uncommitted files on this host'
|
|
@@ -4516,7 +4786,7 @@ selfCmd
|
|
|
4516
4786
|
if (outcome.kind === 'ran') {
|
|
4517
4787
|
target.fetch = fetchRemoteGateArtifacts({ host, remoteDir: target.dir, localDir: resolveArtifactDir(opts.artifactDir!, process.cwd()), ssh: runner.ssh });
|
|
4518
4788
|
} else if (outcome.kind === 'infra') {
|
|
4519
|
-
// The run may have started before it broke — remove the host-side dir;
|
|
4789
|
+
// The run may have started before it broke — remove the host-side dir; remote failure stays unmeasured.
|
|
4520
4790
|
try { runner.ssh(host, remoteArtifactCleanupScript(target.dir), 30_000); } catch { /* best effort */ }
|
|
4521
4791
|
}
|
|
4522
4792
|
}) satisfies NonNullable<import('./self-implement/gate-remote.js').DispatchOptions['onRemoteOutcome']>,
|
|
@@ -4524,12 +4794,14 @@ selfCmd
|
|
|
4524
4794
|
});
|
|
4525
4795
|
} catch (error) {
|
|
4526
4796
|
const reason = error instanceof Error ? error.message : String(error);
|
|
4527
|
-
if (opts.
|
|
4528
|
-
ui.error(`self gate remote unmeasured — ${reason.replace(/\s+/g, ' ').trim()}`);
|
|
4529
|
-
process.exitCode = 1;
|
|
4530
|
-
} else {
|
|
4797
|
+
if (opts.local) {
|
|
4531
4798
|
ui.error(`self gate dispatch failed: ${reason}`);
|
|
4532
4799
|
process.exitCode = runLocal();
|
|
4800
|
+
} else {
|
|
4801
|
+
ui.error(opts.remote !== undefined
|
|
4802
|
+
? `self gate remote unmeasured — ${reason.replace(/\s+/g, ' ').trim()}`
|
|
4803
|
+
: `self gate dispatch failed: ${reason}`);
|
|
4804
|
+
process.exitCode = 1;
|
|
4533
4805
|
}
|
|
4534
4806
|
}
|
|
4535
4807
|
// 원격에서 돌았으면 그 호스트의 산출을 가져와 같은 꼴로 썼다 — 못 가져왔으면 «조용히» 비우지 않고 summary 에 이유를 적는다(판정 불변).
|
|
@@ -4756,7 +5028,7 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4756
5028
|
.option('--no-pod-rebuild', 'pod: 이미지 판(elanous.commit)이 HEAD 와 달라도 다시 굽지 않는다 — 측정은 «이미지 판»을 잰다')
|
|
4757
5029
|
.option('--pod-pass-env <keys>', 'pod: 호스트 env 에서 Pod 로 넘길 키(쉼표) — 예 OPENROUTER_API_KEY,ANTHROPIC_API_KEY(벤치마크 과금 경로)')
|
|
4758
5030
|
.option('--bench-arms <spec>', 'pod 벤치마크: 골 1개를 팔마다 «라벨 한 줄만 다르게» 복제해 동시에 — "id=provider[:model][@KEY+KEY];…" (예 codex=openai-codex;or-kimi=openrouter:openrouter/moonshotai/kimi-k3@OPENROUTER_API_KEY) · --auto-merge 거부 · RFC fleet 슈퍼바이저 §A3')
|
|
4759
|
-
.addOption(new Option('--child-llm-provider <id>', 'pod: 구현 자식 LLM provider(openai-codex|grok|openrouter|anthropic|bedrock|glm) — 하니스 --child-llm-provider 가 이 자리로 온다(10-05)').hideHelp())
|
|
5031
|
+
.addOption(new Option('--child-llm-provider <id>', 'pod: 구현 자식 LLM provider(openai-codex|grok|openrouter|opengateway|anthropic|bedrock|glm) — 하니스 --child-llm-provider 가 이 자리로 온다(10-05)').hideHelp())
|
|
4760
5032
|
.addOption(new Option('--child-llm-model <id>', 'pod: 구현 자식 LLM model(--child-llm-provider 와 함께)').hideHelp())
|
|
4761
5033
|
.addOption(new Option('--child-llm-effort <level>', 'pod: 구현 자식 추론 노력(--child-llm-provider 와 함께)').hideHelp())
|
|
4762
5034
|
.option('--help-all', '모든 orchestrate 옵션 표시')
|
|
@@ -4834,7 +5106,7 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4834
5106
|
let parentRequest: string | undefined;
|
|
4835
5107
|
const request = normalizeOrchestrateRequest(joined);
|
|
4836
5108
|
if (opts.decompose) parentRequest = request;
|
|
4837
|
-
const { prepareOrchestrateDecomposeGoals } = await import('./self-dev/self-orchestrate-runtime.js');
|
|
5109
|
+
const { prepareOrchestrateDecomposeGoals, buildOrchestrateDecomposePrepareArgs } = await import('./self-dev/self-orchestrate-runtime.js');
|
|
4838
5110
|
const prepared = await prepareOrchestrateDecomposeGoals(buildOrchestrateDecomposePrepareArgs({
|
|
4839
5111
|
request,
|
|
4840
5112
|
goals: goalTexts.map((feature) => ({ feature, ...promoteDefaults })),
|
|
@@ -4939,7 +5211,7 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4939
5211
|
let podSpawn: import('./task-orchestrator/surfaces/self-implement.js').SelfImplementJobSpawn | undefined;
|
|
4940
5212
|
let podTargets: { context: string; namespace: string }[] | undefined;
|
|
4941
5213
|
if (substrate === 'pod') {
|
|
4942
|
-
const {
|
|
5214
|
+
const { podSubstrateReady, defaultKubectl } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
|
|
4943
5215
|
const poolMod = await import('./task-orchestrator/surfaces/pod-pool.js');
|
|
4944
5216
|
const { harnessLaunchPolicyConfig } = await import('./harness/harness-substrate-default.js');
|
|
4945
5217
|
const launchPolicy = harnessLaunchPolicyConfig();
|
|
@@ -5046,11 +5318,24 @@ const selfOrchestrateCmd = selfCmd
|
|
|
5046
5318
|
const grokKeyNames = ['XAI_API_KEY', 'GROK_API_KEY', 'GROK_CODE_XAI_API_KEY'];
|
|
5047
5319
|
// 명시 계정은 사람의 선택 — 공급자 폴백과 계정 브로커를 우회한다.
|
|
5048
5320
|
const explicitPodAccount = (opts as { podAccount?: string }).podAccount;
|
|
5049
|
-
const
|
|
5321
|
+
const ownerMirrorRaw = process.env.ELANOUS_REMOTE_CODEX_ACCOUNTS;
|
|
5322
|
+
let ownerMirrorAccounts: import('./task-orchestrator/surfaces/pod-account-broker.js').OwnerCodexMirrorAccount[] | undefined;
|
|
5323
|
+
if (ownerMirrorRaw !== undefined) {
|
|
5324
|
+
try { ownerMirrorAccounts = (await import('./task-orchestrator/surfaces/pod-account-broker.js')).parseOwnerCodexMirrorAccounts(ownerMirrorRaw); }
|
|
5325
|
+
catch { ui.error('pod: HQ Codex 미러 계정 목록이 유효하지 않다'); process.exit(2); }
|
|
5326
|
+
const { freshOwnerCodexMirrorAccounts } = await import('./task-orchestrator/surfaces/pod-account-broker.js');
|
|
5327
|
+
const fresh = freshOwnerCodexMirrorAccounts(ownerMirrorAccounts);
|
|
5328
|
+
for (const { account } of ownerMirrorAccounts.filter(({ account }) => !fresh.some((item) => item.account === account))) {
|
|
5329
|
+
debug.log('self-implement.pod', 'owner-access-mirror-excluded', { account, reason: 'access-expiring' });
|
|
5330
|
+
}
|
|
5331
|
+
ownerMirrorAccounts = fresh;
|
|
5332
|
+
if (fresh.length === 0) { ui.error('pod: HQ Codex 미러 access token 이 모두 3시간 안에 만료된다'); process.exit(2); }
|
|
5333
|
+
}
|
|
5334
|
+
const ownerMirrorAccount = ownerMirrorAccounts?.[0]?.account ?? process.env.ELANOUS_REMOTE_CODEX_ACCOUNT?.trim();
|
|
5050
5335
|
const childProvider = opts as { childLlmProvider?: string };
|
|
5051
5336
|
const requestedChildProvider = childProvider.childLlmProvider?.trim();
|
|
5052
|
-
if (ownerMirrorAccount && explicitPodAccount && explicitPodAccount
|
|
5053
|
-
ui.error(`pod: HQ 미러
|
|
5337
|
+
if (ownerMirrorAccount && explicitPodAccount && !(ownerMirrorAccounts?.some(({ account }) => account === explicitPodAccount) ?? explicitPodAccount === ownerMirrorAccount)) {
|
|
5338
|
+
ui.error(`pod: HQ 미러 계정 목록에 --pod-account ${explicitPodAccount} 이 없다`);
|
|
5054
5339
|
process.exit(2);
|
|
5055
5340
|
}
|
|
5056
5341
|
if (ownerMirrorAccount && requestedChildProvider && requestedChildProvider !== 'openai-codex') {
|
|
@@ -5101,7 +5386,7 @@ const selfOrchestrateCmd = selfCmd
|
|
|
5101
5386
|
? 'pod: --child-llm-model/--child-llm-effort 는 --child-llm-provider 와 함께'
|
|
5102
5387
|
: named && benchArms
|
|
5103
5388
|
? 'pod: --child-llm-provider 는 --bench-arms 와 함께 못 쓴다(팔마다 모델이 하나다)'
|
|
5104
|
-
: (named === 'grok' || named === 'openrouter' || named === 'anthropic' || named === 'bedrock' || named === 'glm') && explicitPodAccount
|
|
5389
|
+
: (named === 'grok' || named === 'openrouter' || named === 'opengateway' || named === 'anthropic' || named === 'bedrock' || named === 'glm') && explicitPodAccount
|
|
5105
5390
|
? `pod: --child-llm-provider ${named} 은 --pod-account 와 함께 못 쓴다(그것은 codex 계정을 고정한다)`
|
|
5106
5391
|
: undefined;
|
|
5107
5392
|
if (refuse) { ui.error(refuse); debug.log('self-implement.pod', 'child-provider-refused', { provider: named ?? null, reason: refuse }); process.exit(2); }
|
|
@@ -5163,19 +5448,27 @@ const selfOrchestrateCmd = selfCmd
|
|
|
5163
5448
|
if (namedChild === 'openrouter' && !openrouterKeyPresent) {
|
|
5164
5449
|
try { openrouterKeyPresent = Boolean(readPodKeyFile(podJoin(podHome(), '.cache', 'openrouter_api_key'), 'utf8').trim()); } catch { /* missing host cache */ }
|
|
5165
5450
|
}
|
|
5451
|
+
const openGatewayKeyPresent = namedChild === 'opengateway' && Boolean(
|
|
5452
|
+
(await import('./config.js')).getOpenGatewayApiKey()?.trim()
|
|
5453
|
+
|| configuredOpenGatewayKeys(getUserConfig().llm).length);
|
|
5166
5454
|
// POD-ANTHROPIC-PROVIDER — 제품 자격 해석(`getAnthropicApiKey` · 키 캐시 → env)으로 «있나»만 본다(값은 안 싣는다).
|
|
5167
5455
|
const anthropicKeyPresent = namedChild === 'anthropic' && Boolean((await import('./config.js')).getAnthropicApiKey()?.trim());
|
|
5168
5456
|
const namedChildDecision = podNamedChildProvider(namedChild, {
|
|
5169
5457
|
grokSubscription: namedChild === 'grok' && credential?.kind === 'subscription' && (grokSubscriptionUsable || namedGrokUsable().usable),
|
|
5170
5458
|
grokApiKey: credential?.kind === 'api_key' && grokApiKeyOptIn,
|
|
5171
5459
|
openrouterKey: openrouterKeyPresent,
|
|
5460
|
+
openGatewayKey: openGatewayKeyPresent,
|
|
5172
5461
|
anthropicKey: anthropicKeyPresent,
|
|
5173
5462
|
}, (opts as { childLlmModel?: string }).childLlmModel);
|
|
5174
5463
|
if (namedChildDecision.refuse) { ui.error(namedChildDecision.refuse); debug.log('self-implement.pod', 'child-provider-refused', { provider: namedChild, reason: namedChildDecision.refuse }); process.exit(2); }
|
|
5175
5464
|
// A named codex child must stay codex — the plan may not fall back to grok (post-review must-fix).
|
|
5176
5465
|
const namedCodex = namedChildDecision.provider === 'openai-codex';
|
|
5177
5466
|
let planCandidates = inspectCodexRotation().candidates;
|
|
5178
|
-
if (
|
|
5467
|
+
if (ownerMirrorAccounts) {
|
|
5468
|
+
const { selectOwnerCodexMirrorCandidates } = await import('./task-orchestrator/surfaces/pod-account-broker.js');
|
|
5469
|
+
try { planCandidates = selectOwnerCodexMirrorCandidates(planCandidates, ownerMirrorAccounts); }
|
|
5470
|
+
catch { ui.error('pod: HQ Codex 미러 계정 일부가 원격 auth-store 후보에 없다'); process.exit(2); }
|
|
5471
|
+
} else if (ownerMirrorAccount) {
|
|
5179
5472
|
const used = process.env.ELANOUS_REMOTE_CODEX_USED_PERCENT;
|
|
5180
5473
|
const parsedUsed = used && used !== 'unknown' ? Number(used) : undefined;
|
|
5181
5474
|
const threshold = Number(process.env.ELANOUS_REMOTE_CODEX_THRESHOLD_PERCENT);
|
|
@@ -5187,12 +5480,14 @@ const selfOrchestrateCmd = selfCmd
|
|
|
5187
5480
|
planCandidates = ownerCodexMirrorCandidate(planCandidates, ownerMirrorAccount, parsedUsed !== undefined && Number.isFinite(parsedUsed) ? parsedUsed : undefined);
|
|
5188
5481
|
if (planCandidates.length === 0) { ui.error(`pod: HQ Codex 미러 계정 ${ownerMirrorAccount} 이 원격 auth-store 후보에 없다`); process.exit(2); }
|
|
5189
5482
|
}
|
|
5190
|
-
const plan: import('./task-orchestrator/surfaces/pod-account-broker.js').PodProviderPlan | null = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? null : namedChildDecision.provider === 'grok'
|
|
5483
|
+
const plan: import('./task-orchestrator/surfaces/pod-account-broker.js').PodProviderPlan | null = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'opengateway' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? null : namedChildDecision.provider === 'grok'
|
|
5191
5484
|
? { provider: 'grok', excluded: [], grokSubscriptionEligible: credential?.kind === 'subscription' }
|
|
5192
5485
|
: planPodProvider({
|
|
5193
5486
|
codexCandidates: planCandidates,
|
|
5194
5487
|
// Per-account caps (대표 default:97) override the Pod default cap — without them default was dropped at 60%.
|
|
5195
|
-
thresholdPercentByAccount:
|
|
5488
|
+
thresholdPercentByAccount: ownerMirrorAccounts
|
|
5489
|
+
? Object.fromEntries(ownerMirrorAccounts.map(({ account, thresholdPercent }) => [account, thresholdPercent]))
|
|
5490
|
+
: ownerMirrorAccount
|
|
5196
5491
|
? { [ownerMirrorAccount]: Number(process.env.ELANOUS_REMOTE_CODEX_THRESHOLD_PERCENT) }
|
|
5197
5492
|
: launchPolicy.llm?.codexAccountRotationThresholdPercentByAccount,
|
|
5198
5493
|
// 대표 한도 정책 한 값(`llm.codexQuotaPolicy`) — 크레딧·폴백을 같이 정한다.
|
|
@@ -5213,7 +5508,7 @@ const selfOrchestrateCmd = selfCmd
|
|
|
5213
5508
|
})() } : {}),
|
|
5214
5509
|
});
|
|
5215
5510
|
if (plan?.provider === null) { ui.error(`pod: 쓸 codex 계정이 없다 — ${plan.reasons.join(' · ')}${namedCodex ? ' · child provider 를 openai-codex 로 지정해 grok 으로 넘기지 않는다' : ''} · 계정을 명시하려면 --pod-account <이름>`); process.exit(2); }
|
|
5216
|
-
podProvider = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? namedChildDecision.provider : plan!.provider!;
|
|
5511
|
+
podProvider = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'opengateway' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? namedChildDecision.provider : plan!.provider!;
|
|
5217
5512
|
if (plan?.provider === 'openai-codex') {
|
|
5218
5513
|
accountBroker = makePodAccountBroker({ usable: plan.accounts, excluded: plan.excluded });
|
|
5219
5514
|
rotationAccounts = plan.accounts;
|
|
@@ -5226,6 +5521,10 @@ const selfOrchestrateCmd = selfCmd
|
|
|
5226
5521
|
const model = (opts as { childLlmModel?: string }).childLlmModel!.trim();
|
|
5227
5522
|
debug.log('self-implement.pod', 'provider-named', { provider: 'openrouter', model, openrouterKeyPresent: true });
|
|
5228
5523
|
if (!opts.json) ui.info(`[pod] child provider = openrouter(모델 ${model}) — 발사 인자로 지정됨`);
|
|
5524
|
+
} else if (namedChildDecision.provider === 'opengateway') {
|
|
5525
|
+
const model = (opts as { childLlmModel?: string }).childLlmModel!.trim();
|
|
5526
|
+
debug.log('self-implement.pod', 'provider-named', { provider: 'opengateway', model, openGatewayKeyPresent: true, billing: 'api-key' });
|
|
5527
|
+
if (!opts.json) ui.info(`[pod] child provider = opengateway(모델 ${model}) — 발사 인자로 지정됨 · API 키 과금`);
|
|
5229
5528
|
} else if (namedChildDecision.provider === 'anthropic') {
|
|
5230
5529
|
const model = (opts as { childLlmModel?: string }).childLlmModel?.trim() || null;
|
|
5231
5530
|
// ⓔ 과금 관측 — anthropic 은 API 키 과금(구독 아님). 새 예산 체계는 없다 · 관측 한 줄만.
|
|
@@ -5254,7 +5553,7 @@ const selfOrchestrateCmd = selfCmd
|
|
|
5254
5553
|
if (!opts.json) ui.info(`[pod] 쓸 codex 계정 없음(${plan.excluded.map((x) => `${x.name}: ${x.why}`).join(' · ')}) → grok 으로(모델 ${model})`);
|
|
5255
5554
|
}
|
|
5256
5555
|
}
|
|
5257
|
-
const passEnv = podProvider === 'grok' ? requestedPassEnv.filter((key) => !grokKeyNames.includes(key)) : podProvider === 'openrouter' ? [...new Set([...requestedPassEnv, 'OPENROUTER_API_KEY'])] : podProvider === 'anthropic' ? [...new Set([...requestedPassEnv, 'ANTHROPIC_API_KEY'])] : requestedPassEnv;
|
|
5556
|
+
const passEnv = podProvider === 'grok' ? requestedPassEnv.filter((key) => !grokKeyNames.includes(key)) : podProvider === 'openrouter' ? [...new Set([...requestedPassEnv, 'OPENROUTER_API_KEY'])] : podProvider === 'opengateway' ? [...new Set([...requestedPassEnv, 'OPENGATEWAY_API_KEY'])] : podProvider === 'anthropic' ? [...new Set([...requestedPassEnv, 'ANTHROPIC_API_KEY'])] : requestedPassEnv;
|
|
5258
5557
|
const podSourceSpec = (opts as { podSource?: string }).podSource;
|
|
5259
5558
|
const repairBaseHead = (opts as { repairCommitOnly?: string }).repairCommitOnly;
|
|
5260
5559
|
if (repairBaseHead && (!/^pr:[1-9]\d*$/.test(podSourceSpec ?? '') || !/^[0-9a-f]{40}$/.test(repairBaseHead) || opts.autoMerge || opts.openPr || goalTexts.length !== 1)) {
|
|
@@ -5287,7 +5586,8 @@ const selfOrchestrateCmd = selfCmd
|
|
|
5287
5586
|
const { benchPodSpawn } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
|
|
5288
5587
|
podSpawn = benchPodSpawn(benchArms, podBase);
|
|
5289
5588
|
} else {
|
|
5290
|
-
podSpawn =
|
|
5589
|
+
podSpawn = await (await import('./task-orchestrator/surfaces/pod-si-warm-entry.js'))
|
|
5590
|
+
.podSpawnWithSiWarm(podBase);
|
|
5291
5591
|
}
|
|
5292
5592
|
podTargets = poolMembers.length > 0
|
|
5293
5593
|
? poolMembers.map(({ context }) => ({ context, namespace: 'elanous-test' }))
|
|
@@ -5561,9 +5861,37 @@ selfCmd
|
|
|
5561
5861
|
.option('--include-stale', '모호한 대상 목록에 오래된 마지막 프레임 후보도 표시')
|
|
5562
5862
|
.option('--read-wait <seconds>', '--memo·--stop 뒤 자식이 읽을 때까지 기다리는 최대 초(0 = 기다리지 않음)', '10')
|
|
5563
5863
|
.action(async (space: string | undefined, opts: { stop?: boolean; memo?: string; run?: string; includeStale?: boolean; readWait?: string }) => {
|
|
5864
|
+
let remoteLookupFailure = '';
|
|
5865
|
+
let remoteChildUnconfirmed = false;
|
|
5866
|
+
// A TA parent lives on its recorded host. Its Pod fragment and control inbox are
|
|
5867
|
+
// deliberately absent from HQ state, so a local screen lookup cannot route it.
|
|
5868
|
+
if (opts.run !== undefined && space === undefined && mayLookupRemotePodRun(process.env)) {
|
|
5869
|
+
const { findRemotePodCardForRun, remotePodControlForOptions, RemotePodOwnershipAmbiguousError, sendRemotePodRun } = await import('./harness/self-send-remote.js');
|
|
5870
|
+
let card: ReturnType<typeof findRemotePodCardForRun>['card'] = null;
|
|
5871
|
+
try {
|
|
5872
|
+
({ card, remoteChildUnconfirmed } = findRemotePodCardForRun(opts.run));
|
|
5873
|
+
} catch (error) {
|
|
5874
|
+
if (error instanceof RemotePodOwnershipAmbiguousError) {
|
|
5875
|
+
process.stderr.write(`${error.message}\n`);
|
|
5876
|
+
process.exit(1);
|
|
5877
|
+
}
|
|
5878
|
+
remoteLookupFailure = error instanceof Error ? error.message : String(error);
|
|
5879
|
+
}
|
|
5880
|
+
if (card) {
|
|
5881
|
+
try {
|
|
5882
|
+
const result = sendRemotePodRun(card, opts.run, remotePodControlForOptions(opts));
|
|
5883
|
+
if (result.stderr) process.stderr.write(result.stderr);
|
|
5884
|
+
process.stdout.write(result.stdout);
|
|
5885
|
+
return;
|
|
5886
|
+
} catch (error) {
|
|
5887
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
5888
|
+
process.exit(1);
|
|
5889
|
+
}
|
|
5890
|
+
}
|
|
5891
|
+
}
|
|
5564
5892
|
const { classifyRunScreenMissing, queryRunScreenKey, listRunLedgers } = await import('./self-implement/run-ledger.js');
|
|
5565
5893
|
const { getPtyManifest, listPtyManifestRows } = await import('./pty-shell/pty-manifest.js');
|
|
5566
|
-
const { readPodFragment, podFragmentFinished, listPodFragmentsForRun, dispatchPodSelfSend } = await import('./harness/self-send-target.js');
|
|
5894
|
+
const { readPodFragment, podFragmentFinished, listPodFragmentsForRun, dispatchPodSelfSend, resolveSelfSendTarget } = await import('./harness/self-send-target.js');
|
|
5567
5895
|
const { listHarnessScreens, readHarnessHeartbeat } = await import('./harness/harness-screen.js');
|
|
5568
5896
|
const decision = decideSelfSend({ space, opts, now: Date.now() }, {
|
|
5569
5897
|
resolveRunScreen: (runId) => {
|
|
@@ -5594,6 +5922,8 @@ selfCmd
|
|
|
5594
5922
|
});
|
|
5595
5923
|
if (decision.kind === 'refuse') {
|
|
5596
5924
|
process.stderr.write(decision.message);
|
|
5925
|
+
if (remoteLookupFailure) process.stderr.write(`원격 TA 카드 조회 실패: ${remoteLookupFailure}\n`);
|
|
5926
|
+
else if (remoteChildUnconfirmed) process.stderr.write(`원격 Pod 자식 소유 미확인: ${opts.run}의 카드 연결은 HQ 미러에서 확인되지 않았습니다. 활성 원격 카드 하나에 자식 ID가 없으므로 그 카드의 부모 runId 또는 미러 동기화를 확인하세요.\n`);
|
|
5597
5927
|
process.exit(decision.exitCode);
|
|
5598
5928
|
}
|
|
5599
5929
|
const target = decision.spaceId;
|
|
@@ -5604,9 +5934,18 @@ selfCmd
|
|
|
5604
5934
|
if (hasMemo) {
|
|
5605
5935
|
if (!opts.memo || /[\r\n]/.test(opts.memo)) throw new Error('control inbox memo must be a non-empty single line');
|
|
5606
5936
|
const urgent = opts.memo.startsWith('[urgent] ');
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5937
|
+
const { parsePodReadWait } = await import('./harness/pod-control-send.js');
|
|
5938
|
+
const boundedWait = parsePodReadWait(opts.readWait ?? '10');
|
|
5939
|
+
const receipt = dispatchPodSelfSend(target, { memo: { version: 1, kind: 'supervisor', urgency: urgent ? 'urgent' : 'normal', body: urgent ? opts.memo.slice('[urgent] '.length) : opts.memo } }, undefined, undefined, boundedWait);
|
|
5940
|
+
if (!receipt) throw new Error(`self send 대상 Pod 조각 기록 없음: ${target}`);
|
|
5941
|
+
ui.info(`Pod 조각에 감독 메모 기록: ${target} (${record?.job ?? 'finished'})`);
|
|
5942
|
+
ui.info(receipt?.memoRecord
|
|
5943
|
+
? `${receipt.read ? '자식이 메모 기록을 수거함' : boundedWait > 0 ? '대기 중 읽음 미관측' : '읽음 미관측 (대기 0초)'}: ${receipt.memoRecord}`
|
|
5944
|
+
: 'Pod 메모 전송 확인 · 읽음 미관측 (원격 응답에 record id 없음)');
|
|
5945
|
+
} else {
|
|
5946
|
+
if (!dispatchPodSelfSend(target, { stop: true })) throw new Error(`self send 대상 Pod 조각 기록 없음: ${target}`);
|
|
5947
|
+
ui.info(`Pod 조각에 soft stop 기록: ${target} (${record?.job ?? 'finished'})`);
|
|
5948
|
+
}
|
|
5610
5949
|
return;
|
|
5611
5950
|
} catch (error) {
|
|
5612
5951
|
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
@@ -5892,7 +6231,7 @@ selfCmd
|
|
|
5892
6231
|
.option('--acp', '⭐ ACP(독립 프로세스)로 리뷰 — API 대신 선택한 ACP 백엔드로 독립 리뷰')
|
|
5893
6232
|
.option('--acp-model <alias>', 'ACP 모델 tier (지정 시 고정, 생략 시 선택한 백엔드 기본값)')
|
|
5894
6233
|
.option('--acp-backend <id>', 'ACP 백엔드 id (기본: 설정 acp.reviewBackend, 없으면 공유 기본값)')
|
|
5895
|
-
.option('--acp-timeout <sec>', 'ACP 리뷰 1턴 최대 대기 초(초과 시 cancel·기본 300)'
|
|
6234
|
+
.option('--acp-timeout <sec>', 'ACP 리뷰 1턴 최대 대기 초(초과 시 cancel·기본 claude 600 · 그 외 300)')
|
|
5896
6235
|
.option('--context <path>', '리뷰어가 함께 판단할 레포 상대 파일 경로(반복 가능)', (value: string, previous: string[] = []) => [...previous, value])
|
|
5897
6236
|
.option('--context-text <text>', '리뷰어가 함께 판단할 텍스트(반복 가능)', (value: string, previous: string[] = []) => [...previous, value])
|
|
5898
6237
|
.option('--json', '구조화 출력 {pr, verdict, mustFix, shouldFix, reviewed}')
|
|
@@ -5908,10 +6247,10 @@ selfCmd
|
|
|
5908
6247
|
const { spawnSync } = await import('node:child_process');
|
|
5909
6248
|
const { reviewPullRequest, renderReview } = await import('./agent-substrate/pr-reviewer.js');
|
|
5910
6249
|
const { createRepositoryReferencedFileReader } = await import('./self-implement/goal-file-reader.js');
|
|
5911
|
-
const { streamLLM, getProvider } = await import('./llm.js');
|
|
6250
|
+
const { streamLLM, getProvider, getProviderForConfig } = await import('./llm.js');
|
|
5912
6251
|
const { registerStandaloneLogSink } = await import('./domains/standalone-log-sink.js');
|
|
5913
6252
|
const { debug } = await import('./debug/log.js');
|
|
5914
|
-
const { runSelfReviewCliCommand, reviewerContextArgs, selfReviewJsonLine } = await import('./agent-substrate/self-review-cli.js');
|
|
6253
|
+
const { apiReviewModelFromRoleSpec, runSelfReviewCliCommand, reviewerContextArgs, selfReviewJsonLine } = await import('./agent-substrate/self-review-cli.js');
|
|
5915
6254
|
const { subscriptionReviewerAvailability } = await import('./self-dev/review-provider-fallback.js');
|
|
5916
6255
|
const { makeLazyAcpReviewLLM: makeRoleAcpReviewLLM } = await import('./agent-substrate/acp-reviewer.js');
|
|
5917
6256
|
const { getOpenRouterApiKey: getOpenRouterApiKeyForReview } = await import('./config.js');
|
|
@@ -5922,8 +6261,12 @@ selfCmd
|
|
|
5922
6261
|
// The seam decides whether it applies (only without an explicit reviewer flag).
|
|
5923
6262
|
const { loadLlmPolicy, resolveSubscriptionReviewer } = await import('./policy/llm-policy.js');
|
|
5924
6263
|
const roleReviewerSelection = resolveSubscriptionReviewer(loadLlmPolicy(), getUserConfig().roleLlm);
|
|
6264
|
+
const reviewRoleSpec = getUserConfig().roleLlm?.review;
|
|
6265
|
+
const configuredReviewModel = apiReviewModelFromRoleSpec(reviewRoleSpec);
|
|
5925
6266
|
const { results, failed } = await runSelfReviewCliCommand(prArgs, {
|
|
5926
6267
|
...opts,
|
|
6268
|
+
...(configuredReviewModel ? { configuredReviewModel } : {}),
|
|
6269
|
+
...(configuredReviewModel && reviewRoleSpec?.provider ? { configuredReviewProvider: reviewRoleSpec.provider } : {}),
|
|
5927
6270
|
...(configuredAcpBackend ? { configuredAcpBackend } : {}),
|
|
5928
6271
|
...(roleReviewerSelection ? { roleReviewer: roleReviewerSelection.spec } : {}),
|
|
5929
6272
|
...(contextOrder.length > 0 ? { contextOrder } : {}),
|
|
@@ -5947,15 +6290,29 @@ selfCmd
|
|
|
5947
6290
|
// 명시 `--model` 이면 provider 를 그 모델의 것으로 «고정»한다 — 라우터 폴백(grok 등)으로 조용히 넘어가지 않고 오류로 낸다.
|
|
5948
6291
|
makeApiLlm: (model, o) => {
|
|
5949
6292
|
const effort = reviewReasoningEffort(resolveRoleLlm('review'));
|
|
5950
|
-
return (prompt: string) =>
|
|
5951
|
-
|
|
6293
|
+
return (prompt: string) => {
|
|
6294
|
+
let configuredProvider;
|
|
6295
|
+
if (o?.providerName) {
|
|
6296
|
+
try {
|
|
6297
|
+
const config = getUserConfig();
|
|
6298
|
+
configuredProvider = getProviderForConfig({ ...config, llm: { ...config.llm, provider: o.providerName } }, model);
|
|
6299
|
+
} catch (error) {
|
|
6300
|
+
debug.log('self-review', 'role-review-config-provider-error', {
|
|
6301
|
+
provider: o.providerName, model, source: 'roleLlm.review',
|
|
6302
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
6303
|
+
}, { level: 'error' });
|
|
6304
|
+
throw error;
|
|
6305
|
+
}
|
|
6306
|
+
}
|
|
6307
|
+
return streamLLM([{ role: 'user', content: prompt }], () => {}, {
|
|
5952
6308
|
model,
|
|
5953
6309
|
// ⛔ 어댑터 기본 2048 은 리뷰 응답을 자른다(VERDICT/MUST-FIX 줄이 잘리면 reviewed=false 로 접힌다).
|
|
5954
6310
|
maxTokens: 16_000,
|
|
5955
|
-
...(o?.pinProvider ? { provider: getProvider(model) } : {}),
|
|
6311
|
+
...(configuredProvider ? { provider: configuredProvider } : o?.pinProvider ? { provider: getProvider(model) } : {}),
|
|
5956
6312
|
...(o?.onResolved ? { onResolvedProvider: o.onResolved } : {}),
|
|
5957
6313
|
...(effort ? { reasoningEffort: effort } : {}),
|
|
5958
6314
|
});
|
|
6315
|
+
};
|
|
5959
6316
|
},
|
|
5960
6317
|
makeAcpLlm: (o) => {
|
|
5961
6318
|
// ⚠️ 동기 팩토리라 여기서 동적 import 를 쓸 수 없다 — 지연 로드해 첫 호출에 붙인다.
|
|
@@ -6508,7 +6865,8 @@ program.command('env').description('환경 감지')
|
|
|
6508
6865
|
// src/agent-mission/·관측 카테고리 agent-mission·U1 핸드오프 용어와 정합) — 최상위 `agent`(single-turn
|
|
6509
6866
|
// chat-with-tools)가 이미 점유해 충돌하므로 그 이름은 못 쓴다. 기존 cron/스크립트(`elanous codex review-watch`
|
|
6510
6867
|
// 등)는 commander alias 로 그대로 resolvable(하위호환 불변). 상태경로 codex-mission 은 별도로 보존(아래 락/DB).
|
|
6511
|
-
const agentBackendHelpNames =
|
|
6868
|
+
const agentBackendHelpNames = INDEX_FAST_ROOT ? []
|
|
6869
|
+
: (require('./agent-mission/driver.js') as typeof import('./agent-mission/driver.js')).agentBackendNames();
|
|
6512
6870
|
const agentBackendHelpList = agentBackendHelpNames.map((name, index) => index === 0 ? `${name}[디폴트]` : name).join('·');
|
|
6513
6871
|
const agentCmd = program
|
|
6514
6872
|
.command('agent-mission')
|
|
@@ -6896,7 +7254,7 @@ agentCmd
|
|
|
6896
7254
|
let initialReviewer: ((pr: string) => Promise<{ verdict: import('./agent-mission/review-loop.js').ReviewVerdict; asks: string[] } | null>) | undefined;
|
|
6897
7255
|
if (opts.autoInitialReview === true && opts.dryRun !== true) {
|
|
6898
7256
|
const { reviewDiffBudgetObservation, reviewPullRequest } = await import('./agent-substrate/pr-reviewer.js');
|
|
6899
|
-
const { makeAcpReviewLLM } = await import('./agent-substrate/acp-reviewer.js');
|
|
7257
|
+
const { makeAcpReviewLLM, DEFAULT_REVIEW_BACKEND } = await import('./agent-substrate/acp-reviewer.js');
|
|
6900
7258
|
const { mapReviewToInjected } = await import('./agent-mission/pr-review-watch.js');
|
|
6901
7259
|
const { execFileSync } = await import('node:child_process');
|
|
6902
7260
|
const { lookupPrGoalAcceptance } = await import('./self-implement/run-ledger.js');
|
|
@@ -6958,6 +7316,7 @@ agentCmd
|
|
|
6958
7316
|
.command('setup')
|
|
6959
7317
|
.description('One command: OAuth / API-key auth + model picker + save config')
|
|
6960
7318
|
.action(async () => {
|
|
7319
|
+
const { realIO } = await import('./onboarding.js');
|
|
6961
7320
|
const io = realIO();
|
|
6962
7321
|
try {
|
|
6963
7322
|
await runCodexSetup({ io });
|
|
@@ -7758,7 +8117,7 @@ const selfDevCmd = program
|
|
|
7758
8117
|
humanReadableOutput: !opts.json,
|
|
7759
8118
|
gitResidueSnapshot: { path: gitResiduePath, observation: gitResidue },
|
|
7760
8119
|
}, {
|
|
7761
|
-
runChatTurn: (text, chat) => runChatTurnCli({
|
|
8120
|
+
runChatTurn: async (text, chat) => (await import('./cli/agent-cli.js')).runChatTurnCli({
|
|
7762
8121
|
cfg: reloadUserConfig(),
|
|
7763
8122
|
userText: text,
|
|
7764
8123
|
explicitSessionId: chat.session,
|
|
@@ -8089,7 +8448,9 @@ configCmd
|
|
|
8089
8448
|
}
|
|
8090
8449
|
// IMAGE-LEDGER-TAGS: the baseline pin (the rail sets it through this command) goes into the image ledger.
|
|
8091
8450
|
if (recordImagePinFromConfigSet(path, parsed) === 'recorded') ui.info(`image ledger: baseline ${String(parsed).slice(0, 12)} · keep=pin`);
|
|
8092
|
-
|
|
8451
|
+
// CFG-STORE2-HISTORY-REVERT — set 줄도 «가림 자»를 지난다: 비밀 경로·비밀 모양 값은 MASK(원문 미노출).
|
|
8452
|
+
// 비밀이 아닌 값의 출력은 종전 그대로(JSON.stringify(parsed) == JSON.stringify(maskDeep(parsed))).
|
|
8453
|
+
ui.info(`set ${path} = ${JSON.stringify((await import('./cli/config-audit.js')).maskConfigDisplayValue(path, parsed))}`);
|
|
8093
8454
|
});
|
|
8094
8455
|
|
|
8095
8456
|
configCmd
|
|
@@ -8118,6 +8479,70 @@ configCmd
|
|
|
8118
8479
|
ui.info(`unset ${path}`);
|
|
8119
8480
|
});
|
|
8120
8481
|
|
|
8482
|
+
// ── config audit history / revert (CFG-STORE2-HISTORY-REVERT · 0.2.36 · 2026-10-22) ──
|
|
8483
|
+
// CFG-STORE2 가 set/unset 마다 남긴 원장을 «읽어서» 되돌린다. 원장은 append 전용 —
|
|
8484
|
+
// 되돌림도 새 행 하나(why='config revert')로만 남고, 이전 행은 절대 고치지 않는다.
|
|
8485
|
+
// 계산 = src/cli/config-audit.ts(planConfigRevert · formatConfigHistory · configDomainOf).
|
|
8486
|
+
configCmd
|
|
8487
|
+
.command('history <path>')
|
|
8488
|
+
.description('CFG-STORE2 — 한 키의 감사 이력(변경 전후 값·by·why). 비밀은 가려서 보여준다.')
|
|
8489
|
+
.option('--json', 'JSON 출력')
|
|
8490
|
+
.action(async (path: string, opts: { json?: boolean }) => {
|
|
8491
|
+
const { configDomainOf, formatConfigHistory, readConfigHistory } = await import('./cli/config-audit.js');
|
|
8492
|
+
const rows = readConfigHistory(path);
|
|
8493
|
+
if (opts.json) {
|
|
8494
|
+
await writeStdoutJson(`${JSON.stringify({ key: path, domain: configDomainOf(path), rows }, null, 2)}\n`);
|
|
8495
|
+
return;
|
|
8496
|
+
}
|
|
8497
|
+
await writeStdoutJson(`${formatConfigHistory(path, rows)}\n`);
|
|
8498
|
+
});
|
|
8499
|
+
|
|
8500
|
+
configCmd
|
|
8501
|
+
.command('revert <path>')
|
|
8502
|
+
.description('CFG-STORE2 — 그 키의 마지막 변경을 되돌린다(원장은 지우지 않고 새 행을 append).')
|
|
8503
|
+
.option('--no-backup', "Don't write config.json.bak before saving")
|
|
8504
|
+
.option('--json', 'JSON 출력')
|
|
8505
|
+
.action(async (path: string, opts: { backup?: boolean; json?: boolean }) => {
|
|
8506
|
+
const { configDomainOf, containsMaskValue, MASK, planConfigRevert, recordConfigRevert } = await import('./cli/config-audit.js');
|
|
8507
|
+
const plan = planConfigRevert(path);
|
|
8508
|
+
if (plan.status === 'no-history') {
|
|
8509
|
+
ui.error(`revert ${path} — 감사 이력 없음(되돌릴 변경이 없다)`);
|
|
8510
|
+
process.exit(1);
|
|
8511
|
+
}
|
|
8512
|
+
if (plan.status === 'masked') {
|
|
8513
|
+
ui.error(`revert ${path} — 이전 값이 ${MASK} 라 원문 복원 불가(원문은 원장에 남기지 않는다). 그 키를 직접 set 하라.`);
|
|
8514
|
+
process.exit(1);
|
|
8515
|
+
}
|
|
8516
|
+
if (plan.status === 'already') {
|
|
8517
|
+
ui.info(`revert ${path} — 마지막 변경이 값 변화 없음 (no-op)`);
|
|
8518
|
+
return;
|
|
8519
|
+
}
|
|
8520
|
+
const cfg = getUserConfig() as unknown as Record<string, unknown>;
|
|
8521
|
+
const prev = getConfigPath(cfg, path); // 되돌림도 한 번의 변경 — 그 «전» 값을 남긴다
|
|
8522
|
+
if (opts.backup !== false) backupUserConfig(userConfigPath());
|
|
8523
|
+
if (plan.value === undefined) unsetConfigPath(cfg, path);
|
|
8524
|
+
else setConfigPath(cfg, path, plan.value);
|
|
8525
|
+
saveUserConfig(cfg as unknown as ReturnType<typeof getUserConfig>);
|
|
8526
|
+
reloadUserConfig();
|
|
8527
|
+
// set/unset 과 대칭 — 저장 후 재읽기로 «실제로 복원됐는지» 검증(조용한 성공 금지).
|
|
8528
|
+
// 가림 자가 값으로 되쓰였는지도 본다: 오염값끼리는 직렬화 비교가 같아 조용히 통과한다.
|
|
8529
|
+
const after = getConfigPath(getUserConfig() as unknown as Record<string, unknown>, path);
|
|
8530
|
+
if (containsMaskValue(after)) {
|
|
8531
|
+
console.error(`⚠️ revert ${path} — 복원 값에 가림 자(${MASK})가 섞였다(원문 복원 불가). 그 키를 직접 set 하라.`);
|
|
8532
|
+
process.exit(1);
|
|
8533
|
+
}
|
|
8534
|
+
if (JSON.stringify(after) !== JSON.stringify(plan.value)) {
|
|
8535
|
+
console.error(`⚠️ revert ${path} — 저장 후 값 미반영(직렬화 드롭). 읽힌값=${JSON.stringify(after)}`);
|
|
8536
|
+
process.exit(1);
|
|
8537
|
+
}
|
|
8538
|
+
const row = recordConfigRevert({ key: path, prev, next: plan.value, why: 'config revert' });
|
|
8539
|
+
if (opts.json) {
|
|
8540
|
+
await writeStdoutJson(`${JSON.stringify({ key: path, domain: configDomainOf(path), row }, null, 2)}\n`);
|
|
8541
|
+
return;
|
|
8542
|
+
}
|
|
8543
|
+
ui.info(`revert ${path} = ${JSON.stringify(plan.value ?? null)} (domain=${configDomainOf(path)})`);
|
|
8544
|
+
});
|
|
8545
|
+
|
|
8121
8546
|
// ── config drift / explain (CFG-STORE1 · 0.2.20 · 2026-10-08) — 읽기 전용 «유효 config ⊕ 출처» ──
|
|
8122
8547
|
// 집(~/.elanous)과 파생 시험 우주(<트리>/.elanous-test) config 사본의 드리프트를 한 명령으로.
|
|
8123
8548
|
// ⛔ 쓰기 0 · 못 읽음 ≠ 같음 · 비밀 값 가림. 계산 = src/cli/config-drift.ts.
|
|
@@ -8306,7 +8731,7 @@ program
|
|
|
8306
8731
|
return;
|
|
8307
8732
|
}
|
|
8308
8733
|
const cfg = reloadUserConfig();
|
|
8309
|
-
await runChatTurnCli({
|
|
8734
|
+
await (await import('./cli/agent-cli.js')).runChatTurnCli({
|
|
8310
8735
|
cfg,
|
|
8311
8736
|
userText: parts.join(' '),
|
|
8312
8737
|
explicitSessionId: opts.session,
|
|
@@ -8426,6 +8851,7 @@ program
|
|
|
8426
8851
|
.option('--config <path>', 'Load answers from a JSON answer file (overrides interactive prompts)')
|
|
8427
8852
|
.option('--non-interactive', 'Run without prompts — resolve all answers from --config + env vars')
|
|
8428
8853
|
.action(async (step: string | undefined, opts: { config?: string; nonInteractive?: boolean }) => {
|
|
8854
|
+
const { runOnboarding, runOnboardingStep, runOnboardingNonInteractive } = await import('./onboarding.js');
|
|
8429
8855
|
// C-4e (cleanup ROADMAP 2026-05-08) restricted `elanous setup <step>`
|
|
8430
8856
|
// to llm/skills/obsidian. Telegram/Discord setup migrated to NEXUS
|
|
8431
8857
|
// — `elanous channel-setup --platform telegram|discord` (Track Q).
|
|
@@ -8699,7 +9125,8 @@ sessionCmd
|
|
|
8699
9125
|
sessionCmd
|
|
8700
9126
|
.command('new')
|
|
8701
9127
|
.description('Create a fresh session and mark it active')
|
|
8702
|
-
.action(() => {
|
|
9128
|
+
.action(async () => {
|
|
9129
|
+
const { ensureCliSession } = await import('./session/chat.js');
|
|
8703
9130
|
const cfg = getUserConfig();
|
|
8704
9131
|
const s = ensureCliSession(cfg);
|
|
8705
9132
|
setActiveSessionId(s.id);
|
|
@@ -8728,7 +9155,8 @@ sessionCmd
|
|
|
8728
9155
|
.command('show [prefix]')
|
|
8729
9156
|
.description('Print the messages of a session (default: active)')
|
|
8730
9157
|
.option('--include-tools', 'Include tool-call telemetry (role:tool · 실제 호출 도구·args·result 추적)')
|
|
8731
|
-
.action((prefix: string | undefined, opts: { includeTools?: boolean }) => {
|
|
9158
|
+
.action(async (prefix: string | undefined, opts: { includeTools?: boolean }) => {
|
|
9159
|
+
const { sessionBudget } = await import('./session/chat.js');
|
|
8732
9160
|
const id = prefix ? resolveSessionId(prefix) : getActiveSessionId();
|
|
8733
9161
|
if (!id) { ui.error('no session'); process.exit(1); }
|
|
8734
9162
|
const loaded = loadSession(id);
|
|
@@ -9147,6 +9575,7 @@ async function runFirstSetupForCli(cfg: ReturnType<typeof getUserConfig>, announ
|
|
|
9147
9575
|
}
|
|
9148
9576
|
|
|
9149
9577
|
async function runOnboardingForCli(): Promise<boolean> {
|
|
9578
|
+
const { runOnboarding, handleOnboardingRefusal } = await import('./onboarding.js');
|
|
9150
9579
|
try {
|
|
9151
9580
|
await runOnboarding();
|
|
9152
9581
|
return true;
|
|
@@ -9191,7 +9620,7 @@ program
|
|
|
9191
9620
|
}
|
|
9192
9621
|
if (opts.tools) announceChatToolsCompatibility();
|
|
9193
9622
|
const cfg = getUserConfig();
|
|
9194
|
-
if (await firstChatGate(cfg, {
|
|
9623
|
+
if (await (await import('./onboarding/first-chat-gate.js')).firstChatGate(cfg, {
|
|
9195
9624
|
isTTY: process.stdin.isTTY === true,
|
|
9196
9625
|
runFirstRun: async (deps) => (await import('./onboarding/first-run.js')).runFirstRun(deps),
|
|
9197
9626
|
runInteractive: () => {
|
|
@@ -9222,7 +9651,7 @@ program
|
|
|
9222
9651
|
// 단일 턴 엔진(runChatTurnCli)은 cfg-바인딩 클로저로 주입(순환 회피). opts→DevChatOpts 매핑은 seam.
|
|
9223
9652
|
const { runChatCliCommand } = await import('./chat/chat-cli.js');
|
|
9224
9653
|
await runChatCliCommand(parts.join(' '), opts, {
|
|
9225
|
-
runChatTurn: (text, chat) => runChatTurnCli({
|
|
9654
|
+
runChatTurn: async (text, chat) => (await import('./cli/agent-cli.js')).runChatTurnCli({
|
|
9226
9655
|
cfg: refreshed,
|
|
9227
9656
|
userText: text,
|
|
9228
9657
|
explicitSessionId: chat.session,
|
|
@@ -9267,7 +9696,15 @@ program
|
|
|
9267
9696
|
process.exit(2);
|
|
9268
9697
|
}
|
|
9269
9698
|
const cfg = getUserConfig();
|
|
9270
|
-
if (needsOnboarding(cfg)) {
|
|
9699
|
+
if ((await import('./onboarding.js')).needsOnboarding(cfg)) {
|
|
9700
|
+
// Machine mode contract: stdout carries JSONL only. An onboarding
|
|
9701
|
+
// banner there corrupts the stream (`invalid REPL JSONL response`
|
|
9702
|
+
// in the TUI parent). Fail fast on stderr instead of launching an
|
|
9703
|
+
// interactive wizard on a pipe.
|
|
9704
|
+
if (opts.json === true || opts.stdinJsonl === true) {
|
|
9705
|
+
process.stderr.write('No config yet — run `elanous` once interactively (onboarding) before using repl --json / --stdin-jsonl.\n');
|
|
9706
|
+
process.exit(2);
|
|
9707
|
+
}
|
|
9271
9708
|
if (cfg.onboarding.webFirst === false) ui.info('No config yet — launching setup wizard first.');
|
|
9272
9709
|
if (!await runFirstSetupForCli(cfg, true)) return;
|
|
9273
9710
|
}
|
|
@@ -11613,6 +12050,7 @@ function writeSyncFailure(message: string): void {
|
|
|
11613
12050
|
}
|
|
11614
12051
|
|
|
11615
12052
|
async function runSyncFlow(fromDashboard: boolean): Promise<void> {
|
|
12053
|
+
const { showSyncSelector, showSyncProgress } = await import('./selector.js');
|
|
11616
12054
|
let result: Awaited<ReturnType<typeof showSyncSelector>>;
|
|
11617
12055
|
try {
|
|
11618
12056
|
result = await showSyncSelector(fromDashboard);
|
|
@@ -11741,6 +12179,12 @@ export function filterDashboardArgs(rawArgs: readonly string[], resumeFlagIdx?:
|
|
|
11741
12179
|
}
|
|
11742
12180
|
|
|
11743
12181
|
async function main(): Promise<void> {
|
|
12182
|
+
// TUI-BOOT-TIMING-HOLES — «프로세스→sink» 구간(10:40 실측 9.3s). 그 9.3s 의 대부분은 이 모듈이
|
|
12183
|
+
// import 되는 동안(모듈 로드) 흐르므로, main() 진입만 재면 구간을 잘라 먹는다. `performance.now()`
|
|
12184
|
+
// 의 기준점은 프로세스 시작(`performance.timeOrigin`)이라 sink 등록 직전의 «절대값» 이 곧
|
|
12185
|
+
// 프로세스→sink 다. main() 진입 시각은 그 안에서 «어느 몫이 엔트리 코드인지» 가르는 두 번째 값.
|
|
12186
|
+
// 발행은 sink 등록 뒤로 미룬다(등록 전 debug.log 는 no-op).
|
|
12187
|
+
const bootMainEnteredAt = performance.now();
|
|
11744
12188
|
// WD1 — seed the session working directory from the launch cwd.
|
|
11745
12189
|
// Every later-phase subsystem reads via getSessionCwd() instead of
|
|
11746
12190
|
// process.cwd(). Subcommand dispatch (program.parseAsync) runs
|
|
@@ -11778,6 +12222,15 @@ async function main(): Promise<void> {
|
|
|
11778
12222
|
|
|
11779
12223
|
let rawArgs = process.argv.slice(2);
|
|
11780
12224
|
|
|
12225
|
+
// The root flag can follow other launch options, but never a subcommand.
|
|
12226
|
+
const rootTui = extractRootTuiEntry(rawArgs);
|
|
12227
|
+
if (rootTui.error) {
|
|
12228
|
+
console.error(rootTui.error);
|
|
12229
|
+
process.exitCode = 1;
|
|
12230
|
+
return;
|
|
12231
|
+
}
|
|
12232
|
+
rawArgs = rootTui.args;
|
|
12233
|
+
|
|
11781
12234
|
rawArgs = rewriteBareNexusToStatus({ rawArgs });
|
|
11782
12235
|
|
|
11783
12236
|
// A leading --rich was a dashboard launch flag. The dashboard no longer
|
|
@@ -11921,6 +12374,9 @@ async function main(): Promise<void> {
|
|
|
11921
12374
|
const resolved = await resolveRemoteTarget({});
|
|
11922
12375
|
if (resolved) remote = resolved;
|
|
11923
12376
|
}
|
|
12377
|
+
// Bare entry is classic. The next TUI has no remote transport yet;
|
|
12378
|
+
// an explicit --tui next still reports the unsupported combination below.
|
|
12379
|
+
const tuiEntry = effectiveRootTuiEntry(rootTui, Boolean(remote));
|
|
11924
12380
|
|
|
11925
12381
|
// Root dashboard resume accepts `--resume`. Only a
|
|
11926
12382
|
// leading launch flag is owned here: a subcommand's `-r` stays
|
|
@@ -11985,8 +12441,13 @@ async function main(): Promise<void> {
|
|
|
11985
12441
|
// (e.g. `session watch --debug`), stripping them here would silently
|
|
11986
12442
|
// eat that subcommand's own option before commander ever sees it.
|
|
11987
12443
|
const args = filterDashboardArgs(rawArgs, resumeFlagIdx);
|
|
12444
|
+
if (tuiEntry === 'next' && rootTui.explicit && args.length > 0) {
|
|
12445
|
+
console.error('elanous: --tui next is a standalone TUI entry, not a subcommand option');
|
|
12446
|
+
process.exitCode = 1;
|
|
12447
|
+
return;
|
|
12448
|
+
}
|
|
11988
12449
|
|
|
11989
|
-
// Bare `elanous` (no subcommand) →
|
|
12450
|
+
// Bare `elanous` (no subcommand) → classic dashboard; next TUI only via `--tui next`. The former
|
|
11990
12451
|
// `global.entry.defaultMode` switch (which could route here to the
|
|
11991
12452
|
// headless NEXUS daemon) was removed 2026-07-24: T3/T4 deleted the
|
|
11992
12453
|
// NEXUS interactive TUI, so every non-dashboard route was a dead-end
|
|
@@ -12048,7 +12509,7 @@ async function main(): Promise<void> {
|
|
|
12048
12509
|
// Bare entry only requires an LLM; detailed setup stays behind `eln setup`.
|
|
12049
12510
|
const firstRunStartedAt = Date.now();
|
|
12050
12511
|
const cfg = getUserConfig();
|
|
12051
|
-
if (needsFirstRun(cfg)) {
|
|
12512
|
+
if ((await import('./onboarding.js')).needsFirstRun(cfg)) {
|
|
12052
12513
|
if (cfg.onboarding.webFirst !== false) {
|
|
12053
12514
|
const { runWebFirstSetup } = await import('./onboarding/web-first.js');
|
|
12054
12515
|
if (await runWebFirstSetup({ config: cfg, startedAt: firstRunStartedAt, startIfMissing: false }) === 'link-shown') return;
|
|
@@ -12098,7 +12559,20 @@ async function main(): Promise<void> {
|
|
|
12098
12559
|
// PR#4622(self utterance CLI)·session-cli 미러. fail-open·비블로킹.
|
|
12099
12560
|
const bootTimer = (await import('./dashboard/boot-timing.js')).createBootTimer();
|
|
12100
12561
|
bootTimer.begin();
|
|
12562
|
+
// 창은 sink 등록 «직전» 에 닫는다(등록 전 debug.log 는 no-op 이라 발행은 등록 뒤).
|
|
12563
|
+
const procToLogSinkMs = performance.now();
|
|
12564
|
+
const mainEnterToLogSinkMs = procToLogSinkMs - bootMainEnteredAt;
|
|
12101
12565
|
try { await (await import('./domains/standalone-log-sink.js')).registerStandaloneLogSink('tui'); } catch { /* fail-open */ }
|
|
12566
|
+
debug.log('tui.boot', 'phase', {
|
|
12567
|
+
phase: 'proc-to-log-sink',
|
|
12568
|
+
ms: Math.round(procToLogSinkMs),
|
|
12569
|
+
from: 'process-start',
|
|
12570
|
+
});
|
|
12571
|
+
debug.log('tui.boot', 'phase', {
|
|
12572
|
+
phase: 'main-enter-to-log-sink',
|
|
12573
|
+
ms: Math.round(mainEnterToLogSinkMs),
|
|
12574
|
+
from: 'main-entry',
|
|
12575
|
+
});
|
|
12102
12576
|
bootTimer.phase('log-sink');
|
|
12103
12577
|
// P3(대표 2026-07-26) — footgun 관측을 logs.db 에 도달시킨다. 초반(arg 파싱 前) warnProdSpawnFootgun 은
|
|
12104
12578
|
// StoreSink 등록 前이라 debug.log 가 logs.db 미도달이었다(순서 갭). sink 등록 직후 관측만 재발행(stderr 중복 X).
|
|
@@ -12125,20 +12599,214 @@ async function main(): Promise<void> {
|
|
|
12125
12599
|
}
|
|
12126
12600
|
}
|
|
12127
12601
|
bootTimer.begin();
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
}
|
|
12602
|
+
if (tuiEntry === 'next') {
|
|
12603
|
+
if (remote) {
|
|
12604
|
+
console.error('elanous: --tui next currently reads local sessions only; drop it (classic is the default) for remote attach');
|
|
12605
|
+
process.exitCode = 1;
|
|
12606
|
+
return;
|
|
12607
|
+
}
|
|
12608
|
+
if ((process.stdout.columns || 0) < 20 || (process.stdout.rows || 0) < 6) {
|
|
12609
|
+
console.error('elanous: --tui next requires at least 20 columns and 6 rows');
|
|
12610
|
+
process.exitCode = 1;
|
|
12611
|
+
return;
|
|
12612
|
+
}
|
|
12613
|
+
const { showNextTui } = await import('./tui/entry.js');
|
|
12614
|
+
await showNextTui({ resumeSessionId });
|
|
12615
|
+
bootTimer.phase('show-next');
|
|
12616
|
+
bootTimer.done();
|
|
12617
|
+
} else {
|
|
12618
|
+
const { showDashboard } = await import('./dashboard/index.js');
|
|
12619
|
+
await showDashboard({
|
|
12620
|
+
...dashboardOpts,
|
|
12621
|
+
// TUI-BOOT-TIMING-HOLES — show 동기 셋업(2.3s)은 종전 첫 프레임 신호 하나에 묶여 안 보였다.
|
|
12622
|
+
// bootTimer 는 createBootTimer 시점부터 재므로, dashboard 가 잰 «진입~첫 프레임» 값을 그대로
|
|
12623
|
+
// 이벤트로 남긴다(요약 phase 회계는 종전 그대로 보존).
|
|
12624
|
+
onSyncSetupComplete: (ms: number) => {
|
|
12625
|
+
debug.log('tui.boot', 'show-dashboard-setup', { ms: Math.round(ms) });
|
|
12626
|
+
},
|
|
12627
|
+
onFirstFrameRendered: () => {
|
|
12628
|
+
bootTimer.phase('show-dashboard');
|
|
12629
|
+
bootTimer.done();
|
|
12630
|
+
},
|
|
12631
|
+
});
|
|
12632
|
+
closeTui();
|
|
12633
|
+
}
|
|
12634
|
+
// TUI-H9-ACTIVE-SESSION-ID — 기동 뒤 설치본/체크아웃이 움직였으면 «이 TUI 가 지금 보여 주던 대화»
|
|
12635
|
+
// 로 스스로 다시 뜬다. 확인이 안 되면 다시 뜨지 않고 이유를 남긴다(전역 최신·기동 resume 으로 메우지 않는다).
|
|
12636
|
+
await exitTuiRun();
|
|
12637
|
+
}
|
|
12638
|
+
|
|
12639
|
+
// ── TUI-H9-ACTIVE-SESSION-ID · 0.2.36 — 재기동은 «이 TUI 의 활성 대화» 로만 ──
|
|
12640
|
+
//
|
|
12641
|
+
// #30046 의 H9 배선은 재기동 세션을 `resumeSessionId ?? getActiveSessionId() ?? listSessions()[0]?.id`
|
|
12642
|
+
// 로 골랐다 — 기동 때의 resume 값이 이후의 활성 세션보다 우선했고, 활성 id 가 없으면 전역 최신(다른
|
|
12643
|
+
// 자리의 맥락일 수 있다)을 집어 왔다. 여기서는 ①이 TUI 가 화면으로 확인한 대화(tui-self-report 의
|
|
12644
|
+
// 소유 기록)와 ②지금 집중된 활성 id 가 «같고» ③그 대화가 저장소에 실재할 때만 재기동한다. 하나라도
|
|
12645
|
+
// 어긋나면 다시 뜨지 않고 이유를 남긴다 — 비슷한 id 로 메우지 않는다.
|
|
12646
|
+
|
|
12647
|
+
/**
|
|
12648
|
+
* TUI 종료 경계 — 재기동 «요청»(`requestTuiSelfRestart`)이 있고 판이 낡았으면 «이 TUI 의 활성 대화» 로
|
|
12649
|
+
* 자식을 띄우고, 부모는 그 종료 코드로 끝난다. 요청이 없으면(사용자 `q`/Ctrl+Q) 낡음을 재지도 않고
|
|
12650
|
+
* 지금처럼 0 으로 끝난다 — 종료 의도를 재기동으로 바꾸지 않는다.
|
|
12651
|
+
* 강제 종료는 그대로다: 대시보드의 배경 타이머(clipboard poller·shimmer/blink)가 Bun 이벤트 루프를
|
|
12652
|
+
* 붙잡아 `q`/Ctrl+Q 뒤에도 터미널이 멈춘 채 남는다.
|
|
12653
|
+
*/
|
|
12654
|
+
export async function exitTuiRun(
|
|
12655
|
+
deps: TuiSelfRestartDeps & {
|
|
12656
|
+
readonly exit?: (code: number) => never;
|
|
12657
|
+
/** 재기동 요청 — 기본 = `takeTuiSelfRestartRequest()`(한 번 읽고 지운다). */
|
|
12658
|
+
readonly takeRestartRequest?: () => { readonly reason: string } | null;
|
|
12659
|
+
} = {},
|
|
12660
|
+
): Promise<void> {
|
|
12661
|
+
const exit = deps.exit ?? ((code: number): never => process.exit(code));
|
|
12662
|
+
const take = deps.takeRestartRequest
|
|
12663
|
+
?? (await import('./capture/tui-self-report.js')).takeTuiSelfRestartRequest;
|
|
12664
|
+
const request = take();
|
|
12665
|
+
if (!request) {
|
|
12666
|
+
try {
|
|
12667
|
+
(deps.log ?? ((event: string, detail: Record<string, unknown>) => debug.log('tui.self-restart', event, detail)))(
|
|
12668
|
+
'skip', { reason: 'no-restart-request' },
|
|
12669
|
+
);
|
|
12670
|
+
} catch { /* 관측 실패가 종료를 막지 않는다 */ }
|
|
12671
|
+
exit(0);
|
|
12672
|
+
}
|
|
12673
|
+
const selfRestart = await runTuiSelfRestartOnStaleBuild(deps);
|
|
12674
|
+
if (selfRestart.outcome === 'relaunch') {
|
|
12675
|
+
// 자식이 화면을 이어받았다 — 부모는 자식 종료 코드로 끝난다.
|
|
12676
|
+
exit(selfRestart.exitCode ?? 0);
|
|
12677
|
+
}
|
|
12678
|
+
exit(0);
|
|
12679
|
+
}
|
|
12680
|
+
|
|
12681
|
+
export interface TuiSelfRestartResult {
|
|
12682
|
+
readonly outcome: 'skip' | 'blocked' | 'relaunch';
|
|
12683
|
+
readonly reason: string;
|
|
12684
|
+
readonly sessionId?: string;
|
|
12685
|
+
readonly argv?: readonly string[];
|
|
12686
|
+
readonly exitCode?: number;
|
|
12687
|
+
}
|
|
12688
|
+
|
|
12689
|
+
export interface TuiSelfRestartDeps {
|
|
12690
|
+
/** 재기동 자식의 스크립트 경로 — 기본 = `process.argv[1]`(배포 엔트리). */
|
|
12691
|
+
readonly scriptPath?: string;
|
|
12692
|
+
/** 사용자 인자 — 기본 = `process.argv.slice(2)`. 이전 `--resume`/`--continue` 는 걷어내고 우리 id 만 싣는다. */
|
|
12693
|
+
readonly args?: readonly string[];
|
|
12694
|
+
/** 낡음 판정 — 기본 = `judgeBuildStaleness(runningBuild ⊕ readCurrentInstallRecord ⊕ readCheckoutHead)`. */
|
|
12695
|
+
readonly stale?: () => { readonly stale: boolean | null; readonly reason: string };
|
|
12696
|
+
/** 이 TUI 가 화면으로 확인한 대화 — 기본 = 소유 기록(`getTuiOwnedSession`). */
|
|
12697
|
+
readonly owned?: () => { readonly sessionId: string; readonly at: number } | null;
|
|
12698
|
+
/** 지금 집중된 활성 대화 id — 기본 = `getActiveSessionId()`. */
|
|
12699
|
+
readonly liveActiveSessionId?: () => string | null;
|
|
12700
|
+
/** 그 id 의 대화가 실재하나 — 기본 = `loadSession(id) !== null`. */
|
|
12701
|
+
readonly sessionExists?: (sessionId: string) => boolean;
|
|
12702
|
+
/** 관측 전용 — «전역 최신»이 무엇이든 재기동 id 는 여기서 고르지 않는다(로그·사유 문면에만 적는다). */
|
|
12703
|
+
readonly globalLatestSessionId?: () => string | null;
|
|
12704
|
+
readonly spawnChild?: (command: string, argv: readonly string[], env: Record<string, string>) => Promise<number>;
|
|
12705
|
+
readonly log?: (event: string, detail: Record<string, unknown>) => void;
|
|
12706
|
+
}
|
|
12707
|
+
|
|
12708
|
+
/** 한 런의 재기동 세대 상한 — 재기동한 자식이 또 낡아도 여기서 멈춘다(무한 재기동 방지). */
|
|
12709
|
+
const TUI_SELF_RESTART_MAX_GENERATION = 3;
|
|
12710
|
+
|
|
12711
|
+
/** 재기동 자식에게 넘길 argv — 이 TUI 의 활성 대화만 `--resume` 으로 싣는다. */
|
|
12712
|
+
export function planTuiRestartArgv(input: {
|
|
12713
|
+
readonly scriptPath: string;
|
|
12714
|
+
readonly args: readonly string[];
|
|
12715
|
+
readonly sessionId: string;
|
|
12716
|
+
}): string[] {
|
|
12717
|
+
const kept: string[] = [];
|
|
12718
|
+
for (let i = 0; i < input.args.length; i += 1) {
|
|
12719
|
+
const arg = input.args[i]!;
|
|
12720
|
+
if (arg === '--resume') {
|
|
12721
|
+
// 값 없는 `--resume` 뒤에 오는 플래그는 값이 아니다 — 삼키지 않는다.
|
|
12722
|
+
const next = input.args[i + 1];
|
|
12723
|
+
if (next !== undefined && !next.startsWith('-')) i += 1;
|
|
12724
|
+
continue;
|
|
12725
|
+
}
|
|
12726
|
+
if (arg === '--continue' || arg.startsWith('--resume=') || arg.startsWith('--continue=')) continue;
|
|
12727
|
+
kept.push(arg);
|
|
12728
|
+
}
|
|
12729
|
+
return [input.scriptPath, ...kept, '--resume', input.sessionId];
|
|
12730
|
+
}
|
|
12731
|
+
|
|
12732
|
+
/**
|
|
12733
|
+
* 낡은 판에서 TUI 를 스스로 다시 띄운다 — 이 TUI 가 보여 주던 대화로만.
|
|
12734
|
+
* 확인 실패는 «재기동 안 함» 이고 그 이유가 로그·stderr 로 남는다.
|
|
12735
|
+
*/
|
|
12736
|
+
export async function runTuiSelfRestartOnStaleBuild(deps: TuiSelfRestartDeps = {}): Promise<TuiSelfRestartResult> {
|
|
12737
|
+
const report = deps.log ?? ((event: string, detail: Record<string, unknown>) => debug.log('tui.self-restart', event, detail));
|
|
12738
|
+
const { judgeBuildStaleness, readCheckoutHead, readCurrentInstallRecord, runningBuild } = await import('./pty-shell/tui-run-state.js');
|
|
12739
|
+
const staleness = (deps.stale ?? (() => {
|
|
12740
|
+
const build = runningBuild();
|
|
12741
|
+
const checkoutHead = build.source === 'checkout' && build.codeRoot ? readCheckoutHead(build.codeRoot) : undefined;
|
|
12742
|
+
return judgeBuildStaleness({ build, installed: readCurrentInstallRecord(), ...(checkoutHead ? { checkoutHead } : {}) });
|
|
12743
|
+
}))();
|
|
12744
|
+
if (staleness.stale !== true) {
|
|
12745
|
+
report('skip', { reason: staleness.reason });
|
|
12746
|
+
return { outcome: 'skip', reason: staleness.reason };
|
|
12747
|
+
}
|
|
12748
|
+
const generation = Number.parseInt(process.env.ELANOUS_TUI_RESTART_GEN ?? '0', 10) || 0;
|
|
12749
|
+
const tuiReport = await import('./capture/tui-self-report.js');
|
|
12750
|
+
const store = await import('./session/index.js');
|
|
12751
|
+
const owned = (deps.owned ?? tuiReport.getTuiOwnedSession)();
|
|
12752
|
+
const liveActiveSessionId = (deps.liveActiveSessionId ?? store.getActiveSessionId)();
|
|
12753
|
+
const globalLatestSessionId = (deps.globalLatestSessionId
|
|
12754
|
+
?? (() => { try { return store.listSessions({ limit: 1 })[0]?.id ?? null; } catch { return null; } }))();
|
|
12755
|
+
if (generation >= TUI_SELF_RESTART_MAX_GENERATION) {
|
|
12756
|
+
report('blocked', { reason: 'generation-limit', generation, staleReason: staleness.reason });
|
|
12757
|
+
console.error(`elanous: 설치본이 바뀌었지만 이 런은 이미 ${generation}번 다시 떴다 — 자동 재기동을 멈춘다(수동으로 다시 열어라).`);
|
|
12758
|
+
return { outcome: 'blocked', reason: 'generation-limit' };
|
|
12759
|
+
}
|
|
12760
|
+
const decision = tuiReport.decideTuiRestartSession({
|
|
12761
|
+
owned,
|
|
12762
|
+
liveActiveSessionId,
|
|
12763
|
+
sessionExists: deps.sessionExists ?? ((id: string) => { try { return store.loadSession(id) !== null; } catch { return false; } }),
|
|
12764
|
+
});
|
|
12765
|
+
if (!decision.ok) {
|
|
12766
|
+
report('blocked', {
|
|
12767
|
+
reason: decision.reason,
|
|
12768
|
+
staleReason: staleness.reason,
|
|
12769
|
+
ownedSessionId: owned?.sessionId ?? null,
|
|
12770
|
+
liveActiveSessionId,
|
|
12771
|
+
globalLatestSessionId,
|
|
12772
|
+
generation,
|
|
12773
|
+
});
|
|
12774
|
+
console.error(`elanous: 설치본이 바뀌었지만 이 TUI 의 활성 대화를 확인하지 못해 다시 뜨지 않았다(${decision.reason}) — 다시 열면 지금 화면의 대화로 이어진다.`);
|
|
12775
|
+
return { outcome: 'blocked', reason: decision.reason };
|
|
12776
|
+
}
|
|
12777
|
+
const argv = planTuiRestartArgv({
|
|
12778
|
+
scriptPath: deps.scriptPath ?? process.argv[1] ?? '',
|
|
12779
|
+
args: deps.args ?? process.argv.slice(2),
|
|
12780
|
+
sessionId: decision.sessionId,
|
|
12781
|
+
});
|
|
12782
|
+
const env: Record<string, string> = {};
|
|
12783
|
+
for (const [key, value] of Object.entries(process.env)) if (typeof value === 'string') env[key] = value;
|
|
12784
|
+
env.ELANOUS_TUI_RESTART_GEN = String(generation + 1);
|
|
12785
|
+
report('relaunch', {
|
|
12786
|
+
sessionId: decision.sessionId,
|
|
12787
|
+
claimedAt: decision.claimedAt,
|
|
12788
|
+
staleReason: staleness.reason,
|
|
12789
|
+
generation,
|
|
12790
|
+
argv,
|
|
12791
|
+
globalLatestSessionId,
|
|
12792
|
+
});
|
|
12793
|
+
console.error(`elanous: 설치본이 바뀌어 이 TUI 의 대화(${decision.sessionId})로 다시 뜬다${globalLatestSessionId && globalLatestSessionId !== decision.sessionId ? ` — 전역 최신 ${globalLatestSessionId} 은 싣지 않는다` : ''}.`);
|
|
12794
|
+
const exitCode = await (deps.spawnChild ?? defaultTuiSelfRestartSpawn)(process.execPath, argv, env);
|
|
12795
|
+
return { outcome: 'relaunch', reason: staleness.reason, sessionId: decision.sessionId, argv, exitCode };
|
|
12796
|
+
}
|
|
12797
|
+
|
|
12798
|
+
/** 재기동 자식 — 같은 터미널(stdio inherit)을 물려받는다. 부모는 자식 종료를 기다린 뒤 그 코드로 끝난다. */
|
|
12799
|
+
async function defaultTuiSelfRestartSpawn(command: string, argv: readonly string[], env: Record<string, string>): Promise<number> {
|
|
12800
|
+
const childProcess = await import('node:child_process');
|
|
12801
|
+
const child: import('node:child_process').ChildProcess = childProcess.spawn(
|
|
12802
|
+
command,
|
|
12803
|
+
[...argv],
|
|
12804
|
+
{ stdio: 'inherit', env: env as NodeJS.ProcessEnv },
|
|
12805
|
+
);
|
|
12806
|
+
return await new Promise<number>((resolve) => {
|
|
12807
|
+
child.on('error', () => resolve(1));
|
|
12808
|
+
child.on('exit', (code, signal) => resolve(typeof code === 'number' ? code : signal ? 1 : 0));
|
|
12134
12809
|
});
|
|
12135
|
-
closeTui();
|
|
12136
|
-
// Force exit: the dashboard starts background timers (clipboard
|
|
12137
|
-
// poller, shimmer/blink animations) that keep the Bun event loop
|
|
12138
|
-
// alive even after the TUI tears down. Without this hard exit,
|
|
12139
|
-
// `q` / Ctrl+Q would leave the user staring at a wedged terminal
|
|
12140
|
-
// until they sent SIGINT.
|
|
12141
|
-
process.exit(0);
|
|
12142
12810
|
}
|
|
12143
12811
|
|
|
12144
12812
|
/**
|