gemini-web-bridge 0.0.0-stage → 0.3.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 +17 -2
- package/bin/gsb.js +6 -0
- package/lib/platform.js +47 -0
- package/lib/run.js +49 -0
- package/package.json +39 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 azrinaldi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
-
#
|
|
1
|
+
# gemini-web-bridge
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use your **Gemini Web** subscription inside **opencode** and **agy** through one small local daemon: OpenAI-compatible API, several accounts with quota-aware rotation, a dashboard, and one-command setup.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npx gemini-web-bridge start # guided setup: sign in, configure opencode and agy, test
|
|
7
|
+
npx gemini-web-bridge login # add an account (a one-time page on this computer)
|
|
8
|
+
npx gemini-web-bridge ui # open the dashboard
|
|
9
|
+
npx gemini-web-bridge status # quota, resets and usage per account
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Or install it once: `npm install -g gemini-web-bridge`, then use `gsb` or `gemini-web-bridge`.
|
|
13
|
+
|
|
14
|
+
Linux x64 and arm64. The package ships a prebuilt binary through an optional platform package; set `GSB_BINARY=/path/to/gsb` to use your own build.
|
|
15
|
+
|
|
16
|
+
> **Risk:** this drives a personal Gemini Web session by impersonating Chrome, which may violate Google's Terms of Service and could get the account restricted. Use an account you own and can afford to lose.
|
|
17
|
+
|
|
18
|
+
Source, docs and security notes: https://github.com/techbysakh963/gemini-web-bridge
|
package/bin/gsb.js
ADDED
package/lib/platform.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const fs = require('node:fs')
|
|
3
|
+
|
|
4
|
+
/** An error whose message is meant to be shown to the user as-is (no stack trace). */
|
|
5
|
+
class LauncherError extends Error {}
|
|
6
|
+
|
|
7
|
+
const PACKAGES = {
|
|
8
|
+
'linux/x64': 'gemini-web-bridge-linux-x64',
|
|
9
|
+
'linux/arm64': 'gemini-web-bridge-linux-arm64',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function packageFor(platform, arch) {
|
|
13
|
+
return PACKAGES[`${platform}/${arch}`] || null
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Finds the gsb binary: GSB_BINARY if set, else the binary shipped by the matching
|
|
18
|
+
* platform package (installed as an optional dependency of this package).
|
|
19
|
+
*/
|
|
20
|
+
function resolveBinary({ platform, arch, env, resolve }) {
|
|
21
|
+
if (env.GSB_BINARY) {
|
|
22
|
+
if (!fs.existsSync(env.GSB_BINARY)) {
|
|
23
|
+
throw new LauncherError(`GSB_BINARY points at ${env.GSB_BINARY}, which does not exist.`)
|
|
24
|
+
}
|
|
25
|
+
return env.GSB_BINARY
|
|
26
|
+
}
|
|
27
|
+
const pkg = packageFor(platform, arch)
|
|
28
|
+
if (!pkg) {
|
|
29
|
+
throw new LauncherError(
|
|
30
|
+
`gemini-web-bridge has no prebuilt binary for ${platform}/${arch}. Supported: ${Object.keys(PACKAGES).join(', ')}.\n` +
|
|
31
|
+
`Build it from source instead (needs Go): go build -o gsb ./cmd/gsb, then set GSB_BINARY=/path/to/gsb.`,
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
return resolve(`${pkg}/bin/gsb`)
|
|
36
|
+
} catch (e) {
|
|
37
|
+
if (e && e.code === 'MODULE_NOT_FOUND') {
|
|
38
|
+
throw new LauncherError(
|
|
39
|
+
`The binary package ${pkg} is not installed. It is an optional dependency, so it is skipped when npm runs with --omit=optional / --no-optional.\n` +
|
|
40
|
+
`Reinstall without that flag (npm install gemini-web-bridge), or install the binary directly: npm install ${pkg}.`,
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
throw e
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
module.exports = { packageFor, resolveBinary, LauncherError, PACKAGES }
|
package/lib/run.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const { spawn } = require('node:child_process')
|
|
3
|
+
const fs = require('node:fs')
|
|
4
|
+
const { resolveBinary, LauncherError } = require('./platform')
|
|
5
|
+
|
|
6
|
+
const FORWARDED = ['SIGINT', 'SIGTERM', 'SIGHUP', 'SIGQUIT']
|
|
7
|
+
|
|
8
|
+
/** Runs gsb with the given arguments, wiring stdio, signals and the exit status through. */
|
|
9
|
+
function main(argv, { env = process.env, platform = process.platform, arch = process.arch, resolve = require.resolve } = {}) {
|
|
10
|
+
let bin
|
|
11
|
+
try {
|
|
12
|
+
bin = resolveBinary({ platform, arch, env, resolve })
|
|
13
|
+
try {
|
|
14
|
+
fs.accessSync(bin, fs.constants.X_OK)
|
|
15
|
+
} catch {
|
|
16
|
+
fs.chmodSync(bin, 0o755) // npm can drop the executable bit on some setups
|
|
17
|
+
}
|
|
18
|
+
} catch (e) {
|
|
19
|
+
if (e instanceof LauncherError) {
|
|
20
|
+
process.stderr.write(`gemini-web-bridge: ${e.message}\n`)
|
|
21
|
+
return 127
|
|
22
|
+
}
|
|
23
|
+
throw e
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const child = spawn(bin, argv, { stdio: 'inherit', env })
|
|
27
|
+
const relay = (sig) => () => {
|
|
28
|
+
if (!child.killed) child.kill(sig)
|
|
29
|
+
}
|
|
30
|
+
const handlers = FORWARDED.map((sig) => [sig, relay(sig)])
|
|
31
|
+
for (const [sig, h] of handlers) process.on(sig, h)
|
|
32
|
+
|
|
33
|
+
child.on('error', (e) => {
|
|
34
|
+
process.stderr.write(`gemini-web-bridge: could not start ${bin}: ${e.message}\n`)
|
|
35
|
+
process.exit(126)
|
|
36
|
+
})
|
|
37
|
+
child.on('exit', (code, signal) => {
|
|
38
|
+
for (const [sig, h] of handlers) process.removeListener(sig, h)
|
|
39
|
+
if (signal) {
|
|
40
|
+
// End the same way the child did, so shells and supervisors see the real cause.
|
|
41
|
+
process.kill(process.pid, signal)
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
process.exit(code === null ? 1 : code)
|
|
45
|
+
})
|
|
46
|
+
return null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = { main }
|
package/package.json
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gemini-web-bridge",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Use your Gemini Web subscription in opencode and agy: a local OpenAI-compatible bridge with multi-account rotation, a dashboard and one-command setup.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"gemini",
|
|
7
|
+
"opencode",
|
|
8
|
+
"agy",
|
|
9
|
+
"openai-compatible",
|
|
10
|
+
"bridge",
|
|
11
|
+
"proxy"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"bin": {
|
|
15
|
+
"gemini-web-bridge": "bin/gsb.js",
|
|
16
|
+
"gsb": "bin/gsb.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"bin",
|
|
20
|
+
"lib",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"optionalDependencies": {
|
|
28
|
+
"gemini-web-bridge-linux-arm64": "0.3.1",
|
|
29
|
+
"gemini-web-bridge-linux-x64": "0.3.1"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/techbysakh963/gemini-web-bridge.git"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"test": "node --test \"test/*.test.js\""
|
|
40
|
+
}
|
|
41
|
+
}
|