mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 12:22:34 +03:00
Compare commits
1 Commits
fix/12413-
...
chore/work
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
636c06b5c3 |
212
@omniroute/opencode-plugin-v2/package-lock.json
generated
212
@omniroute/opencode-plugin-v2/package-lock.json
generated
@@ -22,7 +22,7 @@
|
||||
"node": ">=22.22.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opencode-ai/plugin": ">=1.18.29 <2"
|
||||
"@opencode-ai/plugin": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@ai-sdk/provider": {
|
||||
@@ -39,9 +39,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
|
||||
"integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
|
||||
"integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -56,9 +56,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
|
||||
"integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
|
||||
"integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -73,9 +73,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
|
||||
"integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
|
||||
"integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -90,9 +90,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
|
||||
"integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
|
||||
"integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -107,9 +107,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
|
||||
"integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
|
||||
"integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -124,9 +124,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
|
||||
"integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
|
||||
"integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -141,9 +141,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
|
||||
"integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
|
||||
"integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -158,9 +158,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
|
||||
"integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
|
||||
"integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -175,9 +175,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
|
||||
"integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
|
||||
"integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -192,9 +192,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
|
||||
"integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
|
||||
"integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -209,9 +209,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
|
||||
"integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
|
||||
"integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -226,9 +226,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
|
||||
"integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
|
||||
"integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@@ -243,9 +243,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
|
||||
"integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
|
||||
"integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
@@ -260,9 +260,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
|
||||
"integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
|
||||
"integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -277,9 +277,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
|
||||
"integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
|
||||
"integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -294,9 +294,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
|
||||
"integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
|
||||
"integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -311,9 +311,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
|
||||
"integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
|
||||
"version": "0.28.1",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -328,9 +326,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
|
||||
"integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
|
||||
"integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -345,9 +343,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
|
||||
"integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
|
||||
"integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -362,9 +360,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
|
||||
"integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
|
||||
"integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -379,9 +377,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
|
||||
"integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
|
||||
"integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -396,9 +394,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openharmony-arm64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
|
||||
"integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
|
||||
"integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -413,9 +411,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
|
||||
"integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
|
||||
"integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -430,9 +428,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
|
||||
"integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
|
||||
"integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -447,9 +445,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
|
||||
"integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
|
||||
"integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -464,9 +462,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
|
||||
"integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
|
||||
"version": "0.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
|
||||
"integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1182,9 +1180,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
|
||||
"integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
|
||||
"version": "0.28.1",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
@@ -1195,32 +1191,32 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.28.2",
|
||||
"@esbuild/android-arm": "0.28.2",
|
||||
"@esbuild/android-arm64": "0.28.2",
|
||||
"@esbuild/android-x64": "0.28.2",
|
||||
"@esbuild/darwin-arm64": "0.28.2",
|
||||
"@esbuild/darwin-x64": "0.28.2",
|
||||
"@esbuild/freebsd-arm64": "0.28.2",
|
||||
"@esbuild/freebsd-x64": "0.28.2",
|
||||
"@esbuild/linux-arm": "0.28.2",
|
||||
"@esbuild/linux-arm64": "0.28.2",
|
||||
"@esbuild/linux-ia32": "0.28.2",
|
||||
"@esbuild/linux-loong64": "0.28.2",
|
||||
"@esbuild/linux-mips64el": "0.28.2",
|
||||
"@esbuild/linux-ppc64": "0.28.2",
|
||||
"@esbuild/linux-riscv64": "0.28.2",
|
||||
"@esbuild/linux-s390x": "0.28.2",
|
||||
"@esbuild/linux-x64": "0.28.2",
|
||||
"@esbuild/netbsd-arm64": "0.28.2",
|
||||
"@esbuild/netbsd-x64": "0.28.2",
|
||||
"@esbuild/openbsd-arm64": "0.28.2",
|
||||
"@esbuild/openbsd-x64": "0.28.2",
|
||||
"@esbuild/openharmony-arm64": "0.28.2",
|
||||
"@esbuild/sunos-x64": "0.28.2",
|
||||
"@esbuild/win32-arm64": "0.28.2",
|
||||
"@esbuild/win32-ia32": "0.28.2",
|
||||
"@esbuild/win32-x64": "0.28.2"
|
||||
"@esbuild/aix-ppc64": "0.28.1",
|
||||
"@esbuild/android-arm": "0.28.1",
|
||||
"@esbuild/android-arm64": "0.28.1",
|
||||
"@esbuild/android-x64": "0.28.1",
|
||||
"@esbuild/darwin-arm64": "0.28.1",
|
||||
"@esbuild/darwin-x64": "0.28.1",
|
||||
"@esbuild/freebsd-arm64": "0.28.1",
|
||||
"@esbuild/freebsd-x64": "0.28.1",
|
||||
"@esbuild/linux-arm": "0.28.1",
|
||||
"@esbuild/linux-arm64": "0.28.1",
|
||||
"@esbuild/linux-ia32": "0.28.1",
|
||||
"@esbuild/linux-loong64": "0.28.1",
|
||||
"@esbuild/linux-mips64el": "0.28.1",
|
||||
"@esbuild/linux-ppc64": "0.28.1",
|
||||
"@esbuild/linux-riscv64": "0.28.1",
|
||||
"@esbuild/linux-s390x": "0.28.1",
|
||||
"@esbuild/linux-x64": "0.28.1",
|
||||
"@esbuild/netbsd-arm64": "0.28.1",
|
||||
"@esbuild/netbsd-x64": "0.28.1",
|
||||
"@esbuild/openbsd-arm64": "0.28.1",
|
||||
"@esbuild/openbsd-x64": "0.28.1",
|
||||
"@esbuild/openharmony-arm64": "0.28.1",
|
||||
"@esbuild/sunos-x64": "0.28.1",
|
||||
"@esbuild/win32-arm64": "0.28.1",
|
||||
"@esbuild/win32-ia32": "0.28.1",
|
||||
"@esbuild/win32-x64": "0.28.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-check": {
|
||||
|
||||
6
@omniroute/opencode-plugin/package-lock.json
generated
6
@omniroute/opencode-plugin/package-lock.json
generated
@@ -1745,9 +1745,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/toml": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/toml/-/toml-4.3.0.tgz",
|
||||
"integrity": "sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/toml/-/toml-4.1.1.tgz",
|
||||
"integrity": "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
||||
17
AGENTS.md
17
AGENTS.md
@@ -578,14 +578,31 @@ own dedicated branch, and you MUST confirm the base branch with the operator bef
|
||||
# HARD LINKS (`cp -al`), never a symlink: ~5s for the whole tree and near-zero extra
|
||||
# disk (the inodes are shared), and unlike a symlink it does not break the dev server.
|
||||
cp -al "$(git -C <main_checkout> rev-parse --show-toplevel)/node_modules" node_modules
|
||||
# `.husky/_` is gitignored, so a fresh worktree does NOT have it and
|
||||
# `core.hooksPath=.husky/_` then points at a directory that does not exist —
|
||||
# every pre-commit gate goes silently mute. Copy it too.
|
||||
cp -a "$(git -C <main_checkout> rev-parse --show-toplevel)/.husky/_" .husky/_
|
||||
```
|
||||
|
||||
`scripts/dev/new-worktree.sh <branch> [base]` does all of the above (canonical path,
|
||||
hard-linked `node_modules`, `.husky/_`) and then **verifies** the hook is actually
|
||||
executable, so prefer it over running the steps by hand.
|
||||
|
||||
**Never `ln -s` node_modules.** Turbopack rejects a symlink that resolves outside the
|
||||
project root, so `npm run dev` dies with a FATAL panic (`Symlink [project]/node_modules
|
||||
is invalid, it points out of the filesystem root`) while typecheck, lint and the test
|
||||
runners all keep passing — the error names "filesystem root", not the worktree, so it
|
||||
reads like a Next/build bug and costs real time to trace (incident 2026-07-31, #9043).
|
||||
|
||||
**A worktree without `.husky/_` runs NO pre-commit gate — and says nothing.** `git`
|
||||
resolves `core.hooksPath` relative to the worktree top; when the directory is missing it
|
||||
simply finds no hook and commits. Nothing is printed, the commit succeeds, and the
|
||||
identity/lint/docs gates never ran. This is how 59 commits carrying a stale identity
|
||||
override (name of a contributor + the maintainer's e-mail) got past
|
||||
`scripts/check/check-git-identity.sh` between 2026-08-29 and 09-02 — they were all made in
|
||||
`cp -al` worktrees. Verify with `ls .husky/_/pre-commit` inside a new worktree, or just use
|
||||
`scripts/dev/new-worktree.sh`, which fails loudly when the hook is not executable.
|
||||
|
||||
3. **Work, commit, push, open the PR — all from inside the worktree.** Never `git checkout` a
|
||||
different branch inside a worktree another session might share.
|
||||
4. **Tear down only your own** worktree + branch when done, from the main checkout:
|
||||
|
||||
@@ -54,34 +54,6 @@ async function openBrowser(url) {
|
||||
}
|
||||
}
|
||||
|
||||
// Mirrors src/lib/oauth/providers.ts::isLoopbackHostname — used here to detect
|
||||
// when the redirect_uri the server resolved (and the authorize URL now
|
||||
// advertises) points at a loopback address the CLI never binds a listener on
|
||||
// (issue #12413). Returns false on an unparseable URI rather than throwing.
|
||||
function isLoopbackHost(uri) {
|
||||
try {
|
||||
return /^(localhost|127\.0\.0\.1|\[::1\]|::1)$/i.test(new URL(uri).hostname);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function printLoopbackRedirectWarning(providerId, redirectUri) {
|
||||
process.stdout.write(
|
||||
`Note: the authorize URL below advertises ${redirectUri}, but this CLI does not\n` +
|
||||
"listen on that port. Right after you approve, the browser is expected to\n" +
|
||||
"show a connection error (e.g. \"This site can't be reached\" / \n" +
|
||||
"ERR_CONNECTION_REFUSED) — that is normal, not a failure. Copy the full URL\n" +
|
||||
"from the address bar anyway and paste it below.\n"
|
||||
);
|
||||
if (providerId === "antigravity") {
|
||||
process.stdout.write(
|
||||
"Tip: `omniroute login antigravity` captures the code automatically and\n" +
|
||||
"avoids that error page entirely.\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function targetApiOptions(opts = {}) {
|
||||
return {
|
||||
baseUrl: opts.baseUrl,
|
||||
@@ -138,10 +110,6 @@ async function runBrowserFlow(def, opts) {
|
||||
const { codeVerifier, state, redirectUri: returnedRedirectUri } = start;
|
||||
const finalRedirectUri = returnedRedirectUri || redirectUri;
|
||||
|
||||
if (finalRedirectUri && isLoopbackHost(finalRedirectUri)) {
|
||||
printLoopbackRedirectWarning(def.id, finalRedirectUri);
|
||||
}
|
||||
|
||||
process.stdout.write(`\nOpen this URL to authorize:\n ${url}\n\n`);
|
||||
if (opts.browser !== false) await openBrowser(url);
|
||||
process.stdout.write(
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
- fix(oauth): warn before the dead localhost:8080 redirect in antigravity/gemini `oauth start` (#12413)
|
||||
6
electron/package-lock.json
generated
6
electron/package-lock.json
generated
@@ -2113,9 +2113,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
|
||||
"integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
|
||||
"integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
|
||||
50
package-lock.json
generated
50
package-lock.json
generated
@@ -8687,6 +8687,20 @@
|
||||
"license": "ISC",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@openai/codex-security/node_modules/smol-toml": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz",
|
||||
"integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/cyyynthia"
|
||||
}
|
||||
},
|
||||
"node_modules/@openai/codex-security/node_modules/type-fest": {
|
||||
"version": "5.9.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.9.0.tgz",
|
||||
@@ -15203,9 +15217,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@yarnpkg/parsers/node_modules/js-yaml": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
|
||||
"integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
|
||||
"integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -18521,9 +18535,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/csv-parse": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-7.0.2.tgz",
|
||||
"integrity": "sha512-uKZghv9UmPkMVLYy//KZ9HFAIJsl7wkhoEdIL0+rhuSY9pZQlhaeGEDPIe+/w7eh81MOql8Q/9+inAGWG6ZHYA==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-7.0.1.tgz",
|
||||
"integrity": "sha512-+2z7Ar0APQ7Uu6fX4cn+pitRmxjZ1WPBcGmZFKmA74FCyi7Et/XZx8cjNQ5CjbZ4HCOxXCOpRBYvYH08Qa003A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -23589,9 +23603,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/hono": {
|
||||
"version": "4.13.7",
|
||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.7.tgz",
|
||||
"integrity": "sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==",
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.0.tgz",
|
||||
"integrity": "sha512-jhunvfHWxd7J5EFfSgH4xsYJzSe/lfqbUCxiyyeaQasUsXeEHXtzVid+7EOGByc5JnFa23SSFL3Y2RV/z1T+eQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
@@ -26102,9 +26116,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/joi": {
|
||||
"version": "18.2.8",
|
||||
"resolved": "https://registry.npmjs.org/joi/-/joi-18.2.8.tgz",
|
||||
"integrity": "sha512-G2TX62h58ZHuwqetJgP2F4ualakqAmZtBYe3jWen7gxQRw5xApX6crnFtuB91WC0c3ESBnva+kGSnb3+6pIQDQ==",
|
||||
"version": "18.2.3",
|
||||
"resolved": "https://registry.npmjs.org/joi/-/joi-18.2.3.tgz",
|
||||
"integrity": "sha512-N5A3KTWQpPWT4ExxxPlUx7WmykGXRzhNidWhV41d6Abu9YfI2NyWCJuxdPnslJCPWtbRpSVOWSnSS6GakLM/Rg==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
@@ -27932,9 +27946,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lockfile-lint/node_modules/js-yaml": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
|
||||
"integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
|
||||
"integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -39606,9 +39620,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/xmlbuilder2/node_modules/js-yaml": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
|
||||
"integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
|
||||
"integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
||||
@@ -486,10 +486,7 @@
|
||||
"fast-uri": "^3.1.7",
|
||||
"body-parser": "^2.3.0",
|
||||
"@yarnpkg/parsers": {
|
||||
"js-yaml": "^4.3.2"
|
||||
},
|
||||
"@openai/codex-security": {
|
||||
"smol-toml": "^1.8.0"
|
||||
"js-yaml": "^4.3.1"
|
||||
},
|
||||
"jsdom": {
|
||||
"undici": "^7.29.0"
|
||||
|
||||
92
scripts/dev/new-worktree.sh
Executable file
92
scripts/dev/new-worktree.sh
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env sh
|
||||
# Cria uma worktree isolada seguindo o protocolo obrigatório do AGENTS.md
|
||||
# (Git Workflow → "Worktree isolation" / Hard Rule #19), incluindo os dois
|
||||
# passos que são fáceis de esquecer e falham em silêncio:
|
||||
#
|
||||
# 1. node_modules por HARD LINK (`cp -al`), nunca symlink — um symlink que
|
||||
# resolve fora da raiz mata o Turbopack com um FATAL que culpa a
|
||||
# "filesystem root" e não a worktree (incidente 2026-07-31, #9043).
|
||||
# 2. `.husky/_` copiado — é gitignored, então uma worktree nova NÃO o tem, e
|
||||
# `core.hooksPath=.husky/_` aponta para um diretório inexistente: TODOS os
|
||||
# hooks de pre-commit ficam mudos, sem aviso nenhum. Foi assim que 59
|
||||
# commits com identidade trocada passaram pelo gate entre 29/08 e 02/09
|
||||
# (ver .mailmap e scripts/check/check-git-identity.sh).
|
||||
#
|
||||
# Uso: scripts/dev/new-worktree.sh <branch> [base-branch]
|
||||
# Ex.: scripts/dev/new-worktree.sh fix/12345-algo release/v3.8.51
|
||||
|
||||
set -e
|
||||
|
||||
BRANCH="$1"
|
||||
BASE="$2"
|
||||
|
||||
if [ -z "$BRANCH" ]; then
|
||||
echo "uso: scripts/dev/new-worktree.sh <branch> [base-branch]" >&2
|
||||
echo " ex: scripts/dev/new-worktree.sh fix/12345-algo release/v3.8.51" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# O checkout PRINCIPAL, mesmo quando este script roda de dentro de outra worktree:
|
||||
# `--show-toplevel` devolveria a worktree atual, e a nova nasceria aninhada nela.
|
||||
MAIN=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")
|
||||
cd "$MAIN"
|
||||
|
||||
# Sem base explícita, usa a release ativa (maior release/* por semver) — nunca
|
||||
# `main` e nunca "a branch em que eu estou", conforme a Hard Rule #19.
|
||||
if [ -z "$BASE" ]; then
|
||||
BASE=$(git ls-remote --heads origin 'refs/heads/release/*' \
|
||||
| sed 's#.*refs/heads/##' | sort -V | tail -1)
|
||||
[ -z "$BASE" ] && { echo "não consegui resolver a release ativa; passe a base explicitamente" >&2; exit 1; }
|
||||
echo "base não informada — usando a release ativa: $BASE"
|
||||
fi
|
||||
|
||||
DIR=".claude/worktrees/${BRANCH##*/}"
|
||||
[ -e "$DIR" ] && { echo "já existe: $DIR" >&2; exit 1; }
|
||||
|
||||
git fetch origin "$BASE" --quiet
|
||||
git worktree add "$DIR" -b "$BRANCH" "origin/$BASE"
|
||||
|
||||
# `.husky/_` PRIMEIRO: é minúsculo e é o que decide se os gates locais rodam.
|
||||
# Copiar node_modules antes seria arriscar abortar (set -e) numa árvore de ~10 GB
|
||||
# e deixar a worktree sem hook nenhum — exatamente o defeito que este script existe
|
||||
# para impedir.
|
||||
if [ -d "$MAIN/.husky/_" ]; then
|
||||
cp -a "$MAIN/.husky/_" "$DIR/.husky/_"
|
||||
else
|
||||
echo "AVISO: .husky/_ não existe no checkout principal — rode 'npm install' lá primeiro" >&2
|
||||
fi
|
||||
|
||||
# node_modules: hard links, ~5s e disco quase zero (inodes compartilhados).
|
||||
# Um `cp -al SRC DEST` com DEST já existente aninharia SRC DENTRO dele
|
||||
# (node_modules/node_modules), então DEST não pode existir aqui.
|
||||
if [ -d "$MAIN/node_modules/node_modules" ]; then
|
||||
echo "AVISO: $MAIN/node_modules/node_modules existe — resíduo de um cp -al aninhado." >&2
|
||||
echo " Ele infla a cópia e esgota o limite de hard links; convém removê-lo." >&2
|
||||
fi
|
||||
if [ -d "$MAIN/node_modules" ]; then
|
||||
# Falha parcial (limite de hard links, disco) não pode derrubar a worktree inteira:
|
||||
# os hooks já estão no lugar e o npm install continua sendo uma saída válida.
|
||||
if cp -al "$MAIN/node_modules" "$DIR/node_modules" 2>"$DIR/.cp-node-modules.log"; then
|
||||
echo "node_modules: $(ls "$DIR/node_modules" | wc -l) entradas (hard links)"
|
||||
rm -f "$DIR/.cp-node-modules.log"
|
||||
else
|
||||
echo "AVISO: a cópia de node_modules falhou parcialmente (veja $DIR/.cp-node-modules.log)." >&2
|
||||
echo " Primeiras linhas:" >&2
|
||||
head -3 "$DIR/.cp-node-modules.log" >&2
|
||||
fi
|
||||
else
|
||||
echo "AVISO: node_modules não existe no checkout principal — rode 'npm install' lá primeiro" >&2
|
||||
fi
|
||||
|
||||
# Verificação: o hook precisa estar REALMENTE ativo, não apenas presente.
|
||||
HOOKS_PATH=$(git -C "$DIR" config --get core.hooksPath || echo ".git/hooks")
|
||||
if [ -x "$DIR/$HOOKS_PATH/pre-commit" ]; then
|
||||
echo "hooks: ativos ($HOOKS_PATH/pre-commit)"
|
||||
else
|
||||
echo "AVISO: pre-commit NÃO está ativo em $DIR/$HOOKS_PATH — os gates locais não vão rodar" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "pronto: $DIR (branch $BRANCH, base $BASE)"
|
||||
echo " cd $DIR"
|
||||
@@ -19,10 +19,7 @@ export async function DELETE(request: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// Scope the sweep to the caller. Only the operator's own dashboard (session
|
||||
// auth) may clear the whole instance; an API key clears only its own
|
||||
// completed batches (GHSA-wvxc-jp3v-5mg5).
|
||||
const result = deleteCompletedBatches(scope.isSessionAuth ? undefined : scope.apiKeyId);
|
||||
const result = deleteCompletedBatches();
|
||||
|
||||
return NextResponse.json(
|
||||
{ deleted: true, deletedBatches: result.deletedBatches, deletedFiles: result.deletedFiles },
|
||||
|
||||
@@ -411,37 +411,15 @@ export function deleteBatch(id: string): boolean {
|
||||
return result.changes > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk-delete completed batches and the files they reference.
|
||||
*
|
||||
* `apiKeyId` scopes EVERY statement to that owner. Omitting it keeps the
|
||||
* instance-wide sweep, which is legitimate for the operator's own dashboard
|
||||
* (session auth) and for nothing else: without the predicate, an ordinary
|
||||
* inference key could wipe every tenant's completed batches and null out their
|
||||
* file contents (GHSA-wvxc-jp3v-5mg5). Same ownership shape as `listBatches`
|
||||
* and `countBatches` above.
|
||||
*/
|
||||
export function deleteCompletedBatches(apiKeyId?: string | null): {
|
||||
deletedBatches: number;
|
||||
deletedFiles: number;
|
||||
} {
|
||||
export function deleteCompletedBatches(): { deletedBatches: number; deletedFiles: number } {
|
||||
const db = getDbInstance();
|
||||
const scoped = typeof apiKeyId === "string" && apiKeyId.length > 0;
|
||||
|
||||
// Collect unique file IDs from the completed batches in scope
|
||||
const rows = (
|
||||
scoped
|
||||
? db
|
||||
.prepare(
|
||||
"SELECT input_file_id, output_file_id, error_file_id FROM batches WHERE status = 'completed' AND api_key_id = ?"
|
||||
)
|
||||
.all(apiKeyId)
|
||||
: db
|
||||
.prepare(
|
||||
"SELECT input_file_id, output_file_id, error_file_id FROM batches WHERE status = 'completed'"
|
||||
)
|
||||
.all()
|
||||
) as Array<{
|
||||
// Collect unique file IDs from all completed batches
|
||||
const rows = db
|
||||
.prepare(
|
||||
"SELECT input_file_id, output_file_id, error_file_id FROM batches WHERE status = 'completed'"
|
||||
)
|
||||
.all() as Array<{
|
||||
input_file_id: string | null;
|
||||
output_file_id: string | null;
|
||||
error_file_id: string | null;
|
||||
@@ -463,16 +441,6 @@ export function deleteCompletedBatches(apiKeyId?: string | null): {
|
||||
}
|
||||
}
|
||||
|
||||
if (scoped) {
|
||||
db.prepare(
|
||||
"DELETE FROM batch_item_checkpoints WHERE batch_id IN (SELECT id FROM batches WHERE status = 'completed' AND api_key_id = ?)"
|
||||
).run(apiKeyId);
|
||||
const result = db
|
||||
.prepare("DELETE FROM batches WHERE status = 'completed' AND api_key_id = ?")
|
||||
.run(apiKeyId);
|
||||
return { deletedBatches: result.changes, deletedFiles };
|
||||
}
|
||||
|
||||
db.prepare(
|
||||
"DELETE FROM batch_item_checkpoints WHERE batch_id IN (SELECT id FROM batches WHERE status = 'completed')"
|
||||
).run();
|
||||
|
||||
@@ -58,8 +58,6 @@
|
||||
"tests/unit/account-fallback-retry-after-json.test.ts",
|
||||
"tests/unit/account-fallback-route-restriction-403.test.ts",
|
||||
"tests/unit/account-fallback-service.test.ts",
|
||||
"tests/unit/combo-pin-implicit-allowlist.test.ts",
|
||||
"tests/unit/combo/execute-target-gates.test.ts",
|
||||
"tests/unit/moonshot-quota-writeback.test.ts",
|
||||
"tests/unit/accountfallback-ratelimit-400-4976.test.ts",
|
||||
"tests/unit/adaptive-admission-route-matrix.test.ts",
|
||||
@@ -77,8 +75,6 @@
|
||||
"tests/unit/api-key-policy-noauth-allowed-connections.test.ts",
|
||||
"tests/unit/api-key-rotator-health.test.ts",
|
||||
"tests/unit/chat-routing-synced-inventory-11089.test.ts",
|
||||
"tests/unit/openai-compatible-per-upstream-402-health.test.ts",
|
||||
"tests/unit/quota-window-label.test.ts",
|
||||
"tests/unit/repro-combo-persisted-cooldown-preskip.test.ts",
|
||||
"tests/unit/repro-glm-iso-reset-24h-cap.test.ts",
|
||||
"tests/unit/security-route-guard-tiers.test.ts",
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/**
|
||||
* GHSA-wvxc-jp3v-5mg5 — `DELETE /api/v1/batches/delete-completed` deleted the
|
||||
* completed batches of EVERY api key on the instance, and nulled the contents of
|
||||
* every file those batches referenced.
|
||||
*
|
||||
* Two defects in one endpoint:
|
||||
* 1. `deleteCompletedBatches()` carried no `api_key_id` predicate — the file
|
||||
* SELECT, the checkpoint DELETE and the batch DELETE were all instance-wide.
|
||||
* 2. The route only checked that SOME key was present (`!scope.apiKeyId` →
|
||||
* 401), never that the caller owned anything. A key with `scopes: []` —
|
||||
* an ordinary inference key — could wipe another tenant's batches.
|
||||
*
|
||||
* The ownership pattern this restores is not new: `listBatches(apiKeyId?)` and
|
||||
* `countBatches(apiKeyId?)` in the same module already scope by `api_key_id`,
|
||||
* and `batches/[id]/route.ts` already gates per-record access with `scopeCheck`
|
||||
* (session auth sees everything, a key sees only its own). This helper was the
|
||||
* one that never got it.
|
||||
*
|
||||
* Run with:
|
||||
* node --import tsx/esm --test tests/unit/batch-delete-completed-ownership-wvxc.test.ts
|
||||
*/
|
||||
|
||||
import { describe, it } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { createFile, getFile } from "@/lib/db/files";
|
||||
import { createBatch, getBatch, deleteCompletedBatches } from "@/lib/db/batches";
|
||||
|
||||
const KEY_A = "key-wvxc-aaaa";
|
||||
const KEY_B = "key-wvxc-bbbb";
|
||||
|
||||
function seedCompletedBatch(apiKeyId: string | null, tag: string) {
|
||||
const file = createFile({
|
||||
bytes: 10,
|
||||
filename: `wvxc-${tag}.jsonl`,
|
||||
purpose: "batch",
|
||||
content: Buffer.from("{}"),
|
||||
});
|
||||
const batch = createBatch({
|
||||
endpoint: "/v1/chat/completions",
|
||||
completionWindow: "24h",
|
||||
inputFileId: file.id,
|
||||
status: "completed",
|
||||
apiKeyId,
|
||||
});
|
||||
return { file, batch };
|
||||
}
|
||||
|
||||
describe("deleteCompletedBatches — ownership scoping (GHSA-wvxc-jp3v-5mg5)", () => {
|
||||
it("scoped to one key deletes ONLY that key's completed batches", () => {
|
||||
const a = seedCompletedBatch(KEY_A, "a1");
|
||||
const b = seedCompletedBatch(KEY_B, "b1");
|
||||
|
||||
const result = deleteCompletedBatches(KEY_A);
|
||||
|
||||
assert.equal(getBatch(a.batch.id), null, "the caller's own batch should be gone");
|
||||
assert.ok(getBatch(b.batch.id), "another key's batch must survive");
|
||||
assert.equal(result.deletedBatches, 1, "must report only what it actually deleted");
|
||||
});
|
||||
|
||||
it("scoped deletion does not touch another key's file contents", () => {
|
||||
const a = seedCompletedBatch(KEY_A, "a2");
|
||||
const b = seedCompletedBatch(KEY_B, "b2");
|
||||
|
||||
deleteCompletedBatches(KEY_A);
|
||||
|
||||
assert.equal(getFile(a.file.id), null, "the caller's own file should be gone");
|
||||
assert.ok(getFile(b.file.id), "another key's file must survive with its content intact");
|
||||
});
|
||||
|
||||
it("a key with no completed batches deletes nothing at all", () => {
|
||||
const b = seedCompletedBatch(KEY_B, "b3");
|
||||
|
||||
const result = deleteCompletedBatches("key-wvxc-with-nothing");
|
||||
|
||||
assert.equal(result.deletedBatches, 0);
|
||||
assert.equal(result.deletedFiles, 0);
|
||||
assert.ok(getBatch(b.batch.id), "an unrelated key's batch must survive");
|
||||
});
|
||||
|
||||
it("unscoped (dashboard session) still clears the whole instance", () => {
|
||||
// The operator's own dashboard legitimately cleans up everything; that is
|
||||
// the ONLY caller allowed to omit the key. Preserved deliberately.
|
||||
seedCompletedBatch(KEY_A, "a4");
|
||||
seedCompletedBatch(KEY_B, "b4");
|
||||
|
||||
const result = deleteCompletedBatches();
|
||||
|
||||
assert.ok(
|
||||
result.deletedBatches >= 2,
|
||||
`expected an instance-wide sweep, got ${result.deletedBatches}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("the route passes the caller's key through", () => {
|
||||
it("delete-completed scopes by api key instead of calling the helper bare", async () => {
|
||||
const { readFileSync } = await import("node:fs");
|
||||
const { fileURLToPath } = await import("node:url");
|
||||
const src = readFileSync(
|
||||
fileURLToPath(
|
||||
new URL("../../src/app/api/v1/batches/delete-completed/route.ts", import.meta.url)
|
||||
),
|
||||
"utf8"
|
||||
);
|
||||
assert.ok(
|
||||
!/deleteCompletedBatches\(\s*\)/.test(src),
|
||||
"the route still calls deleteCompletedBatches() with no owner — every tenant's batches go"
|
||||
);
|
||||
assert.ok(
|
||||
/deleteCompletedBatches\(\s*scope\./.test(src),
|
||||
"the route must pass the caller's scope into the helper"
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -13,11 +13,6 @@ type Check = {
|
||||
validate?: (content: string, claim?: string) => { ok: boolean; detail: string };
|
||||
};
|
||||
|
||||
/** Escape a value that is interpolated into a RegExp source. */
|
||||
function escapeRegExp(value: string): string {
|
||||
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
describe("ToS caution heading count", () => {
|
||||
it("the Caution heading carries the count the gate checks", () => {
|
||||
const txt = readFileSync(join(process.cwd(), "docs/reference/FREE_TIERS.md"), "utf8");
|
||||
@@ -26,24 +21,7 @@ describe("ToS caution heading count", () => {
|
||||
const tos = (buildChecks() as Check[]).find((c) =>
|
||||
String(c.docKey ?? "").includes("ToS caution")
|
||||
);
|
||||
// The backslashes must survive the TEMPLATE LITERAL to reach the regex.
|
||||
// Written as `\(\s*…` they did not: JS resolves `\(` to "(" and `\s` to the
|
||||
// LETTER "s" before RegExp ever sees them, so the pattern compiled to
|
||||
// `(s*16s*)` — a capture group around optional "s" characters. That matched
|
||||
// any heading merely containing the number, with no literal parentheses
|
||||
// required at all, so this guard passed on headings it was written to reject
|
||||
// (CodeQL js/useless-regexp-character-escape #994-#997).
|
||||
const count = escapeRegExp(String(tos?.actual));
|
||||
assert.match(heading, new RegExp(`\\(\\s*${count}\\s*\\)`));
|
||||
});
|
||||
|
||||
it("the heading guard actually requires the parentheses", () => {
|
||||
// Pins the defect above: the pattern this test builds must REJECT a heading
|
||||
// that carries the count without parentheses. Before the fix it accepted it.
|
||||
const pattern = new RegExp(`\\(\\s*${escapeRegExp("16")}\\s*\\)`);
|
||||
assert.equal(pattern.test("### Caution — clauses worth checking 16"), false);
|
||||
assert.equal(pattern.test("### Caution — clauses worth checking (16)"), true);
|
||||
assert.equal(pattern.test("### Caution — clauses worth checking ( 16 )"), true);
|
||||
assert.match(heading, new RegExp(`\(\s*${String(tos?.actual)}\s*\)`));
|
||||
});
|
||||
it("buildChecks exposes a soft ToS entry on FREE_TIERS.md with requireClaim", () => {
|
||||
const checks = buildChecks() as Check[];
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { Readable } from "node:stream";
|
||||
|
||||
// Repro probe for issue #12413: `omniroute oauth start --provider antigravity`
|
||||
// prints the Google authorize URL (which advertises
|
||||
// redirect_uri=http://localhost:8080/callback) and then silently waits for a
|
||||
// pasted callback URL/code — nothing in the CLI output warns the operator
|
||||
// that their browser is about to land on a dead port (ERR_CONNECTION_REFUSED)
|
||||
// and that seeing that error is expected, not a failure.
|
||||
//
|
||||
// This asserts the CLI's browser-flow instructions proactively mention the
|
||||
// expected browser error (e.g. "can't be reached" / "connection refused" /
|
||||
// "ERR_CONNECTION_REFUSED") BEFORE the user is sent to authorize.
|
||||
|
||||
function makeResp(data: unknown, status = 200) {
|
||||
return {
|
||||
ok: status < 400,
|
||||
status,
|
||||
json: () => Promise.resolve(data),
|
||||
text: () => Promise.resolve(JSON.stringify(data)),
|
||||
headers: new Headers(),
|
||||
};
|
||||
}
|
||||
|
||||
async function captureStdout(fn: () => Promise<void>) {
|
||||
const chunks: string[] = [];
|
||||
const orig = process.stdout.write.bind(process.stdout);
|
||||
(process.stdout.write as unknown) = (c: string | Uint8Array) => {
|
||||
chunks.push(typeof c === "string" ? c : Buffer.from(c).toString("utf8"));
|
||||
return true;
|
||||
};
|
||||
try {
|
||||
await fn();
|
||||
} finally {
|
||||
process.stdout.write = orig;
|
||||
}
|
||||
return chunks.join("");
|
||||
}
|
||||
|
||||
function makeCmd() {
|
||||
return { optsWithGlobals: () => ({ output: "json", quiet: true }) };
|
||||
}
|
||||
|
||||
// readline's `close` fallback (bin/cli/io.mjs) only fires once per stdin EOF —
|
||||
// reusing the real (already-ended) process.stdin across tests in the same file
|
||||
// means the second readline.createInterface() never sees another `end`/`close`
|
||||
// event and hangs forever. Swap in a fresh, already-ended Readable per test
|
||||
// instead of calling `process.stdin.push(null)` on the shared real stream.
|
||||
async function withEndedStdin<T>(fn: () => Promise<T>): Promise<T> {
|
||||
const origStdin = process.stdin;
|
||||
const fakeStdin = new Readable({ read() {} });
|
||||
fakeStdin.push(null);
|
||||
Object.defineProperty(process, "stdin", { value: fakeStdin, configurable: true });
|
||||
try {
|
||||
return await fn();
|
||||
} finally {
|
||||
Object.defineProperty(process, "stdin", { value: origStdin, configurable: true });
|
||||
}
|
||||
}
|
||||
|
||||
test("runOAuthStart browser flow warns antigravity users before the dead localhost:8080 redirect (#12413)", async () => {
|
||||
const origFetch = globalThis.fetch;
|
||||
const origExit = process.exit;
|
||||
let exitErr: Error | null = null;
|
||||
|
||||
(globalThis.fetch as unknown) = (url: string) => {
|
||||
if (url.includes("/api/oauth/antigravity/authorize")) {
|
||||
return Promise.resolve(
|
||||
makeResp({
|
||||
authUrl:
|
||||
"https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcallback",
|
||||
codeVerifier: "verifier",
|
||||
state: "state123",
|
||||
redirectUri: "http://localhost:8080/callback",
|
||||
})
|
||||
);
|
||||
}
|
||||
return Promise.reject(new Error(`Unexpected fetch: ${url}`));
|
||||
};
|
||||
|
||||
(process.exit as unknown) = (code?: number) => {
|
||||
exitErr = new Error(`exit ${code}`);
|
||||
throw exitErr;
|
||||
};
|
||||
|
||||
let out = "";
|
||||
try {
|
||||
const { runOAuthStart } = await import("../../bin/cli/commands/oauth.mjs");
|
||||
out = await withEndedStdin(() =>
|
||||
captureStdout(async () => {
|
||||
try {
|
||||
await runOAuthStart({ provider: "antigravity", browser: false }, makeCmd());
|
||||
} catch (e) {
|
||||
if (e !== exitErr) throw e;
|
||||
}
|
||||
})
|
||||
);
|
||||
} finally {
|
||||
globalThis.fetch = origFetch;
|
||||
process.exit = origExit;
|
||||
}
|
||||
|
||||
assert.ok(out.includes("8080"), "should print the advertised (dead) redirect port");
|
||||
|
||||
const mentionsExpectedBrowserError =
|
||||
/can't be reached|connection refused|err_connection_refused|won't load|expected/i.test(out);
|
||||
assert.ok(
|
||||
mentionsExpectedBrowserError,
|
||||
`expected the CLI to warn about the dead-redirect browser error BEFORE the user hits it, got:\n${out}`
|
||||
);
|
||||
});
|
||||
|
||||
test("runOAuthStart browser flow does NOT warn for a non-loopback redirect (claude-code)", async () => {
|
||||
const origFetch = globalThis.fetch;
|
||||
const origExit = process.exit;
|
||||
let exitErr: Error | null = null;
|
||||
|
||||
(globalThis.fetch as unknown) = (url: string) => {
|
||||
if (url.includes("/api/oauth/claude/authorize")) {
|
||||
return Promise.resolve(
|
||||
makeResp({
|
||||
authUrl: "https://platform.claude.com/oauth/authorize?redirect_uri=fixed",
|
||||
codeVerifier: "verifier",
|
||||
state: "state123",
|
||||
redirectUri: "https://platform.claude.com/oauth/code/callback",
|
||||
})
|
||||
);
|
||||
}
|
||||
return Promise.reject(new Error(`Unexpected fetch: ${url}`));
|
||||
};
|
||||
|
||||
(process.exit as unknown) = (code?: number) => {
|
||||
exitErr = new Error(`exit ${code}`);
|
||||
throw exitErr;
|
||||
};
|
||||
|
||||
let out = "";
|
||||
try {
|
||||
const { runOAuthStart } = await import("../../bin/cli/commands/oauth.mjs");
|
||||
out = await withEndedStdin(() =>
|
||||
captureStdout(async () => {
|
||||
try {
|
||||
await runOAuthStart({ provider: "claude-code", browser: false }, makeCmd());
|
||||
} catch (e) {
|
||||
if (e !== exitErr) throw e;
|
||||
}
|
||||
})
|
||||
);
|
||||
} finally {
|
||||
globalThis.fetch = origFetch;
|
||||
process.exit = origExit;
|
||||
}
|
||||
|
||||
const mentionsExpectedBrowserError =
|
||||
/can't be reached|connection refused|err_connection_refused|won't load/i.test(out);
|
||||
assert.ok(
|
||||
!mentionsExpectedBrowserError,
|
||||
`did not expect a dead-redirect warning for a non-loopback provider, got:\n${out}`
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user