Skip to content

Commit 04064a9

Browse files
authored
docs(maintainers): separate agent directives into different packages (#2556)
1 parent 189714e commit 04064a9

2 files changed

Lines changed: 253 additions & 229 deletions

File tree

AGENTS.md

Lines changed: 10 additions & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -85,240 +85,21 @@ npm run build --workspace=@slack/socket-mode
8585
- **Formatting**: configured in `biome.json`
8686
- **Test files**: `*.test.{ts,js}` using `node:test` + `node:assert/strict`; coverage via `--experimental-test-coverage`
8787
- **Type tests**: `*.test-d.ts` using tsd
88-
- **Naming conventions for request/response types**:
89-
- Request: `{Namespace}{Action}Arguments` (e.g., `ChatPostMessageArguments`)
90-
- Response: `{Namespace}{Action}Response` (e.g., `ChatPostMessageResponse`)
91-
- **Method names**: camelCase matching the Slack API method (e.g., `chat.postMessage``postMessage`)
88+
- **CI matrix**: Node 18.x, 20.x, 22.x, 24.x on Ubuntu + Windows
9289

93-
## Adding a New Slack API Method
90+
## Package-Level AGENTS.md
9491

95-
This is the most common contribution. Follow these steps in order.
92+
Individual packages have their own `AGENTS.md` with package-specific guidance:
9693

97-
### Step 1: Look Up the API Method Documentation
94+
- `packages/web-api/AGENTS.md` — adding API methods, code generation, client architecture
9895

99-
Reference: `https://docs.slack.dev/reference/methods/{method.name}`
100-
101-
For example, for `chat.appendStream`: https://docs.slack.dev/reference/methods/chat.appendStream
102-
103-
### Step 2: Generate Response Types
104-
105-
Run the generation script from the repo root:
106-
107-
```bash
108-
bash scripts/generate-web-api-types.sh
109-
```
110-
111-
This script:
112-
113-
1. Clones/updates `slackapi/java-slack-sdk` into `tmp/java-slack-sdk`
114-
2. Reads JSON response samples from `tmp/java-slack-sdk/json-logs/samples/api/`
115-
3. Runs `scripts/code_generator.rb` which uses quicktype to generate TypeScript types
116-
4. Outputs `*Response.ts` files to `packages/web-api/src/types/response/`
117-
5. Regenerates `packages/web-api/src/types/response/index.ts`
118-
6. Runs `npm run lint:fix` on the generated files
119-
120-
**Prerequisites**: Ruby and npm must be installed.
121-
122-
Generated response types look like this (example: `ChatAppendStreamResponse.ts`):
123-
124-
```typescript
125-
import type { WebAPICallResult } from '../../WebClient';
126-
export type ChatAppendStreamResponse = WebAPICallResult & {
127-
channel?: string;
128-
error?: string;
129-
needed?: string;
130-
ok?: boolean;
131-
provided?: string;
132-
ts?: string;
133-
};
134-
```
135-
136-
All generated files extend `WebAPICallResult` and have all properties optional.
137-
138-
**Note**: If the JSON sample doesn't exist yet in `java-slack-sdk`, the API method has not been added to that project yet. The maintainers need to add it there first before it can be added here.
139-
140-
### Step 3: Add Request Argument Types
141-
142-
File: `packages/web-api/src/types/request/<namespace>.ts`
143-
144-
Create an interface/type for the method's arguments. Reuse mixins from `packages/web-api/src/types/request/common.ts`:
145-
146-
| Mixin | Purpose |
147-
|-------|---------|
148-
| `TokenOverridable` | Optional `token` override |
149-
| `CursorPaginationEnabled` | `cursor` + `limit` pagination |
150-
| `TimelinePaginationEnabled` | `oldest` + `latest` + `inclusive` pagination |
151-
| `TraditionalPagingEnabled` | `count` + `page` pagination |
152-
| `OptionalTeamAssignable` | Optional `team_id` |
153-
| `LocaleAware` | Optional `include_locale` |
154-
155-
Also reuse namespace-specific mixins from the same file (e.g., `Channel`, `ChannelAndTS`, `AsUser` in `chat.ts`).
156-
157-
**Example**`ChatAppendStreamArguments` from `packages/web-api/src/types/request/chat.ts`:
158-
159-
```typescript
160-
export interface ChatAppendStreamArguments extends TokenOverridable, ChannelAndTS, Partial<MarkdownText> {
161-
/**
162-
* @description An array of chunk objects to append to the stream.
163-
* Either `markdown_text` or `chunks` is required.
164-
*/
165-
chunks?: AnyChunk[];
166-
}
167-
```
168-
169-
### Step 4: Export Request Types
170-
171-
File: `packages/web-api/src/types/request/index.ts`
172-
173-
Add the new type to the appropriate export block:
174-
175-
```typescript
176-
export type {
177-
ChatAppendStreamArguments,
178-
ChatStartStreamArguments,
179-
ChatStopStreamArguments,
180-
// ... existing exports
181-
} from './chat';
182-
```
183-
184-
### Step 5: Add Method Binding
185-
186-
File: `packages/web-api/src/methods.ts`
187-
188-
1. Import the argument and response types at the top of the file.
189-
2. Add a method binding in the appropriate namespace object of the `Methods` class.
190-
191-
**Import pattern**:
192-
193-
```typescript
194-
// Request types are imported from the request index barrel
195-
import type {
196-
ChatAppendStreamArguments,
197-
// ...
198-
} from './types/request';
199-
200-
// Response types are imported from individual files
201-
import type { ChatAppendStreamResponse } from './types/response/ChatAppendStreamResponse';
202-
```
203-
204-
**Note**: Request types are imported from the barrel `./types/request` (already grouped by namespace), but response types are imported from their individual files (e.g., `./types/response/ChatAppendStreamResponse`).
205-
206-
**Binding pattern** — within the appropriate namespace object in the `Methods` class:
207-
208-
```typescript
209-
public readonly chat = {
210-
/**
211-
* @description Appends text to an existing streaming conversation.
212-
* @see {@link https://docs.slack.dev/reference/methods/chat.appendStream `chat.appendStream` API reference}.
213-
*/
214-
appendStream: bindApiCall<ChatAppendStreamArguments, ChatAppendStreamResponse>(this, 'chat.appendStream'),
215-
// ...
216-
};
217-
```
218-
219-
**`bindApiCall` vs `bindApiCallWithOptionalArgument`**:
220-
221-
- `bindApiCall` — for methods with **required** arguments (most methods)
222-
- `bindApiCallWithOptionalArgument` — for methods where **all arguments are optional**
223-
224-
### Step 6: Add Type Tests
225-
226-
File: `packages/web-api/test/types/methods/<namespace>.test-d.ts`
227-
228-
Add both sad path (should error) and happy path (should compile) tests:
229-
230-
```typescript
231-
import { expectAssignable, expectError } from 'tsd';
232-
import { WebClient } from '../../../src/WebClient';
233-
234-
const web = new WebClient('TOKEN');
235-
236-
// chat.appendStream
237-
// -- sad path
238-
expectError(web.chat.appendStream()); // lacking argument
239-
expectError(web.chat.appendStream({})); // empty argument
240-
expectError(
241-
web.chat.appendStream({
242-
channel: 'C1234', // missing ts and markdown_text
243-
}),
244-
);
245-
246-
// -- happy path
247-
expectAssignable<Parameters<typeof web.chat.appendStream>>([
248-
{
249-
channel: 'C1234',
250-
ts: '1234.56',
251-
markdown_text: 'hello',
252-
},
253-
]);
254-
```
255-
256-
### Summary Checklist
257-
258-
- [ ] Looked up method docs at `https://docs.slack.dev/reference/methods/{method.name}`
259-
- [ ] Generated response types via `scripts/generate-web-api-types.sh` (or created manually if JSON sample unavailable)
260-
- [ ] Added request argument type in `packages/web-api/src/types/request/<namespace>.ts`
261-
- [ ] Exported new request type from `packages/web-api/src/types/request/index.ts`
262-
- [ ] Imported argument + response types in `packages/web-api/src/methods.ts`
263-
- [ ] Added method binding with `bindApiCall` in appropriate namespace in `packages/web-api/src/methods.ts`
264-
- [ ] Added sad/happy path type tests in `packages/web-api/test/types/methods/<namespace>.test-d.ts`
265-
- [ ] Verified: `npm test --workspace=packages/web-api`
266-
267-
## Code Generation Details
268-
269-
### `scripts/generate-web-api-types.sh`
270-
271-
Entry point for response type generation. It:
272-
273-
1. Clones or pulls `slackapi/java-slack-sdk` into `tmp/`
274-
2. Runs `npm install` in `scripts/` to install quicktype
275-
3. Executes `scripts/code_generator.rb`
276-
4. Runs `npm run lint:fix` on `packages/web-api`
277-
278-
## Testing
279-
280-
- **Test framework**: `node:test` (built-in) with `node:assert/strict` for assertions
281-
- **Test runner**: `node --experimental-test-coverage --import tsx --test`
282-
- **Unit tests**: `*.test.{ts,js}` files alongside source (e.g., `src/WebClient.test.ts`)
283-
- **Type tests**: tsd (`*.test-d.ts` files in `packages/web-api/test/types/`)
284-
- **Integration tests**: CommonJS, ESM, and TypeScript compatibility checks
285-
- **CI matrix**: Node 18.x, 20.x, 22.x, 24.x on Ubuntu + Windows (8 jobs total)
286-
- **Coverage output**: `lcov.info` at each package root (not in `coverage/` dir)
287-
- **Test results**: `test-results.xml` at each package root (JUnit format)
288-
289-
Per-package test commands:
290-
291-
```bash
292-
npm test --workspace=packages/web-api # all tests (types + integration + unit)
293-
npm run test:unit --workspace=packages/web-api
294-
npm run test:types --workspace=packages/web-api
295-
```
296-
297-
## Web API Client Architecture
298-
299-
`packages/web-api/src/WebClient.ts`:
96+
## Development Philosophy
30097

301-
- Extends the `Methods` class (which defines all API method bindings in `methods.ts`)
302-
- Uses Axios for HTTP requests
303-
- `p-queue` for request concurrency control
304-
- `p-retry` for automatic retries with backoff
305-
- Built-in cursor pagination via `paginate()`
306-
- Streaming support via `chatStream()` using `ChatStreamer`
307-
- Rate limiting with emitted events
98+
- **Follow existing patterns exactly** — when adding or modifying code, match the style of adjacent code.
99+
- **Reuse mixins and shared types** rather than duplicating field definitions across packages.
100+
- **PascalCase for types**, camelCase for methods.
101+
- **JSDoc on public APIs**: Always include `@description` and `@see` with a link to the API reference.
308102

309103
## Common Pitfalls
310104

311-
- **Don't edit generated response types** — use `scripts/generate-web-api-types.sh` instead. Look for the "DO NOT EDIT" banner.
312-
- **Build in dependency order** — building `web-api` before `logger` and `types` will fail.
313-
- **Use Biome, not ESLint/Prettier** — this repo uses Biome exclusively (`biome.json`).
314-
- **Biome overrides exist for generated code**`packages/web-api/src/types/response/**/*.ts` has relaxed rules (`noBannedTypes: off`, `noExplicitAny: off`).
315-
- **Import organization is disabled** for `packages/web-api/src/index.ts` in Biome config.
316-
- **Response type imports use individual files**, not the barrel — e.g., `import type { ChatPostMessageResponse } from './types/response/ChatPostMessageResponse'`.
317-
318-
## Development Philosophy
319-
320-
- **Follow existing patterns exactly** — when adding a new method, match the style of adjacent methods.
321-
- **Reuse mixins** from `common.ts` and namespace-specific files rather than duplicating field definitions.
322-
- **Every API method needs four things**: request type, response type, method binding, and type tests.
323-
- **Naming conventions**: PascalCase for types (`ChatPostMessageArguments`), camelCase for methods (`postMessage`).
324-
- **JSDoc on method bindings**: Always include `@description` and `@see` with a link to the API reference.
105+
- **Build in dependency order** — see the dependency graph above.

0 commit comments

Comments
 (0)