From 8590efd229eb05fcbc0c3858c6640a770b61b95a Mon Sep 17 00:00:00 2001 From: Taylor Mullen Date: Fri, 23 May 2025 12:27:48 -0700 Subject: [PATCH] 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. --- eslint.config.js | 1 + package-lock.json | 6 ++++++ package.json | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/eslint.config.js b/eslint.config.js index da9e3221..33447b5f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -33,6 +33,7 @@ export default tseslint.config( 'packages/cli/dist/**', 'packages/server/dist/**', 'eslint-rules/*', + 'bundle/**', ], }, eslint.configs.recommended, diff --git a/package-lock.json b/package-lock.json index 878a4f5b..c30e11ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index c60f07d0..e084447b 100644 --- a/package.json +++ b/package.json @@ -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",