diff --git a/.changeset/ship-plugin-installer.md b/.changeset/ship-plugin-installer.md new file mode 100644 index 0000000..bbfa737 --- /dev/null +++ b/.changeset/ship-plugin-installer.md @@ -0,0 +1,5 @@ +--- +"grok-bot-cli": patch +--- + +Ship the `grok-bot` agent plugin inside the npm package: `npm install --global grok-bot-cli` now also provides `gbot-install install|uninstall cursor|claude|codex` and `gbot-install doctor` (Node 22.19+), which install the bundled `gbot_send` / `gbot_thread` MCP server and `talk-to-grok-bot` Skill from `plugin/dist` without cloning the repository. `npm run build:plugin` (run automatically by `npm pack` / `npm publish`) produces that directory with `agent-bundle prepack`. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d5e8a5..f6039c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,9 @@ jobs: - name: Test run: npm test + - name: Build the plugin distribution (gbot-install bin + host projections) + run: npm run build:plugin + - name: Lint the package run: npx --yes publint@0.3.24 @@ -38,6 +41,12 @@ jobs: install_root=$(mktemp -d) npm install --global --prefix "$install_root" "./$package_file" "$install_root/bin/gbot" --help + "$install_root/bin/gbot-install" --help + fake_home=$(mktemp -d) + mkdir -p "$fake_home/.cursor" + HOME="$fake_home" "$install_root/bin/gbot-install" install cursor --json + test -f "$fake_home/.cursor/plugins/local/grok-bot/.agent-bundle-install.json" + test -f "$fake_home/.cursor/plugins/local/grok-bot/plugin.json" plugin: runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fc1ce29..c4fafd6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,6 +39,9 @@ jobs: - name: Test run: npm test + - name: Build the plugin distribution (gbot-install bin + host projections) + run: npm run build:plugin + - name: Lint the package run: npx --yes publint@0.3.24 @@ -53,6 +56,11 @@ jobs: test "${#package_files[@]}" -eq 1 npm install --global --prefix "$install_root" "${package_files[0]}" "$install_root/bin/gbot" --help + "$install_root/bin/gbot-install" --help + fake_home=$(mktemp -d) + mkdir -p "$fake_home/.cursor" + HOME="$fake_home" "$install_root/bin/gbot-install" install cursor --json + test -f "$fake_home/.cursor/plugins/local/grok-bot/.agent-bundle-install.json" - name: Create release pull request or publish id: changesets diff --git a/README.md b/README.md index cabe478..b42562f 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,25 @@ Manage [Grok Bot](https://cursor.com/help/grok-bot/plans) agents, groups, and me npm install --global grok-bot-cli ``` +The package ships two things: the `gbot` CLI and the `grok-bot` agent plugin (the `gbot_send` / +`gbot_thread` MCP server plus the `talk-to-grok-bot` Skill) as an [Agent Bundle](https://scriptedalchemy.github.io/agent-bundle/) +artifact under `plugin/dist`. Install the plugin into whichever hosts you use with the bundled installer: + +```sh +gbot-install install cursor # ~/.cursor/plugins/local/grok-bot (reload Cursor afterwards) +gbot-install install claude # claude plugin marketplace add + install, scope user +gbot-install install codex # codex plugin marketplace add + plugin add +gbot-install doctor # what each host has, and whether it matches this package +gbot-install install cursor --replace # upgrade a copy installed from an older version +gbot-install uninstall cursor # removes only what the receipt says this package installed +``` + +`gbot-install` needs Node.js 22.19+ (the plugin runtime); `gbot` itself runs on Node.js 18+. The same +artifact is documented host by host in `plugin/dist/INSTALL.md` inside the installed package, and +developers with the `agent-bundle` CLI can run `agent-bundle install --from plugin/dist` +instead. Building from a checkout: `npm run build:plugin` produces `plugin/dist` (it is also what +`npm pack` / `npm publish` run first). + Requires Node.js 18+ and the Grok Bot desktop app on macOS, Linux, or Windows. Open Grok Bot and sign in once; `gbot` automatically uses the app's encrypted session and routing credentials. No token copying is required. On Linux the app keeps its session under `~/.config/Grok Bot` (or `$XDG_CONFIG_HOME`); when it is stored in the system keyring, `gbot` reads the key with `secret-tool` (package `libsecret-tools`). On Windows the session lives under `%APPDATA%\\Grok Bot` and decrypts with the app's DPAPI-wrapped Safe Storage key. ## Use @@ -87,8 +106,9 @@ that gives Codex, Claude Code, and Cursor two MCP tools on a `grok-bot` server, when to ping a bot and how to word the message. The tools bundle this repository's gateway client, so the installed plugin does not need `gbot` on `PATH`. -The plugin is not part of the npm package. From a clone of this repository, build -the artifact once, then install it into each host you use: +The built plugin ships inside the npm package; `gbot-install install ` (see +[Install](#install)) is the normal path. From a clone of this repository you can also build +and install the development artifact directly: ```sh git clone https://github.com/ScriptedAlchemy/grok-bot-cli.git @@ -103,7 +123,8 @@ npx agent-bundle doctor --from artifact Add `--replace` to an install command to overwrite an earlier copy. `npm run check` runs the plugin gates: source validation, build, artifact validation, typecheck, and -the route-unit tests, which drive both tools against a loopback fake gateway. +the route-unit tests, which drive both tools against a loopback fake gateway; +`npm run prepack` emits the npm-root form under `plugin/dist` that the package ships. `gbot_thread` returns a small receipt by default: deterministic `summary`, opaque `cursor`, `entryCount`, and `gapReset`. diff --git a/package.json b/package.json index 685ef92..f1b476d 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "type": "module", "bin": { "gbot": "src/cli.js", - "grok-bot": "src/cli.js" + "grok-bot": "src/cli.js", + "gbot-install": "plugin/dist/bin/gbot-install.js" }, "engines": { "node": ">=18" @@ -14,7 +15,9 @@ "changeset": "changeset", "gbot": "node src/cli.js", "release": "changeset publish", - "test": "node scripts/run-unit-tests.mjs" + "test": "node scripts/run-unit-tests.mjs", + "build:plugin": "npm --prefix plugin ci --no-json --silent && npm --prefix plugin run --silent prepack", + "prepack": "npm run --silent build:plugin 1>&2" }, "repository": { "type": "git", @@ -39,6 +42,7 @@ ], "files": [ "src", + "plugin/dist", "README.md", "LICENSE" ], diff --git a/plugin/README.md b/plugin/README.md new file mode 100644 index 0000000..4e8a2df --- /dev/null +++ b/plugin/README.md @@ -0,0 +1,16 @@ +# grok-bot plugin + +The Agent Bundle plugin half of [`grok-bot-cli`](https://github.com/ScriptedAlchemy/grok-bot-cli): the +`grok-bot` MCP server (`gbot_send`, `gbot_thread`) and the `talk-to-grok-bot` Skill for Codex, Claude Code, +and Cursor. + +It is not published on its own. `agent-bundle prepack` emits `dist/`, and the `grok-bot-cli` tarball ships +that directory together with the `gbot-install` bin: + +```sh +npm install --global grok-bot-cli +gbot-install install cursor # or claude / codex; --replace upgrades an older copy +gbot-install doctor +``` + +Develop with `npm ci && npm run check` in this directory (Node 22.19+). diff --git a/plugin/agent-bundle.config.ts b/plugin/agent-bundle.config.ts index 16b0991..89977c2 100644 --- a/plugin/agent-bundle.config.ts +++ b/plugin/agent-bundle.config.ts @@ -1,6 +1,9 @@ import { defineConfig } from 'agent-bundle/config'; export default defineConfig({ + // Package-bound installer shipped inside the `grok-bot-cli` tarball as the + // `gbot-install` bin (`plugin/dist/bin/gbot-install.js`); see README "Install". + bin: { 'gbot-install': './src/gbot-install.ts' }, lib: false, marketplace: true, output: { distPath: 'artifact' }, diff --git a/plugin/package-lock.json b/plugin/package-lock.json index 21a72b3..0e543f7 100644 --- a/plugin/package-lock.json +++ b/plugin/package-lock.json @@ -7,26 +7,26 @@ "": { "name": "grok-bot-plugin", "version": "0.1.0", - "dependencies": { - "@agent-bundle/runtime": "https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@62ffe403c5af73499fe7f5767c6d60be26e250db", - "grok-bot-cli": "file:..", - "react": "19.3.0", - "react-dom": "19.3.0", - "zod": "4.6.5" - }, "devDependencies": { + "@agent-bundle/runtime": "https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@62ffe403c5af73499fe7f5767c6d60be26e250db", "@rstest/core": "0.11.12", "@types/node": "^24.0.0", "@types/react": "^19.2.18", "agent-bundle": "https://pkg.pr.new/ScriptedAlchemy/agent-bundle/agent-bundle@62ffe403c5af73499fe7f5767c6d60be26e250db", - "typescript": "7.0.2" + "grok-bot-cli": "file:..", + "react": "19.3.0", + "react-dom": "19.3.0", + "typescript": "7.0.2", + "zod": "4.6.5" }, "engines": { "node": ">=22.19.0" } }, "..": { - "version": "0.2.3", + "name": "grok-bot-cli", + "version": "0.3.1", + "dev": true, "license": "MIT", "bin": { "gbot": "src/cli.js", @@ -43,6 +43,7 @@ "version": "0.0.0-preview-62ffe40", "resolved": "https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@62ffe403c5af73499fe7f5767c6d60be26e250db", "integrity": "sha512-9UOa9oBHMndugsVwD869n1KzqYqqsI3I106ZtaOEPM4y7vR/ZU0qNBMeRO5IcdW2bZR9C4GKt1yKDpJEF8PkHA==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@modelcontextprotocol/server": "2.0.0", @@ -273,6 +274,7 @@ "version": "1.11.3", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.3.tgz", "integrity": "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -284,6 +286,7 @@ "version": "1.11.3", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -294,6 +297,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz", "integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -336,6 +340,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/core/-/core-2.0.0.tgz", "integrity": "sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==", + "dev": true, "license": "MIT", "dependencies": { "zod": "^4.2.0" @@ -370,6 +375,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.0.0.tgz", "integrity": "sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==", + "dev": true, "license": "MIT", "dependencies": { "@modelcontextprotocol/core": "2.0.0", @@ -386,6 +392,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -399,6 +406,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -412,6 +420,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -425,6 +434,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -438,6 +448,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -451,6 +462,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -461,6 +473,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -745,6 +758,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-2.2.4.tgz", "integrity": "sha512-KoH5Wofyt1+egnqWF3pr8ItiYQiLgrHYLHOAn4YpzIMsGc8zDur3dCIhrhJ1uhbD3O7zkKqav4he3bo1kAmX9Q==", + "dev": true, "license": "MIT", "optionalDependencies": { "@rspack/binding-darwin-arm64": "2.2.4", @@ -770,6 +784,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -783,6 +798,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -796,6 +812,7 @@ "cpu": [ "arm64" ], + "dev": true, "libc": [ "glibc" ], @@ -812,6 +829,7 @@ "cpu": [ "arm64" ], + "dev": true, "libc": [ "musl" ], @@ -828,6 +846,7 @@ "cpu": [ "ppc64" ], + "dev": true, "libc": [ "glibc" ], @@ -844,6 +863,7 @@ "cpu": [ "riscv64" ], + "dev": true, "libc": [ "glibc" ], @@ -860,6 +880,7 @@ "cpu": [ "riscv64" ], + "dev": true, "libc": [ "musl" ], @@ -876,6 +897,7 @@ "cpu": [ "s390x" ], + "dev": true, "libc": [ "glibc" ], @@ -892,6 +914,7 @@ "cpu": [ "x64" ], + "dev": true, "libc": [ "glibc" ], @@ -908,6 +931,7 @@ "cpu": [ "x64" ], + "dev": true, "libc": [ "musl" ], @@ -924,6 +948,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -939,6 +964,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -952,6 +978,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -965,6 +992,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -975,6 +1003,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/@rspack/core/-/core-2.2.4.tgz", "integrity": "sha512-p8/w2i3viGQDVaqbHZtKpBwQNG7rY+Bf8iwu3i+d4KHwC1+VMLc4fBD30qU+cAHuUtsdx15sicvTVz3CniYOlg==", + "dev": true, "license": "MIT", "dependencies": { "@rspack/binding": "2.2.4" @@ -1059,7 +1088,7 @@ "version": "0.5.23", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" @@ -1069,6 +1098,7 @@ "version": "0.10.4", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.4.tgz", "integrity": "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -1664,6 +1694,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, "license": "Apache-2.0", "optional": true, "engines": { @@ -1674,6 +1705,7 @@ "version": "4.0.0-rc.112", "resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-rc.112.tgz", "integrity": "sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A==", + "dev": true, "license": "MIT", "dependencies": { "fast-check": "^4.9.0", @@ -1714,6 +1746,7 @@ "version": "4.10.0", "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.10.0.tgz", "integrity": "sha512-hhqQL+IJllZi3aM4TKvmCj3bywLEcycNTTLZeLhA9ttMxBrCqM07q7Di4kl+j9EWSTXvJH1+EpIgsDbF/+8H5Q==", + "dev": true, "funding": [ { "type": "individual", @@ -1800,6 +1833,7 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/flare-redact/-/flare-redact-1.6.1.tgz", "integrity": "sha512-13Htu6VPk2ttxcoVOP909pXao6orrIBAMS/qWdhQn3/BS5AxSB5fpyqaPZnRGJhfBAM2M9T+RE662hxEpv6nGQ==", + "dev": true, "license": "MIT", "bin": { "flare-gateway": "bin/flare-gateway.mjs", @@ -1978,6 +2012,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-2.1.0.tgz", "integrity": "sha512-p/pBCVO63CsvvpkomUnNNag6+n38rULuDA6HHe70o2gtC8ODI52foF/4ko2qQcp6OiErJXTmrZeXmsGGHsIQNQ==", + "dev": true, "license": "MIT", "optionalDependencies": { "msgpackr-extract": "^3.0.4" @@ -1987,6 +2022,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz", "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -2009,6 +2045,7 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -2083,6 +2120,7 @@ "version": "8.4.2", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.2.tgz", "integrity": "sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng==", + "dev": true, "funding": [ { "type": "individual", @@ -2120,6 +2158,7 @@ "version": "19.3.0", "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -2129,6 +2168,7 @@ "version": "19.3.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", + "dev": true, "license": "MIT", "dependencies": { "scheduler": "^0.28.0" @@ -2151,6 +2191,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/react-server-dom-rspack/-/react-server-dom-rspack-0.1.0.tgz", "integrity": "sha512-KqDzmxBUZEcAphwg/PnEHOBkqTJjesTmLoBygLHie1gkiLINiZuVKPRccS6qDzfdj9ccYCaJ743IDYVh0wPf/w==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -2226,6 +2267,7 @@ "version": "0.0.0-preview-62ffe40", "resolved": "https://pkg.pr.new/ScriptedAlchemy/agent-bundle/rsc-markdown-stream@62ffe403c5af73499fe7f5767c6d60be26e250db", "integrity": "sha512-w7tS3Z2Cj4a9seDTrn/QpYo78sQoSsi/mWTiVMPvbbwDldAv75OnPuffRmvJnfXUhLrXhXzAOVTpy9+S7Z3iqQ==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=22.19.0" @@ -2262,6 +2304,7 @@ "version": "0.28.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "dev": true, "license": "MIT" }, "node_modules/semver": { @@ -2317,7 +2360,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "devOptional": true, + "dev": true, "license": "0BSD" }, "node_modules/typescript": { @@ -2430,6 +2473,7 @@ "version": "4.6.5", "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.5.tgz", "integrity": "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/plugin/package.json b/plugin/package.json index 0d79f95..e818610 100644 --- a/plugin/package.json +++ b/plugin/package.json @@ -2,7 +2,7 @@ "name": "grok-bot-plugin", "version": "0.1.0", "private": true, - "description": "Agent Bundle plugin: message Grok Bot from Codex, Claude Code, and Cursor through the gbot gateway client.", + "description": "Agent Bundle plugin for grok-bot-cli: message Grok Bot from Codex, Claude Code, and Cursor. Ships inside the grok-bot-cli npm package as the gbot-install bin.", "type": "module", "engines": { "node": ">=22.19.0" @@ -13,20 +13,19 @@ "test": "rstest --config rstest.route-unit.config.ts", "typecheck": "tsc -p tsconfig.json --noEmit", "validate": "agent-bundle validate", - "validate:artifact": "agent-bundle validate --artifact artifact" - }, - "dependencies": { - "@agent-bundle/runtime": "https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@62ffe403c5af73499fe7f5767c6d60be26e250db", - "grok-bot-cli": "file:..", - "react": "19.3.0", - "react-dom": "19.3.0", - "zod": "4.6.5" + "validate:artifact": "agent-bundle validate --artifact artifact", + "prepack": "agent-bundle prepack" }, "devDependencies": { + "@agent-bundle/runtime": "https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@62ffe403c5af73499fe7f5767c6d60be26e250db", "@rstest/core": "0.11.12", "@types/node": "^24.0.0", "@types/react": "^19.2.18", "agent-bundle": "https://pkg.pr.new/ScriptedAlchemy/agent-bundle/agent-bundle@62ffe403c5af73499fe7f5767c6d60be26e250db", - "typescript": "7.0.2" + "grok-bot-cli": "file:..", + "react": "19.3.0", + "react-dom": "19.3.0", + "typescript": "7.0.2", + "zod": "4.6.5" } } diff --git a/plugin/src/gbot-install.ts b/plugin/src/gbot-install.ts new file mode 100644 index 0000000..c0e477b --- /dev/null +++ b/plugin/src/gbot-install.ts @@ -0,0 +1,14 @@ +import { fileURLToPath } from 'node:url'; + +import { runInstallCli } from 'agent-bundle/install'; + +/** + * `gbot-install install|uninstall ` and `gbot-install doctor`, bound to the + * emitted npm root (`plugin/dist` inside the `grok-bot-cli` tarball) that holds the + * Claude, Codex, and Cursor projections of the grok-bot plugin. + */ +export const main = (argv: readonly string[]): Promise => + runInstallCli(argv, { + from: fileURLToPath(new URL('..', import.meta.url)), + name: 'gbot-install', + }); diff --git a/test/release-config.test.js b/test/release-config.test.js index b85ce19..0d078fc 100644 --- a/test/release-config.test.js +++ b/test/release-config.test.js @@ -24,5 +24,9 @@ test("npm executable paths are already normalized for publishing", () => { assert.deepEqual(packageJson.bin, { gbot: "src/cli.js", "grok-bot": "src/cli.js", + "gbot-install": "plugin/dist/bin/gbot-install.js", }); + // The plugin's npm root ships with the CLI and is built before any pack. + assert.ok(packageJson.files.includes("plugin/dist")); + assert.equal(packageJson.scripts.prepack, "npm run --silent build:plugin 1>&2"); });