chore: release 0.3.0 with idx-mcp

Bump the workspace and npm packages to 0.3.0. The release workflow
builds and attaches idx-mcp binaries next to idx, the npm launcher and
installer pick their binary from package.json so npm/idx-mcp reuses
them, and the npm smoke test covers both packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
hermes 2026-10-14 19:01:29 +00:00
commit 8e3323e4f7
15 changed files with 186 additions and 92 deletions

View file

@ -16,6 +16,7 @@ on:
- "crates/*/Cargo.toml" - "crates/*/Cargo.toml"
- "Cargo.lock" - "Cargo.lock"
- "package.json" - "package.json"
- "npm/idx-mcp/package.json"
- "scripts/install.js" - "scripts/install.js"
- "install.sh" - "install.sh"
@ -69,19 +70,25 @@ jobs:
# Bundled SQLite and ring compile C code; build it against musl too. # Bundled SQLite and ring compile C code; build it against musl too.
export "CC_${target//-/_}=musl-gcc" export "CC_${target//-/_}=musl-gcc"
fi fi
cargo build --release --locked --target "$target" cargo build --release --locked --target "$target" -p idx-cli -p idx-mcp
cp "target/${{ matrix.target }}/release/idx" "idx-${{ matrix.asset }}" for bin in idx idx-mcp; do
chmod 0755 "idx-${{ matrix.asset }}" cp "target/${{ matrix.target }}/release/$bin" "$bin-${{ matrix.asset }}"
chmod 0755 "$bin-${{ matrix.asset }}"
done
- name: Check binary runs - name: Check binaries run
if: matrix.target != 'x86_64-apple-darwin' if: matrix.target != 'x86_64-apple-darwin'
run: ./idx-${{ matrix.asset }} --help >/dev/null run: |
./idx-${{ matrix.asset }} --help >/dev/null
./idx-mcp-${{ matrix.asset }} --help >/dev/null
- name: Upload target artifact - name: Upload target artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: idx-${{ matrix.asset }} name: idx-${{ matrix.asset }}
path: idx-${{ matrix.asset }} path: |
idx-${{ matrix.asset }}
idx-mcp-${{ matrix.asset }}
if-no-files-found: error if-no-files-found: error
publish: publish:
@ -105,7 +112,11 @@ jobs:
merge-multiple: true merge-multiple: true
- name: Write checksums - name: Write checksums
run: sha256sum idx-linux-x64 idx-linux-arm64 idx-darwin-arm64 idx-darwin-x64 > SHA256SUMS run: |
sha256sum \
idx-linux-x64 idx-linux-arm64 idx-darwin-arm64 idx-darwin-x64 \
idx-mcp-linux-x64 idx-mcp-linux-arm64 idx-mcp-darwin-arm64 idx-mcp-darwin-x64 \
> SHA256SUMS
- name: Attach binaries to the version tag - name: Attach binaries to the version tag
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
@ -116,5 +127,9 @@ jobs:
idx-linux-arm64 idx-linux-arm64
idx-darwin-arm64 idx-darwin-arm64
idx-darwin-x64 idx-darwin-x64
idx-mcp-linux-x64
idx-mcp-linux-arm64
idx-mcp-darwin-arm64
idx-mcp-darwin-x64
SHA256SUMS SHA256SUMS
src/install.sh src/install.sh

6
Cargo.lock generated
View file

@ -901,7 +901,7 @@ dependencies = [
[[package]] [[package]]
name = "idx-cli" name = "idx-cli"
version = "0.2.4" version = "0.3.0"
dependencies = [ dependencies = [
"assert_cmd", "assert_cmd",
"chrono", "chrono",
@ -921,7 +921,7 @@ dependencies = [
[[package]] [[package]]
name = "idx-core" name = "idx-core"
version = "0.2.4" version = "0.3.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"clap", "clap",
@ -940,7 +940,7 @@ dependencies = [
[[package]] [[package]]
name = "idx-mcp" name = "idx-mcp"
version = "0.2.4" version = "0.3.0"
dependencies = [ dependencies = [
"clap", "clap",
"idx-core", "idx-core",

View file

@ -3,7 +3,7 @@ resolver = "3"
members = ["crates/idx-core", "crates/idx-cli", "crates/idx-mcp"] members = ["crates/idx-core", "crates/idx-cli", "crates/idx-mcp"]
[workspace.package] [workspace.package]
version = "0.2.4" version = "0.3.0"
edition = "2024" edition = "2024"
rust-version = "1.85" rust-version = "1.85"
license = "MIT" license = "MIT"
@ -11,7 +11,7 @@ repository = "https://github.com/0xrsydn/idx-cli"
homepage = "https://github.com/0xrsydn/idx-cli" homepage = "https://github.com/0xrsydn/idx-cli"
[workspace.dependencies] [workspace.dependencies]
idx-core = { path = "crates/idx-core", version = "=0.2.4" } idx-core = { path = "crates/idx-core", version = "=0.3.0" }
clap = { version = "4", features = ["derive"] } clap = { version = "4", features = ["derive"] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["raw_value"] } serde_json = { version = "1", features = ["raw_value"] }

View file

@ -13,7 +13,7 @@ curl -fsSL https://raw.githubusercontent.com/0xrsydn/idx-cli/main/install.sh | s
Downloads the prebuilt `idx` binary for your platform from GitHub Releases, Downloads the prebuilt `idx` binary for your platform from GitHub Releases,
verifies it against the release `SHA256SUMS`, and installs it into verifies it against the release `SHA256SUMS`, and installs it into
`~/.local/bin` without sudo. Pin a version or change the directory with `~/.local/bin` without sudo. Pin a version or change the directory with
`sh -s -- --version v0.2.4 --dir ~/bin`. See [docs/INSTALL.md](docs/INSTALL.md). `sh -s -- --version v0.3.0 --dir ~/bin`. See [docs/INSTALL.md](docs/INSTALL.md).
### npm / npx ### npm / npx
@ -167,13 +167,17 @@ change it to `auto` with `idx config set general.output auto`.
`{data, source, fetched_at, stale}`; errors use the CLI's `{error, code, `{data, source, fetched_at, stale}`; errors use the CLI's `{error, code,
message}` body. It shares idx's config, cache, and ownership database. message}` body. It shares idx's config, cache, and ownership database.
Until it is released, build it from this repo: Install it like `idx` (npm, Cargo, or Nix), then register it with your MCP
client:
```bash ```bash
cargo install --path crates/idx-mcp # or: nix build .#idx-mcp claude mcp add idx -- npx -y idx-mcp # Claude Code, via npm
claude mcp add idx -- idx-mcp # Claude Code; other clients run `idx-mcp` cargo install idx-mcp # or build it (Rust 1.88+)
nix profile install github:0xrsydn/idx-cli#idx-mcp
``` ```
Other clients run the `idx-mcp` command over stdio.
Ownership tools need a populated database: run `idx ownership sync` once, or Ownership tools need a populated database: run `idx ownership sync` once, or
start the server with `idx-mcp --allow-sync` to expose an `ownership_sync` start the server with `idx-mcp --allow-sync` to expose an `ownership_sync`
tool (it downloads several MB). tool (it downloads several MB).

View file

@ -19,7 +19,6 @@ history lives in git.
- Additional providers (Alpha Vantage, Twelve Data, IDX official) - Additional providers (Alpha Vantage, Twelve Data, IDX official)
## Agent integration ## Agent integration
- Publish `idx-mcp` (crates.io, npm, release assets); see `docs/DESIGN.md` phase 5
- JSON Schema export for command output - JSON Schema export for command output
- Composite `analyze` command (quote, fundamentals, ownership, sentiment) - Composite `analyze` command (quote, fundamentals, ownership, sentiment)

View file

@ -1,6 +1,6 @@
# System Design: idx-core and its frontends # System Design: idx-core and its frontends
**Status:** Accepted 2026-10-14. Implementation on `refactor/idx-core`; phases 0-4 done. **Status:** Accepted 2026-10-14. Released in v0.3.0; phases 0-5 done.
## Goal ## Goal

View file

@ -11,7 +11,7 @@ Each release also carries a copy of the script as a release asset, so a
versioned URL stays stable: versioned URL stays stable:
```bash ```bash
curl -fsSL https://github.com/0xrsydn/idx-cli/releases/download/v0.2.4/install.sh | sh curl -fsSL https://github.com/0xrsydn/idx-cli/releases/download/v0.3.0/install.sh | sh
``` ```
## What it does ## What it does
@ -45,7 +45,7 @@ them yourself.
Pass flags through the pipe with `sh -s --`: Pass flags through the pipe with `sh -s --`:
```bash ```bash
curl -fsSL https://raw.githubusercontent.com/0xrsydn/idx-cli/main/install.sh | sh -s -- --version v0.2.4 --dir ~/bin curl -fsSL https://raw.githubusercontent.com/0xrsydn/idx-cli/main/install.sh | sh -s -- --version v0.3.0 --dir ~/bin
``` ```
## Supported platforms ## Supported platforms

View file

@ -1,6 +1,10 @@
# npm distribution # npm distribution
The npm package `idx-cli` is a small wrapper around the native `idx` binary. The npm packages `idx-cli` (repo root) and `idx-mcp` (`npm/idx-mcp/`) are small
wrappers around the native `idx` and `idx-mcp` binaries. Both use the same
launcher and installer from `scripts/`; the package's `nativeBinary` field
picks the binary, and `npm/idx-mcp` copies the scripts in at `prepack`.
The `idx-cli` package
The package keeps the JavaScript launcher and postinstall downloader. The The package keeps the JavaScript launcher and postinstall downloader. The
downloader selects a prebuilt GitHub Release asset for the current platform and downloader selects a prebuilt GitHub Release asset for the current platform and
places it at the path used by the `idx` bin entry. places it at the path used by the `idx` bin entry.
@ -14,6 +18,9 @@ Supported release assets:
| macOS arm64 | `aarch64-apple-darwin` | `idx-darwin-arm64` | | macOS arm64 | `aarch64-apple-darwin` | `idx-darwin-arm64` |
| macOS x64 | `x86_64-apple-darwin` | `idx-darwin-x64` | | macOS x64 | `x86_64-apple-darwin` | `idx-darwin-x64` |
`idx-mcp` assets use the same platforms with an `idx-mcp-` prefix, for
example `idx-mcp-linux-x64`.
The Linux binaries are statically linked against musl, so they do not depend The Linux binaries are statically linked against musl, so they do not depend
on the host glibc version. on the host glibc version.
@ -31,7 +38,7 @@ npx idx-cli --help
``` ```
The package version and the release tag must match. For example, package The package version and the release tag must match. For example, package
version `0.2.4` downloads assets from the `v0.2.4` GitHub Release. version `0.3.0` downloads assets from the `v0.3.0` GitHub Release.
The postinstall script downloads `SHA256SUMS` from the same release and The postinstall script downloads `SHA256SUMS` from the same release and
refuses to install a binary whose checksum does not match. refuses to install a binary whose checksum does not match.
@ -81,7 +88,7 @@ URLs must stay aligned with `scripts/install.js`.
To attach binaries to a tag that already exists, run the workflow manually: To attach binaries to a tag that already exists, run the workflow manually:
```bash ```bash
gh workflow run release.yml -f tag=v0.2.4 gh workflow run release.yml -f tag=v0.3.0
``` ```
Pull requests that touch the workflow or the installer run the build jobs Pull requests that touch the workflow or the installer run the build jobs
@ -89,9 +96,13 @@ without publishing, so target breakage shows up before a release.
Release order: Release order:
1. Push the tag, or run the workflow for an existing tag. 1. Bump the version together in `Cargo.toml` (workspace version and the
2. Confirm the release has all binaries plus `SHA256SUMS`. `idx-core` dependency pin), `package.json`, and `npm/idx-mcp/package.json`.
3. Run `npm publish` from the tagged commit. The account has two-factor auth, A version number can never be republished.
so npm asks for a browser approval or `--otp=<code>`. A version number 2. Push the tag, or run the workflow for an existing tag.
can never be republished, so bump `Cargo.toml` and `package.json` together 3. Publish the crates from the tagged commit, dependency first:
before tagging. `cargo publish -p idx-core`, then `-p idx-cli` and `-p idx-mcp`.
4. Confirm the release has all eight binaries plus `SHA256SUMS`.
5. Run `npm publish` in the repo root and in `npm/idx-mcp/` from the tagged
commit. The account has two-factor auth, so npm asks for a browser
approval or `--otp=<code>`.

1
npm/idx-mcp/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
scripts/

12
npm/idx-mcp/README.md Normal file
View file

@ -0,0 +1,12 @@
# idx-mcp
MCP server (stdio) for Indonesian stock market (IDX) data: quotes, price
history, screener, company financials, analysis, and KSEI shareholder
ownership. This package downloads the native `idx-mcp` binary for your
platform from the matching GitHub release and verifies its SHA-256.
```bash
claude mcp add idx -- npx -y idx-mcp
```
See https://github.com/0xrsydn/idx-cli#mcp-server for the tools and options.

34
npm/idx-mcp/package.json Normal file
View file

@ -0,0 +1,34 @@
{
"name": "idx-mcp",
"version": "0.3.0",
"description": "MCP server for Indonesian stock market (IDX) market, financial, and ownership data",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/0xrsydn/idx-cli.git",
"directory": "npm/idx-mcp"
},
"homepage": "https://github.com/0xrsydn/idx-cli",
"keywords": [
"idx",
"stocks",
"indonesia",
"finance",
"mcp"
],
"engines": {
"node": ">=16"
},
"nativeBinary": "idx-mcp",
"bin": {
"idx-mcp": "./scripts/idx.js"
},
"files": [
"scripts/idx.js",
"scripts/install.js"
],
"scripts": {
"prepack": "mkdir -p scripts && cp ../../scripts/idx.js ../../scripts/install.js scripts/",
"postinstall": "node scripts/install.js"
}
}

View file

@ -1,6 +1,6 @@
{ {
"name": "idx-cli", "name": "idx-cli",
"version": "0.2.4", "version": "0.3.0",
"description": "CLI tool for Indonesian stock market (IDX) analysis", "description": "CLI tool for Indonesian stock market (IDX) analysis",
"license": "MIT", "license": "MIT",
"repository": { "repository": {

View file

@ -5,12 +5,17 @@ const fs = require("node:fs");
const path = require("node:path"); const path = require("node:path");
const { spawn } = require("node:child_process"); const { spawn } = require("node:child_process");
const binaryName = process.platform === "win32" ? "idx.exe" : "idx"; const packageManifest = JSON.parse(
fs.readFileSync(path.join(__dirname, "..", "package.json"), "utf8"),
);
const nativeBinary = packageManifest.nativeBinary || "idx";
const packageName = packageManifest.name;
const binaryName = process.platform === "win32" ? `${nativeBinary}.exe` : nativeBinary;
const binaryPath = path.join(__dirname, "..", "bin", binaryName); const binaryPath = path.join(__dirname, "..", "bin", binaryName);
if (!fs.existsSync(binaryPath)) { if (!fs.existsSync(binaryPath)) {
console.error(`idx-cli: installed binary not found at ${binaryPath}`); console.error(`${packageName}: installed binary not found at ${binaryPath}`);
console.error("idx-cli: rerun npm install or set IDX_BINARY_URL for a local binary"); console.error(`${packageName}: rerun npm install or set IDX_BINARY_URL for a local binary`);
process.exit(1); process.exit(1);
} }
@ -24,7 +29,7 @@ for (const signal of ["SIGTERM", "SIGHUP"]) {
process.on("SIGINT", () => {}); process.on("SIGINT", () => {});
child.once("error", (error) => { child.once("error", (error) => {
console.error(`idx-cli: failed to start ${binaryPath}: ${error.message}`); console.error(`${packageName}: failed to start ${binaryPath}: ${error.message}`);
process.exit(1); process.exit(1);
}); });

View file

@ -13,7 +13,11 @@ const packageRoot = path.resolve(__dirname, "..");
const packageManifest = JSON.parse( const packageManifest = JSON.parse(
fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"), fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"),
); );
const binaryName = process.platform === "win32" ? "idx.exe" : "idx"; // The package names its native binary (`idx` or `idx-mcp`); release assets
// are named `<binary>-<platform>`.
const nativeBinary = packageManifest.nativeBinary || "idx";
const packageName = packageManifest.name;
const binaryName = process.platform === "win32" ? `${nativeBinary}.exe` : nativeBinary;
const binaryDirectory = path.join(packageRoot, "bin"); const binaryDirectory = path.join(packageRoot, "bin");
const binaryPath = path.join(binaryDirectory, binaryName); const binaryPath = path.join(binaryDirectory, binaryName);
const githubRepository = "0xrsydn/idx-cli"; const githubRepository = "0xrsydn/idx-cli";
@ -24,22 +28,22 @@ const targets = {
"linux/x64": { "linux/x64": {
label: "linux-x64", label: "linux-x64",
triple: "x86_64-unknown-linux-gnu", triple: "x86_64-unknown-linux-gnu",
asset: "idx-linux-x64", asset: `${nativeBinary}-linux-x64`,
}, },
"linux/arm64": { "linux/arm64": {
label: "linux-arm64", label: "linux-arm64",
triple: "aarch64-unknown-linux-gnu", triple: "aarch64-unknown-linux-gnu",
asset: "idx-linux-arm64", asset: `${nativeBinary}-linux-arm64`,
}, },
"darwin/arm64": { "darwin/arm64": {
label: "darwin-arm64", label: "darwin-arm64",
triple: "aarch64-apple-darwin", triple: "aarch64-apple-darwin",
asset: "idx-darwin-arm64", asset: `${nativeBinary}-darwin-arm64`,
}, },
"darwin/x64": { "darwin/x64": {
label: "darwin-x64", label: "darwin-x64",
triple: "x86_64-apple-darwin", triple: "x86_64-apple-darwin",
asset: "idx-darwin-x64", asset: `${nativeBinary}-darwin-x64`,
}, },
}; };
@ -111,7 +115,7 @@ function request(url, onResponse, redirects = 0) {
{ {
headers: { headers: {
Accept: "application/octet-stream", Accept: "application/octet-stream",
"User-Agent": `idx-cli-npm/${packageManifest.version}`, "User-Agent": `${packageName}-npm/${packageManifest.version}`,
}, },
}, },
(response) => { (response) => {
@ -226,7 +230,7 @@ async function main() {
// `npm install` inside the Rust checkout should not fetch a release binary. // `npm install` inside the Rust checkout should not fetch a release binary.
if (!override && fs.existsSync(path.join(packageRoot, "Cargo.toml"))) { if (!override && fs.existsSync(path.join(packageRoot, "Cargo.toml"))) {
console.log("idx-cli: source checkout detected; skipping binary download (set IDX_BINARY_URL to override)"); console.log(`${packageName}: source checkout detected; skipping binary download (set IDX_BINARY_URL to override)`);
return; return;
} }
@ -241,22 +245,22 @@ async function main() {
verifyChecksum(localPath, overrideSha256, localPath); verifyChecksum(localPath, overrideSha256, localPath);
} }
replaceWithLocalBinary(localPath); replaceWithLocalBinary(localPath);
console.log(`idx-cli: installed local binary from ${path.resolve(localPath)}`); console.log(`${packageName}: installed local binary from ${path.resolve(localPath)}`);
return; return;
} }
console.log(`idx-cli: downloading binary from IDX_BINARY_URL (${override})`); console.log(`${packageName}: downloading binary from IDX_BINARY_URL (${override})`);
} else { } else {
console.log(`idx-cli: downloading ${target.asset} for ${target.label} from ${source}`); console.log(`${packageName}: downloading ${target.asset} for ${target.label} from ${source}`);
} }
const expectedSha256 = override const expectedSha256 = override
? overrideSha256 ? overrideSha256
: await expectedReleaseChecksum(target.asset); : await expectedReleaseChecksum(target.asset);
await replaceWithDownloadedBinary(source, expectedSha256); await replaceWithDownloadedBinary(source, expectedSha256);
console.log(`idx-cli: installed binary at ${binaryPath}`); console.log(`${packageName}: installed binary at ${binaryPath}`);
} }
main().catch((error) => { main().catch((error) => {
console.error(`idx-cli: ${error.message}`); console.error(`${packageName}: ${error.message}`);
process.exit(1); process.exit(1);
}); });

View file

@ -3,7 +3,6 @@ set -Eeuo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
smoke_dir="$(mktemp -d "${TMPDIR:-/tmp}/idx-cli-npm-smoke.XXXXXX")" smoke_dir="$(mktemp -d "${TMPDIR:-/tmp}/idx-cli-npm-smoke.XXXXXX")"
install_dir="${smoke_dir}/install"
npm_cache="${smoke_dir}/npm-cache" npm_cache="${smoke_dir}/npm-cache"
cleanup() { cleanup() {
@ -21,31 +20,32 @@ trap on_error ERR
cd "$repo_root" cd "$repo_root"
release_binary="${repo_root}/target/release/idx" # Packs the npm package in <dir>, installs it with the local release binary,
if [[ -x "$release_binary" ]]; then # and checks that `<bin> --help` prints `<usage>`.
echo "npm smoke: reusing ${release_binary}" smoke_package() {
else local package_dir="$1" bin="$2" usage="$3"
echo "npm smoke: building ${release_binary}" local release_binary="${repo_root}/target/release/${bin}"
cargo build --release --locked local work="${smoke_dir}/${bin}"
fi local install_dir="${work}/install"
mkdir -p "$work" "$install_dir"
if [[ ! -x "$release_binary" ]]; then if [[ ! -x "$release_binary" ]]; then
echo "npm smoke: release binary was not produced at ${release_binary}" >&2 echo "npm smoke: release binary was not produced at ${release_binary}" >&2
exit 1 exit 1
fi fi
echo "npm smoke: packing wrapper" echo "npm smoke: packing ${package_dir}"
mkdir -p "$npm_cache" local tarball_name tarball
tarball_name="$(npm_config_cache="$npm_cache" npm pack --silent --pack-destination "$smoke_dir" | tail -n 1)" tarball_name="$(cd "$package_dir" && npm_config_cache="$npm_cache" npm pack --silent --pack-destination "$work" | tail -n 1)"
tarball="${smoke_dir}/${tarball_name}" tarball="${work}/${tarball_name}"
if [[ -z "$tarball_name" || ! -f "$tarball" ]]; then if [[ -z "$tarball_name" || ! -f "$tarball" ]]; then
echo "npm smoke: expected tarball was not produced at ${tarball}" >&2 echo "npm smoke: expected tarball was not produced at ${tarball}" >&2
exit 1 exit 1
fi fi
mkdir -p "$install_dir" local binary_url
binary_url="$(node -e 'const { pathToFileURL } = require("node:url"); process.stdout.write(pathToFileURL(process.argv[1]).href)' "$release_binary")" binary_url="$(node -e 'const { pathToFileURL } = require("node:url"); process.stdout.write(pathToFileURL(process.argv[1]).href)' "$release_binary")"
echo "npm smoke: installing tarball into ${install_dir}" echo "npm smoke: installing ${tarball_name} into ${install_dir}"
npm_config_cache="$npm_cache" IDX_BINARY_URL="$binary_url" npm install \ npm_config_cache="$npm_cache" IDX_BINARY_URL="$binary_url" npm install \
--prefix "$install_dir" \ --prefix "$install_dir" \
"$tarball" \ "$tarball" \
@ -55,20 +55,29 @@ npm_config_cache="$npm_cache" IDX_BINARY_URL="$binary_url" npm install \
--no-fund \ --no-fund \
--foreground-scripts --foreground-scripts
resolved_bin="${install_dir}/node_modules/.bin/idx" local resolved_bin="${install_dir}/node_modules/.bin/${bin}"
if [[ ! -x "$resolved_bin" ]]; then if [[ ! -x "$resolved_bin" ]]; then
echo "npm smoke: npm did not create an executable bin link at ${resolved_bin}" >&2 echo "npm smoke: npm did not create an executable bin link at ${resolved_bin}" >&2
exit 1 exit 1
fi fi
help_output="${smoke_dir}/help.txt" echo "npm smoke: running installed ${bin} --help"
echo "npm smoke: running installed idx --help" "$resolved_bin" --help | tee "${work}/help.txt"
"$resolved_bin" --help | tee "$help_output" if ! grep -q "$usage" "${work}/help.txt"; then
if ! grep -q "Usage: idx" "$help_output"; then echo "npm smoke: ${bin} --help did not contain '${usage}'" >&2
echo "npm smoke: --help output did not contain the expected usage line" >&2
exit 1 exit 1
fi fi
}
echo "npm smoke: running installed idx config --help" if [[ -x target/release/idx && -x target/release/idx-mcp ]]; then
"$resolved_bin" config --help echo "npm smoke: reusing target/release/{idx,idx-mcp}"
echo "npm smoke: PASS (pack, install, --help, and config --help)" else
echo "npm smoke: building release binaries"
cargo build --release --locked -p idx-cli -p idx-mcp
fi
mkdir -p "$npm_cache"
smoke_package "$repo_root" idx "Usage: idx"
"${smoke_dir}/idx/install/node_modules/.bin/idx" config --help >/dev/null
smoke_package "${repo_root}/npm/idx-mcp" idx-mcp "Usage: idx-mcp"
echo "npm smoke: PASS (idx-cli and idx-mcp: pack, install, --help)"