Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/skills/ably-new-command/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ If the topic/subtopic doesn't exist yet, you also need an index file at `src/com
**Product API commands** (channels, rooms, spaces, presence, pub/sub):
```typescript
import { Args, Flags } from "@oclif/core";
import * as Ably from "ably";
import type * as Ably from "@ably/pubsub-server";
import chalk from "chalk";

import { AblyBaseCommand } from "../../base-command.js";
Expand Down Expand Up @@ -466,7 +466,7 @@ See the "Keeping Skills Up to Date" section in `CLAUDE.md` for the full list of
- [ ] Non-JSON data output uses multi-line labeled blocks (see `patterns.md` "Human-Readable Output Format"), not tables or custom grids
- [ ] Non-JSON output exposes all available SDK fields (same data as JSON mode, omitting only null/empty values)
- [ ] SDK types imported directly (`import type { CursorUpdate } from "@ably/spaces"`) — no local interface redefinitions of SDK types (display interfaces in `src/utils/` are fine)
- [ ] Field coverage checked against SDK type definitions (`node_modules/ably/ably.d.ts`, `node_modules/@ably/spaces/dist/mjs/types.d.ts`)
- [ ] Field coverage checked against SDK type definitions (`node_modules/@ably/pubsub-core/types.d.ts`, re-exported by `@ably/pubsub-server`; `node_modules/@ably/spaces/dist/mjs/types.d.ts`)
- [ ] Subscribe commands do NOT fetch initial state — they only listen for new events (use `get-all` for current state)
- [ ] Resource names use `formatResource(name)`, never quoted
- [ ] JSON output uses `logJsonResult()` (one-shot) or `logJsonEvent()` (streaming), not direct `formatJsonRecord()`
Expand Down
6 changes: 4 additions & 2 deletions .claude/skills/ably-new-command/references/patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -615,18 +615,20 @@ Attributes: {"priority": "high"}

| SDK | Type file | Key types |
|-----|-----------|-----------|
| `ably` | `node_modules/ably/ably.d.ts` | `Message`, `PresenceMessage`, `ChannelStateChange`, `ConnectionStateChange` |
| `@ably/pubsub-server` | `node_modules/@ably/pubsub-core/types.d.ts` (re-exported) | `PubSubRealtimeClient`, `PubSubHttpClient`, `Message`, `PresenceMessage`, `ChannelStateChange`, `ConnectionStateChange` |
| `@ably/spaces` | `node_modules/@ably/spaces/dist/mjs/types.d.ts` | `SpaceMember`, `CursorUpdate`, `CursorPosition`, `CursorData`, `Lock`, `ProfileData` |
| `@ably/chat` | `node_modules/@ably/chat/dist/chat/core/*.d.ts` | `Message` (chat), `PresenceMember`, `OccupancyEvent`, `Reaction` |

**Use SDK source code as the source of truth** for method behavior — whether a method requires prior state (e.g., `space.enter()`), what side effects it has, what it actually returns. When in doubt, read the implementation:

| SDK | Source directory | Key files |
|-----|-----------------|-----------|
| `ably` | `node_modules/ably/` | Realtime, REST, channels, presence |
| `@ably/pubsub-server` | `node_modules/@ably/pubsub-core/build/` (its runtime) | Realtime, HTTP, channels, presence |
| `@ably/spaces` | `node_modules/@ably/spaces/dist/mjs/` | `Space.js`, `Members.js`, `Locations.js`, `Cursors.js`, `Locks.js` |
| `@ably/chat` | `node_modules/@ably/chat/dist/chat/core/` | Rooms, messages, presence, reactions |

**Never construct Pub/Sub clients directly or import `ably`.** CLI code imports Pub/Sub types with `import type * as Ably from "@ably/pubsub-server"` and gets clients from `createAblyRestClient()` / `createAblyRealtimeClient()`, which build them with `@ably/pubsub-server`'s `createHttpClient` / `createRealtimeClient`, so the CLI always connects as a server. `@ably/chat` (`createChatClient`) and `@ably/spaces` (`createSpacesClient`) wrap that same realtime client; `ably` v2 is not installed at all.

**Import SDK types directly** — never redefine SDK interfaces locally. If `@ably/spaces` exports `CursorPosition`, import it:
```typescript
// WRONG — local redefinition duplicates SDK type
Expand Down
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,10 @@ When adding COMMANDS sections in `src/help.ts`, use `chalk.bold()` for headers,
- Spaces: https://ably.com/docs/spaces and API ref at https://sdk.ably.com/builds/ably/spaces/main/typedoc/index.html
- Control API: https://ably.com/docs/account/control-api and ref at https://ably.com/docs/api/control-api
- Platform: https://ably.com/docs/platform
- **Pub/Sub packages**: the CLI never imports `ably`, and depends on `@ably/pubsub-server` only. Types come from it too (`import type * as Ably from "@ably/pubsub-server"`; clients are `Ably.PubSubRealtimeClient` / `Ably.PubSubHttpClient`). Clients are constructed only by `createAblyRestClient()` / `createAblyRealtimeClient()` in the base command, with `createHttpClient` / `createRealtimeClient` from `@ably/pubsub-server`, so the CLI always connects as a server. Chat and Spaces are built on the same core: create them with `createChatClient(realtime, options)` and `createSpacesClient(realtime)`, passing the CLI's own realtime client. Nothing in the dependency tree uses `ably` v2.
- The CLI uses Ably SDKs for all data plane commands. When an API exists in the data plane REST API but has no corresponding SDK method, use the Pub/Sub SDK's request method.
- The Control API has no official SDK, so raw HTTP requests are used.
- **SDK packages (`node_modules/ably/`, `node_modules/@ably/spaces/`, `node_modules/@ably/chat/`) are the local source of truth** for types and method behavior. Type definitions (e.g., `ably.d.ts`, `types.d.ts`) tell you what fields exist; source code (e.g., `Space.js`, `Members.js`) tells you how methods behave (side effects, prerequisites like `space.enter()`). When in doubt, read the implementation — not just the types. See `references/patterns.md` "Field display rules" in the `ably-new-command` skill for the full path table and import conventions.
- **SDK packages (`node_modules/@ably/pubsub-core/` (the core behind `@ably/pubsub-server`), `node_modules/@ably/spaces/`, `node_modules/@ably/chat/`) are the local source of truth** for types and method behavior. Type definitions (e.g., `@ably/pubsub-core/types.d.ts`, `types.d.ts`) tell you what fields exist; source code (e.g., `Space.js`, `Members.js`) tells you how methods behave (side effects, prerequisites like `space.enter()`). When in doubt, read the implementation — not just the types. See `references/patterns.md` "Field display rules" in the `ably-new-command` skill for the full path table and import conventions.

## Development Standards

Expand Down
4 changes: 2 additions & 2 deletions docs/Testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ Call generators at describe-block level. Write `"functionality"` and `"error han

| File | Provides |
|------|----------|
| `mock-ably-realtime.ts` | Mock `Ably.Realtime` — channels, presence, connection events |
| `mock-ably-rest.ts` | Mock `Ably.Rest` — REST channel operations, request() |
| `mock-ably-realtime.ts` | Mock `PubSubRealtimeClient` — channels, presence, connection events |
| `mock-ably-rest.ts` | Mock `PubSubHttpClient` — REST channel operations, request() |
| `mock-ably-chat.ts` | Mock Chat SDK — rooms, messages, typing, reactions |
| `mock-ably-spaces.ts` | Mock Spaces SDK — members, cursors, locations, locks |

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@
}
},
"dependencies": {
"@ably/chat": "^1.3.1",
"@ably/spaces": "^0.5.2",
"@ably/chat": "0.0.0-canary.20261001T1209.783b80e6",
"@ably/pubsub-server": "3.0.0-canary.20261001T0958.2d5f47d6",
"@ably/spaces": "0.0.0-canary.20261001T1221.ca08adce",
"@inquirer/prompts": "^8.4.2",
"@oclif/core": "^4.11.1",
"@oclif/plugin-autocomplete": "^3.2.48",
"@oclif/plugin-warn-if-update-available": "^3.1.63",
"@xterm/addon-fit": "^0.11.0",
"@xterm/addon-web-links": "^0.12.0",
"@xterm/xterm": "^6.0.0",
"ably": "^2.21.0",
"chalk": "^5.6.2",
"cli-table3": "^0.6.5",
"color-json": "^3.0.5",
Expand Down
131 changes: 63 additions & 68 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading