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
25 changes: 25 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,31 @@ When adding a new wrapper, follow this structure:
body(result: Float) { |res| res.result }
```


## Organizing wrappers with `draw`

Use `draw` to keep large wrappers readable by splitting DSL declarations into
smaller files.

```ruby
# clients/payments/client.rb
class Payments::Client < Purple::Client
domain 'https://api.example.com'

draw 'paths/invoices'
draw 'paths/refunds.rb'
end

# clients/payments/paths/invoices.rb
path :invoices do
response :ok do
body :default
end

root_method :invoices
end
```

## DO / DON'T (for LLMs)

**DO**
Expand Down
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,36 @@ end
MessagesClient.send_message
```

### Splitting large wrappers with `draw`

If a wrapper gets too long, you can move parts of the DSL into separate files
and load them with `draw`.

`draw` resolves paths relative to the file where it is called. If you omit the
extension, `.rb` is added automatically.

```ruby
# clients/payments/client.rb
class Payments::Client < Purple::Client
domain 'https://api.example.com'

draw 'paths/invoices'
draw 'paths/refunds.rb'
end

# clients/payments/paths/invoices.rb
path :invoices do
response :ok do
body :default
end
root_method :invoices
end
```

Use `draw` only to organize DSL definitions (`path`, `params`, `response`,
`root_method`) into smaller files. Keep wrapper behavior declarative and avoid
adding non-DSL business logic in drawn files.

## How to build a wrapper client (5 steps)

1. **Define a `domain`** for the API host.
Expand Down