Skip to content

feat(cli): improve tigris init and add npx tigris alias - #230

Merged
designcode merged 1 commit into
mainfrom
feat/cli-init-improvements
Aug 4, 2026
Merged

feat(cli): improve tigris init and add npx tigris alias#230
designcode merged 1 commit into
mainfrom
feat/cli-init-improvements

Conversation

@designcode

@designcode designcode commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two changes to tigris init, plus the package that makes npx tigris init work.

init no longer offers to install a CLI you already have

The wizard advertised CLI - Global in its "Defaults" hint and ran a CLI step on every run, regardless of whether tigris was already on PATH. Now:

  • The PATH check moved ahead of the mode prompt, so the hint reflects reality:

    hint
    tigris on PATH MCP - Global, Skills - Project
    not on PATH CLI - Global, MCP - Global, Skills - Project
  • An existing install is updated rather than reinstalled, by delegating to tigris update. That command runs its own registry check and getUpdateCommand() picks the path matching how the CLI was installed — npm install -g, brew upgrade tigris, or the curl/PowerShell installer for standalone binaries. Forcing npm install -g from init could fail or leave a second copy on PATH. It's a no-op when current, so nothing needs checking before calling it — which let the bespoke fetchLatestVersionCapped helper and its ref'd-timer handling go away entirely.

  • If that update fails (offline, no write permission), it can leave a CLI predating init --agent in place. Handing such an agent tigris init --agent just errors, so the handoff degrades to npx. Detected by probing (--agent only writes to stdout, captured and discarded) rather than comparing against a hardcoded 3.5.0, so it stays correct as the recipe moves.

init --agent picks the CLI step instead of delegating the decision

The recipe used to print both branches and let the agent evaluate them:

1. If `tigris` isn't on $PATH (`command -v tigris`), ask permission, then `npm install -g ...`.
2. If `tigris` is on $PATH, ensure it's latest version using `tigris update`.
3. Check if the user is already authenticated ...

init already knows which applies, so it now emits one unambiguous step and renumbers the rest:

tigris on PATH:   1. Ensure the CLI is on the latest version: `tigris update`.
not on PATH:      1. Ask permission, then install the CLI: `npm install -g @tigrisdata/cli --ignore-scripts`.

New tigris package

An unscoped alias so the CLI is reachable without the scope:

npx tigris init

bin.js is one line — import '@tigrisdata/cli' — which runs the CLI in-process, so argv, stdio, signals and exit codes all pass through unchanged, and --version/help still report the real CLI (Commander takes its program name from specs.yaml, not the filename). Every command works, not just init.

.changeset/config.json gains "fixed": [["@tigrisdata/cli", "tigris"]] so the alias can never drift from the CLI it wraps.

Testing

  • pnpm test — 811 pass, 214 skipped. Added test/lib/init/{plan,shared}.test.ts (10 tests); init had none before.
  • pnpm lint, tsc --noEmit, and the binary tsconfig.binary.json typecheck all clean. publint clean on both packages.
  • Both recipe branches exercised against the built CLI, with and without tigris on PATH.
  • Confirmed empirically that init --agent shipped in 3.5.0: 3.4.3 and older exit 1 with unknown option '--agent', which is what the handoff probe keys on.
  • Wrapper installed from a publish-shaped tarball against the registry CLI — both tigris and t3 bins work, including through npx.
  • Dry-ran changeset version and reverted: both packages land on 3.7.0.

⚠️ Before this releases

npm trusted publishing must be configured for the tigris package name. The release workflow publishes via OIDC with no NODE_AUTH_TOKEN, and tigris currently exists on npm as a 0.0.0 placeholder that predates this repo. If the trusted publisher isn't set up, @tigrisdata/cli@3.7.0 will publish and tigris will fail — leaving npx tigris resolving to the placeholder, which the wizard's fallback handoff now points users at.

Follow-up (not in this PR)

init isn't in the generated CLI README at all — #203 added the command without running pnpm updatedocs. Regenerating produces a large unrelated diff, so I left it out; happy to do it separately.

🤖 Generated with Claude Code


Note

Medium Risk
Onboarding and global npm publish path change; mistaken PATH handling could mis-detect installs, and the new tigris package must publish correctly or npx handoffs break.

Overview
tigris init now treats an on-PATH CLI as already installed: the Defaults hint omits CLI - Global, existing installs are refreshed via tigris update (not forced npm install -g), and the agent handoff uses npx tigris init --agent when update fails or the CLI is too old for init --agent.

When run via npx/pnpm dlx, PATH is scrubbed of throwaway runner .bin dirs so init does not mistake the ephemeral binary for a real install.

tigris init --agent prints one resolved first step (install or update) via buildAgentSetup, instead of both PATH branches for the agent to interpret.

Adds the unscoped tigris package (re-exports @tigrisdata/cli) so npx tigris works; changesets fixed @tigrisdata/cli and tigris together. New tests cover the agent recipe and PATH helpers.

Reviewed by Cursor Bugbot for commit c49efff. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR improves CLI detection and agent setup instructions while adding an unscoped tigris npm alias.

  • Moves CLI detection ahead of interactive setup choices and delegates existing installations to tigris update.
  • Generates an install-or-update agent recipe based on detected CLI availability.
  • Adds the tigris wrapper package and fixes its release version to @tigrisdata/cli.
  • Updates documentation, command examples, tests, and the workspace lockfile.

Confidence Score: 4/5

The PR should not merge until npx tigris init --agent correctly recognizes that its transient executable is not a persistent CLI installation.

The newly advertised npx path inherits a temporary tigris binary on PATH, causing the generated recipe to omit installation even though every later setup command requires tigris after the npx process exits.

Files Needing Attention: packages/cli/src/lib/init/index.ts and packages/cli/src/lib/init/shared.ts

Important Files Changed

Filename Overview
packages/cli/src/lib/init/index.ts Selects the agent recipe from PATH detection, but npx's transient executable is misclassified as a persistent installation.
packages/cli/src/lib/init/interactive.ts Reworks install/update behavior and introduces capability-based fallback after failed updates.
packages/cli/src/lib/init/plan.ts Refactors the static agent recipe into a generated, consecutively numbered install-or-update plan.
packages/cli/src/lib/init/shared.ts Centralizes CLI detection and spawn options, though inherited PATH cannot distinguish npx from a global installation.
packages/tigris/package.json Defines the public unscoped alias package with CLI bins and a workspace dependency on the scoped CLI.
packages/tigris/bin.js Delegates execution in-process to the scoped CLI package.
.changeset/config.json Keeps the alias and scoped CLI package versions fixed together.

Reviews (1): Last reviewed commit: "feat(cli): skip CLI install in init when..." | Re-trigger Greptile

Comment thread packages/cli/src/lib/init/index.ts
@designcode
designcode force-pushed the feat/cli-init-improvements branch from e579f48 to 810ad19 Compare August 4, 2026 07:37

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 810ad19. Configure here.

Comment thread packages/cli/src/lib/init/shared.ts
`tigris init` advertised and ran a CLI install step even when `tigris` was
already on PATH. It now installs only when the CLI is missing and updates it
otherwise, and the CLI is reachable unscoped as `npx tigris`.

- Move the PATH check ahead of the mode prompt so the "Defaults" hint drops
  `CLI - Global` when the CLI is already installed.
- Replace the bespoke registry fetch with a delegation to `tigris update`,
  which runs its own version check and picks the upgrade path matching how
  the CLI was installed (npm / Homebrew / standalone binary). Removes
  `fetchLatestVersionCapped` and its ref'd-timer handling.
- Ignore package-runner bin directories when looking for an installed CLI.
  `npx`, `pnpm dlx`, `yarn dlx` and `bunx` all unpack into a throwaway tree
  and put its `.bin` on PATH for one run, so an unfiltered probe finds a copy
  that vanishes when the runner exits — and init would tell the agent to
  update a CLI that was never installed. The directory is derived from this
  process's own location rather than from each manager's cache layout, and is
  stripped for the whole command so the update and handoff paths can't reach
  it either.
- Fall back to `npx` for the agent handoff when an update fails and leaves a
  CLI predating `init --agent` (< 3.5.0), probed rather than version-matched.
- Build the `--agent` recipe from a step list so it opens with a single CLI
  step chosen from what `init` detected — install when missing, update when
  present — instead of two steps behind `if tigris isn't on $PATH` conditions.
- Add `packages/tigris`: an unscoped alias whose bin imports `@tigrisdata/cli`,
  so argv, stdio, signals and exit codes pass through unchanged. Held to the
  CLI's version by a Changesets `fixed` group so the alias can't drift.
- Add tests for the recipe, the defaults hint, and the PATH filtering; init
  had none.

Assisted-by: Claude Opus 5 via Claude Code

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@designcode
designcode force-pushed the feat/cli-init-improvements branch from 810ad19 to c49efff Compare August 4, 2026 07:57
@designcode
designcode merged commit 931178a into main Aug 4, 2026
2 checks passed
@designcode
designcode deleted the feat/cli-init-improvements branch August 4, 2026 08:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants