@redscope-ai/redscope 1.0.0
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/README.md +224 -0
- package/dist/chunk-090920rk.js +288 -0
- package/dist/chunk-0afb2r78.js +141 -0
- package/dist/chunk-0d4ekx1g.js +73 -0
- package/dist/chunk-0g6nwbhq.js +15 -0
- package/dist/chunk-0qj905nt.js +18 -0
- package/dist/chunk-0s5btnn1.js +186 -0
- package/dist/chunk-0s8fars0.js +91 -0
- package/dist/chunk-10ev3dvh.js +312 -0
- package/dist/chunk-10k5jfc5.js +1295 -0
- package/dist/chunk-12tspwqa.js +240 -0
- package/dist/chunk-13qesvnw.js +17 -0
- package/dist/chunk-143eh1e0.js +121 -0
- package/dist/chunk-14p6wvsq.js +39 -0
- package/dist/chunk-19f3zb1m.js +342 -0
- package/dist/chunk-1a5cep8h.js +145 -0
- package/dist/chunk-1abw9kkn.js +34 -0
- package/dist/chunk-1aer7c78.js +118 -0
- package/dist/chunk-1dazz4g6.js +154 -0
- package/dist/chunk-1fcf4ty1.js +142 -0
- package/dist/chunk-1gnxhyf8.js +62 -0
- package/dist/chunk-1he3944e.js +8124 -0
- package/dist/chunk-1jpayz7y.js +952 -0
- package/dist/chunk-1qd6f6vk.js +269 -0
- package/dist/chunk-1v0kpe62.js +2547 -0
- package/dist/chunk-1w20m7gw.js +445 -0
- package/dist/chunk-1y7kp51j.js +72 -0
- package/dist/chunk-1ycb5sxt.js +247 -0
- package/dist/chunk-1zbwhcbt.js +1124 -0
- package/dist/chunk-20psem54.js +116 -0
- package/dist/chunk-23h69r5b.js +30 -0
- package/dist/chunk-23x86ptv.js +473 -0
- package/dist/chunk-24fyv3jz.js +378 -0
- package/dist/chunk-24kv69g3.js +97 -0
- package/dist/chunk-2azx8zsc.js +125 -0
- package/dist/chunk-2d1gwzz9.js +524 -0
- package/dist/chunk-2g0ytd9d.js +29058 -0
- package/dist/chunk-2hfp9kat.js +21 -0
- package/dist/chunk-2j875eq6.js +37 -0
- package/dist/chunk-2kcgxnvp.js +39 -0
- package/dist/chunk-2kz09j2s.js +23 -0
- package/dist/chunk-2mwnwp0n.js +17 -0
- package/dist/chunk-2p1cqhcn.js +921 -0
- package/dist/chunk-2p369q9z.js +61 -0
- package/dist/chunk-2rf6asgf.js +151 -0
- package/dist/chunk-2vr7mqx1.js +384 -0
- package/dist/chunk-2xcg933e.js +205 -0
- package/dist/chunk-2ypwckbz.js +40310 -0
- package/dist/chunk-30wnahyg.js +626 -0
- package/dist/chunk-326zehp8.js +204 -0
- package/dist/chunk-32s6jzgw.js +183 -0
- package/dist/chunk-35yzt1a7.js +202 -0
- package/dist/chunk-38frkej6.js +62 -0
- package/dist/chunk-3abaq08g.js +34 -0
- package/dist/chunk-3h59ttr5.js +32 -0
- package/dist/chunk-3nk9q8dr.js +154 -0
- package/dist/chunk-3prrxevm.js +224 -0
- package/dist/chunk-3tv8p9xw.js +127 -0
- package/dist/chunk-3txyekes.js +19 -0
- package/dist/chunk-3vfxjn7g.js +19 -0
- package/dist/chunk-3w9sye8h.js +81 -0
- package/dist/chunk-3y69j7y8.js +24 -0
- package/dist/chunk-3zwjpkjh.js +1603 -0
- package/dist/chunk-40t1d75v.js +3442 -0
- package/dist/chunk-470kmby4.js +318 -0
- package/dist/chunk-47jc141z.js +335 -0
- package/dist/chunk-48rz50ct.js +868 -0
- package/dist/chunk-49wv03ts.js +232 -0
- package/dist/chunk-4a189mn2.js +103 -0
- package/dist/chunk-4c4fmh7a.js +15 -0
- package/dist/chunk-4ct8dsj5.js +49 -0
- package/dist/chunk-4kqt1pm1.js +100 -0
- package/dist/chunk-4ng0xy0e.js +802 -0
- package/dist/chunk-4spgkgr3.js +43 -0
- package/dist/chunk-4tjdwtyy.js +19 -0
- package/dist/chunk-4tr60273.js +370 -0
- package/dist/chunk-4vnaeng5.js +29 -0
- package/dist/chunk-4wbqpeaw.js +871 -0
- package/dist/chunk-4wgkv3fv.js +1140 -0
- package/dist/chunk-4yjskjb6.js +40 -0
- package/dist/chunk-50m3a23z.js +35 -0
- package/dist/chunk-511f79az.js +182 -0
- package/dist/chunk-51sgztvv.js +161 -0
- package/dist/chunk-563fcpv1.js +290 -0
- package/dist/chunk-564cnq6v.js +735 -0
- package/dist/chunk-569r8cxc.js +31 -0
- package/dist/chunk-570x55d4.js +12 -0
- package/dist/chunk-571556cm.js +80 -0
- package/dist/chunk-59t4c56e.js +63 -0
- package/dist/chunk-5axjhkma.js +36 -0
- package/dist/chunk-5b188q5e.js +157 -0
- package/dist/chunk-5dmn1865.js +439 -0
- package/dist/chunk-5ks4829r.js +267 -0
- package/dist/chunk-5mmhfbxb.js +1078 -0
- package/dist/chunk-5rdt14hy.js +742 -0
- package/dist/chunk-5ssryexj.js +121 -0
- package/dist/chunk-5v95pnq4.js +15 -0
- package/dist/chunk-5xvjt2t9.js +68 -0
- package/dist/chunk-5zyq6t1q.js +118 -0
- package/dist/chunk-60fkafk2.js +15 -0
- package/dist/chunk-62fjkf5q.js +46 -0
- package/dist/chunk-64gazrrb.js +8067 -0
- package/dist/chunk-65tq2yjx.js +126 -0
- package/dist/chunk-65zbgg1n.js +14 -0
- package/dist/chunk-66v8mty3.js +264 -0
- package/dist/chunk-6acx5heq.js +292 -0
- package/dist/chunk-6hr7742d.js +61 -0
- package/dist/chunk-6hygvrhn.js +143 -0
- package/dist/chunk-6kjh280m.js +128 -0
- package/dist/chunk-6s0q1s5r.js +66 -0
- package/dist/chunk-6x35ffpx.js +690 -0
- package/dist/chunk-71jfy1hh.js +570 -0
- package/dist/chunk-71sdcaq6.js +15 -0
- package/dist/chunk-754qdxs5.js +92 -0
- package/dist/chunk-79v5bkj4.js +1176 -0
- package/dist/chunk-7br0w7j5.js +151 -0
- package/dist/chunk-7cjgrzz1.js +298 -0
- package/dist/chunk-7d41ks0y.js +133 -0
- package/dist/chunk-7f40pmtr.js +71 -0
- package/dist/chunk-7g15x8hm.js +131 -0
- package/dist/chunk-7gtnzdet.js +120 -0
- package/dist/chunk-7h0z4aqx.js +702 -0
- package/dist/chunk-7h7e5a7d.js +25 -0
- package/dist/chunk-7m2cznwr.js +40 -0
- package/dist/chunk-7nvday0n.js +252 -0
- package/dist/chunk-7qey87th.js +145 -0
- package/dist/chunk-7qx3xhv3.js +9076 -0
- package/dist/chunk-7tfdhkpy.js +61 -0
- package/dist/chunk-80m511j6.js +121 -0
- package/dist/chunk-80ysxfe9.js +784 -0
- package/dist/chunk-8375zk8t.js +17200 -0
- package/dist/chunk-85bpkyy9.js +412 -0
- package/dist/chunk-85tcn547.js +876 -0
- package/dist/chunk-85vqgbc8.js +13 -0
- package/dist/chunk-86626jb4.js +49 -0
- package/dist/chunk-87ms17f6.js +444 -0
- package/dist/chunk-87mz239c.js +118 -0
- package/dist/chunk-89vdzt4e.js +254 -0
- package/dist/chunk-89z3e99z.js +159 -0
- package/dist/chunk-8cwrz1dd.js +1806 -0
- package/dist/chunk-8gv2pjby.js +21 -0
- package/dist/chunk-8hdevr3s.js +140 -0
- package/dist/chunk-8hdsk6qc.js +710 -0
- package/dist/chunk-8kct9arg.js +724 -0
- package/dist/chunk-8kf8h7xf.js +23 -0
- package/dist/chunk-8qed8ymj.js +605 -0
- package/dist/chunk-8sdgr592.js +101 -0
- package/dist/chunk-8we9w8pw.js +111 -0
- package/dist/chunk-8xnm5637.js +72 -0
- package/dist/chunk-8y3q0eqy.js +67 -0
- package/dist/chunk-8yvsnrkr.js +3449 -0
- package/dist/chunk-8zz4z1q3.js +42 -0
- package/dist/chunk-90eyff3k.js +119 -0
- package/dist/chunk-92bjkrf2.js +121 -0
- package/dist/chunk-92zrc7c6.js +327 -0
- package/dist/chunk-935nrvdb.js +13 -0
- package/dist/chunk-94pfyv6a.js +48 -0
- package/dist/chunk-9568p8se.js +115 -0
- package/dist/chunk-96km1ywr.js +37 -0
- package/dist/chunk-980bg4w4.js +163 -0
- package/dist/chunk-9a9g5hbj.js +205 -0
- package/dist/chunk-9cm4725d.js +4395 -0
- package/dist/chunk-9ds3vzq8.js +847 -0
- package/dist/chunk-9ffc9n60.js +618 -0
- package/dist/chunk-9fstrwv2.js +184 -0
- package/dist/chunk-9gt0g0qe.js +153 -0
- package/dist/chunk-9h9k5vz3.js +2761 -0
- package/dist/chunk-9he8bmhy.js +17 -0
- package/dist/chunk-9hn8e6h1.js +12 -0
- package/dist/chunk-9j0n3g8e.js +179 -0
- package/dist/chunk-9j6pa3ft.js +251 -0
- package/dist/chunk-9jpg9dn7.js +122 -0
- package/dist/chunk-9mycnwj5.js +46 -0
- package/dist/chunk-9npy2c17.js +517 -0
- package/dist/chunk-9p6sec8n.js +34 -0
- package/dist/chunk-9pnym83h.js +4584 -0
- package/dist/chunk-9skwrnd2.js +25 -0
- package/dist/chunk-9tsfaqr8.js +459 -0
- package/dist/chunk-9tsw3cqv.js +5924 -0
- package/dist/chunk-9w6ckyk4.js +49 -0
- package/dist/chunk-a15bwzv6.js +147 -0
- package/dist/chunk-a9t6cp69.js +28 -0
- package/dist/chunk-ad2yk19p.js +102 -0
- package/dist/chunk-ad4cw4nw.js +336 -0
- package/dist/chunk-ad69fbsk.js +347 -0
- package/dist/chunk-ae76ded0.js +30 -0
- package/dist/chunk-aeysytks.js +216 -0
- package/dist/chunk-ag81m9bq.js +61 -0
- package/dist/chunk-ahx7gp6r.js +4448 -0
- package/dist/chunk-aj4tk4tk.js +23 -0
- package/dist/chunk-an82t9jc.js +104 -0
- package/dist/chunk-apg95qd7.js +1393 -0
- package/dist/chunk-aq5n2adz.js +27 -0
- package/dist/chunk-aw4s3a99.js +208 -0
- package/dist/chunk-awgdfggg.js +14 -0
- package/dist/chunk-ayymxgn1.js +164 -0
- package/dist/chunk-azbab59e.js +637 -0
- package/dist/chunk-azdxq2a3.js +293 -0
- package/dist/chunk-b0tjx3k1.js +523 -0
- package/dist/chunk-b5pp4g2g.js +371 -0
- package/dist/chunk-b5zm8dt6.js +26 -0
- package/dist/chunk-bcnye5a0.js +109 -0
- package/dist/chunk-beqz3k49.js +190 -0
- package/dist/chunk-bf906wpw.js +147 -0
- package/dist/chunk-bgan4cpf.js +13 -0
- package/dist/chunk-bhzp13h7.js +1178 -0
- package/dist/chunk-bk403kpw.js +142 -0
- package/dist/chunk-bmq4c135.js +489 -0
- package/dist/chunk-bprbeda7.js +35 -0
- package/dist/chunk-bst7czdd.js +888 -0
- package/dist/chunk-bths4xgn.js +111 -0
- package/dist/chunk-btjn3qby.js +13 -0
- package/dist/chunk-bwb1vxnt.js +120 -0
- package/dist/chunk-bxa6tw4m.js +643 -0
- package/dist/chunk-bxfjr8qb.js +27 -0
- package/dist/chunk-bxpzhrej.js +73 -0
- package/dist/chunk-bzyzrq0k.js +51 -0
- package/dist/chunk-c0k7b0jw.js +4265 -0
- package/dist/chunk-c17f0h2s.js +16 -0
- package/dist/chunk-c1yc761e.js +6748 -0
- package/dist/chunk-c5g9shkw.js +298 -0
- package/dist/chunk-c696122m.js +69 -0
- package/dist/chunk-c92b3yxx.js +109 -0
- package/dist/chunk-c9aqz56y.js +143 -0
- package/dist/chunk-cba7c5w3.js +345 -0
- package/dist/chunk-cbcxbbe6.js +6543 -0
- package/dist/chunk-cdfjb87h.js +11 -0
- package/dist/chunk-ce8zjt1y.js +136 -0
- package/dist/chunk-cep7e37k.js +22740 -0
- package/dist/chunk-chs5qm8d.js +258 -0
- package/dist/chunk-ckydq33g.js +144 -0
- package/dist/chunk-cnge6wpj.js +514 -0
- package/dist/chunk-cpnsvqf1.js +13 -0
- package/dist/chunk-cqqebkv4.js +32 -0
- package/dist/chunk-cvqpp7dk.js +627 -0
- package/dist/chunk-cwc33j40.js +65 -0
- package/dist/chunk-cypvrq2a.js +155 -0
- package/dist/chunk-d1ha0swn.js +475 -0
- package/dist/chunk-d2an0138.js +35 -0
- package/dist/chunk-d2tt72ck.js +343 -0
- package/dist/chunk-d6wvcqrw.js +9507 -0
- package/dist/chunk-d7ys2kka.js +991 -0
- package/dist/chunk-dbts5q5p.js +122 -0
- package/dist/chunk-dct29ggs.js +295 -0
- package/dist/chunk-de0qnnf7.js +1059 -0
- package/dist/chunk-dep72ce4.js +513 -0
- package/dist/chunk-dgpvgy8x.js +47 -0
- package/dist/chunk-dhhd7dtc.js +20 -0
- package/dist/chunk-dhzpmxv6.js +594 -0
- package/dist/chunk-djes4da7.js +413 -0
- package/dist/chunk-dnhv3vx7.js +166 -0
- package/dist/chunk-dqtvafan.js +2365 -0
- package/dist/chunk-dr4a3tcp.js +60 -0
- package/dist/chunk-dz2xk9kb.js +100 -0
- package/dist/chunk-dz7nc6rf.js +15 -0
- package/dist/chunk-e3abfxpy.js +1486 -0
- package/dist/chunk-e3cq9z89.js +85 -0
- package/dist/chunk-e3j7m7k2.js +642 -0
- package/dist/chunk-e4dsy4g1.js +9951 -0
- package/dist/chunk-e5592pnn.js +197 -0
- package/dist/chunk-e55hdegh.js +129 -0
- package/dist/chunk-e5r5r04e.js +1030 -0
- package/dist/chunk-e60zztbt.js +442 -0
- package/dist/chunk-e7qq6vn0.js +372 -0
- package/dist/chunk-e9aat7xw.js +80 -0
- package/dist/chunk-e9d5v3zs.js +143 -0
- package/dist/chunk-eax32zk4.js +87 -0
- package/dist/chunk-ebfwmbx1.js +117 -0
- package/dist/chunk-ec71pb8t.js +971 -0
- package/dist/chunk-eemjb825.js +17252 -0
- package/dist/chunk-ees8xdhd.js +256 -0
- package/dist/chunk-eewg66y1.js +112 -0
- package/dist/chunk-eg22v12d.js +266 -0
- package/dist/chunk-enzzk67f.js +313 -0
- package/dist/chunk-eskhp70f.js +117 -0
- package/dist/chunk-ewx6z4g8.js +55 -0
- package/dist/chunk-eyvx461k.js +76 -0
- package/dist/chunk-eztq2b5f.js +94 -0
- package/dist/chunk-f0ffwzdd.js +321 -0
- package/dist/chunk-f80n68mf.js +119 -0
- package/dist/chunk-fae2hjxp.js +99 -0
- package/dist/chunk-fbtfp370.js +60 -0
- package/dist/chunk-fc6ndtgf.js +94 -0
- package/dist/chunk-fdwabr8p.js +13870 -0
- package/dist/chunk-fejeqe61.js +785 -0
- package/dist/chunk-fh0d6mvk.js +168 -0
- package/dist/chunk-fh19zcaf.js +304 -0
- package/dist/chunk-fh8bd39r.js +186 -0
- package/dist/chunk-fj2ebbpn.js +33 -0
- package/dist/chunk-fjn632v7.js +194 -0
- package/dist/chunk-fncpkzs5.js +1389 -0
- package/dist/chunk-fpd1gpt8.js +332 -0
- package/dist/chunk-fq9snrnh.js +295 -0
- package/dist/chunk-fqcfzg3j.js +207 -0
- package/dist/chunk-ftt3vqj2.js +1919 -0
- package/dist/chunk-g06pm4n9.js +395 -0
- package/dist/chunk-g4m5pf4g.js +8 -0
- package/dist/chunk-g72h52y6.js +36 -0
- package/dist/chunk-g79ej71s.js +1627 -0
- package/dist/chunk-g7fwk59d.js +19 -0
- package/dist/chunk-g9jnkrtm.js +663 -0
- package/dist/chunk-g9vg5d7t.js +38 -0
- package/dist/chunk-ga1jkyqy.js +1636 -0
- package/dist/chunk-gaaap2nk.js +676 -0
- package/dist/chunk-gc6erq5q.js +483 -0
- package/dist/chunk-gjrcmf0a.js +752 -0
- package/dist/chunk-gmdy2w3z.js +238999 -0
- package/dist/chunk-gsz4yrrk.js +81 -0
- package/dist/chunk-gy47rjy8.js +3830 -0
- package/dist/chunk-h12a4f4x.js +11 -0
- package/dist/chunk-h1yratmg.js +725 -0
- package/dist/chunk-h9y0jnsy.js +155 -0
- package/dist/chunk-hbhs3mwy.js +133 -0
- package/dist/chunk-hbs8cmb4.js +8 -0
- package/dist/chunk-hdk0t1ht.js +940 -0
- package/dist/chunk-hef8dx4s.js +178 -0
- package/dist/chunk-hgsca8mt.js +381 -0
- package/dist/chunk-hhsxm2yr.js +67 -0
- package/dist/chunk-hj5tzzpd.js +39 -0
- package/dist/chunk-hjxqmtg5.js +94 -0
- package/dist/chunk-hn4w9pkj.js +68 -0
- package/dist/chunk-hnprkjgp.js +25 -0
- package/dist/chunk-hq3n5ex7.js +183 -0
- package/dist/chunk-hqjspfma.js +158 -0
- package/dist/chunk-hqxp6b72.js +1198 -0
- package/dist/chunk-hs6nrmq6.js +94 -0
- package/dist/chunk-hwba5xdc.js +267 -0
- package/dist/chunk-hy566ev3.js +430 -0
- package/dist/chunk-hzmzwte2.js +153 -0
- package/dist/chunk-hzxzvzw8.js +274 -0
- package/dist/chunk-j139fzgs.js +114 -0
- package/dist/chunk-j1mep9ck.js +62 -0
- package/dist/chunk-j3xveeg4.js +273 -0
- package/dist/chunk-j5y1s11j.js +100 -0
- package/dist/chunk-j9475b46.js +26 -0
- package/dist/chunk-j9rgqs8m.js +1192 -0
- package/dist/chunk-jccjaddz.js +74 -0
- package/dist/chunk-jdkwfy9e.js +35 -0
- package/dist/chunk-jdqp0r4h.js +6157 -0
- package/dist/chunk-jdzk4zwn.js +587 -0
- package/dist/chunk-jfafmkte.js +49 -0
- package/dist/chunk-jg3r989b.js +16 -0
- package/dist/chunk-jhtccjc9.js +54 -0
- package/dist/chunk-jj2ff1pr.js +688 -0
- package/dist/chunk-jmv7k0jn.js +37 -0
- package/dist/chunk-jmxzmwpw.js +65 -0
- package/dist/chunk-jnjxdqyr.js +353 -0
- package/dist/chunk-jsbbez9j.js +138 -0
- package/dist/chunk-jvpt2dc0.js +424 -0
- package/dist/chunk-jwd7cka0.js +34 -0
- package/dist/chunk-jy5er3st.js +15 -0
- package/dist/chunk-jyby79z5.js +121 -0
- package/dist/chunk-jzyr6j5n.js +332 -0
- package/dist/chunk-k49xc781.js +63 -0
- package/dist/chunk-k7dt2g4a.js +41 -0
- package/dist/chunk-k7hexw3v.js +969 -0
- package/dist/chunk-k7wwkraa.js +117 -0
- package/dist/chunk-kb3758f7.js +51 -0
- package/dist/chunk-kc67kt75.js +3119 -0
- package/dist/chunk-kdhmfxmh.js +3149 -0
- package/dist/chunk-kejdd6zc.js +51 -0
- package/dist/chunk-kekrjeem.js +402 -0
- package/dist/chunk-kez5r0zz.js +280 -0
- package/dist/chunk-kfsvcs5t.js +75 -0
- package/dist/chunk-khtvffc4.js +285 -0
- package/dist/chunk-kkz4w1tv.js +64 -0
- package/dist/chunk-kmywng0j.js +272 -0
- package/dist/chunk-kq6vcpdr.js +224 -0
- package/dist/chunk-kqzdszcc.js +37 -0
- package/dist/chunk-ktxpp02w.js +435 -0
- package/dist/chunk-kwcvhbtz.js +26 -0
- package/dist/chunk-kx0cm9qr.js +128 -0
- package/dist/chunk-kxcmqz10.js +120 -0
- package/dist/chunk-kxwava1g.js +14 -0
- package/dist/chunk-kywtr3jg.js +825 -0
- package/dist/chunk-kzwg923p.js +8 -0
- package/dist/chunk-m1eq3sgv.js +255 -0
- package/dist/chunk-m21h5zb4.js +119 -0
- package/dist/chunk-m2c3bjv1.js +111 -0
- package/dist/chunk-m41e19ms.js +42 -0
- package/dist/chunk-m7ka36ex.js +97 -0
- package/dist/chunk-m81w8tbm.js +259 -0
- package/dist/chunk-m95ggkax.js +281 -0
- package/dist/chunk-manx26xa.js +145 -0
- package/dist/chunk-mdxh3pk2.js +298 -0
- package/dist/chunk-mhbfkcja.js +311 -0
- package/dist/chunk-mjnr5erm.js +173 -0
- package/dist/chunk-mngvnmwp.js +135 -0
- package/dist/chunk-mvfqanv5.js +63 -0
- package/dist/chunk-mw1nesq1.js +140 -0
- package/dist/chunk-mx168925.js +661 -0
- package/dist/chunk-mxwvj18g.js +795 -0
- package/dist/chunk-my7r5mba.js +257 -0
- package/dist/chunk-myaa1kkf.js +17 -0
- package/dist/chunk-myypc3tn.js +46 -0
- package/dist/chunk-mzcnmnpq.js +3379 -0
- package/dist/chunk-mznav6d1.js +194 -0
- package/dist/chunk-n0qxskpr.js +24 -0
- package/dist/chunk-n6a6hgtp.js +394 -0
- package/dist/chunk-n6d5fgx0.js +254 -0
- package/dist/chunk-n6ym3n03.js +120 -0
- package/dist/chunk-n9g24mwe.js +104 -0
- package/dist/chunk-naamqdf9.js +185 -0
- package/dist/chunk-nb2jk7zj.js +15 -0
- package/dist/chunk-nbkbq9en.js +67 -0
- package/dist/chunk-ndttd6es.js +38 -0
- package/dist/chunk-nfygaaxg.js +133 -0
- package/dist/chunk-ngdzpszd.js +454 -0
- package/dist/chunk-nmfwksa4.js +1297 -0
- package/dist/chunk-nt837qt9.js +21 -0
- package/dist/chunk-nwc3v0vp.js +691 -0
- package/dist/chunk-nz8ha95p.js +3610 -0
- package/dist/chunk-nzxfj0gq.js +2007 -0
- package/dist/chunk-p0r8887g.js +6932 -0
- package/dist/chunk-p1seyqdm.js +120 -0
- package/dist/chunk-p425zbgw.js +726 -0
- package/dist/chunk-p7hamd2c.js +146 -0
- package/dist/chunk-pdvg91cg.js +32 -0
- package/dist/chunk-pecy49yr.js +14649 -0
- package/dist/chunk-pfxrg89f.js +547 -0
- package/dist/chunk-pfyw3155.js +2750 -0
- package/dist/chunk-pr8m11pm.js +1192 -0
- package/dist/chunk-ptxteaeh.js +1591 -0
- package/dist/chunk-pv164mac.js +394 -0
- package/dist/chunk-pxxhtxf5.js +10154 -0
- package/dist/chunk-q0e485mg.js +61 -0
- package/dist/chunk-q1vrhh0q.js +458 -0
- package/dist/chunk-q2h79ncs.js +370 -0
- package/dist/chunk-q3b4n194.js +56 -0
- package/dist/chunk-q44zc68f.js +4301 -0
- package/dist/chunk-q8gknbdx.js +352 -0
- package/dist/chunk-q8xk3kdj.js +11 -0
- package/dist/chunk-qak46xtp.js +119 -0
- package/dist/chunk-qfq7absv.js +95 -0
- package/dist/chunk-qfsn720k.js +151 -0
- package/dist/chunk-qg4811f6.js +228 -0
- package/dist/chunk-qgzn3qps.js +90 -0
- package/dist/chunk-qhaggqkt.js +113 -0
- package/dist/chunk-qjjp27z8.js +195 -0
- package/dist/chunk-qxp0nye6.js +34 -0
- package/dist/chunk-qy3nagaq.js +4957 -0
- package/dist/chunk-qz2meav1.js +1452 -0
- package/dist/chunk-r50hne7m.js +63 -0
- package/dist/chunk-r6m0vgnv.js +80 -0
- package/dist/chunk-r7yw38vf.js +22864 -0
- package/dist/chunk-r8xc618w.js +42 -0
- package/dist/chunk-r961r5kj.js +87 -0
- package/dist/chunk-r9b5xrh0.js +66 -0
- package/dist/chunk-rcn2pd6q.js +477 -0
- package/dist/chunk-rdeh8p3y.js +148 -0
- package/dist/chunk-rg9x1742.js +542 -0
- package/dist/chunk-rgyzsbs3.js +39 -0
- package/dist/chunk-rk2fsxtz.js +16 -0
- package/dist/chunk-rkchkwv9.js +40 -0
- package/dist/chunk-rp8whpb3.js +478 -0
- package/dist/chunk-rpkxdtgr.js +68 -0
- package/dist/chunk-rpmntgyh.js +394 -0
- package/dist/chunk-rpshz4dy.js +614 -0
- package/dist/chunk-rqd60ay5.js +133 -0
- package/dist/chunk-rrsjf2ea.js +229 -0
- package/dist/chunk-rtjk8c8e.js +173 -0
- package/dist/chunk-rw0y2wdf.js +1017 -0
- package/dist/chunk-rx5w7ess.js +663 -0
- package/dist/chunk-rx8t9d35.js +1947 -0
- package/dist/chunk-rxcazxgf.js +195 -0
- package/dist/chunk-rxg6q3bp.js +1413 -0
- package/dist/chunk-rxrb7xnd.js +71 -0
- package/dist/chunk-rxrzxff3.js +118 -0
- package/dist/chunk-ryqjc943.js +71 -0
- package/dist/chunk-rzk9k2rf.js +81 -0
- package/dist/chunk-s2qv0nht.js +119 -0
- package/dist/chunk-s3hafnk3.js +2285 -0
- package/dist/chunk-s4a496tt.js +226 -0
- package/dist/chunk-s4d1h3ka.js +35 -0
- package/dist/chunk-sm3k3ze4.js +16525 -0
- package/dist/chunk-sn0bja82.js +385 -0
- package/dist/chunk-sngjggw1.js +4227 -0
- package/dist/chunk-sq047n34.js +364 -0
- package/dist/chunk-sttwe2tw.js +8584 -0
- package/dist/chunk-sw8qx1r0.js +86 -0
- package/dist/chunk-swstah6a.js +240 -0
- package/dist/chunk-syrkr0mf.js +63 -0
- package/dist/chunk-sz206bd9.js +26 -0
- package/dist/chunk-t09669cj.js +333 -0
- package/dist/chunk-t5f8e30k.js +602 -0
- package/dist/chunk-t5m78mc8.js +432 -0
- package/dist/chunk-t5x1dqwn.js +143 -0
- package/dist/chunk-t877ea0w.js +168 -0
- package/dist/chunk-t91hb71c.js +17 -0
- package/dist/chunk-tb636bcf.js +942 -0
- package/dist/chunk-tb8sykbr.js +426 -0
- package/dist/chunk-tbdkekz3.js +125 -0
- package/dist/chunk-td2gsz7s.js +225 -0
- package/dist/chunk-tenvxbyh.js +20 -0
- package/dist/chunk-texg4qqt.js +317 -0
- package/dist/chunk-teymzz80.js +266 -0
- package/dist/chunk-tj26qpf7.js +153 -0
- package/dist/chunk-tk85ec4p.js +395 -0
- package/dist/chunk-tq205h01.js +164 -0
- package/dist/chunk-tqzddjzg.js +61 -0
- package/dist/chunk-trqrj23e.js +134 -0
- package/dist/chunk-tw1hfsxv.js +2477 -0
- package/dist/chunk-txxdfq83.js +122 -0
- package/dist/chunk-v0yhe582.js +31 -0
- package/dist/chunk-v14184xm.js +15 -0
- package/dist/chunk-v1h9z4hw.js +138 -0
- package/dist/chunk-v3ey5j7f.js +329 -0
- package/dist/chunk-v3nh1sfn.js +208 -0
- package/dist/chunk-v3x8tcc0.js +45 -0
- package/dist/chunk-v4nqnvqq.js +3984 -0
- package/dist/chunk-v4ypszbb.js +15 -0
- package/dist/chunk-v7wbqcx9.js +63 -0
- package/dist/chunk-v8r5fev3.js +341 -0
- package/dist/chunk-v9zg5kzx.js +2810 -0
- package/dist/chunk-va1wh5ss.js +24 -0
- package/dist/chunk-vbfswhht.js +42 -0
- package/dist/chunk-ve7x2tfq.js +124 -0
- package/dist/chunk-vfz8k89y.js +485 -0
- package/dist/chunk-vgm5k14x.js +35678 -0
- package/dist/chunk-vh9pej3c.js +247 -0
- package/dist/chunk-vjxqyt6f.js +3820 -0
- package/dist/chunk-vpb1xstn.js +178 -0
- package/dist/chunk-vqt79tj8.js +110 -0
- package/dist/chunk-vr0n9pv9.js +152 -0
- package/dist/chunk-vrejmja5.js +90 -0
- package/dist/chunk-vrxasmdw.js +449 -0
- package/dist/chunk-vrxb946v.js +125 -0
- package/dist/chunk-vv4kj0q8.js +98 -0
- package/dist/chunk-vvpfng7w.js +8 -0
- package/dist/chunk-vw6ybyew.js +2007 -0
- package/dist/chunk-vwenx8ke.js +17 -0
- package/dist/chunk-vwfa0s5a.js +155 -0
- package/dist/chunk-vx71j8xe.js +63 -0
- package/dist/chunk-vxbjzggp.js +43 -0
- package/dist/chunk-vxjxtz8w.js +440 -0
- package/dist/chunk-vy0c1bwp.js +9 -0
- package/dist/chunk-w3zczyse.js +14 -0
- package/dist/chunk-w4p5t920.js +655 -0
- package/dist/chunk-w68wc625.js +287 -0
- package/dist/chunk-w9ddp3yf.js +96 -0
- package/dist/chunk-wcggm5ja.js +125 -0
- package/dist/chunk-wgnyph3q.js +1306 -0
- package/dist/chunk-wjm5pc1e.js +134 -0
- package/dist/chunk-wnve0drm.js +131 -0
- package/dist/chunk-wp27ev2k.js +135 -0
- package/dist/chunk-wyvy8a4x.js +131 -0
- package/dist/chunk-x671y4dk.js +129 -0
- package/dist/chunk-xbj5keyy.js +22 -0
- package/dist/chunk-xf4fzms8.js +39 -0
- package/dist/chunk-xf59k3zg.js +65 -0
- package/dist/chunk-xgzc4w49.js +204 -0
- package/dist/chunk-xhj7g13b.js +2149 -0
- package/dist/chunk-xjp0cd00.js +56 -0
- package/dist/chunk-xkhnmhqs.js +74 -0
- package/dist/chunk-xkrkqx61.js +55 -0
- package/dist/chunk-xmpgmeb8.js +114 -0
- package/dist/chunk-xrw80zgd.js +4249 -0
- package/dist/chunk-xrzc96g0.js +202 -0
- package/dist/chunk-xt76sm44.js +318 -0
- package/dist/chunk-xwet3awb.js +20 -0
- package/dist/chunk-xyg1sk2w.js +78 -0
- package/dist/chunk-y0jpkqb0.js +180 -0
- package/dist/chunk-y1q7rt9n.js +102 -0
- package/dist/chunk-y67ntyek.js +258 -0
- package/dist/chunk-ybk37qp9.js +37 -0
- package/dist/chunk-yc1stfve.js +5386 -0
- package/dist/chunk-ychjpjef.js +62 -0
- package/dist/chunk-yez8fa9g.js +276 -0
- package/dist/chunk-ygm7xszr.js +90 -0
- package/dist/chunk-ym11azkj.js +37 -0
- package/dist/chunk-ympz2h15.js +578 -0
- package/dist/chunk-yqx3az3n.js +129 -0
- package/dist/chunk-yt3nfhcc.js +152 -0
- package/dist/chunk-yy8q0n8s.js +120 -0
- package/dist/chunk-yzb92zxv.js +8 -0
- package/dist/chunk-yzet6xyr.js +119 -0
- package/dist/chunk-yzm97qp1.js +226 -0
- package/dist/chunk-z0jgeax8.js +35 -0
- package/dist/chunk-z1r3z6w6.js +29 -0
- package/dist/chunk-z2dp53wn.js +17 -0
- package/dist/chunk-z79355gz.js +308 -0
- package/dist/chunk-z7e94hxz.js +251 -0
- package/dist/chunk-z8cqdcec.js +173 -0
- package/dist/chunk-z99tbg45.js +148 -0
- package/dist/chunk-z9nsjcht.js +37 -0
- package/dist/chunk-za3k6h2h.js +470 -0
- package/dist/chunk-zacynq5p.js +265 -0
- package/dist/chunk-zb0x40az.js +1785 -0
- package/dist/chunk-zbxtzycc.js +274 -0
- package/dist/chunk-zga50181.js +342 -0
- package/dist/chunk-zhb2pns1.js +44 -0
- package/dist/chunk-zkch6trx.js +231 -0
- package/dist/chunk-znf3z4qt.js +954 -0
- package/dist/chunk-zp8zwdgq.js +72 -0
- package/dist/chunk-ztjd8pyf.js +120 -0
- package/dist/chunk-ztmb7geg.js +173 -0
- package/dist/chunk-zvr4snzv.js +887 -0
- package/dist/chunk-zw62m6n3.js +34858 -0
- package/dist/chunk-zwwdebd0.js +65 -0
- package/dist/chunk-zxc6x9w8.js +340 -0
- package/dist/chunk-zy2e7sz0.js +8 -0
- package/dist/chunk-zzf074w3.js +196 -0
- package/dist/chunk-zzz0nwb5.js +310 -0
- package/dist/cli-bun.js +2 -0
- package/dist/cli-node.js +2 -0
- package/dist/cli.js +218 -0
- package/dist/vendor/audio-capture/arm64-darwin/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/arm64-linux/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/arm64-win32/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/x64-darwin/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/x64-linux/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/x64-win32/audio-capture.node +0 -0
- package/dist/vendor/ripgrep/x64-win32/rg.exe +0 -0
- package/package.json +243 -0
- package/scripts/chrome-mcp-bridge-resolver.mjs +43 -0
- package/scripts/chrome-mcp-env.mjs +19 -0
- package/scripts/postinstall.cjs +339 -0
- package/scripts/run-parallel.mjs +10 -0
- package/scripts/setup-chrome-mcp.mjs +69 -0
|
@@ -0,0 +1,4227 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
StructuredIO,
|
|
4
|
+
exports_cronJitterConfig,
|
|
5
|
+
exports_cronScheduler,
|
|
6
|
+
extractInboundMessageFields,
|
|
7
|
+
init_cronJitterConfig,
|
|
8
|
+
init_cronScheduler,
|
|
9
|
+
ndjsonSafeStringify,
|
|
10
|
+
outputSchema,
|
|
11
|
+
permissionPromptToolResultToPermissionDecision,
|
|
12
|
+
reconcileMarketplaces
|
|
13
|
+
} from "./chunk-g79ej71s.js";
|
|
14
|
+
import {
|
|
15
|
+
restoreAgentFromSession,
|
|
16
|
+
restoreSessionStateFromLog,
|
|
17
|
+
skillChangeDetector
|
|
18
|
+
} from "./chunk-gc6erq5q.js";
|
|
19
|
+
import {
|
|
20
|
+
detectAndUninstallDelistedPlugins
|
|
21
|
+
} from "./chunk-eax32zk4.js";
|
|
22
|
+
import"./chunk-y0jpkqb0.js";
|
|
23
|
+
import {
|
|
24
|
+
HybridTransport,
|
|
25
|
+
WebSocketTransport
|
|
26
|
+
} from "./chunk-nwc3v0vp.js";
|
|
27
|
+
import {
|
|
28
|
+
CCRClient,
|
|
29
|
+
CCRInitError
|
|
30
|
+
} from "./chunk-80ysxfe9.js";
|
|
31
|
+
import"./chunk-nt837qt9.js";
|
|
32
|
+
import {
|
|
33
|
+
resolveAndPrepend
|
|
34
|
+
} from "./chunk-mw1nesq1.js";
|
|
35
|
+
import {
|
|
36
|
+
externalMetadataToAppState
|
|
37
|
+
} from "./chunk-j139fzgs.js";
|
|
38
|
+
import {
|
|
39
|
+
getPollIntervalConfig
|
|
40
|
+
} from "./chunk-syrkr0mf.js";
|
|
41
|
+
import"./chunk-yt3nfhcc.js";
|
|
42
|
+
import {
|
|
43
|
+
SSETransport,
|
|
44
|
+
init_SSETransport
|
|
45
|
+
} from "./chunk-87ms17f6.js";
|
|
46
|
+
import {
|
|
47
|
+
ask,
|
|
48
|
+
buildSideQuestionFallbackParams
|
|
49
|
+
} from "./chunk-rw0y2wdf.js";
|
|
50
|
+
import"./chunk-apg95qd7.js";
|
|
51
|
+
import {
|
|
52
|
+
init_toolPool,
|
|
53
|
+
mergeAndFilterTools
|
|
54
|
+
} from "./chunk-3h59ttr5.js";
|
|
55
|
+
import"./chunk-ryqjc943.js";
|
|
56
|
+
import {
|
|
57
|
+
init_settingsSync
|
|
58
|
+
} from "./chunk-ygm7xszr.js";
|
|
59
|
+
import {
|
|
60
|
+
init_refresh,
|
|
61
|
+
refreshActivePlugins
|
|
62
|
+
} from "./chunk-jsbbez9j.js";
|
|
63
|
+
import {
|
|
64
|
+
init_mappers,
|
|
65
|
+
toInternalMessages,
|
|
66
|
+
toSDKRateLimitInfo
|
|
67
|
+
} from "./chunk-qg4811f6.js";
|
|
68
|
+
import {
|
|
69
|
+
generateSessionTitle,
|
|
70
|
+
init_sessionTitle
|
|
71
|
+
} from "./chunk-wjm5pc1e.js";
|
|
72
|
+
import"./chunk-d2an0138.js";
|
|
73
|
+
import {
|
|
74
|
+
init_omit,
|
|
75
|
+
omit_default
|
|
76
|
+
} from "./chunk-fpd1gpt8.js";
|
|
77
|
+
import {
|
|
78
|
+
ChannelMessageNotificationSchema,
|
|
79
|
+
findChannelEntry,
|
|
80
|
+
gateChannelServer,
|
|
81
|
+
init_channelAllowlist,
|
|
82
|
+
init_channelNotification,
|
|
83
|
+
isChannelAllowlisted,
|
|
84
|
+
isChannelsEnabled,
|
|
85
|
+
wrapChannelMessage
|
|
86
|
+
} from "./chunk-tj26qpf7.js";
|
|
87
|
+
import"./chunk-bxa6tw4m.js";
|
|
88
|
+
import"./chunk-aw4s3a99.js";
|
|
89
|
+
import {
|
|
90
|
+
collectContextData,
|
|
91
|
+
init_context_noninteractive
|
|
92
|
+
} from "./chunk-470kmby4.js";
|
|
93
|
+
import"./chunk-dz7nc6rf.js";
|
|
94
|
+
import {
|
|
95
|
+
init_sideQuestion,
|
|
96
|
+
runSideQuestion
|
|
97
|
+
} from "./chunk-dz2xk9kb.js";
|
|
98
|
+
import"./chunk-3abaq08g.js";
|
|
99
|
+
import {
|
|
100
|
+
DEFAULT_OUTPUT_STYLE_NAME,
|
|
101
|
+
EFFORT_LEVELS,
|
|
102
|
+
OAuthService,
|
|
103
|
+
SHELL_TOOL_NAMES,
|
|
104
|
+
SandboxManager,
|
|
105
|
+
applySettingsChange,
|
|
106
|
+
areMcpConfigsEqual,
|
|
107
|
+
asSessionId,
|
|
108
|
+
assembleToolPool,
|
|
109
|
+
atomicWriteToZipCache,
|
|
110
|
+
buildBridgeConnectUrl,
|
|
111
|
+
checkGroveForNonInteractive,
|
|
112
|
+
cleanupSessionPluginCache,
|
|
113
|
+
clearCommandsCache,
|
|
114
|
+
clearMarketplacesCache,
|
|
115
|
+
clearPluginCache,
|
|
116
|
+
clearServerCache,
|
|
117
|
+
commandBelongsToServer,
|
|
118
|
+
commitAutonomyQueuedPrompt,
|
|
119
|
+
connectToServer,
|
|
120
|
+
createAbortController,
|
|
121
|
+
createCombinedAbortSignal,
|
|
122
|
+
createModelSwitchBreadcrumbs,
|
|
123
|
+
createProactiveAutonomyCommands,
|
|
124
|
+
createSyntheticOutputTool,
|
|
125
|
+
dequeue,
|
|
126
|
+
dequeueAllMatching,
|
|
127
|
+
doesMessageExistInSession,
|
|
128
|
+
enqueue,
|
|
129
|
+
executeNotificationHooks,
|
|
130
|
+
exports_prompt1 as exports_prompt,
|
|
131
|
+
extractReadFilesFromMessages,
|
|
132
|
+
fetchToolsForClient,
|
|
133
|
+
fileHistoryCanRestore,
|
|
134
|
+
fileHistoryEnabled,
|
|
135
|
+
fileHistoryGetDiffStats,
|
|
136
|
+
fileHistoryRewind,
|
|
137
|
+
filterMcpServersByPolicy,
|
|
138
|
+
filterToolsByDenyRules,
|
|
139
|
+
filterToolsByServer,
|
|
140
|
+
finalizeAutonomyRunCompleted,
|
|
141
|
+
finalizeAutonomyRunFailed,
|
|
142
|
+
finalizePendingAsyncHooks,
|
|
143
|
+
findUnresolvedToolUse,
|
|
144
|
+
formatDescriptionWithSource,
|
|
145
|
+
fromArray,
|
|
146
|
+
getAllMcpConfigs,
|
|
147
|
+
getAllOutputStyles,
|
|
148
|
+
getAutoModeUnavailableNotification,
|
|
149
|
+
getAutoModeUnavailableReason,
|
|
150
|
+
getCommandName,
|
|
151
|
+
getCommands,
|
|
152
|
+
getCommandsByMaxPriority,
|
|
153
|
+
getDeclaredMarketplaces,
|
|
154
|
+
getLastCacheSafeParams,
|
|
155
|
+
getMarketplaceJsonRelativePath,
|
|
156
|
+
getMcpConfigByName,
|
|
157
|
+
getModelOptions,
|
|
158
|
+
getPluginZipCachePath,
|
|
159
|
+
getRemoteSessionUrl,
|
|
160
|
+
getRunningTasks,
|
|
161
|
+
getZipCacheKnownMarketplacesPath,
|
|
162
|
+
getZipCacheMarketplacesDir,
|
|
163
|
+
getZipCachePluginsDir,
|
|
164
|
+
gracefulShutdown,
|
|
165
|
+
gracefulShutdownSync,
|
|
166
|
+
hasCommandsInQueue,
|
|
167
|
+
hasPermissionsToUseTool,
|
|
168
|
+
headlessProfilerCheckpoint,
|
|
169
|
+
headlessProfilerStartTurn,
|
|
170
|
+
hydrateFromCCRv2InternalEvents,
|
|
171
|
+
hydrateRemoteSession,
|
|
172
|
+
init_AsyncHookRegistry,
|
|
173
|
+
init_SyntheticOutputTool,
|
|
174
|
+
init_Tool,
|
|
175
|
+
init_abortController,
|
|
176
|
+
init_applySettingsChange,
|
|
177
|
+
init_auth as init_auth2,
|
|
178
|
+
init_auth1 as init_auth3,
|
|
179
|
+
init_autonomyAuthority,
|
|
180
|
+
init_autonomyRuns,
|
|
181
|
+
init_bridgeStatusUtil,
|
|
182
|
+
init_changeDetector,
|
|
183
|
+
init_claudeAiLimits,
|
|
184
|
+
init_client,
|
|
185
|
+
init_combinedAbortSignal,
|
|
186
|
+
init_commandLifecycle,
|
|
187
|
+
init_commands1 as init_commands,
|
|
188
|
+
init_config,
|
|
189
|
+
init_constants,
|
|
190
|
+
init_constants1 as init_constants2,
|
|
191
|
+
init_conversationRecovery,
|
|
192
|
+
init_effort,
|
|
193
|
+
init_elicitationHandler,
|
|
194
|
+
init_fileHistory,
|
|
195
|
+
init_filesApi,
|
|
196
|
+
init_forkedAgent,
|
|
197
|
+
init_framework,
|
|
198
|
+
init_generators,
|
|
199
|
+
init_gracefulShutdown,
|
|
200
|
+
init_grove,
|
|
201
|
+
init_headlessProfiler,
|
|
202
|
+
init_hookEvents,
|
|
203
|
+
init_hooks1 as init_hooks,
|
|
204
|
+
init_ids,
|
|
205
|
+
init_loadAgentsDir,
|
|
206
|
+
init_marketplaceManager,
|
|
207
|
+
init_messageQueueManager,
|
|
208
|
+
init_messages1 as init_messages,
|
|
209
|
+
init_modelOptions,
|
|
210
|
+
init_oauth,
|
|
211
|
+
init_outputStyles,
|
|
212
|
+
init_outputsScanner,
|
|
213
|
+
init_permissionSetup,
|
|
214
|
+
init_permissions,
|
|
215
|
+
init_pluginLoader,
|
|
216
|
+
init_policyLimits,
|
|
217
|
+
init_product,
|
|
218
|
+
init_prompt as init_prompt2,
|
|
219
|
+
init_prompt1 as init_prompt3,
|
|
220
|
+
init_prompt12 as init_prompt8,
|
|
221
|
+
init_prompt13 as init_prompt9,
|
|
222
|
+
init_prompt2 as init_prompt4,
|
|
223
|
+
init_prompt3 as init_prompt5,
|
|
224
|
+
init_prompt5 as init_prompt6,
|
|
225
|
+
init_prompt9 as init_prompt7,
|
|
226
|
+
init_promptSuggestion,
|
|
227
|
+
init_queryHelpers,
|
|
228
|
+
init_queryProfiler,
|
|
229
|
+
init_reject,
|
|
230
|
+
init_remoteManagedSettings,
|
|
231
|
+
init_sandbox_adapter,
|
|
232
|
+
init_sessionStart,
|
|
233
|
+
init_sessionStorage,
|
|
234
|
+
init_shellToolUtils,
|
|
235
|
+
init_stopTask,
|
|
236
|
+
init_teammateMailbox,
|
|
237
|
+
init_thinking,
|
|
238
|
+
init_tools1 as init_tools,
|
|
239
|
+
init_types2,
|
|
240
|
+
init_uniqBy,
|
|
241
|
+
init_utils,
|
|
242
|
+
init_uuid,
|
|
243
|
+
init_vscodeSdkMcp,
|
|
244
|
+
init_zipCache,
|
|
245
|
+
installOAuthTokens,
|
|
246
|
+
isAutoModeGateEnabled,
|
|
247
|
+
isBackgroundTask,
|
|
248
|
+
isBuiltInAgent,
|
|
249
|
+
isBypassPermissionsModeDisabled,
|
|
250
|
+
isMarketplaceSourceSupportedByZipCache,
|
|
251
|
+
isMcpServerDisabled,
|
|
252
|
+
isPluginZipCacheEnabled,
|
|
253
|
+
isPolicyAllowed,
|
|
254
|
+
isQualifiedForGrove,
|
|
255
|
+
isShutdownApproved,
|
|
256
|
+
isShuttingDown,
|
|
257
|
+
loadAllPluginsCacheOnly,
|
|
258
|
+
loadConversationForResume,
|
|
259
|
+
loadKnownMarketplacesConfigSafe,
|
|
260
|
+
logHeadlessProfilerTurn,
|
|
261
|
+
logQueryProfileReport,
|
|
262
|
+
logSuggestionOutcome,
|
|
263
|
+
logSuggestionSuppressed,
|
|
264
|
+
markAutonomyRunFailed,
|
|
265
|
+
markAutonomyRunRunning,
|
|
266
|
+
markMessagesAsRead,
|
|
267
|
+
modelSupportsAdaptiveThinking,
|
|
268
|
+
modelSupportsEffort,
|
|
269
|
+
modelSupportsMaxEffort,
|
|
270
|
+
notifyCommandLifecycle,
|
|
271
|
+
parseAgentsFromJson,
|
|
272
|
+
peek,
|
|
273
|
+
performMCPOAuthFlow,
|
|
274
|
+
prepareAutonomyTurnPrompt,
|
|
275
|
+
processSessionStartHooks,
|
|
276
|
+
processSetupHooks,
|
|
277
|
+
readUnreadMessages,
|
|
278
|
+
reconnectMcpServerImpl,
|
|
279
|
+
recordAttributionSnapshot,
|
|
280
|
+
registerHookEventHandler,
|
|
281
|
+
registerSeedMarketplaces,
|
|
282
|
+
reject_default,
|
|
283
|
+
resetSessionFilePointer,
|
|
284
|
+
resolveAppliedEffort,
|
|
285
|
+
restoreSessionMetadata,
|
|
286
|
+
revokeServerTokens,
|
|
287
|
+
runElicitationHooks,
|
|
288
|
+
runElicitationResultHooks,
|
|
289
|
+
saveAgentSetting,
|
|
290
|
+
saveAiGeneratedTitle,
|
|
291
|
+
setCommandLifecycleListener,
|
|
292
|
+
setInternalEventReader,
|
|
293
|
+
setInternalEventWriter,
|
|
294
|
+
setMcpServerEnabled,
|
|
295
|
+
settingsChangeDetector,
|
|
296
|
+
setupSdkMcpClients,
|
|
297
|
+
setupVscodeSdkMcp,
|
|
298
|
+
startQueryProfile,
|
|
299
|
+
statusListeners,
|
|
300
|
+
stopTask,
|
|
301
|
+
subscribeToCommandQueue,
|
|
302
|
+
takeInitialUserMessage,
|
|
303
|
+
toolMatchesName,
|
|
304
|
+
transitionPermissionMode,
|
|
305
|
+
tryGenerateSuggestion,
|
|
306
|
+
uniqBy_default,
|
|
307
|
+
validateUuid,
|
|
308
|
+
waitForRemoteManagedSettingsToLoad
|
|
309
|
+
} from "./chunk-gmdy2w3z.js";
|
|
310
|
+
import"./chunk-q0e485mg.js";
|
|
311
|
+
import"./chunk-2kcgxnvp.js";
|
|
312
|
+
import"./chunk-14p6wvsq.js";
|
|
313
|
+
import"./chunk-6s0q1s5r.js";
|
|
314
|
+
import"./chunk-3w9sye8h.js";
|
|
315
|
+
import {
|
|
316
|
+
EMPTY_USAGE,
|
|
317
|
+
drainSdkEvents,
|
|
318
|
+
exports_proactive,
|
|
319
|
+
getSessionIngressAuthToken,
|
|
320
|
+
getSessionState,
|
|
321
|
+
init_proactive,
|
|
322
|
+
init_sdkEventQueue,
|
|
323
|
+
init_sessionIngressAuth,
|
|
324
|
+
init_sessionState,
|
|
325
|
+
init_src,
|
|
326
|
+
notifySessionMetadataChanged,
|
|
327
|
+
notifySessionStateChanged,
|
|
328
|
+
setPermissionModeChangedListener,
|
|
329
|
+
setSessionMetadataChangedListener,
|
|
330
|
+
setSessionStateChangedListener
|
|
331
|
+
} from "./chunk-nzxfj0gq.js";
|
|
332
|
+
import"./chunk-vr0n9pv9.js";
|
|
333
|
+
import"./chunk-9a9g5hbj.js";
|
|
334
|
+
import"./chunk-ptxteaeh.js";
|
|
335
|
+
import {
|
|
336
|
+
incrementPromptCount,
|
|
337
|
+
init_commitAttribution
|
|
338
|
+
} from "./chunk-w4p5t920.js";
|
|
339
|
+
import"./chunk-rgyzsbs3.js";
|
|
340
|
+
import"./chunk-q3b4n194.js";
|
|
341
|
+
import {
|
|
342
|
+
init_tasks,
|
|
343
|
+
init_teamHelpers,
|
|
344
|
+
removeTeammateFromTeamFile,
|
|
345
|
+
unassignTeammateTasks
|
|
346
|
+
} from "./chunk-kywtr3jg.js";
|
|
347
|
+
import"./chunk-eewg66y1.js";
|
|
348
|
+
import"./chunk-71sdcaq6.js";
|
|
349
|
+
import"./chunk-9hn8e6h1.js";
|
|
350
|
+
import {
|
|
351
|
+
init_pluginIdentifier,
|
|
352
|
+
parsePluginIdentifier
|
|
353
|
+
} from "./chunk-7qey87th.js";
|
|
354
|
+
import"./chunk-zw62m6n3.js";
|
|
355
|
+
import"./chunk-1w20m7gw.js";
|
|
356
|
+
import"./chunk-zzf074w3.js";
|
|
357
|
+
import"./chunk-rpmntgyh.js";
|
|
358
|
+
import {
|
|
359
|
+
READ_FILE_STATE_CACHE_SIZE,
|
|
360
|
+
createFileStateCacheWithSizeLimit,
|
|
361
|
+
init_fileStateCache,
|
|
362
|
+
mergeFileStateCaches
|
|
363
|
+
} from "./chunk-24kv69g3.js";
|
|
364
|
+
import"./chunk-hzxzvzw8.js";
|
|
365
|
+
import"./chunk-30wnahyg.js";
|
|
366
|
+
import"./chunk-ztmb7geg.js";
|
|
367
|
+
import"./chunk-tbdkekz3.js";
|
|
368
|
+
import"./chunk-65zbgg1n.js";
|
|
369
|
+
import"./chunk-4spgkgr3.js";
|
|
370
|
+
import"./chunk-60fkafk2.js";
|
|
371
|
+
import"./chunk-50m3a23z.js";
|
|
372
|
+
import"./chunk-6hygvrhn.js";
|
|
373
|
+
import"./chunk-7tfdhkpy.js";
|
|
374
|
+
import"./chunk-8gv2pjby.js";
|
|
375
|
+
import"./chunk-g06pm4n9.js";
|
|
376
|
+
import"./chunk-2p369q9z.js";
|
|
377
|
+
import"./chunk-z0jgeax8.js";
|
|
378
|
+
import"./chunk-w68wc625.js";
|
|
379
|
+
import"./chunk-6hr7742d.js";
|
|
380
|
+
import"./chunk-xyg1sk2w.js";
|
|
381
|
+
import"./chunk-935nrvdb.js";
|
|
382
|
+
import"./chunk-8zz4z1q3.js";
|
|
383
|
+
import"./chunk-fncpkzs5.js";
|
|
384
|
+
import"./chunk-hqxp6b72.js";
|
|
385
|
+
import"./chunk-m2c3bjv1.js";
|
|
386
|
+
import"./chunk-jhtccjc9.js";
|
|
387
|
+
import"./chunk-7nvday0n.js";
|
|
388
|
+
import"./chunk-vxbjzggp.js";
|
|
389
|
+
import"./chunk-yc1stfve.js";
|
|
390
|
+
import"./chunk-8yvsnrkr.js";
|
|
391
|
+
import"./chunk-5mmhfbxb.js";
|
|
392
|
+
import {
|
|
393
|
+
AwsAuthStatusManager,
|
|
394
|
+
KnownMarketplacesFileSchema,
|
|
395
|
+
TASK_STOP_TOOL_NAME,
|
|
396
|
+
WORKLOAD_CRON,
|
|
397
|
+
ensureModelStringsInitialized,
|
|
398
|
+
getAPIProvider,
|
|
399
|
+
getAccountInformation,
|
|
400
|
+
getDefaultMainLoopModel,
|
|
401
|
+
getFastModeState,
|
|
402
|
+
getFeatureValue_CACHED_MAY_BE_STALE,
|
|
403
|
+
getMainLoopModel,
|
|
404
|
+
getMcpPrefix,
|
|
405
|
+
getSettingsWithSources,
|
|
406
|
+
getSettings_DEPRECATED,
|
|
407
|
+
init_auth,
|
|
408
|
+
init_awsAuthStatusManager,
|
|
409
|
+
init_betas1 as init_betas,
|
|
410
|
+
init_fastMode,
|
|
411
|
+
init_growthbook,
|
|
412
|
+
init_mcpStringUtils,
|
|
413
|
+
init_model,
|
|
414
|
+
init_modelStrings,
|
|
415
|
+
init_paths,
|
|
416
|
+
init_prompt,
|
|
417
|
+
init_providers,
|
|
418
|
+
init_schemas,
|
|
419
|
+
init_settings1 as init_settings,
|
|
420
|
+
init_stringUtils,
|
|
421
|
+
init_workloadContext,
|
|
422
|
+
initializeGrowthBook,
|
|
423
|
+
isExtractModeActive,
|
|
424
|
+
isFastModeAvailable,
|
|
425
|
+
isFastModeEnabled,
|
|
426
|
+
isFastModeSupportedByModel,
|
|
427
|
+
modelDisplayString,
|
|
428
|
+
modelSupportsAutoMode,
|
|
429
|
+
parseUserSpecifiedModel,
|
|
430
|
+
runWithWorkload
|
|
431
|
+
} from "./chunk-eemjb825.js";
|
|
432
|
+
import {
|
|
433
|
+
init_json,
|
|
434
|
+
safeParseJSON
|
|
435
|
+
} from "./chunk-ga1jkyqy.js";
|
|
436
|
+
import {
|
|
437
|
+
expandPath,
|
|
438
|
+
init_path
|
|
439
|
+
} from "./chunk-y1q7rt9n.js";
|
|
440
|
+
import"./chunk-8kct9arg.js";
|
|
441
|
+
import {
|
|
442
|
+
hasActiveInProcessTeammates,
|
|
443
|
+
hasWorkingInProcessTeammates,
|
|
444
|
+
init_array,
|
|
445
|
+
init_teammate,
|
|
446
|
+
isTeamLead,
|
|
447
|
+
uniq,
|
|
448
|
+
waitForTeammatesToBecomeIdle
|
|
449
|
+
} from "./chunk-k7hexw3v.js";
|
|
450
|
+
import"./chunk-trqrj23e.js";
|
|
451
|
+
import"./chunk-za3k6h2h.js";
|
|
452
|
+
import"./chunk-8kf8h7xf.js";
|
|
453
|
+
import"./chunk-bgan4cpf.js";
|
|
454
|
+
import {
|
|
455
|
+
init_sleep,
|
|
456
|
+
sleep
|
|
457
|
+
} from "./chunk-jmv7k0jn.js";
|
|
458
|
+
import"./chunk-hjxqmtg5.js";
|
|
459
|
+
import"./chunk-bzyzrq0k.js";
|
|
460
|
+
import"./chunk-vwenx8ke.js";
|
|
461
|
+
import"./chunk-q2h79ncs.js";
|
|
462
|
+
import"./chunk-v4ypszbb.js";
|
|
463
|
+
import"./chunk-qfsn720k.js";
|
|
464
|
+
import {
|
|
465
|
+
ElicitRequestSchema,
|
|
466
|
+
ElicitationCompleteNotificationSchema,
|
|
467
|
+
init_types
|
|
468
|
+
} from "./chunk-7qx3xhv3.js";
|
|
469
|
+
import"./chunk-j9475b46.js";
|
|
470
|
+
import"./chunk-fdwabr8p.js";
|
|
471
|
+
import"./chunk-e4dsy4g1.js";
|
|
472
|
+
import"./chunk-326zehp8.js";
|
|
473
|
+
import"./chunk-kc67kt75.js";
|
|
474
|
+
import"./chunk-40t1d75v.js";
|
|
475
|
+
import"./chunk-dbts5q5p.js";
|
|
476
|
+
import"./chunk-e3abfxpy.js";
|
|
477
|
+
import"./chunk-q44zc68f.js";
|
|
478
|
+
import"./chunk-fejeqe61.js";
|
|
479
|
+
import"./chunk-q1vrhh0q.js";
|
|
480
|
+
import"./chunk-hn4w9pkj.js";
|
|
481
|
+
import"./chunk-2g0ytd9d.js";
|
|
482
|
+
import"./chunk-de0qnnf7.js";
|
|
483
|
+
import {
|
|
484
|
+
init_analytics,
|
|
485
|
+
logEvent
|
|
486
|
+
} from "./chunk-j1mep9ck.js";
|
|
487
|
+
import"./chunk-6x35ffpx.js";
|
|
488
|
+
import"./chunk-1zbwhcbt.js";
|
|
489
|
+
import"./chunk-92bjkrf2.js";
|
|
490
|
+
import {
|
|
491
|
+
init_diagLogs,
|
|
492
|
+
logForDiagnosticsNoPII,
|
|
493
|
+
withDiagnosticsTiming
|
|
494
|
+
} from "./chunk-10k5jfc5.js";
|
|
495
|
+
import"./chunk-n9g24mwe.js";
|
|
496
|
+
import"./chunk-e3j7m7k2.js";
|
|
497
|
+
import"./chunk-hzmzwte2.js";
|
|
498
|
+
import {
|
|
499
|
+
getCwd,
|
|
500
|
+
init_cwd
|
|
501
|
+
} from "./chunk-pdvg91cg.js";
|
|
502
|
+
import"./chunk-c696122m.js";
|
|
503
|
+
import"./chunk-xbj5keyy.js";
|
|
504
|
+
import"./chunk-c1yc761e.js";
|
|
505
|
+
import"./chunk-c5g9shkw.js";
|
|
506
|
+
import"./chunk-aeysytks.js";
|
|
507
|
+
import {
|
|
508
|
+
LOCAL_COMMAND_STDOUT_TAG,
|
|
509
|
+
TEAMMATE_MESSAGE_TAG,
|
|
510
|
+
TICK_TAG,
|
|
511
|
+
errorMessage,
|
|
512
|
+
getFsImplementation,
|
|
513
|
+
getInMemoryErrors,
|
|
514
|
+
init_cleanupRegistry,
|
|
515
|
+
init_debug,
|
|
516
|
+
init_envUtils,
|
|
517
|
+
init_errors,
|
|
518
|
+
init_fsOperations,
|
|
519
|
+
init_log,
|
|
520
|
+
init_slowOperations,
|
|
521
|
+
init_xml,
|
|
522
|
+
isBareMode,
|
|
523
|
+
isDebugMode,
|
|
524
|
+
isEnvDefinedFalsy,
|
|
525
|
+
isEnvTruthy,
|
|
526
|
+
jsonParse,
|
|
527
|
+
jsonStringify,
|
|
528
|
+
logError,
|
|
529
|
+
logForDebugging,
|
|
530
|
+
logMCPDebug,
|
|
531
|
+
registerCleanup,
|
|
532
|
+
toError
|
|
533
|
+
} from "./chunk-s3hafnk3.js";
|
|
534
|
+
import {
|
|
535
|
+
init_process,
|
|
536
|
+
registerProcessOutputErrorHandlers,
|
|
537
|
+
writeToStdout
|
|
538
|
+
} from "./chunk-kb3758f7.js";
|
|
539
|
+
import {
|
|
540
|
+
getAllowedChannels,
|
|
541
|
+
getFlagSettingsInline,
|
|
542
|
+
getInitJsonSchema,
|
|
543
|
+
getMainThreadAgentType,
|
|
544
|
+
getSessionId,
|
|
545
|
+
init_state,
|
|
546
|
+
isSessionPersistenceDisabled,
|
|
547
|
+
registerHookCallbacks,
|
|
548
|
+
setAllowedChannels,
|
|
549
|
+
setFlagSettingsInline,
|
|
550
|
+
setInitJsonSchema,
|
|
551
|
+
setMainLoopModelOverride,
|
|
552
|
+
setMainThreadAgentType,
|
|
553
|
+
setSdkAgentProgressSummariesEnabled,
|
|
554
|
+
switchSession
|
|
555
|
+
} from "./chunk-9h9k5vz3.js";
|
|
556
|
+
import"./chunk-xmpgmeb8.js";
|
|
557
|
+
import"./chunk-2kz09j2s.js";
|
|
558
|
+
import"./chunk-c0k7b0jw.js";
|
|
559
|
+
import"./chunk-pecy49yr.js";
|
|
560
|
+
import"./chunk-azbab59e.js";
|
|
561
|
+
import"./chunk-3nk9q8dr.js";
|
|
562
|
+
import {
|
|
563
|
+
__require,
|
|
564
|
+
__toCommonJS
|
|
565
|
+
} from "./chunk-hhsxm2yr.js";
|
|
566
|
+
|
|
567
|
+
// src/cli/print.ts
|
|
568
|
+
init_settingsSync();
|
|
569
|
+
init_remoteManagedSettings();
|
|
570
|
+
import { readFile as readFile2, stat } from "fs/promises";
|
|
571
|
+
import { dirname } from "path";
|
|
572
|
+
|
|
573
|
+
// src/cli/remoteIO.ts
|
|
574
|
+
init_state();
|
|
575
|
+
import { PassThrough } from "stream";
|
|
576
|
+
import { URL as URL3 } from "url";
|
|
577
|
+
init_cleanupRegistry();
|
|
578
|
+
init_commandLifecycle();
|
|
579
|
+
init_debug();
|
|
580
|
+
init_diagLogs();
|
|
581
|
+
init_envUtils();
|
|
582
|
+
init_errors();
|
|
583
|
+
init_gracefulShutdown();
|
|
584
|
+
init_log();
|
|
585
|
+
init_process();
|
|
586
|
+
init_sessionIngressAuth();
|
|
587
|
+
init_sessionState();
|
|
588
|
+
init_sessionStorage();
|
|
589
|
+
init_SSETransport();
|
|
590
|
+
|
|
591
|
+
// src/cli/transports/transportUtils.ts
|
|
592
|
+
init_envUtils();
|
|
593
|
+
import { URL as URL2 } from "url";
|
|
594
|
+
init_SSETransport();
|
|
595
|
+
function getTransportForUrl(url, headers = {}, sessionId, refreshHeaders) {
|
|
596
|
+
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_CCR_V2)) {
|
|
597
|
+
const sseUrl = new URL2(url.href);
|
|
598
|
+
if (sseUrl.protocol === "wss:") {
|
|
599
|
+
sseUrl.protocol = "https:";
|
|
600
|
+
} else if (sseUrl.protocol === "ws:") {
|
|
601
|
+
sseUrl.protocol = "http:";
|
|
602
|
+
}
|
|
603
|
+
sseUrl.pathname = sseUrl.pathname.replace(/\/$/, "") + "/worker/events/stream";
|
|
604
|
+
return new SSETransport(sseUrl, headers, sessionId, refreshHeaders);
|
|
605
|
+
}
|
|
606
|
+
if (url.protocol === "ws:" || url.protocol === "wss:") {
|
|
607
|
+
if (isEnvTruthy(process.env.CLAUDE_CODE_POST_FOR_SESSION_INGRESS_V2)) {
|
|
608
|
+
return new HybridTransport(url, headers, sessionId, refreshHeaders);
|
|
609
|
+
}
|
|
610
|
+
return new WebSocketTransport(url, headers, sessionId, refreshHeaders);
|
|
611
|
+
} else {
|
|
612
|
+
throw new Error(`Unsupported protocol: ${url.protocol}`);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// src/cli/remoteIO.ts
|
|
617
|
+
class RemoteIO extends StructuredIO {
|
|
618
|
+
url;
|
|
619
|
+
transport;
|
|
620
|
+
inputStream;
|
|
621
|
+
isBridge = false;
|
|
622
|
+
isDebug = false;
|
|
623
|
+
ccrClient = null;
|
|
624
|
+
keepAliveTimer = null;
|
|
625
|
+
constructor(streamUrl, initialPrompt, replayUserMessages) {
|
|
626
|
+
const inputStream = new PassThrough({ encoding: "utf8" });
|
|
627
|
+
super(inputStream, replayUserMessages);
|
|
628
|
+
this.inputStream = inputStream;
|
|
629
|
+
this.url = new URL3(streamUrl);
|
|
630
|
+
const headers = {};
|
|
631
|
+
const sessionToken = getSessionIngressAuthToken();
|
|
632
|
+
if (sessionToken) {
|
|
633
|
+
headers["Authorization"] = `Bearer ${sessionToken}`;
|
|
634
|
+
} else {
|
|
635
|
+
logForDebugging("[remote-io] No session ingress token available", {
|
|
636
|
+
level: "error"
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
const erVersion = process.env.CLAUDE_CODE_ENVIRONMENT_RUNNER_VERSION;
|
|
640
|
+
if (erVersion) {
|
|
641
|
+
headers["x-environment-runner-version"] = erVersion;
|
|
642
|
+
}
|
|
643
|
+
const refreshHeaders = () => {
|
|
644
|
+
const h = {};
|
|
645
|
+
const freshToken = getSessionIngressAuthToken();
|
|
646
|
+
if (freshToken) {
|
|
647
|
+
h["Authorization"] = `Bearer ${freshToken}`;
|
|
648
|
+
}
|
|
649
|
+
const freshErVersion = process.env.CLAUDE_CODE_ENVIRONMENT_RUNNER_VERSION;
|
|
650
|
+
if (freshErVersion) {
|
|
651
|
+
h["x-environment-runner-version"] = freshErVersion;
|
|
652
|
+
}
|
|
653
|
+
return h;
|
|
654
|
+
};
|
|
655
|
+
this.transport = getTransportForUrl(this.url, headers, getSessionId(), refreshHeaders);
|
|
656
|
+
this.isBridge = process.env.CLAUDE_CODE_ENVIRONMENT_KIND === "bridge";
|
|
657
|
+
this.isDebug = isDebugMode();
|
|
658
|
+
this.transport.setOnData((data) => {
|
|
659
|
+
this.inputStream.write(data);
|
|
660
|
+
if (this.isBridge && this.isDebug) {
|
|
661
|
+
writeToStdout(data.endsWith(`
|
|
662
|
+
`) ? data : data + `
|
|
663
|
+
`);
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
this.transport.setOnClose(() => {
|
|
667
|
+
this.inputStream.end();
|
|
668
|
+
});
|
|
669
|
+
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_CCR_V2)) {
|
|
670
|
+
if (!(this.transport instanceof SSETransport)) {
|
|
671
|
+
throw new Error("CCR v2 requires SSETransport; check getTransportForUrl");
|
|
672
|
+
}
|
|
673
|
+
this.ccrClient = new CCRClient(this.transport, this.url);
|
|
674
|
+
const init = this.ccrClient.initialize();
|
|
675
|
+
this.restoredWorkerState = init.catch(() => null);
|
|
676
|
+
init.catch((error) => {
|
|
677
|
+
logForDiagnosticsNoPII("error", "cli_worker_lifecycle_init_failed", {
|
|
678
|
+
reason: error instanceof CCRInitError ? error.reason : "unknown"
|
|
679
|
+
});
|
|
680
|
+
logError(new Error(`CCRClient initialization failed: ${errorMessage(error)}`));
|
|
681
|
+
gracefulShutdown(1, "other");
|
|
682
|
+
});
|
|
683
|
+
registerCleanup(async () => this.ccrClient?.close());
|
|
684
|
+
setInternalEventWriter((eventType, payload, options) => this.ccrClient.writeInternalEvent(eventType, payload, options));
|
|
685
|
+
setInternalEventReader(() => this.ccrClient.readInternalEvents(), () => this.ccrClient.readSubagentInternalEvents());
|
|
686
|
+
const LIFECYCLE_TO_DELIVERY = {
|
|
687
|
+
started: "processing",
|
|
688
|
+
completed: "processed"
|
|
689
|
+
};
|
|
690
|
+
setCommandLifecycleListener((uuid, state) => {
|
|
691
|
+
this.ccrClient?.reportDelivery(uuid, LIFECYCLE_TO_DELIVERY[state]);
|
|
692
|
+
});
|
|
693
|
+
setSessionStateChangedListener((state, details) => {
|
|
694
|
+
this.ccrClient?.reportState(state, details);
|
|
695
|
+
});
|
|
696
|
+
setSessionMetadataChangedListener((metadata) => {
|
|
697
|
+
this.ccrClient?.reportMetadata(metadata);
|
|
698
|
+
}, { replayCurrent: true });
|
|
699
|
+
}
|
|
700
|
+
this.transport.connect();
|
|
701
|
+
const keepAliveIntervalMs = getPollIntervalConfig().session_keepalive_interval_v2_ms;
|
|
702
|
+
if (this.isBridge && keepAliveIntervalMs > 0) {
|
|
703
|
+
this.keepAliveTimer = setInterval(() => {
|
|
704
|
+
logForDebugging("[remote-io] keep_alive sent");
|
|
705
|
+
this.write({ type: "keep_alive" }).catch((err) => {
|
|
706
|
+
logForDebugging(`[remote-io] keep_alive write failed: ${errorMessage(err)}`);
|
|
707
|
+
});
|
|
708
|
+
}, keepAliveIntervalMs);
|
|
709
|
+
this.keepAliveTimer.unref?.();
|
|
710
|
+
}
|
|
711
|
+
registerCleanup(async () => this.close());
|
|
712
|
+
if (initialPrompt) {
|
|
713
|
+
const stream = this.inputStream;
|
|
714
|
+
(async () => {
|
|
715
|
+
for await (const chunk of initialPrompt) {
|
|
716
|
+
stream.write(String(chunk).replace(/\n$/, "") + `
|
|
717
|
+
`);
|
|
718
|
+
}
|
|
719
|
+
})();
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
flushInternalEvents() {
|
|
723
|
+
return this.ccrClient?.flushInternalEvents() ?? Promise.resolve();
|
|
724
|
+
}
|
|
725
|
+
get internalEventsPending() {
|
|
726
|
+
return this.ccrClient?.internalEventsPending ?? 0;
|
|
727
|
+
}
|
|
728
|
+
async write(message) {
|
|
729
|
+
if (this.ccrClient) {
|
|
730
|
+
await this.ccrClient.writeEvent(message);
|
|
731
|
+
} else {
|
|
732
|
+
await this.transport.write(message);
|
|
733
|
+
}
|
|
734
|
+
if (this.isBridge) {
|
|
735
|
+
if (message.type === "control_request" || this.isDebug) {
|
|
736
|
+
writeToStdout(ndjsonSafeStringify(message) + `
|
|
737
|
+
`);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
close() {
|
|
742
|
+
if (this.keepAliveTimer) {
|
|
743
|
+
clearInterval(this.keepAliveTimer);
|
|
744
|
+
this.keepAliveTimer = null;
|
|
745
|
+
}
|
|
746
|
+
this.transport.close();
|
|
747
|
+
this.inputStream.end();
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// src/cli/print.ts
|
|
752
|
+
init_commands();
|
|
753
|
+
|
|
754
|
+
// src/utils/streamlinedTransform.ts
|
|
755
|
+
init_constants();
|
|
756
|
+
init_prompt3();
|
|
757
|
+
init_prompt4();
|
|
758
|
+
init_prompt5();
|
|
759
|
+
init_prompt2();
|
|
760
|
+
init_prompt8();
|
|
761
|
+
init_prompt9();
|
|
762
|
+
init_constants2();
|
|
763
|
+
init_prompt();
|
|
764
|
+
init_prompt6();
|
|
765
|
+
init_messages();
|
|
766
|
+
init_shellToolUtils();
|
|
767
|
+
init_stringUtils();
|
|
768
|
+
var COMMAND_TOOLS = [...SHELL_TOOL_NAMES, "Tmux", TASK_STOP_TOOL_NAME];
|
|
769
|
+
|
|
770
|
+
// src/utils/streamJsonStdoutGuard.ts
|
|
771
|
+
init_cleanupRegistry();
|
|
772
|
+
init_debug();
|
|
773
|
+
var STDOUT_GUARD_MARKER = "[stdout-guard]";
|
|
774
|
+
var installed = false;
|
|
775
|
+
var buffer = "";
|
|
776
|
+
var originalWrite = null;
|
|
777
|
+
function isJsonLine(line) {
|
|
778
|
+
if (line.length === 0) {
|
|
779
|
+
return true;
|
|
780
|
+
}
|
|
781
|
+
try {
|
|
782
|
+
JSON.parse(line);
|
|
783
|
+
return true;
|
|
784
|
+
} catch {
|
|
785
|
+
return false;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
function installStreamJsonStdoutGuard() {
|
|
789
|
+
if (installed) {
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
installed = true;
|
|
793
|
+
originalWrite = process.stdout.write.bind(process.stdout);
|
|
794
|
+
process.stdout.write = function(chunk, encodingOrCb, cb) {
|
|
795
|
+
const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf-8");
|
|
796
|
+
buffer += text;
|
|
797
|
+
let newlineIdx;
|
|
798
|
+
let wrote = true;
|
|
799
|
+
while ((newlineIdx = buffer.indexOf(`
|
|
800
|
+
`)) !== -1) {
|
|
801
|
+
const line = buffer.slice(0, newlineIdx);
|
|
802
|
+
buffer = buffer.slice(newlineIdx + 1);
|
|
803
|
+
if (isJsonLine(line)) {
|
|
804
|
+
wrote = originalWrite(line + `
|
|
805
|
+
`);
|
|
806
|
+
} else {
|
|
807
|
+
process.stderr.write(`${STDOUT_GUARD_MARKER} ${line}
|
|
808
|
+
`);
|
|
809
|
+
logForDebugging(`streamJsonStdoutGuard diverted non-JSON stdout line: ${line.slice(0, 200)}`);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
const callback = typeof encodingOrCb === "function" ? encodingOrCb : cb;
|
|
813
|
+
if (callback) {
|
|
814
|
+
queueMicrotask(() => callback());
|
|
815
|
+
}
|
|
816
|
+
return wrote;
|
|
817
|
+
};
|
|
818
|
+
registerCleanup(async () => {
|
|
819
|
+
if (buffer.length > 0) {
|
|
820
|
+
if (originalWrite && isJsonLine(buffer)) {
|
|
821
|
+
originalWrite(buffer + `
|
|
822
|
+
`);
|
|
823
|
+
} else {
|
|
824
|
+
process.stderr.write(`${STDOUT_GUARD_MARKER} ${buffer}
|
|
825
|
+
`);
|
|
826
|
+
}
|
|
827
|
+
buffer = "";
|
|
828
|
+
}
|
|
829
|
+
if (originalWrite) {
|
|
830
|
+
process.stdout.write = originalWrite;
|
|
831
|
+
originalWrite = null;
|
|
832
|
+
}
|
|
833
|
+
installed = false;
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// src/cli/print.ts
|
|
838
|
+
init_tools();
|
|
839
|
+
init_uniqBy();
|
|
840
|
+
init_array();
|
|
841
|
+
init_toolPool();
|
|
842
|
+
init_analytics();
|
|
843
|
+
init_growthbook();
|
|
844
|
+
init_debug();
|
|
845
|
+
init_diagLogs();
|
|
846
|
+
init_Tool();
|
|
847
|
+
init_loadAgentsDir();
|
|
848
|
+
init_messageQueueManager();
|
|
849
|
+
init_commandLifecycle();
|
|
850
|
+
init_sessionState();
|
|
851
|
+
init_log();
|
|
852
|
+
init_process();
|
|
853
|
+
init_src();
|
|
854
|
+
init_conversationRecovery();
|
|
855
|
+
init_channelNotification();
|
|
856
|
+
init_channelAllowlist();
|
|
857
|
+
init_pluginIdentifier();
|
|
858
|
+
init_uuid();
|
|
859
|
+
init_generators();
|
|
860
|
+
init_fileStateCache();
|
|
861
|
+
init_path();
|
|
862
|
+
init_queryHelpers();
|
|
863
|
+
init_hookEvents();
|
|
864
|
+
|
|
865
|
+
// src/utils/filePersistence/filePersistence.ts
|
|
866
|
+
init_analytics();
|
|
867
|
+
init_filesApi();
|
|
868
|
+
init_cwd();
|
|
869
|
+
init_errors();
|
|
870
|
+
init_log();
|
|
871
|
+
init_sessionIngressAuth();
|
|
872
|
+
init_outputsScanner();
|
|
873
|
+
|
|
874
|
+
// src/cli/print.ts
|
|
875
|
+
init_AsyncHookRegistry();
|
|
876
|
+
init_gracefulShutdown();
|
|
877
|
+
init_cleanupRegistry();
|
|
878
|
+
|
|
879
|
+
// src/utils/idleTimeout.ts
|
|
880
|
+
init_debug();
|
|
881
|
+
init_gracefulShutdown();
|
|
882
|
+
function createIdleTimeoutManager(isIdle) {
|
|
883
|
+
const exitAfterStopDelay = process.env.CLAUDE_CODE_EXIT_AFTER_STOP_DELAY;
|
|
884
|
+
const delayMs = exitAfterStopDelay ? parseInt(exitAfterStopDelay, 10) : null;
|
|
885
|
+
const isValidDelay = delayMs && !isNaN(delayMs) && delayMs > 0;
|
|
886
|
+
let timer = null;
|
|
887
|
+
let lastIdleTime = 0;
|
|
888
|
+
return {
|
|
889
|
+
start() {
|
|
890
|
+
if (timer) {
|
|
891
|
+
clearTimeout(timer);
|
|
892
|
+
timer = null;
|
|
893
|
+
}
|
|
894
|
+
if (isValidDelay) {
|
|
895
|
+
lastIdleTime = Date.now();
|
|
896
|
+
timer = setTimeout(() => {
|
|
897
|
+
const idleDuration = Date.now() - lastIdleTime;
|
|
898
|
+
if (isIdle() && idleDuration >= delayMs) {
|
|
899
|
+
logForDebugging(`Exiting after ${delayMs}ms of idle time`);
|
|
900
|
+
gracefulShutdownSync();
|
|
901
|
+
}
|
|
902
|
+
}, delayMs);
|
|
903
|
+
}
|
|
904
|
+
},
|
|
905
|
+
stop() {
|
|
906
|
+
if (timer) {
|
|
907
|
+
clearTimeout(timer);
|
|
908
|
+
timer = null;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// src/cli/print.ts
|
|
915
|
+
init_cwd();
|
|
916
|
+
init_omit();
|
|
917
|
+
init_reject();
|
|
918
|
+
init_policyLimits();
|
|
919
|
+
init_product();
|
|
920
|
+
init_bridgeStatusUtil();
|
|
921
|
+
import { cwd } from "process";
|
|
922
|
+
init_permissions();
|
|
923
|
+
init_json();
|
|
924
|
+
init_abortController();
|
|
925
|
+
init_combinedAbortSignal();
|
|
926
|
+
init_sessionTitle();
|
|
927
|
+
init_sideQuestion();
|
|
928
|
+
init_sessionStart();
|
|
929
|
+
init_outputStyles();
|
|
930
|
+
init_xml();
|
|
931
|
+
init_settings();
|
|
932
|
+
init_changeDetector();
|
|
933
|
+
init_applySettingsChange();
|
|
934
|
+
init_fastMode();
|
|
935
|
+
init_permissionSetup();
|
|
936
|
+
init_promptSuggestion();
|
|
937
|
+
init_forkedAgent();
|
|
938
|
+
init_auth();
|
|
939
|
+
init_oauth();
|
|
940
|
+
init_auth3();
|
|
941
|
+
init_providers();
|
|
942
|
+
init_awsAuthStatusManager();
|
|
943
|
+
init_state();
|
|
944
|
+
init_SyntheticOutputTool();
|
|
945
|
+
|
|
946
|
+
// src/utils/sessionUrl.ts
|
|
947
|
+
init_uuid();
|
|
948
|
+
import { randomUUID } from "crypto";
|
|
949
|
+
function parseSessionIdentifier(resumeIdentifier) {
|
|
950
|
+
if (resumeIdentifier.toLowerCase().endsWith(".jsonl")) {
|
|
951
|
+
return {
|
|
952
|
+
sessionId: randomUUID(),
|
|
953
|
+
ingressUrl: null,
|
|
954
|
+
isUrl: false,
|
|
955
|
+
jsonlFile: resumeIdentifier,
|
|
956
|
+
isJsonlFile: true
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
if (validateUuid(resumeIdentifier)) {
|
|
960
|
+
return {
|
|
961
|
+
sessionId: resumeIdentifier,
|
|
962
|
+
ingressUrl: null,
|
|
963
|
+
isUrl: false,
|
|
964
|
+
jsonlFile: null,
|
|
965
|
+
isJsonlFile: false
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
try {
|
|
969
|
+
const url = new URL(resumeIdentifier);
|
|
970
|
+
return {
|
|
971
|
+
sessionId: randomUUID(),
|
|
972
|
+
ingressUrl: url.href,
|
|
973
|
+
isUrl: true,
|
|
974
|
+
jsonlFile: null,
|
|
975
|
+
isJsonlFile: false
|
|
976
|
+
};
|
|
977
|
+
} catch {}
|
|
978
|
+
return null;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// src/cli/print.ts
|
|
982
|
+
init_sessionStorage();
|
|
983
|
+
init_commitAttribution();
|
|
984
|
+
init_client();
|
|
985
|
+
init_config();
|
|
986
|
+
init_auth2();
|
|
987
|
+
init_elicitationHandler();
|
|
988
|
+
init_hooks();
|
|
989
|
+
init_types();
|
|
990
|
+
init_mcpStringUtils();
|
|
991
|
+
init_utils();
|
|
992
|
+
init_vscodeSdkMcp();
|
|
993
|
+
init_config();
|
|
994
|
+
init_grove();
|
|
995
|
+
init_mappers();
|
|
996
|
+
init_messages();
|
|
997
|
+
init_context_noninteractive();
|
|
998
|
+
init_xml();
|
|
999
|
+
init_claudeAiLimits();
|
|
1000
|
+
init_model();
|
|
1001
|
+
init_modelOptions();
|
|
1002
|
+
init_effort();
|
|
1003
|
+
init_thinking();
|
|
1004
|
+
init_betas();
|
|
1005
|
+
init_modelStrings();
|
|
1006
|
+
init_state();
|
|
1007
|
+
init_workloadContext();
|
|
1008
|
+
init_fileHistory();
|
|
1009
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
1010
|
+
init_sandbox_adapter();
|
|
1011
|
+
init_headlessProfiler();
|
|
1012
|
+
init_queryProfiler();
|
|
1013
|
+
init_ids();
|
|
1014
|
+
init_autonomyRuns();
|
|
1015
|
+
init_autonomyAuthority();
|
|
1016
|
+
init_slowOperations();
|
|
1017
|
+
init_commands();
|
|
1018
|
+
init_envUtils();
|
|
1019
|
+
|
|
1020
|
+
// src/utils/plugins/headlessPluginInstall.ts
|
|
1021
|
+
init_analytics();
|
|
1022
|
+
init_cleanupRegistry();
|
|
1023
|
+
init_debug();
|
|
1024
|
+
init_diagLogs();
|
|
1025
|
+
init_fsOperations();
|
|
1026
|
+
init_log();
|
|
1027
|
+
init_marketplaceManager();
|
|
1028
|
+
init_pluginLoader();
|
|
1029
|
+
init_zipCache();
|
|
1030
|
+
|
|
1031
|
+
// src/utils/plugins/zipCacheAdapters.ts
|
|
1032
|
+
init_debug();
|
|
1033
|
+
init_slowOperations();
|
|
1034
|
+
init_marketplaceManager();
|
|
1035
|
+
init_schemas();
|
|
1036
|
+
init_zipCache();
|
|
1037
|
+
import { readFile } from "fs/promises";
|
|
1038
|
+
import { join } from "path";
|
|
1039
|
+
async function readZipCacheKnownMarketplaces() {
|
|
1040
|
+
try {
|
|
1041
|
+
const content = await readFile(getZipCacheKnownMarketplacesPath(), "utf-8");
|
|
1042
|
+
const parsed = KnownMarketplacesFileSchema().safeParse(jsonParse(content));
|
|
1043
|
+
if (!parsed.success) {
|
|
1044
|
+
logForDebugging(`Invalid known_marketplaces.json in zip cache: ${parsed.error.message}`, { level: "error" });
|
|
1045
|
+
return {};
|
|
1046
|
+
}
|
|
1047
|
+
return parsed.data;
|
|
1048
|
+
} catch {
|
|
1049
|
+
return {};
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
async function writeZipCacheKnownMarketplaces(data) {
|
|
1053
|
+
await atomicWriteToZipCache(getZipCacheKnownMarketplacesPath(), jsonStringify(data, null, 2));
|
|
1054
|
+
}
|
|
1055
|
+
async function saveMarketplaceJsonToZipCache(marketplaceName, installLocation) {
|
|
1056
|
+
const zipCachePath = getPluginZipCachePath();
|
|
1057
|
+
if (!zipCachePath) {
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
const content = await readMarketplaceJsonContent(installLocation);
|
|
1061
|
+
if (content !== null) {
|
|
1062
|
+
const relPath = getMarketplaceJsonRelativePath(marketplaceName);
|
|
1063
|
+
await atomicWriteToZipCache(join(zipCachePath, relPath), content);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
async function readMarketplaceJsonContent(dir) {
|
|
1067
|
+
const candidates = [
|
|
1068
|
+
join(dir, ".claude-plugin", "marketplace.json"),
|
|
1069
|
+
join(dir, "marketplace.json"),
|
|
1070
|
+
dir
|
|
1071
|
+
];
|
|
1072
|
+
for (const candidate of candidates) {
|
|
1073
|
+
try {
|
|
1074
|
+
return await readFile(candidate, "utf-8");
|
|
1075
|
+
} catch {}
|
|
1076
|
+
}
|
|
1077
|
+
return null;
|
|
1078
|
+
}
|
|
1079
|
+
async function syncMarketplacesToZipCache() {
|
|
1080
|
+
const knownMarketplaces = await loadKnownMarketplacesConfigSafe();
|
|
1081
|
+
for (const [name, entry] of Object.entries(knownMarketplaces)) {
|
|
1082
|
+
if (!entry.installLocation)
|
|
1083
|
+
continue;
|
|
1084
|
+
try {
|
|
1085
|
+
await saveMarketplaceJsonToZipCache(name, entry.installLocation);
|
|
1086
|
+
} catch (error) {
|
|
1087
|
+
logForDebugging(`Failed to save marketplace JSON for ${name}: ${error}`);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
const zipCacheKnownMarketplaces = await readZipCacheKnownMarketplaces();
|
|
1091
|
+
const mergedKnownMarketplaces = {
|
|
1092
|
+
...zipCacheKnownMarketplaces,
|
|
1093
|
+
...knownMarketplaces
|
|
1094
|
+
};
|
|
1095
|
+
await writeZipCacheKnownMarketplaces(mergedKnownMarketplaces);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
// src/utils/plugins/headlessPluginInstall.ts
|
|
1099
|
+
async function installPluginsForHeadless() {
|
|
1100
|
+
const zipCacheMode = isPluginZipCacheEnabled();
|
|
1101
|
+
logForDebugging(`installPluginsForHeadless: starting${zipCacheMode ? " (zip cache mode)" : ""}`);
|
|
1102
|
+
const seedChanged = await registerSeedMarketplaces();
|
|
1103
|
+
if (seedChanged) {
|
|
1104
|
+
clearMarketplacesCache();
|
|
1105
|
+
clearPluginCache("headlessPluginInstall: seed marketplaces registered");
|
|
1106
|
+
}
|
|
1107
|
+
if (zipCacheMode) {
|
|
1108
|
+
await getFsImplementation().mkdir(getZipCacheMarketplacesDir());
|
|
1109
|
+
await getFsImplementation().mkdir(getZipCachePluginsDir());
|
|
1110
|
+
}
|
|
1111
|
+
const declaredCount = Object.keys(getDeclaredMarketplaces()).length;
|
|
1112
|
+
const metrics = {
|
|
1113
|
+
marketplaces_installed: 0,
|
|
1114
|
+
delisted_count: 0
|
|
1115
|
+
};
|
|
1116
|
+
let pluginsChanged = seedChanged;
|
|
1117
|
+
try {
|
|
1118
|
+
if (declaredCount === 0) {
|
|
1119
|
+
logForDebugging("installPluginsForHeadless: no marketplaces declared");
|
|
1120
|
+
} else {
|
|
1121
|
+
const reconcileResult = await withDiagnosticsTiming("headless_marketplace_reconcile", () => reconcileMarketplaces({
|
|
1122
|
+
skip: zipCacheMode ? (_name, source) => !isMarketplaceSourceSupportedByZipCache(source) : undefined,
|
|
1123
|
+
onProgress: (event) => {
|
|
1124
|
+
if (event.type === "installed") {
|
|
1125
|
+
logForDebugging(`installPluginsForHeadless: installed marketplace ${event.name}`);
|
|
1126
|
+
} else if (event.type === "failed") {
|
|
1127
|
+
logForDebugging(`installPluginsForHeadless: failed to install marketplace ${event.name}: ${event.error}`);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
}), (r) => ({
|
|
1131
|
+
installed_count: r.installed.length,
|
|
1132
|
+
updated_count: r.updated.length,
|
|
1133
|
+
failed_count: r.failed.length,
|
|
1134
|
+
skipped_count: r.skipped.length
|
|
1135
|
+
}));
|
|
1136
|
+
if (reconcileResult.skipped.length > 0) {
|
|
1137
|
+
logForDebugging(`installPluginsForHeadless: skipped ${reconcileResult.skipped.length} marketplace(s) unsupported by zip cache: ${reconcileResult.skipped.join(", ")}`);
|
|
1138
|
+
}
|
|
1139
|
+
const marketplacesChanged = reconcileResult.installed.length + reconcileResult.updated.length;
|
|
1140
|
+
if (marketplacesChanged > 0) {
|
|
1141
|
+
clearMarketplacesCache();
|
|
1142
|
+
clearPluginCache("headlessPluginInstall: marketplaces reconciled");
|
|
1143
|
+
pluginsChanged = true;
|
|
1144
|
+
}
|
|
1145
|
+
metrics.marketplaces_installed = marketplacesChanged;
|
|
1146
|
+
}
|
|
1147
|
+
if (zipCacheMode) {
|
|
1148
|
+
await syncMarketplacesToZipCache();
|
|
1149
|
+
}
|
|
1150
|
+
const newlyDelisted = await detectAndUninstallDelistedPlugins();
|
|
1151
|
+
metrics.delisted_count = newlyDelisted.length;
|
|
1152
|
+
if (newlyDelisted.length > 0) {
|
|
1153
|
+
pluginsChanged = true;
|
|
1154
|
+
}
|
|
1155
|
+
if (pluginsChanged) {
|
|
1156
|
+
clearPluginCache("headlessPluginInstall: plugins changed");
|
|
1157
|
+
}
|
|
1158
|
+
if (zipCacheMode) {
|
|
1159
|
+
registerCleanup(cleanupSessionPluginCache);
|
|
1160
|
+
}
|
|
1161
|
+
return pluginsChanged;
|
|
1162
|
+
} catch (error) {
|
|
1163
|
+
logError(error);
|
|
1164
|
+
return false;
|
|
1165
|
+
} finally {
|
|
1166
|
+
logEvent("tengu_headless_plugin_install", metrics);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
// src/cli/print.ts
|
|
1171
|
+
init_refresh();
|
|
1172
|
+
init_pluginLoader();
|
|
1173
|
+
init_teammate();
|
|
1174
|
+
init_teammateMailbox();
|
|
1175
|
+
init_teamHelpers();
|
|
1176
|
+
init_tasks();
|
|
1177
|
+
init_framework();
|
|
1178
|
+
init_types2();
|
|
1179
|
+
init_stopTask();
|
|
1180
|
+
init_sdkEventQueue();
|
|
1181
|
+
init_growthbook();
|
|
1182
|
+
init_errors();
|
|
1183
|
+
init_sleep();
|
|
1184
|
+
init_paths();
|
|
1185
|
+
var proactiveModule = (init_proactive(), __toCommonJS(exports_proactive));
|
|
1186
|
+
var cronSchedulerModule = (init_cronScheduler(), __toCommonJS(exports_cronScheduler));
|
|
1187
|
+
var cronJitterConfigModule = (init_cronJitterConfig(), __toCommonJS(exports_cronJitterConfig));
|
|
1188
|
+
var cronGate = (init_prompt7(), __toCommonJS(exports_prompt));
|
|
1189
|
+
async function loadExtractMemoriesModule() {
|
|
1190
|
+
return import("./chunk-143eh1e0.js");
|
|
1191
|
+
}
|
|
1192
|
+
var SHUTDOWN_TEAM_PROMPT = `<system-reminder>
|
|
1193
|
+
You are running in non-interactive mode and cannot return a response to the user until your team is shut down.
|
|
1194
|
+
|
|
1195
|
+
You MUST shut down your team before preparing your final response:
|
|
1196
|
+
1. Use requestShutdown to ask each team member to shut down gracefully
|
|
1197
|
+
2. Wait for shutdown approvals
|
|
1198
|
+
3. Use the cleanup operation to clean up the team
|
|
1199
|
+
4. Only then provide your final response to the user
|
|
1200
|
+
|
|
1201
|
+
The user cannot receive your response until the team is completely shut down.
|
|
1202
|
+
</system-reminder>
|
|
1203
|
+
|
|
1204
|
+
Shut down your team and prepare your final response for the user.`;
|
|
1205
|
+
var MAX_RECEIVED_UUIDS = 1e4;
|
|
1206
|
+
var receivedMessageUuids = new Set;
|
|
1207
|
+
var receivedMessageUuidsOrder = [];
|
|
1208
|
+
function trackReceivedMessageUuid(uuid) {
|
|
1209
|
+
if (receivedMessageUuids.has(uuid)) {
|
|
1210
|
+
return false;
|
|
1211
|
+
}
|
|
1212
|
+
receivedMessageUuids.add(uuid);
|
|
1213
|
+
receivedMessageUuidsOrder.push(uuid);
|
|
1214
|
+
if (receivedMessageUuidsOrder.length > MAX_RECEIVED_UUIDS) {
|
|
1215
|
+
const toEvict = receivedMessageUuidsOrder.splice(0, receivedMessageUuidsOrder.length - MAX_RECEIVED_UUIDS);
|
|
1216
|
+
for (const old of toEvict) {
|
|
1217
|
+
receivedMessageUuids.delete(old);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
return true;
|
|
1221
|
+
}
|
|
1222
|
+
function toBlocks(v) {
|
|
1223
|
+
return typeof v === "string" ? [{ type: "text", text: v }] : v;
|
|
1224
|
+
}
|
|
1225
|
+
function joinPromptValues(values) {
|
|
1226
|
+
if (values.length === 1)
|
|
1227
|
+
return values[0];
|
|
1228
|
+
if (values.every((v) => typeof v === "string")) {
|
|
1229
|
+
return values.join(`
|
|
1230
|
+
`);
|
|
1231
|
+
}
|
|
1232
|
+
return values.flatMap(toBlocks);
|
|
1233
|
+
}
|
|
1234
|
+
function canBatchWith(head, next) {
|
|
1235
|
+
return next !== undefined && next.mode === "prompt" && next.workload === head.workload && next.isMeta === head.isMeta;
|
|
1236
|
+
}
|
|
1237
|
+
async function runHeadless(inputPrompt, getAppState, setAppState, commands, tools, sdkMcpConfigs, agents, options) {
|
|
1238
|
+
if (process.env.USER_TYPE === "ant" && isEnvTruthy(process.env.CLAUDE_CODE_EXIT_AFTER_FIRST_RENDER)) {
|
|
1239
|
+
process.stderr.write(`
|
|
1240
|
+
Startup time: ${Math.round(process.uptime() * 1000)}ms
|
|
1241
|
+
`);
|
|
1242
|
+
process.exit(0);
|
|
1243
|
+
}
|
|
1244
|
+
if (false) {}
|
|
1245
|
+
settingsChangeDetector.subscribe((source) => {
|
|
1246
|
+
applySettingsChange(source, setAppState);
|
|
1247
|
+
if (isFastModeEnabled()) {
|
|
1248
|
+
setAppState((prev) => {
|
|
1249
|
+
const s = prev.settings;
|
|
1250
|
+
const fastMode = s.fastMode === true && !s.fastModePerSessionOptIn;
|
|
1251
|
+
return { ...prev, fastMode };
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
});
|
|
1255
|
+
if (proactiveModule && !proactiveModule.isProactiveActive() && isEnvTruthy(process.env.CLAUDE_CODE_PROACTIVE)) {
|
|
1256
|
+
proactiveModule.activateProactive("command");
|
|
1257
|
+
}
|
|
1258
|
+
if (typeof Bun !== "undefined") {
|
|
1259
|
+
const gcTimer = setInterval(Bun.gc, 1000);
|
|
1260
|
+
gcTimer.unref();
|
|
1261
|
+
}
|
|
1262
|
+
headlessProfilerStartTurn();
|
|
1263
|
+
headlessProfilerCheckpoint("runHeadless_entry");
|
|
1264
|
+
if (await isQualifiedForGrove()) {
|
|
1265
|
+
await checkGroveForNonInteractive();
|
|
1266
|
+
}
|
|
1267
|
+
headlessProfilerCheckpoint("after_grove_check");
|
|
1268
|
+
initializeGrowthBook();
|
|
1269
|
+
if (options.resumeSessionAt && !options.resume) {
|
|
1270
|
+
process.stderr.write(`Error: --resume-session-at requires --resume
|
|
1271
|
+
`);
|
|
1272
|
+
gracefulShutdownSync(1);
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
if (options.rewindFiles && !options.resume) {
|
|
1276
|
+
process.stderr.write(`Error: --rewind-files requires --resume
|
|
1277
|
+
`);
|
|
1278
|
+
gracefulShutdownSync(1);
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
if (options.rewindFiles && inputPrompt) {
|
|
1282
|
+
process.stderr.write(`Error: --rewind-files is a standalone operation and cannot be used with a prompt
|
|
1283
|
+
`);
|
|
1284
|
+
gracefulShutdownSync(1);
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1287
|
+
const structuredIO = getStructuredIO(inputPrompt, options);
|
|
1288
|
+
if (options.outputFormat === "stream-json") {
|
|
1289
|
+
installStreamJsonStdoutGuard();
|
|
1290
|
+
}
|
|
1291
|
+
const sandboxUnavailableReason = SandboxManager.getSandboxUnavailableReason();
|
|
1292
|
+
if (sandboxUnavailableReason) {
|
|
1293
|
+
if (SandboxManager.isSandboxRequired()) {
|
|
1294
|
+
process.stderr.write(`
|
|
1295
|
+
Error: sandbox required but unavailable: ${sandboxUnavailableReason}
|
|
1296
|
+
` + ` sandbox.failIfUnavailable is set \u2014 refusing to start without a working sandbox.
|
|
1297
|
+
|
|
1298
|
+
`);
|
|
1299
|
+
gracefulShutdownSync(1);
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
process.stderr.write(`
|
|
1303
|
+
\u26A0 Sandbox disabled: ${sandboxUnavailableReason}
|
|
1304
|
+
Commands will run WITHOUT sandboxing. Network and filesystem restrictions will NOT be enforced.
|
|
1305
|
+
|
|
1306
|
+
`);
|
|
1307
|
+
} else if (SandboxManager.isSandboxingEnabled()) {
|
|
1308
|
+
try {
|
|
1309
|
+
await SandboxManager.initialize(structuredIO.createSandboxAskCallback());
|
|
1310
|
+
} catch (err) {
|
|
1311
|
+
process.stderr.write(`
|
|
1312
|
+
\u274C Sandbox Error: ${errorMessage(err)}
|
|
1313
|
+
`);
|
|
1314
|
+
gracefulShutdownSync(1, "other");
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
if (options.outputFormat === "stream-json" && options.verbose) {
|
|
1319
|
+
registerHookEventHandler((event) => {
|
|
1320
|
+
const message = (() => {
|
|
1321
|
+
switch (event.type) {
|
|
1322
|
+
case "started":
|
|
1323
|
+
return {
|
|
1324
|
+
type: "system",
|
|
1325
|
+
subtype: "hook_started",
|
|
1326
|
+
hook_id: event.hookId,
|
|
1327
|
+
hook_name: event.hookName,
|
|
1328
|
+
hook_event: event.hookEvent,
|
|
1329
|
+
uuid: randomUUID2(),
|
|
1330
|
+
session_id: getSessionId()
|
|
1331
|
+
};
|
|
1332
|
+
case "progress":
|
|
1333
|
+
return {
|
|
1334
|
+
type: "system",
|
|
1335
|
+
subtype: "hook_progress",
|
|
1336
|
+
hook_id: event.hookId,
|
|
1337
|
+
hook_name: event.hookName,
|
|
1338
|
+
hook_event: event.hookEvent,
|
|
1339
|
+
stdout: event.stdout,
|
|
1340
|
+
stderr: event.stderr,
|
|
1341
|
+
output: event.output,
|
|
1342
|
+
uuid: randomUUID2(),
|
|
1343
|
+
session_id: getSessionId()
|
|
1344
|
+
};
|
|
1345
|
+
case "response":
|
|
1346
|
+
return {
|
|
1347
|
+
type: "system",
|
|
1348
|
+
subtype: "hook_response",
|
|
1349
|
+
hook_id: event.hookId,
|
|
1350
|
+
hook_name: event.hookName,
|
|
1351
|
+
hook_event: event.hookEvent,
|
|
1352
|
+
output: event.output,
|
|
1353
|
+
stdout: event.stdout,
|
|
1354
|
+
stderr: event.stderr,
|
|
1355
|
+
exit_code: event.exitCode,
|
|
1356
|
+
outcome: event.outcome,
|
|
1357
|
+
uuid: randomUUID2(),
|
|
1358
|
+
session_id: getSessionId()
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
})();
|
|
1362
|
+
structuredIO.write(message);
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
if (options.setupTrigger) {
|
|
1366
|
+
await processSetupHooks(options.setupTrigger);
|
|
1367
|
+
}
|
|
1368
|
+
headlessProfilerCheckpoint("before_loadInitialMessages");
|
|
1369
|
+
const appState = getAppState();
|
|
1370
|
+
const {
|
|
1371
|
+
messages: initialMessages,
|
|
1372
|
+
turnInterruptionState,
|
|
1373
|
+
agentSetting: resumedAgentSetting
|
|
1374
|
+
} = await loadInitialMessages(setAppState, {
|
|
1375
|
+
continue: options.continue,
|
|
1376
|
+
teleport: options.teleport,
|
|
1377
|
+
resume: options.resume,
|
|
1378
|
+
resumeSessionAt: options.resumeSessionAt,
|
|
1379
|
+
forkSession: options.forkSession,
|
|
1380
|
+
outputFormat: options.outputFormat,
|
|
1381
|
+
sessionStartHooksPromise: options.sessionStartHooksPromise,
|
|
1382
|
+
restoredWorkerState: structuredIO.restoredWorkerState
|
|
1383
|
+
});
|
|
1384
|
+
const hookInitialUserMessage = takeInitialUserMessage();
|
|
1385
|
+
if (hookInitialUserMessage) {
|
|
1386
|
+
structuredIO.prependUserMessage(hookInitialUserMessage);
|
|
1387
|
+
}
|
|
1388
|
+
if (!options.agent && !getMainThreadAgentType() && resumedAgentSetting) {
|
|
1389
|
+
const { agentDefinition: restoredAgent } = restoreAgentFromSession(resumedAgentSetting, undefined, { activeAgents: agents, allAgents: agents });
|
|
1390
|
+
if (restoredAgent) {
|
|
1391
|
+
setAppState((prev) => ({ ...prev, agent: restoredAgent.agentType }));
|
|
1392
|
+
if (!options.systemPrompt && !isBuiltInAgent(restoredAgent)) {
|
|
1393
|
+
const agentSystemPrompt = restoredAgent.getSystemPrompt();
|
|
1394
|
+
if (agentSystemPrompt) {
|
|
1395
|
+
options.systemPrompt = agentSystemPrompt;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
saveAgentSetting(restoredAgent.agentType);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
if (initialMessages.length === 0 && process.exitCode !== undefined) {
|
|
1402
|
+
return;
|
|
1403
|
+
}
|
|
1404
|
+
if (options.rewindFiles) {
|
|
1405
|
+
const targetMessage = initialMessages.find((m) => m.uuid === options.rewindFiles);
|
|
1406
|
+
if (!targetMessage || targetMessage.type !== "user") {
|
|
1407
|
+
process.stderr.write(`Error: --rewind-files requires a user message UUID, but ${options.rewindFiles} is not a user message in this session
|
|
1408
|
+
`);
|
|
1409
|
+
gracefulShutdownSync(1);
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1412
|
+
const currentAppState = getAppState();
|
|
1413
|
+
const result = await handleRewindFiles(options.rewindFiles, currentAppState, setAppState, false);
|
|
1414
|
+
if (!result.canRewind) {
|
|
1415
|
+
process.stderr.write(`Error: ${result.error || "Unexpected error"}
|
|
1416
|
+
`);
|
|
1417
|
+
gracefulShutdownSync(1);
|
|
1418
|
+
return;
|
|
1419
|
+
}
|
|
1420
|
+
process.stdout.write(`Files rewound to state at message ${options.rewindFiles}
|
|
1421
|
+
`);
|
|
1422
|
+
gracefulShutdownSync(0);
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
const hasValidResumeSessionId = typeof options.resume === "string" && (Boolean(validateUuid(options.resume)) || options.resume.endsWith(".jsonl"));
|
|
1426
|
+
const isUsingSdkUrl = Boolean(options.sdkUrl);
|
|
1427
|
+
if (!inputPrompt && !hasValidResumeSessionId && !isUsingSdkUrl) {
|
|
1428
|
+
process.stderr.write(`Error: Input must be provided either through stdin or as a prompt argument when using --print
|
|
1429
|
+
`);
|
|
1430
|
+
gracefulShutdownSync(1);
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
if (options.outputFormat === "stream-json" && !options.verbose) {
|
|
1434
|
+
process.stderr.write(`Error: When using --print, --output-format=stream-json requires --verbose
|
|
1435
|
+
`);
|
|
1436
|
+
gracefulShutdownSync(1);
|
|
1437
|
+
return;
|
|
1438
|
+
}
|
|
1439
|
+
const allowedMcpTools = filterToolsByDenyRules(appState.mcp.tools, appState.toolPermissionContext);
|
|
1440
|
+
let filteredTools = [...tools, ...allowedMcpTools];
|
|
1441
|
+
const effectivePermissionPromptToolName = options.sdkUrl ? "stdio" : options.permissionPromptToolName;
|
|
1442
|
+
const onPermissionPrompt = (details) => {
|
|
1443
|
+
if (true) {
|
|
1444
|
+
setAppState((prev) => ({
|
|
1445
|
+
...prev,
|
|
1446
|
+
attribution: {
|
|
1447
|
+
...prev.attribution,
|
|
1448
|
+
permissionPromptCount: prev.attribution.permissionPromptCount + 1
|
|
1449
|
+
}
|
|
1450
|
+
}));
|
|
1451
|
+
}
|
|
1452
|
+
notifySessionStateChanged("requires_action", details);
|
|
1453
|
+
};
|
|
1454
|
+
const canUseTool = getCanUseToolFn(effectivePermissionPromptToolName, structuredIO, () => getAppState().mcp.tools, onPermissionPrompt);
|
|
1455
|
+
if (options.permissionPromptToolName) {
|
|
1456
|
+
filteredTools = filteredTools.filter((tool) => !toolMatchesName(tool, options.permissionPromptToolName));
|
|
1457
|
+
}
|
|
1458
|
+
registerProcessOutputErrorHandlers();
|
|
1459
|
+
headlessProfilerCheckpoint("after_loadInitialMessages");
|
|
1460
|
+
await ensureModelStringsInitialized();
|
|
1461
|
+
headlessProfilerCheckpoint("after_modelStrings");
|
|
1462
|
+
const needsFullArray = options.outputFormat === "json" && options.verbose;
|
|
1463
|
+
const messages = [];
|
|
1464
|
+
let lastMessage;
|
|
1465
|
+
const transformToStreamlined = null;
|
|
1466
|
+
headlessProfilerCheckpoint("before_runHeadlessStreaming");
|
|
1467
|
+
for await (const message of runHeadlessStreaming(structuredIO, appState.mcp.clients, [...commands, ...appState.mcp.commands], filteredTools, initialMessages, canUseTool, sdkMcpConfigs, getAppState, setAppState, agents, options, turnInterruptionState)) {
|
|
1468
|
+
if (transformToStreamlined) {
|
|
1469
|
+
const transformed = transformToStreamlined(message);
|
|
1470
|
+
if (transformed) {
|
|
1471
|
+
await structuredIO.write(transformed);
|
|
1472
|
+
}
|
|
1473
|
+
} else if (options.outputFormat === "stream-json" && options.verbose) {
|
|
1474
|
+
await structuredIO.write(message);
|
|
1475
|
+
}
|
|
1476
|
+
if (message.type !== "control_response" && message.type !== "control_request" && message.type !== "control_cancel_request" && !(message.type === "system" && (message.subtype === "session_state_changed" || message.subtype === "task_notification" || message.subtype === "task_started" || message.subtype === "task_progress" || message.subtype === "post_turn_summary")) && message.type !== "stream_event" && message.type !== "keep_alive" && message.type !== "streamlined_text" && message.type !== "streamlined_tool_use_summary" && message.type !== "prompt_suggestion") {
|
|
1477
|
+
if (needsFullArray) {
|
|
1478
|
+
messages.push(message);
|
|
1479
|
+
}
|
|
1480
|
+
lastMessage = message;
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
switch (options.outputFormat) {
|
|
1484
|
+
case "json":
|
|
1485
|
+
if (!lastMessage || lastMessage.type !== "result") {
|
|
1486
|
+
throw new Error("No messages returned");
|
|
1487
|
+
}
|
|
1488
|
+
if (options.verbose) {
|
|
1489
|
+
writeToStdout(jsonStringify(messages) + `
|
|
1490
|
+
`);
|
|
1491
|
+
break;
|
|
1492
|
+
}
|
|
1493
|
+
writeToStdout(jsonStringify(lastMessage) + `
|
|
1494
|
+
`);
|
|
1495
|
+
break;
|
|
1496
|
+
case "stream-json":
|
|
1497
|
+
break;
|
|
1498
|
+
default:
|
|
1499
|
+
if (!lastMessage || lastMessage.type !== "result") {
|
|
1500
|
+
throw new Error("No messages returned");
|
|
1501
|
+
}
|
|
1502
|
+
switch (lastMessage.subtype) {
|
|
1503
|
+
case "success":
|
|
1504
|
+
writeToStdout(lastMessage.result.endsWith(`
|
|
1505
|
+
`) ? lastMessage.result : lastMessage.result + `
|
|
1506
|
+
`);
|
|
1507
|
+
break;
|
|
1508
|
+
case "error_during_execution":
|
|
1509
|
+
writeToStdout(`Execution error`);
|
|
1510
|
+
break;
|
|
1511
|
+
case "error_max_turns":
|
|
1512
|
+
writeToStdout(`Error: Reached max turns (${options.maxTurns})`);
|
|
1513
|
+
break;
|
|
1514
|
+
case "error_max_budget_usd":
|
|
1515
|
+
writeToStdout(`Error: Exceeded USD budget (${options.maxBudgetUsd})`);
|
|
1516
|
+
break;
|
|
1517
|
+
case "error_max_structured_output_retries":
|
|
1518
|
+
writeToStdout(`Error: Failed to provide valid structured output after maximum retries`);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
logHeadlessProfilerTurn();
|
|
1522
|
+
if (isExtractModeActive()) {
|
|
1523
|
+
const extractMemoriesModule = await loadExtractMemoriesModule();
|
|
1524
|
+
await extractMemoriesModule.drainPendingExtraction();
|
|
1525
|
+
}
|
|
1526
|
+
gracefulShutdownSync(lastMessage?.type === "result" && lastMessage?.is_error ? 1 : 0);
|
|
1527
|
+
}
|
|
1528
|
+
function runHeadlessStreaming(structuredIO, mcpClients, commands, tools, initialMessages, canUseTool, sdkMcpConfigs, getAppState, setAppState, agents, options, turnInterruptionState) {
|
|
1529
|
+
let running = false;
|
|
1530
|
+
let runPhase;
|
|
1531
|
+
let inputClosed = false;
|
|
1532
|
+
let shutdownPromptInjected = false;
|
|
1533
|
+
let heldBackResult = null;
|
|
1534
|
+
let abortController;
|
|
1535
|
+
const output = structuredIO.outbound;
|
|
1536
|
+
const sigintHandler = () => {
|
|
1537
|
+
logForDiagnosticsNoPII("info", "shutdown_signal", { signal: "SIGINT" });
|
|
1538
|
+
if (abortController && !abortController.signal.aborted) {
|
|
1539
|
+
abortController.abort();
|
|
1540
|
+
}
|
|
1541
|
+
gracefulShutdown(0);
|
|
1542
|
+
};
|
|
1543
|
+
process.on("SIGINT", sigintHandler);
|
|
1544
|
+
registerCleanup(async () => {
|
|
1545
|
+
const bg = {};
|
|
1546
|
+
for (const t of getRunningTasks(getAppState())) {
|
|
1547
|
+
if (isBackgroundTask(t))
|
|
1548
|
+
bg[t.type] = (bg[t.type] ?? 0) + 1;
|
|
1549
|
+
}
|
|
1550
|
+
logForDiagnosticsNoPII("info", "run_state_at_shutdown", {
|
|
1551
|
+
run_active: running,
|
|
1552
|
+
run_phase: runPhase,
|
|
1553
|
+
worker_status: getSessionState(),
|
|
1554
|
+
internal_events_pending: structuredIO.internalEventsPending,
|
|
1555
|
+
bg_tasks: bg
|
|
1556
|
+
});
|
|
1557
|
+
});
|
|
1558
|
+
setPermissionModeChangedListener((newMode) => {
|
|
1559
|
+
if (newMode === "default" || newMode === "acceptEdits" || newMode === "bypassPermissions" || newMode === "plan" || newMode === "auto" || newMode === "dontAsk") {
|
|
1560
|
+
output.enqueue({
|
|
1561
|
+
type: "system",
|
|
1562
|
+
subtype: "status",
|
|
1563
|
+
status: null,
|
|
1564
|
+
permissionMode: newMode,
|
|
1565
|
+
uuid: randomUUID2(),
|
|
1566
|
+
session_id: getSessionId()
|
|
1567
|
+
});
|
|
1568
|
+
}
|
|
1569
|
+
});
|
|
1570
|
+
const suggestionState = {
|
|
1571
|
+
abortController: null,
|
|
1572
|
+
inflightPromise: null,
|
|
1573
|
+
lastEmitted: null,
|
|
1574
|
+
pendingSuggestion: null,
|
|
1575
|
+
pendingLastEmittedEntry: null
|
|
1576
|
+
};
|
|
1577
|
+
let unsubscribeAuthStatus;
|
|
1578
|
+
if (options.enableAuthStatus) {
|
|
1579
|
+
const authStatusManager = AwsAuthStatusManager.getInstance();
|
|
1580
|
+
unsubscribeAuthStatus = authStatusManager.subscribe((status) => {
|
|
1581
|
+
output.enqueue({
|
|
1582
|
+
type: "auth_status",
|
|
1583
|
+
isAuthenticating: status.isAuthenticating,
|
|
1584
|
+
output: status.output,
|
|
1585
|
+
error: status.error,
|
|
1586
|
+
uuid: randomUUID2(),
|
|
1587
|
+
session_id: getSessionId()
|
|
1588
|
+
});
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
const rateLimitListener = (limits) => {
|
|
1592
|
+
const rateLimitInfo = toSDKRateLimitInfo(limits);
|
|
1593
|
+
if (rateLimitInfo) {
|
|
1594
|
+
output.enqueue({
|
|
1595
|
+
type: "rate_limit_event",
|
|
1596
|
+
rate_limit_info: rateLimitInfo,
|
|
1597
|
+
uuid: randomUUID2(),
|
|
1598
|
+
session_id: getSessionId()
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
statusListeners.add(rateLimitListener);
|
|
1603
|
+
const mutableMessages = initialMessages;
|
|
1604
|
+
let readFileState = extractReadFilesFromMessages(initialMessages, cwd(), READ_FILE_STATE_CACHE_SIZE);
|
|
1605
|
+
const pendingSeeds = createFileStateCacheWithSizeLimit(READ_FILE_STATE_CACHE_SIZE);
|
|
1606
|
+
const resumeInterruptedTurnEnv = process.env.CLAUDE_CODE_RESUME_INTERRUPTED_TURN;
|
|
1607
|
+
if (turnInterruptionState && turnInterruptionState.kind !== "none" && resumeInterruptedTurnEnv) {
|
|
1608
|
+
logForDebugging(`[print.ts] Auto-resuming interrupted turn (kind: ${turnInterruptionState.kind})`);
|
|
1609
|
+
removeInterruptedMessage(mutableMessages, turnInterruptionState.message);
|
|
1610
|
+
enqueue({
|
|
1611
|
+
mode: "prompt",
|
|
1612
|
+
value: turnInterruptionState.message.message.content,
|
|
1613
|
+
uuid: randomUUID2()
|
|
1614
|
+
});
|
|
1615
|
+
}
|
|
1616
|
+
const modelOptions = getModelOptions();
|
|
1617
|
+
const modelInfos = modelOptions.map((option) => {
|
|
1618
|
+
const modelId = option.value === null ? "default" : option.value;
|
|
1619
|
+
const resolvedModel = modelId === "default" ? getDefaultMainLoopModel() : parseUserSpecifiedModel(modelId);
|
|
1620
|
+
const hasEffort = modelSupportsEffort(resolvedModel);
|
|
1621
|
+
const hasAdaptiveThinking = modelSupportsAdaptiveThinking(resolvedModel);
|
|
1622
|
+
const hasFastMode = isFastModeSupportedByModel(option.value);
|
|
1623
|
+
const hasAutoMode = modelSupportsAutoMode(resolvedModel);
|
|
1624
|
+
return {
|
|
1625
|
+
name: modelId,
|
|
1626
|
+
value: modelId,
|
|
1627
|
+
displayName: option.label,
|
|
1628
|
+
description: option.description,
|
|
1629
|
+
...hasEffort && {
|
|
1630
|
+
supportsEffort: true,
|
|
1631
|
+
supportedEffortLevels: modelSupportsMaxEffort(resolvedModel) ? [...EFFORT_LEVELS] : EFFORT_LEVELS.filter((l) => l !== "max")
|
|
1632
|
+
},
|
|
1633
|
+
...hasAdaptiveThinking && { supportsAdaptiveThinking: true },
|
|
1634
|
+
...hasFastMode && { supportsFastMode: true },
|
|
1635
|
+
...hasAutoMode && { supportsAutoMode: true }
|
|
1636
|
+
};
|
|
1637
|
+
});
|
|
1638
|
+
let activeUserSpecifiedModel = options.userSpecifiedModel;
|
|
1639
|
+
function injectModelSwitchBreadcrumbs(modelArg, resolvedModel) {
|
|
1640
|
+
const breadcrumbs = createModelSwitchBreadcrumbs(modelArg, modelDisplayString(resolvedModel));
|
|
1641
|
+
mutableMessages.push(...breadcrumbs);
|
|
1642
|
+
for (const crumb of breadcrumbs) {
|
|
1643
|
+
if (typeof crumb.message.content === "string" && crumb.message.content.includes(`<${LOCAL_COMMAND_STDOUT_TAG}>`)) {
|
|
1644
|
+
output.enqueue({
|
|
1645
|
+
type: "user",
|
|
1646
|
+
content: crumb.message.content,
|
|
1647
|
+
message: crumb.message,
|
|
1648
|
+
session_id: getSessionId(),
|
|
1649
|
+
parent_tool_use_id: null,
|
|
1650
|
+
uuid: crumb.uuid,
|
|
1651
|
+
timestamp: crumb.timestamp,
|
|
1652
|
+
isReplay: true
|
|
1653
|
+
});
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
let sdkClients = [];
|
|
1658
|
+
let sdkTools = [];
|
|
1659
|
+
const elicitationRegistered = new Set;
|
|
1660
|
+
function registerElicitationHandlers(clients) {
|
|
1661
|
+
for (const connection of clients) {
|
|
1662
|
+
if (connection.type !== "connected" || elicitationRegistered.has(connection.name)) {
|
|
1663
|
+
continue;
|
|
1664
|
+
}
|
|
1665
|
+
if (connection.config.type === "sdk") {
|
|
1666
|
+
continue;
|
|
1667
|
+
}
|
|
1668
|
+
const serverName = connection.name;
|
|
1669
|
+
try {
|
|
1670
|
+
connection.client.setRequestHandler(ElicitRequestSchema, async (request, extra) => {
|
|
1671
|
+
logMCPDebug(serverName, `Elicitation request received in print mode: ${jsonStringify(request)}`);
|
|
1672
|
+
const mode = request.params.mode === "url" ? "url" : "form";
|
|
1673
|
+
logEvent("tengu_mcp_elicitation_shown", {
|
|
1674
|
+
mode
|
|
1675
|
+
});
|
|
1676
|
+
const hookResponse = await runElicitationHooks(serverName, request.params, extra.signal);
|
|
1677
|
+
if (hookResponse) {
|
|
1678
|
+
logMCPDebug(serverName, `Elicitation resolved by hook: ${jsonStringify(hookResponse)}`);
|
|
1679
|
+
logEvent("tengu_mcp_elicitation_response", {
|
|
1680
|
+
mode,
|
|
1681
|
+
action: hookResponse.action
|
|
1682
|
+
});
|
|
1683
|
+
return hookResponse;
|
|
1684
|
+
}
|
|
1685
|
+
const url = "url" in request.params ? request.params.url : undefined;
|
|
1686
|
+
const requestedSchema = "requestedSchema" in request.params ? request.params.requestedSchema : undefined;
|
|
1687
|
+
const elicitationId = "elicitationId" in request.params ? request.params.elicitationId : undefined;
|
|
1688
|
+
const rawResult = await structuredIO.handleElicitation(serverName, request.params.message, requestedSchema, extra.signal, mode, url, elicitationId);
|
|
1689
|
+
const result = await runElicitationResultHooks(serverName, rawResult, extra.signal, mode, elicitationId);
|
|
1690
|
+
logEvent("tengu_mcp_elicitation_response", {
|
|
1691
|
+
mode,
|
|
1692
|
+
action: result.action
|
|
1693
|
+
});
|
|
1694
|
+
return result;
|
|
1695
|
+
});
|
|
1696
|
+
connection.client.setNotificationHandler(ElicitationCompleteNotificationSchema, (notification) => {
|
|
1697
|
+
const { elicitationId } = notification.params;
|
|
1698
|
+
logMCPDebug(serverName, `Elicitation completion notification: ${elicitationId}`);
|
|
1699
|
+
executeNotificationHooks({
|
|
1700
|
+
message: `MCP server "${serverName}" confirmed elicitation ${elicitationId} complete`,
|
|
1701
|
+
notificationType: "elicitation_complete"
|
|
1702
|
+
});
|
|
1703
|
+
output.enqueue({
|
|
1704
|
+
type: "system",
|
|
1705
|
+
subtype: "elicitation_complete",
|
|
1706
|
+
mcp_server_name: serverName,
|
|
1707
|
+
elicitation_id: elicitationId,
|
|
1708
|
+
uuid: randomUUID2(),
|
|
1709
|
+
session_id: getSessionId()
|
|
1710
|
+
});
|
|
1711
|
+
});
|
|
1712
|
+
elicitationRegistered.add(serverName);
|
|
1713
|
+
} catch {}
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
async function updateSdkMcp() {
|
|
1717
|
+
const currentServerNames = new Set(Object.keys(sdkMcpConfigs));
|
|
1718
|
+
const connectedServerNames = new Set(sdkClients.map((c) => c.name));
|
|
1719
|
+
const hasNewServers = Array.from(currentServerNames).some((name) => !connectedServerNames.has(name));
|
|
1720
|
+
const hasRemovedServers = Array.from(connectedServerNames).some((name) => !currentServerNames.has(name));
|
|
1721
|
+
const hasPendingSdkClients = sdkClients.some((c) => c.type === "pending");
|
|
1722
|
+
const hasFailedSdkClients = sdkClients.some((c) => c.type === "failed");
|
|
1723
|
+
const haveServersChanged = hasNewServers || hasRemovedServers || hasPendingSdkClients || hasFailedSdkClients;
|
|
1724
|
+
if (haveServersChanged) {
|
|
1725
|
+
for (const client of sdkClients) {
|
|
1726
|
+
if (!currentServerNames.has(client.name)) {
|
|
1727
|
+
if (client.type === "connected") {
|
|
1728
|
+
await client.cleanup();
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
const sdkSetup = await setupSdkMcpClients(sdkMcpConfigs, (serverName, message) => structuredIO.sendMcpMessage(serverName, message));
|
|
1733
|
+
sdkClients = sdkSetup.clients;
|
|
1734
|
+
sdkTools = sdkSetup.tools;
|
|
1735
|
+
const allSdkNames = uniq([...connectedServerNames, ...currentServerNames]);
|
|
1736
|
+
setAppState((prev) => ({
|
|
1737
|
+
...prev,
|
|
1738
|
+
mcp: {
|
|
1739
|
+
...prev.mcp,
|
|
1740
|
+
tools: [
|
|
1741
|
+
...prev.mcp.tools.filter((t) => !allSdkNames.some((name) => t.name.startsWith(getMcpPrefix(name)))),
|
|
1742
|
+
...sdkTools
|
|
1743
|
+
]
|
|
1744
|
+
}
|
|
1745
|
+
}));
|
|
1746
|
+
setupVscodeSdkMcp(sdkClients);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
updateSdkMcp();
|
|
1750
|
+
let dynamicMcpState = {
|
|
1751
|
+
clients: [],
|
|
1752
|
+
tools: [],
|
|
1753
|
+
configs: {}
|
|
1754
|
+
};
|
|
1755
|
+
const buildAllTools = (appState) => {
|
|
1756
|
+
const assembledTools = assembleToolPool(appState.toolPermissionContext, appState.mcp.tools);
|
|
1757
|
+
let allTools = uniqBy_default(mergeAndFilterTools([...tools, ...sdkTools, ...dynamicMcpState.tools], assembledTools, appState.toolPermissionContext.mode), "name");
|
|
1758
|
+
if (options.permissionPromptToolName) {
|
|
1759
|
+
allTools = allTools.filter((tool) => !toolMatchesName(tool, options.permissionPromptToolName));
|
|
1760
|
+
}
|
|
1761
|
+
const initJsonSchema = getInitJsonSchema();
|
|
1762
|
+
if (initJsonSchema && !options.jsonSchema) {
|
|
1763
|
+
const syntheticOutputResult = createSyntheticOutputTool(initJsonSchema);
|
|
1764
|
+
if ("tool" in syntheticOutputResult) {
|
|
1765
|
+
allTools = [...allTools, syntheticOutputResult.tool];
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
return allTools;
|
|
1769
|
+
};
|
|
1770
|
+
let bridgeHandle = null;
|
|
1771
|
+
let bridgeLastForwardedIndex = 0;
|
|
1772
|
+
function forwardMessagesToBridge() {
|
|
1773
|
+
if (!bridgeHandle)
|
|
1774
|
+
return;
|
|
1775
|
+
const startIndex = Math.min(bridgeLastForwardedIndex, mutableMessages.length);
|
|
1776
|
+
const newMessages = mutableMessages.slice(startIndex).filter((m) => m.type === "user" || m.type === "assistant");
|
|
1777
|
+
bridgeLastForwardedIndex = mutableMessages.length;
|
|
1778
|
+
if (newMessages.length > 0) {
|
|
1779
|
+
bridgeHandle.writeMessages(newMessages);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
let mcpChangesPromise = Promise.resolve({
|
|
1783
|
+
response: {
|
|
1784
|
+
added: [],
|
|
1785
|
+
removed: [],
|
|
1786
|
+
errors: {}
|
|
1787
|
+
},
|
|
1788
|
+
sdkServersChanged: false
|
|
1789
|
+
});
|
|
1790
|
+
function applyMcpServerChanges(servers) {
|
|
1791
|
+
const doWork = async () => {
|
|
1792
|
+
const oldSdkClientNames = new Set(sdkClients.map((c) => c.name));
|
|
1793
|
+
const result = await handleMcpSetServers(servers, { configs: sdkMcpConfigs, clients: sdkClients, tools: sdkTools }, dynamicMcpState, setAppState);
|
|
1794
|
+
for (const key of Object.keys(sdkMcpConfigs)) {
|
|
1795
|
+
delete sdkMcpConfigs[key];
|
|
1796
|
+
}
|
|
1797
|
+
Object.assign(sdkMcpConfigs, result.newSdkState.configs);
|
|
1798
|
+
sdkClients = result.newSdkState.clients;
|
|
1799
|
+
sdkTools = result.newSdkState.tools;
|
|
1800
|
+
dynamicMcpState = result.newDynamicState;
|
|
1801
|
+
if (result.sdkServersChanged) {
|
|
1802
|
+
const newSdkClientNames = new Set(sdkClients.map((c) => c.name));
|
|
1803
|
+
const allSdkNames = uniq([...oldSdkClientNames, ...newSdkClientNames]);
|
|
1804
|
+
setAppState((prev) => ({
|
|
1805
|
+
...prev,
|
|
1806
|
+
mcp: {
|
|
1807
|
+
...prev.mcp,
|
|
1808
|
+
tools: [
|
|
1809
|
+
...prev.mcp.tools.filter((t) => !allSdkNames.some((name) => t.name.startsWith(getMcpPrefix(name)))),
|
|
1810
|
+
...sdkTools
|
|
1811
|
+
]
|
|
1812
|
+
}
|
|
1813
|
+
}));
|
|
1814
|
+
}
|
|
1815
|
+
return {
|
|
1816
|
+
response: result.response,
|
|
1817
|
+
sdkServersChanged: result.sdkServersChanged
|
|
1818
|
+
};
|
|
1819
|
+
};
|
|
1820
|
+
mcpChangesPromise = mcpChangesPromise.then(doWork, doWork);
|
|
1821
|
+
return mcpChangesPromise;
|
|
1822
|
+
}
|
|
1823
|
+
function buildMcpServerStatuses() {
|
|
1824
|
+
const currentAppState = getAppState();
|
|
1825
|
+
const currentMcpClients = currentAppState.mcp.clients;
|
|
1826
|
+
const allMcpTools = uniqBy_default([...currentAppState.mcp.tools, ...dynamicMcpState.tools], "name");
|
|
1827
|
+
const existingNames = new Set([
|
|
1828
|
+
...currentMcpClients.map((c) => c.name),
|
|
1829
|
+
...sdkClients.map((c) => c.name)
|
|
1830
|
+
]);
|
|
1831
|
+
return [
|
|
1832
|
+
...currentMcpClients,
|
|
1833
|
+
...sdkClients,
|
|
1834
|
+
...dynamicMcpState.clients.filter((c) => !existingNames.has(c.name))
|
|
1835
|
+
].map((connection) => {
|
|
1836
|
+
let config;
|
|
1837
|
+
if (connection.config.type === "sse" || connection.config.type === "http") {
|
|
1838
|
+
config = {
|
|
1839
|
+
type: connection.config.type,
|
|
1840
|
+
url: connection.config.url,
|
|
1841
|
+
headers: connection.config.headers,
|
|
1842
|
+
oauth: connection.config.oauth
|
|
1843
|
+
};
|
|
1844
|
+
} else if (connection.config.type === "claudeai-proxy") {
|
|
1845
|
+
config = {
|
|
1846
|
+
type: "claudeai-proxy",
|
|
1847
|
+
url: connection.config.url,
|
|
1848
|
+
id: connection.config.id
|
|
1849
|
+
};
|
|
1850
|
+
} else if (connection.config.type === "stdio" || connection.config.type === undefined) {
|
|
1851
|
+
const stdioConfig = connection.config;
|
|
1852
|
+
config = {
|
|
1853
|
+
type: "stdio",
|
|
1854
|
+
command: stdioConfig.command,
|
|
1855
|
+
args: stdioConfig.args
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1858
|
+
const serverTools = connection.type === "connected" ? filterToolsByServer(allMcpTools, connection.name).map((tool) => ({
|
|
1859
|
+
name: tool.mcpInfo?.toolName ?? tool.name,
|
|
1860
|
+
annotations: {
|
|
1861
|
+
readOnly: tool.isReadOnly({}) || undefined,
|
|
1862
|
+
destructive: tool.isDestructive?.({}) || undefined,
|
|
1863
|
+
openWorld: tool.isOpenWorld?.({}) || undefined
|
|
1864
|
+
}
|
|
1865
|
+
})) : undefined;
|
|
1866
|
+
let capabilities;
|
|
1867
|
+
if (connection.type === "connected" && connection.capabilities.experimental) {
|
|
1868
|
+
const exp = { ...connection.capabilities.experimental };
|
|
1869
|
+
if (exp["claude/channel"] && (!isChannelsEnabled() || !isChannelAllowlisted(connection.config.pluginSource))) {
|
|
1870
|
+
delete exp["claude/channel"];
|
|
1871
|
+
}
|
|
1872
|
+
if (Object.keys(exp).length > 0) {
|
|
1873
|
+
capabilities = { experimental: exp };
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
return {
|
|
1877
|
+
name: connection.name,
|
|
1878
|
+
status: connection.type,
|
|
1879
|
+
serverInfo: connection.type === "connected" ? connection.serverInfo : undefined,
|
|
1880
|
+
error: connection.type === "failed" ? connection.error : undefined,
|
|
1881
|
+
config,
|
|
1882
|
+
scope: connection.config.scope,
|
|
1883
|
+
tools: serverTools,
|
|
1884
|
+
capabilities
|
|
1885
|
+
};
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
async function installPluginsAndApplyMcpInBackground() {
|
|
1889
|
+
try {
|
|
1890
|
+
await Promise.all([
|
|
1891
|
+
Promise.resolve(),
|
|
1892
|
+
withDiagnosticsTiming("headless_managed_settings_wait", () => waitForRemoteManagedSettingsToLoad())
|
|
1893
|
+
]);
|
|
1894
|
+
const pluginsInstalled = await installPluginsForHeadless();
|
|
1895
|
+
if (pluginsInstalled) {
|
|
1896
|
+
await applyPluginMcpDiff();
|
|
1897
|
+
}
|
|
1898
|
+
} catch (error) {
|
|
1899
|
+
logError(error);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
let pluginInstallPromise = null;
|
|
1903
|
+
if (!isBareMode()) {
|
|
1904
|
+
if (isEnvTruthy(process.env.CLAUDE_CODE_SYNC_PLUGIN_INSTALL)) {
|
|
1905
|
+
pluginInstallPromise = installPluginsAndApplyMcpInBackground();
|
|
1906
|
+
} else {
|
|
1907
|
+
installPluginsAndApplyMcpInBackground();
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
const idleTimeout = createIdleTimeoutManager(() => !running);
|
|
1911
|
+
let currentCommands = commands;
|
|
1912
|
+
let currentAgents = agents;
|
|
1913
|
+
async function refreshPluginState() {
|
|
1914
|
+
const { agentDefinitions: freshAgentDefs } = await refreshActivePlugins(setAppState);
|
|
1915
|
+
currentCommands = await getCommands(cwd());
|
|
1916
|
+
const sdkAgents = currentAgents.filter((a) => a.source === "flagSettings");
|
|
1917
|
+
currentAgents = [...freshAgentDefs.allAgents, ...sdkAgents];
|
|
1918
|
+
}
|
|
1919
|
+
async function applyPluginMcpDiff() {
|
|
1920
|
+
const { servers: newConfigs } = await getAllMcpConfigs();
|
|
1921
|
+
const supportedConfigs = {};
|
|
1922
|
+
for (const [name, config] of Object.entries(newConfigs)) {
|
|
1923
|
+
const type = config.type;
|
|
1924
|
+
if (type === undefined || type === "stdio" || type === "sse" || type === "http" || type === "sdk") {
|
|
1925
|
+
supportedConfigs[name] = config;
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
for (const [name, config] of Object.entries(sdkMcpConfigs)) {
|
|
1929
|
+
if (config.type === "sdk" && !(name in supportedConfigs)) {
|
|
1930
|
+
supportedConfigs[name] = config;
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
const { response, sdkServersChanged } = await applyMcpServerChanges(supportedConfigs);
|
|
1934
|
+
if (sdkServersChanged) {
|
|
1935
|
+
updateSdkMcp();
|
|
1936
|
+
}
|
|
1937
|
+
logForDebugging(`Headless MCP refresh: added=${response.added.length}, removed=${response.removed.length}`);
|
|
1938
|
+
}
|
|
1939
|
+
const unsubscribeSkillChanges = skillChangeDetector.subscribe(() => {
|
|
1940
|
+
clearCommandsCache();
|
|
1941
|
+
getCommands(cwd()).then((newCommands) => {
|
|
1942
|
+
currentCommands = newCommands;
|
|
1943
|
+
});
|
|
1944
|
+
});
|
|
1945
|
+
const scheduleProactiveTick = () => {
|
|
1946
|
+
setTimeout(() => {
|
|
1947
|
+
if (!proactiveModule?.isProactiveActive() || proactiveModule.isProactivePaused() || inputClosed) {
|
|
1948
|
+
return;
|
|
1949
|
+
}
|
|
1950
|
+
(async () => {
|
|
1951
|
+
const commands2 = await createProactiveAutonomyCommands({
|
|
1952
|
+
basePrompt: `<${TICK_TAG}>${new Date().toLocaleTimeString()}</${TICK_TAG}>`,
|
|
1953
|
+
currentDir: cwd(),
|
|
1954
|
+
shouldCreate: () => !inputClosed
|
|
1955
|
+
});
|
|
1956
|
+
for (const command of commands2) {
|
|
1957
|
+
if (inputClosed) {
|
|
1958
|
+
return;
|
|
1959
|
+
}
|
|
1960
|
+
enqueue({
|
|
1961
|
+
...command,
|
|
1962
|
+
uuid: randomUUID2()
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
run();
|
|
1966
|
+
})();
|
|
1967
|
+
}, 0);
|
|
1968
|
+
};
|
|
1969
|
+
subscribeToCommandQueue(() => {
|
|
1970
|
+
if (abortController && getCommandsByMaxPriority("now").length > 0) {
|
|
1971
|
+
abortController.abort("interrupt");
|
|
1972
|
+
}
|
|
1973
|
+
});
|
|
1974
|
+
const run = async () => {
|
|
1975
|
+
if (running) {
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
running = true;
|
|
1979
|
+
runPhase = undefined;
|
|
1980
|
+
notifySessionStateChanged("running");
|
|
1981
|
+
idleTimeout.stop();
|
|
1982
|
+
headlessProfilerCheckpoint("run_entry");
|
|
1983
|
+
await updateSdkMcp();
|
|
1984
|
+
headlessProfilerCheckpoint("after_updateSdkMcp");
|
|
1985
|
+
if (pluginInstallPromise) {
|
|
1986
|
+
const timeoutMs = parseInt(process.env.CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS || "", 10);
|
|
1987
|
+
if (timeoutMs > 0) {
|
|
1988
|
+
const timeout = sleep(timeoutMs).then(() => "timeout");
|
|
1989
|
+
const result = await Promise.race([pluginInstallPromise, timeout]);
|
|
1990
|
+
if (result === "timeout") {
|
|
1991
|
+
logError(new Error(`CLAUDE_CODE_SYNC_PLUGIN_INSTALL: plugin installation timed out after ${timeoutMs}ms`));
|
|
1992
|
+
logEvent("tengu_sync_plugin_install_timeout", {
|
|
1993
|
+
timeout_ms: timeoutMs
|
|
1994
|
+
});
|
|
1995
|
+
}
|
|
1996
|
+
} else {
|
|
1997
|
+
await pluginInstallPromise;
|
|
1998
|
+
}
|
|
1999
|
+
pluginInstallPromise = null;
|
|
2000
|
+
await refreshPluginState();
|
|
2001
|
+
const { setupPluginHookHotReload } = await import("./chunk-wcggm5ja.js");
|
|
2002
|
+
setupPluginHookHotReload();
|
|
2003
|
+
}
|
|
2004
|
+
const isMainThread = (cmd) => cmd.agentId === undefined;
|
|
2005
|
+
try {
|
|
2006
|
+
let command;
|
|
2007
|
+
let waitingForAgents = false;
|
|
2008
|
+
const drainCommandQueue = async () => {
|
|
2009
|
+
while (command = dequeue(isMainThread)) {
|
|
2010
|
+
if (command.mode !== "prompt" && command.mode !== "orphaned-permission" && command.mode !== "task-notification") {
|
|
2011
|
+
throw new Error("only prompt commands are supported in streaming mode");
|
|
2012
|
+
}
|
|
2013
|
+
const batch = [command];
|
|
2014
|
+
if (command.mode === "prompt") {
|
|
2015
|
+
while (canBatchWith(command, peek(isMainThread))) {
|
|
2016
|
+
batch.push(dequeue(isMainThread));
|
|
2017
|
+
}
|
|
2018
|
+
if (batch.length > 1) {
|
|
2019
|
+
command = {
|
|
2020
|
+
...command,
|
|
2021
|
+
value: joinPromptValues(batch.map((c) => c.value)),
|
|
2022
|
+
uuid: batch.findLast((c) => c.uuid)?.uuid ?? command.uuid
|
|
2023
|
+
};
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
const batchUuids = batch.map((c) => c.uuid).filter((u) => u !== undefined);
|
|
2027
|
+
if (options.replayUserMessages && batch.length > 1) {
|
|
2028
|
+
for (const c of batch) {
|
|
2029
|
+
if (c.uuid && c.uuid !== command.uuid) {
|
|
2030
|
+
output.enqueue({
|
|
2031
|
+
type: "user",
|
|
2032
|
+
content: c.value,
|
|
2033
|
+
message: { role: "user", content: c.value },
|
|
2034
|
+
session_id: getSessionId(),
|
|
2035
|
+
parent_tool_use_id: null,
|
|
2036
|
+
uuid: c.uuid,
|
|
2037
|
+
isReplay: true
|
|
2038
|
+
});
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
const appState = getAppState();
|
|
2043
|
+
const allMcpClients = [
|
|
2044
|
+
...appState.mcp.clients,
|
|
2045
|
+
...sdkClients,
|
|
2046
|
+
...dynamicMcpState.clients
|
|
2047
|
+
];
|
|
2048
|
+
registerElicitationHandlers(allMcpClients);
|
|
2049
|
+
for (const client of allMcpClients) {
|
|
2050
|
+
reregisterChannelHandlerAfterReconnect(client);
|
|
2051
|
+
}
|
|
2052
|
+
const allTools = buildAllTools(appState);
|
|
2053
|
+
for (const uuid of batchUuids) {
|
|
2054
|
+
notifyCommandLifecycle(uuid, "started");
|
|
2055
|
+
}
|
|
2056
|
+
if (command.mode === "task-notification") {
|
|
2057
|
+
const notificationText = typeof command.value === "string" ? command.value : "";
|
|
2058
|
+
const taskIdMatch = notificationText.match(/<task-id>([^<]+)<\/task-id>/);
|
|
2059
|
+
const toolUseIdMatch = notificationText.match(/<tool-use-id>([^<]+)<\/tool-use-id>/);
|
|
2060
|
+
const outputFileMatch = notificationText.match(/<output-file>([^<]+)<\/output-file>/);
|
|
2061
|
+
const statusMatch = notificationText.match(/<status>([^<]+)<\/status>/);
|
|
2062
|
+
const summaryMatch = notificationText.match(/<summary>([^<]+)<\/summary>/);
|
|
2063
|
+
const isValidStatus = (s) => s === "completed" || s === "failed" || s === "stopped" || s === "killed";
|
|
2064
|
+
const rawStatus = statusMatch?.[1];
|
|
2065
|
+
const status = isValidStatus(rawStatus) ? rawStatus === "killed" ? "stopped" : rawStatus : "completed";
|
|
2066
|
+
const usageMatch = notificationText.match(/<usage>([\s\S]*?)<\/usage>/);
|
|
2067
|
+
const usageContent = usageMatch?.[1] ?? "";
|
|
2068
|
+
const totalTokensMatch = usageContent.match(/<total_tokens>(\d+)<\/total_tokens>/);
|
|
2069
|
+
const toolUsesMatch = usageContent.match(/<tool_uses>(\d+)<\/tool_uses>/);
|
|
2070
|
+
const durationMsMatch = usageContent.match(/<duration_ms>(\d+)<\/duration_ms>/);
|
|
2071
|
+
if (statusMatch) {
|
|
2072
|
+
output.enqueue({
|
|
2073
|
+
type: "system",
|
|
2074
|
+
subtype: "task_notification",
|
|
2075
|
+
task_id: taskIdMatch?.[1] ?? "",
|
|
2076
|
+
tool_use_id: toolUseIdMatch?.[1],
|
|
2077
|
+
status,
|
|
2078
|
+
output_file: outputFileMatch?.[1] ?? "",
|
|
2079
|
+
summary: summaryMatch?.[1] ?? "",
|
|
2080
|
+
usage: totalTokensMatch && toolUsesMatch ? {
|
|
2081
|
+
total_tokens: parseInt(totalTokensMatch[1], 10),
|
|
2082
|
+
tool_uses: parseInt(toolUsesMatch[1], 10),
|
|
2083
|
+
duration_ms: durationMsMatch ? parseInt(durationMsMatch[1], 10) : 0
|
|
2084
|
+
} : undefined,
|
|
2085
|
+
session_id: getSessionId(),
|
|
2086
|
+
uuid: randomUUID2()
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
const input = command.value;
|
|
2091
|
+
const autonomyRunIds = batch.map((item) => item.autonomy?.runId).filter((runId) => Boolean(runId));
|
|
2092
|
+
if (structuredIO instanceof RemoteIO && command.mode === "prompt") {
|
|
2093
|
+
logEvent("tengu_bridge_message_received", {
|
|
2094
|
+
is_repl: false
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
suggestionState.abortController?.abort();
|
|
2098
|
+
suggestionState.abortController = null;
|
|
2099
|
+
suggestionState.pendingSuggestion = null;
|
|
2100
|
+
suggestionState.pendingLastEmittedEntry = null;
|
|
2101
|
+
if (suggestionState.lastEmitted) {
|
|
2102
|
+
if (command.mode === "prompt") {
|
|
2103
|
+
const inputText = typeof input === "string" ? input : input.find((b) => b.type === "text")?.text;
|
|
2104
|
+
if (typeof inputText === "string") {
|
|
2105
|
+
logSuggestionOutcome(suggestionState.lastEmitted.text, inputText, suggestionState.lastEmitted.emittedAt, suggestionState.lastEmitted.promptId, suggestionState.lastEmitted.generationRequestId);
|
|
2106
|
+
}
|
|
2107
|
+
suggestionState.lastEmitted = null;
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
abortController = createAbortController();
|
|
2111
|
+
const turnStartTime = undefined;
|
|
2112
|
+
headlessProfilerCheckpoint("before_ask");
|
|
2113
|
+
startQueryProfile();
|
|
2114
|
+
const cmd = command;
|
|
2115
|
+
for (const runId of autonomyRunIds) {
|
|
2116
|
+
await markAutonomyRunRunning(runId);
|
|
2117
|
+
}
|
|
2118
|
+
let lastResultIsError = false;
|
|
2119
|
+
try {
|
|
2120
|
+
await runWithWorkload(cmd.workload ?? options.workload, async () => {
|
|
2121
|
+
for await (const message of ask({
|
|
2122
|
+
commands: uniqBy_default([...currentCommands, ...appState.mcp.commands], "name"),
|
|
2123
|
+
prompt: input,
|
|
2124
|
+
promptUuid: cmd.uuid,
|
|
2125
|
+
isMeta: cmd.isMeta,
|
|
2126
|
+
cwd: cwd(),
|
|
2127
|
+
tools: allTools,
|
|
2128
|
+
verbose: options.verbose,
|
|
2129
|
+
mcpClients: allMcpClients,
|
|
2130
|
+
thinkingConfig: options.thinkingConfig,
|
|
2131
|
+
maxTurns: options.maxTurns,
|
|
2132
|
+
maxBudgetUsd: options.maxBudgetUsd,
|
|
2133
|
+
taskBudget: options.taskBudget,
|
|
2134
|
+
canUseTool,
|
|
2135
|
+
userSpecifiedModel: activeUserSpecifiedModel,
|
|
2136
|
+
fallbackModel: options.fallbackModel,
|
|
2137
|
+
jsonSchema: getInitJsonSchema() ?? options.jsonSchema,
|
|
2138
|
+
mutableMessages,
|
|
2139
|
+
getReadFileCache: () => pendingSeeds.size === 0 ? readFileState : mergeFileStateCaches(readFileState, pendingSeeds),
|
|
2140
|
+
setReadFileCache: (cache) => {
|
|
2141
|
+
readFileState = cache;
|
|
2142
|
+
for (const [path, seed] of pendingSeeds.entries()) {
|
|
2143
|
+
const existing = readFileState.get(path);
|
|
2144
|
+
if (!existing || seed.timestamp > existing.timestamp) {
|
|
2145
|
+
readFileState.set(path, seed);
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
pendingSeeds.clear();
|
|
2149
|
+
},
|
|
2150
|
+
customSystemPrompt: options.systemPrompt,
|
|
2151
|
+
appendSystemPrompt: options.appendSystemPrompt,
|
|
2152
|
+
getAppState,
|
|
2153
|
+
setAppState,
|
|
2154
|
+
abortController,
|
|
2155
|
+
replayUserMessages: options.replayUserMessages,
|
|
2156
|
+
includePartialMessages: options.includePartialMessages,
|
|
2157
|
+
handleElicitation: (serverName, params, elicitSignal) => structuredIO.handleElicitation(serverName, params.message, undefined, elicitSignal, params.mode, params.url, "elicitationId" in params ? params.elicitationId : undefined),
|
|
2158
|
+
agents: currentAgents,
|
|
2159
|
+
orphanedPermission: cmd.orphanedPermission,
|
|
2160
|
+
setSDKStatus: (status) => {
|
|
2161
|
+
output.enqueue({
|
|
2162
|
+
type: "system",
|
|
2163
|
+
subtype: "status",
|
|
2164
|
+
status,
|
|
2165
|
+
session_id: getSessionId(),
|
|
2166
|
+
uuid: randomUUID2()
|
|
2167
|
+
});
|
|
2168
|
+
}
|
|
2169
|
+
})) {
|
|
2170
|
+
forwardMessagesToBridge();
|
|
2171
|
+
if (message.type === "result") {
|
|
2172
|
+
lastResultIsError = !!message.is_error;
|
|
2173
|
+
for (const event of drainSdkEvents()) {
|
|
2174
|
+
output.enqueue(event);
|
|
2175
|
+
}
|
|
2176
|
+
const currentState = getAppState();
|
|
2177
|
+
if (getRunningTasks(currentState).some((t) => (t.type === "local_agent" || t.type === "local_workflow") && isBackgroundTask(t))) {
|
|
2178
|
+
heldBackResult = message;
|
|
2179
|
+
} else {
|
|
2180
|
+
heldBackResult = null;
|
|
2181
|
+
output.enqueue(message);
|
|
2182
|
+
}
|
|
2183
|
+
} else {
|
|
2184
|
+
for (const event of drainSdkEvents()) {
|
|
2185
|
+
output.enqueue(event);
|
|
2186
|
+
}
|
|
2187
|
+
output.enqueue(message);
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
});
|
|
2191
|
+
if (lastResultIsError) {
|
|
2192
|
+
for (const runId of autonomyRunIds) {
|
|
2193
|
+
await finalizeAutonomyRunFailed({
|
|
2194
|
+
runId,
|
|
2195
|
+
error: "ask() returned an error result"
|
|
2196
|
+
});
|
|
2197
|
+
}
|
|
2198
|
+
} else {
|
|
2199
|
+
for (const runId of autonomyRunIds) {
|
|
2200
|
+
const nextCommands = await finalizeAutonomyRunCompleted({
|
|
2201
|
+
runId,
|
|
2202
|
+
currentDir: cwd(),
|
|
2203
|
+
priority: "later",
|
|
2204
|
+
workload: cmd.workload ?? options.workload
|
|
2205
|
+
});
|
|
2206
|
+
for (const nextCommand of nextCommands) {
|
|
2207
|
+
enqueue({
|
|
2208
|
+
...nextCommand,
|
|
2209
|
+
uuid: randomUUID2()
|
|
2210
|
+
});
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
} catch (error) {
|
|
2215
|
+
for (const runId of autonomyRunIds) {
|
|
2216
|
+
await finalizeAutonomyRunFailed({
|
|
2217
|
+
runId,
|
|
2218
|
+
error: String(error)
|
|
2219
|
+
});
|
|
2220
|
+
}
|
|
2221
|
+
throw error;
|
|
2222
|
+
}
|
|
2223
|
+
for (const uuid of batchUuids) {
|
|
2224
|
+
notifyCommandLifecycle(uuid, "completed");
|
|
2225
|
+
}
|
|
2226
|
+
forwardMessagesToBridge();
|
|
2227
|
+
bridgeHandle?.sendResult();
|
|
2228
|
+
if (false) {}
|
|
2229
|
+
if (options.promptSuggestions && !isEnvDefinedFalsy(process.env.CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION)) {
|
|
2230
|
+
const state = suggestionState;
|
|
2231
|
+
state.abortController?.abort();
|
|
2232
|
+
const localAbort = new AbortController;
|
|
2233
|
+
suggestionState.abortController = localAbort;
|
|
2234
|
+
const cacheSafeParams = getLastCacheSafeParams();
|
|
2235
|
+
if (!cacheSafeParams) {
|
|
2236
|
+
logSuggestionSuppressed("sdk_no_params", undefined, undefined, "sdk");
|
|
2237
|
+
} else {
|
|
2238
|
+
const ref = { promise: null };
|
|
2239
|
+
ref.promise = (async () => {
|
|
2240
|
+
try {
|
|
2241
|
+
const result = await tryGenerateSuggestion(localAbort, mutableMessages, getAppState, cacheSafeParams, "sdk");
|
|
2242
|
+
if (!result || localAbort.signal.aborted)
|
|
2243
|
+
return;
|
|
2244
|
+
const suggestionMsg = {
|
|
2245
|
+
type: "prompt_suggestion",
|
|
2246
|
+
suggestion: result.suggestion,
|
|
2247
|
+
uuid: randomUUID2(),
|
|
2248
|
+
session_id: getSessionId()
|
|
2249
|
+
};
|
|
2250
|
+
const lastEmittedEntry = {
|
|
2251
|
+
text: result.suggestion,
|
|
2252
|
+
emittedAt: Date.now(),
|
|
2253
|
+
promptId: result.promptId,
|
|
2254
|
+
generationRequestId: result.generationRequestId
|
|
2255
|
+
};
|
|
2256
|
+
if (heldBackResult) {
|
|
2257
|
+
suggestionState.pendingSuggestion = suggestionMsg;
|
|
2258
|
+
suggestionState.pendingLastEmittedEntry = {
|
|
2259
|
+
text: lastEmittedEntry.text,
|
|
2260
|
+
promptId: lastEmittedEntry.promptId,
|
|
2261
|
+
generationRequestId: lastEmittedEntry.generationRequestId
|
|
2262
|
+
};
|
|
2263
|
+
} else {
|
|
2264
|
+
suggestionState.lastEmitted = lastEmittedEntry;
|
|
2265
|
+
output.enqueue(suggestionMsg);
|
|
2266
|
+
}
|
|
2267
|
+
} catch (error) {
|
|
2268
|
+
if (error instanceof Error && (error.name === "AbortError" || error.name === "APIUserAbortError")) {
|
|
2269
|
+
logSuggestionSuppressed("aborted", undefined, undefined, "sdk");
|
|
2270
|
+
return;
|
|
2271
|
+
}
|
|
2272
|
+
logError(toError(error));
|
|
2273
|
+
} finally {
|
|
2274
|
+
if (suggestionState.inflightPromise === ref.promise) {
|
|
2275
|
+
suggestionState.inflightPromise = null;
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
})();
|
|
2279
|
+
suggestionState.inflightPromise = ref.promise;
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
logHeadlessProfilerTurn();
|
|
2283
|
+
logQueryProfileReport();
|
|
2284
|
+
headlessProfilerStartTurn();
|
|
2285
|
+
}
|
|
2286
|
+
};
|
|
2287
|
+
do {
|
|
2288
|
+
for (const event of drainSdkEvents()) {
|
|
2289
|
+
output.enqueue(event);
|
|
2290
|
+
}
|
|
2291
|
+
runPhase = "draining_commands";
|
|
2292
|
+
await drainCommandQueue();
|
|
2293
|
+
waitingForAgents = false;
|
|
2294
|
+
{
|
|
2295
|
+
const state = getAppState();
|
|
2296
|
+
const hasRunningBg = getRunningTasks(state).some((t) => isBackgroundTask(t) && t.type !== "in_process_teammate");
|
|
2297
|
+
const hasMainThreadQueued = peek(isMainThread) !== undefined;
|
|
2298
|
+
if (hasRunningBg || hasMainThreadQueued) {
|
|
2299
|
+
waitingForAgents = true;
|
|
2300
|
+
if (!hasMainThreadQueued) {
|
|
2301
|
+
runPhase = "waiting_for_agents";
|
|
2302
|
+
await sleep(100);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
} while (waitingForAgents);
|
|
2307
|
+
if (heldBackResult) {
|
|
2308
|
+
output.enqueue(heldBackResult);
|
|
2309
|
+
heldBackResult = null;
|
|
2310
|
+
if (suggestionState.pendingSuggestion) {
|
|
2311
|
+
output.enqueue(suggestionState.pendingSuggestion);
|
|
2312
|
+
if (suggestionState.pendingLastEmittedEntry) {
|
|
2313
|
+
suggestionState.lastEmitted = {
|
|
2314
|
+
...suggestionState.pendingLastEmittedEntry,
|
|
2315
|
+
emittedAt: Date.now()
|
|
2316
|
+
};
|
|
2317
|
+
suggestionState.pendingLastEmittedEntry = null;
|
|
2318
|
+
}
|
|
2319
|
+
suggestionState.pendingSuggestion = null;
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
} catch (error) {
|
|
2323
|
+
try {
|
|
2324
|
+
await structuredIO.write({
|
|
2325
|
+
type: "result",
|
|
2326
|
+
subtype: "error_during_execution",
|
|
2327
|
+
duration_ms: 0,
|
|
2328
|
+
duration_api_ms: 0,
|
|
2329
|
+
is_error: true,
|
|
2330
|
+
num_turns: 0,
|
|
2331
|
+
stop_reason: null,
|
|
2332
|
+
session_id: getSessionId(),
|
|
2333
|
+
total_cost_usd: 0,
|
|
2334
|
+
usage: EMPTY_USAGE,
|
|
2335
|
+
modelUsage: {},
|
|
2336
|
+
permission_denials: [],
|
|
2337
|
+
uuid: randomUUID2(),
|
|
2338
|
+
errors: [
|
|
2339
|
+
errorMessage(error),
|
|
2340
|
+
...getInMemoryErrors().map((_) => _.error)
|
|
2341
|
+
]
|
|
2342
|
+
});
|
|
2343
|
+
} catch {}
|
|
2344
|
+
suggestionState.abortController?.abort();
|
|
2345
|
+
gracefulShutdownSync(1);
|
|
2346
|
+
return;
|
|
2347
|
+
} finally {
|
|
2348
|
+
runPhase = "finally_flush";
|
|
2349
|
+
await structuredIO.flushInternalEvents();
|
|
2350
|
+
runPhase = "finally_post_flush";
|
|
2351
|
+
if (!isShuttingDown()) {
|
|
2352
|
+
notifySessionStateChanged("idle");
|
|
2353
|
+
for (const event of drainSdkEvents()) {
|
|
2354
|
+
output.enqueue(event);
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
running = false;
|
|
2358
|
+
idleTimeout.start();
|
|
2359
|
+
}
|
|
2360
|
+
if (proactiveModule?.isProactiveActive() && !proactiveModule.isProactivePaused()) {
|
|
2361
|
+
if (peek(isMainThread) === undefined && !inputClosed) {
|
|
2362
|
+
scheduleProactiveTick();
|
|
2363
|
+
return;
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
if (peek(isMainThread) !== undefined) {
|
|
2367
|
+
run();
|
|
2368
|
+
return;
|
|
2369
|
+
}
|
|
2370
|
+
{
|
|
2371
|
+
const currentAppState = getAppState();
|
|
2372
|
+
const teamContext = currentAppState.teamContext;
|
|
2373
|
+
if (teamContext && isTeamLead(teamContext)) {
|
|
2374
|
+
const agentName = "team-lead";
|
|
2375
|
+
const POLL_INTERVAL_MS = 500;
|
|
2376
|
+
while (true) {
|
|
2377
|
+
const refreshedState = getAppState();
|
|
2378
|
+
const hasActiveTeammates = hasActiveInProcessTeammates(refreshedState) || refreshedState.teamContext && Object.keys(refreshedState.teamContext.teammates).length > 0;
|
|
2379
|
+
if (!hasActiveTeammates) {
|
|
2380
|
+
logForDebugging("[print.ts] No more active teammates, stopping poll");
|
|
2381
|
+
break;
|
|
2382
|
+
}
|
|
2383
|
+
const unread = await readUnreadMessages(agentName, refreshedState.teamContext?.teamName);
|
|
2384
|
+
if (unread.length > 0) {
|
|
2385
|
+
logForDebugging(`[print.ts] Team-lead found ${unread.length} unread messages`);
|
|
2386
|
+
await markMessagesAsRead(agentName, refreshedState.teamContext?.teamName);
|
|
2387
|
+
const teamName = refreshedState.teamContext?.teamName;
|
|
2388
|
+
for (const m of unread) {
|
|
2389
|
+
const shutdownApproval = isShutdownApproved(m.text);
|
|
2390
|
+
if (shutdownApproval && teamName) {
|
|
2391
|
+
const teammateToRemove = shutdownApproval.from;
|
|
2392
|
+
logForDebugging(`[print.ts] Processing shutdown_approved from ${teammateToRemove}`);
|
|
2393
|
+
const teammateId = refreshedState.teamContext?.teammates ? Object.entries(refreshedState.teamContext.teammates).find(([, t]) => t.name === teammateToRemove)?.[0] : undefined;
|
|
2394
|
+
if (teammateId) {
|
|
2395
|
+
removeTeammateFromTeamFile(teamName, {
|
|
2396
|
+
agentId: teammateId,
|
|
2397
|
+
name: teammateToRemove
|
|
2398
|
+
});
|
|
2399
|
+
logForDebugging(`[print.ts] Removed ${teammateToRemove} from team file`);
|
|
2400
|
+
await unassignTeammateTasks(teamName, teammateId, teammateToRemove, "shutdown");
|
|
2401
|
+
setAppState((prev) => {
|
|
2402
|
+
if (!prev.teamContext?.teammates)
|
|
2403
|
+
return prev;
|
|
2404
|
+
if (!(teammateId in prev.teamContext.teammates))
|
|
2405
|
+
return prev;
|
|
2406
|
+
const { [teammateId]: _, ...remainingTeammates } = prev.teamContext.teammates;
|
|
2407
|
+
return {
|
|
2408
|
+
...prev,
|
|
2409
|
+
teamContext: {
|
|
2410
|
+
...prev.teamContext,
|
|
2411
|
+
teammates: remainingTeammates
|
|
2412
|
+
}
|
|
2413
|
+
};
|
|
2414
|
+
});
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
const formatted = unread.map((m) => `<${TEAMMATE_MESSAGE_TAG} teammate_id="${m.from}"${m.color ? ` color="${m.color}"` : ""}>
|
|
2419
|
+
${m.text}
|
|
2420
|
+
</${TEAMMATE_MESSAGE_TAG}>`).join(`
|
|
2421
|
+
|
|
2422
|
+
`);
|
|
2423
|
+
enqueue({
|
|
2424
|
+
mode: "prompt",
|
|
2425
|
+
value: formatted,
|
|
2426
|
+
uuid: randomUUID2()
|
|
2427
|
+
});
|
|
2428
|
+
run();
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2431
|
+
if (inputClosed && !shutdownPromptInjected) {
|
|
2432
|
+
shutdownPromptInjected = true;
|
|
2433
|
+
logForDebugging("[print.ts] Input closed with active teammates, injecting shutdown prompt");
|
|
2434
|
+
enqueue({
|
|
2435
|
+
mode: "prompt",
|
|
2436
|
+
value: SHUTDOWN_TEAM_PROMPT,
|
|
2437
|
+
uuid: randomUUID2()
|
|
2438
|
+
});
|
|
2439
|
+
run();
|
|
2440
|
+
return;
|
|
2441
|
+
}
|
|
2442
|
+
await sleep(POLL_INTERVAL_MS);
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
if (inputClosed) {
|
|
2447
|
+
const hasActiveSwarm = await (async () => {
|
|
2448
|
+
const currentAppState = getAppState();
|
|
2449
|
+
if (hasWorkingInProcessTeammates(currentAppState)) {
|
|
2450
|
+
await waitForTeammatesToBecomeIdle(setAppState, currentAppState);
|
|
2451
|
+
}
|
|
2452
|
+
const refreshedAppState = getAppState();
|
|
2453
|
+
const refreshedTeamContext = refreshedAppState.teamContext;
|
|
2454
|
+
const hasTeamMembersNotCleanedUp = refreshedTeamContext && Object.keys(refreshedTeamContext.teammates).length > 0;
|
|
2455
|
+
return hasTeamMembersNotCleanedUp || hasActiveInProcessTeammates(refreshedAppState);
|
|
2456
|
+
})();
|
|
2457
|
+
if (hasActiveSwarm) {
|
|
2458
|
+
enqueue({
|
|
2459
|
+
mode: "prompt",
|
|
2460
|
+
value: SHUTDOWN_TEAM_PROMPT,
|
|
2461
|
+
uuid: randomUUID2()
|
|
2462
|
+
});
|
|
2463
|
+
run();
|
|
2464
|
+
} else {
|
|
2465
|
+
if (suggestionState.inflightPromise) {
|
|
2466
|
+
await Promise.race([suggestionState.inflightPromise, sleep(5000)]);
|
|
2467
|
+
}
|
|
2468
|
+
suggestionState.abortController?.abort();
|
|
2469
|
+
suggestionState.abortController = null;
|
|
2470
|
+
await finalizePendingAsyncHooks();
|
|
2471
|
+
unsubscribeSkillChanges();
|
|
2472
|
+
unsubscribeAuthStatus?.();
|
|
2473
|
+
statusListeners.delete(rateLimitListener);
|
|
2474
|
+
output.done();
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
};
|
|
2478
|
+
if (false) {}
|
|
2479
|
+
let cronScheduler = null;
|
|
2480
|
+
if (cronGate.isKairosCronEnabled()) {
|
|
2481
|
+
cronScheduler = cronSchedulerModule.createCronScheduler({
|
|
2482
|
+
onFire: (prompt) => {
|
|
2483
|
+
if (inputClosed)
|
|
2484
|
+
return;
|
|
2485
|
+
(async () => {
|
|
2486
|
+
const prepared = await prepareAutonomyTurnPrompt({
|
|
2487
|
+
basePrompt: prompt,
|
|
2488
|
+
trigger: "scheduled-task",
|
|
2489
|
+
currentDir: cwd()
|
|
2490
|
+
});
|
|
2491
|
+
if (inputClosed)
|
|
2492
|
+
return;
|
|
2493
|
+
const command = await commitAutonomyQueuedPrompt({
|
|
2494
|
+
prepared,
|
|
2495
|
+
currentDir: cwd(),
|
|
2496
|
+
workload: WORKLOAD_CRON
|
|
2497
|
+
});
|
|
2498
|
+
if (inputClosed)
|
|
2499
|
+
return;
|
|
2500
|
+
enqueue({
|
|
2501
|
+
...command,
|
|
2502
|
+
uuid: randomUUID2()
|
|
2503
|
+
});
|
|
2504
|
+
run();
|
|
2505
|
+
})();
|
|
2506
|
+
},
|
|
2507
|
+
onFireTask: (task) => {
|
|
2508
|
+
if (inputClosed)
|
|
2509
|
+
return;
|
|
2510
|
+
(async () => {
|
|
2511
|
+
if (task.agentId) {
|
|
2512
|
+
const prepared2 = await prepareAutonomyTurnPrompt({
|
|
2513
|
+
basePrompt: task.prompt,
|
|
2514
|
+
trigger: "scheduled-task",
|
|
2515
|
+
currentDir: cwd()
|
|
2516
|
+
});
|
|
2517
|
+
if (inputClosed)
|
|
2518
|
+
return;
|
|
2519
|
+
const command2 = await commitAutonomyQueuedPrompt({
|
|
2520
|
+
prepared: prepared2,
|
|
2521
|
+
currentDir: cwd(),
|
|
2522
|
+
sourceId: task.id,
|
|
2523
|
+
sourceLabel: task.prompt,
|
|
2524
|
+
workload: WORKLOAD_CRON
|
|
2525
|
+
});
|
|
2526
|
+
await markAutonomyRunFailed(command2.autonomy.runId, `No teammate runtime available for scheduled task owner ${task.agentId} in headless mode.`);
|
|
2527
|
+
return;
|
|
2528
|
+
}
|
|
2529
|
+
const prepared = await prepareAutonomyTurnPrompt({
|
|
2530
|
+
basePrompt: task.prompt,
|
|
2531
|
+
trigger: "scheduled-task",
|
|
2532
|
+
currentDir: cwd()
|
|
2533
|
+
});
|
|
2534
|
+
if (inputClosed)
|
|
2535
|
+
return;
|
|
2536
|
+
const command = await commitAutonomyQueuedPrompt({
|
|
2537
|
+
prepared,
|
|
2538
|
+
currentDir: cwd(),
|
|
2539
|
+
sourceId: task.id,
|
|
2540
|
+
sourceLabel: task.prompt,
|
|
2541
|
+
workload: WORKLOAD_CRON
|
|
2542
|
+
});
|
|
2543
|
+
if (inputClosed)
|
|
2544
|
+
return;
|
|
2545
|
+
enqueue({
|
|
2546
|
+
...command,
|
|
2547
|
+
uuid: randomUUID2()
|
|
2548
|
+
});
|
|
2549
|
+
run();
|
|
2550
|
+
})();
|
|
2551
|
+
},
|
|
2552
|
+
isLoading: () => running || inputClosed,
|
|
2553
|
+
getJitterConfig: cronJitterConfigModule?.getCronJitterConfig,
|
|
2554
|
+
isKilled: () => !cronGate?.isKairosCronEnabled()
|
|
2555
|
+
});
|
|
2556
|
+
cronScheduler.start();
|
|
2557
|
+
}
|
|
2558
|
+
const sendControlResponseSuccess = function(message, response) {
|
|
2559
|
+
output.enqueue({
|
|
2560
|
+
type: "control_response",
|
|
2561
|
+
response: {
|
|
2562
|
+
subtype: "success",
|
|
2563
|
+
request_id: message.request_id,
|
|
2564
|
+
response
|
|
2565
|
+
}
|
|
2566
|
+
});
|
|
2567
|
+
};
|
|
2568
|
+
const sendControlResponseError = function(message, errorMessage2) {
|
|
2569
|
+
output.enqueue({
|
|
2570
|
+
type: "control_response",
|
|
2571
|
+
response: {
|
|
2572
|
+
subtype: "error",
|
|
2573
|
+
request_id: message.request_id,
|
|
2574
|
+
error: errorMessage2
|
|
2575
|
+
}
|
|
2576
|
+
});
|
|
2577
|
+
};
|
|
2578
|
+
const handledOrphanedToolUseIds = new Set;
|
|
2579
|
+
structuredIO.setUnexpectedResponseCallback(async (message) => {
|
|
2580
|
+
await handleOrphanedPermissionResponse({
|
|
2581
|
+
message,
|
|
2582
|
+
setAppState,
|
|
2583
|
+
handledToolUseIds: handledOrphanedToolUseIds,
|
|
2584
|
+
onEnqueued: () => {
|
|
2585
|
+
run();
|
|
2586
|
+
}
|
|
2587
|
+
});
|
|
2588
|
+
});
|
|
2589
|
+
const activeOAuthFlows = new Map;
|
|
2590
|
+
const oauthCallbackSubmitters = new Map;
|
|
2591
|
+
const oauthManualCallbackUsed = new Set;
|
|
2592
|
+
const oauthAuthPromises = new Map;
|
|
2593
|
+
let claudeOAuth = null;
|
|
2594
|
+
(async () => {
|
|
2595
|
+
let initialized = false;
|
|
2596
|
+
logForDiagnosticsNoPII("info", "cli_message_loop_started");
|
|
2597
|
+
for await (const message of structuredIO.structuredInput) {
|
|
2598
|
+
const eventId = "uuid" in message ? message.uuid : undefined;
|
|
2599
|
+
if (eventId && message.type !== "user" && message.type !== "control_response") {
|
|
2600
|
+
notifyCommandLifecycle(eventId, "completed");
|
|
2601
|
+
}
|
|
2602
|
+
if (message.type === "control_request") {
|
|
2603
|
+
const msg = message;
|
|
2604
|
+
const req = msg.request;
|
|
2605
|
+
if (msg.request.subtype === "interrupt") {
|
|
2606
|
+
if (true) {
|
|
2607
|
+
setAppState((prev) => ({
|
|
2608
|
+
...prev,
|
|
2609
|
+
attribution: {
|
|
2610
|
+
...prev.attribution,
|
|
2611
|
+
escapeCount: prev.attribution.escapeCount + 1
|
|
2612
|
+
}
|
|
2613
|
+
}));
|
|
2614
|
+
}
|
|
2615
|
+
if (abortController) {
|
|
2616
|
+
abortController.abort();
|
|
2617
|
+
}
|
|
2618
|
+
suggestionState.abortController?.abort();
|
|
2619
|
+
suggestionState.abortController = null;
|
|
2620
|
+
suggestionState.lastEmitted = null;
|
|
2621
|
+
suggestionState.pendingSuggestion = null;
|
|
2622
|
+
sendControlResponseSuccess(msg);
|
|
2623
|
+
} else if (req.subtype === "end_session") {
|
|
2624
|
+
logForDebugging(`[print.ts] end_session received, reason=${req.reason ?? "unspecified"}`);
|
|
2625
|
+
if (abortController) {
|
|
2626
|
+
abortController.abort();
|
|
2627
|
+
}
|
|
2628
|
+
suggestionState.abortController?.abort();
|
|
2629
|
+
suggestionState.abortController = null;
|
|
2630
|
+
suggestionState.lastEmitted = null;
|
|
2631
|
+
suggestionState.pendingSuggestion = null;
|
|
2632
|
+
sendControlResponseSuccess(msg);
|
|
2633
|
+
break;
|
|
2634
|
+
} else if (msg.request.subtype === "initialize") {
|
|
2635
|
+
if (msg.request.sdkMcpServers && msg.request.sdkMcpServers.length > 0) {
|
|
2636
|
+
for (const serverName of msg.request.sdkMcpServers) {
|
|
2637
|
+
sdkMcpConfigs[serverName] = {
|
|
2638
|
+
type: "sdk",
|
|
2639
|
+
name: serverName
|
|
2640
|
+
};
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
await handleInitializeRequest(msg.request, msg.request_id, initialized, output, commands, modelInfos, structuredIO, !!options.enableAuthStatus, options, agents, getAppState);
|
|
2644
|
+
if (msg.request.promptSuggestions) {
|
|
2645
|
+
setAppState((prev) => {
|
|
2646
|
+
if (prev.promptSuggestionEnabled)
|
|
2647
|
+
return prev;
|
|
2648
|
+
return { ...prev, promptSuggestionEnabled: true };
|
|
2649
|
+
});
|
|
2650
|
+
}
|
|
2651
|
+
if (msg.request.agentProgressSummaries && getFeatureValue_CACHED_MAY_BE_STALE("tengu_slate_prism", true)) {
|
|
2652
|
+
setSdkAgentProgressSummariesEnabled(true);
|
|
2653
|
+
}
|
|
2654
|
+
initialized = true;
|
|
2655
|
+
if (hasCommandsInQueue()) {
|
|
2656
|
+
run();
|
|
2657
|
+
}
|
|
2658
|
+
} else if (msg.request.subtype === "set_permission_mode") {
|
|
2659
|
+
const m = msg.request;
|
|
2660
|
+
setAppState((prev) => ({
|
|
2661
|
+
...prev,
|
|
2662
|
+
toolPermissionContext: handleSetPermissionMode(m, msg.request_id, prev.toolPermissionContext, output),
|
|
2663
|
+
isUltraplanMode: m.ultraplan ?? prev.isUltraplanMode
|
|
2664
|
+
}));
|
|
2665
|
+
} else if (msg.request.subtype === "set_model") {
|
|
2666
|
+
const requestedModel = msg.request.model ?? "default";
|
|
2667
|
+
const model = requestedModel === "default" ? getDefaultMainLoopModel() : requestedModel;
|
|
2668
|
+
activeUserSpecifiedModel = model;
|
|
2669
|
+
setMainLoopModelOverride(model);
|
|
2670
|
+
notifySessionMetadataChanged({ model });
|
|
2671
|
+
injectModelSwitchBreadcrumbs(requestedModel, model);
|
|
2672
|
+
sendControlResponseSuccess(msg);
|
|
2673
|
+
} else if (msg.request.subtype === "set_max_thinking_tokens") {
|
|
2674
|
+
if (msg.request.max_thinking_tokens === null) {
|
|
2675
|
+
options.thinkingConfig = undefined;
|
|
2676
|
+
} else if (msg.request.max_thinking_tokens === 0) {
|
|
2677
|
+
options.thinkingConfig = { type: "disabled" };
|
|
2678
|
+
} else {
|
|
2679
|
+
options.thinkingConfig = {
|
|
2680
|
+
type: "enabled",
|
|
2681
|
+
budgetTokens: msg.request.max_thinking_tokens
|
|
2682
|
+
};
|
|
2683
|
+
}
|
|
2684
|
+
sendControlResponseSuccess(msg);
|
|
2685
|
+
} else if (msg.request.subtype === "mcp_status") {
|
|
2686
|
+
sendControlResponseSuccess(msg, {
|
|
2687
|
+
mcpServers: buildMcpServerStatuses()
|
|
2688
|
+
});
|
|
2689
|
+
} else if (msg.request.subtype === "get_context_usage") {
|
|
2690
|
+
try {
|
|
2691
|
+
const appState = getAppState();
|
|
2692
|
+
const data = await collectContextData({
|
|
2693
|
+
messages: mutableMessages,
|
|
2694
|
+
getAppState,
|
|
2695
|
+
options: {
|
|
2696
|
+
mainLoopModel: getMainLoopModel(),
|
|
2697
|
+
tools: buildAllTools(appState),
|
|
2698
|
+
agentDefinitions: appState.agentDefinitions,
|
|
2699
|
+
customSystemPrompt: options.systemPrompt,
|
|
2700
|
+
appendSystemPrompt: options.appendSystemPrompt
|
|
2701
|
+
}
|
|
2702
|
+
});
|
|
2703
|
+
sendControlResponseSuccess(msg, { ...data });
|
|
2704
|
+
} catch (error) {
|
|
2705
|
+
sendControlResponseError(msg, errorMessage(error));
|
|
2706
|
+
}
|
|
2707
|
+
} else if (msg.request.subtype === "mcp_message") {
|
|
2708
|
+
const mcpRequest = msg.request;
|
|
2709
|
+
const sdkClient = sdkClients.find((client) => client.name === mcpRequest.server_name);
|
|
2710
|
+
if (sdkClient && sdkClient.type === "connected" && sdkClient.client?.transport?.onmessage) {
|
|
2711
|
+
sdkClient.client.transport.onmessage(mcpRequest.message);
|
|
2712
|
+
}
|
|
2713
|
+
sendControlResponseSuccess(msg);
|
|
2714
|
+
} else if (msg.request.subtype === "rewind_files") {
|
|
2715
|
+
const appState = getAppState();
|
|
2716
|
+
const result = await handleRewindFiles(msg.request.user_message_id, appState, setAppState, msg.request.dry_run ?? false);
|
|
2717
|
+
if (result.canRewind || msg.request.dry_run) {
|
|
2718
|
+
sendControlResponseSuccess(msg, result);
|
|
2719
|
+
} else {
|
|
2720
|
+
sendControlResponseError(msg, result.error ?? "Unexpected error");
|
|
2721
|
+
}
|
|
2722
|
+
} else if (msg.request.subtype === "cancel_async_message") {
|
|
2723
|
+
const targetUuid = msg.request.message_uuid;
|
|
2724
|
+
const removed = dequeueAllMatching((cmd) => cmd.uuid === targetUuid);
|
|
2725
|
+
sendControlResponseSuccess(msg, {
|
|
2726
|
+
cancelled: removed.length > 0
|
|
2727
|
+
});
|
|
2728
|
+
} else if (msg.request.subtype === "seed_read_state") {
|
|
2729
|
+
try {
|
|
2730
|
+
const normalizedPath = expandPath(msg.request.path);
|
|
2731
|
+
const diskMtime = Math.floor((await stat(normalizedPath)).mtimeMs);
|
|
2732
|
+
if (diskMtime <= msg.request.mtime) {
|
|
2733
|
+
const raw = await readFile2(normalizedPath, "utf-8");
|
|
2734
|
+
const content = (raw.charCodeAt(0) === 65279 ? raw.slice(1) : raw).replaceAll(`\r
|
|
2735
|
+
`, `
|
|
2736
|
+
`);
|
|
2737
|
+
pendingSeeds.set(normalizedPath, {
|
|
2738
|
+
content,
|
|
2739
|
+
timestamp: diskMtime,
|
|
2740
|
+
offset: undefined,
|
|
2741
|
+
limit: undefined
|
|
2742
|
+
});
|
|
2743
|
+
}
|
|
2744
|
+
} catch {}
|
|
2745
|
+
sendControlResponseSuccess(msg);
|
|
2746
|
+
} else if (msg.request.subtype === "mcp_set_servers") {
|
|
2747
|
+
const { response, sdkServersChanged } = await applyMcpServerChanges(msg.request.servers);
|
|
2748
|
+
sendControlResponseSuccess(msg, response);
|
|
2749
|
+
if (sdkServersChanged) {
|
|
2750
|
+
updateSdkMcp();
|
|
2751
|
+
}
|
|
2752
|
+
} else if (msg.request.subtype === "reload_plugins") {
|
|
2753
|
+
try {
|
|
2754
|
+
if (false) {}
|
|
2755
|
+
const r = await refreshActivePlugins(setAppState);
|
|
2756
|
+
const sdkAgents = currentAgents.filter((a) => a.source === "flagSettings");
|
|
2757
|
+
currentAgents = [...r.agentDefinitions.allAgents, ...sdkAgents];
|
|
2758
|
+
let plugins = [];
|
|
2759
|
+
const [cmdsR, mcpR, pluginsR] = await Promise.allSettled([
|
|
2760
|
+
getCommands(cwd()),
|
|
2761
|
+
applyPluginMcpDiff(),
|
|
2762
|
+
loadAllPluginsCacheOnly()
|
|
2763
|
+
]);
|
|
2764
|
+
if (cmdsR.status === "fulfilled") {
|
|
2765
|
+
currentCommands = cmdsR.value;
|
|
2766
|
+
} else {
|
|
2767
|
+
logError(cmdsR.reason);
|
|
2768
|
+
}
|
|
2769
|
+
if (mcpR.status === "rejected") {
|
|
2770
|
+
logError(mcpR.reason);
|
|
2771
|
+
}
|
|
2772
|
+
if (pluginsR.status === "fulfilled") {
|
|
2773
|
+
plugins = pluginsR.value.enabled.map((p) => ({
|
|
2774
|
+
name: p.name,
|
|
2775
|
+
path: p.path,
|
|
2776
|
+
source: p.source
|
|
2777
|
+
}));
|
|
2778
|
+
} else {
|
|
2779
|
+
logError(pluginsR.reason);
|
|
2780
|
+
}
|
|
2781
|
+
sendControlResponseSuccess(msg, {
|
|
2782
|
+
commands: currentCommands.filter((cmd) => cmd.userInvocable !== false).map((cmd) => ({
|
|
2783
|
+
name: getCommandName(cmd),
|
|
2784
|
+
description: formatDescriptionWithSource(cmd),
|
|
2785
|
+
argumentHint: cmd.argumentHint || ""
|
|
2786
|
+
})),
|
|
2787
|
+
agents: currentAgents.map((a) => ({
|
|
2788
|
+
name: a.agentType,
|
|
2789
|
+
description: a.whenToUse,
|
|
2790
|
+
model: a.model === "inherit" ? undefined : a.model
|
|
2791
|
+
})),
|
|
2792
|
+
plugins,
|
|
2793
|
+
mcpServers: buildMcpServerStatuses(),
|
|
2794
|
+
error_count: r.error_count
|
|
2795
|
+
});
|
|
2796
|
+
} catch (error) {
|
|
2797
|
+
sendControlResponseError(msg, errorMessage(error));
|
|
2798
|
+
}
|
|
2799
|
+
} else if (msg.request.subtype === "mcp_reconnect") {
|
|
2800
|
+
const currentAppState = getAppState();
|
|
2801
|
+
const { serverName } = msg.request;
|
|
2802
|
+
elicitationRegistered.delete(serverName);
|
|
2803
|
+
const config = getMcpConfigByName(serverName) ?? mcpClients.find((c) => c.name === serverName)?.config ?? sdkClients.find((c) => c.name === serverName)?.config ?? dynamicMcpState.clients.find((c) => c.name === serverName)?.config ?? currentAppState.mcp.clients.find((c) => c.name === serverName)?.config ?? null;
|
|
2804
|
+
if (!config) {
|
|
2805
|
+
sendControlResponseError(msg, `Server not found: ${serverName}`);
|
|
2806
|
+
} else {
|
|
2807
|
+
const result = await reconnectMcpServerImpl(serverName, config);
|
|
2808
|
+
const prefix = getMcpPrefix(serverName);
|
|
2809
|
+
setAppState((prev) => ({
|
|
2810
|
+
...prev,
|
|
2811
|
+
mcp: {
|
|
2812
|
+
...prev.mcp,
|
|
2813
|
+
clients: prev.mcp.clients.map((c) => c.name === serverName ? result.client : c),
|
|
2814
|
+
tools: [
|
|
2815
|
+
...reject_default(prev.mcp.tools, (t) => t.name?.startsWith(prefix)),
|
|
2816
|
+
...result.tools
|
|
2817
|
+
],
|
|
2818
|
+
commands: [
|
|
2819
|
+
...reject_default(prev.mcp.commands, (c) => commandBelongsToServer(c, serverName)),
|
|
2820
|
+
...result.commands
|
|
2821
|
+
],
|
|
2822
|
+
resources: result.resources && result.resources.length > 0 ? { ...prev.mcp.resources, [serverName]: result.resources } : omit_default(prev.mcp.resources, serverName)
|
|
2823
|
+
}
|
|
2824
|
+
}));
|
|
2825
|
+
dynamicMcpState = {
|
|
2826
|
+
...dynamicMcpState,
|
|
2827
|
+
clients: [
|
|
2828
|
+
...dynamicMcpState.clients.filter((c) => c.name !== serverName),
|
|
2829
|
+
result.client
|
|
2830
|
+
],
|
|
2831
|
+
tools: [
|
|
2832
|
+
...dynamicMcpState.tools.filter((t) => !t.name?.startsWith(prefix)),
|
|
2833
|
+
...result.tools
|
|
2834
|
+
]
|
|
2835
|
+
};
|
|
2836
|
+
if (result.client.type === "connected") {
|
|
2837
|
+
registerElicitationHandlers([result.client]);
|
|
2838
|
+
reregisterChannelHandlerAfterReconnect(result.client);
|
|
2839
|
+
sendControlResponseSuccess(msg);
|
|
2840
|
+
} else {
|
|
2841
|
+
const errorMessage2 = result.client.type === "failed" ? result.client.error ?? "Connection failed" : `Server status: ${result.client.type}`;
|
|
2842
|
+
sendControlResponseError(msg, errorMessage2);
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
} else if (msg.request.subtype === "mcp_toggle") {
|
|
2846
|
+
const currentAppState = getAppState();
|
|
2847
|
+
const { serverName, enabled } = msg.request;
|
|
2848
|
+
elicitationRegistered.delete(serverName);
|
|
2849
|
+
const config = getMcpConfigByName(serverName) ?? mcpClients.find((c) => c.name === serverName)?.config ?? sdkClients.find((c) => c.name === serverName)?.config ?? dynamicMcpState.clients.find((c) => c.name === serverName)?.config ?? currentAppState.mcp.clients.find((c) => c.name === serverName)?.config ?? null;
|
|
2850
|
+
if (!config) {
|
|
2851
|
+
sendControlResponseError(msg, `Server not found: ${serverName}`);
|
|
2852
|
+
} else if (!enabled) {
|
|
2853
|
+
setMcpServerEnabled(serverName, false);
|
|
2854
|
+
const client = [
|
|
2855
|
+
...mcpClients,
|
|
2856
|
+
...sdkClients,
|
|
2857
|
+
...dynamicMcpState.clients,
|
|
2858
|
+
...currentAppState.mcp.clients
|
|
2859
|
+
].find((c) => c.name === serverName);
|
|
2860
|
+
if (client && client.type === "connected") {
|
|
2861
|
+
await clearServerCache(serverName, config);
|
|
2862
|
+
}
|
|
2863
|
+
const prefix = getMcpPrefix(serverName);
|
|
2864
|
+
setAppState((prev) => ({
|
|
2865
|
+
...prev,
|
|
2866
|
+
mcp: {
|
|
2867
|
+
...prev.mcp,
|
|
2868
|
+
clients: prev.mcp.clients.map((c) => c.name === serverName ? { name: serverName, type: "disabled", config } : c),
|
|
2869
|
+
tools: reject_default(prev.mcp.tools, (t) => t.name?.startsWith(prefix)),
|
|
2870
|
+
commands: reject_default(prev.mcp.commands, (c) => commandBelongsToServer(c, serverName)),
|
|
2871
|
+
resources: omit_default(prev.mcp.resources, serverName)
|
|
2872
|
+
}
|
|
2873
|
+
}));
|
|
2874
|
+
sendControlResponseSuccess(msg);
|
|
2875
|
+
} else {
|
|
2876
|
+
setMcpServerEnabled(serverName, true);
|
|
2877
|
+
const result = await reconnectMcpServerImpl(serverName, config);
|
|
2878
|
+
const prefix = getMcpPrefix(serverName);
|
|
2879
|
+
setAppState((prev) => ({
|
|
2880
|
+
...prev,
|
|
2881
|
+
mcp: {
|
|
2882
|
+
...prev.mcp,
|
|
2883
|
+
clients: prev.mcp.clients.map((c) => c.name === serverName ? result.client : c),
|
|
2884
|
+
tools: [
|
|
2885
|
+
...reject_default(prev.mcp.tools, (t) => t.name?.startsWith(prefix)),
|
|
2886
|
+
...result.tools
|
|
2887
|
+
],
|
|
2888
|
+
commands: [
|
|
2889
|
+
...reject_default(prev.mcp.commands, (c) => commandBelongsToServer(c, serverName)),
|
|
2890
|
+
...result.commands
|
|
2891
|
+
],
|
|
2892
|
+
resources: result.resources && result.resources.length > 0 ? { ...prev.mcp.resources, [serverName]: result.resources } : omit_default(prev.mcp.resources, serverName)
|
|
2893
|
+
}
|
|
2894
|
+
}));
|
|
2895
|
+
if (result.client.type === "connected") {
|
|
2896
|
+
registerElicitationHandlers([result.client]);
|
|
2897
|
+
reregisterChannelHandlerAfterReconnect(result.client);
|
|
2898
|
+
sendControlResponseSuccess(msg);
|
|
2899
|
+
} else {
|
|
2900
|
+
const errorMessage2 = result.client.type === "failed" ? result.client.error ?? "Connection failed" : `Server status: ${result.client.type}`;
|
|
2901
|
+
sendControlResponseError(msg, errorMessage2);
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
} else if (req.subtype === "channel_enable") {
|
|
2905
|
+
const currentAppState = getAppState();
|
|
2906
|
+
handleChannelEnable(msg.request_id, req.serverName, [
|
|
2907
|
+
...currentAppState.mcp.clients,
|
|
2908
|
+
...sdkClients,
|
|
2909
|
+
...dynamicMcpState.clients
|
|
2910
|
+
], output);
|
|
2911
|
+
} else if (req.subtype === "mcp_authenticate") {
|
|
2912
|
+
const serverName = req.serverName;
|
|
2913
|
+
const currentAppState = getAppState();
|
|
2914
|
+
const config = getMcpConfigByName(serverName) ?? mcpClients.find((c) => c.name === serverName)?.config ?? currentAppState.mcp.clients.find((c) => c.name === serverName)?.config ?? null;
|
|
2915
|
+
if (!config) {
|
|
2916
|
+
sendControlResponseError(msg, `Server not found: ${serverName}`);
|
|
2917
|
+
} else if (config.type !== "sse" && config.type !== "http") {
|
|
2918
|
+
sendControlResponseError(msg, `Server type "${config.type}" does not support OAuth authentication`);
|
|
2919
|
+
} else {
|
|
2920
|
+
try {
|
|
2921
|
+
activeOAuthFlows.get(serverName)?.abort();
|
|
2922
|
+
const controller = new AbortController;
|
|
2923
|
+
activeOAuthFlows.set(serverName, controller);
|
|
2924
|
+
let resolveAuthUrl;
|
|
2925
|
+
const authUrlPromise = new Promise((resolve) => {
|
|
2926
|
+
resolveAuthUrl = resolve;
|
|
2927
|
+
});
|
|
2928
|
+
const oauthPromise = performMCPOAuthFlow(serverName, config, (url) => resolveAuthUrl(url), controller.signal, {
|
|
2929
|
+
skipBrowserOpen: true,
|
|
2930
|
+
onWaitingForCallback: (submit) => {
|
|
2931
|
+
oauthCallbackSubmitters.set(serverName, submit);
|
|
2932
|
+
}
|
|
2933
|
+
});
|
|
2934
|
+
const authUrl = await Promise.race([
|
|
2935
|
+
authUrlPromise,
|
|
2936
|
+
oauthPromise.then(() => null)
|
|
2937
|
+
]);
|
|
2938
|
+
if (authUrl) {
|
|
2939
|
+
sendControlResponseSuccess(msg, {
|
|
2940
|
+
authUrl,
|
|
2941
|
+
requiresUserAction: true
|
|
2942
|
+
});
|
|
2943
|
+
} else {
|
|
2944
|
+
sendControlResponseSuccess(msg, {
|
|
2945
|
+
requiresUserAction: false
|
|
2946
|
+
});
|
|
2947
|
+
}
|
|
2948
|
+
oauthAuthPromises.set(serverName, oauthPromise);
|
|
2949
|
+
const fullFlowPromise = oauthPromise.then(async () => {
|
|
2950
|
+
if (isMcpServerDisabled(serverName)) {
|
|
2951
|
+
return;
|
|
2952
|
+
}
|
|
2953
|
+
if (oauthManualCallbackUsed.has(serverName)) {
|
|
2954
|
+
return;
|
|
2955
|
+
}
|
|
2956
|
+
const result = await reconnectMcpServerImpl(serverName, config);
|
|
2957
|
+
const prefix = getMcpPrefix(serverName);
|
|
2958
|
+
setAppState((prev) => ({
|
|
2959
|
+
...prev,
|
|
2960
|
+
mcp: {
|
|
2961
|
+
...prev.mcp,
|
|
2962
|
+
clients: prev.mcp.clients.map((c) => c.name === serverName ? result.client : c),
|
|
2963
|
+
tools: [
|
|
2964
|
+
...reject_default(prev.mcp.tools, (t) => t.name?.startsWith(prefix)),
|
|
2965
|
+
...result.tools
|
|
2966
|
+
],
|
|
2967
|
+
commands: [
|
|
2968
|
+
...reject_default(prev.mcp.commands, (c) => commandBelongsToServer(c, serverName)),
|
|
2969
|
+
...result.commands
|
|
2970
|
+
],
|
|
2971
|
+
resources: result.resources && result.resources.length > 0 ? {
|
|
2972
|
+
...prev.mcp.resources,
|
|
2973
|
+
[serverName]: result.resources
|
|
2974
|
+
} : omit_default(prev.mcp.resources, serverName)
|
|
2975
|
+
}
|
|
2976
|
+
}));
|
|
2977
|
+
dynamicMcpState = {
|
|
2978
|
+
...dynamicMcpState,
|
|
2979
|
+
clients: [
|
|
2980
|
+
...dynamicMcpState.clients.filter((c) => c.name !== serverName),
|
|
2981
|
+
result.client
|
|
2982
|
+
],
|
|
2983
|
+
tools: [
|
|
2984
|
+
...dynamicMcpState.tools.filter((t) => !t.name?.startsWith(prefix)),
|
|
2985
|
+
...result.tools
|
|
2986
|
+
]
|
|
2987
|
+
};
|
|
2988
|
+
}).catch((error) => {
|
|
2989
|
+
logForDebugging(`MCP OAuth failed for ${serverName}: ${error}`, { level: "error" });
|
|
2990
|
+
}).finally(() => {
|
|
2991
|
+
if (activeOAuthFlows.get(serverName) === controller) {
|
|
2992
|
+
activeOAuthFlows.delete(serverName);
|
|
2993
|
+
oauthCallbackSubmitters.delete(serverName);
|
|
2994
|
+
oauthManualCallbackUsed.delete(serverName);
|
|
2995
|
+
oauthAuthPromises.delete(serverName);
|
|
2996
|
+
}
|
|
2997
|
+
});
|
|
2998
|
+
} catch (error) {
|
|
2999
|
+
sendControlResponseError(msg, errorMessage(error));
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
} else if (req.subtype === "mcp_oauth_callback_url") {
|
|
3003
|
+
const serverName = req.serverName;
|
|
3004
|
+
const callbackUrl = req.callbackUrl;
|
|
3005
|
+
const submit = oauthCallbackSubmitters.get(serverName);
|
|
3006
|
+
if (submit) {
|
|
3007
|
+
let hasCodeOrError = false;
|
|
3008
|
+
try {
|
|
3009
|
+
const parsed = new URL(callbackUrl);
|
|
3010
|
+
hasCodeOrError = parsed.searchParams.has("code") || parsed.searchParams.has("error");
|
|
3011
|
+
} catch {}
|
|
3012
|
+
if (!hasCodeOrError) {
|
|
3013
|
+
sendControlResponseError(msg, "Invalid callback URL: missing authorization code. Please paste the full redirect URL including the code parameter.");
|
|
3014
|
+
} else {
|
|
3015
|
+
oauthManualCallbackUsed.add(serverName);
|
|
3016
|
+
submit(callbackUrl);
|
|
3017
|
+
const authPromise = oauthAuthPromises.get(serverName);
|
|
3018
|
+
if (authPromise) {
|
|
3019
|
+
try {
|
|
3020
|
+
await authPromise;
|
|
3021
|
+
sendControlResponseSuccess(msg);
|
|
3022
|
+
} catch (error) {
|
|
3023
|
+
sendControlResponseError(msg, error instanceof Error ? error.message : "OAuth authentication failed");
|
|
3024
|
+
}
|
|
3025
|
+
} else {
|
|
3026
|
+
sendControlResponseSuccess(msg);
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
} else {
|
|
3030
|
+
sendControlResponseError(msg, `No active OAuth flow for server: ${serverName}`);
|
|
3031
|
+
}
|
|
3032
|
+
} else if (req.subtype === "claude_authenticate") {
|
|
3033
|
+
const loginWithClaudeAi = req.loginWithClaudeAi;
|
|
3034
|
+
claudeOAuth?.service.cleanup();
|
|
3035
|
+
logEvent("tengu_oauth_flow_start", {
|
|
3036
|
+
loginWithClaudeAi: loginWithClaudeAi ?? true
|
|
3037
|
+
});
|
|
3038
|
+
const service = new OAuthService;
|
|
3039
|
+
let urlResolver;
|
|
3040
|
+
const urlPromise = new Promise((resolve) => {
|
|
3041
|
+
urlResolver = resolve;
|
|
3042
|
+
});
|
|
3043
|
+
const flow = service.startOAuthFlow(async (manualUrl, automaticUrl) => {
|
|
3044
|
+
urlResolver({ manualUrl, automaticUrl });
|
|
3045
|
+
}, {
|
|
3046
|
+
loginWithClaudeAi: loginWithClaudeAi ?? true,
|
|
3047
|
+
skipBrowserOpen: true
|
|
3048
|
+
}).then(async (tokens) => {
|
|
3049
|
+
await installOAuthTokens(tokens);
|
|
3050
|
+
logEvent("tengu_oauth_success", {
|
|
3051
|
+
loginWithClaudeAi: loginWithClaudeAi ?? true
|
|
3052
|
+
});
|
|
3053
|
+
}).finally(() => {
|
|
3054
|
+
service.cleanup();
|
|
3055
|
+
if (claudeOAuth?.service === service) {
|
|
3056
|
+
claudeOAuth = null;
|
|
3057
|
+
}
|
|
3058
|
+
});
|
|
3059
|
+
claudeOAuth = { service, flow };
|
|
3060
|
+
flow.catch((err) => logForDebugging(`claude_authenticate flow ended: ${err}`, {
|
|
3061
|
+
level: "info"
|
|
3062
|
+
}));
|
|
3063
|
+
try {
|
|
3064
|
+
const { manualUrl, automaticUrl } = await Promise.race([
|
|
3065
|
+
urlPromise,
|
|
3066
|
+
flow.then(() => {
|
|
3067
|
+
throw new Error("OAuth flow completed without producing auth URLs");
|
|
3068
|
+
})
|
|
3069
|
+
]);
|
|
3070
|
+
sendControlResponseSuccess(msg, {
|
|
3071
|
+
manualUrl,
|
|
3072
|
+
automaticUrl
|
|
3073
|
+
});
|
|
3074
|
+
} catch (error) {
|
|
3075
|
+
sendControlResponseError(msg, errorMessage(error));
|
|
3076
|
+
}
|
|
3077
|
+
} else if (req.subtype === "claude_oauth_callback" || req.subtype === "claude_oauth_wait_for_completion") {
|
|
3078
|
+
if (!claudeOAuth) {
|
|
3079
|
+
sendControlResponseError(msg, "No active claude_authenticate flow");
|
|
3080
|
+
} else {
|
|
3081
|
+
if (req.subtype === "claude_oauth_callback") {
|
|
3082
|
+
claudeOAuth.service.handleManualAuthCodeInput({
|
|
3083
|
+
authorizationCode: req.authorizationCode,
|
|
3084
|
+
state: req.state
|
|
3085
|
+
});
|
|
3086
|
+
}
|
|
3087
|
+
const { flow } = claudeOAuth;
|
|
3088
|
+
flow.then(() => {
|
|
3089
|
+
const accountInfo = getAccountInformation();
|
|
3090
|
+
sendControlResponseSuccess(msg, {
|
|
3091
|
+
account: {
|
|
3092
|
+
email: accountInfo?.email,
|
|
3093
|
+
organization: accountInfo?.organization,
|
|
3094
|
+
subscriptionType: accountInfo?.subscription,
|
|
3095
|
+
tokenSource: accountInfo?.tokenSource,
|
|
3096
|
+
apiKeySource: accountInfo?.apiKeySource,
|
|
3097
|
+
apiProvider: getAPIProvider()
|
|
3098
|
+
}
|
|
3099
|
+
});
|
|
3100
|
+
}, (error) => sendControlResponseError(msg, errorMessage(error)));
|
|
3101
|
+
}
|
|
3102
|
+
} else if (req.subtype === "mcp_clear_auth") {
|
|
3103
|
+
const serverName = req.serverName;
|
|
3104
|
+
const currentAppState = getAppState();
|
|
3105
|
+
const config = getMcpConfigByName(serverName) ?? mcpClients.find((c) => c.name === serverName)?.config ?? currentAppState.mcp.clients.find((c) => c.name === serverName)?.config ?? null;
|
|
3106
|
+
if (!config) {
|
|
3107
|
+
sendControlResponseError(msg, `Server not found: ${serverName}`);
|
|
3108
|
+
} else if (config.type !== "sse" && config.type !== "http") {
|
|
3109
|
+
sendControlResponseError(msg, `Cannot clear auth for server type "${config.type}"`);
|
|
3110
|
+
} else {
|
|
3111
|
+
await revokeServerTokens(serverName, config);
|
|
3112
|
+
const result = await reconnectMcpServerImpl(serverName, config);
|
|
3113
|
+
const prefix = getMcpPrefix(serverName);
|
|
3114
|
+
setAppState((prev) => ({
|
|
3115
|
+
...prev,
|
|
3116
|
+
mcp: {
|
|
3117
|
+
...prev.mcp,
|
|
3118
|
+
clients: prev.mcp.clients.map((c) => c.name === serverName ? result.client : c),
|
|
3119
|
+
tools: [
|
|
3120
|
+
...reject_default(prev.mcp.tools, (t) => t.name?.startsWith(prefix)),
|
|
3121
|
+
...result.tools
|
|
3122
|
+
],
|
|
3123
|
+
commands: [
|
|
3124
|
+
...reject_default(prev.mcp.commands, (c) => commandBelongsToServer(c, serverName)),
|
|
3125
|
+
...result.commands
|
|
3126
|
+
],
|
|
3127
|
+
resources: result.resources && result.resources.length > 0 ? {
|
|
3128
|
+
...prev.mcp.resources,
|
|
3129
|
+
[serverName]: result.resources
|
|
3130
|
+
} : omit_default(prev.mcp.resources, serverName)
|
|
3131
|
+
}
|
|
3132
|
+
}));
|
|
3133
|
+
sendControlResponseSuccess(msg, {});
|
|
3134
|
+
}
|
|
3135
|
+
} else if (msg.request.subtype === "apply_flag_settings") {
|
|
3136
|
+
const prevModel = getMainLoopModel();
|
|
3137
|
+
const existing = getFlagSettingsInline() ?? {};
|
|
3138
|
+
const incoming = msg.request.settings;
|
|
3139
|
+
const merged = { ...existing, ...incoming };
|
|
3140
|
+
for (const key of Object.keys(merged)) {
|
|
3141
|
+
if (merged[key] === null) {
|
|
3142
|
+
delete merged[key];
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
setFlagSettingsInline(merged);
|
|
3146
|
+
settingsChangeDetector.notifyChange("flagSettings");
|
|
3147
|
+
if ("model" in incoming) {
|
|
3148
|
+
if (incoming.model != null) {
|
|
3149
|
+
setMainLoopModelOverride(String(incoming.model));
|
|
3150
|
+
} else {
|
|
3151
|
+
setMainLoopModelOverride(undefined);
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
const newModel = getMainLoopModel();
|
|
3155
|
+
if (newModel !== prevModel) {
|
|
3156
|
+
activeUserSpecifiedModel = newModel;
|
|
3157
|
+
const modelArg = incoming.model ? String(incoming.model) : "default";
|
|
3158
|
+
notifySessionMetadataChanged({ model: newModel });
|
|
3159
|
+
injectModelSwitchBreadcrumbs(modelArg, newModel);
|
|
3160
|
+
}
|
|
3161
|
+
sendControlResponseSuccess(msg);
|
|
3162
|
+
} else if (msg.request.subtype === "get_settings") {
|
|
3163
|
+
const currentAppState = getAppState();
|
|
3164
|
+
const model = getMainLoopModel();
|
|
3165
|
+
const effort = modelSupportsEffort(model) ? resolveAppliedEffort(model, currentAppState.effortValue) : undefined;
|
|
3166
|
+
sendControlResponseSuccess(msg, {
|
|
3167
|
+
...getSettingsWithSources(),
|
|
3168
|
+
applied: {
|
|
3169
|
+
model,
|
|
3170
|
+
effort: typeof effort === "string" ? effort : null
|
|
3171
|
+
}
|
|
3172
|
+
});
|
|
3173
|
+
} else if (msg.request.subtype === "stop_task") {
|
|
3174
|
+
const { task_id: taskId } = msg.request;
|
|
3175
|
+
try {
|
|
3176
|
+
await stopTask(taskId, {
|
|
3177
|
+
getAppState,
|
|
3178
|
+
setAppState
|
|
3179
|
+
});
|
|
3180
|
+
sendControlResponseSuccess(msg, {});
|
|
3181
|
+
} catch (error) {
|
|
3182
|
+
sendControlResponseError(msg, errorMessage(error));
|
|
3183
|
+
}
|
|
3184
|
+
} else if (req.subtype === "generate_session_title") {
|
|
3185
|
+
const description = req.description;
|
|
3186
|
+
const persist = req.persist;
|
|
3187
|
+
const titleSignal = (abortController && !abortController.signal.aborted ? abortController : createAbortController()).signal;
|
|
3188
|
+
(async () => {
|
|
3189
|
+
try {
|
|
3190
|
+
const title = await generateSessionTitle(description, titleSignal);
|
|
3191
|
+
if (title && persist) {
|
|
3192
|
+
try {
|
|
3193
|
+
saveAiGeneratedTitle(getSessionId(), title);
|
|
3194
|
+
} catch (e) {
|
|
3195
|
+
logError(e);
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
sendControlResponseSuccess(msg, { title });
|
|
3199
|
+
} catch (e) {
|
|
3200
|
+
sendControlResponseError(msg, errorMessage(e));
|
|
3201
|
+
}
|
|
3202
|
+
})();
|
|
3203
|
+
} else if (req.subtype === "side_question") {
|
|
3204
|
+
const question = req.question;
|
|
3205
|
+
(async () => {
|
|
3206
|
+
try {
|
|
3207
|
+
const saved = getLastCacheSafeParams();
|
|
3208
|
+
const cacheSafeParams = saved ? {
|
|
3209
|
+
...saved,
|
|
3210
|
+
toolUseContext: {
|
|
3211
|
+
...saved.toolUseContext,
|
|
3212
|
+
abortController: createAbortController()
|
|
3213
|
+
}
|
|
3214
|
+
} : await buildSideQuestionFallbackParams({
|
|
3215
|
+
tools: buildAllTools(getAppState()),
|
|
3216
|
+
commands: currentCommands,
|
|
3217
|
+
mcpClients: [
|
|
3218
|
+
...getAppState().mcp.clients,
|
|
3219
|
+
...sdkClients,
|
|
3220
|
+
...dynamicMcpState.clients
|
|
3221
|
+
],
|
|
3222
|
+
messages: mutableMessages,
|
|
3223
|
+
readFileState,
|
|
3224
|
+
getAppState,
|
|
3225
|
+
setAppState,
|
|
3226
|
+
customSystemPrompt: options.systemPrompt,
|
|
3227
|
+
appendSystemPrompt: options.appendSystemPrompt,
|
|
3228
|
+
thinkingConfig: options.thinkingConfig,
|
|
3229
|
+
agents: currentAgents
|
|
3230
|
+
});
|
|
3231
|
+
const result = await runSideQuestion({
|
|
3232
|
+
question,
|
|
3233
|
+
cacheSafeParams
|
|
3234
|
+
});
|
|
3235
|
+
sendControlResponseSuccess(msg, { response: result.response });
|
|
3236
|
+
} catch (e) {
|
|
3237
|
+
sendControlResponseError(msg, errorMessage(e));
|
|
3238
|
+
}
|
|
3239
|
+
})();
|
|
3240
|
+
} else if (msg.request.subtype === "set_proactive") {
|
|
3241
|
+
const req2 = msg.request;
|
|
3242
|
+
if (req2.enabled) {
|
|
3243
|
+
if (!proactiveModule.isProactiveActive()) {
|
|
3244
|
+
proactiveModule.activateProactive("command");
|
|
3245
|
+
scheduleProactiveTick();
|
|
3246
|
+
}
|
|
3247
|
+
} else {
|
|
3248
|
+
proactiveModule.deactivateProactive();
|
|
3249
|
+
}
|
|
3250
|
+
sendControlResponseSuccess(msg);
|
|
3251
|
+
} else if (req.subtype === "remote_control") {
|
|
3252
|
+
if (req.enabled) {
|
|
3253
|
+
if (bridgeHandle) {
|
|
3254
|
+
sendControlResponseSuccess(msg, {
|
|
3255
|
+
session_url: getRemoteSessionUrl(bridgeHandle.bridgeSessionId, bridgeHandle.sessionIngressUrl),
|
|
3256
|
+
connect_url: buildBridgeConnectUrl(bridgeHandle.environmentId, bridgeHandle.sessionIngressUrl),
|
|
3257
|
+
environment_id: bridgeHandle.environmentId
|
|
3258
|
+
});
|
|
3259
|
+
} else {
|
|
3260
|
+
let bridgeFailureDetail;
|
|
3261
|
+
try {
|
|
3262
|
+
const { initReplBridge } = await import("./chunk-3zwjpkjh.js");
|
|
3263
|
+
const handle = await initReplBridge({
|
|
3264
|
+
onInboundMessage(msg2) {
|
|
3265
|
+
const fields = extractInboundMessageFields(msg2);
|
|
3266
|
+
if (!fields)
|
|
3267
|
+
return;
|
|
3268
|
+
const { content, uuid } = fields;
|
|
3269
|
+
enqueue({
|
|
3270
|
+
value: content,
|
|
3271
|
+
mode: "prompt",
|
|
3272
|
+
uuid,
|
|
3273
|
+
skipSlashCommands: true
|
|
3274
|
+
});
|
|
3275
|
+
run();
|
|
3276
|
+
},
|
|
3277
|
+
onPermissionResponse(response) {
|
|
3278
|
+
structuredIO.injectControlResponse(response);
|
|
3279
|
+
},
|
|
3280
|
+
onInterrupt() {
|
|
3281
|
+
abortController?.abort();
|
|
3282
|
+
},
|
|
3283
|
+
onSetModel(model) {
|
|
3284
|
+
const resolved = model === "default" ? getDefaultMainLoopModel() : model;
|
|
3285
|
+
activeUserSpecifiedModel = resolved;
|
|
3286
|
+
setMainLoopModelOverride(resolved);
|
|
3287
|
+
},
|
|
3288
|
+
onSetMaxThinkingTokens(maxTokens) {
|
|
3289
|
+
if (maxTokens === null) {
|
|
3290
|
+
options.thinkingConfig = undefined;
|
|
3291
|
+
} else if (maxTokens === 0) {
|
|
3292
|
+
options.thinkingConfig = { type: "disabled" };
|
|
3293
|
+
} else {
|
|
3294
|
+
options.thinkingConfig = {
|
|
3295
|
+
type: "enabled",
|
|
3296
|
+
budgetTokens: maxTokens
|
|
3297
|
+
};
|
|
3298
|
+
}
|
|
3299
|
+
},
|
|
3300
|
+
onStateChange(state, detail) {
|
|
3301
|
+
if (state === "failed") {
|
|
3302
|
+
bridgeFailureDetail = detail;
|
|
3303
|
+
}
|
|
3304
|
+
logForDebugging(`[bridge:sdk] State change: ${state}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
3305
|
+
output.enqueue({
|
|
3306
|
+
type: "system",
|
|
3307
|
+
subtype: "bridge_state",
|
|
3308
|
+
state,
|
|
3309
|
+
detail,
|
|
3310
|
+
uuid: randomUUID2(),
|
|
3311
|
+
session_id: getSessionId()
|
|
3312
|
+
});
|
|
3313
|
+
},
|
|
3314
|
+
initialMessages: mutableMessages.length > 0 ? mutableMessages : undefined
|
|
3315
|
+
});
|
|
3316
|
+
if (!handle) {
|
|
3317
|
+
sendControlResponseError(msg, bridgeFailureDetail ?? "Remote Control initialization failed");
|
|
3318
|
+
} else {
|
|
3319
|
+
bridgeHandle = handle;
|
|
3320
|
+
bridgeLastForwardedIndex = mutableMessages.length;
|
|
3321
|
+
structuredIO.setOnControlRequestSent((request) => {
|
|
3322
|
+
handle.sendControlRequest(request);
|
|
3323
|
+
});
|
|
3324
|
+
structuredIO.setOnControlRequestResolved((requestId) => {
|
|
3325
|
+
handle.sendControlCancelRequest(requestId);
|
|
3326
|
+
});
|
|
3327
|
+
sendControlResponseSuccess(msg, {
|
|
3328
|
+
session_url: getRemoteSessionUrl(handle.bridgeSessionId, handle.sessionIngressUrl),
|
|
3329
|
+
connect_url: buildBridgeConnectUrl(handle.environmentId, handle.sessionIngressUrl),
|
|
3330
|
+
environment_id: handle.environmentId
|
|
3331
|
+
});
|
|
3332
|
+
}
|
|
3333
|
+
} catch (err) {
|
|
3334
|
+
sendControlResponseError(msg, errorMessage(err));
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
3337
|
+
} else {
|
|
3338
|
+
if (bridgeHandle) {
|
|
3339
|
+
structuredIO.setOnControlRequestSent(undefined);
|
|
3340
|
+
structuredIO.setOnControlRequestResolved(undefined);
|
|
3341
|
+
await bridgeHandle.teardown();
|
|
3342
|
+
bridgeHandle = null;
|
|
3343
|
+
}
|
|
3344
|
+
sendControlResponseSuccess(msg);
|
|
3345
|
+
}
|
|
3346
|
+
} else {
|
|
3347
|
+
sendControlResponseError(msg, `Unsupported control request subtype: ${msg.request.subtype}`);
|
|
3348
|
+
}
|
|
3349
|
+
continue;
|
|
3350
|
+
} else if (message.type === "control_response") {
|
|
3351
|
+
if (options.replayUserMessages) {
|
|
3352
|
+
output.enqueue(message);
|
|
3353
|
+
}
|
|
3354
|
+
continue;
|
|
3355
|
+
} else if (message.type === "keep_alive") {
|
|
3356
|
+
continue;
|
|
3357
|
+
} else if (message.type === "update_environment_variables") {
|
|
3358
|
+
continue;
|
|
3359
|
+
} else if (message.type === "assistant" || message.type === "system") {
|
|
3360
|
+
const internalMsgs = toInternalMessages([message]);
|
|
3361
|
+
mutableMessages.push(...internalMsgs);
|
|
3362
|
+
if (message.type === "assistant" && options.replayUserMessages) {
|
|
3363
|
+
output.enqueue(message);
|
|
3364
|
+
}
|
|
3365
|
+
continue;
|
|
3366
|
+
}
|
|
3367
|
+
if (message.type !== "user") {
|
|
3368
|
+
continue;
|
|
3369
|
+
}
|
|
3370
|
+
const userMsg = message;
|
|
3371
|
+
initialized = true;
|
|
3372
|
+
if (userMsg.uuid) {
|
|
3373
|
+
const sessionId = getSessionId();
|
|
3374
|
+
const existsInSession = await doesMessageExistInSession(sessionId, userMsg.uuid);
|
|
3375
|
+
if (existsInSession || receivedMessageUuids.has(userMsg.uuid)) {
|
|
3376
|
+
logForDebugging(`Skipping duplicate user message: ${userMsg.uuid}`);
|
|
3377
|
+
if (options.replayUserMessages) {
|
|
3378
|
+
logForDebugging(`Sending acknowledgment for duplicate user message: ${userMsg.uuid}`);
|
|
3379
|
+
output.enqueue({
|
|
3380
|
+
type: "user",
|
|
3381
|
+
content: userMsg.message?.content ?? "",
|
|
3382
|
+
message: userMsg.message,
|
|
3383
|
+
session_id: sessionId,
|
|
3384
|
+
parent_tool_use_id: null,
|
|
3385
|
+
uuid: userMsg.uuid,
|
|
3386
|
+
timestamp: userMsg.timestamp,
|
|
3387
|
+
isReplay: true
|
|
3388
|
+
});
|
|
3389
|
+
}
|
|
3390
|
+
if (existsInSession) {
|
|
3391
|
+
notifyCommandLifecycle(userMsg.uuid, "completed");
|
|
3392
|
+
}
|
|
3393
|
+
continue;
|
|
3394
|
+
}
|
|
3395
|
+
trackReceivedMessageUuid(userMsg.uuid);
|
|
3396
|
+
}
|
|
3397
|
+
enqueue({
|
|
3398
|
+
mode: "prompt",
|
|
3399
|
+
value: await resolveAndPrepend(userMsg, userMsg.message.content),
|
|
3400
|
+
uuid: userMsg.uuid,
|
|
3401
|
+
priority: userMsg.priority
|
|
3402
|
+
});
|
|
3403
|
+
if (true) {
|
|
3404
|
+
setAppState((prev) => ({
|
|
3405
|
+
...prev,
|
|
3406
|
+
attribution: incrementPromptCount(prev.attribution, (snapshot) => {
|
|
3407
|
+
recordAttributionSnapshot(snapshot).catch((error) => {
|
|
3408
|
+
logForDebugging(`Attribution: Failed to save snapshot: ${error}`);
|
|
3409
|
+
});
|
|
3410
|
+
})
|
|
3411
|
+
}));
|
|
3412
|
+
}
|
|
3413
|
+
run();
|
|
3414
|
+
}
|
|
3415
|
+
inputClosed = true;
|
|
3416
|
+
cronScheduler?.stop();
|
|
3417
|
+
if (!running) {
|
|
3418
|
+
if (suggestionState.inflightPromise) {
|
|
3419
|
+
await Promise.race([suggestionState.inflightPromise, sleep(5000)]);
|
|
3420
|
+
}
|
|
3421
|
+
suggestionState.abortController?.abort();
|
|
3422
|
+
suggestionState.abortController = null;
|
|
3423
|
+
await finalizePendingAsyncHooks();
|
|
3424
|
+
unsubscribeSkillChanges();
|
|
3425
|
+
unsubscribeAuthStatus?.();
|
|
3426
|
+
statusListeners.delete(rateLimitListener);
|
|
3427
|
+
output.done();
|
|
3428
|
+
}
|
|
3429
|
+
})();
|
|
3430
|
+
return output;
|
|
3431
|
+
}
|
|
3432
|
+
function createCanUseToolWithPermissionPrompt(permissionPromptTool) {
|
|
3433
|
+
const canUseTool = async (tool, input, toolUseContext, assistantMessage, toolUseId, forceDecision) => {
|
|
3434
|
+
const mainPermissionResult = forceDecision ?? await hasPermissionsToUseTool(tool, input, toolUseContext, assistantMessage, toolUseId);
|
|
3435
|
+
if (mainPermissionResult.behavior === "allow" || mainPermissionResult.behavior === "deny") {
|
|
3436
|
+
return mainPermissionResult;
|
|
3437
|
+
}
|
|
3438
|
+
const { signal: combinedSignal, cleanup: cleanupAbortListener } = createCombinedAbortSignal(toolUseContext.abortController.signal);
|
|
3439
|
+
if (combinedSignal.aborted) {
|
|
3440
|
+
cleanupAbortListener();
|
|
3441
|
+
return {
|
|
3442
|
+
behavior: "deny",
|
|
3443
|
+
message: "Permission prompt was aborted.",
|
|
3444
|
+
decisionReason: {
|
|
3445
|
+
type: "permissionPromptTool",
|
|
3446
|
+
permissionPromptToolName: tool.name,
|
|
3447
|
+
toolResult: undefined
|
|
3448
|
+
}
|
|
3449
|
+
};
|
|
3450
|
+
}
|
|
3451
|
+
const abortPromise = new Promise((resolve) => {
|
|
3452
|
+
combinedSignal.addEventListener("abort", () => resolve("aborted"), {
|
|
3453
|
+
once: true
|
|
3454
|
+
});
|
|
3455
|
+
});
|
|
3456
|
+
const toolCallPromise = permissionPromptTool.call({
|
|
3457
|
+
tool_name: tool.name,
|
|
3458
|
+
input,
|
|
3459
|
+
tool_use_id: toolUseId
|
|
3460
|
+
}, toolUseContext, canUseTool, assistantMessage);
|
|
3461
|
+
const raceResult = await Promise.race([toolCallPromise, abortPromise]);
|
|
3462
|
+
cleanupAbortListener();
|
|
3463
|
+
if (raceResult === "aborted" || combinedSignal.aborted) {
|
|
3464
|
+
return {
|
|
3465
|
+
behavior: "deny",
|
|
3466
|
+
message: "Permission prompt was aborted.",
|
|
3467
|
+
decisionReason: {
|
|
3468
|
+
type: "permissionPromptTool",
|
|
3469
|
+
permissionPromptToolName: tool.name,
|
|
3470
|
+
toolResult: undefined
|
|
3471
|
+
}
|
|
3472
|
+
};
|
|
3473
|
+
}
|
|
3474
|
+
const result = raceResult;
|
|
3475
|
+
const permissionToolResultBlockParam = permissionPromptTool.mapToolResultToToolResultBlockParam(result.data, "1");
|
|
3476
|
+
if (!permissionToolResultBlockParam.content || !Array.isArray(permissionToolResultBlockParam.content) || !permissionToolResultBlockParam.content[0] || permissionToolResultBlockParam.content[0].type !== "text" || typeof permissionToolResultBlockParam.content[0].text !== "string") {
|
|
3477
|
+
throw new Error('Permission prompt tool returned an invalid result. Expected a single text block param with type="text" and a string text value.');
|
|
3478
|
+
}
|
|
3479
|
+
return permissionPromptToolResultToPermissionDecision(outputSchema().parse(safeParseJSON(permissionToolResultBlockParam.content[0].text)), permissionPromptTool, input, toolUseContext);
|
|
3480
|
+
};
|
|
3481
|
+
return canUseTool;
|
|
3482
|
+
}
|
|
3483
|
+
function getCanUseToolFn(permissionPromptToolName, structuredIO, getMcpTools, onPermissionPrompt) {
|
|
3484
|
+
if (permissionPromptToolName === "stdio") {
|
|
3485
|
+
return structuredIO.createCanUseTool(onPermissionPrompt);
|
|
3486
|
+
}
|
|
3487
|
+
if (!permissionPromptToolName) {
|
|
3488
|
+
return async (tool, input, toolUseContext, assistantMessage, toolUseId, forceDecision) => forceDecision ?? await hasPermissionsToUseTool(tool, input, toolUseContext, assistantMessage, toolUseId);
|
|
3489
|
+
}
|
|
3490
|
+
let resolved = null;
|
|
3491
|
+
return async (tool, input, toolUseContext, assistantMessage, toolUseId, forceDecision) => {
|
|
3492
|
+
if (!resolved) {
|
|
3493
|
+
const mcpTools = getMcpTools();
|
|
3494
|
+
const permissionPromptTool = mcpTools.find((t) => toolMatchesName(t, permissionPromptToolName));
|
|
3495
|
+
if (!permissionPromptTool) {
|
|
3496
|
+
const error = `Error: MCP tool ${permissionPromptToolName} (passed via --permission-prompt-tool) not found. Available MCP tools: ${mcpTools.map((t) => t.name).join(", ") || "none"}`;
|
|
3497
|
+
process.stderr.write(`${error}
|
|
3498
|
+
`);
|
|
3499
|
+
gracefulShutdownSync(1);
|
|
3500
|
+
throw new Error(error);
|
|
3501
|
+
}
|
|
3502
|
+
if (!permissionPromptTool.inputJSONSchema) {
|
|
3503
|
+
const error = `Error: tool ${permissionPromptToolName} (passed via --permission-prompt-tool) must be an MCP tool`;
|
|
3504
|
+
process.stderr.write(`${error}
|
|
3505
|
+
`);
|
|
3506
|
+
gracefulShutdownSync(1);
|
|
3507
|
+
throw new Error(error);
|
|
3508
|
+
}
|
|
3509
|
+
resolved = createCanUseToolWithPermissionPrompt(permissionPromptTool);
|
|
3510
|
+
}
|
|
3511
|
+
return resolved(tool, input, toolUseContext, assistantMessage, toolUseId, forceDecision);
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3514
|
+
async function handleInitializeRequest(request, requestId, initialized, output, commands, modelInfos, structuredIO, enableAuthStatus, options, agents, getAppState) {
|
|
3515
|
+
if (initialized) {
|
|
3516
|
+
output.enqueue({
|
|
3517
|
+
type: "control_response",
|
|
3518
|
+
response: {
|
|
3519
|
+
subtype: "error",
|
|
3520
|
+
error: "Already initialized",
|
|
3521
|
+
request_id: requestId,
|
|
3522
|
+
pending_permission_requests: structuredIO.getPendingPermissionRequests()
|
|
3523
|
+
}
|
|
3524
|
+
});
|
|
3525
|
+
return;
|
|
3526
|
+
}
|
|
3527
|
+
if (request.systemPrompt !== undefined) {
|
|
3528
|
+
options.systemPrompt = request.systemPrompt;
|
|
3529
|
+
}
|
|
3530
|
+
if (request.appendSystemPrompt !== undefined) {
|
|
3531
|
+
options.appendSystemPrompt = request.appendSystemPrompt;
|
|
3532
|
+
}
|
|
3533
|
+
if (request.promptSuggestions !== undefined) {
|
|
3534
|
+
options.promptSuggestions = request.promptSuggestions;
|
|
3535
|
+
}
|
|
3536
|
+
if (request.agents) {
|
|
3537
|
+
const stdinAgents = parseAgentsFromJson(request.agents, "flagSettings");
|
|
3538
|
+
agents.push(...stdinAgents);
|
|
3539
|
+
}
|
|
3540
|
+
if (options.agent) {
|
|
3541
|
+
const alreadyResolved = getMainThreadAgentType() === options.agent;
|
|
3542
|
+
const mainThreadAgent = agents.find((a) => a.agentType === options.agent);
|
|
3543
|
+
if (mainThreadAgent && !alreadyResolved) {
|
|
3544
|
+
setMainThreadAgentType(mainThreadAgent.agentType);
|
|
3545
|
+
if (!options.systemPrompt && !isBuiltInAgent(mainThreadAgent)) {
|
|
3546
|
+
const agentSystemPrompt = mainThreadAgent.getSystemPrompt();
|
|
3547
|
+
if (agentSystemPrompt) {
|
|
3548
|
+
options.systemPrompt = agentSystemPrompt;
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
if (!options.userSpecifiedModel && mainThreadAgent.model && mainThreadAgent.model !== "inherit") {
|
|
3552
|
+
const agentModel = parseUserSpecifiedModel(mainThreadAgent.model);
|
|
3553
|
+
setMainLoopModelOverride(agentModel);
|
|
3554
|
+
}
|
|
3555
|
+
if (mainThreadAgent.initialPrompt) {
|
|
3556
|
+
structuredIO.prependUserMessage(mainThreadAgent.initialPrompt);
|
|
3557
|
+
}
|
|
3558
|
+
} else if (mainThreadAgent?.initialPrompt) {
|
|
3559
|
+
structuredIO.prependUserMessage(mainThreadAgent.initialPrompt);
|
|
3560
|
+
}
|
|
3561
|
+
}
|
|
3562
|
+
const settings = getSettings_DEPRECATED();
|
|
3563
|
+
const outputStyle = settings?.outputStyle || DEFAULT_OUTPUT_STYLE_NAME;
|
|
3564
|
+
const availableOutputStyles = await getAllOutputStyles(getCwd());
|
|
3565
|
+
const accountInfo = getAccountInformation();
|
|
3566
|
+
if (request.hooks) {
|
|
3567
|
+
const hooks = {};
|
|
3568
|
+
for (const [event, matchers] of Object.entries(request.hooks)) {
|
|
3569
|
+
hooks[event] = matchers.map((matcher) => {
|
|
3570
|
+
const callbacks = matcher.hookCallbackIds.map((callbackId) => {
|
|
3571
|
+
return structuredIO.createHookCallback(callbackId, matcher.timeout);
|
|
3572
|
+
});
|
|
3573
|
+
return {
|
|
3574
|
+
matcher: matcher.matcher,
|
|
3575
|
+
hooks: callbacks
|
|
3576
|
+
};
|
|
3577
|
+
});
|
|
3578
|
+
}
|
|
3579
|
+
registerHookCallbacks(hooks);
|
|
3580
|
+
}
|
|
3581
|
+
if (request.jsonSchema) {
|
|
3582
|
+
setInitJsonSchema(request.jsonSchema);
|
|
3583
|
+
}
|
|
3584
|
+
const initResponse = {
|
|
3585
|
+
commands: commands.filter((cmd) => cmd.userInvocable !== false).map((cmd) => ({
|
|
3586
|
+
name: getCommandName(cmd),
|
|
3587
|
+
description: formatDescriptionWithSource(cmd),
|
|
3588
|
+
argumentHint: cmd.argumentHint || ""
|
|
3589
|
+
})),
|
|
3590
|
+
agents: agents.map((agent) => ({
|
|
3591
|
+
name: agent.agentType,
|
|
3592
|
+
description: agent.whenToUse,
|
|
3593
|
+
model: agent.model === "inherit" ? undefined : agent.model
|
|
3594
|
+
})),
|
|
3595
|
+
output_style: outputStyle,
|
|
3596
|
+
available_output_styles: Object.keys(availableOutputStyles),
|
|
3597
|
+
models: modelInfos,
|
|
3598
|
+
account: {
|
|
3599
|
+
email: accountInfo?.email,
|
|
3600
|
+
organization: accountInfo?.organization,
|
|
3601
|
+
subscriptionType: accountInfo?.subscription,
|
|
3602
|
+
tokenSource: accountInfo?.tokenSource,
|
|
3603
|
+
apiKeySource: accountInfo?.apiKeySource,
|
|
3604
|
+
apiProvider: getAPIProvider()
|
|
3605
|
+
},
|
|
3606
|
+
pid: process.pid
|
|
3607
|
+
};
|
|
3608
|
+
if (isFastModeEnabled() && isFastModeAvailable()) {
|
|
3609
|
+
const appState = getAppState();
|
|
3610
|
+
initResponse.fast_mode_state = getFastModeState(options.userSpecifiedModel ?? null, appState.fastMode);
|
|
3611
|
+
}
|
|
3612
|
+
output.enqueue({
|
|
3613
|
+
type: "control_response",
|
|
3614
|
+
response: {
|
|
3615
|
+
subtype: "success",
|
|
3616
|
+
request_id: requestId,
|
|
3617
|
+
response: initResponse
|
|
3618
|
+
}
|
|
3619
|
+
});
|
|
3620
|
+
if (enableAuthStatus) {
|
|
3621
|
+
const authStatusManager = AwsAuthStatusManager.getInstance();
|
|
3622
|
+
const status = authStatusManager.getStatus();
|
|
3623
|
+
if (status) {
|
|
3624
|
+
output.enqueue({
|
|
3625
|
+
type: "auth_status",
|
|
3626
|
+
isAuthenticating: status.isAuthenticating,
|
|
3627
|
+
output: status.output,
|
|
3628
|
+
error: status.error,
|
|
3629
|
+
uuid: randomUUID2(),
|
|
3630
|
+
session_id: getSessionId()
|
|
3631
|
+
});
|
|
3632
|
+
}
|
|
3633
|
+
}
|
|
3634
|
+
}
|
|
3635
|
+
async function handleRewindFiles(userMessageId, appState, setAppState, dryRun) {
|
|
3636
|
+
if (!fileHistoryEnabled()) {
|
|
3637
|
+
return {
|
|
3638
|
+
canRewind: false,
|
|
3639
|
+
error: "File rewinding is not enabled.",
|
|
3640
|
+
filesChanged: []
|
|
3641
|
+
};
|
|
3642
|
+
}
|
|
3643
|
+
if (!fileHistoryCanRestore(appState.fileHistory, userMessageId)) {
|
|
3644
|
+
return {
|
|
3645
|
+
canRewind: false,
|
|
3646
|
+
error: "No file checkpoint found for this message.",
|
|
3647
|
+
filesChanged: []
|
|
3648
|
+
};
|
|
3649
|
+
}
|
|
3650
|
+
if (dryRun) {
|
|
3651
|
+
const diffStats = await fileHistoryGetDiffStats(appState.fileHistory, userMessageId);
|
|
3652
|
+
return {
|
|
3653
|
+
canRewind: true,
|
|
3654
|
+
filesChanged: diffStats?.filesChanged ?? [],
|
|
3655
|
+
insertions: diffStats?.insertions,
|
|
3656
|
+
deletions: diffStats?.deletions
|
|
3657
|
+
};
|
|
3658
|
+
}
|
|
3659
|
+
try {
|
|
3660
|
+
await fileHistoryRewind((updater) => setAppState((prev) => ({
|
|
3661
|
+
...prev,
|
|
3662
|
+
fileHistory: updater(prev.fileHistory)
|
|
3663
|
+
})), userMessageId);
|
|
3664
|
+
} catch (error) {
|
|
3665
|
+
return {
|
|
3666
|
+
canRewind: false,
|
|
3667
|
+
error: `Failed to rewind: ${errorMessage(error)}`,
|
|
3668
|
+
filesChanged: []
|
|
3669
|
+
};
|
|
3670
|
+
}
|
|
3671
|
+
return { canRewind: true, filesChanged: [] };
|
|
3672
|
+
}
|
|
3673
|
+
function handleSetPermissionMode(request, requestId, toolPermissionContext, output) {
|
|
3674
|
+
if (request.mode === "bypassPermissions") {
|
|
3675
|
+
if (isBypassPermissionsModeDisabled()) {
|
|
3676
|
+
output.enqueue({
|
|
3677
|
+
type: "control_response",
|
|
3678
|
+
response: {
|
|
3679
|
+
subtype: "error",
|
|
3680
|
+
request_id: requestId,
|
|
3681
|
+
error: "Cannot set permission mode to bypassPermissions because it is disabled by settings or configuration"
|
|
3682
|
+
}
|
|
3683
|
+
});
|
|
3684
|
+
return toolPermissionContext;
|
|
3685
|
+
}
|
|
3686
|
+
if (!toolPermissionContext.isBypassPermissionsModeAvailable) {
|
|
3687
|
+
output.enqueue({
|
|
3688
|
+
type: "control_response",
|
|
3689
|
+
response: {
|
|
3690
|
+
subtype: "error",
|
|
3691
|
+
request_id: requestId,
|
|
3692
|
+
error: "Cannot set permission mode to bypassPermissions because the session was not launched with --dangerously-skip-permissions"
|
|
3693
|
+
}
|
|
3694
|
+
});
|
|
3695
|
+
return toolPermissionContext;
|
|
3696
|
+
}
|
|
3697
|
+
}
|
|
3698
|
+
if (request.mode === "auto" && !isAutoModeGateEnabled()) {
|
|
3699
|
+
const reason = getAutoModeUnavailableReason();
|
|
3700
|
+
output.enqueue({
|
|
3701
|
+
type: "control_response",
|
|
3702
|
+
response: {
|
|
3703
|
+
subtype: "error",
|
|
3704
|
+
request_id: requestId,
|
|
3705
|
+
error: reason ? `Cannot set permission mode to auto: ${getAutoModeUnavailableNotification(reason)}` : "Cannot set permission mode to auto"
|
|
3706
|
+
}
|
|
3707
|
+
});
|
|
3708
|
+
return toolPermissionContext;
|
|
3709
|
+
}
|
|
3710
|
+
output.enqueue({
|
|
3711
|
+
type: "control_response",
|
|
3712
|
+
response: {
|
|
3713
|
+
subtype: "success",
|
|
3714
|
+
request_id: requestId,
|
|
3715
|
+
response: {
|
|
3716
|
+
mode: request.mode
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
});
|
|
3720
|
+
return {
|
|
3721
|
+
...transitionPermissionMode(toolPermissionContext.mode, request.mode, toolPermissionContext),
|
|
3722
|
+
mode: request.mode
|
|
3723
|
+
};
|
|
3724
|
+
}
|
|
3725
|
+
function handleChannelEnable(requestId, serverName, connectionPool, output) {
|
|
3726
|
+
const respondError = (error) => output.enqueue({
|
|
3727
|
+
type: "control_response",
|
|
3728
|
+
response: { subtype: "error", request_id: requestId, error }
|
|
3729
|
+
});
|
|
3730
|
+
if (false) {}
|
|
3731
|
+
const connection = connectionPool.find((c) => c.name === serverName && c.type === "connected");
|
|
3732
|
+
if (!connection || connection.type !== "connected") {
|
|
3733
|
+
return respondError(`server ${serverName} is not connected`);
|
|
3734
|
+
}
|
|
3735
|
+
const pluginSource = connection.config.pluginSource;
|
|
3736
|
+
const parsed = pluginSource ? parsePluginIdentifier(pluginSource) : undefined;
|
|
3737
|
+
if (!parsed?.marketplace) {
|
|
3738
|
+
return respondError(`server ${serverName} is not plugin-sourced; channel_enable requires a marketplace plugin`);
|
|
3739
|
+
}
|
|
3740
|
+
const entry = {
|
|
3741
|
+
kind: "plugin",
|
|
3742
|
+
name: parsed.name,
|
|
3743
|
+
marketplace: parsed.marketplace
|
|
3744
|
+
};
|
|
3745
|
+
const prior = getAllowedChannels();
|
|
3746
|
+
const already = prior.some((e) => e.kind === "plugin" && e.name === entry.name && e.marketplace === entry.marketplace);
|
|
3747
|
+
if (!already)
|
|
3748
|
+
setAllowedChannels([...prior, entry]);
|
|
3749
|
+
const gate = gateChannelServer(serverName, connection.capabilities, pluginSource);
|
|
3750
|
+
if (gate.action === "skip") {
|
|
3751
|
+
if (!already)
|
|
3752
|
+
setAllowedChannels(prior);
|
|
3753
|
+
return respondError(gate.reason);
|
|
3754
|
+
}
|
|
3755
|
+
const pluginId = `${entry.name}@${entry.marketplace}`;
|
|
3756
|
+
logMCPDebug(serverName, "Channel notifications registered");
|
|
3757
|
+
logEvent("tengu_mcp_channel_enable", { plugin: pluginId });
|
|
3758
|
+
connection.client.setNotificationHandler(ChannelMessageNotificationSchema(), async (notification) => {
|
|
3759
|
+
const { content, meta } = notification.params;
|
|
3760
|
+
logMCPDebug(serverName, `notifications/claude/channel: ${content.slice(0, 80)}`);
|
|
3761
|
+
logEvent("tengu_mcp_channel_message", {
|
|
3762
|
+
content_length: content.length,
|
|
3763
|
+
meta_key_count: Object.keys(meta ?? {}).length,
|
|
3764
|
+
entry_kind: "plugin",
|
|
3765
|
+
is_dev: false,
|
|
3766
|
+
plugin: pluginId
|
|
3767
|
+
});
|
|
3768
|
+
enqueue({
|
|
3769
|
+
mode: "prompt",
|
|
3770
|
+
value: wrapChannelMessage(serverName, content, meta),
|
|
3771
|
+
priority: "next",
|
|
3772
|
+
isMeta: true,
|
|
3773
|
+
origin: { kind: "channel", server: serverName },
|
|
3774
|
+
skipSlashCommands: true
|
|
3775
|
+
});
|
|
3776
|
+
});
|
|
3777
|
+
output.enqueue({
|
|
3778
|
+
type: "control_response",
|
|
3779
|
+
response: {
|
|
3780
|
+
subtype: "success",
|
|
3781
|
+
request_id: requestId,
|
|
3782
|
+
response: undefined
|
|
3783
|
+
}
|
|
3784
|
+
});
|
|
3785
|
+
}
|
|
3786
|
+
function reregisterChannelHandlerAfterReconnect(connection) {
|
|
3787
|
+
if (connection.type !== "connected")
|
|
3788
|
+
return;
|
|
3789
|
+
const gate = gateChannelServer(connection.name, connection.capabilities, connection.config.pluginSource);
|
|
3790
|
+
if (gate.action !== "register")
|
|
3791
|
+
return;
|
|
3792
|
+
const entry = findChannelEntry(connection.name, getAllowedChannels());
|
|
3793
|
+
const pluginId = entry?.kind === "plugin" ? `${entry.name}@${entry.marketplace}` : undefined;
|
|
3794
|
+
logMCPDebug(connection.name, "Channel notifications re-registered after reconnect");
|
|
3795
|
+
connection.client.setNotificationHandler(ChannelMessageNotificationSchema(), async (notification) => {
|
|
3796
|
+
const { content, meta } = notification.params;
|
|
3797
|
+
logMCPDebug(connection.name, `notifications/claude/channel: ${content.slice(0, 80)}`);
|
|
3798
|
+
logEvent("tengu_mcp_channel_message", {
|
|
3799
|
+
content_length: content.length,
|
|
3800
|
+
meta_key_count: Object.keys(meta ?? {}).length,
|
|
3801
|
+
entry_kind: entry?.kind,
|
|
3802
|
+
is_dev: entry?.dev ?? false,
|
|
3803
|
+
plugin: pluginId
|
|
3804
|
+
});
|
|
3805
|
+
enqueue({
|
|
3806
|
+
mode: "prompt",
|
|
3807
|
+
value: wrapChannelMessage(connection.name, content, meta),
|
|
3808
|
+
priority: "next",
|
|
3809
|
+
isMeta: true,
|
|
3810
|
+
origin: {
|
|
3811
|
+
kind: "channel",
|
|
3812
|
+
server: connection.name
|
|
3813
|
+
},
|
|
3814
|
+
skipSlashCommands: true
|
|
3815
|
+
});
|
|
3816
|
+
});
|
|
3817
|
+
}
|
|
3818
|
+
function emitLoadError(message, outputFormat) {
|
|
3819
|
+
if (outputFormat === "stream-json") {
|
|
3820
|
+
const errorResult = {
|
|
3821
|
+
type: "result",
|
|
3822
|
+
subtype: "error_during_execution",
|
|
3823
|
+
duration_ms: 0,
|
|
3824
|
+
duration_api_ms: 0,
|
|
3825
|
+
is_error: true,
|
|
3826
|
+
num_turns: 0,
|
|
3827
|
+
stop_reason: null,
|
|
3828
|
+
session_id: getSessionId(),
|
|
3829
|
+
total_cost_usd: 0,
|
|
3830
|
+
usage: EMPTY_USAGE,
|
|
3831
|
+
modelUsage: {},
|
|
3832
|
+
permission_denials: [],
|
|
3833
|
+
uuid: randomUUID2(),
|
|
3834
|
+
errors: [message]
|
|
3835
|
+
};
|
|
3836
|
+
process.stdout.write(jsonStringify(errorResult) + `
|
|
3837
|
+
`);
|
|
3838
|
+
} else {
|
|
3839
|
+
process.stderr.write(message + `
|
|
3840
|
+
`);
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3843
|
+
function removeInterruptedMessage(messages, interruptedUserMessage) {
|
|
3844
|
+
const idx = messages.findIndex((m) => m.uuid === interruptedUserMessage.uuid);
|
|
3845
|
+
if (idx !== -1) {
|
|
3846
|
+
messages.splice(idx, 2);
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
async function loadInitialMessages(setAppState, options) {
|
|
3850
|
+
const persistSession = !isSessionPersistenceDisabled();
|
|
3851
|
+
if (options.continue) {
|
|
3852
|
+
try {
|
|
3853
|
+
logEvent("tengu_continue_print", {});
|
|
3854
|
+
const result = await loadConversationForResume(undefined, undefined);
|
|
3855
|
+
if (result) {
|
|
3856
|
+
if (false) {}
|
|
3857
|
+
if (!options.forkSession) {
|
|
3858
|
+
if (result.sessionId) {
|
|
3859
|
+
switchSession(asSessionId(result.sessionId), result.fullPath ? dirname(result.fullPath) : null);
|
|
3860
|
+
if (persistSession) {
|
|
3861
|
+
await resetSessionFilePointer();
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
restoreSessionStateFromLog(result, setAppState);
|
|
3866
|
+
restoreSessionMetadata(options.forkSession ? { ...result, worktreeSession: undefined } : result);
|
|
3867
|
+
if (false) {}
|
|
3868
|
+
return {
|
|
3869
|
+
messages: result.messages,
|
|
3870
|
+
turnInterruptionState: result.turnInterruptionState,
|
|
3871
|
+
agentSetting: result.agentSetting
|
|
3872
|
+
};
|
|
3873
|
+
}
|
|
3874
|
+
} catch (error) {
|
|
3875
|
+
logError(error);
|
|
3876
|
+
gracefulShutdownSync(1);
|
|
3877
|
+
return { messages: [] };
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
if (options.teleport) {
|
|
3881
|
+
try {
|
|
3882
|
+
if (!isPolicyAllowed("allow_remote_sessions")) {
|
|
3883
|
+
throw new Error("Remote sessions are disabled by your organization's policy.");
|
|
3884
|
+
}
|
|
3885
|
+
logEvent("tengu_teleport_print", {});
|
|
3886
|
+
if (typeof options.teleport !== "string") {
|
|
3887
|
+
throw new Error("No session ID provided for teleport");
|
|
3888
|
+
}
|
|
3889
|
+
const {
|
|
3890
|
+
checkOutTeleportedSessionBranch,
|
|
3891
|
+
processMessagesForTeleportResume,
|
|
3892
|
+
teleportResumeCodeSession,
|
|
3893
|
+
validateGitState
|
|
3894
|
+
} = await import("./chunk-hbhs3mwy.js");
|
|
3895
|
+
await validateGitState();
|
|
3896
|
+
const teleportResult = await teleportResumeCodeSession(options.teleport);
|
|
3897
|
+
const { branchError } = await checkOutTeleportedSessionBranch(teleportResult.branch);
|
|
3898
|
+
return {
|
|
3899
|
+
messages: processMessagesForTeleportResume(teleportResult.log, branchError)
|
|
3900
|
+
};
|
|
3901
|
+
} catch (error) {
|
|
3902
|
+
logError(error);
|
|
3903
|
+
gracefulShutdownSync(1);
|
|
3904
|
+
return { messages: [] };
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3907
|
+
if (options.resume) {
|
|
3908
|
+
try {
|
|
3909
|
+
logEvent("tengu_resume_print", {});
|
|
3910
|
+
const parsedSessionId = parseSessionIdentifier(typeof options.resume === "string" ? options.resume : "");
|
|
3911
|
+
if (!parsedSessionId) {
|
|
3912
|
+
let errorMessage2 = "Error: --resume requires a valid session ID when used with --print. Usage: redscope -p --resume <session-id>";
|
|
3913
|
+
if (typeof options.resume === "string") {
|
|
3914
|
+
errorMessage2 += `. Session IDs must be in UUID format (e.g., 550e8400-e29b-41d4-a716-446655440000). Provided value "${options.resume}" is not a valid UUID`;
|
|
3915
|
+
}
|
|
3916
|
+
emitLoadError(errorMessage2, options.outputFormat);
|
|
3917
|
+
gracefulShutdownSync(1);
|
|
3918
|
+
return { messages: [] };
|
|
3919
|
+
}
|
|
3920
|
+
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_CCR_V2)) {
|
|
3921
|
+
const [, metadata] = await Promise.all([
|
|
3922
|
+
hydrateFromCCRv2InternalEvents(parsedSessionId.sessionId),
|
|
3923
|
+
options.restoredWorkerState
|
|
3924
|
+
]);
|
|
3925
|
+
if (metadata) {
|
|
3926
|
+
setAppState(externalMetadataToAppState(metadata));
|
|
3927
|
+
if (typeof metadata.model === "string") {
|
|
3928
|
+
setMainLoopModelOverride(metadata.model);
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
} else if (parsedSessionId.isUrl && parsedSessionId.ingressUrl && isEnvTruthy(process.env.ENABLE_SESSION_PERSISTENCE)) {
|
|
3932
|
+
await hydrateRemoteSession(parsedSessionId.sessionId, parsedSessionId.ingressUrl);
|
|
3933
|
+
}
|
|
3934
|
+
const result = await loadConversationForResume(parsedSessionId.sessionId, parsedSessionId.jsonlFile || undefined);
|
|
3935
|
+
if (!result || result.messages.length === 0) {
|
|
3936
|
+
if (parsedSessionId.isUrl || isEnvTruthy(process.env.CLAUDE_CODE_USE_CCR_V2)) {
|
|
3937
|
+
return {
|
|
3938
|
+
messages: await (options.sessionStartHooksPromise ?? processSessionStartHooks("startup"))
|
|
3939
|
+
};
|
|
3940
|
+
} else {
|
|
3941
|
+
emitLoadError(`No conversation found with session ID: ${parsedSessionId.sessionId}`, options.outputFormat);
|
|
3942
|
+
gracefulShutdownSync(1);
|
|
3943
|
+
return { messages: [] };
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3946
|
+
if (options.resumeSessionAt) {
|
|
3947
|
+
const index = result.messages.findIndex((m) => m.uuid === options.resumeSessionAt);
|
|
3948
|
+
if (index < 0) {
|
|
3949
|
+
emitLoadError(`No message found with message.uuid of: ${options.resumeSessionAt}`, options.outputFormat);
|
|
3950
|
+
gracefulShutdownSync(1);
|
|
3951
|
+
return { messages: [] };
|
|
3952
|
+
}
|
|
3953
|
+
result.messages = index >= 0 ? result.messages.slice(0, index + 1) : [];
|
|
3954
|
+
}
|
|
3955
|
+
if (false) {}
|
|
3956
|
+
if (!options.forkSession && result.sessionId) {
|
|
3957
|
+
switchSession(asSessionId(result.sessionId), result.fullPath ? dirname(result.fullPath) : null);
|
|
3958
|
+
if (persistSession) {
|
|
3959
|
+
await resetSessionFilePointer();
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
restoreSessionStateFromLog(result, setAppState);
|
|
3963
|
+
restoreSessionMetadata(options.forkSession ? { ...result, worktreeSession: undefined } : result);
|
|
3964
|
+
if (false) {}
|
|
3965
|
+
return {
|
|
3966
|
+
messages: result.messages,
|
|
3967
|
+
turnInterruptionState: result.turnInterruptionState,
|
|
3968
|
+
agentSetting: result.agentSetting
|
|
3969
|
+
};
|
|
3970
|
+
} catch (error) {
|
|
3971
|
+
logError(error);
|
|
3972
|
+
const errorMessage2 = error instanceof Error ? `Failed to resume session: ${error.message}` : "Failed to resume session with --print mode";
|
|
3973
|
+
emitLoadError(errorMessage2, options.outputFormat);
|
|
3974
|
+
gracefulShutdownSync(1);
|
|
3975
|
+
return { messages: [] };
|
|
3976
|
+
}
|
|
3977
|
+
}
|
|
3978
|
+
return {
|
|
3979
|
+
messages: await (options.sessionStartHooksPromise ?? processSessionStartHooks("startup"))
|
|
3980
|
+
};
|
|
3981
|
+
}
|
|
3982
|
+
function getStructuredIO(inputPrompt, options) {
|
|
3983
|
+
let inputStream;
|
|
3984
|
+
if (typeof inputPrompt === "string") {
|
|
3985
|
+
if (inputPrompt.trim() !== "") {
|
|
3986
|
+
inputStream = fromArray([
|
|
3987
|
+
jsonStringify({
|
|
3988
|
+
type: "user",
|
|
3989
|
+
content: inputPrompt,
|
|
3990
|
+
uuid: "",
|
|
3991
|
+
session_id: "",
|
|
3992
|
+
message: {
|
|
3993
|
+
role: "user",
|
|
3994
|
+
content: inputPrompt
|
|
3995
|
+
},
|
|
3996
|
+
parent_tool_use_id: null
|
|
3997
|
+
})
|
|
3998
|
+
]);
|
|
3999
|
+
} else {
|
|
4000
|
+
inputStream = fromArray([]);
|
|
4001
|
+
}
|
|
4002
|
+
} else {
|
|
4003
|
+
inputStream = inputPrompt;
|
|
4004
|
+
}
|
|
4005
|
+
return options.sdkUrl ? new RemoteIO(options.sdkUrl, inputStream, options.replayUserMessages) : new StructuredIO(inputStream, options.replayUserMessages);
|
|
4006
|
+
}
|
|
4007
|
+
async function handleOrphanedPermissionResponse({
|
|
4008
|
+
message,
|
|
4009
|
+
setAppState,
|
|
4010
|
+
onEnqueued,
|
|
4011
|
+
handledToolUseIds
|
|
4012
|
+
}) {
|
|
4013
|
+
const responseInner = message.response;
|
|
4014
|
+
if (responseInner?.subtype === "success" && responseInner.response?.toolUseID && typeof responseInner.response.toolUseID === "string") {
|
|
4015
|
+
const permissionResult = responseInner.response;
|
|
4016
|
+
const toolUseID = permissionResult.toolUseID;
|
|
4017
|
+
if (!toolUseID) {
|
|
4018
|
+
return false;
|
|
4019
|
+
}
|
|
4020
|
+
logForDebugging(`handleOrphanedPermissionResponse: received orphaned control_response for toolUseID=${toolUseID} request_id=${responseInner.request_id}`);
|
|
4021
|
+
if (handledToolUseIds.has(toolUseID)) {
|
|
4022
|
+
logForDebugging(`handleOrphanedPermissionResponse: skipping duplicate orphaned permission for toolUseID=${toolUseID} (already handled)`);
|
|
4023
|
+
return false;
|
|
4024
|
+
}
|
|
4025
|
+
const assistantMessage = await findUnresolvedToolUse(toolUseID);
|
|
4026
|
+
if (!assistantMessage) {
|
|
4027
|
+
logForDebugging(`handleOrphanedPermissionResponse: no unresolved tool_use found for toolUseID=${toolUseID} (already resolved in transcript)`);
|
|
4028
|
+
return false;
|
|
4029
|
+
}
|
|
4030
|
+
handledToolUseIds.add(toolUseID);
|
|
4031
|
+
logForDebugging(`handleOrphanedPermissionResponse: enqueuing orphaned permission for toolUseID=${toolUseID} messageID=${assistantMessage.message.id}`);
|
|
4032
|
+
enqueue({
|
|
4033
|
+
mode: "orphaned-permission",
|
|
4034
|
+
value: [],
|
|
4035
|
+
orphanedPermission: {
|
|
4036
|
+
permissionResult,
|
|
4037
|
+
assistantMessage
|
|
4038
|
+
}
|
|
4039
|
+
});
|
|
4040
|
+
onEnqueued?.();
|
|
4041
|
+
return true;
|
|
4042
|
+
}
|
|
4043
|
+
return false;
|
|
4044
|
+
}
|
|
4045
|
+
function toScopedConfig(config) {
|
|
4046
|
+
return { ...config, scope: "dynamic" };
|
|
4047
|
+
}
|
|
4048
|
+
async function handleMcpSetServers(servers, sdkState, dynamicState, setAppState) {
|
|
4049
|
+
const { allowed: allowedServers, blocked } = filterMcpServersByPolicy(servers);
|
|
4050
|
+
const policyErrors = {};
|
|
4051
|
+
for (const name of blocked) {
|
|
4052
|
+
policyErrors[name] = "Blocked by enterprise policy (allowedMcpServers/deniedMcpServers)";
|
|
4053
|
+
}
|
|
4054
|
+
const sdkServers = {};
|
|
4055
|
+
const processServers = {};
|
|
4056
|
+
for (const [name, config] of Object.entries(allowedServers)) {
|
|
4057
|
+
if (config.type === "sdk") {
|
|
4058
|
+
sdkServers[name] = config;
|
|
4059
|
+
} else {
|
|
4060
|
+
processServers[name] = config;
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
const currentSdkNames = new Set(Object.keys(sdkState.configs));
|
|
4064
|
+
const newSdkNames = new Set(Object.keys(sdkServers));
|
|
4065
|
+
const sdkAdded = [];
|
|
4066
|
+
const sdkRemoved = [];
|
|
4067
|
+
const newSdkConfigs = { ...sdkState.configs };
|
|
4068
|
+
let newSdkClients = [...sdkState.clients];
|
|
4069
|
+
let newSdkTools = [...sdkState.tools];
|
|
4070
|
+
for (const name of currentSdkNames) {
|
|
4071
|
+
if (!newSdkNames.has(name)) {
|
|
4072
|
+
const client = newSdkClients.find((c) => c.name === name);
|
|
4073
|
+
if (client && client.type === "connected") {
|
|
4074
|
+
await client.cleanup();
|
|
4075
|
+
}
|
|
4076
|
+
newSdkClients = newSdkClients.filter((c) => c.name !== name);
|
|
4077
|
+
const prefix = `mcp__${name}__`;
|
|
4078
|
+
newSdkTools = newSdkTools.filter((t) => !t.name.startsWith(prefix));
|
|
4079
|
+
delete newSdkConfigs[name];
|
|
4080
|
+
sdkRemoved.push(name);
|
|
4081
|
+
}
|
|
4082
|
+
}
|
|
4083
|
+
for (const [name, config] of Object.entries(sdkServers)) {
|
|
4084
|
+
if (!currentSdkNames.has(name)) {
|
|
4085
|
+
newSdkConfigs[name] = config;
|
|
4086
|
+
const pendingClient = {
|
|
4087
|
+
type: "pending",
|
|
4088
|
+
name,
|
|
4089
|
+
config: { ...config, scope: "dynamic" }
|
|
4090
|
+
};
|
|
4091
|
+
newSdkClients = [...newSdkClients, pendingClient];
|
|
4092
|
+
sdkAdded.push(name);
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
const processResult = await reconcileMcpServers(processServers, dynamicState, setAppState);
|
|
4096
|
+
return {
|
|
4097
|
+
response: {
|
|
4098
|
+
added: [...sdkAdded, ...processResult.response.added],
|
|
4099
|
+
removed: [...sdkRemoved, ...processResult.response.removed],
|
|
4100
|
+
errors: { ...policyErrors, ...processResult.response.errors }
|
|
4101
|
+
},
|
|
4102
|
+
newSdkState: {
|
|
4103
|
+
configs: newSdkConfigs,
|
|
4104
|
+
clients: newSdkClients,
|
|
4105
|
+
tools: newSdkTools
|
|
4106
|
+
},
|
|
4107
|
+
newDynamicState: processResult.newState,
|
|
4108
|
+
sdkServersChanged: sdkAdded.length > 0 || sdkRemoved.length > 0
|
|
4109
|
+
};
|
|
4110
|
+
}
|
|
4111
|
+
async function reconcileMcpServers(desiredConfigs, currentState, setAppState) {
|
|
4112
|
+
const currentNames = new Set(Object.keys(currentState.configs));
|
|
4113
|
+
const desiredNames = new Set(Object.keys(desiredConfigs));
|
|
4114
|
+
const toRemove = [...currentNames].filter((n) => !desiredNames.has(n));
|
|
4115
|
+
const toAdd = [...desiredNames].filter((n) => !currentNames.has(n));
|
|
4116
|
+
const toCheck = [...currentNames].filter((n) => desiredNames.has(n));
|
|
4117
|
+
const toReplace = toCheck.filter((name) => {
|
|
4118
|
+
const currentConfig = currentState.configs[name];
|
|
4119
|
+
const desiredConfigRaw = desiredConfigs[name];
|
|
4120
|
+
if (!currentConfig || !desiredConfigRaw)
|
|
4121
|
+
return true;
|
|
4122
|
+
const desiredConfig = toScopedConfig(desiredConfigRaw);
|
|
4123
|
+
return !areMcpConfigsEqual(currentConfig, desiredConfig);
|
|
4124
|
+
});
|
|
4125
|
+
const removed = [];
|
|
4126
|
+
const added = [];
|
|
4127
|
+
const errors = {};
|
|
4128
|
+
let newClients = [...currentState.clients];
|
|
4129
|
+
let newTools = [...currentState.tools];
|
|
4130
|
+
for (const name of [...toRemove, ...toReplace]) {
|
|
4131
|
+
const client = newClients.find((c) => c.name === name);
|
|
4132
|
+
const config = currentState.configs[name];
|
|
4133
|
+
if (client && config) {
|
|
4134
|
+
if (client.type === "connected") {
|
|
4135
|
+
try {
|
|
4136
|
+
await client.cleanup();
|
|
4137
|
+
} catch (e) {
|
|
4138
|
+
logError(e);
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
await clearServerCache(name, config);
|
|
4142
|
+
}
|
|
4143
|
+
const prefix = `mcp__${name}__`;
|
|
4144
|
+
newTools = newTools.filter((t) => !t.name.startsWith(prefix));
|
|
4145
|
+
newClients = newClients.filter((c) => c.name !== name);
|
|
4146
|
+
if (toRemove.includes(name)) {
|
|
4147
|
+
removed.push(name);
|
|
4148
|
+
}
|
|
4149
|
+
}
|
|
4150
|
+
for (const name of [...toAdd, ...toReplace]) {
|
|
4151
|
+
const config = desiredConfigs[name];
|
|
4152
|
+
if (!config)
|
|
4153
|
+
continue;
|
|
4154
|
+
const scopedConfig = toScopedConfig(config);
|
|
4155
|
+
if (config.type === "sdk") {
|
|
4156
|
+
added.push(name);
|
|
4157
|
+
continue;
|
|
4158
|
+
}
|
|
4159
|
+
try {
|
|
4160
|
+
const client = await connectToServer(name, scopedConfig);
|
|
4161
|
+
newClients.push(client);
|
|
4162
|
+
if (client.type === "connected") {
|
|
4163
|
+
const serverTools = await fetchToolsForClient(client);
|
|
4164
|
+
newTools.push(...serverTools);
|
|
4165
|
+
} else if (client.type === "failed") {
|
|
4166
|
+
errors[name] = client.error || "Connection failed";
|
|
4167
|
+
}
|
|
4168
|
+
added.push(name);
|
|
4169
|
+
} catch (e) {
|
|
4170
|
+
const err = toError(e);
|
|
4171
|
+
errors[name] = err.message;
|
|
4172
|
+
logError(err);
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
const newConfigs = {};
|
|
4176
|
+
for (const name of desiredNames) {
|
|
4177
|
+
const config = desiredConfigs[name];
|
|
4178
|
+
if (config) {
|
|
4179
|
+
newConfigs[name] = toScopedConfig(config);
|
|
4180
|
+
}
|
|
4181
|
+
}
|
|
4182
|
+
const newState = {
|
|
4183
|
+
clients: newClients,
|
|
4184
|
+
tools: newTools,
|
|
4185
|
+
configs: newConfigs
|
|
4186
|
+
};
|
|
4187
|
+
setAppState((prev) => {
|
|
4188
|
+
const allDynamicServerNames = new Set([
|
|
4189
|
+
...Object.keys(currentState.configs),
|
|
4190
|
+
...Object.keys(newConfigs)
|
|
4191
|
+
]);
|
|
4192
|
+
const nonDynamicTools = prev.mcp.tools.filter((t) => {
|
|
4193
|
+
for (const serverName of allDynamicServerNames) {
|
|
4194
|
+
if (t.name.startsWith(`mcp__${serverName}__`)) {
|
|
4195
|
+
return false;
|
|
4196
|
+
}
|
|
4197
|
+
}
|
|
4198
|
+
return true;
|
|
4199
|
+
});
|
|
4200
|
+
const nonDynamicClients = prev.mcp.clients.filter((c) => {
|
|
4201
|
+
return !allDynamicServerNames.has(c.name);
|
|
4202
|
+
});
|
|
4203
|
+
return {
|
|
4204
|
+
...prev,
|
|
4205
|
+
mcp: {
|
|
4206
|
+
...prev.mcp,
|
|
4207
|
+
tools: [...nonDynamicTools, ...newTools],
|
|
4208
|
+
clients: [...nonDynamicClients, ...newClients]
|
|
4209
|
+
}
|
|
4210
|
+
};
|
|
4211
|
+
});
|
|
4212
|
+
return {
|
|
4213
|
+
response: { added, removed, errors },
|
|
4214
|
+
newState
|
|
4215
|
+
};
|
|
4216
|
+
}
|
|
4217
|
+
export {
|
|
4218
|
+
runHeadless,
|
|
4219
|
+
removeInterruptedMessage,
|
|
4220
|
+
reconcileMcpServers,
|
|
4221
|
+
joinPromptValues,
|
|
4222
|
+
handleOrphanedPermissionResponse,
|
|
4223
|
+
handleMcpSetServers,
|
|
4224
|
+
getCanUseToolFn,
|
|
4225
|
+
createCanUseToolWithPermissionPrompt,
|
|
4226
|
+
canBatchWith
|
|
4227
|
+
};
|