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
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
// daemon exit.
|
|
29
29
|
|
|
30
30
|
import type { McpServerSpec } from '../../user-config.js';
|
|
31
|
-
import { McpClient, McpConnectionError, type McpToolCallResult } from '../../mcp/client.js';
|
|
31
|
+
import { McpClient, McpConnectionError, type McpTool, type McpToolCallResult } from '../../mcp/client.js';
|
|
32
32
|
import {
|
|
33
33
|
createMcpProxyRuntime,
|
|
34
34
|
createMcpToolAuthorizer,
|
|
@@ -36,13 +36,13 @@ import {
|
|
|
36
36
|
import { registerToolRuntime, unregisterToolRuntime } from '../../tool-runtime/registry.js';
|
|
37
37
|
import { debug, redactSecretText } from '../../debug/log.js';
|
|
38
38
|
import { elanousStateRoot } from '../../autopilot/state-paths.js';
|
|
39
|
-
import { spawn as nodeSpawn } from 'node:child_process';
|
|
39
|
+
import { spawn as nodeSpawn, type ChildProcess } from 'node:child_process';
|
|
40
40
|
import { listNodeKinds } from '../../graph-kinds/registry.js';
|
|
41
41
|
import { syncInstalledPluginNodes } from '../../graph-kinds/installed-plugin-nodes.js';
|
|
42
42
|
import { listInstalledPlugins } from '../../plugins/install/plugin-install.js';
|
|
43
43
|
import { pluginEnv, credentialStatus } from '../../plugins/install/plugin-credentials.js';
|
|
44
|
-
import { existsSync, realpathSync } from 'node:fs';
|
|
45
|
-
import { resolve, sep } from 'node:path';
|
|
44
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
|
|
45
|
+
import { join, resolve, sep } from 'node:path';
|
|
46
46
|
|
|
47
47
|
export interface McpClientsHandle {
|
|
48
48
|
/** Live clients (one per successfully started server). */
|
|
@@ -56,6 +56,9 @@ export interface McpClientsHandle {
|
|
|
56
56
|
// ⇒ 노출하지 않는다. 허가 상태는 「등록된 런타임이 거부하나」로 «행동»으로 관측한다.
|
|
57
57
|
/** Stop all clients gracefully and revoke this handle's grants. Safe to call multiple times. */
|
|
58
58
|
shutdown(): Promise<void>;
|
|
59
|
+
/** 동기 마지막 수단 — 프로세스 exit 훅은 `await` 할 수 없다. 살아 있는 자식에
|
|
60
|
+
* SIGTERM 만 «즉시» 쏘고 신호를 보낸 수를 돌려준다(유예·SIGKILL 은 `shutdown` 몫). */
|
|
61
|
+
terminateChildrenSync?(): number;
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
export interface McpServerBootResult {
|
|
@@ -65,6 +68,10 @@ export interface McpServerBootResult {
|
|
|
65
68
|
status: 'ready' | 'disabled' | 'failed';
|
|
66
69
|
/** Number of tools registered from this server. 0 unless status=='ready'. */
|
|
67
70
|
toolCount: number;
|
|
71
|
+
/** When status=='ready' under `lazy`: the tools above were announced from the
|
|
72
|
+
* cached tool index and the child has NOT been spawned yet — the first
|
|
73
|
+
* `callTool` on one of them spawns it (once). Absent = spawned eagerly. */
|
|
74
|
+
deferred?: boolean;
|
|
68
75
|
/** When status=='failed', the error message captured (string only —
|
|
69
76
|
* callers should not depend on Error identity). */
|
|
70
77
|
reason?: string;
|
|
@@ -126,8 +133,33 @@ export interface RegisterMcpClientsOpts {
|
|
|
126
133
|
setTimeoutFn?: (cb: () => void, ms: number) => { unref?(): void };
|
|
127
134
|
/** Test seam — replaces `clearTimeout`. */
|
|
128
135
|
clearTimeoutFn?: (handle: { unref?(): void }) => void;
|
|
136
|
+
/** CLASSIC-IDLE-MCP-LAZY (0.2.35) — classic TUI 백그라운드 경량화.
|
|
137
|
+
* true 면 자식은 «기동 때»가 아니라 «첫 도구 호출» 때 한 번 뜬다.
|
|
138
|
+
* 그 전까지 알리는 툴 «목록»은 지난 부팅이 적어 둔 인덱스
|
|
139
|
+
* (`MCP_TOOL_INDEX_FILENAME`) 그대로다 — 목록·권한은 무변경.
|
|
140
|
+
* 인덱스가 없는 서버(콜드 스타트)는 종전대로 즉시 기동하고 인덱스를 적는다. */
|
|
141
|
+
lazy?: boolean;
|
|
142
|
+
/** `lazy` 가 읽고 쓰는 툴 인덱스. 기본은 상태 루트의 `mcp-tool-index.json`. */
|
|
143
|
+
toolIndexStore?: McpToolIndexStore;
|
|
144
|
+
/** `lazy` 자식의 SIGTERM→SIGKILL 유예(ms). 기본 2500 — 종료 3초 계약 안쪽. */
|
|
145
|
+
lazyShutdownGraceMs?: number;
|
|
129
146
|
}
|
|
130
147
|
|
|
148
|
+
/** 한 서버가 지난 부팅에서 알린 툴 목록. `mcp-tool-index.json` 의 값. */
|
|
149
|
+
export type McpToolIndex = Record<string, McpTool[]>;
|
|
150
|
+
|
|
151
|
+
/** 툴 목록 캐시의 읽기/쓰기 자리 — 테스트가 임시 저장소로 갈아 끼운다. */
|
|
152
|
+
export interface McpToolIndexStore {
|
|
153
|
+
read(): McpToolIndex;
|
|
154
|
+
write(index: McpToolIndex): void;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export const MCP_TOOL_INDEX_FILENAME = 'mcp-tool-index.json';
|
|
158
|
+
|
|
159
|
+
/** 지연 기동 자식의 정리 유예. `McpClient` 기본 5000ms 는 「SIGTERM 3초 안에
|
|
160
|
+
* 안 끝남」이던 classic 종료 계약을 넘긴다 — 2500ms 면 SIGKILL 까지 3초 안쪽. */
|
|
161
|
+
const DEFAULT_LAZY_SHUTDOWN_GRACE_MS = 2500;
|
|
162
|
+
|
|
131
163
|
const DEFAULT_HANDSHAKE_TIMEOUT_MS = 8000;
|
|
132
164
|
|
|
133
165
|
/** Race `op` against a timeout. Resolves to `op` on success; rejects
|
|
@@ -151,6 +183,60 @@ function withTimeout<T>(
|
|
|
151
183
|
});
|
|
152
184
|
}
|
|
153
185
|
|
|
186
|
+
type DeferredInner = Pick<McpClient, 'start' | 'listTools' | 'callTool' | 'dispose'>;
|
|
187
|
+
|
|
188
|
+
/** 첫 도구 호출까지 자식을 띄우지 않는 MCP 클라이언트 프록시.
|
|
189
|
+
* - `callTool` 이 «한 번» 기동하고 동시 호출은 같은 기동을 기다린다.
|
|
190
|
+
* - 기동 실패는 캐시하지 않는다 — 자식이 늦게 뜨면 다음 호출이 다시 시도한다.
|
|
191
|
+
* - `dispose()` 는 진행 중 기동을 먼저 기다린다 — 자식이 새지 않는다. */
|
|
192
|
+
class DeferredMcpClient implements DeferredInner {
|
|
193
|
+
private pending: Promise<void> | null = null;
|
|
194
|
+
private started = false;
|
|
195
|
+
private disposed = false;
|
|
196
|
+
|
|
197
|
+
constructor(
|
|
198
|
+
private readonly inner: DeferredInner,
|
|
199
|
+
private readonly boot: () => Promise<void>,
|
|
200
|
+
private readonly serverId: string,
|
|
201
|
+
) {}
|
|
202
|
+
|
|
203
|
+
get spawned(): boolean { return this.started; }
|
|
204
|
+
|
|
205
|
+
async start(): Promise<void> { await this.ensureStarted(); }
|
|
206
|
+
|
|
207
|
+
async listTools(): Promise<McpTool[]> {
|
|
208
|
+
await this.ensureStarted();
|
|
209
|
+
return this.inner.listTools();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async callTool(name: string, args: Record<string, unknown>): Promise<McpToolCallResult> {
|
|
213
|
+
await this.ensureStarted();
|
|
214
|
+
// ⚠️ 기동 «뒤»의 inner.callTool 을 부른다 — 자격증명 마스킹 래퍼가
|
|
215
|
+
// createClient 직후 client.callTool 에 씌워지므로 그 래퍼를 탄다.
|
|
216
|
+
return this.inner.callTool(name, args);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async dispose(): Promise<void> {
|
|
220
|
+
this.disposed = true;
|
|
221
|
+
if (this.pending) {
|
|
222
|
+
try { await this.pending; } catch { /* 기동 실패는 정리를 막지 않는다 */ }
|
|
223
|
+
}
|
|
224
|
+
try { await this.inner.dispose(); } catch { /* dispose() is best-effort */ }
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private async ensureStarted(): Promise<void> {
|
|
228
|
+
if (this.disposed) {
|
|
229
|
+
throw new Error(`mcp.${this.serverId}: lazy client was disposed before its first tool call`);
|
|
230
|
+
}
|
|
231
|
+
if (this.started) return;
|
|
232
|
+
if (!this.pending) {
|
|
233
|
+
this.pending = this.boot().then(() => { this.started = true; });
|
|
234
|
+
this.pending.catch(() => { this.pending = null; });
|
|
235
|
+
}
|
|
236
|
+
await this.pending;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
154
240
|
export interface McpBootLogger {
|
|
155
241
|
info(line: string): void;
|
|
156
242
|
warn(line: string): void;
|
|
@@ -196,6 +282,9 @@ export async function registerMcpClients(
|
|
|
196
282
|
debug.log('mcp.client.boot', event, { id, ...safe });
|
|
197
283
|
} catch { /* logger must never throw the boot */ }
|
|
198
284
|
};
|
|
285
|
+
// 이 부팅이 띄운 자식들. 지연 기동이면 «첫 도구 호출» 뒤에야 채워지고,
|
|
286
|
+
// 프로세스가 그냥 죽는 경로(exit 훅)에서는 여기 남은 자식에 SIGTERM 을 쏜다.
|
|
287
|
+
const spawnedChildren = new Set<ChildProcess>();
|
|
199
288
|
const createClient =
|
|
200
289
|
opts.createClient ??
|
|
201
290
|
((spec: McpServerSpec) => {
|
|
@@ -221,6 +310,8 @@ export async function registerMcpClients(
|
|
|
221
310
|
const selected = commandOwners.length === 1 && owners.length === 1 && owners[0] === commandOwners[0]
|
|
222
311
|
? commandOwners[0] : undefined;
|
|
223
312
|
return new McpClient({ id: spec.id, command: spec.command, logger: bootLogger(spec.id),
|
|
313
|
+
// 지연 기동이면 정리 유예를 좁힌다 — classic 종료는 3초 안에 끝나야 한다.
|
|
314
|
+
...(opts.lazy === true ? { shutdownGraceMs: opts.lazyShutdownGraceMs ?? DEFAULT_LAZY_SHUTDOWN_GRACE_MS } : {}),
|
|
224
315
|
spawn: (cmd, args) => {
|
|
225
316
|
const declaredEnv = [...new Set(listInstalledPlugins(root).map(item => item.name))]
|
|
226
317
|
.flatMap(name => credentialStatus(name, root).fields.map(field => field.env));
|
|
@@ -234,7 +325,10 @@ export async function registerMcpClients(
|
|
|
234
325
|
Object.assign(childEnv, env);
|
|
235
326
|
injectedValuesByServer.set(spec.id, Object.values(env));
|
|
236
327
|
}
|
|
237
|
-
|
|
328
|
+
const child = nodeSpawn(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'], env: childEnv });
|
|
329
|
+
spawnedChildren.add(child);
|
|
330
|
+
child.once('exit', () => { spawnedChildren.delete(child); });
|
|
331
|
+
return child;
|
|
238
332
|
},
|
|
239
333
|
});
|
|
240
334
|
});
|
|
@@ -252,6 +346,66 @@ export async function registerMcpClients(
|
|
|
252
346
|
const perServer: Record<string, McpServerBootResult> = {};
|
|
253
347
|
let registered = 0;
|
|
254
348
|
|
|
349
|
+
// ── CLASSIC-IDLE-MCP-LAZY ────────────────────────────────────────────────
|
|
350
|
+
// classic TUI 는 MCP 서버 둘(xcodebuildmcp · aside mcp)을 «기동 때» 띄워
|
|
351
|
+
// 상주시켰다 — TUI 하나당 node⊕aside 자손 RSS 약 267MB, SIGTERM 3초 안에
|
|
352
|
+
// 안 끝남(0.2.35 OP 실측). ⇒ `lazy` 면 자식은 «첫 도구 호출» 때 한 번 뜨고,
|
|
353
|
+
// 그 전에 알리는 툴 «목록»은 지난 부팅이 적어 둔 인덱스 그대로다.
|
|
354
|
+
const lazy = opts.lazy === true;
|
|
355
|
+
const toolIndexStore = lazy ? (opts.toolIndexStore ?? defaultMcpToolIndexStore()) : undefined;
|
|
356
|
+
const toolIndex: McpToolIndex = toolIndexStore ? readToolIndex(toolIndexStore) : {};
|
|
357
|
+
const deferredClients: DeferredMcpClient[] = [];
|
|
358
|
+
const lazyToolsFor = (serverId: string): McpTool[] | undefined => {
|
|
359
|
+
if (!lazy) return undefined;
|
|
360
|
+
const cached = toolIndex[serverId];
|
|
361
|
+
return cached && cached.length > 0 ? cached : undefined;
|
|
362
|
+
};
|
|
363
|
+
const recordToolIndex = (serverId: string, tools: readonly McpTool[]): void => {
|
|
364
|
+
if (!toolIndexStore) return;
|
|
365
|
+
toolIndex[serverId] = [...tools];
|
|
366
|
+
toolIndexStore.write(toolIndex);
|
|
367
|
+
};
|
|
368
|
+
const logLazyBoot = (
|
|
369
|
+
serverId: string,
|
|
370
|
+
reason: 'deferred' | 'first-call' | 'no-index',
|
|
371
|
+
toolCount?: number,
|
|
372
|
+
): void => {
|
|
373
|
+
try {
|
|
374
|
+
debug.log('mcp.client', 'lazy-boot', {
|
|
375
|
+
server: serverId,
|
|
376
|
+
reason,
|
|
377
|
+
...(toolCount === undefined ? {} : { toolCount }),
|
|
378
|
+
});
|
|
379
|
+
} catch { /* logger must never throw the boot */ }
|
|
380
|
+
};
|
|
381
|
+
/** 허가 관문 보고 — 지연·즉시 두 경로가 «같은 문면»을 낸다. */
|
|
382
|
+
const reportAuthorization = (serverId: string, tools: readonly { name: string }[]): void => {
|
|
383
|
+
const grantedCount = tools.filter((t) => authorizer.isGranted(serverId, t.name)).length;
|
|
384
|
+
if (tools.length > 0 && grantedCount === 0) {
|
|
385
|
+
logger.warn(
|
|
386
|
+
// ⛔ 접두 «라벨»도 같은 문자열이다 — 본문만 이스케이프하면 개행이 여기로 샌다.
|
|
387
|
+
`[nexus] mcp-client ${JSON.stringify(serverId)}: ${tools.length} tool(s) registered but NONE authorized — every call will be denied. ` +
|
|
388
|
+
// ⛔ 「복사해 붙일 수 있게」라고 말하려면 «붙일 수 있는 것»을 줘야 한다.
|
|
389
|
+
// ⇒ 서버 항목 «전체»를 흉내 내지 말고 ***더할 필드 한 줄***만 준다.
|
|
390
|
+
`Add this field to the ${JSON.stringify(serverId)} entry of mcp.servers in your elanous config: ` +
|
|
391
|
+
`"authorizedTools": [${tools.slice(0, 3).map((t) => JSON.stringify(t.name)).join(', ')}]`,
|
|
392
|
+
);
|
|
393
|
+
} else if (grantedCount < tools.length) {
|
|
394
|
+
logger.warn(
|
|
395
|
+
`[nexus] mcp-client ${JSON.stringify(serverId)}: ${tools.length} tool(s) registered but only ${grantedCount} authorized — unlisted tool calls will be denied.`,
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
debug.log('mcp.authorization', 'boot-summary', {
|
|
399
|
+
serverId,
|
|
400
|
+
toolCount: tools.length,
|
|
401
|
+
grantedCount,
|
|
402
|
+
});
|
|
403
|
+
logger.info(
|
|
404
|
+
`[nexus] mcp-client connected: ${serverId} (${tools.length} tool${tools.length === 1 ? '' : 's'}` +
|
|
405
|
+
`${grantedCount === tools.length ? '' : ` · ${grantedCount} authorized`})`,
|
|
406
|
+
);
|
|
407
|
+
};
|
|
408
|
+
|
|
255
409
|
if (opts.servers.some(spec => spec.transport === 'stdio') && !opts.createClient) {
|
|
256
410
|
try { syncInstalledPluginNodes(elanousStateRoot()); }
|
|
257
411
|
catch (error) { debug.log('graph.kinds', 'installed-sync-failed', { reason: String(error) }); }
|
|
@@ -280,6 +434,45 @@ export async function registerMcpClients(
|
|
|
280
434
|
}
|
|
281
435
|
};
|
|
282
436
|
}
|
|
437
|
+
const announced = lazyToolsFor(spec.id);
|
|
438
|
+
if (lazy && !announced) logLazyBoot(spec.id, 'no-index');
|
|
439
|
+
if (announced) {
|
|
440
|
+
// ⭐ 지연 기동 — 여기서 자식은 «하나도» 안 뜬다. 허가는 즉시 경로와
|
|
441
|
+
// 같은 관문에 미리 넣고, 등록하는 툴은 지난 부팅이 알린 목록 그대로다.
|
|
442
|
+
for (const toolName of spec.authorizedTools ?? []) {
|
|
443
|
+
authorizer.grant({ serverId: spec.id, toolName });
|
|
444
|
+
}
|
|
445
|
+
const deferred = new DeferredMcpClient(client, async () => {
|
|
446
|
+
await withTimeout(`mcp.${spec.id}.start`, () => client!.start(), serverHandshakeTimeoutMs, setTimeoutFn, clearTimeoutFn);
|
|
447
|
+
const live = await withTimeout(
|
|
448
|
+
`mcp.${spec.id}.listTools`,
|
|
449
|
+
() => client!.listTools(),
|
|
450
|
+
serverHandshakeTimeoutMs,
|
|
451
|
+
setTimeoutFn,
|
|
452
|
+
clearTimeoutFn,
|
|
453
|
+
);
|
|
454
|
+
// 이제 자식이 있다 — 리소스 경로·종료 스냅샷이 보는 clients 에 넣는다.
|
|
455
|
+
clients.push(client!);
|
|
456
|
+
recordToolIndex(spec.id, live);
|
|
457
|
+
logLazyBoot(spec.id, 'first-call', live.length);
|
|
458
|
+
}, spec.id);
|
|
459
|
+
deferredClients.push(deferred);
|
|
460
|
+
for (const t of announced) {
|
|
461
|
+
const runtime = createMcpProxyRuntime({
|
|
462
|
+
serverId: spec.id,
|
|
463
|
+
mcpTool: t,
|
|
464
|
+
client: deferred,
|
|
465
|
+
authorizer,
|
|
466
|
+
});
|
|
467
|
+
register(runtime);
|
|
468
|
+
registeredIds.push(runtime.id);
|
|
469
|
+
registered += 1;
|
|
470
|
+
}
|
|
471
|
+
perServer[spec.id] = { status: 'ready', toolCount: announced.length, deferred: true };
|
|
472
|
+
reportAuthorization(spec.id, announced);
|
|
473
|
+
logLazyBoot(spec.id, 'deferred', announced.length);
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
283
476
|
await withTimeout(`mcp.${spec.id}.start`, () => client!.start(), serverHandshakeTimeoutMs, setTimeoutFn, clearTimeoutFn);
|
|
284
477
|
const tools = await withTimeout(
|
|
285
478
|
`mcp.${spec.id}.listTools`,
|
|
@@ -304,37 +497,14 @@ export async function registerMcpClients(
|
|
|
304
497
|
}
|
|
305
498
|
clients.push(client);
|
|
306
499
|
perServer[spec.id] = { status: 'ready', toolCount: tools.length };
|
|
500
|
+
// 콜드 스타트(인덱스 없음) 1회 뒤에는 다음 부팅이 지연 기동할 수 있게 적어 둔다.
|
|
501
|
+
if (lazy) recordToolIndex(spec.id, tools);
|
|
307
502
|
// ⛔⭐ **금지에는 «길»을 붙인다.** 허가 관문은 fail-closed 라 `authorizedTools` 를
|
|
308
503
|
// 안 적은 서버의 툴은 «전부» 거부된다 — 그것이 의도지만, 조용하면 사용자는
|
|
309
504
|
// ***「어제 되던 툴이 오늘 안 된다」***만 겪고 이유도 고치는 법도 모른다.
|
|
310
505
|
// ⇒ 붙었는데 허가가 «하나도 없는» 서버는 이름을 대고 «무엇을 적어야 하는지»까지 말한다.
|
|
311
506
|
// ⚠️ 부팅을 막지는 않는다 — 이 배선의 계약은 「한 서버가 실패해도 계속」이다.
|
|
312
|
-
|
|
313
|
-
if (tools.length > 0 && grantedCount === 0) {
|
|
314
|
-
logger.warn(
|
|
315
|
-
// ⛔ 접두 «라벨»도 같은 문자열이다 — 본문만 이스케이프하면 개행이 여기로 샌다.
|
|
316
|
-
`[nexus] mcp-client ${JSON.stringify(spec.id)}: ${tools.length} tool(s) registered but NONE authorized — every call will be denied. ` +
|
|
317
|
-
// ⛔ 「복사해 붙일 수 있게」라고 말하려면 «붙일 수 있는 것»을 줘야 한다.
|
|
318
|
-
// 초판은 `{"id":…, ..., "authorizedTools":[…]}` 를 줬는데 그 `...` 때문에
|
|
319
|
-
// «유효한 JSON 이 아니었다» — 말과 산출이 어긋났다(리뷰가 잡음).
|
|
320
|
-
// ⇒ 서버 항목 «전체»를 흉내 내지 말고 ***더할 필드 한 줄***만 준다.
|
|
321
|
-
`Add this field to the ${JSON.stringify(spec.id)} entry of mcp.servers in your elanous config: ` +
|
|
322
|
-
`"authorizedTools": [${tools.slice(0, 3).map((t) => JSON.stringify(t.name)).join(', ')}]`,
|
|
323
|
-
);
|
|
324
|
-
} else if (grantedCount < tools.length) {
|
|
325
|
-
logger.warn(
|
|
326
|
-
`[nexus] mcp-client ${JSON.stringify(spec.id)}: ${tools.length} tool(s) registered but only ${grantedCount} authorized — unlisted tool calls will be denied.`,
|
|
327
|
-
);
|
|
328
|
-
}
|
|
329
|
-
debug.log('mcp.authorization', 'boot-summary', {
|
|
330
|
-
serverId: spec.id,
|
|
331
|
-
toolCount: tools.length,
|
|
332
|
-
grantedCount,
|
|
333
|
-
});
|
|
334
|
-
logger.info(
|
|
335
|
-
`[nexus] mcp-client connected: ${spec.id} (${tools.length} tool${tools.length === 1 ? '' : 's'}` +
|
|
336
|
-
`${grantedCount === tools.length ? '' : ` · ${grantedCount} authorized`})`,
|
|
337
|
-
);
|
|
507
|
+
reportAuthorization(spec.id, tools);
|
|
338
508
|
} catch (err) {
|
|
339
509
|
// ⛔⭐ **이 줄은 「방어적 no-op」이 아니다.** try 블록이 등록 «루프»까지 감싸므로,
|
|
340
510
|
// 툴 3개 중 2개까지 `register()` 가 성공한 뒤 3번째가 던지면 ***이미 등록된 두 개가
|
|
@@ -381,6 +551,19 @@ export async function registerMcpClients(
|
|
|
381
551
|
async shutdown() {
|
|
382
552
|
// Snapshot + clear so a re-entrant call (e.g. SIGTERM races) is a no-op.
|
|
383
553
|
const snapshot = clients.splice(0);
|
|
554
|
+
// 아직 «안 뜬» 지연 클라이언트도 여기서 내린다 — 기동 중이면 그 기동을
|
|
555
|
+
// 기다렸다가 내리므로 자식이 새지 않는다. 이미 뜬 것은 snapshot 이 맡는다.
|
|
556
|
+
const pendingDeferred = deferredClients.splice(0).filter((d) => !d.spawned);
|
|
557
|
+
// ⭐ 자식에게 SIGTERM 을 «먼저» 보낸다 — 유예(지연 기동 기본 2500ms)가 지나면
|
|
558
|
+
// SIGKILL 이라 종료 전체가 3초 안에 끝난다. 등록·허가 걷기는 그 뒤.
|
|
559
|
+
const teardown = [
|
|
560
|
+
...snapshot.map((c) =>
|
|
561
|
+
c.dispose().catch(() => {
|
|
562
|
+
/* dispose() is best-effort; swallow */
|
|
563
|
+
}),
|
|
564
|
+
),
|
|
565
|
+
...pendingDeferred.map((d) => d.dispose().catch(() => { /* 아직 안 뜬 클라이언트 */ })),
|
|
566
|
+
];
|
|
384
567
|
for (const spec of opts.servers) authorizer.revokeServer(spec.id);
|
|
385
568
|
// ⭐ 등록도 «되돌린다». 데몬 종료 때는 어차피 프로세스가 죽으니 무해하고,
|
|
386
569
|
// 재장전 때는 ***이 줄이 없으면 다음 등록이 전부 id 충돌로 죽는다***.
|
|
@@ -389,18 +572,60 @@ export async function registerMcpClients(
|
|
|
389
572
|
for (const id of ids) {
|
|
390
573
|
try { unregister(id); } catch { /* best-effort */ }
|
|
391
574
|
}
|
|
392
|
-
await Promise.all(
|
|
393
|
-
snapshot.map((c) =>
|
|
394
|
-
c.dispose().catch(() => {
|
|
395
|
-
/* dispose() is best-effort; swallow */
|
|
396
|
-
}),
|
|
397
|
-
),
|
|
398
|
-
);
|
|
575
|
+
await Promise.all(teardown);
|
|
399
576
|
injectedValuesByServer.clear();
|
|
400
577
|
},
|
|
578
|
+
terminateChildrenSync(): number {
|
|
579
|
+
let signalled = 0;
|
|
580
|
+
for (const child of [...spawnedChildren]) {
|
|
581
|
+
spawnedChildren.delete(child);
|
|
582
|
+
try {
|
|
583
|
+
if (child.exitCode === null && child.signalCode === null && child.kill('SIGTERM')) signalled += 1;
|
|
584
|
+
} catch {
|
|
585
|
+
/* 이미 죽은 자식 — 쏠 대상이 없다 */
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return signalled;
|
|
589
|
+
},
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/** 기본 툴 인덱스 저장소 — `<state>/mcp-tool-index.json`.
|
|
594
|
+
* ⚠️ 읽기·쓰기 모두 «부팅을 막지 않는다»: 깨진 JSON 은 빈 인덱스(콜드 스타트)로
|
|
595
|
+
* 떨어지고, 쓰기 실패는 debug 한 줄만 남긴다. */
|
|
596
|
+
export function defaultMcpToolIndexStore(root: string = elanousStateRoot()): McpToolIndexStore {
|
|
597
|
+
const file = join(root, MCP_TOOL_INDEX_FILENAME);
|
|
598
|
+
return {
|
|
599
|
+
read(): McpToolIndex {
|
|
600
|
+
try {
|
|
601
|
+
const parsed: unknown = JSON.parse(readFileSync(file, 'utf8'));
|
|
602
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {};
|
|
603
|
+
const index: McpToolIndex = {};
|
|
604
|
+
for (const [serverId, tools] of Object.entries(parsed as Record<string, unknown>)) {
|
|
605
|
+
if (!Array.isArray(tools)) continue;
|
|
606
|
+
const kept = tools.filter((tool): tool is McpTool =>
|
|
607
|
+
!!tool && typeof tool === 'object' && typeof (tool as { name?: unknown }).name === 'string');
|
|
608
|
+
if (kept.length > 0) index[serverId] = kept;
|
|
609
|
+
}
|
|
610
|
+
return index;
|
|
611
|
+
} catch { return {}; }
|
|
612
|
+
},
|
|
613
|
+
write(index: McpToolIndex): void {
|
|
614
|
+
try {
|
|
615
|
+
mkdirSync(root, { recursive: true });
|
|
616
|
+
writeFileSync(file, `${JSON.stringify(index, null, 2)}\n`, 'utf8');
|
|
617
|
+
} catch (error) {
|
|
618
|
+
try { debug.log('mcp.client', 'tool-index-write-failed', { reason: String(error) }); }
|
|
619
|
+
catch { /* logger must never throw the boot */ }
|
|
620
|
+
}
|
|
621
|
+
},
|
|
401
622
|
};
|
|
402
623
|
}
|
|
403
624
|
|
|
625
|
+
function readToolIndex(store: McpToolIndexStore): McpToolIndex {
|
|
626
|
+
try { return store.read(); } catch { return {}; }
|
|
627
|
+
}
|
|
628
|
+
|
|
404
629
|
function defaultLogger(): McpBootLogger {
|
|
405
630
|
return {
|
|
406
631
|
info: (line) => console.info(line),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WizardIO } from '../../onboarding.js';
|
|
2
2
|
import type { SetupCheckResult } from '../setup-status.js';
|
|
3
3
|
import type { TailscaleProbe } from './tailscale-probe.js';
|
|
4
|
-
import { createManagementStarterContract } from '../../persona/presets.js';
|
|
4
|
+
import { clonePreset, createManagementStarterContract, type PersonaPreset, type PersonaWriteOptions, type PersonaWriteResult } from '../../persona/presets.js';
|
|
5
5
|
|
|
6
6
|
export interface FirstBootWizardDeps {
|
|
7
7
|
io: WizardIO;
|
|
@@ -39,9 +39,12 @@ export type FirstBootResult =
|
|
|
39
39
|
|
|
40
40
|
/** 직업 질문 답의 정규화 — «1»·«경영»·«management» 는 경영,
|
|
41
41
|
* 나머지(빈 답 포함)는 일반(현재 첫 실행 동작 유지). */
|
|
42
|
-
export
|
|
42
|
+
export type OccupationChoice = 'management' | 'marketing' | 'general';
|
|
43
|
+
|
|
44
|
+
export function normalizeOccupationChoice(input: string): OccupationChoice {
|
|
43
45
|
const v = input.trim().toLowerCase();
|
|
44
46
|
if (v === '1' || v === '경영' || v === 'management') return 'management';
|
|
47
|
+
if (v === '3' || v === '마케팅' || v === 'marketing') return 'marketing';
|
|
45
48
|
return 'general';
|
|
46
49
|
}
|
|
47
50
|
|
|
@@ -108,6 +111,45 @@ function printPwaSetupBanner(deps: FirstBootWizardDeps): void {
|
|
|
108
111
|
deps.io.print('');
|
|
109
112
|
}
|
|
110
113
|
|
|
114
|
+
/** 0.2.35 PERSONA-STARTER-FU — 첫 실행 «마케팅» 스타터 계약 원본. 경계 계약상
|
|
115
|
+
* 완료 경계 코드(first-boot-wizard.ts) 안에서 기존 clonePreset 파이프라인으로
|
|
116
|
+
* persona store 에 정확히 한 장 쓴다. */
|
|
117
|
+
const MARKETING_STARTER_PRESET: PersonaPreset = {
|
|
118
|
+
personaId: 'starter-marketing',
|
|
119
|
+
displayName: '마케팅 스타터',
|
|
120
|
+
names: ['마케팅 스타터', '마케팅', 'starter-marketing'],
|
|
121
|
+
role: '마케팅 파트너',
|
|
122
|
+
title: '첫 실행 스타터',
|
|
123
|
+
oneLine: '고객·메시지·채널을 같이 세우는 짝.',
|
|
124
|
+
voice: {
|
|
125
|
+
rule: '짧고 단정하게 — 고객 말로 먼저, 근거 한 줄.',
|
|
126
|
+
examples: [
|
|
127
|
+
'이번 주 메시지는 하나로 좁힙니다 — 첫 화면에서 5초 안에 남는 문장.',
|
|
128
|
+
'그 채널은 도달 근거가 부족합니다 — 가장 싼 실험부터 하시죠.',
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
tasks: [
|
|
132
|
+
{ when: '아침 루프', what: '채널 반응·미결 발행물을 한 화면에 모아 첫 판단을 준다' },
|
|
133
|
+
{ when: '메시지가 갈릴 때', what: '후보 문장을 셋으로 좁혀 고객·채널·되돌림 수단을 나란히 놓는다' },
|
|
134
|
+
{ when: '주간 정산', what: '지난 발행과 실제 반응을 대조해 다음 메시지 기준을 고친다' },
|
|
135
|
+
],
|
|
136
|
+
tools: [],
|
|
137
|
+
firstQuestions: [
|
|
138
|
+
'지금 가장 급한 고객 메시지는 무엇인가요?',
|
|
139
|
+
'이번 주에 꼭 내보낼 채널이 있나요?',
|
|
140
|
+
],
|
|
141
|
+
doesNot: [
|
|
142
|
+
'고객 개인정보를 외부에 전송하지 않는다',
|
|
143
|
+
'합의되지 않은 광고·발행을 대신 실행하지 않는다',
|
|
144
|
+
],
|
|
145
|
+
forWhom: '처음 elanous 를 여는 마케터 — 고객·메시지·채널을 함께 시작하려는 사람.',
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/** 첫 실행 «마케팅» 선택이 부르는 유일한 제작 입구 — 스타터 계약 한 장을 persona store 에 쓴다. */
|
|
149
|
+
export function createMarketingStarterContract(opts: PersonaWriteOptions = {}): PersonaWriteResult {
|
|
150
|
+
return clonePreset(MARKETING_STARTER_PRESET, MARKETING_STARTER_PRESET.displayName, opts);
|
|
151
|
+
}
|
|
152
|
+
|
|
111
153
|
/** 0.2.29 PERSONA-STARTER — 직업 질문. «경영»이면 경영 스타터 계약 한 장을
|
|
112
154
|
* 만들고, 일반이면 계약 없이 현재 흐름 그대로. 계약 생성이 실패해도
|
|
113
155
|
* wizard 결과는 completed 로 유지한다(fail-soft). */
|
|
@@ -120,20 +162,26 @@ async function askOccupationAndCreateStarter(
|
|
|
120
162
|
io.print('');
|
|
121
163
|
io.print(' 어떤 일을 하세요? 고르면 스타터 계약 한 장을 만듭니다.');
|
|
122
164
|
io.print(' 1) 경영 — 방향·판단·운영을 함께 세우는 경영 스타터');
|
|
165
|
+
io.print(' 3) 마케팅 — 고객·메시지·채널을 함께 세우는 마케팅 스타터');
|
|
123
166
|
io.print(' 2) 일반 — 지금처럼 계속 (스타터 계약 없이)');
|
|
124
167
|
let answer: string;
|
|
125
168
|
try {
|
|
126
|
-
answer = await io.ask(' 선택 (1/2 · Enter=일반): ');
|
|
169
|
+
answer = await io.ask(' 선택 (1/2/3 · Enter=일반): ');
|
|
127
170
|
} catch (err) {
|
|
128
171
|
out.error(`first-boot wizard: occupation question failed: ${(err as Error).message}`);
|
|
129
172
|
return undefined;
|
|
130
173
|
}
|
|
131
|
-
|
|
174
|
+
const choice = normalizeOccupationChoice(answer);
|
|
175
|
+
if (choice === 'general') return undefined;
|
|
132
176
|
try {
|
|
133
|
-
const written =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
177
|
+
const written = choice === 'management'
|
|
178
|
+
? createManagementStarterContract(
|
|
179
|
+
deps.starterContractDir ? { dir: deps.starterContractDir } : {},
|
|
180
|
+
)
|
|
181
|
+
: createMarketingStarterContract(
|
|
182
|
+
deps.starterContractDir ? { dir: deps.starterContractDir } : {},
|
|
183
|
+
);
|
|
184
|
+
io.print(` ✓ ${choice === 'management' ? '경영' : '마케팅'} 스타터 계약이 만들어졌습니다: ${written.path}`);
|
|
137
185
|
return { personaId: written.personaId, displayName: written.displayName, path: written.path };
|
|
138
186
|
} catch (err) {
|
|
139
187
|
out.error(`first-boot wizard: starter contract failed: ${(err as Error).message}`);
|
package/src/oauth/codex.ts
CHANGED
|
@@ -458,6 +458,10 @@ export async function loadFreshCodexAuthState(
|
|
|
458
458
|
});
|
|
459
459
|
return state;
|
|
460
460
|
}
|
|
461
|
+
if (process.env.ELANOUS_REMOTE_CODEX_ACCESS_ONLY === '1') {
|
|
462
|
+
observeCodexAuth('no-credential', { storeKey: account.storeKey, mirrorPath: mirrorPath ?? null, reason: 'access-only-expiring' });
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
461
465
|
observeCodexAuth('refresh-start', {
|
|
462
466
|
storeKey: account.storeKey, remainingSeconds: remainingSeconds(state),
|
|
463
467
|
mirrorPath: mirrorPath ?? null, bufferMs: CODEX_REFRESH_BUFFER_MS,
|
|
@@ -602,6 +606,9 @@ export async function refreshCodexAccountHome(
|
|
|
602
606
|
now?: () => number;
|
|
603
607
|
} = {},
|
|
604
608
|
): Promise<CodexAccountRefreshResult> {
|
|
609
|
+
if (process.env.ELANOUS_REMOTE_CODEX_ACCESS_ONLY === '1') {
|
|
610
|
+
return { ok: false, kind: 'no-tokens', message: '원격 access 미러는 refresh 권한이 없다' };
|
|
611
|
+
}
|
|
605
612
|
// ⛔ The CEO's default account (~/.codex) is shared with the official CLI — refreshing it here
|
|
606
613
|
// rotates the refresh token out from under that CLI. Named accounts only.
|
|
607
614
|
if (name === DEFAULT_CODEX_ACCOUNT) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as readline from 'node:readline/promises';
|
|
2
2
|
import { detectProviders, type DetectedProvider } from '../llm/provider-detect.js';
|
|
3
3
|
import { debug } from '../debug/log.js';
|
|
4
|
+
import { detectLocale, type Locale } from '../expression/locale.js';
|
|
4
5
|
import { unattendedNextStepLine } from './entry-hints.js';
|
|
5
6
|
import { resolveProviderCredential } from '../llm/provider-credentials.js';
|
|
6
7
|
import {
|
|
@@ -13,6 +14,8 @@ export interface FirstRunDeps {
|
|
|
13
14
|
path?: string;
|
|
14
15
|
detectProviders?: () => Promise<DetectedProvider[]>;
|
|
15
16
|
isTTY?: boolean;
|
|
17
|
+
/** Locale for user-facing wording; defaults to the shared ambient decision (detectLocale). */
|
|
18
|
+
locale?: Locale;
|
|
16
19
|
chooseProvider?: (detected: readonly LLMProviderName[]) => Promise<LLMProviderName | null>;
|
|
17
20
|
print?: (message: string) => void;
|
|
18
21
|
saveConfig?: (config: UserConfig, path: string) => void;
|
|
@@ -44,12 +47,21 @@ export function parseMenuAnswer(answer: string, choices: readonly LLMProviderNam
|
|
|
44
47
|
return provider !== undefined ? { kind: 'chosen', provider } : { kind: 'miss' };
|
|
45
48
|
}
|
|
46
49
|
|
|
50
|
+
/**
|
|
51
|
+
* The fixed choice line of the first-run menu (`1 Codex, 2 Grok, 3 Claude`).
|
|
52
|
+
* Single source of the wording: the prompt below renders it, and the ux-sim
|
|
53
|
+
* first-run device asserts against it, so a wording change cannot drift apart.
|
|
54
|
+
*/
|
|
55
|
+
export function formatProviderMenu(choices: readonly LLMProviderName[]): string {
|
|
56
|
+
return choices.map((name, i) => `${i + 1} ${CHOICE_LABEL[name] ?? name}`).join(', ');
|
|
57
|
+
}
|
|
58
|
+
|
|
47
59
|
export async function promptProviderMenu(
|
|
48
60
|
ask: (prompt: string) => Promise<string>,
|
|
49
61
|
detected: readonly LLMProviderName[] = [],
|
|
50
62
|
): Promise<LLMProviderName | null> {
|
|
51
63
|
const choices = orderProviderChoices(detected);
|
|
52
|
-
const menu = choices
|
|
64
|
+
const menu = formatProviderMenu(choices);
|
|
53
65
|
for (;;) {
|
|
54
66
|
const parsed = parseMenuAnswer(await ask(`Choose LLM (${menu}; Enter to cancel): `), choices);
|
|
55
67
|
if (parsed.kind === 'chosen') return parsed.provider;
|
|
@@ -66,7 +78,23 @@ async function chooseProvider(detected: readonly LLMProviderName[] = []): Promis
|
|
|
66
78
|
}
|
|
67
79
|
}
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
/** User-facing first-run fallback wording, routed by the shared locale decision (detectLocale). */
|
|
82
|
+
const FIRST_RUN_TEXT = {
|
|
83
|
+
ko: {
|
|
84
|
+
detectedPrefix: '감지: ',
|
|
85
|
+
subscription: ' 구독',
|
|
86
|
+
needsLlm: 'eln setup llm 으로 고르세요',
|
|
87
|
+
claudeNoPath: 'claude-code 구독은 구독으로 쓸 수 있는 경로가 없어 자동 선택하지 않음',
|
|
88
|
+
multipleDetected: '둘 이상 감지되어 고르세요',
|
|
89
|
+
},
|
|
90
|
+
en: {
|
|
91
|
+
detectedPrefix: 'detected: ',
|
|
92
|
+
subscription: ' subscription',
|
|
93
|
+
needsLlm: 'pick a provider via eln setup llm',
|
|
94
|
+
claudeNoPath: 'claude-code subscription has no usable path in elanous; not auto-selecting',
|
|
95
|
+
multipleDetected: 'more than one detected; pick one',
|
|
96
|
+
},
|
|
97
|
+
} as const;
|
|
70
98
|
|
|
71
99
|
export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
|
|
72
100
|
outcome: 'ready' | 'needs-llm' | 'cancelled'; provider?: string; inputs: number;
|
|
@@ -74,6 +102,9 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
|
|
|
74
102
|
const path = deps.path ?? userConfigPath();
|
|
75
103
|
const cfg = deps.config ?? getUserConfig(path);
|
|
76
104
|
const print = deps.print ?? console.log;
|
|
105
|
+
const text = FIRST_RUN_TEXT[(deps.locale ?? detectLocale()) === 'en' ? 'en' : 'ko'];
|
|
106
|
+
const detectionLabel = (provider: string) =>
|
|
107
|
+
`${provider === 'openai-codex' ? 'codex' : provider}${text.subscription}`;
|
|
77
108
|
let detected: DetectedProvider[] = [];
|
|
78
109
|
try { detected = await (deps.detectProviders ?? detectProviders)(); }
|
|
79
110
|
catch { /* Detection is advisory; a TTY can still choose. */ }
|
|
@@ -93,9 +124,9 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
|
|
|
93
124
|
// claude-code is detected but has no subscription path in elanous: mapping it to the 'anthropic'
|
|
94
125
|
// API-key provider would save a provider whose first call fails for a subscription-only user.
|
|
95
126
|
const usable = SUBSCRIPTION_PRIORITY.filter((name) => providers.includes(name));
|
|
96
|
-
const detectionLine = (outcome: string) =>
|
|
127
|
+
const detectionLine = (outcome: string) => `${text.detectedPrefix}${providers.map(detectionLabel).join(' · ')} → ${outcome}`;
|
|
97
128
|
const needsLlm = (inputs: number, extra: string[] = []) => {
|
|
98
|
-
print(
|
|
129
|
+
print(text.needsLlm);
|
|
99
130
|
for (const line of extra) print(line);
|
|
100
131
|
observe('needs-llm', inputs);
|
|
101
132
|
return { outcome: 'needs-llm' as const, inputs };
|
|
@@ -106,8 +137,8 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
|
|
|
106
137
|
if (!provider) {
|
|
107
138
|
if (providers.length > 0) {
|
|
108
139
|
print(detectionLine(usable.length === 0
|
|
109
|
-
?
|
|
110
|
-
:
|
|
140
|
+
? text.claudeNoPath
|
|
141
|
+
: text.multipleDetected));
|
|
111
142
|
}
|
|
112
143
|
if ((deps.isTTY ?? process.stdin.isTTY) !== true) {
|
|
113
144
|
// FIRST-CHAT-NONTTY — bare `elanous` with no TTY gets the same one-line next step as the other entrances.
|