diff --git a/CHANGELOG.md b/CHANGELOG.md index 19b997a..6f17b42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,13 @@ All notable changes to the qqq CLI and its packages. Versions follow [semver](https://semver.org); `@qrun-io/qqq-ui-api-client` follows the UI API version of the document it is generated from. -## [1.0.0-rc.1] - 2026-10-31 +## [1.0.0] - YYYY-MM-DD -First release candidate of `qqq` 1.0: the command-line client and the full-screen terminal UI -(`qqq ui`), shipped together as one binary per platform. Packages: `@qrun-io/qqq-cli` 1.0.0-rc.1, -`@qrun-io/qqq-core` 1.0.0-rc.1 (new), `@qrun-io/qqq-ui-api-client` 1.8.0-rc.2, -`@qrun-io/qqq-ui-api-conformance` 1.6.0-rc.2. Servers: UI API 1.6.0 up to 2.0. This entry becomes the -1.0.0 entry. +`qqq` 1.0: the command-line client and the full-screen terminal UI (`qqq ui`), shipped together as one +binary per platform. Packages: `@qrun-io/qqq-cli` 1.0.0, `@qrun-io/qqq-core` 1.0.0 (new), +`@qrun-io/qqq-ui-api-client` 1.8.0, `@qrun-io/qqq-ui-api-conformance` 1.6.0. Servers: UI API 1.6.0 up +to 2.0. Released as 1.0.0-rc.1 first (tags `v1.8.0-rc.2`, `cli-v1.0.0-rc.1`); this entry is that +candidate's, unchanged in content. ### Changed from 0.1 diff --git a/README.md b/README.md index d19e554..6d59c0a 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,17 @@ QQQ server only through the **UI API** (`/qqq/v1`), the API the web UI uses too. application is built in: apps, tables, fields, processes, widgets and extensions all come from the server's metadata, so the same binary works against any QQQ application. -This is **1.0.0-rc.1**, the first release candidate. It works with servers that serve UI API 1.6.0 up to +This is **1.0.0**. It works with servers that serve UI API 1.6.0 up to 2.0 (QQQ 4.1.0-RC.15 or later); `qqq --version` prints the range. The repository also holds the libraries the CLI is built on, for anyone writing a CLI, TUI or native client: | Package | Version | What it is | |---|---|---| -| [`@qrun-io/qqq-cli`](packages/cli) | 1.0.0-rc.1 | `qqq`, the CLI | -| [`@qrun-io/qqq-core`](packages/core) | 1.0.0-rc.1 | the client kernel: sessions and keyring, metadata cache, filter grammar, forms, processes, records, render model, output formats. No terminal code | -| [`@qrun-io/qqq-ui-api-client`](packages/ui-api-client) | 1.8.0-rc.2 | a typed TypeScript client generated from the merged UI API document (core plus 13 extensions), with OAuth2 device-flow and PKCE sign-in, token refresh and the realtime (SSE) stream | -| [`@qrun-io/qqq-ui-api-conformance`](packages/conformance) | 1.6.0-rc.2 | a read-only conformance suite for any UI API server, and `qqq-dev-idp`, a local OIDC provider for testing native clients | +| [`@qrun-io/qqq-cli`](packages/cli) | 1.0.0 | `qqq`, the CLI | +| [`@qrun-io/qqq-core`](packages/core) | 1.0.0 | the client kernel: sessions and keyring, metadata cache, filter grammar, forms, processes, records, render model, output formats. No terminal code | +| [`@qrun-io/qqq-ui-api-client`](packages/ui-api-client) | 1.8.0 | a typed TypeScript client generated from the merged UI API document (core plus 13 extensions), with OAuth2 device-flow and PKCE sign-in, token refresh and the realtime (SSE) stream | +| [`@qrun-io/qqq-ui-api-conformance`](packages/conformance) | 1.6.0 | a read-only conformance suite for any UI API server, and `qqq-dev-idp`, a local OIDC provider for testing native clients | | [`packages/tui`](packages/tui) | in the binaries | `qqq ui`, the full-screen terminal UI (OpenTUI on Bun), bundled into every `qqq` binary; not an npm package | ## Install @@ -29,7 +29,7 @@ curl -fsSL https://raw.githubusercontent.com/QRun-IO/qqq-cli/main/scripts/instal ``` The installer picks the right build and checks it against the release's `SHA256SUMS` -(`--version 1.0.0-rc.1`, `--dir /usr/local/bin`). Homebrew (`brew install qrun-io/tap/qqq`) and Scoop +(`--version 1.0.0`, `--dir /usr/local/bin`). Homebrew (`brew install qrun-io/tap/qqq`) and Scoop packages are prepared in [`docs/packaging`](docs/packaging/README.md) and land with the release. **macOS, downloaded with a browser:** until the binaries are notarized, Gatekeeper stops a binary that a @@ -42,7 +42,7 @@ Or the CLI alone from npm (GitHub Packages), with Node.js 20 or later (no `qqq u ```sh echo "@qrun-io:registry=https://npm.pkg.github.com" >> ~/.npmrc -npm install -g @qrun-io/qqq-cli@rc +npm install -g @qrun-io/qqq-cli ``` ## First sign-in diff --git a/TRY-IT.md b/TRY-IT.md index 4be98b5..19cff0e 100644 --- a/TRY-IT.md +++ b/TRY-IT.md @@ -21,12 +21,12 @@ and say when a new build is ready. After a reboot, `qqq-sample-server start` aga ## Try the release binary (`qqq-bin`) -`qqq-bin` on this machine (`~/.local/bin/qqq-bin`) is the darwin-arm64 release-candidate binary: the CLI +`qqq-bin` on this machine (`~/.local/bin/qqq-bin`) is the darwin-arm64 release binary: the CLI and the terminal UI in one file, no Node or Bun. It is the same build a user downloads; `qqq` stays the from-source launcher. Both use the same profiles and keychain items. ```sh -qqq-bin --version # qqq 1.0.0-rc.1 (darwin-arm64 binary with ui, , bun 1.4.4) +qqq-bin --version # qqq 1.0.0 (darwin-arm64 binary with ui, , bun 1.4.4) qqq-bin doctor # first line: the build, runtime and platform; then server, sign-in, terminal qqq-bin --profile sample ui # the terminal UI from the binary qqq-bin ui --check # the terminal check, with the build line support asks for diff --git a/docs/release-notes/1.0.0.md b/docs/release-notes/1.0.0.md new file mode 100644 index 0000000..3075c16 --- /dev/null +++ b/docs/release-notes/1.0.0.md @@ -0,0 +1,111 @@ + + +# qqq 1.0.0 + +**qqq 1.0**: the command-line client and the full-screen terminal UI for +[QQQ](https://github.com/QRun-IO/qqq) applications, in **one binary per platform**. Everything comes from +the server's metadata through the QQQ UI API, so the same binary works with any QQQ application. + +Works with servers on UI API 1.6.0 up to 2.0 (QQQ 4.1.0-RC.15 or later). `qqq --version` shows the range. + +## Install + +```sh +curl -fsSL https://raw.githubusercontent.com/QRun-IO/qqq-cli/main/scripts/install.sh | sh -s -- --version 1.0.0 +``` + +Or download the binary for your platform below and check it against `SHA256SUMS`: + +| Platform | File | +|---|---| +| macOS, Apple silicon | `qqq-darwin-arm64` | +| macOS, Intel | `qqq-darwin-x64` | +| Linux x64 / arm64 (glibc) | `qqq-linux-x64`, `qqq-linux-arm64` | +| Linux x64 / arm64 (musl, Alpine: `apk add libstdc++ libgcc`) | `qqq-linux-x64-musl`, `qqq-linux-arm64-musl` | +| Windows x64 | `qqq-windows-x64.exe` | + +The npm package (`npm install -g @qrun-io/qqq-cli` from GitHub Packages, Node 20+) has the CLI +without the terminal UI. + +**macOS:** these binaries are not notarized yet. A binary downloaded with a browser is stopped by +Gatekeeper; clear the flag once with `xattr -d com.apple.quarantine ./qqq-darwin-arm64`. The installer +above does not set it. **Windows:** the `.exe` is not signed yet, so SmartScreen may warn on first run. + +## Get started + +```sh +qqq login --server https://your-qqq-server # device flow, browser (PKCE), Auth0, TABLE_BASED or a session +qqq home # what you can open and do +qqq table query person -w "lastName STARTS_WITH S" -o -id -l 5 +qqq process run greetInteractive -r 1,2 -v greetingPrefix=Hi +qqq ui # the terminal UI on the same profile +qqq doctor # connection, sign-in, terminal, and the build for support +``` + +## What is in it + +**The terminal UI (`qqq ui`)**: a classic full-screen UI with a function-key bar, Home, the F9 command +center and F2 go-to, a server-paged grid (sort, filter builder or grammar, quick search, statistics, saved +views, variants, export), records with forms, contingent pickers, uploads and downloads, audits, tags and +sharing, the process wizard, the bulk-load wizard, reports and saved-report editors, dashboards and +widgets that act, developer mode, F1 help from the application, every sign-in type, themes, and a terminal +check that finds tmux key and colour problems and offers fixes. + +**The CLI (`qqq `)**: tables (query, count, stats, get, create, copy, update, delete, export, +children, downloads and uploads, variants, columns), bulk insert, edit and delete from CSV or Excel, +processes with every step screen, async jobs and cancel, reports and saved reports (pivots, schedules), +saved views, sharing, audits, widgets and dashboards as text, home and find, preferences, help, every +extension the server installs (`qqq esb`, `qqq collab`, ...), developer mode, and `qqq api` for any of +the 202 UI API operations. JSON, table, text, CSV and YAML output with JMESPath `--query`; shell +completion for bash, zsh, fish and PowerShell; sign-ins in the OS keyring; profiles like `aws --profile`. + +**Parity**: every row of the web UI's acceptance matrix that applies to a terminal passes in both the CLI +and the UI, or is blocked on a filed server issue. + +## Known limitations + +- Text filters ask the server for case-insensitive matching, but servers do not read that option over the + UI API yet (qqq#1358), so matching stays case-sensitive until they do. +- Jobs need a server with durable jobs. Auth0 sign-in has not been tried against a real tenant. +- The Windows and Intel macOS binaries are cross-compiled; until the macOS and Windows CI lanes run, they + are not tested before a release. + +Full list of changes: [CHANGELOG.md](https://github.com/QRun-IO/qqq-cli/blob/main/CHANGELOG.md). diff --git a/docs/release-runbook.md b/docs/release-runbook.md index 454a9e6..dfcbd02 100644 --- a/docs/release-runbook.md +++ b/docs/release-runbook.md @@ -70,6 +70,20 @@ smoke against the sample server), linux-x64 glibc, linux-arm64 glibc and linux-a ## 2. Versions: release candidate to final +**For 1.0.0 this step is already done** on the branch `release/1.0.0` (one commit on top of the rc.1 +commit 6517373): all four packages final, the exact workspace pins, `## [1.0.0] - YYYY-MM-DD` in the +CHANGELOG (fill in the date), `docs/release-notes/1.0.0.md`, and the README at 1.0.0. The day rc.1 +feedback is accepted, that branch is fast-forwarded onto `main` (after any rc fixes have been merged into +it); nothing else changes versions: + +```sh +git checkout main && git pull --ff-only +git merge --ff-only release/1.0.0 # fails if main moved: rebase release/1.0.0 onto main first +git push origin main +``` + +For later releases, the table below is the recipe. + On a branch `release/1.0.0` from `main`: | File | Change | diff --git a/package-lock.json b/package-lock.json index 4f034a6..10fc132 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2954,12 +2954,12 @@ }, "packages/cli": { "name": "@qrun-io/qqq-cli", - "version": "1.0.0-rc.1", + "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "@qrun-io/qqq-core": "1.0.0-rc.1", - "@qrun-io/qqq-ui-api-client": "1.8.0-rc.2", - "@qrun-io/qqq-ui-api-conformance": "1.6.0-rc.2", + "@qrun-io/qqq-core": "1.0.0", + "@qrun-io/qqq-ui-api-client": "1.8.0", + "@qrun-io/qqq-ui-api-conformance": "1.6.0", "commander": "15.0.0" }, "bin": { @@ -2971,7 +2971,7 @@ }, "packages/conformance": { "name": "@qrun-io/qqq-ui-api-conformance", - "version": "1.6.0-rc.2", + "version": "1.6.0", "license": "Apache-2.0", "dependencies": { "ajv": "8.20.0" @@ -2986,10 +2986,10 @@ }, "packages/core": { "name": "@qrun-io/qqq-core", - "version": "1.0.0-rc.1", + "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "@qrun-io/qqq-ui-api-client": "1.8.0-rc.2", + "@qrun-io/qqq-ui-api-client": "1.8.0", "jmespath": "0.16.0", "yaml": "2.9.1" }, @@ -3002,7 +3002,7 @@ }, "packages/ui-api-client": { "name": "@qrun-io/qqq-ui-api-client", - "version": "1.8.0-rc.2", + "version": "1.8.0", "license": "Apache-2.0", "dependencies": { "openapi-fetch": "0.17.0" diff --git a/packages/cli/README.md b/packages/cli/README.md index dfcf9b3..67f8345 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -6,7 +6,7 @@ field and process comes from the server's metadata. ```sh echo "@qrun-io:registry=https://npm.pkg.github.com" >> ~/.npmrc -npm install -g @qrun-io/qqq-cli@rc +npm install -g @qrun-io/qqq-cli qqq login --server https://admin.example.com qqq table query person -w "lastName STARTS_WITH S" -o -id -l 5 ``` diff --git a/packages/cli/package.json b/packages/cli/package.json index 1583a18..c367494 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@qrun-io/qqq-cli", - "version": "1.0.0-rc.1", + "version": "1.0.0", "description": "Reference command-line client for QQQ applications, built only on the QQQ UI API (/qqq/v1).", "keywords": [ "qqq", @@ -56,9 +56,9 @@ "prepack": "node ../../scripts/copy-license.mjs" }, "dependencies": { - "@qrun-io/qqq-core": "1.0.0-rc.1", - "@qrun-io/qqq-ui-api-client": "1.8.0-rc.2", - "@qrun-io/qqq-ui-api-conformance": "1.6.0-rc.2", + "@qrun-io/qqq-core": "1.0.0", + "@qrun-io/qqq-ui-api-client": "1.8.0", + "@qrun-io/qqq-ui-api-conformance": "1.6.0", "commander": "15.0.0" } } diff --git a/packages/cli/src/version.ts b/packages/cli/src/version.ts index e5a5c67..64c5f32 100644 --- a/packages/cli/src/version.ts +++ b/packages/cli/src/version.ts @@ -18,7 +18,7 @@ declare const QQQ_BUILD_SHA: string | undefined declare const QQQ_BUILD_TARGET: string | undefined declare const QQQ_BUILD_UI: boolean | undefined -export const CLI_VERSION = '1.0.0-rc.1' +export const CLI_VERSION = '1.0.0' /** The oldest UI API a server may serve for this CLI (operationIds, clientCapabilities and traceId since 1.6.0). */ export const UI_API_MIN_VERSION = '1.6.0' diff --git a/packages/conformance/package.json b/packages/conformance/package.json index fe42428..c6822fe 100644 --- a/packages/conformance/package.json +++ b/packages/conformance/package.json @@ -1,6 +1,6 @@ { "name": "@qrun-io/qqq-ui-api-conformance", - "version": "1.6.0-rc.2", + "version": "1.6.0", "description": "Black-box conformance suite for QQQ UI API (/qqq/v1) servers, plus qqq-dev-idp, a local OIDC provider for testing native clients.", "license": "Apache-2.0", "type": "module", diff --git a/packages/core/package.json b/packages/core/package.json index 9c09c52..93a7baa 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@qrun-io/qqq-core", - "version": "1.0.0-rc.1", + "version": "1.0.0", "description": "Client kernel for QQQ terminal clients: sessions, metadata, filter grammar, records, processes, jobs, render model and output formats. No terminal code.", "keywords": [ "qqq", @@ -47,7 +47,7 @@ "prepack": "node ../../scripts/copy-license.mjs" }, "dependencies": { - "@qrun-io/qqq-ui-api-client": "1.8.0-rc.2", + "@qrun-io/qqq-ui-api-client": "1.8.0", "jmespath": "0.16.0", "yaml": "2.9.1" }, diff --git a/packages/ui-api-client/package.json b/packages/ui-api-client/package.json index dd4f945..e3ce06c 100644 --- a/packages/ui-api-client/package.json +++ b/packages/ui-api-client/package.json @@ -1,6 +1,6 @@ { "name": "@qrun-io/qqq-ui-api-client", - "version": "1.8.0-rc.2", + "version": "1.8.0", "description": "Typed TypeScript client for the QQQ UI API (/qqq/v1), generated from the merged OpenAPI document (core + extensions), with OAuth2 device-flow sign-in, token refresh and a realtime (SSE) reader.", "keywords": [ "qqq",