Skip to content

Commit 775653f

Browse files
authored
Merge pull request #380 from ably/release/v1.0.0
chore: prepare release 1.0.0
2 parents fb7b371 + d6c684e commit 775653f

9 files changed

Lines changed: 65 additions & 34 deletions

File tree

CHANGELOG.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,61 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.0.0] - 2026-05-01
9+
10+
First stable release. This is a large release that overhauls authentication, command argument conventions, output formatting, and adds several new command groups. Key user-facing changes are summarised below; review the migration notes before upgrading.
11+
12+
### Added
13+
14+
- **OAuth Device Authorization login**`ably login` now uses the OAuth 2.0 Device Authorization Grant for browser-based sign-in. Works in SSH sessions, containers, and headless CI without a localhost callback. Multi-account is built in: sign in once per account, switch contexts with `ably accounts switch`, and tokens refresh transparently in the background.
15+
- **`--force` flag for destructive operations** — unified across delete/revoke/wipe commands. Interactive use prompts for confirmation; non-interactive use (scripts, agents) refuses to run unless `--force` is passed explicitly. Prevents accidental destruction by automation that has general CLI access.
16+
- **Error hints** — fatal errors now include a `hint` field naming a specific next-step command (e.g. "run `ably login`" for auth errors). Surfaced in both human-readable output and the JSON error envelope, so agents can self-heal in fewer turns.
17+
- **Chat message mutations**`ably rooms messages update`, `delete`, and reactions/annotations support
18+
- **Push notification publish**`ably push publish` for sending push notifications via channels
19+
- **Annotations** — new `ably channels annotations` command group with publish/subscribe/get/count/delete
20+
- **Spaces commands** — expanded coverage including locks acquire/release, locations set, cursors set, members enter, and `get`/`get-all` queries
21+
- **Integrations** — first-class command group for managing integration rules (`ably integrations list/get/create/update/delete`)
22+
- **Channel rules for mutable messages** — flags for configuring update/delete/annotation policies on channel rules
23+
- **Stats top-level command**`ably stats` (moved out of `apps`)
24+
25+
### Changed
26+
27+
- **BREAKING: Auth flags removed**`--api-key`, `--token`, and `--access-token` no longer accepted on commands. Use `ably login` or env vars `ABLY_API_KEY` / `ABLY_TOKEN` / `ABLY_ACCESS_TOKEN`.
28+
- **BREAKING: Primary entity identifiers are now positional arguments** — flags like `--name`, `--channel`, `--location`, and `--key` that named the entity being acted on have been replaced with positional args (POSIX/docopt convention). Affects `apps`, `keys`, `queues`, `rules`, `push`, `channels`, `rooms`, `spaces locations`, and others.
29+
- **BREAKING: Standardized argument naming** — argument names in errors and help output are snake_case; commands use camelCase identifiers consistently (`appId`, `keyName`, `channelName`).
30+
- **BREAKING: Flexible name-or-ID lookup**`apps`, `keys`, `queues`, and `rules` commands now resolve either name or ID. Behaviour for ambiguous lookups may differ from previous versions.
31+
- **BREAKING: `auth revoke-token`** no longer accepts a `TOKEN` positional; pass `--client-id` or `--revocation-key`. Adds confirmation prompt and `--force`.
32+
- **Unified JSON output envelope** — every command now emits `{type, command, success, ...}` with domain data nested under singular/plural domain keys. Streaming commands emit NDJSON with `status: "listening"` / `"holding"` signals and a final `status: "completed"` event.
33+
- **Unified output helpers**`logProgress`, `logSuccessMessage`, `logListening`, `logHolding`, `logWarning` replace ad-hoc `chalk` usage; non-JSON output uses labeled multi-line blocks (no ASCII tables).
34+
- **Unified time-range flags**`--start` / `--end` accept ISO 8601, Unix ms, or relative (`"1h"`, `"30m"`) across all history and stats commands.
35+
- **Unified pagination** — cursor-based pagination with `formatPaginationLog` warnings when multiple pages are fetched, and `next` hints in JSON output.
36+
- **Help theme** — colour-coded help via oclif theme (commands cyan, flags whiteBright, headers bold, defaults yellow, required red).
37+
- **Error handling** — fatal errors now flow through a single `this.fail()` funnel that preserves Ably error codes/HTTP status and emits structured JSON error envelopes.
38+
39+
### Fixed
40+
41+
- Many fixes around JSON output consistency, timestamp formatting, error envelopes, billable message warnings, channel-rule handling, push message shape, batch publish, room messages subscribe across multiple rooms, presence flows, and exit codes.
42+
- Web CLI: file-read security hardening, auto-connect detection with signed config, domain-scoped credential clearing.
43+
- Spaces `enter` no longer triggers on read-only commands (subscribe/get are now passive observers).
44+
- Duplicated "Press Ctrl+C to exit" suffixes removed from holding messages.
45+
46+
### Removed
47+
48+
- **BREAKING: Auth CLI flags** (see Changed section above)
49+
50+
### Migration Notes
51+
52+
If you have scripts targeting v0.x, the most likely breakages are:
53+
54+
1. **Replace `--api-key`/`--token`/`--access-token`** flags with environment variables (`ABLY_API_KEY`, `ABLY_TOKEN`, `ABLY_ACCESS_TOKEN`) or run `ably login` once on the host.
55+
2. **Move primary entity identifiers from flags to positional args**, e.g.:
56+
- `ably apps update --name my-app …``ably apps update my-app …`
57+
- `ably channels publish --channel foo --message bar``ably channels publish foo bar`
58+
- `ably spaces locations set --location ./path …``ably spaces locations set ./path …`
59+
3. **Update JSON consumers** — top-level shape now includes `type`, `command`, and `success` fields, with payload nested under a domain key (`message`, `cursor`, `lock`, `rules`, etc.).
60+
4. **Rename argument references** in any error-handling code that matched on previous arg names.
61+
5. **`ably auth revoke-token <TOKEN>`**`ably auth revoke-token --client-id <ID>` or `--revocation-key <KEY>` (the positional `TOKEN` arg is no longer accepted).
62+
863
## [0.17.0] - 2026-03-08
964

1065
### Added

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ably/cli",
3-
"version": "0.17.0",
3+
"version": "1.0.0",
44
"description": "Ably CLI for Pub/Sub, Chat and Spaces",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/react-web-cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ably/react-web-cli",
3-
"version": "0.17.0",
3+
"version": "1.0.0",
44
"description": "React component for embedding the Ably CLI in a web terminal",
55
"main": "dist/index.js",
66
"module": "dist/index.mjs",

src/commands/interactive.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { fileURLToPath } from "node:url";
66
import chalk from "chalk";
77
import { HistoryManager } from "../services/history-manager.js";
88
import { displayLogo } from "../utils/logo.js";
9-
import { formatReleaseStatus } from "../utils/version.js";
109
import {
1110
WEB_CLI_RESTRICTED_COMMANDS,
1211
WEB_CLI_ANONYMOUS_RESTRICTED_COMMANDS,
@@ -137,8 +136,7 @@ export default class Interactive extends Command {
137136
// Display logo
138137
displayLogo(console.log);
139138

140-
// Show release status
141-
console.log(` ${formatReleaseStatus(this.config.version, true)}\n`);
139+
console.log(` ${chalk.dim(`Version ${this.config.version}`)}\n`);
142140

143141
// Show appropriate tagline based on mode
144142
let tagline = "ably.com ";

src/commands/version.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import { AblyBaseCommand } from "../base-command.js";
22
import { coreGlobalFlags } from "../flags.js";
3-
import {
4-
getVersionInfo,
5-
formatVersionString,
6-
formatReleaseStatus,
7-
} from "../utils/version.js";
3+
import { getVersionInfo, formatVersionString } from "../utils/version.js";
84

95
export default class Version extends AblyBaseCommand {
106
static description = "Display CLI version information";
@@ -31,9 +27,7 @@ export default class Version extends AblyBaseCommand {
3127
if (this.shouldOutputJson(flags)) {
3228
this.logJsonResult({ version: versionInfo }, flags);
3329
} else {
34-
// Use shared string formatting and display release status
3530
this.log(formatVersionString(this.config));
36-
this.log(formatReleaseStatus(this.config.version, true));
3731
}
3832
}
3933
}

src/help.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
createConfigManager,
88
} from "./services/config-manager.js";
99
import { displayLogo } from "./utils/logo.js";
10-
import { formatReleaseStatus } from "./utils/version.js";
1110

1211
/** Convert camelCase arg name to snake_case so oclif's toUpperCase() produces UPPER_SNAKE_CASE */
1312
export function camelToSnake(name: string): string {
@@ -229,7 +228,7 @@ export default class CustomHelp extends Help {
229228
const headerLines = [
230229
chalk.bold(titleText),
231230
"",
232-
formatReleaseStatus(config.version, true),
231+
chalk.dim(`Version ${config.version}`),
233232
"",
234233
`${chalk.bold("USAGE")}`,
235234
` ${this.interactiveMode ? "ably> " : chalk.green("$") + " " + chalk.cyan(config.bin) + " "}[COMMAND]`,
@@ -325,7 +324,7 @@ export default class CustomHelp extends Help {
325324
lines.push(
326325
chalk.bold("ably.com browser-based CLI for Pub/Sub, Chat and Spaces"),
327326
"",
328-
formatReleaseStatus(this.config.version, true),
327+
chalk.dim(`Version ${this.config.version}`),
329328
"",
330329
);
331330

src/hooks/init/version-flag.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ import {
44
JsonRecordType,
55
formatJsonString,
66
} from "../../utils/output.js";
7-
import {
8-
getVersionInfo,
9-
formatVersionString,
10-
formatReleaseStatus,
11-
} from "../../utils/version.js";
7+
import { getVersionInfo, formatVersionString } from "../../utils/version.js";
128

139
/**
1410
* Helper function to handle exit or throw based on interactive mode
@@ -61,9 +57,7 @@ const hook: Hook<"init"> = async function (opts) {
6157
console.log(jsonOutput);
6258
handleVersionExit();
6359
} else {
64-
// Non-JSON output: show standard version string and release status
6560
console.log(formatVersionString(config));
66-
console.log(formatReleaseStatus(config.version, true));
6761
handleVersionExit();
6862
}
6963
}

src/utils/version.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/**
22
* Common utilities for version-related functionality
33
*/
4-
import chalk from "chalk";
54
// Import package.json directly - TypeScript will resolve this at compile time
65
import packageJson from "../../package.json" with { type: "json" };
76
import isWebCliMode from "./web-mode.js";
@@ -46,14 +45,6 @@ export function getVersionInfo(config: {
4645
};
4746
}
4847

49-
/**
50-
* Format release status with version number
51-
*/
52-
export function formatReleaseStatus(version: string, colored = false): string {
53-
const status = `Public Preview - Version ${version}`;
54-
return colored ? chalk.yellow(status) : status;
55-
}
56-
5748
/**
5849
* Format version info as a standard string
5950
*/

test/unit/commands/version.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ describe("version command", () => {
2020
expect(stdout).toContain(process.version);
2121
});
2222

23-
it("should display Public Preview status", async () => {
23+
it("should display version info without Public Preview text", async () => {
2424
const { stdout } = await runCommand(["version"], import.meta.url);
2525

26-
expect(stdout).toContain("Public Preview");
27-
expect(stdout).toContain("Version");
26+
expect(stdout).not.toContain("Public Preview");
27+
expect(stdout).toContain("@ably/cli");
2828
});
2929

3030
it("should output JSON when --json flag is used", async () => {

0 commit comments

Comments
 (0)