Skip to content

Commit 74ff9a2

Browse files
project: widen prettier scope to cover all files
Switch from explicit path lists to `prettier .` (matching ably-js's approach) and reformat all files that had drifted. Submodules (ably-common, specification) are excluded via .prettierignore. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 77a8052 commit 74ff9a2

File tree

74 files changed

+1431
-1181
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1431
-1181
lines changed

.claude/rules/ABSTRACTIONS.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,12 @@ ably-common/ # Git submodule — shared protocol resour
3939

4040
The SDK ships four entry points from a single package:
4141

42-
| Export path | Contains | Purpose | External deps |
43-
|---|---|---|---|
44-
| `@ably/ai-transport` | Generic codec interfaces, `createClientTransport`, `createServerTransport`, shared utilities | Core primitives — codec-agnostic transport and encoding | `ably` (peer) |
45-
| `@ably/ai-transport/react` | `useClientTransport`, `useView`, `useTree`, `useSend`, `useRegenerate`, `useEdit`, `useActiveTurns`, `useAblyMessages` | Generic React hooks for any codec | `ably`, `react` (peers) |
46-
| `@ably/ai-transport/vercel` | `UIMessageCodec`, `createServerTransport`, `createClientTransport`, `createChatTransport`, Vercel-specific types | Drop-in Vercel AI SDK integration | `ably`, `ai` (peers) |
47-
| `@ably/ai-transport/vercel/react` | `useChatTransport`, `useMessageSync` | React hooks for Vercel's `useChat` | `ably`, `ai`, `react` (peers) |
48-
42+
| Export path | Contains | Purpose | External deps |
43+
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------------------------- |
44+
| `@ably/ai-transport` | Generic codec interfaces, `createClientTransport`, `createServerTransport`, shared utilities | Core primitives — codec-agnostic transport and encoding | `ably` (peer) |
45+
| `@ably/ai-transport/react` | `useClientTransport`, `useView`, `useTree`, `useSend`, `useRegenerate`, `useEdit`, `useActiveTurns`, `useAblyMessages` | Generic React hooks for any codec | `ably`, `react` (peers) |
46+
| `@ably/ai-transport/vercel` | `UIMessageCodec`, `createServerTransport`, `createClientTransport`, `createChatTransport`, Vercel-specific types | Drop-in Vercel AI SDK integration | `ably`, `ai` (peers) |
47+
| `@ably/ai-transport/vercel/react` | `useChatTransport`, `useMessageSync` | React hooks for Vercel's `useChat` | `ably`, `ai`, `react` (peers) |
4948

5049
## Two-Layer Architecture
5150

@@ -67,11 +66,11 @@ Header/event/message-name constants and Ably message utilities used by both laye
6766

6867
The client-side architecture separates three concerns:
6968

70-
| Component | Owns | Events |
71-
|---|---|---|
72-
| **Tree** | Complete conversation state — every node from live messages and history. Turn tracking (active turn → clientId). | `update` (any structural change), `ably-message` (every raw message), `turn` (start/end) — unfiltered, fires for all changes |
73-
| **View** | Pagination window — which history-loaded nodes are visible vs withheld. | Same event names, but **scoped to the visible window** — only fires when the visible output changes |
74-
| **Transport** | Write path (send/regenerate/edit/cancel), channel subscription, stream routing, decode loop. | `error` only — all data events moved to Tree/View |
69+
| Component | Owns | Events |
70+
| ------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
71+
| **Tree** | Complete conversation state — every node from live messages and history. Turn tracking (active turn → clientId). | `update` (any structural change), `ably-message` (every raw message), `turn` (start/end) — unfiltered, fires for all changes |
72+
| **View** | Pagination window — which history-loaded nodes are visible vs withheld. | Same event names, but **scoped to the visible window** — only fires when the visible output changes |
73+
| **Transport** | Write path (send/regenerate/edit/cancel), channel subscription, stream routing, decode loop. | `error` only — all data events moved to Tree/View |
7574

7675
The Tree is the source of truth. The View subscribes to Tree events and re-emits them filtered to what's visible. The Transport wires the channel to the Tree and exposes both as `transport.tree` and `transport.view`.
7776

@@ -146,8 +145,8 @@ Public-facing entry points (e.g. `createClientTransport()`) are factory function
146145

147146
1. **Two-layer split**: Generic transport/codec knows nothing about Vercel. Vercel layer implements the codec and provides convenience wrappers.
148147
2. **Codec-parameterized**: All generic components are parameterized by `<TEvent, TMessage>` via the `Codec` interface.
149-
4. **Constructor/option injection**: All dependencies passed explicitly — no singletons, no globals.
150-
3. **Composition, not inheritance**: Transports compose features; no class hierarchies.
148+
3. **Constructor/option injection**: All dependencies passed explicitly — no singletons, no globals.
149+
4. **Composition, not inheritance**: Transports compose features; no class hierarchies.
151150
5. **Interface-first**: Public contracts are TypeScript interfaces. Implementations are internal `Default*` classes, exposed to consumers via factory functions.
152151
6. **Header discipline**: Generic layer uses only `x-ably-*` headers. Domain-specific headers (e.g. `x-domain-*`) belong in the Vercel layer.
153152
7. **Explicit exports**: Only types and functions listed in `index.ts` files are public API.

.claude/rules/ERRORS.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Every error should either be handled internally with a clear recovery strategy,
1111
- **Isolate handler callbacks**: When the SDK invokes developer-provided callbacks (event listeners, hooks), wrap each in try/catch. One bad handler shouldn't kill internal machinery or prevent other handlers from firing.
1212
- **Define recovery semantics explicitly**: For every internal operation that can fail, decide upfront: retry, degrade, or propagate. Document the choice.
1313
- **Preserve the original error**: When wrapping errors, always attach the original as `cause`. Developers debugging production issues need the full chain.
14-
- **Best-effort operations should be labeled**: If something is fire-and-forget (e.g. cleanup publish on close), comment it as such. Swallowing an error is only acceptable when failure is unrecoverable *and* non-impactful.
14+
- **Best-effort operations should be labeled**: If something is fire-and-forget (e.g. cleanup publish on close), comment it as such. Swallowing an error is only acceptable when failure is unrecoverable _and_ non-impactful.
1515

1616
### Surfacing errors to developers
1717

@@ -145,12 +145,12 @@ reject(
145145

146146
Use the custom Vitest matchers in a test helper (`test/helper/expectations.ts`):
147147

148-
| Matcher | Usage |
149-
|---|---|
150-
| `toBeErrorInfo({ code?, statusCode?, message?, cause? })` | Assert a value is an `Ably.ErrorInfo` matching the given fields |
151-
| `toThrowErrorInfo({ code?, statusCode?, message? })` | Assert a sync function throws a matching `Ably.ErrorInfo` |
152-
| `toBeErrorInfoWithCode(code)` | Shorthand — assert value is `Ably.ErrorInfo` with a specific code |
153-
| `toThrowErrorInfoWithCode(code)` | Shorthand — assert sync function throws with a specific code |
154-
| `toBeErrorInfoWithCauseCode(code)` | Assert value is `Ably.ErrorInfo` whose `.cause.code` matches |
148+
| Matcher | Usage |
149+
| --------------------------------------------------------- | ----------------------------------------------------------------- |
150+
| `toBeErrorInfo({ code?, statusCode?, message?, cause? })` | Assert a value is an `Ably.ErrorInfo` matching the given fields |
151+
| `toThrowErrorInfo({ code?, statusCode?, message? })` | Assert a sync function throws a matching `Ably.ErrorInfo` |
152+
| `toBeErrorInfoWithCode(code)` | Shorthand — assert value is `Ably.ErrorInfo` with a specific code |
153+
| `toThrowErrorInfoWithCode(code)` | Shorthand — assert sync function throws with a specific code |
154+
| `toBeErrorInfoWithCauseCode(code)` | Assert value is `Ably.ErrorInfo` whose `.cause.code` matches |
155155

156156
The matchers only check the fields you provide — omitted fields are not compared. The `cause` field is checked recursively.

.claude/rules/LOGGING.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ type LogContext = Record<string, any>;
1919

2020
## Log Levels
2121

22-
| Level | When to use |
23-
|---|---|
24-
| `Trace` | Routine operations — entry point of every key method. The most verbose level. |
25-
| `Debug` | Useful for debugging but superfluous in normal operation — successful completions, state transitions, decision points. |
26-
| `Info` | Operationally significant but expected — transport open/close, lifecycle events. |
27-
| `Warn` | Not an error yet, but could cause problems — unexpected but recoverable states. |
28-
| `Error` | An operation has failed and cannot be automatically recovered. |
29-
| `Silent` | No logging. |
22+
| Level | When to use |
23+
| -------- | ---------------------------------------------------------------------------------------------------------------------- |
24+
| `Trace` | Routine operations — entry point of every key method. The most verbose level. |
25+
| `Debug` | Useful for debugging but superfluous in normal operation — successful completions, state transitions, decision points. |
26+
| `Info` | Operationally significant but expected — transport open/close, lifecycle events. |
27+
| `Warn` | Not an error yet, but could cause problems — unexpected but recoverable states. |
28+
| `Error` | An operation has failed and cannot be automatically recovered. |
29+
| `Silent` | No logging. |
3030

3131
Levels are hierarchical. Setting the level to `Debug` suppresses `Trace` but shows everything else.
3232

@@ -85,7 +85,8 @@ this._logger.debug('Tree.upsert(); inserting new node', { msgId, parentId, forkO
8585

8686
// Warning
8787
this._logger.warn('DefaultDecoderCore.decode(); unexpected message action', {
88-
action, serial: message.serial,
88+
action,
89+
serial: message.serial,
8990
});
9091

9192
// Error
@@ -130,7 +131,8 @@ Not yet an error, but something that could cascade:
130131

131132
```ts
132133
this._logger.warn('DefaultDecoderCore.decode(); unrecognized message name', {
133-
name: message.name, serial: message.serial,
134+
name: message.name,
135+
serial: message.serial,
134136
});
135137
```
136138

.claude/rules/TESTS.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
## Two tiers
44

5-
| Tier | Command | Runs against | What it proves |
6-
|---|---|---|---|
7-
| **Unit** | `npm test` | Mocks only | Every code path works correctly in isolation |
8-
| **Integration** | `npm run test:integration` | Real Ably channels | Happy path works end-to-end over real Ably |
5+
| Tier | Command | Runs against | What it proves |
6+
| --------------- | -------------------------- | ------------------ | -------------------------------------------- |
7+
| **Unit** | `npm test` | Mocks only | Every code path works correctly in isolation |
8+
| **Integration** | `npm run test:integration` | Real Ably channels | Happy path works end-to-end over real Ably |
99

1010
Config: `vitest.config.ts` (unit, excludes `*.integration.test.ts`) and `vitest.config.integration.ts` (integration only).
1111

@@ -49,11 +49,11 @@ By default, integration tests run against the **Ably sandbox**. The globalSetup
4949

5050
To run against a different environment, set `VITE_ABLY_ENV`:
5151

52-
| `VITE_ABLY_ENV` | Behaviour | API key required? |
53-
|---|---|---|
54-
| *(unset)* / `sandbox` | Provisions a sandbox app automatically | No |
55-
| `local` | Connects to `local-rest.ably.io:8081` (no TLS) | Yes — set `VITE_ABLY_API_KEY` |
56-
| `production` | Connects to production Ably | Yes — set `VITE_ABLY_API_KEY` |
52+
| `VITE_ABLY_ENV` | Behaviour | API key required? |
53+
| --------------------- | ---------------------------------------------- | ----------------------------- |
54+
| _(unset)_ / `sandbox` | Provisions a sandbox app automatically | No |
55+
| `local` | Connects to `local-rest.ably.io:8081` (no TLS) | Yes — set `VITE_ABLY_API_KEY` |
56+
| `production` | Connects to production Ably | Yes — set `VITE_ABLY_API_KEY` |
5757

5858
### Conventions
5959

.claude/skills/commit/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ project-specific guidance takes precedence.
5757
### Project-specific component prefixes
5858

5959
The component prefix is derived from the file paths in the diff. Examples:
60+
6061
- `codec:` `codec/vercel:` `transport:` `transport/vercel:`
6162
- `react:` `react/vercel:`
6263
- `claude/skills:` `claude/rules:`

.claude/skills/docs/SKILL.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,23 @@ direct, declarative statement. No preamble, no "In this guide, we'll..."
8383

8484
```markdown
8585
<!-- Good -->
86+
8687
Cancellation in `@ably/ai` is a channel-level operation - the client publishes
8788
a cancel signal on the Ably channel, the server receives it and aborts the
8889
matching turns.
8990

9091
<!-- Good -->
92+
9193
Interruption is when a user sends a new message while the AI is still streaming
9294
a response.
9395

9496
<!-- Bad -->
97+
9598
In this guide, we'll explore how to cancel streaming responses in your
9699
AI application.
97100

98101
<!-- Bad -->
102+
99103
This page covers the cancellation feature of the AI Transport SDK.
100104
```
101105

@@ -195,8 +199,8 @@ Internals pages follow this flow:
195199
glossary, and the corresponding feature/concept pages
196200

197201
Internals pages differ from concept pages: concept pages explain what
198-
developers need to know to *use* the SDK. Internals pages explain how the
199-
SDK works *internally* for contributors and curious engineers. Internals
202+
developers need to know to _use_ the SDK. Internals pages explain how the
203+
SDK works _internally_ for contributors and curious engineers. Internals
200204
pages can reference source file paths and internal class names.
201205

202206
### Tables
@@ -206,10 +210,10 @@ codes, phase behaviors. Tables are scannable and dense. Prefer a table over
206210
a bullet list when comparing properties across items.
207211

208212
```markdown
209-
| Filter | Effect | Use case |
210-
|---|---|---|
211-
| `{ own: true }` (default) | Cancel all turns started by this client | Stop button |
212-
| `{ turnId: "abc" }` | Cancel one specific turn | Cancel a specific generation |
213+
| Filter | Effect | Use case |
214+
| ------------------------- | --------------------------------------- | ---------------------------- |
215+
| `{ own: true }` (default) | Cancel all turns started by this client | Stop button |
216+
| `{ turnId: "abc" }` | Cancel one specific turn | Cancel a specific generation |
213217
```
214218

215219
### Diagrams
@@ -273,11 +277,13 @@ readers skim, and the link needs to be where the concept appears.
273277

274278
```markdown
275279
<!-- Good: inline link where the concept is mentioned -->
280+
276281
The [decoder](decoder.md) accumulates deltas via string concatenation and
277282
uses [prefix-matching](decoder.md#known-serial-prefix-match) to detect
278283
whether an update is incremental or a replacement.
279284

280285
<!-- Bad: concept mentioned without link, with "See also" at the bottom -->
286+
281287
The decoder accumulates deltas via string concatenation and uses
282288
prefix-matching to detect whether an update is incremental or a replacement.
283289
...
@@ -351,14 +357,14 @@ docs/
351357

352358
**Page type by directory:**
353359

354-
| Directory | Page type | Pattern |
355-
|---|---|---|
356-
| `concepts/` | Concept page | Definition → architecture → data flow → key details |
357-
| `get-started/` | Quickstart | Prerequisites → step-by-step → "what's happening" → next steps |
358-
| `frameworks/` | Framework guide | What the framework provides → what's missing → how AIT fills gaps → integration paths |
359-
| `features/` | Feature page | Definition → problem framing → mechanism → client code → server code → edge cases |
360-
| `reference/` | Reference page | One section per API item: signature, params table, return type, example |
361-
| `internals/` | Internals page | Definition → concepts → operations → algorithms → edge cases → cross-refs |
360+
| Directory | Page type | Pattern |
361+
| -------------- | --------------- | ------------------------------------------------------------------------------------- |
362+
| `concepts/` | Concept page | Definition → architecture → data flow → key details |
363+
| `get-started/` | Quickstart | Prerequisites → step-by-step → "what's happening" → next steps |
364+
| `frameworks/` | Framework guide | What the framework provides → what's missing → how AIT fills gaps → integration paths |
365+
| `features/` | Feature page | Definition → problem framing → mechanism → client code → server code → edge cases |
366+
| `reference/` | Reference page | One section per API item: signature, params table, return type, example |
367+
| `internals/` | Internals page | Definition → concepts → operations → algorithms → edge cases → cross-refs |
362368

363369
If a page doesn't fit these categories, discuss placement before writing.
364370

.claude/skills/pr-description/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Write a PR description with this structure:
5959
```
6060

6161
Guidelines:
62+
6263
- Lead with motivation, not mechanics
6364
- Be specific: name the types, methods, and interfaces involved
6465
- Keep it scannable — reviewers skim first, read deeply second

.claude/skills/rebase/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ If there are uncommitted changes, warn the user and stop — rebase
2121
requires a clean working tree.
2222

2323
Determine the **target branch**:
24+
2425
- If the user specified a branch (e.g. `/rebase main`), use that.
2526
- Otherwise, default to `main`.
2627

0 commit comments

Comments
 (0)