claude-code-best 1.4.2 → 1.4.3
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/dist/{chunk-cbew0pjr.js → chunk-01pfrqr8.js} +3 -3
- package/dist/{chunk-6pn8yw8f.js → chunk-045t7r98.js} +2 -2
- package/dist/{chunk-ze24rc11.js → chunk-05tebmww.js} +2 -2
- package/dist/chunk-0786r5qj.js +26 -0
- package/dist/{chunk-rnwcyhhr.js → chunk-0925w20x.js} +35 -32
- package/dist/{chunk-gsfvjkxs.js → chunk-0bthwtc4.js} +2 -2
- package/dist/{chunk-chzfw06n.js → chunk-0cshr8vt.js} +1 -1
- package/dist/{chunk-hb2tgq01.js → chunk-0dwxmzv5.js} +40 -38
- package/dist/{chunk-6p49gxps.js → chunk-0grvs3fk.js} +32 -29
- package/dist/{chunk-n01yv986.js → chunk-0mzj4pd6.js} +2 -2
- package/dist/{chunk-a53nf3qs.js → chunk-0tqqepp7.js} +1 -1
- package/dist/{chunk-2pnjckz1.js → chunk-0w1sq2wh.js} +32 -29
- package/dist/{chunk-j71410ke.js → chunk-11rpa5zm.js} +3 -3
- package/dist/{chunk-2c5g8fre.js → chunk-13z0sgs1.js} +2 -2
- package/dist/{chunk-dcekzc4y.js → chunk-1c9eqthz.js} +32 -29
- package/dist/{chunk-gccn64qd.js → chunk-1dnx9t9k.js} +32 -29
- package/dist/{chunk-swyjab92.js → chunk-1e3vcw6m.js} +102 -24
- package/dist/chunk-1ed27xte.js +395 -0
- package/dist/chunk-1f59hhb4.js +436 -0
- package/dist/{chunk-1avwhb0y.js → chunk-1feqvkrs.js} +38 -35
- package/dist/chunk-1gj0pnga.js +394 -0
- package/dist/{chunk-0bged80h.js → chunk-1j57r4bp.js} +2 -2
- package/dist/{chunk-xz76edqf.js → chunk-1jp931g0.js} +33 -30
- package/dist/{chunk-98z3psrf.js → chunk-1nkqjw8f.js} +1 -1
- package/dist/{chunk-bdy2epzn.js → chunk-1vddy71a.js} +33 -30
- package/dist/{chunk-xt7s28fx.js → chunk-25bv0psg.js} +32 -29
- package/dist/{chunk-6j28h9yw.js → chunk-27ezf4tc.js} +1 -1
- package/dist/{chunk-v038k0we.js → chunk-2hwxpswc.js} +2 -2
- package/dist/{chunk-70r0vj1c.js → chunk-2rdnvcex.js} +3 -3
- package/dist/{chunk-61nfv7fe.js → chunk-309spvbz.js} +4 -4
- package/dist/{chunk-6mr0jg0z.js → chunk-32p0jkaj.js} +32 -29
- package/dist/{chunk-bf9fz19d.js → chunk-34ct1dk0.js} +8 -8
- package/dist/{chunk-05p2rq7p.js → chunk-35bdpz91.js} +3 -3
- package/dist/{chunk-fsq6r5fm.js → chunk-35c6r949.js} +3 -3
- package/dist/{chunk-e7m4m372.js → chunk-35nbv64e.js} +33 -30
- package/dist/{chunk-jtmqgw9b.js → chunk-3c1emyyp.js} +7 -7
- package/dist/{chunk-mw1qkqcc.js → chunk-3czpsqvd.js} +47 -44
- package/dist/{chunk-v134wa9t.js → chunk-3e41bc8q.js} +1 -1
- package/dist/{chunk-jz4f7zpz.js → chunk-3jhddwfc.js} +7 -7
- package/dist/{chunk-dttqmtms.js → chunk-3me3nd70.js} +34 -31
- package/dist/{chunk-91e25as4.js → chunk-3nxv7rc1.js} +32 -29
- package/dist/{chunk-sx14s38q.js → chunk-3ybsbz1m.js} +41 -38
- package/dist/{chunk-90d9rpg3.js → chunk-40k3k0bt.js} +8 -8
- package/dist/{chunk-dpzdk73b.js → chunk-43v0vw9y.js} +1 -1
- package/dist/{chunk-2q5mzsfz.js → chunk-49hrrcw1.js} +33 -30
- package/dist/{chunk-9t3jghwt.js → chunk-4qv97nv2.js} +9 -9
- package/dist/{chunk-nbr86en0.js → chunk-4v58psnx.js} +32 -29
- package/dist/{chunk-kbys4txa.js → chunk-541f5hfx.js} +1 -1
- package/dist/{chunk-1byxenrx.js → chunk-572eqfcb.js} +34 -31
- package/dist/{chunk-yh18j16m.js → chunk-5b3k6tpd.js} +32 -29
- package/dist/{chunk-kay473m2.js → chunk-5cc4s826.js} +7 -7
- package/dist/{chunk-2nwebta4.js → chunk-5dhrvrtg.js} +3 -3
- package/dist/{chunk-6y2fbkkx.js → chunk-5fnc2arn.js} +2989 -2283
- package/dist/{chunk-frnvg2zn.js → chunk-5hjn2k7k.js} +3 -3
- package/dist/{chunk-fqfhd27m.js → chunk-5q0pv8vm.js} +1 -1
- package/dist/{chunk-s2a06w54.js → chunk-5tscygm0.js} +32 -29
- package/dist/{chunk-q2g2za2r.js → chunk-5vkft7fk.js} +32 -29
- package/dist/{chunk-41qawevz.js → chunk-65nwpf7n.js} +1 -1
- package/dist/{chunk-bp52cyyh.js → chunk-691kttad.js} +32 -29
- package/dist/{chunk-d9y7sf7e.js → chunk-6bsm0zew.js} +36 -33
- package/dist/{chunk-927q4w00.js → chunk-6cj8bg38.js} +40 -38
- package/dist/{chunk-fbkfb5yy.js → chunk-6dfy9qjt.js} +1 -1
- package/dist/{chunk-8k3skcxp.js → chunk-6fbnt5h9.js} +32 -29
- package/dist/{chunk-90vj8x7v.js → chunk-6h9gxb9m.js} +6 -6
- package/dist/{chunk-d4a8wx96.js → chunk-6kr82nrb.js} +32 -29
- package/dist/{chunk-s99sq9ns.js → chunk-6kwx0aa4.js} +32 -29
- package/dist/{chunk-tjntxkt8.js → chunk-6rcfewfp.js} +4 -4
- package/dist/{chunk-ab2ksmbe.js → chunk-6s311f7t.js} +33 -30
- package/dist/{chunk-4e1mxma5.js → chunk-6v12h56j.js} +33 -30
- package/dist/{chunk-y3wg874f.js → chunk-75y4edzf.js} +1 -1
- package/dist/{chunk-r770mj33.js → chunk-7cn3st3a.js} +2 -2
- package/dist/{chunk-sgxttpf4.js → chunk-7rncd7c0.js} +9 -9
- package/dist/{chunk-796j6qp5.js → chunk-813bqtt4.js} +6 -6
- package/dist/{chunk-03spjt6z.js → chunk-819mbp4a.js} +38 -35
- package/dist/{chunk-95qc0qm2.js → chunk-865khv0s.js} +32 -29
- package/dist/{chunk-1q3ht06y.js → chunk-8b70kazk.js} +4 -4
- package/dist/{chunk-aew7yrsf.js → chunk-8czrx8ht.js} +1045 -190
- package/dist/{chunk-69rtrkmf.js → chunk-8epxe23k.js} +3 -3
- package/dist/{chunk-nkz07g41.js → chunk-8fttwfkm.js} +7 -7
- package/dist/chunk-8fw7frqb.js +513 -0
- package/dist/{chunk-4d6ryx98.js → chunk-8k26yg8y.js} +35 -32
- package/dist/{chunk-ht4k8qc2.js → chunk-8rmntsad.js} +32 -29
- package/dist/{chunk-hqsvvf0s.js → chunk-8y6xx3na.js} +35 -32
- package/dist/{chunk-n3r19e7j.js → chunk-8yqnkf9n.js} +1 -1
- package/dist/{chunk-pe5vktd8.js → chunk-8zfdkr9j.js} +32 -29
- package/dist/{chunk-36p752m8.js → chunk-964fpq2b.js} +6 -6
- package/dist/{chunk-en7bhyyg.js → chunk-9aak4pwq.js} +32 -29
- package/dist/{chunk-mmegp36z.js → chunk-9b0yx2w5.js} +40 -37
- package/dist/{chunk-0nae74g7.js → chunk-9b77th8n.js} +2 -2
- package/dist/{chunk-e90spxq9.js → chunk-9f1w8esq.js} +65 -59
- package/dist/{chunk-7aa7tk3e.js → chunk-9frfqse4.js} +1 -1
- package/dist/{chunk-2aqy976t.js → chunk-9r057b2r.js} +8 -6
- package/dist/{chunk-bgbyse6n.js → chunk-9s5zmrvx.js} +38 -35
- package/dist/{chunk-n9pjjkmd.js → chunk-9v303wbj.js} +32 -29
- package/dist/{chunk-76vhxz6d.js → chunk-a9psh500.js} +40 -38
- package/dist/{chunk-k523rbgc.js → chunk-aex4kmfm.js} +1 -1
- package/dist/{chunk-8nq3rcrh.js → chunk-aga3cvg8.js} +32 -29
- package/dist/{chunk-p0mmn00m.js → chunk-apyd6jg3.js} +4 -4
- package/dist/{chunk-8zdrx5jf.js → chunk-avbb5066.js} +1 -1
- package/dist/{chunk-c9f9bxyz.js → chunk-b5hv2cbp.js} +7 -7
- package/dist/chunk-bcfd2zw7.js +20 -0
- package/dist/{chunk-k83gceng.js → chunk-bec4mkst.js} +7 -7
- package/dist/{chunk-18dacfjw.js → chunk-bg0k9ktd.js} +3 -3
- package/dist/{chunk-136cpn7r.js → chunk-bgbp3zkb.js} +39 -36
- package/dist/{chunk-fr9p38bg.js → chunk-bh9dh708.js} +2 -2
- package/dist/chunk-bhdt6k7w.js +15 -0
- package/dist/{chunk-v1sfwgy2.js → chunk-bkafccpc.js} +33 -30
- package/dist/{chunk-behtrnvw.js → chunk-bmpwagz8.js} +34 -31
- package/dist/{chunk-57zs28dc.js → chunk-brg57n5r.js} +9 -9
- package/dist/chunk-bsbmmfyt.js +17 -0
- package/dist/{chunk-zc5b1zt8.js → chunk-bx42jx3q.js} +1 -1
- package/dist/{chunk-5t6qedbx.js → chunk-c0mdv9w6.js} +1 -1
- package/dist/{chunk-aq013trm.js → chunk-c4r8jfrs.js} +33 -30
- package/dist/{chunk-y07sc1z5.js → chunk-c5mxmjvf.js} +32 -29
- package/dist/{chunk-ynywa4qc.js → chunk-c79brdh8.js} +93 -88
- package/dist/{chunk-3t37as7j.js → chunk-cbssxph9.js} +6 -6
- package/dist/{chunk-fjg2v3kn.js → chunk-cd48n5z6.js} +32 -29
- package/dist/{chunk-pp51xf04.js → chunk-ch7hgejq.js} +131 -18
- package/dist/{chunk-dmcepess.js → chunk-ckw2286k.js} +32 -29
- package/dist/{chunk-cqqbkkf0.js → chunk-cp21k6j3.js} +32 -29
- package/dist/{chunk-y2e98987.js → chunk-czk5s0d6.js} +37 -34
- package/dist/chunk-d015m8yn.js +109 -0
- package/dist/chunk-d6qweage.js +112 -0
- package/dist/{chunk-0x2wtgpc.js → chunk-d9fng1q2.js} +2 -2
- package/dist/{chunk-7sn5nw7n.js → chunk-djhtjksq.js} +32 -29
- package/dist/{chunk-94jwe227.js → chunk-dmj8nwb4.js} +1 -1
- package/dist/{chunk-5c6rsxsf.js → chunk-dmk1xmtv.js} +2 -2
- package/dist/{chunk-20k0vm6d.js → chunk-dpwxnzqj.js} +32 -29
- package/dist/{chunk-b4byq7f8.js → chunk-dpzvkxtn.js} +1 -1
- package/dist/{chunk-6er7h0ce.js → chunk-dq4mt605.js} +32 -29
- package/dist/{chunk-gwhnvzbg.js → chunk-dx0wh311.js} +11 -6
- package/dist/{chunk-s5kja2qn.js → chunk-e1f6mcs9.js} +1 -1
- package/dist/{chunk-xt8gvmsx.js → chunk-e1z0nyq5.js} +34 -31
- package/dist/{chunk-8wegtg2m.js → chunk-e6yh7vb2.js} +32 -29
- package/dist/{chunk-axenqvc8.js → chunk-ea7t0b92.js} +1 -1
- package/dist/{chunk-8h43r0g4.js → chunk-ebnp9s5b.js} +1 -1
- package/dist/{chunk-qfr1sn45.js → chunk-ecj9mwz9.js} +4 -4
- package/dist/{chunk-81amwnap.js → chunk-enkmd54m.js} +32 -29
- package/dist/{chunk-vf30axzz.js → chunk-ettyndhe.js} +3 -3
- package/dist/{chunk-w2fv2vbn.js → chunk-ew5daj4s.js} +1 -1
- package/dist/{chunk-ggntxyqw.js → chunk-exg8st0p.js} +3 -3
- package/dist/{chunk-h0rbjg6x.js → chunk-f2mhrmww.js} +8 -1
- package/dist/{chunk-yh01ya6y.js → chunk-fb2ta2tx.js} +32 -29
- package/dist/{chunk-8dmvv3vh.js → chunk-fb7hgch7.js} +33 -30
- package/dist/{chunk-68d95r50.js → chunk-fbt6vctw.js} +6 -6
- package/dist/{chunk-hp4cdr1t.js → chunk-fejedxv7.js} +3 -3
- package/dist/{chunk-fhz29daj.js → chunk-fengsq7f.js} +7 -7
- package/dist/{chunk-ytew4nzj.js → chunk-ftfgv9wc.js} +33 -30
- package/dist/{chunk-rs9c0tp6.js → chunk-fvr6n12m.js} +1 -1
- package/dist/{chunk-mgdpdt82.js → chunk-fytzzgd4.js} +32 -29
- package/dist/{chunk-cy2hswr1.js → chunk-g1k68z1b.js} +1 -1
- package/dist/{chunk-wrbh0cfk.js → chunk-g4wnmj57.js} +1 -1
- package/dist/{chunk-rxtbs7n0.js → chunk-g588xxp7.js} +2 -2
- package/dist/{chunk-axc8en7y.js → chunk-g9tce9xp.js} +43 -40
- package/dist/{chunk-qkxfahwy.js → chunk-gfs9md4a.js} +34 -31
- package/dist/{chunk-v6vnhsk9.js → chunk-gptd9heq.js} +6 -6
- package/dist/{chunk-edyny263.js → chunk-grvhbg1q.js} +2 -2
- package/dist/{chunk-szcsdmpv.js → chunk-gwkgfkj5.js} +10 -10
- package/dist/{chunk-ys9yeb7q.js → chunk-h1qt9p3c.js} +32 -29
- package/dist/{chunk-5y175yzc.js → chunk-h2mr7m2a.js} +4 -4
- package/dist/{chunk-eqt6c9hn.js → chunk-h2ywbfms.js} +22 -18
- package/dist/{chunk-xpk6dapv.js → chunk-h6hh3va9.js} +7 -7
- package/dist/{chunk-vrt7c6k9.js → chunk-h83fz0gd.js} +33 -30
- package/dist/{chunk-1nxqqjjt.js → chunk-hbeg1qyg.js} +33 -30
- package/dist/chunk-hhwwyqt1.js +194 -0
- package/dist/{chunk-4qenyk9g.js → chunk-hn3hk8tc.js} +7 -7
- package/dist/chunk-j1x3ns18.js +183 -0
- package/dist/{chunk-bxecxvr6.js → chunk-j52vz59d.js} +33 -30
- package/dist/{chunk-3j2q2rdk.js → chunk-j66ffy26.js} +18 -18
- package/dist/{chunk-140880hg.js → chunk-j84jdj7r.js} +7 -7
- package/dist/{chunk-jhq4q5mx.js → chunk-jebb8j1d.js} +33 -30
- package/dist/{chunk-3gx9gg4n.js → chunk-jf3995b3.js} +252 -151
- package/dist/{chunk-385yn056.js → chunk-jff3fbst.js} +136 -241
- package/dist/{chunk-1cvzdf3f.js → chunk-jgf7597r.js} +38 -35
- package/dist/{chunk-p6zb606e.js → chunk-jk1arbw0.js} +6 -6
- package/dist/{chunk-c7vjkt02.js → chunk-jnhp78c8.js} +1 -1
- package/dist/{chunk-0x6bwqtj.js → chunk-jpk1syr5.js} +36 -33
- package/dist/{chunk-skd3bkmx.js → chunk-jqr257x5.js} +95 -90
- package/dist/{chunk-4n8p6kj0.js → chunk-k1af22na.js} +6 -6
- package/dist/{chunk-4g82v54s.js → chunk-k384qakk.js} +32 -29
- package/dist/{chunk-padnh4m8.js → chunk-k3eb60ct.js} +1 -1
- package/dist/{chunk-5smyhzmn.js → chunk-k3p4x944.js} +1 -1
- package/dist/{chunk-mxezad7a.js → chunk-k4zz5qt6.js} +35 -32
- package/dist/{chunk-dyaf8e7s.js → chunk-k7qcpvdq.js} +34 -31
- package/dist/{chunk-957q89kn.js → chunk-k80dnb78.js} +11 -11
- package/dist/{chunk-8zy4rsnp.js → chunk-kgj9893t.js} +33 -30
- package/dist/{chunk-x5k1etjx.js → chunk-kksbjtad.js} +1 -1
- package/dist/{chunk-fh1ax1cg.js → chunk-krcxgtkq.js} +35 -32
- package/dist/{chunk-qppzesmk.js → chunk-kw1hpgh9.js} +1 -1
- package/dist/chunk-kzhw03m7.js +242 -0
- package/dist/chunk-m41d561t.js +115 -0
- package/dist/{chunk-8mt5w0hv.js → chunk-m4sp7ycd.js} +2 -2
- package/dist/{chunk-qgtt30h3.js → chunk-m737wsqq.js} +4 -4
- package/dist/{chunk-yg5r52h3.js → chunk-m7m8tbj3.js} +2 -2
- package/dist/{chunk-r5eka7tm.js → chunk-m9e7stwq.js} +4 -4
- package/dist/{chunk-0w7nszy9.js → chunk-mcyyqkv6.js} +4 -82
- package/dist/{chunk-bnsgd143.js → chunk-mday155d.js} +5 -5
- package/dist/{chunk-yhpxy5st.js → chunk-mk7e37ps.js} +35 -32
- package/dist/{chunk-d3kt34ew.js → chunk-mmn3cbyd.js} +32 -29
- package/dist/{chunk-c7t69jmn.js → chunk-mqvvd1sy.js} +1 -1
- package/dist/{chunk-30qe8vg5.js → chunk-n0y737n2.js} +42 -39
- package/dist/{chunk-d161bz6z.js → chunk-n1hc1e25.js} +32 -29
- package/dist/{chunk-nm2nptw1.js → chunk-n7gcwz03.js} +16 -16
- package/dist/{chunk-anw7kmsz.js → chunk-ndbcx9we.js} +11 -11
- package/dist/{chunk-057p2c7q.js → chunk-ng8k4ywf.js} +40 -37
- package/dist/{chunk-d127m8zb.js → chunk-nh76pgrt.js} +2 -2
- package/dist/{chunk-1re18c21.js → chunk-nnjw47pz.js} +7 -7
- package/dist/{chunk-af58qhb4.js → chunk-nt3r80s6.js} +35 -32
- package/dist/{chunk-q180111z.js → chunk-nwrtz4yt.js} +1 -1
- package/dist/{chunk-x8s2ysqw.js → chunk-nxa79974.js} +3 -3
- package/dist/{chunk-6xbff4vx.js → chunk-nzpww4n5.js} +1 -1
- package/dist/{chunk-wfmkfs38.js → chunk-p12z0hqk.js} +1 -1
- package/dist/{chunk-3dnzff6j.js → chunk-p6q6twct.js} +7 -7
- package/dist/{chunk-w3h4a3kh.js → chunk-p814dt75.js} +3008 -1038
- package/dist/chunk-pj0866mn.js +196 -0
- package/dist/{chunk-p466g3q9.js → chunk-pjmqey38.js} +1 -1
- package/dist/{chunk-fckykghd.js → chunk-pjms1h2b.js} +2 -2
- package/dist/{chunk-f5h4mxdx.js → chunk-pkm2nhk9.js} +3 -3
- package/dist/{chunk-vg3exmen.js → chunk-pp147tk2.js} +32 -29
- package/dist/{chunk-0m3cqq85.js → chunk-pyb8mk8k.js} +4 -4
- package/dist/{chunk-m8j8f4rm.js → chunk-q33kdbcv.js} +35 -32
- package/dist/{chunk-bhp62x16.js → chunk-q80ddpch.js} +7 -7
- package/dist/chunk-qbaszyg6.js +133 -0
- package/dist/{chunk-6kpbgc5w.js → chunk-qbrsmra3.js} +1 -1
- package/dist/{chunk-7zj334zr.js → chunk-qdx64b6y.js} +7 -7
- package/dist/{chunk-d6ytdgha.js → chunk-qjxk8wrn.js} +2 -2
- package/dist/{chunk-cwbdfjp9.js → chunk-qq72x3fs.js} +4 -4
- package/dist/{chunk-vk9rhhqy.js → chunk-qx67chz8.js} +1 -1
- package/dist/{chunk-gss0qg24.js → chunk-qyeh87q9.js} +33 -30
- package/dist/{chunk-n7e9fm08.js → chunk-r71sjhpf.js} +32 -29
- package/dist/{chunk-d68resa3.js → chunk-r7n5brf9.js} +16 -16
- package/dist/chunk-rbfe062s.js +67 -0
- package/dist/{chunk-jzj3p696.js → chunk-rde4wtp8.js} +2 -2
- package/dist/{chunk-k7aebzb7.js → chunk-rmb338tt.js} +29 -29
- package/dist/{chunk-r2e2d9te.js → chunk-rwz2d4a6.js} +33 -30
- package/dist/{chunk-ve35wfqa.js → chunk-ry4ct8z8.js} +1 -1
- package/dist/{chunk-vrpq3d3m.js → chunk-s0d48jma.js} +1 -1
- package/dist/{chunk-sg1qd2yq.js → chunk-s0f9h1ke.js} +33 -30
- package/dist/{chunk-daycsk4d.js → chunk-s2t3qrte.js} +1 -1
- package/dist/{chunk-jjj6rejt.js → chunk-s8atpq1r.js} +32 -29
- package/dist/chunk-sf0ay82k.js +120 -0
- package/dist/{chunk-5tf3y2x4.js → chunk-sfmxv59p.js} +10 -10
- package/dist/chunk-sfqs55dz.js +79 -0
- package/dist/{chunk-sz611c7y.js → chunk-smf3xf1p.js} +33 -30
- package/dist/{chunk-3zzgpj8d.js → chunk-spbanbyj.js} +7 -7
- package/dist/{chunk-1t58cm9p.js → chunk-sstfswx9.js} +10 -10
- package/dist/chunk-sxaedgmw.js +94 -0
- package/dist/chunk-sznnpxg3.js +72 -0
- package/dist/{chunk-bnnfby0p.js → chunk-t0644p95.js} +32 -29
- package/dist/{chunk-m6h8sefk.js → chunk-t6w2xwm7.js} +32 -29
- package/dist/{chunk-2tahgz0j.js → chunk-tc1yyeaa.js} +32 -4
- package/dist/{chunk-d6pvxq4t.js → chunk-tj45shek.js} +1 -1
- package/dist/{chunk-3ayj5sjm.js → chunk-tjqcyj2x.js} +2 -2
- package/dist/{chunk-0ks6dz1s.js → chunk-tmmjr5ta.js} +4 -4
- package/dist/{chunk-wqmpewdd.js → chunk-tp7b8ek9.js} +4 -4
- package/dist/{chunk-dgz6h4qd.js → chunk-trj0ahk0.js} +3 -3
- package/dist/{chunk-ytrefhw5.js → chunk-tsd9qae1.js} +1 -1
- package/dist/{chunk-bcqk9yw1.js → chunk-tv7hgcvj.js} +33 -30
- package/dist/{chunk-xr75ftr6.js → chunk-twmgrmfw.js} +1 -1
- package/dist/{chunk-vqsjg97m.js → chunk-tzqx43zc.js} +32 -29
- package/dist/{chunk-nt2esar1.js → chunk-v30g8yjp.js} +1 -1
- package/dist/{chunk-yzggptj9.js → chunk-vcctr6md.js} +32 -29
- package/dist/{chunk-kntspztd.js → chunk-vk6s7hsj.js} +4 -4
- package/dist/{chunk-fy965myk.js → chunk-vnkmsvcm.js} +1 -1
- package/dist/{chunk-wf0tb0v2.js → chunk-vrq6n6h1.js} +2 -2
- package/dist/{chunk-hmx6fwqe.js → chunk-vs6r3az0.js} +34 -31
- package/dist/{chunk-wvc46bgr.js → chunk-w0hw971e.js} +6 -6
- package/dist/{chunk-7290d32y.js → chunk-w375z6hb.js} +33 -30
- package/dist/{chunk-vqtate03.js → chunk-w6k4bxas.js} +7 -7
- package/dist/{chunk-zpr7s3f8.js → chunk-wbv06vv2.js} +4 -4
- package/dist/chunk-wdz993z8.js +131 -0
- package/dist/{chunk-ckan2z85.js → chunk-wgwhgb0q.js} +7 -7
- package/dist/{chunk-r5jmfhb0.js → chunk-wkxg48gk.js} +33 -30
- package/dist/{chunk-zzv0m6zw.js → chunk-wny26e8e.js} +10 -10
- package/dist/{chunk-9ceyr5ed.js → chunk-wpcgztry.js} +5 -5
- package/dist/{chunk-pjvrckqq.js → chunk-wsx9nt4e.js} +8 -8
- package/dist/{chunk-4t38jjwb.js → chunk-wvac5hhg.js} +7 -7
- package/dist/{chunk-s72mp5r4.js → chunk-wx1f33e7.js} +38 -35
- package/dist/{chunk-xcx7yh0e.js → chunk-x6v6emh0.js} +2 -2
- package/dist/{chunk-mb0j3qcs.js → chunk-xdrgnnrx.js} +35 -32
- package/dist/{chunk-wtmv0phz.js → chunk-xmh281bd.js} +33 -30
- package/dist/{chunk-12yafvjz.js → chunk-xnakns4w.js} +32 -29
- package/dist/{chunk-f081fc9h.js → chunk-xthpe23e.js} +46 -43
- package/dist/{chunk-vyemja4g.js → chunk-xx1p336b.js} +2 -2
- package/dist/{chunk-p5fg24e5.js → chunk-xxdk3d0d.js} +2 -2
- package/dist/{chunk-nrnctdca.js → chunk-y413jeq2.js} +32 -29
- package/dist/{chunk-c965t34b.js → chunk-y49d81am.js} +44 -41
- package/dist/{chunk-yvypnga9.js → chunk-y6f7kmzf.js} +32 -29
- package/dist/{chunk-1d39h7zf.js → chunk-y9zmxrg1.js} +1 -1
- package/dist/{chunk-ermp1abj.js → chunk-yamdfram.js} +36 -33
- package/dist/{chunk-bvvnv69h.js → chunk-yefearm8.js} +2 -2
- package/dist/{chunk-w78h4cpg.js → chunk-ygc38zsc.js} +32 -29
- package/dist/{chunk-x03eqvrv.js → chunk-yt46a969.js} +1 -1
- package/dist/{chunk-ptkr15ng.js → chunk-z3hw83qk.js} +34 -31
- package/dist/{chunk-x1ja2cne.js → chunk-z7dv1v7n.js} +9 -9
- package/dist/chunk-zcn4zxbj.js +142 -0
- package/dist/{chunk-rvt67hgh.js → chunk-zftb15xp.js} +34 -31
- package/dist/{chunk-bx1aj5va.js → chunk-zj3en2ka.js} +35 -32
- package/dist/{chunk-37gp1zzs.js → chunk-zm12zvc2.js} +35 -32
- package/dist/{chunk-25c7xvcj.js → chunk-zt4jjf59.js} +6 -6
- package/dist/{chunk-95t31nbm.js → chunk-ztb7kzx4.js} +34 -31
- package/dist/{chunk-f4cbehwk.js → chunk-zypp6syd.js} +32 -29
- package/dist/cli.js +44 -16
- package/package.json +1 -1
- package/dist/chunk-0paqc2yw.js +0 -15
- package/dist/chunk-51a8mdyr.js +0 -46
- package/dist/chunk-r4sr5fcm.js +0 -93
- package/dist/{chunk-0spb0sqd.js → chunk-6gg2cvm2.js} +3 -3
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createCapacityWake
|
|
4
4
|
} from "./chunk-ae76ded0.js";
|
|
5
|
+
import {
|
|
6
|
+
getPollIntervalConfig
|
|
7
|
+
} from "./chunk-5q0pv8vm.js";
|
|
5
8
|
import {
|
|
6
9
|
buildCCRv2SdkUrl,
|
|
7
10
|
buildSdkUrl,
|
|
@@ -9,164 +12,103 @@ import {
|
|
|
9
12
|
registerWorker,
|
|
10
13
|
sameSessionId
|
|
11
14
|
} from "./chunk-2m6jk78c.js";
|
|
12
|
-
import {
|
|
13
|
-
getPollIntervalConfig
|
|
14
|
-
} from "./chunk-fqfhd27m.js";
|
|
15
15
|
import {
|
|
16
16
|
createTokenRefreshScheduler
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-kw1hpgh9.js";
|
|
18
18
|
import {
|
|
19
19
|
getBootstrapArgs,
|
|
20
20
|
getScriptPath,
|
|
21
21
|
init_cliLaunch
|
|
22
22
|
} from "./chunk-w669wpk5.js";
|
|
23
23
|
import {
|
|
24
|
+
$toString,
|
|
24
25
|
init_server
|
|
25
26
|
} from "./chunk-jdgeec04.js";
|
|
26
27
|
import {
|
|
27
|
-
BRIDGE_LOGIN_ERROR,
|
|
28
28
|
BridgeFatalError,
|
|
29
|
-
|
|
29
|
+
FAILED_FOOTER_TEXT,
|
|
30
|
+
TOOL_DISPLAY_EXPIRY_MS,
|
|
31
|
+
buildActiveFooterText,
|
|
32
|
+
buildBridgeConnectUrl,
|
|
33
|
+
buildBridgeSessionUrl,
|
|
34
|
+
buildIdleFooterText,
|
|
30
35
|
createAgentWorktree,
|
|
31
36
|
createBridgeApiClient,
|
|
32
37
|
getRemoteSessionUrl,
|
|
33
38
|
init_bridgeApi,
|
|
34
39
|
init_bridgeStatusUtil,
|
|
35
40
|
init_product,
|
|
36
|
-
init_types4 as init_types,
|
|
37
41
|
init_worktree,
|
|
38
42
|
isExpiredErrorType,
|
|
39
43
|
isSuppressible403,
|
|
40
44
|
removeAgentWorktree,
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
timestamp,
|
|
46
|
+
validateBridgeId,
|
|
47
|
+
wrapWithOsc8Link
|
|
48
|
+
} from "./chunk-p814dt75.js";
|
|
43
49
|
import {
|
|
44
50
|
init_rcDebugLog,
|
|
45
51
|
rcLog
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import"./chunk-x5k1etjx.js";
|
|
48
|
-
import"./chunk-qe3qr56q.js";
|
|
52
|
+
} from "./chunk-rmb338tt.js";
|
|
49
53
|
import {
|
|
50
54
|
getTrustedDeviceToken,
|
|
51
55
|
init_trustedDevice
|
|
52
|
-
} from "./chunk-
|
|
53
|
-
import
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
import"./chunk-ehtwnxpg.js";
|
|
59
|
-
import"./chunk-wf0tb0v2.js";
|
|
60
|
-
import"./chunk-ytrefhw5.js";
|
|
61
|
-
import"./chunk-cgfdkzhb.js";
|
|
62
|
-
import"./chunk-2f6hs25r.js";
|
|
63
|
-
import"./chunk-dpzdk73b.js";
|
|
64
|
-
import"./chunk-6qj1adtm.js";
|
|
65
|
-
import"./chunk-d6v6abvy.js";
|
|
66
|
-
import"./chunk-d127m8zb.js";
|
|
67
|
-
import"./chunk-zttmdag3.js";
|
|
68
|
-
import"./chunk-8zdrx5jf.js";
|
|
69
|
-
import"./chunk-p5816r2t.js";
|
|
70
|
-
import"./chunk-ps49ymvj.js";
|
|
56
|
+
} from "./chunk-1nkqjw8f.js";
|
|
57
|
+
import {
|
|
58
|
+
BRIDGE_LOGIN_ERROR,
|
|
59
|
+
DEFAULT_SESSION_TIMEOUT_MS,
|
|
60
|
+
init_types
|
|
61
|
+
} from "./chunk-bhdt6k7w.js";
|
|
71
62
|
import {
|
|
72
63
|
debugTruncate,
|
|
73
64
|
describeAxiosError,
|
|
74
65
|
init_debugUtils,
|
|
75
66
|
init_sessionIdCompat,
|
|
76
|
-
toCompatSessionId
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
import"./chunk-t4kcvmes.js";
|
|
80
|
-
import"./chunk-padnh4m8.js";
|
|
81
|
-
import"./chunk-41qawevz.js";
|
|
82
|
-
import"./chunk-cy1z66c2.js";
|
|
83
|
-
import"./chunk-v134wa9t.js";
|
|
84
|
-
import"./chunk-3twcp74a.js";
|
|
85
|
-
import"./chunk-4jm600zv.js";
|
|
86
|
-
import"./chunk-5t6qedbx.js";
|
|
87
|
-
import"./chunk-3xzcr9ha.js";
|
|
88
|
-
import"./chunk-rkmwx1yz.js";
|
|
89
|
-
import"./chunk-k523rbgc.js";
|
|
90
|
-
import"./chunk-ykr5qx9v.js";
|
|
91
|
-
import"./chunk-d6pvxq4t.js";
|
|
92
|
-
import"./chunk-nt2esar1.js";
|
|
67
|
+
toCompatSessionId,
|
|
68
|
+
toInfraSessionId
|
|
69
|
+
} from "./chunk-0cshr8vt.js";
|
|
93
70
|
import {
|
|
94
|
-
init_datadog
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
import"./chunk-ad6rg8vz.js";
|
|
98
|
-
import"./chunk-x95fhbwq.js";
|
|
71
|
+
init_datadog,
|
|
72
|
+
shutdownDatadog
|
|
73
|
+
} from "./chunk-k3p4x944.js";
|
|
99
74
|
import {
|
|
100
|
-
|
|
101
|
-
|
|
75
|
+
BRIDGE_FAILED_INDICATOR,
|
|
76
|
+
BRIDGE_READY_INDICATOR,
|
|
77
|
+
BRIDGE_SPINNER_FRAMES,
|
|
78
|
+
checkGate_CACHED_OR_BLOCKING,
|
|
102
79
|
init_figures,
|
|
103
80
|
init_firstPartyEventLogger,
|
|
104
|
-
init_growthbook
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
import"./chunk-0spb0sqd.js";
|
|
108
|
-
import"./chunk-zwarn9h7.js";
|
|
109
|
-
import"./chunk-hxc8e6wd.js";
|
|
110
|
-
import"./chunk-7hmy36fh.js";
|
|
111
|
-
import"./chunk-6kpbgc5w.js";
|
|
112
|
-
import"./chunk-xpsb3jm8.js";
|
|
113
|
-
import"./chunk-64c1avct.js";
|
|
114
|
-
import"./chunk-pjz4m7pd.js";
|
|
81
|
+
init_growthbook,
|
|
82
|
+
shutdown1PEventLogging
|
|
83
|
+
} from "./chunk-ch7hgejq.js";
|
|
115
84
|
import {
|
|
116
85
|
init_sleep,
|
|
117
86
|
sleep
|
|
118
87
|
} from "./chunk-8g5pe1gr.js";
|
|
119
|
-
import"./chunk-zvdc0eh1.js";
|
|
120
|
-
import"./chunk-4cp6193g.js";
|
|
121
|
-
import"./chunk-8g747a8x.js";
|
|
122
|
-
import"./chunk-d7886r6a.js";
|
|
123
|
-
import"./chunk-90wp6wez.js";
|
|
124
|
-
import"./chunk-a8ejc632.js";
|
|
125
|
-
import"./chunk-f5ma3nh5.js";
|
|
126
|
-
import"./chunk-qz2x630m.js";
|
|
127
|
-
import"./chunk-c7t69jmn.js";
|
|
128
|
-
import"./chunk-6y2wszkc.js";
|
|
129
|
-
import"./chunk-3c25bcsw.js";
|
|
130
|
-
import"./chunk-9qh5f9r3.js";
|
|
131
|
-
import"./chunk-xhesahm0.js";
|
|
132
|
-
import"./chunk-rh5a2rg9.js";
|
|
133
|
-
import"./chunk-p2816w9z.js";
|
|
134
|
-
import"./chunk-v9smspw2.js";
|
|
135
|
-
import"./chunk-v1kzp02e.js";
|
|
136
88
|
import {
|
|
137
89
|
formatDuration,
|
|
138
90
|
init_format,
|
|
139
91
|
truncateToWidth
|
|
140
|
-
} from "./chunk-
|
|
141
|
-
import"./chunk-crmjpsqe.js";
|
|
92
|
+
} from "./chunk-ea7t0b92.js";
|
|
142
93
|
import {
|
|
143
|
-
|
|
94
|
+
init_source,
|
|
95
|
+
init_src,
|
|
96
|
+
source_default,
|
|
97
|
+
stringWidth
|
|
144
98
|
} from "./chunk-m9w972ny.js";
|
|
145
|
-
import"./chunk-b5wxetbv.js";
|
|
146
99
|
import {
|
|
147
100
|
init_analytics,
|
|
148
|
-
logEvent
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
import"./chunk-0xjaqda8.js";
|
|
152
|
-
import"./chunk-trt2sfjg.js";
|
|
101
|
+
logEvent,
|
|
102
|
+
logEventAsync
|
|
103
|
+
} from "./chunk-f2mhrmww.js";
|
|
153
104
|
import {
|
|
154
105
|
init_diagLogs,
|
|
155
106
|
logForDiagnosticsNoPII
|
|
156
107
|
} from "./chunk-73pxnrgv.js";
|
|
157
|
-
import"./chunk-5aw4k8fc.js";
|
|
158
|
-
import"./chunk-zs5b1dgr.js";
|
|
159
|
-
import"./chunk-99zt59gg.js";
|
|
160
|
-
import"./chunk-tv74hgw9.js";
|
|
161
108
|
import {
|
|
162
109
|
init_log,
|
|
163
110
|
logError
|
|
164
111
|
} from "./chunk-vp2p7azg.js";
|
|
165
|
-
import"./chunk-8tnsngw2.js";
|
|
166
|
-
import"./chunk-vsbyhpfy.js";
|
|
167
|
-
import"./chunk-p7pj6wf8.js";
|
|
168
|
-
import"./chunk-5z28bqne.js";
|
|
169
|
-
import"./chunk-qajrkk97.js";
|
|
170
112
|
import {
|
|
171
113
|
errorMessage,
|
|
172
114
|
init_debug,
|
|
@@ -176,28 +118,15 @@ import {
|
|
|
176
118
|
jsonStringify,
|
|
177
119
|
logForDebugging
|
|
178
120
|
} from "./chunk-5khwvj1z.js";
|
|
179
|
-
import"./chunk-fbv4apne.js";
|
|
180
|
-
import"./chunk-gzp6rza1.js";
|
|
181
|
-
import"./chunk-50dgek10.js";
|
|
182
|
-
import"./chunk-7wm5s02e.js";
|
|
183
|
-
import"./chunk-z0csm2zq.js";
|
|
184
121
|
import {
|
|
185
122
|
init_envUtils,
|
|
186
123
|
isEnvTruthy,
|
|
187
124
|
isInProtectedNamespace
|
|
188
125
|
} from "./chunk-hxhwzgnn.js";
|
|
189
|
-
import"./chunk-qx8z601m.js";
|
|
190
|
-
import"./chunk-cgm6758j.js";
|
|
191
|
-
import"./chunk-9m27g5s1.js";
|
|
192
|
-
import"./chunk-8pn8tvgg.js";
|
|
193
|
-
import"./chunk-netzwgv1.js";
|
|
194
126
|
import {
|
|
195
127
|
__require
|
|
196
128
|
} from "./chunk-qp2qdcda.js";
|
|
197
129
|
|
|
198
|
-
// src/daemon/workerRegistry.ts
|
|
199
|
-
import { resolve as resolve2 } from "path";
|
|
200
|
-
|
|
201
130
|
// src/bridge/bridgeMain.ts
|
|
202
131
|
init_product();
|
|
203
132
|
init_datadog();
|
|
@@ -221,11 +150,366 @@ import { hostname, tmpdir as tmpdir2 } from "os";
|
|
|
221
150
|
import { basename, join as join2, resolve } from "path";
|
|
222
151
|
|
|
223
152
|
// src/bridge/bridgeUI.ts
|
|
153
|
+
init_source();
|
|
224
154
|
init_server();
|
|
225
155
|
init_figures();
|
|
226
156
|
init_src();
|
|
227
157
|
init_debug();
|
|
228
158
|
init_bridgeStatusUtil();
|
|
159
|
+
var QR_OPTIONS = {
|
|
160
|
+
type: "utf8",
|
|
161
|
+
errorCorrectionLevel: "L",
|
|
162
|
+
small: true
|
|
163
|
+
};
|
|
164
|
+
async function generateQr(url) {
|
|
165
|
+
const qr = await $toString(url, QR_OPTIONS);
|
|
166
|
+
return qr.split(`
|
|
167
|
+
`).filter((line) => line.length > 0);
|
|
168
|
+
}
|
|
169
|
+
function createBridgeLogger(options) {
|
|
170
|
+
const write = options.write ?? ((s) => process.stdout.write(s));
|
|
171
|
+
const verbose = options.verbose;
|
|
172
|
+
let statusLineCount = 0;
|
|
173
|
+
let currentState = "idle";
|
|
174
|
+
let currentStateText = "Ready";
|
|
175
|
+
let repoName = "";
|
|
176
|
+
let branch = "";
|
|
177
|
+
let debugLogPath = "";
|
|
178
|
+
let connectUrl = "";
|
|
179
|
+
let cachedIngressUrl = "";
|
|
180
|
+
let cachedEnvironmentId = "";
|
|
181
|
+
let activeSessionUrl = null;
|
|
182
|
+
let qrLines = [];
|
|
183
|
+
let qrVisible = false;
|
|
184
|
+
let lastToolSummary = null;
|
|
185
|
+
let lastToolTime = 0;
|
|
186
|
+
let sessionActive = 0;
|
|
187
|
+
let sessionMax = 1;
|
|
188
|
+
let spawnModeDisplay = null;
|
|
189
|
+
let spawnMode = "single-session";
|
|
190
|
+
const sessionDisplayInfo = new Map;
|
|
191
|
+
let connectingTimer = null;
|
|
192
|
+
let connectingTick = 0;
|
|
193
|
+
function countVisualLines(text) {
|
|
194
|
+
const cols = process.stdout.columns || 80;
|
|
195
|
+
let count = 0;
|
|
196
|
+
for (const logical of text.split(`
|
|
197
|
+
`)) {
|
|
198
|
+
if (logical.length === 0) {
|
|
199
|
+
count++;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const width = stringWidth(logical);
|
|
203
|
+
count += Math.max(1, Math.ceil(width / cols));
|
|
204
|
+
}
|
|
205
|
+
if (text.endsWith(`
|
|
206
|
+
`)) {
|
|
207
|
+
count--;
|
|
208
|
+
}
|
|
209
|
+
return count;
|
|
210
|
+
}
|
|
211
|
+
function writeStatus(text) {
|
|
212
|
+
write(text);
|
|
213
|
+
statusLineCount += countVisualLines(text);
|
|
214
|
+
}
|
|
215
|
+
function clearStatusLines() {
|
|
216
|
+
if (statusLineCount <= 0)
|
|
217
|
+
return;
|
|
218
|
+
logForDebugging(`[bridge:ui] clearStatusLines count=${statusLineCount}`);
|
|
219
|
+
write(`\x1B[${statusLineCount}A`);
|
|
220
|
+
write("\x1B[J");
|
|
221
|
+
statusLineCount = 0;
|
|
222
|
+
}
|
|
223
|
+
function printLog(line) {
|
|
224
|
+
clearStatusLines();
|
|
225
|
+
write(line);
|
|
226
|
+
}
|
|
227
|
+
function regenerateQr(url) {
|
|
228
|
+
generateQr(url).then((lines) => {
|
|
229
|
+
qrLines = lines;
|
|
230
|
+
renderStatusLine();
|
|
231
|
+
}).catch((e) => {
|
|
232
|
+
logForDebugging(`QR code generation failed: ${e}`, { level: "error" });
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function renderConnectingLine() {
|
|
236
|
+
clearStatusLines();
|
|
237
|
+
const frame = BRIDGE_SPINNER_FRAMES[connectingTick % BRIDGE_SPINNER_FRAMES.length];
|
|
238
|
+
let suffix = "";
|
|
239
|
+
if (repoName) {
|
|
240
|
+
suffix += source_default.dim(" \xB7 ") + source_default.dim(repoName);
|
|
241
|
+
}
|
|
242
|
+
if (branch) {
|
|
243
|
+
suffix += source_default.dim(" \xB7 ") + source_default.dim(branch);
|
|
244
|
+
}
|
|
245
|
+
writeStatus(`${source_default.yellow(frame)} ${source_default.yellow("Connecting")}${suffix}
|
|
246
|
+
`);
|
|
247
|
+
}
|
|
248
|
+
function startConnecting() {
|
|
249
|
+
stopConnecting();
|
|
250
|
+
renderConnectingLine();
|
|
251
|
+
connectingTimer = setInterval(() => {
|
|
252
|
+
connectingTick++;
|
|
253
|
+
renderConnectingLine();
|
|
254
|
+
}, 150);
|
|
255
|
+
}
|
|
256
|
+
function stopConnecting() {
|
|
257
|
+
if (connectingTimer) {
|
|
258
|
+
clearInterval(connectingTimer);
|
|
259
|
+
connectingTimer = null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function renderStatusLine() {
|
|
263
|
+
if (currentState === "reconnecting" || currentState === "failed") {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
clearStatusLines();
|
|
267
|
+
const isIdle = currentState === "idle";
|
|
268
|
+
if (qrVisible) {
|
|
269
|
+
for (const line of qrLines) {
|
|
270
|
+
writeStatus(`${source_default.dim(line)}
|
|
271
|
+
`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const indicator = BRIDGE_READY_INDICATOR;
|
|
275
|
+
const indicatorColor = isIdle ? source_default.green : source_default.cyan;
|
|
276
|
+
const baseColor = isIdle ? source_default.green : source_default.cyan;
|
|
277
|
+
const stateText = baseColor(currentStateText);
|
|
278
|
+
let suffix = "";
|
|
279
|
+
if (repoName) {
|
|
280
|
+
suffix += source_default.dim(" \xB7 ") + source_default.dim(repoName);
|
|
281
|
+
}
|
|
282
|
+
if (branch && spawnMode !== "worktree") {
|
|
283
|
+
suffix += source_default.dim(" \xB7 ") + source_default.dim(branch);
|
|
284
|
+
}
|
|
285
|
+
if (process.env.USER_TYPE === "ant" && debugLogPath) {
|
|
286
|
+
writeStatus(`${source_default.yellow("[ANT-ONLY] Logs:")} ${source_default.dim(debugLogPath)}
|
|
287
|
+
`);
|
|
288
|
+
}
|
|
289
|
+
writeStatus(`${indicatorColor(indicator)} ${stateText}${suffix}
|
|
290
|
+
`);
|
|
291
|
+
if (sessionMax > 1) {
|
|
292
|
+
const modeHint = spawnMode === "worktree" ? "New sessions will be created in an isolated worktree" : "New sessions will be created in the current directory";
|
|
293
|
+
writeStatus(` ${source_default.dim(`Capacity: ${sessionActive}/${sessionMax} \xB7 ${modeHint}`)}
|
|
294
|
+
`);
|
|
295
|
+
for (const [, info] of sessionDisplayInfo) {
|
|
296
|
+
const titleText = info.title ? truncateToWidth(info.title, 35) : source_default.dim("Attached");
|
|
297
|
+
const titleLinked = wrapWithOsc8Link(titleText, info.url);
|
|
298
|
+
const act = info.activity;
|
|
299
|
+
const showAct = act && act.type !== "result" && act.type !== "error";
|
|
300
|
+
const actText = showAct ? source_default.dim(` ${truncateToWidth(act.summary, 40)}`) : "";
|
|
301
|
+
writeStatus(` ${titleLinked}${actText}
|
|
302
|
+
`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (sessionMax === 1) {
|
|
306
|
+
const modeText = spawnMode === "single-session" ? "Single session \xB7 exits when complete" : spawnMode === "worktree" ? `Capacity: ${sessionActive}/1 \xB7 New sessions will be created in an isolated worktree` : `Capacity: ${sessionActive}/1 \xB7 New sessions will be created in the current directory`;
|
|
307
|
+
writeStatus(` ${source_default.dim(modeText)}
|
|
308
|
+
`);
|
|
309
|
+
}
|
|
310
|
+
if (sessionMax === 1 && !isIdle && lastToolSummary && Date.now() - lastToolTime < TOOL_DISPLAY_EXPIRY_MS) {
|
|
311
|
+
writeStatus(` ${source_default.dim(truncateToWidth(lastToolSummary, 60))}
|
|
312
|
+
`);
|
|
313
|
+
}
|
|
314
|
+
const url = activeSessionUrl ?? connectUrl;
|
|
315
|
+
if (url) {
|
|
316
|
+
writeStatus(`
|
|
317
|
+
`);
|
|
318
|
+
const footerText = isIdle ? buildIdleFooterText(url) : buildActiveFooterText(url);
|
|
319
|
+
const qrHint = qrVisible ? source_default.dim.italic("space to hide QR code") : source_default.dim.italic("space to show QR code");
|
|
320
|
+
const toggleHint = spawnModeDisplay ? source_default.dim.italic(" \xB7 w to toggle spawn mode") : "";
|
|
321
|
+
writeStatus(`${source_default.dim(footerText)}
|
|
322
|
+
`);
|
|
323
|
+
writeStatus(`${qrHint}${toggleHint}
|
|
324
|
+
`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
printBanner(config, environmentId) {
|
|
329
|
+
cachedIngressUrl = config.sessionIngressUrl;
|
|
330
|
+
cachedEnvironmentId = environmentId;
|
|
331
|
+
connectUrl = buildBridgeConnectUrl(environmentId, cachedIngressUrl);
|
|
332
|
+
regenerateQr(connectUrl);
|
|
333
|
+
if (verbose) {
|
|
334
|
+
write(source_default.dim(`Remote Control`) + ` v${"2.1.888"}
|
|
335
|
+
`);
|
|
336
|
+
}
|
|
337
|
+
if (verbose) {
|
|
338
|
+
if (config.spawnMode !== "single-session") {
|
|
339
|
+
write(source_default.dim(`Spawn mode: `) + `${config.spawnMode}
|
|
340
|
+
`);
|
|
341
|
+
write(source_default.dim(`Max concurrent sessions: `) + `${config.maxSessions}
|
|
342
|
+
`);
|
|
343
|
+
}
|
|
344
|
+
write(source_default.dim(`Environment ID: `) + `${environmentId}
|
|
345
|
+
`);
|
|
346
|
+
}
|
|
347
|
+
if (config.sandbox) {
|
|
348
|
+
write(source_default.dim(`Sandbox: `) + `${source_default.green("Enabled")}
|
|
349
|
+
`);
|
|
350
|
+
}
|
|
351
|
+
write(`
|
|
352
|
+
`);
|
|
353
|
+
startConnecting();
|
|
354
|
+
},
|
|
355
|
+
logSessionStart(sessionId, prompt) {
|
|
356
|
+
if (verbose) {
|
|
357
|
+
const short = truncateToWidth(prompt, 80);
|
|
358
|
+
printLog(source_default.dim(`[${timestamp()}]`) + ` Session started: ${source_default.white(`"${short}"`)} (${source_default.dim(sessionId)})
|
|
359
|
+
`);
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
logSessionComplete(sessionId, durationMs) {
|
|
363
|
+
printLog(source_default.dim(`[${timestamp()}]`) + ` Session ${source_default.green("completed")} (${formatDuration(durationMs)}) ${source_default.dim(sessionId)}
|
|
364
|
+
`);
|
|
365
|
+
},
|
|
366
|
+
logSessionFailed(sessionId, error) {
|
|
367
|
+
printLog(source_default.dim(`[${timestamp()}]`) + ` Session ${source_default.red("failed")}: ${error} ${source_default.dim(sessionId)}
|
|
368
|
+
`);
|
|
369
|
+
},
|
|
370
|
+
logStatus(message) {
|
|
371
|
+
printLog(source_default.dim(`[${timestamp()}]`) + ` ${message}
|
|
372
|
+
`);
|
|
373
|
+
},
|
|
374
|
+
logVerbose(message) {
|
|
375
|
+
if (verbose) {
|
|
376
|
+
printLog(source_default.dim(`[${timestamp()}] ${message}`) + `
|
|
377
|
+
`);
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
logError(message) {
|
|
381
|
+
printLog(source_default.red(`[${timestamp()}] Error: ${message}`) + `
|
|
382
|
+
`);
|
|
383
|
+
},
|
|
384
|
+
logReconnected(disconnectedMs) {
|
|
385
|
+
printLog(source_default.dim(`[${timestamp()}]`) + ` ${source_default.green("Reconnected")} after ${formatDuration(disconnectedMs)}
|
|
386
|
+
`);
|
|
387
|
+
},
|
|
388
|
+
setRepoInfo(repo, branchName) {
|
|
389
|
+
repoName = repo;
|
|
390
|
+
branch = branchName;
|
|
391
|
+
},
|
|
392
|
+
setDebugLogPath(path) {
|
|
393
|
+
debugLogPath = path;
|
|
394
|
+
},
|
|
395
|
+
updateIdleStatus() {
|
|
396
|
+
stopConnecting();
|
|
397
|
+
currentState = "idle";
|
|
398
|
+
currentStateText = "Ready";
|
|
399
|
+
lastToolSummary = null;
|
|
400
|
+
lastToolTime = 0;
|
|
401
|
+
activeSessionUrl = null;
|
|
402
|
+
regenerateQr(connectUrl);
|
|
403
|
+
renderStatusLine();
|
|
404
|
+
},
|
|
405
|
+
setAttached(sessionId) {
|
|
406
|
+
stopConnecting();
|
|
407
|
+
currentState = "attached";
|
|
408
|
+
currentStateText = "Connected";
|
|
409
|
+
lastToolSummary = null;
|
|
410
|
+
lastToolTime = 0;
|
|
411
|
+
if (sessionMax <= 1) {
|
|
412
|
+
activeSessionUrl = buildBridgeSessionUrl(sessionId, cachedEnvironmentId, cachedIngressUrl);
|
|
413
|
+
regenerateQr(activeSessionUrl);
|
|
414
|
+
}
|
|
415
|
+
renderStatusLine();
|
|
416
|
+
},
|
|
417
|
+
updateReconnectingStatus(delayStr, elapsedStr) {
|
|
418
|
+
stopConnecting();
|
|
419
|
+
clearStatusLines();
|
|
420
|
+
currentState = "reconnecting";
|
|
421
|
+
if (qrVisible) {
|
|
422
|
+
for (const line of qrLines) {
|
|
423
|
+
writeStatus(`${source_default.dim(line)}
|
|
424
|
+
`);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
const frame = BRIDGE_SPINNER_FRAMES[connectingTick % BRIDGE_SPINNER_FRAMES.length];
|
|
428
|
+
connectingTick++;
|
|
429
|
+
writeStatus(`${source_default.yellow(frame)} ${source_default.yellow("Reconnecting")} ${source_default.dim("\xB7")} ${source_default.dim(`retrying in ${delayStr}`)} ${source_default.dim("\xB7")} ${source_default.dim(`disconnected ${elapsedStr}`)}
|
|
430
|
+
`);
|
|
431
|
+
},
|
|
432
|
+
updateFailedStatus(error) {
|
|
433
|
+
stopConnecting();
|
|
434
|
+
clearStatusLines();
|
|
435
|
+
currentState = "failed";
|
|
436
|
+
let suffix = "";
|
|
437
|
+
if (repoName) {
|
|
438
|
+
suffix += source_default.dim(" \xB7 ") + source_default.dim(repoName);
|
|
439
|
+
}
|
|
440
|
+
if (branch) {
|
|
441
|
+
suffix += source_default.dim(" \xB7 ") + source_default.dim(branch);
|
|
442
|
+
}
|
|
443
|
+
writeStatus(`${source_default.red(BRIDGE_FAILED_INDICATOR)} ${source_default.red("Remote Control Failed")}${suffix}
|
|
444
|
+
`);
|
|
445
|
+
writeStatus(`${source_default.dim(FAILED_FOOTER_TEXT)}
|
|
446
|
+
`);
|
|
447
|
+
if (error) {
|
|
448
|
+
writeStatus(`${source_default.red(error)}
|
|
449
|
+
`);
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
updateSessionStatus(_sessionId, _elapsed, activity, _trail) {
|
|
453
|
+
if (activity.type === "tool_start") {
|
|
454
|
+
lastToolSummary = activity.summary;
|
|
455
|
+
lastToolTime = Date.now();
|
|
456
|
+
}
|
|
457
|
+
renderStatusLine();
|
|
458
|
+
},
|
|
459
|
+
clearStatus() {
|
|
460
|
+
stopConnecting();
|
|
461
|
+
clearStatusLines();
|
|
462
|
+
},
|
|
463
|
+
toggleQr() {
|
|
464
|
+
qrVisible = !qrVisible;
|
|
465
|
+
renderStatusLine();
|
|
466
|
+
},
|
|
467
|
+
updateSessionCount(active, max, mode) {
|
|
468
|
+
if (sessionActive === active && sessionMax === max && spawnMode === mode)
|
|
469
|
+
return;
|
|
470
|
+
sessionActive = active;
|
|
471
|
+
sessionMax = max;
|
|
472
|
+
spawnMode = mode;
|
|
473
|
+
},
|
|
474
|
+
setSpawnModeDisplay(mode) {
|
|
475
|
+
if (spawnModeDisplay === mode)
|
|
476
|
+
return;
|
|
477
|
+
spawnModeDisplay = mode;
|
|
478
|
+
if (mode)
|
|
479
|
+
spawnMode = mode;
|
|
480
|
+
},
|
|
481
|
+
addSession(sessionId, url) {
|
|
482
|
+
sessionDisplayInfo.set(sessionId, { url });
|
|
483
|
+
},
|
|
484
|
+
updateSessionActivity(sessionId, activity) {
|
|
485
|
+
const info = sessionDisplayInfo.get(sessionId);
|
|
486
|
+
if (!info)
|
|
487
|
+
return;
|
|
488
|
+
info.activity = activity;
|
|
489
|
+
},
|
|
490
|
+
setSessionTitle(sessionId, title) {
|
|
491
|
+
const info = sessionDisplayInfo.get(sessionId);
|
|
492
|
+
if (!info)
|
|
493
|
+
return;
|
|
494
|
+
info.title = title;
|
|
495
|
+
if (currentState === "reconnecting" || currentState === "failed")
|
|
496
|
+
return;
|
|
497
|
+
if (sessionMax === 1) {
|
|
498
|
+
currentState = "titled";
|
|
499
|
+
currentStateText = truncateToWidth(title, 40);
|
|
500
|
+
}
|
|
501
|
+
renderStatusLine();
|
|
502
|
+
},
|
|
503
|
+
removeSession(sessionId) {
|
|
504
|
+
sessionDisplayInfo.delete(sessionId);
|
|
505
|
+
},
|
|
506
|
+
refreshDisplay() {
|
|
507
|
+
if (currentState === "reconnecting" || currentState === "failed")
|
|
508
|
+
return;
|
|
509
|
+
renderStatusLine();
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
}
|
|
229
513
|
|
|
230
514
|
// src/bridge/bridgeMain.ts
|
|
231
515
|
init_debugUtils();
|
|
@@ -592,6 +876,10 @@ var DEFAULT_BACKOFF = {
|
|
|
592
876
|
generalGiveUpMs: 600000
|
|
593
877
|
};
|
|
594
878
|
var STATUS_UPDATE_INTERVAL_MS = 1000;
|
|
879
|
+
var SPAWN_SESSIONS_DEFAULT = 32;
|
|
880
|
+
async function isMultiSessionSpawnEnabled() {
|
|
881
|
+
return checkGate_CACHED_OR_BLOCKING("tengu_ccr_bridge_multi_session");
|
|
882
|
+
}
|
|
595
883
|
function pollSleepDetectionThresholdMs(backoff) {
|
|
596
884
|
return backoff.connCapMs * 2;
|
|
597
885
|
}
|
|
@@ -1067,7 +1355,7 @@ async function runBridgeLoop(config, environmentId, environmentSecret, api, spaw
|
|
|
1067
1355
|
const title = deriveSessionTitle(text);
|
|
1068
1356
|
logger.setSessionTitle(compatSessionId, title);
|
|
1069
1357
|
logForDebugging(`[bridge:title] derived title for ${compatSessionId}: ${title}`);
|
|
1070
|
-
import("./chunk-
|
|
1358
|
+
import("./chunk-01pfrqr8.js").then(({ updateBridgeSessionTitle }) => updateBridgeSessionTitle(compatSessionId, title, {
|
|
1071
1359
|
baseUrl: config.apiBaseUrl
|
|
1072
1360
|
})).catch((err) => logForDebugging(`[bridge:title] failed to update title for ${compatSessionId}: ${err}`, { level: "error" }));
|
|
1073
1361
|
}
|
|
@@ -1401,16 +1689,651 @@ function onSessionTimeout(sessionId, timeoutMs, logger, timedOutSessions, handle
|
|
|
1401
1689
|
timedOutSessions.add(sessionId);
|
|
1402
1690
|
handle.kill();
|
|
1403
1691
|
}
|
|
1692
|
+
var SPAWN_FLAG_VALUES = ["session", "same-dir", "worktree"];
|
|
1693
|
+
function parseSpawnValue(raw) {
|
|
1694
|
+
if (raw === "session")
|
|
1695
|
+
return "single-session";
|
|
1696
|
+
if (raw === "same-dir")
|
|
1697
|
+
return "same-dir";
|
|
1698
|
+
if (raw === "worktree")
|
|
1699
|
+
return "worktree";
|
|
1700
|
+
return `--spawn requires one of: ${SPAWN_FLAG_VALUES.join(", ")} (got: ${raw ?? "<missing>"})`;
|
|
1701
|
+
}
|
|
1702
|
+
function parseCapacityValue(raw) {
|
|
1703
|
+
const n = raw === undefined ? NaN : parseInt(raw, 10);
|
|
1704
|
+
if (isNaN(n) || n < 1) {
|
|
1705
|
+
return `--capacity requires a positive integer (got: ${raw ?? "<missing>"})`;
|
|
1706
|
+
}
|
|
1707
|
+
return n;
|
|
1708
|
+
}
|
|
1709
|
+
function parseArgs(args) {
|
|
1710
|
+
let verbose = false;
|
|
1711
|
+
let sandbox = false;
|
|
1712
|
+
let debugFile;
|
|
1713
|
+
let sessionTimeoutMs;
|
|
1714
|
+
let permissionMode;
|
|
1715
|
+
let name;
|
|
1716
|
+
let help = false;
|
|
1717
|
+
let spawnMode;
|
|
1718
|
+
let capacity;
|
|
1719
|
+
let createSessionInDir;
|
|
1720
|
+
let sessionId;
|
|
1721
|
+
let continueSession = false;
|
|
1722
|
+
for (let i = 0;i < args.length; i++) {
|
|
1723
|
+
const arg = args[i];
|
|
1724
|
+
if (arg === "--help" || arg === "-h") {
|
|
1725
|
+
help = true;
|
|
1726
|
+
} else if (arg === "--verbose" || arg === "-v") {
|
|
1727
|
+
verbose = true;
|
|
1728
|
+
} else if (arg === "--sandbox") {
|
|
1729
|
+
sandbox = true;
|
|
1730
|
+
} else if (arg === "--no-sandbox") {
|
|
1731
|
+
sandbox = false;
|
|
1732
|
+
} else if (arg === "--debug-file" && i + 1 < args.length) {
|
|
1733
|
+
debugFile = resolve(args[++i]);
|
|
1734
|
+
} else if (arg.startsWith("--debug-file=")) {
|
|
1735
|
+
debugFile = resolve(arg.slice("--debug-file=".length));
|
|
1736
|
+
} else if (arg === "--session-timeout" && i + 1 < args.length) {
|
|
1737
|
+
sessionTimeoutMs = parseInt(args[++i], 10) * 1000;
|
|
1738
|
+
} else if (arg.startsWith("--session-timeout=")) {
|
|
1739
|
+
sessionTimeoutMs = parseInt(arg.slice("--session-timeout=".length), 10) * 1000;
|
|
1740
|
+
} else if (arg === "--permission-mode" && i + 1 < args.length) {
|
|
1741
|
+
permissionMode = args[++i];
|
|
1742
|
+
} else if (arg.startsWith("--permission-mode=")) {
|
|
1743
|
+
permissionMode = arg.slice("--permission-mode=".length);
|
|
1744
|
+
} else if (arg === "--name" && i + 1 < args.length) {
|
|
1745
|
+
name = args[++i];
|
|
1746
|
+
} else if (arg.startsWith("--name=")) {
|
|
1747
|
+
name = arg.slice("--name=".length);
|
|
1748
|
+
} else if (arg === "--session-id" && i + 1 < args.length) {
|
|
1749
|
+
sessionId = args[++i];
|
|
1750
|
+
if (!sessionId) {
|
|
1751
|
+
return makeError("--session-id requires a value");
|
|
1752
|
+
}
|
|
1753
|
+
} else if (arg.startsWith("--session-id=")) {
|
|
1754
|
+
sessionId = arg.slice("--session-id=".length);
|
|
1755
|
+
if (!sessionId) {
|
|
1756
|
+
return makeError("--session-id requires a value");
|
|
1757
|
+
}
|
|
1758
|
+
} else if (arg === "--continue" || arg === "-c") {
|
|
1759
|
+
continueSession = true;
|
|
1760
|
+
} else if (arg === "--spawn" || arg.startsWith("--spawn=")) {
|
|
1761
|
+
if (spawnMode !== undefined) {
|
|
1762
|
+
return makeError("--spawn may only be specified once");
|
|
1763
|
+
}
|
|
1764
|
+
const raw = arg.startsWith("--spawn=") ? arg.slice("--spawn=".length) : args[++i];
|
|
1765
|
+
const v = parseSpawnValue(raw);
|
|
1766
|
+
if (v === "single-session" || v === "same-dir" || v === "worktree") {
|
|
1767
|
+
spawnMode = v;
|
|
1768
|
+
} else {
|
|
1769
|
+
return makeError(v);
|
|
1770
|
+
}
|
|
1771
|
+
} else if (arg === "--capacity" || arg.startsWith("--capacity=")) {
|
|
1772
|
+
if (capacity !== undefined) {
|
|
1773
|
+
return makeError("--capacity may only be specified once");
|
|
1774
|
+
}
|
|
1775
|
+
const raw = arg.startsWith("--capacity=") ? arg.slice("--capacity=".length) : args[++i];
|
|
1776
|
+
const v = parseCapacityValue(raw);
|
|
1777
|
+
if (typeof v === "number")
|
|
1778
|
+
capacity = v;
|
|
1779
|
+
else
|
|
1780
|
+
return makeError(v);
|
|
1781
|
+
} else if (arg === "--create-session-in-dir") {
|
|
1782
|
+
createSessionInDir = true;
|
|
1783
|
+
} else if (arg === "--no-create-session-in-dir") {
|
|
1784
|
+
createSessionInDir = false;
|
|
1785
|
+
} else {
|
|
1786
|
+
return makeError(`Unknown argument: ${arg}
|
|
1787
|
+
Run 'claude remote-control --help' for usage.`);
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
if (spawnMode === "single-session" && capacity !== undefined) {
|
|
1791
|
+
return makeError(`--capacity cannot be used with --spawn=session (single-session mode has fixed capacity 1).`);
|
|
1792
|
+
}
|
|
1793
|
+
if ((sessionId || continueSession) && (spawnMode !== undefined || capacity !== undefined || createSessionInDir !== undefined)) {
|
|
1794
|
+
return makeError(`--session-id and --continue cannot be used with --spawn, --capacity, or --create-session-in-dir.`);
|
|
1795
|
+
}
|
|
1796
|
+
if (sessionId && continueSession) {
|
|
1797
|
+
return makeError(`--session-id and --continue cannot be used together.`);
|
|
1798
|
+
}
|
|
1799
|
+
return {
|
|
1800
|
+
verbose,
|
|
1801
|
+
sandbox,
|
|
1802
|
+
debugFile,
|
|
1803
|
+
sessionTimeoutMs,
|
|
1804
|
+
permissionMode,
|
|
1805
|
+
name,
|
|
1806
|
+
spawnMode,
|
|
1807
|
+
capacity,
|
|
1808
|
+
createSessionInDir,
|
|
1809
|
+
sessionId,
|
|
1810
|
+
continueSession,
|
|
1811
|
+
help
|
|
1812
|
+
};
|
|
1813
|
+
function makeError(error) {
|
|
1814
|
+
return {
|
|
1815
|
+
verbose,
|
|
1816
|
+
sandbox,
|
|
1817
|
+
debugFile,
|
|
1818
|
+
sessionTimeoutMs,
|
|
1819
|
+
permissionMode,
|
|
1820
|
+
name,
|
|
1821
|
+
spawnMode,
|
|
1822
|
+
capacity,
|
|
1823
|
+
createSessionInDir,
|
|
1824
|
+
sessionId,
|
|
1825
|
+
continueSession,
|
|
1826
|
+
help,
|
|
1827
|
+
error
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
async function printHelp() {
|
|
1832
|
+
const { EXTERNAL_PERMISSION_MODES } = await import("./chunk-g1k68z1b.js");
|
|
1833
|
+
const modes = EXTERNAL_PERMISSION_MODES.join(", ");
|
|
1834
|
+
const showServer = await isMultiSessionSpawnEnabled();
|
|
1835
|
+
const serverOptions = showServer ? ` --spawn <mode> Spawn mode: same-dir, worktree, session
|
|
1836
|
+
(default: same-dir)
|
|
1837
|
+
--capacity <N> Max concurrent sessions in worktree or
|
|
1838
|
+
same-dir mode (default: ${SPAWN_SESSIONS_DEFAULT})
|
|
1839
|
+
--[no-]create-session-in-dir Pre-create a session in the current
|
|
1840
|
+
directory; in worktree mode this session
|
|
1841
|
+
stays in cwd while on-demand sessions get
|
|
1842
|
+
isolated worktrees (default: on)
|
|
1843
|
+
` : "";
|
|
1844
|
+
const serverDescription = showServer ? `
|
|
1845
|
+
Remote Control runs as a persistent server that accepts multiple concurrent
|
|
1846
|
+
sessions in the current directory. One session is pre-created on start so
|
|
1847
|
+
you have somewhere to type immediately. Use --spawn=worktree to isolate
|
|
1848
|
+
each on-demand session in its own git worktree, or --spawn=session for
|
|
1849
|
+
the classic single-session mode (exits when that session ends). Press 'w'
|
|
1850
|
+
during runtime to toggle between same-dir and worktree.
|
|
1851
|
+
` : "";
|
|
1852
|
+
const serverNote = showServer ? ` - Worktree mode requires a git repository or WorktreeCreate/WorktreeRemove hooks
|
|
1853
|
+
` : "";
|
|
1854
|
+
const help = `
|
|
1855
|
+
Remote Control - Connect your local environment to claude.ai/code
|
|
1856
|
+
|
|
1857
|
+
USAGE
|
|
1858
|
+
claude remote-control [options]
|
|
1859
|
+
OPTIONS
|
|
1860
|
+
--name <name> Name for the session (shown in claude.ai/code)
|
|
1861
|
+
-c, --continue Resume the last session in this directory
|
|
1862
|
+
--session-id <id> Resume a specific session by ID (cannot be
|
|
1863
|
+
used with spawn flags or --continue)
|
|
1864
|
+
--permission-mode <mode> Permission mode for spawned sessions
|
|
1865
|
+
(${modes})
|
|
1866
|
+
--debug-file <path> Write debug logs to file
|
|
1867
|
+
-v, --verbose Enable verbose output
|
|
1868
|
+
-h, --help Show this help
|
|
1869
|
+
${serverOptions}
|
|
1870
|
+
DESCRIPTION
|
|
1871
|
+
Remote Control allows you to control sessions on your local device from
|
|
1872
|
+
claude.ai/code (https://claude.ai/code). Run this command in the
|
|
1873
|
+
directory you want to work in, then connect from the Claude app or web.
|
|
1874
|
+
${serverDescription}
|
|
1875
|
+
NOTES
|
|
1876
|
+
- You must be logged in with a Claude account that has a subscription
|
|
1877
|
+
- Run \`claude\` first in the directory to accept the workspace trust dialog
|
|
1878
|
+
${serverNote}`;
|
|
1879
|
+
console.log(help);
|
|
1880
|
+
}
|
|
1404
1881
|
var TITLE_MAX_LEN = 80;
|
|
1405
1882
|
function deriveSessionTitle(text) {
|
|
1406
1883
|
const flat = text.replace(/\s+/g, " ").trim();
|
|
1407
1884
|
return truncateToWidth(flat, TITLE_MAX_LEN);
|
|
1408
1885
|
}
|
|
1409
1886
|
async function fetchSessionTitle(compatSessionId, baseUrl) {
|
|
1410
|
-
const { getBridgeSession } = await import("./chunk-
|
|
1887
|
+
const { getBridgeSession } = await import("./chunk-01pfrqr8.js");
|
|
1411
1888
|
const session = await getBridgeSession(compatSessionId, { baseUrl });
|
|
1412
1889
|
return session?.title || undefined;
|
|
1413
1890
|
}
|
|
1891
|
+
async function bridgeMain(args) {
|
|
1892
|
+
const parsed = parseArgs(args);
|
|
1893
|
+
if (parsed.help) {
|
|
1894
|
+
await printHelp();
|
|
1895
|
+
return;
|
|
1896
|
+
}
|
|
1897
|
+
if (parsed.error) {
|
|
1898
|
+
console.error(`Error: ${parsed.error}`);
|
|
1899
|
+
process.exit(1);
|
|
1900
|
+
}
|
|
1901
|
+
const {
|
|
1902
|
+
verbose,
|
|
1903
|
+
sandbox,
|
|
1904
|
+
debugFile,
|
|
1905
|
+
sessionTimeoutMs,
|
|
1906
|
+
permissionMode,
|
|
1907
|
+
name,
|
|
1908
|
+
spawnMode: parsedSpawnMode,
|
|
1909
|
+
capacity: parsedCapacity,
|
|
1910
|
+
createSessionInDir: parsedCreateSessionInDir,
|
|
1911
|
+
sessionId: parsedSessionId,
|
|
1912
|
+
continueSession
|
|
1913
|
+
} = parsed;
|
|
1914
|
+
let resumeSessionId = parsedSessionId;
|
|
1915
|
+
let resumePointerDir;
|
|
1916
|
+
const usedMultiSessionFeature = parsedSpawnMode !== undefined || parsedCapacity !== undefined || parsedCreateSessionInDir !== undefined;
|
|
1917
|
+
if (permissionMode !== undefined) {
|
|
1918
|
+
const { PERMISSION_MODES } = await import("./chunk-g1k68z1b.js");
|
|
1919
|
+
const valid = PERMISSION_MODES;
|
|
1920
|
+
if (!valid.includes(permissionMode)) {
|
|
1921
|
+
console.error(`Error: Invalid permission mode '${permissionMode}'. Valid modes: ${valid.join(", ")}`);
|
|
1922
|
+
process.exit(1);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
const dir = resolve(".");
|
|
1926
|
+
const { enableConfigs, checkHasTrustDialogAccepted } = await import("./chunk-cbssxph9.js");
|
|
1927
|
+
enableConfigs();
|
|
1928
|
+
const { initSinks } = await import("./chunk-sfmxv59p.js");
|
|
1929
|
+
initSinks();
|
|
1930
|
+
const multiSessionEnabled = await isMultiSessionSpawnEnabled();
|
|
1931
|
+
if (usedMultiSessionFeature && !multiSessionEnabled) {
|
|
1932
|
+
await logEventAsync("tengu_bridge_multi_session_denied", {
|
|
1933
|
+
used_spawn: parsedSpawnMode !== undefined,
|
|
1934
|
+
used_capacity: parsedCapacity !== undefined,
|
|
1935
|
+
used_create_session_in_dir: parsedCreateSessionInDir !== undefined
|
|
1936
|
+
});
|
|
1937
|
+
await Promise.race([
|
|
1938
|
+
Promise.all([shutdown1PEventLogging(), shutdownDatadog()]),
|
|
1939
|
+
sleep(500, undefined, { unref: true })
|
|
1940
|
+
]).catch(() => {});
|
|
1941
|
+
console.error("Error: Multi-session Remote Control is not enabled for your account yet.");
|
|
1942
|
+
process.exit(1);
|
|
1943
|
+
}
|
|
1944
|
+
const { setOriginalCwd, setCwdState } = await import("./chunk-m1tjr9xq.js");
|
|
1945
|
+
setOriginalCwd(dir);
|
|
1946
|
+
setCwdState(dir);
|
|
1947
|
+
if (!checkHasTrustDialogAccepted()) {
|
|
1948
|
+
console.error(`Error: Workspace not trusted. Please run \`claude\` in ${dir} first to review and accept the workspace trust dialog.`);
|
|
1949
|
+
process.exit(1);
|
|
1950
|
+
}
|
|
1951
|
+
const { clearOAuthTokenCache, checkAndRefreshOAuthTokenIfNeeded } = await import("./chunk-w0hw971e.js");
|
|
1952
|
+
const { getBridgeAccessToken, getBridgeBaseUrl } = await import("./chunk-bec4mkst.js");
|
|
1953
|
+
const bridgeToken = getBridgeAccessToken();
|
|
1954
|
+
if (!bridgeToken) {
|
|
1955
|
+
console.error(BRIDGE_LOGIN_ERROR);
|
|
1956
|
+
process.exit(1);
|
|
1957
|
+
}
|
|
1958
|
+
const {
|
|
1959
|
+
getGlobalConfig,
|
|
1960
|
+
saveGlobalConfig,
|
|
1961
|
+
getCurrentProjectConfig,
|
|
1962
|
+
saveCurrentProjectConfig
|
|
1963
|
+
} = await import("./chunk-cbssxph9.js");
|
|
1964
|
+
if (!getGlobalConfig().remoteDialogSeen) {
|
|
1965
|
+
const readline = await import("readline");
|
|
1966
|
+
const rl = readline.createInterface({
|
|
1967
|
+
input: process.stdin,
|
|
1968
|
+
output: process.stdout
|
|
1969
|
+
});
|
|
1970
|
+
console.log(`
|
|
1971
|
+
Remote Control lets you access this CLI session from the web (claude.ai/code)
|
|
1972
|
+
or the Claude app, so you can pick up where you left off on any device.
|
|
1973
|
+
|
|
1974
|
+
You can disconnect remote access anytime by running /remote-control again.
|
|
1975
|
+
`);
|
|
1976
|
+
const answer = await new Promise((resolve2) => {
|
|
1977
|
+
rl.question("Enable Remote Control? (y/n) ", resolve2);
|
|
1978
|
+
});
|
|
1979
|
+
rl.close();
|
|
1980
|
+
saveGlobalConfig((current) => {
|
|
1981
|
+
if (current.remoteDialogSeen)
|
|
1982
|
+
return current;
|
|
1983
|
+
return { ...current, remoteDialogSeen: true };
|
|
1984
|
+
});
|
|
1985
|
+
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
1986
|
+
process.exit(0);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
if (continueSession) {
|
|
1990
|
+
const { readBridgePointerAcrossWorktrees } = await import("./chunk-fxpsa506.js");
|
|
1991
|
+
const found = await readBridgePointerAcrossWorktrees(dir);
|
|
1992
|
+
if (!found) {
|
|
1993
|
+
console.error(`Error: No recent session found in this directory or its worktrees. Run \`claude remote-control\` to start a new one.`);
|
|
1994
|
+
process.exit(1);
|
|
1995
|
+
}
|
|
1996
|
+
const { pointer, dir: pointerDir } = found;
|
|
1997
|
+
const ageMin = Math.round(pointer.ageMs / 60000);
|
|
1998
|
+
const ageStr = ageMin < 60 ? `${ageMin}m` : `${Math.round(ageMin / 60)}h`;
|
|
1999
|
+
const fromWt = pointerDir !== dir ? ` from worktree ${pointerDir}` : "";
|
|
2000
|
+
console.error(`Resuming session ${pointer.sessionId} (${ageStr} ago)${fromWt}\u2026`);
|
|
2001
|
+
resumeSessionId = pointer.sessionId;
|
|
2002
|
+
resumePointerDir = pointerDir;
|
|
2003
|
+
}
|
|
2004
|
+
const baseUrl = getBridgeBaseUrl();
|
|
2005
|
+
if (baseUrl.startsWith("http://") && !baseUrl.includes("localhost") && !baseUrl.includes("127.0.0.1")) {
|
|
2006
|
+
console.error("Error: Remote Control base URL uses HTTP. Only HTTPS or localhost HTTP is allowed.");
|
|
2007
|
+
process.exit(1);
|
|
2008
|
+
}
|
|
2009
|
+
const sessionIngressUrl = process.env.CLAUDE_BRIDGE_SESSION_INGRESS_URL || baseUrl;
|
|
2010
|
+
const { getBranch, getRemoteUrl, findGitRoot } = await import("./chunk-dy8tttdp.js");
|
|
2011
|
+
const { hasWorktreeCreateHook } = await import("./chunk-6kwx0aa4.js");
|
|
2012
|
+
const worktreeAvailable = hasWorktreeCreateHook() || findGitRoot(dir) !== null;
|
|
2013
|
+
let savedSpawnMode = multiSessionEnabled ? getCurrentProjectConfig().remoteControlSpawnMode : undefined;
|
|
2014
|
+
if (savedSpawnMode === "worktree" && !worktreeAvailable) {
|
|
2015
|
+
console.error("Warning: Saved spawn mode is worktree but this directory is not a git repository. Falling back to same-dir.");
|
|
2016
|
+
savedSpawnMode = undefined;
|
|
2017
|
+
saveCurrentProjectConfig((current) => {
|
|
2018
|
+
if (current.remoteControlSpawnMode === undefined)
|
|
2019
|
+
return current;
|
|
2020
|
+
return { ...current, remoteControlSpawnMode: undefined };
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
if (multiSessionEnabled && !savedSpawnMode && worktreeAvailable && parsedSpawnMode === undefined && !resumeSessionId && process.stdin.isTTY) {
|
|
2024
|
+
const readline = await import("readline");
|
|
2025
|
+
const rl = readline.createInterface({
|
|
2026
|
+
input: process.stdin,
|
|
2027
|
+
output: process.stdout
|
|
2028
|
+
});
|
|
2029
|
+
console.log(`
|
|
2030
|
+
Claude Remote Control is launching in spawn mode which lets you create new sessions in this project from Claude Code on Web or your Mobile app. Learn more here: https://code.claude.com/docs/en/remote-control
|
|
2031
|
+
|
|
2032
|
+
Spawn mode for this project:
|
|
2033
|
+
` + ` [1] same-dir \u2014 sessions share the current directory (default)
|
|
2034
|
+
` + ` [2] worktree \u2014 each session gets an isolated git worktree
|
|
2035
|
+
|
|
2036
|
+
` + `This can be changed later or explicitly set with --spawn=same-dir or --spawn=worktree.
|
|
2037
|
+
`);
|
|
2038
|
+
const answer = await new Promise((resolve2) => {
|
|
2039
|
+
rl.question("Choose [1/2] (default: 1): ", resolve2);
|
|
2040
|
+
});
|
|
2041
|
+
rl.close();
|
|
2042
|
+
const chosen = answer.trim() === "2" ? "worktree" : "same-dir";
|
|
2043
|
+
savedSpawnMode = chosen;
|
|
2044
|
+
logEvent("tengu_bridge_spawn_mode_chosen", {
|
|
2045
|
+
spawn_mode: chosen
|
|
2046
|
+
});
|
|
2047
|
+
saveCurrentProjectConfig((current) => {
|
|
2048
|
+
if (current.remoteControlSpawnMode === chosen)
|
|
2049
|
+
return current;
|
|
2050
|
+
return { ...current, remoteControlSpawnMode: chosen };
|
|
2051
|
+
});
|
|
2052
|
+
}
|
|
2053
|
+
let spawnModeSource;
|
|
2054
|
+
let spawnMode;
|
|
2055
|
+
if (resumeSessionId) {
|
|
2056
|
+
spawnMode = "single-session";
|
|
2057
|
+
spawnModeSource = "resume";
|
|
2058
|
+
} else if (parsedSpawnMode !== undefined) {
|
|
2059
|
+
spawnMode = parsedSpawnMode;
|
|
2060
|
+
spawnModeSource = "flag";
|
|
2061
|
+
} else if (savedSpawnMode !== undefined) {
|
|
2062
|
+
spawnMode = savedSpawnMode;
|
|
2063
|
+
spawnModeSource = "saved";
|
|
2064
|
+
} else {
|
|
2065
|
+
spawnMode = multiSessionEnabled ? "same-dir" : "single-session";
|
|
2066
|
+
spawnModeSource = "gate_default";
|
|
2067
|
+
}
|
|
2068
|
+
const maxSessions = spawnMode === "single-session" ? 1 : parsedCapacity ?? SPAWN_SESSIONS_DEFAULT;
|
|
2069
|
+
const preCreateSession = parsedCreateSessionInDir ?? true;
|
|
2070
|
+
if (!resumeSessionId) {
|
|
2071
|
+
const { clearBridgePointer } = await import("./chunk-fxpsa506.js");
|
|
2072
|
+
await clearBridgePointer(dir);
|
|
2073
|
+
}
|
|
2074
|
+
if (spawnMode === "worktree" && !worktreeAvailable) {
|
|
2075
|
+
console.error(`Error: Worktree mode requires a git repository or WorktreeCreate hooks configured. Use --spawn=session for single-session mode.`);
|
|
2076
|
+
process.exit(1);
|
|
2077
|
+
}
|
|
2078
|
+
const branch = await getBranch();
|
|
2079
|
+
const gitRepoUrl = await getRemoteUrl();
|
|
2080
|
+
const machineName = hostname();
|
|
2081
|
+
const bridgeId = randomUUID();
|
|
2082
|
+
const { handleOAuth401Error } = await import("./chunk-w0hw971e.js");
|
|
2083
|
+
const api = createBridgeApiClient({
|
|
2084
|
+
baseUrl,
|
|
2085
|
+
getAccessToken: getBridgeAccessToken,
|
|
2086
|
+
runnerVersion: "2.1.888",
|
|
2087
|
+
onDebug: logForDebugging,
|
|
2088
|
+
onAuth401: handleOAuth401Error,
|
|
2089
|
+
getTrustedDeviceToken
|
|
2090
|
+
});
|
|
2091
|
+
let reuseEnvironmentId;
|
|
2092
|
+
if (resumeSessionId) {
|
|
2093
|
+
try {
|
|
2094
|
+
validateBridgeId(resumeSessionId, "sessionId");
|
|
2095
|
+
} catch {
|
|
2096
|
+
console.error(`Error: Invalid session ID "${resumeSessionId}". Session IDs must not contain unsafe characters.`);
|
|
2097
|
+
process.exit(1);
|
|
2098
|
+
}
|
|
2099
|
+
await checkAndRefreshOAuthTokenIfNeeded();
|
|
2100
|
+
clearOAuthTokenCache();
|
|
2101
|
+
const { getBridgeSession } = await import("./chunk-01pfrqr8.js");
|
|
2102
|
+
const session = await getBridgeSession(resumeSessionId, {
|
|
2103
|
+
baseUrl,
|
|
2104
|
+
getAccessToken: getBridgeAccessToken
|
|
2105
|
+
});
|
|
2106
|
+
if (!session) {
|
|
2107
|
+
if (resumePointerDir) {
|
|
2108
|
+
const { clearBridgePointer } = await import("./chunk-fxpsa506.js");
|
|
2109
|
+
await clearBridgePointer(resumePointerDir);
|
|
2110
|
+
}
|
|
2111
|
+
console.error(`Error: Session ${resumeSessionId} not found. It may have been archived or expired, or your login may have lapsed (run \`claude /login\`).`);
|
|
2112
|
+
process.exit(1);
|
|
2113
|
+
}
|
|
2114
|
+
if (!session.environment_id) {
|
|
2115
|
+
if (resumePointerDir) {
|
|
2116
|
+
const { clearBridgePointer } = await import("./chunk-fxpsa506.js");
|
|
2117
|
+
await clearBridgePointer(resumePointerDir);
|
|
2118
|
+
}
|
|
2119
|
+
console.error(`Error: Session ${resumeSessionId} has no environment_id. It may never have been attached to a bridge.`);
|
|
2120
|
+
process.exit(1);
|
|
2121
|
+
}
|
|
2122
|
+
reuseEnvironmentId = session.environment_id;
|
|
2123
|
+
logForDebugging(`[bridge:init] Resuming session ${resumeSessionId} on environment ${reuseEnvironmentId}`);
|
|
2124
|
+
}
|
|
2125
|
+
const config = {
|
|
2126
|
+
dir,
|
|
2127
|
+
machineName,
|
|
2128
|
+
branch,
|
|
2129
|
+
gitRepoUrl,
|
|
2130
|
+
maxSessions,
|
|
2131
|
+
spawnMode,
|
|
2132
|
+
verbose,
|
|
2133
|
+
sandbox,
|
|
2134
|
+
bridgeId,
|
|
2135
|
+
workerType: "claude_code",
|
|
2136
|
+
environmentId: randomUUID(),
|
|
2137
|
+
reuseEnvironmentId,
|
|
2138
|
+
apiBaseUrl: baseUrl,
|
|
2139
|
+
sessionIngressUrl,
|
|
2140
|
+
debugFile,
|
|
2141
|
+
sessionTimeoutMs
|
|
2142
|
+
};
|
|
2143
|
+
logForDebugging(`[bridge:init] bridgeId=${bridgeId}${reuseEnvironmentId ? ` reuseEnvironmentId=${reuseEnvironmentId}` : ""} dir=${dir} branch=${branch} gitRepoUrl=${gitRepoUrl} machine=${machineName}`);
|
|
2144
|
+
logForDebugging(`[bridge:init] apiBaseUrl=${baseUrl} sessionIngressUrl=${sessionIngressUrl}`);
|
|
2145
|
+
logForDebugging(`[bridge:init] sandbox=${sandbox}${debugFile ? ` debugFile=${debugFile}` : ""}`);
|
|
2146
|
+
let environmentId;
|
|
2147
|
+
let environmentSecret;
|
|
2148
|
+
try {
|
|
2149
|
+
const reg = await api.registerBridgeEnvironment(config);
|
|
2150
|
+
environmentId = reg.environment_id;
|
|
2151
|
+
environmentSecret = reg.environment_secret;
|
|
2152
|
+
} catch (err) {
|
|
2153
|
+
logEvent("tengu_bridge_registration_failed", {
|
|
2154
|
+
status: err instanceof BridgeFatalError ? err.status : undefined
|
|
2155
|
+
});
|
|
2156
|
+
console.error(err instanceof BridgeFatalError && err.status === 404 ? "Remote Control environments are not available for your account." : `Error: ${errorMessage(err)}`);
|
|
2157
|
+
process.exit(1);
|
|
2158
|
+
}
|
|
2159
|
+
let effectiveResumeSessionId;
|
|
2160
|
+
if (resumeSessionId) {
|
|
2161
|
+
if (reuseEnvironmentId && environmentId !== reuseEnvironmentId) {
|
|
2162
|
+
logError(new Error(`Bridge resume env mismatch: requested ${reuseEnvironmentId}, backend returned ${environmentId}. Falling back to fresh session.`));
|
|
2163
|
+
console.warn(`Warning: Could not resume session ${resumeSessionId} \u2014 its environment has expired. Creating a fresh session instead.`);
|
|
2164
|
+
} else {
|
|
2165
|
+
const infraResumeId = toInfraSessionId(resumeSessionId);
|
|
2166
|
+
const reconnectCandidates = infraResumeId === resumeSessionId ? [resumeSessionId] : [resumeSessionId, infraResumeId];
|
|
2167
|
+
let reconnected = false;
|
|
2168
|
+
let lastReconnectErr;
|
|
2169
|
+
for (const candidateId of reconnectCandidates) {
|
|
2170
|
+
try {
|
|
2171
|
+
await api.reconnectSession(environmentId, candidateId);
|
|
2172
|
+
logForDebugging(`[bridge:init] Session ${candidateId} re-queued via bridge/reconnect`);
|
|
2173
|
+
effectiveResumeSessionId = resumeSessionId;
|
|
2174
|
+
reconnected = true;
|
|
2175
|
+
break;
|
|
2176
|
+
} catch (err) {
|
|
2177
|
+
lastReconnectErr = err;
|
|
2178
|
+
logForDebugging(`[bridge:init] reconnectSession(${candidateId}) failed: ${errorMessage(err)}`);
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
if (!reconnected) {
|
|
2182
|
+
const err = lastReconnectErr;
|
|
2183
|
+
const isFatal = err instanceof BridgeFatalError;
|
|
2184
|
+
if (resumePointerDir && isFatal) {
|
|
2185
|
+
const { clearBridgePointer } = await import("./chunk-fxpsa506.js");
|
|
2186
|
+
await clearBridgePointer(resumePointerDir);
|
|
2187
|
+
}
|
|
2188
|
+
console.error(isFatal ? `Error: ${errorMessage(err)}` : `Error: Failed to reconnect session ${resumeSessionId}: ${errorMessage(err)}
|
|
2189
|
+
The session may still be resumable \u2014 try running the same command again.`);
|
|
2190
|
+
process.exit(1);
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
logForDebugging(`[bridge:init] Registered, server environmentId=${environmentId}`);
|
|
2195
|
+
const startupPollConfig = getPollIntervalConfig();
|
|
2196
|
+
logEvent("tengu_bridge_started", {
|
|
2197
|
+
max_sessions: config.maxSessions,
|
|
2198
|
+
has_debug_file: !!config.debugFile,
|
|
2199
|
+
sandbox: config.sandbox,
|
|
2200
|
+
verbose: config.verbose,
|
|
2201
|
+
heartbeat_interval_ms: startupPollConfig.non_exclusive_heartbeat_interval_ms,
|
|
2202
|
+
spawn_mode: config.spawnMode,
|
|
2203
|
+
spawn_mode_source: spawnModeSource,
|
|
2204
|
+
multi_session_gate: multiSessionEnabled,
|
|
2205
|
+
pre_create_session: preCreateSession,
|
|
2206
|
+
worktree_available: worktreeAvailable
|
|
2207
|
+
});
|
|
2208
|
+
logForDiagnosticsNoPII("info", "bridge_started", {
|
|
2209
|
+
max_sessions: config.maxSessions,
|
|
2210
|
+
sandbox: config.sandbox,
|
|
2211
|
+
spawn_mode: config.spawnMode
|
|
2212
|
+
});
|
|
2213
|
+
const spawner = createSessionSpawner({
|
|
2214
|
+
execPath: process.execPath,
|
|
2215
|
+
scriptArgs: spawnScriptArgs(),
|
|
2216
|
+
env: process.env,
|
|
2217
|
+
verbose,
|
|
2218
|
+
sandbox,
|
|
2219
|
+
debugFile,
|
|
2220
|
+
permissionMode,
|
|
2221
|
+
onDebug: logForDebugging,
|
|
2222
|
+
onActivity: (sessionId, activity) => {
|
|
2223
|
+
logForDebugging(`[bridge:activity] sessionId=${sessionId} ${activity.type} ${activity.summary}`);
|
|
2224
|
+
},
|
|
2225
|
+
onPermissionRequest: (sessionId, request, _accessToken) => {
|
|
2226
|
+
logForDebugging(`[bridge:perm] sessionId=${sessionId} tool=${request.request.tool_name} request_id=${request.request_id} (not auto-approving)`);
|
|
2227
|
+
}
|
|
2228
|
+
});
|
|
2229
|
+
const logger = createBridgeLogger({ verbose });
|
|
2230
|
+
const { parseGitHubRepository } = await import("./chunk-469hyn07.js");
|
|
2231
|
+
const ownerRepo = gitRepoUrl ? parseGitHubRepository(gitRepoUrl) : null;
|
|
2232
|
+
const repoName = ownerRepo ? ownerRepo.split("/").pop() : basename(dir);
|
|
2233
|
+
logger.setRepoInfo(repoName, branch);
|
|
2234
|
+
const toggleAvailable = spawnMode !== "single-session" && worktreeAvailable;
|
|
2235
|
+
if (toggleAvailable) {
|
|
2236
|
+
logger.setSpawnModeDisplay(spawnMode);
|
|
2237
|
+
}
|
|
2238
|
+
const onStdinData = (data) => {
|
|
2239
|
+
if (data[0] === 3 || data[0] === 4) {
|
|
2240
|
+
process.emit("SIGINT");
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
if (data[0] === 32) {
|
|
2244
|
+
logger.toggleQr();
|
|
2245
|
+
return;
|
|
2246
|
+
}
|
|
2247
|
+
if (data[0] === 119) {
|
|
2248
|
+
if (!toggleAvailable)
|
|
2249
|
+
return;
|
|
2250
|
+
const newMode = config.spawnMode === "same-dir" ? "worktree" : "same-dir";
|
|
2251
|
+
config.spawnMode = newMode;
|
|
2252
|
+
logEvent("tengu_bridge_spawn_mode_toggled", {
|
|
2253
|
+
spawn_mode: newMode
|
|
2254
|
+
});
|
|
2255
|
+
logger.logStatus(newMode === "worktree" ? "Spawn mode: worktree (new sessions get isolated git worktrees)" : "Spawn mode: same-dir (new sessions share the current directory)");
|
|
2256
|
+
logger.setSpawnModeDisplay(newMode);
|
|
2257
|
+
logger.refreshDisplay();
|
|
2258
|
+
saveCurrentProjectConfig((current) => {
|
|
2259
|
+
if (current.remoteControlSpawnMode === newMode)
|
|
2260
|
+
return current;
|
|
2261
|
+
return { ...current, remoteControlSpawnMode: newMode };
|
|
2262
|
+
});
|
|
2263
|
+
return;
|
|
2264
|
+
}
|
|
2265
|
+
};
|
|
2266
|
+
if (process.stdin.isTTY) {
|
|
2267
|
+
process.stdin.setRawMode(true);
|
|
2268
|
+
process.stdin.resume();
|
|
2269
|
+
process.stdin.on("data", onStdinData);
|
|
2270
|
+
}
|
|
2271
|
+
const controller = new AbortController;
|
|
2272
|
+
const onSigint = () => {
|
|
2273
|
+
logForDebugging("[bridge:shutdown] SIGINT received, shutting down");
|
|
2274
|
+
controller.abort();
|
|
2275
|
+
};
|
|
2276
|
+
const onSigterm = () => {
|
|
2277
|
+
logForDebugging("[bridge:shutdown] SIGTERM received, shutting down");
|
|
2278
|
+
controller.abort();
|
|
2279
|
+
};
|
|
2280
|
+
process.on("SIGINT", onSigint);
|
|
2281
|
+
process.on("SIGTERM", onSigterm);
|
|
2282
|
+
let initialSessionId = effectiveResumeSessionId ? effectiveResumeSessionId : null;
|
|
2283
|
+
if (preCreateSession && !effectiveResumeSessionId) {
|
|
2284
|
+
const { createBridgeSession } = await import("./chunk-01pfrqr8.js");
|
|
2285
|
+
try {
|
|
2286
|
+
initialSessionId = await createBridgeSession({
|
|
2287
|
+
environmentId,
|
|
2288
|
+
title: name,
|
|
2289
|
+
events: [],
|
|
2290
|
+
gitRepoUrl,
|
|
2291
|
+
branch,
|
|
2292
|
+
signal: controller.signal,
|
|
2293
|
+
baseUrl,
|
|
2294
|
+
getAccessToken: getBridgeAccessToken,
|
|
2295
|
+
permissionMode
|
|
2296
|
+
});
|
|
2297
|
+
if (initialSessionId) {
|
|
2298
|
+
logForDebugging(`[bridge:init] Created initial session ${initialSessionId}`);
|
|
2299
|
+
}
|
|
2300
|
+
} catch (err) {
|
|
2301
|
+
logForDebugging(`[bridge:init] Session creation failed (non-fatal): ${errorMessage(err)}`);
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
let pointerRefreshTimer = null;
|
|
2305
|
+
if (initialSessionId && spawnMode === "single-session") {
|
|
2306
|
+
const { writeBridgePointer } = await import("./chunk-fxpsa506.js");
|
|
2307
|
+
const pointerPayload = {
|
|
2308
|
+
sessionId: initialSessionId,
|
|
2309
|
+
environmentId,
|
|
2310
|
+
source: "standalone"
|
|
2311
|
+
};
|
|
2312
|
+
await writeBridgePointer(config.dir, pointerPayload);
|
|
2313
|
+
pointerRefreshTimer = setInterval(writeBridgePointer, 3600000, config.dir, pointerPayload);
|
|
2314
|
+
pointerRefreshTimer.unref?.();
|
|
2315
|
+
}
|
|
2316
|
+
try {
|
|
2317
|
+
await runBridgeLoop(config, environmentId, environmentSecret, api, spawner, logger, controller.signal, undefined, initialSessionId ?? undefined, async () => {
|
|
2318
|
+
clearOAuthTokenCache();
|
|
2319
|
+
await checkAndRefreshOAuthTokenIfNeeded();
|
|
2320
|
+
return getBridgeAccessToken();
|
|
2321
|
+
});
|
|
2322
|
+
} finally {
|
|
2323
|
+
if (pointerRefreshTimer !== null) {
|
|
2324
|
+
clearInterval(pointerRefreshTimer);
|
|
2325
|
+
}
|
|
2326
|
+
process.off("SIGINT", onSigint);
|
|
2327
|
+
process.off("SIGTERM", onSigterm);
|
|
2328
|
+
process.stdin.off("data", onStdinData);
|
|
2329
|
+
if (process.stdin.isTTY) {
|
|
2330
|
+
process.stdin.setRawMode(false);
|
|
2331
|
+
}
|
|
2332
|
+
process.stdin.pause();
|
|
2333
|
+
}
|
|
2334
|
+
process.exit(0);
|
|
2335
|
+
}
|
|
2336
|
+
|
|
1414
2337
|
class BridgeHeadlessPermanentError extends Error {
|
|
1415
2338
|
constructor(message) {
|
|
1416
2339
|
super(message);
|
|
@@ -1423,9 +2346,9 @@ async function runBridgeHeadless(opts, signal) {
|
|
|
1423
2346
|
const { setOriginalCwd, setCwdState } = await import("./chunk-m1tjr9xq.js");
|
|
1424
2347
|
setOriginalCwd(dir);
|
|
1425
2348
|
setCwdState(dir);
|
|
1426
|
-
const { enableConfigs, checkHasTrustDialogAccepted } = await import("./chunk-
|
|
2349
|
+
const { enableConfigs, checkHasTrustDialogAccepted } = await import("./chunk-cbssxph9.js");
|
|
1427
2350
|
enableConfigs();
|
|
1428
|
-
const { initSinks } = await import("./chunk-
|
|
2351
|
+
const { initSinks } = await import("./chunk-sfmxv59p.js");
|
|
1429
2352
|
initSinks();
|
|
1430
2353
|
if (!checkHasTrustDialogAccepted()) {
|
|
1431
2354
|
throw new BridgeHeadlessPermanentError(`Workspace not trusted: ${dir}. Run \`claude\` in that directory first to accept the trust dialog.`);
|
|
@@ -1433,14 +2356,14 @@ async function runBridgeHeadless(opts, signal) {
|
|
|
1433
2356
|
if (!opts.getAccessToken()) {
|
|
1434
2357
|
throw new Error(BRIDGE_LOGIN_ERROR);
|
|
1435
2358
|
}
|
|
1436
|
-
const { getBridgeBaseUrl } = await import("./chunk-
|
|
2359
|
+
const { getBridgeBaseUrl } = await import("./chunk-bec4mkst.js");
|
|
1437
2360
|
const baseUrl = getBridgeBaseUrl();
|
|
1438
2361
|
if (baseUrl.startsWith("http://") && !baseUrl.includes("localhost") && !baseUrl.includes("127.0.0.1")) {
|
|
1439
2362
|
throw new BridgeHeadlessPermanentError("Remote Control base URL uses HTTP. Only HTTPS or localhost HTTP is allowed.");
|
|
1440
2363
|
}
|
|
1441
2364
|
const sessionIngressUrl = process.env.CLAUDE_BRIDGE_SESSION_INGRESS_URL || baseUrl;
|
|
1442
2365
|
const { getBranch, getRemoteUrl, findGitRoot } = await import("./chunk-dy8tttdp.js");
|
|
1443
|
-
const { hasWorktreeCreateHook } = await import("./chunk-
|
|
2366
|
+
const { hasWorktreeCreateHook } = await import("./chunk-6kwx0aa4.js");
|
|
1444
2367
|
if (opts.spawnMode === "worktree") {
|
|
1445
2368
|
const worktreeAvailable = hasWorktreeCreateHook() || findGitRoot(dir) !== null;
|
|
1446
2369
|
if (!worktreeAvailable) {
|
|
@@ -1497,7 +2420,7 @@ async function runBridgeHeadless(opts, signal) {
|
|
|
1497
2420
|
logger.printBanner(config, environmentId);
|
|
1498
2421
|
let initialSessionId;
|
|
1499
2422
|
if (opts.createSessionOnStart) {
|
|
1500
|
-
const { createBridgeSession } = await import("./chunk-
|
|
2423
|
+
const { createBridgeSession } = await import("./chunk-01pfrqr8.js");
|
|
1501
2424
|
try {
|
|
1502
2425
|
const sid = await createBridgeSession({
|
|
1503
2426
|
environmentId,
|
|
@@ -1550,72 +2473,4 @@ function createHeadlessBridgeLogger(log) {
|
|
|
1550
2473
|
};
|
|
1551
2474
|
}
|
|
1552
2475
|
|
|
1553
|
-
|
|
1554
|
-
init_auth();
|
|
1555
|
-
init_errors();
|
|
1556
|
-
var EXIT_CODE_PERMANENT = 78;
|
|
1557
|
-
var EXIT_CODE_TRANSIENT = 1;
|
|
1558
|
-
async function runDaemonWorker(kind) {
|
|
1559
|
-
if (!kind) {
|
|
1560
|
-
console.error("Error: --daemon-worker requires a worker kind");
|
|
1561
|
-
process.exitCode = EXIT_CODE_PERMANENT;
|
|
1562
|
-
return;
|
|
1563
|
-
}
|
|
1564
|
-
switch (kind) {
|
|
1565
|
-
case "remoteControl":
|
|
1566
|
-
await runRemoteControlWorker();
|
|
1567
|
-
break;
|
|
1568
|
-
default:
|
|
1569
|
-
console.error(`Error: unknown daemon worker kind '${kind}'`);
|
|
1570
|
-
process.exitCode = EXIT_CODE_PERMANENT;
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
async function runRemoteControlWorker() {
|
|
1574
|
-
const dir = process.env.DAEMON_WORKER_DIR || resolve2(".");
|
|
1575
|
-
const name = process.env.DAEMON_WORKER_NAME || undefined;
|
|
1576
|
-
const spawnMode = process.env.DAEMON_WORKER_SPAWN_MODE || "same-dir";
|
|
1577
|
-
const capacity = parseInt(process.env.DAEMON_WORKER_CAPACITY || "4", 10);
|
|
1578
|
-
const permissionMode = process.env.DAEMON_WORKER_PERMISSION || undefined;
|
|
1579
|
-
const sandbox = process.env.DAEMON_WORKER_SANDBOX === "1";
|
|
1580
|
-
const sessionTimeoutMs = process.env.DAEMON_WORKER_TIMEOUT_MS ? parseInt(process.env.DAEMON_WORKER_TIMEOUT_MS, 10) : undefined;
|
|
1581
|
-
const createSessionOnStart = process.env.DAEMON_WORKER_CREATE_SESSION !== "0";
|
|
1582
|
-
const controller = new AbortController;
|
|
1583
|
-
const onSignal = () => controller.abort();
|
|
1584
|
-
process.on("SIGTERM", onSignal);
|
|
1585
|
-
process.on("SIGINT", onSignal);
|
|
1586
|
-
const opts = {
|
|
1587
|
-
dir,
|
|
1588
|
-
name,
|
|
1589
|
-
spawnMode,
|
|
1590
|
-
capacity,
|
|
1591
|
-
permissionMode,
|
|
1592
|
-
sandbox,
|
|
1593
|
-
sessionTimeoutMs,
|
|
1594
|
-
createSessionOnStart,
|
|
1595
|
-
getAccessToken: () => getClaudeAIOAuthTokens()?.accessToken,
|
|
1596
|
-
onAuth401: async (_failedToken) => {
|
|
1597
|
-
const tokens = getClaudeAIOAuthTokens();
|
|
1598
|
-
return !!tokens?.accessToken;
|
|
1599
|
-
},
|
|
1600
|
-
log: (s) => {
|
|
1601
|
-
console.log(`[remoteControl] ${s}`);
|
|
1602
|
-
}
|
|
1603
|
-
};
|
|
1604
|
-
try {
|
|
1605
|
-
await runBridgeHeadless(opts, controller.signal);
|
|
1606
|
-
} catch (err) {
|
|
1607
|
-
if (err instanceof BridgeHeadlessPermanentError) {
|
|
1608
|
-
console.error(`[remoteControl] permanent error: ${err.message}`);
|
|
1609
|
-
process.exitCode = EXIT_CODE_PERMANENT;
|
|
1610
|
-
} else {
|
|
1611
|
-
console.error(`[remoteControl] transient error: ${errorMessage(err)}`);
|
|
1612
|
-
process.exitCode = EXIT_CODE_TRANSIENT;
|
|
1613
|
-
}
|
|
1614
|
-
} finally {
|
|
1615
|
-
process.off("SIGTERM", onSignal);
|
|
1616
|
-
process.off("SIGINT", onSignal);
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
export {
|
|
1620
|
-
runDaemonWorker
|
|
1621
|
-
};
|
|
2476
|
+
export { runBridgeLoop, isConnectionError, isServerError, parseArgs, bridgeMain, BridgeHeadlessPermanentError, runBridgeHeadless };
|