Skip to content

Commit c941a2c

Browse files
committed
docs(agents): add guidance to make working with opencode better
After working with the codebase using opencode a bit: - Add guidance on regenerating SDK after schema changes - Document type predicate pattern for filtering discriminated unions - Discourage use of 'as' casts when TypeScript's type narrowing fails - Add guidance to run prettier after changing code with ./script/format.ts - .gitignore: exclude bun-build files Significantly reduces errors in the output in my experience. Signed-off-by: Christian Stewart <[email protected]>
1 parent eed48e7 commit c941a2c

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ Session.vim
1818
opencode.json
1919
a.out
2020
target
21+
*.bun-build

AGENTS.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,34 @@
22

33
- To test opencode in the `packages/opencode` directory you can run `bun dev`
44

5+
## Code Formatting
6+
7+
- After changing TypeScript code, run `./script/format.ts` to format the code
8+
- This ensures consistent formatting across the codebase
9+
10+
## Type Safety
11+
12+
- NEVER use `as any` or type casts to work around type errors caused by outdated SDK types
13+
- If adding new schemas/types to `message-v2.ts` or other core files causes SDK type mismatches, regenerate the SDK first
14+
- Run `cd packages/sdk/js && bun ./script/build.ts` to regenerate SDK types after schema changes
15+
- Type errors are signals that something needs to be fixed properly, not suppressed
16+
17+
### Type Predicates for Discriminated Unions
18+
19+
- NEVER use `as` type assertions when filtering discriminated unions (e.g., `find()`, `filter()`)
20+
- ALWAYS use type predicate functions instead:
21+
22+
```typescript
23+
// ❌ BAD: Using 'as' cast
24+
const subtask = parts.find((x) => x.type === "subtask") as SubtaskPart | undefined
25+
26+
// ✅ GOOD: Using type predicate
27+
const isSubtaskPart = (part: Part): part is SubtaskPart => part.type === "subtask"
28+
const subtask = parts.find(isSubtaskPart)
29+
```
30+
31+
**Why**: TypeScript's discriminated union narrowing doesn't work with array methods like `find()` or `filter()` because the predicate function doesn't act as a type guard. The return type is still the full union type, not the narrowed type. Type predicates (`part is Type`) explicitly tell TypeScript that the returned value matches a specific variant of the union.
32+
533
## Tool Calling
634

735
- ALWAYS USE PARALLEL TOOLS WHEN APPLICABLE. Here is an example illustrating how to execute 3 parallel file reads in this chat environment:

0 commit comments

Comments
 (0)