feat: Enable npx execution directly from GitHub URL

This commit modifies the packaging setup to allow the CLI to be
executed directly from its GitHub URL using `npx`, for example:
`npx https://github.com/google-gemini/gemini-cli` (once merged to main).
This is achieved without requiring the bundle to be checked into
the repository.

Key changes and motivations:

- Modify `scripts.prepare` to run `npm run bundle`:
  Ensures the CLI bundle is generated automatically when `npx`
  installs the package from a git URL. This replaces previous
  approaches (e.g., using `prepack`) which were not consistently
  triggered in the `npx` environment.

- Update `scripts.bundle` to use a direct path for `esbuild`
  and externalize `sqlite3`:
  Using `node_modules/.bin/esbuild` provides a more reliable way
  to invoke the bundler. Externalizing `sqlite3` is crucial for
  correctly handling its native addon, preventing runtime errors.

- Add `bin`, `files`, and root `sqlite3` dependency:
  - The `bin` field defines the `gemini` command.
  - The `files` array ensures the generated `bundle/` directory is
    recognized by npm.
  - `sqlite3` is added as a root dependency to ensure it's
    installed by `npx` when `gemini-code` is fetched, allowing the
    externalized module to be resolved.

These changes collectively ensure that the necessary build artifacts
are created on-the-fly during `npx` installation, providing a
seamless execution experience directly from the GitHub repository URL.
This commit is contained in:
Taylor Mullen 2025-05-23 12:27:48 -07:00 committed by N. Taylor Mullen
parent 8f266f9652
commit 8590efd229
3 changed files with 22 additions and 1 deletions

View File

@ -33,6 +33,7 @@ export default tseslint.config(
'packages/cli/dist/**',
'packages/server/dist/**',
'eslint-rules/*',
'bundle/**',
],
},
eslint.configs.recommended,

6
package-lock.json generated
View File

@ -10,6 +10,12 @@
"workspaces": [
"packages/*"
],
"dependencies": {
"sqlite3": "^5.1.7"
},
"bin": {
"gemini": "bundle/gemini.js"
},
"devDependencies": {
"@types/mime-types": "^2.1.4",
"@vitest/coverage-v8": "^3.1.1",

View File

@ -11,6 +11,7 @@
"build:sandbox": "scripts/build_sandbox.sh",
"build:all": "npm run build && npm run build:sandbox",
"clean": "scripts/clean.sh",
"prepare": "npm run bundle",
"test": "npm run test --workspaces",
"coverage": "npm run coverage --workspaces --if-present",
"start": "NODE_ENV=development scripts/start.sh",
@ -24,7 +25,20 @@
"auth:docker": "gcloud auth configure-docker us-west1-docker.pkg.dev",
"auth": "npm run auth:npm && npm run auth:docker",
"prerelease:dev": "npm run prerelease:version --workspaces && npm run prerelease:deps --workspaces",
"bundle": "esbuild packages/cli/index.ts --bundle --outfile=bundle/gemini.js --platform=node --format=esm --banner:js=\"import { createRequire } from 'module'; const require = createRequire(import.meta.url); globalThis.__filename = require('url').fileURLToPath(import.meta.url); globalThis.__dirname = require('path').dirname(globalThis.__filename);\" && bash scripts/copy_bundle_assets.sh"
"bundle": "node_modules/.bin/esbuild packages/cli/index.ts --bundle --outfile=bundle/gemini.js --platform=node --format=esm --external:sqlite3 --banner:js=\"import { createRequire } from 'module'; const require = createRequire(import.meta.url); globalThis.__filename = require('url').fileURLToPath(import.meta.url); globalThis.__dirname = require('path').dirname(globalThis.__filename);\" && bash scripts/copy_bundle_assets.sh"
},
"bin": {
"gemini": "bundle/gemini.js"
},
"files": [
"bundle/",
"packages/cli/dist",
"packages/cli/package.json",
"packages/server/dist",
"packages/server/package.json"
],
"dependencies": {
"sqlite3": "^5.1.7"
},
"devDependencies": {
"@types/mime-types": "^2.1.4",