diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3d18d2b..ceb1d96 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,8 @@ jobs: - run: npm run build + # Publishes `upstash` (the name in package.json), then the same build + # again as @upstash/cli so existing installs keep getting releases. - name: Publish release candidate if: github.event.release.prerelease run: npm publish --access public --tag=canary --provenance @@ -38,3 +40,16 @@ jobs: - name: Publish if: "!github.event.release.prerelease" run: npm publish --access public --provenance + + - name: Rename the package to @upstash/cli + run: | + jq '.name = "@upstash/cli"' package.json > package.tmp.json + mv package.tmp.json package.json + + - name: Publish @upstash/cli release candidate + if: github.event.release.prerelease + run: npm publish --access public --tag=canary --provenance + + - name: Publish @upstash/cli + if: "!github.event.release.prerelease" + run: npm publish --access public --provenance diff --git a/README.md b/README.md index e09b9b6..0d9363e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Upstash CLI [![GitHub release](https://img.shields.io/github/v/release/upstash/cli)](https://github.com/upstash/cli/releases/latest) -[![npm downloads](https://img.shields.io/npm/dw/@upstash/cli.svg)](https://npmjs.org/package/@upstash/cli) +[![npm downloads](https://img.shields.io/npm/dw/upstash.svg)](https://npmjs.org/package/upstash) Agent-friendly CLI for managing & debugging Upstash resources from your terminal. [Docs](https://upstash.com/docs/agent-resources/cli). @@ -10,9 +10,11 @@ Agent-friendly CLI for managing & debugging Upstash resources from your terminal Requires Node.js 20 or newer. ```bash -npm i -g @upstash/cli +npm i -g upstash ``` +The same build is also published as `@upstash/cli`, with the same version, so existing installs keep working. + For agents, pair the CLI with the [Upstash Skill](https://docs.upstash.com/agent-resources/skills), it bundles Upstash docs alongside docs for the `upstash` CLI. ```bash @@ -24,9 +26,11 @@ npx skills add upstash/skills One command wires Upstash into your coding agents: ```bash -npx @upstash/cli setup +npx upstash ``` +With no arguments in a terminal, `upstash` runs `upstash setup`. From an agent or a script, a bare `upstash` prints the help instead, so run `upstash setup` explicitly there. + It picks the best install path per agent: | Agent | What gets installed | diff --git a/package-lock.json b/package-lock.json index ada0576..4d2dd4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "@upstash/cli", + "name": "upstash", "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@upstash/cli", + "name": "upstash", "version": "0.0.0", "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index ed3cf19..7ba2027 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@upstash/cli", + "name": "upstash", "version": "0.0.0", "description": "Agent-friendly CLI for Upstash", "repository": { diff --git a/src/cli.ts b/src/cli.ts index 881703a..6f8a824 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -14,6 +14,7 @@ import { registerStartRedis } from "./commands/start-redis.js"; import { registerTelemetry } from "./commands/telemetry.js"; import { registerSetup } from "./commands/setup.js"; import { handleError } from "./output.js"; +import { withDefaultCommand } from "./default-command.js"; import dotenv from "dotenv"; // Pre-scan argv for --env-path before Commander parses, so dotenv loads @@ -53,4 +54,6 @@ registerSearch(program); registerQStash(program); registerBlob(program); -program.parseAsync().catch(handleError); +const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY); +const args = withDefaultCommand(process.argv.slice(2), interactive); +program.parseAsync(args, { from: "user" }).catch(handleError); diff --git a/src/default-command.ts b/src/default-command.ts new file mode 100644 index 0000000..a84f4af --- /dev/null +++ b/src/default-command.ts @@ -0,0 +1,9 @@ +/** + * A bare `upstash` in a terminal is the agent setup entry point, so + * `npx upstash` connects your coding agents. Outside a terminal (an agent, a + * script, CI) it keeps the default help output, so it never rewrites agent + * configs unasked. + */ +export function withDefaultCommand(args: string[], interactive: boolean): string[] { + return args.length === 0 && interactive ? ["setup"] : args; +} diff --git a/tests/unit/default-command.test.ts b/tests/unit/default-command.test.ts new file mode 100644 index 0000000..599b9d9 --- /dev/null +++ b/tests/unit/default-command.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from "vitest"; +import { withDefaultCommand } from "../../src/default-command.js"; + +describe("bare `upstash`", () => { + it("runs setup in a terminal", () => { + expect(withDefaultCommand([], true)).toEqual(["setup"]); + }); + + it("keeps the help outside a terminal, so agents never trigger setup", () => { + expect(withDefaultCommand([], false)).toEqual([]); + }); + + it("passes every other invocation through unchanged", () => { + expect(withDefaultCommand(["redis", "list"], true)).toEqual(["redis", "list"]); + expect(withDefaultCommand(["--version"], true)).toEqual(["--version"]); + }); +});