@dev-anywhere/proxy 0.0.1
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/LICENSE +21 -0
- package/README.md +113 -0
- package/assets/fonts/sarasa-fixed-sc/00c59ca448ea49756112128d6a43b127.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/011decfe3e67ab099af86e86a15e4f12.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/0133a2c4604dd809764dc749af72dc79.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/02928e8a3c2bf5ae6677bdf552664108.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/02eb3185bd0fd343bb2ae5a13260e805.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/04248a8ea5cd1204f875bc7661f1096c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/059276218fbb9297f1668b1e37611796.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/05c6ae1e7580a1eff4be47341a155474.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/0681e7debe2dd44962f142b5c454676e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/06ec078ae766d56e900c2837556eaa21.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/0765562d298aed694539cfcc4e26537c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/090128a865f81baab82dfa2776ef9d39.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/098ff8830b5d779d8656e7ca93253c12.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/09b4eba4363eb15092534724123a78f2.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/0a32f2f6ed1a99ffa5e833e6891d1f82.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/0c1c080e1ac07d6a49dca531de9725a4.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/0d022c7c63996b8e5dc70b7fd7b0689d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/0e7c7848d16895e68f79a55fd7b8c29d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1021bfe59ce4f905808dd5c3ea3fecc4.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/103c3dd7a5ee0d3be6cab3d04bd40c96.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/104a138cdd04cdbf3f786d2abeeed70a.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/105c39ea073d59b2e2f5e16ca68b2d71.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1113c82b3ef6588e32cf20d7bd723355.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1284d569e10290971bf3200bf4ddf94f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/13401a392cffb9f2f7254e91bf44a106.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1364ce313965ebf440ff2f0311cd4c83.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1641d3bae07fd8d369349f78dd6c9c40.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/187edd679db5112bd2699bf1adad4a32.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1918eaee7987c39db5198d637623a538.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1aa2711726a364e3ea6fb7ca8a95d950.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1ab01fa7bd43e3242f3c9d5b6f73dc90.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1ae20f7adc1aa93e95c1842ce3b0c329.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1c16e221d67a71a270f700e31e406230.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1c40fcc59ed13b4b861844a8feb8205b.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1d0e76f87701ab6daecb38b5aff5e35c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1d18a292fa9adaae7261de62ab3d5b83.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/1f99a7c91c71e6303282aa66c99c6670.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/20e0dab161488105b7fa7852470503b1.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/210b0efe54084a98b88028a6f3f35b0d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/2116632ed1a3bdf3bf0106e1703c0781.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/22b3a91f654e334e2e7fbe3780f67764.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/24c5d226f02d96f03a7d050b0fdfd1d1.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/254d3a725f55d7111abbafa05858f2d6.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/26506a3ce2dbbfbfde40d11d65230272.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/268f0d094899c94260e840ac55320e20.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/277fc44cecacaf16cefce4681495bdce.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/27b773ac20ca5fa1bdd09d2109dfd5dc.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/2803a14ad17e6753704504009dad3333.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/2a0d78f9037bc2b5846bb4bcb42bfedc.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/2ac0bf1c4f9ad6e69bc01259f6e17058.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/2b01deb59e13f60e307d370b674b7b3b.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/2b74162a48979b6282e4893199f1346d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/2d11bafb03690fc87494426325d90414.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/2dbf9030d7fa41019c78d5a717726261.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/30ce0c911f54ecd538247018d5289bb6.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/31bc5b0f3eb1e0f0845f37ae39f1a43e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/31cdb9be17f46537a2958ba142c9765f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/31d182ea6704bc50689becec8f417674.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/31f6abd51bf73062085ad82253fc302d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/32d1abf03444175b162eadfef3a8e937.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/3397f69dc93262cf856a7c836fb33cb1.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/349035f271962ecacc5fa5cd56930c44.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/3525d0f8fb4e24d09024d35992e9095d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/393876ac692b10f5ab7190590b062745.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/3bf37030a116e7377dcaf47356f08ef1.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/3c953d2e03b93436ee5c522ce3a27e1a.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/3fe795fd56b36a734a31613b1fed5441.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/401e69f55dc74b2e6fb774dcbba811da.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/404518f4b01a2fe38462bd04bfd76d35.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/404fe750213a60cbd07016ab43aacb71.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/41491053defe7688d8d53bfc313c6974.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/420121d03c1887873aa0eaa37a534e0c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/42dffba83a406a85b208fba09e465c4d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/44b74f10fbe44658d1acb6627b3a8b94.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/450be7e82a27dca52c8c1c582fcf182d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/454ab2db1835c113f7b99f366a627247.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/45ec91cf9684c378adb99130acd6477e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/4610b2980f41ab106bfe74b6951b34bb.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/46cad9f32908fa67609b51b74bc5693b.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/4a51964240b7e2c93d276dfef3794b5b.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/4b800716e356efb3e4b429085bcdb61a.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/4d8dad1e6c57ca3629d21230981cbb0e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/4e625675fc1cb257e07a9ff2e331a9fe.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/4f2207b0342d6e2dd4290614e53cf0c5.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/50b0854263c0cf842979ce447020051a.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/552fe6d8e7144695a8fb38b8760295df.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/56175fa000590397d0ec4074c1f1e9f2.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/570f8c343327a818e4f0b0c4962ba4a1.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/579fbe9abeb15d0e96ee4770e6719719.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/57c37c54a9699166f03c0e6f871e6735.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/58e7c2324d8d292d58534d9f236f1552.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/59584acacc4c1852a6814f7e389ea191.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/598705446ef817283f04a709e974d473.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/59e93050018a5206bebf980e0f52fa78.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/5c129ed60734fd511937f3e72a07f936.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/5c40c780ef301baacb66efb9750e258b.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/5d1a982cb896e55ee96ada379c4a1d0c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/5eba8579b88524026f6f6ec30cb81baa.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/601ad6234d43753b4e3efe8486b315c1.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/603b9e361dc9dd05250221356255a176.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/6133adaaf70a9467188b7e9e34039480.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/6158d9e8e90c6a553485c49e8adc991c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/63c707f20b4af887788bfe53c6eee3ec.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/63c8475e9aa8acc0033fde9f792b8acf.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/64466c4274848cdee185275fb52660df.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/652d2da7b3c1dc0a70efdbb85e820055.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/6653b549c4d40a370724f6f32223e8a7.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/6734957b7e0bdd9f9e66cf24be7dc058.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/689a7d17cf5f82d7f148d660a21df759.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/6a864ec605e3b28cfdebf1d8fab2451e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/6b4101e34138d999fd3ba9d2684ddebf.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/6b70494a68af284b2f21967109bf0311.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/6dde2f1140ce0a20159b7c1625bc3b45.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/6faa59cc7dff0a7751347b5baa8a5015.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/70364e9456886f13e2d5c9674ffb08f4.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/736f91321c58d7a9316ea9cddf4d83a7.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/7458762c6210651559b6019d5508ae2c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/7460d9b012420e17a4bbfd2cb6796468.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/75a0c446c8bf8e4051d7cd65ed17e114.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/77ee59e7be1d66b59e87880e9c283491.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/782cda0bc3f24b5553f93c3d5b6fe581.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/78e84df88175c20e7f2562e4cdaad257.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/79e46c399f5e7383f853281b499269ee.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/7acff1baf69f6628c6372be0554191f1.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/7c5323aa737b291adacceecedac3e56a.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/7c9c9097a200464fd8ccec8eafc80178.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/7f77666d943dd01e947a2e35ffed945f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/7f7e1463e29e6528378ed51589c4ebc0.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/80d4285084348d043a775221eb1c93b1.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/81258e5d1abdeafe44be69ad32f74c19.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/83a8da8e1de25f9eb39fe9d980e04a5d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/83be0efd62f30539368d37cf7529f95c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/84266b5a67707c745ce2c7101c559735.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/84905ac6e9d149bcacc34e2a71b82a67.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/852ae9183bf83dc2a2414290d3aa0236.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/85f5aa76f5f1e09b6852af36ec781960.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/860a1c6d20d4e631bd8e80735f5f3581.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/8afa5d1ab930027046ad09ec6349ab31.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/8b81739358772947619c9a58575c863a.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/8b9212f06a935902e9a4d8ad435c6a6e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/8cc210fa91949bb44ea2bf607991b7bf.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/8f0b853b5728d58ac137870b3fd7ab02.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/8f0cdbad1758d5f68a48effbca6f74f8.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/8f5261cd877891595879479ee2440ae4.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/910a758ea12189f5a6a1e025fca33c5a.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/911993a058e817f1a231fbac27b3781c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/91daedcfd8d0745222bf82c1fd310a33.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/943d6560828548692eeb4a533aa89494.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/945d0c206221572e76cc03fdd474685a.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/946411ab6f4f655273da613188359c06.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/9514ffa1f75fb1ad995392125c963b1b.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/971106de1248ba224fbfe50cf5c8a3dc.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/9714a586ded7b76747709b1fbe32c344.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/98b75b8dba788b62ef809337088ef030.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/98b7b436090e7874e2affbfd4ad28fd9.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/9a952ea6da219d92841b5503d43c746e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/a0eabe8e58be580b4a5b0db87e3d282b.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/a11e9313ebf3147b1622c47e8cb1bacd.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/a2030c8eca8b7b75cf8d6fbbf29940cb.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/a2e0e75587d53e7e6c50da180ad76815.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/a3e96d6e1a2bdfe27d35140d1cb84600.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/a645858417844eaeb35eec60463a8758.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/a691a029b0ffe2f516dc0ba2680a7b24.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/a8731b06984003e15944af2045bac0ba.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/a8b5a37da8e22efc24e1d51e3dd133f2.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/aa4030d4e6a032ebd37ab080a87f0b15.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ab0f237ab351bf258b3579011285bdb2.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ac3a84416815f292543ac24c909b8f53.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ac4188ae92c726da6cce789716706455.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ac9e1d7b7d0e738c0965e0c37a171594.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ad0efa49e97c104bb4f7d2a5d15eabef.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ad3ac003a089fb00191c1e00aa56061e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ae481a90ce6dc650ffb8e777ab9fc089.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/aef606698752748d6b411ab230cd1760.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/aefc6f1da14ea5d5daf751fbf71b29a2.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/afe37b0740a4f9cc8f6a8aa5515a7826.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b1a36f37842e3cd3981ee51b5d9b3edc.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b3791b3fb0de0352fb1265cb02a021fb.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b37e11130ac85f74432248a20b134622.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b39422dfd00810613d15bd6572b05aa3.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b3e514ad857c99211370e0bc572f776f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b4bd13b2c8086a5320644893d557b747.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b6b23d001929bf0450f2ee16e9236f1f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b78cefc4f6a28eb5b5dd551dd873bcbd.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b7e35bfc1e67312ea4f7399d87101681.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b8493cdc783af55e9c50fc16c9b55bc3.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/b8e187dc66c9864eb348ee91951eacdf.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/bbf72353d229f1e5d6ccea65888451fe.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/bc6f1bd38107e5c152f4d568e75b3cf0.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/bc884e50f2cf284e61c6cc8274bb3cc5.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/bd0f4de744997828af2f5be5ec11428f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/bf85faaa5f8efc2e1023f5e9504c0d4e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/c509336eb0f6e35088064f15ddddc844.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/c5dd4097aac455d055badef188473371.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/c66f535c634eadaf34e0fe041672ae4b.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/c693a3ac340ea557c7ee39ddef0451a2.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/c8e0baa6e08346d410255ea827a8be27.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ca8a49ee7846219a65d63ee1ec51c194.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/cd52152b8b48869f0fb1175983d9a505.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/cea8a7b71e661b383a7dc2f15cc2f47a.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d2e284352932a735dda55727c0879153.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d2fd9591ebfd0e779de7682d2745dbbb.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d4a14f2651525d4affbbb753b6dbdf07.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d5caf76d2720e294f4d0b1625f01ec9c.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d5d463ae4788148f67a28de9ec4c1dca.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d6e2c1e4c4b88bc14079e9c4a7549497.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d70ea44ff65a30a175801cb104f83448.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d750b314131793e148b4ebf50ffb91af.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d7ae616c789f29be08782214e0288a0d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/d8ae70630c929796cb0364e5202037e4.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/da5bdab3ae018a4c1207bd67ab854bc2.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/dab7b758f386eaae246f675ec7e23f0f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/db1cc9bd868a6ff45d7bbe5b28d4b8d7.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/dc34cae5db8221efc393ea494597b1ec.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/dd32cf24e261a9aa261b7e196da33f2d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/dda618cc791e2c20645ca5b7843c50dc.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/df9de632322bb3378c647420760aab61.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e00c9c693f510281ead88131d09c18d2.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e02d34cae25f04c920a31db2c80d1d8f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e22efb34fb5fe61f5b45504d76d20781.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e25f5e7e1d5b88a59d981b5f6f669283.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e3bb4be954796cb47ac6851ab724ecaf.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e3bdeda10d9131256fad8417fd1da09f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e73e3950ff542ab97969b032c1f7241f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e78879cfa489561d3ec6eef16a4a0a4d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e811136959f0512a25a18acc520970b5.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/e9a7cf7d3d15fb2e50730469b07f2e39.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/eb514af63c1e9b14ccec7dee432b8edc.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ed0b4344be5485ee0b0c207f28762fb8.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/edf89add9339773b26c1c2dd2244a179.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ef8de64aca34834c6f110f4adc7515bd.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f0438b1823af0a0de674c239fa03eaba.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f0604027051cb387c2f85940dfff3755.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f065b514c78eb2344c42e496865369a9.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f0d97a6f8e1880316015bc2283d0f156.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f1834c69e3074e71093d17a68b9d4d7d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f29b465128cba69d5e68235945cd3edd.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f330fd41c2fbf0ae89bb98047c08d516.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f383e78159d65c11032dc8b8d9c360f3.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f647c059126fa5bf24355dcbfed09c4f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f6af810265a209ab307886171ded4113.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f74844d2228da8984fe156b5b9c28acc.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f7f2840050c367f26cfbc2b81c3a5fad.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f85435b23bb50124e045f50cfe54dd3e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f865cd6ba4d22d8d61fce2a2d63be7dc.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/f8a66c1ab7db90820de697f664ea136d.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/fa6cf45901b333e63b3eabc045783c69.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/fa827d13030f9366a57edbfc22ce4336.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/fb6ac0e1252b3d366009d4f4ffeab4fc.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/fbb64faabca9f28743b2d0d5dc448e5f.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/fd299dbef627ab6738d61d4e4bac56e2.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/fd8cd455b632147c1758bfb9bd0ba42e.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/ff8cf784cc8ef060bf9d2dc7e698b451.woff2 +0 -0
- package/assets/fonts/sarasa-fixed-sc/result.css +20 -0
- package/dist/chunk-2Q3Z3ICU.js +155 -0
- package/dist/chunk-2Q3Z3ICU.js.map +1 -0
- package/dist/chunk-6O6JTF24.js +318 -0
- package/dist/chunk-6O6JTF24.js.map +1 -0
- package/dist/chunk-OO64L35C.js +34 -0
- package/dist/chunk-OO64L35C.js.map +1 -0
- package/dist/chunk-QJ5CQDK7.js +1038 -0
- package/dist/chunk-QJ5CQDK7.js.map +1 -0
- package/dist/chunk-UGFYGF3Y.js +142 -0
- package/dist/chunk-UGFYGF3Y.js.map +1 -0
- package/dist/chunk-ZUWAB67J.js +55 -0
- package/dist/chunk-ZUWAB67J.js.map +1 -0
- package/dist/index.js +279 -0
- package/dist/index.js.map +1 -0
- package/dist/serve.js +4375 -0
- package/dist/serve.js.map +1 -0
- package/dist/session-worker.js +357 -0
- package/dist/session-worker.js.map +1 -0
- package/dist/terminal-TTRA2VJY.js +671 -0
- package/dist/terminal-TTRA2VJY.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,671 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
daemonEnvArgs
|
|
4
|
+
} from "./chunk-OO64L35C.js";
|
|
5
|
+
import {
|
|
6
|
+
createFSM,
|
|
7
|
+
extractOscSequences,
|
|
8
|
+
extractOscSignals,
|
|
9
|
+
shouldReleaseApprovalWait,
|
|
10
|
+
stateAfterApprovalRelease,
|
|
11
|
+
terminalLogger
|
|
12
|
+
} from "./chunk-UGFYGF3Y.js";
|
|
13
|
+
import {
|
|
14
|
+
spawnScript
|
|
15
|
+
} from "./chunk-ZUWAB67J.js";
|
|
16
|
+
import {
|
|
17
|
+
CLAUDE_PROVIDER,
|
|
18
|
+
CODEX_PROVIDER
|
|
19
|
+
} from "./chunk-6O6JTF24.js";
|
|
20
|
+
import {
|
|
21
|
+
SERVICE_LOG_PATH,
|
|
22
|
+
SOCK_PATH,
|
|
23
|
+
STOPPED_PATH,
|
|
24
|
+
createIpcReader,
|
|
25
|
+
encodeBinaryIpcFrame,
|
|
26
|
+
serializeIpc,
|
|
27
|
+
tildify
|
|
28
|
+
} from "./chunk-QJ5CQDK7.js";
|
|
29
|
+
|
|
30
|
+
// src/terminal.ts
|
|
31
|
+
import { connect } from "net";
|
|
32
|
+
import { existsSync, unlinkSync } from "fs";
|
|
33
|
+
import { setTimeout as sleep } from "timers/promises";
|
|
34
|
+
|
|
35
|
+
// src/terminal/tty.ts
|
|
36
|
+
function readTtySize(stream) {
|
|
37
|
+
const { columns, rows } = stream;
|
|
38
|
+
if (columns === void 0 || rows === void 0) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
"stdout is not an interactive TTY (columns/rows undefined); dev-anywhere requires running in a real terminal"
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return { cols: columns, rows };
|
|
44
|
+
}
|
|
45
|
+
function notifyUser(message) {
|
|
46
|
+
process.stderr.write(`\x1B]9;${message}\x07`);
|
|
47
|
+
}
|
|
48
|
+
function restoreHostTerminalModes(stream) {
|
|
49
|
+
if (!stream.isTTY) return;
|
|
50
|
+
const restoreSequences = [
|
|
51
|
+
"\x1B[?1l",
|
|
52
|
+
// application cursor keys off
|
|
53
|
+
"\x1B>",
|
|
54
|
+
// application keypad off
|
|
55
|
+
"\x1B[?1000l",
|
|
56
|
+
"\x1B[?1002l",
|
|
57
|
+
"\x1B[?1003l",
|
|
58
|
+
"\x1B[?1004l",
|
|
59
|
+
"\x1B[?1006l",
|
|
60
|
+
"\x1B[?1015l",
|
|
61
|
+
"\x1B[?2004l",
|
|
62
|
+
// bracketed paste off
|
|
63
|
+
"\x1B[>4;0m",
|
|
64
|
+
// xterm modifyOtherKeys off
|
|
65
|
+
"\x1B[<u"
|
|
66
|
+
// kitty keyboard protocol off
|
|
67
|
+
].join("");
|
|
68
|
+
stream.write(restoreSequences);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/terminal/pty-manager.ts
|
|
72
|
+
import * as pty from "node-pty";
|
|
73
|
+
var PtyManager = class {
|
|
74
|
+
child = null;
|
|
75
|
+
provider;
|
|
76
|
+
providerArgs;
|
|
77
|
+
cwd;
|
|
78
|
+
hook;
|
|
79
|
+
tap;
|
|
80
|
+
stdin;
|
|
81
|
+
stdout;
|
|
82
|
+
onSessionExit;
|
|
83
|
+
onResize;
|
|
84
|
+
constructor(options) {
|
|
85
|
+
this.provider = options.provider;
|
|
86
|
+
this.providerArgs = options.providerArgs;
|
|
87
|
+
this.cwd = options.cwd;
|
|
88
|
+
this.hook = options.hook;
|
|
89
|
+
this.tap = options.tap;
|
|
90
|
+
this.stdin = options.stdin;
|
|
91
|
+
this.stdout = options.stdout;
|
|
92
|
+
this.onSessionExit = options.onSessionExit;
|
|
93
|
+
this.onResize = options.onResize;
|
|
94
|
+
}
|
|
95
|
+
start() {
|
|
96
|
+
const { cols, rows } = readTtySize(this.stdout);
|
|
97
|
+
const command = this.provider.buildTerminalCommand(
|
|
98
|
+
{ args: this.providerArgs, hook: this.hook },
|
|
99
|
+
process.env
|
|
100
|
+
);
|
|
101
|
+
const child = pty.spawn(command.command, command.args, {
|
|
102
|
+
name: process.env.TERM ?? "xterm-256color",
|
|
103
|
+
cols,
|
|
104
|
+
rows,
|
|
105
|
+
cwd: this.cwd,
|
|
106
|
+
env: command.env
|
|
107
|
+
});
|
|
108
|
+
this.child = child;
|
|
109
|
+
const isInteractive = this.stdin.isTTY === true;
|
|
110
|
+
if (isInteractive) {
|
|
111
|
+
this.stdin.setRawMode(true);
|
|
112
|
+
}
|
|
113
|
+
this.stdin.resume();
|
|
114
|
+
this.stdin.on("data", (data) => {
|
|
115
|
+
child.write(data.toString());
|
|
116
|
+
});
|
|
117
|
+
child.onData((data) => this.handleData(data));
|
|
118
|
+
let resizeTimer = null;
|
|
119
|
+
this.stdout.on("resize", () => {
|
|
120
|
+
if (resizeTimer) clearTimeout(resizeTimer);
|
|
121
|
+
resizeTimer = setTimeout(() => {
|
|
122
|
+
const { cols: newCols, rows: newRows } = readTtySize(this.stdout);
|
|
123
|
+
child.resize(newCols, newRows);
|
|
124
|
+
this.onResize?.(newCols, newRows);
|
|
125
|
+
}, 50);
|
|
126
|
+
});
|
|
127
|
+
child.onExit(({ exitCode, signal }) => {
|
|
128
|
+
if (isInteractive) {
|
|
129
|
+
try {
|
|
130
|
+
this.stdin.setRawMode(false);
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
restoreHostTerminalModes(this.stdout);
|
|
135
|
+
const code = signal ? 128 + signal : exitCode;
|
|
136
|
+
this.onSessionExit?.(code);
|
|
137
|
+
});
|
|
138
|
+
this.stdin.on("end", () => {
|
|
139
|
+
child.write("");
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* PTY 数据到达时的统一处理:OSC 9 修复 + 输出到终端 + 传给 tap
|
|
144
|
+
*/
|
|
145
|
+
handleData(data) {
|
|
146
|
+
const fixed = data.replace(
|
|
147
|
+
// eslint-disable-next-line no-control-regex
|
|
148
|
+
/\x1b\]9;([\s\S]*?)\x07/g,
|
|
149
|
+
(_, content) => `\x1B]9;${content.replace(/\r\n/g, "\n")}\x07`
|
|
150
|
+
);
|
|
151
|
+
this.stdout.write(fixed);
|
|
152
|
+
this.tap(data);
|
|
153
|
+
}
|
|
154
|
+
// 向 PTY 子进程写入数据,用于远程输入注入
|
|
155
|
+
write(data) {
|
|
156
|
+
this.child?.write(data);
|
|
157
|
+
}
|
|
158
|
+
cleanup(exitCode) {
|
|
159
|
+
if (this.stdin.isTTY) {
|
|
160
|
+
try {
|
|
161
|
+
this.stdin.setRawMode(false);
|
|
162
|
+
} catch {
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
restoreHostTerminalModes(this.stdout);
|
|
166
|
+
if (this.child) {
|
|
167
|
+
try {
|
|
168
|
+
this.child.kill();
|
|
169
|
+
} catch {
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
this.onSessionExit?.(exitCode);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// src/terminal/cwd.ts
|
|
177
|
+
import { statSync } from "fs";
|
|
178
|
+
function isDirectory(path) {
|
|
179
|
+
if (!path) return false;
|
|
180
|
+
try {
|
|
181
|
+
return statSync(path).isDirectory();
|
|
182
|
+
} catch {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function resolveTerminalCwd(env = process.env) {
|
|
187
|
+
const candidates = [env.DEV_ANYWHERE_CWD, env.INIT_CWD, env.PWD, process.cwd()];
|
|
188
|
+
return candidates.find(isDirectory) ?? process.cwd();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/terminal.ts
|
|
192
|
+
import pkg from "@xterm/headless";
|
|
193
|
+
import { SerializeAddon } from "@xterm/addon-serialize";
|
|
194
|
+
import { UnicodeGraphemesAddon } from "@xterm/addon-unicode-graphemes";
|
|
195
|
+
|
|
196
|
+
// src/terminal/state.ts
|
|
197
|
+
var TerminalState = {
|
|
198
|
+
INIT: "init",
|
|
199
|
+
CONNECTING_SERVICE: "connecting_service",
|
|
200
|
+
CREATING_SESSION: "creating_session",
|
|
201
|
+
RUNNING: "running",
|
|
202
|
+
RECONNECTING: "reconnecting",
|
|
203
|
+
EXITED: "exited"
|
|
204
|
+
};
|
|
205
|
+
var TERMINAL_TRANSITIONS = {
|
|
206
|
+
init: ["connecting_service"],
|
|
207
|
+
connecting_service: ["creating_session", "exited"],
|
|
208
|
+
creating_session: ["running", "reconnecting", "exited"],
|
|
209
|
+
running: ["reconnecting", "exited"],
|
|
210
|
+
reconnecting: ["creating_session", "running", "exited"],
|
|
211
|
+
exited: []
|
|
212
|
+
};
|
|
213
|
+
function createExitHandler(deps) {
|
|
214
|
+
const exit = deps.exit ?? ((code) => process.exit(code));
|
|
215
|
+
return (code) => {
|
|
216
|
+
if (deps.fsm.is(TerminalState.EXITED)) return;
|
|
217
|
+
deps.fsm.transitionTo(TerminalState.EXITED);
|
|
218
|
+
const timer = deps.getIdleCheckTimer();
|
|
219
|
+
if (timer) clearInterval(timer);
|
|
220
|
+
const socket = deps.getSocket();
|
|
221
|
+
const sessionId = deps.getSessionId();
|
|
222
|
+
if (socket.writable && sessionId) {
|
|
223
|
+
socket.end(serializeIpc({ type: "pty_deregister", sessionId }), () => exit(code));
|
|
224
|
+
} else {
|
|
225
|
+
exit(code);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/terminal.ts
|
|
231
|
+
var { Terminal: HeadlessTerminal } = pkg;
|
|
232
|
+
var ENSURE_SERVICE_MAX_RETRIES = 20;
|
|
233
|
+
var ENSURE_SERVICE_INITIAL_DELAY_MS = 100;
|
|
234
|
+
var ENSURE_SERVICE_MAX_DELAY_MS = 2e3;
|
|
235
|
+
var WAIT_FOR_MESSAGE_TIMEOUT_MS = 1e4;
|
|
236
|
+
var IDLE_CHECK_INTERVAL_MS = 3e3;
|
|
237
|
+
var IDLE_THRESHOLD_MS = 3e3;
|
|
238
|
+
var RECONNECT_INITIAL_DELAY_MS = 1e3;
|
|
239
|
+
var RECONNECT_MAX_DELAY_MS = 5e3;
|
|
240
|
+
var SPAWN_FAILURE_THRESHOLD = 3;
|
|
241
|
+
var PROVIDERS = {
|
|
242
|
+
claude: CLAUDE_PROVIDER,
|
|
243
|
+
codex: CODEX_PROVIDER
|
|
244
|
+
};
|
|
245
|
+
function tryConnect(sockPath) {
|
|
246
|
+
return new Promise((resolve) => {
|
|
247
|
+
const s = connect(sockPath);
|
|
248
|
+
s.on("connect", () => resolve(s));
|
|
249
|
+
s.on("error", () => resolve(null));
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
async function ensureService(autoStart = true) {
|
|
253
|
+
const existing = await tryConnect(SOCK_PATH);
|
|
254
|
+
if (existing) {
|
|
255
|
+
terminalLogger.info("Connected to existing service");
|
|
256
|
+
return existing;
|
|
257
|
+
}
|
|
258
|
+
if (!autoStart) throw new Error("Service is not running");
|
|
259
|
+
if (existsSync(STOPPED_PATH)) unlinkSync(STOPPED_PATH);
|
|
260
|
+
terminalLogger.info("Auto-starting serve daemon");
|
|
261
|
+
const child = spawnScript(new URL("./serve", import.meta.url), daemonEnvArgs(), { logger: terminalLogger });
|
|
262
|
+
let childFailed = false;
|
|
263
|
+
let exitCode = null;
|
|
264
|
+
let exitSignal = null;
|
|
265
|
+
let spawnError = null;
|
|
266
|
+
child.once("exit", (code, signal) => {
|
|
267
|
+
childFailed = true;
|
|
268
|
+
exitCode = code;
|
|
269
|
+
exitSignal = signal;
|
|
270
|
+
});
|
|
271
|
+
child.once("error", (err) => {
|
|
272
|
+
childFailed = true;
|
|
273
|
+
spawnError = err;
|
|
274
|
+
});
|
|
275
|
+
for (let i = 0; i < ENSURE_SERVICE_MAX_RETRIES; i++) {
|
|
276
|
+
const delay = Math.min(ENSURE_SERVICE_INITIAL_DELAY_MS * (i + 1), ENSURE_SERVICE_MAX_DELAY_MS);
|
|
277
|
+
await sleep(delay);
|
|
278
|
+
if (childFailed) {
|
|
279
|
+
terminalLogger.error(
|
|
280
|
+
{ code: exitCode, signal: exitSignal, err: spawnError && String(spawnError) },
|
|
281
|
+
"Serve daemon failed to start"
|
|
282
|
+
);
|
|
283
|
+
const detail = spawnError ? `spawn error=${String(spawnError)}` : `code=${exitCode}, signal=${exitSignal}`;
|
|
284
|
+
throw new Error(
|
|
285
|
+
`Serve daemon failed to start (${detail}). Check ${SERVICE_LOG_PATH} for details.`
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
const socket = await tryConnect(SOCK_PATH);
|
|
289
|
+
if (socket) {
|
|
290
|
+
terminalLogger.info({ attempt: i + 1 }, "Connected to service after retry");
|
|
291
|
+
return socket;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
terminalLogger.error({ maxRetries: ENSURE_SERVICE_MAX_RETRIES }, "Failed to connect to service");
|
|
295
|
+
throw new Error(
|
|
296
|
+
`Failed to connect to dev-anywhere service after ${ENSURE_SERVICE_MAX_RETRIES} retries. Check ${SERVICE_LOG_PATH} for details.`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
function waitForMessage(socket, messageType) {
|
|
300
|
+
return new Promise((resolve, reject) => {
|
|
301
|
+
let timeout = null;
|
|
302
|
+
const dispose = createIpcReader(socket, (msg) => {
|
|
303
|
+
if (msg.type === messageType) {
|
|
304
|
+
if (timeout) clearTimeout(timeout);
|
|
305
|
+
dispose();
|
|
306
|
+
resolve(msg);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
timeout = setTimeout(() => {
|
|
310
|
+
dispose();
|
|
311
|
+
reject(new Error(`Timeout waiting for ${messageType}`));
|
|
312
|
+
}, WAIT_FOR_MESSAGE_TIMEOUT_MS);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
var TerminalSession = class {
|
|
316
|
+
constructor(provider, providerArgs) {
|
|
317
|
+
this.provider = provider;
|
|
318
|
+
this.providerArgs = providerArgs;
|
|
319
|
+
}
|
|
320
|
+
provider;
|
|
321
|
+
providerArgs;
|
|
322
|
+
fsm = createFSM({
|
|
323
|
+
initial: TerminalState.INIT,
|
|
324
|
+
transitions: TERMINAL_TRANSITIONS,
|
|
325
|
+
onTransition: (from, to) => terminalLogger.info({ from, to }, "Terminal state transition")
|
|
326
|
+
});
|
|
327
|
+
sessionCwd = resolveTerminalCwd();
|
|
328
|
+
// socket 在 run() 中连上 serve 后首次赋值;reconnect 会重新赋值为新实例
|
|
329
|
+
socket;
|
|
330
|
+
sessionId = null;
|
|
331
|
+
hookContext = null;
|
|
332
|
+
ptyManager = null;
|
|
333
|
+
lastOutputTime = 0;
|
|
334
|
+
idleCheckTimer = null;
|
|
335
|
+
currentPtyState = "turn_complete";
|
|
336
|
+
// headless terminal 在本进程维护,用于按需 serialize() 给远程 client
|
|
337
|
+
headlessTerminal = null;
|
|
338
|
+
serializeAddon = null;
|
|
339
|
+
outputSeq = 0;
|
|
340
|
+
remoteDetached = false;
|
|
341
|
+
// 记录上次 bridge 状态避免重连抖动导致 banner 连刷;初值 null 让首次状态(无论真假)都打,启动时提示 remote viewing 是否就绪
|
|
342
|
+
lastBridgeConnected = null;
|
|
343
|
+
// 收尾函数在 run() 里创建一次,PTY 退出与 SIGTERM 共用;内部通过 fsm EXITED 检查短路
|
|
344
|
+
cleanupAndExit;
|
|
345
|
+
async run() {
|
|
346
|
+
terminalLogger.info("Terminal starting");
|
|
347
|
+
this.fsm.transitionTo(TerminalState.CONNECTING_SERVICE);
|
|
348
|
+
this.socket = await ensureService();
|
|
349
|
+
await this.createSession();
|
|
350
|
+
this.initHeadlessTerminal();
|
|
351
|
+
this.cleanupAndExit = createExitHandler({
|
|
352
|
+
fsm: this.fsm,
|
|
353
|
+
getSocket: () => this.socket,
|
|
354
|
+
getSessionId: () => this.sessionId,
|
|
355
|
+
getIdleCheckTimer: () => this.idleCheckTimer
|
|
356
|
+
});
|
|
357
|
+
this.setupSocketHandlers();
|
|
358
|
+
this.startPtyManager();
|
|
359
|
+
this.socket.write(
|
|
360
|
+
serializeIpc({ type: "pty_register", sessionId: this.sessionId, pid: process.pid })
|
|
361
|
+
);
|
|
362
|
+
this.replayCurrentPtyState();
|
|
363
|
+
this.fsm.transitionTo(TerminalState.RUNNING);
|
|
364
|
+
this.setupIdleCheck();
|
|
365
|
+
process.on("SIGTERM", () => {
|
|
366
|
+
terminalLogger.info({ sessionId: this.sessionId }, "SIGTERM received, shutting down");
|
|
367
|
+
this.cleanupAndExit(143);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
async createSession() {
|
|
371
|
+
this.fsm.transitionTo(TerminalState.CREATING_SESSION);
|
|
372
|
+
const responsePromise = waitForMessage(this.socket, "session_create_response");
|
|
373
|
+
this.socket.write(
|
|
374
|
+
serializeIpc({
|
|
375
|
+
type: "session_create_request",
|
|
376
|
+
mode: "pty",
|
|
377
|
+
provider: this.provider.id,
|
|
378
|
+
cwd: this.sessionCwd,
|
|
379
|
+
name: tildify(this.sessionCwd),
|
|
380
|
+
pid: process.pid
|
|
381
|
+
})
|
|
382
|
+
);
|
|
383
|
+
const response = await responsePromise;
|
|
384
|
+
if (response.error) {
|
|
385
|
+
throw new Error(`Failed to create session: ${response.error}`);
|
|
386
|
+
}
|
|
387
|
+
this.sessionId = response.sessionId;
|
|
388
|
+
this.hookContext = response.hook ?? null;
|
|
389
|
+
}
|
|
390
|
+
initHeadlessTerminal() {
|
|
391
|
+
const { cols, rows } = readTtySize(process.stdout);
|
|
392
|
+
terminalLogger.info(
|
|
393
|
+
{ sessionId: this.sessionId, cols, rows },
|
|
394
|
+
"Session created, initializing headless terminal"
|
|
395
|
+
);
|
|
396
|
+
this.headlessTerminal = new HeadlessTerminal({
|
|
397
|
+
cols,
|
|
398
|
+
rows,
|
|
399
|
+
scrollback: 5e3,
|
|
400
|
+
allowProposedApi: true
|
|
401
|
+
});
|
|
402
|
+
this.serializeAddon = new SerializeAddon();
|
|
403
|
+
this.headlessTerminal.loadAddon(this.serializeAddon);
|
|
404
|
+
this.headlessTerminal.loadAddon(new UnicodeGraphemesAddon());
|
|
405
|
+
}
|
|
406
|
+
startPtyManager() {
|
|
407
|
+
this.ptyManager = new PtyManager({
|
|
408
|
+
provider: this.provider,
|
|
409
|
+
providerArgs: this.providerArgs,
|
|
410
|
+
cwd: this.sessionCwd,
|
|
411
|
+
hook: this.hookContext ?? void 0,
|
|
412
|
+
tap: (data) => this.handlePtyData(data),
|
|
413
|
+
stdin: process.stdin,
|
|
414
|
+
stdout: process.stdout,
|
|
415
|
+
onResize: (newCols, newRows) => {
|
|
416
|
+
if (this.headlessTerminal) this.headlessTerminal.resize(newCols, newRows);
|
|
417
|
+
if (this.socket.writable && this.sessionId) {
|
|
418
|
+
this.socket.write(
|
|
419
|
+
serializeIpc({
|
|
420
|
+
type: "pty_resize",
|
|
421
|
+
sessionId: this.sessionId,
|
|
422
|
+
cols: newCols,
|
|
423
|
+
rows: newRows
|
|
424
|
+
})
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
},
|
|
428
|
+
onSessionExit: (code) => {
|
|
429
|
+
terminalLogger.info({ sessionId: this.sessionId, exitCode: code }, "PTY exited, cleaning up");
|
|
430
|
+
this.cleanupAndExit(code);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
this.ptyManager.start();
|
|
434
|
+
terminalLogger.info({ sessionId: this.sessionId }, "PTY started with headless terminal");
|
|
435
|
+
}
|
|
436
|
+
// PTY 的每一帧输出都要:追到 headless terminal 状态、推 binary IPC、提取 provider 语义事件
|
|
437
|
+
handlePtyData(data) {
|
|
438
|
+
this.lastOutputTime = Date.now();
|
|
439
|
+
this.outputSeq += 1;
|
|
440
|
+
if (this.headlessTerminal) this.headlessTerminal.write(data);
|
|
441
|
+
if (!this.remoteDetached && this.socket.writable && this.sessionId) {
|
|
442
|
+
this.socket.write(
|
|
443
|
+
encodeBinaryIpcFrame(this.sessionId, Buffer.from(data, "utf-8"), this.outputSeq)
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
const oscSequences = extractOscSequences(data);
|
|
447
|
+
const signal = extractOscSignals(data, this.provider.id);
|
|
448
|
+
if (oscSequences.length > 0) {
|
|
449
|
+
terminalLogger.debug(
|
|
450
|
+
{
|
|
451
|
+
sessionId: this.sessionId,
|
|
452
|
+
oscSequences,
|
|
453
|
+
signal
|
|
454
|
+
},
|
|
455
|
+
"PTY OSC sequences parsed"
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
if (signal?.title) {
|
|
459
|
+
this.sendTerminalTitle(signal.title);
|
|
460
|
+
}
|
|
461
|
+
if (signal?.state === "approval_wait") {
|
|
462
|
+
this.currentPtyState = "approval_wait";
|
|
463
|
+
this.sendPtyState("approval_wait", { title: signal?.title, tool: signal?.tool });
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
if (shouldReleaseApprovalWait({
|
|
467
|
+
currentState: this.currentPtyState,
|
|
468
|
+
signalState: signal?.state
|
|
469
|
+
})) {
|
|
470
|
+
const nextState = stateAfterApprovalRelease(signal?.state);
|
|
471
|
+
this.currentPtyState = nextState;
|
|
472
|
+
this.sendPtyState(nextState, { title: signal?.title, tool: signal?.tool });
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if (this.currentPtyState === "approval_wait" && signal?.state !== "turn_complete") {
|
|
476
|
+
this.sendPtyState("approval_wait", { title: signal?.title, tool: signal?.tool });
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
if (signal && signal.state !== "working") {
|
|
480
|
+
this.currentPtyState = signal.state;
|
|
481
|
+
this.sendPtyState(signal.state, { title: signal.title, tool: signal.tool });
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
if (this.currentPtyState !== "working") {
|
|
485
|
+
this.currentPtyState = "working";
|
|
486
|
+
this.sendPtyState("working");
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
sendTerminalTitle(title) {
|
|
490
|
+
if (this.remoteDetached || !this.socket.writable || !this.sessionId) return;
|
|
491
|
+
this.socket.write(
|
|
492
|
+
serializeIpc({
|
|
493
|
+
type: "pty_title_change",
|
|
494
|
+
sessionId: this.sessionId,
|
|
495
|
+
title
|
|
496
|
+
})
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
sendPtyState(state, meta) {
|
|
500
|
+
if (this.remoteDetached || !this.socket.writable || !this.sessionId) return;
|
|
501
|
+
this.socket.write(
|
|
502
|
+
serializeIpc({
|
|
503
|
+
type: "pty_semantic_event",
|
|
504
|
+
sessionId: this.sessionId,
|
|
505
|
+
state,
|
|
506
|
+
...meta?.title !== void 0 ? { title: meta.title } : {},
|
|
507
|
+
...meta?.tool !== void 0 ? { tool: meta.tool } : {}
|
|
508
|
+
})
|
|
509
|
+
);
|
|
510
|
+
terminalLogger.info(
|
|
511
|
+
{ sessionId: this.sessionId, state, title: meta?.title, tool: meta?.tool },
|
|
512
|
+
"PTY semantic event pushed"
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
replayCurrentPtyState() {
|
|
516
|
+
if (this.currentPtyState === "turn_complete") return;
|
|
517
|
+
this.sendPtyState(this.currentPtyState);
|
|
518
|
+
}
|
|
519
|
+
handleBridgeStatus(connected) {
|
|
520
|
+
if (this.remoteDetached) return;
|
|
521
|
+
if (this.lastBridgeConnected === connected) return;
|
|
522
|
+
this.lastBridgeConnected = connected;
|
|
523
|
+
terminalLogger.info({ connected }, "Bridge status changed, notifying user");
|
|
524
|
+
notifyUser(connected ? "relay online" : "relay offline \u2014 remote viewing unavailable");
|
|
525
|
+
}
|
|
526
|
+
setupSocketHandlers() {
|
|
527
|
+
createIpcReader(this.socket, (msg) => {
|
|
528
|
+
if (msg.type === "pty_input" && msg.sessionId === this.sessionId) {
|
|
529
|
+
terminalLogger.debug({ sessionId: this.sessionId, bytes: msg.data.length }, "Remote input received");
|
|
530
|
+
this.ptyManager?.write(msg.data);
|
|
531
|
+
} else if (msg.type === "pty_detach" && msg.sessionId === this.sessionId) {
|
|
532
|
+
this.detachRemoteView();
|
|
533
|
+
} else if (msg.type === "bridge_status") {
|
|
534
|
+
this.handleBridgeStatus(msg.connected);
|
|
535
|
+
} else if (msg.type === "pty_subscribe" && msg.sessionId === this.sessionId) {
|
|
536
|
+
if (this.serializeAddon && this.headlessTerminal) {
|
|
537
|
+
const data = this.serializeAddon.serialize();
|
|
538
|
+
this.socket.write(
|
|
539
|
+
serializeIpc({
|
|
540
|
+
type: "pty_snapshot",
|
|
541
|
+
sessionId: msg.sessionId,
|
|
542
|
+
cols: this.headlessTerminal.cols,
|
|
543
|
+
rows: this.headlessTerminal.rows,
|
|
544
|
+
data,
|
|
545
|
+
outputSeq: this.outputSeq,
|
|
546
|
+
requestId: msg.requestId
|
|
547
|
+
})
|
|
548
|
+
);
|
|
549
|
+
terminalLogger.info(
|
|
550
|
+
{
|
|
551
|
+
sessionId: this.sessionId,
|
|
552
|
+
cols: this.headlessTerminal.cols,
|
|
553
|
+
rows: this.headlessTerminal.rows,
|
|
554
|
+
bytes: data.length
|
|
555
|
+
},
|
|
556
|
+
"Snapshot sent via IPC"
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
this.socket.on("close", () => {
|
|
562
|
+
terminalLogger.info("Serve socket closed");
|
|
563
|
+
if (this.remoteDetached) {
|
|
564
|
+
terminalLogger.info("Remote view detached, skipping serve reconnect");
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (!this.fsm.isIn([TerminalState.RECONNECTING, TerminalState.EXITED])) {
|
|
568
|
+
this.fsm.transitionTo(TerminalState.RECONNECTING);
|
|
569
|
+
this.reconnectToServe();
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
this.socket.on("error", (err) => {
|
|
573
|
+
terminalLogger.warn({ err: err.message }, "Serve socket error");
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
// 超过 IDLE_THRESHOLD_MS 无 PTY 输出则从 working 翻回 turn_complete
|
|
577
|
+
setupIdleCheck() {
|
|
578
|
+
if (this.idleCheckTimer) clearInterval(this.idleCheckTimer);
|
|
579
|
+
this.idleCheckTimer = setInterval(() => {
|
|
580
|
+
if (this.lastOutputTime > 0 && Date.now() - this.lastOutputTime > IDLE_THRESHOLD_MS) {
|
|
581
|
+
this.lastOutputTime = 0;
|
|
582
|
+
if (this.currentPtyState === "working") {
|
|
583
|
+
this.currentPtyState = "turn_complete";
|
|
584
|
+
this.sendPtyState("turn_complete");
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}, IDLE_CHECK_INTERVAL_MS);
|
|
588
|
+
}
|
|
589
|
+
async reconnectToServe() {
|
|
590
|
+
terminalLogger.info("Serve connection lost, starting reconnection");
|
|
591
|
+
let consecutiveSpawnFailures = 0;
|
|
592
|
+
for (let i = 0; ; i++) {
|
|
593
|
+
if (this.remoteDetached) return;
|
|
594
|
+
await sleep(Math.min(RECONNECT_INITIAL_DELAY_MS * (i + 1), RECONNECT_MAX_DELAY_MS));
|
|
595
|
+
const stopped = existsSync(STOPPED_PATH);
|
|
596
|
+
const degraded = consecutiveSpawnFailures >= SPAWN_FAILURE_THRESHOLD;
|
|
597
|
+
const passive = stopped || degraded;
|
|
598
|
+
try {
|
|
599
|
+
terminalLogger.debug({ attempt: i + 1, stopped, degraded }, "Reconnect attempt");
|
|
600
|
+
const newSocket = passive ? await tryConnect(SOCK_PATH) : await ensureService();
|
|
601
|
+
if (!newSocket) continue;
|
|
602
|
+
if (degraded) notifyUser("serve daemon reachable, reconnected");
|
|
603
|
+
consecutiveSpawnFailures = 0;
|
|
604
|
+
this.socket = newSocket;
|
|
605
|
+
terminalLogger.info({ attempt: i + 1, sessionId: this.sessionId }, "Reconnected to serve");
|
|
606
|
+
this.setupSocketHandlers();
|
|
607
|
+
if (this.sessionId) {
|
|
608
|
+
this.fsm.transitionTo(TerminalState.CREATING_SESSION);
|
|
609
|
+
this.socket.write(
|
|
610
|
+
serializeIpc({
|
|
611
|
+
type: "session_create_request",
|
|
612
|
+
mode: "pty",
|
|
613
|
+
provider: this.provider.id,
|
|
614
|
+
cwd: this.sessionCwd,
|
|
615
|
+
name: tildify(this.sessionCwd),
|
|
616
|
+
pid: process.pid,
|
|
617
|
+
sessionId: this.sessionId
|
|
618
|
+
})
|
|
619
|
+
);
|
|
620
|
+
const resp = await waitForMessage(this.socket, "session_create_response");
|
|
621
|
+
if (!resp.error) {
|
|
622
|
+
this.sessionId = resp.sessionId;
|
|
623
|
+
this.socket.write(
|
|
624
|
+
serializeIpc({ type: "pty_register", sessionId: this.sessionId, pid: process.pid })
|
|
625
|
+
);
|
|
626
|
+
this.replayCurrentPtyState();
|
|
627
|
+
this.fsm.transitionTo(TerminalState.RUNNING);
|
|
628
|
+
terminalLogger.info({ sessionId: this.sessionId }, "Session re-registered after reconnect");
|
|
629
|
+
}
|
|
630
|
+
} else {
|
|
631
|
+
this.fsm.transitionTo(TerminalState.RUNNING);
|
|
632
|
+
}
|
|
633
|
+
return;
|
|
634
|
+
} catch (err) {
|
|
635
|
+
if (!passive) {
|
|
636
|
+
consecutiveSpawnFailures++;
|
|
637
|
+
if (consecutiveSpawnFailures === SPAWN_FAILURE_THRESHOLD) {
|
|
638
|
+
notifyUser(
|
|
639
|
+
`serve daemon spawn failed ${SPAWN_FAILURE_THRESHOLD}x \u2014 auto-spawn disabled; check environment or run 'dev-anywhere start'`
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
terminalLogger.debug(
|
|
644
|
+
{ err: err instanceof Error ? err.message : err, attempt: i + 1, degraded },
|
|
645
|
+
"Reconnect attempt failed"
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
detachRemoteView() {
|
|
651
|
+
const sessionId = this.sessionId;
|
|
652
|
+
if (!sessionId) return;
|
|
653
|
+
this.remoteDetached = true;
|
|
654
|
+
this.sessionId = null;
|
|
655
|
+
this.hookContext = null;
|
|
656
|
+
this.currentPtyState = "turn_complete";
|
|
657
|
+
terminalLogger.info({ sessionId }, "Remote view detached; local PTY keeps running");
|
|
658
|
+
notifyUser("remote viewing detached");
|
|
659
|
+
if (this.socket.writable) this.socket.end();
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
function providerFromEnv() {
|
|
663
|
+
return process.env.DEV_ANYWHERE_PROVIDER === "codex" ? "codex" : "claude";
|
|
664
|
+
}
|
|
665
|
+
async function startTerminal(providerArgs, providerId = providerFromEnv()) {
|
|
666
|
+
await new TerminalSession(PROVIDERS[providerId], providerArgs).run();
|
|
667
|
+
}
|
|
668
|
+
export {
|
|
669
|
+
startTerminal
|
|
670
|
+
};
|
|
671
|
+
//# sourceMappingURL=terminal-TTRA2VJY.js.map
|